diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp | 55 | ||||
| -rw-r--r-- | llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | 19 | ||||
| -rw-r--r-- | llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 18 | ||||
| -rw-r--r-- | llvm/lib/Target/RISCV/RISCVISelLowering.h | 4 | 
4 files changed, 96 insertions, 0 deletions
diff --git a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp index 4808e6c73c5..bbaa8ec454f 100644 --- a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp +++ b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp @@ -41,6 +41,13 @@ public:    void EmitInstruction(const MachineInstr *MI) override; +  bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, +                       unsigned AsmVariant, const char *ExtraCode, +                       raw_ostream &OS) override; +  bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, +                             unsigned AsmVariant, const char *ExtraCode, +                             raw_ostream &OS) override; +    bool emitPseudoExpansionLowering(MCStreamer &OutStreamer,                                     const MachineInstr *MI); @@ -65,6 +72,54 @@ void RISCVAsmPrinter::EmitInstruction(const MachineInstr *MI) {    EmitToStreamer(*OutStreamer, TmpInst);  } +bool RISCVAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, +                                      unsigned AsmVariant, +                                      const char *ExtraCode, raw_ostream &OS) { +  if (AsmVariant != 0) +    report_fatal_error("There are no defined alternate asm variants"); + +  // First try the generic code, which knows about modifiers like 'c' and 'n'. +  if (!AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, OS)) +    return false; + +  if (!ExtraCode) { +    const MachineOperand &MO = MI->getOperand(OpNo); +    switch (MO.getType()) { +    case MachineOperand::MO_Immediate: +      OS << MO.getImm(); +      return false; +    case MachineOperand::MO_Register: +      OS << RISCVInstPrinter::getRegisterName(MO.getReg()); +      return false; +    default: +      break; +    } +  } + +  return true; +} + +bool RISCVAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, +                                            unsigned OpNo, unsigned AsmVariant, +                                            const char *ExtraCode, +                                            raw_ostream &OS) { +  if (AsmVariant != 0) +    report_fatal_error("There are no defined alternate asm variants"); + +  if (!ExtraCode) { +    const MachineOperand &MO = MI->getOperand(OpNo); +    // For now, we only support register memory operands in registers and +    // assume there is no addend +    if (!MO.isReg()) +      return true; + +    OS << "0(" << RISCVInstPrinter::getRegisterName(MO.getReg()) << ")"; +    return false; +  } + +  return AsmPrinter::PrintAsmMemoryOperand(MI, OpNo, AsmVariant, ExtraCode, OS); +} +  // Force static initialization.  extern "C" void LLVMInitializeRISCVAsmPrinter() {    RegisterAsmPrinter<RISCVAsmPrinter> X(getTheRISCV32Target()); diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp index 113a45ac7cc..23a0382d442 100644 --- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp @@ -44,6 +44,9 @@ public:    void Select(SDNode *Node) override; +  bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID, +                                    std::vector<SDValue> &OutOps) override; +    bool SelectAddrFI(SDValue Addr, SDValue &Base);  // Include the pieces autogenerated from the target description. @@ -93,6 +96,22 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {    SelectCode(Node);  } +bool RISCVDAGToDAGISel::SelectInlineAsmMemoryOperand( +    const SDValue &Op, unsigned ConstraintID, std::vector<SDValue> &OutOps) { +  switch (ConstraintID) { +  case InlineAsm::Constraint_i: +  case InlineAsm::Constraint_m: +    // We just support simple memory operands that have a single address +    // operand and need no special handling. +    OutOps.push_back(Op); +    return false; +  default: +    break; +  } + +  return true; +} +  bool RISCVDAGToDAGISel::SelectAddrFI(SDValue Addr, SDValue &Base) {    if (auto FIN = dyn_cast<FrameIndexSDNode>(Addr)) {      Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), Subtarget->getXLenVT()); diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index bd44ab9a138..0dec008a3e9 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -994,3 +994,21 @@ const char *RISCVTargetLowering::getTargetNodeName(unsigned Opcode) const {    }    return nullptr;  } + +std::pair<unsigned, const TargetRegisterClass *> +RISCVTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, +                                                  StringRef Constraint, +                                                  MVT VT) const { +  // First, see if this is a constraint that directly corresponds to a +  // RISCV register class. +  if (Constraint.size() == 1) { +    switch (Constraint[0]) { +    case 'r': +      return std::make_pair(0U, &RISCV::GPRRegClass); +    default: +      break; +    } +  } + +  return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT); +} diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h index 51c942b2e6a..2f9c202fb64 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.h +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h @@ -43,6 +43,10 @@ public:    // This method returns the name of a target specific DAG node.    const char *getTargetNodeName(unsigned Opcode) 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;  | 

