aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/rs6000/rs6000.c41
2 files changed, 31 insertions, 15 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3efacb5..513e14a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,10 @@
2020-01-06 Michael Meissner <meissner@linux.ibm.com>
+ * config/rs6000/rs6000.c (hard_reg_and_mode_to_addr_mask): New
+ helper function to return the valid addressing formats for a given
+ hard register and mode.
+ (rs6000_adjust_vec_address): Call hard_reg_and_mode_to_addr_mask.
+
* config/rs6000/constraints.md (Q constraint): Update
documentation.
* doc/md.texi (RS/6000 constraints): Update 'Q' cosntraint
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 64b40a4..127927d 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -6729,6 +6729,30 @@ rs6000_expand_vector_extract (rtx target, rtx vec, rtx elt)
}
}
+/* Helper function to return an address mask based on a physical register. */
+
+static addr_mask_type
+hard_reg_and_mode_to_addr_mask (rtx reg, machine_mode mode)
+{
+ unsigned int r = reg_or_subregno (reg);
+ addr_mask_type addr_mask;
+
+ gcc_assert (HARD_REGISTER_NUM_P (r));
+ if (INT_REGNO_P (r))
+ addr_mask = reg_addr[mode].addr_mask[RELOAD_REG_GPR];
+
+ else if (FP_REGNO_P (r))
+ addr_mask = reg_addr[mode].addr_mask[RELOAD_REG_FPR];
+
+ else if (ALTIVEC_REGNO_P (r))
+ addr_mask = reg_addr[mode].addr_mask[RELOAD_REG_VMX];
+
+ else
+ gcc_unreachable ();
+
+ return addr_mask;
+}
+
/* Adjust a memory address (MEM) of a vector type to point to a scalar field
within the vector (ELEMENT) with a mode (SCALAR_MODE). Use a base register
temporary (BASE_TMP) to fixup the address. Return the new memory address
@@ -6865,21 +6889,8 @@ rs6000_adjust_vec_address (rtx scalar_reg,
if (GET_CODE (new_addr) == PLUS)
{
rtx op1 = XEXP (new_addr, 1);
- addr_mask_type addr_mask;
- unsigned int scalar_regno = reg_or_subregno (scalar_reg);
-
- gcc_assert (HARD_REGISTER_NUM_P (scalar_regno));
- if (INT_REGNO_P (scalar_regno))
- addr_mask = reg_addr[scalar_mode].addr_mask[RELOAD_REG_GPR];
-
- else if (FP_REGNO_P (scalar_regno))
- addr_mask = reg_addr[scalar_mode].addr_mask[RELOAD_REG_FPR];
-
- else if (ALTIVEC_REGNO_P (scalar_regno))
- addr_mask = reg_addr[scalar_mode].addr_mask[RELOAD_REG_VMX];
-
- else
- gcc_unreachable ();
+ addr_mask_type addr_mask
+ = hard_reg_and_mode_to_addr_mask (scalar_reg, scalar_mode);
if (REG_P (op1) || SUBREG_P (op1))
valid_addr_p = (addr_mask & RELOAD_REG_INDEXED) != 0;