1;; Machine description of the Synopsys DesignWare ARC cpu Floating Point 2;; extensions for GNU C compiler 3;; Copyright (C) 2007-2021 Free Software Foundation, Inc. 4 5;; This file is part of GCC. 6 7;; GCC is free software; you can redistribute it and/or modify 8;; it under the terms of the GNU General Public License as published by 9;; the Free Software Foundation; either version 3, or (at your option) 10;; any later version. 11 12;; GCC is distributed in the hope that it will be useful, 13;; but WITHOUT ANY WARRANTY; without even the implied warranty of 14;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15;; GNU General Public License for more details. 16 17;; You should have received a copy of the GNU General Public License 18;; along with GCC; see the file COPYING3. If not see 19;; <http://www.gnu.org/licenses/>. 20 21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 22;; TODOs: 23;; dpfp blocks? 24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 25;; Scheduler descriptions for the fpx instructions 26(define_insn_reservation "spfp_compact" 3 27 (and (match_test "TARGET_SPFP_COMPACT_SET") 28 (eq_attr "type" "spfp")) 29 "issue+core, nothing*2, write_port") 30 31(define_insn_reservation "spfp_fast" 6 32 (and (match_test "TARGET_SPFP_FAST_SET") 33 (eq_attr "type" "spfp")) 34 "issue+core, nothing*5, write_port") 35 36(define_insn_reservation "dpfp_compact_mult" 7 37 (and (match_test "TARGET_DPFP_COMPACT_SET") 38 (eq_attr "type" "dpfp_mult")) 39 "issue+core, nothing*6, write_port") 40 41(define_insn_reservation "dpfp_compact_addsub" 5 42 (and (match_test "TARGET_DPFP_COMPACT_SET") 43 (eq_attr "type" "dpfp_addsub")) 44 "issue+core, nothing*4, write_port") 45 46(define_insn_reservation "dpfp_fast" 5 47 (and (match_test "TARGET_DPFP_FAST_SET") 48 (eq_attr "type" "dpfp_mult,dpfp_addsub")) 49 "issue+core, nothing*4, write_port") 50 51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 52 53(define_insn "*addsf3_fpx" 54 [(set (match_operand:SF 0 "register_operand" "=r,r,r,r,r ") 55 (plus:SF (match_operand:SF 1 "nonmemory_operand" "0,r,GCal,r,0") 56 (match_operand:SF 2 "nonmemory_operand" "I,rL,r,GCal,LrCal")))] 57; "(TARGET_ARC700 || TARGET_ARC600) && TARGET_SPFP_SET";Add flag for float 58 "TARGET_SPFP" 59 "@ 60 fadd %0,%1,%2 61 fadd %0,%1,%2 62 fadd %0,%1,%2 63 fadd %0,%1,%2 64 fadd%? %0,%1,%2" 65 [(set_attr "type" "spfp") 66 (set_attr "length" "4,4,8,8,8")]) 67 68(define_insn "*subsf3_fpx" 69 [(set (match_operand:SF 0 "register_operand" "=r,r,r,r,r ") 70 (minus:SF (match_operand:SF 1 "nonmemory_operand" "r,0,GCal,r,0") 71 (match_operand:SF 2 "nonmemory_operand" "rL,I,r,GCal,LrCal")))] 72 ;"(TARGET_ARC700 || TARGET_ARC600) && TARGET_SPFP_SET";Add flag for float 73 "TARGET_SPFP" 74 "@ 75 fsub %0,%1,%2 76 fsub %0,%1,%2 77 fsub %0,%1,%2 78 fsub %0,%1,%2 79 fsub%? %0,%1,%2" 80 [(set_attr "type" "spfp") 81 (set_attr "length" "4,4,8,8,8")]) 82 83(define_insn "*mulsf3_fpx" 84 [(set (match_operand:SF 0 "register_operand" "=r,r,r,r,r ") 85 (mult:SF (match_operand:SF 1 "nonmemory_operand" "r,0,GCal,r,0") 86 (match_operand:SF 2 "nonmemory_operand" "rL,I,r,GCal,LrCal")))] 87; "(TARGET_ARC700 || TARGET_ARC600) && TARGET_SPFP_SET" ;Add flag for float 88 "TARGET_SPFP" 89 "@ 90 fmul %0,%1,%2 91 fmul %0,%1,%2 92 fmul %0,%1,%2 93 fmul %0,%1,%2 94 fmul%? %0,%1,%2" 95 [(set_attr "type" "spfp") 96 (set_attr "length" "4,4,8,8,8")]) 97 98 99;; For comparisons, we can avoid storing the top half of the result into 100;; a register since '.f' lets us set the Z bit for the conditional 101;; branch insns. 102 103;; ??? FIXME (x-y)==0 is not a correct comparison for floats: 104;; http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm 105(define_insn "cmpsfpx_raw" 106 [(set (reg:CC_FPX 61) 107 (compare:CC_FPX (match_operand:SF 0 "register_operand" "r") 108 (match_operand:SF 1 "register_operand" "r")))] 109 "TARGET_ARGONAUT_SET && TARGET_SPFP" 110 "fsub.f 0,%0,%1" 111 [(set_attr "type" "spfp") 112 (set_attr "length" "4")]) 113 114;; ??? FIXME (x-y)==0 is not a correct comparison for floats: 115;; http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm 116;; ??? FIXME we claim to clobber operand 2, yet the two numbers appended 117;; to the actual instructions are incorrect. The result of the d*subh 118;; insn is stored in the Dx register specified by that first number. 119(define_insn "cmpdfpx_raw" 120 [(set (reg:CC_FPX 61) 121 (compare:CC_FPX (match_operand:DF 0 "nonmemory_operand" "D,r") 122 (match_operand:DF 1 "nonmemory_operand" "r,D"))) 123 (clobber (match_scratch:DF 2 "=D,D"))] 124 "TARGET_ARGONAUT_SET && TARGET_DPFP" 125 "@ 126 dsubh%F0%F1.f 0,%H2,%L2 127 drsubh%F0%F2.f 0,%H1,%L1" 128 [(set_attr "type" "dpfp_addsub") 129 (set_attr "length" "4")]) 130 131;; ??? FIXME subtraction is not a correct comparison for floats: 132;; http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm 133(define_insn "*cmpfpx_gt" 134 [(set (reg:CC_FP_GT 61) (compare:CC_FP_GT (reg:CC_FPX 61) (const_int 0)))] 135 "TARGET_ARGONAUT_SET" 136 "cmp.ls pcl,pcl" 137 [(set_attr "type" "compare") 138 (set_attr "length" "4")]) 139 140;; ??? FIXME subtraction is not a correct comparison for floats: 141;; http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm 142(define_insn "*cmpfpx_ge" 143 [(set (reg:CC_FP_GE 61) (compare:CC_FP_GE (reg:CC_FPX 61) (const_int 0)))] 144 "TARGET_ARGONAUT_SET" 145 "rcmp.pnz pcl,0" 146 [(set_attr "type" "compare") 147 (set_attr "length" "4")]) 148 149;; DPFP instructions begin... 150 151;; op0_reg = D1_reg.low 152(define_insn "*lr_double_lower" 153 [(set (match_operand:SI 0 "register_operand" "=r") 154 (unspec_volatile:SI [(match_operand:DF 1 "arc_double_register_operand" "D")] VUNSPEC_ARC_LR ))] 155 "TARGET_DPFP && !TARGET_DPFP_DISABLE_LRSR" 156"lr %0, [%1l] ; *lr_double_lower" 157[(set_attr "length" "8") 158(set_attr "type" "lr")] 159) 160 161(define_insn "*lr_double_higher" 162 [(set (match_operand:SI 0 "register_operand" "=r") 163 (unspec_volatile:SI [(match_operand:DF 1 "arc_double_register_operand" "D")] 164 VUNSPEC_ARC_LR_HIGH ))] 165 "TARGET_DPFP && !TARGET_DPFP_DISABLE_LRSR" 166"lr %0, [%1h] ; *lr_double_higher" 167[(set_attr "length" "8") 168(set_attr "type" "lr")] 169) 170 171(define_insn "*dexcl_3op_peep2_insn" 172 [(set (match_operand:SI 0 "dest_reg_operand" "=r") ; not register_operand, to accept SUBREG 173 (unspec_volatile:SI 174 [(match_operand:SI 1 "shouldbe_register_operand" "r") ; r1 175 (match_operand:SI 2 "shouldbe_register_operand" "r") ; r0 176 ] VUNSPEC_ARC_DEXCL )) 177 (clobber (match_operand:DF 3 "arc_double_register_operand" "=&D"))] 178 "TARGET_DPFP" 179 "dexcl%F3 %0, %1, %2" 180 [(set_attr "type" "move") 181 (set_attr "length" "4")] 182) 183 184;; version which will not overwrite operand0 185(define_insn "dexcl_2op" 186 [(set (match_operand:DF 0 "arc_double_register_operand" "=D") 187 (unspec_volatile:DF 188 [(match_operand:SI 1 "shouldbe_register_operand" "r") ; r1 189 (match_operand:SI 2 "shouldbe_register_operand" "r") ; r0 190 ] VUNSPEC_ARC_DEXCL_NORES)) 191 ] 192 "TARGET_DPFP" 193 "dexcl%F0 0, %1, %2" 194 [(set_attr "type" "move") 195 (set_attr "length" "4")] 196) 197 198;; dexcl a,b,c pattern generated by the peephole2 above 199(define_insn "*dexcl_3op_peep2_insn_lr" 200 [(parallel [(set (match_operand:SI 0 "register_operand" "=r") 201 (unspec_volatile:SI [(match_operand:DF 1 "arc_double_register_operand" "=D")] VUNSPEC_ARC_LR )) 202 (set (match_dup 1) (match_operand:DF 2 "register_operand" "r"))] 203 ) 204 ] 205 "TARGET_DPFP && !TARGET_DPFP_DISABLE_LRSR" 206 "dexcl%F1 %0, %H2, %L2" 207 [(set_attr "type" "move") 208 (set_attr "length" "4")] 209) 210 211 212;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 213;; doubles support for ARC 214;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 215 216;; D0 = D1+{reg_pair}2 217;; (define_expand "adddf3" 218;; [(set (match_operand:DF 0 "arc_double_register_operand" "") 219;; (plus:DF (match_operand:DF 1 "arc_double_register_operand" "") 220;; (match_operand:DF 2 "nonmemory_operand" "")))] 221;; "TARGET_DPFP" 222;; " " 223;; ) 224;; daddh{0}{1} 0, {reg_pair}2.hi, {reg_pair}2.lo 225;; OR 226;; daddh{0}{1} 0, reg3, limm2.lo 227;; daddh{0}{1} 0, {reg_pair}2.hi, {reg_pair}2.lo /* operand 4 = 1*/ 228;; OR 229;; daddh{0}{1} 0, reg3, limm2.lo /* operand 4 = 0 */ 230;; 231(define_insn "adddf3_insn" 232 [(set (match_operand:DF 0 "arc_double_register_operand" "=D,D") 233 (plus:DF (match_operand:DF 1 "arc_double_register_operand" "D,D") 234 (match_operand:DF 2 "nonmemory_operand" "!r,G"))) 235 (use (match_operand:SI 3 "" "N,r")) 236 (use (match_operand:SI 4 "" "N,Q")) 237 ; Prevent can_combine_p from combining muldf3_insn patterns with 238 ; different USE pairs. 239 (use (match_dup 2)) 240 ] 241 "TARGET_DPFP && 242 !(GET_CODE(operands[2]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT)" 243 "@ 244 daddh%F0%F1 0,%H2,%L2 245 daddh%F0%F1 0,%3,%L2" 246 [(set_attr "type" "dpfp_addsub") 247 (set_attr "length" "4,8")]) 248 249;; dmulh{0}{1} 0, {reg_pair}2.hi, {reg_pair}2.lo 250;; OR 251;; dmulh{0}{1} 0, reg3, limm2.lo 252;; dmulh{0}{1} 0, {reg_pair}2.hi, {reg_pair}2.lo /* operand 4 = 1*/ 253;; OR 254;; dmulh{0}{1} 0, reg3, limm2.lo /* operand 4 = 0*/ 255(define_insn "muldf3_insn" 256 [(set (match_operand:DF 0 "arc_double_register_operand" "=D,D") 257 (mult:DF (match_operand:DF 1 "arc_double_register_operand" "D,D") 258 (match_operand:DF 2 "nonmemory_operand" "!r,G"))) 259 (use (match_operand:SI 3 "" "N,!r")) 260 (use (match_operand:SI 4 "" "N,Q")) 261 ; Prevent can_combine_p from combining muldf3_insn patterns with 262 ; different USE pairs. 263 (use (match_dup 2)) 264 ] 265 "TARGET_DPFP && 266 !(GET_CODE(operands[2]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT)" 267 "@ 268 dmulh%F0%F1 0,%H2,%L2 269 dmulh%F0%F1 0,%3, %L2" 270 [(set_attr "type" "dpfp_mult") 271 (set_attr "length" "4,8")]) 272 273;; dsubh{0}{1} 0, {reg_pair}2.hi, {reg_pair}2.lo 274;; OR 275;; dsubh{0}{1} 0, reg3, limm2.lo 276;; OR 277;; drsubh{0}{2} 0, {reg_pair}1.hi, {reg_pair}1.lo 278;; OR 279;; drsubh{0}{2} 0, reg3, limm1.lo 280;; dsubh{0}{1} 0, {reg_pair}2.hi, {reg_pair}2.lo /* operand 4 = 1 */ 281;; OR 282;; dsubh{0}{1} 0, reg3, limm2.lo /* operand 4 = 0*/ 283;; OR 284;; drsubh{0}{2} 0, {reg_pair}1.hi, {reg_pair}1.lo /* operand 4 = 1 */ 285;; OR 286;; drsubh{0}{2} 0, reg3, limm1.lo /* operand 4 = 0*/ 287(define_insn "subdf3_insn" 288 [(set (match_operand:DF 0 "arc_double_register_operand" "=D,D,D,D") 289 (minus:DF (match_operand:DF 1 "nonmemory_operand" "D,D,!r,G") 290 (match_operand:DF 2 "nonmemory_operand" "!r,G,D,D"))) 291 (use (match_operand:SI 3 "" "N,r,N,r")) 292 (use (match_operand:SI 4 "" "N,Q,N,Q")) 293 ; Prevent can_combine_p from combining muldf3_insn patterns with 294 ; different USE pairs. 295 (use (match_dup 2))] 296 "TARGET_DPFP && 297 !(GET_CODE(operands[2]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT) && 298 !(GET_CODE(operands[1]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT)" 299 "@ 300 dsubh%F0%F1 0,%H2,%L2 301 dsubh%F0%F1 0,%3,%L2 302 drsubh%F0%F2 0,%H1,%L1 303 drsubh%F0%F2 0,%3,%L1" 304 [(set_attr "type" "dpfp_addsub") 305 (set_attr "length" "4,8,4,8") 306 (set_attr "cpu_facility" "*,*,fpx,fpx")]) 307 308;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 309;; ;; Peephole for following conversion 310;; ;; D0 = D2<op>{reg_pair}3 311;; ;; {reg_pair}5 = D0 312;; ;; D0 = {reg_pair}6 313;; ;; | 314;; ;; V 315;; ;; _________________________________________________________ 316;; ;; / D0 = D2 <op> {regpair3_or_limmreg34} 317;; ;; ---- + {reg_pair}5.hi = ( D2<op>{regpair3_or_limmreg34} ).hi 318;; ;; | \_________________________________________________________ 319;; ;; | 320;; ;; | ________________________________________________________ 321;; ;; | / {reg_pair}5.lo = ( D2<op>{regpair3_or_limmreg34} ).lo 322;; ;; +-----+ D0 = {reg_pair}6 323;; ;; \ _________________________________________________________ 324;; ;; || 325;; ;; || 326;; ;; \/ 327;; ;; d<op>{0}{2}h {reg_pair}5.hi, {regpair3_or_limmreg34}.lo, {regpair3_or_limmreg34}.hi 328;; ;; dexcl{0} {reg_pair}5.lo, {reg_pair}6.lo, {reg_pair}6.hi 329;; ;; ----------------------------------------------------------------------------------------- 330;; ;; where <op> is one of {+,*,-} 331;; ;; <opname> is {add,mult,sub} 332;; ;; 333;; ;; NOTE: For rsub insns D2 and {regpair3_or_limmreg34} get interchanged as 334;; ;; {regpair2_or_limmreg24} and D3 335;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 336;; (define_peephole2 337;; [(parallel [(set (match_operand:DF 0 "register_operand" "") 338;; (match_operator:DF 1 "arc_dpfp_operator" [(match_operand:DF 2 "nonmemory_operand" "") 339;; (match_operand:DF 3 "nonmemory_operand" "")])) 340;; (use (match_operand:SI 4 "" ""))]) 341;; (set (match_operand:DF 5 "register_operand" "") 342;; (match_dup 0)) 343;; (set (match_dup 0) 344;; (match_operand:DF 6 "register_operand" "")) 345;; ] 346;; "TARGET_DPFP" 347;; [ 348;; (parallel [(set (match_dup 0) 349;; (match_op_dup:DF 1 [(match_dup 2) 350;; (match_dup 3)])) 351;; (use (match_dup 4)) 352;; (set (match_dup 5) 353;; (match_op_dup:DF 1 [(match_dup 2) 354;; (match_dup 3)]))]) 355;; (parallel [ 356;; ;; (set (subreg:SI (match_dup 5) 0) 357;; (set (match_dup 7) 358;; (unspec_volatile [(match_dup 0)] VUNSPEC_ARC_LR )) 359;; (set (match_dup 0) (match_dup 6))] 360;; ) 361;; ] 362;; "operands[7] = simplify_gen_subreg(SImode,operands[5],DFmode,0);" 363;; ) 364;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 365;; Peephole for following conversion 366;; D0 = D2<op>{reg_pair}3 367;; {reg_pair}6 = D0 368;; D0 = {reg_pair}7 369;; | 370;; V 371;; _________________________________________________________ 372;; / D0 = D2 <op> {regpair3_or_limmreg34} 373;; ---- + {reg_pair}6.hi = ( D2<op>{regpair3_or_limmreg34} ).hi 374;; | \_________________________________________________________ 375;; | 376;; | ________________________________________________________ 377;; | / {reg_pair}6.lo = ( D2<op>{regpair3_or_limmreg34} ).lo 378;; +-----+ D0 = {reg_pair}7 379;; \ _________________________________________________________ 380;; || 381;; || 382;; \/ 383;; d<op>{0}{2}h {reg_pair}6.hi, {regpair3_or_limmreg34}.lo, {regpair3_or_limmreg34}.hi 384;; dexcl{0} {reg_pair}6.lo, {reg_pair}7.lo, {reg_pair}7.hi 385;; ----------------------------------------------------------------------------------------- 386;; where <op> is one of {+,*,-} 387;; <opname> is {add,mult,sub} 388;; 389;; NOTE: For rsub insns D2 and {regpair3_or_limmreg34} get interchanged as 390;; {regpair2_or_limmreg24} and D3 391;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 392(define_peephole2 393 [(parallel [(set (match_operand:DF 0 "register_operand" "") 394 (match_operator:DF 1 "arc_dpfp_operator" [(match_operand:DF 2 "nonmemory_operand" "") 395 (match_operand:DF 3 "nonmemory_operand" "")])) 396 (use (match_operand:SI 4 "" "")) 397 (use (match_operand:SI 5 "" "")) 398 (use (match_operand:SI 6 "" ""))]) 399 (set (match_operand:DF 7 "register_operand" "") 400 (match_dup 0)) 401 (set (match_dup 0) 402 (match_operand:DF 8 "register_operand" "")) 403 ] 404 "TARGET_DPFP && !TARGET_DPFP_DISABLE_LRSR" 405 [ 406 (parallel [(set (match_dup 0) 407 (match_op_dup:DF 1 [(match_dup 2) 408 (match_dup 3)])) 409 (use (match_dup 4)) 410 (use (match_dup 5)) 411 (set (match_dup 7) 412 (match_op_dup:DF 1 [(match_dup 2) 413 (match_dup 3)]))]) 414 (parallel [ 415;; (set (subreg:SI (match_dup 7) 0) 416 (set (match_dup 9) 417 (unspec_volatile:SI [(match_dup 0)] VUNSPEC_ARC_LR )) 418 (set (match_dup 0) (match_dup 8))] 419 ) 420 ] 421 "operands[9] = simplify_gen_subreg(SImode,operands[7],DFmode,0);" 422 ) 423 424;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 425;; ;; Peephole to generate d<opname>{ij}h a,b,c instructions 426;; ;; D0 = D2<op>{reg_pair}3 427;; ;; {reg_pair}5 = D0 428;; ;; | 429;; ;; V 430;; ;; __________________________________________ 431;; ;; / D0 = D2 <op> {regpair3_or_limmreg34} 432;; ;; ---- + {reg_pair}5.hi = ( D2<op>{regpair3_or_limmreg34} ).hi 433;; ;; | \__________________________________________ 434;; ;; | 435;; ;; + --- {reg_pair}5.lo = ( D2<op>{regpair3_or_limmreg34} ).lo 436;; ;; || 437;; ;; || 438;; ;; \/ 439;; ;; d<op>{0}{2}h {reg_pair}4.hi, {regpair3_or_limmreg34}.lo, {regpair3_or_limmreg34}.hi 440;; ;; lr {reg_pair}4.lo, {D2l} 441;; ;; ---------------------------------------------------------------------------------------- 442;; ;; where <op> is one of {+,*,-} 443;; ;; <opname> is {add,mult,sub} 444;; ;; 445;; ;; NOTE: For rsub insns D2 and {regpair3_or_limmreg34} get interchanged as 446;; ;; {regpair2_or_limmreg24} and D3 447;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 448;; (define_peephole2 449;; [(parallel [(set (match_operand:DF 0 "register_operand" "") 450;; (match_operator:DF 1 "arc_dpfp_operator" [(match_operand:DF 2 "nonmemory_operand" "") 451;; (match_operand:DF 3 "nonmemory_operand" "")])) 452;; (use (match_operand:SI 4 "" ""))]) 453;; (set (match_operand:DF 5 "register_operand" "") 454;; (match_dup 0)) 455;; ] 456;; "TARGET_DPFP" 457;; [ 458;; (parallel [(set (match_dup 0) 459;; (match_op_dup:DF 1 [(match_dup 2) 460;; (match_dup 3)])) 461;; (use (match_dup 4)) 462;; (set (match_dup 5) 463;; (match_op_dup:DF 1 [(match_dup 2) 464;; (match_dup 3)]))]) 465;; ; (set (subreg:SI (match_dup 5) 0) 466;; (set (match_dup 6) 467;; (unspec_volatile [(match_dup 0)] VUNSPEC_ARC_LR )) 468;; ] 469;; "operands[6] = simplify_gen_subreg(SImode,operands[5],DFmode,0);" 470;; ) 471;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 472;; Peephole to generate d<opname>{ij}h a,b,c instructions 473;; D0 = D2<op>{reg_pair}3 474;; {reg_pair}6 = D0 475;; | 476;; V 477;; __________________________________________ 478;; / D0 = D2 <op> {regpair3_or_limmreg34} 479;; ---- + {reg_pair}6.hi = ( D2<op>{regpair3_or_limmreg34} ).hi 480;; | \__________________________________________ 481;; | 482;; + --- {reg_pair}6.lo = ( D2<op>{regpair3_or_limmreg34} ).lo 483;; || 484;; || 485;; \/ 486;; d<op>{0}{2}h {reg_pair}4.hi, {regpair3_or_limmreg34}.lo, {regpair3_or_limmreg34}.hi 487;; lr {reg_pair}4.lo, {D2l} 488;; ---------------------------------------------------------------------------------------- 489;; where <op> is one of {+,*,-} 490;; <opname> is {add,mult,sub} 491;; 492;; NOTE: For rsub insns D2 and {regpair3_or_limmreg34} get interchanged as 493;; {regpair2_or_limmreg24} and D3 494;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 495(define_peephole2 496 [(parallel [(set (match_operand:DF 0 "register_operand" "") 497 (match_operator:DF 1 "arc_dpfp_operator" [(match_operand:DF 2 "nonmemory_operand" "") 498 (match_operand:DF 3 "nonmemory_operand" "")])) 499 (use (match_operand:SI 4 "" "")) 500 (use (match_operand:SI 5 "" "")) 501 (use (match_operand:SI 6 "" ""))]) 502 (set (match_operand:DF 7 "register_operand" "") 503 (match_dup 0)) 504 ] 505 "TARGET_DPFP && !TARGET_DPFP_DISABLE_LRSR" 506 [ 507 (parallel [(set (match_dup 0) 508 (match_op_dup:DF 1 [(match_dup 2) 509 (match_dup 3)])) 510 (use (match_dup 4)) 511 (use (match_dup 5)) 512 (set (match_dup 7) 513 (match_op_dup:DF 1 [(match_dup 2) 514 (match_dup 3)]))]) 515; (set (subreg:SI (match_dup 7) 0) 516 (set (match_dup 8) 517 (unspec_volatile:SI [(match_dup 0)] VUNSPEC_ARC_LR )) 518 ] 519 "operands[8] = simplify_gen_subreg(SImode,operands[7],DFmode,0);" 520 ) 521 522;; ;; _______________________________________________________ 523;; ;; / D0 = D1 + {regpair2_or_limmreg23} 524;; ;; + {reg_pair}4.hi = ( D1 + {regpair2_or_limmreg23} ).hi 525;; ;; \_______________________________________________________ 526;; (define_insn "*daddh_peep2_insn" 527;; [(parallel [(set (match_operand:DF 0 "arc_double_register_operand" "=D,D") 528;; (plus:DF (match_operand:DF 1 "arc_double_register_operand" "D,D") 529;; (match_operand:DF 2 "nonmemory_operand" "r,G"))) 530;; (use (match_operand:SI 3 "" "N,r")) 531;; (set (match_operand:DF 4 "register_operand" "=r,r") 532;; (plus:DF (match_dup 1) 533;; (match_dup 2)))])] 534;; "TARGET_DPFP" 535;; "@ 536;; daddh%F0%F1 %H4, %H2, %L2 537;; daddh%F0%F1 %H4, %3, %L2" 538;; [(set_attr "type" "dpfp_addsub") 539;; (set_attr "length" "4,8")] 540;; ) 541;; _______________________________________________________ 542;; / D0 = D1 + {regpair2_or_limmreg23} 543;; + {reg_pair}5.hi = ( D1 + {regpair2_or_limmreg23} ).hi 544;; \_______________________________________________________ 545(define_insn "*daddh_peep2_insn" 546 [(parallel [(set (match_operand:DF 0 "arc_double_register_operand" "=D,D") 547 (plus:DF (match_operand:DF 1 "arc_double_register_operand" "D,D") 548 (match_operand:DF 2 "nonmemory_operand" "r,G"))) 549 (use (match_operand:SI 3 "" "N,r")) 550 (use (match_operand:SI 4 "" "N,Q")) 551 (use (match_operand:SI 5 "" "")) 552 (set (match_operand:DF 6 "register_operand" "=r,r") 553 (plus:DF (match_dup 1) 554 (match_dup 2)))])] 555 "TARGET_DPFP && 556 !(GET_CODE(operands[2]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT)" 557 "@ 558 daddh%F0%F1 %H6, %H2, %L2 559 daddh%F0%F1 %H6, %3, %L2" 560 [(set_attr "type" "dpfp_addsub") 561 (set_attr "length" "4,8")] 562) 563 564;; _______________________________________________________ 565;; / D0 = D1 * {regpair2_or_limmreg23} 566;; + {reg_pair}5.hi = ( D1 * {regpair2_or_limmreg23} ).hi 567;; \_______________________________________________________ 568(define_insn "*dmulh_peep2_insn" 569 [(parallel [(set (match_operand:DF 0 "arc_double_register_operand" "=D,D") 570 (mult:DF (match_operand:DF 1 "arc_double_register_operand" "D,D") 571 (match_operand:DF 2 "nonmemory_operand" "r,G"))) 572 (use (match_operand:SI 3 "" "N,r")) 573 (use (match_operand:SI 4 "" "N,Q")) 574 (use (match_operand:SI 5 "" "")) 575 (set (match_operand:DF 6 "register_operand" "=r,r") 576 (mult:DF (match_dup 1) 577 (match_dup 2)))])] 578 "TARGET_DPFP && 579 !(GET_CODE(operands[2]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT)" 580 "@ 581 dmulh%F0%F1 %H6, %H2, %L2 582 dmulh%F0%F1 %H6, %3, %L2" 583 [(set_attr "type" "dpfp_mult") 584 (set_attr "length" "4,8")] 585) 586 587;; _______________________________________________________ 588;; / D0 = D1 - {regpair2_or_limmreg23} 589;; + {reg_pair}5.hi = ( D1 - {regpair2_or_limmreg23} ).hi 590;; \_______________________________________________________ 591;; OR 592;; _______________________________________________________ 593;; / D0 = {regpair1_or_limmreg13} - D2 594;; + {reg_pair}5.hi = ( {regpair1_or_limmreg13} ).hi - D2 595;; \_______________________________________________________ 596(define_insn "*dsubh_peep2_insn" 597 [(parallel [(set (match_operand:DF 0 "arc_double_register_operand" "=D,D,D,D") 598 (minus:DF (match_operand:DF 1 "nonmemory_operand" "D,D,r,G") 599 (match_operand:DF 2 "nonmemory_operand" "r,G,D,D"))) 600 (use (match_operand:SI 3 "" "N,r,N,r")) 601 (use (match_operand:SI 4 "" "N,Q,N,Q")) 602 (use (match_operand:SI 5 "" "")) 603 (set (match_operand:DF 6 "register_operand" "=r,r,r,r") 604 (minus:DF (match_dup 1) 605 (match_dup 2)))])] 606 "TARGET_DPFP && 607 !(GET_CODE(operands[2]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT) && 608 !(GET_CODE(operands[1]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT)" 609 "@ 610 dsubh%F0%F1 %H6, %H2, %L2 611 dsubh%F0%F1 %H6, %3, %L2 612 drsubh%F0%F2 %H6, %H1, %L1 613 drsubh%F0%F2 %H6, %3, %L1" 614 [(set_attr "type" "dpfp_addsub") 615 (set_attr "length" "4,8,4,8") 616 (set_attr "cpu_facility" "*,*,fpx,fpx")]) 617 618;; Intel QUARK SE extensions 619(define_mode_iterator QUARK_CMP [CC_FP_GT CC_FP_GE]) 620(define_mode_attr quark_cmp [(CC_FP_GT "gt") (CC_FP_GE "ge")]) 621 622(define_expand "cmp_quark" 623 [(parallel [(set (match_operand 0 "") 624 (match_operand 1 "")) 625 (clobber (match_scratch:SI 2 ""))])] 626 "" 627 "") 628 629(define_insn "*cmpsf_quark_<quark_cmp>" 630 [(set (reg:QUARK_CMP CC_REG) 631 (compare:QUARK_CMP (match_operand:SF 0 "register_operand" "r") 632 (match_operand:SF 1 "register_operand" "r"))) 633 (clobber (match_scratch:SI 2 "=&r"))] 634 "TARGET_FPX_QUARK" 635 "dsp_fp_cmp\\t%2,%0,%1\\n\\trsub.f\\t0,%2,7\\n\\tcmp.nc\\t%2,1\\n\\tcmp.hi\\t%2,3" 636 [(set_attr "length" "16") 637 (set_attr "cond" "set") 638 (set_attr "predicable" "no") 639 (set_attr "cond" "nocond")]) 640 641(define_insn "*cmpsf_quark_ord" 642 [(set (reg:CC_FP_ORD CC_REG) 643 (compare:CC_FP_ORD (match_operand:SF 0 "register_operand" "r") 644 (match_operand:SF 1 "register_operand" "r"))) 645 (clobber (match_scratch:SI 2 "=&r"))] 646 "TARGET_FPX_QUARK" 647 "dsp_fp_cmp\\t%2,%0,%1\\n\\tadd.f\\t%2,%2,-8" 648 [(set_attr "length" "8") 649 (set_attr "cond" "set") 650 (set_attr "predicable" "no") 651 (set_attr "cond" "nocond")]) 652 653(define_insn "*cmpsf_quark_uneq" 654 [(set (reg:CC_FP_UNEQ CC_REG) 655 (compare:CC_FP_UNEQ (match_operand:SF 0 "register_operand" "r") 656 (match_operand:SF 1 "register_operand" "r"))) 657 (clobber (match_scratch:SI 2 "=&r"))] 658 "TARGET_FPX_QUARK" 659 "dsp_fp_cmp\\t%2,%0,%1\\n\\ttst\\t%2,6" 660 [(set_attr "length" "8") 661 (set_attr "cond" "set") 662 (set_attr "predicable" "no") 663 (set_attr "cond" "nocond")]) 664 665(define_insn "*cmpsf_quark_eq" 666 [(set (reg:CC_Z CC_REG) 667 (compare:CC_Z (match_operand:SF 0 "register_operand" "r") 668 (match_operand:SF 1 "register_operand" "r"))) 669 (clobber (match_scratch:SI 2 "=&r"))] 670 "TARGET_FPX_QUARK" 671 "dsp_fp_cmp\\t%2,%0,%1\\n\\ttst\\t%2,0x0E" 672 [(set_attr "length" "8") 673 (set_attr "cond" "set") 674 (set_attr "predicable" "no") 675 (set_attr "cond" "nocond")]) 676 677(define_insn "*divsf3_quark" 678 [(set (match_operand:SF 0 "register_operand" "=r") 679 (div:SF (match_operand:SF 1 "register_operand" "r") 680 (match_operand:SF 2 "register_operand" "r")))] 681 "TARGET_FPX_QUARK" 682 "dsp_fp_div\\t%0,%1,%2" 683 [(set_attr "length" "4") 684 (set_attr "predicable" "no") 685 (set_attr "cond" "nocond")]) 686 687(define_insn "*sqrtsf2_quark" 688 [(set (match_operand:SF 0 "register_operand" "=r") 689 (sqrt:SF (match_operand:SF 1 "register_operand" "r")))] 690 "TARGET_FPX_QUARK" 691 "dsp_fp_sqrt\\t%0,%1" 692 [(set_attr "length" "4") 693 (set_attr "predicable" "no") 694 (set_attr "cond" "nocond")]) 695 696;; SF->SI (using rounding towards zero) 697(define_insn "*fix_truncsfsi2_quark" 698 [(set (match_operand:SI 0 "register_operand" "=r") 699 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "r"))))] 700 "TARGET_FPX_QUARK" 701 "dsp_fp_flt2i\\t%0,%1" 702 [(set_attr "length" "4") 703 (set_attr "predicable" "no") 704 (set_attr "cond" "nocond")]) 705 706;; SI->SF 707(define_insn "*floatsisf2_quark" 708 [(set (match_operand:SF 0 "register_operand" "=r") 709 (float:SF (match_operand:SI 1 "register_operand" "r")))] 710 "TARGET_FPX_QUARK" 711 "dsp_fp_i2flt\\t%0,%1" 712 [(set_attr "length" "4") 713 (set_attr "predicable" "no") 714 (set_attr "cond" "nocond")]) 715 716