diff options
author | Yonghong Song <yhs@fb.com> | 2017-09-18 23:29:36 +0000 |
---|---|---|
committer | Yonghong Song <yhs@fb.com> | 2017-09-18 23:29:36 +0000 |
commit | 9ef85f06775dea8b5f11b118421e5ce997eb7c88 (patch) | |
tree | 2cdadafbcfcde59e72c70040c43c30d3204983e1 /llvm/lib | |
parent | bb4b4eef61d3377863a2fa7688db0d0c67fe5285 (diff) | |
download | llvm-9ef85f06775dea8b5f11b118421e5ce997eb7c88.zip llvm-9ef85f06775dea8b5f11b118421e5ce997eb7c88.tar.gz llvm-9ef85f06775dea8b5f11b118421e5ce997eb7c88.tar.bz2 |
bpf: add inline-asm support
Signed-off-by: Yonghong Song <yhs@fb.com>
Acked-by: Alexei Starovoitov <ast@kernel.org>
llvm-svn: 313593
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/BPF/BPFAsmPrinter.cpp | 77 | ||||
-rw-r--r-- | llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp | 24 | ||||
-rw-r--r-- | llvm/lib/Target/BPF/BPFISelLowering.cpp | 16 | ||||
-rw-r--r-- | llvm/lib/Target/BPF/BPFISelLowering.h | 4 |
4 files changed, 121 insertions, 0 deletions
diff --git a/llvm/lib/Target/BPF/BPFAsmPrinter.cpp b/llvm/lib/Target/BPF/BPFAsmPrinter.cpp index 9397c78..705211b 100644 --- a/llvm/lib/Target/BPF/BPFAsmPrinter.cpp +++ b/llvm/lib/Target/BPF/BPFAsmPrinter.cpp @@ -40,11 +40,88 @@ public: : AsmPrinter(TM, std::move(Streamer)) {} StringRef getPassName() const override { return "BPF Assembly Printer"; } + void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O); + bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, + unsigned AsmVariant, const char *ExtraCode, + raw_ostream &O) override; + bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum, + unsigned AsmVariant, const char *ExtraCode, + raw_ostream &O) override; void EmitInstruction(const MachineInstr *MI) override; }; } // namespace +void BPFAsmPrinter::printOperand(const MachineInstr *MI, int OpNum, + raw_ostream &O) { + const MachineOperand &MO = MI->getOperand(OpNum); + + switch (MO.getType()) { + case MachineOperand::MO_Register: + O << BPFInstPrinter::getRegisterName(MO.getReg()); + break; + + case MachineOperand::MO_Immediate: + O << MO.getImm(); + break; + + case MachineOperand::MO_MachineBasicBlock: + O << *MO.getMBB()->getSymbol(); + break; + + case MachineOperand::MO_GlobalAddress: + O << *getSymbol(MO.getGlobal()); + break; + + case MachineOperand::MO_BlockAddress: { + MCSymbol *BA = GetBlockAddressSymbol(MO.getBlockAddress()); + O << BA->getName(); + break; + } + + case MachineOperand::MO_ExternalSymbol: + O << *GetExternalSymbolSymbol(MO.getSymbolName()); + break; + + case MachineOperand::MO_JumpTableIndex: + case MachineOperand::MO_ConstantPoolIndex: + default: + llvm_unreachable("<unknown operand type>"); + } +} + +bool BPFAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, + unsigned /*AsmVariant*/, + const char *ExtraCode, raw_ostream &O) { + if (ExtraCode && ExtraCode[0]) + return true; // BPF does not have special modifiers + + printOperand(MI, OpNo, O); + return false; +} + +bool BPFAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, + unsigned OpNum, unsigned AsmVariant, + const char *ExtraCode, + raw_ostream &O) { + assert(OpNum + 1 < MI->getNumOperands() && "Insufficient operands"); + const MachineOperand &BaseMO = MI->getOperand(OpNum); + const MachineOperand &OffsetMO = MI->getOperand(OpNum + 1); + assert(BaseMO.isReg() && "Unexpected base pointer for inline asm memory operand."); + assert(OffsetMO.isImm() && "Unexpected offset for inline asm memory operand."); + int Offset = OffsetMO.getImm(); + + if (ExtraCode) + return true; // Unknown modifier. + + if (Offset < 0) + O << "(" << BPFInstPrinter::getRegisterName(BaseMO.getReg()) << " - " << -Offset << ")"; + else + O << "(" << BPFInstPrinter::getRegisterName(BaseMO.getReg()) << " + " << Offset << ")"; + + return false; +} + void BPFAsmPrinter::EmitInstruction(const MachineInstr *MI) { BPFMCInstLower MCInstLowering(OutContext, *this); diff --git a/llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp b/llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp index f48429e..1f382f3 100644 --- a/llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp +++ b/llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp @@ -48,6 +48,10 @@ public: void PreprocessISelDAG() override; + bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintCode, + std::vector<SDValue> &OutOps) override; + + private: // Include the pieces autogenerated from the target description. #include "BPFGenDAGISel.inc" @@ -145,6 +149,26 @@ bool BPFDAGToDAGISel::SelectFIAddr(SDValue Addr, SDValue &Base, return false; } +bool BPFDAGToDAGISel::SelectInlineAsmMemoryOperand( + const SDValue &Op, unsigned ConstraintCode, std::vector<SDValue> &OutOps) { + SDValue Op0, Op1; + switch (ConstraintCode) { + default: + return true; + case InlineAsm::Constraint_m: // memory + if (!SelectAddr(Op, Op0, Op1)) + return true; + break; + } + + SDLoc DL(Op); + SDValue AluOp = CurDAG->getTargetConstant(ISD::ADD, DL, MVT::i32);; + OutOps.push_back(Op0); + OutOps.push_back(Op1); + OutOps.push_back(AluOp); + return false; +} + void BPFDAGToDAGISel::Select(SDNode *Node) { unsigned Opcode = Node->getOpcode(); diff --git a/llvm/lib/Target/BPF/BPFISelLowering.cpp b/llvm/lib/Target/BPF/BPFISelLowering.cpp index 94b3c7a..d4e06ddc 100644 --- a/llvm/lib/Target/BPF/BPFISelLowering.cpp +++ b/llvm/lib/Target/BPF/BPFISelLowering.cpp @@ -139,6 +139,22 @@ bool BPFTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) cons return false; } +std::pair<unsigned, const TargetRegisterClass *> +BPFTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, + StringRef Constraint, + MVT VT) const { + if (Constraint.size() == 1) + // GCC Constraint Letters + switch (Constraint[0]) { + case 'r': // GENERAL_REGS + return std::make_pair(0U, &BPF::GPRRegClass); + default: + break; + } + + return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT); +} + SDValue BPFTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { switch (Op.getOpcode()) { case ISD::BR_CC: diff --git a/llvm/lib/Target/BPF/BPFISelLowering.h b/llvm/lib/Target/BPF/BPFISelLowering.h index 35065f2..984843a 100644 --- a/llvm/lib/Target/BPF/BPFISelLowering.h +++ b/llvm/lib/Target/BPF/BPFISelLowering.h @@ -46,6 +46,10 @@ public: // with the given GlobalAddress is legal. bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override; + std::pair<unsigned, const TargetRegisterClass *> + getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, + StringRef Constraint, MVT VT) const override; + MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *BB) const override; |