From b222082eee8ef6df2023bc00c085f90bd15bf238 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Thu, 15 Apr 1999 02:19:03 +0200 Subject: [PATCH] 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 From-SVN: r26465 --- gcc/ChangeLog | 13 ++++ gcc/config/i386/i386.c | 20 ++++-- gcc/config/i386/i386.h | 2 +- gcc/config/i386/i386.md | 136 +++++++++++++++++++++------------------- 4 files changed, 100 insertions(+), 71 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5d592f04423..3739e5f3de8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +Thu Apr 15 01:03:21 1999 Jan Hubicka + Jeff Law + + * 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 * 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 8432443a06a..5665800bcb3 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 56967a69165..1d752c7b472 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 034c0e67401..da131099ec5 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)) -- 2.30.2