[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