aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/AArch64/AArch64AsmPrinter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/AArch64/AArch64AsmPrinter.cpp')
-rw-r--r--lib/Target/AArch64/AArch64AsmPrinter.cpp130
1 files changed, 64 insertions, 66 deletions
diff --git a/lib/Target/AArch64/AArch64AsmPrinter.cpp b/lib/Target/AArch64/AArch64AsmPrinter.cpp
index 9498722..d59ca56 100644
--- a/lib/Target/AArch64/AArch64AsmPrinter.cpp
+++ b/lib/Target/AArch64/AArch64AsmPrinter.cpp
@@ -32,17 +32,18 @@ using namespace llvm;
/// argument to be printed as "bN".
static bool printModifiedFPRAsmOperand(const MachineOperand &MO,
const TargetRegisterInfo *TRI,
- const TargetRegisterClass &RegClass,
- raw_ostream &O) {
+ char RegType, raw_ostream &O) {
if (!MO.isReg())
return true;
for (MCRegAliasIterator AR(MO.getReg(), TRI, true); AR.isValid(); ++AR) {
- if (RegClass.contains(*AR)) {
- O << AArch64InstPrinter::getRegisterName(*AR);
+ if (AArch64::FPR8RegClass.contains(*AR)) {
+ O << RegType << TRI->getEncodingValue(MO.getReg());
return false;
}
}
+
+ // The register doesn't correspond to anything floating-point like.
return true;
}
@@ -81,9 +82,9 @@ bool AArch64AsmPrinter::printSymbolicAddress(const MachineOperand &MO,
StringRef Modifier;
switch (MO.getType()) {
default:
- llvm_unreachable("Unexpected operand for symbolic address constraint");
+ return true;
case MachineOperand::MO_GlobalAddress:
- Name = Mang->getSymbol(MO.getGlobal())->getName();
+ Name = getSymbol(MO.getGlobal())->getName();
// Global variables may be accessed either via a GOT or in various fun and
// interesting TLS-model specific ways. Set the prefix modifier as
@@ -145,57 +146,29 @@ bool AArch64AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
unsigned AsmVariant,
const char *ExtraCode, raw_ostream &O) {
const TargetRegisterInfo *TRI = MF->getTarget().getRegisterInfo();
- if (!ExtraCode || !ExtraCode[0]) {
- // There's actually no operand modifier, which leads to a slightly eclectic
- // set of behaviour which we have to handle here.
- const MachineOperand &MO = MI->getOperand(OpNum);
- switch (MO.getType()) {
- default:
- llvm_unreachable("Unexpected operand for inline assembly");
- case MachineOperand::MO_Register:
- // GCC prints the unmodified operand of a 'w' constraint as the vector
- // register. Technically, we could allocate the argument as a VPR128, but
- // that leads to extremely dodgy copies being generated to get the data
- // there.
- if (printModifiedFPRAsmOperand(MO, TRI, AArch64::VPR128RegClass, O))
- O << AArch64InstPrinter::getRegisterName(MO.getReg());
- break;
- case MachineOperand::MO_Immediate:
- O << '#' << MO.getImm();
- break;
- case MachineOperand::MO_FPImmediate:
- assert(MO.getFPImm()->isExactlyValue(0.0) && "Only FP 0.0 expected");
- O << "#0.0";
- break;
- case MachineOperand::MO_BlockAddress:
- case MachineOperand::MO_ConstantPoolIndex:
- case MachineOperand::MO_GlobalAddress:
- case MachineOperand::MO_ExternalSymbol:
- return printSymbolicAddress(MO, false, "", O);
- }
- return false;
- }
- // We have a real modifier to handle.
+ if (!ExtraCode)
+ ExtraCode = "";
+
switch(ExtraCode[0]) {
default:
- // See if this is a generic operand
- return AsmPrinter::PrintAsmOperand(MI, OpNum, AsmVariant, ExtraCode, O);
- case 'c': // Don't print "#" before an immediate operand.
- if (!MI->getOperand(OpNum).isImm())
- return true;
- O << MI->getOperand(OpNum).getImm();
- return false;
+ if (!AsmPrinter::PrintAsmOperand(MI, OpNum, AsmVariant, ExtraCode, O))
+ return false;
+ break;
case 'w':
// Output 32-bit general register operand, constant zero as wzr, or stack
// pointer as wsp. Ignored when used with other operand types.
- return printModifiedGPRAsmOperand(MI->getOperand(OpNum), TRI,
- AArch64::GPR32RegClass, O);
+ if (!printModifiedGPRAsmOperand(MI->getOperand(OpNum), TRI,
+ AArch64::GPR32RegClass, O))
+ return false;
+ break;
case 'x':
// Output 64-bit general register operand, constant zero as xzr, or stack
// pointer as sp. Ignored when used with other operand types.
- return printModifiedGPRAsmOperand(MI->getOperand(OpNum), TRI,
- AArch64::GPR64RegClass, O);
+ if (!printModifiedGPRAsmOperand(MI->getOperand(OpNum), TRI,
+ AArch64::GPR64RegClass, O))
+ return false;
+ break;
case 'H':
// Output higher numbered of a 64-bit general register pair
case 'Q':
@@ -211,40 +184,65 @@ bool AArch64AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
// copies ...).
llvm_unreachable("FIXME: Unimplemented register pairs");
case 'b':
- // Output 8-bit FP/SIMD scalar register operand, prefixed with b.
- return printModifiedFPRAsmOperand(MI->getOperand(OpNum), TRI,
- AArch64::FPR8RegClass, O);
case 'h':
- // Output 16-bit FP/SIMD scalar register operand, prefixed with h.
- return printModifiedFPRAsmOperand(MI->getOperand(OpNum), TRI,
- AArch64::FPR16RegClass, O);
case 's':
- // Output 32-bit FP/SIMD scalar register operand, prefixed with s.
- return printModifiedFPRAsmOperand(MI->getOperand(OpNum), TRI,
- AArch64::FPR32RegClass, O);
case 'd':
- // Output 64-bit FP/SIMD scalar register operand, prefixed with d.
- return printModifiedFPRAsmOperand(MI->getOperand(OpNum), TRI,
- AArch64::FPR64RegClass, O);
case 'q':
- // Output 128-bit FP/SIMD scalar register operand, prefixed with q.
- return printModifiedFPRAsmOperand(MI->getOperand(OpNum), TRI,
- AArch64::FPR128RegClass, O);
+ if (!printModifiedFPRAsmOperand(MI->getOperand(OpNum), TRI,
+ ExtraCode[0], O))
+ return false;
+ break;
case 'A':
// Output symbolic address with appropriate relocation modifier (also
// suitable for ADRP).
- return printSymbolicAddress(MI->getOperand(OpNum), false, "", O);
+ if (!printSymbolicAddress(MI->getOperand(OpNum), false, "", O))
+ return false;
+ break;
case 'L':
// Output bits 11:0 of symbolic address with appropriate :lo12: relocation
// modifier.
- return printSymbolicAddress(MI->getOperand(OpNum), true, "lo12", O);
+ if (!printSymbolicAddress(MI->getOperand(OpNum), true, "lo12", O))
+ return false;
+ break;
case 'G':
// Output bits 23:12 of symbolic address with appropriate :hi12: relocation
// modifier (currently only for TLS local exec).
- return printSymbolicAddress(MI->getOperand(OpNum), true, "hi12", O);
+ if (!printSymbolicAddress(MI->getOperand(OpNum), true, "hi12", O))
+ return false;
+ break;
+ case 'a':
+ return PrintAsmMemoryOperand(MI, OpNum, AsmVariant, ExtraCode, O);
}
+ // There's actually no operand modifier, which leads to a slightly eclectic
+ // set of behaviour which we have to handle here.
+ const MachineOperand &MO = MI->getOperand(OpNum);
+ switch (MO.getType()) {
+ default:
+ llvm_unreachable("Unexpected operand for inline assembly");
+ case MachineOperand::MO_Register:
+ // GCC prints the unmodified operand of a 'w' constraint as the vector
+ // register. Technically, we could allocate the argument as a VPR128, but
+ // that leads to extremely dodgy copies being generated to get the data
+ // there.
+ if (printModifiedFPRAsmOperand(MO, TRI, 'v', O))
+ O << AArch64InstPrinter::getRegisterName(MO.getReg());
+ break;
+ case MachineOperand::MO_Immediate:
+ O << '#' << MO.getImm();
+ break;
+ case MachineOperand::MO_FPImmediate:
+ assert(MO.getFPImm()->isExactlyValue(0.0) && "Only FP 0.0 expected");
+ O << "#0.0";
+ break;
+ case MachineOperand::MO_BlockAddress:
+ case MachineOperand::MO_ConstantPoolIndex:
+ case MachineOperand::MO_GlobalAddress:
+ case MachineOperand::MO_ExternalSymbol:
+ return printSymbolicAddress(MO, false, "", O);
+ }
+ return false;
}
bool AArch64AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,