Commit 8d33eae8 by Thomas Preud'homme Committed by Thomas Preud'homme

ARM] Improve robustness of -mslow-flash-data

Current code to handle -mslow-flash-data in machine description files
suffers from a number of issues which this patch fixes:

1) The insn_and_split in vfp.md to load a generic floating-point
constant via GPR first and move it to VFP register are guarded by
!reload_completed which is forbidden explicitely in the GCC internals
documentation section 17.2 point 3;

2) A number of testcase in the testsuite ICEs under -mslow-flash-data
when targeting the hardfloat ABI [1];

3) Instructions performing load from literal pool are not disabled.

These problems are addressed by 2 separate actions:

1) Making the splitters take a clobber and changing the expanders
accordingly to generate a mov with clobber in cases where a literal
pool would be used. The splitter can thus be enabled after reload since
it does not call gen_reg_rtx anymore;

2) Adding new predicates and constraints to disable literal pool loads
in existing instructions when -mslow-flash-data is in effect.

The patch also rework the splitter for DFmode slightly to generate an
intermediate DI load instead of 2 intermediate SI loads, thus relying on
the existing DI splitters instead of redoing their job. At last, the
patch adds some missing arm_fp_ok effective target to some of the
slow-flash-data testcases.

[1]
c-c++-common/Wunused-var-3.c
gcc.c-torture/compile/pr72771.c
gcc.c-torture/compile/vector-5.c
gcc.c-torture/compile/vector-6.c
gcc.c-torture/execute/20030914-1.c
gcc.c-torture/execute/20050316-1.c
gcc.c-torture/execute/pr59643.c
gcc.dg/builtin-tgmath-1.c
gcc.dg/debug/pr55730.c
gcc.dg/graphite/interchange-7.c
gcc.dg/pr56890-2.c
gcc.dg/pr68474.c
gcc.dg/pr80286.c
gcc.dg/torture/pr35227.c
gcc.dg/torture/pr65077.c
gcc.dg/torture/pr86363.c
g++.dg/torture/pr81112.C
g++.dg/torture/pr82985.C
g++.dg/warn/Wunused-var-7.C
and a lot more in libstdc++ in special_functions/*_comp_ellint_* and
special_functions/*_ellint_* directories.

2018-12-14  Thomas Preud'homme  <thomas.preudhomme@arm.com>

    gcc/
    * config/arm/arm.md (arm_movdi): Split if -mslow-flash-data and
    source is a constant that would be loaded by literal pool.
    (movsf expander): Generate a no_literal_pool_sf_immediate insn if
    -mslow-flash-data is present, targeting hardfloat ABI and source is a
    float constant that cannot be loaded via vmov.
    (movdf expander): Likewise but generate a no_literal_pool_df_immediate
    insn.
    (arm_movsf_soft_insn): Split if -mslow-flash-data and source is a
    float constant that would be loaded by literal pool.
    (softfloat constant movsf splitter): Splitter for the above case.
    (movdf_soft_insn): Split if -mslow-flash-data and source is a float
    constant that would be loaded by literal pool.
    (softfloat constant movdf splitter): Splitter for the above case.
    * config/arm/constraints.md (Pz): Document existing constraint.
    (Ha): Define constraint.
    (Tu): Likewise.
    * config/arm/predicates.md (hard_sf_operand): New predicate.
    (hard_df_operand): Likewise.
    * config/arm/thumb2.md (thumb2_movsi_insn): Split if
    -mslow-flash-data and constant would be loaded by literal pool.
    * constant/arm/vfp.md (thumb2_movsi_vfp): Likewise and disable constant
    load in VFP register.
    (movdi_vfp): Likewise.
    (thumb2_movsf_vfp): Use hard_sf_operand as predicate for source to
    prevent match for a constant load if -mslow-flash-data and constant
    cannot be loaded via vmov.  Adapt constraint accordingly by
    using Ha instead of E for generic floating-point constant load.
    (thumb2_movdf_vfp): Likewise using hard_df_operand predicate instead.
    (no_literal_pool_df_immediate): Add a clobber to use as the
    intermediate general purpose register and also enable it after reload
    but disable it constant is a valid FP constant.  Add constraints and
    generate a DI intermediate load rather than 2 SI loads.
    (no_literal_pool_sf_immediate): Add a clobber to use as the
    intermediate general purpose register and also enable it after
    reload.

2018-11-14  Thomas Preud'homme  <thomas.preudhomme@arm.com>

    gcc/testsuite/
    * gcc.target/arm/thumb2-slow-flash-data-2.c: Require arm_fp_ok
    effective target.
    * gcc.target/arm/thumb2-slow-flash-data-3.c: Likewise.
    * gcc.target/arm/thumb2-slow-flash-data-4.c: Likewise.
    * gcc.target/arm/thumb2-slow-flash-data-5.c: Likewise.

From-SVN: r267141
parent b2d02c49
2018-12-14 Thomas Preud'homme <thomas.preudhomme@arm.com>
* config/arm/arm.md (arm_movdi): Split if -mslow-flash-data and
source is a constant that would be loaded by literal pool.
(movsf expander): Generate a no_literal_pool_sf_immediate insn if
-mslow-flash-data is present, targeting hardfloat ABI and source is a
float constant that cannot be loaded via vmov.
(movdf expander): Likewise but generate a no_literal_pool_df_immediate
insn.
(arm_movsf_soft_insn): Split if -mslow-flash-data and source is a
float constant that would be loaded by literal pool.
(softfloat constant movsf splitter): Splitter for the above case.
(movdf_soft_insn): Split if -mslow-flash-data and source is a float
constant that would be loaded by literal pool.
(softfloat constant movdf splitter): Splitter for the above case.
* config/arm/constraints.md (Pz): Document existing constraint.
(Ha): Define constraint.
(Tu): Likewise.
* config/arm/predicates.md (hard_sf_operand): New predicate.
(hard_df_operand): Likewise.
* config/arm/thumb2.md (thumb2_movsi_insn): Split if
-mslow-flash-data and constant would be loaded by literal pool.
* constant/arm/vfp.md (thumb2_movsi_vfp): Likewise and disable constant
load in VFP register.
(movdi_vfp): Likewise.
(thumb2_movsf_vfp): Use hard_sf_operand as predicate for source to
prevent match for a constant load if -mslow-flash-data and constant
cannot be loaded via vmov. Adapt constraint accordingly by
using Ha instead of E for generic floating-point constant load.
(thumb2_movdf_vfp): Likewise using hard_df_operand predicate instead.
(no_literal_pool_df_immediate): Add a clobber to use as the
intermediate general purpose register and also enable it after reload
but disable it constant is a valid FP constant. Add constraints and
generate a DI intermediate load rather than 2 SI loads.
(no_literal_pool_sf_immediate): Add a clobber to use as the
intermediate general purpose register and also enable it after
reload.
2018-12-14 Uros Bizjak <ubizjak@gmail.com> 2018-12-14 Uros Bizjak <ubizjak@gmail.com>
PR target/88474 PR target/88474
...@@ -5831,6 +5831,11 @@ ...@@ -5831,6 +5831,11 @@
case 1: case 1:
case 2: case 2:
return \"#\"; return \"#\";
case 3:
/* Cannot load it directly, split to load it via MOV / MOVT. */
if (!MEM_P (operands[1]) && arm_disable_literal_pool)
return \"#\";
/* Fall through. */
default: default:
return output_move_double (operands, true, NULL); return output_move_double (operands, true, NULL);
} }
...@@ -6940,6 +6945,20 @@ ...@@ -6940,6 +6945,20 @@
operands[1] = force_reg (SFmode, operands[1]); operands[1] = force_reg (SFmode, operands[1]);
} }
} }
/* Cannot load it directly, generate a load with clobber so that it can be
loaded via GPR with MOV / MOVT. */
if (arm_disable_literal_pool
&& (REG_P (operands[0]) || SUBREG_P (operands[0]))
&& CONST_DOUBLE_P (operands[1])
&& TARGET_HARD_FLOAT
&& !vfp3_const_double_rtx (operands[1]))
{
rtx clobreg = gen_reg_rtx (SFmode);
emit_insn (gen_no_literal_pool_sf_immediate (operands[0], operands[1],
clobreg));
DONE;
}
" "
) )
...@@ -6967,10 +6986,19 @@ ...@@ -6967,10 +6986,19 @@
&& TARGET_SOFT_FLOAT && TARGET_SOFT_FLOAT
&& (!MEM_P (operands[0]) && (!MEM_P (operands[0])
|| register_operand (operands[1], SFmode))" || register_operand (operands[1], SFmode))"
"@ {
mov%?\\t%0, %1 switch (which_alternative)
ldr%?\\t%0, %1\\t%@ float {
str%?\\t%1, %0\\t%@ float" case 0: return \"mov%?\\t%0, %1\";
case 1:
/* Cannot load it directly, split to load it via MOV / MOVT. */
if (!MEM_P (operands[1]) && arm_disable_literal_pool)
return \"#\";
return \"ldr%?\\t%0, %1\\t%@ float\";
case 2: return \"str%?\\t%1, %0\\t%@ float\";
default: gcc_unreachable ();
}
}
[(set_attr "predicable" "yes") [(set_attr "predicable" "yes")
(set_attr "type" "mov_reg,load_4,store_4") (set_attr "type" "mov_reg,load_4,store_4")
(set_attr "arm_pool_range" "*,4096,*") (set_attr "arm_pool_range" "*,4096,*")
...@@ -6979,6 +7007,21 @@ ...@@ -6979,6 +7007,21 @@
(set_attr "thumb2_neg_pool_range" "*,0,*")] (set_attr "thumb2_neg_pool_range" "*,0,*")]
) )
;; Splitter for the above.
(define_split
[(set (match_operand:SF 0 "s_register_operand")
(match_operand:SF 1 "const_double_operand"))]
"arm_disable_literal_pool && TARGET_SOFT_FLOAT"
[(const_int 0)]
{
long buf;
real_to_target (&buf, CONST_DOUBLE_REAL_VALUE (operands[1]), SFmode);
rtx cst = gen_int_mode (buf, SImode);
emit_move_insn (simplify_gen_subreg (SImode, operands[0], SFmode, 0), cst);
DONE;
}
)
(define_expand "movdf" (define_expand "movdf"
[(set (match_operand:DF 0 "general_operand" "") [(set (match_operand:DF 0 "general_operand" "")
(match_operand:DF 1 "general_operand" ""))] (match_operand:DF 1 "general_operand" ""))]
...@@ -6997,6 +7040,21 @@ ...@@ -6997,6 +7040,21 @@
operands[1] = force_reg (DFmode, operands[1]); operands[1] = force_reg (DFmode, operands[1]);
} }
} }
/* Cannot load it directly, generate a load with clobber so that it can be
loaded via GPR with MOV / MOVT. */
if (arm_disable_literal_pool
&& (REG_P (operands[0]) || SUBREG_P (operands[0]))
&& CONSTANT_P (operands[1])
&& TARGET_HARD_FLOAT
&& !arm_const_double_rtx (operands[1])
&& !(TARGET_VFP_DOUBLE && vfp3_const_double_rtx (operands[1])))
{
rtx clobreg = gen_reg_rtx (DFmode);
emit_insn (gen_no_literal_pool_df_immediate (operands[0], operands[1],
clobreg));
DONE;
}
" "
) )
...@@ -7056,6 +7114,11 @@ ...@@ -7056,6 +7114,11 @@
case 1: case 1:
case 2: case 2:
return \"#\"; return \"#\";
case 3:
/* Cannot load it directly, split to load it via MOV / MOVT. */
if (!MEM_P (operands[1]) && arm_disable_literal_pool)
return \"#\";
/* Fall through. */
default: default:
return output_move_double (operands, true, NULL); return output_move_double (operands, true, NULL);
} }
...@@ -7067,6 +7130,24 @@ ...@@ -7067,6 +7130,24 @@
(set_attr "arm_neg_pool_range" "*,*,*,1004,*") (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
(set_attr "thumb2_neg_pool_range" "*,*,*,0,*")] (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
) )
;; Splitter for the above.
(define_split
[(set (match_operand:DF 0 "s_register_operand")
(match_operand:DF 1 "const_double_operand"))]
"arm_disable_literal_pool && TARGET_SOFT_FLOAT"
[(const_int 0)]
{
long buf[2];
int order = BYTES_BIG_ENDIAN ? 1 : 0;
real_to_target (buf, CONST_DOUBLE_REAL_VALUE (operands[1]), DFmode);
unsigned HOST_WIDE_INT ival = zext_hwi (buf[order], 32);
ival |= (zext_hwi (buf[1 - order], 32) << 32);
rtx cst = gen_int_mode (ival, DImode);
emit_move_insn (simplify_gen_subreg (DImode, operands[0], DFmode, 0), cst);
DONE;
}
)
;; load- and store-multiple insns ;; load- and store-multiple insns
......
...@@ -31,9 +31,10 @@ ...@@ -31,9 +31,10 @@
;; 'H' was previously used for FPA. ;; 'H' was previously used for FPA.
;; The following multi-letter normal constraints have been used: ;; The following multi-letter normal constraints have been used:
;; in ARM/Thumb-2 state: Da, Db, Dc, Dd, Dn, Dl, DL, Do, Dv, Dy, Di, Dt, Dp, Dz ;; in ARM/Thumb-2 state: Da, Db, Dc, Dd, Dn, Dl, DL, Do, Dv, Dy, Di, Dt, Dp,
;; Dz, Tu
;; in Thumb-1 state: Pa, Pb, Pc, Pd, Pe ;; in Thumb-1 state: Pa, Pb, Pc, Pd, Pe
;; in Thumb-2 state: Pj, PJ, Ps, Pt, Pu, Pv, Pw, Px, Py ;; in Thumb-2 state: Ha, Pj, PJ, Ps, Pt, Pu, Pv, Pw, Px, Py, Pz
;; in all states: Pf ;; in all states: Pf
;; The following memory constraints have been used: ;; The following memory constraints have been used:
...@@ -234,6 +235,12 @@ ...@@ -234,6 +235,12 @@
(and (match_code "const_double") (and (match_code "const_double")
(match_test "TARGET_32BIT && arm_const_double_rtx (op)"))) (match_test "TARGET_32BIT && arm_const_double_rtx (op)")))
(define_constraint "Ha"
"@internal In ARM / Thumb-2 a float constant iff literal pools are allowed."
(and (match_code "const_double")
(match_test "satisfies_constraint_E (op)")
(match_test "!arm_disable_literal_pool")))
(define_constraint "Dz" (define_constraint "Dz"
"@internal "@internal
In ARM/Thumb-2 state a vector of constant zeros." In ARM/Thumb-2 state a vector of constant zeros."
...@@ -351,6 +358,12 @@ ...@@ -351,6 +358,12 @@
(match_test "TARGET_32BIT (match_test "TARGET_32BIT
&& vfp3_const_double_for_bits (op) > 0"))) && vfp3_const_double_for_bits (op) > 0")))
(define_constraint "Tu"
"@internal In ARM / Thumb-2 an integer constant iff literal pools are
allowed."
(and (match_test "CONSTANT_P (op)")
(match_test "!arm_disable_literal_pool")))
(define_register_constraint "Ts" "(arm_restrict_it) ? LO_REGS : GENERAL_REGS" (define_register_constraint "Ts" "(arm_restrict_it) ? LO_REGS : GENERAL_REGS"
"For arm_restrict_it the core registers @code{r0}-@code{r7}. GENERAL_REGS otherwise.") "For arm_restrict_it the core registers @code{r0}-@code{r7}. GENERAL_REGS otherwise.")
......
...@@ -473,6 +473,24 @@ ...@@ -473,6 +473,24 @@
(and (match_code "reg,subreg,mem") (and (match_code "reg,subreg,mem")
(match_operand 0 "nonimmediate_soft_df_operand")))) (match_operand 0 "nonimmediate_soft_df_operand"))))
;; Predicate for thumb2_movsf_vfp. Compared to general_operand, this
;; forbids constant loaded via literal pool iff literal pools are disabled.
(define_predicate "hard_sf_operand"
(and (match_operand 0 "general_operand")
(ior (not (match_code "const_double"))
(not (match_test "arm_disable_literal_pool"))
(match_test "satisfies_constraint_Dv (op)"))))
;; Predicate for thumb2_movdf_vfp. Compared to soft_df_operand used in
;; movdf_soft_insn, this forbids constant loaded via literal pool iff
;; literal pools are disabled.
(define_predicate "hard_df_operand"
(and (match_operand 0 "soft_df_operand")
(ior (not (match_code "const_double"))
(not (match_test "arm_disable_literal_pool"))
(match_test "satisfies_constraint_Dy (op)")
(match_test "satisfies_constraint_G (op)"))))
(define_special_predicate "load_multiple_operation" (define_special_predicate "load_multiple_operation"
(match_code "parallel") (match_code "parallel")
{ {
......
...@@ -252,16 +252,26 @@ ...@@ -252,16 +252,26 @@
"TARGET_THUMB2 && !TARGET_IWMMXT && !TARGET_HARD_FLOAT "TARGET_THUMB2 && !TARGET_IWMMXT && !TARGET_HARD_FLOAT
&& ( register_operand (operands[0], SImode) && ( register_operand (operands[0], SImode)
|| register_operand (operands[1], SImode))" || register_operand (operands[1], SImode))"
"@ {
mov%?\\t%0, %1 switch (which_alternative)
mov%?\\t%0, %1 {
mov%?\\t%0, %1 case 0:
mvn%?\\t%0, #%B1 case 1:
movw%?\\t%0, %1 case 2:
ldr%?\\t%0, %1 return \"mov%?\\t%0, %1\";
ldr%?\\t%0, %1 case 3: return \"mvn%?\\t%0, #%B1\";
str%?\\t%1, %0 case 4: return \"movw%?\\t%0, %1\";
str%?\\t%1, %0" case 5:
case 6:
/* Cannot load it directly, split to load it via MOV / MOVT. */
if (!MEM_P (operands[1]) && arm_disable_literal_pool)
return \"#\";
return \"ldr%?\\t%0, %1\";
case 7:
case 8: return \"str%?\\t%1, %0\";
default: gcc_unreachable ();
}
}
[(set_attr "type" "mov_reg,mov_imm,mov_imm,mvn_imm,mov_imm,load_4,load_4,store_4,store_4") [(set_attr "type" "mov_reg,mov_imm,mov_imm,mvn_imm,mov_imm,load_4,load_4,store_4,store_4")
(set_attr "length" "2,4,2,4,4,4,4,4,4") (set_attr "length" "2,4,2,4,4,4,4,4,4")
(set_attr "predicable" "yes") (set_attr "predicable" "yes")
......
...@@ -259,7 +259,7 @@ ...@@ -259,7 +259,7 @@
;; arm_restrict_it. ;; arm_restrict_it.
(define_insn "*thumb2_movsi_vfp" (define_insn "*thumb2_movsi_vfp"
[(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,l,r,r, l,*hk,m, *m,*t, r,*t,*t, *Uv") [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,l,r,r, l,*hk,m, *m,*t, r,*t,*t, *Uv")
(match_operand:SI 1 "general_operand" "rk,I,Py,K,j,mi,*mi,l,*hk, r,*t,*t,*Uvi,*t"))] (match_operand:SI 1 "general_operand" "rk,I,Py,K,j,mi,*mi,l,*hk, r,*t,*t,*UvTu,*t"))]
"TARGET_THUMB2 && TARGET_HARD_FLOAT "TARGET_THUMB2 && TARGET_HARD_FLOAT
&& ( s_register_operand (operands[0], SImode) && ( s_register_operand (operands[0], SImode)
|| s_register_operand (operands[1], SImode))" || s_register_operand (operands[1], SImode))"
...@@ -276,6 +276,9 @@ ...@@ -276,6 +276,9 @@
return \"movw%?\\t%0, %1\"; return \"movw%?\\t%0, %1\";
case 5: case 5:
case 6: case 6:
/* Cannot load it directly, split to load it via MOV / MOVT. */
if (!MEM_P (operands[1]) && arm_disable_literal_pool)
return \"#\";
return \"ldr%?\\t%0, %1\"; return \"ldr%?\\t%0, %1\";
case 7: case 7:
case 8: case 8:
...@@ -305,7 +308,7 @@ ...@@ -305,7 +308,7 @@
(define_insn "*movdi_vfp" (define_insn "*movdi_vfp"
[(set (match_operand:DI 0 "nonimmediate_di_operand" "=r,r,r,r,q,q,m,w,!r,w,w, Uv") [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r,r,r,r,q,q,m,w,!r,w,w, Uv")
(match_operand:DI 1 "di_operand" "r,rDa,Db,Dc,mi,mi,q,r,w,w,Uvi,w"))] (match_operand:DI 1 "di_operand" "r,rDa,Db,Dc,mi,mi,q,r,w,w,UvTu,w"))]
"TARGET_32BIT && TARGET_HARD_FLOAT "TARGET_32BIT && TARGET_HARD_FLOAT
&& ( register_operand (operands[0], DImode) && ( register_operand (operands[0], DImode)
|| register_operand (operands[1], DImode)) || register_operand (operands[1], DImode))
...@@ -321,6 +324,10 @@ ...@@ -321,6 +324,10 @@
return \"#\"; return \"#\";
case 4: case 4:
case 5: case 5:
/* Cannot load it directly, split to load it via MOV / MOVT. */
if (!MEM_P (operands[1]) && arm_disable_literal_pool)
return \"#\";
/* Fall through. */
case 6: case 6:
return output_move_double (operands, true, NULL); return output_move_double (operands, true, NULL);
case 7: case 7:
...@@ -587,7 +594,7 @@ ...@@ -587,7 +594,7 @@
(define_insn "*thumb2_movsf_vfp" (define_insn "*thumb2_movsf_vfp"
[(set (match_operand:SF 0 "nonimmediate_operand" "=t,?r,t, t ,Uv,r ,m,t,r") [(set (match_operand:SF 0 "nonimmediate_operand" "=t,?r,t, t ,Uv,r ,m,t,r")
(match_operand:SF 1 "general_operand" " ?r,t,Dv,UvE,t, mE,r,t,r"))] (match_operand:SF 1 "hard_sf_operand" " ?r,t,Dv,UvHa,t, mHa,r,t,r"))]
"TARGET_THUMB2 && TARGET_HARD_FLOAT "TARGET_THUMB2 && TARGET_HARD_FLOAT
&& ( s_register_operand (operands[0], SFmode) && ( s_register_operand (operands[0], SFmode)
|| s_register_operand (operands[1], SFmode))" || s_register_operand (operands[1], SFmode))"
...@@ -676,7 +683,7 @@ ...@@ -676,7 +683,7 @@
(define_insn "*thumb2_movdf_vfp" (define_insn "*thumb2_movdf_vfp"
[(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,?r,w ,w,w ,Uv,r ,m,w,r") [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,?r,w ,w,w ,Uv,r ,m,w,r")
(match_operand:DF 1 "soft_df_operand" " ?r,w,Dy,G,UvF,w, mF,r, w,r"))] (match_operand:DF 1 "hard_df_operand" " ?r,w,Dy,G,UvHa,w, mHa,r, w,r"))]
"TARGET_THUMB2 && TARGET_HARD_FLOAT "TARGET_THUMB2 && TARGET_HARD_FLOAT
&& ( register_operand (operands[0], DFmode) && ( register_operand (operands[0], DFmode)
|| register_operand (operands[1], DFmode))" || register_operand (operands[1], DFmode))"
...@@ -1983,39 +1990,50 @@ ...@@ -1983,39 +1990,50 @@
;; Support for xD (single precision only) variants. ;; Support for xD (single precision only) variants.
;; fmrrs, fmsrr ;; fmrrs, fmsrr
;; Split an immediate DF move to two immediate SI moves. ;; Load a DF immediate via GPR (where combinations of MOV and MOVT can be used)
;; and then move it into a VFP register.
(define_insn_and_split "no_literal_pool_df_immediate" (define_insn_and_split "no_literal_pool_df_immediate"
[(set (match_operand:DF 0 "s_register_operand" "") [(set (match_operand:DF 0 "s_register_operand" "=w")
(match_operand:DF 1 "const_double_operand" ""))] (match_operand:DF 1 "const_double_operand" "F"))
"TARGET_THUMB2 && arm_disable_literal_pool (clobber (match_operand:DF 2 "s_register_operand" "=r"))]
&& !(TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE "arm_disable_literal_pool
&& vfp3_const_double_rtx (operands[1]))" && TARGET_HARD_FLOAT
&& !arm_const_double_rtx (operands[1])
&& !(TARGET_VFP_DOUBLE && vfp3_const_double_rtx (operands[1]))"
"#" "#"
"&& !reload_completed" ""
[(set (subreg:SI (match_dup 1) 0) (match_dup 2)) [(const_int 0)]
(set (subreg:SI (match_dup 1) 4) (match_dup 3)) {
(set (match_dup 0) (match_dup 1))]
"
long buf[2]; long buf[2];
int order = BYTES_BIG_ENDIAN ? 1 : 0;
real_to_target (buf, CONST_DOUBLE_REAL_VALUE (operands[1]), DFmode); real_to_target (buf, CONST_DOUBLE_REAL_VALUE (operands[1]), DFmode);
operands[2] = GEN_INT ((int) buf[0]); unsigned HOST_WIDE_INT ival = zext_hwi (buf[order], 32);
operands[3] = GEN_INT ((int) buf[1]); ival |= (zext_hwi (buf[1 - order], 32) << 32);
operands[1] = gen_reg_rtx (DFmode); rtx cst = gen_int_mode (ival, DImode);
") emit_move_insn (simplify_gen_subreg (DImode, operands[2], DFmode, 0), cst);
emit_move_insn (operands[0], operands[2]);
DONE;
}
)
;; Split an immediate SF move to one immediate SI move. ;; Load a SF immediate via GPR (where combinations of MOV and MOVT can be used)
;; and then move it into a VFP register.
(define_insn_and_split "no_literal_pool_sf_immediate" (define_insn_and_split "no_literal_pool_sf_immediate"
[(set (match_operand:SF 0 "s_register_operand" "") [(set (match_operand:SF 0 "s_register_operand" "=t")
(match_operand:SF 1 "const_double_operand" ""))] (match_operand:SF 1 "const_double_operand" "E"))
"TARGET_THUMB2 && arm_disable_literal_pool (clobber (match_operand:SF 2 "s_register_operand" "=r"))]
&& !(TARGET_HARD_FLOAT && vfp3_const_double_rtx (operands[1]))" "arm_disable_literal_pool
&& TARGET_HARD_FLOAT
&& !vfp3_const_double_rtx (operands[1])"
"#" "#"
"&& !reload_completed" ""
[(set (subreg:SI (match_dup 1) 0) (match_dup 2)) [(const_int 0)]
(set (match_dup 0) (match_dup 1))] {
"
long buf; long buf;
real_to_target (&buf, CONST_DOUBLE_REAL_VALUE (operands[1]), SFmode); real_to_target (&buf, CONST_DOUBLE_REAL_VALUE (operands[1]), SFmode);
operands[2] = GEN_INT ((int) buf); rtx cst = gen_int_mode (buf, SImode);
operands[1] = gen_reg_rtx (SFmode); emit_move_insn (simplify_gen_subreg (SImode, operands[2], SFmode, 0), cst);
") emit_move_insn (operands[0], operands[2]);
DONE;
}
)
2018-11-14 Thomas Preud'homme <thomas.preudhomme@arm.com>
* gcc.target/arm/thumb2-slow-flash-data-2.c: Require arm_fp_ok
effective target.
* gcc.target/arm/thumb2-slow-flash-data-3.c: Likewise.
* gcc.target/arm/thumb2-slow-flash-data-4.c: Likewise.
* gcc.target/arm/thumb2-slow-flash-data-5.c: Likewise.
2018-12-14 H.J. Lu <hongjiu.lu@intel.com> 2018-12-14 H.J. Lu <hongjiu.lu@intel.com>
PR target/88483 PR target/88483
......
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-require-effective-target arm_cortex_m } */ /* { dg-require-effective-target arm_cortex_m } */
/* { dg-require-effective-target arm_thumb2_ok } */ /* { dg-require-effective-target arm_thumb2_ok } */
/* { dg-require-effective-target arm_fp_ok } */
/* { dg-skip-if "avoid conflicts with multilib options" { *-*-* } { "-mcpu=*" } { "-mcpu=cortex-m4" "-mcpu=cortex-m7" } } */ /* { dg-skip-if "avoid conflicts with multilib options" { *-*-* } { "-mcpu=*" } { "-mcpu=cortex-m4" "-mcpu=cortex-m7" } } */
/* { dg-skip-if "do not override -mfloat-abi" { *-*-* } { "-mfloat-abi=*" } { "-mfloat-abi=hard" } } */ /* { dg-skip-if "do not override -mfloat-abi" { *-*-* } { "-mfloat-abi=*" } { "-mfloat-abi=hard" } } */
/* { dg-skip-if "-mslow-flash-data and -mword-relocations incompatible" { *-*-* } { "-mword-relocations" } } */ /* { dg-skip-if "-mslow-flash-data and -mword-relocations incompatible" { *-*-* } { "-mword-relocations" } } */
......
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-require-effective-target arm_cortex_m } */ /* { dg-require-effective-target arm_cortex_m } */
/* { dg-require-effective-target arm_thumb2_ok } */ /* { dg-require-effective-target arm_thumb2_ok } */
/* { dg-require-effective-target arm_fp_ok } */
/* { dg-skip-if "avoid conflicts with multilib options" { *-*-* } { "-mcpu=*" } { "-mcpu=cortex-m4" "-mcpu=cortex-m7" } } */ /* { dg-skip-if "avoid conflicts with multilib options" { *-*-* } { "-mcpu=*" } { "-mcpu=cortex-m4" "-mcpu=cortex-m7" } } */
/* { dg-skip-if "do not override -mfloat-abi" { *-*-* } { "-mfloat-abi=*" } { "-mfloat-abi=hard" } } */ /* { dg-skip-if "do not override -mfloat-abi" { *-*-* } { "-mfloat-abi=*" } { "-mfloat-abi=hard" } } */
/* { dg-skip-if "-mslow-flash-data and -mword-relocations incompatible" { *-*-* } { "-mword-relocations" } } */ /* { dg-skip-if "-mslow-flash-data and -mword-relocations incompatible" { *-*-* } { "-mword-relocations" } } */
......
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-require-effective-target arm_cortex_m } */ /* { dg-require-effective-target arm_cortex_m } */
/* { dg-require-effective-target arm_thumb2_ok } */ /* { dg-require-effective-target arm_thumb2_ok } */
/* { dg-require-effective-target arm_fp_ok } */
/* { dg-skip-if "avoid conflicts with multilib options" { *-*-* } { "-mcpu=*" } { "-mcpu=cortex-m4" "-mcpu=cortex-m7" } } */ /* { dg-skip-if "avoid conflicts with multilib options" { *-*-* } { "-mcpu=*" } { "-mcpu=cortex-m4" "-mcpu=cortex-m7" } } */
/* { dg-skip-if "do not override -mfloat-abi" { *-*-* } { "-mfloat-abi=*" } { "-mfloat-abi=hard" } } */ /* { dg-skip-if "do not override -mfloat-abi" { *-*-* } { "-mfloat-abi=*" } { "-mfloat-abi=hard" } } */
/* { dg-skip-if "-mslow-flash-data and -mword-relocations incompatible" { *-*-* } { "-mword-relocations" } } */ /* { dg-skip-if "-mslow-flash-data and -mword-relocations incompatible" { *-*-* } { "-mword-relocations" } } */
......
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-require-effective-target arm_cortex_m } */ /* { dg-require-effective-target arm_cortex_m } */
/* { dg-require-effective-target arm_thumb2_ok } */ /* { dg-require-effective-target arm_thumb2_ok } */
/* { dg-require-effective-target arm_fp_ok } */
/* { dg-skip-if "avoid conflicts with multilib options" { *-*-* } { "-mcpu=*" } { "-mcpu=cortex-m4" "-mcpu=cortex-m7" } } */ /* { dg-skip-if "avoid conflicts with multilib options" { *-*-* } { "-mcpu=*" } { "-mcpu=cortex-m4" "-mcpu=cortex-m7" } } */
/* { dg-skip-if "do not override -mfloat-abi" { *-*-* } { "-mfloat-abi=*" } { "-mfloat-abi=hard" } } */ /* { dg-skip-if "do not override -mfloat-abi" { *-*-* } { "-mfloat-abi=*" } { "-mfloat-abi=hard" } } */
/* { dg-skip-if "-mslow-flash-data and -mword-relocations incompatible" { *-*-* } { "-mword-relocations" } } */ /* { dg-skip-if "-mslow-flash-data and -mword-relocations incompatible" { *-*-* } { "-mword-relocations" } } */
......
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