1;;- Machine description for the Motorola 88000 for GNU C compiler 2;; Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000 3;; Free Software Foundation, Inc. 4;; Contributed by Michael Tiemann (tiemann@mcc.com) 5 6;; This file is part of GCC. 7 8;; GCC is free software; you can redistribute it and/or modify 9;; it under the terms of the GNU General Public License as published by 10;; the Free Software Foundation; either version 2, or (at your option) 11;; any later version. 12 13;; GCC is distributed in the hope that it will be useful, 14;; but WITHOUT ANY WARRANTY; without even the implied warranty of 15;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16;; GNU General Public License for more details. 17 18;; You should have received a copy of the GNU General Public License 19;; along with GCC; see the file COPYING. If not, write to 20;; the Free Software Foundation, 51 Franklin Street, Fifth Floor, 21;; Boston, MA 02110-1301, USA. 22 23 24;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. 25 26(define_constants 27 [(UNSPEC_ABDIFF 0) 28 (UNSPEC_GOT_REL 1) 29 ]) 30 31(include "predicates.md") 32(include "constraints.md") 33 34;; Attribute describing the processor. This attribute must match exactly 35;; with the processor_type enumeration in m88k.h. 36 37; Target CPU. 38(define_attr "cpu" "m88100,m88110,m88000" 39 (const (symbol_ref "m88k_cpu"))) 40 41; Type of each instruction. Default is arithmetic. 42; I'd like to write the list as this, but genattrtab won't accept it. 43; 44; "branch,jump,call, ; flow-control instructions 45; load,store,loadd,loada, ; data unit instructions 46; spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv, ; FPU add instructions 47; spmul,dpmul,imul, ; FPU multiply instructions 48; arith,bit,mov ; integer unit instructions 49; marith,weird" ; multi-word instructions 50 51; Classification of each insn. Some insns of TYPE_BRANCH are multi-word. 52(define_attr "type" 53 "branch,jump,call,load,store,loadd,loada,spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv,spmul,dpmul,imul,arith,bit,mov,marith,weird" 54 (const_string "arith")) 55 56(define_attr "fpu" "yes,no" 57 (if_then_else 58 (eq_attr "type" "spmul,dpmul,imul,spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv") 59 (const_string "yes") (const_string "no"))) 60 61; Length in # of instructions of each insn. The values are not exact, but 62; are safe. 63(define_attr "length" "" 64 (cond [(eq_attr "type" "marith,weird,branch") 65 (const_int 2)] 66 (const_int 1))) 67 68; Describe a user's asm statement. 69(define_asm_attributes 70 [(set_attr "type" "weird") 71 (set_attr "length" "1")]) 72 73; Define the delay slot requirements for branches and calls. 74; The m88100 annuls instructions if a conditional branch is taken. 75; For insns of TYPE_BRANCH that are multi-word instructions, the 76; delay slot applies to the first instruction. 77 78; @@ For the moment, reorg.c requires that the delay slot of a branch not 79; be a call or branch. 80 81(define_delay (eq_attr "type" "branch,jump") 82 [(and (and (eq_attr "type" "!branch,jump,call,marith,weird") ; required. 83 (eq_attr "type" "!load,loadd")) ; issue as-soon-as-possible. 84 (eq_attr "fpu" "no")) ; issue as-soon-as-possible. 85 (eq_attr "type" "!call,branch,jump") (nil)]) 86 87; output_call supports an unconditional branch in the delay slot of 88; a call. (@@ Support for this case is expected in reorg.c soon.) 89 90(define_delay (eq_attr "type" "call") 91 [(eq_attr "type" "!branch,call,marith,weird") ; required. 92 (nil) (nil)]) 93 94;; Scheduling information 95 96;; This section is derived from the old define_function_unit description. 97;; Each reservation can be overriden on a processor-by-processor basis. 98 99; An abstract block diagram of the function units for the m88100. 100; 101; * 102; | 103; +---v----+ 104; | decode | 105; +-vv-v-v-+ fpu 106; ,----------'| | `----------------------. 107; | | | | ,-----. 108; load | store | | arith | | | 109; | | | +-v-v-+ | dp source 110; | | | | fp1 |---' 111; store | | | div +-v-v-+ 112; ,------. | | | ,-----. ,-----------' `-----------. 113; | | | | | | | | | 114; | +--v---v--+ ,---' | | +-v-v---+ +---v---+ 115; | | stage 2 | | | `---| add 2 | | mul 2 | 116; | +---------+ | +--v--+ +-------+ imul +-------+ 117; | | stage 1 | | | alu | | add 3 | ,--------| mul 3 | 118; | +---------+ | +--v--+ +-------+ | +-------+ 119; | | stage 0 | | | | add 4 | | | mul 4 | 120; | +--v---v--+ | | +---v---+ | +-------+ 121; | | | | | | | | mul 5 | 122; | * | | | | | +---v---+ 123; | | | | | +----v----+ | 124; | load | | | fp add `------>| fp last |<------' fp mul 125; | | | | +---v-v--^+ 126; | | | | | | | 127; | | | | | `--' dp dest 128; | | +--v-----v--+ | 129; | `--->| writeback |<--------------------' 130; | +--v-----v--+ 131; | | | 132; `------------------' * 133; 134; The decode unit need not be specified. 135; Consideration of writeback contention is critical to superb scheduling. 136 137(define_automaton "alu,fpu") 138 139(define_cpu_unit "alu" "alu") 140(define_cpu_unit "fpu" "fpu") 141 142(define_insn_reservation "generic_alu" 1 143 (eq_attr "type" "!store,marith,weird") 144 "alu") 145 146(define_insn_reservation "generic_alu_2" 2 147 (eq_attr "type" "marith,weird") 148 "alu") 149 150; 88100 specific 151 152(define_insn_reservation "store_88100" 1 153 (and (eq_attr "cpu" "m88100") 154 (eq_attr "type" "store,loada")) 155 "alu") 156 157(define_insn_reservation "load_88100" 3 158 (and (eq_attr "cpu" "m88100") 159 (eq_attr "type" "load")) 160 "alu") 161 162(define_insn_reservation "loadd_88100" 3 163 (and (eq_attr "cpu" "m88100") 164 (eq_attr "type" "loadd")) 165 "alu*2") 166 167; The times are adjusted to include fp1 and fplast, but then are further 168; adjusted based on the actual generated code. The notation to the right 169; is the total latency. A range denotes a group of instructions and/or 170; conditions (the extra clock of fplast time with some sequences). 171 172(define_insn_reservation "spmul_88100" 4 173 (and (eq_attr "cpu" "m88100") 174 (eq_attr "type" "spmul")) 175 "fpu") ; 6-8 176(define_insn_reservation "dpmul_88100" 7 177 (and (eq_attr "cpu" "m88100") 178 (eq_attr "type" "dpmul")) 179 "fpu") ; 9-10 180(define_insn_reservation "imul_88100" 3 181 (and (eq_attr "cpu" "m88100") 182 (eq_attr "type" "imul")) 183 "fpu") ; 4 184 185(define_insn_reservation "spdiv_88100" 30 186 (and (eq_attr "cpu" "m88100") 187 (eq_attr "type" "spdiv")) 188 "fpu") ; 30-31 189(define_insn_reservation "dpdiv_88100" 60 190 (and (eq_attr "cpu" "m88100") 191 (eq_attr "type" "dpdiv")) 192 "fpu") ; 60-61 193(define_insn_reservation "idiv_88100" 38 194 (and (eq_attr "cpu" "m88100") 195 (eq_attr "type" "idiv")) 196 "fpu") ; 38 197 198(define_insn_reservation "spadd_88100" 3 199 (and (eq_attr "cpu" "m88100") 200 (eq_attr "type" "spadd,spcmp")) 201 "fpu") ; 5-6 202(define_insn_reservation "dpadd_88100" 4 203 (and (eq_attr "cpu" "m88100") 204 (eq_attr "type" "dpadd,dpcmp")) 205 "fpu") ; 6-7 206 207; 88110 specific 208 209(define_insn_reservation "alu_88110" 2 210 (and (eq_attr "cpu" "!m88100") 211 (eq_attr "type" "loada,arith,mov")) 212 "alu") 213(define_insn_reservation "arith_88110" 4 214 (and (eq_attr "cpu" "!m88100") 215 (eq_attr "type" "marith,weird")) 216 "alu") 217 218(define_insn_reservation "bit_88110" 2 219 (and (eq_attr "cpu" "!m88100") 220 (eq_attr "type" "bit")) 221 "alu*2") 222 223(define_insn_reservation "load_88110" 3 224 (and (eq_attr "cpu" "!m88100") 225 (eq_attr "type" "load,loadd")) 226 "alu*2") 227(define_insn_reservation "store_88110" 1 228 (and (eq_attr "cpu" "!m88100") 229 (eq_attr "type" "store")) 230 "alu*2") 231 232(define_insn_reservation "spdiv_88110" 25 233 (and (eq_attr "cpu" "!m88100") 234 (eq_attr "type" "spdiv")) 235 "fpu*2") ; 13 236(define_insn_reservation "dpdiv_88110" 45 237 (and (eq_attr "cpu" "!m88100") 238 (eq_attr "type" "dpdiv")) 239 "fpu*2") ; 23 240(define_insn_reservation "idiv_88110" 35 241 (and (eq_attr "cpu" "!m88100") 242 (eq_attr "type" "idiv")) 243 "fpu*2") ; 18 244 245(define_insn_reservation "mul_88110" 5 246 (and (eq_attr "cpu" "!m88100") 247 (eq_attr "type" "imul,spmul,dpmul")) 248 "fpu*2") ; 3 249 250(define_insn_reservation "fpadd_88110" 5 251 (and (eq_attr "cpu" "!m88100") 252 (eq_attr "type" "spadd,dpadd")) 253 "fpu*2") ; 3 254(define_insn_reservation "fpcmp_88110" 2 255 (and (eq_attr "cpu" "!m88100") 256 (eq_attr "type" "spcmp,dpcmp")) 257 "fpu*2") ; 1 258 259;; Superoptimizer sequences 260 261;; geu+: { r = ((unsigned_word) v0 >= (unsigned_word) v1) + v2; } 262;; subu.co r5,r2,r3 263;; addu.cio r6,r4,r0 264 265(define_split 266 [(set (match_operand:SI 0 "register_operand" "") 267 (minus:SI (match_operand:SI 1 "register_operand" "") 268 (geu:SI (match_operand:SI 2 "register_operand" "") 269 (match_operand:SI 3 "register_operand" ""))))] 270 "GET_CODE (operands[0]) == REG 271 && GET_CODE (operands[1]) == REG 272 && GET_CODE (operands[2]) == REG 273 && GET_CODE (operands[3]) == REG" 274 [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1)) 275 (set (match_dup 0) 276 (plus:SI (match_dup 1) 277 (unspec:SI [(const_int 0) 278 (reg:CC 0)] 0)))] 279 "") 280 281;; leu+: { r = ((unsigned_word) v0 <= (unsigned_word) v1) + v2; } 282;; subu.co r5,r3,r2 283;; addu.cio r6,r4,r0 284 285(define_split 286 [(set (match_operand:SI 0 "register_operand" "") 287 (minus:SI (match_operand:SI 1 "register_operand" "") 288 (leu:SI (match_operand:SI 3 "register_operand" "") 289 (match_operand:SI 2 "register_operand" ""))))] 290 "GET_CODE (operands[0]) == REG 291 && GET_CODE (operands[1]) == REG 292 && GET_CODE (operands[2]) == REG 293 && GET_CODE (operands[3]) == REG" 294 [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1)) 295 (set (match_dup 0) 296 (plus:SI (match_dup 1) 297 (unspec:SI [(const_int 0) 298 (reg:CC 0)] 0)))] 299 "") 300 301;; eq0+: { r = (v0 == 0) + v1; } 302;; subu.co r4,r0,r2 303;; addu.cio r5,r3,r0 304 305(define_split 306 [(set (match_operand:SI 0 "register_operand" "") 307 (minus:SI (match_operand:SI 1 "register_operand" "") 308 (eq:SI (match_operand:SI 2 "register_operand" "") 309 (const_int 0))))] 310 "GET_CODE (operands[0]) == REG 311 && GET_CODE (operands[1]) == REG 312 && GET_CODE (operands[2]) == REG" 313 [(set (reg:CC 0) (unspec:CC [(const_int 0) (match_dup 2)] 1)) 314 (set (match_dup 0) 315 (plus:SI (match_dup 1) 316 (unspec:SI [(const_int 0) 317 (reg:CC 0)] 0)))] 318 "") 319 320;; ltu-: { r = v2 - ((unsigned_word) v0 < (unsigned_word) v1); } 321;; subu.co r5,r2,r3 322;; subu.cio r6,r4,r0 323 324(define_split 325 [(set (match_operand:SI 0 "register_operand" "") 326 (plus:SI (ltu:SI (match_operand:SI 2 "register_operand" "") 327 (match_operand:SI 3 "register_operand" "")) 328 (match_operand:SI 1 "register_operand" "")))] 329 "GET_CODE (operands[0]) == REG 330 && GET_CODE (operands[1]) == REG 331 && GET_CODE (operands[2]) == REG 332 && GET_CODE (operands[3]) == REG" 333 [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1)) 334 (set (match_dup 0) 335 (minus:SI (match_dup 1) 336 (unspec:SI [(const_int 0) 337 (reg:CC 0)] 1)))] 338 "") 339 340;; gtu-: { r = v2 - ((unsigned_word) v0 > (unsigned_word) v1); } 341;; subu.co r5,r3,r2 342;; subu.cio r6,r4,r0 343 344(define_split 345 [(set (match_operand:SI 0 "register_operand" "") 346 (plus:SI (gtu:SI (match_operand:SI 3 "register_operand" "") 347 (match_operand:SI 2 "register_operand" "")) 348 (match_operand:SI 1 "register_operand" "")))] 349 "GET_CODE (operands[0]) == REG 350 && GET_CODE (operands[1]) == REG 351 && GET_CODE (operands[2]) == REG 352 && GET_CODE (operands[3]) == REG" 353 [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1)) 354 (set (match_dup 0) 355 (minus:SI (match_dup 1) 356 (unspec:SI [(const_int 0) 357 (reg:CC 0)] 1)))] 358 "") 359 360;; ne0-: { r = v1 - (v0 != 0); } 361;; subu.co r4,r0,r2 362;; subu.cio r5,r3,r0 363 364(define_split 365 [(set (match_operand:SI 0 "register_operand" "") 366 (plus:SI (ne:SI (match_operand:SI 2 "register_operand" "") 367 (const_int 0)) 368 (match_operand:SI 1 "register_operand" "")))] 369 "GET_CODE (operands[0]) == REG 370 && GET_CODE (operands[1]) == REG 371 && GET_CODE (operands[2]) == REG" 372 [(set (reg:CC 0) (unspec:CC [(const_int 0) (match_dup 2)] 1)) 373 (set (match_dup 0) 374 (minus:SI (match_dup 1) 375 (unspec:SI [(const_int 0) 376 (reg:CC 0)] 1)))] 377 "") 378 379;; ges0-: { r = v1 - ((signed_word) v0 >= 0); } 380;; addu.co r4,r2,r2 381;; subu.cio r5,r3,r0 382 383(define_split 384 [(set (match_operand:SI 0 "register_operand" "") 385 (minus:SI (match_operand:SI 1 "register_operand" "") 386 (xor:SI (lshiftrt:SI 387 (match_operand:SI 2 "register_operand" "") 388 (const_int 31)) 389 (const_int 1))))] 390 "GET_CODE (operands[0]) == REG 391 && GET_CODE (operands[1]) == REG 392 && GET_CODE (operands[2]) == REG" 393 [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 2)] 0)) 394 (set (match_dup 0) 395 (minus:SI (match_dup 1) 396 (unspec:SI [(const_int 0) 397 (reg:CC 0)] 1)))] 398 "") 399 400;; This rich set of complex patterns are mostly due to Torbjorn Granlund 401;; (tege@sics.se). They've changed since then, so don't complain to him 402;; if they don't work right. 403 404;; Regarding shifts, gen_lshlsi3 generates ASHIFT. The gen functions 405;; produce the necessary insns to support TARGET_*_LARGE_SHIFT, so nothing 406;; special needs to be done here. 407 408;; Optimize possible cases of the set instruction. 409 410(define_insn "" 411 [(set (match_operand:SI 0 "register_operand" "=r") 412 (ashift:SI (const_int -1) 413 (match_operand:SI 1 "register_operand" "r")))] 414 "" 415 "set %0,%#r0,%1" 416 [(set_attr "type" "bit")]) 417 418(define_insn "" 419 [(set (match_operand:SI 0 "register_operand" "=r") 420 (ior:SI (ashift:SI (const_int -1) 421 (match_operand:SI 1 "register_operand" "r")) 422 (match_operand:SI 2 "register_operand" "r")))] 423 "" 424 "set %0,%2,%1" 425 [(set_attr "type" "bit")]) 426 427(define_insn "" 428 [(set (match_operand:SI 0 "register_operand" "=r") 429 (ior:SI (match_operand:SI 1 "register_operand" "r") 430 (ashift:SI (const_int -1) 431 (match_operand:SI 2 "register_operand" "r"))))] 432 "" 433 "set %0,%1,%2" 434 [(set_attr "type" "bit")]) 435 436;; Optimize possible cases of the mak instruction. 437 438(define_insn "" 439 [(set (match_operand:SI 0 "register_operand" "=r") 440 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r") 441 (match_operand:SI 2 "int5_operand" "")) 442 (match_operand:SI 3 "immediate_operand" "n")))] 443 "mak_mask_p (INTVAL (operands[3]) >> INTVAL (operands[2]))" 444{ 445 operands[4] = GEN_INT (exact_log2 (1 + (INTVAL (operands[3]) 446 >> INTVAL(operands[2])))); 447 return "mak %0,%1,%4<%2>"; 448} 449 [(set_attr "type" "bit")]) 450 451;; Optimize possible cases of output_and. 452 453(define_insn "" 454 [(set (match_operand:SI 0 "register_operand" "=r") 455 (ashift:SI (zero_extract:SI (match_operand:SI 1 "register_operand" "r") 456 (match_operand:SI 2 "int5_operand" "") 457 (match_operand:SI 3 "int5_operand" "")) 458 (match_operand:SI 4 "int5_operand" "")))] 459 "INTVAL (operands[2]) + INTVAL (operands[3]) + INTVAL (operands[4]) == 32" 460{ 461 operands[2] 462 = GEN_INT (((1 << INTVAL (operands[2])) - 1) << INTVAL (operands[4])); 463 return output_and (operands); 464} 465 [(set_attr "type" "marith")]) ; arith,bit,marith. length is 1 or 2. 466 467;; Improve logical operations on compare words 468;; 469;; We define all logical operations on CCmode values to preserve the pairwise 470;; relationship of the compare bits. This allows a future branch prediction 471;; pass the degree of freedom needed to change and/bb0-le into or/bb1-gt. 472;; THIS IS CURRENTLY FALSE! 473;; 474;; Opportunities arise when conditional expressions using && and || are made 475;; unconditional. When these are used to branch, the sequence is 476;; cmp/cmp/extu/extu/{and,or}/bcnd-{eq0,ne0}. When these are used to create 477;; a value, the sequence is cmp/cmp/extu/extu/{and,or} for 1 or 0 or 478;; cmp/cmp/ext/ext/{and,or} for -1 or 0. 479;; 480;; When the extracted conditions are the same, the define_split patterns 481;; below change extu/extu/{and,or} into {and,or}/extu. If the reversed 482;; conditions match, one compare word can be complemented, resulting in 483;; {and.c,or.c}/extu. These changes are done for ext/ext/{and,or} as well. 484;; If the conditions don't line up, one can be rotated. To keep the pairwise 485;; relationship, it may be necessary to both rotate and complement. Rotating 486;; makes branching cheaper, but doesn't help (or hurt) creating a value, so 487;; we don't do this for ext/ext/{and,or}. 488;; 489;; These changes result in the sequence extu/bcnd-{eq0,ne0} which is combined 490;; into an alternate form of bb0 and bb1. 491 492(define_split 493 [(set (match_operand:SI 0 "register_operand" "") 494 (ior:SI (neg:SI 495 (match_operator 1 "even_relop" 496 [(match_operand 2 "partial_ccmode_register_operand" "%r") 497 (const_int 0)])) 498 (neg:SI 499 (match_operator 3 "relop" 500 [(match_operand 4 "partial_ccmode_register_operand" "r") 501 (const_int 0)])))) 502 (clobber (match_operand:SI 5 "register_operand" ""))] 503 "reload_completed 504 && GET_CODE (operands[0]) == REG" 505 [(set (match_dup 5) 506 (ior:CCEVEN (match_dup 4) 507 (match_dup 2))) 508 (set (match_dup 0) 509 (neg:SI (match_op_dup 1 [(match_dup 5) (const_int 0)])))] 510 "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0); 511 if (GET_CODE (operands[1]) == GET_CODE (operands[3])) 512 ; /* The conditions match. */ 513 else if (GET_CODE (operands[1]) 514 == reverse_condition (GET_CODE (operands[3]))) 515 /* Reverse the condition by complementing the compare word. */ 516 operands[4] = gen_rtx_NOT (CCmode, operands[4]); 517 else 518 { 519 /* Make the condition pairs line up by rotating the compare word. */ 520 int cv1 = condition_value (operands[1]); 521 int cv2 = condition_value (operands[3]); 522 523 operands[4] = gen_rtx_ROTATE (CCEVENmode, operands[4], 524 GEN_INT (((cv2 & ~1) - (cv1 & ~1)) 525 & 0x1f)); 526 /* Reverse the condition if needed. */ 527 if ((cv1 & 1) != (cv2 & 1)) 528 operands[4] = gen_rtx_NOT (CCmode, operands[4]); 529 }") 530 531(define_split 532 [(set (match_operand:SI 0 "register_operand" "") 533 (ior:SI (neg:SI 534 (match_operator 1 "odd_relop" 535 [(match_operand 2 "partial_ccmode_register_operand" "%r") 536 (const_int 0)])) 537 (neg:SI 538 (match_operator 3 "odd_relop" 539 [(match_operand 4 "partial_ccmode_register_operand" "r") 540 (const_int 0)])))) 541 (clobber (match_operand:SI 5 "register_operand" ""))] 542 "reload_completed 543 && GET_CODE (operands[0]) == REG" 544 [(set (match_dup 5) 545 (and:CCEVEN (match_dup 4) 546 (match_dup 2))) 547 (set (match_dup 0) 548 (neg:SI (match_op_dup 1 [(match_dup 5) (const_int 0)])))] 549 "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0); 550 if (GET_CODE (operands[1]) == GET_CODE (operands[3])) 551 ; /* The conditions match. */ 552 else 553 { 554 /* Make the condition pairs line up by rotating the compare word. */ 555 int cv1 = condition_value (operands[1]); 556 int cv2 = condition_value (operands[3]); 557 558 operands[4] = gen_rtx_ROTATE (CCEVENmode, operands[4], 559 GEN_INT ((cv2 - cv1) & 0x1f)); 560 }") 561 562(define_split 563 [(set (match_operand:SI 0 "register_operand" "") 564 (ior:SI (neg:SI 565 (match_operator 1 "odd_relop" 566 [(match_operand 2 "partial_ccmode_register_operand" "%r") 567 (const_int 0)])) 568 (neg:SI 569 (match_operator 3 "even_relop" 570 [(match_operand 4 "partial_ccmode_register_operand" "r") 571 (const_int 0)])))) 572 (clobber (match_operand:SI 5 "register_operand" ""))] 573 "reload_completed 574 && GET_CODE (operands[0]) == REG" 575 [(set (match_dup 5) 576 (ior:CCEVEN (not:CC (match_dup 2)) 577 (match_dup 4))) 578 (set (match_dup 0) 579 (neg:SI (match_op_dup 3 [(match_dup 5) (const_int 0)])))] 580 "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0); 581 if (GET_CODE (operands[1]) 582 == reverse_condition (GET_CODE (operands[3]))) 583 ; 584 else 585 { 586 /* Make the condition pairs line up by rotating the compare word. */ 587 int cv1 = condition_value (operands[1]); 588 int cv2 = condition_value (operands[3]); 589 590 operands[2] = gen_rtx_ROTATE (CCEVENmode, operands[2], 591 GEN_INT (((cv1 & ~1) - (cv2 & ~1)) 592 & 0x1f)); 593 }") 594 595(define_split 596 [(set (match_operand:SI 0 "register_operand" "") 597 (ior:SI (match_operator 1 "even_relop" 598 [(match_operand 2 "partial_ccmode_register_operand" "%r") 599 (const_int 0)]) 600 (match_operator 3 "relop" 601 [(match_operand 4 "partial_ccmode_register_operand" "r") 602 (const_int 0)]))) 603 (clobber (match_operand:SI 5 "register_operand" ""))] 604 "reload_completed 605 && GET_CODE (operands[0]) == REG 606 && (GET_CODE (operands[1]) == GET_CODE (operands[3]) 607 || GET_CODE (operands[1]) == reverse_condition (GET_CODE (operands[3])))" 608 [(set (match_dup 5) 609 (ior:CCEVEN (match_dup 4) 610 (match_dup 2))) 611 (set (match_dup 0) 612 (match_op_dup 1 [(match_dup 5) (const_int 0)]))] 613 "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0); 614 /* Reverse the condition by complementing the compare word. */ 615 if (GET_CODE (operands[1]) != GET_CODE (operands[3])) 616 operands[4] = gen_rtx_NOT (CCmode, operands[4]);") 617 618(define_split 619 [(set (match_operand:SI 0 "register_operand" "") 620 (ior:SI (match_operator 1 "odd_relop" 621 [(match_operand 2 "partial_ccmode_register_operand" "%r") 622 (const_int 0)]) 623 (match_operator 3 "odd_relop" 624 [(match_operand 4 "partial_ccmode_register_operand" "r") 625 (const_int 0)]))) 626 (clobber (match_operand:SI 5 "register_operand" ""))] 627 "reload_completed 628 && GET_CODE (operands[0]) == REG 629 && GET_CODE (operands[1]) == GET_CODE (operands[3])" 630 [(set (match_dup 5) 631 (and:CCEVEN (match_dup 4) 632 (match_dup 2))) 633 (set (match_dup 0) 634 (match_op_dup 1 [(match_dup 5) (const_int 0)]))] 635 "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0);") 636 637(define_split 638 [(set (match_operand:SI 0 "register_operand" "") 639 (ior:SI (match_operator 1 "odd_relop" 640 [(match_operand 2 "partial_ccmode_register_operand" "%r") 641 (const_int 0)]) 642 (match_operator 3 "even_relop" 643 [(match_operand 4 "partial_ccmode_register_operand" "r") 644 (const_int 0)]))) 645 (clobber (match_operand:SI 5 "register_operand" ""))] 646 "reload_completed 647 && GET_CODE (operands[0]) == REG 648 && GET_CODE (operands[1]) == reverse_condition (GET_CODE (operands[3]))" 649 [(set (match_dup 5) 650 (ior:CCEVEN (not:CC (match_dup 4)) 651 (match_dup 2))) 652 (set (match_dup 0) 653 (match_op_dup 1 [(match_dup 5) (const_int 0)]))] 654 "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0);") 655 656(define_split 657 [(set (match_operand:SI 0 "register_operand" "") 658 (and:SI (neg:SI 659 (match_operator 1 "even_relop" 660 [(match_operand 2 "partial_ccmode_register_operand" "%r") 661 (const_int 0)])) 662 (neg:SI 663 (match_operator 3 "relop" 664 [(match_operand 4 "partial_ccmode_register_operand" "r") 665 (const_int 0)])))) 666 (clobber (match_operand:SI 5 "register_operand" ""))] 667 "reload_completed 668 && GET_CODE (operands[0]) == REG" 669 [(set (match_dup 5) 670 (and:CCEVEN (match_dup 4) 671 (match_dup 2))) 672 (set (match_dup 0) 673 (neg:SI (match_op_dup 1 [(match_dup 5) (const_int 0)])))] 674 "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0); 675 if (GET_CODE (operands[1]) == GET_CODE (operands[3])) 676 ; /* The conditions match. */ 677 else if (GET_CODE (operands[1]) 678 == reverse_condition (GET_CODE (operands[3]))) 679 /* Reverse the condition by complementing the compare word. */ 680 operands[4] = gen_rtx_NOT (CCmode, operands[4]); 681 else 682 { 683 /* Make the condition pairs line up by rotating the compare word. */ 684 int cv1 = condition_value (operands[1]); 685 int cv2 = condition_value (operands[3]); 686 operands[4] = gen_rtx_ROTATE (CCmode, operands[4], 687 GEN_INT (((cv2 & ~1) - (cv1 & ~1)) 688 & 0x1f)); 689 /* Reverse the condition if needed. */ 690 if ((cv1 & 1) != (cv2 & 1)) 691 operands[4] = gen_rtx_NOT (CCmode, operands[4]); 692 }") 693 694(define_split 695 [(set (match_operand:SI 0 "register_operand" "") 696 (and:SI (neg:SI 697 (match_operator 1 "odd_relop" 698 [(match_operand 2 "partial_ccmode_register_operand" "%r") 699 (const_int 0)])) 700 (neg:SI 701 (match_operator 3 "odd_relop" 702 [(match_operand 4 "partial_ccmode_register_operand" "r") 703 (const_int 0)])))) 704 (clobber (match_operand:SI 5 "register_operand" ""))] 705 "reload_completed 706 && GET_CODE (operands[0]) == REG" 707 [(set (match_dup 5) 708 (ior:CCEVEN (match_dup 4) 709 (match_dup 2))) 710 (set (match_dup 0) 711 (neg:SI (match_op_dup 1 [(match_dup 5) (const_int 0)])))] 712 "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0); 713 if (GET_CODE (operands[1]) == GET_CODE (operands[3])) 714 ; /* The conditions match. */ 715 else 716 { 717 /* Make the condition pairs line up by rotating the compare word. */ 718 int cv1 = condition_value (operands[1]); 719 int cv2 = condition_value (operands[3]); 720 operands[4] = gen_rtx_ROTATE (CCEVENmode, operands[4], 721 GEN_INT ((cv2 - cv1) & 0x1f)); 722 }") 723 724(define_split 725 [(set (match_operand:SI 0 "register_operand" "") 726 (and:SI (neg:SI 727 (match_operator 1 "odd_relop" 728 [(match_operand 2 "partial_ccmode_register_operand" "%r") 729 (const_int 0)])) 730 (neg:SI 731 (match_operator 3 "even_relop" 732 [(match_operand 4 "partial_ccmode_register_operand" "r") 733 (const_int 0)])))) 734 (clobber (match_operand:SI 5 "register_operand" ""))] 735 "reload_completed 736 && GET_CODE (operands[0]) == REG" 737 [(set (match_dup 5) 738 (and:CCEVEN (not:CC (match_dup 2)) 739 (match_dup 4))) 740 (set (match_dup 0) 741 (neg:SI (match_op_dup 3 [(match_dup 5) (const_int 0)])))] 742 "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0); 743 if (GET_CODE (operands[1]) 744 == reverse_condition (GET_CODE (operands[3]))) 745 ; 746 else 747 { 748 /* Make the condition pairs line up by rotating the compare word. */ 749 int cv1 = condition_value (operands[1]); 750 int cv2 = condition_value (operands[3]); 751 operands[2] = gen_rtx_ROTATE (CCEVENmode, operands[2], 752 GEN_INT (((cv1 & ~1) - (cv2 & ~1)) 753 & 0x1f)); 754 }") 755 756(define_split 757 [(set (match_operand:SI 0 "register_operand" "") 758 (and:SI (match_operator 1 "even_relop" 759 [(match_operand 2 "partial_ccmode_register_operand" "%r") 760 (const_int 0)]) 761 (match_operator 3 "relop" 762 [(match_operand 4 "partial_ccmode_register_operand" "r") 763 (const_int 0)]))) 764 (clobber (match_operand:SI 5 "register_operand" ""))] 765 "reload_completed 766 && GET_CODE (operands[0]) == REG 767 && (GET_CODE (operands[1]) == GET_CODE (operands[3]) 768 || GET_CODE (operands[1]) == reverse_condition (GET_CODE (operands[3])))" 769 [(set (match_dup 5) 770 (and:CCEVEN (match_dup 4) 771 (match_dup 2))) 772 (set (match_dup 0) 773 (match_op_dup 1 [(match_dup 5) (const_int 0)]))] 774 "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0); 775 /* Reverse the condition by complementing the compare word. */ 776 if (GET_CODE (operands[1]) != GET_CODE (operands[3])) 777 operands[4] = gen_rtx_NOT (CCmode, operands[4]);") 778 779(define_split 780 [(set (match_operand:SI 0 "register_operand" "") 781 (and:SI (match_operator 1 "odd_relop" 782 [(match_operand 2 "partial_ccmode_register_operand" "%r") 783 (const_int 0)]) 784 (match_operator 3 "odd_relop" 785 [(match_operand 4 "partial_ccmode_register_operand" "r") 786 (const_int 0)]))) 787 (clobber (match_operand:SI 5 "register_operand" ""))] 788 "reload_completed 789 && GET_CODE (operands[0]) == REG 790 && GET_CODE (operands[1]) == GET_CODE (operands[3])" 791 [(set (match_dup 5) 792 (ior:CCEVEN (match_dup 4) 793 (match_dup 2))) 794 (set (match_dup 0) 795 (match_op_dup 1 [(match_dup 5) (const_int 0)]))] 796 "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0);") 797 798(define_split 799 [(set (match_operand:SI 0 "register_operand" "") 800 (and:SI (match_operator 1 "odd_relop" 801 [(match_operand 2 "partial_ccmode_register_operand" "%r") 802 (const_int 0)]) 803 (match_operator 3 "even_relop" 804 [(match_operand 4 "partial_ccmode_register_operand" "r") 805 (const_int 0)]))) 806 (clobber (match_operand:SI 5 "register_operand" ""))] 807 "reload_completed 808 && GET_CODE (operands[0]) == REG 809 && GET_CODE (operands[1]) == reverse_condition (GET_CODE (operands[3]))" 810 [(set (match_dup 5) 811 (and:CCEVEN (not:CC (match_dup 2)) 812 (match_dup 4))) 813 (set (match_dup 0) 814 (match_op_dup 3 [(match_dup 5) (const_int 0)]))] 815 "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0);") 816 817 818;; Logical operations on compare words. 819 820(define_insn "" 821 [(set (match_operand:CCEVEN 0 "register_operand" "=r") 822 (and:CCEVEN (not:CC (match_operand 1 "partial_ccmode_register_operand" "r")) 823 (match_operand 2 "partial_ccmode_register_operand" "r")))] 824 "" 825 "and.c %0,%2,%1") 826 827(define_insn "" 828 [(set (match_operand:CCEVEN 0 "register_operand" "=r") 829 (and:CCEVEN (match_operand 1 "partial_ccmode_register_operand" "%r") 830 (match_operand 2 "partial_ccmode_register_operand" "r")))] 831 "" 832 "and %0,%1,%2") 833 834(define_insn "" 835 [(set (match_operand:CCEVEN 0 "register_operand" "=r") 836 (ior:CCEVEN (not:CC (match_operand 1 "partial_ccmode_register_operand" "r")) 837 (match_operand 2 "partial_ccmode_register_operand" "r")))] 838 "" 839 "or.c %0,%2,%1") 840 841(define_insn "" 842 [(set (match_operand:CCEVEN 0 "register_operand" "=r") 843 (ior:CCEVEN (match_operand 1 "partial_ccmode_register_operand" "%r") 844 (match_operand 2 "partial_ccmode_register_operand" "r")))] 845 "" 846 "or %0,%1,%2") 847 848(define_insn "" 849 [(set (match_operand:CC 0 "register_operand" "=r") 850 (rotate:CC (match_operand:CC 1 "register_operand" "r") 851 (match_operand:CC 2 "int5_operand" "")))] 852 "" 853 "rot %0,%1,%2" 854 [(set_attr "type" "bit")]) 855 856(define_insn "" 857 [(set (match_operand:CCEVEN 0 "register_operand" "=r") 858 (rotate:CCEVEN (match_operand 1 "partial_ccmode_register_operand" "r") 859 (match_operand:CC 2 "int5_operand" "")))] 860 "" 861 "rot %0,%1,%2" 862 [(set_attr "type" "bit")]) 863 864;; rotate/and[.c] and rotate/ior[.c] 865 866(define_split 867 [(set (match_operand:CCEVEN 0 "register_operand" "") 868 (ior:CCEVEN (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "") 869 (match_operand:CC 2 "int5_operand" "")) 870 (match_operand 3 "partial_ccmode_register_operand" ""))) 871 (clobber (match_operand:CCEVEN 4 "register_operand" ""))] 872 "reload_completed 873 && GET_CODE (operands[0]) == REG 874 && partial_ccmode_register_operand (operands[1], VOIDmode) 875 && partial_ccmode_register_operand (operands[3], VOIDmode)" 876 [(set (match_dup 4) 877 (rotate:CC (match_dup 1) (match_dup 2))) 878 (set (match_dup 0) 879 (ior:CCEVEN (match_dup 4) (match_dup 3)))] 880 "") 881 882(define_insn "" 883 [(set (match_operand:CCEVEN 0 "register_operand" "=r") 884 (ior:CCEVEN (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r") 885 (match_operand:CC 2 "int5_operand" "")) 886 (match_operand 3 "partial_ccmode_register_operand" "r"))) 887 (clobber (match_scratch:CCEVEN 4 "=r"))] 888 "" 889 "#") 890 891(define_split 892 [(set (match_operand:CCEVEN 0 "register_operand" "") 893 (ior:CCEVEN (not:CC (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "") 894 (match_operand:CC 2 "int5_operand" ""))) 895 (match_operand 3 "partial_ccmode_register_operand" ""))) 896 (clobber (match_operand:CCEVEN 4 "register_operand" ""))] 897 "reload_completed 898 && GET_CODE (operands[0]) == REG 899 && partial_ccmode_register_operand (operands[1], VOIDmode) 900 && partial_ccmode_register_operand (operands[3], VOIDmode)" 901 [(set (match_dup 4) 902 (rotate:CC (match_dup 1) (match_dup 2))) 903 (set (match_dup 0) 904 (ior:CCEVEN (not:CC (match_dup 4)) (match_dup 3)))] 905 "") 906 907(define_insn "" 908 [(set (match_operand:CCEVEN 0 "register_operand" "=r") 909 (ior:CCEVEN (not:CC (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r") 910 (match_operand:CC 2 "int5_operand" ""))) 911 (match_operand 3 "partial_ccmode_register_operand" "r"))) 912 (clobber (match_scratch:CCEVEN 4 "=r"))] 913 "" 914 "#") 915 916(define_split 917 [(set (match_operand:CCEVEN 0 "register_operand" "") 918 (and:CCEVEN (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "") 919 (match_operand:CC 2 "int5_operand" "")) 920 (match_operand 3 "partial_ccmode_register_operand" ""))) 921 (clobber (match_operand:CCEVEN 4 "register_operand" ""))] 922 "reload_completed 923 && GET_CODE (operands[0]) == REG 924 && partial_ccmode_register_operand (operands[1], VOIDmode) 925 && partial_ccmode_register_operand (operands[3], VOIDmode)" 926 [(set (match_dup 4) 927 (rotate:CC (match_dup 1) (match_dup 2))) 928 (set (match_dup 0) 929 (and:CCEVEN (match_dup 4) (match_dup 3)))] 930 "") 931 932(define_insn "" 933 [(set (match_operand:CCEVEN 0 "register_operand" "=r") 934 (and:CCEVEN (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r") 935 (match_operand:CC 2 "int5_operand" "")) 936 (match_operand 3 "partial_ccmode_register_operand" "r"))) 937 (clobber (match_scratch:CCEVEN 4 "=r"))] 938 "" 939 "#") 940 941(define_split 942 [(set (match_operand:CCEVEN 0 "register_operand" "") 943 (and:CCEVEN (not:CC (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "") 944 (match_operand:CC 2 "int5_operand" ""))) 945 (match_operand 3 "partial_ccmode_register_operand" ""))) 946 (clobber (match_operand:CCEVEN 4 "register_operand" ""))] 947 "reload_completed 948 && GET_CODE (operands[0]) == REG 949 && partial_ccmode_register_operand (operands[1], VOIDmode) 950 && partial_ccmode_register_operand (operands[3], VOIDmode)" 951 [(set (match_dup 4) 952 (rotate:CC (match_dup 1) (match_dup 2))) 953 (set (match_dup 0) 954 (and:CCEVEN (not:CC (match_dup 4)) (match_dup 3)))] 955 "") 956 957(define_insn "" 958 [(set (match_operand:CCEVEN 0 "register_operand" "=r") 959 (and:CCEVEN (not:CC (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r") 960 (match_operand:CC 2 "int5_operand" ""))) 961 (match_operand 3 "partial_ccmode_register_operand" "r"))) 962 (clobber (match_scratch:CCEVEN 4 "=r"))] 963 "" 964 "#") 965 966 967;; Recognize bcnd instructions for integer values. This is distinguished 968;; from a conditional branch instruction (below) with SImode instead of 969;; CCmode. 970 971(define_insn "" 972 [(set (pc) 973 (if_then_else 974 (match_operator 0 "relop_no_unsigned" 975 [(match_operand:SI 1 "register_operand" "r") 976 (const_int 0)]) 977 (match_operand 2 "pc_or_label_ref" "") 978 (match_operand 3 "pc_or_label_ref" "")))] 979 "" 980 "bcnd%. %R3%B0,%1,%P2%P3" 981 [(set_attr "type" "branch")]) 982 983;; Recognize tests for sign and zero. 984 985(define_insn "" 986 [(set (pc) 987 (if_then_else 988 (match_operator 0 "equality_op" 989 [(match_operand:SI 1 "register_operand" "r") 990 (const_int -2147483648)]) 991 (match_operand 2 "pc_or_label_ref" "") 992 (match_operand 3 "pc_or_label_ref" "")))] 993 "" 994 "bcnd%. %R3%E0,%1,%P2%P3" 995 [(set_attr "type" "branch")]) 996 997(define_insn "" 998 [(set (pc) 999 (if_then_else 1000 (match_operator 0 "equality_op" 1001 [(zero_extract:SI 1002 (match_operand:SI 1 "register_operand" "r") 1003 (const_int 31) 1004 (const_int 1)) 1005 (const_int 0)]) 1006 (match_operand 2 "pc_or_label_ref" "") 1007 (match_operand 3 "pc_or_label_ref" "")))] 1008 "" 1009 "bcnd%. %R3%D0,%1,%P2%P3" 1010 [(set_attr "type" "branch")]) 1011 1012;; Recognize bcnd instructions for double integer values 1013 1014(define_insn "" 1015 [(set (pc) 1016 (if_then_else 1017 (match_operator 0 "relop_no_unsigned" 1018 [(sign_extend:DI 1019 (match_operand:SI 1 "register_operand" "r")) 1020 (const_int 0)]) 1021 (match_operand 2 "pc_or_label_ref" "") 1022 (match_operand 3 "pc_or_label_ref" "")))] 1023 "" 1024 "bcnd%. %R3%B0,%1,%P2%P3" 1025 [(set_attr "type" "branch")]) 1026 1027(define_insn "" 1028 [(set (pc) 1029 (if_then_else 1030 (match_operator 0 "equality_op" 1031 [(zero_extend:DI 1032 (match_operand:SI 1 "register_operand" "r")) 1033 (const_int 0)]) 1034 (match_operand 2 "pc_or_label_ref" "") 1035 (match_operand 3 "pc_or_label_ref" "")))] 1036 "" 1037 "bcnd%. %R3%B0,%1,%P2%P3" 1038 [(set_attr "type" "branch")]) 1039 1040;; Recognize bcnd instructions for single precision float values 1041;; Exclude relational operations as they must signal NaNs. 1042 1043;; @@ These bcnd insns for float and double values don't seem to be recognized. 1044 1045(define_insn "" 1046 [(set (pc) 1047 (if_then_else 1048 (match_operator 0 "equality_op" 1049 [(float_extend:DF 1050 (match_operand:SF 1 "register_operand" "r")) 1051 (const_int 0)]) 1052 (match_operand 2 "pc_or_label_ref" "") 1053 (match_operand 3 "pc_or_label_ref" "")))] 1054 "" 1055 "bcnd%. %R3%D0,%1,%P2%P3" 1056 [(set_attr "type" "branch")]) 1057 1058(define_insn "" 1059 [(set (pc) 1060 (if_then_else 1061 (match_operator 0 "equality_op" 1062 [(match_operand:SF 1 "register_operand" "r") 1063 (const_int 0)]) 1064 (match_operand 2 "pc_or_label_ref" "") 1065 (match_operand 3 "pc_or_label_ref" "")))] 1066 "" 1067 "bcnd%. %R3%D0,%1,%P2%P3" 1068 [(set_attr "type" "branch")]) 1069 1070;; Recognize bcnd instructions for double precision float values 1071;; Exclude relational operations as they must signal NaNs. 1072 1073(define_insn "" 1074 [(set (pc) 1075 (if_then_else 1076 (match_operator 0 "equality_op" 1077 [(match_operand:DF 1 "register_operand" "r") 1078 (const_int 0)]) 1079 (match_operand 2 "pc_or_label_ref" "") 1080 (match_operand 3 "pc_or_label_ref" "")))] 1081 "" 1082{ 1083 if (GET_CODE (operands[0]) == NE) 1084 { 1085 rtx op2 = operands[2]; 1086 operands[2] = operands[3]; 1087 operands[3] = op2; 1088 } 1089 if (GET_CODE (operands[3]) == LABEL_REF) 1090 return "bcnd 0x5,%1,%3\;bcnd %#ne0,%d1,%3"; 1091 1092 operands[3] = gen_label_rtx (); 1093 output_asm_insn ("bcnd 0x5,%1,%3\;bcnd %#eq0,%d1,%2", operands); 1094 emit_label (operands[3]); 1095 return ""; 1096} 1097 [(set_attr "type" "weird") 1098 (set_attr "length" "3")]) 1099 1100;; Recognize bb0 and bb1 instructions. These use two unusual template 1101;; patterns, %Lx and %Px. %Lx outputs a 1 if operand `x' is a LABEL_REF 1102;; otherwise it outputs a 0. It then may print ".n" if the delay slot 1103;; is used. %Px does noting if `x' is PC and outputs the operand if `x' 1104;; is a LABEL_REF. 1105 1106(define_insn "" 1107 [(set (pc) 1108 (if_then_else 1109 (ne (sign_extract:SI (match_operand:SI 0 "register_operand" "r") 1110 (const_int 1) 1111 (match_operand:SI 1 "int5_operand" "")) 1112 (const_int 0)) 1113 (match_operand 2 "pc_or_label_ref" "") 1114 (match_operand 3 "pc_or_label_ref" "")))] 1115 "" 1116 "bb%L2 (31-%1),%0,%P2%P3" 1117 [(set_attr "type" "branch")]) 1118 1119(define_insn "" 1120 [(set (pc) 1121 (if_then_else 1122 (eq (sign_extract:SI (match_operand:SI 0 "register_operand" "r") 1123 (const_int 1) 1124 (match_operand:SI 1 "int5_operand" "")) 1125 (const_int 0)) 1126 (match_operand 2 "pc_or_label_ref" "") 1127 (match_operand 3 "pc_or_label_ref" "")))] 1128 "" 1129 "bb%L3 (31-%1),%0,%P2%P3" 1130 [(set_attr "type" "branch")]) 1131 1132(define_insn "" 1133 [(set (pc) 1134 (if_then_else 1135 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r") 1136 (const_int 1) 1137 (match_operand:SI 1 "int5_operand" "")) 1138 (const_int 0)) 1139 (match_operand 2 "pc_or_label_ref" "") 1140 (match_operand 3 "pc_or_label_ref" "")))] 1141 "" 1142 "bb%L2 (31-%1),%0,%P2%P3" 1143 [(set_attr "type" "branch")]) 1144 1145(define_insn "" 1146 [(set (pc) 1147 (if_then_else 1148 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r") 1149 (const_int 1) 1150 (match_operand:SI 1 "int5_operand" "")) 1151 (const_int 0)) 1152 (match_operand 2 "pc_or_label_ref" "") 1153 (match_operand 3 "pc_or_label_ref" "")))] 1154 "" 1155 "bb%L3 (31-%1),%0,%P2%P3" 1156 [(set_attr "type" "branch")]) 1157 1158(define_insn "" 1159 [(set (pc) 1160 (if_then_else 1161 (eq (and:SI (match_operand:SI 0 "reg_or_bbx_mask_operand" "%r") 1162 (match_operand:SI 1 "reg_or_bbx_mask_operand" "n")) 1163 (const_int 0)) 1164 (match_operand 2 "pc_or_label_ref" "") 1165 (match_operand 3 "pc_or_label_ref" "")))] 1166 "(GET_CODE (operands[0]) == CONST_INT) 1167 != (GET_CODE (operands[1]) == CONST_INT)" 1168 "bb%L3 %p1,%0,%P2%P3" 1169 [(set_attr "type" "branch")]) 1170 1171(define_insn "" 1172 [(set (pc) 1173 (if_then_else 1174 (ne (and:SI (match_operand:SI 0 "reg_or_bbx_mask_operand" "%r") 1175 (match_operand:SI 1 "reg_or_bbx_mask_operand" "n")) 1176 (const_int 0)) 1177 (match_operand 2 "pc_or_label_ref" "") 1178 (match_operand 3 "pc_or_label_ref" "")))] 1179 "(GET_CODE (operands[0]) == CONST_INT) 1180 != (GET_CODE (operands[1]) == CONST_INT)" 1181 "bb%L2 %p1,%0,%P2%P3" 1182 [(set_attr "type" "branch")]) 1183 1184;; The comparison operations store the comparison into a register and 1185;; record that register. The following Bxx or Sxx insn uses that 1186;; register as an input. To facilitate use of bcnd instead of cmp/bb1, 1187;; cmpsi records its operands and produces no code when any operand 1188;; is constant. In this case, the Bxx insns use gen_bcnd and the 1189;; Sxx insns use gen_test to ensure a cmp has been emitted. 1190;; 1191;; This could also be done for SFmode and DFmode having only beq and bne 1192;; use gen_bcnd. The others must signal NaNs. It seems though that zero 1193;; has already been copied into a register. 1194;; 1195;; cmpsi/beq and cmpsi/bne can always be done with bcnd if any operand 1196;; is a constant. (This idea is due to Torbjorn Granlund.) Others can 1197;; use bcnd only if an operand is zero. 1198;; 1199;; It is necessary to distinguish a register holding condition codes. 1200;; This is done by context. 1201 1202(define_expand "test" 1203 [(set (match_dup 2) 1204 (compare:CC (match_operand 0 "" "") 1205 (match_operand 1 "" "")))] 1206 "" 1207 " 1208{ 1209 gcc_assert (m88k_compare_reg == NULL_RTX); 1210 1211 if (GET_CODE (operands[0]) == CONST_INT 1212 && ! SMALL_INT (operands[0])) 1213 operands[0] = force_reg (SImode, operands[0]); 1214 1215 if (GET_CODE (operands[1]) == CONST_INT 1216 && ! SMALL_INT (operands[1])) 1217 operands[1] = force_reg (SImode, operands[1]); 1218 1219 operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode); 1220}") 1221 1222(define_expand "cmpsi" 1223 [(set (match_dup 2) 1224 (compare:CC (match_operand:SI 0 "register_operand" "") 1225 (match_operand:SI 1 "arith32_operand" "")))] 1226 "" 1227 " 1228{ 1229 if (GET_CODE (operands[0]) == CONST_INT 1230 || GET_CODE (operands[1]) == CONST_INT) 1231 { 1232 m88k_compare_reg = NULL_RTX; 1233 m88k_compare_op0 = operands[0]; 1234 m88k_compare_op1 = operands[1]; 1235 DONE; 1236 } 1237 operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode); 1238}") 1239 1240(define_expand "cmpsf" 1241 [(set (match_dup 2) 1242 (compare:CC (match_operand:SF 0 "register_operand" "") 1243 (match_operand:SF 1 "register_operand" "")))] 1244 "" 1245 "operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);") 1246 1247(define_expand "cmpdf" 1248 [(set (match_dup 2) 1249 (compare:CC (match_operand:DF 0 "general_operand" "") 1250 (match_operand:DF 1 "general_operand" "")))] 1251 "" 1252 " 1253{ 1254 operands[0] = legitimize_operand (operands[0], DFmode); 1255 operands[1] = legitimize_operand (operands[1], DFmode); 1256 operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode); 1257}") 1258 1259;; The actual compare instructions. 1260 1261(define_insn "" 1262 [(set (match_operand:CC 0 "register_operand" "=r") 1263 (compare:CC (match_operand:SI 1 "register_operand" "rO") 1264 (match_operand:SI 2 "arith_operand" "rI")))] 1265 "" 1266 "cmp %0,%r1,%2") 1267 1268(define_insn "" 1269 [(set (match_operand:CC 0 "register_operand" "=r,r,r,r") 1270 (compare:CC (match_operand:SF 1 "register_operand" "r,r,x,x") 1271 (match_operand:SF 2 "real_or_0_operand" "r,G,x,G")))] 1272 "" 1273 "@ 1274 fcmp.sss %0,%1,%2 1275 fcmp.sss %0,%1,%#r0 1276 fcmp.sss %0,%1,%2 1277 fcmp.sss %0,%1,%#x0" 1278 [(set_attr "type" "spcmp")]) 1279 1280(define_insn "" 1281 [(set (match_operand:CC 0 "register_operand" "=r,r") 1282 (compare:CC (match_operand:DF 1 "register_operand" "r,x") 1283 (float_extend:DF 1284 (match_operand:SF 2 "register_operand" "r,x"))))] 1285 "" 1286 "fcmp.sds %0,%1,%2" 1287 [(set_attr "type" "dpcmp")]) 1288 1289(define_insn "" 1290 [(set (match_operand:CC 0 "register_operand" "=r,r") 1291 (compare:CC (float_extend:DF 1292 (match_operand:SF 1 "register_operand" "r,x")) 1293 (match_operand:DF 2 "register_operand" "r,x")))] 1294 "" 1295 "fcmp.ssd %0,%1,%2" 1296 [(set_attr "type" "dpcmp")]) 1297 1298(define_insn "" 1299 [(set (match_operand:CC 0 "register_operand" "=r,r,r,r") 1300 (compare:CC (match_operand:DF 1 "register_operand" "r,r,x,x") 1301 (match_operand:DF 2 "real_or_0_operand" "r,G,x,G")))] 1302 "" 1303 "@ 1304 fcmp.sdd %0,%1,%2 1305 fcmp.sds %0,%1,%#r0 1306 fcmp.sdd %0,%1,%2 1307 fcmp.sds %0,%1,%#x0" 1308 [(set_attr "type" "dpcmp")]) 1309 1310;; Store condition code insns. The compare insns set a register 1311;; rather than cc0 and record that register for use here. See above 1312;; for the special treatment of cmpsi with a constant operand. 1313 1314;; @@ For the m88110, use fcmpu for bxx sxx inequality comparisons. 1315 1316(define_expand "seq" 1317 [(set (match_operand:SI 0 "register_operand" "") 1318 (match_dup 1))] 1319 "" 1320 "operands[1] = emit_test (EQ, SImode);") 1321 1322(define_expand "sne" 1323 [(set (match_operand:SI 0 "register_operand" "") 1324 (match_dup 1))] 1325 "" 1326 "operands[1] = emit_test (NE, SImode);") 1327 1328(define_expand "sgt" 1329 [(set (match_operand:SI 0 "register_operand" "") 1330 (match_dup 1))] 1331 "" 1332 "operands[1] = emit_test (GT, SImode);") 1333 1334(define_expand "sgtu" 1335 [(set (match_operand:SI 0 "register_operand" "") 1336 (match_dup 1))] 1337 "" 1338 "operands[1] = emit_test (GTU, SImode);") 1339 1340(define_expand "slt" 1341 [(set (match_operand:SI 0 "register_operand" "") 1342 (match_dup 1))] 1343 "" 1344 "operands[1] = emit_test (LT, SImode);") 1345 1346(define_expand "sltu" 1347 [(set (match_operand:SI 0 "register_operand" "") 1348 (match_dup 1))] 1349 "" 1350 "operands[1] = emit_test (LTU, SImode);") 1351 1352(define_expand "sge" 1353 [(set (match_operand:SI 0 "register_operand" "") 1354 (match_dup 1))] 1355 "" 1356 "operands[1] = emit_test (GE, SImode);") 1357 1358(define_expand "sgeu" 1359 [(set (match_operand:SI 0 "register_operand" "") 1360 (match_dup 1))] 1361 "" 1362 "operands[1] = emit_test (GEU, SImode);") 1363 1364(define_expand "sle" 1365 [(set (match_operand:SI 0 "register_operand" "") 1366 (match_dup 1))] 1367 "" 1368 "operands[1] = emit_test (LE, SImode);") 1369 1370(define_expand "sleu" 1371 [(set (match_operand:SI 0 "register_operand" "") 1372 (match_dup 1))] 1373 "" 1374 "operands[1] = emit_test (LEU, SImode);") 1375 1376;; The actual set condition code instruction. 1377 1378(define_insn "" 1379 [(set (match_operand:SI 0 "register_operand" "=r") 1380 (match_operator:SI 1 "relop" 1381 [(match_operand:CC 2 "register_operand" "r") 1382 (const_int 0)]))] 1383 "" 1384 "ext %0,%2,1<%C1>" 1385 [(set_attr "type" "bit")]) 1386 1387(define_insn "" 1388 [(set (match_operand:SI 0 "register_operand" "=r") 1389 (match_operator:SI 1 "even_relop" 1390 [(match_operand:CCEVEN 2 "register_operand" "r") 1391 (const_int 0)]))] 1392 "" 1393 "ext %0,%2,1<%C1>" 1394 [(set_attr "type" "bit")]) 1395 1396(define_insn "" 1397 [(set (match_operand:SI 0 "register_operand" "=r") 1398 (not:SI (match_operator:SI 1 "odd_relop" 1399 [(match_operand:CCEVEN 2 "register_operand" "r") 1400 (const_int 0)])))] 1401 "" 1402 "ext %0,%2,1<%!%C1>" 1403 [(set_attr "type" "bit")]) 1404 1405(define_split 1406 [(set (match_operand:SI 0 "register_operand" "") 1407 (match_operator:SI 1 "odd_relop" 1408 [(match_operand:CCEVEN 2 "register_operand" "r") 1409 (const_int 0)])) 1410 (clobber (match_operand:SI 3 "register_operand" ""))] 1411 "reload_completed 1412 && GET_CODE (operands[0]) == REG" 1413 [(set (match_dup 3) (not:SI (match_op_dup 1 [(match_dup 2) (const_int 0)]))) 1414 (set (match_dup 0) (not:SI (match_dup 3)))] 1415 "") 1416 1417(define_insn "" 1418 [(set (match_operand:SI 0 "register_operand" "=r") 1419 (match_operator:SI 1 "odd_relop" 1420 [(match_operand:CCEVEN 2 "register_operand" "r") 1421 (const_int 0)])) 1422 (clobber (match_scratch:SI 3 "=r"))] 1423 "" 1424 "#") 1425 1426(define_insn "" 1427 [(set (match_operand:SI 0 "register_operand" "=r") 1428 (neg:SI 1429 (match_operator:SI 1 "relop" 1430 [(match_operand:CC 2 "register_operand" "r") 1431 (const_int 0)])))] 1432 "" 1433 "extu %0,%2,1<%C1>" 1434 [(set_attr "type" "bit")]) 1435 1436(define_insn "" 1437 [(set (match_operand:SI 0 "register_operand" "=r") 1438 (neg:SI 1439 (match_operator:SI 1 "even_relop" 1440 [(match_operand:CCEVEN 2 "register_operand" "r") 1441 (const_int 0)])))] 1442 "" 1443 "extu %0,%2,1<%C1>" 1444 [(set_attr "type" "bit")]) 1445 1446(define_insn "" 1447 [(set (match_operand:SI 0 "register_operand" "=r") 1448 (neg:SI 1449 (not:SI (match_operator:SI 1 "odd_relop" 1450 [(match_operand:CCEVEN 2 "register_operand" "r") 1451 (const_int 0)]))))] 1452 "" 1453 "extu %0,%2,1<%!%C1>" 1454 [(set_attr "type" "bit")]) 1455 1456(define_split 1457 [(set (match_operand:SI 0 "register_operand" "") 1458 (neg:SI (match_operator:SI 1 "odd_relop" 1459 [(match_operand:CCEVEN 2 "register_operand" "r") 1460 (const_int 0)]))) 1461 (clobber (match_operand:SI 3 "register_operand" ""))] 1462 "reload_completed 1463 && GET_CODE (operands[0]) == REG" 1464 [(set (match_dup 3) (neg:SI (not:SI (match_op_dup 1 [(match_dup 2) 1465 (const_int 0)])))) 1466 (set (match_dup 0) (xor:SI (match_dup 3) (const_int 1)))] 1467 "") 1468 1469(define_insn 1470 "" 1471 [(set (match_operand:SI 0 "register_operand" "=r") 1472 (neg:SI (match_operator:SI 1 "odd_relop" 1473 [(match_operand:CCEVEN 2 "register_operand" "r") 1474 (const_int 0)]))) 1475 (clobber (match_scratch:SI 3 "=r"))] 1476 "" 1477 "#") 1478 1479 1480 1481 1482;; Conditional branch insns. The compare insns set a register 1483;; rather than cc0 and record that register for use here. See above 1484;; for the special case of cmpsi with a constant operand. 1485 1486(define_expand "bcnd" 1487 [(set (pc) 1488 (if_then_else (match_operand 0 "" "") 1489 (label_ref (match_operand 1 "" "")) 1490 (pc)))] 1491 "" 1492 "gcc_assert (m88k_compare_reg == NULL_RTX);") 1493 1494(define_expand "bxx" 1495 [(set (pc) 1496 (if_then_else (match_operand 0 "" "") 1497 (label_ref (match_operand 1 "" "")) 1498 (pc)))] 1499 "" 1500 "gcc_assert (m88k_compare_reg != NULL_RTX);") 1501 1502(define_expand "beq" 1503 [(set (pc) 1504 (if_then_else (eq (match_dup 1) (const_int 0)) 1505 (label_ref (match_operand 0 "" "")) 1506 (pc)))] 1507 "" 1508 "if (m88k_compare_reg == NULL_RTX) 1509 { 1510 emit_bcnd (EQ, operands[0]); 1511 DONE; 1512 } 1513 operands[1] = m88k_compare_reg;") 1514 1515(define_expand "bne" 1516 [(set (pc) 1517 (if_then_else (ne (match_dup 1) (const_int 0)) 1518 (label_ref (match_operand 0 "" "")) 1519 (pc)))] 1520 "" 1521 "if (m88k_compare_reg == NULL_RTX) 1522 { 1523 emit_bcnd (NE, operands[0]); 1524 DONE; 1525 } 1526 operands[1] = m88k_compare_reg;") 1527 1528(define_expand "bgt" 1529 [(set (pc) 1530 (if_then_else (gt (match_dup 1) (const_int 0)) 1531 (label_ref (match_operand 0 "" "")) 1532 (pc)))] 1533 "" 1534 "if (m88k_compare_reg == NULL_RTX) 1535 { 1536 emit_bcnd (GT, operands[0]); 1537 DONE; 1538 } 1539 operands[1] = m88k_compare_reg;") 1540 1541(define_expand "bgtu" 1542 [(set (pc) 1543 (if_then_else (gtu (match_dup 1) (const_int 0)) 1544 (label_ref (match_operand 0 "" "")) 1545 (pc)))] 1546 "" 1547 "if (m88k_compare_reg == NULL_RTX) 1548 { 1549 emit_jump_insn (gen_bxx (emit_test (GTU, VOIDmode), operands[0])); 1550 DONE; 1551 } 1552 operands[1] = m88k_compare_reg;") 1553 1554(define_expand "blt" 1555 [(set (pc) 1556 (if_then_else (lt (match_dup 1) (const_int 0)) 1557 (label_ref (match_operand 0 "" "")) 1558 (pc)))] 1559 "" 1560 "if (m88k_compare_reg == NULL_RTX) 1561 { 1562 emit_bcnd (LT, operands[0]); 1563 DONE; 1564 } 1565 operands[1] = m88k_compare_reg;") 1566 1567(define_expand "bltu" 1568 [(set (pc) 1569 (if_then_else (ltu (match_dup 1) (const_int 0)) 1570 (label_ref (match_operand 0 "" "")) 1571 (pc)))] 1572 "" 1573 "if (m88k_compare_reg == NULL_RTX) 1574 { 1575 emit_jump_insn (gen_bxx (emit_test (LTU, VOIDmode), operands[0])); 1576 DONE; 1577 } 1578 operands[1] = m88k_compare_reg;") 1579 1580(define_expand "bge" 1581 [(set (pc) 1582 (if_then_else (ge (match_dup 1) (const_int 0)) 1583 (label_ref (match_operand 0 "" "")) 1584 (pc)))] 1585 "" 1586 "if (m88k_compare_reg == NULL_RTX) 1587 { 1588 emit_bcnd (GE, operands[0]); 1589 DONE; 1590 } 1591 operands[1] = m88k_compare_reg;") 1592 1593(define_expand "bgeu" 1594 [(set (pc) 1595 (if_then_else (geu (match_dup 1) (const_int 0)) 1596 (label_ref (match_operand 0 "" "")) 1597 (pc)))] 1598 "" 1599 "if (m88k_compare_reg == NULL_RTX) 1600 { 1601 emit_jump_insn (gen_bxx (emit_test (GEU, VOIDmode), operands[0])); 1602 DONE; 1603 } 1604 operands[1] = m88k_compare_reg;") 1605 1606(define_expand "ble" 1607 [(set (pc) 1608 (if_then_else (le (match_dup 1) (const_int 0)) 1609 (label_ref (match_operand 0 "" "")) 1610 (pc)))] 1611 "" 1612 "if (m88k_compare_reg == NULL_RTX) 1613 { 1614 emit_bcnd (LE, operands[0]); 1615 DONE; 1616 } 1617 operands[1] = m88k_compare_reg;") 1618 1619(define_expand "bleu" 1620 [(set (pc) 1621 (if_then_else (leu (match_dup 1) (const_int 0)) 1622 (label_ref (match_operand 0 "" "")) 1623 (pc)))] 1624 "" 1625 "if (m88k_compare_reg == NULL_RTX) 1626 { 1627 emit_jump_insn (gen_bxx (emit_test (LEU, VOIDmode), operands[0])); 1628 DONE; 1629 } 1630 operands[1] = m88k_compare_reg;") 1631 1632;; The actual conditional branch instruction (both directions). This 1633;; uses two unusual template patterns, %Rx and %Px. %Rx is a prefix code 1634;; for the immediately following condition and reverses the condition iff 1635;; operand `x' is a LABEL_REF. %Px does nothing if `x' is PC and outputs 1636;; the operand if `x' is a LABEL_REF. 1637 1638(define_insn "" 1639 [(set (pc) (if_then_else 1640 (match_operator 0 "relop" 1641 [(match_operand:CC 1 "register_operand" "r") 1642 (const_int 0)]) 1643 (match_operand 2 "pc_or_label_ref" "") 1644 (match_operand 3 "pc_or_label_ref" "")))] 1645 "" 1646{ 1647 if (mostly_false_jump (insn, operands[0])) 1648 return "bb0%. %R2%C0,%1,%P2%P3"; 1649 else 1650 return "bb1%. %R3%C0,%1,%P2%P3"; 1651} 1652 [(set_attr "type" "branch")]) 1653 1654;; 1655;; Here branch prediction is sacrificed. To get it back, you need 1656;; - CCODD (CC mode where the ODD bits are valid) 1657;; - several define_split that can apply De Morgan's Law. 1658;; - transformations between CCEVEN and CCODD modes. 1659;; 1660 1661(define_insn "" 1662 [(set (pc) (if_then_else 1663 (match_operator 0 "even_relop" 1664 [(match_operand:CCEVEN 1 "register_operand" "r") 1665 (const_int 0)]) 1666 (match_operand 2 "pc_or_label_ref" "") 1667 (match_operand 3 "pc_or_label_ref" "")))] 1668 "" 1669 "bb%L2%. %C0,%1,%P2%P3" 1670 [(set_attr "type" "branch")]) 1671 1672(define_insn "" 1673 [(set (pc) (if_then_else 1674 (match_operator 0 "odd_relop" 1675 [(match_operand:CCEVEN 1 "register_operand" "r") 1676 (const_int 0)]) 1677 (match_operand 2 "pc_or_label_ref" "") 1678 (match_operand 3 "pc_or_label_ref" "")))] 1679 "" 1680 "bb%L3%. %!%C0,%1,%P2%P3" 1681 [(set_attr "type" "branch")]) 1682 1683;; Branch conditional on scc values. These arise from manipulations on 1684;; compare words above. 1685;; Are these really used ? 1686 1687(define_insn "" 1688 [(set (pc) 1689 (if_then_else 1690 (ne (match_operator 0 "relop" 1691 [(match_operand:CC 1 "register_operand" "r") 1692 (const_int 0)]) 1693 (const_int 0)) 1694 (match_operand 2 "pc_or_label_ref" "") 1695 (match_operand 3 "pc_or_label_ref" "")))] 1696 "" 1697 "bb%L2 %C0,%1,%P2%P3" 1698 [(set_attr "type" "branch")]) 1699 1700(define_insn "" 1701 [(set (pc) 1702 (if_then_else 1703 (ne (match_operator 0 "even_relop" 1704 [(match_operand:CCEVEN 1 "register_operand" "r") 1705 (const_int 0)]) 1706 (const_int 0)) 1707 (match_operand 2 "pc_or_label_ref" "") 1708 (match_operand 3 "pc_or_label_ref" "")))] 1709 "" 1710 "bb%L2 %C0,%1,%P2%P3" 1711 [(set_attr "type" "branch")]) 1712 1713(define_insn "" 1714 [(set (pc) 1715 (if_then_else 1716 (ne (match_operator 0 "odd_relop" 1717 [(match_operand:CCEVEN 1 "register_operand" "r") 1718 (const_int 0)]) 1719 (const_int 0)) 1720 (match_operand 2 "pc_or_label_ref" "") 1721 (match_operand 3 "pc_or_label_ref" "")))] 1722 "" 1723 "bb%L3 %!%C0,%1,%P2%P3" 1724 [(set_attr "type" "branch")]) 1725 1726(define_insn "" 1727 [(set (pc) 1728 (if_then_else 1729 (eq (match_operator 0 "relop" 1730 [(match_operand:CC 1 "register_operand" "r") 1731 (const_int 0)]) 1732 (const_int 0)) 1733 (match_operand 2 "pc_or_label_ref" "") 1734 (match_operand 3 "pc_or_label_ref" "")))] 1735 "" 1736 "bb%L3 %C0,%1,%P2%P3" 1737 [(set_attr "type" "branch")]) 1738 1739(define_insn "" 1740 [(set (pc) 1741 (if_then_else 1742 (eq (match_operator 0 "even_relop" 1743 [(match_operand:CCEVEN 1 "register_operand" "r") 1744 (const_int 0)]) 1745 (const_int 0)) 1746 (match_operand 2 "pc_or_label_ref" "") 1747 (match_operand 3 "pc_or_label_ref" "")))] 1748 "" 1749 "bb%L3 %C0,%1,%P2%P3" 1750 [(set_attr "type" "branch")]) 1751 1752(define_insn "" 1753 [(set (pc) 1754 (if_then_else 1755 (eq (match_operator 0 "odd_relop" 1756 [(match_operand:CCEVEN 1 "register_operand" "r") 1757 (const_int 0)]) 1758 (const_int 0)) 1759 (match_operand 2 "pc_or_label_ref" "") 1760 (match_operand 3 "pc_or_label_ref" "")))] 1761 "" 1762 "bb%L2 %!%C0,%1,%P2%P3" 1763 [(set_attr "type" "branch")]) 1764 1765(define_insn "locate1" 1766 [(set (match_operand:SI 0 "register_operand" "=r") 1767 (high:SI (unspec:SI [(label_ref (match_operand 1 "" ""))] UNSPEC_ABDIFF)))] 1768 "flag_pic" 1769 "or.u %0,%#r0,%#hi16(%1#abdiff)") 1770 1771(define_insn "locate2" 1772 [(parallel [(set (reg:SI 1) (pc)) 1773 (set (match_operand:SI 0 "register_operand" "=r") 1774 (lo_sum:SI (match_dup 0) 1775 (unspec:SI 1776 [(label_ref (match_operand 1 "" ""))] UNSPEC_ABDIFF)))])] 1777 "flag_pic" 1778 "bsr.n %1\;or %0,%0,%#lo16(%1#abdiff)\\n%1:" 1779 [(set_attr "length" "2")]) 1780 1781;; SImode move instructions 1782 1783(define_expand "movsi" 1784 [(set (match_operand:SI 0 "general_operand" "") 1785 (match_operand:SI 1 "general_operand" ""))] 1786 "" 1787 " 1788{ 1789 if (emit_move_sequence (operands, SImode, NULL_RTX)) 1790 DONE; 1791}") 1792 1793(define_expand "reload_insi" 1794 [(set (match_operand:SI 0 "register_operand" "=r") 1795 (match_operand:SI 1 "general_operand" "")) 1796 (clobber (match_operand:SI 2 "register_operand" "=&r"))] 1797 "" 1798 " 1799{ 1800 if (emit_move_sequence (operands, SImode, operands[2])) 1801 DONE; 1802 1803 /* We don't want the clobber emitted, so handle this ourselves. */ 1804 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); 1805 DONE; 1806}") 1807 1808(define_insn "" 1809 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m,r,r,r,x,x,x,m") 1810 (match_operand:SI 1 "move_operand" "rI,m,rO,J,M,x,r,x,m,x"))] 1811 "(register_operand (operands[0], SImode) 1812 || register_operand (operands[1], SImode) 1813 || operands[1] == const0_rtx)" 1814 "@ 1815 or %0,%#r0,%1 1816 %V1ld\\t %0,%1 1817 %v0st\\t %r1,%0 1818 subu %0,%#r0,%n1 1819 set %0,%#r0,%s1 1820 mov.s %0,%1 1821 mov.s %0,%1 1822 mov %0,%1 1823 %V1ld\\t %0,%1 1824 %v0st\\t %1,%0" 1825 [(set_attr "type" "arith,load,store,arith,bit,mov,mov,mov,load,store")]) 1826 1827(define_insn "" 1828 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r") 1829 (match_operand:SI 1 "arith32_operand" "rI,J,L,M,n"))] 1830 "" 1831 "@ 1832 or %0,%#r0,%1 1833 subu %0,%#r0,%n1 1834 or.u %0,%#r0,%X1 1835 set %0,%#r0,%s1 1836 or.u %0,%#r0,%X1\;or %0,%0,%x1" 1837 [(set_attr "type" "arith,arith,arith,bit,marith")]) 1838 1839;; @@ Why the constraint "in"? Doesn't `i' include `n'? 1840(define_insn "" 1841 [(set (match_operand:SI 0 "register_operand" "=r") 1842 (lo_sum:SI (match_operand:SI 1 "register_operand" "r") 1843 (match_operand:SI 2 "immediate_operand" "in")))] 1844 "" 1845 "or %0,%1,%#lo16(%g2)") 1846 1847(define_insn "" 1848 [(set (match_operand:SI 0 "register_operand" "=r") 1849 (high:SI (match_operand 1 "" "")))] 1850 "" 1851 "or.u %0,%#r0,%#hi16(%g1)") 1852 1853;; For PIC, symbol_refs are put inside unspec so that the optimizer won't 1854;; confuse them with real addresses. 1855 1856(define_insn "movsi_lo_sum_pic" 1857 [(set (match_operand:SI 0 "register_operand" "=r") 1858 (lo_sum:SI (match_operand:SI 1 "register_operand" "r") 1859 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_GOT_REL)))] 1860 "flag_pic" 1861 "or %0,%1,%#lo16(%g2)" 1862 ;; Need to set length for this arith insn because operand2 1863 ;; is not an "arith_operand". 1864 [(set_attr "length" "1")]) 1865 1866(define_insn "movsi_high_pic" 1867 [(set (match_operand:SI 0 "register_operand" "=r") 1868 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_GOT_REL)))] 1869 "flag_pic" 1870 "or.u %0,%#r0,%#hi16(%g1)" 1871 ;; Need to set length for this arith insn because operand2 1872 ;; is not an arith_operand. 1873 [(set_attr "length" "1")]) 1874 1875;; HImode move instructions 1876 1877(define_expand "movhi" 1878 [(set (match_operand:HI 0 "general_operand" "") 1879 (match_operand:HI 1 "general_operand" ""))] 1880 "" 1881 " 1882{ 1883 if (emit_move_sequence (operands, HImode, NULL_RTX)) 1884 DONE; 1885}") 1886 1887(define_insn "" 1888 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r") 1889 (match_operand:HI 1 "move_operand" "rP,m,rO,N"))] 1890 "(register_operand (operands[0], HImode) 1891 || register_operand (operands[1], HImode) 1892 || operands[1] == const0_rtx)" 1893 "@ 1894 or %0,%#r0,%h1 1895 %V1ld.hu\\t %0,%1 1896 %v0st.h\\t %r1,%0 1897 subu %0,%#r0,%H1" 1898 [(set_attr "type" "arith,load,store,arith")]) 1899 1900(define_insn "" 1901 [(set (match_operand:HI 0 "register_operand" "=r") 1902 (subreg:HI (lo_sum:SI (match_operand:SI 1 "register_operand" "r") 1903 (match_operand:SI 2 "immediate_operand" "in")) 0))] 1904 "!flag_pic" 1905 "or %0,%1,%#lo16(%2)") 1906 1907;; QImode move instructions 1908 1909(define_expand "movqi" 1910 [(set (match_operand:QI 0 "general_operand" "") 1911 (match_operand:QI 1 "general_operand" ""))] 1912 "" 1913 " 1914{ 1915 if (emit_move_sequence (operands, QImode, NULL_RTX)) 1916 DONE; 1917}") 1918 1919(define_insn "" 1920 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r") 1921 (match_operand:QI 1 "move_operand" "rP,m,rO,N"))] 1922 "(register_operand (operands[0], QImode) 1923 || register_operand (operands[1], QImode) 1924 || operands[1] == const0_rtx)" 1925 "@ 1926 or %0,%#r0,%q1 1927 %V1ld.bu\\t %0,%1 1928 %v0st.b\\t %r1,%0 1929 subu %0,%#r0,%Q1" 1930 [(set_attr "type" "arith,load,store,arith")]) 1931 1932(define_insn "" 1933 [(set (match_operand:QI 0 "register_operand" "=r") 1934 (subreg:QI (lo_sum:SI (match_operand:SI 1 "register_operand" "r") 1935 (match_operand:SI 2 "immediate_operand" "in")) 0))] 1936 "!flag_pic" 1937 "or %0,%1,%#lo16(%2)") 1938 1939;; DImode move instructions 1940 1941(define_expand "movdi" 1942 [(set (match_operand:DI 0 "general_operand" "") 1943 (match_operand:DI 1 "general_operand" ""))] 1944 "" 1945 " 1946{ 1947 if (emit_move_sequence (operands, DImode, NULL_RTX)) 1948 DONE; 1949}") 1950 1951(define_insn "" 1952 [(set (match_operand:DI 0 "register_operand" "=r,x") 1953 (const_int 0))] 1954 "" 1955 "@ 1956 or %0,%#r0,0\;or %d0,%#r0,0 1957 mov %0,%#x0" 1958 [(set_attr "type" "marith,mov")]) 1959 1960(define_insn "" 1961 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,x,x,x,m") 1962 (match_operand:DI 1 "nonimmediate_operand" "r,m,r,x,r,x,m,x"))] 1963 "" 1964 "@ 1965 or %0,%#r0,%1\;or %d0,%#r0,%d1 1966 %V1ld.d\\t %0,%1 1967 %v0st.d\\t %1,%0 1968 mov.d %0,%1 1969 mov.d %0,%1 1970 mov %0,%1 1971 %V1ld.d\\t %0,%1 1972 %v0st.d\\t %1,%0" 1973 [(set_attr "type" "marith,loadd,store,mov,mov,mov,loadd,store")]) 1974 1975(define_insn "" 1976 [(set (match_operand:DI 0 "register_operand" "=r") 1977 (subreg:DI (lo_sum:SI (match_operand:SI 1 "register_operand" "r") 1978 (match_operand:SI 2 "immediate_operand" "in")) 0))] 1979 "!flag_pic" 1980 "or %0,%1,%#lo16(%2)") 1981 1982(define_insn "" 1983 [(set (match_operand:DI 0 "register_operand" "=r") 1984 (match_operand:DI 1 "immediate_operand" "n"))] 1985 "" 1986 "* return output_load_const_dimode (operands);" 1987 [(set_attr "type" "marith") 1988 (set_attr "length" "4")]) ; length is 2, 3 or 4. 1989 1990;; DFmode move instructions 1991 1992(define_expand "movdf" 1993 [(set (match_operand:DF 0 "general_operand" "") 1994 (match_operand:DF 1 "general_operand" ""))] 1995 "" 1996 " 1997{ 1998 if (emit_move_sequence (operands, DFmode, NULL_RTX)) 1999 DONE; 2000}") 2001 2002(define_split 2003 [(set (match_operand:DF 0 "register_operand" "") 2004 (match_operand:DF 1 "register_operand" ""))] 2005 "reload_completed 2006 && GET_CODE (operands[0]) == REG && !XRF_REGNO_P (REGNO (operands[0])) 2007 && GET_CODE (operands[1]) == REG && !XRF_REGNO_P (REGNO (operands[1]))" 2008 [(set (match_dup 2) (match_dup 3)) 2009 (set (match_dup 4) (match_dup 5))] 2010 " 2011{ operands[2] = operand_subword (operands[0], 0, 0, DFmode); 2012 operands[3] = operand_subword (operands[1], 0, 0, DFmode); 2013 operands[4] = operand_subword (operands[0], 1, 0, DFmode); 2014 operands[5] = operand_subword (operands[1], 1, 0, DFmode); }") 2015 2016(define_insn "" 2017 [(set (match_operand:DF 0 "register_operand" "=r,x") 2018 (const_int 0))] 2019 "" 2020 "@ 2021 or %0,%#r0,0\;or %d0,%#r0,0 2022 mov %0,%#x0" 2023 [(set_attr "type" "marith,mov")]) 2024 2025(define_insn "" 2026 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,x,r,x,x,m") 2027 (match_operand:DF 1 "nonimmediate_operand" "r,m,r,r,x,x,m,x"))] 2028 "" 2029 "@ 2030 or %0,%#r0,%1\;or %d0,%#r0,%d1 2031 %V1ld.d\\t %0,%1 2032 %v0st.d\\t %1,%0 2033 mov.d %0,%1 2034 mov.d %0,%1 2035 mov %0,%1 2036 %V1ld.d\\t %0,%1 2037 %v0st.d\\t %1,%0" 2038 [(set_attr "type" "marith,loadd,store,mov,mov,mov,loadd,store")]) 2039 2040(define_insn "" 2041 [(set (match_operand:DF 0 "register_operand" "=r") 2042 (subreg:DF (lo_sum:SI (match_operand:SI 1 "register_operand" "r") 2043 (match_operand:SI 2 "immediate_operand" "in")) 0))] 2044 "!flag_pic" 2045 "or %0,%1,%#lo16(%2)") 2046 2047(define_insn "" 2048 [(set (match_operand:DF 0 "register_operand" "=r") 2049 (match_operand:DF 1 "immediate_operand" "F"))] 2050 "" 2051 "* return output_load_const_double (operands);" 2052 [(set_attr "type" "marith") 2053 (set_attr "length" "4")]) ; length is 2, 3, or 4. 2054 2055;; SFmode move instructions 2056 2057(define_expand "movsf" 2058 [(set (match_operand:SF 0 "general_operand" "") 2059 (match_operand:SF 1 "general_operand" ""))] 2060 "" 2061 " 2062{ 2063 if (emit_move_sequence (operands, SFmode, NULL_RTX)) 2064 DONE; 2065}") 2066 2067(define_insn "" 2068 [(set (match_operand:SF 0 "register_operand" "=r,x") 2069 (const_int 0))] 2070 "" 2071 "@ 2072 or %0,%#r0,0 2073 mov %0,%#x0" 2074 [(set_attr "type" "arith,mov")]) 2075 2076(define_insn "" 2077 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,x,r,x,x,m") 2078 (match_operand:SF 1 "nonimmediate_operand" "r,m,r,r,x,x,m,x"))] 2079 "" 2080 "@ 2081 or %0,%#r0,%1 2082 %V1ld\\t %0,%1 2083 %v0st\\t %r1,%0 2084 mov.s %0,%1 2085 mov.s %0,%1 2086 mov %0,%1 2087 %V1ld\\t %0,%1 2088 %v0st\\t %r1,%0" 2089 [(set_attr "type" "arith,load,store,mov,mov,mov,load,store")]) 2090 2091(define_insn "" 2092 [(set (match_operand:SF 0 "register_operand" "=r") 2093 (subreg:SF (lo_sum:SI (match_operand:SI 1 "register_operand" "r") 2094 (match_operand:SI 2 "immediate_operand" "in")) 0))] 2095 "!flag_pic" 2096 "or %0,%1,%#lo16(%2)") 2097 2098(define_insn "" 2099 [(set (match_operand:SF 0 "register_operand" "=r") 2100 (match_operand:SF 1 "immediate_operand" "F"))] 2101 "operands[1] != const0_rtx" 2102 "* return output_load_const_float (operands);" 2103 [(set_attr "type" "marith")]) ; length is 1 or 2. 2104 2105;; CCmode move instructions 2106 2107;; These are a subset of the SImode move instructions. They are necessary 2108;; because the reload pass may elect to store reg:CC registers in memory, 2109;; and read them back. 2110 2111(define_expand "movcc" 2112 [(set (match_operand:CC 0 "general_operand" "") 2113 (match_operand:CC 1 "general_operand" ""))] 2114 "" 2115 " 2116{ 2117 if (emit_move_sequence (operands, CCmode, NULL_RTX)) 2118 DONE; 2119}") 2120 2121(define_insn "" 2122 [(set (match_operand:CC 0 "nonimmediate_operand" "=r,r,m") 2123 (match_operand:CC 1 "move_operand" "rI,m,rO"))] 2124 "(register_operand (operands[0], CCmode) 2125 || register_operand (operands[1], CCmode) 2126 || operands[1] == const0_rtx)" 2127 "@ 2128 or %0,%#r0,%1 2129 %V1ld\\t %0,%1 2130 %v0st\\t %r1,%0" 2131 [(set_attr "type" "arith,load,store")]) 2132 2133 2134;; String/block move insn. See m88k.c for details. 2135 2136(define_expand "movstrsi" 2137 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" "")) 2138 (mem:BLK (match_operand:BLK 1 "" ""))) 2139 (use (match_operand:SI 2 "arith32_operand" "")) 2140 (use (match_operand:SI 3 "immediate_operand" ""))])] 2141 "" 2142 " 2143{ 2144 rtx dest_mem = operands[0]; 2145 rtx src_mem = operands[1]; 2146 operands[0] = copy_to_mode_reg (SImode, XEXP (operands[0], 0)); 2147 operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0)); 2148 expand_block_move (dest_mem, src_mem, operands); 2149 DONE; 2150}") 2151 2152;; Call a non-looping block move library function (e.g. __movstrSI96x64). 2153;; operand 0 is the function name 2154;; operand 1 is the destination pointer 2155;; operand 2 is the source pointer 2156;; operand 3 is the offset for the source and destination pointers 2157;; operand 4 is the first value to be loaded 2158;; operand 5 is the register to hold the value (r4 or r5, or r4 or r6 if DImode) 2159 2160(define_expand "call_block_move" 2161 [(set (reg:SI 3) (minus:SI (match_operand:SI 2 "register_operand" "") 2162 (match_operand:SI 3 "immediate_operand" ""))) 2163 (set (match_operand 5 "register_operand" "") 2164 (match_operand 4 "memory_operand" "")) 2165 (set (reg:SI 2) (minus:SI (match_operand:SI 1 "register_operand" "") 2166 (match_dup 3))) 2167 (use (reg:SI 2)) 2168 (use (reg:SI 3)) 2169 (use (reg:SI 4)) 2170 (use (reg:SI 5)) 2171 (parallel [(set (reg:DI 2) 2172 (call (mem:SI (match_operand 0 "" "")) 2173 (const_int 0))) 2174 (clobber (reg:SI 1))])] 2175 "" 2176 "") 2177 2178(define_expand "call_block_move_DI" 2179 [(set (reg:SI 3) (minus:SI (match_operand:SI 2 "register_operand" "") 2180 (match_operand:SI 3 "immediate_operand" ""))) 2181 (set (match_operand 5 "register_operand" "") 2182 (match_operand 4 "memory_operand" "")) 2183 (set (reg:SI 2) (minus:SI (match_operand:SI 1 "register_operand" "") 2184 (match_dup 3))) 2185 (use (reg:SI 2)) 2186 (use (reg:SI 3)) 2187 (use (reg:DI 4)) 2188 (use (reg:DI 6)) 2189 (parallel [(set (reg:DI 2) 2190 (call (mem:SI (match_operand 0 "" "")) 2191 (const_int 0))) 2192 (clobber (reg:SI 1))])] 2193 "" 2194 "") 2195 2196;; Call an SImode looping block move library function (e.g. __movstrSI64n68). 2197;; operands 0-5 as in the non-looping interface 2198;; operand 6 is the loop count 2199 2200(define_expand "call_movstrsi_loop" 2201 [(set (reg:SI 3) (minus:SI (match_operand:SI 2 "register_operand" "") 2202 (match_operand:SI 3 "immediate_operand" ""))) 2203 (set (match_operand:SI 5 "register_operand" "") 2204 (match_operand 4 "memory_operand" "")) 2205 (set (reg:SI 2) (minus:SI (match_operand:SI 1 "register_operand" "") 2206 (match_dup 3))) 2207 (set (reg:SI 6) (match_operand:SI 6 "immediate_operand" "")) 2208 (use (reg:SI 2)) 2209 (use (reg:SI 3)) 2210 (use (match_dup 5)) 2211 (use (reg:SI 6)) 2212 (parallel [(set (reg:DI 2) 2213 (call (mem:SI (match_operand 0 "" "")) 2214 (const_int 0))) 2215 (clobber (reg:SI 1))])] 2216 "" 2217 "") 2218 2219;;- zero extension instructions 2220 2221(define_expand "zero_extendhisi2" 2222 [(set (match_operand:SI 0 "register_operand" "") 2223 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] 2224 "" 2225 " 2226{ 2227 if (GET_CODE (operands[1]) == MEM 2228 && symbolic_operand (XEXP (operands[1], 0), SImode)) 2229 operands[1] 2230 = legitimize_address (flag_pic, operands[1], 0, 0); 2231}") 2232 2233(define_insn "" 2234 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 2235 (zero_extend:SI (match_operand:HI 1 "move_operand" "!r,n,m")))] 2236 "GET_CODE (operands[1]) != CONST_INT" 2237 "@ 2238 mask %0,%1,0xffff 2239 or %0,%#r0,%h1 2240 %V1ld.hu\\t %0,%1" 2241 [(set_attr "type" "arith,arith,load")]) 2242 2243(define_expand "zero_extendqihi2" 2244 [(set (match_operand:HI 0 "register_operand" "") 2245 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))] 2246 "" 2247 " 2248{ 2249 if (GET_CODE (operands[1]) == MEM 2250 && symbolic_operand (XEXP (operands[1], 0), HImode)) 2251 operands[1] 2252 = legitimize_address (flag_pic, operands[1], 0, 0); 2253}") 2254 2255(define_insn "" 2256 [(set (match_operand:HI 0 "register_operand" "=r,r,r") 2257 (zero_extend:HI (match_operand:QI 1 "move_operand" "r,n,m")))] 2258 "GET_CODE (operands[1]) != CONST_INT" 2259 "@ 2260 mask %0,%1,0xff 2261 or %0,%#r0,%q1 2262 %V1ld.bu\\t %0,%1" 2263 [(set_attr "type" "arith,arith,load")]) 2264 2265(define_expand "zero_extendqisi2" 2266 [(set (match_operand:SI 0 "register_operand" "") 2267 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))] 2268 "" 2269 " 2270{ 2271 if (GET_CODE (operands[1]) == MEM 2272 && symbolic_operand (XEXP (operands[1], 0), SImode)) 2273 { 2274 operands[1] 2275 = legitimize_address (flag_pic, operands[1], 0, 0); 2276 emit_insn (gen_rtx_SET (VOIDmode, operands[0], 2277 gen_rtx_ZERO_EXTEND (SImode, operands[1]))); 2278 DONE; 2279 } 2280}") 2281 2282(define_insn "" 2283 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 2284 (zero_extend:SI (match_operand:QI 1 "move_operand" "r,n,m")))] 2285 "GET_CODE (operands[1]) != CONST_INT" 2286 "@ 2287 mask %0,%1,0xff 2288 or %0,%#r0,%q1 2289 %V1ld.bu\\t %0,%1" 2290 [(set_attr "type" "arith,arith,load")]) 2291 2292;;- sign extension instructions 2293 2294(define_insn "extendsidi2" 2295 [(set (match_operand:DI 0 "register_operand" "=r") 2296 (sign_extend:DI (match_operand:SI 1 "register_operand" "r")))] 2297 "" 2298 "#") 2299 2300(define_split 2301 [(set (match_operand:DI 0 "register_operand" "") 2302 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))] 2303 "reload_completed 2304 && GET_CODE (operands[0]) == REG 2305 && GET_CODE (operands[1]) == REG" 2306 [(set (subreg:SI (match_dup 0) 4) (match_dup 1)) 2307 (set (subreg:SI (match_dup 0) 0) 2308 (ashiftrt:SI (match_dup 1) (const_int 31)))] 2309 "") 2310 2311(define_expand "extendhisi2" 2312 [(set (match_operand:SI 0 "register_operand" "") 2313 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] 2314 "" 2315 " 2316{ 2317 if (GET_CODE (operands[1]) == MEM 2318 && symbolic_operand (XEXP (operands[1], 0), SImode)) 2319 operands[1] 2320 = legitimize_address (flag_pic, operands[1], 0, 0); 2321}") 2322 2323(define_insn "" 2324 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") 2325 (sign_extend:SI (match_operand:HI 1 "move_operand" "!r,P,N,m")))] 2326 "GET_CODE (operands[1]) != CONST_INT" 2327 "@ 2328 ext %0,%1,16<0> 2329 or %0,%#r0,%h1 2330 subu %0,%#r0,%H1 2331 %V1ld.h\\t %0,%1" 2332 [(set_attr "type" "bit,arith,arith,load")]) 2333 2334(define_expand "extendqihi2" 2335 [(set (match_operand:HI 0 "register_operand" "") 2336 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))] 2337 "" 2338 " 2339{ 2340 if (GET_CODE (operands[1]) == MEM 2341 && symbolic_operand (XEXP (operands[1], 0), HImode)) 2342 operands[1] 2343 = legitimize_address (flag_pic, operands[1], 0, 0); 2344}") 2345 2346(define_insn "" 2347 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r") 2348 (sign_extend:HI (match_operand:QI 1 "move_operand" "!r,P,N,m")))] 2349 "GET_CODE (operands[1]) != CONST_INT" 2350 "@ 2351 ext %0,%1,8<0> 2352 or %0,%#r0,%q1 2353 subu %0,%#r0,%Q1 2354 %V1ld.b\\t %0,%1" 2355 [(set_attr "type" "bit,arith,arith,load")]) 2356 2357(define_expand "extendqisi2" 2358 [(set (match_operand:SI 0 "register_operand" "") 2359 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))] 2360 "" 2361 " 2362{ 2363 if (GET_CODE (operands[1]) == MEM 2364 && symbolic_operand (XEXP (operands[1], 0), SImode)) 2365 operands[1] 2366 = legitimize_address (flag_pic, operands[1], 0, 0); 2367}") 2368 2369(define_insn "" 2370 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") 2371 (sign_extend:SI (match_operand:QI 1 "move_operand" "!r,P,N,m")))] 2372 "GET_CODE (operands[1]) != CONST_INT" 2373 "@ 2374 ext %0,%1,8<0> 2375 or %0,%#r0,%q1 2376 subu %0,%#r0,%Q1 2377 %V1ld.b\\t %0,%1" 2378 [(set_attr "type" "bit,arith,arith,load")]) 2379 2380;; Conversions between float and double. 2381 2382;; The fadd instruction does not conform to IEEE 754 when used to 2383;; convert between float and double. In particular, the sign of -0 is 2384;; not preserved. Interestingly, fsub does conform. 2385 2386(define_expand "extendsfdf2" 2387 [(set (match_operand:DF 0 "register_operand" "=r") 2388 (float_extend:DF (match_operand:SF 1 "register_operand" "r")))] 2389 "" 2390 "") 2391 2392(define_insn "" 2393 [(set (match_operand:DF 0 "register_operand" "=r") 2394 (float_extend:DF (match_operand:SF 1 "register_operand" "r")))] 2395 "! TARGET_88110" 2396 "fsub.dss %0,%1,%#r0" 2397 [(set_attr "type" "spadd")]) 2398 2399(define_insn "" 2400 [(set (match_operand:DF 0 "register_operand" "=r,x") 2401 (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")))] 2402 "TARGET_88110" 2403 "fcvt.ds %0,%1" 2404 [(set_attr "type" "spadd")]) 2405 2406(define_expand "truncdfsf2" 2407 [(set (match_operand:SF 0 "register_operand" "=r") 2408 (float_truncate:SF (match_operand:DF 1 "register_operand" "r")))] 2409 "" 2410 "") 2411 2412(define_insn "" 2413 [(set (match_operand:SF 0 "register_operand" "=r") 2414 (float_truncate:SF (match_operand:DF 1 "register_operand" "r")))] 2415 "! TARGET_88110" 2416 "fsub.sds %0,%1,%#r0" 2417 [(set_attr "type" "dpadd")]) 2418 2419(define_insn "" 2420 [(set (match_operand:SF 0 "register_operand" "=r,x") 2421 (float_truncate:SF (match_operand:DF 1 "register_operand" "r,x")))] 2422 "TARGET_88110" 2423 "fcvt.sd %0,%1" 2424 [(set_attr "type" "dpadd")]) 2425 2426;; Conversions between floating point and integer 2427 2428(define_insn "floatsidf2" 2429 [(set (match_operand:DF 0 "register_operand" "=r,x") 2430 (float:DF (match_operand:SI 1 "register_operand" "r,r")))] 2431 "" 2432 "flt.ds %0,%1" 2433 [(set_attr "type" "spadd,dpadd")]) 2434 2435(define_insn "floatsisf2" 2436 [(set (match_operand:SF 0 "register_operand" "=r,x") 2437 (float:SF (match_operand:SI 1 "register_operand" "r,r")))] 2438 "" 2439 "flt.ss %0,%1" 2440 [(set_attr "type" "spadd,spadd")]) 2441 2442(define_insn "fix_truncdfsi2" 2443 [(set (match_operand:SI 0 "register_operand" "=r,r") 2444 (fix:SI (match_operand:DF 1 "register_operand" "r,x")))] 2445 "" 2446 "trnc.sd %0,%1" 2447 [(set_attr "type" "dpadd,dpadd")]) 2448 2449(define_insn "fix_truncsfsi2" 2450 [(set (match_operand:SI 0 "register_operand" "=r,r") 2451 (fix:SI (match_operand:SF 1 "register_operand" "r,x")))] 2452 "" 2453 "trnc.ss %0,%1" 2454 [(set_attr "type" "spadd,dpadd")]) 2455 2456 2457;;- arithmetic instructions 2458;;- add instructions 2459 2460(define_insn "addsi3" 2461 [(set (match_operand:SI 0 "register_operand" "=r,r") 2462 (plus:SI (match_operand:SI 1 "arith32_operand" "%r,r") 2463 (match_operand:SI 2 "arith32_operand" "rI,J")))] 2464 "" 2465 "@ 2466 addu %0,%1,%2 2467 subu %0,%1,%n2") 2468 2469;; patterns for mixed mode floating point. 2470;; Do not define patterns that utilize mixed mode arithmetic that result 2471;; in narrowing the precision, because it loses accuracy, since the standard 2472;; requires double rounding, whereas the 88000 instruction only rounds once. 2473 2474(define_expand "adddf3" 2475 [(set (match_operand:DF 0 "register_operand" "=r,x") 2476 (plus:DF (match_operand:DF 1 "general_operand" "%r,x") 2477 (match_operand:DF 2 "general_operand" "r,x")))] 2478 "" 2479 " 2480{ 2481 operands[1] = legitimize_operand (operands[1], DFmode); 2482 operands[2] = legitimize_operand (operands[2], DFmode); 2483}") 2484 2485(define_insn "" 2486 [(set (match_operand:DF 0 "register_operand" "=r,x") 2487 (plus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")) 2488 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))] 2489 "" 2490 "fadd.dss %0,%1,%2" 2491 [(set_attr "type" "spadd")]) 2492 2493(define_insn "" 2494 [(set (match_operand:DF 0 "register_operand" "=r,x") 2495 (plus:DF (match_operand:DF 1 "register_operand" "r,x") 2496 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))] 2497 "" 2498 "fadd.dds %0,%1,%2" 2499 [(set_attr "type" "dpadd")]) 2500 2501(define_insn "" 2502 [(set (match_operand:DF 0 "register_operand" "=r,x") 2503 (plus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")) 2504 (match_operand:DF 2 "register_operand" "r,x")))] 2505 "" 2506 "fadd.dsd %0,%1,%2" 2507 [(set_attr "type" "dpadd")]) 2508 2509(define_insn "" 2510 [(set (match_operand:DF 0 "register_operand" "=r,x") 2511 (plus:DF (match_operand:DF 1 "register_operand" "%r,x") 2512 (match_operand:DF 2 "register_operand" "r,x")))] 2513 "" 2514 "fadd.ddd %0,%1,%2" 2515 [(set_attr "type" "dpadd")]) 2516 2517(define_insn "addsf3" 2518 [(set (match_operand:SF 0 "register_operand" "=r,x") 2519 (plus:SF (match_operand:SF 1 "register_operand" "%r,x") 2520 (match_operand:SF 2 "register_operand" "r,x")))] 2521 "" 2522 "fadd.sss %0,%1,%2" 2523 [(set_attr "type" "spadd")]) 2524 2525(define_insn "" 2526 [(set (match_operand:DI 0 "register_operand" "=r") 2527 (plus:DI (match_operand:DI 1 "register_operand" "r") 2528 (zero_extend:DI 2529 (match_operand:SI 2 "register_operand" "r")))) 2530 (clobber (reg:CC 0))] 2531 "" 2532 "addu.co %d0,%d1,%2\;addu.ci %0,%1,%#r0" 2533 [(set_attr "type" "marith")]) 2534 2535(define_insn "" 2536 [(set (match_operand:DI 0 "register_operand" "=r") 2537 (plus:DI (zero_extend:DI 2538 (match_operand:SI 1 "register_operand" "r")) 2539 (match_operand:DI 2 "register_operand" "r"))) 2540 (clobber (reg:CC 0))] 2541 "" 2542 "addu.co %d0,%1,%d2\;addu.ci %0,%#r0,%2" 2543 [(set_attr "type" "marith")]) 2544 2545(define_insn "adddi3" 2546 [(set (match_operand:DI 0 "register_operand" "=r") 2547 (plus:DI (match_operand:DI 1 "register_operand" "%r") 2548 (match_operand:DI 2 "register_operand" "r"))) 2549 (clobber (reg:CC 0))] 2550 "" 2551 "addu.co %d0,%d1,%d2\;addu.ci %0,%1,%2" 2552 [(set_attr "type" "marith")]) 2553 2554;; Add with carry insns. 2555 2556(define_insn "" 2557 [(parallel [(set (match_operand:SI 0 "register_operand" "=r") 2558 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "rO") 2559 (match_operand:SI 2 "reg_or_0_operand" "rO"))) 2560 (set (reg:CC 0) 2561 (unspec:CC [(match_dup 1) (match_dup 2)] 0))])] 2562 "" 2563 "addu.co %0,%r1,%r2") 2564 2565(define_insn "" 2566 [(set (reg:CC 0) (unspec:CC [(match_operand:SI 0 "reg_or_0_operand" "rO") 2567 (match_operand:SI 1 "reg_or_0_operand" "rO")] 2568 0))] 2569 "" 2570 "addu.co %#r0,%r0,%r1") 2571 2572(define_insn "" 2573 [(set (match_operand:SI 0 "register_operand" "=r") 2574 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "rO") 2575 (unspec:SI [(match_operand:SI 2 "reg_or_0_operand" "rO") 2576 (reg:CC 0)] 0)))] 2577 "" 2578 "addu.ci %0,%r1,%r2") 2579 2580;;- subtract instructions 2581 2582(define_insn "subsi3" 2583 [(set (match_operand:SI 0 "register_operand" "=r") 2584 (minus:SI (match_operand:SI 1 "register_operand" "r") 2585 (match_operand:SI 2 "arith32_operand" "rI")))] 2586 "" 2587 "subu %0,%1,%2") 2588 2589;; patterns for mixed mode floating point 2590;; Do not define patterns that utilize mixed mode arithmetic that result 2591;; in narrowing the precision, because it loses accuracy, since the standard 2592;; requires double rounding, whereas the 88000 instruction only rounds once. 2593 2594(define_expand "subdf3" 2595 [(set (match_operand:DF 0 "register_operand" "=r,x") 2596 (minus:DF (match_operand:DF 1 "general_operand" "r,x") 2597 (match_operand:DF 2 "general_operand" "r,x")))] 2598 "" 2599 " 2600{ 2601 operands[1] = legitimize_operand (operands[1], DFmode); 2602 operands[2] = legitimize_operand (operands[2], DFmode); 2603}") 2604 2605(define_insn "" 2606 [(set (match_operand:DF 0 "register_operand" "=r,x") 2607 (minus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")) 2608 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))] 2609 "" 2610 "fsub.dss %0,%1,%2" 2611 [(set_attr "type" "spadd")]) 2612 2613(define_insn "" 2614 [(set (match_operand:DF 0 "register_operand" "=r,x") 2615 (minus:DF (match_operand:DF 1 "register_operand" "r,x") 2616 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))] 2617 "" 2618 "fsub.dds %0,%1,%2" 2619 [(set_attr "type" "dpadd")]) 2620 2621(define_insn "" 2622 [(set (match_operand:DF 0 "register_operand" "=r,x") 2623 (minus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")) 2624 (match_operand:DF 2 "register_operand" "r,x")))] 2625 "" 2626 "fsub.dsd %0,%1,%2" 2627 [(set_attr "type" "dpadd")]) 2628 2629(define_insn "" 2630 [(set (match_operand:DF 0 "register_operand" "=r,x") 2631 (minus:DF (match_operand:DF 1 "register_operand" "r,x") 2632 (match_operand:DF 2 "register_operand" "r,x")))] 2633 "" 2634 "fsub.ddd %0,%1,%2" 2635 [(set_attr "type" "dpadd")]) 2636 2637(define_insn "subsf3" 2638 [(set (match_operand:SF 0 "register_operand" "=r,x") 2639 (minus:SF (match_operand:SF 1 "register_operand" "r,x") 2640 (match_operand:SF 2 "register_operand" "r,x")))] 2641 "" 2642 "fsub.sss %0,%1,%2" 2643 [(set_attr "type" "spadd")]) 2644 2645(define_insn "" 2646 [(set (match_operand:DI 0 "register_operand" "=r") 2647 (minus:DI (match_operand:DI 1 "register_operand" "r") 2648 (zero_extend:DI 2649 (match_operand:SI 2 "register_operand" "r")))) 2650 (clobber (reg:CC 0))] 2651 "" 2652 "subu.co %d0,%d1,%2\;subu.ci %0,%1,%#r0" 2653 [(set_attr "type" "marith")]) 2654 2655(define_insn "" 2656 [(set (match_operand:DI 0 "register_operand" "=r") 2657 (minus:DI (zero_extend:DI 2658 (match_operand:SI 1 "register_operand" "r")) 2659 (match_operand:DI 2 "register_operand" "r"))) 2660 (clobber (reg:CC 0))] 2661 "" 2662 "subu.co %d0,%1,%d2\;subu.ci %0,%#r0,%2" 2663 [(set_attr "type" "marith")]) 2664 2665(define_insn "subdi3" 2666 [(set (match_operand:DI 0 "register_operand" "=r") 2667 (minus:DI (match_operand:DI 1 "register_operand" "r") 2668 (match_operand:DI 2 "register_operand" "r"))) 2669 (clobber (reg:CC 0))] 2670 "" 2671 "subu.co %d0,%d1,%d2\;subu.ci %0,%1,%2" 2672 [(set_attr "type" "marith")]) 2673 2674;; Subtract with carry insns. 2675 2676(define_insn "" 2677 [(parallel [(set (match_operand:SI 0 "register_operand" "=r") 2678 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO") 2679 (match_operand:SI 2 "reg_or_0_operand" "rO"))) 2680 (set (reg:CC 0) 2681 (unspec:CC [(match_dup 1) (match_dup 2)] 1))])] 2682 "" 2683 "subu.co %0,%r1,%r2") 2684 2685(define_insn "" 2686 [(set (reg:CC 0) (unspec:CC [(match_operand:SI 0 "reg_or_0_operand" "rO") 2687 (match_operand:SI 1 "reg_or_0_operand" "rO")] 2688 1))] 2689 "" 2690 "subu.co %#r0,%r0,%r1") 2691 2692(define_insn "" 2693 [(set (match_operand:SI 0 "register_operand" "=r") 2694 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO") 2695 (unspec:SI [(match_operand:SI 2 "reg_or_0_operand" "rO") 2696 (reg:CC 0)] 1)))] 2697 "" 2698 "subu.ci %0,%r1,%r2") 2699 2700;;- multiply instructions 2701;; 2702;; There is an unfounded silicon errata for E.1 requiring that an 2703;; immediate constant value in div/divu/mul instructions be less than 2704;; 0x800. This is no longer provided for. 2705 2706(define_insn "mulsi3" 2707 [(set (match_operand:SI 0 "register_operand" "=r") 2708 (mult:SI (match_operand:SI 1 "arith32_operand" "%r") 2709 (match_operand:SI 2 "arith32_operand" "rI")))] 2710 "" 2711 "mul %0,%1,%2" 2712 [(set_attr "type" "imul")]) 2713 2714(define_insn "umulsidi3" 2715 [(set (match_operand:DI 0 "register_operand" "=r") 2716 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%r")) 2717 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))] 2718 "TARGET_88110" 2719 "mulu.d %0,%1,%2" 2720 [(set_attr "type" "imul")]) 2721 2722;; patterns for mixed mode floating point 2723;; Do not define patterns that utilize mixed mode arithmetic that result 2724;; in narrowing the precision, because it loses accuracy, since the standard 2725;; requires double rounding, whereas the 88000 instruction only rounds once. 2726 2727(define_expand "muldf3" 2728 [(set (match_operand:DF 0 "register_operand" "=r,x") 2729 (mult:DF (match_operand:DF 1 "general_operand" "%r,x") 2730 (match_operand:DF 2 "general_operand" "r,x")))] 2731 "" 2732 " 2733{ 2734 operands[1] = legitimize_operand (operands[1], DFmode); 2735 operands[2] = legitimize_operand (operands[2], DFmode); 2736}") 2737 2738(define_insn "" 2739 [(set (match_operand:DF 0 "register_operand" "=r,x") 2740 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")) 2741 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))] 2742 "" 2743 "fmul.dss %0,%1,%2" 2744 [(set_attr "type" "spmul")]) 2745 2746(define_insn "" 2747 [(set (match_operand:DF 0 "register_operand" "=r,x") 2748 (mult:DF (match_operand:DF 1 "register_operand" "r,x") 2749 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))] 2750 "" 2751 "fmul.dds %0,%1,%2" 2752 [(set_attr "type" "spmul")]) 2753 2754(define_insn "" 2755 [(set (match_operand:DF 0 "register_operand" "=r,x") 2756 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")) 2757 (match_operand:DF 2 "register_operand" "r,x")))] 2758 "" 2759 "fmul.dsd %0,%1,%2" 2760 [(set_attr "type" "spmul")]) 2761 2762(define_insn "" 2763 [(set (match_operand:DF 0 "register_operand" "=r,x") 2764 (mult:DF (match_operand:DF 1 "register_operand" "%r,x") 2765 (match_operand:DF 2 "register_operand" "r,x")))] 2766 "" 2767 "fmul.ddd %0,%1,%2" 2768 [(set_attr "type" "dpmul")]) 2769 2770(define_insn "mulsf3" 2771 [(set (match_operand:SF 0 "register_operand" "=r,x") 2772 (mult:SF (match_operand:SF 1 "register_operand" "%r,x") 2773 (match_operand:SF 2 "register_operand" "r,x")))] 2774 "" 2775 "fmul.sss %0,%1,%2" 2776 [(set_attr "type" "spmul")]) 2777 2778;;- divide instructions 2779;; 2780;; The 88k div and divu instructions don't reliably trap on 2781;; divide-by-zero. A trap to vector 503 asserts divide-by-zero. The 2782;; general scheme for doing divide is to do a 4-way split based on the 2783;; sign of the two operand and do the appropriate negates. 2784;; 2785;; The conditional trap instruction is not used as this serializes the 2786;; processor. Instead a conditional branch and an unconditional trap 2787;; are used, but after the divu. Since the divu takes up to 38 cycles, 2788;; the conditional branch is essentially free. 2789;; 2790;; Two target options control how divide is done. One options selects 2791;; whether to do the branch and negate scheme instead of using the div 2792;; instruction; the other option selects whether to explicitly check 2793;; for divide-by-zero or take your chances. If the div instruction is 2794;; used, the O/S must complete the operation if the operands are 2795;; negative. The O/S will signal an overflow condition if the most 2796;; negative number (-2147483648) is divided by negative 1. 2797;; 2798;; There is an unfounded silicon errata for E.1 requiring that an 2799;; immediate constant value in div/divu/mul instructions be less than 2800;; 0x800. This is no longer provided for. 2801 2802;; Division by 0 trap 2803(define_insn "trap_divide_by_zero" 2804 [(trap_if (const_int 1) (const_int 503))] 2805 "" 2806 "tb0 0,%#r0,503" 2807 [(set_attr "type" "weird") 2808 (set_attr "length" "1")]) 2809 2810;; Conditional division by 0 trap. 2811(define_expand "tcnd_divide_by_zero" 2812 [(set (pc) 2813 (if_then_else (eq (match_operand:SI 0 "register_operand" "") 2814 (const_int 0)) 2815 (pc) 2816 (match_operand 1 "" ""))) 2817 (trap_if (const_int 1) (const_int 503))] 2818 "" 2819 " 2820{ 2821 emit_insn (gen_cmpsi (operands[0], const0_rtx)); 2822 emit_jump_insn (gen_bne (operands[1])); 2823 emit_insn (gen_trap_divide_by_zero ()); 2824 DONE; 2825}") 2826 2827(define_expand "divsi3" 2828 [(set (match_operand:SI 0 "register_operand" "") 2829 (div:SI (match_operand:SI 1 "arith32_operand" "") 2830 (match_operand:SI 2 "arith32_operand" "")))] 2831 "" 2832 " 2833{ 2834 rtx op0 = operands[0]; 2835 rtx op1 = operands[1]; 2836 rtx op2 = operands[2]; 2837 rtx join_label; 2838 2839 /* @@ This needs to be reworked. Torbjorn Granlund has suggested making 2840 it a runtime (perhaps quite special). */ 2841 2842 if (GET_CODE (op1) == CONST_INT) 2843 op1 = force_reg (SImode, op1); 2844 2845 else if (GET_CODE (op2) == CONST_INT 2846 && ! SMALL_INT (operands[2])) 2847 op2 = force_reg (SImode, op2); 2848 2849 if (op2 == const0_rtx) 2850 { 2851 emit_insn (gen_trap_divide_by_zero ()); 2852 emit_insn (gen_dummy (op0)); 2853 DONE; 2854 } 2855 2856 if (TARGET_USE_DIV) 2857 { 2858 emit_move_insn (op0, gen_rtx_DIV (SImode, op1, op2)); 2859 if (TARGET_CHECK_ZERO_DIV && GET_CODE (op2) != CONST_INT) 2860 { 2861 rtx label = gen_label_rtx (); 2862 emit_insn (gen_tcnd_divide_by_zero (op2, label)); 2863 emit_label (label); 2864 emit_insn (gen_dummy (op0)); 2865 } 2866 DONE; 2867 } 2868 2869 join_label = gen_label_rtx (); 2870 if (GET_CODE (op1) == CONST_INT) 2871 { 2872 int neg = FALSE; 2873 rtx neg_op2 = gen_reg_rtx (SImode); 2874 rtx label1 = gen_label_rtx (); 2875 2876 if (INTVAL (op1) < 0) 2877 { 2878 neg = TRUE; 2879 op1 = GEN_INT (-INTVAL (op1)); 2880 } 2881 op1 = force_reg (SImode, op1); 2882 2883 emit_insn (gen_negsi2 (neg_op2, op2)); 2884 emit_insn (gen_cmpsi (op2, const0_rtx)); 2885 emit_jump_insn (gen_bgt (label1)); 2886 /* constant / 0-or-negative */ 2887 emit_move_insn (op0, gen_rtx_UDIV (SImode, op1, neg_op2)); 2888 if (!neg) 2889 emit_insn (gen_negsi2 (op0, op0)); 2890 2891 if (TARGET_CHECK_ZERO_DIV) 2892 emit_insn (gen_tcnd_divide_by_zero (op2, join_label)); 2893 emit_jump_insn (gen_jump (join_label)); 2894 emit_barrier (); 2895 2896 emit_label (label1); /* constant / positive */ 2897 emit_move_insn (op0, gen_rtx_UDIV (SImode, op1, op2)); 2898 if (neg) 2899 emit_insn (gen_negsi2 (op0, op0)); 2900 } 2901 2902 else if (GET_CODE (op2) == CONST_INT) 2903 { 2904 int neg = FALSE; 2905 rtx neg_op1 = gen_reg_rtx (SImode); 2906 rtx label1 = gen_label_rtx (); 2907 2908 if (INTVAL (op2) < 0) 2909 { 2910 neg = TRUE; 2911 op2 = GEN_INT (-INTVAL (op2)); 2912 } 2913 else if (! SMALL_INT (operands[2])) 2914 op2 = force_reg (SImode, op2); 2915 2916 emit_insn (gen_negsi2 (neg_op1, op1)); 2917 emit_insn (gen_cmpsi (op1, const0_rtx)); 2918 emit_jump_insn (gen_bge (label1)); 2919 /* 0-or-negative / constant */ 2920 emit_move_insn (op0, gen_rtx_UDIV (SImode, neg_op1, op2)); 2921 if (!neg) 2922 emit_insn (gen_negsi2 (op0, op0)); 2923 2924 emit_jump_insn (gen_jump (join_label)); 2925 emit_barrier (); 2926 2927 emit_label (label1); /* positive / constant */ 2928 emit_move_insn (op0, gen_rtx_UDIV (SImode, op1, op2)); 2929 if (neg) 2930 emit_insn (gen_negsi2 (op0, op0)); 2931 } 2932 2933 else 2934 { 2935 rtx neg_op1 = gen_reg_rtx (SImode); 2936 rtx neg_op2 = gen_reg_rtx (SImode); 2937 rtx label1 = gen_label_rtx (); 2938 rtx label2 = gen_label_rtx (); 2939 rtx label3 = gen_label_rtx (); 2940 rtx label4 = NULL_RTX; 2941 2942 emit_insn (gen_negsi2 (neg_op2, op2)); 2943 emit_insn (gen_cmpsi (op2, const0_rtx)); 2944 emit_jump_insn (gen_bgt (label1)); 2945 2946 emit_insn (gen_negsi2 (neg_op1, op1)); 2947 emit_insn (gen_cmpsi (op1, const0_rtx)); 2948 emit_jump_insn (gen_bge (label2)); 2949 /* negative / negative-or-0 */ 2950 emit_move_insn (op0, gen_rtx_UDIV (SImode, neg_op1, neg_op2)); 2951 2952 if (TARGET_CHECK_ZERO_DIV) 2953 { 2954 label4 = gen_label_rtx (); 2955 emit_insn (gen_cmpsi (op2, const0_rtx)); 2956 emit_jump_insn (gen_bne (join_label)); 2957 emit_label (label4); 2958 emit_insn (gen_trap_divide_by_zero ()); 2959 } 2960 emit_jump_insn (gen_jump (join_label)); 2961 emit_barrier (); 2962 2963 emit_label (label2); /* pos.-or-0 / neg.-or-0 */ 2964 emit_move_insn (op0, gen_rtx_UDIV (SImode, op1, neg_op2)); 2965 2966 if (TARGET_CHECK_ZERO_DIV) 2967 { 2968 emit_insn (gen_cmpsi (op2, const0_rtx)); 2969 emit_jump_insn (gen_beq (label4)); 2970 } 2971 2972 emit_insn (gen_negsi2 (op0, op0)); 2973 emit_jump_insn (gen_jump (join_label)); 2974 emit_barrier (); 2975 2976 emit_label (label1); 2977 emit_insn (gen_negsi2 (neg_op1, op1)); 2978 emit_insn (gen_cmpsi (op1, const0_rtx)); 2979 emit_jump_insn (gen_bge (label3)); 2980 /* negative / positive */ 2981 emit_move_insn (op0, gen_rtx_UDIV (SImode, neg_op1, op2)); 2982 emit_insn (gen_negsi2 (op0, op0)); 2983 emit_jump_insn (gen_jump (join_label)); 2984 emit_barrier (); 2985 2986 emit_label (label3); /* positive-or-0 / positive */ 2987 emit_move_insn (op0, gen_rtx_UDIV (SImode, op1, op2)); 2988 } 2989 2990 emit_label (join_label); 2991 2992 emit_insn (gen_dummy (op0)); 2993 DONE; 2994}") 2995 2996(define_insn "" 2997 [(set (match_operand:SI 0 "register_operand" "=r") 2998 (div:SI (match_operand:SI 1 "register_operand" "r") 2999 (match_operand:SI 2 "arith_operand" "rI")))] 3000 "" 3001 "div %0,%1,%2" 3002 [(set_attr "type" "idiv")]) 3003 3004(define_expand "udivsi3" 3005 [(set (match_operand:SI 0 "register_operand" "") 3006 (udiv:SI (match_operand:SI 1 "register_operand" "") 3007 (match_operand:SI 2 "arith32_operand" "")))] 3008 "" 3009 " 3010{ 3011 rtx op2 = operands[2]; 3012 3013 if (op2 == const0_rtx) 3014 { 3015 emit_insn (gen_trap_divide_by_zero ()); 3016 emit_insn (gen_dummy (operands[0])); 3017 DONE; 3018 } 3019 else if (GET_CODE (op2) != CONST_INT && TARGET_CHECK_ZERO_DIV) 3020 { 3021 rtx label = gen_label_rtx (); 3022 emit_insn (gen_rtx_SET (VOIDmode, operands[0], 3023 gen_rtx_UDIV (SImode, operands[1], op2))); 3024 emit_insn (gen_tcnd_divide_by_zero (op2, label)); 3025 emit_label (label); 3026 emit_insn (gen_dummy (operands[0])); 3027 DONE; 3028 } 3029}") 3030 3031(define_insn "" 3032 [(set (match_operand:SI 0 "register_operand" "=r") 3033 (udiv:SI (match_operand:SI 1 "register_operand" "r") 3034 (match_operand:SI 2 "arith32_operand" "rI")))] 3035 "operands[2] != const0_rtx" 3036 "divu %0,%1,%2" 3037 [(set_attr "type" "idiv")]) 3038 3039(define_insn "" 3040 [(set (match_operand:SI 0 "register_operand" "=r") 3041 (udiv:SI (match_operand:SI 1 "register_operand" "r") 3042 (const_int 0)))] 3043 "" 3044 "tb0 0,%#r0,503" 3045 [(set_attr "type" "weird") 3046 (set_attr "length" "1")]) 3047 3048;; patterns for mixed mode floating point. 3049;; Do not define patterns that utilize mixed mode arithmetic that result 3050;; in narrowing the precision, because it loses accuracy, since the standard 3051;; requires double rounding, whereas the 88000 instruction only rounds once. 3052 3053(define_expand "divdf3" 3054 [(set (match_operand:DF 0 "register_operand" "=r,x") 3055 (div:DF (match_operand:DF 1 "general_operand" "r,x") 3056 (match_operand:DF 2 "general_operand" "r,x")))] 3057 "" 3058 " 3059{ 3060 operands[1] = legitimize_operand (operands[1], DFmode); 3061 if (real_power_of_2_operand (operands[2])) 3062 { 3063 REAL_VALUE_TYPE r; 3064 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]); 3065 bool result; 3066 3067 result = exact_real_inverse (DFmode, &r); 3068 gcc_assert (result); 3069 emit_insn (gen_muldf3 (operands[0], operands[1], 3070 CONST_DOUBLE_FROM_REAL_VALUE (r, DFmode))); 3071 DONE; 3072 } 3073 else if (! register_operand (operands[2], DFmode)) 3074 operands[2] = force_reg (DFmode, operands[2]); 3075}") 3076 3077(define_insn "" 3078 [(set (match_operand:DF 0 "register_operand" "=r,x") 3079 (div:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")) 3080 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))] 3081 "" 3082 "fdiv.dss %0,%1,%2" 3083 [(set_attr "type" "dpdiv")]) 3084 3085(define_insn "" 3086 [(set (match_operand:DF 0 "register_operand" "=r,x") 3087 (div:DF (match_operand:DF 1 "register_operand" "r,x") 3088 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))] 3089 "" 3090 "fdiv.dds %0,%1,%2" 3091 [(set_attr "type" "dpdiv")]) 3092 3093(define_insn "" 3094 [(set (match_operand:DF 0 "register_operand" "=r,x") 3095 (div:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")) 3096 (match_operand:DF 2 "register_operand" "r,x")))] 3097 "" 3098 "fdiv.dsd %0,%1,%2" 3099 [(set_attr "type" "dpdiv")]) 3100 3101(define_insn "divsf3" 3102 [(set (match_operand:SF 0 "register_operand" "=r,x") 3103 (div:SF (match_operand:SF 1 "register_operand" "r,x") 3104 (match_operand:SF 2 "register_operand" "r,x")))] 3105 "" 3106 "fdiv.sss %0,%1,%2" 3107 [(set_attr "type" "spdiv")]) 3108 3109(define_insn "" 3110 [(set (match_operand:DF 0 "register_operand" "=r,x") 3111 (div:DF (match_operand:DF 1 "register_operand" "r,x") 3112 (match_operand:DF 2 "register_operand" "r,x")))] 3113 "" 3114 "fdiv.ddd %0,%1,%2" 3115 [(set_attr "type" "dpdiv")]) 3116 3117;; - remainder instructions, don't define, since the hardware doesn't have any 3118;; direct support, and GNU can synthesis them out of div/mul just fine. 3119 3120;;- load effective address, must come after add, so that we favor using 3121;; addu reg,reg,reg instead of: lda reg,reg,reg (addu doesn't require 3122;; the data unit), and also future 88k chips might not support unscaled 3123;; lda instructions. 3124 3125(define_insn "" 3126 [(set (match_operand:SI 0 "register_operand" "=r") 3127 (match_operand:HI 1 "address_operand" "p"))] 3128 "" 3129 "lda.h %0,%a1" 3130 [(set_attr "type" "loada")]) 3131 3132(define_insn "" 3133 [(set (match_operand:SI 0 "register_operand" "=r") 3134 (match_operand:SI 1 "address_operand" "p"))] 3135 "" 3136 "lda %0,%a1" 3137 [(set_attr "type" "loada")]) 3138 3139(define_insn "" 3140 [(set (match_operand:SI 0 "register_operand" "=r") 3141 (match_operand:DI 1 "address_operand" "p"))] 3142 "" 3143 "lda.d %0,%a1" 3144 [(set_attr "type" "loada")]) 3145 3146(define_insn "" 3147 [(set (match_operand:SI 0 "register_operand" "=r") 3148 (match_operand:SF 1 "address_operand" "p"))] 3149 "" 3150 "lda %0,%a1" 3151 [(set_attr "type" "loada")]) 3152 3153(define_insn "" 3154 [(set (match_operand:SI 0 "register_operand" "=r") 3155 (match_operand:DF 1 "address_operand" "p"))] 3156 "" 3157 "lda.d %0,%a1" 3158 [(set_attr "type" "loada")]) 3159 3160;;- and instructions (with complement also) 3161(define_insn "" 3162 [(set (match_operand:SI 0 "register_operand" "=r") 3163 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r")) 3164 (match_operand:SI 2 "register_operand" "r")))] 3165 "" 3166 "and.c %0,%2,%1") 3167 3168;; If the operation is being performed on a 32-bit constant such that 3169;; it cannot be done in one insn, do it in two. We may lose a bit on 3170;; CSE in pathological cases, but it seems better doing it this way. 3171 3172(define_expand "andsi3" 3173 [(set (match_operand:SI 0 "register_operand" "") 3174 (and:SI (match_operand:SI 1 "arith32_operand" "") 3175 (match_operand:SI 2 "arith32_operand" "")))] 3176 "" 3177 " 3178{ 3179 if (GET_CODE (operands[2]) == CONST_INT) 3180 { 3181 int value = INTVAL (operands[2]); 3182 3183 if (! (SMALL_INTVAL (value) 3184 || (value & 0xffff0000) == 0xffff0000 3185 || (value & 0xffff) == 0xffff 3186 || (value & 0xffff) == 0 3187 || integer_ok_for_set (~value))) 3188 { 3189 emit_insn (gen_andsi3 (operands[0], operands[1], 3190 GEN_INT (value | 0xffff))); 3191 operands[1] = operands[0]; 3192 operands[2] = GEN_INT (value | 0xffff0000); 3193 } 3194 } 3195}") 3196 3197(define_insn "" 3198 [(set (match_operand:SI 0 "register_operand" "=r,r") 3199 (and:SI (match_operand:SI 1 "arith32_operand" "%r,r") 3200 (match_operand:SI 2 "arith32_operand" "rIJL,rn")))] 3201 "" 3202 "* return output_and (operands);" 3203 [(set_attr "type" "arith,marith")]) 3204 3205(define_insn "" 3206 [(set (match_operand:DI 0 "register_operand" "=r") 3207 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r")) 3208 (match_operand:DI 2 "register_operand" "r")))] 3209 "" 3210 "and.c %d0,%d2,%d1\;and.c %0,%2,%1" 3211 [(set_attr "type" "marith")]) 3212 3213(define_insn "anddi3" 3214 [(set (match_operand:DI 0 "register_operand" "=r") 3215 (and:DI (match_operand:DI 1 "arith64_operand" "%r") 3216 (match_operand:DI 2 "arith64_operand" "rn")))] 3217 "" 3218{ 3219 rtx xoperands[10]; 3220 3221 xoperands[0] = operand_subword (operands[0], 1, 0, DImode); 3222 xoperands[1] = operand_subword (operands[1], 1, 0, DImode); 3223 xoperands[2] = operand_subword (operands[2], 1, 0, DImode); 3224 3225 output_asm_insn (output_and (xoperands), xoperands); 3226 3227 operands[0] = operand_subword (operands[0], 0, 0, DImode); 3228 operands[1] = operand_subword (operands[1], 0, 0, DImode); 3229 operands[2] = operand_subword (operands[2], 0, 0, DImode); 3230 3231 return output_and (operands); 3232} 3233 [(set_attr "type" "marith") 3234 (set_attr "length" "4")]) ; length is 2, 3, or 4. 3235 3236;;- Bit set (inclusive or) instructions (with complement also) 3237(define_insn "" 3238 [(set (match_operand:SI 0 "register_operand" "=r") 3239 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r")) 3240 (match_operand:SI 2 "register_operand" "r")))] 3241 "" 3242 "or.c %0,%2,%1") 3243 3244(define_expand "iorsi3" 3245 [(set (match_operand:SI 0 "register_operand" "") 3246 (ior:SI (match_operand:SI 1 "arith32_operand" "") 3247 (match_operand:SI 2 "arith32_operand" "")))] 3248 "" 3249 " 3250{ 3251 if (GET_CODE (operands[2]) == CONST_INT) 3252 { 3253 int value = INTVAL (operands[2]); 3254 3255 if (! (SMALL_INTVAL (value) 3256 || (value & 0xffff) == 0 3257 || integer_ok_for_set (value))) 3258 { 3259 emit_insn (gen_iorsi3 (operands[0], operands[1], 3260 GEN_INT (value & 0xffff0000))); 3261 operands[1] = operands[0]; 3262 operands[2] = GEN_INT (value & 0xffff); 3263 } 3264 } 3265}") 3266 3267(define_insn "" 3268 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") 3269 (ior:SI (match_operand:SI 1 "arith32_operand" "%r,r,r,r") 3270 (match_operand:SI 2 "arith32_operand" "rI,L,M,n")))] 3271 "" 3272 "@ 3273 or %0,%1,%2 3274 or.u %0,%1,%X2 3275 set %0,%1,%s2 3276 or.u %0,%1,%X2\;or %0,%0,%x2" 3277 [(set_attr "type" "arith,arith,bit,marith")]) 3278 3279(define_insn "" 3280 [(set (match_operand:DI 0 "register_operand" "=r") 3281 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r")) 3282 (match_operand:DI 2 "register_operand" "r")))] 3283 "" 3284 "or.c %d0,%d2,%d1\;or.c %0,%2,%1" 3285 [(set_attr "type" "marith")]) 3286 3287(define_insn "iordi3" 3288 [(set (match_operand:DI 0 "register_operand" "=r") 3289 (ior:DI (match_operand:DI 1 "arith64_operand" "%r") 3290 (match_operand:DI 2 "arith64_operand" "rn")))] 3291 "" 3292{ 3293 rtx xoperands[10]; 3294 3295 xoperands[0] = operand_subword (operands[0], 1, 0, DImode); 3296 xoperands[1] = operand_subword (operands[1], 1, 0, DImode); 3297 xoperands[2] = operand_subword (operands[2], 1, 0, DImode); 3298 3299 output_asm_insn (output_ior (xoperands), xoperands); 3300 3301 operands[0] = operand_subword (operands[0], 0, 0, DImode); 3302 operands[1] = operand_subword (operands[1], 0, 0, DImode); 3303 operands[2] = operand_subword (operands[2], 0, 0, DImode); 3304 3305 return output_ior (operands); 3306} 3307 [(set_attr "type" "marith") 3308 (set_attr "length" "4")]) ; length is 2, 3, or 4. 3309 3310;;- xor instructions (with complement also) 3311(define_insn "" 3312 [(set (match_operand:SI 0 "register_operand" "=r") 3313 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "%r") 3314 (match_operand:SI 2 "register_operand" "r"))))] 3315 "" 3316 "xor.c %0,%1,%2") 3317 3318(define_expand "xorsi3" 3319 [(set (match_operand:SI 0 "register_operand" "") 3320 (xor:SI (match_operand:SI 1 "arith32_operand" "") 3321 (match_operand:SI 2 "arith32_operand" "")))] 3322 "" 3323 " 3324{ 3325 if (GET_CODE (operands[2]) == CONST_INT) 3326 { 3327 int value = INTVAL (operands[2]); 3328 3329 if (! (SMALL_INTVAL (value) 3330 || (value & 0xffff) == 0)) 3331 { 3332 emit_insn (gen_xorsi3 (operands[0], operands[1], 3333 GEN_INT (value & 0xffff0000))); 3334 operands[1] = operands[0]; 3335 operands[2] = GEN_INT (value & 0xffff); 3336 } 3337 } 3338}") 3339 3340(define_insn "" 3341 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 3342 (xor:SI (match_operand:SI 1 "arith32_operand" "%r,r,r") 3343 (match_operand:SI 2 "arith32_operand" "rI,L,n")))] 3344 "" 3345 "@ 3346 xor %0,%1,%2 3347 xor.u %0,%1,%X2 3348 xor.u %0,%1,%X2\;xor %0,%0,%x2" 3349 [(set_attr "type" "arith,arith,marith")]) 3350 3351(define_insn "" 3352 [(set (match_operand:DI 0 "register_operand" "=r") 3353 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r") 3354 (match_operand:DI 2 "register_operand" "r"))))] 3355 "" 3356 "xor.c %d0,%d1,%d2\;xor.c %0,%1,%2" 3357 [(set_attr "type" "marith")]) 3358 3359(define_insn "xordi3" 3360 [(set (match_operand:DI 0 "register_operand" "=r") 3361 (xor:DI (match_operand:DI 1 "arith64_operand" "%r") 3362 (match_operand:DI 2 "arith64_operand" "rn")))] 3363 "" 3364{ 3365 rtx xoperands[10]; 3366 3367 xoperands[0] = operand_subword (operands[0], 1, 0, DImode); 3368 xoperands[1] = operand_subword (operands[1], 1, 0, DImode); 3369 xoperands[2] = operand_subword (operands[2], 1, 0, DImode); 3370 3371 output_asm_insn (output_xor (xoperands), xoperands); 3372 3373 operands[0] = operand_subword (operands[0], 0, 0, DImode); 3374 operands[1] = operand_subword (operands[1], 0, 0, DImode); 3375 operands[2] = operand_subword (operands[2], 0, 0, DImode); 3376 3377 return output_xor (operands); 3378} 3379 [(set_attr "type" "marith") 3380 (set_attr "length" "4")]) ; length is 2, 3, or 4. 3381 3382;;- ones complement instructions 3383(define_insn "one_cmplsi2" 3384 [(set (match_operand:SI 0 "register_operand" "=r") 3385 (not:SI (match_operand:SI 1 "register_operand" "r")))] 3386 "" 3387 "xor.c %0,%1,%#r0") 3388 3389(define_insn "one_cmpldi2" 3390 [(set (match_operand:DI 0 "register_operand" "=r") 3391 (not:DI (match_operand:DI 1 "register_operand" "r")))] 3392 "" 3393 "xor.c %d0,%d1,%#r0\;xor.c %0,%1,%#r0" 3394 [(set_attr "type" "marith")]) 3395 3396;; Optimized special cases of shifting. 3397;; Must precede the general case. 3398 3399;; @@ What about HImode shifted by 8? 3400 3401(define_insn "" 3402 [(set (match_operand:SI 0 "register_operand" "=r") 3403 (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m") 3404 (const_int 24)))] 3405 "! SCALED_ADDRESS_P (XEXP (operands[1], 0))" 3406 "%V1ld.b\\t %0,%1" 3407 [(set_attr "type" "load")]) 3408 3409(define_insn "" 3410 [(set (match_operand:SI 0 "register_operand" "=r") 3411 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m") 3412 (const_int 24)))] 3413 "! SCALED_ADDRESS_P (XEXP (operands[1], 0))" 3414 "%V1ld.bu\\t %0,%1" 3415 [(set_attr "type" "load")]) 3416 3417(define_insn "" 3418 [(set (match_operand:SI 0 "register_operand" "=r") 3419 (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m") 3420 (const_int 16)))] 3421 "! SCALED_ADDRESS_P (XEXP (operands[1], 0))" 3422 "%V1ld.h\\t %0,%1" 3423 [(set_attr "type" "load")]) 3424 3425(define_insn "" 3426 [(set (match_operand:SI 0 "register_operand" "=r") 3427 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m") 3428 (const_int 16)))] 3429 "! SCALED_ADDRESS_P (XEXP (operands[1], 0))" 3430 "%V1ld.hu\\t %0,%1" 3431 [(set_attr "type" "load")]) 3432 3433;;- arithmetic shift instructions. 3434 3435;; @@ Do the optimized patterns with -1 get used? Perhaps operand 1 should 3436;; be arith32_operand? 3437 3438;; Use tbnd to support TARGET_TRAP_LARGE_SHIFT. 3439(define_insn "tbnd" 3440 [(trap_if (gtu (match_operand:SI 0 "register_operand" "r") 3441 (match_operand:SI 1 "arith_operand" "rI")) 3442 (const_int 7))] 3443 "" 3444 "tbnd %0,%1" 3445 [(set_attr "type" "weird") 3446 (set_attr "length" "1")]) 3447 3448;; Just in case the optimizer decides to fold away the test. 3449(define_insn "" 3450 [(trap_if (const_int 1) (const_int 7))] 3451 "" 3452 "tbnd %#r31,0" 3453 [(set_attr "type" "weird") 3454 (set_attr "length" "1")]) 3455 3456(define_expand "ashlsi3" 3457 [(set (match_operand:SI 0 "register_operand" "") 3458 (ashift:SI (match_operand:SI 1 "register_operand" "") 3459 (match_operand:SI 2 "arith32_operand" "")))] 3460 "" 3461 " 3462{ 3463 if (GET_CODE (operands[2]) == CONST_INT) 3464 { 3465 if ((unsigned) INTVAL (operands[2]) > 31) 3466 { 3467 if (TARGET_TRAP_LARGE_SHIFT) 3468 emit_insn (gen_tbnd (force_reg (SImode, operands[2]), 3469 GEN_INT (31))); 3470 else 3471 emit_move_insn (operands[0], const0_rtx); 3472 DONE; 3473 } 3474 } 3475 3476 else if (TARGET_TRAP_LARGE_SHIFT) 3477 emit_insn (gen_tbnd (operands[2], GEN_INT (31))); 3478 3479 else if (TARGET_HANDLE_LARGE_SHIFT) 3480 { 3481 rtx reg = gen_reg_rtx (SImode); 3482 emit_insn (gen_cmpsi (operands[2], GEN_INT (31))); 3483 emit_insn (gen_sleu (reg)); 3484 emit_insn (gen_andsi3 (reg, operands[1], reg)); 3485 operands[1] = reg; 3486 } 3487}") 3488 3489(define_insn "" 3490 [(set (match_operand:SI 0 "register_operand" "=r,r") 3491 (ashift:SI (match_operand:SI 1 "register_operand" "r,r") 3492 (match_operand:SI 2 "arith5_operand" "r,K")))] 3493 "" 3494 "@ 3495 mak %0,%1,%2 3496 mak %0,%1,0<%2>" 3497 [(set_attr "type" "bit")]) 3498 3499(define_expand "ashrsi3" 3500 [(set (match_operand:SI 0 "register_operand" "") 3501 (ashiftrt:SI (match_operand:SI 1 "register_operand" "") 3502 (match_operand:SI 2 "arith32_operand" "")))] 3503 "" 3504 " 3505{ 3506 if (GET_CODE (operands[2]) == CONST_INT) 3507 { 3508 if ((unsigned) INTVAL (operands[2]) > 31) 3509 { 3510 if (TARGET_TRAP_LARGE_SHIFT) 3511 { 3512 emit_insn (gen_tbnd (force_reg (SImode, operands[2]), 3513 GEN_INT (31))); 3514 DONE; 3515 } 3516 else 3517 operands[2] = GEN_INT (31); 3518 } 3519 } 3520 3521 else if (TARGET_TRAP_LARGE_SHIFT) 3522 emit_insn (gen_tbnd (operands[2], GEN_INT (31))); 3523 3524 else if (TARGET_HANDLE_LARGE_SHIFT) 3525 { 3526 rtx reg = gen_reg_rtx (SImode); 3527 emit_insn (gen_cmpsi (operands[2], GEN_INT (31))); 3528 emit_insn (gen_sgtu (reg)); 3529 emit_insn (gen_iorsi3 (reg, operands[2], reg)); 3530 operands[2] = reg; 3531 } 3532}") 3533 3534(define_insn "" 3535 [(set (match_operand:SI 0 "register_operand" "=r,r") 3536 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r") 3537 (match_operand:SI 2 "arith5_operand" "r,K")))] 3538 "" 3539 "@ 3540 ext %0,%1,%2 3541 ext %0,%1,0<%2>" 3542 [(set_attr "type" "bit")]) 3543 3544;;- logical shift instructions. Logical shift left becomes arithmetic 3545;; shift left. 3546 3547(define_expand "lshrsi3" 3548 [(set (match_operand:SI 0 "register_operand" "") 3549 (lshiftrt:SI (match_operand:SI 1 "register_operand" "") 3550 (match_operand:SI 2 "arith32_operand" "")))] 3551 "" 3552 " 3553{ 3554 if (GET_CODE (operands[2]) == CONST_INT) 3555 { 3556 if ((unsigned) INTVAL (operands[2]) > 31) 3557 { 3558 if (TARGET_TRAP_LARGE_SHIFT) 3559 emit_insn (gen_tbnd (force_reg (SImode, operands[2]), 3560 GEN_INT (31))); 3561 else 3562 emit_move_insn (operands[0], const0_rtx); 3563 DONE; 3564 } 3565 } 3566 3567 else if (TARGET_TRAP_LARGE_SHIFT) 3568 emit_insn (gen_tbnd (operands[2], GEN_INT (31))); 3569 3570 else if (TARGET_HANDLE_LARGE_SHIFT) 3571 { 3572 rtx reg = gen_reg_rtx (SImode); 3573 emit_insn (gen_cmpsi (operands[2], GEN_INT (31))); 3574 emit_insn (gen_sleu (reg)); 3575 emit_insn (gen_andsi3 (reg, operands[1], reg)); 3576 operands[1] = reg; 3577 } 3578}") 3579 3580(define_insn "" 3581 [(set (match_operand:SI 0 "register_operand" "=r,r") 3582 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r") 3583 (match_operand:SI 2 "arith5_operand" "r,K")))] 3584 "" 3585 "@ 3586 extu %0,%1,%2 3587 extu %0,%1,0<%2>" 3588 [(set_attr "type" "bit")]) 3589 3590;;- rotate instructions 3591 3592(define_expand "rotlsi3" 3593 [(set (match_operand:SI 0 "register_operand" "") 3594 (rotatert:SI (match_operand:SI 1 "register_operand" "") 3595 (match_operand:SI 2 "arith32_operand" "")))] 3596 "" 3597 " 3598{ 3599 if (GET_CODE (operands[2]) == CONST_INT 3600 && (unsigned) INTVAL (operands[2]) >= 32) 3601 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32); 3602 else 3603 { 3604 rtx op = gen_reg_rtx (SImode); 3605 emit_insn (gen_negsi2 (op, operands[2])); 3606 operands[2] = op; 3607 } 3608}") 3609 3610(define_insn "rotrsi3" 3611 [(set (match_operand:SI 0 "register_operand" "=r") 3612 (rotatert:SI (match_operand:SI 1 "register_operand" "r") 3613 (match_operand:SI 2 "arith_operand" "rI")))] 3614 "" 3615 "rot %0,%1,%2" 3616 [(set_attr "type" "bit")]) 3617 3618;; find first set. 3619 3620;; The ff1 instruction searches from the most significant bit while ffs 3621;; searches from the least significant bit. The bit index and treatment of 3622;; zero also differ. This amazing sequence was discovered using the GNU 3623;; Superoptimizer. 3624 3625(define_insn "ffssi2" 3626 [(set (match_operand:SI 0 "register_operand" "=r,&r") 3627 (ffs:SI (match_operand:SI 1 "register_operand" "0,r"))) 3628 (clobber (reg:CC 0)) 3629 (clobber (match_scratch:SI 2 "=r,X"))] 3630 "" 3631 "@ 3632 subu.co %2,%#r0,%1\;and %2,%2,%1\;addu.ci %2,%2,%2\;ff1 %0,%2 3633 subu.co %0,%#r0,%1\;and %0,%0,%1\;addu.ci %0,%0,%0\;ff1 %0,%0" 3634 [(set_attr "type" "marith") 3635 (set_attr "length" "4")]) 3636 3637;; Bit field instructions. 3638 3639(define_insn "" 3640 [(set (match_operand:SI 0 "register_operand" "=r") 3641 (sign_extract:SI (match_operand:SI 1 "register_operand" "r") 3642 (const_int 32) 3643 (const_int 0)))] 3644 "" 3645 "or %0,%#r0,%1") 3646 3647(define_insn "extv" 3648 [(set (match_operand:SI 0 "register_operand" "=r") 3649 (sign_extract:SI (match_operand:SI 1 "register_operand" "r") 3650 (match_operand:SI 2 "int5_operand" "") 3651 (match_operand:SI 3 "int5_operand" "")))] 3652 "" 3653{ 3654 operands[4] = GEN_INT ((32 - INTVAL (operands[2])) - INTVAL (operands[3])); 3655 return "ext %0,%1,%2<%4>"; /* <(32-%2-%3)> */ 3656} 3657 [(set_attr "type" "bit")]) 3658 3659(define_insn "" 3660 [(set (match_operand:SI 0 "register_operand" "=r") 3661 (zero_extract:SI (match_operand:SI 1 "register_operand" "r") 3662 (const_int 32) 3663 (const_int 0)))] 3664 "" 3665 "or %0,%#r0,%1") 3666 3667(define_insn "extzv" 3668 [(set (match_operand:SI 0 "register_operand" "=r") 3669 (zero_extract:SI (match_operand:SI 1 "register_operand" "r") 3670 (match_operand:SI 2 "int5_operand" "") 3671 (match_operand:SI 3 "int5_operand" "")))] 3672 "" 3673{ 3674 operands[4] = GEN_INT ((32 - INTVAL (operands[2])) - INTVAL (operands[3])); 3675 return "extu %0,%1,%2<%4>"; /* <(32-%2-%3)> */ 3676} 3677 [(set_attr "type" "bit")]) 3678 3679(define_insn "" 3680 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") 3681 (match_operand:SI 1 "int5_operand" "") 3682 (match_operand:SI 2 "int5_operand" "")) 3683 (const_int 0))] 3684 "" 3685{ 3686 operands[3] = GEN_INT ((32 - INTVAL (operands[1])) - INTVAL (operands[2])); 3687 return "clr %0,%0,%1<%3>"; /* <(32-%1-%2)> */ 3688} 3689 [(set_attr "type" "bit")]) 3690 3691(define_insn "" 3692 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") 3693 (match_operand:SI 1 "int5_operand" "") 3694 (match_operand:SI 2 "int5_operand" "")) 3695 (const_int -1))] 3696 "" 3697{ 3698 operands[3] = GEN_INT ((32 - INTVAL (operands[1])) - INTVAL (operands[2])); 3699 return "set %0,%0,%1<%3>"; /* <(32-%1-%2)> */ 3700} 3701 [(set_attr "type" "bit")]) 3702 3703(define_insn "" 3704 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") 3705 (match_operand:SI 1 "int5_operand" "") 3706 (match_operand:SI 2 "int5_operand" "")) 3707 (match_operand:SI 3 "int32_operand" "n"))] 3708 "" 3709{ 3710 int value = INTVAL (operands[3]); 3711 3712 if (INTVAL (operands[1]) < 32) 3713 value &= (1 << INTVAL (operands[1])) - 1; 3714 3715 operands[2] = GEN_INT (32 - (INTVAL(operands[1]) + INTVAL(operands[2]))); 3716 3717 value <<= INTVAL (operands[2]); 3718 operands[3] = GEN_INT (value); 3719 3720 if (SMALL_INTVAL (value)) 3721 return "clr %0,%0,%1<%2>\;or %0,%0,%3"; 3722 else if ((value & 0x0000ffff) == 0) 3723 return "clr %0,%0,%1<%2>\;or.u %0,%0,%X3"; 3724 else 3725 return "clr %0,%0,%1<%2>\;or.u %0,%0,%X3\;or %0,%0,%x3"; 3726} 3727 [(set_attr "type" "marith") 3728 (set_attr "length" "3")]) ; may be 2 or 3. 3729 3730;; negate insns 3731(define_insn "negsi2" 3732 [(set (match_operand:SI 0 "register_operand" "=r") 3733 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))] 3734 "" 3735 "subu %0,%#r0,%1") 3736 3737(define_insn "" 3738 [(set (match_operand:SF 0 "register_operand" "=r,x") 3739 (float_truncate:SF (neg:DF (match_operand:DF 1 "register_operand" "r,x"))))] 3740 "" 3741 "@ 3742 fsub.ssd %0,%#r0,%1 3743 fsub.ssd %0,%#x0,%1" 3744 [(set_attr "type" "dpadd")]) 3745 3746(define_insn "negdf2" 3747 [(set (match_operand:DF 0 "register_operand" "=&r,r") 3748 (neg:DF (match_operand:DF 1 "register_operand" "r,0")))] 3749 "" 3750 "@ 3751 xor.u %0,%1,0x8000\;or %d0,%#r0,%d1 3752 xor.u %0,%0,0x8000" 3753 [(set_attr "type" "marith,arith")]) 3754 3755(define_insn "negsf2" 3756 [(set (match_operand:SF 0 "register_operand" "=r") 3757 (neg:SF (match_operand:SF 1 "register_operand" "r")))] 3758 "" 3759 "xor.u %0,%1,0x8000") 3760 3761;; absolute value insns for floating-point (integer abs can be done using the 3762;; machine-independent sequence). 3763 3764(define_insn "absdf2" 3765 [(set (match_operand:DF 0 "register_operand" "=&r,r") 3766 (abs:DF (match_operand:DF 1 "register_operand" "r,0")))] 3767 "" 3768 "@ 3769 and.u %0,%1,0x7fff\;or %d0,%#r0,%d1 3770 and.u %0,%0,0x7fff" 3771 [(set_attr "type" "marith,arith")]) 3772 3773(define_insn "abssf2" 3774 [(set (match_operand:SF 0 "register_operand" "=r") 3775 (abs:SF (match_operand:SF 1 "register_operand" "r")))] 3776 "" 3777 "and.u %0,%1,0x7fff") 3778 3779;; Subroutines of "casesi". 3780 3781;; Operand 0 is index 3782;; operand 1 is the minimum bound 3783;; operand 2 is the maximum bound - minimum bound + 1 3784;; operand 3 is CODE_LABEL for the table; 3785;; operand 4 is the CODE_LABEL to go to if index out of range. 3786 3787(define_expand "casesi" 3788 ;; We don't use these for generating the RTL, but we must describe 3789 ;; the operands here. 3790 [(match_operand:SI 0 "general_operand" "") 3791 (match_operand:SI 1 "immediate_operand" "") 3792 (match_operand:SI 2 "immediate_operand" "") 3793 (match_operand 3 "" "") 3794 (match_operand 4 "" "")] 3795 "" 3796 " 3797{ 3798 register rtx index_diff = gen_reg_rtx (SImode); 3799 register rtx low = GEN_INT (-INTVAL (operands[1])); 3800 register rtx label = gen_rtx_LABEL_REF (Pmode, operands[3]); 3801 register rtx base = NULL_RTX; 3802 3803 if (! CASE_VECTOR_INSNS) 3804 /* These instructions are likely to be scheduled and made loop invariant. 3805 This decreases the cost of the dispatch at the expense of the default 3806 case. */ 3807 base = force_reg (SImode, memory_address_noforce (SImode, label)); 3808 3809 /* Compute the index difference and handle the default case. */ 3810 emit_insn (gen_addsi3 (index_diff, 3811 force_reg (SImode, operands[0]), 3812 ADD_INT (low) ? low : force_reg (SImode, low))); 3813 emit_insn (gen_cmpsi (index_diff, operands[2])); 3814 /* It's possible to replace this branch with sgtu/iorsi3 and adding a -1 3815 entry to the table. However, that doesn't seem to win on the m88110. */ 3816 emit_jump_insn (gen_bgtu (operands[4])); 3817 3818 if (CASE_VECTOR_INSNS) 3819 /* Call the jump that will branch to the appropriate case. */ 3820 emit_jump_insn (gen_casesi_enter (label, index_diff, operands[3])); 3821 else 3822 /* Load the table entry and jump to it. */ 3823 emit_jump_insn (gen_casesi_jump (gen_reg_rtx (SImode), base, index_diff, operands[3])); 3824 3825 /* Claim that flow drops into the table so it will be adjacent by not 3826 emitting a barrier. */ 3827 DONE; 3828}") 3829 3830(define_expand "casesi_jump" 3831 [(set (match_operand:SI 0 "" "") 3832 (mem:SI (plus:SI (match_operand:SI 1 "" "") 3833 (mult:SI (match_operand:SI 2 "" "") 3834 (const_int 4))))) 3835 (parallel [(set (pc) (match_dup 0)) 3836 (use (label_ref (match_operand 3 "" "")))])] 3837 "" 3838 "") 3839 3840(define_insn "" 3841 [(set (pc) (match_operand:SI 0 "register_operand" "r")) 3842 (use (label_ref (match_operand 1 "" "")))] 3843 "" 3844 "jmp%. %0" 3845 [(set_attr "type" "jump")]) 3846 3847;; The bsr.n instruction is directed to the END of the table. See 3848;; ASM_OUTPUT_CASE_END. 3849 3850(define_insn "casesi_enter" 3851 [(set (pc) (match_operand 0 "" "")) 3852 (use (match_operand:SI 1 "register_operand" "r")) 3853 ;; The USE here is so that at least one jump-insn will refer to the label, 3854 ;; to keep it alive in jump_optimize. 3855 (use (label_ref (match_operand 2 "" ""))) 3856 (clobber (reg:SI 1))] 3857 "" 3858{ 3859 if (flag_delayed_branch) 3860 return "bsr.n %0e\;lda %#r1,%#r1[%1]"; 3861 m88k_case_index = REGNO (operands[1]); 3862 return "bsr %0e"; 3863} 3864 [(set_attr "type" "weird") 3865 (set_attr "length" "3")]) ; Including the "jmp r1". 3866 3867;;- jump to subroutine 3868(define_expand "call" 3869 [(parallel [(call (match_operand:SI 0 "" "") 3870 (match_operand 1 "" "")) 3871 (clobber (reg:SI 1))])] 3872 "" 3873 " 3874{ 3875 gcc_assert (GET_CODE (operands[0]) == MEM); 3876 3877 if (! call_address_operand (XEXP (operands[0], 0), SImode)) /* Pmode ? */ 3878 operands[0] = gen_rtx_MEM (GET_MODE (operands[0]), 3879 force_reg (Pmode, XEXP (operands[0], 0))); 3880}") 3881 3882(define_insn "" 3883 [(parallel [(call (mem:SI (match_operand:SI 0 "call_address_operand" "rQ")) 3884 (match_operand 1 "" "")) 3885 (clobber (reg:SI 1))])] 3886 "" 3887 "* return output_call (operands, operands[0]);" 3888 [(set_attr "type" "call")]) 3889 3890(define_expand "call_value" 3891 [(parallel [(set (match_operand 0 "register_operand" "") 3892 (call (match_operand:SI 1 "" "") 3893 (match_operand 2 "" ""))) 3894 (clobber (reg:SI 1))])] 3895 "" 3896 " 3897{ 3898 gcc_assert (GET_CODE (operands[1]) == MEM); 3899 3900 if (! call_address_operand (XEXP (operands[1], 0), SImode)) 3901 operands[1] = gen_rtx_MEM (GET_MODE (operands[1]), 3902 force_reg (Pmode, XEXP (operands[1], 0))); 3903}") 3904 3905(define_insn "" 3906 [(parallel [(set (match_operand 0 "register_operand" "=r") 3907 (call (mem:SI 3908 (match_operand:SI 1 "call_address_operand" "rQ")) 3909 (match_operand 2 "" ""))) 3910 (clobber (reg:SI 1))])] 3911 "" 3912 "* return output_call (operands, operands[1]);" 3913 [(set_attr "type" "call")]) 3914 3915;; Nop instruction and others 3916 3917(define_insn "nop" 3918 [(const_int 0)] 3919 "" 3920 "ff0 %#r0,%#r0" 3921 [(set_attr "type" "bit")]) 3922 3923(define_insn "return" 3924 [(return)] 3925 "null_prologue()" 3926 "jmp%. %#r1" 3927 [(set_attr "type" "jump")]) 3928 3929(define_expand "prologue" 3930 [(use (const_int 0))] 3931 "" 3932{ 3933 m88k_expand_prologue (); 3934 DONE; 3935}) 3936 3937(define_expand "epilogue" 3938 [(use (const_int 0))] 3939 "" 3940{ 3941 m88k_expand_epilogue (); 3942}) 3943 3944(define_insn "blockage" 3945 [(unspec_volatile [(const_int 0)] 0)] 3946 "" 3947 "" 3948 [(set_attr "length" "0")]) 3949 3950(define_insn "indirect_jump" 3951 [(set (pc) (match_operand:SI 0 "register_operand" "r"))] 3952 "" 3953 "jmp%. %0" 3954 [(set_attr "type" "jump")]) 3955 3956(define_insn "jump" 3957 [(set (pc) 3958 (label_ref (match_operand 0 "" "")))] 3959 "" 3960 "br%. %l0" 3961 [(set_attr "type" "jump")]) 3962 3963;; This insn is used for some loop tests, typically loops reversed when 3964;; strength reduction is used. It is actually created when the instruction 3965;; combination phase combines the special loop test. Since this insn 3966;; is both a jump insn and has an output, it must deal with its own 3967;; reloads, hence the `m' constraints. The `!' constraints direct reload 3968;; to not choose the register alternatives in the event a reload is needed. 3969 3970(define_expand "decrement_and_branch_until_zero" 3971 [(parallel [(set (pc) 3972 (if_then_else 3973 (match_operator 0 "relop_no_unsigned" 3974 [(match_operand:SI 1 "register_operand" "") 3975 (const_int 0)]) 3976 (label_ref (match_operand 2 "" "")) 3977 (pc))) 3978 (set (match_dup 1) 3979 (plus:SI (match_dup 1) 3980 (match_operand:SI 3 "add_operand" ""))) 3981 (clobber (match_scratch:SI 4 "")) 3982 (clobber (match_scratch:SI 5 "=X,X,&r,&r"))])] 3983 "" 3984 "") 3985 3986(define_insn "" 3987 [(set (pc) 3988 (if_then_else 3989 (match_operator 0 "relop_no_unsigned" 3990 [(match_operand:SI 1 "register_operand" "+!r,!r,m,m") 3991 (const_int 0)]) 3992 (label_ref (match_operand 2 "" "")) 3993 (pc))) 3994 (set (match_dup 1) 3995 (plus:SI (match_dup 1) 3996 (match_operand:SI 3 "add_operand" "rI,J,rI,J"))) 3997 (clobber (match_scratch:SI 4 "=X,X,&r,&r")) 3998 (clobber (match_scratch:SI 5 "=X,X,&r,&r"))] 3999 "find_reg_note (insn, REG_NONNEG, 0)" 4000 "@ 4001 bcnd.n %B0,%1,%2\;addu %1,%1,%3 4002 bcnd.n %B0,%1,%2\;subu %1,%1,%n3 4003 ld %4,%1\;addu %5,%4,%3\;bcnd.n %B0,%4,%2\;st %5,%1 4004 ld %4,%1\;subu %5,%4,%n3\;bcnd.n %B0,%4,%2\;st %5,%1" 4005 [(set_attr "type" "weird") 4006 (set_attr "length" "2,2,4,4")]) 4007 4008;; Special insn to serve as the last insn of a define_expand. This insn 4009;; will generate no code. 4010 4011(define_expand "dummy" 4012 [(set (match_operand 0 "" "") (match_dup 0))] 4013 "" 4014 "") 4015