mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-01 00:33:09 +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) {
|
||||
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";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user