mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-25 13:24:46 +00:00
Add support for the VIA PadLock instructions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@128826 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -75,6 +75,12 @@ static int modRMRequired(OpcodeType type,
|
||||
case THREEBYTE_3A:
|
||||
decision = &THREEBYTE3A_SYM;
|
||||
break;
|
||||
case THREEBYTE_A6:
|
||||
decision = &THREEBYTEA6_SYM;
|
||||
break;
|
||||
case THREEBYTE_A7:
|
||||
decision = &THREEBYTEA7_SYM;
|
||||
break;
|
||||
}
|
||||
|
||||
return decision->opcodeDecisions[insnContext].modRMDecisions[opcode].
|
||||
@@ -115,6 +121,12 @@ static InstrUID decode(OpcodeType type,
|
||||
case THREEBYTE_3A:
|
||||
dec = &THREEBYTE3A_SYM.opcodeDecisions[insnContext].modRMDecisions[opcode];
|
||||
break;
|
||||
case THREEBYTE_A6:
|
||||
dec = &THREEBYTEA6_SYM.opcodeDecisions[insnContext].modRMDecisions[opcode];
|
||||
break;
|
||||
case THREEBYTE_A7:
|
||||
dec = &THREEBYTEA7_SYM.opcodeDecisions[insnContext].modRMDecisions[opcode];
|
||||
break;
|
||||
}
|
||||
|
||||
switch (dec->modrm_type) {
|
||||
@@ -580,6 +592,24 @@ static int readOpcode(struct InternalInstruction* insn) {
|
||||
return -1;
|
||||
|
||||
insn->opcodeType = THREEBYTE_3A;
|
||||
} else if (current == 0xa6) {
|
||||
dbgprintf(insn, "Found a three-byte escape prefix (0x%hhx)", current);
|
||||
|
||||
insn->threeByteEscape = current;
|
||||
|
||||
if (consumeByte(insn, ¤t))
|
||||
return -1;
|
||||
|
||||
insn->opcodeType = THREEBYTE_A6;
|
||||
} else if (current == 0xa7) {
|
||||
dbgprintf(insn, "Found a three-byte escape prefix (0x%hhx)", current);
|
||||
|
||||
insn->threeByteEscape = current;
|
||||
|
||||
if (consumeByte(insn, ¤t))
|
||||
return -1;
|
||||
|
||||
insn->opcodeType = THREEBYTE_A7;
|
||||
} else {
|
||||
dbgprintf(insn, "Didn't find a three-byte escape prefix");
|
||||
|
||||
|
@@ -30,6 +30,8 @@
|
||||
#define TWOBYTE_SYM x86DisassemblerTwoByteOpcodes
|
||||
#define THREEBYTE38_SYM x86DisassemblerThreeByte38Opcodes
|
||||
#define THREEBYTE3A_SYM x86DisassemblerThreeByte3AOpcodes
|
||||
#define THREEBYTEA6_SYM x86DisassemblerThreeByteA6Opcodes
|
||||
#define THREEBYTEA7_SYM x86DisassemblerThreeByteA7Opcodes
|
||||
|
||||
#define INSTRUCTIONS_STR "x86DisassemblerInstrSpecifiers"
|
||||
#define CONTEXTS_STR "x86DisassemblerContexts"
|
||||
@@ -37,6 +39,8 @@
|
||||
#define TWOBYTE_STR "x86DisassemblerTwoByteOpcodes"
|
||||
#define THREEBYTE38_STR "x86DisassemblerThreeByte38Opcodes"
|
||||
#define THREEBYTE3A_STR "x86DisassemblerThreeByte3AOpcodes"
|
||||
#define THREEBYTEA6_STR "x86DisassemblerThreeByteA6Opcodes"
|
||||
#define THREEBYTEA7_STR "x86DisassemblerThreeByteA7Opcodes"
|
||||
|
||||
/*
|
||||
* Attributes of an instruction that must be known before the opcode can be
|
||||
@@ -119,7 +123,9 @@ typedef enum {
|
||||
ONEBYTE = 0,
|
||||
TWOBYTE = 1,
|
||||
THREEBYTE_38 = 2,
|
||||
THREEBYTE_3A = 3
|
||||
THREEBYTE_3A = 3,
|
||||
THREEBYTE_A6 = 4,
|
||||
THREEBYTE_A7 = 5
|
||||
} OpcodeType;
|
||||
|
||||
/*
|
||||
|
@@ -652,6 +652,8 @@ void Emitter<CodeEmitter>::emitInstruction(MachineInstr &MI,
|
||||
case X86II::TB: // Two-byte opcode prefix
|
||||
case X86II::T8: // 0F 38
|
||||
case X86II::TA: // 0F 3A
|
||||
case X86II::A6: // 0F A6
|
||||
case X86II::A7: // 0F A7
|
||||
Need0FPrefix = true;
|
||||
break;
|
||||
case X86II::TF: // F2 0F 38
|
||||
@@ -695,6 +697,12 @@ void Emitter<CodeEmitter>::emitInstruction(MachineInstr &MI,
|
||||
case X86II::TA: // 0F 3A
|
||||
MCE.emitByte(0x3A);
|
||||
break;
|
||||
case X86II::A6: // 0F A6
|
||||
MCE.emitByte(0xA6);
|
||||
break;
|
||||
case X86II::A7: // 0F A7
|
||||
MCE.emitByte(0xA7);
|
||||
break;
|
||||
}
|
||||
|
||||
// If this is a two-address instruction, skip one of the register operands.
|
||||
|
@@ -105,7 +105,9 @@ class XD { bits<5> Prefix = 11; }
|
||||
class XS { bits<5> Prefix = 12; }
|
||||
class T8 { bits<5> Prefix = 13; }
|
||||
class TA { bits<5> Prefix = 14; }
|
||||
class TF { bits<5> Prefix = 15; }
|
||||
class A6 { bits<5> Prefix = 15; }
|
||||
class A7 { bits<5> Prefix = 16; }
|
||||
class TF { bits<5> Prefix = 17; }
|
||||
class VEX { bit hasVEXPrefix = 1; }
|
||||
class VEX_W { bit hasVEX_WPrefix = 1; }
|
||||
class VEX_4V : VEX { bit hasVEX_4VPrefix = 1; }
|
||||
|
@@ -368,11 +368,12 @@ namespace X86II {
|
||||
// floating point operations performed in the SSE registers.
|
||||
XD = 11 << Op0Shift, XS = 12 << Op0Shift,
|
||||
|
||||
// T8, TA - Prefix after the 0x0F prefix.
|
||||
// T8, TA, A6, A7 - Prefix after the 0x0F prefix.
|
||||
T8 = 13 << Op0Shift, TA = 14 << Op0Shift,
|
||||
A6 = 15 << Op0Shift, A7 = 16 << Op0Shift,
|
||||
|
||||
// TF - Prefix before and after 0x0F
|
||||
TF = 15 << Op0Shift,
|
||||
TF = 17 << Op0Shift,
|
||||
|
||||
//===------------------------------------------------------------------===//
|
||||
// REX_W - REX prefixes are instruction prefixes used in 64-bit mode.
|
||||
|
@@ -398,3 +398,23 @@ let Defs = [RDX, RAX], Uses = [RCX] in
|
||||
|
||||
let Uses = [RDX, RAX, RCX] in
|
||||
def XSETBV : I<0x01, MRM_D1, (outs), (ins), "xsetbv", []>, TB;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// VIA PadLock crypto instructions
|
||||
let Defs = [RAX, RDI], Uses = [RDX, RDI] in
|
||||
def XSTORE : I<0xc0, RawFrm, (outs), (ins), "xstore", []>, A7;
|
||||
|
||||
let Defs = [RSI, RDI], Uses = [RBX, RDX, RSI, RDI] in {
|
||||
def XCRYPTECB : I<0xc8, RawFrm, (outs), (ins), "xcryptecb", []>, A7;
|
||||
def XCRYPTCBC : I<0xd0, RawFrm, (outs), (ins), "xcryptcbc", []>, A7;
|
||||
def XCRYPTCTR : I<0xd8, RawFrm, (outs), (ins), "xcryptctr", []>, A7;
|
||||
def XCRYPTCFB : I<0xe0, RawFrm, (outs), (ins), "xcryptcfb", []>, A7;
|
||||
def XCRYPTOFB : I<0xe8, RawFrm, (outs), (ins), "xcryptofb", []>, A7;
|
||||
}
|
||||
|
||||
let Defs = [RAX, RSI, RDI], Uses = [RAX, RSI, RDI] in {
|
||||
def XSHA1 : I<0xc8, RawFrm, (outs), (ins), "xsha1", []>, A6;
|
||||
def XSHA256 : I<0xd0, RawFrm, (outs), (ins), "xsha256", []>, A6;
|
||||
}
|
||||
let Defs = [RAX, RDX, RSI], Uses = [RAX, RSI] in
|
||||
def MONTMUL : I<0xc0, RawFrm, (outs), (ins), "montmul", []>, A6;
|
||||
|
@@ -470,6 +470,8 @@ void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
|
||||
case X86II::XD: // F2 0F
|
||||
VEX_PP = 0x3;
|
||||
break;
|
||||
case X86II::A6: // Bypass: Not used by VEX
|
||||
case X86II::A7: // Bypass: Not used by VEX
|
||||
case X86II::TB: // Bypass: Not used by VEX
|
||||
case 0:
|
||||
break; // No prefix!
|
||||
@@ -742,6 +744,8 @@ void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
|
||||
case X86II::TB: // Two-byte opcode prefix
|
||||
case X86II::T8: // 0F 38
|
||||
case X86II::TA: // 0F 3A
|
||||
case X86II::A6: // 0F A6
|
||||
case X86II::A7: // 0F A7
|
||||
Need0FPrefix = true;
|
||||
break;
|
||||
case X86II::TF: // F2 0F 38
|
||||
@@ -786,6 +790,12 @@ void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
|
||||
case X86II::TA: // 0F 3A
|
||||
EmitByte(0x3A, CurByte, OS);
|
||||
break;
|
||||
case X86II::A6: // 0F A6
|
||||
EmitByte(0xA6, CurByte, OS);
|
||||
break;
|
||||
case X86II::A7: // 0F A7
|
||||
EmitByte(0xA7, CurByte, OS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user