1;; Machine description for TI C6X. 2;; Copyright (C) 2010-2020 Free Software Foundation, Inc. 3;; Contributed by Andrew Jenner <andrew@codesourcery.com> 4;; Contributed by Bernd Schmidt <bernds@codesourcery.com> 5;; Contributed by CodeSourcery. 6;; 7;; This file is part of GCC. 8;; 9;; GCC is free software; you can redistribute it and/or modify 10;; it under the terms of the GNU General Public License as published by 11;; the Free Software Foundation; either version 3, or (at your option) 12;; any later version. 13;; 14;; GCC is distributed in the hope that it will be useful, 15;; but WITHOUT ANY WARRANTY; without even the implied warranty of 16;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17;; GNU General Public License for more details. 18;; 19;; You should have received a copy of the GNU General Public License 20;; along with GCC; see the file COPYING3. If not see 21;; <http://www.gnu.org/licenses/>. 22 23 24;; Register names 25 26(define_constants 27 [(REG_A0 0) 28 (REG_A1 1) 29 (REG_A2 2) 30 (REG_A3 3) 31 (REG_A4 4) 32 (REG_A5 5) 33 (REG_A6 6) 34 (REG_A7 7) 35 (REG_A8 8) 36 (REG_A9 9) 37 (REG_A10 10) 38 (REG_A11 11) 39 (REG_A12 12) 40 (REG_A13 13) 41 (REG_A14 14) 42 (REG_A15 15) 43 (REG_A16 16) 44 (REG_A17 17) 45 (REG_A18 18) 46 (REG_A19 19) 47 (REG_A20 20) 48 (REG_A21 21) 49 (REG_A22 22) 50 (REG_A23 23) 51 (REG_A24 24) 52 (REG_A25 25) 53 (REG_A26 26) 54 (REG_A27 27) 55 (REG_A28 28) 56 (REG_A29 29) 57 (REG_A30 30) 58 (REG_A31 31) 59 (REG_B0 32) 60 (REG_B1 33) 61 (REG_B2 34) 62 (REG_B3 35) 63 (REG_B4 36) 64 (REG_B5 37) 65 (REG_B6 38) 66 (REG_B7 39) 67 (REG_B8 40) 68 (REG_B9 41) 69 (REG_B10 42) 70 (REG_B11 43) 71 (REG_B12 44) 72 (REG_B13 45) 73 (REG_B14 46) 74 (REG_SP 47) 75 (REG_B15 47) 76 (REG_B16 48) 77 (REG_B17 49) 78 (REG_B18 50) 79 (REG_B19 51) 80 (REG_B20 52) 81 (REG_B21 53) 82 (REG_B22 54) 83 (REG_B23 55) 84 (REG_B24 56) 85 (REG_B25 57) 86 (REG_B26 58) 87 (REG_B27 59) 88 (REG_B28 60) 89 (REG_B29 61) 90 (REG_B30 62) 91 (REG_B31 63) 92 (REG_FRAME 64) 93 (REG_ARGP 65) 94 (REG_ILC 66)]) 95 96(define_c_enum "unspec" [ 97 UNSPEC_NOP 98 UNSPEC_RCP 99 UNSPEC_MISALIGNED_ACCESS 100 UNSPEC_ADDKPC 101 UNSPEC_SETUP_DSBT 102 UNSPEC_LOAD_GOT 103 UNSPEC_LOAD_SDATA 104 UNSPEC_BITREV 105 UNSPEC_GOTOFF 106 UNSPEC_MVILC 107 UNSPEC_REAL_JUMP 108 UNSPEC_REAL_LOAD 109 UNSPEC_REAL_MULT 110 UNSPEC_JUMP_SHADOW 111 UNSPEC_LOAD_SHADOW 112 UNSPEC_MULT_SHADOW 113 UNSPEC_EPILOGUE_BARRIER 114 UNSPEC_ATOMIC 115 UNSPEC_CLR 116 UNSPEC_EXT 117 UNSPEC_EXTU 118 UNSPEC_SUBC 119 UNSPEC_AVG 120]) 121 122(define_c_enum "unspecv" [ 123 UNSPECV_BLOCKAGE 124 UNSPECV_SPLOOP 125 UNSPECV_SPKERNEL 126 UNSPECV_EH_RETURN 127 UNSPECV_CAS 128]) 129 130;; ------------------------------------------------------------------------- 131;; Instruction attributes 132;; ------------------------------------------------------------------------- 133 134(define_attr "cpu" 135 "c62x,c64x,c64xp,c67x,c67xp,c674x" 136 (const (symbol_ref "(enum attr_cpu)c6x_arch"))) 137 138;; Define a type for each insn which is used in the scheduling description. 139;; These correspond to the types defined in chapter 4 of the C674x manual. 140(define_attr "type" 141 "unknown,single,mpy2,store,storen,mpy4,load,loadn,branch,call,callp,dp2,fp4, 142 intdp,cmpdp,adddp,mpy,mpyi,mpyid,mpydp,mpyspdp,mpysp2dp,spkernel,sploop, 143 mvilc,blockage,shadow,load_shadow,mult_shadow,atomic" 144 (const_string "single")) 145 146;; The register file used by an instruction's destination register. 147;; The function destreg_file computes this; instructions can override the 148;; attribute if they aren't a single_set. 149(define_attr "dest_regfile" 150 "unknown,any,a,b" 151 (cond [(eq_attr "type" "single,load,mpy2,mpy4,dp2,fp4,intdp,cmpdp,adddp,mpy,mpyi,mpyid,mpydp,mpyspdp,mpysp2dp") 152 (cond [(match_operand 0 "a_register" "") (const_string "a") 153 (match_operand 0 "b_register" "") (const_string "b")] 154 (const_string "unknown")) 155 (eq_attr "type" "store") 156 (cond [(match_operand 1 "a_register" "") (const_string "a") 157 (match_operand 1 "b_register" "") (const_string "b")] 158 (const_string "unknown"))] 159 (const_string "unknown"))) 160 161(define_attr "addr_regfile" 162 "unknown,a,b" 163 (const_string "unknown")) 164 165(define_attr "cross" 166 "n,y" 167 (const_string "n")) 168 169;; This describes the relationship between operands and register files. 170;; For example, "sxs" means that operands 0 and 2 determine the side of 171;; the machine, and operand 1 can optionally use the cross path. "dt" and 172;; "td" are used to describe loads and stores. 173;; Used for register renaming in loops for improving modulo scheduling. 174(define_attr "op_pattern" 175 "unknown,dt,td,sx,sxs,ssx" 176 (cond [(eq_attr "type" "load") (const_string "td") 177 (eq_attr "type" "store") (const_string "dt")] 178 (const_string "unknown"))) 179 180(define_attr "has_shadow" 181 "n,y" 182 (const_string "n")) 183 184;; The number of cycles the instruction takes to finish. Any cycles above 185;; the first are delay slots. 186(define_attr "cycles" "" 187 (cond [(eq_attr "type" "branch,call") (const_int 6) 188 (eq_attr "type" "load,loadn") (const_int 5) 189 (eq_attr "type" "dp2") (const_int 2) 190 (eq_attr "type" "mpy2") (const_int 2) 191 (eq_attr "type" "mpy4") (const_int 4) 192 (eq_attr "type" "fp4") (const_int 4) 193 (eq_attr "type" "mvilc") (const_int 4) 194 (eq_attr "type" "cmpdp") (const_int 2) 195 (eq_attr "type" "intdp") (const_int 5) 196 (eq_attr "type" "adddp") (const_int 7) 197 (eq_attr "type" "mpydp") (const_int 10) 198 (eq_attr "type" "mpyi") (const_int 9) 199 (eq_attr "type" "mpyid") (const_int 10) 200 (eq_attr "type" "mpyspdp") (const_int 7) 201 (eq_attr "type" "mpysp2dp") (const_int 5)] 202 (const_int 1))) 203 204;; The number of cycles during which the instruction reserves functional 205;; units. 206(define_attr "reserve_cycles" "" 207 (cond [(eq_attr "type" "cmpdp") (const_int 2) 208 (eq_attr "type" "adddp") (const_int 2) 209 (eq_attr "type" "mpydp") (const_int 4) 210 (eq_attr "type" "mpyi") (const_int 4) 211 (eq_attr "type" "mpyid") (const_int 4) 212 (eq_attr "type" "mpyspdp") (const_int 2)] 213 (const_int 1))) 214 215(define_attr "predicable" "no,yes" 216 (const_string "yes")) 217 218(define_attr "enabled" "no,yes" 219 (const_string "yes")) 220 221;; Specify which units can be used by a given instruction. Normally, 222;; dest_regfile is used to select between the two halves of the machine. 223;; D_ADDR is for load/store instructions; they use the D unit and use 224;; addr_regfile to choose between D1 and D2. 225 226(define_attr "units62" 227 "unknown,d,d_addr,l,m,s,dl,ds,dls,ls" 228 (const_string "unknown")) 229 230(define_attr "units64" 231 "unknown,d,d_addr,l,m,s,dl,ds,dls,ls" 232 (const_string "unknown")) 233 234(define_attr "units64p" 235 "unknown,d,d_addr,l,m,s,dl,ds,dls,ls" 236 (attr "units64")) 237 238(define_attr "units67" 239 "unknown,d,d_addr,l,m,s,dl,ds,dls,ls" 240 (attr "units62")) 241 242(define_attr "units67p" 243 "unknown,d,d_addr,l,m,s,dl,ds,dls,ls" 244 (attr "units67")) 245 246(define_attr "units674" 247 "unknown,d,d_addr,l,m,s,dl,ds,dls,ls" 248 (attr "units64")) 249 250(define_attr "units" 251 "unknown,d,d_addr,l,m,s,dl,ds,dls,ls" 252 (cond [(eq_attr "cpu" "c62x") 253 (attr "units62") 254 (eq_attr "cpu" "c67x") 255 (attr "units67") 256 (eq_attr "cpu" "c67xp") 257 (attr "units67p") 258 (eq_attr "cpu" "c64x") 259 (attr "units64") 260 (eq_attr "cpu" "c64xp") 261 (attr "units64p") 262 (eq_attr "cpu" "c674x") 263 (attr "units674") 264 ] 265 (const_string "unknown"))) 266 267(define_automaton "c6x_1,c6x_2,c6x_m1,c6x_m2,c6x_t1,c6x_t2,c6x_branch") 268(automata_option "no-comb-vect") 269(automata_option "ndfa") 270(automata_option "collapse-ndfa") 271 272(define_query_cpu_unit "d1,l1,s1" "c6x_1") 273(define_cpu_unit "x1" "c6x_1") 274(define_cpu_unit "l1w,s1w" "c6x_1") 275(define_query_cpu_unit "m1" "c6x_m1") 276(define_cpu_unit "m1w" "c6x_m1") 277(define_cpu_unit "t1" "c6x_t1") 278(define_query_cpu_unit "d2,l2,s2" "c6x_2") 279(define_cpu_unit "x2" "c6x_2") 280(define_cpu_unit "l2w,s2w" "c6x_2") 281(define_query_cpu_unit "m2" "c6x_m2") 282(define_cpu_unit "m2w" "c6x_m2") 283(define_cpu_unit "t2" "c6x_t2") 284;; A special set of units used to identify specific reservations, rather than 285;; just units. 286(define_query_cpu_unit "fps1,fpl1,adddps1,adddpl1" "c6x_1") 287(define_query_cpu_unit "fps2,fpl2,adddps2,adddpl2" "c6x_2") 288 289;; There can be up to two branches in one cycle (on the .s1 and .s2 290;; units), but some instructions must not be scheduled in parallel 291;; with a branch. We model this by reserving either br0 or br1 for a 292;; normal branch, and both of them for an insn such as callp. 293;; Another constraint is that two branches may only execute in parallel 294;; if one uses an offset, and the other a register. We can distinguish 295;; these by the dest_regfile attribute; it is "any" iff the branch uses 296;; an offset. br0 is reserved for these, while br1 is reserved for 297;; branches using a register. 298(define_cpu_unit "br0,br1" "c6x_branch") 299 300(include "c6x-sched.md") 301 302;; Some reservations which aren't generated from c6x-sched.md.in 303 304(define_insn_reservation "branch_s1any" 6 305 (and (eq_attr "type" "branch") 306 (and (eq_attr "cross" "n") 307 (and (eq_attr "units" "s") 308 (eq_attr "dest_regfile" "any")))) 309 "s1+s1w+br0") 310 311;; For calls, we also reserve the units needed in the following cycles 312;; to load the return address. There are two options; using addkpc or 313;; mvkh/mvkl. The code in c6x_reorg knows whether to use one of these 314;; or whether to use callp. The actual insns are emitted only after 315;; the final scheduling pass is complete. 316;; We always reserve S2 for PC-relative call insns, since that allows 317;; us to turn them into callp insns later on. 318(define_insn_reservation "call_addkpc_s1any" 6 319 (and (eq_attr "type" "call") 320 (and (ne (symbol_ref "TARGET_INSNS_64") (const_int 0)) 321 (and (eq_attr "cross" "n") 322 (and (eq_attr "units" "s") 323 (eq_attr "dest_regfile" "any"))))) 324 "s2+s2w+br0,s2+s2w+br0+br1") 325 326(define_insn_reservation "call_mvk_s1any" 6 327 (and (eq_attr "type" "call") 328 (and (eq (symbol_ref "TARGET_INSNS_64") (const_int 0)) 329 (and (eq_attr "cross" "n") 330 (and (eq_attr "units" "s") 331 (eq_attr "dest_regfile" "any"))))) 332 "s2+s2w+br0,s2+s2w,s2+s2w") 333 334(define_reservation "all" "s1+s2+d1+d2+l1+l2+m1+m2") 335 336(define_insn_reservation "callp_s1" 1 337 (and (eq_attr "type" "callp") (eq_attr "dest_regfile" "a")) 338 "s1+s1w,all*5") 339 340(define_insn_reservation "callp_s2" 1 341 (and (eq_attr "type" "callp") (eq_attr "dest_regfile" "b")) 342 "s2+s2w,all*5") 343 344;; Constraints 345 346(include "constraints.md") 347 348;; Predicates 349 350(include "predicates.md") 351 352;; General predication pattern. 353 354(define_cond_exec 355 [(match_operator 0 "eqne_operator" 356 [(match_operand 1 "predicate_register" "AB") 357 (const_int 0)])] 358 "" 359 "") 360 361;; ------------------------------------------------------------------------- 362;; NOP instruction 363;; ------------------------------------------------------------------------- 364 365(define_insn "nop" 366 [(const_int 0)] 367 "" 368 "nop") 369 370(define_insn "nop_count" 371 [(unspec [(match_operand 0 "const_int_operand" "n")] UNSPEC_NOP)] 372 "" 373 "%|%.\\tnop\\t%0") 374 375;; ------------------------------------------------------------------------- 376;; Move instructions 377;; ------------------------------------------------------------------------- 378 379(define_mode_iterator QIHIM [QI HI]) 380(define_mode_iterator SIDIM [SI DI]) 381(define_mode_iterator SIDIVM [SI DI V2HI V4QI]) 382(define_mode_iterator VEC4M [V2HI V4QI]) 383(define_mode_iterator VEC8M [V2SI V4HI V8QI]) 384(define_mode_iterator SISFVM [SI SF V2HI V4QI]) 385(define_mode_iterator DIDFM [DI DF]) 386(define_mode_iterator DIDFVM [DI DF V2SI V4HI V8QI]) 387(define_mode_iterator SFDFM [SF DF]) 388(define_mode_iterator M32 [QI HI SI SF V2HI V4QI]) 389 390;; The C6X LO_SUM and HIGH are backwards - HIGH sets the low bits, and 391;; LO_SUM adds in the high bits. Fortunately these are opaque operations 392;; so this does not matter. 393(define_insn "movsi_lo_sum" 394 [(set (match_operand:SI 0 "register_operand" "=ab") 395 (lo_sum:SI (match_operand:SI 1 "register_operand" "0") 396 (match_operand:SI 2 "const_int_or_symbolic_operand" "i")))] 397 "reload_completed" 398 "%|%.\\tmvkh\\t%$\\t%2, %0" 399 [(set_attr "units" "s")]) 400 401(define_insn "movsi_high" 402 [(set (match_operand:SI 0 "register_operand" "=ab") 403 (high:SI (match_operand:SI 1 "const_int_or_symbolic_operand" "i")))] 404 "reload_completed" 405 "%|%.\\tmvkl\\t%$\\t%1, %0" 406 [(set_attr "units" "s")]) 407 408(define_insn "movsi_gotoff_lo_sum" 409 [(set (match_operand:SI 0 "register_operand" "=ab") 410 (lo_sum:SI (match_operand:SI 1 "register_operand" "0") 411 (unspec:SI [(match_operand:SI 2 "symbolic_operand" "S2")] 412 UNSPEC_GOTOFF)))] 413 "flag_pic == 2" 414 "%|%.\\tmvkh\\t%$\\t$dpr_got%2, %0" 415 [(set_attr "units" "s")]) 416 417(define_insn "movsi_gotoff_high" 418 [(set (match_operand:SI 0 "register_operand" "=ab") 419 (high:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "S2")] 420 UNSPEC_GOTOFF)))] 421 "flag_pic == 2" 422 "%|%.\\tmvkl\\t%$\\t$dpr_got%1, %0" 423 [(set_attr "units" "s")]) 424 425;; Normally we'd represent this as a normal load insn, but we can't currently 426;; represent the addressing mode. 427(define_insn "load_got_gotoff" 428 [(set (match_operand:SI 0 "register_operand" "=a,b") 429 (unspec:SI [(match_operand:SI 1 "register_operand" "Z,Z") 430 (match_operand:SI 2 "register_operand" "b,b")] 431 UNSPEC_GOTOFF))] 432 "flag_pic == 2" 433 "%|%.\\tldw\\t%$\\t*+%1[%2], %0" 434 [(set_attr "type" "load") 435 (set_attr "units" "d_addr") 436 (set_attr "op_pattern" "unknown") 437 (set_attr "dest_regfile" "a,b") 438 (set_attr "addr_regfile" "b")]) 439 440(define_insn "*movstricthi_high" 441 [(set (match_operand:SI 0 "register_operand" "+ab") 442 (ior:SI (and:SI (match_dup 0) (const_int 65535)) 443 (ashift:SI (match_operand:SI 1 "const_int_operand" "IuB") 444 (const_int 16))))] 445 "reload_completed" 446 "%|%.\\tmvklh\\t%$\\t%1, %0" 447 [(set_attr "units" "s")]) 448 449;; Break up SImode loads of immediate operands. 450 451(define_split 452 [(set (match_operand:SI 0 "register_operand" "") 453 (match_operand:SI 1 "const_int_operand" ""))] 454 "reload_completed 455 && !satisfies_constraint_IsB (operands[1])" 456 [(set (match_dup 0) (match_dup 2)) 457 (set (match_dup 0) (ior:SI (and:SI (match_dup 0) (const_int 65535)) 458 (ashift:SI (match_dup 3) (const_int 16))))] 459{ 460 HOST_WIDE_INT val = INTVAL (operands[1]); 461 operands[2] = GEN_INT (trunc_int_for_mode (val, HImode)); 462 operands[3] = GEN_INT ((val >> 16) & 65535); 463}) 464 465(define_split 466 [(set (match_operand:VEC4M 0 "register_operand" "") 467 (match_operand:VEC4M 1 "const_vector_operand" ""))] 468 "reload_completed" 469 [(set (match_dup 2) (match_dup 3))] 470{ 471 unsigned HOST_WIDE_INT mask, val; 472 machine_mode inner_mode = GET_MODE_INNER (<MODE>mode); 473 int i; 474 475 val = 0; 476 mask = GET_MODE_MASK (inner_mode); 477 if (TARGET_BIG_ENDIAN) 478 { 479 for (i = 0; i < GET_MODE_NUNITS (<MODE>mode); i++) 480 { 481 val <<= GET_MODE_BITSIZE (inner_mode); 482 val |= INTVAL (CONST_VECTOR_ELT (operands[1], i)) & mask; 483 } 484 } 485 else 486 { 487 i = GET_MODE_NUNITS (<MODE>mode); 488 while (i-- > 0) 489 { 490 val <<= GET_MODE_BITSIZE (inner_mode); 491 val |= INTVAL (CONST_VECTOR_ELT (operands[1], i)) & mask; 492 } 493 } 494 operands[2] = gen_rtx_REG (SImode, REGNO (operands[0])); 495 operands[3] = GEN_INT (trunc_int_for_mode (val, SImode)); 496}) 497 498(define_split 499 [(set (match_operand:VEC8M 0 "register_operand" "") 500 (match_operand:VEC8M 1 "const_vector_operand" ""))] 501 "reload_completed" 502 [(set (match_dup 2) (match_dup 3)) 503 (set (match_dup 4) (match_dup 5))] 504{ 505 unsigned HOST_WIDE_INT mask; 506 unsigned HOST_WIDE_INT val[2]; 507 rtx lo_half, hi_half; 508 machine_mode inner_mode = GET_MODE_INNER (<MODE>mode); 509 int i, j; 510 511 split_di (operands, 1, &lo_half, &hi_half); 512 513 val[0] = val[1] = 0; 514 mask = GET_MODE_MASK (inner_mode); 515 if (TARGET_BIG_ENDIAN) 516 { 517 for (i = 0, j = 1; i < GET_MODE_NUNITS (<MODE>mode); i++) 518 { 519 if (i * 2 == GET_MODE_NUNITS (<MODE>mode)) 520 j--; 521 val[j] <<= GET_MODE_BITSIZE (inner_mode); 522 val[j] |= INTVAL (CONST_VECTOR_ELT (operands[1], i)) & mask; 523 } 524 } 525 else 526 { 527 i = GET_MODE_NUNITS (<MODE>mode); 528 j = 1; 529 while (i-- > 0) 530 { 531 val[j] <<= GET_MODE_BITSIZE (inner_mode); 532 val[j] |= INTVAL (CONST_VECTOR_ELT (operands[1], i)) & mask; 533 if (i * 2 == GET_MODE_NUNITS (<MODE>mode)) 534 j--; 535 } 536 } 537 operands[2] = lo_half; 538 operands[3] = GEN_INT (trunc_int_for_mode (val[0], SImode)); 539 operands[4] = hi_half; 540 operands[5] = GEN_INT (trunc_int_for_mode (val[1], SImode)); 541}) 542 543(define_split 544 [(set (match_operand:SF 0 "register_operand" "") 545 (match_operand:SF 1 "immediate_operand" ""))] 546 "reload_completed" 547 [(set (match_dup 2) (match_dup 3)) 548 (set (match_dup 2) (ior:SI (and:SI (match_dup 2) (const_int 65535)) 549 (ashift:SI (match_dup 4) (const_int 16))))] 550{ 551 long values; 552 553 gcc_assert (GET_CODE (operands[1]) == CONST_DOUBLE); 554 555 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (operands[1]), values); 556 557 operands[2] = gen_rtx_REG (SImode, true_regnum (operands[0])); 558 operands[3] = GEN_INT (trunc_int_for_mode (values, HImode)); 559 if (values >= -32768 && values < 32768) 560 { 561 emit_move_insn (operands[2], operands[3]); 562 DONE; 563 } 564 operands[4] = GEN_INT ((values >> 16) & 65535); 565}) 566 567(define_split 568 [(set (match_operand:SI 0 "register_operand" "") 569 (match_operand:SI 1 "symbolic_operand" ""))] 570 "reload_completed 571 && (!TARGET_INSNS_64PLUS 572 || !sdata_symbolic_operand (operands[1], SImode))" 573 [(set (match_dup 0) (high:SI (match_dup 1))) 574 (set (match_dup 0) (lo_sum:SI (match_dup 0) (match_dup 1)))] 575 "") 576 577;; Normally, we represent the load of an sdata address as a normal 578;; move of a SYMBOL_REF. In DSBT mode, B14 is not constant, so we 579;; should show the dependency. 580(define_insn "load_sdata_pic" 581 [(set (match_operand:SI 0 "register_operand" "=a,b") 582 (plus:SI (match_operand:SI 1 "pic_register_operand" "Z,Z") 583 (unspec:SI [(match_operand:SI 2 "sdata_symbolic_operand" "S0,S0")] 584 UNSPEC_LOAD_SDATA)))] 585 "flag_pic" 586 "@ 587 %|%.\\tadda%D2\\t%$\\t%1, %2, %0 588 %|%.\\tadda%D2\\t%$\\t%1, %2, %0" 589 [(set_attr "units" "d") 590 (set_attr "cross" "y,n") 591 (set_attr "op_pattern" "unknown") 592 (set_attr "predicable" "no")]) 593 594;; Move instruction patterns 595 596(define_mode_attr LDST_SUFFIX [(QI "b") (HI "h") 597 (SI "w") (SF "w") (V2HI "w") (V4QI "w") 598 (DI "dw") (V2SI "dw") (V4HI "dw") (V8QI "dw")]) 599 600(define_insn "mov<mode>_insn" 601 [(set (match_operand:QIHIM 0 "nonimmediate_operand" 602 "=a,b, a, b, ab, ab,a,?a, b,?b, Q, R, R, Q") 603 (match_operand:QIHIM 1 "general_operand" 604 "a,b,?b,?a,Is5,IsB,Q, R, R, Q, a,?a, b,?b"))] 605 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) == REG" 606 "@ 607 %|%.\\tmv\\t%$\\t%1, %0 608 %|%.\\tmv\\t%$\\t%1, %0 609 %|%.\\tmv\\t%$\\t%1, %0 610 %|%.\\tmv\\t%$\\t%1, %0 611 %|%.\\tmvk\\t%$\\t%1, %0 612 %|%.\\tmvk\\t%$\\t%1, %0 613 %|%.\\tld<LDST_SUFFIX>\\t%$\\t%1, %0 614 %|%.\\tld<LDST_SUFFIX>\\t%$\\t%1, %0 615 %|%.\\tld<LDST_SUFFIX>\\t%$\\t%1, %0 616 %|%.\\tld<LDST_SUFFIX>\\t%$\\t%1, %0 617 %|%.\\tst<LDST_SUFFIX>\\t%$\\t%1, %0 618 %|%.\\tst<LDST_SUFFIX>\\t%$\\t%1, %0 619 %|%.\\tst<LDST_SUFFIX>\\t%$\\t%1, %0 620 %|%.\\tst<LDST_SUFFIX>\\t%$\\t%1, %0" 621 [(set_attr "type" "*,*,*,*,*,*,load,load,load,load,store,store,store,store") 622 (set_attr "units62" "dls,dls,ls,ls,s,s,d_addr,d_addr,d_addr,d_addr,d_addr,d_addr,d_addr,d_addr") 623 (set_attr "units64" "dls,dls,ls,ls,dl,s,d_addr,d_addr,d_addr,d_addr,d_addr,d_addr,d_addr,d_addr") 624 (set_attr "op_pattern" "sx,sx,sx,sx,*,*,*,*,*,*,*,*,*,*") 625 (set_attr "addr_regfile" "*,*,*,*,*,*,a,b,b,a,a,b,b,a") 626 (set_attr "dest_regfile" "*,*,*,*,*,*,a,a,b,b,a,a,b,b") 627 (set_attr "cross" "n,n,y,y,n,n,n,y,n,y,n,y,n,y")]) 628 629(define_insn "mov<mode>_insn" 630 [(set (match_operand:SISFVM 0 "nonimmediate_operand" 631 "=a,b, a, b, ab, ab,a,b,ab,a,?a, b,?b, Q, R, R, Q") 632 (match_operand:SISFVM 1 "general_operand" 633 "a,b,?b,?a,Is5,IsB,S0,S0,Si,Q, R, R, Q, a,?a, b,?b"))] 634 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) == REG 635 || (GET_CODE (operands[1]) == SUBREG && REG_P (SUBREG_REG (operands[1]))))" 636 "@ 637 %|%.\\tmv\\t%$\\t%1, %0 638 %|%.\\tmv\\t%$\\t%1, %0 639 %|%.\\tmv\\t%$\\t%1, %0 640 %|%.\\tmv\\t%$\\t%1, %0 641 %|%.\\tmvk\\t%$\\t%1, %0 642 %|%.\\tmvk\\t%$\\t%1, %0 643 %|%.\\tadda%D1\\t%$\\tB14, %1, %0 644 %|%.\\tadda%D1\\t%$\\tB14, %1, %0 645 # 646 %|%.\\tldw\\t%$\\t%1, %0 647 %|%.\\tldw\\t%$\\t%1, %0 648 %|%.\\tldw\\t%$\\t%1, %0 649 %|%.\\tldw\\t%$\\t%1, %0 650 %|%.\\tstw\\t%$\\t%1, %0 651 %|%.\\tstw\\t%$\\t%1, %0 652 %|%.\\tstw\\t%$\\t%1, %0 653 %|%.\\tstw\\t%$\\t%1, %0" 654 [(set_attr "type" "*,*,*,*,*,*,*,*,*,load,load,load,load,store,store,store,store") 655 (set_attr "units62" "dls,dls,ls,ls,s,s,d,d,*,d_addr,d_addr,d_addr,d_addr,d_addr,d_addr,d_addr,d_addr") 656 (set_attr "units64" "dls,dls,ls,ls,dl,s,d,d,*,d_addr,d_addr,d_addr,d_addr,d_addr,d_addr,d_addr,d_addr") 657 (set_attr "op_pattern" "sx,sx,sx,sx,*,*,*,*,*,*,*,*,*,*,*,*,*") 658 (set_attr "addr_regfile" "*,*,*,*,*,*,*,*,*,a,b,b,a,a,b,b,a") 659 (set_attr "dest_regfile" "*,*,*,*,*,*,*,*,*,a,a,b,b,a,a,b,b") 660 (set_attr "cross" "n,n,y,y,n,n,y,n,*,n,y,n,y,n,y,n,y") 661 (set_attr "predicable" "yes,yes,yes,yes,yes,yes,no,no,yes,yes,yes,yes,yes,yes,yes,yes,yes")]) 662 663(define_insn "*mov<mode>_insn" 664 [(set (match_operand:DIDFVM 0 "nonimmediate_operand" 665 "=a,b, a, b,ab,a,?a, b,?b, Q, R, R, Q") 666 (match_operand:DIDFVM 1 "general_operand" 667 "a,b,?b,?a,iF,Q, R, R, Q, a,?a, b,?b"))] 668 "(!MEM_P (operands[0]) || REG_P (operands[1]) 669 || (GET_CODE (operands[1]) == SUBREG && REG_P (SUBREG_REG (operands[1]))))" 670{ 671 if (MEM_P (operands[1]) && TARGET_LDDW) 672 return "%|%.\\tlddw\\t%$\\t%1, %0"; 673 if (MEM_P (operands[0]) && TARGET_STDW) 674 return "%|%.\\tstdw\\t%$\\t%1, %0"; 675 if (TARGET_INSNS_64PLUS && REG_P (operands[0]) && REG_P (operands[1]) 676 && A_REGNO_P (REGNO (operands[0])) == A_REGNO_P (REGNO (operands[1]))) 677 return "%|%.\\tdmv\\t%$\\t%P1, %p1, %0"; 678 return "#"; 679} 680 [(set_attr "units" "s,s,*,*,*,d_addr,d_addr,d_addr,d_addr,d_addr,d_addr,d_addr,d_addr") 681 (set_attr "addr_regfile" "*,*,*,*,*,a,b,b,a,a,b,b,a") 682 (set_attr "dest_regfile" "*,*,*,*,*,a,a,b,b,a,a,b,b") 683 (set_attr "type" "*,*,*,*,*,load,load,load,load,store,store,store,store") 684 (set_attr "cross" "n,n,y,y,*,n,y,n,y,n,y,n,y")]) 685 686(define_split 687 [(set (match_operand:DIDFVM 0 "nonimmediate_operand" "") 688 (match_operand:DIDFVM 1 "general_operand" ""))] 689 "reload_completed 690 && !((MEM_P (operands[0]) && TARGET_STDW) 691 || (MEM_P (operands[1]) && TARGET_LDDW)) 692 && !const_vector_operand (operands[1], <MODE>mode) 693 && !(TARGET_INSNS_64PLUS && REG_P (operands[0]) && REG_P (operands[1]) 694 && A_REGNO_P (REGNO (operands[0])) == A_REGNO_P (REGNO (operands[1])))" 695 [(set (match_dup 2) (match_dup 3)) 696 (set (match_dup 4) (match_dup 5))] 697{ 698 rtx lo_half[2], hi_half[2]; 699 split_di (operands, 2, lo_half, hi_half); 700 701 /* We can't have overlap for a register-register move, but if 702 memory is involved, we have to make sure we don't clobber the 703 address. */ 704 if (reg_overlap_mentioned_p (lo_half[0], hi_half[1])) 705 { 706 operands[2] = hi_half[0]; 707 operands[3] = hi_half[1]; 708 operands[4] = lo_half[0]; 709 operands[5] = lo_half[1]; 710 } 711 else 712 { 713 operands[2] = lo_half[0]; 714 operands[3] = lo_half[1]; 715 operands[4] = hi_half[0]; 716 operands[5] = hi_half[1]; 717 } 718}) 719 720(define_insn "real_load<mode>" 721 [(unspec [(match_operand 0 "const_int_operand" "JA,JA,JB,JB") 722 (match_operand:M32 1 "memory_operand" "Q,R,R,Q")] 723 UNSPEC_REAL_LOAD)] 724 "" 725 "%|%.\\tld<LDST_SUFFIX>\\t%$\\t%1, %k0" 726 [(set_attr "type" "load") 727 (set_attr "units" "d_addr") 728 (set_attr "addr_regfile" "a,b,b,a") 729 (set_attr "dest_regfile" "a,a,b,b") 730 (set_attr "cross" "n,y,n,y")]) 731 732(define_insn "real_load<mode>" 733 [(unspec [(match_operand 0 "const_int_operand" "JA,JA,JB,JB") 734 (match_operand:DIDFVM 1 "memory_operand" "Q,R,R,Q")] 735 UNSPEC_REAL_LOAD)] 736 "TARGET_LDDW" 737 "%|%.\\tlddw\\t%$\\t%1, %K0" 738 [(set_attr "type" "load") 739 (set_attr "units" "d_addr") 740 (set_attr "addr_regfile" "a,b,b,a") 741 (set_attr "dest_regfile" "a,a,b,b") 742 (set_attr "cross" "n,y,n,y")]) 743 744(define_insn "load_shadow" 745 [(set (match_operand 0 "register_operand" "=ab") 746 (unspec [(pc)] UNSPEC_LOAD_SHADOW))] 747 "" 748 ";; load to %0 occurs" 749 [(set_attr "type" "load_shadow")]) 750 751(define_insn "mult_shadow" 752 [(set (match_operand 0 "register_operand" "=ab") 753 (unspec [(pc)] UNSPEC_MULT_SHADOW))] 754 "" 755 ";; multiplication occurs and stores to %0" 756 [(set_attr "type" "mult_shadow")]) 757 758 759(define_mode_iterator MOV [QI HI SI SF DI DF V2HI V4QI V2SI V4HI V8QI]) 760 761(define_expand "mov<mode>" 762 [(set (match_operand:MOV 0 "nonimmediate_operand" "") 763 (match_operand:MOV 1 "general_operand" ""))] 764 "" 765{ 766 if (expand_move (operands, <MODE>mode)) 767 DONE; 768}) 769 770(define_expand "movmisalign<mode>" 771 [(set (match_operand:SIDIVM 0 "nonimmediate_operand" "") 772 (unspec:SIDIVM [(match_operand:SIDIVM 1 "nonimmediate_operand" "")] 773 UNSPEC_MISALIGNED_ACCESS))] 774 "TARGET_INSNS_64" 775{ 776 if (MEM_P (operands[0])) 777 { 778 emit_insn (gen_movmisalign<mode>_store (operands[0], operands[1])); 779 DONE; 780 } 781}) 782 783(define_insn_and_split "movmisalign<mode>_store" 784 [(set (match_operand:SIDIVM 0 "memory_operand" "=W,Q,T,Q,T") 785 (unspec:SIDIVM [(match_operand:SIDIVM 1 "register_operand" "r,a,b,b,a")] 786 UNSPEC_MISALIGNED_ACCESS)) 787 (clobber (match_scratch:SI 2 "=r,X,X,X,X"))] 788 "TARGET_INSNS_64" 789 "@ 790 # 791 %|%.\\tstn<LDST_SUFFIX>\\t%$\\t%1, %0 792 %|%.\\tstn<LDST_SUFFIX>\\t%$\\t%1, %0 793 %|%.\\tstn<LDST_SUFFIX>\\t%$\\t%1, %0 794 %|%.\\tstn<LDST_SUFFIX>\\t%$\\t%1, %0" 795 "&& reload_completed && satisfies_constraint_W (operands[0])" 796 [(parallel 797 [(set (match_dup 3) (unspec:SIDIVM [(match_dup 1)] UNSPEC_MISALIGNED_ACCESS)) 798 (clobber (match_dup 4))])] 799{ 800 rtx addr = XEXP (operands[0], 0); 801 rtx tmpreg = operands[2]; 802 803 if (GET_CODE (addr) == PLUS && XEXP (addr, 0) == stack_pointer_rtx 804 && GET_CODE (XEXP (addr, 1)) == CONST_INT) 805 { 806 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1)); 807 val &= GET_MODE_SIZE (<MODE>mode) - 1; 808 if (val == 0) 809 { 810 emit_move_insn (operands[0], operands[1]); 811 DONE; 812 } 813 } 814 operands[3] = change_address (operands[0], <MODE>mode, tmpreg); 815 emit_move_insn (tmpreg, addr); 816 operands[4] = gen_rtx_SCRATCH (SImode); 817} 818 [(set_attr "type" "storen") 819 (set_attr "units" "d_addr") 820 (set_attr "addr_regfile" "*,a,b,a,b") 821 (set_attr "dest_regfile" "*,a,b,b,a") 822 (set_attr "cross" "*,n,n,y,y")]) 823 824(define_insn_and_split "movmisalign<mode>_load" 825 [(set (match_operand:SIDIVM 0 "register_operand" "=ab,a,b,b,a") 826 (unspec:SIDIVM [(match_operand:SIDIVM 1 "memory_operand" "W,Q,T,Q,T")] 827 UNSPEC_MISALIGNED_ACCESS))] 828 "TARGET_INSNS_64" 829 "@ 830 # 831 %|%.\\tldn<LDST_SUFFIX>\\t%$\\t%1, %0 832 %|%.\\tldn<LDST_SUFFIX>\\t%$\\t%1, %0 833 %|%.\\tldn<LDST_SUFFIX>\\t%$\\t%1, %0 834 %|%.\\tldn<LDST_SUFFIX>\\t%$\\t%1, %0" 835 "&& reload_completed && satisfies_constraint_W (operands[1])" 836 [(set (match_dup 0) (unspec:SIDIVM [(match_dup 2)] UNSPEC_MISALIGNED_ACCESS))] 837{ 838 rtx addr = XEXP (operands[1], 0); 839 rtx tmpreg = (GET_MODE (operands[0]) == SImode ? operands[0] 840 : operand_subword_force (operands[0], 0, DImode)); 841 842 if (GET_CODE (addr) == PLUS && XEXP (addr, 0) == stack_pointer_rtx 843 && GET_CODE (XEXP (addr, 1)) == CONST_INT) 844 { 845 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1)); 846 val &= GET_MODE_SIZE (<MODE>mode) - 1; 847 if (val == 0) 848 { 849 emit_move_insn (operands[0], operands[1]); 850 DONE; 851 } 852 } 853 operands[2] = change_address (operands[1], <MODE>mode, tmpreg); 854 emit_move_insn (tmpreg, addr); 855} 856 [(set_attr "type" "loadn") 857 (set_attr "units" "d_addr") 858 (set_attr "addr_regfile" "*,a,b,a,b") 859 (set_attr "dest_regfile" "*,a,b,b,a") 860 (set_attr "cross" "*,n,n,y,y")]) 861 862;; 863 864;; ------------------------------------------------------------------------- 865;; Extensions/extractions 866;; ------------------------------------------------------------------------- 867 868(define_code_iterator any_extract [zero_extract sign_extract]) 869(define_code_iterator any_ext [zero_extend sign_extend]) 870 871(define_code_attr ext_name [(zero_extend "zero_extend") (sign_extend "sign_extend")]) 872 873(define_code_attr u [(zero_extend "u") (sign_extend "")]) 874 875(define_code_attr z [(zero_extract "z") (sign_extract "")]) 876(define_code_attr zu [(zero_extract "u") (sign_extract "")]) 877 878(define_mode_attr ext_shift [(QI "24") (HI "16")]) 879 880(define_insn "<ext_name><mode>si2" 881 [(set (match_operand:SI 0 "register_operand" "=a,b,a,?a, b,?b") 882 (any_ext:SI (match_operand:QIHIM 1 "nonimmediate_operand" "a,b,Q, R, R, Q")))] 883 "" 884 "@ 885 %|%.\\text<u>\\t%$\\t%1, <ext_shift>, <ext_shift>, %0 886 %|%.\\text<u>\\t%$\\t%1, <ext_shift>, <ext_shift>, %0 887 %|%.\\tld<LDST_SUFFIX><u>\\t%$\\t%1, %0 888 %|%.\\tld<LDST_SUFFIX><u>\\t%$\\t%1, %0 889 %|%.\\tld<LDST_SUFFIX><u>\\t%$\\t%1, %0 890 %|%.\\tld<LDST_SUFFIX><u>\\t%$\\t%1, %0" 891 [(set_attr "type" "*,*,load,load,load,load") 892 (set_attr "units" "s,s,d_addr,d_addr,d_addr,d_addr") 893 (set_attr "addr_regfile" "*,*,a,b,b,a") 894 (set_attr "dest_regfile" "*,*,a,a,b,b") 895 (set_attr "cross" "n,n,n,y,n,y")]) 896 897(define_insn "*ext<z>v_const" 898 [(set (match_operand:SI 0 "nonimmediate_operand" "=a,b") 899 (any_extract:SI (match_operand:SI 1 "register_operand" "a,b") 900 (match_operand:SI 2 "const_int_operand" "n,n") 901 (match_operand:SI 3 "const_int_operand" "n,n")))] 902 "INTVAL (operands[3]) >= 0 903 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32" 904{ 905 int pos = INTVAL (operands[3]); 906 int len = INTVAL (operands[2]); 907 rtx xop[4]; 908 xop[0] = operands[0]; 909 xop[1] = operands[1]; 910 xop[2] = GEN_INT (32 - pos - len); 911 xop[3] = GEN_INT (32 - len); 912 913 output_asm_insn ("%|%.\\text<zu>\\t%$\\t%1, %2, %3, %0", xop); 914 return ""; 915} 916 [(set_attr "units" "s") 917 (set_attr "cross" "n")]) 918 919(define_expand "ext<z>v" 920 [(set (match_operand:SI 0 "register_operand" "") 921 (any_extract:SI (match_operand:SI 1 "register_operand" "") 922 (match_operand:SI 2 "const_int_operand" "") 923 (match_operand:SI 3 "const_int_operand" "")))] 924 "" 925{ 926 if (INTVAL (operands[2]) < 0 927 || INTVAL (operands[2]) + INTVAL (operands[3]) > 32) 928 FAIL; 929}) 930 931(define_insn "real_<ext_name><mode>" 932 [(unspec [(match_operand 0 "const_int_operand" "JA,JA,JB,JB") 933 (any_ext:SI (match_operand:QIHIM 1 "memory_operand" "Q,R,R,Q"))] 934 UNSPEC_REAL_LOAD)] 935 "" 936 "%|%.\\tld<LDST_SUFFIX><u>\\t%$\\t%1, %k0" 937 [(set_attr "type" "load") 938 (set_attr "units" "d_addr") 939 (set_attr "addr_regfile" "a,b,b,a") 940 (set_attr "dest_regfile" "a,a,b,b") 941 (set_attr "cross" "n,y,n,y")]) 942 943(define_insn "clrr" 944 [(set (match_operand:SI 0 "register_operand" "=a,b,a,b") 945 (unspec:SI [(match_operand:SI 1 "register_operand" "0,0,0,0") 946 (match_operand:SI 2 "register_operand" "a,b,?b,?a") 947 (match_operand:SI 3 "reg_or_const_int_operand" "ai,bi,a,b")] 948 UNSPEC_CLR))] 949 "" 950{ 951 if (CONST_INT_P (operands[2])) 952 { 953 rtx xops[4]; 954 int v1 = INTVAL (operands[2]); 955 int v2 = (v1 >> 5) & 0x1f; 956 v1 &= 0x1f; 957 xops[0] = operands[0]; 958 xops[1] = operands[1]; 959 xops[2] = GEN_INT (v1); 960 xops[3] = GEN_INT (v2); 961 output_asm_insn ("%|%.\\tclr\\t%$\\t%1, %3, %2, %0", xops); 962 return ""; 963 } 964 return "%|%.\\tclr\\t%$\\t%2, %3, %0"; 965} 966 [(set_attr "units" "s") 967 (set_attr "cross" "n,n,y,y")]) 968 969(define_insn "extr" 970 [(set (match_operand:SI 0 "register_operand" "=a,b,a,b") 971 (unspec:SI [(match_operand:SI 1 "register_operand" "a,b,?b,?a") 972 (match_operand:SI 2 "reg_or_const_int_operand" "ai,bi,a,b")] 973 UNSPEC_EXT))] 974 "" 975{ 976 if (CONST_INT_P (operands[2])) 977 { 978 rtx xops[4]; 979 int v1 = INTVAL (operands[2]); 980 int v2 = (v1 >> 5) & 0x1f; 981 v1 &= 0x1f; 982 xops[0] = operands[0]; 983 xops[1] = operands[1]; 984 xops[2] = GEN_INT (v1); 985 xops[3] = GEN_INT (v2); 986 output_asm_insn ("%|%.\\text\\t%$\\t%1, %3, %2, %0", xops); 987 return ""; 988 } 989 return "%|%.\\text\\t%$\\t%1, %2, %0"; 990} 991 [(set_attr "units" "s") 992 (set_attr "cross" "n,n,y,y")]) 993 994(define_insn "extru" 995 [(set (match_operand:SI 0 "register_operand" "=a,b,a,b") 996 (unspec:SI [(match_operand:SI 1 "register_operand" "a,b,?b,?a") 997 (match_operand:SI 2 "reg_or_const_int_operand" "ai,bi,a,b")] 998 UNSPEC_EXTU))] 999 "" 1000{ 1001 if (CONST_INT_P (operands[2])) 1002 { 1003 rtx xops[4]; 1004 int v1 = INTVAL (operands[2]); 1005 int v2 = (v1 >> 5) & 0x1f; 1006 v1 &= 0x1f; 1007 xops[0] = operands[0]; 1008 xops[1] = operands[1]; 1009 xops[2] = GEN_INT (v1); 1010 xops[3] = GEN_INT (v2); 1011 output_asm_insn ("%|%.\\textu\\t%$\\t%1, %3, %2, %0", xops); 1012 return ""; 1013 } 1014 return "%|%.\\textu\\t%$\\t%1, %2, %0"; 1015} 1016 [(set_attr "units" "s") 1017 (set_attr "cross" "n,y,n,y")]) 1018 1019;; ------------------------------------------------------------------------- 1020;; Compare instructions 1021;; ------------------------------------------------------------------------- 1022 1023(define_insn "scmpsi_insn" 1024 [(set (match_operand:SI 0 "register_operand" "=ab,a,b,a,b") 1025 (match_operator:SI 1 "eqltgt_operator" 1026 [(match_operand:SI 2 "register_operand" "ab,a,b,?b,?a") 1027 (match_operand:SI 3 "reg_or_scst5_operand" "Is5,aIs5,bIs5,aIs5,bIs5")]))] 1028 "" 1029 "%|%.\\tcmp%C1\\t%$\\t%3, %2, %0" 1030 [(set_attr "units" "l") 1031 (set (attr "cross") 1032 (symbol_ref "CROSS_OPERANDS (operands[0], operands[2])"))]) 1033 1034(define_insn "*ucmpsi_insn_64" 1035 [(set (match_operand:SI 0 "register_operand" "=ab,a,b,a,b") 1036 (match_operator:SI 1 "ltugtu_operator" 1037 [(match_operand:SI 2 "register_operand" "ab,a,b,?b,?a") 1038 (match_operand:SI 3 "reg_or_ucst5_operand" "Iu5,aIu5,bIu5,aIu5,bIu5")]))] 1039 "TARGET_INSNS_64" 1040 "%|%.\\tcmp%C1\\t%$\\t%3, %2, %0" 1041 [(set_attr "units" "l") 1042 (set (attr "cross") 1043 (symbol_ref "CROSS_OPERANDS (operands[0], operands[2])"))]) 1044 1045(define_insn "*ucmpsi_insn" 1046 [(set (match_operand:SI 0 "register_operand" "=ab,a,b,a,b") 1047 (match_operator:SI 1 "ltugtu_operator" 1048 [(match_operand:SI 2 "register_operand" "ab,a,b,?b,?a") 1049 (match_operand:SI 3 "reg_or_ucst4_operand" "Iu4,aIu4,bIu4,aIu4,bIu4")]))] 1050 "!TARGET_INSNS_64" 1051 "%|%.\\tcmp%C1\\t%$\\t%3, %2, %0" 1052 [(set_attr "units" "l") 1053 (set (attr "cross") 1054 (symbol_ref "CROSS_OPERANDS (operands[0], operands[2])"))]) 1055 1056(define_code_iterator andior_eqne [eq ne]) 1057(define_code_attr andior_name [(eq "and") (ne "ior")]) 1058(define_code_attr andior_condmod [(eq "") (ne "!")]) 1059 1060(define_insn "*scmpsi_<andior_name>_insn" 1061 [(set (match_operand:SI 0 "register_operand" "=A,B,A,B") 1062 (if_then_else:SI 1063 (andior_eqne:SI (match_operand:SI 4 "register_operand" "0,0,0,0") 1064 (const_int 0)) 1065 (match_dup 4) 1066 (match_operator:SI 1 "eqltgt_operator" 1067 [(match_operand:SI 2 "register_operand" "a,b,?b,?a") 1068 (match_operand:SI 3 "reg_or_scst5_operand" "aIs5,bIs5,aIs5,bIs5")])))] 1069 "" 1070 "%|[<andior_condmod>%4]\\tcmp%C1\\t%$\\t%3, %2, %0" 1071 [(set_attr "units" "l") 1072 (set_attr "cross" "n,n,y,y") 1073 (set_attr "predicable" "no")]) 1074 1075(define_insn "*ucmpsi_<andior_name>_insn_64" 1076 [(set (match_operand:SI 0 "register_operand" "=A,B,A,B") 1077 (if_then_else:SI 1078 (andior_eqne:SI (match_operand:SI 4 "register_operand" "0,0,0,0") 1079 (const_int 0)) 1080 (match_dup 4) 1081 (match_operator:SI 1 "ltugtu_operator" 1082 [(match_operand:SI 2 "register_operand" "a,b,?b,?a") 1083 (match_operand:SI 3 "reg_or_ucst5_operand" "aIu5,bIu5,aIu5,bIu5")])))] 1084 "TARGET_INSNS_64" 1085 "%|[<andior_condmod>%4]\\tcmp%C1\\t%$\\t%3, %2, %0" 1086 [(set_attr "units" "l") 1087 (set_attr "cross" "n,n,y,y") 1088 (set_attr "predicable" "no")]) 1089 1090(define_insn "*ucmpsi_<andior_name>_insn" 1091 [(set (match_operand:SI 0 "register_operand" "=A,B,A,B") 1092 (if_then_else:SI 1093 (andior_eqne:SI (match_operand:SI 4 "register_operand" "0,0,0,0") 1094 (const_int 0)) 1095 (match_dup 4) 1096 (match_operator:SI 1 "ltugtu_operator" 1097 [(match_operand:SI 2 "register_operand" "a,b,?b,?a") 1098 (match_operand:SI 3 "reg_or_ucst4_operand" "aIu4,bIu4,aIu4,bIu4")])))] 1099 "!TARGET_INSNS_64" 1100 "%|[<andior_condmod>%4]\\tcmp%C1\\t%$\\t%3, %2, %0" 1101 [(set_attr "units" "l") 1102 (set_attr "cross" "n,n,y,y") 1103 (set_attr "predicable" "no")]) 1104 1105(define_expand "cmpsi_<andior_name>" 1106 [(set (match_operand:SI 0 "register_operand" "") 1107 (if_then_else:SI 1108 (andior_eqne:SI (match_operand:SI 4 "register_operand" "0,0,0,0") 1109 (const_int 0)) 1110 (match_dup 4) 1111 (match_operator:SI 1 "c6x_comparison_operator" 1112 [(match_operand:SI 2 "register_operand" "") 1113 (match_operand:SI 3 "reg_or_const_int_operand" "")])))] 1114 "" 1115{ 1116 if (c6x_force_op_for_comparison_p (GET_CODE (operands[1]), operands[3])) 1117 operands[3] = force_reg (SImode, operands[3]); 1118}) 1119 1120(define_insn "*cmpsf_insn" 1121 [(set (match_operand:SI 0 "register_operand" "=a,b,a,b") 1122 (match_operator:SI 1 "eqltgt_operator" 1123 [(match_operand:SF 2 "register_operand" "a,b,a,b") 1124 (match_operand:SF 3 "register_operand" "a,b,?b,?a")]))] 1125 "TARGET_FP" 1126 "%|%.\\tcmp%c1sp\\t%$\\t%2, %3, %0" 1127 [(set_attr "units" "s") 1128 (set_attr "cross" "n,n,y,y")]) 1129 1130(define_insn "*cmpdf_insn" 1131 [(set (match_operand:SI 0 "register_operand" "=a,b,a,b") 1132 (match_operator:SI 1 "eqltgt_operator" 1133 [(match_operand:DF 2 "register_operand" "a,b,a,b") 1134 (match_operand:DF 3 "register_operand" "a,b,?b,?a")]))] 1135 "TARGET_FP" 1136 "%|%.\\tcmp%c1dp\\t%$\\t%2, %3, %0" 1137 [(set_attr "type" "cmpdp") 1138 (set_attr "units" "s") 1139 (set_attr "cross" "n,n,y,y")]) 1140 1141(define_expand "cmp<mode>_<andior_name>" 1142 [(set (match_operand:SI 0 "register_operand" "") 1143 (if_then_else:SI 1144 (andior_eqne:SI (match_operand:SI 4 "register_operand" "0,0,0,0") 1145 (const_int 0)) 1146 (match_dup 4) 1147 (match_operator:SI 1 "eqltgt_operator" 1148 [(match_operand:SFDFM 2 "register_operand" "") 1149 (match_operand:SFDFM 3 "register_operand" "")])))] 1150 "TARGET_FP") 1151 1152(define_insn "*cmpsf_<andior_name>_insn" 1153 [(set (match_operand:SI 0 "register_operand" "=A,B,A,B") 1154 (if_then_else:SI 1155 (andior_eqne:SI (match_operand:SI 4 "register_operand" "0,0,0,0") 1156 (const_int 0)) 1157 (match_dup 4) 1158 (match_operator:SI 1 "eqltgt_operator" 1159 [(match_operand:SF 2 "register_operand" "a,b,a,b") 1160 (match_operand:SF 3 "register_operand" "a,b,?b,?a")])))] 1161 "TARGET_FP" 1162 "%|[<andior_condmod>%4]\\tcmp%c1sp\\t%$\\t%2, %3, %0" 1163 [(set_attr "units" "s") 1164 (set_attr "cross" "n,n,y,y") 1165 (set_attr "predicable" "no")]) 1166 1167;; reload_reg_class_lower will ensure that two-word reloads are allocated first, 1168;; which could exhaust the predicate registers if we used just "a" and "b" 1169;; constraints on operands 2 and 3. 1170(define_insn "*cmpdf_<andior_name>_insn" 1171 [(set (match_operand:SI 0 "register_operand" "=A,B,A,B") 1172 (if_then_else:SI 1173 (andior_eqne:SI (match_operand:SI 4 "register_operand" "0,0,0,0") 1174 (const_int 0)) 1175 (match_dup 4) 1176 (match_operator:SI 1 "eqltgt_operator" 1177 [(match_operand:DF 2 "register_operand" "Da,Db,Da,Db") 1178 (match_operand:DF 3 "register_operand" "Da,Db,?Db,?Da")])))] 1179 "TARGET_FP" 1180 "%|[<andior_condmod>%4]\\tcmp%c1dp\\t%$\\t%2, %3, %0" 1181 [(set_attr "type" "cmpdp") 1182 (set_attr "units" "s") 1183 (set_attr "cross" "n,n,y,y") 1184 (set_attr "predicable" "no")]) 1185 1186(define_split 1187 [(set (match_operand:SI 0 "register_operand" "") 1188 (ior:SI (match_operand 1 "c6x_any_comparison_operand" "") 1189 (match_operand 2 "c6x_any_comparison_operand" "")))] 1190 "!reg_overlap_mentioned_p (operands[0], operands[2])" 1191 [(set (match_dup 0) (match_dup 1)) 1192 (set (match_dup 0) 1193 (if_then_else:SI (ne:SI (match_dup 0) (const_int 0)) 1194 (match_dup 0) 1195 (match_dup 2)))]) 1196 1197(define_split 1198 [(set (match_operand:SI 0 "register_operand" "") 1199 (and:SI (match_operand 1 "c6x_any_comparison_operand" "") 1200 (match_operand 2 "c6x_any_comparison_operand" "")))] 1201 "!reg_overlap_mentioned_p (operands[0], operands[2])" 1202 [(set (match_dup 0) (match_dup 1)) 1203 (set (match_dup 0) 1204 (if_then_else:SI (eq:SI (match_dup 0) (const_int 0)) 1205 (match_dup 0) 1206 (match_dup 2)))]) 1207 1208 1209;; ------------------------------------------------------------------------- 1210;; setcc instructions 1211;; ------------------------------------------------------------------------- 1212 1213(define_expand "cstoresi4" 1214 [(set (match_operand:SI 0 "register_operand" "") 1215 (match_operator:SI 1 "comparison_operator" 1216 [(match_operand:SI 2 "register_operand" "") 1217 (match_operand:SI 3 "reg_or_ucst4_operand" "")]))] 1218 "" 1219{ 1220 if (!c6x_comparison_operator (operands[1], SImode)) 1221 { 1222 rtx tmpreg = gen_reg_rtx (SImode); 1223 rtx t = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[1])), 1224 SImode, operands[2], operands[3]); 1225 emit_insn (gen_rtx_SET (tmpreg, t)); 1226 emit_insn (gen_scmpsi_insn (operands[0], 1227 gen_rtx_fmt_ee (EQ, SImode, tmpreg, const0_rtx), 1228 tmpreg, const0_rtx)); 1229 DONE; 1230 } 1231}) 1232 1233;; ------------------------------------------------------------------------- 1234;; Jump instructions 1235;; ------------------------------------------------------------------------- 1236 1237(define_insn "indirect_jump" 1238 [(set (pc) (match_operand:SI 0 "register_operand" "a,b"))] 1239 "" 1240 "%|%.\\tb\\t%$\\t%0" 1241 [(set_attr "type" "branch") 1242 (set_attr "units" "s") 1243 (set_attr "cross" "y,n") 1244 (set_attr "dest_regfile" "b")]) 1245 1246(define_insn "jump" 1247 [(set (pc) 1248 (label_ref (match_operand 0 "" "")))] 1249 "" 1250 "%|%.\\tb\\t%$\\t%l0" 1251 [(set_attr "type" "branch") 1252 (set_attr "units" "s") 1253 (set_attr "dest_regfile" "any")]) 1254 1255(define_expand "tablejump" 1256 [(parallel [(set (pc) (match_operand:SI 0 "register_operand" "")) 1257 (use (label_ref (match_operand 1 "" "")))])] 1258 "!flag_pic || !TARGET_INSNS_64" 1259{ 1260}) 1261 1262(define_insn "*tablejump_internal" 1263 [(set (pc) (match_operand:SI 0 "register_operand" "b")) 1264 (use (label_ref (match_operand 1 "" "")))] 1265 "!flag_pic || !TARGET_INSNS_64" 1266 "%|\\tb\\t%$\\t%0" 1267 [(set_attr "type" "branch") 1268 (set_attr "predicable" "no") 1269 (set_attr "units" "s") 1270 (set_attr "dest_regfile" "b")]) 1271 1272;; Implement switch statements when generating PIC code. Switches are 1273;; implemented by `tablejump' when not using -fpic. 1274 1275;; Emit code here to do the range checking and make the index zero based. 1276;; operand 0 is the index 1277;; operand 1 is the lower bound 1278;; operand 2 is the range of indices (highest - lowest + 1) 1279;; operand 3 is the label that precedes the table itself 1280;; operand 4 is the fall through label 1281 1282(define_expand "casesi" 1283 [(use (match_operand:SI 0 "register_operand" "")) 1284 (use (match_operand:SI 1 "const_int_operand" "")) 1285 (use (match_operand:SI 2 "const_int_operand" "")) 1286 (use (match_operand 3 "" "")) 1287 (use (match_operand 4 "" ""))] 1288 "flag_pic && TARGET_INSNS_64" 1289{ 1290 rtx indx; 1291 rtx low = operands[1]; 1292 rtx range = operands[2]; 1293 rtx table = operands[3]; 1294 rtx fail = operands[4]; 1295 1296 gcc_assert (GET_CODE (operands[1]) == CONST_INT); 1297 gcc_assert (GET_CODE (operands[2]) == CONST_INT); 1298 1299 if (!reg_or_ucst4_operand (range, SImode)) 1300 range = force_reg (SImode, range); 1301 1302 /* If low bound is 0, we don't have to subtract it. */ 1303 if (INTVAL (operands[1]) == 0) 1304 indx = operands[0]; 1305 else 1306 { 1307 rtx offset = GEN_INT (-INTVAL (low)); 1308 indx = gen_reg_rtx (SImode); 1309 if (!addsi_operand (offset, SImode)) 1310 offset = force_reg (SImode, offset); 1311 emit_insn (gen_addsi3 (indx, operands[0], offset)); 1312 } 1313 emit_cmp_and_jump_insns (indx, range, GTU, NULL_RTX, SImode, 1, fail); 1314 1315 emit_jump_insn (gen_casesi_internal (indx, table)); 1316 DONE; 1317}) 1318 1319;; This is the only instance in this file where a pattern emits more than 1320;; one instruction. The concern here is that the addkpc insn could otherwise 1321;; be scheduled too far away from the label. A tablejump always ends an 1322;; extended basic block, so it shouldn't happen that the scheduler places 1323;; something in the delay slots. 1324(define_insn "casesi_internal" 1325 [(set (pc) 1326 (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "b") 1327 (const_int 4)) 1328 (label_ref (match_operand 1 "" ""))))) 1329 (clobber (match_scratch:SI 2 "=&b")) 1330 (clobber (match_scratch:SI 3 "=b"))] 1331 "flag_pic && TARGET_INSNS_64" 1332 "addkpc\t.s2\t%l1,%2, 0\n\t\tldw\t.d2t2\t*+%2[%0], %3\n\t\tnop\t\t4\n\t\tadd\t.l2\t%2, %3, %3\n\t\tb\t.s2\t%3" 1333 [(set_attr "type" "branch") 1334 (set_attr "predicable" "no") 1335 (set_attr "dest_regfile" "b")]) 1336 1337(define_expand "cbranch<mode>4" 1338 [(set (pc) 1339 (if_then_else (match_operator 0 "comparison_operator" 1340 [(match_operand:SIDIM 1 "register_operand" "") 1341 (match_operand:SIDIM 2 "reg_or_const_int_operand" "")]) 1342 (label_ref (match_operand 3 "" "")) 1343 (pc)))] 1344 "" 1345{ 1346 rtx t = c6x_expand_compare (operands[0], VOIDmode); 1347 operands[0] = t; 1348 operands[1] = XEXP (t, 0); 1349 operands[2] = XEXP (t, 1); 1350}) 1351 1352(define_expand "cbranch<mode>4" 1353 [(set (pc) 1354 (if_then_else (match_operator 0 "c6x_fp_comparison_operator" 1355 [(match_operand:SFDFM 1 "register_operand" "") 1356 (match_operand:SFDFM 2 "register_operand" "")]) 1357 (label_ref (match_operand 3 "" "")) 1358 (pc)))] 1359 "" 1360{ 1361 rtx t = c6x_expand_compare (operands[0], VOIDmode); 1362 operands[0] = t; 1363 operands[1] = XEXP (t, 0); 1364 operands[2] = XEXP (t, 1); 1365}) 1366 1367(define_insn "br_true" 1368 [(set (pc) 1369 (if_then_else (match_operator 0 "predicate_operator" 1370 [(match_operand:SI 1 "register_operand" "AB") 1371 (const_int 0)]) 1372 (label_ref (match_operand 2 "" "")) 1373 (pc)))] 1374 "" 1375 "%|[%J0]\\tb\\t%$\\t%l2" 1376 [(set_attr "type" "branch") 1377 (set_attr "predicable" "no") 1378 (set_attr "units" "s") 1379 (set_attr "dest_regfile" "any")]) 1380 1381(define_insn "br_false" 1382 [(set (pc) 1383 (if_then_else (match_operator 0 "predicate_operator" 1384 [(match_operand:SI 1 "register_operand" "AB") 1385 (const_int 0)]) 1386 (pc) 1387 (label_ref (match_operand 2 "" ""))))] 1388 "" 1389 "%|[%j0]\\tb\\t%$\\t%l2" 1390 [(set_attr "type" "branch") 1391 (set_attr "predicable" "no") 1392 (set_attr "units" "s") 1393 (set_attr "dest_regfile" "any")]) 1394 1395(define_expand "return" 1396 [(parallel 1397 [(return) 1398 (use (reg:SI REG_B3))])] 1399 "reload_completed && get_frame_size () == 0 && c6x_nsaved_regs () == 0") 1400 1401;; We can't expand this before we know where the link register is stored. 1402(define_insn_and_split "eh_return" 1403 [(unspec_volatile [(match_operand:SI 0 "register_operand" "ab")] 1404 UNSPECV_EH_RETURN) 1405 (clobber (match_scratch:SI 1 "=&ab"))] 1406 "" 1407 "#" 1408 "&& reload_completed" 1409 [(const_int 0)] 1410 " 1411 { 1412 c6x_set_return_address (operands[0], operands[1]); 1413 DONE; 1414 }" 1415) 1416 1417;; ------------------------------------------------------------------------- 1418;; Doloop 1419;; ------------------------------------------------------------------------- 1420 1421; operand 0 is the loop count pseudo register 1422; operand 1 is the label to jump to at the top of the loop 1423(define_expand "doloop_end" 1424 [(parallel [(set (pc) (if_then_else 1425 (ne (match_operand:SI 0 "" "") 1426 (const_int 1)) 1427 (label_ref (match_operand 1 "" "")) 1428 (pc))) 1429 (set (match_dup 0) 1430 (plus:SI (match_dup 0) 1431 (const_int -1))) 1432 (clobber (match_dup 2))])] ; match_scratch 1433 "TARGET_INSNS_64PLUS && optimize" 1434{ 1435 /* The loop optimizer doesn't check the predicates... */ 1436 if (GET_MODE (operands[0]) != SImode) 1437 FAIL; 1438 operands[2] = gen_rtx_SCRATCH (SImode); 1439}) 1440 1441(define_insn "mvilc" 1442 [(set (reg:SI REG_ILC) 1443 (unspec [(match_operand:SI 0 "register_operand" "a,b")] UNSPEC_MVILC))] 1444 "TARGET_INSNS_64PLUS" 1445 "%|%.\\tmvc\\t%$\\t%0, ILC" 1446 [(set_attr "predicable" "no") 1447 (set_attr "cross" "y,n") 1448 (set_attr "units" "s") 1449 (set_attr "dest_regfile" "b") 1450 (set_attr "type" "mvilc")]) 1451 1452(define_insn "sploop" 1453 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i") 1454 (reg:SI REG_ILC)] 1455 UNSPECV_SPLOOP)] 1456 "TARGET_INSNS_64PLUS" 1457 "%|%.\\tsploop\t%0" 1458 [(set_attr "predicable" "no") 1459 (set_attr "type" "sploop")]) 1460 1461(define_insn "spkernel" 1462 [(set (pc) 1463 (if_then_else 1464 (ne (unspec_volatile:SI 1465 [(match_operand:SI 0 "const_int_operand" "i") 1466 (match_operand:SI 1 "const_int_operand" "i")] 1467 UNSPECV_SPKERNEL) 1468 (const_int 1)) 1469 (label_ref (match_operand 2 "" "")) 1470 (pc)))] 1471 "TARGET_INSNS_64PLUS" 1472 "%|%.\\tspkernel\t%0, %1" 1473 [(set_attr "predicable" "no") 1474 (set_attr "type" "spkernel")]) 1475 1476(define_insn "loop_end" 1477 [(set (pc) 1478 (if_then_else (ne (match_operand:SI 3 "nonimmediate_operand" "0,0,0,*r") 1479 (const_int 1)) 1480 (label_ref (match_operand 1 "" "")) 1481 (pc))) 1482 (set (match_operand:SI 0 "nonimmediate_operand" "=AB,*r,m,m") 1483 (plus:SI (match_dup 3) 1484 (const_int -1))) 1485 (clobber (match_scratch:SI 2 "=X,&AB,&AB,&AB"))] 1486 "TARGET_INSNS_64PLUS && optimize" 1487 "#" 1488 [(set_attr "type" "spkernel")]) 1489 1490(define_split 1491 [(set (pc) 1492 (if_then_else (ne (match_operand:SI 3 "nonimmediate_operand" "") 1493 (const_int 1)) 1494 (label_ref (match_operand 1 "" "")) 1495 (pc))) 1496 (set (match_operand:SI 0 "memory_operand" "") 1497 (plus:SI (match_dup 3) 1498 (const_int -1))) 1499 (clobber (match_scratch 2))] 1500 "" 1501 [(set (match_dup 2) (plus:SI (match_dup 3) (const_int -1))) 1502 (set (match_dup 0) (match_dup 2)) 1503 (set (pc) 1504 (if_then_else (ne (match_dup 2) (const_int 0)) 1505 (label_ref (match_dup 1)) 1506 (pc)))] 1507{ 1508 if (!REG_P (operands[3])) 1509 { 1510 emit_move_insn (operands[2], operands[3]); 1511 operands[3] = operands[2]; 1512 } 1513}) 1514 1515;; ------------------------------------------------------------------------- 1516;; Delayed-branch real jumps and shadows 1517;; ------------------------------------------------------------------------- 1518 1519(define_insn "real_jump" 1520 [(unspec [(match_operand 0 "c6x_jump_operand" "a,b,S3") (const_int 0)] 1521 UNSPEC_REAL_JUMP)] 1522 "" 1523{ 1524 if (GET_CODE (operands[0]) == LABEL_REF) 1525 return "%|%.\\tb\\t%$\\t%l0"; 1526 return "%|%.\\tb\\t%$\\t%0"; 1527} 1528 [(set_attr "type" "branch") 1529 (set_attr "has_shadow" "y") 1530 (set_attr "units" "s") 1531 (set_attr "cross" "y,n,n") 1532 (set_attr "dest_regfile" "b,b,any")]) 1533 1534(define_insn "real_call" 1535 [(unspec [(match_operand 0 "c6x_call_operand" "a,b,S1") (const_int 1)] 1536 UNSPEC_REAL_JUMP) 1537 (clobber (reg:SI REG_B3))] 1538 "" 1539 "%|%.\\tcall\\t%$\\t%0" 1540 [(set_attr "type" "call") 1541 (set_attr "has_shadow" "y") 1542 (set_attr "predicable" "no") 1543 (set_attr "units" "s") 1544 (set_attr "cross" "y,n,n") 1545 (set_attr "dest_regfile" "b,b,any")]) 1546 1547(define_insn "real_ret" 1548 [(unspec [(match_operand 0 "register_operand" "a,b") (const_int 2)] 1549 UNSPEC_REAL_JUMP)] 1550 "" 1551 "%|%.\\tret\\t%$\\t%0" 1552 [(set_attr "type" "branch") 1553 (set_attr "has_shadow" "y") 1554 (set_attr "units" "s") 1555 (set_attr "cross" "y,n") 1556 (set_attr "dest_regfile" "b")]) 1557 1558;; computed_jump_p returns true if it finds a constant; so use one in the 1559;; unspec. 1560(define_insn "indirect_jump_shadow" 1561 [(set (pc) (unspec [(const_int 1)] UNSPEC_JUMP_SHADOW))] 1562 "" 1563 ";; indirect jump occurs" 1564 [(set_attr "type" "shadow")]) 1565 1566;; Operand 0 may be a PARALLEL which isn't handled by output_operand, so 1567;; we don't try to print it. 1568(define_insn "indirect_call_value_shadow" 1569 [(set (match_operand 0 "" "") 1570 (call (unspec [(pc)] UNSPEC_JUMP_SHADOW) 1571 (const_int 0)))] 1572 "" 1573 ";; indirect call occurs, with return value" 1574 [(set_attr "type" "shadow")]) 1575 1576(define_insn "indirect_sibcall_shadow" 1577 [(call (unspec [(pc)] UNSPEC_JUMP_SHADOW) 1578 (const_int 0))] 1579 "SIBLING_CALL_P (insn)" 1580 ";; indirect sibcall occurs" 1581 [(set_attr "type" "shadow")]) 1582 1583(define_insn "indirect_call_shadow" 1584 [(call (unspec [(pc)] UNSPEC_JUMP_SHADOW) 1585 (const_int 0))] 1586 "" 1587 ";; indirect call occurs" 1588 [(set_attr "type" "shadow")]) 1589 1590(define_insn "call_value_shadow" 1591 [(set (match_operand 0 "" "") 1592 (call (unspec [(match_operand 1 "" "")] UNSPEC_JUMP_SHADOW) 1593 (const_int 0)))] 1594 "" 1595 ";; call to %1 occurs, with return value" 1596 [(set_attr "type" "shadow")]) 1597 1598(define_insn "call_shadow" 1599 [(call (unspec [(match_operand 0 "" "")] UNSPEC_JUMP_SHADOW) 1600 (const_int 0))] 1601 "!SIBLING_CALL_P (insn)" 1602 ";; call to %0 occurs" 1603 [(set_attr "type" "shadow")]) 1604 1605(define_insn "sibcall_shadow" 1606 [(call (unspec [(match_operand 0 "" "")] UNSPEC_JUMP_SHADOW) 1607 (const_int 0))] 1608 "SIBLING_CALL_P (insn)" 1609 ";; sibcall to %0 occurs" 1610 [(set_attr "type" "shadow")]) 1611 1612(define_insn "jump_shadow" 1613 [(set (pc) (unspec [(match_operand 0 "" "")] UNSPEC_JUMP_SHADOW))] 1614 "" 1615 ";; jump to %0 occurs" 1616 [(set_attr "type" "shadow")]) 1617 1618(define_insn "condjump_shadow" 1619 [(set (pc) 1620 (if_then_else (eq (unspec [(const_int 0)] UNSPEC_JUMP_SHADOW) 1621 (const_int 0)) 1622 (match_operand 0 "" "") 1623 (pc)))] 1624 "" 1625 ";; condjump to %0 occurs" 1626 [(set_attr "type" "shadow")]) 1627 1628(define_insn "return_shadow" 1629 [(unspec [(const_int 0)] UNSPEC_JUMP_SHADOW) 1630 (return)] 1631 "" 1632 ";; return occurs" 1633 [(set_attr "type" "shadow")]) 1634 1635;; ------------------------------------------------------------------------- 1636;; Add instructions 1637;; ------------------------------------------------------------------------- 1638 1639(define_insn "addsi3" 1640 [(set (match_operand:SI 0 "register_operand" 1641 "=a ,b , a, b, a, b, a, b, ab, a, b, a, b,ab") 1642 (plus:SI (match_operand:SI 1 "register_operand" 1643 "%a ,b , a, b, b, a, b, a, 0, a, b, z, z,0") 1644 (match_operand:SI 2 "addsi_operand" 1645 "aIs5,bIs5,?b,?a,?a,?b,?aIs5,?bIs5,I5x,I5x,I5x,Iux,Iux,IsB")))] 1646 "" 1647{ 1648 if (CONSTANT_P (operands[2])) 1649 { 1650 HOST_WIDE_INT val = INTVAL (operands[2]); 1651 1652 if (c6x_get_unit_specifier (insn) == 'd') 1653 { 1654 bool issp = (TARGET_INSNS_64PLUS 1655 && operands[1] == stack_pointer_rtx 1656 && GET_CODE (PATTERN (insn)) != COND_EXEC); 1657 1658 if (get_attr_cross (insn) == CROSS_N) 1659 { 1660 if (satisfies_constraint_Iu5 (operands[2])) 1661 return "%|%.\\tadd\\t%$\\t%1, %2, %0"; 1662 else if (satisfies_constraint_In5 (operands[2])) 1663 return "%|%.\\tsub\\t%$\\t%1, %n2, %0"; 1664 } 1665 1666 if (issp && val > 0 && val < 32768) 1667 { 1668 return "%|%.\\taddab\\t%$\\t%1, %2, %0"; 1669 } 1670 if ((val & 1) == 0 && ((val >= -62 && val <= 62) 1671 || (issp && val > 0 && val < 65536))) 1672 { 1673 if (val < 0) 1674 return "%|%.\\tsubah\\t%$\\t%1, %r2, %0"; 1675 else 1676 return "%|%.\\taddah\\t%$\\t%1, %r2, %0"; 1677 } 1678 else if ((val & 3) == 0 && ((val >= -124 && val <= 124) 1679 || (issp && val > 0 && val < 131072))) 1680 { 1681 if (val < 0) 1682 return "%|%.\\tsubaw\\t%$\\t%1, %R2, %0"; 1683 else 1684 return "%|%.\\taddaw\\t%$\\t%1, %R2, %0"; 1685 } 1686 else if ((val & 7) == 0 && val > 0 && val <= 248) 1687 { 1688 rtx xop[3]; 1689 xop[0] = operands[0]; 1690 xop[1] = operands[1]; 1691 xop[2] = GEN_INT (val >> 3); 1692 output_asm_insn ("%|%.\\taddad\\t%$\\t%1, %2, %0", xop); 1693 return ""; 1694 } 1695 } 1696 else 1697 { 1698 if (satisfies_constraint_Is5 (operands[2])) 1699 return "%|%.\\tadd\\t%$\\t%2, %1, %0"; 1700 } 1701 gcc_assert (rtx_equal_p (operands[0], operands[1])); 1702 return "%|%.\\taddk\\t%$\\t%2, %0"; 1703 } 1704 if (which_alternative == 4 || which_alternative == 5) 1705 return "%|%.\\tadd\\t%$\\t%2, %1, %0"; 1706 else 1707 return "%|%.\\tadd\\t%$\\t%1, %2, %0"; 1708} 1709 [(set_attr "units62" "dls,dls,ls,ls,ls,ls,ls,ls,s,d,d,*,*,s") 1710 (set_attr "units67" "dls,dls,ls,ls,ls,ls,ls,ls,ds,d,d,*,*,s") 1711 (set_attr "units64" "dls,dls,dls,dls,dls,dls,ls,ls,ds,d,d,d,d,s") 1712 (set_attr "cross" "n,n,y,y,y,y,y,y,n,n,n,y,n,n") 1713 (set_attr "predicable" "yes,yes,yes,yes,yes,yes,yes,yes,yes,yes,yes,no,no,yes")]) 1714 1715(define_insn "subsi3" 1716 [(set (match_operand:SI 0 "register_operand" "=a,b,a,b,a,b") 1717 (minus:SI (match_operand:SI 1 "reg_or_scst5_operand" "a,b,aIs5,bIs5,bIs5,aIs5") 1718 (match_operand:SI 2 "register_operand" "a,b,a,b,?a,?b")))] 1719 "" 1720 "%|%.\\tsub\\t%$\\t%1, %2, %0" 1721 [(set_attr "units62" "dls,dls,ls,ls,l,l") 1722 (set_attr "units64" "dls,dls,ls,ls,ls,ls") 1723 (set_attr "cross" "n,n,n,n,y,y")]) 1724 1725(define_insn "*addshiftsi" 1726 [(set (match_operand:SI 0 "register_operand" "=a,b") 1727 (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "a,b") 1728 (match_operand:SI 3 "adda_scale_operand" "n,n")) 1729 (match_operand:SI 1 "register_operand" "a,b")))] 1730 "" 1731 "%|%.\\tadda%d3\\t%$\\t%1, %2, %0" 1732 [(set_attr "units" "d")]) 1733 1734(define_insn "*subshiftsi" 1735 [(set (match_operand:SI 0 "register_operand" "=a,b") 1736 (minus:SI (match_operand:SI 1 "register_operand" "a,b") 1737 (mult:SI (match_operand:SI 2 "register_operand" "a,b") 1738 (match_operand:SI 3 "suba_scale_operand" "n,n"))))] 1739 "" 1740 "%|%.\\tsuba%d3\\t%$\\t%1, %2, %0" 1741 [(set_attr "units" "d")]) 1742 1743(define_insn "addsidi3_widen" 1744 [(set (match_operand:DI 0 "register_operand" "=a,b,a,b") 1745 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%a,b,a,b")) 1746 (zero_extend:DI (match_operand:SI 2 "register_operand" "a,b,?b,?a"))))] 1747 "" 1748 "%|%.\\taddu\\t%$\\t%1, %2, %0" 1749 [(set_attr "units" "l") 1750 (set_attr "cross" "n,n,y,y")]) 1751 1752(define_expand "adddi3" 1753 [(set (match_operand:DI 0 "register_operand" "") 1754 (plus:DI (match_operand:DI 1 "register_operand" "") 1755 (match_operand:DI 2 "register_operand" "")))] 1756 "" 1757{ 1758 rtx tmp; 1759 rtx lo_half[3], hi_half[3]; 1760 split_di (operands + 1, 2, lo_half + 1, hi_half + 1); 1761 if (reg_overlap_mentioned_p (operands[0], hi_half[1]) 1762 || reg_overlap_mentioned_p (operands[0], hi_half[2])) 1763 tmp = gen_reg_rtx (DImode); 1764 else 1765 tmp = operands[0]; 1766 split_di (&tmp, 1, lo_half, hi_half); 1767 emit_insn (gen_addsidi3_widen (tmp, lo_half[1], lo_half[2])); 1768 emit_insn (gen_addsi3 (hi_half[0], copy_rtx (hi_half[0]), hi_half[1])); 1769 emit_insn (gen_addsi3 (copy_rtx (hi_half[0]), 1770 copy_rtx (hi_half[0]), hi_half[2])); 1771 if (tmp != operands[0]) 1772 emit_move_insn (operands[0], tmp); 1773 DONE; 1774}) 1775 1776(define_insn "addsf3" 1777 [(set (match_operand:SF 0 "register_operand" "=a,b,a,b") 1778 (plus:SF (match_operand:SF 1 "register_operand" "%a,b,a,b") 1779 (match_operand:SF 2 "register_operand" "a,b,?b,?a")))] 1780 "TARGET_FP" 1781 "%|%.\\taddsp\\t%$\\t%1, %2, %0" 1782 [(set_attr "type" "fp4") 1783 (set_attr "units67" "l") 1784 (set_attr "units67p" "ls") 1785 (set_attr "units674" "ls") 1786 (set_attr "cross" "n,n,y,y")]) 1787 1788(define_insn "adddf3" 1789 [(set (match_operand:DF 0 "register_operand" "=a,b,a,b") 1790 (plus:DF (match_operand:DF 1 "register_operand" "%a,b,a,b") 1791 (match_operand:DF 2 "register_operand" "a,b,?b,?a")))] 1792 "TARGET_FP" 1793 "%|%.\\tadddp\\t%$\\t%1, %2, %0" 1794 [(set_attr "type" "adddp") 1795 (set_attr "units67" "l") 1796 (set_attr "units67p" "ls") 1797 (set_attr "units674" "ls") 1798 (set_attr "cross" "n,n,y,y")]) 1799 1800(define_insn "subsf3" 1801 [(set (match_operand:SF 0 "register_operand" "=a,b, a, b, a, b") 1802 (minus:SF (match_operand:SF 1 "register_operand" "a,b, b, a, a, b") 1803 (match_operand:SF 2 "register_operand" "a,b,?a,?b,?b,?a")))] 1804 "TARGET_FP" 1805 "%|%.\\tsubsp\\t%$\\t%1, %2, %0" 1806 [(set_attr "type" "fp4") 1807 (set_attr "units67" "l") 1808 (set_attr "units67p" "ls") 1809 (set_attr "units674" "ls") 1810 (set_attr "cross" "n,n,y,y,y,y")]) 1811 1812(define_insn "subdf3" 1813 [(set (match_operand:DF 0 "register_operand" "=a,b, a, b, a, b") 1814 (minus:DF (match_operand:DF 1 "register_operand" "a,b, b, a, a, b") 1815 (match_operand:DF 2 "register_operand" "a,b,?a,?b,?b,?a")))] 1816 "TARGET_FP" 1817 "%|%.\\tsubdp\\t%$\\t%1, %2, %0" 1818 [(set_attr "type" "adddp") 1819 (set_attr "units67" "l") 1820 (set_attr "units67p" "ls") 1821 (set_attr "units674" "ls") 1822 (set_attr "cross" "n,n,y,y,y,y")]) 1823 1824;; ------------------------------------------------------------------------- 1825;; Logical instructions 1826;; ------------------------------------------------------------------------- 1827 1828(define_insn "andsi3" 1829 [(set (match_operand:SI 0 "register_operand" "=a,b,a,b,a,b") 1830 (and:SI (match_operand:SI 1 "register_operand" "%a,b,b,a,a,b") 1831 (match_operand:SI 2 "andsi_operand" "aIs5,bIs5,?aIs5,?bIs5,aJc,bJc")))] 1832 "" 1833{ 1834 if (which_alternative < 4) 1835 return "%|%.\\tand\\t%$\\t%2, %1, %0"; 1836 else 1837 return "%|%.\\tclr\\t%$\\t%1, %f2, %F2, %0"; 1838} 1839 [(set_attr "units62" "ls,ls,ls,ls,s,s") 1840 (set_attr "units64" "dls,dls,dls,dls,s,s") 1841 (set_attr "cross" "n,n,y,y,n,n")]) 1842 1843(define_insn "iorsi3" 1844 [(set (match_operand:SI 0 "register_operand" "=a,b,a,b,a,b") 1845 (ior:SI (match_operand:SI 1 "register_operand" "%a,b,b,a,a,b") 1846 (match_operand:SI 2 "iorsi_operand" "aIs5,bIs5,?aIs5,?bIs5,aJs,bJs")))] 1847 "" 1848{ 1849 if (which_alternative < 4) 1850 return "%|%.\\tor\\t%$\\t%2, %1, %0"; 1851 else 1852 return "%|%.\\tset\\t%$\\t%1, %s2, %S2, %0"; 1853} 1854 [(set_attr "units62" "ls,ls,ls,ls,s,s") 1855 (set_attr "units64" "dls,dls,dls,dls,s,s") 1856 (set_attr "cross" "n,n,y,y,n,n")]) 1857 1858(define_insn "xorsi3" 1859 [(set (match_operand:SI 0 "register_operand" "=a,b,a,b") 1860 (xor:SI (match_operand:SI 1 "register_operand" "%a,b,b,a") 1861 (match_operand:SI 2 "reg_or_scst5_operand" "aIs5,bIs5,?aIs5,?bIs5")))] 1862 "" 1863 "%|%.\\txor\\t%$\\t%2, %1, %0" 1864 [(set_attr "units62" "ls") 1865 (set_attr "units64" "dls") 1866 (set_attr "cross" "n,n,y,y")]) 1867 1868;; ------------------------------------------------------------------------- 1869;; Conversions 1870;; ------------------------------------------------------------------------- 1871 1872(define_insn "extendsfdf2" 1873 [(set (match_operand:DF 0 "register_operand" "=a,b,a,b") 1874 (float_extend:DF (match_operand:SF 1 "register_operand" "a,b,?b,?a")))] 1875 "TARGET_FP" 1876 "%|%.\\tspdp\\t%$\\t%1,%0" 1877 [(set_attr "type" "dp2") 1878 (set_attr "units" "s") 1879 (set_attr "cross" "n,n,y,y")]) 1880 1881(define_insn "truncdfsf2" 1882 [(set (match_operand:SF 0 "register_operand" "=a,b") 1883 (float_truncate:SF (match_operand:DF 1 "register_operand" "a,b")))] 1884 "TARGET_FP" 1885 "%|%.\\tdpsp\\t%$\\t%1,%0" 1886 [(set_attr "type" "fp4") 1887 (set_attr "units" "l") 1888 (set_attr "cross" "n")]) 1889 1890;;;; Convert between signed integer types and floating point. 1891(define_insn "floatsisf2" 1892 [(set (match_operand:SF 0 "register_operand" "=a,b,a,b") 1893 (float:SF (match_operand:SI 1 "register_operand" "a,b,?b,?a")))] 1894 "TARGET_FP" 1895 "%|%.\\tintsp\\t%$\\t%1,%0" 1896 [(set_attr "type" "fp4") 1897 (set_attr "units" "l") 1898 (set_attr "cross" "n,n,y,y")]) 1899 1900(define_insn "floatunssisf2" 1901 [(set (match_operand:SF 0 "register_operand" "=a,b,a,b") 1902 (unsigned_float:SF (match_operand:SI 1 "register_operand" "a,b,?b,?a")))] 1903 "TARGET_FP" 1904 "%|%.\\tintspu\\t%$\\t%1,%0" 1905 [(set_attr "type" "fp4") 1906 (set_attr "units" "l") 1907 (set_attr "cross" "n,n,y,y")]) 1908 1909(define_insn "floatsidf2" 1910 [(set (match_operand:DF 0 "register_operand" "=a,b,a,b") 1911 (float:DF (match_operand:SI 1 "register_operand" "a,b,?b,?a")))] 1912 "TARGET_FP" 1913 "%|%.\\tintdp\\t%$\\t%1,%0" 1914 [(set_attr "type" "intdp") 1915 (set_attr "units" "l") 1916 (set_attr "cross" "n,n,y,y")]) 1917 1918(define_insn "floatunssidf2" 1919 [(set (match_operand:DF 0 "register_operand" "=a,b,a,b") 1920 (unsigned_float:DF (match_operand:SI 1 "register_operand" "a,b,?b,?a")))] 1921 "TARGET_FP" 1922 "%|%.\\tintdpu\\t%$\\t%1,%0" 1923 [(set_attr "type" "intdp") 1924 (set_attr "units" "l") 1925 (set_attr "cross" "n,n,y,y")]) 1926 1927(define_insn "fix_truncsfsi2" 1928 [(set (match_operand:SI 0 "register_operand" "=a,b,a,b") 1929 (fix:SI (match_operand:SF 1 "register_operand" "a,b,?b,?a")))] 1930 "TARGET_FP" 1931 "%|%.\\tsptrunc\\t%$\\t%1,%0" 1932 [(set_attr "type" "fp4") 1933 (set_attr "units" "l") 1934 (set_attr "cross" "n,n,y,y")]) 1935 1936(define_insn "fix_truncdfsi2" 1937 [(set (match_operand:SI 0 "register_operand" "=a,b") 1938 (fix:SI (match_operand:DF 1 "register_operand" "a,b")))] 1939 "TARGET_FP" 1940 "%|%.\\tdptrunc\\t%$\\t%1,%0" 1941 [(set_attr "type" "fp4") 1942 (set_attr "units" "l") 1943 (set_attr "cross" "n")]) 1944 1945;; ------------------------------------------------------------------------- 1946;; Saturating arithmetic 1947;; ------------------------------------------------------------------------- 1948 1949(define_insn "saddsi3" 1950 [(set (match_operand:SI 0 "register_operand" "=a,b,a,b,a,b,a,b") 1951 (ss_plus:SI (match_operand:SI 1 "register_operand" "a,b,?b,?a,a,b,?b,?a") 1952 (match_operand:SI 2 "reg_or_const_int_operand" "a,b,a,b,aIs5,bIs5,aIs5,bIs5")))] 1953 "" 1954 "%|%.\\tsadd\\t%$\\t%2, %1, %0" 1955 [(set_attr "units" "ls,ls,ls,ls,l,l,l,l") 1956 (set_attr "cross" "n,n,y,y,n,n,y,y")]) 1957 1958(define_insn "ssubsi3" 1959 [(set (match_operand:SI 0 "register_operand" "=a,b,a,b") 1960 (ss_minus:SI (match_operand:SI 1 "reg_or_scst5_operand" "aIs5,bIs5,?bIs5,?aIs5") 1961 (match_operand:SI 2 "register_operand" "a,b,a,b")))] 1962 "" 1963 "%|%.\\tssub\\t%$\\t%1, %2, %0" 1964 [(set_attr "units" "l") 1965 (set_attr "cross" "n,n,y,y")]) 1966 1967(define_insn "subcsi3" 1968 [(set (match_operand:SI 0 "register_operand" "=a,b,a,b") 1969 (unspec:SI 1970 [(match_operand:SI 1 "register_operand" "a,b,a,b") 1971 (match_operand:SI 2 "register_operand" "a,b,?b,?a")] 1972 UNSPEC_SUBC))] 1973 "" 1974 "%|%.\\tsubc\\t%$\\t%1, %2, %0" 1975 [(set_attr "units" "l") 1976 (set_attr "cross" "n,n,y,y")]) 1977 1978;; ------------------------------------------------------------------------- 1979;; Call instructions 1980;; ------------------------------------------------------------------------- 1981 1982(define_expand "call" 1983 [(match_operand 0 "" "")] 1984 "" 1985{ 1986 c6x_expand_call (NULL_RTX, operands[0], false); 1987 DONE; 1988}) 1989 1990(define_expand "call_value" 1991 [(match_operand 0 "" "") 1992 (match_operand 1 "" "")] 1993 "" 1994{ 1995 c6x_expand_call (operands[0], operands[1], false); 1996 DONE; 1997}) 1998 1999(define_expand "sibcall" 2000 [(match_operand 0 "" "")] 2001 "" 2002{ 2003 c6x_expand_call (NULL_RTX, operands[0], true); 2004 cfun->machine->contains_sibcall = true; 2005 DONE; 2006}) 2007 2008(define_expand "sibcall_value" 2009 [(match_operand 0 "" "") 2010 (match_operand 1 "" "")] 2011 "" 2012{ 2013 c6x_expand_call (operands[0], operands[1], true); 2014 cfun->machine->contains_sibcall = true; 2015 DONE; 2016}) 2017 2018(define_insn "call_internal" 2019 [(call (mem (match_operand:SI 0 "c6x_call_operand" "S1,a,b")) 2020 (const_int 0))] 2021 "!SIBLING_CALL_P (insn)" 2022 "%|%.\\tcall\\t%$\\t%0" 2023 [(set_attr "type" "call") 2024 (set_attr "predicable" "no") 2025 (set_attr "units" "s") 2026 (set_attr "dest_regfile" "any,b,b") 2027 (set_attr "cross" "n,y,n")]) 2028 2029(define_insn "call_value_internal" 2030 [(set (match_operand 0 "" "") 2031 (call (mem (match_operand:SI 1 "c6x_call_operand" "S1,a,b")) 2032 (const_int 0)))] 2033 "" 2034 "%|%.\\tcall\\t%$\\t%1" 2035 [(set_attr "type" "call") 2036 (set_attr "predicable" "no") 2037 (set_attr "units" "s") 2038 (set_attr "dest_regfile" "any,b,b") 2039 (set_attr "cross" "n,y,n")]) 2040 2041(define_insn "sibcall_internal" 2042 [(call (mem (match_operand:SI 0 "c6x_call_operand" "S1,C")) 2043 (const_int 0))] 2044 "SIBLING_CALL_P (insn)" 2045 "%|%.\\tb\\t%$\\t%0" 2046 [(set_attr "type" "branch") 2047 (set_attr "predicable" "no") 2048 (set_attr "units" "s") 2049 (set_attr "dest_regfile" "any,b")]) 2050 2051(define_insn "callp" 2052 [(call (mem (match_operand:SI 0 "c6x_call_operand" "S1")) 2053 (const_int 0)) 2054 (unspec [(const_int 6)] UNSPEC_NOP)] 2055 "!SIBLING_CALL_P (insn)" 2056 "%|%.\\tcallp\\t%$\\t%0, B3" 2057 [(set_attr "type" "callp") 2058 (set_attr "predicable" "no") 2059 (set_attr "units" "s") 2060 (set_attr "dest_regfile" "b") 2061 (set_attr "cross" "n")]) 2062 2063(define_insn "callp_value" 2064 [(set (match_operand:SI 0 "register_operand" "") 2065 (call (mem (match_operand:SI 1 "c6x_call_operand" "S1")) 2066 (const_int 0))) 2067 (unspec [(const_int 6)] UNSPEC_NOP)] 2068 "!SIBLING_CALL_P (insn)" 2069 "%|%.\\tcallp\\t%$\\t%1, B3" 2070 [(set_attr "type" "callp") 2071 (set_attr "predicable" "no") 2072 (set_attr "units" "s") 2073 (set_attr "dest_regfile" "b") 2074 (set_attr "cross" "n")]) 2075 2076(define_insn "return_internal" 2077 [(return) 2078 (use (match_operand:SI 0 "register_operand" "b"))] 2079 "reload_completed" 2080 "%|%.\\tret\\t%$\\t%0" 2081 [(set_attr "type" "branch") 2082 (set_attr "units" "s") 2083 (set_attr "dest_regfile" "b")]) 2084 2085(define_insn "addkpc" 2086 [(set (match_operand:SI 0 "register_operand" "=b") 2087 (unspec:SI [(match_operand 1 "" "")] UNSPEC_ADDKPC)) 2088 (unspec [(match_operand 2 "const_int_operand" "n")] UNSPEC_NOP)] 2089 "TARGET_INSNS_64" 2090 "%|%.\\taddkpc\\t%$\\t%l1, %0, %2" 2091 [(set_attr "units" "s") 2092 (set_attr "dest_regfile" "b")]) 2093 2094;; ------------------------------------------------------------------------- 2095;; Unary operations 2096;; ------------------------------------------------------------------------- 2097 2098(define_insn "negsi2" 2099 [(set (match_operand:SI 0 "register_operand" "=a, a, b, b") 2100 (neg:SI (match_operand:SI 1 "register_operand" "a,?b, b,?a")))] 2101 "" 2102 "%|%.\\tneg\\t%$\\t%1, %0" 2103 [(set_attr "units" "ls") 2104 (set_attr "cross" "n,y,n,y")]) 2105 2106(define_insn "one_cmplsi2" 2107 [(set (match_operand:SI 0 "register_operand" "=a, a, b, b") 2108 (not:SI (match_operand:SI 1 "register_operand" "a,?b, b,?a")))] 2109 "" 2110 "%|%.\\tnot\\t%$\\t%1, %0" 2111 [(set_attr "units" "ls") 2112 (set_attr "cross" "n,y,n,y")]) 2113 2114(define_insn "clrsbsi2" 2115 [(set (match_operand:SI 0 "register_operand" "=a, a, b, b") 2116 (clrsb:SI (match_operand:SI 1 "register_operand" "a,?b, b,?a")))] 2117 "" 2118 "%|%.\\tnorm\\t%$\\t%1, %0" 2119 [(set_attr "units" "l") 2120 (set_attr "cross" "n,y,n,y")]) 2121 2122(define_insn "clzsi2" 2123 [(set (match_operand:SI 0 "register_operand" "=a, a, b, b") 2124 (clz:SI (match_operand:SI 1 "register_operand" "a,?b, b,?a")))] 2125 "" 2126 "%|%.\\tlmbd\\t%$\\t1, %1, %0" 2127 [(set_attr "units" "l") 2128 (set_attr "cross" "n,y,n,y")]) 2129 2130;; bitrevsi2 is defined in c6x-mult.md.in. 2131 2132(define_expand "ctzsi2" 2133 [(set (match_operand:SI 0 "register_operand" "") 2134 (ctz:SI (match_operand:SI 1 "register_operand" "")))] 2135 "TARGET_INSNS_64" 2136{ 2137 rtx tmpreg = gen_reg_rtx (SImode); 2138 emit_insn (gen_bitrevsi2 (tmpreg, operands[1])); 2139 emit_insn (gen_clzsi2 (operands[0], tmpreg)); 2140 DONE; 2141}) 2142 2143(define_expand "ctzdi2" 2144 [(set (match_operand:DI 0 "register_operand" "") 2145 (ctz:DI (match_operand:DI 1 "register_operand" "")))] 2146 "TARGET_INSNS_64" 2147{ 2148 rtx tmpreg = gen_reg_rtx (DImode); 2149 rtx out; 2150 emit_insn (gen_bitrevsi2 (gen_highpart (SImode, tmpreg), 2151 gen_lowpart (SImode, operands[1]))); 2152 emit_insn (gen_bitrevsi2 (gen_lowpart (SImode, tmpreg), 2153 gen_highpart (SImode, operands[1]))); 2154 out = expand_unop (DImode, clz_optab, tmpreg, operands[0], 1); 2155 if (!rtx_equal_p (out, operands[0])) 2156 emit_move_insn (operands[0], out); 2157 DONE; 2158}) 2159 2160(define_insn "ssabssi2" 2161 [(set (match_operand:SI 0 "register_operand" "=a, a, b, b") 2162 (ss_abs:SI (match_operand:SI 1 "register_operand" "a,?b, b,?a")))] 2163 "" 2164 "%|%.\\tabs\\t%$\\t%1, %0" 2165 [(set_attr "units" "l") 2166 (set_attr "cross" "n,y,n,y")]) 2167 2168;; ------------------------------------------------------------------------- 2169;; Shift instructions 2170;; ------------------------------------------------------------------------- 2171 2172(define_code_iterator any_shift [ss_ashift ashift ashiftrt lshiftrt]) 2173(define_code_iterator any_rshift [ashiftrt lshiftrt]) 2174(define_code_attr shift_code [(ss_ashift "ss_ashl") (ashift "ashl") 2175 (ashiftrt "ashr") (lshiftrt "lshr")]) 2176(define_code_attr shift_insn [(ss_ashift "sshl") (ashift "shl") 2177 (ashiftrt "shr") (lshiftrt "shru")]) 2178 2179(define_insn "<shift_code>si3" 2180 [(set (match_operand:SI 0 "register_operand" "=a,b,a,b") 2181 (any_shift:SI (match_operand:SI 1 "register_operand" "a,b,?b,?a") 2182 (match_operand:SI 2 "reg_or_ucst5_operand" "aIu5,bIu5,aIu5,bIu5")))] 2183 "" 2184 "%|%.\\t<shift_insn>\\t%$\\t%1, %2, %0" 2185 [(set_attr "units" "s") 2186 (set_attr "cross" "n,n,y,y")]) 2187 2188;; See c6x-mult.md.in for the rotlsi3 pattern. 2189 2190(define_insn "rotrdi3_16" 2191 [(set (match_operand:DI 0 "register_operand" "=a,b") 2192 (rotatert:DI (match_operand:DI 1 "register_operand" "a,b") 2193 (const_int 16)))] 2194 "TARGET_INSNS_64PLUS" 2195 "%|%.\\tdpackx2\\t%$\\t%P1, %p1, %0" 2196 [(set_attr "units" "l") 2197 (set_attr "cross" "n")]) 2198 2199(define_insn "shlmbsi3" 2200 [(set (match_operand:SI 0 "register_operand" "=a,b,a,b") 2201 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "a,b,?b,?a") 2202 (const_int 8)) 2203 (lshiftrt:SI (match_operand:SI 2 "register_operand" "a,b,a,b") 2204 (const_int 24))))] 2205 "TARGET_INSNS_64" 2206 "%|%.\\tshlmb\\t%$\\t%2, %1, %0" 2207 [(set_attr "units" "ls") 2208 (set_attr "cross" "n,n,y,y")]) 2209 2210(define_expand "ashldi3" 2211 [(set (match_operand:DI 0 "register_operand" "") 2212 (ashift:DI (match_operand:DI 1 "register_operand" "") 2213 (match_operand:SI 2 "const_int_operand" "")))] 2214 "TARGET_INSNS_64" 2215{ 2216 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 8) 2217 { 2218 rtx lo0, lo1, hi0, hi1, tmp; 2219 lo0 = gen_lowpart (SImode, operands[0]); 2220 hi0 = gen_highpart (SImode, operands[0]); 2221 lo1 = gen_lowpart (SImode, operands[1]); 2222 hi1 = gen_highpart (SImode, operands[1]); 2223 if (reg_overlap_mentioned_p (hi0, lo1)) 2224 tmp = gen_reg_rtx (SImode); 2225 else 2226 tmp = hi0; 2227 emit_insn (gen_shlmbsi3 (tmp, hi1, lo1)); 2228 emit_insn (gen_ashlsi3 (lo0, lo1, operands[2])); 2229 if (tmp != hi0) 2230 emit_move_insn (hi0, tmp); 2231 DONE; 2232 } 2233 FAIL; 2234}) 2235 2236(define_expand "rotrdi3" 2237 [(set (match_operand:DI 0 "register_operand" "") 2238 (rotatert:DI (match_operand:DI 1 "register_operand" "") 2239 (match_operand:SI 2 "const_int_operand" "")))] 2240 "TARGET_INSNS_64PLUS" 2241{ 2242 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 16) 2243 { 2244 emit_insn (gen_rotrdi3_16 (operands[0], operands[1])); 2245 DONE; 2246 } 2247 FAIL; 2248}) 2249 2250(define_insn "bswapv2hi2" 2251 [(set (match_operand:V2HI 0 "register_operand" "=a,b,a,b") 2252 (bswap:V2HI (match_operand:V2HI 1 "register_operand" "a,b,?b,?a")))] 2253 "TARGET_INSNS_64" 2254 "%|%.\\tswap4\\t%$\\t%1, %0" 2255 [(set_attr "units" "l") 2256 (set_attr "cross" "n,n,y,y")]) 2257 2258(define_expand "bswapsi2" 2259 [(set (match_operand:SI 0 "register_operand" "") 2260 (bswap:SI (match_operand:SI 1 "register_operand" "")))] 2261 "TARGET_INSNS_64" 2262{ 2263 rtx tmpreg = gen_reg_rtx (SImode); 2264 rtx tmpv2 = gen_lowpart (V2HImode, tmpreg); 2265 rtx op0v2 = gen_lowpart (V2HImode, operands[0]); 2266 emit_insn (gen_rotlsi3 (tmpreg, operands[1], GEN_INT (16))); 2267 emit_insn (gen_bswapv2hi2 (op0v2, tmpv2)); 2268 DONE; 2269}) 2270 2271;; ------------------------------------------------------------------------- 2272;; Division 2273;; ------------------------------------------------------------------------- 2274 2275(define_insn "divsi3_insn" 2276 [(set (reg:SI REG_A4) (div:SI (reg:SI REG_A4) (reg:SI REG_B4))) 2277 (clobber (reg:SI REG_A0)) 2278 (clobber (reg:SI REG_A1)) 2279 (clobber (reg:SI REG_A2)) 2280 (clobber (reg:SI REG_A6)) 2281 (clobber (reg:SI REG_B0)) 2282 (clobber (reg:SI REG_B1)) 2283 (clobber (reg:SI REG_B2)) 2284 (clobber (reg:SI REG_B3)) 2285 (clobber (reg:SI REG_B4)) 2286 (clobber (reg:SI REG_B5)) 2287 (clobber (reg:SI REG_B30)) 2288 (clobber (reg:SI REG_B31))] 2289 "" 2290 "%|%.\\tcall\\t%$\\t__c6xabi_divi" 2291 [(set_attr "type" "call") 2292 (set_attr "dest_regfile" "any") 2293 (set_attr "units" "s") 2294 (set_attr "cross" "n")]) 2295 2296(define_insn "divsi3_insn_indcall" 2297 [(set (reg:SI REG_A4) (div:SI (reg:SI REG_A4) (reg:SI REG_B4))) 2298 (use (match_operand:SI 0 "register_operand" "b")) 2299 (clobber (reg:SI REG_A0)) 2300 (clobber (reg:SI REG_A1)) 2301 (clobber (reg:SI REG_A2)) 2302 (clobber (reg:SI REG_A6)) 2303 (clobber (reg:SI REG_B0)) 2304 (clobber (reg:SI REG_B1)) 2305 (clobber (reg:SI REG_B2)) 2306 (clobber (reg:SI REG_B3)) 2307 (clobber (reg:SI REG_B4)) 2308 (clobber (reg:SI REG_B5)) 2309 (clobber (reg:SI REG_B30)) 2310 (clobber (reg:SI REG_B31))] 2311 "" 2312 "%|%.\\tcall\\t%$\\t%0" 2313 [(set_attr "type" "call") 2314 (set_attr "dest_regfile" "any") 2315 (set_attr "units" "s") 2316 (set_attr "cross" "n")]) 2317 2318(define_insn "udivsi3_insn" 2319 [(set (reg:SI REG_A4) (udiv:SI (reg:SI REG_A4) (reg:SI REG_B4))) 2320 (clobber (reg:SI REG_A0)) 2321 (clobber (reg:SI REG_A1)) 2322 (clobber (reg:SI REG_A2)) 2323 (clobber (reg:SI REG_A6)) 2324 (clobber (reg:SI REG_B0)) 2325 (clobber (reg:SI REG_B1)) 2326 (clobber (reg:SI REG_B2)) 2327 (clobber (reg:SI REG_B3)) 2328 (clobber (reg:SI REG_B4)) 2329 (clobber (reg:SI REG_B30)) 2330 (clobber (reg:SI REG_B31))] 2331 "" 2332 "%|%.\\tcall\\t%$\\t__c6xabi_divu" 2333 [(set_attr "type" "call") 2334 (set_attr "dest_regfile" "any") 2335 (set_attr "units" "s") 2336 (set_attr "cross" "n")]) 2337 2338(define_insn "udivsi3_insn_indcall" 2339 [(set (reg:SI REG_A4) (udiv:SI (reg:SI REG_A4) (reg:SI REG_B4))) 2340 (use (match_operand:SI 0 "register_operand" "b")) 2341 (clobber (reg:SI REG_A0)) 2342 (clobber (reg:SI REG_A1)) 2343 (clobber (reg:SI REG_A2)) 2344 (clobber (reg:SI REG_A6)) 2345 (clobber (reg:SI REG_B0)) 2346 (clobber (reg:SI REG_B1)) 2347 (clobber (reg:SI REG_B2)) 2348 (clobber (reg:SI REG_B3)) 2349 (clobber (reg:SI REG_B4)) 2350 (clobber (reg:SI REG_B30)) 2351 (clobber (reg:SI REG_B31))] 2352 "" 2353 "%|%.\\tcall\\t%$\\t%0" 2354 [(set_attr "type" "call") 2355 (set_attr "dest_regfile" "any") 2356 (set_attr "units" "s") 2357 (set_attr "cross" "n")]) 2358 2359(define_insn "modsi3_insn" 2360 [(set (reg:SI REG_A4) (mod:SI (reg:SI REG_A4) (reg:SI REG_B4))) 2361 (clobber (reg:SI REG_A1)) 2362 (clobber (reg:SI REG_A2)) 2363 (clobber (reg:SI REG_A5)) 2364 (clobber (reg:SI REG_A6)) 2365 (clobber (reg:SI REG_B0)) 2366 (clobber (reg:SI REG_B1)) 2367 (clobber (reg:SI REG_B2)) 2368 (clobber (reg:SI REG_B3)) 2369 (clobber (reg:SI REG_B4)) 2370 (clobber (reg:SI REG_B30)) 2371 (clobber (reg:SI REG_B31))] 2372 "" 2373 "%|%.\\tcall\\t%$\\t__c6xabi_remi" 2374 [(set_attr "type" "call") 2375 (set_attr "dest_regfile" "any") 2376 (set_attr "units" "s") 2377 (set_attr "cross" "n")]) 2378 2379(define_insn "modsi3_insn_indcall" 2380 [(set (reg:SI REG_A4) (mod:SI (reg:SI REG_A4) (reg:SI REG_B4))) 2381 (use (match_operand:SI 0 "register_operand" "b")) 2382 (clobber (reg:SI REG_A1)) 2383 (clobber (reg:SI REG_A2)) 2384 (clobber (reg:SI REG_A5)) 2385 (clobber (reg:SI REG_A6)) 2386 (clobber (reg:SI REG_B0)) 2387 (clobber (reg:SI REG_B1)) 2388 (clobber (reg:SI REG_B2)) 2389 (clobber (reg:SI REG_B3)) 2390 (clobber (reg:SI REG_B4)) 2391 (clobber (reg:SI REG_B30)) 2392 (clobber (reg:SI REG_B31))] 2393 "" 2394 "%|%.\\tcall\\t%$\\t%0" 2395 [(set_attr "type" "call") 2396 (set_attr "dest_regfile" "any") 2397 (set_attr "units" "s") 2398 (set_attr "cross" "n")]) 2399 2400(define_insn "divmodsi4_insn" 2401 [(set (reg:SI REG_A4) (div:SI (reg:SI REG_A4) (reg:SI REG_B4))) 2402 (set (reg:SI REG_A5) (mod:SI (reg:SI REG_A4) (reg:SI REG_B4))) 2403 (clobber (reg:SI REG_A1)) 2404 (clobber (reg:SI REG_A2)) 2405 (clobber (reg:SI REG_A6)) 2406 (clobber (reg:SI REG_B0)) 2407 (clobber (reg:SI REG_B1)) 2408 (clobber (reg:SI REG_B2)) 2409 (clobber (reg:SI REG_B3)) 2410 (clobber (reg:SI REG_B4)) 2411 (clobber (reg:SI REG_B30)) 2412 (clobber (reg:SI REG_B31))] 2413 "" 2414 "%|%.\\tcall\\t%$\\t__c6xabi_divremi" 2415 [(set_attr "type" "call") 2416 (set_attr "dest_regfile" "any") 2417 (set_attr "units" "s") 2418 (set_attr "cross" "n")]) 2419 2420(define_insn "divmodsi4_insn_indcall" 2421 [(set (reg:SI REG_A4) (div:SI (reg:SI REG_A4) (reg:SI REG_B4))) 2422 (set (reg:SI REG_A5) (mod:SI (reg:SI REG_A4) (reg:SI REG_B4))) 2423 (use (match_operand:SI 0 "register_operand" "b")) 2424 (clobber (reg:SI REG_A1)) 2425 (clobber (reg:SI REG_A2)) 2426 (clobber (reg:SI REG_A5)) 2427 (clobber (reg:SI REG_A6)) 2428 (clobber (reg:SI REG_B0)) 2429 (clobber (reg:SI REG_B1)) 2430 (clobber (reg:SI REG_B2)) 2431 (clobber (reg:SI REG_B3)) 2432 (clobber (reg:SI REG_B4)) 2433 (clobber (reg:SI REG_B30)) 2434 (clobber (reg:SI REG_B31))] 2435 "" 2436 "%|%.\\tcall\\t%$\\t%0" 2437 [(set_attr "type" "call") 2438 (set_attr "dest_regfile" "any") 2439 (set_attr "units" "s") 2440 (set_attr "cross" "n")]) 2441 2442(define_insn "umodsi3_insn" 2443 [(set (reg:SI REG_A4) (umod:SI (reg:SI REG_A4) (reg:SI REG_B4))) 2444 (clobber (reg:SI REG_A1)) 2445 (clobber (reg:SI REG_A5)) 2446 (clobber (reg:SI REG_A7)) 2447 (clobber (reg:SI REG_B0)) 2448 (clobber (reg:SI REG_B1)) 2449 (clobber (reg:SI REG_B2)) 2450 (clobber (reg:SI REG_B3)) 2451 (clobber (reg:SI REG_B4)) 2452 (clobber (reg:SI REG_B30)) 2453 (clobber (reg:SI REG_B31))] 2454 "" 2455 "%|%.\\tcall\\t%$\\t__c6xabi_remu" 2456 [(set_attr "type" "call") 2457 (set_attr "dest_regfile" "any") 2458 (set_attr "units" "s") 2459 (set_attr "cross" "n")]) 2460 2461(define_insn "umodsi3_insn_indcall" 2462 [(set (reg:SI REG_A4) (umod:SI (reg:SI REG_A4) (reg:SI REG_B4))) 2463 (use (match_operand:SI 0 "register_operand" "b")) 2464 (clobber (reg:SI REG_A1)) 2465 (clobber (reg:SI REG_A5)) 2466 (clobber (reg:SI REG_A7)) 2467 (clobber (reg:SI REG_B0)) 2468 (clobber (reg:SI REG_B1)) 2469 (clobber (reg:SI REG_B2)) 2470 (clobber (reg:SI REG_B3)) 2471 (clobber (reg:SI REG_B4)) 2472 (clobber (reg:SI REG_B30)) 2473 (clobber (reg:SI REG_B31))] 2474 "" 2475 "%|%.\\tcall\\t%$\\t%0" 2476 [(set_attr "type" "call") 2477 (set_attr "dest_regfile" "any") 2478 (set_attr "units" "s") 2479 (set_attr "cross" "n")]) 2480 2481(define_insn "udivmodsi4_insn" 2482 [(set (reg:SI REG_A4) (udiv:SI (reg:SI REG_A4) (reg:SI REG_B4))) 2483 (set (reg:SI REG_A5) (umod:SI (reg:SI REG_A4) (reg:SI REG_B4))) 2484 (clobber (reg:SI REG_A0)) 2485 (clobber (reg:SI REG_A1)) 2486 (clobber (reg:SI REG_A2)) 2487 (clobber (reg:SI REG_A6)) 2488 (clobber (reg:SI REG_B0)) 2489 (clobber (reg:SI REG_B1)) 2490 (clobber (reg:SI REG_B2)) 2491 (clobber (reg:SI REG_B3)) 2492 (clobber (reg:SI REG_B4)) 2493 (clobber (reg:SI REG_B30)) 2494 (clobber (reg:SI REG_B31))] 2495 "" 2496 "%|%.\\tcall\\t%$\\t__c6xabi_divremu" 2497 [(set_attr "type" "call") 2498 (set_attr "dest_regfile" "any") 2499 (set_attr "units" "s") 2500 (set_attr "cross" "n")]) 2501 2502(define_insn "udivmodsi4_insn_indcall" 2503 [(set (reg:SI REG_A4) (udiv:SI (reg:SI REG_A4) (reg:SI REG_B4))) 2504 (set (reg:SI REG_A5) (umod:SI (reg:SI REG_A4) (reg:SI REG_B4))) 2505 (use (match_operand:SI 0 "register_operand" "b")) 2506 (clobber (reg:SI REG_A0)) 2507 (clobber (reg:SI REG_A1)) 2508 (clobber (reg:SI REG_A2)) 2509 (clobber (reg:SI REG_A6)) 2510 (clobber (reg:SI REG_B0)) 2511 (clobber (reg:SI REG_B1)) 2512 (clobber (reg:SI REG_B2)) 2513 (clobber (reg:SI REG_B3)) 2514 (clobber (reg:SI REG_B4)) 2515 (clobber (reg:SI REG_B30)) 2516 (clobber (reg:SI REG_B31))] 2517 "" 2518 "%|%.\\tcall\\t%$\\t%0" 2519 [(set_attr "type" "call") 2520 (set_attr "dest_regfile" "any") 2521 (set_attr "units" "s") 2522 (set_attr "cross" "n")]) 2523 2524(define_insn_and_split "divmodsi4" 2525 [(set (match_operand:SI 0 "register_operand" "") 2526 (div:SI (match_operand:SI 1 "register_operand" "") 2527 (match_operand:SI 2 "register_operand" ""))) 2528 (set (match_operand:SI 3 "register_operand" "") 2529 (mod:SI (match_dup 1) (match_dup 2))) 2530 (clobber (reg:SI REG_A0)) 2531 (clobber (reg:SI REG_A1)) 2532 (clobber (reg:SI REG_A2)) 2533 (clobber (reg:SI REG_A4)) 2534 (clobber (reg:SI REG_A5)) 2535 (clobber (reg:SI REG_A6)) 2536 (clobber (reg:SI REG_B0)) 2537 (clobber (reg:SI REG_B1)) 2538 (clobber (reg:SI REG_B2)) 2539 (clobber (reg:SI REG_B3)) 2540 (clobber (reg:SI REG_B4)) 2541 (clobber (reg:SI REG_B5)) 2542 (clobber (reg:SI REG_B30)) 2543 (clobber (reg:SI REG_B31))] 2544 "" 2545 "#" 2546 "" 2547 [(const_int 0)] 2548{ 2549 rtx reg = NULL_RTX; 2550 2551 if (TARGET_LONG_CALLS) 2552 { 2553 if (reload_completed) 2554 reg = gen_rtx_REG (SImode, REG_A6); 2555 else 2556 reg = gen_reg_rtx (SImode); 2557 } 2558 emit_move_insn (gen_rtx_REG (SImode, REG_A4), operands[1]); 2559 emit_move_insn (gen_rtx_REG (SImode, REG_B4), operands[2]); 2560 if (find_reg_note (curr_insn, REG_UNUSED, operands[3])) 2561 { 2562 if (TARGET_LONG_CALLS) 2563 { 2564 emit_move_insn (reg, optab_libfunc (sdiv_optab, SImode)); 2565 emit_insn (gen_divsi3_insn_indcall (reg)); 2566 } 2567 else 2568 emit_insn (gen_divsi3_insn ()); 2569 emit_move_insn (operands[0], gen_rtx_REG (SImode, REG_A4)); 2570 } 2571 else if (find_reg_note (curr_insn, REG_UNUSED, operands[0])) 2572 { 2573 if (TARGET_LONG_CALLS) 2574 { 2575 emit_move_insn (reg, optab_libfunc (smod_optab, SImode)); 2576 emit_insn (gen_modsi3_insn_indcall (reg)); 2577 } 2578 else 2579 emit_insn (gen_modsi3_insn ()); 2580 emit_move_insn (operands[3], gen_rtx_REG (SImode, REG_A4)); 2581 } 2582 else 2583 { 2584 if (TARGET_LONG_CALLS) 2585 { 2586 emit_move_insn (reg, optab_libfunc (sdivmod_optab, SImode)); 2587 emit_insn (gen_divmodsi4_insn_indcall (reg)); 2588 } 2589 else 2590 emit_insn (gen_divmodsi4_insn ()); 2591 emit_move_insn (operands[0], gen_rtx_REG (SImode, REG_A4)); 2592 emit_move_insn (operands[3], gen_rtx_REG (SImode, REG_A5)); 2593 } 2594 DONE; 2595}) 2596 2597(define_insn_and_split "udivmodsi4" 2598 [(set (match_operand:SI 0 "register_operand" "") 2599 (udiv:SI (match_operand:SI 1 "register_operand" "") 2600 (match_operand:SI 2 "register_operand" ""))) 2601 (set (match_operand:SI 3 "register_operand" "") 2602 (umod:SI (match_dup 1) (match_dup 2))) 2603 (clobber (reg:SI REG_A0)) 2604 (clobber (reg:SI REG_A1)) 2605 (clobber (reg:SI REG_A2)) 2606 (clobber (reg:SI REG_A4)) 2607 (clobber (reg:SI REG_A5)) 2608 (clobber (reg:SI REG_A6)) 2609 (clobber (reg:SI REG_A7)) 2610 (clobber (reg:SI REG_B0)) 2611 (clobber (reg:SI REG_B1)) 2612 (clobber (reg:SI REG_B2)) 2613 (clobber (reg:SI REG_B3)) 2614 (clobber (reg:SI REG_B4)) 2615 (clobber (reg:SI REG_B30)) 2616 (clobber (reg:SI REG_B31))] 2617 "" 2618 "#" 2619 "" 2620 [(const_int 0)] 2621{ 2622 rtx reg = NULL_RTX; 2623 2624 if (TARGET_LONG_CALLS) 2625 { 2626 if (reload_completed) 2627 reg = gen_rtx_REG (SImode, REG_A6); 2628 else 2629 reg = gen_reg_rtx (SImode); 2630 } 2631 2632 emit_move_insn (gen_rtx_REG (SImode, REG_A4), operands[1]); 2633 emit_move_insn (gen_rtx_REG (SImode, REG_B4), operands[2]); 2634 if (find_reg_note (curr_insn, REG_UNUSED, operands[3])) 2635 { 2636 if (TARGET_LONG_CALLS) 2637 { 2638 emit_move_insn (reg, optab_libfunc (udiv_optab, SImode)); 2639 emit_insn (gen_udivsi3_insn_indcall (reg)); 2640 } 2641 else 2642 emit_insn (gen_udivsi3_insn ()); 2643 emit_move_insn (operands[0], gen_rtx_REG (SImode, REG_A4)); 2644 } 2645 else if (find_reg_note (curr_insn, REG_UNUSED, operands[0])) 2646 { 2647 if (TARGET_LONG_CALLS) 2648 { 2649 emit_move_insn (reg, optab_libfunc (umod_optab, SImode)); 2650 emit_insn (gen_umodsi3_insn_indcall (reg)); 2651 } 2652 else 2653 emit_insn (gen_umodsi3_insn ()); 2654 emit_move_insn (operands[3], gen_rtx_REG (SImode, REG_A4)); 2655 } 2656 else 2657 { 2658 if (TARGET_LONG_CALLS) 2659 { 2660 emit_move_insn (reg, optab_libfunc (udivmod_optab, SImode)); 2661 emit_insn (gen_udivmodsi4_insn_indcall (reg)); 2662 } 2663 else 2664 emit_insn (gen_udivmodsi4_insn ()); 2665 emit_move_insn (operands[0], gen_rtx_REG (SImode, REG_A4)); 2666 emit_move_insn (operands[3], gen_rtx_REG (SImode, REG_A5)); 2667 } 2668 DONE; 2669}) 2670 2671;; ------------------------------------------------------------------------- 2672;; Multiplication 2673;; See c6x-mult.md.in for define_insn patterns. 2674;; ------------------------------------------------------------------------- 2675 2676(define_expand "mulhisi3" 2677 [(set (match_operand:SI 0 "register_operand" "") 2678 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "")) 2679 (sign_extend:SI (match_operand:HI 2 "reg_or_scst5_operand" ""))))] 2680 "" 2681{ 2682 if (CONSTANT_P (operands[2])) 2683 { 2684 emit_insn (gen_mulhisi3_const (operands[0], operands[1], operands[2])); 2685 DONE; 2686 } 2687}) 2688 2689(define_expand "usmulhisi3" 2690 [(set (match_operand:SI 0 "register_operand" "") 2691 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "")) 2692 (sign_extend:SI (match_operand:HI 2 "reg_or_scst5_operand" ""))))] 2693 "" 2694{ 2695 if (CONSTANT_P (operands[2])) 2696 { 2697 emit_insn (gen_usmulhisi3_const (operands[0], operands[1], operands[2])); 2698 DONE; 2699 } 2700}) 2701 2702(define_expand "mulsi3" 2703 [(set (match_operand:SI 0 "register_operand" "") 2704 (mult:SI (match_operand:SI 1 "register_operand" "") 2705 (match_operand:SI 2 "register_operand" "")))] 2706 "" 2707{ 2708 if (!TARGET_MPY32) 2709 { 2710 rtx lo1 = gen_lowpart (HImode, operands[1]); 2711 rtx lo2 = gen_lowpart (HImode, operands[2]); 2712 /* (N * AH + AL) * (N * BH + BL) 2713 = N*(AH * BL + BH * AL) + AL*BL */ 2714 rtx tmp1 = gen_reg_rtx (SImode); 2715 rtx tmp2 = gen_reg_rtx (SImode); 2716 rtx tmp3 = gen_reg_rtx (SImode); 2717 emit_insn (gen_umulhisi3 (tmp1, lo1, lo2)); 2718 emit_insn (gen_umulhisi3_lh (tmp2, lo1, operands[2])); 2719 emit_insn (gen_umulhisi3_hl (tmp3, operands[1], lo2)); 2720 emit_insn (gen_addsi3 (tmp2, tmp2, tmp3)); 2721 emit_insn (gen_ashlsi3 (tmp2, tmp2, GEN_INT (16))); 2722 emit_insn (gen_addsi3 (operands[0], tmp1, tmp2)); 2723 DONE; 2724 } 2725}) 2726 2727;; ------------------------------------------------------------------------- 2728;; Floating point multiplication 2729;; ------------------------------------------------------------------------- 2730 2731(define_insn "mulsf3" 2732 [(set (match_operand:SF 0 "register_operand" "=a,b,a,b") 2733 (mult:SF (match_operand:SF 1 "register_operand" "%a,b,?a,?b") 2734 (match_operand:SF 2 "register_operand" "a,b,b,a")))] 2735 "TARGET_FP" 2736 "%|%.\\tmpysp\\t%$\\t%1, %2, %0" 2737 [(set_attr "type" "mpy4") 2738 (set_attr "units" "m") 2739 (set_attr "cross" "n,n,y,y")]) 2740 2741(define_insn "muldf3" 2742 [(set (match_operand:DF 0 "register_operand" "=a,b") 2743 (mult:DF (match_operand:DF 1 "register_operand" "%a,b") 2744 (match_operand:DF 2 "register_operand" "a,b")))] 2745 "TARGET_FP" 2746 "%|%.\\tmpydp\\t%$\\t%1, %2, %0" 2747 [(set_attr "type" "mpydp") 2748 (set_attr "units" "m") 2749 (set_attr "cross" "n")]) 2750 2751;; Note that mpyspdp and mpysp2dp are available on C67x, despite what the 2752;; manual says. 2753(define_insn "*muldf_ext1" 2754 [(set (match_operand:DF 0 "register_operand" "=a,b,a,b") 2755 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "a,b,a,b")) 2756 (match_operand:DF 2 "register_operand" "a,b,?b,?a")))] 2757 "TARGET_FP_EXT" 2758 "%|%.\\tmpyspdp\\t%$\\t%1, %2, %0" 2759 [(set_attr "type" "mpyspdp") 2760 (set_attr "units" "m") 2761 (set_attr "cross" "n,n,y,y")]) 2762 2763(define_insn "*muldf_ext2" 2764 [(set (match_operand:DF 0 "register_operand" "=a,b,a,b") 2765 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "%a,b,a,b")) 2766 (float_extend:DF (match_operand:SF 2 "register_operand" "a,b,?b,?a"))))] 2767 "TARGET_FP_EXT" 2768 "%|%.\\tmpysp2dp\\t%$\\t%1, %2, %0" 2769 [(set_attr "type" "mpysp2dp") 2770 (set_attr "units" "m") 2771 (set_attr "cross" "n,n,y,y")]) 2772 2773;; ------------------------------------------------------------------------- 2774;; Floating point division 2775;; ------------------------------------------------------------------------- 2776 2777(define_insn "rcpsf2" 2778 [(set (match_operand:SF 0 "register_operand" "=a,b,a,b") 2779 (unspec:SF [(match_operand:SF 1 "register_operand" "a,b,?b,?a")] 2780 UNSPEC_RCP))] 2781 "TARGET_FP" 2782 "%|%.\\trcpsp\\t%$\\t%1, %0" 2783 [(set_attr "units" "s") 2784 (set_attr "cross" "n,n,y,y")]) 2785 2786(define_insn "rcpdf2" 2787 [(set (match_operand:DF 0 "register_operand" "=a,b") 2788 (unspec:DF [(match_operand:DF 1 "register_operand" "a,b")] 2789 UNSPEC_RCP))] 2790 "TARGET_FP" 2791 "%|%.\\trcpdp\\t%$\\t%1, %0" 2792 [(set_attr "type" "dp2") 2793 (set_attr "units" "s") 2794 (set_attr "cross" "n")]) 2795 2796(define_expand "divsf3" 2797 [(set (match_dup 4) 2798 (unspec:SF [(match_operand:SF 2 "register_operand" "")] 2799 UNSPEC_RCP)) 2800 (set (match_dup 5) (mult:SF (match_dup 2) (match_dup 4))) 2801 (set (match_dup 6) (minus:SF (match_dup 3) (match_dup 5))) 2802 (set (match_dup 4) (mult:SF (match_dup 4) (match_dup 6))) 2803 (set (match_dup 5) (mult:SF (match_dup 2) (match_dup 4))) 2804 (set (match_dup 6) (minus:SF (match_dup 3) (match_dup 5))) 2805 (set (match_dup 4) (mult:SF (match_dup 4) (match_dup 6))) 2806 (set (match_operand:SF 0 "register_operand" "") 2807 (mult:SF (match_operand:SF 1 "register_operand") 2808 (match_dup 4)))] 2809 "TARGET_FP && flag_reciprocal_math" 2810{ 2811 operands[3] = force_reg (SFmode, 2812 const_double_from_real_value (dconst2, SFmode)); 2813 operands[4] = gen_reg_rtx (SFmode); 2814 operands[5] = gen_reg_rtx (SFmode); 2815 operands[6] = gen_reg_rtx (SFmode); 2816}) 2817 2818(define_expand "divdf3" 2819 [(set (match_dup 4) 2820 (unspec:DF [(match_operand:DF 2 "register_operand" "")] 2821 UNSPEC_RCP)) 2822 (set (match_dup 5) (mult:DF (match_dup 2) (match_dup 4))) 2823 (set (match_dup 6) (minus:DF (match_dup 3) (match_dup 5))) 2824 (set (match_dup 4) (mult:DF (match_dup 4) (match_dup 6))) 2825 (set (match_dup 5) (mult:DF (match_dup 2) (match_dup 4))) 2826 (set (match_dup 6) (minus:DF (match_dup 3) (match_dup 5))) 2827 (set (match_dup 4) (mult:DF (match_dup 4) (match_dup 6))) 2828 (set (match_dup 5) (mult:DF (match_dup 2) (match_dup 4))) 2829 (set (match_dup 6) (minus:DF (match_dup 3) (match_dup 5))) 2830 (set (match_dup 4) (mult:DF (match_dup 4) (match_dup 6))) 2831 (set (match_operand:DF 0 "register_operand" "") 2832 (mult:DF (match_operand:DF 1 "register_operand") 2833 (match_dup 4)))] 2834 "TARGET_FP && flag_reciprocal_math" 2835{ 2836 operands[3] = force_reg (DFmode, 2837 const_double_from_real_value (dconst2, DFmode)); 2838 operands[4] = gen_reg_rtx (DFmode); 2839 operands[5] = gen_reg_rtx (DFmode); 2840 operands[6] = gen_reg_rtx (DFmode); 2841}) 2842 2843;; ------------------------------------------------------------------------- 2844;; Block moves 2845;; ------------------------------------------------------------------------- 2846 2847(define_expand "cpymemsi" 2848 [(use (match_operand:BLK 0 "memory_operand" "")) 2849 (use (match_operand:BLK 1 "memory_operand" "")) 2850 (use (match_operand:SI 2 "nonmemory_operand" "")) 2851 (use (match_operand:SI 3 "const_int_operand" "")) 2852 (use (match_operand:SI 4 "const_int_operand" "")) 2853 (use (match_operand:SI 5 "const_int_operand" ""))] 2854 "" 2855{ 2856 if (c6x_expand_cpymem (operands[0], operands[1], operands[2], operands[3], 2857 operands[4], operands[5])) 2858 DONE; 2859 else 2860 FAIL; 2861}) 2862 2863;; ------------------------------------------------------------------------- 2864;; Prologue and epilogue. 2865;; ------------------------------------------------------------------------- 2866 2867;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and 2868;; all of memory. This blocks insns from being moved across this point. 2869 2870(define_insn "blockage" 2871 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)] 2872 "" 2873 "" 2874 [(set_attr "type" "blockage")]) 2875 2876(define_insn "push_rts" 2877 [(set (mem:SI (reg:SI REG_SP)) (reg:SI REG_B14)) 2878 (set (mem:DI (plus:SI (reg:SI REG_SP) (const_int -8))) (reg:DI REG_A14)) 2879 (set (mem:DI (plus:SI (reg:SI REG_SP) (const_int -16))) (reg:DI REG_B12)) 2880 (set (mem:DI (plus:SI (reg:SI REG_SP) (const_int -24))) (reg:DI REG_A12)) 2881 (set (mem:DI (plus:SI (reg:SI REG_SP) (const_int -32))) (reg:DI REG_B10)) 2882 (set (mem:DI (plus:SI (reg:SI REG_SP) (const_int -40))) (reg:DI REG_A10)) 2883 (set (mem:DI (plus:SI (reg:SI REG_SP) (const_int -48))) (reg:DI REG_B2)) 2884 (set (reg:SI REG_SP) (plus:SI (reg:SI REG_SP) (const_int -56))) 2885 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 2886 (clobber (reg:SI REG_A3))] 2887 "TARGET_INSNS_64PLUS" 2888 "%|%.\\tcallp\\t%$\\t__c6xabi_push_rts, a3" 2889 [(set_attr "type" "callp") 2890 (set_attr "dest_regfile" "a") 2891 (set_attr "units" "s") 2892 (set_attr "cross" "n")]) 2893 2894(define_insn "pop_rts" 2895 [(set (reg:SI REG_B14) (mem:SI (plus:SI (reg:SI REG_SP) (const_int 56)))) 2896 (set (reg:DI REG_A14) (mem:DI (plus:SI (reg:SI REG_SP) (const_int 48)))) 2897 (set (reg:DI REG_B12) (mem:DI (plus:SI (reg:SI REG_SP) (const_int 40)))) 2898 (set (reg:DI REG_A12) (mem:DI (plus:SI (reg:SI REG_SP) (const_int 32)))) 2899 (set (reg:DI REG_B10) (mem:DI (plus:SI (reg:SI REG_SP) (const_int 24)))) 2900 (set (reg:DI REG_A10) (mem:DI (plus:SI (reg:SI REG_SP) (const_int 16)))) 2901 (set (reg:DI REG_B2) (mem:DI (plus:SI (reg:SI REG_SP) (const_int 8)))) 2902 (set (reg:SI REG_SP) (plus:SI (reg:SI REG_SP) (const_int 56))) 2903 (clobber (reg:SI REG_A3)) 2904 (return)] 2905 "TARGET_INSNS_64PLUS" 2906 "%|%.\\tretp\\t%$\\t__c6xabi_pop_rts, a3" 2907 [(set_attr "type" "callp") 2908 (set_attr "dest_regfile" "a") 2909 (set_attr "units" "s") 2910 (set_attr "cross" "n")]) 2911 2912(define_expand "prologue" 2913 [(const_int 1)] 2914 "" 2915 "c6x_expand_prologue (); DONE;") 2916 2917(define_expand "epilogue" 2918 [(const_int 1)] 2919 "" 2920 "c6x_expand_epilogue (false); DONE;") 2921 2922(define_expand "sibcall_epilogue" 2923 [(return)] 2924 "" 2925{ 2926 c6x_expand_epilogue (true); 2927 DONE; 2928}) 2929 2930(define_insn "setup_dsbt" 2931 [(set (match_operand:SI 0 "pic_register_operand" "+Z") 2932 (unspec:SI [(match_dup 0) 2933 (match_operand:SI 1 "symbolic_operand" "")] 2934 UNSPEC_SETUP_DSBT))] 2935 "TARGET_DSBT" 2936 "%|%.\\tldw\\t%$\\t*+%0($DSBT_index%1), %0" 2937 [(set_attr "type" "load") 2938 (set_attr "units" "d_addr") 2939 (set_attr "dest_regfile" "b") 2940 (set_attr "addr_regfile" "b")]) 2941 2942 2943;; A dummy use/set to prevent prologue and epiloge overlapping. 2944;; This can be caused by sched-ebb in the presence of multiple 2945;; exit sequences, and causes the unwinding table generation to explode. 2946(define_insn "epilogue_barrier" 2947 [(set (match_operand:SI 0 "register_operand" "") 2948 (unspec:SI [(match_operand:SI 1 "register_operand" "")] 2949 UNSPEC_EPILOGUE_BARRIER))] 2950 "" 2951 "" 2952 [(set_attr "type" "blockage")]) 2953 2954;; ------------------------------------------------------------------------- 2955;; Vector insns 2956;; ------------------------------------------------------------------------- 2957 2958(define_code_iterator logical [and ior xor]) 2959(define_code_attr logical_insn [(and "and") (ior "ior") (xor "xor")]) 2960(define_code_attr logical_opcode [(and "and") (ior "or") (xor "xor")]) 2961(define_code_iterator plusminus [plus minus]) 2962(define_code_attr plusminus_insn [(plus "add") (minus "sub")]) 2963(define_code_iterator ss_plusminus [ss_plus ss_minus]) 2964(define_code_attr ss_plusminus_insn [(ss_plus "add") (ss_minus "sub")]) 2965 2966;; Vector logical insns 2967 2968(define_insn "<logical_insn><mode>3" 2969 [(set (match_operand:VEC4M 0 "register_operand" "=a,b,a,b") 2970 (logical:VEC4M (match_operand:VEC4M 1 "register_operand" "a,b,a,b") 2971 (match_operand:VEC4M 2 "register_operand" "a,b,?b,?a")))] 2972 "" 2973 "%|%.\\t<logical_opcode>\\t%$\\t%1, %2, %0" 2974 [(set_attr "units62" "ls") 2975 (set_attr "units64" "dls") 2976 (set_attr "cross" "n,n,y,y")]) 2977 2978;; Vector add/subtract 2979 2980(define_insn "<plusminus_insn>v2hi3" 2981 [(set (match_operand:V2HI 0 "register_operand" "=a,b,a,b") 2982 (plusminus:V2HI (match_operand:V2HI 1 "register_operand" "a,b,a,b") 2983 (match_operand:V2HI 2 "register_operand" "a,b,?b,?a")))] 2984 "" 2985 "%|%.\\t<plusminus_insn>2\\t%$\\t%1, %2, %0" 2986 [(set_attr "units62" "l") 2987 (set_attr "units64" "dls") 2988 (set_attr "cross" "n,n,y,y")]) 2989 2990(define_insn "<plusminus_insn>v4qi3" 2991 [(set (match_operand:V4QI 0 "register_operand" "=a,b,a,b") 2992 (plusminus:V4QI (match_operand:V4QI 1 "register_operand" "a,b,a,b") 2993 (match_operand:V4QI 2 "register_operand" "a,b,?b,?a")))] 2994 "TARGET_INSNS_64" 2995 "%|%.\\t<plusminus_insn>4\\t%$\\t%1, %2, %0" 2996 [(set_attr "units" "l") 2997 (set_attr "cross" "n,n,y,y")]) 2998 2999(define_insn "ss_addv2hi3" 3000 [(set (match_operand:V2HI 0 "register_operand" "=a,b,a,b") 3001 (ss_plus:V2HI (match_operand:V2HI 1 "register_operand" "a,b,a,b") 3002 (match_operand:V2HI 2 "register_operand" "a,b,?b,?a")))] 3003 "TARGET_INSNS_64" 3004 "%|%.\\tsadd2\\t%$\\t%1, %2, %0" 3005 [(set_attr "units" "s") 3006 (set_attr "cross" "n,n,y,y")]) 3007 3008(define_insn "ss_subv2hi3" 3009 [(set (match_operand:V2HI 0 "register_operand" "=a,b,a,b") 3010 (ss_minus:V2HI (match_operand:V2HI 1 "register_operand" "a,b,a,b") 3011 (match_operand:V2HI 2 "register_operand" "a,b,?b,?a")))] 3012 "TARGET_INSNS_64" 3013 "%|%.\\tssub2\\t%$\\t%1, %2, %0" 3014 [(set_attr "units" "l") 3015 (set_attr "cross" "n,n,y,y")]) 3016 3017(define_insn "us_addv4qi3" 3018 [(set (match_operand:V4QI 0 "register_operand" "=a,b,a,b") 3019 (ss_plus:V4QI (match_operand:V4QI 1 "register_operand" "a,b,a,b") 3020 (match_operand:V4QI 2 "register_operand" "a,b,?b,?a")))] 3021 "TARGET_INSNS_64" 3022 "%|%.\\tsaddu4\\t%$\\t%1, %2, %0" 3023 [(set_attr "units" "s") 3024 (set_attr "cross" "n,n,y,y")]) 3025 3026;; Vector/scalar min/max 3027 3028(define_mode_iterator SMINMAX [HI V2HI]) 3029(define_mode_iterator UMINMAX [QI V4QI]) 3030 3031(define_insn "smax<mode>3" 3032 [(set (match_operand:SMINMAX 0 "register_operand" "=a,b,a,b") 3033 (smax:SMINMAX (match_operand:SMINMAX 1 "register_operand" "a,b,a,b") 3034 (match_operand:SMINMAX 2 "register_operand" "a,b,?b,?a")))] 3035 "TARGET_INSNS_64" 3036 "%|%.\\tmax2\\t%$\\t%1, %2, %0" 3037 [(set_attr "units64" "l") 3038 (set_attr "units64p" "ls") 3039 (set_attr "cross" "n,n,y,y")]) 3040 3041(define_insn "smin<mode>3" 3042 [(set (match_operand:SMINMAX 0 "register_operand" "=a,b,a,b") 3043 (smin:SMINMAX (match_operand:SMINMAX 1 "register_operand" "a,b,a,b") 3044 (match_operand:SMINMAX 2 "register_operand" "a,b,?b,?a")))] 3045 "TARGET_INSNS_64" 3046 "%|%.\\tmin2\\t%$\\t%1, %2, %0" 3047 [(set_attr "units64" "l") 3048 (set_attr "units64p" "ls") 3049 (set_attr "cross" "n,n,y,y")]) 3050 3051(define_insn "umax<mode>3" 3052 [(set (match_operand:UMINMAX 0 "register_operand" "=a,b,a,b") 3053 (umax:UMINMAX (match_operand:UMINMAX 1 "register_operand" "a,b,a,b") 3054 (match_operand:UMINMAX 2 "register_operand" "a,b,?b,?a")))] 3055 "TARGET_INSNS_64" 3056 "%|%.\\tmaxu4\\t%$\\t%1, %2, %0" 3057 [(set_attr "units" "l") 3058 (set_attr "cross" "n,n,y,y")]) 3059 3060(define_insn "umin<mode>3" 3061 [(set (match_operand:UMINMAX 0 "register_operand" "=a,b,a,b") 3062 (umin:UMINMAX (match_operand:UMINMAX 1 "register_operand" "a,b,a,b") 3063 (match_operand:UMINMAX 2 "register_operand" "a,b,?b,?a")))] 3064 "TARGET_INSNS_64" 3065 "%|%.\\tminu4\\t%$\\t%1, %2, %0" 3066 [(set_attr "units" "l") 3067 (set_attr "cross" "n,n,y,y")]) 3068 3069;; Vector shifts 3070 3071(define_insn "<shift_code>v2hi3" 3072 [(set (match_operand:V2HI 0 "register_operand" "=a,b,a,b") 3073 (any_rshift:V2HI (match_operand:V2HI 1 "register_operand" "a,b,?b,?a") 3074 (match_operand:SI 2 "reg_or_ucst5_operand" "aIu5,bIu5,aIu5,bIu5")))] 3075 "TARGET_INSNS_64" 3076 "%|%.\\t<shift_insn>2\\t%$\\t%1, %2, %0" 3077 [(set_attr "units" "s") 3078 (set_attr "cross" "n,n,y,y")]) 3079 3080;; See c6x-mult.md.in for avg2/avgu4 3081 3082;; Widening vector multiply and dot product. 3083;; See c6x-mult.md.in for the define_insn patterns 3084 3085(define_expand "sdot_prodv2hi" 3086 [(match_operand:SI 0 "register_operand" "") 3087 (match_operand:V2HI 1 "register_operand" "") 3088 (match_operand:V2HI 2 "register_operand" "") 3089 (match_operand:SI 3 "register_operand" "")] 3090 "TARGET_INSNS_64" 3091{ 3092 rtx t = gen_reg_rtx (SImode); 3093 emit_insn (gen_dotv2hi (t, operands[1], operands[2])); 3094 emit_insn (gen_addsi3 (operands[0], operands[3], t)); 3095 DONE; 3096}) 3097 3098;; Unary vector operations 3099 3100(define_insn "ssabsv2hi2" 3101 [(set (match_operand:V2HI 0 "register_operand" "=a, a, b, b") 3102 (ss_abs:V2HI (match_operand:V2HI 1 "register_operand" "a,?b, b,?a")))] 3103 "TARGET_INSNS_64" 3104 "%|%.\\tabs2\\t%$\\t%1, %0" 3105 [(set_attr "units" "l") 3106 (set_attr "cross" "n,y,n,y")]) 3107 3108;; Pack insns 3109 3110(define_insn "*packv2hi_insv" 3111 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+a,b,a,b,ab") 3112 (const_int 16) 3113 (const_int 16)) 3114 (match_operand:SI 1 "nonmemory_operand" "a,b,?b,?a,n"))] 3115 "TARGET_INSNS_64" 3116 "@ 3117 %|%.\\tpack2\\t%$\\t%1, %0, %0 3118 %|%.\\tpack2\\t%$\\t%1, %0, %0 3119 %|%.\\tpack2\\t%$\\t%1, %0, %0 3120 %|%.\\tpack2\\t%$\\t%1, %0, %0 3121 %|%.\\tmvklh\\t%$\\t%1, %0" 3122 [(set_attr "units" "ls") 3123 (set_attr "cross" "n,n,y,y,n")]) 3124 3125(define_insn "movstricthi" 3126 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+a,b,a,b")) 3127 (match_operand:HI 1 "register_operand" "a,b,?b,?a"))] 3128 "TARGET_INSNS_64" 3129 "%|%.\\tpackhl2\\t%$\\t%0, %1, %0" 3130 [(set_attr "units" "ls") 3131 (set_attr "cross" "n,n,y,y")]) 3132 3133(include "c6x-mult.md") 3134(include "sync.md") 3135