implement printSORegOperand, add lowering for the nasty and despicable MOVi2pieces :)
authorChris Lattner <sabre@nondot.org>
Tue, 20 Oct 2009 00:40:56 +0000 (00:40 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 20 Oct 2009 00:40:56 +0000 (00:40 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@84573 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMInstrInfo.td
lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp
lib/Target/ARM/AsmPrinter/ARMInstPrinter.h

index 6ec78bc72ee7791cf1d2ea28b43fd5d3edcf91c2..3e0691cbe9d888831a3a77ab3566ce1b41408a1b 100644 (file)
@@ -1582,8 +1582,9 @@ def : ARMPat<(xor GPR:$LHS, so_imm2part:$RHS),
                     (so_imm2part_2 imm:$RHS))>;
 
 // 32-bit immediate using movw + movt.
-// This is a single pseudo instruction to make it re-materializable. Remove
-// when we can do generalized remat.
+// This is a single pseudo instruction, the benefit is that it can be remat'd
+// as a single unit instead of having to handle reg inputs.
+// FIXME: Remove this when we can do generalized remat.
 let isReMaterializable = 1 in
 def MOVi32imm : AI1x2<(outs GPR:$dst), (ins i32imm:$src), Pseudo, IIC_iMOVi,
                      "movw", " $dst, ${src:lo16}\n\tmovt${p} $dst, ${src:hi16}",
index f0be545d84749bffa3ce9a17a451645320d21894..446287d1f38399de3d138c34fddbdc97bbb75a20 100644 (file)
@@ -1375,6 +1375,45 @@ void ARMAsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI) {
     
     return;
   }
+  case ARM::MOVi2pieces: { // FIXME: Remove asmstring from td file.
+    // This is a hack that lowers as a two instruction sequence.
+    unsigned DstReg = MI->getOperand(0).getReg();
+    unsigned ImmVal = (unsigned)MI->getOperand(1).getImm();
+
+    unsigned SOImmValV1 = ARM_AM::getSOImmTwoPartFirst(ImmVal);
+    unsigned SOImmValV2 = ARM_AM::getSOImmTwoPartSecond(ImmVal);
+    
+    {
+      MCInst TmpInst;
+      TmpInst.setOpcode(ARM::MOVi);
+      TmpInst.addOperand(MCOperand::CreateReg(DstReg));
+      TmpInst.addOperand(MCOperand::CreateImm(SOImmValV1));
+      
+      // Predicate.
+      TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
+      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
+      printMCInst(&TmpInst);
+      O << '\n';
+    }
+
+    {
+      MCInst TmpInst;
+      TmpInst.setOpcode(ARM::ORRri);
+      TmpInst.addOperand(MCOperand::CreateReg(DstReg));     // dstreg
+      TmpInst.addOperand(MCOperand::CreateReg(DstReg));     // inreg
+      TmpInst.addOperand(MCOperand::CreateImm(SOImmValV2)); // so_imm
+      // Predicate.
+      TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
+      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
+      
+      TmpInst.addOperand(MCOperand::CreateReg(0));          // cc_out
+      printMCInst(&TmpInst);
+    }
+    return; 
+  }
+      // FIXME: Also MOVi32imm.
+
+      
   }
       
   MCInst TmpInst;
index b227baec62a6f61147e673b6e09475851ebe00f2..abb0399fa456590dced56748f78f47f7cc2377e8 100644 (file)
@@ -79,6 +79,37 @@ void ARMInstPrinter::printSOImmOperand(const MCInst *MI, unsigned OpNum) {
   printSOImm(O, MO.getImm(), VerboseAsm, &MAI);
 }
 
+/// printSOImm2PartOperand - SOImm is broken into two pieces using a 'mov'
+/// followed by an 'orr' to materialize.
+void ARMInstPrinter::printSOImm2PartOperand(const MCInst *MI, unsigned OpNum) {
+  // FIXME: REMOVE this method.
+  abort();
+}
+
+// so_reg is a 4-operand unit corresponding to register forms of the A5.1
+// "Addressing Mode 1 - Data-processing operands" forms.  This includes:
+//    REG 0   0           - e.g. R5
+//    REG REG 0,SH_OPC    - e.g. R5, ROR R3
+//    REG 0   IMM,SH_OPC  - e.g. R5, LSL #3
+void ARMInstPrinter::printSORegOperand(const MCInst *MI, unsigned OpNum) {
+  const MCOperand &MO1 = MI->getOperand(OpNum);
+  const MCOperand &MO2 = MI->getOperand(OpNum+1);
+  const MCOperand &MO3 = MI->getOperand(OpNum+2);
+  
+  O << getRegisterName(MO1.getReg());
+  
+  // Print the shift opc.
+  O << ", "
+    << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3.getImm()))
+    << ' ';
+  
+  if (MO2.getReg()) {
+    O << getRegisterName(MO2.getReg());
+    assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
+  } else {
+    O << "#" << ARM_AM::getSORegOffset(MO3.getImm());
+  }
+}
 
 
 void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op) {
index 41e59e9937c01eded2696763fd3222020b109d41..99388e0d6c567098696b357e56751b7a6b7db604 100644 (file)
@@ -36,10 +36,9 @@ public:
                     const char *Modifier = 0);
     
   void printSOImmOperand(const MCInst *MI, unsigned OpNum);
+  void printSOImm2PartOperand(const MCInst *MI, unsigned OpNum);
   
-  
-  void printSOImm2PartOperand(const MCInst *MI, unsigned OpNum) {}
-  void printSORegOperand(const MCInst *MI, unsigned OpNum) {}
+  void printSORegOperand(const MCInst *MI, unsigned OpNum);
   void printAddrMode2Operand(const MCInst *MI, unsigned OpNum);
   void printAddrMode2OffsetOperand(const MCInst *MI, unsigned OpNum) {}
   void printAddrMode3Operand(const MCInst *MI, unsigned OpNum) {}