Index: third_party/yasm/patched-yasm/modules/arch/x86/x86bc.c |
=================================================================== |
--- third_party/yasm/patched-yasm/modules/arch/x86/x86bc.c (revision 71129) |
+++ third_party/yasm/patched-yasm/modules/arch/x86/x86bc.c (working copy) |
@@ -25,7 +25,7 @@ |
* POSSIBILITY OF SUCH DAMAGE. |
*/ |
#include <util.h> |
-/*@unused@*/ RCSID("$Id: x86bc.c 2130 2008-10-07 05:38:11Z peter $"); |
+/*@unused@*/ RCSID("$Id: x86bc.c 2279 2010-01-19 07:57:43Z peter $"); |
#include <libyasm.h> |
@@ -106,9 +106,9 @@ |
}; |
int |
-yasm_x86__set_rex_from_reg(unsigned char *rex, unsigned char *drex, |
- unsigned char *low3, uintptr_t reg, |
- unsigned int bits, x86_rex_bit_pos rexbit) |
+yasm_x86__set_rex_from_reg(unsigned char *rex, unsigned char *low3, |
+ uintptr_t reg, unsigned int bits, |
+ x86_rex_bit_pos rexbit) |
{ |
*low3 = (unsigned char)(reg&7); |
@@ -116,17 +116,13 @@ |
x86_expritem_reg_size size = (x86_expritem_reg_size)(reg & ~0xFUL); |
if (size == X86_REG8X || (reg & 0xF) >= 8) { |
- if (drex) { |
- *drex |= ((reg & 8) >> 3) << rexbit; |
- } else { |
- /* 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); |
+ /* 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) { |
@@ -160,16 +156,14 @@ |
} |
void |
-yasm_x86__ea_init(x86_effaddr *x86_ea, unsigned int spare, unsigned int drex, |
- unsigned int need_drex, yasm_bytecode *precbc) |
+yasm_x86__ea_init(x86_effaddr *x86_ea, unsigned int spare, |
+ yasm_bytecode *precbc) |
{ |
if (yasm_value_finalize(&x86_ea->ea.disp, precbc)) |
yasm_error_set(YASM_ERROR_TOO_COMPLEX, |
N_("effective address too complex")); |
x86_ea->modrm &= 0xC7; /* zero spare/reg bits */ |
x86_ea->modrm |= (spare << 3) & 0x38; /* plug in provided bits */ |
- x86_ea->drex = (unsigned char)drex; |
- x86_ea->need_drex = (unsigned char)need_drex; |
} |
void |
@@ -179,7 +173,6 @@ |
x86_ea->need_modrm = 0; |
x86_ea->valid_sib = 0; |
x86_ea->need_sib = 0; |
- x86_ea->need_drex = 0; |
} |
static x86_effaddr * |
@@ -202,20 +195,17 @@ |
x86_ea->sib = 0; |
x86_ea->valid_sib = 0; |
x86_ea->need_sib = 0; |
- x86_ea->drex = 0; |
- x86_ea->need_drex = 0; |
return x86_ea; |
} |
x86_effaddr * |
yasm_x86__ea_create_reg(x86_effaddr *x86_ea, unsigned long reg, |
- unsigned char *rex, unsigned char *drex, |
- unsigned int bits) |
+ unsigned char *rex, unsigned int bits) |
{ |
unsigned char rm; |
- if (yasm_x86__set_rex_from_reg(rex, drex, &rm, reg, bits, X86_REX_B)) |
+ if (yasm_x86__set_rex_from_reg(rex, &rm, reg, bits, X86_REX_B)) |
return NULL; |
if (!x86_ea) |
@@ -236,7 +226,7 @@ |
x86_ea = ea_create(); |
if (arch_x86->parser == X86_PARSER_GAS) { |
- /* Need to change foo+rip into foo wrt rip. |
+ /* Need to change foo+rip into foo wrt rip (even in .intel_syntax mode). |
* Note this assumes a particular ordering coming from the parser |
* to work (it's not very smart)! |
*/ |
@@ -560,7 +550,6 @@ |
/* Compute length of ea and add to total */ |
bc->len += x86_ea->need_modrm + (x86_ea->need_sib ? 1:0); |
- bc->len += x86_ea->need_drex ? 1:0; |
bc->len += (x86_ea->ea.segreg != 0) ? 1 : 0; |
} |
@@ -603,10 +592,10 @@ |
bc->len += immlen/8; |
} |
- /* VEX prefixes never have REX. We can come into this function with the |
- * three byte form, so we need to see if we can optimize to the two byte |
- * form. We can't do it earlier, as we don't know all of the REX byte |
- * until now. |
+ /* VEX and XOP prefixes never have REX (it's embedded in the opcode). |
+ * For VEX, we can come into this function with the three byte form, |
+ * so we need to see if we can optimize to the two byte form. |
+ * We can't do it earlier, as we don't know all of the REX byte until now. |
*/ |
if (insn->special_prefix == 0xC4) { |
/* See if we can shorten the VEX prefix to its two byte form. |
@@ -623,7 +612,7 @@ |
insn->special_prefix = 0xC5; /* mark as two-byte VEX */ |
} |
} else if (insn->rex != 0xff && insn->rex != 0 && |
- insn->special_prefix != 0xC5) |
+ insn->special_prefix != 0xC5 && insn->special_prefix != 0x8F) |
bc->len++; |
bc->len += insn->opcode.len; |
@@ -825,8 +814,8 @@ |
x86_ea ? (unsigned int)(x86_ea->ea.segreg>>8) : 0); |
if (insn->special_prefix != 0) |
YASM_WRITE_8(*bufp, insn->special_prefix); |
- if (insn->special_prefix == 0xC4) { |
- /* 3-byte VEX; merge in 1s complement of REX.R, REX.X, REX.B */ |
+ if (insn->special_prefix == 0xC4 || insn->special_prefix == 0x8F) { |
+ /* 3-byte VEX/XOP; merge in 1s complement of REX.R, REX.X, REX.B */ |
insn->opcode.opcode[0] &= 0x1F; |
if (insn->rex != 0xff) |
insn->opcode.opcode[0] |= ((~insn->rex) & 0x07) << 5; |
@@ -868,9 +857,6 @@ |
YASM_WRITE_8(*bufp, x86_ea->sib); |
} |
- if (x86_ea->need_drex) |
- YASM_WRITE_8(*bufp, x86_ea->drex); |
- |
if (x86_ea->ea.need_disp) { |
unsigned int disp_len = x86_ea->ea.disp.size/8; |