1;; Machine description of the Renesas M32R cpu for GNU C compiler 2;; Copyright (C) 1996, 1997, 1998, 1999, 2001, 2003, 2004, 2005, 3; 2007, 2008, 2009 Free Software Foundation, Inc. 4 5;; This file is part of GCC. 6 7;; GCC is free software; you can redistribute it and/or modify it 8;; under the terms of the GNU General Public License as published 9;; by the Free Software Foundation; either version 3, or (at your 10;; option) any later version. 11 12;; GCC is distributed in the hope that it will be useful, but WITHOUT 13;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 15;; License for more details. 16 17;; You should have received a copy of the GNU General Public License 18;; along with GCC; see the file COPYING3. If not see 19;; <http://www.gnu.org/licenses/>. 20 21;; See file "rtl.def" for documentation on define_insn, match_*, et. al. 22 23;; UNSPEC_VOLATILE usage 24(define_constants 25 [(UNSPECV_BLOCKAGE 0) 26 (UNSPECV_FLUSH_ICACHE 1)]) 27 28;; UNSPEC usage 29(define_constants 30 [(UNSPEC_LOAD_SDA_BASE 2) 31 (UNSPEC_SET_CBIT 3) 32 (UNSPEC_PIC_LOAD_ADDR 4) 33 (UNSPEC_GET_PC 5) 34 (UNSPEC_GOTOFF 6) 35 ]) 36 37;; Insn type. Used to default other attribute values. 38(define_attr "type" 39 "int2,int4,load2,load4,load8,store2,store4,store8,shift2,shift4,mul2,div4,uncond_branch,branch,call,multi,misc" 40 (const_string "misc")) 41 42;; Length in bytes. 43(define_attr "length" "" 44 (cond [(eq_attr "type" "int2,load2,store2,shift2,mul2") 45 (const_int 2) 46 47 (eq_attr "type" "int4,load4,store4,shift4,div4") 48 (const_int 4) 49 50 (eq_attr "type" "multi") 51 (const_int 8) 52 53 (eq_attr "type" "uncond_branch,branch,call") 54 (const_int 4)] 55 56 (const_int 4))) 57 58;; The length here is the length of a single asm. Unfortunately it might be 59;; 2 or 4 so we must allow for 4. That's ok though. 60(define_asm_attributes 61 [(set_attr "length" "4") 62 (set_attr "type" "multi")]) 63 64;; Whether an instruction is short (16-bit) or long (32-bit). 65(define_attr "insn_size" "short,long" 66 (if_then_else (eq_attr "type" "int2,load2,store2,shift2,mul2") 67 (const_string "short") 68 (const_string "long"))) 69 70;; The target CPU we're compiling for. 71(define_attr "cpu" "m32r,m32r2,m32rx" 72 (cond [(ne (symbol_ref "TARGET_M32RX") (const_int 0)) 73 (const_string "m32rx") 74 (ne (symbol_ref "TARGET_M32R2") (const_int 0)) 75 (const_string "m32r2")] 76 (const_string "m32r"))) 77 78;; Defines the pipeline where an instruction can be executed on. 79;; For the M32R, a short instruction can execute one of the two pipes. 80;; For the M32Rx, the restrictions are modelled in the second 81;; condition of this attribute definition. 82(define_attr "m32r_pipeline" "either,s,o,long" 83 (cond [(and (eq_attr "cpu" "m32r") 84 (eq_attr "insn_size" "short")) 85 (const_string "either") 86 (eq_attr "insn_size" "!short") 87 (const_string "long")] 88 (cond [(eq_attr "type" "int2") 89 (const_string "either") 90 (eq_attr "type" "load2,store2,shift2,uncond_branch,branch,call") 91 (const_string "o") 92 (eq_attr "type" "mul2") 93 (const_string "s")] 94 (const_string "long")))) 95 96;; :::::::::::::::::::: 97;; :: 98;; :: Pipeline description 99;; :: 100;; :::::::::::::::::::: 101 102;; This model is based on Chapter 2, Appendix 3 and Appendix 4 of the 103;; "M32R-FPU Software Manual", Revision 1.01, plus additional information 104;; obtained by our best friend and mine, Google. 105;; 106;; The pipeline is modelled as a fetch unit, and a core with a memory unit, 107;; two execution units, where "fetch" models IF and D, "memory" for MEM1 108;; and MEM2, and "EXEC" for E, E1, E2, EM, and EA. Writeback and 109;; bypasses are not modelled. 110(define_automaton "m32r") 111 112;; We pretend there are two short (16 bits) instruction fetchers. The 113;; "s" short fetcher cannot be reserved until the "o" short fetcher is 114;; reserved. Some instructions reserve both the left and right fetchers. 115;; These fetch units are a hack to get GCC to better pack the instructions 116;; for the M32Rx processor, which has two execution pipes. 117;; 118;; In reality there is only one decoder, which can decode either two 16-bit 119;; instructions, or a single 32-bit instruction. 120;; 121;; Note, "fetch" models both the IF and the D pipeline stages. 122;; 123;; The m32rx core has two execution pipes. We name them o_E and s_E. 124;; In addition, there's a memory unit. 125 126(define_cpu_unit "o_IF,s_IF,o_E,s_E,memory" "m32r") 127 128;; Prevent the s pipe from being reserved before the o pipe. 129(absence_set "s_IF" "o_IF") 130(absence_set "s_E" "o_E") 131 132;; On the M32Rx, long instructions execute on both pipes, so reserve 133;; both fetch slots and both pipes. 134(define_reservation "long_IF" "o_IF+s_IF") 135(define_reservation "long_E" "o_E+s_E") 136 137;; :::::::::::::::::::: 138 139;; Simple instructions do 4 stages: IF D E WB. WB is not modelled. 140;; Hence, ready latency is 1. 141(define_insn_reservation "short_left" 1 142 (and (eq_attr "m32r_pipeline" "o") 143 (and (eq_attr "insn_size" "short") 144 (eq_attr "type" "!load2"))) 145 "o_IF,o_E") 146 147(define_insn_reservation "short_right" 1 148 (and (eq_attr "m32r_pipeline" "s") 149 (and (eq_attr "insn_size" "short") 150 (eq_attr "type" "!load2"))) 151 "s_IF,s_E") 152 153(define_insn_reservation "short_either" 1 154 (and (eq_attr "m32r_pipeline" "either") 155 (and (eq_attr "insn_size" "short") 156 (eq_attr "type" "!load2"))) 157 "o_IF|s_IF,o_E|s_E") 158 159(define_insn_reservation "long_m32r" 1 160 (and (eq_attr "cpu" "m32r") 161 (and (eq_attr "insn_size" "long") 162 (eq_attr "type" "!load4,load8"))) 163 "long_IF,long_E") 164 165(define_insn_reservation "long_m32rx" 2 166 (and (eq_attr "m32r_pipeline" "long") 167 (and (eq_attr "insn_size" "long") 168 (eq_attr "type" "!load4,load8"))) 169 "long_IF,long_E") 170 171;; Load/store instructions do 6 stages: IF D E MEM1 MEM2 WB. 172;; MEM1 may require more than one cycle depending on locality. We 173;; optimistically assume all memory is nearby, i.e. MEM1 takes only 174;; one cycle. Hence, ready latency is 3. 175 176;; The M32Rx can do short load/store only on the left pipe. 177(define_insn_reservation "short_load_left" 3 178 (and (eq_attr "m32r_pipeline" "o") 179 (and (eq_attr "insn_size" "short") 180 (eq_attr "type" "load2"))) 181 "o_IF,o_E,memory*2") 182 183(define_insn_reservation "short_load" 3 184 (and (eq_attr "m32r_pipeline" "either") 185 (and (eq_attr "insn_size" "short") 186 (eq_attr "type" "load2"))) 187 "s_IF|o_IF,s_E|o_E,memory*2") 188 189(define_insn_reservation "long_load" 3 190 (and (eq_attr "cpu" "m32r") 191 (and (eq_attr "insn_size" "long") 192 (eq_attr "type" "load4,load8"))) 193 "long_IF,long_E,memory*2") 194 195(define_insn_reservation "long_load_m32rx" 3 196 (and (eq_attr "m32r_pipeline" "long") 197 (eq_attr "type" "load4,load8")) 198 "long_IF,long_E,memory*2") 199 200 201(include "predicates.md") 202(include "constraints.md") 203 204;; Expand prologue as RTL 205(define_expand "prologue" 206 [(const_int 1)] 207 "" 208 " 209{ 210 m32r_expand_prologue (); 211 DONE; 212}") 213 214;; Expand epilogue as RTL 215(define_expand "epilogue" 216 [(return)] 217 "" 218 " 219{ 220 m32r_expand_epilogue (); 221 emit_jump_insn (gen_return_normal ()); 222 DONE; 223}") 224 225;; Move instructions. 226;; 227;; For QI and HI moves, the register must contain the full properly 228;; sign-extended value. nonzero_bits assumes this [otherwise 229;; SHORT_IMMEDIATES_SIGN_EXTEND must be used, but the comment for it 230;; says it's a kludge and the .md files should be fixed instead]. 231 232(define_expand "movqi" 233 [(set (match_operand:QI 0 "general_operand" "") 234 (match_operand:QI 1 "general_operand" ""))] 235 "" 236 " 237{ 238 /* Fixup PIC cases. */ 239 if (flag_pic) 240 { 241 if (symbolic_operand (operands[1], QImode)) 242 { 243 if (reload_in_progress || reload_completed) 244 operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]); 245 else 246 operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX); 247 } 248 } 249 250 /* Everything except mem = const or mem = mem can be done easily. 251 Objects in the small data area are handled too. */ 252 253 if (MEM_P (operands[0])) 254 operands[1] = force_reg (QImode, operands[1]); 255}") 256 257(define_insn "*movqi_insn" 258 [(set (match_operand:QI 0 "move_dest_operand" "=r,r,r,r,r,T,m") 259 (match_operand:QI 1 "move_src_operand" "r,I,JQR,T,m,r,r"))] 260 "register_operand (operands[0], QImode) || register_operand (operands[1], QImode)" 261 "@ 262 mv %0,%1 263 ldi %0,%#%1 264 ldi %0,%#%1 265 ldub %0,%1 266 ldub %0,%1 267 stb %1,%0 268 stb %1,%0" 269 [(set_attr "type" "int2,int2,int4,load2,load4,store2,store4") 270 (set_attr "length" "2,2,4,2,4,2,4")]) 271 272(define_expand "movhi" 273 [(set (match_operand:HI 0 "general_operand" "") 274 (match_operand:HI 1 "general_operand" ""))] 275 "" 276 " 277{ 278 /* Fixup PIC cases. */ 279 if (flag_pic) 280 { 281 if (symbolic_operand (operands[1], HImode)) 282 { 283 if (reload_in_progress || reload_completed) 284 operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]); 285 else 286 operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX); 287 } 288 } 289 290 /* Everything except mem = const or mem = mem can be done easily. */ 291 292 if (MEM_P (operands[0])) 293 operands[1] = force_reg (HImode, operands[1]); 294}") 295 296(define_insn "*movhi_insn" 297 [(set (match_operand:HI 0 "move_dest_operand" "=r,r,r,r,r,r,T,m") 298 (match_operand:HI 1 "move_src_operand" "r,I,JQR,K,T,m,r,r"))] 299 "register_operand (operands[0], HImode) || register_operand (operands[1], HImode)" 300 "@ 301 mv %0,%1 302 ldi %0,%#%1 303 ldi %0,%#%1 304 ld24 %0,%#%1 305 lduh %0,%1 306 lduh %0,%1 307 sth %1,%0 308 sth %1,%0" 309 [(set_attr "type" "int2,int2,int4,int4,load2,load4,store2,store4") 310 (set_attr "length" "2,2,4,4,2,4,2,4")]) 311 312(define_expand "movsi_push" 313 [(set (mem:SI (pre_dec:SI (match_operand:SI 0 "register_operand" ""))) 314 (match_operand:SI 1 "register_operand" ""))] 315 "" 316 "") 317 318(define_expand "movsi_pop" 319 [(set (match_operand:SI 0 "register_operand" "") 320 (mem:SI (post_inc:SI (match_operand:SI 1 "register_operand" ""))))] 321 "" 322 "") 323 324(define_expand "movsi" 325 [(set (match_operand:SI 0 "general_operand" "") 326 (match_operand:SI 1 "general_operand" ""))] 327 "" 328 " 329{ 330 /* Fixup PIC cases. */ 331 if (flag_pic) 332 { 333 if (symbolic_operand (operands[1], SImode)) 334 { 335 if (reload_in_progress || reload_completed) 336 operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]); 337 else 338 operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX); 339 } 340 } 341 342 /* Everything except mem = const or mem = mem can be done easily. */ 343 344 if (MEM_P (operands[0])) 345 operands[1] = force_reg (SImode, operands[1]); 346 347 /* Small Data Area reference? */ 348 if (small_data_operand (operands[1], SImode)) 349 { 350 emit_insn (gen_movsi_sda (operands[0], operands[1])); 351 DONE; 352 } 353 354 /* If medium or large code model, symbols have to be loaded with 355 seth/add3. */ 356 if (addr32_operand (operands[1], SImode)) 357 { 358 emit_insn (gen_movsi_addr32 (operands[0], operands[1])); 359 DONE; 360 } 361}") 362 363;; ??? Do we need a const_double constraint here for large unsigned values? 364(define_insn "*movsi_insn" 365 [(set (match_operand:SI 0 "move_dest_operand" "=r,r,r,r,r,r,r,r,r,T,S,m") 366 (match_operand:SI 1 "move_src_operand" "r,I,J,MQ,L,n,T,U,m,r,r,r"))] 367 "register_operand (operands[0], SImode) || register_operand (operands[1], SImode)" 368 "* 369{ 370 if (REG_P (operands[0]) || GET_CODE (operands[1]) == SUBREG) 371 { 372 switch (GET_CODE (operands[1])) 373 { 374 default: 375 break; 376 377 case REG: 378 case SUBREG: 379 return \"mv %0,%1\"; 380 381 case MEM: 382 if (GET_CODE (XEXP (operands[1], 0)) == POST_INC 383 && XEXP (XEXP (operands[1], 0), 0) == stack_pointer_rtx) 384 return \"pop %0\"; 385 386 return \"ld %0,%1\"; 387 388 case CONST_INT: 389 if (satisfies_constraint_J (operands[1])) 390 return \"ldi %0,%#%1\\t; %X1\"; 391 392 if (satisfies_constraint_M (operands[1])) 393 return \"ld24 %0,%#%1\\t; %X1\"; 394 395 if (satisfies_constraint_L (operands[1])) 396 return \"seth %0,%#%T1\\t; %X1\"; 397 398 return \"#\"; 399 400 case CONST: 401 case SYMBOL_REF: 402 case LABEL_REF: 403 if (TARGET_ADDR24) 404 return \"ld24 %0,%#%1\"; 405 406 return \"#\"; 407 } 408 } 409 410 else if (MEM_P (operands[0]) 411 && (REG_P (operands[1]) || GET_CODE (operands[1]) == SUBREG)) 412 { 413 if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC 414 && XEXP (XEXP (operands[0], 0), 0) == stack_pointer_rtx) 415 return \"push %1\"; 416 417 return \"st %1,%0\"; 418 } 419 420 gcc_unreachable (); 421}" 422 [(set_attr "type" "int2,int2,int4,int4,int4,multi,load2,load2,load4,store2,store2,store4") 423 (set_attr "length" "2,2,4,4,4,8,2,2,4,2,2,4")]) 424 425; Try to use a four byte / two byte pair for constants not loadable with 426; ldi, ld24, seth. 427 428(define_split 429 [(set (match_operand:SI 0 "register_operand" "") 430 (match_operand:SI 1 "two_insn_const_operand" ""))] 431 "" 432 [(set (match_dup 0) (match_dup 2)) 433 (set (match_dup 0) (ior:SI (match_dup 0) (match_dup 3)))] 434 " 435{ 436 unsigned HOST_WIDE_INT val = INTVAL (operands[1]); 437 unsigned HOST_WIDE_INT tmp; 438 int shift; 439 440 /* In all cases we will emit two instructions. However we try to 441 use 2 byte instructions wherever possible. We can assume the 442 constant isn't loadable with any of ldi, ld24, or seth. */ 443 444 /* See if we can load a 24-bit unsigned value and invert it. */ 445 if (UINT24_P (~ val)) 446 { 447 emit_insn (gen_movsi (operands[0], GEN_INT (~ val))); 448 emit_insn (gen_one_cmplsi2 (operands[0], operands[0])); 449 DONE; 450 } 451 452 /* See if we can load a 24-bit unsigned value and shift it into place. 453 0x01fffffe is just beyond ld24's range. */ 454 for (shift = 1, tmp = 0x01fffffe; 455 shift < 8; 456 ++shift, tmp <<= 1) 457 { 458 if ((val & ~tmp) == 0) 459 { 460 emit_insn (gen_movsi (operands[0], GEN_INT (val >> shift))); 461 emit_insn (gen_ashlsi3 (operands[0], operands[0], GEN_INT (shift))); 462 DONE; 463 } 464 } 465 466 /* Can't use any two byte insn, fall back to seth/or3. Use ~0xffff instead 467 of 0xffff0000, since the later fails on a 64-bit host. */ 468 operands[2] = GEN_INT ((val) & ~0xffff); 469 operands[3] = GEN_INT ((val) & 0xffff); 470}") 471 472(define_split 473 [(set (match_operand:SI 0 "register_operand" "") 474 (match_operand:SI 1 "seth_add3_operand" ""))] 475 "TARGET_ADDR32" 476 [(set (match_dup 0) 477 (high:SI (match_dup 1))) 478 (set (match_dup 0) 479 (lo_sum:SI (match_dup 0) 480 (match_dup 1)))] 481 "") 482 483;; Small data area support. 484;; The address of _SDA_BASE_ is loaded into a register and all objects in 485;; the small data area are indexed off that. This is done for each reference 486;; but cse will clean things up for us. We let the compiler choose the 487;; register to use so we needn't allocate (and maybe even fix) a special 488;; register to use. Since the load and store insns have a 16-bit offset the 489;; total size of the data area can be 64K. However, if the data area lives 490;; above 16M (24 bits), _SDA_BASE_ will have to be loaded with seth/add3 which 491;; would then yield 3 instructions to reference an object [though there would 492;; be no net loss if two or more objects were referenced]. The 3 insns can be 493;; reduced back to 2 if the size of the small data area were reduced to 32K 494;; [then seth + ld/st would work for any object in the area]. Doing this 495;; would require special handling of _SDA_BASE_ (its value would be 496;; (.sdata + 32K) & 0xffff0000) and reloc computations would be different 497;; [I think]. What to do about this is deferred until later and for now we 498;; require .sdata to be in the first 16M. 499 500(define_expand "movsi_sda" 501 [(set (match_dup 2) 502 (unspec:SI [(const_int 0)] UNSPEC_LOAD_SDA_BASE)) 503 (set (match_operand:SI 0 "register_operand" "") 504 (lo_sum:SI (match_dup 2) 505 (match_operand:SI 1 "small_data_operand" "")))] 506 "" 507 " 508{ 509 if (reload_in_progress || reload_completed) 510 operands[2] = operands[0]; 511 else 512 operands[2] = gen_reg_rtx (SImode); 513}") 514 515(define_insn "*load_sda_base_32" 516 [(set (match_operand:SI 0 "register_operand" "=r") 517 (unspec:SI [(const_int 0)] UNSPEC_LOAD_SDA_BASE))] 518 "TARGET_ADDR32" 519 "seth %0,%#shigh(_SDA_BASE_)\;add3 %0,%0,%#low(_SDA_BASE_)" 520 [(set_attr "type" "multi") 521 (set_attr "length" "8")]) 522 523(define_insn "*load_sda_base" 524 [(set (match_operand:SI 0 "register_operand" "=r") 525 (unspec:SI [(const_int 0)] UNSPEC_LOAD_SDA_BASE))] 526 "" 527 "ld24 %0,#_SDA_BASE_" 528 [(set_attr "type" "int4") 529 (set_attr "length" "4")]) 530 531;; 32-bit address support. 532 533(define_expand "movsi_addr32" 534 [(set (match_dup 2) 535 ; addr32_operand isn't used because it's too restrictive, 536 ; seth_add3_operand is more general and thus safer. 537 (high:SI (match_operand:SI 1 "seth_add3_operand" ""))) 538 (set (match_operand:SI 0 "register_operand" "") 539 (lo_sum:SI (match_dup 2) (match_dup 1)))] 540 "" 541 " 542{ 543 if (reload_in_progress || reload_completed) 544 operands[2] = operands[0]; 545 else 546 operands[2] = gen_reg_rtx (SImode); 547}") 548 549(define_insn "set_hi_si" 550 [(set (match_operand:SI 0 "register_operand" "=r") 551 (high:SI (match_operand 1 "symbolic_operand" "")))] 552 "" 553 "seth %0,%#shigh(%1)" 554 [(set_attr "type" "int4") 555 (set_attr "length" "4")]) 556 557(define_insn "lo_sum_si" 558 [(set (match_operand:SI 0 "register_operand" "=r") 559 (lo_sum:SI (match_operand:SI 1 "register_operand" "r") 560 (match_operand:SI 2 "immediate_operand" "in")))] 561 "" 562 "add3 %0,%1,%#%B2" 563 [(set_attr "type" "int4") 564 (set_attr "length" "4")]) 565 566(define_expand "movdi" 567 [(set (match_operand:DI 0 "general_operand" "") 568 (match_operand:DI 1 "general_operand" ""))] 569 "" 570 " 571{ 572 /* Fixup PIC cases. */ 573 if (flag_pic) 574 { 575 if (symbolic_operand (operands[1], DImode)) 576 { 577 if (reload_in_progress || reload_completed) 578 operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]); 579 else 580 operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX); 581 } 582 } 583 584 /* Everything except mem = const or mem = mem can be done easily. */ 585 586 if (MEM_P (operands[0])) 587 operands[1] = force_reg (DImode, operands[1]); 588}") 589 590(define_insn "*movdi_insn" 591 [(set (match_operand:DI 0 "move_dest_operand" "=r,r,r,r,m") 592 (match_operand:DI 1 "move_double_src_operand" "r,nG,F,m,r"))] 593 "register_operand (operands[0], DImode) || register_operand (operands[1], DImode)" 594 "#" 595 [(set_attr "type" "multi,multi,multi,load8,store8") 596 (set_attr "length" "4,4,16,6,6")]) 597 598(define_split 599 [(set (match_operand:DI 0 "move_dest_operand" "") 600 (match_operand:DI 1 "move_double_src_operand" ""))] 601 "reload_completed" 602 [(match_dup 2)] 603 "operands[2] = gen_split_move_double (operands);") 604 605;; Floating point move insns. 606 607(define_expand "movsf" 608 [(set (match_operand:SF 0 "general_operand" "") 609 (match_operand:SF 1 "general_operand" ""))] 610 "" 611 " 612{ 613 /* Fixup PIC cases. */ 614 if (flag_pic) 615 { 616 if (symbolic_operand (operands[1], SFmode)) 617 { 618 if (reload_in_progress || reload_completed) 619 operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]); 620 else 621 operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX); 622 } 623 } 624 625 /* Everything except mem = const or mem = mem can be done easily. */ 626 627 if (MEM_P (operands[0])) 628 operands[1] = force_reg (SFmode, operands[1]); 629}") 630 631(define_insn "*movsf_insn" 632 [(set (match_operand:SF 0 "move_dest_operand" "=r,r,r,r,r,T,S,m") 633 (match_operand:SF 1 "move_src_operand" "r,F,U,S,m,r,r,r"))] 634 "register_operand (operands[0], SFmode) || register_operand (operands[1], SFmode)" 635 "@ 636 mv %0,%1 637 # 638 ld %0,%1 639 ld %0,%1 640 ld %0,%1 641 st %1,%0 642 st %1,%0 643 st %1,%0" 644 ;; ??? Length of alternative 1 is either 2, 4 or 8. 645 [(set_attr "type" "int2,multi,load2,load2,load4,store2,store2,store4") 646 (set_attr "length" "2,8,2,2,4,2,2,4")]) 647 648(define_split 649 [(set (match_operand:SF 0 "register_operand" "") 650 (match_operand:SF 1 "const_double_operand" ""))] 651 "reload_completed" 652 [(set (match_dup 2) (match_dup 3))] 653 " 654{ 655 operands[2] = operand_subword (operands[0], 0, 0, SFmode); 656 operands[3] = operand_subword (operands[1], 0, 0, SFmode); 657}") 658 659(define_expand "movdf" 660 [(set (match_operand:DF 0 "general_operand" "") 661 (match_operand:DF 1 "general_operand" ""))] 662 "" 663 " 664{ 665 /* Fixup PIC cases. */ 666 if (flag_pic) 667 { 668 if (symbolic_operand (operands[1], DFmode)) 669 { 670 if (reload_in_progress || reload_completed) 671 operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]); 672 else 673 operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX); 674 } 675 } 676 677 /* Everything except mem = const or mem = mem can be done easily. */ 678 679 if (MEM_P (operands[0])) 680 operands[1] = force_reg (DFmode, operands[1]); 681}") 682 683(define_insn "*movdf_insn" 684 [(set (match_operand:DF 0 "move_dest_operand" "=r,r,r,m") 685 (match_operand:DF 1 "move_double_src_operand" "r,F,m,r"))] 686 "register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode)" 687 "#" 688 [(set_attr "type" "multi,multi,load8,store8") 689 (set_attr "length" "4,16,6,6")]) 690 691(define_split 692 [(set (match_operand:DF 0 "move_dest_operand" "") 693 (match_operand:DF 1 "move_double_src_operand" ""))] 694 "reload_completed" 695 [(match_dup 2)] 696 "operands[2] = gen_split_move_double (operands);") 697 698;; Zero extension instructions. 699 700(define_insn "zero_extendqihi2" 701 [(set (match_operand:HI 0 "register_operand" "=r,r,r") 702 (zero_extend:HI (match_operand:QI 1 "extend_operand" "r,T,m")))] 703 "" 704 "@ 705 and3 %0,%1,%#255 706 ldub %0,%1 707 ldub %0,%1" 708 [(set_attr "type" "int4,load2,load4") 709 (set_attr "length" "4,2,4")]) 710 711(define_insn "zero_extendqisi2" 712 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 713 (zero_extend:SI (match_operand:QI 1 "extend_operand" "r,T,m")))] 714 "" 715 "@ 716 and3 %0,%1,%#255 717 ldub %0,%1 718 ldub %0,%1" 719 [(set_attr "type" "int4,load2,load4") 720 (set_attr "length" "4,2,4")]) 721 722(define_insn "zero_extendhisi2" 723 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 724 (zero_extend:SI (match_operand:HI 1 "extend_operand" "r,T,m")))] 725 "" 726 "@ 727 and3 %0,%1,%#65535 728 lduh %0,%1 729 lduh %0,%1" 730 [(set_attr "type" "int4,load2,load4") 731 (set_attr "length" "4,2,4")]) 732 733;; Signed conversions from a smaller integer to a larger integer 734(define_insn "extendqihi2" 735 [(set (match_operand:HI 0 "register_operand" "=r,r,r") 736 (sign_extend:HI (match_operand:QI 1 "extend_operand" "0,T,m")))] 737 "" 738 "@ 739 # 740 ldb %0,%1 741 ldb %0,%1" 742 [(set_attr "type" "multi,load2,load4") 743 (set_attr "length" "2,2,4")]) 744 745(define_split 746 [(set (match_operand:HI 0 "register_operand" "") 747 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))] 748 "reload_completed" 749 [(match_dup 2) 750 (match_dup 3)] 751 " 752{ 753 rtx op0 = gen_lowpart (SImode, operands[0]); 754 rtx shift = GEN_INT (24); 755 756 operands[2] = gen_ashlsi3 (op0, op0, shift); 757 operands[3] = gen_ashrsi3 (op0, op0, shift); 758}") 759 760(define_insn "extendqisi2" 761 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 762 (sign_extend:SI (match_operand:QI 1 "extend_operand" "0,T,m")))] 763 "" 764 "@ 765 # 766 ldb %0,%1 767 ldb %0,%1" 768 [(set_attr "type" "multi,load2,load4") 769 (set_attr "length" "4,2,4")]) 770 771(define_split 772 [(set (match_operand:SI 0 "register_operand" "") 773 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))] 774 "reload_completed" 775 [(match_dup 2) 776 (match_dup 3)] 777 " 778{ 779 rtx shift = GEN_INT (24); 780 781 operands[2] = gen_ashlsi3 (operands[0], operands[0], shift); 782 operands[3] = gen_ashrsi3 (operands[0], operands[0], shift); 783}") 784 785(define_insn "extendhisi2" 786 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 787 (sign_extend:SI (match_operand:HI 1 "extend_operand" "0,T,m")))] 788 "" 789 "@ 790 # 791 ldh %0,%1 792 ldh %0,%1" 793 [(set_attr "type" "multi,load2,load4") 794 (set_attr "length" "4,2,4")]) 795 796(define_split 797 [(set (match_operand:SI 0 "register_operand" "") 798 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))] 799 "reload_completed" 800 [(match_dup 2) 801 (match_dup 3)] 802 " 803{ 804 rtx shift = GEN_INT (16); 805 806 operands[2] = gen_ashlsi3 (operands[0], operands[0], shift); 807 operands[3] = gen_ashrsi3 (operands[0], operands[0], shift); 808}") 809 810;; Arithmetic instructions. 811 812; ??? Adding an alternative to split add3 of small constants into two 813; insns yields better instruction packing but slower code. Adds of small 814; values is done a lot. 815 816(define_insn "addsi3" 817 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 818 (plus:SI (match_operand:SI 1 "register_operand" "%0,0,r") 819 (match_operand:SI 2 "nonmemory_operand" "r,I,J")))] 820 "" 821 "@ 822 add %0,%2 823 addi %0,%#%2 824 add3 %0,%1,%#%2" 825 [(set_attr "type" "int2,int2,int4") 826 (set_attr "length" "2,2,4")]) 827 828;(define_split 829; [(set (match_operand:SI 0 "register_operand" "") 830; (plus:SI (match_operand:SI 1 "register_operand" "") 831; (match_operand:SI 2 "int8_operand" "")))] 832; "reload_completed 833; && REGNO (operands[0]) != REGNO (operands[1]) 834; && satisfies_constraint_I (operands[2]) 835; && INTVAL (operands[2]) != 0" 836; [(set (match_dup 0) (match_dup 1)) 837; (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))] 838; "") 839 840(define_insn "adddi3" 841 [(set (match_operand:DI 0 "register_operand" "=r") 842 (plus:DI (match_operand:DI 1 "register_operand" "%0") 843 (match_operand:DI 2 "register_operand" "r"))) 844 (clobber (reg:CC 17))] 845 "" 846 "#" 847 [(set_attr "type" "multi") 848 (set_attr "length" "6")]) 849 850;; ??? The cmp clears the condition bit. Can we speed up somehow? 851(define_split 852 [(set (match_operand:DI 0 "register_operand" "") 853 (plus:DI (match_operand:DI 1 "register_operand" "") 854 (match_operand:DI 2 "register_operand" ""))) 855 (clobber (reg:CC 17))] 856 "reload_completed" 857 [(parallel [(set (reg:CC 17) 858 (const_int 0)) 859 (use (match_dup 4))]) 860 (parallel [(set (match_dup 4) 861 (plus:SI (match_dup 4) 862 (plus:SI (match_dup 5) 863 (ne:SI (reg:CC 17) (const_int 0))))) 864 (set (reg:CC 17) 865 (unspec:CC [(const_int 0)] UNSPEC_SET_CBIT))]) 866 (parallel [(set (match_dup 6) 867 (plus:SI (match_dup 6) 868 (plus:SI (match_dup 7) 869 (ne:SI (reg:CC 17) (const_int 0))))) 870 (set (reg:CC 17) 871 (unspec:CC [(const_int 0)] UNSPEC_SET_CBIT))])] 872 " 873{ 874 operands[4] = operand_subword (operands[0], (WORDS_BIG_ENDIAN != 0), 0, DImode); 875 operands[5] = operand_subword (operands[2], (WORDS_BIG_ENDIAN != 0), 0, DImode); 876 operands[6] = operand_subword (operands[0], (WORDS_BIG_ENDIAN == 0), 0, DImode); 877 operands[7] = operand_subword (operands[2], (WORDS_BIG_ENDIAN == 0), 0, DImode); 878}") 879 880(define_insn "*clear_c" 881 [(set (reg:CC 17) 882 (const_int 0)) 883 (use (match_operand:SI 0 "register_operand" "r"))] 884 "" 885 "cmp %0,%0" 886 [(set_attr "type" "int2") 887 (set_attr "length" "2")]) 888 889(define_insn "*add_carry" 890 [(set (match_operand:SI 0 "register_operand" "=r") 891 (plus:SI (match_operand:SI 1 "register_operand" "%0") 892 (plus:SI (match_operand:SI 2 "register_operand" "r") 893 (ne:SI (reg:CC 17) (const_int 0))))) 894 (set (reg:CC 17) 895 (unspec:CC [(const_int 0)] UNSPEC_SET_CBIT))] 896 "" 897 "addx %0,%2" 898 [(set_attr "type" "int2") 899 (set_attr "length" "2")]) 900 901(define_insn "subsi3" 902 [(set (match_operand:SI 0 "register_operand" "=r") 903 (minus:SI (match_operand:SI 1 "register_operand" "0") 904 (match_operand:SI 2 "register_operand" "r")))] 905 "" 906 "sub %0,%2" 907 [(set_attr "type" "int2") 908 (set_attr "length" "2")]) 909 910(define_insn "subdi3" 911 [(set (match_operand:DI 0 "register_operand" "=r") 912 (minus:DI (match_operand:DI 1 "register_operand" "0") 913 (match_operand:DI 2 "register_operand" "r"))) 914 (clobber (reg:CC 17))] 915 "" 916 "#" 917 [(set_attr "type" "multi") 918 (set_attr "length" "6")]) 919 920;; ??? The cmp clears the condition bit. Can we speed up somehow? 921(define_split 922 [(set (match_operand:DI 0 "register_operand" "") 923 (minus:DI (match_operand:DI 1 "register_operand" "") 924 (match_operand:DI 2 "register_operand" ""))) 925 (clobber (reg:CC 17))] 926 "reload_completed" 927 [(parallel [(set (reg:CC 17) 928 (const_int 0)) 929 (use (match_dup 4))]) 930 (parallel [(set (match_dup 4) 931 (minus:SI (match_dup 4) 932 (minus:SI (match_dup 5) 933 (ne:SI (reg:CC 17) (const_int 0))))) 934 (set (reg:CC 17) 935 (unspec:CC [(const_int 0)] UNSPEC_SET_CBIT))]) 936 (parallel [(set (match_dup 6) 937 (minus:SI (match_dup 6) 938 (minus:SI (match_dup 7) 939 (ne:SI (reg:CC 17) (const_int 0))))) 940 (set (reg:CC 17) 941 (unspec:CC [(const_int 0)] UNSPEC_SET_CBIT))])] 942 " 943{ 944 operands[4] = operand_subword (operands[0], (WORDS_BIG_ENDIAN != 0), 0, DImode); 945 operands[5] = operand_subword (operands[2], (WORDS_BIG_ENDIAN != 0), 0, DImode); 946 operands[6] = operand_subword (operands[0], (WORDS_BIG_ENDIAN == 0), 0, DImode); 947 operands[7] = operand_subword (operands[2], (WORDS_BIG_ENDIAN == 0), 0, DImode); 948}") 949 950(define_insn "*sub_carry" 951 [(set (match_operand:SI 0 "register_operand" "=r") 952 (minus:SI (match_operand:SI 1 "register_operand" "%0") 953 (minus:SI (match_operand:SI 2 "register_operand" "r") 954 (ne:SI (reg:CC 17) (const_int 0))))) 955 (set (reg:CC 17) 956 (unspec:CC [(const_int 0)] UNSPEC_SET_CBIT))] 957 "" 958 "subx %0,%2" 959 [(set_attr "type" "int2") 960 (set_attr "length" "2")]) 961 962; Multiply/Divide instructions. 963 964(define_insn "mulhisi3" 965 [(set (match_operand:SI 0 "register_operand" "=r") 966 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "r")) 967 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))] 968 "" 969 "mullo %1,%2\;mvfacmi %0" 970 [(set_attr "type" "multi") 971 (set_attr "length" "4")]) 972 973(define_insn "mulsi3" 974 [(set (match_operand:SI 0 "register_operand" "=r") 975 (mult:SI (match_operand:SI 1 "register_operand" "%0") 976 (match_operand:SI 2 "register_operand" "r")))] 977 "" 978 "mul %0,%2" 979 [(set_attr "type" "mul2") 980 (set_attr "length" "2")]) 981 982(define_insn "divsi3" 983 [(set (match_operand:SI 0 "register_operand" "=r") 984 (div:SI (match_operand:SI 1 "register_operand" "0") 985 (match_operand:SI 2 "register_operand" "r")))] 986 "" 987 "div %0,%2" 988 [(set_attr "type" "div4") 989 (set_attr "length" "4")]) 990 991(define_insn "udivsi3" 992 [(set (match_operand:SI 0 "register_operand" "=r") 993 (udiv:SI (match_operand:SI 1 "register_operand" "0") 994 (match_operand:SI 2 "register_operand" "r")))] 995 "" 996 "divu %0,%2" 997 [(set_attr "type" "div4") 998 (set_attr "length" "4")]) 999 1000(define_insn "modsi3" 1001 [(set (match_operand:SI 0 "register_operand" "=r") 1002 (mod:SI (match_operand:SI 1 "register_operand" "0") 1003 (match_operand:SI 2 "register_operand" "r")))] 1004 "" 1005 "rem %0,%2" 1006 [(set_attr "type" "div4") 1007 (set_attr "length" "4")]) 1008 1009(define_insn "umodsi3" 1010 [(set (match_operand:SI 0 "register_operand" "=r") 1011 (umod:SI (match_operand:SI 1 "register_operand" "0") 1012 (match_operand:SI 2 "register_operand" "r")))] 1013 "" 1014 "remu %0,%2" 1015 [(set_attr "type" "div4") 1016 (set_attr "length" "4")]) 1017 1018;; Boolean instructions. 1019;; 1020;; We don't define the DImode versions as expand_binop does a good enough job. 1021;; And if it doesn't it should be fixed. 1022 1023(define_insn "andsi3" 1024 [(set (match_operand:SI 0 "register_operand" "=r,r") 1025 (and:SI (match_operand:SI 1 "register_operand" "%0,r") 1026 (match_operand:SI 2 "reg_or_uint16_operand" "r,K")))] 1027 "" 1028 "* 1029{ 1030 /* If we are worried about space, see if we can break this up into two 1031 short instructions, which might eliminate a NOP being inserted. */ 1032 if (optimize_size 1033 && m32r_not_same_reg (operands[0], operands[1]) 1034 && satisfies_constraint_I (operands[2])) 1035 return \"#\"; 1036 1037 else if (CONST_INT_P (operands[2])) 1038 return \"and3 %0,%1,%#%X2\"; 1039 1040 return \"and %0,%2\"; 1041}" 1042 [(set_attr "type" "int2,int4") 1043 (set_attr "length" "2,4")]) 1044 1045(define_split 1046 [(set (match_operand:SI 0 "register_operand" "") 1047 (and:SI (match_operand:SI 1 "register_operand" "") 1048 (match_operand:SI 2 "int8_operand" "")))] 1049 "optimize_size && m32r_not_same_reg (operands[0], operands[1])" 1050 [(set (match_dup 0) (match_dup 2)) 1051 (set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))] 1052 "") 1053 1054(define_insn "iorsi3" 1055 [(set (match_operand:SI 0 "register_operand" "=r,r") 1056 (ior:SI (match_operand:SI 1 "register_operand" "%0,r") 1057 (match_operand:SI 2 "reg_or_uint16_operand" "r,K")))] 1058 "" 1059 "* 1060{ 1061 /* If we are worried about space, see if we can break this up into two 1062 short instructions, which might eliminate a NOP being inserted. */ 1063 if (optimize_size 1064 && m32r_not_same_reg (operands[0], operands[1]) 1065 && satisfies_constraint_I (operands[2])) 1066 return \"#\"; 1067 1068 else if (CONST_INT_P (operands[2])) 1069 return \"or3 %0,%1,%#%X2\"; 1070 1071 return \"or %0,%2\"; 1072}" 1073 [(set_attr "type" "int2,int4") 1074 (set_attr "length" "2,4")]) 1075 1076(define_split 1077 [(set (match_operand:SI 0 "register_operand" "") 1078 (ior:SI (match_operand:SI 1 "register_operand" "") 1079 (match_operand:SI 2 "int8_operand" "")))] 1080 "optimize_size && m32r_not_same_reg (operands[0], operands[1])" 1081 [(set (match_dup 0) (match_dup 2)) 1082 (set (match_dup 0) (ior:SI (match_dup 0) (match_dup 1)))] 1083 "") 1084 1085(define_insn "xorsi3" 1086 [(set (match_operand:SI 0 "register_operand" "=r,r") 1087 (xor:SI (match_operand:SI 1 "register_operand" "%0,r") 1088 (match_operand:SI 2 "reg_or_uint16_operand" "r,K")))] 1089 "" 1090 "* 1091{ 1092 /* If we are worried about space, see if we can break this up into two 1093 short instructions, which might eliminate a NOP being inserted. */ 1094 if (optimize_size 1095 && m32r_not_same_reg (operands[0], operands[1]) 1096 && satisfies_constraint_I (operands[2])) 1097 return \"#\"; 1098 1099 else if (CONST_INT_P (operands[2])) 1100 return \"xor3 %0,%1,%#%X2\"; 1101 1102 return \"xor %0,%2\"; 1103}" 1104 [(set_attr "type" "int2,int4") 1105 (set_attr "length" "2,4")]) 1106 1107(define_split 1108 [(set (match_operand:SI 0 "register_operand" "") 1109 (xor:SI (match_operand:SI 1 "register_operand" "") 1110 (match_operand:SI 2 "int8_operand" "")))] 1111 "optimize_size && m32r_not_same_reg (operands[0], operands[1])" 1112 [(set (match_dup 0) (match_dup 2)) 1113 (set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))] 1114 "") 1115 1116(define_insn "negsi2" 1117 [(set (match_operand:SI 0 "register_operand" "=r") 1118 (neg:SI (match_operand:SI 1 "register_operand" "r")))] 1119 "" 1120 "neg %0,%1" 1121 [(set_attr "type" "int2") 1122 (set_attr "length" "2")]) 1123 1124(define_insn "one_cmplsi2" 1125 [(set (match_operand:SI 0 "register_operand" "=r") 1126 (not:SI (match_operand:SI 1 "register_operand" "r")))] 1127 "" 1128 "not %0,%1" 1129 [(set_attr "type" "int2") 1130 (set_attr "length" "2")]) 1131 1132;; Shift instructions. 1133 1134(define_insn "ashlsi3" 1135 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 1136 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r") 1137 (match_operand:SI 2 "reg_or_uint16_operand" "r,O,K")))] 1138 "" 1139 "@ 1140 sll %0,%2 1141 slli %0,%#%2 1142 sll3 %0,%1,%#%2" 1143 [(set_attr "type" "shift2,shift2,shift4") 1144 (set_attr "length" "2,2,4")]) 1145 1146(define_insn "ashrsi3" 1147 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 1148 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r") 1149 (match_operand:SI 2 "reg_or_uint16_operand" "r,O,K")))] 1150 "" 1151 "@ 1152 sra %0,%2 1153 srai %0,%#%2 1154 sra3 %0,%1,%#%2" 1155 [(set_attr "type" "shift2,shift2,shift4") 1156 (set_attr "length" "2,2,4")]) 1157 1158(define_insn "lshrsi3" 1159 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 1160 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r") 1161 (match_operand:SI 2 "reg_or_uint16_operand" "r,O,K")))] 1162 "" 1163 "@ 1164 srl %0,%2 1165 srli %0,%#%2 1166 srl3 %0,%1,%#%2" 1167 [(set_attr "type" "shift2,shift2,shift4") 1168 (set_attr "length" "2,2,4")]) 1169 1170;; Compare instructions. 1171;; This controls RTL generation and register allocation. 1172 1173;; We generate RTL for comparisons and branches by having the cmpxx 1174;; patterns store away the operands. Then the bcc patterns 1175;; emit RTL for both the compare and the branch. 1176;; 1177;; On the m32r it is more efficient to use the bxxz instructions and 1178;; thus merge the compare and branch into one instruction, so they are 1179;; preferred. 1180 1181(define_insn "cmp_eqsi_zero_insn" 1182 [(set (reg:CC 17) 1183 (eq:CC (match_operand:SI 0 "register_operand" "r,r") 1184 (match_operand:SI 1 "reg_or_zero_operand" "r,P")))] 1185 "TARGET_M32RX || TARGET_M32R2" 1186 "@ 1187 cmpeq %0, %1 1188 cmpz %0" 1189 [(set_attr "type" "int4") 1190 (set_attr "length" "4")]) 1191 1192;; The cmp_xxx_insn patterns set the condition bit to the result of the 1193;; comparison. There isn't a "compare equal" instruction so cmp_eqsi_insn 1194;; is quite inefficient. However, it is rarely used. 1195 1196(define_insn "cmp_eqsi_insn" 1197 [(set (reg:CC 17) 1198 (eq:CC (match_operand:SI 0 "register_operand" "r,r") 1199 (match_operand:SI 1 "reg_or_cmp_int16_operand" "r,P"))) 1200 (clobber (match_scratch:SI 2 "=&r,&r"))] 1201 "" 1202 "* 1203{ 1204 if (which_alternative == 0) 1205 { 1206 return \"mv %2,%0\;sub %2,%1\;cmpui %2,#1\"; 1207 } 1208 else 1209 { 1210 if (INTVAL (operands [1]) == 0) 1211 return \"cmpui %0, #1\"; 1212 else if (REGNO (operands [2]) == REGNO (operands [0])) 1213 return \"addi %0,%#%N1\;cmpui %2,#1\"; 1214 else 1215 return \"add3 %2,%0,%#%N1\;cmpui %2,#1\"; 1216 } 1217}" 1218 [(set_attr "type" "multi,multi") 1219 (set_attr "length" "8,8")]) 1220 1221(define_insn "cmp_ltsi_insn" 1222 [(set (reg:CC 17) 1223 (lt:CC (match_operand:SI 0 "register_operand" "r,r") 1224 (match_operand:SI 1 "reg_or_int16_operand" "r,J")))] 1225 "" 1226 "@ 1227 cmp %0,%1 1228 cmpi %0,%#%1" 1229 [(set_attr "type" "int2,int4") 1230 (set_attr "length" "2,4")]) 1231 1232(define_insn "cmp_ltusi_insn" 1233 [(set (reg:CC 17) 1234 (ltu:CC (match_operand:SI 0 "register_operand" "r,r") 1235 (match_operand:SI 1 "reg_or_int16_operand" "r,J")))] 1236 "" 1237 "@ 1238 cmpu %0,%1 1239 cmpui %0,%#%1" 1240 [(set_attr "type" "int2,int4") 1241 (set_attr "length" "2,4")]) 1242 1243;; These control RTL generation for conditional jump insns. 1244 1245(define_expand "cbranchsi4" 1246 ; the comparison is emitted by gen_compare if needed. 1247 [(set (pc) 1248 (if_then_else (match_operator 0 "ordered_comparison_operator" 1249 [(match_operand:SI 1 "register_operand" "") 1250 (match_operand:SI 2 "reg_or_cmp_int16_operand" "")]) 1251 (label_ref (match_operand 3 "" "")) 1252 (pc)))] 1253 "" 1254 " 1255{ 1256 operands[0] = gen_compare (GET_CODE (operands[0]), operands[1], operands[2], FALSE); 1257 operands[1] = XEXP (operands[0], 0); 1258 operands[2] = XEXP (operands[0], 1); 1259}") 1260 1261;; Now match both normal and inverted jump. 1262 1263(define_insn "*branch_insn" 1264 [(set (pc) 1265 (if_then_else (match_operator 1 "eqne_comparison_operator" 1266 [(reg 17) (const_int 0)]) 1267 (label_ref (match_operand 0 "" "")) 1268 (pc)))] 1269 "" 1270 "* 1271{ 1272 static char instruction[40]; 1273 sprintf (instruction, \"%s%s %%l0\", 1274 (GET_CODE (operands[1]) == NE) ? \"bc\" : \"bnc\", 1275 (get_attr_length (insn) == 2) ? \".s\" : \"\"); 1276 return instruction; 1277}" 1278 [(set_attr "type" "branch") 1279 ; cf PR gcc/28508 1280 ; We use 300/600 instead of 512,1024 to account for inaccurate insn 1281 ; lengths and insn alignments that are complex to track. 1282 ; It's not important that we be hyper-precise here. It may be more 1283 ; important blah blah blah when the chip supports parallel execution 1284 ; blah blah blah but until then blah blah blah this is simple and 1285 ; suffices. 1286 (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc)) 1287 (const_int 300)) 1288 (const_int 600)) 1289 (const_int 2) 1290 (const_int 4)))]) 1291 1292(define_insn "*rev_branch_insn" 1293 [(set (pc) 1294 (if_then_else (match_operator 1 "eqne_comparison_operator" 1295 [(reg 17) (const_int 0)]) 1296 (pc) 1297 (label_ref (match_operand 0 "" ""))))] 1298 ;"REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))" 1299 "" 1300 "* 1301{ 1302 static char instruction[40]; 1303 sprintf (instruction, \"%s%s %%l0\", 1304 (GET_CODE (operands[1]) == EQ) ? \"bc\" : \"bnc\", 1305 (get_attr_length (insn) == 2) ? \".s\" : \"\"); 1306 return instruction; 1307}" 1308 [(set_attr "type" "branch") 1309 ; cf PR gcc/28508 1310 ; We use 300/600 instead of 512,1024 to account for inaccurate insn 1311 ; lengths and insn alignments that are complex to track. 1312 ; It's not important that we be hyper-precise here. It may be more 1313 ; important blah blah blah when the chip supports parallel execution 1314 ; blah blah blah but until then blah blah blah this is simple and 1315 ; suffices. 1316 (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc)) 1317 (const_int 300)) 1318 (const_int 600)) 1319 (const_int 2) 1320 (const_int 4)))]) 1321 1322; reg/reg compare and branch insns 1323 1324(define_insn "*reg_branch_insn" 1325 [(set (pc) 1326 (if_then_else (match_operator 1 "eqne_comparison_operator" 1327 [(match_operand:SI 2 "register_operand" "r") 1328 (match_operand:SI 3 "register_operand" "r")]) 1329 (label_ref (match_operand 0 "" "")) 1330 (pc)))] 1331 "" 1332 "* 1333{ 1334 /* Is branch target reachable with beq/bne? */ 1335 if (get_attr_length (insn) == 4) 1336 { 1337 if (GET_CODE (operands[1]) == EQ) 1338 return \"beq %2,%3,%l0\"; 1339 else 1340 return \"bne %2,%3,%l0\"; 1341 } 1342 else 1343 { 1344 if (GET_CODE (operands[1]) == EQ) 1345 return \"bne %2,%3,1f\;bra %l0\;1:\"; 1346 else 1347 return \"beq %2,%3,1f\;bra %l0\;1:\"; 1348 } 1349}" 1350 [(set_attr "type" "branch") 1351 ; We use 25000/50000 instead of 32768/65536 to account for slot filling 1352 ; which is complex to track and inaccurate length specs. 1353 (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc)) 1354 (const_int 25000)) 1355 (const_int 50000)) 1356 (const_int 4) 1357 (const_int 8)))]) 1358 1359(define_insn "*rev_reg_branch_insn" 1360 [(set (pc) 1361 (if_then_else (match_operator 1 "eqne_comparison_operator" 1362 [(match_operand:SI 2 "register_operand" "r") 1363 (match_operand:SI 3 "register_operand" "r")]) 1364 (pc) 1365 (label_ref (match_operand 0 "" ""))))] 1366 "" 1367 "* 1368{ 1369 /* Is branch target reachable with beq/bne? */ 1370 if (get_attr_length (insn) == 4) 1371 { 1372 if (GET_CODE (operands[1]) == NE) 1373 return \"beq %2,%3,%l0\"; 1374 else 1375 return \"bne %2,%3,%l0\"; 1376 } 1377 else 1378 { 1379 if (GET_CODE (operands[1]) == NE) 1380 return \"bne %2,%3,1f\;bra %l0\;1:\"; 1381 else 1382 return \"beq %2,%3,1f\;bra %l0\;1:\"; 1383 } 1384}" 1385 [(set_attr "type" "branch") 1386 ; We use 25000/50000 instead of 32768/65536 to account for slot filling 1387 ; which is complex to track and inaccurate length specs. 1388 (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc)) 1389 (const_int 25000)) 1390 (const_int 50000)) 1391 (const_int 4) 1392 (const_int 8)))]) 1393 1394; reg/zero compare and branch insns 1395 1396(define_insn "*zero_branch_insn" 1397 [(set (pc) 1398 (if_then_else (match_operator 1 "signed_comparison_operator" 1399 [(match_operand:SI 2 "register_operand" "r") 1400 (const_int 0)]) 1401 (label_ref (match_operand 0 "" "")) 1402 (pc)))] 1403 "" 1404 "* 1405{ 1406 const char *br,*invbr; 1407 char asmtext[40]; 1408 1409 switch (GET_CODE (operands[1])) 1410 { 1411 case EQ : br = \"eq\"; invbr = \"ne\"; break; 1412 case NE : br = \"ne\"; invbr = \"eq\"; break; 1413 case LE : br = \"le\"; invbr = \"gt\"; break; 1414 case GT : br = \"gt\"; invbr = \"le\"; break; 1415 case LT : br = \"lt\"; invbr = \"ge\"; break; 1416 case GE : br = \"ge\"; invbr = \"lt\"; break; 1417 1418 default: gcc_unreachable (); 1419 } 1420 1421 /* Is branch target reachable with bxxz? */ 1422 if (get_attr_length (insn) == 4) 1423 { 1424 sprintf (asmtext, \"b%sz %%2,%%l0\", br); 1425 output_asm_insn (asmtext, operands); 1426 } 1427 else 1428 { 1429 sprintf (asmtext, \"b%sz %%2,1f\;bra %%l0\;1:\", invbr); 1430 output_asm_insn (asmtext, operands); 1431 } 1432 return \"\"; 1433}" 1434 [(set_attr "type" "branch") 1435 ; We use 25000/50000 instead of 32768/65536 to account for slot filling 1436 ; which is complex to track and inaccurate length specs. 1437 (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc)) 1438 (const_int 25000)) 1439 (const_int 50000)) 1440 (const_int 4) 1441 (const_int 8)))]) 1442 1443(define_insn "*rev_zero_branch_insn" 1444 [(set (pc) 1445 (if_then_else (match_operator 1 "eqne_comparison_operator" 1446 [(match_operand:SI 2 "register_operand" "r") 1447 (const_int 0)]) 1448 (pc) 1449 (label_ref (match_operand 0 "" ""))))] 1450 "" 1451 "* 1452{ 1453 const char *br,*invbr; 1454 char asmtext[40]; 1455 1456 switch (GET_CODE (operands[1])) 1457 { 1458 case EQ : br = \"eq\"; invbr = \"ne\"; break; 1459 case NE : br = \"ne\"; invbr = \"eq\"; break; 1460 case LE : br = \"le\"; invbr = \"gt\"; break; 1461 case GT : br = \"gt\"; invbr = \"le\"; break; 1462 case LT : br = \"lt\"; invbr = \"ge\"; break; 1463 case GE : br = \"ge\"; invbr = \"lt\"; break; 1464 1465 default: gcc_unreachable (); 1466 } 1467 1468 /* Is branch target reachable with bxxz? */ 1469 if (get_attr_length (insn) == 4) 1470 { 1471 sprintf (asmtext, \"b%sz %%2,%%l0\", invbr); 1472 output_asm_insn (asmtext, operands); 1473 } 1474 else 1475 { 1476 sprintf (asmtext, \"b%sz %%2,1f\;bra %%l0\;1:\", br); 1477 output_asm_insn (asmtext, operands); 1478 } 1479 return \"\"; 1480}" 1481 [(set_attr "type" "branch") 1482 ; We use 25000/50000 instead of 32768/65536 to account for slot filling 1483 ; which is complex to track and inaccurate length specs. 1484 (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc)) 1485 (const_int 25000)) 1486 (const_int 50000)) 1487 (const_int 4) 1488 (const_int 8)))]) 1489 1490;; S<cc> operations to set a register to 1/0 based on a comparison 1491 1492(define_expand "cstoresi4" 1493 [(match_operand:SI 0 "register_operand" "") 1494 (match_operator:SI 1 "ordered_comparison_operator" 1495 [(match_operand:SI 2 "register_operand" "") 1496 (match_operand:SI 3 "reg_or_cmp_int16_operand" "")])] 1497 "" 1498 " 1499{ 1500 if (GET_MODE (operands[0]) != SImode) 1501 FAIL; 1502 1503 if (!gen_cond_store (GET_CODE (operands[1]), 1504 operands[0], operands[2], operands[3])) 1505 FAIL; 1506 1507 DONE; 1508}") 1509 1510(define_insn "seq_insn_m32rx" 1511 [(set (match_operand:SI 0 "register_operand" "=r") 1512 (eq:SI (match_operand:SI 1 "register_operand" "%r") 1513 (match_operand:SI 2 "reg_or_zero_operand" "rP"))) 1514 (clobber (reg:CC 17))] 1515 "TARGET_M32RX || TARGET_M32R2" 1516 "#" 1517 [(set_attr "type" "multi") 1518 (set_attr "length" "6")]) 1519 1520(define_split 1521 [(set (match_operand:SI 0 "register_operand" "") 1522 (eq:SI (match_operand:SI 1 "register_operand" "") 1523 (match_operand:SI 2 "reg_or_zero_operand" ""))) 1524 (clobber (reg:CC 17))] 1525 "TARGET_M32RX || TARGET_M32R2" 1526 [(set (reg:CC 17) 1527 (eq:CC (match_dup 1) 1528 (match_dup 2))) 1529 (set (match_dup 0) 1530 (ne:SI (reg:CC 17) (const_int 0)))] 1531 "") 1532 1533(define_insn "seq_zero_insn" 1534 [(set (match_operand:SI 0 "register_operand" "=r") 1535 (eq:SI (match_operand:SI 1 "register_operand" "r") 1536 (const_int 0))) 1537 (clobber (reg:CC 17))] 1538 "TARGET_M32R" 1539 "#" 1540 [(set_attr "type" "multi") 1541 (set_attr "length" "6")]) 1542 1543(define_split 1544 [(set (match_operand:SI 0 "register_operand" "") 1545 (eq:SI (match_operand:SI 1 "register_operand" "") 1546 (const_int 0))) 1547 (clobber (reg:CC 17))] 1548 "TARGET_M32R" 1549 [(match_dup 3)] 1550 " 1551{ 1552 rtx op0 = operands[0]; 1553 rtx op1 = operands[1]; 1554 1555 start_sequence (); 1556 emit_insn (gen_cmp_ltusi_insn (op1, const1_rtx)); 1557 emit_insn (gen_movcc_insn (op0)); 1558 operands[3] = get_insns (); 1559 end_sequence (); 1560}") 1561 1562(define_insn "seq_insn" 1563 [(set (match_operand:SI 0 "register_operand" "=r,r,??r,r") 1564 (eq:SI (match_operand:SI 1 "register_operand" "r,r,r,r") 1565 (match_operand:SI 2 "reg_or_eq_int16_operand" "r,r,r,PK"))) 1566 (clobber (reg:CC 17)) 1567 (clobber (match_scratch:SI 3 "=1,2,&r,r"))] 1568 "TARGET_M32R" 1569 "#" 1570 [(set_attr "type" "multi") 1571 (set_attr "length" "8,8,10,10")]) 1572 1573(define_split 1574 [(set (match_operand:SI 0 "register_operand" "") 1575 (eq:SI (match_operand:SI 1 "register_operand" "") 1576 (match_operand:SI 2 "reg_or_eq_int16_operand" ""))) 1577 (clobber (reg:CC 17)) 1578 (clobber (match_scratch:SI 3 ""))] 1579 "TARGET_M32R && reload_completed" 1580 [(match_dup 4)] 1581 " 1582{ 1583 rtx op0 = operands[0]; 1584 rtx op1 = operands[1]; 1585 rtx op2 = operands[2]; 1586 rtx op3 = operands[3]; 1587 HOST_WIDE_INT value; 1588 1589 if (REG_P (op2) && REG_P (op3) 1590 && REGNO (op2) == REGNO (op3)) 1591 { 1592 op1 = operands[2]; 1593 op2 = operands[1]; 1594 } 1595 1596 start_sequence (); 1597 if (REG_P (op1) && REG_P (op3) 1598 && REGNO (op1) != REGNO (op3)) 1599 { 1600 emit_move_insn (op3, op1); 1601 op1 = op3; 1602 } 1603 1604 if (satisfies_constraint_P (op2) && (value = INTVAL (op2)) != 0) 1605 emit_insn (gen_addsi3 (op3, op1, GEN_INT (-value))); 1606 else 1607 emit_insn (gen_xorsi3 (op3, op1, op2)); 1608 1609 emit_insn (gen_cmp_ltusi_insn (op3, const1_rtx)); 1610 emit_insn (gen_movcc_insn (op0)); 1611 operands[4] = get_insns (); 1612 end_sequence (); 1613}") 1614 1615(define_insn "sne_zero_insn" 1616 [(set (match_operand:SI 0 "register_operand" "=r") 1617 (ne:SI (match_operand:SI 1 "register_operand" "r") 1618 (const_int 0))) 1619 (clobber (reg:CC 17)) 1620 (clobber (match_scratch:SI 2 "=&r"))] 1621 "" 1622 "#" 1623 [(set_attr "type" "multi") 1624 (set_attr "length" "6")]) 1625 1626(define_split 1627 [(set (match_operand:SI 0 "register_operand" "") 1628 (ne:SI (match_operand:SI 1 "register_operand" "") 1629 (const_int 0))) 1630 (clobber (reg:CC 17)) 1631 (clobber (match_scratch:SI 2 ""))] 1632 "reload_completed" 1633 [(set (match_dup 2) 1634 (const_int 0)) 1635 (set (reg:CC 17) 1636 (ltu:CC (match_dup 2) 1637 (match_dup 1))) 1638 (set (match_dup 0) 1639 (ne:SI (reg:CC 17) (const_int 0)))] 1640 "") 1641 1642(define_insn "slt_insn" 1643 [(set (match_operand:SI 0 "register_operand" "=r,r") 1644 (lt:SI (match_operand:SI 1 "register_operand" "r,r") 1645 (match_operand:SI 2 "reg_or_int16_operand" "r,J"))) 1646 (clobber (reg:CC 17))] 1647 "" 1648 "#" 1649 [(set_attr "type" "multi") 1650 (set_attr "length" "4,6")]) 1651 1652(define_split 1653 [(set (match_operand:SI 0 "register_operand" "") 1654 (lt:SI (match_operand:SI 1 "register_operand" "") 1655 (match_operand:SI 2 "reg_or_int16_operand" ""))) 1656 (clobber (reg:CC 17))] 1657 "" 1658 [(set (reg:CC 17) 1659 (lt:CC (match_dup 1) 1660 (match_dup 2))) 1661 (set (match_dup 0) 1662 (ne:SI (reg:CC 17) (const_int 0)))] 1663 "") 1664 1665(define_insn "sle_insn" 1666 [(set (match_operand:SI 0 "register_operand" "=r") 1667 (le:SI (match_operand:SI 1 "register_operand" "r") 1668 (match_operand:SI 2 "register_operand" "r"))) 1669 (clobber (reg:CC 17))] 1670 "" 1671 "#" 1672 [(set_attr "type" "multi") 1673 (set_attr "length" "8")]) 1674 1675(define_split 1676 [(set (match_operand:SI 0 "register_operand" "") 1677 (le:SI (match_operand:SI 1 "register_operand" "") 1678 (match_operand:SI 2 "register_operand" ""))) 1679 (clobber (reg:CC 17))] 1680 "!optimize_size" 1681 [(set (reg:CC 17) 1682 (lt:CC (match_dup 2) 1683 (match_dup 1))) 1684 (set (match_dup 0) 1685 (ne:SI (reg:CC 17) (const_int 0))) 1686 (set (match_dup 0) 1687 (xor:SI (match_dup 0) 1688 (const_int 1)))] 1689 "") 1690 1691;; If optimizing for space, use -(reg - 1) to invert the comparison rather than 1692;; xor reg,reg,1 which might eliminate a NOP being inserted. 1693(define_split 1694 [(set (match_operand:SI 0 "register_operand" "") 1695 (le:SI (match_operand:SI 1 "register_operand" "") 1696 (match_operand:SI 2 "register_operand" ""))) 1697 (clobber (reg:CC 17))] 1698 "optimize_size" 1699 [(set (reg:CC 17) 1700 (lt:CC (match_dup 2) 1701 (match_dup 1))) 1702 (set (match_dup 0) 1703 (ne:SI (reg:CC 17) (const_int 0))) 1704 (set (match_dup 0) 1705 (plus:SI (match_dup 0) 1706 (const_int -1))) 1707 (set (match_dup 0) 1708 (neg:SI (match_dup 0)))] 1709 "") 1710 1711(define_insn "sge_insn" 1712 [(set (match_operand:SI 0 "register_operand" "=r,r") 1713 (ge:SI (match_operand:SI 1 "register_operand" "r,r") 1714 (match_operand:SI 2 "reg_or_int16_operand" "r,J"))) 1715 (clobber (reg:CC 17))] 1716 "" 1717 "#" 1718 [(set_attr "type" "multi") 1719 (set_attr "length" "8,10")]) 1720 1721(define_split 1722 [(set (match_operand:SI 0 "register_operand" "") 1723 (ge:SI (match_operand:SI 1 "register_operand" "") 1724 (match_operand:SI 2 "reg_or_int16_operand" ""))) 1725 (clobber (reg:CC 17))] 1726 "!optimize_size" 1727 [(set (reg:CC 17) 1728 (lt:CC (match_dup 1) 1729 (match_dup 2))) 1730 (set (match_dup 0) 1731 (ne:SI (reg:CC 17) (const_int 0))) 1732 (set (match_dup 0) 1733 (xor:SI (match_dup 0) 1734 (const_int 1)))] 1735 "") 1736 1737;; If optimizing for space, use -(reg - 1) to invert the comparison rather than 1738;; xor reg,reg,1 which might eliminate a NOP being inserted. 1739(define_split 1740 [(set (match_operand:SI 0 "register_operand" "") 1741 (ge:SI (match_operand:SI 1 "register_operand" "") 1742 (match_operand:SI 2 "reg_or_int16_operand" ""))) 1743 (clobber (reg:CC 17))] 1744 "optimize_size" 1745 [(set (reg:CC 17) 1746 (lt:CC (match_dup 1) 1747 (match_dup 2))) 1748 (set (match_dup 0) 1749 (ne:SI (reg:CC 17) (const_int 0))) 1750 (set (match_dup 0) 1751 (plus:SI (match_dup 0) 1752 (const_int -1))) 1753 (set (match_dup 0) 1754 (neg:SI (match_dup 0)))] 1755 "") 1756 1757(define_insn "sltu_insn" 1758 [(set (match_operand:SI 0 "register_operand" "=r,r") 1759 (ltu:SI (match_operand:SI 1 "register_operand" "r,r") 1760 (match_operand:SI 2 "reg_or_int16_operand" "r,J"))) 1761 (clobber (reg:CC 17))] 1762 "" 1763 "#" 1764 [(set_attr "type" "multi") 1765 (set_attr "length" "6,8")]) 1766 1767(define_split 1768 [(set (match_operand:SI 0 "register_operand" "") 1769 (ltu:SI (match_operand:SI 1 "register_operand" "") 1770 (match_operand:SI 2 "reg_or_int16_operand" ""))) 1771 (clobber (reg:CC 17))] 1772 "" 1773 [(set (reg:CC 17) 1774 (ltu:CC (match_dup 1) 1775 (match_dup 2))) 1776 (set (match_dup 0) 1777 (ne:SI (reg:CC 17) (const_int 0)))] 1778 "") 1779 1780(define_insn "sleu_insn" 1781 [(set (match_operand:SI 0 "register_operand" "=r") 1782 (leu:SI (match_operand:SI 1 "register_operand" "r") 1783 (match_operand:SI 2 "register_operand" "r"))) 1784 (clobber (reg:CC 17))] 1785 "" 1786 "#" 1787 [(set_attr "type" "multi") 1788 (set_attr "length" "8")]) 1789 1790(define_split 1791 [(set (match_operand:SI 0 "register_operand" "") 1792 (leu:SI (match_operand:SI 1 "register_operand" "") 1793 (match_operand:SI 2 "register_operand" ""))) 1794 (clobber (reg:CC 17))] 1795 "!optimize_size" 1796 [(set (reg:CC 17) 1797 (ltu:CC (match_dup 2) 1798 (match_dup 1))) 1799 (set (match_dup 0) 1800 (ne:SI (reg:CC 17) (const_int 0))) 1801 (set (match_dup 0) 1802 (xor:SI (match_dup 0) 1803 (const_int 1)))] 1804 "") 1805 1806;; If optimizing for space, use -(reg - 1) to invert the comparison rather than 1807;; xor reg,reg,1 which might eliminate a NOP being inserted. 1808(define_split 1809 [(set (match_operand:SI 0 "register_operand" "") 1810 (leu:SI (match_operand:SI 1 "register_operand" "") 1811 (match_operand:SI 2 "register_operand" ""))) 1812 (clobber (reg:CC 17))] 1813 "optimize_size" 1814 [(set (reg:CC 17) 1815 (ltu:CC (match_dup 2) 1816 (match_dup 1))) 1817 (set (match_dup 0) 1818 (ne:SI (reg:CC 17) (const_int 0))) 1819 (set (match_dup 0) 1820 (plus:SI (match_dup 0) 1821 (const_int -1))) 1822 (set (match_dup 0) 1823 (neg:SI (match_dup 0)))] 1824 "") 1825 1826(define_insn "sgeu_insn" 1827 [(set (match_operand:SI 0 "register_operand" "=r,r") 1828 (geu:SI (match_operand:SI 1 "register_operand" "r,r") 1829 (match_operand:SI 2 "reg_or_int16_operand" "r,J"))) 1830 (clobber (reg:CC 17))] 1831 "" 1832 "#" 1833 [(set_attr "type" "multi") 1834 (set_attr "length" "8,10")]) 1835 1836(define_split 1837 [(set (match_operand:SI 0 "register_operand" "") 1838 (geu:SI (match_operand:SI 1 "register_operand" "") 1839 (match_operand:SI 2 "reg_or_int16_operand" ""))) 1840 (clobber (reg:CC 17))] 1841 "!optimize_size" 1842 [(set (reg:CC 17) 1843 (ltu:CC (match_dup 1) 1844 (match_dup 2))) 1845 (set (match_dup 0) 1846 (ne:SI (reg:CC 17) (const_int 0))) 1847 (set (match_dup 0) 1848 (xor:SI (match_dup 0) 1849 (const_int 1)))] 1850 "") 1851 1852;; If optimizing for space, use -(reg - 1) to invert the comparison rather than 1853;; xor reg,reg,1 which might eliminate a NOP being inserted. 1854(define_split 1855 [(set (match_operand:SI 0 "register_operand" "") 1856 (geu:SI (match_operand:SI 1 "register_operand" "") 1857 (match_operand:SI 2 "reg_or_int16_operand" ""))) 1858 (clobber (reg:CC 17))] 1859 "optimize_size" 1860 [(set (reg:CC 17) 1861 (ltu:CC (match_dup 1) 1862 (match_dup 2))) 1863 (set (match_dup 0) 1864 (ne:SI (reg:CC 17) (const_int 0))) 1865 (set (match_dup 0) 1866 (plus:SI (match_dup 0) 1867 (const_int -1))) 1868 (set (match_dup 0) 1869 (neg:SI (match_dup 0)))] 1870 "") 1871 1872(define_insn "movcc_insn" 1873 [(set (match_operand:SI 0 "register_operand" "=r") 1874 (ne:SI (reg:CC 17) (const_int 0)))] 1875 "" 1876 "mvfc %0, cbr" 1877 [(set_attr "type" "misc") 1878 (set_attr "length" "2")]) 1879 1880 1881;; Unconditional and other jump instructions. 1882 1883(define_insn "jump" 1884 [(set (pc) (label_ref (match_operand 0 "" "")))] 1885 "" 1886 "bra %l0" 1887 [(set_attr "type" "uncond_branch") 1888 (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc)) 1889 (const_int 400)) 1890 (const_int 800)) 1891 (const_int 2) 1892 (const_int 4)))]) 1893 1894(define_insn "indirect_jump" 1895 [(set (pc) (match_operand:SI 0 "address_operand" "p"))] 1896 "" 1897 "jmp %a0" 1898 [(set_attr "type" "uncond_branch") 1899 (set_attr "length" "2")]) 1900 1901(define_insn "return_lr" 1902 [(parallel [(return) (use (reg:SI 14))])] 1903 "" 1904 "jmp lr" 1905 [(set_attr "type" "uncond_branch") 1906 (set_attr "length" "2")]) 1907 1908(define_insn "return_rte" 1909 [(return)] 1910 "" 1911 "rte" 1912 [(set_attr "type" "uncond_branch") 1913 (set_attr "length" "2")]) 1914 1915(define_expand "return" 1916 [(return)] 1917 "direct_return ()" 1918 " 1919{ 1920 emit_jump_insn (gen_return_lr ()); 1921 DONE; 1922}") 1923 1924(define_expand "return_normal" 1925 [(return)] 1926 "!direct_return ()" 1927 " 1928{ 1929 enum m32r_function_type fn_type; 1930 1931 fn_type = m32r_compute_function_type (current_function_decl); 1932 if (M32R_INTERRUPT_P (fn_type)) 1933 { 1934 emit_jump_insn (gen_return_rte ()); 1935 DONE; 1936 } 1937 1938 emit_jump_insn (gen_return_lr ()); 1939 DONE; 1940}") 1941 1942(define_expand "tablejump" 1943 [(parallel [(set (pc) (match_operand 0 "register_operand" "r")) 1944 (use (label_ref (match_operand 1 "" "")))])] 1945 "" 1946 " 1947{ 1948 /* In pic mode, our address differences are against the base of the 1949 table. Add that base value back in; CSE ought to be able to combine 1950 the two address loads. */ 1951 if (flag_pic) 1952 { 1953 rtx tmp, tmp2; 1954 1955 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]); 1956 tmp2 = operands[0]; 1957 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp); 1958 operands[0] = memory_address (Pmode, tmp); 1959 } 1960}") 1961 1962(define_insn "*tablejump_insn" 1963 [(set (pc) (match_operand:SI 0 "address_operand" "p")) 1964 (use (label_ref (match_operand 1 "" "")))] 1965 "" 1966 "jmp %a0" 1967 [(set_attr "type" "uncond_branch") 1968 (set_attr "length" "2")]) 1969 1970(define_expand "call" 1971 ;; operands[1] is stack_size_rtx 1972 ;; operands[2] is next_arg_register 1973 [(parallel [(call (match_operand:SI 0 "call_operand" "") 1974 (match_operand 1 "" "")) 1975 (clobber (reg:SI 14))])] 1976 "" 1977 " 1978{ 1979 if (flag_pic) 1980 crtl->uses_pic_offset_table = 1; 1981}") 1982 1983(define_insn "*call_via_reg" 1984 [(call (mem:SI (match_operand:SI 0 "register_operand" "r")) 1985 (match_operand 1 "" "")) 1986 (clobber (reg:SI 14))] 1987 "" 1988 "jl %0" 1989 [(set_attr "type" "call") 1990 (set_attr "length" "2")]) 1991 1992(define_insn "*call_via_label" 1993 [(call (mem:SI (match_operand:SI 0 "call_address_operand" "")) 1994 (match_operand 1 "" "")) 1995 (clobber (reg:SI 14))] 1996 "" 1997 "* 1998{ 1999 int call26_p = call26_operand (operands[0], FUNCTION_MODE); 2000 2001 if (! call26_p) 2002 { 2003 /* We may not be able to reach with a `bl' insn so punt and leave it to 2004 the linker. 2005 We do this here, rather than doing a force_reg in the define_expand 2006 so these insns won't be separated, say by scheduling, thus simplifying 2007 the linker. */ 2008 return \"seth r14,%T0\;add3 r14,r14,%B0\;jl r14\"; 2009 } 2010 else 2011 return \"bl %0\"; 2012}" 2013 [(set_attr "type" "call") 2014 (set (attr "length") 2015 (if_then_else (eq (symbol_ref "call26_operand (operands[0], FUNCTION_MODE)") 2016 (const_int 0)) 2017 (const_int 12) ; 10 + 2 for nop filler 2018 ; The return address must be on a 4 byte boundary so 2019 ; there's no point in using a value of 2 here. A 2 byte 2020 ; insn may go in the left slot but we currently can't 2021 ; use such knowledge. 2022 (const_int 4)))]) 2023 2024(define_expand "call_value" 2025 ;; operand 2 is stack_size_rtx 2026 ;; operand 3 is next_arg_register 2027 [(parallel [(set (match_operand 0 "register_operand" "=r") 2028 (call (match_operand:SI 1 "call_operand" "") 2029 (match_operand 2 "" ""))) 2030 (clobber (reg:SI 14))])] 2031 "" 2032 " 2033{ 2034 if (flag_pic) 2035 crtl->uses_pic_offset_table = 1; 2036}") 2037 2038(define_insn "*call_value_via_reg" 2039 [(set (match_operand 0 "register_operand" "=r") 2040 (call (mem:SI (match_operand:SI 1 "register_operand" "r")) 2041 (match_operand 2 "" ""))) 2042 (clobber (reg:SI 14))] 2043 "" 2044 "jl %1" 2045 [(set_attr "type" "call") 2046 (set_attr "length" "2")]) 2047 2048(define_insn "*call_value_via_label" 2049 [(set (match_operand 0 "register_operand" "=r") 2050 (call (mem:SI (match_operand:SI 1 "call_address_operand" "")) 2051 (match_operand 2 "" ""))) 2052 (clobber (reg:SI 14))] 2053 "" 2054 "* 2055{ 2056 int call26_p = call26_operand (operands[1], FUNCTION_MODE); 2057 2058 if (flag_pic) 2059 crtl->uses_pic_offset_table = 1; 2060 2061 if (! call26_p) 2062 { 2063 /* We may not be able to reach with a `bl' insn so punt and leave it to 2064 the linker. 2065 We do this here, rather than doing a force_reg in the define_expand 2066 so these insns won't be separated, say by scheduling, thus simplifying 2067 the linker. */ 2068 return \"seth r14,%T1\;add3 r14,r14,%B1\;jl r14\"; 2069 } 2070 else 2071 return \"bl %1\"; 2072}" 2073 [(set_attr "type" "call") 2074 (set (attr "length") 2075 (if_then_else (eq (symbol_ref "call26_operand (operands[1], FUNCTION_MODE)") 2076 (const_int 0)) 2077 (const_int 12) ; 10 + 2 for nop filler 2078 ; The return address must be on a 4 byte boundary so 2079 ; there's no point in using a value of 2 here. A 2 byte 2080 ; insn may go in the left slot but we currently can't 2081 ; use such knowledge. 2082 (const_int 4)))]) 2083 2084(define_insn "nop" 2085 [(const_int 0)] 2086 "" 2087 "nop" 2088 [(set_attr "type" "int2") 2089 (set_attr "length" "2")]) 2090 2091;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and 2092;; all of memory. This blocks insns from being moved across this point. 2093 2094(define_insn "blockage" 2095 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)] 2096 "" 2097 "") 2098 2099;; Special pattern to flush the icache. 2100 2101(define_insn "flush_icache" 2102 [(unspec_volatile [(match_operand 0 "memory_operand" "m")] 2103 UNSPECV_FLUSH_ICACHE) 2104 (match_operand 1 "" "") 2105 (clobber (reg:SI 17))] 2106 "" 2107 "* return \"trap %#%1 ; flush-icache\";" 2108 [(set_attr "type" "int4") 2109 (set_attr "length" "4")]) 2110 2111;; Speed up fabs and provide correct sign handling for -0 2112 2113(define_insn "absdf2" 2114 [(set (match_operand:DF 0 "register_operand" "=r") 2115 (abs:DF (match_operand:DF 1 "register_operand" "0")))] 2116 "" 2117 "#" 2118 [(set_attr "type" "multi") 2119 (set_attr "length" "4")]) 2120 2121(define_split 2122 [(set (match_operand:DF 0 "register_operand" "") 2123 (abs:DF (match_operand:DF 1 "register_operand" "")))] 2124 "reload_completed" 2125 [(set (match_dup 2) 2126 (ashift:SI (match_dup 2) 2127 (const_int 1))) 2128 (set (match_dup 2) 2129 (lshiftrt:SI (match_dup 2) 2130 (const_int 1)))] 2131 "operands[2] = gen_highpart (SImode, operands[0]);") 2132 2133(define_insn "abssf2" 2134 [(set (match_operand:SF 0 "register_operand" "=r") 2135 (abs:SF (match_operand:SF 1 "register_operand" "0")))] 2136 "" 2137 "#" 2138 [(set_attr "type" "multi") 2139 (set_attr "length" "4")]) 2140 2141(define_split 2142 [(set (match_operand:SF 0 "register_operand" "") 2143 (abs:SF (match_operand:SF 1 "register_operand" "")))] 2144 "reload_completed" 2145 [(set (match_dup 2) 2146 (ashift:SI (match_dup 2) 2147 (const_int 1))) 2148 (set (match_dup 2) 2149 (lshiftrt:SI (match_dup 2) 2150 (const_int 1)))] 2151 "operands[2] = gen_highpart (SImode, operands[0]);") 2152 2153;; Conditional move instructions 2154;; Based on those done for the d10v 2155 2156(define_expand "movsicc" 2157 [ 2158 (set (match_operand:SI 0 "register_operand" "r") 2159 (if_then_else:SI (match_operand 1 "" "") 2160 (match_operand:SI 2 "conditional_move_operand" "O") 2161 (match_operand:SI 3 "conditional_move_operand" "O") 2162 ) 2163 ) 2164 ] 2165 "" 2166 " 2167{ 2168 if (! zero_and_one (operands [2], operands [3])) 2169 FAIL; 2170 2171 /* Generate the comparison that will set the carry flag. */ 2172 operands[1] = gen_compare (GET_CODE (operands[1]), XEXP (operands[1], 0), 2173 XEXP (operands[1], 1), TRUE); 2174 2175 /* See other movsicc pattern below for reason why. */ 2176 emit_insn (gen_blockage ()); 2177}") 2178 2179;; Generate the conditional instructions based on how the carry flag is examined. 2180(define_insn "*movsicc_internal" 2181 [(set (match_operand:SI 0 "register_operand" "=r") 2182 (if_then_else:SI (match_operand 1 "carry_compare_operand" "") 2183 (match_operand:SI 2 "conditional_move_operand" "O") 2184 (match_operand:SI 3 "conditional_move_operand" "O") 2185 ) 2186 )] 2187 "zero_and_one (operands [2], operands[3])" 2188 "* return emit_cond_move (operands, insn);" 2189 [(set_attr "type" "multi") 2190 (set_attr "length" "8") 2191 ] 2192) 2193 2194 2195;; Block moves, see m32r.c for more details. 2196;; Argument 0 is the destination 2197;; Argument 1 is the source 2198;; Argument 2 is the length 2199;; Argument 3 is the alignment 2200 2201(define_expand "movmemsi" 2202 [(parallel [(set (match_operand:BLK 0 "general_operand" "") 2203 (match_operand:BLK 1 "general_operand" "")) 2204 (use (match_operand:SI 2 "immediate_operand" "")) 2205 (use (match_operand:SI 3 "immediate_operand" ""))])] 2206 "" 2207 " 2208{ 2209 if (operands[0]) /* Avoid unused code messages. */ 2210 { 2211 if (m32r_expand_block_move (operands)) 2212 DONE; 2213 else 2214 FAIL; 2215 } 2216}") 2217 2218;; Insn generated by block moves 2219 2220(define_insn "movmemsi_internal" 2221 [(set (mem:BLK (match_operand:SI 0 "register_operand" "r")) ;; destination 2222 (mem:BLK (match_operand:SI 1 "register_operand" "r"))) ;; source 2223 (use (match_operand:SI 2 "m32r_block_immediate_operand" "J"));; # bytes to move 2224 (set (match_operand:SI 3 "register_operand" "=0") 2225 (plus:SI (minus (match_dup 2) (const_int 4)) 2226 (match_dup 0))) 2227 (set (match_operand:SI 4 "register_operand" "=1") 2228 (plus:SI (match_dup 1) 2229 (match_dup 2))) 2230 (clobber (match_scratch:SI 5 "=&r")) ;; temp1 2231 (clobber (match_scratch:SI 6 "=&r"))] ;; temp2 2232 "" 2233 "* m32r_output_block_move (insn, operands); return \"\"; " 2234 [(set_attr "type" "store8") 2235 (set_attr "length" "72")]) ;; Maximum 2236 2237;; PIC 2238 2239/* When generating pic, we need to load the symbol offset into a register. 2240 So that the optimizer does not confuse this with a normal symbol load 2241 we use an unspec. The offset will be loaded from a constant pool entry, 2242 since that is the only type of relocation we can use. */ 2243 2244(define_insn "pic_load_addr" 2245 [(set (match_operand:SI 0 "register_operand" "=r") 2246 (unspec:SI [(match_operand 1 "" "")] UNSPEC_PIC_LOAD_ADDR))] 2247 "flag_pic" 2248 "ld24 %0,%#%1" 2249 [(set_attr "type" "int4")]) 2250 2251(define_insn "gotoff_load_addr" 2252 [(set (match_operand:SI 0 "register_operand" "=r") 2253 (unspec:SI [(match_operand 1 "" "")] UNSPEC_GOTOFF))] 2254 "flag_pic" 2255 "seth %0, %#shigh(%1@GOTOFF)\;add3 %0, %0, low(%1@GOTOFF)" 2256 [(set_attr "type" "int4") 2257 (set_attr "length" "8")]) 2258 2259;; Load program counter insns. 2260 2261(define_insn "get_pc" 2262 [(clobber (reg:SI 14)) 2263 (set (match_operand 0 "register_operand" "=r,r") 2264 (unspec [(match_operand 1 "" "")] UNSPEC_GET_PC)) 2265 (use (match_operand:SI 2 "immediate_operand" "W,i"))] 2266 "flag_pic" 2267 "@ 2268 bl.s .+4\;seth %0,%#shigh(%1)\;add3 %0,%0,%#low(%1+4)\;add %0,lr 2269 bl.s .+4\;ld24 %0,%#%1\;add %0,lr" 2270 [(set_attr "length" "12,8")]) 2271 2272(define_expand "builtin_setjmp_receiver" 2273 [(label_ref (match_operand 0 "" ""))] 2274 "flag_pic" 2275 " 2276{ 2277 m32r_load_pic_register (); 2278 DONE; 2279}") 2280