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-2022 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 (operands[0], gen_rtx_HIGH (SImode, operands[1]))); 199 emit_insn (gen_rtx_SET (operands[0], gen_rtx_LO_SUM (SImode, operands[0], 200 operands[1]))); 201 DONE; 202 } 203 else if (GET_CODE (operands[1]) == CONST_INT) 204 { 205 if (!(satisfies_constraint_K (operands[1]) 206 || satisfies_constraint_L (operands[1]) 207 || satisfies_constraint_U (operands[1]))) 208 { 209 emit_insn (gen_movsi_insn (operands[0], 210 GEN_INT (INTVAL (operands[1]) & ~0xffff))); 211 emit_insn (gen_iorsi3 (operands[0], 212 operands[0], 213 GEN_INT (INTVAL (operands[1]) & 0xffff))); 214 DONE; 215 } 216 } 217}") 218 219(define_expand "cpymemsi" 220 [(parallel [(set (match_operand:BLK 0 "general_operand" "") 221 (match_operand:BLK 1 "general_operand" "")) 222 (use (match_operand:SI 2 "" "")) 223 (use (match_operand:SI 3 "const_int_operand" ""))])] 224 "" 225{ 226 if (!lm32_expand_block_move (operands)) 227 FAIL; 228 DONE; 229}) 230 231;; --------------------------------- 232;; load/stores/moves 233;; --------------------------------- 234 235(define_insn "movsi_got" 236 [(set (match_operand:SI 0 "register_operand" "=r") 237 (unspec:SI [(match_operand 1 "" "")] UNSPEC_GOT))] 238 "flag_pic" 239 "lw %0, (gp+got(%1))" 240 [(set_attr "type" "load")] 241) 242 243(define_insn "movsi_gotoff_hi16" 244 [(set (match_operand:SI 0 "register_operand" "=r") 245 (unspec:SI [(match_operand 1 "" "")] UNSPEC_GOTOFF_HI16))] 246 "flag_pic" 247 "orhi %0, r0, gotoffhi16(%1)" 248 [(set_attr "type" "load")] 249) 250 251(define_insn "movsi_gotoff_lo16" 252 [(set (match_operand:SI 0 "register_operand" "=r") 253 (unspec:SI [(plus:SI (match_operand:SI 1 "register_operand" "0") 254 (match_operand 2 "" ""))] UNSPEC_GOTOFF_LO16))] 255 "flag_pic" 256 "addi %0, %1, gotofflo16(%2)" 257 [(set_attr "type" "arith")] 258) 259 260(define_insn "*movsi_lo_sum" 261 [(set (match_operand:SI 0 "register_operand" "=r") 262 (lo_sum:SI (match_operand:SI 1 "register_operand" "0") 263 (match_operand:SI 2 "reloc_operand" "i")))] 264 "!flag_pic" 265 "ori %0, %0, lo(%2)" 266 [(set_attr "type" "arith")] 267) 268 269(define_insn "*movqi_insn" 270 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,m,r") 271 (match_operand:QI 1 "general_operand" "m,r,r,J,n"))] 272 "lm32_move_ok (QImode, operands)" 273 "@ 274 lbu %0, %1 275 or %0, %1, r0 276 sb %0, %1 277 sb %0, r0 278 addi %0, r0, %1" 279 [(set_attr "type" "load,arith,store,store,arith")] 280) 281 282(define_insn "*movhi_insn" 283 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,m,r,r") 284 (match_operand:HI 1 "general_operand" "m,r,r,J,K,L"))] 285 "lm32_move_ok (HImode, operands)" 286 "@ 287 lhu %0, %1 288 or %0, %1, r0 289 sh %0, %1 290 sh %0, r0 291 addi %0, r0, %1 292 ori %0, r0, %1" 293 [(set_attr "type" "load,arith,store,store,arith,arith")] 294) 295 296(define_insn "movsi_insn" 297 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m,m,r,r,r,r,r,r") 298 (match_operand:SI 1 "general_operand" "m,r,r,J,K,L,U,S,Y,n"))] 299 "lm32_move_ok (SImode, operands)" 300 "@ 301 lw %0, %1 302 or %0, %1, r0 303 sw %0, %1 304 sw %0, r0 305 addi %0, r0, %1 306 ori %0, r0, %1 307 orhi %0, r0, hi(%1) 308 mva %0, gp(%1) 309 orhi %0, r0, hi(%1) 310 ori %0, r0, lo(%1); orhi %0, %0, hi(%1)" 311 [(set_attr "type" "load,arith,store,store,arith,arith,arith,arith,arith,arith")] 312) 313 314;; --------------------------------- 315;; sign and zero extension 316;; --------------------------------- 317 318(define_insn "*extendqihi2" 319 [(set (match_operand:HI 0 "register_operand" "=r,r") 320 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m,r")))] 321 "TARGET_SIGN_EXTEND_ENABLED || (GET_CODE (operands[1]) != REG)" 322 "@ 323 lb %0, %1 324 sextb %0, %1" 325 [(set_attr "type" "load,arith")] 326) 327 328(define_insn "zero_extendqihi2" 329 [(set (match_operand:HI 0 "register_operand" "=r,r") 330 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m,r")))] 331 "" 332 "@ 333 lbu %0, %1 334 andi %0, %1, 0xff" 335 [(set_attr "type" "load,arith")] 336) 337 338(define_insn "*extendqisi2" 339 [(set (match_operand:SI 0 "register_operand" "=r,r") 340 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "m,r")))] 341 "TARGET_SIGN_EXTEND_ENABLED || (GET_CODE (operands[1]) != REG)" 342 "@ 343 lb %0, %1 344 sextb %0, %1" 345 [(set_attr "type" "load,arith")] 346) 347 348(define_insn "zero_extendqisi2" 349 [(set (match_operand:SI 0 "register_operand" "=r,r") 350 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "m,r")))] 351 "" 352 "@ 353 lbu %0, %1 354 andi %0, %1, 0xff" 355 [(set_attr "type" "load,arith")] 356) 357 358(define_insn "*extendhisi2" 359 [(set (match_operand:SI 0 "register_operand" "=r,r") 360 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "m,r")))] 361 "TARGET_SIGN_EXTEND_ENABLED || (GET_CODE (operands[1]) != REG)" 362 "@ 363 lh %0, %1 364 sexth %0, %1" 365 [(set_attr "type" "load,arith")] 366) 367 368(define_insn "zero_extendhisi2" 369 [(set (match_operand:SI 0 "register_operand" "=r,r") 370 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "m,r")))] 371 "" 372 "@ 373 lhu %0, %1 374 andi %0, %1, 0xffff" 375 [(set_attr "type" "load,arith")] 376) 377 378;; --------------------------------- 379;; compare 380;; --------------------------------- 381 382(define_expand "cstoresi4" 383 [(set (match_operand:SI 0 "register_operand") 384 (match_operator:SI 1 "ordered_comparison_operator" 385 [(match_operand:SI 2 "register_operand") 386 (match_operand:SI 3 "register_or_int_operand")]))] 387 "" 388{ 389 lm32_expand_scc (operands); 390 DONE; 391}) 392 393(define_insn "*seq" 394 [(set (match_operand:SI 0 "register_operand" "=r,r") 395 (eq:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ") 396 (match_operand:SI 2 "register_or_K_operand" "r,K")))] 397 "" 398 "@ 399 cmpe %0, %z1, %2 400 cmpei %0, %z1, %2" 401 [(set_attr "type" "compare")] 402) 403 404(define_insn "*sne" 405 [(set (match_operand:SI 0 "register_operand" "=r,r") 406 (ne:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ") 407 (match_operand:SI 2 "register_or_K_operand" "r,K")))] 408 "" 409 "@ 410 cmpne %0, %z1, %2 411 cmpnei %0, %z1, %2" 412 [(set_attr "type" "compare")] 413) 414 415(define_insn "*sgt" 416 [(set (match_operand:SI 0 "register_operand" "=r,r") 417 (gt:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ") 418 (match_operand:SI 2 "register_or_K_operand" "r,K")))] 419 "" 420 "@ 421 cmpg %0, %z1, %2 422 cmpgi %0, %z1, %2" 423 [(set_attr "type" "compare")] 424) 425 426(define_insn "*sge" 427 [(set (match_operand:SI 0 "register_operand" "=r,r") 428 (ge:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ") 429 (match_operand:SI 2 "register_or_K_operand" "r,K")))] 430 "" 431 "@ 432 cmpge %0, %z1, %2 433 cmpgei %0, %z1, %2" 434 [(set_attr "type" "compare")] 435) 436 437(define_insn "*sgtu" 438 [(set (match_operand:SI 0 "register_operand" "=r,r") 439 (gtu:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ") 440 (match_operand:SI 2 "register_or_L_operand" "r,L")))] 441 "" 442 "@ 443 cmpgu %0, %z1, %2 444 cmpgui %0, %z1, %2" 445 [(set_attr "type" "compare")] 446) 447 448(define_insn "*sgeu" 449 [(set (match_operand:SI 0 "register_operand" "=r,r") 450 (geu:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ") 451 (match_operand:SI 2 "register_or_L_operand" "r,L")))] 452 "" 453 "@ 454 cmpgeu %0, %z1, %2 455 cmpgeui %0, %z1, %2" 456 [(set_attr "type" "compare")] 457) 458 459;; --------------------------------- 460;; unconditional branch 461;; --------------------------------- 462 463(define_insn "jump" 464 [(set (pc) (label_ref (match_operand 0 "" "")))] 465 "" 466 "bi %0" 467 [(set_attr "type" "ubranch")] 468) 469 470(define_insn "indirect_jump" 471 [(set (pc) (match_operand:SI 0 "register_operand" "r"))] 472 "" 473 "b %0" 474 [(set_attr "type" "uibranch")] 475) 476 477;; --------------------------------- 478;; conditional branch 479;; --------------------------------- 480 481(define_expand "cbranchsi4" 482 [(set (pc) 483 (if_then_else (match_operator 0 "comparison_operator" 484 [(match_operand:SI 1 "register_operand") 485 (match_operand:SI 2 "nonmemory_operand")]) 486 (label_ref (match_operand 3 "" "")) 487 (pc)))] 488 "" 489 " 490{ 491 lm32_expand_conditional_branch (operands); 492 DONE; 493}") 494 495(define_insn "*beq" 496 [(set (pc) 497 (if_then_else (eq:SI (match_operand:SI 0 "register_or_zero_operand" "rJ") 498 (match_operand:SI 1 "register_or_zero_operand" "rJ")) 499 (label_ref (match_operand 2 "" "")) 500 (pc)))] 501 "" 502{ 503 return get_attr_length (insn) == 4 504 ? "be %z0,%z1,%2" 505 : "bne %z0,%z1,8\n\tbi %2"; 506} 507 [(set_attr "type" "cbranch")]) 508 509(define_insn "*bne" 510 [(set (pc) 511 (if_then_else (ne:SI (match_operand:SI 0 "register_or_zero_operand" "rJ") 512 (match_operand:SI 1 "register_or_zero_operand" "rJ")) 513 (label_ref (match_operand 2 "" "")) 514 (pc)))] 515 "" 516{ 517 return get_attr_length (insn) == 4 518 ? "bne %z0,%z1,%2" 519 : "be %z0,%z1,8\n\tbi %2"; 520} 521 [(set_attr "type" "cbranch")]) 522 523(define_insn "*bgt" 524 [(set (pc) 525 (if_then_else (gt:SI (match_operand:SI 0 "register_or_zero_operand" "rJ") 526 (match_operand:SI 1 "register_or_zero_operand" "rJ")) 527 (label_ref (match_operand 2 "" "")) 528 (pc)))] 529 "" 530{ 531 return get_attr_length (insn) == 4 532 ? "bg %z0,%z1,%2" 533 : "bge %z1,%z0,8\n\tbi %2"; 534} 535 [(set_attr "type" "cbranch")]) 536 537(define_insn "*bge" 538 [(set (pc) 539 (if_then_else (ge:SI (match_operand:SI 0 "register_or_zero_operand" "rJ") 540 (match_operand:SI 1 "register_or_zero_operand" "rJ")) 541 (label_ref (match_operand 2 "" "")) 542 (pc)))] 543 "" 544{ 545 return get_attr_length (insn) == 4 546 ? "bge %z0,%z1,%2" 547 : "bg %z1,%z0,8\n\tbi %2"; 548} 549 [(set_attr "type" "cbranch")]) 550 551(define_insn "*bgtu" 552 [(set (pc) 553 (if_then_else (gtu:SI (match_operand:SI 0 "register_or_zero_operand" "rJ") 554 (match_operand:SI 1 "register_or_zero_operand" "rJ")) 555 (label_ref (match_operand 2 "" "")) 556 (pc)))] 557 "" 558{ 559 return get_attr_length (insn) == 4 560 ? "bgu %z0,%z1,%2" 561 : "bgeu %z1,%z0,8\n\tbi %2"; 562} 563 [(set_attr "type" "cbranch")]) 564 565(define_insn "*bgeu" 566 [(set (pc) 567 (if_then_else (geu:SI (match_operand:SI 0 "register_or_zero_operand" "rJ") 568 (match_operand:SI 1 "register_or_zero_operand" "rJ")) 569 (label_ref (match_operand 2 "" "")) 570 (pc)))] 571 "" 572{ 573 return get_attr_length (insn) == 4 574 ? "bgeu %z0,%z1,%2" 575 : "bgu %z1,%z0,8\n\tbi %2"; 576} 577 [(set_attr "type" "cbranch")]) 578 579;; --------------------------------- 580;; call 581;; --------------------------------- 582 583(define_expand "call" 584 [(parallel [(call (match_operand 0 "" "") 585 (match_operand 1 "" "")) 586 (clobber (reg:SI RA_REGNUM)) 587 ])] 588 "" 589 " 590{ 591 rtx addr = XEXP (operands[0], 0); 592 if (!CONSTANT_ADDRESS_P (addr)) 593 XEXP (operands[0], 0) = force_reg (Pmode, addr); 594}") 595 596(define_insn "*call" 597 [(call (mem:SI (match_operand:SI 0 "call_operand" "r,s")) 598 (match_operand 1 "" "")) 599 (clobber (reg:SI RA_REGNUM))] 600 "" 601 "@ 602 call %0 603 calli %0" 604 [(set_attr "type" "call,icall")] 605) 606 607(define_expand "call_value" 608 [(parallel [(set (match_operand 0 "" "") 609 (call (match_operand 1 "" "") 610 (match_operand 2 "" ""))) 611 (clobber (reg:SI RA_REGNUM)) 612 ])] 613 "" 614 " 615{ 616 rtx addr = XEXP (operands[1], 0); 617 if (!CONSTANT_ADDRESS_P (addr)) 618 XEXP (operands[1], 0) = force_reg (Pmode, addr); 619}") 620 621(define_insn "*call_value" 622 [(set (match_operand 0 "register_operand" "=r,r") 623 (call (mem:SI (match_operand:SI 1 "call_operand" "r,s")) 624 (match_operand 2 "" ""))) 625 (clobber (reg:SI RA_REGNUM))] 626 "" 627 "@ 628 call %1 629 calli %1" 630 [(set_attr "type" "call,icall")] 631) 632 633(define_insn "return_internal" 634 [(use (match_operand:SI 0 "register_operand" "r")) 635 (return)] 636 "" 637 "b %0" 638 [(set_attr "type" "uibranch")] 639) 640 641(define_expand "return" 642 [(return)] 643 "lm32_can_use_return ()" 644 "" 645) 646 647(define_expand "simple_return" 648 [(simple_return)] 649 "" 650 "" 651) 652 653(define_insn "*return" 654 [(return)] 655 "reload_completed" 656 "ret" 657 [(set_attr "type" "uibranch")] 658) 659 660(define_insn "*simple_return" 661 [(simple_return)] 662 "" 663 "ret" 664 [(set_attr "type" "uibranch")] 665) 666 667;; --------------------------------- 668;; switch/case statements 669;; --------------------------------- 670 671(define_expand "tablejump" 672 [(set (pc) (match_operand 0 "register_operand" "")) 673 (use (label_ref (match_operand 1 "" "")))] 674 "" 675 " 676{ 677 rtx target = operands[0]; 678 if (flag_pic) 679 { 680 /* For PIC, the table entry is relative to the start of the table. */ 681 rtx label = gen_reg_rtx (SImode); 682 target = gen_reg_rtx (SImode); 683 emit_move_insn (label, gen_rtx_LABEL_REF (SImode, operands[1])); 684 emit_insn (gen_addsi3 (target, operands[0], label)); 685 } 686 emit_jump_insn (gen_tablejumpsi (target, operands[1])); 687 DONE; 688}") 689 690(define_insn "tablejumpsi" 691 [(set (pc) (match_operand:SI 0 "register_operand" "r")) 692 (use (label_ref (match_operand 1 "" "")))] 693 "" 694 "b %0" 695 [(set_attr "type" "ubranch")] 696) 697 698;; --------------------------------- 699;; arithmetic 700;; --------------------------------- 701 702(define_insn "addsi3" 703 [(set (match_operand:SI 0 "register_operand" "=r,r") 704 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ") 705 (match_operand:SI 2 "register_or_K_operand" "r,K")))] 706 "" 707 "@ 708 add %0, %z1, %2 709 addi %0, %z1, %2" 710 [(set_attr "type" "arith")] 711) 712 713(define_insn "subsi3" 714 [(set (match_operand:SI 0 "register_operand" "=r") 715 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") 716 (match_operand:SI 2 "register_or_zero_operand" "rJ")))] 717 "" 718 "sub %0, %z1, %z2" 719 [(set_attr "type" "arith")] 720) 721 722(define_insn "mulsi3" 723 [(set (match_operand:SI 0 "register_operand" "=r,r") 724 (mult:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ") 725 (match_operand:SI 2 "register_or_K_operand" "r,K")))] 726 "TARGET_MULTIPLY_ENABLED" 727 "@ 728 mul %0, %z1, %2 729 muli %0, %z1, %2" 730 [(set_attr "type" "multiply")] 731) 732 733(define_insn "udivsi3" 734 [(set (match_operand:SI 0 "register_operand" "=r") 735 (udiv:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") 736 (match_operand:SI 2 "register_operand" "r")))] 737 "TARGET_DIVIDE_ENABLED" 738 "divu %0, %z1, %2" 739 [(set_attr "type" "divide")] 740) 741 742(define_insn "umodsi3" 743 [(set (match_operand:SI 0 "register_operand" "=r") 744 (umod:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") 745 (match_operand:SI 2 "register_operand" "r")))] 746 "TARGET_DIVIDE_ENABLED" 747 "modu %0, %z1, %2" 748 [(set_attr "type" "divide")] 749) 750 751;; --------------------------------- 752;; negation and inversion 753;; --------------------------------- 754 755(define_insn "negsi2" 756 [(set (match_operand:SI 0 "register_operand" "=r") 757 (neg:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")))] 758 "" 759 "sub %0, r0, %z1" 760 [(set_attr "type" "arith")] 761) 762 763(define_insn "one_cmplsi2" 764 [(set (match_operand:SI 0 "register_operand" "=r") 765 (not:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")))] 766 "" 767 "not %0, %z1" 768 [(set_attr "type" "arith")] 769) 770 771;; --------------------------------- 772;; logical 773;; --------------------------------- 774 775(define_insn "andsi3" 776 [(set (match_operand:SI 0 "register_operand" "=r,r") 777 (and:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ") 778 (match_operand:SI 2 "register_or_L_operand" "r,L")))] 779 "" 780 "@ 781 and %0, %z1, %2 782 andi %0, %z1, %2" 783 [(set_attr "type" "arith")] 784) 785 786(define_insn "iorsi3" 787 [(set (match_operand:SI 0 "register_operand" "=r,r") 788 (ior:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ") 789 (match_operand:SI 2 "register_or_L_operand" "r,L")))] 790 "" 791 "@ 792 or %0, %z1, %2 793 ori %0, %z1, %2" 794 [(set_attr "type" "arith")] 795) 796 797(define_insn "xorsi3" 798 [(set (match_operand:SI 0 "register_operand" "=r,r") 799 (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ") 800 (match_operand:SI 2 "register_or_L_operand" "r,L")))] 801 "" 802 "@ 803 xor %0, %z1, %2 804 xori %0, %z1, %2" 805 [(set_attr "type" "arith")] 806) 807 808(define_insn "*norsi3" 809 [(set (match_operand:SI 0 "register_operand" "=r,r") 810 (not:SI (ior:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ") 811 (match_operand:SI 2 "register_or_L_operand" "r,L"))))] 812 "" 813 "@ 814 nor %0, %z1, %2 815 nori %0, %z1, %2" 816 [(set_attr "type" "arith")] 817) 818 819(define_insn "*xnorsi3" 820 [(set (match_operand:SI 0 "register_operand" "=r,r") 821 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ") 822 (match_operand:SI 2 "register_or_L_operand" "r,L"))))] 823 "" 824 "@ 825 xnor %0, %z1, %2 826 xnori %0, %z1, %2" 827 [(set_attr "type" "arith")] 828) 829 830;; --------------------------------- 831;; shifts 832;; --------------------------------- 833 834(define_expand "ashlsi3" 835 [(set (match_operand:SI 0 "register_operand" "") 836 (ashift:SI (match_operand:SI 1 "register_or_zero_operand" "") 837 (match_operand:SI 2 "register_or_L_operand" "")))] 838 "" 839{ 840 if (!TARGET_BARREL_SHIFT_ENABLED) 841 { 842 if (!optimize_size 843 && satisfies_constraint_L (operands[2]) 844 && INTVAL (operands[2]) <= 8) 845 { 846 int i; 847 int shifts = INTVAL (operands[2]); 848 849 if (shifts == 0) 850 emit_move_insn (operands[0], operands[1]); 851 else 852 emit_insn (gen_addsi3 (operands[0], operands[1], operands[1])); 853 for (i = 1; i < shifts; i++) 854 emit_insn (gen_addsi3 (operands[0], operands[0], operands[0])); 855 DONE; 856 } 857 else 858 FAIL; 859 } 860}) 861 862(define_insn "*ashlsi3" 863 [(set (match_operand:SI 0 "register_operand" "=r,r") 864 (ashift:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ") 865 (match_operand:SI 2 "register_or_L_operand" "r,L")))] 866 "TARGET_BARREL_SHIFT_ENABLED" 867 "@ 868 sl %0, %z1, %2 869 sli %0, %z1, %2" 870 [(set_attr "type" "shift")] 871) 872 873(define_expand "ashrsi3" 874 [(set (match_operand:SI 0 "register_operand" "") 875 (ashiftrt:SI (match_operand:SI 1 "register_or_zero_operand" "") 876 (match_operand:SI 2 "register_or_L_operand" "")))] 877 "" 878{ 879 if (!TARGET_BARREL_SHIFT_ENABLED) 880 { 881 if (!optimize_size 882 && satisfies_constraint_L (operands[2]) 883 && INTVAL (operands[2]) <= 8) 884 { 885 int i; 886 int shifts = INTVAL (operands[2]); 887 rtx one = GEN_INT (1); 888 889 if (shifts == 0) 890 emit_move_insn (operands[0], operands[1]); 891 else 892 emit_insn (gen_ashrsi3_1bit (operands[0], operands[1], one)); 893 for (i = 1; i < shifts; i++) 894 emit_insn (gen_ashrsi3_1bit (operands[0], operands[0], one)); 895 DONE; 896 } 897 else 898 FAIL; 899 } 900}) 901 902(define_insn "*ashrsi3" 903 [(set (match_operand:SI 0 "register_operand" "=r,r") 904 (ashiftrt:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ") 905 (match_operand:SI 2 "register_or_L_operand" "r,L")))] 906 "TARGET_BARREL_SHIFT_ENABLED" 907 "@ 908 sr %0, %z1, %2 909 sri %0, %z1, %2" 910 [(set_attr "type" "shift")] 911) 912 913(define_insn "ashrsi3_1bit" 914 [(set (match_operand:SI 0 "register_operand" "=r") 915 (ashiftrt:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") 916 (match_operand:SI 2 "constant_M_operand" "M")))] 917 "!TARGET_BARREL_SHIFT_ENABLED" 918 "sri %0, %z1, %2" 919 [(set_attr "type" "shift")] 920) 921 922(define_expand "lshrsi3" 923 [(set (match_operand:SI 0 "register_operand" "") 924 (lshiftrt:SI (match_operand:SI 1 "register_or_zero_operand" "") 925 (match_operand:SI 2 "register_or_L_operand" "")))] 926 "" 927{ 928 if (!TARGET_BARREL_SHIFT_ENABLED) 929 { 930 if (!optimize_size 931 && satisfies_constraint_L (operands[2]) 932 && INTVAL (operands[2]) <= 8) 933 { 934 int i; 935 int shifts = INTVAL (operands[2]); 936 rtx one = GEN_INT (1); 937 938 if (shifts == 0) 939 emit_move_insn (operands[0], operands[1]); 940 else 941 emit_insn (gen_lshrsi3_1bit (operands[0], operands[1], one)); 942 for (i = 1; i < shifts; i++) 943 emit_insn (gen_lshrsi3_1bit (operands[0], operands[0], one)); 944 DONE; 945 } 946 else 947 FAIL; 948 } 949}) 950 951(define_insn "*lshrsi3" 952 [(set (match_operand:SI 0 "register_operand" "=r,r") 953 (lshiftrt:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ") 954 (match_operand:SI 2 "register_or_L_operand" "r,L")))] 955 "TARGET_BARREL_SHIFT_ENABLED" 956 "@ 957 sru %0, %z1, %2 958 srui %0, %z1, %2" 959 [(set_attr "type" "shift")] 960) 961 962(define_insn "lshrsi3_1bit" 963 [(set (match_operand:SI 0 "register_operand" "=r") 964 (lshiftrt:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") 965 (match_operand:SI 2 "constant_M_operand" "M")))] 966 "!TARGET_BARREL_SHIFT_ENABLED" 967 "srui %0, %z1, %2" 968 [(set_attr "type" "shift")] 969) 970 971;; --------------------------------- 972;; function entry / exit 973;; --------------------------------- 974 975(define_expand "prologue" 976 [(const_int 1)] 977 "" 978 " 979{ 980 lm32_expand_prologue (); 981 DONE; 982}") 983 984(define_expand "epilogue" 985 [(return)] 986 "" 987 " 988{ 989 lm32_expand_epilogue (); 990 DONE; 991}") 992 993;; --------------------------------- 994;; nop 995;; --------------------------------- 996 997(define_insn "nop" 998 [(const_int 0)] 999 "" 1000 "nop" 1001 [(set_attr "type" "arith")] 1002) 1003 1004;; --------------------------------- 1005;; blockage 1006;; --------------------------------- 1007 1008;; used to stop the scheduler from 1009;; scheduling code across certain boundaries 1010 1011(define_insn "blockage" 1012 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)] 1013 "" 1014 "" 1015 [(set_attr "length" "0")] 1016) 1017