From 4ecd5d79fc18197838852479cff3ffb1abe78e1a Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Fri, 24 Feb 2012 21:51:46 -0800 Subject: HLE: Implement the basic mechanism for XACQUIRE/XRELEASE This implements the mechanism for XACQUIRE/XRELEASE. It does not include the necessary annotations in insns.dat. Signed-off-by: H. Peter Anvin --- assemble.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- disasm.c | 21 +++++++++++++++++++++ insns.pl | 6 ++++++ nasm.h | 4 ++-- nasmlib.c | 5 +++-- parser.c | 2 ++ tokens.dat | 4 +++- 7 files changed, 87 insertions(+), 6 deletions(-) diff --git a/assemble.c b/assemble.c index 691e792..06fba53 100644 --- a/assemble.c +++ b/assemble.c @@ -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; } diff --git a/disasm.c b/disasm.c index 9bedcc7..c2a21fd 100644 --- a/disasm.c +++ b/disasm.c @@ -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; diff --git a/insns.pl b/insns.pl index d9a968b..d5645e0 100755 --- a/insns.pl +++ b/insns.pl @@ -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); diff --git a/nasm.h b/nasm.h index 23def29..46e4c05 100644 --- a/nasm.h +++ b/nasm.h @@ -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 }; diff --git a/nasmlib.c b/nasmlib.c index e35d99e..254c84c 100644 --- a/nasmlib.c +++ b/nasmlib.c @@ -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) diff --git a/parser.c b/parser.c index 3a592fe..aa2df24 100644 --- a/parser.c +++ b/parser.c @@ -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: diff --git a/tokens.dat b/tokens.dat index c7d3b97..25179fa 100644 --- a/tokens.dat +++ b/tokens.dat @@ -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 -- cgit v1.2.3