diff --git a/llvm/lib/Target/MSP430/MSP430AsmPrinter.cpp b/llvm/lib/Target/MSP430/MSP430AsmPrinter.cpp --- a/llvm/lib/Target/MSP430/MSP430AsmPrinter.cpp +++ b/llvm/lib/Target/MSP430/MSP430AsmPrinter.cpp @@ -47,8 +47,8 @@ bool runOnMachineFunction(MachineFunction &MF) override; - void printOperand(const MachineInstr *MI, int OpNum, - raw_ostream &O, const char* Modifier = nullptr); + void PrintGlobalOperand(const MachineOperand &MO, raw_ostream &O); + void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O); void printSrcMemOperand(const MachineInstr *MI, int OpNum, raw_ostream &O); bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, @@ -61,9 +61,21 @@ }; } // end of anonymous namespace +void MSP430AsmPrinter::PrintGlobalOperand(const MachineOperand &MO, + raw_ostream &O) { + assert(MO.getType() == MachineOperand::MO_GlobalAddress); + uint64_t Offset = MO.getOffset(); + if (Offset) + O << '(' << Offset << '+'; + + getSymbol(MO.getGlobal())->print(O, MAI); + + if (Offset) + O << ')'; +} void MSP430AsmPrinter::printOperand(const MachineInstr *MI, int OpNum, - raw_ostream &O, const char *Modifier) { + raw_ostream &O) { const MachineOperand &MO = MI->getOperand(OpNum); switch (MO.getType()) { default: llvm_unreachable("Not implemented yet!"); @@ -71,33 +83,20 @@ O << MSP430InstPrinter::getRegisterName(MO.getReg()); return; case MachineOperand::MO_Immediate: - if (!Modifier || strcmp(Modifier, "nohash")) - O << '#'; - O << MO.getImm(); + O << '#' << MO.getImm(); return; case MachineOperand::MO_MachineBasicBlock: MO.getMBB()->getSymbol()->print(O, MAI); return; case MachineOperand::MO_GlobalAddress: { - bool isMemOp = Modifier && !strcmp(Modifier, "mem"); - uint64_t Offset = MO.getOffset(); - // If the global address expression is a part of displacement field with a // register base, we should not emit any prefix symbol here, e.g. // mov.w &foo, r1 // vs // mov.w glb(r1), r2 // Otherwise (!) msp430-as will silently miscompile the output :( - if (!Modifier || strcmp(Modifier, "nohash")) - O << (isMemOp ? '&' : '#'); - if (Offset) - O << '(' << Offset << '+'; - - getSymbol(MO.getGlobal())->print(O, MAI); - - if (Offset) - O << ')'; - + O << '#'; + PrintGlobalOperand(MO, O); return; } } @@ -110,10 +109,15 @@ // Print displacement first - // Imm here is in fact global address - print extra modifier. - if (Disp.isImm() && Base.getReg() == MSP430::SR) - O << '&'; - printOperand(MI, OpNum+1, O, "nohash"); + if (Disp.isImm()) { + // Imm here is in fact global address - print extra modifier. + if (Base.getReg() == MSP430::SR) + O << '&'; + O << Disp.getImm(); + } else if (Disp.isGlobal()) + PrintGlobalOperand(Disp, O); + else + printOperand(MI, OpNum + 1, O); // Print register base field if (Base.getReg() != MSP430::SR && Base.getReg() != MSP430::PC) { diff --git a/llvm/test/CodeGen/MSP430/inline-asm-absolute-addressing.ll b/llvm/test/CodeGen/MSP430/inline-asm-absolute-addressing.ll --- a/llvm/test/CodeGen/MSP430/inline-asm-absolute-addressing.ll +++ b/llvm/test/CodeGen/MSP430/inline-asm-absolute-addressing.ll @@ -13,3 +13,47 @@ call void asm sideeffect "mov r1, $0", "*m"(i8* inttoptr (i16 256 to i8*)) ret void } + +@baz = internal global i32 0, align 4 + +; CHECK-LABEL: foo +; CHECK: mov &baz, r1 +define dso_local void @foo() { + call void asm sideeffect "mov.w &baz, r1", ""() + ret void +} + +; CHECK-LABEL: bar +; CHECK: mov baz(r1), r2 +define dso_local void @bar() { + call void asm sideeffect "mov.w baz(r1), r2", ""() + ret void +} + +; CHECK-LABEL: quux +; CHECK: mov #baz, r1 +define dso_local void @quux() { + call void asm sideeffect "mov.w #baz, r1", ""() + ret void +} + +; CHECK-LABEL: foobar +; CHECK: mov #baz, r1 +define dso_local void @foobar() { + call void asm sideeffect "mov.w $0, r1", "i"(i32* nonnull @baz) + ret void +} + +; CHECK-LABEL: foobarbaz +; CHECK: call #foobar +define dso_local void @foobarbaz() { + call void asm sideeffect "call #foobar", ""() + ret void +} + +; CHECK-LABEL: foobarbazquux +; CHECK: mov #baz, 0(r1) +define dso_local void @foobarbazquux() { + call void asm sideeffect "mov.w $0, r1", "m"(i32* nonnull @baz) + ret void +}