From: David Edelsohn Date: Sat, 19 Jun 1999 00:04:59 +0000 (+0000) Subject: rs6000.c (find_addr_reg): New function. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=000034eb46b0c429f01982212bf4879de0fec964;p=gcc.git rs6000.c (find_addr_reg): New function. * rs6000.c (find_addr_reg): New function. * rs6000.h (find_addr_reg): Declare. (offsettable_addr_operand): Delete. * rs6000.md (movdf_hardfloat32): Handle non-offsettable loads from and stores to GPRs. From-SVN: r27602 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5efb552b16b..46f9d17617e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +Fri Jun 18 23:47:06 1999 David Edelsohn + + * rs6000.c (find_addr_reg): New function. + * rs6000.h (find_addr_reg): Declare. + (offsettable_addr_operand): Delete. + * rs6000.md (movdf_hardfloat32): Handle non-offsettable loads + from and stores to GPRs. + Fri Jun 18 15:44:18 1999 Richard Henderson * alpha.c (alpha_expand_block_move): Use get_insns rather than diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index d22e4e76c10..7d6faf5cb6c 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -5681,7 +5681,33 @@ rs6000_encode_section_info (decl) } #endif /* USING_SVR4_H */ + +/* Return a REG that occurs in ADDR with coefficient 1. + ADDR can be effectively incremented by incrementing REG. */ + +struct rtx_def * +find_addr_reg (addr) + rtx addr; +{ + while (GET_CODE (addr) == PLUS) + { + if (GET_CODE (XEXP (addr, 0)) == REG) + addr = XEXP (addr, 0); + else if (GET_CODE (XEXP (addr, 1)) == REG) + addr = XEXP (addr, 1); + else if (CONSTANT_P (XEXP (addr, 0))) + addr = XEXP (addr, 1); + else if (CONSTANT_P (XEXP (addr, 1))) + addr = XEXP (addr, 0); + else + abort (); + } + if (GET_CODE (addr) == REG) + return addr; + abort (); +} + void rs6000_fatal_bad_address (op) rtx op; diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 08ac9fd2245..4e221314e42 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -3224,13 +3224,13 @@ extern int flag_expensive_optimizations; extern int frame_pointer_needed; /* Declare functions in rs6000.c */ -extern int offsettable_mem_operand (); extern void optimization_options (); extern void output_options (); extern void rs6000_override_options (); extern void rs6000_file_start (); extern struct rtx_def *rs6000_float_const (); extern struct rtx_def *rs6000_got_register (); +extern struct rtx_def *find_addr_reg(); extern int direct_return (); extern int get_issue_rate (); extern int any_operand (); @@ -3249,7 +3249,7 @@ extern int got_no_const_operand (); extern int num_insns_constant (); extern int easy_fp_constant (); extern int volatile_mem_operand (); -extern int offsettable_addr_operand (); +extern int offsettable_mem_operand (); extern int mem_or_easy_const_operand (); extern int add_operand (); extern int non_add_cint_operand (); diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index e8338634d82..4286d89ccc0 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -6307,8 +6307,8 @@ ;; The "??" is a kludge until we can figure out a more reasonable way ;; of handling these non-offsettable values. (define_insn "*movdf_hardfloat32" - [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,o,!r,!r,!r,f,f,m") - (match_operand:DF 1 "input_operand" "r,o,r,G,H,F,f,m,f"))] + [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,m,!r,!r,!r,f,f,m") + (match_operand:DF 1 "input_operand" "r,m,r,G,H,F,f,m,f"))] "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && (gpc_reg_operand (operands[0], DFmode) || gpc_reg_operand (operands[1], DFmode))" @@ -6320,24 +6320,70 @@ abort (); case 0: /* We normally copy the low-numbered register first. However, if - the first register operand 0 is the same as the second register of - operand 1, we must copy in the opposite order. */ + the first register operand 0 is the same as the second register + of operand 1, we must copy in the opposite order. */ if (REGNO (operands[0]) == REGNO (operands[1]) + 1) return \"mr %L0,%L1\;mr %0,%1\"; else return \"mr %0,%1\;mr %L0,%L1\"; case 1: - /* If the low-address word is used in the address, we must load it - last. Otherwise, load it first. Note that we cannot have - auto-increment in that case since the address register is known to be - dead. */ - if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1, - operands [1], 0)) - return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\"; + if (offsettable_memref_p (operands[1])) + { + /* If the low-address word is used in the address, we must load + it last. Otherwise, load it first. Note that we cannot have + auto-increment in that case since the address register is + known to be dead. */ + if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1, + operands[1], 0)) + return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\"; + else + return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\"; + } else - return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\"; + { + rtx addreg; + + if (GET_CODE (XEXP (operands[1], 0)) == PRE_INC + || GET_CODE (XEXP (operands[1], 0)) == PRE_DEC) + abort (); + + addreg = find_addr_reg (XEXP (operands[1], 0)); + if (refers_to_regno_p (REGNO (operands[0]), + REGNO (operands[0]) + 1, + operands[1], 0)) + { + output_asm_insn (\"{cal|la} %0,4(%0)\", &addreg); + output_asm_insn (\"{lx|lwzx} %L0,%1\", operands); + output_asm_insn (\"{cal|la} %0,-4(%0)\", &addreg); + return \"{lx|lwzx} %0,%1\"; + } + else + { + output_asm_insn (\"{lx|lwzx} %0,%1\", operands); + output_asm_insn (\"{cal|la} %0,4(%0)\", &addreg); + output_asm_insn (\"{lx|lwzx} %L0,%1\", operands); + output_asm_insn (\"{cal|la} %0,-4(%0)\", &addreg); + return \"\"; + } + } case 2: - return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\"; + if (offsettable_memref_p (operands[0])) + return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\"; + else + { + rtx addreg; + + if (GET_CODE (XEXP (operands[1], 0)) == PRE_INC + || GET_CODE (XEXP (operands[1], 0)) == PRE_DEC) + abort (); + + addreg = find_addr_reg (XEXP (operands[0], 0)); + output_asm_insn (\"{stx|stwx} %1,%0\", operands); + output_asm_insn (\"{cal|la} %0,4(%0)\", &addreg); + output_asm_insn (\"{stx|stwx} %L1,%0\", operands); + output_asm_insn (\"{cal|la} %0,-4(%0)\", &addreg); + return \"\"; + } case 3: case 4: case 5: