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