Add support for three-byte opcodes, starting with the 0x0f 0x38 prefix. Use P_EXT2 as the new constant, and shift all other constants so that P_EXT and P_EXT2 have neighbouring values.
Signed-off-by: Aurelien Jarno <aurel...@aurel32.net> --- tcg/i386/tcg-target.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c index 753b3a1..e247829 100644 --- a/tcg/i386/tcg-target.c +++ b/tcg/i386/tcg-target.c @@ -240,13 +240,14 @@ static inline int tcg_target_const_match(tcg_target_long val, #endif #define P_EXT 0x100 /* 0x0f opcode prefix */ -#define P_DATA16 0x200 /* 0x66 opcode prefix */ +#define P_EXT2 0x200 /* 0x0f 0x38 opcode prefix */ +#define P_DATA16 0x400 /* 0x66 opcode prefix */ #if TCG_TARGET_REG_BITS == 64 -# define P_ADDR32 0x400 /* 0x67 opcode prefix */ -# define P_REXW 0x800 /* Set REX.W = 1 */ -# define P_REXB_R 0x1000 /* REG field as byte register */ -# define P_REXB_RM 0x2000 /* R/M field as byte register */ -# define P_GS 0x4000 /* gs segment override */ +# define P_ADDR32 0x800 /* 0x67 opcode prefix */ +# define P_REXW 0x1000 /* Set REX.W = 1 */ +# define P_REXB_R 0x2000 /* REG field as byte register */ +# define P_REXB_RM 0x4000 /* R/M field as byte register */ +# define P_GS 0x8000 /* gs segment override */ #else # define P_ADDR32 0 # define P_REXW 0 @@ -401,6 +402,11 @@ static void tcg_out_opc(TCGContext *s, int opc, int r, int rm, int x) if (opc & P_EXT) { tcg_out8(s, 0x0f); } + + if (opc & P_EXT2) { + tcg_out8(s, 0x0f); + tcg_out8(s, 0x38); + } tcg_out8(s, opc); } #else @@ -412,6 +418,10 @@ static void tcg_out_opc(TCGContext *s, int opc) if (opc & P_EXT) { tcg_out8(s, 0x0f); } + if (opc & P_EXT2) { + tcg_out8(s, 0x0f); + tcg_out8(s, 0x38); + } tcg_out8(s, opc); } /* Discard the register arguments to tcg_out_opc early, so as not to penalize -- 1.7.10.4