1;; Machine description of the Lattice Mico32 architecture for GNU C compiler. 2;; Contributed by Jon Beniston <jon@beniston.com> 3 4;; Copyright (C) 2009-2015 Free Software Foundation, Inc. 5 6;; This file is part of GCC. 7 8;; GCC is free software; you can redistribute it and/or modify it 9;; under the terms of the GNU General Public License as published 10;; by the Free Software Foundation; either version 3, or (at your 11;; option) any later version. 12 13;; GCC is distributed in the hope that it will be useful, but WITHOUT 14;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 15;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 16;; License for more details. 17 18;; You should have received a copy of the GNU General Public License 19;; along with GCC; see the file COPYING3. If not see 20;; <http://www.gnu.org/licenses/>. 21 22;; Include predicate and constraint definitions 23(include "predicates.md") 24(include "constraints.md") 25 26 27;; Register numbers 28(define_constants 29 [(RA_REGNUM 29) ; return address register. 30 ] 31) 32 33;; LM32 specific volatile operations 34(define_constants 35 [(UNSPECV_BLOCKAGE 1)] ; prevent scheduling across pro/epilog boundaries 36) 37 38;; LM32 specific operations 39(define_constants 40 [(UNSPEC_GOT 2) 41 (UNSPEC_GOTOFF_HI16 3) 42 (UNSPEC_GOTOFF_LO16 4)] 43) 44 45;; --------------------------------- 46;; instruction types 47;; --------------------------------- 48 49(define_attr "type" 50 "unknown,load,store,arith,compare,shift,multiply,divide,call,icall,ubranch,uibranch,cbranch" 51 (const_string "unknown")) 52 53;; --------------------------------- 54;; instruction lengths 55;; --------------------------------- 56 57; All instructions are 4 bytes 58; Except for branches that are out of range, and have to be implemented 59; as two instructions 60(define_attr "length" "" 61 (cond [ 62 (eq_attr "type" "cbranch") 63 (if_then_else 64 (lt (abs (minus (match_dup 2) (pc))) 65 (const_int 32768) 66 ) 67 (const_int 4) 68 (const_int 8) 69 ) 70 ] 71 (const_int 4)) 72) 73 74;; --------------------------------- 75;; scheduling 76;; --------------------------------- 77 78(define_automaton "lm32") 79 80(define_cpu_unit "x" "lm32") 81(define_cpu_unit "m" "lm32") 82(define_cpu_unit "w" "lm32") 83 84(define_insn_reservation "singlecycle" 1 85 (eq_attr "type" "store,arith,call,icall,ubranch,uibranch,cbranch") 86 "x") 87 88(define_insn_reservation "twocycle" 2 89 (eq_attr "type" "compare,shift,divide") 90 "x,m") 91 92(define_insn_reservation "threecycle" 3 93 (eq_attr "type" "load,multiply") 94 "x,m,w") 95 96;; --------------------------------- 97;; mov 98;; --------------------------------- 99 100(define_expand "movqi" 101 [(set (match_operand:QI 0 "general_operand" "") 102 (match_operand:QI 1 "general_operand" ""))] 103 "" 104 " 105{ 106 if (can_create_pseudo_p ()) 107 { 108 if (GET_CODE (operand0) == MEM) 109 { 110 /* Source operand for store must be in a register. */ 111 operands[1] = force_reg (QImode, operands[1]); 112 } 113 } 114}") 115 116(define_expand "movhi" 117 [(set (match_operand:HI 0 "general_operand" "") 118 (match_operand:HI 1 "general_operand" ""))] 119 "" 120 " 121{ 122 if (can_create_pseudo_p ()) 123 { 124 if (GET_CODE (operands[0]) == MEM) 125 { 126 /* Source operand for store must be in a register. */ 127 operands[1] = force_reg (HImode, operands[1]); 128 } 129 } 130}") 131 132(define_expand "movsi" 133 [(set (match_operand:SI 0 "general_operand" "") 134 (match_operand:SI 1 "general_operand" ""))] 135 "" 136 " 137{ 138 if (can_create_pseudo_p ()) 139 { 140 if (GET_CODE (operands[0]) == MEM 141 || (GET_CODE (operands[0]) == SUBREG 142 && GET_CODE (SUBREG_REG (operands[0])) == MEM)) 143 { 144 /* Source operand for store must be in a register. */ 145 operands[1] = force_reg (SImode, operands[1]); 146 } 147 } 148 149 if (flag_pic && symbolic_operand (operands[1], SImode)) 150 { 151 if (GET_CODE (operands[1]) == LABEL_REF 152 || (GET_CODE (operands[1]) == SYMBOL_REF 153 && SYMBOL_REF_LOCAL_P (operands[1]) 154 && !SYMBOL_REF_WEAK (operands[1]))) 155 { 156 emit_insn (gen_movsi_gotoff_hi16 (operands[0], operands[1])); 157 emit_insn (gen_addsi3 (operands[0], 158 operands[0], 159 pic_offset_table_rtx)); 160 emit_insn (gen_movsi_gotoff_lo16 (operands[0], 161 operands[0], 162 operands[1])); 163 } 164 else 165 emit_insn (gen_movsi_got (operands[0], operands[1])); 166 crtl->uses_pic_offset_table = 1; 167 DONE; 168 } 169 else if (flag_pic && GET_CODE (operands[1]) == CONST) 170 { 171 rtx op = XEXP (operands[1], 0); 172 if (GET_CODE (op) == PLUS) 173 { 174 rtx arg0 = XEXP (op, 0); 175 rtx arg1 = XEXP (op, 1); 176 if (GET_CODE (arg0) == LABEL_REF 177 || (GET_CODE (arg0) == SYMBOL_REF 178 && SYMBOL_REF_LOCAL_P (arg0) 179 && !SYMBOL_REF_WEAK (arg0))) 180 { 181 emit_insn (gen_movsi_gotoff_hi16 (operands[0], arg0)); 182 emit_insn (gen_addsi3 (operands[0], 183 operands[0], 184 pic_offset_table_rtx)); 185 emit_insn (gen_movsi_gotoff_lo16 (operands[0], 186 operands[0], 187 arg0)); 188 } 189 else 190 emit_insn (gen_movsi_got (operands[0], arg0)); 191 emit_insn (gen_addsi3 (operands[0], operands[0], arg1)); 192 crtl->uses_pic_offset_table = 1; 193 DONE; 194 } 195 } 196 else if (!flag_pic && reloc_operand (operands[1], GET_MODE (operands[1]))) 197 { 198 emit_insn (gen_rtx_SET (SImode, operands[0], gen_rtx_HIGH (SImode, operands[1]))); 199 emit_insn (gen_rtx_SET (SImode, operands[0], gen_rtx_LO_SUM (SImode, operands[0], operands[1]))); 200 DONE; 201 } 202 else if (GET_CODE (operands[1]) == CONST_INT) 203 { 204 if (!(satisfies_constraint_K (operands[1]) 205 || satisfies_constraint_L (operands[1]) 206 || satisfies_constraint_U (operands[1]))) 207 { 208 emit_insn (gen_movsi_insn (operands[0], 209 GEN_INT (INTVAL (operands[1]) & ~0xffff))); 210 emit_insn (gen_iorsi3 (operands[0], 211 operands[0], 212 GEN_INT (INTVAL (operands[1]) & 0xffff))); 213 DONE; 214 } 215 } 216}") 217 218(define_expand "movmemsi" 219 [(parallel [(set (match_operand:BLK 0 "general_operand" "") 220 (match_operand:BLK 1 "general_operand" "")) 221 (use (match_operand:SI 2 "" "")) 222 (use (match_operand:SI 3 "const_int_operand" ""))])] 223 "" 224{ 225 if (!lm32_expand_block_move (operands)) 226 FAIL; 227 DONE; 228}) 229 230;; --------------------------------- 231;; load/stores/moves 232;; --------------------------------- 233 234(define_insn "movsi_got" 235 [(set (match_operand:SI 0 "register_operand" "=r") 236 (unspec:SI [(match_operand 1 "" "")] UNSPEC_GOT))] 237 "flag_pic" 238 "lw %0, (gp+got(%1))" 239 [(set_attr "type" "load")] 240) 241 242(define_insn "movsi_gotoff_hi16" 243 [(set (match_operand:SI 0 "register_operand" "=r") 244 (unspec:SI [(match_operand 1 "" "")] UNSPEC_GOTOFF_HI16))] 245 "flag_pic" 246 "orhi %0, r0, gotoffhi16(%1)" 247 [(set_attr "type" "load")] 248) 249 250(define_insn "movsi_gotoff_lo16" 251 [(set (match_operand:SI 0 "register_operand" "=r") 252 (unspec:SI [(plus:SI (match_operand:SI 1 "register_operand" "0") 253 (match_operand 2 "" ""))] UNSPEC_GOTOFF_LO16))] 254 "flag_pic" 255 "addi %0, %1, gotofflo16(%2)" 256 [(set_attr "type" "arith")] 257) 258 259(define_insn "*movsi_lo_sum" 260 [(set (match_operand:SI 0 "register_operand" "=r") 261 (lo_sum:SI (match_operand:SI 1 "register_operand" "0") 262 (match_operand:SI 2 "reloc_operand" "i")))] 263 "!flag_pic" 264 "ori %0, %0, lo(%2)" 265 [(set_attr "type" "arith")] 266) 267 268(define_insn "*movqi_insn" 269 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,m,r") 270 (match_operand:QI 1 "general_operand" "m,r,r,J,n"))] 271 "lm32_move_ok (QImode, operands)" 272 "@ 273 lbu %0, %1 274 or %0, %1, r0 275 sb %0, %1 276 sb %0, r0 277 addi %0, r0, %1" 278 [(set_attr "type" "load,arith,store,store,arith")] 279) 280 281(define_insn "*movhi_insn" 282 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,m,r,r") 283 (match_operand:HI 1 "general_operand" "m,r,r,J,K,L"))] 284 "lm32_move_ok (HImode, operands)" 285 "@ 286 lhu %0, %1 287 or %0, %1, r0 288 sh %0, %1 289 sh %0, r0 290 addi %0, r0, %1 291 ori %0, r0, %1" 292 [(set_attr "type" "load,arith,store,store,arith,arith")] 293) 294 295(define_insn "movsi_insn" 296 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m,m,r,r,r,r,r,r") 297 (match_operand:SI 1 "general_operand" "m,r,r,J,K,L,U,S,Y,n"))] 298 "lm32_move_ok (SImode, operands)" 299 "@ 300 lw %0, %1 301 or %0, %1, r0 302 sw %0, %1 303 sw %0, r0 304 addi %0, r0, %1 305 ori %0, r0, %1 306 orhi %0, r0, hi(%1) 307 mva %0, gp(%1) 308 orhi %0, r0, hi(%1) 309 ori %0, r0, lo(%1); orhi %0, %0, hi(%1)" 310 [(set_attr "type" "load,arith,store,store,arith,arith,arith,arith,arith,arith")] 311) 312 313;; --------------------------------- 314;; sign and zero extension 315;; --------------------------------- 316 317(define_insn "*extendqihi2" 318 [(set (match_operand:HI 0 "register_operand" "=r,r") 319 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m,r")))] 320 "TARGET_SIGN_EXTEND_ENABLED || (GET_CODE (operands[1]) != REG)" 321 "@ 322 lb %0, %1 323 sextb %0, %1" 324 [(set_attr "type" "load,arith")] 325) 326 327(define_insn "zero_extendqihi2" 328 [(set (match_operand:HI 0 "register_operand" "=r,r") 329 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m,r")))] 330 "" 331 "@ 332 lbu %0, %1 333 andi %0, %1, 0xff" 334 [(set_attr "type" "load,arith")] 335) 336 337(define_insn "*extendqisi2" 338 [(set (match_operand:SI 0 "register_operand" "=r,r") 339 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "m,r")))] 340 "TARGET_SIGN_EXTEND_ENABLED || (GET_CODE (operands[1]) != REG)" 341 "@ 342 lb %0, %1 343 sextb %0, %1" 344 [(set_attr "type" "load,arith")] 345) 346 347(define_insn "zero_extendqisi2" 348 [(set (match_operand:SI 0 "register_operand" "=r,r") 349 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "m,r")))] 350 "" 351 "@ 352 lbu %0, %1 353 andi %0, %1, 0xff" 354 [(set_attr "type" "load,arith")] 355) 356 357(define_insn "*extendhisi2" 358 [(set (match_operand:SI 0 "register_operand" "=r,r") 359 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "m,r")))] 360 "TARGET_SIGN_EXTEND_ENABLED || (GET_CODE (operands[1]) != REG)" 361 "@ 362 lh %0, %1 363 sexth %0, %1" 364 [(set_attr "type" "load,arith")] 365) 366 367(define_insn "zero_extendhisi2" 368 [(set (match_operand:SI 0 "register_operand" "=r,r") 369 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "m,r")))] 370 "" 371 "@ 372 lhu %0, %1 373 andi %0, %1, 0xffff" 374 [(set_attr "type" "load,arith")] 375) 376 377;; --------------------------------- 378;; compare 379;; --------------------------------- 380 381(define_expand "cstoresi4" 382 [(set (match_operand:SI 0 "register_operand") 383 (match_operator:SI 1 "ordered_comparison_operator" 384 [(match_operand:SI 2 "register_operand") 385 (match_operand:SI 3 "register_or_int_operand")]))] 386 "" 387{ 388 lm32_expand_scc (operands); 389 DONE; 390}) 391 392(define_insn "*seq" 393 [(set (match_operand:SI 0 "register_operand" "=r,r") 394 (eq:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ") 395 (match_operand:SI 2 "register_or_K_operand" "r,K")))] 396 "" 397 "@ 398 cmpe %0, %z1, %2 399 cmpei %0, %z1, %2" 400 [(set_attr "type" "compare")] 401) 402 403(define_insn "*sne" 404 [(set (match_operand:SI 0 "register_operand" "=r,r") 405 (ne:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ") 406 (match_operand:SI 2 "register_or_K_operand" "r,K")))] 407 "" 408 "@ 409 cmpne %0, %z1, %2 410 cmpnei %0, %z1, %2" 411 [(set_attr "type" "compare")] 412) 413 414(define_insn "*sgt" 415 [(set (match_operand:SI 0 "register_operand" "=r,r") 416 (gt:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ") 417 (match_operand:SI 2 "register_or_K_operand" "r,K")))] 418 "" 419 "@ 420 cmpg %0, %z1, %2 421 cmpgi %0, %z1, %2" 422 [(set_attr "type" "compare")] 423) 424 425(define_insn "*sge" 426 [(set (match_operand:SI 0 "register_operand" "=r,r") 427 (ge:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ") 428 (match_operand:SI 2 "register_or_K_operand" "r,K")))] 429 "" 430 "@ 431 cmpge %0, %z1, %2 432 cmpgei %0, %z1, %2" 433 [(set_attr "type" "compare")] 434) 435 436(define_insn "*sgtu" 437 [(set (match_operand:SI 0 "register_operand" "=r,r") 438 (gtu:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ") 439 (match_operand:SI 2 "register_or_L_operand" "r,L")))] 440 "" 441 "@ 442 cmpgu %0, %z1, %2 443 cmpgui %0, %z1, %2" 444 [(set_attr "type" "compare")] 445) 446 447(define_insn "*sgeu" 448 [(set (match_operand:SI 0 "register_operand" "=r,r") 449 (geu:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ") 450 (match_operand:SI 2 "register_or_L_operand" "r,L")))] 451 "" 452 "@ 453 cmpgeu %0, %z1, %2 454 cmpgeui %0, %z1, %2" 455 [(set_attr "type" "compare")] 456) 457 458;; --------------------------------- 459;; unconditional branch 460;; --------------------------------- 461 462(define_insn "jump" 463 [(set (pc) (label_ref (match_operand 0 "" "")))] 464 "" 465 "bi %0" 466 [(set_attr "type" "ubranch")] 467) 468 469(define_insn "indirect_jump" 470 [(set (pc) (match_operand:SI 0 "register_operand" "r"))] 471 "" 472 "b %0" 473 [(set_attr "type" "uibranch")] 474) 475 476;; --------------------------------- 477;; conditional branch 478;; --------------------------------- 479 480(define_expand "cbranchsi4" 481 [(set (pc) 482 (if_then_else (match_operator 0 "comparison_operator" 483 [(match_operand:SI 1 "register_operand") 484 (match_operand:SI 2 "nonmemory_operand")]) 485 (label_ref (match_operand 3 "" "")) 486 (pc)))] 487 "" 488 " 489{ 490 lm32_expand_conditional_branch (operands); 491 DONE; 492}") 493 494(define_insn "*beq" 495 [(set (pc) 496 (if_then_else (eq:SI (match_operand:SI 0 "register_or_zero_operand" "rJ") 497 (match_operand:SI 1 "register_or_zero_operand" "rJ")) 498 (label_ref (match_operand 2 "" "")) 499 (pc)))] 500 "" 501{ 502 return get_attr_length (insn) == 4 503 ? "be %z0,%z1,%2" 504 : "bne %z0,%z1,8\n\tbi %2"; 505} 506 [(set_attr "type" "cbranch")]) 507 508(define_insn "*bne" 509 [(set (pc) 510 (if_then_else (ne:SI (match_operand:SI 0 "register_or_zero_operand" "rJ") 511 (match_operand:SI 1 "register_or_zero_operand" "rJ")) 512 (label_ref (match_operand 2 "" "")) 513 (pc)))] 514 "" 515{ 516 return get_attr_length (insn) == 4 517 ? "bne %z0,%z1,%2" 518 : "be %z0,%z1,8\n\tbi %2"; 519} 520 [(set_attr "type" "cbranch")]) 521 522(define_insn "*bgt" 523 [(set (pc) 524 (if_then_else (gt:SI (match_operand:SI 0 "register_or_zero_operand" "rJ") 525 (match_operand:SI 1 "register_or_zero_operand" "rJ")) 526 (label_ref (match_operand 2 "" "")) 527 (pc)))] 528 "" 529{ 530 return get_attr_length (insn) == 4 531 ? "bg %z0,%z1,%2" 532 : "bge %z1,%z0,8\n\tbi %2"; 533} 534 [(set_attr "type" "cbranch")]) 535 536(define_insn "*bge" 537 [(set (pc) 538 (if_then_else (ge:SI (match_operand:SI 0 "register_or_zero_operand" "rJ") 539 (match_operand:SI 1 "register_or_zero_operand" "rJ")) 540 (label_ref (match_operand 2 "" "")) 541 (pc)))] 542 "" 543{ 544 return get_attr_length (insn) == 4 545 ? "bge %z0,%z1,%2" 546 : "bg %z1,%z0,8\n\tbi %2"; 547} 548 [(set_attr "type" "cbranch")]) 549 550(define_insn "*bgtu" 551 [(set (pc) 552 (if_then_else (gtu:SI (match_operand:SI 0 "register_or_zero_operand" "rJ") 553 (match_operand:SI 1 "register_or_zero_operand" "rJ")) 554 (label_ref (match_operand 2 "" "")) 555 (pc)))] 556 "" 557{ 558 return get_attr_length (insn) == 4 559 ? "bgu %z0,%z1,%2" 560 : "bgeu %z1,%z0,8\n\tbi %2"; 561} 562 [(set_attr "type" "cbranch")]) 563 564(define_insn "*bgeu" 565 [(set (pc) 566 (if_then_else (geu:SI (match_operand:SI 0 "register_or_zero_operand" "rJ") 567 (match_operand:SI 1 "register_or_zero_operand" "rJ")) 568 (label_ref (match_operand 2 "" "")) 569 (pc)))] 570 "" 571{ 572 return get_attr_length (insn) == 4 573 ? "bgeu %z0,%z1,%2" 574 : "bgu %z1,%z0,8\n\tbi %2"; 575} 576 [(set_attr "type" "cbranch")]) 577 578;; --------------------------------- 579;; call 580;; --------------------------------- 581 582(define_expand "call" 583 [(parallel [(call (match_operand 0 "" "") 584 (match_operand 1 "" "")) 585 (clobber (reg:SI RA_REGNUM)) 586 ])] 587 "" 588 " 589{ 590 rtx addr = XEXP (operands[0], 0); 591 if (!CONSTANT_ADDRESS_P (addr)) 592 XEXP (operands[0], 0) = force_reg (Pmode, addr); 593}") 594 595(define_insn "*call" 596 [(call (mem:SI (match_operand:SI 0 "call_operand" "r,s")) 597 (match_operand 1 "" "")) 598 (clobber (reg:SI RA_REGNUM))] 599 "" 600 "@ 601 call %0 602 calli %0" 603 [(set_attr "type" "call,icall")] 604) 605 606(define_expand "call_value" 607 [(parallel [(set (match_operand 0 "" "") 608 (call (match_operand 1 "" "") 609 (match_operand 2 "" ""))) 610 (clobber (reg:SI RA_REGNUM)) 611 ])] 612 "" 613 " 614{ 615 rtx addr = XEXP (operands[1], 0); 616 if (!CONSTANT_ADDRESS_P (addr)) 617 XEXP (operands[1], 0) = force_reg (Pmode, addr); 618}") 619 620(define_insn "*call_value" 621 [(set (match_operand 0 "register_operand" "=r,r") 622 (call (mem:SI (match_operand:SI 1 "call_operand" "r,s")) 623 (match_operand 2 "" ""))) 624 (clobber (reg:SI RA_REGNUM))] 625 "" 626 "@ 627 call %1 628 calli %1" 629 [(set_attr "type" "call,icall")] 630) 631 632(define_insn "return_internal" 633 [(use (match_operand:SI 0 "register_operand" "r")) 634 (return)] 635 "" 636 "b %0" 637 [(set_attr "type" "uibranch")] 638) 639 640(define_expand "return" 641 [(return)] 642 "lm32_can_use_return ()" 643 "" 644) 645 646(define_expand "simple_return" 647 [(simple_return)] 648 "" 649 "" 650) 651 652(define_insn "*return" 653 [(return)] 654 "reload_completed" 655 "ret" 656 [(set_attr "type" "uibranch")] 657) 658 659(define_insn "*simple_return" 660 [(simple_return)] 661 "" 662 "ret" 663 [(set_attr "type" "uibranch")] 664) 665 666;; --------------------------------- 667;; switch/case statements 668;; --------------------------------- 669 670(define_expand "tablejump" 671 [(set (pc) (match_operand 0 "register_operand" "")) 672 (use (label_ref (match_operand 1 "" "")))] 673 "" 674 " 675{ 676 rtx target = operands[0]; 677 if (flag_pic) 678 { 679 /* For PIC, the table entry is relative to the start of the table. */ 680 rtx label = gen_reg_rtx (SImode); 681 target = gen_reg_rtx (SImode); 682 emit_move_insn (label, gen_rtx_LABEL_REF (SImode, operands[1])); 683 emit_insn (gen_addsi3 (target, operands[0], label)); 684 } 685 emit_jump_insn (gen_tablejumpsi (target, operands[1])); 686 DONE; 687}") 688 689(define_insn "tablejumpsi" 690 [(set (pc) (match_operand:SI 0 "register_operand" "r")) 691 (use (label_ref (match_operand 1 "" "")))] 692 "" 693 "b %0" 694 [(set_attr "type" "ubranch")] 695) 696 697;; --------------------------------- 698;; arithmetic 699;; --------------------------------- 700 701(define_insn "addsi3" 702 [(set (match_operand:SI 0 "register_operand" "=r,r") 703 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ") 704 (match_operand:SI 2 "register_or_K_operand" "r,K")))] 705 "" 706 "@ 707 add %0, %z1, %2 708 addi %0, %z1, %2" 709 [(set_attr "type" "arith")] 710) 711 712(define_insn "subsi3" 713 [(set (match_operand:SI 0 "register_operand" "=r") 714 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") 715 (match_operand:SI 2 "register_or_zero_operand" "rJ")))] 716 "" 717 "sub %0, %z1, %z2" 718 [(set_attr "type" "arith")] 719) 720 721(define_insn "mulsi3" 722 [(set (match_operand:SI 0 "register_operand" "=r,r") 723 (mult:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ") 724 (match_operand:SI 2 "register_or_K_operand" "r,K")))] 725 "TARGET_MULTIPLY_ENABLED" 726 "@ 727 mul %0, %z1, %2 728 muli %0, %z1, %2" 729 [(set_attr "type" "multiply")] 730) 731 732(define_insn "udivsi3" 733 [(set (match_operand:SI 0 "register_operand" "=r") 734 (udiv:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") 735 (match_operand:SI 2 "register_operand" "r")))] 736 "TARGET_DIVIDE_ENABLED" 737 "divu %0, %z1, %2" 738 [(set_attr "type" "divide")] 739) 740 741(define_insn "umodsi3" 742 [(set (match_operand:SI 0 "register_operand" "=r") 743 (umod:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") 744 (match_operand:SI 2 "register_operand" "r")))] 745 "TARGET_DIVIDE_ENABLED" 746 "modu %0, %z1, %2" 747 [(set_attr "type" "divide")] 748) 749 750;; --------------------------------- 751;; negation and inversion 752;; --------------------------------- 753 754(define_insn "negsi2" 755 [(set (match_operand:SI 0 "register_operand" "=r") 756 (neg:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")))] 757 "" 758 "sub %0, r0, %z1" 759 [(set_attr "type" "arith")] 760) 761 762(define_insn "one_cmplsi2" 763 [(set (match_operand:SI 0 "register_operand" "=r") 764 (not:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")))] 765 "" 766 "not %0, %z1" 767 [(set_attr "type" "arith")] 768) 769 770;; --------------------------------- 771;; logical 772;; --------------------------------- 773 774(define_insn "andsi3" 775 [(set (match_operand:SI 0 "register_operand" "=r,r") 776 (and:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ") 777 (match_operand:SI 2 "register_or_L_operand" "r,L")))] 778 "" 779 "@ 780 and %0, %z1, %2 781 andi %0, %z1, %2" 782 [(set_attr "type" "arith")] 783) 784 785(define_insn "iorsi3" 786 [(set (match_operand:SI 0 "register_operand" "=r,r") 787 (ior:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ") 788 (match_operand:SI 2 "register_or_L_operand" "r,L")))] 789 "" 790 "@ 791 or %0, %z1, %2 792 ori %0, %z1, %2" 793 [(set_attr "type" "arith")] 794) 795 796(define_insn "xorsi3" 797 [(set (match_operand:SI 0 "register_operand" "=r,r") 798 (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ") 799 (match_operand:SI 2 "register_or_L_operand" "r,L")))] 800 "" 801 "@ 802 xor %0, %z1, %2 803 xori %0, %z1, %2" 804 [(set_attr "type" "arith")] 805) 806 807(define_insn "*norsi3" 808 [(set (match_operand:SI 0 "register_operand" "=r,r") 809 (not:SI (ior:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ") 810 (match_operand:SI 2 "register_or_L_operand" "r,L"))))] 811 "" 812 "@ 813 nor %0, %z1, %2 814 nori %0, %z1, %2" 815 [(set_attr "type" "arith")] 816) 817 818(define_insn "*xnorsi3" 819 [(set (match_operand:SI 0 "register_operand" "=r,r") 820 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ") 821 (match_operand:SI 2 "register_or_L_operand" "r,L"))))] 822 "" 823 "@ 824 xnor %0, %z1, %2 825 xnori %0, %z1, %2" 826 [(set_attr "type" "arith")] 827) 828 829;; --------------------------------- 830;; shifts 831;; --------------------------------- 832 833(define_expand "ashlsi3" 834 [(set (match_operand:SI 0 "register_operand" "") 835 (ashift:SI (match_operand:SI 1 "register_or_zero_operand" "") 836 (match_operand:SI 2 "register_or_L_operand" "")))] 837 "" 838{ 839 if (!TARGET_BARREL_SHIFT_ENABLED) 840 { 841 if (!optimize_size 842 && satisfies_constraint_L (operands[2]) 843 && INTVAL (operands[2]) <= 8) 844 { 845 int i; 846 int shifts = INTVAL (operands[2]); 847 848 if (shifts == 0) 849 emit_move_insn (operands[0], operands[1]); 850 else 851 emit_insn (gen_addsi3 (operands[0], operands[1], operands[1])); 852 for (i = 1; i < shifts; i++) 853 emit_insn (gen_addsi3 (operands[0], operands[0], operands[0])); 854 DONE; 855 } 856 else 857 FAIL; 858 } 859}) 860 861(define_insn "*ashlsi3" 862 [(set (match_operand:SI 0 "register_operand" "=r,r") 863 (ashift:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ") 864 (match_operand:SI 2 "register_or_L_operand" "r,L")))] 865 "TARGET_BARREL_SHIFT_ENABLED" 866 "@ 867 sl %0, %z1, %2 868 sli %0, %z1, %2" 869 [(set_attr "type" "shift")] 870) 871 872(define_expand "ashrsi3" 873 [(set (match_operand:SI 0 "register_operand" "") 874 (ashiftrt:SI (match_operand:SI 1 "register_or_zero_operand" "") 875 (match_operand:SI 2 "register_or_L_operand" "")))] 876 "" 877{ 878 if (!TARGET_BARREL_SHIFT_ENABLED) 879 { 880 if (!optimize_size 881 && satisfies_constraint_L (operands[2]) 882 && INTVAL (operands[2]) <= 8) 883 { 884 int i; 885 int shifts = INTVAL (operands[2]); 886 rtx one = GEN_INT (1); 887 888 if (shifts == 0) 889 emit_move_insn (operands[0], operands[1]); 890 else 891 emit_insn (gen_ashrsi3_1bit (operands[0], operands[1], one)); 892 for (i = 1; i < shifts; i++) 893 emit_insn (gen_ashrsi3_1bit (operands[0], operands[0], one)); 894 DONE; 895 } 896 else 897 FAIL; 898 } 899}) 900 901(define_insn "*ashrsi3" 902 [(set (match_operand:SI 0 "register_operand" "=r,r") 903 (ashiftrt:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ") 904 (match_operand:SI 2 "register_or_L_operand" "r,L")))] 905 "TARGET_BARREL_SHIFT_ENABLED" 906 "@ 907 sr %0, %z1, %2 908 sri %0, %z1, %2" 909 [(set_attr "type" "shift")] 910) 911 912(define_insn "ashrsi3_1bit" 913 [(set (match_operand:SI 0 "register_operand" "=r") 914 (ashiftrt:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") 915 (match_operand:SI 2 "constant_M_operand" "M")))] 916 "!TARGET_BARREL_SHIFT_ENABLED" 917 "sri %0, %z1, %2" 918 [(set_attr "type" "shift")] 919) 920 921(define_expand "lshrsi3" 922 [(set (match_operand:SI 0 "register_operand" "") 923 (lshiftrt:SI (match_operand:SI 1 "register_or_zero_operand" "") 924 (match_operand:SI 2 "register_or_L_operand" "")))] 925 "" 926{ 927 if (!TARGET_BARREL_SHIFT_ENABLED) 928 { 929 if (!optimize_size 930 && satisfies_constraint_L (operands[2]) 931 && INTVAL (operands[2]) <= 8) 932 { 933 int i; 934 int shifts = INTVAL (operands[2]); 935 rtx one = GEN_INT (1); 936 937 if (shifts == 0) 938 emit_move_insn (operands[0], operands[1]); 939 else 940 emit_insn (gen_lshrsi3_1bit (operands[0], operands[1], one)); 941 for (i = 1; i < shifts; i++) 942 emit_insn (gen_lshrsi3_1bit (operands[0], operands[0], one)); 943 DONE; 944 } 945 else 946 FAIL; 947 } 948}) 949 950(define_insn "*lshrsi3" 951 [(set (match_operand:SI 0 "register_operand" "=r,r") 952 (lshiftrt:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ") 953 (match_operand:SI 2 "register_or_L_operand" "r,L")))] 954 "TARGET_BARREL_SHIFT_ENABLED" 955 "@ 956 sru %0, %z1, %2 957 srui %0, %z1, %2" 958 [(set_attr "type" "shift")] 959) 960 961(define_insn "lshrsi3_1bit" 962 [(set (match_operand:SI 0 "register_operand" "=r") 963 (lshiftrt:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") 964 (match_operand:SI 2 "constant_M_operand" "M")))] 965 "!TARGET_BARREL_SHIFT_ENABLED" 966 "srui %0, %z1, %2" 967 [(set_attr "type" "shift")] 968) 969 970;; --------------------------------- 971;; function entry / exit 972;; --------------------------------- 973 974(define_expand "prologue" 975 [(const_int 1)] 976 "" 977 " 978{ 979 lm32_expand_prologue (); 980 DONE; 981}") 982 983(define_expand "epilogue" 984 [(return)] 985 "" 986 " 987{ 988 lm32_expand_epilogue (); 989 DONE; 990}") 991 992;; --------------------------------- 993;; nop 994;; --------------------------------- 995 996(define_insn "nop" 997 [(const_int 0)] 998 "" 999 "nop" 1000 [(set_attr "type" "arith")] 1001) 1002 1003;; --------------------------------- 1004;; blockage 1005;; --------------------------------- 1006 1007;; used to stop the scheduler from 1008;; scheduling code across certain boundaries 1009 1010(define_insn "blockage" 1011 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)] 1012 "" 1013 "" 1014 [(set_attr "length" "0")] 1015) 1016