Nuke it from orbit. It's the only way to be sure.

(Kill the dead non-MC asm printer for the ARM target.)


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@115127 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jim Grosbach 2010-09-30 01:57:53 +00:00
parent ca96a86165
commit 2317e40539
3 changed files with 22 additions and 766 deletions

View File

@ -16,6 +16,7 @@
include "llvm/Target/Target.td" include "llvm/Target/Target.td"
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// ARM Subtarget features. // ARM Subtarget features.
// //
@ -184,6 +185,17 @@ include "ARMInstrInfo.td"
def ARMInstrInfo : InstrInfo; def ARMInstrInfo : InstrInfo;
//===----------------------------------------------------------------------===//
// Assembly printer
//===----------------------------------------------------------------------===//
// ARM Uses the MC printer for asm output, so make sure the TableGen
// AsmWriter bits get associated with the correct class.
def ARMAsmWriter : AsmWriter {
string AsmWriterClassName = "InstPrinter";
bit isMCAsmWriter = 1;
}
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Declare the target which we are implementing // Declare the target which we are implementing
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -191,4 +203,6 @@ def ARMInstrInfo : InstrInfo;
def ARM : Target { def ARM : Target {
// Pull in Instruction Info: // Pull in Instruction Info:
let InstructionSet = ARMInstrInfo; let InstructionSet = ARMInstrInfo;
let AssemblyWriters = [ARMAsmWriter];
} }

View File

@ -87,106 +87,8 @@ namespace {
return "ARM Assembly Printer"; return "ARM Assembly Printer";
} }
void EmitJumpTable(const MachineInstr *MI);
void EmitJump2Table(const MachineInstr *MI);
void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O, void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O,
const char *Modifier = 0); const char *Modifier = 0);
void printSOImmOperand(const MachineInstr *MI, int OpNum, raw_ostream &O);
void printSOImm2PartOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O);
void printSORegOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O);
void printAddrMode2Operand(const MachineInstr *MI, int OpNum,
raw_ostream &O);
void printAddrMode2OffsetOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O);
void printAddrMode3Operand(const MachineInstr *MI, int OpNum,
raw_ostream &O);
void printAddrMode3OffsetOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O);
void printAddrMode4Operand(const MachineInstr *MI, int OpNum,raw_ostream &O,
const char *Modifier = 0);
void printAddrMode5Operand(const MachineInstr *MI, int OpNum,raw_ostream &O,
const char *Modifier = 0);
void printAddrMode6Operand(const MachineInstr *MI, int OpNum,
raw_ostream &O);
void printAddrMode6OffsetOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O);
void printAddrModePCOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O,
const char *Modifier = 0);
void printBitfieldInvMaskImmOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O);
void printMemBOption(const MachineInstr *MI, int OpNum,
raw_ostream &O);
void printShiftImmOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O);
void printThumbS4ImmOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O);
void printThumbITMask(const MachineInstr *MI, int OpNum, raw_ostream &O);
void printThumbAddrModeRROperand(const MachineInstr *MI, int OpNum,
raw_ostream &O);
void printThumbAddrModeRI5Operand(const MachineInstr *MI, int OpNum,
raw_ostream &O,
unsigned Scale);
void printThumbAddrModeS1Operand(const MachineInstr *MI, int OpNum,
raw_ostream &O);
void printThumbAddrModeS2Operand(const MachineInstr *MI, int OpNum,
raw_ostream &O);
void printThumbAddrModeS4Operand(const MachineInstr *MI, int OpNum,
raw_ostream &O);
void printThumbAddrModeSPOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O);
void printT2SOOperand(const MachineInstr *MI, int OpNum, raw_ostream &O);
void printT2AddrModeImm12Operand(const MachineInstr *MI, int OpNum,
raw_ostream &O);
void printT2AddrModeImm8Operand(const MachineInstr *MI, int OpNum,
raw_ostream &O);
void printT2AddrModeImm8s4Operand(const MachineInstr *MI, int OpNum,
raw_ostream &O);
void printT2AddrModeImm8OffsetOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O);
void printT2AddrModeImm8s4OffsetOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O) {}
void printT2AddrModeSoRegOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O);
void printCPSOptionOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O) {}
void printMSRMaskOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O) {}
void printNegZeroOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O) {}
void printPredicateOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O);
void printMandatoryPredicateOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O);
void printSBitModifierOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O);
void printPCLabel(const MachineInstr *MI, int OpNum,
raw_ostream &O);
void printRegisterList(const MachineInstr *MI, int OpNum,
raw_ostream &O);
void printCPInstOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O,
const char *Modifier);
void printJTBlockOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O);
void printJT2BlockOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O);
void printTBAddrMode(const MachineInstr *MI, int OpNum,
raw_ostream &O);
void printNoHashImmediate(const MachineInstr *MI, int OpNum,
raw_ostream &O);
void printVFPf32ImmOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O);
void printVFPf64ImmOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O);
void printNEONModImmOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O);
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
unsigned AsmVariant, const char *ExtraCode, unsigned AsmVariant, const char *ExtraCode,
@ -195,9 +97,8 @@ namespace {
unsigned AsmVariant, unsigned AsmVariant,
const char *ExtraCode, raw_ostream &O); const char *ExtraCode, raw_ostream &O);
void printInstruction(const MachineInstr *MI, raw_ostream &O); // autogen void EmitJumpTable(const MachineInstr *MI);
static const char *getRegisterName(unsigned RegNo); void EmitJump2Table(const MachineInstr *MI);
virtual void EmitInstruction(const MachineInstr *MI); virtual void EmitInstruction(const MachineInstr *MI);
bool runOnMachineFunction(MachineFunction &F); bool runOnMachineFunction(MachineFunction &F);
@ -296,8 +197,6 @@ namespace {
}; };
} // end of anonymous namespace } // end of anonymous namespace
#include "ARMGenAsmWriter.inc"
void ARMAsmPrinter::EmitFunctionEntryLabel() { void ARMAsmPrinter::EmitFunctionEntryLabel() {
if (AFI->isThumbFunction()) { if (AFI->isThumbFunction()) {
OutStreamer.EmitRawText(StringRef("\t.code\t16")); OutStreamer.EmitRawText(StringRef("\t.code\t16"));
@ -316,7 +215,7 @@ void ARMAsmPrinter::EmitFunctionEntryLabel() {
OutStreamer.EmitLabel(CurrentFnSym); OutStreamer.EmitLabel(CurrentFnSym);
} }
/// runOnMachineFunction - This uses the printInstruction() /// runOnMachineFunction - This uses the EmitInstruction()
/// method to print assembly for each instruction. /// method to print assembly for each instruction.
/// ///
bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) { bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
@ -342,10 +241,10 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
unsigned DReg = unsigned DReg =
TM.getRegisterInfo()->getMatchingSuperReg(Reg, TM.getRegisterInfo()->getMatchingSuperReg(Reg,
RegNum & 1 ? ARM::ssub_1 : ARM::ssub_0, &ARM::DPR_VFP2RegClass); RegNum & 1 ? ARM::ssub_1 : ARM::ssub_0, &ARM::DPR_VFP2RegClass);
O << getRegisterName(DReg) << '[' << (RegNum & 1) << ']'; O << ARMInstPrinter::getRegisterName(DReg) << '[' << (RegNum & 1) << ']';
} else { } else {
assert(!MO.getSubReg() && "Subregs should be eliminated!"); assert(!MO.getSubReg() && "Subregs should be eliminated!");
O << getRegisterName(Reg); O << ARMInstPrinter::getRegisterName(Reg);
} }
break; break;
} }
@ -401,538 +300,8 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
} }
} }
static void printSOImm(raw_ostream &O, int64_t V, bool VerboseAsm,
const MCAsmInfo *MAI) {
// Break it up into two parts that make up a shifter immediate.
V = ARM_AM::getSOImmVal(V);
assert(V != -1 && "Not a valid so_imm value!");
unsigned Imm = ARM_AM::getSOImmValImm(V);
unsigned Rot = ARM_AM::getSOImmValRot(V);
// Print low-level immediate formation info, per
// A5.1.3: "Data-processing operands - Immediate".
if (Rot) {
O << "#" << Imm << ", " << Rot;
// Pretty printed version.
if (VerboseAsm) {
O << "\t" << MAI->getCommentString() << ' ';
O << (int)ARM_AM::rotr32(Imm, Rot);
}
} else {
O << "#" << Imm;
}
}
/// printSOImmOperand - SOImm is 4-bit rotate amount in bits 8-11 with 8-bit
/// immediate in bits 0-7.
void ARMAsmPrinter::printSOImmOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O) {
const MachineOperand &MO = MI->getOperand(OpNum);
assert(MO.isImm() && "Not a valid so_imm value!");
printSOImm(O, MO.getImm(), isVerbose(), MAI);
}
/// printSOImm2PartOperand - SOImm is broken into two pieces using a 'mov'
/// followed by an 'orr' to materialize.
void ARMAsmPrinter::printSOImm2PartOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O) {
const MachineOperand &MO = MI->getOperand(OpNum);
assert(MO.isImm() && "Not a valid so_imm value!");
unsigned V1 = ARM_AM::getSOImmTwoPartFirst(MO.getImm());
unsigned V2 = ARM_AM::getSOImmTwoPartSecond(MO.getImm());
printSOImm(O, V1, isVerbose(), MAI);
O << "\n\torr";
printPredicateOperand(MI, 2, O);
O << "\t";
printOperand(MI, 0, O);
O << ", ";
printOperand(MI, 0, O);
O << ", ";
printSOImm(O, V2, isVerbose(), MAI);
}
// so_reg is a 4-operand unit corresponding to register forms of the A5.1
// "Addressing Mode 1 - Data-processing operands" forms. This includes:
// REG 0 0 - e.g. R5
// REG REG 0,SH_OPC - e.g. R5, ROR R3
// REG 0 IMM,SH_OPC - e.g. R5, LSL #3
void ARMAsmPrinter::printSORegOperand(const MachineInstr *MI, int Op,
raw_ostream &O) {
const MachineOperand &MO1 = MI->getOperand(Op);
const MachineOperand &MO2 = MI->getOperand(Op+1);
const MachineOperand &MO3 = MI->getOperand(Op+2);
O << getRegisterName(MO1.getReg());
// Print the shift opc.
ARM_AM::ShiftOpc ShOpc = ARM_AM::getSORegShOp(MO3.getImm());
O << ", " << ARM_AM::getShiftOpcStr(ShOpc);
if (MO2.getReg()) {
O << ' ' << getRegisterName(MO2.getReg());
assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
} else if (ShOpc != ARM_AM::rrx) {
O << " #" << ARM_AM::getSORegOffset(MO3.getImm());
}
}
void ARMAsmPrinter::printAddrMode2Operand(const MachineInstr *MI, int Op,
raw_ostream &O) {
const MachineOperand &MO1 = MI->getOperand(Op);
const MachineOperand &MO2 = MI->getOperand(Op+1);
const MachineOperand &MO3 = MI->getOperand(Op+2);
if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
printOperand(MI, Op, O);
return;
}
O << "[" << getRegisterName(MO1.getReg());
if (!MO2.getReg()) {
if (ARM_AM::getAM2Offset(MO3.getImm())) // Don't print +0.
O << ", #"
<< ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
<< ARM_AM::getAM2Offset(MO3.getImm());
O << "]";
return;
}
O << ", "
<< ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
<< getRegisterName(MO2.getReg());
if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm()))
O << ", "
<< ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm()))
<< " #" << ShImm;
O << "]";
}
void ARMAsmPrinter::printAddrMode2OffsetOperand(const MachineInstr *MI, int Op,
raw_ostream &O) {
const MachineOperand &MO1 = MI->getOperand(Op);
const MachineOperand &MO2 = MI->getOperand(Op+1);
if (!MO1.getReg()) {
unsigned ImmOffs = ARM_AM::getAM2Offset(MO2.getImm());
O << "#"
<< ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm()))
<< ImmOffs;
return;
}
O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm()))
<< getRegisterName(MO1.getReg());
if (unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm()))
O << ", "
<< ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO2.getImm()))
<< " #" << ShImm;
}
void ARMAsmPrinter::printAddrMode3Operand(const MachineInstr *MI, int Op,
raw_ostream &O) {
const MachineOperand &MO1 = MI->getOperand(Op);
const MachineOperand &MO2 = MI->getOperand(Op+1);
const MachineOperand &MO3 = MI->getOperand(Op+2);
assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
O << "[" << getRegisterName(MO1.getReg());
if (MO2.getReg()) {
O << ", "
<< (char)ARM_AM::getAM3Op(MO3.getImm())
<< getRegisterName(MO2.getReg())
<< "]";
return;
}
if (unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm()))
O << ", #"
<< ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO3.getImm()))
<< ImmOffs;
O << "]";
}
void ARMAsmPrinter::printAddrMode3OffsetOperand(const MachineInstr *MI, int Op,
raw_ostream &O){
const MachineOperand &MO1 = MI->getOperand(Op);
const MachineOperand &MO2 = MI->getOperand(Op+1);
if (MO1.getReg()) {
O << (char)ARM_AM::getAM3Op(MO2.getImm())
<< getRegisterName(MO1.getReg());
return;
}
unsigned ImmOffs = ARM_AM::getAM3Offset(MO2.getImm());
O << "#"
<< ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm()))
<< ImmOffs;
}
void ARMAsmPrinter::printAddrMode4Operand(const MachineInstr *MI, int Op,
raw_ostream &O,
const char *Modifier) {
const MachineOperand &MO2 = MI->getOperand(Op+1);
ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO2.getImm());
if (Modifier && strcmp(Modifier, "submode") == 0) {
O << ARM_AM::getAMSubModeStr(Mode);
} else if (Modifier && strcmp(Modifier, "wide") == 0) {
ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO2.getImm());
if (Mode == ARM_AM::ia)
O << ".w";
} else {
printOperand(MI, Op, O);
}
}
void ARMAsmPrinter::printAddrMode5Operand(const MachineInstr *MI, int Op,
raw_ostream &O,
const char *Modifier) {
const MachineOperand &MO1 = MI->getOperand(Op);
const MachineOperand &MO2 = MI->getOperand(Op+1);
if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
printOperand(MI, Op, O);
return;
}
assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
O << "[" << getRegisterName(MO1.getReg());
if (unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm())) {
O << ", #"
<< ARM_AM::getAddrOpcStr(ARM_AM::getAM5Op(MO2.getImm()))
<< ImmOffs*4;
}
O << "]";
}
void ARMAsmPrinter::printAddrMode6Operand(const MachineInstr *MI, int Op,
raw_ostream &O) {
const MachineOperand &MO1 = MI->getOperand(Op);
const MachineOperand &MO2 = MI->getOperand(Op+1);
O << "[" << getRegisterName(MO1.getReg());
if (MO2.getImm()) {
// FIXME: Both darwin as and GNU as violate ARM docs here.
O << ", :" << (MO2.getImm() << 3);
}
O << "]";
}
void ARMAsmPrinter::printAddrMode6OffsetOperand(const MachineInstr *MI, int Op,
raw_ostream &O){
const MachineOperand &MO = MI->getOperand(Op);
if (MO.getReg() == 0)
O << "!";
else
O << ", " << getRegisterName(MO.getReg());
}
void ARMAsmPrinter::printAddrModePCOperand(const MachineInstr *MI, int Op,
raw_ostream &O,
const char *Modifier) {
if (Modifier && strcmp(Modifier, "label") == 0) {
printPCLabel(MI, Op+1, O);
return;
}
const MachineOperand &MO1 = MI->getOperand(Op);
assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
O << "[pc, " << getRegisterName(MO1.getReg()) << "]";
}
void
ARMAsmPrinter::printBitfieldInvMaskImmOperand(const MachineInstr *MI, int Op,
raw_ostream &O) {
const MachineOperand &MO = MI->getOperand(Op);
uint32_t v = ~MO.getImm();
int32_t lsb = CountTrailingZeros_32(v);
int32_t width = (32 - CountLeadingZeros_32 (v)) - lsb;
assert(MO.isImm() && "Not a valid bf_inv_mask_imm value!");
O << "#" << lsb << ", #" << width;
}
void
ARMAsmPrinter::printMemBOption(const MachineInstr *MI, int OpNum,
raw_ostream &O) {
unsigned val = MI->getOperand(OpNum).getImm();
O << ARM_MB::MemBOptToString(val);
}
void ARMAsmPrinter::printShiftImmOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O) {
unsigned ShiftOp = MI->getOperand(OpNum).getImm();
ARM_AM::ShiftOpc Opc = ARM_AM::getSORegShOp(ShiftOp);
switch (Opc) {
case ARM_AM::no_shift:
return;
case ARM_AM::lsl:
O << ", lsl #";
break;
case ARM_AM::asr:
O << ", asr #";
break;
default:
assert(0 && "unexpected shift opcode for shift immediate operand");
}
O << ARM_AM::getSORegOffset(ShiftOp);
}
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
void ARMAsmPrinter::printThumbS4ImmOperand(const MachineInstr *MI, int Op,
raw_ostream &O) {
O << "#" << MI->getOperand(Op).getImm() * 4;
}
void
ARMAsmPrinter::printThumbITMask(const MachineInstr *MI, int Op,
raw_ostream &O) {
// (3 - the number of trailing zeros) is the number of then / else.
unsigned Mask = MI->getOperand(Op).getImm();
unsigned CondBit0 = Mask >> 4 & 1;
unsigned NumTZ = CountTrailingZeros_32(Mask);
assert(NumTZ <= 3 && "Invalid IT mask!");
for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) {
bool T = ((Mask >> Pos) & 1) == CondBit0;
if (T)
O << 't';
else
O << 'e';
}
}
void
ARMAsmPrinter::printThumbAddrModeRROperand(const MachineInstr *MI, int Op,
raw_ostream &O) {
const MachineOperand &MO1 = MI->getOperand(Op);
const MachineOperand &MO2 = MI->getOperand(Op+1);
O << "[" << getRegisterName(MO1.getReg());
O << ", " << getRegisterName(MO2.getReg()) << "]";
}
void
ARMAsmPrinter::printThumbAddrModeRI5Operand(const MachineInstr *MI, int Op,
raw_ostream &O,
unsigned Scale) {
const MachineOperand &MO1 = MI->getOperand(Op);
const MachineOperand &MO2 = MI->getOperand(Op+1);
const MachineOperand &MO3 = MI->getOperand(Op+2);
if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
printOperand(MI, Op, O);
return;
}
O << "[" << getRegisterName(MO1.getReg());
if (MO3.getReg())
O << ", " << getRegisterName(MO3.getReg());
else if (unsigned ImmOffs = MO2.getImm())
O << ", #" << ImmOffs * Scale;
O << "]";
}
void
ARMAsmPrinter::printThumbAddrModeS1Operand(const MachineInstr *MI, int Op,
raw_ostream &O) {
printThumbAddrModeRI5Operand(MI, Op, O, 1);
}
void
ARMAsmPrinter::printThumbAddrModeS2Operand(const MachineInstr *MI, int Op,
raw_ostream &O) {
printThumbAddrModeRI5Operand(MI, Op, O, 2);
}
void
ARMAsmPrinter::printThumbAddrModeS4Operand(const MachineInstr *MI, int Op,
raw_ostream &O) {
printThumbAddrModeRI5Operand(MI, Op, O, 4);
}
void ARMAsmPrinter::printThumbAddrModeSPOperand(const MachineInstr *MI,int Op,
raw_ostream &O) {
const MachineOperand &MO1 = MI->getOperand(Op);
const MachineOperand &MO2 = MI->getOperand(Op+1);
O << "[" << getRegisterName(MO1.getReg());
if (unsigned ImmOffs = MO2.getImm())
O << ", #" << ImmOffs*4;
O << "]";
}
//===--------------------------------------------------------------------===//
// Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2
// register with shift forms.
// REG 0 0 - e.g. R5
// REG IMM, SH_OPC - e.g. R5, LSL #3
void ARMAsmPrinter::printT2SOOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O) {
const MachineOperand &MO1 = MI->getOperand(OpNum);
const MachineOperand &MO2 = MI->getOperand(OpNum+1);
unsigned Reg = MO1.getReg();
assert(TargetRegisterInfo::isPhysicalRegister(Reg));
O << getRegisterName(Reg);
// Print the shift opc.
assert(MO2.isImm() && "Not a valid t2_so_reg value!");
ARM_AM::ShiftOpc ShOpc = ARM_AM::getSORegShOp(MO2.getImm());
O << ", " << ARM_AM::getShiftOpcStr(ShOpc);
if (ShOpc != ARM_AM::rrx)
O << " #" << ARM_AM::getSORegOffset(MO2.getImm());
}
void ARMAsmPrinter::printT2AddrModeImm12Operand(const MachineInstr *MI,
int OpNum,
raw_ostream &O) {
const MachineOperand &MO1 = MI->getOperand(OpNum);
const MachineOperand &MO2 = MI->getOperand(OpNum+1);
O << "[" << getRegisterName(MO1.getReg());
unsigned OffImm = MO2.getImm();
if (OffImm) // Don't print +0.
O << ", #" << OffImm;
O << "]";
}
void ARMAsmPrinter::printT2AddrModeImm8Operand(const MachineInstr *MI,
int OpNum,
raw_ostream &O) {
const MachineOperand &MO1 = MI->getOperand(OpNum);
const MachineOperand &MO2 = MI->getOperand(OpNum+1);
O << "[" << getRegisterName(MO1.getReg());
int32_t OffImm = (int32_t)MO2.getImm();
// Don't print +0.
if (OffImm < 0)
O << ", #-" << -OffImm;
else if (OffImm > 0)
O << ", #" << OffImm;
O << "]";
}
void ARMAsmPrinter::printT2AddrModeImm8s4Operand(const MachineInstr *MI,
int OpNum,
raw_ostream &O) {
const MachineOperand &MO1 = MI->getOperand(OpNum);
const MachineOperand &MO2 = MI->getOperand(OpNum+1);
O << "[" << getRegisterName(MO1.getReg());
int32_t OffImm = (int32_t)MO2.getImm() / 4;
// Don't print +0.
if (OffImm < 0)
O << ", #-" << -OffImm * 4;
else if (OffImm > 0)
O << ", #" << OffImm * 4;
O << "]";
}
void ARMAsmPrinter::printT2AddrModeImm8OffsetOperand(const MachineInstr *MI,
int OpNum,
raw_ostream &O) {
const MachineOperand &MO1 = MI->getOperand(OpNum);
int32_t OffImm = (int32_t)MO1.getImm();
// Don't print +0.
if (OffImm < 0)
O << "#-" << -OffImm;
else if (OffImm > 0)
O << "#" << OffImm;
}
void ARMAsmPrinter::printT2AddrModeSoRegOperand(const MachineInstr *MI,
int OpNum,
raw_ostream &O) {
const MachineOperand &MO1 = MI->getOperand(OpNum);
const MachineOperand &MO2 = MI->getOperand(OpNum+1);
const MachineOperand &MO3 = MI->getOperand(OpNum+2);
O << "[" << getRegisterName(MO1.getReg());
assert(MO2.getReg() && "Invalid so_reg load / store address!");
O << ", " << getRegisterName(MO2.getReg());
unsigned ShAmt = MO3.getImm();
if (ShAmt) {
assert(ShAmt <= 3 && "Not a valid Thumb2 addressing mode!");
O << ", lsl #" << ShAmt;
}
O << "]";
}
//===--------------------------------------------------------------------===//
void ARMAsmPrinter::printPredicateOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O) {
ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
if (CC != ARMCC::AL)
O << ARMCondCodeToString(CC);
}
void ARMAsmPrinter::printMandatoryPredicateOperand(const MachineInstr *MI,
int OpNum,
raw_ostream &O) {
ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
O << ARMCondCodeToString(CC);
}
void ARMAsmPrinter::printSBitModifierOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O){
unsigned Reg = MI->getOperand(OpNum).getReg();
if (Reg) {
assert(Reg == ARM::CPSR && "Expect ARM CPSR register!");
O << 's';
}
}
void ARMAsmPrinter::printPCLabel(const MachineInstr *MI, int OpNum,
raw_ostream &O) {
int Id = (int)MI->getOperand(OpNum).getImm();
O << MAI->getPrivateGlobalPrefix()
<< "PC" << getFunctionNumber() << "_" << Id;
}
void ARMAsmPrinter::printRegisterList(const MachineInstr *MI, int OpNum,
raw_ostream &O) {
O << "{";
for (unsigned i = OpNum, e = MI->getNumOperands(); i != e; ++i) {
if (MI->getOperand(i).isImplicit())
continue;
if ((int)i != OpNum) O << ", ";
printOperand(MI, i, O);
}
O << "}";
}
void ARMAsmPrinter::printCPInstOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O, const char *Modifier) {
assert(Modifier && "This operand only works with a modifier!");
// There are two aspects to a CONSTANTPOOL_ENTRY operand, the label and the
// data itself.
if (!strcmp(Modifier, "label")) {
unsigned ID = MI->getOperand(OpNum).getImm();
OutStreamer.EmitLabel(GetCPISymbol(ID));
} else {
assert(!strcmp(Modifier, "cpentry") && "Unknown modifier for CPE");
unsigned CPI = MI->getOperand(OpNum).getIndex();
const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPI];
if (MCPE.isMachineConstantPoolEntry()) {
EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
} else {
EmitGlobalConstant(MCPE.Val.ConstVal);
}
}
}
MCSymbol *ARMAsmPrinter:: MCSymbol *ARMAsmPrinter::
GetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2, GetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2,
const MachineBasicBlock *MBB) const { const MachineBasicBlock *MBB) const {
@ -959,128 +328,6 @@ MCSymbol *ARMAsmPrinter::GetARMSJLJEHLabel(void) const {
return OutContext.GetOrCreateSymbol(Name.str()); return OutContext.GetOrCreateSymbol(Name.str());
} }
void ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O) {
assert(!Subtarget->isThumb2() && "Thumb2 should use double-jump jumptables!");
const MachineOperand &MO1 = MI->getOperand(OpNum);
const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
unsigned JTI = MO1.getIndex();
MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
// Can't use EmitLabel until instprinter happens, label comes out in the wrong
// order.
O << "\n" << *JTISymbol << ":\n";
const char *JTEntryDirective = MAI->getData32bitsDirective();
const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
bool UseSet= MAI->hasSetDirective() && TM.getRelocationModel() == Reloc::PIC_;
SmallPtrSet<MachineBasicBlock*, 8> JTSets;
for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
MachineBasicBlock *MBB = JTBBs[i];
bool isNew = JTSets.insert(MBB);
if (UseSet && isNew) {
O << "\t.set\t"
<< *GetARMSetPICJumpTableLabel2(JTI, MO2.getImm(), MBB) << ','
<< *MBB->getSymbol() << '-' << *JTISymbol << '\n';
}
O << JTEntryDirective << ' ';
if (UseSet)
O << *GetARMSetPICJumpTableLabel2(JTI, MO2.getImm(), MBB);
else if (TM.getRelocationModel() == Reloc::PIC_)
O << *MBB->getSymbol() << '-' << *JTISymbol;
else
O << *MBB->getSymbol();
if (i != e-1)
O << '\n';
}
}
void ARMAsmPrinter::printJT2BlockOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O) {
const MachineOperand &MO1 = MI->getOperand(OpNum);
const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
unsigned JTI = MO1.getIndex();
MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
// Can't use EmitLabel until instprinter happens, label comes out in the wrong
// order.
O << "\n" << *JTISymbol << ":\n";
const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
bool ByteOffset = false, HalfWordOffset = false;
if (MI->getOpcode() == ARM::t2TBB)
ByteOffset = true;
else if (MI->getOpcode() == ARM::t2TBH)
HalfWordOffset = true;
for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
MachineBasicBlock *MBB = JTBBs[i];
if (ByteOffset)
O << MAI->getData8bitsDirective();
else if (HalfWordOffset)
O << MAI->getData16bitsDirective();
if (ByteOffset || HalfWordOffset)
O << '(' << *MBB->getSymbol() << "-" << *JTISymbol << ")/2";
else
O << "\tb.w " << *MBB->getSymbol();
if (i != e-1)
O << '\n';
}
}
void ARMAsmPrinter::printTBAddrMode(const MachineInstr *MI, int OpNum,
raw_ostream &O) {
O << "[pc, " << getRegisterName(MI->getOperand(OpNum).getReg());
if (MI->getOpcode() == ARM::t2TBH)
O << ", lsl #1";
O << ']';
}
void ARMAsmPrinter::printNoHashImmediate(const MachineInstr *MI, int OpNum,
raw_ostream &O) {
O << MI->getOperand(OpNum).getImm();
}
void ARMAsmPrinter::printVFPf32ImmOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O) {
const ConstantFP *FP = MI->getOperand(OpNum).getFPImm();
O << '#' << FP->getValueAPF().convertToFloat();
if (isVerbose()) {
O << "\t\t" << MAI->getCommentString() << ' ';
WriteAsOperand(O, FP, /*PrintType=*/false);
}
}
void ARMAsmPrinter::printVFPf64ImmOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O) {
const ConstantFP *FP = MI->getOperand(OpNum).getFPImm();
O << '#' << FP->getValueAPF().convertToDouble();
if (isVerbose()) {
O << "\t\t" << MAI->getCommentString() << ' ';
WriteAsOperand(O, FP, /*PrintType=*/false);
}
}
void ARMAsmPrinter::printNEONModImmOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O) {
unsigned EncodedImm = MI->getOperand(OpNum).getImm();
unsigned EltBits;
uint64_t Val = ARM_AM::decodeNEONModImm(EncodedImm, EltBits);
O << "#0x" << utohexstr(Val);
}
bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
unsigned AsmVariant, const char *ExtraCode, unsigned AsmVariant, const char *ExtraCode,
raw_ostream &O) { raw_ostream &O) {
@ -1092,14 +339,14 @@ bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
default: return true; // Unknown modifier. default: return true; // Unknown modifier.
case 'a': // Print as a memory address. case 'a': // Print as a memory address.
if (MI->getOperand(OpNum).isReg()) { if (MI->getOperand(OpNum).isReg()) {
O << "[" << getRegisterName(MI->getOperand(OpNum).getReg()) << "]"; O << "[" << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg()) << "]";
return false; return false;
} }
// Fallthrough // Fallthrough
case 'c': // Don't print "#" before an immediate operand. case 'c': // Don't print "#" before an immediate operand.
if (!MI->getOperand(OpNum).isImm()) if (!MI->getOperand(OpNum).isImm())
return true; return true;
printNoHashImmediate(MI, OpNum, O); O << MI->getOperand(OpNum).getImm();
return false; return false;
case 'P': // Print a VFP double precision register. case 'P': // Print a VFP double precision register.
case 'q': // Print a NEON quad precision register. case 'q': // Print a NEON quad precision register.
@ -1126,7 +373,7 @@ bool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
const MachineOperand &MO = MI->getOperand(OpNum); const MachineOperand &MO = MI->getOperand(OpNum);
assert(MO.isReg() && "unexpected inline asm memory operand"); assert(MO.isReg() && "unexpected inline asm memory operand");
O << "[" << getRegisterName(MO.getReg()) << "]"; O << "[" << ARMInstPrinter::getRegisterName(MO.getReg()) << "]";
return false; return false;
} }

View File

@ -22,12 +22,7 @@
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
using namespace llvm; using namespace llvm;
// Include the auto-generated portion of the assembly writer.
#define MachineInstr MCInst
#define ARMAsmPrinter ARMInstPrinter // FIXME: REMOVE.
#include "ARMGenAsmWriter.inc" #include "ARMGenAsmWriter.inc"
#undef MachineInstr
#undef ARMAsmPrinter
static unsigned getDPRSuperRegForSPR(unsigned Reg) { static unsigned getDPRSuperRegForSPR(unsigned Reg) {
switch (Reg) { switch (Reg) {