From b514dbe5388e8afa98f6e7f49413807aa60038d4 Mon Sep 17 00:00:00 2001 From: David Edelsohn Date: Mon, 21 Jun 1999 04:18:49 +0000 Subject: [PATCH] rs6000.md (movdf_hardfloat32): Use worst case insn length attributes for cases 1 and 2. * rs6000.md (movdf_hardfloat32): Use worst case insn length attributes for cases 1 and 2. * 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: r27629 --- gcc/ChangeLog | 11 ++++++ gcc/config/rs6000/rs6000.c | 26 +++++++++++++ gcc/config/rs6000/rs6000.h | 4 +- gcc/config/rs6000/rs6000.md | 74 ++++++++++++++++++++++++++++++------- 4 files changed, 99 insertions(+), 16 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cc530223d8d9..1baf016c10f6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +Mon Jun 21 05:17:00 1999 David Edelsohn + + * rs6000.md (movdf_hardfloat32): Use worst case insn length + attributes for cases 1 and 2. + + * 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. + Mon Jun 21 04:44:31 1999 Jeffrey A Law (law@cygnus.com) * sparc.h (LEGITIMIZE_RELOAD_ADDRESS): Fix paren error introduced diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 433ef2041058..7e6f6090a421 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -5676,7 +5676,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 2f264ea8075a..c9634451bf4e 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 e8338634d82c..fa6c59187169 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: @@ -6351,7 +6397,7 @@ } }" [(set_attr "type" "*,load,store,*,*,*,fp,fpload,fpstore") - (set_attr "length" "8,8,8,8,12,16,*,*,*")]) + (set_attr "length" "8,16,16,8,12,16,*,*,*")]) (define_insn "*movdf_softfloat32" [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,r,r,r") -- 2.47.2