diff options
-rw-r--r-- | assemble.c | 51 | ||||
-rw-r--r-- | disasm.c | 21 | ||||
-rwxr-xr-x | insns.pl | 6 | ||||
-rw-r--r-- | nasm.h | 4 | ||||
-rw-r--r-- | nasmlib.c | 5 | ||||
-rw-r--r-- | parser.c | 2 | ||||
-rw-r--r-- | tokens.dat | 4 |
7 files changed, 87 insertions, 6 deletions
@@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- * * - * Copyright 1996-2011 The NASM Authors - All Rights Reserved + * Copyright 1996-2012 The NASM Authors - All Rights Reserved * See the file AUTHORS included with the NASM distribution for * the specific copyright holders. * @@ -97,6 +97,9 @@ * * t = 0 for VEX (C4/C5), t = 1 for XOP (8F). * + * \271 - instruction takes XRELEASE (F3) with or without lock + * \272 - instruction takes XACQUIRE/XRELEASE with or without lock + * \273 - instruction takes XACQUIRE/XRELEASE with lock only * \274..\277 - a signed byte immediate operand, from operand 0..3, * which is to be extended to the operand size. * \310 - indicates fixed 16-bit address size, i.e. optional 0x67. @@ -507,11 +510,13 @@ int64_t assemble(int32_t segment, int64_t offset, int bits, uint32_t cp, break; case P_REPNE: case P_REPNZ: + case P_XACQUIRE: c = 0xF2; break; case P_REPE: case P_REPZ: case P_REP: + case P_XRELEASE: c = 0xF3; break; case R_CS: @@ -787,6 +792,41 @@ static bool is_sbyte32(operand *o) return v >= -128 && v <= 127; } +static void bad_hle_warn(const insn * ins, uint8_t hleok) +{ + enum prefixes rep_pfx = ins->prefixes[PPS_REP]; + enum whatwarn { w_none, w_lock, w_inval }; + static const enum whatwarn warn[2][4] = + { + { w_inval, w_inval, w_none, w_lock }, /* XACQUIRE */ + { w_inval, w_none, w_none, w_lock }, /* XRELEASE */ + }; + unsigned int n; + + n = (unsigned int)rep_pfx - P_XACQUIRE; + if (n > 1) + return; /* Not XACQUIRE/XRELEASE */ + + switch (warn[n][hleok]) { + case w_none: + break; + + case w_lock: + if (ins->prefixes[PPS_LOCK] != P_LOCK) { + errfunc(ERR_WARNING | ERR_PASS2, + "%s with this instruction requires lock", + prefix_name(rep_pfx)); + } + break; + + case w_inval: + errfunc(ERR_WARNING | ERR_PASS2, + "%s invalid with this instruction", + prefix_name(rep_pfx)); + break; + } +} + /* Common construct */ #define case4(x) case (x): case (x)+1: case (x)+2: case (x)+3 @@ -800,6 +840,7 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits, struct operand *opx; uint8_t opex = 0; enum ea_type eat; + uint8_t hleok = 0; ins->rex = 0; /* Ensure REX is reset */ eat = EA_SCALAR; /* Expect a scalar EA */ @@ -939,6 +980,12 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits, ins->vex_wlp = *codes++; break; + case 0271: + case 0272: + case 0273: + hleok = c & 3; + break; + case4(0274): length++; break; @@ -1190,6 +1237,8 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits, return -1; } } + + bad_hle_warn(ins, hleok); return length; } @@ -703,6 +703,27 @@ static int matches(const struct itemplate *t, uint8_t *data, break; } + case 0271: + if (prefix->rep == 0xF3) + drep = P_XRELEASE; + break; + + case 0272: + if (prefix->rep == 0xF2) + drep = P_XACQUIRE; + else if (prefix->rep == 0xF3) + drep = P_XRELEASE; + break; + + case 0273: + if (prefix->lock == 0xF0) { + if (prefix->rep == 0xF2) + drep = P_XACQUIRE; + else if (prefix->rep == 0xF3) + drep = P_XRELEASE; + } + break; + case 0310: if (asize != 16) return false; @@ -744,6 +744,12 @@ sub byte_code_compile($$) { push(@codes, 0325); } elsif ($op eq 'wait') { # Needs a wait prefix push(@codes, 0341); + } elsif ($op eq 'hlexr') { + push(@codes, 0271); + } elsif ($op eq 'hlenl') { + push(@codes, 0272); + } elsif ($op eq 'hle') { + push(@codes, 0273); } elsif ($op eq 'vsibx' || $op eq 'vm32x' || $op eq 'vm64x') { # This instruction takes XMM VSIB push(@codes, 0374); @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- * * - * Copyright 1996-2011 The NASM Authors - All Rights Reserved + * Copyright 1996-2012 The NASM Authors - All Rights Reserved * See the file AUTHORS included with the NASM distribution for * the specific copyright holders. * @@ -473,7 +473,7 @@ enum prefixes { /* instruction prefixes */ P_A16 = PREFIX_ENUM_START, P_A32, P_A64, P_ASP, P_LOCK, P_O16, P_O32, P_O64, P_OSP, P_REP, P_REPE, P_REPNE, P_REPNZ, P_REPZ, P_TIMES, - P_WAIT, + P_WAIT, P_XACQUIRE, P_XRELEASE, PREFIX_ENUM_LIMIT }; @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- * * - * Copyright 1996-2010 The NASM Authors - All Rights Reserved + * Copyright 1996-2012 The NASM Authors - All Rights Reserved * See the file AUTHORS included with the NASM distribution for * the specific copyright holders. * @@ -563,7 +563,8 @@ void standard_extension(char *inname, char *outname, char *extension) */ static const char *prefix_names[] = { "a16", "a32", "a64", "asp", "lock", "o16", "o32", "o64", "osp", - "rep", "repe", "repne", "repnz", "repz", "times", "wait" + "rep", "repe", "repne", "repnz", "repz", "times", "wait", + "xacquire", "xrelease" }; const char *prefix_name(int token) @@ -87,6 +87,8 @@ static int prefix_slot(int prefix) case P_REPZ: case P_REPNE: case P_REPNZ: + case P_XACQUIRE: + case P_XRELEASE: return PPS_REP; case P_O16: case P_O32: @@ -1,6 +1,6 @@ ## -------------------------------------------------------------------------- ## -## Copyright 1996-2009 The NASM Authors - All Rights Reserved +## Copyright 1996-2012 The NASM Authors - All Rights Reserved ## See the file AUTHORS included with the NASM distribution for ## the specific copyright holders. ## @@ -52,6 +52,8 @@ repnz repz times wait +xacquire +xrelease % TOKEN_SPECIAL, 0, S_* abs |