mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-23 02:29:18 +00:00
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:
parent
ca96a86165
commit
2317e40539
@ -16,6 +16,7 @@
|
||||
|
||||
include "llvm/Target/Target.td"
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ARM Subtarget features.
|
||||
//
|
||||
@ -184,6 +185,17 @@ include "ARMInstrInfo.td"
|
||||
|
||||
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
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -191,4 +203,6 @@ def ARMInstrInfo : InstrInfo;
|
||||
def ARM : Target {
|
||||
// Pull in Instruction Info:
|
||||
let InstructionSet = ARMInstrInfo;
|
||||
|
||||
let AssemblyWriters = [ARMAsmWriter];
|
||||
}
|
||||
|
@ -87,106 +87,8 @@ namespace {
|
||||
return "ARM Assembly Printer";
|
||||
}
|
||||
|
||||
void EmitJumpTable(const MachineInstr *MI);
|
||||
void EmitJump2Table(const MachineInstr *MI);
|
||||
|
||||
void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O,
|
||||
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,
|
||||
unsigned AsmVariant, const char *ExtraCode,
|
||||
@ -195,9 +97,8 @@ namespace {
|
||||
unsigned AsmVariant,
|
||||
const char *ExtraCode, raw_ostream &O);
|
||||
|
||||
void printInstruction(const MachineInstr *MI, raw_ostream &O); // autogen
|
||||
static const char *getRegisterName(unsigned RegNo);
|
||||
|
||||
void EmitJumpTable(const MachineInstr *MI);
|
||||
void EmitJump2Table(const MachineInstr *MI);
|
||||
virtual void EmitInstruction(const MachineInstr *MI);
|
||||
bool runOnMachineFunction(MachineFunction &F);
|
||||
|
||||
@ -296,8 +197,6 @@ namespace {
|
||||
};
|
||||
} // end of anonymous namespace
|
||||
|
||||
#include "ARMGenAsmWriter.inc"
|
||||
|
||||
void ARMAsmPrinter::EmitFunctionEntryLabel() {
|
||||
if (AFI->isThumbFunction()) {
|
||||
OutStreamer.EmitRawText(StringRef("\t.code\t16"));
|
||||
@ -316,7 +215,7 @@ void ARMAsmPrinter::EmitFunctionEntryLabel() {
|
||||
OutStreamer.EmitLabel(CurrentFnSym);
|
||||
}
|
||||
|
||||
/// runOnMachineFunction - This uses the printInstruction()
|
||||
/// runOnMachineFunction - This uses the EmitInstruction()
|
||||
/// method to print assembly for each instruction.
|
||||
///
|
||||
bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
|
||||
@ -342,10 +241,10 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
|
||||
unsigned DReg =
|
||||
TM.getRegisterInfo()->getMatchingSuperReg(Reg,
|
||||
RegNum & 1 ? ARM::ssub_1 : ARM::ssub_0, &ARM::DPR_VFP2RegClass);
|
||||
O << getRegisterName(DReg) << '[' << (RegNum & 1) << ']';
|
||||
O << ARMInstPrinter::getRegisterName(DReg) << '[' << (RegNum & 1) << ']';
|
||||
} else {
|
||||
assert(!MO.getSubReg() && "Subregs should be eliminated!");
|
||||
O << getRegisterName(Reg);
|
||||
O << ARMInstPrinter::getRegisterName(Reg);
|
||||
}
|
||||
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::
|
||||
GetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2,
|
||||
const MachineBasicBlock *MBB) const {
|
||||
@ -959,128 +328,6 @@ MCSymbol *ARMAsmPrinter::GetARMSJLJEHLabel(void) const {
|
||||
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,
|
||||
unsigned AsmVariant, const char *ExtraCode,
|
||||
raw_ostream &O) {
|
||||
@ -1092,14 +339,14 @@ bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
|
||||
default: return true; // Unknown modifier.
|
||||
case 'a': // Print as a memory address.
|
||||
if (MI->getOperand(OpNum).isReg()) {
|
||||
O << "[" << getRegisterName(MI->getOperand(OpNum).getReg()) << "]";
|
||||
O << "[" << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg()) << "]";
|
||||
return false;
|
||||
}
|
||||
// Fallthrough
|
||||
case 'c': // Don't print "#" before an immediate operand.
|
||||
if (!MI->getOperand(OpNum).isImm())
|
||||
return true;
|
||||
printNoHashImmediate(MI, OpNum, O);
|
||||
O << MI->getOperand(OpNum).getImm();
|
||||
return false;
|
||||
case 'P': // Print a VFP double 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);
|
||||
assert(MO.isReg() && "unexpected inline asm memory operand");
|
||||
O << "[" << getRegisterName(MO.getReg()) << "]";
|
||||
O << "[" << ARMInstPrinter::getRegisterName(MO.getReg()) << "]";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -22,12 +22,7 @@
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
using namespace llvm;
|
||||
|
||||
// Include the auto-generated portion of the assembly writer.
|
||||
#define MachineInstr MCInst
|
||||
#define ARMAsmPrinter ARMInstPrinter // FIXME: REMOVE.
|
||||
#include "ARMGenAsmWriter.inc"
|
||||
#undef MachineInstr
|
||||
#undef ARMAsmPrinter
|
||||
|
||||
static unsigned getDPRSuperRegForSPR(unsigned Reg) {
|
||||
switch (Reg) {
|
||||
|
Loading…
Reference in New Issue
Block a user