1;; GCC machine description for NEC V850 2;; Copyright (C) 1996-2019 Free Software Foundation, Inc. 3;; Contributed by Jeff Law (law@cygnus.com). 4 5;; This file is part of GCC. 6 7;; GCC is free software; you can redistribute it and/or modify 8;; it under the terms of the GNU General Public License as published by 9;; the Free Software Foundation; either version 3, or (at your option) 10;; any later version. 11 12;; GCC is distributed in the hope that it will be useful, 13;; but WITHOUT ANY WARRANTY; without even the implied warranty of 14;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15;; GNU General Public License for more details. 16 17;; You should have received a copy of the GNU General Public License 18;; along with GCC; see the file COPYING3. If not see 19;; <http://www.gnu.org/licenses/>. 20 21;; The original PO technology requires these to be ordered by speed, 22;; so that assigner will pick the fastest. 23 24;; See file "rtl.def" for documentation on define_insn, match_*, et. al. 25 26;; The V851 manual states that the instruction address space is 16M; 27;; the various branch/call instructions only have a 22bit offset (4M range). 28;; 29;; One day we'll probably need to handle calls to targets more than 4M 30;; away. 31;; 32 33;; Condition codes 34;; 35;; Data movement (load, store, register copy) does not modify condition 36;; codes. But there is no way to add two registers together without 37;; modifying the condition codes. 38;; 39;; So we do not expose the condition codes until after reload. The 40;; general approach is to have a define_insn_and_split for the basic 41;; operation with no condition codes in the pattern (to give the 42;; optimizers maximal freedom). The splitter adds a clobber of the 43;; condition codes after reload. There is a distinct pattern which 44;; sets the condition codes. 45;; 46;; As noted, data movement does not affect condition codes. 47;; 48;; Arithmetic generally set the codes in the expected ways, with mul 49;; instructions being a notable outlier. div instructions generally 50;; do the right thing, except when the output registers are the same 51;; when the flags do not get set. We just assume they're clobbered 52;; for div instructions to avoid MD bloat with marginal benefit 53;; 54;; The bit manipulation instructions (clr1, not1, set1) set condition 55;; codes, but not in a useful way (they're set to the prior status of 56;; the bit). So we just model those as clobbers. tst1 does set the 57;; condition codes in a useful way. We could perhaps do better with 58;; these by noting they only modify the Z flag, it doesn't seem worth 59;; the effort. 60;; 61;; Byte swaps seem to change the condition codes, but I haven't tried 62;; to describe how. 63;; 64;; I have no documentation on the rotate instructions. They likely 65;; set the condition codes, but I've left them as clobbers for now. 66 67 68;; The size of instructions in bytes. 69 70;;--------------------------------------------------------------------------- 71;; Constants 72 73;; 74(define_constants 75 [(ZERO_REGNUM 0) ; constant zero 76 (SP_REGNUM 3) ; Stack Pointer 77 (GP_REGNUM 4) ; GP Pointer 78 (RV_REGNUM 10) ; Return value register 79 (EP_REGNUM 30) ; EP pointer 80 (LP_REGNUM 31) ; Return address register 81 (CC_REGNUM 32) ; Condition code pseudo register 82 (FCC_REGNUM 33) ; Floating Condition code pseudo register 83 ] 84) 85 86(define_c_enum "unspec" [ 87 UNSPEC_LOOP 88 UNSPEC_RCP 89 UNSPEC_RSQRT 90]) 91 92(define_attr "length" "" 93 (const_int 4)) 94 95(define_attr "long_calls" "yes,no" 96 (const (if_then_else (symbol_ref "TARGET_LONG_CALLS") 97 (const_string "yes") 98 (const_string "no")))) 99 100;; Types of instructions (for scheduling purposes). 101 102(define_attr "type" "load,store,bit1,mult,macc,div,fpu,single,other" 103 (const_string "other")) 104 105(define_attr "cpu" "none,v850,v850e,v850e1,v850e2,v850e2v3,v850e3v5" 106 (cond [(match_test "TARGET_V850") 107 (const_string "v850") 108 (match_test "TARGET_V850E") 109 (const_string "v850e") 110 (match_test "TARGET_V850E1") 111 (const_string "v850e1") 112 (match_test "TARGET_V850E2") 113 (const_string "v850e2") 114 (match_test "TARGET_V850E2V3") 115 (const_string "v850e2v3") 116 (match_test "TARGET_V850E3V5") 117 (const_string "v850e3v5")] 118 (const_string "none"))) 119 120 121;; Function units for the V850. As best as I can tell, there's 122;; a traditional memory load/use stall as well as a stall if 123;; the result of a multiply is used too early. 124 125(define_insn_reservation "v850_other" 1 126 (eq_attr "type" "other") 127 "nothing") 128(define_insn_reservation "v850_mult" 2 129 (eq_attr "type" "mult") 130 "nothing") 131(define_insn_reservation "v850_memory" 2 132 (eq_attr "type" "load") 133 "nothing") 134 135(include "predicates.md") 136(include "constraints.md") 137 138;; ---------------------------------------------------------------------- 139;; MOVE INSTRUCTIONS 140;; ---------------------------------------------------------------------- 141;; movdi 142 143(define_expand "movdi" 144 [(set (match_operand:DI 0 "general_operand") 145 (match_operand:DI 1 "general_operand"))] 146 "TARGET_V850E3V5_UP" 147 { 148 /* One of the ops has to be in a register or 0. */ 149 if (!register_operand (operand0, DImode) 150 && !register_operand (operand1, DImode)) 151 operands[1] = copy_to_mode_reg (DImode, operand1); 152 153 if (register_operand (operand0, DImode) 154 && (CONST_INT_P (operands[1]) || CONST_DOUBLE_P (operands[1]))) 155 { 156 int i; 157 158 for (i = 0; i < UNITS_PER_WORD * 2; i += UNITS_PER_WORD) 159 emit_move_insn (simplify_gen_subreg (SImode, operands[0], DImode, i), 160 simplify_gen_subreg (SImode, operands[1], DImode, i)); 161 DONE; 162 } 163 } 164) 165 166(define_insn "*movdi_internal" 167 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,e!r,m") 168 (match_operand:DI 1 "nonimmediate_operand" "r,m,e!r"))] 169 "TARGET_V850E3V5_UP 170 || (register_operand (operands[0], DImode) && register_operand (operands[1], DImode))" 171 { return v850_gen_movdi (operands); } 172 [(set_attr "length" "4,12,12") 173 (set_attr "type" "other,load,store")]) 174 175;; movqi 176 177(define_expand "movqi" 178 [(set (match_operand:QI 0 "general_operand" "") 179 (match_operand:QI 1 "general_operand" ""))] 180 "" 181 { 182 /* One of the ops has to be in a register or 0 */ 183 if (!register_operand (operand0, QImode) 184 && !reg_or_0_operand (operand1, QImode)) 185 operands[1] = copy_to_mode_reg (QImode, operand1); 186 }) 187 188(define_insn "*movqi_internal" 189 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,Q,r,m,m") 190 (match_operand:QI 1 "general_operand" "Jr,n,Q,Ir,m,r,I"))] 191 "register_operand (operands[0], QImode) 192 || reg_or_0_operand (operands[1], QImode)" 193{ 194 return output_move_single (operands); 195} 196 [(set_attr "length" "2,4,2,2,4,4,4") 197 (set_attr "type" "other,other,load,other,load,store,store")]) 198 199;; movhi 200 201(define_expand "movhi" 202 [(set (match_operand:HI 0 "general_operand" "") 203 (match_operand:HI 1 "general_operand" ""))] 204 "" 205{ 206 /* One of the ops has to be in a register or 0 */ 207 if (!register_operand (operand0, HImode) 208 && !reg_or_0_operand (operand1, HImode)) 209 operands[1] = copy_to_mode_reg (HImode, operand1); 210}) 211 212(define_insn "*movhi_internal" 213 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,Q,r,m,m") 214 (match_operand:HI 1 "general_operand" "Jr,n,Q,Ir,m,r,I"))] 215 "register_operand (operands[0], HImode) 216 || reg_or_0_operand (operands[1], HImode)" 217{ 218 return output_move_single (operands); 219} 220 [(set_attr "length" "2,4,2,2,4,4,4") 221 (set_attr "type" "other,other,load,other,load,store,store")]) 222 223;; movsi and helpers 224 225(define_insn "*movsi_high" 226 [(set (match_operand:SI 0 "register_operand" "=r") 227 (high:SI (match_operand 1 "immediate_operand" "i")))] 228 "" 229 "movhi hi(%1),%.,%0" 230 [(set_attr "length" "4") 231 (set_attr "type" "other")]) 232 233(define_insn "*movsi_lo" 234 [(set (match_operand:SI 0 "register_operand" "=r") 235 (lo_sum:SI (match_operand:SI 1 "register_operand" "r") 236 (match_operand:SI 2 "immediate_operand" "i")))] 237 "" 238 "movea lo(%2),%1,%0" 239 [(set_attr "length" "4") 240 (set_attr "type" "other")]) 241 242(define_expand "movsi" 243 [(set (match_operand:SI 0 "general_operand" "") 244 (match_operand:SI 1 "general_operand" ""))] 245 "" 246 { 247 /* One of the ops has to be in a register or 0 */ 248 if (!register_operand (operand0, SImode) 249 && !reg_or_0_operand (operand1, SImode)) 250 operands[1] = copy_to_mode_reg (SImode, operand1); 251 252 /* Some constants, as well as symbolic operands 253 must be done with HIGH & LO_SUM patterns. */ 254 if (CONSTANT_P (operands[1]) 255 && GET_CODE (operands[1]) != HIGH 256 && ! (TARGET_V850E_UP) 257 && !special_symbolref_operand (operands[1], VOIDmode) 258 && !(GET_CODE (operands[1]) == CONST_INT 259 && (CONST_OK_FOR_J (INTVAL (operands[1])) 260 || CONST_OK_FOR_K (INTVAL (operands[1])) 261 || CONST_OK_FOR_L (INTVAL (operands[1]))))) 262 { 263 rtx temp; 264 265 if (reload_in_progress || reload_completed) 266 temp = operands[0]; 267 else 268 temp = gen_reg_rtx (SImode); 269 270 emit_insn (gen_rtx_SET (temp, gen_rtx_HIGH (SImode, operand1))); 271 emit_insn (gen_rtx_SET (operand0, 272 gen_rtx_LO_SUM (SImode, temp, operand1))); 273 DONE; 274 } 275 }) 276 277;; This is the same as the following pattern, except that it includes 278;; support for arbitrary 32-bit immediates. 279 280;; ??? This always loads addresses using hilo. If the only use of this address 281;; was in a load/store, then we would get smaller code if we only loaded the 282;; upper part with hi, and then put the lower part in the load/store insn. 283 284(define_insn "*movsi_internal_v850e" 285 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,Q,r,r,m,m,r") 286 (match_operand:SI 1 "general_operand" "Jr,K,L,Q,Ir,m,R,r,I,i"))] 287 "(TARGET_V850E_UP) 288 && (register_operand (operands[0], SImode) 289 || reg_or_0_operand (operands[1], SImode))" 290{ 291 return output_move_single (operands); 292} 293 [(set_attr "length" "2,4,4,2,2,4,4,4,4,6") 294 (set_attr "type" "other,other,other,load,other,load,other,store,store,other")]) 295 296(define_insn "*movsi_internal" 297 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,Q,r,r,m,m") 298 (match_operand:SI 1 "movsi_source_operand" "Jr,K,L,Q,Ir,m,R,r,I"))] 299 "register_operand (operands[0], SImode) 300 || reg_or_0_operand (operands[1], SImode)" 301{ 302 return output_move_single (operands); 303} 304 [(set_attr "length" "2,4,4,2,2,4,4,4,4") 305 (set_attr "type" "other,other,other,load,other,load,store,store,other")]) 306 307(define_insn "*movsf_internal" 308 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,Q,r,m,m,r") 309 (match_operand:SF 1 "general_operand" "Jr,K,L,n,Q,Ir,m,r,IG,iF"))] 310 "register_operand (operands[0], SFmode) 311 || reg_or_0_operand (operands[1], SFmode)" 312{ 313 return output_move_single (operands); 314} 315 [(set_attr "length" "2,4,4,8,2,2,4,4,4,8") 316 (set_attr "type" "other,other,other,other,load,other,load,store,store,other")]) 317 318;; ---------------------------------------------------------------------- 319;; TEST INSTRUCTIONS 320;; ---------------------------------------------------------------------- 321 322(define_insn "*v850_tst1" 323 [(set (reg:CCZ CC_REGNUM) 324 (compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "m") 325 (const_int 1) 326 (match_operand:QI 1 "const_int_operand" "n")) 327 (const_int 0)))] 328 "reload_completed" 329 "tst1 %1,%0" 330 [(set_attr "length" "4")]) 331 332;; This replaces ld.b;sar;andi with tst1;setf nz. 333;; Should there be variants for HI or SI modes? 334 335(define_insn_and_split "" 336 [(set (match_operand:SI 0 "register_operand" "") 337 (compare (zero_extract:SI (match_operand:QI 1 "memory_operand" "") 338 (const_int 1) 339 (match_operand 2 "const_int_operand" "")) 340 (const_int 0)))] 341 "" 342 "#" 343 "reload_completed" 344 [(set (reg:CCZ CC_REGNUM) (compare (zero_extract:SI (match_dup 1) 345 (const_int 1) 346 (match_dup 2)) 347 (const_int 0))) 348 (set (match_dup 0) (ne:SI (reg:CCZ CC_REGNUM) (const_int 0)))]) 349 350(define_expand "cbranchsi4" 351 [(set (pc) 352 (if_then_else 353 (match_operator 0 "comparison_operator" 354 [(match_operand:SI 1 "register_operand") 355 (match_operand:SI 2 "reg_or_int5_operand")]) 356 (label_ref (match_operand 3 "" "")) 357 (pc)))] 358 "") 359 360(define_insn "cmpsi_insn" 361 [(set (reg:CC CC_REGNUM) 362 (compare (match_operand:SI 0 "register_operand" "r,r") 363 (match_operand:SI 1 "reg_or_int5_operand" "r,J")))] 364 "reload_completed" 365 "cmp %1,%0" 366 [(set_attr "length" "2,2")]) 367 368(define_insn_and_split "cbranchsf4" 369 [(set (pc) 370 (if_then_else (match_operator 0 "ordered_comparison_operator" 371 [(match_operand:SF 1 "register_operand" "r") 372 (match_operand:SF 2 "register_operand" "r")]) 373 (label_ref (match_operand 3 "")) 374 (pc)))] 375 "TARGET_USE_FPU" 376 "#" 377 "reload_completed" 378 [(set (match_dup 4) (match_dup 5)) 379 (set (pc) 380 (if_then_else (match_dup 6) 381 (label_ref (match_dup 3)) 382 (pc)))] 383 "{ 384 /* This will generate the comparison insn at the start of 385 the sequence and get us the right mode to use for our 386 condition code registers. */ 387 enum machine_mode mode 388 = v850_gen_float_compare (GET_CODE (operands[0]), 389 GET_MODE (operands[1]), 390 operands[1], operands[2]); 391 /* We want operands referring to CC_REGNUM and FCC_REGNUM 392 in mode MODE. */ 393 operands[4] = gen_rtx_REG (mode, CC_REGNUM); 394 operands[5] = gen_rtx_REG (mode, FCC_REGNUM); 395 if (mode == CC_FPU_NEmode) 396 operands[6] = gen_rtx_NE (mode, operands[4], const0_rtx); 397 else 398 operands[6] = gen_rtx_EQ (mode, operands[4], const0_rtx); 399}") 400 401(define_insn "cstoresf4" 402 [(set (match_operand:SI 0 "register_operand" "=r") 403 (match_operator:SI 1 "ordered_comparison_operator" 404 [(match_operand:SF 2 "register_operand" "r") 405 (match_operand:SF 3 "register_operand" "r")])) 406 (clobber (reg:CC CC_REGNUM))] 407 "TARGET_USE_FPU" 408{ 409 if (GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == GE) 410 return "cmpf.s %c1, %z2, %z3 ; trfsr ; setf nz, %0"; 411 if (GET_CODE (operands[1]) == LT || GET_CODE (operands[1]) == LE) 412 return "cmpf.s %c1, %z2, %z3 ; trfsr ; setf z, %0"; 413 if (GET_CODE (operands[1]) == EQ) 414 return "cmpf.s eq, %z2, %z3 ; trfsr ; setf z, %0"; 415 if (GET_CODE (operands[1]) == NE) 416 return "cmpf.s neq, %z2, %z3 ; trfsr ; setf nz, %0"; 417 gcc_unreachable (); 418} 419 [(set_attr "length" "12") 420 (set_attr "type" "fpu")]) 421 422(define_insn_and_split "cbranchdf4" 423 [(set (pc) 424 (if_then_else (match_operator 0 "ordered_comparison_operator" 425 [(match_operand:DF 1 "even_reg_operand" "r") 426 (match_operand:DF 2 "even_reg_operand" "r")]) 427 (label_ref (match_operand 3 "")) 428 (pc)))] 429 "TARGET_USE_FPU" 430 "#" 431 "reload_completed" 432;; How to get the mode here? 433 [(set (match_dup 4) (match_dup 5)) 434 (set (pc) 435 (if_then_else (match_dup 6) 436 (label_ref (match_dup 3)) 437 (pc)))] 438 "{ 439 /* This will generate the comparison insn at the start of 440 the sequence and get us the right mode to use for our 441 condition code registers. */ 442 enum machine_mode mode 443 = v850_gen_float_compare (GET_CODE (operands[0]), 444 GET_MODE (operands[1]), 445 operands[1], operands[2]); 446 PUT_MODE (operands[0], mode); 447 /* We want operands referring to CC_REGNUM and FCC_REGNUM 448 in mode MODE. */ 449 operands[4] = gen_rtx_REG (mode, CC_REGNUM); 450 operands[5] = gen_rtx_REG (mode, FCC_REGNUM); 451 if (mode == CC_FPU_NEmode) 452 operands[6] = gen_rtx_NE (mode, operands[4], const0_rtx); 453 else 454 operands[6] = gen_rtx_EQ (mode, operands[4], const0_rtx); 455}") 456 457(define_insn "cstoredf4" 458 [(set (match_operand:SI 0 "register_operand" "=r") 459 (match_operator:SI 1 "ordered_comparison_operator" 460 [(match_operand:DF 2 "even_reg_operand" "r") 461 (match_operand:DF 3 "even_reg_operand" "r")])) 462 (clobber (reg:CC CC_REGNUM))] 463 "TARGET_USE_FPU" 464{ 465 if (GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == GE) 466 return "cmpf.d %c1, %z2, %z3 ; trfsr ; setf nz, %0"; 467 if (GET_CODE (operands[1]) == LT || GET_CODE (operands[1]) == LE) 468 return "cmpf.d %c1, %z2, %z3 ; trfsr ; setf z, %0"; 469 if (GET_CODE (operands[1]) == EQ) 470 return "cmpf.d eq, %z2, %z3 ; trfsr ; setf z ,%0"; 471 if (GET_CODE (operands[1]) == NE) 472 return "cmpf.d neq, %z2, %z3 ; trfsr ; setf nz, %0"; 473 gcc_unreachable (); 474} 475 [(set_attr "length" "12") 476 (set_attr "type" "fpu")]) 477 478;; ---------------------------------------------------------------------- 479;; ADD INSTRUCTIONS 480;; ---------------------------------------------------------------------- 481 482(define_insn_and_split "addsi3" 483 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 484 (plus:SI (match_operand:SI 1 "register_operand" "%0,r,r") 485 (match_operand:SI 2 "nonmemory_operand" "rJ,K,U")))] 486 "" 487 "#" 488 "reload_completed" 489 [(parallel [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2))) 490 (clobber (reg:CC CC_REGNUM))])]) 491 492(define_insn "addsi3_clobber_flags" 493 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 494 (plus:SI (match_operand:SI 1 "register_operand" "%0,r,r") 495 (match_operand:SI 2 "nonmemory_operand" "rJ,K,U"))) 496 (clobber (reg:CC CC_REGNUM))] 497 "" 498 "@ 499 add %2,%0 500 addi %2,%1,%0 501 addi %O2(%P2),%1,%0" 502 [(set_attr "length" "2,4,4")]) 503 504(define_insn "addsi3_set_flags" 505 [(set (reg:CCNZ CC_REGNUM) 506 (compare:CCNZ (plus:SI (match_operand:SI 1 "register_operand" "%0,r,r") 507 (match_operand:SI 2 "nonmemory_operand" "rJ,K,U")) 508 (const_int 0))) 509 (set (match_operand:SI 0 "register_operand" "=r,r,r") 510 (plus:SI (match_dup 1) (match_dup 2)))] 511 "reload_completed" 512 "@ 513 add %2,%0 514 addi %2,%1,%0 515 addi %O2(%P2),%1,%0" 516 [(set_attr "length" "2,4,4")]) 517 518;; ---------------------------------------------------------------------- 519;; SUBTRACT INSTRUCTIONS 520;; ---------------------------------------------------------------------- 521(define_insn_and_split "subsi3" 522 [(set (match_operand:SI 0 "register_operand" "=r,r") 523 (minus:SI (match_operand:SI 1 "register_operand" "0,r") 524 (match_operand:SI 2 "register_operand" "r,0")))] 525 "" 526 "#" 527 "reload_completed" 528 [(parallel [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2))) 529 (clobber (reg:CC CC_REGNUM))])]) 530 531(define_insn "subsi3_clobber_flags" 532 [(set (match_operand:SI 0 "register_operand" "=r,r") 533 (minus:SI (match_operand:SI 1 "register_operand" "0,r") 534 (match_operand:SI 2 "register_operand" "r,0"))) 535 (clobber (reg:CC CC_REGNUM))] 536 "" 537 "@ 538 sub %2,%0 539 subr %1,%0" 540 [(set_attr "length" "2,2")]) 541 542(define_insn "*subsi3_set_flags" 543 [(set (reg:CCNZ CC_REGNUM) 544 (compare:CCNZ (minus:SI (match_operand:SI 1 "register_operand" "0,r") 545 (match_operand:SI 2 "nonmemory_operand" "r,0")) 546 (const_int 0))) 547 (set (match_operand:SI 0 "register_operand" "=r,r") 548 (minus:SI (match_dup 1) (match_dup 2)))] 549 "reload_completed" 550 "@ 551 sub %2,%0 552 subr %1,%0" 553 [(set_attr "length" "2,2")]) 554 555(define_insn_and_split "negsi2" 556 [(set (match_operand:SI 0 "register_operand" "=r") 557 (neg:SI (match_operand:SI 1 "register_operand" "0")))] 558 "" 559 "#" 560 "reload_completed" 561 [(parallel [(set (match_dup 0) (neg:SI (match_dup 1))) 562 (clobber (reg:CC CC_REGNUM))])]) 563 564(define_insn "negsi2_clobber_flags" 565 [(set (match_operand:SI 0 "register_operand" "=r") 566 (neg:SI (match_operand:SI 1 "register_operand" "0"))) 567 (clobber (reg:CC CC_REGNUM))] 568 "" 569 "subr %.,%0" 570 [(set_attr "length" "2")]) 571 572(define_insn "*negsi2_set_flags" 573 [(set (reg:CCNZ CC_REGNUM) 574 (compare:CCNZ (neg:SI (match_operand:SI 1 "register_operand" "0")) 575 (const_int 0))) 576 (set (match_operand:SI 0 "register_operand" "=r") 577 (neg:SI (match_dup 1)))] 578 "reload_completed" 579 "subr %.,%0" 580 [(set_attr "length" "2")]) 581 582;; ---------------------------------------------------------------------- 583;; MULTIPLY INSTRUCTIONS 584;; ---------------------------------------------------------------------- 585 586(define_expand "mulhisi3" 587 [(set (match_operand:SI 0 "register_operand" "") 588 (mult:SI 589 (sign_extend:SI (match_operand:HI 1 "register_operand" "")) 590 (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" ""))))] 591 "" 592 { 593 if (GET_CODE (operands[2]) == CONST_INT) 594 { 595 emit_insn (gen_mulhisi3_internal2 (operands[0], operands[1], operands[2])); 596 DONE; 597 } 598 }) 599 600(define_insn "*mulhisi3_internal1" 601 [(set (match_operand:SI 0 "register_operand" "=r") 602 (mult:SI 603 (sign_extend:SI (match_operand:HI 1 "register_operand" "%0")) 604 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))] 605 "" 606 "mulh %2,%0" 607 [(set_attr "length" "2") 608 (set_attr "type" "mult")]) 609 610(define_insn "mulhisi3_internal2" 611 [(set (match_operand:SI 0 "register_operand" "=r,r") 612 (mult:SI 613 (sign_extend:SI (match_operand:HI 1 "register_operand" "%0,r")) 614 (match_operand:HI 2 "const_int_operand" "J,K")))] 615 "" 616 "@ 617 mulh %2,%0 618 mulhi %2,%1,%0" 619 [(set_attr "length" "2,4") 620 (set_attr "type" "mult")]) 621 622;; ??? The scheduling info is probably wrong. 623 624;; ??? This instruction can also generate the 32-bit highpart, but using it 625;; may increase code size counter to the desired result. 626 627;; ??? This instructions can also give a DImode result. 628 629;; ??? There is unsigned version, but it matters only for the DImode/highpart 630;; results. 631 632(define_insn "mulsi3" 633 [(set (match_operand:SI 0 "register_operand" "=r") 634 (mult:SI (match_operand:SI 1 "register_operand" "%0") 635 (match_operand:SI 2 "reg_or_int9_operand" "rO")))] 636 "(TARGET_V850E_UP)" 637 "mul %2,%1,%." 638 [(set_attr "length" "4") 639 (set_attr "type" "mult")]) 640 641;; ---------------------------------------------------------------------- 642;; DIVIDE INSTRUCTIONS 643;; ---------------------------------------------------------------------- 644 645;; ??? These insns do set the Z/N condition codes, except that they are based 646;; on only one of the two results, so it doesn't seem to make sense to use 647;; them. 648 649;; ??? The scheduling info is probably wrong. 650 651(define_insn "divmodsi4" 652 [(set (match_operand:SI 0 "register_operand" "=r") 653 (div:SI (match_operand:SI 1 "register_operand" "0") 654 (match_operand:SI 2 "register_operand" "r"))) 655 (set (match_operand:SI 3 "register_operand" "=r") 656 (mod:SI (match_dup 1) 657 (match_dup 2))) 658 (clobber (reg:CC CC_REGNUM))] 659 "TARGET_V850E_UP" 660{ 661 if (TARGET_V850E2_UP) 662 return "divq %2,%0,%3"; 663 else 664 return "div %2,%0,%3"; 665} 666 [(set_attr "length" "4") 667 (set_attr "type" "div")]) 668 669(define_insn "udivmodsi4" 670 [(set (match_operand:SI 0 "register_operand" "=r") 671 (udiv:SI (match_operand:SI 1 "register_operand" "0") 672 (match_operand:SI 2 "register_operand" "r"))) 673 (set (match_operand:SI 3 "register_operand" "=r") 674 (umod:SI (match_dup 1) 675 (match_dup 2))) 676 (clobber (reg:CC CC_REGNUM))] 677 "TARGET_V850E_UP" 678{ 679 if (TARGET_V850E2_UP) 680 return "divqu %2,%0,%3"; 681 else 682 return "divu %2,%0,%3"; 683} 684 [(set_attr "length" "4") 685 (set_attr "type" "div")]) 686 687;; ??? There is a 2 byte instruction for generating only the quotient. 688;; However, it isn't clear how to compute the length field correctly. 689 690(define_insn "divmodhi4" 691 [(set (match_operand:HI 0 "register_operand" "=r") 692 (div:HI (match_operand:HI 1 "register_operand" "0") 693 (match_operand:HI 2 "register_operand" "r"))) 694 (set (match_operand:HI 3 "register_operand" "=r") 695 (mod:HI (match_dup 1) 696 (match_dup 2))) 697 (clobber (reg:CC CC_REGNUM))] 698 "TARGET_V850E_UP" 699 "sxh %0\\n\\tdivh %2,%0,%3" 700 [(set_attr "length" "6") 701 (set_attr "type" "div")]) 702 703;; The half word needs to be zero/sign extended to 32 bits before doing 704;; the division/modulo operation. 705 706(define_insn "udivmodhi4" 707 [(set (match_operand:HI 0 "register_operand" "=r") 708 (udiv:HI (match_operand:HI 1 "register_operand" "0") 709 (match_operand:HI 2 "register_operand" "r"))) 710 (set (match_operand:HI 3 "register_operand" "=r") 711 (umod:HI (match_dup 1) 712 (match_dup 2))) 713 (clobber (reg:CC CC_REGNUM))] 714 "TARGET_V850E_UP" 715 "zxh %0\\n\\ndivhu %2,%0,%3" 716 [(set_attr "length" "6") 717 (set_attr "type" "div")]) 718 719;; ---------------------------------------------------------------------- 720;; AND INSTRUCTIONS 721;; ---------------------------------------------------------------------- 722 723(define_insn "*v850_clr1_1" 724 [(set (match_operand:QI 0 "memory_operand" "=m") 725 (subreg:QI 726 (and:SI (subreg:SI (match_dup 0) 0) 727 (match_operand:QI 1 "not_power_of_two_operand" "")) 0)) 728 (clobber (reg:CC CC_REGNUM))] 729 "" 730{ 731 rtx xoperands[2]; 732 xoperands[0] = operands[0]; 733 xoperands[1] = GEN_INT (~INTVAL (operands[1]) & 0xff); 734 output_asm_insn ("clr1 %M1,%0", xoperands); 735 return ""; 736} 737 [(set_attr "length" "4") 738 (set_attr "type" "bit1")]) 739 740(define_insn "*v850_clr1_2" 741 [(set (match_operand:HI 0 "indirect_operand" "=m") 742 (subreg:HI 743 (and:SI (subreg:SI (match_dup 0) 0) 744 (match_operand:HI 1 "not_power_of_two_operand" "")) 0)) 745 (clobber (reg:CC CC_REGNUM))] 746 "" 747{ 748 int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffff); 749 750 rtx xoperands[2]; 751 xoperands[0] = gen_rtx_MEM (QImode, 752 plus_constant (Pmode, XEXP (operands[0], 0), 753 log2 / 8)); 754 xoperands[1] = GEN_INT (log2 % 8); 755 output_asm_insn ("clr1 %1,%0", xoperands); 756 return ""; 757} 758 [(set_attr "length" "4") 759 (set_attr "type" "bit1")]) 760 761(define_insn "*v850_clr1_3" 762 [(set (match_operand:SI 0 "indirect_operand" "=m") 763 (and:SI (match_dup 0) 764 (match_operand:SI 1 "not_power_of_two_operand" ""))) 765 (clobber (reg:CC CC_REGNUM))] 766 "" 767{ 768 int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffffffff); 769 770 rtx xoperands[2]; 771 xoperands[0] = gen_rtx_MEM (QImode, 772 plus_constant (Pmode, XEXP (operands[0], 0), 773 log2 / 8)); 774 xoperands[1] = GEN_INT (log2 % 8); 775 output_asm_insn ("clr1 %1,%0", xoperands); 776 return ""; 777} 778 [(set_attr "length" "4") 779 (set_attr "type" "bit1")]) 780 781(define_insn_and_split "andsi3" 782 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 783 (and:SI (match_operand:SI 1 "register_operand" "%0,0,r") 784 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))] 785 "" 786 "#" 787 "reload_completed" 788 [(parallel [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2))) 789 (clobber (reg:CC CC_REGNUM))])]) 790 791(define_insn "andsi3_clobber_flags" 792 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 793 (and:SI (match_operand:SI 1 "register_operand" "%0,0,r") 794 (match_operand:SI 2 "nonmemory_operand" "r,I,M"))) 795 (clobber (reg:CC CC_REGNUM))] 796 "reload_completed" 797 "@ 798 and %2,%0 799 and %.,%0 800 andi %2,%1,%0" 801 [(set_attr "length" "2,2,4")]) 802 803(define_insn "andsi3_set_flags" 804 [(set (reg:CC CC_REGNUM) 805 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "%0,0,r") 806 (match_operand:SI 2 "nonmemory_operand" "r,I,M")) 807 (const_int 0))) 808 (set (match_operand:SI 0 "register_operand" "=r,r,r") 809 (and:SI (match_dup 1) (match_dup 2)))] 810 "reload_completed" 811 "@ 812 and %2,%0 813 and %.,%0 814 andi %2,%1,%0" 815 [(set_attr "length" "2,2,4")]) 816 817;; ---------------------------------------------------------------------- 818;; OR INSTRUCTIONS 819;; ---------------------------------------------------------------------- 820 821(define_insn "*v850_set1_1" 822 [(set (match_operand:QI 0 "memory_operand" "=m") 823 (subreg:QI (ior:SI (subreg:SI (match_dup 0) 0) 824 (match_operand 1 "power_of_two_operand" "")) 0)) 825 (clobber (reg:CC CC_REGNUM))] 826 "" 827 "set1 %M1,%0" 828 [(set_attr "length" "4") 829 (set_attr "type" "bit1")]) 830 831(define_insn "*v850_set1_2" 832 [(set (match_operand:HI 0 "indirect_operand" "=m") 833 (subreg:HI (ior:SI (subreg:SI (match_dup 0) 0) 834 (match_operand 1 "power_of_two_operand" "")) 0))] 835 "" 836{ 837 int log2 = exact_log2 (INTVAL (operands[1])); 838 839 if (log2 < 8) 840 return "set1 %M1,%0"; 841 else 842 { 843 rtx xoperands[2]; 844 xoperands[0] = gen_rtx_MEM (QImode, 845 plus_constant (Pmode, XEXP (operands[0], 0), 846 log2 / 8)); 847 xoperands[1] = GEN_INT (log2 % 8); 848 output_asm_insn ("set1 %1,%0", xoperands); 849 } 850 return ""; 851} 852 [(set_attr "length" "4") 853 (set_attr "type" "bit1")]) 854 855(define_insn "*v850_set1_3" 856 [(set (match_operand:SI 0 "indirect_operand" "=m") 857 (ior:SI (match_dup 0) 858 (match_operand 1 "power_of_two_operand" ""))) 859 (clobber (reg:CC CC_REGNUM))] 860 "" 861{ 862 int log2 = exact_log2 (INTVAL (operands[1])); 863 864 if (log2 < 8) 865 return "set1 %M1,%0"; 866 else 867 { 868 rtx xoperands[2]; 869 xoperands[0] = gen_rtx_MEM (QImode, 870 plus_constant (Pmode, XEXP (operands[0], 0), 871 log2 / 8)); 872 xoperands[1] = GEN_INT (log2 % 8); 873 output_asm_insn ("set1 %1,%0", xoperands); 874 } 875 return ""; 876} 877 [(set_attr "length" "4") 878 (set_attr "type" "bit1")]) 879 880(define_insn_and_split "iorsi3" 881 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 882 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,r") 883 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))] 884 "" 885 "#" 886 "reload_completed" 887 [(parallel [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2))) 888 (clobber (reg:CC CC_REGNUM))])]) 889 890(define_insn "iorsi3_clobber_flags" 891 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 892 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,r") 893 (match_operand:SI 2 "nonmemory_operand" "r,I,M"))) 894 (clobber (reg:CC CC_REGNUM))] 895 "" 896 "@ 897 or %2,%0 898 or %.,%0 899 ori %2,%1,%0" 900 [(set_attr "length" "2,2,4")]) 901 902(define_insn "*iorsi3_set_flags" 903 [(set (reg:CC CC_REGNUM) 904 (compare:CC (ior:SI (match_operand:SI 1 "register_operand" "%0,0,r") 905 (match_operand:SI 2 "nonmemory_operand" "r,I,M")) 906 (const_int 0))) 907 (set (match_operand:SI 0 "register_operand" "=r,r,r") 908 (ior:SI (match_dup 1) (match_dup 2)))] 909 "reload_completed" 910 "@ 911 or %2,%0 912 or %.,%0 913 ori %2,%1,%0" 914 [(set_attr "length" "2,2,4")]) 915 916;; ---------------------------------------------------------------------- 917;; XOR INSTRUCTIONS 918;; ---------------------------------------------------------------------- 919 920(define_insn "*v850_not1_1" 921 [(set (match_operand:QI 0 "memory_operand" "=m") 922 (subreg:QI (xor:SI (subreg:SI (match_dup 0) 0) 923 (match_operand 1 "power_of_two_operand" "")) 0)) 924 (clobber (reg:CC CC_REGNUM))] 925 "" 926 "not1 %M1,%0" 927 [(set_attr "length" "4") 928 (set_attr "type" "bit1")]) 929 930(define_insn "*v850_not1_2" 931 [(set (match_operand:HI 0 "indirect_operand" "=m") 932 (subreg:HI (xor:SI (subreg:SI (match_dup 0) 0) 933 (match_operand 1 "power_of_two_operand" "")) 0))] 934 "" 935{ 936 int log2 = exact_log2 (INTVAL (operands[1])); 937 938 if (log2 < 8) 939 return "not1 %M1,%0"; 940 else 941 { 942 rtx xoperands[2]; 943 xoperands[0] = gen_rtx_MEM (QImode, 944 plus_constant (Pmode, XEXP (operands[0], 0), 945 log2 / 8)); 946 xoperands[1] = GEN_INT (log2 % 8); 947 output_asm_insn ("not1 %1,%0", xoperands); 948 } 949 return ""; 950} 951 [(set_attr "length" "4") 952 (set_attr "type" "bit1")]) 953 954(define_insn "*v850_not1_3" 955 [(set (match_operand:SI 0 "indirect_operand" "=m") 956 (xor:SI (match_dup 0) 957 (match_operand 1 "power_of_two_operand" ""))) 958 (clobber (reg:CC CC_REGNUM))] 959 "" 960{ 961 int log2 = exact_log2 (INTVAL (operands[1])); 962 963 if (log2 < 8) 964 return "not1 %M1,%0"; 965 else 966 { 967 rtx xoperands[2]; 968 xoperands[0] = gen_rtx_MEM (QImode, 969 plus_constant (Pmode, XEXP (operands[0], 0), 970 log2 / 8)); 971 xoperands[1] = GEN_INT (log2 % 8); 972 output_asm_insn ("not1 %1,%0", xoperands); 973 } 974 return ""; 975} 976 [(set_attr "length" "4") 977 (set_attr "type" "bit1")]) 978 979(define_insn_and_split "xorsi3" 980 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 981 (xor:SI (match_operand:SI 1 "register_operand" "%0,0,r") 982 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))] 983 "" 984 "#" 985 "reload_completed" 986 [(parallel [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2))) 987 (clobber (reg:CC CC_REGNUM))])]) 988 989(define_insn "xorsi3_clobber_flags" 990 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 991 (xor:SI (match_operand:SI 1 "register_operand" "%0,0,r") 992 (match_operand:SI 2 "nonmemory_operand" "r,I,M"))) 993 (clobber (reg:CC CC_REGNUM))] 994 "" 995 "@ 996 xor %2,%0 997 xor %.,%0 998 xori %2,%1,%0" 999 [(set_attr "length" "2,2,4")]) 1000 1001(define_insn "*xorsi3_set_flags" 1002 [(set (reg:CC CC_REGNUM) 1003 (compare:CC (xor:SI (match_operand:SI 1 "register_operand" "%0,0,r") 1004 (match_operand:SI 2 "nonmemory_operand" "r,I,M")) 1005 (const_int 0))) 1006 (set (match_operand:SI 0 "register_operand" "=r,r,r") 1007 (xor:SI (match_dup 1) (match_dup 2)))] 1008 "reload_completed" 1009 "@ 1010 xor %2,%0 1011 xor %.,%0 1012 xori %2,%1,%0" 1013 [(set_attr "length" "2,2,4")]) 1014 1015 1016;; ---------------------------------------------------------------------- 1017;; NOT INSTRUCTIONS 1018;; ---------------------------------------------------------------------- 1019 1020(define_insn_and_split "one_cmplsi2" 1021 [(set (match_operand:SI 0 "register_operand" "=r") 1022 (not:SI (match_operand:SI 1 "register_operand" "r")))] 1023 "" 1024 "#" 1025 "reload_completed" 1026 [(parallel [(set (match_dup 0) (not:SI (match_dup 1))) 1027 (clobber (reg:CC CC_REGNUM))])]) 1028 1029 1030(define_insn "one_cmplsi2_clobber_flags" 1031 [(set (match_operand:SI 0 "register_operand" "=r") 1032 (not:SI (match_operand:SI 1 "register_operand" "r"))) 1033 (clobber (reg:CC CC_REGNUM))] 1034 "" 1035 "not %1,%0" 1036 [(set_attr "length" "2")]) 1037 1038(define_insn "*one_cmplsi2_set_flags" 1039 [(set (reg:CC CC_REGNUM) 1040 (compare:CC (not:SI (match_operand:SI 1 "register_operand" "r")) 1041 (const_int 0))) 1042 (set (match_operand:SI 0 "register_operand" "=r") 1043 (not:SI (match_dup 1)))] 1044 "reload_completed" 1045 "not %1,%0" 1046 [(set_attr "length" "2")]) 1047 1048;; ----------------------------------------------------------------- 1049;; BIT FIELDS 1050;; ----------------------------------------------------------------- 1051 1052;; ??? Is it worth defining insv and extv for the V850 series?!? 1053 1054;; An insv pattern would be useful, but does not get used because 1055;; store_bit_field never calls insv when storing a constant value into a 1056;; single-bit bitfield. 1057 1058;; extv/extzv patterns would be useful, but do not get used because 1059;; optimize_bitfield_compare in fold-const usually converts single 1060;; bit extracts into an AND with a mask. 1061 1062(define_insn "insv" 1063 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") 1064 (match_operand:SI 1 "immediate_operand" "n") 1065 (match_operand:SI 2 "immediate_operand" "n")) 1066 (match_operand:SI 3 "register_operand" "r")) 1067 (clobber (reg:CC CC_REGNUM))] 1068 "TARGET_V850E3V5_UP" 1069 "bins %3, %2, %1, %0" 1070 [(set_attr "length" "4")]) 1071 1072;; ----------------------------------------------------------------- 1073;; Scc INSTRUCTIONS 1074;; ----------------------------------------------------------------- 1075 1076(define_insn_and_split "*cbranchsi4_insn" 1077 [(set (pc) 1078 (if_then_else (match_operator 0 "comparison_operator" 1079 [(match_operand:SI 1 "register_operand" "r") 1080 (match_operand:SI 2 "reg_or_int5_operand" "rJ")]) 1081 (label_ref (match_operand 3 "" "")) 1082 (pc)))] 1083 "" 1084 "#" 1085 "reload_completed" 1086 [(set (reg:CC CC_REGNUM) 1087 (compare:CC (match_dup 1) (match_dup 2))) 1088 (set (pc) 1089 (if_then_else (match_op_dup 0 1090 [(reg:CC CC_REGNUM) (const_int 0)]) 1091 (label_ref (match_dup 3)) 1092 (pc)))] 1093 "") 1094 1095 1096(define_insn_and_split "cstoresi4" 1097 [(set (match_operand:SI 0 "register_operand" "=r") 1098 (match_operator:SI 1 "comparison_operator" 1099 [(match_operand:SI 2 "register_operand" "r") 1100 (match_operand:SI 3 "reg_or_int5_operand" "rJ")]))] 1101 "" 1102 "#" 1103 "reload_completed" 1104 [(set (reg:CC CC_REGNUM) 1105 (compare:CC (match_dup 2) (match_dup 3))) 1106 (set (match_dup 0) (match_op_dup 1 1107 [(reg:CC CC_REGNUM) (const_int 0)]))] 1108 "") 1109 1110(define_insn "*setcc_insn" 1111 [(set (match_operand:SI 0 "register_operand" "=r") 1112 (match_operator:SI 1 "comparison_operator" 1113 [(reg:CC CC_REGNUM) (const_int 0)]))] 1114 "reload_completed" 1115 "setf %c1,%0" 1116 [(set_attr "length" "4")]) 1117 1118(define_insn "set_z_insn" 1119 [(set (match_operand:SI 0 "register_operand" "=r") 1120 (match_operand 1 "v850_float_z_comparison_operator" ""))] 1121 "TARGET_V850E2V3_UP" 1122 "setf z,%0" 1123 [(set_attr "length" "4")]) 1124 1125(define_insn "set_nz_insn" 1126 [(set (match_operand:SI 0 "register_operand" "=r") 1127 (match_operand 1 "v850_float_nz_comparison_operator" ""))] 1128 "TARGET_V850E2V3_UP" 1129 "setf nz,%0" 1130 [(set_attr "length" "4")]) 1131 1132;; ---------------------------------------------------------------------- 1133;; CONDITIONAL MOVE INSTRUCTIONS 1134;; ---------------------------------------------------------------------- 1135 1136;; Instructions using cc0 aren't allowed to have input reloads, so we must 1137;; hide the fact that this instruction uses cc0. We do so by including the 1138;; compare instruction inside it. 1139 1140(define_expand "movsicc" 1141 [(set (match_operand:SI 0 "register_operand" "=r") 1142 (if_then_else:SI 1143 (match_operand 1 "comparison_operator") 1144 (match_operand:SI 2 "reg_or_const_operand" "rJ") 1145 (match_operand:SI 3 "reg_or_const_operand" "rI")))] 1146 "(TARGET_V850E_UP)" 1147 { 1148 /* Make sure that we have an integer comparison... */ 1149 if (GET_MODE (XEXP (operands[1], 0)) != CCmode 1150 && GET_MODE (XEXP (operands[1], 0)) != SImode) 1151 FAIL; 1152 1153 if ((GET_CODE (operands[2]) == CONST_INT 1154 && GET_CODE (operands[3]) == CONST_INT)) 1155 { 1156 int o2 = INTVAL (operands[2]); 1157 int o3 = INTVAL (operands[3]); 1158 1159 if (o2 == 1 && o3 == 0) 1160 FAIL; /* setf */ 1161 if (o3 == 1 && o2 == 0) 1162 FAIL; /* setf */ 1163 if (o2 == 0 && (o3 < -16 || o3 > 15) && exact_log2 (o3) >= 0) 1164 FAIL; /* setf + shift */ 1165 if (o3 == 0 && (o2 < -16 || o2 > 15) && exact_log2 (o2) >=0) 1166 FAIL; /* setf + shift */ 1167 if (o2 != 0) 1168 operands[2] = copy_to_mode_reg (SImode, operands[2]); 1169 if (o3 !=0 ) 1170 operands[3] = copy_to_mode_reg (SImode, operands[3]); 1171 } 1172 else 1173 { 1174 if (GET_CODE (operands[2]) != REG) 1175 operands[2] = copy_to_mode_reg (SImode,operands[2]); 1176 if (GET_CODE (operands[3]) != REG) 1177 operands[3] = copy_to_mode_reg (SImode, operands[3]); 1178 } 1179 }) 1180 1181(define_insn "movsicc_normal_cc" 1182 [(set (match_operand:SI 0 "register_operand" "=r") 1183 (if_then_else:SI 1184 (match_operator 1 "comparison_operator" 1185 [(reg:CC CC_REGNUM) (const_int 0)]) 1186 (match_operand:SI 2 "reg_or_int5_operand" "rJ") 1187 (match_operand:SI 3 "reg_or_0_operand" "rI")))] 1188 "reload_completed && (TARGET_V850E_UP)" 1189 "cmov %c1,%2,%z3,%0"; 1190 [(set_attr "length" "6")]) 1191 1192(define_insn "movsicc_reversed_cc" 1193 [(set (match_operand:SI 0 "register_operand" "=r") 1194 (if_then_else:SI 1195 (match_operator 1 "comparison_operator" 1196 [(reg:CC CC_REGNUM) (const_int 0)]) 1197 (match_operand:SI 2 "reg_or_0_operand" "rI") 1198 (match_operand:SI 3 "reg_or_int5_operand" "rJ")))] 1199 "reload_completed && (TARGET_V850E_UP)" 1200 "cmov %C1,%3,%z2,%0" 1201 [(set_attr "length" "6")]) 1202 1203(define_insn_and_split "*movsicc_normal" 1204 [(set (match_operand:SI 0 "register_operand" "=r") 1205 (if_then_else:SI 1206 (match_operator 1 "comparison_operator" 1207 [(match_operand:SI 4 "register_operand" "r") 1208 (match_operand:SI 5 "reg_or_int5_operand" "rJ")]) 1209 (match_operand:SI 2 "reg_or_int5_operand" "rJ") 1210 (match_operand:SI 3 "reg_or_0_operand" "rI")))] 1211 "(TARGET_V850E_UP)" 1212 "#" 1213 "reload_completed" 1214 [(set (reg:CC CC_REGNUM) 1215 (compare:CC (match_dup 4) (match_dup 5))) 1216 (set (match_dup 0) 1217 (if_then_else:SI (match_op_dup 1 1218 [(reg:CC CC_REGNUM) (const_int 0)]) 1219 (match_dup 2) (match_dup 3)))]) 1220 1221 1222(define_insn_and_split "*movsicc_reversed" 1223 [(set (match_operand:SI 0 "register_operand" "=r") 1224 (if_then_else:SI 1225 (match_operator 1 "comparison_operator" 1226 [(match_operand:SI 4 "register_operand" "r") 1227 (match_operand:SI 5 "reg_or_int5_operand" "rJ")]) 1228 (match_operand:SI 2 "reg_or_int5_operand" "rI") 1229 (match_operand:SI 3 "reg_or_0_operand" "rJ")))] 1230 "(TARGET_V850E_UP)" 1231 "#" 1232 "reload_completed" 1233 [(set (reg:CC CC_REGNUM) 1234 (compare:CC (match_dup 4) (match_dup 5))) 1235 (set (match_dup 0) 1236 (if_then_else:SI (match_op_dup 1 1237 [(reg:CC CC_REGNUM) (const_int 0)]) 1238 (match_dup 2) (match_dup 3)))]) 1239 1240;; We could expose the setting of the condition codes here. 1241(define_insn "*movsicc_tst1" 1242 [(set (match_operand:SI 0 "register_operand" "=r") 1243 (if_then_else:SI 1244 (match_operator 1 "comparison_operator" 1245 [(zero_extract:SI 1246 (match_operand:QI 2 "memory_operand" "m") 1247 (const_int 1) 1248 (match_operand 3 "const_int_operand" "n")) 1249 (const_int 0)]) 1250 (match_operand:SI 4 "reg_or_int5_operand" "rJ") 1251 (match_operand:SI 5 "reg_or_0_operand" "rI"))) 1252 (clobber (reg:CC CC_REGNUM))] 1253 "(TARGET_V850E_UP)" 1254 "tst1 %3,%2 ; cmov %c1,%4,%z5,%0" 1255 [(set_attr "length" "8")]) 1256 1257;; We could expose the setting of the condition codes here. 1258(define_insn "*movsicc_tst1_reversed" 1259 [(set (match_operand:SI 0 "register_operand" "=r") 1260 (if_then_else:SI 1261 (match_operator 1 "comparison_operator" 1262 [(zero_extract:SI 1263 (match_operand:QI 2 "memory_operand" "m") 1264 (const_int 1) 1265 (match_operand 3 "const_int_operand" "n")) 1266 (const_int 0)]) 1267 (match_operand:SI 4 "reg_or_0_operand" "rI") 1268 (match_operand:SI 5 "reg_or_int5_operand" "rJ"))) 1269 (clobber (reg:CC CC_REGNUM))] 1270 "(TARGET_V850E_UP)" 1271 "tst1 %3,%2 ; cmov %C1,%5,%z4,%0" 1272 [(set_attr "length" "8")]) 1273 1274;; Matching for sasf requires combining 4 instructions, so we provide a 1275;; dummy pattern to match the first 3, which will always be turned into the 1276;; second pattern by subsequent combining. As above, we must include the 1277;; comparison to avoid input reloads in an insn using cc0. 1278 1279;; We could expose the setting of the condition codes here. 1280;; However, I haven't seen this pattern used, so I'm not going 1281;; to bother. 1282(define_insn "*sasf" 1283 [(set (match_operand:SI 0 "register_operand" "=r") 1284 (ior:SI 1285 (match_operator 1 "comparison_operator" 1286 [(match_operand:SI 3 "register_operand" "r") 1287 (match_operand:SI 4 "reg_or_int5_operand" "rJ")]) 1288 (ashift:SI (match_operand:SI 2 "register_operand" "0") 1289 (const_int 1)))) 1290 (clobber (reg:CC CC_REGNUM))] 1291 "(TARGET_V850E_UP)" 1292 "cmp %4,%3 ; sasf %c1,%0" 1293 [(set_attr "length" "6")]) 1294 1295(define_split 1296 [(set (match_operand:SI 0 "register_operand" "") 1297 (if_then_else:SI 1298 (match_operator 1 "comparison_operator" 1299 [(match_operand:SI 4 "register_operand" "") 1300 (match_operand:SI 5 "reg_or_int5_operand" "")]) 1301 (match_operand:SI 2 "const_int_operand" "") 1302 (match_operand:SI 3 "const_int_operand" ""))) 1303 (clobber (reg:CC CC_REGNUM))] 1304 "(TARGET_V850E_UP) 1305 && ((INTVAL (operands[2]) ^ INTVAL (operands[3])) == 1) 1306 && ((INTVAL (operands[2]) + INTVAL (operands[3])) != 1) 1307 && (GET_CODE (operands[5]) == CONST_INT 1308 || REGNO (operands[0]) != REGNO (operands[5])) 1309 && REGNO (operands[0]) != REGNO (operands[4])" 1310 [(set (match_dup 0) (match_dup 6)) 1311 (parallel [(set (match_dup 0) 1312 (ior:SI (match_op_dup 7 [(match_dup 4) (match_dup 5)]) 1313 (ashift:SI (match_dup 0) (const_int 1)))) 1314 (clobber (reg:CC CC_REGNUM))])] 1315 { 1316 operands[6] = GEN_INT (INTVAL (operands[2]) >> 1); 1317 if (INTVAL (operands[2]) & 0x1) 1318 operands[7] = operands[1]; 1319 else 1320 operands[7] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[1])), 1321 GET_MODE (operands[1]), 1322 XEXP (operands[1], 0), XEXP (operands[1], 1)); 1323 }) 1324 1325;; --------------------------------------------------------------------- 1326;; BYTE SWAP INSTRUCTIONS 1327;; --------------------------------------------------------------------- 1328(define_expand "rotlhi3" 1329 [(parallel [(set (match_operand:HI 0 "register_operand" "") 1330 (rotate:HI (match_operand:HI 1 "register_operand" "") 1331 (match_operand:HI 2 "const_int_operand" ""))) 1332 (clobber (reg:CC CC_REGNUM))])] 1333 "(TARGET_V850E_UP)" 1334 { 1335 if (INTVAL (operands[2]) != 8) 1336 FAIL; 1337 }) 1338 1339(define_insn "*rotlhi3_8" 1340 [(set (match_operand:HI 0 "register_operand" "=r") 1341 (rotate:HI (match_operand:HI 1 "register_operand" "r") 1342 (const_int 8))) 1343 (clobber (reg:CC CC_REGNUM))] 1344 "(TARGET_V850E_UP)" 1345 "bsh %1,%0" 1346 [(set_attr "length" "4")]) 1347 1348(define_expand "rotlsi3" 1349 [(parallel [(set (match_operand:SI 0 "register_operand" "") 1350 (rotate:SI (match_operand:SI 1 "register_operand" "") 1351 (match_operand:SI 2 "const_int_operand" ""))) 1352 (clobber (reg:CC CC_REGNUM))])] 1353 "(TARGET_V850E_UP)" 1354 { 1355 if (INTVAL (operands[2]) != 16) 1356 FAIL; 1357 }) 1358 1359(define_insn "rotlsi3_a" 1360 [(set (match_operand:SI 0 "register_operand" "=r") 1361 (match_operator:SI 4 "ior_operator" 1362 [(ashift:SI (match_operand:SI 1 "register_operand" "r") 1363 (match_operand:SI 2 "const_int_operand" "n")) 1364 (lshiftrt:SI (match_dup 1) 1365 (match_operand:SI 3 "const_int_operand" "n"))])) 1366 (clobber (reg:CC CC_REGNUM))] 1367 "TARGET_V850E3V5_UP && (INTVAL (operands[2]) + INTVAL (operands[3]) == 32)" 1368 "rotl %2, %1, %0" 1369 [(set_attr "length" "4")]) 1370 1371(define_insn "rotlsi3_b" 1372 [(set (match_operand:SI 0 "register_operand" "=r") 1373 (match_operator:SI 4 "ior_operator" 1374 [(lshiftrt:SI (match_operand:SI 1 "register_operand" "r") 1375 (match_operand:SI 3 "const_int_operand" "n")) 1376 (ashift:SI (match_dup 1) 1377 (match_operand:SI 2 "const_int_operand" "n"))])) 1378 (clobber (reg:CC CC_REGNUM))] 1379 "TARGET_V850E3V5_UP && (INTVAL (operands[2]) + INTVAL (operands[3]) == 32)" 1380 "rotl %2, %1, %0" 1381 [(set_attr "length" "4")]) 1382 1383(define_insn "rotlsi3_v850e3v5" 1384 [(set (match_operand:SI 0 "register_operand" "=r") 1385 (rotate:SI (match_operand:SI 1 "register_operand" "r") 1386 (match_operand:SI 2 "e3v5_shift_operand" "rn"))) 1387 (clobber (reg:CC CC_REGNUM))] 1388 "TARGET_V850E3V5_UP" 1389 "rotl %2, %1, %0" 1390 [(set_attr "length" "4")]) 1391 1392(define_insn "*rotlsi3_16" 1393 [(set (match_operand:SI 0 "register_operand" "=r") 1394 (rotate:SI (match_operand:SI 1 "register_operand" "r") 1395 (const_int 16))) 1396 (clobber (reg:CC CC_REGNUM))] 1397 "(TARGET_V850E_UP)" 1398 "hsw %1,%0" 1399 [(set_attr "length" "4")]) 1400 1401;; ---------------------------------------------------------------------- 1402;; JUMP INSTRUCTIONS 1403;; ---------------------------------------------------------------------- 1404 1405;; Doloop 1406 1407(define_expand "doloop_begin" 1408 [(use (match_operand 0 "" "")) ; loop pseudo 1409 (use (match_operand 1 "" ""))] ; doloop_end pattern 1410 "TARGET_V850E3V5_UP && TARGET_LOOP" 1411 { 1412 rtx loop_cnt = operands[0]; 1413 gcc_assert (GET_MODE (loop_cnt) == SImode); 1414 emit_insn (gen_fix_loop_counter (loop_cnt)); 1415 DONE; 1416 } 1417) 1418 1419;; Note the embedded arithmetic. That affects the condition codes! 1420(define_insn "fix_loop_counter" 1421 [(unspec:SI [(match_operand:SI 0 "register_operand" "+r,!m") 1422 (clobber (match_scratch:SI 1 "=X,r"))] UNSPEC_LOOP) 1423 (clobber (reg:CC CC_REGNUM))] 1424 "TARGET_V850E3V5_UP && TARGET_LOOP" 1425 { 1426 switch (which_alternative) 1427 { 1428 case 0: return "add 1, %0 # LOOP_BEGIN"; 1429 case 1: return "ld.w %0, %1; add 1, %1; st.w %1, %0 # LOOP_BEGIN"; 1430 default: gcc_unreachable (); 1431 } 1432 } 1433 [(set_attr "length" "2,6")]) 1434 1435(define_expand "doloop_end" 1436 [(use (match_operand 0 "" "")) ; loop pseudo 1437 (use (match_operand 1 "" ""))] ; label 1438 "TARGET_V850E3V5_UP && TARGET_LOOP" 1439 { 1440 rtx loop_cnt = operands[0]; 1441 rtx label = operands[1]; 1442 1443 if (GET_MODE (loop_cnt) != SImode) 1444 FAIL; 1445 1446 emit_jump_insn (gen_doloop_end_internal_loop (label, loop_cnt)); 1447 DONE; 1448 } 1449) 1450 1451(define_insn "doloop_end_internal_loop" 1452 [(set (pc) 1453 (if_then_else (ne (match_operand:SI 1 "register_operand" "+r,!m") 1454 (const_int 0)) 1455 (label_ref (match_operand 0 "" "")) 1456 (pc))) 1457 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1))) 1458 (clobber (match_scratch:SI 2 "=X,r")) 1459 (clobber (reg:CC CC_REGNUM))] 1460 "TARGET_V850E3V5_UP && TARGET_LOOP" 1461 { 1462 switch (which_alternative) 1463 { 1464 case 0: 1465 if (get_attr_length (insn) == 4) 1466 return "loop %1, %0 # LOOP.1.0"; 1467 1468 return "add -1, %1; bne %l0 # LOOP.1.1"; 1469 case 1: 1470 return "ld.w %1, %2; add -1, %2; st.w %2, %1; bne %l0 # LOOP.2.1"; 1471 default: 1472 gcc_unreachable (); 1473 } 1474 } 1475 [(set (attr "length") 1476 (if_then_else (lt (abs (minus (match_dup 0) (pc))) 1477 (const_int 65534)) 1478 (const_int 4) 1479 (const_int 14)))]) 1480 1481;; Conditional jump instructions 1482 1483(define_insn_and_split "*cbranchsi4_insn" 1484 [(set (pc) 1485 (if_then_else (match_operator 0 "comparison_operator" 1486 [(match_operand:SI 1 "register_operand" "r") 1487 (match_operand:SI 2 "reg_or_int5_operand" "rJ")]) 1488 (label_ref (match_operand 3 "" "")) 1489 (pc)))] 1490 "" 1491 "#" 1492 "reload_completed" 1493 [(set (reg:CC CC_REGNUM) 1494 (compare:CC (match_dup 1) (match_dup 2))) 1495 (set (pc) 1496 (if_then_else (match_op_dup 0 1497 [(reg:CC CC_REGNUM) (const_int 0)]) 1498 (label_ref (match_dup 3)) 1499 (pc)))] 1500 "") 1501 1502(define_insn "*branch_normal" 1503 [(set (pc) 1504 (if_then_else (match_operator 1 "comparison_operator" 1505 [(reg CC_REGNUM) (const_int 0)]) 1506 (label_ref (match_operand 0 "" "")) 1507 (pc)))] 1508 "reload_completed" 1509{ 1510 bool nzmode = GET_MODE (XEXP (operands[1], 0)) == CCNZmode; 1511 if (get_attr_length (insn) == 2) 1512 { 1513 if (nzmode) 1514 return "b%d1 %l0"; 1515 else 1516 return "b%b1 %l0"; 1517 } 1518 if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4) 1519 { 1520 if (nzmode) 1521 return "b%d1 %l0"; 1522 else 1523 return "b%b1 %l0"; 1524 } 1525 if (nzmode) 1526 return "b%D1 .+6 ; jr %l0"; 1527 else 1528 return "b%B1 .+6 ; jr %l0"; 1529} 1530 [(set (attr "length") 1531 (if_then_else (lt (abs (minus (match_dup 0) (pc))) 1532 (const_int 256)) 1533 (const_int 2) 1534 (if_then_else (lt (abs (minus (match_dup 0) (pc))) 1535 (const_int 65536)) 1536 (const_int 4) 1537 (const_int 6))))]) 1538 1539(define_insn "*branch_invert" 1540 [(set (pc) 1541 (if_then_else (match_operator 1 "comparison_operator" 1542 [(reg CC_REGNUM) (const_int 0)]) 1543 (pc) 1544 (label_ref (match_operand 0 "" ""))))] 1545 "reload_completed" 1546{ 1547 bool nzmode = GET_MODE (XEXP (operands[1], 0)) == CCNZmode; 1548 1549 if (get_attr_length (insn) == 2) 1550 { 1551 if (nzmode) 1552 return "b%D1 %l0"; 1553 else 1554 return "b%B1 %l0"; 1555 } 1556 1557 if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4) 1558 { 1559 if (nzmode) 1560 return "b%D1 %l0"; 1561 else 1562 return "b%B1 %l0"; 1563 } 1564 1565 if (nzmode) 1566 return "b%d1 .+6 ; jr %l0"; 1567 else 1568 return "b%b1 .+6 ; jr %l0"; 1569} 1570 [(set (attr "length") 1571 (if_then_else (lt (abs (minus (match_dup 0) (pc))) 1572 (const_int 256)) 1573 (const_int 2) 1574 (if_then_else (lt (abs (minus (match_dup 0) (pc))) 1575 (const_int 65536)) 1576 (const_int 4) 1577 (const_int 6))))]) 1578 1579;; Unconditional and other jump instructions. 1580 1581(define_insn "jump" 1582 [(set (pc) 1583 (label_ref (match_operand 0 "" "")))] 1584 "" 1585{ 1586 if (get_attr_length (insn) == 2) 1587 return "br %0"; 1588 else 1589 return "jr %0"; 1590} 1591 [(set (attr "length") 1592 (if_then_else (lt (abs (minus (match_dup 0) (pc))) 1593 (const_int 256)) 1594 (const_int 2) 1595 (const_int 4)))]) 1596 1597(define_insn "indirect_jump" 1598 [(set (pc) (match_operand:SI 0 "register_operand" "r"))] 1599 "" 1600 "jmp %0" 1601 [(set_attr "length" "2")]) 1602 1603(define_insn "tablejump" 1604 [(set (pc) (match_operand:SI 0 "register_operand" "r")) 1605 (use (label_ref (match_operand 1 "" "")))] 1606 "" 1607 "jmp %0" 1608 [(set_attr "length" "2")]) 1609 1610(define_insn "switch" 1611 [(set (pc) 1612 (plus:SI 1613 (sign_extend:SI 1614 (mem:HI 1615 (plus:SI (ashift:SI (match_operand:SI 0 "register_operand" "r") 1616 (const_int 1)) 1617 (label_ref (match_operand 1 "" ""))))) 1618 (label_ref (match_dup 1))))] 1619 "(TARGET_V850E_UP)" 1620 "switch %0" 1621 [(set_attr "length" "2")]) 1622 1623(define_expand "casesi" 1624 [(match_operand:SI 0 "register_operand" "") 1625 (match_operand:SI 1 "register_operand" "") 1626 (match_operand:SI 2 "register_operand" "") 1627 (match_operand 3 "" "") (match_operand 4 "" "")] 1628 "" 1629 { 1630 rtx reg = gen_reg_rtx (SImode); 1631 rtx tableaddress = gen_reg_rtx (SImode); 1632 rtx test; 1633 rtx mem; 1634 1635 /* Subtract the lower bound from the index. */ 1636 emit_insn (gen_subsi3 (reg, operands[0], operands[1])); 1637 1638 /* Compare the result against the number of table entries; 1639 branch to the default label if out of range of the table. */ 1640 test = gen_rtx_fmt_ee (GTU, VOIDmode, reg, operands[2]); 1641 emit_jump_insn (gen_cbranchsi4 (test, reg, operands[2], operands[4])); 1642 1643 /* Shift index for the table array access. */ 1644 emit_insn (gen_ashlsi3 (reg, reg, GEN_INT (TARGET_BIG_SWITCH ? 2 : 1))); 1645 /* Load the table address into a pseudo. */ 1646 emit_insn (gen_movsi (tableaddress, 1647 gen_rtx_LABEL_REF (Pmode, operands[3]))); 1648 /* Add the table address to the index. */ 1649 emit_insn (gen_addsi3 (reg, reg, tableaddress)); 1650 /* Load the table entry. */ 1651 mem = gen_const_mem (CASE_VECTOR_MODE, reg); 1652 if (! TARGET_BIG_SWITCH) 1653 { 1654 rtx reg2 = gen_reg_rtx (HImode); 1655 emit_insn (gen_movhi (reg2, mem)); 1656 emit_insn (gen_extendhisi2 (reg, reg2)); 1657 } 1658 else 1659 emit_insn (gen_movsi (reg, mem)); 1660 /* Add the table address. */ 1661 emit_insn (gen_addsi3 (reg, reg, tableaddress)); 1662 /* Branch to the switch label. */ 1663 emit_jump_insn (gen_tablejump (reg, operands[3])); 1664 DONE; 1665 }) 1666 1667;; Call subroutine with no return value. 1668 1669(define_expand "call" 1670 [(call (match_operand:QI 0 "general_operand" "") 1671 (match_operand:SI 1 "general_operand" ""))] 1672 "" 1673 { 1674 if (! call_address_operand (XEXP (operands[0], 0), QImode) 1675 || TARGET_LONG_CALLS) 1676 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0)); 1677 if (TARGET_LONG_CALLS) 1678 emit_call_insn (gen_call_internal_long (XEXP (operands[0], 0), operands[1])); 1679 else 1680 emit_call_insn (gen_call_internal_short (XEXP (operands[0], 0), operands[1])); 1681 1682 DONE; 1683 }) 1684 1685(define_insn "call_internal_short" 1686 [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r")) 1687 (match_operand:SI 1 "general_operand" "g,g")) 1688 (clobber (reg:CC CC_REGNUM)) 1689 (clobber (reg:SI 31))] 1690 "! TARGET_LONG_CALLS" 1691 { 1692 if (which_alternative == 1) 1693 { 1694 if (TARGET_V850E3V5_UP) 1695 return "jarl [%0], r31"; 1696 1697 return "jarl .+4, r31 ; add 4, r31 ; jmp %0"; 1698 } 1699 1700 return "jarl %0, r31"; 1701 } 1702 [(set_attr "length" "4,8")]) 1703 1704(define_insn "call_internal_long" 1705 [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r")) 1706 (match_operand:SI 1 "general_operand" "g,g")) 1707 (clobber (reg:CC CC_REGNUM)) 1708 (clobber (reg:SI 31))] 1709 "TARGET_LONG_CALLS" 1710{ 1711 if (which_alternative == 0) 1712 { 1713 if (GET_CODE (operands[0]) == REG) 1714 return "jarl %0,r31"; 1715 1716 if (TARGET_V850E3V5_UP) 1717 return "mov hilo(%0), r11 ; jarl [r11], r31"; 1718 1719 return "movhi hi(%0), r0, r11 ; movea lo(%0), r11, r11 ; jarl .+4,r31 ; add 4, r31 ; jmp r11"; 1720 } 1721 1722 if (TARGET_V850E3V5_UP) 1723 return "jarl [%0], r31"; 1724 1725 return "jarl .+4,r31 ; add 4,r31 ; jmp %0"; 1726} 1727 [(set_attr "length" "16,8")]) 1728 1729;; Call subroutine, returning value in operand 0 1730;; (which must be a hard register). 1731 1732(define_expand "call_value" 1733 [(set (match_operand 0 "" "") 1734 (call (match_operand:QI 1 "general_operand" "") 1735 (match_operand:SI 2 "general_operand" "")))] 1736 "" 1737 { 1738 if (! call_address_operand (XEXP (operands[1], 0), QImode) 1739 || TARGET_LONG_CALLS) 1740 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0)); 1741 if (TARGET_LONG_CALLS) 1742 emit_call_insn (gen_call_value_internal_long (operands[0], 1743 XEXP (operands[1], 0), 1744 operands[2])); 1745 else 1746 emit_call_insn (gen_call_value_internal_short (operands[0], 1747 XEXP (operands[1], 0), 1748 operands[2])); 1749 DONE; 1750 }) 1751 1752(define_insn "call_value_internal_short" 1753 [(set (match_operand 0 "" "=r,r") 1754 (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r")) 1755 (match_operand:SI 2 "general_operand" "g,g"))) 1756 (clobber (reg:CC CC_REGNUM)) 1757 (clobber (reg:SI 31))] 1758 "! TARGET_LONG_CALLS" 1759 { 1760 if (which_alternative == 1) 1761 { 1762 if (TARGET_V850E3V5_UP) 1763 return "jarl [%1], r31"; 1764 1765 return "jarl .+4, r31 ; add 4, r31 ; jmp %1"; 1766 } 1767 1768 return "jarl %1, r31"; 1769 } 1770 [(set_attr "length" "4,8")]) 1771 1772(define_insn "call_value_internal_long" 1773 [(set (match_operand 0 "" "=r,r") 1774 (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r")) 1775 (match_operand:SI 2 "general_operand" "g,g"))) 1776 (clobber (reg:CC CC_REGNUM)) 1777 (clobber (reg:SI 31))] 1778 "TARGET_LONG_CALLS" 1779{ 1780 if (which_alternative == 0) 1781 { 1782 if (GET_CODE (operands[1]) == REG) 1783 return "jarl %1, r31"; 1784 1785 /* Reload can generate this pattern.... */ 1786 if (TARGET_V850E3V5_UP) 1787 return "mov hilo(%1), r11 ; jarl [r11], r31"; 1788 1789 return "movhi hi(%1), r0, r11 ; movea lo(%1), r11, r11 ; jarl .+4, r31 ; add 4, r31 ; jmp r11"; 1790 } 1791 1792 if (TARGET_V850E3V5_UP) 1793 return "jarl [%1], r31"; 1794 1795 return "jarl .+4, r31 ; add 4, r31 ; jmp %1"; 1796} 1797 [(set_attr "length" "16,8")]) 1798 1799(define_insn "nop" 1800 [(const_int 0)] 1801 "" 1802 "nop" 1803 [(set_attr "length" "2")]) 1804 1805;; ---------------------------------------------------------------------- 1806;; EXTEND INSTRUCTIONS 1807;; ---------------------------------------------------------------------- 1808 1809;; We only need the CC clobber because of the andi alternative 1810(define_insn "*zero_extendhisi2_v850e" 1811 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") 1812 (zero_extend:SI 1813 (match_operand:HI 1 "nonimmediate_operand" "0,r,T,m"))) 1814 (clobber (reg:CC CC_REGNUM))] 1815 "(TARGET_V850E_UP)" 1816 "@ 1817 zxh %0 1818 andi 65535,%1,%0 1819 sld.hu %1,%0 1820 ld.hu %1,%0" 1821 [(set_attr "length" "2,4,2,4")]) 1822 1823(define_insn "*zero_extendhisi2_v850" 1824 [(set (match_operand:SI 0 "register_operand" "=r") 1825 (zero_extend:SI 1826 (match_operand:HI 1 "register_operand" "r"))) 1827 (clobber (reg:CC CC_REGNUM))] ;; A lie, but we have to match the expander 1828 "" 1829 "andi 65535,%1,%0" 1830 [(set_attr "length" "4")]) 1831 1832(define_insn "*zero_extendhisi2_v850_set_flags" 1833 [(set (reg:CCNZ CC_REGNUM) 1834 (compare:CCNZ (zero_extend:SI (match_operand:HI 1 "register_operand" "r")) 1835 (const_int 0))) 1836 (set (match_operand:SI 0 "register_operand" "=r") 1837 (zero_extend:SI (match_dup 1)))] 1838 "reload_completed" 1839 "andi 65535,%1,%0" 1840 [(set_attr "length" "4")]) 1841 1842(define_expand "zero_extendhisi2" 1843 [(parallel [(set (match_operand:SI 0 "register_operand") 1844 (zero_extend:SI 1845 (match_operand:HI 1 "nonimmediate_operand"))) 1846 (clobber (reg:CC CC_REGNUM))])] 1847 "" 1848 { 1849 if (! (TARGET_V850E_UP)) 1850 operands[1] = force_reg (HImode, operands[1]); 1851 }) 1852 1853(define_insn "*zero_extendqisi2_v850e" 1854 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") 1855 (zero_extend:SI 1856 (match_operand:QI 1 "nonimmediate_operand" "0,r,T,m"))) 1857 (clobber (reg:CC CC_REGNUM))] 1858 "(TARGET_V850E_UP)" 1859 "@ 1860 zxb %0 1861 andi 255,%1,%0 1862 sld.bu %1,%0 1863 ld.bu %1,%0" 1864 [(set_attr "length" "2,4,2,4")]) 1865 1866(define_insn "*zero_extendqisi2_v850" 1867 [(set (match_operand:SI 0 "register_operand" "=r") 1868 (zero_extend:SI 1869 (match_operand:QI 1 "register_operand" "r"))) 1870 (clobber (reg:CC CC_REGNUM))] ;; A lie, but we have to match the expander 1871 "" 1872 "andi 255,%1,%0" 1873 [(set_attr "length" "4")]) 1874 1875(define_insn "*zero_extendqisi2_v850_set_flags" 1876 [(set (reg:CCNZ CC_REGNUM) 1877 (compare:CCNZ (zero_extend:SI (match_operand:QI 1 "register_operand" "r")) 1878 (const_int 0))) 1879 (set (match_operand:SI 0 "register_operand" "=r") 1880 (zero_extend:SI (match_dup 1)))] 1881 "reload_completed" 1882 "andi 255,%1,%0" 1883 [(set_attr "length" "4")]) 1884 1885(define_expand "zero_extendqisi2" 1886 [(parallel [(set (match_operand:SI 0 "register_operand") 1887 (zero_extend:SI 1888 (match_operand:QI 1 "nonimmediate_operand"))) 1889 (clobber (reg:CC CC_REGNUM))])] 1890 "" 1891 { 1892 if (! (TARGET_V850E_UP)) 1893 operands[1] = force_reg (QImode, operands[1]); 1894 }) 1895 1896;;- sign extension instructions 1897 1898;; ??? The extendhisi2 pattern should not emit shifts for v850e? 1899 1900(define_insn "*extendhisi_insn" 1901 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 1902 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,Q,m")))] 1903 "(TARGET_V850E_UP)" 1904 "@ 1905 sxh %0 1906 sld.h %1,%0 1907 ld.h %1,%0" 1908 [(set_attr "length" "2,2,4")]) 1909 1910;; ??? This is missing a sign extend from memory pattern to match the ld.h 1911;; instruction. 1912 1913(define_expand "extendhisi2" 1914 [(parallel [(set (match_dup 2) 1915 (ashift:SI (match_operand:HI 1 "register_operand" "") 1916 (const_int 16))) 1917 (clobber (reg:CC CC_REGNUM))]) 1918 (parallel [(set (match_operand:SI 0 "register_operand" "") 1919 (ashiftrt:SI (match_dup 2) 1920 (const_int 16))) 1921 (clobber (reg:CC CC_REGNUM))])] 1922 "" 1923 { 1924 operands[1] = gen_lowpart (SImode, operands[1]); 1925 operands[2] = gen_reg_rtx (SImode); 1926 }) 1927 1928;; ??? The extendqisi2 pattern should not emit shifts for v850e? 1929 1930(define_insn "*extendqisi_insn" 1931 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 1932 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,Q,m")))] 1933 "(TARGET_V850E_UP)" 1934 "@ 1935 sxb %0 1936 sld.b %1,%0 1937 ld.b %1,%0" 1938 [(set_attr "length" "2,2,4")]) 1939 1940;; ??? This is missing a sign extend from memory pattern to match the ld.b 1941;; instruction. 1942 1943(define_expand "extendqisi2" 1944 [(parallel [(set (match_dup 2) 1945 (ashift:SI (match_operand:QI 1 "register_operand" "") 1946 (const_int 24))) 1947 (clobber (reg:CC CC_REGNUM))]) 1948 (parallel [(set (match_operand:SI 0 "register_operand" "") 1949 (ashiftrt:SI (match_dup 2) 1950 (const_int 24))) 1951 (clobber (reg:CC CC_REGNUM))])] 1952 "" 1953 { 1954 operands[1] = gen_lowpart (SImode, operands[1]); 1955 operands[2] = gen_reg_rtx (SImode); 1956 }) 1957 1958;; ---------------------------------------------------------------------- 1959;; SHIFTS 1960;; ---------------------------------------------------------------------- 1961 1962(define_insn_and_split "ashlsi3" 1963 [(set (match_operand:SI 0 "register_operand" "=r,r") 1964 (ashift:SI 1965 (match_operand:SI 1 "register_operand" "0,0") 1966 (match_operand:SI 2 "nonmemory_operand" "r,N")))] 1967 "" 1968 "#" 1969 "reload_completed" 1970 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2))) 1971 (clobber (reg:CC CC_REGNUM))])]) 1972 1973(define_insn "ashlsi3_clobber_flags" 1974 [(set (match_operand:SI 0 "register_operand" "=r,r") 1975 (ashift:SI 1976 (match_operand:SI 1 "register_operand" "0,0") 1977 (match_operand:SI 2 "nonmemory_operand" "r,N"))) 1978 (clobber (reg:CC CC_REGNUM))] 1979 "" 1980 "@ 1981 shl %2,%0 1982 shl %2,%0" 1983 [(set_attr "length" "4,2")]) 1984 1985(define_insn "ashlsi3_set_flags" 1986 [(set (reg:CCNZ CC_REGNUM) 1987 (compare:CCNZ (ashift:SI (match_operand:SI 1 "register_operand" "0,0") 1988 (match_operand:SI 2 "nonmemory_operand" "r,N")) 1989 (const_int 0))) 1990 (set (match_operand:SI 0 "register_operand" "=r,r") 1991 (ashift:SI (match_dup 1) (match_dup 2)))] 1992 "reload_completed" 1993 "@ 1994 shl %2,%0 1995 shl %2,%0" 1996 [(set_attr "length" "4,2")]) 1997 1998(define_insn "ashlsi3_v850e2_clobber_flags" 1999 [(set (match_operand:SI 0 "register_operand" "=r") 2000 (ashift:SI 2001 (match_operand:SI 1 "register_operand" "r") 2002 (match_operand:SI 2 "nonmemory_operand" "r"))) 2003 (clobber (reg:CC CC_REGNUM))] 2004 "TARGET_V850E2_UP" 2005 "shl %2,%1,%0" 2006 [(set_attr "length" "4")]) 2007 2008(define_insn "ashlsi3_v850e2_set_flags" 2009 [(set (reg:CCNZ CC_REGNUM) 2010 (compare:CCNZ (ashift:SI (match_operand:SI 1 "register_operand" "r") 2011 (match_operand:SI 2 "nonmemory_operand" "r")) 2012 (const_int 0))) 2013 (set (match_operand:SI 0 "register_operand" "=r") 2014 (ashift:SI (match_dup 1) (match_dup 2)))] 2015 "reload_completed && TARGET_V850E2_UP" 2016 "shl %2,%1,%0" 2017 [(set_attr "length" "4")]) 2018 2019(define_insn_and_split "lshrsi3" 2020 [(set (match_operand:SI 0 "register_operand" "=r,r") 2021 (lshiftrt:SI 2022 (match_operand:SI 1 "register_operand" "0,0") 2023 (match_operand:SI 2 "nonmemory_operand" "r,N")))] 2024 "" 2025 "#" 2026 "reload_completed" 2027 [(parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (match_dup 2))) 2028 (clobber (reg:CC CC_REGNUM))])]) 2029 2030(define_insn "lshrsi3_clobber_flags" 2031 [(set (match_operand:SI 0 "register_operand" "=r,r") 2032 (lshiftrt:SI 2033 (match_operand:SI 1 "register_operand" "0,0") 2034 (match_operand:SI 2 "nonmemory_operand" "r,N"))) 2035 (clobber (reg:CC CC_REGNUM))] 2036 "" 2037 "@ 2038 shr %2,%0 2039 shr %2,%0" 2040 [(set_attr "length" "4,2")]) 2041 2042(define_insn "lshrsi3_set_flags" 2043 [(set (reg:CC CC_REGNUM) 2044 (compare:CC (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0") 2045 (match_operand:SI 2 "nonmemory_operand" "r,N")) 2046 (const_int 0))) 2047 (set (match_operand:SI 0 "register_operand" "=r,r") 2048 (lshiftrt:SI (match_dup 1) (match_dup 2)))] 2049 "reload_completed" 2050 "@ 2051 shr %2,%0 2052 shr %2,%0" 2053 [(set_attr "length" "4,2")]) 2054 2055(define_insn "lshrsi3_v850e2_clobber_flags" 2056 [(set (match_operand:SI 0 "register_operand" "=r") 2057 (lshiftrt:SI 2058 (match_operand:SI 1 "register_operand" "r") 2059 (match_operand:SI 2 "nonmemory_operand" "r"))) 2060 (clobber (reg:CC CC_REGNUM))] 2061 "TARGET_V850E2_UP" 2062 "shr %2,%1,%0" 2063 [(set_attr "length" "4")]) 2064 2065(define_insn "lshrsi3_v850e2_set_flags" 2066 [(set (reg:CC CC_REGNUM) 2067 (compare:CC (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") 2068 (match_operand:SI 2 "nonmemory_operand" "r")) 2069 (const_int 0))) 2070 (set (match_operand:SI 0 "register_operand" "=r") 2071 (lshiftrt:SI (match_dup 1) (match_dup 2)))] 2072 "reload_completed && TARGET_V850E2_UP" 2073 "shr %2,%1,%0" 2074 [(set_attr "length" "4")]) 2075 2076(define_insn_and_split "ashrsi3" 2077 [(set (match_operand:SI 0 "register_operand" "=r,r") 2078 (ashiftrt:SI 2079 (match_operand:SI 1 "register_operand" "0,0") 2080 (match_operand:SI 2 "nonmemory_operand" "r,N")))] 2081 "" 2082 "#" 2083 "reload_completed" 2084 [(parallel [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (match_dup 2))) 2085 (clobber (reg:CC CC_REGNUM))])]) 2086 2087(define_insn "ashrsi3_clobber_flags" 2088 [(set (match_operand:SI 0 "register_operand" "=r,r") 2089 (ashiftrt:SI 2090 (match_operand:SI 1 "register_operand" "0,0") 2091 (match_operand:SI 2 "nonmemory_operand" "r,N"))) 2092 (clobber (reg:CC CC_REGNUM))] 2093 "" 2094 "@ 2095 sar %2,%0 2096 sar %2,%0" 2097 [(set_attr "length" "4,2")]) 2098 2099(define_insn "ashrsi3_set_flags" 2100 [(set (reg:CC CC_REGNUM) 2101 (compare:CC (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0") 2102 (match_operand:SI 2 "nonmemory_operand" "r,N")) 2103 (const_int 0))) 2104 (set (match_operand:SI 0 "register_operand" "=r,r") 2105 (ashiftrt:SI (match_dup 1) (match_dup 2)))] 2106 "reload_completed" 2107 "@ 2108 sar %2,%0 2109 sar %2,%0" 2110 [(set_attr "length" "4,2")]) 2111 2112(define_insn "ashrsi3_v850e2_clobber_flags" 2113 [(set (match_operand:SI 0 "register_operand" "=r") 2114 (ashiftrt:SI 2115 (match_operand:SI 1 "register_operand" "r") 2116 (match_operand:SI 2 "nonmemory_operand" "r"))) 2117 (clobber (reg:CC CC_REGNUM))] 2118 "TARGET_V850E2_UP" 2119 "sar %2,%1,%0" 2120 [(set_attr "length" "4")]) 2121 2122(define_insn "ashrsi3_v850e2_set_flags" 2123 [(set (reg:CC CC_REGNUM) 2124 (compare:CC (ashiftrt:SI (match_operand:SI 1 "register_operand" "r") 2125 (match_operand:SI 2 "nonmemory_operand" "r")) 2126 (const_int 0))) 2127 (set (match_operand:SI 0 "register_operand" "=r") 2128 (ashiftrt:SI (match_dup 1) (match_dup 2)))] 2129 "reload_completed && TARGET_V850E2_UP" 2130 "sar %2,%1,%0" 2131 [(set_attr "length" "4")]) 2132 2133;; ---------------------------------------------------------------------- 2134;; FIND FIRST BIT INSTRUCTION 2135;; ---------------------------------------------------------------------- 2136 2137(define_insn "ffssi2" 2138 [(set (match_operand:SI 0 "register_operand" "=r") 2139 (ffs:SI (match_operand:SI 1 "register_operand" "r"))) 2140 (clobber (reg:CC CC_REGNUM))] 2141 "TARGET_V850E2_UP" 2142 "sch1r %1,%0" 2143 [(set_attr "length" "4")]) 2144 2145;; ---------------------------------------------------------------------- 2146;; PROLOGUE/EPILOGUE 2147;; ---------------------------------------------------------------------- 2148(define_expand "prologue" 2149 [(const_int 0)] 2150 "" 2151 { 2152 expand_prologue (); 2153 DONE; 2154 }) 2155 2156(define_expand "epilogue" 2157 [(return)] 2158 "" 2159 { 2160 expand_epilogue (); 2161 DONE; 2162 }) 2163 2164(define_insn "return_simple" 2165 [(return)] 2166 "reload_completed" 2167 "jmp [r31]" 2168 [(set_attr "length" "2")]) 2169 2170(define_insn "return_internal" 2171 [(return) 2172 (use (reg:SI 31))] 2173 "" 2174 "jmp [r31]" 2175 [(set_attr "length" "2")]) 2176 2177;; ---------------------------------------------------------------------- 2178;; v850e2V3 floating-point hardware support 2179;; ---------------------------------------------------------------------- 2180 2181 2182(define_insn "addsf3" 2183 [(set (match_operand:SF 0 "register_operand" "=r") 2184 (plus:SF (match_operand:SF 1 "register_operand" "r") 2185 (match_operand:SF 2 "register_operand" "r")))] 2186 "TARGET_USE_FPU" 2187 "addf.s %1,%2,%0" 2188 [(set_attr "length" "4") 2189 (set_attr "type" "fpu")]) 2190 2191(define_insn "adddf3" 2192 [(set (match_operand:DF 0 "even_reg_operand" "=r") 2193 (plus:DF (match_operand:DF 1 "even_reg_operand" "r") 2194 (match_operand:DF 2 "even_reg_operand" "r")))] 2195 "TARGET_USE_FPU" 2196 "addf.d %1,%2,%0" 2197 [(set_attr "length" "4") 2198 (set_attr "type" "fpu")]) 2199 2200(define_insn "subsf3" 2201 [(set (match_operand:SF 0 "register_operand" "=r") 2202 (minus:SF (match_operand:SF 1 "register_operand" "r") 2203 (match_operand:SF 2 "register_operand" "r")))] 2204 "TARGET_USE_FPU" 2205 "subf.s %2,%1,%0" 2206 [(set_attr "length" "4") 2207 (set_attr "type" "fpu")]) 2208 2209(define_insn "subdf3" 2210 [(set (match_operand:DF 0 "even_reg_operand" "=r") 2211 (minus:DF (match_operand:DF 1 "even_reg_operand" "r") 2212 (match_operand:DF 2 "even_reg_operand" "r")))] 2213 "TARGET_USE_FPU" 2214 "subf.d %2,%1,%0" 2215 [(set_attr "length" "4") 2216 (set_attr "type" "fpu")]) 2217 2218(define_insn "mulsf3" 2219 [(set (match_operand:SF 0 "register_operand" "=r") 2220 (mult:SF (match_operand:SF 1 "register_operand" "r") 2221 (match_operand:SF 2 "register_operand" "r")))] 2222 "TARGET_USE_FPU" 2223 "mulf.s %1,%2,%0" 2224 [(set_attr "length" "4") 2225 (set_attr "type" "fpu")]) 2226 2227(define_insn "muldf3" 2228 [(set (match_operand:DF 0 "even_reg_operand" "=r") 2229 (mult:DF (match_operand:DF 1 "even_reg_operand" "r") 2230 (match_operand:DF 2 "even_reg_operand" "r")))] 2231 "TARGET_USE_FPU" 2232 "mulf.d %1,%2,%0" 2233 [(set_attr "length" "4") 2234 (set_attr "type" "fpu")]) 2235 2236(define_insn "divsf3" 2237 [(set (match_operand:SF 0 "register_operand" "=r") 2238 (div:SF (match_operand:SF 1 "register_operand" "r") 2239 (match_operand:SF 2 "register_operand" "r")))] 2240 "TARGET_USE_FPU" 2241 "divf.s %2,%1,%0" 2242 [(set_attr "length" "4") 2243 (set_attr "type" "fpu")]) 2244 2245(define_insn "divdf3" 2246 [(set (match_operand:DF 0 "register_operand" "=r") 2247 (div:DF (match_operand:DF 1 "even_reg_operand" "r") 2248 (match_operand:DF 2 "even_reg_operand" "r")))] 2249 "TARGET_USE_FPU" 2250 "divf.d %2,%1,%0" 2251 [(set_attr "length" "4") 2252 (set_attr "type" "fpu")]) 2253 2254(define_insn "minsf3" 2255 [(set (match_operand:SF 0 "register_operand" "=r") 2256 (smin:SF (match_operand:SF 1 "reg_or_0_operand" "r") 2257 (match_operand:SF 2 "reg_or_0_operand" "r")))] 2258 "TARGET_USE_FPU" 2259 "minf.s %z1,%z2,%0" 2260 [(set_attr "length" "4") 2261 (set_attr "type" "fpu")]) 2262 2263(define_insn "mindf3" 2264 [(set (match_operand:DF 0 "even_reg_operand" "=r") 2265 (smin:DF (match_operand:DF 1 "even_reg_operand" "r") 2266 (match_operand:DF 2 "even_reg_operand" "r")))] 2267 "TARGET_USE_FPU" 2268 "minf.d %1,%2,%0" 2269 [(set_attr "length" "4") 2270 (set_attr "type" "fpu")]) 2271 2272(define_insn "maxsf3" 2273 [(set (match_operand:SF 0 "register_operand" "=r") 2274 (smax:SF (match_operand:SF 1 "reg_or_0_operand" "r") 2275 (match_operand:SF 2 "reg_or_0_operand" "r")))] 2276 "TARGET_USE_FPU" 2277 "maxf.s %z1,%z2,%0" 2278 [(set_attr "length" "4") 2279 (set_attr "type" "fpu")]) 2280 2281(define_insn "maxdf3" 2282 [(set (match_operand:DF 0 "even_reg_operand" "=r") 2283 (smax:DF (match_operand:DF 1 "even_reg_operand" "r") 2284 (match_operand:DF 2 "even_reg_operand" "r")))] 2285 "TARGET_USE_FPU" 2286 "maxf.d %1,%2,%0" 2287 [(set_attr "length" "4") 2288 (set_attr "type" "fpu")]) 2289 2290(define_insn "abssf2" 2291 [(set (match_operand:SF 0 "register_operand" "=r") 2292 (abs:SF (match_operand:SF 1 "register_operand" "r")))] 2293 "TARGET_USE_FPU" 2294 "absf.s %1,%0" 2295 [(set_attr "length" "4") 2296 (set_attr "type" "fpu")]) 2297 2298(define_insn "absdf2" 2299 [(set (match_operand:DF 0 "even_reg_operand" "=r") 2300 (abs:DF (match_operand:DF 1 "even_reg_operand" "r")))] 2301 "TARGET_USE_FPU" 2302 "absf.d %1,%0" 2303 [(set_attr "length" "4") 2304 (set_attr "type" "fpu")]) 2305 2306(define_insn "negsf2" 2307 [(set (match_operand:SF 0 "register_operand" "=r") 2308 (neg:SF (match_operand:SF 1 "register_operand" "r")))] 2309 "TARGET_USE_FPU" 2310 "negf.s %1,%0" 2311 [(set_attr "length" "4") 2312 (set_attr "type" "fpu")]) 2313 2314(define_insn "negdf2" 2315 [(set (match_operand:DF 0 "even_reg_operand" "=r") 2316 (neg:DF (match_operand:DF 1 "even_reg_operand" "r")))] 2317 "TARGET_USE_FPU" 2318 "negf.d %1,%0" 2319 [(set_attr "length" "4") 2320 (set_attr "type" "fpu")]) 2321 2322;; square-root 2323(define_insn "sqrtsf2" 2324 [(set (match_operand:SF 0 "register_operand" "=r") 2325 (sqrt:SF (match_operand:SF 1 "register_operand" "r")))] 2326 "TARGET_USE_FPU" 2327 "sqrtf.s %1,%0" 2328 [(set_attr "length" "4") 2329 (set_attr "type" "fpu")]) 2330 2331(define_insn "sqrtdf2" 2332 [(set (match_operand:DF 0 "even_reg_operand" "=r") 2333 (sqrt:DF (match_operand:DF 1 "even_reg_operand" "r")))] 2334 "TARGET_USE_FPU" 2335 "sqrtf.d %1,%0" 2336 [(set_attr "length" "4") 2337 (set_attr "type" "fpu")]) 2338 2339;; float -> int 2340(define_insn "fix_truncsfsi2" 2341 [(set (match_operand:SI 0 "register_operand" "=r") 2342 (fix:SI (match_operand:SF 1 "register_operand" "r")))] 2343 "TARGET_USE_FPU" 2344 "trncf.sw %1,%0" 2345 [(set_attr "length" "4") 2346 (set_attr "type" "fpu")]) 2347 2348(define_insn "fixuns_truncsfsi2" 2349 [(set (match_operand:SI 0 "register_operand" "=r") 2350 (unsigned_fix:SI (match_operand:SF 1 "register_operand" "r")))] 2351 "TARGET_USE_FPU" 2352 "trncf.suw %1, %0" 2353 [(set_attr "length" "4") 2354 (set_attr "type" "fpu")]) 2355 2356(define_insn "fix_truncdfsi2" 2357 [(set (match_operand:SI 0 "register_operand" "=r") 2358 (fix:SI (match_operand:DF 1 "even_reg_operand" "r")))] 2359 "TARGET_USE_FPU" 2360 "trncf.dw %1,%0" 2361 [(set_attr "length" "4") 2362 (set_attr "type" "fpu")]) 2363 2364(define_insn "fixuns_truncdfsi2" 2365 [(set (match_operand:SI 0 "register_operand" "=r") 2366 (unsigned_fix:SI (match_operand:DF 1 "even_reg_operand" "r")))] 2367 "TARGET_USE_FPU" 2368 "trncf.duw %1, %0" 2369 [(set_attr "length" "4") 2370 (set_attr "type" "fpu")]) 2371 2372(define_insn "fix_truncsfdi2" 2373 [(set (match_operand:DI 0 "register_operand" "=r") 2374 (fix:DI (match_operand:SF 1 "register_operand" "r")))] 2375 "TARGET_USE_FPU" 2376 "trncf.sl %1, %0" 2377 [(set_attr "length" "4") 2378 (set_attr "type" "fpu")]) 2379 2380(define_insn "fixuns_truncsfdi2" 2381 [(set (match_operand:DI 0 "register_operand" "=r") 2382 (unsigned_fix:DI (match_operand:SF 1 "register_operand" "r")))] 2383 "TARGET_USE_FPU" 2384 "trncf.sul %1, %0" 2385 [(set_attr "length" "4") 2386 (set_attr "type" "fpu")]) 2387 2388(define_insn "fix_truncdfdi2" 2389 [(set (match_operand:DI 0 "register_operand" "=r") 2390 (fix:DI (match_operand:DF 1 "even_reg_operand" "r")))] 2391 "TARGET_USE_FPU" 2392 "trncf.dl %1, %0" 2393 [(set_attr "length" "4") 2394 (set_attr "type" "fpu")]) 2395 2396(define_insn "fixuns_truncdfdi2" 2397 [(set (match_operand:DI 0 "register_operand" "=r") 2398 (unsigned_fix:DI (match_operand:DF 1 "even_reg_operand" "r")))] 2399 "TARGET_USE_FPU" 2400 "trncf.dul %1, %0" 2401 [(set_attr "length" "4") 2402 (set_attr "type" "fpu")]) 2403 2404;; int -> float 2405(define_insn "floatsisf2" 2406 [(set (match_operand:SF 0 "register_operand" "=r") 2407 (float:SF (match_operand:SI 1 "reg_or_0_operand" "rI")))] 2408 "TARGET_USE_FPU" 2409 "cvtf.ws %z1, %0" 2410 [(set_attr "length" "4") 2411 (set_attr "type" "fpu")]) 2412 2413(define_insn "unsfloatsisf2" 2414 [(set (match_operand:SF 0 "register_operand" "=r") 2415 (unsigned_float:SF (match_operand:SI 1 "reg_or_0_operand" "rI")))] 2416 "TARGET_USE_FPU" 2417 "cvtf.uws %z1, %0" 2418 [(set_attr "length" "4") 2419 (set_attr "type" "fpu")]) 2420 2421(define_insn "floatsidf2" 2422 [(set (match_operand:DF 0 "even_reg_operand" "=r") 2423 (float:DF (match_operand:SI 1 "reg_or_0_operand" "rI")))] 2424 "TARGET_USE_FPU" 2425 "cvtf.wd %z1,%0" 2426 [(set_attr "length" "4") 2427 (set_attr "type" "fpu")]) 2428 2429(define_insn "unsfloatsidf2" 2430 [(set (match_operand:DF 0 "even_reg_operand" "=r") 2431 (unsigned_float:DF (match_operand:SI 1 "reg_or_0_operand" "rI")))] 2432 "TARGET_USE_FPU" 2433 "cvtf.uwd %z1, %0" 2434 [(set_attr "length" "4") 2435 (set_attr "type" "fpu")]) 2436 2437(define_insn "floatdisf2" 2438 [(set (match_operand:SF 0 "even_reg_operand" "=r") 2439 (float:SF (match_operand:DI 1 "reg_or_0_operand" "rI")))] 2440 "TARGET_USE_FPU" 2441 "cvtf.ls %z1, %0" 2442 [(set_attr "length" "4") 2443 (set_attr "type" "fpu")]) 2444 2445(define_insn "unsfloatdisf2" 2446 [(set (match_operand:SF 0 "even_reg_operand" "=r") 2447 (unsigned_float:SF (match_operand:DI 1 "reg_or_0_operand" "rI")))] 2448 "TARGET_USE_FPU" 2449 "cvtf.uls %z1, %0" 2450 [(set_attr "length" "4") 2451 (set_attr "type" "fpu")]) 2452 2453(define_insn "floatdidf2" 2454 [(set (match_operand:DF 0 "even_reg_operand" "=r") 2455 (float:DF (match_operand:DI 1 "reg_or_0_operand" "rI")))] 2456 "TARGET_USE_FPU" 2457 "cvtf.ld %z1, %0" 2458 [(set_attr "length" "4") 2459 (set_attr "type" "fpu")]) 2460 2461(define_insn "unsfloatdidf2" 2462 [(set (match_operand:DF 0 "even_reg_operand" "=r") 2463 (unsigned_float:DF (match_operand:DI 1 "reg_or_0_operand" "rI")))] 2464 "TARGET_USE_FPU" 2465 "cvtf.uld %z1, %0" 2466 [(set_attr "length" "4") 2467 (set_attr "type" "fpu")]) 2468 2469;; single-float -> double-float 2470(define_insn "extendsfdf2" 2471 [(set (match_operand:DF 0 "even_reg_operand" "=r") 2472 (float_extend:DF 2473 (match_operand:SF 1 "reg_or_0_operand" "rI")))] 2474 "TARGET_USE_FPU" 2475 "cvtf.sd %z1,%0" 2476 [(set_attr "length" "4") 2477 (set_attr "type" "fpu")]) 2478 2479;; double-float -> single-float 2480(define_insn "truncdfsf2" 2481 [(set (match_operand:SF 0 "register_operand" "=r") 2482 (float_truncate:SF 2483 (match_operand:DF 1 "even_reg_operand" "r")))] 2484 "TARGET_USE_FPU" 2485 "cvtf.ds %1,%0" 2486 [(set_attr "length" "4") 2487 (set_attr "type" "fpu")]) 2488 2489;; 2490;; ---------------- special insns 2491;; 2492 2493;; reciprocal 2494 2495;; Generic code demands that the recip and rsqrt named patterns 2496;; have precisely one operand. So that's what we expose in the 2497;; expander via the strange UNSPEC. However, those expanders 2498;; generate normal looking recip and rsqrt patterns. 2499 2500(define_expand "recipsf2" 2501 [(set (match_operand:SF 0 "register_operand" "") 2502 (unspec:SF [(match_operand:SF 1 "register_operand" "")] 2503 UNSPEC_RCP))] 2504 "TARGET_USE_FPU" 2505 { 2506 emit_insn (gen_recipsf2_insn (operands[0], CONST1_RTX (SFmode), operands[1])); 2507 DONE; 2508 }) 2509 2510(define_insn "recipsf2_insn" 2511 [(set (match_operand:SF 0 "register_operand" "=r") 2512 (div:SF (match_operand:SF 1 "const_float_1_operand" "") 2513 (match_operand:SF 2 "register_operand" "r")))] 2514 "TARGET_USE_FPU" 2515 "recipf.s %2,%0" 2516 [(set_attr "length" "4") 2517 (set_attr "type" "fpu")]) 2518 2519(define_expand "recipdf2" 2520 [(set (match_operand:DF 0 "even_reg_operand" "") 2521 (unspec:DF [(match_operand:SF 1 "even_reg_operand" "")] 2522 UNSPEC_RCP))] 2523 "TARGET_USE_FPU" 2524 { 2525 emit_insn (gen_recipdf2_insn (operands[0], CONST1_RTX (DFmode), operands[1])); 2526 DONE; 2527 }) 2528 2529(define_insn "recipdf2_insn" 2530 [(set (match_operand:DF 0 "even_reg_operand" "=r") 2531 (div:DF (match_operand:DF 1 "const_float_1_operand" "") 2532 (match_operand:DF 2 "even_reg_operand" "r")))] 2533 "TARGET_USE_FPU" 2534 "recipf.d %2,%0" 2535 [(set_attr "length" "4") 2536 (set_attr "type" "fpu")]) 2537 2538;;; reciprocal of square-root 2539(define_expand "rsqrtsf2" 2540 [(set (match_operand:SF 0 "register_operand" "=") 2541 (unspec:SF [(match_operand:SF 1 "register_operand" "")] 2542 UNSPEC_RSQRT))] 2543 "TARGET_USE_FPU" 2544 { 2545 emit_insn (gen_rsqrtsf2_insn (operands[0], CONST1_RTX (SFmode), operands[1])); 2546 DONE; 2547 }) 2548 2549(define_insn "rsqrtsf2_insn" 2550 [(set (match_operand:SF 0 "register_operand" "=r") 2551 (div:SF (match_operand:SF 1 "const_float_1_operand" "") 2552 (sqrt:SF (match_operand:SF 2 "register_operand" "r"))))] 2553 "TARGET_USE_FPU" 2554 "rsqrtf.s %2,%0" 2555 [(set_attr "length" "4") 2556 (set_attr "type" "fpu")]) 2557 2558(define_expand "rsqrtdf2" 2559 [(set (match_operand:DF 0 "even_reg_operand" "=r") 2560 (unspec:DF [(match_operand:DF 1 "even_reg_operand" "r")] 2561 UNSPEC_RSQRT))] 2562 "TARGET_USE_FPU" 2563 { 2564 emit_insn (gen_rsqrtdf2_insn (operands[0], CONST1_RTX (DFmode), operands[1])); 2565 DONE; 2566 }) 2567 2568(define_insn "rsqrtdf2_insn" 2569 [(set (match_operand:DF 0 "even_reg_operand" "=r") 2570 (div:DF (match_operand:DF 1 "const_float_1_operand" "") 2571 (sqrt:DF (match_operand:DF 2 "even_reg_operand" "r"))))] 2572 "TARGET_USE_FPU" 2573 "rsqrtf.d %2,%0" 2574 [(set_attr "length" "4") 2575 (set_attr "type" "fpu")]) 2576 2577;; Note: The FPU-2.0 (ie pre e3v5) versions of these routines do not actually 2578;; need operand 4 to be the same as operand 0. But the FPU-2.0 versions are 2579;; also deprecated so the loss of flexibility is unimportant. 2580 2581;;; multiply-add 2582(define_insn "fmasf4" 2583 [(set (match_operand:SF 0 "register_operand" "=r") 2584 (fma:SF (match_operand:SF 1 "register_operand" "r") 2585 (match_operand:SF 2 "register_operand" "r") 2586 (match_operand:SF 3 "register_operand" "0")))] 2587 "TARGET_USE_FPU" 2588 { return TARGET_V850E3V5_UP ? "fmaf.s %1, %2, %0" : "maddf.s %2, %1, %3, %0"; } 2589 [(set_attr "length" "4") 2590 (set_attr "type" "fpu")]) 2591 2592;;; multiply-subtract 2593(define_insn "fmssf4" 2594 [(set (match_operand:SF 0 "register_operand" "=r") 2595 (fma:SF (match_operand:SF 1 "register_operand" "r") 2596 (match_operand:SF 2 "register_operand" "r") 2597 (neg:SF (match_operand:SF 3 "register_operand" "0"))))] 2598 "TARGET_USE_FPU" 2599 { return TARGET_V850E3V5_UP ? "fmsf.s %1, %2, %0" : "msubf.s %2, %1, %3, %0"; } 2600 [(set_attr "length" "4") 2601 (set_attr "type" "fpu")]) 2602 2603;;; negative-multiply-add 2604(define_insn "fnmasf4" 2605 [(set (match_operand:SF 0 "register_operand" "=r") 2606 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "r") 2607 (match_operand:SF 2 "register_operand" "r") 2608 (match_operand:SF 3 "register_operand" "0"))))] 2609 "TARGET_USE_FPU" 2610 { return TARGET_V850E3V5_UP ? "fnmaf.s %1, %2, %0" : "nmaddf.s %2, %1, %3, %0"; } 2611 [(set_attr "length" "4") 2612 (set_attr "type" "fpu")]) 2613 2614;; negative-multiply-subtract 2615(define_insn "fnmssf4" 2616 [(set (match_operand:SF 0 "register_operand" "=r") 2617 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "r") 2618 (match_operand:SF 2 "register_operand" "r") 2619 (neg:SF (match_operand:SF 3 "register_operand" "0")))))] 2620 "TARGET_USE_FPU" 2621 { return TARGET_V850E3V5_UP ? "fnmsf.s %1, %2, %0" : "nmsubf.s %2, %1, %3, %0"; } 2622 [(set_attr "length" "4") 2623 (set_attr "type" "fpu")]) 2624; 2625; ---------------- comparison/conditionals 2626; 2627; SF 2628 2629(define_insn "cmpsf_le_insn" 2630 [(set (reg:CC_FPU_LE FCC_REGNUM) 2631 (compare:CC_FPU_LE (match_operand:SF 0 "register_operand" "r") 2632 (match_operand:SF 1 "register_operand" "r")))] 2633 "reload_completed && TARGET_USE_FPU" 2634 "cmpf.s le, %z0, %z1" 2635 [(set_attr "length" "4") 2636 (set_attr "type" "fpu")]) 2637 2638(define_insn "cmpsf_lt_insn" 2639 [(set (reg:CC_FPU_LT FCC_REGNUM) 2640 (compare:CC_FPU_LT (match_operand:SF 0 "register_operand" "r") 2641 (match_operand:SF 1 "register_operand" "r")))] 2642 "reload_completed && TARGET_USE_FPU" 2643 "cmpf.s lt, %z0, %z1" 2644 [(set_attr "length" "4") 2645 (set_attr "type" "fpu")]) 2646 2647(define_insn "cmpsf_ge_insn" 2648 [(set (reg:CC_FPU_GE FCC_REGNUM) 2649 (compare:CC_FPU_GE (match_operand:SF 0 "register_operand" "r") 2650 (match_operand:SF 1 "register_operand" "r")))] 2651 "reload_completed && TARGET_USE_FPU" 2652 "cmpf.s le, %z1, %z0" 2653 [(set_attr "length" "4") 2654 (set_attr "type" "fpu")]) 2655 2656(define_insn "cmpsf_gt_insn" 2657 [(set (reg:CC_FPU_GT FCC_REGNUM) 2658 (compare:CC_FPU_GT (match_operand:SF 0 "register_operand" "r") 2659 (match_operand:SF 1 "register_operand" "r")))] 2660 "reload_completed && TARGET_USE_FPU" 2661 "cmpf.s lt, %z1, %z0" 2662 [(set_attr "length" "4") 2663 (set_attr "type" "fpu")]) 2664 2665(define_insn "cmpsf_eq_insn" 2666 [(set (reg:CC_FPU_EQ FCC_REGNUM) 2667 (compare:CC_FPU_EQ (match_operand:SF 0 "register_operand" "r") 2668 (match_operand:SF 1 "register_operand" "r")))] 2669 "reload_completed && TARGET_USE_FPU" 2670 "cmpf.s eq, %z0, %z1" 2671 [(set_attr "length" "4") 2672 (set_attr "type" "fpu")]) 2673 2674; DF 2675 2676(define_insn "cmpdf_le_insn" 2677 [(set (reg:CC_FPU_LE FCC_REGNUM) 2678 (compare:CC_FPU_LE (match_operand:DF 0 "even_reg_operand" "r") 2679 (match_operand:DF 1 "even_reg_operand" "r")))] 2680 "reload_completed && TARGET_USE_FPU" 2681 "cmpf.d le, %z0, %z1" 2682 [(set_attr "length" "4") 2683 (set_attr "type" "fpu")]) 2684 2685(define_insn "cmpdf_lt_insn" 2686 [(set (reg:CC_FPU_LT FCC_REGNUM) 2687 (compare:CC_FPU_LT (match_operand:DF 0 "even_reg_operand" "r") 2688 (match_operand:DF 1 "even_reg_operand" "r")))] 2689 "reload_completed && TARGET_USE_FPU" 2690 "cmpf.d lt, %z0, %z1" 2691 [(set_attr "length" "4") 2692 (set_attr "type" "fpu")]) 2693 2694(define_insn "cmpdf_ge_insn" 2695 [(set (reg:CC_FPU_GE FCC_REGNUM) 2696 (compare:CC_FPU_GE (match_operand:DF 0 "even_reg_operand" "r") 2697 (match_operand:DF 1 "even_reg_operand" "r")))] 2698 "reload_completed && TARGET_USE_FPU" 2699 "cmpf.d le, %z1, %z0" 2700 [(set_attr "length" "4") 2701 (set_attr "type" "fpu")]) 2702 2703(define_insn "cmpdf_gt_insn" 2704 [(set (reg:CC_FPU_GT FCC_REGNUM) 2705 (compare:CC_FPU_GT (match_operand:DF 0 "even_reg_operand" "r") 2706 (match_operand:DF 1 "even_reg_operand" "r")))] 2707 "reload_completed && TARGET_USE_FPU" 2708 "cmpf.d lt, %z1, %z0" 2709 [(set_attr "length" "4") 2710 (set_attr "type" "fpu")]) 2711 2712(define_insn "cmpdf_eq_insn" 2713 [(set (reg:CC_FPU_EQ FCC_REGNUM) 2714 (compare:CC_FPU_EQ (match_operand:DF 0 "even_reg_operand" "r") 2715 (match_operand:DF 1 "even_reg_operand" "r")))] 2716 "reload_completed && TARGET_USE_FPU" 2717 "cmpf.d eq, %z0, %z1" 2718 [(set_attr "length" "4") 2719 (set_attr "type" "fpu")]) 2720 2721;; 2722;; Transfer a v850e2v3 fcc to the Z bit of CC0 (this is necessary to do a 2723;; conditional branch based on a floating-point compare) 2724;; 2725 2726(define_insn "trfsr" 2727 [(set (match_operand 0 "" "") (match_operand 1 "" ""))] 2728 "reload_completed 2729 && TARGET_USE_FPU 2730 && GET_MODE(operands[0]) == GET_MODE(operands[1]) 2731 && GET_CODE(operands[0]) == REG && REGNO (operands[0]) == CC_REGNUM 2732 && GET_CODE(operands[1]) == REG && REGNO (operands[1]) == FCC_REGNUM 2733 && (GET_MODE(operands[0]) == CC_FPU_LEmode 2734 || GET_MODE(operands[0]) == CC_FPU_GEmode 2735 || GET_MODE(operands[0]) == CC_FPU_LTmode 2736 || GET_MODE(operands[0]) == CC_FPU_GTmode 2737 || GET_MODE(operands[0]) == CC_FPU_EQmode 2738 || GET_MODE(operands[0]) == CC_FPU_NEmode)" 2739 "trfsr" 2740 [(set_attr "length" "4") 2741 (set_attr "type" "fpu")]) 2742 2743;; 2744;; Floating-point conditional moves for the v850e2v3. 2745;; 2746 2747;; The actual v850e2v3 conditional move instructions 2748;; 2749(define_insn "movsfcc_z_insn" 2750 [(set (match_operand:SF 0 "register_operand" "=r") 2751 (if_then_else:SF 2752 (match_operand 3 "v850_float_z_comparison_operator" "") 2753 (match_operand:SF 1 "reg_or_0_operand" "rIG") 2754 (match_operand:SF 2 "reg_or_0_operand" "rIG")))] 2755 "TARGET_USE_FPU" 2756 "cmovf.s 0,%z1,%z2,%0") 2757 2758(define_insn "movsfcc_nz_insn" 2759 [(set (match_operand:SF 0 "register_operand" "=r") 2760 (if_then_else:SF 2761 (match_operand 3 "v850_float_nz_comparison_operator" "") 2762 (match_operand:SF 1 "reg_or_0_operand" "rIG") 2763 (match_operand:SF 2 "reg_or_0_operand" "rIG")))] 2764 "TARGET_USE_FPU" 2765 "cmovf.s 0,%z2,%z1,%0") 2766 2767(define_insn "movdfcc_z_insn" 2768 [(set (match_operand:DF 0 "even_reg_operand" "=r") 2769 (if_then_else:DF 2770 (match_operand 3 "v850_float_z_comparison_operator" "") 2771 (match_operand:DF 1 "even_reg_operand" "r") 2772 (match_operand:DF 2 "even_reg_operand" "r")))] 2773 "TARGET_USE_FPU" 2774 "cmovf.d 0,%z1,%z2,%0") 2775 2776(define_insn "movdfcc_nz_insn" 2777 [(set (match_operand:DF 0 "even_reg_operand" "=r") 2778 (if_then_else:DF 2779 (match_operand 3 "v850_float_nz_comparison_operator" "") 2780 (match_operand:DF 1 "even_reg_operand" "r") 2781 (match_operand:DF 2 "even_reg_operand" "r")))] 2782 "TARGET_USE_FPU" 2783 "cmovf.d 0,%z2,%z1,%0") 2784 2785(define_insn "movedfcc_z_zero" 2786 [(set (match_operand:DF 0 "register_operand" "=r") 2787 (if_then_else:DF 2788 (match_operand 3 "v850_float_z_comparison_operator" "") 2789 (match_operand:DF 1 "reg_or_0_operand" "rIG") 2790 (match_operand:DF 2 "reg_or_0_operand" "rIG")))] 2791 "TARGET_USE_FPU" 2792 "cmovf.s 0,%z1,%z2,%0 ; cmovf.s 0,%Z1,%Z2,%R0" 2793 [(set_attr "length" "8")]) 2794 2795(define_insn "movedfcc_nz_zero" 2796 [(set (match_operand:DF 0 "register_operand" "=r") 2797 (if_then_else:DF 2798 (match_operand 3 "v850_float_nz_comparison_operator" "") 2799 (match_operand:DF 1 "reg_or_0_operand" "rIG") 2800 (match_operand:DF 2 "reg_or_0_operand" "rIG")))] 2801 "TARGET_USE_FPU" 2802 "cmovf.s 0,%z2,%z1,%0 ; cmovf.s 0,%Z2,%Z1,%R0" 2803 [(set_attr "length" "8")]) 2804 2805 2806;; ---------------------------------------------------------------------- 2807;; HELPER INSTRUCTIONS for saving the prologue and epilogue registers 2808;; ---------------------------------------------------------------------- 2809 2810;; This pattern will match a stack adjust RTX followed by any number of push 2811;; RTXs. These RTXs will then be turned into a suitable call to a worker 2812;; function. 2813 2814;; 2815;; Actually, convert the RTXs into a PREPARE instruction. 2816;; 2817 2818(define_insn "" 2819 [(match_parallel 0 "pattern_is_ok_for_prepare" 2820 [(set (reg:SI 3) 2821 (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i"))) 2822 (set (mem:SI (plus:SI (reg:SI 3) 2823 (match_operand:SI 2 "immediate_operand" "i"))) 2824 (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])] 2825 "TARGET_PROLOG_FUNCTION && (TARGET_V850E_UP)" 2826{ 2827 return construct_prepare_instruction (operands[0]); 2828} 2829 [(set_attr "length" "4")]) 2830 2831(define_insn "" 2832 [(match_parallel 0 "pattern_is_ok_for_prologue" 2833 [(set (reg:SI 3) 2834 (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i"))) 2835 (set (mem:SI (plus:SI (reg:SI 3) 2836 (match_operand:SI 2 "immediate_operand" "i"))) 2837 (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])] 2838 "TARGET_PROLOG_FUNCTION" 2839{ 2840 return construct_save_jarl (operands[0]); 2841} 2842 [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes") 2843 (const_string "16") 2844 (const_string "4")))]) 2845 2846;; 2847;; Actually, turn the RTXs into a DISPOSE instruction. 2848;; 2849(define_insn "" 2850 [(match_parallel 0 "pattern_is_ok_for_dispose" 2851 [(return) 2852 (set (reg:SI 3) 2853 (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i"))) 2854 (set (match_operand:SI 2 "register_is_ok_for_epilogue" "=r") 2855 (mem:SI (plus:SI (reg:SI 3) 2856 (match_operand:SI 3 "immediate_operand" "i"))))])] 2857 "TARGET_PROLOG_FUNCTION && (TARGET_V850E_UP)" 2858{ 2859 return construct_dispose_instruction (operands[0]); 2860} 2861 [(set_attr "length" "4")]) 2862 2863;; This pattern will match a return RTX followed by any number of pop RTXs 2864;; and possible a stack adjustment as well. These RTXs will be turned into 2865;; a suitable call to a worker function. 2866 2867(define_insn "" 2868[(match_parallel 0 "pattern_is_ok_for_epilogue" 2869 [(return) 2870 (set (reg:SI 3) 2871 (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i"))) 2872 (set (match_operand:SI 2 "register_is_ok_for_epilogue" "=r") 2873 (mem:SI (plus:SI (reg:SI 3) 2874 (match_operand:SI 3 "immediate_operand" "i"))))])] 2875 "TARGET_PROLOG_FUNCTION" 2876{ 2877 return construct_restore_jr (operands[0]); 2878} 2879 [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes") 2880 (const_string "12") 2881 (const_string "4")))]) 2882 2883;; Initialize an interrupt function. Do not depend on TARGET_PROLOG_FUNCTION. 2884(define_insn "callt_save_interrupt" 2885 [(unspec_volatile [(const_int 0)] 2) 2886 (clobber (reg:CC CC_REGNUM))] 2887 "(TARGET_V850E_UP) && !TARGET_DISABLE_CALLT" 2888 ;; The CALLT instruction stores the next address of CALLT to CTPC register 2889 ;; without saving its previous value. So if the interrupt handler 2890 ;; or its caller could possibly execute the CALLT insn, save_interrupt 2891 ;; MUST NOT be called via CALLT. 2892{ 2893 output_asm_insn ("addi -28, sp, sp", operands); 2894 output_asm_insn ("st.w r1, 24[sp]", operands); 2895 output_asm_insn ("st.w r10, 12[sp]", operands); 2896 output_asm_insn ("st.w r11, 16[sp]", operands); 2897 output_asm_insn ("stsr ctpc, r10", operands); 2898 output_asm_insn ("st.w r10, 20[sp]", operands); 2899 output_asm_insn ("stsr ctpsw, r10", operands); 2900 output_asm_insn ("st.w r10, 24[sp]", operands); 2901 output_asm_insn ("callt ctoff(__callt_save_interrupt)", operands); 2902 return ""; 2903} 2904 [(set_attr "length" "26")]) 2905 2906(define_insn "callt_return_interrupt" 2907 [(unspec_volatile [(const_int 0)] 3) 2908 (clobber (reg:CC CC_REGNUM))] 2909 "(TARGET_V850E_UP) && !TARGET_DISABLE_CALLT" 2910 "callt ctoff(__callt_return_interrupt)" 2911 [(set_attr "length" "2")]) 2912 2913(define_insn "save_interrupt" 2914 [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -20))) 2915 (set (mem:SI (plus:SI (reg:SI 3) (const_int -20))) (reg:SI 30)) 2916 (set (mem:SI (plus:SI (reg:SI 3) (const_int -16))) (reg:SI 4)) 2917 (set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 1)) 2918 (set (mem:SI (plus:SI (reg:SI 3) (const_int -8))) (reg:SI 10)) 2919 (set (mem:SI (plus:SI (reg:SI 3) (const_int -4))) (reg:SI 11)) 2920 (clobber (reg:CC CC_REGNUM))] 2921 "" 2922{ 2923 if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS) 2924 return "addi -20,sp,sp \; st.w r11,16[sp] \; st.w r10,12[sp] \; jarl __save_interrupt,r10"; 2925 else 2926 { 2927 output_asm_insn ("addi -20, sp, sp", operands); 2928 output_asm_insn ("st.w r11, 16[sp]", operands); 2929 output_asm_insn ("st.w r10, 12[sp]", operands); 2930 output_asm_insn ("st.w ep, 0[sp]", operands); 2931 output_asm_insn ("st.w gp, 4[sp]", operands); 2932 output_asm_insn ("st.w r1, 8[sp]", operands); 2933 output_asm_insn ("movhi hi(__ep), r0, ep", operands); 2934 output_asm_insn ("movea lo(__ep), ep, ep", operands); 2935 output_asm_insn ("movhi hi(__gp), r0, gp", operands); 2936 output_asm_insn ("movea lo(__gp), gp, gp", operands); 2937 return ""; 2938 } 2939} 2940 [(set (attr "length") 2941 (if_then_else (match_test "TARGET_LONG_CALLS") 2942 (const_int 10) 2943 (const_int 34)))]) 2944 2945;; Restore r1, r4, r10, and return from the interrupt 2946(define_insn "return_interrupt" 2947 [(return) 2948 (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 20))) 2949 (set (reg:SI 11) (mem:SI (plus:SI (reg:SI 3) (const_int 16)))) 2950 (set (reg:SI 10) (mem:SI (plus:SI (reg:SI 3) (const_int 12)))) 2951 (set (reg:SI 1) (mem:SI (plus:SI (reg:SI 3) (const_int 8)))) 2952 (set (reg:SI 4) (mem:SI (plus:SI (reg:SI 3) (const_int 4)))) 2953 (set (reg:SI 30) (mem:SI (reg:SI 3))) 2954 (clobber (reg:CC CC_REGNUM))] 2955 "" 2956{ 2957 if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS) 2958 return "jr __return_interrupt"; 2959 else 2960 { 2961 output_asm_insn ("ld.w 0[sp], ep", operands); 2962 output_asm_insn ("ld.w 4[sp], gp", operands); 2963 output_asm_insn ("ld.w 8[sp], r1", operands); 2964 output_asm_insn ("ld.w 12[sp], r10", operands); 2965 output_asm_insn ("ld.w 16[sp], r11", operands); 2966 output_asm_insn ("addi 20, sp, sp", operands); 2967 output_asm_insn ("reti", operands); 2968 return ""; 2969 } 2970} 2971 [(set (attr "length") 2972 (if_then_else (match_test "TARGET_LONG_CALLS") 2973 (const_int 4) 2974 (const_int 24)))]) 2975 2976;; Save all registers except for the registers saved in save_interrupt when 2977;; an interrupt function makes a call. 2978;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and 2979;; all of memory. This blocks insns from being moved across this point. 2980;; This is needed because the rest of the compiler is not ready to handle 2981;; insns this complicated. 2982 2983(define_insn "callt_save_all_interrupt" 2984 [(unspec_volatile [(const_int 0)] 0) 2985 (clobber (reg:CC CC_REGNUM))] 2986 "(TARGET_V850E_UP) && !TARGET_DISABLE_CALLT" 2987 "callt ctoff(__callt_save_all_interrupt)" 2988 [(set_attr "length" "2")]) 2989 2990(define_insn "save_all_interrupt" 2991 [(unspec_volatile [(const_int 0)] 0) 2992 (clobber (reg:CC CC_REGNUM))] 2993 "" 2994{ 2995 if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS) 2996 return "jarl __save_all_interrupt,r10"; 2997 2998 output_asm_insn ("addi -120, sp, sp", operands); 2999 3000 if (TARGET_EP) 3001 { 3002 output_asm_insn ("mov ep, r1", operands); 3003 output_asm_insn ("mov sp, ep", operands); 3004 output_asm_insn ("sst.w r31, 116[ep]", operands); 3005 output_asm_insn ("sst.w r2, 112[ep]", operands); 3006 output_asm_insn ("sst.w gp, 108[ep]", operands); 3007 output_asm_insn ("sst.w r6, 104[ep]", operands); 3008 output_asm_insn ("sst.w r7, 100[ep]", operands); 3009 output_asm_insn ("sst.w r8, 96[ep]", operands); 3010 output_asm_insn ("sst.w r9, 92[ep]", operands); 3011 output_asm_insn ("sst.w r11, 88[ep]", operands); 3012 output_asm_insn ("sst.w r12, 84[ep]", operands); 3013 output_asm_insn ("sst.w r13, 80[ep]", operands); 3014 output_asm_insn ("sst.w r14, 76[ep]", operands); 3015 output_asm_insn ("sst.w r15, 72[ep]", operands); 3016 output_asm_insn ("sst.w r16, 68[ep]", operands); 3017 output_asm_insn ("sst.w r17, 64[ep]", operands); 3018 output_asm_insn ("sst.w r18, 60[ep]", operands); 3019 output_asm_insn ("sst.w r19, 56[ep]", operands); 3020 output_asm_insn ("sst.w r20, 52[ep]", operands); 3021 output_asm_insn ("sst.w r21, 48[ep]", operands); 3022 output_asm_insn ("sst.w r22, 44[ep]", operands); 3023 output_asm_insn ("sst.w r23, 40[ep]", operands); 3024 output_asm_insn ("sst.w r24, 36[ep]", operands); 3025 output_asm_insn ("sst.w r25, 32[ep]", operands); 3026 output_asm_insn ("sst.w r26, 28[ep]", operands); 3027 output_asm_insn ("sst.w r27, 24[ep]", operands); 3028 output_asm_insn ("sst.w r28, 20[ep]", operands); 3029 output_asm_insn ("sst.w r29, 16[ep]", operands); 3030 output_asm_insn ("mov r1, ep", operands); 3031 } 3032 else 3033 { 3034 output_asm_insn ("st.w r31, 116[sp]", operands); 3035 output_asm_insn ("st.w r2, 112[sp]", operands); 3036 output_asm_insn ("st.w gp, 108[sp]", operands); 3037 output_asm_insn ("st.w r6, 104[sp]", operands); 3038 output_asm_insn ("st.w r7, 100[sp]", operands); 3039 output_asm_insn ("st.w r8, 96[sp]", operands); 3040 output_asm_insn ("st.w r9, 92[sp]", operands); 3041 output_asm_insn ("st.w r11, 88[sp]", operands); 3042 output_asm_insn ("st.w r12, 84[sp]", operands); 3043 output_asm_insn ("st.w r13, 80[sp]", operands); 3044 output_asm_insn ("st.w r14, 76[sp]", operands); 3045 output_asm_insn ("st.w r15, 72[sp]", operands); 3046 output_asm_insn ("st.w r16, 68[sp]", operands); 3047 output_asm_insn ("st.w r17, 64[sp]", operands); 3048 output_asm_insn ("st.w r18, 60[sp]", operands); 3049 output_asm_insn ("st.w r19, 56[sp]", operands); 3050 output_asm_insn ("st.w r20, 52[sp]", operands); 3051 output_asm_insn ("st.w r21, 48[sp]", operands); 3052 output_asm_insn ("st.w r22, 44[sp]", operands); 3053 output_asm_insn ("st.w r23, 40[sp]", operands); 3054 output_asm_insn ("st.w r24, 36[sp]", operands); 3055 output_asm_insn ("st.w r25, 32[sp]", operands); 3056 output_asm_insn ("st.w r26, 28[sp]", operands); 3057 output_asm_insn ("st.w r27, 24[sp]", operands); 3058 output_asm_insn ("st.w r28, 20[sp]", operands); 3059 output_asm_insn ("st.w r29, 16[sp]", operands); 3060 } 3061 3062 return ""; 3063} 3064 [(set (attr "length") 3065 (if_then_else (match_test "TARGET_LONG_CALLS") 3066 (const_int 4) 3067 (const_int 62) 3068 ))]) 3069 3070(define_insn "_save_all_interrupt" 3071 [(unspec_volatile [(const_int 0)] 0) 3072 (clobber (reg:CC CC_REGNUM))] 3073 "TARGET_V850 && ! TARGET_LONG_CALLS" 3074 "jarl __save_all_interrupt,r10" 3075 [(set_attr "length" "4")]) 3076 3077;; Restore all registers saved when an interrupt function makes a call. 3078;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and 3079;; all of memory. This blocks insns from being moved across this point. 3080;; This is needed because the rest of the compiler is not ready to handle 3081;; insns this complicated. 3082 3083(define_insn "callt_restore_all_interrupt" 3084 [(unspec_volatile [(const_int 0)] 1) 3085 (clobber (reg:CC CC_REGNUM))] 3086 "(TARGET_V850E_UP) && !TARGET_DISABLE_CALLT" 3087 "callt ctoff(__callt_restore_all_interrupt)" 3088 [(set_attr "length" "2")]) 3089 3090(define_insn "restore_all_interrupt" 3091 [(unspec_volatile [(const_int 0)] 1) 3092 (clobber (reg:CC CC_REGNUM))] 3093 "" 3094{ 3095 if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS) 3096 return "jarl __restore_all_interrupt,r10"; 3097 3098 if (TARGET_EP) 3099 { 3100 output_asm_insn ("mov ep, r1", operands); 3101 output_asm_insn ("mov sp, ep", operands); 3102 output_asm_insn ("sld.w 116[ep], r31", operands); 3103 output_asm_insn ("sld.w 112[ep], r2", operands); 3104 output_asm_insn ("sld.w 108[ep], gp", operands); 3105 output_asm_insn ("sld.w 104[ep], r6", operands); 3106 output_asm_insn ("sld.w 100[ep], r7", operands); 3107 output_asm_insn ("sld.w 96[ep], r8", operands); 3108 output_asm_insn ("sld.w 92[ep], r9", operands); 3109 output_asm_insn ("sld.w 88[ep], r11", operands); 3110 output_asm_insn ("sld.w 84[ep], r12", operands); 3111 output_asm_insn ("sld.w 80[ep], r13", operands); 3112 output_asm_insn ("sld.w 76[ep], r14", operands); 3113 output_asm_insn ("sld.w 72[ep], r15", operands); 3114 output_asm_insn ("sld.w 68[ep], r16", operands); 3115 output_asm_insn ("sld.w 64[ep], r17", operands); 3116 output_asm_insn ("sld.w 60[ep], r18", operands); 3117 output_asm_insn ("sld.w 56[ep], r19", operands); 3118 output_asm_insn ("sld.w 52[ep], r20", operands); 3119 output_asm_insn ("sld.w 48[ep], r21", operands); 3120 output_asm_insn ("sld.w 44[ep], r22", operands); 3121 output_asm_insn ("sld.w 40[ep], r23", operands); 3122 output_asm_insn ("sld.w 36[ep], r24", operands); 3123 output_asm_insn ("sld.w 32[ep], r25", operands); 3124 output_asm_insn ("sld.w 28[ep], r26", operands); 3125 output_asm_insn ("sld.w 24[ep], r27", operands); 3126 output_asm_insn ("sld.w 20[ep], r28", operands); 3127 output_asm_insn ("sld.w 16[ep], r29", operands); 3128 output_asm_insn ("mov r1, ep", operands); 3129 } 3130 else 3131 { 3132 output_asm_insn ("ld.w 116[sp], r31", operands); 3133 output_asm_insn ("ld.w 112[sp], r2", operands); 3134 output_asm_insn ("ld.w 108[sp], gp", operands); 3135 output_asm_insn ("ld.w 104[sp], r6", operands); 3136 output_asm_insn ("ld.w 100[sp], r7", operands); 3137 output_asm_insn ("ld.w 96[sp], r8", operands); 3138 output_asm_insn ("ld.w 92[sp], r9", operands); 3139 output_asm_insn ("ld.w 88[sp], r11", operands); 3140 output_asm_insn ("ld.w 84[sp], r12", operands); 3141 output_asm_insn ("ld.w 80[sp], r13", operands); 3142 output_asm_insn ("ld.w 76[sp], r14", operands); 3143 output_asm_insn ("ld.w 72[sp], r15", operands); 3144 output_asm_insn ("ld.w 68[sp], r16", operands); 3145 output_asm_insn ("ld.w 64[sp], r17", operands); 3146 output_asm_insn ("ld.w 60[sp], r18", operands); 3147 output_asm_insn ("ld.w 56[sp], r19", operands); 3148 output_asm_insn ("ld.w 52[sp], r20", operands); 3149 output_asm_insn ("ld.w 48[sp], r21", operands); 3150 output_asm_insn ("ld.w 44[sp], r22", operands); 3151 output_asm_insn ("ld.w 40[sp], r23", operands); 3152 output_asm_insn ("ld.w 36[sp], r24", operands); 3153 output_asm_insn ("ld.w 32[sp], r25", operands); 3154 output_asm_insn ("ld.w 28[sp], r26", operands); 3155 output_asm_insn ("ld.w 24[sp], r27", operands); 3156 output_asm_insn ("ld.w 20[sp], r28", operands); 3157 output_asm_insn ("ld.w 16[sp], r29", operands); 3158 } 3159 output_asm_insn ("addi 120, sp, sp", operands); 3160 return ""; 3161} 3162 [(set (attr "length") 3163 (if_then_else (match_test "TARGET_LONG_CALLS") 3164 (const_int 4) 3165 (const_int 62) 3166 ))]) 3167 3168(define_insn "_restore_all_interrupt" 3169 [(unspec_volatile [(const_int 0)] 1) 3170 (clobber (reg:CC CC_REGNUM))] 3171 "TARGET_V850 && ! TARGET_LONG_CALLS" 3172 "jarl __restore_all_interrupt,r10" 3173 [(set_attr "length" "4")]) 3174