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)
}
/* 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. */
int
......@@ -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)
......
......@@ -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 ();
......
......@@ -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
......
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