diff options
Diffstat (limited to 'gcc/config/sparc/sparc.c')
-rw-r--r-- | gcc/config/sparc/sparc.c | 36 |
1 files changed, 22 insertions, 14 deletions
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index b28d1570990..af56ddd8432 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -2188,7 +2188,7 @@ sparc_expand_move (machine_mode mode, rtx *operands) } } - /* Fixup TLS cases. */ + /* Fix up TLS cases. */ if (TARGET_HAVE_TLS && CONSTANT_P (operands[1]) && sparc_tls_referenced_p (operands [1])) @@ -2197,15 +2197,20 @@ sparc_expand_move (machine_mode mode, rtx *operands) return false; } - /* Fixup PIC cases. */ + /* Fix up PIC cases. */ if (flag_pic && CONSTANT_P (operands[1])) { if (pic_address_needs_scratch (operands[1])) operands[1] = sparc_legitimize_pic_address (operands[1], NULL_RTX); /* We cannot use the mov{si,di}_pic_label_ref patterns in all cases. */ - if (GET_CODE (operands[1]) == LABEL_REF - && can_use_mov_pic_label_ref (operands[1])) + if ((GET_CODE (operands[1]) == LABEL_REF + && can_use_mov_pic_label_ref (operands[1])) + || (GET_CODE (operands[1]) == CONST + && GET_CODE (XEXP (operands[1], 0)) == PLUS + && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF + && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT + && can_use_mov_pic_label_ref (XEXP (XEXP (operands[1], 0), 0)))) { if (mode == SImode) { @@ -2215,7 +2220,6 @@ sparc_expand_move (machine_mode mode, rtx *operands) if (mode == DImode) { - gcc_assert (TARGET_ARCH64); emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1])); return true; } @@ -4216,10 +4220,11 @@ int pic_address_needs_scratch (rtx x) { /* An address which is a symbolic plus a non SMALL_INT needs a temp reg. */ - if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS + if (GET_CODE (x) == CONST + && GET_CODE (XEXP (x, 0)) == PLUS && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT - && ! SMALL_INT (XEXP (XEXP (x, 0), 1))) + && !SMALL_INT (XEXP (XEXP (x, 0), 1))) return 1; return 0; @@ -4667,16 +4672,15 @@ sparc_legitimize_tls_address (rtx addr) static rtx sparc_legitimize_pic_address (rtx orig, rtx reg) { - bool gotdata_op = false; - if (GET_CODE (orig) == SYMBOL_REF /* See the comment in sparc_expand_move. */ || (GET_CODE (orig) == LABEL_REF && !can_use_mov_pic_label_ref (orig))) { + bool gotdata_op = false; rtx pic_ref, address; rtx_insn *insn; - if (reg == 0) + if (!reg) { gcc_assert (can_create_pseudo_p ()); reg = gen_reg_rtx (Pmode); @@ -4687,8 +4691,7 @@ sparc_legitimize_pic_address (rtx orig, rtx reg) /* If not during reload, allocate another temp reg here for loading in the address, so that these instructions can be optimized properly. */ - rtx temp_reg = (! can_create_pseudo_p () - ? reg : gen_reg_rtx (Pmode)); + rtx temp_reg = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : reg; /* Must put the SYMBOL_REF inside an UNSPEC here so that cse won't get confused into thinking that these two instructions @@ -4704,6 +4707,7 @@ sparc_legitimize_pic_address (rtx orig, rtx reg) emit_insn (gen_movsi_high_pic (temp_reg, orig)); emit_insn (gen_movsi_lo_sum_pic (temp_reg, temp_reg, orig)); } + address = temp_reg; gotdata_op = true; } @@ -4744,7 +4748,7 @@ sparc_legitimize_pic_address (rtx orig, rtx reg) && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx) return orig; - if (reg == 0) + if (!reg) { gcc_assert (can_create_pseudo_p ()); reg = gen_reg_rtx (Pmode); @@ -4853,7 +4857,11 @@ sparc_delegitimize_address (rtx x) && XINT (XEXP (XEXP (x, 1), 1), 1) == UNSPEC_MOVE_PIC_LABEL) { x = XVECEXP (XEXP (XEXP (x, 1), 1), 0, 0); - gcc_assert (GET_CODE (x) == LABEL_REF); + gcc_assert (GET_CODE (x) == LABEL_REF + || (GET_CODE (x) == CONST + && GET_CODE (XEXP (x, 0)) == PLUS + && GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF + && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)); } return x; |