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