Commit c4c40373 by Michael Meissner

Use integer ops to load SF constants for software floating point; fix up…

Use integer ops to load SF constants for software floating point; fix up software floating constants in general

From-SVN: r12421
parent a7273471
...@@ -373,6 +373,24 @@ rs6000_immed_double_const (i0, i1, mode) ...@@ -373,6 +373,24 @@ rs6000_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. */ /* Return non-zero if this function is known to have a null epilogue. */
int int
...@@ -614,7 +632,7 @@ num_insns_constant (op, mode) ...@@ -614,7 +632,7 @@ num_insns_constant (op, mode)
rtx op; rtx op;
enum machine_mode mode; enum machine_mode mode;
{ {
if (mode != SImode && mode != DImode) if (mode != SImode && mode != DImode && mode != SFmode && mode != DFmode)
abort (); abort ();
if (GET_CODE (op) == CONST_INT) if (GET_CODE (op) == CONST_INT)
......
...@@ -1029,12 +1029,13 @@ enum reg_class ...@@ -1029,12 +1029,13 @@ enum reg_class
We flag for special constants when we can copy the constant into 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. 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) \ #define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
((C) == 'G' ? easy_fp_constant (VALUE, GET_MODE (VALUE)) : \ ( (C) == 'G' ? (num_insns_constant (VALUE, GET_MODE (VALUE)) \
(C) == 'H' ? (num_insns_constant (VALUE, DImode) == 3) : \ == ((GET_MODE (VALUE) == SFmode) ? 1 : 2)) \
0) : (C) == 'H' ? (num_insns_constant (VALUE, GET_MODE (VALUE)) == 3) \
: 0)
/* Optional extra constraints for this machine. /* Optional extra constraints for this machine.
...@@ -3018,6 +3019,7 @@ extern void rs6000_override_options (); ...@@ -3018,6 +3019,7 @@ extern void rs6000_override_options ();
extern void rs6000_file_start (); extern void rs6000_file_start ();
extern struct rtx_def *rs6000_float_const (); extern struct rtx_def *rs6000_float_const ();
extern struct rtx_def *rs6000_immed_double_const (); extern struct rtx_def *rs6000_immed_double_const ();
extern struct rtx_def *rs6000_got_register ();
extern int direct_return (); extern int direct_return ();
extern int any_operand (); extern int any_operand ();
extern int short_cint_operand (); extern int short_cint_operand ();
......
...@@ -5036,10 +5036,7 @@ ...@@ -5036,10 +5036,7 @@
"(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) && flag_pic" "(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) && flag_pic"
" "
{ {
if (!pic_offset_table_rtx) operands[2] = rs6000_got_register (operands[1]);
pic_offset_table_rtx = gen_reg_rtx (SImode);
operands[2] = pic_offset_table_rtx;
if (flag_pic > 1) if (flag_pic > 1)
{ {
emit_insn (gen_movsi_got_large (operands[0], operands[1], operands[2])); emit_insn (gen_movsi_got_large (operands[0], operands[1], operands[2]));
...@@ -5468,7 +5465,7 @@ ...@@ -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]); operands[1] = force_const_mem (SFmode, operands[1]);
if (! memory_address_p (SFmode, XEXP (operands[1], 0)) if (! memory_address_p (SFmode, XEXP (operands[1], 0))
...@@ -5480,9 +5477,9 @@ ...@@ -5480,9 +5477,9 @@
(define_split (define_split
[(set (match_operand:SF 0 "gpc_reg_operand" "") [(set (match_operand:SF 0 "gpc_reg_operand" "")
(match_operand:SF 1 "easy_fp_constant" ""))] (match_operand:SF 1 "const_double_operand" ""))]
"reload_completed && REGNO (operands[0]) <= 31" "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], SFmode) <= 1 && REGNO (operands[0]) <= 31"
[(set (subreg:SI (match_dup 0) 0) (match_dup 2))] [(set (match_dup 2) (match_dup 3))]
" "
{ {
long l; long l;
...@@ -5490,23 +5487,47 @@ ...@@ -5490,23 +5487,47 @@
REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]); REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
REAL_VALUE_TO_TARGET_SINGLE (rv, l); 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 "" (define_split
[(set (match_operand:SF 0 "fp_reg_or_mem_operand" "=f,f,m") [(set (match_operand:SF 0 "gpc_reg_operand" "")
(match_operand:SF 1 "input_operand" "f,m,f"))] (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[0], SFmode)
|| gpc_reg_operand (operands[1], SFmode)) && TARGET_HARD_FLOAT" || gpc_reg_operand (operands[1], SFmode)) && TARGET_HARD_FLOAT"
"@ "@
fmr %0,%1 fmr %0,%1
lfs%U1%X1 %0,%1 lfs%U1%X1 %0,%1
stfs%U0%X0 %1,%0" stfs%U0%X0 %1,%0
[(set_attr "type" "fp,fpload,fpstore")]) #
#"
[(set_attr "type" "fp,fpload,fpstore,*,*")
(set_attr "length" "4,4,4,4,8")])
(define_insn "" (define_insn "*movsf_softfloat"
[(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,r,r,r") [(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"))] (match_operand:SF 1 "input_operand" "r,m,r,I,J,R,G,Fn"))]
"(gpc_reg_operand (operands[0], SFmode) "(gpc_reg_operand (operands[0], SFmode)
|| gpc_reg_operand (operands[1], SFmode)) && TARGET_SOFT_FLOAT" || gpc_reg_operand (operands[1], SFmode)) && TARGET_SOFT_FLOAT"
"@ "@
...@@ -5515,8 +5536,11 @@ ...@@ -5515,8 +5536,11 @@
{st%U0%X0|stw%U0%X0} %1,%0 {st%U0%X0|stw%U0%X0} %1,%0
{lil|li} %0,%1 {lil|li} %0,%1
{liu|lis} %0,%v1 {liu|lis} %0,%v1
{cal|la} %0,%1(%*)" {cal|la} %0,%1(%*)
[(set_attr "type" "*,load,store,*,*,*")]) #
#"
[(set_attr "type" "*,load,store,*,*,*,*,*")
(set_attr "length" "4,4,4,4,4,4,4,8")])
(define_expand "movdf" (define_expand "movdf"
...@@ -5557,15 +5581,101 @@ ...@@ -5557,15 +5581,101 @@
(define_split (define_split
[(set (match_operand:DF 0 "gpc_reg_operand" "") [(set (match_operand:DF 0 "gpc_reg_operand" "")
(match_operand:DF 1 "easy_fp_constant" ""))] (match_operand:DF 1 "const_int_operand" ""))]
"TARGET_32BIT && reload_completed && REGNO (operands[0]) <= 31" "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DFmode) <= 1 && REGNO (operands[0]) <= 31"
[(set (match_dup 2) (match_dup 3)) [(set (match_dup 2) (match_dup 4))
(set (match_dup 4) (match_dup 5))] (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); HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
operands[4] = operand_subword (operands[0], 1, 0, DFmode); HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
operands[5] = operand_subword (operands[1], 1, 0, DFmode); }")
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 (define_split
[(set (match_operand:DF 0 "gpc_reg_operand" "") [(set (match_operand:DF 0 "gpc_reg_operand" "")
...@@ -5580,9 +5690,9 @@ ...@@ -5580,9 +5690,9 @@
;; the constant into an FP register, since it will probably be used there. ;; 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 ;; The "??" is a kludge until we can figure out a more reasonable way
;; of handling these non-offsettable values. ;; of handling these non-offsettable values.
(define_insn "" (define_insn "*movdf_hardfloat32"
[(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,o,!r,f,f,m") [(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,f,m,f"))] (match_operand:DF 1 "input_operand" "r,o,r,G,H,F,f,m,f"))]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
&& (register_operand (operands[0], DFmode) && (register_operand (operands[0], DFmode)
|| register_operand (operands[1], DFmode))" || register_operand (operands[1], DFmode))"
...@@ -5611,21 +5721,23 @@ ...@@ -5611,21 +5721,23 @@
case 2: case 2:
return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\"; return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
case 3: case 3:
return \"#\";
case 4: case 4:
return \"fmr %0,%1\";
case 5: case 5:
return \"lfd%U1%X1 %0,%1\"; return \"#\";
case 6: case 6:
return \"fmr %0,%1\";
case 7:
return \"lfd%U1%X1 %0,%1\";
case 8:
return \"stfd%U0%X0 %1,%0\"; return \"stfd%U0%X0 %1,%0\";
} }
}" }"
[(set_attr "type" "*,load,store,*,fp,fpload,fpstore") [(set_attr "type" "*,load,store,*,*,*,fp,fpload,fpstore")
(set_attr "length" "8,8,8,8,*,*,*")]) (set_attr "length" "8,8,8,8,12,16,*,*,*")])
(define_insn "" (define_insn "*movdf_softfloat32"
[(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,o,r") [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,o,r,r,r")
(match_operand:DF 1 "input_operand" "r,o,r,G"))] (match_operand:DF 1 "input_operand" "r,o,r,G,H,F"))]
"! TARGET_POWERPC64 && TARGET_SOFT_FLOAT "! TARGET_POWERPC64 && TARGET_SOFT_FLOAT
&& (register_operand (operands[0], DFmode) && (register_operand (operands[0], DFmode)
|| register_operand (operands[1], DFmode))" || register_operand (operands[1], DFmode))"
...@@ -5654,15 +5766,17 @@ ...@@ -5654,15 +5766,17 @@
case 2: case 2:
return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\"; return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
case 3: case 3:
case 4:
case 5:
return \"#\"; return \"#\";
} }
}" }"
[(set_attr "type" "*,load,store,*") [(set_attr "type" "*,load,store,*,*,*")
(set_attr "length" "8,8,8,8")]) (set_attr "length" "8,8,8,8,12,16")])
(define_insn "" (define_insn "*movdf_hardfloat64"
[(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,o,!r,f,f,m") [(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,f,m,f"))] (match_operand:DF 1 "input_operand" "r,o,r,G,H,F,f,m,f"))]
"TARGET_POWERPC64 && TARGET_HARD_FLOAT "TARGET_POWERPC64 && TARGET_HARD_FLOAT
&& (register_operand (operands[0], DFmode) && (register_operand (operands[0], DFmode)
|| register_operand (operands[1], DFmode))" || register_operand (operands[1], DFmode))"
...@@ -5671,14 +5785,17 @@ ...@@ -5671,14 +5785,17 @@
ld%U1%X1 %0,%1 ld%U1%X1 %0,%1
std%U0%X0 %1,%0 std%U0%X0 %1,%0
# #
#
#
fmr %0,%1 fmr %0,%1
lfd%U1%X1 %0,%1 lfd%U1%X1 %0,%1
stfd%U0%X0 %1,%0" 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 "" (define_insn "*movdf_softfloat64"
[(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,o,r") [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,o,r,r,r")
(match_operand:DF 1 "input_operand" "r,o,r,G"))] (match_operand:DF 1 "input_operand" "r,o,r,G,H,F"))]
"TARGET_POWERPC64 && TARGET_SOFT_FLOAT "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
&& (register_operand (operands[0], DFmode) && (register_operand (operands[0], DFmode)
|| register_operand (operands[1], DFmode))" || register_operand (operands[1], DFmode))"
...@@ -5686,8 +5803,11 @@ ...@@ -5686,8 +5803,11 @@
mr %0,%1 mr %0,%1
ld%U1%X1 %0,%1 ld%U1%X1 %0,%1
std%U0%X0 %1,%0 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 ;; Next come the multi-word integer load and store and the load and store
;; multiple insns. ;; multiple insns.
...@@ -5761,7 +5881,7 @@ ...@@ -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") [(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"))] (match_operand:DI 1 "input_operand" "r,m,r,f,m,f,IJK,n,G,H,F"))]
"TARGET_32BIT "TARGET_32BIT
...@@ -5906,7 +6026,7 @@ ...@@ -5906,7 +6026,7 @@
operands[7] = GEN_INT (low & 0x0000ffff); 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") [(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"))] (match_operand:DI 1 "input_operand" "r,m,r,I,J,nF,R,f,m,f,*h,r,0"))]
"TARGET_64BIT "TARGET_64BIT
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment