1 ;; Machine description for Visium. 2 ;; Copyright (C) 2002-2022 Free Software Foundation, Inc. 3 ;; Contributed by C.Nettleton, J.P.Parkes and P.Garbett. 4 5 ;; This file is part of GCC. 6 7 ;; GCC is free software; you can redistribute it and/or modify it 8 ;; under the terms of the GNU General Public License as published 9 ;; by the Free Software Foundation; either version 3, or (at your 10 ;; option) any later version. 11 12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT 13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 15 ;; 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 ;; 22 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 23 ;; 24 ;; Extra register constraints are: 25 ;; 'b' EAM register mdb 26 ;; 'c' EAM register mdc 27 ;; 'f' Floating-point register 28 ;; 'k' Register that can be used as the target of a sibcall, i.e. call-used 29 ;; general register not clobbered in the epilogue: r1-r8 and r10 30 ;; 'l' Low general register, i.e. general register accessible in user mode 31 ;; on the GR6 and, consequently, that can be used as the target of a 32 ;; branch with prediction: r1-r28 33 ;; 't' Register r1 34 ;; 'u' Register r2 35 ;; 'v' Register r3 36 ;; 37 ;; Immediate integer operand constraints are: 38 ;; 'J' 0 .. 65535 (16-bit immediate) 39 ;; 'K' 1 .. 31 (5-bit immediate) 40 ;; 'L' -1 .. -65535 (16-bit negative immediate) 41 ;; 'M' -1 (minus one) 42 ;; 'O' 0 (integer zero) 43 ;; 'P' 32 (thirty two) 44 ;; 45 ;; Immediate FP operand constraints are: 46 ;; 'G' 0.0 (floating-point zero) 47 ;; 48 ;; Operand substitution characters are: 49 ;; %# delay slot follows, if empty, fill with NOP 50 ;; %b LS 8 bits of immediate operand 51 ;; %w LS 16 bits of immediate operand 52 ;; %u MS 16 bits of immediate operand 53 ;; %r register or zero (r0) 54 ;; %f FP register or zero (f0) 55 ;; %d second register in a pair 56 ;; 57 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 58 ;; 59 60 ;; Registers by name. 61 (define_constants [ 62 (R_R1 1) 63 (R_R2 2) 64 (R_R3 3) 65 (R_R4 4) 66 (R_R5 5) 67 (R_R6 6) 68 (R_LINK 21) 69 (R_FP 22) 70 (R_SP 23) 71 (R_MDB 32) 72 (R_MDC 33) 73 (R_FLAGS 50) 74 ]) 75 76 ;; UNSPEC usage. 77 (define_c_enum "unspec" [ 78 UNSPEC_MDBHI 79 UNSPEC_FLOAD 80 UNSPEC_FSTORE 81 UNSPEC_ITOF 82 UNSPEC_FTOI 83 UNSPEC_NOP 84 UNSPEC_ADDV 85 UNSPEC_SUBV 86 UNSPEC_NEGV 87 ]) 88 89 ;; UNSPEC_VOLATILE usage. 90 (define_c_enum "unspecv" [ 91 UNSPECV_BLOCKAGE 92 UNSPECV_DSI 93 ]) 94 95 (include "predicates.md") 96 (include "constraints.md") 97 98 ;; 99 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 100 ;; 101 ;; Attributes. 102 ;; 103 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 104 ;; 105 106 ; Attribute for cpu type. 107 ; These must match the values for enum processor_type in visium-opts.h. 108 (define_attr "cpu" "gr5,gr6" (const (symbol_ref "visium_cpu_attr"))) 109 110 ; Instruction type. 111 ; 112 ;imm_reg Move of immediate value to register. 113 ;mem_reg Move from memory to register. 114 ;eam_reg Move from EAM to register. 115 ;fp_reg Move from FPU to register. 116 ;reg_mem Move from register to memory. 117 ;reg_eam Move from register to EAM. 118 ;reg_fp Move from register to FPU. 119 ;arith Arithmetic operation, result in register, sets overflow. 120 ;arith2 Two successive arithmetic operations. 121 ;logic Logical operation, result in register, does not set overflow. 122 ;abs_branch Absolute branch. 123 ;branch Branch. 124 ;bmi Block move. 125 ;call Call to subprogram. 126 ;ret Return from subprogram. 127 ;rfi Return from interrupt. 128 ;dsi Disable interrupts. 129 ;cmp Compare or test. 130 ;div EAM 32/32 division. 131 ;divd EAM 64/32 division. 132 ;mul EAM 32 * 32 -> 64 multiplication. 133 ;shiftdi EAM 64 bit shift. 134 ;fdiv Floating point divide. 135 ;fsqrt Floating point square root. 136 ;ftoi Fix float to integer. 137 ;itof Float integer. 138 ;fmove Floating point move w/ or w/o change of sign: fmove, fabs, fneg. 139 ;fcmp Floating point compare or test. 140 ;fp Other floating point operations. 141 ;nop No operation. 142 ;multi Multiple instructions which split. 143 ;asm User asm instructions. 144 ;trap Trap instructions. 145 146 (define_attr "type" 147 "imm_reg,mem_reg,eam_reg,fp_reg,reg_mem,reg_eam,reg_fp,arith,arith2,logic,abs_branch,branch,bmi,call,ret,rfi,dsi,cmp,div,divd,mul,shiftdi,fdiv,fsqrt,ftoi,itof,fmove,fcmp,fp,nop,multi,asm,trap" (const_string "logic")) 148 149 ; Those insns that occupy 4 bytes. 150 (define_attr "single_insn" "no,yes" 151 (if_then_else (eq_attr "type" "arith2,rfi,multi") 152 (const_string "no") 153 (const_string "yes"))) 154 155 ; True if branch or call will be emitting a nop into its delay slot. 156 (define_attr "empty_delay_slot" "false,true" 157 (symbol_ref "(empty_delay_slot (insn) 158 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)")) 159 160 ; Length in bytes. 161 ; On the GR6, absolute branches must be aligned on a 64-bit boundary to avoid 162 ; a pipeline hazard. This is done by the assembler, so the length of these 163 ; instructions for the compiler can effectively be 4, 8, or 12 bytes. 164 ; The allowed range for the offset of relative branches is [-131072;131068] 165 ; and it is counted from the address of the insn so we need to subtract 166 ; 8 for forward branches because (pc) points to the next insn for them. 167 (define_attr "length" "" 168 (cond [(eq_attr "type" "abs_branch,call,ret") 169 (if_then_else (eq_attr "empty_delay_slot" "true") 170 (if_then_else (and (eq_attr "cpu" "gr6") 171 (eq (mod (pc) (const_int 8)) 172 (const_int 4))) 173 (const_int 12) 174 (const_int 8)) 175 (if_then_else (and (eq_attr "cpu" "gr6") 176 (eq (mod (pc) (const_int 8)) 177 (const_int 4))) 178 (const_int 8) 179 (const_int 4))) 180 (eq_attr "type" "branch") 181 (if_then_else (leu (plus (minus (match_dup 0) (pc)) 182 (const_int 131060)) 183 (const_int 262120)) 184 (if_then_else (eq_attr "empty_delay_slot" "true") 185 (const_int 8) 186 (const_int 4)) 187 (if_then_else (and (eq_attr "cpu" "gr6") 188 (eq (mod (pc) (const_int 8)) 189 (const_int 0))) 190 (const_int 24) 191 (const_int 20))) 192 (eq_attr "single_insn" "no") 193 (const_int 8)] (const_int 4))) 194 195 (define_asm_attributes [(set_attr "type" "asm")]) 196 197 ; Delay slots. 198 (define_delay (eq_attr "type" "abs_branch,branch,call,ret") 199 [(and (eq_attr "type" "!abs_branch,branch,call,ret,rfi,bmi,mul,div,divd,fdiv,fsqrt,asm") 200 (eq_attr "single_insn" "yes")) 201 (nil) (nil)]) 202 203 ;; 204 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 205 ;; 206 ;; Processor pipeline description. 207 ;; 208 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 209 ;; 210 211 (include "gr5.md") 212 (include "gr6.md") 213 214 ;; 215 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 216 ;; 217 ;; Iterators. 218 ;; 219 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 220 ;; 221 222 (define_mode_iterator QHI [QI HI]) 223 (define_mode_iterator I [QI HI SI]) 224 (define_mode_attr b [(QI "8") (HI "16") (SI "32")]) 225 (define_mode_attr s [(QI ".b") (HI ".w") (SI ".l")]) 226 227 ; This code iterator allows signed and unsigned widening multiplications 228 ; to use the same template. 229 (define_code_iterator any_extend [sign_extend zero_extend]) 230 231 ; <u> expands to an empty string when doing a signed operation and 232 ; "u" when doing an unsigned operation. 233 (define_code_attr u [(sign_extend "") (zero_extend "u")]) 234 235 ; <su> is like <u>, but the signed form expands to "s" rather than "". 236 (define_code_attr su [(sign_extend "s") (zero_extend "u")]) 237 238 ; This code iterator allows returns and simple returns to use the same template. 239 (define_code_iterator any_return [return simple_return]) 240 (define_code_attr return_pred [(return "visium_can_use_return_insn_p ()") 241 (simple_return "!visium_interrupt_function_p ()")]) 242 (define_code_attr return_str [(return "") (simple_return "simple_")]) 243 244 ; This code iterator allows integer and FP cstores to use the same template. 245 (define_code_iterator any_scc [ltu lt]) 246 (define_code_attr scc_str [(ltu "sltu") (lt "slt")]) 247 248 ;This code iterator allows cstore splitters to use the same template. 249 (define_code_iterator any_add [plus minus]) 250 (define_code_attr add_op [(plus "PLUS") (minus "MINUS")]) 251 (define_code_attr add_str [(plus "plus") (minus "minus")]) 252 253 ;; 254 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 255 ;; 256 ;; Substitutions. 257 ;; 258 ;; They are used to define the first instruction of the pairs required by 259 ;; the postreload compare elimination pass, with a first variant for the 260 ;; logical insns and a second variant for the arithmetic insns. 261 ;; 262 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 263 ;; 264 265 (define_subst "flags_subst_logic" 266 [(set (match_operand 0 "") (match_operand 1 "")) 267 (clobber (reg:CC R_FLAGS))] 268 "" 269 [(set (reg:CC R_FLAGS) 270 (compare:CC (match_dup 1) (const_int 0))) 271 (set (match_dup 0) (match_dup 1))]) 272 273 (define_subst_attr "subst_logic" "flags_subst_logic" "_flags" "_set_flags") 274 275 (define_subst "flags_subst_arith" 276 [(set (match_operand 0 "") (match_operand 1 "")) 277 (clobber (reg:CC R_FLAGS))] 278 "" 279 [(set (reg:CCNZ R_FLAGS) 280 (compare:CCNZ (match_dup 1) (const_int 0))) 281 (set (match_dup 0) (match_dup 1))]) 282 283 (define_subst_attr "subst_arith" "flags_subst_arith" "_flags" "_set_flags") 284 285 ;; 286 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 287 ;; 288 ;; QImode moves 289 ;; 290 ;; For moving among registers we use the move.b instruction. This is 291 ;; actually an OR instruction using an alias. For moving between register 292 ;; and memory we need the address of the memory location in a register. 293 ;; However, we can accept an expression (reg + offset) where offset is in 294 ;; the range 0 .. 31. 295 ;; 296 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 297 ;; 298 299 (define_expand "movqi" 300 [(set (match_operand:QI 0 "nonimmediate_operand" "") 301 (match_operand:QI 1 "general_operand" ""))] 302 "" 303 { 304 prepare_move_operands (operands, QImode); 305 }) 306 307 (define_insn "*movqi_insn" 308 [(set (match_operand:QI 0 "nonimmediate_operand" "=r, m,?b,?c, r, r,r,r") 309 (match_operand:QI 1 "general_operand" " r,rO, r, r,?b,?c,i,m"))] 310 "ok_for_simple_move_operands (operands, QImode)" 311 "@ 312 # 313 write.b %0,%r1 314 writemd %1,r0 ;movqi ?b r 315 writemdc %1 ;movqi ?c r 316 readmda %0 ;movqi r ?b 317 readmdc %0 ;movqi r ?c 318 moviq %0,%b1 ;movqi r i 319 read.b %0,%1" 320 [(set_attr "type" "logic,reg_mem,reg_eam,reg_eam,eam_reg,eam_reg,imm_reg,mem_reg")]) 321 322 (define_insn "*movqi_insn<subst_logic>" 323 [(set (match_operand:QI 0 "gpc_reg_operand" "=r") 324 (match_operand:QI 1 "gpc_reg_operand" "r")) 325 (clobber (reg:CC R_FLAGS))] 326 "reload_completed" 327 "move.b %0,%1" 328 [(set_attr "type" "logic")]) 329 330 (define_split 331 [(set (match_operand:QI 0 "gpc_reg_operand" "") 332 (match_operand:QI 1 "gpc_reg_operand" ""))] 333 "reload_completed" 334 [(parallel [(set (match_dup 0) (match_dup 1)) 335 (clobber (reg:CC R_FLAGS))])] 336 "") 337 338 (define_expand "movstrictqi" 339 [(set (strict_low_part (match_operand:QI 0 "register_operand" "")) 340 (match_operand:QI 1 "general_operand" ""))] 341 "") 342 343 (define_insn "*movstrictqi_insn" 344 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+r,r")) 345 (match_operand:QI 1 "general_operand" "rO,m"))] 346 "ok_for_simple_move_strict_operands (operands, QImode)" 347 "@ 348 # 349 read.b %0,%1" 350 [(set_attr "type" "logic,mem_reg")]) 351 352 (define_insn "*movstrictqi_insn<subst_logic>" 353 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+r")) 354 (match_operand:QI 1 "reg_or_0_operand" "rO")) 355 (clobber (reg:CC R_FLAGS))] 356 "reload_completed" 357 "move.b %0,%r1" 358 [(set_attr "type" "logic")]) 359 360 (define_split 361 [(set (strict_low_part (match_operand:QI 0 "register_operand" "")) 362 (match_operand:QI 1 "reg_or_0_operand" ""))] 363 "reload_completed" 364 [(parallel [(set (strict_low_part (match_dup 0)) (match_dup 1)) 365 (clobber (reg:CC R_FLAGS))])] 366 "") 367 368 ;; 369 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 370 ;; 371 ;; HImode moves 372 ;; 373 ;; For moving among registers we use the move.w instruction. This is 374 ;; actually an OR instruction using an alias. For moving between register 375 ;; and memory we need the address of the memory location in a register. 376 ;; However, we can accept an expression (reg + offset) where offset is in 377 ;; the range 0 .. 62 and is shifted right one place in the assembled 378 ;; instruction. 379 ;; 380 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 381 ;; 382 383 (define_expand "movhi" 384 [(set (match_operand:HI 0 "nonimmediate_operand" "") 385 (match_operand:HI 1 "general_operand" ""))] 386 "" 387 { 388 prepare_move_operands (operands, HImode); 389 }) 390 391 (define_insn "*movhi_insn" 392 [(set (match_operand:HI 0 "nonimmediate_operand" "=r, m,?b,?c, r, r,r,r") 393 (match_operand:HI 1 "general_operand" " r,rO, r, r,?b,?c,i,m"))] 394 "ok_for_simple_move_operands (operands, HImode)" 395 "@ 396 # 397 write.w %0,%r1 398 writemd %1,r0 ;movhi ?b r 399 writemdc %1 ;movhi ?c r 400 readmda %0 ;movhi r ?b 401 readmdc %0 ;movhi r ?c 402 moviq %0,%w1 ;movhi r i 403 read.w %0,%1" 404 [(set_attr "type" "logic,reg_mem,reg_eam,reg_eam,eam_reg,eam_reg,imm_reg,mem_reg")]) 405 406 (define_insn "*movhi_insn<subst_logic>" 407 [(set (match_operand:HI 0 "gpc_reg_operand" "=r") 408 (match_operand:HI 1 "gpc_reg_operand" "r")) 409 (clobber (reg:CC R_FLAGS))] 410 "reload_completed" 411 "move.w %0,%1" 412 [(set_attr "type" "logic")]) 413 414 (define_split 415 [(set (match_operand:HI 0 "gpc_reg_operand" "") 416 (match_operand:HI 1 "gpc_reg_operand" ""))] 417 "reload_completed" 418 [(parallel [(set (match_dup 0) (match_dup 1)) 419 (clobber (reg:CC R_FLAGS))])] 420 "") 421 422 (define_expand "movstricthi" 423 [(set (strict_low_part (match_operand:HI 0 "register_operand" "")) 424 (match_operand:HI 1 "general_operand" ""))] 425 "") 426 427 (define_insn "*movstricthi_insn" 428 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r,r,r")) 429 (match_operand:HI 1 "general_operand" " r,i,m"))] 430 "ok_for_simple_move_strict_operands (operands, HImode)" 431 "@ 432 # 433 movil %0,%w1 434 read.w %0,%1" 435 [(set_attr "type" "logic,imm_reg,mem_reg")]) 436 437 (define_insn "*movstricthi_insn<subst_logic>" 438 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r")) 439 (match_operand:HI 1 "register_operand" "r")) 440 (clobber (reg:CC R_FLAGS))] 441 "reload_completed" 442 "move.w %0,%1" 443 [(set_attr "type" "logic")]) 444 445 (define_split 446 [(set (strict_low_part (match_operand:HI 0 "register_operand" "")) 447 (match_operand:HI 1 "register_operand" ""))] 448 "reload_completed" 449 [(parallel [(set (strict_low_part (match_dup 0)) (match_dup 1)) 450 (clobber (reg:CC R_FLAGS))])] 451 "") 452 453 ;; 454 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 455 ;; 456 ;; SImode moves 457 ;; 458 ;; For moving among registers we use the move.l instruction. This is 459 ;; actually an OR instruction using an alias. For moving between register 460 ;; and memory we need the address of the memory location in a register. 461 ;; However, we can accept an expression (reg + offset) where offset is in 462 ;; the range 0 .. 124 and is shifted right two places in the assembled 463 ;; instruction. 464 ;; 465 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 466 ;; 467 468 (define_expand "movsi" 469 [(set (match_operand:SI 0 "nonimmediate_operand" "") 470 (match_operand:SI 1 "general_operand" ""))] 471 "" 472 { 473 prepare_move_operands (operands, SImode); 474 }) 475 476 (define_insn "*movsi_high" 477 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") 478 (high:SI (match_operand:SI 1 "immediate_operand" "n,i")) )] 479 "" 480 "@ 481 moviu %0,%u1 482 moviu %0,%%u %a1" 483 [(set_attr "type" "imm_reg")]) 484 485 ; We only care about the lower 16 bits of the constant 486 ; being inserted into the upper 16 bits of the register. 487 (define_insn "*moviu" 488 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r") 489 (const_int 16) 490 (const_int 0)) 491 (match_operand:SI 1 "const_int_operand" "n"))] 492 "" 493 "moviu %0,%w1" 494 [(set_attr "type" "imm_reg")]) 495 496 (define_insn "*movsi_losum" 497 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") 498 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 499 (match_operand:SI 2 "immediate_operand" "n,i")))] 500 "" 501 "@ 502 movil %0,%w2 503 movil %0,%%l %a2" 504 [(set_attr "type" "imm_reg")]) 505 506 (define_insn "*movil" 507 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r") 508 (const_int 16) 509 (const_int 16)) 510 (match_operand:SI 1 "const_int_operand" "n"))] 511 "" 512 "movil %0,%w1" 513 [(set_attr "type" "imm_reg")]) 514 515 (define_insn "*movsi_insn_no_ieee" 516 [(set (match_operand:SI 0 "nonimmediate_operand" "=r, m,?b,?c, r, r,r,r,r,r, r,!f") 517 (match_operand:SI 1 "general_operand" " r,rO, r, r,?b,?c,J,M,i,m,!f, r"))] 518 "!TARGET_FPU_IEEE && ok_for_simple_move_operands (operands, SImode)" 519 "@ 520 # 521 write.l %0,%r1 522 writemd %1,r0 ;movsi ?b r 523 writemdc %1 ;movsi ?c r 524 readmda %0 ;movsi r ?b 525 readmdc %0 ;movsi r ?c 526 moviq %0,%1 ;movsi r J 527 # 528 # ;movsi r i 529 read.l %0,%1 530 fstore %0,%1 531 fload %0,%1" 532 [(set_attr "type" "logic,reg_mem,reg_eam,reg_eam,eam_reg,eam_reg,imm_reg,logic,multi,mem_reg,fp_reg,reg_fp")]) 533 534 (define_insn "*movsi_insn" 535 [(set (match_operand:SI 0 "nonimmediate_operand" "=r, m,?b,?c, r, r,r,r,r,r, r,?f,f") 536 (match_operand:SI 1 "general_operand" " r,rO, r, r,?b,?c,J,M,i,m,?f, r,f"))] 537 "TARGET_FPU_IEEE && ok_for_simple_move_operands (operands, SImode)" 538 "@ 539 # 540 write.l %0,%r1 541 writemd %1,r0 ;movsi ?b r 542 writemdc %1 ;movsi ?c r 543 readmda %0 ;movsi r ?b 544 readmdc %0 ;movsi r ?c 545 moviq %0,%1 ;movsi r J 546 # 547 # ;movsi r i 548 read.l %0,%1 549 fstore %0,%1 550 fload %0,%1 551 fmove %0,%1" 552 [(set_attr "type" "logic,reg_mem,reg_eam,reg_eam,eam_reg,eam_reg,imm_reg,logic,multi,mem_reg,fp_reg,reg_fp,fmove")]) 553 554 (define_insn "*movsi_insn<subst_logic>" 555 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 556 (match_operand:SI 1 "gpc_reg_operand" "r")) 557 (clobber (reg:CC R_FLAGS))] 558 "reload_completed" 559 "move.l %0,%1" 560 [(set_attr "type" "logic")]) 561 562 (define_insn "*movsi_insn_m1<subst_logic>" 563 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 564 (const_int -1)) 565 (clobber (reg:CC R_FLAGS))] 566 "reload_completed" 567 "not.l %0,r0" 568 [(set_attr "type" "logic")]) 569 570 (define_split 571 [(set (match_operand:SI 0 "gpc_reg_operand" "") 572 (match_operand:SI 1 "gpc_reg_operand" ""))] 573 "reload_completed" 574 [(parallel [(set (match_dup 0) (match_dup 1)) 575 (clobber (reg:CC R_FLAGS))])] 576 "") 577 578 (define_split 579 [(set (match_operand:SI 0 "gpc_reg_operand" "") 580 (const_int -1))] 581 "reload_completed" 582 [(parallel [(set (match_dup 0) (const_int -1)) 583 (clobber (reg:CC R_FLAGS))])] 584 "") 585 586 (define_insn "*movsi_mdbhi" 587 [(set (match_operand:SI 0 "register_operand" "=r") 588 (unspec:SI [(reg:DI R_MDB)] UNSPEC_MDBHI))] 589 "" 590 "readmdb %0" 591 [(set_attr "type" "eam_reg")]) 592 593 (define_split 594 [(set (match_operand:SI 0 "gpc_reg_operand" "") 595 (match_operand:SI 1 "large_immediate_operand" ""))] 596 "reload_completed" 597 [(set (match_dup 0) 598 (high:SI (match_dup 1)) ) 599 (set (match_dup 0) 600 (lo_sum:SI (match_dup 0) (match_dup 1)))] 601 "") 602 603 ;; 604 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 605 ;; 606 ;; DImode moves 607 ;; 608 ;; When the destination is the EAM register MDB, then we use the writemd 609 ;; instruction. In all other cases we split the move into two 32-bit moves. 610 ;; 611 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 612 ;; 613 614 (define_expand "movdi" 615 [(set (match_operand:DI 0 "nonimmediate_operand" "") 616 (match_operand:DI 1 "general_operand" ""))] 617 "" 618 { 619 prepare_move_operands (operands, DImode); 620 }) 621 622 (define_insn "*movdi_insn" 623 [(set (match_operand:DI 0 "nonimmediate_operand" "= r, m, r,??b") 624 (match_operand:DI 1 "general_operand" "rim,rO,?b, r"))] 625 "ok_for_simple_move_operands (operands, DImode)" 626 "@ 627 # 628 # 629 # 630 writemd %d1,%1 ;movdi ?b r" 631 [(set_attr "type" "multi,multi,multi,reg_eam")]) 632 633 (define_split 634 [(set (match_operand:DI 0 "gpc_reg_operand" "") (reg:DI R_MDB))] 635 "reload_completed" 636 [(set (match_dup 1) (unspec:SI [(reg:DI R_MDB)] UNSPEC_MDBHI)) 637 (set (match_dup 2) (reg:SI R_MDB))] 638 { 639 operands[1] = operand_subword (operands[0], 0, 1, DImode); 640 operands[2] = operand_subword (operands[0], 1, 1, DImode); 641 }) 642 643 (define_split 644 [(set (match_operand:DI 0 "non_eam_dst_operand" "") 645 (match_operand:DI 1 "non_eam_src_operand" ""))] 646 "reload_completed" 647 [(set (match_dup 2) (match_dup 3)) 648 (set (match_dup 4) (match_dup 5))] 649 { 650 visium_split_double_move (operands, DImode); 651 }) 652 653 ;; 654 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 655 ;; 656 ;; SFmode moves 657 ;; 658 ;; Constants are constructed in a GP register and moved to the FP register. 659 ;; 660 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 661 ;; 662 663 (define_expand "movsf" 664 [(set (match_operand:SF 0 "nonimmediate_operand" "") 665 (match_operand:SF 1 "general_operand" ""))] 666 "" 667 { 668 prepare_move_operands (operands, SFmode); 669 }) 670 671 (define_insn "*movsf_insn" 672 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,r,r, m,r,r,r") 673 (match_operand:SF 1 "general_operand" " f,G,r,f,r,rG,G,F,m"))] 674 "ok_for_simple_move_operands (operands, SFmode)" 675 "@ 676 fmove %0,%1 677 fmove %0,f0 678 fload %0,%1 679 fstore %0,%1 680 # 681 write.l %0,%r1 682 moviq %0,0 683 # 684 read.l %0,%1" 685 [(set_attr "type" "fmove,fmove,reg_fp,fp_reg,logic,reg_mem,imm_reg,multi,mem_reg")]) 686 687 (define_insn "*movsf_insn" 688 [(set (match_operand:SF 0 "gpc_reg_operand" "=r") 689 (match_operand:SF 1 "gpc_reg_operand" "r")) 690 (clobber (reg:CC R_FLAGS))] 691 "reload_completed" 692 "move.l %0,%1" 693 [(set_attr "type" "logic")]) 694 695 (define_split 696 [(set (match_operand:SF 0 "gpc_reg_operand" "") 697 (match_operand:SF 1 "gpc_reg_operand" ""))] 698 "reload_completed" 699 [(parallel [(set (match_dup 0) (match_dup 1)) 700 (clobber (reg:CC R_FLAGS))])] 701 "") 702 703 (define_split 704 [(set (match_operand:SF 0 "gpc_reg_operand" "") 705 (match_operand:SF 1 "const_double_operand" ""))] 706 "reload_completed" 707 [(set (match_dup 2) (match_dup 3))] 708 { 709 long l; 710 711 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (operands[1]), l); 712 713 operands[2] = operand_subword (operands[0], 0, 0, SFmode); 714 operands[3] = GEN_INT (trunc_int_for_mode (l, SImode)); 715 }) 716 717 ;; 718 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 719 ;; 720 ;; DFmode moves 721 ;; 722 ;; We always split a DFmode move into two SImode moves. 723 ;; 724 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 725 ;; 726 727 (define_expand "movdf" 728 [(set (match_operand:DF 0 "nonimmediate_operand" "") 729 (match_operand:DF 1 "general_operand" ""))] 730 "" 731 { 732 prepare_move_operands (operands, DFmode); 733 }) 734 735 (define_insn "*movdf_insn" 736 [(set (match_operand:DF 0 "nonimmediate_operand" "= r, m") 737 (match_operand:DF 1 "general_operand" "rFm,rG"))] 738 "ok_for_simple_move_operands (operands, DFmode)" 739 "#" 740 [(set_attr "type" "multi")]) 741 742 (define_split 743 [(set (match_operand:DF 0 "nonimmediate_operand" "") 744 (match_operand:DF 1 "general_operand" ""))] 745 "reload_completed" 746 [(set (match_dup 2) (match_dup 3)) 747 (set (match_dup 4) (match_dup 5))] 748 { 749 visium_split_double_move (operands, DFmode); 750 }) 751 752 ;; 753 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 754 ;; 755 ;; Integer Add 756 ;; 757 ;; Modes QI, HI, SI and DI are supported directly. 758 ;; 759 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 760 ;; 761 762 (define_expand "add<mode>3" 763 [(set (match_operand:QHI 0 "register_operand" "") 764 (plus:QHI (match_operand:QHI 1 "register_operand" "") 765 (match_operand:QHI 2 "register_operand" "")))] 766 "") 767 768 (define_expand "uaddv<mode>4" 769 [(set (match_operand:I 0 "register_operand" "") 770 (plus:I (match_operand:I 1 "register_operand" "") 771 (match_operand:I 2 "register_operand" ""))) 772 (set (pc) 773 (if_then_else (ltu (match_dup 0) (match_dup 1)) 774 (label_ref (match_operand 3 "")) 775 (pc)))] 776 "") 777 778 (define_expand "addv<mode>4" 779 [(set (match_operand:I 0 "register_operand" "") 780 (plus:I (match_operand:I 1 "register_operand" "") 781 (match_operand:I 2 "register_operand" ""))) 782 (set (pc) 783 (if_then_else (ne (match_dup 0) 784 (unspec:I [(match_dup 1) (match_dup 2)] UNSPEC_ADDV)) 785 (label_ref (match_operand 3 "")) 786 (pc)))] 787 "") 788 789 (define_insn_and_split "*add<mode>3_insn" 790 [(set (match_operand:QHI 0 "register_operand" "=r") 791 (plus:QHI (match_operand:QHI 1 "register_operand" "%r") 792 (match_operand:QHI 2 "register_operand" "r")))] 793 "ok_for_simple_arith_logic_operands (operands, <MODE>mode)" 794 "#" 795 "reload_completed" 796 [(parallel [(set (match_dup 0) 797 (plus:QHI (match_dup 1) (match_dup 2))) 798 (clobber (reg:CC R_FLAGS))])] 799 "" 800 [(set_attr "type" "arith")]) 801 802 (define_insn "*add<mode>3_insn<subst_arith>" 803 [(set (match_operand:QHI 0 "register_operand" "=r") 804 (plus:QHI (match_operand:QHI 1 "register_operand" "%r") 805 (match_operand:QHI 2 "register_operand" "r"))) 806 (clobber (reg:CC R_FLAGS))] 807 "reload_completed" 808 "add<s> %0,%1,%2" 809 [(set_attr "type" "arith")]) 810 811 (define_insn "*add<mode>3_insn_set_carry" 812 [(set (reg:CCC R_FLAGS) 813 (compare:CCC (plus:QHI (match_operand:QHI 1 "register_operand" "%r") 814 (match_operand:QHI 2 "register_operand" "r")) 815 (match_dup 1))) 816 (set (match_operand:QHI 0 "register_operand" "=r") 817 (plus:QHI (match_dup 1) (match_dup 2)))] 818 "reload_completed" 819 "add<s> %0,%1,%2" 820 [(set_attr "type" "arith")]) 821 822 (define_insn "*add<mode>3_insn_set_overflow" 823 [(set (reg:CCV R_FLAGS) 824 (compare:CCV (plus:QHI (match_operand:QHI 1 "register_operand" "%r") 825 (match_operand:QHI 2 "register_operand" "r")) 826 (unspec:QHI [(match_dup 1) (match_dup 2)] UNSPEC_ADDV))) 827 (set (match_operand:QHI 0 "register_operand" "=r") 828 (plus:QHI (match_dup 1) (match_dup 2)))] 829 "reload_completed" 830 "add<s> %0,%1,%2" 831 [(set_attr "type" "arith")]) 832 833 (define_expand "addsi3" 834 [(set (match_operand:SI 0 "register_operand" "") 835 (plus:SI (match_operand:SI 1 "register_operand" "") 836 (match_operand:SI 2 "add_operand" "")))] 837 "") 838 839 (define_expand "addsi3_flags" 840 [(parallel [(set (match_operand:SI 0 "register_operand" "") 841 (plus:SI (match_operand:SI 1 "register_operand" "") 842 (match_operand:SI 2 "add_operand" ""))) 843 (clobber (reg:CC R_FLAGS))])] 844 "reload_completed" 845 "") 846 847 (define_insn_and_split "*addsi3_insn" 848 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 849 (plus:SI (match_operand:SI 1 "register_operand" "%0,r,0") 850 (match_operand:SI 2 "add_operand" " L,r,J")))] 851 "ok_for_simple_arith_logic_operands (operands, SImode)" 852 "#" 853 "reload_completed" 854 [(parallel [(set (match_dup 0) 855 (plus:SI (match_dup 1) (match_dup 2))) 856 (clobber (reg:CC R_FLAGS))])] 857 "" 858 [(set_attr "type" "arith")]) 859 860 ; Favour the addition of small negative constants, since they are 861 ; expensive to load into a register. 862 863 (define_insn "*addsi3_insn<subst_arith>" 864 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 865 (plus:SI (match_operand:SI 1 "register_operand" "%0,r,0") 866 (match_operand:SI 2 "add_operand" " L,r,J"))) 867 (clobber (reg:CC R_FLAGS))] 868 "reload_completed" 869 "@ 870 subi %0,%n2 871 add.l %0,%1,%2 872 addi %0,%2" 873 [(set_attr "type" "arith")]) 874 875 (define_insn "addsi3_insn_set_carry" 876 [(set (reg:CCC R_FLAGS) 877 (compare:CCC (plus:SI (match_operand:SI 1 "register_operand" "%r,0") 878 (match_operand:SI 2 "real_add_operand" " r,J")) 879 (match_dup 1))) 880 (set (match_operand:SI 0 "register_operand" "=r,r") 881 (plus:SI (match_dup 1) (match_dup 2)))] 882 "reload_completed" 883 "@ 884 add.l %0,%1,%2 885 addi %0,%2" 886 [(set_attr "type" "arith")]) 887 888 (define_insn "*addsi3_insn_set_overflow" 889 [(set (reg:CCV R_FLAGS) 890 (compare:CCV (plus:SI (match_operand:SI 1 "register_operand" "%r,0") 891 (match_operand:SI 2 "real_add_operand" " r,J")) 892 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_ADDV))) 893 (set (match_operand:SI 0 "register_operand" "=r,r") 894 (plus:SI (match_dup 1) (match_dup 2)))] 895 "reload_completed" 896 "@ 897 add.l %0,%1,%2 898 addi %0,%2" 899 [(set_attr "type" "arith")]) 900 901 (define_expand "adddi3" 902 [(set (match_operand:DI 0 "register_operand" "") 903 (plus:DI (match_operand:DI 1 "register_operand" "") 904 (match_operand:DI 2 "add_operand" "")))] 905 "") 906 907 ; Disfavour the use of add.l because of the early clobber. 908 909 (define_insn_and_split "*addi3_insn" 910 [(set (match_operand:DI 0 "register_operand" "=r,r,&r") 911 (plus:DI (match_operand:DI 1 "register_operand" "%0,0, r") 912 (match_operand:DI 2 "add_operand" " L,J, r")))] 913 "ok_for_simple_arith_logic_operands (operands, DImode)" 914 "#" 915 "reload_completed" 916 [(const_int 0)] 917 { 918 visium_split_double_add (PLUS, operands[0], operands[1], operands[2]); 919 DONE; 920 } 921 [(set_attr "type" "arith2")]) 922 923 ;; 924 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 925 ;; 926 ;; Integer Add with Carry 927 ;; 928 ;; Only SI mode is supported. 929 ;; 930 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 931 ;; 932 933 (define_insn "*<scc_str><subst_arith>" 934 [(set (match_operand:SI 0 "register_operand" "=r") 935 (any_scc:SI (reg R_FLAGS) (const_int 0))) 936 (clobber (reg:CC R_FLAGS))] 937 "reload_completed" 938 "adc.l %0,r0,r0" 939 [(set_attr "type" "arith")]) 940 941 (define_insn "*plus_<scc_str><subst_arith>" 942 [(set (match_operand:SI 0 "register_operand" "=r") 943 (plus:SI (match_operand:SI 1 "register_operand" "r") 944 (any_scc:SI (reg R_FLAGS) (const_int 0)))) 945 (clobber (reg:CC R_FLAGS))] 946 "reload_completed" 947 "adc.l %0,%1,r0" 948 [(set_attr "type" "arith")]) 949 950 (define_insn "*plus_plus_sltu<subst_arith>" 951 [(set (match_operand:SI 0 "register_operand" "=r") 952 (plus:SI (plus:SI (match_operand:SI 1 "register_operand" "r") 953 (match_operand:SI 2 "register_operand" "r")) 954 (ltu:SI (reg R_FLAGS) (const_int 0)))) 955 (clobber (reg:CC R_FLAGS))] 956 "reload_completed" 957 "adc.l %0,%1,%2" 958 [(set_attr "type" "arith")]) 959 960 ;; 961 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 962 ;; 963 ;; Integer Subtract 964 ;; 965 ;; Modes QI, HI, SI and DI are supported directly. 966 ;; 967 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 968 ;; 969 970 (define_expand "sub<mode>3" 971 [(set (match_operand:QHI 0 "register_operand" "") 972 (minus:QHI (match_operand:QHI 1 "reg_or_0_operand" "") 973 (match_operand:QHI 2 "register_operand" "")))] 974 "") 975 976 (define_expand "usubv<mode>4" 977 [(set (match_operand:I 0 "register_operand" "") 978 (minus:I (match_operand:I 1 "reg_or_0_operand" "") 979 (match_operand:I 2 "register_operand" ""))) 980 (set (pc) 981 (if_then_else (ltu (match_dup 1) (match_dup 2)) 982 (label_ref (match_operand 3 "")) 983 (pc)))] 984 "" 985 { 986 if (operands[1] == const0_rtx) 987 { 988 emit_insn (gen_unegv<mode>3 (operands[0], operands[2], operands[3])); 989 DONE; 990 } 991 }) 992 993 (define_expand "subv<mode>4" 994 [(set (match_operand:I 0 "register_operand" "") 995 (minus:I (match_operand:I 1 "register_operand" "") 996 (match_operand:I 2 "register_operand" ""))) 997 (set (pc) 998 (if_then_else (ne (match_dup 0) 999 (unspec:I [(match_dup 1) (match_dup 2)] UNSPEC_SUBV)) 1000 (label_ref (match_operand 3 "")) 1001 (pc)))] 1002 "") 1003 1004 (define_insn_and_split "*sub<mode>3_insn" 1005 [(set (match_operand:QHI 0 "register_operand" "=r") 1006 (minus:QHI (match_operand:QHI 1 "reg_or_0_operand" "rO") 1007 (match_operand:QHI 2 "register_operand" "r")))] 1008 "ok_for_simple_arith_logic_operands (operands, <MODE>mode)" 1009 "#" 1010 "reload_completed" 1011 [(parallel [(set (match_dup 0) 1012 (minus:QHI (match_dup 1) (match_dup 2))) 1013 (clobber (reg:CC R_FLAGS))])] 1014 "" 1015 [(set_attr "type" "arith")]) 1016 1017 (define_insn "*sub<mode>3_insn<subst_arith>" 1018 [(set (match_operand:QHI 0 "register_operand" "=r") 1019 (minus:QHI (match_operand:QHI 1 "reg_or_0_operand" "rO") 1020 (match_operand:QHI 2 "register_operand" "r"))) 1021 (clobber (reg:CC R_FLAGS))] 1022 "reload_completed" 1023 "sub<s> %0,%r1,%2" 1024 [(set_attr "type" "arith")]) 1025 1026 (define_insn "*sub<mode>3_insn_set_carry" 1027 [(set (reg:CC R_FLAGS) 1028 (compare:CC (match_operand:QHI 1 "reg_or_0_operand" "r0") 1029 (match_operand:QHI 2 "register_operand" "r"))) 1030 (set (match_operand:QHI 0 "register_operand" "=r") 1031 (minus:QHI (match_dup 1) (match_dup 2)))] 1032 "reload_completed" 1033 "sub<s> %0,%r1,%2" 1034 [(set_attr "type" "arith")]) 1035 1036 (define_insn "*sub<mode>3_insn_set_overflow" 1037 [(set (reg:CCV R_FLAGS) 1038 (compare:CCV (minus:QHI (match_operand:QHI 1 "reg_or_0_operand" "r0") 1039 (match_operand:QHI 2 "register_operand" "r")) 1040 (unspec:QHI [(match_dup 1) (match_dup 2)] UNSPEC_SUBV))) 1041 (set (match_operand:QHI 0 "register_operand" "=r") 1042 (minus:QHI (match_dup 1) (match_dup 2)))] 1043 "reload_completed" 1044 "sub<s> %0,%r1,%2" 1045 [(set_attr "type" "arith")]) 1046 1047 (define_expand "subsi3" 1048 [(set (match_operand:SI 0 "register_operand" "") 1049 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "") 1050 (match_operand:SI 2 "add_operand" "")))] 1051 "") 1052 1053 (define_expand "subsi3_flags" 1054 [(parallel [(set (match_operand:SI 0 "register_operand" "") 1055 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "") 1056 (match_operand:SI 2 "add_operand" ""))) 1057 (clobber (reg:CC R_FLAGS))])] 1058 "reload_completed" 1059 "") 1060 1061 (define_insn_and_split "*subsi3_insn" 1062 [(set (match_operand:SI 0 "register_operand" "=r,r, r") 1063 (minus:SI (match_operand:SI 1 "reg_or_0_operand" " 0,rO,0") 1064 (match_operand:SI 2 "add_operand" " L,r, J")))] 1065 "ok_for_simple_arith_logic_operands (operands, SImode)" 1066 "#" 1067 "reload_completed" 1068 [(parallel [(set (match_dup 0) 1069 (minus:SI (match_dup 1) (match_dup 2))) 1070 (clobber (reg:CC R_FLAGS))])] 1071 "" 1072 [(set_attr "type" "arith")]) 1073 1074 ; Favour the subtraction of small negative constants, since they are 1075 ; expensive to load into a register. 1076 1077 (define_insn "*subsi3_insn<subst_arith>" 1078 [(set (match_operand:SI 0 "register_operand" "=r,r, r") 1079 (minus:SI (match_operand:SI 1 "reg_or_0_operand" " 0,rO,0") 1080 (match_operand:SI 2 "add_operand" " L,r, J"))) 1081 (clobber (reg:CC R_FLAGS))] 1082 "reload_completed" 1083 "@ 1084 addi %0,%n2 1085 sub.l %0,%r1,%2 1086 subi %0,%2" 1087 [(set_attr "type" "arith")]) 1088 1089 (define_insn "subsi3_insn_set_carry" 1090 [(set (reg:CC R_FLAGS) 1091 (compare:CC (match_operand:SI 1 "register_operand" "r,0") 1092 (match_operand:SI 2 "real_add_operand" "r,J"))) 1093 (set (match_operand:SI 0 "register_operand" "=r,r") 1094 (minus:SI (match_dup 1) (match_dup 2)))] 1095 "reload_completed" 1096 "@ 1097 sub.l %0,%r1,%2 1098 subi %0,%2" 1099 [(set_attr "type" "arith")]) 1100 1101 (define_insn "*subsi3_insn_set_overflow" 1102 [(set (reg:CCV R_FLAGS) 1103 (compare:CCV (minus:SI (match_operand:SI 1 "register_operand" "r,0") 1104 (match_operand:SI 2 "real_add_operand" "r,J")) 1105 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_SUBV))) 1106 (set (match_operand:SI 0 "register_operand" "=r,r") 1107 (minus:SI (match_dup 1) (match_dup 2)))] 1108 "reload_completed" 1109 "@ 1110 sub.l %0,%1,%2 1111 subi %0,%2" 1112 [(set_attr "type" "arith")]) 1113 1114 (define_expand "subdi3" 1115 [(set (match_operand:DI 0 "register_operand" "") 1116 (minus:DI (match_operand:DI 1 "register_operand" "") 1117 (match_operand:DI 2 "add_operand" "")))] 1118 "") 1119 1120 ; Disfavour the use of the sub.l because of the early clobber. 1121 1122 (define_insn_and_split "*subdi3_insn" 1123 [(set (match_operand:DI 0 "register_operand" "=r,r,&r") 1124 (minus:DI (match_operand:DI 1 "register_operand" " 0,0, r") 1125 (match_operand:DI 2 "add_operand" " L,J, r")))] 1126 "ok_for_simple_arith_logic_operands (operands, DImode)" 1127 "#" 1128 "reload_completed" 1129 [(const_int 0)] 1130 { 1131 visium_split_double_add (MINUS, operands[0], operands[1], operands[2]); 1132 DONE; 1133 } 1134 [(set_attr "type" "arith2")]) 1135 1136 ;; 1137 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1138 ;; 1139 ;; Integer Subtract with Carry 1140 ;; 1141 ;; Only SI mode is supported. 1142 ;; 1143 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1144 ;; 1145 1146 (define_insn "*neg_<scc_str><subst_arith>" 1147 [(set (match_operand:SI 0 "register_operand" "=r") 1148 (neg:SI (any_scc:SI (reg R_FLAGS) (const_int 0)))) 1149 (clobber (reg:CC R_FLAGS))] 1150 "reload_completed" 1151 "subc.l %0,r0,r0" 1152 [(set_attr "type" "arith")]) 1153 1154 (define_insn "*minus_<scc_str><subst_arith>" 1155 [(set (match_operand:SI 0 "register_operand" "=r") 1156 (minus:SI (match_operand:SI 1 "register_operand" "r") 1157 (any_scc:SI (reg R_FLAGS) (const_int 0)))) 1158 (clobber (reg:CC R_FLAGS))] 1159 "reload_completed" 1160 "subc.l %0,%1,r0" 1161 [(set_attr "type" "arith")]) 1162 1163 (define_insn "*minus_minus_sltu<subst_arith>" 1164 [(set (match_operand:SI 0 "register_operand" "=r") 1165 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO") 1166 (match_operand:SI 2 "register_operand" "r")) 1167 (ltu:SI (reg R_FLAGS) (const_int 0)))) 1168 (clobber (reg:CC R_FLAGS))] 1169 "reload_completed" 1170 "subc.l %0,%r1,%2" 1171 [(set_attr "type" "arith")]) 1172 1173 ;; 1174 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1175 ;; 1176 ;; Integer Negate 1177 ;; 1178 ;; Modes QI, HI, SI and DI are supported directly. 1179 ;; 1180 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1181 ;; 1182 1183 (define_expand "neg<mode>2" 1184 [(set (match_operand:I 0 "register_operand" "") 1185 (neg:I (match_operand:I 1 "register_operand" "")))] 1186 "") 1187 1188 (define_expand "unegv<mode>3" 1189 [(set (match_operand:I 0 "register_operand" "") 1190 (neg:I (match_operand:I 1 "register_operand" ""))) 1191 (set (pc) 1192 (if_then_else (ne (match_dup 0) (const_int 0)) 1193 (label_ref (match_operand 2 "")) 1194 (pc)))] 1195 "") 1196 1197 (define_expand "negv<mode>3" 1198 [(set (match_operand:I 0 "register_operand" "") 1199 (neg:I (match_operand:I 1 "register_operand" ""))) 1200 (set (pc) 1201 (if_then_else (ne (match_dup 0) 1202 (unspec:I [(match_dup 1)] UNSPEC_NEGV)) 1203 (label_ref (match_operand 2 "")) 1204 (pc)))] 1205 "") 1206 1207 (define_insn_and_split "*neg<mode>2_insn" 1208 [(set (match_operand:I 0 "register_operand" "=r") 1209 (neg:I (match_operand:I 1 "register_operand" "r")))] 1210 "ok_for_simple_arith_logic_operands (operands, <MODE>mode)" 1211 "#" 1212 "reload_completed" 1213 [(parallel [(set (match_dup 0) (neg:I (match_dup 1))) 1214 (clobber (reg:CC R_FLAGS))])] 1215 "" 1216 [(set_attr "type" "arith")]) 1217 1218 (define_insn "*neg<mode>2_insn<subst_arith>" 1219 [(set (match_operand:I 0 "register_operand" "=r") 1220 (neg:I (match_operand:I 1 "register_operand" "r"))) 1221 (clobber (reg:CC R_FLAGS))] 1222 "reload_completed" 1223 "sub<s> %0,r0,%1" 1224 [(set_attr "type" "arith")]) 1225 1226 (define_insn "neg<mode>2_insn_set_carry" 1227 [(set (reg:CCC R_FLAGS) 1228 (compare:CCC (not:I (neg:I (match_operand:I 1 "register_operand" "r"))) 1229 (const_int -1))) 1230 (set (match_operand:I 0 "register_operand" "=r") 1231 (neg:I (match_dup 1)))] 1232 "reload_completed" 1233 "sub<s> %0,r0,%1" 1234 [(set_attr "type" "arith")]) 1235 1236 (define_insn "*neg<mode>2_insn_set_overflow" 1237 [(set (reg:CCV R_FLAGS) 1238 (compare:CCV (neg:I (match_operand:I 1 "register_operand" "r")) 1239 (unspec:I [(match_dup 1)] UNSPEC_NEGV))) 1240 (set (match_operand:I 0 "register_operand" "=r") 1241 (neg:I (match_dup 1)))] 1242 "reload_completed" 1243 "sub<s> %0,r0,%1" 1244 [(set_attr "type" "arith")]) 1245 1246 (define_expand "negdi2" 1247 [(set (match_operand:DI 0 "register_operand" "") 1248 (neg:DI (match_operand:DI 1 "register_operand" "")))] 1249 "") 1250 1251 (define_insn_and_split "*negdi2_insn" 1252 [(set (match_operand:DI 0 "register_operand" "=&r") 1253 (neg:DI (match_operand:DI 1 "register_operand" "r")))] 1254 "ok_for_simple_arith_logic_operands (operands, DImode)" 1255 "#" 1256 "reload_completed" 1257 [(const_int 0)] 1258 { 1259 visium_split_double_add (MINUS, operands[0], const0_rtx, operands[1]); 1260 DONE; 1261 } 1262 [(set_attr "type" "arith2")]) 1263 1264 ;; 1265 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1266 ;; 1267 ;; Integer Multiply (non-widening and widening, signed and unsigned) 1268 ;; 1269 ;; Only SI mode is supported. 1270 ;; 1271 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1272 ;; 1273 1274 ; The mults and multu instructions clear MDC but we only pretend that they 1275 ; clobber it to keep things relatively simple. 1276 1277 (define_insn "mulsi3" 1278 [(set (match_operand:SI 0 "register_operand" "=b") 1279 (mult:SI (match_operand:SI 1 "register_operand" "%r") 1280 (match_operand:SI 2 "register_operand" "r"))) 1281 (clobber (reg:SI R_MDC))] 1282 "" 1283 "mults %1,%2" 1284 [(set_attr "type" "mul")]) 1285 1286 ; The names are mulsidi3 and umulsidi3 here. 1287 1288 (define_insn "<u>mulsidi3" 1289 [(set (match_operand:DI 0 "register_operand" "=b") 1290 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "%r")) 1291 (any_extend:DI (match_operand:SI 2 "register_operand" "r")))) 1292 (clobber (reg:SI R_MDC))] 1293 "" 1294 "mult<su> %1,%2" 1295 [(set_attr "type" "mul")]) 1296 1297 ; But they are smulsi3_highpart and umulsi3_highpart here. 1298 1299 (define_insn_and_split "<su>mulsi3_highpart" 1300 [(set (match_operand:SI 0 "register_operand" "=r") 1301 (truncate:SI 1302 (ashiftrt:DI 1303 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "%r")) 1304 (any_extend:DI (match_operand:SI 2 "register_operand" "r"))) 1305 (const_int 32)))) 1306 (clobber (reg:DI R_MDB)) 1307 (clobber (reg:SI R_MDC))] 1308 "" 1309 "#" 1310 "reload_completed" 1311 [(parallel [(set (reg:DI R_MDB) 1312 (mult:DI (any_extend:DI (match_dup 1)) 1313 (any_extend:DI (match_dup 2)))) 1314 (clobber (reg:SI R_MDC))]) 1315 (set (match_dup 0) (unspec:SI [(reg:DI R_MDB)] UNSPEC_MDBHI))] 1316 "" 1317 [(set_attr "type" "multi")]) 1318 1319 ;; 1320 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1321 ;; 1322 ;; Integer divide and modulus (signed and unsigned) 1323 ;; 1324 ;; Only SI mode is supported. 1325 ;; 1326 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1327 ;; 1328 1329 (define_insn "*divmodsi4_insn" 1330 [(set (match_operand:SI 0 "register_operand" "=b") 1331 (div:SI (match_operand:SI 1 "register_operand" "0") 1332 (match_operand:SI 2 "register_operand" "r"))) 1333 (set (reg:SI R_MDC) (mod:SI (match_dup 1) (match_dup 2)))] 1334 "" 1335 "divs %2" 1336 [(set_attr "type" "div")]) 1337 1338 (define_insn_and_split "divmodsi4" 1339 [(set (match_operand:SI 0 "register_operand" "=b") 1340 (div:SI (match_operand:SI 1 "register_operand" "0") 1341 (match_operand:SI 2 "register_operand" "r"))) 1342 (set (match_operand:SI 3 "register_operand" "=r") 1343 (mod:SI (match_dup 1) (match_dup 2))) 1344 (clobber (reg:SI R_MDC))] 1345 "" 1346 "#" 1347 "reload_completed" 1348 [(parallel [(set (match_dup 0) (div:SI (match_dup 1) (match_dup 2))) 1349 (set (reg:SI R_MDC) (mod:SI (match_dup 1) (match_dup 2)))]) 1350 (set (match_dup 3) (reg:SI R_MDC))] 1351 "" 1352 [(set_attr "type" "multi")]) 1353 1354 (define_insn "*udivmodsi4_insn" 1355 [(set (match_operand:SI 0 "register_operand" "=b") 1356 (udiv:SI (match_operand:SI 1 "register_operand" "0") 1357 (match_operand:SI 2 "register_operand" "r"))) 1358 (set (reg:SI R_MDC) (umod:SI (match_dup 1) (match_dup 2)))] 1359 "" 1360 "divu %2" 1361 [(set_attr "type" "div")]) 1362 1363 (define_insn_and_split "udivmodsi4" 1364 [(set (match_operand:SI 0 "register_operand" "=b") 1365 (udiv:SI (match_operand:SI 1 "register_operand" "0") 1366 (match_operand:SI 2 "register_operand" "r"))) 1367 (set (match_operand:SI 3 "register_operand" "=r") 1368 (umod:SI (match_dup 1) (match_dup 2))) 1369 (clobber (reg:SI R_MDC))] 1370 "" 1371 "#" 1372 "reload_completed" 1373 [(parallel [(set (match_dup 0) (udiv:SI (match_dup 1) (match_dup 2))) 1374 (set (reg:SI R_MDC) (umod:SI (match_dup 1) (match_dup 2)))]) 1375 (set (match_dup 3) (reg:SI R_MDC))] 1376 "" 1377 [(set_attr "type" "multi")]) 1378 1379 ; FIXME. How do we persuade the compiler to use 64/32 bit divides directly ? 1380 1381 (define_insn "*divds" 1382 [(set (reg:DI R_MDB) 1383 (div:DI (reg:DI R_MDB) (sign_extend:DI (match_operand:SI 0 "register_operand" "r")))) 1384 (set (reg:SI R_MDC) (truncate:SI (mod:DI (reg:DI R_MDB) (sign_extend:DI (match_dup 0)))))] 1385 "" 1386 "divds %0" 1387 [(set_attr "type" "divd")]) 1388 1389 (define_insn "*divdu" 1390 [(set (reg:DI R_MDB) 1391 (udiv:DI (reg:DI R_MDB) (zero_extend:DI (match_operand:SI 0 "register_operand" "r")))) 1392 (set (reg:SI R_MDC) (truncate:SI (umod:DI (reg:DI R_MDB) (zero_extend:DI (match_dup 0)))))] 1393 "" 1394 "divdu %0" 1395 [(set_attr "type" "divd")]) 1396 1397 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1398 ;; 1399 ;; Bitwise Logical AND 1400 ;; 1401 ;; Modes QI, HI and SI are supported directly. 1402 ;; 1403 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1404 ;; 1405 1406 (define_expand "and<mode>3" 1407 [(set (match_operand:I 0 "register_operand" "") 1408 (and:I (match_operand:I 1 "register_operand" "") 1409 (match_operand:I 2 "register_operand" "")))] 1410 "") 1411 1412 (define_insn_and_split "*and<mode>3_insn" 1413 [(set (match_operand:I 0 "register_operand" "=r") 1414 (and:I (match_operand:I 1 "register_operand" "%r") 1415 (match_operand:I 2 "register_operand" "r")))] 1416 "ok_for_simple_arith_logic_operands (operands, <MODE>mode)" 1417 "#" 1418 "reload_completed" 1419 [(parallel [(set (match_dup 0) 1420 (and:I (match_dup 1) (match_dup 2))) 1421 (clobber (reg:CC R_FLAGS))])] 1422 "" 1423 [(set_attr "type" "logic")]) 1424 1425 (define_insn "*and<mode>3_insn<subst_logic>" 1426 [(set (match_operand:I 0 "register_operand" "=r") 1427 (and:I (match_operand:I 1 "register_operand" "%r") 1428 (match_operand:I 2 "register_operand" "r"))) 1429 (clobber (reg:CC R_FLAGS))] 1430 "reload_completed" 1431 "and<s> %0,%1,%2" 1432 [(set_attr "type" "logic")]) 1433 1434 ;; 1435 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1436 ;; 1437 ;; Bitwise Inclusive Logical OR 1438 ;; 1439 ;; Modes QI, HI and SI are supported directly. 1440 ;; 1441 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1442 ;; 1443 1444 (define_expand "ior<mode>3" 1445 [(set (match_operand:I 0 "register_operand" "") 1446 (ior:I (match_operand:I 1 "register_operand" "") 1447 (match_operand:I 2 "register_operand" "")))] 1448 "") 1449 1450 (define_insn_and_split "*ior<mode>3_insn" 1451 [(set (match_operand:I 0 "register_operand" "=r") 1452 (ior:I (match_operand:I 1 "register_operand" "%r") 1453 (match_operand:I 2 "register_operand" "r")))] 1454 "ok_for_simple_arith_logic_operands (operands, <MODE>mode)" 1455 "#" 1456 "reload_completed" 1457 [(parallel [(set (match_dup 0) 1458 (ior:I (match_dup 1) (match_dup 2))) 1459 (clobber (reg:CC R_FLAGS))])] 1460 "" 1461 [(set_attr "type" "logic")]) 1462 1463 (define_insn "*ior<mode>3_insn<subst_logic>" 1464 [(set (match_operand:I 0 "register_operand" "=r") 1465 (ior:I (match_operand:I 1 "register_operand" "%r") 1466 (match_operand:I 2 "register_operand" "r"))) 1467 (clobber (reg:CC R_FLAGS))] 1468 "reload_completed" 1469 "or<s> %0,%1,%2" 1470 [(set_attr "type" "logic")]) 1471 1472 ;; 1473 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1474 ;; 1475 ;; Bitwise Exclusive Logical OR 1476 ;; 1477 ;; Modes QI, HI and SI are supported directly. 1478 ;; 1479 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1480 ;; 1481 1482 (define_expand "xor<mode>3" 1483 [(set (match_operand:I 0 "register_operand" "") 1484 (xor:I (match_operand:I 1 "register_operand" "") 1485 (match_operand:I 2 "register_operand" "")))] 1486 "") 1487 1488 (define_insn_and_split "*xor<mode>3_insn" 1489 [(set (match_operand:I 0 "register_operand" "=r") 1490 (xor:I (match_operand:I 1 "register_operand" "%r") 1491 (match_operand:I 2 "register_operand" "r")))] 1492 "ok_for_simple_arith_logic_operands (operands, <MODE>mode)" 1493 "#" 1494 "reload_completed" 1495 [(parallel [(set (match_dup 0) 1496 (xor:I (match_dup 1) (match_dup 2))) 1497 (clobber (reg:CC R_FLAGS))])] 1498 "" 1499 [(set_attr "type" "logic")]) 1500 1501 (define_insn "*xor<mode>3_insn<subst_logic>" 1502 [(set (match_operand:I 0 "register_operand" "=r") 1503 (xor:I (match_operand:I 1 "register_operand" "%r") 1504 (match_operand:I 2 "register_operand" "r"))) 1505 (clobber (reg:CC R_FLAGS))] 1506 "reload_completed" 1507 "xor<s> %0,%1,%2" 1508 [(set_attr "type" "logic")]) 1509 1510 ;; 1511 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1512 ;; 1513 ;; Bitwise Logical NOT 1514 ;; 1515 ;; Modes QI, HI and SI are supported directly. 1516 ;; 1517 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1518 ;; 1519 1520 (define_expand "one_cmpl<mode>2" 1521 [(set (match_operand:I 0 "register_operand" "") 1522 (not:I (match_operand:I 1 "reg_or_0_operand" "")))] 1523 "") 1524 1525 (define_insn_and_split "*one_cmpl<mode>2_insn" 1526 [(set (match_operand:I 0 "register_operand" "=r") 1527 (not:I (match_operand:I 1 "reg_or_0_operand" "rO")))] 1528 "ok_for_simple_arith_logic_operands (operands, <MODE>mode)" 1529 "#" 1530 "reload_completed" 1531 [(parallel [(set (match_dup 0) (not:I (match_dup 1))) 1532 (clobber (reg:CC R_FLAGS))])] 1533 "" 1534 [(set_attr "type" "logic")]) 1535 1536 (define_insn "*one_cmpl<mode>2_insn<subst_logic>" 1537 [(set (match_operand:I 0 "register_operand" "=r") 1538 (not:I (match_operand:I 1 "reg_or_0_operand" "rO"))) 1539 (clobber (reg:CC R_FLAGS))] 1540 "reload_completed" 1541 "not<s> %0,%r1" 1542 [(set_attr "type" "logic")]) 1543 1544 ;; 1545 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1546 ;; 1547 ;; Arithmetic Shift Left 1548 ;; 1549 ;; Modes QI, HI, SI and DI are supported directly. 1550 ;; 1551 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1552 ;; 1553 1554 (define_expand "ashl<mode>3" 1555 [(set (match_operand:I 0 "register_operand" "") 1556 (ashift:I (match_operand:I 1 "register_operand" "") 1557 (match_operand:QI 2 "reg_or_shift_operand" "")))] 1558 "") 1559 1560 (define_insn_and_split "*ashl<mode>3_insn" 1561 [(set (match_operand:I 0 "register_operand" "=r,r") 1562 (ashift:I (match_operand:I 1 "register_operand" "r,r") 1563 (match_operand:QI 2 "reg_or_shift_operand" "r,K")))] 1564 "ok_for_simple_arith_logic_operands (operands, <MODE>mode)" 1565 "#" 1566 "reload_completed" 1567 [(parallel [(set (match_dup 0) 1568 (ashift:I (match_dup 1) (match_dup 2))) 1569 (clobber (reg:CC R_FLAGS))])] 1570 "" 1571 [(set_attr "type" "arith")]) 1572 1573 (define_insn "*ashl<mode>3_insn<subst_arith>" 1574 [(set (match_operand:I 0 "register_operand" "=r,r") 1575 (ashift:I (match_operand:I 1 "register_operand" "r,r") 1576 (match_operand:QI 2 "reg_or_shift_operand" "r,K"))) 1577 (clobber (reg:CC R_FLAGS))] 1578 "reload_completed" 1579 "asl<s> %0,%1,%2" 1580 [(set_attr "type" "arith")]) 1581 1582 (define_insn "ashldi3" 1583 [(set (match_operand:DI 0 "register_operand" "=b,r") 1584 (ashift:DI (match_operand:DI 1 "register_operand" "0,r") 1585 (match_operand:QI 2 "reg_or_32_operand" "r,P"))) 1586 (clobber (reg:SI R_MDC))] 1587 "" 1588 "@ 1589 asld %2 1590 #" 1591 [(set_attr "type" "shiftdi,multi")]) 1592 1593 (define_split 1594 [(set (match_operand:DI 0 "gpc_reg_operand" "") 1595 (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") 1596 (const_int 32))) 1597 (clobber (reg:SI R_MDC))] 1598 "reload_completed" 1599 [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 4)) 1600 (set (subreg:SI (match_dup 0) 4) (const_int 0))] 1601 "") 1602 1603 ;; 1604 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1605 ;; 1606 ;; Arithmetic Shift Right 1607 ;; 1608 ;; Modes QI, HI, SI and DI are supported directly. 1609 ;; 1610 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1611 ;; 1612 1613 (define_expand "ashr<mode>3" 1614 [(set (match_operand:I 0 "register_operand" "") 1615 (ashiftrt:I (match_operand:I 1 "register_operand" "") 1616 (match_operand:QI 2 "reg_or_shift_operand" "")))] 1617 "") 1618 1619 (define_insn_and_split "*ashr<mode>3_insn" 1620 [(set (match_operand:I 0 "register_operand" "=r,r") 1621 (ashiftrt:I (match_operand:I 1 "register_operand" "r,r") 1622 (match_operand:QI 2 "reg_or_shift_operand" "r,K")))] 1623 "ok_for_simple_arith_logic_operands (operands, <MODE>mode)" 1624 "#" 1625 "reload_completed" 1626 [(parallel [(set (match_dup 0) 1627 (ashiftrt:I (match_dup 1) (match_dup 2))) 1628 (clobber (reg:CC R_FLAGS))])] 1629 "" 1630 [(set_attr "type" "logic")]) 1631 1632 (define_insn "*ashr<mode>3_insn<subst_logic>" 1633 [(set (match_operand:I 0 "register_operand" "=r,r") 1634 (ashiftrt:I (match_operand:I 1 "register_operand" "r,r") 1635 (match_operand:QI 2 "reg_or_shift_operand" "r,K"))) 1636 (clobber (reg:CC R_FLAGS))] 1637 "reload_completed" 1638 "asr<s> %0,%1,%2" 1639 [(set_attr "type" "logic")]) 1640 1641 (define_insn "ashrdi3" 1642 [(set (match_operand:DI 0 "register_operand" "=b,r") 1643 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,r") 1644 (match_operand:QI 2 "reg_or_32_operand" "r,P"))) 1645 (clobber (reg:SI R_MDC))] 1646 "" 1647 "@ 1648 asrd %2 1649 #" 1650 [(set_attr "type" "shiftdi,multi")]) 1651 1652 (define_split 1653 [(set (match_operand:DI 0 "gpc_reg_operand" "") 1654 (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "") 1655 (const_int 32))) 1656 (clobber (reg:SI R_MDC))] 1657 "reload_completed" 1658 [(set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 0)) 1659 (parallel [(set (subreg:SI (match_dup 0) 0) 1660 (ashiftrt:SI (subreg:SI (match_dup 1) 0) (const_int 31))) 1661 (clobber (reg:CC R_FLAGS))])] 1662 "") 1663 1664 ;; 1665 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1666 ;; 1667 ;; Logical Shift Right 1668 ;; 1669 ;; Modes QI, HI, SI and DI are supported directly. 1670 ;; 1671 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1672 ;; 1673 1674 (define_expand "lshr<mode>3" 1675 [(set (match_operand:I 0 "register_operand" "") 1676 (lshiftrt:I (match_operand:I 1 "register_operand" "") 1677 (match_operand:QI 2 "reg_or_shift_operand" "")))] 1678 "") 1679 1680 (define_insn_and_split "*lshr<mode>3_insn" 1681 [(set (match_operand:I 0 "register_operand" "=r,r") 1682 (lshiftrt:I (match_operand:I 1 "register_operand" "r,r") 1683 (match_operand:QI 2 "reg_or_shift_operand" "r,K")))] 1684 "ok_for_simple_arith_logic_operands (operands, <MODE>mode)" 1685 "#" 1686 "reload_completed" 1687 [(parallel [(set (match_dup 0) 1688 (lshiftrt:I (match_dup 1) (match_dup 2))) 1689 (clobber (reg:CC R_FLAGS))])] 1690 "" 1691 [(set_attr "type" "logic")]) 1692 1693 (define_insn "*lshr<mode>3_insn<subst_logic>" 1694 [(set (match_operand:I 0 "register_operand" "=r,r") 1695 (lshiftrt:I (match_operand:I 1 "register_operand" "r,r") 1696 (match_operand:QI 2 "reg_or_shift_operand" "r,K"))) 1697 (clobber (reg:CC R_FLAGS))] 1698 "reload_completed" 1699 "lsr<s> %0,%1,%2" 1700 [(set_attr "type" "logic")]) 1701 1702 (define_insn "lshrdi3" 1703 [(set (match_operand:DI 0 "register_operand" "=b,r") 1704 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,r") 1705 (match_operand:QI 2 "reg_or_32_operand" "r,P"))) 1706 (clobber (reg:SI R_MDC))] 1707 "" 1708 "@ 1709 lsrd %2 1710 #" 1711 [(set_attr "type" "shiftdi,multi")]) 1712 1713 (define_split 1714 [(set (match_operand:DI 0 "gpc_reg_operand" "") 1715 (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "") 1716 (const_int 32))) 1717 (clobber (reg:SI R_MDC))] 1718 "reload_completed" 1719 [(set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 0)) 1720 (set (subreg:SI (match_dup 0) 0) (const_int 0))] 1721 "") 1722 1723 ;; 1724 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1725 ;; 1726 ;; Truncate 1727 ;; 1728 ;; Truncations among modes QI, HI, SI and DI are supported directly. 1729 ;; 1730 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1731 ;; 1732 1733 (define_expand "trunchiqi2" 1734 [(set (match_operand:QI 0 "register_operand" "") 1735 (truncate:QI (match_operand:HI 1 "register_operand" "")))] 1736 "") 1737 1738 (define_insn_and_split "*trunchiqi2_insn" 1739 [(set (match_operand:QI 0 "register_operand" "=r") 1740 (truncate:QI (match_operand:HI 1 "register_operand" "r")))] 1741 "ok_for_simple_arith_logic_operands (operands, QImode)" 1742 "#" 1743 "reload_completed" 1744 [(parallel [(set (match_dup 0) (truncate:QI (match_dup 1))) 1745 (clobber (reg:CC R_FLAGS))])] 1746 "" 1747 [(set_attr "type" "logic")]) 1748 1749 (define_insn "*trunchiqi2_insn<subst_logic>" 1750 [(set (match_operand:QI 0 "register_operand" "=r") 1751 (truncate:QI (match_operand:HI 1 "register_operand" "r"))) 1752 (clobber (reg:CC R_FLAGS))] 1753 "reload_completed" 1754 "move.b %0,%1" 1755 [(set_attr "type" "logic")]) 1756 1757 (define_expand "truncsihi2" 1758 [(set (match_operand:HI 0 "register_operand" "") 1759 (truncate:HI (match_operand:SI 1 "register_operand" "")))] 1760 "") 1761 1762 (define_insn_and_split "*truncsihi2_insn" 1763 [(set (match_operand:HI 0 "register_operand" "=r") 1764 (truncate:HI (match_operand:SI 1 "register_operand" "r")))] 1765 "ok_for_simple_arith_logic_operands (operands, HImode)" 1766 "#" 1767 "reload_completed" 1768 [(parallel [(set (match_dup 0) (truncate:HI (match_dup 1))) 1769 (clobber (reg:CC R_FLAGS))])] 1770 "" 1771 [(set_attr "type" "logic")]) 1772 1773 (define_insn "*truncsihi2_insn<subst_logic>" 1774 [(set (match_operand:HI 0 "register_operand" "=r") 1775 (truncate:HI (match_operand:SI 1 "register_operand" "r"))) 1776 (clobber (reg:CC R_FLAGS))] 1777 "reload_completed" 1778 "move.w %0,%1" 1779 [(set_attr "type" "logic")]) 1780 1781 (define_expand "truncdisi2" 1782 [(set (match_operand:SI 0 "register_operand" "") 1783 (truncate:SI (match_operand:DI 1 "register_operand" "")))] 1784 "") 1785 1786 (define_insn_and_split "*truncdisi2_insn" 1787 [(set (match_operand:SI 0 "register_operand" "=r") 1788 (truncate:SI (match_operand:DI 1 "register_operand" "r")))] 1789 "ok_for_simple_arith_logic_operands (operands, SImode)" 1790 "#" 1791 "reload_completed" 1792 [(parallel [(set (match_dup 0) (truncate:SI (match_dup 1))) 1793 (clobber (reg:CC R_FLAGS))])] 1794 "" 1795 [(set_attr "type" "logic")]) 1796 1797 (define_insn "*truncdisi2_insn<subst_logic>" 1798 [(set (match_operand:SI 0 "register_operand" "=r") 1799 (truncate:SI (match_operand:DI 1 "register_operand" "r"))) 1800 (clobber (reg:CC R_FLAGS))] 1801 "reload_completed" 1802 "move.l %0,%d1" 1803 [(set_attr "type" "logic")]) 1804 1805 ;; 1806 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1807 ;; 1808 ;; Sign-extend 1809 ;; 1810 ;; Sign-extensions among modes QI, HI, SI and DI are supported directly. 1811 ;; 1812 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1813 ;; 1814 1815 (define_expand "extendqihi2" 1816 [(set (match_operand:HI 0 "register_operand" "") 1817 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))] 1818 "") 1819 1820 (define_insn_and_split "*extendqihi2_insn" 1821 [(set (match_operand:HI 0 "register_operand" "=r") 1822 (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))] 1823 "ok_for_simple_arith_logic_operands (operands, HImode)" 1824 "#" 1825 "reload_completed" 1826 [(parallel [(set (match_dup 0) (sign_extend:HI (match_dup 1))) 1827 (clobber (reg:CC R_FLAGS))])] 1828 "" 1829 [(set_attr "type" "logic")]) 1830 1831 (define_insn "*extendqihi2_insn<subst_logic>" 1832 [(set (match_operand:HI 0 "register_operand" "=r") 1833 (sign_extend:HI (match_operand:QI 1 "register_operand" "r"))) 1834 (clobber (reg:CC R_FLAGS))] 1835 "reload_completed" 1836 "extb.w %0,%1" 1837 [(set_attr "type" "logic")]) 1838 1839 (define_expand "extendqisi2" 1840 [(set (match_operand:SI 0 "register_operand" "") 1841 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))] 1842 "") 1843 1844 (define_insn_and_split "*extendqisi2_insn" 1845 [(set (match_operand:SI 0 "register_operand" "=r") 1846 (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))] 1847 "ok_for_simple_arith_logic_operands (operands, SImode)" 1848 "#" 1849 "reload_completed" 1850 [(parallel [(set (match_dup 0) (sign_extend:SI (match_dup 1))) 1851 (clobber (reg:CC R_FLAGS))])] 1852 "" 1853 [(set_attr "type" "logic")]) 1854 1855 (define_insn "*extendqisi2_insn<subst_logic>" 1856 [(set (match_operand:SI 0 "register_operand" "=r") 1857 (sign_extend:SI (match_operand:QI 1 "register_operand" "r"))) 1858 (clobber (reg:CC R_FLAGS))] 1859 "reload_completed" 1860 "extb.l %0,%1" 1861 [(set_attr "type" "logic")]) 1862 1863 (define_expand "extendhisi2" 1864 [(set (match_operand:SI 0 "register_operand" "") 1865 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))] 1866 "") 1867 1868 (define_insn_and_split "*extendhisi2_insn" 1869 [(set (match_operand:SI 0 "register_operand" "=r") 1870 (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))] 1871 "ok_for_simple_arith_logic_operands (operands, SImode)" 1872 "#" 1873 "reload_completed" 1874 [(parallel [(set (match_operand:SI 0 "register_operand" "") 1875 (sign_extend:SI (match_operand:HI 1 "register_operand" ""))) 1876 (clobber (reg:CC R_FLAGS))])] 1877 "" 1878 [(set_attr "type" "logic")]) 1879 1880 (define_insn "*extendhisi2_insn<subst_logic>" 1881 [(set (match_operand:SI 0 "register_operand" "=r") 1882 (sign_extend:SI (match_operand:HI 1 "register_operand" "r"))) 1883 (clobber (reg:CC R_FLAGS))] 1884 "reload_completed" 1885 "extw.l %0,%1" 1886 [(set_attr "type" "logic")]) 1887 1888 (define_expand "extendsidi2" 1889 [(set (match_operand:DI 0 "register_operand" "") 1890 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))] 1891 "") 1892 1893 (define_insn_and_split "*extendsidi2_insn" 1894 [(set (match_operand:DI 0 "register_operand" "=r") 1895 (sign_extend:DI (match_operand:SI 1 "register_operand" "r")))] 1896 "ok_for_simple_arith_logic_operands (operands, DImode)" 1897 "#" 1898 "reload_completed" 1899 [(parallel [(set (match_dup 3) (match_dup 1)) 1900 (clobber (reg:CC R_FLAGS))]) 1901 (parallel [(set (match_dup 2) 1902 (ashiftrt:SI (match_dup 1) (const_int 31))) 1903 (clobber (reg:CC R_FLAGS))])] 1904 { 1905 operands[2] = operand_subword (operands[0], 0, 0, DImode); 1906 operands[3] = operand_subword (operands[0], 1, 0, DImode); 1907 } 1908 [(set_attr "type" "multi")]) 1909 1910 ;; 1911 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1912 ;; 1913 ;; Zero-extend 1914 ;; 1915 ;; Zero-extensions among modes QI, HI, SI and DI are supported directly. 1916 ;; 1917 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1918 ;; 1919 1920 ; QI is zero-extended to wider modes by shifting left and then performing 1921 ; a logical shift right to insert the zeroes. This avoids the need to use 1922 ; another register. 1923 1924 (define_expand "zero_extendqihi2" 1925 [(set (match_operand:HI 0 "register_operand" "") 1926 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))] 1927 "") 1928 1929 (define_insn_and_split "*zero_extendqihi2_insn" 1930 [(set (match_operand:HI 0 "register_operand" "=r") 1931 (zero_extend:HI (match_operand:QI 1 "register_operand" "r")))] 1932 "ok_for_simple_arith_logic_operands (operands, HImode)" 1933 "#" 1934 "reload_completed" 1935 [(parallel [(set (match_dup 0) 1936 (ashift:HI (match_dup 2) (const_int 8))) 1937 (clobber (reg:CC R_FLAGS))]) 1938 (parallel [(set (match_dup 0) 1939 (lshiftrt:HI (match_dup 0) (const_int 8))) 1940 (clobber (reg:CC R_FLAGS))])] 1941 { 1942 operands[2] = gen_rtx_SUBREG (HImode, operands[1], 0); 1943 } 1944 [(set_attr "type" "multi")]) 1945 1946 (define_expand "zero_extendqisi2" 1947 [(set (match_operand:SI 0 "register_operand" "") 1948 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))] 1949 "") 1950 1951 (define_insn_and_split "*zero_extendqisi2_insn" 1952 [(set (match_operand:SI 0 "register_operand" "=r") 1953 (zero_extend:SI (match_operand:QI 1 "register_operand" "r")))] 1954 "ok_for_simple_arith_logic_operands (operands, SImode)" 1955 "#" 1956 "reload_completed" 1957 [(parallel [(set (match_dup 0) 1958 (ashift:SI (match_dup 2) (const_int 24))) 1959 (clobber (reg:CC R_FLAGS))]) 1960 (parallel [(set (match_dup 0) 1961 (lshiftrt:SI (match_dup 0) (const_int 24))) 1962 (clobber (reg:CC R_FLAGS))])] 1963 { 1964 operands[2] = gen_rtx_SUBREG (SImode, operands[1], 0); 1965 } 1966 [(set_attr "type" "multi")]) 1967 1968 (define_insn "zero_extendhisi2" 1969 [(set (match_operand:SI 0 "register_operand" "=r") 1970 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))] 1971 "" 1972 "moviu %0,0" 1973 [(set_attr "type" "imm_reg")]) 1974 1975 (define_expand "zero_extendsidi2" 1976 [(set (match_operand:DI 0 "register_operand" "") 1977 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))] 1978 "") 1979 1980 (define_insn_and_split "*zero_extendsidi2_insn" 1981 [(set (match_operand:DI 0 "register_operand" "=r") 1982 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))] 1983 "ok_for_simple_arith_logic_operands (operands, DImode)" 1984 "#" 1985 "reload_completed" 1986 [(parallel [(set (match_dup 3) (match_dup 1)) 1987 (clobber (reg:CC R_FLAGS))]) 1988 (set (match_dup 2) (const_int 0))] 1989 { 1990 operands[2] = operand_subword (operands[0], 0, 0, DImode); 1991 operands[3] = operand_subword (operands[0], 1, 0, DImode); 1992 } 1993 [(set_attr "type" "multi")]) 1994 1995 ;; 1996 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1997 ;; 1998 ;; Bit Test 1999 ;; 2000 ;; Only SI mode is supported directly. 2001 ;; 2002 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2003 ;; 2004 2005 ; BITS_BIG_ENDIAN is defined to 1 so operand #1 counts from the MSB. 2006 2007 (define_insn "*btst<mode>" 2008 [(set (reg:CCC R_FLAGS) 2009 (compare:CCC (zero_extract:I 2010 (match_operand:I 0 "register_operand" "r") 2011 (const_int 1) 2012 (match_operand:QI 1 "const_shift_operand" "K")) 2013 (const_int 0)))] 2014 "reload_completed" 2015 "lsr<s> r0,%0,<b>-%1" 2016 [(set_attr "type" "logic")]) 2017 2018 ;; 2019 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2020 ;; 2021 ;; Integer overflow tests 2022 ;; 2023 ;; Modes QI, HI and SI are supported directly. 2024 ;; 2025 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2026 ;; 2027 2028 (define_insn "*addv_tst<mode>" 2029 [(set (reg:CCV R_FLAGS) 2030 (compare:CCV (match_operand:I 0 "register_operand" "r") 2031 (unspec:I [(match_operand:I 1 "register_operand" "%r") 2032 (match_operand:I 2 "register_operand" "r")] 2033 UNSPEC_ADDV)))] 2034 "reload_completed" 2035 "add<s> r0,%1,%2" 2036 [(set_attr "type" "arith")]) 2037 2038 (define_insn "*subv_tst<mode>" 2039 [(set (reg:CCV R_FLAGS) 2040 (compare:CCV (match_operand:I 0 "register_operand" "r") 2041 (unspec:I [(match_operand:I 1 "reg_or_0_operand" "rO") 2042 (match_operand:I 2 "register_operand" "r")] 2043 UNSPEC_SUBV)))] 2044 "reload_completed" 2045 "sub<s> r0,%r1,%2" 2046 [(set_attr "type" "arith")]) 2047 2048 (define_insn "*negv_tst<mode>" 2049 [(set (reg:CCV R_FLAGS) 2050 (compare:CCV (match_operand:I 0 "register_operand" "r") 2051 (unspec:I [(match_operand:I 1 "register_operand" "r")] 2052 UNSPEC_NEGV)))] 2053 "reload_completed" 2054 "sub<s> r0,r0,%1" 2055 [(set_attr "type" "arith")]) 2056 2057 ;; 2058 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2059 ;; 2060 ;; Integer comparisons 2061 ;; 2062 ;; Modes QI, HI and SI are supported directly. 2063 ;; 2064 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2065 ;; 2066 2067 (define_insn "*cmp<mode>" 2068 [(set (reg:CC R_FLAGS) 2069 (compare:CC (match_operand:I 0 "register_operand" "r") 2070 (match_operand:I 1 "reg_or_0_operand" "rO")))] 2071 "reload_completed" 2072 "cmp<s> %0,%r1" 2073 [(set_attr "type" "cmp")]) 2074 2075 (define_insn "*cmp<mode>_sne" 2076 [(set (reg:CCC R_FLAGS) 2077 (compare:CCC (not:I (match_operand:I 0 "register_operand" "r")) 2078 (const_int -1)))] 2079 "reload_completed" 2080 "cmp<s> r0,%0" 2081 [(set_attr "type" "cmp")]) 2082 2083 ;; 2084 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2085 ;; 2086 ;; Single float operations 2087 ;; 2088 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2089 ;; 2090 2091 (define_insn "addsf3" 2092 [(set (match_operand:SF 0 "fp_reg_operand" "=f") 2093 (plus:SF (match_operand:SF 1 "fp_reg_operand" "%f") 2094 (match_operand:SF 2 "fp_reg_operand" "f")))] 2095 "TARGET_FPU" 2096 "fadd %0,%1,%2" 2097 [(set_attr "type" "fp")]) 2098 2099 (define_insn "subsf3" 2100 [(set (match_operand:SF 0 "fp_reg_operand" "=f") 2101 (minus:SF (match_operand:SF 1 "fp_reg_operand" "f") 2102 (match_operand:SF 2 "fp_reg_operand" "f")))] 2103 "TARGET_FPU" 2104 "fsub %0,%1,%2" 2105 [(set_attr "type" "fp")]) 2106 2107 (define_insn "mulsf3" 2108 [(set (match_operand:SF 0 "fp_reg_operand" "=f") 2109 (mult:SF (match_operand:SF 1 "fp_reg_operand" "%f") 2110 (match_operand:SF 2 "fp_reg_operand" "f")))] 2111 "TARGET_FPU" 2112 "fmult %0,%1,%2" 2113 [(set_attr "type" "fp")]) 2114 2115 (define_insn "divsf3" 2116 [(set (match_operand:SF 0 "fp_reg_operand" "=f") 2117 (div:SF (match_operand:SF 1 "fp_reg_operand" "f") 2118 (match_operand:SF 2 "fp_reg_operand" "f")))] 2119 "TARGET_FPU" 2120 "fdiv %0,%1,%2" 2121 [(set_attr "type" "fdiv")]) 2122 2123 (define_insn "sqrtsf2" 2124 [(set (match_operand:SF 0 "fp_reg_operand" "=f") 2125 (sqrt:SF (match_operand:SF 1 "fp_reg_operand" "f")))] 2126 "TARGET_FPU" 2127 "fsqrt %0,%1" 2128 [(set_attr "type" "fsqrt")]) 2129 2130 (define_insn "negsf2" 2131 [(set (match_operand:SF 0 "fp_reg_operand" "=f") 2132 (neg:SF (match_operand:SF 1 "fp_reg_operand" "f")))] 2133 "TARGET_FPU" 2134 "fneg %0,%1" 2135 [(set_attr "type" "fmove")]) 2136 2137 (define_insn "abssf2" 2138 [(set (match_operand:SF 0 "fp_reg_operand" "=f") 2139 (abs:SF (match_operand:SF 1 "fp_reg_operand" "f")))] 2140 "TARGET_FPU" 2141 "fabs %0,%1" 2142 [(set_attr "type" "fmove")]) 2143 2144 (define_expand "copysignsf3" 2145 [(match_operand:SF 0 "register_operand" "") 2146 (match_operand:SF 1 "nonmemory_operand" "") 2147 (match_operand:SF 2 "register_operand" "")] 2148 "TARGET_FPU && !TARGET_FPU_IEEE" 2149 { 2150 visium_expand_copysign (operands, SFmode); 2151 DONE; 2152 }) 2153 2154 ;; 2155 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2156 ;; 2157 ;; Single float <-> single integer conversions for !TARGET_FPU_IEEE 2158 ;; 2159 ;; An FMOVE instruction converts a signalling NaN (zero high order bit of the 2160 ;; mantissa) to a quiet NaN (-1). This is acceptable when the data to be 2161 ;; moved is in fact a floating-point number, but to avoid nasty surprises 2162 ;; integers must in general be kept out of the floating-point registers. 2163 ;; TARGET_HARD_REGNO_MODE_OK thus only allows SFmode in these registers. 2164 ;; However, since FTOI and ITOF use floating-point registers for both their 2165 ;; inputs and outputs, to use these instructions integers must transiently 2166 ;; occupy such registers. To disguise this from the compiler, UNSPECs are 2167 ;; used for floating-point operations on integers and floating from general 2168 ;; register to floating-point register and fixing in the reverse direction 2169 ;; are only split into the individual UNSPEC operations after reload. 2170 ;; 2171 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2172 ;; 2173 2174 (define_insn "*fload_no_ieee" 2175 [(set (match_operand:SF 0 "fp_reg_operand" "=f") 2176 (unspec:SF [(match_operand:SI 1 "register_operand" "r")] UNSPEC_FLOAD))] 2177 "TARGET_FPU && !TARGET_FPU_IEEE" 2178 "fload %0,%1" 2179 [(set_attr "type" "reg_fp")]) 2180 2181 (define_insn "*itof_no_ieee" 2182 [(set (match_operand:SF 0 "fp_reg_operand" "=f") 2183 (unspec:SF [(match_operand:SF 1 "fp_reg_operand" "f")] UNSPEC_ITOF))] 2184 "TARGET_FPU && !TARGET_FPU_IEEE" 2185 "itof %0,%1" 2186 [(set_attr "type" "itof")]) 2187 2188 (define_insn_and_split "*floatsisf2_no_ieee" 2189 [(set (match_operand:SF 0 "fp_reg_operand" "=f") 2190 (float:SF (match_operand:SI 1 "register_operand" "r")))] 2191 "TARGET_FPU && !TARGET_FPU_IEEE" 2192 "#" 2193 "&& reload_completed" 2194 [(set (match_dup 0) 2195 (unspec:SF [(match_dup 1)] UNSPEC_FLOAD)) 2196 (set (match_dup 0) 2197 (unspec:SF [(match_dup 0)] UNSPEC_ITOF))] 2198 "" 2199 [(set_attr "type" "multi")]) 2200 2201 (define_insn "*ftoi_no_ieee" 2202 [(set (match_operand:SF 0 "fp_reg_operand" "=f") 2203 (unspec:SF [(match_operand:SF 1 "fp_reg_operand" "f")] UNSPEC_FTOI))] 2204 "TARGET_FPU && !TARGET_FPU_IEEE" 2205 "ftoi %0,%1" 2206 [(set_attr "type" "ftoi")]) 2207 2208 (define_insn "*fstore_no_ieee" 2209 [(set (match_operand:SI 0 "register_operand" "=r") 2210 (unspec:SI [(match_operand:SF 1 "fp_reg_operand" "f")] UNSPEC_FSTORE))] 2211 "TARGET_FPU && !TARGET_FPU_IEEE" 2212 "fstore %0,%1" 2213 [(set_attr "type" "fp_reg")]) 2214 2215 (define_insn_and_split "fix_truncsfsi2_no_ieee" 2216 [(set (match_operand:SI 0 "register_operand" "=r") 2217 (fix:SI (fix:SF (match_operand:SF 1 "fp_reg_operand" "f")))) 2218 (clobber (match_scratch:SF 2 "=1"))] 2219 "TARGET_FPU && !TARGET_FPU_IEEE" 2220 "#" 2221 "&& reload_completed" 2222 [(set (match_dup 1) 2223 (unspec:SF [(match_dup 1)] UNSPEC_FTOI)) 2224 (set (match_dup 0) 2225 (unspec:SI [(match_dup 1)] UNSPEC_FSTORE))] 2226 "" 2227 [(set_attr "type" "multi")]) 2228 2229 ;; 2230 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2231 ;; 2232 ;; Single float <-> single integer conversions 2233 ;; 2234 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2235 ;; 2236 2237 (define_insn "*itof" 2238 [(set (match_operand:SF 0 "fp_reg_operand" "=f") 2239 (float:SF (match_operand:SI 1 "register_operand" "f")))] 2240 "TARGET_FPU_IEEE" 2241 "itof %0,%1" 2242 [(set_attr "type" "itof")]) 2243 2244 (define_expand "floatsisf2" 2245 [(set (match_operand:SF 0 "fp_reg_operand" "") 2246 (float:SF (match_operand:SI 1 "register_operand" "")))] 2247 "TARGET_FPU" 2248 "") 2249 2250 (define_insn "*ftoi" 2251 [(set (match_operand:SI 0 "register_operand" "=f") 2252 (fix:SI (fix:SF (match_operand:SF 1 "fp_reg_operand" "f"))))] 2253 "TARGET_FPU_IEEE" 2254 "ftoi %0,%1" 2255 [(set_attr "type" "ftoi")]) 2256 2257 (define_expand "fix_truncsfsi2" 2258 [(set (match_operand:SI 0 "register_operand" "") 2259 (fix:SI (fix:SF (match_operand:SF 1 "fp_reg_operand" ""))))] 2260 "TARGET_FPU" 2261 { 2262 if (!TARGET_FPU_IEEE) 2263 { 2264 emit_insn (gen_fix_truncsfsi2_no_ieee (operands[0], operands[1])); 2265 DONE; 2266 } 2267 }) 2268 2269 ;; 2270 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2271 ;; 2272 ;; Single float comparisons 2273 ;; 2274 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2275 ;; 2276 2277 (define_insn "*cmpsf_fp" 2278 [(set (reg:CCFP R_FLAGS) 2279 (compare:CCFP (match_operand:SF 0 "fp_reg_or_0_operand" "fG") 2280 (match_operand:SF 1 "fp_reg_or_0_operand" "fG")))] 2281 "TARGET_FPU && reload_completed" 2282 "fcmp r0,%f0,%f1" 2283 [(set_attr "type" "fcmp")]) 2284 2285 (define_insn "*cmpsf_fpe" 2286 [(set (reg:CCFPE R_FLAGS) 2287 (compare:CCFPE (match_operand:SF 0 "fp_reg_or_0_operand" "fG") 2288 (match_operand:SF 1 "fp_reg_or_0_operand" "fG")))] 2289 "TARGET_FPU && reload_completed" 2290 "fcmpe r0,%f0,%f1" 2291 [(set_attr "type" "fcmp")]) 2292 2293 ;; 2294 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2295 ;; 2296 ;; Conditional branch instructions 2297 ;; 2298 ;; Note - we do not specify the two instructions necessary to perform 2299 ;; a compare-and-branch in the cbranch<mode>4 pattern because that would 2300 ;; allow the comparison to be moved away from the jump before the reload 2301 ;; pass has completed. That would be problematical because reload can 2302 ;; generate instructions in between which would clobber the CC register. 2303 ;; 2304 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2305 ;; 2306 2307 (define_expand "cbranch<mode>4" 2308 [(set (pc) 2309 (if_then_else (match_operator 0 "ordered_comparison_operator" 2310 [(match_operand:I 1 "register_operand") 2311 (match_operand:I 2 "reg_or_0_operand")]) 2312 (label_ref (match_operand 3 "")) 2313 (pc)))] 2314 "" 2315 ) 2316 2317 (define_insn_and_split "*cbranch<mode>4_insn" 2318 [(set (pc) 2319 (if_then_else (match_operator 0 "ordered_comparison_operator" 2320 [(match_operand:I 1 "register_operand" "r") 2321 (match_operand:I 2 "reg_or_0_operand" "rO")]) 2322 (label_ref (match_operand 3 "")) 2323 (pc)))] 2324 "" 2325 "#" 2326 "reload_completed" 2327 [(const_int 0)] 2328 { 2329 visium_split_cbranch (GET_CODE (operands[0]), operands[1], operands[2], 2330 operands[3]); 2331 DONE; 2332 } 2333 [(set_attr "type" "cmp")]) 2334 2335 (define_insn_and_split "*cbranch<mode>4_addv_insn" 2336 [(set (pc) 2337 (if_then_else (match_operator 0 "visium_equality_comparison_operator" 2338 [(match_operand:I 1 "register_operand" "r") 2339 (unspec:I [(match_operand:I 2 "register_operand" "%r") 2340 (match_operand:I 3 "register_operand" "r")] 2341 UNSPEC_ADDV)]) 2342 (label_ref (match_operand 4 "")) 2343 (pc)))] 2344 "" 2345 "#" 2346 "reload_completed" 2347 [(const_int 0)] 2348 { 2349 visium_split_cbranch (GET_CODE (operands[0]), XEXP (operands[0], 0), 2350 XEXP (operands[0], 1), operands[4]); 2351 DONE; 2352 } 2353 [(set_attr "type" "cmp")]) 2354 2355 (define_insn_and_split "*cbranch<mode>4_subv_insn" 2356 [(set (pc) 2357 (if_then_else (match_operator 0 "visium_equality_comparison_operator" 2358 [(match_operand:I 1 "register_operand" "r") 2359 (unspec:I [(match_operand:I 2 "reg_or_0_operand" "rO") 2360 (match_operand:I 3 "register_operand" "r")] 2361 UNSPEC_SUBV)]) 2362 (label_ref (match_operand 4 "")) 2363 (pc)))] 2364 "" 2365 "#" 2366 "reload_completed" 2367 [(const_int 0)] 2368 { 2369 visium_split_cbranch (GET_CODE (operands[0]), XEXP (operands[0], 0), 2370 XEXP (operands[0], 1), operands[4]); 2371 DONE; 2372 } 2373 [(set_attr "type" "cmp")]) 2374 2375 (define_insn_and_split "*cbranch<mode>4_negv_insn" 2376 [(set (pc) 2377 (if_then_else (match_operator 0 "visium_equality_comparison_operator" 2378 [(match_operand:I 1 "register_operand" "r") 2379 (unspec:I [(match_operand:I 2 "register_operand" "r")] 2380 UNSPEC_NEGV)]) 2381 (label_ref (match_operand 3 "")) 2382 (pc)))] 2383 "" 2384 "#" 2385 "reload_completed" 2386 [(const_int 0)] 2387 { 2388 visium_split_cbranch (GET_CODE (operands[0]), XEXP (operands[0], 0), 2389 XEXP (operands[0], 1), operands[3]); 2390 DONE; 2391 } 2392 [(set_attr "type" "cmp")]) 2393 2394 (define_insn_and_split "*cbranch<mode>4_btst_insn" 2395 [(set (pc) 2396 (if_then_else (match_operator 0 "visium_equality_comparison_operator" 2397 [(zero_extract:I 2398 (match_operand:I 1 "register_operand" "r") 2399 (const_int 1) 2400 (match_operand:QI 2 "const_shift_operand" "K")) 2401 (const_int 0)]) 2402 (label_ref (match_operand 3 "")) 2403 (pc)))] 2404 "" 2405 "#" 2406 "reload_completed" 2407 [(const_int 0)] 2408 { 2409 visium_split_cbranch (GET_CODE (operands[0]), XEXP (operands[0], 0), 2410 XEXP (operands[0], 1), operands[3]); 2411 DONE; 2412 } 2413 [(set_attr "type" "cmp")]) 2414 2415 (define_expand "cbranchsf4" 2416 [(set (pc) 2417 (if_then_else (match_operator 0 "visium_fp_comparison_operator" 2418 [(match_operand:SF 1 "fp_reg_operand") 2419 (match_operand:SF 2 "fp_reg_or_0_operand")]) 2420 (label_ref (match_operand 3 "")) 2421 (pc)))] 2422 "TARGET_FPU" 2423 ) 2424 2425 (define_insn_and_split "*cbranchsf4_insn" 2426 [(set (pc) 2427 (if_then_else (match_operator 0 "visium_fp_comparison_operator" 2428 [(match_operand:SF 1 "fp_reg_operand" "f") 2429 (match_operand:SF 2 "fp_reg_or_0_operand" "fG")]) 2430 (label_ref (match_operand 3 "")) 2431 (pc)))] 2432 "TARGET_FPU" 2433 "#" 2434 "&& reload_completed" 2435 [(const_int 0)] 2436 { 2437 visium_split_cbranch (GET_CODE (operands[0]), operands[1], operands[2], 2438 operands[3]); 2439 DONE; 2440 } 2441 [(set_attr "type" "fcmp")]) 2442 2443 ; Now match both normal and inverted branches. 2444 2445 (define_insn "*normal_branch" 2446 [(set (pc) 2447 (if_then_else (match_operator 1 "visium_branch_operator" 2448 [(reg R_FLAGS) (const_int 0)]) 2449 (label_ref (match_operand 0 "")) 2450 (pc)))] 2451 "reload_completed" 2452 { 2453 return output_cbranch (operands[0], GET_CODE (operands[1]), 2454 GET_MODE (XEXP (operands[1], 0)), 0, insn); 2455 } 2456 [(set_attr "type" "branch")]) 2457 2458 (define_insn "*inverted_branch" 2459 [(set (pc) 2460 (if_then_else (match_operator 1 "visium_branch_operator" 2461 [(reg R_FLAGS) (const_int 0)]) 2462 (pc) 2463 (label_ref (match_operand 0 ""))))] 2464 "reload_completed" 2465 { 2466 return output_cbranch (operands[0], GET_CODE (operands[1]), 2467 GET_MODE (XEXP (operands[1], 0)), 1, insn); 2468 } 2469 [(set_attr "type" "branch")]) 2470 2471 ; And then match both normal and inverted returns. 2472 2473 (define_insn "*cond_<return_str>return" 2474 [(set (pc) 2475 (if_then_else (match_operator 0 "visium_branch_operator" 2476 [(reg R_FLAGS) (const_int 0)]) 2477 (any_return) 2478 (pc)))] 2479 "<return_pred> && reload_completed" 2480 { 2481 return output_cbranch (pc_rtx, GET_CODE (operands[0]), 2482 GET_MODE (XEXP (operands[0], 0)), 0, insn); 2483 } 2484 [(set_attr "type" "ret")]) 2485 2486 (define_insn "*inverted_cond_<return_str>return" 2487 [(set (pc) 2488 (if_then_else (match_operator 0 "visium_branch_operator" 2489 [(reg R_FLAGS) (const_int 0)]) 2490 (pc) 2491 (any_return)))] 2492 "<return_pred> && reload_completed" 2493 { 2494 return output_cbranch (pc_rtx, GET_CODE (operands[0]), 2495 GET_MODE (XEXP (operands[0], 0)), 1, insn); 2496 } 2497 [(set_attr "type" "ret")]) 2498 2499 ;; 2500 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2501 ;; 2502 ;; Unconditional branch instructions 2503 ;; 2504 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2505 ;; 2506 2507 (define_insn "jump" 2508 [(set (pc) 2509 (label_ref (match_operand 0 "" "")))] 2510 "" 2511 { 2512 return output_ubranch (operands[0], insn); 2513 } 2514 [(set_attr "type" "branch")]) 2515 2516 (define_insn "indirect_jump" 2517 [(set (pc) 2518 (match_operand:SI 0 "register_operand" "r"))] 2519 "" 2520 "bra tr,%0,r0%# ;indirect jump" 2521 [(set_attr "type" "abs_branch")]) 2522 2523 (define_insn "tablejump" 2524 [(set (pc) 2525 (match_operand:SI 0 "register_operand" "r")) 2526 (use (label_ref (match_operand 1 "" "")))] 2527 "" 2528 "bra tr,%0,r0%# ;tablejump" 2529 [(set_attr "type" "abs_branch")]) 2530 2531 ;; 2532 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2533 ;; 2534 ;; trap instructions 2535 ;; 2536 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2537 ;; 2538 2539 (define_insn "trap" 2540 [(trap_if (const_int 1) (const_int 0))] 2541 "" 2542 "stop 0,r0" 2543 [(set_attr "type" "trap")]) 2544 2545 ;; 2546 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2547 ;; 2548 ;; Subprogram call instructions 2549 ;; 2550 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2551 ;; 2552 2553 ; Subroutine call instruction returning no value. Operand 0 is the function 2554 ; to call; operand 1 is the number of bytes of arguments pushed (in mode 2555 ; 'SImode', except it is normally a 'const_int'); operand 2 is the number of 2556 ; registers used as operands. 2557 2558 (define_expand "call" 2559 [(parallel [(call (match_operand 0 "" "") 2560 (match_operand 1 "" "")) 2561 (use (match_operand 2 "" "")) 2562 (clobber (match_dup 3))])] 2563 "" 2564 { 2565 if (GET_CODE (XEXP (operands[0], 0)) != REG) 2566 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0)); 2567 2568 if (!operands[2]) 2569 operands[2] = const0_rtx; 2570 2571 operands[3] = gen_rtx_REG (Pmode, R_LINK); 2572 }) 2573 2574 (define_insn "*call_internal" 2575 [(call (mem:SI (match_operand:SI 0 "register_operand" "l,!r")) 2576 (match_operand 1 "" "")) 2577 (use (match_operand 2 "" "")) 2578 (clobber (match_operand 3 "" ""))] 2579 "!SIBLING_CALL_P (insn)" 2580 "bra tr,%0,%3%# ;call" 2581 [(set_attr "type" "call")]) 2582 2583 ; Subroutine call instruction returning a value. Operand 0 is the hard 2584 ; register in which the value is returned. There are three more operands, the 2585 ; same as the three operands of the 'call' instruction (but with numbers 2586 ; increased by one). 2587 2588 (define_expand "call_value" 2589 [(parallel [(set (match_operand 0 "register_operand" "") 2590 (call (match_operand 1 "" "") 2591 (match_operand 2 "" ""))) 2592 (use (match_operand 3 "" "")) 2593 (clobber (match_dup 4))])] 2594 "" 2595 { 2596 if (GET_CODE (XEXP (operands[1], 0)) != REG) 2597 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); 2598 2599 if (!operands[3]) 2600 operands[3] = const0_rtx; 2601 2602 operands[4] = gen_rtx_REG (Pmode, R_LINK); 2603 }) 2604 2605 (define_insn "*call_value_internal" 2606 [(set (match_operand 0 "register_operand" "") 2607 (call (mem:SI (match_operand:SI 1 "register_operand" "l,!r")) 2608 (match_operand 2 "" ""))) 2609 (use (match_operand 3 "" "")) 2610 (clobber (match_operand 4 "" ""))] 2611 "!SIBLING_CALL_P (insn)" 2612 "bra tr,%1,%4%# ;call value" 2613 [(set_attr "type" "call")]) 2614 2615 ; Tail calls are similar, except that the link register is not used. But 2616 ; we don't use r0 as the destination register of the branch because we want 2617 ; the Branch Pre-decode Logic of the GR6 to use the Address Load Array to 2618 ; predict the branch target. 2619 2620 (define_expand "sibcall" 2621 [(parallel [(call (match_operand 0 "" "") 2622 (match_operand 1 "" "")) 2623 (use (match_operand 2 "" "")) 2624 (clobber (match_dup 3))])] 2625 "" 2626 { 2627 if (GET_CODE (XEXP (operands[0], 0)) != REG) 2628 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0)); 2629 2630 if (!operands[2]) 2631 operands[2] = const0_rtx; 2632 2633 operands[3] = gen_rtx_SCRATCH (SImode); 2634 }) 2635 2636 (define_insn "*sibcall_internal" 2637 [(call (mem:SI (match_operand:SI 0 "register_operand" "k")) 2638 (match_operand 1 "" "")) 2639 (use (match_operand 2 "" "")) 2640 (clobber (match_scratch:SI 3 "=0"))] 2641 "SIBLING_CALL_P (insn)" 2642 "bra tr,%0,%0%# ;sibcall" 2643 [(set_attr "type" "call")]) 2644 2645 (define_expand "sibcall_value" 2646 [(parallel [(set (match_operand 0 "register_operand" "") 2647 (call (match_operand 1 "" "") 2648 (match_operand 2 "" ""))) 2649 (use (match_operand 3 "" "")) 2650 (clobber (match_dup 4))])] 2651 "" 2652 { 2653 if (GET_CODE (XEXP (operands[1], 0)) != REG) 2654 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); 2655 2656 if (!operands[3]) 2657 operands[3] = const0_rtx; 2658 2659 operands[4] = gen_rtx_SCRATCH (SImode); 2660 }) 2661 2662 (define_insn "*sibcall_value_internal" 2663 [(set (match_operand 0 "register_operand" "") 2664 (call (mem:SI (match_operand:SI 1 "register_operand" "k")) 2665 (match_operand 2 "" ""))) 2666 (use (match_operand 3 "" "")) 2667 (clobber (match_scratch:SI 4 "=1"))] 2668 "SIBLING_CALL_P (insn)" 2669 "bra tr,%1,%1%# ;sibcall value" 2670 [(set_attr "type" "call")]) 2671 2672 ; Call subroutine returning any type. 2673 (define_expand "untyped_call" 2674 [(parallel [(call (match_operand 0 "" "") 2675 (const_int 0)) 2676 (match_operand 1 "" "") 2677 (match_operand 2 "" "")])] 2678 "" 2679 { 2680 int i; 2681 2682 emit_call_insn (gen_call (operands[0], const0_rtx, NULL)); 2683 2684 for (i = 0; i < XVECLEN (operands[2], 0); i++) 2685 { 2686 rtx set = XVECEXP (operands[2], 0, i); 2687 emit_move_insn (SET_DEST (set), SET_SRC (set)); 2688 } 2689 2690 /* The optimizer does not know that the call sets the function value 2691 registers we stored in the result block. We avoid problems by 2692 claiming that all hard registers are used and clobbered at this 2693 point. */ 2694 emit_insn (gen_blockage ()); 2695 2696 DONE; 2697 }) 2698 2699 ;; 2700 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2701 ;; 2702 ;; Compare-and-store instructions 2703 ;; 2704 ;; Modes QI, HI, SI and SF are supported directly. 2705 ;; 2706 ;; Note - we do not specify the two instructions necessary to perform 2707 ;; a compare-and-store in the cstore<mode>4 pattern because that would 2708 ;; allow the comparison to be moved away from the store before the reload 2709 ;; pass has completed. That would be problematical because reload can 2710 ;; generate instructions in between which would clobber the CC register. 2711 ;; 2712 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2713 ;; 2714 2715 (define_expand "cstore<mode>4" 2716 [(set (match_operand:SI 0) 2717 (match_operator:SI 1 "visium_int_cstore_operator" 2718 [(match_operand:I 2 "register_operand") 2719 (match_operand:I 3 "reg_or_0_operand")]))] 2720 "" 2721 { 2722 visium_expand_int_cstore (operands, <MODE>mode); 2723 DONE; 2724 }) 2725 2726 (define_insn_and_split "*cstore<mode>4_insn" 2727 [(set (match_operand:SI 0 "register_operand" "=r") 2728 (ltu:SI (match_operand:I 1 "register_operand" "r") 2729 (match_operand:I 2 "reg_or_0_operand" "rO")))] 2730 "" 2731 "#" 2732 "reload_completed" 2733 [(const_int 0)] 2734 { 2735 visium_split_cstore (SET, operands[0], NULL_RTX, 2736 LTU, operands[1], operands[2]); 2737 DONE; 2738 } 2739 [(set_attr "type" "cmp")]) 2740 2741 (define_insn_and_split "*neg_cstore<mode>4_insn" 2742 [(set (match_operand:SI 0 "register_operand" "=r") 2743 (neg:SI (ltu:SI (match_operand:I 1 "register_operand" "r") 2744 (match_operand:I 2 "reg_or_0_operand" "rO"))))] 2745 "" 2746 "#" 2747 "reload_completed" 2748 [(const_int 0)] 2749 { 2750 visium_split_cstore (NEG, operands[0], NULL_RTX, 2751 LTU, operands[1], operands[2]); 2752 DONE; 2753 } 2754 [(set_attr "type" "cmp")]) 2755 2756 (define_insn_and_split "*<add_str>_cstore<mode>4_insn" 2757 [(set (match_operand:SI 0 "register_operand" "=r") 2758 (any_add:SI (match_operand:SI 1 "register_operand" "r") 2759 (ltu:SI (match_operand:I 2 "register_operand" "r") 2760 (match_operand:I 3 "reg_or_0_operand" "rO"))))] 2761 "" 2762 "#" 2763 "reload_completed" 2764 [(const_int 0)] 2765 { 2766 visium_split_cstore (<add_op>, operands[0], operands[1], 2767 LTU, operands[2], operands[3]); 2768 DONE; 2769 } 2770 [(set_attr "type" "cmp")]) 2771 2772 (define_insn_and_split "*cstore<mode>4_sne_insn" 2773 [(set (match_operand:SI 0 "register_operand" "=r") 2774 (ltu:SI (not:I (match_operand:I 1 "register_operand" "r")) 2775 (const_int -1)))] 2776 "" 2777 "#" 2778 "reload_completed" 2779 [(const_int 0)] 2780 { 2781 visium_split_cstore (SET, operands[0], NULL_RTX, 2782 LTU, gen_rtx_NOT (<MODE>mode, operands[1]), constm1_rtx); 2783 DONE; 2784 } 2785 [(set_attr "type" "cmp")]) 2786 2787 (define_insn_and_split "*neg_cstore<mode>4_sne_insn" 2788 [(set (match_operand:SI 0 "register_operand" "=r") 2789 (neg:SI (ltu:SI (not:I (match_operand:I 1 "register_operand" "r")) 2790 (const_int -1))))] 2791 "" 2792 "#" 2793 "reload_completed" 2794 [(const_int 0)] 2795 { 2796 visium_split_cstore (NEG, operands[0], NULL_RTX, 2797 LTU, gen_rtx_NOT (<MODE>mode, operands[1]), constm1_rtx); 2798 DONE; 2799 } 2800 [(set_attr "type" "cmp")]) 2801 2802 (define_insn_and_split "*<add_str>_cstore<mode>4_sne_insn" 2803 [(set (match_operand:SI 0 "register_operand" "=r") 2804 (any_add:SI (match_operand:SI 1 "register_operand" "r") 2805 (ltu:SI (not:I (match_operand:I 2 "register_operand" "r")) 2806 (const_int -1))))] 2807 "" 2808 "#" 2809 "reload_completed" 2810 [(const_int 0)] 2811 { 2812 visium_split_cstore (<add_op>, operands[0], operands[1], 2813 LTU, gen_rtx_NOT (<MODE>mode, operands[2]), constm1_rtx); 2814 DONE; 2815 } 2816 [(set_attr "type" "cmp")]) 2817 2818 (define_expand "cstoresf4" 2819 [(set (match_operand:SI 0) 2820 (match_operator:SI 1 "visium_fp_cstore_operator" 2821 [(match_operand:SF 2 "fp_reg_operand") 2822 (match_operand:SF 3 "fp_reg_or_0_operand")]))] 2823 "TARGET_FPU" 2824 { 2825 visium_expand_fp_cstore (operands, SFmode); 2826 DONE; 2827 }) 2828 2829 (define_insn_and_split "*cstoresf4_insn" 2830 [(set (match_operand:SI 0 "register_operand" "=r") 2831 (lt:SI (match_operand:SF 1 "fp_reg_or_0_operand" "fG") 2832 (match_operand:SF 2 "fp_reg_or_0_operand" "fG")))] 2833 "TARGET_FPU" 2834 "#" 2835 "&& reload_completed" 2836 [(const_int 0)] 2837 { 2838 visium_split_cstore (SET, operands [0], NULL_RTX, 2839 LT, operands[1], operands[2]); 2840 DONE; 2841 } 2842 [(set_attr "type" "fcmp")]) 2843 2844 (define_insn_and_split "*neg_cstoresf4_insn" 2845 [(set (match_operand:SI 0 "register_operand" "=r") 2846 (neg:SI (lt:SI (match_operand:SF 1 "fp_reg_or_0_operand" "fG") 2847 (match_operand:SF 2 "fp_reg_or_0_operand" "fG"))))] 2848 "TARGET_FPU" 2849 "#" 2850 "&& reload_completed" 2851 [(const_int 0)] 2852 { 2853 visium_split_cstore (NEG, operands [0], NULL_RTX, 2854 LT, operands[1], operands[2]); 2855 DONE; 2856 } 2857 [(set_attr "type" "fcmp")]) 2858 2859 (define_insn_and_split "*<add_str>_cstoresf4_insn" 2860 [(set (match_operand:SI 0 "register_operand" "=r") 2861 (any_add:SI (match_operand:SI 1 "register_operand" "r") 2862 (lt:SI (match_operand:SF 2 "fp_reg_or_0_operand" "fG") 2863 (match_operand:SF 3 "fp_reg_or_0_operand" "fG"))))] 2864 "TARGET_FPU" 2865 "#" 2866 "&& reload_completed" 2867 [(const_int 0)] 2868 { 2869 visium_split_cstore (<add_op>, operands [0], operands[1], 2870 LT, operands[2], operands[3]); 2871 DONE; 2872 } 2873 [(set_attr "type" "fcmp")]) 2874 2875 ;; 2876 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2877 ;; 2878 ;; RTL pro/epilogue support 2879 ;; 2880 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2881 ;; 2882 2883 ; Expand prologue in RTL 2884 (define_expand "prologue" 2885 [(const_int 0)] 2886 "" 2887 { 2888 visium_expand_prologue (); 2889 DONE; 2890 }) 2891 2892 ; Expand epilogue in RTL 2893 (define_expand "epilogue" 2894 [(return)] 2895 "" 2896 { 2897 visium_expand_epilogue (); 2898 }) 2899 2900 ; Expand epilogue without a final jump in RTL 2901 (define_expand "sibcall_epilogue" 2902 [(return)] 2903 "" 2904 { 2905 visium_expand_epilogue (); 2906 DONE; 2907 }) 2908 2909 ; The artificial dependency on the link register is to prevent the 2910 ; frame instruction from being put in a call delay slot, which can 2911 ; confuse the CFI machinery. 2912 2913 (define_insn "stack_save" 2914 [(set (reg:SI R_FP) (reg:SI R_SP)) 2915 (use (reg:SI R_LINK)) 2916 (clobber (reg:CC R_FLAGS))] 2917 "reload_completed" 2918 "move.l fp,sp ;stack_save" 2919 [(set_attr "type" "logic")]) 2920 2921 ; The construct (mem:BLK (scratch)) is considered to alias all other 2922 ; memory accesses. Thus it can be used as a memory barrier in stack 2923 ; deallocation patterns. 2924 2925 (define_insn "stack_restore" 2926 [(set (reg:SI R_SP) (reg:SI R_FP)) 2927 (clobber (mem:BLK (scratch))) 2928 (clobber (reg:CC R_FLAGS))] 2929 "reload_completed" 2930 "move.l sp,fp ;stack_restore" 2931 [(set_attr "type" "logic")]) 2932 2933 (define_insn "stack_pop" 2934 [(set (reg:SI R_SP) 2935 (plus:SI (reg:SI R_SP) (match_operand:SI 0 "add_operand" "J,r"))) 2936 (clobber (mem:BLK (scratch))) 2937 (clobber (reg:CC R_FLAGS))] 2938 "reload_completed" 2939 "@ 2940 addi sp,%0 ;stack pop 2941 add.l sp,sp,%0 ;stack pop" 2942 [(set_attr "type" "arith")]) 2943 2944 (define_expand "<return_str>return" 2945 [(any_return)] 2946 "<return_pred>" 2947 "") 2948 2949 (define_insn "*<return_str>return_internal" 2950 [(any_return)] 2951 "!visium_interrupt_function_p ()" 2952 { 2953 return output_ubranch (pc_rtx, insn); 2954 } 2955 [(set_attr "type" "ret")]) 2956 2957 (define_insn "*return_internal_interrupt" 2958 [(return)] 2959 "visium_interrupt_function_p ()" 2960 "rfi\n\t nop ;return from interrupt" 2961 [(set_attr "type" "rfi")]) 2962 2963 (define_insn "dsi" 2964 [(unspec_volatile [(const_int 0)] UNSPECV_DSI)] 2965 "" 2966 "dsi" 2967 [(set_attr "type" "dsi")]) 2968 2969 ;; 2970 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2971 ;; 2972 ;; NOP (no-op instruction) 2973 ;; 2974 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2975 ;; 2976 2977 (define_insn "nop" 2978 [(const_int 0)] 2979 "" 2980 "nop ;generated" 2981 [(set_attr "type" "nop")]) 2982 2983 (define_insn "hazard_nop" 2984 [(unspec_volatile [(const_int 0)] UNSPEC_NOP)] 2985 "" 2986 "nop ;hazard avoidance" 2987 [(set_attr "type" "nop")]) 2988 2989 (define_insn "blockage" 2990 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)] 2991 "" 2992 "" 2993 [(set_attr "type" "nop")]) 2994 2995 ;; 2996 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2997 ;; 2998 ;; String/block operations 2999 ;; 3000 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3001 ;; 3002 3003 ;; String/block move insn. 3004 ;; Argument 0 is the destination 3005 ;; Argument 1 is the source 3006 ;; Argument 2 is the length 3007 ;; Argument 3 is the alignment 3008 3009 (define_expand "cpymemsi" 3010 [(parallel [(set (match_operand:BLK 0 "memory_operand" "") 3011 (match_operand:BLK 1 "memory_operand" "")) 3012 (use (match_operand:SI 2 "general_operand" "")) 3013 (use (match_operand:SI 3 "const_int_operand" ""))])] 3014 "" 3015 { 3016 if (visium_expand_block_move (operands)) 3017 DONE; 3018 else 3019 FAIL; 3020 }) 3021 3022 (define_insn "*bmd" 3023 [(set (mem:BLK (reg:SI R_R1)) 3024 (mem:BLK (reg:SI R_R2))) 3025 (use (reg:SI R_R3)) 3026 (clobber (reg:SI R_R1)) 3027 (clobber (reg:SI R_R2)) 3028 (clobber (reg:SI R_R3)) 3029 (clobber (reg:SI R_R4)) 3030 (clobber (reg:SI R_R5)) 3031 (clobber (reg:SI R_R6))] 3032 "TARGET_BMI" 3033 "bmd r1,r2,r3" 3034 [(set_attr "type" "bmi")]) 3035 3036 ;; String/block set insn. 3037 ;; Argument 0 is the destination 3038 ;; Argument 1 is the length 3039 ;; Argument 2 is the value 3040 ;; Argument 3 is the alignment 3041 3042 (define_expand "setmemsi" 3043 [(parallel [(set (match_operand:BLK 0 "memory_operand" "") 3044 (match_operand 2 "nonmemory_operand" "")) 3045 (use (match_operand:SI 1 "general_operand" "")) 3046 (use (match_operand:SI 3 "const_int_operand" ""))])] 3047 "" 3048 { 3049 if (visium_expand_block_set (operands)) 3050 DONE; 3051 else 3052 FAIL; 3053 }) 3054