OSDN Git Service

* i386.md (notsi, nothi, xorsi, xorhi, and xorqi patterns): Call
authorlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 15 Apr 1999 00:19:03 +0000 (00:19 +0000)
committerlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 15 Apr 1999 00:19:03 +0000 (00:19 +0000)
        memory_address_displacement_length instead of memory_address_length.
        * i386.c (memory_address_info): Renamed from memory_address_length.
        Accept new argument DISP_LENGTH.  All callers changed.  If DISP_LENGTH,
        then return the displacement length.  Else return length of the
        entire memory address.  Handle MULT case correctly.
        * i386.h (memory_address_info): Update declaration.
        * i386.md (memory_bit_test): Fix paren error.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@26465 138bc75d-0d04-0410-961f-82ee72b054a4

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

index 5d592f0..3739e5f 100644 (file)
@@ -1,3 +1,16 @@
+Thu Apr 15 01:03:21 1999  Jan Hubicka <hubicka@freesoft.cz>
+                         Jeff Law <law@cygnus.com>
+
+       * i386.md (notsi, nothi, xorsi, xorhi, and xorqi patterns): Call
+       memory_address_displacement_length instead of memory_address_length.
+       * i386.c (memory_address_info): Renamed from memory_address_length.
+       Accept new argument DISP_LENGTH.  All callers changed.  If DISP_LENGTH,
+       then return the displacement length.  Else return length of the
+       entire memory address.  Handle MULT case correctly.
+       * i386.h (memory_address_info): Update declaration.
+
+       * i386.md (memory_bit_test): Fix paren error.
+
 Wed Apr 14 21:29:18 1999  Andrew Haley  <aph@cygnus.com>
 
        * flow.c: (make_edges): Always make edges from a basic block
index 8432443..5665800 100644 (file)
@@ -5610,12 +5610,16 @@ output_ashlsi3 (operands)
   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.  */
+/* Given the memory address ADDR, calculate the length of the address or
+   the length of just the displacement (controlled by DISP_LENGTH).
+  
+   The length returned does not include the one-byte modrm, opcode,
+   or prefix.  */
 
 int
-memory_address_length (addr)
+memory_address_info (addr, disp_length)
      rtx addr;
+     int disp_length;
 {
   rtx base, index, disp, scale;
   rtx op0, op1;
@@ -5709,6 +5713,11 @@ memory_address_length (addr)
   if (base == frame_pointer_rtx && !disp)
     disp = const0_rtx;
 
+  /* Scaling can not be encoded without base or displacement.  
+     Except for scale == 1 where we can encode reg + reg instead of reg * 2.  */
+  if (!base && index && scale != 1)
+    disp = const0_rtx;
+
   /* Find the length of the displacement constant.  */
   len = 0;
   if (disp)
@@ -5720,8 +5729,9 @@ memory_address_length (addr)
        len = 4;
     }
 
-  /* An index requires the two-byte modrm form.  */
-  if (index)
+  /* An index requires the two-byte modrm form.  Not important
+     if we are computing just length of the displacement.  */
+  if (index && ! disp_length)
     len += 1;
 
   return len;
index 56967a6..1d752c7 100644 (file)
@@ -2766,7 +2766,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 ();
+extern int memory_address_info ();
 
 #ifdef NOTYET
 extern struct rtx_def *copy_all_rtx ();
index 034c0e6..da13109 100644 (file)
@@ -4497,7 +4497,7 @@ byte_xor_operation:
            if (intval == 0xff
                 && (!TARGET_PENTIUM || optimize_size
                     || (GET_CODE (operands[0]) == MEM 
-                        && memory_address_length (XEXP (operands[0], 0)) != 0)))
+                        && memory_address_info (XEXP (operands[0], 0), 1))))
              return AS1 (not%B0,%b0);
 
            if (intval != INTVAL (operands[2]))
@@ -4516,7 +4516,7 @@ byte_xor_operation:
              if (intval == 0xff 
                   && (!TARGET_PENTIUM || optimize_size
                       || (GET_CODE (operands[0]) == MEM 
-                          && memory_address_length (XEXP (operands[0], 0)) != 0)))
+                          && memory_address_info (XEXP (operands[0], 0), 1))))
                return AS1 (not%B0,%h0);
 
              operands[2] = GEN_INT (intval);
@@ -4576,7 +4576,7 @@ byte_xor_operation:
          if (INTVAL (operands[2]) == 0xff 
               && (!TARGET_PENTIUM || optimize_size
                   || (GET_CODE (operands[0]) == MEM 
-                      && memory_address_length (XEXP (operands[0], 0)) != 0)))
+                      && memory_address_info (XEXP (operands[0], 0), 1))))
            return AS1 (not%B0,%b0);
 
          return AS2 (xor%B0,%2,%b0);
@@ -4593,7 +4593,7 @@ byte_xor_operation:
          if (INTVAL (operands[2]) == 0xff
               && (!TARGET_PENTIUM || optimize_size
                   || (GET_CODE (operands[0]) == MEM 
-                      && memory_address_length (XEXP (operands[0], 0)) != 0)))
+                      && memory_address_info (XEXP (operands[0], 0), 1))))
            return AS1 (not%B0,%h0);
 
          return AS2 (xor%B0,%2,%h0);
@@ -4881,81 +4881,87 @@ byte_xor_operation:
        (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
   ""
   "*
-/* A Pentium NOT is not pariable.  Output it only in case of complex
-   memory address, because XOR will be inpariable anyway because
-   of immediate/displacement rule.  */
+{
+  /* A Pentium NOT is not pariable.  Output it only in case of complex
+     memory address, because XOR will be inpariable anyway because
+     of immediate/displacement rule.  */
 
-if (TARGET_PENTIUM && !optimize_size
-    && (GET_CODE (operands[0]) != MEM 
-        || memory_address_length (XEXP (operands[0], 0)) == 0))
-  {
-    rtx xops[2];
-    xops[0] = operands[0];
-    xops[1] = GEN_INT (0xffffffff);
-    output_asm_insn (AS2 (xor%L0,%1,%0), xops);
-    RET;
-  }
-else
-  return AS1 (not%L0,%0);")
+  if (TARGET_PENTIUM && !optimize_size
+      && (GET_CODE (operands[0]) != MEM 
+         || memory_address_info (XEXP (operands[0], 0), 1) == 0))
+    {
+      rtx xops[2];
+      xops[0] = operands[0];
+      xops[1] = GEN_INT (0xffffffff);
+      output_asm_insn (AS2 (xor%L0,%1,%0), xops);
+      RET;
+    }
+  else
+    return AS1 (not%L0,%0);
+}")
 
 (define_insn "one_cmplhi2"
   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
        (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
   ""
   "*
-/* A Pentium NOT is not pariable.  Output it only in case of complex
-   memory address, because XOR will be inpariable anyway because
-   of immediate/displacement rule.  */
+{
+  /* A Pentium NOT is not pariable.  Output it only in case of complex
+     memory address, because XOR will be inpariable anyway because
+     of immediate/displacement rule.  */
 
-if (TARGET_PENTIUM && !optimize_size
-    && (GET_CODE (operands[0]) != MEM 
-        || memory_address_length (XEXP (operands[0], 0)) == 0))
-  {
-    rtx xops[2];
-    xops[0] = operands[0];
-    xops[1] = GEN_INT (0xffff);
-    if (REG_P (operands[0])
-        && i386_cc_probably_useless_p (insn))
-     {
-        CC_STATUS_INIT;
-        output_asm_insn (AS2 (xor%L0,%1,%k0), xops);
-     }
-    else
-      output_asm_insn (AS2 (xor%W0,%1,%0), xops);
-    RET;
-  }
-else
-  {
-    if (REG_P (operands[0])
-        && i386_cc_probably_useless_p (insn))
-     {
-        CC_STATUS_INIT;
-        return AS1 (not%L0,%k0);
-     }
-    return AS1 (not%W0,%0);
-  }")
+  if (TARGET_PENTIUM && !optimize_size
+      && (GET_CODE (operands[0]) != MEM 
+         || memory_address_info (XEXP (operands[0], 0), 1) == 0))
+    {
+      rtx xops[2];
+      xops[0] = operands[0];
+      xops[1] = GEN_INT (0xffff);
+      if (REG_P (operands[0])
+         && i386_cc_probably_useless_p (insn))
+       {
+         CC_STATUS_INIT;
+         output_asm_insn (AS2 (xor%L0,%1,%k0), xops);
+       }
+      else
+       output_asm_insn (AS2 (xor%W0,%1,%0), xops);
+      RET;
+    }
+  else
+    {
+      if (REG_P (operands[0])
+         && i386_cc_probably_useless_p (insn))
+       {
+         CC_STATUS_INIT;
+         return AS1 (not%L0,%k0);
+       }
+      return AS1 (not%W0,%0);
+    }
+}")
 
 (define_insn "one_cmplqi2"
   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
        (not:QI (match_operand:QI 1 "nonimmediate_operand" "0")))]
   ""
   "*
-/* A Pentium NOT is not pariable.  Output it only in case of complex
-   memory address, because XOR will be inpariable anyway because
-   of immediate/displacement rule.  */
+{
+  /* A Pentium NOT is not pariable.  Output it only in case of complex
+     memory address, because XOR will be inpariable anyway because
+     of immediate/displacement rule.  */
 
-if (TARGET_PENTIUM && !optimize_size
-    && (GET_CODE (operands[0]) != MEM 
-        || memory_address_length (XEXP (operands[0], 0)) == 0))
-  {
-    rtx xops[2];
-    xops[0] = operands[0];
-    xops[1] = GEN_INT (0xff);
-    output_asm_insn (AS2 (xor%B0,%1,%0), xops);
-    RET;
-  }
-else
-  return AS1 (not%B0,%0);")
+  if (TARGET_PENTIUM && !optimize_size
+      && (GET_CODE (operands[0]) != MEM 
+         || memory_address_info (XEXP (operands[0], 0), 1) == 0))
+    {
+      rtx xops[2];
+      xops[0] = operands[0];
+      xops[1] = GEN_INT (0xff);
+      output_asm_insn (AS2 (xor%B0,%1,%0), xops);
+      RET;
+    }
+  else
+    return AS1 (not%B0,%0);
+}")
 \f
 ;;- arithmetic shift instructions
 
@@ -5729,7 +5735,7 @@ else
   mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]);
   operands[1] = GEN_INT (mask);
 
-  if (! REG_P (operands[0]) || QI_REG_P (operands[0])
+  if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
       /* A Pentium test is pairable only with eax. Not with ah or al.  */
       && (! REG_P (operands[0]) || REGNO (operands[0]) || !TARGET_PENTIUM
           || optimize_size))