summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>1999-04-13 23:19:26 +0000
committerlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>1999-04-13 23:19:26 +0000
commitcf281cd6027d1c9d1f45e90263dd51c8849e0a95 (patch)
tree7b18d5275c0d4fdd99ef657513638bbaef61e3ef
parent78c45660ff322714605c833a8b312061e1339ec7 (diff)
downloadppe42-gcc-cf281cd6027d1c9d1f45e90263dd51c8849e0a95.tar.gz
ppe42-gcc-cf281cd6027d1c9d1f45e90263dd51c8849e0a95.zip
* i386.c (memory_address_length): New function.
* i386.h (memory_address_length): Declare it. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@26432 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/i386/i386.c117
-rw-r--r--gcc/config/i386/i386.h1
3 files changed, 123 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b9fe80a1d56..f1c5773e50a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+Wed Apr 14 00:08:46 1999 Richard Henderson <rth@cygnus.com>
+
+ * i386.c (memory_address_length): New function.
+ * i386.h (memory_address_length): Declare it.
+
Tue Apr 13 22:52:04 1999 Donn Terry (donn@interix.com)
Martin Heller (Ing.-Buero_Heller@t-online.de)
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index e6f807bc781..671d529a919 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -5545,3 +5545,120 @@ output_ashlsi3 (operands)
/* Otherwise use a shift instruction. */
return AS2 (sal%L0,%2,%0);
}
+
+/* Calculate the length of the memory address in the instruction
+ encoding. Does not include the one-byte modrm, opcode, or prefix. */
+
+int
+memory_address_length (addr)
+ rtx addr;
+{
+ rtx base, index, disp, scale;
+ rtx op0, op1;
+ int len;
+
+ if (GET_CODE (addr) == PRE_DEC
+ || GET_CODE (addr) == POST_INC)
+ return 0;
+
+ /* Register Indirect. */
+ if (register_operand (addr, Pmode))
+ {
+ /* Special cases: ebp and esp need the two-byte modrm form.
+
+ We change [ESI] to [ESI+0] on the K6 when not optimizing
+ for size. */
+ if (addr == stack_pointer_rtx
+ || addr == arg_pointer_rtx
+ || addr == frame_pointer_rtx
+ || (REGNO_REG_CLASS (REGNO (addr)) == SIREG
+ && ix86_cpu == PROCESSOR_K6 && !optimize_size)
+ return 1;
+ else
+ return 0;
+ }
+
+ /* Direct Addressing. */
+ if (CONSTANT_P (addr))
+ return 4;
+
+ index = base = disp = scale = NULL_RTX;
+ op0 = XEXP (addr, 0);
+ op1 = XEXP (addr, 1);
+
+ if (GET_CODE (addr) == PLUS)
+ {
+ if (register_operand (op0, Pmode))
+ {
+ if (register_operand (op1, Pmode))
+ index = op0, base = op1;
+ else
+ base = op0, disp = op1;
+ }
+ else if (GET_CODE (op0) == MULT)
+ {
+ index = XEXP (op0, 0);
+ scale = XEXP (op0, 1);
+ if (register_operand (op1, Pmode))
+ base = op1;
+ else
+ disp = op1;
+ }
+ else if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 0)) == MULT)
+ {
+ index = XEXP (XEXP (op0, 0), 0);
+ scale = XEXP (XEXP (op0, 0), 1);
+ base = XEXP (op0, 1);
+ disp = op1;
+ }
+ else if (GET_CODE (op0) == PLUS)
+ {
+ index = XEXP (op0, 0);
+ base = XEXP (op0, 1);
+ disp = op1;
+ }
+ else
+ abort ();
+ }
+ else if (GET_CODE (addr) == MULT
+ /* We're called for lea too, which implements ashift on occasion. */
+ || GET_CODE (addr) == ASHIFT)
+ {
+ index = XEXP (addr, 0);
+ scale = XEXP (addr, 1);
+ }
+ else
+ abort ();
+
+ /* Allow arg pointer and stack pointer as index if there is not scaling */
+ if (base && index && !scale
+ && (index == stack_pointer_rtx
+ || index == arg_pointer_rtx
+ || index == frame_pointer_rtx))
+ {
+ rtx tmp = base;
+ base = index;
+ index = tmp;
+ }
+
+ /* Special case: ebp cannot be encoded as a base without a displacement. */
+ if (base == frame_pointer_rtx && !disp)
+ disp = const0_rtx;
+
+ /* Find the length of the displacement constant. */
+ len = 0;
+ if (disp)
+ {
+ if (GET_CODE (disp) == CONST_INT
+ && CONST_OK_FOR_LETTER_P (INTVAL (disp), 'K'))
+ len = 1;
+ else
+ len = 4;
+ }
+
+ /* An index requires the two-byte modrm form. */
+ if (index)
+ len += 1;
+
+ return len;
+}
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 3e6ed9efe49..de4da2cb6fe 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -2765,6 +2765,7 @@ extern char *output_fp_conditional_move ();
extern int ix86_can_use_return_insn_p ();
extern int small_shift_operand ();
extern char *output_ashlsi3 ();
+extern int memory_address_length ();
#ifdef NOTYET
extern struct rtx_def *copy_all_rtx ();
OpenPOWER on IntegriCloud