diff options
author | danglin <danglin@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-12-19 01:50:00 +0000 |
---|---|---|
committer | danglin <danglin@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-12-19 01:50:00 +0000 |
commit | 5ab11d5e9d155358a1bfbef101848ea51e90e079 (patch) | |
tree | 2a272a8ca5c296f15d99a4fd7bbb5ad03763623d /gcc/config/pa | |
parent | ec358058e4491135a3bd9aba8c76092e5e3105e0 (diff) | |
download | gcc-5ab11d5e9d155358a1bfbef101848ea51e90e079.tar.gz |
PR target/68729
* config/pa/pa.c (pa_emit_move_sequence): Reorganize handling of
floating-point reloads. Only reload operands that are not valid
floating-point memory operands.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@231845 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/pa')
-rw-r--r-- | gcc/config/pa/pa.c | 106 |
1 files changed, 61 insertions, 45 deletions
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index 50424c769b7..1d2227228d2 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -1688,31 +1688,39 @@ pa_emit_move_sequence (rtx *operands, machine_mode mode, rtx scratch_reg) || (GET_CODE (operand1) == SUBREG && MEM_P (XEXP (operand1, 0))))) { - if (GET_CODE (operand1) == SUBREG) - operand1 = XEXP (operand1, 0); + rtx op1 = operand1; - /* SCRATCH_REG will hold an address and maybe the actual data. We want - it in WORD_MODE regardless of what mode it was originally given - to us. */ - scratch_reg = force_mode (word_mode, scratch_reg); + if (GET_CODE (op1) == SUBREG) + op1 = XEXP (op1, 0); - /* D might not fit in 14 bits either; for such cases load D into - scratch reg. */ - if (reg_plus_base_memory_operand (operand1, GET_MODE (operand1)) - && !INT_14_BITS (XEXP (XEXP (operand1, 0), 1))) + if (reg_plus_base_memory_operand (op1, GET_MODE (op1)) + && !(TARGET_PA_20 + && !TARGET_ELF32 + && INT_14_BITS (XEXP (XEXP (op1, 0), 1))) + && !INT_5_BITS (XEXP (XEXP (op1, 0), 1))) { - emit_move_insn (scratch_reg, XEXP (XEXP (operand1, 0), 1)); - emit_move_insn (scratch_reg, - gen_rtx_fmt_ee (GET_CODE (XEXP (operand1, 0)), - Pmode, - XEXP (XEXP (operand1, 0), 0), - scratch_reg)); + /* SCRATCH_REG will hold an address and maybe the actual data. + We want it in WORD_MODE regardless of what mode it was + originally given to us. */ + scratch_reg = force_mode (word_mode, scratch_reg); + + /* D might not fit in 14 bits either; for such cases load D into + scratch reg. */ + if (!INT_14_BITS (XEXP (XEXP (op1, 0), 1))) + { + emit_move_insn (scratch_reg, XEXP (XEXP (op1, 0), 1)); + emit_move_insn (scratch_reg, + gen_rtx_fmt_ee (GET_CODE (XEXP (op1, 0)), + Pmode, + XEXP (XEXP (op1, 0), 0), + scratch_reg)); + } + else + emit_move_insn (scratch_reg, XEXP (op1, 0)); + emit_insn (gen_rtx_SET (operand0, + replace_equiv_address (op1, scratch_reg))); + return 1; } - else - emit_move_insn (scratch_reg, XEXP (operand1, 0)); - emit_insn (gen_rtx_SET (operand0, - replace_equiv_address (operand1, scratch_reg))); - return 1; } else if (scratch_reg && FP_REG_P (operand1) @@ -1720,32 +1728,39 @@ pa_emit_move_sequence (rtx *operands, machine_mode mode, rtx scratch_reg) || (GET_CODE (operand0) == SUBREG && MEM_P (XEXP (operand0, 0))))) { - if (GET_CODE (operand0) == SUBREG) - operand0 = XEXP (operand0, 0); + rtx op0 = operand0; - /* SCRATCH_REG will hold an address and maybe the actual data. We want - it in WORD_MODE regardless of what mode it was originally given - to us. */ - scratch_reg = force_mode (word_mode, scratch_reg); + if (GET_CODE (op0) == SUBREG) + op0 = XEXP (op0, 0); - /* D might not fit in 14 bits either; for such cases load D into - scratch reg. */ - if (reg_plus_base_memory_operand (operand0, GET_MODE (operand0)) - && !INT_14_BITS (XEXP (XEXP (operand0, 0), 1))) + if (reg_plus_base_memory_operand (op0, GET_MODE (op0)) + && !(TARGET_PA_20 + && !TARGET_ELF32 + && INT_14_BITS (XEXP (XEXP (op0, 0), 1))) + && !INT_5_BITS (XEXP (XEXP (op0, 0), 1))) { - emit_move_insn (scratch_reg, XEXP (XEXP (operand0, 0), 1)); - emit_move_insn (scratch_reg, gen_rtx_fmt_ee (GET_CODE (XEXP (operand0, - 0)), - Pmode, - XEXP (XEXP (operand0, 0), - 0), - scratch_reg)); + /* SCRATCH_REG will hold an address and maybe the actual data. + We want it in WORD_MODE regardless of what mode it was + originally given to us. */ + scratch_reg = force_mode (word_mode, scratch_reg); + + /* D might not fit in 14 bits either; for such cases load D into + scratch reg. */ + if (!INT_14_BITS (XEXP (XEXP (op0, 0), 1))) + { + emit_move_insn (scratch_reg, XEXP (XEXP (op0, 0), 1)); + emit_move_insn (scratch_reg, + gen_rtx_fmt_ee (GET_CODE (XEXP (op0, 0)), + Pmode, + XEXP (XEXP (op0, 0), 0), + scratch_reg)); + } + else + emit_move_insn (scratch_reg, XEXP (op0, 0)); + emit_insn (gen_rtx_SET (replace_equiv_address (op0, scratch_reg), + operand1)); + return 1; } - else - emit_move_insn (scratch_reg, XEXP (operand0, 0)); - emit_insn (gen_rtx_SET (replace_equiv_address (operand0, scratch_reg), - operand1)); - return 1; } /* Handle secondary reloads for loads of FP registers from constant expressions by forcing the constant into memory. For the most part, @@ -1754,7 +1769,7 @@ pa_emit_move_sequence (rtx *operands, machine_mode mode, rtx scratch_reg) Use scratch_reg to hold the address of the memory location. */ else if (scratch_reg && CONSTANT_P (operand1) - && fp_reg_operand (operand0, mode)) + && FP_REG_P (operand0)) { rtx const_mem, xoperands[2]; @@ -1830,8 +1845,9 @@ pa_emit_move_sequence (rtx *operands, machine_mode mode, rtx scratch_reg) emit_move_insn (operand0, scratch_reg); return 1; } + /* Handle the most common case: storing into a register. */ - else if (register_operand (operand0, mode)) + if (register_operand (operand0, mode)) { /* Legitimize TLS symbol references. This happens for references that aren't a legitimate constant. */ |