Add support for four bytes instructions

This commit is contained in:
jca 2024-02-27 00:32:38 +01:00 committed by Peter Johnson
parent 121ab150b3
commit e2c133fe29
4 changed files with 29 additions and 21 deletions

View file

@ -321,7 +321,7 @@ class GroupForm(object):
cpus_str = "|".join("CPU_%s" % x for x in sorted(self.cpu))
if len(self.modifiers) > 3:
if len(self.modifiers) > 4:
raise ValueError("too many modifiers: %s" % (self.modifiers,))
cpus_str = []
@ -337,9 +337,9 @@ class GroupForm(object):
mods = ["MOD_%s" % x for x in self.modifiers]
# Ensure mods initializer string is 3 long
mods.extend(["0", "0", "0"])
mod_str = "{" + ', '.join(mods[0:3]) + "}"
# Ensure mods initializer string is 4 long
mods.extend(["0", "0", "0", "0"])
mod_str = "{" + ', '.join(mods[0:4]) + "}"
gas_flags = []
if self.gas_only:
@ -479,12 +479,12 @@ class Insn(object):
# Ensure cpus initializer string is 3 long
cpus_str.extend(["0", "0", "0"])
if len(self.modifiers) > 3:
if len(self.modifiers) > 4:
raise ValueError("too many modifiers")
mods_str = ["0x%02X" % x for x in self.modifiers]
# Ensure modifiers is at least 3 long
mods_str.extend(["0", "0", "0"])
# Ensure modifiers is at least 4 long
mods_str.extend(["0", "0", "0", "0"])
return ",\t".join(["%s_insn" % self.groupname,
"%d" % len(groups[self.groupname]),

View file

@ -235,7 +235,7 @@ typedef struct x86_common {
} x86_common;
typedef struct x86_opcode {
unsigned char opcode[3]; /* opcode */
unsigned char opcode[4]; /* opcode */
unsigned char len;
} x86_opcode;

View file

@ -426,10 +426,11 @@ x86_common_print(const x86_common *common, FILE *f, int indent_level)
static void
x86_opcode_print(const x86_opcode *opcode, FILE *f, int indent_level)
{
fprintf(f, "%*sOpcode: %02x %02x %02x OpLen=%u\n", indent_level, "",
fprintf(f, "%*sOpcode: %02x %02x %02x %02x OpLen=%u\n", indent_level, "",
(unsigned int)opcode->opcode[0],
(unsigned int)opcode->opcode[1],
(unsigned int)opcode->opcode[2],
(unsigned int)opcode->opcode[3],
(unsigned int)opcode->len);
}

View file

@ -42,13 +42,14 @@ static const char *cpu_find_reverse(unsigned int cpu0, unsigned int cpu1,
#define MOD_Op0Add 2 /* Parameter adds to opcode byte 0 */
#define MOD_Op1Add 3 /* Parameter adds to opcode byte 1 */
#define MOD_Op2Add 4 /* Parameter adds to opcode byte 2 */
#define MOD_SpAdd 5 /* Parameter adds to "spare" value */
#define MOD_OpSizeR 6 /* Parameter replaces opersize */
#define MOD_Imm8 7 /* Parameter is included as immediate byte */
#define MOD_AdSizeR 8 /* Parameter replaces addrsize (jmp only) */
#define MOD_DOpS64R 9 /* Parameter replaces default 64-bit opersize */
#define MOD_Op1AddSp 10 /* Parameter is added as "spare" to opcode byte 2 */
#define MOD_SetVEX 11 /* Parameter replaces internal VEX prefix value */
#define MOD_Op3Add 5 /* Parameter adds to opcode byte 3 */
#define MOD_SpAdd 6 /* Parameter adds to "spare" value */
#define MOD_OpSizeR 7 /* Parameter replaces opersize */
#define MOD_Imm8 8 /* Parameter is included as immediate byte */
#define MOD_AdSizeR 9 /* Parameter replaces addrsize (jmp only) */
#define MOD_DOpS64R 10 /* Parameter replaces default 64-bit opersize */
#define MOD_Op1AddSp 11 /* Parameter is added as "spare" to opcode byte 2 */
#define MOD_SetVEX 12 /* Parameter replaces internal VEX prefix value */
/* GAS suffix flags for instructions */
enum x86_gas_suffix_flags {
@ -251,9 +252,9 @@ typedef struct x86_insn_info {
* its parameter in LSB->MSB order from the arch-specific data[1] from the
* lexer data, and the LSB of the arch-specific data[1] is reserved for the
* count of insn_info structures in the instruction grouping, there can
* only be a maximum of 3 modifiers.
* only be a maximum of 4 modifiers.
*/
unsigned char modifiers[3];
unsigned char modifiers[4];
/* Operand Size */
unsigned char opersize;
@ -282,10 +283,10 @@ typedef struct x86_insn_info {
/* The length of the basic opcode */
unsigned char opcode_len;
/* The basic 1-3 byte opcode (not including the special instruction
/* The basic 1-4 byte opcode (not including the special instruction
* prefix).
*/
unsigned char opcode[3];
unsigned char opcode[4];
/* The 3-bit "spare" value (extended opcode) for the R/M byte field */
unsigned char spare;
@ -309,7 +310,7 @@ typedef struct x86_id_insn {
wordptr cpu_enabled;
/* Modifier data */
unsigned char mod_data[3];
unsigned char mod_data[4];
/* Number of elements in the instruction parse group */
unsigned int num_info:8;
@ -477,6 +478,9 @@ x86_finalize_jmpfar(yasm_bytecode *bc, yasm_bytecode *prev_bc,
case MOD_Op2Add:
jmpfar->opcode.opcode[2] += mod_data[i];
break;
case MOD_Op3Add:
jmpfar->opcode.opcode[3] += mod_data[i];
break;
case MOD_Op1AddSp:
jmpfar->opcode.opcode[1] += mod_data[i]<<3;
break;
@ -1197,6 +1201,9 @@ x86_id_insn_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
case MOD_Op2Add:
insn->opcode.opcode[2] += mod_data[i];
break;
case MOD_Op3Add:
insn->opcode.opcode[3] += mod_data[i];
break;
case MOD_SpAdd:
spare += mod_data[i];
break;