Newer
Older
filter = new DumbFilter();
opcodeToSet = Opcode;
break;
case X86Local::A7:
opcodeType = THREEBYTE_A7;
if (needsModRMForDecode(Form))
filter = new ModFilter(isRegFormat(Form));
else
filter = new DumbFilter();
opcodeToSet = Opcode;
break;
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
case X86Local::XOP8:
opcodeType = XOP8_MAP;
if (needsModRMForDecode(Form))
filter = new ModFilter(isRegFormat(Form));
else
filter = new DumbFilter();
opcodeToSet = Opcode;
break;
case X86Local::XOP9:
opcodeType = XOP9_MAP;
switch (Opcode) {
default:
if (needsModRMForDecode(Form))
filter = new ModFilter(isRegFormat(Form));
else
filter = new DumbFilter();
break;
#define EXTENSION_TABLE(n) case 0x##n:
XOP9_MAP_EXTENSION_TABLES
#undef EXTENSION_TABLE
switch (Form) {
default:
llvm_unreachable("Unhandled XOP9 extended opcode");
case X86Local::MRM0r:
case X86Local::MRM1r:
case X86Local::MRM2r:
case X86Local::MRM3r:
case X86Local::MRM4r:
case X86Local::MRM5r:
case X86Local::MRM6r:
case X86Local::MRM7r:
filter = new ExtendedFilter(true, Form - X86Local::MRM0r);
break;
case X86Local::MRM0m:
case X86Local::MRM1m:
case X86Local::MRM2m:
case X86Local::MRM3m:
case X86Local::MRM4m:
case X86Local::MRM5m:
case X86Local::MRM6m:
case X86Local::MRM7m:
filter = new ExtendedFilter(false, Form - X86Local::MRM0m);
break;
MRM_MAPPING
} // switch (Form)
break;
} // switch (Opcode)
opcodeToSet = Opcode;
break;
case X86Local::XOPA:
opcodeType = XOPA_MAP;
if (needsModRMForDecode(Form))
filter = new ModFilter(isRegFormat(Form));
else
filter = new DumbFilter();
opcodeToSet = Opcode;
break;
case X86Local::D8:
case X86Local::D9:
case X86Local::DA:
case X86Local::DB:
case X86Local::DC:
case X86Local::DD:
case X86Local::DE:
case X86Local::DF:
assert(Opcode >= 0xc0 && "Unexpected opcode for an escape opcode");
opcodeType = ONEBYTE;
if (Form == X86Local::AddRegFrm) {
Spec->modifierType = MODIFIER_MODRM;
Spec->modifierBase = Opcode;
filter = new AddRegEscapeFilter(Opcode);
} else {
filter = new ExactFilter(Opcode);
}
opcodeToSet = 0xd8 + (Prefix - X86Local::D8);
break;
case X86Local::REP:
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
opcodeType = ONEBYTE;
switch (Opcode) {
#define EXTENSION_TABLE(n) case 0x##n:
ONE_BYTE_EXTENSION_TABLES
#undef EXTENSION_TABLE
switch (Form) {
default:
llvm_unreachable("Fell through the cracks of a single-byte "
"extended opcode");
case X86Local::MRM0r:
case X86Local::MRM1r:
case X86Local::MRM2r:
case X86Local::MRM3r:
case X86Local::MRM4r:
case X86Local::MRM5r:
case X86Local::MRM6r:
case X86Local::MRM7r:
filter = new ExtendedFilter(true, Form - X86Local::MRM0r);
break;
case X86Local::MRM0m:
case X86Local::MRM1m:
case X86Local::MRM2m:
case X86Local::MRM3m:
case X86Local::MRM4m:
case X86Local::MRM5m:
case X86Local::MRM6m:
case X86Local::MRM7m:
filter = new ExtendedFilter(false, Form - X86Local::MRM0m);
break;
} // switch (Form)
break;
case 0xd8:
case 0xd9:
case 0xda:
case 0xdb:
case 0xdc:
case 0xdd:
case 0xde:
case 0xdf:
switch (Form) {
default:
llvm_unreachable("Unhandled escape opcode form");
case X86Local::MRM0m:
case X86Local::MRM1m:
case X86Local::MRM2m:
case X86Local::MRM3m:
case X86Local::MRM4m:
case X86Local::MRM5m:
case X86Local::MRM6m:
case X86Local::MRM7m:
filter = new ExtendedFilter(false, Form - X86Local::MRM0m);
break;
} // switch (Form)
break;
default:
if (needsModRMForDecode(Form))
filter = new ModFilter(isRegFormat(Form));
else
filter = new DumbFilter();
break;
} // switch (Opcode)
opcodeToSet = Opcode;
} // switch (Prefix)
assert(opcodeType != (OpcodeType)-1 &&
"Opcode type not set");
assert(filter && "Filter not set");
if (Form == X86Local::AddRegFrm) {
if(Spec->modifierType != MODIFIER_MODRM) {
assert(opcodeToSet < 0xf9 &&
"Not enough room for all ADDREG_FRM operands");
uint8_t currentOpcode;
for (currentOpcode = opcodeToSet;
currentOpcode < opcodeToSet + 8;
++currentOpcode)
tables.setTableFields(opcodeType,
insnContext(),
currentOpcode,
*filter,
UID, Is32Bit, IgnoresVEX_L);
Spec->modifierType = MODIFIER_OPCODE;
Spec->modifierBase = opcodeToSet;
} else {
// modifierBase was set where MODIFIER_MODRM was set
tables.setTableFields(opcodeType,
insnContext(),
opcodeToSet,
*filter,
UID, Is32Bit, IgnoresVEX_L);
}
} else {
tables.setTableFields(opcodeType,
insnContext(),
opcodeToSet,
*filter,
UID, Is32Bit, IgnoresVEX_L);
Spec->modifierType = MODIFIER_NONE;
Spec->modifierBase = opcodeToSet;
}
delete filter;
}
#define TYPE(str, type) if (s == str) return type;
OperandType RecognizableInstr::typeFromString(const std::string &s,
bool isSSE,
bool hasREX_WPrefix,
bool hasOpSizePrefix) {
if (isSSE) {
// For SSE instructions, we ignore the OpSize prefix and force operand
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
// sizes.
TYPE("GR16", TYPE_R16)
TYPE("GR32", TYPE_R32)
TYPE("GR64", TYPE_R64)
}
if(hasREX_WPrefix) {
// For instructions with a REX_W prefix, a declared 32-bit register encoding
// is special.
TYPE("GR32", TYPE_R32)
}
if(!hasOpSizePrefix) {
// For instructions without an OpSize prefix, a declared 16-bit register or
// immediate encoding is special.
TYPE("GR16", TYPE_R16)
TYPE("i16imm", TYPE_IMM16)
}
TYPE("i16mem", TYPE_Mv)
TYPE("i16imm", TYPE_IMMv)
TYPE("i16i8imm", TYPE_IMMv)
TYPE("GR16", TYPE_Rv)
TYPE("i32mem", TYPE_Mv)
TYPE("i32imm", TYPE_IMMv)
TYPE("i32i8imm", TYPE_IMM32)
Kevin Enderby
committed
TYPE("u32u8imm", TYPE_IMM32)
TYPE("GR32", TYPE_Rv)
TYPE("GR32orGR64", TYPE_R32)
TYPE("i64mem", TYPE_Mv)
TYPE("i64i32imm", TYPE_IMM64)
TYPE("i64i8imm", TYPE_IMM64)
TYPE("GR64", TYPE_R64)
TYPE("i8mem", TYPE_M8)
TYPE("i8imm", TYPE_IMM8)
TYPE("GR8", TYPE_R8)
TYPE("VR128", TYPE_XMM128)
TYPE("VR128X", TYPE_XMM128)
TYPE("f128mem", TYPE_M128)
TYPE("f256mem", TYPE_M256)
TYPE("f512mem", TYPE_M512)
TYPE("FR64", TYPE_XMM64)
TYPE("FR64X", TYPE_XMM64)
TYPE("f64mem", TYPE_M64FP)
TYPE("sdmem", TYPE_M64FP)
TYPE("FR32", TYPE_XMM32)
TYPE("FR32X", TYPE_XMM32)
TYPE("f32mem", TYPE_M32FP)
TYPE("ssmem", TYPE_M32FP)
TYPE("RST", TYPE_ST)
TYPE("i128mem", TYPE_M128)
TYPE("i256mem", TYPE_M256)
TYPE("i512mem", TYPE_M512)
TYPE("i64i32imm_pcrel", TYPE_REL64)
TYPE("i16imm_pcrel", TYPE_REL16)
TYPE("i32imm_pcrel", TYPE_REL32)
TYPE("SSECC", TYPE_IMM3)
Craig Topper
committed
TYPE("AVXCC", TYPE_IMM5)
TYPE("brtarget", TYPE_RELv)
Owen Anderson
committed
TYPE("uncondbrtarget", TYPE_RELv)
TYPE("brtarget8", TYPE_REL8)
TYPE("f80mem", TYPE_M80FP)
TYPE("lea32mem", TYPE_LEA)
TYPE("lea64_32mem", TYPE_LEA)
TYPE("lea64mem", TYPE_LEA)
TYPE("VR64", TYPE_MM64)
TYPE("i64imm", TYPE_IMMv)
TYPE("opaque32mem", TYPE_M1616)
TYPE("opaque48mem", TYPE_M1632)
TYPE("opaque80mem", TYPE_M1664)
TYPE("opaque512mem", TYPE_M512)
TYPE("SEGMENT_REG", TYPE_SEGMENTREG)
TYPE("DEBUG_REG", TYPE_DEBUGREG)
TYPE("CONTROL_REG", TYPE_CONTROLREG)
TYPE("offset8", TYPE_MOFFS8)
TYPE("offset16", TYPE_MOFFS16)
TYPE("offset32", TYPE_MOFFS32)
TYPE("offset64", TYPE_MOFFS64)
TYPE("VR256", TYPE_XMM256)
TYPE("VR256X", TYPE_XMM256)
TYPE("VR512", TYPE_XMM512)
TYPE("VK1", TYPE_VK1)
TYPE("VK1WM", TYPE_VK1)
TYPE("VK8", TYPE_VK8)
TYPE("VK8WM", TYPE_VK8)
TYPE("VK16", TYPE_VK16)
TYPE("VK16WM", TYPE_VK16)
Craig Topper
committed
TYPE("GR16_NOAX", TYPE_Rv)
TYPE("GR32_NOAX", TYPE_Rv)
TYPE("GR64_NOAX", TYPE_R64)
TYPE("vx32mem", TYPE_M32)
TYPE("vy32mem", TYPE_M32)
TYPE("vz32mem", TYPE_M32)
TYPE("vx64mem", TYPE_M64)
TYPE("vy64mem", TYPE_M64)
TYPE("vy64xmem", TYPE_M64)
TYPE("vz64mem", TYPE_M64)
errs() << "Unhandled type string " << s << "\n";
llvm_unreachable("Unhandled type string");
}
#undef TYPE
#define ENCODING(str, encoding) if (s == str) return encoding;
OperandEncoding RecognizableInstr::immediateEncodingFromString
(const std::string &s,
bool hasOpSizePrefix) {
if(!hasOpSizePrefix) {
// For instructions without an OpSize prefix, a declared 16-bit register or
// immediate encoding is special.
ENCODING("i16imm", ENCODING_IW)
}
ENCODING("i32i8imm", ENCODING_IB)
Kevin Enderby
committed
ENCODING("u32u8imm", ENCODING_IB)
ENCODING("SSECC", ENCODING_IB)
Craig Topper
committed
ENCODING("AVXCC", ENCODING_IB)
ENCODING("i16imm", ENCODING_Iv)
ENCODING("i16i8imm", ENCODING_IB)
ENCODING("i32imm", ENCODING_Iv)
ENCODING("i64i32imm", ENCODING_ID)
ENCODING("i64i8imm", ENCODING_IB)
ENCODING("i8imm", ENCODING_IB)
// This is not a typo. Instructions like BLENDVPD put
// register IDs in 8-bit immediates nowadays.
ENCODING("FR32", ENCODING_IB)
ENCODING("FR64", ENCODING_IB)
ENCODING("VR128", ENCODING_IB)
ENCODING("VR256", ENCODING_IB)
ENCODING("FR32X", ENCODING_IB)
ENCODING("FR64X", ENCODING_IB)
ENCODING("VR128X", ENCODING_IB)
ENCODING("VR256X", ENCODING_IB)
ENCODING("VR512", ENCODING_IB)
errs() << "Unhandled immediate encoding " << s << "\n";
llvm_unreachable("Unhandled immediate encoding");
}
OperandEncoding RecognizableInstr::rmRegisterEncodingFromString
(const std::string &s,
bool hasOpSizePrefix) {
ENCODING("GR16", ENCODING_RM)
ENCODING("GR32", ENCODING_RM)
ENCODING("GR32orGR64", ENCODING_RM)
ENCODING("GR64", ENCODING_RM)
ENCODING("GR8", ENCODING_RM)
ENCODING("VR128", ENCODING_RM)
ENCODING("VR128X", ENCODING_RM)
ENCODING("FR64", ENCODING_RM)
ENCODING("FR32", ENCODING_RM)
ENCODING("FR64X", ENCODING_RM)
ENCODING("FR32X", ENCODING_RM)
ENCODING("VR64", ENCODING_RM)
ENCODING("VR256", ENCODING_RM)
ENCODING("VR256X", ENCODING_RM)
ENCODING("VR512", ENCODING_RM)
ENCODING("VK1", ENCODING_RM)
ENCODING("VK8", ENCODING_RM)
ENCODING("VK16", ENCODING_RM)
errs() << "Unhandled R/M register encoding " << s << "\n";
llvm_unreachable("Unhandled R/M register encoding");
}
OperandEncoding RecognizableInstr::roRegisterEncodingFromString
(const std::string &s,
bool hasOpSizePrefix) {
ENCODING("GR16", ENCODING_REG)
ENCODING("GR32", ENCODING_REG)
ENCODING("GR32orGR64", ENCODING_REG)
ENCODING("GR64", ENCODING_REG)
ENCODING("GR8", ENCODING_REG)
ENCODING("VR128", ENCODING_REG)
ENCODING("FR64", ENCODING_REG)
ENCODING("FR32", ENCODING_REG)
ENCODING("VR64", ENCODING_REG)
ENCODING("SEGMENT_REG", ENCODING_REG)
ENCODING("DEBUG_REG", ENCODING_REG)
ENCODING("CONTROL_REG", ENCODING_REG)
ENCODING("VR256", ENCODING_REG)
ENCODING("VR256X", ENCODING_REG)
ENCODING("VR128X", ENCODING_REG)
ENCODING("FR64X", ENCODING_REG)
ENCODING("FR32X", ENCODING_REG)
ENCODING("VR512", ENCODING_REG)
ENCODING("VK1", ENCODING_REG)
ENCODING("VK8", ENCODING_REG)
ENCODING("VK16", ENCODING_REG)
ENCODING("VK1WM", ENCODING_REG)
ENCODING("VK8WM", ENCODING_REG)
ENCODING("VK16WM", ENCODING_REG)
errs() << "Unhandled reg/opcode register encoding " << s << "\n";
llvm_unreachable("Unhandled reg/opcode register encoding");
}
OperandEncoding RecognizableInstr::vvvvRegisterEncodingFromString
(const std::string &s,
bool hasOpSizePrefix) {
ENCODING("GR32", ENCODING_VVVV)
ENCODING("GR64", ENCODING_VVVV)
ENCODING("FR32", ENCODING_VVVV)
ENCODING("FR64", ENCODING_VVVV)
ENCODING("VR128", ENCODING_VVVV)
ENCODING("VR256", ENCODING_VVVV)
ENCODING("FR32X", ENCODING_VVVV)
ENCODING("FR64X", ENCODING_VVVV)
ENCODING("VR128X", ENCODING_VVVV)
ENCODING("VR256X", ENCODING_VVVV)
ENCODING("VR512", ENCODING_VVVV)
ENCODING("VK1", ENCODING_VVVV)
ENCODING("VK8", ENCODING_VVVV)
ENCODING("VK16", ENCODING_VVVV)
errs() << "Unhandled VEX.vvvv register encoding " << s << "\n";
llvm_unreachable("Unhandled VEX.vvvv register encoding");
}
OperandEncoding RecognizableInstr::writemaskRegisterEncodingFromString
(const std::string &s,
bool hasOpSizePrefix) {
ENCODING("VK1WM", ENCODING_WRITEMASK)
ENCODING("VK8WM", ENCODING_WRITEMASK)
ENCODING("VK16WM", ENCODING_WRITEMASK)
errs() << "Unhandled mask register encoding " << s << "\n";
llvm_unreachable("Unhandled mask register encoding");
}
OperandEncoding RecognizableInstr::memoryEncodingFromString
(const std::string &s,
bool hasOpSizePrefix) {
ENCODING("i16mem", ENCODING_RM)
ENCODING("i32mem", ENCODING_RM)
ENCODING("i64mem", ENCODING_RM)
ENCODING("i8mem", ENCODING_RM)
ENCODING("ssmem", ENCODING_RM)
ENCODING("sdmem", ENCODING_RM)
ENCODING("f128mem", ENCODING_RM)
ENCODING("f256mem", ENCODING_RM)
ENCODING("f512mem", ENCODING_RM)
ENCODING("f64mem", ENCODING_RM)
ENCODING("f32mem", ENCODING_RM)
ENCODING("i128mem", ENCODING_RM)
ENCODING("i256mem", ENCODING_RM)
ENCODING("i512mem", ENCODING_RM)
ENCODING("f80mem", ENCODING_RM)
ENCODING("lea32mem", ENCODING_RM)
ENCODING("lea64_32mem", ENCODING_RM)
ENCODING("lea64mem", ENCODING_RM)
ENCODING("opaque32mem", ENCODING_RM)
ENCODING("opaque48mem", ENCODING_RM)
ENCODING("opaque80mem", ENCODING_RM)
ENCODING("opaque512mem", ENCODING_RM)
ENCODING("vx32mem", ENCODING_RM)
ENCODING("vy32mem", ENCODING_RM)
ENCODING("vz32mem", ENCODING_RM)
ENCODING("vx64mem", ENCODING_RM)
ENCODING("vy64mem", ENCODING_RM)
ENCODING("vy64xmem", ENCODING_RM)
ENCODING("vz64mem", ENCODING_RM)
errs() << "Unhandled memory encoding " << s << "\n";
llvm_unreachable("Unhandled memory encoding");
}
OperandEncoding RecognizableInstr::relocationEncodingFromString
(const std::string &s,
bool hasOpSizePrefix) {
if(!hasOpSizePrefix) {
// For instructions without an OpSize prefix, a declared 16-bit register or
// immediate encoding is special.
ENCODING("i16imm", ENCODING_IW)
}
ENCODING("i16imm", ENCODING_Iv)
ENCODING("i16i8imm", ENCODING_IB)
ENCODING("i32imm", ENCODING_Iv)
ENCODING("i32i8imm", ENCODING_IB)
ENCODING("i64i32imm", ENCODING_ID)
ENCODING("i64i8imm", ENCODING_IB)
ENCODING("i8imm", ENCODING_IB)
ENCODING("i64i32imm_pcrel", ENCODING_ID)
ENCODING("i16imm_pcrel", ENCODING_IW)
ENCODING("i32imm_pcrel", ENCODING_ID)
ENCODING("brtarget", ENCODING_Iv)
ENCODING("brtarget8", ENCODING_IB)
ENCODING("i64imm", ENCODING_IO)
ENCODING("offset8", ENCODING_Ia)
ENCODING("offset16", ENCODING_Ia)
ENCODING("offset32", ENCODING_Ia)
ENCODING("offset64", ENCODING_Ia)
errs() << "Unhandled relocation encoding " << s << "\n";
llvm_unreachable("Unhandled relocation encoding");
}
OperandEncoding RecognizableInstr::opcodeModifierEncodingFromString
(const std::string &s,
bool hasOpSizePrefix) {
ENCODING("RST", ENCODING_I)
ENCODING("GR32", ENCODING_Rv)
ENCODING("GR64", ENCODING_RO)
ENCODING("GR16", ENCODING_Rv)
ENCODING("GR8", ENCODING_RB)
Craig Topper
committed
ENCODING("GR16_NOAX", ENCODING_Rv)
ENCODING("GR32_NOAX", ENCODING_Rv)
ENCODING("GR64_NOAX", ENCODING_RO)
errs() << "Unhandled opcode modifier encoding " << s << "\n";
llvm_unreachable("Unhandled opcode modifier encoding");
}