mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
[AsmPrinter] refactor to support %c w/ GlobalAddress'
Summary: Targets like ARM, MSP430, PPC, and SystemZ have complex behavior when printing the address of a MachineOperand::MO_GlobalAddress. Move that handling into a new overriden method in each base class. A virtual method was added to the base class for handling the generic case. Refactors a few subclasses to support the target independent %a, %c, and %n. The patch also contains small cleanups for AVRAsmPrinter and SystemZAsmPrinter. It seems that NVPTXTargetLowering is possibly missing some logic to transform GlobalAddressSDNodes for TargetLowering::LowerAsmOperandForConstraint to handle with "i" extended inline assembly asm constraints. Fixes: - https://bugs.llvm.org/show_bug.cgi?id=41402 - https://github.com/ClangBuiltLinux/linux/issues/449 Reviewers: echristo, void Reviewed By: void Subscribers: void, craig.topper, jholewinski, dschuff, jyknight, dylanmckay, sdardis, nemanjai, javed.absar, sbc100, jgravelle-google, eraman, kristof.beyls, hiraditya, aheejin, kbarton, fedor.sergeev, jrtc27, atanasyan, jsji, llvm-commits, kees, tpimh, nathanchance, peter.smith, srhines Tags: #llvm Differential Revision: https://reviews.llvm.org/D60887 llvm-svn: 359337
This commit is contained in:
parent
18bf91733a
commit
02a0e7f7fc
@ -590,6 +590,10 @@ public:
|
|||||||
virtual void PrintSpecial(const MachineInstr *MI, raw_ostream &OS,
|
virtual void PrintSpecial(const MachineInstr *MI, raw_ostream &OS,
|
||||||
const char *Code) const;
|
const char *Code) const;
|
||||||
|
|
||||||
|
/// Print the MachineOperand as a symbol. Targets with complex handling of
|
||||||
|
/// symbol references should override the base implementation.
|
||||||
|
virtual void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &OS);
|
||||||
|
|
||||||
/// Print the specified operand of MI, an INLINEASM instruction, using the
|
/// Print the specified operand of MI, an INLINEASM instruction, using the
|
||||||
/// specified assembler variant. Targets should override this to format as
|
/// specified assembler variant. Targets should override this to format as
|
||||||
/// appropriate. This method can return true if the operand is erroneous.
|
/// appropriate. This method can return true if the operand is erroneous.
|
||||||
|
@ -599,6 +599,12 @@ void AsmPrinter::PrintSpecial(const MachineInstr *MI, raw_ostream &OS,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AsmPrinter::PrintSymbolOperand(const MachineOperand &MO, raw_ostream &OS) {
|
||||||
|
assert(MO.isGlobal() && "caller should check MO.isGlobal");
|
||||||
|
getSymbol(MO.getGlobal())->print(OS, MAI);
|
||||||
|
printOffset(MO.getOffset(), OS);
|
||||||
|
}
|
||||||
|
|
||||||
/// PrintAsmOperand - Print the specified operand of MI, an INLINEASM
|
/// PrintAsmOperand - Print the specified operand of MI, an INLINEASM
|
||||||
/// instruction, using the specified assembler variant. Targets should
|
/// instruction, using the specified assembler variant. Targets should
|
||||||
/// override this to format as appropriate for machine specific ExtraCodes
|
/// override this to format as appropriate for machine specific ExtraCodes
|
||||||
@ -621,10 +627,15 @@ bool AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
|
|||||||
}
|
}
|
||||||
LLVM_FALLTHROUGH; // GCC allows '%a' to behave like '%c' with immediates.
|
LLVM_FALLTHROUGH; // GCC allows '%a' to behave like '%c' with immediates.
|
||||||
case 'c': // Substitute immediate value without immediate syntax
|
case 'c': // Substitute immediate value without immediate syntax
|
||||||
if (!MO.isImm())
|
if (MO.isImm()) {
|
||||||
return true;
|
O << MO.getImm();
|
||||||
O << MO.getImm();
|
return false;
|
||||||
return false;
|
}
|
||||||
|
if (MO.isGlobal()) {
|
||||||
|
PrintSymbolOperand(MO, O);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
case 'n': // Negate the immediate constant.
|
case 'n': // Negate the immediate constant.
|
||||||
if (!MO.isImm())
|
if (!MO.isImm())
|
||||||
return true;
|
return true;
|
||||||
|
@ -436,14 +436,7 @@ void AArch64AsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNum,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MachineOperand::MO_GlobalAddress: {
|
case MachineOperand::MO_GlobalAddress: {
|
||||||
const GlobalValue *GV = MO.getGlobal();
|
PrintSymbolOperand(MO, O);
|
||||||
MCSymbol *Sym = getSymbol(GV);
|
|
||||||
|
|
||||||
// FIXME: Can we get anything other than a plain symbol here?
|
|
||||||
assert(!MO.getTargetFlags() && "Unknown operand target flag!");
|
|
||||||
|
|
||||||
Sym->print(O, MAI);
|
|
||||||
printOffset(MO.getOffset(), O);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MachineOperand::MO_BlockAddress: {
|
case MachineOperand::MO_BlockAddress: {
|
||||||
|
@ -183,10 +183,21 @@ bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ARMAsmPrinter::PrintSymbolOperand(const MachineOperand &MO,
|
||||||
|
raw_ostream &O) {
|
||||||
|
assert(MO.isGlobal() && "caller should check MO.isGlobal");
|
||||||
|
unsigned TF = MO.getTargetFlags();
|
||||||
|
if (TF & ARMII::MO_LO16)
|
||||||
|
O << ":lower16:";
|
||||||
|
else if (TF & ARMII::MO_HI16)
|
||||||
|
O << ":upper16:";
|
||||||
|
GetARMGVSymbol(MO.getGlobal(), TF)->print(O, MAI);
|
||||||
|
printOffset(MO.getOffset(), O);
|
||||||
|
}
|
||||||
|
|
||||||
void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
|
void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
|
||||||
raw_ostream &O) {
|
raw_ostream &O) {
|
||||||
const MachineOperand &MO = MI->getOperand(OpNum);
|
const MachineOperand &MO = MI->getOperand(OpNum);
|
||||||
unsigned TF = MO.getTargetFlags();
|
|
||||||
|
|
||||||
switch (MO.getType()) {
|
switch (MO.getType()) {
|
||||||
default: llvm_unreachable("<unknown operand type>");
|
default: llvm_unreachable("<unknown operand type>");
|
||||||
@ -203,27 +214,20 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MachineOperand::MO_Immediate: {
|
case MachineOperand::MO_Immediate: {
|
||||||
int64_t Imm = MO.getImm();
|
|
||||||
O << '#';
|
O << '#';
|
||||||
|
unsigned TF = MO.getTargetFlags();
|
||||||
if (TF == ARMII::MO_LO16)
|
if (TF == ARMII::MO_LO16)
|
||||||
O << ":lower16:";
|
O << ":lower16:";
|
||||||
else if (TF == ARMII::MO_HI16)
|
else if (TF == ARMII::MO_HI16)
|
||||||
O << ":upper16:";
|
O << ":upper16:";
|
||||||
O << Imm;
|
O << MO.getImm();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MachineOperand::MO_MachineBasicBlock:
|
case MachineOperand::MO_MachineBasicBlock:
|
||||||
MO.getMBB()->getSymbol()->print(O, MAI);
|
MO.getMBB()->getSymbol()->print(O, MAI);
|
||||||
return;
|
return;
|
||||||
case MachineOperand::MO_GlobalAddress: {
|
case MachineOperand::MO_GlobalAddress: {
|
||||||
const GlobalValue *GV = MO.getGlobal();
|
PrintSymbolOperand(MO, O);
|
||||||
if (TF & ARMII::MO_LO16)
|
|
||||||
O << ":lower16:";
|
|
||||||
else if (TF & ARMII::MO_HI16)
|
|
||||||
O << ":upper16:";
|
|
||||||
GetARMGVSymbol(GV, TF)->print(O, MAI);
|
|
||||||
|
|
||||||
printOffset(MO.getOffset(), O);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MachineOperand::MO_ConstantPoolIndex:
|
case MachineOperand::MO_ConstantPoolIndex:
|
||||||
|
@ -75,6 +75,7 @@ public:
|
|||||||
|
|
||||||
void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O);
|
void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O);
|
||||||
|
|
||||||
|
void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &O) override;
|
||||||
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
|
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
|
||||||
const char *ExtraCode, raw_ostream &O) override;
|
const char *ExtraCode, raw_ostream &O) override;
|
||||||
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum,
|
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum,
|
||||||
|
@ -42,8 +42,7 @@ public:
|
|||||||
|
|
||||||
StringRef getPassName() const override { return "AVR Assembly Printer"; }
|
StringRef getPassName() const override { return "AVR Assembly Printer"; }
|
||||||
|
|
||||||
void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O,
|
void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
|
||||||
const char *Modifier = 0);
|
|
||||||
|
|
||||||
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
|
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
|
||||||
const char *ExtraCode, raw_ostream &O) override;
|
const char *ExtraCode, raw_ostream &O) override;
|
||||||
@ -58,7 +57,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
void AVRAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
|
void AVRAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
|
||||||
raw_ostream &O, const char *Modifier) {
|
raw_ostream &O) {
|
||||||
const MachineOperand &MO = MI->getOperand(OpNo);
|
const MachineOperand &MO = MI->getOperand(OpNo);
|
||||||
|
|
||||||
switch (MO.getType()) {
|
switch (MO.getType()) {
|
||||||
|
@ -104,7 +104,7 @@ void BPFAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
|
|||||||
bool BPFAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
|
bool BPFAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
|
||||||
const char *ExtraCode, raw_ostream &O) {
|
const char *ExtraCode, raw_ostream &O) {
|
||||||
if (ExtraCode && ExtraCode[0])
|
if (ExtraCode && ExtraCode[0])
|
||||||
return true; // BPF does not have special modifiers
|
return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O);
|
||||||
|
|
||||||
printOperand(MI, OpNo, O);
|
printOperand(MI, OpNo, O);
|
||||||
return false;
|
return false;
|
||||||
|
@ -91,9 +91,7 @@ void HexagonAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
|
|||||||
GetCPISymbol(MO.getIndex())->print(O, MAI);
|
GetCPISymbol(MO.getIndex())->print(O, MAI);
|
||||||
return;
|
return;
|
||||||
case MachineOperand::MO_GlobalAddress:
|
case MachineOperand::MO_GlobalAddress:
|
||||||
// Computing the address of a global symbol, not calling it.
|
PrintSymbolOperand(MO, O);
|
||||||
getSymbol(MO.getGlobal())->print(O, MAI);
|
|
||||||
printOffset(MO.getOffset(), O);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -136,7 +136,7 @@ bool LanaiAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return true; // Unknown modifier.
|
return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printOperand(MI, OpNo, O);
|
printOperand(MI, OpNo, O);
|
||||||
|
@ -47,6 +47,7 @@ namespace {
|
|||||||
|
|
||||||
bool runOnMachineFunction(MachineFunction &MF) override;
|
bool runOnMachineFunction(MachineFunction &MF) override;
|
||||||
|
|
||||||
|
void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &O) override;
|
||||||
void printOperand(const MachineInstr *MI, int OpNum,
|
void printOperand(const MachineInstr *MI, int OpNum,
|
||||||
raw_ostream &O, const char* Modifier = nullptr);
|
raw_ostream &O, const char* Modifier = nullptr);
|
||||||
void printSrcMemOperand(const MachineInstr *MI, int OpNum,
|
void printSrcMemOperand(const MachineInstr *MI, int OpNum,
|
||||||
@ -61,6 +62,17 @@ namespace {
|
|||||||
};
|
};
|
||||||
} // end of anonymous namespace
|
} // end of anonymous namespace
|
||||||
|
|
||||||
|
void MSP430AsmPrinter::PrintSymbolOperand(const MachineOperand &MO,
|
||||||
|
raw_ostream &O) {
|
||||||
|
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,
|
void MSP430AsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
|
||||||
raw_ostream &O, const char *Modifier) {
|
raw_ostream &O, const char *Modifier) {
|
||||||
@ -79,25 +91,13 @@ void MSP430AsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
|
|||||||
MO.getMBB()->getSymbol()->print(O, MAI);
|
MO.getMBB()->getSymbol()->print(O, MAI);
|
||||||
return;
|
return;
|
||||||
case MachineOperand::MO_GlobalAddress: {
|
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
|
// 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.
|
// register base, we should not emit any prefix symbol here, e.g.
|
||||||
// mov.w &foo, r1
|
|
||||||
// vs
|
|
||||||
// mov.w glb(r1), r2
|
// mov.w glb(r1), r2
|
||||||
// Otherwise (!) msp430-as will silently miscompile the output :(
|
// Otherwise (!) msp430-as will silently miscompile the output :(
|
||||||
if (!Modifier || strcmp(Modifier, "nohash"))
|
if (!Modifier || strcmp(Modifier, "nohash"))
|
||||||
O << (isMemOp ? '&' : '#');
|
O << '#';
|
||||||
if (Offset)
|
PrintSymbolOperand(MO, O);
|
||||||
O << '(' << Offset << '+';
|
|
||||||
|
|
||||||
getSymbol(MO.getGlobal())->print(O, MAI);
|
|
||||||
|
|
||||||
if (Offset)
|
|
||||||
O << ')';
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -129,7 +129,7 @@ bool MSP430AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
|
|||||||
const char *ExtraCode, raw_ostream &O) {
|
const char *ExtraCode, raw_ostream &O) {
|
||||||
// Does this asm operand have a single letter operand modifier?
|
// Does this asm operand have a single letter operand modifier?
|
||||||
if (ExtraCode && ExtraCode[0])
|
if (ExtraCode && ExtraCode[0])
|
||||||
return true; // Unknown modifier.
|
return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O);
|
||||||
|
|
||||||
printOperand(MI, OpNo, O);
|
printOperand(MI, OpNo, O);
|
||||||
return false;
|
return false;
|
||||||
|
@ -692,7 +692,7 @@ void MipsAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
case MachineOperand::MO_GlobalAddress:
|
case MachineOperand::MO_GlobalAddress:
|
||||||
getSymbol(MO.getGlobal())->print(O, MAI);
|
PrintSymbolOperand(MO, O);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MachineOperand::MO_BlockAddress: {
|
case MachineOperand::MO_BlockAddress: {
|
||||||
|
@ -2230,7 +2230,7 @@ void NVPTXAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case MachineOperand::MO_GlobalAddress:
|
case MachineOperand::MO_GlobalAddress:
|
||||||
getSymbol(MO.getGlobal())->print(O, MAI);
|
PrintSymbolOperand(MO, O);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MachineOperand::MO_MachineBasicBlock:
|
case MachineOperand::MO_MachineBasicBlock:
|
||||||
|
@ -101,6 +101,7 @@ public:
|
|||||||
/// The \p MI would be INLINEASM ONLY.
|
/// The \p MI would be INLINEASM ONLY.
|
||||||
void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
|
void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
|
||||||
|
|
||||||
|
void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &O) override;
|
||||||
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
|
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
|
||||||
const char *ExtraCode, raw_ostream &O) override;
|
const char *ExtraCode, raw_ostream &O) override;
|
||||||
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
|
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
|
||||||
@ -158,6 +159,30 @@ public:
|
|||||||
|
|
||||||
} // end anonymous namespace
|
} // end anonymous namespace
|
||||||
|
|
||||||
|
void PPCAsmPrinter::PrintSymbolOperand(const MachineOperand &MO,
|
||||||
|
raw_ostream &O) {
|
||||||
|
// Computing the address of a global symbol, not calling it.
|
||||||
|
const GlobalValue *GV = MO.getGlobal();
|
||||||
|
MCSymbol *SymToPrint;
|
||||||
|
|
||||||
|
// External or weakly linked global variables need non-lazily-resolved stubs
|
||||||
|
if (Subtarget->hasLazyResolverStub(GV)) {
|
||||||
|
SymToPrint = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
|
||||||
|
MachineModuleInfoImpl::StubValueTy &StubSym =
|
||||||
|
MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(
|
||||||
|
SymToPrint);
|
||||||
|
if (!StubSym.getPointer())
|
||||||
|
StubSym = MachineModuleInfoImpl::StubValueTy(getSymbol(GV),
|
||||||
|
!GV->hasInternalLinkage());
|
||||||
|
} else {
|
||||||
|
SymToPrint = getSymbol(GV);
|
||||||
|
}
|
||||||
|
|
||||||
|
SymToPrint->print(O, MAI);
|
||||||
|
|
||||||
|
printOffset(MO.getOffset(), O);
|
||||||
|
}
|
||||||
|
|
||||||
void PPCAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
|
void PPCAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
|
||||||
raw_ostream &O) {
|
raw_ostream &O) {
|
||||||
const DataLayout &DL = getDataLayout();
|
const DataLayout &DL = getDataLayout();
|
||||||
@ -190,26 +215,7 @@ void PPCAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
|
|||||||
GetBlockAddressSymbol(MO.getBlockAddress())->print(O, MAI);
|
GetBlockAddressSymbol(MO.getBlockAddress())->print(O, MAI);
|
||||||
return;
|
return;
|
||||||
case MachineOperand::MO_GlobalAddress: {
|
case MachineOperand::MO_GlobalAddress: {
|
||||||
// Computing the address of a global symbol, not calling it.
|
PrintSymbolOperand(MO, O);
|
||||||
const GlobalValue *GV = MO.getGlobal();
|
|
||||||
MCSymbol *SymToPrint;
|
|
||||||
|
|
||||||
// External or weakly linked global variables need non-lazily-resolved stubs
|
|
||||||
if (Subtarget->hasLazyResolverStub(GV)) {
|
|
||||||
SymToPrint = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
|
|
||||||
MachineModuleInfoImpl::StubValueTy &StubSym =
|
|
||||||
MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(
|
|
||||||
SymToPrint);
|
|
||||||
if (!StubSym.getPointer())
|
|
||||||
StubSym = MachineModuleInfoImpl::StubValueTy(getSymbol(GV),
|
|
||||||
!GV->hasInternalLinkage());
|
|
||||||
} else {
|
|
||||||
SymToPrint = getSymbol(GV);
|
|
||||||
}
|
|
||||||
|
|
||||||
SymToPrint->print(O, MAI);
|
|
||||||
|
|
||||||
printOffset(MO.getOffset(), O);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -357,7 +357,7 @@ void SparcAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
|
|||||||
MO.getMBB()->getSymbol()->print(O, MAI);
|
MO.getMBB()->getSymbol()->print(O, MAI);
|
||||||
return;
|
return;
|
||||||
case MachineOperand::MO_GlobalAddress:
|
case MachineOperand::MO_GlobalAddress:
|
||||||
getSymbol(MO.getGlobal())->print(O, MAI);
|
PrintSymbolOperand(MO, O);
|
||||||
break;
|
break;
|
||||||
case MachineOperand::MO_BlockAddress:
|
case MachineOperand::MO_BlockAddress:
|
||||||
O << GetBlockAddressSymbol(MO.getBlockAddress())->getName();
|
O << GetBlockAddressSymbol(MO.getBlockAddress())->getName();
|
||||||
|
@ -620,15 +620,11 @@ EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
|
|||||||
bool SystemZAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
|
bool SystemZAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
|
||||||
const char *ExtraCode,
|
const char *ExtraCode,
|
||||||
raw_ostream &OS) {
|
raw_ostream &OS) {
|
||||||
if (ExtraCode && *ExtraCode == 'n') {
|
if (ExtraCode)
|
||||||
if (!MI->getOperand(OpNo).isImm())
|
return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS);
|
||||||
return true;
|
SystemZMCInstLower Lower(MF->getContext(), *this);
|
||||||
OS << -int64_t(MI->getOperand(OpNo).getImm());
|
MCOperand MO(Lower.lowerOperand(MI->getOperand(OpNo)));
|
||||||
} else {
|
SystemZInstPrinter::printOperand(MO, MAI, OS);
|
||||||
SystemZMCInstLower Lower(MF->getContext(), *this);
|
|
||||||
MCOperand MO(Lower.lowerOperand(MI->getOperand(OpNo)));
|
|
||||||
SystemZInstPrinter::printOperand(MO, MAI, OS);
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -407,8 +407,7 @@ bool WebAssemblyAsmPrinter::PrintAsmOperand(const MachineInstr *MI,
|
|||||||
OS << regToString(MO);
|
OS << regToString(MO);
|
||||||
return false;
|
return false;
|
||||||
case MachineOperand::MO_GlobalAddress:
|
case MachineOperand::MO_GlobalAddress:
|
||||||
getSymbol(MO.getGlobal())->print(OS, MAI);
|
PrintSymbolOperand(MO, OS);
|
||||||
printOffset(MO.getOffset(), OS);
|
|
||||||
return false;
|
return false;
|
||||||
case MachineOperand::MO_ExternalSymbol:
|
case MachineOperand::MO_ExternalSymbol:
|
||||||
GetExternalSymbolSymbol(MO.getSymbolName())->print(OS, MAI);
|
GetExternalSymbolSymbol(MO.getSymbolName())->print(OS, MAI);
|
||||||
|
@ -299,6 +299,7 @@ void X86AsmPrinter::PrintLeaMemReference(const MachineInstr *MI, unsigned OpNo,
|
|||||||
case MachineOperand::MO_GlobalAddress:
|
case MachineOperand::MO_GlobalAddress:
|
||||||
case MachineOperand::MO_ConstantPoolIndex:
|
case MachineOperand::MO_ConstantPoolIndex:
|
||||||
PrintSymbolOperand(DispSpec, O);
|
PrintSymbolOperand(DispSpec, O);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Modifier && strcmp(Modifier, "H") == 0)
|
if (Modifier && strcmp(Modifier, "H") == 0)
|
||||||
|
@ -102,7 +102,7 @@ class LLVM_LIBRARY_VISIBILITY X86AsmPrinter : public AsmPrinter {
|
|||||||
// Choose between emitting .seh_ directives and .cv_fpo_ directives.
|
// Choose between emitting .seh_ directives and .cv_fpo_ directives.
|
||||||
void EmitSEHInstruction(const MachineInstr *MI);
|
void EmitSEHInstruction(const MachineInstr *MI);
|
||||||
|
|
||||||
void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &O);
|
void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &O) override;
|
||||||
void PrintOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
|
void PrintOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
|
||||||
void PrintModifiedOperand(const MachineInstr *MI, unsigned OpNo,
|
void PrintModifiedOperand(const MachineInstr *MI, unsigned OpNo,
|
||||||
raw_ostream &O, const char *Modifier);
|
raw_ostream &O, const char *Modifier);
|
||||||
|
@ -213,7 +213,7 @@ void XCoreAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
|
|||||||
MO.getMBB()->getSymbol()->print(O, MAI);
|
MO.getMBB()->getSymbol()->print(O, MAI);
|
||||||
break;
|
break;
|
||||||
case MachineOperand::MO_GlobalAddress:
|
case MachineOperand::MO_GlobalAddress:
|
||||||
getSymbol(MO.getGlobal())->print(O, MAI);
|
PrintSymbolOperand(MO, O);
|
||||||
break;
|
break;
|
||||||
case MachineOperand::MO_ConstantPoolIndex:
|
case MachineOperand::MO_ConstantPoolIndex:
|
||||||
O << DL.getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_'
|
O << DL.getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_'
|
||||||
|
27
test/CodeGen/AArch64/inlineasm-output-template.ll
Normal file
27
test/CodeGen/AArch64/inlineasm-output-template.ll
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
; RUN: llc -mtriple=aarch64-linux-gnu < %s | FileCheck %s
|
||||||
|
|
||||||
|
|
||||||
|
; Test that %c works with immediates
|
||||||
|
; CHECK-LABEL: test_inlineasm_c_output_template0
|
||||||
|
; CHECK: TEST 42
|
||||||
|
define dso_local i32 @test_inlineasm_c_output_template0() {
|
||||||
|
tail call void asm sideeffect "//TEST ${0:c}", "i"(i32 42)
|
||||||
|
ret i32 42
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test that %c works with global address
|
||||||
|
; CHECK-LABEL: test_inlineasm_c_output_template1:
|
||||||
|
; CHECK: TEST {{_?}}baz
|
||||||
|
@baz = internal global i32 0, align 4
|
||||||
|
define dso_local i32 @test_inlineasm_c_output_template1() {
|
||||||
|
tail call void asm sideeffect "//TEST ${0:c}", "i"(i32* nonnull @baz)
|
||||||
|
ret i32 43
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test that %n works with immediates
|
||||||
|
; CHECK-LABEL: test_inlineasm_c_output_template2
|
||||||
|
; CHECK: TEST -42
|
||||||
|
define dso_local i32 @test_inlineasm_c_output_template2() {
|
||||||
|
tail call void asm sideeffect "//TEST ${0:n}", "i"(i32 42)
|
||||||
|
ret i32 42
|
||||||
|
}
|
@ -8,6 +8,15 @@ define dso_local i32 @test_inlineasm_c_output_template0() {
|
|||||||
ret i32 42
|
ret i32 42
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; Test that %c works with global address
|
||||||
|
; CHECK-LABEL: test_inlineasm_c_output_template2
|
||||||
|
; CHECK: @TEST baz
|
||||||
|
@baz = internal global i32 0, align 4
|
||||||
|
define dso_local i32 @test_inlineasm_c_output_template2() {
|
||||||
|
tail call void asm sideeffect "@TEST ${0:c}", "i"(i32* nonnull @baz)
|
||||||
|
ret i32 42
|
||||||
|
}
|
||||||
|
|
||||||
; Test that %n works with immediates
|
; Test that %n works with immediates
|
||||||
; CHECK-LABEL: test_inlineasm_c_output_template1
|
; CHECK-LABEL: test_inlineasm_c_output_template1
|
||||||
; CHECK: @TEST -42
|
; CHECK: @TEST -42
|
||||||
|
26
test/CodeGen/BPF/inlineasm-output-template.ll
Normal file
26
test/CodeGen/BPF/inlineasm-output-template.ll
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
; RUN: llc -mtriple=bpfel-linux-gnu < %s | FileCheck %s
|
||||||
|
|
||||||
|
; Test that %c works with immediates
|
||||||
|
; CHECK-LABEL: test_inlineasm_c_output_template0
|
||||||
|
; CHECK: #TEST 42
|
||||||
|
define dso_local i32 @test_inlineasm_c_output_template0() {
|
||||||
|
tail call void asm sideeffect "#TEST ${0:c}", "i"(i32 42)
|
||||||
|
ret i32 42
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test that %c works with global address
|
||||||
|
; CHECK-LABEL: test_inlineasm_c_output_template1
|
||||||
|
; CHECK: #TEST baz
|
||||||
|
@baz = internal global i32 0, align 4
|
||||||
|
define dso_local i32 @test_inlineasm_c_output_template1() {
|
||||||
|
tail call void asm sideeffect "#TEST ${0:c}", "i"(i32* nonnull @baz)
|
||||||
|
ret i32 42
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test that %n works with immediates
|
||||||
|
; CHECK-LABEL: test_inlineasm_c_output_template2
|
||||||
|
; CHECK: #TEST -42
|
||||||
|
define dso_local i32 @test_inlineasm_c_output_template2() {
|
||||||
|
tail call void asm sideeffect "#TEST ${0:n}", "i"(i32 42)
|
||||||
|
ret i32 42
|
||||||
|
}
|
@ -8,10 +8,19 @@ define dso_local i32 @test_inlineasm_c_output_template0() {
|
|||||||
ret i32 42
|
ret i32 42
|
||||||
}
|
}
|
||||||
|
|
||||||
; Test that %n works with immediates
|
; Test that %c works with global address
|
||||||
; CHECK-LABEL: test_inlineasm_c_output_template1
|
; CHECK-LABEL: test_inlineasm_c_output_template1:
|
||||||
; CHECK: //TEST -42
|
; CHECK: TEST {{_?}}baz
|
||||||
|
@baz = internal global i32 0, align 4
|
||||||
define dso_local i32 @test_inlineasm_c_output_template1() {
|
define dso_local i32 @test_inlineasm_c_output_template1() {
|
||||||
|
tail call void asm sideeffect "//TEST ${0:c}", "i"(i32* nonnull @baz)
|
||||||
|
ret i32 43
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test that %n works with immediates
|
||||||
|
; CHECK-LABEL: test_inlineasm_c_output_template2
|
||||||
|
; CHECK: //TEST -42
|
||||||
|
define dso_local i32 @test_inlineasm_c_output_template2() {
|
||||||
tail call void asm sideeffect "//TEST ${0:n}", "i"(i32 42)
|
tail call void asm sideeffect "//TEST ${0:n}", "i"(i32 42)
|
||||||
ret i32 42
|
ret i32 42
|
||||||
}
|
}
|
||||||
|
26
test/CodeGen/Lanai/inlineasm-output-template.ll
Normal file
26
test/CodeGen/Lanai/inlineasm-output-template.ll
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
; RUN: llc -mtriple=lanai-linux-gnueabi < %s | FileCheck %s
|
||||||
|
|
||||||
|
; Test that %c works with immediates
|
||||||
|
; CHECK-LABEL: test_inlineasm_c_output_template0
|
||||||
|
; CHECK: !TEST 42
|
||||||
|
define dso_local i32 @test_inlineasm_c_output_template0() {
|
||||||
|
tail call void asm sideeffect "!TEST ${0:c}", "i"(i32 42)
|
||||||
|
ret i32 42
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test that %c works with global address
|
||||||
|
; CHECK-LABEL: test_inlineasm_c_output_template1
|
||||||
|
; CHECK: !TEST baz
|
||||||
|
@baz = internal global i32 0, align 4
|
||||||
|
define dso_local i32 @test_inlineasm_c_output_template1() {
|
||||||
|
tail call void asm sideeffect "!TEST ${0:c}", "i"(i32* nonnull @baz)
|
||||||
|
ret i32 42
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test that %n works with immediates
|
||||||
|
; CHECK-LABEL: test_inlineasm_c_output_template2
|
||||||
|
; CHECK: !TEST -42
|
||||||
|
define dso_local i32 @test_inlineasm_c_output_template2() {
|
||||||
|
tail call void asm sideeffect "!TEST ${0:n}", "i"(i32 42)
|
||||||
|
ret i32 42
|
||||||
|
}
|
26
test/CodeGen/MSP430/inlineasm-output-template.ll
Normal file
26
test/CodeGen/MSP430/inlineasm-output-template.ll
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
; RUN: llc -mtriple=msp430-linux-gnu < %s | FileCheck %s
|
||||||
|
|
||||||
|
; Test that %c works with immediates
|
||||||
|
; CHECK-LABEL: test_inlineasm_c_output_template0
|
||||||
|
; CHECK: ;TEST 42
|
||||||
|
define dso_local i32 @test_inlineasm_c_output_template0() {
|
||||||
|
tail call void asm sideeffect ";TEST ${0:c}", "i"(i32 42)
|
||||||
|
ret i32 42
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test that %c works with global address
|
||||||
|
; CHECK-LABEL: test_inlineasm_c_output_template2
|
||||||
|
; CHECK: ;TEST baz
|
||||||
|
@baz = internal global i32 0, align 4
|
||||||
|
define dso_local i32 @test_inlineasm_c_output_template2() {
|
||||||
|
tail call void asm sideeffect ";TEST ${0:c}", "i"(i32* nonnull @baz)
|
||||||
|
ret i32 42
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test that %n works with immediates
|
||||||
|
; CHECK-LABEL: test_inlineasm_c_output_template1
|
||||||
|
; CHECK: ;TEST -42
|
||||||
|
define dso_local i32 @test_inlineasm_c_output_template1() {
|
||||||
|
tail call void asm sideeffect ";TEST ${0:n}", "i"(i32 42)
|
||||||
|
ret i32 42
|
||||||
|
}
|
26
test/CodeGen/Mips/inlineasm-output-template.ll
Normal file
26
test/CodeGen/Mips/inlineasm-output-template.ll
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
; RUN: llc -mtriple=mips64el-linux-gnu < %s | FileCheck %s
|
||||||
|
|
||||||
|
; Test that %c works with immediates
|
||||||
|
; CHECK-LABEL: test_inlineasm_c_output_template0
|
||||||
|
; CHECK: #TEST 42
|
||||||
|
define dso_local i32 @test_inlineasm_c_output_template0() {
|
||||||
|
tail call void asm sideeffect "#TEST ${0:c}", "i"(i32 42)
|
||||||
|
ret i32 42
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test that %c works with global address
|
||||||
|
; CHECK-LABEL: test_inlineasm_c_output_template1
|
||||||
|
; CHECK: #TEST baz
|
||||||
|
@baz = internal global i32 0, align 4
|
||||||
|
define dso_local i32 @test_inlineasm_c_output_template1() {
|
||||||
|
tail call void asm sideeffect "#TEST ${0:c}", "i"(i32* nonnull @baz)
|
||||||
|
ret i32 42
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test that %n works with immediates
|
||||||
|
; CHECK-LABEL: test_inlineasm_c_output_template2
|
||||||
|
; CHECK: #TEST -42
|
||||||
|
define dso_local i32 @test_inlineasm_c_output_template2() {
|
||||||
|
tail call void asm sideeffect "#TEST ${0:n}", "i"(i32 42)
|
||||||
|
ret i32 42
|
||||||
|
}
|
28
test/CodeGen/NVPTX/inlineasm-output-template.ll
Normal file
28
test/CodeGen/NVPTX/inlineasm-output-template.ll
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
; RUN: llc -march=nvptx < %s | FileCheck %s
|
||||||
|
|
||||||
|
; Test that %c works with immediates
|
||||||
|
; CHECK-LABEL: test_inlineasm_c_output_template0
|
||||||
|
; CHECK: //TEST 42
|
||||||
|
define dso_local i32 @test_inlineasm_c_output_template0() {
|
||||||
|
tail call void asm sideeffect "//TEST ${0:c}", "i"(i32 42)
|
||||||
|
ret i32 42
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test that %c works with global address
|
||||||
|
; FIXME: seems this case isn't handled properly by
|
||||||
|
; SelectionDAG TargetLowering::LowerAsmOperandForConstraint?
|
||||||
|
; check: test_inlineasm_c_output_template1
|
||||||
|
; check: //TEST baz
|
||||||
|
;@baz = internal global i32 0, align 4
|
||||||
|
;define dso_local i32 @test_inlineasm_c_output_template1() {
|
||||||
|
; tail call void asm sideeffect "//TEST ${0:c}", "i"(i32* nonnull @baz)
|
||||||
|
; ret i32 42
|
||||||
|
;}
|
||||||
|
|
||||||
|
; Test that %n works with immediates
|
||||||
|
; CHECK-LABEL: test_inlineasm_c_output_template2
|
||||||
|
; CHECK: //TEST -42
|
||||||
|
define dso_local i32 @test_inlineasm_c_output_template2() {
|
||||||
|
tail call void asm sideeffect "//TEST ${0:n}", "i"(i32 42)
|
||||||
|
ret i32 42
|
||||||
|
}
|
@ -8,10 +8,19 @@ define dso_local i32 @test_inlineasm_c_output_template0() {
|
|||||||
ret i32 42
|
ret i32 42
|
||||||
}
|
}
|
||||||
|
|
||||||
; Test that %n works with immediates
|
; Test that %c works with global address
|
||||||
; CHECK-LABEL: test_inlineasm_c_output_template1
|
; CHECK-LABEL: test_inlineasm_c_output_template1:
|
||||||
; CHECK: #TEST -42
|
; CHECK: #TEST baz
|
||||||
|
@baz = internal global i32 0, align 4
|
||||||
define dso_local i32 @test_inlineasm_c_output_template1() {
|
define dso_local i32 @test_inlineasm_c_output_template1() {
|
||||||
|
tail call void asm sideeffect "#TEST ${0:c}", "i"(i32* nonnull @baz)
|
||||||
|
ret i32 43
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test that %n works with immediates
|
||||||
|
; CHECK-LABEL: test_inlineasm_c_output_template2
|
||||||
|
; CHECK: #TEST -42
|
||||||
|
define dso_local i32 @test_inlineasm_c_output_template2() {
|
||||||
tail call void asm sideeffect "#TEST ${0:n}", "i"(i32 42)
|
tail call void asm sideeffect "#TEST ${0:n}", "i"(i32 42)
|
||||||
ret i32 42
|
ret i32 42
|
||||||
}
|
}
|
||||||
|
26
test/CodeGen/SPARC/inlineasm-output-template.ll
Normal file
26
test/CodeGen/SPARC/inlineasm-output-template.ll
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
; RUN: llc -mtriple=sparc-linux-gnu < %s | FileCheck %s
|
||||||
|
|
||||||
|
; Test that %c works with immediates
|
||||||
|
; CHECK-LABEL: test_inlineasm_c_output_template0
|
||||||
|
; CHECK: !TEST 42
|
||||||
|
define dso_local i32 @test_inlineasm_c_output_template0() {
|
||||||
|
tail call void asm sideeffect "!TEST ${0:c}", "i"(i32 42)
|
||||||
|
ret i32 42
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test that %c works with global address
|
||||||
|
; CHECK-LABEL: test_inlineasm_c_output_template1
|
||||||
|
; CHECK: !TEST baz
|
||||||
|
@baz = internal global i32 0, align 4
|
||||||
|
define dso_local i32 @test_inlineasm_c_output_template1() {
|
||||||
|
tail call void asm sideeffect "!TEST ${0:c}", "i"(i32* nonnull @baz)
|
||||||
|
ret i32 42
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test that %n works with immediates
|
||||||
|
; CHECK-LABEL: test_inlineasm_c_output_template2
|
||||||
|
; CHECK: !TEST -42
|
||||||
|
define dso_local i32 @test_inlineasm_c_output_template2() {
|
||||||
|
tail call void asm sideeffect "!TEST ${0:n}", "i"(i32 42)
|
||||||
|
ret i32 42
|
||||||
|
}
|
26
test/CodeGen/SystemZ/inlineasm-output-template.ll
Normal file
26
test/CodeGen/SystemZ/inlineasm-output-template.ll
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
; RUN: llc -mtriple=s390x-linux-gnu < %s | FileCheck %s
|
||||||
|
|
||||||
|
; Test that %c works with immediates
|
||||||
|
; CHECK-LABEL: test_inlineasm_c_output_template0
|
||||||
|
; CHECK: #TEST 42
|
||||||
|
define dso_local i32 @test_inlineasm_c_output_template0() {
|
||||||
|
tail call void asm sideeffect "#TEST ${0:c}", "i"(i32 42)
|
||||||
|
ret i32 42
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test that %c works with global address
|
||||||
|
; CHECK-LABEL: test_inlineasm_c_output_template2
|
||||||
|
; CHECK: #TEST baz
|
||||||
|
@baz = internal global i32 0, align 4
|
||||||
|
define dso_local i32 @test_inlineasm_c_output_template2() {
|
||||||
|
tail call void asm sideeffect "#TEST ${0:c}", "i"(i32* nonnull @baz)
|
||||||
|
ret i32 42
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test that %n works with immediates
|
||||||
|
; CHECK-LABEL: test_inlineasm_c_output_template1
|
||||||
|
; CHECK: #TEST -42
|
||||||
|
define dso_local i32 @test_inlineasm_c_output_template1() {
|
||||||
|
tail call void asm sideeffect "#TEST ${0:n}", "i"(i32 42)
|
||||||
|
ret i32 42
|
||||||
|
}
|
26
test/CodeGen/WebAssembly/inlineasm-output-template.ll
Normal file
26
test/CodeGen/WebAssembly/inlineasm-output-template.ll
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
; RUN: llc -mtriple=wasm32 < %s | FileCheck %s
|
||||||
|
|
||||||
|
; Test that %c works with immediates
|
||||||
|
; CHECK-LABEL: test_inlineasm_c_output_template0
|
||||||
|
; CHECK: #TEST 42
|
||||||
|
define dso_local i32 @test_inlineasm_c_output_template0() {
|
||||||
|
tail call void asm sideeffect "#TEST ${0:c}", "i"(i32 42)
|
||||||
|
ret i32 42
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test that %c works with global address
|
||||||
|
; CHECK-LABEL: test_inlineasm_c_output_template2
|
||||||
|
; CHECK: #TEST baz
|
||||||
|
@baz = internal global i32 0, align 4
|
||||||
|
define dso_local i32 @test_inlineasm_c_output_template2() {
|
||||||
|
tail call void asm sideeffect "#TEST ${0:c}", "i"(i32* nonnull @baz)
|
||||||
|
ret i32 42
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test that %n works with immediates
|
||||||
|
; CHECK-LABEL: test_inlineasm_c_output_template1
|
||||||
|
; CHECK: #TEST -42
|
||||||
|
define dso_local i32 @test_inlineasm_c_output_template1() {
|
||||||
|
tail call void asm sideeffect "#TEST ${0:n}", "i"(i32 42)
|
||||||
|
ret i32 42
|
||||||
|
}
|
18
test/CodeGen/X86/inline-asm-modifier-c.ll
Normal file
18
test/CodeGen/X86/inline-asm-modifier-c.ll
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
; RUN: llc -mtriple=x86_64-linux-gnu < %s | FileCheck %s
|
||||||
|
|
||||||
|
; Test that %c works with immediates
|
||||||
|
; CHECK-LABEL: test_inlineasm_c_output_template0
|
||||||
|
; CHECK: #TEST 42
|
||||||
|
define dso_local i32 @test_inlineasm_c_output_template0() {
|
||||||
|
tail call void asm sideeffect "#TEST ${0:c}", "i"(i32 42)
|
||||||
|
ret i32 42
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test that %c works with global address
|
||||||
|
; CHECK-LABEL: test_inlineasm_c_output_template1
|
||||||
|
; CHECK: #TEST baz
|
||||||
|
@baz = internal global i32 0, align 4
|
||||||
|
define dso_local i32 @test_inlineasm_c_output_template1() {
|
||||||
|
tail call void asm sideeffect "#TEST ${0:c}", "i"(i32* nonnull @baz)
|
||||||
|
ret i32 42
|
||||||
|
}
|
26
test/CodeGen/XCore/inlineasm-output-template.ll
Normal file
26
test/CodeGen/XCore/inlineasm-output-template.ll
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
; RUN: llc -march=xcore < %s | FileCheck %s
|
||||||
|
|
||||||
|
; Test that %c works with immediates
|
||||||
|
; CHECK-LABEL: test_inlineasm_c_output_template0
|
||||||
|
; CHECK: #TEST 42
|
||||||
|
define dso_local i32 @test_inlineasm_c_output_template0() {
|
||||||
|
tail call void asm sideeffect "#TEST ${0:c}", "i"(i32 42)
|
||||||
|
ret i32 42
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test that %c works with global address
|
||||||
|
; CHECK-LABEL: test_inlineasm_c_output_template2
|
||||||
|
; CHECK: #TEST baz
|
||||||
|
@baz = internal global i32 0, align 4
|
||||||
|
define dso_local i32 @test_inlineasm_c_output_template2() {
|
||||||
|
tail call void asm sideeffect "#TEST ${0:c}", "i"(i32* nonnull @baz)
|
||||||
|
ret i32 42
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test that %n works with immediates
|
||||||
|
; CHECK-LABEL: test_inlineasm_c_output_template1
|
||||||
|
; CHECK: #TEST -42
|
||||||
|
define dso_local i32 @test_inlineasm_c_output_template1() {
|
||||||
|
tail call void asm sideeffect "#TEST ${0:n}", "i"(i32 42)
|
||||||
|
ret i32 42
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user