From: Michael Meissner Date: Wed, 10 Jul 1996 19:12:59 +0000 (+0000) Subject: Use integer ops to load SF constants for software floating point; fix up software... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c4c4037309a400397313e01b3fd7c38ae2264acf;p=gcc.git Use integer ops to load SF constants for software floating point; fix up software floating constants in general From-SVN: r12421 --- diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 408661c1dbc..7b7896001b4 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -372,6 +372,24 @@ rs6000_immed_double_const (i0, i1, mode) return immed_double_const (i0, i1, mode); } + +/* Return the GOT register, creating it if needed. */ + +struct rtx_def * +rs6000_got_register (value) + rtx value; +{ + if (!pic_offset_table_rtx) + { + if (reload_in_progress || reload_completed) + fatal_insn ("internal error -- needed new GOT register during reload phase to load:", value); + + pic_offset_table_rtx = gen_reg_rtx (SImode); + } + + return pic_offset_table_rtx; +} + /* Return non-zero if this function is known to have a null epilogue. */ @@ -614,7 +632,7 @@ num_insns_constant (op, mode) rtx op; enum machine_mode mode; { - if (mode != SImode && mode != DImode) + if (mode != SImode && mode != DImode && mode != SFmode && mode != DFmode) abort (); if (GET_CODE (op) == CONST_INT) diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 7626eff03c5..f291bae62a3 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -1029,12 +1029,13 @@ enum reg_class We flag for special constants when we can copy the constant into a general register in two insns for DF/DI and one insn for SF. - 'H' is used for DI constants that take 3 insns. */ + 'H' is used for DI/DF constants that take 3 insns. */ #define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \ - ((C) == 'G' ? easy_fp_constant (VALUE, GET_MODE (VALUE)) : \ - (C) == 'H' ? (num_insns_constant (VALUE, DImode) == 3) : \ - 0) + ( (C) == 'G' ? (num_insns_constant (VALUE, GET_MODE (VALUE)) \ + == ((GET_MODE (VALUE) == SFmode) ? 1 : 2)) \ + : (C) == 'H' ? (num_insns_constant (VALUE, GET_MODE (VALUE)) == 3) \ + : 0) /* Optional extra constraints for this machine. @@ -3018,6 +3019,7 @@ extern void rs6000_override_options (); extern void rs6000_file_start (); extern struct rtx_def *rs6000_float_const (); extern struct rtx_def *rs6000_immed_double_const (); +extern struct rtx_def *rs6000_got_register (); extern int direct_return (); extern int any_operand (); extern int short_cint_operand (); diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index c015c3dfcf7..80135d3da06 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -5036,10 +5036,7 @@ "(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) && flag_pic" " { - if (!pic_offset_table_rtx) - pic_offset_table_rtx = gen_reg_rtx (SImode); - - operands[2] = pic_offset_table_rtx; + operands[2] = rs6000_got_register (operands[1]); if (flag_pic > 1) { emit_insn (gen_movsi_got_large (operands[0], operands[1], operands[2])); @@ -5468,7 +5465,7 @@ } } - if (CONSTANT_P (operands[1])) + if (CONSTANT_P (operands[1]) && TARGET_HARD_FLOAT) { operands[1] = force_const_mem (SFmode, operands[1]); if (! memory_address_p (SFmode, XEXP (operands[1], 0)) @@ -5480,9 +5477,9 @@ (define_split [(set (match_operand:SF 0 "gpc_reg_operand" "") - (match_operand:SF 1 "easy_fp_constant" ""))] - "reload_completed && REGNO (operands[0]) <= 31" - [(set (subreg:SI (match_dup 0) 0) (match_dup 2))] + (match_operand:SF 1 "const_double_operand" ""))] + "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], SFmode) <= 1 && REGNO (operands[0]) <= 31" + [(set (match_dup 2) (match_dup 3))] " { long l; @@ -5490,23 +5487,47 @@ REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]); REAL_VALUE_TO_TARGET_SINGLE (rv, l); - operands[2] = GEN_INT(l); + + operands[2] = gen_rtx (SUBREG, SImode, operands[0], 0); + operands[3] = GEN_INT(l); }") -(define_insn "" - [(set (match_operand:SF 0 "fp_reg_or_mem_operand" "=f,f,m") - (match_operand:SF 1 "input_operand" "f,m,f"))] +(define_split + [(set (match_operand:SF 0 "gpc_reg_operand" "") + (match_operand:SF 1 "const_double_operand" ""))] + "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], SFmode) == 2 && REGNO (operands[0]) <= 31" + [(set (match_dup 2) (match_dup 3)) + (set (match_dup 2) (ior:SI (match_dup 2) (match_dup 4)))] + " +{ + long l; + REAL_VALUE_TYPE rv; + + REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]); + REAL_VALUE_TO_TARGET_SINGLE (rv, l); + + operands[2] = gen_rtx (SUBREG, SImode, operands[0], 0); + operands[3] = GEN_INT(l & 0xffff0000); + operands[4] = GEN_INT(l & 0x0000ffff); +}") + +(define_insn "*movsf_hardfloat" + [(set (match_operand:SF 0 "fp_reg_or_mem_operand" "=f,f,m,!r,!r") + (match_operand:SF 1 "input_operand" "f,m,f,G,Fn"))] "(gpc_reg_operand (operands[0], SFmode) || gpc_reg_operand (operands[1], SFmode)) && TARGET_HARD_FLOAT" "@ fmr %0,%1 lfs%U1%X1 %0,%1 - stfs%U0%X0 %1,%0" - [(set_attr "type" "fp,fpload,fpstore")]) + stfs%U0%X0 %1,%0 + # + #" + [(set_attr "type" "fp,fpload,fpstore,*,*") + (set_attr "length" "4,4,4,4,8")]) -(define_insn "" - [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,r,r,r") - (match_operand:SF 1 "input_operand" "r,m,r,I,J,R"))] +(define_insn "*movsf_softfloat" + [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,r") + (match_operand:SF 1 "input_operand" "r,m,r,I,J,R,G,Fn"))] "(gpc_reg_operand (operands[0], SFmode) || gpc_reg_operand (operands[1], SFmode)) && TARGET_SOFT_FLOAT" "@ @@ -5515,8 +5536,11 @@ {st%U0%X0|stw%U0%X0} %1,%0 {lil|li} %0,%1 {liu|lis} %0,%v1 - {cal|la} %0,%1(%*)" - [(set_attr "type" "*,load,store,*,*,*")]) + {cal|la} %0,%1(%*) + # + #" + [(set_attr "type" "*,load,store,*,*,*,*,*") + (set_attr "length" "4,4,4,4,4,4,4,8")]) (define_expand "movdf" @@ -5557,15 +5581,101 @@ (define_split [(set (match_operand:DF 0 "gpc_reg_operand" "") - (match_operand:DF 1 "easy_fp_constant" ""))] - "TARGET_32BIT && reload_completed && REGNO (operands[0]) <= 31" - [(set (match_dup 2) (match_dup 3)) - (set (match_dup 4) (match_dup 5))] + (match_operand:DF 1 "const_int_operand" ""))] + "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DFmode) <= 1 && REGNO (operands[0]) <= 31" + [(set (match_dup 2) (match_dup 4)) + (set (match_dup 3) (match_dup 1))] + " +{ + operands[2] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0); + operands[3] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0); + operands[4] = (INTVAL (operands[1]) & 0x80000000) ? constm1_rtx : const0_rtx; +}") + +(define_split + [(set (match_operand:DF 0 "gpc_reg_operand" "") + (match_operand:DF 1 "const_int_operand" ""))] + "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DFmode) >= 2 && REGNO (operands[0]) <= 31" + [(set (match_dup 3) (match_dup 5)) + (set (match_dup 2) (match_dup 4)) + (set (match_dup 3) (ior:SI (match_dup 3) (match_dup 6)))] + " +{ + HOST_WIDE_INT value = INTVAL (operands[1]); + operands[2] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0); + operands[3] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0); + operands[4] = (value & 0x80000000) ? constm1_rtx : const0_rtx; + operands[5] = GEN_INT (value & 0xffff0000); + operands[6] = GEN_INT (value & 0x0000ffff); +}") + +(define_split + [(set (match_operand:DF 0 "gpc_reg_operand" "") + (match_operand:DF 1 "const_double_operand" ""))] + "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DFmode) <= 2 && REGNO (operands[0]) <= 31" + [(set (match_dup 2) (match_dup 4)) + (set (match_dup 3) (match_dup 5))] + " +{ + operands[2] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0); + operands[3] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0); + operands[4] = GEN_INT (CONST_DOUBLE_HIGH (operands[1])); + operands[5] = GEN_INT (CONST_DOUBLE_LOW (operands[1])); +}") + +(define_split + [(set (match_operand:DF 0 "gpc_reg_operand" "") + (match_operand:DF 1 "const_double_operand" ""))] + "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DFmode) == 3 && REGNO (operands[0]) <= 31" + [(set (match_dup 2) (match_dup 4)) + (set (match_dup 3) (match_dup 5)) + (set (match_dup 2) (ior:SI (match_dup 2) (match_dup 6)))] + " +{ + HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]); + HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]); + rtx high_reg = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0); + rtx low_reg = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0); + + if (((unsigned HOST_WIDE_INT) (low + 0x8000) < 0x10000) + || (low & 0xffff) == 0) + { + operands[2] = high_reg; + operands[3] = low_reg; + operands[4] = GEN_INT (high & 0xffff0000); + operands[5] = GEN_INT (low); + operands[6] = GEN_INT (high & 0x0000ffff); + } + else + { + operands[2] = low_reg; + operands[3] = high_reg; + operands[4] = GEN_INT (low & 0xffff0000); + operands[5] = GEN_INT (high); + operands[6] = GEN_INT (low & 0x0000ffff); + } +}") + +(define_split + [(set (match_operand:DF 0 "gpc_reg_operand" "") + (match_operand:DF 1 "const_double_operand" ""))] + "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DFmode) >= 4 && REGNO (operands[0]) <= 31" + [(set (match_dup 2) (match_dup 4)) + (set (match_dup 3) (match_dup 5)) + (set (match_dup 2) (ior:SI (match_dup 2) (match_dup 6))) + (set (match_dup 3) (ior:SI (match_dup 3) (match_dup 7)))] " -{ operands[2] = operand_subword (operands[0], 0, 0, DFmode); - operands[3] = operand_subword (operands[1], 0, 0, DFmode); - operands[4] = operand_subword (operands[0], 1, 0, DFmode); - operands[5] = operand_subword (operands[1], 1, 0, DFmode); }") +{ + HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]); + HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]); + + operands[2] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0); + operands[3] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0); + operands[4] = GEN_INT (high & 0xffff0000); + operands[5] = GEN_INT (low & 0xffff0000); + operands[6] = GEN_INT (high & 0x0000ffff); + operands[7] = GEN_INT (low & 0x0000ffff); +}") (define_split [(set (match_operand:DF 0 "gpc_reg_operand" "") @@ -5580,9 +5690,9 @@ ;; the constant into an FP register, since it will probably be used there. ;; The "??" is a kludge until we can figure out a more reasonable way ;; of handling these non-offsettable values. -(define_insn "" - [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,o,!r,f,f,m") - (match_operand:DF 1 "input_operand" "r,o,r,G,f,m,f"))] +(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"))] "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && (register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode))" @@ -5611,21 +5721,23 @@ case 2: return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\"; case 3: - return \"#\"; case 4: - return \"fmr %0,%1\"; case 5: - return \"lfd%U1%X1 %0,%1\"; + return \"#\"; case 6: + return \"fmr %0,%1\"; + case 7: + return \"lfd%U1%X1 %0,%1\"; + case 8: return \"stfd%U0%X0 %1,%0\"; } }" - [(set_attr "type" "*,load,store,*,fp,fpload,fpstore") - (set_attr "length" "8,8,8,8,*,*,*")]) + [(set_attr "type" "*,load,store,*,*,*,fp,fpload,fpstore") + (set_attr "length" "8,8,8,8,12,16,*,*,*")]) -(define_insn "" - [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,o,r") - (match_operand:DF 1 "input_operand" "r,o,r,G"))] +(define_insn "*movdf_softfloat32" + [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,o,r,r,r") + (match_operand:DF 1 "input_operand" "r,o,r,G,H,F"))] "! TARGET_POWERPC64 && TARGET_SOFT_FLOAT && (register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode))" @@ -5654,15 +5766,17 @@ case 2: return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\"; case 3: + case 4: + case 5: return \"#\"; } }" - [(set_attr "type" "*,load,store,*") - (set_attr "length" "8,8,8,8")]) + [(set_attr "type" "*,load,store,*,*,*") + (set_attr "length" "8,8,8,8,12,16")]) -(define_insn "" - [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,o,!r,f,f,m") - (match_operand:DF 1 "input_operand" "r,o,r,G,f,m,f"))] +(define_insn "*movdf_hardfloat64" + [(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"))] "TARGET_POWERPC64 && TARGET_HARD_FLOAT && (register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode))" @@ -5671,14 +5785,17 @@ ld%U1%X1 %0,%1 std%U0%X0 %1,%0 # + # + # fmr %0,%1 lfd%U1%X1 %0,%1 stfd%U0%X0 %1,%0" - [(set_attr "type" "*,load,store,*,fp,fpload,fpstore")]) + [(set_attr "type" "*,load,store,*,*,*,fp,fpload,fpstore") + (set_attr "length" "4,4,4,8,12,16,4,4,4")]) -(define_insn "" - [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,o,r") - (match_operand:DF 1 "input_operand" "r,o,r,G"))] +(define_insn "*movdf_softfloat64" + [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,o,r,r,r") + (match_operand:DF 1 "input_operand" "r,o,r,G,H,F"))] "TARGET_POWERPC64 && TARGET_SOFT_FLOAT && (register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode))" @@ -5686,8 +5803,11 @@ mr %0,%1 ld%U1%X1 %0,%1 std%U0%X0 %1,%0 + # + # #" - [(set_attr "type" "*,load,store,*")]) + [(set_attr "type" "*,load,store,*,*,*") + (set_attr "length" "*,*,*,8,12,16")]) ;; Next come the multi-word integer load and store and the load and store ;; multiple insns. @@ -5761,7 +5881,7 @@ } }") -(define_insn "" +(define_insn "*movdi_32" [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,f,f,m,r,r,r,r,r") (match_operand:DI 1 "input_operand" "r,m,r,f,m,f,IJK,n,G,H,F"))] "TARGET_32BIT @@ -5906,7 +6026,7 @@ operands[7] = GEN_INT (low & 0x0000ffff); }") -(define_insn "" +(define_insn "*movdi_64" [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,f,f,m,r,*h,*h") (match_operand:DI 1 "input_operand" "r,m,r,I,J,nF,R,f,m,f,*h,r,0"))] "TARGET_64BIT