aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Law <law@gcc.gnu.org>1997-06-12 15:37:43 -0600
committerJeff Law <law@gcc.gnu.org>1997-06-12 15:37:43 -0600
commitb0fabad3944585b9982992ce8256c7030a0903fa (patch)
tree0da3a021b802102127541bc69253300a9eeca5c2
parentb96257b6df86d010bb9b2487c09364699b0bbcea (diff)
downloadgcc-b0fabad3944585b9982992ce8256c7030a0903fa.zip
gcc-b0fabad3944585b9982992ce8256c7030a0903fa.tar.gz
gcc-b0fabad3944585b9982992ce8256c7030a0903fa.tar.bz2
pa.c (emit_move_sequence): Rewrite code to handle arithmetic involving plabels.
* pa.c (emit_move_sequence): Rewrite code to handle arithmetic involving plabels. From-SVN: r14231
-rw-r--r--gcc/config/pa/pa.c63
1 files changed, 38 insertions, 25 deletions
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index 75c1021..2f9ea94 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -1242,27 +1242,51 @@ emit_move_sequence (operands, mode, scratch_reg)
}
if (symbolic_operand (operand1, mode))
{
- rtx const_part = NULL;
-
/* Argh. The assembler and linker can't handle arithmetic
- involving plabels. We'll have to split up operand1 here
- if it's a function label involved in an arithmetic
- expression. Luckily, this only happens with addition
- of constants to plabels, which simplifies the test.
+ involving plabels.
- We add the constant back in just before returning to
- our caller. */
+ So we force the plabel into memory, load operand0 from
+ the memory location, then add in the constant part. */
if (GET_CODE (operand1) == CONST
&& GET_CODE (XEXP (operand1, 0)) == PLUS
&& function_label_operand (XEXP (XEXP (operand1, 0), 0), Pmode))
{
+ rtx scratch_reg, temp, const_part;
+
+ /* Figure out what (if any) scratch register to use. */
+ if (reload_in_progress || reload_completed)
+ scratch_reg = scratch_reg ? scratch_reg : operand0;
+ else if (flag_pic)
+ scratch_reg = gen_reg_rtx (Pmode);
+
/* Save away the constant part of the expression. */
const_part = XEXP (XEXP (operand1, 0), 1);
if (GET_CODE (const_part) != CONST_INT)
abort ();
- /* Set operand1 to just the SYMBOL_REF. */
- operand1 = XEXP (XEXP (operand1, 0), 0);
+ /* Force the function label into memory. */
+ temp = force_const_mem (mode, XEXP (XEXP (operand1, 0), 0));
+
+ /* Get the address of the memory location. PIC-ify it if
+ necessary. */
+ temp = XEXP (temp, 0);
+ if (flag_pic)
+ temp = legitimize_pic_address (temp, mode, scratch_reg);
+
+ /* Put the address of the memory location into our destination
+ register. */
+ operands[1] = temp;
+ emit_move_sequence (operands, mode, scratch_reg);
+
+ /* Now load from the memory location into our destination
+ register. */
+ operands[1] = gen_rtx (MEM, Pmode, operands[0]);
+ emit_move_sequence (operands, mode, scratch_reg);
+
+ /* And add back in the constant part. */
+ expand_inc (operand0, const_part);
+
+ return 1;
}
if (flag_pic)
@@ -1274,17 +1298,10 @@ emit_move_sequence (operands, mode, scratch_reg)
else
temp = gen_reg_rtx (Pmode);
- /* If operand1 is a function label, then we've got to
- force it to memory, then load op0 from memory. */
- if (function_label_operand (operand1, mode))
- {
- operands[1] = force_const_mem (mode, operand1);
- emit_move_sequence (operands, mode, temp);
- }
- /* Likewise for (const (plus (symbol) (const_int))) when
- generating pic code during or after reload and const_int
- will not fit in 14 bits. */
- else if (GET_CODE (operand1) == CONST
+ /* (const (plus (symbol) (const_int))) must be forced to
+ memory during/after reload if the const_int will not fit
+ in 14 bits. */
+ if (GET_CODE (operand1) == CONST
&& GET_CODE (XEXP (operand1, 0)) == PLUS
&& GET_CODE (XEXP (XEXP (operand1, 0), 1)) == CONST_INT
&& !INT_14_BITS (XEXP (XEXP (operand1, 0), 1))
@@ -1336,10 +1353,6 @@ emit_move_sequence (operands, mode, scratch_reg)
emit_insn (set);
}
-
- /* Add back in the constant part if needed. */
- if (const_part != NULL)
- expand_inc (operand0, const_part);
return 1;
}
else if (GET_CODE (operand1) != CONST_INT