aboutsummaryrefslogtreecommitdiff
path: root/gas/config
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2009-11-12 18:57:14 +0000
committerH.J. Lu <hjl.tools@gmail.com>2009-11-12 18:57:14 +0000
commitc32fa91d70ea20b38f90e5a88911f796b9a6418c (patch)
tree47cc7bf842135ee3a38260211a4df6cdf9ceed74 /gas/config
parentbdf7534a4d39d12d8cfe036007d698c97c922b27 (diff)
downloadgdb-c32fa91d70ea20b38f90e5a88911f796b9a6418c.zip
gdb-c32fa91d70ea20b38f90e5a88911f796b9a6418c.tar.gz
gdb-c32fa91d70ea20b38f90e5a88911f796b9a6418c.tar.bz2
gas/
2009-11-12 H.J. Lu <hongjiu.lu@intel.com> * config/tc-i386.c (LOCKREP_PREFIX): Removed. (REP_PREFIX): New. (LOCK_PREFIX): Likewise. (PREFIX_GROUP): Likewise. (REX_PREFIX): Updated. (MAX_PREFIXES): Likewise. (add_prefix): Updated. Return enum PREFIX_GROUP. (md_assemble): Check for lock without a lockable instruction. (parse_insn): Updated. (output_insn): Likewise. gas/testsuite/ 2009-11-12 H.J. Lu <hongjiu.lu@intel.com> * gas/i386/i386.exp: Run lock-1, lock-1-intel, lockbad-1, x86-64-lock-1, x86-64-lock-1-intel and x86-64-lockbad-1. * gas/i386/lock-1-intel.d: New. * gas/i386/lock-1.d: Likewise. * gas/i386/lock-1.s: Likewise. * gas/i386/lockbad-1.l: Likewise. * gas/i386/lockbad-1.s: Likewise. * gas/i386/x86-64-lock-1-intel.d: Likewise. * gas/i386/x86-64-lock-1.d: Likewise. * gas/i386/x86-64-lock-1.s: Likewise. * gas/i386/x86-64-lockbad-1.l: Likewise. * gas/i386/x86-64-lockbad-1.s: Likewise. opcodes/ 2009-11-12 H.J. Lu <hongjiu.lu@intel.com> * i386-gen.c (opcode_modifiers): Add IsLockable. * i386-opc.h (IsLockable): New. (i386_opcode_modifier): Add islockable. * i386-opc.tbl: Add IsLockable to add, adc, and, btc, btr, bts, cmpxchg, cmpxch8b, dec, inc, neg, not, or, sbb, sub, xor, xadd and xchg. * i386-tbl.h: Regenerated.
Diffstat (limited to 'gas/config')
-rw-r--r--gas/config/tc-i386.c62
1 files changed, 45 insertions, 17 deletions
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index e787215..4f80e98 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -59,14 +59,15 @@
WAIT_PREFIX must be the first prefix since FWAIT is really is an
instruction, and so must come before any prefixes.
The preferred prefix order is SEG_PREFIX, ADDR_PREFIX, DATA_PREFIX,
- LOCKREP_PREFIX. */
+ REP_PREFIX, LOCK_PREFIX. */
#define WAIT_PREFIX 0
#define SEG_PREFIX 1
#define ADDR_PREFIX 2
#define DATA_PREFIX 3
-#define LOCKREP_PREFIX 4
-#define REX_PREFIX 5 /* must come last. */
-#define MAX_PREFIXES 6 /* max prefixes per opcode */
+#define REP_PREFIX 4
+#define LOCK_PREFIX 5
+#define REX_PREFIX 6 /* must come last. */
+#define MAX_PREFIXES 7 /* max prefixes per opcode */
/* we define the syntax here (modulo base,index,scale syntax) */
#define REGISTER_PREFIX '%'
@@ -1783,13 +1784,26 @@ offset_in_range (offsetT val, int size)
return val & mask;
}
-/* Returns 0 if attempting to add a prefix where one from the same
- class already exists, 1 if non rep/repne added, 2 if rep/repne
- added. */
-static int
+enum PREFIX_GROUP
+{
+ PREFIX_EXIST = 0,
+ PREFIX_LOCK,
+ PREFIX_REP,
+ PREFIX_OTHER
+};
+
+/* Returns
+ a. PREFIX_EXIST if attempting to add a prefix where one from the
+ same class already exists.
+ b. PREFIX_LOCK if lock prefix is added.
+ c. PREFIX_REP if rep/repne prefix is added.
+ d. PREFIX_OTHER if other prefix is added.
+ */
+
+static enum PREFIX_GROUP
add_prefix (unsigned int prefix)
{
- int ret = 1;
+ enum PREFIX_GROUP ret = PREFIX_OTHER;
unsigned int q;
if (prefix >= REX_OPCODE && prefix < REX_OPCODE + 16
@@ -1798,7 +1812,7 @@ add_prefix (unsigned int prefix)
if ((i.prefix[REX_PREFIX] & prefix & REX_W)
|| ((i.prefix[REX_PREFIX] & (REX_R | REX_X | REX_B))
&& (prefix & (REX_R | REX_X | REX_B))))
- ret = 0;
+ ret = PREFIX_EXIST;
q = REX_PREFIX;
}
else
@@ -1819,10 +1833,13 @@ add_prefix (unsigned int prefix)
case REPNE_PREFIX_OPCODE:
case REPE_PREFIX_OPCODE:
- ret = 2;
- /* fall thru */
+ q = REP_PREFIX;
+ ret = PREFIX_REP;
+ break;
+
case LOCK_PREFIX_OPCODE:
- q = LOCKREP_PREFIX;
+ q = LOCK_PREFIX;
+ ret = PREFIX_LOCK;
break;
case FWAIT_OPCODE:
@@ -1838,7 +1855,7 @@ add_prefix (unsigned int prefix)
break;
}
if (i.prefix[q] != 0)
- ret = 0;
+ ret = PREFIX_EXIST;
}
if (ret)
@@ -2915,6 +2932,15 @@ md_assemble (char *line)
if (!add_prefix (FWAIT_OPCODE))
return;
+ /* Check for lock without a lockable instruction. */
+ if (i.prefix[LOCK_PREFIX]
+ && (!i.tm.opcode_modifier.islockable
+ || i.mem_operands == 0))
+ {
+ as_bad (_("expecting lockable instruction after `lock'"));
+ return;
+ }
+
/* Check string instruction segment overrides. */
if (i.tm.opcode_modifier.isstring && i.mem_operands != 0)
{
@@ -3111,11 +3137,13 @@ parse_insn (char *line, char *mnemonic)
/* Add prefix, checking for repeated prefixes. */
switch (add_prefix (current_templates->start->base_opcode))
{
- case 0:
+ case PREFIX_EXIST:
return NULL;
- case 2:
+ case PREFIX_REP:
expecting_string_instruction = current_templates->start->name;
break;
+ default:
+ break;
}
/* Skip past PREFIX_SEPARATOR and reset token_start. */
token_start = ++l;
@@ -5636,7 +5664,7 @@ output_insn (void)
{
check_prefix:
if (prefix != REPE_PREFIX_OPCODE
- || (i.prefix[LOCKREP_PREFIX]
+ || (i.prefix[REP_PREFIX]
!= REPE_PREFIX_OPCODE))
add_prefix (prefix);
}