mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-20 18:56:04 +00:00
[bpf] add support for bswap instructions
BPF has cpu_to_be and cpu_to_le instructions. For now assume little endian and generate cpu_to_be for ISD::BSWAP. llvm-svn: 233620
This commit is contained in:
parent
0bd9422f2b
commit
dc42b623c1
@ -137,7 +137,6 @@ BPFTargetLowering::BPFTargetLowering(const TargetMachine &TM,
|
||||
setOperationAction(ISD::SRL_PARTS, MVT::i64, Expand);
|
||||
setOperationAction(ISD::SRA_PARTS, MVT::i64, Expand);
|
||||
|
||||
setOperationAction(ISD::BSWAP, MVT::i64, Expand);
|
||||
setOperationAction(ISD::CTTZ, MVT::i64, Custom);
|
||||
setOperationAction(ISD::CTLZ, MVT::i64, Custom);
|
||||
setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i64, Custom);
|
||||
|
@ -484,6 +484,33 @@ def XADD64 : XADD<3, "xadd64", atomic_load_add_64>;
|
||||
// undefined def XADD8 : XADD<2, "xadd8", atomic_load_add_8>;
|
||||
}
|
||||
|
||||
// bswap16, bswap32, bswap64
|
||||
class BSWAP<bits<32> SizeOp, string OpcodeStr, list<dag> Pattern>
|
||||
: InstBPF<(outs GPR:$dst), (ins GPR:$src),
|
||||
!strconcat(OpcodeStr, "\t$dst"),
|
||||
Pattern> {
|
||||
bits<4> op;
|
||||
bits<1> BPFSrc;
|
||||
bits<4> dst;
|
||||
bits<32> imm;
|
||||
|
||||
let Inst{63-60} = op;
|
||||
let Inst{59} = BPFSrc;
|
||||
let Inst{51-48} = dst;
|
||||
let Inst{31-0} = imm;
|
||||
|
||||
let op = 0xd; // BPF_END
|
||||
let BPFSrc = 1; // BPF_TO_BE (TODO: use BPF_TO_LE for big-endian target)
|
||||
let BPFClass = 4; // BPF_ALU
|
||||
let imm = SizeOp;
|
||||
}
|
||||
|
||||
let Constraints = "$dst = $src" in {
|
||||
def BSWAP16 : BSWAP<16, "bswap16", [(set GPR:$dst, (srl (bswap GPR:$src), (i64 48)))]>;
|
||||
def BSWAP32 : BSWAP<32, "bswap32", [(set GPR:$dst, (srl (bswap GPR:$src), (i64 32)))]>;
|
||||
def BSWAP64 : BSWAP<64, "bswap64", [(set GPR:$dst, (bswap GPR:$src))]>;
|
||||
}
|
||||
|
||||
let Defs = [R0, R1, R2, R3, R4, R5], Uses = [R6], hasSideEffects = 1,
|
||||
hasExtraDefRegAllocReq = 1, hasExtraSrcRegAllocReq = 1, mayLoad = 1 in {
|
||||
class LOAD_ABS<bits<2> SizeOp, string OpcodeStr, Intrinsic OpNode>
|
||||
|
@ -61,3 +61,28 @@ entry:
|
||||
declare void @bar(i64, i32) #1
|
||||
|
||||
declare i64 @llvm.bpf.pseudo(i64, i64) #2
|
||||
|
||||
define i32 @bswap(i64 %a, i64 %b, i64 %c) #0 {
|
||||
entry:
|
||||
%0 = tail call i64 @llvm.bswap.i64(i64 %a)
|
||||
%conv = trunc i64 %b to i32
|
||||
%1 = tail call i32 @llvm.bswap.i32(i32 %conv)
|
||||
%conv1 = zext i32 %1 to i64
|
||||
%add = add i64 %conv1, %0
|
||||
%conv2 = trunc i64 %c to i16
|
||||
%2 = tail call i16 @llvm.bswap.i16(i16 %conv2)
|
||||
%conv3 = zext i16 %2 to i64
|
||||
%add4 = add i64 %add, %conv3
|
||||
%conv5 = trunc i64 %add4 to i32
|
||||
ret i32 %conv5
|
||||
; CHECK-LABEL: bswap:
|
||||
; CHECK: bswap64 r1 # encoding: [0xdc,0x01,0x00,0x00,0x40,0x00,0x00,0x00]
|
||||
; CHECK: bswap32 r2 # encoding: [0xdc,0x02,0x00,0x00,0x20,0x00,0x00,0x00]
|
||||
; CHECK: add r2, r1 # encoding: [0x0f,0x12,0x00,0x00,0x00,0x00,0x00,0x00]
|
||||
; CHECK: bswap16 r3 # encoding: [0xdc,0x03,0x00,0x00,0x10,0x00,0x00,0x00]
|
||||
; CHECK: add r2, r3 # encoding: [0x0f,0x32,0x00,0x00,0x00,0x00,0x00,0x00]
|
||||
}
|
||||
|
||||
declare i64 @llvm.bswap.i64(i64) #1
|
||||
declare i32 @llvm.bswap.i32(i32) #1
|
||||
declare i16 @llvm.bswap.i16(i16) #1
|
||||
|
Loading…
x
Reference in New Issue
Block a user