forked from OSchip/llvm-project
Finally, the entire instruction asmprinter is now generated from tblgen, woo!
llvm-svn: 15658
This commit is contained in:
parent
a0bafce127
commit
d1bee6ee12
|
@ -438,8 +438,8 @@ static bool isMem(const MachineInstr *MI, unsigned Op) {
|
||||||
if (MI->getOperand(Op).isFrameIndex()) return true;
|
if (MI->getOperand(Op).isFrameIndex()) return true;
|
||||||
if (MI->getOperand(Op).isConstantPoolIndex()) return true;
|
if (MI->getOperand(Op).isConstantPoolIndex()) return true;
|
||||||
return Op+4 <= MI->getNumOperands() &&
|
return Op+4 <= MI->getNumOperands() &&
|
||||||
MI->getOperand(Op ).isRegister() &&isScale(MI->getOperand(Op+1)) &&
|
MI->getOperand(Op ).isRegister() && isScale(MI->getOperand(Op+1)) &&
|
||||||
MI->getOperand(Op+2).isRegister() &&MI->getOperand(Op+3).isImmediate();
|
MI->getOperand(Op+2).isRegister() && MI->getOperand(Op+3).isImmediate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -490,17 +490,6 @@ void X86AsmPrinter::printOp(const MachineOperand &MO,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* const sizePtr(const TargetInstrDescriptor &Desc) {
|
|
||||||
switch (Desc.TSFlags & X86II::MemMask) {
|
|
||||||
default: assert(0 && "Unknown arg size!");
|
|
||||||
case X86II::Mem8: return "BYTE PTR";
|
|
||||||
case X86II::Mem16: return "WORD PTR";
|
|
||||||
case X86II::Mem32: return "DWORD PTR";
|
|
||||||
case X86II::Mem64: return "QWORD PTR";
|
|
||||||
case X86II::Mem80: return "XWORD PTR";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void X86AsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op) {
|
void X86AsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op) {
|
||||||
assert(isMem(MI, Op) && "Invalid memory reference!");
|
assert(isMem(MI, Op) && "Invalid memory reference!");
|
||||||
|
|
||||||
|
@ -619,289 +608,12 @@ void X86AsmPrinter::printMachineInstruction(const MachineInstr *MI) {
|
||||||
O << "\t# ";
|
O << "\t# ";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (printInstruction(MI))
|
// Call the autogenerated instruction printer routines.
|
||||||
return; // Printer was automatically generated
|
bool Handled = printInstruction(MI);
|
||||||
|
if (!Handled) {
|
||||||
MI->dump();
|
MI->dump();
|
||||||
abort();
|
assert(0 && "Do not know how to print this instruction!");
|
||||||
|
abort();
|
||||||
unsigned Opcode = MI->getOpcode();
|
|
||||||
const TargetInstrInfo &TII = *TM.getInstrInfo();
|
|
||||||
const TargetInstrDescriptor &Desc = TII.get(Opcode);
|
|
||||||
|
|
||||||
switch (Desc.TSFlags & X86II::FormMask) {
|
|
||||||
case X86II::Pseudo:
|
|
||||||
// Print pseudo-instructions as comments; either they should have been
|
|
||||||
// turned into real instructions by now, or they don't need to be
|
|
||||||
// seen by the assembler (e.g., IMPLICIT_USEs.)
|
|
||||||
O << "# ";
|
|
||||||
if (Opcode == X86::PHI) {
|
|
||||||
printOp(MI->getOperand(0));
|
|
||||||
O << " = phi ";
|
|
||||||
for (unsigned i = 1, e = MI->getNumOperands(); i != e; i+=2) {
|
|
||||||
if (i != 1) O << ", ";
|
|
||||||
O << "[";
|
|
||||||
printOp(MI->getOperand(i));
|
|
||||||
O << ", ";
|
|
||||||
printOp(MI->getOperand(i+1));
|
|
||||||
O << "]";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
unsigned i = 0;
|
|
||||||
if (MI->getNumOperands() && MI->getOperand(0).isDef()) {
|
|
||||||
printOp(MI->getOperand(0));
|
|
||||||
O << " = ";
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
O << TII.getName(MI->getOpcode());
|
|
||||||
|
|
||||||
for (unsigned e = MI->getNumOperands(); i != e; ++i) {
|
|
||||||
O << " ";
|
|
||||||
if (MI->getOperand(i).isDef()) O << "*";
|
|
||||||
printOp(MI->getOperand(i));
|
|
||||||
if (MI->getOperand(i).isDef()) O << "*";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
O << "\n";
|
|
||||||
return;
|
|
||||||
|
|
||||||
case X86II::RawFrm:
|
|
||||||
{
|
|
||||||
// The accepted forms of Raw instructions are:
|
|
||||||
// 1. jmp foo - MachineBasicBlock operand
|
|
||||||
// 2. call bar - GlobalAddress Operand or External Symbol Operand
|
|
||||||
// 3. in AL, imm - Immediate operand
|
|
||||||
//
|
|
||||||
assert(MI->getNumOperands() == 1 &&
|
|
||||||
(MI->getOperand(0).isMachineBasicBlock() ||
|
|
||||||
MI->getOperand(0).isGlobalAddress() ||
|
|
||||||
MI->getOperand(0).isExternalSymbol() ||
|
|
||||||
MI->getOperand(0).isImmediate()) &&
|
|
||||||
"Illegal raw instruction!");
|
|
||||||
O << TII.getName(MI->getOpcode()) << " ";
|
|
||||||
|
|
||||||
bool LeadingComma = false;
|
|
||||||
if (MI->getNumOperands() == 1) {
|
|
||||||
printOp(MI->getOperand(0), true); // Don't print "OFFSET"...
|
|
||||||
LeadingComma = true;
|
|
||||||
}
|
|
||||||
printImplUsesAfter(Desc, LeadingComma);
|
|
||||||
O << "\n";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
case X86II::AddRegFrm: {
|
|
||||||
// There are currently two forms of acceptable AddRegFrm instructions.
|
|
||||||
// Either the instruction JUST takes a single register (like inc, dec, etc),
|
|
||||||
// or it takes a register and an immediate of the same size as the register
|
|
||||||
// (move immediate f.e.). Note that this immediate value might be stored as
|
|
||||||
// an LLVM value, to represent, for example, loading the address of a global
|
|
||||||
// into a register. The initial register might be duplicated if this is a
|
|
||||||
// M_2_ADDR_REG instruction
|
|
||||||
//
|
|
||||||
assert(MI->getOperand(0).isRegister() &&
|
|
||||||
(MI->getNumOperands() == 1 ||
|
|
||||||
(MI->getNumOperands() == 2 &&
|
|
||||||
(MI->getOperand(1).getVRegValueOrNull() ||
|
|
||||||
MI->getOperand(1).isImmediate() ||
|
|
||||||
MI->getOperand(1).isRegister() ||
|
|
||||||
MI->getOperand(1).isGlobalAddress() ||
|
|
||||||
MI->getOperand(1).isExternalSymbol()))) &&
|
|
||||||
"Illegal form for AddRegFrm instruction!");
|
|
||||||
|
|
||||||
unsigned Reg = MI->getOperand(0).getReg();
|
|
||||||
|
|
||||||
O << TII.getName(MI->getOpcode()) << " ";
|
|
||||||
|
|
||||||
printOp(MI->getOperand(0));
|
|
||||||
if (MI->getNumOperands() == 2 &&
|
|
||||||
(!MI->getOperand(1).isRegister() ||
|
|
||||||
MI->getOperand(1).getVRegValueOrNull() ||
|
|
||||||
MI->getOperand(1).isGlobalAddress() ||
|
|
||||||
MI->getOperand(1).isExternalSymbol())) {
|
|
||||||
O << ", ";
|
|
||||||
printOp(MI->getOperand(1));
|
|
||||||
}
|
|
||||||
printImplUsesAfter(Desc);
|
|
||||||
O << "\n";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
case X86II::MRMDestReg: {
|
|
||||||
// There are three forms of MRMDestReg instructions, those with 2
|
|
||||||
// or 3 operands:
|
|
||||||
//
|
|
||||||
// 2 Operands: this is for things like mov that do not read a
|
|
||||||
// second input.
|
|
||||||
//
|
|
||||||
// 2 Operands: two address instructions which def&use the first
|
|
||||||
// argument and use the second as input.
|
|
||||||
//
|
|
||||||
// 3 Operands: in this form, two address instructions are the same
|
|
||||||
// as in 2 but have a constant argument as well.
|
|
||||||
//
|
|
||||||
bool isTwoAddr = TII.isTwoAddrInstr(Opcode);
|
|
||||||
assert(MI->getOperand(0).isRegister() &&
|
|
||||||
(MI->getNumOperands() == 2 ||
|
|
||||||
(MI->getNumOperands() == 3 && MI->getOperand(2).isImmediate()))
|
|
||||||
&& "Bad format for MRMDestReg!");
|
|
||||||
|
|
||||||
O << TII.getName(MI->getOpcode()) << " ";
|
|
||||||
printOp(MI->getOperand(0));
|
|
||||||
O << ", ";
|
|
||||||
printOp(MI->getOperand(1));
|
|
||||||
if (MI->getNumOperands() == 3) {
|
|
||||||
O << ", ";
|
|
||||||
printOp(MI->getOperand(2));
|
|
||||||
}
|
|
||||||
printImplUsesAfter(Desc);
|
|
||||||
O << "\n";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
case X86II::MRMDestMem: {
|
|
||||||
// These instructions are the same as MRMDestReg, but instead of having a
|
|
||||||
// register reference for the mod/rm field, it's a memory reference.
|
|
||||||
//
|
|
||||||
assert(isMem(MI, 0) &&
|
|
||||||
(MI->getNumOperands() == 4+1 ||
|
|
||||||
(MI->getNumOperands() == 4+2 && MI->getOperand(5).isImmediate()))
|
|
||||||
&& "Bad format for MRMDestMem!");
|
|
||||||
|
|
||||||
O << TII.getName(MI->getOpcode()) << " " << sizePtr(Desc) << " ";
|
|
||||||
printMemReference(MI, 0);
|
|
||||||
O << ", ";
|
|
||||||
printOp(MI->getOperand(4));
|
|
||||||
if (MI->getNumOperands() == 4+2) {
|
|
||||||
O << ", ";
|
|
||||||
printOp(MI->getOperand(5));
|
|
||||||
}
|
|
||||||
printImplUsesAfter(Desc);
|
|
||||||
O << "\n";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
case X86II::MRMSrcReg: {
|
|
||||||
// There are three forms that are acceptable for MRMSrcReg
|
|
||||||
// instructions, those with 2 or 3 operands:
|
|
||||||
//
|
|
||||||
// 2 Operands: this is for things like mov that do not read a
|
|
||||||
// second input.
|
|
||||||
//
|
|
||||||
// 2 Operands: in this form, the last register is the ModR/M
|
|
||||||
// input. The first operand is a def&use. This is for things
|
|
||||||
// like: add r32, r/m32
|
|
||||||
//
|
|
||||||
// 3 Operands: in this form, we can have 'INST R1, R2, imm', which is used
|
|
||||||
// for instructions like the IMULrri instructions.
|
|
||||||
//
|
|
||||||
//
|
|
||||||
assert(MI->getOperand(0).isRegister() &&
|
|
||||||
MI->getOperand(1).isRegister() &&
|
|
||||||
(MI->getNumOperands() == 2 ||
|
|
||||||
(MI->getNumOperands() == 3 &&
|
|
||||||
(MI->getOperand(2).isImmediate())))
|
|
||||||
&& "Bad format for MRMSrcReg!");
|
|
||||||
|
|
||||||
O << TII.getName(MI->getOpcode()) << " ";
|
|
||||||
printOp(MI->getOperand(0));
|
|
||||||
O << ", ";
|
|
||||||
printOp(MI->getOperand(1));
|
|
||||||
if (MI->getNumOperands() == 3) {
|
|
||||||
O << ", ";
|
|
||||||
printOp(MI->getOperand(2));
|
|
||||||
}
|
|
||||||
O << "\n";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
case X86II::MRMSrcMem: {
|
|
||||||
// These instructions are the same as MRMSrcReg, but instead of having a
|
|
||||||
// register reference for the mod/rm field, it's a memory reference.
|
|
||||||
//
|
|
||||||
assert(MI->getOperand(0).isRegister() &&
|
|
||||||
((MI->getNumOperands() == 1+4 && isMem(MI, 1)) ||
|
|
||||||
(MI->getNumOperands() == 2+4 && MI->getOperand(5).isImmediate() &&
|
|
||||||
isMem(MI, 1)))
|
|
||||||
&& "Bad format for MRMSrcMem!");
|
|
||||||
O << TII.getName(MI->getOpcode()) << " ";
|
|
||||||
printOp(MI->getOperand(0));
|
|
||||||
O << ", " << sizePtr(Desc) << " ";
|
|
||||||
printMemReference(MI, 1);
|
|
||||||
if (MI->getNumOperands() == 2+4) {
|
|
||||||
O << ", ";
|
|
||||||
printOp(MI->getOperand(5));
|
|
||||||
}
|
|
||||||
O << "\n";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
case X86II::MRM0r: case X86II::MRM1r:
|
|
||||||
case X86II::MRM2r: case X86II::MRM3r:
|
|
||||||
case X86II::MRM4r: case X86II::MRM5r:
|
|
||||||
case X86II::MRM6r: case X86II::MRM7r: {
|
|
||||||
// In this form, the following are valid formats:
|
|
||||||
// 1. sete r
|
|
||||||
// 2. cmp reg, immediate
|
|
||||||
// 2. shl rdest, rinput <implicit CL or 1>
|
|
||||||
// 3. sbb rdest, rinput, immediate [rdest = rinput]
|
|
||||||
//
|
|
||||||
assert(MI->getNumOperands() > 0 && MI->getNumOperands() < 4 &&
|
|
||||||
MI->getOperand(0).isRegister() && "Bad MRMSxR format!");
|
|
||||||
assert((MI->getNumOperands() != 2 ||
|
|
||||||
MI->getOperand(1).isRegister() || MI->getOperand(1).isImmediate())&&
|
|
||||||
"Bad MRMSxR format!");
|
|
||||||
assert((MI->getNumOperands() < 3 ||
|
|
||||||
(MI->getOperand(1).isRegister() && MI->getOperand(2).isImmediate())) &&
|
|
||||||
"Bad MRMSxR format!");
|
|
||||||
|
|
||||||
if (MI->getNumOperands() > 1 && MI->getOperand(1).isRegister() &&
|
|
||||||
MI->getOperand(0).getReg() != MI->getOperand(1).getReg())
|
|
||||||
O << "**";
|
|
||||||
|
|
||||||
O << TII.getName(MI->getOpcode()) << " ";
|
|
||||||
printOp(MI->getOperand(0));
|
|
||||||
if (MI->getOperand(MI->getNumOperands()-1).isImmediate()) {
|
|
||||||
O << ", ";
|
|
||||||
printOp(MI->getOperand(MI->getNumOperands()-1));
|
|
||||||
}
|
|
||||||
printImplUsesAfter(Desc);
|
|
||||||
O << "\n";
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
case X86II::MRM0m: case X86II::MRM1m:
|
|
||||||
case X86II::MRM2m: case X86II::MRM3m:
|
|
||||||
case X86II::MRM4m: case X86II::MRM5m:
|
|
||||||
case X86II::MRM6m: case X86II::MRM7m: {
|
|
||||||
// In this form, the following are valid formats:
|
|
||||||
// 1. sete [m]
|
|
||||||
// 2. cmp [m], immediate
|
|
||||||
// 2. shl [m], rinput <implicit CL or 1>
|
|
||||||
// 3. sbb [m], immediate
|
|
||||||
//
|
|
||||||
assert(MI->getNumOperands() >= 4 && MI->getNumOperands() <= 5 &&
|
|
||||||
isMem(MI, 0) && "Bad MRMSxM format!");
|
|
||||||
assert((MI->getNumOperands() != 5 ||
|
|
||||||
(MI->getOperand(4).isImmediate() ||
|
|
||||||
MI->getOperand(4).isGlobalAddress())) &&
|
|
||||||
"Bad MRMSxM format!");
|
|
||||||
|
|
||||||
const MachineOperand &Op3 = MI->getOperand(3);
|
|
||||||
|
|
||||||
O << TII.getName(MI->getOpcode()) << " ";
|
|
||||||
O << sizePtr(Desc) << " ";
|
|
||||||
printMemReference(MI, 0);
|
|
||||||
if (MI->getNumOperands() == 5) {
|
|
||||||
O << ", ";
|
|
||||||
printOp(MI->getOperand(4));
|
|
||||||
}
|
|
||||||
printImplUsesAfter(Desc);
|
|
||||||
O << "\n";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
O << "\tUNKNOWN FORM:\t\t-"; MI->print(O, &TM); break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue