From: Alan Modra <alan@SPRI.Levels.UniSA.Edu.Au>
To: Klaus Espenlaub <espenlaub@informatik.uni-ulm.de>
Cc: binutils@sourceware.cygnus.com
Subject: Re: binutils-as: can addr32 prefix be automatically inferred?
Date: Mon, 02 Aug 1999 16:20:00 -0000 [thread overview]
Message-ID: <Pine.LNX.4.10.9908030841550.28159-100000@mullet.itr.unisa.edu.au> (raw)
In-Reply-To: <37A5BBB0.7E6753E@informatik.uni-ulm.de>
On Mon, 2 Aug 1999, Klaus Espenlaub wrote:
> I just stumbled across some old code that already uses the .code16 feature
> of the i386 gas. It contains instructions like
>
> .code16
> movl 8(%ebp),%edx
> leal (%esi,%edx),%eax
>
> The old gas (2.9.1) automatically inferred the required addr32 prefixes for
> these instructions, while the 990628 snapshot just gives error messages:
>
> /tmp/cca19394.s:257: Error: `8(%ebp)' is not a valid 16 bit base/index expression
> /tmp/cca20380.s:289: Error: `(%esi,%edx)' is not a valid 16 bit base/index expression
>
> While this is a valid behaviour, it would be more convenient to put at
> least a limited heuristics into gas, making old code acceptable to the
> newer (and stricter) gas. But if you decide against it, please state that
> somewhere public (like the gas docs) so that there is no further confusion
> about this matter. I don't care, because someone else has to maintain the
> code I am just using :)
Hello Klaus,
The following patch (untested!) ought to do what you want. I
re-indented i386_intel_operand, so there are a few extra lines in the
patch. Can you test it out please?
--- binutils-current/gas/config/tc-i386.c~ Tue Jul 20 23:41:31 1999
+++ binutils-current/gas/config/tc-i386.c Tue Aug 3 08:38:14 1999
@@ -40,6 +40,10 @@
#define REGISTER_WARNINGS 1
#endif
+#ifndef INFER_ADDR_PREFIX
+#define INFER_ADDR_PREFIX 1
+#endif
+
#ifndef SCALE1_WHEN_NO_INDEX
/* Specifying a scale factor besides 1 when there is no index is
futile. eg. `mov (%ebx,2),%al' does exactly the same as
@@ -3241,71 +3245,71 @@ i386_intel_operand (operand_string, got_
case SHORT:
case NONE_FOUND:
- /* Should be register or immediate */
- if (is_digit_char (*op_string)
- && strchr (op_string, '[') == 0)
- {
- if (!i386_immediate (op_string))
- return 0;
- }
- else if (*op_string == REGISTER_PREFIX
- || (allow_naked_reg
- && i386_is_reg (op_string)))
- {
-
- register const reg_entry * r;
- char *end_op;
+ /* Should be register or immediate */
+ if (is_digit_char (*op_string)
+ && strchr (op_string, '[') == 0)
+ {
+ if (!i386_immediate (op_string))
+ return 0;
+ }
+ else if (*op_string == REGISTER_PREFIX
+ || (allow_naked_reg
+ && i386_is_reg (op_string)))
+ {
- r = parse_register (op_string, &end_op);
- if (r == NULL)
- return 0;
+ register const reg_entry * r;
+ char *end_op;
- /* Check for a segment override by searching for ':' after a
- segment register. */
- op_string = end_op;
- if (is_space_char (*op_string))
- ++op_string;
- if (*op_string == ':' && (r->reg_type & (SReg2 | SReg3)))
- {
- switch (r->reg_num)
- {
- case 0:
- i.seg[i.mem_operands] = &es;
- break;
- case 1:
- i.seg[i.mem_operands] = &cs;
- break;
- case 2:
- i.seg[i.mem_operands] = &ss;
- break;
- case 3:
- i.seg[i.mem_operands] = &ds;
- break;
- case 4:
- i.seg[i.mem_operands] = &fs;
- break;
- case 5:
- i.seg[i.mem_operands] = &gs;
- break;
- }
+ r = parse_register (op_string, &end_op);
+ if (r == NULL)
+ return 0;
+
+ /* Check for a segment override by searching for ':' after a
+ segment register. */
+ op_string = end_op;
+ if (is_space_char (*op_string))
+ ++op_string;
+ if (*op_string == ':' && (r->reg_type & (SReg2 | SReg3)))
+ {
+ switch (r->reg_num)
+ {
+ case 0:
+ i.seg[i.mem_operands] = &es;
+ break;
+ case 1:
+ i.seg[i.mem_operands] = &cs;
+ break;
+ case 2:
+ i.seg[i.mem_operands] = &ss;
+ break;
+ case 3:
+ i.seg[i.mem_operands] = &ds;
+ break;
+ case 4:
+ i.seg[i.mem_operands] = &fs;
+ break;
+ case 5:
+ i.seg[i.mem_operands] = &gs;
+ break;
+ }
- }
- i.types[this_operand] |= r->reg_type & ~BaseIndex;
- i.regs[this_operand] = r;
- i.reg_operands++;
- }
+ }
+ i.types[this_operand] |= r->reg_type & ~BaseIndex;
+ i.regs[this_operand] = r;
+ i.reg_operands++;
+ }
- else
- {
+ else
+ {
- if (!i386_intel_memory_operand (op_string))
- return 0;
+ if (!i386_intel_memory_operand (op_string))
+ return 0;
- i.mem_operands++;
- }
- break;
+ i.mem_operands++;
+ }
+ break;
- } /* end switch */
+ } /* end switch */
/* Special case for (%dx) while doing input/output op. */
if (i.base_reg
&& i.base_reg->reg_type == (Reg16 | InOutPortReg)
@@ -3313,42 +3317,68 @@ i386_intel_operand (operand_string, got_
&& i.log2_scale_factor == 0
&& i.seg[i.mem_operands] == 0
&& (i.types[this_operand] & Disp) == 0)
- {
- i.types[this_operand] = InOutPortReg;
- return 1;
- }
+ {
+ i.types[this_operand] = InOutPortReg;
+ return 1;
+ }
/* Make sure the memory operand we've been dealt is valid. */
if (flag_16bit_code ^ (i.prefix[ADDR_PREFIX] != 0))
{
+#if INFER_ADDR_PREFIX
+ try16:
+#endif
if ((i.base_reg
&& ((i.base_reg->reg_type & (Reg16|BaseIndex))
- != (Reg16|BaseIndex)))
- || (i.index_reg
- && (((i.index_reg->reg_type & (Reg16|BaseIndex))
- != (Reg16|BaseIndex))
- || ! (i.base_reg
- && i.base_reg->reg_num < 6
- && i.index_reg->reg_num >= 6
- && i.log2_scale_factor == 0))))
- {
- as_bad (_("`%s' is not a valid %s bit base/index expression"),
- operand_string, "16");
- return 0;
- }
+ != (Reg16|BaseIndex)))
+ || (i.index_reg
+ && (((i.index_reg->reg_type & (Reg16|BaseIndex))
+ != (Reg16|BaseIndex))
+ || ! (i.base_reg
+ && i.base_reg->reg_num < 6
+ && i.index_reg->reg_num >= 6
+ && i.log2_scale_factor == 0))))
+ {
+ if (i.prefix[ADDR_PREFIX] != 0)
+ {
+ as_bad (_("`%s' is not a valid %s bit base/index expression"),
+ operand_string, "16");
+ return 0;
+ }
+#if INFER_ADDR_PREFIX
+ else
+ {
+ i.prefix[ADDR_PREFIX] = ADDR_PREFIX_OPCODE;
+ goto try32;
+ }
+#endif
+ }
}
- else
+ else
+ {
+#if INFER_ADDR_PREFIX
+ try32:
+#endif
+ if ((i.base_reg
+ && (i.base_reg->reg_type & Reg32) == 0)
+ || (i.index_reg
+ && ((i.index_reg->reg_type & (Reg32|BaseIndex))
+ != (Reg32|BaseIndex))))
{
- if ((i.base_reg
- && (i.base_reg->reg_type & Reg32) == 0)
- || (i.index_reg
- && ((i.index_reg->reg_type & (Reg32|BaseIndex))
- != (Reg32|BaseIndex))))
+ if (i.prefix[ADDR_PREFIX] != 0)
{
as_bad (_("`%s' is not a valid %s bit base/index expression"),
operand_string, "32");
return 0;
}
+#if INFER_ADDR_PREFIX
+ else
+ {
+ i.prefix[ADDR_PREFIX] = ADDR_PREFIX_OPCODE;
+ goto try16;
+ }
+#endif
}
+ }
return 1;
}
next parent reply other threads:[~1999-08-02 16:20 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <37A5BBB0.7E6753E@informatik.uni-ulm.de>
1999-08-02 16:20 ` Alan Modra [this message]
1999-08-02 22:52 ` Alan Modra
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Pine.LNX.4.10.9908030841550.28159-100000@mullet.itr.unisa.edu.au \
--to=alan@spri.levels.unisa.edu.au \
--cc=binutils@sourceware.cygnus.com \
--cc=espenlaub@informatik.uni-ulm.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).