--- gcc/config/rs6000.md 2018/04/24 17:51:37 1.1.1.1 +++ gcc/config/rs6000.md 2018/04/24 17:55:07 1.1.1.2 @@ -22,7 +22,7 @@ ;; Define an insn type attribute. This is used in function unit delay ;; computations. -(define_attr "type" "load,integer,fp,compare,delayed_compare,fpcompare" +(define_attr "type" "load,integer,fp,compare,delayed_compare,fpcompare,mtlr" (const_string "integer")) ;; Memory delivers its result in two cycles. @@ -40,6 +40,9 @@ ;; Floating-point comparisons take eight cycles. (define_function_unit "compare" 1 0 (eq_attr "type" "fpcompare") 8 0) + +;; Branches on LR cannot be done until five cycles after LR is set. +(define_function_unit "branch" 1 0 (eq_attr "type" "mtlr") 5 0) ;; Start with fixed-point load and store insns. Here we put only the more ;; complex forms. Basic data transfer is done later. @@ -265,8 +268,6 @@ negate_rtx (SImode, operands[2]))); DONE; } - else - operands[2] = force_reg (SImode, operands[2]); }") ;; For SMIN, SMAX, UMIN, and UMAX, we use DEFINE_EXPAND's that involve a doz[i] @@ -328,7 +329,7 @@ (define_insn "" [(set (match_operand:SI 0 "gen_reg_operand" "=r") (if_then_else:SI (gt (match_operand:SI 1 "gen_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "r")) + (match_operand:SI 2 "reg_or_short_operand" "rI")) (const_int 0) (minus:SI (match_dup 2) (match_dup 1))))] "" @@ -338,7 +339,7 @@ [(set (match_operand:CC 0 "cc_reg_operand" "=x") (compare:CC (if_then_else:SI (gt (match_operand:SI 1 "gen_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "r")) + (match_operand:SI 2 "reg_or_short_operand" "rI")) (const_int 0) (minus:SI (match_dup 2) (match_dup 1))) (const_int 0))) @@ -351,7 +352,7 @@ [(set (match_operand:CC 3 "cc_reg_operand" "=x") (compare:CC (if_then_else:SI (gt (match_operand:SI 1 "gen_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "r")) + (match_operand:SI 2 "reg_or_short_operand" "rI")) (const_int 0) (minus:SI (match_dup 2) (match_dup 1))) (const_int 0))) @@ -1277,6 +1278,8 @@ "rlinm. %0,%h1,%h2,%m3,%M3" [(set_attr "type" "delayed_compare")]) +;; The RS/6000 assembler mis-handles "sri x,x,0", so write that case as +;; "sli x,x,0". (define_insn "lshrsi3" [(set (match_operand:SI 0 "gen_reg_operand" "=r,r") (lshiftrt:SI (match_operand:SI 1 "gen_reg_operand" "r,r") @@ -1285,7 +1288,7 @@ "" "@ sre %0,%1,%2 - sri %0,%1,%h2") + s%A2i %0,%1,%h2") (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,x") @@ -1297,7 +1300,7 @@ "" "@ sre. %3,%1,%2 - sri. %3,%1,%h2" + s%A2i. %3,%1,%h2" [(set_attr "type" "delayed_compare")]) (define_insn "" @@ -1311,7 +1314,7 @@ "" "@ sre. %0,%1,%2 - sri. %0,%1,%h2" + s%A2i. %0,%1,%h2" [(set_attr "type" "delayed_compare")]) (define_insn "" @@ -1936,19 +1939,19 @@ sli %0,%L1,%h2\;cal %L0,0(0) sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2 sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2 - sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2 ") + sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2") (define_insn "lshrdi3" - [(set (match_operand:DI 0 "gen_reg_operand" "=r,r,r,&r") + [(set (match_operand:DI 0 "gen_reg_operand" "=&r,r,r,&r") (lshiftrt:DI (match_operand:DI 1 "gen_reg_operand" "r,r,0,r") (match_operand:SI 2 "reg_or_cint_operand" "M,i,r,r"))) (clobber (match_scratch:SI 3 "=X,q,q,q"))] "" "@ - cal %0,0(0)\;sri %L0,%1,%h2 - sr%I2q %L0,%L1,%2\;srl%I2q %0,%1,%2 - sr%I2q %L0,%L1,%2\;srl%I2q %0,%1,%2 - sr%I2q %L0,%L1,%2\;srl%I2q %0,%1,%2 ") + cal %0,0(0)\;s%A2i %L0,%1,%h2 + s%A2%I2q %L0,%L1,%2\;srl%I2q %0,%1,%2 + s%A2%I2q %L0,%L1,%2\;srl%I2q %0,%1,%2 + s%A2%I2q %L0,%L1,%2\;srl%I2q %0,%1,%2") ;; Shift by a variable amount is too complex to be worth open-coding. We ;; just handle shifts by constants. @@ -2007,8 +2010,8 @@ }") (define_insn "" - [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m,r,r,r,*h") - (match_operand:SI 1 "input_operand" "r,m,r,I,J,*h,r"))] + [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m,r,r,r,*c*q,*l") + (match_operand:SI 1 "input_operand" "r,m,r,I,J,*h,r,r"))] "gen_reg_operand (operands[0], SImode) || gen_reg_operand (operands[1], SImode)" "@ @@ -2018,8 +2021,9 @@ cal %0,%1(0) cau %0,0,%u1 mf%1 %0 + mt%0 %1 mt%0 %1" - [(set_attr "type" "*,load,*,*,*,*,*")]) + [(set_attr "type" "*,load,*,*,*,*,*,mtlr")]) (define_insn "" [(set (match_operand:CC 2 "cc_reg_operand" "=x") @@ -2773,7 +2777,7 @@ ;; Next come insns related to the calling sequence. ;; ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca). -;; We move the back-chain and decremement the stack pointer. This is slightly +;; We move the back-chain and decrement the stack pointer. This is slightly ;; less efficient than it needs to be for long constants, but that case ;; should be rare.