initial implementation of addressing mode 5
authorRafael Espindola <rafael.espindola@gmail.com>
Tue, 17 Oct 2006 18:04:53 +0000 (18:04 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Tue, 17 Oct 2006 18:04:53 +0000 (18:04 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31002 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMAsmPrinter.cpp
lib/Target/ARM/ARMISelDAGToDAG.cpp
lib/Target/ARM/ARMInstrInfo.td
test/CodeGen/ARM/fpmem.ll [new file with mode: 0644]

index 8a0f113c5d9ec0dab51d0543a09fd6dfcabbf1e5..f67f39aa7d0b01039c61286a648356c5c82ad79a 100644 (file)
@@ -55,6 +55,7 @@ namespace {
     }
 
     void printAddrMode1(const MachineInstr *MI, int opNum);
+    void printAddrMode5(const MachineInstr *MI, int opNum);
 
     void printMemRegImm(const MachineInstr *MI, int opNum,
                        const char *Modifier = NULL) {
@@ -193,6 +194,24 @@ void ARMAsmPrinter::printAddrMode1(const MachineInstr *MI, int opNum) {
   }
 }
 
+void ARMAsmPrinter::printAddrMode5(const MachineInstr *MI, int opNum) {
+  const MachineOperand &Arg    = MI->getOperand(opNum);
+  const MachineOperand &Offset = MI->getOperand(opNum + 1);
+  assert(Offset.isImmediate());
+
+  if (Arg.isConstantPoolIndex()) {
+    assert(Offset.getImmedValue() == 0);
+    printOperand(MI, opNum);
+  } else {
+    assert(Arg.isRegister());
+    O << '[';
+    printOperand(MI, opNum);
+    O << ", ";
+    printOperand(MI, opNum + 1);
+    O << ']';
+  }
+}
+
 void ARMAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
   const MachineOperand &MO = MI->getOperand (opNum);
   const MRegisterInfo &RI = *TM.getRegisterInfo();
index 905d9620e20d9a44d778e6ae809221cbe203e8e2..13dd33cc9028ded045029613ff9cf0aab27e7ec3 100644 (file)
@@ -737,6 +737,7 @@ public:
   bool SelectAddrRegImm(SDOperand N, SDOperand &Offset, SDOperand &Base);
   bool SelectAddrMode1(SDOperand N, SDOperand &Arg, SDOperand &Shift,
                       SDOperand &ShiftType);
+  bool SelectAddrMode5(SDOperand N, SDOperand &Arg, SDOperand &Offset);
 
   // Include the pieces autogenerated from the target description.
 #include "ARMGenDAGISel.inc"
@@ -835,6 +836,14 @@ bool ARMDAGToDAGISel::SelectAddrMode1(SDOperand N,
   return true;
 }
 
+bool ARMDAGToDAGISel::SelectAddrMode5(SDOperand N, SDOperand &Arg,
+                                      SDOperand &Offset) {
+  //TODO: detect offset
+  Offset = CurDAG->getTargetConstant(0, MVT::i32);
+  Arg    = N;
+  return true;
+}
+
 //register plus/minus 12 bit offset
 bool ARMDAGToDAGISel::SelectAddrRegImm(SDOperand N, SDOperand &Offset,
                                    SDOperand &Base) {
index ff9d9e7a0367cd2e06d3bad4c2a06e01a6750278..42919cfc81e8287d6a96a9f5cc4dd1eb2e840651 100644 (file)
@@ -19,6 +19,12 @@ def op_addr_mode1 : Operand<iPTR> {
   let MIOperandInfo = (ops ptr_rc, ptr_rc, i32imm);
 }
 
+def op_addr_mode5 : Operand<iPTR> {
+  let PrintMethod = "printAddrMode5";
+  let NumMIOperands = 2;
+  let MIOperandInfo = (ops ptr_rc, i32imm);
+}
+
 def memri : Operand<iPTR> {
   let PrintMethod = "printMemRegImm";
   let NumMIOperands = 2;
@@ -30,6 +36,9 @@ def memri : Operand<iPTR> {
 def addr_mode1 : ComplexPattern<iPTR, 3, "SelectAddrMode1", [imm, sra, shl, srl],
                                 []>;
 
+//Addressing Mode 5: VFP load/store
+def addr_mode5 : ComplexPattern<iPTR, 2, "SelectAddrMode5", [], []>;
+
 //register plus/minus 12 bit offset
 def iaddr  : ComplexPattern<iPTR, 2, "SelectAddrRegImm", [frameindex], []>;
 //register plus scaled register
@@ -285,22 +294,22 @@ def FDIVS   : FPBinOp<"fdivs", fdiv>;
 def FDIVD   : DFPBinOp<"fdivd", fdiv>;
 
 // Floating Point Load
-def FLDS  : InstARM<(ops FPRegs:$dst, IntRegs:$addr),
-                     "flds $dst, [$addr]",
-                     [(set FPRegs:$dst, (load IntRegs:$addr))]>;
+def FLDS  : InstARM<(ops FPRegs:$dst, op_addr_mode5:$addr),
+                     "flds $dst, $addr",
+                     [(set FPRegs:$dst, (load addr_mode5:$addr))]>;
 
-def FLDD  : InstARM<(ops DFPRegs:$dst, IntRegs:$addr),
-                     "fldd $dst, [$addr]",
-                     [(set DFPRegs:$dst, (load IntRegs:$addr))]>;
+def FLDD  : InstARM<(ops DFPRegs:$dst, op_addr_mode5:$addr),
+                     "fldd $dst, $addr",
+                     [(set DFPRegs:$dst, (load addr_mode5:$addr))]>;
 
 // Floating Point Store
-def FSTS    : InstARM<(ops FPRegs:$src, IntRegs:$addr),
+def FSTS    : InstARM<(ops FPRegs:$src, op_addr_mode5:$addr),
                        "fsts $src, [$addr]",
-                       [(store FPRegs:$src, IntRegs:$addr)]>;
+                       [(store FPRegs:$src, addr_mode5:$addr)]>;
 
-def FSTD    : InstARM<(ops DFPRegs:$src, IntRegs:$addr),
+def FSTD    : InstARM<(ops DFPRegs:$src, op_addr_mode5:$addr),
                        "fstd $src, [$addr]",
-                       [(store DFPRegs:$src, IntRegs:$addr)]>;
+                       [(store DFPRegs:$src, addr_mode5:$addr)]>;
 
 def : Pat<(ARMcall tglobaladdr:$dst),
           (bl tglobaladdr:$dst)>;
diff --git a/test/CodeGen/ARM/fpmem.ll b/test/CodeGen/ARM/fpmem.ll
new file mode 100644 (file)
index 0000000..e1ea410
--- /dev/null
@@ -0,0 +1,14 @@
+; RUN: llvm-as < %s | llc -march=arm &&
+; RUN: llvm-as < %s | llc -march=arm | grep flds | wc -l | grep 2 &&
+; RUN: llvm-as < %s | llc -march=arm | grep "flds.*\[" | wc -l | grep 1
+
+float %g(float %a) {
+entry:
+       ret float 0.000000e+00
+}
+
+float %g(float* %v) {
+entry:
+        %tmp = load float* %v
+       ret float %tmp
+}