From: Peter Johnson Date: Tue, 3 Oct 2006 05:33:54 +0000 (-0000) Subject: Improve error message for illegal use of A/B/C/DH with REX instruction. X-Git-Tag: v0.6.0~142 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=590a1cc51087be27f0427ea16ae27786b3d7a080;p=yasm Improve error message for illegal use of A/B/C/DH with REX instruction. svn path=/trunk/yasm/; revision=1637 --- diff --git a/modules/arch/x86/tests/mem64-err.errwarn b/modules/arch/x86/tests/mem64-err.errwarn index d8972bbc..c9b1943d 100644 --- a/modules/arch/x86/tests/mem64-err.errwarn +++ b/modules/arch/x86/tests/mem64-err.errwarn @@ -2,4 +2,4 @@ -:4: 16-bit addresses not supported in 64-bit mode -:5: invalid effective address -:6: invalid effective address --:7: invalid combination of operands and effective address +-:7: cannot use A/B/C/DH with instruction needing REX diff --git a/modules/arch/x86/tests/nomem64-err2.errwarn b/modules/arch/x86/tests/nomem64-err2.errwarn index f4a79b24..b26a14d1 100644 --- a/modules/arch/x86/tests/nomem64-err2.errwarn +++ b/modules/arch/x86/tests/nomem64-err2.errwarn @@ -1,2 +1,2 @@ --:2: invalid combination of opcode and operands --:3: invalid combination of opcode and operands +-:2: cannot use A/B/C/DH with instruction needing REX +-:3: cannot use A/B/C/DH with instruction needing REX diff --git a/modules/arch/x86/x86bc.c b/modules/arch/x86/x86bc.c index 6897261b..4cc19a0c 100644 --- a/modules/arch/x86/x86bc.c +++ b/modules/arch/x86/x86bc.c @@ -128,14 +128,21 @@ yasm_x86__set_rex_from_reg(unsigned char *rex, unsigned char *low3, x86_expritem_reg_size size = (x86_expritem_reg_size)(reg & ~0xFUL); if (size == X86_REG8X || (reg & 0xF) >= 8) { - if (*rex == 0xff) + /* Check to make sure we can set it */ + if (*rex == 0xff) { + yasm_error_set(YASM_ERROR_TYPE, + N_("cannot use A/B/C/DH with instruction needing REX")); return 1; + } *rex |= 0x40 | (((reg & 8) >> 3) << rexbit); } else if (size == X86_REG8 && (reg & 7) >= 4) { /* AH/BH/CH/DH, so no REX allowed */ - if (*rex != 0 && *rex != 0xff) + if (*rex != 0 && *rex != 0xff) { + yasm_error_set(YASM_ERROR_TYPE, + N_("cannot use A/B/C/DH with instruction needing REX")); return 1; - *rex = 0xff; + } + *rex = 0xff; /* Flag so we can NEVER set it (see above) */ } } diff --git a/modules/arch/x86/x86expr.c b/modules/arch/x86/x86expr.c index c114547c..2d6b390f 100644 --- a/modules/arch/x86/x86expr.c +++ b/modules/arch/x86/x86expr.c @@ -788,11 +788,8 @@ yasm_x86__expr_checkea(x86_effaddr *x86_ea, unsigned char *addrsize, */ if (yasm_x86__set_rex_from_reg(rex, &low3, (unsigned int)(X86_REG64 | basereg), - bits, X86_REX_B)) { - yasm_error_set(YASM_ERROR_TYPE, - N_("invalid combination of operands and effective address")); + bits, X86_REX_B)) return 1; - } x86_ea->modrm |= low3; /* we don't need an SIB *unless* basereg is ESP or R12 */ if (basereg == REG3264_ESP || basereg == REG64_R12) @@ -818,11 +815,8 @@ yasm_x86__expr_checkea(x86_effaddr *x86_ea, unsigned char *addrsize, else { if (yasm_x86__set_rex_from_reg(rex, &low3, (unsigned int) (X86_REG64 | basereg), bits, - X86_REX_B)) { - yasm_error_set(YASM_ERROR_TYPE, - N_("invalid combination of operands and effective address")); + X86_REX_B)) return 1; - } x86_ea->sib |= low3; } @@ -833,11 +827,8 @@ yasm_x86__expr_checkea(x86_effaddr *x86_ea, unsigned char *addrsize, else { if (yasm_x86__set_rex_from_reg(rex, &low3, (unsigned int) (X86_REG64 | indexreg), bits, - X86_REX_X)) { - yasm_error_set(YASM_ERROR_TYPE, - N_("invalid combination of operands and effective address")); + X86_REX_X)) return 1; - } x86_ea->sib |= low3 << 3; /* Set scale field, 1 case -> 0, so don't bother. */ switch (reg3264mult[indexreg]) { diff --git a/modules/arch/x86/x86id.c b/modules/arch/x86/x86id.c index def4549b..1e73cb27 100644 --- a/modules/arch/x86/x86id.c +++ b/modules/arch/x86/x86id.c @@ -2829,11 +2829,8 @@ yasm_x86__finalize_insn(yasm_arch *arch, yasm_bytecode *bc, spare = (unsigned char)(op->data.reg&7); else if (op->type == YASM_INSN__OPERAND_REG) { if (yasm_x86__set_rex_from_reg(&insn->rex, &spare, - op->data.reg, mode_bits, X86_REX_R)) { - yasm_error_set(YASM_ERROR_TYPE, - N_("invalid combination of opcode and operands")); + op->data.reg, mode_bits, X86_REX_R)) return; - } } else yasm_internal_error(N_("invalid operand conversion")); break; @@ -2841,11 +2838,8 @@ yasm_x86__finalize_insn(yasm_arch *arch, yasm_bytecode *bc, if (op->type == YASM_INSN__OPERAND_REG) { unsigned char opadd; if (yasm_x86__set_rex_from_reg(&insn->rex, &opadd, - op->data.reg, mode_bits, X86_REX_B)) { - yasm_error_set(YASM_ERROR_TYPE, - N_("invalid combination of opcode and operands")); + op->data.reg, mode_bits, X86_REX_B)) return; - } insn->opcode.opcode[0] += opadd; } else yasm_internal_error(N_("invalid operand conversion")); @@ -2854,11 +2848,8 @@ yasm_x86__finalize_insn(yasm_arch *arch, yasm_bytecode *bc, if (op->type == YASM_INSN__OPERAND_REG) { unsigned char opadd; if (yasm_x86__set_rex_from_reg(&insn->rex, &opadd, - op->data.reg, mode_bits, X86_REX_B)) { - yasm_error_set(YASM_ERROR_TYPE, - N_("invalid combination of opcode and operands")); + op->data.reg, mode_bits, X86_REX_B)) return; - } insn->opcode.opcode[1] += opadd; } else yasm_internal_error(N_("invalid operand conversion")); @@ -2871,8 +2862,6 @@ yasm_x86__finalize_insn(yasm_arch *arch, yasm_bytecode *bc, if (!insn->x86_ea || yasm_x86__set_rex_from_reg(&insn->rex, &spare, op->data.reg, mode_bits, X86_REX_R)) { - yasm_error_set(YASM_ERROR_TYPE, - N_("invalid combination of opcode and operands")); if (insn->x86_ea) yasm_xfree(insn->x86_ea); yasm_xfree(insn);