mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-01 15:11:24 +00:00
XOP encoding bits and logic.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146397 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
cca33a3f24
commit
ebebe35d1c
@ -304,6 +304,12 @@ namespace X86II {
|
|||||||
// TAXD - Prefix before and after 0x0F. Combination of TA and XD.
|
// TAXD - Prefix before and after 0x0F. Combination of TA and XD.
|
||||||
TAXD = 19 << Op0Shift,
|
TAXD = 19 << Op0Shift,
|
||||||
|
|
||||||
|
// XOP8 - Prefix to include use of imm byte.
|
||||||
|
XOP8 = 20 << Op0Shift,
|
||||||
|
|
||||||
|
// XOP9 - Prefix to exclude use of imm byte.
|
||||||
|
XOP9 = 21 << Op0Shift,
|
||||||
|
|
||||||
//===------------------------------------------------------------------===//
|
//===------------------------------------------------------------------===//
|
||||||
// REX_W - REX prefixes are instruction prefixes used in 64-bit mode.
|
// REX_W - REX prefixes are instruction prefixes used in 64-bit mode.
|
||||||
// They are used to specify GPRs and SSE registers, 64-bit operand size,
|
// They are used to specify GPRs and SSE registers, 64-bit operand size,
|
||||||
@ -423,7 +429,11 @@ namespace X86II {
|
|||||||
/// XOP_W - Same bit as VEX_W. Used to indicate swapping of
|
/// XOP_W - Same bit as VEX_W. Used to indicate swapping of
|
||||||
/// operand 3 and 4 to be encoded in ModRM or I8IMM. This is used
|
/// operand 3 and 4 to be encoded in ModRM or I8IMM. This is used
|
||||||
/// for FMA4 and XOP instructions.
|
/// for FMA4 and XOP instructions.
|
||||||
XOP_W = 1U << 8
|
XOP_W = 1U << 8,
|
||||||
|
|
||||||
|
/// XOP - Opcode prefix used by XOP instructions.
|
||||||
|
XOP = 1U << 9
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// getBaseOpcodeFor - This function returns the "base" X86 opcode for the
|
// getBaseOpcodeFor - This function returns the "base" X86 opcode for the
|
||||||
|
@ -435,6 +435,9 @@ void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
|
|||||||
// swap operand 3 and 4 for FMA4 and XOP instructions
|
// swap operand 3 and 4 for FMA4 and XOP instructions
|
||||||
unsigned char XOP_W = 0;
|
unsigned char XOP_W = 0;
|
||||||
|
|
||||||
|
// XOP: Use XOP prefix byte 0x8f instead of VEX.
|
||||||
|
unsigned char XOP = 0;
|
||||||
|
|
||||||
// VEX_5M (VEX m-mmmmm field):
|
// VEX_5M (VEX m-mmmmm field):
|
||||||
//
|
//
|
||||||
// 0b00000: Reserved for future use
|
// 0b00000: Reserved for future use
|
||||||
@ -442,7 +445,8 @@ void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
|
|||||||
// 0b00010: implied 0F 38 leading opcode bytes
|
// 0b00010: implied 0F 38 leading opcode bytes
|
||||||
// 0b00011: implied 0F 3A leading opcode bytes
|
// 0b00011: implied 0F 3A leading opcode bytes
|
||||||
// 0b00100-0b11111: Reserved for future use
|
// 0b00100-0b11111: Reserved for future use
|
||||||
//
|
// 0b01000: XOP map select - 08h instructions with imm byte
|
||||||
|
// 0b10001: XOP map select - 09h instructions with no imm byte
|
||||||
unsigned char VEX_5M = 0x1;
|
unsigned char VEX_5M = 0x1;
|
||||||
|
|
||||||
// VEX_4V (VEX vvvv field): a register specifier
|
// VEX_4V (VEX vvvv field): a register specifier
|
||||||
@ -476,6 +480,9 @@ void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
|
|||||||
if ((TSFlags >> X86II::VEXShift) & X86II::XOP_W)
|
if ((TSFlags >> X86II::VEXShift) & X86II::XOP_W)
|
||||||
XOP_W = 1;
|
XOP_W = 1;
|
||||||
|
|
||||||
|
if ((TSFlags >> X86II::VEXShift) & X86II::XOP)
|
||||||
|
XOP = 1;
|
||||||
|
|
||||||
if ((TSFlags >> X86II::VEXShift) & X86II::VEX_L)
|
if ((TSFlags >> X86II::VEXShift) & X86II::VEX_L)
|
||||||
VEX_L = 1;
|
VEX_L = 1;
|
||||||
|
|
||||||
@ -505,6 +512,12 @@ void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
|
|||||||
case X86II::XD: // F2 0F
|
case X86II::XD: // F2 0F
|
||||||
VEX_PP = 0x3;
|
VEX_PP = 0x3;
|
||||||
break;
|
break;
|
||||||
|
case X86II::XOP8:
|
||||||
|
VEX_5M = 0x8;
|
||||||
|
break;
|
||||||
|
case X86II::XOP9:
|
||||||
|
VEX_5M = 0x9;
|
||||||
|
break;
|
||||||
case X86II::A6: // Bypass: Not used by VEX
|
case X86II::A6: // Bypass: Not used by VEX
|
||||||
case X86II::A7: // Bypass: Not used by VEX
|
case X86II::A7: // Bypass: Not used by VEX
|
||||||
case X86II::TB: // Bypass: Not used by VEX
|
case X86II::TB: // Bypass: Not used by VEX
|
||||||
@ -512,6 +525,7 @@ void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
|
|||||||
break; // No prefix!
|
break; // No prefix!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Set the vector length to 256-bit if YMM0-YMM15 is used
|
// Set the vector length to 256-bit if YMM0-YMM15 is used
|
||||||
for (unsigned i = 0; i != MI.getNumOperands(); ++i) {
|
for (unsigned i = 0; i != MI.getNumOperands(); ++i) {
|
||||||
if (!MI.getOperand(i).isReg())
|
if (!MI.getOperand(i).isReg())
|
||||||
@ -646,14 +660,14 @@ void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
|
|||||||
//
|
//
|
||||||
unsigned char LastByte = VEX_PP | (VEX_L << 2) | (VEX_4V << 3);
|
unsigned char LastByte = VEX_PP | (VEX_L << 2) | (VEX_4V << 3);
|
||||||
|
|
||||||
if (VEX_B && VEX_X && !VEX_W && (VEX_5M == 1)) { // 2 byte VEX prefix
|
if (VEX_B && VEX_X && !VEX_W && !XOP && (VEX_5M == 1)) { // 2 byte VEX prefix
|
||||||
EmitByte(0xC5, CurByte, OS);
|
EmitByte(0xC5, CurByte, OS);
|
||||||
EmitByte(LastByte | (VEX_R << 7), CurByte, OS);
|
EmitByte(LastByte | (VEX_R << 7), CurByte, OS);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3 byte VEX prefix
|
// 3 byte VEX prefix
|
||||||
EmitByte(0xC4, CurByte, OS);
|
EmitByte(XOP ? 0x8F : 0xC4, CurByte, OS);
|
||||||
EmitByte(VEX_R << 7 | VEX_X << 6 | VEX_B << 5 | VEX_5M, CurByte, OS);
|
EmitByte(VEX_R << 7 | VEX_X << 6 | VEX_B << 5 | VEX_5M, CurByte, OS);
|
||||||
EmitByte(LastByte | ((VEX_W | XOP_W) << 7), CurByte, OS);
|
EmitByte(LastByte | ((VEX_W | XOP_W) << 7), CurByte, OS);
|
||||||
}
|
}
|
||||||
@ -1097,7 +1111,7 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS,
|
|||||||
// according to the right size for the instruction.
|
// according to the right size for the instruction.
|
||||||
if (CurOp != NumOps) {
|
if (CurOp != NumOps) {
|
||||||
// The last source register of a 4 operand instruction in AVX is encoded
|
// The last source register of a 4 operand instruction in AVX is encoded
|
||||||
// in bits[7:4] of a immediate byte, and bits[3:0] are ignored.
|
// in bits[7:4] of a immediate byte.
|
||||||
if ((TSFlags >> X86II::VEXShift) & X86II::VEX_I8IMM) {
|
if ((TSFlags >> X86II::VEXShift) & X86II::VEX_I8IMM) {
|
||||||
const MCOperand &MO = MI.getOperand(HasXOP_W ? XOP_W_I8IMMOperand
|
const MCOperand &MO = MI.getOperand(HasXOP_W ? XOP_W_I8IMMOperand
|
||||||
: CurOp);
|
: CurOp);
|
||||||
@ -1105,6 +1119,16 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS,
|
|||||||
bool IsExtReg = X86II::isX86_64ExtendedReg(MO.getReg());
|
bool IsExtReg = X86II::isX86_64ExtendedReg(MO.getReg());
|
||||||
unsigned RegNum = (IsExtReg ? (1 << 7) : 0);
|
unsigned RegNum = (IsExtReg ? (1 << 7) : 0);
|
||||||
RegNum |= GetX86RegNum(MO) << 4;
|
RegNum |= GetX86RegNum(MO) << 4;
|
||||||
|
// If there is an additional 5th operand it must be an immediate, which
|
||||||
|
// is encoded in bits[3:0]
|
||||||
|
if(CurOp != NumOps) {
|
||||||
|
const MCOperand &MIMM = MI.getOperand(CurOp++);
|
||||||
|
if(MIMM.isImm()) {
|
||||||
|
unsigned Val = MIMM.getImm();
|
||||||
|
assert(Val < 16 && "Immediate operand value out of range");
|
||||||
|
RegNum |= Val;
|
||||||
|
}
|
||||||
|
}
|
||||||
EmitImmediate(MCOperand::CreateImm(RegNum), 1, FK_Data_1, CurByte, OS,
|
EmitImmediate(MCOperand::CreateImm(RegNum), 1, FK_Data_1, CurByte, OS,
|
||||||
Fixups);
|
Fixups);
|
||||||
} else {
|
} else {
|
||||||
|
@ -110,6 +110,8 @@ class A7 { bits<5> Prefix = 16; }
|
|||||||
class T8XD { bits<5> Prefix = 17; }
|
class T8XD { bits<5> Prefix = 17; }
|
||||||
class T8XS { bits<5> Prefix = 18; }
|
class T8XS { bits<5> Prefix = 18; }
|
||||||
class TAXD { bits<5> Prefix = 19; }
|
class TAXD { bits<5> Prefix = 19; }
|
||||||
|
class XOP8 { bits<5> Prefix = 20; }
|
||||||
|
class XOP9 { bits<5> Prefix = 21; }
|
||||||
class VEX { bit hasVEXPrefix = 1; }
|
class VEX { bit hasVEXPrefix = 1; }
|
||||||
class VEX_W { bit hasVEX_WPrefix = 1; }
|
class VEX_W { bit hasVEX_WPrefix = 1; }
|
||||||
class VEX_4V : VEX { bit hasVEX_4VPrefix = 1; }
|
class VEX_4V : VEX { bit hasVEX_4VPrefix = 1; }
|
||||||
@ -119,6 +121,7 @@ class VEX_L { bit hasVEX_L = 1; }
|
|||||||
class VEX_LIG { bit ignoresVEX_L = 1; }
|
class VEX_LIG { bit ignoresVEX_L = 1; }
|
||||||
class Has3DNow0F0FOpcode { bit has3DNow0F0FOpcode = 1; }
|
class Has3DNow0F0FOpcode { bit has3DNow0F0FOpcode = 1; }
|
||||||
class XOP_W { bit hasXOP_WPrefix = 1; }
|
class XOP_W { bit hasXOP_WPrefix = 1; }
|
||||||
|
class XOP { bit hasXOP_Prefix = 1; }
|
||||||
class X86Inst<bits<8> opcod, Format f, ImmType i, dag outs, dag ins,
|
class X86Inst<bits<8> opcod, Format f, ImmType i, dag outs, dag ins,
|
||||||
string AsmStr, Domain d = GenericDomain>
|
string AsmStr, Domain d = GenericDomain>
|
||||||
: Instruction {
|
: Instruction {
|
||||||
@ -159,6 +162,7 @@ class X86Inst<bits<8> opcod, Format f, ImmType i, dag outs, dag ins,
|
|||||||
bit ignoresVEX_L = 0; // Does this instruction ignore the L-bit
|
bit ignoresVEX_L = 0; // Does this instruction ignore the L-bit
|
||||||
bit has3DNow0F0FOpcode =0;// Wacky 3dNow! encoding?
|
bit has3DNow0F0FOpcode =0;// Wacky 3dNow! encoding?
|
||||||
bit hasXOP_WPrefix = 0; // Same bit as VEX_W, but used for swapping operands
|
bit hasXOP_WPrefix = 0; // Same bit as VEX_W, but used for swapping operands
|
||||||
|
bit hasXOP_Prefix = 0; // Does this inst require an XOP prefix?
|
||||||
|
|
||||||
// TSFlags layout should be kept in sync with X86InstrInfo.h.
|
// TSFlags layout should be kept in sync with X86InstrInfo.h.
|
||||||
let TSFlags{5-0} = FormBits;
|
let TSFlags{5-0} = FormBits;
|
||||||
@ -181,6 +185,7 @@ class X86Inst<bits<8> opcod, Format f, ImmType i, dag outs, dag ins,
|
|||||||
let TSFlags{39} = ignoresVEX_L;
|
let TSFlags{39} = ignoresVEX_L;
|
||||||
let TSFlags{40} = has3DNow0F0FOpcode;
|
let TSFlags{40} = has3DNow0F0FOpcode;
|
||||||
let TSFlags{41} = hasXOP_WPrefix;
|
let TSFlags{41} = hasXOP_WPrefix;
|
||||||
|
let TSFlags{42} = hasXOP_Prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
class PseudoI<dag oops, dag iops, list<dag> pattern>
|
class PseudoI<dag oops, dag iops, list<dag> pattern>
|
||||||
|
Loading…
Reference in New Issue
Block a user