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