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