summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2012-02-24 21:51:46 -0800
committerH. Peter Anvin <hpa@zytor.com>2012-02-24 21:57:17 -0800
commit4ecd5d79fc18197838852479cff3ffb1abe78e1a (patch)
treed53db43dcbb42b7266c9286243ee8784128f8a53
parent442a05a8975d53e5e56dd7630ae4480150e5bff4 (diff)
downloadnasm-4ecd5d79fc18197838852479cff3ffb1abe78e1a.tar.gz
nasm-4ecd5d79fc18197838852479cff3ffb1abe78e1a.tar.bz2
nasm-4ecd5d79fc18197838852479cff3ffb1abe78e1a.zip
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 <hpa@zytor.com>
-rw-r--r--assemble.c51
-rw-r--r--disasm.c21
-rwxr-xr-xinsns.pl6
-rw-r--r--nasm.h4
-rw-r--r--nasmlib.c5
-rw-r--r--parser.c2
-rw-r--r--tokens.dat4
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