--- gcc/config/m88k.md 2018/04/24 17:54:23 1.1.1.2 +++ gcc/config/m88k.md 2018/04/24 17:59:20 1.1.1.3 @@ -28,7 +28,7 @@ (define_expand "m88k_sccs_id" [(match_operand:SI 0 "" "")] "" - "{ static char sccs_id[] = \"@(#)m88k.md 2.0.3.4 20 Mar 1992 15:09:03\"; + "{ static char sccs_id[] = \"@(#)m88k.md 2.1.11.6 29 May 1992 10:55:49\"; FAIL; }") ;; Attribute specifications @@ -42,26 +42,34 @@ ; ; "branch,jump,call, ; flow-control instructions ; load,store,loada, ; data unit instructions -; spadd,dpadd,spdiv,dpdiv,idiv, ; FPU add instructions +; spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv, ; FPU add instructions ; spmul,dpmul,imul, ; FPU multiply instructions -; arith, ; integer unit instructions -; marith,mstore,mfp,weird" ; multi-word instructions +; arith,bit,mov ; integer unit instructions +; marith,mbit,mfp,weird" ; multi-word instructions ; Classification of each insn. Some insns of TYPE_BRANCH are multi-word. (define_attr "type" - "branch,jump,call,load,store,loada,spadd,dpadd,spdiv,dpdiv,idiv,spmul,dpmul,imul,arith,marith,mstore,mfp,weird" + "branch,jump,call,load,store,loada,spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv,spmul,dpmul,imul,arith,bit,mov,marith,mbit,mfp,weird" (const_string "arith")) ; Convenience attributes. +(define_attr "unit" "bit,memory,multiply,divide,fpadd,other" + (cond [(eq_attr "type" "bit,mbit") (const_string "bit") + (eq_attr "type" "load,store") (const_string "memory") + (eq_attr "type" "spmul,dpmul,imul") (const_string "multiply") + (eq_attr "type" "spdiv,dpdiv,idiv") (const_string "divide") + (eq_attr "type" "spadd,dpadd,spcmp,dpcmp,mfp") (const_string "fpadd")] + (const_string "other"))) + (define_attr "fpu" "yes,no" (if_then_else - (eq_attr "type" "spmul,dpmul,imul,spadd,dpadd,spdiv,dpdiv,idiv,mfp") + (eq_attr "type" "spmul,dpmul,imul,spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv,mfp") (const_string "yes") (const_string "no"))) ; Length in # of instructions of each insn. The values are not exact, but ; are safe. (define_attr "length" "" - (cond [(eq_attr "type" "marith,mstore,mfp") + (cond [(eq_attr "type" "marith,mbit,mfp") (const_int 2)] (const_int 1))) @@ -80,7 +88,7 @@ (define_delay (eq_attr "type" "branch,jump") [(and (and - (eq_attr "type" "!branch,jump,call,marith,mstore,mfp,weird") ; required. + (eq_attr "type" "!branch,jump,call,marith,mbit,mfp,weird") ; required. (eq_attr "type" "!load")) ; issue as-soon-as-possible. (eq_attr "fpu" "no")) ; issue as-soon-as-possible. (eq_attr "type" "!call,branch,jump") (nil)]) ; @@ was (const_int 1) @@ -89,7 +97,7 @@ ; a call. (@@ Support for this case is expected in reorg.c soon.) (define_delay (eq_attr "type" "call") - [(eq_attr "type" "!branch,call,marith,mstore,mfp,weird") ; required. + [(eq_attr "type" "!branch,call,marith,mbit,mfp,weird") ; required. (nil) (nil)]) ; An abstract block diagram of the function units for the m88100. @@ -137,10 +145,18 @@ ; Describing the alu is currently not useful. ;(define_function_unit "alu" 1 0 (eq_attr "type" -; "!store,mstore,marith,mfp,weird") 1 0) -;(define_function_unit "alu" 1 0 (eq_attr "type" "marith,weird") 2 0) +; "!store,marith,mbit,mfp,weird") 1 0) +;(define_function_unit "alu" 1 0 (eq_attr "type" "marith,mbit,weird") 2 0) -(define_function_unit "memory" 1 3 (eq_attr "type" "load") 3 2) +(define_function_unit "alu" 1 0 + (and (eq_attr "type" "loada,arith,bit,mov") (eq_attr "cpu" "!m88100")) 2 0) +(define_function_unit "alu" 1 0 + (and (eq_attr "type" "marith,mbit,weird") (eq_attr "cpu" "!m88100")) 4 0) + +(define_function_unit "memory" 1 3 + (and (eq_attr "type" "load") (eq_attr "cpu" "m88100")) 3 2) +(define_function_unit "memory" 1 3 + (and (eq_attr "type" "load") (eq_attr "cpu" "!m88100")) 4 2) ; The fp1 and fplast descriptions currently have no effect. ;(define_function_unit "fp1" 1 1 (eq_attr "fpu" "yes") 1 2) @@ -149,27 +165,50 @@ ; adjusted based on the actual generated code. The notation to the right ; is the total latency. A range denotes a group of instructions and/or ; conditions (the extra clock of fplast time with some sequences). -(define_function_unit "fpmul" 1 4 (eq_attr "type" "spmul") 4 2) ; 6-8 -(define_function_unit "fpmul" 1 4 (eq_attr "type" "dpmul,mfp") 7 2) ; 9-10 -(define_function_unit "fpmul" 1 4 (eq_attr "type" "imul") 3 2) ; 4 - -(define_function_unit "fpadd" 1 3 (eq_attr "type" "spadd") 3 2) ; 5-6 -(define_function_unit "fpadd" 1 3 (eq_attr "type" "dpadd") 4 2) ; 6-7 -(define_function_unit "fpadd" 1 3 (eq_attr "type" "spdiv") 30 2) ; 30-31 -(define_function_unit "fpadd" 1 3 (eq_attr "type" "dpdiv") 60 2) ; 60-61 -(define_function_unit "fpadd" 1 3 (eq_attr "type" "idiv") 38 2) ; 38 +(define_function_unit "fpmul" 1 4 + (and (eq_attr "type" "spmul") (eq_attr "cpu" "m88100")) 4 2) ; 6-8 +(define_function_unit "fpmul" 1 4 + (and (eq_attr "type" "dpmul,mfp") (eq_attr "cpu" "m88100")) 7 2) ; 9-10 +(define_function_unit "fpmul" 1 4 + (and (eq_attr "type" "imul") (eq_attr "cpu" "m88100")) 3 2) ; 4 + +(define_function_unit "fpmul" 1 4 + (and (eq_attr "type" "imul,spmul,dpmul,mfp") + (eq_attr "cpu" "!m88100")) 6 2) ; 3 + +(define_function_unit "fpadd" 1 3 + (and (eq_attr "type" "spadd,spcmp") (eq_attr "cpu" "m88100")) 3 2) ; 5-6 +(define_function_unit "fpadd" 1 3 + (and (eq_attr "type" "dpadd,dpcmp") (eq_attr "cpu" "m88100")) 4 2) ; 6-7 +(define_function_unit "fpadd" 1 3 + (and (eq_attr "type" "spdiv") (eq_attr "cpu" "m88100")) 30 2) ; 30-31 +(define_function_unit "fpadd" 1 3 + (and (eq_attr "type" "dpdiv") (eq_attr "cpu" "m88100")) 60 2) ; 60-61 +(define_function_unit "fpadd" 1 3 + (and (eq_attr "type" "idiv") (eq_attr "cpu" "m88100")) 38 2) ; 38 + +(define_function_unit "fpadd" 1 3 + (and (eq_attr "type" "spadd,dpadd") (eq_attr "cpu" "!m88100")) 6 2) ; 3 +(define_function_unit "fpadd" 1 3 + (and (eq_attr "type" "spcmp,dpcmp") (eq_attr "cpu" "!m88100")) 2 2) ; 3 +(define_function_unit "fpadd" 1 3 + (and (eq_attr "type" "spdiv") (eq_attr "cpu" "!m88100")) 26 2) ; 13 +(define_function_unit "fpadd" 1 3 + (and (eq_attr "type" "dpdiv") (eq_attr "cpu" "!m88100")) 46 2) ; 23 +(define_function_unit "fpadd" 1 3 + (and (eq_attr "type" "idiv") (eq_attr "cpu" "!m88100")) 36 2) ; 18 ;(define_function_unit "fplast" 1 1 (eq_attr "fpu" "yes") 1 2) ; Describing writeback contention is currently not useful. ;(define_function_unit "writeback" 1 1 -; (eq_attr "type" "!store,mstore,branch,jump,call") 0 1) +; (eq_attr "type" "!store,branch,jump,call") 0 1) ; Describing stores is currently not useful. The suggestion here is that the ; function unit ordering has already been established (writeback is last) and ; that store insns use the units in an unusual order. -;(define_function_unit "writeback" 1 1 (eq_attr "type" "store,mstore") 0 1) -;(define_function_unit "memory" 1 3 (eq_attr "type" "store,mstore") 1 2) +;(define_function_unit "writeback" 1 1 (eq_attr "type" "store") 0 1) +;(define_function_unit "memory" 1 3 (eq_attr "type" "store") 1 2) ;; This rich set of complex patterns are mostly due to Torbjorn Granlund ;; (tege@sics.se). They've changed since then, so don't complain to him @@ -194,7 +233,8 @@ operands[4] = gen_rtx (CONST_INT, SImode, INTVAL (operands[3]) - INTVAL (operands[2])); return \"ext %0,%1,%w3<%4>\"; /* <(%3-%2)> */ -}") +}" + [(set_attr "type" "bit")]) (define_insn "" [(set (match_operand:SI 0 "register_operand" "=r") @@ -207,7 +247,8 @@ operands[4] = gen_rtx (CONST_INT, SImode, INTVAL (operands[3]) - INTVAL (operands[2])); return \"extu %0,%1,%w3<%4>\"; /* <(%3-%2)> */ -}") +}" + [(set_attr "type" "bit")]) ;; Optimize possible cases of the set instruction. @@ -216,7 +257,8 @@ (ashift:SI (const_int -1) (match_operand:SI 1 "register_operand" "r")))] "" - "set %0,%#r0,%1") + "set %0,%#r0,%1" + [(set_attr "type" "bit")]) (define_insn "" [(set (match_operand:SI 0 "register_operand" "=r") @@ -224,7 +266,8 @@ (match_operand:SI 1 "register_operand" "r")) (match_operand:SI 2 "register_operand" "r")))] "" - "set %0,%2,%1") + "set %0,%2,%1" + [(set_attr "type" "bit")]) (define_insn "" [(set (match_operand:SI 0 "register_operand" "=r") @@ -232,7 +275,8 @@ (ashift:SI (const_int -1) (match_operand:SI 2 "register_operand" "r"))))] "" - "set %0,%1,%2") + "set %0,%1,%2" + [(set_attr "type" "bit")]) ;; Optimize possible cases of the mak instruction. @@ -248,7 +292,8 @@ exact_log2 (1 + (INTVAL (operands[3]) >> INTVAL(operands[2])))); return \"mak %0,%1,%4<%2>\"; -}") +}" + [(set_attr "type" "bit")]) ;; Optimize possible cases of output_and. @@ -266,7 +311,7 @@ ((1 << INTVAL (operands[2])) - 1) << INTVAL (operands[4])); return output_and (operands); }" - [(set_attr "type" "marith")]) ; length is 1 or 2. + [(set_attr "type" "marith")]) ; arith,bit,marith. length is 1 or 2. ;; Recognize bcnd instructions for integer values. This is distinguished ;; from a conditional branch instruction (below) with SImode instead of @@ -663,47 +708,53 @@ "cmp %0,%r1,%2") (define_insn "" - [(set (match_operand:CC 0 "register_operand" "=r,r") - (compare:CC (match_operand:SF 1 "register_operand" "r,r") - (match_operand:SF 2 "real_or_0_operand" "r,G")))] + [(set (match_operand:CC 0 "register_operand" "=r,r,r,r") + (compare:CC (match_operand:SF 1 "register_operand" "r,r,x,x") + (match_operand:SF 2 "real_or_0_operand" "r,G,x,G")))] "" "@ fcmp.sss %0,%1,%2 - fcmp.sss %0,%1,%#r0" - [(set_attr "type" "spadd")]) + fcmp.sss %0,%1,%#r0 + fcmp.sss %0,%1,%2 + fcmp.sss %0,%1,%#x0" + [(set_attr "type" "spcmp")]) (define_insn "" - [(set (match_operand:CC 0 "register_operand" "=r") - (compare:CC (match_operand:DF 1 "register_operand" "r") + [(set (match_operand:CC 0 "register_operand" "=r,r") + (compare:CC (match_operand:DF 1 "register_operand" "r,x") (float_extend:DF - (match_operand:SF 2 "register_operand" "r"))))] + (match_operand:SF 2 "register_operand" "r,x"))))] "" "fcmp.sds %0,%1,%2" - [(set_attr "type" "dpadd")]) + [(set_attr "type" "dpcmp")]) (define_insn "" - [(set (match_operand:CC 0 "register_operand" "=r") + [(set (match_operand:CC 0 "register_operand" "=r,r") (compare:CC (float_extend:DF - (match_operand:SF 1 "register_operand" "r")) - (match_operand:DF 2 "register_operand" "r")))] + (match_operand:SF 1 "register_operand" "r,x")) + (match_operand:DF 2 "register_operand" "r,x")))] "" "fcmp.ssd %0,%1,%2" - [(set_attr "type" "dpadd")]) + [(set_attr "type" "dpcmp")]) (define_insn "" - [(set (match_operand:CC 0 "register_operand" "=r,r") - (compare:CC (match_operand:DF 1 "register_operand" "r,r") - (match_operand:DF 2 "real_or_0_operand" "r,G")))] + [(set (match_operand:CC 0 "register_operand" "=r,r,r,r") + (compare:CC (match_operand:DF 1 "register_operand" "r,r,x,x") + (match_operand:DF 2 "real_or_0_operand" "r,G,x,G")))] "" "@ fcmp.sdd %0,%1,%2 - fcmp.sds %0,%1,%#r0" - [(set_attr "type" "dpadd")]) + fcmp.sds %0,%1,%#r0 + fcmp.sdd %0,%1,%2 + fcmp.sds %0,%1,%#x0" + [(set_attr "type" "dpcmp")]) ;; Store condition code insns. The compare insns set a register ;; rather than cc0 and record that register for use here. See above ;; for the special treatment of cmpsi with a constant operand. +;; @@ For the m88110, use fcmpu for bxx sxx inequality comparisons. + (define_expand "seq" [(set (match_operand:SI 0 "register_operand" "") (match_dup 1))] @@ -772,7 +823,8 @@ [(match_operand:CC 2 "register_operand" "r") (const_int 0)]))] "" - "ext %0,%2,1<%C1>") + "ext %0,%2,1<%C1>" + [(set_attr "type" "bit")]) (define_insn "" [(set (match_operand:SI 0 "register_operand" "=r") @@ -781,7 +833,8 @@ [(match_operand:CC 2 "register_operand" "r") (const_int 0)])))] "" - "extu %0,%2,1<%C1>") + "extu %0,%2,1<%C1>" + [(set_attr "type" "bit")]) ;; Conditional branch insns. The compare insns set a register ;; rather than cc0 and record that register for use here. See above @@ -947,7 +1000,13 @@ (match_operand 2 "pc_or_label_ref" "") (match_operand 3 "pc_or_label_ref" "")))] "" - "bb1%. %R3%C0,%1,%P2%P3" + "* +{ + if (mostly_false_jump (insn, operands[0])) + return \"bb0%. %R2%C0,%1,%P2%P3\"; + else + return \"bb1%. %R3%C0,%1,%P2%P3\"; +}" [(set_attr "type" "branch")]) ;; SImode move instructions @@ -963,8 +1022,8 @@ }") (define_insn "" - [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m,r,r") - (match_operand:SI 1 "move_operand" "rI,m,rO,J,M"))] + [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m,r,r,r,x,x,x,m") + (match_operand:SI 1 "move_operand" "rI,m,rO,J,M,x,r,x,m,x"))] "(register_operand (operands[0], SImode) || register_operand (operands[1], SImode) || operands[1] == const0_rtx)" @@ -973,8 +1032,13 @@ ld %0,%1 st %r1,%0 subu %0,%#r0,%n1 - set %0,%#r0,%s1" - [(set_attr "type" "arith,load,store,arith,arith")]) + set %0,%#r0,%s1 + mov.s %0,%1 + mov.s %0,%1 + mov %0,%1 + ld %0,%1 + st %1,%0" + [(set_attr "type" "arith,load,store,arith,bit,mov,mov,mov,load,store")]) (define_insn "" [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r") @@ -986,7 +1050,7 @@ or.u %0,%#r0,%X1 set %0,%#r0,%s1 or.u %0,%#r0,%X1\;or %0,%0,%x1" - [(set_attr "type" "arith,arith,arith,arith,marith")]) + [(set_attr "type" "arith,arith,arith,bit,marith")]) ;; @@ Why the constraint "in"? Doesn't `i' include `n'? (define_insn "" @@ -1079,21 +1143,28 @@ }") (define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") + [(set (match_operand:DI 0 "register_operand" "=r,x") (const_int 0))] "" - "or %0,%#r0,0\;or %d0,%#r0,0" - [(set_attr "type" "marith")]) + "@ + or %0,%#r0,0\;or %d0,%#r0,0 + mov %0,%#x0" + [(set_attr "type" "marith,mov")]) (define_insn "" - [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m") - (match_operand:DI 1 "nonimmediate_operand" "r,m,r"))] + [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,x,x,x,m") + (match_operand:DI 1 "nonimmediate_operand" "r,m,r,x,r,x,m,x"))] "" "@ or %0,%#r0,%1\;or %d0,%#r0,%d1 ld.d %0,%1 + st.d %1,%0 + mov.d %0,%1 + mov.d %0,%1 + mov %0,%1 + ld.d %0,%1 st.d %1,%0" - [(set_attr "type" "marith,load,store")]) + [(set_attr "type" "marith,load,store,mov,mov,mov,load,store")]) (define_insn "" [(set (match_operand:DI 0 "register_operand" "=r") @@ -1145,21 +1216,28 @@ ;}") (define_insn "" - [(set (match_operand:DF 0 "register_operand" "=r") + [(set (match_operand:DF 0 "register_operand" "=r,x") (const_int 0))] "" - "or %0,%#r0,0\;or %d0,%#r0,0" - [(set_attr "type" "marith")]) + "@ + or %0,%#r0,0\;or %d0,%#r0,0 + mov %0,%#x0" + [(set_attr "type" "marith,mov")]) (define_insn "" - [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m") - (match_operand:DF 1 "nonimmediate_operand" "r,m,r"))] + [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,x,r,x,x,m") + (match_operand:DF 1 "nonimmediate_operand" "r,m,r,r,x,x,m,x"))] "" "@ or %0,%#r0,%1\;or %d0,%#r0,%d1 ld.d %0,%1 + st.d %1,%0 + mov.d %0,%1 + mov.d %0,%1 + mov %0,%1 + ld.d %0,%1 st.d %1,%0" - [(set_attr "type" "marith,load,store")]) + [(set_attr "type" "marith,load,store,mov,mov,mov,load,store")]) (define_insn "" [(set (match_operand:DF 0 "register_operand" "=r") @@ -1190,20 +1268,28 @@ ;; @@ What happens to fconst0_rtx? (define_insn "" - [(set (match_operand:SF 0 "register_operand" "=r") + [(set (match_operand:SF 0 "register_operand" "=r,x") (const_int 0))] "" - "or %0,%#r0,0") + "@ + or %0,%#r0,0 + mov %0,%#x0" + [(set_attr "type" "arith,mov")]) (define_insn "" - [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m") - (match_operand:SF 1 "nonimmediate_operand" "r,m,r"))] + [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,x,r,x,x,m") + (match_operand:SF 1 "nonimmediate_operand" "r,m,r,r,x,x,m,x"))] "" "@ or %0,%#r0,%1 ld %0,%1 + st %r1,%0 + mov.s %0,%1 + mov.s %0,%1 + mov %0,%1 + ld %0,%1 st %r1,%0" - [(set_attr "type" "arith,load,store")]) + [(set_attr "type" "arith,load,store,mov,mov,mov,load,store")]) (define_insn "" [(set (match_operand:SF 0 "register_operand" "=r") @@ -1244,7 +1330,6 @@ ;; operand 3 is the offset for the source and destination pointers ;; operand 4 is the first value to be loaded ;; operand 5 is the register to hold the value (r4 or r5) -;; Upon completion, r2 and r3 are unchanged (define_expand "call_block_move" [(set (reg:SI 3) (minus:SI (match_operand:SI 2 "register_operand" "r") @@ -1255,13 +1340,10 @@ (match_dup 3))) (use (reg:SI 2)) (use (reg:SI 3)) - (use (reg:SI 4)) - (use (reg:SI 5)) + (use (match_dup 5)) (parallel [(call (mem:SI (match_operand 0 "" "")) (const_int 0)) - (use (reg:SI 1))]) - (clobber (reg:SI 4)) - (clobber (reg:SI 5))] + (clobber (reg:SI 1))])] "" "") @@ -1279,15 +1361,11 @@ (set (reg:SI 6) (match_operand:SI 6 "immediate_operand" "i")) (use (reg:SI 2)) (use (reg:SI 3)) - (use (reg:SI 4)) - (use (reg:SI 5)) + (use (match_dup 5)) (use (reg:SI 6)) (parallel [(call (mem:SI (match_operand 0 "" "")) (const_int 0)) - (use (reg:SI 1))]) - (clobber (reg:SI 4)) - (clobber (reg:SI 5)) - (clobber (reg:SI 6))] + (clobber (reg:SI 1))])] "" "") @@ -1396,7 +1474,7 @@ or %0,%#r0,%h1 subu %0,%#r0,%H1 ld.h %0,%1" - [(set_attr "type" "arith,arith,arith,load")]) + [(set_attr "type" "bit,arith,arith,load")]) (define_expand "extendqihi2" [(set (match_operand:HI 0 "register_operand" "") @@ -1419,7 +1497,7 @@ or %0,%#r0,%q1 subu %0,%#r0,%Q1 ld.b %0,%1" - [(set_attr "type" "arith,arith,arith,load")]) + [(set_attr "type" "bit,arith,arith,load")]) (define_expand "extendqisi2" [(set (match_operand:SI 0 "register_operand" "") @@ -1442,7 +1520,7 @@ or %0,%#r0,%q1 subu %0,%#r0,%Q1 ld.b %0,%1" - [(set_attr "type" "arith,arith,arith,load")]) + [(set_attr "type" "bit,arith,arith,load")]) ;; Conversions between float and double. @@ -1450,49 +1528,75 @@ ;; convert between float and double. In particular, the sign of -0 is ;; not preserved. Interestingly, fsub does conform. -(define_insn "extendsfdf2" +(define_expand "extendsfdf2" [(set (match_operand:DF 0 "register_operand" "=r") (float_extend:DF (match_operand:SF 1 "register_operand" "r")))] "" + "") + +(define_insn "" + [(set (match_operand:DF 0 "register_operand" "=r") + (float_extend:DF (match_operand:SF 1 "register_operand" "r")))] + "! TARGET_88110" "fsub.dss %0,%1,%#r0" [(set_attr "type" "spadd")]) -(define_insn "truncdfsf2" +(define_insn "" + [(set (match_operand:DF 0 "register_operand" "=r,x") + (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")))] + "TARGET_88110" + "fcvt.ds %0,%1" + [(set_attr "type" "spadd")]) + +(define_expand "truncdfsf2" [(set (match_operand:SF 0 "register_operand" "=r") (float_truncate:SF (match_operand:DF 1 "register_operand" "r")))] "" + "") + +(define_insn "" + [(set (match_operand:SF 0 "register_operand" "=r") + (float_truncate:SF (match_operand:DF 1 "register_operand" "r")))] + "! TARGET_88110" "fsub.sds %0,%1,%#r0" [(set_attr "type" "dpadd")]) +(define_insn "" + [(set (match_operand:SF 0 "register_operand" "=r,x") + (float_truncate:SF (match_operand:DF 1 "register_operand" "r,x")))] + "TARGET_88110" + "fcvt.sd %0,%1" + [(set_attr "type" "dpadd")]) + ;; Conversions between floating point and integer (define_insn "floatsidf2" - [(set (match_operand:DF 0 "register_operand" "=r") - (float:DF (match_operand:SI 1 "register_operand" "r")))] + [(set (match_operand:DF 0 "register_operand" "=r,x") + (float:DF (match_operand:SI 1 "register_operand" "r,r")))] "" "flt.ds %0,%1" - [(set_attr "type" "spadd")]) + [(set_attr "type" "spadd,dpadd")]) (define_insn "floatsisf2" - [(set (match_operand:SF 0 "register_operand" "=r") - (float:SF (match_operand:SI 1 "register_operand" "r")))] + [(set (match_operand:SF 0 "register_operand" "=r,x") + (float:SF (match_operand:SI 1 "register_operand" "r,r")))] "" "flt.ss %0,%1" - [(set_attr "type" "spadd")]) + [(set_attr "type" "spadd,spadd")]) (define_insn "fix_truncdfsi2" - [(set (match_operand:SI 0 "register_operand" "=r") - (fix:SI (match_operand:DF 1 "register_operand" "r")))] + [(set (match_operand:SI 0 "register_operand" "=r,x") + (fix:SI (match_operand:DF 1 "register_operand" "r,r")))] "" "trnc.sd %0,%1" - [(set_attr "type" "dpadd")]) + [(set_attr "type" "dpadd,dpadd")]) (define_insn "fix_truncsfsi2" - [(set (match_operand:SI 0 "register_operand" "=r") - (fix:SI (match_operand:SF 1 "register_operand" "r")))] + [(set (match_operand:SI 0 "register_operand" "=r,x") + (fix:SI (match_operand:SF 1 "register_operand" "r,r")))] "" "trnc.ss %0,%1" - [(set_attr "type" "spadd")]) + [(set_attr "type" "spadd,dpadd")]) ;;- arithmetic instructions @@ -1539,9 +1643,9 @@ ;; requires double rounding, whereas the 88000 instruction only rounds once. (define_expand "adddf3" - [(set (match_operand:DF 0 "register_operand" "=r") - (plus:DF (match_operand:DF 1 "general_operand" "%r") - (match_operand:DF 2 "general_operand" "r")))] + [(set (match_operand:DF 0 "register_operand" "=r,x") + (plus:DF (match_operand:DF 1 "general_operand" "%r,x") + (match_operand:DF 2 "general_operand" "r,x")))] "" " { @@ -1550,41 +1654,41 @@ }") (define_insn "" - [(set (match_operand:DF 0 "register_operand" "=r") - (plus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r")) - (float_extend:DF (match_operand:SF 2 "register_operand" "r"))))] + [(set (match_operand:DF 0 "register_operand" "=r,x") + (plus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")) + (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))] "" "fadd.dss %0,%1,%2" [(set_attr "type" "spadd")]) (define_insn "" - [(set (match_operand:DF 0 "register_operand" "=r") - (plus:DF (match_operand:DF 1 "register_operand" "r") - (float_extend:DF (match_operand:SF 2 "register_operand" "r"))))] + [(set (match_operand:DF 0 "register_operand" "=r,x") + (plus:DF (match_operand:DF 1 "register_operand" "r,x") + (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))] "" "fadd.dds %0,%1,%2" [(set_attr "type" "dpadd")]) (define_insn "" - [(set (match_operand:DF 0 "register_operand" "=r") - (plus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r")) - (match_operand:DF 2 "register_operand" "r")))] + [(set (match_operand:DF 0 "register_operand" "=r,x") + (plus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")) + (match_operand:DF 2 "register_operand" "r,x")))] "" "fadd.dsd %0,%1,%2" [(set_attr "type" "dpadd")]) (define_insn "" - [(set (match_operand:DF 0 "register_operand" "=r") - (plus:DF (match_operand:DF 1 "register_operand" "%r") - (match_operand:DF 2 "register_operand" "r")))] + [(set (match_operand:DF 0 "register_operand" "=r,x") + (plus:DF (match_operand:DF 1 "register_operand" "%r,x") + (match_operand:DF 2 "register_operand" "r,x")))] "" "fadd.ddd %0,%1,%2" [(set_attr "type" "dpadd")]) (define_insn "addsf3" - [(set (match_operand:SF 0 "register_operand" "=r") - (plus:SF (match_operand:SF 1 "register_operand" "%r") - (match_operand:SF 2 "register_operand" "r")))] + [(set (match_operand:SF 0 "register_operand" "=r,x") + (plus:SF (match_operand:SF 1 "register_operand" "%r,x") + (match_operand:SF 2 "register_operand" "r,x")))] "" "fadd.sss %0,%1,%2" [(set_attr "type" "spadd")]) @@ -1630,9 +1734,9 @@ ;; requires double rounding, whereas the 88000 instruction only rounds once. (define_expand "subdf3" - [(set (match_operand:DF 0 "register_operand" "=r") - (minus:DF (match_operand:DF 1 "general_operand" "r") - (match_operand:DF 2 "general_operand" "r")))] + [(set (match_operand:DF 0 "register_operand" "=r,x") + (minus:DF (match_operand:DF 1 "general_operand" "r,x") + (match_operand:DF 2 "general_operand" "r,x")))] "" " { @@ -1641,41 +1745,41 @@ }") (define_insn "" - [(set (match_operand:DF 0 "register_operand" "=r") - (minus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r")) - (float_extend:DF (match_operand:SF 2 "register_operand" "r"))))] + [(set (match_operand:DF 0 "register_operand" "=r,x") + (minus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")) + (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))] "" "fsub.dss %0,%1,%2" [(set_attr "type" "spadd")]) (define_insn "" - [(set (match_operand:DF 0 "register_operand" "=r") - (minus:DF (match_operand:DF 1 "register_operand" "r") - (float_extend:DF (match_operand:SF 2 "register_operand" "r"))))] + [(set (match_operand:DF 0 "register_operand" "=r,x") + (minus:DF (match_operand:DF 1 "register_operand" "r,x") + (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))] "" "fsub.dds %0,%1,%2" [(set_attr "type" "dpadd")]) (define_insn "" - [(set (match_operand:DF 0 "register_operand" "=r") - (minus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r")) - (match_operand:DF 2 "register_operand" "r")))] + [(set (match_operand:DF 0 "register_operand" "=r,x") + (minus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")) + (match_operand:DF 2 "register_operand" "r,x")))] "" "fsub.dsd %0,%1,%2" [(set_attr "type" "dpadd")]) (define_insn "" - [(set (match_operand:DF 0 "register_operand" "=r") - (minus:DF (match_operand:DF 1 "register_operand" "r") - (match_operand:DF 2 "register_operand" "r")))] + [(set (match_operand:DF 0 "register_operand" "=r,x") + (minus:DF (match_operand:DF 1 "register_operand" "r,x") + (match_operand:DF 2 "register_operand" "r,x")))] "" "fsub.ddd %0,%1,%2" [(set_attr "type" "dpadd")]) (define_insn "subsf3" - [(set (match_operand:SF 0 "register_operand" "=r") - (minus:SF (match_operand:SF 1 "register_operand" "r") - (match_operand:SF 2 "register_operand" "r")))] + [(set (match_operand:SF 0 "register_operand" "=r,x") + (minus:SF (match_operand:SF 1 "register_operand" "r,x") + (match_operand:SF 2 "register_operand" "r,x")))] "" "fsub.sss %0,%1,%2" [(set_attr "type" "spadd")]) @@ -1720,15 +1824,23 @@ "mul %0,%1,%2" [(set_attr "type" "imul")]) +(define_insn "umulsidi3" + [(set (match_operand:DI 0 "register_operand" "=r") + (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%r")) + (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))] + "TARGET_88110" + "mulu.d %0,%1,%2" + [(set_attr "type" "imul")]) + ;; patterns for mixed mode floating point ;; Do not define patterns that utilize mixed mode arithmetic that result ;; in narrowing the precision, because it loses accuracy, since the standard ;; requires double rounding, whereas the 88000 instruction only rounds once. (define_expand "muldf3" - [(set (match_operand:DF 0 "register_operand" "=r") - (mult:DF (match_operand:DF 1 "general_operand" "%r") - (match_operand:DF 2 "general_operand" "r")))] + [(set (match_operand:DF 0 "register_operand" "=r,x") + (mult:DF (match_operand:DF 1 "general_operand" "%r,x") + (match_operand:DF 2 "general_operand" "r,x")))] "" " { @@ -1737,41 +1849,41 @@ }") (define_insn "" - [(set (match_operand:DF 0 "register_operand" "=r") - (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r")) - (float_extend:DF (match_operand:SF 2 "register_operand" "r"))))] + [(set (match_operand:DF 0 "register_operand" "=r,x") + (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")) + (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))] "" "fmul.dss %0,%1,%2" [(set_attr "type" "spmul")]) (define_insn "" - [(set (match_operand:DF 0 "register_operand" "=r") - (mult:DF (match_operand:DF 1 "register_operand" "r") - (float_extend:DF (match_operand:SF 2 "register_operand" "r"))))] + [(set (match_operand:DF 0 "register_operand" "=r,x") + (mult:DF (match_operand:DF 1 "register_operand" "r,x") + (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))] "" "fmul.dds %0,%1,%2" [(set_attr "type" "spmul")]) (define_insn "" - [(set (match_operand:DF 0 "register_operand" "=r") - (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r")) - (match_operand:DF 2 "register_operand" "r")))] + [(set (match_operand:DF 0 "register_operand" "=r,x") + (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")) + (match_operand:DF 2 "register_operand" "r,x")))] "" "fmul.dsd %0,%1,%2" [(set_attr "type" "spmul")]) (define_insn "" - [(set (match_operand:DF 0 "register_operand" "=r") - (mult:DF (match_operand:DF 1 "register_operand" "%r") - (match_operand:DF 2 "register_operand" "r")))] + [(set (match_operand:DF 0 "register_operand" "=r,x") + (mult:DF (match_operand:DF 1 "register_operand" "%r,x") + (match_operand:DF 2 "register_operand" "r,x")))] "" "fmul.ddd %0,%1,%2" [(set_attr "type" "dpmul")]) (define_insn "mulsf3" - [(set (match_operand:SF 0 "register_operand" "=r") - (mult:SF (match_operand:SF 1 "register_operand" "%r") - (match_operand:SF 2 "register_operand" "r")))] + [(set (match_operand:SF 0 "register_operand" "=r,x") + (mult:SF (match_operand:SF 1 "register_operand" "%r,x") + (match_operand:SF 2 "register_operand" "r,x")))] "" "fmul.sss %0,%1,%2" [(set_attr "type" "spmul")]) @@ -2060,9 +2172,9 @@ ;; requires double rounding, whereas the 88000 instruction only rounds once. (define_expand "divdf3" - [(set (match_operand:DF 0 "register_operand" "=r") - (div:DF (match_operand:DF 1 "general_operand" "r") - (match_operand:DF 2 "general_operand" "r")))] + [(set (match_operand:DF 0 "register_operand" "=r,x") + (div:DF (match_operand:DF 1 "general_operand" "r,x") + (match_operand:DF 2 "general_operand" "r,x")))] "" " { @@ -2080,41 +2192,41 @@ }") (define_insn "" - [(set (match_operand:DF 0 "register_operand" "=r") - (div:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r")) - (float_extend:DF (match_operand:SF 2 "register_operand" "r"))))] + [(set (match_operand:DF 0 "register_operand" "=r,x") + (div:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")) + (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))] "" "fdiv.dss %0,%1,%2" [(set_attr "type" "dpdiv")]) (define_insn "" - [(set (match_operand:DF 0 "register_operand" "=r") - (div:DF (match_operand:DF 1 "register_operand" "r") - (float_extend:DF (match_operand:SF 2 "register_operand" "r"))))] + [(set (match_operand:DF 0 "register_operand" "=r,x") + (div:DF (match_operand:DF 1 "register_operand" "r,x") + (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))] "" "fdiv.dds %0,%1,%2" [(set_attr "type" "dpdiv")]) (define_insn "" - [(set (match_operand:DF 0 "register_operand" "=r") - (div:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r")) - (match_operand:DF 2 "register_operand" "r")))] + [(set (match_operand:DF 0 "register_operand" "=r,x") + (div:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")) + (match_operand:DF 2 "register_operand" "r,x")))] "" "fdiv.dsd %0,%1,%2" [(set_attr "type" "dpdiv")]) (define_insn "divsf3" - [(set (match_operand:SF 0 "register_operand" "=r") - (div:SF (match_operand:SF 1 "register_operand" "r") - (match_operand:SF 2 "register_operand" "r")))] + [(set (match_operand:SF 0 "register_operand" "=r,x") + (div:SF (match_operand:SF 1 "register_operand" "r,x") + (match_operand:SF 2 "register_operand" "r,x")))] "" "fdiv.sss %0,%1,%2" [(set_attr "type" "spdiv")]) (define_insn "" - [(set (match_operand:DF 0 "register_operand" "=r") - (div:DF (match_operand:DF 1 "register_operand" "r") - (match_operand:DF 2 "register_operand" "r")))] + [(set (match_operand:DF 0 "register_operand" "=r,x") + (div:DF (match_operand:DF 1 "register_operand" "r,x") + (match_operand:DF 2 "register_operand" "r,x")))] "" "fdiv.ddd %0,%1,%2" [(set_attr "type" "dpdiv")]) @@ -2288,7 +2400,7 @@ or.u %0,%1,%X2 set %0,%1,%s2 or.u %0,%1,%X2\;or %0,%0,%x2" - [(set_attr "type" "arith,arith,arith,marith")]) + [(set_attr "type" "arith,arith,bit,marith")]) (define_insn "" [(set (match_operand:DI 0 "register_operand" "=r") @@ -2508,7 +2620,8 @@ "" "@ mak %0,%1,%2 - mak %0,%1,0<%2>") + mak %0,%1,0<%2>" + [(set_attr "type" "bit")]) (define_expand "ashrsi3" [(set (match_operand:SI 0 "register_operand" "") @@ -2552,7 +2665,8 @@ "" "@ ext %0,%1,%2 - ext %0,%1,0<%2>") + ext %0,%1,0<%2>" + [(set_attr "type" "bit")]) ;;- logical shift instructions. Logical shift left becomes arithmetic ;; shift left. LSHIFT is not normally produced, but is supported. @@ -2575,7 +2689,8 @@ "" "@ mak %0,%1,%2 - mak %0,%1,0<%2>") + mak %0,%1,0<%2>" + [(set_attr "type" "bit")]) (define_expand "lshrsi3" [(set (match_operand:SI 0 "register_operand" "") @@ -2617,7 +2732,8 @@ "" "@ extu %0,%1,%2 - extu %0,%1,0<%2>") + extu %0,%1,0<%2>" + [(set_attr "type" "bit")]) ;;- rotate instructions @@ -2645,7 +2761,8 @@ (rotatert:SI (match_operand:SI 1 "register_operand" "r") (match_operand:SI 2 "arith_operand" "rI")))] "" - "rot %0,%1,%2") + "rot %0,%1,%2" + [(set_attr "type" "bit")]) ;; Bit field instructions. @@ -2668,7 +2785,8 @@ operands[4] = gen_rtx (CONST_INT, SImode, (32 - INTVAL (operands[2])) - INTVAL (operands[3])); return \"ext %0,%1,%2<%4>\"; /* <(32-%2-%3)> */ -}") +}" + [(set_attr "type" "bit")]) (define_insn "" [(set (match_operand:SI 0 "register_operand" "=r") @@ -2689,7 +2807,8 @@ operands[4] = gen_rtx (CONST_INT, SImode, (32 - INTVAL (operands[2])) - INTVAL (operands[3])); return \"extu %0,%1,%2<%4>\"; /* <(32-%2-%3)> */ -}") +}" + [(set_attr "type" "bit")]) (define_insn "" [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") @@ -2702,7 +2821,8 @@ operands[3] = gen_rtx (CONST_INT, SImode, (32 - INTVAL (operands[1])) - INTVAL (operands[2])); return \"clr %0,%0,%1<%3>\"; /* <(32-%1-%2)> */ -}") +}" + [(set_attr "type" "bit")]) (define_insn "" [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") @@ -2715,7 +2835,8 @@ operands[3] = gen_rtx (CONST_INT, SImode, (32 - INTVAL (operands[1])) - INTVAL (operands[2])); return \"set %0,%0,%1<%3>\"; /* <(32-%1-%2)> */ -}") +}" + [(set_attr "type" "bit")]) (define_insn "" [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") @@ -2754,10 +2875,12 @@ "subu %0,%#r0,%1") (define_insn "" - [(set (match_operand:SF 0 "register_operand" "=r") - (float_truncate:SF (neg:DF (match_operand:DF 1 "register_operand" "r"))))] + [(set (match_operand:SF 0 "register_operand" "=r,x") + (float_truncate:SF (neg:DF (match_operand:DF 1 "register_operand" "r,x"))))] "" - "fsub.ssd %0,%#r0,%1" + "@ + fsub.ssd %0,%#r0,%1 + fsub.ssd %0,%#x0,%1" [(set_attr "type" "dpadd")]) (define_insn "" @@ -2822,22 +2945,45 @@ { register rtx index_diff = gen_reg_rtx (SImode); register rtx low = gen_rtx (CONST_INT, VOIDmode, -INTVAL (operands[1])); + register rtx label = gen_rtx (LABEL_REF, VOIDmode, operands[3]); + register rtx base; + + if (! CASE_VECTOR_INSNS) + /* These instructions are likely to be scheduled and made loop invariant. + This decreases the cost of the dispatch at the expense of the default + case. */ + base = force_reg (SImode, memory_address_noforce (SImode, label)); /* Compute the index difference and handle the default case. */ emit_insn (gen_addsi3 (index_diff, force_reg (SImode, operands[0]), ADD_INT (low) ? low : force_reg (SImode, low))); emit_insn (gen_cmpsi (index_diff, operands[2])); + /* It's possible to replace this branch with sgtu/iorsi3 and adding a -1 + entry to the table. However, that doesn't seem to win on the m88110. */ emit_jump_insn (gen_bgtu (operands[4])); - /* Call the jump that will branch to the appropriate case. */ - emit_jump_insn (gen_casesi_enter (gen_rtx (LABEL_REF, VOIDmode, operands[3]), - index_diff, - operands[3])); - /* Claim that flow drops into the table so it will be adjacent. */ + if (CASE_VECTOR_INSNS) + /* Call the jump that will branch to the appropriate case. */ + emit_jump_insn (gen_casesi_enter (label, index_diff, operands[3])); + else + /* Load the table entry and jump to it. */ + emit_jump_insn (gen_casesi_jump (gen_reg_rtx (SImode), base, index_diff)); + + /* Claim that flow drops into the table so it will be adjacent by not + emitting a barrier. */ DONE; }") +(define_expand "casesi_jump" + [(set (match_operand:SI 0 "" "") + (mem:SI (plus:SI (match_operand:SI 1 "" "") + (mult:SI (match_operand:SI 2 "" "") + (const_int 4))))) + (set (pc) (match_dup 0))] + "" + "") + ;; The bsr.n instruction is directed to the END of the table. See ;; ASM_OUTPUT_CASE_END. @@ -2863,7 +3009,7 @@ (define_expand "call" [(parallel [(call (match_operand:SI 0 "" "") (match_operand 1 "" "")) - (use (reg:SI 1))])] + (clobber (reg:SI 1))])] "" " { @@ -2876,7 +3022,7 @@ (define_insn "" [(parallel [(call (mem:SI (match_operand:SI 0 "call_address_operand" "rQ")) (match_operand 1 "" "")) - (use (reg:SI 1))])] + (clobber (reg:SI 1))])] "" "* return output_call (operands, operands[0]);" [(set_attr "type" "call")]) @@ -2885,7 +3031,7 @@ [(parallel [(set (match_operand 0 "register_operand" "") (call (match_operand:SI 1 "" "") (match_operand 2 "" ""))) - (use (reg:SI 1))])] + (clobber (reg:SI 1))])] "" " { @@ -2900,7 +3046,7 @@ (call (mem:SI (match_operand:SI 1 "call_address_operand" "rQ")) (match_operand 2 "" ""))) - (use (reg:SI 1))])] + (clobber (reg:SI 1))])] "" "* return output_call (operands, operands[1]);" [(set_attr "type" "call")]) @@ -2910,19 +3056,20 @@ (define_insn "nop" [(const_int 0)] "" - "ff0 %#r0,%#r0") + "ff0 %#r0,%#r0" + [(set_attr "type" "bit")]) (define_insn "return" [(return)] "null_epilogue ()" "jmp%. %#r1" - [(set_attr "type" "branch")]) + [(set_attr "type" "jump")]) (define_insn "indirect_jump" [(set (pc) (match_operand:SI 0 "register_operand" "r"))] "" "jmp%. %0" - [(set_attr "type" "branch")]) + [(set_attr "type" "jump")]) (define_insn "jump" [(set (pc)