i386.c (memory_address_length): New function.
authorRichard Henderson <rth@cygnus.com>
Tue, 13 Apr 1999 23:19:26 +0000 (16:19 -0700)
committerJeff Law <law@gcc.gnu.org>
Tue, 13 Apr 1999 23:19:26 +0000 (17:19 -0600)
        * i386.c (memory_address_length): New function.
        * i386.h (memory_address_length): Declare it.

From-SVN: r26432

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/config/i386/i386.h

index b9fe80a1d566369d0cf3651e0076264eed26532f..f1c5773e50a72e78d5b418164cde0f5680bd20db 100644 (file)
@@ -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)
 
index e6f807bc781b0f433a35118fb28859cace2d410c..671d529a9194ba95de35854f6e94da53c42447ab 100644 (file)
@@ -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;
+}
index 3e6ed9efe490f69229c75d71b80600292b581b1e..de4da2cb6fe7d28293c8d375094cab6157ca7645 100644 (file)
@@ -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 ();