1;;- Machine description for GNU compiler, Motorola 68000 Version 2;; Copyright (C) 1987-2018 Free Software Foundation, Inc. 3 4;; This file is part of GCC. 5 6;; GCC is free software; you can redistribute it and/or modify 7;; it under the terms of the GNU General Public License as published by 8;; the Free Software Foundation; either version 3, or (at your option) 9;; any later version. 10 11;; GCC is distributed in the hope that it will be useful, 12;; but WITHOUT ANY WARRANTY; without even the implied warranty of 13;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14;; GNU General Public License for more details. 15 16;; You should have received a copy of the GNU General Public License 17;; along with GCC; see the file COPYING3. If not see 18;; <http://www.gnu.org/licenses/>. 19 20;;- Information about MCF5200 port. 21 22;;- The MCF5200 "ColdFire" architecture is a reduced version of the 23;;- 68k ISA. Differences include reduced support for byte and word 24;;- operands and the removal of BCD, bitfield, rotate, and integer 25;;- divide instructions. The TARGET_COLDFIRE flag turns the use of the 26;;- removed opcodes and addressing modes off. 27;;- 28 29 30;;- instruction definitions 31 32;;- @@The original PO technology requires these to be ordered by speed, 33;;- @@ so that assigner will pick the fastest. 34 35;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. 36 37;;- When naming insn's (operand 0 of define_insn) be careful about using 38;;- names from other targets machine descriptions. 39 40;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code 41;;- updates for most instructions. 42 43;;- Operand classes for the register allocator: 44;;- 'a' one of the address registers can be used. 45;;- 'd' one of the data registers can be used. 46;;- 'f' one of the m68881/fpu registers can be used 47;;- 'r' either a data or an address register can be used. 48 49;;- Immediate Floating point operator constraints 50;;- 'G' a floating point constant that is *NOT* one of the standard 51;; 68881 constant values (to force calling output_move_const_double 52;; to get it from rom if it is a 68881 constant). 53;; 54;; See the functions standard_XXX_constant_p in output-m68k.c for more 55;; info. 56 57;;- Immediate integer operand constraints: 58;;- 'I' 1 .. 8 59;;- 'J' -32768 .. 32767 60;;- 'K' all integers EXCEPT -128 .. 127 61;;- 'L' -8 .. -1 62;;- 'M' all integers EXCEPT -256 .. 255 63;;- 'N' 24 .. 31 64;;- 'O' 16 65;;- 'P' 8 .. 15 66 67;;- Assembler specs: 68;;- "%." size separator ("." or "") move%.l d0,d1 69;;- "%-" push operand "sp@-" move%.l d0,%- 70;;- "%+" pop operand "sp@+" move%.l d0,%+ 71;;- "%@" top of stack "sp@" move%.l d0,%@ 72;;- "%!" fpcr register 73;;- "%$" single-precision fp specifier ("s" or "") f%$add.x fp0,fp1 74;;- "%&" double-precision fp specifier ("d" or "") f%&add.x fp0,fp1 75 76;;- Information about 68040 port. 77 78;;- The 68040 executes all 68030 and 68881/2 instructions, but some must 79;;- be emulated in software by the OS. It is faster to avoid these 80;;- instructions and issue a library call rather than trapping into 81;;- the kernel. The affected instructions are fintrz and fscale. The 82;;- TUNE_68040 flag turns the use of the opcodes off. 83 84;;- The '040 also implements a set of new floating-point instructions 85;;- which specify the rounding precision in the opcode. This finally 86;;- permit the 68k series to be truly IEEE compliant, and solves all 87;;- issues of excess precision accumulating in the extended registers. 88;;- By default, GCC does not use these instructions, since such code will 89;;- not run on an '030. To use these instructions, use the -m68040-only 90;;- switch. 91 92;;- These new instructions aren't directly in the md. They are brought 93;;- into play by defining "%$" and "%&" to expand to "s" and "d" rather 94;;- than "". 95 96;;- Information about 68060 port. 97 98;;- The 68060 executes all 68030 and 68881/2 instructions, but some must 99;;- be emulated in software by the OS. It is faster to avoid these 100;;- instructions and issue a library call rather than trapping into 101;;- the kernel. The affected instructions are: divs.l <ea>,Dr:Dq; 102;;- divu.l <ea>,Dr:Dq; muls.l <ea>,Dr:Dq; mulu.l <ea>,Dr:Dq; and 103;;- fscale. The TUNE_68060 flag turns the use of the opcodes off. 104 105;;- Some of these insn's are composites of several m68000 op codes. 106;;- The assembler (or final @@??) insures that the appropriate one is 107;;- selected. 108 109;; UNSPEC usage: 110 111(define_constants 112 [(UNSPEC_SIN 1) 113 (UNSPEC_COS 2) 114 (UNSPEC_GOT 3) 115 (UNSPEC_IB 4) 116 (UNSPEC_TIE 5) 117 (UNSPEC_RELOC16 6) 118 (UNSPEC_RELOC32 7) 119 ]) 120 121;; UNSPEC_VOLATILE usage: 122 123(define_constants 124 [(UNSPECV_BLOCKAGE 0) 125 (UNSPECV_CAS_1 1) 126 (UNSPECV_CAS_2 2) 127 (UNSPECV_TAS_1 3) 128 (UNSPECV_TAS_2 4) 129 ]) 130 131;; Registers by name. 132(define_constants 133 [(D0_REG 0) 134 (A0_REG 8) 135 (A1_REG 9) 136 (PIC_REG 13) 137 (A6_REG 14) 138 (SP_REG 15) 139 (FP0_REG 16) 140 ]) 141 142(include "predicates.md") 143(include "constraints.md") 144 145;; :::::::::::::::::::: 146;; :: 147;; :: Attributes 148;; :: 149;; :::::::::::::::::::: 150 151;; Processor type. 152(define_attr "cpu" "cfv1, cfv2, cfv3, cfv4, unknown" 153 (const (symbol_ref "m68k_sched_cpu"))) 154 155;; MAC type. 156(define_attr "mac" "no, cf_mac, cf_emac" 157 (const (symbol_ref "m68k_sched_mac"))) 158 159;; Instruction type for use in scheduling description. 160;; _l and _w suffixes indicate size of the operands of instruction. 161;; alu - usual arithmetic or logic instruction. 162;; aluq - arithmetic or logic instruction which has a quick immediate (the one 163;; that is encoded in the instruction word) for its Y operand. 164;; alux - Arithmetic instruction that uses carry bit (e.g., addx and subx). 165;; bcc - conditional branch. 166;; bitr - bit operation that only updates flags. 167;; bitrw - bit operation that updates flags and output operand. 168;; bra, bsr, clr, cmp, div, ext - corresponding instruction. 169;; falu, fbcc, fcmp, fdiv, fmove, fmul, fneg, fsqrt, ftst - corresponding 170;; instruction. 171;; ib - fake instruction to subscribe slots in ColdFire V1,V2,V3 instruction 172;; buffer. 173;; ignore - fake instruction. 174;; jmp, jsr, lea, link, mov3q, move, moveq, mul - corresponding instruction. 175;; mvsz - mvs or mvz instruction. 176;; neg, nop, pea, rts, scc - corresponding instruction. 177;; shift - arithmetic or logical shift instruction. 178;; trap, tst, unlk - corresponding instruction. 179(define_attr "type" 180 "alu_l,aluq_l,alux_l,bcc,bitr,bitrw,bra,bsr,clr,clr_l,cmp,cmp_l, 181 div_w,div_l,ext, 182 falu,fbcc,fcmp,fdiv,fmove,fmul,fneg,fsqrt,ftst, 183 ib,ignore, 184 jmp,jsr,lea,link,mov3q_l,move,move_l,moveq_l,mul_w,mul_l,mvsz,neg_l,nop, 185 pea,rts,scc,shift, 186 trap,tst,tst_l,unlk, 187 unknown" 188 (const_string "unknown")) 189 190;; Index of the X or Y operand in recog_data.operand[]. 191;; Should be used only within opx_type and opy_type. 192(define_attr "opx" "" (const_int 0)) 193(define_attr "opy" "" (const_int 1)) 194 195;; Type of the Y operand. 196;; See m68k.c: enum attr_op_type. 197(define_attr "opy_type" 198 "none,Rn,FPn,mem1,mem234,mem5,mem6,mem7,imm_q,imm_w,imm_l" 199 (cond [(eq_attr "type" "ext,fbcc,ftst,neg_l,bcc,bra,bsr,clr,clr_l,ib,ignore, 200 jmp,jsr,nop,rts,scc,trap,tst,tst_l, 201 unlk,unknown") (const_string "none") 202 (eq_attr "type" "lea,pea") 203 (symbol_ref "m68k_sched_attr_opy_type (insn, 1)")] 204 (symbol_ref "m68k_sched_attr_opy_type (insn, 0)"))) 205 206;; Type of the X operand. 207;; See m68k.c: enum attr_op_type. 208(define_attr "opx_type" 209 "none,Rn,FPn,mem1,mem234,mem5,mem6,mem7,imm_q,imm_w,imm_l" 210 (cond [(eq_attr "type" "ib,ignore,nop,rts,trap,unlk, 211 unknown") (const_string "none") 212 (eq_attr "type" "pea") (const_string "mem1") 213 (eq_attr "type" "jmp,jsr") 214 (symbol_ref "m68k_sched_attr_opx_type (insn, 1)")] 215 (symbol_ref "m68k_sched_attr_opx_type (insn, 0)"))) 216 217;; Access to the X operand: none, read, write, read/write, unknown. 218;; Access to the Y operand is either none (if opy_type is none) 219;; or read otherwise. 220(define_attr "opx_access" "none, r, w, rw" 221 (cond [(eq_attr "type" "ib,ignore,nop,rts,trap,unlk, 222 unknown") (const_string "none") 223 (eq_attr "type" "bcc,bra,bsr,bitr,cmp,cmp_l,fbcc,fcmp,ftst, 224 jmp,jsr,tst,tst_l") (const_string "r") 225 (eq_attr "type" "clr,clr_l,fneg,fmove,lea, 226 mov3q_l,move,move_l,moveq_l,mvsz, 227 pea,scc") (const_string "w") 228 (eq_attr "type" "alu_l,aluq_l,alux_l,bitrw,div_w,div_l,ext, 229 falu,fdiv,fmul,fsqrt,link,mul_w,mul_l, 230 neg_l,shift") (const_string "rw")] 231 ;; Should never be used. 232 (symbol_ref "(gcc_unreachable (), OPX_ACCESS_NONE)"))) 233 234;; Memory accesses of the insn. 235;; 00 - no memory references 236;; 10 - memory is read 237;; i0 - indexed memory is read 238;; 01 - memory is written 239;; 0i - indexed memory is written 240;; 11 - memory is read, memory is written 241;; i1 - indexed memory is read, memory is written 242;; 1i - memory is read, indexed memory is written 243(define_attr "op_mem" "00, 10, i0, 01, 0i, 11, i1, 1i" 244 (symbol_ref "m68k_sched_attr_op_mem (insn)")) 245 246;; Instruction size in words. 247(define_attr "size" "1,2,3" 248 (symbol_ref "m68k_sched_attr_size (insn)")) 249 250;; Alternative is OK for ColdFire. 251(define_attr "ok_for_coldfire" "yes,no" (const_string "yes")) 252 253;; Define 'enabled' attribute. 254(define_attr "enabled" "" 255 (cond [(and (match_test "TARGET_COLDFIRE") 256 (eq_attr "ok_for_coldfire" "no")) 257 (const_int 0)] 258 (const_int 1))) 259 260;; Mode macros for integer operations. 261(define_mode_iterator I [QI HI SI]) 262(define_mode_attr sz [(QI "%.b") (HI "%.w") (SI "%.l")]) 263 264;; Mode macros for floating point operations. 265;; Valid floating point modes 266(define_mode_iterator FP [SF DF (XF "TARGET_68881")]) 267;; Mnemonic infix to round result 268(define_mode_attr round [(SF "%$") (DF "%&") (XF "")]) 269;; Mnemonic infix to round result for mul or div instruction 270(define_mode_attr round_mul [(SF "sgl") (DF "%&") (XF "")]) 271;; Suffix specifying source operand format 272(define_mode_attr prec [(SF "s") (DF "d") (XF "x")]) 273;; Allowable D registers 274(define_mode_attr dreg [(SF "d") (DF "") (XF "")]) 275;; Allowable 68881 constant constraints 276(define_mode_attr const [(SF "F") (DF "G") (XF "")]) 277 278 279(define_insn_and_split "*movdf_internal" 280 [(set (match_operand:DF 0 "push_operand" "=m, m") 281 (match_operand:DF 1 "general_operand" "f, ro<>E"))] 282 "" 283 "@ 284 fmove%.d %f1,%0 285 #" 286 "&& reload_completed && (extract_constrain_insn_cached (insn), which_alternative == 1)" 287 [(const_int 0)] 288{ 289 m68k_emit_move_double (operands); 290 DONE; 291} 292 [(set_attr "type" "fmove,*")]) 293 294(define_insn_and_split "pushdi" 295 [(set (match_operand:DI 0 "push_operand" "=m") 296 (match_operand:DI 1 "general_operand" "ro<>Fi"))] 297 "" 298 "#" 299 "&& reload_completed" 300 [(const_int 0)] 301{ 302 m68k_emit_move_double (operands); 303 DONE; 304}) 305 306;; We don't want to allow a constant operand for test insns because 307;; (set (cc0) (const_int foo)) has no mode information. Such insns will 308;; be folded while optimizing anyway. 309 310(define_insn "tstdi" 311 [(set (cc0) 312 (compare (match_operand:DI 0 "nonimmediate_operand" "am,d") 313 (const_int 0))) 314 (clobber (match_scratch:SI 1 "=X,d")) 315 (clobber (match_scratch:DI 2 "=d,X"))] 316 "" 317{ 318 if (which_alternative == 0) 319 { 320 rtx xoperands[2]; 321 322 xoperands[0] = operands[2]; 323 xoperands[1] = operands[0]; 324 output_move_double (xoperands); 325 cc_status.flags |= CC_REVERSED; /*|*/ 326 return "neg%.l %R2\;negx%.l %2"; 327 } 328 if (find_reg_note (insn, REG_DEAD, operands[0])) 329 { 330 cc_status.flags |= CC_REVERSED; /*|*/ 331 return "neg%.l %R0\;negx%.l %0"; 332 } 333 else 334 /* 335 'sub' clears %1, and also clears the X cc bit 336 'tst' sets the Z cc bit according to the low part of the DImode operand 337 'subx %1' (i.e. subx #0) acts as a (non-existent) tstx on the high part. 338 */ 339 return "sub%.l %1,%1\;tst%.l %R0\;subx%.l %1,%0"; 340}) 341 342;; If you think that the 68020 does not support tstl a0, 343;; reread page B-167 of the 68020 manual more carefully. 344(define_insn "*tstsi_internal_68020_cf" 345 [(set (cc0) 346 (compare (match_operand:SI 0 "nonimmediate_operand" "rm") 347 (const_int 0)))] 348 "TARGET_68020 || TARGET_COLDFIRE" 349 "tst%.l %0" 350 [(set_attr "type" "tst_l")]) 351 352;; On an address reg, cmpw may replace cmpl. 353(define_insn "*tstsi_internal" 354 [(set (cc0) 355 (compare (match_operand:SI 0 "nonimmediate_operand" "dm,r") 356 (const_int 0)))] 357 "!(TARGET_68020 || TARGET_COLDFIRE)" 358 "@ 359 tst%.l %0 360 cmp%.w #0,%0" 361 [(set_attr "type" "tst_l,cmp")]) 362 363;; This can't use an address register, because comparisons 364;; with address registers as second operand always test the whole word. 365(define_insn "*tsthi_internal" 366 [(set (cc0) 367 (compare (match_operand:HI 0 "nonimmediate_operand" "dm") 368 (const_int 0)))] 369 "" 370 "tst%.w %0" 371 [(set_attr "type" "tst")]) 372 373(define_insn "*tstqi_internal" 374 [(set (cc0) 375 (compare (match_operand:QI 0 "nonimmediate_operand" "dm") 376 (const_int 0)))] 377 "" 378 "tst%.b %0" 379 [(set_attr "type" "tst")]) 380 381(define_insn "tst<mode>_68881" 382 [(set (cc0) 383 (compare (match_operand:FP 0 "general_operand" "f<FP:dreg>m") 384 (match_operand:FP 1 "const0_operand" "H")))] 385 "TARGET_68881" 386{ 387 cc_status.flags = CC_IN_68881; 388 if (FP_REG_P (operands[0])) 389 return "ftst%.x %0"; 390 return "ftst%.<FP:prec> %0"; 391} 392 [(set_attr "type" "ftst")]) 393 394(define_insn "tst<mode>_cf" 395 [(set (cc0) 396 (compare (match_operand:FP 0 "general_operand" "f<FP:dreg><Q>U") 397 (match_operand:FP 1 "const0_operand" "H")))] 398 "TARGET_COLDFIRE_FPU" 399{ 400 cc_status.flags = CC_IN_68881; 401 if (FP_REG_P (operands[0])) 402 return "ftst%.d %0"; 403 return "ftst%.<FP:prec> %0"; 404} 405 [(set_attr "type" "ftst")]) 406 407 408;; compare instructions. 409 410(define_insn "*cmpdi_internal" 411 [(set (cc0) 412 (compare (match_operand:DI 1 "nonimmediate_operand" "0,d") 413 (match_operand:DI 2 "general_operand" "d,0"))) 414 (clobber (match_scratch:DI 0 "=d,d"))] 415 "" 416{ 417 if (rtx_equal_p (operands[0], operands[1])) 418 return "sub%.l %R2,%R0\;subx%.l %2,%0"; 419 else 420 { 421 cc_status.flags |= CC_REVERSED; /*|*/ 422 return "sub%.l %R1,%R0\;subx%.l %1,%0"; 423 } 424}) 425 426(define_insn "cmpdi" 427 [(set (cc0) 428 (compare (match_operand:DI 0 "nonimmediate_operand") 429 (match_operand:DI 1 "general_operand"))) 430 (clobber (match_scratch:DI 2))] 431 "" 432 "") 433 434 435(define_expand "cbranchdi4" 436 [(set (pc) 437 (if_then_else (match_operator 0 "ordered_comparison_operator" 438 [(match_operand:DI 1 "nonimmediate_operand") 439 (match_operand:DI 2 "general_operand")]) 440 (label_ref (match_operand 3 "")) 441 (pc)))] 442 "" 443{ 444 if (operands[2] == const0_rtx) 445 emit_insn (gen_tstdi (operands[1])); 446 else 447 emit_insn (gen_cmpdi (operands[1], operands[2])); 448 operands[1] = cc0_rtx; 449 operands[2] = const0_rtx; 450}) 451 452(define_expand "cstoredi4" 453 [(set (match_operand:QI 0 "register_operand") 454 (match_operator:QI 1 "ordered_comparison_operator" 455 [(match_operand:DI 2 "nonimmediate_operand") 456 (match_operand:DI 3 "general_operand")]))] 457 "" 458{ 459 if (operands[3] == const0_rtx) 460 emit_insn (gen_tstdi (operands[2])); 461 else 462 emit_insn (gen_cmpdi (operands[2], operands[3])); 463 operands[2] = cc0_rtx; 464 operands[3] = const0_rtx; 465}) 466 467 468(define_expand "cbranchsi4" 469 [(set (cc0) 470 (compare (match_operand:SI 1 "nonimmediate_operand" "") 471 (match_operand:SI 2 "general_operand" ""))) 472 (set (pc) 473 (if_then_else (match_operator 0 "ordered_comparison_operator" 474 [(cc0) (const_int 0)]) 475 (label_ref (match_operand 3 "")) 476 (pc)))] 477 "" 478 "") 479 480(define_expand "cstoresi4" 481 [(set (cc0) 482 (compare (match_operand:SI 2 "nonimmediate_operand" "") 483 (match_operand:SI 3 "general_operand" ""))) 484 (set (match_operand:QI 0 "register_operand") 485 (match_operator:QI 1 "ordered_comparison_operator" 486 [(cc0) (const_int 0)]))] 487 "" 488 "") 489 490 491;; A composite of the cmp, cmpa, cmpi & cmpm m68000 op codes. 492;; 493;; In theory we ought to be able to use some 'S' constraints and 494;; operand predicates that allow PC-rel addressing modes in the 495;; comparison patterns and expanders below. But we would have to be 496;; cognizant of the fact that PC-rel addresses are not allowed for 497;; both operands and determining whether or not we emit the operands in 498;; order or reversed is not trivial to do just based on the constraints 499;; and operand predicates. So to be safe, just don't allow the PC-rel 500;; versions in the various comparison expanders, patterns, for comparisons. 501(define_insn "" 502 [(set (cc0) 503 (compare (match_operand:SI 0 "nonimmediate_operand" "rKT,rKs,mr,ma,>") 504 (match_operand:SI 1 "general_operand" "mr,ma,KTr,Ksr,>")))] 505 "!TARGET_COLDFIRE" 506{ 507 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 508 return "cmpm%.l %1,%0"; 509 if (REG_P (operands[1]) 510 || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM)) 511 { 512 cc_status.flags |= CC_REVERSED; /*|*/ 513 return "cmp%.l %d0,%d1"; 514 } 515 if (ADDRESS_REG_P (operands[0]) 516 && GET_CODE (operands[1]) == CONST_INT 517 && INTVAL (operands[1]) < 0x8000 518 && INTVAL (operands[1]) >= -0x8000) 519 return "cmp%.w %1,%0"; 520 return "cmp%.l %d1,%d0"; 521}) 522 523(define_insn "*cmpsi_cf" 524 [(set (cc0) 525 (compare (match_operand:SI 0 "nonimmediate_operand" "mrKs,r") 526 (match_operand:SI 1 "general_operand" "r,mrKs")))] 527 "TARGET_COLDFIRE" 528{ 529 if (REG_P (operands[1]) 530 || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM)) 531 { 532 cc_status.flags |= CC_REVERSED; /*|*/ 533 return "cmp%.l %d0,%d1"; 534 } 535 return "cmp%.l %d1,%d0"; 536} 537 [(set_attr "type" "cmp_l")]) 538 539(define_expand "cbranchhi4" 540 [(set (cc0) 541 (compare (match_operand:HI 1 "nonimmediate_operand" "") 542 (match_operand:HI 2 "m68k_subword_comparison_operand" ""))) 543 (set (pc) 544 (if_then_else (match_operator 0 "ordered_comparison_operator" 545 [(cc0) (const_int 0)]) 546 (label_ref (match_operand 3 "")) 547 (pc)))] 548 "" 549 "") 550 551(define_expand "cstorehi4" 552 [(set (cc0) 553 (compare (match_operand:HI 2 "nonimmediate_operand" "") 554 (match_operand:HI 3 "m68k_subword_comparison_operand" ""))) 555 (set (match_operand:QI 0 "register_operand") 556 (match_operator:QI 1 "ordered_comparison_operator" 557 [(cc0) (const_int 0)]))] 558 "" 559 "") 560 561(define_insn "" 562 [(set (cc0) 563 (compare (match_operand:HI 0 "nonimmediate_operand" "rnm,d,n,m,>") 564 (match_operand:HI 1 "general_operand" "d,rnm,m,n,>")))] 565 "!TARGET_COLDFIRE" 566{ 567 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 568 return "cmpm%.w %1,%0"; 569 if ((REG_P (operands[1]) && !ADDRESS_REG_P (operands[1])) 570 || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM)) 571 { 572 cc_status.flags |= CC_REVERSED; /*|*/ 573 return "cmp%.w %d0,%d1"; 574 } 575 return "cmp%.w %d1,%d0"; 576}) 577 578(define_expand "cbranchqi4" 579 [(set (cc0) 580 (compare (match_operand:QI 1 "nonimmediate_operand" "") 581 (match_operand:QI 2 "m68k_subword_comparison_operand" ""))) 582 (set (pc) 583 (if_then_else (match_operator 0 "ordered_comparison_operator" 584 [(cc0) (const_int 0)]) 585 (label_ref (match_operand 3 "")) 586 (pc)))] 587 "" 588 "") 589 590(define_expand "cstoreqi4" 591 [(set (cc0) 592 (compare (match_operand:QI 2 "nonimmediate_operand" "") 593 (match_operand:QI 3 "m68k_subword_comparison_operand" ""))) 594 (set (match_operand:QI 0 "register_operand") 595 (match_operator:QI 1 "ordered_comparison_operator" 596 [(cc0) (const_int 0)]))] 597 "" 598 "") 599 600(define_insn "" 601 [(set (cc0) 602 (compare (match_operand:QI 0 "nonimmediate_operand" "dn,dm,>") 603 (match_operand:QI 1 "general_operand" "dm,nd,>")))] 604 "!TARGET_COLDFIRE" 605{ 606 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 607 return "cmpm%.b %1,%0"; 608 if (REG_P (operands[1]) 609 || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM)) 610 { 611 cc_status.flags |= CC_REVERSED; /*|*/ 612 return "cmp%.b %d0,%d1"; 613 } 614 return "cmp%.b %d1,%d0"; 615}) 616 617(define_expand "cbranch<mode>4" 618 [(set (cc0) 619 (compare (match_operand:FP 1 "register_operand" "") 620 (match_operand:FP 2 "fp_src_operand" ""))) 621 (set (pc) 622 (if_then_else (match_operator 0 "comparison_operator" 623 [(cc0) (const_int 0)]) 624 (label_ref (match_operand 3 "")) 625 (pc)))] 626 "TARGET_HARD_FLOAT" 627 "") 628 629(define_expand "cstore<mode>4" 630 [(set (cc0) 631 (compare (match_operand:FP 2 "register_operand" "") 632 (match_operand:FP 3 "fp_src_operand" ""))) 633 (set (match_operand:QI 0 "register_operand") 634 (match_operator:QI 1 "m68k_cstore_comparison_operator" 635 [(cc0) (const_int 0)]))] 636 "TARGET_HARD_FLOAT && !(TUNE_68060 || TARGET_COLDFIRE_FPU)" 637 "if (TARGET_COLDFIRE && operands[2] != const0_rtx) 638 FAIL;") 639 640(define_insn "*cmp<mode>_68881" 641 [(set (cc0) 642 (compare (match_operand:FP 0 "fp_src_operand" "f,f,<FP:dreg>mF") 643 (match_operand:FP 1 "fp_src_operand" "f,<FP:dreg>mF,f")))] 644 "TARGET_68881 645 && (register_operand (operands[0], <MODE>mode) 646 || register_operand (operands[1], <MODE>mode))" 647 "@ 648 fcmp%.x %1,%0 649 fcmp%.<FP:prec> %f1,%0 650 fcmp%.<FP:prec> %0,%f1" 651 [(set_attr "type" "fcmp")]) 652 653(define_insn "*cmp<mode>_cf" 654 [(set (cc0) 655 (compare (match_operand:FP 0 "fp_src_operand" "f,f,<FP:dreg><Q>U") 656 (match_operand:FP 1 "fp_src_operand" "f,<FP:dreg><Q>U,f")))] 657 "TARGET_COLDFIRE_FPU 658 && (register_operand (operands[0], <MODE>mode) 659 || register_operand (operands[1], <MODE>mode))" 660 "@ 661 fcmp%.d %1,%0 662 fcmp%.<FP:prec> %f1,%0 663 fcmp%.<FP:prec> %0,%f1" 664 [(set_attr "type" "fcmp")]) 665 666;; Recognizers for btst instructions. 667 668;; ColdFire/5200 only allows "<Q>" type addresses when the bit position is 669;; specified as a constant, so we must disable all patterns that may extract 670;; from a MEM at a constant bit position if we can't use this as a constraint. 671 672(define_insn "" 673 [(set 674 (cc0) 675 (compare (zero_extract:SI (match_operand:QI 0 "memory_src_operand" "oS") 676 (const_int 1) 677 (minus:SI (const_int 7) 678 (match_operand:SI 1 "general_operand" "di"))) 679 (const_int 0)))] 680 "!TARGET_COLDFIRE" 681{ 682 return output_btst (operands, operands[1], operands[0], insn, 7); 683}) 684 685;; This is the same as the above pattern except for the constraints. The 'i' 686;; has been deleted. 687 688(define_insn "" 689 [(set 690 (cc0) 691 (compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "o") 692 (const_int 1) 693 (minus:SI (const_int 7) 694 (match_operand:SI 1 "general_operand" "d"))) 695 (const_int 0)))] 696 "TARGET_COLDFIRE" 697{ 698 return output_btst (operands, operands[1], operands[0], insn, 7); 699}) 700 701(define_insn "" 702 [(set 703 (cc0) 704 (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "d") 705 (const_int 1) 706 (minus:SI (const_int 31) 707 (match_operand:SI 1 "general_operand" "di"))) 708 (const_int 0)))] 709 "!(CONST_INT_P (operands[1]) && !IN_RANGE (INTVAL (operands[1]), 0, 31))" 710{ 711 return output_btst (operands, operands[1], operands[0], insn, 31); 712}) 713 714;; The following two patterns are like the previous two 715;; except that they use the fact that bit-number operands 716;; are automatically masked to 3 or 5 bits. 717 718(define_insn "" 719 [(set 720 (cc0) 721 (compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "o") 722 (const_int 1) 723 (minus:SI (const_int 7) 724 (and:SI 725 (match_operand:SI 1 "register_operand" "d") 726 (const_int 7)))) 727 (const_int 0)))] 728 "" 729{ 730 return output_btst (operands, operands[1], operands[0], insn, 7); 731}) 732 733(define_insn "" 734 [(set 735 (cc0) 736 (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "d") 737 (const_int 1) 738 (minus:SI (const_int 31) 739 (and:SI 740 (match_operand:SI 1 "register_operand" "d") 741 (const_int 31)))) 742 (const_int 0)))] 743 "" 744{ 745 return output_btst (operands, operands[1], operands[0], insn, 31); 746}) 747 748;; Nonoffsettable mem refs are ok in this one pattern 749;; since we don't try to adjust them. 750(define_insn "" 751 [(set 752 (cc0) 753 (compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "m") 754 (const_int 1) 755 (match_operand:SI 1 "const_int_operand" "n")) 756 (const_int 0)))] 757 "(unsigned) INTVAL (operands[1]) < 8 && !TARGET_COLDFIRE" 758{ 759 operands[1] = GEN_INT (7 - INTVAL (operands[1])); 760 return output_btst (operands, operands[1], operands[0], insn, 7); 761}) 762 763(define_insn "" 764 [(set 765 (cc0) 766 (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "do") 767 (const_int 1) 768 (match_operand:SI 1 "const_int_operand" "n")) 769 (const_int 0)))] 770 "!TARGET_COLDFIRE 771 && !(REG_P (operands[0]) && !IN_RANGE (INTVAL (operands[1]), 0, 31))" 772{ 773 if (GET_CODE (operands[0]) == MEM) 774 { 775 operands[0] = adjust_address (operands[0], QImode, 776 INTVAL (operands[1]) / 8); 777 operands[1] = GEN_INT (7 - INTVAL (operands[1]) % 8); 778 return output_btst (operands, operands[1], operands[0], insn, 7); 779 } 780 operands[1] = GEN_INT (31 - INTVAL (operands[1])); 781 return output_btst (operands, operands[1], operands[0], insn, 31); 782}) 783 784;; This is the same as the above pattern except for the constraints. 785;; The 'o' has been replaced with 'Q'. 786 787(define_insn "" 788 [(set 789 (cc0) 790 (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "dQ") 791 (const_int 1) 792 (match_operand:SI 1 "const_int_operand" "n")) 793 (const_int 0)))] 794 "TARGET_COLDFIRE 795 && !(REG_P (operands[0]) && !IN_RANGE (INTVAL (operands[1]), 0, 31))" 796{ 797 if (GET_CODE (operands[0]) == MEM) 798 { 799 operands[0] = adjust_address (operands[0], QImode, 800 INTVAL (operands[1]) / 8); 801 operands[1] = GEN_INT (7 - INTVAL (operands[1]) % 8); 802 return output_btst (operands, operands[1], operands[0], insn, 7); 803 } 804 operands[1] = GEN_INT (31 - INTVAL (operands[1])); 805 return output_btst (operands, operands[1], operands[0], insn, 31); 806}) 807 808 809;; move instructions 810 811;; A special case in which it is not desirable 812;; to reload the constant into a data register. 813(define_insn "pushexthisi_const" 814 [(set (match_operand:SI 0 "push_operand" "=m,m,m") 815 (match_operand:SI 1 "const_int_operand" "C0,R,J"))] 816 "INTVAL (operands[1]) >= -0x8000 && INTVAL (operands[1]) < 0x8000" 817 "@ 818 clr%.l %0 819 mov3q%.l %1,%- 820 pea %a1" 821 [(set_attr "type" "clr_l,mov3q_l,pea")]) 822 823;This is never used. 824;(define_insn "swapsi" 825; [(set (match_operand:SI 0 "nonimmediate_operand" "+r") 826; (match_operand:SI 1 "general_operand" "+r")) 827; (set (match_dup 1) (match_dup 0))] 828; "" 829; "exg %1,%0") 830 831;; Special case of fullword move when source is zero for 68000_10. 832;; moveq is faster on the 68000. 833(define_insn "*movsi_const0_68000_10" 834 [(set (match_operand:SI 0 "movsi_const0_operand" "=d,a,g") 835 (const_int 0))] 836 "TUNE_68000_10" 837 "@ 838 moveq #0,%0 839 sub%.l %0,%0 840 clr%.l %0" 841 [(set_attr "type" "moveq_l,alu_l,clr_l") 842 (set_attr "opy" "*,0,*")]) 843 844;; Special case of fullword move when source is zero for 68040_60. 845;; On the '040, 'subl an,an' takes 2 clocks while lea takes only 1 846(define_insn "*movsi_const0_68040_60" 847 [(set (match_operand:SI 0 "movsi_const0_operand" "=a,g") 848 (const_int 0))] 849 "TUNE_68040_60" 850{ 851 if (which_alternative == 0) 852 return MOTOROLA ? "lea 0.w,%0" : "lea 0:w,%0"; 853 else if (which_alternative == 1) 854 return "clr%.l %0"; 855 else 856 { 857 gcc_unreachable (); 858 return ""; 859 } 860} 861 [(set_attr "type" "lea,clr_l")]) 862 863;; Special case of fullword move when source is zero. 864(define_insn "*movsi_const0" 865 [(set (match_operand:SI 0 "movsi_const0_operand" "=a,g") 866 (const_int 0))] 867 "!(TUNE_68000_10 || TUNE_68040_60)" 868 "@ 869 sub%.l %0,%0 870 clr%.l %0" 871 [(set_attr "type" "alu_l,clr_l") 872 (set_attr "opy" "0,*")]) 873 874;; General case of fullword move. 875;; 876;; This is the main "hook" for PIC code. When generating 877;; PIC, movsi is responsible for determining when the source address 878;; needs PIC relocation and appropriately calling legitimize_pic_address 879;; to perform the actual relocation. 880;; 881;; In both the PIC and non-PIC cases the patterns generated will 882;; matched by the next define_insn. 883(define_expand "movsi" 884 [(set (match_operand:SI 0 "" "") 885 (match_operand:SI 1 "" ""))] 886 "" 887{ 888 rtx tmp, base, offset; 889 890 /* Recognize the case where operand[1] is a reference to thread-local 891 data and load its address to a register. */ 892 if (!TARGET_PCREL && m68k_tls_reference_p (operands[1], false)) 893 { 894 rtx tmp = operands[1]; 895 rtx addend = NULL; 896 897 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS) 898 { 899 addend = XEXP (XEXP (tmp, 0), 1); 900 tmp = XEXP (XEXP (tmp, 0), 0); 901 } 902 903 gcc_assert (GET_CODE (tmp) == SYMBOL_REF); 904 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0); 905 906 tmp = m68k_legitimize_tls_address (tmp); 907 908 if (addend) 909 { 910 if (!REG_P (tmp)) 911 { 912 rtx reg; 913 914 reg = gen_reg_rtx (Pmode); 915 emit_move_insn (reg, tmp); 916 tmp = reg; 917 } 918 919 tmp = gen_rtx_PLUS (SImode, tmp, addend); 920 } 921 922 operands[1] = tmp; 923 } 924 else if (flag_pic && !TARGET_PCREL && symbolic_operand (operands[1], SImode)) 925 { 926 /* The source is an address which requires PIC relocation. 927 Call legitimize_pic_address with the source, mode, and a relocation 928 register (a new pseudo, or the final destination if reload_in_progress 929 is set). Then fall through normally */ 930 rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode); 931 operands[1] = legitimize_pic_address (operands[1], SImode, temp); 932 } 933 else if (flag_pic && TARGET_PCREL && ! reload_in_progress) 934 { 935 /* Don't allow writes to memory except via a register; 936 the m68k doesn't consider PC-relative addresses to be writable. */ 937 if (symbolic_operand (operands[0], SImode)) 938 operands[0] = force_reg (SImode, XEXP (operands[0], 0)); 939 else if (GET_CODE (operands[0]) == MEM 940 && symbolic_operand (XEXP (operands[0], 0), SImode)) 941 operands[0] = gen_rtx_MEM (SImode, 942 force_reg (SImode, XEXP (operands[0], 0))); 943 } 944 if (M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P) 945 { 946 split_const (operands[1], &base, &offset); 947 if (GET_CODE (base) == SYMBOL_REF 948 && !offset_within_block_p (base, INTVAL (offset))) 949 { 950 tmp = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (SImode); 951 emit_move_insn (tmp, base); 952 emit_insn (gen_addsi3 (operands[0], tmp, offset)); 953 DONE; 954 } 955 } 956}) 957 958;; General case of fullword move. 959(define_insn "*movsi_m68k" 960 ;; Notes: make sure no alternative allows g vs g. 961 ;; We don't allow f-regs since fixed point cannot go in them. 962 [(set (match_operand:SI 0 "nonimmediate_operand" "=g,d,a<") 963 (match_operand:SI 1 "general_src_operand" "damSnT,n,i"))] 964 "!TARGET_COLDFIRE && reload_completed" 965{ 966 return output_move_simode (operands); 967}) 968 969;; Before reload is completed the register constraints 970;; force integer constants in range for a moveq to be reloaded 971;; if they are headed for memory. 972(define_insn "*movsi_m68k2" 973 [(set (match_operand:SI 0 "nonimmediate_operand" "=g,d,a<") 974 (match_operand:SI 1 "general_src_operand" "damSKT,n,i"))] 975 976 "!TARGET_COLDFIRE" 977{ 978 return output_move_simode (operands); 979}) 980 981;; ColdFire move instructions can have at most one operand of mode >= 6. 982(define_insn "*movsi_cf" 983 [(set (match_operand:SI 0 "nonimmediate_operand" "=g,d, d, d, d, d, a,Ap, a, r<Q>,g, U") 984 (match_operand:SI 1 "general_operand" " R,CQ,CW,CZ,CS,Ci,J,J Cs,Cs, g, Rr<Q>,U"))] 985 "TARGET_COLDFIRE" 986{ 987 switch (which_alternative) 988 { 989 case 0: 990 return "mov3q%.l %1,%0"; 991 992 case 1: 993 return "moveq %1,%0"; 994 995 case 2: 996 { 997 unsigned u = INTVAL (operands[1]); 998 999 operands[1] = GEN_INT ((u << 16) | (u >> 16)); /*|*/ 1000 return "moveq %1,%0\n\tswap %0"; 1001 } 1002 1003 case 3: 1004 return "mvz%.w %1,%0"; 1005 1006 case 4: 1007 return "mvs%.w %1,%0"; 1008 1009 case 5: 1010 return "move%.l %1,%0"; 1011 1012 case 6: 1013 return "move%.w %1,%0"; 1014 1015 case 7: 1016 return "pea %a1"; 1017 1018 case 8: 1019 return "lea %a1,%0"; 1020 1021 case 9: 1022 case 10: 1023 case 11: 1024 return "move%.l %1,%0"; 1025 1026 default: 1027 gcc_unreachable (); 1028 return ""; 1029 } 1030} 1031 [(set_attr "type" "mov3q_l,moveq_l,*,mvsz,mvsz,move_l,move,pea,lea,move_l,move_l,move_l")]) 1032 1033;; Special case of fullword move, where we need to get a non-GOT PIC 1034;; reference into an address register. 1035(define_insn "" 1036 [(set (match_operand:SI 0 "nonimmediate_operand" "=a<") 1037 (match_operand:SI 1 "pcrel_address" ""))] 1038 "TARGET_PCREL" 1039{ 1040 if (push_operand (operands[0], SImode)) 1041 return "pea %a1"; 1042 return "lea %a1,%0"; 1043}) 1044 1045(define_expand "movhi" 1046 [(set (match_operand:HI 0 "nonimmediate_operand" "") 1047 (match_operand:HI 1 "general_operand" ""))] 1048 "" 1049 "") 1050 1051(define_insn "" 1052 [(set (match_operand:HI 0 "nonimmediate_operand" "=g") 1053 (match_operand:HI 1 "general_src_operand" "gS"))] 1054 "!TARGET_COLDFIRE" 1055 "* return output_move_himode (operands);") 1056 1057(define_insn "" 1058 [(set (match_operand:HI 0 "nonimmediate_operand" "=r<Q>,g,U") 1059 (match_operand:HI 1 "general_operand" "g,r<Q>,U"))] 1060 "TARGET_COLDFIRE" 1061 "* return output_move_himode (operands);") 1062 1063(define_expand "movstricthi" 1064 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "")) 1065 (match_operand:HI 1 "general_src_operand" ""))] 1066 "" 1067 "") 1068 1069(define_insn "" 1070 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+dm")) 1071 (match_operand:HI 1 "general_src_operand" "rmSn"))] 1072 "!TARGET_COLDFIRE" 1073 "* return output_move_stricthi (operands);") 1074 1075(define_insn "" 1076 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+d,m")) 1077 (match_operand:HI 1 "general_src_operand" "rmn,r"))] 1078 "TARGET_COLDFIRE" 1079 "* return output_move_stricthi (operands);") 1080 1081(define_expand "movqi" 1082 [(set (match_operand:QI 0 "nonimmediate_operand" "") 1083 (match_operand:QI 1 "general_src_operand" ""))] 1084 "" 1085 "") 1086 1087(define_insn "" 1088 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,*a,m") 1089 (match_operand:QI 1 "general_src_operand" "dmSi*a,di*a,dmSi"))] 1090 "!TARGET_COLDFIRE" 1091 "* return output_move_qimode (operands);") 1092 1093(define_insn "" 1094 [(set (match_operand:QI 0 "nonimmediate_operand" "=d<Q>,dm,U,d*a") 1095 (match_operand:QI 1 "general_src_operand" "dmi,d<Q>,U,di*a"))] 1096 "TARGET_COLDFIRE" 1097 "* return output_move_qimode (operands);") 1098 1099(define_expand "movstrictqi" 1100 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "")) 1101 (match_operand:QI 1 "general_src_operand" ""))] 1102 "" 1103 "") 1104 1105(define_insn "" 1106 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+dm")) 1107 (match_operand:QI 1 "general_src_operand" "dmSn"))] 1108 "!TARGET_COLDFIRE" 1109 "* return output_move_strictqi (operands);") 1110 1111(define_insn "*movstrictqi_cf" 1112 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+d, Ac, d,m")) 1113 (match_operand:QI 1 "general_src_operand" "C0,C0, dmn,d"))] 1114 "TARGET_COLDFIRE" 1115 "@ 1116 clr%.b %0 1117 clr%.b %0 1118 move%.b %1,%0 1119 move%.b %1,%0" 1120 [(set_attr "type" "clr,clr,move,move")]) 1121 1122(define_expand "pushqi1" 1123 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -2))) 1124 (set (mem:QI (plus:SI (reg:SI SP_REG) (const_int 1))) 1125 (match_operand:QI 0 "general_operand" ""))] 1126 "!TARGET_COLDFIRE" 1127 "") 1128 1129(define_expand "reload_insf" 1130 [(set (match_operand:SF 0 "nonimmediate_operand" "=f") 1131 (match_operand:SF 1 "general_operand" "mf")) 1132 (clobber (match_operand:SI 2 "register_operand" "=&a"))] 1133 "TARGET_COLDFIRE_FPU" 1134{ 1135 if (emit_move_sequence (operands, SFmode, operands[2])) 1136 DONE; 1137 1138 /* We don't want the clobber emitted, so handle this ourselves. */ 1139 emit_insn (gen_rtx_SET (operands[0], operands[1])); 1140 DONE; 1141}) 1142 1143(define_expand "reload_outsf" 1144 [(set (match_operand:SF 0 "general_operand" "") 1145 (match_operand:SF 1 "register_operand" "f")) 1146 (clobber (match_operand:SI 2 "register_operand" "=&a"))] 1147 "TARGET_COLDFIRE_FPU" 1148{ 1149 if (emit_move_sequence (operands, SFmode, operands[2])) 1150 DONE; 1151 1152 /* We don't want the clobber emitted, so handle this ourselves. */ 1153 emit_insn (gen_rtx_SET (operands[0], operands[1])); 1154 DONE; 1155}) 1156 1157(define_expand "movsf" 1158 [(set (match_operand:SF 0 "nonimmediate_operand" "") 1159 (match_operand:SF 1 "general_operand" ""))] 1160 "" 1161 "") 1162 1163(define_insn "" 1164 [(set (match_operand:SF 0 "nonimmediate_operand" "=rmf") 1165 (match_operand:SF 1 "general_operand" "rmfF"))] 1166 "!TARGET_COLDFIRE" 1167{ 1168 if (FP_REG_P (operands[0])) 1169 { 1170 if (FP_REG_P (operands[1])) 1171 return "f%$move%.x %1,%0"; 1172 else if (ADDRESS_REG_P (operands[1])) 1173 return "move%.l %1,%-\;f%$move%.s %+,%0"; 1174 else if (GET_CODE (operands[1]) == CONST_DOUBLE) 1175 return output_move_const_single (operands); 1176 return "f%$move%.s %f1,%0"; 1177 } 1178 if (FP_REG_P (operands[1])) 1179 { 1180 if (ADDRESS_REG_P (operands[0])) 1181 return "fmove%.s %1,%-\;move%.l %+,%0"; 1182 return "fmove%.s %f1,%0"; 1183 } 1184 if (operands[1] == CONST0_RTX (SFmode) 1185 /* clr insns on 68000 read before writing. */ 1186 && ((TARGET_68010 || TARGET_COLDFIRE) 1187 || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))) 1188 { 1189 if (ADDRESS_REG_P (operands[0])) 1190 { 1191 /* On the '040, 'subl an,an' takes 2 clocks while lea takes only 1 */ 1192 if (TUNE_68040_60) 1193 return MOTOROLA ? "lea 0.w,%0" : "lea 0:w,%0"; 1194 else 1195 return "sub%.l %0,%0"; 1196 } 1197 /* moveq is faster on the 68000. */ 1198 if (DATA_REG_P (operands[0]) && TUNE_68000_10) 1199 return "moveq #0,%0"; 1200 return "clr%.l %0"; 1201 } 1202 return "move%.l %1,%0"; 1203}) 1204 1205(define_insn "movsf_cf_soft" 1206 [(set (match_operand:SF 0 "nonimmediate_operand" "=r<Q>,g,U") 1207 (match_operand:SF 1 "general_operand" "g,r<Q>,U"))] 1208 "TARGET_COLDFIRE && !TARGET_COLDFIRE_FPU" 1209 "move%.l %1,%0" 1210 [(set_attr "type" "move_l")]) 1211 1212;; SFmode MEMs are restricted to modes 2-4 if TARGET_COLDFIRE_FPU. 1213;; The move instructions can handle all combinations. 1214(define_insn "movsf_cf_hard" 1215 [(set (match_operand:SF 0 "nonimmediate_operand" "=r<Q>U, f, f,mr,f,r<Q>,f 1216,m") 1217 (match_operand:SF 1 "general_operand" " f, r<Q>U,f,rm,F,F, m 1218,f"))] 1219 "TARGET_COLDFIRE_FPU" 1220{ 1221 if (which_alternative == 4 || which_alternative == 5) { 1222 rtx xoperands[2]; 1223 long l; 1224 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (operands[1]), l); 1225 xoperands[0] = operands[0]; 1226 xoperands[1] = GEN_INT (l); 1227 if (which_alternative == 5) { 1228 if (l == 0) { 1229 if (ADDRESS_REG_P (xoperands[0])) 1230 output_asm_insn ("sub%.l %0,%0", xoperands); 1231 else 1232 output_asm_insn ("clr%.l %0", xoperands); 1233 } else 1234 if (GET_CODE (operands[0]) == MEM 1235 && symbolic_operand (XEXP (operands[0], 0), SImode)) 1236 output_asm_insn ("move%.l %1,%-;move%.l %+,%0", xoperands); 1237 else 1238 output_asm_insn ("move%.l %1,%0", xoperands); 1239 return ""; 1240 } 1241 if (l != 0) 1242 output_asm_insn ("move%.l %1,%-;fsmove%.s %+,%0", xoperands); 1243 else 1244 output_asm_insn ("clr%.l %-;fsmove%.s %+,%0", xoperands); 1245 return ""; 1246 } 1247 if (FP_REG_P (operands[0])) 1248 { 1249 if (ADDRESS_REG_P (operands[1])) 1250 return "move%.l %1,%-;fsmove%.s %+,%0"; 1251 if (FP_REG_P (operands[1])) 1252 return "fsmove%.d %1,%0"; 1253 return "fsmove%.s %f1,%0"; 1254 } 1255 if (FP_REG_P (operands[1])) 1256 { 1257 if (ADDRESS_REG_P (operands[0])) 1258 return "fmove%.s %1,%-;move%.l %+,%0"; 1259 return "fmove%.s %f1,%0"; 1260 } 1261 if (operands[1] == CONST0_RTX (SFmode)) 1262 { 1263 if (ADDRESS_REG_P (operands[0])) 1264 return "sub%.l %0,%0"; 1265 return "clr%.l %0"; 1266 } 1267 return "move%.l %1,%0"; 1268}) 1269 1270(define_expand "reload_indf" 1271 [(set (match_operand:DF 0 "nonimmediate_operand" "=f") 1272 (match_operand:DF 1 "general_operand" "mf")) 1273 (clobber (match_operand:SI 2 "register_operand" "=&a"))] 1274 "TARGET_COLDFIRE_FPU" 1275{ 1276 if (emit_move_sequence (operands, DFmode, operands[2])) 1277 DONE; 1278 1279 /* We don't want the clobber emitted, so handle this ourselves. */ 1280 emit_insn (gen_rtx_SET (operands[0], operands[1])); 1281 DONE; 1282}) 1283 1284(define_expand "reload_outdf" 1285 [(set (match_operand:DF 0 "general_operand" "") 1286 (match_operand:DF 1 "register_operand" "f")) 1287 (clobber (match_operand:SI 2 "register_operand" "=&a"))] 1288 "TARGET_COLDFIRE_FPU" 1289{ 1290 if (emit_move_sequence (operands, DFmode, operands[2])) 1291 DONE; 1292 1293 /* We don't want the clobber emitted, so handle this ourselves. */ 1294 emit_insn (gen_rtx_SET (operands[0], operands[1])); 1295 DONE; 1296}) 1297 1298(define_expand "movdf" 1299 [(set (match_operand:DF 0 "nonimmediate_operand" "") 1300 (match_operand:DF 1 "general_operand" ""))] 1301 "" 1302{ 1303 if (TARGET_COLDFIRE_FPU) 1304 if (emit_move_sequence (operands, DFmode, 0)) 1305 DONE; 1306}) 1307 1308(define_insn "" 1309 [(set (match_operand:DF 0 "nonimmediate_operand" "=rm,rf,rf,&rof<>") 1310 (match_operand:DF 1 "general_operand" "*rf,m,0,*rofE<>"))] 1311; [(set (match_operand:DF 0 "nonimmediate_operand" "=rm,&rf,&rof<>") 1312; (match_operand:DF 1 "general_operand" "rf,m,rofF<>"))] 1313 "!TARGET_COLDFIRE" 1314{ 1315 if (FP_REG_P (operands[0])) 1316 { 1317 if (FP_REG_P (operands[1])) 1318 return "f%&move%.x %1,%0"; 1319 if (REG_P (operands[1])) 1320 { 1321 rtx xoperands[2]; 1322 xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1); 1323 output_asm_insn ("move%.l %1,%-", xoperands); 1324 output_asm_insn ("move%.l %1,%-", operands); 1325 return "f%&move%.d %+,%0"; 1326 } 1327 if (GET_CODE (operands[1]) == CONST_DOUBLE) 1328 return output_move_const_double (operands); 1329 return "f%&move%.d %f1,%0"; 1330 } 1331 else if (FP_REG_P (operands[1])) 1332 { 1333 if (REG_P (operands[0])) 1334 { 1335 output_asm_insn ("fmove%.d %f1,%-\;move%.l %+,%0", operands); 1336 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); 1337 return "move%.l %+,%0"; 1338 } 1339 else 1340 return "fmove%.d %f1,%0"; 1341 } 1342 return output_move_double (operands); 1343}) 1344 1345(define_insn_and_split "movdf_cf_soft" 1346 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,g") 1347 (match_operand:DF 1 "general_operand" "g,r"))] 1348 "TARGET_COLDFIRE && !TARGET_COLDFIRE_FPU" 1349 "#" 1350 "&& reload_completed" 1351 [(const_int 0)] 1352{ 1353 m68k_emit_move_double (operands); 1354 DONE; 1355}) 1356 1357(define_insn "movdf_cf_hard" 1358 [(set (match_operand:DF 0 "nonimmediate_operand" "=f, <Q>U,r,f,r,r,m,f") 1359 (match_operand:DF 1 "general_operand" " f<Q>U,f, f,r,r,m,r,E"))] 1360 "TARGET_COLDFIRE_FPU" 1361{ 1362 rtx xoperands[3]; 1363 long l[2]; 1364 1365 switch (which_alternative) 1366 { 1367 default: 1368 return "fdmove%.d %1,%0"; 1369 case 1: 1370 return "fmove%.d %1,%0"; 1371 case 2: 1372 return "fmove%.d %1,%-;move%.l %+,%0;move%.l %+,%R0"; 1373 case 3: 1374 return "move%.l %R1,%-;move%.l %1,%-;fdmove%.d %+,%0"; 1375 case 4: case 5: case 6: 1376 return output_move_double (operands); 1377 case 7: 1378 REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (operands[1]), l); 1379 xoperands[0] = operands[0]; 1380 xoperands[1] = GEN_INT (l[0]); 1381 xoperands[2] = GEN_INT (l[1]); 1382 if (operands[1] == CONST0_RTX (DFmode)) 1383 output_asm_insn ("clr%.l %-;clr%.l %-;fdmove%.d %+,%0", 1384 xoperands); 1385 else 1386 if (l[1] == 0) 1387 output_asm_insn ("clr%.l %-;move%.l %1,%-;fdmove%.d %+,%0", 1388 xoperands); 1389 else 1390 output_asm_insn ("move%.l %2,%-;move%.l %1,%-;fdmove%.d %+,%0", 1391 xoperands); 1392 return ""; 1393 } 1394}) 1395 1396;; ??? The XFmode patterns are schizophrenic about whether constants are 1397;; allowed. Most but not all have predicates and constraint that disallow 1398;; constants. Most but not all have output templates that handle constants. 1399;; See also TARGET_LEGITIMATE_CONSTANT_P. 1400 1401(define_expand "movxf" 1402 [(set (match_operand:XF 0 "nonimmediate_operand" "") 1403 (match_operand:XF 1 "general_operand" ""))] 1404 "" 1405{ 1406 /* We can't rewrite operands during reload. */ 1407 if (! reload_in_progress) 1408 { 1409 if (CONSTANT_P (operands[1])) 1410 { 1411 operands[1] = force_const_mem (XFmode, operands[1]); 1412 if (! memory_address_p (XFmode, XEXP (operands[1], 0))) 1413 operands[1] = adjust_address (operands[1], XFmode, 0); 1414 } 1415 if (flag_pic && TARGET_PCREL) 1416 { 1417 /* Don't allow writes to memory except via a register; the 1418 m68k doesn't consider PC-relative addresses to be writable. */ 1419 if (GET_CODE (operands[0]) == MEM 1420 && symbolic_operand (XEXP (operands[0], 0), SImode)) 1421 operands[0] = gen_rtx_MEM (XFmode, 1422 force_reg (SImode, XEXP (operands[0], 0))); 1423 } 1424 } 1425}) 1426 1427(define_insn "" 1428 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,!r,!f,!r,m,!r") 1429 (match_operand:XF 1 "nonimmediate_operand" "m,f,f,f,r,!r,!r,m"))] 1430 "TARGET_68881" 1431{ 1432 if (FP_REG_P (operands[0])) 1433 { 1434 if (FP_REG_P (operands[1])) 1435 return "fmove%.x %1,%0"; 1436 if (REG_P (operands[1])) 1437 { 1438 rtx xoperands[2]; 1439 xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 2); 1440 output_asm_insn ("move%.l %1,%-", xoperands); 1441 xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1); 1442 output_asm_insn ("move%.l %1,%-", xoperands); 1443 output_asm_insn ("move%.l %1,%-", operands); 1444 return "fmove%.x %+,%0"; 1445 } 1446 if (GET_CODE (operands[1]) == CONST_DOUBLE) 1447 return "fmove%.x %1,%0"; 1448 return "fmove%.x %f1,%0"; 1449 } 1450 if (FP_REG_P (operands[1])) 1451 { 1452 if (REG_P (operands[0])) 1453 { 1454 output_asm_insn ("fmove%.x %f1,%-\;move%.l %+,%0", operands); 1455 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); 1456 output_asm_insn ("move%.l %+,%0", operands); 1457 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); 1458 return "move%.l %+,%0"; 1459 } 1460 /* Must be memory destination. */ 1461 return "fmove%.x %f1,%0"; 1462 } 1463 return output_move_double (operands); 1464}) 1465 1466(define_insn "" 1467 [(set (match_operand:XF 0 "nonimmediate_operand" "=rm,rf,&rof<>") 1468 (match_operand:XF 1 "nonimmediate_operand" "rf,m,rof<>"))] 1469 "! TARGET_68881 && ! TARGET_COLDFIRE" 1470{ 1471 if (FP_REG_P (operands[0])) 1472 { 1473 if (FP_REG_P (operands[1])) 1474 return "fmove%.x %1,%0"; 1475 if (REG_P (operands[1])) 1476 { 1477 rtx xoperands[2]; 1478 xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 2); 1479 output_asm_insn ("move%.l %1,%-", xoperands); 1480 xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1); 1481 output_asm_insn ("move%.l %1,%-", xoperands); 1482 output_asm_insn ("move%.l %1,%-", operands); 1483 return "fmove%.x %+,%0"; 1484 } 1485 if (GET_CODE (operands[1]) == CONST_DOUBLE) 1486 return "fmove%.x %1,%0"; 1487 return "fmove%.x %f1,%0"; 1488 } 1489 if (FP_REG_P (operands[1])) 1490 { 1491 if (REG_P (operands[0])) 1492 { 1493 output_asm_insn ("fmove%.x %f1,%-\;move%.l %+,%0", operands); 1494 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); 1495 output_asm_insn ("move%.l %+,%0", operands); 1496 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); 1497 return "move%.l %+,%0"; 1498 } 1499 else 1500 return "fmove%.x %f1,%0"; 1501 } 1502 return output_move_double (operands); 1503}) 1504 1505(define_insn "" 1506 [(set (match_operand:XF 0 "nonimmediate_operand" "=r,g") 1507 (match_operand:XF 1 "nonimmediate_operand" "g,r"))] 1508 "! TARGET_68881 && TARGET_COLDFIRE" 1509 "* return output_move_double (operands);") 1510 1511(define_expand "movdi" 1512 ;; Let's see if it really still needs to handle fp regs, and, if so, why. 1513 [(set (match_operand:DI 0 "nonimmediate_operand" "") 1514 (match_operand:DI 1 "general_operand" ""))] 1515 "" 1516 "") 1517 1518;; movdi can apply to fp regs in some cases 1519(define_insn "" 1520 ;; Let's see if it really still needs to handle fp regs, and, if so, why. 1521 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r,&ro<>") 1522 (match_operand:DI 1 "general_operand" "rF,m,roi<>F"))] 1523; [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,&r,&ro<>,!&rm,!&f") 1524; (match_operand:DI 1 "general_operand" "r,m,roi<>,fF"))] 1525; [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,&rf,&ro<>,!&rm,!&f") 1526; (match_operand:DI 1 "general_operand" "r,m,roi<>,fF,rfF"))] 1527 "!TARGET_COLDFIRE" 1528{ 1529 if (FP_REG_P (operands[0])) 1530 { 1531 if (FP_REG_P (operands[1])) 1532 return "fmove%.x %1,%0"; 1533 if (REG_P (operands[1])) 1534 { 1535 rtx xoperands[2]; 1536 xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1); 1537 output_asm_insn ("move%.l %1,%-", xoperands); 1538 output_asm_insn ("move%.l %1,%-", operands); 1539 return "fmove%.d %+,%0"; 1540 } 1541 if (GET_CODE (operands[1]) == CONST_DOUBLE) 1542 return output_move_const_double (operands); 1543 return "fmove%.d %f1,%0"; 1544 } 1545 else if (FP_REG_P (operands[1])) 1546 { 1547 if (REG_P (operands[0])) 1548 { 1549 output_asm_insn ("fmove%.d %f1,%-\;move%.l %+,%0", operands); 1550 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); 1551 return "move%.l %+,%0"; 1552 } 1553 else 1554 return "fmove%.d %f1,%0"; 1555 } 1556 return output_move_double (operands); 1557}) 1558 1559(define_insn "" 1560 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,g") 1561 (match_operand:DI 1 "general_operand" "g,r"))] 1562 "TARGET_COLDFIRE" 1563 "* return output_move_double (operands);") 1564 1565;; Thus goes after the move instructions 1566;; because the move instructions are better (require no spilling) 1567;; when they can apply. It goes before the add/sub insns 1568;; so we will prefer it to them. 1569 1570(define_insn "pushasi" 1571 [(set (match_operand:SI 0 "push_operand" "=m") 1572 (match_operand:SI 1 "address_operand" "p"))] 1573 "" 1574 "pea %a1" 1575 [(set_attr "type" "pea")]) 1576 1577;; truncation instructions 1578(define_insn "truncsiqi2" 1579 [(set (match_operand:QI 0 "nonimmediate_operand" "=dm,d") 1580 (truncate:QI 1581 (match_operand:SI 1 "general_src_operand" "doJS,i")))] 1582 "!TARGET_COLDFIRE" 1583{ 1584 if (GET_CODE (operands[0]) == REG) 1585 { 1586 /* Must clear condition codes, since the move.l bases them on 1587 the entire 32 bits, not just the desired 8 bits. */ 1588 CC_STATUS_INIT; 1589 return "move%.l %1,%0"; 1590 } 1591 if (GET_CODE (operands[1]) == MEM) 1592 operands[1] = adjust_address (operands[1], QImode, 3); 1593 return "move%.b %1,%0"; 1594}) 1595 1596(define_insn "trunchiqi2" 1597 [(set (match_operand:QI 0 "nonimmediate_operand" "=dm,d") 1598 (truncate:QI 1599 (match_operand:HI 1 "general_src_operand" "doJS,i")))] 1600 "!TARGET_COLDFIRE" 1601{ 1602 if (GET_CODE (operands[0]) == REG 1603 && (GET_CODE (operands[1]) == MEM 1604 || GET_CODE (operands[1]) == CONST_INT)) 1605 { 1606 /* Must clear condition codes, since the move.w bases them on 1607 the entire 16 bits, not just the desired 8 bits. */ 1608 CC_STATUS_INIT; 1609 return "move%.w %1,%0"; 1610 } 1611 if (GET_CODE (operands[0]) == REG) 1612 { 1613 /* Must clear condition codes, since the move.l bases them on 1614 the entire 32 bits, not just the desired 8 bits. */ 1615 CC_STATUS_INIT; 1616 return "move%.l %1,%0"; 1617 } 1618 if (GET_CODE (operands[1]) == MEM) 1619 operands[1] = adjust_address (operands[1], QImode, 1); 1620 return "move%.b %1,%0"; 1621}) 1622 1623(define_insn "truncsihi2" 1624 [(set (match_operand:HI 0 "nonimmediate_operand" "=dm,d") 1625 (truncate:HI 1626 (match_operand:SI 1 "general_src_operand" "roJS,i")))] 1627 "!TARGET_COLDFIRE" 1628{ 1629 if (GET_CODE (operands[0]) == REG) 1630 { 1631 /* Must clear condition codes, since the move.l bases them on 1632 the entire 32 bits, not just the desired 8 bits. */ 1633 CC_STATUS_INIT; 1634 return "move%.l %1,%0"; 1635 } 1636 if (GET_CODE (operands[1]) == MEM) 1637 operands[1] = adjust_address (operands[1], QImode, 2); 1638 return "move%.w %1,%0"; 1639}) 1640 1641;; zero extension instructions 1642 1643;; two special patterns to match various post_inc/pre_dec patterns 1644(define_insn_and_split "*zero_extend_inc" 1645 [(set (match_operand 0 "post_inc_operand" "") 1646 (zero_extend (match_operand 1 "register_operand" "")))] 1647 "GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT && 1648 GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT && 1649 GET_MODE_SIZE (GET_MODE (operands[0])) == GET_MODE_SIZE (GET_MODE (operands[1])) * 2" 1650 "#" 1651 "" 1652 [(set (match_dup 0) 1653 (const_int 0)) 1654 (set (match_dup 0) 1655 (match_dup 1))] 1656{ 1657 operands[0] = adjust_address (operands[0], GET_MODE (operands[1]), 0); 1658}) 1659 1660(define_insn_and_split "*zero_extend_dec" 1661 [(set (match_operand 0 "pre_dec_operand" "") 1662 (zero_extend (match_operand 1 "register_operand" "")))] 1663 "(GET_MODE (operands[0]) != HImode || XEXP (XEXP (operands[0], 0), 0) != stack_pointer_rtx) && 1664 GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT && 1665 GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT && 1666 GET_MODE_SIZE (GET_MODE (operands[0])) == GET_MODE_SIZE (GET_MODE (operands[1])) * 2" 1667 "#" 1668 "" 1669 [(set (match_dup 0) 1670 (match_dup 1)) 1671 (set (match_dup 0) 1672 (const_int 0))] 1673{ 1674 operands[0] = adjust_address (operands[0], GET_MODE (operands[1]), 0); 1675}) 1676 1677(define_insn_and_split "zero_extendqidi2" 1678 [(set (match_operand:DI 0 "register_operand" "") 1679 (zero_extend:DI (match_operand:QI 1 "nonimmediate_src_operand" "")))] 1680 "" 1681 "#" 1682 "" 1683 [(set (match_dup 2) 1684 (zero_extend:SI (match_dup 1))) 1685 (set (match_dup 3) 1686 (const_int 0))] 1687{ 1688 operands[2] = gen_lowpart (SImode, operands[0]); 1689 operands[3] = gen_highpart (SImode, operands[0]); 1690}) 1691 1692(define_insn_and_split "zero_extendhidi2" 1693 [(set (match_operand:DI 0 "register_operand" "") 1694 (zero_extend:DI (match_operand:HI 1 "nonimmediate_src_operand" "")))] 1695 "" 1696 "#" 1697 "" 1698 [(set (match_dup 2) 1699 (zero_extend:SI (match_dup 1))) 1700 (set (match_dup 3) 1701 (const_int 0))] 1702{ 1703 operands[2] = gen_lowpart (SImode, operands[0]); 1704 operands[3] = gen_highpart (SImode, operands[0]); 1705}) 1706 1707(define_expand "zero_extendsidi2" 1708 [(set (match_operand:DI 0 "nonimmediate_operand" "") 1709 (zero_extend:DI (match_operand:SI 1 "nonimmediate_src_operand" "")))] 1710 "" 1711{ 1712 if (GET_CODE (operands[0]) == MEM 1713 && GET_CODE (operands[1]) == MEM) 1714 operands[1] = force_reg (SImode, operands[1]); 1715}) 1716 1717(define_insn_and_split "*zero_extendsidi2" 1718 [(set (match_operand:DI 0 "nonimmediate_operand" "") 1719 (zero_extend:DI (match_operand:SI 1 "nonimmediate_src_operand" "")))] 1720 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" 1721 "#" 1722 "" 1723 [(set (match_dup 2) 1724 (match_dup 1)) 1725 (set (match_dup 3) 1726 (const_int 0))] 1727{ 1728 operands[2] = gen_lowpart (SImode, operands[0]); 1729 operands[3] = gen_highpart (SImode, operands[0]); 1730}) 1731 1732(define_insn "*zero_extendhisi2_cf" 1733 [(set (match_operand:SI 0 "register_operand" "=d") 1734 (zero_extend:SI (match_operand:HI 1 "nonimmediate_src_operand" "rmS")))] 1735 "ISA_HAS_MVS_MVZ" 1736 "mvz%.w %1,%0" 1737 [(set_attr "type" "mvsz")]) 1738 1739(define_insn "zero_extendhisi2" 1740 [(set (match_operand:SI 0 "register_operand" "=d") 1741 (zero_extend:SI (match_operand:HI 1 "nonimmediate_src_operand" "rmS")))] 1742 "" 1743 "#") 1744 1745(define_expand "zero_extendqihi2" 1746 [(set (match_operand:HI 0 "register_operand" "") 1747 (zero_extend:HI (match_operand:QI 1 "nonimmediate_src_operand" "")))] 1748 "!TARGET_COLDFIRE" 1749 "") 1750 1751(define_insn "*zero_extendqihi2" 1752 [(set (match_operand:HI 0 "register_operand" "=d") 1753 (zero_extend:HI (match_operand:QI 1 "nonimmediate_src_operand" "dmS")))] 1754 "!TARGET_COLDFIRE" 1755 "#") 1756 1757(define_insn "*zero_extendqisi2_cfv4" 1758 [(set (match_operand:SI 0 "register_operand" "=d") 1759 (zero_extend:SI (match_operand:QI 1 "nonimmediate_src_operand" "dmS")))] 1760 "ISA_HAS_MVS_MVZ" 1761 "mvz%.b %1,%0" 1762 [(set_attr "type" "mvsz")]) 1763 1764(define_insn "zero_extendqisi2" 1765 [(set (match_operand:SI 0 "register_operand" "=d") 1766 (zero_extend:SI (match_operand:QI 1 "nonimmediate_src_operand" "dmS")))] 1767 "" 1768 "#") 1769 1770;; these two pattern split everything else which isn't matched by 1771;; something else above 1772(define_split 1773 [(set (match_operand 0 "register_operand" "") 1774 (zero_extend (match_operand 1 "nonimmediate_src_operand" "")))] 1775 "!ISA_HAS_MVS_MVZ 1776 && reload_completed 1777 && reg_mentioned_p (operands[0], operands[1])" 1778 [(set (strict_low_part (match_dup 2)) 1779 (match_dup 1)) 1780 (set (match_dup 0) 1781 (match_op_dup 4 [(match_dup 0) (match_dup 3)]))] 1782{ 1783 operands[2] = gen_lowpart (GET_MODE (operands[1]), operands[0]); 1784 operands[3] = GEN_INT (GET_MODE_MASK (GET_MODE (operands[1]))); 1785 operands[4] = gen_rtx_AND (GET_MODE (operands[0]), operands[0], operands[3]); 1786}) 1787 1788(define_split 1789 [(set (match_operand 0 "register_operand" "") 1790 (zero_extend (match_operand 1 "nonimmediate_src_operand" "")))] 1791 "!ISA_HAS_MVS_MVZ && reload_completed" 1792 [(set (match_dup 0) 1793 (const_int 0)) 1794 (set (strict_low_part (match_dup 2)) 1795 (match_dup 1))] 1796{ 1797 operands[2] = gen_lowpart (GET_MODE (operands[1]), operands[0]); 1798}) 1799 1800;; sign extension instructions 1801 1802(define_insn "extendqidi2" 1803 [(set (match_operand:DI 0 "nonimmediate_operand" "=d") 1804 (sign_extend:DI (match_operand:QI 1 "general_src_operand" "rmS")))] 1805 "" 1806{ 1807 CC_STATUS_INIT; 1808 operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); 1809 if (ISA_HAS_MVS_MVZ) 1810 return "mvs%.b %1,%2\;smi %0\;extb%.l %0"; 1811 if (TARGET_68020 || TARGET_COLDFIRE) 1812 { 1813 if (ADDRESS_REG_P (operands[1])) 1814 return "move%.w %1,%2\;extb%.l %2\;smi %0\;extb%.l %0"; 1815 else 1816 return "move%.b %1,%2\;extb%.l %2\;smi %0\;extb%.l %0"; 1817 } 1818 else 1819 { 1820 if (ADDRESS_REG_P (operands[1])) 1821 return "move%.w %1,%2\;ext%.w %2\;ext%.l %2\;move%.l %2,%0\;smi %0"; 1822 else 1823 return "move%.b %1,%2\;ext%.w %2\;ext%.l %2\;move%.l %2,%0\;smi %0"; 1824 } 1825}) 1826 1827(define_insn "extendhidi2" 1828 [(set (match_operand:DI 0 "nonimmediate_operand" "=d") 1829 (sign_extend:DI 1830 (match_operand:HI 1 "general_src_operand" "rmS")))] 1831 "" 1832{ 1833 CC_STATUS_INIT; 1834 operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); 1835 if (ISA_HAS_MVS_MVZ) 1836 return "mvs%.w %1,%2\;smi %0\;extb%.l %0"; 1837 if (TARGET_68020 || TARGET_COLDFIRE) 1838 return "move%.w %1,%2\;ext%.l %2\;smi %0\;extb%.l %0"; 1839 else 1840 return "move%.w %1,%2\;ext%.l %2\;smi %0\;ext%.w %0\;ext%.l %0"; 1841}) 1842 1843(define_insn "extendsidi2" 1844 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,o,o,<") 1845 (sign_extend:DI 1846 (match_operand:SI 1 "nonimmediate_src_operand" "rm,rm,r<Q>,rm"))) 1847 (clobber (match_scratch:SI 2 "=X,d,d,d"))] 1848 "" 1849{ 1850 CC_STATUS_INIT; 1851 1852 if (which_alternative == 0) 1853 /* Handle alternative 0. */ 1854 { 1855 if (TARGET_68020 || TARGET_COLDFIRE) 1856 return "move%.l %1,%R0\;smi %0\;extb%.l %0"; 1857 else 1858 return "move%.l %1,%R0\;smi %0\;ext%.w %0\;ext%.l %0"; 1859 } 1860 1861 /* Handle alternatives 1, 2 and 3. We don't need to adjust address by 4 1862 in alternative 3 because autodecrement will do that for us. */ 1863 operands[3] = adjust_address (operands[0], SImode, 1864 which_alternative == 3 ? 0 : 4); 1865 operands[0] = adjust_address (operands[0], SImode, 0); 1866 1867 if (TARGET_68020 || TARGET_COLDFIRE) 1868 return "move%.l %1,%3\;smi %2\;extb%.l %2\;move%.l %2,%0"; 1869 else 1870 return "move%.l %1,%3\;smi %2\;ext%.w %2\;ext%.l %2\;move%.l %2,%0"; 1871} 1872 [(set_attr "ok_for_coldfire" "yes,no,yes,yes")]) 1873 1874;; Special case when one can avoid register clobbering, copy and test 1875;; Maybe there is a way to make that the general case, by forcing the 1876;; result of the SI tree to be in the lower register of the DI target 1877 1878;; Don't allow memory for operand 1 as that would require an earlyclobber 1879;; which results in worse code 1880(define_insn "extendplussidi" 1881 [(set (match_operand:DI 0 "register_operand" "=d") 1882 (sign_extend:DI (plus:SI (match_operand:SI 1 "general_operand" "%rn") 1883 (match_operand:SI 2 "general_operand" "rmn"))))] 1884 "" 1885{ 1886 CC_STATUS_INIT; 1887 operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); 1888 if (GET_CODE (operands[1]) == CONST_INT 1889 && (unsigned) INTVAL (operands[1]) > 8) 1890 { 1891 rtx tmp = operands[1]; 1892 1893 operands[1] = operands[2]; 1894 operands[2] = tmp; 1895 } 1896 if (GET_CODE (operands[1]) == REG 1897 && REGNO (operands[1]) == REGNO (operands[3])) 1898 output_asm_insn ("add%.l %2,%3", operands); 1899 else 1900 output_asm_insn ("move%.l %2,%3\;add%.l %1,%3", operands); 1901 if (TARGET_68020 || TARGET_COLDFIRE) 1902 return "smi %0\;extb%.l %0"; 1903 else 1904 return "smi %0\;ext%.w %0\;ext%.l %0"; 1905}) 1906 1907(define_expand "extendhisi2" 1908 [(set (match_operand:SI 0 "nonimmediate_operand" "") 1909 (sign_extend:SI 1910 (match_operand:HI 1 "nonimmediate_src_operand" "")))] 1911 "" 1912 "") 1913 1914(define_insn "*cfv4_extendhisi2" 1915 [(set (match_operand:SI 0 "nonimmediate_operand" "=d") 1916 (sign_extend:SI 1917 (match_operand:HI 1 "nonimmediate_src_operand" "rmS")))] 1918 "ISA_HAS_MVS_MVZ" 1919 "mvs%.w %1,%0" 1920 [(set_attr "type" "mvsz")]) 1921 1922(define_insn "*68k_extendhisi2" 1923 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,a") 1924 (sign_extend:SI 1925 (match_operand:HI 1 "nonimmediate_src_operand" "0,rmS")))] 1926 "!ISA_HAS_MVS_MVZ" 1927 "@ 1928 ext%.l %0 1929 move%.w %1,%0" 1930 [(set_attr "type" "ext,move")]) 1931 1932(define_insn "extendqihi2" 1933 [(set (match_operand:HI 0 "nonimmediate_operand" "=d") 1934 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0")))] 1935 "" 1936 "ext%.w %0" 1937 [(set_attr "type" "ext")]) 1938 1939(define_expand "extendqisi2" 1940 [(set (match_operand:SI 0 "nonimmediate_operand" "") 1941 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))] 1942 "TARGET_68020 || TARGET_COLDFIRE" 1943 "") 1944 1945(define_insn "*cfv4_extendqisi2" 1946 [(set (match_operand:SI 0 "nonimmediate_operand" "=d") 1947 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rms")))] 1948 "ISA_HAS_MVS_MVZ" 1949 "mvs%.b %1,%0" 1950 [(set_attr "type" "mvsz")]) 1951 1952(define_insn "*68k_extendqisi2" 1953 [(set (match_operand:SI 0 "nonimmediate_operand" "=d") 1954 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0")))] 1955 "TARGET_68020 || (TARGET_COLDFIRE && !ISA_HAS_MVS_MVZ)" 1956 "extb%.l %0" 1957 [(set_attr "type" "ext")]) 1958 1959;; Conversions between float and double. 1960 1961(define_expand "extendsfdf2" 1962 [(set (match_operand:DF 0 "nonimmediate_operand" "") 1963 (float_extend:DF 1964 (match_operand:SF 1 "general_operand" "")))] 1965 "TARGET_HARD_FLOAT" 1966 "") 1967 1968(define_insn "" 1969 [(set (match_operand:DF 0 "nonimmediate_operand" "=*fdm,f") 1970 (float_extend:DF 1971 (match_operand:SF 1 "general_operand" "f,dmF")))] 1972 "TARGET_68881" 1973{ 1974 if (FP_REG_P (operands[0]) && FP_REG_P (operands[1])) 1975 { 1976 if (REGNO (operands[0]) == REGNO (operands[1])) 1977 { 1978 /* Extending float to double in an fp-reg is a no-op. 1979 NOTICE_UPDATE_CC has already assumed that the 1980 cc will be set. So cancel what it did. */ 1981 cc_status = cc_prev_status; 1982 return ""; 1983 } 1984 return "f%&move%.x %1,%0"; 1985 } 1986 if (FP_REG_P (operands[0])) 1987 return "f%&move%.s %f1,%0"; 1988 if (DATA_REG_P (operands[0]) && FP_REG_P (operands[1])) 1989 { 1990 output_asm_insn ("fmove%.d %f1,%-\;move%.l %+,%0", operands); 1991 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); 1992 return "move%.l %+,%0"; 1993 } 1994 return "fmove%.d %f1,%0"; 1995}) 1996 1997(define_insn "extendsfdf2_cf" 1998 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f") 1999 (float_extend:DF 2000 (match_operand:SF 1 "general_operand" "f,<Q>U")))] 2001 "TARGET_COLDFIRE_FPU" 2002{ 2003 if (FP_REG_P (operands[0]) && FP_REG_P (operands[1])) 2004 { 2005 if (REGNO (operands[0]) == REGNO (operands[1])) 2006 { 2007 /* Extending float to double in an fp-reg is a no-op. 2008 NOTICE_UPDATE_CC has already assumed that the 2009 cc will be set. So cancel what it did. */ 2010 cc_status = cc_prev_status; 2011 return ""; 2012 } 2013 return "fdmove%.d %1,%0"; 2014 } 2015 return "fdmove%.s %f1,%0"; 2016}) 2017 2018;; This cannot output into an f-reg because there is no way to be 2019;; sure of truncating in that case. 2020(define_expand "truncdfsf2" 2021 [(set (match_operand:SF 0 "nonimmediate_operand" "") 2022 (float_truncate:SF 2023 (match_operand:DF 1 "general_operand" "")))] 2024 "TARGET_HARD_FLOAT" 2025 "") 2026 2027;; On the '040 we can truncate in a register accurately and easily. 2028(define_insn "" 2029 [(set (match_operand:SF 0 "nonimmediate_operand" "=f") 2030 (float_truncate:SF 2031 (match_operand:DF 1 "general_operand" "fmG")))] 2032 "TARGET_68881 && TARGET_68040" 2033{ 2034 if (FP_REG_P (operands[1])) 2035 return "f%$move%.x %1,%0"; 2036 return "f%$move%.d %f1,%0"; 2037}) 2038 2039(define_insn "truncdfsf2_cf" 2040 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,d<Q>U") 2041 (float_truncate:SF 2042 (match_operand:DF 1 "general_operand" "<Q>U,f")))] 2043 "TARGET_COLDFIRE_FPU" 2044 "@ 2045 fsmove%.d %1,%0 2046 fmove%.s %1,%0" 2047 [(set_attr "type" "fmove")]) 2048 2049(define_insn "*truncdfsf2_68881" 2050 [(set (match_operand:SF 0 "nonimmediate_operand" "=dm") 2051 (float_truncate:SF 2052 (match_operand:DF 1 "general_operand" "f")))] 2053 "TARGET_68881" 2054 "fmove%.s %f1,%0" 2055 [(set_attr "type" "fmove")]) 2056 2057;; Conversion between fixed point and floating point. 2058;; Note that among the fix-to-float insns 2059;; the ones that start with SImode come first. 2060;; That is so that an operand that is a CONST_INT 2061;; (and therefore lacks a specific machine mode). 2062;; will be recognized as SImode (which is always valid) 2063;; rather than as QImode or HImode. 2064 2065(define_expand "floatsi<mode>2" 2066 [(set (match_operand:FP 0 "nonimmediate_operand" "") 2067 (float:FP (match_operand:SI 1 "general_operand" "")))] 2068 "TARGET_HARD_FLOAT" 2069 "") 2070 2071(define_insn "floatsi<mode>2_68881" 2072 [(set (match_operand:FP 0 "nonimmediate_operand" "=f") 2073 (float:FP (match_operand:SI 1 "general_operand" "dmi")))] 2074 "TARGET_68881" 2075 "f<FP:round>move%.l %1,%0" 2076 [(set_attr "type" "fmove")]) 2077 2078(define_insn "floatsi<mode>2_cf" 2079 [(set (match_operand:FP 0 "nonimmediate_operand" "=f") 2080 (float:FP (match_operand:SI 1 "general_operand" "d<Q>U")))] 2081 "TARGET_COLDFIRE_FPU" 2082 "f<FP:prec>move%.l %1,%0" 2083 [(set_attr "type" "fmove")]) 2084 2085 2086(define_expand "floathi<mode>2" 2087 [(set (match_operand:FP 0 "nonimmediate_operand" "") 2088 (float:FP (match_operand:HI 1 "general_operand" "")))] 2089 "TARGET_HARD_FLOAT" 2090 "") 2091 2092(define_insn "floathi<mode>2_68881" 2093 [(set (match_operand:FP 0 "nonimmediate_operand" "=f") 2094 (float:FP (match_operand:HI 1 "general_operand" "dmn")))] 2095 "TARGET_68881" 2096 "fmove%.w %1,%0" 2097 [(set_attr "type" "fmove")]) 2098 2099(define_insn "floathi<mode>2_cf" 2100 [(set (match_operand:FP 0 "nonimmediate_operand" "=f") 2101 (float:FP (match_operand:HI 1 "general_operand" "d<Q>U")))] 2102 "TARGET_COLDFIRE_FPU" 2103 "fmove%.w %1,%0" 2104 [(set_attr "type" "fmove")]) 2105 2106 2107(define_expand "floatqi<mode>2" 2108 [(set (match_operand:FP 0 "nonimmediate_operand" "") 2109 (float:FP (match_operand:QI 1 "general_operand" "")))] 2110 "TARGET_HARD_FLOAT" 2111 "") 2112 2113(define_insn "floatqi<mode>2_68881" 2114 [(set (match_operand:FP 0 "nonimmediate_operand" "=f") 2115 (float:FP (match_operand:QI 1 "general_operand" "dmn")))] 2116 "TARGET_68881" 2117 "fmove%.b %1,%0" 2118 [(set_attr "type" "fmove")]) 2119 2120(define_insn "floatqi<mode>2_cf" 2121 [(set (match_operand:FP 0 "nonimmediate_operand" "=f") 2122 (float:FP (match_operand:QI 1 "general_operand" "d<Q>U")))] 2123 "TARGET_COLDFIRE_FPU" 2124 "fmove%.b %1,%0" 2125 [(set_attr "type" "fmove")]) 2126 2127 2128;; New routines to convert floating-point values to integers 2129;; to be used on the '040. These should be faster than trapping 2130;; into the kernel to emulate fintrz. They should also be faster 2131;; than calling the subroutines fixsfsi or fixdfsi. 2132 2133(define_insn "fix_truncdfsi2" 2134 [(set (match_operand:SI 0 "nonimmediate_operand" "=dm") 2135 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f")))) 2136 (clobber (match_scratch:SI 2 "=d")) 2137 (clobber (match_scratch:SI 3 "=d"))] 2138 "TARGET_68881 && TUNE_68040" 2139{ 2140 CC_STATUS_INIT; 2141 return "fmovem%.l %!,%2\;moveq #16,%3\;or%.l %2,%3\;and%.w #-33,%3\;fmovem%.l %3,%!\;fmove%.l %1,%0\;fmovem%.l %2,%!"; 2142}) 2143 2144(define_insn "fix_truncdfhi2" 2145 [(set (match_operand:HI 0 "nonimmediate_operand" "=dm") 2146 (fix:HI (fix:DF (match_operand:DF 1 "register_operand" "f")))) 2147 (clobber (match_scratch:SI 2 "=d")) 2148 (clobber (match_scratch:SI 3 "=d"))] 2149 "TARGET_68881 && TUNE_68040" 2150{ 2151 CC_STATUS_INIT; 2152 return "fmovem%.l %!,%2\;moveq #16,%3\;or%.l %2,%3\;and%.w #-33,%3\;fmovem%.l %3,%!\;fmove%.w %1,%0\;fmovem%.l %2,%!"; 2153}) 2154 2155(define_insn "fix_truncdfqi2" 2156 [(set (match_operand:QI 0 "nonimmediate_operand" "=dm") 2157 (fix:QI (fix:DF (match_operand:DF 1 "register_operand" "f")))) 2158 (clobber (match_scratch:SI 2 "=d")) 2159 (clobber (match_scratch:SI 3 "=d"))] 2160 "TARGET_68881 && TUNE_68040" 2161{ 2162 CC_STATUS_INIT; 2163 return "fmovem%.l %!,%2\;moveq #16,%3\;or%.l %2,%3\;and%.w #-33,%3\;fmovem%.l %3,%!\;fmove%.b %1,%0\;fmovem%.l %2,%!"; 2164}) 2165 2166;; Convert a float to a float whose value is an integer. 2167;; This is the first stage of converting it to an integer type. 2168 2169(define_expand "ftrunc<mode>2" 2170 [(set (match_operand:FP 0 "nonimmediate_operand" "") 2171 (fix:FP (match_operand:FP 1 "general_operand" "")))] 2172 "TARGET_HARD_FLOAT && !TUNE_68040" 2173 "") 2174 2175(define_insn "ftrunc<mode>2_68881" 2176 [(set (match_operand:FP 0 "nonimmediate_operand" "=f") 2177 (fix:FP (match_operand:FP 1 "general_operand" "f<FP:dreg>m")))] 2178 "TARGET_68881 && !TUNE_68040" 2179{ 2180 if (FP_REG_P (operands[1])) 2181 return "fintrz%.x %f1,%0"; 2182 return "fintrz%.<FP:prec> %f1,%0"; 2183} 2184 [(set_attr "type" "falu")]) 2185 2186(define_insn "ftrunc<mode>2_cf" 2187 [(set (match_operand:FP 0 "nonimmediate_operand" "=f") 2188 (fix:FP (match_operand:FP 1 "general_operand" "f<FP:dreg><Q>U")))] 2189 "TARGET_COLDFIRE_FPU" 2190{ 2191 if (FP_REG_P (operands[1])) 2192 return "fintrz%.d %f1,%0"; 2193 return "fintrz%.<FP:prec> %f1,%0"; 2194} 2195 [(set_attr "type" "falu")]) 2196 2197;; Convert a float whose value is an integer 2198;; to an actual integer. Second stage of converting float to integer type. 2199(define_expand "fix<mode>qi2" 2200 [(set (match_operand:QI 0 "nonimmediate_operand" "") 2201 (fix:QI (match_operand:FP 1 "general_operand" "")))] 2202 "TARGET_HARD_FLOAT" 2203 "") 2204 2205(define_insn "fix<mode>qi2_68881" 2206 [(set (match_operand:QI 0 "nonimmediate_operand" "=dm") 2207 (fix:QI (match_operand:FP 1 "general_operand" "f")))] 2208 "TARGET_68881" 2209 "fmove%.b %1,%0" 2210 [(set_attr "type" "fmove")]) 2211 2212(define_insn "fix<mode>qi2_cf" 2213 [(set (match_operand:QI 0 "nonimmediate_operand" "=d<Q>U") 2214 (fix:QI (match_operand:FP 1 "general_operand" "f")))] 2215 "TARGET_COLDFIRE_FPU" 2216 "fmove%.b %1,%0" 2217 [(set_attr "type" "fmove")]) 2218 2219(define_expand "fix<mode>hi2" 2220 [(set (match_operand:HI 0 "nonimmediate_operand" "") 2221 (fix:HI (match_operand:FP 1 "general_operand" "")))] 2222 "TARGET_HARD_FLOAT" 2223 "") 2224 2225(define_insn "fix<mode>hi2_68881" 2226 [(set (match_operand:HI 0 "nonimmediate_operand" "=dm") 2227 (fix:HI (match_operand:FP 1 "general_operand" "f")))] 2228 "TARGET_68881" 2229 "fmove%.w %1,%0" 2230 [(set_attr "type" "fmove")]) 2231 2232(define_insn "fix<mode>hi2_cf" 2233 [(set (match_operand:HI 0 "nonimmediate_operand" "=d<Q>U") 2234 (fix:HI (match_operand:FP 1 "general_operand" "f")))] 2235 "TARGET_COLDFIRE_FPU" 2236 "fmove%.w %1,%0" 2237 [(set_attr "type" "fmove")]) 2238 2239(define_expand "fix<mode>si2" 2240 [(set (match_operand:SI 0 "nonimmediate_operand" "") 2241 (fix:SI (match_operand:FP 1 "general_operand" "")))] 2242 "TARGET_HARD_FLOAT" 2243 "") 2244 2245(define_insn "fix<mode>si2_68881" 2246 [(set (match_operand:SI 0 "nonimmediate_operand" "=dm") 2247 (fix:SI (match_operand:FP 1 "general_operand" "f")))] 2248 "TARGET_68881" 2249 "fmove%.l %1,%0" 2250 [(set_attr "type" "fmove")]) 2251 2252(define_insn "fix<mode>si2_cf" 2253 [(set (match_operand:SI 0 "nonimmediate_operand" "=d<Q>U") 2254 (fix:SI (match_operand:FP 1 "general_operand" "f")))] 2255 "TARGET_COLDFIRE_FPU" 2256 "fmove%.l %1,%0" 2257 [(set_attr "type" "fmove")]) 2258 2259 2260;; add instructions 2261 2262(define_insn "adddi_lshrdi_63" 2263 [(set (match_operand:DI 0 "nonimmediate_operand" "=d") 2264 (plus:DI (lshiftrt:DI (match_operand:DI 1 "general_operand" "rm") 2265 (const_int 63)) 2266 (match_dup 1))) 2267 (clobber (match_scratch:SI 2 "=d"))] 2268 "" 2269{ 2270 operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); 2271 if (REG_P (operands[1]) && REGNO (operands[1]) == REGNO (operands[0])) 2272 return 2273 "move%.l %1,%2\;add%.l %2,%2\;subx%.l %2,%2\;sub%.l %2,%3\;subx%.l %2,%0"; 2274 if (GET_CODE (operands[1]) == REG) 2275 operands[4] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1); 2276 else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC 2277 || GET_CODE (XEXP (operands[1], 0)) == PRE_DEC) 2278 operands[4] = operands[1]; 2279 else 2280 operands[4] = adjust_address (operands[1], SImode, 4); 2281 if (GET_CODE (operands[1]) == MEM 2282 && GET_CODE (XEXP (operands[1], 0)) == PRE_DEC) 2283 output_asm_insn ("move%.l %4,%3", operands); 2284 output_asm_insn ("move%.l %1,%0\;smi %2", operands); 2285 if (TARGET_68020 || TARGET_COLDFIRE) 2286 output_asm_insn ("extb%.l %2", operands); 2287 else 2288 output_asm_insn ("ext%.w %2\;ext%.l %2", operands); 2289 if (GET_CODE (operands[1]) != MEM 2290 || GET_CODE (XEXP (operands[1], 0)) != PRE_DEC) 2291 output_asm_insn ("move%.l %4,%3", operands); 2292 return "sub%.l %2,%3\;subx%.l %2,%0"; 2293}) 2294 2295(define_insn "adddi_sexthishl32" 2296 [(set (match_operand:DI 0 "nonimmediate_operand" "=o,a,*d,*d") 2297 (plus:DI (ashift:DI (sign_extend:DI 2298 (match_operand:HI 1 "general_operand" "rm,rm,rm,rm")) 2299 (const_int 32)) 2300 (match_operand:DI 2 "general_operand" "0,0,0,0"))) 2301 (clobber (match_scratch:SI 3 "=&d,X,a,?d"))] 2302 "!TARGET_COLDFIRE" 2303{ 2304 CC_STATUS_INIT; 2305 if (ADDRESS_REG_P (operands[0])) 2306 return "add%.w %1,%0"; 2307 else if (ADDRESS_REG_P (operands[3])) 2308 return "move%.w %1,%3\;add%.l %3,%0"; 2309 else 2310 return "move%.w %1,%3\;ext%.l %3\;add%.l %3,%0"; 2311}) 2312 2313(define_insn "*adddi_dilshr32" 2314 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,o") 2315 (plus:DI (lshiftrt:DI (match_operand:DI 1 "general_operand" "ro,d") 2316 (const_int 32)) 2317 (match_operand:DI 2 "general_operand" "0,0")))] 2318 "!TARGET_COLDFIRE" 2319{ 2320 CC_STATUS_INIT; 2321 if (GET_CODE (operands[0]) == REG) 2322 operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); 2323 else 2324 operands[2] = adjust_address (operands[0], SImode, 4); 2325 return "add%.l %1,%2\;negx%.l %0\;neg%.l %0"; 2326}) 2327 2328(define_insn "*adddi_dilshr32_cf" 2329 [(set (match_operand:DI 0 "register_operand" "=d") 2330 (plus:DI (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "ro") 2331 (const_int 32)) 2332 (match_operand:DI 2 "register_operand" "0")))] 2333 "TARGET_COLDFIRE" 2334{ 2335 CC_STATUS_INIT; 2336 return "add%.l %1,%R0\;negx%.l %0\;neg%.l %0"; 2337}) 2338 2339(define_insn "adddi_dishl32" 2340 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o") 2341;; (plus:DI (match_operand:DI 2 "general_operand" "%0") 2342;; (ashift:DI (match_operand:DI 1 "general_operand" "ro") 2343;; (const_int 32))))] 2344 (plus:DI (ashift:DI (match_operand:DI 1 "general_operand" "ro,d") 2345 (const_int 32)) 2346 (match_operand:DI 2 "general_operand" "0,0")))] 2347 "" 2348{ 2349 CC_STATUS_INIT; 2350 if (GET_CODE (operands[1]) == REG) 2351 operands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1); 2352 else 2353 operands[1] = adjust_address (operands[1], SImode, 4); 2354 return "add%.l %1,%0"; 2355} 2356 [(set_attr "type" "alu_l")]) 2357 2358(define_insn "adddi3" 2359 [(set (match_operand:DI 0 "nonimmediate_operand" "=o<>,d,d,d") 2360 (plus:DI (match_operand:DI 1 "general_operand" "%0,0,0,0") 2361 (match_operand:DI 2 "general_operand" "d,no>,d,a"))) 2362 (clobber (match_scratch:SI 3 "=&d,&d,X,&d"))] 2363 "" 2364{ 2365 if (DATA_REG_P (operands[0])) 2366 { 2367 if (DATA_REG_P (operands[2])) 2368 return "add%.l %R2,%R0\;addx%.l %2,%0"; 2369 else if (GET_CODE (operands[2]) == MEM 2370 && GET_CODE (XEXP (operands[2], 0)) == POST_INC) 2371 return "move%.l %2,%3\;add%.l %2,%R0\;addx%.l %3,%0"; 2372 else 2373 { 2374 rtx high, low; 2375 rtx xoperands[2]; 2376 2377 if (GET_CODE (operands[2]) == REG) 2378 { 2379 low = gen_rtx_REG (SImode, REGNO (operands[2]) + 1); 2380 high = operands[2]; 2381 } 2382 else if (CONSTANT_P (operands[2])) 2383 split_double (operands[2], &high, &low); 2384 else 2385 { 2386 low = adjust_address (operands[2], SImode, 4); 2387 high = operands[2]; 2388 } 2389 2390 operands[1] = low, operands[2] = high; 2391 xoperands[0] = operands[3]; 2392 if (GET_CODE (operands[1]) == CONST_INT 2393 && INTVAL (operands[1]) >= -8 && INTVAL (operands[1]) < 0) 2394 xoperands[1] = GEN_INT (-INTVAL (operands[2]) - 1); 2395 else 2396 xoperands[1] = operands[2]; 2397 2398 output_asm_insn (output_move_simode (xoperands), xoperands); 2399 if (GET_CODE (operands[1]) == CONST_INT) 2400 { 2401 if (INTVAL (operands[1]) > 0 && INTVAL (operands[1]) <= 8) 2402 return "addq%.l %1,%R0\;addx%.l %3,%0"; 2403 else if (INTVAL (operands[1]) >= -8 && INTVAL (operands[1]) < 0) 2404 { 2405 operands[1] = GEN_INT (-INTVAL (operands[1])); 2406 return "subq%.l %1,%R0\;subx%.l %3,%0"; 2407 } 2408 } 2409 return "add%.l %1,%R0\;addx%.l %3,%0"; 2410 } 2411 } 2412 else 2413 { 2414 gcc_assert (GET_CODE (operands[0]) == MEM); 2415 CC_STATUS_INIT; 2416 if (GET_CODE (XEXP (operands[0], 0)) == POST_INC) 2417 { 2418 operands[1] = gen_rtx_MEM (SImode, 2419 plus_constant (Pmode, 2420 XEXP(operands[0], 0), -8)); 2421 return "move%.l %0,%3\;add%.l %R2,%0\;addx%.l %2,%3\;move%.l %3,%1"; 2422 } 2423 else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) 2424 { 2425 operands[1] = XEXP(operands[0], 0); 2426 return "add%.l %R2,%0\;move%.l %0,%3\;addx%.l %2,%3\;move%.l %3,%1"; 2427 } 2428 else 2429 { 2430 operands[1] = adjust_address (operands[0], SImode, 4); 2431 return "add%.l %R2,%1\;move%.l %0,%3\;addx%.l %2,%3\;move%.l %3,%0"; 2432 } 2433 } 2434}) 2435 2436(define_insn "addsi_lshrsi_31" 2437 [(set (match_operand:SI 0 "nonimmediate_operand" "=dm,dm,d<Q>") 2438 (plus:SI (lshiftrt:SI (match_operand:SI 1 "general_operand" "rm,r<Q>,rm") 2439 (const_int 31)) 2440 (match_dup 1)))] 2441 "" 2442{ 2443 operands[2] = operands[0]; 2444 operands[3] = gen_label_rtx(); 2445 if (GET_CODE (operands[0]) == MEM) 2446 { 2447 if (GET_CODE (XEXP (operands[0], 0)) == POST_INC) 2448 operands[0] = gen_rtx_MEM (SImode, XEXP (XEXP (operands[0], 0), 0)); 2449 else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) 2450 operands[2] = gen_rtx_MEM (SImode, XEXP (XEXP (operands[0], 0), 0)); 2451 } 2452 output_asm_insn ("move%.l %1,%0", operands); 2453 output_asm_insn ("jpl %l3", operands); 2454 output_asm_insn ("addq%.l #1,%2", operands); 2455 (*targetm.asm_out.internal_label) (asm_out_file, "L", 2456 CODE_LABEL_NUMBER (operands[3])); 2457 return ""; 2458} 2459 [(set_attr "ok_for_coldfire" "no,yes,yes")]) 2460 2461(define_expand "addsi3" 2462 [(set (match_operand:SI 0 "nonimmediate_operand" "") 2463 (plus:SI (match_operand:SI 1 "general_operand" "") 2464 (match_operand:SI 2 "general_src_operand" "")))] 2465 "" 2466 "") 2467 2468;; Note that the middle two alternatives are near-duplicates 2469;; in order to handle insns generated by reload. 2470;; This is needed since they are not themselves reloaded, 2471;; so commutativity won't apply to them. 2472(define_insn "*addsi3_internal" 2473 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?a,?a,d,a") 2474 (plus:SI (match_operand:SI 1 "general_operand" "%0,a,rJK,0,0") 2475 (match_operand:SI 2 "general_src_operand" "dIKLT,rJK,a,mSrIKLT,mSrIKLs")))] 2476 2477 2478 "! TARGET_COLDFIRE" 2479 "* return output_addsi3 (operands);") 2480 2481(define_insn_and_split "*addsi3_5200" 2482 [(set (match_operand:SI 0 "nonimmediate_operand" "=mr,mr,a, m,r, ?a, ?a,?a,?a") 2483 (plus:SI (match_operand:SI 1 "general_operand" "%0, 0, 0, 0,0, a, a, r, a") 2484 (match_operand:SI 2 "general_src_operand" " I, L, JCu,d,mrKi,Cj, r, a, JCu")))] 2485 "TARGET_COLDFIRE" 2486{ 2487 switch (which_alternative) 2488 { 2489 case 0: 2490 return "addq%.l %2,%0"; 2491 2492 case 1: 2493 operands[2] = GEN_INT (- INTVAL (operands[2])); 2494 return "subq%.l %2,%0"; 2495 2496 case 3: 2497 case 4: 2498 return "add%.l %2,%0"; 2499 2500 case 5: 2501 /* move%.l %2,%0\n\tadd%.l %1,%0 */ 2502 return "#"; 2503 2504 case 6: 2505 return MOTOROLA ? "lea (%1,%2.l),%0" : "lea %1@(0,%2:l),%0"; 2506 2507 case 7: 2508 return MOTOROLA ? "lea (%2,%1.l),%0" : "lea %2@(0,%1:l),%0"; 2509 2510 case 2: 2511 case 8: 2512 return MOTOROLA ? "lea (%c2,%1),%0" : "lea %1@(%c2),%0"; 2513 2514 default: 2515 gcc_unreachable (); 2516 return ""; 2517 } 2518} 2519 "&& reload_completed && (extract_constrain_insn_cached (insn), which_alternative == 5) && !operands_match_p (operands[0], operands[1])" 2520 [(set (match_dup 0) 2521 (match_dup 2)) 2522 (set (match_dup 0) 2523 (plus:SI (match_dup 0) 2524 (match_dup 1)))] 2525 "" 2526 [(set_attr "type" "aluq_l,aluq_l,lea, alu_l,alu_l,*,lea, lea, lea") 2527 (set_attr "opy" "2, 2, *, 2, 2, *,*, *, *") 2528 (set_attr "opy_type" "*, *, mem5,*, *, *,mem6,mem6,mem5")]) 2529 2530(define_insn "" 2531 [(set (match_operand:SI 0 "nonimmediate_operand" "=a") 2532 (plus:SI (match_operand:SI 1 "general_operand" "0") 2533 (sign_extend:SI 2534 (match_operand:HI 2 "nonimmediate_src_operand" "rmS"))))] 2535 "!TARGET_COLDFIRE" 2536 "add%.w %2,%0") 2537 2538(define_insn "addhi3" 2539 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,r") 2540 (plus:HI (match_operand:HI 1 "general_operand" "%0,0") 2541 (match_operand:HI 2 "general_src_operand" "dn,rmSn")))] 2542 "!TARGET_COLDFIRE" 2543{ 2544 if (GET_CODE (operands[2]) == CONST_INT) 2545 { 2546 /* If the constant would be a negative number when interpreted as 2547 HImode, make it negative. This is usually, but not always, done 2548 elsewhere in the compiler. First check for constants out of range, 2549 which could confuse us. */ 2550 2551 if (INTVAL (operands[2]) >= 32768) 2552 operands[2] = GEN_INT (INTVAL (operands[2]) - 65536); 2553 2554 if (INTVAL (operands[2]) > 0 2555 && INTVAL (operands[2]) <= 8) 2556 return "addq%.w %2,%0"; 2557 if (INTVAL (operands[2]) < 0 2558 && INTVAL (operands[2]) >= -8) 2559 { 2560 operands[2] = GEN_INT (- INTVAL (operands[2])); 2561 return "subq%.w %2,%0"; 2562 } 2563 /* On the CPU32 it is faster to use two addqw instructions to 2564 add a small integer (8 < N <= 16) to a register. 2565 Likewise for subqw. */ 2566 if (TUNE_CPU32 && REG_P (operands[0])) 2567 { 2568 if (INTVAL (operands[2]) > 8 2569 && INTVAL (operands[2]) <= 16) 2570 { 2571 operands[2] = GEN_INT (INTVAL (operands[2]) - 8); 2572 return "addq%.w #8,%0\;addq%.w %2,%0"; 2573 } 2574 if (INTVAL (operands[2]) < -8 2575 && INTVAL (operands[2]) >= -16) 2576 { 2577 operands[2] = GEN_INT (- INTVAL (operands[2]) - 8); 2578 return "subq%.w #8,%0\;subq%.w %2,%0"; 2579 } 2580 } 2581 if (ADDRESS_REG_P (operands[0]) && !TUNE_68040) 2582 return MOTOROLA ? "lea (%c2,%0),%0" : "lea %0@(%c2),%0"; 2583 } 2584 return "add%.w %2,%0"; 2585}) 2586 2587;; These insns must use MATCH_DUP instead of the more expected 2588;; use of a matching constraint because the "output" here is also 2589;; an input, so you can't use the matching constraint. That also means 2590;; that you can't use the "%", so you need patterns with the matched 2591;; operand in both positions. 2592 2593(define_insn "" 2594 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d")) 2595 (plus:HI (match_dup 0) 2596 (match_operand:HI 1 "general_src_operand" "dn,rmSn")))] 2597 "!TARGET_COLDFIRE" 2598{ 2599 if (GET_CODE (operands[1]) == CONST_INT) 2600 { 2601 /* If the constant would be a negative number when interpreted as 2602 HImode, make it negative. This is usually, but not always, done 2603 elsewhere in the compiler. First check for constants out of range, 2604 which could confuse us. */ 2605 2606 if (INTVAL (operands[1]) >= 32768) 2607 operands[1] = GEN_INT (INTVAL (operands[1]) - 65536); 2608 2609 if (INTVAL (operands[1]) > 0 2610 && INTVAL (operands[1]) <= 8) 2611 return "addq%.w %1,%0"; 2612 if (INTVAL (operands[1]) < 0 2613 && INTVAL (operands[1]) >= -8) 2614 { 2615 operands[1] = GEN_INT (- INTVAL (operands[1])); 2616 return "subq%.w %1,%0"; 2617 } 2618 /* On the CPU32 it is faster to use two addqw instructions to 2619 add a small integer (8 < N <= 16) to a register. 2620 Likewise for subqw. */ 2621 if (TUNE_CPU32 && REG_P (operands[0])) 2622 { 2623 if (INTVAL (operands[1]) > 8 2624 && INTVAL (operands[1]) <= 16) 2625 { 2626 operands[1] = GEN_INT (INTVAL (operands[1]) - 8); 2627 return "addq%.w #8,%0\;addq%.w %1,%0"; 2628 } 2629 if (INTVAL (operands[1]) < -8 2630 && INTVAL (operands[1]) >= -16) 2631 { 2632 operands[1] = GEN_INT (- INTVAL (operands[1]) - 8); 2633 return "subq%.w #8,%0\;subq%.w %1,%0"; 2634 } 2635 } 2636 if (ADDRESS_REG_P (operands[0]) && !TUNE_68040) 2637 return MOTOROLA ? "lea (%c1,%0),%0" : "lea %0@(%c1),%0"; 2638 } 2639 return "add%.w %1,%0"; 2640}) 2641 2642(define_insn "" 2643 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d")) 2644 (plus:HI (match_operand:HI 1 "general_src_operand" "dn,rmSn") 2645 (match_dup 0)))] 2646 "!TARGET_COLDFIRE" 2647{ 2648 if (GET_CODE (operands[1]) == CONST_INT) 2649 { 2650 /* If the constant would be a negative number when interpreted as 2651 HImode, make it negative. This is usually, but not always, done 2652 elsewhere in the compiler. First check for constants out of range, 2653 which could confuse us. */ 2654 2655 if (INTVAL (operands[1]) >= 32768) 2656 operands[1] = GEN_INT (INTVAL (operands[1]) - 65536); 2657 2658 if (INTVAL (operands[1]) > 0 2659 && INTVAL (operands[1]) <= 8) 2660 return "addq%.w %1,%0"; 2661 if (INTVAL (operands[1]) < 0 2662 && INTVAL (operands[1]) >= -8) 2663 { 2664 operands[1] = GEN_INT (- INTVAL (operands[1])); 2665 return "subq%.w %1,%0"; 2666 } 2667 /* On the CPU32 it is faster to use two addqw instructions to 2668 add a small integer (8 < N <= 16) to a register. 2669 Likewise for subqw. */ 2670 if (TUNE_CPU32 && REG_P (operands[0])) 2671 { 2672 if (INTVAL (operands[1]) > 8 2673 && INTVAL (operands[1]) <= 16) 2674 { 2675 operands[1] = GEN_INT (INTVAL (operands[1]) - 8); 2676 return "addq%.w #8,%0\;addq%.w %1,%0"; 2677 } 2678 if (INTVAL (operands[1]) < -8 2679 && INTVAL (operands[1]) >= -16) 2680 { 2681 operands[1] = GEN_INT (- INTVAL (operands[1]) - 8); 2682 return "subq%.w #8,%0\;subq%.w %1,%0"; 2683 } 2684 } 2685 if (ADDRESS_REG_P (operands[0]) && !TUNE_68040) 2686 return MOTOROLA ? "lea (%c1,%0),%0" : "lea %0@(%c1),%0"; 2687 } 2688 return "add%.w %1,%0"; 2689}) 2690 2691(define_insn "addqi3" 2692 [(set (match_operand:QI 0 "nonimmediate_operand" "=m,d") 2693 (plus:QI (match_operand:QI 1 "general_operand" "%0,0") 2694 (match_operand:QI 2 "general_src_operand" "dn,dmSn")))] 2695 "!TARGET_COLDFIRE" 2696{ 2697 if (GET_CODE (operands[2]) == CONST_INT) 2698 { 2699 if (INTVAL (operands[2]) >= 128) 2700 operands[2] = GEN_INT (INTVAL (operands[2]) - 256); 2701 2702 if (INTVAL (operands[2]) > 0 2703 && INTVAL (operands[2]) <= 8) 2704 return "addq%.b %2,%0"; 2705 if (INTVAL (operands[2]) < 0 && INTVAL (operands[2]) >= -8) 2706 { 2707 operands[2] = GEN_INT (- INTVAL (operands[2])); 2708 return "subq%.b %2,%0"; 2709 } 2710 } 2711 return "add%.b %2,%0"; 2712}) 2713 2714(define_insn "" 2715 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d")) 2716 (plus:QI (match_dup 0) 2717 (match_operand:QI 1 "general_src_operand" "dn,dmSn")))] 2718 "!TARGET_COLDFIRE" 2719{ 2720 if (GET_CODE (operands[1]) == CONST_INT) 2721 { 2722 if (INTVAL (operands[1]) >= 128) 2723 operands[1] = GEN_INT (INTVAL (operands[1]) - 256); 2724 2725 if (INTVAL (operands[1]) > 0 2726 && INTVAL (operands[1]) <= 8) 2727 return "addq%.b %1,%0"; 2728 if (INTVAL (operands[1]) < 0 && INTVAL (operands[1]) >= -8) 2729 { 2730 operands[1] = GEN_INT (- INTVAL (operands[1])); 2731 return "subq%.b %1,%0"; 2732 } 2733 } 2734 return "add%.b %1,%0"; 2735}) 2736 2737(define_insn "" 2738 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d")) 2739 (plus:QI (match_operand:QI 1 "general_src_operand" "dn,dmSn") 2740 (match_dup 0)))] 2741 "!TARGET_COLDFIRE" 2742{ 2743 if (GET_CODE (operands[1]) == CONST_INT) 2744 { 2745 if (INTVAL (operands[1]) >= 128) 2746 operands[1] = GEN_INT (INTVAL (operands[1]) - 256); 2747 2748 if (INTVAL (operands[1]) > 0 2749 && INTVAL (operands[1]) <= 8) 2750 return "addq%.b %1,%0"; 2751 if (INTVAL (operands[1]) < 0 && INTVAL (operands[1]) >= -8) 2752 { 2753 operands[1] = GEN_INT (- INTVAL (operands[1])); 2754 return "subq%.b %1,%0"; 2755 } 2756 } 2757 return "add%.b %1,%0"; 2758}) 2759 2760(define_expand "add<mode>3" 2761 [(set (match_operand:FP 0 "nonimmediate_operand" "") 2762 (plus:FP (match_operand:FP 1 "general_operand" "") 2763 (match_operand:FP 2 "general_operand" "")))] 2764 "TARGET_HARD_FLOAT" 2765 "") 2766 2767(define_insn "add<mode>3_floatsi_68881" 2768 [(set (match_operand:FP 0 "nonimmediate_operand" "=f") 2769 (plus:FP (float:FP (match_operand:SI 2 "general_operand" "dmi")) 2770 (match_operand:FP 1 "general_operand" "0")))] 2771 "TARGET_68881" 2772 "f<FP:round>add%.l %2,%0" 2773 [(set_attr "type" "falu") 2774 (set_attr "opy" "2")]) 2775 2776(define_insn "add<mode>3_floathi_68881" 2777 [(set (match_operand:FP 0 "nonimmediate_operand" "=f") 2778 (plus:FP (float:FP (match_operand:HI 2 "general_operand" "dmn")) 2779 (match_operand:FP 1 "general_operand" "0")))] 2780 "TARGET_68881" 2781 "f<FP:round>add%.w %2,%0" 2782 [(set_attr "type" "falu") 2783 (set_attr "opy" "2")]) 2784 2785(define_insn "add<mode>3_floatqi_68881" 2786 [(set (match_operand:FP 0 "nonimmediate_operand" "=f") 2787 (plus:FP (float:FP (match_operand:QI 2 "general_operand" "dmn")) 2788 (match_operand:FP 1 "general_operand" "0")))] 2789 "TARGET_68881" 2790 "f<FP:round>add%.b %2,%0" 2791 [(set_attr "type" "falu") 2792 (set_attr "opy" "2")]) 2793 2794(define_insn "add<mode>3_68881" 2795 [(set (match_operand:FP 0 "nonimmediate_operand" "=f") 2796 (plus:FP (match_operand:FP 1 "general_operand" "%0") 2797 (match_operand:FP 2 "general_operand" "f<FP:dreg>m<FP:const>")))] 2798 "TARGET_68881" 2799{ 2800 if (FP_REG_P (operands[2])) 2801 return "f<FP:round>add%.x %2,%0"; 2802 return "f<FP:round>add%.<FP:prec> %f2,%0"; 2803} 2804 [(set_attr "type" "falu") 2805 (set_attr "opy" "2")]) 2806 2807(define_insn "add<mode>3_cf" 2808 [(set (match_operand:FP 0 "nonimmediate_operand" "=f") 2809 (plus:FP (match_operand:FP 1 "general_operand" "%0") 2810 (match_operand:FP 2 "general_operand" "f<FP:dreg><Q>U")))] 2811 "TARGET_COLDFIRE_FPU" 2812{ 2813 if (FP_REG_P (operands[2])) 2814 return "f<FP:prec>add%.d %2,%0"; 2815 return "f<FP:prec>add%.<FP:prec> %2,%0"; 2816} 2817 [(set_attr "type" "falu") 2818 (set_attr "opy" "2")]) 2819 2820;; subtract instructions 2821 2822(define_insn "subdi_sexthishl32" 2823 [(set (match_operand:DI 0 "nonimmediate_operand" "=o,a,*d,*d") 2824 (minus:DI (match_operand:DI 1 "general_operand" "0,0,0,0") 2825 (ashift:DI (sign_extend:DI (match_operand:HI 2 "general_operand" "rm,rm,rm,rm")) 2826 (const_int 32)))) 2827 (clobber (match_scratch:SI 3 "=&d,X,a,?d"))] 2828 "!TARGET_COLDFIRE" 2829{ 2830 CC_STATUS_INIT; 2831 if (ADDRESS_REG_P (operands[0])) 2832 return "sub%.w %2,%0"; 2833 else if (ADDRESS_REG_P (operands[3])) 2834 return "move%.w %2,%3\;sub%.l %3,%0"; 2835 else 2836 return "move%.w %2,%3\;ext%.l %3\;sub%.l %3,%0"; 2837}) 2838 2839(define_insn "subdi_dishl32" 2840 [(set (match_operand:DI 0 "nonimmediate_operand" "+ro") 2841 (minus:DI (match_dup 0) 2842 (ashift:DI (match_operand:DI 1 "general_operand" "ro") 2843 (const_int 32))))] 2844 "" 2845{ 2846 CC_STATUS_INIT; 2847 if (GET_CODE (operands[1]) == REG) 2848 operands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1); 2849 else 2850 operands[1] = adjust_address (operands[1], SImode, 4); 2851 return "sub%.l %1,%0"; 2852} 2853 [(set_attr "type" "alu_l")]) 2854 2855(define_insn "subdi3" 2856 [(set (match_operand:DI 0 "nonimmediate_operand" "=o<>,d,d,d") 2857 (minus:DI (match_operand:DI 1 "general_operand" "0,0,0,0") 2858 (match_operand:DI 2 "general_operand" "d,no>,d,a"))) 2859 (clobber (match_scratch:SI 3 "=&d,&d,X,&d"))] 2860 "" 2861{ 2862 if (DATA_REG_P (operands[0])) 2863 { 2864 if (DATA_REG_P (operands[2])) 2865 return "sub%.l %R2,%R0\;subx%.l %2,%0"; 2866 else if (GET_CODE (operands[2]) == MEM 2867 && GET_CODE (XEXP (operands[2], 0)) == POST_INC) 2868 { 2869 return "move%.l %2,%3\;sub%.l %2,%R0\;subx%.l %3,%0"; 2870 } 2871 else 2872 { 2873 rtx high, low; 2874 rtx xoperands[2]; 2875 2876 if (GET_CODE (operands[2]) == REG) 2877 { 2878 low = gen_rtx_REG (SImode, REGNO (operands[2]) + 1); 2879 high = operands[2]; 2880 } 2881 else if (CONSTANT_P (operands[2])) 2882 split_double (operands[2], &high, &low); 2883 else 2884 { 2885 low = adjust_address (operands[2], SImode, 4); 2886 high = operands[2]; 2887 } 2888 2889 operands[1] = low, operands[2] = high; 2890 xoperands[0] = operands[3]; 2891 if (GET_CODE (operands[1]) == CONST_INT 2892 && INTVAL (operands[1]) >= -8 && INTVAL (operands[1]) < 0) 2893 xoperands[1] = GEN_INT (-INTVAL (operands[2]) - 1); 2894 else 2895 xoperands[1] = operands[2]; 2896 2897 output_asm_insn (output_move_simode (xoperands), xoperands); 2898 if (GET_CODE (operands[1]) == CONST_INT) 2899 { 2900 if (INTVAL (operands[1]) > 0 && INTVAL (operands[1]) <= 8) 2901 return "subq%.l %1,%R0\;subx%.l %3,%0"; 2902 else if (INTVAL (operands[1]) >= -8 && INTVAL (operands[1]) < 0) 2903 { 2904 operands[1] = GEN_INT (-INTVAL (operands[1])); 2905 return "addq%.l %1,%R0\;addx%.l %3,%0"; 2906 } 2907 } 2908 return "sub%.l %1,%R0\;subx%.l %3,%0"; 2909 } 2910 } 2911 else 2912 { 2913 gcc_assert (GET_CODE (operands[0]) == MEM); 2914 CC_STATUS_INIT; 2915 if (GET_CODE (XEXP (operands[0], 0)) == POST_INC) 2916 { 2917 operands[1] 2918 = gen_rtx_MEM (SImode, plus_constant (Pmode, 2919 XEXP (operands[0], 0), -8)); 2920 return "move%.l %0,%3\;sub%.l %R2,%0\;subx%.l %2,%3\;move%.l %3,%1"; 2921 } 2922 else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) 2923 { 2924 operands[1] = XEXP(operands[0], 0); 2925 return "sub%.l %R2,%0\;move%.l %0,%3\;subx%.l %2,%3\;move%.l %3,%1"; 2926 } 2927 else 2928 { 2929 operands[1] = adjust_address (operands[0], SImode, 4); 2930 return "sub%.l %R2,%1\;move%.l %0,%3\;subx%.l %2,%3\;move%.l %3,%0"; 2931 } 2932 } 2933}) 2934 2935(define_insn "subsi3" 2936 [(set (match_operand:SI 0 "nonimmediate_operand" "=mda,m,d,a") 2937 (minus:SI (match_operand:SI 1 "general_operand" "0,0,0,0") 2938 (match_operand:SI 2 "general_src_operand" "I,dT,mSrT,mSrs")))] 2939 "" 2940 "@ 2941 subq%.l %2, %0 2942 sub%.l %2,%0 2943 sub%.l %2,%0 2944 sub%.l %2,%0" 2945 [(set_attr "type" "aluq_l,alu_l,alu_l,alu_l") 2946 (set_attr "opy" "2")]) 2947 2948(define_insn "" 2949 [(set (match_operand:SI 0 "nonimmediate_operand" "=a") 2950 (minus:SI (match_operand:SI 1 "general_operand" "0") 2951 (sign_extend:SI 2952 (match_operand:HI 2 "nonimmediate_src_operand" "rmS"))))] 2953 "!TARGET_COLDFIRE" 2954 "sub%.w %2,%0") 2955 2956(define_insn "subhi3" 2957 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,r") 2958 (minus:HI (match_operand:HI 1 "general_operand" "0,0") 2959 (match_operand:HI 2 "general_src_operand" "dn,rmSn")))] 2960 "!TARGET_COLDFIRE" 2961 "sub%.w %2,%0") 2962 2963(define_insn "" 2964 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d")) 2965 (minus:HI (match_dup 0) 2966 (match_operand:HI 1 "general_src_operand" "dn,rmSn")))] 2967 "!TARGET_COLDFIRE" 2968 "sub%.w %1,%0") 2969 2970(define_insn "subqi3" 2971 [(set (match_operand:QI 0 "nonimmediate_operand" "=m,d") 2972 (minus:QI (match_operand:QI 1 "general_operand" "0,0") 2973 (match_operand:QI 2 "general_src_operand" "dn,dmSn")))] 2974 "!TARGET_COLDFIRE" 2975 "sub%.b %2,%0") 2976 2977(define_insn "" 2978 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d")) 2979 (minus:QI (match_dup 0) 2980 (match_operand:QI 1 "general_src_operand" "dn,dmSn")))] 2981 "!TARGET_COLDFIRE" 2982 "sub%.b %1,%0") 2983 2984(define_expand "sub<mode>3" 2985 [(set (match_operand:FP 0 "nonimmediate_operand" "") 2986 (minus:FP (match_operand:FP 1 "general_operand" "") 2987 (match_operand:FP 2 "general_operand" "")))] 2988 "TARGET_HARD_FLOAT" 2989 "") 2990 2991(define_insn "sub<mode>3_floatsi_68881" 2992 [(set (match_operand:FP 0 "nonimmediate_operand" "=f") 2993 (minus:FP (match_operand:FP 1 "general_operand" "0") 2994 (float:FP (match_operand:SI 2 "general_operand" "dmi"))))] 2995 "TARGET_68881" 2996 "f<FP:round>sub%.l %2,%0" 2997 [(set_attr "type" "falu") 2998 (set_attr "opy" "2")]) 2999 3000(define_insn "sub<mode>3_floathi_68881" 3001 [(set (match_operand:FP 0 "nonimmediate_operand" "=f") 3002 (minus:FP (match_operand:FP 1 "general_operand" "0") 3003 (float:FP (match_operand:HI 2 "general_operand" "dmn"))))] 3004 "TARGET_68881" 3005 "f<FP:round>sub%.w %2,%0" 3006 [(set_attr "type" "falu") 3007 (set_attr "opy" "2")]) 3008 3009(define_insn "sub<mode>3_floatqi_68881" 3010 [(set (match_operand:FP 0 "nonimmediate_operand" "=f") 3011 (minus:FP (match_operand:FP 1 "general_operand" "0") 3012 (float:FP (match_operand:QI 2 "general_operand" "dmn"))))] 3013 "TARGET_68881" 3014 "f<FP:round>sub%.b %2,%0" 3015 [(set_attr "type" "falu") 3016 (set_attr "opy" "2")]) 3017 3018(define_insn "sub<mode>3_68881" 3019 [(set (match_operand:FP 0 "nonimmediate_operand" "=f") 3020 (minus:FP (match_operand:FP 1 "general_operand" "0") 3021 (match_operand:FP 2 "general_operand" "f<FP:dreg>m<FP:const>")))] 3022 "TARGET_68881" 3023{ 3024 if (FP_REG_P (operands[2])) 3025 return "f<FP:round>sub%.x %2,%0"; 3026 return "f<FP:round>sub%.<FP:prec> %f2,%0"; 3027} 3028 [(set_attr "type" "falu") 3029 (set_attr "opy" "2")]) 3030 3031(define_insn "sub<mode>3_cf" 3032 [(set (match_operand:FP 0 "nonimmediate_operand" "=f") 3033 (minus:FP (match_operand:FP 1 "general_operand" "0") 3034 (match_operand:FP 2 "general_operand" "f<FP:dreg><Q>U")))] 3035 "TARGET_COLDFIRE_FPU" 3036{ 3037 if (FP_REG_P (operands[2])) 3038 return "f<FP:prec>sub%.d %2,%0"; 3039 return "f<FP:prec>sub%.<FP:prec> %2,%0"; 3040} 3041 [(set_attr "type" "falu") 3042 (set_attr "opy" "2")]) 3043 3044;; multiply instructions 3045 3046(define_insn "mulhi3" 3047 [(set (match_operand:HI 0 "nonimmediate_operand" "=d") 3048 (mult:HI (match_operand:HI 1 "general_operand" "%0") 3049 (match_operand:HI 2 "general_src_operand" "dmSn")))] 3050 "" 3051{ 3052 return MOTOROLA ? "muls%.w %2,%0" : "muls %2,%0"; 3053} 3054 [(set_attr "type" "mul_w") 3055 (set_attr "opy" "2")]) 3056 3057(define_insn "mulhisi3" 3058 [(set (match_operand:SI 0 "nonimmediate_operand" "=d") 3059 (mult:SI (sign_extend:SI 3060 (match_operand:HI 1 "nonimmediate_operand" "%0")) 3061 (sign_extend:SI 3062 (match_operand:HI 2 "nonimmediate_src_operand" "dmS"))))] 3063 "" 3064{ 3065 return MOTOROLA ? "muls%.w %2,%0" : "muls %2,%0"; 3066} 3067 [(set_attr "type" "mul_w") 3068 (set_attr "opy" "2")]) 3069 3070(define_insn "*mulhisisi3_s" 3071 [(set (match_operand:SI 0 "nonimmediate_operand" "=d") 3072 (mult:SI (sign_extend:SI 3073 (match_operand:HI 1 "nonimmediate_operand" "%0")) 3074 (match_operand:SI 2 "const_int_operand" "n")))] 3075 "INTVAL (operands[2]) >= -0x8000 && INTVAL (operands[2]) <= 0x7fff" 3076{ 3077 return MOTOROLA ? "muls%.w %2,%0" : "muls %2,%0"; 3078} 3079 [(set_attr "type" "mul_w") 3080 (set_attr "opy" "2")]) 3081 3082(define_expand "mulsi3" 3083 [(set (match_operand:SI 0 "nonimmediate_operand" "") 3084 (mult:SI (match_operand:SI 1 "general_operand" "") 3085 (match_operand:SI 2 "general_operand" "")))] 3086 "TARGET_68020 || TARGET_COLDFIRE" 3087 "") 3088 3089(define_insn "*mulsi3_68020" 3090 [(set (match_operand:SI 0 "nonimmediate_operand" "=d") 3091 (mult:SI (match_operand:SI 1 "general_operand" "%0") 3092 (match_operand:SI 2 "general_src_operand" "dmSTK")))] 3093 3094 "TARGET_68020" 3095 "muls%.l %2,%0" 3096 [(set_attr "type" "mul_l") 3097 (set_attr "opy" "2")]) 3098 3099(define_insn "*mulsi3_cf" 3100 [(set (match_operand:SI 0 "nonimmediate_operand" "=d") 3101 (mult:SI (match_operand:SI 1 "general_operand" "%0") 3102 (match_operand:SI 2 "general_operand" "d<Q>")))] 3103 "TARGET_COLDFIRE" 3104 "muls%.l %2,%0" 3105 [(set_attr "type" "mul_l") 3106 (set_attr "opy" "2")]) 3107 3108(define_insn "umulhisi3" 3109 [(set (match_operand:SI 0 "nonimmediate_operand" "=d") 3110 (mult:SI (zero_extend:SI 3111 (match_operand:HI 1 "nonimmediate_operand" "%0")) 3112 (zero_extend:SI 3113 (match_operand:HI 2 "nonimmediate_src_operand" "dmS"))))] 3114 "" 3115{ 3116 return MOTOROLA ? "mulu%.w %2,%0" : "mulu %2,%0"; 3117} 3118 [(set_attr "type" "mul_w") 3119 (set_attr "opy" "2")]) 3120 3121(define_insn "*mulhisisi3_z" 3122 [(set (match_operand:SI 0 "nonimmediate_operand" "=d") 3123 (mult:SI (zero_extend:SI 3124 (match_operand:HI 1 "nonimmediate_operand" "%0")) 3125 (match_operand:SI 2 "const_int_operand" "n")))] 3126 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 0xffff" 3127{ 3128 return MOTOROLA ? "mulu%.w %2,%0" : "mulu %2,%0"; 3129} 3130 [(set_attr "type" "mul_w") 3131 (set_attr "opy" "2")]) 3132 3133;; We need a separate DEFINE_EXPAND for u?mulsidi3 to be able to use the 3134;; proper matching constraint. This is because the matching is between 3135;; the high-numbered word of the DImode operand[0] and operand[1]. 3136(define_expand "umulsidi3" 3137 [(parallel 3138 [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 4) 3139 (mult:SI (match_operand:SI 1 "register_operand" "") 3140 (match_operand:SI 2 "register_operand" ""))) 3141 (set (subreg:SI (match_dup 0) 0) 3142 (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1)) 3143 (zero_extend:DI (match_dup 2))) 3144 (const_int 32))))])] 3145 "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE" 3146 "") 3147 3148(define_insn "" 3149 [(set (match_operand:SI 0 "register_operand" "=d") 3150 (mult:SI (match_operand:SI 1 "register_operand" "%0") 3151 (match_operand:SI 2 "nonimmediate_operand" "dm"))) 3152 (set (match_operand:SI 3 "register_operand" "=d") 3153 (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1)) 3154 (zero_extend:DI (match_dup 2))) 3155 (const_int 32))))] 3156 "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE" 3157 "mulu%.l %2,%3:%0") 3158 3159; Match immediate case. For 2.4 only match things < 2^31. 3160; It's tricky with larger values in these patterns since we need to match 3161; values between the two parallel multiplies, between a CONST_DOUBLE and 3162; a CONST_INT. 3163(define_insn "" 3164 [(set (match_operand:SI 0 "register_operand" "=d") 3165 (mult:SI (match_operand:SI 1 "register_operand" "%0") 3166 (match_operand:SI 2 "const_int_operand" "n"))) 3167 (set (match_operand:SI 3 "register_operand" "=d") 3168 (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1)) 3169 (match_dup 2)) 3170 (const_int 32))))] 3171 "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE 3172 && (unsigned) INTVAL (operands[2]) <= 0x7fffffff" 3173 "mulu%.l %2,%3:%0") 3174 3175(define_expand "mulsidi3" 3176 [(parallel 3177 [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 4) 3178 (mult:SI (match_operand:SI 1 "register_operand" "") 3179 (match_operand:SI 2 "register_operand" ""))) 3180 (set (subreg:SI (match_dup 0) 0) 3181 (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1)) 3182 (sign_extend:DI (match_dup 2))) 3183 (const_int 32))))])] 3184 "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE" 3185 "") 3186 3187(define_insn "" 3188 [(set (match_operand:SI 0 "register_operand" "=d") 3189 (mult:SI (match_operand:SI 1 "register_operand" "%0") 3190 (match_operand:SI 2 "nonimmediate_operand" "dm"))) 3191 (set (match_operand:SI 3 "register_operand" "=d") 3192 (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1)) 3193 (sign_extend:DI (match_dup 2))) 3194 (const_int 32))))] 3195 "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE" 3196 "muls%.l %2,%3:%0") 3197 3198(define_insn "" 3199 [(set (match_operand:SI 0 "register_operand" "=d") 3200 (mult:SI (match_operand:SI 1 "register_operand" "%0") 3201 (match_operand:SI 2 "const_int_operand" "n"))) 3202 (set (match_operand:SI 3 "register_operand" "=d") 3203 (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1)) 3204 (match_dup 2)) 3205 (const_int 32))))] 3206 "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE" 3207 "muls%.l %2,%3:%0") 3208 3209(define_expand "umulsi3_highpart" 3210 [(parallel 3211 [(set (match_operand:SI 0 "register_operand" "") 3212 (truncate:SI 3213 (lshiftrt:DI 3214 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "")) 3215 (zero_extend:DI (match_operand:SI 2 "general_operand" ""))) 3216 (const_int 32)))) 3217 (clobber (match_dup 3))])] 3218 "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE" 3219{ 3220 operands[3] = gen_reg_rtx (SImode); 3221 3222 if (GET_CODE (operands[2]) == CONST_INT) 3223 { 3224 operands[2] = immed_double_const (INTVAL (operands[2]) & 0xffffffff, 3225 0, DImode); 3226 3227 /* We have to adjust the operand order for the matching constraints. */ 3228 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[3], 3229 operands[1], operands[2])); 3230 DONE; 3231 } 3232}) 3233 3234(define_insn "" 3235 [(set (match_operand:SI 0 "register_operand" "=d") 3236 (truncate:SI 3237 (lshiftrt:DI 3238 (mult:DI (zero_extend:DI (match_operand:SI 2 "register_operand" "%1")) 3239 (zero_extend:DI (match_operand:SI 3 "nonimmediate_operand" "dm"))) 3240 (const_int 32)))) 3241 (clobber (match_operand:SI 1 "register_operand" "=d"))] 3242 "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE" 3243{ 3244 CC_STATUS_INIT; 3245 return "mulu%.l %3,%0:%1"; 3246}) 3247 3248(define_insn "const_umulsi3_highpart" 3249 [(set (match_operand:SI 0 "register_operand" "=d") 3250 (truncate:SI 3251 (lshiftrt:DI 3252 (mult:DI (zero_extend:DI (match_operand:SI 2 "register_operand" "1")) 3253 (match_operand:DI 3 "const_uint32_operand" "n")) 3254 (const_int 32)))) 3255 (clobber (match_operand:SI 1 "register_operand" "=d"))] 3256 "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE" 3257{ 3258 CC_STATUS_INIT; 3259 return "mulu%.l %3,%0:%1"; 3260}) 3261 3262(define_expand "smulsi3_highpart" 3263 [(parallel 3264 [(set (match_operand:SI 0 "register_operand" "") 3265 (truncate:SI 3266 (lshiftrt:DI 3267 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "")) 3268 (sign_extend:DI (match_operand:SI 2 "general_operand" ""))) 3269 (const_int 32)))) 3270 (clobber (match_dup 3))])] 3271 "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE" 3272{ 3273 operands[3] = gen_reg_rtx (SImode); 3274 if (GET_CODE (operands[2]) == CONST_INT) 3275 { 3276 /* We have to adjust the operand order for the matching constraints. */ 3277 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[3], 3278 operands[1], operands[2])); 3279 DONE; 3280 } 3281}) 3282 3283(define_insn "" 3284 [(set (match_operand:SI 0 "register_operand" "=d") 3285 (truncate:SI 3286 (lshiftrt:DI 3287 (mult:DI (sign_extend:DI (match_operand:SI 2 "register_operand" "%1")) 3288 (sign_extend:DI (match_operand:SI 3 "nonimmediate_operand" "dm"))) 3289 (const_int 32)))) 3290 (clobber (match_operand:SI 1 "register_operand" "=d"))] 3291 "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE" 3292{ 3293 CC_STATUS_INIT; 3294 return "muls%.l %3,%0:%1"; 3295}) 3296 3297(define_insn "const_smulsi3_highpart" 3298 [(set (match_operand:SI 0 "register_operand" "=d") 3299 (truncate:SI 3300 (lshiftrt:DI 3301 (mult:DI (sign_extend:DI (match_operand:SI 2 "register_operand" "1")) 3302 (match_operand:DI 3 "const_sint32_operand" "n")) 3303 (const_int 32)))) 3304 (clobber (match_operand:SI 1 "register_operand" "=d"))] 3305 "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE" 3306{ 3307 CC_STATUS_INIT; 3308 return "muls%.l %3,%0:%1"; 3309}) 3310 3311(define_expand "mul<mode>3" 3312 [(set (match_operand:FP 0 "nonimmediate_operand" "") 3313 (mult:FP (match_operand:FP 1 "general_operand" "") 3314 (match_operand:FP 2 "general_operand" "")))] 3315 "TARGET_HARD_FLOAT" 3316 "") 3317 3318(define_insn "mul<mode>3_floatsi_68881" 3319 [(set (match_operand:FP 0 "nonimmediate_operand" "=f") 3320 (mult:FP (float:FP (match_operand:SI 2 "general_operand" "dmi")) 3321 (match_operand:FP 1 "general_operand" "0")))] 3322 "TARGET_68881" 3323{ 3324 return TARGET_68040 3325 ? "f<FP:round>mul%.l %2,%0" 3326 : "f<FP:round_mul>mul%.l %2,%0"; 3327} 3328 [(set_attr "type" "fmul") 3329 (set_attr "opy" "2")]) 3330 3331(define_insn "mul<mode>3_floathi_68881" 3332 [(set (match_operand:FP 0 "nonimmediate_operand" "=f") 3333 (mult:FP (float:FP (match_operand:HI 2 "general_operand" "dmn")) 3334 (match_operand:FP 1 "general_operand" "0")))] 3335 "TARGET_68881" 3336{ 3337 return TARGET_68040 3338 ? "f<FP:round>mul%.w %2,%0" 3339 : "f<FP:round_mul>mul%.w %2,%0"; 3340} 3341 [(set_attr "type" "fmul") 3342 (set_attr "opy" "2")]) 3343 3344(define_insn "mul<mode>3_floatqi_68881" 3345 [(set (match_operand:FP 0 "nonimmediate_operand" "=f") 3346 (mult:FP (float:FP (match_operand:QI 2 "general_operand" "dmn")) 3347 (match_operand:FP 1 "general_operand" "0")))] 3348 "TARGET_68881" 3349{ 3350 return TARGET_68040 3351 ? "f<FP:round>mul%.b %2,%0" 3352 : "f<FP:round_mul>mul%.b %2,%0"; 3353} 3354 [(set_attr "type" "fmul") 3355 (set_attr "opy" "2")]) 3356 3357(define_insn "muldf_68881" 3358 [(set (match_operand:DF 0 "nonimmediate_operand" "=f") 3359 (mult:DF (match_operand:DF 1 "general_operand" "%0") 3360 (match_operand:DF 2 "general_operand" "fmG")))] 3361 "TARGET_68881" 3362{ 3363 if (GET_CODE (operands[2]) == CONST_DOUBLE 3364 && floating_exact_log2 (operands[2]) && !TUNE_68040_60) 3365 { 3366 int i = floating_exact_log2 (operands[2]); 3367 operands[2] = GEN_INT (i); 3368 return "fscale%.l %2,%0"; 3369 } 3370 if (REG_P (operands[2])) 3371 return "f%&mul%.x %2,%0"; 3372 return "f%&mul%.d %f2,%0"; 3373}) 3374 3375(define_insn "mulsf_68881" 3376 [(set (match_operand:SF 0 "nonimmediate_operand" "=f") 3377 (mult:SF (match_operand:SF 1 "general_operand" "%0") 3378 (match_operand:SF 2 "general_operand" "fdmF")))] 3379 "TARGET_68881" 3380{ 3381 if (FP_REG_P (operands[2])) 3382 return (TARGET_68040 3383 ? "fsmul%.x %2,%0" 3384 : "fsglmul%.x %2,%0"); 3385 return (TARGET_68040 3386 ? "fsmul%.s %f2,%0" 3387 : "fsglmul%.s %f2,%0"); 3388}) 3389 3390(define_insn "mulxf3_68881" 3391 [(set (match_operand:XF 0 "nonimmediate_operand" "=f") 3392 (mult:XF (match_operand:XF 1 "nonimmediate_operand" "%0") 3393 (match_operand:XF 2 "nonimmediate_operand" "fm")))] 3394 "TARGET_68881" 3395{ 3396 return "fmul%.x %f2,%0"; 3397}) 3398 3399(define_insn "fmul<mode>3_cf" 3400 [(set (match_operand:FP 0 "nonimmediate_operand" "=f") 3401 (mult:FP (match_operand:FP 1 "general_operand" "%0") 3402 (match_operand:FP 2 "general_operand" "f<Q>U<FP:dreg>")))] 3403 "TARGET_COLDFIRE_FPU" 3404{ 3405 if (FP_REG_P (operands[2])) 3406 return "f<FP:prec>mul%.d %2,%0"; 3407 return "f<FP:prec>mul%.<FP:prec> %2,%0"; 3408} 3409 [(set_attr "type" "fmul") 3410 (set_attr "opy" "2")]) 3411 3412;; divide instructions 3413 3414(define_expand "div<mode>3" 3415 [(set (match_operand:FP 0 "nonimmediate_operand" "") 3416 (div:FP (match_operand:FP 1 "general_operand" "") 3417 (match_operand:FP 2 "general_operand" "")))] 3418 "TARGET_HARD_FLOAT" 3419 "") 3420 3421(define_insn "div<mode>3_floatsi_68881" 3422 [(set (match_operand:FP 0 "nonimmediate_operand" "=f") 3423 (div:FP (match_operand:FP 1 "general_operand" "0") 3424 (float:FP (match_operand:SI 2 "general_operand" "dmi"))))] 3425 "TARGET_68881" 3426{ 3427 return TARGET_68040 3428 ? "f<FP:round>div%.l %2,%0" 3429 : "f<FP:round_mul>div%.l %2,%0"; 3430}) 3431 3432(define_insn "div<mode>3_floathi_68881" 3433 [(set (match_operand:FP 0 "nonimmediate_operand" "=f") 3434 (div:FP (match_operand:FP 1 "general_operand" "0") 3435 (float:FP (match_operand:HI 2 "general_operand" "dmn"))))] 3436 "TARGET_68881" 3437{ 3438 return TARGET_68040 3439 ? "f<FP:round>div%.w %2,%0" 3440 : "f<FP:round_mul>div%.w %2,%0"; 3441}) 3442 3443(define_insn "div<mode>3_floatqi_68881" 3444 [(set (match_operand:FP 0 "nonimmediate_operand" "=f") 3445 (div:FP (match_operand:FP 1 "general_operand" "0") 3446 (float:FP (match_operand:QI 2 "general_operand" "dmn"))))] 3447 "TARGET_68881" 3448{ 3449 return TARGET_68040 3450 ? "f<FP:round>div%.b %2,%0" 3451 : "f<FP:round_mul>div%.b %2,%0"; 3452}) 3453 3454(define_insn "div<mode>3_68881" 3455 [(set (match_operand:FP 0 "nonimmediate_operand" "=f") 3456 (div:FP (match_operand:FP 1 "general_operand" "0") 3457 (match_operand:FP 2 "general_operand" "f<FP:dreg>m<FP:const>")))] 3458 "TARGET_68881" 3459{ 3460 if (FP_REG_P (operands[2])) 3461 return (TARGET_68040 3462 ? "f<FP:round>div%.x %2,%0" 3463 : "f<FP:round_mul>div%.x %2,%0"); 3464 return (TARGET_68040 3465 ? "f<FP:round>div%.<FP:prec> %f2,%0" 3466 : "f<FP:round_mul>div%.<FP:prec> %f2,%0"); 3467}) 3468 3469(define_insn "div<mode>3_cf" 3470 [(set (match_operand:FP 0 "nonimmediate_operand" "=f") 3471 (div:FP (match_operand:FP 1 "general_operand" "0") 3472 (match_operand:FP 2 "general_operand" "f<Q>U<FP:dreg>")))] 3473 "TARGET_COLDFIRE_FPU" 3474{ 3475 if (FP_REG_P (operands[2])) 3476 return "f<FP:prec>div%.d %2,%0"; 3477 return "f<FP:prec>div%.<FP:prec> %2,%0"; 3478} 3479 [(set_attr "type" "fdiv") 3480 (set_attr "opy" "2")]) 3481 3482;; Remainder instructions. 3483 3484(define_expand "divmodsi4" 3485 [(parallel 3486 [(set (match_operand:SI 0 "nonimmediate_operand" "") 3487 (div:SI (match_operand:SI 1 "general_operand" "") 3488 (match_operand:SI 2 "general_src_operand" ""))) 3489 (set (match_operand:SI 3 "nonimmediate_operand" "") 3490 (mod:SI (match_dup 1) (match_dup 2)))])] 3491 "TARGET_68020 || TARGET_CF_HWDIV" 3492 "") 3493 3494(define_insn "" 3495 [(set (match_operand:SI 0 "nonimmediate_operand" "=d") 3496 (div:SI (match_operand:SI 1 "general_operand" "0") 3497 (match_operand:SI 2 "general_src_operand" "d<Q>U"))) 3498 (set (match_operand:SI 3 "nonimmediate_operand" "=&d") 3499 (mod:SI (match_dup 1) (match_dup 2)))] 3500 "TARGET_CF_HWDIV" 3501{ 3502 if (find_reg_note (insn, REG_UNUSED, operands[3])) 3503 return "divs%.l %2,%0"; 3504 else if (find_reg_note (insn, REG_UNUSED, operands[0])) 3505 return "rems%.l %2,%3:%0"; 3506 else 3507 return "rems%.l %2,%3:%0\;divs%.l %2,%0"; 3508} 3509 [(set_attr "type" "div_l") 3510 (set_attr "opy" "2")]) 3511 3512(define_insn "" 3513 [(set (match_operand:SI 0 "nonimmediate_operand" "=d") 3514 (div:SI (match_operand:SI 1 "general_operand" "0") 3515 (match_operand:SI 2 "general_src_operand" "dmSTK"))) 3516 (set (match_operand:SI 3 "nonimmediate_operand" "=d") 3517 (mod:SI (match_dup 1) (match_dup 2)))] 3518 "TARGET_68020" 3519{ 3520 if (find_reg_note (insn, REG_UNUSED, operands[3])) 3521 return "divs%.l %2,%0"; 3522 else 3523 return "divsl%.l %2,%3:%0"; 3524}) 3525 3526(define_expand "udivmodsi4" 3527 [(parallel 3528 [(set (match_operand:SI 0 "nonimmediate_operand" "=d") 3529 (udiv:SI (match_operand:SI 1 "general_operand" "0") 3530 (match_operand:SI 2 "general_src_operand" "dmSTK"))) 3531 (set (match_operand:SI 3 "nonimmediate_operand" "=d") 3532 (umod:SI (match_dup 1) (match_dup 2)))])] 3533 "TARGET_68020 || TARGET_CF_HWDIV" 3534 "") 3535 3536(define_insn "" 3537 [(set (match_operand:SI 0 "nonimmediate_operand" "=d") 3538 (udiv:SI (match_operand:SI 1 "general_operand" "0") 3539 (match_operand:SI 2 "general_src_operand" "d<Q>U"))) 3540 (set (match_operand:SI 3 "nonimmediate_operand" "=&d") 3541 (umod:SI (match_dup 1) (match_dup 2)))] 3542 "TARGET_CF_HWDIV" 3543{ 3544 if (find_reg_note (insn, REG_UNUSED, operands[3])) 3545 return "divu%.l %2,%0"; 3546 else if (find_reg_note (insn, REG_UNUSED, operands[0])) 3547 return "remu%.l %2,%3:%0"; 3548 else 3549 return "remu%.l %2,%3:%0\;divu%.l %2,%0"; 3550} 3551 [(set_attr "type" "div_l") 3552 (set_attr "opy" "2")]) 3553 3554(define_insn "" 3555 [(set (match_operand:SI 0 "nonimmediate_operand" "=d") 3556 (udiv:SI (match_operand:SI 1 "general_operand" "0") 3557 (match_operand:SI 2 "general_src_operand" "dmSTK"))) 3558 (set (match_operand:SI 3 "nonimmediate_operand" "=d") 3559 (umod:SI (match_dup 1) (match_dup 2)))] 3560 "TARGET_68020 && !TARGET_COLDFIRE" 3561{ 3562 if (find_reg_note (insn, REG_UNUSED, operands[3])) 3563 return "divu%.l %2,%0"; 3564 else 3565 return "divul%.l %2,%3:%0"; 3566}) 3567 3568(define_insn "divmodhi4" 3569 [(set (match_operand:HI 0 "nonimmediate_operand" "=d") 3570 (div:HI (match_operand:HI 1 "general_operand" "0") 3571 (match_operand:HI 2 "general_src_operand" "dmSKT"))) 3572 (set (match_operand:HI 3 "nonimmediate_operand" "=d") 3573 (mod:HI (match_dup 1) (match_dup 2)))] 3574 "!TARGET_COLDFIRE || TARGET_CF_HWDIV" 3575{ 3576 output_asm_insn (MOTOROLA ? 3577 "ext%.l %0\;divs%.w %2,%0" : 3578 "extl %0\;divs %2,%0", 3579 operands); 3580 if (!find_reg_note(insn, REG_UNUSED, operands[3])) 3581 { 3582 CC_STATUS_INIT; 3583 return "move%.l %0,%3\;swap %3"; 3584 } 3585 else 3586 return ""; 3587}) 3588 3589(define_insn "udivmodhi4" 3590 [(set (match_operand:HI 0 "nonimmediate_operand" "=d") 3591 (udiv:HI (match_operand:HI 1 "general_operand" "0") 3592 (match_operand:HI 2 "general_src_operand" "dmSKT"))) 3593 (set (match_operand:HI 3 "nonimmediate_operand" "=d") 3594 (umod:HI (match_dup 1) (match_dup 2)))] 3595 "!TARGET_COLDFIRE || TARGET_CF_HWDIV" 3596{ 3597 if (ISA_HAS_MVS_MVZ) 3598 output_asm_insn (MOTOROLA ? 3599 "mvz%.w %0,%0\;divu%.w %2,%0" : 3600 "mvz%.w %0,%0\;divu %2,%0", 3601 operands); 3602 else 3603 output_asm_insn (MOTOROLA ? 3604 "and%.l #0xFFFF,%0\;divu%.w %2,%0" : 3605 "and%.l #0xFFFF,%0\;divu %2,%0", 3606 operands); 3607 3608 if (!find_reg_note(insn, REG_UNUSED, operands[3])) 3609 { 3610 CC_STATUS_INIT; 3611 return "move%.l %0,%3\;swap %3"; 3612 } 3613 else 3614 return ""; 3615}) 3616 3617;; logical-and instructions 3618 3619;; Prevent AND from being made with sp. This doesn't exist in the machine 3620;; and reload will cause inefficient code. Since sp is a FIXED_REG, we 3621;; can't allocate pseudos into it. 3622 3623(define_expand "andsi3" 3624 [(set (match_operand:SI 0 "not_sp_operand" "") 3625 (and:SI (match_operand:SI 1 "general_operand" "") 3626 (match_operand:SI 2 "general_src_operand" "")))] 3627 "" 3628 "") 3629 3630;; produced by split operations after reload finished 3631(define_insn "*andsi3_split" 3632 [(set (match_operand:SI 0 "register_operand" "=d") 3633 (and:SI (match_operand:SI 1 "register_operand" "0") 3634 (match_operand:SI 2 "const_int_operand" "i")))] 3635 "reload_completed && !TARGET_COLDFIRE" 3636{ 3637 return output_andsi3 (operands); 3638}) 3639 3640(define_insn "andsi3_internal" 3641 [(set (match_operand:SI 0 "not_sp_operand" "=m,d") 3642 (and:SI (match_operand:SI 1 "general_operand" "%0,0") 3643 (match_operand:SI 2 "general_src_operand" "dKT,dmSM")))] 3644 "!TARGET_COLDFIRE" 3645{ 3646 return output_andsi3 (operands); 3647}) 3648 3649(define_insn "andsi3_5200" 3650 [(set (match_operand:SI 0 "not_sp_operand" "=m,d") 3651 (and:SI (match_operand:SI 1 "general_operand" "%0,0") 3652 (match_operand:SI 2 "general_src_operand" "d,dmsK")))] 3653 "TARGET_COLDFIRE" 3654{ 3655 if (ISA_HAS_MVS_MVZ 3656 && DATA_REG_P (operands[0]) 3657 && GET_CODE (operands[2]) == CONST_INT) 3658 { 3659 if (INTVAL (operands[2]) == 0x000000ff) 3660 return "mvz%.b %0,%0"; 3661 else if (INTVAL (operands[2]) == 0x0000ffff) 3662 return "mvz%.w %0,%0"; 3663 } 3664 return output_andsi3 (operands); 3665}) 3666 3667(define_insn "andhi3" 3668 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,d") 3669 (and:HI (match_operand:HI 1 "general_operand" "%0,0") 3670 (match_operand:HI 2 "general_src_operand" "dn,dmSn")))] 3671 "!TARGET_COLDFIRE" 3672 "and%.w %2,%0") 3673 3674(define_insn "" 3675 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d")) 3676 (and:HI (match_dup 0) 3677 (match_operand:HI 1 "general_src_operand" "dn,dmSn")))] 3678 "!TARGET_COLDFIRE" 3679 "and%.w %1,%0") 3680 3681(define_insn "" 3682 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d")) 3683 (and:HI (match_operand:HI 1 "general_src_operand" "dn,dmSn") 3684 (match_dup 0)))] 3685 "!TARGET_COLDFIRE" 3686 "and%.w %1,%0") 3687 3688(define_insn "andqi3" 3689 [(set (match_operand:QI 0 "nonimmediate_operand" "=m,d") 3690 (and:QI (match_operand:QI 1 "general_operand" "%0,0") 3691 (match_operand:QI 2 "general_src_operand" "dn,dmSn")))] 3692 "!TARGET_COLDFIRE" 3693 "and%.b %2,%0") 3694 3695(define_insn "" 3696 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d")) 3697 (and:QI (match_dup 0) 3698 (match_operand:QI 1 "general_src_operand" "dn,dmSn")))] 3699 "!TARGET_COLDFIRE" 3700 "and%.b %1,%0") 3701 3702(define_insn "" 3703 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d")) 3704 (and:QI (match_operand:QI 1 "general_src_operand" "dn,dmSn") 3705 (match_dup 0)))] 3706 "!TARGET_COLDFIRE" 3707 "and%.b %1,%0") 3708 3709;; inclusive-or instructions 3710 3711(define_insn "iordi_zext" 3712 [(set (match_operand:DI 0 "nonimmediate_operand" "=o,d") 3713 (ior:DI (zero_extend:DI (match_operand 1 "general_operand" "dn,dmn")) 3714 (match_operand:DI 2 "general_operand" "0,0")))] 3715 "!TARGET_COLDFIRE" 3716{ 3717 int byte_mode; 3718 3719 CC_STATUS_INIT; 3720 if (GET_CODE (operands[0]) == REG) 3721 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); 3722 else 3723 operands[0] = adjust_address (operands[0], SImode, 4); 3724 if (GET_MODE (operands[1]) == SImode) 3725 return "or%.l %1,%0"; 3726 byte_mode = (GET_MODE (operands[1]) == QImode); 3727 if (GET_CODE (operands[0]) == MEM) 3728 operands[0] = adjust_address (operands[0], byte_mode ? QImode : HImode, 3729 byte_mode ? 3 : 2); 3730 if (byte_mode) 3731 return "or%.b %1,%0"; 3732 else 3733 return "or%.w %1,%0"; 3734}) 3735 3736(define_expand "iorsi3" 3737 [(set (match_operand:SI 0 "nonimmediate_operand" "") 3738 (ior:SI (match_operand:SI 1 "general_operand" "") 3739 (match_operand:SI 2 "general_src_operand" "")))] 3740 "" 3741 "") 3742 3743(define_insn "iorsi3_internal" 3744 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,d") 3745 (ior:SI (match_operand:SI 1 "general_operand" "%0,0") 3746 (match_operand:SI 2 "general_src_operand" "dKT,dmSMT")))] 3747 "! TARGET_COLDFIRE" 3748{ 3749 return output_iorsi3 (operands); 3750}) 3751 3752(define_insn "iorsi3_5200" 3753 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,d") 3754 (ior:SI (match_operand:SI 1 "general_operand" "%0,0") 3755 (match_operand:SI 2 "general_src_operand" "d,dmsK")))] 3756 "TARGET_COLDFIRE" 3757{ 3758 return output_iorsi3 (operands); 3759}) 3760 3761(define_insn "iorhi3" 3762 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,d") 3763 (ior:HI (match_operand:HI 1 "general_operand" "%0,0") 3764 (match_operand:HI 2 "general_src_operand" "dn,dmSn")))] 3765 "!TARGET_COLDFIRE" 3766 "or%.w %2,%0") 3767 3768(define_insn "" 3769 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d")) 3770 (ior:HI (match_dup 0) 3771 (match_operand:HI 1 "general_src_operand" "dn,dmSn")))] 3772 "!TARGET_COLDFIRE" 3773 "or%.w %1,%0") 3774 3775(define_insn "" 3776 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d")) 3777 (ior:HI (match_operand:HI 1 "general_src_operand" "dn,dmSn") 3778 (match_dup 0)))] 3779 "!TARGET_COLDFIRE" 3780 "or%.w %1,%0") 3781 3782(define_insn "iorqi3" 3783 [(set (match_operand:QI 0 "nonimmediate_operand" "=m,d") 3784 (ior:QI (match_operand:QI 1 "general_operand" "%0,0") 3785 (match_operand:QI 2 "general_src_operand" "dn,dmSn")))] 3786 "!TARGET_COLDFIRE" 3787 "or%.b %2,%0") 3788 3789(define_insn "" 3790 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d")) 3791 (ior:QI (match_dup 0) 3792 (match_operand:QI 1 "general_src_operand" "dn,dmSn")))] 3793 "!TARGET_COLDFIRE" 3794 "or%.b %1,%0") 3795 3796(define_insn "" 3797 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d")) 3798 (ior:QI (match_operand:QI 1 "general_src_operand" "dn,dmSn") 3799 (match_dup 0)))] 3800 "!TARGET_COLDFIRE" 3801 "or%.b %1,%0") 3802 3803;; On all 68k models, this makes faster code in a special case. 3804;; See also ashlsi_16, ashrsi_16 and lshrsi_16. 3805 3806(define_insn "iorsi_zexthi_ashl16" 3807 [(set (match_operand:SI 0 "nonimmediate_operand" "=&d") 3808 (ior:SI (zero_extend:SI (match_operand:HI 1 "general_operand" "rmn")) 3809 (ashift:SI (match_operand:SI 2 "general_operand" "or") 3810 (const_int 16))))] 3811 "" 3812{ 3813 CC_STATUS_INIT; 3814 if (GET_CODE (operands[2]) != REG) 3815 operands[2] = adjust_address (operands[2], HImode, 2); 3816 if (GET_CODE (operands[2]) != REG 3817 || REGNO (operands[2]) != REGNO (operands[0])) 3818 output_asm_insn ("move%.w %2,%0", operands); 3819 return "swap %0\;mov%.w %1,%0"; 3820}) 3821 3822(define_insn "iorsi_zext" 3823 [(set (match_operand:SI 0 "nonimmediate_operand" "=o,d") 3824 (ior:SI (zero_extend:SI (match_operand 1 "general_operand" "dn,dmn")) 3825 (match_operand:SI 2 "general_operand" "0,0")))] 3826 "!TARGET_COLDFIRE" 3827{ 3828 int byte_mode; 3829 3830 CC_STATUS_INIT; 3831 byte_mode = (GET_MODE (operands[1]) == QImode); 3832 if (GET_CODE (operands[0]) == MEM) 3833 operands[0] = adjust_address (operands[0], byte_mode ? QImode : HImode, 3834 byte_mode ? 3 : 2); 3835 if (byte_mode) 3836 return "or%.b %1,%0"; 3837 else 3838 return "or%.w %1,%0"; 3839}) 3840 3841;; xor instructions 3842 3843(define_expand "xorsi3" 3844 [(set (match_operand:SI 0 "nonimmediate_operand" "") 3845 (xor:SI (match_operand:SI 1 "general_operand" "") 3846 (match_operand:SI 2 "general_operand" "")))] 3847 "" 3848 "") 3849 3850(define_insn "xorsi3_internal" 3851 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,o,m") 3852 (xor:SI (match_operand:SI 1 "general_operand" "%0, 0,0") 3853 (match_operand:SI 2 "general_operand" "di,dK,dKT")))] 3854 3855 "!TARGET_COLDFIRE" 3856{ 3857 return output_xorsi3 (operands); 3858}) 3859 3860(define_insn "xorsi3_5200" 3861 [(set (match_operand:SI 0 "nonimmediate_operand" "=dm,d") 3862 (xor:SI (match_operand:SI 1 "general_operand" "%0,0") 3863 (match_operand:SI 2 "general_operand" "d,Ks")))] 3864 "TARGET_COLDFIRE" 3865{ 3866 return output_xorsi3 (operands); 3867}) 3868 3869(define_insn "xorhi3" 3870 [(set (match_operand:HI 0 "nonimmediate_operand" "=dm") 3871 (xor:HI (match_operand:HI 1 "general_operand" "%0") 3872 (match_operand:HI 2 "general_operand" "dn")))] 3873 "!TARGET_COLDFIRE" 3874 "eor%.w %2,%0") 3875 3876(define_insn "" 3877 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+dm")) 3878 (xor:HI (match_dup 0) 3879 (match_operand:HI 1 "general_operand" "dn")))] 3880 "!TARGET_COLDFIRE" 3881 "eor%.w %1,%0") 3882 3883(define_insn "" 3884 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+dm")) 3885 (xor:HI (match_operand:HI 1 "general_operand" "dn") 3886 (match_dup 0)))] 3887 "!TARGET_COLDFIRE" 3888 "eor%.w %1,%0") 3889 3890(define_insn "xorqi3" 3891 [(set (match_operand:QI 0 "nonimmediate_operand" "=dm") 3892 (xor:QI (match_operand:QI 1 "general_operand" "%0") 3893 (match_operand:QI 2 "general_operand" "dn")))] 3894 "!TARGET_COLDFIRE" 3895 "eor%.b %2,%0") 3896 3897(define_insn "" 3898 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+dm")) 3899 (xor:QI (match_dup 0) 3900 (match_operand:QI 1 "general_operand" "dn")))] 3901 "!TARGET_COLDFIRE" 3902 "eor%.b %1,%0") 3903 3904(define_insn "" 3905 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+dm")) 3906 (xor:QI (match_operand:QI 1 "general_operand" "dn") 3907 (match_dup 0)))] 3908 "!TARGET_COLDFIRE" 3909 "eor%.b %1,%0") 3910 3911;; negation instructions 3912 3913(define_expand "negdi2" 3914 [(set (match_operand:DI 0 "nonimmediate_operand" "") 3915 (neg:DI (match_operand:DI 1 "general_operand" "")))] 3916 "" 3917{ 3918 if (TARGET_COLDFIRE) 3919 emit_insn (gen_negdi2_5200 (operands[0], operands[1])); 3920 else 3921 emit_insn (gen_negdi2_internal (operands[0], operands[1])); 3922 DONE; 3923}) 3924 3925(define_insn "negdi2_internal" 3926 [(set (match_operand:DI 0 "nonimmediate_operand" "=<,do,!*a") 3927 (neg:DI (match_operand:DI 1 "general_operand" "0,0,0")))] 3928 "!TARGET_COLDFIRE" 3929{ 3930 if (which_alternative == 0) 3931 return "neg%.l %0\;negx%.l %0"; 3932 if (GET_CODE (operands[0]) == REG) 3933 operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); 3934 else 3935 operands[1] = adjust_address (operands[0], SImode, 4); 3936 if (ADDRESS_REG_P (operands[0])) 3937 return "exg %/d0,%1\;neg%.l %/d0\;exg %/d0,%1\;exg %/d0,%0\;negx%.l %/d0\;exg %/d0,%0"; 3938 else 3939 return "neg%.l %1\;negx%.l %0"; 3940}) 3941 3942(define_insn "negdi2_5200" 3943 [(set (match_operand:DI 0 "nonimmediate_operand" "=d") 3944 (neg:DI (match_operand:DI 1 "general_operand" "0")))] 3945 "TARGET_COLDFIRE" 3946{ 3947 operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); 3948 return "neg%.l %1\;negx%.l %0"; 3949}) 3950 3951(define_expand "negsi2" 3952 [(set (match_operand:SI 0 "nonimmediate_operand" "") 3953 (neg:SI (match_operand:SI 1 "general_operand" "")))] 3954 "" 3955{ 3956 if (TARGET_COLDFIRE) 3957 emit_insn (gen_negsi2_5200 (operands[0], operands[1])); 3958 else 3959 emit_insn (gen_negsi2_internal (operands[0], operands[1])); 3960 DONE; 3961}) 3962 3963(define_insn "negsi2_internal" 3964 [(set (match_operand:SI 0 "nonimmediate_operand" "=dm") 3965 (neg:SI (match_operand:SI 1 "general_operand" "0")))] 3966 "!TARGET_COLDFIRE" 3967 "neg%.l %0" 3968 [(set_attr "type" "neg_l")]) 3969 3970(define_insn "negsi2_5200" 3971 [(set (match_operand:SI 0 "nonimmediate_operand" "=d") 3972 (neg:SI (match_operand:SI 1 "general_operand" "0")))] 3973 "TARGET_COLDFIRE" 3974 "neg%.l %0" 3975 [(set_attr "type" "neg_l")]) 3976 3977(define_insn "neghi2" 3978 [(set (match_operand:HI 0 "nonimmediate_operand" "=dm") 3979 (neg:HI (match_operand:HI 1 "general_operand" "0")))] 3980 "!TARGET_COLDFIRE" 3981 "neg%.w %0") 3982 3983(define_insn "" 3984 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+dm")) 3985 (neg:HI (match_dup 0)))] 3986 "!TARGET_COLDFIRE" 3987 "neg%.w %0") 3988 3989(define_insn "negqi2" 3990 [(set (match_operand:QI 0 "nonimmediate_operand" "=dm") 3991 (neg:QI (match_operand:QI 1 "general_operand" "0")))] 3992 "!TARGET_COLDFIRE" 3993 "neg%.b %0") 3994 3995(define_insn "" 3996 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+dm")) 3997 (neg:QI (match_dup 0)))] 3998 "!TARGET_COLDFIRE" 3999 "neg%.b %0") 4000 4001;; If using software floating point, just flip the sign bit. 4002 4003(define_expand "negsf2" 4004 [(set (match_operand:SF 0 "nonimmediate_operand" "") 4005 (neg:SF (match_operand:SF 1 "general_operand" "")))] 4006 "" 4007{ 4008 if (!TARGET_HARD_FLOAT) 4009 { 4010 rtx result; 4011 rtx target; 4012 4013 target = operand_subword_force (operands[0], 0, SFmode); 4014 result = expand_binop (SImode, xor_optab, 4015 operand_subword_force (operands[1], 0, SFmode), 4016 GEN_INT (-2147483647 - 1), target, 0, OPTAB_WIDEN); 4017 gcc_assert (result); 4018 4019 if (result != target) 4020 emit_move_insn (result, target); 4021 4022 /* Make a place for REG_EQUAL. */ 4023 emit_move_insn (operands[0], operands[0]); 4024 DONE; 4025 } 4026}) 4027 4028(define_expand "negdf2" 4029 [(set (match_operand:DF 0 "nonimmediate_operand" "") 4030 (neg:DF (match_operand:DF 1 "general_operand" "")))] 4031 "" 4032{ 4033 if (!TARGET_HARD_FLOAT) 4034 { 4035 rtx result; 4036 rtx target; 4037 rtx insns; 4038 4039 start_sequence (); 4040 target = operand_subword (operands[0], 0, 1, DFmode); 4041 result = expand_binop (SImode, xor_optab, 4042 operand_subword_force (operands[1], 0, DFmode), 4043 GEN_INT (-2147483647 - 1), target, 0, OPTAB_WIDEN); 4044 gcc_assert (result); 4045 4046 if (result != target) 4047 emit_move_insn (result, target); 4048 4049 emit_move_insn (operand_subword (operands[0], 1, 1, DFmode), 4050 operand_subword_force (operands[1], 1, DFmode)); 4051 4052 insns = get_insns (); 4053 end_sequence (); 4054 4055 emit_insn (insns); 4056 DONE; 4057 } 4058}) 4059 4060(define_expand "negxf2" 4061 [(set (match_operand:XF 0 "nonimmediate_operand" "") 4062 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))] 4063 "" 4064{ 4065 if (!TARGET_68881) 4066 { 4067 rtx result; 4068 rtx target; 4069 rtx insns; 4070 4071 start_sequence (); 4072 target = operand_subword (operands[0], 0, 1, XFmode); 4073 result = expand_binop (SImode, xor_optab, 4074 operand_subword_force (operands[1], 0, XFmode), 4075 GEN_INT (-2147483647 - 1), target, 0, OPTAB_WIDEN); 4076 gcc_assert (result); 4077 4078 if (result != target) 4079 emit_move_insn (result, target); 4080 4081 emit_move_insn (operand_subword (operands[0], 1, 1, XFmode), 4082 operand_subword_force (operands[1], 1, XFmode)); 4083 emit_move_insn (operand_subword (operands[0], 2, 1, XFmode), 4084 operand_subword_force (operands[1], 2, XFmode)); 4085 4086 insns = get_insns (); 4087 end_sequence (); 4088 4089 emit_insn (insns); 4090 DONE; 4091 } 4092}) 4093 4094(define_insn "neg<mode>2_68881" 4095 [(set (match_operand:FP 0 "nonimmediate_operand" "=f,d") 4096 (neg:FP (match_operand:FP 1 "general_operand" "f<FP:dreg>m<FP:const>,0")))] 4097 "TARGET_68881" 4098{ 4099 if (DATA_REG_P (operands[0])) 4100 { 4101 operands[1] = GEN_INT (31); 4102 return "bchg %1,%0"; 4103 } 4104 if (FP_REG_P (operands[1])) 4105 return "f<FP:round>neg%.x %1,%0"; 4106 return "f<FP:round>neg%.<FP:prec> %f1,%0"; 4107}) 4108 4109(define_insn "neg<mode>2_cf" 4110 [(set (match_operand:FP 0 "nonimmediate_operand" "=f,d") 4111 (neg:FP (match_operand:FP 1 "general_operand" "f<FP:dreg><Q>U,0")))] 4112 "TARGET_COLDFIRE_FPU" 4113{ 4114 if (DATA_REG_P (operands[0])) 4115 { 4116 operands[1] = GEN_INT (31); 4117 return "bchg %1,%0"; 4118 } 4119 if (FP_REG_P (operands[1])) 4120 return "f<FP:prec>neg%.d %1,%0"; 4121 return "f<FP:prec>neg%.<FP:prec> %1,%0"; 4122}) 4123 4124;; Sqrt instruction for the 68881 4125 4126(define_expand "sqrt<mode>2" 4127 [(set (match_operand:FP 0 "nonimmediate_operand" "") 4128 (sqrt:FP (match_operand:FP 1 "general_operand" "")))] 4129 "TARGET_HARD_FLOAT" 4130 "") 4131 4132(define_insn "sqrt<mode>2_68881" 4133 [(set (match_operand:FP 0 "nonimmediate_operand" "=f") 4134 (sqrt:FP (match_operand:FP 1 "general_operand" "f<FP:dreg>m")))] 4135 "TARGET_68881" 4136{ 4137 if (FP_REG_P (operands[1])) 4138 return "f<FP:round>sqrt%.x %1,%0"; 4139 return "f<FP:round>sqrt%.<FP:prec> %1,%0"; 4140} 4141 [(set_attr "type" "fsqrt")]) 4142 4143(define_insn "sqrt<mode>2_cf" 4144 [(set (match_operand:FP 0 "nonimmediate_operand" "=f") 4145 (sqrt:FP (match_operand:FP 1 "general_operand" "f<FP:dreg><Q>U")))] 4146 "TARGET_COLDFIRE_FPU" 4147{ 4148 if (FP_REG_P (operands[1])) 4149 return "f<FP:prec>sqrt%.d %1,%0"; 4150 return "f<FP:prec>sqrt%.<FP:prec> %1,%0"; 4151} 4152 [(set_attr "type" "fsqrt")]) 4153;; Absolute value instructions 4154;; If using software floating point, just zero the sign bit. 4155 4156(define_expand "abssf2" 4157 [(set (match_operand:SF 0 "nonimmediate_operand" "") 4158 (abs:SF (match_operand:SF 1 "general_operand" "")))] 4159 "" 4160{ 4161 if (!TARGET_HARD_FLOAT) 4162 { 4163 rtx result; 4164 rtx target; 4165 4166 target = operand_subword_force (operands[0], 0, SFmode); 4167 result = expand_binop (SImode, and_optab, 4168 operand_subword_force (operands[1], 0, SFmode), 4169 GEN_INT (0x7fffffff), target, 0, OPTAB_WIDEN); 4170 gcc_assert (result); 4171 4172 if (result != target) 4173 emit_move_insn (result, target); 4174 4175 /* Make a place for REG_EQUAL. */ 4176 emit_move_insn (operands[0], operands[0]); 4177 DONE; 4178 } 4179}) 4180 4181(define_expand "absdf2" 4182 [(set (match_operand:DF 0 "nonimmediate_operand" "") 4183 (abs:DF (match_operand:DF 1 "general_operand" "")))] 4184 "" 4185{ 4186 if (!TARGET_HARD_FLOAT) 4187 { 4188 rtx result; 4189 rtx target; 4190 rtx insns; 4191 4192 start_sequence (); 4193 target = operand_subword (operands[0], 0, 1, DFmode); 4194 result = expand_binop (SImode, and_optab, 4195 operand_subword_force (operands[1], 0, DFmode), 4196 GEN_INT (0x7fffffff), target, 0, OPTAB_WIDEN); 4197 gcc_assert (result); 4198 4199 if (result != target) 4200 emit_move_insn (result, target); 4201 4202 emit_move_insn (operand_subword (operands[0], 1, 1, DFmode), 4203 operand_subword_force (operands[1], 1, DFmode)); 4204 4205 insns = get_insns (); 4206 end_sequence (); 4207 4208 emit_insn (insns); 4209 DONE; 4210 } 4211}) 4212 4213(define_expand "absxf2" 4214 [(set (match_operand:XF 0 "nonimmediate_operand" "") 4215 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))] 4216 "" 4217{ 4218 if (!TARGET_68881) 4219 { 4220 rtx result; 4221 rtx target; 4222 rtx insns; 4223 4224 start_sequence (); 4225 target = operand_subword (operands[0], 0, 1, XFmode); 4226 result = expand_binop (SImode, and_optab, 4227 operand_subword_force (operands[1], 0, XFmode), 4228 GEN_INT (0x7fffffff), target, 0, OPTAB_WIDEN); 4229 gcc_assert (result); 4230 4231 if (result != target) 4232 emit_move_insn (result, target); 4233 4234 emit_move_insn (operand_subword (operands[0], 1, 1, XFmode), 4235 operand_subword_force (operands[1], 1, XFmode)); 4236 emit_move_insn (operand_subword (operands[0], 2, 1, XFmode), 4237 operand_subword_force (operands[1], 2, XFmode)); 4238 4239 insns = get_insns (); 4240 end_sequence (); 4241 4242 emit_insn (insns); 4243 DONE; 4244 } 4245}) 4246 4247(define_insn "abs<mode>2_68881" 4248 [(set (match_operand:FP 0 "nonimmediate_operand" "=f,d") 4249 (abs:FP (match_operand:FP 1 "general_operand" "f<FP:dreg>m<FP:const>,0")))] 4250 "TARGET_68881" 4251{ 4252 if (DATA_REG_P (operands[0])) 4253 { 4254 operands[1] = GEN_INT (31); 4255 return "bclr %1,%0"; 4256 } 4257 if (FP_REG_P (operands[1])) 4258 return "f<FP:round>abs%.x %1,%0"; 4259 return "f<FP:round>abs%.<FP:prec> %f1,%0"; 4260}) 4261 4262(define_insn "abs<mode>2_cf" 4263 [(set (match_operand:FP 0 "nonimmediate_operand" "=f,d") 4264 (abs:FP (match_operand:FP 1 "general_operand" "f<FP:dreg><Q>U,0")))] 4265 "TARGET_COLDFIRE_FPU" 4266{ 4267 if (DATA_REG_P (operands[0])) 4268 { 4269 operands[1] = GEN_INT (31); 4270 return "bclr %1,%0"; 4271 } 4272 if (FP_REG_P (operands[1])) 4273 return "f<FP:prec>abs%.d %1,%0"; 4274 return "f<FP:prec>abs%.<FP:prec> %1,%0"; 4275} 4276 [(set_attr "type" "bitrw,fneg")]) 4277 4278;; bit indexing instructions 4279 4280(define_expand "clzsi2" 4281 [(set (match_operand:SI 0 "register_operand" "") 4282 (clz:SI (match_operand:SI 1 "general_operand" "")))] 4283 "ISA_HAS_FF1 || (TARGET_68020 && TARGET_BITFIELD)" 4284{ 4285 if (ISA_HAS_FF1) 4286 operands[1] = force_reg (SImode, operands[1]); 4287}) 4288 4289(define_insn "*clzsi2_68k" 4290 [(set (match_operand:SI 0 "register_operand" "=d") 4291 (clz:SI (match_operand:SI 1 "general_operand" "do")))] 4292 "TARGET_68020 && TARGET_BITFIELD" 4293{ 4294 CC_STATUS_INIT; 4295 return "bfffo %1{#0:#0},%0"; 4296}) 4297 4298;; ColdFire ff1 instruction implements clz. 4299(define_insn "*clzsi2_cf" 4300 [(set (match_operand:SI 0 "register_operand" "=d") 4301 (clz:SI (match_operand:SI 1 "register_operand" "0")))] 4302 "ISA_HAS_FF1" 4303{ 4304 CC_STATUS_INIT; 4305 return "ff1 %0"; 4306} 4307 [(set_attr "type" "ext")]) 4308 4309;; one complement instructions 4310 4311(define_expand "one_cmplsi2" 4312 [(set (match_operand:SI 0 "nonimmediate_operand" "") 4313 (not:SI (match_operand:SI 1 "general_operand" "")))] 4314 "" 4315{ 4316 if (TARGET_COLDFIRE) 4317 emit_insn (gen_one_cmplsi2_5200 (operands[0], operands[1])); 4318 else 4319 emit_insn (gen_one_cmplsi2_internal (operands[0], operands[1])); 4320 DONE; 4321}) 4322 4323(define_insn "one_cmplsi2_internal" 4324 [(set (match_operand:SI 0 "nonimmediate_operand" "=dm") 4325 (not:SI (match_operand:SI 1 "general_operand" "0")))] 4326 "!TARGET_COLDFIRE" 4327 "not%.l %0") 4328 4329(define_insn "one_cmplsi2_5200" 4330 [(set (match_operand:SI 0 "nonimmediate_operand" "=d") 4331 (not:SI (match_operand:SI 1 "general_operand" "0")))] 4332 "TARGET_COLDFIRE" 4333 "not%.l %0" 4334 [(set_attr "type" "neg_l")]) 4335 4336(define_insn "one_cmplhi2" 4337 [(set (match_operand:HI 0 "nonimmediate_operand" "=dm") 4338 (not:HI (match_operand:HI 1 "general_operand" "0")))] 4339 "!TARGET_COLDFIRE" 4340 "not%.w %0") 4341 4342(define_insn "" 4343 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+dm")) 4344 (not:HI (match_dup 0)))] 4345 "!TARGET_COLDFIRE" 4346 "not%.w %0") 4347 4348(define_insn "one_cmplqi2" 4349 [(set (match_operand:QI 0 "nonimmediate_operand" "=dm") 4350 (not:QI (match_operand:QI 1 "general_operand" "0")))] 4351 "!TARGET_COLDFIRE" 4352 "not%.b %0") 4353 4354(define_insn "" 4355 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+dm")) 4356 (not:QI (match_dup 0)))] 4357 "!TARGET_COLDFIRE" 4358 "not%.b %0") 4359 4360;; arithmetic shift instructions 4361;; We don't need the shift memory by 1 bit instruction 4362(define_insn_and_split "ashldi_extsi" 4363 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro") 4364 (ashift:DI 4365 (match_operator:DI 2 "extend_operator" 4366 [(match_operand:SI 1 "general_operand" "rm")]) 4367 (const_int 32)))] 4368 "" 4369 "#" 4370 "&& reload_completed" 4371 [(set (match_dup 3) (match_dup 1)) 4372 (set (match_dup 2) (const_int 0))] 4373 "split_di(operands, 1, operands + 2, operands + 3);") 4374 4375(define_insn "ashldi_sexthi" 4376 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,a*d") 4377 (ashift:DI (sign_extend:DI (match_operand:HI 1 "general_operand" "rm,rm")) 4378 (const_int 32))) 4379 (clobber (match_scratch:SI 2 "=a,X"))] 4380 "" 4381{ 4382 CC_STATUS_INIT; 4383 if (GET_CODE (operands[0]) == MEM) 4384 { 4385 if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) 4386 return "clr%.l %0\;move%.w %1,%2\;move%.l %2,%0"; 4387 else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC) 4388 return "move%.w %1,%2\;move%.l %2,%0\;clr%.l %0"; 4389 else 4390 { 4391 operands[3] = adjust_address (operands[0], SImode, 4); 4392 return "move%.w %1,%2\;move%.l %2,%0\;clr%.l %3"; 4393 } 4394 } 4395 else if (DATA_REG_P (operands[0])) 4396 return "move%.w %1,%0\;ext%.l %0\;clr%.l %R0"; 4397 else 4398 return "move%.w %1,%0\;sub%.l %R0,%R0"; 4399}) 4400 4401(define_insn "*ashldi3_const1" 4402 [(set (match_operand:DI 0 "register_operand" "=d") 4403 (ashift:DI (match_operand:DI 1 "register_operand" "0") 4404 (const_int 1)))] 4405 "!TARGET_COLDFIRE" 4406 "add%.l %R0,%R0\;addx%.l %0,%0") 4407 4408(define_split 4409 [(set (match_operand:DI 0 "register_operand" "") 4410 (ashift:DI (match_operand:DI 1 "register_operand" "") 4411 (const_int 2)))] 4412 "reload_completed && !TARGET_COLDFIRE" 4413 [(set (match_dup 0) 4414 (ashift:DI (match_dup 1) (const_int 1))) 4415 (set (match_dup 0) 4416 (ashift:DI (match_dup 0) (const_int 1)))] 4417 "") 4418 4419(define_split 4420 [(set (match_operand:DI 0 "register_operand" "") 4421 (ashift:DI (match_operand:DI 1 "register_operand" "") 4422 (const_int 3)))] 4423 "reload_completed && !TARGET_COLDFIRE" 4424 [(set (match_dup 0) 4425 (ashift:DI (match_dup 1) (const_int 2))) 4426 (set (match_dup 0) 4427 (ashift:DI (match_dup 0) (const_int 1)))] 4428 "") 4429 4430(define_split 4431 [(set (match_operand:DI 0 "register_operand" "") 4432 (ashift:DI (match_operand:DI 1 "register_operand" "") 4433 (const_int 8)))] 4434 "reload_completed && !TARGET_COLDFIRE" 4435 [(set (match_dup 2) 4436 (rotate:SI (match_dup 2) (const_int 8))) 4437 (set (match_dup 3) 4438 (rotate:SI (match_dup 3) (const_int 8))) 4439 (set (strict_low_part (subreg:QI (match_dup 0) 3)) 4440 (subreg:QI (match_dup 0) 7)) 4441 (set (strict_low_part (subreg:QI (match_dup 0) 7)) 4442 (const_int 0))] 4443{ 4444 operands[2] = gen_highpart (SImode, operands[0]); 4445 operands[3] = gen_lowpart (SImode, operands[0]); 4446}) 4447 4448(define_split 4449 [(set (match_operand:DI 0 "register_operand" "") 4450 (ashift:DI (match_operand:DI 1 "register_operand" "") 4451 (const_int 16)))] 4452 "reload_completed && !TARGET_COLDFIRE" 4453 [(set (match_dup 2) 4454 (rotate:SI (match_dup 2) (const_int 16))) 4455 (set (match_dup 3) 4456 (rotate:SI (match_dup 3) (const_int 16))) 4457 (set (strict_low_part (subreg:HI (match_dup 0) 2)) 4458 (subreg:HI (match_dup 0) 6)) 4459 (set (strict_low_part (subreg:HI (match_dup 0) 6)) 4460 (const_int 0))] 4461{ 4462 operands[2] = gen_highpart (SImode, operands[0]); 4463 operands[3] = gen_lowpart (SImode, operands[0]); 4464}) 4465 4466(define_split 4467 [(set (match_operand:DI 0 "pre_dec_operand" "") 4468 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "") 4469 (const_int 32)))] 4470 "reload_completed" 4471 [(set (match_dup 0) (const_int 0)) 4472 (set (match_dup 0) (match_dup 1))] 4473{ 4474 operands[0] = adjust_address(operands[0], SImode, 0); 4475 operands[1] = gen_lowpart(SImode, operands[1]); 4476}) 4477 4478(define_split 4479 [(set (match_operand:DI 0 "post_inc_operand" "") 4480 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "") 4481 (const_int 32)))] 4482 "reload_completed" 4483 [(set (match_dup 0) (match_dup 1)) 4484 (set (match_dup 0) (const_int 0))] 4485{ 4486 operands[0] = adjust_address(operands[0], SImode, 0); 4487 operands[1] = gen_lowpart(SImode, operands[1]); 4488}) 4489 4490(define_insn_and_split "*ashldi3_const32" 4491 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro<>") 4492 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "ro") 4493 (const_int 32)))] 4494 "" 4495 "#" 4496 "&& reload_completed" 4497 [(set (match_dup 4) (match_dup 3)) 4498 (set (match_dup 2) (const_int 0))] 4499 "split_di(operands, 2, operands + 2, operands + 4);") 4500 4501(define_split 4502 [(set (match_operand:DI 0 "register_operand" "") 4503 (ashift:DI (match_operand:DI 1 "register_operand" "") 4504 (match_operand 2 "const_int_operand" "")))] 4505 "reload_completed && !TARGET_COLDFIRE 4506 && INTVAL (operands[2]) > 32 && INTVAL (operands[2]) <= 40" 4507 [(set (match_dup 4) (ashift:SI (match_dup 4) (match_dup 2))) 4508 (set (match_dup 3) (match_dup 4)) 4509 (set (match_dup 4) (const_int 0))] 4510{ 4511 operands[2] = GEN_INT (INTVAL (operands[2]) - 32); 4512 operands[3] = gen_highpart (SImode, operands[0]); 4513 operands[4] = gen_lowpart (SImode, operands[0]); 4514}) 4515 4516(define_split 4517 [(set (match_operand:DI 0 "register_operand" "") 4518 (ashift:DI (match_operand:DI 1 "register_operand" "") 4519 (const_int 48)))] 4520 "reload_completed && !TARGET_COLDFIRE" 4521 [(set (match_dup 2) (match_dup 3)) 4522 (set (match_dup 2) 4523 (rotate:SI (match_dup 2) (const_int 16))) 4524 (set (match_dup 3) (const_int 0)) 4525 (set (strict_low_part (subreg:HI (match_dup 0) 2)) 4526 (const_int 0))] 4527{ 4528 operands[2] = gen_highpart (SImode, operands[0]); 4529 operands[3] = gen_lowpart (SImode, operands[0]); 4530}) 4531 4532(define_split 4533 [(set (match_operand:DI 0 "register_operand" "") 4534 (ashift:DI (match_operand:DI 1 "register_operand" "") 4535 (match_operand 2 "const_int_operand" "")))] 4536 "reload_completed && !TARGET_COLDFIRE 4537 && INTVAL (operands[2]) > 40 && INTVAL (operands[2]) <= 63" 4538 [(set (match_dup 3) (match_dup 2)) 4539 (set (match_dup 4) (ashift:SI (match_dup 4) (match_dup 3))) 4540 (set (match_dup 3) (match_dup 4)) 4541 (set (match_dup 4) (const_int 0))] 4542{ 4543 operands[2] = GEN_INT (INTVAL (operands[2]) - 32); 4544 operands[3] = gen_highpart (SImode, operands[0]); 4545 operands[4] = gen_lowpart (SImode, operands[0]); 4546}) 4547 4548(define_insn "*ashldi3" 4549 [(set (match_operand:DI 0 "register_operand" "=d") 4550 (ashift:DI (match_operand:DI 1 "register_operand" "0") 4551 (match_operand 2 "const_int_operand" "n")))] 4552 "!TARGET_COLDFIRE 4553 && ((INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3) 4554 || INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16 4555 || (INTVAL (operands[2]) > 32 && INTVAL (operands[2]) <= 63))" 4556 "#") 4557 4558(define_expand "ashldi3" 4559 [(set (match_operand:DI 0 "register_operand" "") 4560 (ashift:DI (match_operand:DI 1 "register_operand" "") 4561 (match_operand:SI 2 "const_int_operand" "")))] 4562 "!TARGET_COLDFIRE" 4563{ 4564 /* ??? This is a named pattern like this is not allowed to FAIL based 4565 on its operands. */ 4566 if (GET_CODE (operands[2]) != CONST_INT 4567 || ((INTVAL (operands[2]) < 1 || INTVAL (operands[2]) > 3) 4568 && INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16 4569 && (INTVAL (operands[2]) < 32 || INTVAL (operands[2]) > 63))) 4570 FAIL; 4571}) 4572 4573;; On most 68k models, this makes faster code in a special case. 4574 4575(define_insn "ashlsi_16" 4576 [(set (match_operand:SI 0 "register_operand" "=d") 4577 (ashift:SI (match_operand:SI 1 "register_operand" "0") 4578 (const_int 16)))] 4579 "!TUNE_68060" 4580{ 4581 CC_STATUS_INIT; 4582 return "swap %0\;clr%.w %0"; 4583}) 4584 4585;; ashift patterns : use lsl instead of asl, because lsl always clears the 4586;; overflow bit, so we must not set CC_NO_OVERFLOW. 4587 4588;; On the 68000, this makes faster code in a special case. 4589 4590(define_insn "ashlsi_17_24" 4591 [(set (match_operand:SI 0 "register_operand" "=d") 4592 (ashift:SI (match_operand:SI 1 "register_operand" "0") 4593 (match_operand:SI 2 "const_int_operand" "n")))] 4594 "TUNE_68000_10 4595 && INTVAL (operands[2]) > 16 4596 && INTVAL (operands[2]) <= 24" 4597{ 4598 CC_STATUS_INIT; 4599 4600 operands[2] = GEN_INT (INTVAL (operands[2]) - 16); 4601 return "lsl%.w %2,%0\;swap %0\;clr%.w %0"; 4602}) 4603 4604(define_insn "ashlsi3" 4605 [(set (match_operand:SI 0 "register_operand" "=d") 4606 (ashift:SI (match_operand:SI 1 "register_operand" "0") 4607 (match_operand:SI 2 "general_operand" "dI")))] 4608 "" 4609{ 4610 if (operands[2] == const1_rtx) 4611 { 4612 cc_status.flags = CC_NO_OVERFLOW; 4613 return "add%.l %0,%0"; 4614 } 4615 return "lsl%.l %2,%0"; 4616}) 4617 4618(define_insn "ashlhi3" 4619 [(set (match_operand:HI 0 "register_operand" "=d") 4620 (ashift:HI (match_operand:HI 1 "register_operand" "0") 4621 (match_operand:HI 2 "general_operand" "dI")))] 4622 "!TARGET_COLDFIRE" 4623 "lsl%.w %2,%0") 4624 4625(define_insn "" 4626 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d")) 4627 (ashift:HI (match_dup 0) 4628 (match_operand:HI 1 "general_operand" "dI")))] 4629 "!TARGET_COLDFIRE" 4630 "lsl%.w %1,%0") 4631 4632(define_insn "ashlqi3" 4633 [(set (match_operand:QI 0 "register_operand" "=d") 4634 (ashift:QI (match_operand:QI 1 "register_operand" "0") 4635 (match_operand:QI 2 "general_operand" "dI")))] 4636 "!TARGET_COLDFIRE" 4637 "lsl%.b %2,%0") 4638 4639(define_insn "" 4640 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d")) 4641 (ashift:QI (match_dup 0) 4642 (match_operand:QI 1 "general_operand" "dI")))] 4643 "!TARGET_COLDFIRE" 4644 "lsl%.b %1,%0") 4645 4646;; On most 68k models, this makes faster code in a special case. 4647 4648(define_insn "ashrsi_16" 4649 [(set (match_operand:SI 0 "register_operand" "=d") 4650 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") 4651 (const_int 16)))] 4652 "!TUNE_68060" 4653 "swap %0\;ext%.l %0") 4654 4655;; On the 68000, this makes faster code in a special case. 4656 4657(define_insn "" 4658 [(set (match_operand:SI 0 "register_operand" "=d") 4659 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") 4660 (match_operand:SI 2 "const_int_operand" "n")))] 4661 "TUNE_68000_10 4662 && INTVAL (operands[2]) > 16 4663 && INTVAL (operands[2]) <= 24" 4664{ 4665 operands[2] = GEN_INT (INTVAL (operands[2]) - 16); 4666 return "swap %0\;asr%.w %2,%0\;ext%.l %0"; 4667}) 4668 4669(define_insn "subreghi1ashrdi_const32" 4670 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 4671 (subreg:HI (ashiftrt:DI (match_operand:DI 1 "general_operand" "ro") 4672 (const_int 32)) 6))] 4673 "" 4674{ 4675 if (GET_CODE (operands[1]) != REG) 4676 operands[1] = adjust_address (operands[1], HImode, 2); 4677 return "move%.w %1,%0"; 4678} 4679 [(set_attr "type" "move")]) 4680 4681(define_insn "subregsi1ashrdi_const32" 4682 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 4683 (subreg:SI (ashiftrt:DI (match_operand:DI 1 "general_operand" "ro") 4684 (const_int 32)) 4))] 4685 "" 4686{ 4687 return "move%.l %1,%0"; 4688} 4689 [(set_attr "type" "move_l")]) 4690 4691(define_insn "*ashrdi3_const1" 4692 [(set (match_operand:DI 0 "register_operand" "=d") 4693 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0") 4694 (const_int 1)))] 4695 "!TARGET_COLDFIRE" 4696{ 4697 operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); 4698 CC_STATUS_INIT; 4699 return "asr%.l #1,%0\;roxr%.l #1,%1"; 4700}) 4701 4702(define_split 4703 [(set (match_operand:DI 0 "register_operand" "") 4704 (ashiftrt:DI (match_operand:DI 1 "register_operand" "") 4705 (const_int 2)))] 4706 "reload_completed && !TARGET_COLDFIRE" 4707 [(set (match_dup 0) 4708 (ashiftrt:DI (match_dup 1) (const_int 1))) 4709 (set (match_dup 0) 4710 (ashiftrt:DI (match_dup 0) (const_int 1)))] 4711 "") 4712 4713(define_split 4714 [(set (match_operand:DI 0 "register_operand" "") 4715 (ashiftrt:DI (match_operand:DI 1 "register_operand" "") 4716 (const_int 3)))] 4717 "reload_completed && !TARGET_COLDFIRE" 4718 [(set (match_dup 0) 4719 (ashiftrt:DI (match_dup 1) (const_int 2))) 4720 (set (match_dup 0) 4721 (ashiftrt:DI (match_dup 0) (const_int 1)))] 4722 "") 4723 4724(define_split 4725 [(set (match_operand:DI 0 "register_operand" "") 4726 (ashiftrt:DI (match_operand:DI 1 "register_operand" "") 4727 (const_int 8)))] 4728 "reload_completed && !TARGET_COLDFIRE" 4729 [(set (strict_low_part (subreg:QI (match_dup 0) 7)) 4730 (subreg:QI (match_dup 0) 3)) 4731 (set (match_dup 2) 4732 (ashiftrt:SI (match_dup 2) (const_int 8))) 4733 (set (match_dup 3) 4734 (rotatert:SI (match_dup 3) (const_int 8)))] 4735{ 4736 operands[2] = gen_highpart (SImode, operands[0]); 4737 operands[3] = gen_lowpart (SImode, operands[0]); 4738}) 4739 4740(define_split 4741 [(set (match_operand:DI 0 "register_operand" "") 4742 (ashiftrt:DI (match_operand:DI 1 "register_operand" "") 4743 (const_int 16)))] 4744 "reload_completed && !TARGET_COLDFIRE" 4745 [(set (strict_low_part (subreg:HI (match_dup 0) 6)) 4746 (subreg:HI (match_dup 0) 2)) 4747 (set (match_dup 2) 4748 (rotate:SI (match_dup 2) (const_int 16))) 4749 (set (match_dup 3) 4750 (rotate:SI (match_dup 3) (const_int 16))) 4751 (set (match_dup 2) 4752 (sign_extend:SI (subreg:HI (match_dup 2) 2)))] 4753{ 4754 operands[2] = gen_highpart (SImode, operands[0]); 4755 operands[3] = gen_lowpart (SImode, operands[0]); 4756}) 4757 4758(define_insn "*ashrdi_const32" 4759 [(set (match_operand:DI 0 "register_operand" "=d") 4760 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_src_operand" "ro") 4761 (const_int 32)))] 4762 "" 4763{ 4764 CC_STATUS_INIT; 4765 if (TARGET_68020) 4766 return "move%.l %1,%R0\;smi %0\;extb%.l %0"; 4767 else 4768 return "move%.l %1,%R0\;smi %0\;ext%.w %0\;ext%.l %0"; 4769}) 4770 4771(define_insn "*ashrdi_const32_mem" 4772 [(set (match_operand:DI 0 "memory_operand" "=o,<") 4773 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_src_operand" "ro,ro") 4774 (const_int 32))) 4775 (clobber (match_scratch:SI 2 "=d,d"))] 4776 "" 4777{ 4778 CC_STATUS_INIT; 4779 operands[3] = adjust_address (operands[0], SImode, 4780 which_alternative == 0 ? 4 : 0); 4781 operands[0] = adjust_address (operands[0], SImode, 0); 4782 if (TARGET_68020 || TARGET_COLDFIRE) 4783 return "move%.l %1,%3\;smi %2\;extb%.l %2\;move%.l %2,%0"; 4784 else 4785 return "move%.l %1,%3\;smi %2\;ext%.w %2\;ext%.l %2\;move%.l %2,%0"; 4786}) 4787 4788(define_split 4789 [(set (match_operand:DI 0 "register_operand" "") 4790 (ashiftrt:DI (match_operand:DI 1 "register_operand" "") 4791 (const_int 63)))] 4792 "reload_completed && !TARGET_COLDFIRE" 4793 [(set (match_dup 3) 4794 (ashiftrt:SI (match_dup 3) (const_int 31))) 4795 (set (match_dup 2) 4796 (match_dup 3))] 4797 "split_di(operands, 1, operands + 2, operands + 3);") 4798 4799;; The predicate below must be general_operand, because ashrdi3 allows that 4800(define_insn "ashrdi_const" 4801 [(set (match_operand:DI 0 "register_operand" "=d") 4802 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0") 4803 (match_operand 2 "const_int_operand" "n")))] 4804 "!TARGET_COLDFIRE 4805 && ((INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3) 4806 || INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16 4807 || INTVAL (operands[2]) == 31 4808 || (INTVAL (operands[2]) > 32 && INTVAL (operands[2]) <= 63))" 4809{ 4810 operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); 4811 CC_STATUS_INIT; 4812 if (INTVAL (operands[2]) == 48) 4813 return "swap %0\;ext%.l %0\;move%.l %0,%1\;smi %0\;ext%.w %0"; 4814 if (INTVAL (operands[2]) == 31) 4815 return "add%.l %1,%1\;addx%.l %0,%0\;move%.l %0,%1\;subx%.l %0,%0"; 4816 if (INTVAL (operands[2]) > 32 && INTVAL (operands[2]) <= 63) 4817 { 4818 operands[2] = GEN_INT (INTVAL (operands[2]) - 32); 4819 output_asm_insn (INTVAL (operands[2]) <= 8 ? "asr%.l %2,%0" : 4820 "moveq %2,%1\;asr%.l %1,%0", operands); 4821 output_asm_insn ("mov%.l %0,%1\;smi %0", operands); 4822 return INTVAL (operands[2]) >= 15 ? "ext%.w %d0" : 4823 TARGET_68020 ? "extb%.l %0" : "ext%.w %0\;ext%.l %0"; 4824 } 4825 return "#"; 4826}) 4827 4828(define_expand "ashrdi3" 4829 [(set (match_operand:DI 0 "register_operand" "") 4830 (ashiftrt:DI (match_operand:DI 1 "register_operand" "") 4831 (match_operand:SI 2 "const_int_operand" "")))] 4832 "!TARGET_COLDFIRE" 4833{ 4834 /* ??? This is a named pattern like this is not allowed to FAIL based 4835 on its operands. */ 4836 if (GET_CODE (operands[2]) != CONST_INT 4837 || ((INTVAL (operands[2]) < 1 || INTVAL (operands[2]) > 3) 4838 && INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16 4839 && (INTVAL (operands[2]) < 31 || INTVAL (operands[2]) > 63))) 4840 FAIL; 4841}) 4842 4843;; On all 68k models, this makes faster code in a special case. 4844 4845(define_insn "ashrsi_31" 4846 [(set (match_operand:SI 0 "register_operand" "=d") 4847 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") 4848 (const_int 31)))] 4849 "" 4850{ 4851 return "add%.l %0,%0\;subx%.l %0,%0"; 4852}) 4853 4854(define_insn "ashrsi3" 4855 [(set (match_operand:SI 0 "register_operand" "=d") 4856 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") 4857 (match_operand:SI 2 "general_operand" "dI")))] 4858 "" 4859 "asr%.l %2,%0" 4860 [(set_attr "type" "shift") 4861 (set_attr "opy" "2")]) 4862 4863(define_insn "ashrhi3" 4864 [(set (match_operand:HI 0 "register_operand" "=d") 4865 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0") 4866 (match_operand:HI 2 "general_operand" "dI")))] 4867 "!TARGET_COLDFIRE" 4868 "asr%.w %2,%0") 4869 4870(define_insn "" 4871 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d")) 4872 (ashiftrt:HI (match_dup 0) 4873 (match_operand:HI 1 "general_operand" "dI")))] 4874 "!TARGET_COLDFIRE" 4875 "asr%.w %1,%0") 4876 4877(define_insn "ashrqi3" 4878 [(set (match_operand:QI 0 "register_operand" "=d") 4879 (ashiftrt:QI (match_operand:QI 1 "register_operand" "0") 4880 (match_operand:QI 2 "general_operand" "dI")))] 4881 "!TARGET_COLDFIRE" 4882 "asr%.b %2,%0") 4883 4884(define_insn "" 4885 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d")) 4886 (ashiftrt:QI (match_dup 0) 4887 (match_operand:QI 1 "general_operand" "dI")))] 4888 "!TARGET_COLDFIRE" 4889 "asr%.b %1,%0") 4890 4891;; logical shift instructions 4892 4893;; commented out because of reload problems in 950612-1.c 4894;;(define_insn "" 4895;; [(set (cc0) 4896;; (subreg:SI (lshiftrt:DI (match_operand:DI 0 "general_operand" "ro") 4897;; (const_int 32)) 4)) 4898;; (set (match_operand:SI 1 "nonimmediate_operand" "=dm") 4899;; (subreg:SI (lshiftrt:DI (match_dup 0) 4900;; (const_int 32)) 4))] 4901;; "" 4902;;{ 4903;; return "move%.l %0,%1"; 4904;;}) 4905;; 4906;;(define_insn "" 4907;; [(set (cc0) 4908;; (subreg:SI (lshiftrt:DI (match_operand:DI 0 "general_operand" "ro") 4909;; (const_int 32)) 0)) 4910;; (set (match_operand:DI 1 "nonimmediate_operand" "=do") 4911;; (lshiftrt:DI (match_dup 0) 4912;; (const_int 32)))] 4913;; "" 4914;;{ 4915;; if (GET_CODE (operands[1]) == REG) 4916;; operands[2] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1); 4917;; else 4918;; operands[2] = adjust_address (operands[1], SImode, 4); 4919;; return "move%.l %0,%2\;clr%.l %1"; 4920;;}) 4921 4922(define_insn "subreg1lshrdi_const32" 4923 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 4924 (subreg:SI (lshiftrt:DI (match_operand:DI 1 "general_operand" "ro") 4925 (const_int 32)) 4))] 4926 "" 4927 "move%.l %1,%0" 4928 [(set_attr "type" "move_l")]) 4929 4930(define_insn "*lshrdi3_const1" 4931 [(set (match_operand:DI 0 "register_operand" "=d") 4932 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0") 4933 (const_int 1)))] 4934 "!TARGET_COLDFIRE" 4935{ 4936 CC_STATUS_INIT; 4937 return "lsr%.l #1,%0\;roxr%.l #1,%R0"; 4938}) 4939 4940(define_split 4941 [(set (match_operand:DI 0 "register_operand" "") 4942 (lshiftrt:DI (match_operand:DI 1 "register_operand" "") 4943 (const_int 2)))] 4944 "reload_completed && !TARGET_COLDFIRE" 4945 [(set (match_dup 0) 4946 (lshiftrt:DI (match_dup 1) (const_int 1))) 4947 (set (match_dup 0) 4948 (lshiftrt:DI (match_dup 0) (const_int 1)))] 4949 "") 4950 4951(define_split 4952 [(set (match_operand:DI 0 "register_operand" "") 4953 (lshiftrt:DI (match_operand:DI 1 "register_operand" "") 4954 (const_int 3)))] 4955 "reload_completed && !TARGET_COLDFIRE" 4956 [(set (match_dup 0) 4957 (lshiftrt:DI (match_dup 1) (const_int 2))) 4958 (set (match_dup 0) 4959 (lshiftrt:DI (match_dup 0) (const_int 1)))] 4960 "") 4961 4962(define_split 4963 [(set (match_operand:DI 0 "register_operand" "") 4964 (lshiftrt:DI (match_operand:DI 1 "register_operand" "") 4965 (const_int 8)))] 4966 "reload_completed && !TARGET_COLDFIRE" 4967 [(set (strict_low_part (subreg:QI (match_dup 0) 7)) 4968 (subreg:QI (match_dup 0) 3)) 4969 (set (match_dup 2) 4970 (lshiftrt:SI (match_dup 2) (const_int 8))) 4971 (set (match_dup 3) 4972 (rotatert:SI (match_dup 3) (const_int 8)))] 4973{ 4974 operands[2] = gen_highpart (SImode, operands[0]); 4975 operands[3] = gen_lowpart (SImode, operands[0]); 4976}) 4977 4978(define_split 4979 [(set (match_operand:DI 0 "register_operand" "") 4980 (lshiftrt:DI (match_operand:DI 1 "register_operand" "") 4981 (const_int 16)))] 4982 "reload_completed && !TARGET_COLDFIRE" 4983 [(set (strict_low_part (subreg:HI (match_dup 0) 6)) 4984 (subreg:HI (match_dup 0) 2)) 4985 (set (strict_low_part (subreg:HI (match_dup 0) 2)) 4986 (const_int 0)) 4987 (set (match_dup 3) 4988 (rotate:SI (match_dup 3) (const_int 16))) 4989 (set (match_dup 2) 4990 (rotate:SI (match_dup 2) (const_int 16)))] 4991{ 4992 operands[2] = gen_highpart (SImode, operands[0]); 4993 operands[3] = gen_lowpart (SImode, operands[0]); 4994}) 4995 4996(define_split 4997 [(set (match_operand:DI 0 "pre_dec_operand" "") 4998 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "") 4999 (const_int 32)))] 5000 "reload_completed" 5001 [(set (match_dup 0) (match_dup 1)) 5002 (set (match_dup 0) (const_int 0))] 5003{ 5004 operands[0] = adjust_address(operands[0], SImode, 0); 5005 operands[1] = gen_highpart(SImode, operands[1]); 5006}) 5007 5008(define_split 5009 [(set (match_operand:DI 0 "post_inc_operand" "") 5010 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "") 5011 (const_int 32)))] 5012 "reload_completed" 5013 [(set (match_dup 0) (const_int 0)) 5014 (set (match_dup 0) (match_dup 1))] 5015{ 5016 operands[0] = adjust_address(operands[0], SImode, 0); 5017 operands[1] = gen_highpart(SImode, operands[1]); 5018}) 5019 5020(define_split 5021 [(set (match_operand:DI 0 "nonimmediate_operand" "") 5022 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "") 5023 (const_int 32)))] 5024 "reload_completed" 5025 [(set (match_dup 2) (match_dup 5)) 5026 (set (match_dup 4) (const_int 0))] 5027 "split_di(operands, 2, operands + 2, operands + 4);") 5028 5029(define_insn "*lshrdi_const32" 5030 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro<>") 5031 (lshiftrt:DI (match_operand:DI 1 "general_operand" "ro") 5032 (const_int 32)))] 5033 "" 5034 "#") 5035 5036(define_split 5037 [(set (match_operand:DI 0 "register_operand" "") 5038 (lshiftrt:DI (match_operand:DI 1 "register_operand" "") 5039 (match_operand 2 "const_int_operand" "")))] 5040 "reload_completed && !TARGET_COLDFIRE 5041 && INTVAL (operands[2]) > 32 && INTVAL (operands[2]) <= 40" 5042 [(set (match_dup 3) (lshiftrt:SI (match_dup 3) (match_dup 2))) 5043 (set (match_dup 4) (match_dup 3)) 5044 (set (match_dup 3) (const_int 0))] 5045{ 5046 operands[2] = GEN_INT (INTVAL (operands[2]) - 32); 5047 operands[3] = gen_highpart (SImode, operands[0]); 5048 operands[4] = gen_lowpart (SImode, operands[0]); 5049}) 5050 5051(define_split 5052 [(set (match_operand:DI 0 "register_operand" "") 5053 (lshiftrt:DI (match_operand:DI 1 "register_operand" "") 5054 (const_int 48)))] 5055 "reload_completed" 5056 [(set (match_dup 3) (match_dup 2)) 5057 (set (strict_low_part (subreg:HI (match_dup 0) 6)) 5058 (const_int 0)) 5059 (set (match_dup 2) (const_int 0)) 5060 (set (match_dup 3) 5061 (rotate:SI (match_dup 3) (const_int 16)))] 5062{ 5063 operands[2] = gen_highpart (SImode, operands[0]); 5064 operands[3] = gen_lowpart (SImode, operands[0]); 5065}) 5066 5067(define_split 5068 [(set (match_operand:DI 0 "register_operand" "") 5069 (lshiftrt:DI (match_operand:DI 1 "register_operand" "") 5070 (match_operand 2 "const_int_operand" "")))] 5071 "reload_completed && !TARGET_COLDFIRE 5072 && INTVAL (operands[2]) > 40 && INTVAL (operands[2]) <= 62" 5073 [(set (match_dup 4) (match_dup 2)) 5074 (set (match_dup 3) (lshiftrt:SI (match_dup 3) (match_dup 4))) 5075 (set (match_dup 4) (match_dup 3)) 5076 (set (match_dup 3) (const_int 0))] 5077{ 5078 operands[2] = GEN_INT (INTVAL (operands[2]) - 32); 5079 operands[3] = gen_highpart (SImode, operands[0]); 5080 operands[4] = gen_lowpart (SImode, operands[0]); 5081}) 5082 5083(define_insn "*lshrdi_const63" 5084 [(set (match_operand:DI 0 "register_operand" "=d") 5085 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0") 5086 (const_int 63)))] 5087 "" 5088 "add%.l %0,%0\;clr%.l %0\;clr%.l %R1\;addx%.l %R1,%R1") 5089 5090(define_insn "*lshrdi3_const" 5091 [(set (match_operand:DI 0 "register_operand" "=d") 5092 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0") 5093 (match_operand 2 "const_int_operand" "n")))] 5094 "(!TARGET_COLDFIRE 5095 && ((INTVAL (operands[2]) >= 2 && INTVAL (operands[2]) <= 3) 5096 || INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16 5097 || (INTVAL (operands[2]) > 32 && INTVAL (operands[2]) <= 63)))" 5098 "#") 5099 5100(define_expand "lshrdi3" 5101 [(set (match_operand:DI 0 "register_operand" "") 5102 (lshiftrt:DI (match_operand:DI 1 "register_operand" "") 5103 (match_operand:SI 2 "const_int_operand" "")))] 5104 "!TARGET_COLDFIRE" 5105{ 5106 /* ??? This is a named pattern like this is not allowed to FAIL based 5107 on its operands. */ 5108 if (GET_CODE (operands[2]) != CONST_INT 5109 || ((INTVAL (operands[2]) < 1 || INTVAL (operands[2]) > 3) 5110 && INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16 5111 && (INTVAL (operands[2]) < 32 || INTVAL (operands[2]) > 63))) 5112 FAIL; 5113}) 5114 5115;; On all 68k models, this makes faster code in a special case. 5116 5117(define_insn "lshrsi_31" 5118 [(set (match_operand:SI 0 "register_operand" "=d") 5119 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0") 5120 (const_int 31)))] 5121 "" 5122{ 5123 return "add%.l %0,%0\;subx%.l %0,%0\;neg%.l %0"; 5124}) 5125 5126;; On most 68k models, this makes faster code in a special case. 5127 5128(define_insn "lshrsi_16" 5129 [(set (match_operand:SI 0 "register_operand" "=d") 5130 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0") 5131 (const_int 16)))] 5132 "!TUNE_68060" 5133{ 5134 CC_STATUS_INIT; 5135 return "clr%.w %0\;swap %0"; 5136}) 5137 5138;; On the 68000, this makes faster code in a special case. 5139 5140(define_insn "lshrsi_17_24" 5141 [(set (match_operand:SI 0 "register_operand" "=d") 5142 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0") 5143 (match_operand:SI 2 "const_int_operand" "n")))] 5144 "TUNE_68000_10 5145 && INTVAL (operands[2]) > 16 5146 && INTVAL (operands[2]) <= 24" 5147{ 5148 /* I think lsr%.w sets the CC properly. */ 5149 operands[2] = GEN_INT (INTVAL (operands[2]) - 16); 5150 return "clr%.w %0\;swap %0\;lsr%.w %2,%0"; 5151}) 5152 5153(define_insn "lshrsi3" 5154 [(set (match_operand:SI 0 "register_operand" "=d") 5155 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0") 5156 (match_operand:SI 2 "general_operand" "dI")))] 5157 "" 5158 "lsr%.l %2,%0" 5159 [(set_attr "type" "shift") 5160 (set_attr "opy" "2")]) 5161 5162(define_insn "lshrhi3" 5163 [(set (match_operand:HI 0 "register_operand" "=d") 5164 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0") 5165 (match_operand:HI 2 "general_operand" "dI")))] 5166 "!TARGET_COLDFIRE" 5167 "lsr%.w %2,%0") 5168 5169(define_insn "" 5170 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d")) 5171 (lshiftrt:HI (match_dup 0) 5172 (match_operand:HI 1 "general_operand" "dI")))] 5173 "!TARGET_COLDFIRE" 5174 "lsr%.w %1,%0") 5175 5176(define_insn "lshrqi3" 5177 [(set (match_operand:QI 0 "register_operand" "=d") 5178 (lshiftrt:QI (match_operand:QI 1 "register_operand" "0") 5179 (match_operand:QI 2 "general_operand" "dI")))] 5180 "!TARGET_COLDFIRE" 5181 "lsr%.b %2,%0") 5182 5183(define_insn "" 5184 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d")) 5185 (lshiftrt:QI (match_dup 0) 5186 (match_operand:QI 1 "general_operand" "dI")))] 5187 "!TARGET_COLDFIRE" 5188 "lsr%.b %1,%0") 5189 5190;; rotate instructions 5191 5192(define_insn "rotlsi_16" 5193 [(set (match_operand:SI 0 "register_operand" "=d") 5194 (rotate:SI (match_operand:SI 1 "register_operand" "0") 5195 (const_int 16)))] 5196 "" 5197 "swap %0" 5198 [(set_attr "type" "shift")]) 5199 5200(define_insn "rotlsi3" 5201 [(set (match_operand:SI 0 "register_operand" "=d") 5202 (rotate:SI (match_operand:SI 1 "register_operand" "0") 5203 (match_operand:SI 2 "general_operand" "dINO")))] 5204 "!TARGET_COLDFIRE" 5205{ 5206 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 16) 5207 return "swap %0"; 5208 else if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 16) 5209 { 5210 operands[2] = GEN_INT (32 - INTVAL (operands[2])); 5211 return "ror%.l %2,%0"; 5212 } 5213 else 5214 return "rol%.l %2,%0"; 5215}) 5216 5217(define_insn "rotlhi3" 5218 [(set (match_operand:HI 0 "register_operand" "=d") 5219 (rotate:HI (match_operand:HI 1 "register_operand" "0") 5220 (match_operand:HI 2 "general_operand" "dIP")))] 5221 "!TARGET_COLDFIRE" 5222{ 5223 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 8) 5224 { 5225 operands[2] = GEN_INT (16 - INTVAL (operands[2])); 5226 return "ror%.w %2,%0"; 5227 } 5228 else 5229 return "rol%.w %2,%0"; 5230}) 5231 5232(define_insn "*rotlhi3_lowpart" 5233 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d")) 5234 (rotate:HI (match_dup 0) 5235 (match_operand:HI 1 "general_operand" "dIP")))] 5236 "!TARGET_COLDFIRE" 5237{ 5238 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) >= 8) 5239 { 5240 operands[1] = GEN_INT (16 - INTVAL (operands[1])); 5241 return "ror%.w %1,%0"; 5242 } 5243 else 5244 return "rol%.w %1,%0"; 5245}) 5246 5247(define_insn "rotlqi3" 5248 [(set (match_operand:QI 0 "register_operand" "=d") 5249 (rotate:QI (match_operand:QI 1 "register_operand" "0") 5250 (match_operand:QI 2 "general_operand" "dI")))] 5251 "!TARGET_COLDFIRE" 5252{ 5253 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 4) 5254 { 5255 operands[2] = GEN_INT (8 - INTVAL (operands[2])); 5256 return "ror%.b %2,%0"; 5257 } 5258 else 5259 return "rol%.b %2,%0"; 5260}) 5261 5262(define_insn "*rotlqi3_lowpart" 5263 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d")) 5264 (rotate:QI (match_dup 0) 5265 (match_operand:QI 1 "general_operand" "dI")))] 5266 "!TARGET_COLDFIRE" 5267{ 5268 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) >= 4) 5269 { 5270 operands[1] = GEN_INT (8 - INTVAL (operands[1])); 5271 return "ror%.b %1,%0"; 5272 } 5273 else 5274 return "rol%.b %1,%0"; 5275}) 5276 5277(define_insn "rotrsi3" 5278 [(set (match_operand:SI 0 "register_operand" "=d") 5279 (rotatert:SI (match_operand:SI 1 "register_operand" "0") 5280 (match_operand:SI 2 "general_operand" "dI")))] 5281 "!TARGET_COLDFIRE" 5282 "ror%.l %2,%0") 5283 5284(define_insn "rotrhi3" 5285 [(set (match_operand:HI 0 "register_operand" "=d") 5286 (rotatert:HI (match_operand:HI 1 "register_operand" "0") 5287 (match_operand:HI 2 "general_operand" "dI")))] 5288 "!TARGET_COLDFIRE" 5289 "ror%.w %2,%0") 5290 5291(define_insn "rotrhi_lowpart" 5292 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d")) 5293 (rotatert:HI (match_dup 0) 5294 (match_operand:HI 1 "general_operand" "dI")))] 5295 "!TARGET_COLDFIRE" 5296 "ror%.w %1,%0") 5297 5298(define_insn "rotrqi3" 5299 [(set (match_operand:QI 0 "register_operand" "=d") 5300 (rotatert:QI (match_operand:QI 1 "register_operand" "0") 5301 (match_operand:QI 2 "general_operand" "dI")))] 5302 "!TARGET_COLDFIRE" 5303 "ror%.b %2,%0") 5304 5305(define_insn "" 5306 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d")) 5307 (rotatert:QI (match_dup 0) 5308 (match_operand:QI 1 "general_operand" "dI")))] 5309 "!TARGET_COLDFIRE" 5310 "ror%.b %1,%0") 5311 5312(define_expand "bswapsi2" 5313 [(set (match_operand:SI 0 "register_operand") 5314 (bswap:SI (match_operand:SI 1 "register_operand")))] 5315 "!TARGET_COLDFIRE" 5316{ 5317 rtx x = operands[0]; 5318 emit_move_insn (x, operands[1]); 5319 emit_insn (gen_rotrhi_lowpart (gen_lowpart (HImode, x), GEN_INT (8))); 5320 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16))); 5321 emit_insn (gen_rotrhi_lowpart (gen_lowpart (HImode, x), GEN_INT (8))); 5322 DONE; 5323}) 5324 5325 5326;; Bit set/clear in memory byte. 5327 5328;; set bit, bit number is int 5329(define_insn "bsetmemqi" 5330 [(set (match_operand:QI 0 "memory_operand" "+m") 5331 (ior:QI (subreg:QI (ashift:SI (const_int 1) 5332 (match_operand:SI 1 "general_operand" "d")) 3) 5333 (match_dup 0)))] 5334 "" 5335{ 5336 CC_STATUS_INIT; 5337 return "bset %1,%0"; 5338} 5339 [(set_attr "type" "bitrw")]) 5340 5341;; set bit, bit number is (sign/zero)_extended from HImode/QImode 5342(define_insn "*bsetmemqi_ext" 5343 [(set (match_operand:QI 0 "memory_operand" "+m") 5344 (ior:QI (subreg:QI (ashift:SI (const_int 1) 5345 (match_operator:SI 2 "extend_operator" 5346 [(match_operand 1 "general_operand" "d")])) 3) 5347 (match_dup 0)))] 5348 "" 5349{ 5350 CC_STATUS_INIT; 5351 return "bset %1,%0"; 5352} 5353 [(set_attr "type" "bitrw")]) 5354 5355(define_insn "*bsetdreg" 5356 [(set (match_operand:SI 0 "register_operand" "=d") 5357 (ior:SI (ashift:SI (const_int 1) 5358 (and:SI (match_operand:SI 1 "register_operand" "d") 5359 (const_int 31))) 5360 (match_operand:SI 2 "register_operand" "0")))] 5361 "" 5362{ 5363 CC_STATUS_INIT; 5364 return "bset %1,%0"; 5365} 5366 [(set_attr "type" "bitrw")]) 5367 5368(define_insn "*bchgdreg" 5369 [(set (match_operand:SI 0 "register_operand" "=d") 5370 (xor:SI (ashift:SI (const_int 1) 5371 (and:SI (match_operand:SI 1 "register_operand" "d") 5372 (const_int 31))) 5373 (match_operand:SI 2 "register_operand" "0")))] 5374 "" 5375{ 5376 CC_STATUS_INIT; 5377 return "bchg %1,%0"; 5378} 5379 [(set_attr "type" "bitrw")]) 5380 5381(define_insn "*bclrdreg" 5382 [(set (match_operand:SI 0 "register_operand" "=d") 5383 (and:SI (rotate:SI (const_int -2) 5384 (and:SI (match_operand:SI 1 "register_operand" "d") 5385 (const_int 31))) 5386 (match_operand:SI 2 "register_operand" "0")))] 5387 "" 5388{ 5389 CC_STATUS_INIT; 5390 return "bclr %1,%0"; 5391} 5392 [(set_attr "type" "bitrw")]) 5393 5394;; clear bit, bit number is int 5395(define_insn "bclrmemqi" 5396 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+m") 5397 (const_int 1) 5398 (minus:SI (const_int 7) 5399 (match_operand:SI 1 "general_operand" "d"))) 5400 (const_int 0))] 5401 "" 5402{ 5403 CC_STATUS_INIT; 5404 return "bclr %1,%0"; 5405} 5406 [(set_attr "type" "bitrw")]) 5407 5408;; clear bit, bit number is (sign/zero)_extended from HImode/QImode 5409(define_insn "*bclrmemqi_ext" 5410 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+m") 5411 (const_int 1) 5412 (minus:SI (const_int 7) 5413 (match_operator:SI 2 "extend_operator" 5414 [(match_operand 1 "general_operand" "d")]))) 5415 (const_int 0))] 5416 "" 5417{ 5418 CC_STATUS_INIT; 5419 return "bclr %1,%0"; 5420} 5421 [(set_attr "type" "bitrw")]) 5422 5423;; Special cases of bit-field insns which we should 5424;; recognize in preference to the general case. 5425;; These handle aligned 8-bit and 16-bit fields, 5426;; which can usually be done with move instructions. 5427 5428; 5429; Special case for 32-bit field in memory. This only occurs when 32-bit 5430; alignment of structure members is specified. 5431; 5432; The move is allowed to be odd byte aligned, because that's still faster 5433; than an odd byte aligned bit-field instruction. 5434; 5435(define_insn "*insv_32_mem" 5436 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o") 5437 (const_int 32) 5438 (match_operand:SI 1 "const_int_operand" "n")) 5439 (match_operand:SI 2 "general_src_operand" "rmSi"))] 5440 "TARGET_68020 && TARGET_BITFIELD 5441 && (INTVAL (operands[1]) % 8) == 0 5442 && ! mode_dependent_address_p (XEXP (operands[0], 0), 5443 MEM_ADDR_SPACE (operands[0]))" 5444{ 5445 operands[0] 5446 = adjust_address (operands[0], SImode, INTVAL (operands[1]) / 8); 5447 5448 return "move%.l %2,%0"; 5449}) 5450 5451(define_insn "*insv_8_16_reg" 5452 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+d") 5453 (match_operand:SI 1 "const_int_operand" "n") 5454 (match_operand:SI 2 "const_int_operand" "n")) 5455 (match_operand:SI 3 "register_operand" "d"))] 5456 "TARGET_68020 && TARGET_BITFIELD 5457 && IN_RANGE (INTVAL (operands[2]), 0, 31) 5458 && (INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16) 5459 && INTVAL (operands[2]) % INTVAL (operands[1]) == 0" 5460{ 5461 if (INTVAL (operands[1]) + INTVAL (operands[2]) != 32) 5462 return "bfins %3,%0{%b2:%b1}"; 5463 5464 if (INTVAL (operands[1]) == 8) 5465 return "move%.b %3,%0"; 5466 return "move%.w %3,%0"; 5467}) 5468 5469 5470; 5471; Special case for 32-bit field in memory. This only occurs when 32-bit 5472; alignment of structure members is specified. 5473; 5474; The move is allowed to be odd byte aligned, because that's still faster 5475; than an odd byte aligned bit-field instruction. 5476; 5477(define_insn "*extzv_32_mem" 5478 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 5479 (zero_extract:SI (match_operand:QI 1 "memory_src_operand" "oS") 5480 (const_int 32) 5481 (match_operand:SI 2 "const_int_operand" "n")))] 5482 "TARGET_68020 && TARGET_BITFIELD 5483 && (INTVAL (operands[2]) % 8) == 0 5484 && ! mode_dependent_address_p (XEXP (operands[1], 0), 5485 MEM_ADDR_SPACE (operands[1]))" 5486{ 5487 operands[1] 5488 = adjust_address (operands[1], SImode, INTVAL (operands[2]) / 8); 5489 5490 return "move%.l %1,%0"; 5491}) 5492 5493(define_insn "*extzv_8_16_reg" 5494 [(set (match_operand:SI 0 "nonimmediate_operand" "=&d") 5495 (zero_extract:SI (match_operand:SI 1 "register_operand" "d") 5496 (match_operand:SI 2 "const_int_operand" "n") 5497 (match_operand:SI 3 "const_int_operand" "n")))] 5498 "TARGET_68020 && TARGET_BITFIELD 5499 && IN_RANGE (INTVAL (operands[3]), 0, 31) 5500 && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) 5501 && INTVAL (operands[3]) % INTVAL (operands[2]) == 0" 5502{ 5503 cc_status.flags |= CC_NOT_NEGATIVE; 5504 if (INTVAL (operands[2]) + INTVAL (operands[3]) != 32) 5505 return "bfextu %1{%b3:%b2},%0"; 5506 5507 output_asm_insn ("clr%.l %0", operands); 5508 if (INTVAL (operands[2]) == 8) 5509 return "move%.b %1,%0"; 5510 return "move%.w %1,%0"; 5511}) 5512 5513; 5514; Special case for 32-bit field in memory. This only occurs when 32-bit 5515; alignment of structure members is specified. 5516; 5517; The move is allowed to be odd byte aligned, because that's still faster 5518; than an odd byte aligned bit-field instruction. 5519; 5520(define_insn "*extv_32_mem" 5521 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 5522 (sign_extract:SI (match_operand:QI 1 "memory_src_operand" "oS") 5523 (const_int 32) 5524 (match_operand:SI 2 "const_int_operand" "n")))] 5525 "TARGET_68020 && TARGET_BITFIELD 5526 && (INTVAL (operands[2]) % 8) == 0 5527 && ! mode_dependent_address_p (XEXP (operands[1], 0), 5528 MEM_ADDR_SPACE (operands[1]))" 5529{ 5530 operands[1] 5531 = adjust_address (operands[1], SImode, INTVAL (operands[2]) / 8); 5532 5533 return "move%.l %1,%0"; 5534}) 5535 5536(define_insn "*extv_8_16_reg" 5537 [(set (match_operand:SI 0 "nonimmediate_operand" "=d") 5538 (sign_extract:SI (match_operand:SI 1 "register_operand" "d") 5539 (match_operand:SI 2 "const_int_operand" "n") 5540 (match_operand:SI 3 "const_int_operand" "n")))] 5541 "TARGET_68020 && TARGET_BITFIELD 5542 && IN_RANGE (INTVAL (operands[3]), 0, 31) 5543 && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) 5544 && INTVAL (operands[3]) % INTVAL (operands[2]) == 0" 5545{ 5546 if (INTVAL (operands[2]) + INTVAL (operands[3]) != 32) 5547 return "bfexts %1{%b3:%b2},%0"; 5548 5549 if (INTVAL (operands[2]) == 8) 5550 return "move%.b %1,%0\;extb%.l %0"; 5551 return "move%.w %1,%0\;ext%.l %0"; 5552}) 5553 5554;; Bit-field instructions, general cases. 5555;; "o,d" constraint causes a nonoffsettable memref to match the "o" 5556;; so that its address is reloaded. 5557 5558(define_expand "extv" 5559 [(set (match_operand:SI 0 "register_operand" "") 5560 (sign_extract:SI (match_operand:SI 1 "general_operand" "") 5561 (match_operand:SI 2 "const_int_operand" "") 5562 (match_operand:SI 3 "const_int_operand" "")))] 5563 "TARGET_68020 && TARGET_BITFIELD" 5564 "") 5565 5566(define_insn "*extv_bfexts_mem" 5567 [(set (match_operand:SI 0 "register_operand" "=d") 5568 (sign_extract:SI (match_operand:QI 1 "memory_operand" "o") 5569 (match_operand:SI 2 "nonmemory_operand" "dn") 5570 (match_operand:SI 3 "nonmemory_operand" "dn")))] 5571 "TARGET_68020 && TARGET_BITFIELD" 5572 "bfexts %1{%b3:%b2},%0") 5573 5574(define_expand "extzv" 5575 [(set (match_operand:SI 0 "register_operand" "") 5576 (zero_extract:SI (match_operand:SI 1 "general_operand" "") 5577 (match_operand:SI 2 "const_int_operand" "") 5578 (match_operand:SI 3 "const_int_operand" "")))] 5579 "TARGET_68020 && TARGET_BITFIELD" 5580 "") 5581 5582(define_insn "*extzv_bfextu_mem" 5583 [(set (match_operand:SI 0 "register_operand" "=d") 5584 (zero_extract:SI (match_operand:QI 1 "memory_operand" "o") 5585 (match_operand:SI 2 "nonmemory_operand" "dn") 5586 (match_operand:SI 3 "nonmemory_operand" "dn")))] 5587 "TARGET_68020 && TARGET_BITFIELD" 5588{ 5589 if (GET_CODE (operands[2]) == CONST_INT) 5590 { 5591 if (INTVAL (operands[2]) != 32) 5592 cc_status.flags |= CC_NOT_NEGATIVE; 5593 } 5594 else 5595 { 5596 CC_STATUS_INIT; 5597 } 5598 return "bfextu %1{%b3:%b2},%0"; 5599}) 5600 5601(define_insn "*insv_bfchg_mem" 5602 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o") 5603 (match_operand:SI 1 "nonmemory_operand" "dn") 5604 (match_operand:SI 2 "nonmemory_operand" "dn")) 5605 (xor:SI (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2)) 5606 (match_operand 3 "const_int_operand" "n")))] 5607 "TARGET_68020 && TARGET_BITFIELD 5608 && (INTVAL (operands[3]) == -1 5609 || (GET_CODE (operands[1]) == CONST_INT 5610 && (~ INTVAL (operands[3]) & ((1 << INTVAL (operands[1]))- 1)) == 0))" 5611{ 5612 CC_STATUS_INIT; 5613 return "bfchg %0{%b2:%b1}"; 5614}) 5615 5616(define_insn "*insv_bfclr_mem" 5617 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o") 5618 (match_operand:SI 1 "nonmemory_operand" "dn") 5619 (match_operand:SI 2 "nonmemory_operand" "dn")) 5620 (const_int 0))] 5621 "TARGET_68020 && TARGET_BITFIELD" 5622{ 5623 CC_STATUS_INIT; 5624 return "bfclr %0{%b2:%b1}"; 5625}) 5626 5627(define_insn "*insv_bfset_mem" 5628 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o") 5629 (match_operand:SI 1 "general_operand" "dn") 5630 (match_operand:SI 2 "general_operand" "dn")) 5631 (const_int -1))] 5632 "TARGET_68020 && TARGET_BITFIELD" 5633{ 5634 CC_STATUS_INIT; 5635 return "bfset %0{%b2:%b1}"; 5636}) 5637 5638(define_expand "insv" 5639 [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "") 5640 (match_operand:SI 1 "const_int_operand" "") 5641 (match_operand:SI 2 "const_int_operand" "")) 5642 (match_operand:SI 3 "reg_or_pow2_m1_operand" ""))] 5643 "TARGET_68020 && TARGET_BITFIELD" 5644 " 5645{ 5646 /* Special case initializing a field to all ones. */ 5647 if (GET_CODE (operands[3]) == CONST_INT) 5648 { 5649 if (exact_log2 (INTVAL (operands[3]) + 1) != INTVAL (operands[1])) 5650 operands[3] = force_reg (SImode, operands[3]); 5651 else 5652 operands[3] = constm1_rtx; 5653 5654 } 5655}") 5656 5657(define_insn "*insv_bfins_mem" 5658 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o") 5659 (match_operand:SI 1 "nonmemory_operand" "dn") 5660 (match_operand:SI 2 "nonmemory_operand" "dn")) 5661 (match_operand:SI 3 "register_operand" "d"))] 5662 "TARGET_68020 && TARGET_BITFIELD" 5663 "bfins %3,%0{%b2:%b1}") 5664 5665;; Now recognize bit-field insns that operate on registers 5666;; (or at least were intended to do so). 5667 5668(define_insn "*extv_bfexts_reg" 5669 [(set (match_operand:SI 0 "nonimmediate_operand" "=d") 5670 (sign_extract:SI (match_operand:SI 1 "register_operand" "d") 5671 (match_operand:SI 2 "const_int_operand" "n") 5672 (match_operand:SI 3 "const_int_operand" "n")))] 5673 "TARGET_68020 && TARGET_BITFIELD && IN_RANGE (INTVAL (operands[3]), 0, 31)" 5674 "bfexts %1{%b3:%b2},%0") 5675 5676(define_insn "*extv_bfextu_reg" 5677 [(set (match_operand:SI 0 "nonimmediate_operand" "=d") 5678 (zero_extract:SI (match_operand:SI 1 "register_operand" "d") 5679 (match_operand:SI 2 "const_int_operand" "n") 5680 (match_operand:SI 3 "const_int_operand" "n")))] 5681 "TARGET_68020 && TARGET_BITFIELD && IN_RANGE (INTVAL (operands[3]), 0, 31)" 5682{ 5683 if (GET_CODE (operands[2]) == CONST_INT) 5684 { 5685 if (INTVAL (operands[2]) != 32) 5686 cc_status.flags |= CC_NOT_NEGATIVE; 5687 } 5688 else 5689 { 5690 CC_STATUS_INIT; 5691 } 5692 return "bfextu %1{%b3:%b2},%0"; 5693}) 5694 5695(define_insn "*insv_bfclr_reg" 5696 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+d") 5697 (match_operand:SI 1 "const_int_operand" "n") 5698 (match_operand:SI 2 "const_int_operand" "n")) 5699 (const_int 0))] 5700 "TARGET_68020 && TARGET_BITFIELD && IN_RANGE (INTVAL (operands[2]), 0, 31)" 5701{ 5702 CC_STATUS_INIT; 5703 return "bfclr %0{%b2:%b1}"; 5704}) 5705 5706(define_insn "*insv_bfset_reg" 5707 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+d") 5708 (match_operand:SI 1 "const_int_operand" "n") 5709 (match_operand:SI 2 "const_int_operand" "n")) 5710 (const_int -1))] 5711 "TARGET_68020 && TARGET_BITFIELD && IN_RANGE (INTVAL (operands[2]), 0, 31)" 5712{ 5713 CC_STATUS_INIT; 5714 return "bfset %0{%b2:%b1}"; 5715}) 5716 5717(define_insn "*insv_bfins_reg" 5718 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+d") 5719 (match_operand:SI 1 "const_int_operand" "n") 5720 (match_operand:SI 2 "const_int_operand" "n")) 5721 (match_operand:SI 3 "register_operand" "d"))] 5722 "TARGET_68020 && TARGET_BITFIELD && IN_RANGE (INTVAL (operands[2]), 0, 31)" 5723{ 5724#if 0 5725 /* These special cases are now recognized by a specific pattern. */ 5726 if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (operands[2]) == CONST_INT 5727 && INTVAL (operands[1]) == 16 && INTVAL (operands[2]) == 16) 5728 return "move%.w %3,%0"; 5729 if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (operands[2]) == CONST_INT 5730 && INTVAL (operands[1]) == 24 && INTVAL (operands[2]) == 8) 5731 return "move%.b %3,%0"; 5732#endif 5733 return "bfins %3,%0{%b2:%b1}"; 5734}) 5735 5736;; Special patterns for optimizing bit-field instructions. 5737 5738(define_insn "*tst_bftst_mem" 5739 [(set (cc0) 5740 (compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "o") 5741 (match_operand:SI 1 "const_int_operand" "n") 5742 (match_operand:SI 2 "general_operand" "dn")) 5743 (const_int 0)))] 5744 "TARGET_68020 && TARGET_BITFIELD" 5745{ 5746 if (operands[1] == const1_rtx 5747 && GET_CODE (operands[2]) == CONST_INT) 5748 { 5749 int width = GET_CODE (operands[0]) == REG ? 31 : 7; 5750 return output_btst (operands, 5751 GEN_INT (width - INTVAL (operands[2])), 5752 operands[0], insn, 1000); 5753 /* Pass 1000 as SIGNPOS argument so that btst will 5754 not think we are testing the sign bit for an `and' 5755 and assume that nonzero implies a negative result. */ 5756 } 5757 if (INTVAL (operands[1]) != 32) 5758 cc_status.flags = CC_NOT_NEGATIVE; 5759 return "bftst %0{%b2:%b1}"; 5760}) 5761 5762 5763;;; now handle the register cases 5764(define_insn "*tst_bftst_reg" 5765 [(set (cc0) 5766 (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "d") 5767 (match_operand:SI 1 "const_int_operand" "n") 5768 (match_operand:SI 2 "general_operand" "dn")) 5769 (const_int 0)))] 5770 "TARGET_68020 && TARGET_BITFIELD 5771 && !(CONST_INT_P (operands[2]) && !IN_RANGE (INTVAL (operands[2]), 0, 31))" 5772{ 5773 if (operands[1] == const1_rtx 5774 && GET_CODE (operands[2]) == CONST_INT) 5775 { 5776 int width = GET_CODE (operands[0]) == REG ? 31 : 7; 5777 return output_btst (operands, GEN_INT (width - INTVAL (operands[2])), 5778 operands[0], insn, 1000); 5779 /* Pass 1000 as SIGNPOS argument so that btst will 5780 not think we are testing the sign bit for an `and' 5781 and assume that nonzero implies a negative result. */ 5782 } 5783 if (INTVAL (operands[1]) != 32) 5784 cc_status.flags = CC_NOT_NEGATIVE; 5785 return "bftst %0{%b2:%b1}"; 5786}) 5787 5788(define_insn "scc0_di" 5789 [(set (match_operand:QI 0 "nonimmediate_operand" "=dm") 5790 (match_operator 1 "ordered_comparison_operator" 5791 [(match_operand:DI 2 "general_operand" "ro") (const_int 0)]))] 5792 "! TARGET_COLDFIRE" 5793{ 5794 return output_scc_di (operands[1], operands[2], const0_rtx, operands[0]); 5795}) 5796 5797(define_insn "scc0_di_5200" 5798 [(set (match_operand:QI 0 "nonimmediate_operand" "=d") 5799 (match_operator 1 "ordered_comparison_operator" 5800 [(match_operand:DI 2 "general_operand" "ro") (const_int 0)]))] 5801 "TARGET_COLDFIRE" 5802{ 5803 return output_scc_di (operands[1], operands[2], const0_rtx, operands[0]); 5804}) 5805 5806(define_insn "scc_di" 5807 [(set (match_operand:QI 0 "nonimmediate_operand" "=dm,dm") 5808 (match_operator 1 "ordered_comparison_operator" 5809 [(match_operand:DI 2 "general_operand" "ro,r") 5810 (match_operand:DI 3 "general_operand" "r,ro")]))] 5811 "! TARGET_COLDFIRE" 5812{ 5813 return output_scc_di (operands[1], operands[2], operands[3], operands[0]); 5814}) 5815 5816(define_insn "scc_di_5200" 5817 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d") 5818 (match_operator 1 "ordered_comparison_operator" 5819 [(match_operand:DI 2 "general_operand" "ro,r") 5820 (match_operand:DI 3 "general_operand" "r,ro")]))] 5821 "TARGET_COLDFIRE" 5822{ 5823 return output_scc_di (operands[1], operands[2], operands[3], operands[0]); 5824}) 5825 5826;; Note that operand 0 of an SCC insn is supported in the hardware as 5827;; memory, but we cannot allow it to be in memory in case the address 5828;; needs to be reloaded. 5829 5830(define_insn "" 5831 [(set (match_operand:QI 0 "register_operand" "=d") 5832 (eq:QI (cc0) (const_int 0)))] 5833 "" 5834{ 5835 cc_status = cc_prev_status; 5836 OUTPUT_JUMP ("seq %0", "fseq %0", "seq %0"); 5837}) 5838 5839(define_insn "" 5840 [(set (match_operand:QI 0 "register_operand" "=d") 5841 (ne:QI (cc0) (const_int 0)))] 5842 "" 5843{ 5844 cc_status = cc_prev_status; 5845 OUTPUT_JUMP ("sne %0", "fsne %0", "sne %0"); 5846}) 5847 5848(define_insn "" 5849 [(set (match_operand:QI 0 "register_operand" "=d") 5850 (gt:QI (cc0) (const_int 0)))] 5851 "" 5852{ 5853 cc_status = cc_prev_status; 5854 OUTPUT_JUMP ("sgt %0", "fsgt %0", 0); 5855}) 5856 5857(define_insn "" 5858 [(set (match_operand:QI 0 "register_operand" "=d") 5859 (gtu:QI (cc0) (const_int 0)))] 5860 "" 5861{ 5862 cc_status = cc_prev_status; 5863 return "shi %0"; 5864}) 5865 5866(define_insn "" 5867 [(set (match_operand:QI 0 "register_operand" "=d") 5868 (lt:QI (cc0) (const_int 0)))] 5869 "" 5870{ 5871 cc_status = cc_prev_status; 5872 OUTPUT_JUMP ("slt %0", "fslt %0", "smi %0"); 5873}) 5874 5875(define_insn "" 5876 [(set (match_operand:QI 0 "register_operand" "=d") 5877 (ltu:QI (cc0) (const_int 0)))] 5878 "" 5879{ 5880 cc_status = cc_prev_status; 5881 return "scs %0"; 5882}) 5883 5884(define_insn "" 5885 [(set (match_operand:QI 0 "register_operand" "=d") 5886 (ge:QI (cc0) (const_int 0)))] 5887 "" 5888{ 5889 cc_status = cc_prev_status; 5890 OUTPUT_JUMP ("sge %0", "fsge %0", "spl %0"); 5891}) 5892 5893(define_insn "*scc" 5894 [(set (match_operand:QI 0 "register_operand" "=d") 5895 (geu:QI (cc0) (const_int 0)))] 5896 "" 5897{ 5898 cc_status = cc_prev_status; 5899 return "scc %0"; 5900} 5901 [(set_attr "type" "scc")]) 5902 5903(define_insn "" 5904 [(set (match_operand:QI 0 "register_operand" "=d") 5905 (le:QI (cc0) (const_int 0)))] 5906 "" 5907{ 5908 cc_status = cc_prev_status; 5909 OUTPUT_JUMP ("sle %0", "fsle %0", 0); 5910}) 5911 5912(define_insn "*sls" 5913 [(set (match_operand:QI 0 "register_operand" "=d") 5914 (leu:QI (cc0) (const_int 0)))] 5915 "" 5916{ 5917 cc_status = cc_prev_status; 5918 return "sls %0"; 5919} 5920 [(set_attr "type" "scc")]) 5921 5922(define_insn "*sordered_1" 5923 [(set (match_operand:QI 0 "register_operand" "=d") 5924 (ordered:QI (cc0) (const_int 0)))] 5925 "TARGET_68881 && !TUNE_68060" 5926{ 5927 cc_status = cc_prev_status; 5928 return "fsor %0"; 5929}) 5930 5931(define_insn "*sunordered_1" 5932 [(set (match_operand:QI 0 "register_operand" "=d") 5933 (unordered:QI (cc0) (const_int 0)))] 5934 "TARGET_68881 && !TUNE_68060" 5935{ 5936 cc_status = cc_prev_status; 5937 return "fsun %0"; 5938}) 5939 5940(define_insn "*suneq_1" 5941 [(set (match_operand:QI 0 "register_operand" "=d") 5942 (uneq:QI (cc0) (const_int 0)))] 5943 "TARGET_68881 && !TUNE_68060" 5944{ 5945 cc_status = cc_prev_status; 5946 return "fsueq %0"; 5947}) 5948 5949(define_insn "*sunge_1" 5950 [(set (match_operand:QI 0 "register_operand" "=d") 5951 (unge:QI (cc0) (const_int 0)))] 5952 "TARGET_68881 && !TUNE_68060" 5953{ 5954 cc_status = cc_prev_status; 5955 return "fsuge %0"; 5956}) 5957 5958(define_insn "*sungt_1" 5959 [(set (match_operand:QI 0 "register_operand" "=d") 5960 (ungt:QI (cc0) (const_int 0)))] 5961 "TARGET_68881 && !TUNE_68060" 5962{ 5963 cc_status = cc_prev_status; 5964 return "fsugt %0"; 5965}) 5966 5967(define_insn "*sunle_1" 5968 [(set (match_operand:QI 0 "register_operand" "=d") 5969 (unle:QI (cc0) (const_int 0)))] 5970 "TARGET_68881 && !TUNE_68060" 5971{ 5972 cc_status = cc_prev_status; 5973 return "fsule %0"; 5974}) 5975 5976(define_insn "*sunlt_1" 5977 [(set (match_operand:QI 0 "register_operand" "=d") 5978 (unlt:QI (cc0) (const_int 0)))] 5979 "TARGET_68881 && !TUNE_68060" 5980{ 5981 cc_status = cc_prev_status; 5982 return "fsult %0"; 5983}) 5984 5985(define_insn "*sltgt_1" 5986 [(set (match_operand:QI 0 "register_operand" "=d") 5987 (ltgt:QI (cc0) (const_int 0)))] 5988 "TARGET_68881 && !TUNE_68060" 5989{ 5990 cc_status = cc_prev_status; 5991 return "fsogl %0"; 5992}) 5993 5994(define_insn "*fsogt_1" 5995 [(set (match_operand:QI 0 "register_operand" "=d") 5996 (not:QI (unle:QI (cc0) (const_int 0))))] 5997 "TARGET_68881 && !TUNE_68060" 5998{ 5999 cc_status = cc_prev_status; 6000 return "fsogt %0"; 6001}) 6002 6003(define_insn "*fsoge_1" 6004 [(set (match_operand:QI 0 "register_operand" "=d") 6005 (not:QI (unlt:QI (cc0) (const_int 0))))] 6006 "TARGET_68881 && !TUNE_68060" 6007{ 6008 cc_status = cc_prev_status; 6009 return "fsoge %0"; 6010}) 6011 6012(define_insn "*fsolt_1" 6013 [(set (match_operand:QI 0 "register_operand" "=d") 6014 (not:QI (unge:QI (cc0) (const_int 0))))] 6015 "TARGET_68881 && !TUNE_68060" 6016{ 6017 cc_status = cc_prev_status; 6018 return "fsolt %0"; 6019}) 6020 6021(define_insn "*fsole_1" 6022 [(set (match_operand:QI 0 "register_operand" "=d") 6023 (not:QI (ungt:QI (cc0) (const_int 0))))] 6024 "TARGET_68881 && !TUNE_68060" 6025{ 6026 cc_status = cc_prev_status; 6027 return "fsole %0"; 6028}) 6029 6030;; Basic conditional jump instructions. 6031 6032(define_insn "beq0_di" 6033 [(set (pc) 6034 (if_then_else (eq (match_operand:DI 0 "general_operand" "d*a,o,<>") 6035 (const_int 0)) 6036 (label_ref (match_operand 1 "" ",,")) 6037 (pc))) 6038 (clobber (match_scratch:SI 2 "=d,&d,d"))] 6039 "" 6040{ 6041 CC_STATUS_INIT; 6042 if (which_alternative == 2) 6043 return "move%.l %0,%2\;or%.l %0,%2\;jeq %l1"; 6044 if ((cc_prev_status.value1 6045 && rtx_equal_p (cc_prev_status.value1, operands[0])) 6046 || (cc_prev_status.value2 6047 && rtx_equal_p (cc_prev_status.value2, operands[0]))) 6048 { 6049 cc_status = cc_prev_status; 6050 return "jeq %l1"; 6051 } 6052 if (GET_CODE (operands[0]) == REG) 6053 operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); 6054 else 6055 operands[3] = adjust_address (operands[0], SImode, 4); 6056 if (! ADDRESS_REG_P (operands[0])) 6057 { 6058 if (reg_overlap_mentioned_p (operands[2], operands[0])) 6059 { 6060 if (reg_overlap_mentioned_p (operands[2], operands[3])) 6061 return "or%.l %0,%2\;jeq %l1"; 6062 else 6063 return "or%.l %3,%2\;jeq %l1"; 6064 } 6065 return "move%.l %0,%2\;or%.l %3,%2\;jeq %l1"; 6066 } 6067 operands[4] = gen_label_rtx(); 6068 if (TARGET_68020 || TARGET_COLDFIRE) 6069 output_asm_insn ("tst%.l %0\;jne %l4\;tst%.l %3\;jeq %l1", operands); 6070 else 6071 output_asm_insn ("cmp%.w #0,%0\;jne %l4\;cmp%.w #0,%3\;jeq %l1", operands); 6072 (*targetm.asm_out.internal_label) (asm_out_file, "L", 6073 CODE_LABEL_NUMBER (operands[4])); 6074 return ""; 6075}) 6076 6077(define_insn "bne0_di" 6078 [(set (pc) 6079 (if_then_else (ne (match_operand:DI 0 "general_operand" "d,o,*a") 6080 (const_int 0)) 6081 (label_ref (match_operand 1 "" ",,")) 6082 (pc))) 6083 (clobber (match_scratch:SI 2 "=d,&d,X"))] 6084 "" 6085{ 6086 if ((cc_prev_status.value1 6087 && rtx_equal_p (cc_prev_status.value1, operands[0])) 6088 || (cc_prev_status.value2 6089 && rtx_equal_p (cc_prev_status.value2, operands[0]))) 6090 { 6091 cc_status = cc_prev_status; 6092 return "jne %l1"; 6093 } 6094 CC_STATUS_INIT; 6095 if (GET_CODE (operands[0]) == REG) 6096 operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); 6097 else 6098 operands[3] = adjust_address (operands[0], SImode, 4); 6099 if (!ADDRESS_REG_P (operands[0])) 6100 { 6101 if (reg_overlap_mentioned_p (operands[2], operands[0])) 6102 { 6103 if (reg_overlap_mentioned_p (operands[2], operands[3])) 6104 return "or%.l %0,%2\;jne %l1"; 6105 else 6106 return "or%.l %3,%2\;jne %l1"; 6107 } 6108 return "move%.l %0,%2\;or%.l %3,%2\;jne %l1"; 6109 } 6110 if (TARGET_68020 || TARGET_COLDFIRE) 6111 return "tst%.l %0\;jne %l1\;tst%.l %3\;jne %l1"; 6112 else 6113 return "cmp%.w #0,%0\;jne %l1\;cmp%.w #0,%3\;jne %l1"; 6114}) 6115 6116(define_insn "bge0_di" 6117 [(set (pc) 6118 (if_then_else (ge (match_operand:DI 0 "general_operand" "ro") 6119 (const_int 0)) 6120 (label_ref (match_operand 1 "" "")) 6121 (pc)))] 6122 "" 6123{ 6124 if ((cc_prev_status.value1 6125 && rtx_equal_p (cc_prev_status.value1, operands[0])) 6126 || (cc_prev_status.value2 6127 && rtx_equal_p (cc_prev_status.value2, operands[0]))) 6128 { 6129 cc_status = cc_prev_status; 6130 return cc_status.flags & CC_REVERSED ? "jle %l1" : "jpl %l1"; 6131 } 6132 CC_STATUS_INIT; 6133 if (TARGET_68020 || TARGET_COLDFIRE || ! ADDRESS_REG_P (operands[0])) 6134 output_asm_insn("tst%.l %0", operands); 6135 else 6136 { 6137 /* On an address reg, cmpw may replace cmpl. */ 6138 output_asm_insn("cmp%.w #0,%0", operands); 6139 } 6140 return "jpl %l1"; 6141}) 6142 6143(define_insn "blt0_di" 6144 [(set (pc) 6145 (if_then_else (lt (match_operand:DI 0 "general_operand" "ro") 6146 (const_int 0)) 6147 (label_ref (match_operand 1 "" "")) 6148 (pc)))] 6149 "" 6150{ 6151 if ((cc_prev_status.value1 6152 && rtx_equal_p (cc_prev_status.value1, operands[0])) 6153 || (cc_prev_status.value2 6154 && rtx_equal_p (cc_prev_status.value2, operands[0]))) 6155 { 6156 cc_status = cc_prev_status; 6157 return cc_status.flags & CC_REVERSED ? "jgt %l1" : "jmi %l1"; 6158 } 6159 CC_STATUS_INIT; 6160 if (TARGET_68020 || TARGET_COLDFIRE || ! ADDRESS_REG_P (operands[0])) 6161 output_asm_insn("tst%.l %0", operands); 6162 else 6163 { 6164 /* On an address reg, cmpw may replace cmpl. */ 6165 output_asm_insn("cmp%.w #0,%0", operands); 6166 } 6167 return "jmi %l1"; 6168}) 6169 6170(define_insn "beq" 6171 [(set (pc) 6172 (if_then_else (eq (cc0) 6173 (const_int 0)) 6174 (label_ref (match_operand 0 "" "")) 6175 (pc)))] 6176 "" 6177{ 6178 OUTPUT_JUMP ("jeq %l0", "fjeq %l0", "jeq %l0"); 6179} 6180 [(set_attr "type" "bcc")]) 6181 6182(define_insn "bne" 6183 [(set (pc) 6184 (if_then_else (ne (cc0) 6185 (const_int 0)) 6186 (label_ref (match_operand 0 "" "")) 6187 (pc)))] 6188 "" 6189{ 6190 OUTPUT_JUMP ("jne %l0", "fjne %l0", "jne %l0"); 6191} 6192 [(set_attr "type" "bcc")]) 6193 6194(define_insn "bgt" 6195 [(set (pc) 6196 (if_then_else (gt (cc0) 6197 (const_int 0)) 6198 (label_ref (match_operand 0 "" "")) 6199 (pc)))] 6200 "" 6201{ 6202 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) 6203 { 6204 cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; 6205 return 0; 6206 } 6207 6208 OUTPUT_JUMP ("jgt %l0", "fjgt %l0", 0); 6209} 6210 [(set_attr "type" "bcc")]) 6211 6212(define_insn "bgtu" 6213 [(set (pc) 6214 (if_then_else (gtu (cc0) 6215 (const_int 0)) 6216 (label_ref (match_operand 0 "" "")) 6217 (pc)))] 6218 "" 6219{ 6220 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) 6221 { 6222 cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; 6223 return 0; 6224 } 6225 6226 return "jhi %l0"; 6227} 6228 [(set_attr "type" "bcc")]) 6229 6230(define_insn "blt" 6231 [(set (pc) 6232 (if_then_else (lt (cc0) 6233 (const_int 0)) 6234 (label_ref (match_operand 0 "" "")) 6235 (pc)))] 6236 "" 6237{ 6238 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) 6239 { 6240 cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; 6241 return 0; 6242 } 6243 6244 OUTPUT_JUMP ("jlt %l0", "fjlt %l0", "jmi %l0"); 6245} 6246 [(set_attr "type" "bcc")]) 6247 6248(define_insn "bltu" 6249 [(set (pc) 6250 (if_then_else (ltu (cc0) 6251 (const_int 0)) 6252 (label_ref (match_operand 0 "" "")) 6253 (pc)))] 6254 "" 6255{ 6256 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) 6257 { 6258 cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; 6259 return 0; 6260 } 6261 6262 return "jcs %l0"; 6263} 6264 [(set_attr "type" "bcc")]) 6265 6266(define_insn "bge" 6267 [(set (pc) 6268 (if_then_else (ge (cc0) 6269 (const_int 0)) 6270 (label_ref (match_operand 0 "" "")) 6271 (pc)))] 6272 "" 6273{ 6274 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) 6275 { 6276 cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; 6277 return 0; 6278 } 6279 6280 OUTPUT_JUMP ("jge %l0", "fjge %l0", "jpl %l0"); 6281}) 6282 6283(define_insn "bgeu" 6284 [(set (pc) 6285 (if_then_else (geu (cc0) 6286 (const_int 0)) 6287 (label_ref (match_operand 0 "" "")) 6288 (pc)))] 6289 "" 6290{ 6291 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) 6292 { 6293 cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; 6294 return 0; 6295 } 6296 6297 return "jcc %l0"; 6298} 6299 [(set_attr "type" "bcc")]) 6300 6301(define_insn "ble" 6302 [(set (pc) 6303 (if_then_else (le (cc0) 6304 (const_int 0)) 6305 (label_ref (match_operand 0 "" "")) 6306 (pc)))] 6307 "" 6308{ 6309 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) 6310 { 6311 cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; 6312 return 0; 6313 } 6314 6315 OUTPUT_JUMP ("jle %l0", "fjle %l0", 0); 6316} 6317 [(set_attr "type" "bcc")]) 6318 6319(define_insn "bleu" 6320 [(set (pc) 6321 (if_then_else (leu (cc0) 6322 (const_int 0)) 6323 (label_ref (match_operand 0 "" "")) 6324 (pc)))] 6325 "" 6326{ 6327 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) 6328 { 6329 cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; 6330 return 0; 6331 } 6332 6333 return "jls %l0"; 6334} 6335 [(set_attr "type" "bcc")]) 6336 6337(define_insn "bordered" 6338 [(set (pc) 6339 (if_then_else (ordered (cc0) (const_int 0)) 6340 (label_ref (match_operand 0 "" "")) 6341 (pc)))] 6342 "TARGET_HARD_FLOAT" 6343{ 6344 gcc_assert (cc_prev_status.flags & CC_IN_68881); 6345 return "fjor %l0"; 6346} 6347 [(set_attr "type" "fbcc")]) 6348 6349(define_insn "bunordered" 6350 [(set (pc) 6351 (if_then_else (unordered (cc0) (const_int 0)) 6352 (label_ref (match_operand 0 "" "")) 6353 (pc)))] 6354 "TARGET_HARD_FLOAT" 6355{ 6356 gcc_assert (cc_prev_status.flags & CC_IN_68881); 6357 return "fjun %l0"; 6358} 6359 [(set_attr "type" "fbcc")]) 6360 6361(define_insn "buneq" 6362 [(set (pc) 6363 (if_then_else (uneq (cc0) (const_int 0)) 6364 (label_ref (match_operand 0 "" "")) 6365 (pc)))] 6366 "TARGET_HARD_FLOAT" 6367{ 6368 gcc_assert (cc_prev_status.flags & CC_IN_68881); 6369 return "fjueq %l0"; 6370} 6371 [(set_attr "type" "fbcc")]) 6372 6373(define_insn "bunge" 6374 [(set (pc) 6375 (if_then_else (unge (cc0) (const_int 0)) 6376 (label_ref (match_operand 0 "" "")) 6377 (pc)))] 6378 "TARGET_HARD_FLOAT" 6379{ 6380 gcc_assert (cc_prev_status.flags & CC_IN_68881); 6381 return "fjuge %l0"; 6382} 6383 [(set_attr "type" "fbcc")]) 6384 6385(define_insn "bungt" 6386 [(set (pc) 6387 (if_then_else (ungt (cc0) (const_int 0)) 6388 (label_ref (match_operand 0 "" "")) 6389 (pc)))] 6390 "TARGET_HARD_FLOAT" 6391{ 6392 gcc_assert (cc_prev_status.flags & CC_IN_68881); 6393 return "fjugt %l0"; 6394} 6395 [(set_attr "type" "fbcc")]) 6396 6397(define_insn "bunle" 6398 [(set (pc) 6399 (if_then_else (unle (cc0) (const_int 0)) 6400 (label_ref (match_operand 0 "" "")) 6401 (pc)))] 6402 "TARGET_HARD_FLOAT" 6403{ 6404 gcc_assert (cc_prev_status.flags & CC_IN_68881); 6405 return "fjule %l0"; 6406} 6407 [(set_attr "type" "fbcc")]) 6408 6409(define_insn "bunlt" 6410 [(set (pc) 6411 (if_then_else (unlt (cc0) (const_int 0)) 6412 (label_ref (match_operand 0 "" "")) 6413 (pc)))] 6414 "TARGET_HARD_FLOAT" 6415{ 6416 gcc_assert (cc_prev_status.flags & CC_IN_68881); 6417 return "fjult %l0"; 6418} 6419 [(set_attr "type" "fbcc")]) 6420 6421(define_insn "bltgt" 6422 [(set (pc) 6423 (if_then_else (ltgt (cc0) (const_int 0)) 6424 (label_ref (match_operand 0 "" "")) 6425 (pc)))] 6426 "TARGET_HARD_FLOAT" 6427{ 6428 gcc_assert (cc_prev_status.flags & CC_IN_68881); 6429 return "fjogl %l0"; 6430} 6431 [(set_attr "type" "fbcc")]) 6432 6433;; Negated conditional jump instructions. 6434 6435(define_insn "*beq_rev" 6436 [(set (pc) 6437 (if_then_else (eq (cc0) 6438 (const_int 0)) 6439 (pc) 6440 (label_ref (match_operand 0 "" ""))))] 6441 "" 6442{ 6443 OUTPUT_JUMP ("jne %l0", "fjne %l0", "jne %l0"); 6444} 6445 [(set_attr "type" "bcc")]) 6446 6447(define_insn "*bne_rev" 6448 [(set (pc) 6449 (if_then_else (ne (cc0) 6450 (const_int 0)) 6451 (pc) 6452 (label_ref (match_operand 0 "" ""))))] 6453 "" 6454{ 6455 OUTPUT_JUMP ("jeq %l0", "fjeq %l0", "jeq %l0"); 6456} 6457 [(set_attr "type" "bcc")]) 6458 6459(define_insn "*bgt_rev" 6460 [(set (pc) 6461 (if_then_else (gt (cc0) 6462 (const_int 0)) 6463 (pc) 6464 (label_ref (match_operand 0 "" ""))))] 6465 "" 6466{ 6467 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) 6468 { 6469 cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; 6470 return 0; 6471 } 6472 6473 OUTPUT_JUMP ("jle %l0", "fjngt %l0", 0); 6474} 6475 [(set_attr "type" "bcc")]) 6476 6477(define_insn "*bgtu_rev" 6478 [(set (pc) 6479 (if_then_else (gtu (cc0) 6480 (const_int 0)) 6481 (pc) 6482 (label_ref (match_operand 0 "" ""))))] 6483 "" 6484{ 6485 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) 6486 { 6487 cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; 6488 return 0; 6489 } 6490 6491 return "jls %l0"; 6492} 6493 [(set_attr "type" "bcc")]) 6494 6495(define_insn "*blt_rev" 6496 [(set (pc) 6497 (if_then_else (lt (cc0) 6498 (const_int 0)) 6499 (pc) 6500 (label_ref (match_operand 0 "" ""))))] 6501 "" 6502{ 6503 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) 6504 { 6505 cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; 6506 return 0; 6507 } 6508 6509 OUTPUT_JUMP ("jge %l0", "fjnlt %l0", "jpl %l0"); 6510} 6511 [(set_attr "type" "bcc")]) 6512 6513(define_insn "*bltu_rev" 6514 [(set (pc) 6515 (if_then_else (ltu (cc0) 6516 (const_int 0)) 6517 (pc) 6518 (label_ref (match_operand 0 "" ""))))] 6519 "" 6520{ 6521 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) 6522 { 6523 cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; 6524 return 0; 6525 } 6526 6527 return "jcc %l0"; 6528} 6529 [(set_attr "type" "bcc")]) 6530 6531(define_insn "*bge_rev" 6532 [(set (pc) 6533 (if_then_else (ge (cc0) 6534 (const_int 0)) 6535 (pc) 6536 (label_ref (match_operand 0 "" ""))))] 6537 "" 6538{ 6539 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) 6540 { 6541 cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; 6542 return 0; 6543 } 6544 6545 OUTPUT_JUMP ("jlt %l0", "fjnge %l0", "jmi %l0"); 6546} 6547 [(set_attr "type" "bcc")]) 6548 6549(define_insn "*bgeu_rev" 6550 [(set (pc) 6551 (if_then_else (geu (cc0) 6552 (const_int 0)) 6553 (pc) 6554 (label_ref (match_operand 0 "" ""))))] 6555 "" 6556{ 6557 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) 6558 { 6559 cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; 6560 return 0; 6561 } 6562 6563 return "jcs %l0"; 6564} 6565 [(set_attr "type" "bcc")]) 6566 6567(define_insn "*ble_rev" 6568 [(set (pc) 6569 (if_then_else (le (cc0) 6570 (const_int 0)) 6571 (pc) 6572 (label_ref (match_operand 0 "" ""))))] 6573 "" 6574{ 6575 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) 6576 { 6577 cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; 6578 return 0; 6579 } 6580 6581 OUTPUT_JUMP ("jgt %l0", "fjnle %l0", 0); 6582} 6583 [(set_attr "type" "bcc")]) 6584 6585(define_insn "*bleu_rev" 6586 [(set (pc) 6587 (if_then_else (leu (cc0) 6588 (const_int 0)) 6589 (pc) 6590 (label_ref (match_operand 0 "" ""))))] 6591 "" 6592{ 6593 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) 6594 { 6595 cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; 6596 return 0; 6597 } 6598 6599 return "jhi %l0"; 6600} 6601 [(set_attr "type" "bcc")]) 6602 6603(define_insn "*bordered_rev" 6604 [(set (pc) 6605 (if_then_else (ordered (cc0) (const_int 0)) 6606 (pc) 6607 (label_ref (match_operand 0 "" ""))))] 6608 "TARGET_HARD_FLOAT" 6609{ 6610 gcc_assert (cc_prev_status.flags & CC_IN_68881); 6611 return "fjun %l0"; 6612} 6613 [(set_attr "type" "fbcc")]) 6614 6615(define_insn "*bunordered_rev" 6616 [(set (pc) 6617 (if_then_else (unordered (cc0) (const_int 0)) 6618 (pc) 6619 (label_ref (match_operand 0 "" ""))))] 6620 "TARGET_HARD_FLOAT" 6621{ 6622 gcc_assert (cc_prev_status.flags & CC_IN_68881); 6623 return "fjor %l0"; 6624} 6625 [(set_attr "type" "fbcc")]) 6626 6627(define_insn "*buneq_rev" 6628 [(set (pc) 6629 (if_then_else (uneq (cc0) (const_int 0)) 6630 (pc) 6631 (label_ref (match_operand 0 "" ""))))] 6632 "TARGET_HARD_FLOAT" 6633{ 6634 gcc_assert (cc_prev_status.flags & CC_IN_68881); 6635 return "fjogl %l0"; 6636} 6637 [(set_attr "type" "fbcc")]) 6638 6639(define_insn "*bunge_rev" 6640 [(set (pc) 6641 (if_then_else (unge (cc0) (const_int 0)) 6642 (pc) 6643 (label_ref (match_operand 0 "" ""))))] 6644 "TARGET_HARD_FLOAT" 6645{ 6646 gcc_assert (cc_prev_status.flags & CC_IN_68881); 6647 return "fjolt %l0"; 6648} 6649 [(set_attr "type" "fbcc")]) 6650 6651(define_insn "*bungt_rev" 6652 [(set (pc) 6653 (if_then_else (ungt (cc0) (const_int 0)) 6654 (pc) 6655 (label_ref (match_operand 0 "" ""))))] 6656 "TARGET_HARD_FLOAT" 6657{ 6658 gcc_assert (cc_prev_status.flags & CC_IN_68881); 6659 return "fjole %l0"; 6660} 6661 [(set_attr "type" "fbcc")]) 6662 6663(define_insn "*bunle_rev" 6664 [(set (pc) 6665 (if_then_else (unle (cc0) (const_int 0)) 6666 (pc) 6667 (label_ref (match_operand 0 "" ""))))] 6668 "TARGET_HARD_FLOAT" 6669{ 6670 gcc_assert (cc_prev_status.flags & CC_IN_68881); 6671 return "fjogt %l0"; 6672} 6673 [(set_attr "type" "fbcc")]) 6674 6675(define_insn "*bunlt_rev" 6676 [(set (pc) 6677 (if_then_else (unlt (cc0) (const_int 0)) 6678 (pc) 6679 (label_ref (match_operand 0 "" ""))))] 6680 "TARGET_HARD_FLOAT" 6681{ 6682 gcc_assert (cc_prev_status.flags & CC_IN_68881); 6683 return "fjoge %l0"; 6684} 6685 [(set_attr "type" "fbcc")]) 6686 6687(define_insn "*bltgt_rev" 6688 [(set (pc) 6689 (if_then_else (ltgt (cc0) (const_int 0)) 6690 (pc) 6691 (label_ref (match_operand 0 "" ""))))] 6692 "TARGET_HARD_FLOAT" 6693{ 6694 gcc_assert (cc_prev_status.flags & CC_IN_68881); 6695 return "fjueq %l0"; 6696} 6697 [(set_attr "type" "fbcc")]) 6698 6699;; Unconditional and other jump instructions 6700(define_insn "jump" 6701 [(set (pc) 6702 (label_ref (match_operand 0 "" "")))] 6703 "" 6704 "jra %l0" 6705 [(set_attr "type" "bra")]) 6706 6707(define_expand "tablejump" 6708 [(parallel [(set (pc) (match_operand 0 "" "")) 6709 (use (label_ref (match_operand 1 "" "")))])] 6710 "" 6711{ 6712#if CASE_VECTOR_PC_RELATIVE 6713 operands[0] = gen_rtx_PLUS (SImode, pc_rtx, 6714 TARGET_LONG_JUMP_TABLE_OFFSETS 6715 ? operands[0] 6716 : gen_rtx_SIGN_EXTEND (SImode, operands[0])); 6717#endif 6718}) 6719 6720;; Jump to variable address from dispatch table of absolute addresses. 6721(define_insn "*tablejump_internal" 6722 [(set (pc) (match_operand:SI 0 "register_operand" "a")) 6723 (use (label_ref (match_operand 1 "" "")))] 6724 "" 6725{ 6726 return MOTOROLA ? "jmp (%0)" : "jmp %0@"; 6727} 6728 [(set_attr "type" "jmp")]) 6729 6730;; Jump to variable address from dispatch table of relative addresses. 6731(define_insn "*tablejump_pcrel_si" 6732 [(set (pc) 6733 (plus:SI (pc) 6734 (match_operand:SI 0 "register_operand" "r"))) 6735 (use (label_ref (match_operand 1 "" "")))] 6736 "TARGET_LONG_JUMP_TABLE_OFFSETS" 6737{ 6738#ifdef ASM_RETURN_CASE_JUMP 6739 ASM_RETURN_CASE_JUMP; 6740#else 6741 return MOTOROLA ? "jmp (2,pc,%0.l)" : "jmp pc@(2,%0:l)"; 6742#endif 6743}) 6744 6745(define_insn "*tablejump_pcrel_hi" 6746 [(set (pc) 6747 (plus:SI (pc) 6748 (sign_extend:SI (match_operand:HI 0 "register_operand" "r")))) 6749 (use (label_ref (match_operand 1 "" "")))] 6750 "!TARGET_LONG_JUMP_TABLE_OFFSETS" 6751{ 6752#ifdef ASM_RETURN_CASE_JUMP 6753 ASM_RETURN_CASE_JUMP; 6754#else 6755 if (TARGET_COLDFIRE) 6756 { 6757 if (ADDRESS_REG_P (operands[0])) 6758 return MOTOROLA ? "jmp (2,pc,%0.l)" : "jmp pc@(2,%0:l)"; 6759 else if (MOTOROLA) 6760 return "ext%.l %0\;jmp (2,pc,%0.l)"; 6761 else 6762 return "extl %0\;jmp pc@(2,%0:l)"; 6763 } 6764 else 6765 return MOTOROLA ? "jmp (2,pc,%0.w)" : "jmp pc@(2,%0:w)"; 6766#endif 6767}) 6768 6769;; Decrement-and-branch insns. 6770(define_insn "*dbne_hi" 6771 [(set (pc) 6772 (if_then_else 6773 (ne (match_operand:HI 0 "nonimmediate_operand" "+d*g") 6774 (const_int 0)) 6775 (label_ref (match_operand 1 "" "")) 6776 (pc))) 6777 (set (match_dup 0) 6778 (plus:HI (match_dup 0) 6779 (const_int -1)))] 6780 "!TARGET_COLDFIRE" 6781{ 6782 CC_STATUS_INIT; 6783 if (DATA_REG_P (operands[0])) 6784 return "dbra %0,%l1"; 6785 if (GET_CODE (operands[0]) == MEM) 6786 return "subq%.w #1,%0\;jcc %l1"; 6787 return "subq%.w #1,%0\;cmp%.w #-1,%0\;jne %l1"; 6788}) 6789 6790(define_insn "*dbne_si" 6791 [(set (pc) 6792 (if_then_else 6793 (ne (match_operand:SI 0 "nonimmediate_operand" "+d*g") 6794 (const_int 0)) 6795 (label_ref (match_operand 1 "" "")) 6796 (pc))) 6797 (set (match_dup 0) 6798 (plus:SI (match_dup 0) 6799 (const_int -1)))] 6800 "!TARGET_COLDFIRE" 6801{ 6802 CC_STATUS_INIT; 6803 if (DATA_REG_P (operands[0])) 6804 return "dbra %0,%l1\;clr%.w %0\;subq%.l #1,%0\;jcc %l1"; 6805 if (GET_CODE (operands[0]) == MEM) 6806 return "subq%.l #1,%0\;jcc %l1"; 6807 return "subq%.l #1,%0\;cmp%.l #-1,%0\;jne %l1"; 6808}) 6809 6810;; Two dbra patterns that use REG_NOTES info generated by strength_reduce. 6811 6812(define_insn "*dbge_hi" 6813 [(set (pc) 6814 (if_then_else 6815 (ge (plus:HI (match_operand:HI 0 "nonimmediate_operand" "+d*am") 6816 (const_int -1)) 6817 (const_int 0)) 6818 (label_ref (match_operand 1 "" "")) 6819 (pc))) 6820 (set (match_dup 0) 6821 (plus:HI (match_dup 0) 6822 (const_int -1)))] 6823 "!TARGET_COLDFIRE && find_reg_note (insn, REG_NONNEG, 0)" 6824{ 6825 CC_STATUS_INIT; 6826 if (DATA_REG_P (operands[0])) 6827 return "dbra %0,%l1"; 6828 if (GET_CODE (operands[0]) == MEM) 6829 return "subq%.w #1,%0\;jcc %l1"; 6830 return "subq%.w #1,%0\;cmp%.w #-1,%0\;jne %l1"; 6831}) 6832 6833(define_expand "decrement_and_branch_until_zero" 6834 [(parallel [(set (pc) 6835 (if_then_else 6836 (ge (plus:SI (match_operand:SI 0 "nonimmediate_operand" "") 6837 (const_int -1)) 6838 (const_int 0)) 6839 (label_ref (match_operand 1 "" "")) 6840 (pc))) 6841 (set (match_dup 0) 6842 (plus:SI (match_dup 0) 6843 (const_int -1)))])] 6844 "" 6845 "") 6846 6847(define_insn "*dbge_si" 6848 [(set (pc) 6849 (if_then_else 6850 (ge (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+d*am") 6851 (const_int -1)) 6852 (const_int 0)) 6853 (label_ref (match_operand 1 "" "")) 6854 (pc))) 6855 (set (match_dup 0) 6856 (plus:SI (match_dup 0) 6857 (const_int -1)))] 6858 "!TARGET_COLDFIRE && find_reg_note (insn, REG_NONNEG, 0)" 6859{ 6860 CC_STATUS_INIT; 6861 if (DATA_REG_P (operands[0])) 6862 return "dbra %0,%l1\;clr%.w %0\;subq%.l #1,%0\;jcc %l1"; 6863 if (GET_CODE (operands[0]) == MEM) 6864 return "subq%.l #1,%0\;jcc %l1"; 6865 return "subq%.l #1,%0\;cmp%.l #-1,%0\;jne %l1"; 6866}) 6867 6868(define_expand "sibcall" 6869 [(call (match_operand:QI 0 "memory_operand" "") 6870 (match_operand:SI 1 "general_operand" ""))] 6871 "" 6872{ 6873 operands[0] = m68k_legitimize_sibcall_address (operands[0]); 6874}) 6875 6876(define_insn "*sibcall" 6877 [(call (mem:QI (match_operand:SI 0 "sibcall_operand" "")) 6878 (match_operand:SI 1 "general_operand" ""))] 6879 "SIBLING_CALL_P (insn)" 6880{ 6881 return output_sibcall (operands[0]); 6882}) 6883 6884(define_expand "sibcall_value" 6885 [(set (match_operand 0 "" "") 6886 (call (match_operand:QI 1 "memory_operand" "") 6887 (match_operand:SI 2 "general_operand" "")))] 6888 "" 6889{ 6890 operands[1] = m68k_legitimize_sibcall_address (operands[1]); 6891}) 6892 6893(define_insn "*sibcall_value" 6894 [(set (match_operand 0 "" "=rf,rf") 6895 (call (mem:QI (match_operand:SI 1 "sibcall_operand" "")) 6896 (match_operand:SI 2 "general_operand" "")))] 6897 "SIBLING_CALL_P (insn)" 6898{ 6899 operands[0] = operands[1]; 6900 return output_sibcall (operands[0]); 6901}) 6902 6903;; Call subroutine with no return value. 6904(define_expand "call" 6905 [(call (match_operand:QI 0 "memory_operand" "") 6906 (match_operand:SI 1 "general_operand" ""))] 6907 ;; Operand 1 not really used on the m68000. 6908 "" 6909{ 6910 operands[0] = m68k_legitimize_call_address (operands[0]); 6911}) 6912 6913(define_insn "*call" 6914 [(call (mem:QI (match_operand:SI 0 "call_operand" "a,W")) 6915 (match_operand:SI 1 "general_operand" "g,g"))] 6916 ;; Operand 1 not really used on the m68000. 6917 "!SIBLING_CALL_P (insn)" 6918{ 6919 return output_call (operands[0]); 6920} 6921 [(set_attr "type" "jsr")]) 6922 6923;; Call subroutine, returning value in operand 0 6924;; (which must be a hard register). 6925(define_expand "call_value" 6926 [(set (match_operand 0 "" "") 6927 (call (match_operand:QI 1 "memory_operand" "") 6928 (match_operand:SI 2 "general_operand" "")))] 6929 ;; Operand 2 not really used on the m68000. 6930 "" 6931{ 6932 operands[1] = m68k_legitimize_call_address (operands[1]); 6933}) 6934 6935(define_insn "*non_symbolic_call_value" 6936 [(set (match_operand 0 "" "=rf,rf") 6937 (call (mem:QI (match_operand:SI 1 "non_symbolic_call_operand" "a,W")) 6938 (match_operand:SI 2 "general_operand" "g,g")))] 6939 ;; Operand 2 not really used on the m68000. 6940 "!SIBLING_CALL_P (insn)" 6941 "jsr %a1" 6942 [(set_attr "type" "jsr") 6943 (set_attr "opx" "1")]) 6944 6945(define_insn "*symbolic_call_value_jsr" 6946 [(set (match_operand 0 "" "=rf,rf") 6947 (call (mem:QI (match_operand:SI 1 "symbolic_operand" "a,W")) 6948 (match_operand:SI 2 "general_operand" "g,g")))] 6949 ;; Operand 2 not really used on the m68000. 6950 "!SIBLING_CALL_P (insn) && m68k_symbolic_call_var == M68K_SYMBOLIC_CALL_JSR" 6951{ 6952 operands[0] = operands[1]; 6953 return m68k_symbolic_call; 6954} 6955 [(set_attr "type" "jsr") 6956 (set_attr "opx" "1")]) 6957 6958(define_insn "*symbolic_call_value_bsr" 6959 [(set (match_operand 0 "" "=rf,rf") 6960 (call (mem:QI (match_operand:SI 1 "symbolic_operand" "a,W")) 6961 (match_operand:SI 2 "general_operand" "g,g")))] 6962 ;; Operand 2 not really used on the m68000. 6963 "!SIBLING_CALL_P (insn) 6964 && (m68k_symbolic_call_var == M68K_SYMBOLIC_CALL_BSR_C 6965 || m68k_symbolic_call_var == M68K_SYMBOLIC_CALL_BSR_P)" 6966{ 6967 operands[0] = operands[1]; 6968 return m68k_symbolic_call; 6969} 6970 [(set_attr "type" "bsr") 6971 (set_attr "opx" "1")]) 6972 6973;; Call subroutine returning any type. 6974 6975(define_expand "untyped_call" 6976 [(parallel [(call (match_operand 0 "" "") 6977 (const_int 0)) 6978 (match_operand 1 "" "") 6979 (match_operand 2 "" "")])] 6980 "NEEDS_UNTYPED_CALL" 6981{ 6982 int i; 6983 6984 emit_call_insn (gen_call (operands[0], const0_rtx)); 6985 6986 for (i = 0; i < XVECLEN (operands[2], 0); i++) 6987 { 6988 rtx set = XVECEXP (operands[2], 0, i); 6989 emit_move_insn (SET_DEST (set), SET_SRC (set)); 6990 } 6991 6992 /* The optimizer does not know that the call sets the function value 6993 registers we stored in the result block. We avoid problems by 6994 claiming that all hard registers are used and clobbered at this 6995 point. */ 6996 emit_insn (gen_blockage ()); 6997 6998 DONE; 6999}) 7000 7001;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and 7002;; all of memory. This blocks insns from being moved across this point. 7003 7004(define_insn "blockage" 7005 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)] 7006 "" 7007 "") 7008 7009(define_insn "nop" 7010 [(const_int 0)] 7011 "" 7012 "nop" 7013 [(set_attr "type" "nop")]) 7014 7015(define_expand "prologue" 7016 [(const_int 0)] 7017 "" 7018{ 7019 m68k_expand_prologue (); 7020 DONE; 7021}) 7022 7023(define_expand "epilogue" 7024 [(return)] 7025 "" 7026{ 7027 m68k_expand_epilogue (false); 7028 DONE; 7029}) 7030 7031(define_expand "sibcall_epilogue" 7032 [(return)] 7033 "" 7034{ 7035 m68k_expand_epilogue (true); 7036 DONE; 7037}) 7038 7039;; Used for frameless functions which save no regs and allocate no locals. 7040(define_expand "return" 7041 [(return)] 7042 "m68k_use_return_insn ()" 7043 "") 7044 7045(define_insn "*return" 7046 [(return)] 7047 "" 7048{ 7049 switch (m68k_get_function_kind (current_function_decl)) 7050 { 7051 case m68k_fk_interrupt_handler: 7052 return "rte"; 7053 7054 case m68k_fk_interrupt_thread: 7055 return "sleep"; 7056 7057 default: 7058 if (crtl->args.pops_args) 7059 { 7060 operands[0] = GEN_INT (crtl->args.pops_args); 7061 return "rtd %0"; 7062 } 7063 else 7064 return "rts"; 7065 } 7066} 7067 [(set_attr "type" "rts")]) 7068 7069(define_insn "*m68k_store_multiple" 7070 [(match_parallel 0 "" [(match_operand 1 "")])] 7071 "m68k_movem_pattern_p (operands[0], NULL, 0, true)" 7072{ 7073 return m68k_output_movem (operands, operands[0], 0, true); 7074}) 7075 7076(define_insn "*m68k_store_multiple_automod" 7077 [(match_parallel 0 "" 7078 [(set (match_operand:SI 1 "register_operand" "=a") 7079 (plus:SI (match_operand:SI 2 "register_operand" "1") 7080 (match_operand:SI 3 "const_int_operand")))])] 7081 "m68k_movem_pattern_p (operands[0], operands[1], INTVAL (operands[3]), true)" 7082{ 7083 return m68k_output_movem (operands, operands[0], INTVAL (operands[3]), true); 7084}) 7085 7086(define_insn "*m68k_load_multiple" 7087 [(match_parallel 0 "" [(match_operand 1 "")])] 7088 "m68k_movem_pattern_p (operands[0], NULL, 0, false)" 7089{ 7090 return m68k_output_movem (operands, operands[0], 0, false); 7091}) 7092 7093(define_insn "*m68k_load_multiple_automod" 7094 [(match_parallel 0 "" 7095 [(set (match_operand:SI 1 "register_operand" "=a") 7096 (plus:SI (match_operand:SI 2 "register_operand" "1") 7097 (match_operand:SI 3 "const_int_operand")))])] 7098 "m68k_movem_pattern_p (operands[0], operands[1], 7099 INTVAL (operands[3]), false)" 7100{ 7101 return m68k_output_movem (operands, operands[0], 7102 INTVAL (operands[3]), false); 7103}) 7104 7105(define_expand "link" 7106 [(parallel 7107 [(set (match_operand:SI 0 "register_operand") 7108 (plus:SI (reg:SI SP_REG) (const_int -4))) 7109 (set (match_dup 2) 7110 (match_dup 0)) 7111 (set (reg:SI SP_REG) 7112 (plus:SI (reg:SI SP_REG) 7113 (match_operand:SI 1 "const_int_operand")))])] 7114 "TARGET_68020 || INTVAL (operands[1]) >= -0x8004" 7115{ 7116 operands[2] = gen_frame_mem (SImode, 7117 plus_constant (Pmode, stack_pointer_rtx, -4)); 7118}) 7119 7120(define_insn "*link" 7121 [(set (match_operand:SI 0 "register_operand" "+r") 7122 (plus:SI (reg:SI SP_REG) (const_int -4))) 7123 (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4))) 7124 (match_dup 0)) 7125 (set (reg:SI SP_REG) 7126 (plus:SI (reg:SI SP_REG) 7127 (match_operand:SI 1 "const_int_operand")))] 7128 "TARGET_68020 || INTVAL (operands[1]) >= -0x8004" 7129{ 7130 operands[1] = GEN_INT (INTVAL (operands[1]) + 4); 7131 if (!MOTOROLA) 7132 return "link %0,%1"; 7133 else if (INTVAL (operands[1]) >= -0x8000) 7134 return "link.w %0,%1"; 7135 else 7136 return "link.l %0,%1"; 7137} 7138 [(set_attr "type" "link")]) 7139 7140(define_expand "unlink" 7141 [(parallel 7142 [(set (match_operand:SI 0 "register_operand") 7143 (match_dup 1)) 7144 (set (reg:SI SP_REG) 7145 (plus:SI (match_dup 0) 7146 (const_int 4)))])] 7147 "" 7148{ 7149 operands[1] = gen_frame_mem (SImode, copy_rtx (operands[0])); 7150}) 7151 7152(define_insn "*unlink" 7153 [(set (match_operand:SI 0 "register_operand" "+r") 7154 (mem:SI (match_dup 0))) 7155 (set (reg:SI SP_REG) 7156 (plus:SI (match_dup 0) 7157 (const_int 4)))] 7158 "" 7159 "unlk %0" 7160 [(set_attr "type" "unlk")]) 7161 7162(define_insn "load_got" 7163 [(set (match_operand:SI 0 "register_operand" "=a") 7164 (unspec:SI [(const_int 0)] UNSPEC_GOT))] 7165 "" 7166{ 7167 if (TARGET_ID_SHARED_LIBRARY) 7168 { 7169 operands[1] = gen_rtx_REG (Pmode, PIC_REG); 7170 return MOTOROLA ? "move.l %?(%1),%0" : "movel %1@(%?), %0"; 7171 } 7172 else if (MOTOROLA) 7173 { 7174 if (TARGET_COLDFIRE) 7175 /* Load the full 32-bit PC-relative offset of 7176 _GLOBAL_OFFSET_TABLE_ into the PIC register, then use it to 7177 calculate the absolute value. The offset and "lea" 7178 operation word together occupy 6 bytes. */ 7179 return ("move.l #_GLOBAL_OFFSET_TABLE_@GOTPC, %0\n\t" 7180 "lea (-6, %%pc, %0), %0"); 7181 else 7182 return "lea (%%pc, _GLOBAL_OFFSET_TABLE_@GOTPC), %0"; 7183 } 7184 else 7185 return ("movel #_GLOBAL_OFFSET_TABLE_, %0\n\t" 7186 "lea %%pc@(0,%0:l),%0"); 7187}) 7188 7189(define_insn "indirect_jump" 7190 [(set (pc) (match_operand:SI 0 "address_operand" "p"))] 7191 "" 7192 "jmp %a0" 7193 [(set_attr "type" "jmp")]) 7194 7195;; This should not be used unless the add/sub insns can't be. 7196 7197(define_insn "*lea" 7198 [(set (match_operand:SI 0 "nonimmediate_operand" "=a") 7199 (match_operand:QI 1 "address_operand" "p"))] 7200 "" 7201 "lea %a1,%0") 7202 7203;; This is the first machine-dependent peephole optimization. 7204;; It is useful when a floating value is returned from a function call 7205;; and then is moved into an FP register. 7206;; But it is mainly intended to test the support for these optimizations. 7207 7208(define_peephole2 7209 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4))) 7210 (set (match_operand:DF 0 "register_operand" "") 7211 (match_operand:DF 1 "register_operand" ""))] 7212 "FP_REG_P (operands[0]) && !FP_REG_P (operands[1])" 7213 [(set (mem:SI (reg:SI SP_REG)) (match_dup 1)) 7214 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 2)) 7215 (set (match_dup 0) (mem:DF (post_inc:SI (reg:SI SP_REG))))] 7216 "split_di(operands + 1, 1, operands + 1, operands + 2);") 7217 7218;; Optimize a stack-adjust followed by a push of an argument. 7219;; This is said to happen frequently with -msoft-float 7220;; when there are consecutive library calls. 7221 7222(define_peephole2 7223 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4))) 7224 (set (match_operand:SF 0 "push_operand" "") 7225 (match_operand:SF 1 "general_operand" ""))] 7226 "!reg_mentioned_p (stack_pointer_rtx, operands[0])" 7227 [(set (match_dup 0) (match_dup 1))] 7228 "operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);") 7229 7230(define_peephole2 7231 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) 7232 (match_operand:SI 0 "const_int_operand" ""))) 7233 (set (match_operand:SF 1 "push_operand" "") 7234 (match_operand:SF 2 "general_operand" ""))] 7235 "INTVAL (operands[0]) > 4 7236 && !reg_mentioned_p (stack_pointer_rtx, operands[2])" 7237 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 0))) 7238 (set (match_dup 1) (match_dup 2))] 7239{ 7240 operands[0] = GEN_INT (INTVAL (operands[0]) - 4); 7241 operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx); 7242}) 7243 7244;; Speed up stack adjust followed by a fullword fixedpoint push. 7245;; Constant operands need special care, as replacing a "pea X.w" with 7246;; "move.l #X,(%sp)" is often not a win. 7247 7248;; Already done by the previous csa pass, left as reference. 7249(define_peephole2 7250 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4))) 7251 (set (match_operand:SI 0 "push_operand" "") 7252 (match_operand:SI 1 "general_operand" ""))] 7253 "!reg_mentioned_p (stack_pointer_rtx, operands[1])" 7254 [(set (match_dup 0) (match_dup 1))] 7255 "operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);") 7256 7257;; Try to use moveq, after stack push has been changed into a simple move. 7258(define_peephole2 7259 [(match_scratch:SI 2 "d") 7260 (set (match_operand:SI 0 "memory_operand" "") 7261 (match_operand:SI 1 "const_int_operand" ""))] 7262 "GET_CODE (XEXP (operands[0], 0)) != PRE_DEC 7263 && INTVAL (operands[1]) != 0 7264 && IN_RANGE (INTVAL (operands[1]), -0x80, 0x7f) 7265 && !valid_mov3q_const (INTVAL (operands[1]))" 7266 [(set (match_dup 2) (match_dup 1)) 7267 (set (match_dup 0) (match_dup 2))]) 7268 7269;; This sequence adds an instruction, but is two bytes shorter. 7270(define_peephole2 7271 [(match_scratch:SI 2 "d") 7272 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 12))) 7273 (set (match_operand:SI 0 "push_operand" "") 7274 (match_operand:SI 1 "const_int_operand" ""))] 7275 "INTVAL (operands[1]) != 0 7276 && IN_RANGE (INTVAL (operands[1]), -0x80, 0x7f) 7277 && !valid_mov3q_const (INTVAL (operands[1]))" 7278 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8))) 7279 (set (match_dup 2) (match_dup 1)) 7280 (set (match_dup 0) (match_dup 2))] 7281 "operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);") 7282 7283;; Changing pea X.w into a move.l is no real win here. 7284(define_peephole2 7285 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) 7286 (match_operand:SI 0 "const_int_operand" ""))) 7287 (set (match_operand:SI 1 "push_operand" "") 7288 (match_operand:SI 2 "general_operand" ""))] 7289 "INTVAL (operands[0]) > 4 7290 && !reg_mentioned_p (stack_pointer_rtx, operands[2]) 7291 && !(CONST_INT_P (operands[2]) && INTVAL (operands[2]) != 0 7292 && IN_RANGE (INTVAL (operands[2]), -0x8000, 0x7fff) 7293 && !valid_mov3q_const (INTVAL (operands[2])))" 7294 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 0))) 7295 (set (match_dup 1) (match_dup 2))] 7296{ 7297 operands[0] = GEN_INT (INTVAL (operands[0]) - 4); 7298 operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx); 7299}) 7300 7301;; Speed up pushing a single byte/two bytes but leaving four bytes of space 7302;; (which differs slightly between m680x0 and ColdFire). 7303 7304(define_peephole2 7305 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4))) 7306 (set (match_operand:QI 0 "memory_operand" "") 7307 (match_operand:QI 1 "register_operand" ""))] 7308 "!reg_mentioned_p (stack_pointer_rtx, operands[1]) 7309 && GET_CODE (XEXP (operands[0], 0)) == PLUS 7310 && rtx_equal_p (XEXP (XEXP (operands[0], 0), 0), stack_pointer_rtx) 7311 && CONST_INT_P (XEXP (XEXP (operands[0], 0), 1)) 7312 && INTVAL (XEXP (XEXP (operands[0], 0), 1)) == 3" 7313 [(set (match_dup 0) (match_dup 1))] 7314{ 7315 rtx addr = gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx); 7316 operands[0] = adjust_automodify_address (operands[0], SImode, addr, -3); 7317 operands[1] = simplify_gen_subreg (SImode, operands[1], QImode, 0); 7318}) 7319 7320(define_peephole2 7321 [(set (match_operand:QI 0 "push_operand" "") 7322 (match_operand:QI 1 "register_operand" "")) 7323 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -3)))] 7324 "!reg_mentioned_p (stack_pointer_rtx, operands[1])" 7325 [(set (match_dup 0) (match_dup 1))] 7326{ 7327 operands[0] = adjust_automodify_address (operands[0], SImode, 7328 XEXP (operands[0], 0), -3); 7329 operands[1] = simplify_gen_subreg (SImode, operands[1], QImode, 0); 7330}) 7331 7332(define_peephole2 7333 [(set (match_operand:HI 0 "push_operand" "") 7334 (match_operand:HI 1 "register_operand" "")) 7335 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -2)))] 7336 "!reg_mentioned_p (stack_pointer_rtx, operands[1])" 7337 [(set (match_dup 0) (match_dup 1))] 7338{ 7339 operands[0] = adjust_automodify_address (operands[0], SImode, 7340 XEXP (operands[0], 0), -2); 7341 operands[1] = simplify_gen_subreg (SImode, operands[1], HImode, 0); 7342}) 7343 7344;; Optimize a series of strict_low_part assignments 7345 7346(define_peephole2 7347 [(set (match_operand:SI 0 "register_operand" "") 7348 (const_int 0)) 7349 (set (strict_low_part (match_operand:HI 1 "register_operand" "")) 7350 (match_operand:HI 2 "general_operand" ""))] 7351 "REGNO (operands[0]) == REGNO (operands[1]) 7352 && strict_low_part_peephole_ok (HImode, insn, operands[0])" 7353 [(set (strict_low_part (match_dup 1)) (match_dup 2))] 7354 "") 7355 7356(define_peephole2 7357 [(set (match_operand:SI 0 "register_operand" "") 7358 (const_int 0)) 7359 (set (strict_low_part (match_operand:QI 1 "register_operand" "")) 7360 (match_operand:QI 2 "general_operand" ""))] 7361 "REGNO (operands[0]) == REGNO (operands[1]) 7362 && strict_low_part_peephole_ok (QImode, insn, operands[0])" 7363 [(set (strict_low_part (match_dup 1)) (match_dup 2))] 7364 "") 7365 7366;; dbCC peepholes 7367;; 7368;; Turns 7369;; loop: 7370;; [ ... ] 7371;; jCC label ; abnormal loop termination 7372;; dbra dN, loop ; normal loop termination 7373;; 7374;; Into 7375;; loop: 7376;; [ ... ] 7377;; dbCC dN, loop 7378;; jCC label 7379;; 7380;; Which moves the jCC condition outside the inner loop for free. 7381;; 7382 7383(define_peephole 7384 [(set (pc) (if_then_else (match_operator 3 "valid_dbcc_comparison_p" 7385 [(cc0) (const_int 0)]) 7386 (label_ref (match_operand 2 "" "")) 7387 (pc))) 7388 (parallel 7389 [(set (pc) 7390 (if_then_else 7391 (ne (match_operand:HI 0 "register_operand" "") 7392 (const_int 0)) 7393 (label_ref (match_operand 1 "" "")) 7394 (pc))) 7395 (set (match_dup 0) 7396 (plus:HI (match_dup 0) 7397 (const_int -1)))])] 7398 "!TARGET_COLDFIRE && DATA_REG_P (operands[0]) && ! flags_in_68881 ()" 7399{ 7400 CC_STATUS_INIT; 7401 output_dbcc_and_branch (operands); 7402 return ""; 7403}) 7404 7405(define_peephole 7406 [(set (pc) (if_then_else (match_operator 3 "valid_dbcc_comparison_p" 7407 [(cc0) (const_int 0)]) 7408 (label_ref (match_operand 2 "" "")) 7409 (pc))) 7410 (parallel 7411 [(set (pc) 7412 (if_then_else 7413 (ne (match_operand:SI 0 "register_operand" "") 7414 (const_int 0)) 7415 (label_ref (match_operand 1 "" "")) 7416 (pc))) 7417 (set (match_dup 0) 7418 (plus:SI (match_dup 0) 7419 (const_int -1)))])] 7420 "!TARGET_COLDFIRE && DATA_REG_P (operands[0]) && ! flags_in_68881 ()" 7421{ 7422 CC_STATUS_INIT; 7423 output_dbcc_and_branch (operands); 7424 return ""; 7425}) 7426 7427(define_peephole 7428 [(set (pc) (if_then_else (match_operator 3 "valid_dbcc_comparison_p" 7429 [(cc0) (const_int 0)]) 7430 (label_ref (match_operand 2 "" "")) 7431 (pc))) 7432 (parallel 7433 [(set (pc) 7434 (if_then_else 7435 (ge (plus:HI (match_operand:HI 0 "register_operand" "") 7436 (const_int -1)) 7437 (const_int 0)) 7438 (label_ref (match_operand 1 "" "")) 7439 (pc))) 7440 (set (match_dup 0) 7441 (plus:HI (match_dup 0) 7442 (const_int -1)))])] 7443 "!TARGET_COLDFIRE && DATA_REG_P (operands[0]) && ! flags_in_68881 ()" 7444{ 7445 CC_STATUS_INIT; 7446 output_dbcc_and_branch (operands); 7447 return ""; 7448}) 7449 7450(define_peephole 7451 [(set (pc) (if_then_else (match_operator 3 "valid_dbcc_comparison_p" 7452 [(cc0) (const_int 0)]) 7453 (label_ref (match_operand 2 "" "")) 7454 (pc))) 7455 (parallel 7456 [(set (pc) 7457 (if_then_else 7458 (ge (plus:SI (match_operand:SI 0 "register_operand" "") 7459 (const_int -1)) 7460 (const_int 0)) 7461 (label_ref (match_operand 1 "" "")) 7462 (pc))) 7463 (set (match_dup 0) 7464 (plus:SI (match_dup 0) 7465 (const_int -1)))])] 7466 "!TARGET_COLDFIRE && DATA_REG_P (operands[0]) && ! flags_in_68881 ()" 7467{ 7468 CC_STATUS_INIT; 7469 output_dbcc_and_branch (operands); 7470 return ""; 7471}) 7472 7473 7474(define_insn "extendsfxf2" 7475 [(set (match_operand:XF 0 "nonimmediate_operand" "=fm,f") 7476 (float_extend:XF (match_operand:SF 1 "general_operand" "f,rmF")))] 7477 "TARGET_68881" 7478{ 7479 if (FP_REG_P (operands[0]) && FP_REG_P (operands[1])) 7480 { 7481 if (REGNO (operands[0]) == REGNO (operands[1])) 7482 { 7483 /* Extending float to double in an fp-reg is a no-op. 7484 NOTICE_UPDATE_CC has already assumed that the 7485 cc will be set. So cancel what it did. */ 7486 cc_status = cc_prev_status; 7487 return ""; 7488 } 7489 return "f%$move%.x %1,%0"; 7490 } 7491 if (FP_REG_P (operands[0])) 7492 { 7493 if (FP_REG_P (operands[1])) 7494 return "f%$move%.x %1,%0"; 7495 else if (ADDRESS_REG_P (operands[1])) 7496 return "move%.l %1,%-\;f%$move%.s %+,%0"; 7497 else if (GET_CODE (operands[1]) == CONST_DOUBLE) 7498 return output_move_const_single (operands); 7499 return "f%$move%.s %f1,%0"; 7500 } 7501 return "fmove%.x %f1,%0"; 7502}) 7503 7504 7505(define_insn "extenddfxf2" 7506 [(set (match_operand:XF 0 "nonimmediate_operand" "=fm,f") 7507 (float_extend:XF 7508 (match_operand:DF 1 "general_operand" "f,rmE")))] 7509 "TARGET_68881" 7510{ 7511 if (FP_REG_P (operands[0]) && FP_REG_P (operands[1])) 7512 { 7513 if (REGNO (operands[0]) == REGNO (operands[1])) 7514 { 7515 /* Extending float to double in an fp-reg is a no-op. 7516 NOTICE_UPDATE_CC has already assumed that the 7517 cc will be set. So cancel what it did. */ 7518 cc_status = cc_prev_status; 7519 return ""; 7520 } 7521 return "fmove%.x %1,%0"; 7522 } 7523 if (FP_REG_P (operands[0])) 7524 { 7525 if (REG_P (operands[1])) 7526 { 7527 rtx xoperands[2]; 7528 xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1); 7529 output_asm_insn ("move%.l %1,%-", xoperands); 7530 output_asm_insn ("move%.l %1,%-", operands); 7531 return "f%&move%.d %+,%0"; 7532 } 7533 if (GET_CODE (operands[1]) == CONST_DOUBLE) 7534 return output_move_const_double (operands); 7535 return "f%&move%.d %f1,%0"; 7536 } 7537 return "fmove%.x %f1,%0"; 7538}) 7539 7540(define_insn "truncxfdf2" 7541 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,!r") 7542 (float_truncate:DF 7543 (match_operand:XF 1 "general_operand" "f,f")))] 7544 "TARGET_68881" 7545{ 7546 if (REG_P (operands[0])) 7547 { 7548 output_asm_insn ("fmove%.d %f1,%-\;move%.l %+,%0", operands); 7549 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); 7550 return "move%.l %+,%0"; 7551 } 7552 return "fmove%.d %f1,%0"; 7553}) 7554 7555(define_insn "truncxfsf2" 7556 [(set (match_operand:SF 0 "nonimmediate_operand" "=dm") 7557 (float_truncate:SF 7558 (match_operand:XF 1 "general_operand" "f")))] 7559 "TARGET_68881" 7560 "fmove%.s %f1,%0") 7561 7562(define_insn "sin<mode>2" 7563 [(set (match_operand:FP 0 "nonimmediate_operand" "=f") 7564 (unspec:FP 7565 [(match_operand:FP 1 "general_operand" "f<FP:dreg>m")] UNSPEC_SIN))] 7566 "TARGET_68881 && flag_unsafe_math_optimizations" 7567{ 7568 if (FP_REG_P (operands[1])) 7569 return "fsin%.x %1,%0"; 7570 else 7571 return "fsin%.<FP:prec> %1,%0"; 7572}) 7573 7574(define_insn "cos<mode>2" 7575 [(set (match_operand:FP 0 "nonimmediate_operand" "=f") 7576 (unspec:FP 7577 [(match_operand:FP 1 "general_operand" "f<FP:dreg>m")] UNSPEC_COS))] 7578 "TARGET_68881 && flag_unsafe_math_optimizations" 7579{ 7580 if (FP_REG_P (operands[1])) 7581 return "fcos%.x %1,%0"; 7582 else 7583 return "fcos%.<FP:prec> %1,%0"; 7584}) 7585 7586;; Unconditional traps are assumed to have (const_int 1) for the condition. 7587(define_insn "trap" 7588 [(trap_if (const_int 1) (const_int 7))] 7589 "" 7590 "trap #7" 7591 [(set_attr "type" "trap")]) 7592 7593(define_expand "ctrapdi4" 7594 [(trap_if (match_operator 0 "ordered_comparison_operator" 7595 [(cc0) (const_int 0)]) 7596 (match_operand:SI 3 "const1_operand" ""))] 7597 "TARGET_68020" 7598{ 7599 if (operands[2] == const0_rtx) 7600 emit_insn (gen_tstdi (operands[1])); 7601 else 7602 emit_insn (gen_cmpdi (operands[1], operands[2])); 7603 operands[1] = cc0_rtx; 7604 operands[2] = const0_rtx; 7605}) 7606 7607(define_expand "ctrapsi4" 7608 [(set (cc0) 7609 (compare (match_operand:SI 1 "nonimmediate_operand" "") 7610 (match_operand:SI 2 "general_operand" ""))) 7611 (trap_if (match_operator 0 "ordered_comparison_operator" 7612 [(cc0) (const_int 0)]) 7613 (match_operand:SI 3 "const1_operand" ""))] 7614 "TARGET_68020" 7615 "") 7616 7617(define_expand "ctraphi4" 7618 [(set (cc0) 7619 (compare (match_operand:HI 1 "nonimmediate_src_operand" "") 7620 (match_operand:HI 2 "general_src_operand" ""))) 7621 (trap_if (match_operator 0 "ordered_comparison_operator" 7622 [(cc0) (const_int 0)]) 7623 (match_operand:SI 3 "const1_operand" ""))] 7624 "TARGET_68020" 7625 "") 7626 7627(define_expand "ctrapqi4" 7628 [(set (cc0) 7629 (compare (match_operand:QI 1 "nonimmediate_src_operand" "") 7630 (match_operand:QI 2 "general_src_operand" ""))) 7631 (trap_if (match_operator 0 "ordered_comparison_operator" 7632 [(cc0) (const_int 0)]) 7633 (match_operand:SI 3 "const1_operand" ""))] 7634 "TARGET_68020" 7635 "") 7636 7637(define_insn "*conditional_trap" 7638 [(trap_if (match_operator 0 "ordered_comparison_operator" 7639 [(cc0) (const_int 0)]) 7640 (match_operand:SI 1 "const1_operand" "I"))] 7641 "TARGET_68020 && ! flags_in_68881 ()" 7642{ 7643 switch (GET_CODE (operands[0])) 7644 { 7645 case EQ: return "trapeq"; 7646 case NE: return "trapne"; 7647 case GT: return "trapgt"; 7648 case GTU: return "traphi"; 7649 case LT: return "traplt"; 7650 case LTU: return "trapcs"; 7651 case GE: return "trapge"; 7652 case GEU: return "trapcc"; 7653 case LE: return "traple"; 7654 case LEU: return "trapls"; 7655 default: gcc_unreachable (); 7656 } 7657}) 7658 7659;; These are to prevent the scheduler from moving stores to the frame 7660;; before the stack adjustment. 7661(define_insn "stack_tie" 7662 [(set (mem:BLK (scratch)) 7663 (unspec:BLK [(match_operand:SI 0 "register_operand" "r") 7664 (match_operand:SI 1 "register_operand" "r")] 7665 UNSPEC_TIE))] 7666 "" 7667 "" 7668 [(set_attr "type" "ignore")]) 7669 7670;; Instruction that subscribes one word in ColdFire instruction buffer. 7671;; This instruction is used within scheduler only and should not appear 7672;; in the instruction stream. 7673(define_insn "ib" 7674 [(unspec [(const_int 0)] UNSPEC_IB)] 7675 "" 7676 "#" 7677 [(set_attr "type" "ib")]) 7678 7679(include "cf.md") 7680(include "sync.md") 7681 7682;; Convert 7683;; 7684;; move.l 4(%a0),%a0 7685;; clr.b (%a0,%a1.l) 7686;; 7687;; into 7688;; 7689;; add.l 4(%a0),%a1 7690;; clr.b (%a1) 7691;; 7692;; The latter is smaller. It is faster on all models except m68060. 7693 7694(define_peephole2 7695 [(set (match_operand:SI 0 "register_operand" "") 7696 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "") 7697 (match_operand:SI 2 "const_int_operand" "")))) 7698 (set (mem:QI (plus:SI (match_operand:SI 3 "register_operand" "") 7699 (match_operand:SI 4 "register_operand" ""))) 7700 (const_int 0))] 7701 "(optimize_size || !TUNE_68060) 7702 && (operands[0] == operands[3] || operands[0] == operands[4]) 7703 && ADDRESS_REG_P (operands[1]) 7704 && ADDRESS_REG_P ((operands[0] == operands[3]) ? operands[4] : operands[3]) 7705 && peep2_reg_dead_p (2, operands[3]) 7706 && peep2_reg_dead_p (2, operands[4])" 7707 [(set (match_dup 5) 7708 (plus:SI (match_dup 5) 7709 (mem:SI (plus:SI (match_dup 1) 7710 (match_dup 2))))) 7711 (set (mem:QI (match_dup 5)) 7712 (const_int 0))] 7713 "operands[5] = (operands[0] == operands[3]) ? operands[4] : operands[3];") 7714 7715;; We want to turn 7716;; moveq const,dX 7717;; cmp.l dX,dY 7718;; je/jne 7719;; 7720;; into 7721;; addq/subq -const,dY 7722;; cmp.l dY, 0 7723;; je/jne 7724;; 7725;; dX and dY must both be dead at the end of the sequence and the constant 7726;; must be valid for addq/subq. 7727;; 7728;; Essentially we're making it trivial for final to realize the comparison 7729;; is not needed 7730;; 7731;; Testing has shown a variant where the operands are reversed in the 7732;; comparison never hits, so I have not included that variant. 7733;; 7734 7735(define_peephole2 7736 [(set (match_operand:SI 0 "register_operand" "") 7737 (match_operand:SI 1 "addq_subq_operand" "")) 7738 (set (cc0) (compare (match_operand:SI 2 "register_operand" "") 7739 (match_dup 0))) 7740 (set (pc) (if_then_else (match_operator 5 "equality_comparison_operator" 7741 [(cc0) (const_int 0)]) 7742 (match_operand 3 "pc_or_label_operand") 7743 (match_operand 4 "pc_or_label_operand")))] 7744 "peep2_reg_dead_p (2, operands[0]) 7745 && peep2_reg_dead_p (2, operands[2]) 7746 && (operands[3] == pc_rtx || operands[4] == pc_rtx) 7747 && DATA_REG_P (operands[2]) 7748 && !rtx_equal_p (operands[0], operands[2])" 7749 [(set (match_dup 2) (plus:SI (match_dup 2) (match_dup 6))) 7750 (set (cc0) (compare (match_dup 2) (const_int 0))) 7751 (set (pc) (if_then_else (match_op_dup 5 [(cc0) (const_int 0)]) 7752 (match_dup 3) 7753 (match_dup 4)))] 7754 "operands[6] = GEN_INT (-INTVAL (operands[1]));") 7755 7756(define_peephole2 7757 [(set (match_operand:SI 0 "register_operand" "") 7758 (match_operand:SI 1 "pow2_m1_operand" "")) 7759 (set (cc0) (compare (match_operand:SI 2 "register_operand" "") 7760 (match_operand:SI 3 "register_operand" ""))) 7761 (set (pc) (if_then_else (gtu (cc0) (const_int 0)) 7762 (match_operand 4 "pc_or_label_operand") 7763 (match_operand 5 "pc_or_label_operand")))] 7764 "INTVAL (operands[1]) <= 255 7765 && operands[0] == operands[3] 7766 && peep2_reg_dead_p (2, operands[0]) 7767 && peep2_reg_dead_p (2, operands[2]) 7768 && (operands[4] == pc_rtx || operands[5] == pc_rtx) 7769 && (optimize_size || TUNE_68040_60) 7770 && DATA_REG_P (operands[2])" 7771 [(set (match_dup 7) (lshiftrt:SI (match_dup 7) (match_dup 6))) 7772 (set (cc0) (compare (match_dup 7) (const_int 0))) 7773 (set (pc) (if_then_else (ne (cc0) (const_int 0)) 7774 (match_dup 4) (match_dup 5)))] 7775 " 7776{ 7777 operands[6] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1)); 7778 operands[7] = operands[2]; 7779}") 7780 7781(define_peephole2 7782 [(set (cc0) (compare (match_operand:SI 0 "register_operand" "") 7783 (match_operand:SI 1 "pow2_m1_operand" ""))) 7784 (set (pc) (if_then_else (gtu (cc0) (const_int 0)) 7785 (match_operand 2 "pc_or_label_operand") 7786 (match_operand 3 "pc_or_label_operand")))] 7787 "INTVAL (operands[1]) <= 255 7788 && peep2_reg_dead_p (1, operands[0]) 7789 && (operands[2] == pc_rtx || operands[3] == pc_rtx) 7790 && (optimize_size || TUNE_68040_60) 7791 && DATA_REG_P (operands[0])" 7792 [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 4))) 7793 (set (cc0) (compare (match_dup 0) (const_int 0))) 7794 (set (pc) (if_then_else (ne (cc0) (const_int 0)) 7795 (match_dup 2) (match_dup 3)))] 7796 "{ operands[4] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1)); }") 7797 7798(define_peephole2 7799 [(set (match_operand:SI 0 "register_operand" "") 7800 (match_operand:SI 1 "pow2_m1_operand" "")) 7801 (set (cc0) (compare (match_operand:SI 2 "register_operand" "") 7802 (match_operand:SI 3 "register_operand" ""))) 7803 (set (pc) (if_then_else (leu (cc0) (const_int 0)) 7804 (match_operand 4 "pc_or_label_operand") 7805 (match_operand 5 "pc_or_label_operand")))] 7806 "INTVAL (operands[1]) <= 255 7807 && operands[0] == operands[3] 7808 && peep2_reg_dead_p (2, operands[0]) 7809 && peep2_reg_dead_p (2, operands[2]) 7810 && (operands[4] == pc_rtx || operands[5] == pc_rtx) 7811 && (optimize_size || TUNE_68040_60) 7812 && DATA_REG_P (operands[2])" 7813 [(set (match_dup 7) (lshiftrt:SI (match_dup 7) (match_dup 6))) 7814 (set (cc0) (compare (match_dup 7) (const_int 0))) 7815 (set (pc) (if_then_else (eq (cc0) (const_int 0)) 7816 (match_dup 4) (match_dup 5)))] 7817 " 7818{ 7819 operands[6] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1)); 7820 operands[7] = operands[2]; 7821}") 7822(define_peephole2 7823 [(set (cc0) (compare (match_operand:SI 0 "register_operand" "") 7824 (match_operand:SI 1 "pow2_m1_operand" ""))) 7825 (set (pc) (if_then_else (leu (cc0) (const_int 0)) 7826 (match_operand 2 "pc_or_label_operand") 7827 (match_operand 3 "pc_or_label_operand")))] 7828 "INTVAL (operands[1]) <= 255 7829 && peep2_reg_dead_p (1, operands[0]) 7830 && (operands[2] == pc_rtx || operands[3] == pc_rtx) 7831 && (optimize_size || TUNE_68040_60) 7832 && DATA_REG_P (operands[0])" 7833 [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 4))) 7834 (set (cc0) (compare (match_dup 0) (const_int 0))) 7835 (set (pc) (if_then_else (eq (cc0) (const_int 0)) 7836 (match_dup 2) (match_dup 3)))] 7837 "{ operands[4] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1)); }") 7838 7839;; When optimizing for size or for the original 68000 or 68010, we can 7840;; improve some relational tests against 65536 (which get canonicalized 7841;; internally against 65535). 7842;; The rotate in the output pattern will turn into a swap. 7843(define_peephole2 7844 [(set (cc0) (compare (match_operand:SI 0 "register_operand" "") 7845 (const_int 65535))) 7846 (set (pc) (if_then_else (match_operator 1 "swap_peephole_relational_operator" 7847 [(cc0) (const_int 0)]) 7848 (match_operand 2 "pc_or_label_operand") 7849 (match_operand 3 "pc_or_label_operand")))] 7850 "peep2_reg_dead_p (1, operands[0]) 7851 && (operands[2] == pc_rtx || operands[3] == pc_rtx) 7852 && (optimize_size || TUNE_68000_10) 7853 && DATA_REG_P (operands[0])" 7854 [(set (match_dup 0) (rotate:SI (match_dup 0) (const_int 16))) 7855 (set (cc0) (compare (subreg:HI (match_dup 0) 2) (const_int 0))) 7856 (set (pc) (if_then_else (match_op_dup 1 [(cc0) (const_int 0)]) 7857 (match_dup 2) (match_dup 3)))] 7858 "") 7859