sh.md revision 1.1.1.1
1;;- Machine description for Renesas / SuperH SH. 2;; Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 3;; 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. 4;; Contributed by Steve Chamberlain (sac@cygnus.com). 5;; Improved by Jim Wilson (wilson@cygnus.com). 6 7;; This file is part of GCC. 8 9;; GCC is free software; you can redistribute it and/or modify 10;; it under the terms of the GNU General Public License as published by 11;; the Free Software Foundation; either version 3, or (at your option) 12;; any later version. 13 14;; GCC is distributed in the hope that it will be useful, 15;; but WITHOUT ANY WARRANTY; without even the implied warranty of 16;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17;; GNU General Public License for more details. 18 19;; You should have received a copy of the GNU General Public License 20;; along with GCC; see the file COPYING3. If not see 21;; <http://www.gnu.org/licenses/>. 22 23 24;; ??? Should prepend a * to all pattern names which are not used. 25;; This will make the compiler smaller, and rebuilds after changes faster. 26 27;; ??? Should be enhanced to include support for many more GNU superoptimizer 28;; sequences. Especially the sequences for arithmetic right shifts. 29 30;; ??? Should check all DImode patterns for consistency and usefulness. 31 32;; ??? The MAC.W and MAC.L instructions are not supported. There is no 33;; way to generate them. 34 35;; ??? The cmp/str instruction is not supported. Perhaps it can be used 36;; for a str* inline function. 37 38;; BSR is not generated by the compiler proper, but when relaxing, it 39;; generates .uses pseudo-ops that allow linker relaxation to create 40;; BSR. This is actually implemented in bfd/{coff,elf32}-sh.c 41 42;; Special constraints for SH machine description: 43;; 44;; t -- T 45;; x -- mac 46;; l -- pr 47;; z -- r0 48;; 49;; Special formats used for outputting SH instructions: 50;; 51;; %. -- print a .s if insn needs delay slot 52;; %@ -- print rte/rts if is/isn't an interrupt function 53;; %# -- output a nop if there is nothing to put in the delay slot 54;; %O -- print a constant without the # 55;; %R -- print the lsw reg of a double 56;; %S -- print the msw reg of a double 57;; %T -- print next word of a double REG or MEM 58;; 59;; Special predicates: 60;; 61;; arith_operand -- operand is valid source for arithmetic op 62;; arith_reg_operand -- operand is valid register for arithmetic op 63;; general_movdst_operand -- operand is valid move destination 64;; general_movsrc_operand -- operand is valid move source 65;; logical_operand -- operand is valid source for logical op 66 67;; ------------------------------------------------------------------------- 68;; Constants 69;; ------------------------------------------------------------------------- 70 71(define_constants [ 72 (AP_REG 145) 73 (PR_REG 146) 74 (T_REG 147) 75 (GBR_REG 144) 76 (MACH_REG 148) 77 (MACL_REG 149) 78 (FPUL_REG 150) 79 (RAP_REG 152) 80 81 (FPSCR_REG 151) 82 83 (PIC_REG 12) 84 (FP_REG 14) 85 (SP_REG 15) 86 87 (PR_MEDIA_REG 18) 88 (T_MEDIA_REG 19) 89 90 (R0_REG 0) 91 (R1_REG 1) 92 (R2_REG 2) 93 (R3_REG 3) 94 (R4_REG 4) 95 (R5_REG 5) 96 (R6_REG 6) 97 (R7_REG 7) 98 (R8_REG 8) 99 (R9_REG 9) 100 (R10_REG 10) 101 (R20_REG 20) 102 (R21_REG 21) 103 (R22_REG 22) 104 (R23_REG 23) 105 106 (DR0_REG 64) 107 (DR2_REG 66) 108 (DR4_REG 68) 109 (FR23_REG 87) 110 111 (TR0_REG 128) 112 (TR1_REG 129) 113 (TR2_REG 130) 114 115 (XD0_REG 136) 116 117 ;; These are used with unspec. 118 (UNSPEC_COMPACT_ARGS 0) 119 (UNSPEC_MOVA 1) 120 (UNSPEC_CASESI 2) 121 (UNSPEC_DATALABEL 3) 122 (UNSPEC_BBR 4) 123 (UNSPEC_SFUNC 5) 124 (UNSPEC_PIC 6) 125 (UNSPEC_GOT 7) 126 (UNSPEC_GOTOFF 8) 127 (UNSPEC_PLT 9) 128 (UNSPEC_CALLER 10) 129 (UNSPEC_GOTPLT 11) 130 (UNSPEC_ICACHE 12) 131 (UNSPEC_INIT_TRAMP 13) 132 (UNSPEC_FCOSA 14) 133 (UNSPEC_FSRRA 15) 134 (UNSPEC_FSINA 16) 135 (UNSPEC_NSB 17) 136 (UNSPEC_ALLOCO 18) 137 (UNSPEC_TLSGD 20) 138 (UNSPEC_TLSLDM 21) 139 (UNSPEC_TLSIE 22) 140 (UNSPEC_DTPOFF 23) 141 (UNSPEC_GOTTPOFF 24) 142 (UNSPEC_TPOFF 25) 143 (UNSPEC_RA 26) 144 (UNSPEC_DIV_INV_M0 30) 145 (UNSPEC_DIV_INV_M1 31) 146 (UNSPEC_DIV_INV_M2 32) 147 (UNSPEC_DIV_INV_M3 33) 148 (UNSPEC_DIV_INV20 34) 149 (UNSPEC_DIV_INV_TABLE 37) 150 (UNSPEC_ASHIFTRT 35) 151 (UNSPEC_THUNK 36) 152 (UNSPEC_CHKADD 38) 153 (UNSPEC_SP_SET 40) 154 (UNSPEC_SP_TEST 41) 155 (UNSPEC_MOVUA 42) 156 157 ;; (unspec [VAL SHIFT] UNSPEC_EXTRACT_S16) computes (short) (VAL >> SHIFT). 158 ;; UNSPEC_EXTRACT_U16 is the unsigned equivalent. 159 (UNSPEC_EXTRACT_S16 43) 160 (UNSPEC_EXTRACT_U16 44) 161 162 ;; (unspec [TARGET ANCHOR] UNSPEC_SYMOFF) == TARGET - ANCHOR. 163 (UNSPEC_SYMOFF 45) 164 165 ;; (unspec [OFFSET ANCHOR] UNSPEC_PCREL_SYMOFF) == OFFSET - (ANCHOR - .). 166 (UNSPEC_PCREL_SYMOFF 46) 167 168 ;; These are used with unspec_volatile. 169 (UNSPECV_BLOCKAGE 0) 170 (UNSPECV_ALIGN 1) 171 (UNSPECV_CONST2 2) 172 (UNSPECV_CONST4 4) 173 (UNSPECV_CONST8 6) 174 (UNSPECV_WINDOW_END 10) 175 (UNSPECV_CONST_END 11) 176 (UNSPECV_EH_RETURN 12) 177]) 178 179;; ------------------------------------------------------------------------- 180;; Attributes 181;; ------------------------------------------------------------------------- 182 183;; Target CPU. 184 185(define_attr "cpu" 186 "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5" 187 (const (symbol_ref "sh_cpu_attr"))) 188 189(define_attr "endian" "big,little" 190 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN") 191 (const_string "little") (const_string "big")))) 192 193;; Indicate if the default fpu mode is single precision. 194(define_attr "fpu_single" "yes,no" 195 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE") 196 (const_string "yes") (const_string "no")))) 197 198(define_attr "fmovd" "yes,no" 199 (const (if_then_else (symbol_ref "TARGET_FMOVD") 200 (const_string "yes") (const_string "no")))) 201;; pipeline model 202(define_attr "pipe_model" "sh1,sh4,sh5media" 203 (const 204 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media") 205 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")] 206 (const_string "sh1")))) 207 208;; cbranch conditional branch instructions 209;; jump unconditional jumps 210;; arith ordinary arithmetic 211;; arith3 a compound insn that behaves similarly to a sequence of 212;; three insns of type arith 213;; arith3b like above, but might end with a redirected branch 214;; load from memory 215;; load_si Likewise, SImode variant for general register. 216;; fload Likewise, but load to fp register. 217;; store to memory 218;; fstore floating point register to memory 219;; move general purpose register to register 220;; movi8 8-bit immediate to general purpose register 221;; mt_group other sh4 mt instructions 222;; fmove register to register, floating point 223;; smpy word precision integer multiply 224;; dmpy longword or doublelongword precision integer multiply 225;; return rts 226;; pload load of pr reg, which can't be put into delay slot of rts 227;; prset copy register to pr reg, ditto 228;; pstore store of pr reg, which can't be put into delay slot of jsr 229;; prget copy pr to register, ditto 230;; pcload pc relative load of constant value 231;; pcfload Likewise, but load to fp register. 232;; pcload_si Likewise, SImode variant for general register. 233;; rte return from exception 234;; sfunc special function call with known used registers 235;; call function call 236;; fp floating point 237;; fpscr_toggle toggle a bit in the fpscr 238;; fdiv floating point divide (or square root) 239;; gp_fpul move from general purpose register to fpul 240;; fpul_gp move from fpul to general purpose register 241;; mac_gp move from mac[lh] to general purpose register 242;; gp_mac move from general purpose register to mac[lh] 243;; mac_mem move from mac[lh] to memory 244;; mem_mac move from memory to mac[lh] 245;; dfp_arith,dfp_mul, fp_cmp,dfp_cmp,dfp_conv 246;; ftrc_s fix_truncsfsi2_i4 247;; dfdiv double precision floating point divide (or square root) 248;; cwb ic_invalidate_line_i 249;; movua SH4a unaligned load 250;; fsrra square root reciprocal approximate 251;; fsca sine and cosine approximate 252;; tls_load load TLS related address 253;; arith_media SHmedia arithmetic, logical, and shift instructions 254;; cbranch_media SHmedia conditional branch instructions 255;; cmp_media SHmedia compare instructions 256;; dfdiv_media SHmedia double precision divide and square root 257;; dfmul_media SHmedia double precision multiply instruction 258;; dfparith_media SHmedia double precision floating point arithmetic 259;; dfpconv_media SHmedia double precision floating point conversions 260;; dmpy_media SHmedia longword multiply 261;; fcmp_media SHmedia floating point compare instructions 262;; fdiv_media SHmedia single precision divide and square root 263;; fload_media SHmedia floating point register load instructions 264;; fmove_media SHmedia floating point register moves (inc. fabs and fneg) 265;; fparith_media SHmedia single precision floating point arithmetic 266;; fpconv_media SHmedia single precision floating point conversions 267;; fstore_media SHmedia floating point register store instructions 268;; gettr_media SHmedia gettr instruction 269;; invalidate_line_media SHmedia invalidate_line sequence 270;; jump_media SHmedia unconditional branch instructions 271;; load_media SHmedia general register load instructions 272;; pt_media SHmedia pt instruction (expanded by assembler) 273;; ptabs_media SHmedia ptabs instruction 274;; store_media SHmedia general register store instructions 275;; mcmp_media SHmedia multimedia compare, absolute, saturating ops 276;; mac_media SHmedia mac-style fixed point operations 277;; d2mpy_media SHmedia: two 32-bit integer multiplies 278;; atrans_media SHmedia approximate transcendental functions 279;; ustore_media SHmedia unaligned stores 280;; nil no-op move, will be deleted. 281 282(define_attr "type" 283 "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,fstore,move,movi8,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fpscr_toggle,fdiv,ftrc_s,dfp_arith,dfp_mul,fp_cmp,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,gp_mac,mac_mem,mem_mac,mem_fpscr,gp_fpscr,cwb,movua,fsrra,fsca,tls_load,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other" 284 (const_string "other")) 285 286;; We define a new attribute namely "insn_class".We use 287;; this for the DFA based pipeline description. 288;; 289;; mt_group SH4 "mt" group instructions. 290;; 291;; ex_group SH4 "ex" group instructions. 292;; 293;; ls_group SH4 "ls" group instructions. 294;; 295 296(define_attr "insn_class" 297 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none" 298 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group") 299 (eq_attr "type" "movi8,arith,dyn_shift") (const_string "ex_group") 300 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,fstore,gp_fpul,fpul_gp") (const_string "ls_group") 301 (eq_attr "type" "cbranch,jump") (const_string "br_group") 302 (eq_attr "type" "fp,fp_cmp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv") 303 (const_string "fe_group") 304 (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb,gp_mac,mac_mem,mem_mac") (const_string "co_group")] 305 (const_string "none"))) 306;; nil are zero instructions, and arith3 / arith3b are multiple instructions, 307;; so these do not belong in an insn group, although they are modeled 308;; with their own define_insn_reservations. 309 310;; Indicate what precision must be selected in fpscr for this insn, if any. 311 312(define_attr "fp_mode" "single,double,none" (const_string "none")) 313 314;; Indicate if the fpu mode is set by this instruction 315;; "unknown" must have the value as "none" in fp_mode, and means 316;; that the instruction/abi has left the processor in an unknown 317;; state. 318;; "none" means that nothing has changed and no mode is set. 319;; This attribute is only used for the Renesas ABI. 320(define_attr "fp_set" "single,double,unknown,none" (const_string "none")) 321 322; If a conditional branch destination is within -252..258 bytes away 323; from the instruction it can be 2 bytes long. Something in the 324; range -4090..4100 bytes can be 6 bytes long. All other conditional 325; branches are initially assumed to be 16 bytes long. 326; In machine_dependent_reorg, we split all branches that are longer than 327; 2 bytes. 328 329;; The maximum range used for SImode constant pool entries is 1018. A final 330;; instruction can add 8 bytes while only being 4 bytes in size, thus we 331;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch 332;; instruction around the pool table, 2 bytes of alignment before the table, 333;; and 30 bytes of alignment after the table. That gives a maximum total 334;; pool size of 1058 bytes. 335;; Worst case code/pool content size ratio is 1:2 (using asms). 336;; Thus, in the worst case, there is one instruction in front of a maximum 337;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of 338;; code. For the last n bytes of code, there are 2n + 36 bytes of pool. 339;; If we have a forward branch, the initial table will be put after the 340;; unconditional branch. 341;; 342;; ??? We could do much better by keeping track of the actual pcloads within 343;; the branch range and in the pcload range in front of the branch range. 344 345;; ??? This looks ugly because genattrtab won't allow if_then_else or cond 346;; inside an le. 347(define_attr "short_cbranch_p" "no,yes" 348 (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0)) 349 (const_string "no") 350 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506)) 351 (const_string "yes") 352 (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0)) 353 (const_string "no") 354 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508)) 355 (const_string "yes") 356 ] (const_string "no"))) 357 358(define_attr "med_branch_p" "no,yes" 359 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990)) 360 (const_int 1988)) 361 (const_string "yes") 362 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0)) 363 (const_string "no") 364 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092)) 365 (const_int 8186)) 366 (const_string "yes") 367 ] (const_string "no"))) 368 369(define_attr "med_cbranch_p" "no,yes" 370 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988)) 371 (const_int 1986)) 372 (const_string "yes") 373 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0)) 374 (const_string "no") 375 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090)) 376 (const_int 8184)) 377 (const_string "yes") 378 ] (const_string "no"))) 379 380(define_attr "braf_branch_p" "no,yes" 381 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0)) 382 (const_string "no") 383 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330)) 384 (const_int 20660)) 385 (const_string "yes") 386 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0)) 387 (const_string "no") 388 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764)) 389 (const_int 65530)) 390 (const_string "yes") 391 ] (const_string "no"))) 392 393(define_attr "braf_cbranch_p" "no,yes" 394 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0)) 395 (const_string "no") 396 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328)) 397 (const_int 20658)) 398 (const_string "yes") 399 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0)) 400 (const_string "no") 401 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762)) 402 (const_int 65528)) 403 (const_string "yes") 404 ] (const_string "no"))) 405 406; An unconditional jump in the range -4092..4098 can be 2 bytes long. 407; For wider ranges, we need a combination of a code and a data part. 408; If we can get a scratch register for a long range jump, the code 409; part can be 4 bytes long; otherwise, it must be 8 bytes long. 410; If the jump is in the range -32764..32770, the data part can be 2 bytes 411; long; otherwise, it must be 6 bytes long. 412 413; All other instructions are two bytes long by default. 414 415;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)), 416;; but getattrtab doesn't understand this. 417(define_attr "length" "" 418 (cond [(eq_attr "type" "cbranch") 419 (cond [(eq_attr "short_cbranch_p" "yes") 420 (const_int 2) 421 (eq_attr "med_cbranch_p" "yes") 422 (const_int 6) 423 (eq_attr "braf_cbranch_p" "yes") 424 (const_int 12) 425;; ??? using pc is not computed transitively. 426 (ne (match_dup 0) (match_dup 0)) 427 (const_int 14) 428 (ne (symbol_ref ("flag_pic")) (const_int 0)) 429 (const_int 24) 430 ] (const_int 16)) 431 (eq_attr "type" "jump") 432 (cond [(eq_attr "med_branch_p" "yes") 433 (const_int 2) 434 (and (ne (symbol_ref "prev_nonnote_insn (insn)") 435 (const_int 0)) 436 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))") 437 (symbol_ref "INSN")) 438 (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))") 439 (symbol_ref "code_for_indirect_jump_scratch")))) 440 (cond [(eq_attr "braf_branch_p" "yes") 441 (const_int 6) 442 (eq (symbol_ref "flag_pic") (const_int 0)) 443 (const_int 10) 444 (ne (symbol_ref "TARGET_SH2") (const_int 0)) 445 (const_int 10)] (const_int 18)) 446 (eq_attr "braf_branch_p" "yes") 447 (const_int 10) 448;; ??? using pc is not computed transitively. 449 (ne (match_dup 0) (match_dup 0)) 450 (const_int 12) 451 (ne (symbol_ref ("flag_pic")) (const_int 0)) 452 (const_int 22) 453 ] (const_int 14)) 454 (eq_attr "type" "pt_media") 455 (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0)) 456 (const_int 20) (const_int 12)) 457 (and (eq_attr "type" "jump_media") 458 (ne (symbol_ref "TARGET_SH5_CUT2_WORKAROUND") (const_int 0))) 459 (const_int 8) 460 ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0)) 461 (const_int 4) 462 (const_int 2)))) 463 464;; DFA descriptions for the pipelines 465 466(include "sh1.md") 467(include "shmedia.md") 468(include "sh4.md") 469 470(include "predicates.md") 471(include "constraints.md") 472 473;; Definitions for filling delay slots 474 475(define_attr "needs_delay_slot" "yes,no" (const_string "no")) 476 477(define_attr "banked" "yes,no" 478 (cond [(eq (symbol_ref "sh_loads_bankedreg_p (insn)") 479 (const_int 1)) 480 (const_string "yes")] 481 (const_string "no"))) 482 483;; ??? This should be (nil) instead of (const_int 0) 484(define_attr "hit_stack" "yes,no" 485 (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)") 486 (const_int 0)) 487 (const_string "no")] 488 (const_string "yes"))) 489 490(define_attr "interrupt_function" "no,yes" 491 (const (symbol_ref "current_function_interrupt"))) 492 493(define_attr "in_delay_slot" "yes,no" 494 (cond [(eq_attr "type" "cbranch") (const_string "no") 495 (eq_attr "type" "pcload,pcload_si") (const_string "no") 496 (eq_attr "needs_delay_slot" "yes") (const_string "no") 497 (eq_attr "length" "2") (const_string "yes") 498 ] (const_string "no"))) 499 500(define_attr "cond_delay_slot" "yes,no" 501 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes") 502 ] (const_string "no"))) 503 504(define_attr "is_sfunc" "" 505 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0))) 506 507(define_attr "is_mac_media" "" 508 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0))) 509 510(define_attr "branch_zero" "yes,no" 511 (cond [(eq_attr "type" "!cbranch") (const_string "no") 512 (ne (symbol_ref "(next_active_insn (insn)\ 513 == (prev_active_insn\ 514 (XEXP (SET_SRC (PATTERN (insn)), 1))))\ 515 && get_attr_length (next_active_insn (insn)) == 2") 516 (const_int 0)) 517 (const_string "yes")] 518 (const_string "no"))) 519 520;; SH4 Double-precision computation with double-precision result - 521;; the two halves are ready at different times. 522(define_attr "dfp_comp" "yes,no" 523 (cond [(eq_attr "type" "dfp_arith,dfp_mul,dfp_conv,dfdiv") (const_string "yes")] 524 (const_string "no"))) 525 526;; Insns for which the latency of a preceding fp insn is decreased by one. 527(define_attr "late_fp_use" "yes,no" (const_string "no")) 528;; And feeding insns for which this relevant. 529(define_attr "any_fp_comp" "yes,no" 530 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv") 531 (const_string "yes")] 532 (const_string "no"))) 533 534(define_attr "any_int_load" "yes,no" 535 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si") 536 (const_string "yes")] 537 (const_string "no"))) 538 539(define_attr "highpart" "user, ignore, extend, depend, must_split" 540 (const_string "user")) 541 542(define_delay 543 (eq_attr "needs_delay_slot" "yes") 544 [(eq_attr "in_delay_slot" "yes") (nil) (nil)]) 545 546;; On the SH and SH2, the rte instruction reads the return pc from the stack, 547;; and thus we can't put a pop instruction in its delay slot. 548;; ??? On the SH3, the rte instruction does not use the stack, so a pop 549;; instruction can go in the delay slot. 550 551;; Since a normal return (rts) implicitly uses the PR register, 552;; we can't allow PR register loads in an rts delay slot. 553 554(define_delay 555 (eq_attr "type" "return") 556 [(and (eq_attr "in_delay_slot" "yes") 557 (ior (and (eq_attr "interrupt_function" "no") 558 (eq_attr "type" "!pload,prset")) 559 (and (eq_attr "interrupt_function" "yes") 560 (ior 561 (eq (symbol_ref "TARGET_SH3") (const_int 0)) 562 (eq_attr "hit_stack" "no") 563 (eq_attr "banked" "no"))))) (nil) (nil)]) 564 565;; Since a call implicitly uses the PR register, we can't allow 566;; a PR register store in a jsr delay slot. 567 568(define_delay 569 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc")) 570 [(and (eq_attr "in_delay_slot" "yes") 571 (eq_attr "type" "!pstore,prget")) (nil) (nil)]) 572 573;; Say that we have annulled true branches, since this gives smaller and 574;; faster code when branches are predicted as not taken. 575 576;; ??? The non-annulled condition should really be "in_delay_slot", 577;; but insns that can be filled in non-annulled get priority over insns 578;; that can only be filled in anulled. 579 580(define_delay 581 (and (eq_attr "type" "cbranch") 582 (ne (symbol_ref "TARGET_SH2") (const_int 0))) 583 ;; SH2e has a hardware bug that pretty much prohibits the use of 584 ;; annuled delay slots. 585 [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes") 586 (not (eq_attr "cpu" "sh2e"))) (nil)]) 587 588;; ------------------------------------------------------------------------- 589;; SImode signed integer comparisons 590;; ------------------------------------------------------------------------- 591 592(define_insn "" 593 [(set (reg:SI T_REG) 594 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r") 595 (match_operand:SI 1 "logical_operand" "K08,r")) 596 (const_int 0)))] 597 "TARGET_SH1" 598 "tst %1,%0" 599 [(set_attr "type" "mt_group")]) 600 601;; ??? Perhaps should only accept reg/constant if the register is reg 0. 602;; That would still allow reload to create cmpi instructions, but would 603;; perhaps allow forcing the constant into a register when that is better. 604;; Probably should use r0 for mem/imm compares, but force constant into a 605;; register for pseudo/imm compares. 606 607(define_insn "cmpeqsi_t" 608 [(set (reg:SI T_REG) 609 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r") 610 (match_operand:SI 1 "arith_operand" "N,rI08,r")))] 611 "TARGET_SH1" 612 "@ 613 tst %0,%0 614 cmp/eq %1,%0 615 cmp/eq %1,%0" 616 [(set_attr "type" "mt_group")]) 617 618(define_insn "cmpgtsi_t" 619 [(set (reg:SI T_REG) 620 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r") 621 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))] 622 "TARGET_SH1" 623 "@ 624 cmp/gt %1,%0 625 cmp/pl %0" 626 [(set_attr "type" "mt_group")]) 627 628(define_insn "cmpgesi_t" 629 [(set (reg:SI T_REG) 630 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r") 631 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))] 632 "TARGET_SH1" 633 "@ 634 cmp/ge %1,%0 635 cmp/pz %0" 636 [(set_attr "type" "mt_group")]) 637 638;; ------------------------------------------------------------------------- 639;; SImode compare and branch 640;; ------------------------------------------------------------------------- 641 642(define_expand "cbranchsi4" 643 [(set (pc) 644 (if_then_else (match_operator 0 "comparison_operator" 645 [(match_operand:SI 1 "arith_operand" "") 646 (match_operand:SI 2 "arith_operand" "")]) 647 (label_ref (match_operand 3 "" "")) 648 (pc))) 649 (clobber (reg:SI T_REG))] 650 "" 651 "if (TARGET_SHMEDIA) 652 emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1], 653 operands[2], operands[3])); 654 else if (TARGET_CBRANCHDI4) 655 expand_cbranchsi4 (operands, LAST_AND_UNUSED_RTX_CODE, -1); 656 else 657 sh_emit_compare_and_branch (operands, SImode); 658 DONE;") 659 660;; ------------------------------------------------------------------------- 661;; SImode unsigned integer comparisons 662;; ------------------------------------------------------------------------- 663 664(define_insn_and_split "cmpgeusi_t" 665 [(set (reg:SI T_REG) 666 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r") 667 (match_operand:SI 1 "arith_reg_or_0_operand" "rN")))] 668 "TARGET_SH1" 669 "cmp/hs %1,%0" 670 "&& operands[1] == CONST0_RTX (SImode)" 671 [(pc)] 672 " 673{ 674 emit_insn (gen_sett ()); 675 DONE; 676}" 677 [(set_attr "type" "mt_group")]) 678 679(define_insn "cmpgtusi_t" 680 [(set (reg:SI T_REG) 681 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r") 682 (match_operand:SI 1 "arith_reg_operand" "r")))] 683 "TARGET_SH1" 684 "cmp/hi %1,%0" 685 [(set_attr "type" "mt_group")]) 686 687 688;; ------------------------------------------------------------------------- 689;; DImode compare and branch 690;; ------------------------------------------------------------------------- 691 692 693;; arith3 patterns don't work well with the sh4-300 branch prediction mechanism. 694;; Therefore, we aim to have a set of three branches that go straight to the 695;; destination, i.e. only one of them is taken at any one time. 696;; This mechanism should also be slightly better for the sh4-200. 697 698(define_expand "cbranchdi4" 699 [(set (pc) 700 (if_then_else (match_operator 0 "comparison_operator" 701 [(match_operand:DI 1 "arith_operand" "") 702 (match_operand:DI 2 "arith_operand" "")]) 703 (label_ref (match_operand 3 "" "")) 704 (pc))) 705 (clobber (match_dup 4)) 706 (clobber (reg:SI T_REG))] 707 "TARGET_CBRANCHDI4 || TARGET_SH2 || TARGET_SHMEDIA" 708 " 709{ 710 enum rtx_code comparison; 711 712 if (TARGET_SHMEDIA) 713 { 714 emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1], 715 operands[2], operands[3])); 716 DONE; 717 } 718 719 else if (!TARGET_CBRANCHDI4) 720 { 721 sh_emit_compare_and_branch (operands, DImode); 722 DONE; 723 } 724 725 else 726 { 727 if (expand_cbranchdi4 (operands, LAST_AND_UNUSED_RTX_CODE)) 728 DONE; 729 730 comparison = prepare_cbranch_operands (operands, DImode, 731 LAST_AND_UNUSED_RTX_CODE); 732 if (comparison != GET_CODE (operands[0])) 733 operands[0] 734 = gen_rtx_fmt_ee (comparison, VOIDmode, operands[1], operands[2]); 735 operands[4] = gen_rtx_SCRATCH (SImode); 736 } 737}") 738 739(define_insn_and_split "cbranchdi4_i" 740 [(set (pc) 741 (if_then_else (match_operator 0 "comparison_operator" 742 [(match_operand:DI 1 "arith_operand" "r,r") 743 (match_operand:DI 2 "arith_operand" "rN,I08")]) 744 (label_ref (match_operand 3 "" "")) 745 (pc))) 746 (clobber (match_scratch:SI 4 "=X,&r")) 747 (clobber (reg:SI T_REG))] 748 "TARGET_CBRANCHDI4" 749 "#" 750 "&& reload_completed" 751 [(pc)] 752 " 753{ 754 if (!expand_cbranchdi4 (operands, GET_CODE (operands[0]))) 755 FAIL; 756 DONE; 757}") 758 759;; ------------------------------------------------------------------------- 760;; DImode signed integer comparisons 761;; ------------------------------------------------------------------------- 762 763(define_insn "" 764 [(set (reg:SI T_REG) 765 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r") 766 (match_operand:DI 1 "arith_operand" "r")) 767 (const_int 0)))] 768 "TARGET_SH1" 769 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\", 770 insn, operands);" 771 [(set_attr "length" "6") 772 (set_attr "type" "arith3b")]) 773 774(define_insn "cmpeqdi_t" 775 [(set (reg:SI T_REG) 776 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r") 777 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))] 778 "TARGET_SH1" 779 "@ 780 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=: 781 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:" 782 [(set_attr "length" "6") 783 (set_attr "type" "arith3b")]) 784 785(define_split 786 [(set (reg:SI T_REG) 787 (eq:SI (match_operand:DI 0 "arith_reg_operand" "") 788 (match_operand:DI 1 "arith_reg_or_0_operand" "")))] 789;; If we applied this split when not optimizing, it would only be 790;; applied during the machine-dependent reorg, when no new basic blocks 791;; may be created. 792 "TARGET_SH1 && reload_completed && optimize" 793 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3))) 794 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0)) 795 (label_ref (match_dup 6)) 796 (pc))) 797 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5))) 798 (match_dup 6)] 799 " 800{ 801 operands[2] 802 = gen_rtx_REG (SImode, 803 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0)); 804 operands[3] 805 = (operands[1] == const0_rtx 806 ? const0_rtx 807 : gen_rtx_REG (SImode, 808 true_regnum (operands[1]) 809 + (TARGET_LITTLE_ENDIAN ? 1 : 0))); 810 operands[4] = gen_lowpart (SImode, operands[0]); 811 operands[5] = gen_lowpart (SImode, operands[1]); 812 operands[6] = gen_label_rtx (); 813}") 814 815(define_insn "cmpgtdi_t" 816 [(set (reg:SI T_REG) 817 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r") 818 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))] 819 "TARGET_SH2" 820 "@ 821 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=: 822 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:" 823 [(set_attr "length" "8") 824 (set_attr "type" "arith3")]) 825 826(define_insn "cmpgedi_t" 827 [(set (reg:SI T_REG) 828 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r") 829 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))] 830 "TARGET_SH2" 831 "@ 832 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=: 833 cmp/pz\\t%S0" 834 [(set_attr "length" "8,2") 835 (set_attr "type" "arith3,mt_group")]) 836 837;; ------------------------------------------------------------------------- 838;; DImode unsigned integer comparisons 839;; ------------------------------------------------------------------------- 840 841(define_insn "cmpgeudi_t" 842 [(set (reg:SI T_REG) 843 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r") 844 (match_operand:DI 1 "arith_reg_operand" "r")))] 845 "TARGET_SH2" 846 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:" 847 [(set_attr "length" "8") 848 (set_attr "type" "arith3")]) 849 850(define_insn "cmpgtudi_t" 851 [(set (reg:SI T_REG) 852 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r") 853 (match_operand:DI 1 "arith_reg_operand" "r")))] 854 "TARGET_SH2" 855 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:" 856 [(set_attr "length" "8") 857 (set_attr "type" "arith3")]) 858 859(define_insn "cmpeqsi_media" 860 [(set (match_operand:SI 0 "register_operand" "=r") 861 (eq:SI (match_operand:SI 1 "logical_operand" "%r") 862 (match_operand:SI 2 "cmp_operand" "Nr")))] 863 "TARGET_SHMEDIA" 864 "cmpeq %1, %N2, %0" 865 [(set_attr "type" "cmp_media")]) 866 867(define_insn "cmpeqdi_media" 868 [(set (match_operand:SI 0 "register_operand" "=r") 869 (eq:SI (match_operand:DI 1 "register_operand" "%r") 870 (match_operand:DI 2 "cmp_operand" "Nr")))] 871 "TARGET_SHMEDIA" 872 "cmpeq %1, %N2, %0" 873 [(set_attr "type" "cmp_media")]) 874 875(define_insn "cmpgtsi_media" 876 [(set (match_operand:SI 0 "register_operand" "=r") 877 (gt:SI (match_operand:SI 1 "cmp_operand" "Nr") 878 (match_operand:SI 2 "cmp_operand" "rN")))] 879 "TARGET_SHMEDIA" 880 "cmpgt %N1, %N2, %0" 881 [(set_attr "type" "cmp_media")]) 882 883(define_insn "cmpgtdi_media" 884 [(set (match_operand:SI 0 "register_operand" "=r") 885 (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr") 886 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))] 887 "TARGET_SHMEDIA" 888 "cmpgt %N1, %N2, %0" 889 [(set_attr "type" "cmp_media")]) 890 891(define_insn "cmpgtusi_media" 892 [(set (match_operand:SI 0 "register_operand" "=r") 893 (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr") 894 (match_operand:SI 2 "cmp_operand" "rN")))] 895 "TARGET_SHMEDIA" 896 "cmpgtu %N1, %N2, %0" 897 [(set_attr "type" "cmp_media")]) 898 899(define_insn "cmpgtudi_media" 900 [(set (match_operand:SI 0 "register_operand" "=r") 901 (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr") 902 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))] 903 "TARGET_SHMEDIA" 904 "cmpgtu %N1, %N2, %0" 905 [(set_attr "type" "cmp_media")]) 906 907; These two patterns are for combine. 908(define_insn "*cmpne0sisi_media" 909 [(set (match_operand:SI 0 "register_operand" "=r") 910 (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))] 911 "TARGET_SHMEDIA" 912 "cmpgtu %1,r63,%0" 913 [(set_attr "type" "cmp_media")]) 914 915;; ------------------------------------------------------------------------- 916;; Conditional move instructions 917;; ------------------------------------------------------------------------- 918 919;; The insn names may seem reversed, but note that cmveq performs the move 920;; if op1 == 0, and cmvne does it if op1 != 0. 921 922(define_insn "movdicc_false" 923 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 924 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r") 925 (const_int 0)) 926 (match_operand:DI 2 "arith_reg_or_0_operand" "rN") 927 (match_operand:DI 3 "arith_reg_operand" "0")))] 928 "TARGET_SHMEDIA" 929 "cmveq %1, %N2, %0" 930 [(set_attr "type" "arith_media")]) 931 932(define_insn "movdicc_true" 933 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 934 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r") 935 (const_int 0)) 936 (match_operand:DI 2 "arith_reg_or_0_operand" "rN") 937 (match_operand:DI 3 "arith_reg_operand" "0")))] 938 "TARGET_SHMEDIA" 939 "cmvne %1, %N2, %0" 940 [(set_attr "type" "arith_media")]) 941 942(define_peephole2 943 [(set (match_operand:DI 0 "arith_reg_dest" "") 944 (if_then_else:DI (match_operator 3 "equality_comparison_operator" 945 [(match_operand:DI 1 "arith_reg_operand" "") 946 (const_int 0)]) 947 (match_operand:DI 2 "arith_reg_dest" "") 948 (match_dup 0))) 949 (set (match_dup 2) (match_dup 0))] 950 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])" 951 [(set (match_dup 2) 952 (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))] 953 " 954{ 955 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])), 956 VOIDmode, operands[1], CONST0_RTX (DImode)); 957}") 958 959(define_peephole2 960 [(set (match_operand:DI 0 "general_movdst_operand" "") 961 (match_operand:DI 1 "arith_reg_or_0_operand" "")) 962 (set (match_operand:DI 2 "arith_reg_dest" "") 963 (if_then_else:DI (match_operator 4 "equality_comparison_operator" 964 [(match_operand:DI 3 "arith_reg_operand" "") 965 (const_int 0)]) 966 (match_dup 0) 967 (match_dup 2)))] 968 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])" 969 [(set (match_dup 2) 970 (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))] 971 "") 972 973(define_expand "movdicc" 974 [(set (match_operand:DI 0 "register_operand" "") 975 (if_then_else:DI (match_operand 1 "comparison_operator" "") 976 (match_operand:DI 2 "register_operand" "") 977 (match_operand:DI 3 "register_operand" "")))] 978 "TARGET_SHMEDIA" 979 " 980{ 981 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE) 982 && GET_MODE (XEXP (operands[1], 0)) == DImode 983 && XEXP (operands[1], 1) == const0_rtx) 984 ; 985 else 986 { 987 if (!can_create_pseudo_p ()) 988 FAIL; 989 990 operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]), 991 GET_CODE (operands[1]), 992 XEXP (operands[1], 0), 993 XEXP (operands[1], 1)); 994 if (!operands[1]) 995 FAIL; 996 } 997}") 998 999;; Add SImode variants for cmveq / cmvne to compensate for not promoting 1000;; SImode to DImode. 1001(define_insn "movsicc_false" 1002 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 1003 (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r") 1004 (const_int 0)) 1005 (match_operand:SI 2 "arith_reg_or_0_operand" "rN") 1006 (match_operand:SI 3 "arith_reg_operand" "0")))] 1007 "TARGET_SHMEDIA" 1008 "cmveq %1, %N2, %0" 1009 [(set_attr "type" "arith_media")]) 1010 1011(define_insn "movsicc_true" 1012 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 1013 (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r") 1014 (const_int 0)) 1015 (match_operand:SI 2 "arith_reg_or_0_operand" "rN") 1016 (match_operand:SI 3 "arith_reg_operand" "0")))] 1017 "TARGET_SHMEDIA" 1018 "cmvne %1, %N2, %0" 1019 [(set_attr "type" "arith_media")]) 1020 1021(define_peephole2 1022 [(set (match_operand:SI 0 "arith_reg_dest" "") 1023 (if_then_else:SI (match_operator 3 "equality_comparison_operator" 1024 [(match_operand:SI 1 "arith_reg_operand" "") 1025 (const_int 0)]) 1026 (match_operand:SI 2 "arith_reg_dest" "") 1027 (match_dup 0))) 1028 (set (match_dup 2) (match_dup 0))] 1029 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])" 1030 [(set (match_dup 2) 1031 (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))] 1032 " 1033{ 1034 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])), 1035 VOIDmode, operands[1], CONST0_RTX (SImode)); 1036}") 1037 1038(define_peephole2 1039 [(set (match_operand:SI 0 "general_movdst_operand" "") 1040 (match_operand:SI 1 "arith_reg_or_0_operand" "")) 1041 (set (match_operand:SI 2 "arith_reg_dest" "") 1042 (if_then_else:SI (match_operator 4 "equality_comparison_operator" 1043 [(match_operand:SI 3 "arith_reg_operand" "") 1044 (const_int 0)]) 1045 (match_dup 0) 1046 (match_dup 2)))] 1047 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0]) 1048 && (!REG_P (operands[1]) || GENERAL_REGISTER_P (REGNO (operands[1])))" 1049 [(set (match_dup 2) 1050 (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))] 1051 " 1052{ 1053 replace_rtx (operands[4], operands[0], operands[1]); 1054}") 1055 1056(define_peephole2 1057 [(set (match_operand 0 "any_register_operand" "") 1058 (match_operand 1 "any_register_operand" "")) 1059 (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" "")) 1060 (set (match_operand 4 "" "") (match_operand 5 "" ""))] 1061 "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2])) 1062 <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0]))) 1063 && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2]) 1064 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0]) 1065 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2]) 1066 && ! reg_overlap_mentioned_p (operands[0], operands[3]) 1067 && ! reg_overlap_mentioned_p (operands[2], operands[0]) 1068 && ! reg_overlap_mentioned_p (operands[0], operands[1]) 1069 && (REGNO_REG_CLASS (REGNO (operands[0])) 1070 == REGNO_REG_CLASS (REGNO (operands[2]))) 1071 && (REGNO_REG_CLASS (REGNO (operands[1])) 1072 == REGNO_REG_CLASS (REGNO (operands[0])))" 1073 [(set (match_dup 0) (match_dup 3)) 1074 (set (match_dup 4) (match_dup 5))] 1075 " 1076{ 1077 rtx set1, set2, insn2; 1078 rtx replacements[4]; 1079 1080 /* We want to replace occurrences of operands[0] with operands[1] and 1081 operands[2] with operands[0] in operands[4]/operands[5]. 1082 Doing just two replace_rtx calls naively would result in the second 1083 replacement undoing all that the first did if operands[1] and operands[2] 1084 are identical, so we must do this simultaneously. */ 1085 replacements[0] = operands[0]; 1086 replacements[1] = operands[1]; 1087 replacements[2] = operands[2]; 1088 replacements[3] = operands[0]; 1089 if (!replace_n_hard_rtx (operands[5], replacements, 2, 0) 1090 || !replace_n_hard_rtx (operands[4], replacements, 2, 0) 1091 || !replace_n_hard_rtx (operands[2], replacements, 2, 0)) 1092 FAIL; 1093 1094 operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1); 1095 replace_n_hard_rtx (operands[4], replacements, 2, 1); 1096 operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1); 1097 /* The operands array is aliased to recog_data.operand, which gets 1098 clobbered by extract_insn, so finish with it now. */ 1099 set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]); 1100 set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]); 1101 /* ??? The last insn might be a jump insn, but the generic peephole2 code 1102 always uses emit_insn. */ 1103 /* Check that we don't violate matching constraints or earlyclobbers. */ 1104 extract_insn (emit_insn (set1)); 1105 if (! constrain_operands (1)) 1106 goto failure; 1107 insn2 = emit (set2); 1108 if (GET_CODE (insn2) == BARRIER) 1109 goto failure; 1110 extract_insn (insn2); 1111 if (! constrain_operands (1)) 1112 { 1113 rtx tmp; 1114 failure: 1115 tmp = replacements[0]; 1116 replacements[0] = replacements[1]; 1117 replacements[1] = tmp; 1118 tmp = replacements[2]; 1119 replacements[2] = replacements[3]; 1120 replacements[3] = tmp; 1121 replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1); 1122 replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1); 1123 replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1); 1124 FAIL; 1125 } 1126 DONE; 1127}") 1128 1129;; The register allocator is rather clumsy in handling multi-way conditional 1130;; moves, so allow the combiner to make them, and we split them up after 1131;; reload. */ 1132(define_insn_and_split "*movsicc_umin" 1133 [(set (match_operand:SI 0 "arith_reg_dest" "=&r") 1134 (umin:SI (if_then_else:SI 1135 (eq (match_operand:SI 1 "arith_reg_operand" "r") 1136 (const_int 0)) 1137 (match_operand:SI 2 "arith_reg_or_0_operand" "rN") 1138 (match_operand:SI 3 "register_operand" "0")) 1139 (match_operand:SI 4 "arith_reg_or_0_operand" "r"))) 1140 (clobber (match_scratch:SI 5 "=&r"))] 1141 "TARGET_SHMEDIA && !can_create_pseudo_p ()" 1142 "#" 1143 "TARGET_SHMEDIA && reload_completed" 1144 [(pc)] 1145 " 1146{ 1147 emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2], 1148 operands[3])); 1149 emit_insn (gen_cmpgtusi_media (operands[5], operands[4], operands[0])); 1150 emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4], 1151 operands[0])); 1152 DONE; 1153}") 1154 1155(define_insn "*movsicc_t_false" 1156 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r") 1157 (if_then_else (eq (reg:SI T_REG) (const_int 0)) 1158 (match_operand:SI 1 "general_movsrc_operand" "r,I08") 1159 (match_operand:SI 2 "arith_reg_operand" "0,0")))] 1160 "TARGET_PRETEND_CMOVE 1161 && (arith_reg_operand (operands[1], SImode) 1162 || (immediate_operand (operands[1], SImode) 1163 && satisfies_constraint_I08 (operands[1])))" 1164 "bt 0f\;mov %1,%0\\n0:" 1165 [(set_attr "type" "mt_group,arith") ;; poor approximation 1166 (set_attr "length" "4")]) 1167 1168(define_insn "*movsicc_t_true" 1169 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r") 1170 (if_then_else (ne (reg:SI T_REG) (const_int 0)) 1171 (match_operand:SI 1 "general_movsrc_operand" "r,I08") 1172 (match_operand:SI 2 "arith_reg_operand" "0,0")))] 1173 "TARGET_PRETEND_CMOVE 1174 && (arith_reg_operand (operands[1], SImode) 1175 || (immediate_operand (operands[1], SImode) 1176 && satisfies_constraint_I08 (operands[1])))" 1177 "bf 0f\;mov %1,%0\\n0:" 1178 [(set_attr "type" "mt_group,arith") ;; poor approximation 1179 (set_attr "length" "4")]) 1180 1181(define_expand "movsicc" 1182 [(set (match_operand:SI 0 "arith_reg_dest" "") 1183 (if_then_else:SI (match_operand 1 "comparison_operator" "") 1184 (match_operand:SI 2 "arith_reg_or_0_operand" "") 1185 (match_operand:SI 3 "arith_reg_operand" "")))] 1186 "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE" 1187 " 1188{ 1189 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE) 1190 && GET_MODE (XEXP (operands[1], 0)) == SImode 1191 && (TARGET_SHMEDIA 1192 || (REG_P (XEXP (operands[1], 0)) 1193 && REGNO (XEXP (operands[1], 0)) == T_REG)) 1194 && XEXP (operands[1], 1) == const0_rtx) 1195 ; 1196 1197 else if (TARGET_PRETEND_CMOVE) 1198 { 1199 enum rtx_code code = GET_CODE (operands[1]); 1200 enum rtx_code new_code = code; 1201 rtx op0 = XEXP (operands[1], 0); 1202 rtx op1 = XEXP (operands[1], 1); 1203 1204 if (! currently_expanding_to_rtl) 1205 FAIL; 1206 switch (code) 1207 { 1208 case LT: case LE: case LEU: case LTU: 1209 if (GET_MODE_CLASS (GET_MODE (op0)) != MODE_INT) 1210 break; 1211 case NE: 1212 new_code = reverse_condition (code); 1213 break; 1214 case EQ: case GT: case GE: case GEU: case GTU: 1215 break; 1216 default: 1217 FAIL; 1218 } 1219 sh_emit_scc_to_t (new_code, op0, op1); 1220 operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode, 1221 gen_rtx_REG (SImode, T_REG), const0_rtx); 1222 } 1223 else 1224 { 1225 if (!can_create_pseudo_p ()) 1226 FAIL; 1227 1228 operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]), 1229 GET_CODE (operands[1]), 1230 XEXP (operands[1], 0), 1231 XEXP (operands[1], 1)); 1232 if (!operands[1]) 1233 FAIL; 1234 } 1235}") 1236 1237(define_expand "movqicc" 1238 [(set (match_operand:QI 0 "register_operand" "") 1239 (if_then_else:QI (match_operand 1 "comparison_operator" "") 1240 (match_operand:QI 2 "register_operand" "") 1241 (match_operand:QI 3 "register_operand" "")))] 1242 "TARGET_SHMEDIA" 1243 " 1244{ 1245 operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0); 1246 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0); 1247 operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0); 1248 emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3])); 1249 DONE; 1250}") 1251 1252;; ------------------------------------------------------------------------- 1253;; Addition instructions 1254;; ------------------------------------------------------------------------- 1255 1256(define_expand "adddi3" 1257 [(set (match_operand:DI 0 "arith_reg_operand" "") 1258 (plus:DI (match_operand:DI 1 "arith_reg_operand" "") 1259 (match_operand:DI 2 "arith_operand" "")))] 1260 "" 1261 " 1262{ 1263 if (TARGET_SH1) 1264 { 1265 if (!can_create_pseudo_p () && ! arith_reg_operand (operands[2], DImode)) 1266 FAIL; 1267 operands[2] = force_reg (DImode, operands[2]); 1268 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2])); 1269 DONE; 1270 } 1271}") 1272 1273(define_insn "*adddi3_media" 1274 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r") 1275 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r") 1276 (match_operand:DI 2 "arith_operand" "r,I10")))] 1277 "TARGET_SHMEDIA" 1278 "@ 1279 add %1, %2, %0 1280 addi %1, %2, %0" 1281 [(set_attr "type" "arith_media")]) 1282 1283(define_insn "*adddisi3_media" 1284 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0) 1285 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r") 1286 (match_operand:DI 2 "arith_operand" "r,I10")))] 1287 "TARGET_SHMEDIA" 1288 "@ 1289 add.l %1, %2, %0 1290 addi.l %1, %2, %0" 1291 [(set_attr "type" "arith_media") 1292 (set_attr "highpart" "ignore")]) 1293 1294(define_insn "adddi3z_media" 1295 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 1296 (zero_extend:DI 1297 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r") 1298 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))] 1299 "TARGET_SHMEDIA" 1300 "addz.l %1, %N2, %0" 1301 [(set_attr "type" "arith_media") 1302 (set_attr "highpart" "ignore")]) 1303 1304(define_insn "adddi3_compact" 1305 [(set (match_operand:DI 0 "arith_reg_dest" "=&r") 1306 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0") 1307 (match_operand:DI 2 "arith_reg_operand" "r"))) 1308 (clobber (reg:SI T_REG))] 1309 "TARGET_SH1" 1310 "#" 1311 [(set_attr "length" "6")]) 1312 1313(define_split 1314 [(set (match_operand:DI 0 "arith_reg_dest" "") 1315 (plus:DI (match_operand:DI 1 "arith_reg_operand" "") 1316 (match_operand:DI 2 "arith_reg_operand" ""))) 1317 (clobber (reg:SI T_REG))] 1318 "TARGET_SH1 && reload_completed" 1319 [(const_int 0)] 1320 " 1321{ 1322 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]); 1323 high0 = gen_rtx_REG (SImode, 1324 true_regnum (operands[0]) 1325 + (TARGET_LITTLE_ENDIAN ? 1 : 0)); 1326 high2 = gen_rtx_REG (SImode, 1327 true_regnum (operands[2]) 1328 + (TARGET_LITTLE_ENDIAN ? 1 : 0)); 1329 emit_insn (gen_clrt ()); 1330 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2]))); 1331 emit_insn (gen_addc1 (high0, high0, high2)); 1332 DONE; 1333}") 1334 1335(define_insn "addc" 1336 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 1337 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0") 1338 (match_operand:SI 2 "arith_reg_operand" "r")) 1339 (reg:SI T_REG))) 1340 (set (reg:SI T_REG) 1341 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))] 1342 "TARGET_SH1" 1343 "addc %2,%0" 1344 [(set_attr "type" "arith")]) 1345 1346(define_insn "addc1" 1347 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 1348 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0") 1349 (match_operand:SI 2 "arith_reg_operand" "r")) 1350 (reg:SI T_REG))) 1351 (clobber (reg:SI T_REG))] 1352 "TARGET_SH1" 1353 "addc %2,%0" 1354 [(set_attr "type" "arith")]) 1355 1356(define_expand "addsi3" 1357 [(set (match_operand:SI 0 "arith_reg_operand" "") 1358 (plus:SI (match_operand:SI 1 "arith_operand" "") 1359 (match_operand:SI 2 "arith_operand" "")))] 1360 "" 1361 " 1362{ 1363 if (TARGET_SHMEDIA) 1364 operands[1] = force_reg (SImode, operands[1]); 1365}") 1366 1367(define_insn "addsi3_media" 1368 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r") 1369 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r") 1370 (match_operand:SI 2 "arith_operand" "r,I10")))] 1371 "TARGET_SHMEDIA" 1372 "@ 1373 add.l %1, %2, %0 1374 addi.l %1, %2, %0" 1375 [(set_attr "type" "arith_media") 1376 (set_attr "highpart" "ignore")]) 1377 1378(define_insn "addsidi3_media" 1379 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r") 1380 (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand" 1381 "%r,r") 1382 (match_operand:SI 2 "arith_operand" 1383 "r,I10"))))] 1384 "TARGET_SHMEDIA" 1385 "@ 1386 add.l %1, %2, %0 1387 addi.l %1, %2, %0" 1388 [(set_attr "type" "arith_media") 1389 (set_attr "highpart" "ignore")]) 1390 1391(define_insn "*addsi3_compact" 1392 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 1393 (plus:SI (match_operand:SI 1 "arith_operand" "%0") 1394 (match_operand:SI 2 "arith_operand" "rI08")))] 1395 "TARGET_SH1" 1396 "add %2,%0" 1397 [(set_attr "type" "arith")]) 1398 1399;; ------------------------------------------------------------------------- 1400;; Subtraction instructions 1401;; ------------------------------------------------------------------------- 1402 1403(define_expand "subdi3" 1404 [(set (match_operand:DI 0 "arith_reg_operand" "") 1405 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "") 1406 (match_operand:DI 2 "arith_reg_operand" "")))] 1407 "" 1408 " 1409{ 1410 if (TARGET_SH1) 1411 { 1412 operands[1] = force_reg (DImode, operands[1]); 1413 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2])); 1414 DONE; 1415 } 1416}") 1417 1418(define_insn "*subdi3_media" 1419 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 1420 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN") 1421 (match_operand:DI 2 "arith_reg_operand" "r")))] 1422 "TARGET_SHMEDIA" 1423 "sub %N1, %2, %0" 1424 [(set_attr "type" "arith_media")]) 1425 1426(define_insn "subdisi3_media" 1427 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0) 1428 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN") 1429 (match_operand:DI 2 "arith_reg_operand" "r")))] 1430 "TARGET_SHMEDIA" 1431 "sub.l %N1, %2, %0" 1432 [(set_attr "type" "arith_media") 1433 (set_attr "highpart" "ignore")]) 1434 1435(define_insn "subdi3_compact" 1436 [(set (match_operand:DI 0 "arith_reg_dest" "=&r") 1437 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0") 1438 (match_operand:DI 2 "arith_reg_operand" "r"))) 1439 (clobber (reg:SI T_REG))] 1440 "TARGET_SH1" 1441 "#" 1442 [(set_attr "length" "6")]) 1443 1444(define_split 1445 [(set (match_operand:DI 0 "arith_reg_dest" "") 1446 (minus:DI (match_operand:DI 1 "arith_reg_operand" "") 1447 (match_operand:DI 2 "arith_reg_operand" ""))) 1448 (clobber (reg:SI T_REG))] 1449 "TARGET_SH1 && reload_completed" 1450 [(const_int 0)] 1451 " 1452{ 1453 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]); 1454 high0 = gen_rtx_REG (SImode, 1455 true_regnum (operands[0]) 1456 + (TARGET_LITTLE_ENDIAN ? 1 : 0)); 1457 high2 = gen_rtx_REG (SImode, 1458 true_regnum (operands[2]) 1459 + (TARGET_LITTLE_ENDIAN ? 1 : 0)); 1460 emit_insn (gen_clrt ()); 1461 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2]))); 1462 emit_insn (gen_subc1 (high0, high0, high2)); 1463 DONE; 1464}") 1465 1466(define_insn "subc" 1467 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 1468 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0") 1469 (match_operand:SI 2 "arith_reg_operand" "r")) 1470 (reg:SI T_REG))) 1471 (set (reg:SI T_REG) 1472 (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2)) 1473 (reg:SI T_REG)) 1474 (match_dup 1)))] 1475 "TARGET_SH1" 1476 "subc %2,%0" 1477 [(set_attr "type" "arith")]) 1478 1479(define_insn "subc1" 1480 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 1481 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0") 1482 (match_operand:SI 2 "arith_reg_operand" "r")) 1483 (reg:SI T_REG))) 1484 (clobber (reg:SI T_REG))] 1485 "TARGET_SH1" 1486 "subc %2,%0" 1487 [(set_attr "type" "arith")]) 1488 1489;; life_analysis thinks rn is live before subc rn,rn, so make a special 1490;; pattern for this case. This helps multimedia applications that compute 1491;; the sum of absolute differences. 1492(define_insn "mov_neg_si_t" 1493 [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))] 1494 "TARGET_SH1" 1495 "subc %0,%0" 1496 [(set_attr "type" "arith")]) 1497 1498(define_insn "*subsi3_internal" 1499 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 1500 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0") 1501 (match_operand:SI 2 "arith_reg_operand" "r")))] 1502 "TARGET_SH1" 1503 "sub %2,%0" 1504 [(set_attr "type" "arith")]) 1505 1506(define_insn_and_split "*subsi3_media" 1507 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 1508 (minus:SI (match_operand:SI 1 "minuend_operand" "rN") 1509 (match_operand:SI 2 "extend_reg_operand" "r")))] 1510 "TARGET_SHMEDIA 1511 && (operands[1] != constm1_rtx 1512 || (GET_CODE (operands[2]) != TRUNCATE 1513 && GET_CODE (operands[2]) != SUBREG))" 1514 "sub.l %N1, %2, %0" 1515 "operands[1] == constm1_rtx" 1516 [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))] 1517 "" 1518 [(set_attr "type" "arith_media") 1519 (set_attr "highpart" "ignore")]) 1520 1521(define_split 1522 [(set (match_operand:SI 0 "arith_reg_dest" "") 1523 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1 1524 "general_extend_operand" 1525 "") 0)) 0)))] 1526 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN" 1527 [(set (match_dup 0) (zero_extend:SI (match_dup 1))) 1528 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))] 1529 "") 1530 1531(define_split 1532 [(set (match_operand:SI 0 "arith_reg_dest" "") 1533 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1 1534 "general_extend_operand" 1535 "") 0)) 3)))] 1536 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN" 1537 [(set (match_dup 0) (zero_extend:SI (match_dup 1))) 1538 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))] 1539 "") 1540;; Convert `constant - reg' to `neg rX; add rX, #const' since this 1541;; will sometimes save one instruction. Otherwise we might get 1542;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs 1543;; are the same. 1544 1545(define_expand "subsi3" 1546 [(set (match_operand:SI 0 "arith_reg_operand" "") 1547 (minus:SI (match_operand:SI 1 "arith_operand" "") 1548 (match_operand:SI 2 "arith_reg_operand" "")))] 1549 "" 1550 " 1551{ 1552 if (TARGET_SH1 && CONST_INT_P (operands[1])) 1553 { 1554 emit_insn (gen_negsi2 (operands[0], operands[2])); 1555 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1])); 1556 DONE; 1557 } 1558 if (TARGET_SHMEDIA) 1559 { 1560 if (!can_create_pseudo_p () 1561 && ! arith_reg_or_0_operand (operands[1], SImode)) 1562 FAIL; 1563 if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG) 1564 operands[1] = force_reg (SImode, operands[1]); 1565 } 1566}") 1567 1568;; ------------------------------------------------------------------------- 1569;; Division instructions 1570;; ------------------------------------------------------------------------- 1571 1572;; We take advantage of the library routines which don't clobber as many 1573;; registers as a normal function call would. 1574 1575;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it 1576;; also has an effect on the register that holds the address of the sfunc. 1577;; To make this work, we have an extra dummy insn that shows the use 1578;; of this register for reorg. 1579 1580(define_insn "use_sfunc_addr" 1581 [(set (reg:SI PR_REG) 1582 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))] 1583 "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])" 1584 "" 1585 [(set_attr "length" "0")]) 1586 1587(define_insn "udivsi3_sh2a" 1588 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 1589 (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0") 1590 (match_operand:SI 2 "arith_reg_operand" "z")))] 1591 "TARGET_SH2A" 1592 "divu %2,%1" 1593 [(set_attr "type" "arith") 1594 (set_attr "in_delay_slot" "no")]) 1595 1596;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than 1597;; hard register 0. If we used hard register 0, then the next instruction 1598;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg 1599;; gets allocated to a stack slot that needs its address reloaded, then 1600;; there is nothing to prevent reload from using r0 to reload the address. 1601;; This reload would clobber the value in r0 we are trying to store. 1602;; If we let reload allocate r0, then this problem can never happen. 1603 1604(define_insn "udivsi3_i1" 1605 [(set (match_operand:SI 0 "register_operand" "=z") 1606 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG))) 1607 (clobber (reg:SI T_REG)) 1608 (clobber (reg:SI PR_REG)) 1609 (clobber (reg:SI R4_REG)) 1610 (use (match_operand:SI 1 "arith_reg_operand" "r"))] 1611 "TARGET_SH1 && ! TARGET_SH4" 1612 "jsr @%1%#" 1613 [(set_attr "type" "sfunc") 1614 (set_attr "needs_delay_slot" "yes")]) 1615 1616; Since shmedia-nofpu code could be linked against shcompact code, and 1617; the udivsi3 libcall has the same name, we must consider all registers 1618; clobbered that are in the union of the registers clobbered by the 1619; shmedia and the shcompact implementation. Note, if the shcompact 1620; implementation actually used shcompact code, we'd need to clobber 1621; also r23 and fr23. 1622(define_insn "udivsi3_i1_media" 1623 [(set (match_operand:SI 0 "register_operand" "=z") 1624 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG))) 1625 (clobber (reg:SI T_MEDIA_REG)) 1626 (clobber (reg:SI PR_MEDIA_REG)) 1627 (clobber (reg:SI R20_REG)) 1628 (clobber (reg:SI R21_REG)) 1629 (clobber (reg:SI R22_REG)) 1630 (clobber (reg:DI TR0_REG)) 1631 (clobber (reg:DI TR1_REG)) 1632 (clobber (reg:DI TR2_REG)) 1633 (use (match_operand 1 "target_reg_operand" "b"))] 1634 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)" 1635 "blink %1, r18" 1636 [(set_attr "type" "sfunc") 1637 (set_attr "needs_delay_slot" "yes")]) 1638 1639(define_expand "udivsi3_i4_media" 1640 [(set (match_dup 3) 1641 (zero_extend:DI (match_operand:SI 1 "register_operand" ""))) 1642 (set (match_dup 4) 1643 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))) 1644 (set (match_dup 5) (float:DF (match_dup 3))) 1645 (set (match_dup 6) (float:DF (match_dup 4))) 1646 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6))) 1647 (set (match_dup 8) (fix:DI (match_dup 7))) 1648 (set (match_operand:SI 0 "register_operand" "") 1649 (truncate:SI (match_dup 8)))] 1650 "TARGET_SHMEDIA_FPU" 1651 " 1652{ 1653 operands[3] = gen_reg_rtx (DImode); 1654 operands[4] = gen_reg_rtx (DImode); 1655 operands[5] = gen_reg_rtx (DFmode); 1656 operands[6] = gen_reg_rtx (DFmode); 1657 operands[7] = gen_reg_rtx (DFmode); 1658 operands[8] = gen_reg_rtx (DImode); 1659}") 1660 1661(define_insn "udivsi3_i4" 1662 [(set (match_operand:SI 0 "register_operand" "=y") 1663 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG))) 1664 (clobber (reg:SI T_REG)) 1665 (clobber (reg:SI PR_REG)) 1666 (clobber (reg:DF DR0_REG)) 1667 (clobber (reg:DF DR2_REG)) 1668 (clobber (reg:DF DR4_REG)) 1669 (clobber (reg:SI R0_REG)) 1670 (clobber (reg:SI R1_REG)) 1671 (clobber (reg:SI R4_REG)) 1672 (clobber (reg:SI R5_REG)) 1673 (use (reg:PSI FPSCR_REG)) 1674 (use (match_operand:SI 1 "arith_reg_operand" "r"))] 1675 "TARGET_SH4 && ! TARGET_FPU_SINGLE" 1676 "jsr @%1%#" 1677 [(set_attr "type" "sfunc") 1678 (set_attr "fp_mode" "double") 1679 (set_attr "needs_delay_slot" "yes")]) 1680 1681(define_insn "udivsi3_i4_single" 1682 [(set (match_operand:SI 0 "register_operand" "=y") 1683 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG))) 1684 (clobber (reg:SI T_REG)) 1685 (clobber (reg:SI PR_REG)) 1686 (clobber (reg:DF DR0_REG)) 1687 (clobber (reg:DF DR2_REG)) 1688 (clobber (reg:DF DR4_REG)) 1689 (clobber (reg:SI R0_REG)) 1690 (clobber (reg:SI R1_REG)) 1691 (clobber (reg:SI R4_REG)) 1692 (clobber (reg:SI R5_REG)) 1693 (use (match_operand:SI 1 "arith_reg_operand" "r"))] 1694 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE" 1695 "jsr @%1%#" 1696 [(set_attr "type" "sfunc") 1697 (set_attr "needs_delay_slot" "yes")]) 1698 1699(define_insn "udivsi3_i4_int" 1700 [(set (match_operand:SI 0 "register_operand" "=z") 1701 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG))) 1702 (clobber (reg:SI T_REG)) 1703 (clobber (reg:SI R1_REG)) 1704 (clobber (reg:SI PR_REG)) 1705 (clobber (reg:SI MACH_REG)) 1706 (clobber (reg:SI MACL_REG)) 1707 (use (match_operand:SI 1 "arith_reg_operand" "r"))] 1708 "TARGET_SH1" 1709 "jsr @%1%#" 1710 [(set_attr "type" "sfunc") 1711 (set_attr "needs_delay_slot" "yes")]) 1712 1713 1714(define_expand "udivsi3" 1715 [(set (match_dup 3) (symbol_ref:SI "__udivsi3")) 1716 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" "")) 1717 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" "")) 1718 (parallel [(set (match_operand:SI 0 "register_operand" "") 1719 (udiv:SI (reg:SI R4_REG) 1720 (reg:SI R5_REG))) 1721 (clobber (reg:SI T_REG)) 1722 (clobber (reg:SI PR_REG)) 1723 (clobber (reg:SI R4_REG)) 1724 (use (match_dup 3))])] 1725 "" 1726 " 1727{ 1728 rtx last; 1729 1730 operands[3] = gen_reg_rtx (Pmode); 1731 /* Emit the move of the address to a pseudo outside of the libcall. */ 1732 if (TARGET_DIVIDE_CALL_TABLE) 1733 { 1734 /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since 1735 that causes problems when the divide code is supposed to come from a 1736 separate library. Division by zero is undefined, so dividing 1 can be 1737 implemented by comparing with the divisor. */ 1738 if (operands[1] == const1_rtx && currently_expanding_to_rtl) 1739 { 1740 rtx test = gen_rtx_GEU (VOIDmode, operands[1], operands[2]); 1741 emit_insn (gen_cstoresi4 (operands[0], test, 1742 operands[1], operands[2])); 1743 DONE; 1744 } 1745 else if (operands[2] == const0_rtx) 1746 { 1747 emit_move_insn (operands[0], operands[2]); 1748 DONE; 1749 } 1750 function_symbol (operands[3], \"__udivsi3_i4i\", SFUNC_GOT); 1751 last = gen_udivsi3_i4_int (operands[0], operands[3]); 1752 } 1753 else if (TARGET_DIVIDE_CALL_FP) 1754 { 1755 function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC); 1756 if (TARGET_FPU_SINGLE) 1757 last = gen_udivsi3_i4_single (operands[0], operands[3]); 1758 else 1759 last = gen_udivsi3_i4 (operands[0], operands[3]); 1760 } 1761 else if (TARGET_SHMEDIA_FPU) 1762 { 1763 operands[1] = force_reg (SImode, operands[1]); 1764 operands[2] = force_reg (SImode, operands[2]); 1765 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2])); 1766 DONE; 1767 } 1768 else if (TARGET_SH2A) 1769 { 1770 operands[1] = force_reg (SImode, operands[1]); 1771 operands[2] = force_reg (SImode, operands[2]); 1772 emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2])); 1773 DONE; 1774 } 1775 else if (TARGET_SH5) 1776 { 1777 function_symbol (operands[3], 1778 TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\", 1779 SFUNC_STATIC); 1780 1781 if (TARGET_SHMEDIA) 1782 last = gen_udivsi3_i1_media (operands[0], operands[3]); 1783 else if (TARGET_FPU_ANY) 1784 last = gen_udivsi3_i4_single (operands[0], operands[3]); 1785 else 1786 last = gen_udivsi3_i1 (operands[0], operands[3]); 1787 } 1788 else 1789 { 1790 function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC); 1791 last = gen_udivsi3_i1 (operands[0], operands[3]); 1792 } 1793 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]); 1794 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]); 1795 emit_insn (last); 1796 DONE; 1797}") 1798 1799(define_insn "divsi3_sh2a" 1800 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 1801 (div:SI (match_operand:SI 1 "arith_reg_operand" "0") 1802 (match_operand:SI 2 "arith_reg_operand" "z")))] 1803 "TARGET_SH2A" 1804 "divs %2,%1" 1805 [(set_attr "type" "arith") 1806 (set_attr "in_delay_slot" "no")]) 1807 1808(define_insn "divsi3_i1" 1809 [(set (match_operand:SI 0 "register_operand" "=z") 1810 (div:SI (reg:SI R4_REG) (reg:SI R5_REG))) 1811 (clobber (reg:SI T_REG)) 1812 (clobber (reg:SI PR_REG)) 1813 (clobber (reg:SI R1_REG)) 1814 (clobber (reg:SI R2_REG)) 1815 (clobber (reg:SI R3_REG)) 1816 (use (match_operand:SI 1 "arith_reg_operand" "r"))] 1817 "TARGET_SH1 && ! TARGET_SH4" 1818 "jsr @%1%#" 1819 [(set_attr "type" "sfunc") 1820 (set_attr "needs_delay_slot" "yes")]) 1821 1822(define_insn "divsi3_i1_media" 1823 [(set (match_operand:SI 0 "register_operand" "=z") 1824 (div:SI (reg:SI R4_REG) (reg:SI R5_REG))) 1825 (clobber (reg:SI T_MEDIA_REG)) 1826 (clobber (reg:SI PR_MEDIA_REG)) 1827 (clobber (reg:SI R1_REG)) 1828 (clobber (reg:SI R20_REG)) 1829 (clobber (reg:SI R21_REG)) 1830 (clobber (reg:SI TR0_REG)) 1831 (use (match_operand 1 "target_reg_operand" "b"))] 1832 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)" 1833 "blink %1, r18" 1834 [(set_attr "type" "sfunc")]) 1835 1836(define_insn "divsi3_media_2" 1837 [(set (match_operand:SI 0 "register_operand" "=z") 1838 (div:SI (reg:SI R4_REG) (reg:SI R5_REG))) 1839 (clobber (reg:SI T_MEDIA_REG)) 1840 (clobber (reg:SI PR_MEDIA_REG)) 1841 (clobber (reg:SI R1_REG)) 1842 (clobber (reg:SI R21_REG)) 1843 (clobber (reg:SI TR0_REG)) 1844 (use (reg:SI R20_REG)) 1845 (use (match_operand 1 "target_reg_operand" "b"))] 1846 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)" 1847 "blink %1, r18" 1848 [(set_attr "type" "sfunc")]) 1849 1850;; This pattern acts as a placeholder for -mdiv=inv:call to carry 1851;; hard reg clobbers and data dependencies that we need when we want 1852;; to rematerialize the division into a call. 1853(define_insn_and_split "divsi_inv_call" 1854 [(set (match_operand:SI 0 "register_operand" "=r") 1855 (div:SI (match_operand:SI 1 "register_operand" "r") 1856 (match_operand:SI 2 "register_operand" "r"))) 1857 (clobber (reg:SI R4_REG)) 1858 (clobber (reg:SI R5_REG)) 1859 (clobber (reg:SI T_MEDIA_REG)) 1860 (clobber (reg:SI PR_MEDIA_REG)) 1861 (clobber (reg:SI R1_REG)) 1862 (clobber (reg:SI R21_REG)) 1863 (clobber (reg:SI TR0_REG)) 1864 (clobber (reg:SI R20_REG)) 1865 (use (match_operand:SI 3 "register_operand" "r"))] 1866 "TARGET_SHMEDIA" 1867 "#" 1868 "&& (high_life_started || reload_completed)" 1869 [(set (match_dup 0) (match_dup 3))] 1870 "" 1871 [(set_attr "highpart" "must_split")]) 1872 1873;; This is the combiner pattern for -mdiv=inv:call . 1874(define_insn_and_split "*divsi_inv_call_combine" 1875 [(set (match_operand:SI 0 "register_operand" "=z") 1876 (div:SI (match_operand:SI 1 "register_operand" "r") 1877 (match_operand:SI 2 "register_operand" "r"))) 1878 (clobber (reg:SI R4_REG)) 1879 (clobber (reg:SI R5_REG)) 1880 (clobber (reg:SI T_MEDIA_REG)) 1881 (clobber (reg:SI PR_MEDIA_REG)) 1882 (clobber (reg:SI R1_REG)) 1883 (clobber (reg:SI R21_REG)) 1884 (clobber (reg:SI TR0_REG)) 1885 (clobber (reg:SI R20_REG)) 1886 (use (unspec:SI [(match_dup 1) 1887 (match_operand:SI 3 "" "") 1888 (unspec:SI [(match_operand:SI 4 "" "") 1889 (match_dup 3) 1890 (match_operand:DI 5 "" "")] 1891 UNSPEC_DIV_INV_M2) 1892 (match_operand:DI 6 "" "") 1893 (const_int 0) 1894 (const_int 0)] 1895 UNSPEC_DIV_INV_M3))] 1896 "TARGET_SHMEDIA" 1897 "#" 1898 "&& (high_life_started || reload_completed)" 1899 [(pc)] 1900 " 1901{ 1902 const char *name = sh_divsi3_libfunc; 1903 enum sh_function_kind kind = SFUNC_GOT; 1904 rtx sym; 1905 1906 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]); 1907 emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]); 1908 while (TARGET_DIVIDE_INV_CALL2) 1909 { 1910 rtx x = operands[3]; 1911 1912 if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1) 1913 break; 1914 x = XVECEXP (x, 0, 0); 1915 name = \"__sdivsi3_2\"; 1916 kind = SFUNC_STATIC; 1917 emit_move_insn (gen_rtx_REG (DImode, R20_REG), x); 1918 break; 1919 } 1920 sym = function_symbol (NULL, name, kind); 1921 emit_insn (gen_divsi3_media_2 (operands[0], sym)); 1922 DONE; 1923}" 1924 [(set_attr "highpart" "must_split")]) 1925 1926(define_expand "divsi3_i4_media" 1927 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r"))) 1928 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r"))) 1929 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4))) 1930 (set (match_operand:SI 0 "register_operand" "=r") 1931 (fix:SI (match_dup 5)))] 1932 "TARGET_SHMEDIA_FPU" 1933 " 1934{ 1935 operands[3] = gen_reg_rtx (DFmode); 1936 operands[4] = gen_reg_rtx (DFmode); 1937 operands[5] = gen_reg_rtx (DFmode); 1938}") 1939 1940(define_insn "divsi3_i4" 1941 [(set (match_operand:SI 0 "register_operand" "=y") 1942 (div:SI (reg:SI R4_REG) (reg:SI R5_REG))) 1943 (clobber (reg:SI PR_REG)) 1944 (clobber (reg:DF DR0_REG)) 1945 (clobber (reg:DF DR2_REG)) 1946 (use (reg:PSI FPSCR_REG)) 1947 (use (match_operand:SI 1 "arith_reg_operand" "r"))] 1948 "TARGET_SH4 && ! TARGET_FPU_SINGLE" 1949 "jsr @%1%#" 1950 [(set_attr "type" "sfunc") 1951 (set_attr "fp_mode" "double") 1952 (set_attr "needs_delay_slot" "yes")]) 1953 1954(define_insn "divsi3_i4_single" 1955 [(set (match_operand:SI 0 "register_operand" "=y") 1956 (div:SI (reg:SI R4_REG) (reg:SI R5_REG))) 1957 (clobber (reg:SI PR_REG)) 1958 (clobber (reg:DF DR0_REG)) 1959 (clobber (reg:DF DR2_REG)) 1960 (clobber (reg:SI R2_REG)) 1961 (use (match_operand:SI 1 "arith_reg_operand" "r"))] 1962 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE" 1963 "jsr @%1%#" 1964 [(set_attr "type" "sfunc") 1965 (set_attr "needs_delay_slot" "yes")]) 1966 1967(define_insn "divsi3_i4_int" 1968 [(set (match_operand:SI 0 "register_operand" "=z") 1969 (div:SI (reg:SI R4_REG) (reg:SI R5_REG))) 1970 (clobber (reg:SI T_REG)) 1971 (clobber (reg:SI PR_REG)) 1972 (clobber (reg:SI R1_REG)) 1973 (clobber (reg:SI MACH_REG)) 1974 (clobber (reg:SI MACL_REG)) 1975 (use (match_operand:SI 1 "arith_reg_operand" "r"))] 1976 "TARGET_SH1" 1977 "jsr @%1%#" 1978 [(set_attr "type" "sfunc") 1979 (set_attr "needs_delay_slot" "yes")]) 1980 1981(define_expand "divsi3" 1982 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3")) 1983 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" "")) 1984 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" "")) 1985 (parallel [(set (match_operand:SI 0 "register_operand" "") 1986 (div:SI (reg:SI R4_REG) 1987 (reg:SI R5_REG))) 1988 (clobber (reg:SI T_REG)) 1989 (clobber (reg:SI PR_REG)) 1990 (clobber (reg:SI R1_REG)) 1991 (clobber (reg:SI R2_REG)) 1992 (clobber (reg:SI R3_REG)) 1993 (use (match_dup 3))])] 1994 "" 1995 " 1996{ 1997 rtx last; 1998 1999 operands[3] = gen_reg_rtx (Pmode); 2000 /* Emit the move of the address to a pseudo outside of the libcall. */ 2001 if (TARGET_DIVIDE_CALL_TABLE) 2002 { 2003 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT); 2004 last = gen_divsi3_i4_int (operands[0], operands[3]); 2005 } 2006 else if (TARGET_DIVIDE_CALL_FP) 2007 { 2008 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC); 2009 if (TARGET_FPU_SINGLE) 2010 last = gen_divsi3_i4_single (operands[0], operands[3]); 2011 else 2012 last = gen_divsi3_i4 (operands[0], operands[3]); 2013 } 2014 else if (TARGET_SH2A) 2015 { 2016 operands[1] = force_reg (SImode, operands[1]); 2017 operands[2] = force_reg (SImode, operands[2]); 2018 emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2])); 2019 DONE; 2020 } 2021 else if (TARGET_DIVIDE_INV) 2022 { 2023 rtx dividend = operands[1]; 2024 rtx divisor = operands[2]; 2025 rtx tab_base; 2026 rtx nsb_res = gen_reg_rtx (DImode); 2027 rtx norm64 = gen_reg_rtx (DImode); 2028 rtx tab_ix = gen_reg_rtx (DImode); 2029 rtx norm32 = gen_reg_rtx (SImode); 2030 rtx i92 = force_reg (DImode, GEN_INT (92)); 2031 rtx scratch0a = gen_reg_rtx (DImode); 2032 rtx scratch0b = gen_reg_rtx (DImode); 2033 rtx inv0 = gen_reg_rtx (SImode); 2034 rtx scratch1a = gen_reg_rtx (DImode); 2035 rtx scratch1b = gen_reg_rtx (DImode); 2036 rtx shift = gen_reg_rtx (DImode); 2037 rtx i2p27, i43; 2038 rtx inv1 = gen_reg_rtx (SImode); 2039 rtx scratch2a = gen_reg_rtx (DImode); 2040 rtx scratch2b = gen_reg_rtx (SImode); 2041 rtx inv2 = gen_reg_rtx (SImode); 2042 rtx scratch3a = gen_reg_rtx (DImode); 2043 rtx scratch3b = gen_reg_rtx (DImode); 2044 rtx scratch3c = gen_reg_rtx (DImode); 2045 rtx scratch3d = gen_reg_rtx (SImode); 2046 rtx scratch3e = gen_reg_rtx (DImode); 2047 rtx result = gen_reg_rtx (SImode); 2048 2049 if (! arith_reg_or_0_operand (dividend, SImode)) 2050 dividend = force_reg (SImode, dividend); 2051 if (! arith_reg_operand (divisor, SImode)) 2052 divisor = force_reg (SImode, divisor); 2053 if (flag_pic && Pmode != DImode) 2054 { 2055 tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\"); 2056 tab_base = gen_datalabel_ref (tab_base); 2057 tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base)); 2058 } 2059 else 2060 { 2061 tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\"); 2062 tab_base = gen_datalabel_ref (tab_base); 2063 tab_base = force_reg (DImode, tab_base); 2064 } 2065 if (TARGET_DIVIDE_INV20U) 2066 i2p27 = force_reg (DImode, GEN_INT (-2 << 27)); 2067 else 2068 i2p27 = GEN_INT (0); 2069 if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L) 2070 i43 = force_reg (DImode, GEN_INT (43)); 2071 else 2072 i43 = GEN_INT (0); 2073 emit_insn (gen_nsbdi (nsb_res, 2074 simplify_gen_subreg (DImode, divisor, SImode, 0))); 2075 emit_insn (gen_ashldi3_media (norm64, 2076 gen_rtx_SUBREG (DImode, divisor, 0), 2077 nsb_res)); 2078 emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58))); 2079 emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32))); 2080 emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32, 2081 inv0, scratch0a, scratch0b, 2082 scratch1a, scratch1b)); 2083 emit_insn (gen_subdi3 (shift, i92, nsb_res)); 2084 emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92, 2085 scratch2a)); 2086 emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift, 2087 i2p27, i43, 2088 scratch3a, scratch3b, scratch3c, 2089 scratch2a, scratch2b, scratch3d, scratch3e)); 2090 if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2) 2091 emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result)); 2092 else if (TARGET_DIVIDE_INV_FP) 2093 emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result, 2094 gen_reg_rtx (SImode), gen_reg_rtx (SImode), 2095 gen_reg_rtx (DFmode), gen_reg_rtx (DFmode), 2096 gen_reg_rtx (DFmode))); 2097 else 2098 emit_move_insn (operands[0], result); 2099 DONE; 2100 } 2101 else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP) 2102 { 2103 operands[1] = force_reg (SImode, operands[1]); 2104 operands[2] = force_reg (SImode, operands[2]); 2105 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2])); 2106 DONE; 2107 } 2108 else if (TARGET_SH5) 2109 { 2110 if (TARGET_DIVIDE_CALL2) 2111 { 2112 rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\"); 2113 tab_base = gen_datalabel_ref (tab_base); 2114 emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base); 2115 } 2116 if (TARGET_FPU_ANY && TARGET_SH1) 2117 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC); 2118 else if (TARGET_DIVIDE_CALL2) 2119 function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC); 2120 else 2121 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT); 2122 2123 if (TARGET_SHMEDIA) 2124 last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media) 2125 (operands[0], operands[3])); 2126 else if (TARGET_FPU_ANY) 2127 last = gen_divsi3_i4_single (operands[0], operands[3]); 2128 else 2129 last = gen_divsi3_i1 (operands[0], operands[3]); 2130 } 2131 else 2132 { 2133 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT); 2134 last = gen_divsi3_i1 (operands[0], operands[3]); 2135 } 2136 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]); 2137 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]); 2138 emit_insn (last); 2139 DONE; 2140}") 2141 2142;; operands: scratch, tab_base, tab_ix 2143;; These are unspecs because we could generate an indexed addressing mode 2144;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would 2145;; confuse reload. See PR27117. 2146 2147(define_insn "divsi_inv_qitable" 2148 [(set (match_operand:DI 0 "register_operand" "=r") 2149 (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r") 2150 (match_operand:DI 2 "register_operand" "r")] 2151 UNSPEC_DIV_INV_TABLE)))] 2152 "TARGET_SHMEDIA" 2153 "@ 2154 ldx.ub %1, %2, %0" 2155 [(set_attr "type" "load_media") 2156 (set_attr "highpart" "user")]) 2157 2158;; operands: scratch, tab_base, tab_ix 2159(define_insn "divsi_inv_hitable" 2160 [(set (match_operand:DI 0 "register_operand" "=r") 2161 (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r") 2162 (match_operand:DI 2 "register_operand" "r")] 2163 UNSPEC_DIV_INV_TABLE)))] 2164 "TARGET_SHMEDIA" 2165 "@ 2166 ldx.w %1, %2, %0" 2167 [(set_attr "type" "load_media") 2168 (set_attr "highpart" "user")]) 2169 2170;; operands: inv0, tab_base, tab_ix, norm32 2171;; scratch equiv in sdivsi3_2: r19, r21 2172(define_expand "divsi_inv_m0" 2173 [(set (match_operand:SI 0 "register_operand" "=r") 2174 (unspec:SI [(match_operand:DI 1 "register_operand" "r") 2175 (match_operand:DI 2 "register_operand" "r") 2176 (match_operand:SI 3 "register_operand" "r")] 2177 UNSPEC_DIV_INV_M0)) 2178 (clobber (match_operand:DI 4 "register_operand" "=r")) 2179 (clobber (match_operand:DI 5 "register_operand" "=r"))] 2180 "TARGET_SHMEDIA" 2181 " 2182{ 2183/* 2184tab_base: r20 2185tab_ix: r21 2186norm32: r25 2187 ldx.ub r20, r21, r19 // u0.8 2188 shlli r21, 1, r21 2189 muls.l r25, r19, r19 // s2.38 2190 ldx.w r20, r21, r21 // s2.14 2191 shari r19, 24, r19 // truncate to s2.14 2192 sub r21, r19, r19 // some 11 bit inverse in s1.14 2193*/ 2194 2195 rtx inv0 = operands[0]; 2196 rtx tab_base = operands[1]; 2197 rtx tab_ix = operands[2]; 2198 rtx norm32 = operands[3]; 2199 rtx scratch0 = operands[4]; 2200 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF); 2201 rtx scratch1 = operands[5]; 2202 2203 emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix)); 2204 emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1))); 2205 emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si)); 2206 emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1)); 2207 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24))); 2208 emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0)); 2209 DONE; 2210}") 2211 2212;; operands: inv1, tab_base, tab_ix, norm32 2213(define_insn_and_split "divsi_inv_m1" 2214 [(set (match_operand:SI 0 "register_operand" "=r") 2215 (unspec:SI [(match_operand:DI 1 "register_operand" "r") 2216 (match_operand:DI 2 "register_operand" "r") 2217 (match_operand:SI 3 "register_operand" "r")] 2218 UNSPEC_DIV_INV_M1)) 2219 (clobber (match_operand:SI 4 "register_operand" "=r")) 2220 (clobber (match_operand:DI 5 "register_operand" "=r")) 2221 (clobber (match_operand:DI 6 "register_operand" "=r")) 2222 (clobber (match_operand:DI 7 "register_operand" "=r")) 2223 (clobber (match_operand:DI 8 "register_operand" "=r"))] 2224 "TARGET_SHMEDIA" 2225 "#" 2226 "&& !can_create_pseudo_p ()" 2227 [(pc)] 2228 " 2229{ 2230/* inv0: r19 2231 muls.l r19, r19, r18 // u0.28 2232 muls.l r25, r18, r18 // s2.58 2233 shlli r19, 45, r0 // multiply by two and convert to s2.58 2234 sub r0, r18, r18 2235 shari r18, 28, r18 // some 18 bit inverse in s1.30 2236*/ 2237 2238 rtx inv1 = operands[0]; 2239 rtx tab_base = operands[1]; 2240 rtx tab_ix = operands[2]; 2241 rtx norm32 = operands[3]; 2242 rtx inv0 = operands[4]; 2243 rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0); 2244 rtx scratch0a = operands[5]; 2245 rtx scratch0b = operands[6]; 2246 rtx scratch0 = operands[7]; 2247 rtx scratch1 = operands[8]; 2248 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF); 2249 2250 emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32, 2251 scratch0a, scratch0b)); 2252 emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0)); 2253 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si)); 2254 emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45))); 2255 emit_insn (gen_subdi3 (scratch1, scratch0, scratch1)); 2256 emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28))); 2257 DONE; 2258}") 2259 2260;; operands: inv2, norm32, inv1, i92 2261(define_insn_and_split "divsi_inv_m2" 2262 [(set (match_operand:SI 0 "register_operand" "=r") 2263 (unspec:SI [(match_operand:SI 1 "register_operand" "r") 2264 (match_operand:SI 2 "register_operand" "r") 2265 (match_operand:DI 3 "register_operand" "r")] 2266 UNSPEC_DIV_INV_M2)) 2267 (clobber (match_operand:DI 4 "register_operand" "=r"))] 2268 "TARGET_SHMEDIA" 2269 "#" 2270 "&& !can_create_pseudo_p ()" 2271 [(pc)] 2272 " 2273{ 2274/* 2275 muls.l r18, r25, r0 // s2.60 2276 shari r0, 16, r0 // s-16.44 2277 sub 2278 muls.l r0, r18, r19 // s-16.74 2279 shari r19, 30, r19 // s-16.44 2280*/ 2281 rtx inv2 = operands[0]; 2282 rtx norm32 = operands[1]; 2283 rtx inv1 = operands[2]; 2284 rtx i92 = operands[3]; 2285 rtx scratch0 = operands[4]; 2286 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF); 2287 2288 emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32)); 2289 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16))); 2290 emit_insn (gen_subdi3 (scratch0, i92, scratch0)); 2291 emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1)); 2292 emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30))); 2293 DONE; 2294}") 2295 2296(define_insn_and_split "divsi_inv_m3" 2297 [(set (match_operand:SI 0 "register_operand" "=r") 2298 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN") 2299 (match_operand:SI 2 "register_operand" "r") 2300 (match_operand:SI 3 "register_operand" "r") 2301 (match_operand:DI 4 "register_operand" "r") 2302 (match_operand:DI 5 "arith_reg_or_0_operand" "rN") 2303 (match_operand:DI 6 "arith_reg_or_0_operand" "rN")] 2304 UNSPEC_DIV_INV_M3)) 2305 (clobber (match_operand:DI 7 "register_operand" "=r")) 2306 (clobber (match_operand:DI 8 "register_operand" "=r")) 2307 (clobber (match_operand:DI 9 "register_operand" "=r")) 2308 (clobber (match_operand:DI 10 "register_operand" "=r")) 2309 (clobber (match_operand:SI 11 "register_operand" "=r")) 2310 (clobber (match_operand:SI 12 "register_operand" "=r")) 2311 (clobber (match_operand:DI 13 "register_operand" "=r"))] 2312 "TARGET_SHMEDIA" 2313 "#" 2314 "&& !can_create_pseudo_p ()" 2315 [(pc)] 2316 " 2317{ 2318/* 2319 r0: result r1: shift r4: dividend r18: inv1 r19: inv2 2320 r0: scratch0 r19: scratch1 r21: scratch2 2321 2322 muls.l r18, r4, r25 // s32.30 2323 muls.l r19, r4, r19 // s15.30 2324 shari r25, 63, r21 2325 shari r19, 14, r19 // s18.-14 2326 sub r25, r19, r0 2327 shard r0, r1, r0 2328 sub r0, r21, r0 2329*/ 2330 2331 rtx result = operands[0]; 2332 rtx dividend = operands[1]; 2333 rtx inv1 = operands[2]; 2334 rtx inv2 = operands[3]; 2335 rtx shift = operands[4]; 2336 rtx scratch0 = operands[7]; 2337 rtx scratch1 = operands[8]; 2338 rtx scratch2 = operands[9]; 2339 2340 if (satisfies_constraint_N (dividend)) 2341 { 2342 emit_move_insn (result, dividend); 2343 DONE; 2344 } 2345 2346 emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend)); 2347 emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend)); 2348 emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63))); 2349 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14))); 2350 emit_insn (gen_adddi3 (scratch0, scratch0, scratch1)); 2351 emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift)); 2352 emit_insn (gen_subdisi3_media (result, scratch0, scratch2)); 2353 DONE; 2354}") 2355 2356;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43 2357;; inv1: tab_base, tab_ix, norm32 2358;; inv2: norm32, inv1, i92 2359(define_insn_and_split "divsi_inv_m1_3" 2360 [(set (match_operand:SI 0 "register_operand" "=r") 2361 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN") 2362 (unspec:SI [(match_operand:DI 2 "register_operand" "r") 2363 (match_operand:DI 3 "register_operand" "r") 2364 (match_operand:SI 4 "register_operand" "r")] 2365 UNSPEC_DIV_INV_M1) 2366 (unspec:SI [(match_dup 4) 2367 (unspec:SI [(match_dup 2) 2368 (match_dup 3) 2369 (match_dup 4)] UNSPEC_DIV_INV_M1) 2370 (match_operand:SI 5 "" "")] 2371 UNSPEC_DIV_INV_M2) 2372 (match_operand:DI 6 "register_operand" "r") 2373 (match_operand:DI 7 "arith_reg_or_0_operand" "rN") 2374 (match_operand:DI 8 "arith_reg_or_0_operand" "rN")] 2375 UNSPEC_DIV_INV_M3)) 2376 (clobber (match_operand:DI 9 "register_operand" "=r")) 2377 (clobber (match_operand:DI 10 "register_operand" "=r")) 2378 (clobber (match_operand:DI 11 "register_operand" "=r")) 2379 (clobber (match_operand:DI 12 "register_operand" "=r")) 2380 (clobber (match_operand:SI 13 "register_operand" "=r")) 2381 (clobber (match_operand:SI 14 "register_operand" "=r")) 2382 (clobber (match_operand:DI 15 "register_operand" "=r"))] 2383 "TARGET_SHMEDIA 2384 && (TARGET_DIVIDE_INV_MINLAT 2385 || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)" 2386 "#" 2387 "&& !can_create_pseudo_p ()" 2388 [(pc)] 2389 " 2390{ 2391 rtx result = operands[0]; 2392 rtx dividend = operands[1]; 2393 rtx tab_base = operands[2]; 2394 rtx tab_ix = operands[3]; 2395 rtx norm32 = operands[4]; 2396 /* rtx i92 = operands[5]; */ 2397 rtx shift = operands[6]; 2398 rtx i2p27 = operands[7]; 2399 rtx i43 = operands[8]; 2400 rtx scratch0 = operands[9]; 2401 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF); 2402 rtx scratch1 = operands[10]; 2403 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF); 2404 rtx scratch2 = operands[11]; 2405 rtx scratch3 = operands[12]; 2406 rtx scratch4 = operands[13]; 2407 rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0); 2408 rtx scratch5 = operands[14]; 2409 rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0); 2410 rtx scratch6 = operands[15]; 2411 2412 emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32, 2413 scratch0, scratch1)); 2414 /* inv0 == scratch4 */ 2415 if (! TARGET_DIVIDE_INV20U) 2416 { 2417 emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4)); 2418 i2p27 = scratch0; 2419 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si)); 2420 } 2421 else 2422 { 2423 emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4)); 2424 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si)); 2425 } 2426 emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45))); 2427 emit_insn (gen_subdi3 (scratch1, scratch2, scratch1)); 2428 emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28))); 2429 /* inv1 == scratch4 */ 2430 2431 if (TARGET_DIVIDE_INV_MINLAT) 2432 { 2433 emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32)); 2434 emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4)); 2435 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16))); 2436 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4)); 2437 emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63))); 2438 emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14))); 2439 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30))); 2440 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5)); 2441 emit_insn (gen_xordi3 (scratch0, scratch3, i2p27)); 2442 emit_insn (gen_adddi3 (scratch2, scratch2, scratch0)); 2443 emit_insn (gen_subdi3 (scratch2, scratch2, scratch1)); 2444 } 2445 else 2446 { 2447 rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ()); 2448 /* Use separate scratch regs for nsb and sign to allow scheduling. */ 2449 emit_insn (gen_nsbdi (scratch6, 2450 simplify_gen_subreg (DImode, dividend, SImode, 0))); 2451 emit_insn (gen_xorsi3 (scratch5, dividend, norm32)); 2452 emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63))); 2453 emit_insn (gen_divsi_inv20 (scratch2, 2454 norm32, scratch4, dividend, 2455 scratch6, scratch3, i43, 2456 /* scratch0 may be shared with i2p27. */ 2457 scratch0, scratch1, scratch5, 2458 label, label, i2p27)); 2459 } 2460 emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift)); 2461 emit_insn (gen_subdisi3_media (result, scratch2, scratch3)); 2462 DONE; 2463}") 2464 2465(define_insn "divsi_inv20" 2466 [(set (match_operand:DI 0 "register_operand" "=&r") 2467 (unspec:DI [(match_operand:SI 1 "register_operand" "r") 2468 (match_operand:SI 2 "register_operand" "r") 2469 (match_operand:SI 3 "register_operand" "r") 2470 (match_operand:DI 4 "register_operand" "r") 2471 (match_operand:DI 5 "register_operand" "r") 2472 (match_operand:DI 6 "register_operand" "r") 2473 (match_operand:DI 12 "register_operand" "r") 2474 (match_operand 10 "target_operand" "b") 2475 (match_operand 11 "immediate_operand" "i")] 2476 UNSPEC_DIV_INV20)) 2477 (clobber (match_operand:DI 7 "register_operand" "=&r")) 2478 (clobber (match_operand:DI 8 "register_operand" "=&r")) 2479 (clobber (match_operand:SI 9 "register_operand" "=r"))] 2480 "TARGET_SHMEDIA 2481 && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)" 2482 "* 2483{ 2484/* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend, 2485 %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27, 2486 %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si) 2487 %10 label (tr), %11 label (imm) 2488 2489 muls.l inv1, norm32, scratch0 // s2.60 2490 muls.l inv1, dividend, result // s32.30 2491 xor i2p27, result_sign, round_scratch 2492 bge/u dividend_nsb, i43, tr.. (label) 2493 shari scratch0, 16, scratch0 // s-16.44 2494 muls.l sratch0_si, inv1, scratch0 // s-16.74 2495 sub result, round_scratch, result 2496 shari dividend, 14, scratch1 // s19.-14 2497 shari scratch0, 30, scratch0 // s-16.44 2498 muls.l scratch0, scratch1, round_scratch // s15.30 2499label: 2500 sub result, round_scratch, result */ 2501 2502 int likely = TARGET_DIVIDE_INV20L; 2503 2504 if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands); 2505 output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands); 2506 output_asm_insn (likely 2507 ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\" 2508 : \"bge/u\t%4, %6, %10\", operands); 2509 output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands); 2510 if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands); 2511 output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands); 2512 return (likely 2513 ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\" 2514 : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\"); 2515}") 2516 2517(define_insn_and_split "divsi_inv_fp" 2518 [(set (match_operand:SI 0 "general_movdst_operand" "=rf") 2519 (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf") 2520 (match_operand:SI 2 "register_operand" "rf"))) 2521 (use (match_operand:SI 3 "general_movsrc_operand" "r")) 2522 (clobber (match_operand:SI 4 "register_operand" "=r")) 2523 (clobber (match_operand:SI 5 "register_operand" "=r")) 2524 (clobber (match_operand:DF 6 "register_operand" "=r")) 2525 (clobber (match_operand:DF 7 "register_operand" "=r")) 2526 (clobber (match_operand:DF 8 "register_operand" "=r"))] 2527 "TARGET_SHMEDIA_FPU" 2528 "#" 2529 "&& (high_life_started || reload_completed)" 2530 [(set (match_dup 0) (match_dup 3))] 2531 "" 2532 [(set_attr "highpart" "must_split")]) 2533 2534;; If a matching group of divide-by-inverse instructions is in the same 2535;; basic block after gcse & loop optimizations, we want to transform them 2536;; to a straight division using floating point for TARGET_DIVIDE_INV_FP. 2537(define_insn_and_split "*divsi_inv_fp_combine" 2538 [(set (match_operand:SI 0 "register_operand" "=f") 2539 (div:SI (match_operand:SI 1 "register_operand" "f") 2540 (match_operand:SI 2 "register_operand" "f"))) 2541 (use (unspec:SI [(match_dup 1) 2542 (match_operand:SI 3 "" "") 2543 (unspec:SI [(match_operand:SI 4 "" "") 2544 (match_dup 3) 2545 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2) 2546 (match_operand:DI 6 "" "") 2547 (const_int 0) 2548 (const_int 0)] UNSPEC_DIV_INV_M3)) 2549 (clobber (match_operand:SI 7 "fp_arith_reg_operand" "")) 2550 (clobber (match_operand:SI 8 "fp_arith_reg_operand" "")) 2551 (clobber (match_operand:DF 9 "fp_arith_reg_operand" "")) 2552 (clobber (match_operand:DF 10 "fp_arith_reg_operand" "")) 2553 (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))] 2554 "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && !can_create_pseudo_p ()" 2555 "#" 2556 "&& 1" 2557 [(set (match_dup 9) (float:DF (match_dup 1))) 2558 (set (match_dup 10) (float:DF (match_dup 2))) 2559 (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10))) 2560 (set (match_dup 8) 2561 (fix:SI (match_dup 11))) 2562 (set (match_dup 0) (match_dup 8))] 2563 " 2564{ 2565 if (! fp_arith_reg_operand (operands[1], SImode)) 2566 { 2567 emit_move_insn (operands[7], operands[1]); 2568 operands[1] = operands[7]; 2569 } 2570 if (! fp_arith_reg_operand (operands[2], SImode)) 2571 { 2572 emit_move_insn (operands[8], operands[2]); 2573 operands[2] = operands[8]; 2574 } 2575}" 2576 [(set_attr "highpart" "must_split")]) 2577 2578;; ------------------------------------------------------------------------- 2579;; Multiplication instructions 2580;; ------------------------------------------------------------------------- 2581 2582(define_insn "umulhisi3_i" 2583 [(set (reg:SI MACL_REG) 2584 (mult:SI (zero_extend:SI 2585 (match_operand:HI 0 "arith_reg_operand" "r")) 2586 (zero_extend:SI 2587 (match_operand:HI 1 "arith_reg_operand" "r"))))] 2588 "TARGET_SH1" 2589 "mulu.w %1,%0" 2590 [(set_attr "type" "smpy")]) 2591 2592(define_insn "mulhisi3_i" 2593 [(set (reg:SI MACL_REG) 2594 (mult:SI (sign_extend:SI 2595 (match_operand:HI 0 "arith_reg_operand" "r")) 2596 (sign_extend:SI 2597 (match_operand:HI 1 "arith_reg_operand" "r"))))] 2598 "TARGET_SH1" 2599 "muls.w %1,%0" 2600 [(set_attr "type" "smpy")]) 2601 2602(define_expand "mulhisi3" 2603 [(set (reg:SI MACL_REG) 2604 (mult:SI (sign_extend:SI 2605 (match_operand:HI 1 "arith_reg_operand" "")) 2606 (sign_extend:SI 2607 (match_operand:HI 2 "arith_reg_operand" "")))) 2608 (set (match_operand:SI 0 "arith_reg_operand" "") 2609 (reg:SI MACL_REG))] 2610 "TARGET_SH1" 2611 " 2612{ 2613 rtx insn, macl; 2614 2615 macl = gen_rtx_REG (SImode, MACL_REG); 2616 start_sequence (); 2617 emit_insn (gen_mulhisi3_i (operands[1], operands[2])); 2618 insn = get_insns (); 2619 end_sequence (); 2620 /* expand_binop can't find a suitable code in umul_widen_optab to 2621 make a REG_EQUAL note from, so make one here. 2622 See also smulsi3_highpart. 2623 ??? Alternatively, we could put this at the calling site of expand_binop, 2624 i.e. expand_expr. */ 2625 /* Use emit_libcall_block for loop invariant code motion and to make 2626 a REG_EQUAL note. */ 2627 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn))); 2628 2629 DONE; 2630}") 2631 2632(define_expand "umulhisi3" 2633 [(set (reg:SI MACL_REG) 2634 (mult:SI (zero_extend:SI 2635 (match_operand:HI 1 "arith_reg_operand" "")) 2636 (zero_extend:SI 2637 (match_operand:HI 2 "arith_reg_operand" "")))) 2638 (set (match_operand:SI 0 "arith_reg_operand" "") 2639 (reg:SI MACL_REG))] 2640 "TARGET_SH1" 2641 " 2642{ 2643 rtx insn, macl; 2644 2645 macl = gen_rtx_REG (SImode, MACL_REG); 2646 start_sequence (); 2647 emit_insn (gen_umulhisi3_i (operands[1], operands[2])); 2648 insn = get_insns (); 2649 end_sequence (); 2650 /* expand_binop can't find a suitable code in umul_widen_optab to 2651 make a REG_EQUAL note from, so make one here. 2652 See also smulsi3_highpart. 2653 ??? Alternatively, we could put this at the calling site of expand_binop, 2654 i.e. expand_expr. */ 2655 /* Use emit_libcall_block for loop invariant code motion and to make 2656 a REG_EQUAL note. */ 2657 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn))); 2658 2659 DONE; 2660}") 2661 2662;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate 2663;; a call to a routine which clobbers known registers. 2664 2665(define_insn "" 2666 [(set (match_operand:SI 1 "register_operand" "=z") 2667 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG))) 2668 (clobber (reg:SI MACL_REG)) 2669 (clobber (reg:SI T_REG)) 2670 (clobber (reg:SI PR_REG)) 2671 (clobber (reg:SI R3_REG)) 2672 (clobber (reg:SI R2_REG)) 2673 (clobber (reg:SI R1_REG)) 2674 (use (match_operand:SI 0 "arith_reg_operand" "r"))] 2675 "TARGET_SH1" 2676 "jsr @%0%#" 2677 [(set_attr "type" "sfunc") 2678 (set_attr "needs_delay_slot" "yes")]) 2679 2680(define_expand "mulsi3_call" 2681 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" "")) 2682 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" "")) 2683 (parallel[(set (match_operand:SI 0 "register_operand" "") 2684 (mult:SI (reg:SI R4_REG) 2685 (reg:SI R5_REG))) 2686 (clobber (reg:SI MACL_REG)) 2687 (clobber (reg:SI T_REG)) 2688 (clobber (reg:SI PR_REG)) 2689 (clobber (reg:SI R3_REG)) 2690 (clobber (reg:SI R2_REG)) 2691 (clobber (reg:SI R1_REG)) 2692 (use (match_operand:SI 3 "register_operand" ""))])] 2693 "TARGET_SH1" 2694 "") 2695 2696(define_insn "mul_r" 2697 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 2698 (mult:SI (match_operand:SI 1 "arith_reg_operand" "0") 2699 (match_operand:SI 2 "arith_reg_operand" "z")))] 2700 "TARGET_SH2A" 2701 "mulr %2,%0" 2702 [(set_attr "type" "dmpy")]) 2703 2704(define_insn "mul_l" 2705 [(set (reg:SI MACL_REG) 2706 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r") 2707 (match_operand:SI 1 "arith_reg_operand" "r")))] 2708 "TARGET_SH2" 2709 "mul.l %1,%0" 2710 [(set_attr "type" "dmpy")]) 2711 2712(define_expand "mulsi3" 2713 [(set (reg:SI MACL_REG) 2714 (mult:SI (match_operand:SI 1 "arith_reg_operand" "") 2715 (match_operand:SI 2 "arith_reg_operand" ""))) 2716 (set (match_operand:SI 0 "arith_reg_operand" "") 2717 (reg:SI MACL_REG))] 2718 "TARGET_SH1" 2719 " 2720{ 2721 if (!TARGET_SH2) 2722 { 2723 /* The address must be set outside the libcall, 2724 since it goes into a pseudo. */ 2725 rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC); 2726 rtx addr = force_reg (SImode, sym); 2727 rtx insns = gen_mulsi3_call (operands[0], operands[1], 2728 operands[2], addr); 2729 emit_insn (insns); 2730 } 2731 else 2732 { 2733 rtx macl = gen_rtx_REG (SImode, MACL_REG); 2734 2735 emit_insn (gen_mul_l (operands[1], operands[2])); 2736 /* consec_sets_giv can only recognize the first insn that sets a 2737 giv as the giv insn. So we must tag this also with a REG_EQUAL 2738 note. */ 2739 emit_insn (gen_movsi_i ((operands[0]), macl)); 2740 } 2741 DONE; 2742}") 2743 2744(define_insn "mulsidi3_i" 2745 [(set (reg:SI MACH_REG) 2746 (truncate:SI 2747 (lshiftrt:DI 2748 (mult:DI 2749 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r")) 2750 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))) 2751 (const_int 32)))) 2752 (set (reg:SI MACL_REG) 2753 (mult:SI (match_dup 0) 2754 (match_dup 1)))] 2755 "TARGET_SH2" 2756 "dmuls.l %1,%0" 2757 [(set_attr "type" "dmpy")]) 2758 2759(define_expand "mulsidi3" 2760 [(set (match_operand:DI 0 "arith_reg_operand" "=r") 2761 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")) 2762 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))] 2763 "TARGET_SH2 || TARGET_SHMEDIA" 2764 " 2765{ 2766 if (TARGET_SH2) 2767 { 2768 emit_insn (gen_mulsidi3_compact (operands[0], operands[1], 2769 operands[2])); 2770 DONE; 2771 } 2772}") 2773 2774(define_insn "mulsidi3_media" 2775 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 2776 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r")) 2777 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))] 2778 "TARGET_SHMEDIA" 2779 "muls.l %1, %2, %0" 2780 [(set_attr "type" "dmpy_media") 2781 (set_attr "highpart" "ignore")]) 2782 2783(define_insn "mulsidi3_compact" 2784 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 2785 (mult:DI 2786 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")) 2787 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r")))) 2788 (clobber (reg:SI MACH_REG)) 2789 (clobber (reg:SI MACL_REG))] 2790 "TARGET_SH2" 2791 "#") 2792 2793(define_split 2794 [(set (match_operand:DI 0 "arith_reg_dest" "") 2795 (mult:DI 2796 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "")) 2797 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))) 2798 (clobber (reg:SI MACH_REG)) 2799 (clobber (reg:SI MACL_REG))] 2800 "TARGET_SH2" 2801 [(const_int 0)] 2802 " 2803{ 2804 rtx low_dst = gen_lowpart (SImode, operands[0]); 2805 rtx high_dst = gen_highpart (SImode, operands[0]); 2806 2807 emit_insn (gen_mulsidi3_i (operands[1], operands[2])); 2808 2809 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG)); 2810 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG)); 2811 /* We need something to tag the possible REG_EQUAL notes on to. */ 2812 emit_move_insn (operands[0], operands[0]); 2813 DONE; 2814}") 2815 2816(define_insn "umulsidi3_i" 2817 [(set (reg:SI MACH_REG) 2818 (truncate:SI 2819 (lshiftrt:DI 2820 (mult:DI 2821 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r")) 2822 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))) 2823 (const_int 32)))) 2824 (set (reg:SI MACL_REG) 2825 (mult:SI (match_dup 0) 2826 (match_dup 1)))] 2827 "TARGET_SH2" 2828 "dmulu.l %1,%0" 2829 [(set_attr "type" "dmpy")]) 2830 2831(define_expand "umulsidi3" 2832 [(set (match_operand:DI 0 "arith_reg_operand" "=r") 2833 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")) 2834 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))] 2835 "TARGET_SH2 || TARGET_SHMEDIA" 2836 " 2837{ 2838 if (TARGET_SH2) 2839 { 2840 emit_insn (gen_umulsidi3_compact (operands[0], operands[1], 2841 operands[2])); 2842 DONE; 2843 } 2844}") 2845 2846(define_insn "umulsidi3_media" 2847 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 2848 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r")) 2849 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))] 2850 "TARGET_SHMEDIA" 2851 "mulu.l %1, %2, %0" 2852 [(set_attr "type" "dmpy_media") 2853 (set_attr "highpart" "ignore")]) 2854 2855(define_insn "umulsidi3_compact" 2856 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 2857 (mult:DI 2858 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")) 2859 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r")))) 2860 (clobber (reg:SI MACH_REG)) 2861 (clobber (reg:SI MACL_REG))] 2862 "TARGET_SH2" 2863 "#") 2864 2865(define_split 2866 [(set (match_operand:DI 0 "arith_reg_dest" "") 2867 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "")) 2868 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))) 2869 (clobber (reg:SI MACH_REG)) 2870 (clobber (reg:SI MACL_REG))] 2871 "TARGET_SH2" 2872 [(const_int 0)] 2873 " 2874{ 2875 rtx low_dst = gen_lowpart (SImode, operands[0]); 2876 rtx high_dst = gen_highpart (SImode, operands[0]); 2877 2878 emit_insn (gen_umulsidi3_i (operands[1], operands[2])); 2879 2880 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG)); 2881 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG)); 2882 /* We need something to tag the possible REG_EQUAL notes on to. */ 2883 emit_move_insn (operands[0], operands[0]); 2884 DONE; 2885}") 2886 2887(define_insn "smulsi3_highpart_i" 2888 [(set (reg:SI MACH_REG) 2889 (truncate:SI 2890 (lshiftrt:DI 2891 (mult:DI 2892 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r")) 2893 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))) 2894 (const_int 32)))) 2895 (clobber (reg:SI MACL_REG))] 2896 "TARGET_SH2" 2897 "dmuls.l %1,%0" 2898 [(set_attr "type" "dmpy")]) 2899 2900(define_expand "smulsi3_highpart" 2901 [(parallel 2902 [(set (reg:SI MACH_REG) 2903 (truncate:SI 2904 (lshiftrt:DI 2905 (mult:DI 2906 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "")) 2907 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))) 2908 (const_int 32)))) 2909 (clobber (reg:SI MACL_REG))]) 2910 (set (match_operand:SI 0 "arith_reg_operand" "") 2911 (reg:SI MACH_REG))] 2912 "TARGET_SH2" 2913 " 2914{ 2915 rtx insn, mach; 2916 2917 mach = gen_rtx_REG (SImode, MACH_REG); 2918 start_sequence (); 2919 emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2])); 2920 insn = get_insns (); 2921 end_sequence (); 2922 /* expand_binop can't find a suitable code in mul_highpart_optab to 2923 make a REG_EQUAL note from, so make one here. 2924 See also {,u}mulhisi. 2925 ??? Alternatively, we could put this at the calling site of expand_binop, 2926 i.e. expand_mult_highpart. */ 2927 /* Use emit_libcall_block for loop invariant code motion and to make 2928 a REG_EQUAL note. */ 2929 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn))); 2930 2931 DONE; 2932}") 2933 2934(define_insn "umulsi3_highpart_i" 2935 [(set (reg:SI MACH_REG) 2936 (truncate:SI 2937 (lshiftrt:DI 2938 (mult:DI 2939 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r")) 2940 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))) 2941 (const_int 32)))) 2942 (clobber (reg:SI MACL_REG))] 2943 "TARGET_SH2" 2944 "dmulu.l %1,%0" 2945 [(set_attr "type" "dmpy")]) 2946 2947(define_expand "umulsi3_highpart" 2948 [(parallel 2949 [(set (reg:SI MACH_REG) 2950 (truncate:SI 2951 (lshiftrt:DI 2952 (mult:DI 2953 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "")) 2954 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))) 2955 (const_int 32)))) 2956 (clobber (reg:SI MACL_REG))]) 2957 (set (match_operand:SI 0 "arith_reg_operand" "") 2958 (reg:SI MACH_REG))] 2959 "TARGET_SH2" 2960 " 2961{ 2962 rtx insn, mach; 2963 2964 mach = gen_rtx_REG (SImode, MACH_REG); 2965 start_sequence (); 2966 emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2])); 2967 insn = get_insns (); 2968 end_sequence (); 2969 /* Use emit_libcall_block for loop invariant code motion and to make 2970 a REG_EQUAL note. */ 2971 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn))); 2972 2973 DONE; 2974}") 2975 2976(define_insn_and_split "muldi3" 2977 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 2978 (mult:DI (match_operand:DI 1 "arith_reg_operand" "r") 2979 (match_operand:DI 2 "arith_reg_operand" "r"))) 2980 (clobber (match_scratch:DI 3 "=&r")) 2981 (clobber (match_scratch:DI 4 "=r"))] 2982 "TARGET_SHMEDIA" 2983 "#" 2984 "reload_completed" 2985 [(const_int 0)] 2986 " 2987{ 2988 rtx op3_v2si, op2_v2si; 2989 2990 op3_v2si = operands[3]; 2991 if (GET_CODE (op3_v2si) == SIGN_EXTEND) 2992 { 2993 op3_v2si = XEXP (op3_v2si, 0); 2994 op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0); 2995 } 2996 op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0); 2997 op2_v2si = operands[2]; 2998 if (GET_CODE (op2_v2si) == SIGN_EXTEND) 2999 { 3000 op2_v2si = XEXP (op2_v2si, 0); 3001 op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0); 3002 } 3003 op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0); 3004 emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32))); 3005 emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si)); 3006 emit_insn (gen_umulsidi3_media (operands[4], 3007 sh_gen_truncate (SImode, operands[1], 0), 3008 sh_gen_truncate (SImode, operands[2], 0))); 3009 emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL))); 3010 emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32))); 3011 emit_insn (gen_adddi3 (operands[0], operands[3], operands[0])); 3012 emit_insn (gen_adddi3 (operands[0], operands[4], operands[0])); 3013 DONE; 3014}") 3015 3016 3017;; ------------------------------------------------------------------------- 3018;; Logical operations 3019;; ------------------------------------------------------------------------- 3020 3021(define_insn "*andsi3_compact" 3022 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z") 3023 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0") 3024 (match_operand:SI 2 "logical_operand" "r,K08")))] 3025 "TARGET_SH1" 3026 "and %2,%0" 3027 [(set_attr "type" "arith")]) 3028 3029(define_insn "*andsi3_media" 3030 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r") 3031 (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r") 3032 (match_operand:SI 2 "logical_operand" "r,I10")))] 3033 "TARGET_SHMEDIA" 3034 "@ 3035 and %1, %2, %0 3036 andi %1, %2, %0" 3037 [(set_attr "type" "arith_media")]) 3038 3039(define_insn "*andsi3_bclr" 3040 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 3041 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0") 3042 (match_operand:SI 2 "const_int_operand" "Psz")))] 3043 "TARGET_SH2A && satisfies_constraint_Psz (operands[2])" 3044 "bclr\\t%W2,%0" 3045 [(set_attr "type" "arith")]) 3046 3047;; If the constant is 255, then emit an extu.b instruction instead of an 3048;; and, since that will give better code. 3049 3050(define_expand "andsi3" 3051 [(set (match_operand:SI 0 "arith_reg_operand" "") 3052 (and:SI (match_operand:SI 1 "logical_reg_operand" "") 3053 (match_operand:SI 2 "logical_operand" "")))] 3054 "" 3055 " 3056{ 3057 if (TARGET_SH1 3058 && CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 255) 3059 { 3060 emit_insn (gen_zero_extendqisi2 (operands[0], 3061 gen_lowpart (QImode, operands[1]))); 3062 DONE; 3063 } 3064}") 3065 3066(define_insn_and_split "anddi3" 3067 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r") 3068 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r") 3069 (match_operand:DI 2 "and_operand" "r,I10,J16")))] 3070 "TARGET_SHMEDIA" 3071 "@ 3072 and %1, %2, %0 3073 andi %1, %2, %0 3074 #" 3075 "reload_completed 3076 && ! logical_operand (operands[2], DImode)" 3077 [(const_int 0)] 3078 " 3079{ 3080 if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff) 3081 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode))); 3082 else 3083 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1])); 3084 DONE; 3085}" 3086 [(set_attr "type" "arith_media")]) 3087 3088(define_insn "andcsi3" 3089 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 3090 (and:SI (match_operand:SI 1 "arith_reg_operand" "r") 3091 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))] 3092 "TARGET_SHMEDIA" 3093 "andc %1,%2,%0" 3094 [(set_attr "type" "arith_media")]) 3095 3096(define_insn "andcdi3" 3097 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 3098 (and:DI (match_operand:DI 1 "arith_reg_operand" "r") 3099 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))] 3100 "TARGET_SHMEDIA" 3101 "andc %1,%2,%0" 3102 [(set_attr "type" "arith_media")]) 3103 3104(define_expand "iorsi3" 3105 [(set (match_operand:SI 0 "arith_reg_operand" "") 3106 (ior:SI (match_operand:SI 1 "logical_reg_operand" "") 3107 (match_operand:SI 2 "logical_operand" "")))] 3108 "" 3109 "") 3110 3111(define_insn "*iorsi3_compact" 3112 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z") 3113 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0") 3114 (match_operand:SI 2 "logical_operand" "r,K08")))] 3115 "TARGET_SH1 3116 && !(TARGET_SH2A && satisfies_constraint_Pso (operands[2]))" 3117 "or %2,%0" 3118 [(set_attr "type" "arith")]) 3119 3120(define_insn "*iorsi3_media" 3121 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r") 3122 (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r") 3123 (match_operand:SI 2 "logical_operand" "r,I10")))] 3124 "TARGET_SHMEDIA" 3125 "@ 3126 or %1, %2, %0 3127 ori %1, %2, %0" 3128 [(set_attr "type" "arith_media")]) 3129 3130(define_insn "*iorsi3_bset" 3131 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 3132 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0") 3133 (match_operand:SI 2 "const_int_operand" "Pso")))] 3134 "TARGET_SH2A && satisfies_constraint_Pso (operands[2])" 3135 "bset\\t%V2,%0" 3136 [(set_attr "type" "arith")]) 3137 3138(define_insn "iordi3" 3139 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r") 3140 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r") 3141 (match_operand:DI 2 "logical_operand" "r,I10")))] 3142 "TARGET_SHMEDIA" 3143 "@ 3144 or %1, %2, %0 3145 ori %1, %2, %0" 3146 [(set_attr "type" "arith_media")]) 3147 3148(define_insn_and_split "*logical_sidi3" 3149 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r") 3150 (sign_extend:DI (match_operator:SI 3 "logical_operator" 3151 [(match_operand:SI 1 "arith_reg_operand" "%r,r") 3152 (match_operand:SI 2 "logical_operand" "r,I10")])))] 3153 "TARGET_SHMEDIA" 3154 "#" 3155 "&& reload_completed" 3156 [(set (match_dup 0) (match_dup 3))] 3157 " 3158{ 3159 operands[3] 3160 = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode, 3161 simplify_gen_subreg (DImode, operands[1], SImode, 0), 3162 simplify_gen_subreg (DImode, operands[2], SImode, 0)); 3163}") 3164 3165(define_insn_and_split "*logical_sidisi3" 3166 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r") 3167 (truncate:SI (sign_extend:DI 3168 (match_operator:SI 3 "logical_operator" 3169 [(match_operand:SI 1 "arith_reg_operand" "%r,r") 3170 (match_operand:SI 2 "logical_operand" "r,I10")]))))] 3171 "TARGET_SHMEDIA" 3172 "#" 3173 "&& 1" 3174 [(set (match_dup 0) (match_dup 3))]) 3175 3176(define_insn_and_split "*logical_sidi3_2" 3177 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r") 3178 (sign_extend:DI (truncate:SI (sign_extend:DI 3179 (match_operator:SI 3 "logical_operator" 3180 [(match_operand:SI 1 "arith_reg_operand" "%r,r") 3181 (match_operand:SI 2 "logical_operand" "r,I10")])))))] 3182 "TARGET_SHMEDIA" 3183 "#" 3184 "&& 1" 3185 [(set (match_dup 0) (sign_extend:DI (match_dup 3)))]) 3186 3187(define_expand "xorsi3" 3188 [(set (match_operand:SI 0 "arith_reg_operand" "") 3189 (xor:SI (match_operand:SI 1 "logical_reg_operand" "") 3190 (match_operand:SI 2 "xor_operand" "")))] 3191 "" 3192 "") 3193 3194(define_insn "*xorsi3_compact" 3195 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r") 3196 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0") 3197 (match_operand:SI 2 "logical_operand" "K08,r")))] 3198 "TARGET_SH1" 3199 "xor %2,%0" 3200 [(set_attr "type" "arith")]) 3201 3202(define_insn "*xorsi3_media" 3203 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r") 3204 (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r") 3205 (match_operand:SI 2 "xor_operand" "r,I06")))] 3206 "TARGET_SHMEDIA" 3207 "@ 3208 xor %1, %2, %0 3209 xori %1, %2, %0" 3210 [(set_attr "type" "arith_media")]) 3211 3212;; Store the complements of the T bit in a register. 3213(define_insn "xorsi3_movrt" 3214 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 3215 (xor:SI (reg:SI T_REG) 3216 (const_int 1)))] 3217 "TARGET_SH2A" 3218 "movrt\\t%0" 3219 [(set_attr "type" "arith")]) 3220 3221(define_insn "xordi3" 3222 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r") 3223 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r") 3224 (match_operand:DI 2 "xor_operand" "r,I06")))] 3225 "TARGET_SHMEDIA" 3226 "@ 3227 xor %1, %2, %0 3228 xori %1, %2, %0" 3229 [(set_attr "type" "arith_media")]) 3230 3231;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate. 3232;; converts 2 * sign extend -> logical op into logical op -> sign extend 3233(define_split 3234 [(set (match_operand:DI 0 "arith_reg_dest" "") 3235 (sign_extend:DI (match_operator 4 "binary_logical_operator" 3236 [(match_operand 1 "any_register_operand" "") 3237 (match_operand 2 "any_register_operand" "")])))] 3238 "TARGET_SHMEDIA" 3239 [(set (match_dup 5) (match_dup 4)) 3240 (set (match_dup 0) (sign_extend:DI (match_dup 5)))] 3241" 3242{ 3243 enum machine_mode inmode = GET_MODE (operands[1]); 3244 int offset = 0; 3245 3246 if (GET_CODE (operands[0]) == SUBREG) 3247 { 3248 offset = SUBREG_BYTE (operands[0]); 3249 operands[0] = SUBREG_REG (operands[0]); 3250 } 3251 gcc_assert (REG_P (operands[0])); 3252 if (! TARGET_LITTLE_ENDIAN) 3253 offset += 8 - GET_MODE_SIZE (inmode); 3254 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset); 3255}") 3256 3257;; ------------------------------------------------------------------------- 3258;; Shifts and rotates 3259;; ------------------------------------------------------------------------- 3260 3261(define_expand "rotldi3" 3262 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 3263 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r") 3264 (match_operand:HI 2 "mextr_bit_offset" "i")))] 3265 "TARGET_SHMEDIA" 3266 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;") 3267 3268(define_insn "rotldi3_mextr" 3269 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 3270 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r") 3271 (match_operand:HI 2 "mextr_bit_offset" "i")))] 3272 "TARGET_SHMEDIA" 3273 "* 3274{ 3275 static char templ[16]; 3276 3277 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", 3278 8 - (int) (INTVAL (operands[2]) >> 3)); 3279 return templ; 3280}" 3281 [(set_attr "type" "arith_media")]) 3282 3283(define_expand "rotrdi3" 3284 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 3285 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r") 3286 (match_operand:HI 2 "mextr_bit_offset" "i")))] 3287 "TARGET_SHMEDIA" 3288 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;") 3289 3290(define_insn "rotrdi3_mextr" 3291 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 3292 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r") 3293 (match_operand:HI 2 "mextr_bit_offset" "i")))] 3294 "TARGET_SHMEDIA" 3295 "* 3296{ 3297 static char templ[16]; 3298 3299 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3); 3300 return templ; 3301}" 3302 [(set_attr "type" "arith_media")]) 3303 3304(define_split 3305 [(set (match_operand:DI 0 "arith_reg_dest" "") 3306 (ior:DI (zero_extend:DI (mem:QI (match_operand 1 3307 "ua_address_operand" ""))) 3308 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "") 3309 (const_int 8)))) 3310 (clobber (match_operand:DI 3 "register_operand" ""))] 3311 "TARGET_SHMEDIA" 3312 [(match_dup 4) (match_dup 5)] 3313 " 3314{ 3315 operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q) 3316 (operands[3], operands[1])); 3317 operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2], 3318 GEN_INT (56), GEN_INT (8)); 3319}") 3320 3321(define_insn "rotlsi3_1" 3322 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 3323 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0") 3324 (const_int 1))) 3325 (set (reg:SI T_REG) 3326 (lshiftrt:SI (match_dup 1) (const_int 31)))] 3327 "TARGET_SH1" 3328 "rotl %0" 3329 [(set_attr "type" "arith")]) 3330 3331(define_insn "rotlsi3_31" 3332 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 3333 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0") 3334 (const_int 31))) 3335 (clobber (reg:SI T_REG))] 3336 "TARGET_SH1" 3337 "rotr %0" 3338 [(set_attr "type" "arith")]) 3339 3340(define_insn "rotlsi3_16" 3341 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 3342 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r") 3343 (const_int 16)))] 3344 "TARGET_SH1" 3345 "swap.w %1,%0" 3346 [(set_attr "type" "arith")]) 3347 3348(define_expand "rotlsi3" 3349 [(set (match_operand:SI 0 "arith_reg_dest" "") 3350 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "") 3351 (match_operand:SI 2 "immediate_operand" "")))] 3352 "TARGET_SH1" 3353 " 3354{ 3355 static const char rot_tab[] = { 3356 000, 000, 000, 000, 000, 000, 010, 001, 3357 001, 001, 011, 013, 003, 003, 003, 003, 3358 003, 003, 003, 003, 003, 013, 012, 002, 3359 002, 002, 010, 000, 000, 000, 000, 000, 3360 }; 3361 3362 int count, choice; 3363 3364 if (!CONST_INT_P (operands[2])) 3365 FAIL; 3366 count = INTVAL (operands[2]); 3367 choice = rot_tab[count]; 3368 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1) 3369 FAIL; 3370 choice &= 7; 3371 switch (choice) 3372 { 3373 case 0: 3374 emit_move_insn (operands[0], operands[1]); 3375 count -= (count & 16) * 2; 3376 break; 3377 case 3: 3378 emit_insn (gen_rotlsi3_16 (operands[0], operands[1])); 3379 count -= 16; 3380 break; 3381 case 1: 3382 case 2: 3383 { 3384 rtx parts[2]; 3385 parts[0] = gen_reg_rtx (SImode); 3386 parts[1] = gen_reg_rtx (SImode); 3387 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1])); 3388 emit_move_insn (parts[choice-1], operands[1]); 3389 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8))); 3390 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8))); 3391 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1])); 3392 count = (count & ~16) - 8; 3393 } 3394 } 3395 3396 for (; count > 0; count--) 3397 emit_insn (gen_rotlsi3_1 (operands[0], operands[0])); 3398 for (; count < 0; count++) 3399 emit_insn (gen_rotlsi3_31 (operands[0], operands[0])); 3400 3401 DONE; 3402}") 3403 3404(define_insn "*rotlhi3_8" 3405 [(set (match_operand:HI 0 "arith_reg_dest" "=r") 3406 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r") 3407 (const_int 8)))] 3408 "TARGET_SH1" 3409 "swap.b %1,%0" 3410 [(set_attr "type" "arith")]) 3411 3412(define_expand "rotlhi3" 3413 [(set (match_operand:HI 0 "arith_reg_operand" "") 3414 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "") 3415 (match_operand:HI 2 "immediate_operand" "")))] 3416 "TARGET_SH1" 3417 " 3418{ 3419 if (!CONST_INT_P (operands[2]) || INTVAL (operands[2]) != 8) 3420 FAIL; 3421}") 3422 3423;; 3424;; shift left 3425 3426(define_insn "ashlsi3_sh2a" 3427 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 3428 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") 3429 (match_operand:SI 2 "arith_reg_operand" "r")))] 3430 "TARGET_SH2A" 3431 "shad %2,%0" 3432 [(set_attr "type" "arith") 3433 (set_attr "length" "4")]) 3434 3435;; This pattern is used by init_expmed for computing the costs of shift 3436;; insns. 3437 3438(define_insn_and_split "ashlsi3_std" 3439 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r") 3440 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0") 3441 (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri"))) 3442 (clobber (match_scratch:SI 3 "=X,X,X,&r"))] 3443 "TARGET_SH3 3444 || (TARGET_SH1 && satisfies_constraint_P27 (operands[2]))" 3445 "@ 3446 shld %2,%0 3447 add %0,%0 3448 shll%O2 %0 3449 #" 3450 "TARGET_SH3 3451 && reload_completed 3452 && CONST_INT_P (operands[2]) 3453 && ! satisfies_constraint_P27 (operands[2])" 3454 [(set (match_dup 3) (match_dup 2)) 3455 (parallel 3456 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3))) 3457 (clobber (match_dup 4))])] 3458 "operands[4] = gen_rtx_SCRATCH (SImode);" 3459 [(set_attr "length" "*,*,*,4") 3460 (set_attr "type" "dyn_shift,arith,arith,arith")]) 3461 3462(define_insn "ashlhi3_k" 3463 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r") 3464 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0") 3465 (match_operand:HI 2 "const_int_operand" "M,P27")))] 3466 "TARGET_SH1 && satisfies_constraint_P27 (operands[2])" 3467 "@ 3468 add %0,%0 3469 shll%O2 %0" 3470 [(set_attr "type" "arith")]) 3471 3472(define_insn "ashlsi3_n" 3473 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 3474 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") 3475 (match_operand:SI 2 "const_int_operand" "n"))) 3476 (clobber (reg:SI T_REG))] 3477 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])" 3478 "#" 3479 [(set (attr "length") 3480 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1)) 3481 (const_string "2") 3482 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2)) 3483 (const_string "4") 3484 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3)) 3485 (const_string "6")] 3486 (const_string "8"))) 3487 (set_attr "type" "arith")]) 3488 3489(define_split 3490 [(set (match_operand:SI 0 "arith_reg_dest" "") 3491 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "") 3492 (match_operand:SI 2 "const_int_operand" ""))) 3493 (clobber (reg:SI T_REG))] 3494 "TARGET_SH1 && reload_completed" 3495 [(use (reg:SI R0_REG))] 3496 " 3497{ 3498 gen_shifty_op (ASHIFT, operands); 3499 DONE; 3500}") 3501 3502(define_insn "ashlsi3_media" 3503 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r") 3504 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r") 3505 (match_operand:SI 2 "shift_count_operand" "r,n")))] 3506 "TARGET_SHMEDIA" 3507 "@ 3508 shlld.l %1, %2, %0 3509 shlli.l %1, %2, %0" 3510 [(set_attr "type" "arith_media") 3511 (set_attr "highpart" "ignore")]) 3512 3513(define_expand "ashlsi3" 3514 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "") 3515 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "") 3516 (match_operand:SI 2 "nonmemory_operand" ""))) 3517 (clobber (reg:SI T_REG))])] 3518 "" 3519 " 3520{ 3521 if (TARGET_SHMEDIA) 3522 { 3523 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2])); 3524 DONE; 3525 } 3526 if (CONST_INT_P (operands[2]) 3527 && sh_dynamicalize_shift_p (operands[2])) 3528 operands[2] = force_reg (SImode, operands[2]); 3529 if (TARGET_SH3) 3530 { 3531 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2])); 3532 DONE; 3533 } 3534 if (! immediate_operand (operands[2], GET_MODE (operands[2]))) 3535 FAIL; 3536}") 3537 3538(define_insn "*ashlhi3_n" 3539 [(set (match_operand:HI 0 "arith_reg_dest" "=r") 3540 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0") 3541 (match_operand:HI 2 "const_int_operand" "n"))) 3542 (clobber (reg:SI T_REG))] 3543 "TARGET_SH1" 3544 "#" 3545 [(set (attr "length") 3546 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1)) 3547 (const_string "2") 3548 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2)) 3549 (const_string "4")] 3550 (const_string "6"))) 3551 (set_attr "type" "arith")]) 3552 3553(define_expand "ashlhi3" 3554 [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "") 3555 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "") 3556 (match_operand:SI 2 "nonmemory_operand" ""))) 3557 (clobber (reg:SI T_REG))])] 3558 "TARGET_SH1" 3559 " 3560{ 3561 if (!CONST_INT_P (operands[2])) 3562 FAIL; 3563 /* It may be possible to call gen_ashlhi3 directly with more generic 3564 operands. Make sure operands[1] is a HImode register here. */ 3565 if (!arith_reg_operand (operands[1], HImode)) 3566 operands[1] = copy_to_mode_reg (HImode, operands[1]); 3567}") 3568 3569(define_split 3570 [(set (match_operand:HI 0 "arith_reg_dest" "") 3571 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "") 3572 (match_operand:HI 2 "const_int_operand" ""))) 3573 (clobber (reg:SI T_REG))] 3574 "TARGET_SH1 && reload_completed" 3575 [(use (reg:SI R0_REG))] 3576 " 3577{ 3578 gen_shifty_hi_op (ASHIFT, operands); 3579 DONE; 3580}") 3581 3582; 3583; arithmetic shift right 3584; 3585 3586(define_insn "ashrsi3_sh2a" 3587 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 3588 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0") 3589 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))] 3590 "TARGET_SH2A" 3591 "shad %2,%0" 3592 [(set_attr "type" "dyn_shift") 3593 (set_attr "length" "4")]) 3594 3595(define_insn "ashrsi3_k" 3596 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 3597 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0") 3598 (match_operand:SI 2 "const_int_operand" "M"))) 3599 (clobber (reg:SI T_REG))] 3600 "TARGET_SH1 && INTVAL (operands[2]) == 1" 3601 "shar %0" 3602 [(set_attr "type" "arith")]) 3603 3604;; We can't do HImode right shifts correctly unless we start out with an 3605;; explicit zero / sign extension; doing that would result in worse overall 3606;; code, so just let the machine independent code widen the mode. 3607;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 . 3608 3609 3610;; ??? This should be a define expand. 3611 3612(define_insn "ashrsi2_16" 3613 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 3614 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r") 3615 (const_int 16)))] 3616 "TARGET_SH1" 3617 "#" 3618 [(set_attr "length" "4")]) 3619 3620(define_split 3621 [(set (match_operand:SI 0 "arith_reg_dest" "") 3622 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "") 3623 (const_int 16)))] 3624 "TARGET_SH1" 3625 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16))) 3626 (set (match_dup 0) (sign_extend:SI (match_dup 2)))] 3627 "operands[2] = gen_lowpart (HImode, operands[0]);") 3628 3629;; ??? This should be a define expand. 3630 3631(define_insn "ashrsi2_31" 3632 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 3633 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0") 3634 (const_int 31))) 3635 (clobber (reg:SI T_REG))] 3636 "TARGET_SH1" 3637 "#" 3638 [(set_attr "length" "4")]) 3639 3640(define_split 3641 [(set (match_operand:SI 0 "arith_reg_dest" "") 3642 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "") 3643 (const_int 31))) 3644 (clobber (reg:SI T_REG))] 3645 "TARGET_SH1" 3646 [(const_int 0)] 3647 " 3648{ 3649 emit_insn (gen_ashlsi_c (operands[0], operands[1])); 3650 emit_insn (gen_mov_neg_si_t (copy_rtx (operands[0]))); 3651 DONE; 3652}") 3653 3654(define_peephole2 3655 [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0)) 3656 (set (reg:SI T_REG) 3657 (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))] 3658 "TARGET_SH1 3659 && peep2_reg_dead_p (2, operands[0]) 3660 && peep2_reg_dead_p (2, operands[1])" 3661 [(const_int 0)] 3662 " 3663{ 3664 emit_insn (gen_ashlsi_c (operands[1], operands[1])); 3665 DONE; 3666}") 3667 3668(define_insn "ashlsi_c" 3669 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 3670 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1))) 3671 (set (reg:SI T_REG) 3672 (lt:SI (match_dup 1) (const_int 0)))] 3673 "TARGET_SH1" 3674 "shll %0" 3675 [(set_attr "type" "arith")]) 3676 3677(define_insn "*ashlsi_c_void" 3678 [(set (reg:SI T_REG) 3679 (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0))) 3680 (clobber (match_scratch:SI 1 "=0"))] 3681 "TARGET_SH1 && cse_not_expected" 3682 "shll %0" 3683 [(set_attr "type" "arith")]) 3684 3685(define_insn "ashrsi3_d" 3686 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 3687 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0") 3688 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))] 3689 "TARGET_SH3" 3690 "shad %2,%0" 3691 [(set_attr "type" "dyn_shift")]) 3692 3693(define_insn "ashrsi3_n" 3694 [(set (reg:SI R4_REG) 3695 (ashiftrt:SI (reg:SI R4_REG) 3696 (match_operand:SI 0 "const_int_operand" "i"))) 3697 (clobber (reg:SI T_REG)) 3698 (clobber (reg:SI PR_REG)) 3699 (use (match_operand:SI 1 "arith_reg_operand" "r"))] 3700 "TARGET_SH1" 3701 "jsr @%1%#" 3702 [(set_attr "type" "sfunc") 3703 (set_attr "needs_delay_slot" "yes")]) 3704 3705(define_insn "ashrsi3_media" 3706 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r") 3707 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r") 3708 (match_operand:SI 2 "shift_count_operand" "r,n")))] 3709 "TARGET_SHMEDIA" 3710 "@ 3711 shard.l %1, %2, %0 3712 shari.l %1, %2, %0" 3713 [(set_attr "type" "arith_media") 3714 (set_attr "highpart" "ignore")]) 3715 3716(define_expand "ashrsi3" 3717 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "") 3718 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "") 3719 (match_operand:SI 2 "nonmemory_operand" ""))) 3720 (clobber (reg:SI T_REG))])] 3721 "" 3722 " 3723{ 3724 if (TARGET_SHMEDIA) 3725 { 3726 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2])); 3727 DONE; 3728 } 3729 if (expand_ashiftrt (operands)) 3730 DONE; 3731 else 3732 FAIL; 3733}") 3734 3735;; logical shift right 3736 3737(define_insn "lshrsi3_sh2a" 3738 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 3739 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0") 3740 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))] 3741 "TARGET_SH2A" 3742 "shld %2,%0" 3743 [(set_attr "type" "dyn_shift") 3744 (set_attr "length" "4")]) 3745 3746(define_insn "lshrsi3_d" 3747 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 3748 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0") 3749 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))] 3750 "TARGET_SH3" 3751 "shld %2,%0" 3752 [(set_attr "type" "dyn_shift")]) 3753 3754;; Only the single bit shift clobbers the T bit. 3755 3756(define_insn "lshrsi3_m" 3757 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 3758 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0") 3759 (match_operand:SI 2 "const_int_operand" "M"))) 3760 (clobber (reg:SI T_REG))] 3761 "TARGET_SH1 && satisfies_constraint_M (operands[2])" 3762 "shlr %0" 3763 [(set_attr "type" "arith")]) 3764 3765(define_insn "lshrsi3_k" 3766 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 3767 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0") 3768 (match_operand:SI 2 "const_int_operand" "P27")))] 3769 "TARGET_SH1 && satisfies_constraint_P27 (operands[2]) 3770 && ! satisfies_constraint_M (operands[2])" 3771 "shlr%O2 %0" 3772 [(set_attr "type" "arith")]) 3773 3774(define_insn "lshrsi3_n" 3775 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 3776 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0") 3777 (match_operand:SI 2 "const_int_operand" "n"))) 3778 (clobber (reg:SI T_REG))] 3779 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])" 3780 "#" 3781 [(set (attr "length") 3782 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1)) 3783 (const_string "2") 3784 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2)) 3785 (const_string "4") 3786 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3)) 3787 (const_string "6")] 3788 (const_string "8"))) 3789 (set_attr "type" "arith")]) 3790 3791(define_split 3792 [(set (match_operand:SI 0 "arith_reg_dest" "") 3793 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "") 3794 (match_operand:SI 2 "const_int_operand" ""))) 3795 (clobber (reg:SI T_REG))] 3796 "TARGET_SH1 && reload_completed" 3797 [(use (reg:SI R0_REG))] 3798 " 3799{ 3800 gen_shifty_op (LSHIFTRT, operands); 3801 DONE; 3802}") 3803 3804(define_insn "lshrsi3_media" 3805 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r") 3806 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r") 3807 (match_operand:SI 2 "shift_count_operand" "r,n")))] 3808 "TARGET_SHMEDIA" 3809 "@ 3810 shlrd.l %1, %2, %0 3811 shlri.l %1, %2, %0" 3812 [(set_attr "type" "arith_media") 3813 (set_attr "highpart" "ignore")]) 3814 3815(define_expand "lshrsi3" 3816 [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "") 3817 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "") 3818 (match_operand:SI 2 "nonmemory_operand" ""))) 3819 (clobber (reg:SI T_REG))])] 3820 "" 3821 " 3822{ 3823 if (TARGET_SHMEDIA) 3824 { 3825 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2])); 3826 DONE; 3827 } 3828 if (CONST_INT_P (operands[2]) 3829 && sh_dynamicalize_shift_p (operands[2])) 3830 operands[2] = force_reg (SImode, operands[2]); 3831 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2]))) 3832 { 3833 rtx count = copy_to_mode_reg (SImode, operands[2]); 3834 emit_insn (gen_negsi2 (count, count)); 3835 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count)); 3836 DONE; 3837 } 3838 if (! immediate_operand (operands[2], GET_MODE (operands[2]))) 3839 FAIL; 3840}") 3841 3842;; ??? This should be a define expand. 3843 3844(define_insn "ashldi3_k" 3845 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 3846 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0") 3847 (const_int 1))) 3848 (clobber (reg:SI T_REG))] 3849 "TARGET_SH1" 3850 "shll %R0\;rotcl %S0" 3851 [(set_attr "length" "4") 3852 (set_attr "type" "arith")]) 3853 3854;; Expander for DImode shift left with SImode operations. 3855 3856(define_expand "ashldi3_std" 3857 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 3858 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r") 3859 (match_operand:DI 2 "const_int_operand" "n")))] 3860 "TARGET_SH1 && INTVAL (operands[2]) < 32" 3861 " 3862{ 3863 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1); 3864 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0); 3865 rtx low_src = operand_subword (operands[1], low_word, 0, DImode); 3866 rtx high_src = operand_subword (operands[1], high_word, 0, DImode); 3867 rtx dst = gen_reg_rtx (DImode); 3868 rtx low_dst = operand_subword (dst, low_word, 1, DImode); 3869 rtx high_dst = operand_subword (dst, high_word, 1, DImode); 3870 rtx tmp0, tmp1; 3871 3872 tmp0 = gen_reg_rtx (SImode); 3873 tmp1 = gen_reg_rtx (SImode); 3874 emit_insn (gen_lshrsi3 (tmp0, low_src, GEN_INT (32 - INTVAL (operands[2])))); 3875 emit_insn (gen_ashlsi3 (low_dst, low_src, operands[2])); 3876 emit_insn (gen_ashlsi3 (tmp1, high_src, operands[2])); 3877 emit_insn (gen_iorsi3 (high_dst, tmp0, tmp1)); 3878 emit_move_insn (operands[0], dst); 3879 DONE; 3880}") 3881 3882(define_insn "ashldi3_media" 3883 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r") 3884 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r") 3885 (match_operand:DI 2 "shift_count_operand" "r,n")))] 3886 "TARGET_SHMEDIA" 3887 "@ 3888 shlld %1, %2, %0 3889 shlli %1, %2, %0" 3890 [(set_attr "type" "arith_media")]) 3891 3892(define_insn "*ashldisi3_media" 3893 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0) 3894 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r") 3895 (match_operand:DI 2 "const_int_operand" "n")))] 3896 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32" 3897 "shlli.l %1, %2, %0" 3898 [(set_attr "type" "arith_media") 3899 (set_attr "highpart" "ignore")]) 3900 3901(define_expand "ashldi3" 3902 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "") 3903 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "") 3904 (match_operand:DI 2 "immediate_operand" ""))) 3905 (clobber (reg:SI T_REG))])] 3906 "" 3907 " 3908{ 3909 if (TARGET_SHMEDIA) 3910 { 3911 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2])); 3912 DONE; 3913 } 3914 if (CONST_INT_P (operands[2]) 3915 && INTVAL (operands[2]) == 1) 3916 { 3917 emit_insn (gen_ashldi3_k (operands[0], operands[1])); 3918 DONE; 3919 } 3920 else if (CONST_INT_P (operands[2]) 3921 && INTVAL (operands[2]) < 32) 3922 { 3923 emit_insn (gen_ashldi3_std (operands[0], operands[1], operands[2])); 3924 DONE; 3925 } 3926 else 3927 FAIL; 3928}") 3929 3930;; ??? This should be a define expand. 3931 3932(define_insn "lshrdi3_k" 3933 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 3934 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0") 3935 (const_int 1))) 3936 (clobber (reg:SI T_REG))] 3937 "TARGET_SH1" 3938 "shlr %S0\;rotcr %R0" 3939 [(set_attr "length" "4") 3940 (set_attr "type" "arith")]) 3941 3942(define_insn "lshrdi3_media" 3943 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r") 3944 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r") 3945 (match_operand:DI 2 "shift_count_operand" "r,n")))] 3946 "TARGET_SHMEDIA 3947 && (arith_reg_dest (operands[0], DImode) 3948 || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) > 32))" 3949 "@ 3950 shlrd %1, %2, %0 3951 shlri %1, %2, %0" 3952 [(set_attr "type" "arith_media")]) 3953 3954(define_insn "*lshrdisi3_media" 3955 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0) 3956 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r") 3957 (match_operand:DI 2 "const_int_operand" "n")))] 3958 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32" 3959 "shlri.l %1, %2, %0" 3960 [(set_attr "type" "arith_media") 3961 (set_attr "highpart" "ignore")]) 3962 3963(define_expand "lshrdi3" 3964 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "") 3965 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "") 3966 (match_operand:DI 2 "immediate_operand" ""))) 3967 (clobber (reg:SI T_REG))])] 3968 "" 3969 " 3970{ 3971 if (TARGET_SHMEDIA) 3972 { 3973 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2])); 3974 DONE; 3975 } 3976 if (!CONST_INT_P (operands[2]) 3977 || INTVAL (operands[2]) != 1) 3978 FAIL; 3979}") 3980 3981;; ??? This should be a define expand. 3982 3983(define_insn "ashrdi3_k" 3984 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 3985 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0") 3986 (const_int 1))) 3987 (clobber (reg:SI T_REG))] 3988 "TARGET_SH1" 3989 "shar %S0\;rotcr %R0" 3990 [(set_attr "length" "4") 3991 (set_attr "type" "arith")]) 3992 3993(define_insn "ashrdi3_media" 3994 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r") 3995 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r") 3996 (match_operand:DI 2 "shift_count_operand" "r,n")))] 3997 "TARGET_SHMEDIA 3998 && (arith_reg_dest (operands[0], DImode) 3999 || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) >= 32))" 4000 "@ 4001 shard %1, %2, %0 4002 shari %1, %2, %0" 4003 [(set_attr "type" "arith_media")]) 4004 4005(define_insn "*ashrdisi3_media" 4006 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0) 4007 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r") 4008 (match_operand:DI 2 "const_int_operand" "n")))] 4009 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32" 4010 "shari.l %1, %2, %0" 4011 [(set_attr "type" "arith_media") 4012 (set_attr "highpart" "ignore")]) 4013 4014(define_insn "ashrdisi3_media_high" 4015 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 4016 (truncate:SI 4017 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r") 4018 (match_operand:DI 2 "const_int_operand" "n"))))] 4019 "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32" 4020 "shari %1, %2, %0" 4021 [(set_attr "type" "arith_media")]) 4022 4023(define_insn "ashrdisi3_media_opaque" 4024 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 4025 (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r") 4026 (match_operand:DI 2 "const_int_operand" "n")] 4027 UNSPEC_ASHIFTRT))] 4028 "TARGET_SHMEDIA" 4029 "shari %1, %2, %0" 4030 [(set_attr "type" "arith_media")]) 4031 4032(define_expand "ashrdi3" 4033 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "") 4034 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "") 4035 (match_operand:DI 2 "immediate_operand" ""))) 4036 (clobber (reg:SI T_REG))])] 4037 "" 4038 " 4039{ 4040 if (TARGET_SHMEDIA) 4041 { 4042 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2])); 4043 DONE; 4044 } 4045 if (!CONST_INT_P (operands[2]) 4046 || INTVAL (operands[2]) != 1) 4047 FAIL; 4048}") 4049 4050;; combined left/right shift 4051 4052(define_split 4053 [(set (match_operand:SI 0 "register_operand" "") 4054 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "") 4055 (match_operand:SI 2 "const_int_operand" "")) 4056 (match_operand:SI 3 "const_int_operand" "")))] 4057 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32" 4058 [(use (reg:SI R0_REG))] 4059 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL; 4060 DONE;") 4061 4062(define_split 4063 [(set (match_operand:SI 0 "register_operand" "") 4064 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "") 4065 (match_operand:SI 2 "const_int_operand" "")) 4066 (match_operand:SI 3 "const_int_operand" ""))) 4067 (clobber (reg:SI T_REG))] 4068 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32" 4069 [(use (reg:SI R0_REG))] 4070 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL; 4071 DONE;") 4072 4073(define_insn "" 4074 [(set (match_operand:SI 0 "register_operand" "=r") 4075 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0") 4076 (match_operand:SI 2 "const_int_operand" "n")) 4077 (match_operand:SI 3 "const_int_operand" "n"))) 4078 (clobber (reg:SI T_REG))] 4079 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1" 4080 "#" 4081 [(set (attr "length") 4082 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2)) 4083 (const_string "4") 4084 (eq (symbol_ref "shl_and_length (insn)") (const_int 3)) 4085 (const_string "6") 4086 (eq (symbol_ref "shl_and_length (insn)") (const_int 4)) 4087 (const_string "8") 4088 (eq (symbol_ref "shl_and_length (insn)") (const_int 5)) 4089 (const_string "10") 4090 (eq (symbol_ref "shl_and_length (insn)") (const_int 6)) 4091 (const_string "12") 4092 (eq (symbol_ref "shl_and_length (insn)") (const_int 7)) 4093 (const_string "14") 4094 (eq (symbol_ref "shl_and_length (insn)") (const_int 8)) 4095 (const_string "16")] 4096 (const_string "18"))) 4097 (set_attr "type" "arith")]) 4098 4099(define_insn "" 4100 [(set (match_operand:SI 0 "register_operand" "=z") 4101 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0") 4102 (match_operand:SI 2 "const_int_operand" "n")) 4103 (match_operand:SI 3 "const_int_operand" "n"))) 4104 (clobber (reg:SI T_REG))] 4105 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2" 4106 "#" 4107 [(set (attr "length") 4108 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2)) 4109 (const_string "4") 4110 (eq (symbol_ref "shl_and_length (insn)") (const_int 3)) 4111 (const_string "6") 4112 (eq (symbol_ref "shl_and_length (insn)") (const_int 4)) 4113 (const_string "8")] 4114 (const_string "10"))) 4115 (set_attr "type" "arith")]) 4116 4117;; shift left / and combination with a scratch register: The combine pass 4118;; does not accept the individual instructions, even though they are 4119;; cheap. But it needs a precise description so that it is usable after 4120;; reload. 4121(define_insn "and_shl_scratch" 4122 [(set (match_operand:SI 0 "register_operand" "=r,&r") 4123 (lshiftrt:SI 4124 (ashift:SI 4125 (and:SI 4126 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0") 4127 (match_operand:SI 2 "const_int_operand" "N,n")) 4128 (match_operand:SI 3 "" "0,r")) 4129 (match_operand:SI 4 "const_int_operand" "n,n")) 4130 (match_operand:SI 5 "const_int_operand" "n,n"))) 4131 (clobber (reg:SI T_REG))] 4132 "TARGET_SH1" 4133 "#" 4134 [(set (attr "length") 4135 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2)) 4136 (const_string "4") 4137 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3)) 4138 (const_string "6") 4139 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4)) 4140 (const_string "8") 4141 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5)) 4142 (const_string "10")] 4143 (const_string "12"))) 4144 (set_attr "type" "arith")]) 4145 4146(define_split 4147 [(set (match_operand:SI 0 "register_operand" "") 4148 (lshiftrt:SI 4149 (ashift:SI 4150 (and:SI 4151 (lshiftrt:SI (match_operand:SI 1 "register_operand" "") 4152 (match_operand:SI 2 "const_int_operand" "")) 4153 (match_operand:SI 3 "register_operand" "")) 4154 (match_operand:SI 4 "const_int_operand" "")) 4155 (match_operand:SI 5 "const_int_operand" ""))) 4156 (clobber (reg:SI T_REG))] 4157 "TARGET_SH1" 4158 [(use (reg:SI R0_REG))] 4159 " 4160{ 4161 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1]; 4162 4163 if (INTVAL (operands[2])) 4164 { 4165 gen_shifty_op (LSHIFTRT, operands); 4166 } 4167 emit_insn (gen_andsi3 (operands[0], operands[0], and_source)); 4168 operands[2] = operands[4]; 4169 gen_shifty_op (ASHIFT, operands); 4170 if (INTVAL (operands[5])) 4171 { 4172 operands[2] = operands[5]; 4173 gen_shifty_op (LSHIFTRT, operands); 4174 } 4175 DONE; 4176}") 4177 4178;; signed left/right shift combination. 4179(define_split 4180 [(set (match_operand:SI 0 "register_operand" "") 4181 (sign_extract:SI 4182 (ashift:SI (match_operand:SI 1 "register_operand" "") 4183 (match_operand:SI 2 "const_int_operand" "")) 4184 (match_operand:SI 3 "const_int_operand" "") 4185 (const_int 0))) 4186 (clobber (reg:SI T_REG))] 4187 "TARGET_SH1" 4188 [(use (reg:SI R0_REG))] 4189 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL; 4190 DONE;") 4191 4192(define_insn "shl_sext_ext" 4193 [(set (match_operand:SI 0 "register_operand" "=r") 4194 (sign_extract:SI 4195 (ashift:SI (match_operand:SI 1 "register_operand" "0") 4196 (match_operand:SI 2 "const_int_operand" "n")) 4197 (match_operand:SI 3 "const_int_operand" "n") 4198 (const_int 0))) 4199 (clobber (reg:SI T_REG))] 4200 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5" 4201 "#" 4202 [(set (attr "length") 4203 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1)) 4204 (const_string "2") 4205 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2)) 4206 (const_string "4") 4207 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3)) 4208 (const_string "6") 4209 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4)) 4210 (const_string "8") 4211 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5)) 4212 (const_string "10") 4213 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6)) 4214 (const_string "12") 4215 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7)) 4216 (const_string "14") 4217 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8)) 4218 (const_string "16")] 4219 (const_string "18"))) 4220 (set_attr "type" "arith")]) 4221 4222(define_insn "shl_sext_sub" 4223 [(set (match_operand:SI 0 "register_operand" "=z") 4224 (sign_extract:SI 4225 (ashift:SI (match_operand:SI 1 "register_operand" "0") 4226 (match_operand:SI 2 "const_int_operand" "n")) 4227 (match_operand:SI 3 "const_int_operand" "n") 4228 (const_int 0))) 4229 (clobber (reg:SI T_REG))] 4230 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6" 4231 "#" 4232 [(set (attr "length") 4233 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3)) 4234 (const_string "6") 4235 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4)) 4236 (const_string "8") 4237 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5)) 4238 (const_string "10") 4239 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6)) 4240 (const_string "12")] 4241 (const_string "14"))) 4242 (set_attr "type" "arith")]) 4243 4244;; These patterns are found in expansions of DImode shifts by 16, and 4245;; allow the xtrct instruction to be generated from C source. 4246 4247(define_insn "xtrct_left" 4248 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 4249 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r") 4250 (const_int 16)) 4251 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0") 4252 (const_int 16))))] 4253 "TARGET_SH1" 4254 "xtrct %1,%0" 4255 [(set_attr "type" "arith")]) 4256 4257(define_insn "xtrct_right" 4258 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 4259 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0") 4260 (const_int 16)) 4261 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r") 4262 (const_int 16))))] 4263 "TARGET_SH1" 4264 "xtrct %2,%0" 4265 [(set_attr "type" "arith")]) 4266 4267;; ------------------------------------------------------------------------- 4268;; Unary arithmetic 4269;; ------------------------------------------------------------------------- 4270 4271(define_insn "negc" 4272 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 4273 (neg:SI (plus:SI (reg:SI T_REG) 4274 (match_operand:SI 1 "arith_reg_operand" "r")))) 4275 (set (reg:SI T_REG) 4276 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1)) 4277 (const_int 0)))] 4278 "TARGET_SH1" 4279 "negc %1,%0" 4280 [(set_attr "type" "arith")]) 4281 4282(define_insn "*negdi_media" 4283 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 4284 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))] 4285 "TARGET_SHMEDIA" 4286 "sub r63, %1, %0" 4287 [(set_attr "type" "arith_media")]) 4288 4289(define_expand "negdi2" 4290 [(set (match_operand:DI 0 "arith_reg_operand" "") 4291 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))] 4292 "" 4293 " 4294{ 4295 if (TARGET_SH1) 4296 { 4297 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1); 4298 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0); 4299 4300 rtx low_src = operand_subword (operands[1], low_word, 0, DImode); 4301 rtx high_src = operand_subword (operands[1], high_word, 0, DImode); 4302 4303 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode); 4304 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode); 4305 4306 emit_insn (gen_clrt ()); 4307 emit_insn (gen_negc (low_dst, low_src)); 4308 emit_insn (gen_negc (high_dst, high_src)); 4309 DONE; 4310 } 4311}") 4312 4313(define_insn "negsi2" 4314 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 4315 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))] 4316 "TARGET_SH1" 4317 "neg %1,%0" 4318 [(set_attr "type" "arith")]) 4319 4320(define_insn "one_cmplsi2" 4321 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 4322 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))] 4323 "TARGET_SH1" 4324 "not %1,%0" 4325 [(set_attr "type" "arith")]) 4326 4327(define_expand "one_cmpldi2" 4328 [(set (match_operand:DI 0 "arith_reg_dest" "") 4329 (xor:DI (match_operand:DI 1 "arith_reg_operand" "") 4330 (const_int -1)))] 4331 "TARGET_SHMEDIA" "") 4332 4333/* The SH4 202 can do zero-offset branches without pipeline stalls. 4334 This can be used as some kind of conditional execution, which is useful 4335 for abs. */ 4336(define_split 4337 [(set (match_operand:SI 0 "arith_reg_dest" "") 4338 (plus:SI (xor:SI (neg:SI (reg:SI T_REG)) 4339 (match_operand:SI 1 "arith_reg_operand" "")) 4340 (reg:SI T_REG)))] 4341 "TARGET_HARD_SH4" 4342 [(const_int 0)] 4343 "emit_insn (gen_movsi_i (operands[0], operands[1])); 4344 emit_insn (gen_cneg (operands[0], operands[0], operands[0])); 4345 DONE;") 4346 4347(define_insn "cneg" 4348 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 4349 (if_then_else:SI (eq:SI (reg:SI T_REG) (const_int 0)) 4350 (match_operand:SI 1 "arith_reg_operand" "0") 4351 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))] 4352 "TARGET_HARD_SH4" 4353 "bf 0f\;neg %2,%0\\n0:" 4354 [(set_attr "type" "arith") ;; poor approximation 4355 (set_attr "length" "4")]) 4356 4357 4358;; ------------------------------------------------------------------------- 4359;; Zero extension instructions 4360;; ------------------------------------------------------------------------- 4361 4362(define_insn "zero_extendsidi2" 4363 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 4364 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))] 4365 "TARGET_SHMEDIA" 4366 "addz.l %1, r63, %0" 4367 [(set_attr "type" "arith_media") 4368 (set_attr "highpart" "extend")]) 4369 4370(define_insn "zero_extendhidi2" 4371 [(set (match_operand:DI 0 "register_operand" "=r,r") 4372 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))] 4373 "TARGET_SHMEDIA" 4374 "@ 4375 # 4376 ld%M1.uw %m1, %0" 4377 [(set_attr "type" "*,load_media") 4378 (set (attr "highpart") 4379 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0)) 4380 (const_string "user")] 4381 (const_string "ignore")))]) 4382 4383(define_split 4384 [(set (match_operand:DI 0 "register_operand" "") 4385 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))] 4386 "TARGET_SHMEDIA && reload_completed" 4387 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48))) 4388 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))] 4389 " 4390{ 4391 if (GET_CODE (operands[1]) == TRUNCATE) 4392 operands[1] = XEXP (operands[1], 0); 4393}") 4394 4395;; ??? when a truncated input to a zero_extend is reloaded, reload will 4396;; reload the entire truncate expression. 4397(define_insn_and_split "*loaddi_trunc" 4398 [(set (match_operand 0 "any_register_operand" "=r") 4399 (truncate (match_operand:DI 1 "memory_operand" "m")))] 4400 "TARGET_SHMEDIA && reload_completed" 4401 "#" 4402 "TARGET_SHMEDIA && reload_completed" 4403 [(set (match_dup 0) (match_dup 1))] 4404 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));") 4405 4406(define_insn "zero_extendqidi2" 4407 [(set (match_operand:DI 0 "register_operand" "=r,r") 4408 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))] 4409 "TARGET_SHMEDIA" 4410 "@ 4411 andi %1, 255, %0 4412 ld%M1.ub %m1, %0" 4413 [(set_attr "type" "arith_media,load_media") 4414 (set (attr "highpart") 4415 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0)) 4416 (const_string "user")] 4417 (const_string "ignore")))]) 4418 4419(define_expand "zero_extendhisi2" 4420 [(set (match_operand:SI 0 "arith_reg_operand" "") 4421 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))] 4422 "" 4423 " 4424{ 4425 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode)) 4426 operands[1] = copy_to_mode_reg (HImode, operands[1]); 4427}") 4428 4429(define_insn "*zero_extendhisi2_compact" 4430 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 4431 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))] 4432 "TARGET_SH1" 4433 "extu.w %1,%0" 4434 [(set_attr "type" "arith")]) 4435 4436(define_insn "*zero_extendhisi2_media" 4437 [(set (match_operand:SI 0 "register_operand" "=r,r") 4438 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))] 4439 "TARGET_SHMEDIA" 4440 "@ 4441 # 4442 ld%M1.uw %m1, %0" 4443 [(set_attr "type" "arith_media,load_media") 4444 (set (attr "highpart") 4445 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0)) 4446 (const_string "user")] 4447 (const_string "ignore")))]) 4448 4449(define_split 4450 [(set (match_operand:SI 0 "register_operand" "") 4451 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))] 4452 "TARGET_SHMEDIA && reload_completed" 4453 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16))) 4454 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))] 4455 " 4456{ 4457 rtx op1 = operands[1]; 4458 4459 if (GET_CODE (op1) == TRUNCATE) 4460 op1 = XEXP (op1, 0); 4461 operands[2] 4462 = simplify_gen_subreg (SImode, op1, GET_MODE (op1), 4463 subreg_lowpart_offset (SImode, GET_MODE (op1))); 4464}") 4465 4466(define_expand "zero_extendqisi2" 4467 [(set (match_operand:SI 0 "arith_reg_operand" "") 4468 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))] 4469 "" 4470 " 4471{ 4472 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode)) 4473 operands[1] = copy_to_mode_reg (QImode, operands[1]); 4474}") 4475 4476(define_insn "*zero_extendqisi2_compact" 4477 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 4478 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))] 4479 "TARGET_SH1" 4480 "extu.b %1,%0" 4481 [(set_attr "type" "arith")]) 4482 4483(define_insn "*zero_extendqisi2_media" 4484 [(set (match_operand:SI 0 "register_operand" "=r,r") 4485 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))] 4486 "TARGET_SHMEDIA" 4487 "@ 4488 andi %1, 255, %0 4489 ld%M1.ub %m1, %0" 4490 [(set_attr "type" "arith_media,load_media") 4491 (set (attr "highpart") 4492 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0)) 4493 (const_string "user")] 4494 (const_string "ignore")))]) 4495 4496(define_insn "zero_extendqihi2" 4497 [(set (match_operand:HI 0 "arith_reg_dest" "=r") 4498 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))] 4499 "TARGET_SH1" 4500 "extu.b %1,%0" 4501 [(set_attr "type" "arith")]) 4502 4503;; ------------------------------------------------------------------------- 4504;; Sign extension instructions 4505;; ------------------------------------------------------------------------- 4506 4507;; ??? This should be a define expand. 4508;; ??? Or perhaps it should be dropped? 4509 4510;; convert_move generates good code for SH[1-4]. 4511(define_insn "extendsidi2" 4512 [(set (match_operand:DI 0 "register_operand" "=r,r,r") 4513 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))] 4514 "TARGET_SHMEDIA" 4515 "@ 4516 add.l %1, r63, %0 4517 ld%M1.l %m1, %0 4518 fmov.sl %1, %0" 4519 [(set_attr "type" "arith_media,load_media,fpconv_media") 4520 (set (attr "highpart") 4521 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0)) 4522 (const_string "user")] 4523 (const_string "extend")))]) 4524 4525(define_insn "extendhidi2" 4526 [(set (match_operand:DI 0 "register_operand" "=r,r") 4527 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))] 4528 "TARGET_SHMEDIA" 4529 "@ 4530 # 4531 ld%M1.w %m1, %0" 4532 [(set_attr "type" "*,load_media") 4533 (set (attr "highpart") 4534 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0)) 4535 (const_string "user")] 4536 (const_string "ignore")))]) 4537 4538(define_split 4539 [(set (match_operand:DI 0 "register_operand" "") 4540 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))] 4541 "TARGET_SHMEDIA && reload_completed" 4542 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48))) 4543 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))] 4544 " 4545{ 4546 if (GET_CODE (operands[1]) == TRUNCATE) 4547 operands[1] = XEXP (operands[1], 0); 4548}") 4549 4550(define_insn "extendqidi2" 4551 [(set (match_operand:DI 0 "register_operand" "=r,r") 4552 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))] 4553 "TARGET_SHMEDIA" 4554 "@ 4555 # 4556 ld%M1.b %m1, %0" 4557 [(set_attr "type" "*,load_media") 4558 (set (attr "highpart") 4559 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0)) 4560 (const_string "user")] 4561 (const_string "ignore")))]) 4562 4563(define_split 4564 [(set (match_operand:DI 0 "register_operand" "") 4565 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))] 4566 "TARGET_SHMEDIA && reload_completed" 4567 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56))) 4568 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))] 4569 " 4570{ 4571 if (GET_CODE (operands[1]) == TRUNCATE) 4572 operands[1] = XEXP (operands[1], 0); 4573}") 4574 4575(define_expand "extendhisi2" 4576 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r") 4577 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))] 4578 "" 4579 "") 4580 4581(define_insn "*extendhisi2_compact" 4582 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r") 4583 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))] 4584 "TARGET_SH1" 4585 "@ 4586 exts.w %1,%0 4587 mov.w %1,%0" 4588 [(set_attr "type" "arith,load")]) 4589 4590(define_insn "*extendhisi2_media" 4591 [(set (match_operand:SI 0 "register_operand" "=r,r") 4592 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))] 4593 "TARGET_SHMEDIA" 4594 "@ 4595 # 4596 ld%M1.w %m1, %0" 4597 [(set_attr "type" "arith_media,load_media") 4598 (set (attr "highpart") 4599 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0)) 4600 (const_string "user")] 4601 (const_string "ignore")))]) 4602 4603(define_split 4604 [(set (match_operand:SI 0 "register_operand" "") 4605 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))] 4606 "TARGET_SHMEDIA && reload_completed" 4607 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16))) 4608 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))] 4609 " 4610{ 4611 rtx op1 = operands[1]; 4612 if (GET_CODE (op1) == TRUNCATE) 4613 op1 = XEXP (op1, 0); 4614 operands[2] 4615 = simplify_gen_subreg (SImode, op1, GET_MODE (op1), 4616 subreg_lowpart_offset (SImode, GET_MODE (op1))); 4617}") 4618 4619(define_expand "extendqisi2" 4620 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r") 4621 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))] 4622 "" 4623 "") 4624 4625(define_insn "*extendqisi2_compact" 4626 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r") 4627 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))] 4628 "TARGET_SH1" 4629 "@ 4630 exts.b %1,%0 4631 mov.b %1,%0" 4632 [(set_attr "type" "arith,load") 4633 (set_attr_alternative "length" 4634 [(const_int 2) 4635 (if_then_else 4636 (ne (symbol_ref "TARGET_SH2A") (const_int 0)) 4637 (const_int 4) (const_int 2))])]) 4638 4639(define_insn "*extendqisi2_media" 4640 [(set (match_operand:SI 0 "register_operand" "=r,r") 4641 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))] 4642 "TARGET_SHMEDIA" 4643 "@ 4644 # 4645 ld%M1.b %m1, %0" 4646 [(set_attr "type" "arith_media,load_media") 4647 (set (attr "highpart") 4648 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0)) 4649 (const_string "user")] 4650 (const_string "ignore")))]) 4651 4652(define_split 4653 [(set (match_operand:SI 0 "register_operand" "") 4654 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))] 4655 "TARGET_SHMEDIA && reload_completed" 4656 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24))) 4657 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))] 4658 " 4659{ 4660 rtx op1 = operands[1]; 4661 if (GET_CODE (op1) == TRUNCATE) 4662 op1 = XEXP (op1, 0); 4663 operands[2] 4664 = simplify_gen_subreg (SImode, op1, GET_MODE (op1), 4665 subreg_lowpart_offset (SImode, GET_MODE (op1))); 4666}") 4667 4668(define_insn "extendqihi2" 4669 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r") 4670 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))] 4671 "TARGET_SH1" 4672 "@ 4673 exts.b %1,%0 4674 mov.b %1,%0" 4675 [(set_attr "type" "arith,load") 4676 (set_attr_alternative "length" 4677 [(const_int 2) 4678 (if_then_else 4679 (ne (symbol_ref "TARGET_SH2A") (const_int 0)) 4680 (const_int 4) (const_int 2))])]) 4681 4682/* It would seem useful to combine the truncXi patterns into the movXi 4683 patterns, but unary operators are ignored when matching constraints, 4684 so we need separate patterns. */ 4685(define_insn "truncdisi2" 4686 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f") 4687 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))] 4688 "TARGET_SHMEDIA" 4689 "@ 4690 add.l %1, r63, %0 4691 st%M0.l %m0, %1 4692 fst%M0.s %m0, %T1 4693 fmov.ls %1, %0 4694 fmov.sl %T1, %0 4695 fmov.s %T1, %0" 4696 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media") 4697 (set (attr "highpart") 4698 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0)) 4699 (const_string "user")] 4700 (const_string "extend")))]) 4701 4702(define_insn "truncdihi2" 4703 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m") 4704 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))] 4705 "TARGET_SHMEDIA" 4706 "@ 4707 shlli\\t%1,48,%0\;shlri\\t%0,48,%0 4708 st%M0.w %m0, %1" 4709 [(set_attr "type" "arith_media,store_media") 4710 (set_attr "length" "8,4") 4711 (set (attr "highpart") 4712 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0)) 4713 (const_string "user")] 4714 (const_string "extend")))]) 4715 4716; N.B. This should agree with LOAD_EXTEND_OP and movqi. 4717; Because we use zero extension, we can't provide signed QImode compares 4718; using a simple compare or conditional branch insn. 4719(define_insn "truncdiqi2" 4720 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m") 4721 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))] 4722 "TARGET_SHMEDIA" 4723 "@ 4724 andi %1, 255, %0 4725 st%M0.b %m0, %1" 4726 [(set_attr "type" "arith_media,store") 4727 (set (attr "highpart") 4728 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0)) 4729 (const_string "user")] 4730 (const_string "extend")))]) 4731;; ------------------------------------------------------------------------- 4732;; Move instructions 4733;; ------------------------------------------------------------------------- 4734 4735;; define push and pop so it is easy for sh.c 4736;; We can't use push and pop on SHcompact because the stack must always 4737;; be 8-byte aligned. 4738 4739(define_expand "push" 4740 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) 4741 (match_operand:SI 0 "register_operand" "r,l,x"))] 4742 "TARGET_SH1 && ! TARGET_SH5" 4743 "") 4744 4745(define_expand "pop" 4746 [(set (match_operand:SI 0 "register_operand" "=r,l,x") 4747 (mem:SI (post_inc:SI (reg:SI SP_REG))))] 4748 "TARGET_SH1 && ! TARGET_SH5" 4749 "") 4750 4751(define_expand "push_e" 4752 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) 4753 (match_operand:SF 0 "" "")) 4754 (use (reg:PSI FPSCR_REG)) 4755 (clobber (scratch:SI))])] 4756 "TARGET_SH1 && ! TARGET_SH5" 4757 "") 4758 4759(define_insn "push_fpul" 4760 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))] 4761 "TARGET_SH2E && ! TARGET_SH5" 4762 "sts.l fpul,@-r15" 4763 [(set_attr "type" "fstore") 4764 (set_attr "late_fp_use" "yes") 4765 (set_attr "hit_stack" "yes")]) 4766 4767;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4, 4768;; so use that. 4769(define_expand "push_4" 4770 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG))) 4771 (match_operand:DF 0 "" "")) 4772 (use (reg:PSI FPSCR_REG)) 4773 (clobber (scratch:SI))])] 4774 "TARGET_SH1 && ! TARGET_SH5" 4775 "") 4776 4777(define_expand "pop_e" 4778 [(parallel [(set (match_operand:SF 0 "" "") 4779 (mem:SF (post_inc:SI (reg:SI SP_REG)))) 4780 (use (reg:PSI FPSCR_REG)) 4781 (clobber (scratch:SI))])] 4782 "TARGET_SH1 && ! TARGET_SH5" 4783 "") 4784 4785(define_insn "pop_fpul" 4786 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))] 4787 "TARGET_SH2E && ! TARGET_SH5" 4788 "lds.l @r15+,fpul" 4789 [(set_attr "type" "load") 4790 (set_attr "hit_stack" "yes")]) 4791 4792(define_expand "pop_4" 4793 [(parallel [(set (match_operand:DF 0 "" "") 4794 (mem:DF (post_inc:SI (reg:SI SP_REG)))) 4795 (use (reg:PSI FPSCR_REG)) 4796 (clobber (scratch:SI))])] 4797 "TARGET_SH1 && ! TARGET_SH5" 4798 "") 4799 4800(define_expand "push_fpscr" 4801 [(const_int 0)] 4802 "TARGET_SH2E" 4803 " 4804{ 4805 rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode, 4806 gen_rtx_PRE_DEC (Pmode, 4807 stack_pointer_rtx)), 4808 get_fpscr_rtx ())); 4809 add_reg_note (insn, REG_INC, stack_pointer_rtx); 4810 DONE; 4811}") 4812 4813(define_expand "pop_fpscr" 4814 [(const_int 0)] 4815 "TARGET_SH2E" 4816 " 4817{ 4818 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (), 4819 gen_frame_mem (PSImode, 4820 gen_rtx_POST_INC (Pmode, 4821 stack_pointer_rtx)))); 4822 add_reg_note (insn, REG_INC, stack_pointer_rtx); 4823 DONE; 4824}") 4825 4826;; These two patterns can happen as the result of optimization, when 4827;; comparisons get simplified to a move of zero or 1 into the T reg. 4828;; They don't disappear completely, because the T reg is a fixed hard reg. 4829 4830(define_insn "clrt" 4831 [(set (reg:SI T_REG) (const_int 0))] 4832 "TARGET_SH1" 4833 "clrt") 4834 4835(define_insn "sett" 4836 [(set (reg:SI T_REG) (const_int 1))] 4837 "TARGET_SH1" 4838 "sett") 4839 4840;; t/r must come after r/r, lest reload will try to reload stuff like 4841;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0) 4842;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T. 4843(define_insn "movsi_i" 4844 [(set (match_operand:SI 0 "general_movdst_operand" 4845 "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,r") 4846 (match_operand:SI 1 "general_movsrc_operand" 4847 "Q,r,I08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))] 4848 "TARGET_SH1 4849 && ! TARGET_SH2E 4850 && ! TARGET_SH2A 4851 && (register_operand (operands[0], SImode) 4852 || register_operand (operands[1], SImode))" 4853 "@ 4854 mov.l %1,%0 4855 mov %1,%0 4856 mov %1,%0 4857 cmp/pl %1 4858 mov.l %1,%0 4859 sts %1,%0 4860 sts %1,%0 4861 movt %0 4862 mov.l %1,%0 4863 sts.l %1,%0 4864 sts.l %1,%0 4865 lds %1,%0 4866 lds %1,%0 4867 lds.l %1,%0 4868 lds.l %1,%0 4869 fake %1,%0" 4870 [(set_attr "type" "pcload_si,move,movi8,mt_group,load_si,mac_gp,prget,arith,store,mac_mem,pstore,gp_mac,prset,mem_mac,pload,pcload_si") 4871 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")]) 4872 4873;; t/r must come after r/r, lest reload will try to reload stuff like 4874;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2) 4875;; ??? This allows moves from macl to fpul to be recognized, but these moves 4876;; will require a reload. 4877;; ??? We can't include f/f because we need the proper FPSCR setting when 4878;; TARGET_FMOVD is in effect, and mode switching is done before reload. 4879(define_insn "movsi_ie" 4880 [(set (match_operand:SI 0 "general_movdst_operand" 4881 "=r,r,r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y") 4882 (match_operand:SI 1 "general_movsrc_operand" 4883 "Q,r,I08,I20,I28,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))] 4884 "(TARGET_SH2E || TARGET_SH2A) 4885 && (register_operand (operands[0], SImode) 4886 || register_operand (operands[1], SImode))" 4887 "@ 4888 mov.l %1,%0 4889 mov %1,%0 4890 mov %1,%0 4891 movi20 %1,%0 4892 movi20s %1,%0 4893 cmp/pl %1 4894 mov.l %1,%0 4895 sts %1,%0 4896 sts %1,%0 4897 movt %0 4898 mov.l %1,%0 4899 sts.l %1,%0 4900 sts.l %1,%0 4901 lds %1,%0 4902 lds %1,%0 4903 lds.l %1,%0 4904 lds.l %1,%0 4905 lds.l %1,%0 4906 sts.l %1,%0 4907 fake %1,%0 4908 lds %1,%0 4909 sts %1,%0 4910 fsts fpul,%0 4911 flds %1,fpul 4912 fmov %1,%0 4913 ! move optimized away" 4914 [(set_attr "type" "pcload_si,move,movi8,move,move,*,load_si,mac_gp,prget,arith,store,mac_mem,pstore,gp_mac,prset,mem_mac,pload,load,fstore,pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil") 4915 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*") 4916 (set_attr_alternative "length" 4917 [(const_int 2) 4918 (const_int 2) 4919 (const_int 2) 4920 (const_int 4) 4921 (const_int 4) 4922 (const_int 2) 4923 (if_then_else 4924 (ne (symbol_ref "TARGET_SH2A") (const_int 0)) 4925 (const_int 4) (const_int 2)) 4926 (const_int 2) 4927 (const_int 2) 4928 (const_int 2) 4929 (if_then_else 4930 (ne (symbol_ref "TARGET_SH2A") (const_int 0)) 4931 (const_int 4) (const_int 2)) 4932 (const_int 2) 4933 (const_int 2) 4934 (const_int 2) 4935 (const_int 2) 4936 (const_int 2) 4937 (const_int 2) 4938 (const_int 2) 4939 (const_int 2) 4940 (const_int 2) 4941 (const_int 2) 4942 (const_int 2) 4943 (const_int 2) 4944 (const_int 2) 4945 (const_int 2) 4946 (const_int 0)])]) 4947 4948(define_insn "movsi_i_lowpart" 4949 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,r,m,r")) 4950 (match_operand:SI 1 "general_movsrc_operand" "Q,r,I08,mr,x,l,t,r,i"))] 4951 "TARGET_SH1 4952 && (register_operand (operands[0], SImode) 4953 || register_operand (operands[1], SImode))" 4954 "@ 4955 mov.l %1,%0 4956 mov %1,%0 4957 mov %1,%0 4958 mov.l %1,%0 4959 sts %1,%0 4960 sts %1,%0 4961 movt %0 4962 mov.l %1,%0 4963 fake %1,%0" 4964 [(set_attr "type" "pcload,move,arith,load,mac_gp,prget,arith,store,pcload")]) 4965 4966(define_insn_and_split "load_ra" 4967 [(set (match_operand:SI 0 "general_movdst_operand" "") 4968 (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))] 4969 "TARGET_SH1" 4970 "#" 4971 "&& ! currently_expanding_to_rtl" 4972 [(set (match_dup 0) (match_dup 1))] 4973 " 4974{ 4975 if (TARGET_SHCOMPACT && crtl->saves_all_registers) 4976 operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx); 4977}") 4978 4979;; The '?'s in the following constraints may not reflect the time taken 4980;; to perform the move. They are there to discourage the use of floating- 4981;; point registers for storing integer values. 4982(define_insn "*movsi_media" 4983 [(set (match_operand:SI 0 "general_movdst_operand" 4984 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b") 4985 (match_operand:SI 1 "general_movsrc_operand" 4986 "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))] 4987 "TARGET_SHMEDIA_FPU 4988 && (register_operand (operands[0], SImode) 4989 || sh_register_operand (operands[1], SImode) 4990 || GET_CODE (operands[1]) == TRUNCATE)" 4991 "@ 4992 add.l %1, r63, %0 4993 movi %1, %0 4994 # 4995 ld%M1.l %m1, %0 4996 st%M0.l %m0, %N1 4997 fld%M1.s %m1, %0 4998 fst%M0.s %m0, %1 4999 fmov.ls %N1, %0 5000 fmov.sl %1, %0 5001 fmov.s %1, %0 5002 ptabs %1, %0 5003 gettr %1, %0 5004 pt %1, %0" 5005 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,fload_media,fstore_media,fload_media,fpconv_media,fmove_media,ptabs_media,gettr_media,pt_media") 5006 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12") 5007 (set (attr "highpart") 5008 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0)) 5009 (const_string "user")] 5010 (const_string "ignore")))]) 5011 5012(define_insn "*movsi_media_nofpu" 5013 [(set (match_operand:SI 0 "general_movdst_operand" 5014 "=r,r,r,r,m,*b,r,*b") 5015 (match_operand:SI 1 "general_movsrc_operand" 5016 "r,I16Css,nCpg,m,rZ,r,*b,Csy"))] 5017 "TARGET_SHMEDIA 5018 && (register_operand (operands[0], SImode) 5019 || sh_register_operand (operands[1], SImode) 5020 || GET_CODE (operands[1]) == TRUNCATE)" 5021 "@ 5022 add.l %1, r63, %0 5023 movi %1, %0 5024 # 5025 ld%M1.l %m1, %0 5026 st%M0.l %m0, %N1 5027 ptabs %1, %0 5028 gettr %1, %0 5029 pt %1, %0" 5030 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media") 5031 (set_attr "length" "4,4,8,4,4,4,4,12") 5032 (set (attr "highpart") 5033 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0)) 5034 (const_string "user")] 5035 (const_string "ignore")))]) 5036 5037(define_expand "movsi_const" 5038 [(set (match_operand:SI 0 "arith_reg_operand" "=r") 5039 (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s") 5040 (const_int 16)] UNSPEC_EXTRACT_S16))) 5041 (set (match_dup 0) 5042 (ior:SI (ashift:SI (match_dup 0) (const_int 16)) 5043 (const:SI (unspec:SI [(match_dup 1) 5044 (const_int 0)] UNSPEC_EXTRACT_U16))))] 5045 "TARGET_SHMEDIA && reload_completed 5046 && MOVI_SHORI_BASE_OPERAND_P (operands[1])" 5047 " 5048{ 5049 if (GET_CODE (operands[1]) == LABEL_REF 5050 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL) 5051 LABEL_NUSES (XEXP (operands[1], 0)) += 2; 5052 else if (GOTOFF_P (operands[1])) 5053 { 5054 rtx unspec = XEXP (operands[1], 0); 5055 5056 if (! UNSPEC_GOTOFF_P (unspec)) 5057 { 5058 unspec = XEXP (unspec, 0); 5059 if (! UNSPEC_GOTOFF_P (unspec)) 5060 abort (); 5061 } 5062 if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF 5063 && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL)) 5064 LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2; 5065 } 5066}") 5067 5068(define_expand "movsi_const_16bit" 5069 [(set (match_operand:SI 0 "arith_reg_operand" "=r") 5070 (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s") 5071 (const_int 0)] UNSPEC_EXTRACT_S16)))] 5072 "TARGET_SHMEDIA && flag_pic && reload_completed 5073 && GET_CODE (operands[1]) == SYMBOL_REF" 5074 "") 5075 5076(define_split 5077 [(set (match_operand:SI 0 "arith_reg_dest" "") 5078 (match_operand:SI 1 "immediate_operand" ""))] 5079 "TARGET_SHMEDIA && reload_completed 5080 && MOVI_SHORI_BASE_OPERAND_P (operands[1])" 5081 [(const_int 0)] 5082 " 5083{ 5084 rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1])); 5085 5086 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1])); 5087 5088 DONE; 5089}") 5090 5091(define_split 5092 [(set (match_operand:SI 0 "register_operand" "") 5093 (match_operand:SI 1 "immediate_operand" ""))] 5094 "TARGET_SHMEDIA && reload_completed 5095 && ((CONST_INT_P (operands[1]) 5096 && ! satisfies_constraint_I16 (operands[1])) 5097 || GET_CODE (operands[1]) == CONST_DOUBLE)" 5098 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))]) 5099 5100(define_expand "movsi" 5101 [(set (match_operand:SI 0 "general_movdst_operand" "") 5102 (match_operand:SI 1 "general_movsrc_operand" ""))] 5103 "" 5104 "{ if (prepare_move_operands (operands, SImode)) DONE; }") 5105 5106(define_expand "ic_invalidate_line" 5107 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r") 5108 (match_dup 1)] UNSPEC_ICACHE) 5109 (clobber (scratch:SI))])] 5110 "TARGET_HARD_SH4 || TARGET_SH5" 5111 " 5112{ 5113 if (TARGET_SHMEDIA) 5114 { 5115 emit_insn (gen_ic_invalidate_line_media (operands[0])); 5116 DONE; 5117 } 5118 else if (TARGET_SHCOMPACT) 5119 { 5120 operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC); 5121 operands[1] = force_reg (Pmode, operands[1]); 5122 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1])); 5123 DONE; 5124 } 5125 else if (TARGET_SH4A_ARCH || TARGET_SH4_300) 5126 { 5127 emit_insn (gen_ic_invalidate_line_sh4a (operands[0])); 5128 DONE; 5129 } 5130 operands[0] = force_reg (Pmode, operands[0]); 5131 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008, 5132 Pmode))); 5133}") 5134 5135;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing 5136;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits 5137;; the requirement *1*00 for associative address writes. The alignment of 5138;; %0 implies that its least significant bit is cleared, 5139;; thus we clear the V bit of a matching entry if there is one. 5140(define_insn "ic_invalidate_line_i" 5141 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r") 5142 (match_operand:SI 1 "register_operand" "r")] 5143 UNSPEC_ICACHE) 5144 (clobber (match_scratch:SI 2 "=&r"))] 5145 "TARGET_HARD_SH4" 5146 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2" 5147 [(set_attr "length" "8") 5148 (set_attr "type" "cwb")]) 5149 5150(define_insn "ic_invalidate_line_sh4a" 5151 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] 5152 UNSPEC_ICACHE)] 5153 "TARGET_SH4A_ARCH || TARGET_SH4_300" 5154 "ocbwb\\t@%0\;synco\;icbi\\t@%0" 5155 [(set_attr "length" "16") 5156 (set_attr "type" "cwb")]) 5157 5158;; ??? could make arg 0 an offsettable memory operand to allow to save 5159;; an add in the code that calculates the address. 5160(define_insn "ic_invalidate_line_media" 5161 [(unspec_volatile [(match_operand 0 "any_register_operand" "r")] 5162 UNSPEC_ICACHE)] 5163 "TARGET_SHMEDIA" 5164 "ocbwb %0,0\;synco\;icbi %0, 0\;synci" 5165 [(set_attr "length" "16") 5166 (set_attr "type" "invalidate_line_media")]) 5167 5168(define_insn "ic_invalidate_line_compact" 5169 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z") 5170 (match_operand:SI 1 "register_operand" "r")] 5171 UNSPEC_ICACHE) 5172 (clobber (reg:SI PR_REG))] 5173 "TARGET_SHCOMPACT" 5174 "jsr @%1%#" 5175 [(set_attr "type" "sfunc") 5176 (set_attr "needs_delay_slot" "yes")]) 5177 5178(define_expand "initialize_trampoline" 5179 [(match_operand:SI 0 "" "") 5180 (match_operand:SI 1 "" "") 5181 (match_operand:SI 2 "" "")] 5182 "TARGET_SHCOMPACT" 5183 " 5184{ 5185 rtx sfun, tramp; 5186 5187 tramp = force_reg (Pmode, operands[0]); 5188 sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\", 5189 SFUNC_STATIC)); 5190 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]); 5191 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]); 5192 5193 emit_insn (gen_initialize_trampoline_compact (tramp, sfun)); 5194 DONE; 5195}") 5196 5197(define_insn "initialize_trampoline_compact" 5198 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z") 5199 (match_operand:SI 1 "register_operand" "r") 5200 (reg:SI R2_REG) (reg:SI R3_REG)] 5201 UNSPEC_INIT_TRAMP) 5202 5203 (clobber (reg:SI PR_REG))] 5204 "TARGET_SHCOMPACT" 5205 "jsr @%1%#" 5206 [(set_attr "type" "sfunc") 5207 (set_attr "needs_delay_slot" "yes")]) 5208 5209(define_insn "movqi_i" 5210 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m,r,r,l") 5211 (match_operand:QI 1 "general_movsrc_operand" "r,i,m,r,t,l,r"))] 5212 "TARGET_SH1 5213 && (arith_reg_operand (operands[0], QImode) 5214 || arith_reg_operand (operands[1], QImode))" 5215 "@ 5216 mov %1,%0 5217 mov %1,%0 5218 mov.b %1,%0 5219 mov.b %1,%0 5220 movt %0 5221 sts %1,%0 5222 lds %1,%0" 5223 [(set_attr "type" "move,movi8,load,store,arith,prget,prset") 5224 (set_attr_alternative "length" 5225 [(const_int 2) 5226 (const_int 2) 5227 (if_then_else 5228 (ne (symbol_ref "TARGET_SH2A") (const_int 0)) 5229 (const_int 4) (const_int 2)) 5230 (if_then_else 5231 (ne (symbol_ref "TARGET_SH2A") (const_int 0)) 5232 (const_int 4) (const_int 2)) 5233 (const_int 2) 5234 (const_int 2) 5235 (const_int 2)])]) 5236 5237(define_insn "*movqi_media" 5238 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m") 5239 (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))] 5240 "TARGET_SHMEDIA 5241 && (arith_reg_operand (operands[0], QImode) 5242 || extend_reg_or_0_operand (operands[1], QImode))" 5243 "@ 5244 add.l %1, r63, %0 5245 movi %1, %0 5246 ld%M1.ub %m1, %0 5247 st%M0.b %m0, %N1" 5248 [(set_attr "type" "arith_media,arith_media,load_media,store_media") 5249 (set (attr "highpart") 5250 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0)) 5251 (const_string "user")] 5252 (const_string "ignore")))]) 5253 5254(define_expand "movqi" 5255 [(set (match_operand:QI 0 "general_operand" "") 5256 (match_operand:QI 1 "general_operand" ""))] 5257 "" 5258 "{ if (prepare_move_operands (operands, QImode)) DONE; }") 5259 5260(define_expand "reload_inqi" 5261 [(set (match_operand:SI 2 "" "=&r") 5262 (match_operand:QI 1 "inqhi_operand" "")) 5263 (set (match_operand:QI 0 "arith_reg_operand" "=r") 5264 (truncate:QI (match_dup 3)))] 5265 "TARGET_SHMEDIA" 5266 " 5267{ 5268 rtx inner = XEXP (operands[1], 0); 5269 int regno = REGNO (inner); 5270 5271 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1; 5272 operands[1] = gen_rtx_REG (SImode, regno); 5273 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2])); 5274}") 5275 5276/* When storing r0, we have to avoid reg+reg addressing. */ 5277(define_insn "movhi_i" 5278 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r") 5279 (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))] 5280 "TARGET_SH1 5281 && (arith_reg_operand (operands[0], HImode) 5282 || arith_reg_operand (operands[1], HImode)) 5283 && (!MEM_P (operands[0]) 5284 || GET_CODE (XEXP (operands[0], 0)) != PLUS 5285 || !REG_P (XEXP (XEXP (operands[0], 0), 1)) 5286 || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))" 5287 "@ 5288 mov.w %1,%0 5289 mov %1,%0 5290 mov.w %1,%0 5291 movt %0 5292 mov.w %1,%0 5293 sts %1,%0 5294 lds %1,%0 5295 fake %1,%0" 5296 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")]) 5297 5298(define_insn "*movhi_media" 5299 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m") 5300 (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))] 5301 "TARGET_SHMEDIA 5302 && (arith_reg_operand (operands[0], HImode) 5303 || arith_reg_or_0_operand (operands[1], HImode))" 5304 "@ 5305 add.l %1, r63, %0 5306 movi %1, %0 5307 # 5308 ld%M1.w %m1, %0 5309 st%M0.w %m0, %N1" 5310 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media") 5311 (set (attr "highpart") 5312 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0)) 5313 (const_string "user")] 5314 (const_string "ignore")))]) 5315 5316(define_split 5317 [(set (match_operand:HI 0 "register_operand" "") 5318 (match_operand:HI 1 "immediate_operand" ""))] 5319 "TARGET_SHMEDIA && reload_completed 5320 && ! satisfies_constraint_I16 (operands[1])" 5321 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))]) 5322 5323(define_expand "movhi" 5324 [(set (match_operand:HI 0 "general_movdst_operand" "") 5325 (match_operand:HI 1 "general_movsrc_operand" ""))] 5326 "" 5327 "{ if (prepare_move_operands (operands, HImode)) DONE; }") 5328 5329(define_expand "reload_inhi" 5330 [(set (match_operand:SI 2 "" "=&r") 5331 (match_operand:HI 1 "inqhi_operand" "")) 5332 (set (match_operand:HI 0 "arith_reg_operand" "=r") 5333 (truncate:HI (match_dup 3)))] 5334 "TARGET_SHMEDIA" 5335 " 5336{ 5337 rtx inner = XEXP (operands[1], 0); 5338 int regno = REGNO (inner); 5339 5340 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1; 5341 operands[1] = gen_rtx_REG (SImode, regno); 5342 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2])); 5343}") 5344 5345;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c 5346;; compiled with -m2 -ml -O3 -funroll-loops 5347(define_insn "*movdi_i" 5348 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x") 5349 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))] 5350 "TARGET_SH1 5351 && (arith_reg_operand (operands[0], DImode) 5352 || arith_reg_operand (operands[1], DImode))" 5353 "* return output_movedouble (insn, operands, DImode);" 5354 [(set_attr "length" "4") 5355 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")]) 5356 5357;; If the output is a register and the input is memory or a register, we have 5358;; to be careful and see which word needs to be loaded first. 5359 5360(define_split 5361 [(set (match_operand:DI 0 "general_movdst_operand" "") 5362 (match_operand:DI 1 "general_movsrc_operand" ""))] 5363 "TARGET_SH1 && reload_completed" 5364 [(set (match_dup 2) (match_dup 3)) 5365 (set (match_dup 4) (match_dup 5))] 5366 " 5367{ 5368 int regno; 5369 5370 if ((MEM_P (operands[0]) 5371 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) 5372 || (MEM_P (operands[1]) 5373 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)) 5374 FAIL; 5375 5376 switch (GET_CODE (operands[0])) 5377 { 5378 case REG: 5379 regno = REGNO (operands[0]); 5380 break; 5381 case SUBREG: 5382 regno = subreg_regno (operands[0]); 5383 break; 5384 case MEM: 5385 regno = -1; 5386 break; 5387 default: 5388 gcc_unreachable (); 5389 } 5390 5391 if (regno == -1 5392 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0)) 5393 { 5394 operands[2] = operand_subword (operands[0], 0, 0, DImode); 5395 operands[3] = operand_subword (operands[1], 0, 0, DImode); 5396 operands[4] = operand_subword (operands[0], 1, 0, DImode); 5397 operands[5] = operand_subword (operands[1], 1, 0, DImode); 5398 } 5399 else 5400 { 5401 operands[2] = operand_subword (operands[0], 1, 0, DImode); 5402 operands[3] = operand_subword (operands[1], 1, 0, DImode); 5403 operands[4] = operand_subword (operands[0], 0, 0, DImode); 5404 operands[5] = operand_subword (operands[1], 0, 0, DImode); 5405 } 5406 5407 if (operands[2] == 0 || operands[3] == 0 5408 || operands[4] == 0 || operands[5] == 0) 5409 FAIL; 5410}") 5411 5412;; The '?'s in the following constraints may not reflect the time taken 5413;; to perform the move. They are there to discourage the use of floating- 5414;; point registers for storing integer values. 5415(define_insn "*movdi_media" 5416 [(set (match_operand:DI 0 "general_movdst_operand" 5417 "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b") 5418 (match_operand:DI 1 "general_movsrc_operand" 5419 "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))] 5420 "TARGET_SHMEDIA_FPU 5421 && (register_operand (operands[0], DImode) 5422 || sh_register_operand (operands[1], DImode))" 5423 "@ 5424 add %1, r63, %0 5425 movi %1, %0 5426 # 5427 ld%M1.q %m1, %0 5428 st%M0.q %m0, %N1 5429 fld%M1.d %m1, %0 5430 fst%M0.d %m0, %1 5431 fmov.qd %N1, %0 5432 fmov.dq %1, %0 5433 fmov.d %1, %0 5434 ptabs %1, %0 5435 gettr %1, %0 5436 pt %1, %0" 5437 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,fload_media,fstore_media,fload_media,dfpconv_media,fmove_media,ptabs_media,gettr_media,pt_media") 5438 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")]) 5439 5440(define_insn "*movdi_media_nofpu" 5441 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b"); 5442 (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))] 5443 "TARGET_SHMEDIA 5444 && (register_operand (operands[0], DImode) 5445 || sh_register_operand (operands[1], DImode))" 5446 "@ 5447 add %1, r63, %0 5448 movi %1, %0 5449 # 5450 ld%M1.q %m1, %0 5451 st%M0.q %m0, %N1 5452 ptabs %1, %0 5453 gettr %1, %0 5454 pt %1, %0" 5455 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media") 5456 (set_attr "length" "4,4,16,4,4,4,4,*")]) 5457 5458(define_insn "*movdi_media_I16" 5459 [(set (match_operand:DI 0 "ext_dest_operand" "=r") 5460 (match_operand:DI 1 "const_int_operand" "I16"))] 5461 "TARGET_SHMEDIA && reload_completed" 5462 "movi %1, %0" 5463 [(set_attr "type" "arith_media") 5464 (set_attr "length" "4")]) 5465 5466(define_split 5467 [(set (match_operand:DI 0 "arith_reg_dest" "") 5468 (match_operand:DI 1 "immediate_operand" ""))] 5469 "TARGET_SHMEDIA && reload_completed 5470 && MOVI_SHORI_BASE_OPERAND_P (operands[1])" 5471 [(set (match_dup 0) (match_dup 1))] 5472 " 5473{ 5474 rtx insn; 5475 5476 if (TARGET_SHMEDIA64) 5477 insn = emit_insn (gen_movdi_const (operands[0], operands[1])); 5478 else 5479 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1])); 5480 5481 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1])); 5482 5483 DONE; 5484}") 5485 5486(define_expand "movdi_const" 5487 [(set (match_operand:DI 0 "arith_reg_operand" "=r") 5488 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s") 5489 (const_int 48)] UNSPEC_EXTRACT_S16))) 5490 (set (match_dup 0) 5491 (ior:DI (ashift:DI (match_dup 0) (const_int 16)) 5492 (const:DI (unspec:DI [(match_dup 1) 5493 (const_int 32)] UNSPEC_EXTRACT_U16)))) 5494 (set (match_dup 0) 5495 (ior:DI (ashift:DI (match_dup 0) (const_int 16)) 5496 (const:DI (unspec:DI [(match_dup 1) 5497 (const_int 16)] UNSPEC_EXTRACT_U16)))) 5498 (set (match_dup 0) 5499 (ior:DI (ashift:DI (match_dup 0) (const_int 16)) 5500 (const:DI (unspec:DI [(match_dup 1) 5501 (const_int 0)] UNSPEC_EXTRACT_U16))))] 5502 "TARGET_SHMEDIA64 && reload_completed 5503 && MOVI_SHORI_BASE_OPERAND_P (operands[1])" 5504 " 5505{ 5506 sh_mark_label (operands[1], 4); 5507}") 5508 5509(define_expand "movdi_const_32bit" 5510 [(set (match_operand:DI 0 "arith_reg_operand" "=r") 5511 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s") 5512 (const_int 16)] UNSPEC_EXTRACT_S16))) 5513 (set (match_dup 0) 5514 (ior:DI (ashift:DI (match_dup 0) (const_int 16)) 5515 (const:DI (unspec:DI [(match_dup 1) 5516 (const_int 0)] UNSPEC_EXTRACT_U16))))] 5517 "TARGET_SHMEDIA32 && reload_completed 5518 && MOVI_SHORI_BASE_OPERAND_P (operands[1])" 5519 " 5520{ 5521 sh_mark_label (operands[1], 2); 5522}") 5523 5524(define_expand "movdi_const_16bit" 5525 [(set (match_operand:DI 0 "arith_reg_operand" "=r") 5526 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s") 5527 (const_int 0)] UNSPEC_EXTRACT_S16)))] 5528 "TARGET_SHMEDIA && flag_pic && reload_completed 5529 && GET_CODE (operands[1]) == SYMBOL_REF" 5530 "") 5531 5532(define_split 5533 [(set (match_operand:DI 0 "ext_dest_operand" "") 5534 (match_operand:DI 1 "immediate_operand" ""))] 5535 "TARGET_SHMEDIA && reload_completed 5536 && CONST_INT_P (operands[1]) 5537 && ! satisfies_constraint_I16 (operands[1])" 5538 [(set (match_dup 0) (match_dup 2)) 5539 (match_dup 1)] 5540 " 5541{ 5542 unsigned HOST_WIDE_INT val = INTVAL (operands[1]); 5543 unsigned HOST_WIDE_INT low = val; 5544 unsigned HOST_WIDE_INT high = val; 5545 unsigned HOST_WIDE_INT sign; 5546 unsigned HOST_WIDE_INT val2 = val ^ (val-1); 5547 5548 /* Zero-extend the 16 least-significant bits. */ 5549 low &= 0xffff; 5550 5551 /* Arithmetic shift right the word by 16 bits. */ 5552 high >>= 16; 5553 if (GET_CODE (operands[0]) == SUBREG 5554 && GET_MODE (SUBREG_REG (operands[0])) == SImode) 5555 { 5556 high &= 0xffff; 5557 high ^= 0x8000; 5558 high -= 0x8000; 5559 } 5560 else 5561 { 5562 sign = 1; 5563 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1); 5564 high ^= sign; 5565 high -= sign; 5566 } 5567 do 5568 { 5569 /* If we can't generate the constant with a two-insn movi / shori 5570 sequence, try some other strategies. */ 5571 if (! CONST_OK_FOR_I16 (high)) 5572 { 5573 /* Try constant load / left shift. We know VAL != 0. */ 5574 val2 = val ^ (val-1); 5575 if (val2 > 0x1ffff) 5576 { 5577 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15; 5578 5579 if (CONST_OK_FOR_I16 (val >> trailing_zeroes) 5580 || (! CONST_OK_FOR_I16 (high >> 16) 5581 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16)))) 5582 { 5583 val2 = (HOST_WIDE_INT) val >> trailing_zeroes; 5584 operands[1] = gen_ashldi3_media (operands[0], operands[0], 5585 GEN_INT (trailing_zeroes)); 5586 break; 5587 } 5588 } 5589 /* Try constant load / right shift. */ 5590 val2 = (val >> 15) + 1; 5591 if (val2 == (val2 & -val2)) 5592 { 5593 int shift = 49 - exact_log2 (val2); 5594 5595 val2 = trunc_int_for_mode (val << shift, DImode); 5596 if (CONST_OK_FOR_I16 (val2)) 5597 { 5598 operands[1] = gen_lshrdi3_media (operands[0], operands[0], 5599 GEN_INT (shift)); 5600 break; 5601 } 5602 } 5603 /* Try mperm.w . */ 5604 val2 = val & 0xffff; 5605 if ((val >> 16 & 0xffff) == val2 5606 && (val >> 32 & 0xffff) == val2 5607 && (val >> 48 & 0xffff) == val2) 5608 { 5609 val2 = (HOST_WIDE_INT) val >> 48; 5610 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0])); 5611 operands[1] = gen_mperm_w0 (operands[1], operands[1]); 5612 break; 5613 } 5614 /* Try movi / mshflo.l */ 5615 val2 = (HOST_WIDE_INT) val >> 32; 5616 if (val2 == ((unsigned HOST_WIDE_INT) 5617 trunc_int_for_mode (val, SImode))) 5618 { 5619 operands[1] = gen_mshflo_l_di (operands[0], operands[0], 5620 operands[0]); 5621 break; 5622 } 5623 /* Try movi / mshflo.l w/ r63. */ 5624 val2 = val + ((HOST_WIDE_INT) -1 << 32); 5625 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2)) 5626 { 5627 operands[1] = gen_mshflo_l_di (operands[0], operands[0], 5628 const0_rtx); 5629 break; 5630 } 5631 } 5632 val2 = high; 5633 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low)); 5634 } 5635 while (0); 5636 operands[2] = GEN_INT (val2); 5637}") 5638 5639(define_split 5640 [(set (match_operand:DI 0 "ext_dest_operand" "") 5641 (match_operand:DI 1 "immediate_operand" ""))] 5642 "TARGET_SHMEDIA && reload_completed 5643 && GET_CODE (operands[1]) == CONST_DOUBLE" 5644 [(set (match_dup 0) (match_dup 2)) 5645 (set (match_dup 0) 5646 (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))] 5647 " 5648{ 5649 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]); 5650 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]); 5651 unsigned HOST_WIDE_INT val = low; 5652 unsigned HOST_WIDE_INT sign; 5653 5654 /* Zero-extend the 16 least-significant bits. */ 5655 val &= 0xffff; 5656 operands[1] = GEN_INT (val); 5657 5658 /* Arithmetic shift right the double-word by 16 bits. */ 5659 low >>= 16; 5660 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16); 5661 high >>= 16; 5662 sign = 1; 5663 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1); 5664 high ^= sign; 5665 high -= sign; 5666 5667 /* This will only be true if high is a sign-extension of low, i.e., 5668 it must be either 0 or (unsigned)-1, and be zero iff the 5669 most-significant bit of low is set. */ 5670 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0) 5671 operands[2] = GEN_INT (low); 5672 else 5673 operands[2] = immed_double_const (low, high, DImode); 5674}") 5675 5676(define_insn "shori_media" 5677 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r") 5678 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0") 5679 (const_int 16)) 5680 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))] 5681 "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))" 5682 "@ 5683 shori %u2, %0 5684 #" 5685 [(set_attr "type" "arith_media,*")]) 5686 5687(define_insn "*shori_media_si" 5688 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 5689 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") 5690 (const_int 16)) 5691 (match_operand:SI 2 "immediate_operand" "K16Csu")))] 5692 "TARGET_SHMEDIA" 5693 "shori %u2, %0") 5694 5695(define_expand "movdi" 5696 [(set (match_operand:DI 0 "general_movdst_operand" "") 5697 (match_operand:DI 1 "general_movsrc_operand" ""))] 5698 "" 5699 "{ if (prepare_move_operands (operands, DImode)) DONE; }") 5700 5701(define_insn "movdf_media" 5702 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m") 5703 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))] 5704 "TARGET_SHMEDIA_FPU 5705 && (register_operand (operands[0], DFmode) 5706 || sh_register_operand (operands[1], DFmode))" 5707 "@ 5708 fmov.d %1, %0 5709 fmov.qd %N1, %0 5710 fmov.dq %1, %0 5711 add %1, r63, %0 5712 # 5713 fld%M1.d %m1, %0 5714 fst%M0.d %m0, %1 5715 ld%M1.q %m1, %0 5716 st%M0.q %m0, %N1" 5717 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")]) 5718 5719(define_insn "movdf_media_nofpu" 5720 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m") 5721 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))] 5722 "TARGET_SHMEDIA 5723 && (register_operand (operands[0], DFmode) 5724 || sh_register_operand (operands[1], DFmode))" 5725 "@ 5726 add %1, r63, %0 5727 # 5728 ld%M1.q %m1, %0 5729 st%M0.q %m0, %N1" 5730 [(set_attr "type" "arith_media,*,load_media,store_media")]) 5731 5732(define_split 5733 [(set (match_operand:DF 0 "arith_reg_dest" "") 5734 (match_operand:DF 1 "immediate_operand" ""))] 5735 "TARGET_SHMEDIA && reload_completed" 5736 [(set (match_dup 3) (match_dup 2))] 5737 " 5738{ 5739 int endian = WORDS_BIG_ENDIAN ? 1 : 0; 5740 long values[2]; 5741 REAL_VALUE_TYPE value; 5742 5743 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]); 5744 REAL_VALUE_TO_TARGET_DOUBLE (value, values); 5745 5746 if (HOST_BITS_PER_WIDE_INT >= 64) 5747 operands[2] = immed_double_const ((unsigned long) values[endian] 5748 | ((HOST_WIDE_INT) values[1 - endian] 5749 << 32), 0, DImode); 5750 else 5751 { 5752 gcc_assert (HOST_BITS_PER_WIDE_INT == 32); 5753 operands[2] = immed_double_const (values[endian], values[1 - endian], 5754 DImode); 5755 } 5756 5757 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0])); 5758}") 5759 5760;; ??? This should be a define expand. 5761 5762(define_insn "movdf_k" 5763 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m") 5764 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))] 5765 "TARGET_SH1 5766 && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed 5767 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */ 5768 || (REG_P (operands[0]) && REGNO (operands[0]) == 3) 5769 || (REG_P (operands[1]) && REGNO (operands[1]) == 3)) 5770 && (arith_reg_operand (operands[0], DFmode) 5771 || arith_reg_operand (operands[1], DFmode))" 5772 "* return output_movedouble (insn, operands, DFmode);" 5773 [(set_attr "length" "4") 5774 (set_attr "type" "move,pcload,load,store")]) 5775 5776;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD. 5777;; However, the d/F/c/z alternative cannot be split directly; it is converted 5778;; with special code in machine_dependent_reorg into a load of the R0_REG and 5779;; the d/m/c/X alternative, which is split later into single-precision 5780;; instructions. And when not optimizing, no splits are done before fixing 5781;; up pcloads, so we need usable length information for that. 5782(define_insn "movdf_i4" 5783 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d") 5784 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r")) 5785 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c")) 5786 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))] 5787 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) 5788 && (arith_reg_operand (operands[0], DFmode) 5789 || arith_reg_operand (operands[1], DFmode))" 5790 { 5791 switch (which_alternative) 5792 { 5793 case 0: 5794 if (TARGET_FMOVD) 5795 return "fmov %1,%0"; 5796 else if (REGNO (operands[0]) != REGNO (operands[1]) + 1) 5797 return "fmov %R1,%R0\n\tfmov %S1,%S0"; 5798 else 5799 return "fmov %S1,%S0\n\tfmov %R1,%R0"; 5800 case 3: 5801 case 4: 5802 return "fmov.d %1,%0"; 5803 default: 5804 return "#"; 5805 } 5806 } 5807 [(set_attr_alternative "length" 5808 [(if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 8)) 5809 (const_int 4) 5810 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6)) 5811 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6)) 5812 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6)) 5813 (const_int 4) 5814 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn) 5815 ;; We can't use 4-byte push/pop on SHcompact, so we have to 5816 ;; increment or decrement r15 explicitly. 5817 (if_then_else 5818 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0)) 5819 (const_int 10) (const_int 8)) 5820 (if_then_else 5821 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0)) 5822 (const_int 10) (const_int 8))]) 5823 (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,fload") 5824 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*") 5825 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes") 5826 (const_string "double") 5827 (const_string "none")))]) 5828 5829;; Moving DFmode between fp/general registers through memory 5830;; (the top of the stack) is faster than moving through fpul even for 5831;; little endian. Because the type of an instruction is important for its 5832;; scheduling, it is beneficial to split these operations, rather than 5833;; emitting them in one single chunk, even if this will expose a stack 5834;; use that will prevent scheduling of other stack accesses beyond this 5835;; instruction. 5836(define_split 5837 [(set (match_operand:DF 0 "register_operand" "") 5838 (match_operand:DF 1 "register_operand" "")) 5839 (use (match_operand:PSI 2 "fpscr_operand" "")) 5840 (clobber (match_scratch:SI 3 "=X"))] 5841 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed 5842 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)" 5843 [(const_int 0)] 5844 " 5845{ 5846 rtx insn, tos; 5847 5848 if (TARGET_SH5 && true_regnum (operands[1]) < 16) 5849 { 5850 emit_move_insn (stack_pointer_rtx, 5851 plus_constant (stack_pointer_rtx, -8)); 5852 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx); 5853 } 5854 else 5855 tos = gen_tmp_stack_mem (DFmode, 5856 gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx)); 5857 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2])); 5858 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16)) 5859 add_reg_note (insn, REG_INC, stack_pointer_rtx); 5860 if (TARGET_SH5 && true_regnum (operands[0]) < 16) 5861 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx); 5862 else 5863 tos = gen_tmp_stack_mem (DFmode, 5864 gen_rtx_POST_INC (Pmode, stack_pointer_rtx)); 5865 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2])); 5866 if (TARGET_SH5 && true_regnum (operands[0]) < 16) 5867 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8)); 5868 else 5869 add_reg_note (insn, REG_INC, stack_pointer_rtx); 5870 DONE; 5871}") 5872 5873;; local-alloc sometimes allocates scratch registers even when not required, 5874;; so we must be prepared to handle these. 5875 5876;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k. 5877(define_split 5878 [(set (match_operand:DF 0 "general_movdst_operand" "") 5879 (match_operand:DF 1 "general_movsrc_operand" "")) 5880 (use (match_operand:PSI 2 "fpscr_operand" "")) 5881 (clobber (match_scratch:SI 3 ""))] 5882 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) 5883 && reload_completed 5884 && true_regnum (operands[0]) < 16 5885 && true_regnum (operands[1]) < 16" 5886 [(set (match_dup 0) (match_dup 1))] 5887 " 5888{ 5889 /* If this was a reg <-> mem operation with base + index reg addressing, 5890 we have to handle this in a special way. */ 5891 rtx mem = operands[0]; 5892 int store_p = 1; 5893 if (! memory_operand (mem, DFmode)) 5894 { 5895 mem = operands[1]; 5896 store_p = 0; 5897 } 5898 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0) 5899 mem = SUBREG_REG (mem); 5900 if (MEM_P (mem)) 5901 { 5902 rtx addr = XEXP (mem, 0); 5903 if (GET_CODE (addr) == PLUS 5904 && REG_P (XEXP (addr, 0)) 5905 && REG_P (XEXP (addr, 1))) 5906 { 5907 int offset; 5908 rtx reg0 = gen_rtx_REG (Pmode, 0); 5909 rtx regop = operands[store_p], word0 ,word1; 5910 5911 if (GET_CODE (regop) == SUBREG) 5912 alter_subreg (®op); 5913 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1))) 5914 offset = 2; 5915 else 5916 offset = 4; 5917 mem = copy_rtx (mem); 5918 PUT_MODE (mem, SImode); 5919 word0 = gen_rtx_SUBREG (SImode, regop, 0); 5920 alter_subreg (&word0); 5921 word1 = gen_rtx_SUBREG (SImode, regop, 4); 5922 alter_subreg (&word1); 5923 if (store_p || ! refers_to_regno_p (REGNO (word0), 5924 REGNO (word0) + 1, addr, 0)) 5925 { 5926 emit_insn (store_p 5927 ? gen_movsi_ie (mem, word0) 5928 : gen_movsi_ie (word0, mem)); 5929 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset))); 5930 mem = copy_rtx (mem); 5931 emit_insn (store_p 5932 ? gen_movsi_ie (mem, word1) 5933 : gen_movsi_ie (word1, mem)); 5934 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset))); 5935 } 5936 else 5937 { 5938 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset))); 5939 emit_insn (gen_movsi_ie (word1, mem)); 5940 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset))); 5941 mem = copy_rtx (mem); 5942 emit_insn (gen_movsi_ie (word0, mem)); 5943 } 5944 DONE; 5945 } 5946 } 5947}") 5948 5949;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads. 5950(define_split 5951 [(set (match_operand:DF 0 "register_operand" "") 5952 (match_operand:DF 1 "memory_operand" "")) 5953 (use (match_operand:PSI 2 "fpscr_operand" "")) 5954 (clobber (reg:SI R0_REG))] 5955 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed" 5956 [(parallel [(set (match_dup 0) (match_dup 1)) 5957 (use (match_dup 2)) 5958 (clobber (scratch:SI))])] 5959 "") 5960 5961(define_expand "reload_indf__frn" 5962 [(parallel [(set (match_operand:DF 0 "register_operand" "=a") 5963 (match_operand:DF 1 "immediate_operand" "FQ")) 5964 (use (reg:PSI FPSCR_REG)) 5965 (clobber (match_operand:SI 2 "register_operand" "=&z"))])] 5966 "TARGET_SH1" 5967 "") 5968 5969(define_expand "reload_outdf__RnFRm" 5970 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f") 5971 (match_operand:DF 1 "register_operand" "af,r")) 5972 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])] 5973 "TARGET_SH1" 5974 "") 5975 5976;; Simplify no-op moves. 5977(define_split 5978 [(set (match_operand:SF 0 "register_operand" "") 5979 (match_operand:SF 1 "register_operand" "")) 5980 (use (match_operand:PSI 2 "fpscr_operand" "")) 5981 (clobber (match_scratch:SI 3 ""))] 5982 "TARGET_SH2E && reload_completed 5983 && true_regnum (operands[0]) == true_regnum (operands[1])" 5984 [(set (match_dup 0) (match_dup 0))] 5985 "") 5986 5987;; fmovd substitute post-reload splits 5988(define_split 5989 [(set (match_operand:DF 0 "register_operand" "") 5990 (match_operand:DF 1 "register_operand" "")) 5991 (use (match_operand:PSI 2 "fpscr_operand" "")) 5992 (clobber (match_scratch:SI 3 ""))] 5993 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed 5994 && FP_OR_XD_REGISTER_P (true_regnum (operands[0])) 5995 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))" 5996 [(const_int 0)] 5997 " 5998{ 5999 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]); 6000 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst), 6001 gen_rtx_REG (SFmode, src), operands[2])); 6002 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1), 6003 gen_rtx_REG (SFmode, src + 1), operands[2])); 6004 DONE; 6005}") 6006 6007(define_split 6008 [(set (match_operand:DF 0 "register_operand" "") 6009 (mem:DF (match_operand:SI 1 "register_operand" ""))) 6010 (use (match_operand:PSI 2 "fpscr_operand" "")) 6011 (clobber (match_scratch:SI 3 ""))] 6012 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed 6013 && FP_OR_XD_REGISTER_P (true_regnum (operands[0])) 6014 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))" 6015 [(const_int 0)] 6016 " 6017{ 6018 int regno = true_regnum (operands[0]); 6019 rtx insn; 6020 rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0)); 6021 rtx mem2 6022 = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1])); 6023 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, 6024 regno + !! TARGET_LITTLE_ENDIAN), 6025 mem2, operands[2])); 6026 add_reg_note (insn, REG_INC, operands[1]); 6027 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, 6028 regno + ! TARGET_LITTLE_ENDIAN), 6029 change_address (mem, SFmode, NULL_RTX), 6030 operands[2])); 6031 DONE; 6032}") 6033 6034(define_split 6035 [(set (match_operand:DF 0 "register_operand" "") 6036 (match_operand:DF 1 "memory_operand" "")) 6037 (use (match_operand:PSI 2 "fpscr_operand" "")) 6038 (clobber (match_scratch:SI 3 ""))] 6039 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed 6040 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))" 6041 [(const_int 0)] 6042{ 6043 int regno = true_regnum (operands[0]); 6044 rtx addr, insn; 6045 rtx mem2 = change_address (operands[1], SFmode, NULL_RTX); 6046 rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0)); 6047 rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1)); 6048 6049 operands[1] = copy_rtx (mem2); 6050 addr = XEXP (mem2, 0); 6051 6052 switch (GET_CODE (addr)) 6053 { 6054 case REG: 6055 /* This is complicated. If the register is an arithmetic register 6056 we can just fall through to the REG+DISP case below. Otherwise 6057 we have to use a combination of POST_INC and REG addressing... */ 6058 if (! arith_reg_operand (operands[1], SFmode)) 6059 { 6060 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr); 6061 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2])); 6062 add_reg_note (insn, REG_INC, XEXP (addr, 0)); 6063 6064 emit_insn (gen_movsf_ie (reg1, operands[1], operands[2])); 6065 6066 /* If we have modified the stack pointer, the value that we have 6067 read with post-increment might be modified by an interrupt, 6068 so write it back. */ 6069 if (REGNO (XEXP (addr, 0)) == STACK_POINTER_REGNUM) 6070 emit_insn (gen_push_e (reg0)); 6071 else 6072 emit_insn (gen_addsi3 (XEXP (operands[1], 0), XEXP (operands[1], 0), GEN_INT (-4))); 6073 break; 6074 } 6075 /* Fall through. */ 6076 6077 case PLUS: 6078 emit_insn (gen_movsf_ie (reg0, operands[1], operands[2])); 6079 operands[1] = copy_rtx (operands[1]); 6080 XEXP (operands[1], 0) = plus_constant (addr, 4); 6081 emit_insn (gen_movsf_ie (reg1, operands[1], operands[2])); 6082 break; 6083 6084 case POST_INC: 6085 insn = emit_insn (gen_movsf_ie (reg0, operands[1], operands[2])); 6086 add_reg_note (insn, REG_INC, XEXP (addr, 0)); 6087 6088 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2])); 6089 add_reg_note (insn, REG_INC, XEXP (addr, 0)); 6090 break; 6091 6092 default: 6093 debug_rtx (addr); 6094 gcc_unreachable (); 6095 } 6096 6097 DONE; 6098}) 6099 6100(define_split 6101 [(set (match_operand:DF 0 "memory_operand" "") 6102 (match_operand:DF 1 "register_operand" "")) 6103 (use (match_operand:PSI 2 "fpscr_operand" "")) 6104 (clobber (match_scratch:SI 3 ""))] 6105 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed 6106 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))" 6107 [(const_int 0)] 6108{ 6109 int regno = true_regnum (operands[1]); 6110 rtx insn, addr; 6111 rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0)); 6112 rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1)); 6113 6114 operands[0] = copy_rtx (operands[0]); 6115 PUT_MODE (operands[0], SFmode); 6116 addr = XEXP (operands[0], 0); 6117 6118 switch (GET_CODE (addr)) 6119 { 6120 case REG: 6121 /* This is complicated. If the register is an arithmetic register 6122 we can just fall through to the REG+DISP case below. Otherwise 6123 we have to use a combination of REG and PRE_DEC addressing... */ 6124 if (! arith_reg_operand (operands[0], SFmode)) 6125 { 6126 emit_insn (gen_addsi3 (addr, addr, GEN_INT (4))); 6127 emit_insn (gen_movsf_ie (operands[0], reg1, operands[2])); 6128 6129 operands[0] = copy_rtx (operands[0]); 6130 XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr); 6131 6132 insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2])); 6133 add_reg_note (insn, REG_INC, XEXP (addr, 0)); 6134 break; 6135 } 6136 /* Fall through. */ 6137 6138 case PLUS: 6139 /* Since REG+DISP addressing has already been decided upon by gcc 6140 we can rely upon it having chosen an arithmetic register as the 6141 register component of the address. Just emit the lower numbered 6142 register first, to the lower address, then the higher numbered 6143 register to the higher address. */ 6144 emit_insn (gen_movsf_ie (operands[0], reg0, operands[2])); 6145 6146 operands[0] = copy_rtx (operands[0]); 6147 XEXP (operands[0], 0) = plus_constant (addr, 4); 6148 6149 emit_insn (gen_movsf_ie (operands[0], reg1, operands[2])); 6150 break; 6151 6152 case PRE_DEC: 6153 /* This is easy. Output the word to go to the higher address 6154 first (ie the word in the higher numbered register) then the 6155 word to go to the lower address. */ 6156 6157 insn = emit_insn (gen_movsf_ie (operands[0], reg1, operands[2])); 6158 add_reg_note (insn, REG_INC, XEXP (addr, 0)); 6159 6160 insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2])); 6161 add_reg_note (insn, REG_INC, XEXP (addr, 0)); 6162 break; 6163 6164 default: 6165 /* FAIL; */ 6166 debug_rtx (addr); 6167 gcc_unreachable (); 6168 } 6169 6170 DONE; 6171}) 6172 6173;; If the output is a register and the input is memory or a register, we have 6174;; to be careful and see which word needs to be loaded first. 6175 6176(define_split 6177 [(set (match_operand:DF 0 "general_movdst_operand" "") 6178 (match_operand:DF 1 "general_movsrc_operand" ""))] 6179 "TARGET_SH1 && reload_completed" 6180 [(set (match_dup 2) (match_dup 3)) 6181 (set (match_dup 4) (match_dup 5))] 6182 " 6183{ 6184 int regno; 6185 6186 if ((MEM_P (operands[0]) 6187 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) 6188 || (MEM_P (operands[1]) 6189 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)) 6190 FAIL; 6191 6192 switch (GET_CODE (operands[0])) 6193 { 6194 case REG: 6195 regno = REGNO (operands[0]); 6196 break; 6197 case SUBREG: 6198 regno = subreg_regno (operands[0]); 6199 break; 6200 case MEM: 6201 regno = -1; 6202 break; 6203 default: 6204 gcc_unreachable (); 6205 } 6206 6207 if (regno == -1 6208 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0)) 6209 { 6210 operands[2] = operand_subword (operands[0], 0, 0, DFmode); 6211 operands[3] = operand_subword (operands[1], 0, 0, DFmode); 6212 operands[4] = operand_subword (operands[0], 1, 0, DFmode); 6213 operands[5] = operand_subword (operands[1], 1, 0, DFmode); 6214 } 6215 else 6216 { 6217 operands[2] = operand_subword (operands[0], 1, 0, DFmode); 6218 operands[3] = operand_subword (operands[1], 1, 0, DFmode); 6219 operands[4] = operand_subword (operands[0], 0, 0, DFmode); 6220 operands[5] = operand_subword (operands[1], 0, 0, DFmode); 6221 } 6222 6223 if (operands[2] == 0 || operands[3] == 0 6224 || operands[4] == 0 || operands[5] == 0) 6225 FAIL; 6226}") 6227 6228;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is 6229;; used only once, let combine add in the index again. 6230 6231(define_split 6232 [(set (match_operand:SI 0 "register_operand" "") 6233 (match_operand:SI 1 "" "")) 6234 (clobber (match_operand 2 "register_operand" ""))] 6235 "TARGET_SH1 && ! reload_in_progress && ! reload_completed 6236 && ALLOW_INDEXED_ADDRESS" 6237 [(use (reg:SI R0_REG))] 6238 " 6239{ 6240 rtx addr, reg, const_int; 6241 6242 if (!MEM_P (operands[1])) 6243 FAIL; 6244 addr = XEXP (operands[1], 0); 6245 if (GET_CODE (addr) != PLUS) 6246 FAIL; 6247 reg = XEXP (addr, 0); 6248 const_int = XEXP (addr, 1); 6249 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2]) 6250 && CONST_INT_P (const_int))) 6251 FAIL; 6252 emit_move_insn (operands[2], const_int); 6253 emit_move_insn (operands[0], 6254 change_address (operands[1], VOIDmode, 6255 gen_rtx_PLUS (SImode, reg, operands[2]))); 6256 DONE; 6257}") 6258 6259(define_split 6260 [(set (match_operand:SI 1 "" "") 6261 (match_operand:SI 0 "register_operand" "")) 6262 (clobber (match_operand 2 "register_operand" ""))] 6263 "TARGET_SH1 && ! reload_in_progress && ! reload_completed 6264 && ALLOW_INDEXED_ADDRESS" 6265 [(use (reg:SI R0_REG))] 6266 " 6267{ 6268 rtx addr, reg, const_int; 6269 6270 if (!MEM_P (operands[1])) 6271 FAIL; 6272 addr = XEXP (operands[1], 0); 6273 if (GET_CODE (addr) != PLUS) 6274 FAIL; 6275 reg = XEXP (addr, 0); 6276 const_int = XEXP (addr, 1); 6277 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2]) 6278 && CONST_INT_P (const_int))) 6279 FAIL; 6280 emit_move_insn (operands[2], const_int); 6281 emit_move_insn (change_address (operands[1], VOIDmode, 6282 gen_rtx_PLUS (SImode, reg, operands[2])), 6283 operands[0]); 6284 DONE; 6285}") 6286 6287(define_expand "movdf" 6288 [(set (match_operand:DF 0 "general_movdst_operand" "") 6289 (match_operand:DF 1 "general_movsrc_operand" ""))] 6290 "" 6291 " 6292{ 6293 if (prepare_move_operands (operands, DFmode)) DONE; 6294 if (TARGET_SHMEDIA) 6295 { 6296 if (TARGET_SHMEDIA_FPU) 6297 emit_insn (gen_movdf_media (operands[0], operands[1])); 6298 else 6299 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1])); 6300 DONE; 6301 } 6302 if (TARGET_SH4 || TARGET_SH2A_DOUBLE) 6303 { 6304 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ())); 6305 DONE; 6306 } 6307}") 6308 6309;;This is incompatible with the way gcc uses subregs. 6310;;(define_insn "movv2sf_i" 6311;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m") 6312;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))] 6313;; "TARGET_SHMEDIA_FPU 6314;; && (fp_arith_reg_operand (operands[0], V2SFmode) 6315;; || fp_arith_reg_operand (operands[1], V2SFmode))" 6316;; "@ 6317;; # 6318;; fld%M1.p %m1, %0 6319;; fst%M0.p %m0, %1" 6320;; [(set_attr "type" "*,fload_media,fstore_media")]) 6321 6322(define_insn_and_split "movv2sf_i" 6323 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf") 6324 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))] 6325 "TARGET_SHMEDIA_FPU" 6326 "#" 6327 "TARGET_SHMEDIA_FPU && reload_completed" 6328 [(set (match_dup 0) (match_dup 1))] 6329 " 6330{ 6331 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0); 6332 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0); 6333}") 6334 6335(define_expand "movv2sf" 6336 [(set (match_operand:V2SF 0 "general_movdst_operand" "") 6337 (match_operand:V2SF 1 "nonimmediate_operand" ""))] 6338 "TARGET_SHMEDIA_FPU" 6339 " 6340{ 6341 if (prepare_move_operands (operands, V2SFmode)) 6342 DONE; 6343}") 6344 6345(define_expand "addv2sf3" 6346 [(match_operand:V2SF 0 "fp_arith_reg_operand" "") 6347 (match_operand:V2SF 1 "fp_arith_reg_operand" "") 6348 (match_operand:V2SF 2 "fp_arith_reg_operand" "")] 6349 "TARGET_SHMEDIA_FPU" 6350 " 6351{ 6352 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]); 6353 DONE; 6354}") 6355 6356(define_expand "subv2sf3" 6357 [(match_operand:V2SF 0 "fp_arith_reg_operand" "") 6358 (match_operand:V2SF 1 "fp_arith_reg_operand" "") 6359 (match_operand:V2SF 2 "fp_arith_reg_operand" "")] 6360 "TARGET_SHMEDIA_FPU" 6361 " 6362{ 6363 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]); 6364 DONE; 6365}") 6366 6367(define_expand "mulv2sf3" 6368 [(match_operand:V2SF 0 "fp_arith_reg_operand" "") 6369 (match_operand:V2SF 1 "fp_arith_reg_operand" "") 6370 (match_operand:V2SF 2 "fp_arith_reg_operand" "")] 6371 "TARGET_SHMEDIA_FPU" 6372 " 6373{ 6374 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]); 6375 DONE; 6376}") 6377 6378(define_expand "divv2sf3" 6379 [(match_operand:V2SF 0 "fp_arith_reg_operand" "") 6380 (match_operand:V2SF 1 "fp_arith_reg_operand" "") 6381 (match_operand:V2SF 2 "fp_arith_reg_operand" "")] 6382 "TARGET_SHMEDIA_FPU" 6383 " 6384{ 6385 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]); 6386 DONE; 6387}") 6388 6389(define_insn_and_split "*movv4sf_i" 6390 [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf") 6391 (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))] 6392 "TARGET_SHMEDIA_FPU" 6393 "#" 6394 "&& reload_completed" 6395 [(const_int 0)] 6396 " 6397{ 6398 int i; 6399 6400 for (i = 0; i < 4/2; i++) 6401 { 6402 rtx x, y; 6403 6404 if (MEM_P (operands[0])) 6405 x = adjust_address (operands[0], V2SFmode, 6406 i * GET_MODE_SIZE (V2SFmode)); 6407 else 6408 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8); 6409 6410 if (MEM_P (operands[1])) 6411 y = adjust_address (operands[1], V2SFmode, 6412 i * GET_MODE_SIZE (V2SFmode)); 6413 else 6414 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8); 6415 6416 emit_insn (gen_movv2sf_i (x, y)); 6417 } 6418 6419 DONE; 6420}" 6421 [(set_attr "length" "8")]) 6422 6423(define_expand "movv4sf" 6424 [(set (match_operand:V4SF 0 "nonimmediate_operand" "") 6425 (match_operand:V4SF 1 "general_operand" ""))] 6426 "TARGET_SHMEDIA_FPU" 6427 " 6428{ 6429 if (prepare_move_operands (operands, V4SFmode)) 6430 DONE; 6431}") 6432 6433(define_insn_and_split "*movv16sf_i" 6434 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m") 6435 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))] 6436 "TARGET_SHMEDIA_FPU" 6437 "#" 6438 "&& reload_completed" 6439 [(const_int 0)] 6440 " 6441{ 6442 int i; 6443 6444 for (i = 0; i < 16/2; i++) 6445 { 6446 rtx x,y; 6447 6448 if (MEM_P (operands[0])) 6449 x = adjust_address (operands[0], V2SFmode, 6450 i * GET_MODE_SIZE (V2SFmode)); 6451 else 6452 { 6453 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8); 6454 alter_subreg (&x); 6455 } 6456 6457 if (MEM_P (operands[1])) 6458 y = adjust_address (operands[1], V2SFmode, 6459 i * GET_MODE_SIZE (V2SFmode)); 6460 else 6461 { 6462 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8); 6463 alter_subreg (&y); 6464 } 6465 6466 emit_insn (gen_movv2sf_i (x, y)); 6467 } 6468 6469 DONE; 6470}" 6471 [(set_attr "length" "32")]) 6472 6473(define_expand "movv16sf" 6474 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m") 6475 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))] 6476 "TARGET_SHMEDIA_FPU" 6477 " 6478{ 6479 if (prepare_move_operands (operands, V16SFmode)) 6480 DONE; 6481}") 6482 6483(define_insn "movsf_media" 6484 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m") 6485 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))] 6486 "TARGET_SHMEDIA_FPU 6487 && (register_operand (operands[0], SFmode) 6488 || sh_register_operand (operands[1], SFmode))" 6489 "@ 6490 fmov.s %1, %0 6491 fmov.ls %N1, %0 6492 fmov.sl %1, %0 6493 add.l %1, r63, %0 6494 # 6495 fld%M1.s %m1, %0 6496 fst%M0.s %m0, %1 6497 ld%M1.l %m1, %0 6498 st%M0.l %m0, %N1" 6499 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media") 6500 (set (attr "highpart") 6501 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0)) 6502 (const_string "user")] 6503 (const_string "ignore")))]) 6504 6505(define_insn "movsf_media_nofpu" 6506 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m") 6507 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))] 6508 "TARGET_SHMEDIA 6509 && (register_operand (operands[0], SFmode) 6510 || sh_register_operand (operands[1], SFmode))" 6511 "@ 6512 add.l %1, r63, %0 6513 # 6514 ld%M1.l %m1, %0 6515 st%M0.l %m0, %N1" 6516 [(set_attr "type" "arith_media,*,load_media,store_media") 6517 (set (attr "highpart") 6518 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0)) 6519 (const_string "user")] 6520 (const_string "ignore")))]) 6521 6522(define_split 6523 [(set (match_operand:SF 0 "arith_reg_dest" "") 6524 (match_operand:SF 1 "immediate_operand" ""))] 6525 "TARGET_SHMEDIA && reload_completed 6526 && ! FP_REGISTER_P (true_regnum (operands[0]))" 6527 [(set (match_dup 3) (match_dup 2))] 6528 " 6529{ 6530 long values; 6531 REAL_VALUE_TYPE value; 6532 6533 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]); 6534 REAL_VALUE_TO_TARGET_SINGLE (value, values); 6535 operands[2] = GEN_INT (values); 6536 6537 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0])); 6538}") 6539 6540(define_insn "movsf_i" 6541 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r") 6542 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))] 6543 "TARGET_SH1 6544 && (! TARGET_SH2E 6545 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */ 6546 || (REG_P (operands[0]) && REGNO (operands[0]) == 3) 6547 || (REG_P (operands[1]) && REGNO (operands[1]) == 3)) 6548 && (arith_reg_operand (operands[0], SFmode) 6549 || arith_reg_operand (operands[1], SFmode))" 6550 "@ 6551 mov %1,%0 6552 mov #0,%0 6553 mov.l %1,%0 6554 mov.l %1,%0 6555 mov.l %1,%0 6556 lds %1,%0 6557 sts %1,%0" 6558 [(set_attr "type" "move,move,pcload,load,store,move,move")]) 6559 6560;; We may not split the ry/yr/XX alternatives to movsi_ie, since 6561;; update_flow_info would not know where to put REG_EQUAL notes 6562;; when the destination changes mode. 6563(define_insn "movsf_ie" 6564 [(set (match_operand:SF 0 "general_movdst_operand" 6565 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y") 6566 (match_operand:SF 1 "general_movsrc_operand" 6567 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y")) 6568 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c")) 6569 (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))] 6570 6571 "TARGET_SH2E 6572 && (arith_reg_operand (operands[0], SFmode) 6573 || arith_reg_operand (operands[1], SFmode) 6574 || arith_reg_operand (operands[3], SImode) 6575 || (fpul_operand (operands[0], SFmode) 6576 && memory_operand (operands[1], SFmode) 6577 && GET_CODE (XEXP (operands[1], 0)) == POST_INC) 6578 || (fpul_operand (operands[1], SFmode) 6579 && memory_operand (operands[0], SFmode) 6580 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))" 6581 "@ 6582 fmov %1,%0 6583 mov %1,%0 6584 fldi0 %0 6585 fldi1 %0 6586 # 6587 fmov.s %1,%0 6588 fmov.s %1,%0 6589 mov.l %1,%0 6590 mov.l %1,%0 6591 mov.l %1,%0 6592 fsts fpul,%0 6593 flds %1,fpul 6594 lds.l %1,%0 6595 # 6596 sts %1,%0 6597 lds %1,%0 6598 sts.l %1,%0 6599 lds.l %1,%0 6600 ! move optimized away" 6601 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil") 6602 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*") 6603 (set_attr_alternative "length" 6604 [(const_int 2) 6605 (const_int 2) 6606 (const_int 2) 6607 (const_int 2) 6608 (const_int 4) 6609 (if_then_else 6610 (ne (symbol_ref "TARGET_SH2A") (const_int 0)) 6611 (const_int 4) (const_int 2)) 6612 (if_then_else 6613 (ne (symbol_ref "TARGET_SH2A") (const_int 0)) 6614 (const_int 4) (const_int 2)) 6615 (const_int 2) 6616 (if_then_else 6617 (ne (symbol_ref "TARGET_SH2A") (const_int 0)) 6618 (const_int 4) (const_int 2)) 6619 (if_then_else 6620 (ne (symbol_ref "TARGET_SH2A") (const_int 0)) 6621 (const_int 4) (const_int 2)) 6622 (const_int 2) 6623 (const_int 2) 6624 (const_int 2) 6625 (const_int 4) 6626 (const_int 2) 6627 (const_int 2) 6628 (const_int 2) 6629 (const_int 2) 6630 (const_int 0)]) 6631 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes") 6632 (const_string "single") 6633 (const_string "single")))]) 6634 6635(define_split 6636 [(set (match_operand:SF 0 "register_operand" "") 6637 (match_operand:SF 1 "register_operand" "")) 6638 (use (match_operand:PSI 2 "fpscr_operand" "")) 6639 (clobber (reg:SI FPUL_REG))] 6640 "TARGET_SH1" 6641 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1)) 6642 (use (match_dup 2)) 6643 (clobber (scratch:SI))]) 6644 (parallel [(set (match_dup 0) (reg:SF FPUL_REG)) 6645 (use (match_dup 2)) 6646 (clobber (scratch:SI))])] 6647 "") 6648 6649(define_expand "movsf" 6650 [(set (match_operand:SF 0 "general_movdst_operand" "") 6651 (match_operand:SF 1 "general_movsrc_operand" ""))] 6652 "" 6653 " 6654{ 6655 if (prepare_move_operands (operands, SFmode)) 6656 DONE; 6657 if (TARGET_SHMEDIA) 6658 { 6659 if (TARGET_SHMEDIA_FPU) 6660 emit_insn (gen_movsf_media (operands[0], operands[1])); 6661 else 6662 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1])); 6663 DONE; 6664 } 6665 if (TARGET_SH2E) 6666 { 6667 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ())); 6668 DONE; 6669 } 6670}") 6671 6672(define_insn "mov_nop" 6673 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))] 6674 "TARGET_SH2E" 6675 "" 6676 [(set_attr "length" "0") 6677 (set_attr "type" "nil")]) 6678 6679(define_expand "reload_insf__frn" 6680 [(parallel [(set (match_operand:SF 0 "register_operand" "=a") 6681 (match_operand:SF 1 "immediate_operand" "FQ")) 6682 (use (reg:PSI FPSCR_REG)) 6683 (clobber (match_operand:SI 2 "register_operand" "=&z"))])] 6684 "TARGET_SH1" 6685 "") 6686 6687(define_expand "reload_insi__i_fpul" 6688 [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y") 6689 (match_operand:SI 1 "immediate_operand" "i")) 6690 (clobber (match_operand:SI 2 "register_operand" "=&z"))])] 6691 "TARGET_SH1" 6692 "") 6693 6694(define_expand "ptabs" 6695 [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))] 6696 "TARGET_SHMEDIA" 6697 " 6698{ 6699 if (!TARGET_PT_FIXED) 6700 { 6701 rtx eq = operands[1]; 6702 6703 /* ??? For canonical RTL we really should remove any CONST from EQ 6704 before wrapping it in the AND, and finally wrap the EQ into a 6705 const if is constant. However, for reload we must expose the 6706 input register or symbolic constant, and we can't have 6707 different insn structures outside of the operands for different 6708 alternatives of the same pattern. */ 6709 eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)), 6710 GEN_INT (3)); 6711 operands[1] 6712 = (gen_rtx_IF_THEN_ELSE 6713 (PDImode, 6714 eq, 6715 gen_rtx_MEM (PDImode, operands[1]), 6716 gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE, 6717 PDImode, operands[1]))); 6718 } 6719}") 6720 6721;; expanded by ptabs expander. 6722(define_insn "*extendsipdi_media" 6723 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b"); 6724 (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand" 6725 "r,Csy") 6726 (const_int 3)) 6727 (const_int 3)) 6728 (mem:PDI (match_dup 1)) 6729 (sign_extend:PDI (match_dup 1))))] 6730 "TARGET_SHMEDIA && !TARGET_PT_FIXED" 6731 "@ 6732 ptabs %1, %0 6733 pt %1, %0" 6734 [(set_attr "type" "ptabs_media,pt_media") 6735 (set_attr "length" "4,*")]) 6736 6737(define_insn "*truncdipdi_media" 6738 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b"); 6739 (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand" 6740 "r,Csy") 6741 (const_int 3)) 6742 (const_int 3)) 6743 (mem:PDI (match_dup 1)) 6744 (truncate:PDI (match_dup 1))))] 6745 "TARGET_SHMEDIA && !TARGET_PT_FIXED" 6746 "@ 6747 ptabs %1, %0 6748 pt %1, %0" 6749 [(set_attr "type" "ptabs_media,pt_media") 6750 (set_attr "length" "4,*")]) 6751 6752(define_insn "*movsi_y" 6753 [(set (match_operand:SI 0 "register_operand" "=y,y") 6754 (match_operand:SI 1 "immediate_operand" "Qi,I08")) 6755 (clobber (match_scratch:SI 2 "=&z,r"))] 6756 "TARGET_SH2E 6757 && (reload_in_progress || reload_completed)" 6758 "#" 6759 [(set_attr "length" "4") 6760 (set_attr "type" "pcload,move")]) 6761 6762(define_split 6763 [(set (match_operand:SI 0 "register_operand" "") 6764 (match_operand:SI 1 "immediate_operand" "")) 6765 (clobber (match_operand:SI 2 "register_operand" ""))] 6766 "TARGET_SH1" 6767 [(set (match_dup 2) (match_dup 1)) 6768 (set (match_dup 0) (match_dup 2))] 6769 "") 6770 6771(define_split 6772 [(set (match_operand:SI 0 "register_operand" "") 6773 (match_operand:SI 1 "memory_operand" "")) 6774 (clobber (reg:SI R0_REG))] 6775 "TARGET_SH1" 6776 [(set (match_dup 0) (match_dup 1))] 6777 "") 6778 6779;; ------------------------------------------------------------------------ 6780;; Define the real conditional branch instructions. 6781;; ------------------------------------------------------------------------ 6782 6783(define_insn "branch_true" 6784 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0)) 6785 (label_ref (match_operand 0 "" "")) 6786 (pc)))] 6787 "TARGET_SH1" 6788 "* return output_branch (1, insn, operands);" 6789 [(set_attr "type" "cbranch")]) 6790 6791(define_insn "branch_false" 6792 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0)) 6793 (label_ref (match_operand 0 "" "")) 6794 (pc)))] 6795 "TARGET_SH1" 6796 "* return output_branch (0, insn, operands);" 6797 [(set_attr "type" "cbranch")]) 6798 6799;; Patterns to prevent reorg from re-combining a condbranch with a branch 6800;; which destination is too far away. 6801;; The const_int_operand is distinct for each branch target; it avoids 6802;; unwanted matches with redundant_insn. 6803(define_insn "block_branch_redirect" 6804 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))] 6805 "TARGET_SH1" 6806 "" 6807 [(set_attr "length" "0")]) 6808 6809;; This one has the additional purpose to record a possible scratch register 6810;; for the following branch. 6811;; ??? Unfortunately, just setting the scratch register is not good enough, 6812;; because the insn then might be deemed dead and deleted. And we can't 6813;; make the use in the jump insn explicit because that would disable 6814;; delay slot scheduling from the target. 6815(define_insn "indirect_jump_scratch" 6816 [(set (match_operand:SI 0 "register_operand" "=r") 6817 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR)) 6818 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))] 6819 "TARGET_SH1" 6820 "" 6821 [(set_attr "length" "0")]) 6822 6823;; This one is used to preemt an insn from beyond the bra / braf / jmp 6824;; being pulled into the delay slot of a condbranch that has been made to 6825;; jump around the unconditional jump because it was out of range. 6826(define_insn "stuff_delay_slot" 6827 [(set (pc) 6828 (unspec [(match_operand:SI 0 "const_int_operand" "") (pc) 6829 (match_operand:SI 1 "const_int_operand" "")] UNSPEC_BBR))] 6830 "TARGET_SH1" 6831 "" 6832 [(set_attr "length" "0") 6833 (set_attr "cond_delay_slot" "yes")]) 6834 6835;; Conditional branch insns 6836 6837(define_expand "cbranchint4_media" 6838 [(set (pc) 6839 (if_then_else (match_operator 0 "shmedia_cbranch_comparison_operator" 6840 [(match_operand 1 "" "") 6841 (match_operand 2 "" "")]) 6842 (match_operand 3 "" "") 6843 (pc)))] 6844 "TARGET_SHMEDIA" 6845 " 6846{ 6847 enum machine_mode mode = GET_MODE (operands[1]); 6848 if (mode == VOIDmode) 6849 mode = GET_MODE (operands[2]); 6850 if (GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE) 6851 { 6852 operands[1] = force_reg (mode, operands[1]); 6853 if (CONSTANT_P (operands[2]) 6854 && (! satisfies_constraint_I06 (operands[2]))) 6855 operands[2] = force_reg (mode, operands[2]); 6856 } 6857 else 6858 { 6859 if (operands[1] != const0_rtx) 6860 operands[1] = force_reg (mode, operands[1]); 6861 if (operands[2] != const0_rtx) 6862 operands[2] = force_reg (mode, operands[2]); 6863 } 6864 switch (GET_CODE (operands[0])) 6865 { 6866 case LEU: 6867 case LE: 6868 case LTU: 6869 case LT: 6870 operands[0] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[0])), 6871 VOIDmode, operands[2], operands[1]); 6872 operands[1] = XEXP (operands[0], 0); 6873 operands[2] = XEXP (operands[0], 1); 6874 break; 6875 default: 6876 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]), 6877 VOIDmode, operands[1], operands[2]); 6878 break; 6879 } 6880 operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]); 6881}") 6882 6883(define_expand "cbranchfp4_media" 6884 [(set (pc) 6885 (if_then_else (match_operator 0 "sh_float_comparison_operator" 6886 [(match_operand 1 "" "") 6887 (match_operand 2 "" "")]) 6888 (match_operand 3 "" "") 6889 (pc)))] 6890 "TARGET_SHMEDIA" 6891 " 6892{ 6893 rtx tmp = gen_reg_rtx (SImode); 6894 rtx cmp; 6895 if (GET_CODE (operands[0]) == NE) 6896 cmp = gen_rtx_EQ (SImode, operands[1], operands[2]); 6897 else 6898 cmp = gen_rtx_fmt_ee (GET_CODE (operands[0]), SImode, 6899 operands[1], operands[2]); 6900 6901 emit_insn (gen_cstore4_media (tmp, cmp, operands[1], operands[2])); 6902 6903 if (GET_CODE (cmp) == GET_CODE (operands[0])) 6904 operands[0] = gen_rtx_NE (VOIDmode, tmp, const0_rtx); 6905 else 6906 operands[0] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx); 6907 operands[1] = tmp; 6908 operands[2] = const0_rtx; 6909 operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]); 6910}") 6911 6912(define_insn "*beq_media_i" 6913 [(set (pc) 6914 (if_then_else (match_operator 3 "equality_comparison_operator" 6915 [(match_operand:DI 1 "arith_reg_operand" "r,r") 6916 (match_operand:DI 2 "arith_operand" "r,I06")]) 6917 (match_operand 0 "target_operand" "b,b") 6918 (pc)))] 6919 "TARGET_SHMEDIA" 6920 "@ 6921 b%o3%' %1, %2, %0%> 6922 b%o3i%' %1, %2, %0%>" 6923 [(set_attr "type" "cbranch_media")]) 6924 6925(define_insn "*beq_media_i32" 6926 [(set (pc) 6927 (if_then_else (match_operator 3 "equality_comparison_operator" 6928 [(match_operand:SI 1 "arith_reg_operand" "r,r") 6929 (match_operand:SI 2 "arith_operand" "r,I06")]) 6930 (match_operand 0 "target_operand" "b,b") 6931 (pc)))] 6932 "TARGET_SHMEDIA" 6933 "@ 6934 b%o3%' %1, %2, %0%> 6935 b%o3i%' %1, %2, %0%>" 6936 [(set_attr "type" "cbranch_media")]) 6937 6938(define_insn "*bgt_media_i" 6939 [(set (pc) 6940 (if_then_else (match_operator 3 "greater_comparison_operator" 6941 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN") 6942 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")]) 6943 (match_operand 0 "target_operand" "b") 6944 (pc)))] 6945 "TARGET_SHMEDIA" 6946 "b%o3%' %N1, %N2, %0%>" 6947 [(set_attr "type" "cbranch_media")]) 6948 6949(define_insn "*bgt_media_i32" 6950 [(set (pc) 6951 (if_then_else (match_operator 3 "greater_comparison_operator" 6952 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN") 6953 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")]) 6954 (match_operand 0 "target_operand" "b") 6955 (pc)))] 6956 "TARGET_SHMEDIA" 6957 "b%o3%' %N1, %N2, %0%>" 6958 [(set_attr "type" "cbranch_media")]) 6959 6960;; These are only needed to make invert_jump() happy - otherwise, jump 6961;; optimization will be silently disabled. 6962(define_insn "*blt_media_i" 6963 [(set (pc) 6964 (if_then_else (match_operator 3 "less_comparison_operator" 6965 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN") 6966 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")]) 6967 (match_operand 0 "target_operand" "b") 6968 (pc)))] 6969 "TARGET_SHMEDIA" 6970 "b%o3%' %N2, %N1, %0%>" 6971 [(set_attr "type" "cbranch_media")]) 6972 6973(define_insn "*blt_media_i32" 6974 [(set (pc) 6975 (if_then_else (match_operator 3 "less_comparison_operator" 6976 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN") 6977 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")]) 6978 (match_operand 0 "target_operand" "b") 6979 (pc)))] 6980 "TARGET_SHMEDIA" 6981 "b%o3%' %N2, %N1, %0%>" 6982 [(set_attr "type" "cbranch_media")]) 6983 6984;; combiner splitter for test-and-branch on single bit in register. This 6985;; is endian dependent because the non-paradoxical subreg looks different 6986;; on big endian. 6987(define_split 6988 [(set (pc) 6989 (if_then_else 6990 (match_operator 3 "equality_comparison_operator" 6991 [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1 6992 "extend_reg_operand" "") 6993 0) 6994 (const_int 1) 6995 (match_operand 2 6996 "const_int_operand" "")) 0) 6997 (const_int 0)]) 6998 (match_operand 0 "target_operand" "") 6999 (pc))) 7000 (clobber (match_operand:SI 4 "arith_reg_dest" ""))] 7001 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN" 7002 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5))) 7003 (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))] 7004 7005 " 7006{ 7007 operands[5] = GEN_INT (31 - INTVAL (operands[2])); 7008 operands[6] = (GET_CODE (operands[3]) == EQ 7009 ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx) 7010 : gen_rtx_GT (VOIDmode, const0_rtx, operands[4])); 7011}") 7012 7013; operand 0 is the loop count pseudo register 7014; operand 1 is the number of loop iterations or 0 if it is unknown 7015; operand 2 is the maximum number of loop iterations 7016; operand 3 is the number of levels of enclosed loops 7017; operand 4 is the label to jump to at the top of the loop 7018 7019(define_expand "doloop_end" 7020 [(parallel [(set (pc) (if_then_else 7021 (ne:SI (match_operand:SI 0 "" "") 7022 (const_int 1)) 7023 (label_ref (match_operand 4 "" "")) 7024 (pc))) 7025 (set (match_dup 0) 7026 (plus:SI (match_dup 0) (const_int -1))) 7027 (clobber (reg:SI T_REG))])] 7028 "TARGET_SH2" 7029 " 7030{ 7031 if (GET_MODE (operands[0]) != SImode) 7032 FAIL; 7033} 7034") 7035 7036(define_insn_and_split "doloop_end_split" 7037 [(set (pc) 7038 (if_then_else (ne:SI (match_operand:SI 0 "arith_reg_dest" "+r") 7039 (const_int 1)) 7040 (label_ref (match_operand 1 "" "")) 7041 (pc))) 7042 (set (match_dup 0) 7043 (plus (match_dup 0) (const_int -1))) 7044 (clobber (reg:SI T_REG))] 7045 "TARGET_SH2" 7046 "#" 7047 "" 7048 [(parallel [(set (reg:SI T_REG) 7049 (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r") 7050 (const_int 1))) 7051 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]) 7052 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0)) 7053 (label_ref (match_operand 1 "" "")) 7054 (pc)))] 7055"" 7056 [(set_attr "type" "cbranch")]) 7057 7058 7059;; ------------------------------------------------------------------------ 7060;; Jump and linkage insns 7061;; ------------------------------------------------------------------------ 7062 7063(define_insn "jump_compact" 7064 [(set (pc) 7065 (label_ref (match_operand 0 "" "")))] 7066 "TARGET_SH1 && !find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)" 7067 "* 7068{ 7069 /* The length is 16 if the delay slot is unfilled. */ 7070 if (get_attr_length(insn) > 4) 7071 return output_far_jump(insn, operands[0]); 7072 else 7073 return \"bra %l0%#\"; 7074}" 7075 [(set_attr "type" "jump") 7076 (set_attr "needs_delay_slot" "yes")]) 7077 7078;; ??? It would be much saner to explicitly use the scratch register 7079;; in the jump insn, and have indirect_jump_scratch only set it, 7080;; but fill_simple_delay_slots would refuse to do delay slot filling 7081;; from the target then, as it uses simplejump_p. 7082;;(define_insn "jump_compact_far" 7083;; [(set (pc) 7084;; (label_ref (match_operand 0 "" ""))) 7085;; (use (match_operand 1 "register_operand" "r")] 7086;; "TARGET_SH1" 7087;; "* return output_far_jump(insn, operands[0], operands[1]);" 7088;; [(set_attr "type" "jump") 7089;; (set_attr "needs_delay_slot" "yes")]) 7090 7091(define_insn "jump_media" 7092 [(set (pc) 7093 (match_operand 0 "target_operand" "b"))] 7094 "TARGET_SHMEDIA" 7095 "blink %0, r63%>" 7096 [(set_attr "type" "jump_media")]) 7097 7098(define_expand "jump" 7099 [(set (pc) 7100 (label_ref (match_operand 0 "" "")))] 7101 "" 7102 " 7103{ 7104 if (TARGET_SH1) 7105 emit_jump_insn (gen_jump_compact (operands[0])); 7106 else if (TARGET_SHMEDIA) 7107 { 7108 if (reload_in_progress || reload_completed) 7109 FAIL; 7110 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode, 7111 operands[0]))); 7112 } 7113 DONE; 7114}") 7115 7116(define_insn "force_mode_for_call" 7117 [(use (reg:PSI FPSCR_REG))] 7118 "TARGET_SHCOMPACT" 7119 "" 7120 [(set_attr "length" "0") 7121 (set (attr "fp_mode") 7122 (if_then_else (eq_attr "fpu_single" "yes") 7123 (const_string "single") (const_string "double")))]) 7124 7125(define_insn "calli" 7126 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r")) 7127 (match_operand 1 "" "")) 7128 (use (reg:PSI FPSCR_REG)) 7129 (clobber (reg:SI PR_REG))] 7130 "TARGET_SH1" 7131 "* 7132 { 7133 if (TARGET_SH2A && (dbr_sequence_length () == 0)) 7134 return \"jsr/n\\t@%0\"; 7135 else 7136 return \"jsr\\t@%0%#\"; 7137 }" 7138 7139 [(set_attr "type" "call") 7140 (set (attr "fp_mode") 7141 (if_then_else (eq_attr "fpu_single" "yes") 7142 (const_string "single") (const_string "double"))) 7143 (set_attr "needs_delay_slot" "yes") 7144 (set_attr "fp_set" "unknown")]) 7145 7146;; This is TBR relative jump instruction for SH2A architecture. 7147;; Its use is enabled assigning an attribute "function_vector" 7148;; and the vector number to a function during its declaration. 7149 7150(define_insn "calli_tbr_rel" 7151 [(call (mem (match_operand:SI 0 "symbol_ref_operand" "")) 7152 (match_operand 1 "" "")) 7153 (use (reg:PSI FPSCR_REG)) 7154 (clobber (reg:SI PR_REG))] 7155 "TARGET_SH2A && sh2a_is_function_vector_call (operands[0])" 7156 "* 7157{ 7158 unsigned HOST_WIDE_INT vect_num; 7159 vect_num = sh2a_get_function_vector_number (operands[0]); 7160 operands[2] = GEN_INT (vect_num * 4); 7161 7162 return \"jsr/n\\t@@(%O2,tbr)\"; 7163}" 7164 [(set_attr "type" "call") 7165 (set (attr "fp_mode") 7166 (if_then_else (eq_attr "fpu_single" "yes") 7167 (const_string "single") (const_string "double"))) 7168 (set_attr "needs_delay_slot" "no") 7169 (set_attr "fp_set" "unknown")]) 7170 7171;; This is a pc-rel call, using bsrf, for use with PIC. 7172 7173(define_insn "calli_pcrel" 7174 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r")) 7175 (match_operand 1 "" "")) 7176 (use (reg:PSI FPSCR_REG)) 7177 (use (reg:SI PIC_REG)) 7178 (use (match_operand 2 "" "")) 7179 (clobber (reg:SI PR_REG))] 7180 "TARGET_SH2" 7181 "bsrf %0\\n%O2:%#" 7182 [(set_attr "type" "call") 7183 (set (attr "fp_mode") 7184 (if_then_else (eq_attr "fpu_single" "yes") 7185 (const_string "single") (const_string "double"))) 7186 (set_attr "needs_delay_slot" "yes") 7187 (set_attr "fp_set" "unknown")]) 7188 7189(define_insn_and_split "call_pcrel" 7190 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "")) 7191 (match_operand 1 "" "")) 7192 (use (reg:PSI FPSCR_REG)) 7193 (use (reg:SI PIC_REG)) 7194 (clobber (reg:SI PR_REG)) 7195 (clobber (match_scratch:SI 2 "=r"))] 7196 "TARGET_SH2" 7197 "#" 7198 "reload_completed" 7199 [(const_int 0)] 7200 " 7201{ 7202 rtx lab = PATTERN (gen_call_site ()); 7203 7204 if (SYMBOL_REF_LOCAL_P (operands[0])) 7205 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab)); 7206 else 7207 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab)); 7208 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab))); 7209 DONE; 7210}" 7211 [(set_attr "type" "call") 7212 (set (attr "fp_mode") 7213 (if_then_else (eq_attr "fpu_single" "yes") 7214 (const_string "single") (const_string "double"))) 7215 (set_attr "needs_delay_slot" "yes") 7216 (set_attr "fp_set" "unknown")]) 7217 7218(define_insn "call_compact" 7219 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r")) 7220 (match_operand 1 "" "")) 7221 (match_operand 2 "immediate_operand" "n") 7222 (use (reg:SI R0_REG)) 7223 (use (reg:SI R1_REG)) 7224 (use (reg:PSI FPSCR_REG)) 7225 (clobber (reg:SI PR_REG))] 7226 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))" 7227 "jsr @%0%#" 7228 [(set_attr "type" "call") 7229 (set (attr "fp_mode") 7230 (if_then_else (eq_attr "fpu_single" "yes") 7231 (const_string "single") (const_string "double"))) 7232 (set_attr "needs_delay_slot" "yes")]) 7233 7234(define_insn "call_compact_rettramp" 7235 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r")) 7236 (match_operand 1 "" "")) 7237 (match_operand 2 "immediate_operand" "n") 7238 (use (reg:SI R0_REG)) 7239 (use (reg:SI R1_REG)) 7240 (use (reg:PSI FPSCR_REG)) 7241 (clobber (reg:SI R10_REG)) 7242 (clobber (reg:SI PR_REG))] 7243 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))" 7244 "jsr @%0%#" 7245 [(set_attr "type" "call") 7246 (set (attr "fp_mode") 7247 (if_then_else (eq_attr "fpu_single" "yes") 7248 (const_string "single") (const_string "double"))) 7249 (set_attr "needs_delay_slot" "yes")]) 7250 7251(define_insn "call_media" 7252 [(call (mem:DI (match_operand 0 "target_reg_operand" "b")) 7253 (match_operand 1 "" "")) 7254 (clobber (reg:DI PR_MEDIA_REG))] 7255 "TARGET_SHMEDIA" 7256 "blink %0, r18" 7257 [(set_attr "type" "jump_media")]) 7258 7259(define_insn "call_valuei" 7260 [(set (match_operand 0 "" "=rf") 7261 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r")) 7262 (match_operand 2 "" ""))) 7263 (use (reg:PSI FPSCR_REG)) 7264 (clobber (reg:SI PR_REG))] 7265 "TARGET_SH1" 7266 "* 7267 { 7268 if (TARGET_SH2A && (dbr_sequence_length () == 0)) 7269 return \"jsr/n\\t@%1\"; 7270 else 7271 return \"jsr\\t@%1%#\"; 7272 }" 7273 [(set_attr "type" "call") 7274 (set (attr "fp_mode") 7275 (if_then_else (eq_attr "fpu_single" "yes") 7276 (const_string "single") (const_string "double"))) 7277 (set_attr "needs_delay_slot" "yes") 7278 (set_attr "fp_set" "unknown")]) 7279 7280;; This is TBR relative jump instruction for SH2A architecture. 7281;; Its use is enabled assigning an attribute "function_vector" 7282;; and the vector number to a function during its declaration. 7283 7284(define_insn "call_valuei_tbr_rel" 7285 [(set (match_operand 0 "" "=rf") 7286 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "")) 7287 (match_operand 2 "" ""))) 7288 (use (reg:PSI FPSCR_REG)) 7289 (clobber (reg:SI PR_REG))] 7290 "TARGET_SH2A && sh2a_is_function_vector_call (operands[1])" 7291 "* 7292{ 7293 unsigned HOST_WIDE_INT vect_num; 7294 vect_num = sh2a_get_function_vector_number (operands[1]); 7295 operands[3] = GEN_INT (vect_num * 4); 7296 7297 return \"jsr/n\\t@@(%O3,tbr)\"; 7298}" 7299 [(set_attr "type" "call") 7300 (set (attr "fp_mode") 7301 (if_then_else (eq_attr "fpu_single" "yes") 7302 (const_string "single") (const_string "double"))) 7303 (set_attr "needs_delay_slot" "no") 7304 (set_attr "fp_set" "unknown")]) 7305 7306(define_insn "call_valuei_pcrel" 7307 [(set (match_operand 0 "" "=rf") 7308 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r")) 7309 (match_operand 2 "" ""))) 7310 (use (reg:PSI FPSCR_REG)) 7311 (use (reg:SI PIC_REG)) 7312 (use (match_operand 3 "" "")) 7313 (clobber (reg:SI PR_REG))] 7314 "TARGET_SH2" 7315 "bsrf %1\\n%O3:%#" 7316 [(set_attr "type" "call") 7317 (set (attr "fp_mode") 7318 (if_then_else (eq_attr "fpu_single" "yes") 7319 (const_string "single") (const_string "double"))) 7320 (set_attr "needs_delay_slot" "yes") 7321 (set_attr "fp_set" "unknown")]) 7322 7323(define_insn_and_split "call_value_pcrel" 7324 [(set (match_operand 0 "" "=rf") 7325 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "")) 7326 (match_operand 2 "" ""))) 7327 (use (reg:PSI FPSCR_REG)) 7328 (use (reg:SI PIC_REG)) 7329 (clobber (reg:SI PR_REG)) 7330 (clobber (match_scratch:SI 3 "=r"))] 7331 "TARGET_SH2" 7332 "#" 7333 "reload_completed" 7334 [(const_int 0)] 7335 " 7336{ 7337 rtx lab = PATTERN (gen_call_site ()); 7338 7339 if (SYMBOL_REF_LOCAL_P (operands[1])) 7340 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab)); 7341 else 7342 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab)); 7343 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3], 7344 operands[2], copy_rtx (lab))); 7345 DONE; 7346}" 7347 [(set_attr "type" "call") 7348 (set (attr "fp_mode") 7349 (if_then_else (eq_attr "fpu_single" "yes") 7350 (const_string "single") (const_string "double"))) 7351 (set_attr "needs_delay_slot" "yes") 7352 (set_attr "fp_set" "unknown")]) 7353 7354(define_insn "call_value_compact" 7355 [(set (match_operand 0 "" "=rf") 7356 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r")) 7357 (match_operand 2 "" ""))) 7358 (match_operand 3 "immediate_operand" "n") 7359 (use (reg:SI R0_REG)) 7360 (use (reg:SI R1_REG)) 7361 (use (reg:PSI FPSCR_REG)) 7362 (clobber (reg:SI PR_REG))] 7363 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))" 7364 "jsr @%1%#" 7365 [(set_attr "type" "call") 7366 (set (attr "fp_mode") 7367 (if_then_else (eq_attr "fpu_single" "yes") 7368 (const_string "single") (const_string "double"))) 7369 (set_attr "needs_delay_slot" "yes")]) 7370 7371(define_insn "call_value_compact_rettramp" 7372 [(set (match_operand 0 "" "=rf") 7373 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r")) 7374 (match_operand 2 "" ""))) 7375 (match_operand 3 "immediate_operand" "n") 7376 (use (reg:SI R0_REG)) 7377 (use (reg:SI R1_REG)) 7378 (use (reg:PSI FPSCR_REG)) 7379 (clobber (reg:SI R10_REG)) 7380 (clobber (reg:SI PR_REG))] 7381 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))" 7382 "jsr @%1%#" 7383 [(set_attr "type" "call") 7384 (set (attr "fp_mode") 7385 (if_then_else (eq_attr "fpu_single" "yes") 7386 (const_string "single") (const_string "double"))) 7387 (set_attr "needs_delay_slot" "yes")]) 7388 7389(define_insn "call_value_media" 7390 [(set (match_operand 0 "" "=rf") 7391 (call (mem:DI (match_operand 1 "target_reg_operand" "b")) 7392 (match_operand 2 "" ""))) 7393 (clobber (reg:DI PR_MEDIA_REG))] 7394 "TARGET_SHMEDIA" 7395 "blink %1, r18" 7396 [(set_attr "type" "jump_media")]) 7397 7398(define_expand "call" 7399 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" "")) 7400 (match_operand 1 "" "")) 7401 (match_operand 2 "" "") 7402 (use (reg:PSI FPSCR_REG)) 7403 (clobber (reg:SI PR_REG))])] 7404 "" 7405 " 7406{ 7407 if (TARGET_SHMEDIA) 7408 { 7409 operands[0] = shmedia_prepare_call_address (operands[0], 0); 7410 emit_call_insn (gen_call_media (operands[0], operands[1])); 7411 DONE; 7412 } 7413 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2])) 7414 { 7415 rtx cookie_rtx = operands[2]; 7416 long cookie = INTVAL (cookie_rtx); 7417 rtx func = XEXP (operands[0], 0); 7418 rtx r0, r1; 7419 7420 if (flag_pic) 7421 { 7422 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func)) 7423 { 7424 rtx reg = gen_reg_rtx (Pmode); 7425 7426 emit_insn (gen_symGOTPLT2reg (reg, func)); 7427 func = reg; 7428 } 7429 else 7430 func = legitimize_pic_address (func, Pmode, 0); 7431 } 7432 7433 r0 = gen_rtx_REG (SImode, R0_REG); 7434 r1 = gen_rtx_REG (SImode, R1_REG); 7435 7436 /* Since such a call function may use all call-clobbered 7437 registers, we force a mode switch earlier, so that we don't 7438 run out of registers when adjusting fpscr for the call. */ 7439 emit_insn (gen_force_mode_for_call ()); 7440 7441 operands[0] 7442 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\", 7443 SFUNC_GOT); 7444 operands[0] = force_reg (SImode, operands[0]); 7445 7446 emit_move_insn (r0, func); 7447 emit_move_insn (r1, cookie_rtx); 7448 7449 if (cookie & CALL_COOKIE_RET_TRAMP (1)) 7450 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1], 7451 operands[2])); 7452 else 7453 emit_call_insn (gen_call_compact (operands[0], operands[1], 7454 operands[2])); 7455 7456 DONE; 7457 } 7458 else if (TARGET_SHCOMPACT && flag_pic 7459 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF 7460 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0))) 7461 { 7462 rtx reg = gen_reg_rtx (Pmode); 7463 7464 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0))); 7465 XEXP (operands[0], 0) = reg; 7466 } 7467 if (!flag_pic && TARGET_SH2A 7468 && MEM_P (operands[0]) 7469 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF) 7470 { 7471 if (sh2a_is_function_vector_call (XEXP (operands[0], 0))) 7472 { 7473 emit_call_insn (gen_calli_tbr_rel (XEXP (operands[0], 0), 7474 operands[1])); 7475 DONE; 7476 } 7477 } 7478 if (flag_pic && TARGET_SH2 7479 && MEM_P (operands[0]) 7480 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF) 7481 { 7482 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1])); 7483 DONE; 7484 } 7485 else 7486 { 7487 operands[0] = force_reg (SImode, XEXP (operands[0], 0)); 7488 operands[1] = operands[2]; 7489 } 7490 7491 emit_call_insn (gen_calli (operands[0], operands[1])); 7492 DONE; 7493}") 7494 7495(define_insn "call_pop_compact" 7496 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r")) 7497 (match_operand 1 "" "")) 7498 (match_operand 2 "immediate_operand" "n") 7499 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) 7500 (match_operand 3 "immediate_operand" "n"))) 7501 (use (reg:SI R0_REG)) 7502 (use (reg:SI R1_REG)) 7503 (use (reg:PSI FPSCR_REG)) 7504 (clobber (reg:SI PR_REG))] 7505 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))" 7506 "jsr @%0%#" 7507 [(set_attr "type" "call") 7508 (set (attr "fp_mode") 7509 (if_then_else (eq_attr "fpu_single" "yes") 7510 (const_string "single") (const_string "double"))) 7511 (set_attr "needs_delay_slot" "yes")]) 7512 7513(define_insn "call_pop_compact_rettramp" 7514 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r")) 7515 (match_operand 1 "" "")) 7516 (match_operand 2 "immediate_operand" "n") 7517 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) 7518 (match_operand 3 "immediate_operand" "n"))) 7519 (use (reg:SI R0_REG)) 7520 (use (reg:SI R1_REG)) 7521 (use (reg:PSI FPSCR_REG)) 7522 (clobber (reg:SI R10_REG)) 7523 (clobber (reg:SI PR_REG))] 7524 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))" 7525 "jsr @%0%#" 7526 [(set_attr "type" "call") 7527 (set (attr "fp_mode") 7528 (if_then_else (eq_attr "fpu_single" "yes") 7529 (const_string "single") (const_string "double"))) 7530 (set_attr "needs_delay_slot" "yes")]) 7531 7532(define_expand "call_pop" 7533 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" "")) 7534 (match_operand 1 "" "")) 7535 (match_operand 2 "" "") 7536 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) 7537 (match_operand 3 "" "")))])] 7538 "TARGET_SHCOMPACT" 7539 " 7540{ 7541 rtx cookie_rtx; 7542 long cookie; 7543 rtx func; 7544 rtx r0, r1; 7545 7546 gcc_assert (operands[2] && INTVAL (operands[2])); 7547 cookie_rtx = operands[2]; 7548 cookie = INTVAL (cookie_rtx); 7549 func = XEXP (operands[0], 0); 7550 7551 if (flag_pic) 7552 { 7553 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func)) 7554 { 7555 rtx reg = gen_reg_rtx (Pmode); 7556 emit_insn (gen_symGOTPLT2reg (reg, func)); 7557 func = reg; 7558 } 7559 else 7560 func = legitimize_pic_address (func, Pmode, 0); 7561 } 7562 7563 r0 = gen_rtx_REG (SImode, R0_REG); 7564 r1 = gen_rtx_REG (SImode, R1_REG); 7565 7566 /* Since such a call function may use all call-clobbered 7567 registers, we force a mode switch earlier, so that we don't 7568 run out of registers when adjusting fpscr for the call. */ 7569 emit_insn (gen_force_mode_for_call ()); 7570 7571 operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\", 7572 SFUNC_GOT); 7573 operands[0] = force_reg (SImode, operands[0]); 7574 7575 emit_move_insn (r0, func); 7576 emit_move_insn (r1, cookie_rtx); 7577 7578 if (cookie & CALL_COOKIE_RET_TRAMP (1)) 7579 emit_call_insn (gen_call_pop_compact_rettramp 7580 (operands[0], operands[1], operands[2], operands[3])); 7581 else 7582 emit_call_insn (gen_call_pop_compact 7583 (operands[0], operands[1], operands[2], operands[3])); 7584 7585 DONE; 7586}") 7587 7588(define_expand "call_value" 7589 [(parallel [(set (match_operand 0 "arith_reg_operand" "") 7590 (call (mem:SI (match_operand 1 "arith_reg_operand" "")) 7591 (match_operand 2 "" ""))) 7592 (match_operand 3 "" "") 7593 (use (reg:PSI FPSCR_REG)) 7594 (clobber (reg:SI PR_REG))])] 7595 "" 7596 " 7597{ 7598 if (TARGET_SHMEDIA) 7599 { 7600 operands[1] = shmedia_prepare_call_address (operands[1], 0); 7601 emit_call_insn (gen_call_value_media (operands[0], operands[1], 7602 operands[2])); 7603 DONE; 7604 } 7605 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3])) 7606 { 7607 rtx cookie_rtx = operands[3]; 7608 long cookie = INTVAL (cookie_rtx); 7609 rtx func = XEXP (operands[1], 0); 7610 rtx r0, r1; 7611 7612 if (flag_pic) 7613 { 7614 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func)) 7615 { 7616 rtx reg = gen_reg_rtx (Pmode); 7617 7618 emit_insn (gen_symGOTPLT2reg (reg, func)); 7619 func = reg; 7620 } 7621 else 7622 func = legitimize_pic_address (func, Pmode, 0); 7623 } 7624 7625 r0 = gen_rtx_REG (SImode, R0_REG); 7626 r1 = gen_rtx_REG (SImode, R1_REG); 7627 7628 /* Since such a call function may use all call-clobbered 7629 registers, we force a mode switch earlier, so that we don't 7630 run out of registers when adjusting fpscr for the call. */ 7631 emit_insn (gen_force_mode_for_call ()); 7632 7633 operands[1] 7634 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\", 7635 SFUNC_GOT); 7636 operands[1] = force_reg (SImode, operands[1]); 7637 7638 emit_move_insn (r0, func); 7639 emit_move_insn (r1, cookie_rtx); 7640 7641 if (cookie & CALL_COOKIE_RET_TRAMP (1)) 7642 emit_call_insn (gen_call_value_compact_rettramp (operands[0], 7643 operands[1], 7644 operands[2], 7645 operands[3])); 7646 else 7647 emit_call_insn (gen_call_value_compact (operands[0], operands[1], 7648 operands[2], operands[3])); 7649 7650 DONE; 7651 } 7652 else if (TARGET_SHCOMPACT && flag_pic 7653 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF 7654 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0))) 7655 { 7656 rtx reg = gen_reg_rtx (Pmode); 7657 7658 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0))); 7659 XEXP (operands[1], 0) = reg; 7660 } 7661 if (!flag_pic && TARGET_SH2A 7662 && MEM_P (operands[1]) 7663 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF) 7664 { 7665 if (sh2a_is_function_vector_call (XEXP (operands[1], 0))) 7666 { 7667 emit_call_insn (gen_call_valuei_tbr_rel (operands[0], 7668 XEXP (operands[1], 0), operands[2])); 7669 DONE; 7670 } 7671 } 7672 if (flag_pic && TARGET_SH2 7673 && MEM_P (operands[1]) 7674 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF) 7675 { 7676 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0), 7677 operands[2])); 7678 DONE; 7679 } 7680 else 7681 operands[1] = force_reg (SImode, XEXP (operands[1], 0)); 7682 7683 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2])); 7684 DONE; 7685}") 7686 7687(define_insn "sibcalli" 7688 [(call (mem:SI (match_operand:SI 0 "register_operand" "k")) 7689 (match_operand 1 "" "")) 7690 (use (reg:PSI FPSCR_REG)) 7691 (return)] 7692 "TARGET_SH1" 7693 "jmp @%0%#" 7694 [(set_attr "needs_delay_slot" "yes") 7695 (set (attr "fp_mode") 7696 (if_then_else (eq_attr "fpu_single" "yes") 7697 (const_string "single") (const_string "double"))) 7698 (set_attr "type" "jump_ind")]) 7699 7700(define_insn "sibcalli_pcrel" 7701 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k")) 7702 (match_operand 1 "" "")) 7703 (use (match_operand 2 "" "")) 7704 (use (reg:PSI FPSCR_REG)) 7705 (return)] 7706 "TARGET_SH2" 7707 "braf %0\\n%O2:%#" 7708 [(set_attr "needs_delay_slot" "yes") 7709 (set (attr "fp_mode") 7710 (if_then_else (eq_attr "fpu_single" "yes") 7711 (const_string "single") (const_string "double"))) 7712 (set_attr "type" "jump_ind")]) 7713 7714;; This uses an unspec to describe that the symbol_ref is very close. 7715(define_insn "sibcalli_thunk" 7716 [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")] 7717 UNSPEC_THUNK)) 7718 (match_operand 1 "" "")) 7719 (use (reg:PSI FPSCR_REG)) 7720 (return)] 7721 "TARGET_SH1" 7722 "bra %O0" 7723 [(set_attr "needs_delay_slot" "yes") 7724 (set (attr "fp_mode") 7725 (if_then_else (eq_attr "fpu_single" "yes") 7726 (const_string "single") (const_string "double"))) 7727 (set_attr "type" "jump") 7728 (set_attr "length" "2")]) 7729 7730(define_insn_and_split "sibcall_pcrel" 7731 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "")) 7732 (match_operand 1 "" "")) 7733 (use (reg:PSI FPSCR_REG)) 7734 (clobber (match_scratch:SI 2 "=k")) 7735 (return)] 7736 "TARGET_SH2" 7737 "#" 7738 "reload_completed" 7739 [(const_int 0)] 7740 " 7741{ 7742 rtx lab = PATTERN (gen_call_site ()); 7743 rtx call_insn; 7744 7745 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab)); 7746 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1], 7747 copy_rtx (lab))); 7748 SIBLING_CALL_P (call_insn) = 1; 7749 DONE; 7750}" 7751 [(set_attr "needs_delay_slot" "yes") 7752 (set (attr "fp_mode") 7753 (if_then_else (eq_attr "fpu_single" "yes") 7754 (const_string "single") (const_string "double"))) 7755 (set_attr "type" "jump_ind")]) 7756 7757(define_insn "sibcall_compact" 7758 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k")) 7759 (match_operand 1 "" "")) 7760 (return) 7761 (use (match_operand:SI 2 "register_operand" "z,x")) 7762 (use (reg:SI R1_REG)) 7763 (use (reg:PSI FPSCR_REG)) 7764 ;; We want to make sure the `x' above will only match MACH_REG 7765 ;; because sibcall_epilogue may clobber MACL_REG. 7766 (clobber (reg:SI MACL_REG))] 7767 "TARGET_SHCOMPACT" 7768 "@ 7769 jmp @%0%# 7770 jmp @%0\\n sts %2, r0" 7771 [(set_attr "needs_delay_slot" "yes,no") 7772 (set_attr "length" "2,4") 7773 (set (attr "fp_mode") (const_string "single")) 7774 (set_attr "type" "jump_ind")]) 7775 7776(define_insn "sibcall_media" 7777 [(call (mem:DI (match_operand 0 "target_reg_operand" "k")) 7778 (match_operand 1 "" "")) 7779 (use (reg:SI PR_MEDIA_REG)) 7780 (return)] 7781 "TARGET_SHMEDIA" 7782 "blink %0, r63" 7783 [(set_attr "type" "jump_media")]) 7784 7785(define_expand "sibcall" 7786 [(parallel 7787 [(call (mem:SI (match_operand 0 "arith_reg_operand" "")) 7788 (match_operand 1 "" "")) 7789 (match_operand 2 "" "") 7790 (use (reg:PSI FPSCR_REG)) 7791 (return)])] 7792 "" 7793 " 7794{ 7795 if (TARGET_SHMEDIA) 7796 { 7797 operands[0] = shmedia_prepare_call_address (operands[0], 1); 7798 emit_call_insn (gen_sibcall_media (operands[0], operands[1])); 7799 DONE; 7800 } 7801 else if (TARGET_SHCOMPACT && operands[2] 7802 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1))) 7803 { 7804 rtx cookie_rtx = operands[2]; 7805 long cookie = INTVAL (cookie_rtx); 7806 rtx func = XEXP (operands[0], 0); 7807 rtx mach, r1; 7808 7809 if (flag_pic) 7810 { 7811 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func)) 7812 { 7813 rtx reg = gen_reg_rtx (Pmode); 7814 7815 emit_insn (gen_symGOT2reg (reg, func)); 7816 func = reg; 7817 } 7818 else 7819 func = legitimize_pic_address (func, Pmode, 0); 7820 } 7821 7822 /* FIXME: if we could tell whether all argument registers are 7823 already taken, we could decide whether to force the use of 7824 MACH_REG or to stick to R0_REG. Unfortunately, there's no 7825 simple way to tell. We could use the CALL_COOKIE, but we 7826 can't currently tell a register used for regular argument 7827 passing from one that is unused. If we leave it up to reload 7828 to decide which register to use, it seems to always choose 7829 R0_REG, which leaves no available registers in SIBCALL_REGS 7830 to hold the address of the trampoline. */ 7831 mach = gen_rtx_REG (SImode, MACH_REG); 7832 r1 = gen_rtx_REG (SImode, R1_REG); 7833 7834 /* Since such a call function may use all call-clobbered 7835 registers, we force a mode switch earlier, so that we don't 7836 run out of registers when adjusting fpscr for the call. */ 7837 emit_insn (gen_force_mode_for_call ()); 7838 7839 operands[0] 7840 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\", 7841 SFUNC_GOT); 7842 operands[0] = force_reg (SImode, operands[0]); 7843 7844 /* We don't need a return trampoline, since the callee will 7845 return directly to the upper caller. */ 7846 if (cookie & CALL_COOKIE_RET_TRAMP (1)) 7847 { 7848 cookie &= ~ CALL_COOKIE_RET_TRAMP (1); 7849 cookie_rtx = GEN_INT (cookie); 7850 } 7851 7852 emit_move_insn (mach, func); 7853 emit_move_insn (r1, cookie_rtx); 7854 7855 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach)); 7856 DONE; 7857 } 7858 else if (TARGET_SHCOMPACT && flag_pic 7859 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF 7860 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0))) 7861 { 7862 rtx reg = gen_reg_rtx (Pmode); 7863 7864 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0))); 7865 XEXP (operands[0], 0) = reg; 7866 } 7867 if (flag_pic && TARGET_SH2 7868 && MEM_P (operands[0]) 7869 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF 7870 /* The PLT needs the PIC register, but the epilogue would have 7871 to restore it, so we can only use PC-relative PIC calls for 7872 static functions. */ 7873 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0))) 7874 { 7875 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1])); 7876 DONE; 7877 } 7878 else 7879 operands[0] = force_reg (SImode, XEXP (operands[0], 0)); 7880 7881 emit_call_insn (gen_sibcalli (operands[0], operands[1])); 7882 DONE; 7883}") 7884 7885(define_insn "sibcall_valuei" 7886 [(set (match_operand 0 "" "=rf") 7887 (call (mem:SI (match_operand:SI 1 "register_operand" "k")) 7888 (match_operand 2 "" ""))) 7889 (use (reg:PSI FPSCR_REG)) 7890 (return)] 7891 "TARGET_SH1" 7892 "jmp @%1%#" 7893 [(set_attr "needs_delay_slot" "yes") 7894 (set (attr "fp_mode") 7895 (if_then_else (eq_attr "fpu_single" "yes") 7896 (const_string "single") (const_string "double"))) 7897 (set_attr "type" "jump_ind")]) 7898 7899(define_insn "sibcall_valuei_pcrel" 7900 [(set (match_operand 0 "" "=rf") 7901 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k")) 7902 (match_operand 2 "" ""))) 7903 (use (match_operand 3 "" "")) 7904 (use (reg:PSI FPSCR_REG)) 7905 (return)] 7906 "TARGET_SH2" 7907 "braf %1\\n%O3:%#" 7908 [(set_attr "needs_delay_slot" "yes") 7909 (set (attr "fp_mode") 7910 (if_then_else (eq_attr "fpu_single" "yes") 7911 (const_string "single") (const_string "double"))) 7912 (set_attr "type" "jump_ind")]) 7913 7914(define_insn_and_split "sibcall_value_pcrel" 7915 [(set (match_operand 0 "" "=rf") 7916 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "")) 7917 (match_operand 2 "" ""))) 7918 (use (reg:PSI FPSCR_REG)) 7919 (clobber (match_scratch:SI 3 "=k")) 7920 (return)] 7921 "TARGET_SH2" 7922 "#" 7923 "reload_completed" 7924 [(const_int 0)] 7925 " 7926{ 7927 rtx lab = PATTERN (gen_call_site ()); 7928 rtx call_insn; 7929 7930 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab)); 7931 call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0], 7932 operands[3], 7933 operands[2], 7934 copy_rtx (lab))); 7935 SIBLING_CALL_P (call_insn) = 1; 7936 DONE; 7937}" 7938 [(set_attr "needs_delay_slot" "yes") 7939 (set (attr "fp_mode") 7940 (if_then_else (eq_attr "fpu_single" "yes") 7941 (const_string "single") (const_string "double"))) 7942 (set_attr "type" "jump_ind")]) 7943 7944(define_insn "sibcall_value_compact" 7945 [(set (match_operand 0 "" "=rf,rf") 7946 (call (mem:SI (match_operand:SI 1 "register_operand" "k,k")) 7947 (match_operand 2 "" ""))) 7948 (return) 7949 (use (match_operand:SI 3 "register_operand" "z,x")) 7950 (use (reg:SI R1_REG)) 7951 (use (reg:PSI FPSCR_REG)) 7952 ;; We want to make sure the `x' above will only match MACH_REG 7953 ;; because sibcall_epilogue may clobber MACL_REG. 7954 (clobber (reg:SI MACL_REG))] 7955 "TARGET_SHCOMPACT" 7956 "@ 7957 jmp @%1%# 7958 jmp @%1\\n sts %3, r0" 7959 [(set_attr "needs_delay_slot" "yes,no") 7960 (set_attr "length" "2,4") 7961 (set (attr "fp_mode") (const_string "single")) 7962 (set_attr "type" "jump_ind")]) 7963 7964(define_insn "sibcall_value_media" 7965 [(set (match_operand 0 "" "=rf") 7966 (call (mem:DI (match_operand 1 "target_reg_operand" "k")) 7967 (match_operand 2 "" ""))) 7968 (use (reg:SI PR_MEDIA_REG)) 7969 (return)] 7970 "TARGET_SHMEDIA" 7971 "blink %1, r63" 7972 [(set_attr "type" "jump_media")]) 7973 7974(define_expand "sibcall_value" 7975 [(parallel 7976 [(set (match_operand 0 "arith_reg_operand" "") 7977 (call (mem:SI (match_operand 1 "arith_reg_operand" "")) 7978 (match_operand 2 "" ""))) 7979 (match_operand 3 "" "") 7980 (use (reg:PSI FPSCR_REG)) 7981 (return)])] 7982 "" 7983 " 7984{ 7985 if (TARGET_SHMEDIA) 7986 { 7987 operands[1] = shmedia_prepare_call_address (operands[1], 1); 7988 emit_call_insn (gen_sibcall_value_media (operands[0], operands[1], 7989 operands[2])); 7990 DONE; 7991 } 7992 else if (TARGET_SHCOMPACT && operands[3] 7993 && (INTVAL (operands[3]) & ~ CALL_COOKIE_RET_TRAMP (1))) 7994 { 7995 rtx cookie_rtx = operands[3]; 7996 long cookie = INTVAL (cookie_rtx); 7997 rtx func = XEXP (operands[1], 0); 7998 rtx mach, r1; 7999 8000 if (flag_pic) 8001 { 8002 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func)) 8003 { 8004 rtx reg = gen_reg_rtx (Pmode); 8005 8006 emit_insn (gen_symGOT2reg (reg, func)); 8007 func = reg; 8008 } 8009 else 8010 func = legitimize_pic_address (func, Pmode, 0); 8011 } 8012 8013 /* FIXME: if we could tell whether all argument registers are 8014 already taken, we could decide whether to force the use of 8015 MACH_REG or to stick to R0_REG. Unfortunately, there's no 8016 simple way to tell. We could use the CALL_COOKIE, but we 8017 can't currently tell a register used for regular argument 8018 passing from one that is unused. If we leave it up to reload 8019 to decide which register to use, it seems to always choose 8020 R0_REG, which leaves no available registers in SIBCALL_REGS 8021 to hold the address of the trampoline. */ 8022 mach = gen_rtx_REG (SImode, MACH_REG); 8023 r1 = gen_rtx_REG (SImode, R1_REG); 8024 8025 /* Since such a call function may use all call-clobbered 8026 registers, we force a mode switch earlier, so that we don't 8027 run out of registers when adjusting fpscr for the call. */ 8028 emit_insn (gen_force_mode_for_call ()); 8029 8030 operands[1] 8031 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\", 8032 SFUNC_GOT); 8033 operands[1] = force_reg (SImode, operands[1]); 8034 8035 /* We don't need a return trampoline, since the callee will 8036 return directly to the upper caller. */ 8037 if (cookie & CALL_COOKIE_RET_TRAMP (1)) 8038 { 8039 cookie &= ~ CALL_COOKIE_RET_TRAMP (1); 8040 cookie_rtx = GEN_INT (cookie); 8041 } 8042 8043 emit_move_insn (mach, func); 8044 emit_move_insn (r1, cookie_rtx); 8045 8046 emit_call_insn (gen_sibcall_value_compact (operands[0], operands[1], 8047 operands[2], mach)); 8048 DONE; 8049 } 8050 else if (TARGET_SHCOMPACT && flag_pic 8051 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF 8052 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0))) 8053 { 8054 rtx reg = gen_reg_rtx (Pmode); 8055 8056 emit_insn (gen_symGOT2reg (reg, XEXP (operands[1], 0))); 8057 XEXP (operands[1], 0) = reg; 8058 } 8059 if (flag_pic && TARGET_SH2 8060 && MEM_P (operands[1]) 8061 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF 8062 /* The PLT needs the PIC register, but the epilogue would have 8063 to restore it, so we can only use PC-relative PIC calls for 8064 static functions. */ 8065 && SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0))) 8066 { 8067 emit_call_insn (gen_sibcall_value_pcrel (operands[0], 8068 XEXP (operands[1], 0), 8069 operands[2])); 8070 DONE; 8071 } 8072 else 8073 operands[1] = force_reg (SImode, XEXP (operands[1], 0)); 8074 8075 emit_call_insn (gen_sibcall_valuei (operands[0], operands[1], operands[2])); 8076 DONE; 8077}") 8078 8079(define_insn "call_value_pop_compact" 8080 [(set (match_operand 0 "" "=rf") 8081 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r")) 8082 (match_operand 2 "" ""))) 8083 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) 8084 (match_operand 4 "immediate_operand" "n"))) 8085 (match_operand 3 "immediate_operand" "n") 8086 (use (reg:SI R0_REG)) 8087 (use (reg:SI R1_REG)) 8088 (use (reg:PSI FPSCR_REG)) 8089 (clobber (reg:SI PR_REG))] 8090 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))" 8091 "jsr @%1%#" 8092 [(set_attr "type" "call") 8093 (set (attr "fp_mode") 8094 (if_then_else (eq_attr "fpu_single" "yes") 8095 (const_string "single") (const_string "double"))) 8096 (set_attr "needs_delay_slot" "yes")]) 8097 8098(define_insn "call_value_pop_compact_rettramp" 8099 [(set (match_operand 0 "" "=rf") 8100 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r")) 8101 (match_operand 2 "" ""))) 8102 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) 8103 (match_operand 4 "immediate_operand" "n"))) 8104 (match_operand 3 "immediate_operand" "n") 8105 (use (reg:SI R0_REG)) 8106 (use (reg:SI R1_REG)) 8107 (use (reg:PSI FPSCR_REG)) 8108 (clobber (reg:SI R10_REG)) 8109 (clobber (reg:SI PR_REG))] 8110 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))" 8111 "jsr @%1%#" 8112 [(set_attr "type" "call") 8113 (set (attr "fp_mode") 8114 (if_then_else (eq_attr "fpu_single" "yes") 8115 (const_string "single") (const_string "double"))) 8116 (set_attr "needs_delay_slot" "yes")]) 8117 8118(define_expand "call_value_pop" 8119 [(parallel [(set (match_operand 0 "arith_reg_operand" "") 8120 (call (mem:SI (match_operand 1 "arith_reg_operand" "")) 8121 (match_operand 2 "" ""))) 8122 (match_operand 3 "" "") 8123 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) 8124 (match_operand 4 "" "")))])] 8125 "TARGET_SHCOMPACT" 8126 " 8127{ 8128 rtx cookie_rtx; 8129 long cookie; 8130 rtx func; 8131 rtx r0, r1; 8132 8133 gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3])); 8134 cookie_rtx = operands[3]; 8135 cookie = INTVAL (cookie_rtx); 8136 func = XEXP (operands[1], 0); 8137 8138 if (flag_pic) 8139 { 8140 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func)) 8141 { 8142 rtx reg = gen_reg_rtx (Pmode); 8143 8144 emit_insn (gen_symGOTPLT2reg (reg, func)); 8145 func = reg; 8146 } 8147 else 8148 func = legitimize_pic_address (func, Pmode, 0); 8149 } 8150 8151 r0 = gen_rtx_REG (SImode, R0_REG); 8152 r1 = gen_rtx_REG (SImode, R1_REG); 8153 8154 /* Since such a call function may use all call-clobbered 8155 registers, we force a mode switch earlier, so that we don't 8156 run out of registers when adjusting fpscr for the call. */ 8157 emit_insn (gen_force_mode_for_call ()); 8158 8159 operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\", 8160 SFUNC_GOT); 8161 operands[1] = force_reg (SImode, operands[1]); 8162 8163 emit_move_insn (r0, func); 8164 emit_move_insn (r1, cookie_rtx); 8165 8166 if (cookie & CALL_COOKIE_RET_TRAMP (1)) 8167 emit_call_insn (gen_call_value_pop_compact_rettramp 8168 (operands[0], operands[1], operands[2], 8169 operands[3], operands[4])); 8170 else 8171 emit_call_insn (gen_call_value_pop_compact 8172 (operands[0], operands[1], operands[2], 8173 operands[3], operands[4])); 8174 8175 DONE; 8176}") 8177 8178(define_expand "sibcall_epilogue" 8179 [(return)] 8180 "" 8181 " 8182{ 8183 sh_expand_epilogue (1); 8184 if (TARGET_SHCOMPACT) 8185 { 8186 rtx insn, set; 8187 8188 /* If epilogue clobbers r0, preserve it in macl. */ 8189 for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) 8190 if ((set = single_set (insn)) 8191 && REG_P (SET_DEST (set)) 8192 && REGNO (SET_DEST (set)) == R0_REG) 8193 { 8194 rtx r0 = gen_rtx_REG (SImode, R0_REG); 8195 rtx tmp = gen_rtx_REG (SImode, MACL_REG); 8196 8197 /* We can't tell at this point whether the sibcall is a 8198 sibcall_compact and, if it is, whether it uses r0 or 8199 mach as operand 2, so let the instructions that 8200 preserve r0 be optimized away if r0 turns out to be 8201 dead. */ 8202 emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn); 8203 emit_move_insn (r0, tmp); 8204 break; 8205 } 8206 } 8207 DONE; 8208}") 8209 8210(define_insn "indirect_jump_compact" 8211 [(set (pc) 8212 (match_operand:SI 0 "arith_reg_operand" "r"))] 8213 "TARGET_SH1" 8214 "jmp @%0%#" 8215 [(set_attr "needs_delay_slot" "yes") 8216 (set_attr "type" "jump_ind")]) 8217 8218(define_expand "indirect_jump" 8219 [(set (pc) 8220 (match_operand 0 "register_operand" ""))] 8221 "" 8222 " 8223{ 8224 if (GET_MODE (operands[0]) != Pmode) 8225 operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0); 8226}") 8227 8228;; The use of operand 1 / 2 helps us distinguish case table jumps 8229;; which can be present in structured code from indirect jumps which can not 8230;; be present in structured code. This allows -fprofile-arcs to work. 8231 8232;; For SH1 processors. 8233(define_insn "casesi_jump_1" 8234 [(set (pc) 8235 (match_operand:SI 0 "register_operand" "r")) 8236 (use (label_ref (match_operand 1 "" "")))] 8237 "TARGET_SH1" 8238 "jmp @%0%#" 8239 [(set_attr "needs_delay_slot" "yes") 8240 (set_attr "type" "jump_ind")]) 8241 8242;; For all later processors. 8243(define_insn "casesi_jump_2" 8244 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r") 8245 (label_ref (match_operand 1 "" "")))) 8246 (use (label_ref (match_operand 2 "" "")))] 8247 "TARGET_SH2 8248 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)" 8249 "braf %0%#" 8250 [(set_attr "needs_delay_slot" "yes") 8251 (set_attr "type" "jump_ind")]) 8252 8253(define_insn "casesi_jump_media" 8254 [(set (pc) (match_operand 0 "target_reg_operand" "b")) 8255 (use (label_ref (match_operand 1 "" "")))] 8256 "TARGET_SHMEDIA" 8257 "blink %0, r63" 8258 [(set_attr "type" "jump_media")]) 8259 8260;; Call subroutine returning any type. 8261;; ??? This probably doesn't work. 8262 8263(define_expand "untyped_call" 8264 [(parallel [(call (match_operand 0 "" "") 8265 (const_int 0)) 8266 (match_operand 1 "" "") 8267 (match_operand 2 "" "")])] 8268 "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA" 8269 " 8270{ 8271 int i; 8272 8273 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx)); 8274 8275 for (i = 0; i < XVECLEN (operands[2], 0); i++) 8276 { 8277 rtx set = XVECEXP (operands[2], 0, i); 8278 emit_move_insn (SET_DEST (set), SET_SRC (set)); 8279 } 8280 8281 /* The optimizer does not know that the call sets the function value 8282 registers we stored in the result block. We avoid problems by 8283 claiming that all hard registers are used and clobbered at this 8284 point. */ 8285 emit_insn (gen_blockage ()); 8286 8287 DONE; 8288}") 8289 8290;; ------------------------------------------------------------------------ 8291;; Misc insns 8292;; ------------------------------------------------------------------------ 8293 8294(define_insn "dect" 8295 [(set (reg:SI T_REG) 8296 (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r") (const_int 1))) 8297 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))] 8298 "TARGET_SH2" 8299 "dt %0" 8300 [(set_attr "type" "arith")]) 8301 8302(define_insn "nop" 8303 [(const_int 0)] 8304 "" 8305 "nop") 8306 8307;; Load address of a label. This is only generated by the casesi expand, 8308;; and by machine_dependent_reorg (fixing up fp moves). 8309;; This must use unspec, because this only works for labels that are 8310;; within range, 8311 8312(define_insn "mova" 8313 [(set (reg:SI R0_REG) 8314 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))] 8315 "TARGET_SH1" 8316 "mova %O0,r0" 8317 [(set_attr "in_delay_slot" "no") 8318 (set_attr "type" "arith")]) 8319 8320;; machine_dependent_reorg will make this a `mova'. 8321(define_insn "mova_const" 8322 [(set (reg:SI R0_REG) 8323 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))] 8324 "TARGET_SH1" 8325 "#" 8326 [(set_attr "in_delay_slot" "no") 8327 (set_attr "type" "arith")]) 8328 8329(define_expand "GOTaddr2picreg" 8330 [(set (reg:SI R0_REG) 8331 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))] 8332 UNSPEC_MOVA)) 8333 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))) 8334 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))] 8335 "" " 8336{ 8337 if (TARGET_VXWORKS_RTP) 8338 { 8339 rtx gott_base = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE); 8340 rtx gott_index = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX); 8341 emit_insn (gen_vxworks_picreg (gott_base, gott_index)); 8342 DONE; 8343 } 8344 8345 operands[0] = gen_rtx_REG (Pmode, PIC_REG); 8346 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME); 8347 8348 if (TARGET_SHMEDIA) 8349 { 8350 rtx tr = gen_rtx_REG (Pmode, TR0_REG); 8351 rtx pic = operands[0]; 8352 rtx lab = PATTERN (gen_call_site ()); 8353 rtx insn, equiv; 8354 8355 equiv = operands[1]; 8356 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1], lab), 8357 UNSPEC_PCREL_SYMOFF); 8358 operands[1] = gen_rtx_CONST (Pmode, operands[1]); 8359 8360 if (Pmode == SImode) 8361 { 8362 emit_insn (gen_movsi_const (pic, operands[1])); 8363 emit_insn (gen_ptrel_si (tr, pic, copy_rtx (lab))); 8364 } 8365 else 8366 { 8367 emit_insn (gen_movdi_const (pic, operands[1])); 8368 emit_insn (gen_ptrel_di (tr, pic, copy_rtx (lab))); 8369 } 8370 8371 insn = emit_move_insn (operands[0], tr); 8372 8373 set_unique_reg_note (insn, REG_EQUAL, equiv); 8374 8375 DONE; 8376 } 8377} 8378") 8379 8380;; A helper for GOTaddr2picreg to finish up the initialization of the 8381;; PIC register. 8382 8383(define_expand "vxworks_picreg" 8384 [(set (reg:SI PIC_REG) 8385 (const:SI (unspec:SI [(match_operand:SI 0 "" "")] UNSPEC_PIC))) 8386 (set (reg:SI R0_REG) 8387 (const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))) 8388 (set (reg:SI PIC_REG) 8389 (mem:SI (reg:SI PIC_REG))) 8390 (set (reg:SI PIC_REG) 8391 (mem:SI (plus:SI (reg:SI PIC_REG) 8392 (reg:SI R0_REG))))] 8393 "TARGET_VXWORKS_RTP") 8394 8395(define_insn "*ptb" 8396 [(set (match_operand 0 "target_reg_operand" "=b") 8397 (const (unspec [(match_operand 1 "" "Csy")] 8398 UNSPEC_DATALABEL)))] 8399 "TARGET_SHMEDIA && flag_pic 8400 && satisfies_constraint_Csy (operands[1])" 8401 "ptb/u datalabel %1, %0" 8402 [(set_attr "type" "ptabs_media") 8403 (set_attr "length" "*")]) 8404 8405(define_insn "ptrel_si" 8406 [(set (match_operand:SI 0 "target_reg_operand" "=b") 8407 (plus:SI (match_operand:SI 1 "register_operand" "r") 8408 (pc))) 8409 (match_operand:SI 2 "" "")] 8410 "TARGET_SHMEDIA" 8411 "%O2: ptrel/u %1, %0" 8412 [(set_attr "type" "ptabs_media")]) 8413 8414(define_insn "ptrel_di" 8415 [(set (match_operand:DI 0 "target_reg_operand" "=b") 8416 (plus:DI (match_operand:DI 1 "register_operand" "r") 8417 (pc))) 8418 (match_operand:DI 2 "" "")] 8419 "TARGET_SHMEDIA" 8420 "%O2: ptrel/u %1, %0" 8421 [(set_attr "type" "ptabs_media")]) 8422 8423(define_expand "builtin_setjmp_receiver" 8424 [(match_operand 0 "" "")] 8425 "flag_pic" 8426 " 8427{ 8428 emit_insn (gen_GOTaddr2picreg ()); 8429 DONE; 8430}") 8431 8432(define_expand "call_site" 8433 [(unspec [(match_dup 0)] UNSPEC_CALLER)] 8434 "TARGET_SH1" 8435 " 8436{ 8437 static HOST_WIDE_INT i = 0; 8438 operands[0] = GEN_INT (i); 8439 i++; 8440}") 8441 8442;; op0 = op1 + r12 but hide it before reload completed. See the comment 8443;; in symGOT_load expand. 8444 8445(define_insn_and_split "chk_guard_add" 8446 [(set (match_operand:SI 0 "register_operand" "=&r") 8447 (unspec:SI [(match_operand:SI 1 "register_operand" "r") 8448 (reg:SI PIC_REG)] 8449 UNSPEC_CHKADD))] 8450 "TARGET_SH1" 8451 "#" 8452 "TARGET_SH1 && reload_completed" 8453 [(set (match_dup 0) (reg:SI PIC_REG)) 8454 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))] 8455 "" 8456 [(set_attr "type" "arith")]) 8457 8458(define_expand "sym_label2reg" 8459 [(set (match_operand:SI 0 "" "") 8460 (const:SI (unspec:SI [(match_operand:SI 1 "" "") 8461 (const (plus:SI (match_operand:SI 2 "" "") 8462 (const_int 2)))] 8463 UNSPEC_SYMOFF)))] 8464 "TARGET_SH1" "") 8465 8466(define_expand "symGOT_load" 8467 [(set (match_dup 2) (match_operand 1 "" "")) 8468 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG))) 8469 (set (match_operand 0 "" "") (mem (match_dup 3)))] 8470 "" 8471 " 8472{ 8473 rtx insn, mem; 8474 8475 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode); 8476 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode); 8477 8478 if (TARGET_SHMEDIA) 8479 { 8480 rtx reg = operands[2]; 8481 8482 if (Pmode == DImode) 8483 { 8484 if (flag_pic > 1) 8485 emit_insn (gen_movdi_const_32bit (reg, operands[1])); 8486 else 8487 emit_insn (gen_movdi_const_16bit (reg, operands[1])); 8488 } 8489 else 8490 { 8491 if (flag_pic > 1) 8492 emit_insn (gen_movsi_const (reg, operands[1])); 8493 else 8494 emit_insn (gen_movsi_const_16bit (reg, operands[1])); 8495 } 8496 } 8497 else 8498 emit_move_insn (operands[2], operands[1]); 8499 8500 /* When stack protector inserts codes after the result is set to 8501 R0, @(rX, r12) will cause a spill failure for R0. Use a unspec 8502 insn to avoid combining (set A (plus rX r12)) and (set op0 (mem A)) 8503 when rX is a GOT address for the guard symbol. Ugly but doesn't 8504 matter because this is a rare situation. */ 8505 if (!TARGET_SHMEDIA 8506 && flag_stack_protect 8507 && GET_CODE (operands[1]) == CONST 8508 && GET_CODE (XEXP (operands[1], 0)) == UNSPEC 8509 && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF 8510 && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0), 8511 \"__stack_chk_guard\") == 0) 8512 emit_insn (gen_chk_guard_add (operands[3], operands[2])); 8513 else 8514 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode, operands[2], 8515 gen_rtx_REG (Pmode, PIC_REG))); 8516 8517 /* N.B. This is not constant for a GOTPLT relocation. */ 8518 mem = gen_rtx_MEM (Pmode, operands[3]); 8519 MEM_NOTRAP_P (mem) = 1; 8520 /* ??? Should we have a special alias set for the GOT? */ 8521 insn = emit_move_insn (operands[0], mem); 8522 8523 DONE; 8524}") 8525 8526(define_expand "sym2GOT" 8527 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))] 8528 "" 8529 "") 8530 8531(define_expand "symGOT2reg" 8532 [(match_operand 0 "" "") (match_operand 1 "" "")] 8533 "" 8534 " 8535{ 8536 rtx gotsym, insn; 8537 8538 gotsym = gen_sym2GOT (operands[1]); 8539 PUT_MODE (gotsym, Pmode); 8540 insn = emit_insn (gen_symGOT_load (operands[0], gotsym)); 8541 8542 MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1; 8543 8544 DONE; 8545}") 8546 8547(define_expand "symGOTPLT2reg" 8548 [(match_operand 0 "" "") (match_operand 1 "" "")] 8549 "" 8550 " 8551{ 8552 rtx pltsym = gen_rtx_CONST (Pmode, 8553 gen_rtx_UNSPEC (Pmode, 8554 gen_rtvec (1, operands[1]), 8555 UNSPEC_GOTPLT)); 8556 emit_insn (gen_symGOT_load (operands[0], pltsym)); 8557 DONE; 8558}") 8559 8560(define_expand "sym2GOTOFF" 8561 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))] 8562 "" 8563 "") 8564 8565(define_expand "symGOTOFF2reg" 8566 [(match_operand 0 "" "") (match_operand 1 "" "")] 8567 "" 8568 " 8569{ 8570 rtx gotoffsym, insn; 8571 rtx t = (!can_create_pseudo_p () 8572 ? operands[0] 8573 : gen_reg_rtx (GET_MODE (operands[0]))); 8574 8575 gotoffsym = gen_sym2GOTOFF (operands[1]); 8576 PUT_MODE (gotoffsym, Pmode); 8577 emit_move_insn (t, gotoffsym); 8578 insn = emit_move_insn (operands[0], 8579 gen_rtx_PLUS (Pmode, t, 8580 gen_rtx_REG (Pmode, PIC_REG))); 8581 8582 set_unique_reg_note (insn, REG_EQUAL, operands[1]); 8583 8584 DONE; 8585}") 8586 8587(define_expand "symPLT_label2reg" 8588 [(set (match_operand:SI 0 "" "") 8589 (const:SI 8590 (unspec:SI 8591 [(const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT)) 8592 (const:SI (plus:SI (match_operand:SI 2 "" "") 8593 (const_int 2)))] UNSPEC_PCREL_SYMOFF))) 8594 ;; Even though the PIC register is not really used by the call 8595 ;; sequence in which this is expanded, the PLT code assumes the PIC 8596 ;; register is set, so we must not skip its initialization. Since 8597 ;; we only use this expand as part of calling sequences, and never 8598 ;; to take the address of a function, this is the best point to 8599 ;; insert the (use). Using the PLT to take the address of a 8600 ;; function would be wrong, not only because the PLT entry could 8601 ;; then be called from a function that doesn't initialize the PIC 8602 ;; register to the proper GOT, but also because pointers to the 8603 ;; same function might not compare equal, should they be set by 8604 ;; different shared libraries. 8605 (use (reg:SI PIC_REG))] 8606 "TARGET_SH1" 8607 "") 8608 8609(define_expand "sym2PIC" 8610 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))] 8611 "" 8612 "") 8613 8614;; TLS code generation. 8615;; ??? this should be a define_insn_and_split 8616;; See the thread [PATCH/RFA] SH TLS support on gcc-patches 8617;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html> 8618;; for details. 8619 8620(define_insn "tls_global_dynamic" 8621 [(set (match_operand:SI 0 "register_operand" "=&z") 8622 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")] 8623 UNSPEC_TLSGD)) 8624 (const_int 0))) 8625 (use (reg:PSI FPSCR_REG)) 8626 (use (reg:SI PIC_REG)) 8627 (clobber (reg:SI PR_REG)) 8628 (clobber (scratch:SI))] 8629 "TARGET_SH1" 8630 "* 8631{ 8632 return \"\\ 8633mov.l\\t1f,r4\\n\\ 8634\\tmova\\t2f,r0\\n\\ 8635\\tmov.l\\t2f,r1\\n\\ 8636\\tadd\\tr0,r1\\n\\ 8637\\tjsr\\t@r1\\n\\ 8638\\tadd\\tr12,r4\\n\\ 8639\\tbra\\t3f\\n\\ 8640\\tnop\\n\\ 8641\\t.align\\t2\\n\\ 86421:\\t.long\\t%a1@TLSGD\\n\\ 86432:\\t.long\\t__tls_get_addr@PLT\\n\\ 86443:\"; 8645}" 8646 [(set_attr "type" "tls_load") 8647 (set_attr "length" "26")]) 8648 8649(define_insn "tls_local_dynamic" 8650 [(set (match_operand:SI 0 "register_operand" "=&z") 8651 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")] 8652 UNSPEC_TLSLDM)) 8653 (const_int 0))) 8654 (use (reg:PSI FPSCR_REG)) 8655 (use (reg:SI PIC_REG)) 8656 (clobber (reg:SI PR_REG)) 8657 (clobber (scratch:SI))] 8658 "TARGET_SH1" 8659 "* 8660{ 8661 return \"\\ 8662mov.l\\t1f,r4\\n\\ 8663\\tmova\\t2f,r0\\n\\ 8664\\tmov.l\\t2f,r1\\n\\ 8665\\tadd\\tr0,r1\\n\\ 8666\\tjsr\\t@r1\\n\\ 8667\\tadd\\tr12,r4\\n\\ 8668\\tbra\\t3f\\n\\ 8669\\tnop\\n\\ 8670\\t.align\\t2\\n\\ 86711:\\t.long\\t%a1@TLSLDM\\n\\ 86722:\\t.long\\t__tls_get_addr@PLT\\n\\ 86733:\"; 8674}" 8675 [(set_attr "type" "tls_load") 8676 (set_attr "length" "26")]) 8677 8678(define_expand "sym2DTPOFF" 8679 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))] 8680 "" 8681 "") 8682 8683(define_expand "symDTPOFF2reg" 8684 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")] 8685 "" 8686 " 8687{ 8688 rtx dtpoffsym, insn; 8689 rtx t = (!can_create_pseudo_p () 8690 ? operands[0] 8691 : gen_reg_rtx (GET_MODE (operands[0]))); 8692 8693 dtpoffsym = gen_sym2DTPOFF (operands[1]); 8694 PUT_MODE (dtpoffsym, Pmode); 8695 emit_move_insn (t, dtpoffsym); 8696 insn = emit_move_insn (operands[0], 8697 gen_rtx_PLUS (Pmode, t, operands[2])); 8698 DONE; 8699}") 8700 8701(define_expand "sym2GOTTPOFF" 8702 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))] 8703 "" 8704 "") 8705 8706(define_insn "tls_initial_exec" 8707 [(set (match_operand:SI 0 "register_operand" "=&r") 8708 (unspec:SI [(match_operand:SI 1 "" "")] 8709 UNSPEC_TLSIE)) 8710 (use (reg:SI GBR_REG)) 8711 (use (reg:SI PIC_REG)) 8712 (clobber (reg:SI R0_REG))] 8713 "" 8714 "* 8715{ 8716 return \"\\ 8717mov.l\\t1f,r0\\n\\ 8718\\tstc\\tgbr,%0\\n\\ 8719\\tmov.l\\t@(r0,r12),r0\\n\\ 8720\\tbra\\t2f\\n\\ 8721\\tadd\\tr0,%0\\n\\ 8722\\t.align\\t2\\n\\ 87231:\\t.long\\t%a1\\n\\ 87242:\"; 8725}" 8726 [(set_attr "type" "tls_load") 8727 (set_attr "length" "16")]) 8728 8729(define_expand "sym2TPOFF" 8730 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))] 8731 "" 8732 "") 8733 8734(define_expand "symTPOFF2reg" 8735 [(match_operand 0 "" "") (match_operand 1 "" "")] 8736 "" 8737 " 8738{ 8739 rtx tpoffsym, insn; 8740 8741 tpoffsym = gen_sym2TPOFF (operands[1]); 8742 PUT_MODE (tpoffsym, Pmode); 8743 insn = emit_move_insn (operands[0], tpoffsym); 8744 DONE; 8745}") 8746 8747(define_insn "load_gbr" 8748 [(set (match_operand:SI 0 "register_operand" "=r") (reg:SI GBR_REG)) 8749 (use (reg:SI GBR_REG))] 8750 "" 8751 "stc gbr,%0" 8752 [(set_attr "type" "tls_load")]) 8753 8754;; case instruction for switch statements. 8755 8756;; Operand 0 is index 8757;; operand 1 is the minimum bound 8758;; operand 2 is the maximum bound - minimum bound + 1 8759;; operand 3 is CODE_LABEL for the table; 8760;; operand 4 is the CODE_LABEL to go to if index out of range. 8761 8762(define_expand "casesi" 8763 [(match_operand:SI 0 "arith_reg_operand" "") 8764 (match_operand:SI 1 "arith_reg_operand" "") 8765 (match_operand:SI 2 "arith_reg_operand" "") 8766 (match_operand 3 "" "") (match_operand 4 "" "")] 8767 "" 8768 " 8769{ 8770 rtx reg = gen_reg_rtx (SImode); 8771 rtx reg2 = gen_reg_rtx (SImode); 8772 if (TARGET_SHMEDIA) 8773 { 8774 rtx reg = gen_reg_rtx (DImode); 8775 rtx reg2 = gen_reg_rtx (DImode); 8776 rtx reg3 = gen_reg_rtx (Pmode); 8777 rtx reg4 = gen_reg_rtx (Pmode); 8778 rtx reg5 = gen_reg_rtx (Pmode); 8779 rtx load, test; 8780 8781 operands[0] = convert_modes (DImode, SImode, operands[0], 0); 8782 operands[1] = convert_modes (DImode, SImode, operands[1], 0); 8783 operands[2] = convert_modes (DImode, SImode, operands[2], 1); 8784 8785 test = gen_rtx_GT (VOIDmode, operands[1], operands[0]); 8786 emit_jump_insn (gen_cbranchdi4 (test, operands[1], operands[0], operands[4])); 8787 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1])); 8788 test = gen_rtx_GTU (VOIDmode, reg, operands[2]); 8789 emit_jump_insn (gen_cbranchdi4 (test, reg, operands[2], operands[4])); 8790 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3])); 8791 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF 8792 (Pmode, operands[3]))); 8793 /* Messy: can we subreg to clean this up? */ 8794 if (Pmode == DImode) 8795 load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]); 8796 else 8797 load = gen_casesi_load_media (reg4, 8798 gen_rtx_SUBREG (DImode, reg3, 0), 8799 reg2, operands[3]); 8800 PUT_MODE (SET_SRC (load), Pmode); 8801 emit_insn (load); 8802 /* ??? The following add could be eliminated if we used ptrel. */ 8803 emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4)); 8804 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3])); 8805 emit_barrier (); 8806 DONE; 8807 } 8808 operands[1] = copy_to_mode_reg (SImode, operands[1]); 8809 operands[2] = copy_to_mode_reg (SImode, operands[2]); 8810 /* If optimizing, casesi_worker depends on the mode of the instruction 8811 before label it 'uses' - operands[3]. */ 8812 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4], 8813 reg)); 8814 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3])); 8815 if (TARGET_SH2) 8816 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3])); 8817 else 8818 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3])); 8819 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to 8820 operands[3], but to lab. We will fix this up in 8821 machine_dependent_reorg. */ 8822 emit_barrier (); 8823 DONE; 8824}") 8825 8826(define_expand "casesi_0" 8827 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" "")) 8828 (set (match_dup 4) (minus:SI (match_dup 4) 8829 (match_operand:SI 1 "arith_operand" ""))) 8830 (set (reg:SI T_REG) 8831 (gtu:SI (match_dup 4) 8832 (match_operand:SI 2 "arith_reg_operand" ""))) 8833 (set (pc) 8834 (if_then_else (ne (reg:SI T_REG) 8835 (const_int 0)) 8836 (label_ref (match_operand 3 "" "")) 8837 (pc)))] 8838 "TARGET_SH1" 8839 "") 8840 8841;; ??? reload might clobber r0 if we use it explicitly in the RTL before 8842;; reload; using a R0_REGS pseudo reg is likely to give poor code. 8843;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload. 8844 8845(define_insn "casesi_worker_0" 8846 [(set (match_operand:SI 0 "register_operand" "=r,r") 8847 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r") 8848 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI)) 8849 (clobber (match_scratch:SI 3 "=X,1")) 8850 (clobber (match_scratch:SI 4 "=&z,z"))] 8851 "TARGET_SH1" 8852 "#") 8853 8854(define_split 8855 [(set (match_operand:SI 0 "register_operand" "") 8856 (unspec:SI [(match_operand:SI 1 "register_operand" "") 8857 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI)) 8858 (clobber (match_scratch:SI 3 "")) 8859 (clobber (match_scratch:SI 4 ""))] 8860 "TARGET_SH1 && ! TARGET_SH2 && reload_completed" 8861 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA)) 8862 (parallel [(set (match_dup 0) 8863 (unspec:SI [(reg:SI R0_REG) (match_dup 1) 8864 (label_ref (match_dup 2))] UNSPEC_CASESI)) 8865 (clobber (match_dup 3))]) 8866 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))] 8867 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;") 8868 8869(define_split 8870 [(set (match_operand:SI 0 "register_operand" "") 8871 (unspec:SI [(match_operand:SI 1 "register_operand" "") 8872 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI)) 8873 (clobber (match_scratch:SI 3 "")) 8874 (clobber (match_scratch:SI 4 ""))] 8875 "TARGET_SH2 && reload_completed" 8876 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA)) 8877 (parallel [(set (match_dup 0) 8878 (unspec:SI [(reg:SI R0_REG) (match_dup 1) 8879 (label_ref (match_dup 2))] UNSPEC_CASESI)) 8880 (clobber (match_dup 3))])] 8881 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;") 8882 8883(define_insn "casesi_worker_1" 8884 [(set (match_operand:SI 0 "register_operand" "=r,r") 8885 (unspec:SI [(reg:SI R0_REG) 8886 (match_operand:SI 1 "register_operand" "0,r") 8887 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI)) 8888 (clobber (match_scratch:SI 3 "=X,1"))] 8889 "TARGET_SH1" 8890 "* 8891{ 8892 rtx diff_vec = PATTERN (next_real_insn (operands[2])); 8893 8894 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC); 8895 8896 switch (GET_MODE (diff_vec)) 8897 { 8898 case SImode: 8899 return \"shll2 %1\;mov.l @(r0,%1),%0\"; 8900 case HImode: 8901 return \"add %1,%1\;mov.w @(r0,%1),%0\"; 8902 case QImode: 8903 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned) 8904 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\"; 8905 return \"mov.b @(r0,%1),%0\"; 8906 default: 8907 gcc_unreachable (); 8908 } 8909}" 8910 [(set_attr "length" "4")]) 8911 8912(define_insn "casesi_worker_2" 8913 [(set (match_operand:SI 0 "register_operand" "=r,r") 8914 (unspec:SI [(reg:SI R0_REG) 8915 (match_operand:SI 1 "register_operand" "0,r") 8916 (label_ref (match_operand 2 "" "")) 8917 (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI)) 8918 (clobber (match_operand:SI 4 "" "=X,1"))] 8919 "TARGET_SH2 && reload_completed && flag_pic" 8920 "* 8921{ 8922 rtx diff_vec = PATTERN (next_real_insn (operands[2])); 8923 const char *load; 8924 8925 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC); 8926 8927 switch (GET_MODE (diff_vec)) 8928 { 8929 case SImode: 8930 output_asm_insn (\"shll2 %1\", operands); 8931 load = \"mov.l @(r0,%1),%0\"; break; 8932 case HImode: 8933 output_asm_insn (\"add %1,%1\", operands); 8934 load = \"mov.w @(r0,%1),%0\"; break; 8935 case QImode: 8936 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned) 8937 load = \"mov.b @(r0,%1),%0\;extu.b %0,%0\"; 8938 else 8939 load = \"mov.b @(r0,%1),%0\"; 8940 break; 8941 default: 8942 gcc_unreachable (); 8943 } 8944 output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands); 8945 return load; 8946}" 8947 [(set_attr "length" "8")]) 8948 8949(define_insn "casesi_shift_media" 8950 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 8951 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r") 8952 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))] 8953 UNSPEC_CASESI)))] 8954 "TARGET_SHMEDIA" 8955 "* 8956{ 8957 rtx diff_vec = PATTERN (next_real_insn (operands[2])); 8958 8959 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC); 8960 8961 switch (GET_MODE (diff_vec)) 8962 { 8963 case SImode: 8964 return \"shlli %1, 2, %0\"; 8965 case HImode: 8966 return \"shlli %1, 1, %0\"; 8967 case QImode: 8968 if (rtx_equal_p (operands[0], operands[1])) 8969 return \"\"; 8970 return \"add %1, r63, %0\"; 8971 default: 8972 gcc_unreachable (); 8973 } 8974}" 8975 [(set_attr "type" "arith_media")]) 8976 8977(define_insn "casesi_load_media" 8978 [(set (match_operand 0 "any_arith_reg_dest" "=r") 8979 (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r") 8980 (match_operand:DI 2 "arith_reg_operand" "r") 8981 (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))] 8982 "TARGET_SHMEDIA" 8983 "* 8984{ 8985 rtx diff_vec = PATTERN (next_real_insn (operands[3])); 8986 8987 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC); 8988 8989 switch (GET_MODE (diff_vec)) 8990 { 8991 case SImode: 8992 return \"ldx.l %1, %2, %0\"; 8993 case HImode: 8994#if 0 8995 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned) 8996 return \"ldx.uw %1, %2, %0\"; 8997#endif 8998 return \"ldx.w %1, %2, %0\"; 8999 case QImode: 9000 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned) 9001 return \"ldx.ub %1, %2, %0\"; 9002 return \"ldx.b %1, %2, %0\"; 9003 default: 9004 gcc_unreachable (); 9005 } 9006}" 9007 [(set_attr "type" "load_media")]) 9008 9009(define_expand "return" 9010 [(return)] 9011 "reload_completed && ! sh_need_epilogue ()" 9012 " 9013{ 9014 if (TARGET_SHMEDIA) 9015 { 9016 emit_jump_insn (gen_return_media ()); 9017 DONE; 9018 } 9019 9020 if (TARGET_SHCOMPACT 9021 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))) 9022 { 9023 emit_jump_insn (gen_shcompact_return_tramp ()); 9024 DONE; 9025 } 9026}") 9027 9028(define_insn "*return_i" 9029 [(return)] 9030 "TARGET_SH1 && ! (TARGET_SHCOMPACT 9031 && (crtl->args.info.call_cookie 9032 & CALL_COOKIE_RET_TRAMP (1))) 9033 && reload_completed 9034 && lookup_attribute (\"trap_exit\", 9035 DECL_ATTRIBUTES (current_function_decl)) == NULL_TREE" 9036 "* 9037 { 9038 if (TARGET_SH2A && (dbr_sequence_length () == 0) 9039 && !current_function_interrupt) 9040 return \"rts/n\"; 9041 else 9042 return \"%@ %#\"; 9043 }" 9044 [(set_attr "type" "return") 9045 (set_attr "needs_delay_slot" "yes")]) 9046 9047;; trapa has no delay slot. 9048(define_insn "*return_trapa" 9049 [(return)] 9050 "TARGET_SH1 && !TARGET_SHCOMPACT 9051 && reload_completed" 9052 "%@" 9053 [(set_attr "type" "return")]) 9054 9055(define_expand "shcompact_return_tramp" 9056 [(return)] 9057 "TARGET_SHCOMPACT 9058 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))" 9059 " 9060{ 9061 rtx reg = gen_rtx_REG (Pmode, R0_REG); 9062 9063 function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC); 9064 emit_jump_insn (gen_shcompact_return_tramp_i ()); 9065 DONE; 9066}") 9067 9068(define_insn "shcompact_return_tramp_i" 9069 [(parallel [(return) (use (reg:SI R0_REG))])] 9070 "TARGET_SHCOMPACT 9071 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))" 9072 "jmp @r0%#" 9073 [(set_attr "type" "jump_ind") 9074 (set_attr "needs_delay_slot" "yes")]) 9075 9076(define_insn "return_media_i" 9077 [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])] 9078 "TARGET_SHMEDIA && reload_completed" 9079 "blink %0, r63" 9080 [(set_attr "type" "jump_media")]) 9081 9082(define_insn "return_media_rte" 9083 [(return)] 9084 "TARGET_SHMEDIA && reload_completed && current_function_interrupt" 9085 "rte" 9086 [(set_attr "type" "jump_media")]) 9087 9088(define_expand "return_media" 9089 [(return)] 9090 "TARGET_SHMEDIA && reload_completed" 9091 " 9092{ 9093 int tr_regno = sh_media_register_for_return (); 9094 rtx tr; 9095 9096 if (current_function_interrupt) 9097 { 9098 emit_jump_insn (gen_return_media_rte ()); 9099 DONE; 9100 } 9101 if (tr_regno < 0) 9102 { 9103 rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG); 9104 9105 gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]); 9106 tr_regno = TR0_REG; 9107 tr = gen_rtx_REG (Pmode, tr_regno); 9108 emit_move_insn (tr, r18); 9109 } 9110 else 9111 tr = gen_rtx_REG (Pmode, tr_regno); 9112 9113 emit_jump_insn (gen_return_media_i (tr)); 9114 DONE; 9115}") 9116 9117(define_insn "shcompact_preserve_incoming_args" 9118 [(set (match_operand:SI 0 "register_operand" "+r") 9119 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))] 9120 "TARGET_SHCOMPACT" 9121 "" 9122 [(set_attr "length" "0")]) 9123 9124(define_insn "shcompact_incoming_args" 9125 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS)) 9126 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS)) 9127 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS)) 9128 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS)) 9129 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS)) 9130 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS)) 9131 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS)) 9132 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS)) 9133 (set (mem:BLK (reg:SI MACL_REG)) 9134 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS)) 9135 (use (reg:SI R0_REG)) 9136 (clobber (reg:SI R0_REG)) 9137 (clobber (reg:SI MACL_REG)) 9138 (clobber (reg:SI MACH_REG)) 9139 (clobber (reg:SI PR_REG))] 9140 "TARGET_SHCOMPACT" 9141 "jsr @r0%#" 9142 [(set_attr "needs_delay_slot" "yes")]) 9143 9144(define_insn "shmedia_save_restore_regs_compact" 9145 [(set (reg:SI SP_REG) 9146 (plus:SI (reg:SI SP_REG) 9147 (match_operand:SI 0 "immediate_operand" "i"))) 9148 (use (reg:SI R0_REG)) 9149 (clobber (reg:SI PR_REG))] 9150 "TARGET_SHCOMPACT 9151 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST () 9152 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())" 9153 "jsr @r0%#" 9154 [(set_attr "needs_delay_slot" "yes")]) 9155 9156(define_expand "prologue" 9157 [(const_int 0)] 9158 "" 9159 "sh_expand_prologue (); DONE;") 9160 9161(define_expand "epilogue" 9162 [(return)] 9163 "" 9164 " 9165{ 9166 sh_expand_epilogue (0); 9167 emit_jump_insn (gen_return ()); 9168 DONE; 9169}") 9170 9171(define_expand "eh_return" 9172 [(use (match_operand 0 "register_operand" ""))] 9173 "" 9174{ 9175 rtx ra = operands[0]; 9176 9177 if (TARGET_SHMEDIA64) 9178 emit_insn (gen_eh_set_ra_di (ra)); 9179 else 9180 emit_insn (gen_eh_set_ra_si (ra)); 9181 9182 DONE; 9183}) 9184 9185;; Clobber the return address on the stack. We can't expand this 9186;; until we know where it will be put in the stack frame. 9187 9188(define_insn "eh_set_ra_si" 9189 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] 9190 UNSPECV_EH_RETURN) 9191 (clobber (match_scratch:SI 1 "=&r"))] 9192 "! TARGET_SHMEDIA64" 9193 "#") 9194 9195(define_insn "eh_set_ra_di" 9196 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")] 9197 UNSPECV_EH_RETURN) 9198 (clobber (match_scratch:DI 1 "=&r"))] 9199 "TARGET_SHMEDIA64" 9200 "#") 9201 9202(define_split 9203 [(unspec_volatile [(match_operand 0 "register_operand" "")] 9204 UNSPECV_EH_RETURN) 9205 (clobber (match_scratch 1 ""))] 9206 "reload_completed" 9207 [(const_int 0)] 9208 " 9209{ 9210 sh_set_return_address (operands[0], operands[1]); 9211 DONE; 9212}") 9213 9214(define_insn "blockage" 9215 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)] 9216 "" 9217 "" 9218 [(set_attr "length" "0")]) 9219 9220;; ------------------------------------------------------------------------ 9221;; Scc instructions 9222;; ------------------------------------------------------------------------ 9223 9224(define_insn "movt" 9225 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 9226 (eq:SI (reg:SI T_REG) (const_int 1)))] 9227 "TARGET_SH1" 9228 "movt %0" 9229 [(set_attr "type" "arith")]) 9230 9231(define_expand "cstore4_media" 9232 [(set (match_operand:SI 0 "register_operand" "=r") 9233 (match_operator:SI 1 "sh_float_comparison_operator" 9234 [(match_operand 2 "logical_operand" "") 9235 (match_operand 3 "cmp_operand" "")]))] 9236 "TARGET_SHMEDIA" 9237 " 9238{ 9239 enum machine_mode mode = GET_MODE (operands[2]); 9240 enum rtx_code code = GET_CODE (operands[1]); 9241 bool invert, swap; 9242 if (mode == VOIDmode) 9243 mode = GET_MODE (operands[3]); 9244 if (operands[2] == const0_rtx) 9245 { 9246 if (code == EQ || code == NE) 9247 operands[2] = operands[3], operands[3] = const0_rtx; 9248 } 9249 else 9250 operands[2] = force_reg (mode, operands[2]); 9251 if (operands[3] != const0_rtx) 9252 operands[3] = force_reg (mode, operands[3]); 9253 9254 switch (code) 9255 { 9256 case GEU: 9257 case GE: 9258 swap = invert = !FLOAT_MODE_P (mode); 9259 break; 9260 9261 case LEU: 9262 case LE: 9263 swap = FLOAT_MODE_P (mode), invert = !swap; 9264 break; 9265 9266 case LTU: 9267 case LT: 9268 swap = true, invert = false; 9269 break; 9270 9271 case GTU: 9272 case GT: 9273 case EQ: 9274 case UNORDERED: 9275 swap = invert = false; 9276 break; 9277 9278 case NE: 9279 swap = invert = true; 9280 break; 9281 9282 default: 9283 gcc_unreachable (); 9284 } 9285 9286 if (swap) 9287 { 9288 rtx tem = operands[2]; 9289 operands[2] = operands[3]; 9290 operands[3] = tem; 9291 code = swap_condition (code); 9292 } 9293 9294 if (invert) 9295 { 9296 rtx tem = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0]; 9297 code = reverse_condition (code); 9298 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]); 9299 emit_insn (gen_cstore4_media (tem, operands[1], 9300 operands[2], operands[3])); 9301 code = EQ; 9302 operands[2] = tem; 9303 operands[3] = const0_rtx; 9304 } 9305 9306 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]); 9307}") 9308 9309(define_expand "cstoresi4" 9310 [(set (match_operand:SI 0 "register_operand" "=r") 9311 (match_operator:SI 1 "comparison_operator" 9312 [(match_operand:SI 2 "cmpsi_operand" "") 9313 (match_operand:SI 3 "arith_operand" "")]))] 9314 "TARGET_SH1 || TARGET_SHMEDIA" 9315 "if (TARGET_SHMEDIA) 9316 { 9317 emit_insn (gen_cstore4_media (operands[0], operands[1], 9318 operands[2], operands[3])); 9319 DONE; 9320 } 9321 9322 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE) 9323 && sh_expand_t_scc (operands)) 9324 DONE; 9325 9326 if (! currently_expanding_to_rtl) 9327 FAIL; 9328 9329 sh_emit_compare_and_set (operands, SImode); 9330 DONE; 9331") 9332 9333(define_expand "cstoredi4" 9334 [(set (match_operand:SI 0 "register_operand" "=r") 9335 (match_operator:SI 1 "comparison_operator" 9336 [(match_operand:DI 2 "arith_operand" "") 9337 (match_operand:DI 3 "arith_operand" "")]))] 9338 "TARGET_SH2 || TARGET_SHMEDIA" 9339 "if (TARGET_SHMEDIA) 9340 { 9341 emit_insn (gen_cstore4_media (operands[0], operands[1], 9342 operands[2], operands[3])); 9343 DONE; 9344 } 9345 9346 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE) 9347 && sh_expand_t_scc (operands)) 9348 DONE; 9349 9350 if (! currently_expanding_to_rtl) 9351 FAIL; 9352 9353 sh_emit_compare_and_set (operands, DImode); 9354 DONE; 9355") 9356 9357 9358 9359;; sne moves the complement of the T reg to DEST like this: 9360;; cmp/eq ... 9361;; mov #-1,temp 9362;; negc temp,dest 9363;; This is better than xoring compare result with 1 because it does 9364;; not require r0 and further, the -1 may be CSE-ed or lifted out of a 9365;; loop. 9366 9367(define_expand "movnegt" 9368 [(set (match_dup 1) (const_int -1)) 9369 (parallel [(set (match_operand:SI 0 "" "") 9370 (neg:SI (plus:SI (reg:SI T_REG) 9371 (match_dup 1)))) 9372 (set (reg:SI T_REG) 9373 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1)) 9374 (const_int 0)))])] 9375 "" 9376 " 9377{ 9378 operands[1] = gen_reg_rtx (SImode); 9379}") 9380 9381 9382;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1. 9383;; This prevents a regression that occurred when we switched from xor to 9384;; mov/neg for sne. 9385 9386(define_split 9387 [(set (match_operand:SI 0 "arith_reg_dest" "") 9388 (plus:SI (reg:SI T_REG) 9389 (const_int -1)))] 9390 "TARGET_SH1" 9391 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1))) 9392 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))] 9393 "") 9394 9395(define_expand "cstoresf4" 9396 [(set (match_operand:SI 0 "register_operand" "=r") 9397 (match_operator:SI 1 "sh_float_comparison_operator" 9398 [(match_operand:SF 2 "arith_operand" "") 9399 (match_operand:SF 3 "arith_operand" "")]))] 9400 "TARGET_SH2E || TARGET_SHMEDIA_FPU" 9401 "if (TARGET_SHMEDIA) 9402 { 9403 emit_insn (gen_cstore4_media (operands[0], operands[1], 9404 operands[2], operands[3])); 9405 DONE; 9406 } 9407 9408 if (! currently_expanding_to_rtl) 9409 FAIL; 9410 9411 sh_emit_compare_and_set (operands, SFmode); 9412 DONE; 9413") 9414 9415(define_expand "cstoredf4" 9416 [(set (match_operand:SI 0 "register_operand" "=r") 9417 (match_operator:SI 1 "sh_float_comparison_operator" 9418 [(match_operand:DF 2 "arith_operand" "") 9419 (match_operand:DF 3 "arith_operand" "")]))] 9420 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU" 9421 "if (TARGET_SHMEDIA) 9422 { 9423 emit_insn (gen_cstore4_media (operands[0], operands[1], 9424 operands[2], operands[3])); 9425 DONE; 9426 } 9427 9428 if (! currently_expanding_to_rtl) 9429 FAIL; 9430 9431 sh_emit_compare_and_set (operands, DFmode); 9432 DONE; 9433") 9434 9435 9436;; ------------------------------------------------------------------------- 9437;; Instructions to cope with inline literal tables 9438;; ------------------------------------------------------------------------- 9439 9440; 2 byte integer in line 9441 9442(define_insn "consttable_2" 9443 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g") 9444 (match_operand 1 "" "")] 9445 UNSPECV_CONST2)] 9446 "" 9447 "* 9448{ 9449 if (operands[1] != const0_rtx) 9450 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1); 9451 return \"\"; 9452}" 9453 [(set_attr "length" "2") 9454 (set_attr "in_delay_slot" "no")]) 9455 9456; 4 byte integer in line 9457 9458(define_insn "consttable_4" 9459 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g") 9460 (match_operand 1 "" "")] 9461 UNSPECV_CONST4)] 9462 "" 9463 "* 9464{ 9465 if (operands[1] != const0_rtx) 9466 { 9467 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1); 9468 mark_symbol_refs_as_used (operands[0]); 9469 } 9470 return \"\"; 9471}" 9472 [(set_attr "length" "4") 9473 (set_attr "in_delay_slot" "no")]) 9474 9475; 8 byte integer in line 9476 9477(define_insn "consttable_8" 9478 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g") 9479 (match_operand 1 "" "")] 9480 UNSPECV_CONST8)] 9481 "" 9482 "* 9483{ 9484 if (operands[1] != const0_rtx) 9485 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1); 9486 return \"\"; 9487}" 9488 [(set_attr "length" "8") 9489 (set_attr "in_delay_slot" "no")]) 9490 9491; 4 byte floating point 9492 9493(define_insn "consttable_sf" 9494 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g") 9495 (match_operand 1 "" "")] 9496 UNSPECV_CONST4)] 9497 "" 9498 "* 9499{ 9500 if (operands[1] != const0_rtx) 9501 { 9502 REAL_VALUE_TYPE d; 9503 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]); 9504 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode)); 9505 } 9506 return \"\"; 9507}" 9508 [(set_attr "length" "4") 9509 (set_attr "in_delay_slot" "no")]) 9510 9511; 8 byte floating point 9512 9513(define_insn "consttable_df" 9514 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g") 9515 (match_operand 1 "" "")] 9516 UNSPECV_CONST8)] 9517 "" 9518 "* 9519{ 9520 if (operands[1] != const0_rtx) 9521 { 9522 REAL_VALUE_TYPE d; 9523 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]); 9524 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode)); 9525 } 9526 return \"\"; 9527}" 9528 [(set_attr "length" "8") 9529 (set_attr "in_delay_slot" "no")]) 9530 9531;; Alignment is needed for some constant tables; it may also be added for 9532;; Instructions at the start of loops, or after unconditional branches. 9533;; ??? We would get more accurate lengths if we did instruction 9534;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used 9535;; here is too conservative. 9536 9537; align to a two byte boundary 9538 9539(define_expand "align_2" 9540 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)] 9541 "" 9542 "") 9543 9544; align to a four byte boundary 9545;; align_4 and align_log are instructions for the starts of loops, or 9546;; after unconditional branches, which may take up extra room. 9547 9548(define_expand "align_4" 9549 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)] 9550 "" 9551 "") 9552 9553; align to a cache line boundary 9554 9555(define_insn "align_log" 9556 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)] 9557 "" 9558 "" 9559 [(set_attr "length" "0") 9560 (set_attr "in_delay_slot" "no")]) 9561 9562; emitted at the end of the literal table, used to emit the 9563; 32bit branch labels if needed. 9564 9565(define_insn "consttable_end" 9566 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)] 9567 "" 9568 "* return output_jump_label_table ();" 9569 [(set_attr "in_delay_slot" "no")]) 9570 9571; emitted at the end of the window in the literal table. 9572 9573(define_insn "consttable_window_end" 9574 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)] 9575 "" 9576 "" 9577 [(set_attr "length" "0") 9578 (set_attr "in_delay_slot" "no")]) 9579 9580;; ------------------------------------------------------------------------- 9581;; Misc 9582;; ------------------------------------------------------------------------- 9583 9584;; String/block move insn. 9585 9586(define_expand "movmemsi" 9587 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" "")) 9588 (mem:BLK (match_operand:BLK 1 "" ""))) 9589 (use (match_operand:SI 2 "nonmemory_operand" "")) 9590 (use (match_operand:SI 3 "immediate_operand" "")) 9591 (clobber (reg:SI PR_REG)) 9592 (clobber (reg:SI R4_REG)) 9593 (clobber (reg:SI R5_REG)) 9594 (clobber (reg:SI R0_REG))])] 9595 "TARGET_SH1 && ! TARGET_SH5" 9596 " 9597{ 9598 if(expand_block_move (operands)) 9599 DONE; 9600 else FAIL; 9601}") 9602 9603(define_insn "block_move_real" 9604 [(parallel [(set (mem:BLK (reg:SI R4_REG)) 9605 (mem:BLK (reg:SI R5_REG))) 9606 (use (match_operand:SI 0 "arith_reg_operand" "r")) 9607 (clobber (reg:SI PR_REG)) 9608 (clobber (reg:SI R0_REG))])] 9609 "TARGET_SH1 && ! TARGET_HARD_SH4" 9610 "jsr @%0%#" 9611 [(set_attr "type" "sfunc") 9612 (set_attr "needs_delay_slot" "yes")]) 9613 9614(define_insn "block_lump_real" 9615 [(parallel [(set (mem:BLK (reg:SI R4_REG)) 9616 (mem:BLK (reg:SI R5_REG))) 9617 (use (match_operand:SI 0 "arith_reg_operand" "r")) 9618 (use (reg:SI R6_REG)) 9619 (clobber (reg:SI PR_REG)) 9620 (clobber (reg:SI T_REG)) 9621 (clobber (reg:SI R4_REG)) 9622 (clobber (reg:SI R5_REG)) 9623 (clobber (reg:SI R6_REG)) 9624 (clobber (reg:SI R0_REG))])] 9625 "TARGET_SH1 && ! TARGET_HARD_SH4" 9626 "jsr @%0%#" 9627 [(set_attr "type" "sfunc") 9628 (set_attr "needs_delay_slot" "yes")]) 9629 9630(define_insn "block_move_real_i4" 9631 [(parallel [(set (mem:BLK (reg:SI R4_REG)) 9632 (mem:BLK (reg:SI R5_REG))) 9633 (use (match_operand:SI 0 "arith_reg_operand" "r")) 9634 (clobber (reg:SI PR_REG)) 9635 (clobber (reg:SI R0_REG)) 9636 (clobber (reg:SI R1_REG)) 9637 (clobber (reg:SI R2_REG))])] 9638 "TARGET_HARD_SH4" 9639 "jsr @%0%#" 9640 [(set_attr "type" "sfunc") 9641 (set_attr "needs_delay_slot" "yes")]) 9642 9643(define_insn "block_lump_real_i4" 9644 [(parallel [(set (mem:BLK (reg:SI R4_REG)) 9645 (mem:BLK (reg:SI R5_REG))) 9646 (use (match_operand:SI 0 "arith_reg_operand" "r")) 9647 (use (reg:SI R6_REG)) 9648 (clobber (reg:SI PR_REG)) 9649 (clobber (reg:SI T_REG)) 9650 (clobber (reg:SI R4_REG)) 9651 (clobber (reg:SI R5_REG)) 9652 (clobber (reg:SI R6_REG)) 9653 (clobber (reg:SI R0_REG)) 9654 (clobber (reg:SI R1_REG)) 9655 (clobber (reg:SI R2_REG)) 9656 (clobber (reg:SI R3_REG))])] 9657 "TARGET_HARD_SH4" 9658 "jsr @%0%#" 9659 [(set_attr "type" "sfunc") 9660 (set_attr "needs_delay_slot" "yes")]) 9661 9662;; ------------------------------------------------------------------------- 9663;; Floating point instructions. 9664;; ------------------------------------------------------------------------- 9665 9666;; ??? All patterns should have a type attribute. 9667 9668(define_expand "movpsi" 9669 [(set (match_operand:PSI 0 "register_operand" "") 9670 (match_operand:PSI 1 "general_movsrc_operand" ""))] 9671 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)" 9672 "") 9673 9674;; The c / m alternative is a fake to guide reload to load directly into 9675;; fpscr, since reload doesn't know how to use post-increment. 9676;; TARGET_LEGITIMATE_ADDRESS_P guards about bogus addresses before reload, 9677;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's 9678;; predicate after reload. 9679;; The mac_gp type for r/!c might look a bit odd, but it actually schedules 9680;; like a mac -> gpr move. 9681(define_insn "fpu_switch" 9682 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<") 9683 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))] 9684 "TARGET_SH2E 9685 && (! reload_completed 9686 || true_regnum (operands[0]) != FPSCR_REG 9687 || !MEM_P (operands[1]) 9688 || GET_CODE (XEXP (operands[1], 0)) != PLUS)" 9689 "@ 9690 ! precision stays the same 9691 lds.l %1,fpscr 9692 mov.l %1,%0 9693 # 9694 lds %1,fpscr 9695 mov %1,%0 9696 mov.l %1,%0 9697 sts fpscr,%0 9698 sts.l fpscr,%0" 9699 [(set_attr "length" "0,2,2,4,2,2,2,2,2") 9700 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,fstore")]) 9701 9702(define_peephole2 9703 [(set (reg:PSI FPSCR_REG) 9704 (mem:PSI (match_operand:SI 0 "register_operand" "")))] 9705 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])" 9706 [(const_int 0)] 9707{ 9708 rtx fpscr, mem, new_insn; 9709 9710 fpscr = SET_DEST (PATTERN (curr_insn)); 9711 mem = SET_SRC (PATTERN (curr_insn)); 9712 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0])); 9713 9714 new_insn = emit_insn (gen_fpu_switch (fpscr, mem)); 9715 add_reg_note (new_insn, REG_INC, operands[0]); 9716 DONE; 9717}) 9718 9719(define_split 9720 [(set (reg:PSI FPSCR_REG) 9721 (mem:PSI (match_operand:SI 0 "register_operand" "")))] 9722 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) 9723 && (flag_peephole2 ? epilogue_completed : reload_completed)" 9724 [(const_int 0)] 9725{ 9726 rtx fpscr, mem, new_insn; 9727 9728 fpscr = SET_DEST (PATTERN (curr_insn)); 9729 mem = SET_SRC (PATTERN (curr_insn)); 9730 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0])); 9731 9732 new_insn = emit_insn (gen_fpu_switch (fpscr, mem)); 9733 add_reg_note (new_insn, REG_INC, operands[0]); 9734 9735 if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0]))) 9736 emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4))); 9737 DONE; 9738}) 9739 9740;; ??? This uses the fp unit, but has no type indicating that. 9741;; If we did that, this would either give a bogus latency or introduce 9742;; a bogus FIFO constraint. 9743;; Since this insn is currently only used for prologues/epilogues, 9744;; it is probably best to claim no function unit, which matches the 9745;; current setting. 9746(define_insn "toggle_sz" 9747 [(set (reg:PSI FPSCR_REG) 9748 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))] 9749 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)" 9750 "fschg" 9751 [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")]) 9752 9753;; There's no way we can use it today, since optimize mode switching 9754;; doesn't enable us to know from which mode we're switching to the 9755;; mode it requests, to tell whether we can use a relative mode switch 9756;; (like toggle_pr) or an absolute switch (like loading fpscr from 9757;; memory). 9758(define_insn "toggle_pr" 9759 [(set (reg:PSI FPSCR_REG) 9760 (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))] 9761 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE" 9762 "fpchg" 9763 [(set_attr "type" "fpscr_toggle")]) 9764 9765(define_expand "addsf3" 9766 [(set (match_operand:SF 0 "arith_reg_operand" "") 9767 (plus:SF (match_operand:SF 1 "arith_reg_operand" "") 9768 (match_operand:SF 2 "arith_reg_operand" "")))] 9769 "TARGET_SH2E || TARGET_SHMEDIA_FPU" 9770 " 9771{ 9772 if (TARGET_SH2E) 9773 { 9774 expand_sf_binop (&gen_addsf3_i, operands); 9775 DONE; 9776 } 9777}") 9778 9779(define_insn "*addsf3_media" 9780 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f") 9781 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f") 9782 (match_operand:SF 2 "fp_arith_reg_operand" "f")))] 9783 "TARGET_SHMEDIA_FPU" 9784 "fadd.s %1, %2, %0" 9785 [(set_attr "type" "fparith_media")]) 9786 9787(define_insn_and_split "unary_sf_op" 9788 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f") 9789 (vec_select:V2SF 9790 (vec_concat:V2SF 9791 (vec_select:SF 9792 (match_dup 0) 9793 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))])) 9794 (match_operator:SF 2 "unary_float_operator" 9795 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f") 9796 (parallel [(match_operand 4 9797 "const_int_operand" "n")]))])) 9798 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))] 9799 "TARGET_SHMEDIA_FPU" 9800 "#" 9801 "TARGET_SHMEDIA_FPU && reload_completed" 9802 [(set (match_dup 5) (match_dup 6))] 9803 " 9804{ 9805 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1; 9806 rtx op1 = gen_rtx_REG (SFmode, 9807 (true_regnum (operands[1]) 9808 + (INTVAL (operands[4]) ^ endian))); 9809 9810 operands[7] = gen_rtx_REG (SFmode, 9811 (true_regnum (operands[0]) 9812 + (INTVAL (operands[3]) ^ endian))); 9813 operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1); 9814}" 9815 [(set_attr "type" "fparith_media")]) 9816 9817(define_insn_and_split "binary_sf_op0" 9818 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f") 9819 (vec_concat:V2SF 9820 (match_operator:SF 3 "binary_float_operator" 9821 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f") 9822 (parallel [(const_int 0)])) 9823 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f") 9824 (parallel [(const_int 0)]))]) 9825 (vec_select:SF 9826 (match_dup 0) 9827 (parallel [(const_int 1)]))))] 9828 "TARGET_SHMEDIA_FPU" 9829 "#" 9830 "&& reload_completed" 9831 [(set (match_dup 4) (match_dup 5))] 9832 " 9833{ 9834 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1; 9835 rtx op1 = gen_rtx_REG (SFmode, 9836 true_regnum (operands[1]) + endian); 9837 rtx op2 = gen_rtx_REG (SFmode, 9838 true_regnum (operands[2]) + endian); 9839 9840 operands[4] = gen_rtx_REG (SFmode, 9841 true_regnum (operands[0]) + endian); 9842 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2); 9843}" 9844 [(set_attr "type" "fparith_media")]) 9845 9846(define_insn_and_split "binary_sf_op1" 9847 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f") 9848 (vec_concat:V2SF 9849 (vec_select:SF 9850 (match_dup 0) 9851 (parallel [(const_int 0)])) 9852 (match_operator:SF 3 "binary_float_operator" 9853 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f") 9854 (parallel [(const_int 1)])) 9855 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f") 9856 (parallel [(const_int 1)]))])))] 9857 "TARGET_SHMEDIA_FPU" 9858 "#" 9859 "&& reload_completed" 9860 [(set (match_dup 4) (match_dup 5))] 9861 " 9862{ 9863 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1; 9864 rtx op1 = gen_rtx_REG (SFmode, 9865 true_regnum (operands[1]) + (1 ^ endian)); 9866 rtx op2 = gen_rtx_REG (SFmode, 9867 true_regnum (operands[2]) + (1 ^ endian)); 9868 9869 operands[4] = gen_rtx_REG (SFmode, 9870 true_regnum (operands[0]) + (1 ^ endian)); 9871 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2); 9872}" 9873 [(set_attr "type" "fparith_media")]) 9874 9875(define_insn "addsf3_i" 9876 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f") 9877 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0") 9878 (match_operand:SF 2 "fp_arith_reg_operand" "f"))) 9879 (use (match_operand:PSI 3 "fpscr_operand" "c"))] 9880 "TARGET_SH2E" 9881 "fadd %2,%0" 9882 [(set_attr "type" "fp") 9883 (set_attr "fp_mode" "single")]) 9884 9885(define_expand "subsf3" 9886 [(set (match_operand:SF 0 "fp_arith_reg_operand" "") 9887 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "") 9888 (match_operand:SF 2 "fp_arith_reg_operand" "")))] 9889 "TARGET_SH2E || TARGET_SHMEDIA_FPU" 9890 " 9891{ 9892 if (TARGET_SH2E) 9893 { 9894 expand_sf_binop (&gen_subsf3_i, operands); 9895 DONE; 9896 } 9897}") 9898 9899(define_insn "*subsf3_media" 9900 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f") 9901 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f") 9902 (match_operand:SF 2 "fp_arith_reg_operand" "f")))] 9903 "TARGET_SHMEDIA_FPU" 9904 "fsub.s %1, %2, %0" 9905 [(set_attr "type" "fparith_media")]) 9906 9907(define_insn "subsf3_i" 9908 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f") 9909 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0") 9910 (match_operand:SF 2 "fp_arith_reg_operand" "f"))) 9911 (use (match_operand:PSI 3 "fpscr_operand" "c"))] 9912 "TARGET_SH2E" 9913 "fsub %2,%0" 9914 [(set_attr "type" "fp") 9915 (set_attr "fp_mode" "single")]) 9916 9917(define_expand "mulsf3" 9918 [(set (match_operand:SF 0 "fp_arith_reg_operand" "") 9919 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "") 9920 (match_operand:SF 2 "fp_arith_reg_operand" "")))] 9921 "TARGET_SH2E || TARGET_SHMEDIA_FPU" 9922 "") 9923 9924(define_insn "*mulsf3_media" 9925 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f") 9926 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f") 9927 (match_operand:SF 2 "fp_arith_reg_operand" "f")))] 9928 "TARGET_SHMEDIA_FPU" 9929 "fmul.s %1, %2, %0" 9930 [(set_attr "type" "fparith_media")]) 9931 9932;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR 9933;; register in feeding fp instructions. Thus, in order to generate fmac, 9934;; we start out with a mulsf pattern that does not depend on fpscr. 9935;; This is split after combine to introduce the dependency, in order to 9936;; get mode switching and scheduling right. 9937(define_insn_and_split "mulsf3_ie" 9938 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f") 9939 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0") 9940 (match_operand:SF 2 "fp_arith_reg_operand" "f")))] 9941 "TARGET_SH2E" 9942 "fmul %2,%0" 9943 "TARGET_SH4 || TARGET_SH2A_SINGLE" 9944 [(const_int 0)] 9945 " 9946{ 9947 emit_insn (gen_mulsf3_i4 (operands[0], operands[1], operands[2], 9948 get_fpscr_rtx ())); 9949 DONE; 9950}" 9951 [(set_attr "type" "fp")]) 9952 9953(define_insn "mulsf3_i4" 9954 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f") 9955 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0") 9956 (match_operand:SF 2 "fp_arith_reg_operand" "f"))) 9957 (use (match_operand:PSI 3 "fpscr_operand" "c"))] 9958 "TARGET_SH2E" 9959 "fmul %2,%0" 9960 [(set_attr "type" "fp") 9961 (set_attr "fp_mode" "single")]) 9962 9963(define_insn "mac_media" 9964 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f") 9965 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f") 9966 (match_operand:SF 2 "fp_arith_reg_operand" "f")) 9967 (match_operand:SF 3 "fp_arith_reg_operand" "0")))] 9968 "TARGET_SHMEDIA_FPU && TARGET_FMAC" 9969 "fmac.s %1, %2, %0" 9970 [(set_attr "type" "fparith_media")]) 9971 9972(define_insn "*macsf3" 9973 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f") 9974 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w") 9975 (match_operand:SF 2 "fp_arith_reg_operand" "f")) 9976 (match_operand:SF 3 "arith_reg_operand" "0"))) 9977 (use (match_operand:PSI 4 "fpscr_operand" "c"))] 9978 "TARGET_SH2E && TARGET_FMAC" 9979 "fmac fr0,%2,%0" 9980 [(set_attr "type" "fp") 9981 (set_attr "fp_mode" "single")]) 9982 9983(define_expand "divsf3" 9984 [(set (match_operand:SF 0 "arith_reg_operand" "") 9985 (div:SF (match_operand:SF 1 "arith_reg_operand" "") 9986 (match_operand:SF 2 "arith_reg_operand" "")))] 9987 "TARGET_SH2E || TARGET_SHMEDIA_FPU" 9988 " 9989{ 9990 if (TARGET_SH2E) 9991 { 9992 expand_sf_binop (&gen_divsf3_i, operands); 9993 DONE; 9994 } 9995}") 9996 9997(define_insn "*divsf3_media" 9998 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f") 9999 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f") 10000 (match_operand:SF 2 "fp_arith_reg_operand" "f")))] 10001 "TARGET_SHMEDIA_FPU" 10002 "fdiv.s %1, %2, %0" 10003 [(set_attr "type" "fdiv_media")]) 10004 10005(define_insn "divsf3_i" 10006 [(set (match_operand:SF 0 "arith_reg_dest" "=f") 10007 (div:SF (match_operand:SF 1 "arith_reg_operand" "0") 10008 (match_operand:SF 2 "arith_reg_operand" "f"))) 10009 (use (match_operand:PSI 3 "fpscr_operand" "c"))] 10010 "TARGET_SH2E" 10011 "fdiv %2,%0" 10012 [(set_attr "type" "fdiv") 10013 (set_attr "fp_mode" "single")]) 10014 10015(define_insn "floatdisf2" 10016 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f") 10017 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))] 10018 "TARGET_SHMEDIA_FPU" 10019 "float.qs %1, %0" 10020 [(set_attr "type" "fpconv_media")]) 10021 10022(define_expand "floatsisf2" 10023 [(set (match_operand:SF 0 "fp_arith_reg_operand" "") 10024 (float:SF (match_operand:SI 1 "fpul_operand" "")))] 10025 "TARGET_SH2E || TARGET_SHMEDIA_FPU" 10026 " 10027{ 10028 if (TARGET_SH4 || TARGET_SH2A_SINGLE) 10029 { 10030 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ())); 10031 DONE; 10032 } 10033}") 10034 10035(define_insn "*floatsisf2_media" 10036 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f") 10037 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))] 10038 "TARGET_SHMEDIA_FPU" 10039 "float.ls %1, %0" 10040 [(set_attr "type" "fpconv_media")]) 10041 10042(define_insn "floatsisf2_i4" 10043 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f") 10044 (float:SF (match_operand:SI 1 "fpul_operand" "y"))) 10045 (use (match_operand:PSI 2 "fpscr_operand" "c"))] 10046 "(TARGET_SH4 || TARGET_SH2A_SINGLE)" 10047 "float %1,%0" 10048 [(set_attr "type" "fp") 10049 (set_attr "fp_mode" "single")]) 10050 10051(define_insn "*floatsisf2_ie" 10052 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f") 10053 (float:SF (match_operand:SI 1 "fpul_operand" "y")))] 10054 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)" 10055 "float %1,%0" 10056 [(set_attr "type" "fp")]) 10057 10058(define_insn "fix_truncsfdi2" 10059 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f") 10060 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))] 10061 "TARGET_SHMEDIA_FPU" 10062 "ftrc.sq %1, %0" 10063 [(set_attr "type" "fpconv_media")]) 10064 10065(define_expand "fix_truncsfsi2" 10066 [(set (match_operand:SI 0 "fpul_operand" "=y") 10067 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))] 10068 "TARGET_SH2E || TARGET_SHMEDIA_FPU" 10069 " 10070{ 10071 if (TARGET_SH4 || TARGET_SH2A_SINGLE) 10072 { 10073 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ())); 10074 DONE; 10075 } 10076}") 10077 10078(define_insn "*fix_truncsfsi2_media" 10079 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f") 10080 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))] 10081 "TARGET_SHMEDIA_FPU" 10082 "ftrc.sl %1, %0" 10083 [(set_attr "type" "fpconv_media")]) 10084 10085(define_insn "fix_truncsfsi2_i4" 10086 [(set (match_operand:SI 0 "fpul_operand" "=y") 10087 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f"))) 10088 (use (match_operand:PSI 2 "fpscr_operand" "c"))] 10089 "(TARGET_SH4 || TARGET_SH2A_SINGLE)" 10090 "ftrc %1,%0" 10091 [(set_attr "type" "ftrc_s") 10092 (set_attr "fp_mode" "single")]) 10093 10094;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to 10095;; fix_truncsfsi2_i4. 10096;; (define_insn "fix_truncsfsi2_i4_2" 10097;; [(set (match_operand:SI 0 "arith_reg_operand" "=r") 10098;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f"))) 10099;; (use (reg:PSI FPSCR_REG)) 10100;; (clobber (reg:SI FPUL_REG))] 10101;; "TARGET_SH4" 10102;; "#" 10103;; [(set_attr "length" "4") 10104;; (set_attr "fp_mode" "single")]) 10105 10106;;(define_split 10107;; [(set (match_operand:SI 0 "arith_reg_operand" "=r") 10108;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f"))) 10109;; (use (match_operand:PSI 2 "fpscr_operand" "c")) 10110;; (clobber (reg:SI FPUL_REG))] 10111;; "TARGET_SH4" 10112;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1))) 10113;; (use (match_dup 2))]) 10114;; (set (match_dup 0) (reg:SI FPUL_REG))]) 10115 10116(define_insn "*fixsfsi" 10117 [(set (match_operand:SI 0 "fpul_operand" "=y") 10118 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))] 10119 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)" 10120 "ftrc %1,%0" 10121 [(set_attr "type" "fp")]) 10122 10123(define_insn "cmpgtsf_t" 10124 [(set (reg:SI T_REG) 10125 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f") 10126 (match_operand:SF 1 "fp_arith_reg_operand" "f")))] 10127 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)" 10128 "fcmp/gt %1,%0" 10129 [(set_attr "type" "fp_cmp") 10130 (set_attr "fp_mode" "single")]) 10131 10132(define_insn "cmpeqsf_t" 10133 [(set (reg:SI T_REG) 10134 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f") 10135 (match_operand:SF 1 "fp_arith_reg_operand" "f")))] 10136 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)" 10137 "fcmp/eq %1,%0" 10138 [(set_attr "type" "fp_cmp") 10139 (set_attr "fp_mode" "single")]) 10140 10141(define_insn "ieee_ccmpeqsf_t" 10142 [(set (reg:SI T_REG) 10143 (ior:SI (reg:SI T_REG) 10144 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f") 10145 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))] 10146 "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)" 10147 "* return output_ieee_ccmpeq (insn, operands);" 10148 [(set_attr "length" "4")]) 10149 10150 10151(define_insn "cmpgtsf_t_i4" 10152 [(set (reg:SI T_REG) 10153 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f") 10154 (match_operand:SF 1 "fp_arith_reg_operand" "f"))) 10155 (use (match_operand:PSI 2 "fpscr_operand" "c"))] 10156 "(TARGET_SH4 || TARGET_SH2A_SINGLE)" 10157 "fcmp/gt %1,%0" 10158 [(set_attr "type" "fp_cmp") 10159 (set_attr "fp_mode" "single")]) 10160 10161(define_insn "cmpeqsf_t_i4" 10162 [(set (reg:SI T_REG) 10163 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f") 10164 (match_operand:SF 1 "fp_arith_reg_operand" "f"))) 10165 (use (match_operand:PSI 2 "fpscr_operand" "c"))] 10166 "(TARGET_SH4 || TARGET_SH2A_SINGLE)" 10167 "fcmp/eq %1,%0" 10168 [(set_attr "type" "fp_cmp") 10169 (set_attr "fp_mode" "single")]) 10170 10171(define_insn "*ieee_ccmpeqsf_t_4" 10172 [(set (reg:SI T_REG) 10173 (ior:SI (reg:SI T_REG) 10174 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f") 10175 (match_operand:SF 1 "fp_arith_reg_operand" "f")))) 10176 (use (match_operand:PSI 2 "fpscr_operand" "c"))] 10177 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)" 10178 "* return output_ieee_ccmpeq (insn, operands);" 10179 [(set_attr "length" "4") 10180 (set_attr "fp_mode" "single")]) 10181 10182(define_insn "cmpeqsf_media" 10183 [(set (match_operand:SI 0 "register_operand" "=r") 10184 (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f") 10185 (match_operand:SF 2 "fp_arith_reg_operand" "f")))] 10186 "TARGET_SHMEDIA_FPU" 10187 "fcmpeq.s %1, %2, %0" 10188 [(set_attr "type" "fcmp_media")]) 10189 10190(define_insn "cmpgtsf_media" 10191 [(set (match_operand:SI 0 "register_operand" "=r") 10192 (gt:SI (match_operand:SF 1 "fp_arith_reg_operand" "f") 10193 (match_operand:SF 2 "fp_arith_reg_operand" "f")))] 10194 "TARGET_SHMEDIA_FPU" 10195 "fcmpgt.s %1, %2, %0" 10196 [(set_attr "type" "fcmp_media")]) 10197 10198(define_insn "cmpgesf_media" 10199 [(set (match_operand:SI 0 "register_operand" "=r") 10200 (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f") 10201 (match_operand:SF 2 "fp_arith_reg_operand" "f")))] 10202 "TARGET_SHMEDIA_FPU" 10203 "fcmpge.s %1, %2, %0" 10204 [(set_attr "type" "fcmp_media")]) 10205 10206(define_insn "cmpunsf_media" 10207 [(set (match_operand:SI 0 "register_operand" "=r") 10208 (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f") 10209 (match_operand:SF 2 "fp_arith_reg_operand" "f")))] 10210 "TARGET_SHMEDIA_FPU" 10211 "fcmpun.s %1, %2, %0" 10212 [(set_attr "type" "fcmp_media")]) 10213 10214(define_expand "cbranchsf4" 10215 [(set (pc) 10216 (if_then_else (match_operator 0 "sh_float_comparison_operator" 10217 [(match_operand:SF 1 "arith_operand" "") 10218 (match_operand:SF 2 "arith_operand" "")]) 10219 (match_operand 3 "" "") 10220 (pc)))] 10221 "TARGET_SH2E || TARGET_SHMEDIA_FPU" 10222 " 10223{ 10224 if (TARGET_SHMEDIA) 10225 emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2], 10226 operands[3])); 10227 else 10228 sh_emit_compare_and_branch (operands, SFmode); 10229 DONE; 10230}") 10231 10232(define_expand "negsf2" 10233 [(set (match_operand:SF 0 "fp_arith_reg_operand" "") 10234 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))] 10235 "TARGET_SH2E || TARGET_SHMEDIA_FPU" 10236 " 10237{ 10238 if (TARGET_SH2E) 10239 { 10240 expand_sf_unop (&gen_negsf2_i, operands); 10241 DONE; 10242 } 10243}") 10244 10245(define_insn "*negsf2_media" 10246 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f") 10247 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))] 10248 "TARGET_SHMEDIA_FPU" 10249 "fneg.s %1, %0" 10250 [(set_attr "type" "fmove_media")]) 10251 10252(define_insn "negsf2_i" 10253 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f") 10254 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0"))) 10255 (use (match_operand:PSI 2 "fpscr_operand" "c"))] 10256 "TARGET_SH2E" 10257 "fneg %0" 10258 [(set_attr "type" "fmove") 10259 (set_attr "fp_mode" "single")]) 10260 10261(define_expand "sqrtsf2" 10262 [(set (match_operand:SF 0 "fp_arith_reg_operand" "") 10263 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))] 10264 "TARGET_SH3E || TARGET_SHMEDIA_FPU" 10265 " 10266{ 10267 if (TARGET_SH3E) 10268 { 10269 expand_sf_unop (&gen_sqrtsf2_i, operands); 10270 DONE; 10271 } 10272}") 10273 10274(define_insn "*sqrtsf2_media" 10275 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f") 10276 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))] 10277 "TARGET_SHMEDIA_FPU" 10278 "fsqrt.s %1, %0" 10279 [(set_attr "type" "fdiv_media")]) 10280 10281(define_insn "sqrtsf2_i" 10282 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f") 10283 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0"))) 10284 (use (match_operand:PSI 2 "fpscr_operand" "c"))] 10285 "TARGET_SH3E" 10286 "fsqrt %0" 10287 [(set_attr "type" "fdiv") 10288 (set_attr "fp_mode" "single")]) 10289 10290(define_insn "rsqrtsf2" 10291 [(set (match_operand:SF 0 "register_operand" "=f") 10292 (div:SF (match_operand:SF 1 "immediate_operand" "i") 10293 (sqrt:SF (match_operand:SF 2 "register_operand" "0")))) 10294 (use (match_operand:PSI 3 "fpscr_operand" "c"))] 10295 "TARGET_SH4A_FP && flag_unsafe_math_optimizations 10296 && operands[1] == CONST1_RTX (SFmode)" 10297 "fsrra %0" 10298 [(set_attr "type" "fsrra") 10299 (set_attr "fp_mode" "single")]) 10300 10301(define_insn "fsca" 10302 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f") 10303 (vec_concat:V2SF 10304 (unspec:SF [(mult:SF 10305 (float:SF (match_operand:SI 1 "fpul_operand" "y")) 10306 (match_operand:SF 2 "immediate_operand" "i")) 10307 ] UNSPEC_FSINA) 10308 (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2)) 10309 ] UNSPEC_FCOSA))) 10310 (use (match_operand:PSI 3 "fpscr_operand" "c"))] 10311 "TARGET_SH4A_FP && flag_unsafe_math_optimizations 10312 && operands[2] == sh_fsca_int2sf ()" 10313 "fsca fpul,%d0" 10314 [(set_attr "type" "fsca") 10315 (set_attr "fp_mode" "single")]) 10316 10317(define_expand "sinsf2" 10318 [(set (match_operand:SF 0 "nonimmediate_operand" "") 10319 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")] 10320 UNSPEC_FSINA))] 10321 "TARGET_SH4A_FP && flag_unsafe_math_optimizations" 10322 " 10323{ 10324 rtx scaled = gen_reg_rtx (SFmode); 10325 rtx truncated = gen_reg_rtx (SImode); 10326 rtx fsca = gen_reg_rtx (V2SFmode); 10327 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ()); 10328 10329 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg)); 10330 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled)); 10331 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (), 10332 get_fpscr_rtx ())); 10333 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0)); 10334 DONE; 10335}") 10336 10337(define_expand "cossf2" 10338 [(set (match_operand:SF 0 "nonimmediate_operand" "") 10339 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")] 10340 UNSPEC_FCOSA))] 10341 "TARGET_SH4A_FP && flag_unsafe_math_optimizations" 10342 " 10343{ 10344 rtx scaled = gen_reg_rtx (SFmode); 10345 rtx truncated = gen_reg_rtx (SImode); 10346 rtx fsca = gen_reg_rtx (V2SFmode); 10347 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ()); 10348 10349 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg)); 10350 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled)); 10351 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (), 10352 get_fpscr_rtx ())); 10353 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4)); 10354 DONE; 10355}") 10356 10357(define_expand "sindf2" 10358 [(set (match_operand:DF 0 "fp_arith_reg_operand" "") 10359 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")] 10360 UNSPEC_FSINA))] 10361 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations" 10362 " 10363{ 10364 rtx scaled = gen_reg_rtx (DFmode); 10365 rtx truncated = gen_reg_rtx (SImode); 10366 rtx fsca = gen_reg_rtx (V2SFmode); 10367 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ()); 10368 rtx sfresult = gen_reg_rtx (SFmode); 10369 10370 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg)); 10371 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled)); 10372 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (), 10373 get_fpscr_rtx ())); 10374 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0)); 10375 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult)); 10376 DONE; 10377}") 10378 10379(define_expand "cosdf2" 10380 [(set (match_operand:DF 0 "fp_arith_reg_operand" "") 10381 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")] 10382 UNSPEC_FCOSA))] 10383 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations" 10384 " 10385{ 10386 rtx scaled = gen_reg_rtx (DFmode); 10387 rtx truncated = gen_reg_rtx (SImode); 10388 rtx fsca = gen_reg_rtx (V2SFmode); 10389 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ()); 10390 rtx sfresult = gen_reg_rtx (SFmode); 10391 10392 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg)); 10393 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled)); 10394 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (), 10395 get_fpscr_rtx ())); 10396 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4)); 10397 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult)); 10398 DONE; 10399}") 10400 10401(define_expand "abssf2" 10402 [(set (match_operand:SF 0 "fp_arith_reg_operand" "") 10403 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))] 10404 "TARGET_SH2E || TARGET_SHMEDIA_FPU" 10405 " 10406{ 10407 if (TARGET_SH2E) 10408 { 10409 expand_sf_unop (&gen_abssf2_i, operands); 10410 DONE; 10411 } 10412}") 10413 10414(define_insn "*abssf2_media" 10415 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f") 10416 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))] 10417 "TARGET_SHMEDIA_FPU" 10418 "fabs.s %1, %0" 10419 [(set_attr "type" "fmove_media")]) 10420 10421(define_insn "abssf2_i" 10422 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f") 10423 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0"))) 10424 (use (match_operand:PSI 2 "fpscr_operand" "c"))] 10425 "TARGET_SH2E" 10426 "fabs %0" 10427 [(set_attr "type" "fmove") 10428 (set_attr "fp_mode" "single")]) 10429 10430(define_expand "adddf3" 10431 [(set (match_operand:DF 0 "fp_arith_reg_operand" "") 10432 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "") 10433 (match_operand:DF 2 "fp_arith_reg_operand" "")))] 10434 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU" 10435 " 10436{ 10437 if (TARGET_SH4 || TARGET_SH2A_DOUBLE) 10438 { 10439 expand_df_binop (&gen_adddf3_i, operands); 10440 DONE; 10441 } 10442}") 10443 10444(define_insn "*adddf3_media" 10445 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f") 10446 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f") 10447 (match_operand:DF 2 "fp_arith_reg_operand" "f")))] 10448 "TARGET_SHMEDIA_FPU" 10449 "fadd.d %1, %2, %0" 10450 [(set_attr "type" "dfparith_media")]) 10451 10452(define_insn "adddf3_i" 10453 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f") 10454 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0") 10455 (match_operand:DF 2 "fp_arith_reg_operand" "f"))) 10456 (use (match_operand:PSI 3 "fpscr_operand" "c"))] 10457 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)" 10458 "fadd %2,%0" 10459 [(set_attr "type" "dfp_arith") 10460 (set_attr "fp_mode" "double")]) 10461 10462(define_expand "subdf3" 10463 [(set (match_operand:DF 0 "fp_arith_reg_operand" "") 10464 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "") 10465 (match_operand:DF 2 "fp_arith_reg_operand" "")))] 10466 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU" 10467 " 10468{ 10469 if (TARGET_SH4 || TARGET_SH2A_DOUBLE) 10470 { 10471 expand_df_binop (&gen_subdf3_i, operands); 10472 DONE; 10473 } 10474}") 10475 10476(define_insn "*subdf3_media" 10477 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f") 10478 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f") 10479 (match_operand:DF 2 "fp_arith_reg_operand" "f")))] 10480 "TARGET_SHMEDIA_FPU" 10481 "fsub.d %1, %2, %0" 10482 [(set_attr "type" "dfparith_media")]) 10483 10484(define_insn "subdf3_i" 10485 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f") 10486 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0") 10487 (match_operand:DF 2 "fp_arith_reg_operand" "f"))) 10488 (use (match_operand:PSI 3 "fpscr_operand" "c"))] 10489 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)" 10490 "fsub %2,%0" 10491 [(set_attr "type" "dfp_arith") 10492 (set_attr "fp_mode" "double")]) 10493 10494(define_expand "muldf3" 10495 [(set (match_operand:DF 0 "fp_arith_reg_operand" "") 10496 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "") 10497 (match_operand:DF 2 "fp_arith_reg_operand" "")))] 10498 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU" 10499 " 10500{ 10501 if (TARGET_SH4 || TARGET_SH2A_DOUBLE) 10502 { 10503 expand_df_binop (&gen_muldf3_i, operands); 10504 DONE; 10505 } 10506}") 10507 10508(define_insn "*muldf3_media" 10509 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f") 10510 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f") 10511 (match_operand:DF 2 "fp_arith_reg_operand" "f")))] 10512 "TARGET_SHMEDIA_FPU" 10513 "fmul.d %1, %2, %0" 10514 [(set_attr "type" "dfmul_media")]) 10515 10516(define_insn "muldf3_i" 10517 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f") 10518 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0") 10519 (match_operand:DF 2 "fp_arith_reg_operand" "f"))) 10520 (use (match_operand:PSI 3 "fpscr_operand" "c"))] 10521 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)" 10522 "fmul %2,%0" 10523 [(set_attr "type" "dfp_mul") 10524 (set_attr "fp_mode" "double")]) 10525 10526(define_expand "divdf3" 10527 [(set (match_operand:DF 0 "fp_arith_reg_operand" "") 10528 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "") 10529 (match_operand:DF 2 "fp_arith_reg_operand" "")))] 10530 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU" 10531 " 10532{ 10533 if (TARGET_SH4 || TARGET_SH2A_DOUBLE) 10534 { 10535 expand_df_binop (&gen_divdf3_i, operands); 10536 DONE; 10537 } 10538}") 10539 10540(define_insn "*divdf3_media" 10541 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f") 10542 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f") 10543 (match_operand:DF 2 "fp_arith_reg_operand" "f")))] 10544 "TARGET_SHMEDIA_FPU" 10545 "fdiv.d %1, %2, %0" 10546 [(set_attr "type" "dfdiv_media")]) 10547 10548(define_insn "divdf3_i" 10549 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f") 10550 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0") 10551 (match_operand:DF 2 "fp_arith_reg_operand" "f"))) 10552 (use (match_operand:PSI 3 "fpscr_operand" "c"))] 10553 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)" 10554 "fdiv %2,%0" 10555 [(set_attr "type" "dfdiv") 10556 (set_attr "fp_mode" "double")]) 10557 10558(define_insn "floatdidf2" 10559 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f") 10560 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))] 10561 "TARGET_SHMEDIA_FPU" 10562 "float.qd %1, %0" 10563 [(set_attr "type" "dfpconv_media")]) 10564 10565(define_expand "floatsidf2" 10566 [(set (match_operand:DF 0 "fp_arith_reg_operand" "") 10567 (float:DF (match_operand:SI 1 "fpul_operand" "")))] 10568 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU" 10569 " 10570{ 10571 if (TARGET_SH4 || TARGET_SH2A_DOUBLE) 10572 { 10573 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1], 10574 get_fpscr_rtx ())); 10575 DONE; 10576 } 10577}") 10578 10579(define_insn "*floatsidf2_media" 10580 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f") 10581 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))] 10582 "TARGET_SHMEDIA_FPU" 10583 "float.ld %1, %0" 10584 [(set_attr "type" "dfpconv_media")]) 10585 10586(define_insn "floatsidf2_i" 10587 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f") 10588 (float:DF (match_operand:SI 1 "fpul_operand" "y"))) 10589 (use (match_operand:PSI 2 "fpscr_operand" "c"))] 10590 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)" 10591 "float %1,%0" 10592 [(set_attr "type" "dfp_conv") 10593 (set_attr "fp_mode" "double")]) 10594 10595(define_insn "fix_truncdfdi2" 10596 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f") 10597 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))] 10598 "TARGET_SHMEDIA_FPU" 10599 "ftrc.dq %1, %0" 10600 [(set_attr "type" "dfpconv_media")]) 10601 10602(define_expand "fix_truncdfsi2" 10603 [(set (match_operand:SI 0 "fpul_operand" "") 10604 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))] 10605 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU" 10606 " 10607{ 10608 if (TARGET_SH4 || TARGET_SH2A_DOUBLE) 10609 { 10610 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1], 10611 get_fpscr_rtx ())); 10612 DONE; 10613 } 10614}") 10615 10616(define_insn "*fix_truncdfsi2_media" 10617 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f") 10618 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))] 10619 "TARGET_SHMEDIA_FPU" 10620 "ftrc.dl %1, %0" 10621 [(set_attr "type" "dfpconv_media")]) 10622 10623(define_insn "fix_truncdfsi2_i" 10624 [(set (match_operand:SI 0 "fpul_operand" "=y") 10625 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f"))) 10626 (use (match_operand:PSI 2 "fpscr_operand" "c"))] 10627 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)" 10628 "ftrc %1,%0" 10629 [(set_attr "type" "dfp_conv") 10630 (set_attr "dfp_comp" "no") 10631 (set_attr "fp_mode" "double")]) 10632 10633;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to 10634;; fix_truncdfsi2_i. 10635;; (define_insn "fix_truncdfsi2_i4" 10636;; [(set (match_operand:SI 0 "arith_reg_operand" "=r") 10637;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f"))) 10638;; (use (match_operand:PSI 2 "fpscr_operand" "c")) 10639;; (clobber (reg:SI FPUL_REG))] 10640;; "TARGET_SH4" 10641;; "#" 10642;; [(set_attr "length" "4") 10643;; (set_attr "fp_mode" "double")]) 10644;; 10645;; (define_split 10646;; [(set (match_operand:SI 0 "arith_reg_operand" "=r") 10647;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f"))) 10648;; (use (match_operand:PSI 2 "fpscr_operand" "c")) 10649;; (clobber (reg:SI FPUL_REG))] 10650;; "TARGET_SH4" 10651;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1))) 10652;; (use (match_dup 2))]) 10653;; (set (match_dup 0) (reg:SI FPUL_REG))]) 10654 10655(define_insn "cmpgtdf_t" 10656 [(set (reg:SI T_REG) 10657 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f") 10658 (match_operand:DF 1 "arith_reg_operand" "f"))) 10659 (use (match_operand:PSI 2 "fpscr_operand" "c"))] 10660 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)" 10661 "fcmp/gt %1,%0" 10662 [(set_attr "type" "dfp_cmp") 10663 (set_attr "fp_mode" "double")]) 10664 10665(define_insn "cmpeqdf_t" 10666 [(set (reg:SI T_REG) 10667 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f") 10668 (match_operand:DF 1 "arith_reg_operand" "f"))) 10669 (use (match_operand:PSI 2 "fpscr_operand" "c"))] 10670 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)" 10671 "fcmp/eq %1,%0" 10672 [(set_attr "type" "dfp_cmp") 10673 (set_attr "fp_mode" "double")]) 10674 10675(define_insn "*ieee_ccmpeqdf_t" 10676 [(set (reg:SI T_REG) 10677 (ior:SI (reg:SI T_REG) 10678 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f") 10679 (match_operand:DF 1 "arith_reg_operand" "f")))) 10680 (use (match_operand:PSI 2 "fpscr_operand" "c"))] 10681 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)" 10682 "* return output_ieee_ccmpeq (insn, operands);" 10683 [(set_attr "length" "4") 10684 (set_attr "fp_mode" "double")]) 10685 10686(define_insn "cmpeqdf_media" 10687 [(set (match_operand:SI 0 "register_operand" "=r") 10688 (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f") 10689 (match_operand:DF 2 "fp_arith_reg_operand" "f")))] 10690 "TARGET_SHMEDIA_FPU" 10691 "fcmpeq.d %1,%2,%0" 10692 [(set_attr "type" "fcmp_media")]) 10693 10694(define_insn "cmpgtdf_media" 10695 [(set (match_operand:SI 0 "register_operand" "=r") 10696 (gt:SI (match_operand:DF 1 "fp_arith_reg_operand" "f") 10697 (match_operand:DF 2 "fp_arith_reg_operand" "f")))] 10698 "TARGET_SHMEDIA_FPU" 10699 "fcmpgt.d %1,%2,%0" 10700 [(set_attr "type" "fcmp_media")]) 10701 10702(define_insn "cmpgedf_media" 10703 [(set (match_operand:SI 0 "register_operand" "=r") 10704 (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f") 10705 (match_operand:DF 2 "fp_arith_reg_operand" "f")))] 10706 "TARGET_SHMEDIA_FPU" 10707 "fcmpge.d %1,%2,%0" 10708 [(set_attr "type" "fcmp_media")]) 10709 10710(define_insn "cmpundf_media" 10711 [(set (match_operand:SI 0 "register_operand" "=r") 10712 (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f") 10713 (match_operand:DF 2 "fp_arith_reg_operand" "f")))] 10714 "TARGET_SHMEDIA_FPU" 10715 "fcmpun.d %1,%2,%0" 10716 [(set_attr "type" "fcmp_media")]) 10717 10718(define_expand "cbranchdf4" 10719 [(set (pc) 10720 (if_then_else (match_operator 0 "sh_float_comparison_operator" 10721 [(match_operand:DF 1 "arith_operand" "") 10722 (match_operand:DF 2 "arith_operand" "")]) 10723 (match_operand 3 "" "") 10724 (pc)))] 10725 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU" 10726 " 10727{ 10728 if (TARGET_SHMEDIA) 10729 emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2], 10730 operands[3])); 10731 else 10732 sh_emit_compare_and_branch (operands, DFmode); 10733 DONE; 10734}") 10735 10736 10737(define_expand "negdf2" 10738 [(set (match_operand:DF 0 "arith_reg_operand" "") 10739 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))] 10740 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU" 10741 " 10742{ 10743 if (TARGET_SH4 || TARGET_SH2A_DOUBLE) 10744 { 10745 expand_df_unop (&gen_negdf2_i, operands); 10746 DONE; 10747 } 10748}") 10749 10750(define_insn "*negdf2_media" 10751 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f") 10752 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))] 10753 "TARGET_SHMEDIA_FPU" 10754 "fneg.d %1, %0" 10755 [(set_attr "type" "fmove_media")]) 10756 10757(define_insn "negdf2_i" 10758 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f") 10759 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0"))) 10760 (use (match_operand:PSI 2 "fpscr_operand" "c"))] 10761 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)" 10762 "fneg %0" 10763 [(set_attr "type" "fmove") 10764 (set_attr "fp_mode" "double")]) 10765 10766(define_expand "sqrtdf2" 10767 [(set (match_operand:DF 0 "arith_reg_operand" "") 10768 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))] 10769 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU" 10770 " 10771{ 10772 if (TARGET_SH4 || TARGET_SH2A_DOUBLE) 10773 { 10774 expand_df_unop (&gen_sqrtdf2_i, operands); 10775 DONE; 10776 } 10777}") 10778 10779(define_insn "*sqrtdf2_media" 10780 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f") 10781 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))] 10782 "TARGET_SHMEDIA_FPU" 10783 "fsqrt.d %1, %0" 10784 [(set_attr "type" "dfdiv_media")]) 10785 10786(define_insn "sqrtdf2_i" 10787 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f") 10788 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0"))) 10789 (use (match_operand:PSI 2 "fpscr_operand" "c"))] 10790 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)" 10791 "fsqrt %0" 10792 [(set_attr "type" "dfdiv") 10793 (set_attr "fp_mode" "double")]) 10794 10795(define_expand "absdf2" 10796 [(set (match_operand:DF 0 "arith_reg_operand" "") 10797 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))] 10798 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU" 10799 " 10800{ 10801 if (TARGET_SH4 || TARGET_SH2A_DOUBLE) 10802 { 10803 expand_df_unop (&gen_absdf2_i, operands); 10804 DONE; 10805 } 10806}") 10807 10808(define_insn "*absdf2_media" 10809 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f") 10810 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))] 10811 "TARGET_SHMEDIA_FPU" 10812 "fabs.d %1, %0" 10813 [(set_attr "type" "fmove_media")]) 10814 10815(define_insn "absdf2_i" 10816 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f") 10817 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0"))) 10818 (use (match_operand:PSI 2 "fpscr_operand" "c"))] 10819 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)" 10820 "fabs %0" 10821 [(set_attr "type" "fmove") 10822 (set_attr "fp_mode" "double")]) 10823 10824(define_expand "extendsfdf2" 10825 [(set (match_operand:DF 0 "fp_arith_reg_operand" "") 10826 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))] 10827 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU" 10828 " 10829{ 10830 if (TARGET_SH4 || TARGET_SH2A_DOUBLE) 10831 { 10832 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1], 10833 get_fpscr_rtx ())); 10834 DONE; 10835 } 10836}") 10837 10838(define_insn "*extendsfdf2_media" 10839 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f") 10840 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))] 10841 "TARGET_SHMEDIA_FPU" 10842 "fcnv.sd %1, %0" 10843 [(set_attr "type" "dfpconv_media")]) 10844 10845(define_insn "extendsfdf2_i4" 10846 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f") 10847 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y"))) 10848 (use (match_operand:PSI 2 "fpscr_operand" "c"))] 10849 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)" 10850 "fcnvsd %1,%0" 10851 [(set_attr "type" "fp") 10852 (set_attr "fp_mode" "double")]) 10853 10854(define_expand "truncdfsf2" 10855 [(set (match_operand:SF 0 "fpul_operand" "") 10856 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))] 10857 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU" 10858 " 10859{ 10860 if (TARGET_SH4 || TARGET_SH2A_DOUBLE) 10861 { 10862 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1], 10863 get_fpscr_rtx ())); 10864 DONE; 10865 } 10866}") 10867 10868(define_insn "*truncdfsf2_media" 10869 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f") 10870 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))] 10871 "TARGET_SHMEDIA_FPU" 10872 "fcnv.ds %1, %0" 10873 [(set_attr "type" "dfpconv_media")]) 10874 10875(define_insn "truncdfsf2_i4" 10876 [(set (match_operand:SF 0 "fpul_operand" "=y") 10877 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f"))) 10878 (use (match_operand:PSI 2 "fpscr_operand" "c"))] 10879 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)" 10880 "fcnvds %1,%0" 10881 [(set_attr "type" "fp") 10882 (set_attr "fp_mode" "double")]) 10883 10884;; Bit field extract patterns. These give better code for packed bitfields, 10885;; because they allow auto-increment addresses to be generated. 10886 10887(define_expand "insv" 10888 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "") 10889 (match_operand:SI 1 "immediate_operand" "") 10890 (match_operand:SI 2 "immediate_operand" "")) 10891 (match_operand:SI 3 "general_operand" ""))] 10892 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN" 10893 " 10894{ 10895 rtx addr_target, orig_address, shift_reg, qi_val; 10896 HOST_WIDE_INT bitsize, size, v = 0; 10897 rtx x = operands[3]; 10898 10899 if (TARGET_SH2A && TARGET_BITOPS 10900 && (satisfies_constraint_Sbw (operands[0]) 10901 || satisfies_constraint_Sbv (operands[0])) 10902 && satisfies_constraint_M (operands[1]) 10903 && satisfies_constraint_K03 (operands[2])) 10904 { 10905 if (satisfies_constraint_N (operands[3])) 10906 { 10907 emit_insn (gen_bclr_m2a (operands[0], operands[2])); 10908 DONE; 10909 } 10910 else if (satisfies_constraint_M (operands[3])) 10911 { 10912 emit_insn (gen_bset_m2a (operands[0], operands[2])); 10913 DONE; 10914 } 10915 else if ((REG_P (operands[3]) && REGNO (operands[3]) == T_REG) 10916 && satisfies_constraint_M (operands[1])) 10917 { 10918 emit_insn (gen_bst_m2a (operands[0], operands[2])); 10919 DONE; 10920 } 10921 else if (REG_P (operands[3]) 10922 && satisfies_constraint_M (operands[1])) 10923 { 10924 emit_insn (gen_bld_reg (operands[3], const0_rtx)); 10925 emit_insn (gen_bst_m2a (operands[0], operands[2])); 10926 DONE; 10927 } 10928 } 10929 /* ??? expmed doesn't care for non-register predicates. */ 10930 if (! memory_operand (operands[0], VOIDmode) 10931 || ! immediate_operand (operands[1], VOIDmode) 10932 || ! immediate_operand (operands[2], VOIDmode) 10933 || ! general_operand (x, VOIDmode)) 10934 FAIL; 10935 /* If this isn't a 16 / 24 / 32 bit field, or if 10936 it doesn't start on a byte boundary, then fail. */ 10937 bitsize = INTVAL (operands[1]); 10938 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0 10939 || (INTVAL (operands[2]) % 8) != 0) 10940 FAIL; 10941 10942 size = bitsize / 8; 10943 orig_address = XEXP (operands[0], 0); 10944 shift_reg = gen_reg_rtx (SImode); 10945 if (CONST_INT_P (x)) 10946 { 10947 v = INTVAL (x); 10948 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode))); 10949 } 10950 else 10951 { 10952 emit_insn (gen_movsi (shift_reg, operands[3])); 10953 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3); 10954 } 10955 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1)); 10956 10957 operands[0] = replace_equiv_address (operands[0], addr_target); 10958 emit_insn (gen_movqi (operands[0], qi_val)); 10959 10960 while (size -= 1) 10961 { 10962 if (CONST_INT_P (x)) 10963 qi_val 10964 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode))); 10965 else 10966 { 10967 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8))); 10968 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3); 10969 } 10970 emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx)); 10971 emit_insn (gen_movqi (operands[0], qi_val)); 10972 } 10973 10974 DONE; 10975}") 10976 10977(define_insn "movua" 10978 [(set (match_operand:SI 0 "register_operand" "=z") 10979 (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")] 10980 UNSPEC_MOVUA))] 10981 "TARGET_SH4A_ARCH" 10982 "movua.l %1,%0" 10983 [(set_attr "type" "movua")]) 10984 10985;; We shouldn't need this, but cse replaces increments with references 10986;; to other regs before flow has a chance to create post_inc 10987;; addressing modes, and only postreload's cse_move2add brings the 10988;; increments back to a usable form. 10989(define_peephole2 10990 [(set (match_operand:SI 0 "register_operand" "") 10991 (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" "")) 10992 (const_int 32) (const_int 0))) 10993 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))] 10994 "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])" 10995 [(set (match_operand:SI 0 "register_operand" "") 10996 (sign_extract:SI (mem:SI (post_inc:SI 10997 (match_operand:SI 1 "register_operand" ""))) 10998 (const_int 32) (const_int 0)))] 10999 "") 11000 11001(define_expand "extv" 11002 [(set (match_operand:SI 0 "register_operand" "") 11003 (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "") 11004 (match_operand 2 "const_int_operand" "") 11005 (match_operand 3 "const_int_operand" "")))] 11006 "TARGET_SH4A_ARCH || TARGET_SH2A" 11007{ 11008 if (TARGET_SH2A && TARGET_BITOPS 11009 && (satisfies_constraint_Sbw (operands[1]) 11010 || satisfies_constraint_Sbv (operands[1])) 11011 && satisfies_constraint_M (operands[2]) 11012 && satisfies_constraint_K03 (operands[3])) 11013 { 11014 emit_insn (gen_bldsign_m2a (operands[1], operands[3])); 11015 if (REGNO (operands[0]) != T_REG) 11016 emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG))); 11017 DONE; 11018 } 11019 if (TARGET_SH4A_ARCH 11020 && INTVAL (operands[2]) == 32 11021 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN) 11022 && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32) 11023 { 11024 rtx src = adjust_address (operands[1], BLKmode, 0); 11025 set_mem_size (src, GEN_INT (4)); 11026 emit_insn (gen_movua (operands[0], src)); 11027 DONE; 11028 } 11029 11030 FAIL; 11031}) 11032 11033(define_expand "extzv" 11034 [(set (match_operand:SI 0 "register_operand" "") 11035 (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "") 11036 (match_operand 2 "const_int_operand" "") 11037 (match_operand 3 "const_int_operand" "")))] 11038 "TARGET_SH4A_ARCH || TARGET_SH2A" 11039{ 11040 if (TARGET_SH2A && TARGET_BITOPS 11041 && (satisfies_constraint_Sbw (operands[1]) 11042 || satisfies_constraint_Sbv (operands[1])) 11043 && satisfies_constraint_M (operands[2]) 11044 && satisfies_constraint_K03 (operands[3])) 11045 { 11046 emit_insn (gen_bld_m2a (operands[1], operands[3])); 11047 if (REGNO (operands[0]) != T_REG) 11048 emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG))); 11049 DONE; 11050 } 11051 if (TARGET_SH4A_ARCH 11052 && INTVAL (operands[2]) == 32 11053 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN) 11054 && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32) 11055 { 11056 rtx src = adjust_address (operands[1], BLKmode, 0); 11057 set_mem_size (src, GEN_INT (4)); 11058 emit_insn (gen_movua (operands[0], src)); 11059 DONE; 11060 } 11061 11062 FAIL; 11063}) 11064 11065;; SH2A instructions for bitwise operations. 11066 11067;; Clear a bit in a memory location. 11068(define_insn "bclr_m2a" 11069 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv") 11070 (and:QI 11071 (not:QI (ashift:QI (const_int 1) 11072 (match_operand:QI 1 "const_int_operand" "K03,K03"))) 11073 (match_dup 0)))] 11074 "TARGET_SH2A && TARGET_BITOPS" 11075 "@ 11076 bclr.b\\t%1,%0 11077 bclr.b\\t%1,@(0,%t0)" 11078[(set_attr "length" "4,4")]) 11079 11080(define_insn "bclrmem_m2a" 11081 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv") 11082 (and:QI (match_dup 0) 11083 (match_operand:QI 1 "const_int_operand" "Psz,Psz")))] 11084 "TARGET_SH2A && satisfies_constraint_Psz (operands[1]) && TARGET_BITOPS" 11085 "@ 11086 bclr.b\\t%W1,%0 11087 bclr.b\\t%W1,@(0,%t0)" 11088 [(set_attr "length" "4,4")]) 11089 11090;; Set a bit in a memory location. 11091(define_insn "bset_m2a" 11092 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv") 11093 (ior:QI 11094 (ashift:QI (const_int 1) 11095 (match_operand:QI 1 "const_int_operand" "K03,K03")) 11096 (match_dup 0)))] 11097 "TARGET_SH2A && TARGET_BITOPS" 11098 "@ 11099 bset.b\\t%1,%0 11100 bset.b\\t%1,@(0,%t0)" 11101 [(set_attr "length" "4,4")]) 11102 11103(define_insn "bsetmem_m2a" 11104 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv") 11105 (ior:QI (match_dup 0) 11106 (match_operand:QI 1 "const_int_operand" "Pso,Pso")))] 11107 "TARGET_SH2A && satisfies_constraint_Pso (operands[1]) && TARGET_BITOPS" 11108 "@ 11109 bset.b\\t%V1,%0 11110 bset.b\\t%V1,@(0,%t0)" 11111 [(set_attr "length" "4,4")]) 11112 11113;;; Transfer the contents of the T bit to a specified bit of memory. 11114(define_insn "bst_m2a" 11115 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,m") 11116 (if_then_else (eq (reg:SI T_REG) (const_int 0)) 11117 (and:QI 11118 (not:QI (ashift:QI (const_int 1) 11119 (match_operand:QI 1 "const_int_operand" "K03,K03"))) 11120 (match_dup 0)) 11121 (ior:QI 11122 (ashift:QI (const_int 1) (match_dup 1)) 11123 (match_dup 0))))] 11124 "TARGET_SH2A && TARGET_BITOPS" 11125 "@ 11126 bst.b\\t%1,%0 11127 bst.b\\t%1,@(0,%t0)" 11128 [(set_attr "length" "4")]) 11129 11130;; Store a specified bit of memory in the T bit. 11131(define_insn "bld_m2a" 11132 [(set (reg:SI T_REG) 11133 (zero_extract:SI 11134 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,Sbv") 11135 (const_int 1) 11136 (match_operand 1 "const_int_operand" "K03,K03")))] 11137 "TARGET_SH2A && TARGET_BITOPS" 11138 "@ 11139 bld.b\\t%1,%0 11140 bld.b\\t%1,@(0,%t0)" 11141 [(set_attr "length" "4,4")]) 11142 11143;; Store a specified bit of memory in the T bit. 11144(define_insn "bldsign_m2a" 11145 [(set (reg:SI T_REG) 11146 (sign_extract:SI 11147 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m") 11148 (const_int 1) 11149 (match_operand 1 "const_int_operand" "K03,K03")))] 11150 "TARGET_SH2A && TARGET_BITOPS" 11151 "@ 11152 bld.b\\t%1,%0 11153 bld.b\\t%1,@(0,%t0)" 11154 [(set_attr "length" "4,4")]) 11155 11156;; Store a specified bit of the LSB 8 bits of a register in the T bit. 11157(define_insn "bld_reg" 11158 [(set (reg:SI T_REG) 11159 (zero_extract:SI (match_operand:SI 0 "arith_reg_operand" "r") 11160 (const_int 1) 11161 (match_operand 1 "const_int_operand" "K03")))] 11162 "TARGET_SH2A" 11163 "bld\\t%1,%0") 11164 11165(define_insn "*bld_regqi" 11166 [(set (reg:SI T_REG) 11167 (zero_extract:SI (match_operand:QI 0 "arith_reg_operand" "r") 11168 (const_int 1) 11169 (match_operand 1 "const_int_operand" "K03")))] 11170 "TARGET_SH2A" 11171 "bld\\t%1,%0") 11172 11173;; Take logical and of a specified bit of memory with the T bit and 11174;; store its result in the T bit. 11175(define_insn "band_m2a" 11176 [(set (reg:SI T_REG) 11177 (and:SI (reg:SI T_REG) 11178 (zero_extract:SI 11179 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m") 11180 (const_int 1) 11181 (match_operand 1 "const_int_operand" "K03,K03"))))] 11182 "TARGET_SH2A && TARGET_BITOPS" 11183 "@ 11184 band.b\\t%1,%0 11185 band.b\\t%1,@(0,%t0)" 11186 [(set_attr "length" "4,4")]) 11187 11188(define_insn "bandreg_m2a" 11189 [(set (match_operand:SI 0 "register_operand" "=r,r") 11190 (and:SI (zero_extract:SI 11191 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv") 11192 (const_int 1) 11193 (match_operand 2 "const_int_operand" "K03,K03")) 11194 (match_operand:SI 3 "register_operand" "r,r")))] 11195 "TARGET_SH2A && TARGET_BITOPS" 11196 "@ 11197 band.b\\t%2,%1\;movt\\t%0 11198 band.b\\t%2,@(0,%t1)\;movt\\t%0" 11199 [(set_attr "length" "6,6")]) 11200 11201;; Take logical or of a specified bit of memory with the T bit and 11202;; store its result in the T bit. 11203(define_insn "bor_m2a" 11204 [(set (reg:SI T_REG) 11205 (ior:SI (reg:SI T_REG) 11206 (zero_extract:SI 11207 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m") 11208 (const_int 1) 11209 (match_operand 1 "const_int_operand" "K03,K03"))))] 11210 "TARGET_SH2A && TARGET_BITOPS" 11211 "@ 11212 bor.b\\t%1,%0 11213 bor.b\\t%1,@(0,%t0)" 11214 [(set_attr "length" "4,4")]) 11215 11216(define_insn "borreg_m2a" 11217 [(set (match_operand:SI 0 "register_operand" "=r,r") 11218 (ior:SI (zero_extract:SI 11219 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv") 11220 (const_int 1) 11221 (match_operand 2 "const_int_operand" "K03,K03")) 11222 (match_operand:SI 3 "register_operand" "=r,r")))] 11223 "TARGET_SH2A && TARGET_BITOPS" 11224 "@ 11225 bor.b\\t%2,%1\;movt\\t%0 11226 bor.b\\t%2,@(0,%t1)\;movt\\t%0" 11227 [(set_attr "length" "6,6")]) 11228 11229;; Take exclusive or of a specified bit of memory with the T bit and 11230;; store its result in the T bit. 11231(define_insn "bxor_m2a" 11232 [(set (reg:SI T_REG) 11233 (xor:SI (reg:SI T_REG) 11234 (zero_extract:SI 11235 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m") 11236 (const_int 1) 11237 (match_operand 1 "const_int_operand" "K03,K03"))))] 11238 "TARGET_SH2A && TARGET_BITOPS" 11239 "@ 11240 bxor.b\\t%1,%0 11241 bxor.b\\t%1,@(0,%t0)" 11242 [(set_attr "length" "4,4")]) 11243 11244(define_insn "bxorreg_m2a" 11245 [(set (match_operand:SI 0 "register_operand" "=r,r") 11246 (xor:SI (zero_extract:SI 11247 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv") 11248 (const_int 1) 11249 (match_operand 2 "const_int_operand" "K03,K03")) 11250 (match_operand:SI 3 "register_operand" "=r,r")))] 11251 "TARGET_SH2A && TARGET_BITOPS" 11252 "@ 11253 bxor.b\\t%2,%1\;movt\\t%0 11254 bxor.b\\t%2,@(0,%t1)\;movt\\t%0" 11255 [(set_attr "length" "6,6")]) 11256 11257 11258;; ------------------------------------------------------------------------- 11259;; Peepholes 11260;; ------------------------------------------------------------------------- 11261;; This matches cases where the bit in a memory location is set. 11262(define_peephole2 11263 [(set (match_operand:SI 0 "arith_reg_operand" "r,r") 11264 (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv"))) 11265 (set (match_dup 0) 11266 (ior:SI (match_dup 0) 11267 (match_operand:SI 2 "const_int_operand" "Pso,Pso"))) 11268 (set (match_dup 1) 11269 (match_operand 3 "arith_reg_operand" "r,r"))] 11270 "TARGET_SH2A && TARGET_BITOPS 11271 && satisfies_constraint_Pso (operands[2]) 11272 && REGNO (operands[0]) == REGNO (operands[3])" 11273 [(set (match_dup 1) 11274 (ior:QI (match_dup 1) 11275 (match_dup 2)))] 11276 "") 11277 11278;; This matches cases where the bit in a memory location is cleared. 11279(define_peephole2 11280 [(set (match_operand:SI 0 "arith_reg_operand" "r,r") 11281 (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv"))) 11282 (set (match_dup 0) 11283 (and:SI (match_dup 0) 11284 (match_operand:SI 2 "const_int_operand" "Psz,Psz"))) 11285 (set (match_dup 1) 11286 (match_operand 3 "arith_reg_operand" "r,r"))] 11287 "TARGET_SH2A && TARGET_BITOPS 11288 && satisfies_constraint_Psz (operands[2]) 11289 && REGNO (operands[0]) == REGNO (operands[3])" 11290 [(set (match_dup 1) 11291 (and:QI (match_dup 1) 11292 (match_dup 2)))] 11293 "") 11294 11295;; This matches cases where a stack pointer increment at the start of the 11296;; epilogue combines with a stack slot read loading the return value. 11297 11298(define_peephole 11299 [(set (match_operand:SI 0 "arith_reg_operand" "") 11300 (mem:SI (match_operand:SI 1 "arith_reg_operand" ""))) 11301 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))] 11302 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])" 11303 "mov.l @%1+,%0") 11304 11305;; See the comment on the dt combiner pattern above. 11306 11307(define_peephole 11308 [(set (match_operand:SI 0 "arith_reg_operand" "=r") 11309 (plus:SI (match_dup 0) 11310 (const_int -1))) 11311 (set (reg:SI T_REG) 11312 (eq:SI (match_dup 0) 11313 (const_int 0)))] 11314 "TARGET_SH2" 11315 "dt %0") 11316 11317;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn' 11318;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by 11319;; reload when the constant is too large for a reg+offset address. 11320 11321;; ??? We would get much better code if this was done in reload. This would 11322;; require modifying find_reloads_address to recognize that if the constant 11323;; is out-of-range for an immediate add, then we get better code by reloading 11324;; the constant into a register than by reloading the sum into a register, 11325;; since the former is one instruction shorter if the address does not need 11326;; to be offsettable. Unfortunately this does not work, because there is 11327;; only one register, r0, that can be used as an index register. This register 11328;; is also the function return value register. So, if we try to force reload 11329;; to use double-reg addresses, then we end up with some instructions that 11330;; need to use r0 twice. The only way to fix this is to change the calling 11331;; convention so that r0 is not used to return values. 11332 11333(define_peephole 11334 [(set (match_operand:SI 0 "register_operand" "=r") 11335 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r"))) 11336 (set (mem:SI (match_dup 0)) 11337 (match_operand:SI 2 "general_movsrc_operand" ""))] 11338 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)" 11339 "mov.l %2,@(%0,%1)") 11340 11341(define_peephole 11342 [(set (match_operand:SI 0 "register_operand" "=r") 11343 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r"))) 11344 (set (match_operand:SI 2 "general_movdst_operand" "") 11345 (mem:SI (match_dup 0)))] 11346 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)" 11347 "mov.l @(%0,%1),%2") 11348 11349(define_peephole 11350 [(set (match_operand:SI 0 "register_operand" "=r") 11351 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r"))) 11352 (set (mem:HI (match_dup 0)) 11353 (match_operand:HI 2 "general_movsrc_operand" ""))] 11354 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)" 11355 "mov.w %2,@(%0,%1)") 11356 11357(define_peephole 11358 [(set (match_operand:SI 0 "register_operand" "=r") 11359 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r"))) 11360 (set (match_operand:HI 2 "general_movdst_operand" "") 11361 (mem:HI (match_dup 0)))] 11362 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)" 11363 "mov.w @(%0,%1),%2") 11364 11365(define_peephole 11366 [(set (match_operand:SI 0 "register_operand" "=r") 11367 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r"))) 11368 (set (mem:QI (match_dup 0)) 11369 (match_operand:QI 2 "general_movsrc_operand" ""))] 11370 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)" 11371 "mov.b %2,@(%0,%1)") 11372 11373(define_peephole 11374 [(set (match_operand:SI 0 "register_operand" "=r") 11375 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r"))) 11376 (set (match_operand:QI 2 "general_movdst_operand" "") 11377 (mem:QI (match_dup 0)))] 11378 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)" 11379 "mov.b @(%0,%1),%2") 11380 11381(define_peephole 11382 [(set (match_operand:SI 0 "register_operand" "=r") 11383 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r"))) 11384 (set (mem:SF (match_dup 0)) 11385 (match_operand:SF 2 "general_movsrc_operand" ""))] 11386 "TARGET_SH1 && REGNO (operands[0]) == 0 11387 && ((REG_P (operands[2]) && REGNO (operands[2]) < 16) 11388 || (GET_CODE (operands[2]) == SUBREG 11389 && REGNO (SUBREG_REG (operands[2])) < 16)) 11390 && reg_unused_after (operands[0], insn)" 11391 "mov.l %2,@(%0,%1)") 11392 11393(define_peephole 11394 [(set (match_operand:SI 0 "register_operand" "=r") 11395 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r"))) 11396 (set (match_operand:SF 2 "general_movdst_operand" "") 11397 11398 (mem:SF (match_dup 0)))] 11399 "TARGET_SH1 && REGNO (operands[0]) == 0 11400 && ((REG_P (operands[2]) && REGNO (operands[2]) < 16) 11401 || (GET_CODE (operands[2]) == SUBREG 11402 && REGNO (SUBREG_REG (operands[2])) < 16)) 11403 && reg_unused_after (operands[0], insn)" 11404 "mov.l @(%0,%1),%2") 11405 11406(define_peephole 11407 [(set (match_operand:SI 0 "register_operand" "=r") 11408 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r"))) 11409 (set (mem:SF (match_dup 0)) 11410 (match_operand:SF 2 "general_movsrc_operand" ""))] 11411 "TARGET_SH2E && REGNO (operands[0]) == 0 11412 && ((REG_P (operands[2]) 11413 && FP_OR_XD_REGISTER_P (REGNO (operands[2]))) 11414 || (GET_CODE (operands[2]) == SUBREG 11415 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2]))))) 11416 && reg_unused_after (operands[0], insn)" 11417 "fmov{.s|} %2,@(%0,%1)") 11418 11419(define_peephole 11420 [(set (match_operand:SI 0 "register_operand" "=r") 11421 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r"))) 11422 (set (match_operand:SF 2 "general_movdst_operand" "") 11423 11424 (mem:SF (match_dup 0)))] 11425 "TARGET_SH2E && REGNO (operands[0]) == 0 11426 && ((REG_P (operands[2]) 11427 && FP_OR_XD_REGISTER_P (REGNO (operands[2]))) 11428 || (GET_CODE (operands[2]) == SUBREG 11429 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2]))))) 11430 && reg_unused_after (operands[0], insn)" 11431 "fmov{.s|} @(%0,%1),%2") 11432 11433;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */ 11434(define_insn "sp_switch_1" 11435 [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")] 11436 "TARGET_SH1" 11437 "* 11438{ 11439 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", operands); 11440 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", operands); 11441 return \"mov r0,r15\"; 11442}" 11443 [(set_attr "length" "10")]) 11444 11445;; Switch back to the original stack for interrupt functions with the 11446;; sp_switch attribute. */ 11447(define_insn "sp_switch_2" 11448 [(const_int 2)] 11449 "TARGET_SH1" 11450 "mov.l @r15+,r15\;mov.l @r15+,r0" 11451 [(set_attr "length" "4")]) 11452 11453;; Integer vector moves 11454 11455(define_expand "movv8qi" 11456 [(set (match_operand:V8QI 0 "general_movdst_operand" "") 11457 (match_operand:V8QI 1 "general_movsrc_operand" ""))] 11458 "TARGET_SHMEDIA" 11459 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }") 11460 11461(define_insn "movv8qi_i" 11462 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m") 11463 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))] 11464 "TARGET_SHMEDIA 11465 && (register_operand (operands[0], V8QImode) 11466 || sh_register_operand (operands[1], V8QImode))" 11467 "@ 11468 add %1, r63, %0 11469 movi %1, %0 11470 # 11471 ld%M1.q %m1, %0 11472 st%M0.q %m0, %N1" 11473 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media") 11474 (set_attr "length" "4,4,16,4,4")]) 11475 11476(define_split 11477 [(set (match_operand:V8QI 0 "arith_reg_dest" "") 11478 (subreg:V8QI (const_int 0) 0))] 11479 "TARGET_SHMEDIA" 11480 [(set (match_dup 0) 11481 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0) 11482 (const_int 0) (const_int 0) (const_int 0) 11483 (const_int 0) (const_int 0)]))]) 11484 11485(define_split 11486 [(set (match_operand 0 "arith_reg_dest" "") 11487 (match_operand 1 "sh_rep_vec" ""))] 11488 "TARGET_SHMEDIA && reload_completed 11489 && GET_MODE (operands[0]) == GET_MODE (operands[1]) 11490 && sh_vector_mode_supported_p (GET_MODE (operands[0])) 11491 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8 11492 && (XVECEXP (operands[1], 0, 0) != const0_rtx 11493 || XVECEXP (operands[1], 0, 1) != const0_rtx) 11494 && (XVECEXP (operands[1], 0, 0) != constm1_rtx 11495 || XVECEXP (operands[1], 0, 1) != constm1_rtx)" 11496 [(set (match_dup 0) (match_dup 1)) 11497 (match_dup 2)] 11498 " 11499{ 11500 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1])); 11501 rtx elt1 = XVECEXP (operands[1], 0, 1); 11502 11503 if (unit_size > 2) 11504 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]); 11505 else 11506 { 11507 if (unit_size < 2) 11508 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0])); 11509 operands[2] = gen_mperm_w0 (operands[0], operands[0]); 11510 } 11511 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0])); 11512 operands[1] = XVECEXP (operands[1], 0, 0); 11513 if (unit_size < 2) 11514 { 11515 if (CONST_INT_P (operands[1]) && CONST_INT_P (elt1)) 11516 operands[1] 11517 = GEN_INT (TARGET_LITTLE_ENDIAN 11518 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8) 11519 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff)); 11520 else 11521 { 11522 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0])); 11523 operands[1] 11524 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1)); 11525 } 11526 } 11527}") 11528 11529(define_split 11530 [(set (match_operand 0 "arith_reg_dest" "") 11531 (match_operand 1 "sh_const_vec" ""))] 11532 "TARGET_SHMEDIA && reload_completed 11533 && GET_MODE (operands[0]) == GET_MODE (operands[1]) 11534 && sh_vector_mode_supported_p (GET_MODE (operands[0]))" 11535 [(set (match_dup 0) (match_dup 1))] 11536 " 11537{ 11538 rtx v = operands[1]; 11539 enum machine_mode new_mode 11540 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0); 11541 11542 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0])); 11543 operands[1] 11544 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0); 11545}") 11546 11547(define_expand "movv2hi" 11548 [(set (match_operand:V2HI 0 "general_movdst_operand" "") 11549 (match_operand:V2HI 1 "general_movsrc_operand" ""))] 11550 "TARGET_SHMEDIA" 11551 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }") 11552 11553(define_insn "movv2hi_i" 11554 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m") 11555 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))] 11556 "TARGET_SHMEDIA 11557 && (register_operand (operands[0], V2HImode) 11558 || sh_register_operand (operands[1], V2HImode))" 11559 "@ 11560 add.l %1, r63, %0 11561 movi %1, %0 11562 # 11563 ld%M1.l %m1, %0 11564 st%M0.l %m0, %N1" 11565 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media") 11566 (set_attr "length" "4,4,16,4,4") 11567 (set (attr "highpart") 11568 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0)) 11569 (const_string "user")] 11570 (const_string "ignore")))]) 11571 11572(define_expand "movv4hi" 11573 [(set (match_operand:V4HI 0 "general_movdst_operand" "") 11574 (match_operand:V4HI 1 "general_movsrc_operand" ""))] 11575 "TARGET_SHMEDIA" 11576 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }") 11577 11578(define_insn "movv4hi_i" 11579 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m") 11580 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))] 11581 "TARGET_SHMEDIA 11582 && (register_operand (operands[0], V4HImode) 11583 || sh_register_operand (operands[1], V4HImode))" 11584 "@ 11585 add %1, r63, %0 11586 movi %1, %0 11587 # 11588 ld%M1.q %m1, %0 11589 st%M0.q %m0, %N1" 11590 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media") 11591 (set_attr "length" "4,4,16,4,4") 11592 (set_attr "highpart" "depend")]) 11593 11594(define_expand "movv2si" 11595 [(set (match_operand:V2SI 0 "general_movdst_operand" "") 11596 (match_operand:V2SI 1 "general_movsrc_operand" ""))] 11597 "TARGET_SHMEDIA" 11598 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }") 11599 11600(define_insn "movv2si_i" 11601 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m") 11602 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))] 11603 "TARGET_SHMEDIA 11604 && (register_operand (operands[0], V2SImode) 11605 || sh_register_operand (operands[1], V2SImode))" 11606 "@ 11607 add %1, r63, %0 11608 # 11609 # 11610 ld%M1.q %m1, %0 11611 st%M0.q %m0, %N1" 11612 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media") 11613 (set_attr "length" "4,4,16,4,4") 11614 (set_attr "highpart" "depend")]) 11615 11616;; Multimedia Intrinsics 11617 11618(define_insn "absv2si2" 11619 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r") 11620 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))] 11621 "TARGET_SHMEDIA" 11622 "mabs.l %1, %0" 11623 [(set_attr "type" "mcmp_media") 11624 (set_attr "highpart" "depend")]) 11625 11626(define_insn "absv4hi2" 11627 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r") 11628 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))] 11629 "TARGET_SHMEDIA" 11630 "mabs.w %1, %0" 11631 [(set_attr "type" "mcmp_media") 11632 (set_attr "highpart" "depend")]) 11633 11634(define_insn "addv2si3" 11635 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r") 11636 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r") 11637 (match_operand:V2SI 2 "arith_reg_operand" "r")))] 11638 "TARGET_SHMEDIA" 11639 "madd.l %1, %2, %0" 11640 [(set_attr "type" "arith_media") 11641 (set_attr "highpart" "depend")]) 11642 11643(define_insn "addv4hi3" 11644 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r") 11645 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r") 11646 (match_operand:V4HI 2 "arith_reg_operand" "r")))] 11647 "TARGET_SHMEDIA" 11648 "madd.w %1, %2, %0" 11649 [(set_attr "type" "arith_media") 11650 (set_attr "highpart" "depend")]) 11651 11652(define_insn_and_split "addv2hi3" 11653 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r") 11654 (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r") 11655 (match_operand:V2HI 2 "extend_reg_operand" "r")))] 11656 "TARGET_SHMEDIA" 11657 "#" 11658 "TARGET_SHMEDIA" 11659 [(const_int 0)] 11660 " 11661{ 11662 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0); 11663 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0); 11664 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0); 11665 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0); 11666 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0); 11667 11668 emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1)); 11669 emit_insn (gen_truncdisi2 (si_dst, di_dst)); 11670 DONE; 11671}" 11672 [(set_attr "highpart" "must_split")]) 11673 11674(define_insn "ssaddv2si3" 11675 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r") 11676 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r") 11677 (match_operand:V2SI 2 "arith_reg_operand" "r")))] 11678 "TARGET_SHMEDIA" 11679 "madds.l %1, %2, %0" 11680 [(set_attr "type" "mcmp_media") 11681 (set_attr "highpart" "depend")]) 11682 11683(define_insn "usaddv8qi3" 11684 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r") 11685 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r") 11686 (match_operand:V8QI 2 "arith_reg_operand" "r")))] 11687 "TARGET_SHMEDIA" 11688 "madds.ub %1, %2, %0" 11689 [(set_attr "type" "mcmp_media") 11690 (set_attr "highpart" "depend")]) 11691 11692(define_insn "ssaddv4hi3" 11693 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r") 11694 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r") 11695 (match_operand:V4HI 2 "arith_reg_operand" "r")))] 11696 "TARGET_SHMEDIA" 11697 "madds.w %1, %2, %0" 11698 [(set_attr "type" "mcmp_media") 11699 (set_attr "highpart" "depend")]) 11700 11701(define_insn "negcmpeqv8qi" 11702 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r") 11703 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ") 11704 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))] 11705 "TARGET_SHMEDIA" 11706 "mcmpeq.b %N1, %N2, %0" 11707 [(set_attr "type" "mcmp_media") 11708 (set_attr "highpart" "depend")]) 11709 11710(define_insn "negcmpeqv2si" 11711 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r") 11712 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ") 11713 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))] 11714 "TARGET_SHMEDIA" 11715 "mcmpeq.l %N1, %N2, %0" 11716 [(set_attr "type" "mcmp_media") 11717 (set_attr "highpart" "depend")]) 11718 11719(define_insn "negcmpeqv4hi" 11720 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r") 11721 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ") 11722 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))] 11723 "TARGET_SHMEDIA" 11724 "mcmpeq.w %N1, %N2, %0" 11725 [(set_attr "type" "mcmp_media") 11726 (set_attr "highpart" "depend")]) 11727 11728(define_insn "negcmpgtuv8qi" 11729 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r") 11730 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ") 11731 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))] 11732 "TARGET_SHMEDIA" 11733 "mcmpgt.ub %N1, %N2, %0" 11734 [(set_attr "type" "mcmp_media") 11735 (set_attr "highpart" "depend")]) 11736 11737(define_insn "negcmpgtv2si" 11738 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r") 11739 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ") 11740 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))] 11741 "TARGET_SHMEDIA" 11742 "mcmpgt.l %N1, %N2, %0" 11743 [(set_attr "type" "mcmp_media") 11744 (set_attr "highpart" "depend")]) 11745 11746(define_insn "negcmpgtv4hi" 11747 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r") 11748 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ") 11749 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))] 11750 "TARGET_SHMEDIA" 11751 "mcmpgt.w %N1, %N2, %0" 11752 [(set_attr "type" "mcmp_media") 11753 (set_attr "highpart" "depend")]) 11754 11755(define_insn "mcmv" 11756 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 11757 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ") 11758 (match_operand:DI 2 "arith_reg_operand" "r")) 11759 (and:DI (match_operand:DI 3 "arith_reg_operand" "0") 11760 (not:DI (match_dup 2)))))] 11761 "TARGET_SHMEDIA" 11762 "mcmv %N1, %2, %0" 11763 [(set_attr "type" "arith_media") 11764 (set_attr "highpart" "depend")]) 11765 11766(define_insn "mcnvs_lw" 11767 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r") 11768 (vec_concat:V4HI 11769 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")) 11770 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))] 11771 "TARGET_SHMEDIA" 11772 "mcnvs.lw %N1, %N2, %0" 11773 [(set_attr "type" "mcmp_media")]) 11774 11775(define_insn "mcnvs_wb" 11776 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r") 11777 (vec_concat:V8QI 11778 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")) 11779 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))] 11780 "TARGET_SHMEDIA" 11781 "mcnvs.wb %N1, %N2, %0" 11782 [(set_attr "type" "mcmp_media")]) 11783 11784(define_insn "mcnvs_wub" 11785 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r") 11786 (vec_concat:V8QI 11787 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")) 11788 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))] 11789 "TARGET_SHMEDIA" 11790 "mcnvs.wub %N1, %N2, %0" 11791 [(set_attr "type" "mcmp_media")]) 11792 11793(define_insn "mextr_rl" 11794 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 11795 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ") 11796 (match_operand:HI 3 "mextr_bit_offset" "i")) 11797 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ") 11798 (match_operand:HI 4 "mextr_bit_offset" "i"))))] 11799 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64" 11800 "* 11801{ 11802 static char templ[21]; 11803 11804 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\", 11805 (int) INTVAL (operands[3]) >> 3); 11806 return templ; 11807}" 11808 [(set_attr "type" "arith_media")]) 11809 11810(define_insn "*mextr_lr" 11811 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 11812 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ") 11813 (match_operand:HI 3 "mextr_bit_offset" "i")) 11814 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ") 11815 (match_operand:HI 4 "mextr_bit_offset" "i"))))] 11816 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64" 11817 "* 11818{ 11819 static char templ[21]; 11820 11821 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\", 11822 (int) INTVAL (operands[4]) >> 3); 11823 return templ; 11824}" 11825 [(set_attr "type" "arith_media")]) 11826 11827; mextrN can be modelled with vec_select / vec_concat, but the selection 11828; vector then varies depending on endianness. 11829(define_expand "mextr1" 11830 [(match_operand:DI 0 "arith_reg_dest" "") 11831 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ") 11832 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")] 11833 "TARGET_SHMEDIA" 11834 " 11835{ 11836 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2], 11837 GEN_INT (1 * 8), GEN_INT (7 * 8))); 11838 DONE; 11839}") 11840 11841(define_expand "mextr2" 11842 [(match_operand:DI 0 "arith_reg_dest" "") 11843 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ") 11844 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")] 11845 "TARGET_SHMEDIA" 11846 " 11847{ 11848 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2], 11849 GEN_INT (2 * 8), GEN_INT (6 * 8))); 11850 DONE; 11851}") 11852 11853(define_expand "mextr3" 11854 [(match_operand:DI 0 "arith_reg_dest" "") 11855 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ") 11856 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")] 11857 "TARGET_SHMEDIA" 11858 " 11859{ 11860 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2], 11861 GEN_INT (3 * 8), GEN_INT (5 * 8))); 11862 DONE; 11863}") 11864 11865(define_expand "mextr4" 11866 [(match_operand:DI 0 "arith_reg_dest" "") 11867 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ") 11868 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")] 11869 "TARGET_SHMEDIA" 11870 " 11871{ 11872 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2], 11873 GEN_INT (4 * 8), GEN_INT (4 * 8))); 11874 DONE; 11875}") 11876 11877(define_expand "mextr5" 11878 [(match_operand:DI 0 "arith_reg_dest" "") 11879 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ") 11880 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")] 11881 "TARGET_SHMEDIA" 11882 " 11883{ 11884 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2], 11885 GEN_INT (5 * 8), GEN_INT (3 * 8))); 11886 DONE; 11887}") 11888 11889(define_expand "mextr6" 11890 [(match_operand:DI 0 "arith_reg_dest" "") 11891 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ") 11892 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")] 11893 "TARGET_SHMEDIA" 11894 " 11895{ 11896 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2], 11897 GEN_INT (6 * 8), GEN_INT (2 * 8))); 11898 DONE; 11899}") 11900 11901(define_expand "mextr7" 11902 [(match_operand:DI 0 "arith_reg_dest" "") 11903 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ") 11904 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")] 11905 "TARGET_SHMEDIA" 11906 " 11907{ 11908 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2], 11909 GEN_INT (7 * 8), GEN_INT (1 * 8))); 11910 DONE; 11911}") 11912 11913(define_expand "mmacfx_wl" 11914 [(match_operand:V2SI 0 "arith_reg_dest" "") 11915 (match_operand:V2HI 1 "extend_reg_operand" "") 11916 (match_operand:V2HI 2 "extend_reg_operand" "") 11917 (match_operand:V2SI 3 "arith_reg_operand" "")] 11918 "TARGET_SHMEDIA" 11919 " 11920{ 11921 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3], 11922 operands[1], operands[2])); 11923 DONE; 11924}") 11925 11926;; This could be highpart ignore if it only had inputs 2 or 3, but input 1 11927;; is depend 11928(define_insn "mmacfx_wl_i" 11929 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r") 11930 (ss_plus:V2SI 11931 (match_operand:V2SI 1 "arith_reg_operand" "0") 11932 (ss_truncate:V2SI 11933 (ashift:V2DI 11934 (sign_extend:V2DI 11935 (mult:V2SI 11936 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r")) 11937 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r")))) 11938 (const_int 1)))))] 11939 "TARGET_SHMEDIA" 11940 "mmacfx.wl %2, %3, %0" 11941 [(set_attr "type" "mac_media") 11942 (set_attr "highpart" "depend")]) 11943 11944(define_expand "mmacnfx_wl" 11945 [(match_operand:V2SI 0 "arith_reg_dest" "") 11946 (match_operand:V2HI 1 "extend_reg_operand" "") 11947 (match_operand:V2HI 2 "extend_reg_operand" "") 11948 (match_operand:V2SI 3 "arith_reg_operand" "")] 11949 "TARGET_SHMEDIA" 11950 " 11951{ 11952 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3], 11953 operands[1], operands[2])); 11954 DONE; 11955}") 11956 11957(define_insn "mmacnfx_wl_i" 11958 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r") 11959 (ss_minus:V2SI 11960 (match_operand:V2SI 1 "arith_reg_operand" "0") 11961 (ss_truncate:V2SI 11962 (ashift:V2DI 11963 (sign_extend:V2DI 11964 (mult:V2SI 11965 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r")) 11966 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r")))) 11967 (const_int 1)))))] 11968 "TARGET_SHMEDIA" 11969 "mmacnfx.wl %2, %3, %0" 11970 [(set_attr "type" "mac_media") 11971 (set_attr "highpart" "depend")]) 11972 11973(define_insn "mulv2si3" 11974 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r") 11975 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r") 11976 (match_operand:V2SI 2 "arith_reg_operand" "r")))] 11977 "TARGET_SHMEDIA" 11978 "mmul.l %1, %2, %0" 11979 [(set_attr "type" "d2mpy_media") 11980 (set_attr "highpart" "depend")]) 11981 11982(define_insn "mulv4hi3" 11983 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r") 11984 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r") 11985 (match_operand:V4HI 2 "arith_reg_operand" "r")))] 11986 "TARGET_SHMEDIA" 11987 "mmul.w %1, %2, %0" 11988 [(set_attr "type" "dmpy_media") 11989 (set_attr "highpart" "depend")]) 11990 11991(define_insn "mmulfx_l" 11992 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r") 11993 (ss_truncate:V2SI 11994 (ashiftrt:V2DI 11995 (mult:V2DI 11996 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r")) 11997 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r"))) 11998 (const_int 31))))] 11999 "TARGET_SHMEDIA" 12000 "mmulfx.l %1, %2, %0" 12001 [(set_attr "type" "d2mpy_media") 12002 (set_attr "highpart" "depend")]) 12003 12004(define_insn "mmulfx_w" 12005 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r") 12006 (ss_truncate:V4HI 12007 (ashiftrt:V4SI 12008 (mult:V4SI 12009 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r")) 12010 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r"))) 12011 (const_int 15))))] 12012 "TARGET_SHMEDIA" 12013 "mmulfx.w %1, %2, %0" 12014 [(set_attr "type" "dmpy_media") 12015 (set_attr "highpart" "depend")]) 12016 12017(define_insn "mmulfxrp_w" 12018 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r") 12019 (ss_truncate:V4HI 12020 (ashiftrt:V4SI 12021 (plus:V4SI 12022 (mult:V4SI 12023 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r")) 12024 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r"))) 12025 (const_int 16384)) 12026 (const_int 15))))] 12027 "TARGET_SHMEDIA" 12028 "mmulfxrp.w %1, %2, %0" 12029 [(set_attr "type" "dmpy_media") 12030 (set_attr "highpart" "depend")]) 12031 12032 12033(define_expand "mmulhi_wl" 12034 [(match_operand:V2SI 0 "arith_reg_dest" "") 12035 (match_operand:V4HI 1 "arith_reg_operand" "") 12036 (match_operand:V4HI 2 "arith_reg_operand" "")] 12037 "TARGET_SHMEDIA" 12038 " 12039{ 12040 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl) 12041 (operands[0], operands[1], operands[2])); 12042 DONE; 12043}") 12044 12045(define_expand "mmullo_wl" 12046 [(match_operand:V2SI 0 "arith_reg_dest" "") 12047 (match_operand:V4HI 1 "arith_reg_operand" "") 12048 (match_operand:V4HI 2 "arith_reg_operand" "")] 12049 "TARGET_SHMEDIA" 12050 " 12051{ 12052 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl) 12053 (operands[0], operands[1], operands[2])); 12054 DONE; 12055}") 12056 12057(define_insn "mmul23_wl" 12058 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r") 12059 (vec_select:V2SI 12060 (mult:V4SI 12061 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r")) 12062 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r"))) 12063 (parallel [(const_int 2) (const_int 3)])))] 12064 "TARGET_SHMEDIA" 12065 "* return (TARGET_LITTLE_ENDIAN 12066 ? \"mmulhi.wl %1, %2, %0\" 12067 : \"mmullo.wl %1, %2, %0\");" 12068 [(set_attr "type" "dmpy_media") 12069 (set (attr "highpart") 12070 (cond [(eq_attr "endian" "big") (const_string "ignore")] 12071 (const_string "user")))]) 12072 12073(define_insn "mmul01_wl" 12074 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r") 12075 (vec_select:V2SI 12076 (mult:V4SI 12077 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r")) 12078 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r"))) 12079 (parallel [(const_int 0) (const_int 1)])))] 12080 "TARGET_SHMEDIA" 12081 "* return (TARGET_LITTLE_ENDIAN 12082 ? \"mmullo.wl %1, %2, %0\" 12083 : \"mmulhi.wl %1, %2, %0\");" 12084 [(set_attr "type" "dmpy_media") 12085 (set (attr "highpart") 12086 (cond [(eq_attr "endian" "little") (const_string "ignore")] 12087 (const_string "user")))]) 12088 12089 12090(define_expand "mmulsum_wq" 12091 [(match_operand:DI 0 "arith_reg_dest" "") 12092 (match_operand:V4HI 1 "arith_reg_operand" "") 12093 (match_operand:V4HI 2 "arith_reg_operand" "") 12094 (match_operand:DI 3 "arith_reg_operand" "")] 12095 "TARGET_SHMEDIA" 12096 " 12097{ 12098 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3], 12099 operands[1], operands[2])); 12100 DONE; 12101}") 12102 12103(define_insn "mmulsum_wq_i" 12104 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 12105 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0") 12106 (plus:DI 12107 (plus:DI 12108 (vec_select:DI 12109 (mult:V4DI 12110 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r")) 12111 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r"))) 12112 (parallel [(const_int 0)])) 12113 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2)) 12114 (sign_extend:V4DI (match_dup 3))) 12115 (parallel [(const_int 1)]))) 12116 (plus:DI 12117 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2)) 12118 (sign_extend:V4DI (match_dup 3))) 12119 (parallel [(const_int 2)])) 12120 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2)) 12121 (sign_extend:V4DI (match_dup 3))) 12122 (parallel [(const_int 3)]))))))] 12123 "TARGET_SHMEDIA" 12124 "mmulsum.wq %2, %3, %0" 12125 [(set_attr "type" "mac_media")]) 12126 12127(define_expand "mperm_w" 12128 [(match_operand:V4HI 0 "arith_reg_dest" "=r") 12129 (match_operand:V4HI 1 "arith_reg_operand" "r") 12130 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")] 12131 "TARGET_SHMEDIA" 12132 " 12133{ 12134 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big) 12135 (operands[0], operands[1], operands[2])); 12136 DONE; 12137}") 12138 12139; This use of vec_select isn't exactly correct according to rtl.texi 12140; (because not constant), but it seems a straightforward extension. 12141(define_insn "mperm_w_little" 12142 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r") 12143 (vec_select:V4HI 12144 (match_operand:V4HI 1 "arith_reg_operand" "r") 12145 (parallel 12146 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ") 12147 (const_int 2) (const_int 0)) 12148 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2)) 12149 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4)) 12150 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))] 12151 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN" 12152 "mperm.w %1, %N2, %0" 12153 [(set_attr "type" "arith_media")]) 12154 12155(define_insn "mperm_w_big" 12156 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r") 12157 (vec_select:V4HI 12158 (match_operand:V4HI 1 "arith_reg_operand" "r") 12159 (parallel 12160 [(zero_extract:QI (not:QI (match_operand:QI 2 12161 "extend_reg_or_0_operand" "rZ")) 12162 (const_int 2) (const_int 0)) 12163 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2)) 12164 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4)) 12165 (zero_extract:QI (not:QI (match_dup 2)) 12166 (const_int 2) (const_int 6))])))] 12167 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN" 12168 "mperm.w %1, %N2, %0" 12169 [(set_attr "type" "arith_media")]) 12170 12171(define_insn "mperm_w0" 12172 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r") 12173 (vec_duplicate:V4HI (truncate:HI (match_operand 1 12174 "trunc_hi_operand" "r"))))] 12175 "TARGET_SHMEDIA" 12176 "mperm.w %1, r63, %0" 12177 [(set_attr "type" "arith_media") 12178 (set_attr "highpart" "ignore")]) 12179 12180(define_expand "msad_ubq" 12181 [(match_operand:DI 0 "arith_reg_dest" "") 12182 (match_operand:V8QI 1 "arith_reg_or_0_operand" "") 12183 (match_operand:V8QI 2 "arith_reg_or_0_operand" "") 12184 (match_operand:DI 3 "arith_reg_operand" "")] 12185 "TARGET_SHMEDIA" 12186 " 12187{ 12188 emit_insn (gen_msad_ubq_i (operands[0], operands[3], 12189 operands[1], operands[2])); 12190 DONE; 12191}") 12192 12193(define_insn "msad_ubq_i" 12194 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 12195 (plus:DI 12196 (plus:DI 12197 (plus:DI 12198 (plus:DI 12199 (match_operand:DI 1 "arith_reg_operand" "0") 12200 (abs:DI (vec_select:DI 12201 (minus:V8DI 12202 (zero_extend:V8DI 12203 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")) 12204 (zero_extend:V8DI 12205 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ"))) 12206 (parallel [(const_int 0)])))) 12207 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2)) 12208 (zero_extend:V8DI (match_dup 3))) 12209 (parallel [(const_int 1)])))) 12210 (plus:DI 12211 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2)) 12212 (zero_extend:V8DI (match_dup 3))) 12213 (parallel [(const_int 2)]))) 12214 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2)) 12215 (zero_extend:V8DI (match_dup 3))) 12216 (parallel [(const_int 3)]))))) 12217 (plus:DI 12218 (plus:DI 12219 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2)) 12220 (zero_extend:V8DI (match_dup 3))) 12221 (parallel [(const_int 4)]))) 12222 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2)) 12223 (zero_extend:V8DI (match_dup 3))) 12224 (parallel [(const_int 5)])))) 12225 (plus:DI 12226 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2)) 12227 (zero_extend:V8DI (match_dup 3))) 12228 (parallel [(const_int 6)]))) 12229 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2)) 12230 (zero_extend:V8DI (match_dup 3))) 12231 (parallel [(const_int 7)])))))))] 12232 "TARGET_SHMEDIA" 12233 "msad.ubq %N2, %N3, %0" 12234 [(set_attr "type" "mac_media")]) 12235 12236(define_insn "mshalds_l" 12237 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r") 12238 (ss_truncate:V2SI 12239 (ashift:V2DI 12240 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r")) 12241 (and:DI (match_operand:DI 2 "arith_reg_operand" "r") 12242 (const_int 31)))))] 12243 "TARGET_SHMEDIA" 12244 "mshalds.l %1, %2, %0" 12245 [(set_attr "type" "mcmp_media") 12246 (set_attr "highpart" "depend")]) 12247 12248(define_insn "mshalds_w" 12249 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r") 12250 (ss_truncate:V4HI 12251 (ashift:V4SI 12252 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r")) 12253 (and:DI (match_operand:DI 2 "arith_reg_operand" "r") 12254 (const_int 15)))))] 12255 "TARGET_SHMEDIA" 12256 "mshalds.w %1, %2, %0" 12257 [(set_attr "type" "mcmp_media") 12258 (set_attr "highpart" "depend")]) 12259 12260(define_insn "ashrv2si3" 12261 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r") 12262 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r") 12263 (match_operand:DI 2 "arith_reg_operand" "r")))] 12264 "TARGET_SHMEDIA" 12265 "mshard.l %1, %2, %0" 12266 [(set_attr "type" "arith_media") 12267 (set_attr "highpart" "depend")]) 12268 12269(define_insn "ashrv4hi3" 12270 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r") 12271 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r") 12272 (match_operand:DI 2 "arith_reg_operand" "r")))] 12273 "TARGET_SHMEDIA" 12274 "mshard.w %1, %2, %0" 12275 [(set_attr "type" "arith_media") 12276 (set_attr "highpart" "depend")]) 12277 12278(define_insn "mshards_q" 12279 [(set (match_operand:HI 0 "arith_reg_dest" "=r") 12280 (ss_truncate:HI 12281 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r") 12282 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))] 12283 "TARGET_SHMEDIA" 12284 "mshards.q %1, %N2, %0" 12285 [(set_attr "type" "mcmp_media")]) 12286 12287(define_expand "mshfhi_b" 12288 [(match_operand:V8QI 0 "arith_reg_dest" "") 12289 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ") 12290 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")] 12291 "TARGET_SHMEDIA" 12292 " 12293{ 12294 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b) 12295 (operands[0], operands[1], operands[2])); 12296 DONE; 12297}") 12298 12299(define_expand "mshflo_b" 12300 [(match_operand:V8QI 0 "arith_reg_dest" "") 12301 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ") 12302 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")] 12303 "TARGET_SHMEDIA" 12304 " 12305{ 12306 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b) 12307 (operands[0], operands[1], operands[2])); 12308 DONE; 12309}") 12310 12311(define_insn "mshf4_b" 12312 [(set 12313 (match_operand:V8QI 0 "arith_reg_dest" "=r") 12314 (vec_select:V8QI 12315 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ") 12316 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")) 12317 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13) 12318 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))] 12319 "TARGET_SHMEDIA" 12320 "* return (TARGET_LITTLE_ENDIAN 12321 ? \"mshfhi.b %N1, %N2, %0\" 12322 : \"mshflo.b %N1, %N2, %0\");" 12323 [(set_attr "type" "arith_media") 12324 (set (attr "highpart") 12325 (cond [(eq_attr "endian" "big") (const_string "ignore")] 12326 (const_string "user")))]) 12327 12328(define_insn "mshf0_b" 12329 [(set 12330 (match_operand:V8QI 0 "arith_reg_dest" "=r") 12331 (vec_select:V8QI 12332 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ") 12333 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")) 12334 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9) 12335 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))] 12336 "TARGET_SHMEDIA" 12337 "* return (TARGET_LITTLE_ENDIAN 12338 ? \"mshflo.b %N1, %N2, %0\" 12339 : \"mshfhi.b %N1, %N2, %0\");" 12340 [(set_attr "type" "arith_media") 12341 (set (attr "highpart") 12342 (cond [(eq_attr "endian" "little") (const_string "ignore")] 12343 (const_string "user")))]) 12344 12345(define_expand "mshfhi_l" 12346 [(match_operand:V2SI 0 "arith_reg_dest" "") 12347 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ") 12348 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")] 12349 "TARGET_SHMEDIA" 12350 " 12351{ 12352 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l) 12353 (operands[0], operands[1], operands[2])); 12354 DONE; 12355}") 12356 12357(define_expand "mshflo_l" 12358 [(match_operand:V2SI 0 "arith_reg_dest" "") 12359 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ") 12360 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")] 12361 "TARGET_SHMEDIA" 12362 " 12363{ 12364 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l) 12365 (operands[0], operands[1], operands[2])); 12366 DONE; 12367}") 12368 12369(define_insn "mshf4_l" 12370 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r") 12371 (vec_select:V2SI 12372 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ") 12373 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")) 12374 (parallel [(const_int 1) (const_int 3)])))] 12375 "TARGET_SHMEDIA" 12376 "* return (TARGET_LITTLE_ENDIAN 12377 ? \"mshfhi.l %N1, %N2, %0\" 12378 : \"mshflo.l %N1, %N2, %0\");" 12379 [(set_attr "type" "arith_media") 12380 (set (attr "highpart") 12381 (cond [(eq_attr "endian" "big") (const_string "ignore")] 12382 (const_string "user")))]) 12383 12384(define_insn "mshf0_l" 12385 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r") 12386 (vec_select:V2SI 12387 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ") 12388 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")) 12389 (parallel [(const_int 0) (const_int 2)])))] 12390 "TARGET_SHMEDIA" 12391 "* return (TARGET_LITTLE_ENDIAN 12392 ? \"mshflo.l %N1, %N2, %0\" 12393 : \"mshfhi.l %N1, %N2, %0\");" 12394 [(set_attr "type" "arith_media") 12395 (set (attr "highpart") 12396 (cond [(eq_attr "endian" "little") (const_string "ignore")] 12397 (const_string "user")))]) 12398 12399(define_expand "mshfhi_w" 12400 [(match_operand:V4HI 0 "arith_reg_dest" "") 12401 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ") 12402 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")] 12403 "TARGET_SHMEDIA" 12404 " 12405{ 12406 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w) 12407 (operands[0], operands[1], operands[2])); 12408 DONE; 12409}") 12410 12411(define_expand "mshflo_w" 12412 [(match_operand:V4HI 0 "arith_reg_dest" "") 12413 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ") 12414 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")] 12415 "TARGET_SHMEDIA" 12416 " 12417{ 12418 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w) 12419 (operands[0], operands[1], operands[2])); 12420 DONE; 12421}") 12422 12423(define_insn "mshf4_w" 12424 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r") 12425 (vec_select:V4HI 12426 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ") 12427 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")) 12428 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))] 12429 "TARGET_SHMEDIA" 12430 "* return (TARGET_LITTLE_ENDIAN 12431 ? \"mshfhi.w %N1, %N2, %0\" 12432 : \"mshflo.w %N1, %N2, %0\");" 12433 [(set_attr "type" "arith_media") 12434 (set (attr "highpart") 12435 (cond [(eq_attr "endian" "big") (const_string "ignore")] 12436 (const_string "user")))]) 12437 12438(define_insn "mshf0_w" 12439 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r") 12440 (vec_select:V4HI 12441 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ") 12442 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")) 12443 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))] 12444 "TARGET_SHMEDIA" 12445 "* return (TARGET_LITTLE_ENDIAN 12446 ? \"mshflo.w %N1, %N2, %0\" 12447 : \"mshfhi.w %N1, %N2, %0\");" 12448 [(set_attr "type" "arith_media") 12449 (set (attr "highpart") 12450 (cond [(eq_attr "endian" "little") (const_string "ignore")] 12451 (const_string "user")))]) 12452 12453(define_insn "mshflo_w_x" 12454 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r") 12455 (vec_select:V4HI 12456 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ") 12457 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ")) 12458 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))] 12459 "TARGET_SHMEDIA" 12460 "mshflo.w %N1, %N2, %0" 12461 [(set_attr "type" "arith_media") 12462 (set_attr "highpart" "ignore")]) 12463 12464/* These are useful to expand ANDs and as combiner patterns. */ 12465(define_insn_and_split "mshfhi_l_di" 12466 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f") 12467 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f") 12468 (const_int 32)) 12469 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f") 12470 (const_int -4294967296))))] 12471 "TARGET_SHMEDIA" 12472 "@ 12473 mshfhi.l %N1, %N2, %0 12474 #" 12475 "TARGET_SHMEDIA && reload_completed 12476 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))" 12477 [(set (match_dup 3) (match_dup 4)) 12478 (set (match_dup 5) (match_dup 6))] 12479 " 12480{ 12481 operands[3] = gen_lowpart (SImode, operands[0]); 12482 operands[4] = gen_highpart (SImode, operands[1]); 12483 operands[5] = gen_highpart (SImode, operands[0]); 12484 operands[6] = gen_highpart (SImode, operands[2]); 12485}" 12486 [(set_attr "type" "arith_media")]) 12487 12488(define_insn "*mshfhi_l_di_rev" 12489 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 12490 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ") 12491 (const_int -4294967296)) 12492 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ") 12493 (const_int 32))))] 12494 "TARGET_SHMEDIA" 12495 "mshfhi.l %N2, %N1, %0" 12496 [(set_attr "type" "arith_media")]) 12497 12498(define_split 12499 [(set (match_operand:DI 0 "arith_reg_dest" "") 12500 (ior:DI (zero_extend:DI (match_operand:SI 1 12501 "extend_reg_or_0_operand" "")) 12502 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "") 12503 (const_int -4294967296)))) 12504 (clobber (match_operand:DI 3 "arith_reg_dest" ""))] 12505 "TARGET_SHMEDIA" 12506 [(const_int 0)] 12507 " 12508{ 12509 emit_insn (gen_ashldi3_media (operands[3], 12510 simplify_gen_subreg (DImode, operands[1], 12511 SImode, 0), 12512 GEN_INT (32))); 12513 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2])); 12514 DONE; 12515}") 12516 12517(define_insn "mshflo_l_di" 12518 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 12519 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ") 12520 (const_int 4294967295)) 12521 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ") 12522 (const_int 32))))] 12523 12524 "TARGET_SHMEDIA" 12525 "mshflo.l %N1, %N2, %0" 12526 [(set_attr "type" "arith_media") 12527 (set_attr "highpart" "ignore")]) 12528 12529(define_insn "*mshflo_l_di_rev" 12530 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 12531 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ") 12532 (const_int 32)) 12533 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ") 12534 (const_int 4294967295))))] 12535 12536 "TARGET_SHMEDIA" 12537 "mshflo.l %N2, %N1, %0" 12538 [(set_attr "type" "arith_media") 12539 (set_attr "highpart" "ignore")]) 12540 12541;; Combiner pattern for trampoline initialization. 12542(define_insn_and_split "*double_shori" 12543 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 12544 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0") 12545 (const_int 32)) 12546 (match_operand:DI 2 "const_int_operand" "n")))] 12547 "TARGET_SHMEDIA 12548 && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)" 12549 "#" 12550 "rtx_equal_p (operands[0], operands[1])" 12551 [(const_int 0)] 12552 " 12553{ 12554 HOST_WIDE_INT v = INTVAL (operands[2]); 12555 12556 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16))); 12557 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535))); 12558 DONE; 12559}" 12560 [(set_attr "highpart" "ignore")]) 12561 12562 12563(define_insn "*mshflo_l_di_x" 12564 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 12565 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand" 12566 "rZ")) 12567 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ") 12568 (const_int 32))))] 12569 12570 "TARGET_SHMEDIA" 12571 "mshflo.l %N1, %N2, %0" 12572 [(set_attr "type" "arith_media") 12573 (set_attr "highpart" "ignore")]) 12574 12575(define_insn_and_split "concat_v2sf" 12576 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?") 12577;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f") 12578 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f") 12579 (match_operand:SF 2 "register_operand" "rZ,f,f")))] 12580 12581 "TARGET_SHMEDIA" 12582 "@ 12583 mshflo.l %N1, %N2, %0 12584 # 12585 #" 12586 "TARGET_SHMEDIA && reload_completed 12587 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))" 12588 [(set (match_dup 3) (match_dup 1)) 12589 (set (match_dup 4) (match_dup 2))] 12590 " 12591{ 12592 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0); 12593 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4); 12594}" 12595 [(set_attr "type" "arith_media") 12596 (set_attr "highpart" "ignore")]) 12597 12598(define_insn "*mshflo_l_di_x_rev" 12599 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 12600 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ") 12601 (const_int 32)) 12602 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))] 12603 12604 "TARGET_SHMEDIA" 12605 "mshflo.l %N2, %N1, %0" 12606 [(set_attr "type" "arith_media") 12607 (set_attr "highpart" "ignore")]) 12608 12609(define_insn "ashlv2si3" 12610 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r") 12611 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r") 12612 (match_operand:DI 2 "shift_count_reg_operand" "r")))] 12613 "TARGET_SHMEDIA" 12614 "mshlld.l %1, %2, %0" 12615 [(set_attr "type" "arith_media") 12616 (set_attr "highpart" "depend")]) 12617 12618(define_split 12619 [(set (match_operand 0 "any_register_operand" "") 12620 (match_operator 3 "shift_operator" 12621 [(match_operand 1 "any_register_operand" "") 12622 (match_operand 2 "shift_count_reg_operand" "")]))] 12623 "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)" 12624 [(set (match_dup 0) (match_dup 3))] 12625 " 12626{ 12627 rtx count = operands[2]; 12628 enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode; 12629 12630 while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND 12631 || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0) 12632 || GET_CODE (count) == TRUNCATE) 12633 count = XEXP (count, 0); 12634 inner_mode = GET_MODE (count); 12635 count = simplify_gen_subreg (outer_mode, count, inner_mode, 12636 subreg_lowpart_offset (outer_mode, inner_mode)); 12637 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]), 12638 operands[1], count); 12639}") 12640 12641(define_insn "ashlv4hi3" 12642 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r") 12643 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r") 12644 (match_operand:DI 2 "shift_count_reg_operand" "r")))] 12645 "TARGET_SHMEDIA" 12646 "mshlld.w %1, %2, %0" 12647 [(set_attr "type" "arith_media") 12648 (set_attr "highpart" "depend")]) 12649 12650(define_insn "lshrv2si3" 12651 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r") 12652 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r") 12653 (match_operand:DI 2 "shift_count_reg_operand" "r")))] 12654 "TARGET_SHMEDIA" 12655 "mshlrd.l %1, %2, %0" 12656 [(set_attr "type" "arith_media") 12657 (set_attr "highpart" "depend")]) 12658 12659(define_insn "lshrv4hi3" 12660 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r") 12661 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r") 12662 (match_operand:DI 2 "shift_count_reg_operand" "r")))] 12663 "TARGET_SHMEDIA" 12664 "mshlrd.w %1, %2, %0" 12665 [(set_attr "type" "arith_media") 12666 (set_attr "highpart" "depend")]) 12667 12668(define_insn "subv2si3" 12669 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r") 12670 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ") 12671 (match_operand:V2SI 2 "arith_reg_operand" "r")))] 12672 "TARGET_SHMEDIA" 12673 "msub.l %N1, %2, %0" 12674 [(set_attr "type" "arith_media") 12675 (set_attr "highpart" "depend")]) 12676 12677(define_insn "subv4hi3" 12678 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r") 12679 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ") 12680 (match_operand:V4HI 2 "arith_reg_operand" "r")))] 12681 "TARGET_SHMEDIA" 12682 "msub.w %N1, %2, %0" 12683 [(set_attr "type" "arith_media") 12684 (set_attr "highpart" "depend")]) 12685 12686(define_insn_and_split "subv2hi3" 12687 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r") 12688 (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ") 12689 (match_operand:V2HI 2 "arith_reg_operand" "r")))] 12690 "TARGET_SHMEDIA" 12691 "#" 12692 "TARGET_SHMEDIA" 12693 [(const_int 0)] 12694 " 12695{ 12696 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0); 12697 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0); 12698 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0); 12699 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0); 12700 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0); 12701 12702 emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1)); 12703 emit_insn (gen_truncdisi2 (si_dst, di_dst)); 12704 DONE; 12705}" 12706 [(set_attr "highpart" "must_split")]) 12707 12708(define_insn "sssubv2si3" 12709 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r") 12710 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ") 12711 (match_operand:V2SI 2 "arith_reg_operand" "r")))] 12712 "TARGET_SHMEDIA" 12713 "msubs.l %N1, %2, %0" 12714 [(set_attr "type" "mcmp_media") 12715 (set_attr "highpart" "depend")]) 12716 12717(define_insn "ussubv8qi3" 12718 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r") 12719 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ") 12720 (match_operand:V8QI 2 "arith_reg_operand" "r")))] 12721 "TARGET_SHMEDIA" 12722 "msubs.ub %N1, %2, %0" 12723 [(set_attr "type" "mcmp_media") 12724 (set_attr "highpart" "depend")]) 12725 12726(define_insn "sssubv4hi3" 12727 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r") 12728 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ") 12729 (match_operand:V4HI 2 "arith_reg_operand" "r")))] 12730 "TARGET_SHMEDIA" 12731 "msubs.w %N1, %2, %0" 12732 [(set_attr "type" "mcmp_media") 12733 (set_attr "highpart" "depend")]) 12734 12735;; Floating Point Intrinsics 12736 12737(define_insn "fcosa_s" 12738 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f") 12739 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")] 12740 UNSPEC_FCOSA))] 12741 "TARGET_SHMEDIA" 12742 "fcosa.s %1, %0" 12743 [(set_attr "type" "atrans_media")]) 12744 12745(define_insn "fsina_s" 12746 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f") 12747 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")] 12748 UNSPEC_FSINA))] 12749 "TARGET_SHMEDIA" 12750 "fsina.s %1, %0" 12751 [(set_attr "type" "atrans_media")]) 12752 12753(define_insn "fipr" 12754 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f") 12755 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1 12756 "fp_arith_reg_operand" "f") 12757 (match_operand:V4SF 2 12758 "fp_arith_reg_operand" "f")) 12759 (parallel [(const_int 0)])) 12760 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2)) 12761 (parallel [(const_int 1)]))) 12762 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2)) 12763 (parallel [(const_int 2)])) 12764 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2)) 12765 (parallel [(const_int 3)])))))] 12766 "TARGET_SHMEDIA" 12767 "fipr.s %1, %2, %0" 12768 [(set_attr "type" "fparith_media")]) 12769 12770(define_insn "fsrra_s" 12771 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f") 12772 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")] 12773 UNSPEC_FSRRA))] 12774 "TARGET_SHMEDIA" 12775 "fsrra.s %1, %0" 12776 [(set_attr "type" "atrans_media")]) 12777 12778(define_insn "ftrv" 12779 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f") 12780 (plus:V4SF 12781 (plus:V4SF 12782 (mult:V4SF 12783 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f") 12784 (parallel [(const_int 0) (const_int 5) 12785 (const_int 10) (const_int 15)])) 12786 (match_operand:V4SF 2 "fp_arith_reg_operand" "f")) 12787 (mult:V4SF 12788 (vec_select:V4SF (match_dup 1) 12789 (parallel [(const_int 4) (const_int 9) 12790 (const_int 14) (const_int 3)])) 12791 (vec_select:V4SF (match_dup 2) 12792 (parallel [(const_int 1) (const_int 2) 12793 (const_int 3) (const_int 0)])))) 12794 (plus:V4SF 12795 (mult:V4SF 12796 (vec_select:V4SF (match_dup 1) 12797 (parallel [(const_int 8) (const_int 13) 12798 (const_int 2) (const_int 7)])) 12799 (vec_select:V4SF (match_dup 2) 12800 (parallel [(const_int 2) (const_int 3) 12801 (const_int 0) (const_int 1)]))) 12802 (mult:V4SF 12803 (vec_select:V4SF (match_dup 1) 12804 (parallel [(const_int 12) (const_int 1) 12805 (const_int 6) (const_int 11)])) 12806 (vec_select:V4SF (match_dup 2) 12807 (parallel [(const_int 3) (const_int 0) 12808 (const_int 1) (const_int 2)]))))))] 12809 "TARGET_SHMEDIA" 12810 "ftrv.s %1, %2, %0" 12811 [(set_attr "type" "fparith_media")]) 12812 12813(define_insn "ldhi_l" 12814 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 12815 (zero_extract:SI 12816 (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p") 12817 (const_int 3)) 12818 (const_int -3))) 12819 (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1)) 12820 (const_int 0)))] 12821 "TARGET_SHMEDIA32" 12822 "ldhi.l %U1, %0" 12823 [(set_attr "type" "load_media")]) 12824 12825(define_insn "ldhi_q" 12826 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 12827 (zero_extract:DI 12828 (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p") 12829 (const_int 7)) 12830 (const_int -7))) 12831 (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1)) 12832 (const_int 0)))] 12833 "TARGET_SHMEDIA32" 12834 "ldhi.q %U1, %0" 12835 [(set_attr "type" "load_media")]) 12836 12837(define_insn_and_split "*ldhi_q_comb0" 12838 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 12839 (zero_extract:DI 12840 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1 12841 "register_operand" "r") 12842 (match_operand:SI 2 12843 "ua_offset" "I06")) 12844 (const_int 7)) 12845 (const_int -7))) 12846 (plus:SI (and:SI (match_dup 1) (const_int 7)) 12847 (const_int 1)) 12848 (const_int 0)))] 12849 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0" 12850 "#" 12851 "" 12852 [(pc)] 12853 "emit_insn (gen_ldhi_q (operands[0], 12854 gen_rtx_PLUS (SImode, operands[1], operands[2]))); 12855 DONE;") 12856 12857 12858(define_insn_and_split "*ldhi_q_comb1" 12859 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 12860 (zero_extract:DI 12861 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1 12862 "register_operand" "r") 12863 (match_operand:SI 2 12864 "ua_offset" "I06")) 12865 (const_int 7)) 12866 (const_int -7))) 12867 (plus:SI (and:SI (plus:SI (match_dup 1) (match_operand:SI 3 12868 "ua_offset" "I06")) 12869 (const_int 7)) 12870 (const_int 1)) 12871 (const_int 0)))] 12872 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8) 12873 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])" 12874 "#" 12875 "" 12876 [(pc)] 12877 "emit_insn (gen_ldhi_q (operands[0], 12878 gen_rtx_PLUS (SImode, operands[1], operands[2]))); 12879 DONE;") 12880 12881 12882(define_insn "ldlo_l" 12883 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 12884 (zero_extract:SI 12885 (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p") 12886 (const_int -4))) 12887 (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3))) 12888 (and:SI (match_dup 1) (const_int 3))))] 12889 "TARGET_SHMEDIA32" 12890 "ldlo.l %U1, %0" 12891 [(set_attr "type" "load_media")]) 12892 12893(define_insn "ldlo_q" 12894 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 12895 (zero_extract:DI 12896 (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p") 12897 (const_int -8))) 12898 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7))) 12899 (and:SI (match_dup 1) (const_int 7))))] 12900 "TARGET_SHMEDIA32" 12901 "ldlo.q %U1, %0" 12902 [(set_attr "type" "load_media")]) 12903 12904(define_insn_and_split "*ldlo_q_comb0" 12905 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 12906 (zero_extract:DI 12907 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r") 12908 (match_operand:SI 2 "ua_offset" "I06")) 12909 (const_int -8))) 12910 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7))) 12911 (and:SI (match_dup 1) (const_int 7))))] 12912 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0" 12913 "#" 12914 "" 12915 [(pc)] 12916 "emit_insn (gen_ldlo_q (operands[0], 12917 gen_rtx_PLUS (SImode, operands[1], operands[2]))); 12918 DONE;") 12919 12920(define_insn_and_split "*ldlo_q_comb1" 12921 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 12922 (zero_extract:DI 12923 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r") 12924 (match_operand:SI 2 "ua_offset" "I06")) 12925 (const_int -8))) 12926 (minus:SI (const_int 8) 12927 (and:SI (plus:SI (match_dup 1) 12928 (match_operand:SI 3 "ua_offset" "I06")) 12929 (const_int 7))) 12930 (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))] 12931 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8) 12932 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])" 12933 "#" 12934 "" 12935 [(pc)] 12936 "emit_insn (gen_ldlo_q (operands[0], 12937 gen_rtx_PLUS (SImode, operands[1], operands[2]))); 12938 DONE;") 12939 12940(define_insn "sthi_l" 12941 [(set (zero_extract:SI 12942 (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p") 12943 (const_int 3)) 12944 (const_int -3))) 12945 (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1)) 12946 (const_int 0)) 12947 (match_operand:SI 1 "arith_reg_operand" "r"))] 12948 "TARGET_SHMEDIA32" 12949 "sthi.l %U0, %1" 12950 [(set_attr "type" "ustore_media")]) 12951 12952;; All unaligned stores are considered to be 'narrow' because they typically 12953;; operate on less that a quadword, and when they operate on a full quadword, 12954;; the vanilla store high / store low sequence will cause a stall if not 12955;; scheduled apart. 12956(define_insn "sthi_q" 12957 [(set (zero_extract:DI 12958 (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p") 12959 (const_int 7)) 12960 (const_int -7))) 12961 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1)) 12962 (const_int 0)) 12963 (match_operand:DI 1 "arith_reg_operand" "r"))] 12964 "TARGET_SHMEDIA32" 12965 "sthi.q %U0, %1" 12966 [(set_attr "type" "ustore_media")]) 12967 12968(define_insn_and_split "*sthi_q_comb0" 12969 [(set (zero_extract:DI 12970 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0 12971 "register_operand" "r") 12972 (match_operand:SI 1 "ua_offset" 12973 "I06")) 12974 (const_int 7)) 12975 (const_int -7))) 12976 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1)) 12977 (const_int 0)) 12978 (match_operand:DI 2 "arith_reg_operand" "r"))] 12979 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0" 12980 "#" 12981 "" 12982 [(pc)] 12983 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]), 12984 operands[2])); 12985 DONE;") 12986 12987(define_insn_and_split "*sthi_q_comb1" 12988 [(set (zero_extract:DI 12989 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0 12990 "register_operand" "r") 12991 (match_operand:SI 1 "ua_offset" 12992 "I06")) 12993 (const_int 7)) 12994 (const_int -7))) 12995 (plus:SI (and:SI (plus:SI (match_dup 0) 12996 (match_operand:SI 2 "ua_offset" "I06")) 12997 (const_int 7)) 12998 (const_int 1)) 12999 (const_int 0)) 13000 (match_operand:DI 3 "arith_reg_operand" "r"))] 13001 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8) 13002 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])" 13003 "#" 13004 "" 13005 [(pc)] 13006 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]), 13007 operands[3])); 13008 DONE;") 13009 13010;; This is highpart user because the address is used as full 64 bit. 13011(define_insn "stlo_l" 13012 [(set (zero_extract:SI 13013 (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p") 13014 (const_int -4))) 13015 (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3))) 13016 (and:SI (match_dup 0) (const_int 3))) 13017 (match_operand:SI 1 "arith_reg_operand" "r"))] 13018 "TARGET_SHMEDIA32" 13019 "stlo.l %U0, %1" 13020 [(set_attr "type" "ustore_media")]) 13021 13022(define_insn "stlo_q" 13023 [(set (zero_extract:DI 13024 (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p") 13025 (const_int -8))) 13026 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7))) 13027 (and:SI (match_dup 0) (const_int 7))) 13028 (match_operand:DI 1 "arith_reg_operand" "r"))] 13029 "TARGET_SHMEDIA32" 13030 "stlo.q %U0, %1" 13031 [(set_attr "type" "ustore_media")]) 13032 13033(define_insn_and_split "*stlo_q_comb0" 13034 [(set (zero_extract:DI 13035 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r") 13036 (match_operand:SI 1 "ua_offset" "I06")) 13037 (const_int -8))) 13038 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7))) 13039 (and:SI (match_dup 0) (const_int 7))) 13040 (match_operand:DI 2 "arith_reg_operand" "r"))] 13041 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0" 13042 "#" 13043 "" 13044 [(pc)] 13045 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]), 13046 operands[2])); 13047 DONE;") 13048 13049(define_insn_and_split "*stlo_q_comb1" 13050 [(set (zero_extract:DI 13051 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r") 13052 (match_operand:SI 1 "ua_offset" "I06")) 13053 (const_int -8))) 13054 (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0) 13055 (match_operand:SI 2 13056 "ua_offset" "I06")) 13057 (const_int 7))) 13058 (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7))) 13059 (match_operand:DI 3 "arith_reg_operand" "r"))] 13060 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])" 13061 "#" 13062 "" 13063 [(pc)] 13064 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]), 13065 operands[3])); 13066 DONE;") 13067 13068(define_insn "ldhi_l64" 13069 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 13070 (zero_extract:SI 13071 (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p") 13072 (const_int 3)) 13073 (const_int -3))) 13074 (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1)) 13075 (const_int 0)))] 13076 "TARGET_SHMEDIA64" 13077 "ldhi.l %U1, %0" 13078 [(set_attr "type" "load_media")]) 13079 13080(define_insn "ldhi_q64" 13081 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 13082 (zero_extract:DI 13083 (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p") 13084 (const_int 7)) 13085 (const_int -7))) 13086 (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1)) 13087 (const_int 0)))] 13088 "TARGET_SHMEDIA64" 13089 "ldhi.q %U1, %0" 13090 [(set_attr "type" "load_media")]) 13091 13092(define_insn "ldlo_l64" 13093 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 13094 (zero_extract:SI 13095 (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p") 13096 (const_int -4))) 13097 (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3))) 13098 (and:DI (match_dup 1) (const_int 3))))] 13099 "TARGET_SHMEDIA64" 13100 "ldlo.l %U1, %0" 13101 [(set_attr "type" "load_media")]) 13102 13103(define_insn "ldlo_q64" 13104 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 13105 (zero_extract:DI 13106 (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p") 13107 (const_int -8))) 13108 (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7))) 13109 (and:DI (match_dup 1) (const_int 7))))] 13110 "TARGET_SHMEDIA64" 13111 "ldlo.q %U1, %0" 13112 [(set_attr "type" "load_media")]) 13113 13114(define_insn "sthi_l64" 13115 [(set (zero_extract:SI 13116 (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p") 13117 (const_int 3)) 13118 (const_int -3))) 13119 (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1)) 13120 (const_int 0)) 13121 (match_operand:SI 1 "arith_reg_operand" "r"))] 13122 "TARGET_SHMEDIA64" 13123 "sthi.l %U0, %1" 13124 [(set_attr "type" "ustore_media")]) 13125 13126(define_insn "sthi_q64" 13127 [(set (zero_extract:DI 13128 (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p") 13129 (const_int 7)) 13130 (const_int -7))) 13131 (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1)) 13132 (const_int 0)) 13133 (match_operand:DI 1 "arith_reg_operand" "r"))] 13134 "TARGET_SHMEDIA64" 13135 "sthi.q %U0, %1" 13136 [(set_attr "type" "ustore_media")]) 13137 13138(define_insn "stlo_l64" 13139 [(set (zero_extract:SI 13140 (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p") 13141 (const_int -4))) 13142 (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3))) 13143 (and:DI (match_dup 0) (const_int 3))) 13144 (match_operand:SI 1 "arith_reg_operand" "r"))] 13145 "TARGET_SHMEDIA64" 13146 "stlo.l %U0, %1" 13147 [(set_attr "type" "ustore_media")]) 13148 13149(define_insn "stlo_q64" 13150 [(set (zero_extract:DI 13151 (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p") 13152 (const_int -8))) 13153 (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7))) 13154 (and:DI (match_dup 0) (const_int 7))) 13155 (match_operand:DI 1 "arith_reg_operand" "r"))] 13156 "TARGET_SHMEDIA64" 13157 "stlo.q %U0, %1" 13158 [(set_attr "type" "ustore_media")]) 13159 13160(define_insn "nsb" 13161 [(set (match_operand:QI 0 "arith_reg_dest" "=r") 13162 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")] 13163 UNSPEC_NSB))] 13164 "TARGET_SHMEDIA" 13165 "nsb %1, %0" 13166 [(set_attr "type" "arith_media")]) 13167 13168(define_insn "nsbsi" 13169 [(set (match_operand:SI 0 "arith_reg_dest" "=r") 13170 (zero_extend:SI 13171 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")] 13172 UNSPEC_NSB)))] 13173 "TARGET_SHMEDIA" 13174 "nsb %1, %0" 13175 [(set_attr "type" "arith_media")]) 13176 13177(define_insn "nsbdi" 13178 [(set (match_operand:DI 0 "arith_reg_dest" "=r") 13179 (zero_extend:DI 13180 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")] 13181 UNSPEC_NSB)))] 13182 "TARGET_SHMEDIA" 13183 "nsb %1, %0" 13184 [(set_attr "type" "arith_media")]) 13185 13186(define_expand "ffsdi2" 13187 [(set (match_operand:DI 0 "arith_reg_dest" "") 13188 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))] 13189 "TARGET_SHMEDIA" 13190 " 13191{ 13192 rtx scratch = gen_reg_rtx (DImode); 13193 rtx last; 13194 13195 emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx)); 13196 emit_insn (gen_xordi3 (scratch, operands[1], scratch)); 13197 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx)); 13198 emit_insn (gen_nsbdi (scratch, scratch)); 13199 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64))); 13200 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch)); 13201 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch)); 13202 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (DImode, operands[0])); 13203 13204 DONE; 13205}") 13206 13207(define_expand "ffssi2" 13208 [(set (match_operand:SI 0 "arith_reg_dest" "") 13209 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))] 13210 "TARGET_SHMEDIA" 13211 " 13212{ 13213 rtx scratch = gen_reg_rtx (SImode); 13214 rtx discratch = gen_reg_rtx (DImode); 13215 rtx last; 13216 13217 emit_insn (gen_adddi3 (discratch, 13218 simplify_gen_subreg (DImode, operands[1], SImode, 0), 13219 constm1_rtx)); 13220 emit_insn (gen_andcdi3 (discratch, 13221 simplify_gen_subreg (DImode, operands[1], SImode, 0), 13222 discratch)); 13223 emit_insn (gen_nsbsi (scratch, discratch)); 13224 last = emit_insn (gen_subsi3 (operands[0], 13225 force_reg (SImode, GEN_INT (63)), scratch)); 13226 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (SImode, operands[0])); 13227 13228 DONE; 13229}") 13230 13231(define_insn "byterev" 13232 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r") 13233 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r") 13234 (parallel [(const_int 7) (const_int 6) (const_int 5) 13235 (const_int 4) (const_int 3) (const_int 2) 13236 (const_int 1) (const_int 0)])))] 13237 "TARGET_SHMEDIA" 13238 "byterev %1, %0" 13239 [(set_attr "type" "arith_media")]) 13240 13241(define_insn "*prefetch_media" 13242 [(prefetch (match_operand:QI 0 "address_operand" "p") 13243 (match_operand:SI 1 "const_int_operand" "n") 13244 (match_operand:SI 2 "const_int_operand" "n"))] 13245 "TARGET_SHMEDIA" 13246 "* 13247{ 13248 operands[0] = gen_rtx_MEM (QImode, operands[0]); 13249 output_asm_insn (\"ld%M0.b %m0,r63\", operands); 13250 return \"\"; 13251}" 13252 [(set_attr "type" "other")]) 13253 13254(define_insn "*prefetch_i4" 13255 [(prefetch (match_operand:SI 0 "register_operand" "r") 13256 (match_operand:SI 1 "const_int_operand" "n") 13257 (match_operand:SI 2 "const_int_operand" "n"))] 13258 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && !TARGET_VXWORKS_RTP" 13259 "* 13260{ 13261 return \"pref @%0\"; 13262}" 13263 [(set_attr "type" "other")]) 13264 13265;; In user mode, the "pref" instruction will raise a RADDERR exception 13266;; for accesses to [0x80000000,0xffffffff]. This makes it an unsuitable 13267;; implementation of __builtin_prefetch for VxWorks RTPs. 13268(define_expand "prefetch" 13269 [(prefetch (match_operand 0 "address_operand" "p") 13270 (match_operand:SI 1 "const_int_operand" "n") 13271 (match_operand:SI 2 "const_int_operand" "n"))] 13272 "TARGET_SH2A || ((TARGET_HARD_SH4 || TARGET_SH5) 13273 && (TARGET_SHMEDIA || !TARGET_VXWORKS_RTP))" 13274 " 13275{ 13276 if (GET_MODE (operands[0]) != Pmode 13277 || !CONST_INT_P (operands[1]) 13278 || !CONST_INT_P (operands[2])) 13279 FAIL; 13280 if (! TARGET_SHMEDIA) 13281 operands[0] = force_reg (Pmode, operands[0]); 13282}") 13283 13284(define_insn "prefetch_m2a" 13285 [(prefetch (match_operand:SI 0 "register_operand" "r") 13286 (match_operand:SI 1 "const_int_operand" "n") 13287 (match_operand:SI 2 "const_int_operand" "n"))] 13288 "TARGET_SH2A" 13289 "pref\\t@%0" 13290 [(set_attr "type" "other")]) 13291 13292(define_insn "alloco_i" 13293 [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p")) 13294 (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))] 13295 "TARGET_SHMEDIA32" 13296 "* 13297{ 13298 rtx xops[2]; 13299 13300 if (GET_CODE (operands[0]) == PLUS) 13301 { 13302 xops[0] = XEXP (operands[0], 0); 13303 xops[1] = XEXP (operands[0], 1); 13304 } 13305 else 13306 { 13307 xops[0] = operands[0]; 13308 xops[1] = const0_rtx; 13309 } 13310 output_asm_insn (\"alloco %0, %1\", xops); 13311 return \"\"; 13312}" 13313 [(set_attr "type" "other")]) 13314 13315(define_split 13316 [(set (match_operand 0 "any_register_operand" "") 13317 (match_operand 1 "" ""))] 13318 "TARGET_SHMEDIA && reload_completed" 13319 [(set (match_dup 0) (match_dup 1))] 13320 " 13321{ 13322 int n_changes = 0; 13323 13324 for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes); 13325 if (!n_changes) 13326 FAIL; 13327}") 13328 13329; Stack Protector Patterns 13330 13331(define_expand "stack_protect_set" 13332 [(set (match_operand 0 "memory_operand" "") 13333 (match_operand 1 "memory_operand" ""))] 13334 "" 13335{ 13336 if (TARGET_SHMEDIA) 13337 { 13338 if (TARGET_SHMEDIA64) 13339 emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1])); 13340 else 13341 emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1])); 13342 } 13343 else 13344 emit_insn (gen_stack_protect_set_si (operands[0], operands[1])); 13345 13346 DONE; 13347}) 13348 13349(define_insn "stack_protect_set_si" 13350 [(set (match_operand:SI 0 "memory_operand" "=m") 13351 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET)) 13352 (set (match_scratch:SI 2 "=&r") (const_int 0))] 13353 "!TARGET_SHMEDIA" 13354 "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2" 13355 [(set_attr "type" "other") 13356 (set_attr "length" "6")]) 13357 13358(define_insn "stack_protect_set_si_media" 13359 [(set (match_operand:SI 0 "memory_operand" "=m") 13360 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET)) 13361 (set (match_scratch:SI 2 "=&r") (const_int 0))] 13362 "TARGET_SHMEDIA" 13363 "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2" 13364 [(set_attr "type" "other") 13365 (set_attr "length" "12")]) 13366 13367(define_insn "stack_protect_set_di_media" 13368 [(set (match_operand:DI 0 "memory_operand" "=m") 13369 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET)) 13370 (set (match_scratch:DI 2 "=&r") (const_int 0))] 13371 "TARGET_SHMEDIA64" 13372 "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2" 13373 [(set_attr "type" "other") 13374 (set_attr "length" "12")]) 13375 13376(define_expand "stack_protect_test" 13377 [(match_operand 0 "memory_operand" "") 13378 (match_operand 1 "memory_operand" "") 13379 (match_operand 2 "" "")] 13380 "" 13381{ 13382 if (TARGET_SHMEDIA) 13383 { 13384 rtx tmp = gen_reg_rtx (GET_MODE (operands[0])); 13385 rtx test; 13386 13387 test = gen_rtx_NE (VOIDmode, tmp, const0_rtx); 13388 if (TARGET_SHMEDIA64) 13389 { 13390 emit_insn (gen_stack_protect_test_di_media (tmp, operands[0], 13391 operands[1])); 13392 emit_jump_insn (gen_cbranchdi4 (test, tmp, const0_rtx, operands[2])); 13393 } 13394 else 13395 { 13396 emit_insn (gen_stack_protect_test_si_media (tmp, operands[0], 13397 operands[1])); 13398 emit_jump_insn (gen_cbranchsi4 (test, tmp, const0_rtx, operands[2])); 13399 } 13400 } 13401 else 13402 { 13403 emit_insn (gen_stack_protect_test_si (operands[0], operands[1])); 13404 emit_jump_insn (gen_branch_true (operands[2])); 13405 } 13406 13407 DONE; 13408}) 13409 13410(define_insn "stack_protect_test_si" 13411 [(set (reg:SI T_REG) 13412 (unspec:SI [(match_operand:SI 0 "memory_operand" "m") 13413 (match_operand:SI 1 "memory_operand" "m")] 13414 UNSPEC_SP_TEST)) 13415 (set (match_scratch:SI 2 "=&r") (const_int 0)) 13416 (set (match_scratch:SI 3 "=&r") (const_int 0))] 13417 "!TARGET_SHMEDIA" 13418 "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3" 13419 [(set_attr "type" "other") 13420 (set_attr "length" "10")]) 13421 13422(define_insn "stack_protect_test_si_media" 13423 [(set (match_operand:SI 0 "register_operand" "=&r") 13424 (unspec:SI [(match_operand:SI 1 "memory_operand" "m") 13425 (match_operand:SI 2 "memory_operand" "m")] 13426 UNSPEC_SP_TEST)) 13427 (set (match_scratch:SI 3 "=&r") (const_int 0))] 13428 "TARGET_SHMEDIA" 13429 "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3" 13430 [(set_attr "type" "other") 13431 (set_attr "length" "16")]) 13432 13433(define_insn "stack_protect_test_di_media" 13434 [(set (match_operand:DI 0 "register_operand" "=&r") 13435 (unspec:DI [(match_operand:DI 1 "memory_operand" "m") 13436 (match_operand:DI 2 "memory_operand" "m")] 13437 UNSPEC_SP_TEST)) 13438 (set (match_scratch:DI 3 "=&r") (const_int 0))] 13439 "TARGET_SHMEDIA64" 13440 "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3" 13441 [(set_attr "type" "other") 13442 (set_attr "length" "16")]) 13443