1;; Machine description for FT32 2;; Copyright (C) 2015-2019 Free Software Foundation, Inc. 3;; Contributed by FTDI <support@ftdi.com> 4 5;; This file is part of GCC. 6 7;; GCC is free software; you can redistribute it and/or modify it 8;; under the terms of the GNU General Public License as published 9;; by the Free Software Foundation; either version 3, or (at your 10;; option) any later version. 11 12;; GCC is distributed in the hope that it will be useful, but WITHOUT 13;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 15;; License for more details. 16 17;; You should have received a copy of the GNU General Public License 18;; along with GCC; see the file COPYING3. If not see 19;; <http://www.gnu.org/licenses/>. 20 21;; ------------------------------------------------------------------------- 22;; FT32 specific constraints, predicates and attributes 23;; ------------------------------------------------------------------------- 24 25(include "constraints.md") 26(include "predicates.md") 27 28(define_constants [ 29 (FP_REG 0) 30 (SP_REG 1) 31 (CC_REG 35) 32]) 33 34(define_c_enum "unspec" 35 [UNSPEC_STRLEN 36 UNSPEC_MOVMEM 37 UNSPEC_SETMEM 38 UNSPEC_STPCPY 39 UNSPEC_INDEX_JMP 40 UNSPEC_LPM 41 UNSPEC_FMUL 42 UNSPEC_FMULS 43 UNSPEC_FMULSU 44 UNSPEC_COPYSIGN 45 UNSPEC_IDENTITY 46 UNSPEC_INSERT_BITS 47 UNSPEC_JMP_EPILOG 48 UNSPEC_JMP_EPILOG24 49 UNSPEC_JMP_PROLOG 50 UNSPEC_XCHG 51 ]) 52 53;; ------------------------------------------------------------------------- 54;; nop instruction 55;; ------------------------------------------------------------------------- 56 57(define_insn "nop" 58 [(const_int 0)] 59 "" 60 "nop") 61 62;; ------------------------------------------------------------------------- 63;; Arithmetic instructions 64;; ------------------------------------------------------------------------- 65 66(define_insn "addsi3" 67 [(set (match_operand:SI 0 "register_operand" "=r,r") 68 (plus:SI 69 (match_operand:SI 1 "register_operand" "r,r") 70 (match_operand:SI 2 "ft32_rimm_operand" "KA,r"))) 71 ] 72 "" 73 "add.l %0,%1,%2") 74 75(define_insn "subsi3" 76 [(set (match_operand:SI 0 "register_operand" "=r,r") 77 (minus:SI 78 (match_operand:SI 1 "register_operand" "r,r") 79 (match_operand:SI 2 "ft32_rimm_operand" "KA,r")))] 80 "" 81 "sub.l %0,%1,%2") 82 83(define_insn "mulsi3" 84 [(set (match_operand:SI 0 "register_operand" "=r,r") 85 (mult:SI 86 (match_operand:SI 1 "register_operand" "r,r") 87 (match_operand:SI 2 "ft32_rimm_operand" "KA,r")))] 88 "" 89 "mul.l %0,%1,%2") 90 91(define_insn "umulsidi3" 92 [(set (match_operand:DI 0 "register_operand" "=r,r") 93 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r")) 94 (zero_extend:DI (match_operand:SI 2 "ft32_rimm_operand" "r,KA")))) 95 (clobber (reg:CC CC_REG))] 96 "" 97 "mul.l $cc,%1,%2\;muluh.l %h0,%1,%2\;move.l %0,$cc") 98 99(define_insn "divsi3" 100 [(set (match_operand:SI 0 "register_operand" "=r,r") 101 (div:SI 102 (match_operand:SI 1 "register_operand" "r,r") 103 (match_operand:SI 2 "ft32_rimm_operand" "r,KA")))] 104 "!TARGET_NODIV" 105 "div.l %0,%1,%2") 106 107(define_insn "modsi3" 108 [(set (match_operand:SI 0 "register_operand" "=r,r") 109 (mod:SI 110 (match_operand:SI 1 "register_operand" "r,r") 111 (match_operand:SI 2 "ft32_rimm_operand" "r,KA")))] 112 "!TARGET_NODIV" 113 "mod.l %0,%1,%2") 114 115(define_insn "udivsi3" 116 [(set (match_operand:SI 0 "register_operand" "=r,r") 117 (udiv:SI 118 (match_operand:SI 1 "register_operand" "r,r") 119 (match_operand:SI 2 "ft32_rimm_operand" "r,KA")))] 120 "!TARGET_NODIV" 121 "udiv.l %0,%1,%2") 122 123(define_insn "umodsi3" 124 [(set (match_operand:SI 0 "register_operand" "=r,r") 125 (umod:SI 126 (match_operand:SI 1 "register_operand" "r,r") 127 (match_operand:SI 2 "register_operand" "r,KA")))] 128 "!TARGET_NODIV" 129 "umod.l %0,%1,%2") 130 131(define_insn "extvsi" 132 [(set (match_operand:SI 0 "register_operand" "=r") 133 (sign_extract:SI (match_operand:SI 1 "register_operand" "r") 134 (match_operand:SI 2 "ft32_bwidth_operand" "b") 135 (match_operand:SI 3 "const_int_operand" "i")))] 136 "" 137 "bexts.l %0,%1,((15 & %2) << 5) | (%3)") 138 139(define_insn "extzvsi" 140 [(set (match_operand:SI 0 "register_operand" "=r") 141 (zero_extract:SI (match_operand:SI 1 "register_operand" "r") 142 (match_operand:SI 2 "ft32_bwidth_operand" "b") 143 (match_operand:SI 3 "const_int_operand" "i")))] 144 "" 145 "bextu.l %0,%1,((15 & %2) << 5) | (%3)") 146 147(define_insn "insvsi" 148 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,r") 149 (match_operand:SI 1 "ft32_bwidth_operand" "b,b") 150 (match_operand:SI 2 "const_int_operand" "i,i")) 151 (match_operand:SI 3 "general_operand" "r,O")) 152 (clobber (match_scratch:SI 4 "=&r,r"))] 153 "" 154 { 155 if (which_alternative == 0) 156 { 157 return \"ldl.l %4,%3,((%1&15)<<5)|(%2)\;bins.l %0,%0,%4\"; 158 } 159 else 160 { 161 if ((INTVAL(operands[3]) == 0) || (INTVAL(operands[1]) == 1)) 162 return \"bins.l %0,%0,(%3<<9)|((%1&15)<<5)|(%2)\"; 163 else 164 return \"ldk.l %4,(%3<<10)|((%1&15)<<5)|(%2)\;bins.l %0,%0,%4\"; 165 } 166 }) 167 168;; ------------------------------------------------------------------------- 169;; Unary arithmetic instructions 170;; ------------------------------------------------------------------------- 171 172(define_insn "one_cmplsi2" 173 [(set (match_operand:SI 0 "register_operand" "=r") 174 (not:SI (match_operand:SI 1 "register_operand" "r")))] 175 "" 176 "xor.l %0,%1,-1") 177 178;; ------------------------------------------------------------------------- 179;; Logical operators 180;; ------------------------------------------------------------------------- 181 182(define_insn "andsi3" 183 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 184 (and:SI (match_operand:SI 1 "register_operand" "r,r,r") 185 (match_operand:SI 2 "general_operand" "r,x,KA")))] 186 "" 187 "@ 188 and.l %0,%1,%2 189 bins.l %0,%1,%g2 190 and.l %0,%1,%2") 191 192(define_insn "andqi3" 193 [(set (match_operand:QI 0 "register_operand" "=r,r,r") 194 (and:QI (match_operand:QI 1 "register_operand" "r,r,r") 195 (match_operand:QI 2 "general_operand" "r,x,KA")))] 196 "" 197 "@ 198 and.b %0,%1,%2 199 bins.b %0,%1,%g2 200 and.b %0,%1,%2") 201 202(define_insn "xorsi3" 203 [(set (match_operand:SI 0 "register_operand" "=r,r") 204 (xor:SI (match_operand:SI 1 "register_operand" "r,r") 205 (match_operand:SI 2 "ft32_rimm_operand" "r,KA")))] 206 "" 207{ 208 return "xor.l %0,%1,%2"; 209}) 210 211(define_insn "iorsi3" 212 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 213 (ior:SI (match_operand:SI 1 "register_operand" "r,r,r") 214 (match_operand:SI 2 "general_operand" "r,w,KA")))] 215 "" 216 "@ 217 or.l %0,%1,%2 218 bins.l %0,%1,%f2 219 or.l %0,%1,%2") 220 221;; ------------------------------------------------------------------------- 222;; Shifters 223;; ------------------------------------------------------------------------- 224 225(define_insn "ashlsi3" 226 [(set (match_operand:SI 0 "register_operand" "=r,r") 227 (ashift:SI (match_operand:SI 1 "register_operand" "r,r") 228 (match_operand:SI 2 "ft32_rimm_operand" "r,KA")))] 229 "" 230{ 231 return "ashl.l %0,%1,%2"; 232}) 233 234(define_insn "ashrsi3" 235 [(set (match_operand:SI 0 "register_operand" "=r,r") 236 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r") 237 (match_operand:SI 2 "ft32_rimm_operand" "r,KA")))] 238 "" 239{ 240 return "ashr.l %0,%1,%2"; 241}) 242 243(define_insn "lshrsi3" 244 [(set (match_operand:SI 0 "register_operand" "=r,r") 245 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r") 246 (match_operand:SI 2 "ft32_rimm_operand" "r,KA")))] 247 "" 248{ 249 return "lshr.l %0,%1,%2"; 250}) 251 252;; ------------------------------------------------------------------------- 253;; Move instructions 254;; ------------------------------------------------------------------------- 255 256;; SImode 257 258(define_insn "*sne" 259 [(set (match_operand:SI 0 "register_operand" "=r") 260 (reg:SI CC_REG))] 261 "" 262 "bextu.l %0,$cc,32|0\;xor.l %0,%0,-1" 263) 264 265;; Push a register onto the stack 266(define_insn "movsi_push" 267 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) 268 (match_operand:SI 0 "register_operand" "r"))] 269 "" 270 "push.l %0") 271 272;; Pop a register from the stack 273(define_insn "movsi_pop" 274 [(set (match_operand:SI 0 "register_operand" "=r") 275 (mem:SI (post_inc:SI (reg:SI SP_REG))))] 276 "" 277 "pop.l %0") 278 279(define_expand "movsi" 280 [(set (match_operand:SI 0 "general_operand" "") 281 (match_operand:SI 1 "general_operand" ""))] 282 "" 283{ 284 /* If this is a store, force the value into a register. */ 285 if (!(reload_in_progress || reload_completed)) 286 { 287 if (MEM_P (operands[0])) 288 { 289 operands[1] = force_reg (SImode, operands[1]); 290 if (MEM_P (XEXP (operands[0], 0))) 291 operands[0] = gen_rtx_MEM (SImode, force_reg (SImode, XEXP (operands[0], 0))); 292 } 293 else 294 { 295 if (MEM_P (operands[1]) && MEM_P (XEXP (operands[1], 0))) 296 operands[1] = gen_rtx_MEM (SImode, force_reg (SImode, XEXP (operands[1], 0))); 297 } 298 /* 299 if (MEM_P (operands[0])) { 300 rtx o = XEXP (operands[0], 0); 301 if (!REG_P(o) && 302 !CONST_INT_P(o) && 303 GET_CODE(o) != SYMBOL_REF && 304 GET_CODE(o) != LABEL_REF) { 305 operands[0] = gen_rtx_MEM (SImode, force_reg (SImode, XEXP (operands[0], 0))); 306 } 307 } 308 */ 309 } 310}) 311 312(define_insn "*rtestsi" 313 [(set (reg:SI CC_REG) 314 (match_operand:SI 0 "register_operand" "r"))] 315 "" 316 "cmp.l %0,0" 317) 318 319(define_insn "*rtestqi" 320 [(set (reg:QI CC_REG) 321 (match_operand:QI 0 "register_operand" "r"))] 322 "" 323 "cmp.b %0,0" 324) 325 326(define_insn "*movsi" 327 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,BW,r,r,r,r,A,r,r") 328 (match_operand:SI 1 "ft32_general_movsrc_operand" "r,r,BW,A,S,i,r,e,f"))] 329 "register_operand (operands[0], SImode) || register_operand (operands[1], SImode)" 330 "@ 331 move.l %0,%1 332 sti.l %0,%1 333 ldi.l %0,%1 334 lda.l %0,%1 335 ldk.l %0,%1 336 *return ft32_load_immediate(operands[0], INTVAL(operands[1])); 337 sta.l %0,%1 338 lpm.l %0,%1 339 lpmi.l %0,%1" 340) 341 342(define_expand "movqi" 343 [(set (match_operand:QI 0 "general_operand" "") 344 (match_operand:QI 1 "general_operand" ""))] 345 "" 346{ 347 /* If this is a store, force the value into a register. */ 348 if (!(reload_in_progress || reload_completed)) 349 { 350 if (MEM_P (operands[0])) 351 { 352 operands[1] = force_reg (QImode, operands[1]); 353 if (MEM_P (XEXP (operands[0], 0))) 354 operands[0] = gen_rtx_MEM (QImode, force_reg (SImode, XEXP (operands[0], 0))); 355 } 356 else 357 { 358 if (MEM_P (operands[1]) && MEM_P (XEXP (operands[1], 0))) 359 operands[1] = gen_rtx_MEM (QImode, force_reg (SImode, XEXP (operands[1], 0))); 360 } 361 if (MEM_P (operands[0]) && !REG_P(XEXP (operands[0], 0))) 362 { 363 operands[0] = gen_rtx_MEM (QImode, force_reg (SImode, XEXP (operands[0], 0))); 364 } 365 } 366}) 367 368(define_insn "zero_extendqisi2" 369 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r") 370 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "BW,r,f")))] 371 "" 372 "@ 373 ldi.b %0,%1 374 and.l %0,%1,255 375 lpmi.b %0,%1" 376) 377 378(define_insn "extendqisi2" 379 [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 380 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r")))] 381 "" 382 "bexts.l %0,%1,(8<<5)|0" 383) 384 385(define_insn "zero_extendhisi2" 386 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r") 387 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "BW,r,f")))] 388 "" 389 "@ 390 ldi.s %0,%1 391 bextu.l %0,%1,(0<<5)|0 392 lpmi.s %0,%1" 393) 394 395(define_insn "extendhisi2" 396 [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 397 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r")))] 398 "" 399 "bexts.l %0,%1,(0<<5)|0" 400) 401 402(define_insn "*movqi" 403 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,BW,r,r,A,r,r,r") 404 (match_operand:QI 1 "ft32_general_movsrc_operand" "r,r,BW,A,r,I,e,f"))] 405 "register_operand (operands[0], QImode) 406 || register_operand (operands[1], QImode)" 407 "@ 408 move.b %0,%1 409 sti.b %0,%1 410 ldi.b %0,%1 411 lda.b %0,%1 412 sta.b %0,%1 413 ldk.b %0,%1 414 lpm.b %0,%1 415 lpmi.b %0,%1" 416) 417 418(define_expand "movhi" 419 [(set (match_operand:HI 0 "general_operand" "") 420 (match_operand:HI 1 "general_operand" ""))] 421 "" 422{ 423 /* If this is a store, force the value into a register. */ 424 if (!(reload_in_progress || reload_completed)) 425 { 426 if (MEM_P (operands[0])) 427 { 428 operands[1] = force_reg (HImode, operands[1]); 429 if (MEM_P (XEXP (operands[0], 0))) 430 operands[0] = gen_rtx_MEM (HImode, force_reg (SImode, XEXP (operands[0], 0))); 431 } 432 else 433 { 434 if (MEM_P (operands[1]) && MEM_P (XEXP (operands[1], 0))) 435 operands[1] = gen_rtx_MEM (HImode, force_reg (SImode, XEXP (operands[1], 0))); 436 } 437 if (MEM_P (operands[0])) 438 { 439 rtx o = XEXP (operands[0], 0); 440 if (!REG_P(o) && 441 !CONST_INT_P(o) && 442 GET_CODE(o) != SYMBOL_REF && 443 GET_CODE(o) != LABEL_REF) { 444 operands[0] = gen_rtx_MEM (HImode, force_reg (SImode, XEXP (operands[0], 0))); 445 } 446 } 447 } 448}) 449 450(define_insn "*movhi" 451 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,BW,r,r,A,r,r,r") 452 (match_operand:HI 1 "ft32_general_movsrc_operand" "r,r,BW,A,r,I,e,f"))] 453 "(register_operand (operands[0], HImode) 454 || register_operand (operands[1], HImode))" 455 "@ 456 move.s %0,%1 457 sti.s %0,%1 458 ldi.s %0,%1 459 lda.s %0,%1 460 sta.s %0,%1 461 ldk.s %0,%1 462 lpm.s %0,%1 463 lpmi.s %0,%1" 464) 465 466(define_expand "movsf" 467 [(set (match_operand:SF 0 "general_operand" "") 468 (match_operand:SF 1 "general_operand" ""))] 469 "" 470{ 471 /* If this is a store, force the value into a register. */ 472 if (MEM_P (operands[0])) 473 operands[1] = force_reg (SFmode, operands[1]); 474 if (CONST_DOUBLE_P(operands[1])) 475 operands[1] = force_const_mem(SFmode, operands[1]); 476}) 477 478(define_insn "*movsf" 479 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,BW,r,r,A,r,r") 480 (match_operand:SF 1 "ft32_general_movsrc_operand" "r,r,BW,A,r,I,f"))] 481 "(register_operand (operands[0], SFmode) 482 || register_operand (operands[1], SFmode))" 483 "@ 484 move.l %0,%1 485 sti.l %0,%1 486 ldi.l %0,%1 487 lda.l %0,%1 488 sta.l %0,%1 489 ldk.l %0,%1 490 lpmi.l %0,%1" 491) 492 493;; ------------------------------------------------------------------------- 494;; Compare instructions 495;; ------------------------------------------------------------------------- 496 497(define_expand "cbranchsi4" 498 [(set (reg:CC CC_REG) 499 (compare:CC 500 (match_operand:SI 1 "register_operand" "") 501 (match_operand:SI 2 "ft32_rimm_operand" ""))) 502 (set (pc) 503 (if_then_else (match_operator 0 "comparison_operator" 504 [(reg:CC CC_REG) (const_int 0)]) 505 (label_ref (match_operand 3 "" "")) 506 (pc)))] 507 "" 508 "") 509 510(define_insn "cmpsi" 511 [(set (reg:CC CC_REG) 512 (compare:CC 513 (match_operand:SI 0 "register_operand" "r,r") 514 (match_operand:SI 1 "ft32_rimm_operand" "r,KA")))] 515 "" 516 "cmp.l %0,%1") 517 518(define_insn "" 519 [(set (pc) 520 (if_then_else 521 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r") 522 (const_int 1) 523 (match_operand:SI 1 "const_int_operand" "i")) 524 (const_int 0)) 525 (label_ref (match_operand 2 "" "")) 526 (pc))) 527 (clobber (reg:CC CC_REG))] 528 "" 529 "btst.l %0,(1<<5)|%1\;jmpc nz,%l2") 530 531(define_insn "" 532 [(set (pc) 533 (if_then_else 534 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r") 535 (const_int 1) 536 (match_operand:SI 1 "const_int_operand" "i")) 537 (const_int 0)) 538 (label_ref (match_operand 2 "" "")) 539 (pc))) 540 (clobber (reg:CC CC_REG))] 541 "" 542 "btst.l %0,(1<<5)|%1\;jmpc z,%l2") 543 544(define_expand "cbranchqi4" 545 [(set (reg:CC CC_REG) 546 (compare:CC 547 (match_operand:QI 1 "register_operand" "") 548 (match_operand:QI 2 "ft32_rimm_operand" ""))) 549 (set (pc) 550 (if_then_else (match_operator 0 "comparison_operator" 551 [(reg:CC CC_REG) (const_int 0)]) 552 (label_ref (match_operand 3 "" "")) 553 (pc)))] 554 "" 555 "") 556 557(define_insn "*cmpqi" 558 [(set (reg:CC CC_REG) 559 (compare:CC 560 (match_operand:QI 0 "register_operand" "r,r") 561 (match_operand:QI 1 "ft32_rimm_operand" "r,KA")))] 562 "" 563 "cmp.b %0,%1") 564 565;; ------------------------------------------------------------------------- 566;; Branch instructions 567;; ------------------------------------------------------------------------- 568 569(define_code_iterator cond [ne eq lt ltu gt gtu ge le geu leu]) 570(define_code_attr CC [(ne "nz") (eq "z") (lt "lt") (ltu "b") 571 (gt "gt") (gtu "a") (ge "gte") (le "lte") 572 (geu "ae") (leu "be") ]) 573(define_code_attr rCC [(ne "z") (eq "nz") (lt "gte") (ltu "ae") 574 (gt "lte") (gtu "be") (ge "lt") (le "gt") 575 (geu "b") (leu "a") ]) 576 577(define_insn "*b<cond:code>" 578 [(set (pc) 579 (if_then_else (cond (reg:CC CC_REG) 580 (const_int 0)) 581 (label_ref (match_operand 0 "" "")) 582 (pc)))] 583 "" 584{ 585 return "jmpc <CC>,%l0"; 586} 587) 588 589(define_expand "cstoresi4" 590 [(set (reg:CC CC_REG) 591 (compare:CC (match_operand:SI 2 "register_operand" "r,r") 592 (match_operand:SI 3 "ft32_rimm_operand" "r,KA"))) 593 (set (match_operand:SI 0 "register_operand") 594 (match_operator:SI 1 "ordered_comparison_operator" 595 [(reg:CC CC_REG) (const_int 0)]))] 596 "" 597{ 598 rtx test; 599 600 switch (GET_CODE (operands[1])) { 601 case NE: 602 case GEU: 603 case LT: 604 case LE: 605 case LEU: 606 test = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[1])), 607 SImode, operands[2], operands[3]); 608 emit_insn(gen_cstoresi4(operands[0], test, operands[2], operands[3])); 609 emit_insn(gen_xorsi3(operands[0], operands[0], gen_int_mode(1, SImode))); 610 DONE; 611 default: 612 ; 613 } 614}) 615 616(define_insn "*seq" 617 [(set (match_operand:SI 0 "register_operand" "=r") 618 (eq:SI (reg CC_REG) (const_int 0)))] 619 "" 620 "bextu.l %0,$cc,32|0" 621) 622 623(define_insn "*sltu" 624 [(set (match_operand:SI 0 "register_operand" "=r") 625 (ltu:SI (reg CC_REG) (const_int 0)))] 626 "" 627 "bextu.l %0,$cc,32|1" 628) 629 630(define_insn "*sge" 631 [(set (match_operand:SI 0 "register_operand" "=r") 632 (ge:SI (reg CC_REG) (const_int 0)))] 633 "" 634 "bextu.l %0,$cc,32|4" 635) 636 637(define_insn "*sgt" 638 [(set (match_operand:SI 0 "register_operand" "=r") 639 (gt:SI (reg CC_REG) (const_int 0)))] 640 "" 641 "bextu.l %0,$cc,32|5" 642) 643 644(define_insn "*sgtu" 645 [(set (match_operand:SI 0 "register_operand" "=r") 646 (gtu:SI (reg CC_REG) (const_int 0)))] 647 "" 648 "bextu.l %0,$cc,32|6" 649) 650 651;; ------------------------------------------------------------------------- 652;; Call and Jump instructions 653;; ------------------------------------------------------------------------- 654 655(define_expand "call" 656 [(call (match_operand:QI 0 "memory_operand" "") 657 (match_operand 1 "general_operand" ""))] 658 "" 659{ 660 gcc_assert (MEM_P (operands[0])); 661}) 662 663(define_insn "*call" 664 [(call (mem:QI (match_operand:SI 665 0 "nonmemory_operand" "i,r")) 666 (match_operand 1 "" ""))] 667 "" 668 "@ 669 call %0 670 calli %0" 671) 672 673(define_expand "call_value" 674 [(set (match_operand 0 "" "") 675 (call (match_operand:QI 1 "memory_operand" "") 676 (match_operand 2 "" "")))] 677 "" 678{ 679 gcc_assert (MEM_P (operands[1])); 680}) 681 682(define_insn "*call_value" 683 [(set (match_operand 0 "register_operand" "=r") 684 (call (mem:QI (match_operand:SI 685 1 "immediate_operand" "i")) 686 (match_operand 2 "" "")))] 687 "" 688 "call %1" 689) 690 691(define_insn "*call_value_indirect" 692 [(set (match_operand 0 "register_operand" "=r") 693 (call (mem:QI (match_operand:SI 694 1 "register_operand" "r")) 695 (match_operand 2 "" "")))] 696 "" 697 "calli %1" 698) 699 700(define_insn "indirect_jump" 701 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "r"))] 702 "" 703 "jmpi %0") 704 705(define_insn "jump" 706 [(set (pc) 707 (label_ref (match_operand 0 "" "")))] 708 "" 709 "jmp %l0" 710) 711 712(define_insn "call_prolog" 713 [(unspec:SI [(match_operand 0 "" "")] 714 UNSPEC_JMP_PROLOG)] 715 "" 716 "call __prolog_%0" 717) 718 719(define_insn "jump_epilog" 720 [(unspec:SI [(match_operand 0 "" "")] 721 UNSPEC_JMP_EPILOG)] 722 "" 723 "jmp __epilog_%0" 724) 725 726(define_insn "jump_epilog24" 727 [(unspec:SI [(match_operand 0 "" "")] 728 UNSPEC_JMP_EPILOG24)] 729 "" 730 "jmp __epilog24_%0" 731) 732 733 734;; Subroutines of "casesi". 735;; operand 0 is index 736;; operand 1 is the minimum bound 737;; operand 2 is the maximum bound - minimum bound + 1 738;; operand 3 is CODE_LABEL for the table; 739;; operand 4 is the CODE_LABEL to go to if index out of range. 740 741(define_expand "casesi" 742 [(match_operand:SI 0 "general_operand" "") 743 (match_operand:SI 1 "const_int_operand" "") 744 (match_operand:SI 2 "const_int_operand" "") 745 (match_operand 3 "" "") 746 (match_operand 4 "" "")] 747 "" 748 " 749{ 750 if (GET_CODE (operands[0]) != REG) 751 operands[0] = force_reg (SImode, operands[0]); 752 753 if (operands[1] != const0_rtx) 754 { 755 rtx index = gen_reg_rtx (SImode); 756 rtx offset = gen_reg_rtx (SImode); 757 758 emit_insn (gen_movsi (offset, operands[1])); 759 emit_insn (gen_subsi3 (index, operands[0], offset)); 760 operands[0] = index; 761 } 762 763 { 764 rtx test = gen_rtx_GTU (VOIDmode, operands[0], operands[2]); 765 emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2], operands[4])); 766 } 767 768 emit_jump_insn (gen_casesi0 (operands[0], operands[3])); 769 DONE; 770}") 771 772(define_insn "casesi0" 773 [(set (pc) (mem:SI (plus:SI 774 (mult:SI (match_operand:SI 0 "register_operand" "r") 775 (const_int 4)) 776 (label_ref (match_operand 1 "" ""))))) 777 (clobber (match_scratch:SI 2 "=&r")) 778 ] 779 "" 780 { 781 if (TARGET_NOPM) 782 return \"ldk.l\t$cc,%l1\;ashl.l\t%2,%0,2\;add.l\t%2,%2,$cc\;ldi.l\t%2,%2,0\;jmpi\t%2\"; 783 else 784 return \"ldk.l\t$cc,%l1\;ashl.l\t%2,%0,2\;add.l\t%2,%2,$cc\;lpmi.l\t%2,%2,0\;jmpi\t%2\"; 785 }) 786 787;; ------------------------------------------------------------------------- 788;; Atomic exchange instruction 789;; ------------------------------------------------------------------------- 790 791(define_insn "atomic_exchangesi" 792 [(set (match_operand:SI 0 "register_operand" "=&r,r") ;; output 793 (match_operand:SI 1 "memory_operand" "+BW,A")) ;; memory 794 (set (match_dup 1) 795 (unspec:SI 796 [(match_operand:SI 2 "register_operand" "0,0") ;; input 797 (match_operand:SI 3 "const_int_operand")] ;; model 798 UNSPEC_XCHG))] 799 "" 800 "@ 801 exi.l %0,%1 802 exa.l %0,%1") 803 804(define_insn "atomic_exchangehi" 805 [(set (match_operand:HI 0 "register_operand" "=&r,r") ;; output 806 (match_operand:HI 1 "memory_operand" "+BW,A")) ;; memory 807 (set (match_dup 1) 808 (unspec:HI 809 [(match_operand:HI 2 "register_operand" "0,0") ;; input 810 (match_operand:HI 3 "const_int_operand")] ;; model 811 UNSPEC_XCHG))] 812 "" 813 "@ 814 exi.s %0,%1 815 exa.s %0,%1") 816 817(define_insn "atomic_exchangeqi" 818 [(set (match_operand:QI 0 "register_operand" "=&r,r") ;; output 819 (match_operand:QI 1 "memory_operand" "+BW,A")) ;; memory 820 (set (match_dup 1) 821 (unspec:QI 822 [(match_operand:QI 2 "register_operand" "0,0") ;; input 823 (match_operand:QI 3 "const_int_operand")] ;; model 824 UNSPEC_XCHG))] 825 "" 826 "@ 827 exi.b %0,%1 828 exa.b %0,%1") 829 830;; ------------------------------------------------------------------------- 831;; String instructions 832;; ------------------------------------------------------------------------- 833 834(define_insn "cmpstrsi" 835 [(set (match_operand:SI 0 "register_operand" "=r,r") 836 (compare:SI (match_operand:BLK 1 "memory_operand" "W,BW") 837 (match_operand:BLK 2 "memory_operand" "W,BW"))) 838 (clobber (match_operand:SI 3)) 839 ] 840 "" 841 "strcmp.%d3 %0,%b1,%b2" 842) 843 844(define_insn "movstr" 845[(set (match_operand:BLK 1 "memory_operand" "=W") 846 (match_operand:BLK 2 "memory_operand" "W")) 847 (use (match_operand:SI 0)) 848 (clobber (match_dup 0)) 849 ] 850"0" 851"stpcpy %b1,%b2 # %0 %b1 %b2" 852) 853 854(define_insn "movmemsi" 855 [(set (match_operand:BLK 0 "memory_operand" "=W,BW") 856 (match_operand:BLK 1 "memory_operand" "W,BW")) 857 (use (match_operand:SI 2 "ft32_imm_operand" "KA,KA")) 858 (use (match_operand:SI 3)) 859 ] 860 "" 861 "memcpy.%d3 %b0,%b1,%2 " 862) 863 864(define_insn "setmemsi" 865 [(set (match_operand:BLK 0 "memory_operand" "=BW") (unspec:BLK [ 866 (use (match_operand:QI 2 "register_operand" "r")) 867 (use (match_operand:SI 1 "ft32_imm_operand" "KA")) 868 ] UNSPEC_SETMEM)) 869 (use (match_operand:SI 3)) 870 ] 871 "" 872 "memset.%d3 %b0,%2,%1" 873) 874 875(define_insn "strlensi" 876 [(set (match_operand:SI 0 "register_operand" "=r") 877 (unspec:SI [(match_operand:BLK 1 "memory_operand" "W") 878 (match_operand:QI 2 "const_int_operand" "") 879 (match_operand:SI 3 "ft32_rimm_operand" "")] 880 UNSPEC_STRLEN))] 881 "" 882 "strlen.%d3 %0,%b1 # %2 %3" 883) 884 885;; ------------------------------------------------------------------------- 886;; Prologue & Epilogue 887;; ------------------------------------------------------------------------- 888 889(define_expand "prologue" 890 [(clobber (const_int 0))] 891 "" 892{ 893 extern void ft32_expand_prologue(); 894 ft32_expand_prologue (); 895 DONE; 896}) 897 898 899(define_expand "epilogue" 900 [(return)] 901 "" 902{ 903 extern void ft32_expand_epilogue(); 904 ft32_expand_epilogue (); 905 DONE; 906}) 907 908(define_insn "link" 909 [ 910;; (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) 911;; (reg:SI FP_REG)) 912 (set (match_operand:SI 0) 913 (reg:SI SP_REG)) 914 (set (reg:SI SP_REG) 915 (plus:SI (reg:SI SP_REG) 916 (match_operand:SI 1 "general_operand" "L")))] 917 "" 918 "link %0,%m1" 919) 920 921(define_insn "unlink" 922 [(set (reg:SI FP_REG) 923 (mem:SI (reg:SI FP_REG))) 924 (set (reg:SI SP_REG) 925 (plus:SI (reg:SI FP_REG) 926 (const_int 4)))] 927 "" 928 "unlink $r29" 929) 930 931(define_insn "returner" 932 [(return)] 933 "reload_completed" 934 "return") 935 936(define_insn "pretend_returner" 937 [(set (reg:SI SP_REG) 938 (plus:SI (reg:SI SP_REG) 939 (match_operand:SI 0))) 940 (return)] 941 "reload_completed" 942 "pop.l $cc\;add.l $sp,$sp,%0\;jmpi $cc") 943 944(define_insn "returner24" 945 [ 946 (set (reg:SI SP_REG) 947 (plus:SI 948 (reg:SI SP_REG) 949 (const_int 24))) 950 (return)] 951 "" 952 "jmp __epilog24") 953