mirror of
https://github.com/RPCS3/llvm.git
synced 2025-04-04 06:12:18 +00:00
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:
parent
f822ee999f
commit
5ab29b504d
@ -433,16 +433,14 @@ void Printer::printOp(const MachineOperand &MO,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const std::string sizePtr(const TargetInstrDescriptor &Desc) {
|
static const char* const sizePtr(const TargetInstrDescriptor &Desc) {
|
||||||
switch (Desc.TSFlags & X86II::ArgMask) {
|
switch (Desc.TSFlags & X86II::MemMask) {
|
||||||
default: assert(0 && "Unknown arg size!");
|
default: assert(0 && "Unknown arg size!");
|
||||||
case X86II::Arg8: return "BYTE PTR";
|
case X86II::Mem8: return "BYTE PTR";
|
||||||
case X86II::Arg16: return "WORD PTR";
|
case X86II::Mem16: return "WORD PTR";
|
||||||
case X86II::Arg32: return "DWORD PTR";
|
case X86II::Mem32: return "DWORD PTR";
|
||||||
case X86II::Arg64: return "QWORD PTR";
|
case X86II::Mem64: return "QWORD PTR";
|
||||||
case X86II::ArgF32: return "DWORD PTR";
|
case X86II::Mem80: return "XWORD PTR";
|
||||||
case X86II::ArgF64: return "QWORD PTR";
|
|
||||||
case X86II::ArgF80: return "XWORD PTR";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,10 +33,10 @@ def X86InstrInfo : InstrInfo {
|
|||||||
|
|
||||||
// Define how we want to layout our TargetSpecific information field... This
|
// 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.
|
// should be kept up-to-date with the fields in the X86InstrInfo.h file.
|
||||||
let TSFlagsFields = ["FormBits" , "hasOpSizePrefix" , "Prefix", "TypeBits",
|
let TSFlagsFields = ["FormBits" , "hasOpSizePrefix" , "Prefix", "MemTypeBits",
|
||||||
"FPFormBits", "printImplicitUses", "Opcode"];
|
"ImmTypeBits", "FPFormBits", "printImplicitUses", "Opcode"];
|
||||||
let TSFlagsShifts = [ 0, 5, 6, 10,
|
let TSFlagsShifts = [0, 5, 6, 10, 13,
|
||||||
13, 16, 17];
|
15, 18, 19];
|
||||||
}
|
}
|
||||||
|
|
||||||
def X86 : Target {
|
def X86 : Target {
|
||||||
|
@ -433,16 +433,14 @@ void Printer::printOp(const MachineOperand &MO,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const std::string sizePtr(const TargetInstrDescriptor &Desc) {
|
static const char* const sizePtr(const TargetInstrDescriptor &Desc) {
|
||||||
switch (Desc.TSFlags & X86II::ArgMask) {
|
switch (Desc.TSFlags & X86II::MemMask) {
|
||||||
default: assert(0 && "Unknown arg size!");
|
default: assert(0 && "Unknown arg size!");
|
||||||
case X86II::Arg8: return "BYTE PTR";
|
case X86II::Mem8: return "BYTE PTR";
|
||||||
case X86II::Arg16: return "WORD PTR";
|
case X86II::Mem16: return "WORD PTR";
|
||||||
case X86II::Arg32: return "DWORD PTR";
|
case X86II::Mem32: return "DWORD PTR";
|
||||||
case X86II::Arg64: return "QWORD PTR";
|
case X86II::Mem64: return "QWORD PTR";
|
||||||
case X86II::ArgF32: return "DWORD PTR";
|
case X86II::Mem80: return "XWORD PTR";
|
||||||
case X86II::ArgF64: return "QWORD PTR";
|
|
||||||
case X86II::ArgF80: return "XWORD PTR";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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) {
|
static unsigned sizeOfPtr(const TargetInstrDescriptor &Desc) {
|
||||||
switch (Desc.TSFlags & X86II::ArgMask) {
|
switch (Desc.TSFlags & X86II::MemMask) {
|
||||||
case X86II::Arg8: return 1;
|
case X86II::Mem8: return 1;
|
||||||
case X86II::Arg16: return 2;
|
case X86II::Mem16: return 2;
|
||||||
case X86II::Arg32: return 4;
|
case X86II::Mem32: return 4;
|
||||||
case X86II::ArgF32: return 4;
|
case X86II::Mem64: return 8;
|
||||||
case X86II::ArgF64: return 8;
|
case X86II::Mem80: return 10;
|
||||||
case X86II::ArgF80: return 10;
|
case X86II::Mem128: return 16;
|
||||||
default: assert(0 && "Memory size not set!");
|
default: assert(0 && "Memory size not set!");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -527,25 +537,21 @@ void Emitter::emitInstruction(MachineInstr &MI) {
|
|||||||
MCE.emitByte(BaseOpcode + getX86RegNum(MI.getOperand(0).getReg()));
|
MCE.emitByte(BaseOpcode + getX86RegNum(MI.getOperand(0).getReg()));
|
||||||
if (MI.getNumOperands() == 2) {
|
if (MI.getNumOperands() == 2) {
|
||||||
MachineOperand &MO1 = MI.getOperand(1);
|
MachineOperand &MO1 = MI.getOperand(1);
|
||||||
if (MO1.isImmediate() || MO1.getVRegValueOrNull() ||
|
if (Value *V = MO1.getVRegValueOrNull()) {
|
||||||
MO1.isGlobalAddress() || MO1.isExternalSymbol()) {
|
assert(sizeOfImm(Desc) == 4 && "Don't know how to emit non-pointer values!");
|
||||||
unsigned Size = sizeOfPtr(Desc);
|
emitGlobalAddressForPtr(cast<GlobalValue>(V));
|
||||||
if (Value *V = MO1.getVRegValueOrNull()) {
|
} else if (MO1.isGlobalAddress()) {
|
||||||
assert(Size == 4 && "Don't know how to emit non-pointer values!");
|
assert(sizeOfImm(Desc) == 4 && "Don't know how to emit non-pointer values!");
|
||||||
emitGlobalAddressForPtr(cast<GlobalValue>(V));
|
assert(!MO1.isPCRelative() && "Function pointer ref is PC relative?");
|
||||||
} else if (MO1.isGlobalAddress()) {
|
emitGlobalAddressForPtr(MO1.getGlobal());
|
||||||
assert(Size == 4 && "Don't know how to emit non-pointer values!");
|
} else if (MO1.isExternalSymbol()) {
|
||||||
assert(!MO1.isPCRelative() && "Function pointer ref is PC relative?");
|
assert(sizeOfImm(Desc) == 4 && "Don't know how to emit non-pointer values!");
|
||||||
emitGlobalAddressForPtr(MO1.getGlobal());
|
|
||||||
} else if (MO1.isExternalSymbol()) {
|
|
||||||
assert(Size == 4 && "Don't know how to emit non-pointer values!");
|
|
||||||
|
|
||||||
unsigned Address = MCE.getGlobalValueAddress(MO1.getSymbolName());
|
unsigned Address = MCE.getGlobalValueAddress(MO1.getSymbolName());
|
||||||
assert(Address && "Unknown external symbol!");
|
assert(Address && "Unknown external symbol!");
|
||||||
emitMaybePCRelativeValue(Address, MO1.isPCRelative());
|
emitMaybePCRelativeValue(Address, MO1.isPCRelative());
|
||||||
} else {
|
} else {
|
||||||
emitConstant(MO1.getImmedValue(), Size);
|
emitConstant(MO1.getImmedValue(), sizeOfImm(Desc));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -555,7 +561,7 @@ void Emitter::emitInstruction(MachineInstr &MI) {
|
|||||||
emitRegModRMByte(MI.getOperand(0).getReg(),
|
emitRegModRMByte(MI.getOperand(0).getReg(),
|
||||||
getX86RegNum(MI.getOperand(1).getReg()));
|
getX86RegNum(MI.getOperand(1).getReg()));
|
||||||
if (MI.getNumOperands() == 3)
|
if (MI.getNumOperands() == 3)
|
||||||
emitConstant(MI.getOperand(2).getImmedValue(), sizeOfPtr(Desc));
|
emitConstant(MI.getOperand(2).getImmedValue(), sizeOfImm(Desc));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case X86II::MRMDestMem:
|
case X86II::MRMDestMem:
|
||||||
@ -569,14 +575,14 @@ void Emitter::emitInstruction(MachineInstr &MI) {
|
|||||||
emitRegModRMByte(MI.getOperand(1).getReg(),
|
emitRegModRMByte(MI.getOperand(1).getReg(),
|
||||||
getX86RegNum(MI.getOperand(0).getReg()));
|
getX86RegNum(MI.getOperand(0).getReg()));
|
||||||
if (MI.getNumOperands() == 3)
|
if (MI.getNumOperands() == 3)
|
||||||
emitConstant(MI.getOperand(2).getImmedValue(), sizeOfPtr(Desc));
|
emitConstant(MI.getOperand(2).getImmedValue(), sizeOfImm(Desc));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case X86II::MRMSrcMem:
|
case X86II::MRMSrcMem:
|
||||||
MCE.emitByte(BaseOpcode);
|
MCE.emitByte(BaseOpcode);
|
||||||
emitMemModRMByte(MI, 1, getX86RegNum(MI.getOperand(0).getReg()));
|
emitMemModRMByte(MI, 1, getX86RegNum(MI.getOperand(0).getReg()));
|
||||||
if (MI.getNumOperands() == 2+4)
|
if (MI.getNumOperands() == 2+4)
|
||||||
emitConstant(MI.getOperand(5).getImmedValue(), sizeOfPtr(Desc));
|
emitConstant(MI.getOperand(5).getImmedValue(), sizeOfImm(Desc));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case X86II::MRM0r: case X86II::MRM1r:
|
case X86II::MRM0r: case X86II::MRM1r:
|
||||||
@ -588,8 +594,7 @@ void Emitter::emitInstruction(MachineInstr &MI) {
|
|||||||
(Desc.TSFlags & X86II::FormMask)-X86II::MRM0r);
|
(Desc.TSFlags & X86II::FormMask)-X86II::MRM0r);
|
||||||
|
|
||||||
if (MI.getOperand(MI.getNumOperands()-1).isImmediate()) {
|
if (MI.getOperand(MI.getNumOperands()-1).isImmediate()) {
|
||||||
unsigned Size = sizeOfPtr(Desc);
|
emitConstant(MI.getOperand(MI.getNumOperands()-1).getImmedValue(), sizeOfImm(Desc));
|
||||||
emitConstant(MI.getOperand(MI.getNumOperands()-1).getImmedValue(), Size);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -601,9 +606,8 @@ void Emitter::emitInstruction(MachineInstr &MI) {
|
|||||||
emitMemModRMByte(MI, 0, (Desc.TSFlags & X86II::FormMask)-X86II::MRM0m);
|
emitMemModRMByte(MI, 0, (Desc.TSFlags & X86II::FormMask)-X86II::MRM0m);
|
||||||
|
|
||||||
if (MI.getNumOperands() == 5) {
|
if (MI.getNumOperands() == 5) {
|
||||||
unsigned Size = sizeOfPtr(Desc);
|
|
||||||
if (MI.getOperand(4).isImmediate())
|
if (MI.getOperand(4).isImmediate())
|
||||||
emitConstant(MI.getOperand(4).getImmedValue(), Size);
|
emitConstant(MI.getOperand(4).getImmedValue(), sizeOfImm(Desc));
|
||||||
else if (MI.getOperand(4).isGlobalAddress())
|
else if (MI.getOperand(4).isGlobalAddress())
|
||||||
emitGlobalAddressForPtr(MI.getOperand(4).getGlobal());
|
emitGlobalAddressForPtr(MI.getOperand(4).getGlobal());
|
||||||
else
|
else
|
||||||
|
@ -111,21 +111,29 @@ namespace X86II {
|
|||||||
//===------------------------------------------------------------------===//
|
//===------------------------------------------------------------------===//
|
||||||
// This three-bit field describes the size of a memory operand. Zero is
|
// 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.
|
// unused so that we can tell if we forgot to set a value.
|
||||||
ArgShift = 10,
|
MemShift = 10,
|
||||||
ArgMask = 7 << ArgShift,
|
MemMask = 7 << MemShift,
|
||||||
Arg8 = 1 << ArgShift,
|
Mem8 = 1 << MemShift,
|
||||||
Arg16 = 2 << ArgShift,
|
Mem16 = 2 << MemShift,
|
||||||
Arg32 = 3 << ArgShift,
|
Mem32 = 3 << MemShift,
|
||||||
Arg64 = 4 << ArgShift, // 64 bit int argument for FILD64
|
Mem64 = 4 << MemShift,
|
||||||
ArgF32 = 5 << ArgShift,
|
Mem80 = 5 << MemShift,
|
||||||
ArgF64 = 6 << ArgShift,
|
Mem128 = 6 << MemShift,
|
||||||
ArgF80 = 7 << ArgShift,
|
|
||||||
|
//===------------------------------------------------------------------===//
|
||||||
|
// 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.
|
// FP Instruction Classification... Zero is non-fp instruction.
|
||||||
|
|
||||||
// FPTypeMask - Mask for all of the FP types...
|
// FPTypeMask - Mask for all of the FP types...
|
||||||
FPTypeShift = 13,
|
FPTypeShift = 15,
|
||||||
FPTypeMask = 7 << FPTypeShift,
|
FPTypeMask = 7 << FPTypeShift,
|
||||||
|
|
||||||
// NotFP - The default, set for instructions that do not use FP registers.
|
// NotFP - The default, set for instructions that do not use FP registers.
|
||||||
@ -151,9 +159,9 @@ namespace X86II {
|
|||||||
SpecialFP = 5 << FPTypeShift,
|
SpecialFP = 5 << FPTypeShift,
|
||||||
|
|
||||||
// PrintImplUses - Print out implicit uses in the assembly output.
|
// PrintImplUses - Print out implicit uses in the assembly output.
|
||||||
PrintImplUses = 1 << 16,
|
PrintImplUses = 1 << 18,
|
||||||
|
|
||||||
OpcodeShift = 17,
|
OpcodeShift = 19,
|
||||||
OpcodeMask = 0xFF << OpcodeShift,
|
OpcodeMask = 0xFF << OpcodeShift,
|
||||||
// Bits 25 -> 31 are unused
|
// Bits 25 -> 31 are unused
|
||||||
};
|
};
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user