1;; GCC machine description for CRX. 2;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 3;; 2001, 2002, 2003, 2004 4;; 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 9;; it under the terms of the GNU General Public License as published by 10;; the Free Software Foundation; either version 2, or (at your option) 11;; any later version. 12;; 13;; GCC is distributed in the hope that it will be useful, 14;; but WITHOUT ANY WARRANTY; without even the implied warranty of 15;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16;; GNU General Public 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 COPYING. If not, write to 20;; the Free Software Foundation, 51 Franklin Street, Fifth Floor, 21;; Boston, MA 02110-1301, USA. */ 22 23;; Register numbers 24 25(define_constants 26 [(SP_REGNUM 15) ; Stack pointer 27 (RA_REGNUM 14) ; Return address 28 (LO_REGNUM 16) ; LO register 29 (HI_REGNUM 17) ; HI register 30 (CC_REGNUM 18) ; Condition code register 31 ] 32) 33 34(define_attr "length" "" ( const_int 6 )) 35 36(define_asm_attributes 37 [(set_attr "length" "6")] 38) 39 40;; Predicates 41 42(define_predicate "u4bits_operand" 43 (match_code "const_int,const_double") 44 { 45 if (GET_CODE (op) == CONST_DOUBLE) 46 return crx_const_double_ok (op); 47 return (UNSIGNED_INT_FITS_N_BITS(INTVAL(op), 4)) ? 1 : 0; 48 } 49) 50 51(define_predicate "cst4_operand" 52 (and (match_code "const_int") 53 (match_test "INT_CST4(INTVAL(op))"))) 54 55(define_predicate "reg_or_u4bits_operand" 56 (ior (match_operand 0 "u4bits_operand") 57 (match_operand 0 "register_operand"))) 58 59(define_predicate "reg_or_cst4_operand" 60 (ior (match_operand 0 "cst4_operand") 61 (match_operand 0 "register_operand"))) 62 63(define_predicate "reg_or_sym_operand" 64 (ior (match_code "symbol_ref") 65 (match_operand 0 "register_operand"))) 66 67(define_predicate "nosp_reg_operand" 68 (and (match_operand 0 "register_operand") 69 (match_test "REGNO (op) != SP_REGNUM"))) 70 71(define_predicate "store_operand" 72 (and (match_operand 0 "memory_operand") 73 (not (match_operand 0 "push_operand")))) 74 75;; Mode Macro Definitions 76 77(define_mode_macro ALLMT [QI HI SI SF DI DF]) 78(define_mode_macro CRXMM [QI HI SI SF]) 79(define_mode_macro CRXIM [QI HI SI]) 80(define_mode_macro DIDFM [DI DF]) 81(define_mode_macro SISFM [SI SF]) 82(define_mode_macro SHORT [QI HI]) 83 84(define_mode_attr tIsa [(QI "b") (HI "w") (SI "d") (SF "d")]) 85(define_mode_attr lImmArith [(QI "4") (HI "4") (SI "6")]) 86(define_mode_attr lImmRotl [(QI "2") (HI "2") (SI "4")]) 87(define_mode_attr IJK [(QI "I") (HI "J") (SI "K")]) 88(define_mode_attr iF [(QI "i") (HI "i") (SI "i") (DI "i") (SF "F") (DF "F")]) 89(define_mode_attr JG [(QI "J") (HI "J") (SI "J") (DI "J") (SF "G") (DF "G")]) 90; In HI or QI mode we push 4 bytes. 91(define_mode_attr pushCnstr [(QI "X") (HI "X") (SI "<") (SF "<") (DI "<") (DF "<")]) 92(define_mode_attr tpush [(QI "") (HI "") (SI "") (SF "") (DI "sp, ") (DF "sp, ")]) 93(define_mode_attr lpush [(QI "2") (HI "2") (SI "2") (SF "2") (DI "4") (DF "4")]) 94 95 96;; Code Macro Definitions 97 98(define_code_macro sz_xtnd [sign_extend zero_extend]) 99(define_code_attr sIsa [(sign_extend "") (zero_extend "u")]) 100(define_code_attr sPat [(sign_extend "s") (zero_extend "u")]) 101(define_code_attr szPat [(sign_extend "") (zero_extend "zero_")]) 102(define_code_attr szIsa [(sign_extend "s") (zero_extend "z")]) 103 104(define_code_macro sh_oprnd [ashift ashiftrt lshiftrt]) 105(define_code_attr shIsa [(ashift "ll") (ashiftrt "ra") (lshiftrt "rl")]) 106(define_code_attr shPat [(ashift "ashl") (ashiftrt "ashr") (lshiftrt "lshr")]) 107 108(define_code_macro mima_oprnd [smax umax smin umin]) 109(define_code_attr mimaIsa [(smax "maxs") (umax "maxu") (smin "mins") (umin "minu")]) 110 111(define_code_macro any_cond [eq ne gt gtu lt ltu ge geu le leu]) 112 113;; Addition Instructions 114 115(define_insn "adddi3" 116 [(set (match_operand:DI 0 "register_operand" "=r,r") 117 (plus:DI (match_operand:DI 1 "register_operand" "%0,0") 118 (match_operand:DI 2 "nonmemory_operand" "r,i"))) 119 (clobber (reg:CC CC_REGNUM))] 120 "" 121 "addd\t%L2, %L1\;addcd\t%H2, %H1" 122 [(set_attr "length" "4,12")] 123) 124 125(define_insn "add<mode>3" 126 [(set (match_operand:CRXIM 0 "register_operand" "=r,r") 127 (plus:CRXIM (match_operand:CRXIM 1 "register_operand" "%0,0") 128 (match_operand:CRXIM 2 "nonmemory_operand" "r,i"))) 129 (clobber (reg:CC CC_REGNUM))] 130 "" 131 "add<tIsa>\t%2, %0" 132 [(set_attr "length" "2,<lImmArith>")] 133) 134 135;; Subtract Instructions 136 137(define_insn "subdi3" 138 [(set (match_operand:DI 0 "register_operand" "=r,r") 139 (minus:DI (match_operand:DI 1 "register_operand" "0,0") 140 (match_operand:DI 2 "nonmemory_operand" "r,i"))) 141 (clobber (reg:CC CC_REGNUM))] 142 "" 143 "subd\t%L2, %L1\;subcd\t%H2, %H1" 144 [(set_attr "length" "4,12")] 145) 146 147(define_insn "sub<mode>3" 148 [(set (match_operand:CRXIM 0 "register_operand" "=r,r") 149 (minus:CRXIM (match_operand:CRXIM 1 "register_operand" "0,0") 150 (match_operand:CRXIM 2 "nonmemory_operand" "r,i"))) 151 (clobber (reg:CC CC_REGNUM))] 152 "" 153 "sub<tIsa>\t%2, %0" 154 [(set_attr "length" "2,<lImmArith>")] 155) 156 157;; Multiply Instructions 158 159(define_insn "mul<mode>3" 160 [(set (match_operand:CRXIM 0 "register_operand" "=r,r") 161 (mult:CRXIM (match_operand:CRXIM 1 "register_operand" "%0,0") 162 (match_operand:CRXIM 2 "nonmemory_operand" "r,i"))) 163 (clobber (reg:CC CC_REGNUM))] 164 "" 165 "mul<tIsa>\t%2, %0" 166 [(set_attr "length" "2,<lImmArith>")] 167) 168 169;; Widening-multiplication Instructions 170 171(define_insn "<sIsa>mulsidi3" 172 [(set (match_operand:DI 0 "register_operand" "=k") 173 (mult:DI (sz_xtnd:DI (match_operand:SI 1 "register_operand" "%r")) 174 (sz_xtnd:DI (match_operand:SI 2 "register_operand" "r")))) 175 (clobber (reg:CC CC_REGNUM))] 176 "" 177 "mull<sPat>d\t%2, %1" 178 [(set_attr "length" "4")] 179) 180 181(define_insn "<sIsa>mulhisi3" 182 [(set (match_operand:SI 0 "register_operand" "=r") 183 (mult:SI (sz_xtnd:SI (match_operand:HI 1 "register_operand" "%0")) 184 (sz_xtnd:SI (match_operand:HI 2 "register_operand" "r")))) 185 (clobber (reg:CC CC_REGNUM))] 186 "" 187 "mul<sPat>wd\t%2, %0" 188 [(set_attr "length" "4")] 189) 190 191(define_insn "<sIsa>mulqihi3" 192 [(set (match_operand:HI 0 "register_operand" "=r") 193 (mult:HI (sz_xtnd:HI (match_operand:QI 1 "register_operand" "%0")) 194 (sz_xtnd:HI (match_operand:QI 2 "register_operand" "r")))) 195 (clobber (reg:CC CC_REGNUM))] 196 "" 197 "mul<sPat>bw\t%2, %0" 198 [(set_attr "length" "4")] 199) 200 201;; Logical Instructions - and 202 203(define_insn "and<mode>3" 204 [(set (match_operand:CRXIM 0 "register_operand" "=r,r") 205 (and:CRXIM (match_operand:CRXIM 1 "register_operand" "%0,0") 206 (match_operand:CRXIM 2 "nonmemory_operand" "r,i"))) 207 (clobber (reg:CC CC_REGNUM))] 208 "" 209 "and<tIsa>\t%2, %0" 210 [(set_attr "length" "2,<lImmArith>")] 211) 212 213;; Logical Instructions - or 214 215(define_insn "ior<mode>3" 216 [(set (match_operand:CRXIM 0 "register_operand" "=r,r") 217 (ior:CRXIM (match_operand:CRXIM 1 "register_operand" "%0,0") 218 (match_operand:CRXIM 2 "nonmemory_operand" "r,i"))) 219 (clobber (reg:CC CC_REGNUM))] 220 "" 221 "or<tIsa>\t%2, %0" 222 [(set_attr "length" "2,<lImmArith>")] 223) 224 225;; Logical Instructions - xor 226 227(define_insn "xor<mode>3" 228 [(set (match_operand:CRXIM 0 "register_operand" "=r,r") 229 (xor:CRXIM (match_operand:CRXIM 1 "register_operand" "%0,0") 230 (match_operand:CRXIM 2 "nonmemory_operand" "r,i"))) 231 (clobber (reg:CC CC_REGNUM))] 232 "" 233 "xor<tIsa>\t%2, %0" 234 [(set_attr "length" "2,<lImmArith>")] 235) 236 237;; Sign and Zero Extend Instructions 238 239(define_insn "<szPat>extendhisi2" 240 [(set (match_operand:SI 0 "register_operand" "=r") 241 (sz_xtnd:SI (match_operand:HI 1 "register_operand" "r"))) 242 (clobber (reg:CC CC_REGNUM))] 243 "" 244 "<szIsa>extwd\t%1, %0" 245 [(set_attr "length" "4")] 246) 247 248(define_insn "<szPat>extendqisi2" 249 [(set (match_operand:SI 0 "register_operand" "=r") 250 (sz_xtnd:SI (match_operand:QI 1 "register_operand" "r"))) 251 (clobber (reg:CC CC_REGNUM))] 252 "" 253 "<szIsa>extbd\t%1, %0" 254 [(set_attr "length" "4")] 255) 256 257(define_insn "<szPat>extendqihi2" 258 [(set (match_operand:HI 0 "register_operand" "=r") 259 (sz_xtnd:HI (match_operand:QI 1 "register_operand" "r"))) 260 (clobber (reg:CC CC_REGNUM))] 261 "" 262 "<szIsa>extbw\t%1, %0" 263 [(set_attr "length" "4")] 264) 265 266;; Negation Instructions 267 268(define_insn "neg<mode>2" 269 [(set (match_operand:CRXIM 0 "register_operand" "=r") 270 (neg:CRXIM (match_operand:CRXIM 1 "register_operand" "r"))) 271 (clobber (reg:CC CC_REGNUM))] 272 "" 273 "neg<tIsa>\t%1, %0" 274 [(set_attr "length" "4")] 275) 276 277;; Absolute Instructions 278 279(define_insn "abs<mode>2" 280 [(set (match_operand:CRXIM 0 "register_operand" "=r") 281 (abs:CRXIM (match_operand:CRXIM 1 "register_operand" "r"))) 282 (clobber (reg:CC CC_REGNUM))] 283 "" 284 "abs<tIsa>\t%1, %0" 285 [(set_attr "length" "4")] 286) 287 288;; Max and Min Instructions 289 290(define_insn "<code><mode>3" 291 [(set (match_operand:CRXIM 0 "register_operand" "=r") 292 (mima_oprnd:CRXIM (match_operand:CRXIM 1 "register_operand" "%0") 293 (match_operand:CRXIM 2 "register_operand" "r")))] 294 "" 295 "<mimaIsa><tIsa>\t%2, %0" 296 [(set_attr "length" "4")] 297) 298 299;; One's Complement 300 301(define_insn "one_cmpl<mode>2" 302 [(set (match_operand:CRXIM 0 "register_operand" "=r") 303 (not:CRXIM (match_operand:CRXIM 1 "register_operand" "0"))) 304 (clobber (reg:CC CC_REGNUM))] 305 "" 306 "xor<tIsa>\t$-1, %0" 307 [(set_attr "length" "2")] 308) 309 310;; Rotate Instructions 311 312(define_insn "rotl<mode>3" 313 [(set (match_operand:CRXIM 0 "register_operand" "=r,r") 314 (rotate:CRXIM (match_operand:CRXIM 1 "register_operand" "0,0") 315 (match_operand:CRXIM 2 "nonmemory_operand" "r,<IJK>"))) 316 (clobber (reg:CC CC_REGNUM))] 317 "" 318 "@ 319 rotl<tIsa>\t%2, %0 320 rot<tIsa>\t%2, %0" 321 [(set_attr "length" "4,<lImmRotl>")] 322) 323 324(define_insn "rotr<mode>3" 325 [(set (match_operand:CRXIM 0 "register_operand" "=r") 326 (rotatert:CRXIM (match_operand:CRXIM 1 "register_operand" "0") 327 (match_operand:CRXIM 2 "register_operand" "r"))) 328 (clobber (reg:CC CC_REGNUM))] 329 "" 330 "rotr<tIsa>\t%2, %0" 331 [(set_attr "length" "4")] 332) 333 334;; Arithmetic Left and Right Shift Instructions 335 336(define_insn "<shPat><mode>3" 337 [(set (match_operand:CRXIM 0 "register_operand" "=r,r") 338 (sh_oprnd:CRXIM (match_operand:CRXIM 1 "register_operand" "0,0") 339 (match_operand:QI 2 "nonmemory_operand" "r,<IJK>"))) 340 (clobber (reg:CC CC_REGNUM))] 341 "" 342 "s<shIsa><tIsa>\t%2, %0" 343 [(set_attr "length" "2,2")] 344) 345 346;; Bit Set Instructions 347 348(define_insn "extv" 349 [(set (match_operand:SI 0 "register_operand" "=r") 350 (sign_extract:SI (match_operand:SI 1 "register_operand" "r") 351 (match_operand:SI 2 "const_int_operand" "n") 352 (match_operand:SI 3 "const_int_operand" "n")))] 353 "" 354 { 355 static char buf[100]; 356 int strpntr; 357 int size = INTVAL (operands[2]); 358 int pos = INTVAL (operands[3]); 359 strpntr = sprintf (buf, "ram\t$%d, $31, $%d, %%1, %%0\;", 360 BITS_PER_WORD - (size + pos), BITS_PER_WORD - size); 361 sprintf (buf + strpntr, "srad\t$%d, %%0", BITS_PER_WORD - size); 362 return buf; 363 } 364 [(set_attr "length" "6")] 365) 366 367(define_insn "extzv" 368 [(set (match_operand:SI 0 "register_operand" "=r") 369 (zero_extract:SI (match_operand:SI 1 "register_operand" "r") 370 (match_operand:SI 2 "const_int_operand" "n") 371 (match_operand:SI 3 "const_int_operand" "n")))] 372 "" 373 { 374 static char buf[40]; 375 int size = INTVAL (operands[2]); 376 int pos = INTVAL (operands[3]); 377 sprintf (buf, "ram\t$%d, $%d, $0, %%1, %%0", 378 (BITS_PER_WORD - pos) % BITS_PER_WORD, size - 1); 379 return buf; 380 } 381 [(set_attr "length" "4")] 382) 383 384(define_insn "insv" 385 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") 386 (match_operand:SI 1 "const_int_operand" "n") 387 (match_operand:SI 2 "const_int_operand" "n")) 388 (match_operand:SI 3 "register_operand" "r"))] 389 "" 390 { 391 static char buf[40]; 392 int size = INTVAL (operands[1]); 393 int pos = INTVAL (operands[2]); 394 sprintf (buf, "rim\t$%d, $%d, $%d, %%3, %%0", 395 pos, size + pos - 1, pos); 396 return buf; 397 } 398 [(set_attr "length" "4")] 399) 400 401;; Move Instructions 402 403(define_expand "mov<mode>" 404 [(set (match_operand:ALLMT 0 "nonimmediate_operand" "") 405 (match_operand:ALLMT 1 "general_operand" ""))] 406 "" 407 { 408 if (!(reload_in_progress || reload_completed)) 409 { 410 if (!register_operand (operands[0], <MODE>mode)) 411 { 412 if (push_operand (operands[0], <MODE>mode) ? 413 !nosp_reg_operand (operands[1], <MODE>mode) : 414 !reg_or_u4bits_operand (operands[1], <MODE>mode)) 415 { 416 operands[1] = copy_to_mode_reg (<MODE>mode, operands[1]); 417 } 418 } 419 } 420 } 421) 422 423(define_insn "push<mode>_internal" 424 [(set (match_operand:ALLMT 0 "push_operand" "=<pushCnstr>") 425 (match_operand:ALLMT 1 "nosp_reg_operand" "b"))] 426 "" 427 "push\t<tpush>%p1" 428 [(set_attr "length" "<lpush>")] 429) 430 431(define_insn "mov<mode>_regs" 432 [(set (match_operand:SISFM 0 "register_operand" "=r, r, r, k") 433 (match_operand:SISFM 1 "nonmemory_operand" "r, <iF>, k, r"))] 434 "" 435 "@ 436 movd\t%1, %0 437 movd\t%1, %0 438 mfpr\t%1, %0 439 mtpr\t%1, %0" 440 [(set_attr "length" "2,6,4,4")] 441) 442 443(define_insn "mov<mode>_regs" 444 [(set (match_operand:DIDFM 0 "register_operand" "=r, r, r, k") 445 (match_operand:DIDFM 1 "nonmemory_operand" "r, <iF>, k, r"))] 446 "" 447 { 448 switch (which_alternative) 449 { 450 case 0: if (REGNO (operands[0]) > REGNO (operands[1])) 451 return "movd\t%H1, %H0\;movd\t%L1, %L0"; 452 else 453 return "movd\t%L1, %L0\;movd\t%H1, %H0"; 454 case 1: return "movd\t%H1, %H0\;movd\t%L1, %L0"; 455 case 2: return "mfpr\t%H1, %H0\;mfpr\t%L1, %L0"; 456 case 3: return "mtpr\t%H1, %H0\;mtpr\t%L1, %L0"; 457 default: gcc_unreachable (); 458 } 459 } 460 [(set_attr "length" "4,12,8,8")] 461) 462 463(define_insn "mov<mode>_regs" ; no HI/QI mode in HILO regs 464 [(set (match_operand:SHORT 0 "register_operand" "=r, r") 465 (match_operand:SHORT 1 "nonmemory_operand" "r, i"))] 466 "" 467 "mov<tIsa>\t%1, %0" 468 [(set_attr "length" "2,<lImmArith>")] 469) 470 471(define_insn "mov<mode>_load" 472 [(set (match_operand:CRXMM 0 "register_operand" "=r") 473 (match_operand:CRXMM 1 "memory_operand" "m"))] 474 "" 475 "load<tIsa>\t%1, %0" 476 [(set_attr "length" "6")] 477) 478 479(define_insn "mov<mode>_load" 480 [(set (match_operand:DIDFM 0 "register_operand" "=r") 481 (match_operand:DIDFM 1 "memory_operand" "m"))] 482 "" 483 { 484 rtx first_dest_reg = gen_rtx_REG (SImode, REGNO (operands[0])); 485 if (reg_overlap_mentioned_p (first_dest_reg, operands[1])) 486 return "loadd\t%H1, %H0\;loadd\t%L1, %L0"; 487 return "loadd\t%L1, %L0\;loadd\t%H1, %H0"; 488 } 489 [(set_attr "length" "12")] 490) 491 492(define_insn "mov<mode>_store" 493 [(set (match_operand:CRXMM 0 "store_operand" "=m, m") 494 (match_operand:CRXMM 1 "reg_or_u4bits_operand" "r, <JG>"))] 495 "" 496 "stor<tIsa>\t%1, %0" 497 [(set_attr "length" "6")] 498) 499 500(define_insn "mov<mode>_store" 501 [(set (match_operand:DIDFM 0 "store_operand" "=m, m") 502 (match_operand:DIDFM 1 "reg_or_u4bits_operand" "r, <JG>"))] 503 "" 504 "stord\t%H1, %H0\;stord\t%L1, %L0" 505 [(set_attr "length" "12")] 506) 507 508;; Movmem Instruction 509 510(define_expand "movmemsi" 511 [(use (match_operand:BLK 0 "memory_operand" "")) 512 (use (match_operand:BLK 1 "memory_operand" "")) 513 (use (match_operand:SI 2 "nonmemory_operand" "")) 514 (use (match_operand:SI 3 "const_int_operand" ""))] 515 "" 516 { 517 if (crx_expand_movmem (operands[0], operands[1], operands[2], operands[3])) 518 DONE; 519 else 520 FAIL; 521 } 522) 523 524;; Compare and Branch Instructions 525 526(define_insn "cbranch<mode>4" 527 [(set (pc) 528 (if_then_else (match_operator 0 "comparison_operator" 529 [(match_operand:CRXIM 1 "register_operand" "r") 530 (match_operand:CRXIM 2 "reg_or_cst4_operand" "rL")]) 531 (label_ref (match_operand 3 "" "")) 532 (pc))) 533 (clobber (reg:CC CC_REGNUM))] 534 "" 535 "cmpb%d0<tIsa>\t%2, %1, %l3" 536 [(set_attr "length" "6")] 537) 538 539;; Compare Instructions 540 541(define_expand "cmp<mode>" 542 [(set (reg:CC CC_REGNUM) 543 (compare:CC (match_operand:CRXIM 0 "register_operand" "") 544 (match_operand:CRXIM 1 "nonmemory_operand" "")))] 545 "" 546 { 547 crx_compare_op0 = operands[0]; 548 crx_compare_op1 = operands[1]; 549 DONE; 550 } 551) 552 553(define_insn "cmp<mode>_internal" 554 [(set (reg:CC CC_REGNUM) 555 (compare:CC (match_operand:CRXIM 0 "register_operand" "r,r") 556 (match_operand:CRXIM 1 "nonmemory_operand" "r,i")))] 557 "" 558 "cmp<tIsa>\t%1, %0" 559 [(set_attr "length" "2,<lImmArith>")] 560) 561 562;; Conditional Branch Instructions 563 564(define_expand "b<code>" 565 [(set (pc) 566 (if_then_else (any_cond (reg:CC CC_REGNUM) 567 (const_int 0)) 568 (label_ref (match_operand 0 "")) 569 (pc)))] 570 "" 571 { 572 crx_expand_branch (<CODE>, operands[0]); 573 DONE; 574 } 575) 576 577(define_insn "bCOND_internal" 578 [(set (pc) 579 (if_then_else (match_operator 0 "comparison_operator" 580 [(reg:CC CC_REGNUM) 581 (const_int 0)]) 582 (label_ref (match_operand 1 "")) 583 (pc)))] 584 "" 585 "b%d0\t%l1" 586 [(set_attr "length" "6")] 587) 588 589;; Scond Instructions 590 591(define_expand "s<code>" 592 [(set (match_operand:SI 0 "register_operand") 593 (any_cond:SI (reg:CC CC_REGNUM) (const_int 0)))] 594 "" 595 { 596 crx_expand_scond (<CODE>, operands[0]); 597 DONE; 598 } 599) 600 601(define_insn "sCOND_internal" 602 [(set (match_operand:SI 0 "register_operand" "=r") 603 (match_operator:SI 1 "comparison_operator" 604 [(reg:CC CC_REGNUM) (const_int 0)]))] 605 "" 606 "s%d1\t%0" 607 [(set_attr "length" "2")] 608) 609 610;; Jumps and Branches 611 612(define_insn "indirect_jump_return" 613 [(parallel 614 [(set (pc) 615 (reg:SI RA_REGNUM)) 616 (return)]) 617 ] 618 "reload_completed" 619 "jump\tra" 620 [(set_attr "length" "2")] 621) 622 623(define_insn "indirect_jump" 624 [(set (pc) 625 (match_operand:SI 0 "reg_or_sym_operand" "r,i"))] 626 "" 627 "@ 628 jump\t%0 629 br\t%a0" 630 [(set_attr "length" "2,6")] 631) 632 633(define_insn "interrupt_return" 634 [(parallel 635 [(unspec_volatile [(const_int 0)] 0) 636 (return)])] 637 "" 638 { 639 return crx_prepare_push_pop_string (1); 640 } 641 [(set_attr "length" "14")] 642) 643 644(define_insn "jump_to_imm" 645 [(set (pc) 646 (match_operand 0 "immediate_operand" "i"))] 647 "" 648 "br\t%c0" 649 [(set_attr "length" "6")] 650) 651 652(define_insn "jump" 653 [(set (pc) 654 (label_ref (match_operand 0 "" "")))] 655 "" 656 "br\t%l0" 657 [(set_attr "length" "6")] 658) 659 660;; Function Prologue and Epilogue 661 662(define_expand "prologue" 663 [(const_int 0)] 664 "" 665 { 666 crx_expand_prologue (); 667 DONE; 668 } 669) 670 671(define_insn "push_for_prologue" 672 [(parallel 673 [(set (reg:SI SP_REGNUM) 674 (minus:SI (reg:SI SP_REGNUM) 675 (match_operand:SI 0 "immediate_operand" "i")))])] 676 "reload_completed" 677 { 678 return crx_prepare_push_pop_string (0); 679 } 680 [(set_attr "length" "4")] 681) 682 683(define_expand "epilogue" 684 [(return)] 685 "" 686 { 687 crx_expand_epilogue (); 688 DONE; 689 } 690) 691 692(define_insn "pop_and_popret_return" 693 [(parallel 694 [(set (reg:SI SP_REGNUM) 695 (plus:SI (reg:SI SP_REGNUM) 696 (match_operand:SI 0 "immediate_operand" "i"))) 697 (use (reg:SI RA_REGNUM)) 698 (return)]) 699 ] 700 "reload_completed" 701 { 702 return crx_prepare_push_pop_string (1); 703 } 704 [(set_attr "length" "4")] 705) 706 707(define_insn "popret_RA_return" 708 [(parallel 709 [(use (reg:SI RA_REGNUM)) 710 (return)]) 711 ] 712 "reload_completed" 713 "popret\tra" 714 [(set_attr "length" "2")] 715) 716 717;; Table Jump 718 719(define_insn "tablejump" 720 [(set (pc) 721 (match_operand:SI 0 "register_operand" "r")) 722 (use (label_ref:SI (match_operand 1 "" "" )))] 723 "" 724 "jump\t%0" 725 [(set_attr "length" "2")] 726) 727 728;; Call Instructions 729 730(define_expand "call" 731 [(call (match_operand:QI 0 "memory_operand" "") 732 (match_operand 1 "" ""))] 733 "" 734 { 735 emit_call_insn (gen_crx_call (operands[0], operands[1])); 736 DONE; 737 } 738) 739 740(define_expand "crx_call" 741 [(parallel 742 [(call (match_operand:QI 0 "memory_operand" "") 743 (match_operand 1 "" "")) 744 (clobber (reg:SI RA_REGNUM))])] 745 "" 746 "" 747) 748 749(define_insn "crx_call_insn_branch" 750 [(call (mem:QI (match_operand:SI 0 "immediate_operand" "i")) 751 (match_operand 1 "" "")) 752 (clobber (match_operand:SI 2 "register_operand" "+r"))] 753 "" 754 "bal\tra, %a0" 755 [(set_attr "length" "6")] 756) 757 758(define_insn "crx_call_insn_jump" 759 [(call (mem:QI (match_operand:SI 0 "register_operand" "r")) 760 (match_operand 1 "" "")) 761 (clobber (match_operand:SI 2 "register_operand" "+r"))] 762 "" 763 "jal\t%0" 764 [(set_attr "length" "2")] 765) 766 767(define_insn "crx_call_insn_jalid" 768 [(call (mem:QI (mem:SI (plus:SI 769 (match_operand:SI 0 "register_operand" "r") 770 (match_operand:SI 1 "register_operand" "r")))) 771 (match_operand 2 "" "")) 772 (clobber (match_operand:SI 3 "register_operand" "+r"))] 773 "" 774 "jalid\t%0, %1" 775 [(set_attr "length" "4")] 776) 777 778;; Call Value Instructions 779 780(define_expand "call_value" 781 [(set (match_operand 0 "general_operand" "") 782 (call (match_operand:QI 1 "memory_operand" "") 783 (match_operand 2 "" "")))] 784 "" 785 { 786 emit_call_insn (gen_crx_call_value (operands[0], operands[1], operands[2])); 787 DONE; 788 } 789) 790 791(define_expand "crx_call_value" 792 [(parallel 793 [(set (match_operand 0 "general_operand" "") 794 (call (match_operand 1 "memory_operand" "") 795 (match_operand 2 "" ""))) 796 (clobber (reg:SI RA_REGNUM))])] 797 "" 798 "" 799) 800 801(define_insn "crx_call_value_insn_branch" 802 [(set (match_operand 0 "" "=g") 803 (call (mem:QI (match_operand:SI 1 "immediate_operand" "i")) 804 (match_operand 2 "" ""))) 805 (clobber (match_operand:SI 3 "register_operand" "+r"))] 806 "" 807 "bal\tra, %a1" 808 [(set_attr "length" "6")] 809) 810 811(define_insn "crx_call_value_insn_jump" 812 [(set (match_operand 0 "" "=g") 813 (call (mem:QI (match_operand:SI 1 "register_operand" "r")) 814 (match_operand 2 "" ""))) 815 (clobber (match_operand:SI 3 "register_operand" "+r"))] 816 "" 817 "jal\t%1" 818 [(set_attr "length" "2")] 819) 820 821(define_insn "crx_call_value_insn_jalid" 822 [(set (match_operand 0 "" "=g") 823 (call (mem:QI (mem:SI (plus:SI 824 (match_operand:SI 1 "register_operand" "r") 825 (match_operand:SI 2 "register_operand" "r")))) 826 (match_operand 3 "" ""))) 827 (clobber (match_operand:SI 4 "register_operand" "+r"))] 828 "" 829 "jalid\t%0, %1" 830 [(set_attr "length" "4")] 831) 832 833;; Nop 834 835(define_insn "nop" 836 [(const_int 0)] 837 "" 838 "" 839) 840 841;; Multiply and Accumulate Instructions 842 843(define_insn "<sPat>madsidi3" 844 [(set (match_operand:DI 0 "register_operand" "+k") 845 (plus:DI 846 (mult:DI (sz_xtnd:DI (match_operand:SI 1 "register_operand" "%r")) 847 (sz_xtnd:DI (match_operand:SI 2 "register_operand" "r"))) 848 (match_dup 0))) 849 (clobber (reg:CC CC_REGNUM))] 850 "TARGET_MAC" 851 "mac<sPat>d\t%2, %1" 852 [(set_attr "length" "4")] 853) 854 855(define_insn "<sPat>madhisi3" 856 [(set (match_operand:SI 0 "register_operand" "+l") 857 (plus:SI 858 (mult:SI (sz_xtnd:SI (match_operand:HI 1 "register_operand" "%r")) 859 (sz_xtnd:SI (match_operand:HI 2 "register_operand" "r"))) 860 (match_dup 0))) 861 (clobber (reg:CC CC_REGNUM))] 862 "TARGET_MAC" 863 "mac<sPat>w\t%2, %1" 864 [(set_attr "length" "4")] 865) 866 867(define_insn "<sPat>madqihi3" 868 [(set (match_operand:HI 0 "register_operand" "+l") 869 (plus:HI 870 (mult:HI (sz_xtnd:HI (match_operand:QI 1 "register_operand" "%r")) 871 (sz_xtnd:HI (match_operand:QI 2 "register_operand" "r"))) 872 (match_dup 0))) 873 (clobber (reg:CC CC_REGNUM))] 874 "TARGET_MAC" 875 "mac<sPat>b\t%2, %1" 876 [(set_attr "length" "4")] 877) 878 879;; Loop Instructions 880 881(define_expand "doloop_end" 882 [(use (match_operand 0 "" "")) ; loop pseudo 883 (use (match_operand 1 "" "")) ; iterations; zero if unknown 884 (use (match_operand 2 "" "")) ; max iterations 885 (use (match_operand 3 "" "")) ; loop level 886 (use (match_operand 4 "" ""))] ; label 887 "" 888 { 889 if (INTVAL (operands[3]) > crx_loop_nesting) 890 FAIL; 891 switch (GET_MODE (operands[0])) 892 { 893 case SImode: 894 emit_jump_insn (gen_doloop_end_si (operands[4], operands[0])); 895 break; 896 case HImode: 897 emit_jump_insn (gen_doloop_end_hi (operands[4], operands[0])); 898 break; 899 case QImode: 900 emit_jump_insn (gen_doloop_end_qi (operands[4], operands[0])); 901 break; 902 default: 903 FAIL; 904 } 905 DONE; 906 } 907) 908 909; CRX dbnz[bwd] used explicitly (see above) but also by the combiner. 910 911(define_insn "doloop_end_<mode>" 912 [(set (pc) 913 (if_then_else (ne (match_operand:CRXIM 1 "register_operand" "+r,!m") 914 (const_int 1)) 915 (label_ref (match_operand 0 "" "")) 916 (pc))) 917 (set (match_dup 1) (plus:CRXIM (match_dup 1) (const_int -1))) 918 (clobber (match_scratch:CRXIM 2 "=X,r")) 919 (clobber (reg:CC CC_REGNUM))] 920 "" 921 "@ 922 dbnz<tIsa>\t%1, %l0 923 load<tIsa>\t%1, %2\;add<tIsa>\t$-1, %2\;stor<tIsa>\t%2, %1\;bne\t%l0" 924 [(set_attr "length" "6, 12")] 925) 926