[llvm-commits] [patch] add support for a movi32 of a symbol to the ARM MC asm printer

Rafael Espindola espindola at google.com
Sat May 8 19:11:41 PDT 2010


The attached patch implements support in the new ARM MC asm printer
for a movi32 of a global. Previously only constants were supported.
With this patch "llc -enable-arm-mcinst-printer" works on

--------------------------------------------
target triple = "armv7-unknown-linux-gnueabi"
@.str = private constant [4 x i8] c"%d\0A\00"     ; <[4 x i8]*> [#uses=1]
define i32 @main() nounwind optsize {
entry:
  %call = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds
([4 x i8]* @.str, i32 0, i32 0), i32 1001) nounwind optsize ; <i32>
[#uses=0]
  ret i32 0
}
declare i32 @printf(i8* nocapture, ...) nounwind optsize
------------------------------------------------

I find it strange that I have to define a new instruction just to use
a modifier. Should I try to add VK_LOWER16 and VK_HIGH16 to
VariantKind instead?

Cheers,
-- 
Rafael Ávila de Espíndola
-------------- next part --------------
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td
index 6540497..d11b947 100644
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -1417,6 +1417,16 @@ def MOVi16 : AI1<0b1000, (outs GPR:$dst), (ins i32imm:$src),
   let Inst{25} = 1;
 }
 
+def MOVi16lo16 : AI1<0b1000, (outs GPR:$dst), (ins i32imm:$src),
+                     Pseudo, IIC_iMOVi,
+                     "movw", "\t$dst, ${src:lo16}",
+                     []>,
+                     Requires<[IsARM, HasV6T2]> {
+  let Inst{20} = 0;
+  let Inst{25} = 1;
+}
+
+
 let Constraints = "$src = $dst" in
 def MOVTi16 : AI1<0b1010, (outs GPR:$dst), (ins GPR:$src, i32imm:$imm),
                   DPFrm, IIC_iMOVi,
@@ -1429,6 +1439,16 @@ def MOVTi16 : AI1<0b1010, (outs GPR:$dst), (ins GPR:$src, i32imm:$imm),
   let Inst{25} = 1;
 }
 
+let Constraints = "$src = $dst" in
+def MOVTi16hi16 : AI1<0b1010, (outs GPR:$dst), (ins GPR:$src, i32imm:$imm),
+                      Pseudo, IIC_iMOVi,
+                      "movt", "\t$dst, ${imm:hi16}",
+                      []>,
+                      Requires<[IsARM, HasV6T2]> {
+  let Inst{20} = 0;
+  let Inst{25} = 1;
+}
+
 def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
       Requires<[IsARM, HasV6T2]>;
 
diff --git a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
index 80a9d2d..8b37cc7 100644
--- a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
+++ b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
@@ -1375,13 +1375,30 @@ void ARMAsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI) {
   case ARM::MOVi32imm: { // 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();
-    
+    const MachineOperand &MO = MI->getOperand(1);
+    MCOperand V1, V2;
+    unsigned Opcode1, Opcode2;
+    if (MO.isImm()) {
+      unsigned ImmVal = (unsigned)MI->getOperand(1).getImm();
+      Opcode1 = ARM::MOVi16;
+      Opcode2 = ARM::MOVTi16;
+      V1 = MCOperand::CreateImm(ImmVal & 65535);
+      V2 = MCOperand::CreateImm(ImmVal >> 16);
+    } else if (MO.isGlobal()) {
+      MCSymbol *Symbol = MCInstLowering.GetGlobalAddressSymbol(MO);
+      Opcode1 = ARM::MOVi16lo16;
+      Opcode2 = ARM::MOVTi16hi16;
+      V1 = V2 = MCInstLowering.LowerSymbolOperand(MO, Symbol);
+    }else {
+      MI->dump();
+      llvm_unreachable("cannot handle this operand");
+    }
+
     {
       MCInst TmpInst;
-      TmpInst.setOpcode(ARM::MOVi16);
+      TmpInst.setOpcode(Opcode1);
       TmpInst.addOperand(MCOperand::CreateReg(DstReg));         // dstreg
-      TmpInst.addOperand(MCOperand::CreateImm(ImmVal & 65535)); // lower16(imm)
+      TmpInst.addOperand(V1); // lower16(imm)
       
       // Predicate.
       TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
@@ -1392,10 +1409,10 @@ void ARMAsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI) {
     
     {
       MCInst TmpInst;
-      TmpInst.setOpcode(ARM::MOVTi16);
+      TmpInst.setOpcode(Opcode2);
       TmpInst.addOperand(MCOperand::CreateReg(DstReg));         // dstreg
       TmpInst.addOperand(MCOperand::CreateReg(DstReg));         // srcreg
-      TmpInst.addOperand(MCOperand::CreateImm(ImmVal >> 16));   // upper16(imm)
+      TmpInst.addOperand(V2);   // upper16(imm)
       
       // Predicate.
       TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
diff --git a/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp b/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp
index ac6331f..edda7ff 100644
--- a/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp
+++ b/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp
@@ -217,7 +217,17 @@ void ARMInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
            ((Modifier == 0 || Modifier[0] == 0) && "No modifiers supported"));
     O << '#' << Op.getImm();
   } else {
-    assert((Modifier == 0 || Modifier[0] == 0) && "No modifiers supported");
+    if (Modifier && Modifier[0] != 0) {
+      if (strcmp(Modifier, "lo16") == 0) {
+        O << ":lower16:";
+      } else if (strcmp(Modifier, "hi16") == 0) {
+        O << ":upper16:";
+      } else if (strcmp(Modifier, "call") == 0) {
+        // Nothing.
+      } else {
+        llvm_unreachable("Unsupported modifier");
+      }
+    }
     assert(Op.isExpr() && "unknown operand kind in printOperand");
     O << *Op.getExpr();
   }


More information about the llvm-commits mailing list