Each instruction now has both an ImmType and a MemType. This describes

the size of the immediate and the memory operand on instructions that
use them. This resolves problems with instructions that take both a
memory and an immediate operand but their sizes differ (i.e. ADDmi32b).


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@11967 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Alkis Evlogimenos 2004-02-28 22:02:05 +00:00
parent f822ee999f
commit 5ab29b504d
6 changed files with 548 additions and 506 deletions

View File

@ -433,16 +433,14 @@ void Printer::printOp(const MachineOperand &MO,
}
}
static const std::string sizePtr(const TargetInstrDescriptor &Desc) {
switch (Desc.TSFlags & X86II::ArgMask) {
static const char* const sizePtr(const TargetInstrDescriptor &Desc) {
switch (Desc.TSFlags & X86II::MemMask) {
default: assert(0 && "Unknown arg size!");
case X86II::Arg8: return "BYTE PTR";
case X86II::Arg16: return "WORD PTR";
case X86II::Arg32: return "DWORD PTR";
case X86II::Arg64: return "QWORD PTR";
case X86II::ArgF32: return "DWORD PTR";
case X86II::ArgF64: return "QWORD PTR";
case X86II::ArgF80: return "XWORD PTR";
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";
}
}

View File

@ -33,10 +33,10 @@ def X86InstrInfo : InstrInfo {
// Define how we want to layout our TargetSpecific information field... This
// should be kept up-to-date with the fields in the X86InstrInfo.h file.
let TSFlagsFields = ["FormBits" , "hasOpSizePrefix" , "Prefix", "TypeBits",
"FPFormBits", "printImplicitUses", "Opcode"];
let TSFlagsShifts = [ 0, 5, 6, 10,
13, 16, 17];
let TSFlagsFields = ["FormBits" , "hasOpSizePrefix" , "Prefix", "MemTypeBits",
"ImmTypeBits", "FPFormBits", "printImplicitUses", "Opcode"];
let TSFlagsShifts = [0, 5, 6, 10, 13,
15, 18, 19];
}
def X86 : Target {

View File

@ -433,16 +433,14 @@ void Printer::printOp(const MachineOperand &MO,
}
}
static const std::string sizePtr(const TargetInstrDescriptor &Desc) {
switch (Desc.TSFlags & X86II::ArgMask) {
static const char* const sizePtr(const TargetInstrDescriptor &Desc) {
switch (Desc.TSFlags & X86II::MemMask) {
default: assert(0 && "Unknown arg size!");
case X86II::Arg8: return "BYTE PTR";
case X86II::Arg16: return "WORD PTR";
case X86II::Arg32: return "DWORD PTR";
case X86II::Arg64: return "QWORD PTR";
case X86II::ArgF32: return "DWORD PTR";
case X86II::ArgF64: return "QWORD PTR";
case X86II::ArgF80: return "XWORD PTR";
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";
}
}

View File

@ -453,14 +453,24 @@ void Emitter::emitMemModRMByte(const MachineInstr &MI,
}
}
static unsigned sizeOfImm(const TargetInstrDescriptor &Desc) {
switch (Desc.TSFlags & X86II::ImmMask) {
case X86II::Imm8: return 1;
case X86II::Imm16: return 2;
case X86II::Imm32: return 4;
default: assert(0 && "Immediate size not set!");
return 0;
}
}
static unsigned sizeOfPtr(const TargetInstrDescriptor &Desc) {
switch (Desc.TSFlags & X86II::ArgMask) {
case X86II::Arg8: return 1;
case X86II::Arg16: return 2;
case X86II::Arg32: return 4;
case X86II::ArgF32: return 4;
case X86II::ArgF64: return 8;
case X86II::ArgF80: return 10;
switch (Desc.TSFlags & X86II::MemMask) {
case X86II::Mem8: return 1;
case X86II::Mem16: return 2;
case X86II::Mem32: return 4;
case X86II::Mem64: return 8;
case X86II::Mem80: return 10;
case X86II::Mem128: return 16;
default: assert(0 && "Memory size not set!");
return 0;
}
@ -527,25 +537,21 @@ void Emitter::emitInstruction(MachineInstr &MI) {
MCE.emitByte(BaseOpcode + getX86RegNum(MI.getOperand(0).getReg()));
if (MI.getNumOperands() == 2) {
MachineOperand &MO1 = MI.getOperand(1);
if (MO1.isImmediate() || MO1.getVRegValueOrNull() ||
MO1.isGlobalAddress() || MO1.isExternalSymbol()) {
unsigned Size = sizeOfPtr(Desc);
if (Value *V = MO1.getVRegValueOrNull()) {
assert(Size == 4 && "Don't know how to emit non-pointer values!");
emitGlobalAddressForPtr(cast<GlobalValue>(V));
} else if (MO1.isGlobalAddress()) {
assert(Size == 4 && "Don't know how to emit non-pointer values!");
assert(!MO1.isPCRelative() && "Function pointer ref is PC relative?");
emitGlobalAddressForPtr(MO1.getGlobal());
} else if (MO1.isExternalSymbol()) {
assert(Size == 4 && "Don't know how to emit non-pointer values!");
if (Value *V = MO1.getVRegValueOrNull()) {
assert(sizeOfImm(Desc) == 4 && "Don't know how to emit non-pointer values!");
emitGlobalAddressForPtr(cast<GlobalValue>(V));
} else if (MO1.isGlobalAddress()) {
assert(sizeOfImm(Desc) == 4 && "Don't know how to emit non-pointer values!");
assert(!MO1.isPCRelative() && "Function pointer ref is PC relative?");
emitGlobalAddressForPtr(MO1.getGlobal());
} else if (MO1.isExternalSymbol()) {
assert(sizeOfImm(Desc) == 4 && "Don't know how to emit non-pointer values!");
unsigned Address = MCE.getGlobalValueAddress(MO1.getSymbolName());
assert(Address && "Unknown external symbol!");
emitMaybePCRelativeValue(Address, MO1.isPCRelative());
} else {
emitConstant(MO1.getImmedValue(), Size);
}
unsigned Address = MCE.getGlobalValueAddress(MO1.getSymbolName());
assert(Address && "Unknown external symbol!");
emitMaybePCRelativeValue(Address, MO1.isPCRelative());
} else {
emitConstant(MO1.getImmedValue(), sizeOfImm(Desc));
}
}
break;
@ -555,7 +561,7 @@ void Emitter::emitInstruction(MachineInstr &MI) {
emitRegModRMByte(MI.getOperand(0).getReg(),
getX86RegNum(MI.getOperand(1).getReg()));
if (MI.getNumOperands() == 3)
emitConstant(MI.getOperand(2).getImmedValue(), sizeOfPtr(Desc));
emitConstant(MI.getOperand(2).getImmedValue(), sizeOfImm(Desc));
break;
}
case X86II::MRMDestMem:
@ -569,14 +575,14 @@ void Emitter::emitInstruction(MachineInstr &MI) {
emitRegModRMByte(MI.getOperand(1).getReg(),
getX86RegNum(MI.getOperand(0).getReg()));
if (MI.getNumOperands() == 3)
emitConstant(MI.getOperand(2).getImmedValue(), sizeOfPtr(Desc));
emitConstant(MI.getOperand(2).getImmedValue(), sizeOfImm(Desc));
break;
case X86II::MRMSrcMem:
MCE.emitByte(BaseOpcode);
emitMemModRMByte(MI, 1, getX86RegNum(MI.getOperand(0).getReg()));
if (MI.getNumOperands() == 2+4)
emitConstant(MI.getOperand(5).getImmedValue(), sizeOfPtr(Desc));
emitConstant(MI.getOperand(5).getImmedValue(), sizeOfImm(Desc));
break;
case X86II::MRM0r: case X86II::MRM1r:
@ -588,8 +594,7 @@ void Emitter::emitInstruction(MachineInstr &MI) {
(Desc.TSFlags & X86II::FormMask)-X86II::MRM0r);
if (MI.getOperand(MI.getNumOperands()-1).isImmediate()) {
unsigned Size = sizeOfPtr(Desc);
emitConstant(MI.getOperand(MI.getNumOperands()-1).getImmedValue(), Size);
emitConstant(MI.getOperand(MI.getNumOperands()-1).getImmedValue(), sizeOfImm(Desc));
}
break;
@ -601,9 +606,8 @@ void Emitter::emitInstruction(MachineInstr &MI) {
emitMemModRMByte(MI, 0, (Desc.TSFlags & X86II::FormMask)-X86II::MRM0m);
if (MI.getNumOperands() == 5) {
unsigned Size = sizeOfPtr(Desc);
if (MI.getOperand(4).isImmediate())
emitConstant(MI.getOperand(4).getImmedValue(), Size);
emitConstant(MI.getOperand(4).getImmedValue(), sizeOfImm(Desc));
else if (MI.getOperand(4).isGlobalAddress())
emitGlobalAddressForPtr(MI.getOperand(4).getGlobal());
else

View File

@ -111,21 +111,29 @@ namespace X86II {
//===------------------------------------------------------------------===//
// This three-bit field describes the size of a memory operand. Zero is
// unused so that we can tell if we forgot to set a value.
ArgShift = 10,
ArgMask = 7 << ArgShift,
Arg8 = 1 << ArgShift,
Arg16 = 2 << ArgShift,
Arg32 = 3 << ArgShift,
Arg64 = 4 << ArgShift, // 64 bit int argument for FILD64
ArgF32 = 5 << ArgShift,
ArgF64 = 6 << ArgShift,
ArgF80 = 7 << ArgShift,
MemShift = 10,
MemMask = 7 << MemShift,
Mem8 = 1 << MemShift,
Mem16 = 2 << MemShift,
Mem32 = 3 << MemShift,
Mem64 = 4 << MemShift,
Mem80 = 5 << MemShift,
Mem128 = 6 << MemShift,
//===------------------------------------------------------------------===//
// This tow-bit field describes the size of an immediate operand. Zero is
// unused so that we can tell if we forgot to set a value.
ImmShift = 13,
ImmMask = 7 << ImmShift,
Imm8 = 1 << ImmShift,
Imm16 = 2 << ImmShift,
Imm32 = 3 << ImmShift,
//===------------------------------------------------------------------===//
// FP Instruction Classification... Zero is non-fp instruction.
// FPTypeMask - Mask for all of the FP types...
FPTypeShift = 13,
FPTypeShift = 15,
FPTypeMask = 7 << FPTypeShift,
// NotFP - The default, set for instructions that do not use FP registers.
@ -151,9 +159,9 @@ namespace X86II {
SpecialFP = 5 << FPTypeShift,
// PrintImplUses - Print out implicit uses in the assembly output.
PrintImplUses = 1 << 16,
PrintImplUses = 1 << 18,
OpcodeShift = 17,
OpcodeShift = 19,
OpcodeMask = 0xFF << OpcodeShift,
// Bits 25 -> 31 are unused
};

File diff suppressed because it is too large Load Diff