aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Schwab <schwab@linux-m68k.org>2024-08-27 21:01:00 +0200
committerAndreas Schwab <schwab@linux-m68k.org>2024-08-27 22:21:44 +0200
commita83e519ab2d4e7df2756411cd9d21c6f1b583429 (patch)
treec86dcbfa815e61fbd1324f3efec8b8433f97e2d7
parent02dff52c60e5b89d290147f142f655c7817154c2 (diff)
downloadgcc-a83e519ab2d4e7df2756411cd9d21c6f1b583429.zip
gcc-a83e519ab2d4e7df2756411cd9d21c6f1b583429.tar.gz
gcc-a83e519ab2d4e7df2756411cd9d21c6f1b583429.tar.bz2
m68k: Accept ASHIFT like MULT in address operand
When LRA pulls an address operand out of a MEM it caninoicalizes a containing MULT into ASHIFT. Adjust the address decomposer to recognize this form. PR target/116413 * config/m68k/m68k.cc (m68k_decompose_index): Accept ASHIFT like MULT. (m68k_rtx_costs) [PLUS]: Likewise. (m68k_legitimize_address): Likewise.
-rw-r--r--gcc/config/m68k/m68k.cc58
1 files changed, 40 insertions, 18 deletions
diff --git a/gcc/config/m68k/m68k.cc b/gcc/config/m68k/m68k.cc
index 21c9498..7986e92 100644
--- a/gcc/config/m68k/m68k.cc
+++ b/gcc/config/m68k/m68k.cc
@@ -1503,12 +1503,14 @@ m68k_legitimize_address (rtx x, rtx oldx, machine_mode mode)
#define COPY_ONCE(Y) if (!copied) { Y = copy_rtx (Y); copied = ch = 1; }
- if (GET_CODE (XEXP (x, 0)) == MULT)
+ if (GET_CODE (XEXP (x, 0)) == MULT
+ || GET_CODE (XEXP (x, 0)) == ASHIFT)
{
COPY_ONCE (x);
XEXP (x, 0) = force_operand (XEXP (x, 0), 0);
}
- if (GET_CODE (XEXP (x, 1)) == MULT)
+ if (GET_CODE (XEXP (x, 1)) == MULT
+ || GET_CODE (XEXP (x, 1)) == ASHIFT)
{
COPY_ONCE (x);
XEXP (x, 1) = force_operand (XEXP (x, 1), 0);
@@ -2069,16 +2071,29 @@ m68k_decompose_index (rtx x, bool strict_p, struct m68k_address *address)
/* Check for a scale factor. */
scale = 1;
- if ((TARGET_68020 || TARGET_COLDFIRE)
- && GET_CODE (x) == MULT
- && GET_CODE (XEXP (x, 1)) == CONST_INT
- && (INTVAL (XEXP (x, 1)) == 2
- || INTVAL (XEXP (x, 1)) == 4
- || (INTVAL (XEXP (x, 1)) == 8
- && (TARGET_COLDFIRE_FPU || !TARGET_COLDFIRE))))
+ if (TARGET_68020 || TARGET_COLDFIRE)
{
- scale = INTVAL (XEXP (x, 1));
- x = XEXP (x, 0);
+ if (GET_CODE (x) == MULT
+ && GET_CODE (XEXP (x, 1)) == CONST_INT
+ && (INTVAL (XEXP (x, 1)) == 2
+ || INTVAL (XEXP (x, 1)) == 4
+ || (INTVAL (XEXP (x, 1)) == 8
+ && (TARGET_COLDFIRE_FPU || !TARGET_COLDFIRE))))
+ {
+ scale = INTVAL (XEXP (x, 1));
+ x = XEXP (x, 0);
+ }
+ /* LRA uses ASHIFT instead of MULT outside of MEM. */
+ else if (GET_CODE (x) == ASHIFT
+ && GET_CODE (XEXP (x, 1)) == CONST_INT
+ && (INTVAL (XEXP (x, 1)) == 1
+ || INTVAL (XEXP (x, 1)) == 2
+ || (INTVAL (XEXP (x, 1)) == 3
+ && (TARGET_COLDFIRE_FPU || !TARGET_COLDFIRE))))
+ {
+ scale = 1 << INTVAL (XEXP (x, 1));
+ x = XEXP (x, 0);
+ }
}
/* Check for a word extension. */
@@ -2246,8 +2261,10 @@ m68k_decompose_address (machine_mode mode, rtx x,
??? do_tablejump creates these addresses before placing the target
label, so we have to assume that unplaced labels are jump table
references. It seems unlikely that we would ever generate indexed
- accesses to unplaced labels in other cases. */
+ accesses to unplaced labels in other cases. Do not accept it in
+ PIC mode, since the label address will need to be loaded from memory. */
if (GET_CODE (x) == PLUS
+ && !flag_pic
&& m68k_jump_table_ref_p (XEXP (x, 1))
&& m68k_decompose_index (XEXP (x, 0), strict_p, address))
{
@@ -3068,12 +3085,17 @@ m68k_rtx_costs (rtx x, machine_mode mode, int outer_code,
/* An lea costs about three times as much as a simple add. */
if (mode == SImode
&& GET_CODE (XEXP (x, 1)) == REG
- && GET_CODE (XEXP (x, 0)) == MULT
- && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
- && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
- && (INTVAL (XEXP (XEXP (x, 0), 1)) == 2
- || INTVAL (XEXP (XEXP (x, 0), 1)) == 4
- || INTVAL (XEXP (XEXP (x, 0), 1)) == 8))
+ && ((GET_CODE (XEXP (x, 0)) == MULT
+ && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
+ && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
+ && (INTVAL (XEXP (XEXP (x, 0), 1)) == 2
+ || INTVAL (XEXP (XEXP (x, 0), 1)) == 4
+ || INTVAL (XEXP (XEXP (x, 0), 1)) == 8))
+ || (GET_CODE (XEXP (x, 0)) == ASHIFT
+ && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
+ && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
+ && ((unsigned HOST_WIDE_INT) INTVAL (XEXP (XEXP (x, 0), 1))
+ <= 3))))
{
/* lea an@(dx:l:i),am */
*total = COSTS_N_INSNS (TARGET_COLDFIRE ? 2 : 3);