aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@freesoft.cz>1999-04-15 02:19:03 +0200
committerJeff Law <law@gcc.gnu.org>1999-04-14 18:19:03 -0600
commitb222082eee8ef6df2023bc00c085f90bd15bf238 (patch)
tree8900c6151c018b897e3095560b6584c140cc2792
parenta3e924fcb59eb9d3f506904576d92c7b90df6c32 (diff)
downloadgcc-b222082eee8ef6df2023bc00c085f90bd15bf238.zip
gcc-b222082eee8ef6df2023bc00c085f90bd15bf238.tar.gz
gcc-b222082eee8ef6df2023bc00c085f90bd15bf238.tar.bz2
i386.md (notsi, [...]): Call memory_address_displacement_length instead of memory_address_length.
* 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. Co-Authored-By: Jeffrey A Law <law@cygnus.com> From-SVN: r26465
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/config/i386/i386.c20
-rw-r--r--gcc/config/i386/i386.h2
-rw-r--r--gcc/config/i386/i386.md136
4 files changed, 100 insertions, 71 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5d592f0..3739e5f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 8432443..5665800 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -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;
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 56967a6..1d752c7 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -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 ();
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 034c0e6..da13109 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -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);
+}")
;;- 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))