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