1;; Machine description for AArch64 architecture. 2;; Copyright (C) 2009-2014 Free Software Foundation, Inc. 3;; Contributed by ARM Ltd. 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 by 9;; the Free Software Foundation; either version 3, or (at your option) 10;; any later version. 11;; 12;; GCC is distributed in the hope that it will be useful, but 13;; WITHOUT ANY WARRANTY; without even the implied warranty of 14;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15;; General Public License for more details. 16;; 17;; You should have received a copy of the GNU General Public License 18;; along with GCC; see the file COPYING3. If not see 19;; <http://www.gnu.org/licenses/>. 20 21;; Register numbers 22(define_constants 23 [ 24 (R0_REGNUM 0) 25 (R1_REGNUM 1) 26 (R2_REGNUM 2) 27 (R3_REGNUM 3) 28 (R4_REGNUM 4) 29 (R5_REGNUM 5) 30 (R6_REGNUM 6) 31 (R7_REGNUM 7) 32 (R8_REGNUM 8) 33 (R9_REGNUM 9) 34 (R10_REGNUM 10) 35 (R11_REGNUM 11) 36 (R12_REGNUM 12) 37 (R13_REGNUM 13) 38 (R14_REGNUM 14) 39 (R15_REGNUM 15) 40 (R16_REGNUM 16) 41 (IP0_REGNUM 16) 42 (R17_REGNUM 17) 43 (IP1_REGNUM 17) 44 (R18_REGNUM 18) 45 (R19_REGNUM 19) 46 (R20_REGNUM 20) 47 (R21_REGNUM 21) 48 (R22_REGNUM 22) 49 (R23_REGNUM 23) 50 (R24_REGNUM 24) 51 (R25_REGNUM 25) 52 (R26_REGNUM 26) 53 (R27_REGNUM 27) 54 (R28_REGNUM 28) 55 (R29_REGNUM 29) 56 (R30_REGNUM 30) 57 (LR_REGNUM 30) 58 (SP_REGNUM 31) 59 (V0_REGNUM 32) 60 (V15_REGNUM 47) 61 (V31_REGNUM 63) 62 (SFP_REGNUM 64) 63 (AP_REGNUM 65) 64 (CC_REGNUM 66) 65 ] 66) 67 68(define_c_enum "unspec" [ 69 UNSPEC_CASESI 70 UNSPEC_CLS 71 UNSPEC_FRECPE 72 UNSPEC_FRECPS 73 UNSPEC_FRECPX 74 UNSPEC_FRINTA 75 UNSPEC_FRINTI 76 UNSPEC_FRINTM 77 UNSPEC_FRINTN 78 UNSPEC_FRINTP 79 UNSPEC_FRINTX 80 UNSPEC_FRINTZ 81 UNSPEC_GOTSMALLPIC 82 UNSPEC_GOTSMALLTLS 83 UNSPEC_GOTTINYPIC 84 UNSPEC_LD1 85 UNSPEC_LD2 86 UNSPEC_LD3 87 UNSPEC_LD4 88 UNSPEC_MB 89 UNSPEC_NOP 90 UNSPEC_PRLG_STK 91 UNSPEC_RBIT 92 UNSPEC_SISD_NEG 93 UNSPEC_SISD_SSHL 94 UNSPEC_SISD_USHL 95 UNSPEC_SSHL_2S 96 UNSPEC_SSHR64 97 UNSPEC_ST1 98 UNSPEC_ST2 99 UNSPEC_ST3 100 UNSPEC_ST4 101 UNSPEC_TLS 102 UNSPEC_TLSDESC 103 UNSPEC_USHL_2S 104 UNSPEC_USHR64 105 UNSPEC_VSTRUCTDUMMY 106]) 107 108(define_c_enum "unspecv" [ 109 UNSPECV_EH_RETURN ; Represent EH_RETURN 110 ] 111) 112 113;; If further include files are added the defintion of MD_INCLUDES 114;; must be updated. 115 116(include "constraints.md") 117(include "predicates.md") 118(include "iterators.md") 119 120;; ------------------------------------------------------------------- 121;; Instruction types and attributes 122;; ------------------------------------------------------------------- 123 124; The "type" attribute is is included here from AArch32 backend to be able 125; to share pipeline descriptions. 126(include "../arm/types.md") 127 128;; Attribute that specifies whether or not the instruction touches fp 129;; registers. 130(define_attr "fp" "no,yes" (const_string "no")) 131 132;; Attribute that specifies whether or not the instruction touches simd 133;; registers. 134(define_attr "simd" "no,yes" (const_string "no")) 135 136(define_attr "length" "" 137 (const_int 4)) 138 139;; Attribute that controls whether an alternative is enabled or not. 140;; Currently it is only used to disable alternatives which touch fp or simd 141;; registers when -mgeneral-regs-only is specified. 142(define_attr "enabled" "no,yes" 143 (cond [(ior 144 (and (eq_attr "fp" "yes") 145 (eq (symbol_ref "TARGET_FLOAT") (const_int 0))) 146 (and (eq_attr "simd" "yes") 147 (eq (symbol_ref "TARGET_SIMD") (const_int 0)))) 148 (const_string "no") 149 ] (const_string "yes"))) 150 151;; ------------------------------------------------------------------- 152;; Pipeline descriptions and scheduling 153;; ------------------------------------------------------------------- 154 155;; Processor types. 156(include "aarch64-tune.md") 157 158;; True if the generic scheduling description should be used. 159 160(define_attr "generic_sched" "yes,no" 161 (const (if_then_else 162 (eq_attr "tune" "cortexa53,cortexa15") 163 (const_string "no") 164 (const_string "yes")))) 165 166;; Scheduling 167(include "../arm/cortex-a53.md") 168(include "../arm/cortex-a15.md") 169 170;; ------------------------------------------------------------------- 171;; Jumps and other miscellaneous insns 172;; ------------------------------------------------------------------- 173 174(define_insn "indirect_jump" 175 [(set (pc) (match_operand:DI 0 "register_operand" "r"))] 176 "" 177 "br\\t%0" 178 [(set_attr "type" "branch")] 179) 180 181(define_insn "jump" 182 [(set (pc) (label_ref (match_operand 0 "" "")))] 183 "" 184 "b\\t%l0" 185 [(set_attr "type" "branch")] 186) 187 188(define_expand "cbranch<mode>4" 189 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator" 190 [(match_operand:GPI 1 "register_operand" "") 191 (match_operand:GPI 2 "aarch64_plus_operand" "")]) 192 (label_ref (match_operand 3 "" "")) 193 (pc)))] 194 "" 195 " 196 operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1], 197 operands[2]); 198 operands[2] = const0_rtx; 199 " 200) 201 202(define_expand "cbranch<mode>4" 203 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator" 204 [(match_operand:GPF 1 "register_operand" "") 205 (match_operand:GPF 2 "aarch64_reg_or_zero" "")]) 206 (label_ref (match_operand 3 "" "")) 207 (pc)))] 208 "" 209 " 210 operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1], 211 operands[2]); 212 operands[2] = const0_rtx; 213 " 214) 215 216(define_insn "*condjump" 217 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator" 218 [(match_operand 1 "cc_register" "") (const_int 0)]) 219 (label_ref (match_operand 2 "" "")) 220 (pc)))] 221 "" 222 "b%m0\\t%l2" 223 [(set_attr "type" "branch")] 224) 225 226(define_expand "casesi" 227 [(match_operand:SI 0 "register_operand" "") ; Index 228 (match_operand:SI 1 "const_int_operand" "") ; Lower bound 229 (match_operand:SI 2 "const_int_operand" "") ; Total range 230 (match_operand:DI 3 "" "") ; Table label 231 (match_operand:DI 4 "" "")] ; Out of range label 232 "" 233 { 234 if (operands[1] != const0_rtx) 235 { 236 rtx reg = gen_reg_rtx (SImode); 237 238 /* Canonical RTL says that if you have: 239 240 (minus (X) (CONST)) 241 242 then this should be emitted as: 243 244 (plus (X) (-CONST)) 245 246 The use of trunc_int_for_mode ensures that the resulting 247 constant can be represented in SImode, this is important 248 for the corner case where operand[1] is INT_MIN. */ 249 250 operands[1] = GEN_INT (trunc_int_for_mode (-INTVAL (operands[1]), SImode)); 251 252 if (!(*insn_data[CODE_FOR_addsi3].operand[2].predicate) 253 (operands[1], SImode)) 254 operands[1] = force_reg (SImode, operands[1]); 255 emit_insn (gen_addsi3 (reg, operands[0], operands[1])); 256 operands[0] = reg; 257 } 258 259 if (!aarch64_plus_operand (operands[2], SImode)) 260 operands[2] = force_reg (SImode, operands[2]); 261 emit_jump_insn (gen_cbranchsi4 (gen_rtx_GTU (SImode, const0_rtx, 262 const0_rtx), 263 operands[0], operands[2], operands[4])); 264 265 operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (VOIDmode, operands[3])); 266 emit_jump_insn (gen_casesi_dispatch (operands[2], operands[0], 267 operands[3])); 268 DONE; 269 } 270) 271 272(define_insn "casesi_dispatch" 273 [(parallel 274 [(set (pc) 275 (mem:DI (unspec [(match_operand:DI 0 "register_operand" "r") 276 (match_operand:SI 1 "register_operand" "r")] 277 UNSPEC_CASESI))) 278 (clobber (reg:CC CC_REGNUM)) 279 (clobber (match_scratch:DI 3 "=r")) 280 (clobber (match_scratch:DI 4 "=r")) 281 (use (label_ref (match_operand 2 "" "")))])] 282 "" 283 "* 284 return aarch64_output_casesi (operands); 285 " 286 [(set_attr "length" "16") 287 (set_attr "type" "branch")] 288) 289 290(define_insn "nop" 291 [(unspec[(const_int 0)] UNSPEC_NOP)] 292 "" 293 "nop" 294 [(set_attr "type" "no_insn")] 295) 296 297(define_insn "trap" 298 [(trap_if (const_int 1) (const_int 8))] 299 "" 300 "brk #1000" 301 [(set_attr "type" "trap")]) 302 303(define_expand "prologue" 304 [(clobber (const_int 0))] 305 "" 306 " 307 aarch64_expand_prologue (); 308 DONE; 309 " 310) 311 312(define_expand "epilogue" 313 [(clobber (const_int 0))] 314 "" 315 " 316 aarch64_expand_epilogue (false); 317 DONE; 318 " 319) 320 321(define_expand "sibcall_epilogue" 322 [(clobber (const_int 0))] 323 "" 324 " 325 aarch64_expand_epilogue (true); 326 DONE; 327 " 328) 329 330(define_insn "*do_return" 331 [(return)] 332 "" 333 "ret" 334 [(set_attr "type" "branch")] 335) 336 337(define_insn "eh_return" 338 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")] 339 UNSPECV_EH_RETURN)] 340 "" 341 "#" 342 [(set_attr "type" "branch")] 343 344) 345 346(define_split 347 [(unspec_volatile [(match_operand:DI 0 "register_operand" "")] 348 UNSPECV_EH_RETURN)] 349 "reload_completed" 350 [(set (match_dup 1) (match_dup 0))] 351 { 352 operands[1] = aarch64_final_eh_return_addr (); 353 } 354) 355 356(define_insn "*cb<optab><mode>1" 357 [(set (pc) (if_then_else (EQL (match_operand:GPI 0 "register_operand" "r") 358 (const_int 0)) 359 (label_ref (match_operand 1 "" "")) 360 (pc)))] 361 "" 362 "<cbz>\\t%<w>0, %l1" 363 [(set_attr "type" "branch")] 364 365) 366 367(define_insn "*tb<optab><mode>1" 368 [(set (pc) (if_then_else 369 (EQL (zero_extract:DI (match_operand:GPI 0 "register_operand" "r") 370 (const_int 1) 371 (match_operand 1 "const_int_operand" "n")) 372 (const_int 0)) 373 (label_ref (match_operand 2 "" "")) 374 (pc))) 375 (clobber (match_scratch:DI 3 "=r"))] 376 "" 377 "* 378 if (get_attr_length (insn) == 8) 379 return \"ubfx\\t%<w>3, %<w>0, %1, #1\;<cbz>\\t%<w>3, %l2\"; 380 return \"<tbz>\\t%<w>0, %1, %l2\"; 381 " 382 [(set_attr "type" "branch") 383 (set (attr "length") 384 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -32768)) 385 (lt (minus (match_dup 2) (pc)) (const_int 32764))) 386 (const_int 4) 387 (const_int 8)))] 388) 389 390(define_insn "*cb<optab><mode>1" 391 [(set (pc) (if_then_else (LTGE (match_operand:ALLI 0 "register_operand" "r") 392 (const_int 0)) 393 (label_ref (match_operand 1 "" "")) 394 (pc))) 395 (clobber (match_scratch:DI 2 "=r"))] 396 "" 397 "* 398 if (get_attr_length (insn) == 8) 399 return \"ubfx\\t%<w>2, %<w>0, <sizem1>, #1\;<cbz>\\t%<w>2, %l1\"; 400 return \"<tbz>\\t%<w>0, <sizem1>, %l1\"; 401 " 402 [(set_attr "type" "branch") 403 (set (attr "length") 404 (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -32768)) 405 (lt (minus (match_dup 1) (pc)) (const_int 32764))) 406 (const_int 4) 407 (const_int 8)))] 408) 409 410;; ------------------------------------------------------------------- 411;; Subroutine calls and sibcalls 412;; ------------------------------------------------------------------- 413 414(define_expand "call" 415 [(parallel [(call (match_operand 0 "memory_operand" "") 416 (match_operand 1 "general_operand" "")) 417 (use (match_operand 2 "" "")) 418 (clobber (reg:DI LR_REGNUM))])] 419 "" 420 " 421 { 422 rtx callee; 423 424 /* In an untyped call, we can get NULL for operand 2. */ 425 if (operands[2] == NULL) 426 operands[2] = const0_rtx; 427 428 /* Decide if we should generate indirect calls by loading the 429 64-bit address of the callee into a register before performing 430 the branch-and-link. */ 431 callee = XEXP (operands[0], 0); 432 if (GET_CODE (callee) == SYMBOL_REF 433 ? aarch64_is_long_call_p (callee) 434 : !REG_P (callee)) 435 XEXP (operands[0], 0) = force_reg (Pmode, callee); 436 }" 437) 438 439(define_insn "*call_reg" 440 [(call (mem:DI (match_operand:DI 0 "register_operand" "r")) 441 (match_operand 1 "" "")) 442 (use (match_operand 2 "" "")) 443 (clobber (reg:DI LR_REGNUM))] 444 "" 445 "blr\\t%0" 446 [(set_attr "type" "call")] 447) 448 449(define_insn "*call_symbol" 450 [(call (mem:DI (match_operand:DI 0 "" "")) 451 (match_operand 1 "" "")) 452 (use (match_operand 2 "" "")) 453 (clobber (reg:DI LR_REGNUM))] 454 "GET_CODE (operands[0]) == SYMBOL_REF 455 && !aarch64_is_long_call_p (operands[0])" 456 "bl\\t%a0" 457 [(set_attr "type" "call")] 458) 459 460(define_expand "call_value" 461 [(parallel [(set (match_operand 0 "" "") 462 (call (match_operand 1 "memory_operand" "") 463 (match_operand 2 "general_operand" ""))) 464 (use (match_operand 3 "" "")) 465 (clobber (reg:DI LR_REGNUM))])] 466 "" 467 " 468 { 469 rtx callee; 470 471 /* In an untyped call, we can get NULL for operand 3. */ 472 if (operands[3] == NULL) 473 operands[3] = const0_rtx; 474 475 /* Decide if we should generate indirect calls by loading the 476 64-bit address of the callee into a register before performing 477 the branch-and-link. */ 478 callee = XEXP (operands[1], 0); 479 if (GET_CODE (callee) == SYMBOL_REF 480 ? aarch64_is_long_call_p (callee) 481 : !REG_P (callee)) 482 XEXP (operands[1], 0) = force_reg (Pmode, callee); 483 }" 484) 485 486(define_insn "*call_value_reg" 487 [(set (match_operand 0 "" "") 488 (call (mem:DI (match_operand:DI 1 "register_operand" "r")) 489 (match_operand 2 "" ""))) 490 (use (match_operand 3 "" "")) 491 (clobber (reg:DI LR_REGNUM))] 492 "" 493 "blr\\t%1" 494 [(set_attr "type" "call")] 495 496) 497 498(define_insn "*call_value_symbol" 499 [(set (match_operand 0 "" "") 500 (call (mem:DI (match_operand:DI 1 "" "")) 501 (match_operand 2 "" ""))) 502 (use (match_operand 3 "" "")) 503 (clobber (reg:DI LR_REGNUM))] 504 "GET_CODE (operands[1]) == SYMBOL_REF 505 && !aarch64_is_long_call_p (operands[1])" 506 "bl\\t%a1" 507 [(set_attr "type" "call")] 508) 509 510(define_expand "sibcall" 511 [(parallel [(call (match_operand 0 "memory_operand" "") 512 (match_operand 1 "general_operand" "")) 513 (return) 514 (use (match_operand 2 "" ""))])] 515 "" 516 { 517 if (operands[2] == NULL_RTX) 518 operands[2] = const0_rtx; 519 } 520) 521 522(define_expand "sibcall_value" 523 [(parallel [(set (match_operand 0 "" "") 524 (call (match_operand 1 "memory_operand" "") 525 (match_operand 2 "general_operand" ""))) 526 (return) 527 (use (match_operand 3 "" ""))])] 528 "" 529 { 530 if (operands[3] == NULL_RTX) 531 operands[3] = const0_rtx; 532 } 533) 534 535(define_insn "*sibcall_insn" 536 [(call (mem:DI (match_operand:DI 0 "" "X")) 537 (match_operand 1 "" "")) 538 (return) 539 (use (match_operand 2 "" ""))] 540 "GET_CODE (operands[0]) == SYMBOL_REF" 541 "b\\t%a0" 542 [(set_attr "type" "branch")] 543 544) 545 546(define_insn "*sibcall_value_insn" 547 [(set (match_operand 0 "" "") 548 (call (mem:DI (match_operand 1 "" "X")) 549 (match_operand 2 "" ""))) 550 (return) 551 (use (match_operand 3 "" ""))] 552 "GET_CODE (operands[1]) == SYMBOL_REF" 553 "b\\t%a1" 554 [(set_attr "type" "branch")] 555) 556 557;; Call subroutine returning any type. 558 559(define_expand "untyped_call" 560 [(parallel [(call (match_operand 0 "") 561 (const_int 0)) 562 (match_operand 1 "") 563 (match_operand 2 "")])] 564 "" 565{ 566 int i; 567 568 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx)); 569 570 for (i = 0; i < XVECLEN (operands[2], 0); i++) 571 { 572 rtx set = XVECEXP (operands[2], 0, i); 573 emit_move_insn (SET_DEST (set), SET_SRC (set)); 574 } 575 576 /* The optimizer does not know that the call sets the function value 577 registers we stored in the result block. We avoid problems by 578 claiming that all hard registers are used and clobbered at this 579 point. */ 580 emit_insn (gen_blockage ()); 581 DONE; 582}) 583 584;; ------------------------------------------------------------------- 585;; Moves 586;; ------------------------------------------------------------------- 587 588(define_expand "mov<mode>" 589 [(set (match_operand:SHORT 0 "nonimmediate_operand" "") 590 (match_operand:SHORT 1 "general_operand" ""))] 591 "" 592 " 593 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx) 594 operands[1] = force_reg (<MODE>mode, operands[1]); 595 " 596) 597 598(define_insn "*mov<mode>_aarch64" 599 [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r, *w,r,*w, m, m, r,*w,*w") 600 (match_operand:SHORT 1 "general_operand" " r,M,D<hq>,m, m,rZ,*w,*w, r,*w"))] 601 "(register_operand (operands[0], <MODE>mode) 602 || aarch64_reg_or_zero (operands[1], <MODE>mode))" 603{ 604 switch (which_alternative) 605 { 606 case 0: 607 return "mov\t%w0, %w1"; 608 case 1: 609 return "mov\t%w0, %1"; 610 case 2: 611 return aarch64_output_scalar_simd_mov_immediate (operands[1], 612 <MODE>mode); 613 case 3: 614 return "ldr<size>\t%w0, %1"; 615 case 4: 616 return "ldr\t%<size>0, %1"; 617 case 5: 618 return "str<size>\t%w1, %0"; 619 case 6: 620 return "str\t%<size>1, %0"; 621 case 7: 622 return "umov\t%w0, %1.<v>[0]"; 623 case 8: 624 return "dup\t%0.<Vallxd>, %w1"; 625 case 9: 626 return "dup\t%<Vetype>0, %1.<v>[0]"; 627 default: 628 gcc_unreachable (); 629 } 630} 631 [(set_attr "type" "mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\ 632 neon_from_gp<q>,neon_from_gp<q>, neon_dup") 633 (set_attr "simd" "*,*,yes,*,*,*,*,yes,yes,yes")] 634) 635 636(define_expand "mov<mode>" 637 [(set (match_operand:GPI 0 "nonimmediate_operand" "") 638 (match_operand:GPI 1 "general_operand" ""))] 639 "" 640 " 641 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx) 642 operands[1] = force_reg (<MODE>mode, operands[1]); 643 644 if (CONSTANT_P (operands[1])) 645 { 646 aarch64_expand_mov_immediate (operands[0], operands[1]); 647 DONE; 648 } 649 " 650) 651 652(define_insn "*movsi_aarch64" 653 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,k,r,r,r,*w,m, m,r,r ,*w, r,*w") 654 (match_operand:SI 1 "aarch64_mov_operand" " r,r,k,M,m, m,rZ,*w,S,Ush,rZ,*w,*w"))] 655 "(register_operand (operands[0], SImode) 656 || aarch64_reg_or_zero (operands[1], SImode))" 657 "@ 658 mov\\t%w0, %w1 659 mov\\t%w0, %w1 660 mov\\t%w0, %w1 661 mov\\t%w0, %1 662 ldr\\t%w0, %1 663 ldr\\t%s0, %1 664 str\\t%w1, %0 665 str\\t%s1, %0 666 adr\\t%x0, %a1 667 adrp\\t%x0, %A1 668 fmov\\t%s0, %w1 669 fmov\\t%w0, %s1 670 fmov\\t%s0, %s1" 671 [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,load1,load1,store1,store1,\ 672 adr,adr,fmov,fmov,fmov") 673 (set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes")] 674) 675 676(define_insn "*movdi_aarch64" 677 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,*w,m, m,r,r, *w, r,*w,w") 678 (match_operand:DI 1 "aarch64_mov_operand" " r,r,k,N,m, m,rZ,*w,S,Ush,rZ,*w,*w,Dd"))] 679 "(register_operand (operands[0], DImode) 680 || aarch64_reg_or_zero (operands[1], DImode))" 681 "@ 682 mov\\t%x0, %x1 683 mov\\t%0, %x1 684 mov\\t%x0, %1 685 mov\\t%x0, %1 686 ldr\\t%x0, %1 687 ldr\\t%d0, %1 688 str\\t%x1, %0 689 str\\t%d1, %0 690 adr\\t%x0, %a1 691 adrp\\t%x0, %A1 692 fmov\\t%d0, %x1 693 fmov\\t%x0, %d1 694 fmov\\t%d0, %d1 695 movi\\t%d0, %1" 696 [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,load1,load1,store1,store1,\ 697 adr,adr,fmov,fmov,fmov,fmov") 698 (set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes,*") 699 (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,*,*,yes")] 700) 701 702(define_insn "insv_imm<mode>" 703 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r") 704 (const_int 16) 705 (match_operand:GPI 1 "const_int_operand" "n")) 706 (match_operand:GPI 2 "const_int_operand" "n"))] 707 "UINTVAL (operands[1]) < GET_MODE_BITSIZE (<MODE>mode) 708 && UINTVAL (operands[1]) % 16 == 0" 709 "movk\\t%<w>0, %X2, lsl %1" 710 [(set_attr "type" "mov_imm")] 711) 712 713(define_expand "movti" 714 [(set (match_operand:TI 0 "nonimmediate_operand" "") 715 (match_operand:TI 1 "general_operand" ""))] 716 "" 717 " 718 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx) 719 operands[1] = force_reg (TImode, operands[1]); 720 " 721) 722 723(define_insn "*movti_aarch64" 724 [(set (match_operand:TI 0 725 "nonimmediate_operand" "=r, *w,r ,*w,r ,Ump,Ump,*w,m") 726 (match_operand:TI 1 727 "aarch64_movti_operand" " rn,r ,*w,*w,Ump,r ,Z , m,*w"))] 728 "(register_operand (operands[0], TImode) 729 || aarch64_reg_or_zero (operands[1], TImode))" 730 "@ 731 # 732 # 733 # 734 orr\\t%0.16b, %1.16b, %1.16b 735 ldp\\t%0, %H0, %1 736 stp\\t%1, %H1, %0 737 stp\\txzr, xzr, %0 738 ldr\\t%q0, %1 739 str\\t%q1, %0" 740 [(set_attr "type" "multiple,f_mcr,f_mrc,neon_logic_q, \ 741 load2,store2,store2,f_loadd,f_stored") 742 (set_attr "length" "8,8,8,4,4,4,4,4,4") 743 (set_attr "simd" "*,*,*,yes,*,*,*,*,*") 744 (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")] 745) 746 747;; Split a TImode register-register or register-immediate move into 748;; its component DImode pieces, taking care to handle overlapping 749;; source and dest registers. 750(define_split 751 [(set (match_operand:TI 0 "register_operand" "") 752 (match_operand:TI 1 "aarch64_reg_or_imm" ""))] 753 "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])" 754 [(const_int 0)] 755{ 756 aarch64_split_128bit_move (operands[0], operands[1]); 757 DONE; 758}) 759 760(define_expand "mov<mode>" 761 [(set (match_operand:GPF 0 "nonimmediate_operand" "") 762 (match_operand:GPF 1 "general_operand" ""))] 763 "" 764 " 765 if (!TARGET_FLOAT) 766 { 767 sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\"); 768 FAIL; 769 } 770 771 if (GET_CODE (operands[0]) == MEM) 772 operands[1] = force_reg (<MODE>mode, operands[1]); 773 " 774) 775 776(define_insn "*movsf_aarch64" 777 [(set (match_operand:SF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r") 778 (match_operand:SF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))] 779 "TARGET_FLOAT && (register_operand (operands[0], SFmode) 780 || register_operand (operands[1], SFmode))" 781 "@ 782 fmov\\t%s0, %w1 783 fmov\\t%w0, %s1 784 fmov\\t%s0, %s1 785 fmov\\t%s0, %1 786 ldr\\t%s0, %1 787 str\\t%s1, %0 788 ldr\\t%w0, %1 789 str\\t%w1, %0 790 mov\\t%w0, %w1" 791 [(set_attr "type" "f_mcr,f_mrc,fmov,fconsts,\ 792 f_loads,f_stores,f_loads,f_stores,fmov")] 793) 794 795(define_insn "*movdf_aarch64" 796 [(set (match_operand:DF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r") 797 (match_operand:DF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))] 798 "TARGET_FLOAT && (register_operand (operands[0], DFmode) 799 || register_operand (operands[1], DFmode))" 800 "@ 801 fmov\\t%d0, %x1 802 fmov\\t%x0, %d1 803 fmov\\t%d0, %d1 804 fmov\\t%d0, %1 805 ldr\\t%d0, %1 806 str\\t%d1, %0 807 ldr\\t%x0, %1 808 str\\t%x1, %0 809 mov\\t%x0, %x1" 810 [(set_attr "type" "f_mcr,f_mrc,fmov,fconstd,\ 811 f_loadd,f_stored,f_loadd,f_stored,mov_reg")] 812) 813 814(define_expand "movtf" 815 [(set (match_operand:TF 0 "nonimmediate_operand" "") 816 (match_operand:TF 1 "general_operand" ""))] 817 "" 818 " 819 if (!TARGET_FLOAT) 820 { 821 sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\"); 822 FAIL; 823 } 824 825 if (GET_CODE (operands[0]) == MEM) 826 operands[1] = force_reg (TFmode, operands[1]); 827 " 828) 829 830(define_insn "*movtf_aarch64" 831 [(set (match_operand:TF 0 832 "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Ump") 833 (match_operand:TF 1 834 "general_operand" " w,?r, ?r,w ,Y,Y ,m,w,Ump,?rY"))] 835 "TARGET_FLOAT && (register_operand (operands[0], TFmode) 836 || register_operand (operands[1], TFmode))" 837 "@ 838 orr\\t%0.16b, %1.16b, %1.16b 839 # 840 # 841 # 842 movi\\t%0.2d, #0 843 fmov\\t%s0, wzr 844 ldr\\t%q0, %1 845 str\\t%q1, %0 846 ldp\\t%0, %H0, %1 847 stp\\t%1, %H1, %0" 848 [(set_attr "type" "logic_reg,multiple,f_mcr,f_mrc,fconstd,fconstd,\ 849 f_loadd,f_stored,neon_load1_2reg,neon_store1_2reg") 850 (set_attr "length" "4,8,8,8,4,4,4,4,4,4") 851 (set_attr "fp" "*,*,yes,yes,*,yes,yes,yes,*,*") 852 (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*")] 853) 854 855(define_split 856 [(set (match_operand:TF 0 "register_operand" "") 857 (match_operand:TF 1 "aarch64_reg_or_imm" ""))] 858 "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])" 859 [(const_int 0)] 860 { 861 aarch64_split_128bit_move (operands[0], operands[1]); 862 DONE; 863 } 864) 865 866;; Operands 1 and 3 are tied together by the final condition; so we allow 867;; fairly lax checking on the second memory operation. 868(define_insn "load_pair<mode>" 869 [(set (match_operand:GPI 0 "register_operand" "=r") 870 (match_operand:GPI 1 "aarch64_mem_pair_operand" "Ump")) 871 (set (match_operand:GPI 2 "register_operand" "=r") 872 (match_operand:GPI 3 "memory_operand" "m"))] 873 "rtx_equal_p (XEXP (operands[3], 0), 874 plus_constant (Pmode, 875 XEXP (operands[1], 0), 876 GET_MODE_SIZE (<MODE>mode)))" 877 "ldp\\t%<w>0, %<w>2, %1" 878 [(set_attr "type" "load2")] 879) 880 881;; Operands 0 and 2 are tied together by the final condition; so we allow 882;; fairly lax checking on the second memory operation. 883(define_insn "store_pair<mode>" 884 [(set (match_operand:GPI 0 "aarch64_mem_pair_operand" "=Ump") 885 (match_operand:GPI 1 "register_operand" "r")) 886 (set (match_operand:GPI 2 "memory_operand" "=m") 887 (match_operand:GPI 3 "register_operand" "r"))] 888 "rtx_equal_p (XEXP (operands[2], 0), 889 plus_constant (Pmode, 890 XEXP (operands[0], 0), 891 GET_MODE_SIZE (<MODE>mode)))" 892 "stp\\t%<w>1, %<w>3, %0" 893 [(set_attr "type" "store2")] 894) 895 896;; Operands 1 and 3 are tied together by the final condition; so we allow 897;; fairly lax checking on the second memory operation. 898(define_insn "load_pair<mode>" 899 [(set (match_operand:GPF 0 "register_operand" "=w") 900 (match_operand:GPF 1 "aarch64_mem_pair_operand" "Ump")) 901 (set (match_operand:GPF 2 "register_operand" "=w") 902 (match_operand:GPF 3 "memory_operand" "m"))] 903 "rtx_equal_p (XEXP (operands[3], 0), 904 plus_constant (Pmode, 905 XEXP (operands[1], 0), 906 GET_MODE_SIZE (<MODE>mode)))" 907 "ldp\\t%<w>0, %<w>2, %1" 908 [(set_attr "type" "neon_load1_2reg<q>")] 909) 910 911;; Operands 0 and 2 are tied together by the final condition; so we allow 912;; fairly lax checking on the second memory operation. 913(define_insn "store_pair<mode>" 914 [(set (match_operand:GPF 0 "aarch64_mem_pair_operand" "=Ump") 915 (match_operand:GPF 1 "register_operand" "w")) 916 (set (match_operand:GPF 2 "memory_operand" "=m") 917 (match_operand:GPF 3 "register_operand" "w"))] 918 "rtx_equal_p (XEXP (operands[2], 0), 919 plus_constant (Pmode, 920 XEXP (operands[0], 0), 921 GET_MODE_SIZE (<MODE>mode)))" 922 "stp\\t%<w>1, %<w>3, %0" 923 [(set_attr "type" "neon_store1_2reg<q>")] 924) 925 926;; Load pair with writeback. This is primarily used in function epilogues 927;; when restoring [fp,lr] 928(define_insn "loadwb_pair<GPI:mode>_<P:mode>" 929 [(parallel 930 [(set (match_operand:P 0 "register_operand" "=k") 931 (plus:P (match_operand:P 1 "register_operand" "0") 932 (match_operand:P 4 "const_int_operand" "n"))) 933 (set (match_operand:GPI 2 "register_operand" "=r") 934 (mem:GPI (plus:P (match_dup 1) 935 (match_dup 4)))) 936 (set (match_operand:GPI 3 "register_operand" "=r") 937 (mem:GPI (plus:P (match_dup 1) 938 (match_operand:P 5 "const_int_operand" "n"))))])] 939 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)" 940 "ldp\\t%<w>2, %<w>3, [%1], %4" 941 [(set_attr "type" "load2")] 942) 943 944;; Store pair with writeback. This is primarily used in function prologues 945;; when saving [fp,lr] 946(define_insn "storewb_pair<GPI:mode>_<P:mode>" 947 [(parallel 948 [(set (match_operand:P 0 "register_operand" "=&k") 949 (plus:P (match_operand:P 1 "register_operand" "0") 950 (match_operand:P 4 "const_int_operand" "n"))) 951 (set (mem:GPI (plus:P (match_dup 0) 952 (match_dup 4))) 953 (match_operand:GPI 2 "register_operand" "r")) 954 (set (mem:GPI (plus:P (match_dup 0) 955 (match_operand:P 5 "const_int_operand" "n"))) 956 (match_operand:GPI 3 "register_operand" "r"))])] 957 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)" 958 "stp\\t%<w>2, %<w>3, [%0, %4]!" 959 [(set_attr "type" "store2")] 960) 961 962;; ------------------------------------------------------------------- 963;; Sign/Zero extension 964;; ------------------------------------------------------------------- 965 966(define_expand "<optab>sidi2" 967 [(set (match_operand:DI 0 "register_operand") 968 (ANY_EXTEND:DI (match_operand:SI 1 "nonimmediate_operand")))] 969 "" 970) 971 972(define_insn "*extendsidi2_aarch64" 973 [(set (match_operand:DI 0 "register_operand" "=r,r") 974 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))] 975 "" 976 "@ 977 sxtw\t%0, %w1 978 ldrsw\t%0, %1" 979 [(set_attr "type" "extend,load1")] 980) 981 982(define_insn "*zero_extendsidi2_aarch64" 983 [(set (match_operand:DI 0 "register_operand" "=r,r") 984 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))] 985 "" 986 "@ 987 uxtw\t%0, %w1 988 ldr\t%w0, %1" 989 [(set_attr "type" "extend,load1")] 990) 991 992(define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2" 993 [(set (match_operand:GPI 0 "register_operand") 994 (ANY_EXTEND:GPI (match_operand:SHORT 1 "nonimmediate_operand")))] 995 "" 996) 997 998(define_insn "*extend<SHORT:mode><GPI:mode>2_aarch64" 999 [(set (match_operand:GPI 0 "register_operand" "=r,r") 1000 (sign_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))] 1001 "" 1002 "@ 1003 sxt<SHORT:size>\t%<GPI:w>0, %w1 1004 ldrs<SHORT:size>\t%<GPI:w>0, %1" 1005 [(set_attr "type" "extend,load1")] 1006) 1007 1008(define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64" 1009 [(set (match_operand:GPI 0 "register_operand" "=r,r,*w") 1010 (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m,m")))] 1011 "" 1012 "@ 1013 uxt<SHORT:size>\t%<GPI:w>0, %w1 1014 ldr<SHORT:size>\t%w0, %1 1015 ldr\t%<SHORT:size>0, %1" 1016 [(set_attr "type" "extend,load1,load1")] 1017) 1018 1019(define_expand "<optab>qihi2" 1020 [(set (match_operand:HI 0 "register_operand") 1021 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand")))] 1022 "" 1023) 1024 1025(define_insn "*<optab>qihi2_aarch64" 1026 [(set (match_operand:HI 0 "register_operand" "=r,r") 1027 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))] 1028 "" 1029 "@ 1030 <su>xtb\t%w0, %w1 1031 <ldrxt>b\t%w0, %1" 1032 [(set_attr "type" "extend,load1")] 1033) 1034 1035;; ------------------------------------------------------------------- 1036;; Simple arithmetic 1037;; ------------------------------------------------------------------- 1038 1039(define_expand "add<mode>3" 1040 [(set 1041 (match_operand:GPI 0 "register_operand" "") 1042 (plus:GPI (match_operand:GPI 1 "register_operand" "") 1043 (match_operand:GPI 2 "aarch64_pluslong_operand" "")))] 1044 "" 1045 " 1046 if (! aarch64_plus_operand (operands[2], VOIDmode)) 1047 { 1048 rtx subtarget = ((optimize && can_create_pseudo_p ()) 1049 ? gen_reg_rtx (<MODE>mode) : operands[0]); 1050 HOST_WIDE_INT imm = INTVAL (operands[2]); 1051 1052 if (imm < 0) 1053 imm = -(-imm & ~0xfff); 1054 else 1055 imm &= ~0xfff; 1056 1057 emit_insn (gen_add<mode>3 (subtarget, operands[1], GEN_INT (imm))); 1058 operands[1] = subtarget; 1059 operands[2] = GEN_INT (INTVAL (operands[2]) - imm); 1060 } 1061 " 1062) 1063 1064(define_insn "*addsi3_aarch64" 1065 [(set 1066 (match_operand:SI 0 "register_operand" "=rk,rk,rk") 1067 (plus:SI 1068 (match_operand:SI 1 "register_operand" "%rk,rk,rk") 1069 (match_operand:SI 2 "aarch64_plus_operand" "I,r,J")))] 1070 "" 1071 "@ 1072 add\\t%w0, %w1, %2 1073 add\\t%w0, %w1, %w2 1074 sub\\t%w0, %w1, #%n2" 1075 [(set_attr "type" "alu_imm,alu_reg,alu_imm")] 1076) 1077 1078;; zero_extend version of above 1079(define_insn "*addsi3_aarch64_uxtw" 1080 [(set 1081 (match_operand:DI 0 "register_operand" "=rk,rk,rk") 1082 (zero_extend:DI 1083 (plus:SI (match_operand:SI 1 "register_operand" "%rk,rk,rk") 1084 (match_operand:SI 2 "aarch64_plus_operand" "I,r,J"))))] 1085 "" 1086 "@ 1087 add\\t%w0, %w1, %2 1088 add\\t%w0, %w1, %w2 1089 sub\\t%w0, %w1, #%n2" 1090 [(set_attr "type" "alu_imm,alu_reg,alu_imm")] 1091) 1092 1093(define_insn "*adddi3_aarch64" 1094 [(set 1095 (match_operand:DI 0 "register_operand" "=rk,rk,rk,!w") 1096 (plus:DI 1097 (match_operand:DI 1 "register_operand" "%rk,rk,rk,!w") 1098 (match_operand:DI 2 "aarch64_plus_operand" "I,r,J,!w")))] 1099 "" 1100 "@ 1101 add\\t%x0, %x1, %2 1102 add\\t%x0, %x1, %x2 1103 sub\\t%x0, %x1, #%n2 1104 add\\t%d0, %d1, %d2" 1105 [(set_attr "type" "alu_imm,alu_reg,alu_imm,neon_add") 1106 (set_attr "simd" "*,*,*,yes")] 1107) 1108 1109(define_insn "*add<mode>3_compare0" 1110 [(set (reg:CC_NZ CC_REGNUM) 1111 (compare:CC_NZ 1112 (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r,r") 1113 (match_operand:GPI 2 "aarch64_plus_operand" "r,I,J")) 1114 (const_int 0))) 1115 (set (match_operand:GPI 0 "register_operand" "=r,r,r") 1116 (plus:GPI (match_dup 1) (match_dup 2)))] 1117 "" 1118 "@ 1119 adds\\t%<w>0, %<w>1, %<w>2 1120 adds\\t%<w>0, %<w>1, %<w>2 1121 subs\\t%<w>0, %<w>1, #%n2" 1122 [(set_attr "type" "alus_reg,alus_imm,alus_imm")] 1123) 1124 1125;; zero_extend version of above 1126(define_insn "*addsi3_compare0_uxtw" 1127 [(set (reg:CC_NZ CC_REGNUM) 1128 (compare:CC_NZ 1129 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,r") 1130 (match_operand:SI 2 "aarch64_plus_operand" "r,I,J")) 1131 (const_int 0))) 1132 (set (match_operand:DI 0 "register_operand" "=r,r,r") 1133 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] 1134 "" 1135 "@ 1136 adds\\t%w0, %w1, %w2 1137 adds\\t%w0, %w1, %w2 1138 subs\\t%w0, %w1, #%n2" 1139 [(set_attr "type" "alus_reg,alus_imm,alus_imm")] 1140) 1141 1142(define_insn "*adds_mul_imm_<mode>" 1143 [(set (reg:CC_NZ CC_REGNUM) 1144 (compare:CC_NZ 1145 (plus:GPI (mult:GPI 1146 (match_operand:GPI 1 "register_operand" "r") 1147 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n")) 1148 (match_operand:GPI 3 "register_operand" "r")) 1149 (const_int 0))) 1150 (set (match_operand:GPI 0 "register_operand" "=r") 1151 (plus:GPI (mult:GPI (match_dup 1) (match_dup 2)) 1152 (match_dup 3)))] 1153 "" 1154 "adds\\t%<w>0, %<w>3, %<w>1, lsl %p2" 1155 [(set_attr "type" "alus_shift_imm")] 1156) 1157 1158(define_insn "*subs_mul_imm_<mode>" 1159 [(set (reg:CC_NZ CC_REGNUM) 1160 (compare:CC_NZ 1161 (minus:GPI (match_operand:GPI 1 "register_operand" "r") 1162 (mult:GPI 1163 (match_operand:GPI 2 "register_operand" "r") 1164 (match_operand:QI 3 "aarch64_pwr_2_<mode>" "n"))) 1165 (const_int 0))) 1166 (set (match_operand:GPI 0 "register_operand" "=r") 1167 (minus:GPI (match_dup 1) 1168 (mult:GPI (match_dup 2) (match_dup 3))))] 1169 "" 1170 "subs\\t%<w>0, %<w>1, %<w>2, lsl %p3" 1171 [(set_attr "type" "alus_shift_imm")] 1172) 1173 1174(define_insn "*adds_<optab><ALLX:mode>_<GPI:mode>" 1175 [(set (reg:CC_NZ CC_REGNUM) 1176 (compare:CC_NZ 1177 (plus:GPI 1178 (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r")) 1179 (match_operand:GPI 2 "register_operand" "r")) 1180 (const_int 0))) 1181 (set (match_operand:GPI 0 "register_operand" "=r") 1182 (plus:GPI (ANY_EXTEND:GPI (match_dup 1)) (match_dup 2)))] 1183 "" 1184 "adds\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>" 1185 [(set_attr "type" "alus_ext")] 1186) 1187 1188(define_insn "*subs_<optab><ALLX:mode>_<GPI:mode>" 1189 [(set (reg:CC_NZ CC_REGNUM) 1190 (compare:CC_NZ 1191 (minus:GPI (match_operand:GPI 1 "register_operand" "r") 1192 (ANY_EXTEND:GPI 1193 (match_operand:ALLX 2 "register_operand" "r"))) 1194 (const_int 0))) 1195 (set (match_operand:GPI 0 "register_operand" "=r") 1196 (minus:GPI (match_dup 1) (ANY_EXTEND:GPI (match_dup 2))))] 1197 "" 1198 "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>" 1199 [(set_attr "type" "alus_ext")] 1200) 1201 1202(define_insn "*adds_<optab><mode>_multp2" 1203 [(set (reg:CC_NZ CC_REGNUM) 1204 (compare:CC_NZ 1205 (plus:GPI (ANY_EXTRACT:GPI 1206 (mult:GPI (match_operand:GPI 1 "register_operand" "r") 1207 (match_operand 2 "aarch64_pwr_imm3" "Up3")) 1208 (match_operand 3 "const_int_operand" "n") 1209 (const_int 0)) 1210 (match_operand:GPI 4 "register_operand" "r")) 1211 (const_int 0))) 1212 (set (match_operand:GPI 0 "register_operand" "=r") 1213 (plus:GPI (ANY_EXTRACT:GPI (mult:GPI (match_dup 1) (match_dup 2)) 1214 (match_dup 3) 1215 (const_int 0)) 1216 (match_dup 4)))] 1217 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])" 1218 "adds\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2" 1219 [(set_attr "type" "alus_ext")] 1220) 1221 1222(define_insn "*subs_<optab><mode>_multp2" 1223 [(set (reg:CC_NZ CC_REGNUM) 1224 (compare:CC_NZ 1225 (minus:GPI (match_operand:GPI 4 "register_operand" "r") 1226 (ANY_EXTRACT:GPI 1227 (mult:GPI (match_operand:GPI 1 "register_operand" "r") 1228 (match_operand 2 "aarch64_pwr_imm3" "Up3")) 1229 (match_operand 3 "const_int_operand" "n") 1230 (const_int 0))) 1231 (const_int 0))) 1232 (set (match_operand:GPI 0 "register_operand" "=r") 1233 (minus:GPI (match_dup 4) (ANY_EXTRACT:GPI 1234 (mult:GPI (match_dup 1) (match_dup 2)) 1235 (match_dup 3) 1236 (const_int 0))))] 1237 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])" 1238 "subs\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2" 1239 [(set_attr "type" "alus_ext")] 1240) 1241 1242(define_insn "*add<mode>3nr_compare0" 1243 [(set (reg:CC_NZ CC_REGNUM) 1244 (compare:CC_NZ 1245 (plus:GPI (match_operand:GPI 0 "register_operand" "%r,r,r") 1246 (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")) 1247 (const_int 0)))] 1248 "" 1249 "@ 1250 cmn\\t%<w>0, %<w>1 1251 cmn\\t%<w>0, %<w>1 1252 cmp\\t%<w>0, #%n1" 1253 [(set_attr "type" "alus_reg,alus_imm,alus_imm")] 1254) 1255 1256(define_insn "*compare_neg<mode>" 1257 [(set (reg:CC_Z CC_REGNUM) 1258 (compare:CC_Z 1259 (neg:GPI (match_operand:GPI 0 "register_operand" "r")) 1260 (match_operand:GPI 1 "register_operand" "r")))] 1261 "" 1262 "cmn\\t%<w>1, %<w>0" 1263 [(set_attr "type" "alus_reg")] 1264) 1265 1266(define_insn "*add_<shift>_<mode>" 1267 [(set (match_operand:GPI 0 "register_operand" "=r") 1268 (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r") 1269 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")) 1270 (match_operand:GPI 3 "register_operand" "r")))] 1271 "" 1272 "add\\t%<w>0, %<w>3, %<w>1, <shift> %2" 1273 [(set_attr "type" "alu_shift_imm")] 1274) 1275 1276;; zero_extend version of above 1277(define_insn "*add_<shift>_si_uxtw" 1278 [(set (match_operand:DI 0 "register_operand" "=r") 1279 (zero_extend:DI 1280 (plus:SI (ASHIFT:SI (match_operand:SI 1 "register_operand" "r") 1281 (match_operand:QI 2 "aarch64_shift_imm_si" "n")) 1282 (match_operand:SI 3 "register_operand" "r"))))] 1283 "" 1284 "add\\t%w0, %w3, %w1, <shift> %2" 1285 [(set_attr "type" "alu_shift_imm")] 1286) 1287 1288(define_insn "*add_mul_imm_<mode>" 1289 [(set (match_operand:GPI 0 "register_operand" "=r") 1290 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r") 1291 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n")) 1292 (match_operand:GPI 3 "register_operand" "r")))] 1293 "" 1294 "add\\t%<w>0, %<w>3, %<w>1, lsl %p2" 1295 [(set_attr "type" "alu_shift_imm")] 1296) 1297 1298(define_insn "*add_<optab><ALLX:mode>_<GPI:mode>" 1299 [(set (match_operand:GPI 0 "register_operand" "=rk") 1300 (plus:GPI (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r")) 1301 (match_operand:GPI 2 "register_operand" "r")))] 1302 "" 1303 "add\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>" 1304 [(set_attr "type" "alu_ext")] 1305) 1306 1307;; zero_extend version of above 1308(define_insn "*add_<optab><SHORT:mode>_si_uxtw" 1309 [(set (match_operand:DI 0 "register_operand" "=rk") 1310 (zero_extend:DI 1311 (plus:SI (ANY_EXTEND:SI (match_operand:SHORT 1 "register_operand" "r")) 1312 (match_operand:GPI 2 "register_operand" "r"))))] 1313 "" 1314 "add\\t%w0, %w2, %w1, <su>xt<SHORT:size>" 1315 [(set_attr "type" "alu_ext")] 1316) 1317 1318(define_insn "*add_<optab><ALLX:mode>_shft_<GPI:mode>" 1319 [(set (match_operand:GPI 0 "register_operand" "=rk") 1320 (plus:GPI (ashift:GPI (ANY_EXTEND:GPI 1321 (match_operand:ALLX 1 "register_operand" "r")) 1322 (match_operand 2 "aarch64_imm3" "Ui3")) 1323 (match_operand:GPI 3 "register_operand" "r")))] 1324 "" 1325 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2" 1326 [(set_attr "type" "alu_ext")] 1327) 1328 1329;; zero_extend version of above 1330(define_insn "*add_<optab><SHORT:mode>_shft_si_uxtw" 1331 [(set (match_operand:DI 0 "register_operand" "=rk") 1332 (zero_extend:DI 1333 (plus:SI (ashift:SI (ANY_EXTEND:SI 1334 (match_operand:SHORT 1 "register_operand" "r")) 1335 (match_operand 2 "aarch64_imm3" "Ui3")) 1336 (match_operand:SI 3 "register_operand" "r"))))] 1337 "" 1338 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %2" 1339 [(set_attr "type" "alu_ext")] 1340) 1341 1342(define_insn "*add_<optab><ALLX:mode>_mult_<GPI:mode>" 1343 [(set (match_operand:GPI 0 "register_operand" "=rk") 1344 (plus:GPI (mult:GPI (ANY_EXTEND:GPI 1345 (match_operand:ALLX 1 "register_operand" "r")) 1346 (match_operand 2 "aarch64_pwr_imm3" "Up3")) 1347 (match_operand:GPI 3 "register_operand" "r")))] 1348 "" 1349 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %p2" 1350 [(set_attr "type" "alu_ext")] 1351) 1352 1353;; zero_extend version of above 1354(define_insn "*add_<optab><SHORT:mode>_mult_si_uxtw" 1355 [(set (match_operand:DI 0 "register_operand" "=rk") 1356 (zero_extend:DI (plus:SI (mult:SI (ANY_EXTEND:SI 1357 (match_operand:SHORT 1 "register_operand" "r")) 1358 (match_operand 2 "aarch64_pwr_imm3" "Up3")) 1359 (match_operand:SI 3 "register_operand" "r"))))] 1360 "" 1361 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %p2" 1362 [(set_attr "type" "alu_ext")] 1363) 1364 1365(define_insn "*add_<optab><mode>_multp2" 1366 [(set (match_operand:GPI 0 "register_operand" "=rk") 1367 (plus:GPI (ANY_EXTRACT:GPI 1368 (mult:GPI (match_operand:GPI 1 "register_operand" "r") 1369 (match_operand 2 "aarch64_pwr_imm3" "Up3")) 1370 (match_operand 3 "const_int_operand" "n") 1371 (const_int 0)) 1372 (match_operand:GPI 4 "register_operand" "r")))] 1373 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])" 1374 "add\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2" 1375 [(set_attr "type" "alu_ext")] 1376) 1377 1378;; zero_extend version of above 1379(define_insn "*add_<optab>si_multp2_uxtw" 1380 [(set (match_operand:DI 0 "register_operand" "=rk") 1381 (zero_extend:DI 1382 (plus:SI (ANY_EXTRACT:SI 1383 (mult:SI (match_operand:SI 1 "register_operand" "r") 1384 (match_operand 2 "aarch64_pwr_imm3" "Up3")) 1385 (match_operand 3 "const_int_operand" "n") 1386 (const_int 0)) 1387 (match_operand:SI 4 "register_operand" "r"))))] 1388 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])" 1389 "add\\t%w0, %w4, %w1, <su>xt%e3 %p2" 1390 [(set_attr "type" "alu_ext")] 1391) 1392 1393(define_insn "*add<mode>3_carryin" 1394 [(set 1395 (match_operand:GPI 0 "register_operand" "=r") 1396 (plus:GPI (geu:GPI (reg:CC CC_REGNUM) (const_int 0)) 1397 (plus:GPI 1398 (match_operand:GPI 1 "register_operand" "r") 1399 (match_operand:GPI 2 "register_operand" "r"))))] 1400 "" 1401 "adc\\t%<w>0, %<w>1, %<w>2" 1402 [(set_attr "type" "adc_reg")] 1403) 1404 1405;; zero_extend version of above 1406(define_insn "*addsi3_carryin_uxtw" 1407 [(set 1408 (match_operand:DI 0 "register_operand" "=r") 1409 (zero_extend:DI 1410 (plus:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0)) 1411 (plus:SI 1412 (match_operand:SI 1 "register_operand" "r") 1413 (match_operand:SI 2 "register_operand" "r")))))] 1414 "" 1415 "adc\\t%w0, %w1, %w2" 1416 [(set_attr "type" "adc_reg")] 1417) 1418 1419(define_insn "*add<mode>3_carryin_alt1" 1420 [(set 1421 (match_operand:GPI 0 "register_operand" "=r") 1422 (plus:GPI (plus:GPI 1423 (match_operand:GPI 1 "register_operand" "r") 1424 (match_operand:GPI 2 "register_operand" "r")) 1425 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))))] 1426 "" 1427 "adc\\t%<w>0, %<w>1, %<w>2" 1428 [(set_attr "type" "adc_reg")] 1429) 1430 1431;; zero_extend version of above 1432(define_insn "*addsi3_carryin_alt1_uxtw" 1433 [(set 1434 (match_operand:DI 0 "register_operand" "=r") 1435 (zero_extend:DI 1436 (plus:SI (plus:SI 1437 (match_operand:SI 1 "register_operand" "r") 1438 (match_operand:SI 2 "register_operand" "r")) 1439 (geu:SI (reg:CC CC_REGNUM) (const_int 0)))))] 1440 "" 1441 "adc\\t%w0, %w1, %w2" 1442 [(set_attr "type" "adc_reg")] 1443) 1444 1445(define_insn "*add<mode>3_carryin_alt2" 1446 [(set 1447 (match_operand:GPI 0 "register_operand" "=r") 1448 (plus:GPI (plus:GPI 1449 (geu:GPI (reg:CC CC_REGNUM) (const_int 0)) 1450 (match_operand:GPI 1 "register_operand" "r")) 1451 (match_operand:GPI 2 "register_operand" "r")))] 1452 "" 1453 "adc\\t%<w>0, %<w>1, %<w>2" 1454 [(set_attr "type" "adc_reg")] 1455) 1456 1457;; zero_extend version of above 1458(define_insn "*addsi3_carryin_alt2_uxtw" 1459 [(set 1460 (match_operand:DI 0 "register_operand" "=r") 1461 (zero_extend:DI 1462 (plus:SI (plus:SI 1463 (geu:SI (reg:CC CC_REGNUM) (const_int 0)) 1464 (match_operand:SI 1 "register_operand" "r")) 1465 (match_operand:SI 2 "register_operand" "r"))))] 1466 "" 1467 "adc\\t%w0, %w1, %w2" 1468 [(set_attr "type" "adc_reg")] 1469) 1470 1471(define_insn "*add<mode>3_carryin_alt3" 1472 [(set 1473 (match_operand:GPI 0 "register_operand" "=r") 1474 (plus:GPI (plus:GPI 1475 (geu:GPI (reg:CC CC_REGNUM) (const_int 0)) 1476 (match_operand:GPI 2 "register_operand" "r")) 1477 (match_operand:GPI 1 "register_operand" "r")))] 1478 "" 1479 "adc\\t%<w>0, %<w>1, %<w>2" 1480 [(set_attr "type" "adc_reg")] 1481) 1482 1483;; zero_extend version of above 1484(define_insn "*addsi3_carryin_alt3_uxtw" 1485 [(set 1486 (match_operand:DI 0 "register_operand" "=r") 1487 (zero_extend:DI 1488 (plus:SI (plus:SI 1489 (geu:SI (reg:CC CC_REGNUM) (const_int 0)) 1490 (match_operand:SI 2 "register_operand" "r")) 1491 (match_operand:SI 1 "register_operand" "r"))))] 1492 "" 1493 "adc\\t%w0, %w1, %w2" 1494 [(set_attr "type" "adc_reg")] 1495) 1496 1497(define_insn "*add_uxt<mode>_multp2" 1498 [(set (match_operand:GPI 0 "register_operand" "=rk") 1499 (plus:GPI (and:GPI 1500 (mult:GPI (match_operand:GPI 1 "register_operand" "r") 1501 (match_operand 2 "aarch64_pwr_imm3" "Up3")) 1502 (match_operand 3 "const_int_operand" "n")) 1503 (match_operand:GPI 4 "register_operand" "r")))] 1504 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0" 1505 "* 1506 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), 1507 INTVAL (operands[3]))); 1508 return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";" 1509 [(set_attr "type" "alu_ext")] 1510) 1511 1512;; zero_extend version of above 1513(define_insn "*add_uxtsi_multp2_uxtw" 1514 [(set (match_operand:DI 0 "register_operand" "=rk") 1515 (zero_extend:DI 1516 (plus:SI (and:SI 1517 (mult:SI (match_operand:SI 1 "register_operand" "r") 1518 (match_operand 2 "aarch64_pwr_imm3" "Up3")) 1519 (match_operand 3 "const_int_operand" "n")) 1520 (match_operand:SI 4 "register_operand" "r"))))] 1521 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0" 1522 "* 1523 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), 1524 INTVAL (operands[3]))); 1525 return \"add\t%w0, %w4, %w1, uxt%e3 %p2\";" 1526 [(set_attr "type" "alu_ext")] 1527) 1528 1529(define_insn "subsi3" 1530 [(set (match_operand:SI 0 "register_operand" "=rk") 1531 (minus:SI (match_operand:SI 1 "register_operand" "r") 1532 (match_operand:SI 2 "register_operand" "r")))] 1533 "" 1534 "sub\\t%w0, %w1, %w2" 1535 [(set_attr "type" "alu_reg")] 1536) 1537 1538;; zero_extend version of above 1539(define_insn "*subsi3_uxtw" 1540 [(set (match_operand:DI 0 "register_operand" "=rk") 1541 (zero_extend:DI 1542 (minus:SI (match_operand:SI 1 "register_operand" "r") 1543 (match_operand:SI 2 "register_operand" "r"))))] 1544 "" 1545 "sub\\t%w0, %w1, %w2" 1546 [(set_attr "type" "alu_reg")] 1547) 1548 1549(define_insn "subdi3" 1550 [(set (match_operand:DI 0 "register_operand" "=rk,!w") 1551 (minus:DI (match_operand:DI 1 "register_operand" "r,!w") 1552 (match_operand:DI 2 "register_operand" "r,!w")))] 1553 "" 1554 "@ 1555 sub\\t%x0, %x1, %x2 1556 sub\\t%d0, %d1, %d2" 1557 [(set_attr "type" "alu_reg, neon_sub") 1558 (set_attr "simd" "*,yes")] 1559) 1560 1561 1562(define_insn "*sub<mode>3_compare0" 1563 [(set (reg:CC_NZ CC_REGNUM) 1564 (compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r") 1565 (match_operand:GPI 2 "register_operand" "r")) 1566 (const_int 0))) 1567 (set (match_operand:GPI 0 "register_operand" "=r") 1568 (minus:GPI (match_dup 1) (match_dup 2)))] 1569 "" 1570 "subs\\t%<w>0, %<w>1, %<w>2" 1571 [(set_attr "type" "alus_reg")] 1572) 1573 1574;; zero_extend version of above 1575(define_insn "*subsi3_compare0_uxtw" 1576 [(set (reg:CC_NZ CC_REGNUM) 1577 (compare:CC_NZ (minus:SI (match_operand:SI 1 "register_operand" "r") 1578 (match_operand:SI 2 "register_operand" "r")) 1579 (const_int 0))) 1580 (set (match_operand:DI 0 "register_operand" "=r") 1581 (zero_extend:DI (minus:SI (match_dup 1) (match_dup 2))))] 1582 "" 1583 "subs\\t%w0, %w1, %w2" 1584 [(set_attr "type" "alus_reg")] 1585) 1586 1587(define_insn "*sub_<shift>_<mode>" 1588 [(set (match_operand:GPI 0 "register_operand" "=r") 1589 (minus:GPI (match_operand:GPI 3 "register_operand" "r") 1590 (ASHIFT:GPI 1591 (match_operand:GPI 1 "register_operand" "r") 1592 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))] 1593 "" 1594 "sub\\t%<w>0, %<w>3, %<w>1, <shift> %2" 1595 [(set_attr "type" "alu_shift_imm")] 1596) 1597 1598;; zero_extend version of above 1599(define_insn "*sub_<shift>_si_uxtw" 1600 [(set (match_operand:DI 0 "register_operand" "=r") 1601 (zero_extend:DI 1602 (minus:SI (match_operand:SI 3 "register_operand" "r") 1603 (ASHIFT:SI 1604 (match_operand:SI 1 "register_operand" "r") 1605 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))] 1606 "" 1607 "sub\\t%w0, %w3, %w1, <shift> %2" 1608 [(set_attr "type" "alu_shift_imm")] 1609) 1610 1611(define_insn "*sub_mul_imm_<mode>" 1612 [(set (match_operand:GPI 0 "register_operand" "=r") 1613 (minus:GPI (match_operand:GPI 3 "register_operand" "r") 1614 (mult:GPI 1615 (match_operand:GPI 1 "register_operand" "r") 1616 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))] 1617 "" 1618 "sub\\t%<w>0, %<w>3, %<w>1, lsl %p2" 1619 [(set_attr "type" "alu_shift_imm")] 1620) 1621 1622;; zero_extend version of above 1623(define_insn "*sub_mul_imm_si_uxtw" 1624 [(set (match_operand:DI 0 "register_operand" "=r") 1625 (zero_extend:DI 1626 (minus:SI (match_operand:SI 3 "register_operand" "r") 1627 (mult:SI 1628 (match_operand:SI 1 "register_operand" "r") 1629 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))] 1630 "" 1631 "sub\\t%w0, %w3, %w1, lsl %p2" 1632 [(set_attr "type" "alu_shift_imm")] 1633) 1634 1635(define_insn "*sub_<optab><ALLX:mode>_<GPI:mode>" 1636 [(set (match_operand:GPI 0 "register_operand" "=rk") 1637 (minus:GPI (match_operand:GPI 1 "register_operand" "r") 1638 (ANY_EXTEND:GPI 1639 (match_operand:ALLX 2 "register_operand" "r"))))] 1640 "" 1641 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>" 1642 [(set_attr "type" "alu_ext")] 1643) 1644 1645;; zero_extend version of above 1646(define_insn "*sub_<optab><SHORT:mode>_si_uxtw" 1647 [(set (match_operand:DI 0 "register_operand" "=rk") 1648 (zero_extend:DI 1649 (minus:SI (match_operand:SI 1 "register_operand" "r") 1650 (ANY_EXTEND:SI 1651 (match_operand:SHORT 2 "register_operand" "r")))))] 1652 "" 1653 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size>" 1654 [(set_attr "type" "alu_ext")] 1655) 1656 1657(define_insn "*sub_<optab><ALLX:mode>_shft_<GPI:mode>" 1658 [(set (match_operand:GPI 0 "register_operand" "=rk") 1659 (minus:GPI (match_operand:GPI 1 "register_operand" "r") 1660 (ashift:GPI (ANY_EXTEND:GPI 1661 (match_operand:ALLX 2 "register_operand" "r")) 1662 (match_operand 3 "aarch64_imm3" "Ui3"))))] 1663 "" 1664 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3" 1665 [(set_attr "type" "alu_ext")] 1666) 1667 1668;; zero_extend version of above 1669(define_insn "*sub_<optab><SHORT:mode>_shft_si_uxtw" 1670 [(set (match_operand:DI 0 "register_operand" "=rk") 1671 (zero_extend:DI 1672 (minus:SI (match_operand:SI 1 "register_operand" "r") 1673 (ashift:SI (ANY_EXTEND:SI 1674 (match_operand:SHORT 2 "register_operand" "r")) 1675 (match_operand 3 "aarch64_imm3" "Ui3")))))] 1676 "" 1677 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size> %3" 1678 [(set_attr "type" "alu_ext")] 1679) 1680 1681(define_insn "*sub_<optab><mode>_multp2" 1682 [(set (match_operand:GPI 0 "register_operand" "=rk") 1683 (minus:GPI (match_operand:GPI 4 "register_operand" "r") 1684 (ANY_EXTRACT:GPI 1685 (mult:GPI (match_operand:GPI 1 "register_operand" "r") 1686 (match_operand 2 "aarch64_pwr_imm3" "Up3")) 1687 (match_operand 3 "const_int_operand" "n") 1688 (const_int 0))))] 1689 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])" 1690 "sub\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2" 1691 [(set_attr "type" "alu_ext")] 1692) 1693 1694;; zero_extend version of above 1695(define_insn "*sub_<optab>si_multp2_uxtw" 1696 [(set (match_operand:DI 0 "register_operand" "=rk") 1697 (zero_extend:DI 1698 (minus:SI (match_operand:SI 4 "register_operand" "r") 1699 (ANY_EXTRACT:SI 1700 (mult:SI (match_operand:SI 1 "register_operand" "r") 1701 (match_operand 2 "aarch64_pwr_imm3" "Up3")) 1702 (match_operand 3 "const_int_operand" "n") 1703 (const_int 0)))))] 1704 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])" 1705 "sub\\t%w0, %w4, %w1, <su>xt%e3 %p2" 1706 [(set_attr "type" "alu_ext")] 1707) 1708 1709(define_insn "*sub<mode>3_carryin" 1710 [(set 1711 (match_operand:GPI 0 "register_operand" "=r") 1712 (minus:GPI (minus:GPI 1713 (match_operand:GPI 1 "register_operand" "r") 1714 (ltu:GPI (reg:CC CC_REGNUM) (const_int 0))) 1715 (match_operand:GPI 2 "register_operand" "r")))] 1716 "" 1717 "sbc\\t%<w>0, %<w>1, %<w>2" 1718 [(set_attr "type" "adc_reg")] 1719) 1720 1721;; zero_extend version of the above 1722(define_insn "*subsi3_carryin_uxtw" 1723 [(set 1724 (match_operand:DI 0 "register_operand" "=r") 1725 (zero_extend:DI 1726 (minus:SI (minus:SI 1727 (match_operand:SI 1 "register_operand" "r") 1728 (ltu:SI (reg:CC CC_REGNUM) (const_int 0))) 1729 (match_operand:SI 2 "register_operand" "r"))))] 1730 "" 1731 "sbc\\t%w0, %w1, %w2" 1732 [(set_attr "type" "adc_reg")] 1733) 1734 1735(define_insn "*sub_uxt<mode>_multp2" 1736 [(set (match_operand:GPI 0 "register_operand" "=rk") 1737 (minus:GPI (match_operand:GPI 4 "register_operand" "r") 1738 (and:GPI 1739 (mult:GPI (match_operand:GPI 1 "register_operand" "r") 1740 (match_operand 2 "aarch64_pwr_imm3" "Up3")) 1741 (match_operand 3 "const_int_operand" "n"))))] 1742 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0" 1743 "* 1744 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), 1745 INTVAL (operands[3]))); 1746 return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";" 1747 [(set_attr "type" "alu_ext")] 1748) 1749 1750;; zero_extend version of above 1751(define_insn "*sub_uxtsi_multp2_uxtw" 1752 [(set (match_operand:DI 0 "register_operand" "=rk") 1753 (zero_extend:DI 1754 (minus:SI (match_operand:SI 4 "register_operand" "r") 1755 (and:SI 1756 (mult:SI (match_operand:SI 1 "register_operand" "r") 1757 (match_operand 2 "aarch64_pwr_imm3" "Up3")) 1758 (match_operand 3 "const_int_operand" "n")))))] 1759 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0" 1760 "* 1761 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), 1762 INTVAL (operands[3]))); 1763 return \"sub\t%w0, %w4, %w1, uxt%e3 %p2\";" 1764 [(set_attr "type" "alu_ext")] 1765) 1766 1767(define_insn_and_split "absdi2" 1768 [(set (match_operand:DI 0 "register_operand" "=r,w") 1769 (abs:DI (match_operand:DI 1 "register_operand" "r,w"))) 1770 (clobber (match_scratch:DI 2 "=&r,X"))] 1771 "" 1772 "@ 1773 # 1774 abs\\t%d0, %d1" 1775 "reload_completed 1776 && GP_REGNUM_P (REGNO (operands[0])) 1777 && GP_REGNUM_P (REGNO (operands[1]))" 1778 [(const_int 0)] 1779 { 1780 emit_insn (gen_rtx_SET (VOIDmode, operands[2], 1781 gen_rtx_XOR (DImode, 1782 gen_rtx_ASHIFTRT (DImode, 1783 operands[1], 1784 GEN_INT (63)), 1785 operands[1]))); 1786 emit_insn (gen_rtx_SET (VOIDmode, 1787 operands[0], 1788 gen_rtx_MINUS (DImode, 1789 operands[2], 1790 gen_rtx_ASHIFTRT (DImode, 1791 operands[1], 1792 GEN_INT (63))))); 1793 DONE; 1794 } 1795 [(set_attr "type" "alu_reg")] 1796) 1797 1798(define_insn "neg<mode>2" 1799 [(set (match_operand:GPI 0 "register_operand" "=r,w") 1800 (neg:GPI (match_operand:GPI 1 "register_operand" "r,w")))] 1801 "" 1802 "@ 1803 neg\\t%<w>0, %<w>1 1804 neg\\t%<rtn>0<vas>, %<rtn>1<vas>" 1805 [(set_attr "type" "alu_reg, neon_neg<q>") 1806 (set_attr "simd" "*,yes")] 1807) 1808 1809;; zero_extend version of above 1810(define_insn "*negsi2_uxtw" 1811 [(set (match_operand:DI 0 "register_operand" "=r") 1812 (zero_extend:DI (neg:SI (match_operand:SI 1 "register_operand" "r"))))] 1813 "" 1814 "neg\\t%w0, %w1" 1815 [(set_attr "type" "alu_reg")] 1816) 1817 1818(define_insn "*ngc<mode>" 1819 [(set (match_operand:GPI 0 "register_operand" "=r") 1820 (minus:GPI (neg:GPI (ltu:GPI (reg:CC CC_REGNUM) (const_int 0))) 1821 (match_operand:GPI 1 "register_operand" "r")))] 1822 "" 1823 "ngc\\t%<w>0, %<w>1" 1824 [(set_attr "type" "adc_reg")] 1825) 1826 1827(define_insn "*ngcsi_uxtw" 1828 [(set (match_operand:DI 0 "register_operand" "=r") 1829 (zero_extend:DI 1830 (minus:SI (neg:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))) 1831 (match_operand:SI 1 "register_operand" "r"))))] 1832 "" 1833 "ngc\\t%w0, %w1" 1834 [(set_attr "type" "adc_reg")] 1835) 1836 1837(define_insn "*neg<mode>2_compare0" 1838 [(set (reg:CC_NZ CC_REGNUM) 1839 (compare:CC_NZ (neg:GPI (match_operand:GPI 1 "register_operand" "r")) 1840 (const_int 0))) 1841 (set (match_operand:GPI 0 "register_operand" "=r") 1842 (neg:GPI (match_dup 1)))] 1843 "" 1844 "negs\\t%<w>0, %<w>1" 1845 [(set_attr "type" "alus_reg")] 1846) 1847 1848;; zero_extend version of above 1849(define_insn "*negsi2_compare0_uxtw" 1850 [(set (reg:CC_NZ CC_REGNUM) 1851 (compare:CC_NZ (neg:SI (match_operand:SI 1 "register_operand" "r")) 1852 (const_int 0))) 1853 (set (match_operand:DI 0 "register_operand" "=r") 1854 (zero_extend:DI (neg:SI (match_dup 1))))] 1855 "" 1856 "negs\\t%w0, %w1" 1857 [(set_attr "type" "alus_reg")] 1858) 1859 1860(define_insn "*neg_<shift><mode>3_compare0" 1861 [(set (reg:CC_NZ CC_REGNUM) 1862 (compare:CC_NZ 1863 (neg:GPI (ASHIFT:GPI 1864 (match_operand:GPI 1 "register_operand" "r") 1865 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))) 1866 (const_int 0))) 1867 (set (match_operand:GPI 0 "register_operand" "=r") 1868 (neg:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))))] 1869 "" 1870 "negs\\t%<w>0, %<w>1, <shift> %2" 1871 [(set_attr "type" "alus_shift_imm")] 1872) 1873 1874(define_insn "*neg_<shift>_<mode>2" 1875 [(set (match_operand:GPI 0 "register_operand" "=r") 1876 (neg:GPI (ASHIFT:GPI 1877 (match_operand:GPI 1 "register_operand" "r") 1878 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))] 1879 "" 1880 "neg\\t%<w>0, %<w>1, <shift> %2" 1881 [(set_attr "type" "alu_shift_imm")] 1882) 1883 1884;; zero_extend version of above 1885(define_insn "*neg_<shift>_si2_uxtw" 1886 [(set (match_operand:DI 0 "register_operand" "=r") 1887 (zero_extend:DI 1888 (neg:SI (ASHIFT:SI 1889 (match_operand:SI 1 "register_operand" "r") 1890 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))] 1891 "" 1892 "neg\\t%w0, %w1, <shift> %2" 1893 [(set_attr "type" "alu_shift_imm")] 1894) 1895 1896(define_insn "*neg_mul_imm_<mode>2" 1897 [(set (match_operand:GPI 0 "register_operand" "=r") 1898 (neg:GPI (mult:GPI 1899 (match_operand:GPI 1 "register_operand" "r") 1900 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))] 1901 "" 1902 "neg\\t%<w>0, %<w>1, lsl %p2" 1903 [(set_attr "type" "alu_shift_imm")] 1904) 1905 1906;; zero_extend version of above 1907(define_insn "*neg_mul_imm_si2_uxtw" 1908 [(set (match_operand:DI 0 "register_operand" "=r") 1909 (zero_extend:DI 1910 (neg:SI (mult:SI 1911 (match_operand:SI 1 "register_operand" "r") 1912 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))] 1913 "" 1914 "neg\\t%w0, %w1, lsl %p2" 1915 [(set_attr "type" "alu_shift_imm")] 1916) 1917 1918(define_insn "mul<mode>3" 1919 [(set (match_operand:GPI 0 "register_operand" "=r") 1920 (mult:GPI (match_operand:GPI 1 "register_operand" "r") 1921 (match_operand:GPI 2 "register_operand" "r")))] 1922 "" 1923 "mul\\t%<w>0, %<w>1, %<w>2" 1924 [(set_attr "type" "mul")] 1925) 1926 1927;; zero_extend version of above 1928(define_insn "*mulsi3_uxtw" 1929 [(set (match_operand:DI 0 "register_operand" "=r") 1930 (zero_extend:DI 1931 (mult:SI (match_operand:SI 1 "register_operand" "r") 1932 (match_operand:SI 2 "register_operand" "r"))))] 1933 "" 1934 "mul\\t%w0, %w1, %w2" 1935 [(set_attr "type" "mul")] 1936) 1937 1938(define_insn "*madd<mode>" 1939 [(set (match_operand:GPI 0 "register_operand" "=r") 1940 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r") 1941 (match_operand:GPI 2 "register_operand" "r")) 1942 (match_operand:GPI 3 "register_operand" "r")))] 1943 "" 1944 "madd\\t%<w>0, %<w>1, %<w>2, %<w>3" 1945 [(set_attr "type" "mla")] 1946) 1947 1948;; zero_extend version of above 1949(define_insn "*maddsi_uxtw" 1950 [(set (match_operand:DI 0 "register_operand" "=r") 1951 (zero_extend:DI 1952 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r") 1953 (match_operand:SI 2 "register_operand" "r")) 1954 (match_operand:SI 3 "register_operand" "r"))))] 1955 "" 1956 "madd\\t%w0, %w1, %w2, %w3" 1957 [(set_attr "type" "mla")] 1958) 1959 1960(define_insn "*msub<mode>" 1961 [(set (match_operand:GPI 0 "register_operand" "=r") 1962 (minus:GPI (match_operand:GPI 3 "register_operand" "r") 1963 (mult:GPI (match_operand:GPI 1 "register_operand" "r") 1964 (match_operand:GPI 2 "register_operand" "r"))))] 1965 1966 "" 1967 "msub\\t%<w>0, %<w>1, %<w>2, %<w>3" 1968 [(set_attr "type" "mla")] 1969) 1970 1971;; zero_extend version of above 1972(define_insn "*msubsi_uxtw" 1973 [(set (match_operand:DI 0 "register_operand" "=r") 1974 (zero_extend:DI 1975 (minus:SI (match_operand:SI 3 "register_operand" "r") 1976 (mult:SI (match_operand:SI 1 "register_operand" "r") 1977 (match_operand:SI 2 "register_operand" "r")))))] 1978 1979 "" 1980 "msub\\t%w0, %w1, %w2, %w3" 1981 [(set_attr "type" "mla")] 1982) 1983 1984(define_insn "*mul<mode>_neg" 1985 [(set (match_operand:GPI 0 "register_operand" "=r") 1986 (mult:GPI (neg:GPI (match_operand:GPI 1 "register_operand" "r")) 1987 (match_operand:GPI 2 "register_operand" "r")))] 1988 1989 "" 1990 "mneg\\t%<w>0, %<w>1, %<w>2" 1991 [(set_attr "type" "mul")] 1992) 1993 1994;; zero_extend version of above 1995(define_insn "*mulsi_neg_uxtw" 1996 [(set (match_operand:DI 0 "register_operand" "=r") 1997 (zero_extend:DI 1998 (mult:SI (neg:SI (match_operand:SI 1 "register_operand" "r")) 1999 (match_operand:SI 2 "register_operand" "r"))))] 2000 2001 "" 2002 "mneg\\t%w0, %w1, %w2" 2003 [(set_attr "type" "mul")] 2004) 2005 2006(define_insn "<su_optab>mulsidi3" 2007 [(set (match_operand:DI 0 "register_operand" "=r") 2008 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r")) 2009 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))] 2010 "" 2011 "<su>mull\\t%0, %w1, %w2" 2012 [(set_attr "type" "<su>mull")] 2013) 2014 2015(define_insn "<su_optab>maddsidi4" 2016 [(set (match_operand:DI 0 "register_operand" "=r") 2017 (plus:DI (mult:DI 2018 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r")) 2019 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))) 2020 (match_operand:DI 3 "register_operand" "r")))] 2021 "" 2022 "<su>maddl\\t%0, %w1, %w2, %3" 2023 [(set_attr "type" "<su>mlal")] 2024) 2025 2026(define_insn "<su_optab>msubsidi4" 2027 [(set (match_operand:DI 0 "register_operand" "=r") 2028 (minus:DI 2029 (match_operand:DI 3 "register_operand" "r") 2030 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r")) 2031 (ANY_EXTEND:DI 2032 (match_operand:SI 2 "register_operand" "r")))))] 2033 "" 2034 "<su>msubl\\t%0, %w1, %w2, %3" 2035 [(set_attr "type" "<su>mlal")] 2036) 2037 2038(define_insn "*<su_optab>mulsidi_neg" 2039 [(set (match_operand:DI 0 "register_operand" "=r") 2040 (mult:DI (neg:DI 2041 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))) 2042 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))] 2043 "" 2044 "<su>mnegl\\t%0, %w1, %w2" 2045 [(set_attr "type" "<su>mull")] 2046) 2047 2048(define_insn "<su>muldi3_highpart" 2049 [(set (match_operand:DI 0 "register_operand" "=r") 2050 (truncate:DI 2051 (lshiftrt:TI 2052 (mult:TI 2053 (ANY_EXTEND:TI (match_operand:DI 1 "register_operand" "r")) 2054 (ANY_EXTEND:TI (match_operand:DI 2 "register_operand" "r"))) 2055 (const_int 64))))] 2056 "" 2057 "<su>mulh\\t%0, %1, %2" 2058 [(set_attr "type" "<su>mull")] 2059) 2060 2061(define_insn "<su_optab>div<mode>3" 2062 [(set (match_operand:GPI 0 "register_operand" "=r") 2063 (ANY_DIV:GPI (match_operand:GPI 1 "register_operand" "r") 2064 (match_operand:GPI 2 "register_operand" "r")))] 2065 "" 2066 "<su>div\\t%<w>0, %<w>1, %<w>2" 2067 [(set_attr "type" "<su>div")] 2068) 2069 2070;; zero_extend version of above 2071(define_insn "*<su_optab>divsi3_uxtw" 2072 [(set (match_operand:DI 0 "register_operand" "=r") 2073 (zero_extend:DI 2074 (ANY_DIV:SI (match_operand:SI 1 "register_operand" "r") 2075 (match_operand:SI 2 "register_operand" "r"))))] 2076 "" 2077 "<su>div\\t%w0, %w1, %w2" 2078 [(set_attr "type" "<su>div")] 2079) 2080 2081;; ------------------------------------------------------------------- 2082;; Comparison insns 2083;; ------------------------------------------------------------------- 2084 2085(define_insn "*cmp<mode>" 2086 [(set (reg:CC CC_REGNUM) 2087 (compare:CC (match_operand:GPI 0 "register_operand" "r,r,r") 2088 (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))] 2089 "" 2090 "@ 2091 cmp\\t%<w>0, %<w>1 2092 cmp\\t%<w>0, %<w>1 2093 cmn\\t%<w>0, #%n1" 2094 [(set_attr "type" "alus_reg,alus_imm,alus_imm")] 2095) 2096 2097(define_insn "*cmp<mode>" 2098 [(set (reg:CCFP CC_REGNUM) 2099 (compare:CCFP (match_operand:GPF 0 "register_operand" "w,w") 2100 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))] 2101 "TARGET_FLOAT" 2102 "@ 2103 fcmp\\t%<s>0, #0.0 2104 fcmp\\t%<s>0, %<s>1" 2105 [(set_attr "type" "fcmp<s>")] 2106) 2107 2108(define_insn "*cmpe<mode>" 2109 [(set (reg:CCFPE CC_REGNUM) 2110 (compare:CCFPE (match_operand:GPF 0 "register_operand" "w,w") 2111 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))] 2112 "TARGET_FLOAT" 2113 "@ 2114 fcmpe\\t%<s>0, #0.0 2115 fcmpe\\t%<s>0, %<s>1" 2116 [(set_attr "type" "fcmp<s>")] 2117) 2118 2119(define_insn "*cmp_swp_<shift>_reg<mode>" 2120 [(set (reg:CC_SWP CC_REGNUM) 2121 (compare:CC_SWP (ASHIFT:GPI 2122 (match_operand:GPI 0 "register_operand" "r") 2123 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n")) 2124 (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")))] 2125 "" 2126 "cmp\\t%<w>2, %<w>0, <shift> %1" 2127 [(set_attr "type" "alus_shift_imm")] 2128) 2129 2130(define_insn "*cmp_swp_<optab><ALLX:mode>_reg<GPI:mode>" 2131 [(set (reg:CC_SWP CC_REGNUM) 2132 (compare:CC_SWP (ANY_EXTEND:GPI 2133 (match_operand:ALLX 0 "register_operand" "r")) 2134 (match_operand:GPI 1 "register_operand" "r")))] 2135 "" 2136 "cmp\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>" 2137 [(set_attr "type" "alus_ext")] 2138) 2139 2140(define_insn "*cmp_swp_<optab><ALLX:mode>_shft_<GPI:mode>" 2141 [(set (reg:CC_SWP CC_REGNUM) 2142 (compare:CC_SWP (ashift:GPI 2143 (ANY_EXTEND:GPI 2144 (match_operand:ALLX 0 "register_operand" "r")) 2145 (match_operand 1 "aarch64_imm3" "Ui3")) 2146 (match_operand:GPI 2 "register_operand" "r")))] 2147 "" 2148 "cmp\\t%<GPI:w>2, %<GPI:w>0, <su>xt<ALLX:size> %1" 2149 [(set_attr "type" "alus_ext")] 2150) 2151 2152;; ------------------------------------------------------------------- 2153;; Store-flag and conditional select insns 2154;; ------------------------------------------------------------------- 2155 2156(define_expand "cstore<mode>4" 2157 [(set (match_operand:SI 0 "register_operand" "") 2158 (match_operator:SI 1 "aarch64_comparison_operator" 2159 [(match_operand:GPI 2 "register_operand" "") 2160 (match_operand:GPI 3 "aarch64_plus_operand" "")]))] 2161 "" 2162 " 2163 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2], 2164 operands[3]); 2165 operands[3] = const0_rtx; 2166 " 2167) 2168 2169(define_expand "cstore<mode>4" 2170 [(set (match_operand:SI 0 "register_operand" "") 2171 (match_operator:SI 1 "aarch64_comparison_operator" 2172 [(match_operand:GPF 2 "register_operand" "") 2173 (match_operand:GPF 3 "register_operand" "")]))] 2174 "" 2175 " 2176 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2], 2177 operands[3]); 2178 operands[3] = const0_rtx; 2179 " 2180) 2181 2182(define_insn "*cstore<mode>_insn" 2183 [(set (match_operand:ALLI 0 "register_operand" "=r") 2184 (match_operator:ALLI 1 "aarch64_comparison_operator" 2185 [(match_operand 2 "cc_register" "") (const_int 0)]))] 2186 "" 2187 "cset\\t%<w>0, %m1" 2188 [(set_attr "type" "csel")] 2189) 2190 2191;; zero_extend version of the above 2192(define_insn "*cstoresi_insn_uxtw" 2193 [(set (match_operand:DI 0 "register_operand" "=r") 2194 (zero_extend:DI 2195 (match_operator:SI 1 "aarch64_comparison_operator" 2196 [(match_operand 2 "cc_register" "") (const_int 0)])))] 2197 "" 2198 "cset\\t%w0, %m1" 2199 [(set_attr "type" "csel")] 2200) 2201 2202(define_insn "cstore<mode>_neg" 2203 [(set (match_operand:ALLI 0 "register_operand" "=r") 2204 (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator" 2205 [(match_operand 2 "cc_register" "") (const_int 0)])))] 2206 "" 2207 "csetm\\t%<w>0, %m1" 2208 [(set_attr "type" "csel")] 2209) 2210 2211;; zero_extend version of the above 2212(define_insn "*cstoresi_neg_uxtw" 2213 [(set (match_operand:DI 0 "register_operand" "=r") 2214 (zero_extend:DI 2215 (neg:SI (match_operator:SI 1 "aarch64_comparison_operator" 2216 [(match_operand 2 "cc_register" "") (const_int 0)]))))] 2217 "" 2218 "csetm\\t%w0, %m1" 2219 [(set_attr "type" "csel")] 2220) 2221 2222(define_expand "cmov<mode>6" 2223 [(set (match_operand:GPI 0 "register_operand" "") 2224 (if_then_else:GPI 2225 (match_operator 1 "aarch64_comparison_operator" 2226 [(match_operand:GPI 2 "register_operand" "") 2227 (match_operand:GPI 3 "aarch64_plus_operand" "")]) 2228 (match_operand:GPI 4 "register_operand" "") 2229 (match_operand:GPI 5 "register_operand" "")))] 2230 "" 2231 " 2232 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2], 2233 operands[3]); 2234 operands[3] = const0_rtx; 2235 " 2236) 2237 2238(define_expand "cmov<mode>6" 2239 [(set (match_operand:GPF 0 "register_operand" "") 2240 (if_then_else:GPF 2241 (match_operator 1 "aarch64_comparison_operator" 2242 [(match_operand:GPF 2 "register_operand" "") 2243 (match_operand:GPF 3 "register_operand" "")]) 2244 (match_operand:GPF 4 "register_operand" "") 2245 (match_operand:GPF 5 "register_operand" "")))] 2246 "" 2247 " 2248 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2], 2249 operands[3]); 2250 operands[3] = const0_rtx; 2251 " 2252) 2253 2254(define_insn "*cmov<mode>_insn" 2255 [(set (match_operand:ALLI 0 "register_operand" "=r,r,r,r,r,r,r") 2256 (if_then_else:ALLI 2257 (match_operator 1 "aarch64_comparison_operator" 2258 [(match_operand 2 "cc_register" "") (const_int 0)]) 2259 (match_operand:ALLI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1") 2260 (match_operand:ALLI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1")))] 2261 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx) 2262 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))" 2263 ;; Final two alternatives should be unreachable, but included for completeness 2264 "@ 2265 csel\\t%<w>0, %<w>3, %<w>4, %m1 2266 csinv\\t%<w>0, %<w>3, <w>zr, %m1 2267 csinv\\t%<w>0, %<w>4, <w>zr, %M1 2268 csinc\\t%<w>0, %<w>3, <w>zr, %m1 2269 csinc\\t%<w>0, %<w>4, <w>zr, %M1 2270 mov\\t%<w>0, -1 2271 mov\\t%<w>0, 1" 2272 [(set_attr "type" "csel")] 2273) 2274 2275;; zero_extend version of above 2276(define_insn "*cmovsi_insn_uxtw" 2277 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r") 2278 (zero_extend:DI 2279 (if_then_else:SI 2280 (match_operator 1 "aarch64_comparison_operator" 2281 [(match_operand 2 "cc_register" "") (const_int 0)]) 2282 (match_operand:SI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1") 2283 (match_operand:SI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1"))))] 2284 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx) 2285 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))" 2286 ;; Final two alternatives should be unreachable, but included for completeness 2287 "@ 2288 csel\\t%w0, %w3, %w4, %m1 2289 csinv\\t%w0, %w3, wzr, %m1 2290 csinv\\t%w0, %w4, wzr, %M1 2291 csinc\\t%w0, %w3, wzr, %m1 2292 csinc\\t%w0, %w4, wzr, %M1 2293 mov\\t%w0, -1 2294 mov\\t%w0, 1" 2295 [(set_attr "type" "csel")] 2296) 2297 2298(define_insn "*cmov<mode>_insn" 2299 [(set (match_operand:GPF 0 "register_operand" "=w") 2300 (if_then_else:GPF 2301 (match_operator 1 "aarch64_comparison_operator" 2302 [(match_operand 2 "cc_register" "") (const_int 0)]) 2303 (match_operand:GPF 3 "register_operand" "w") 2304 (match_operand:GPF 4 "register_operand" "w")))] 2305 "TARGET_FLOAT" 2306 "fcsel\\t%<s>0, %<s>3, %<s>4, %m1" 2307 [(set_attr "type" "fcsel")] 2308) 2309 2310(define_expand "mov<mode>cc" 2311 [(set (match_operand:ALLI 0 "register_operand" "") 2312 (if_then_else:ALLI (match_operand 1 "aarch64_comparison_operator" "") 2313 (match_operand:ALLI 2 "register_operand" "") 2314 (match_operand:ALLI 3 "register_operand" "")))] 2315 "" 2316 { 2317 rtx ccreg; 2318 enum rtx_code code = GET_CODE (operands[1]); 2319 2320 if (code == UNEQ || code == LTGT) 2321 FAIL; 2322 2323 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0), 2324 XEXP (operands[1], 1)); 2325 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx); 2326 } 2327) 2328 2329(define_expand "mov<GPF:mode><GPI:mode>cc" 2330 [(set (match_operand:GPI 0 "register_operand" "") 2331 (if_then_else:GPI (match_operand 1 "aarch64_comparison_operator" "") 2332 (match_operand:GPF 2 "register_operand" "") 2333 (match_operand:GPF 3 "register_operand" "")))] 2334 "" 2335 { 2336 rtx ccreg; 2337 enum rtx_code code = GET_CODE (operands[1]); 2338 2339 if (code == UNEQ || code == LTGT) 2340 FAIL; 2341 2342 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0), 2343 XEXP (operands[1], 1)); 2344 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx); 2345 } 2346) 2347 2348(define_insn "*csinc2<mode>_insn" 2349 [(set (match_operand:GPI 0 "register_operand" "=r") 2350 (plus:GPI (match_operator:GPI 2 "aarch64_comparison_operator" 2351 [(match_operand:CC 3 "cc_register" "") (const_int 0)]) 2352 (match_operand:GPI 1 "register_operand" "r")))] 2353 "" 2354 "csinc\\t%<w>0, %<w>1, %<w>1, %M2" 2355 [(set_attr "type" "csel")] 2356) 2357 2358(define_insn "csinc3<mode>_insn" 2359 [(set (match_operand:GPI 0 "register_operand" "=r") 2360 (if_then_else:GPI 2361 (match_operator:GPI 1 "aarch64_comparison_operator" 2362 [(match_operand:CC 2 "cc_register" "") (const_int 0)]) 2363 (plus:GPI (match_operand:GPI 3 "register_operand" "r") 2364 (const_int 1)) 2365 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))] 2366 "" 2367 "csinc\\t%<w>0, %<w>4, %<w>3, %M1" 2368 [(set_attr "type" "csel")] 2369) 2370 2371(define_insn "*csinv3<mode>_insn" 2372 [(set (match_operand:GPI 0 "register_operand" "=r") 2373 (if_then_else:GPI 2374 (match_operator:GPI 1 "aarch64_comparison_operator" 2375 [(match_operand:CC 2 "cc_register" "") (const_int 0)]) 2376 (not:GPI (match_operand:GPI 3 "register_operand" "r")) 2377 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))] 2378 "" 2379 "csinv\\t%<w>0, %<w>4, %<w>3, %M1" 2380 [(set_attr "type" "csel")] 2381) 2382 2383(define_insn "*csneg3<mode>_insn" 2384 [(set (match_operand:GPI 0 "register_operand" "=r") 2385 (if_then_else:GPI 2386 (match_operator:GPI 1 "aarch64_comparison_operator" 2387 [(match_operand:CC 2 "cc_register" "") (const_int 0)]) 2388 (neg:GPI (match_operand:GPI 3 "register_operand" "r")) 2389 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))] 2390 "" 2391 "csneg\\t%<w>0, %<w>4, %<w>3, %M1" 2392 [(set_attr "type" "csel")] 2393) 2394 2395;; ------------------------------------------------------------------- 2396;; Logical operations 2397;; ------------------------------------------------------------------- 2398 2399(define_insn "<optab><mode>3" 2400 [(set (match_operand:GPI 0 "register_operand" "=r,rk") 2401 (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r") 2402 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>")))] 2403 "" 2404 "<logical>\\t%<w>0, %<w>1, %<w>2" 2405 [(set_attr "type" "logic_reg,logic_imm")] 2406) 2407 2408;; zero_extend version of above 2409(define_insn "*<optab>si3_uxtw" 2410 [(set (match_operand:DI 0 "register_operand" "=r,rk") 2411 (zero_extend:DI 2412 (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r,r") 2413 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))))] 2414 "" 2415 "<logical>\\t%w0, %w1, %w2" 2416 [(set_attr "type" "logic_reg,logic_imm")] 2417) 2418 2419(define_insn "*and<mode>3_compare0" 2420 [(set (reg:CC_NZ CC_REGNUM) 2421 (compare:CC_NZ 2422 (and:GPI (match_operand:GPI 1 "register_operand" "%r,r") 2423 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>")) 2424 (const_int 0))) 2425 (set (match_operand:GPI 0 "register_operand" "=r,r") 2426 (and:GPI (match_dup 1) (match_dup 2)))] 2427 "" 2428 "ands\\t%<w>0, %<w>1, %<w>2" 2429 [(set_attr "type" "logics_reg,logics_imm")] 2430) 2431 2432;; zero_extend version of above 2433(define_insn "*andsi3_compare0_uxtw" 2434 [(set (reg:CC_NZ CC_REGNUM) 2435 (compare:CC_NZ 2436 (and:SI (match_operand:SI 1 "register_operand" "%r,r") 2437 (match_operand:SI 2 "aarch64_logical_operand" "r,K")) 2438 (const_int 0))) 2439 (set (match_operand:DI 0 "register_operand" "=r,r") 2440 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))] 2441 "" 2442 "ands\\t%w0, %w1, %w2" 2443 [(set_attr "type" "logics_reg,logics_imm")] 2444) 2445 2446(define_insn "*and_<SHIFT:optab><mode>3_compare0" 2447 [(set (reg:CC_NZ CC_REGNUM) 2448 (compare:CC_NZ 2449 (and:GPI (SHIFT:GPI 2450 (match_operand:GPI 1 "register_operand" "r") 2451 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")) 2452 (match_operand:GPI 3 "register_operand" "r")) 2453 (const_int 0))) 2454 (set (match_operand:GPI 0 "register_operand" "=r") 2455 (and:GPI (SHIFT:GPI (match_dup 1) (match_dup 2)) (match_dup 3)))] 2456 "" 2457 "ands\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2" 2458 [(set_attr "type" "logics_shift_imm")] 2459) 2460 2461;; zero_extend version of above 2462(define_insn "*and_<SHIFT:optab>si3_compare0_uxtw" 2463 [(set (reg:CC_NZ CC_REGNUM) 2464 (compare:CC_NZ 2465 (and:SI (SHIFT:SI 2466 (match_operand:SI 1 "register_operand" "r") 2467 (match_operand:QI 2 "aarch64_shift_imm_si" "n")) 2468 (match_operand:SI 3 "register_operand" "r")) 2469 (const_int 0))) 2470 (set (match_operand:DI 0 "register_operand" "=r") 2471 (zero_extend:DI (and:SI (SHIFT:SI (match_dup 1) (match_dup 2)) 2472 (match_dup 3))))] 2473 "" 2474 "ands\\t%w0, %w3, %w1, <SHIFT:shift> %2" 2475 [(set_attr "type" "logics_shift_imm")] 2476) 2477 2478(define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3" 2479 [(set (match_operand:GPI 0 "register_operand" "=r") 2480 (LOGICAL:GPI (SHIFT:GPI 2481 (match_operand:GPI 1 "register_operand" "r") 2482 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")) 2483 (match_operand:GPI 3 "register_operand" "r")))] 2484 "" 2485 "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2" 2486 [(set_attr "type" "logic_shift_imm")] 2487) 2488 2489;; zero_extend version of above 2490(define_insn "*<LOGICAL:optab>_<SHIFT:optab>si3_uxtw" 2491 [(set (match_operand:DI 0 "register_operand" "=r") 2492 (zero_extend:DI 2493 (LOGICAL:SI (SHIFT:SI 2494 (match_operand:SI 1 "register_operand" "r") 2495 (match_operand:QI 2 "aarch64_shift_imm_si" "n")) 2496 (match_operand:SI 3 "register_operand" "r"))))] 2497 "" 2498 "<LOGICAL:logical>\\t%w0, %w3, %w1, <SHIFT:shift> %2" 2499 [(set_attr "type" "logic_shift_imm")] 2500) 2501 2502(define_insn "one_cmpl<mode>2" 2503 [(set (match_operand:GPI 0 "register_operand" "=r") 2504 (not:GPI (match_operand:GPI 1 "register_operand" "r")))] 2505 "" 2506 "mvn\\t%<w>0, %<w>1" 2507 [(set_attr "type" "logic_reg")] 2508) 2509 2510(define_insn "*one_cmpl_<optab><mode>2" 2511 [(set (match_operand:GPI 0 "register_operand" "=r") 2512 (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r") 2513 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))] 2514 "" 2515 "mvn\\t%<w>0, %<w>1, <shift> %2" 2516 [(set_attr "type" "logic_shift_imm")] 2517) 2518 2519(define_insn "*<LOGICAL:optab>_one_cmpl<mode>3" 2520 [(set (match_operand:GPI 0 "register_operand" "=r") 2521 (LOGICAL:GPI (not:GPI 2522 (match_operand:GPI 1 "register_operand" "r")) 2523 (match_operand:GPI 2 "register_operand" "r")))] 2524 "" 2525 "<LOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1" 2526 [(set_attr "type" "logic_reg")] 2527) 2528 2529(define_insn "*and_one_cmpl<mode>3_compare0" 2530 [(set (reg:CC_NZ CC_REGNUM) 2531 (compare:CC_NZ 2532 (and:GPI (not:GPI 2533 (match_operand:GPI 1 "register_operand" "r")) 2534 (match_operand:GPI 2 "register_operand" "r")) 2535 (const_int 0))) 2536 (set (match_operand:GPI 0 "register_operand" "=r") 2537 (and:GPI (not:GPI (match_dup 1)) (match_dup 2)))] 2538 "" 2539 "bics\\t%<w>0, %<w>2, %<w>1" 2540 [(set_attr "type" "logics_reg")] 2541) 2542 2543;; zero_extend version of above 2544(define_insn "*and_one_cmplsi3_compare0_uxtw" 2545 [(set (reg:CC_NZ CC_REGNUM) 2546 (compare:CC_NZ 2547 (and:SI (not:SI 2548 (match_operand:SI 1 "register_operand" "r")) 2549 (match_operand:SI 2 "register_operand" "r")) 2550 (const_int 0))) 2551 (set (match_operand:DI 0 "register_operand" "=r") 2552 (zero_extend:DI (and:SI (not:SI (match_dup 1)) (match_dup 2))))] 2553 "" 2554 "bics\\t%w0, %w2, %w1" 2555 [(set_attr "type" "logics_reg")] 2556) 2557 2558(define_insn "*<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3" 2559 [(set (match_operand:GPI 0 "register_operand" "=r") 2560 (LOGICAL:GPI (not:GPI 2561 (SHIFT:GPI 2562 (match_operand:GPI 1 "register_operand" "r") 2563 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))) 2564 (match_operand:GPI 3 "register_operand" "r")))] 2565 "" 2566 "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2" 2567 [(set_attr "type" "logics_shift_imm")] 2568) 2569 2570(define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0" 2571 [(set (reg:CC_NZ CC_REGNUM) 2572 (compare:CC_NZ 2573 (and:GPI (not:GPI 2574 (SHIFT:GPI 2575 (match_operand:GPI 1 "register_operand" "r") 2576 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))) 2577 (match_operand:GPI 3 "register_operand" "r")) 2578 (const_int 0))) 2579 (set (match_operand:GPI 0 "register_operand" "=r") 2580 (and:GPI (not:GPI 2581 (SHIFT:GPI 2582 (match_dup 1) (match_dup 2))) (match_dup 3)))] 2583 "" 2584 "bics\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2" 2585 [(set_attr "type" "logics_shift_imm")] 2586) 2587 2588;; zero_extend version of above 2589(define_insn "*and_one_cmpl_<SHIFT:optab>si3_compare0_uxtw" 2590 [(set (reg:CC_NZ CC_REGNUM) 2591 (compare:CC_NZ 2592 (and:SI (not:SI 2593 (SHIFT:SI 2594 (match_operand:SI 1 "register_operand" "r") 2595 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))) 2596 (match_operand:SI 3 "register_operand" "r")) 2597 (const_int 0))) 2598 (set (match_operand:DI 0 "register_operand" "=r") 2599 (zero_extend:DI (and:SI 2600 (not:SI 2601 (SHIFT:SI (match_dup 1) (match_dup 2))) (match_dup 3))))] 2602 "" 2603 "bics\\t%w0, %w3, %w1, <SHIFT:shift> %2" 2604 [(set_attr "type" "logics_shift_imm")] 2605) 2606 2607(define_insn "clz<mode>2" 2608 [(set (match_operand:GPI 0 "register_operand" "=r") 2609 (clz:GPI (match_operand:GPI 1 "register_operand" "r")))] 2610 "" 2611 "clz\\t%<w>0, %<w>1" 2612 [(set_attr "type" "clz")] 2613) 2614 2615(define_expand "ffs<mode>2" 2616 [(match_operand:GPI 0 "register_operand") 2617 (match_operand:GPI 1 "register_operand")] 2618 "" 2619 { 2620 rtx ccreg = aarch64_gen_compare_reg (EQ, operands[1], const0_rtx); 2621 rtx x = gen_rtx_NE (VOIDmode, ccreg, const0_rtx); 2622 2623 emit_insn (gen_rbit<mode>2 (operands[0], operands[1])); 2624 emit_insn (gen_clz<mode>2 (operands[0], operands[0])); 2625 emit_insn (gen_csinc3<mode>_insn (operands[0], x, ccreg, operands[0], const0_rtx)); 2626 DONE; 2627 } 2628) 2629 2630(define_insn "clrsb<mode>2" 2631 [(set (match_operand:GPI 0 "register_operand" "=r") 2632 (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_CLS))] 2633 "" 2634 "cls\\t%<w>0, %<w>1" 2635 [(set_attr "type" "clz")] 2636) 2637 2638(define_insn "rbit<mode>2" 2639 [(set (match_operand:GPI 0 "register_operand" "=r") 2640 (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_RBIT))] 2641 "" 2642 "rbit\\t%<w>0, %<w>1" 2643 [(set_attr "type" "rbit")] 2644) 2645 2646(define_expand "ctz<mode>2" 2647 [(match_operand:GPI 0 "register_operand") 2648 (match_operand:GPI 1 "register_operand")] 2649 "" 2650 { 2651 emit_insn (gen_rbit<mode>2 (operands[0], operands[1])); 2652 emit_insn (gen_clz<mode>2 (operands[0], operands[0])); 2653 DONE; 2654 } 2655) 2656 2657(define_insn "*and<mode>3nr_compare0" 2658 [(set (reg:CC_NZ CC_REGNUM) 2659 (compare:CC_NZ 2660 (and:GPI (match_operand:GPI 0 "register_operand" "%r,r") 2661 (match_operand:GPI 1 "aarch64_logical_operand" "r,<lconst>")) 2662 (const_int 0)))] 2663 "" 2664 "tst\\t%<w>0, %<w>1" 2665 [(set_attr "type" "logics_reg")] 2666) 2667 2668(define_insn "*and_<SHIFT:optab><mode>3nr_compare0" 2669 [(set (reg:CC_NZ CC_REGNUM) 2670 (compare:CC_NZ 2671 (and:GPI (SHIFT:GPI 2672 (match_operand:GPI 0 "register_operand" "r") 2673 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n")) 2674 (match_operand:GPI 2 "register_operand" "r")) 2675 (const_int 0)))] 2676 "" 2677 "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1" 2678 [(set_attr "type" "logics_shift_imm")] 2679) 2680 2681;; ------------------------------------------------------------------- 2682;; Shifts 2683;; ------------------------------------------------------------------- 2684 2685(define_expand "<optab><mode>3" 2686 [(set (match_operand:GPI 0 "register_operand") 2687 (ASHIFT:GPI (match_operand:GPI 1 "register_operand") 2688 (match_operand:QI 2 "nonmemory_operand")))] 2689 "" 2690 { 2691 if (CONST_INT_P (operands[2])) 2692 { 2693 operands[2] = GEN_INT (INTVAL (operands[2]) 2694 & (GET_MODE_BITSIZE (<MODE>mode) - 1)); 2695 2696 if (operands[2] == const0_rtx) 2697 { 2698 emit_insn (gen_mov<mode> (operands[0], operands[1])); 2699 DONE; 2700 } 2701 } 2702 } 2703) 2704 2705(define_expand "ashl<mode>3" 2706 [(set (match_operand:SHORT 0 "register_operand") 2707 (ashift:SHORT (match_operand:SHORT 1 "register_operand") 2708 (match_operand:QI 2 "nonmemory_operand")))] 2709 "" 2710 { 2711 if (CONST_INT_P (operands[2])) 2712 { 2713 operands[2] = GEN_INT (INTVAL (operands[2]) 2714 & (GET_MODE_BITSIZE (<MODE>mode) - 1)); 2715 2716 if (operands[2] == const0_rtx) 2717 { 2718 emit_insn (gen_mov<mode> (operands[0], operands[1])); 2719 DONE; 2720 } 2721 } 2722 } 2723) 2724 2725(define_expand "rotr<mode>3" 2726 [(set (match_operand:GPI 0 "register_operand") 2727 (rotatert:GPI (match_operand:GPI 1 "register_operand") 2728 (match_operand:QI 2 "nonmemory_operand")))] 2729 "" 2730 { 2731 if (CONST_INT_P (operands[2])) 2732 { 2733 operands[2] = GEN_INT (INTVAL (operands[2]) 2734 & (GET_MODE_BITSIZE (<MODE>mode) - 1)); 2735 2736 if (operands[2] == const0_rtx) 2737 { 2738 emit_insn (gen_mov<mode> (operands[0], operands[1])); 2739 DONE; 2740 } 2741 } 2742 } 2743) 2744 2745(define_expand "rotl<mode>3" 2746 [(set (match_operand:GPI 0 "register_operand") 2747 (rotatert:GPI (match_operand:GPI 1 "register_operand") 2748 (match_operand:QI 2 "nonmemory_operand")))] 2749 "" 2750 { 2751 /* (SZ - cnt) % SZ == -cnt % SZ */ 2752 if (CONST_INT_P (operands[2])) 2753 { 2754 operands[2] = GEN_INT ((-INTVAL (operands[2])) 2755 & (GET_MODE_BITSIZE (<MODE>mode) - 1)); 2756 if (operands[2] == const0_rtx) 2757 { 2758 emit_insn (gen_mov<mode> (operands[0], operands[1])); 2759 DONE; 2760 } 2761 } 2762 else 2763 operands[2] = expand_simple_unop (QImode, NEG, operands[2], 2764 NULL_RTX, 1); 2765 } 2766) 2767 2768;; Logical left shift using SISD or Integer instruction 2769(define_insn "*aarch64_ashl_sisd_or_int_<mode>3" 2770 [(set (match_operand:GPI 0 "register_operand" "=w,w,r") 2771 (ashift:GPI 2772 (match_operand:GPI 1 "register_operand" "w,w,r") 2773 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))] 2774 "" 2775 "@ 2776 shl\t%<rtn>0<vas>, %<rtn>1<vas>, %2 2777 ushl\t%<rtn>0<vas>, %<rtn>1<vas>, %<rtn>2<vas> 2778 lsl\t%<w>0, %<w>1, %<w>2" 2779 [(set_attr "simd" "yes,yes,no") 2780 (set_attr "type" "neon_shift_imm<q>, neon_shift_reg<q>,shift_reg")] 2781) 2782 2783;; Logical right shift using SISD or Integer instruction 2784(define_insn "*aarch64_lshr_sisd_or_int_<mode>3" 2785 [(set (match_operand:GPI 0 "register_operand" "=w,w,r") 2786 (lshiftrt:GPI 2787 (match_operand:GPI 1 "register_operand" "w,w,r") 2788 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))] 2789 "" 2790 "@ 2791 ushr\t%<rtn>0<vas>, %<rtn>1<vas>, %2 2792 # 2793 lsr\t%<w>0, %<w>1, %<w>2" 2794 [(set_attr "simd" "yes,yes,no") 2795 (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,shift_reg")] 2796) 2797 2798(define_split 2799 [(set (match_operand:DI 0 "aarch64_simd_register") 2800 (lshiftrt:DI 2801 (match_operand:DI 1 "aarch64_simd_register") 2802 (match_operand:QI 2 "aarch64_simd_register")))] 2803 "TARGET_SIMD && reload_completed" 2804 [(set (match_dup 2) 2805 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG)) 2806 (set (match_dup 0) 2807 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SISD_USHL))] 2808 "" 2809) 2810 2811(define_split 2812 [(set (match_operand:SI 0 "aarch64_simd_register") 2813 (lshiftrt:SI 2814 (match_operand:SI 1 "aarch64_simd_register") 2815 (match_operand:QI 2 "aarch64_simd_register")))] 2816 "TARGET_SIMD && reload_completed" 2817 [(set (match_dup 2) 2818 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG)) 2819 (set (match_dup 0) 2820 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_USHL_2S))] 2821 "" 2822) 2823 2824;; Arithmetic right shift using SISD or Integer instruction 2825(define_insn "*aarch64_ashr_sisd_or_int_<mode>3" 2826 [(set (match_operand:GPI 0 "register_operand" "=w,&w,&w,r") 2827 (ashiftrt:GPI 2828 (match_operand:GPI 1 "register_operand" "w,w,w,r") 2829 (match_operand:QI 2 "aarch64_reg_or_shift_imm_di" "Us<cmode>,w,0,rUs<cmode>")))] 2830 "" 2831 "@ 2832 sshr\t%<rtn>0<vas>, %<rtn>1<vas>, %2 2833 # 2834 # 2835 asr\t%<w>0, %<w>1, %<w>2" 2836 [(set_attr "simd" "yes,yes,yes,no") 2837 (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,neon_shift_reg<q>,shift_reg")] 2838) 2839 2840(define_split 2841 [(set (match_operand:DI 0 "aarch64_simd_register") 2842 (ashiftrt:DI 2843 (match_operand:DI 1 "aarch64_simd_register") 2844 (match_operand:QI 2 "aarch64_simd_register")))] 2845 "TARGET_SIMD && reload_completed" 2846 [(set (match_dup 3) 2847 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG)) 2848 (set (match_dup 0) 2849 (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_SISD_SSHL))] 2850{ 2851 operands[3] = gen_lowpart (QImode, operands[0]); 2852} 2853) 2854 2855(define_split 2856 [(set (match_operand:SI 0 "aarch64_simd_register") 2857 (ashiftrt:SI 2858 (match_operand:SI 1 "aarch64_simd_register") 2859 (match_operand:QI 2 "aarch64_simd_register")))] 2860 "TARGET_SIMD && reload_completed" 2861 [(set (match_dup 3) 2862 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG)) 2863 (set (match_dup 0) 2864 (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_SSHL_2S))] 2865{ 2866 operands[3] = gen_lowpart (QImode, operands[0]); 2867} 2868) 2869 2870(define_insn "*aarch64_sisd_ushl" 2871 [(set (match_operand:DI 0 "register_operand" "=w") 2872 (unspec:DI [(match_operand:DI 1 "register_operand" "w") 2873 (match_operand:QI 2 "register_operand" "w")] 2874 UNSPEC_SISD_USHL))] 2875 "TARGET_SIMD" 2876 "ushl\t%d0, %d1, %d2" 2877 [(set_attr "simd" "yes") 2878 (set_attr "type" "neon_shift_reg")] 2879) 2880 2881(define_insn "*aarch64_ushl_2s" 2882 [(set (match_operand:SI 0 "register_operand" "=w") 2883 (unspec:SI [(match_operand:SI 1 "register_operand" "w") 2884 (match_operand:QI 2 "register_operand" "w")] 2885 UNSPEC_USHL_2S))] 2886 "TARGET_SIMD" 2887 "ushl\t%0.2s, %1.2s, %2.2s" 2888 [(set_attr "simd" "yes") 2889 (set_attr "type" "neon_shift_reg")] 2890) 2891 2892(define_insn "*aarch64_sisd_sshl" 2893 [(set (match_operand:DI 0 "register_operand" "=w") 2894 (unspec:DI [(match_operand:DI 1 "register_operand" "w") 2895 (match_operand:QI 2 "register_operand" "w")] 2896 UNSPEC_SISD_SSHL))] 2897 "TARGET_SIMD" 2898 "sshl\t%d0, %d1, %d2" 2899 [(set_attr "simd" "yes") 2900 (set_attr "type" "neon_shift_reg")] 2901) 2902 2903(define_insn "*aarch64_sshl_2s" 2904 [(set (match_operand:SI 0 "register_operand" "=w") 2905 (unspec:SI [(match_operand:SI 1 "register_operand" "w") 2906 (match_operand:QI 2 "register_operand" "w")] 2907 UNSPEC_SSHL_2S))] 2908 "TARGET_SIMD" 2909 "sshl\t%0.2s, %1.2s, %2.2s" 2910 [(set_attr "simd" "yes") 2911 (set_attr "type" "neon_shift_reg")] 2912) 2913 2914(define_insn "*aarch64_sisd_neg_qi" 2915 [(set (match_operand:QI 0 "register_operand" "=w") 2916 (unspec:QI [(match_operand:QI 1 "register_operand" "w")] 2917 UNSPEC_SISD_NEG))] 2918 "TARGET_SIMD" 2919 "neg\t%d0, %d1" 2920 [(set_attr "simd" "yes") 2921 (set_attr "type" "neon_neg")] 2922) 2923 2924;; Rotate right 2925(define_insn "*ror<mode>3_insn" 2926 [(set (match_operand:GPI 0 "register_operand" "=r") 2927 (rotatert:GPI 2928 (match_operand:GPI 1 "register_operand" "r") 2929 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>")))] 2930 "" 2931 "ror\\t%<w>0, %<w>1, %<w>2" 2932 [(set_attr "type" "shift_reg")] 2933) 2934 2935;; zero_extend version of above 2936(define_insn "*<optab>si3_insn_uxtw" 2937 [(set (match_operand:DI 0 "register_operand" "=r") 2938 (zero_extend:DI (SHIFT:SI 2939 (match_operand:SI 1 "register_operand" "r") 2940 (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss"))))] 2941 "" 2942 "<shift>\\t%w0, %w1, %w2" 2943 [(set_attr "type" "shift_reg")] 2944) 2945 2946(define_insn "*ashl<mode>3_insn" 2947 [(set (match_operand:SHORT 0 "register_operand" "=r") 2948 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r") 2949 (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss")))] 2950 "" 2951 "lsl\\t%<w>0, %<w>1, %<w>2" 2952 [(set_attr "type" "shift_reg")] 2953) 2954 2955(define_insn "*<optab><mode>3_insn" 2956 [(set (match_operand:SHORT 0 "register_operand" "=r") 2957 (ASHIFT:SHORT (match_operand:SHORT 1 "register_operand" "r") 2958 (match_operand 2 "const_int_operand" "n")))] 2959 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)" 2960{ 2961 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2])); 2962 return "<bfshift>\t%w0, %w1, %2, %3"; 2963} 2964 [(set_attr "type" "bfm")] 2965) 2966 2967(define_insn "*extr<mode>5_insn" 2968 [(set (match_operand:GPI 0 "register_operand" "=r") 2969 (ior:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r") 2970 (match_operand 3 "const_int_operand" "n")) 2971 (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r") 2972 (match_operand 4 "const_int_operand" "n"))))] 2973 "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode) && 2974 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (<MODE>mode))" 2975 "extr\\t%<w>0, %<w>1, %<w>2, %4" 2976 [(set_attr "type" "shift_imm")] 2977) 2978 2979;; zero_extend version of the above 2980(define_insn "*extrsi5_insn_uxtw" 2981 [(set (match_operand:DI 0 "register_operand" "=r") 2982 (zero_extend:DI 2983 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r") 2984 (match_operand 3 "const_int_operand" "n")) 2985 (lshiftrt:SI (match_operand:SI 2 "register_operand" "r") 2986 (match_operand 4 "const_int_operand" "n")))))] 2987 "UINTVAL (operands[3]) < 32 && 2988 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)" 2989 "extr\\t%w0, %w1, %w2, %4" 2990 [(set_attr "type" "shift_imm")] 2991) 2992 2993(define_insn "*ror<mode>3_insn" 2994 [(set (match_operand:GPI 0 "register_operand" "=r") 2995 (rotate:GPI (match_operand:GPI 1 "register_operand" "r") 2996 (match_operand 2 "const_int_operand" "n")))] 2997 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)" 2998{ 2999 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2])); 3000 return "ror\\t%<w>0, %<w>1, %3"; 3001} 3002 [(set_attr "type" "shift_imm")] 3003) 3004 3005;; zero_extend version of the above 3006(define_insn "*rorsi3_insn_uxtw" 3007 [(set (match_operand:DI 0 "register_operand" "=r") 3008 (zero_extend:DI 3009 (rotate:SI (match_operand:SI 1 "register_operand" "r") 3010 (match_operand 2 "const_int_operand" "n"))))] 3011 "UINTVAL (operands[2]) < 32" 3012{ 3013 operands[3] = GEN_INT (32 - UINTVAL (operands[2])); 3014 return "ror\\t%w0, %w1, %3"; 3015} 3016 [(set_attr "type" "shift_imm")] 3017) 3018 3019(define_insn "*<ANY_EXTEND:optab><GPI:mode>_ashl<SHORT:mode>" 3020 [(set (match_operand:GPI 0 "register_operand" "=r") 3021 (ANY_EXTEND:GPI 3022 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r") 3023 (match_operand 2 "const_int_operand" "n"))))] 3024 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)" 3025{ 3026 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2])); 3027 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3"; 3028} 3029 [(set_attr "type" "bfm")] 3030) 3031 3032(define_insn "*zero_extend<GPI:mode>_lshr<SHORT:mode>" 3033 [(set (match_operand:GPI 0 "register_operand" "=r") 3034 (zero_extend:GPI 3035 (lshiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r") 3036 (match_operand 2 "const_int_operand" "n"))))] 3037 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)" 3038{ 3039 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2])); 3040 return "ubfx\t%<GPI:w>0, %<GPI:w>1, %2, %3"; 3041} 3042 [(set_attr "type" "bfm")] 3043) 3044 3045(define_insn "*extend<GPI:mode>_ashr<SHORT:mode>" 3046 [(set (match_operand:GPI 0 "register_operand" "=r") 3047 (sign_extend:GPI 3048 (ashiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r") 3049 (match_operand 2 "const_int_operand" "n"))))] 3050 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)" 3051{ 3052 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2])); 3053 return "sbfx\\t%<GPI:w>0, %<GPI:w>1, %2, %3"; 3054} 3055 [(set_attr "type" "bfm")] 3056) 3057 3058;; ------------------------------------------------------------------- 3059;; Bitfields 3060;; ------------------------------------------------------------------- 3061 3062(define_expand "<optab>" 3063 [(set (match_operand:DI 0 "register_operand" "=r") 3064 (ANY_EXTRACT:DI (match_operand:DI 1 "register_operand" "r") 3065 (match_operand 2 "const_int_operand" "n") 3066 (match_operand 3 "const_int_operand" "n")))] 3067 "" 3068 "" 3069) 3070 3071(define_insn "*<optab><mode>" 3072 [(set (match_operand:GPI 0 "register_operand" "=r") 3073 (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r") 3074 (match_operand 2 "const_int_operand" "n") 3075 (match_operand 3 "const_int_operand" "n")))] 3076 "" 3077 "<su>bfx\\t%<w>0, %<w>1, %3, %2" 3078 [(set_attr "type" "bfm")] 3079) 3080 3081;; Bitfield Insert (insv) 3082(define_expand "insv<mode>" 3083 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand") 3084 (match_operand 1 "const_int_operand") 3085 (match_operand 2 "const_int_operand")) 3086 (match_operand:GPI 3 "general_operand"))] 3087 "" 3088{ 3089 unsigned HOST_WIDE_INT width = UINTVAL (operands[1]); 3090 unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]); 3091 rtx value = operands[3]; 3092 3093 if (width == 0 || (pos + width) > GET_MODE_BITSIZE (<MODE>mode)) 3094 FAIL; 3095 3096 if (CONST_INT_P (value)) 3097 { 3098 unsigned HOST_WIDE_INT mask = ((unsigned HOST_WIDE_INT)1 << width) - 1; 3099 3100 /* Prefer AND/OR for inserting all zeros or all ones. */ 3101 if ((UINTVAL (value) & mask) == 0 3102 || (UINTVAL (value) & mask) == mask) 3103 FAIL; 3104 3105 /* 16-bit aligned 16-bit wide insert is handled by insv_imm. */ 3106 if (width == 16 && (pos % 16) == 0) 3107 DONE; 3108 } 3109 operands[3] = force_reg (<MODE>mode, value); 3110}) 3111 3112(define_insn "*insv_reg<mode>" 3113 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r") 3114 (match_operand 1 "const_int_operand" "n") 3115 (match_operand 2 "const_int_operand" "n")) 3116 (match_operand:GPI 3 "register_operand" "r"))] 3117 "!(UINTVAL (operands[1]) == 0 3118 || (UINTVAL (operands[2]) + UINTVAL (operands[1]) 3119 > GET_MODE_BITSIZE (<MODE>mode)))" 3120 "bfi\\t%<w>0, %<w>3, %2, %1" 3121 [(set_attr "type" "bfm")] 3122) 3123 3124(define_insn "*extr_insv_lower_reg<mode>" 3125 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r") 3126 (match_operand 1 "const_int_operand" "n") 3127 (const_int 0)) 3128 (zero_extract:GPI (match_operand:GPI 2 "register_operand" "+r") 3129 (match_dup 1) 3130 (match_operand 3 "const_int_operand" "n")))] 3131 "!(UINTVAL (operands[1]) == 0 3132 || (UINTVAL (operands[3]) + UINTVAL (operands[1]) 3133 > GET_MODE_BITSIZE (<MODE>mode)))" 3134 "bfxil\\t%<w>0, %<w>2, %3, %1" 3135 [(set_attr "type" "bfm")] 3136) 3137 3138(define_insn "*<optab><ALLX:mode>_shft_<GPI:mode>" 3139 [(set (match_operand:GPI 0 "register_operand" "=r") 3140 (ashift:GPI (ANY_EXTEND:GPI 3141 (match_operand:ALLX 1 "register_operand" "r")) 3142 (match_operand 2 "const_int_operand" "n")))] 3143 "UINTVAL (operands[2]) < <GPI:sizen>" 3144{ 3145 operands[3] = (<ALLX:sizen> <= (<GPI:sizen> - UINTVAL (operands[2]))) 3146 ? GEN_INT (<ALLX:sizen>) 3147 : GEN_INT (<GPI:sizen> - UINTVAL (operands[2])); 3148 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3"; 3149} 3150 [(set_attr "type" "bfm")] 3151) 3152 3153;; XXX We should match (any_extend (ashift)) here, like (and (ashift)) below 3154 3155(define_insn "*andim_ashift<mode>_bfiz" 3156 [(set (match_operand:GPI 0 "register_operand" "=r") 3157 (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r") 3158 (match_operand 2 "const_int_operand" "n")) 3159 (match_operand 3 "const_int_operand" "n")))] 3160 "(INTVAL (operands[2]) < (<GPI:sizen>)) 3161 && exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0 3162 && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0" 3163 "ubfiz\\t%<w>0, %<w>1, %2, %P3" 3164 [(set_attr "type" "bfm")] 3165) 3166 3167(define_insn "bswap<mode>2" 3168 [(set (match_operand:GPI 0 "register_operand" "=r") 3169 (bswap:GPI (match_operand:GPI 1 "register_operand" "r")))] 3170 "" 3171 "rev\\t%<w>0, %<w>1" 3172 [(set_attr "type" "rev")] 3173) 3174 3175(define_insn "bswaphi2" 3176 [(set (match_operand:HI 0 "register_operand" "=r") 3177 (bswap:HI (match_operand:HI 1 "register_operand" "r")))] 3178 "" 3179 "rev16\\t%w0, %w1" 3180 [(set_attr "type" "rev")] 3181) 3182 3183;; zero_extend version of above 3184(define_insn "*bswapsi2_uxtw" 3185 [(set (match_operand:DI 0 "register_operand" "=r") 3186 (zero_extend:DI (bswap:SI (match_operand:SI 1 "register_operand" "r"))))] 3187 "" 3188 "rev\\t%w0, %w1" 3189 [(set_attr "type" "rev")] 3190) 3191 3192;; ------------------------------------------------------------------- 3193;; Floating-point intrinsics 3194;; ------------------------------------------------------------------- 3195 3196;; frint floating-point round to integral standard patterns. 3197;; Expands to btrunc, ceil, floor, nearbyint, rint, round. 3198 3199(define_insn "<frint_pattern><mode>2" 3200 [(set (match_operand:GPF 0 "register_operand" "=w") 3201 (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")] 3202 FRINT))] 3203 "TARGET_FLOAT" 3204 "frint<frint_suffix>\\t%<s>0, %<s>1" 3205 [(set_attr "type" "f_rint<s>")] 3206) 3207 3208;; frcvt floating-point round to integer and convert standard patterns. 3209;; Expands to lbtrunc, lceil, lfloor, lround. 3210(define_insn "l<fcvt_pattern><su_optab><GPF:mode><GPI:mode>2" 3211 [(set (match_operand:GPI 0 "register_operand" "=r") 3212 (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")] 3213 FCVT)))] 3214 "TARGET_FLOAT" 3215 "fcvt<frint_suffix><su>\\t%<GPI:w>0, %<GPF:s>1" 3216 [(set_attr "type" "f_cvtf2i")] 3217) 3218 3219;; fma - no throw 3220 3221(define_insn "fma<mode>4" 3222 [(set (match_operand:GPF 0 "register_operand" "=w") 3223 (fma:GPF (match_operand:GPF 1 "register_operand" "w") 3224 (match_operand:GPF 2 "register_operand" "w") 3225 (match_operand:GPF 3 "register_operand" "w")))] 3226 "TARGET_FLOAT" 3227 "fmadd\\t%<s>0, %<s>1, %<s>2, %<s>3" 3228 [(set_attr "type" "fmac<s>")] 3229) 3230 3231(define_insn "fnma<mode>4" 3232 [(set (match_operand:GPF 0 "register_operand" "=w") 3233 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w")) 3234 (match_operand:GPF 2 "register_operand" "w") 3235 (match_operand:GPF 3 "register_operand" "w")))] 3236 "TARGET_FLOAT" 3237 "fmsub\\t%<s>0, %<s>1, %<s>2, %<s>3" 3238 [(set_attr "type" "fmac<s>")] 3239) 3240 3241(define_insn "fms<mode>4" 3242 [(set (match_operand:GPF 0 "register_operand" "=w") 3243 (fma:GPF (match_operand:GPF 1 "register_operand" "w") 3244 (match_operand:GPF 2 "register_operand" "w") 3245 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))] 3246 "TARGET_FLOAT" 3247 "fnmsub\\t%<s>0, %<s>1, %<s>2, %<s>3" 3248 [(set_attr "type" "fmac<s>")] 3249) 3250 3251(define_insn "fnms<mode>4" 3252 [(set (match_operand:GPF 0 "register_operand" "=w") 3253 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w")) 3254 (match_operand:GPF 2 "register_operand" "w") 3255 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))] 3256 "TARGET_FLOAT" 3257 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3" 3258 [(set_attr "type" "fmac<s>")] 3259) 3260 3261;; If signed zeros are ignored, -(a * b + c) = -a * b - c. 3262(define_insn "*fnmadd<mode>4" 3263 [(set (match_operand:GPF 0 "register_operand" "=w") 3264 (neg:GPF (fma:GPF (match_operand:GPF 1 "register_operand" "w") 3265 (match_operand:GPF 2 "register_operand" "w") 3266 (match_operand:GPF 3 "register_operand" "w"))))] 3267 "!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT" 3268 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3" 3269 [(set_attr "type" "fmac<s>")] 3270) 3271 3272;; ------------------------------------------------------------------- 3273;; Floating-point conversions 3274;; ------------------------------------------------------------------- 3275 3276(define_insn "extendsfdf2" 3277 [(set (match_operand:DF 0 "register_operand" "=w") 3278 (float_extend:DF (match_operand:SF 1 "register_operand" "w")))] 3279 "TARGET_FLOAT" 3280 "fcvt\\t%d0, %s1" 3281 [(set_attr "type" "f_cvt")] 3282) 3283 3284(define_insn "truncdfsf2" 3285 [(set (match_operand:SF 0 "register_operand" "=w") 3286 (float_truncate:SF (match_operand:DF 1 "register_operand" "w")))] 3287 "TARGET_FLOAT" 3288 "fcvt\\t%s0, %d1" 3289 [(set_attr "type" "f_cvt")] 3290) 3291 3292(define_insn "fix_trunc<GPF:mode><GPI:mode>2" 3293 [(set (match_operand:GPI 0 "register_operand" "=r") 3294 (fix:GPI (match_operand:GPF 1 "register_operand" "w")))] 3295 "TARGET_FLOAT" 3296 "fcvtzs\\t%<GPI:w>0, %<GPF:s>1" 3297 [(set_attr "type" "f_cvtf2i")] 3298) 3299 3300(define_insn "fixuns_trunc<GPF:mode><GPI:mode>2" 3301 [(set (match_operand:GPI 0 "register_operand" "=r") 3302 (unsigned_fix:GPI (match_operand:GPF 1 "register_operand" "w")))] 3303 "TARGET_FLOAT" 3304 "fcvtzu\\t%<GPI:w>0, %<GPF:s>1" 3305 [(set_attr "type" "f_cvtf2i")] 3306) 3307 3308(define_insn "float<GPI:mode><GPF:mode>2" 3309 [(set (match_operand:GPF 0 "register_operand" "=w") 3310 (float:GPF (match_operand:GPI 1 "register_operand" "r")))] 3311 "TARGET_FLOAT" 3312 "scvtf\\t%<GPF:s>0, %<GPI:w>1" 3313 [(set_attr "type" "f_cvti2f")] 3314) 3315 3316(define_insn "floatuns<GPI:mode><GPF:mode>2" 3317 [(set (match_operand:GPF 0 "register_operand" "=w") 3318 (unsigned_float:GPF (match_operand:GPI 1 "register_operand" "r")))] 3319 "TARGET_FLOAT" 3320 "ucvtf\\t%<GPF:s>0, %<GPI:w>1" 3321 [(set_attr "type" "f_cvt")] 3322) 3323 3324;; ------------------------------------------------------------------- 3325;; Floating-point arithmetic 3326;; ------------------------------------------------------------------- 3327 3328(define_insn "add<mode>3" 3329 [(set (match_operand:GPF 0 "register_operand" "=w") 3330 (plus:GPF 3331 (match_operand:GPF 1 "register_operand" "w") 3332 (match_operand:GPF 2 "register_operand" "w")))] 3333 "TARGET_FLOAT" 3334 "fadd\\t%<s>0, %<s>1, %<s>2" 3335 [(set_attr "type" "fadd<s>")] 3336) 3337 3338(define_insn "sub<mode>3" 3339 [(set (match_operand:GPF 0 "register_operand" "=w") 3340 (minus:GPF 3341 (match_operand:GPF 1 "register_operand" "w") 3342 (match_operand:GPF 2 "register_operand" "w")))] 3343 "TARGET_FLOAT" 3344 "fsub\\t%<s>0, %<s>1, %<s>2" 3345 [(set_attr "type" "fadd<s>")] 3346) 3347 3348(define_insn "mul<mode>3" 3349 [(set (match_operand:GPF 0 "register_operand" "=w") 3350 (mult:GPF 3351 (match_operand:GPF 1 "register_operand" "w") 3352 (match_operand:GPF 2 "register_operand" "w")))] 3353 "TARGET_FLOAT" 3354 "fmul\\t%<s>0, %<s>1, %<s>2" 3355 [(set_attr "type" "fmul<s>")] 3356) 3357 3358(define_insn "*fnmul<mode>3" 3359 [(set (match_operand:GPF 0 "register_operand" "=w") 3360 (mult:GPF 3361 (neg:GPF (match_operand:GPF 1 "register_operand" "w")) 3362 (match_operand:GPF 2 "register_operand" "w")))] 3363 "TARGET_FLOAT" 3364 "fnmul\\t%<s>0, %<s>1, %<s>2" 3365 [(set_attr "type" "fmul<s>")] 3366) 3367 3368(define_insn "div<mode>3" 3369 [(set (match_operand:GPF 0 "register_operand" "=w") 3370 (div:GPF 3371 (match_operand:GPF 1 "register_operand" "w") 3372 (match_operand:GPF 2 "register_operand" "w")))] 3373 "TARGET_FLOAT" 3374 "fdiv\\t%<s>0, %<s>1, %<s>2" 3375 [(set_attr "type" "fdiv<s>")] 3376) 3377 3378(define_insn "neg<mode>2" 3379 [(set (match_operand:GPF 0 "register_operand" "=w") 3380 (neg:GPF (match_operand:GPF 1 "register_operand" "w")))] 3381 "TARGET_FLOAT" 3382 "fneg\\t%<s>0, %<s>1" 3383 [(set_attr "type" "ffarith<s>")] 3384) 3385 3386(define_insn "sqrt<mode>2" 3387 [(set (match_operand:GPF 0 "register_operand" "=w") 3388 (sqrt:GPF (match_operand:GPF 1 "register_operand" "w")))] 3389 "TARGET_FLOAT" 3390 "fsqrt\\t%<s>0, %<s>1" 3391 [(set_attr "type" "fsqrt<s>")] 3392) 3393 3394(define_insn "abs<mode>2" 3395 [(set (match_operand:GPF 0 "register_operand" "=w") 3396 (abs:GPF (match_operand:GPF 1 "register_operand" "w")))] 3397 "TARGET_FLOAT" 3398 "fabs\\t%<s>0, %<s>1" 3399 [(set_attr "type" "ffarith<s>")] 3400) 3401 3402;; Given that smax/smin do not specify the result when either input is NaN, 3403;; we could use either FMAXNM or FMAX for smax, and either FMINNM or FMIN 3404;; for smin. 3405 3406(define_insn "smax<mode>3" 3407 [(set (match_operand:GPF 0 "register_operand" "=w") 3408 (smax:GPF (match_operand:GPF 1 "register_operand" "w") 3409 (match_operand:GPF 2 "register_operand" "w")))] 3410 "TARGET_FLOAT" 3411 "fmaxnm\\t%<s>0, %<s>1, %<s>2" 3412 [(set_attr "type" "f_minmax<s>")] 3413) 3414 3415(define_insn "smin<mode>3" 3416 [(set (match_operand:GPF 0 "register_operand" "=w") 3417 (smin:GPF (match_operand:GPF 1 "register_operand" "w") 3418 (match_operand:GPF 2 "register_operand" "w")))] 3419 "TARGET_FLOAT" 3420 "fminnm\\t%<s>0, %<s>1, %<s>2" 3421 [(set_attr "type" "f_minmax<s>")] 3422) 3423 3424;; ------------------------------------------------------------------- 3425;; Reload support 3426;; ------------------------------------------------------------------- 3427 3428(define_expand "aarch64_reload_mov<mode>" 3429 [(set (match_operand:TX 0 "register_operand" "=w") 3430 (match_operand:TX 1 "register_operand" "w")) 3431 (clobber (match_operand:DI 2 "register_operand" "=&r")) 3432 ] 3433 "" 3434 { 3435 rtx op0 = simplify_gen_subreg (TImode, operands[0], <MODE>mode, 0); 3436 rtx op1 = simplify_gen_subreg (TImode, operands[1], <MODE>mode, 0); 3437 gen_aarch64_movtilow_tilow (op0, op1); 3438 gen_aarch64_movdi_tihigh (operands[2], op1); 3439 gen_aarch64_movtihigh_di (op0, operands[2]); 3440 DONE; 3441 } 3442) 3443 3444;; The following secondary reload helpers patterns are invoked 3445;; after or during reload as we don't want these patterns to start 3446;; kicking in during the combiner. 3447 3448(define_insn "aarch64_movdi_<mode>low" 3449 [(set (match_operand:DI 0 "register_operand" "=r") 3450 (truncate:DI (match_operand:TX 1 "register_operand" "w")))] 3451 "reload_completed || reload_in_progress" 3452 "fmov\\t%x0, %d1" 3453 [(set_attr "type" "f_mrc") 3454 (set_attr "length" "4") 3455 ]) 3456 3457(define_insn "aarch64_movdi_<mode>high" 3458 [(set (match_operand:DI 0 "register_operand" "=r") 3459 (truncate:DI 3460 (lshiftrt:TX (match_operand:TX 1 "register_operand" "w") 3461 (const_int 64))))] 3462 "reload_completed || reload_in_progress" 3463 "fmov\\t%x0, %1.d[1]" 3464 [(set_attr "type" "f_mrc") 3465 (set_attr "length" "4") 3466 ]) 3467 3468(define_insn "aarch64_mov<mode>high_di" 3469 [(set (zero_extract:TX (match_operand:TX 0 "register_operand" "+w") 3470 (const_int 64) (const_int 64)) 3471 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))] 3472 "reload_completed || reload_in_progress" 3473 "fmov\\t%0.d[1], %x1" 3474 [(set_attr "type" "f_mcr") 3475 (set_attr "length" "4") 3476 ]) 3477 3478(define_insn "aarch64_mov<mode>low_di" 3479 [(set (match_operand:TX 0 "register_operand" "=w") 3480 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))] 3481 "reload_completed || reload_in_progress" 3482 "fmov\\t%d0, %x1" 3483 [(set_attr "type" "f_mcr") 3484 (set_attr "length" "4") 3485 ]) 3486 3487(define_insn "aarch64_movtilow_tilow" 3488 [(set (match_operand:TI 0 "register_operand" "=w") 3489 (zero_extend:TI 3490 (truncate:DI (match_operand:TI 1 "register_operand" "w"))))] 3491 "reload_completed || reload_in_progress" 3492 "fmov\\t%d0, %d1" 3493 [(set_attr "type" "f_mcr") 3494 (set_attr "length" "4") 3495 ]) 3496 3497;; There is a deliberate reason why the parameters of high and lo_sum's 3498;; don't have modes for ADRP and ADD instructions. This is to allow high 3499;; and lo_sum's to be used with the labels defining the jump tables in 3500;; rodata section. 3501 3502(define_expand "add_losym" 3503 [(set (match_operand 0 "register_operand" "=r") 3504 (lo_sum (match_operand 1 "register_operand" "r") 3505 (match_operand 2 "aarch64_valid_symref" "S")))] 3506 "" 3507{ 3508 enum machine_mode mode = GET_MODE (operands[0]); 3509 3510 emit_insn ((mode == DImode 3511 ? gen_add_losym_di 3512 : gen_add_losym_si) (operands[0], 3513 operands[1], 3514 operands[2])); 3515 DONE; 3516}) 3517 3518(define_insn "add_losym_<mode>" 3519 [(set (match_operand:P 0 "register_operand" "=r") 3520 (lo_sum:P (match_operand:P 1 "register_operand" "r") 3521 (match_operand 2 "aarch64_valid_symref" "S")))] 3522 "" 3523 "add\\t%<w>0, %<w>1, :lo12:%a2" 3524 [(set_attr "type" "alu_reg")] 3525) 3526 3527(define_insn "ldr_got_small_<mode>" 3528 [(set (match_operand:PTR 0 "register_operand" "=r") 3529 (unspec:PTR [(mem:PTR (lo_sum:PTR 3530 (match_operand:PTR 1 "register_operand" "r") 3531 (match_operand:PTR 2 "aarch64_valid_symref" "S")))] 3532 UNSPEC_GOTSMALLPIC))] 3533 "" 3534 "ldr\\t%<w>0, [%1, #:got_lo12:%a2]" 3535 [(set_attr "type" "load1")] 3536) 3537 3538(define_insn "ldr_got_small_sidi" 3539 [(set (match_operand:DI 0 "register_operand" "=r") 3540 (zero_extend:DI 3541 (unspec:SI [(mem:SI (lo_sum:DI 3542 (match_operand:DI 1 "register_operand" "r") 3543 (match_operand:DI 2 "aarch64_valid_symref" "S")))] 3544 UNSPEC_GOTSMALLPIC)))] 3545 "TARGET_ILP32" 3546 "ldr\\t%w0, [%1, #:got_lo12:%a2]" 3547 [(set_attr "type" "load1")] 3548) 3549 3550(define_insn "ldr_got_tiny" 3551 [(set (match_operand:DI 0 "register_operand" "=r") 3552 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] 3553 UNSPEC_GOTTINYPIC))] 3554 "" 3555 "ldr\\t%0, %L1" 3556 [(set_attr "type" "load1")] 3557) 3558 3559(define_insn "aarch64_load_tp_hard" 3560 [(set (match_operand:DI 0 "register_operand" "=r") 3561 (unspec:DI [(const_int 0)] UNSPEC_TLS))] 3562 "" 3563 "mrs\\t%0, tpidr_el0" 3564 [(set_attr "type" "mrs")] 3565) 3566 3567;; The TLS ABI specifically requires that the compiler does not schedule 3568;; instructions in the TLS stubs, in order to enable linker relaxation. 3569;; Therefore we treat the stubs as an atomic sequence. 3570(define_expand "tlsgd_small" 3571 [(parallel [(set (match_operand 0 "register_operand" "") 3572 (call (mem:DI (match_dup 2)) (const_int 1))) 3573 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "")] UNSPEC_GOTSMALLTLS) 3574 (clobber (reg:DI LR_REGNUM))])] 3575 "" 3576{ 3577 operands[2] = aarch64_tls_get_addr (); 3578}) 3579 3580(define_insn "*tlsgd_small" 3581 [(set (match_operand 0 "register_operand" "") 3582 (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1))) 3583 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] UNSPEC_GOTSMALLTLS) 3584 (clobber (reg:DI LR_REGNUM)) 3585 ] 3586 "" 3587 "adrp\\tx0, %A1\;add\\tx0, x0, %L1\;bl\\t%2\;nop" 3588 [(set_attr "type" "call") 3589 (set_attr "length" "16")]) 3590 3591(define_insn "tlsie_small" 3592 [(set (match_operand:DI 0 "register_operand" "=r") 3593 (unspec:DI [(match_operand:DI 1 "aarch64_tls_ie_symref" "S")] 3594 UNSPEC_GOTSMALLTLS))] 3595 "" 3596 "adrp\\t%0, %A1\;ldr\\t%0, [%0, #%L1]" 3597 [(set_attr "type" "load1") 3598 (set_attr "length" "8")] 3599) 3600 3601(define_insn "tlsle_small" 3602 [(set (match_operand:DI 0 "register_operand" "=r") 3603 (unspec:DI [(match_operand:DI 1 "register_operand" "r") 3604 (match_operand:DI 2 "aarch64_tls_le_symref" "S")] 3605 UNSPEC_GOTSMALLTLS))] 3606 "" 3607 "add\\t%0, %1, #%G2\;add\\t%0, %0, #%L2" 3608 [(set_attr "type" "alu_reg") 3609 (set_attr "length" "8")] 3610) 3611 3612(define_insn "tlsdesc_small" 3613 [(set (reg:DI R0_REGNUM) 3614 (unspec:DI [(match_operand:DI 0 "aarch64_valid_symref" "S")] 3615 UNSPEC_TLSDESC)) 3616 (clobber (reg:DI LR_REGNUM)) 3617 (clobber (reg:CC CC_REGNUM)) 3618 (clobber (match_scratch:DI 1 "=r"))] 3619 "TARGET_TLS_DESC" 3620 "adrp\\tx0, %A0\;ldr\\t%1, [x0, #%L0]\;add\\tx0, x0, %L0\;.tlsdesccall\\t%0\;blr\\t%1" 3621 [(set_attr "type" "call") 3622 (set_attr "length" "16")]) 3623 3624(define_insn "stack_tie" 3625 [(set (mem:BLK (scratch)) 3626 (unspec:BLK [(match_operand:DI 0 "register_operand" "rk") 3627 (match_operand:DI 1 "register_operand" "rk")] 3628 UNSPEC_PRLG_STK))] 3629 "" 3630 "" 3631 [(set_attr "length" "0")] 3632) 3633 3634;; Named pattern for expanding thread pointer reference. 3635(define_expand "get_thread_pointerdi" 3636 [(match_operand:DI 0 "register_operand" "=r")] 3637 "" 3638{ 3639 rtx tmp = aarch64_load_tp (operands[0]); 3640 if (tmp != operands[0]) 3641 emit_move_insn (operands[0], tmp); 3642 DONE; 3643}) 3644 3645;; AdvSIMD Stuff 3646(include "aarch64-simd.md") 3647 3648;; Atomic Operations 3649(include "atomics.md") 3650