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