aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2006-12-29 06:02:04 +0000
committerH.J. Lu <hjl.tools@gmail.com>2006-12-29 06:02:04 +0000
commitcab737b91fedd56af3b24b5bdd3c3c2efb1426f2 (patch)
tree8f6456d8b674fdd0a02c01d66e0153a647765cb8 /gas
parent994d1171c0efce1e6cefd6024abd4f965b41dffc (diff)
downloadgdb-cab737b91fedd56af3b24b5bdd3c3c2efb1426f2.zip
gdb-cab737b91fedd56af3b24b5bdd3c3c2efb1426f2.tar.gz
gdb-cab737b91fedd56af3b24b5bdd3c3c2efb1426f2.tar.bz2
2006-12-28 H.J. Lu <hongjiu.lu@intel.com>
* config/tc-i386.c (process_operands): Check i.reg_operands and increment i.operands when adding a register operand. (build_modrm_byte): Fix 4 operand instruction handling.
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog6
-rw-r--r--gas/config/tc-i386.c38
2 files changed, 33 insertions, 11 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index c545ce1..bb811e3 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,9 @@
+2006-12-28 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/tc-i386.c (process_operands): Check i.reg_operands
+ and increment i.operands when adding a register operand.
+ (build_modrm_byte): Fix 4 operand instruction handling.
+
2006-12-27 H.J. Lu <hongjiu.lu@intel.com>
* config/tc-i386.c (disp_expressions): Use MAX_MEMORY_OPERANDS
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 856e953..079e9d8 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -3335,10 +3335,12 @@ process_operands ()
{
unsigned int first_reg_op = (i.types[0] & Reg) ? 0 : 1;
/* Pretend we saw the extra register operand. */
- assert (i.op[first_reg_op + 1].regs == 0);
+ assert (i.reg_operands == 1
+ && i.op[first_reg_op + 1].regs == 0);
i.op[first_reg_op + 1].regs = i.op[first_reg_op].regs;
i.types[first_reg_op + 1] = i.types[first_reg_op];
- i.reg_operands = 2;
+ i.operands++;
+ i.reg_operands++;
}
if (i.tm.opcode_modifier & ShortForm)
@@ -3427,16 +3429,30 @@ build_modrm_byte ()
if (i.reg_operands == 2)
{
unsigned int source, dest;
- source = ((i.types[0]
- & (Reg | RegMMX | RegXMM
- | SReg2 | SReg3
- | Control | Debug | Test))
- ? 0 : 1);
- /* In 4 operands instructions with 2 immediate operands, the first
- two are immediate bytes and hence source operand will be in the
- next byte after the immediates */
- if ((i.operands == 4)&&(i.imm_operands=2)) source++;
+ switch (i.operands)
+ {
+ case 2:
+ source = 0;
+ break;
+ case 3:
+ /* When there are 3 operands, one of them must be immediate,
+ which may be the first or the last operand. */
+ assert (i.imm_operands == 1);
+ source = (i.types[0] & Imm) ? 1 : 0;
+ break;
+ case 4:
+ /* When there are 4 operands, the first two must be immediate
+ operands. The source operand will be the 3rd one. */
+ assert (i.imm_operands == 2
+ && (i.types[0] & Imm)
+ && (i.types[1] & Imm));
+ source = 2;
+ break;
+ default:
+ abort ();
+ }
+
dest = source + 1;
i.rm.mode = 3;