diff options
-rw-r--r-- | gcc/ChangeLog | 21 | ||||
-rw-r--r-- | gcc/config/arm/arm.md | 28 | ||||
-rw-r--r-- | gcc/config/arm/constraints.md | 3 | ||||
-rw-r--r-- | gcc/config/arm/thumb2.md | 71 | ||||
-rw-r--r-- | gcc/config/arm/vfp.md | 39 |
5 files changed, 100 insertions, 62 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bd6d724dabd..a584e7601d8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,26 @@ 2013-06-28 Kyrylo Tkachov <kyrylo.tkachov@arm.com> + * config/arm/constraints.md (Ts): New constraint. + * config/arm/arm.md (arm_movqi_insn): Add alternatives for + 16-bit encodings. + (compare_scc): Use "Ts" constraint for operand 0. + (ior_scc_scc): Likewise. + (and_scc_scc): Likewise. + (and_scc_scc_nodom): Likewise. + (ior_scc_scc_cmp): Likewise for operand 7. + (and_scc_scc_cmp): Likewise. + * config/arm/thumb2.md (thumb2_movsi_insn): + Add alternatives for 16-bit encodings. + (thumb2_movhi_insn): Likewise. + (thumb2_movsicc_insn): Likewise. + (thumb2_and_scc): Take 'and' outside cond_exec. Use "Ts" constraint. + (thumb2_negscc): Use "Ts" constraint. + Move mvn instruction outside cond_exec block. + * config/arm/vfp.md (thumb2_movsi_vfp): Add alternatives + for 16-bit encodings. + +2013-06-28 Kyrylo Tkachov <kyrylo.tkachov@arm.com> + * config/arm/arm.md (arm_mulsi3_v6): Add alternative for 16-bit encoding. (mulsi3addsi_v6): Disable predicable variant for arm_restrict_it. diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index ff32cad8d23..c464eddebd4 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -7216,26 +7216,28 @@ " ) - (define_insn "*arm_movqi_insn" - [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,Uu,r,m") - (match_operand:QI 1 "general_operand" "r,I,K,Uu,l,m,r"))] + [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m") + (match_operand:QI 1 "general_operand" "r,r,I,Py,K,Uu,l,m,r"))] "TARGET_32BIT && ( register_operand (operands[0], QImode) || register_operand (operands[1], QImode))" "@ mov%?\\t%0, %1 mov%?\\t%0, %1 + mov%?\\t%0, %1 + mov%?\\t%0, %1 mvn%?\\t%0, #%B1 ldr%(b%)\\t%0, %1 str%(b%)\\t%1, %0 ldr%(b%)\\t%0, %1 str%(b%)\\t%1, %0" - [(set_attr "type" "*,simple_alu_imm,simple_alu_imm,load1, store1, load1, store1") - (set_attr "insn" "mov,mov,mvn,*,*,*,*") + [(set_attr "type" "*,*,simple_alu_imm,simple_alu_imm,simple_alu_imm,load1, store1, load1, store1") + (set_attr "insn" "mov,mov,mov,mov,mvn,*,*,*,*") (set_attr "predicable" "yes") - (set_attr "arch" "any,any,any,t2,t2,any,any") - (set_attr "length" "4,4,4,2,2,4,4")] + (set_attr "predicable_short_it" "yes,yes,yes,no,no,no,no,no,no") + (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any") + (set_attr "length" "2,4,4,2,4,2,2,4,4")] ) (define_insn "*thumb1_movqi_insn" @@ -10164,7 +10166,7 @@ (set (match_dup 0) (const_int 1)))]) (define_insn_and_split "*compare_scc" - [(set (match_operand:SI 0 "s_register_operand" "=r,r") + [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts") (match_operator:SI 1 "arm_comparison_operator" [(match_operand:SI 2 "s_register_operand" "r,r") (match_operand:SI 3 "arm_add_operand" "rI,L")])) @@ -10674,7 +10676,7 @@ ) (define_insn_and_split "*ior_scc_scc" - [(set (match_operand:SI 0 "s_register_operand" "=r") + [(set (match_operand:SI 0 "s_register_operand" "=Ts") (ior:SI (match_operator:SI 3 "arm_comparison_operator" [(match_operand:SI 1 "s_register_operand" "r") (match_operand:SI 2 "arm_add_operand" "rIL")]) @@ -10712,7 +10714,7 @@ [(match_operand:SI 4 "s_register_operand" "r") (match_operand:SI 5 "arm_add_operand" "rIL")])) (const_int 0))) - (set (match_operand:SI 7 "s_register_operand" "=r") + (set (match_operand:SI 7 "s_register_operand" "=Ts") (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)]) (match_op_dup 6 [(match_dup 4) (match_dup 5)])))] "TARGET_32BIT" @@ -10730,7 +10732,7 @@ (set_attr "length" "16")]) (define_insn_and_split "*and_scc_scc" - [(set (match_operand:SI 0 "s_register_operand" "=r") + [(set (match_operand:SI 0 "s_register_operand" "=Ts") (and:SI (match_operator:SI 3 "arm_comparison_operator" [(match_operand:SI 1 "s_register_operand" "r") (match_operand:SI 2 "arm_add_operand" "rIL")]) @@ -10770,7 +10772,7 @@ [(match_operand:SI 4 "s_register_operand" "r") (match_operand:SI 5 "arm_add_operand" "rIL")])) (const_int 0))) - (set (match_operand:SI 7 "s_register_operand" "=r") + (set (match_operand:SI 7 "s_register_operand" "=Ts") (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)]) (match_op_dup 6 [(match_dup 4) (match_dup 5)])))] "TARGET_32BIT" @@ -10792,7 +10794,7 @@ ;; need only zero the value if false (if true, then the value is already ;; correct). (define_insn_and_split "*and_scc_scc_nodom" - [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r") + [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts") (and:SI (match_operator:SI 3 "arm_comparison_operator" [(match_operand:SI 1 "s_register_operand" "r,r,0") (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")]) diff --git a/gcc/config/arm/constraints.md b/gcc/config/arm/constraints.md index 13230fae805..251d4975b7c 100644 --- a/gcc/config/arm/constraints.md +++ b/gcc/config/arm/constraints.md @@ -329,6 +329,9 @@ (and (match_code "const_double") (match_test "TARGET_32BIT && TARGET_VFP && vfp3_const_double_for_fract_bits (op)"))) +(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.") + (define_memory_constraint "Ua" "@internal An address valid for loading/storing register exclusive" diff --git a/gcc/config/arm/thumb2.md b/gcc/config/arm/thumb2.md index 4e3ebd7d621..cd5837480b8 100644 --- a/gcc/config/arm/thumb2.md +++ b/gcc/config/arm/thumb2.md @@ -267,8 +267,8 @@ ;; regs. The high register alternatives are not taken into account when ;; choosing register preferences in order to reflect their expense. (define_insn "*thumb2_movsi_insn" - [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,l ,*hk,m,*m") - (match_operand:SI 1 "general_operand" "rk ,I,K,j,mi,*mi,l,*hk"))] + [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,l,r,r,l ,*hk,m,*m") + (match_operand:SI 1 "general_operand" "rk,I,Py,K,j,mi,*mi,l,*hk"))] "TARGET_THUMB2 && ! TARGET_IWMMXT && !(TARGET_HARD_FLOAT && TARGET_VFP) && ( register_operand (operands[0], SImode) @@ -276,16 +276,19 @@ "@ mov%?\\t%0, %1 mov%?\\t%0, %1 + mov%?\\t%0, %1 mvn%?\\t%0, #%B1 movw%?\\t%0, %1 ldr%?\\t%0, %1 ldr%?\\t%0, %1 str%?\\t%1, %0 str%?\\t%1, %0" - [(set_attr "type" "*,*,simple_alu_imm,*,load1,load1,store1,store1") + [(set_attr "type" "*,simple_alu_imm,simple_alu_imm,simple_alu_imm,*,load1,load1,store1,store1") + (set_attr "length" "2,4,2,4,4,4,4,4,4") (set_attr "predicable" "yes") - (set_attr "pool_range" "*,*,*,*,1018,4094,*,*") - (set_attr "neg_pool_range" "*,*,*,*,0,0,*,*")] + (set_attr "predicable_short_it" "yes,no,yes,no,no,no,no,no,no") + (set_attr "pool_range" "*,*,*,*,*,1018,4094,*,*") + (set_attr "neg_pool_range" "*,*,*,*,*,0,0,*,*")] ) (define_insn "tls_load_dot_plus_four" @@ -390,26 +393,32 @@ ) (define_insn_and_split "*thumb2_movsicc_insn" - [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r") + [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r,r,r,r,r,r,r,r,l") (if_then_else:SI (match_operator 3 "arm_comparison_operator" [(match_operand 4 "cc_register" "") (const_int 0)]) - (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K") - (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))] + (match_operand:SI 1 "arm_not_operand" "0 ,Py,0 ,0,rI,K,rI,rI,K ,K,r,lPy") + (match_operand:SI 2 "arm_not_operand" "Py,0 ,rI,K,0 ,0,rI,K ,rI,K,r,lPy")))] "TARGET_THUMB2" "@ it\\t%D3\;mov%D3\\t%0, %2 + it\\t%d3\;mov%d3\\t%0, %1 + it\\t%D3\;mov%D3\\t%0, %2 it\\t%D3\;mvn%D3\\t%0, #%B2 it\\t%d3\;mov%d3\\t%0, %1 it\\t%d3\;mvn%d3\\t%0, #%B1 # # # + # + # #" - ; alt 4: ite\\t%d3\;mov%d3\\t%0, %1\;mov%D3\\t%0, %2 - ; alt 5: ite\\t%d3\;mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2 - ; alt 6: ite\\t%d3\;mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2 - ; alt 7: ite\\t%d3\;mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2" + ; alt 6: ite\\t%d3\;mov%d3\\t%0, %1\;mov%D3\\t%0, %2 + ; alt 7: ite\\t%d3\;mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2 + ; alt 8: ite\\t%d3\;mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2 + ; alt 9: ite\\t%d3\;mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2 + ; alt 10: ite\\t%d3\;mov%d3\\t%0, %1\;mov%D3\\t%0, %2 + ; alt 11: ite\\t%d3\;mov%d3\\t%0, %1\;mov%D3\\t%0, %2" "&& reload_completed" [(const_int 0)] { @@ -440,7 +449,8 @@ operands[2]))); DONE; } - [(set_attr "length" "6,6,6,6,10,10,10,10") + [(set_attr "length" "4,4,6,6,6,6,10,10,10,10,6,6") + (set_attr "enabled_for_depr_it" "yes,yes,no,no,no,no,no,no,no,no,yes,yes") (set_attr "conds" "use")] ) @@ -491,29 +501,30 @@ (define_insn_and_split "*thumb2_and_scc" - [(set (match_operand:SI 0 "s_register_operand" "=r") + [(set (match_operand:SI 0 "s_register_operand" "=Ts") (and:SI (match_operator:SI 1 "arm_comparison_operator" [(match_operand 2 "cc_register" "") (const_int 0)]) (match_operand:SI 3 "s_register_operand" "r")))] "TARGET_THUMB2" - "#" ; "ite\\t%D1\;mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1" + "#" ; "and\\t%0, %3, #1\;it\\t%D1\;mov%D1\\t%0, #0" "&& reload_completed" - [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0))) - (cond_exec (match_dup 4) (set (match_dup 0) - (and:SI (match_dup 3) (const_int 1))))] + [(set (match_dup 0) + (and:SI (match_dup 3) (const_int 1))) + (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))] { enum machine_mode mode = GET_MODE (operands[2]); enum rtx_code rc = GET_CODE (operands[1]); - operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx); if (mode == CCFPmode || mode == CCFPEmode) rc = reverse_condition_maybe_unordered (rc); else rc = reverse_condition (rc); - operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx); + operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx); } [(set_attr "conds" "use") - (set_attr "length" "10")] + (set (attr "length") (if_then_else (match_test "arm_restrict_it") + (const_int 8) + (const_int 10)))] ) (define_insn_and_split "*thumb2_ior_scc" @@ -649,7 +660,7 @@ ) (define_insn_and_split "*thumb2_negscc" - [(set (match_operand:SI 0 "s_register_operand" "=r") + [(set (match_operand:SI 0 "s_register_operand" "=Ts") (neg:SI (match_operator 3 "arm_comparison_operator" [(match_operand:SI 1 "s_register_operand" "r") (match_operand:SI 2 "arm_rhs_operand" "rI")]))) @@ -671,7 +682,7 @@ GEN_INT (31)))); DONE; } - else if (GET_CODE (operands[3]) == NE) + else if (GET_CODE (operands[3]) == NE && !arm_restrict_it) { /* Emit subs\\t%0, %1, %2\;it\\tne\;mvnne\\t%0, #0 */ if (CONST_INT_P (operands[2])) @@ -691,7 +702,7 @@ } else { - /* Emit: cmp\\t%1, %2\;ite\\t%D3\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */ + /* Emit: cmp\\t%1, %2\;mvn\\t%0, #0\;it\\t%D3\;mov%D3\\t%0, #0\;*/ enum rtx_code rc = reverse_condition (GET_CODE (operands[3])); enum machine_mode mode = SELECT_CC_MODE (rc, operands[1], operands[2]); rtx tmp1 = gen_rtx_REG (mode, CC_REGNUM); @@ -699,21 +710,15 @@ emit_insn (gen_rtx_SET (VOIDmode, cc_reg, gen_rtx_COMPARE (CCmode, operands[1], operands[2]))); + + emit_insn (gen_rtx_SET (VOIDmode, operands[0], GEN_INT (~0))); + emit_insn (gen_rtx_COND_EXEC (VOIDmode, gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx), gen_rtx_SET (VOIDmode, operands[0], const0_rtx))); - rc = GET_CODE (operands[3]); - emit_insn (gen_rtx_COND_EXEC (VOIDmode, - gen_rtx_fmt_ee (rc, - VOIDmode, - tmp1, - const0_rtx), - gen_rtx_SET (VOIDmode, - operands[0], - GEN_INT (~0)))); DONE; } FAIL; diff --git a/gcc/config/arm/vfp.md b/gcc/config/arm/vfp.md index 95057e7155f..9ac887e9b19 100644 --- a/gcc/config/arm/vfp.md +++ b/gcc/config/arm/vfp.md @@ -62,45 +62,52 @@ ;; See thumb2.md:thumb2_movsi_insn for an explanation of the split ;; high/low register alternatives for loads and stores here. +;; The l/Py alternative should come after r/I to ensure that the short variant +;; is chosen with length 2 when the instruction is predicated for +;; arm_restrict_it. (define_insn "*thumb2_movsi_vfp" - [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r, l,*hk,m, *m,*t, r,*t,*t, *Uv") - (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,*mi,l,*hk, r,*t,*t,*Uvi,*t"))] + [(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"))] "TARGET_THUMB2 && TARGET_VFP && TARGET_HARD_FLOAT && ( s_register_operand (operands[0], SImode) || s_register_operand (operands[1], SImode))" "* switch (which_alternative) { - case 0: case 1: - return \"mov%?\\t%0, %1\"; + case 0: + case 1: case 2: - return \"mvn%?\\t%0, #%B1\"; + return \"mov%?\\t%0, %1\"; case 3: - return \"movw%?\\t%0, %1\"; + return \"mvn%?\\t%0, #%B1\"; case 4: + return \"movw%?\\t%0, %1\"; case 5: - return \"ldr%?\\t%0, %1\"; case 6: + return \"ldr%?\\t%0, %1\"; case 7: - return \"str%?\\t%1, %0\"; case 8: - return \"fmsr%?\\t%0, %1\\t%@ int\"; + return \"str%?\\t%1, %0\"; case 9: - return \"fmrs%?\\t%0, %1\\t%@ int\"; + return \"fmsr%?\\t%0, %1\\t%@ int\"; case 10: + return \"fmrs%?\\t%0, %1\\t%@ int\"; + case 11: return \"fcpys%?\\t%0, %1\\t%@ int\"; - case 11: case 12: + case 12: case 13: return output_move_vfp (operands); default: gcc_unreachable (); } " [(set_attr "predicable" "yes") - (set_attr "type" "*,*,*,*,load1,load1,store1,store1,r_2_f,f_2_r,fcpys,f_loads,f_stores") - (set_attr "neon_type" "*,*,*,*,*,*,*,*,neon_mcr,neon_mrc,neon_vmov,*,*") - (set_attr "insn" "mov,mov,mvn,mov,*,*,*,*,*,*,*,*,*") - (set_attr "pool_range" "*,*,*,*,1018,4094,*,*,*,*,*,1018,*") - (set_attr "neg_pool_range" "*,*,*,*, 0, 0,*,*,*,*,*,1008,*")] + (set_attr "predicable_short_it" "yes,no,yes,no,no,no,no,no,no,no,no,no,no,no") + (set_attr "type" "*,*,*,*,*,load1,load1,store1,store1,r_2_f,f_2_r,fcpys,f_loads,f_stores") + (set_attr "length" "2,4,2,4,4,4,4,4,4,4,4,4,4,4") + (set_attr "neon_type" "*,*,*,*,*,*,*,*,*,neon_mcr,neon_mrc,neon_vmov,*,*") + (set_attr "insn" "mov,mov,mov,mvn,mov,*,*,*,*,*,*,*,*,*") + (set_attr "pool_range" "*,*,*,*,*,1018,4094,*,*,*,*,*,1018,*") + (set_attr "neg_pool_range" "*,*,*,*,*, 0, 0,*,*,*,*,*,1008,*")] ) |