From c53cc48ca98c86a9ccb9de632c77890c5f7ea2d5 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Thu, 9 Jun 2011 03:31:05 +0000 Subject: [PATCH] Initial support for inline asm memory operand constraints. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132768 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsAsmPrinter.cpp | 16 ++++++++++++++++ lib/Target/Mips/MipsISelDAGToDAG.cpp | 12 ++++++++++++ test/CodeGen/Mips/inlineasmmemop.ll | 23 +++++++++++++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 test/CodeGen/Mips/inlineasmmemop.ll diff --git a/lib/Target/Mips/MipsAsmPrinter.cpp b/lib/Target/Mips/MipsAsmPrinter.cpp index 8caa7cd2f75..6f69ba388fd 100644 --- a/lib/Target/Mips/MipsAsmPrinter.cpp +++ b/lib/Target/Mips/MipsAsmPrinter.cpp @@ -56,6 +56,9 @@ namespace { bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode, raw_ostream &O); + bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum, + unsigned AsmVariant, const char *ExtraCode, + raw_ostream &O); void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O); void printUnsignedImm(const MachineInstr *MI, int opNum, raw_ostream &O); void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O, @@ -304,6 +307,19 @@ bool MipsAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, return false; } +bool MipsAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, + unsigned OpNum, unsigned AsmVariant, + const char *ExtraCode, + raw_ostream &O) { + if (ExtraCode && ExtraCode[0]) + return true; // Unknown modifier. + + const MachineOperand &MO = MI->getOperand(OpNum); + assert(MO.isReg() && "unexpected inline asm memory operand"); + O << "0($" << MipsAsmPrinter::getRegisterName(MO.getReg()) << ")"; + return false; +} + void MipsAsmPrinter::printOperand(const MachineInstr *MI, int opNum, raw_ostream &O) { const MachineOperand &MO = MI->getOperand(opNum); diff --git a/lib/Target/Mips/MipsISelDAGToDAG.cpp b/lib/Target/Mips/MipsISelDAGToDAG.cpp index d8a84ce5299..c35c8522443 100644 --- a/lib/Target/Mips/MipsISelDAGToDAG.cpp +++ b/lib/Target/Mips/MipsISelDAGToDAG.cpp @@ -94,6 +94,10 @@ private: inline SDValue getI32Imm(unsigned Imm) { return CurDAG->getTargetConstant(Imm, MVT::i32); } + + virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, + char ConstraintCode, + std::vector &OutOps); }; } @@ -462,6 +466,14 @@ SDNode* MipsDAGToDAGISel::Select(SDNode *Node) { return ResNode; } +bool MipsDAGToDAGISel:: +SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, + std::vector &OutOps) { + assert(ConstraintCode == 'm' && "unexpected asm memory constraint"); + OutOps.push_back(Op); + return false; +} + /// createMipsISelDag - This pass converts a legalized DAG into a /// MIPS-specific DAG, ready for instruction scheduling. FunctionPass *llvm::createMipsISelDag(MipsTargetMachine &TM) { diff --git a/test/CodeGen/Mips/inlineasmmemop.ll b/test/CodeGen/Mips/inlineasmmemop.ll new file mode 100644 index 00000000000..c5658923dcc --- /dev/null +++ b/test/CodeGen/Mips/inlineasmmemop.ll @@ -0,0 +1,23 @@ +; RUN: llc -march=mipsel -mcpu=4ke < %s | FileCheck %s + +@g1 = external global i32 + +define i32 @f1(i32 %x) nounwind { +entry: +; CHECK: addiu $[[T0:[0-9]+]], $sp +; CHECK: #APP +; CHECK: sw $4, 0($[[T0]]) +; CHECK: #NO_APP +; CHECK: lw $[[T1:[0-9]+]], %got(g1)($gp) +; CHECK: #APP +; CHECK: lw $[[T3:[0-9]+]], 0($[[T0]]) +; CHECK: #NO_APP +; CHECK: sw $[[T3]], 0($[[T1]]) + + %l1 = alloca i32, align 4 + call void asm "sw $1, $0", "=*m,r"(i32* %l1, i32 %x) nounwind + %0 = call i32 asm "lw $0, $1", "=r,*m"(i32* %l1) nounwind + store i32 %0, i32* @g1, align 4 + ret i32 %0 +} +