--- gcc/config/pa/pa.md 2018/04/24 18:17:21 1.1.1.2 +++ gcc/config/pa/pa.md 2018/04/24 18:23:31 1.1.1.3 @@ -74,7 +74,7 @@ (const_string "true") (const_string "false"))) -;; For calls and millicode calls. Allow unconditional branches in the +;; For calls and millicode calls. Allow unconditional branches in the ;; delay slot. (define_attr "in_call_delay" "false,true" (cond [(and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,dyncall,multi,milli") @@ -86,13 +86,19 @@ (const_string "true") (const_string "false"))] (const_string "false"))) - -;; Unconditional branch, call, and millicode call delay slot description. -(define_delay (eq_attr "type" "uncond_branch,branch,call,milli") +;; Unconditional branch and call delay slot description. +(define_delay (eq_attr "type" "uncond_branch,branch,call") [(eq_attr "in_call_delay" "true") (nil) (nil)]) +;; millicode call delay slot description. Note it disallows delay slot +;; when TARGET_LONG_CALLS is true. +(define_delay (eq_attr "type" "milli") + [(and (eq_attr "in_call_delay" "true") + (eq (symbol_ref "TARGET_LONG_CALLS") (const_int 0))) + (nil) (nil)]) + ;; Unconditional branch, return and other similar instructions. (define_delay (eq_attr "type" "uncond_branch,branch") [(eq_attr "in_branch_delay" "true") (nil) (nil)]) @@ -109,8 +115,8 @@ ;; backward branches nullify false. If the direction is unknown ;; then nullification is not allowed. (define_delay (eq_attr "type" "cbranch") - [(eq_attr "in_branch_delay" "true") - (and (eq_attr "in_nullified_branch_delay" "true") + [(eq_attr "in_branch_delay" "true") + (and (eq_attr "in_nullified_branch_delay" "true") (attr_flag "forward")) (and (eq_attr "in_nullified_branch_delay" "true") (attr_flag "backward"))]) @@ -215,22 +221,22 @@ }") (define_insn "" - [(set (reg:CCFP 0) - (match_operator:CCFP 2 "comparison_operator" - [(match_operand:SF 0 "reg_or_0_operand" "fxG") - (match_operand:SF 1 "reg_or_0_operand" "fxG")]))] - "" - "fcmp,sgl,%Y2 %r0,%r1" - [(set_attr "type" "fpcc")]) - -(define_insn "" - [(set (reg:CCFP 0) - (match_operator:CCFP 2 "comparison_operator" - [(match_operand:DF 0 "reg_or_0_operand" "fxG") - (match_operand:DF 1 "reg_or_0_operand" "fxG")]))] - "" - "fcmp,dbl,%Y2 %r0,%r1" - [(set_attr "type" "fpcc")]) + [(set (reg:CCFP 0) + (match_operator:CCFP 2 "comparison_operator" + [(match_operand:SF 0 "reg_or_0_operand" "fG") + (match_operand:SF 1 "reg_or_0_operand" "fG")]))] + "" + "fcmp,sgl,%Y2 %r0,%r1" + [(set_attr "type" "fpcc")]) + +(define_insn "" + [(set (reg:CCFP 0) + (match_operator:CCFP 2 "comparison_operator" + [(match_operand:DF 0 "reg_or_0_operand" "fG") + (match_operand:DF 1 "reg_or_0_operand" "fG")]))] + "" + "fcmp,dbl,%Y2 %r0,%r1" + [(set_attr "type" "fpcc")]) ;; scc insns. @@ -379,19 +385,32 @@ [(set (match_operand:SI 0 "register_operand" "=r") (match_operator:SI 3 "comparison_operator" [(match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "arith11_operand" "rI")]))] + (match_operand:SI 2 "arith11_operand" "rI")]))] "" "com%I2clr,%B3 %2,%1,%0\;ldi 1,%0" [(set_attr "type" "binary") (set_attr "length" "8")]) +(define_insn "iorscc" + [(set (match_operand:SI 0 "register_operand" "=r") + (ior:SI (match_operator:SI 3 "comparison_operator" + [(match_operand:SI 1 "register_operand" "r") + (match_operand:SI 2 "arith11_operand" "rI")]) + (match_operator:SI 6 "comparison_operator" + [(match_operand:SI 4 "register_operand" "r") + (match_operand:SI 5 "arith11_operand" "rI")])))] + "" + "com%I2clr,%S3 %2,%1,0\;com%I5clr,%B6 %5,%4,%0\;ldi 1,%0" + [(set_attr "type" "binary") + (set_attr "length" "8")]) + ;; Combiner patterns for common operations performed with the output -;; from an scc insn (negscc and incscc). +;; from an scc insn (negscc and incscc). (define_insn "negscc" [(set (match_operand:SI 0 "register_operand" "=r") (neg:SI (match_operator:SI 3 "comparison_operator" [(match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "arith11_operand" "rI")])))] + (match_operand:SI 2 "arith11_operand" "rI")])))] "" "com%I2clr,%B3 %2,%1,%0\;ldi -1,%0" [(set_attr "type" "binary") @@ -461,6 +480,17 @@ [(set_attr "type" "binary") (set_attr "length" "8")]) +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=r") + (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r") + (gtu:SI (match_operand:SI 2 "register_operand" "r") + (match_operand:SI 3 "arith11_operand" "rI"))) + (match_operand:SI 4 "register_operand" "r")))] + "" + "sub%I3 %3,%2,0\;subb %1,%4,%0" + [(set_attr "type" "binary") + (set_attr "length" "8")]) + ; This need only accept registers for op3, since canonicalization ; replaces ltu with leu when op3 is an integer. (define_insn "" @@ -473,6 +503,17 @@ [(set_attr "type" "binary") (set_attr "length" "8")]) +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=r") + (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r") + (ltu:SI (match_operand:SI 2 "register_operand" "r") + (match_operand:SI 3 "register_operand" "r"))) + (match_operand:SI 4 "register_operand" "r")))] + "" + "sub %2,%3,0\;subb %1,%4,%0" + [(set_attr "type" "binary") + (set_attr "length" "8")]) + ; Match only integers for op3 here. This is used as canonical form of the ; ltu pattern when op3 is an integer. Don't match registers since we can't ; make better code than the general incscc pattern. @@ -486,6 +527,17 @@ [(set_attr "type" "binary") (set_attr "length" "8")]) +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=r") + (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r") + (leu:SI (match_operand:SI 2 "register_operand" "r") + (match_operand:SI 3 "int11_operand" "I"))) + (match_operand:SI 4 "register_operand" "r")))] + "" + "addi %k3,%2,0\;subb %1,%4,%0" + [(set_attr "type" "binary") + (set_attr "length" "8")]) + (define_insn "decscc" [(set (match_operand:SI 0 "register_operand" "=r,r") (minus:SI (match_operand:SI 1 "register_operand" "0,?r") @@ -762,7 +814,7 @@ ;; Note a long backward conditional branch with an annulled delay slot -;; has a length of 12. +;; has a length of 12. (define_insn "" [(set (pc) (if_then_else @@ -774,11 +826,11 @@ "" "* { - return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn), + return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn), get_attr_length (insn), 0, insn); }" [(set_attr "type" "cbranch") - (set (attr "length") + (set (attr "length") (if_then_else (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) (const_int 8188)) (const_int 4) @@ -797,11 +849,11 @@ "" "* { - return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn), + return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn), get_attr_length (insn), 1, insn); }" [(set_attr "type" "cbranch") - (set (attr "length") + (set (attr "length") (if_then_else (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) (const_int 8188)) (const_int 4) @@ -820,13 +872,13 @@ "" "* { - return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn), - get_attr_length (insn), + return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn), + get_attr_length (insn), (operands[3] != pc_rtx), insn, 0); }" [(set_attr "type" "cbranch") - (set (attr "length") + (set (attr "length") (if_then_else (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) (const_int 8188)) (const_int 4) @@ -844,13 +896,13 @@ "" "* { - return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn), - get_attr_length (insn), + return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn), + get_attr_length (insn), (operands[3] != pc_rtx), insn, 1); }" [(set_attr "type" "cbranch") - (set (attr "length") + (set (attr "length") (if_then_else (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) (const_int 8188)) (const_int 4) @@ -904,7 +956,7 @@ (define_expand "reload_insi" [(set (match_operand:SI 0 "register_operand" "=Z") - (match_operand:SI 1 "general_operand" "")) + (match_operand:SI 1 "non_hard_reg_operand" "")) (clobber (match_operand:SI 2 "register_operand" "=&r"))] "" " @@ -918,7 +970,7 @@ }") (define_expand "reload_outsi" - [(set (match_operand:SI 0 "general_operand" "") + [(set (match_operand:SI 0 "non_hard_reg_operand" "") (match_operand:SI 1 "register_operand" "Z")) (clobber (match_operand:SI 2 "register_operand" "=&r"))] "" @@ -944,14 +996,14 @@ (set_attr "length" "4")]) (define_insn "" - [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" - "=r,r,r,r,r,Q,*q,!fx,fx,*T") - (match_operand:SI 1 "move_operand" - "rM,J,N,K,Q,rM,rM,!fxM,*T,fx"))] + [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" + "=r,r,r,r,r,Q,*q,!f,f,*T") + (match_operand:SI 1 "move_operand" + "r,J,N,K,Q,rM,rM,!fM,*T,f"))] "register_operand (operands[0], SImode) || reg_or_0_operand (operands[1], SImode)" "@ - copy %r1,%0 + copy %1,%0 ldi %1,%0 ldil L'%1,%0 zdepi %Z1,%0 @@ -982,9 +1034,14 @@ ;; This variant of the above insn can occur if the second operand ;; is the frame pointer. This is a kludge, but there doesn't ;; seem to be a way around it. Only recognize it while reloading. +;; Note how operand 3 uses a predicate of "const_int_operand", but +;; has constraints allowing a register. I don't know how this works, +;; but it somehow makes sure that out-of-range constants are placed +;; in a register which somehow magically is a "const_int_operand". +;; (this was stolen from alpha.md, I'm not going to try and change it. (define_insn "" [(set (match_operand:SI 0 "register_operand" "&=r") - (mem:SI (plus:SI (plus:SI + (mem:SI (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r") (const_int 4)) (match_operand:SI 2 "register_operand" "r")) @@ -993,9 +1050,9 @@ "* { if (GET_CODE (operands[3]) == CONST_INT) - return \"sh2add %1,%2,%0\;ldw %3(0,%0),%0\"; + return \"sh2addl %1,%2,%0\;ldw %3(0,%0),%0\"; else - return \"sh2add %1,%2,%0\;ldwx %3(0,%0),%0\"; + return \"sh2addl %1,%2,%0\;ldwx %3(0,%0),%0\"; }" [(set_attr "type" "load") (set_attr "length" "8")]) @@ -1038,7 +1095,7 @@ [(set (match_operand:SI 3 "register_operand" "r") (mem:SI (match_operand:SI 1 "register_operand" "0"))) (set (match_operand:SI 0 "register_operand" "=r") - (plus:SI (match_dup 1) + (plus:SI (match_dup 1) (match_operand:SI 2 "post_cint_operand" "")))] "" "* @@ -1054,7 +1111,7 @@ [(set (mem:SI (match_operand:SI 1 "register_operand" "0")) (match_operand:SI 3 "reg_or_0_operand" "rM")) (set (match_operand:SI 0 "register_operand" "=r") - (plus:SI (match_dup 1) + (plus:SI (match_dup 1) (match_operand:SI 2 "post_cint_operand" "")))] "" "* @@ -1096,7 +1153,7 @@ (define_insn "" [(set (match_operand:SI 0 "register_operand" "=a") (high:SI (match_operand 1 "" "")))] - "symbolic_operand(operands[1], Pmode) + "symbolic_operand (operands[1], Pmode) && ! function_label_operand (operands[1]) && ! read_only_operand (operands[1])" "@ @@ -1104,19 +1161,19 @@ [(set_attr "type" "binary") (set_attr "length" "4")]) -;; This is for use in the prologue/epilogue code. We need it +;; This is for use in the prologue/epilogue code. We need it ;; to add large constants to a stack pointer or frame pointer. ;; Because of the additional %r1 pressure, we probably do not ;; want to use this in general code, so make it available ;; only after reload. (define_insn "add_high_const" [(set (match_operand:SI 0 "register_operand" "=!a,*r") - (plus (match_operand:SI 1 "register_operand" "r,r") - (high:SI (match_operand 2 "const_int_operand" ""))))] + (plus:SI (match_operand:SI 1 "register_operand" "r,r") + (high:SI (match_operand 2 "const_int_operand" ""))))] "reload_completed" "@ addil L'%G2,%1 - ldil L'%G2,%0\;add %0,%1,%0" + ldil L'%G2,%0\;addl %0,%1,%0" [(set_attr "type" "binary,binary") (set_attr "length" "4,8")]) @@ -1124,46 +1181,69 @@ (define_insn "" [(set (match_operand:SI 0 "register_operand" "=r") (high:SI (match_operand:SI 1 "function_label_operand" "")))] - "" + "!TARGET_PORTABLE_RUNTIME" "ldil LP'%G1,%0" [(set_attr "type" "move") (set_attr "length" "4")]) +;; This version is used only for the portable runtime conventions model +;; (it does not use/support plabels) +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=r") + (high:SI (match_operand:SI 1 "function_label_operand" "")))] + "TARGET_PORTABLE_RUNTIME" + "ldil L'%G1,%0" + [(set_attr "type" "move") + (set_attr "length" "4")]) + (define_insn "" [(set (match_operand:SI 0 "register_operand" "=r") (high:SI (match_operand 1 "" "")))] - "check_pic (1)" + "check_pic (1) && !is_function_label_plus_const (operands[1])" "ldil L'%G1,%0" [(set_attr "type" "move") (set_attr "length" "4")]) ;; lo_sum of a function address. +;; +;; Note since we are not supporting MPE style external calls we can +;; use the short ldil;ldo sequence. If one wanted to support +;; MPE external calls you would want to generate something like +;; ldil;ldo;extru;ldw;add. See the HP compiler's output for details. (define_insn "" [(set (match_operand:SI 0 "register_operand" "=r") (lo_sum:SI (match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "function_label_operand" ""))) - (clobber (match_operand:SI 3 "register_operand" "=r"))] - "" - "ldo RP'%G2(%1),%0\;extru,= %0,31,1,%3\;ldw -4(0,%%r27),%3\;add %0,%3,%0" - [(set_attr "type" "multi") - (set_attr "length" "16")]) + (match_operand:SI 2 "function_label_operand" "")))] + "!TARGET_PORTABLE_RUNTIME" + "ldo RP'%G2(%1),%0" + [(set_attr "length" "4")]) + +;; This version is used only for the portable runtime conventions model +;; (it does not use/support plabels) +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=r") + (lo_sum:SI (match_operand:SI 1 "register_operand" "r") + (match_operand:SI 2 "function_label_operand" "")))] + "TARGET_PORTABLE_RUNTIME" + "ldo R'%G2(%1),%0" + [(set_attr "length" "4")]) (define_insn "" [(set (match_operand:SI 0 "register_operand" "=r") (lo_sum:SI (match_operand:SI 1 "register_operand" "r") (match_operand:SI 2 "immediate_operand" "i")))] - "" + "!is_function_label_plus_const (operands[2])" "ldo R'%G2(%1),%0" [(set_attr "length" "4")]) ;; Now that a symbolic_address plus a constant is broken up early ;; in the compilation phase (for better CSE) we need a special ;; combiner pattern to load the symbolic address plus the constant -;; in only 2 instructions. (For cases where the symbolic address +;; in only 2 instructions. (For cases where the symbolic address ;; was not a common subexpression.) (define_split [(set (match_operand:SI 0 "register_operand" "") - (match_operand 1 "symbolic_operand" "")) + (match_operand:SI 1 "symbolic_operand" "")) (clobber (match_operand:SI 2 "register_operand" ""))] "" [(set (match_dup 2) (high:SI (match_dup 1))) @@ -1181,12 +1261,12 @@ }") (define_insn "" - [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q,*q,!fx") - (match_operand:HI 1 "move_operand" "rM,J,N,K,Q,rM,rM,!fxM"))] + [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q,*q,!f") + (match_operand:HI 1 "move_operand" "r,J,N,K,Q,rM,rM,!fM"))] "register_operand (operands[0], HImode) || reg_or_0_operand (operands[1], HImode)" "@ - copy %r1,%0 + copy %1,%0 ldi %1,%0 ldil L'%1,%0 zdepi %Z1,%0 @@ -1210,9 +1290,14 @@ ;; This variant of the above insn can occur if the second operand ;; is the frame pointer. This is a kludge, but there doesn't ;; seem to be a way around it. Only recognize it while reloading. +;; Note how operand 3 uses a predicate of "const_int_operand", but +;; has constraints allowing a register. I don't know how this works, +;; but it somehow makes sure that out-of-range constants are placed +;; in a register which somehow magically is a "const_int_operand". +;; (this was stolen from alpha.md, I'm not going to try and change it. (define_insn "" [(set (match_operand:HI 0 "register_operand" "=&r") - (mem:HI (plus:SI (plus:SI + (mem:HI (plus:SI (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r") (const_int 2)) (match_operand:SI 1 "register_operand" "r")) @@ -1221,9 +1306,9 @@ "* { if (GET_CODE (operands[3]) == CONST_INT) - return \"sh1add %2,%1,%0\;ldh %3(0,%0),%0\"; + return \"sh1addl %2,%1,%0\;ldh %3(0,%0),%0\"; else - return \"sh1add %2,%1,%0\;ldhx %3(0,%0),%0\"; + return \"sh1addl %2,%1,%0\;ldhx %3(0,%0),%0\"; }" [(set_attr "type" "load") (set_attr "length" "8")]) @@ -1277,12 +1362,12 @@ }") (define_insn "" - [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q,*q,!fx") - (match_operand:QI 1 "move_operand" "rM,J,N,K,Q,rM,rM,!fxM"))] + [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q,*q,!f") + (match_operand:QI 1 "move_operand" "r,J,N,K,Q,rM,rM,!fM"))] "register_operand (operands[0], QImode) || reg_or_0_operand (operands[1], QImode)" "@ - copy %r1,%0 + copy %1,%0 ldi %1,%0 ldil L'%1,%0 zdepi %Z1,%0 @@ -1320,8 +1405,8 @@ ;; that anything generated as this insn will be recognized as one ;; and that it will not successfully combine with anything. (define_expand "movstrsi" - [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" "")) - (mem:BLK (match_operand:BLK 1 "general_operand" ""))) + [(parallel [(set (mem:BLK (match_operand:BLK 0 "" "")) + (mem:BLK (match_operand:BLK 1 "" ""))) (clobber (match_dup 0)) (clobber (match_dup 1)) (clobber (match_dup 4)) @@ -1337,7 +1422,7 @@ runtime and make the optimal decisions. */ if (INTVAL (operands[3]) < 4 && (GET_CODE (operands[2]) != CONST_INT - || (INTVAL (operands[2]) / INTVAL (operands[3]) > 16))) + || (INTVAL (operands[2]) / INTVAL (operands[3]) > 8))) FAIL; operands[0] = copy_to_mode_reg (SImode, XEXP (operands[0], 0)); @@ -1372,11 +1457,11 @@ ;; ;; For integer registers we use ldil;ldo to set the appropriate ;; value. -;; +;; ;; This must come before the movdf pattern, and it must be present ;; to handle obscure reloading cases. (define_insn "" - [(set (match_operand:DF 0 "general_operand" "=?r,fx") + [(set (match_operand:DF 0 "general_operand" "=?r,f") (match_operand:DF 1 "" "?E,m"))] "GET_CODE (operands[1]) == CONST_DOUBLE && operands[1] != CONST0_RTX (DFmode)" @@ -1395,16 +1480,49 @@ DONE; }") +;; Reloading an SImode or DImode value requires a scratch register if +;; going in to or out of float point registers. + +(define_expand "reload_indf" + [(set (match_operand:DF 0 "register_operand" "=Z") + (match_operand:DF 1 "non_hard_reg_operand" "")) + (clobber (match_operand:DF 2 "register_operand" "=&r"))] + "" + " +{ + if (emit_move_sequence (operands, DFmode, operands[2])) + DONE; + + /* We don't want the clobber emitted, so handle this ourselves. */ + emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1])); + DONE; +}") + +(define_expand "reload_outdf" + [(set (match_operand:DF 0 "non_hard_reg_operand" "") + (match_operand:DF 1 "register_operand" "Z")) + (clobber (match_operand:DF 2 "register_operand" "=&r"))] + "" + " +{ + if (emit_move_sequence (operands, DFmode, operands[2])) + DONE; + + /* We don't want the clobber emitted, so handle this ourselves. */ + emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1])); + DONE; +}") + (define_insn "" [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" - "=fx,*r,Q,?o,?Q,fx,*&r,*&r") + "=f,*r,Q,?o,?Q,f,*&r,*&r") (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand" - "fxG,*rG,fx,*r,*r,Q,o,Q"))] + "fG,*rG,f,*r,*r,Q,o,Q"))] "register_operand (operands[0], DFmode) || reg_or_0_operand (operands[1], DFmode)" "* { - if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]) + if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]) || operands[1] == CONST0_RTX (DFmode)) return output_fp_move_double (operands); return output_move_double (operands); @@ -1413,7 +1531,7 @@ (set_attr "length" "4,8,4,8,16,4,8,16")]) (define_insn "" - [(set (match_operand:DF 0 "register_operand" "=fx") + [(set (match_operand:DF 0 "register_operand" "=f") (mem:DF (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r") (const_int 8)) (match_operand:SI 2 "register_operand" "r"))))] @@ -1425,12 +1543,17 @@ ;; This variant of the above insn can occur if the second operand ;; is the frame pointer. This is a kludge, but there doesn't ;; seem to be a way around it. Only recognize it while reloading. +;; Note how operand 3 uses a predicate of "const_int_operand", but +;; has constraints allowing a register. I don't know how this works, +;; but it somehow makes sure that out-of-range constants are placed +;; in a register which somehow magically is a "const_int_operand". +;; (this was stolen from alpha.md, I'm not going to try and change it. ;; Ugh. Output is a FP register; so we need to earlyclobber something -;; else as a temporary. +;; else as a temporary. (define_insn "" - [(set (match_operand:DF 0 "register_operand" "=fx") - (mem:DF (plus:SI - (plus:SI + [(set (match_operand:DF 0 "register_operand" "=f") + (mem:DF (plus:SI + (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "+&r") (const_int 8)) (match_operand:SI 2 "register_operand" "r")) @@ -1439,9 +1562,9 @@ "* { if (GET_CODE (operands[3]) == CONST_INT) - return \"sh3add %1,%2,%1\;fldds %3(0,%1),%0\"; + return \"sh3addl %1,%2,%1\;fldds %3(0,%1),%0\"; else - return \"sh3add %1,%2,%1\;flddx %3(0,%1),%0\"; + return \"sh3addl %1,%2,%1\;flddx %3(0,%1),%0\"; }" [(set_attr "type" "fpload") (set_attr "length" "8")]) @@ -1450,7 +1573,7 @@ [(set (mem:DF (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r") (const_int 8)) (match_operand:SI 2 "register_operand" "r"))) - (match_operand:DF 0 "register_operand" "fx"))] + (match_operand:DF 0 "register_operand" "f"))] "! TARGET_DISABLE_INDEXING" "fstdx,s %0,%1(0,%2)" [(set_attr "type" "fpstore") @@ -1459,23 +1582,28 @@ ;; This variant of the above insn can occur if the second operand ;; is the frame pointer. This is a kludge, but there doesn't ;; seem to be a way around it. Only recognize it while reloading. +;; Note how operand 3 uses a predicate of "const_int_operand", but +;; has constraints allowing a register. I don't know how this works, +;; but it somehow makes sure that out-of-range constants are placed +;; in a register which somehow magically is a "const_int_operand". +;; (this was stolen from alpha.md, I'm not going to try and change it. ;; Ugh. Output is a FP register; so we need to earlyclobber something -;; else as a temporary. +;; else as a temporary. (define_insn "" - [(set (mem:DF (plus:SI - (plus:SI + [(set (mem:DF (plus:SI + (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "+&r") (const_int 8)) (match_operand:SI 2 "register_operand" "r")) (match_operand:SI 3 "const_int_operand" "rL"))) - (match_operand:DF 0 "register_operand" "=fx"))] + (match_operand:DF 0 "register_operand" "f"))] "! TARGET_DISABLE_INDEXING && reload_in_progress" "* { if (GET_CODE (operands[3]) == CONST_INT) - return \"sh3add %1,%2,%1\;fstds %3(0,%1),%0\"; + return \"sh3addl %1,%2,%1\;fstds %0,%3(0,%1)\"; else - return \"sh3add %1,%2,%1\;fstdx %3(0,%1),%0\"; + return \"sh3addl %1,%2,%1\;fstdx %0,%3(0,%1)\"; }" [(set_attr "type" "fpstore") (set_attr "length" "8")]) @@ -1491,8 +1619,8 @@ }") (define_expand "reload_indi" - [(set (match_operand:DI 0 "register_operand" "=z") - (match_operand:DI 1 "general_operand" "")) + [(set (match_operand:DI 0 "register_operand" "=f") + (match_operand:DI 1 "non_hard_reg_operand" "")) (clobber (match_operand:SI 2 "register_operand" "=&r"))] "" " @@ -1507,7 +1635,7 @@ (define_expand "reload_outdi" [(set (match_operand:DI 0 "general_operand" "") - (match_operand:DI 1 "register_operand" "z")) + (match_operand:DI 1 "register_operand" "f")) (clobber (match_operand:SI 2 "register_operand" "=&r"))] "" " @@ -1562,9 +1690,9 @@ (define_insn "" [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" - "=r,o,Q,&r,&r,&r,x,x,*T") + "=r,o,Q,&r,&r,&r,f,f,*T") (match_operand:DI 1 "general_operand" - "rM,r,r,o,Q,i,xM,*T,x"))] + "rM,r,r,o,Q,i,fM,*T,f"))] "register_operand (operands[0], DImode) || reg_or_0_operand (operands[1], DImode)" "* @@ -1578,7 +1706,7 @@ (set_attr "length" "8,8,16,8,16,16,4,4,4")]) (define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r,r") + [(set (match_operand:DI 0 "register_operand" "=r,&r") (lo_sum:DI (match_operand:DI 1 "register_operand" "0,r") (match_operand:DI 2 "immediate_operand" "i,i")))] "" @@ -1602,11 +1730,11 @@ ;; ;; For integer registers we use ldil;ldo to set the appropriate ;; value. -;; +;; ;; This must come before the movsf pattern, and it must be present ;; to handle obscure reloading cases. (define_insn "" - [(set (match_operand:SF 0 "general_operand" "=?r,fx") + [(set (match_operand:SF 0 "general_operand" "=?r,f") (match_operand:SF 1 "" "?E,m"))] "GET_CODE (operands[1]) == CONST_DOUBLE && operands[1] != CONST0_RTX (SFmode)" @@ -1625,11 +1753,44 @@ DONE; }") +;; Reloading an SImode or DImode value requires a scratch register if +;; going in to or out of float point registers. + +(define_expand "reload_insf" + [(set (match_operand:SF 0 "register_operand" "=Z") + (match_operand:SF 1 "non_hard_reg_operand" "")) + (clobber (match_operand:SF 2 "register_operand" "=&r"))] + "" + " +{ + if (emit_move_sequence (operands, SFmode, operands[2])) + DONE; + + /* We don't want the clobber emitted, so handle this ourselves. */ + emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1])); + DONE; +}") + +(define_expand "reload_outsf" + [(set (match_operand:SF 0 "non_hard_reg_operand" "") + (match_operand:SF 1 "register_operand" "Z")) + (clobber (match_operand:SF 2 "register_operand" "=&r"))] + "" + " +{ + if (emit_move_sequence (operands, SFmode, operands[2])) + DONE; + + /* We don't want the clobber emitted, so handle this ourselves. */ + emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1])); + DONE; +}") + (define_insn "" [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" - "=fx,r,fx,r,Q,Q") + "=f,r,f,r,Q,Q") (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand" - "fxG,rG,Q,Q,fx,rG"))] + "fG,rG,Q,Q,f,rG"))] "register_operand (operands[0], SFmode) || reg_or_0_operand (operands[1], SFmode)" "@ @@ -1643,7 +1804,7 @@ (set_attr "length" "4,4,4,4,4,4")]) (define_insn "" - [(set (match_operand:SF 0 "register_operand" "=fx") + [(set (match_operand:SF 0 "register_operand" "=f") (mem:SF (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r") (const_int 4)) (match_operand:SI 2 "register_operand" "r"))))] @@ -1655,12 +1816,17 @@ ;; This variant of the above insn can occur if the second operand ;; is the frame pointer. This is a kludge, but there doesn't ;; seem to be a way around it. Only recognize it while reloading. +;; Note how operand 3 uses a predicate of "const_int_operand", but +;; has constraints allowing a register. I don't know how this works, +;; but it somehow makes sure that out-of-range constants are placed +;; in a register which somehow magically is a "const_int_operand". +;; (this was stolen from alpha.md, I'm not going to try and change it. ;; Ugh. Output is a FP register; so we need to earlyclobber something -;; else as a temporary. +;; else as a temporary. (define_insn "" - [(set (match_operand:SF 0 "register_operand" "=fx") - (mem:SF (plus:SI - (plus:SI + [(set (match_operand:SF 0 "register_operand" "=f") + (mem:SF (plus:SI + (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "+&r") (const_int 4)) (match_operand:SI 2 "register_operand" "r")) @@ -1669,9 +1835,9 @@ "* { if (GET_CODE (operands[3]) == CONST_INT) - return \"sh2add %1,%2,%1\;fldws %3(0,%1),%0\"; + return \"sh2addl %1,%2,%1\;fldws %3(0,%1),%0\"; else - return \"sh2add %1,%2,%1\;fldwx %3(0,%1),%0\"; + return \"sh2addl %1,%2,%1\;fldwx %3(0,%1),%0\"; }" [(set_attr "type" "fpload") (set_attr "length" "8")]) @@ -1680,7 +1846,7 @@ [(set (mem:SF (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r") (const_int 4)) (match_operand:SI 2 "register_operand" "r"))) - (match_operand:SF 0 "register_operand" "fx"))] + (match_operand:SF 0 "register_operand" "f"))] "! TARGET_DISABLE_INDEXING" "fstwx,s %0,%1(0,%2)" [(set_attr "type" "fpstore") @@ -1689,23 +1855,28 @@ ;; This variant of the above insn can occur if the second operand ;; is the frame pointer. This is a kludge, but there doesn't ;; seem to be a way around it. Only recognize it while reloading. +;; Note how operand 3 uses a predicate of "const_int_operand", but +;; has constraints allowing a register. I don't know how this works, +;; but it somehow makes sure that out-of-range constants are placed +;; in a register which somehow magically is a "const_int_operand". +;; (this was stolen from alpha.md, I'm not going to try and change it. ;; Ugh. Output is a FP register; so we need to earlyclobber something -;; else as a temporary. +;; else as a temporary. (define_insn "" - [(set (mem:SF (plus:SI - (plus:SI + [(set (mem:SF (plus:SI + (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "+&r") (const_int 4)) (match_operand:SI 2 "register_operand" "r")) (match_operand:SI 3 "const_int_operand" "rL"))) - (match_operand:SF 0 "register_operand" "=fx"))] + (match_operand:SF 0 "register_operand" "f"))] "! TARGET_DISABLE_INDEXING && reload_in_progress" "* { if (GET_CODE (operands[3]) == CONST_INT) - return \"sh2add %1,%2,%1\;fstds %3(0,%1),%0\"; + return \"sh2addl %1,%2,%1\;fstws %0,%3(0,%1)\"; else - return \"sh2add %1,%2,%1\;fstdx %3(0,%1),%0\"; + return \"sh2addl %1,%2,%1\;fstwx %0,%3(0,%1)\"; }" [(set_attr "type" "fpstore") (set_attr "length" "8")]) @@ -1768,17 +1939,17 @@ ;; Conversions between float and double. (define_insn "extendsfdf2" - [(set (match_operand:DF 0 "register_operand" "=fx") + [(set (match_operand:DF 0 "register_operand" "=f") (float_extend:DF - (match_operand:SF 1 "register_operand" "fx")))] + (match_operand:SF 1 "register_operand" "f")))] "" "fcnvff,sgl,dbl %1,%0" [(set_attr "type" "fpalu")]) (define_insn "truncdfsf2" - [(set (match_operand:SF 0 "register_operand" "=fx") + [(set (match_operand:SF 0 "register_operand" "=f") (float_truncate:SF - (match_operand:DF 1 "register_operand" "fx")))] + (match_operand:DF 1 "register_operand" "f")))] "" "fcnvff,dbl,sgl %1,%0" [(set_attr "type" "fpalu")]) @@ -1795,7 +1966,7 @@ ;; to be reloaded by putting the constant into memory. ;; It must come before the more general floatsisf2 pattern. (define_insn "" - [(set (match_operand:SF 0 "general_operand" "=fx") + [(set (match_operand:SF 0 "general_operand" "=f") (float:SF (match_operand:SI 1 "const_int_operand" "m")))] "" "fldws %1,%0\;fcnvxf,sgl,sgl %0,%0" @@ -1803,8 +1974,8 @@ (set_attr "length" "8")]) (define_insn "floatsisf2" - [(set (match_operand:SF 0 "general_operand" "=fx") - (float:SF (match_operand:SI 1 "register_operand" "fx")))] + [(set (match_operand:SF 0 "general_operand" "=f") + (float:SF (match_operand:SI 1 "register_operand" "f")))] "" "fcnvxf,sgl,sgl %1,%0" [(set_attr "type" "fpalu")]) @@ -1813,7 +1984,7 @@ ;; to be reloaded by putting the constant into memory. ;; It must come before the more general floatsidf2 pattern. (define_insn "" - [(set (match_operand:DF 0 "general_operand" "=fx") + [(set (match_operand:DF 0 "general_operand" "=f") (float:DF (match_operand:SI 1 "const_int_operand" "m")))] "" "fldws %1,%0\;fcnvxf,sgl,dbl %0,%0" @@ -1821,8 +1992,8 @@ (set_attr "length" "8")]) (define_insn "floatsidf2" - [(set (match_operand:DF 0 "general_operand" "=fx") - (float:DF (match_operand:SI 1 "register_operand" "fx")))] + [(set (match_operand:DF 0 "general_operand" "=f") + (float:DF (match_operand:SI 1 "register_operand" "f")))] "" "fcnvxf,sgl,dbl %1,%0" [(set_attr "type" "fpalu")]) @@ -1848,15 +2019,15 @@ "operands[2] = gen_reg_rtx (DImode);") (define_insn "floatdisf2" - [(set (match_operand:SF 0 "general_operand" "=x") - (float:SF (match_operand:DI 1 "register_operand" "x")))] + [(set (match_operand:SF 0 "general_operand" "=f") + (float:SF (match_operand:DI 1 "register_operand" "f")))] "TARGET_SNAKE" "fcnvxf,dbl,sgl %1,%0" [(set_attr "type" "fpalu")]) (define_insn "floatdidf2" - [(set (match_operand:DF 0 "general_operand" "=x") - (float:DF (match_operand:DI 1 "register_operand" "x")))] + [(set (match_operand:DF 0 "general_operand" "=f") + (float:DF (match_operand:DI 1 "register_operand" "f")))] "TARGET_SNAKE" "fcnvxf,dbl,dbl %1,%0" [(set_attr "type" "fpalu")]) @@ -1865,29 +2036,29 @@ ;; Truncation is performed as part of the conversion. (define_insn "fix_truncsfsi2" - [(set (match_operand:SI 0 "register_operand" "=fx") - (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "fx"))))] + [(set (match_operand:SI 0 "register_operand" "=f") + (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))] "" "fcnvfxt,sgl,sgl %1,%0" [(set_attr "type" "fpalu")]) (define_insn "fix_truncdfsi2" - [(set (match_operand:SI 0 "register_operand" "=fx") - (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "fx"))))] + [(set (match_operand:SI 0 "register_operand" "=f") + (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))] "" "fcnvfxt,dbl,sgl %1,%0" [(set_attr "type" "fpalu")]) (define_insn "fix_truncsfdi2" - [(set (match_operand:DI 0 "register_operand" "=x") - (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "x"))))] + [(set (match_operand:DI 0 "register_operand" "=f") + (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))] "TARGET_SNAKE" "fcnvfxt,sgl,dbl %1,%0" [(set_attr "type" "fpalu")]) (define_insn "fix_truncdfdi2" - [(set (match_operand:DI 0 "register_operand" "=x") - (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "x"))))] + [(set (match_operand:DI 0 "register_operand" "=f") + (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))] "TARGET_SNAKE" "fcnvfxt,dbl,dbl %1,%0" [(set_attr "type" "fpalu")]) @@ -1927,7 +2098,7 @@ (plus:SI (match_operand:SI 1 "register_operand" "") (match_operand:SI 2 "const_int_operand" ""))) (clobber (match_operand:SI 4 "register_operand" ""))] - "! cint_ok_for_move (INTVAL (operands[2])) + "! cint_ok_for_move (INTVAL (operands[2])) && VAL_14_BITS_P (INTVAL (operands[2]) >> 1)" [(set (match_dup 4) (plus:SI (match_dup 1) (match_dup 2))) (set (match_dup 0) (plus:SI (match_dup 4) (match_dup 3)))] @@ -1952,27 +2123,27 @@ (match_dup 1)))] " { - int intval = INTVAL (operands[2]); + HOST_WIDE_INT intval = INTVAL (operands[2]); - /* Try diving the constant by 2, then 4, and finally 8 to see + /* Try dividing the constant by 2, then 4, and finally 8 to see if we can get a constant which can be loaded into a register in a single instruction (cint_ok_for_move). */ if (intval % 2 == 0 && cint_ok_for_move (intval / 2)) { - operands[2] = GEN_INT (INTVAL (operands[2]) / 2); + operands[2] = GEN_INT (intval / 2); operands[3] = GEN_INT (2); } else if (intval % 4 == 0 && cint_ok_for_move (intval / 4)) { - operands[2] = GEN_INT (INTVAL (operands[2]) / 4); + operands[2] = GEN_INT (intval / 4); operands[3] = GEN_INT (4); } else if (intval % 8 == 0 && cint_ok_for_move (intval / 8)) { - operands[2] = GEN_INT (INTVAL (operands[2]) / 8); + operands[2] = GEN_INT (intval / 8); operands[3] = GEN_INT (8); } - else + else FAIL; }") @@ -1982,7 +2153,7 @@ (match_operand:SI 2 "arith_operand" "r,J")))] "" "@ - add %1,%2,%0 + addl %1,%2,%0 ldo %2(%1),%0") (define_insn "subdi3" @@ -2011,7 +2182,7 @@ [(set (reg:SI 26) (match_operand:SI 1 "move_operand" "")) (set (reg:SI 25) (match_operand:SI 2 "move_operand" "")) (parallel [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25))) - (clobber (match_operand:SI 3 "register_operand" "")) + (clobber (match_dup 3)) (clobber (reg:SI 26)) (clobber (reg:SI 25)) (clobber (reg:SI 31))]) @@ -2030,18 +2201,26 @@ gen_rtx (SUBREG, SImode, scratch, 1))); DONE; } - operands[3] = gen_reg_rtx(SImode); + operands[3] = gen_reg_rtx (SImode); }") (define_insn "umulsidi3" - [(set (match_operand:DI 0 "register_operand" "=x") - (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "x")) - (zero_extend:DI (match_operand:SI 2 "register_operand" "x"))))] + [(set (match_operand:DI 0 "nonimmediate_operand" "=f") + (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f")) + (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "f"))))] "TARGET_SNAKE && ! TARGET_DISABLE_FPREGS" "xmpyu %1,%2,%0" [(set_attr "type" "fpmul")]) (define_insn "" + [(set (match_operand:DI 0 "nonimmediate_operand" "=f") + (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f")) + (match_operand:DI 2 "uint32_operand" "f")))] + "TARGET_SNAKE && ! TARGET_DISABLE_FPREGS" + "xmpyu %1,%R2,%0" + [(set_attr "type" "fpmul")]) + +(define_insn "" [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25))) (clobber (match_operand:SI 0 "register_operand" "=a")) (clobber (reg:SI 26)) @@ -2049,14 +2228,18 @@ (clobber (reg:SI 31))] "" "* return output_mul_insn (0, insn);" - [(set_attr "type" "milli")]) + [(set_attr "type" "milli") + (set (attr "length") (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") + (const_int 0)) + (const_int 4) + (const_int 24)))]) ;;; Division and mod. (define_expand "divsi3" [(set (reg:SI 26) (match_operand:SI 1 "move_operand" "")) (set (reg:SI 25) (match_operand:SI 2 "move_operand" "")) (parallel [(set (reg:SI 29) (div:SI (reg:SI 26) (reg:SI 25))) - (clobber (match_operand:SI 3 "register_operand" "")) + (clobber (match_dup 3)) (clobber (reg:SI 26)) (clobber (reg:SI 25)) (clobber (reg:SI 31))]) @@ -2092,16 +2275,20 @@ (clobber (reg:SI 26)) (clobber (reg:SI 25)) (clobber (reg:SI 31))] - "" - "* - return output_div_insn (operands, 0, insn);" - [(set_attr "type" "milli")]) + "" + "* + return output_div_insn (operands, 0, insn);" + [(set_attr "type" "milli") + (set (attr "length") (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") + (const_int 0)) + (const_int 4) + (const_int 24)))]) (define_expand "udivsi3" [(set (reg:SI 26) (match_operand:SI 1 "move_operand" "")) (set (reg:SI 25) (match_operand:SI 2 "move_operand" "")) (parallel [(set (reg:SI 29) (udiv:SI (reg:SI 26) (reg:SI 25))) - (clobber (match_operand:SI 3 "register_operand" "")) + (clobber (match_dup 3)) (clobber (reg:SI 26)) (clobber (reg:SI 25)) (clobber (reg:SI 31))]) @@ -2121,7 +2308,7 @@ gen_rtx (UDIV, SImode, gen_rtx (REG, SImode, 26), gen_rtx (REG, SImode, 25))), - gen_rtx (CLOBBER, VOIDmode, operands[3]), + gen_rtx (CLOBBER, VOIDmode, operands[3]), gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 26)), gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 25)), gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 31))))); @@ -2137,16 +2324,20 @@ (clobber (reg:SI 26)) (clobber (reg:SI 25)) (clobber (reg:SI 31))] - "" - "* - return output_div_insn (operands, 1, insn);" - [(set_attr "type" "milli")]) + "" + "* + return output_div_insn (operands, 1, insn);" + [(set_attr "type" "milli") + (set (attr "length") (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") + (const_int 0)) + (const_int 4) + (const_int 24)))]) (define_expand "modsi3" [(set (reg:SI 26) (match_operand:SI 1 "move_operand" "")) (set (reg:SI 25) (match_operand:SI 2 "move_operand" "")) (parallel [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25))) - (clobber (match_operand:SI 3 "register_operand" "")) + (clobber (match_dup 3)) (clobber (reg:SI 26)) (clobber (reg:SI 25)) (clobber (reg:SI 31))]) @@ -2164,7 +2355,7 @@ gen_rtx (MOD, SImode, gen_rtx (REG, SImode, 26), gen_rtx (REG, SImode, 25))), - gen_rtx (CLOBBER, VOIDmode, operands[3]), + gen_rtx (CLOBBER, VOIDmode, operands[3]), gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 26)), gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 25)), gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 31))))); @@ -2181,13 +2372,17 @@ "" "* return output_mod_insn (0, insn);" - [(set_attr "type" "milli")]) + [(set_attr "type" "milli") + (set (attr "length") (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") + (const_int 0)) + (const_int 4) + (const_int 24)))]) (define_expand "umodsi3" [(set (reg:SI 26) (match_operand:SI 1 "move_operand" "")) (set (reg:SI 25) (match_operand:SI 2 "move_operand" "")) (parallel [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25))) - (clobber (match_operand:SI 3 "register_operand" "")) + (clobber (match_dup 3)) (clobber (reg:SI 26)) (clobber (reg:SI 25)) (clobber (reg:SI 31))]) @@ -2205,7 +2400,7 @@ gen_rtx (UMOD, SImode, gen_rtx (REG, SImode, 26), gen_rtx (REG, SImode, 25))), - gen_rtx (CLOBBER, VOIDmode, operands[3]), + gen_rtx (CLOBBER, VOIDmode, operands[3]), gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 26)), gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 25)), gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 31))))); @@ -2222,7 +2417,11 @@ "" "* return output_mod_insn (1, insn);" - [(set_attr "type" "milli")]) + [(set_attr "type" "milli") + (set (attr "length") (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") + (const_int 0)) + (const_int 4) + (const_int 24)))]) ;;- and instructions ;; We define DImode `and` so with DImode `not` we can get @@ -2249,9 +2448,11 @@ "and %1,%2,%0\;and %R1,%R2,%R0" [(set_attr "length" "8")]) +; The ? for op1 makes reload prefer zdepi instead of loading a huge +; constant with ldil;ldo. (define_insn "andsi3" [(set (match_operand:SI 0 "register_operand" "=r,r") - (and:SI (match_operand:SI 1 "register_operand" "%r,0") + (and:SI (match_operand:SI 1 "register_operand" "%?r,0") (match_operand:SI 2 "and_operand" "rO,P")))] "" "* return output_and (operands); " @@ -2393,107 +2594,107 @@ ;; Floating point arithmetic instructions. (define_insn "adddf3" - [(set (match_operand:DF 0 "register_operand" "=fx") - (plus:DF (match_operand:DF 1 "register_operand" "fx") - (match_operand:DF 2 "register_operand" "fx")))] + [(set (match_operand:DF 0 "register_operand" "=f") + (plus:DF (match_operand:DF 1 "register_operand" "f") + (match_operand:DF 2 "register_operand" "f")))] "" "fadd,dbl %1,%2,%0" [(set_attr "type" "fpalu")]) (define_insn "addsf3" - [(set (match_operand:SF 0 "register_operand" "=fx") - (plus:SF (match_operand:SF 1 "register_operand" "fx") - (match_operand:SF 2 "register_operand" "fx")))] + [(set (match_operand:SF 0 "register_operand" "=f") + (plus:SF (match_operand:SF 1 "register_operand" "f") + (match_operand:SF 2 "register_operand" "f")))] "" "fadd,sgl %1,%2,%0" [(set_attr "type" "fpalu")]) (define_insn "subdf3" - [(set (match_operand:DF 0 "register_operand" "=fx") - (minus:DF (match_operand:DF 1 "register_operand" "fx") - (match_operand:DF 2 "register_operand" "fx")))] + [(set (match_operand:DF 0 "register_operand" "=f") + (minus:DF (match_operand:DF 1 "register_operand" "f") + (match_operand:DF 2 "register_operand" "f")))] "" "fsub,dbl %1,%2,%0" [(set_attr "type" "fpalu")]) (define_insn "subsf3" - [(set (match_operand:SF 0 "register_operand" "=fx") - (minus:SF (match_operand:SF 1 "register_operand" "fx") - (match_operand:SF 2 "register_operand" "fx")))] + [(set (match_operand:SF 0 "register_operand" "=f") + (minus:SF (match_operand:SF 1 "register_operand" "f") + (match_operand:SF 2 "register_operand" "f")))] "" "fsub,sgl %1,%2,%0" [(set_attr "type" "fpalu")]) (define_insn "muldf3" - [(set (match_operand:DF 0 "register_operand" "=fx") - (mult:DF (match_operand:DF 1 "register_operand" "fx") - (match_operand:DF 2 "register_operand" "fx")))] + [(set (match_operand:DF 0 "register_operand" "=f") + (mult:DF (match_operand:DF 1 "register_operand" "f") + (match_operand:DF 2 "register_operand" "f")))] "" "fmpy,dbl %1,%2,%0" [(set_attr "type" "fpmul")]) (define_insn "mulsf3" - [(set (match_operand:SF 0 "register_operand" "=fx") - (mult:SF (match_operand:SF 1 "register_operand" "fx") - (match_operand:SF 2 "register_operand" "fx")))] + [(set (match_operand:SF 0 "register_operand" "=f") + (mult:SF (match_operand:SF 1 "register_operand" "f") + (match_operand:SF 2 "register_operand" "f")))] "" "fmpy,sgl %1,%2,%0" [(set_attr "type" "fpmul")]) (define_insn "divdf3" - [(set (match_operand:DF 0 "register_operand" "=fx") - (div:DF (match_operand:DF 1 "register_operand" "fx") - (match_operand:DF 2 "register_operand" "fx")))] + [(set (match_operand:DF 0 "register_operand" "=f") + (div:DF (match_operand:DF 1 "register_operand" "f") + (match_operand:DF 2 "register_operand" "f")))] "" "fdiv,dbl %1,%2,%0" [(set_attr "type" "fpdivdbl")]) (define_insn "divsf3" - [(set (match_operand:SF 0 "register_operand" "=fx") - (div:SF (match_operand:SF 1 "register_operand" "fx") - (match_operand:SF 2 "register_operand" "fx")))] + [(set (match_operand:SF 0 "register_operand" "=f") + (div:SF (match_operand:SF 1 "register_operand" "f") + (match_operand:SF 2 "register_operand" "f")))] "" "fdiv,sgl %1,%2,%0" [(set_attr "type" "fpdivsgl")]) (define_insn "negdf2" - [(set (match_operand:DF 0 "register_operand" "=fx") - (neg:DF (match_operand:DF 1 "register_operand" "fx")))] + [(set (match_operand:DF 0 "register_operand" "=f") + (neg:DF (match_operand:DF 1 "register_operand" "f")))] "" "fsub,dbl 0,%1,%0" [(set_attr "type" "fpalu")]) (define_insn "negsf2" - [(set (match_operand:SF 0 "register_operand" "=fx") - (neg:SF (match_operand:SF 1 "register_operand" "fx")))] + [(set (match_operand:SF 0 "register_operand" "=f") + (neg:SF (match_operand:SF 1 "register_operand" "f")))] "" "fsub,sgl 0,%1,%0" [(set_attr "type" "fpalu")]) (define_insn "absdf2" - [(set (match_operand:DF 0 "register_operand" "=fx") - (abs:DF (match_operand:DF 1 "register_operand" "fx")))] + [(set (match_operand:DF 0 "register_operand" "=f") + (abs:DF (match_operand:DF 1 "register_operand" "f")))] "" "fabs,dbl %1,%0" [(set_attr "type" "fpalu")]) (define_insn "abssf2" - [(set (match_operand:SF 0 "register_operand" "=fx") - (abs:SF (match_operand:SF 1 "register_operand" "fx")))] + [(set (match_operand:SF 0 "register_operand" "=f") + (abs:SF (match_operand:SF 1 "register_operand" "f")))] "" "fabs,sgl %1,%0" [(set_attr "type" "fpalu")]) (define_insn "sqrtdf2" - [(set (match_operand:DF 0 "register_operand" "=fx") - (sqrt:DF (match_operand:DF 1 "register_operand" "fx")))] + [(set (match_operand:DF 0 "register_operand" "=f") + (sqrt:DF (match_operand:DF 1 "register_operand" "f")))] "" "fsqrt,dbl %1,%0" [(set_attr "type" "fpsqrtdbl")]) (define_insn "sqrtsf2" - [(set (match_operand:SF 0 "register_operand" "=fx") - (sqrt:SF (match_operand:SF 1 "register_operand" "fx")))] + [(set (match_operand:SF 0 "register_operand" "=f") + (sqrt:SF (match_operand:SF 1 "register_operand" "f")))] "" "fsqrt,sgl %1,%0" [(set_attr "type" "fpsqrtsgl")]) @@ -2526,20 +2727,27 @@ (match_operand:SI 3 "shadd_operand" "")) (match_operand:SI 1 "register_operand" "r")))] "" - "sh%O3add %2,%1,%0") + "sh%O3addl %2,%1,%0") ;; This variant of the above insn can occur if the first operand ;; is the frame pointer. This is a kludge, but there doesn't ;; seem to be a way around it. Only recognize it while reloading. +;; Note how operand 3 uses a predicate of "const_int_operand", but +;; has constraints allowing a register. I don't know how this works, +;; but it somehow makes sure that out-of-range constants are placed +;; in a register which somehow magically is a "const_int_operand". +;; (this was stolen from alpha.md, I'm not going to try and change it. (define_insn "" - [(set (match_operand:SI 0 "register_operand" "=&r") - (plus:SI (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r") + [(set (match_operand:SI 0 "register_operand" "=&r,r") + (plus:SI (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r,r") (match_operand:SI 4 "shadd_operand" "")) - (match_operand:SI 1 "register_operand" "r")) - (match_operand:SI 3 "const_int_operand" "rI")))] + (match_operand:SI 1 "register_operand" "r,r")) + (match_operand:SI 3 "const_int_operand" "r,J")))] "reload_in_progress" - "sh%O4add %2,%1,%0\;add%I3 %3,%0,%0" + "@ + sh%O4addl %2,%1,%0\;addl %3,%0,%0 + sh%O4addl %2,%1,%0\;ldo %3(%0),%0" [(set_attr "type" "multi") (set_attr "length" "8")]) @@ -2560,7 +2768,7 @@ emit_insn (gen_zvdep32 (operands[0], operands[1], temp)); DONE; } - /* Make sure both inputs are not constants, + /* Make sure both inputs are not constants, the recognizer can't handle that. */ operands[1] = force_reg (SImode, operands[1]); }") @@ -2604,6 +2812,36 @@ return \"zvdepi %1,%2,%0\"; }") +(define_insn "vdepi_ior" + [(set (match_operand:SI 0 "register_operand" "=r") + (ior:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "") + (minus:SI (const_int 31) + (match_operand:SI 2 "register_operand" "q"))) + (match_operand:SI 3 "register_operand" "0")))] + ; accept ...0001...1, can this be generalized? + "exact_log2 (INTVAL (operands[1]) + 1) >= 0" + "* +{ + int x = INTVAL (operands[1]); + operands[2] = GEN_INT (exact_log2 (x + 1)); + return \"vdepi -1,%2,%0\"; +}") + +(define_insn "vdepi_and" + [(set (match_operand:SI 0 "register_operand" "=r") + (and:SI (rotate:SI (match_operand:SI 1 "const_int_operand" "") + (minus:SI (const_int 31) + (match_operand:SI 2 "register_operand" "q"))) + (match_operand:SI 3 "register_operand" "0")))] + ; this can be generalized...! + "INTVAL (operands[1]) == -2" + "* +{ + int x = INTVAL (operands[1]); + operands[2] = GEN_INT (exact_log2 ((~x) + 1)); + return \"vdepi 0,%2,%0\"; +}") + (define_expand "ashrsi3" [(set (match_operand:SI 0 "register_operand" "") (ashiftrt:SI (match_operand:SI 1 "register_operand" "") @@ -2727,7 +2965,7 @@ "bv%* 0(%%r2)" [(set_attr "type" "branch")]) -;; Use a different pattern for functions which have non-trivial +;; Use a different pattern for functions which have non-trivial ;; epilogues so as not to confuse jump and reorg. (define_insn "return_internal" [(use (reg:SI 2)) @@ -2746,7 +2984,7 @@ "" " { - /* Try to use the trivial return first. Else use the full + /* Try to use the trivial return first. Else use the full epilogue. */ if (hppa_can_use_return_insn_p ()) emit_jump_insn (gen_return ()); @@ -2782,7 +3020,7 @@ (set (attr "length") (cond [(eq (symbol_ref "jump_in_call_delay (insn)") (const_int 0)) (const_int 4) -;; If the jump is in the delay slot of a call, then its length depends +;; If the jump is in the delay slot of a call, then its length depends ;; on whether or not we can add the proper offset to %r2 with an ldo ;; instruction. (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) @@ -2850,22 +3088,26 @@ return \"sub,>> %0,%1,0\;blr,n %0,0\;b,n %l3\"; } }" - [(set_attr "length" "12")]) + [(set_attr "length" "12")]) ;; Need nops for the calls because execution is supposed to continue ;; past; we don't want to nullify an instruction that we need. ;;- jump to subroutine (define_expand "call" - [(parallel [(call (match_operand:SI 0 "" "") - (match_operand 1 "" "")) - (clobber (reg:SI 2))])] - "" - " + [(parallel [(call (match_operand:SI 0 "" "") + (match_operand 1 "" "")) + (clobber (reg:SI 2))])] + "" + " { rtx op; - - if (TARGET_LONG_CALLS) + + if (flag_pic) + emit_insn (gen_rtx (USE, VOIDmode, + gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM))); + + if (TARGET_LONG_CALLS) op = force_reg (SImode, XEXP (operands[0], 0)); else op = XEXP (operands[0], 0); @@ -2878,41 +3120,53 @@ if (GET_CODE (op) == SYMBOL_REF) emit_call_insn (gen_call_internal_symref (op, operands[1])); else - emit_call_insn (gen_call_internal_reg (op, operands[1])); + emit_call_insn (gen_call_internal_reg (force_reg (SImode, op), + operands[1])); if (flag_pic) { if (!hppa_save_pic_table_rtx) hppa_save_pic_table_rtx = gen_reg_rtx (Pmode); emit_insn (gen_rtx (SET, VOIDmode, - gen_rtx (REG, Pmode, 19), hppa_save_pic_table_rtx)); + gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM), + hppa_save_pic_table_rtx)); } DONE; }") (define_insn "call_internal_symref" - [(call (mem:SI (match_operand:SI 0 "call_operand_address" "")) - (match_operand 1 "" "i")) - (clobber (reg:SI 2)) - (use (const_int 0))] - "! TARGET_LONG_CALLS" - "* + [(call (mem:SI (match_operand:SI 0 "call_operand_address" "")) + (match_operand 1 "" "i")) + (clobber (reg:SI 2)) + (use (const_int 0))] + "! TARGET_LONG_CALLS" + "* { output_arg_descriptor (insn); return output_call (insn, operands[0], gen_rtx (REG, SImode, 2)); }" - [(set_attr "type" "call") - (set_attr "length" "4")]) + [(set_attr "type" "call") + (set_attr "length" "4")]) (define_insn "call_internal_reg" - [(call (mem:SI (match_operand:SI 0 "register_operand" "r")) - (match_operand 1 "" "i")) - (clobber (reg:SI 2)) - (use (const_int 1))] - "" - "copy %r0,%%r22\;.CALL\\tARGW0=GR\;bl $$dyncall,%%r31\;copy %%r31,%%r2" - [(set_attr "type" "dyncall") - (set_attr "length" "12")]) + [(call (mem:SI (match_operand:SI 0 "register_operand" "r")) + (match_operand 1 "" "i")) + (clobber (reg:SI 2)) + (use (const_int 1))] + "" + "* +{ + /* Yuk! bl may not be able to reach $$dyncall. */ + if (TARGET_LONG_CALLS) + return \"copy %r0,%%r22\;ldil L%%$$dyncall,%%r31\;ldo R%%$$dyncall(%%r31),%%r31\;blr 0,%%r2\;bv,n 0(%%r31)\;nop\"; + else + return \"copy %r0,%%r22\;.CALL\\tARGW0=GR\;bl $$dyncall,%%r31\;copy %%r31,%%r2\"; +}" + [(set_attr "type" "dyncall") + (set (attr "length") (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") + (const_int 0)) + (const_int 12) + (const_int 24)))]) (define_expand "call_value" [(parallel [(set (match_operand 0 "" "") @@ -2924,8 +3178,12 @@ " { rtx op; - - if (TARGET_LONG_CALLS) + + if (flag_pic) + emit_insn (gen_rtx (USE, VOIDmode, + gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM))); + + if (TARGET_LONG_CALLS) op = force_reg (SImode, XEXP (operands[1], 0)); else op = XEXP (operands[1], 0); @@ -2939,20 +3197,23 @@ emit_call_insn (gen_call_value_internal_symref (operands[0], op, operands[2])); else - emit_call_insn (gen_call_value_internal_reg (operands[0], op, operands[2])); + emit_call_insn (gen_call_value_internal_reg (operands[0], + force_reg (SImode, op), + operands[2])); if (flag_pic) { if (!hppa_save_pic_table_rtx) hppa_save_pic_table_rtx = gen_reg_rtx (Pmode); emit_insn (gen_rtx (SET, VOIDmode, - gen_rtx (REG, Pmode, 19), hppa_save_pic_table_rtx)); + gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM), + hppa_save_pic_table_rtx)); } DONE; }") (define_insn "call_value_internal_symref" - [(set (match_operand 0 "" "=rfx") + [(set (match_operand 0 "" "=rf") (call (mem:SI (match_operand:SI 1 "call_operand_address" "")) (match_operand 2 "" "i"))) (clobber (reg:SI 2)) @@ -2964,20 +3225,30 @@ output_arg_descriptor (insn); return output_call (insn, operands[1], gen_rtx (REG, SImode, 2)); }" - [(set_attr "type" "call") - (set_attr "length" "4")]) + [(set_attr "type" "call") + (set_attr "length" "4")]) (define_insn "call_value_internal_reg" - [(set (match_operand 0 "" "=rfx") + [(set (match_operand 0 "" "=rf") (call (mem:SI (match_operand:SI 1 "register_operand" "r")) (match_operand 2 "" "i"))) (clobber (reg:SI 2)) (use (const_int 1))] ;;- Don't use operand 1 for most machines. "" - "copy %r1,%%r22\;.CALL\\tARGW0=GR\;bl $$dyncall,%%r31\;copy %%r31,%%r2" - [(set_attr "type" "dyncall") - (set_attr "length" "12")]) + "* +{ + /* Yuk! bl may not be able to reach $$dyncall. */ + if (TARGET_LONG_CALLS) + return \"copy %r1,%%r22\;ldil L%%$$dyncall,%%r31\;ldo R%%$$dyncall(%%r31),%%r31\;blr 0,%%r2\;bv,n 0(%%r31)\;nop\"; + else + return \"copy %r1,%%r22\;.CALL\\tARGW0=GR\;bl $$dyncall,%%r31\;copy %%r31,%%r2\"; +}" + [(set_attr "type" "dyncall") + (set (attr "length") (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") + (const_int 0)) + (const_int 12) + (const_int 24)))]) ;; Call subroutine returning any type. @@ -3016,8 +3287,8 @@ (define_insn "indirect_jump" [(set (pc) (match_operand:SI 0 "register_operand" "r"))] "" - "bv%* 0(%0)" - [(set_attr "type" "branch")]) + "bv%* 0(%0)" + [(set_attr "type" "branch")]) (define_insn "extzv" [(set (match_operand:SI 0 "register_operand" "=r") @@ -3027,6 +3298,14 @@ "" "extru %1,%3+%2-1,%2,%0") +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=r") + (zero_extract:SI (match_operand:SI 1 "register_operand" "r") + (const_int 1) + (match_operand:SI 3 "register_operand" "q")))] + "" + "vextru %1,1,%0") + (define_insn "extv" [(set (match_operand:SI 0 "register_operand" "=r") (sign_extract:SI (match_operand:SI 1 "register_operand" "r") @@ -3035,6 +3314,14 @@ "" "extrs %1,%3+%2-1,%2,%0") +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=r") + (sign_extract:SI (match_operand:SI 1 "register_operand" "r") + (const_int 1) + (match_operand:SI 3 "register_operand" "q")))] + "" + "vextrs %1,1,%0") + (define_insn "insv" [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,r") (match_operand:SI 1 "uint5_operand" "") @@ -3069,7 +3356,7 @@ [(set (pc) (if_then_else (match_operator 2 "comparison_operator" - [(plus:SI (match_operand:SI 0 "register_operand" "+!r,!*f*x,!*m") + [(plus:SI (match_operand:SI 0 "register_operand" "+!r,!*f,!*m") (match_operand:SI 1 "int5_operand" "L,L,L")) (const_int 0)]) (label_ref (match_operand 3 "" "")) @@ -3079,7 +3366,7 @@ (clobber (match_scratch:SI 4 "=X,r,r"))] "" "* return output_dbra (operands, insn, which_alternative); " -;; Do not expect to understand this the first time through. +;; Do not expect to understand this the first time through. [(set_attr "type" "cbranch,multi,multi") (set (attr "length") (if_then_else (eq_attr "alternative" "0") @@ -3095,12 +3382,12 @@ ;; Extra goo to deal with additional reload insns. (if_then_else (eq_attr "alternative" "1") (if_then_else (lt (match_dup 3) (pc)) - (if_then_else + (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 24)))) (const_int 8188)) (const_int 24) (const_int 28)) - (if_then_else + (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) (const_int 8188)) (const_int 24) @@ -3108,25 +3395,25 @@ ;; Loop counter in memory case. ;; Extra goo to deal with additional reload insns. (if_then_else (lt (match_dup 3) (pc)) - (if_then_else + (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12)))) (const_int 8188)) (const_int 12) (const_int 16)) - (if_then_else + (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) (const_int 8188)) (const_int 12) (const_int 16))))))]) -;; Simply another variant of the dbra pattern. More restrictive +;; Simply another variant of the dbra pattern. More restrictive ;; in testing the comparison operator as it must worry about overflow ;; problems. (define_insn "" [(set (pc) (if_then_else (match_operator 2 "eq_neq_comparison_operator" - [(match_operand:SI 0 "register_operand" "+!r,!*f*x,!*m") + [(match_operand:SI 0 "register_operand" "+!r,!*f,!*m") (match_operand:SI 5 "const_int_operand" "")]) (label_ref (match_operand 3 "" "")) (pc))) @@ -3135,7 +3422,7 @@ (clobber (match_scratch:SI 4 "=X,r,r"))] "INTVAL (operands[5]) == - INTVAL (operands[1])" "* return output_dbra (operands, insn, which_alternative);" -;; Do not expect to understand this the first time through. +;; Do not expect to understand this the first time through. [(set_attr "type" "cbranch,multi,multi") (set (attr "length") (if_then_else (eq_attr "alternative" "0") @@ -3151,12 +3438,12 @@ ;; Extra goo to deal with additional reload insns. (if_then_else (eq_attr "alternative" "1") (if_then_else (lt (match_dup 3) (pc)) - (if_then_else + (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 24)))) (const_int 8188)) (const_int 24) (const_int 28)) - (if_then_else + (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) (const_int 8188)) (const_int 24) @@ -3164,12 +3451,12 @@ ;; Loop counter in memory case. ;; Extra goo to deal with additional reload insns. (if_then_else (lt (match_dup 3) (pc)) - (if_then_else + (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12)))) (const_int 8188)) (const_int 12) (const_int 16)) - (if_then_else + (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) (const_int 8188)) (const_int 12) @@ -3182,11 +3469,11 @@ [(match_operand:SI 1 "register_operand" "r,r,r") (const_int 0)]) (label_ref (match_operand 3 "" "")) (pc))) - (set (match_operand:SI 0 "register_operand" "=!r,!*f*x,!*m") + (set (match_operand:SI 0 "register_operand" "=!r,!*f,!*m") (match_dup 1))] "" "* return output_movb (operands, insn, which_alternative, 0); " -;; Do not expect to understand this the first time through. +;; Do not expect to understand this the first time through. [(set_attr "type" "cbranch,multi,multi") (set (attr "length") (if_then_else (eq_attr "alternative" "0") @@ -3202,19 +3489,19 @@ ;; Extra goo to deal with additional reload insns. (if_then_else (eq_attr "alternative" "1") (if_then_else (lt (match_dup 3) (pc)) - (if_then_else + (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12)))) (const_int 8188)) (const_int 12) (const_int 16)) - (if_then_else + (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) (const_int 8188)) (const_int 12) (const_int 16))) ;; Loop counter in memory case. ;; Extra goo to deal with additional reload insns. - (if_then_else + (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) (const_int 8188)) (const_int 8) @@ -3228,11 +3515,11 @@ [(match_operand:SI 1 "register_operand" "r,r,r") (const_int 0)]) (pc) (label_ref (match_operand 3 "" "")))) - (set (match_operand:SI 0 "register_operand" "=!r,!*f*x,!*m") + (set (match_operand:SI 0 "register_operand" "=!r,!*f,!*m") (match_dup 1))] "" "* return output_movb (operands, insn, which_alternative, 1); " -;; Do not expect to understand this the first time through. +;; Do not expect to understand this the first time through. [(set_attr "type" "cbranch,multi,multi") (set (attr "length") (if_then_else (eq_attr "alternative" "0") @@ -3248,37 +3535,37 @@ ;; Extra goo to deal with additional reload insns. (if_then_else (eq_attr "alternative" "1") (if_then_else (lt (match_dup 3) (pc)) - (if_then_else + (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12)))) (const_int 8188)) (const_int 12) (const_int 16)) - (if_then_else + (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) (const_int 8188)) (const_int 12) (const_int 16))) ;; Loop counter in memory case. ;; Extra goo to deal with additional reload insns. - (if_then_else + (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) (const_int 8188)) (const_int 8) (const_int 12)))))]) -;; The next four peepholes take advantage of the new 5 operand +;; The next four peepholes take advantage of the new 5 operand ;; fmpy{add,sub} instructions available on 1.1 CPUS. Basically ;; fmpyadd performs a multiply and add/sub of independent operands ;; at the same time. Because the operands must be independent ;; combine will not try to combine such insns... Thus we have ;; to use a peephole. (define_peephole - [(set (match_operand 0 "register_operand" "=fx") - (mult (match_operand 1 "register_operand" "fx") - (match_operand 2 "register_operand" "fx"))) - (set (match_operand 3 "register_operand" "+fx") - (plus (match_operand 4 "register_operand" "fx") - (match_operand 5 "register_operand" "fx")))] + [(set (match_operand 0 "register_operand" "=f") + (mult (match_operand 1 "register_operand" "f") + (match_operand 2 "register_operand" "f"))) + (set (match_operand 3 "register_operand" "+f") + (plus (match_operand 4 "register_operand" "f") + (match_operand 5 "register_operand" "f")))] "TARGET_SNAKE && fmpyaddoperands (operands)" "* { @@ -3298,13 +3585,13 @@ } }") -(define_peephole - [(set (match_operand 3 "register_operand" "+fx") - (plus (match_operand 4 "register_operand" "fx") - (match_operand 5 "register_operand" "fx"))) - (set (match_operand 0 "register_operand" "=fx") - (mult (match_operand 1 "register_operand" "fx") - (match_operand 2 "register_operand" "fx")))] +(define_peephole + [(set (match_operand 3 "register_operand" "+f") + (plus (match_operand 4 "register_operand" "f") + (match_operand 5 "register_operand" "f"))) + (set (match_operand 0 "register_operand" "=f") + (mult (match_operand 1 "register_operand" "f") + (match_operand 2 "register_operand" "f")))] "TARGET_SNAKE && fmpyaddoperands (operands)" "* { @@ -3327,12 +3614,12 @@ ;; Note fsub subtracts the second operand from the first while fmpysub ;; does the opposite for the subtraction operands! (define_peephole - [(set (match_operand 0 "register_operand" "=fx") - (mult (match_operand 1 "register_operand" "fx") - (match_operand 2 "register_operand" "fx"))) - (set (match_operand 3 "register_operand" "+fx") - (minus (match_operand 4 "register_operand" "fx") - (match_operand 5 "register_operand" "fx")))] + [(set (match_operand 0 "register_operand" "=f") + (mult (match_operand 1 "register_operand" "f") + (match_operand 2 "register_operand" "f"))) + (set (match_operand 3 "register_operand" "+f") + (minus (match_operand 4 "register_operand" "f") + (match_operand 5 "register_operand" "f")))] "TARGET_SNAKE && fmpysuboperands (operands)" "* { @@ -3343,12 +3630,12 @@ }") (define_peephole - [(set (match_operand 3 "register_operand" "+fx") - (minus (match_operand 4 "register_operand" "fx") - (match_operand 5 "register_operand" "fx"))) - (set (match_operand 0 "register_operand" "=fx") - (mult (match_operand 1 "register_operand" "fx") - (match_operand 2 "register_operand" "fx")))] + [(set (match_operand 3 "register_operand" "+f") + (minus (match_operand 4 "register_operand" "f") + (match_operand 5 "register_operand" "f"))) + (set (match_operand 0 "register_operand" "=f") + (mult (match_operand 1 "register_operand" "f") + (match_operand 2 "register_operand" "f")))] "TARGET_SNAKE && fmpysuboperands (operands)" "* {