Commit b0fabad3 by Jeff Law

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
parent b96257b6
...@@ -1242,27 +1242,51 @@ emit_move_sequence (operands, mode, scratch_reg) ...@@ -1242,27 +1242,51 @@ emit_move_sequence (operands, mode, scratch_reg)
} }
if (symbolic_operand (operand1, mode)) if (symbolic_operand (operand1, mode))
{ {
rtx const_part = NULL;
/* Argh. The assembler and linker can't handle arithmetic /* Argh. The assembler and linker can't handle arithmetic
involving plabels. We'll have to split up operand1 here involving plabels.
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.
We add the constant back in just before returning to So we force the plabel into memory, load operand0 from
our caller. */ the memory location, then add in the constant part. */
if (GET_CODE (operand1) == CONST if (GET_CODE (operand1) == CONST
&& GET_CODE (XEXP (operand1, 0)) == PLUS && GET_CODE (XEXP (operand1, 0)) == PLUS
&& function_label_operand (XEXP (XEXP (operand1, 0), 0), Pmode)) && 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. */ /* Save away the constant part of the expression. */
const_part = XEXP (XEXP (operand1, 0), 1); const_part = XEXP (XEXP (operand1, 0), 1);
if (GET_CODE (const_part) != CONST_INT) if (GET_CODE (const_part) != CONST_INT)
abort (); abort ();
/* Set operand1 to just the SYMBOL_REF. */ /* Force the function label into memory. */
operand1 = XEXP (XEXP (operand1, 0), 0); 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) if (flag_pic)
...@@ -1274,17 +1298,10 @@ emit_move_sequence (operands, mode, scratch_reg) ...@@ -1274,17 +1298,10 @@ emit_move_sequence (operands, mode, scratch_reg)
else else
temp = gen_reg_rtx (Pmode); temp = gen_reg_rtx (Pmode);
/* If operand1 is a function label, then we've got to /* (const (plus (symbol) (const_int))) must be forced to
force it to memory, then load op0 from memory. */ memory during/after reload if the const_int will not fit
if (function_label_operand (operand1, mode)) in 14 bits. */
{ if (GET_CODE (operand1) == CONST
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
&& GET_CODE (XEXP (operand1, 0)) == PLUS && GET_CODE (XEXP (operand1, 0)) == PLUS
&& GET_CODE (XEXP (XEXP (operand1, 0), 1)) == CONST_INT && GET_CODE (XEXP (XEXP (operand1, 0), 1)) == CONST_INT
&& !INT_14_BITS (XEXP (XEXP (operand1, 0), 1)) && !INT_14_BITS (XEXP (XEXP (operand1, 0), 1))
...@@ -1336,10 +1353,6 @@ emit_move_sequence (operands, mode, scratch_reg) ...@@ -1336,10 +1353,6 @@ emit_move_sequence (operands, mode, scratch_reg)
emit_insn (set); emit_insn (set);
} }
/* Add back in the constant part if needed. */
if (const_part != NULL)
expand_inc (operand0, const_part);
return 1; return 1;
} }
else if (GET_CODE (operand1) != CONST_INT else if (GET_CODE (operand1) != CONST_INT
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment