diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp | 14 | ||||
| -rw-r--r-- | llvm/lib/Target/BPF/BPFInstrInfo.td | 99 |
2 files changed, 103 insertions, 10 deletions
diff --git a/llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp b/llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp index 014dc86eaec..1c3a246bc09 100644 --- a/llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp +++ b/llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp @@ -39,8 +39,14 @@ using namespace llvm; namespace { class BPFDAGToDAGISel : public SelectionDAGISel { + + /// Subtarget - Keep a pointer to the BPFSubtarget around so that we can + /// make the right decision when generating code for different subtargets. + const BPFSubtarget *Subtarget; + public: - explicit BPFDAGToDAGISel(BPFTargetMachine &TM) : SelectionDAGISel(TM) { + explicit BPFDAGToDAGISel(BPFTargetMachine &TM) + : SelectionDAGISel(TM), Subtarget(nullptr) { curr_func_ = nullptr; } @@ -48,6 +54,12 @@ public: return "BPF DAG->DAG Pattern Instruction Selection"; } + bool runOnMachineFunction(MachineFunction &MF) override { + // Reset the subtarget each time through. + Subtarget = &MF.getSubtarget<BPFSubtarget>(); + return SelectionDAGISel::runOnMachineFunction(MF); + } + void PreprocessISelDAG() override; bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintCode, diff --git a/llvm/lib/Target/BPF/BPFInstrInfo.td b/llvm/lib/Target/BPF/BPFInstrInfo.td index 942a5b013ff..dc4fdc571ab 100644 --- a/llvm/lib/Target/BPF/BPFInstrInfo.td +++ b/llvm/lib/Target/BPF/BPFInstrInfo.td @@ -45,6 +45,8 @@ def BPFselectcc : SDNode<"BPFISD::SELECT_CC", SDT_BPFSelectCC, [SDNPInGlue]> def BPFWrapper : SDNode<"BPFISD::Wrapper", SDT_BPFWrapper>; def BPFIsLittleEndian : Predicate<"CurDAG->getDataLayout().isLittleEndian()">; def BPFIsBigEndian : Predicate<"!CurDAG->getDataLayout().isLittleEndian()">; +def BPFHasALU32 : Predicate<"Subtarget->getHasAlu32()">; +def BPFNoALU32 : Predicate<"!Subtarget->getHasAlu32()">; def brtarget : Operand<OtherVT> { let PrintMethod = "printBrTargetOperand"; @@ -349,9 +351,11 @@ class STORE<BPFWidthModifer SizeOp, string OpcodeStr, list<dag> Pattern> class STOREi64<BPFWidthModifer Opc, string OpcodeStr, PatFrag OpNode> : STORE<Opc, OpcodeStr, [(OpNode i64:$src, ADDRri:$addr)]>; -def STW : STOREi64<BPF_W, "u32", truncstorei32>; -def STH : STOREi64<BPF_H, "u16", truncstorei16>; -def STB : STOREi64<BPF_B, "u8", truncstorei8>; +let Predicates = [BPFNoALU32] in { + def STW : STOREi64<BPF_W, "u32", truncstorei32>; + def STH : STOREi64<BPF_H, "u16", truncstorei16>; + def STB : STOREi64<BPF_B, "u8", truncstorei8>; +} def STD : STOREi64<BPF_DW, "u64", store>; // LOAD instructions @@ -373,9 +377,13 @@ class LOAD<BPFWidthModifer SizeOp, string OpcodeStr, list<dag> Pattern> class LOADi64<BPFWidthModifer SizeOp, string OpcodeStr, PatFrag OpNode> : LOAD<SizeOp, OpcodeStr, [(set i64:$dst, (OpNode ADDRri:$addr))]>; -def LDW : LOADi64<BPF_W, "u32", zextloadi32>; -def LDH : LOADi64<BPF_H, "u16", zextloadi16>; -def LDB : LOADi64<BPF_B, "u8", zextloadi8>; + +let Predicates = [BPFNoALU32] in { + def LDW : LOADi64<BPF_W, "u32", zextloadi32>; + def LDH : LOADi64<BPF_H, "u16", zextloadi16>; + def LDB : LOADi64<BPF_B, "u8", zextloadi8>; +} + def LDD : LOADi64<BPF_DW, "u64", load>; class BRANCH<BPFJumpOp Opc, string OpcodeStr, list<dag> Pattern> @@ -524,9 +532,11 @@ def : Pat<(BPFcall imm:$dst), (JAL imm:$dst)>; def : Pat<(BPFcall GPR:$dst), (JALX GPR:$dst)>; // Loads -def : Pat<(extloadi8 ADDRri:$src), (i64 (LDB ADDRri:$src))>; -def : Pat<(extloadi16 ADDRri:$src), (i64 (LDH ADDRri:$src))>; -def : Pat<(extloadi32 ADDRri:$src), (i64 (LDW ADDRri:$src))>; +let Predicates = [BPFNoALU32] in { + def : Pat<(i64 (extloadi8 ADDRri:$src)), (i64 (LDB ADDRri:$src))>; + def : Pat<(i64 (extloadi16 ADDRri:$src)), (i64 (LDH ADDRri:$src))>; + def : Pat<(i64 (extloadi32 ADDRri:$src)), (i64 (LDW ADDRri:$src))>; +} // Atomics class XADD<BPFWidthModifer SizeOp, string OpcodeStr, PatFrag OpNode> @@ -633,3 +643,74 @@ def : Pat<(i32 (trunc GPR:$src)), // For i32 -> i64 anyext, we don't care about the high bits. def : Pat<(i64 (anyext GPR32:$src)), (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GPR32:$src, sub_32)>; + +class STORE32<BPFWidthModifer SizeOp, string OpcodeStr, list<dag> Pattern> + : TYPE_LD_ST<BPF_MEM.Value, SizeOp.Value, + (outs), + (ins GPR32:$src, MEMri:$addr), + "*("#OpcodeStr#" *)($addr) = $src", + Pattern> { + bits<4> src; + bits<20> addr; + + let Inst{51-48} = addr{19-16}; // base reg + let Inst{55-52} = src; + let Inst{47-32} = addr{15-0}; // offset + let BPFClass = BPF_STX; +} + +class STOREi32<BPFWidthModifer Opc, string OpcodeStr, PatFrag OpNode> + : STORE32<Opc, OpcodeStr, [(OpNode i32:$src, ADDRri:$addr)]>; + +let Predicates = [BPFHasALU32], DecoderNamespace = "BPFALU32" in { + def STW32 : STOREi32<BPF_W, "u32", store>; + def STH32 : STOREi32<BPF_H, "u16", truncstorei16>; + def STB32 : STOREi32<BPF_B, "u8", truncstorei8>; +} + +class LOAD32<BPFWidthModifer SizeOp, string OpcodeStr, list<dag> Pattern> + : TYPE_LD_ST<BPF_MEM.Value, SizeOp.Value, + (outs GPR32:$dst), + (ins MEMri:$addr), + "$dst = *("#OpcodeStr#" *)($addr)", + Pattern> { + bits<4> dst; + bits<20> addr; + + let Inst{51-48} = dst; + let Inst{55-52} = addr{19-16}; + let Inst{47-32} = addr{15-0}; + let BPFClass = BPF_LDX; +} + +class LOADi32<BPFWidthModifer SizeOp, string OpcodeStr, PatFrag OpNode> + : LOAD32<SizeOp, OpcodeStr, [(set i32:$dst, (OpNode ADDRri:$addr))]>; + +let Predicates = [BPFHasALU32], DecoderNamespace = "BPFALU32" in { + def LDW32 : LOADi32<BPF_W, "u32", load>; + def LDH32 : LOADi32<BPF_H, "u16", zextloadi16>; + def LDB32 : LOADi32<BPF_B, "u8", zextloadi8>; +} + +let Predicates = [BPFHasALU32] in { + def : Pat<(truncstorei8 GPR:$src, ADDRri:$dst), + (STB32 (EXTRACT_SUBREG GPR:$src, sub_32), ADDRri:$dst)>; + def : Pat<(truncstorei16 GPR:$src, ADDRri:$dst), + (STH32 (EXTRACT_SUBREG GPR:$src, sub_32), ADDRri:$dst)>; + def : Pat<(truncstorei32 GPR:$src, ADDRri:$dst), + (STW32 (EXTRACT_SUBREG GPR:$src, sub_32), ADDRri:$dst)>; + def : Pat<(i32 (extloadi8 ADDRri:$src)), (i32 (LDB32 ADDRri:$src))>; + def : Pat<(i32 (extloadi16 ADDRri:$src)), (i32 (LDH32 ADDRri:$src))>; + def : Pat<(i64 (zextloadi8 ADDRri:$src)), + (SUBREG_TO_REG (i64 0), (LDB32 ADDRri:$src), sub_32)>; + def : Pat<(i64 (zextloadi16 ADDRri:$src)), + (SUBREG_TO_REG (i64 0), (LDH32 ADDRri:$src), sub_32)>; + def : Pat<(i64 (zextloadi32 ADDRri:$src)), + (SUBREG_TO_REG (i64 0), (LDW32 ADDRri:$src), sub_32)>; + def : Pat<(i64 (extloadi8 ADDRri:$src)), + (SUBREG_TO_REG (i64 0), (LDB32 ADDRri:$src), sub_32)>; + def : Pat<(i64 (extloadi16 ADDRri:$src)), + (SUBREG_TO_REG (i64 0), (LDH32 ADDRri:$src), sub_32)>; + def : Pat<(i64 (extloadi32 ADDRri:$src)), + (SUBREG_TO_REG (i64 0), (LDW32 ADDRri:$src), sub_32)>; +} |

