# HG changeset patch # User Michael Pavone # Date 1432437916 25200 # Node ID cb1c005880e79b260657903f0a5ae6b8773bab4d # Parent 59a98179d3ba2dbb6d9663d11a54bc8652c152b1 Generate an error in x86-32 builds for most cases when a REX prefix would be generated diff -r 59a98179d3ba -r cb1c005880e7 gen_x86.c --- a/gen_x86.c Sat May 23 20:24:27 2015 -0700 +++ b/gen_x86.c Sat May 23 20:25:16 2015 -0700 @@ -130,6 +130,44 @@ X86_R15 } x86_regs_enc; +char * x86_reg_names[] = { +#ifdef X86_64 + "rax", + "rcx", + "rdx", + "rbx", + "rsp", + "rbp", + "rsi", + "rdi", +#else + "eax", + "ecx", + "edx", + "ebx", + "esp", + "ebp", + "esi", + "edi", +#endif + "ah", + "ch", + "dh", + "bh", + "r8", + "r9", + "r10", + "r11", + "r12", + "r13", + "r14", + "r15", +}; + +char * x86_sizes[] = { + "b", "w", "d", "q" +}; + void jmp_nocheck(code_info *code, code_ptr dest) { code_ptr out = code->cur; @@ -190,6 +228,7 @@ src = tmp; } if (size == SZ_Q || src >= R8 || dst >= R8 || (size == SZ_B && src >= RSP && src <= RDI)) { +#ifdef X86_64 *out = PRE_REX; if (src >= AH && src <= BH || dst >= AH && dst <= BH) { fprintf(stderr, "attempt to use *H reg in an instruction requiring REX prefix. opcode = %X\n", opcode); @@ -207,6 +246,10 @@ dst -= (R8 - X86_R8); } out++; +#else + fprintf(stderr, "Instruction requires REX prefix but this is a 32-bit build | opcode: %X, src: %s, dst: %s, size: %s\n", opcode, x86_reg_names[src], x86_reg_names[dst], x86_sizes[size]); + exit(1); +#endif } if (size == SZ_B) { if (src >= AH && src <= BH) { @@ -238,6 +281,7 @@ *(out++) = PRE_SIZE; } if (size == SZ_Q || reg >= R8 || base >= R8 || (size == SZ_B && reg >= RSP && reg <= RDI)) { +#ifdef X86_64 *out = PRE_REX; if (reg >= AH && reg <= BH) { fprintf(stderr, "attempt to use *H reg in an instruction requiring REX prefix. opcode = %X\n", opcode); @@ -255,6 +299,10 @@ base -= (R8 - X86_R8); } out++; +#else + fprintf(stderr, "Instruction requires REX prefix but this is a 32-bit build | opcode: %X, reg: %s, base: %s, size: %s\n", opcode, x86_reg_names[reg], x86_reg_names[base], x86_sizes[size]); + exit(1); +#endif } if (size == SZ_B) { if (reg >= AH && reg <= BH) { @@ -298,6 +346,7 @@ *(out++) = PRE_SIZE; } if (size == SZ_Q || reg >= R8 || base >= R8 || (size == SZ_B && reg >= RSP && reg <= RDI)) { +#ifdef X86_64 *out = PRE_REX; if (reg >= AH && reg <= BH) { fprintf(stderr, "attempt to use *H reg in an instruction requiring REX prefix. opcode = %X\n", opcode); @@ -315,6 +364,10 @@ base -= (R8 - X86_R8); } out++; +#else + fprintf(stderr, "Instruction requires REX prefix but this is a 32-bit build | opcode: %X, reg: %s, base: %s, size: %s\n", opcode, x86_reg_names[reg], x86_reg_names[base], x86_sizes[size]); + exit(1); +#endif } if (size == SZ_B) { if (reg >= AH && reg <= BH) { @@ -349,6 +402,7 @@ *(out++) = PRE_SIZE; } if (size == SZ_Q || reg >= R8 || base >= R8 || (size == SZ_B && reg >= RSP && reg <= RDI)) { +#ifdef X86_64 *out = PRE_REX; if (reg >= AH && reg <= BH) { fprintf(stderr, "attempt to use *H reg in an instruction requiring REX prefix. opcode = %X\n", opcode); @@ -370,6 +424,10 @@ index -= (R8 - X86_R8); } out++; +#else + fprintf(stderr, "Instruction requires REX prefix but this is a 32-bit build | opcode: %X, reg: %s, base: %s, size: %s\n", opcode, x86_reg_names[reg], x86_reg_names[base], x86_sizes[size]); + exit(1); +#endif } if (size == SZ_B) { if (reg >= AH && reg <= BH) { @@ -400,6 +458,7 @@ *(out++) = PRE_SIZE; } if (size == SZ_Q || dst >= R8) { +#ifdef X86_64 *out = PRE_REX; if (dst >= AH && dst <= BH) { fprintf(stderr, "attempt to use *H reg in an instruction requiring REX prefix. opcode = %X\n", opcode); @@ -413,6 +472,10 @@ dst -= (R8 - X86_R8); } out++; +#else + fprintf(stderr, "Instruction requires REX prefix but this is a 32-bit build | opcode: %X:%X, reg: %s, size: %s\n", opcode, opex, x86_reg_names[dst], x86_sizes[size]); + exit(1); +#endif } if (size == SZ_B) { if (dst >= AH && dst <= BH) { @@ -435,6 +498,7 @@ *(out++) = PRE_SIZE; } if (size == SZ_Q || dst >= R8) { +#ifdef X86_64 *out = PRE_REX; if (size == SZ_Q) { *out |= REX_QUAD; @@ -444,6 +508,10 @@ dst -= (R8 - X86_R8); } out++; +#else + fprintf(stderr, "Instruction requires REX prefix but this is a 32-bit build | opcode: %X:%X, reg: %s, size: %s\n", opcode, opex, x86_reg_names[dst], x86_sizes[size]); + exit(1); +#endif } if (size != SZ_B) { opcode |= BIT_SIZE; @@ -478,12 +546,18 @@ if (size != SZ_B) { al_opcode |= BIT_SIZE; if (size == SZ_Q) { +#ifdef X86_64 *out = PRE_REX | REX_QUAD; +#else + fprintf(stderr, "Instruction requires REX prefix but this is a 32-bit build | opcode: %X, reg: %s, size: %s\n", al_opcode, x86_reg_names[dst], x86_sizes[size]); + exit(1); +#endif } } *(out++) = al_opcode | BIT_IMMED_RAX; } else { if (size == SZ_Q || dst >= R8 || (size == SZ_B && dst >= RSP && dst <= RDI)) { +#ifdef X86_64 *out = PRE_REX; if (size == SZ_Q) { *out |= REX_QUAD; @@ -493,6 +567,10 @@ dst -= (R8 - X86_R8); } out++; +#else + fprintf(stderr, "Instruction requires REX prefix but this is a 32-bit build | opcode: %X:%X, reg: %s, size: %s\n", opcode, op_ex, x86_reg_names[dst], x86_sizes[size]); + exit(1); +#endif } if (dst >= AH && dst <= BH) { dst -= (AH-X86_AH); @@ -531,6 +609,7 @@ } if (size == SZ_Q || dst >= R8) { +#ifdef X86_64 *out = PRE_REX; if (size == SZ_Q) { *out |= REX_QUAD; @@ -540,6 +619,10 @@ dst -= (R8 - X86_R8); } out++; +#else + fprintf(stderr, "Instruction requires REX prefix but this is a 32-bit build | opcode: %X:%X, reg: %s, size: %s\n", opcode, op_ex, x86_reg_names[dst], x86_sizes[size]); + exit(1); +#endif } if (size != SZ_B) { opcode |= BIT_SIZE;