1;; GCC machine description for NEC V850 2;; Copyright (C) 1996, 1997, 1998, 1999, 2002, 2004, 2005, 2007, 2008 3;; Free Software Foundation, Inc. 4;; Contributed by Jeff Law (law@cygnus.com). 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 3, 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 COPYING3. If not see 20;; <http://www.gnu.org/licenses/>. 21 22;; The original PO technology requires these to be ordered by speed, 23;; so that assigner will pick the fastest. 24 25;; See file "rtl.def" for documentation on define_insn, match_*, et. al. 26 27;; The V851 manual states that the instruction address space is 16M; 28;; the various branch/call instructions only have a 22bit offset (4M range). 29;; 30;; One day we'll probably need to handle calls to targets more than 4M 31;; away. 32 33;; The size of instructions in bytes. 34 35(define_attr "length" "" 36 (const_int 4)) 37 38(define_attr "long_calls" "yes,no" 39 (const (if_then_else (symbol_ref "TARGET_LONG_CALLS") 40 (const_string "yes") 41 (const_string "no")))) 42 43;; Types of instructions (for scheduling purposes). 44 45(define_attr "type" "load,mult,other" 46 (const_string "other")) 47 48;; Condition code settings. 49;; none - insn does not affect cc 50;; none_0hit - insn does not affect cc but it does modify operand 0 51;; This attribute is used to keep track of when operand 0 changes. 52;; See the description of NOTICE_UPDATE_CC for more info. 53;; set_znv - sets z,n,v to usable values; c is unknown. 54;; set_zn - sets z,n to usable values; v,c is unknown. 55;; compare - compare instruction 56;; clobber - value of cc is unknown 57(define_attr "cc" "none,none_0hit,set_zn,set_znv,compare,clobber" 58 (const_string "clobber")) 59 60;; Function units for the V850. As best as I can tell, there's 61;; a traditional memory load/use stall as well as a stall if 62;; the result of a multiply is used too early. 63 64(define_insn_reservation "v850_other" 1 65 (eq_attr "type" "other") 66 "nothing") 67(define_insn_reservation "v850_mult" 2 68 (eq_attr "type" "mult") 69 "nothing") 70(define_insn_reservation "v850_memory" 2 71 (eq_attr "type" "load") 72 "nothing") 73 74(include "predicates.md") 75 76;; ---------------------------------------------------------------------- 77;; MOVE INSTRUCTIONS 78;; ---------------------------------------------------------------------- 79 80;; movqi 81 82(define_expand "movqi" 83 [(set (match_operand:QI 0 "general_operand" "") 84 (match_operand:QI 1 "general_operand" ""))] 85 "" 86 " 87{ 88 /* One of the ops has to be in a register or 0 */ 89 if (!register_operand (operand0, QImode) 90 && !reg_or_0_operand (operand1, QImode)) 91 operands[1] = copy_to_mode_reg (QImode, operand1); 92}") 93 94(define_insn "*movqi_internal" 95 [(set (match_operand:QI 0 "general_operand" "=r,r,r,Q,r,m,m") 96 (match_operand:QI 1 "general_operand" "Jr,n,Q,Ir,m,r,I"))] 97 "register_operand (operands[0], QImode) 98 || reg_or_0_operand (operands[1], QImode)" 99 "* return output_move_single (operands);" 100 [(set_attr "length" "2,4,2,2,4,4,4") 101 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit") 102 (set_attr "type" "other,other,load,other,load,other,other")]) 103 104;; movhi 105 106(define_expand "movhi" 107 [(set (match_operand:HI 0 "general_operand" "") 108 (match_operand:HI 1 "general_operand" ""))] 109 "" 110 " 111{ 112 /* One of the ops has to be in a register or 0 */ 113 if (!register_operand (operand0, HImode) 114 && !reg_or_0_operand (operand1, HImode)) 115 operands[1] = copy_to_mode_reg (HImode, operand1); 116}") 117 118(define_insn "*movhi_internal" 119 [(set (match_operand:HI 0 "general_operand" "=r,r,r,Q,r,m,m") 120 (match_operand:HI 1 "general_operand" "Jr,n,Q,Ir,m,r,I"))] 121 "register_operand (operands[0], HImode) 122 || reg_or_0_operand (operands[1], HImode)" 123 "* return output_move_single (operands);" 124 [(set_attr "length" "2,4,2,2,4,4,4") 125 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit") 126 (set_attr "type" "other,other,load,other,load,other,other")]) 127 128;; movsi and helpers 129 130(define_insn "*movsi_high" 131 [(set (match_operand:SI 0 "register_operand" "=r") 132 (high:SI (match_operand 1 "" "")))] 133 "" 134 "movhi hi(%1),%.,%0" 135 [(set_attr "length" "4") 136 (set_attr "cc" "none_0hit") 137 (set_attr "type" "other")]) 138 139(define_insn "*movsi_lo" 140 [(set (match_operand:SI 0 "register_operand" "=r") 141 (lo_sum:SI (match_operand:SI 1 "register_operand" "r") 142 (match_operand:SI 2 "immediate_operand" "i")))] 143 "" 144 "movea lo(%2),%1,%0" 145 [(set_attr "length" "4") 146 (set_attr "cc" "none_0hit") 147 (set_attr "type" "other")]) 148 149(define_expand "movsi" 150 [(set (match_operand:SI 0 "general_operand" "") 151 (match_operand:SI 1 "general_operand" ""))] 152 "" 153 " 154{ 155 /* One of the ops has to be in a register or 0 */ 156 if (!register_operand (operand0, SImode) 157 && !reg_or_0_operand (operand1, SImode)) 158 operands[1] = copy_to_mode_reg (SImode, operand1); 159 160 /* Some constants, as well as symbolic operands 161 must be done with HIGH & LO_SUM patterns. */ 162 if (CONSTANT_P (operands[1]) 163 && GET_CODE (operands[1]) != HIGH 164 && ! TARGET_V850E 165 && !special_symbolref_operand (operands[1], VOIDmode) 166 && !(GET_CODE (operands[1]) == CONST_INT 167 && (CONST_OK_FOR_J (INTVAL (operands[1])) 168 || CONST_OK_FOR_K (INTVAL (operands[1])) 169 || CONST_OK_FOR_L (INTVAL (operands[1]))))) 170 { 171 rtx temp; 172 173 if (reload_in_progress || reload_completed) 174 temp = operands[0]; 175 else 176 temp = gen_reg_rtx (SImode); 177 178 emit_insn (gen_rtx_SET (SImode, temp, 179 gen_rtx_HIGH (SImode, operand1))); 180 emit_insn (gen_rtx_SET (SImode, operand0, 181 gen_rtx_LO_SUM (SImode, temp, operand1))); 182 DONE; 183 } 184}") 185 186;; This is the same as the following pattern, except that it includes 187;; support for arbitrary 32-bit immediates. 188 189;; ??? This always loads addresses using hilo. If the only use of this address 190;; was in a load/store, then we would get smaller code if we only loaded the 191;; upper part with hi, and then put the lower part in the load/store insn. 192 193(define_insn "*movsi_internal_v850e" 194 [(set (match_operand:SI 0 "general_operand" "=r,r,r,r,Q,r,r,m,m,r") 195 (match_operand:SI 1 "general_operand" "Jr,K,L,Q,Ir,m,R,r,I,i"))] 196 "TARGET_V850E 197 && (register_operand (operands[0], SImode) 198 || reg_or_0_operand (operands[1], SImode))" 199 "* return output_move_single (operands);" 200 [(set_attr "length" "2,4,4,2,2,4,4,4,4,6") 201 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit") 202 (set_attr "type" "other,other,other,load,other,load,other,other,other,other")]) 203 204(define_insn "*movsi_internal" 205 [(set (match_operand:SI 0 "general_operand" "=r,r,r,r,Q,r,r,m,m") 206 (match_operand:SI 1 "movsi_source_operand" "Jr,K,L,Q,Ir,m,R,r,I"))] 207 "register_operand (operands[0], SImode) 208 || reg_or_0_operand (operands[1], SImode)" 209 "* return output_move_single (operands);" 210 [(set_attr "length" "2,4,4,2,2,4,4,4,4") 211 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit") 212 (set_attr "type" "other,other,other,load,other,load,other,other,other")]) 213 214(define_insn "*movsf_internal" 215 [(set (match_operand:SF 0 "general_operand" "=r,r,r,r,r,Q,r,m,m,r") 216 (match_operand:SF 1 "general_operand" "Jr,K,L,n,Q,Ir,m,r,IG,iF"))] 217 "register_operand (operands[0], SFmode) 218 || reg_or_0_operand (operands[1], SFmode)" 219 "* return output_move_single (operands);" 220 [(set_attr "length" "2,4,4,8,2,2,4,4,4,8") 221 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit") 222 (set_attr "type" "other,other,other,other,load,other,load,other,other,other")]) 223 224 225;; ---------------------------------------------------------------------- 226;; TEST INSTRUCTIONS 227;; ---------------------------------------------------------------------- 228 229(define_insn "*v850_tst1" 230 [(set (cc0) 231 (compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "m") 232 (const_int 1) 233 (match_operand:QI 1 "const_int_operand" "n")) 234 (const_int 0)))] 235 "" 236 "tst1 %1,%0" 237 [(set_attr "length" "4") 238 (set_attr "cc" "clobber")]) 239 240;; This replaces ld.b;sar;andi with tst1;setf nz. 241 242(define_split 243 [(set (match_operand:SI 0 "register_operand" "") 244 (compare (zero_extract:SI (match_operand:QI 1 "memory_operand" "") 245 (const_int 1) 246 (match_operand 2 "const_int_operand" "")) 247 (const_int 0)))] 248 "" 249 [(set (cc0) (compare (zero_extract:SI (match_dup 1) 250 (const_int 1) 251 (match_dup 2)) 252 (const_int 0))) 253 (set (match_dup 0) (ne:SI (cc0) (const_int 0)))]) 254 255(define_expand "cbranchsi4" 256 [(set (cc0) 257 (compare (match_operand:SI 1 "register_operand" "") 258 (match_operand:SI 2 "reg_or_int5_operand" ""))) 259 (set (pc) 260 (if_then_else 261 (match_operator 0 "ordered_comparison_operator" [(cc0) 262 (const_int 0)]) 263 (label_ref (match_operand 3 "" "")) 264 (pc)))] 265 "") 266 267(define_expand "cstoresi4" 268 [(set (cc0) 269 (compare (match_operand:SI 2 "register_operand" "") 270 (match_operand:SI 3 "reg_or_int5_operand" ""))) 271 (set (match_operand:SI 0 "register_operand") 272 (match_operator:SI 1 "ordered_comparison_operator" [(cc0) 273 (const_int 0)]))] 274 "") 275 276(define_insn "*cmpsi" 277 [(set (cc0) 278 (compare (match_operand:SI 0 "register_operand" "r,r,r") 279 (match_operand:SI 1 "reg_or_int5_operand" "r,I,J")))] 280 "" 281 "@ 282 cmp %1,%0 283 cmp %.,%0 284 cmp %1,%0" 285 [(set_attr "length" "2,2,2") 286 (set_attr "cc" "compare,set_znv,compare")]) 287 288 289;; ---------------------------------------------------------------------- 290;; ADD INSTRUCTIONS 291;; ---------------------------------------------------------------------- 292 293(define_insn "addsi3" 294 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 295 (plus:SI (match_operand:SI 1 "register_operand" "%0,r,r") 296 (match_operand:SI 2 "nonmemory_operand" "rJ,K,U")))] 297 "" 298 "@ 299 add %2,%0 300 addi %2,%1,%0 301 addi %O2(%P2),%1,%0" 302 [(set_attr "length" "2,4,4") 303 (set_attr "cc" "set_zn,set_zn,set_zn")]) 304 305;; ---------------------------------------------------------------------- 306;; SUBTRACT INSTRUCTIONS 307;; ---------------------------------------------------------------------- 308 309(define_insn "subsi3" 310 [(set (match_operand:SI 0 "register_operand" "=r,r") 311 (minus:SI (match_operand:SI 1 "register_operand" "0,r") 312 (match_operand:SI 2 "register_operand" "r,0")))] 313 "" 314 "@ 315 sub %2,%0 316 subr %1,%0" 317 [(set_attr "length" "2,2") 318 (set_attr "cc" "set_zn")]) 319 320(define_insn "negsi2" 321 [(set (match_operand:SI 0 "register_operand" "=r") 322 (neg:SI (match_operand:SI 1 "register_operand" "0")))] 323 "" 324 "subr %.,%0" 325 [(set_attr "length" "2") 326 (set_attr "cc" "set_zn")]) 327 328;; ---------------------------------------------------------------------- 329;; MULTIPLY INSTRUCTIONS 330;; ---------------------------------------------------------------------- 331 332(define_expand "mulhisi3" 333 [(set (match_operand:SI 0 "register_operand" "") 334 (mult:SI 335 (sign_extend:SI (match_operand:HI 1 "register_operand" "")) 336 (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" ""))))] 337 "" 338 "if (GET_CODE (operands[2]) == CONST_INT) 339 { 340 emit_insn (gen_mulhisi3_internal2 (operands[0], operands[1], operands[2])); 341 DONE; 342 }") 343 344(define_insn "*mulhisi3_internal1" 345 [(set (match_operand:SI 0 "register_operand" "=r") 346 (mult:SI 347 (sign_extend:SI (match_operand:HI 1 "register_operand" "%0")) 348 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))] 349 "" 350 "mulh %2,%0" 351 [(set_attr "length" "2") 352 (set_attr "cc" "none_0hit") 353 (set_attr "type" "mult")]) 354 355(define_insn "mulhisi3_internal2" 356 [(set (match_operand:SI 0 "register_operand" "=r,r") 357 (mult:SI 358 (sign_extend:SI (match_operand:HI 1 "register_operand" "%0,r")) 359 (match_operand:HI 2 "const_int_operand" "J,K")))] 360 "" 361 "@ 362 mulh %2,%0 363 mulhi %2,%1,%0" 364 [(set_attr "length" "2,4") 365 (set_attr "cc" "none_0hit,none_0hit") 366 (set_attr "type" "mult")]) 367 368;; ??? The scheduling info is probably wrong. 369 370;; ??? This instruction can also generate the 32-bit highpart, but using it 371;; may increase code size counter to the desired result. 372 373;; ??? This instructions can also give a DImode result. 374 375;; ??? There is unsigned version, but it matters only for the DImode/highpart 376;; results. 377 378(define_insn "mulsi3" 379 [(set (match_operand:SI 0 "register_operand" "=r") 380 (mult:SI (match_operand:SI 1 "register_operand" "%0") 381 (match_operand:SI 2 "reg_or_int9_operand" "rO")))] 382 "TARGET_V850E" 383 "mul %2,%1,%." 384 [(set_attr "length" "4") 385 (set_attr "cc" "none_0hit") 386 (set_attr "type" "mult")]) 387 388;; ---------------------------------------------------------------------- 389;; DIVIDE INSTRUCTIONS 390;; ---------------------------------------------------------------------- 391 392;; ??? These insns do set the Z/N condition codes, except that they are based 393;; on only one of the two results, so it doesn't seem to make sense to use 394;; them. 395 396;; ??? The scheduling info is probably wrong. 397 398(define_insn "divmodsi4" 399 [(set (match_operand:SI 0 "register_operand" "=r") 400 (div:SI (match_operand:SI 1 "register_operand" "0") 401 (match_operand:SI 2 "register_operand" "r"))) 402 (set (match_operand:SI 3 "register_operand" "=r") 403 (mod:SI (match_dup 1) 404 (match_dup 2)))] 405 "TARGET_V850E" 406 "div %2,%0,%3" 407 [(set_attr "length" "4") 408 (set_attr "cc" "clobber") 409 (set_attr "type" "other")]) 410 411(define_insn "udivmodsi4" 412 [(set (match_operand:SI 0 "register_operand" "=r") 413 (udiv:SI (match_operand:SI 1 "register_operand" "0") 414 (match_operand:SI 2 "register_operand" "r"))) 415 (set (match_operand:SI 3 "register_operand" "=r") 416 (umod:SI (match_dup 1) 417 (match_dup 2)))] 418 "TARGET_V850E" 419 "divu %2,%0,%3" 420 [(set_attr "length" "4") 421 (set_attr "cc" "clobber") 422 (set_attr "type" "other")]) 423 424;; ??? There is a 2 byte instruction for generating only the quotient. 425;; However, it isn't clear how to compute the length field correctly. 426 427(define_insn "divmodhi4" 428 [(set (match_operand:HI 0 "register_operand" "=r") 429 (div:HI (match_operand:HI 1 "register_operand" "0") 430 (match_operand:HI 2 "register_operand" "r"))) 431 (set (match_operand:HI 3 "register_operand" "=r") 432 (mod:HI (match_dup 1) 433 (match_dup 2)))] 434 "TARGET_V850E" 435 "divh %2,%0,%3" 436 [(set_attr "length" "4") 437 (set_attr "cc" "clobber") 438 (set_attr "type" "other")]) 439 440;; Half-words are sign-extended by default, so we must zero extend to a word 441;; here before doing the divide. 442 443(define_insn "udivmodhi4" 444 [(set (match_operand:HI 0 "register_operand" "=r") 445 (udiv:HI (match_operand:HI 1 "register_operand" "0") 446 (match_operand:HI 2 "register_operand" "r"))) 447 (set (match_operand:HI 3 "register_operand" "=r") 448 (umod:HI (match_dup 1) 449 (match_dup 2)))] 450 "TARGET_V850E" 451 "zxh %0 ; divhu %2,%0,%3" 452 [(set_attr "length" "4") 453 (set_attr "cc" "clobber") 454 (set_attr "type" "other")]) 455 456;; ---------------------------------------------------------------------- 457;; AND INSTRUCTIONS 458;; ---------------------------------------------------------------------- 459 460(define_insn "*v850_clr1_1" 461 [(set (match_operand:QI 0 "memory_operand" "=m") 462 (subreg:QI 463 (and:SI (subreg:SI (match_dup 0) 0) 464 (match_operand:QI 1 "not_power_of_two_operand" "")) 0))] 465 "" 466 "* 467{ 468 rtx xoperands[2]; 469 xoperands[0] = operands[0]; 470 xoperands[1] = GEN_INT (~INTVAL (operands[1]) & 0xff); 471 output_asm_insn (\"clr1 %M1,%0\", xoperands); 472 return \"\"; 473}" 474 [(set_attr "length" "4") 475 (set_attr "cc" "clobber")]) 476 477(define_insn "*v850_clr1_2" 478 [(set (match_operand:HI 0 "indirect_operand" "=m") 479 (subreg:HI 480 (and:SI (subreg:SI (match_dup 0) 0) 481 (match_operand:HI 1 "not_power_of_two_operand" "")) 0))] 482 "" 483 "* 484{ 485 int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffff); 486 487 rtx xoperands[2]; 488 xoperands[0] = gen_rtx_MEM (QImode, 489 plus_constant (XEXP (operands[0], 0), log2 / 8)); 490 xoperands[1] = GEN_INT (log2 % 8); 491 output_asm_insn (\"clr1 %1,%0\", xoperands); 492 return \"\"; 493}" 494 [(set_attr "length" "4") 495 (set_attr "cc" "clobber")]) 496 497(define_insn "*v850_clr1_3" 498 [(set (match_operand:SI 0 "indirect_operand" "=m") 499 (and:SI (match_dup 0) 500 (match_operand:SI 1 "not_power_of_two_operand" "")))] 501 "" 502 "* 503{ 504 int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffffffff); 505 506 rtx xoperands[2]; 507 xoperands[0] = gen_rtx_MEM (QImode, 508 plus_constant (XEXP (operands[0], 0), log2 / 8)); 509 xoperands[1] = GEN_INT (log2 % 8); 510 output_asm_insn (\"clr1 %1,%0\", xoperands); 511 return \"\"; 512}" 513 [(set_attr "length" "4") 514 (set_attr "cc" "clobber")]) 515 516(define_insn "andsi3" 517 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 518 (and:SI (match_operand:SI 1 "register_operand" "%0,0,r") 519 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))] 520 "" 521 "@ 522 and %2,%0 523 and %.,%0 524 andi %2,%1,%0" 525 [(set_attr "length" "2,2,4") 526 (set_attr "cc" "set_znv")]) 527 528;; ---------------------------------------------------------------------- 529;; OR INSTRUCTIONS 530;; ---------------------------------------------------------------------- 531 532(define_insn "*v850_set1_1" 533 [(set (match_operand:QI 0 "memory_operand" "=m") 534 (subreg:QI (ior:SI (subreg:SI (match_dup 0) 0) 535 (match_operand 1 "power_of_two_operand" "")) 0))] 536 "" 537 "set1 %M1,%0" 538 [(set_attr "length" "4") 539 (set_attr "cc" "clobber")]) 540 541(define_insn "*v850_set1_2" 542 [(set (match_operand:HI 0 "indirect_operand" "=m") 543 (subreg:HI (ior:SI (subreg:SI (match_dup 0) 0) 544 (match_operand 1 "power_of_two_operand" "")) 0))] 545 "" 546 "* 547{ 548 int log2 = exact_log2 (INTVAL (operands[1])); 549 550 if (log2 < 8) 551 return \"set1 %M1,%0\"; 552 else 553 { 554 rtx xoperands[2]; 555 xoperands[0] = gen_rtx_MEM (QImode, 556 plus_constant (XEXP (operands[0], 0), 557 log2 / 8)); 558 xoperands[1] = GEN_INT (log2 % 8); 559 output_asm_insn (\"set1 %1,%0\", xoperands); 560 } 561 return \"\"; 562}" 563 [(set_attr "length" "4") 564 (set_attr "cc" "clobber")]) 565 566(define_insn "*v850_set1_3" 567 [(set (match_operand:SI 0 "indirect_operand" "=m") 568 (ior:SI (match_dup 0) 569 (match_operand 1 "power_of_two_operand" "")))] 570 "" 571 "* 572{ 573 int log2 = exact_log2 (INTVAL (operands[1])); 574 575 if (log2 < 8) 576 return \"set1 %M1,%0\"; 577 else 578 { 579 rtx xoperands[2]; 580 xoperands[0] = gen_rtx_MEM (QImode, 581 plus_constant (XEXP (operands[0], 0), 582 log2 / 8)); 583 xoperands[1] = GEN_INT (log2 % 8); 584 output_asm_insn (\"set1 %1,%0\", xoperands); 585 } 586 return \"\"; 587}" 588 [(set_attr "length" "4") 589 (set_attr "cc" "clobber")]) 590 591(define_insn "iorsi3" 592 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 593 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,r") 594 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))] 595 "" 596 "@ 597 or %2,%0 598 or %.,%0 599 ori %2,%1,%0" 600 [(set_attr "length" "2,2,4") 601 (set_attr "cc" "set_znv")]) 602 603;; ---------------------------------------------------------------------- 604;; XOR INSTRUCTIONS 605;; ---------------------------------------------------------------------- 606 607(define_insn "*v850_not1_1" 608 [(set (match_operand:QI 0 "memory_operand" "=m") 609 (subreg:QI (xor:SI (subreg:SI (match_dup 0) 0) 610 (match_operand 1 "power_of_two_operand" "")) 0))] 611 "" 612 "not1 %M1,%0" 613 [(set_attr "length" "4") 614 (set_attr "cc" "clobber")]) 615 616(define_insn "*v850_not1_2" 617 [(set (match_operand:HI 0 "indirect_operand" "=m") 618 (subreg:HI (xor:SI (subreg:SI (match_dup 0) 0) 619 (match_operand 1 "power_of_two_operand" "")) 0))] 620 "" 621 "* 622{ 623 int log2 = exact_log2 (INTVAL (operands[1])); 624 625 if (log2 < 8) 626 return \"not1 %M1,%0\"; 627 else 628 { 629 rtx xoperands[2]; 630 xoperands[0] = gen_rtx_MEM (QImode, 631 plus_constant (XEXP (operands[0], 0), 632 log2 / 8)); 633 xoperands[1] = GEN_INT (log2 % 8); 634 output_asm_insn (\"not1 %1,%0\", xoperands); 635 } 636 return \"\"; 637}" 638 [(set_attr "length" "4") 639 (set_attr "cc" "clobber")]) 640 641(define_insn "*v850_not1_3" 642 [(set (match_operand:SI 0 "indirect_operand" "=m") 643 (xor:SI (match_dup 0) 644 (match_operand 1 "power_of_two_operand" "")))] 645 "" 646 "* 647{ 648 int log2 = exact_log2 (INTVAL (operands[1])); 649 650 if (log2 < 8) 651 return \"not1 %M1,%0\"; 652 else 653 { 654 rtx xoperands[2]; 655 xoperands[0] = gen_rtx_MEM (QImode, 656 plus_constant (XEXP (operands[0], 0), 657 log2 / 8)); 658 xoperands[1] = GEN_INT (log2 % 8); 659 output_asm_insn (\"not1 %1,%0\", xoperands); 660 } 661 return \"\"; 662}" 663 [(set_attr "length" "4") 664 (set_attr "cc" "clobber")]) 665 666(define_insn "xorsi3" 667 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 668 (xor:SI (match_operand:SI 1 "register_operand" "%0,0,r") 669 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))] 670 "" 671 "@ 672 xor %2,%0 673 xor %.,%0 674 xori %2,%1,%0" 675 [(set_attr "length" "2,2,4") 676 (set_attr "cc" "set_znv")]) 677 678;; ---------------------------------------------------------------------- 679;; NOT INSTRUCTIONS 680;; ---------------------------------------------------------------------- 681 682(define_insn "one_cmplsi2" 683 [(set (match_operand:SI 0 "register_operand" "=r") 684 (not:SI (match_operand:SI 1 "register_operand" "r")))] 685 "" 686 "not %1,%0" 687 [(set_attr "length" "2") 688 (set_attr "cc" "set_znv")]) 689 690;; ----------------------------------------------------------------- 691;; BIT FIELDS 692;; ----------------------------------------------------------------- 693 694;; ??? Is it worth defining insv and extv for the V850 series?!? 695 696;; An insv pattern would be useful, but does not get used because 697;; store_bit_field never calls insv when storing a constant value into a 698;; single-bit bitfield. 699 700;; extv/extzv patterns would be useful, but do not get used because 701;; optimize_bitfield_compare in fold-const usually converts single 702;; bit extracts into an AND with a mask. 703 704;; ----------------------------------------------------------------- 705;; Scc INSTRUCTIONS 706;; ----------------------------------------------------------------- 707 708(define_insn "*setcc" 709 [(set (match_operand:SI 0 "register_operand" "=r") 710 (match_operator:SI 1 "comparison_operator" 711 [(cc0) (const_int 0)]))] 712 "" 713 "* 714{ 715 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0 716 && (GET_CODE (operands[1]) == GT 717 || GET_CODE (operands[1]) == GE 718 || GET_CODE (operands[1]) == LE 719 || GET_CODE (operands[1]) == LT)) 720 return 0; 721 722 return \"setf %c1,%0\"; 723}" 724 [(set_attr "length" "4") 725 (set_attr "cc" "none_0hit")]) 726 727;; ---------------------------------------------------------------------- 728;; CONDITIONAL MOVE INSTRUCTIONS 729;; ---------------------------------------------------------------------- 730 731;; Instructions using cc0 aren't allowed to have input reloads, so we must 732;; hide the fact that this instruction uses cc0. We do so by including the 733;; compare instruction inside it. 734 735(define_expand "movsicc" 736 [(set (match_operand:SI 0 "register_operand" "=r") 737 (if_then_else:SI 738 (match_operand 1 "comparison_operator") 739 (match_operand:SI 2 "reg_or_const_operand" "rJ") 740 (match_operand:SI 3 "reg_or_const_operand" "rI")))] 741 "TARGET_V850E" 742 " 743{ 744 if ( (GET_CODE (operands[2]) == CONST_INT 745 && GET_CODE (operands[3]) == CONST_INT)) 746 { 747 int o2 = INTVAL (operands[2]); 748 int o3 = INTVAL (operands[3]); 749 750 if (o2 == 1 && o3 == 0) 751 FAIL; /* setf */ 752 if (o3 == 1 && o2 == 0) 753 FAIL; /* setf */ 754 if (o2 == 0 && (o3 < -16 || o3 > 15) && exact_log2 (o3) >= 0) 755 FAIL; /* setf + shift */ 756 if (o3 == 0 && (o2 < -16 || o2 > 15) && exact_log2 (o2) >=0) 757 FAIL; /* setf + shift */ 758 if (o2 != 0) 759 operands[2] = copy_to_mode_reg (SImode, operands[2]); 760 if (o3 !=0 ) 761 operands[3] = copy_to_mode_reg (SImode, operands[3]); 762 } 763 else 764 { 765 if (GET_CODE (operands[2]) != REG) 766 operands[2] = copy_to_mode_reg (SImode,operands[2]); 767 if (GET_CODE (operands[3]) != REG) 768 operands[3] = copy_to_mode_reg (SImode, operands[3]); 769 } 770}") 771 772;; ??? Clobbering the condition codes is overkill. 773 774;; ??? We sometimes emit an unnecessary compare instruction because the 775;; condition codes may have already been set by an earlier instruction, 776;; but we have no code here to avoid the compare if it is unnecessary. 777 778(define_insn "*movsicc_normal" 779 [(set (match_operand:SI 0 "register_operand" "=r") 780 (if_then_else:SI 781 (match_operator 1 "comparison_operator" 782 [(match_operand:SI 4 "register_operand" "r") 783 (match_operand:SI 5 "reg_or_int5_operand" "rJ")]) 784 (match_operand:SI 2 "reg_or_int5_operand" "rJ") 785 (match_operand:SI 3 "reg_or_0_operand" "rI")))] 786 "TARGET_V850E" 787 "cmp %5,%4 ; cmov %c1,%2,%z3,%0" 788 [(set_attr "length" "6") 789 (set_attr "cc" "clobber")]) 790 791(define_insn "*movsicc_reversed" 792 [(set (match_operand:SI 0 "register_operand" "=r") 793 (if_then_else:SI 794 (match_operator 1 "comparison_operator" 795 [(match_operand:SI 4 "register_operand" "r") 796 (match_operand:SI 5 "reg_or_int5_operand" "rJ")]) 797 (match_operand:SI 2 "reg_or_0_operand" "rI") 798 (match_operand:SI 3 "reg_or_int5_operand" "rJ")))] 799 "TARGET_V850E" 800 "cmp %5,%4 ; cmov %C1,%3,%z2,%0" 801 [(set_attr "length" "6") 802 (set_attr "cc" "clobber")]) 803 804(define_insn "*movsicc_tst1" 805 [(set (match_operand:SI 0 "register_operand" "=r") 806 (if_then_else:SI 807 (match_operator 1 "comparison_operator" 808 [(zero_extract:SI 809 (match_operand:QI 2 "memory_operand" "m") 810 (const_int 1) 811 (match_operand 3 "const_int_operand" "n")) 812 (const_int 0)]) 813 (match_operand:SI 4 "reg_or_int5_operand" "rJ") 814 (match_operand:SI 5 "reg_or_0_operand" "rI")))] 815 "TARGET_V850E" 816 "tst1 %3,%2 ; cmov %c1,%4,%z5,%0" 817 [(set_attr "length" "8") 818 (set_attr "cc" "clobber")]) 819 820(define_insn "*movsicc_tst1_reversed" 821 [(set (match_operand:SI 0 "register_operand" "=r") 822 (if_then_else:SI 823 (match_operator 1 "comparison_operator" 824 [(zero_extract:SI 825 (match_operand:QI 2 "memory_operand" "m") 826 (const_int 1) 827 (match_operand 3 "const_int_operand" "n")) 828 (const_int 0)]) 829 (match_operand:SI 4 "reg_or_0_operand" "rI") 830 (match_operand:SI 5 "reg_or_int5_operand" "rJ")))] 831 "TARGET_V850E" 832 "tst1 %3,%2 ; cmov %C1,%5,%z4,%0" 833 [(set_attr "length" "8") 834 (set_attr "cc" "clobber")]) 835 836;; Matching for sasf requires combining 4 instructions, so we provide a 837;; dummy pattern to match the first 3, which will always be turned into the 838;; second pattern by subsequent combining. As above, we must include the 839;; comparison to avoid input reloads in an insn using cc0. 840 841(define_insn "*sasf_1" 842 [(set (match_operand:SI 0 "register_operand" "") 843 (ior:SI (match_operator 1 "comparison_operator" [(cc0) (const_int 0)]) 844 (ashift:SI (match_operand:SI 2 "register_operand" "") 845 (const_int 1))))] 846 "TARGET_V850E" 847 "* gcc_unreachable ();") 848 849(define_insn "*sasf_2" 850 [(set (match_operand:SI 0 "register_operand" "=r") 851 (ior:SI 852 (match_operator 1 "comparison_operator" 853 [(match_operand:SI 3 "register_operand" "r") 854 (match_operand:SI 4 "reg_or_int5_operand" "rJ")]) 855 (ashift:SI (match_operand:SI 2 "register_operand" "0") 856 (const_int 1))))] 857 "TARGET_V850E" 858 "cmp %4,%3 ; sasf %c1,%0" 859 [(set_attr "length" "6") 860 (set_attr "cc" "clobber")]) 861 862(define_split 863 [(set (match_operand:SI 0 "register_operand" "") 864 (if_then_else:SI 865 (match_operator 1 "comparison_operator" 866 [(match_operand:SI 4 "register_operand" "") 867 (match_operand:SI 5 "reg_or_int5_operand" "")]) 868 (match_operand:SI 2 "const_int_operand" "") 869 (match_operand:SI 3 "const_int_operand" "")))] 870 "TARGET_V850E 871 && ((INTVAL (operands[2]) ^ INTVAL (operands[3])) == 1) 872 && ((INTVAL (operands[2]) + INTVAL (operands[3])) != 1) 873 && (GET_CODE (operands[5]) == CONST_INT 874 || REGNO (operands[0]) != REGNO (operands[5])) 875 && REGNO (operands[0]) != REGNO (operands[4])" 876 [(set (match_dup 0) (match_dup 6)) 877 (set (match_dup 0) 878 (ior:SI (match_op_dup 7 [(match_dup 4) (match_dup 5)]) 879 (ashift:SI (match_dup 0) (const_int 1))))] 880 " 881{ 882 operands[6] = GEN_INT (INTVAL (operands[2]) >> 1); 883 if (INTVAL (operands[2]) & 0x1) 884 operands[7] = operands[1]; 885 else 886 operands[7] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[1])), 887 GET_MODE (operands[1]), 888 XEXP (operands[1], 0), XEXP (operands[1], 1)); 889}") 890;; --------------------------------------------------------------------- 891;; BYTE SWAP INSTRUCTIONS 892;; --------------------------------------------------------------------- 893 894(define_expand "rotlhi3" 895 [(set (match_operand:HI 0 "register_operand" "") 896 (rotate:HI (match_operand:HI 1 "register_operand" "") 897 (match_operand:HI 2 "const_int_operand" "")))] 898 "TARGET_V850E" 899 " 900{ 901 if (INTVAL (operands[2]) != 8) 902 FAIL; 903}") 904 905(define_insn "*rotlhi3_8" 906 [(set (match_operand:HI 0 "register_operand" "=r") 907 (rotate:HI (match_operand:HI 1 "register_operand" "r") 908 (const_int 8)))] 909 "TARGET_V850E" 910 "bsh %1,%0" 911 [(set_attr "length" "4") 912 (set_attr "cc" "clobber")]) 913 914(define_expand "rotlsi3" 915 [(set (match_operand:SI 0 "register_operand" "") 916 (rotate:SI (match_operand:SI 1 "register_operand" "") 917 (match_operand:SI 2 "const_int_operand" "")))] 918 "TARGET_V850E" 919 " 920{ 921 if (INTVAL (operands[2]) != 16) 922 FAIL; 923}") 924 925(define_insn "*rotlsi3_16" 926 [(set (match_operand:SI 0 "register_operand" "=r") 927 (rotate:SI (match_operand:SI 1 "register_operand" "r") 928 (const_int 16)))] 929 "TARGET_V850E" 930 "hsw %1,%0" 931 [(set_attr "length" "4") 932 (set_attr "cc" "clobber")]) 933 934;; ---------------------------------------------------------------------- 935;; JUMP INSTRUCTIONS 936;; ---------------------------------------------------------------------- 937 938;; Conditional jump instructions 939 940(define_insn "*branch_normal" 941 [(set (pc) 942 (if_then_else (match_operator 1 "comparison_operator" 943 [(cc0) (const_int 0)]) 944 (label_ref (match_operand 0 "" "")) 945 (pc)))] 946 "" 947 "* 948{ 949 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0 950 && (GET_CODE (operands[1]) == GT 951 || GET_CODE (operands[1]) == GE 952 || GET_CODE (operands[1]) == LE 953 || GET_CODE (operands[1]) == LT)) 954 return 0; 955 956 if (get_attr_length (insn) == 2) 957 return \"b%b1 %l0\"; 958 else 959 return \"b%B1 .+6 ; jr %l0\"; 960}" 961 [(set (attr "length") 962 (if_then_else (lt (abs (minus (match_dup 0) (pc))) 963 (const_int 256)) 964 (const_int 2) 965 (const_int 6))) 966 (set_attr "cc" "none")]) 967 968(define_insn "*branch_invert" 969 [(set (pc) 970 (if_then_else (match_operator 1 "comparison_operator" 971 [(cc0) (const_int 0)]) 972 (pc) 973 (label_ref (match_operand 0 "" ""))))] 974 "" 975 "* 976{ 977 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0 978 && (GET_CODE (operands[1]) == GT 979 || GET_CODE (operands[1]) == GE 980 || GET_CODE (operands[1]) == LE 981 || GET_CODE (operands[1]) == LT)) 982 return 0; 983 if (get_attr_length (insn) == 2) 984 return \"b%B1 %l0\"; 985 else 986 return \"b%b1 .+6 ; jr %l0\"; 987}" 988 [(set (attr "length") 989 (if_then_else (lt (abs (minus (match_dup 0) (pc))) 990 (const_int 256)) 991 (const_int 2) 992 (const_int 6))) 993 (set_attr "cc" "none")]) 994 995;; Unconditional and other jump instructions. 996 997(define_insn "jump" 998 [(set (pc) 999 (label_ref (match_operand 0 "" "")))] 1000 "" 1001 "* 1002{ 1003 if (get_attr_length (insn) == 2) 1004 return \"br %0\"; 1005 else 1006 return \"jr %0\"; 1007}" 1008 [(set (attr "length") 1009 (if_then_else (lt (abs (minus (match_dup 0) (pc))) 1010 (const_int 256)) 1011 (const_int 2) 1012 (const_int 4))) 1013 (set_attr "cc" "none")]) 1014 1015(define_insn "indirect_jump" 1016 [(set (pc) (match_operand:SI 0 "register_operand" "r"))] 1017 "" 1018 "jmp %0" 1019 [(set_attr "length" "2") 1020 (set_attr "cc" "none")]) 1021 1022(define_insn "tablejump" 1023 [(set (pc) (match_operand:SI 0 "register_operand" "r")) 1024 (use (label_ref (match_operand 1 "" "")))] 1025 "" 1026 "jmp %0" 1027 [(set_attr "length" "2") 1028 (set_attr "cc" "none")]) 1029 1030(define_insn "switch" 1031 [(set (pc) 1032 (plus:SI 1033 (sign_extend:SI 1034 (mem:HI 1035 (plus:SI (ashift:SI (match_operand:SI 0 "register_operand" "r") 1036 (const_int 1)) 1037 (label_ref (match_operand 1 "" ""))))) 1038 (label_ref (match_dup 1))))] 1039 "TARGET_V850E" 1040 "switch %0" 1041 [(set_attr "length" "2") 1042 (set_attr "cc" "none")]) 1043 1044(define_expand "casesi" 1045 [(match_operand:SI 0 "register_operand" "") 1046 (match_operand:SI 1 "register_operand" "") 1047 (match_operand:SI 2 "register_operand" "") 1048 (match_operand 3 "" "") (match_operand 4 "" "")] 1049 "" 1050 " 1051{ 1052 rtx reg = gen_reg_rtx (SImode); 1053 rtx tableaddress = gen_reg_rtx (SImode); 1054 rtx test; 1055 rtx mem; 1056 1057 /* Subtract the lower bound from the index. */ 1058 emit_insn (gen_subsi3 (reg, operands[0], operands[1])); 1059 1060 /* Compare the result against the number of table entries; 1061 branch to the default label if out of range of the table. */ 1062 test = gen_rtx_fmt_ee (GTU, VOIDmode, reg, operands[2]); 1063 emit_jump_insn (gen_cbranchsi4 (test, reg, operands[2], operands[4])); 1064 1065 /* Shift index for the table array access. */ 1066 emit_insn (gen_ashlsi3 (reg, reg, GEN_INT (TARGET_BIG_SWITCH ? 2 : 1))); 1067 /* Load the table address into a pseudo. */ 1068 emit_insn (gen_movsi (tableaddress, 1069 gen_rtx_LABEL_REF (Pmode, operands[3]))); 1070 /* Add the table address to the index. */ 1071 emit_insn (gen_addsi3 (reg, reg, tableaddress)); 1072 /* Load the table entry. */ 1073 mem = gen_const_mem (CASE_VECTOR_MODE, reg); 1074 if (! TARGET_BIG_SWITCH) 1075 { 1076 rtx reg2 = gen_reg_rtx (HImode); 1077 emit_insn (gen_movhi (reg2, mem)); 1078 emit_insn (gen_extendhisi2 (reg, reg2)); 1079 } 1080 else 1081 emit_insn (gen_movsi (reg, mem)); 1082 /* Add the table address. */ 1083 emit_insn (gen_addsi3 (reg, reg, tableaddress)); 1084 /* Branch to the switch label. */ 1085 emit_jump_insn (gen_tablejump (reg, operands[3])); 1086 DONE; 1087}") 1088 1089;; Call subroutine with no return value. 1090 1091(define_expand "call" 1092 [(call (match_operand:QI 0 "general_operand" "") 1093 (match_operand:SI 1 "general_operand" ""))] 1094 "" 1095 " 1096{ 1097 if (! call_address_operand (XEXP (operands[0], 0), QImode) 1098 || TARGET_LONG_CALLS) 1099 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0)); 1100 if (TARGET_LONG_CALLS) 1101 emit_call_insn (gen_call_internal_long (XEXP (operands[0], 0), operands[1])); 1102 else 1103 emit_call_insn (gen_call_internal_short (XEXP (operands[0], 0), operands[1])); 1104 1105 DONE; 1106}") 1107 1108(define_insn "call_internal_short" 1109 [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r")) 1110 (match_operand:SI 1 "general_operand" "g,g")) 1111 (clobber (reg:SI 31))] 1112 "! TARGET_LONG_CALLS" 1113 "@ 1114 jarl %0,r31 1115 jarl .+4,r31 ; add 4,r31 ; jmp %0" 1116 [(set_attr "length" "4,8")] 1117) 1118 1119(define_insn "call_internal_long" 1120 [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r")) 1121 (match_operand:SI 1 "general_operand" "g,g")) 1122 (clobber (reg:SI 31))] 1123 "TARGET_LONG_CALLS" 1124 "* 1125 { 1126 if (which_alternative == 0) 1127 { 1128 if (GET_CODE (operands[0]) == REG) 1129 return \"jarl %0,r31\"; 1130 else 1131 return \"movhi hi(%0), r0, r11 ; movea lo(%0), r11, r11 ; jarl .+4,r31 ; add 4, r31 ; jmp r11\"; 1132 } 1133 else 1134 return \"jarl .+4,r31 ; add 4,r31 ; jmp %0\"; 1135 }" 1136 [(set_attr "length" "16,8")] 1137) 1138 1139;; Call subroutine, returning value in operand 0 1140;; (which must be a hard register). 1141 1142(define_expand "call_value" 1143 [(set (match_operand 0 "" "") 1144 (call (match_operand:QI 1 "general_operand" "") 1145 (match_operand:SI 2 "general_operand" "")))] 1146 "" 1147 " 1148{ 1149 if (! call_address_operand (XEXP (operands[1], 0), QImode) 1150 || TARGET_LONG_CALLS) 1151 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0)); 1152 if (TARGET_LONG_CALLS) 1153 emit_call_insn (gen_call_value_internal_long (operands[0], 1154 XEXP (operands[1], 0), 1155 operands[2])); 1156 else 1157 emit_call_insn (gen_call_value_internal_short (operands[0], 1158 XEXP (operands[1], 0), 1159 operands[2])); 1160 DONE; 1161}") 1162 1163(define_insn "call_value_internal_short" 1164 [(set (match_operand 0 "" "=r,r") 1165 (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r")) 1166 (match_operand:SI 2 "general_operand" "g,g"))) 1167 (clobber (reg:SI 31))] 1168 "! TARGET_LONG_CALLS" 1169 "@ 1170 jarl %1,r31 1171 jarl .+4,r31 ; add 4,r31 ; jmp %1" 1172 [(set_attr "length" "4,8")] 1173) 1174 1175(define_insn "call_value_internal_long" 1176 [(set (match_operand 0 "" "=r,r") 1177 (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r")) 1178 (match_operand:SI 2 "general_operand" "g,g"))) 1179 (clobber (reg:SI 31))] 1180 "TARGET_LONG_CALLS" 1181 "* 1182 { 1183 if (which_alternative == 0) 1184 { 1185 if (GET_CODE (operands[1]) == REG) 1186 return \"jarl %1, r31\"; 1187 else 1188 /* Reload can generate this pattern.... */ 1189 return \"movhi hi(%1), r0, r11 ; movea lo(%1), r11, r11 ; jarl .+4, r31 ; add 4, r31 ; jmp r11\"; 1190 } 1191 else 1192 return \"jarl .+4, r31 ; add 4, r31 ; jmp %1\"; 1193 }" 1194 [(set_attr "length" "16,8")] 1195) 1196 1197(define_insn "nop" 1198 [(const_int 0)] 1199 "" 1200 "nop" 1201 [(set_attr "length" "2") 1202 (set_attr "cc" "none")]) 1203 1204;; ---------------------------------------------------------------------- 1205;; EXTEND INSTRUCTIONS 1206;; ---------------------------------------------------------------------- 1207 1208(define_insn "" 1209 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") 1210 (zero_extend:SI 1211 (match_operand:HI 1 "nonimmediate_operand" "0,r,T,m")))] 1212 "TARGET_V850E" 1213 "@ 1214 zxh %0 1215 andi 65535,%1,%0 1216 sld.hu %1,%0 1217 ld.hu %1,%0" 1218 [(set_attr "length" "2,4,2,4") 1219 (set_attr "cc" "none_0hit,set_znv,none_0hit,none_0hit")]) 1220 1221(define_insn "zero_extendhisi2" 1222 [(set (match_operand:SI 0 "register_operand" "=r") 1223 (zero_extend:SI 1224 (match_operand:HI 1 "register_operand" "r")))] 1225 "" 1226 "andi 65535,%1,%0" 1227 [(set_attr "length" "4") 1228 (set_attr "cc" "set_znv")]) 1229 1230(define_insn "" 1231 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") 1232 (zero_extend:SI 1233 (match_operand:QI 1 "nonimmediate_operand" "0,r,T,m")))] 1234 "TARGET_V850E" 1235 "@ 1236 zxb %0 1237 andi 255,%1,%0 1238 sld.bu %1,%0 1239 ld.bu %1,%0" 1240 [(set_attr "length" "2,4,2,4") 1241 (set_attr "cc" "none_0hit,set_znv,none_0hit,none_0hit")]) 1242 1243(define_insn "zero_extendqisi2" 1244 [(set (match_operand:SI 0 "register_operand" "=r") 1245 (zero_extend:SI 1246 (match_operand:QI 1 "register_operand" "r")))] 1247 "" 1248 "andi 255,%1,%0" 1249 [(set_attr "length" "4") 1250 (set_attr "cc" "set_znv")]) 1251 1252;;- sign extension instructions 1253 1254;; ??? The extendhisi2 pattern should not emit shifts for v850e? 1255 1256(define_insn "*extendhisi_insn" 1257 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 1258 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,Q,m")))] 1259 "TARGET_V850E" 1260 "@ 1261 sxh %0 1262 sld.h %1,%0 1263 ld.h %1,%0" 1264 [(set_attr "length" "2,2,4") 1265 (set_attr "cc" "none_0hit,none_0hit,none_0hit")]) 1266 1267;; ??? This is missing a sign extend from memory pattern to match the ld.h 1268;; instruction. 1269 1270(define_expand "extendhisi2" 1271 [(set (match_dup 2) 1272 (ashift:SI (match_operand:HI 1 "register_operand" "") 1273 (const_int 16))) 1274 (set (match_operand:SI 0 "register_operand" "") 1275 (ashiftrt:SI (match_dup 2) 1276 (const_int 16)))] 1277 "" 1278 " 1279{ 1280 operands[1] = gen_lowpart (SImode, operands[1]); 1281 operands[2] = gen_reg_rtx (SImode); 1282}") 1283 1284;; ??? The extendqisi2 pattern should not emit shifts for v850e? 1285 1286(define_insn "*extendqisi_insn" 1287 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 1288 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,Q,m")))] 1289 "TARGET_V850E" 1290 "@ 1291 sxb %0 1292 sld.b %1,%0 1293 ld.b %1,%0" 1294 [(set_attr "length" "2,2,4") 1295 (set_attr "cc" "none_0hit,none_0hit,none_0hit")]) 1296 1297;; ??? This is missing a sign extend from memory pattern to match the ld.b 1298;; instruction. 1299 1300(define_expand "extendqisi2" 1301 [(set (match_dup 2) 1302 (ashift:SI (match_operand:QI 1 "register_operand" "") 1303 (const_int 24))) 1304 (set (match_operand:SI 0 "register_operand" "") 1305 (ashiftrt:SI (match_dup 2) 1306 (const_int 24)))] 1307 "" 1308 " 1309{ 1310 operands[1] = gen_lowpart (SImode, operands[1]); 1311 operands[2] = gen_reg_rtx (SImode); 1312}") 1313 1314;; ---------------------------------------------------------------------- 1315;; SHIFTS 1316;; ---------------------------------------------------------------------- 1317 1318(define_insn "ashlsi3" 1319 [(set (match_operand:SI 0 "register_operand" "=r,r") 1320 (ashift:SI 1321 (match_operand:SI 1 "register_operand" "0,0") 1322 (match_operand:SI 2 "nonmemory_operand" "r,N")))] 1323 "" 1324 "@ 1325 shl %2,%0 1326 shl %2,%0" 1327 [(set_attr "length" "4,2") 1328 (set_attr "cc" "set_znv")]) 1329 1330(define_insn "lshrsi3" 1331 [(set (match_operand:SI 0 "register_operand" "=r,r") 1332 (lshiftrt:SI 1333 (match_operand:SI 1 "register_operand" "0,0") 1334 (match_operand:SI 2 "nonmemory_operand" "r,N")))] 1335 "" 1336 "@ 1337 shr %2,%0 1338 shr %2,%0" 1339 [(set_attr "length" "4,2") 1340 (set_attr "cc" "set_znv")]) 1341 1342(define_insn "ashrsi3" 1343 [(set (match_operand:SI 0 "register_operand" "=r,r") 1344 (ashiftrt:SI 1345 (match_operand:SI 1 "register_operand" "0,0") 1346 (match_operand:SI 2 "nonmemory_operand" "r,N")))] 1347 "" 1348 "@ 1349 sar %2,%0 1350 sar %2,%0" 1351 [(set_attr "length" "4,2") 1352 (set_attr "cc" "set_znv")]) 1353 1354;; ---------------------------------------------------------------------- 1355;; PROLOGUE/EPILOGUE 1356;; ---------------------------------------------------------------------- 1357(define_expand "prologue" 1358 [(const_int 0)] 1359 "" 1360 "expand_prologue (); DONE;") 1361 1362(define_expand "epilogue" 1363 [(return)] 1364 "" 1365 " 1366{ 1367 expand_epilogue (); 1368 DONE; 1369}") 1370 1371(define_insn "return_simple" 1372 [(return)] 1373 "reload_completed" 1374 "jmp [r31]" 1375 [(set_attr "length" "2") 1376 (set_attr "cc" "none")]) 1377 1378(define_insn "return_internal" 1379 [(return) 1380 (use (reg:SI 31))] 1381 "" 1382 "jmp [r31]" 1383 [(set_attr "length" "2") 1384 (set_attr "cc" "none")]) 1385 1386 1387 1388;; ---------------------------------------------------------------------- 1389;; HELPER INSTRUCTIONS for saving the prologue and epilogue registers 1390;; ---------------------------------------------------------------------- 1391 1392;; This pattern will match a stack adjust RTX followed by any number of push 1393;; RTXs. These RTXs will then be turned into a suitable call to a worker 1394;; function. 1395 1396;; 1397;; Actually, convert the RTXs into a PREPARE instruction. 1398;; 1399(define_insn "" 1400 [(match_parallel 0 "pattern_is_ok_for_prepare" 1401 [(set (reg:SI 3) 1402 (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i"))) 1403 (set (mem:SI (plus:SI (reg:SI 3) 1404 (match_operand:SI 2 "immediate_operand" "i"))) 1405 (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])] 1406 "TARGET_PROLOG_FUNCTION && TARGET_V850E" 1407 "* return construct_prepare_instruction (operands[0]); 1408 " 1409 [(set_attr "length" "4") 1410 (set_attr "cc" "none")]) 1411 1412(define_insn "" 1413 [(match_parallel 0 "pattern_is_ok_for_prologue" 1414 [(set (reg:SI 3) 1415 (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i"))) 1416 (set (mem:SI (plus:SI (reg:SI 3) 1417 (match_operand:SI 2 "immediate_operand" "i"))) 1418 (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])] 1419 "TARGET_PROLOG_FUNCTION && TARGET_V850" 1420 "* return construct_save_jarl (operands[0]); 1421 " 1422 [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes") 1423 (const_string "16") 1424 (const_string "4"))) 1425 (set_attr "cc" "clobber")]) 1426 1427;; 1428;; Actually, turn the RTXs into a DISPOSE instruction. 1429;; 1430(define_insn "" 1431 [(match_parallel 0 "pattern_is_ok_for_dispose" 1432 [(return) 1433 (set (reg:SI 3) 1434 (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i"))) 1435 (set (match_operand:SI 2 "register_is_ok_for_epilogue" "=r") 1436 (mem:SI (plus:SI (reg:SI 3) 1437 (match_operand:SI 3 "immediate_operand" "i"))))])] 1438 "TARGET_PROLOG_FUNCTION && TARGET_V850E" 1439 "* return construct_dispose_instruction (operands[0]); 1440 " 1441 [(set_attr "length" "4") 1442 (set_attr "cc" "none")]) 1443 1444;; This pattern will match a return RTX followed by any number of pop RTXs 1445;; and possible a stack adjustment as well. These RTXs will be turned into 1446;; a suitable call to a worker function. 1447 1448(define_insn "" 1449[(match_parallel 0 "pattern_is_ok_for_epilogue" 1450 [(return) 1451 (set (reg:SI 3) 1452 (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i"))) 1453 (set (match_operand:SI 2 "register_is_ok_for_epilogue" "=r") 1454 (mem:SI (plus:SI (reg:SI 3) 1455 (match_operand:SI 3 "immediate_operand" "i"))))])] 1456 "TARGET_PROLOG_FUNCTION && TARGET_V850" 1457 "* return construct_restore_jr (operands[0]); 1458 " 1459 [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes") 1460 (const_string "12") 1461 (const_string "4"))) 1462 (set_attr "cc" "clobber")]) 1463 1464;; Initialize an interrupt function. Do not depend on TARGET_PROLOG_FUNCTION. 1465(define_insn "callt_save_interrupt" 1466 [(unspec_volatile [(const_int 0)] 2)] 1467 "TARGET_V850E && !TARGET_DISABLE_CALLT" 1468 ;; The CALLT instruction stores the next address of CALLT to CTPC register 1469 ;; without saving its previous value. So if the interrupt handler 1470 ;; or its caller could possibly execute the CALLT insn, save_interrupt 1471 ;; MUST NOT be called via CALLT. 1472 "* 1473{ 1474 output_asm_insn (\"addi -24, sp, sp\", operands); 1475 output_asm_insn (\"st.w r10, 12[sp]\", operands); 1476 output_asm_insn (\"stsr ctpc, r10\", operands); 1477 output_asm_insn (\"st.w r10, 16[sp]\", operands); 1478 output_asm_insn (\"stsr ctpsw, r10\", operands); 1479 output_asm_insn (\"st.w r10, 20[sp]\", operands); 1480 output_asm_insn (\"callt ctoff(__callt_save_interrupt)\", operands); 1481 return \"\"; 1482}" 1483 [(set_attr "length" "26") 1484 (set_attr "cc" "none")]) 1485 1486(define_insn "callt_return_interrupt" 1487 [(unspec_volatile [(const_int 0)] 3)] 1488 "TARGET_V850E && !TARGET_DISABLE_CALLT" 1489 "callt ctoff(__callt_return_interrupt)" 1490 [(set_attr "length" "2") 1491 (set_attr "cc" "clobber")]) 1492 1493(define_insn "save_interrupt" 1494 [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -16))) 1495 (set (mem:SI (plus:SI (reg:SI 3) (const_int -16))) (reg:SI 30)) 1496 (set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 4)) 1497 (set (mem:SI (plus:SI (reg:SI 3) (const_int -8))) (reg:SI 1)) 1498 (set (mem:SI (plus:SI (reg:SI 3) (const_int -4))) (reg:SI 10))] 1499 "" 1500 "* 1501{ 1502 if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS) 1503 return \"add -16,sp\;st.w r10,12[sp]\;jarl __save_interrupt,r10\"; 1504 else 1505 { 1506 output_asm_insn (\"add -16, sp\", operands); 1507 output_asm_insn (\"st.w r10, 12[sp]\", operands); 1508 output_asm_insn (\"st.w ep, 0[sp]\", operands); 1509 output_asm_insn (\"st.w gp, 4[sp]\", operands); 1510 output_asm_insn (\"st.w r1, 8[sp]\", operands); 1511 output_asm_insn (\"movhi hi(__ep), r0, ep\", operands); 1512 output_asm_insn (\"movea lo(__ep), ep, ep\", operands); 1513 output_asm_insn (\"movhi hi(__gp), r0, gp\", operands); 1514 output_asm_insn (\"movea lo(__gp), gp, gp\", operands); 1515 return \"\"; 1516 } 1517}" 1518 [(set (attr "length") 1519 (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") (const_int 0)) 1520 (const_int 10) 1521 (const_int 34))) 1522 (set_attr "cc" "clobber")]) 1523 1524;; Restore r1, r4, r10, and return from the interrupt 1525(define_insn "return_interrupt" 1526 [(return) 1527 (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 16))) 1528 (set (reg:SI 10) (mem:SI (plus:SI (reg:SI 3) (const_int 12)))) 1529 (set (reg:SI 1) (mem:SI (plus:SI (reg:SI 3) (const_int 8)))) 1530 (set (reg:SI 4) (mem:SI (plus:SI (reg:SI 3) (const_int 4)))) 1531 (set (reg:SI 30) (mem:SI (reg:SI 3)))] 1532 "" 1533 "* 1534{ 1535 if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS) 1536 return \"jr __return_interrupt\"; 1537 else 1538 { 1539 output_asm_insn (\"ld.w 0[sp], ep\", operands); 1540 output_asm_insn (\"ld.w 4[sp], gp\", operands); 1541 output_asm_insn (\"ld.w 8[sp], r1\", operands); 1542 output_asm_insn (\"ld.w 12[sp], r10\", operands); 1543 output_asm_insn (\"addi 16, sp, sp\", operands); 1544 output_asm_insn (\"reti\", operands); 1545 return \"\"; 1546 } 1547}" 1548 [(set (attr "length") 1549 (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") (const_int 0)) 1550 (const_int 4) 1551 (const_int 24))) 1552 (set_attr "cc" "clobber")]) 1553 1554;; Save all registers except for the registers saved in save_interrupt when 1555;; an interrupt function makes a call. 1556;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and 1557;; all of memory. This blocks insns from being moved across this point. 1558;; This is needed because the rest of the compiler is not ready to handle 1559;; insns this complicated. 1560 1561(define_insn "callt_save_all_interrupt" 1562 [(unspec_volatile [(const_int 0)] 0)] 1563 "TARGET_V850E && !TARGET_DISABLE_CALLT" 1564 "callt ctoff(__callt_save_all_interrupt)" 1565 [(set_attr "length" "2") 1566 (set_attr "cc" "none")]) 1567 1568(define_insn "save_all_interrupt" 1569 [(unspec_volatile [(const_int 0)] 0)] 1570 "" 1571 "* 1572{ 1573 if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS) 1574 return \"jarl __save_all_interrupt,r10\"; 1575 1576 output_asm_insn (\"addi -120, sp, sp\", operands); 1577 1578 if (TARGET_EP) 1579 { 1580 output_asm_insn (\"mov ep, r1\", operands); 1581 output_asm_insn (\"mov sp, ep\", operands); 1582 output_asm_insn (\"sst.w r31, 116[ep]\", operands); 1583 output_asm_insn (\"sst.w r2, 112[ep]\", operands); 1584 output_asm_insn (\"sst.w gp, 108[ep]\", operands); 1585 output_asm_insn (\"sst.w r6, 104[ep]\", operands); 1586 output_asm_insn (\"sst.w r7, 100[ep]\", operands); 1587 output_asm_insn (\"sst.w r8, 96[ep]\", operands); 1588 output_asm_insn (\"sst.w r9, 92[ep]\", operands); 1589 output_asm_insn (\"sst.w r11, 88[ep]\", operands); 1590 output_asm_insn (\"sst.w r12, 84[ep]\", operands); 1591 output_asm_insn (\"sst.w r13, 80[ep]\", operands); 1592 output_asm_insn (\"sst.w r14, 76[ep]\", operands); 1593 output_asm_insn (\"sst.w r15, 72[ep]\", operands); 1594 output_asm_insn (\"sst.w r16, 68[ep]\", operands); 1595 output_asm_insn (\"sst.w r17, 64[ep]\", operands); 1596 output_asm_insn (\"sst.w r18, 60[ep]\", operands); 1597 output_asm_insn (\"sst.w r19, 56[ep]\", operands); 1598 output_asm_insn (\"sst.w r20, 52[ep]\", operands); 1599 output_asm_insn (\"sst.w r21, 48[ep]\", operands); 1600 output_asm_insn (\"sst.w r22, 44[ep]\", operands); 1601 output_asm_insn (\"sst.w r23, 40[ep]\", operands); 1602 output_asm_insn (\"sst.w r24, 36[ep]\", operands); 1603 output_asm_insn (\"sst.w r25, 32[ep]\", operands); 1604 output_asm_insn (\"sst.w r26, 28[ep]\", operands); 1605 output_asm_insn (\"sst.w r27, 24[ep]\", operands); 1606 output_asm_insn (\"sst.w r28, 20[ep]\", operands); 1607 output_asm_insn (\"sst.w r29, 16[ep]\", operands); 1608 output_asm_insn (\"mov r1, ep\", operands); 1609 } 1610 else 1611 { 1612 output_asm_insn (\"st.w r31, 116[sp]\", operands); 1613 output_asm_insn (\"st.w r2, 112[sp]\", operands); 1614 output_asm_insn (\"st.w gp, 108[sp]\", operands); 1615 output_asm_insn (\"st.w r6, 104[sp]\", operands); 1616 output_asm_insn (\"st.w r7, 100[sp]\", operands); 1617 output_asm_insn (\"st.w r8, 96[sp]\", operands); 1618 output_asm_insn (\"st.w r9, 92[sp]\", operands); 1619 output_asm_insn (\"st.w r11, 88[sp]\", operands); 1620 output_asm_insn (\"st.w r12, 84[sp]\", operands); 1621 output_asm_insn (\"st.w r13, 80[sp]\", operands); 1622 output_asm_insn (\"st.w r14, 76[sp]\", operands); 1623 output_asm_insn (\"st.w r15, 72[sp]\", operands); 1624 output_asm_insn (\"st.w r16, 68[sp]\", operands); 1625 output_asm_insn (\"st.w r17, 64[sp]\", operands); 1626 output_asm_insn (\"st.w r18, 60[sp]\", operands); 1627 output_asm_insn (\"st.w r19, 56[sp]\", operands); 1628 output_asm_insn (\"st.w r20, 52[sp]\", operands); 1629 output_asm_insn (\"st.w r21, 48[sp]\", operands); 1630 output_asm_insn (\"st.w r22, 44[sp]\", operands); 1631 output_asm_insn (\"st.w r23, 40[sp]\", operands); 1632 output_asm_insn (\"st.w r24, 36[sp]\", operands); 1633 output_asm_insn (\"st.w r25, 32[sp]\", operands); 1634 output_asm_insn (\"st.w r26, 28[sp]\", operands); 1635 output_asm_insn (\"st.w r27, 24[sp]\", operands); 1636 output_asm_insn (\"st.w r28, 20[sp]\", operands); 1637 output_asm_insn (\"st.w r29, 16[sp]\", operands); 1638 } 1639 1640 return \"\"; 1641}" 1642 [(set (attr "length") 1643 (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") (const_int 0)) 1644 (const_int 4) 1645 (const_int 62) 1646 )) 1647 (set_attr "cc" "clobber")]) 1648 1649(define_insn "_save_all_interrupt" 1650 [(unspec_volatile [(const_int 0)] 0)] 1651 "TARGET_V850 && ! TARGET_LONG_CALLS" 1652 "jarl __save_all_interrupt,r10" 1653 [(set_attr "length" "4") 1654 (set_attr "cc" "clobber")]) 1655 1656;; Restore all registers saved when an interrupt function makes a call. 1657;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and 1658;; all of memory. This blocks insns from being moved across this point. 1659;; This is needed because the rest of the compiler is not ready to handle 1660;; insns this complicated. 1661 1662(define_insn "callt_restore_all_interrupt" 1663 [(unspec_volatile [(const_int 0)] 1)] 1664 "TARGET_V850E && !TARGET_DISABLE_CALLT" 1665 "callt ctoff(__callt_restore_all_interrupt)" 1666 [(set_attr "length" "2") 1667 (set_attr "cc" "none")]) 1668 1669(define_insn "restore_all_interrupt" 1670 [(unspec_volatile [(const_int 0)] 1)] 1671 "" 1672 "* 1673{ 1674 if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS) 1675 return \"jarl __restore_all_interrupt,r10\"; 1676 1677 if (TARGET_EP) 1678 { 1679 output_asm_insn (\"mov ep, r1\", operands); 1680 output_asm_insn (\"mov sp, ep\", operands); 1681 output_asm_insn (\"sld.w 116[ep], r31\", operands); 1682 output_asm_insn (\"sld.w 112[ep], r2\", operands); 1683 output_asm_insn (\"sld.w 108[ep], gp\", operands); 1684 output_asm_insn (\"sld.w 104[ep], r6\", operands); 1685 output_asm_insn (\"sld.w 100[ep], r7\", operands); 1686 output_asm_insn (\"sld.w 96[ep], r8\", operands); 1687 output_asm_insn (\"sld.w 92[ep], r9\", operands); 1688 output_asm_insn (\"sld.w 88[ep], r11\", operands); 1689 output_asm_insn (\"sld.w 84[ep], r12\", operands); 1690 output_asm_insn (\"sld.w 80[ep], r13\", operands); 1691 output_asm_insn (\"sld.w 76[ep], r14\", operands); 1692 output_asm_insn (\"sld.w 72[ep], r15\", operands); 1693 output_asm_insn (\"sld.w 68[ep], r16\", operands); 1694 output_asm_insn (\"sld.w 64[ep], r17\", operands); 1695 output_asm_insn (\"sld.w 60[ep], r18\", operands); 1696 output_asm_insn (\"sld.w 56[ep], r19\", operands); 1697 output_asm_insn (\"sld.w 52[ep], r20\", operands); 1698 output_asm_insn (\"sld.w 48[ep], r21\", operands); 1699 output_asm_insn (\"sld.w 44[ep], r22\", operands); 1700 output_asm_insn (\"sld.w 40[ep], r23\", operands); 1701 output_asm_insn (\"sld.w 36[ep], r24\", operands); 1702 output_asm_insn (\"sld.w 32[ep], r25\", operands); 1703 output_asm_insn (\"sld.w 28[ep], r26\", operands); 1704 output_asm_insn (\"sld.w 24[ep], r27\", operands); 1705 output_asm_insn (\"sld.w 20[ep], r28\", operands); 1706 output_asm_insn (\"sld.w 16[ep], r29\", operands); 1707 output_asm_insn (\"mov r1, ep\", operands); 1708 } 1709 else 1710 { 1711 output_asm_insn (\"ld.w 116[sp], r31\", operands); 1712 output_asm_insn (\"ld.w 112[sp], r2\", operands); 1713 output_asm_insn (\"ld.w 108[sp], gp\", operands); 1714 output_asm_insn (\"ld.w 104[sp], r6\", operands); 1715 output_asm_insn (\"ld.w 100[sp], r7\", operands); 1716 output_asm_insn (\"ld.w 96[sp], r8\", operands); 1717 output_asm_insn (\"ld.w 92[sp], r9\", operands); 1718 output_asm_insn (\"ld.w 88[sp], r11\", operands); 1719 output_asm_insn (\"ld.w 84[sp], r12\", operands); 1720 output_asm_insn (\"ld.w 80[sp], r13\", operands); 1721 output_asm_insn (\"ld.w 76[sp], r14\", operands); 1722 output_asm_insn (\"ld.w 72[sp], r15\", operands); 1723 output_asm_insn (\"ld.w 68[sp], r16\", operands); 1724 output_asm_insn (\"ld.w 64[sp], r17\", operands); 1725 output_asm_insn (\"ld.w 60[sp], r18\", operands); 1726 output_asm_insn (\"ld.w 56[sp], r19\", operands); 1727 output_asm_insn (\"ld.w 52[sp], r20\", operands); 1728 output_asm_insn (\"ld.w 48[sp], r21\", operands); 1729 output_asm_insn (\"ld.w 44[sp], r22\", operands); 1730 output_asm_insn (\"ld.w 40[sp], r23\", operands); 1731 output_asm_insn (\"ld.w 36[sp], r24\", operands); 1732 output_asm_insn (\"ld.w 32[sp], r25\", operands); 1733 output_asm_insn (\"ld.w 28[sp], r26\", operands); 1734 output_asm_insn (\"ld.w 24[sp], r27\", operands); 1735 output_asm_insn (\"ld.w 20[sp], r28\", operands); 1736 output_asm_insn (\"ld.w 16[sp], r29\", operands); 1737 } 1738 output_asm_insn (\"addi 120, sp, sp\", operands); 1739 return \"\"; 1740}" 1741 [(set (attr "length") 1742 (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") (const_int 0)) 1743 (const_int 4) 1744 (const_int 62) 1745 )) 1746 (set_attr "cc" "clobber")]) 1747 1748(define_insn "_restore_all_interrupt" 1749 [(unspec_volatile [(const_int 0)] 1)] 1750 "TARGET_V850 && ! TARGET_LONG_CALLS" 1751 "jarl __restore_all_interrupt,r10" 1752 [(set_attr "length" "4") 1753 (set_attr "cc" "clobber")]) 1754 1755;; Save r6-r9 for a variable argument function 1756(define_insn "save_r6_r9_v850e" 1757 [(set (mem:SI (reg:SI 3)) (reg:SI 6)) 1758 (set (mem:SI (plus:SI (reg:SI 3) (const_int 4))) (reg:SI 7)) 1759 (set (mem:SI (plus:SI (reg:SI 3) (const_int 8))) (reg:SI 8)) 1760 (set (mem:SI (plus:SI (reg:SI 3) (const_int 12))) (reg:SI 9)) 1761 ] 1762 "TARGET_PROLOG_FUNCTION && TARGET_V850E && !TARGET_DISABLE_CALLT" 1763 "callt ctoff(__callt_save_r6_r9)" 1764 [(set_attr "length" "2") 1765 (set_attr "cc" "none")]) 1766 1767(define_insn "save_r6_r9" 1768 [(set (mem:SI (reg:SI 3)) (reg:SI 6)) 1769 (set (mem:SI (plus:SI (reg:SI 3) (const_int 4))) (reg:SI 7)) 1770 (set (mem:SI (plus:SI (reg:SI 3) (const_int 8))) (reg:SI 8)) 1771 (set (mem:SI (plus:SI (reg:SI 3) (const_int 12))) (reg:SI 9)) 1772 (clobber (reg:SI 10))] 1773 "TARGET_PROLOG_FUNCTION && ! TARGET_LONG_CALLS" 1774 "jarl __save_r6_r9,r10" 1775 [(set_attr "length" "4") 1776 (set_attr "cc" "clobber")]) 1777 1778