1;; Copyright (C) 2006-2019 Free Software Foundation, Inc. 2 3;; This file is free software; you can redistribute it and/or modify it under 4;; the terms of the GNU General Public License as published by the Free 5;; Software Foundation; either version 3 of the License, or (at your option) 6;; any later version. 7 8;; This file is distributed in the hope that it will be useful, but WITHOUT 9;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11;; for more details. 12 13;; You should have received a copy of the GNU General Public License 14;; along with GCC; see the file COPYING3. If not see 15;; <http://www.gnu.org/licenses/>. 16 17 18;; This includes expands for all the intrinsics. 19;; spu_expand_builtin looks at the mode of match_operand. 20 21 22;; load/store 23 24(define_expand "spu_lqd" 25 [(set (match_operand:TI 0 "spu_reg_operand" "") 26 (mem:TI (and:SI (plus:SI (match_operand:SI 1 "spu_reg_operand" "") 27 (match_operand:SI 2 "spu_nonmem_operand" "")) 28 (const_int -16))))] 29 "" 30 { 31 if (GET_CODE (operands[2]) == CONST_INT 32 && (INTVAL (operands[2]) & 15) != 0) 33 operands[2] = GEN_INT (INTVAL (operands[2]) & -16); 34 if (GET_CODE (operands[2]) != CONST_INT) 35 { 36 rtx op2 = operands[2]; 37 operands[2] = force_reg (Pmode, operands[2]); 38 if (!ALIGNED_SYMBOL_REF_P (op2)) 39 emit_insn (gen_andsi3 (operands[2], operands[2], GEN_INT (-16))); 40 } 41 }) 42 43(define_expand "spu_lqx" 44 [(set (match_operand:TI 0 "spu_reg_operand" "") 45 (mem:TI (and:SI (plus:SI (match_operand:SI 1 "spu_reg_operand" "") 46 (match_operand:SI 2 "spu_reg_operand" "")) 47 (const_int -16))))] 48 "" 49 "") 50 51(define_expand "spu_lqa" 52 [(set (match_operand:TI 0 "spu_reg_operand" "") 53 (mem:TI (and:SI (match_operand:SI 1 "immediate_operand" "") 54 (const_int -16))))] 55 "" 56 { 57 if (GET_CODE (operands[1]) == CONST_INT 58 && (INTVAL (operands[1]) & 15) != 0) 59 operands[1] = GEN_INT (INTVAL (operands[1]) & -16); 60 }) 61 62(define_expand "spu_lqr" 63 [(set (match_operand:TI 0 "spu_reg_operand" "") 64 (mem:TI (and:SI (match_operand:SI 1 "address_operand" "") 65 (const_int -16))))] 66 "" 67 "") 68 69(define_expand "spu_stqd" 70 [(set (mem:TI (and:SI (plus:SI (match_operand:SI 1 "spu_reg_operand" "") 71 (match_operand:SI 2 "spu_nonmem_operand" "")) 72 (const_int -16))) 73 (match_operand:TI 0 "spu_reg_operand" "r,r"))] 74 "" 75 { 76 if (GET_CODE (operands[2]) == CONST_INT 77 && (INTVAL (operands[2]) & 15) != 0) 78 operands[2] = GEN_INT (INTVAL (operands[2]) & -16); 79 if (GET_CODE (operands[2]) != CONST_INT) 80 { 81 rtx op2 = operands[2]; 82 operands[2] = force_reg (Pmode, operands[2]); 83 if (!ALIGNED_SYMBOL_REF_P (op2)) 84 emit_insn (gen_andsi3 (operands[2], operands[2], GEN_INT (-16))); 85 } 86 }) 87 88(define_expand "spu_stqx" 89 [(set (mem:TI (and:SI (plus:SI (match_operand:SI 1 "spu_reg_operand" "") 90 (match_operand:SI 2 "spu_reg_operand" "")) 91 (const_int -16))) 92 (match_operand:TI 0 "spu_reg_operand" "r"))] 93 "" 94 "") 95 96(define_expand "spu_stqa" 97 [(set (mem:TI (and:SI (match_operand:SI 1 "immediate_operand" "") 98 (const_int -16))) 99 (match_operand:TI 0 "spu_reg_operand" "r"))] 100 "" 101 { 102 if (GET_CODE (operands[1]) == CONST_INT 103 && (INTVAL (operands[1]) & 15) != 0) 104 operands[1] = GEN_INT (INTVAL (operands[1]) & -16); 105 }) 106 107(define_expand "spu_stqr" 108 [(set (mem:TI (and:SI (match_operand:SI 1 "address_operand" "") 109 (const_int -16))) 110 (match_operand:TI 0 "spu_reg_operand" ""))] 111 "" 112 "") 113 114 115;; generate control word 116 117(define_expand "spu_cbx" 118 [(set (match_operand:TI 0 "spu_reg_operand" "") 119 (unspec:TI [(match_operand:SI 1 "spu_reg_operand" "") 120 (match_operand:SI 2 "spu_nonmem_operand" "") 121 (const_int 1)] UNSPEC_CPAT))] 122 "" 123 "") 124 125(define_expand "spu_chx" 126 [(set (match_operand:TI 0 "spu_reg_operand" "") 127 (unspec:TI [(match_operand:SI 1 "spu_reg_operand" "") 128 (match_operand:SI 2 "spu_nonmem_operand" "") 129 (const_int 2)] UNSPEC_CPAT))] 130 "" 131 "") 132 133(define_expand "spu_cwx" 134 [(set (match_operand:TI 0 "spu_reg_operand" "") 135 (unspec:TI [(match_operand:SI 1 "spu_reg_operand" "") 136 (match_operand:SI 2 "spu_nonmem_operand" "") 137 (const_int 4)] UNSPEC_CPAT))] 138 "" 139 "") 140 141(define_expand "spu_cdx" 142 [(set (match_operand:TI 0 "spu_reg_operand" "") 143 (unspec:TI [(match_operand:SI 1 "spu_reg_operand" "") 144 (match_operand:SI 2 "spu_nonmem_operand" "") 145 (const_int 8)] UNSPEC_CPAT))] 146 "" 147 "") 148 149 150 151;; Constant formation 152 153(define_expand "spu_ilhu" 154 [(set (match_operand:V4SI 0 "spu_reg_operand" "") 155 (const_vector:V4SI [(match_operand:SI 1 "immediate_operand" "")]))] 156 "" 157 "{ emit_insn(gen_movv4si(operands[0], spu_const(V4SImode, (INTVAL(operands[1]) << 16)))); 158 DONE; 159 }") 160 161 162;; integer subtract 163(define_expand "spu_sfh" 164 [(set (match_operand:V8HI 0 "spu_reg_operand" "") 165 (minus:V8HI (match_operand:V8HI 2 "spu_nonmem_operand" "") 166 (match_operand:V8HI 1 "spu_reg_operand" "")))] 167 "" 168 "") 169 170(define_expand "spu_sf" 171 [(set (match_operand:V4SI 0 "spu_reg_operand" "") 172 (minus:V4SI (match_operand:V4SI 2 "spu_nonmem_operand" "") 173 (match_operand:V4SI 1 "spu_reg_operand" "")))] 174 "" 175 "") 176 177(define_expand "spu_sfx" 178 [(set (match_operand:V4SI 0 "spu_reg_operand" "") 179 (unspec:V4SI [(match_operand:V4SI 2 "spu_reg_operand" "") 180 (match_operand:V4SI 1 "spu_reg_operand" "") 181 (match_operand:V4SI 3 "spu_reg_operand" "")] UNSPEC_SFX))] 182 "" 183 "") 184 185(define_expand "spu_bg" 186 [(set (match_operand:V4SI 0 "spu_reg_operand" "") 187 (unspec:V4SI [(match_operand:V4SI 2 "spu_reg_operand" "") 188 (match_operand:V4SI 1 "spu_reg_operand" "")] UNSPEC_BG))] 189 "" 190 "") 191 192(define_expand "spu_bgx" 193 [(set (match_operand:V4SI 0 "spu_reg_operand" "") 194 (unspec:V4SI [(match_operand:V4SI 2 "spu_reg_operand" "") 195 (match_operand:V4SI 1 "spu_reg_operand" "") 196 (match_operand:V4SI 3 "spu_reg_operand" "")] UNSPEC_BGX))] 197 "" 198 "") 199 200(define_insn "spu_mpya" 201 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") 202 (plus:V4SI 203 (mult:V4SI 204 (sign_extend:V4SI 205 (vec_select:V4HI 206 (match_operand:V8HI 1 "spu_reg_operand" "r") 207 (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)]))) 208 (sign_extend:V4SI 209 (vec_select:V4HI 210 (match_operand:V8HI 2 "spu_reg_operand" "r") 211 (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)])))) 212 (match_operand:V4SI 3 "spu_reg_operand" "r")))] 213 "" 214 "mpya\t%0,%1,%2,%3" 215 [(set_attr "type" "fp7")]) 216 217(define_insn "spu_mpyh" 218 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") 219 (ashift:V4SI 220 (mult:V4SI 221 (sign_extend:V4SI 222 (vec_select:V4HI 223 (match_operand:V8HI 1 "spu_reg_operand" "r") 224 (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)]))) 225 (sign_extend:V4SI 226 (vec_select:V4HI 227 (match_operand:V8HI 2 "spu_reg_operand" "r") 228 (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)])))) 229 (const_vector:V4SI [(const_int 16)(const_int 16)(const_int 16)(const_int 16)])))] 230 "" 231 "mpyh\t%0,%1,%2" 232 [(set_attr "type" "fp7")]) 233 234(define_insn "spu_mpys" 235 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") 236 (ashiftrt:V4SI 237 (mult:V4SI 238 (sign_extend:V4SI 239 (vec_select:V4HI 240 (match_operand:V8HI 1 "spu_reg_operand" "r") 241 (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)]))) 242 (sign_extend:V4SI 243 (vec_select:V4HI 244 (match_operand:V8HI 2 "spu_reg_operand" "r") 245 (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)])))) 246 (const_vector:V4SI [(const_int 16)(const_int 16)(const_int 16)(const_int 16)])))] 247 "" 248 "mpys\t%0,%1,%2" 249 [(set_attr "type" "fp7")]) 250 251(define_insn "spu_mpyhhau" 252 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") 253 (plus:V4SI 254 (mult:V4SI 255 (zero_extend:V4SI 256 (vec_select:V4HI 257 (match_operand:V8HI 1 "spu_reg_operand" "r") 258 (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)]))) 259 (zero_extend:V4SI 260 (vec_select:V4HI 261 (match_operand:V8HI 2 "spu_reg_operand" "r") 262 (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)])))) 263 (match_operand:V4SI 3 "spu_reg_operand" "0")))] 264 "" 265 "mpyhhau\t%0,%1,%2" 266 [(set_attr "type" "fp7")]) 267 268(define_insn "spu_mpyhha" 269 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") 270 (plus:V4SI 271 (mult:V4SI 272 (sign_extend:V4SI 273 (vec_select:V4HI 274 (match_operand:V8HI 1 "spu_reg_operand" "r") 275 (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)]))) 276 (sign_extend:V4SI 277 (vec_select:V4HI 278 (match_operand:V8HI 2 "spu_reg_operand" "r") 279 (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)])))) 280 (match_operand:V4SI 3 "spu_reg_operand" "0")))] 281 "" 282 "mpyhha\t%0,%1,%2" 283 [(set_attr "type" "fp7")]) 284 285;; form select mask 286(define_insn "spu_fsmb" 287 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r,r") 288 (unspec:V16QI [(match_operand:SI 1 "spu_nonmem_operand" "r,MN")] UNSPEC_FSMB))] 289 "" 290 "@ 291 fsmb\t%0,%1 292 fsmbi\t%0,%1" 293 [(set_attr "type" "shuf")]) 294 295(define_insn "spu_fsmh" 296 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r") 297 (unspec:V8HI [(match_operand:SI 1 "spu_reg_operand" "r")] UNSPEC_FSMH))] 298 "" 299 "fsmh\t%0,%1" 300 [(set_attr "type" "shuf")]) 301 302(define_insn "spu_fsm" 303 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") 304 (unspec:V4SI [(match_operand:SI 1 "spu_reg_operand" "r")] UNSPEC_FSM))] 305 "" 306 "fsm\t%0,%1" 307 [(set_attr "type" "shuf")]) 308 309 310;; gather bits 311(define_insn "spu_gbb" 312 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") 313 (unspec:V4SI [(match_operand:V16QI 1 "spu_reg_operand" "r")] UNSPEC_GBB))] 314 "" 315 "gbb\t%0,%1" 316 [(set_attr "type" "shuf")]) 317 318(define_insn "spu_gbh" 319 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") 320 (unspec:V4SI [(match_operand:V8HI 1 "spu_reg_operand" "r")] UNSPEC_GBH))] 321 "" 322 "gbh\t%0,%1" 323 [(set_attr "type" "shuf")]) 324 325(define_insn "spu_gb" 326 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") 327 (unspec:V4SI [(match_operand:V4SI 1 "spu_reg_operand" "r")] UNSPEC_GB))] 328 "" 329 "gb\t%0,%1" 330 [(set_attr "type" "shuf")]) 331 332;; misc byte operations 333(define_insn "spu_avgb" 334 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r") 335 (unspec:V16QI [(match_operand:V16QI 1 "spu_reg_operand" "r") 336 (match_operand:V16QI 2 "spu_reg_operand" "r")] UNSPEC_AVGB))] 337 "" 338 "avgb\t%0,%1,%2" 339 [(set_attr "type" "fxb")]) 340 341(define_insn "spu_absdb" 342 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r") 343 (unspec:V16QI [(match_operand:V16QI 1 "spu_reg_operand" "r") 344 (match_operand:V16QI 2 "spu_reg_operand" "r")] UNSPEC_ABSDB))] 345 "" 346 "absdb\t%0,%1,%2" 347 [(set_attr "type" "fxb")]) 348 349(define_insn "spu_sumb" 350 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r") 351 (unspec:V8HI [(match_operand:V16QI 1 "spu_reg_operand" "r") 352 (match_operand:V16QI 2 "spu_reg_operand" "r")] UNSPEC_SUMB))] 353 "" 354 "sumb\t%0,%1,%2" 355 [(set_attr "type" "fxb")]) 356 357;; sign extend 358(define_insn "spu_xsbh" 359 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r") 360 (sign_extend:V8HI 361 (vec_select:V8QI 362 (match_operand:V16QI 1 "spu_reg_operand" "r") 363 (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7) 364 (const_int 9)(const_int 11)(const_int 13)(const_int 15)]))))] 365 "" 366 "xsbh\t%0,%1") 367 368(define_insn "spu_xshw" 369 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") 370 (sign_extend:V4SI 371 (vec_select:V4HI 372 (match_operand:V8HI 1 "spu_reg_operand" "r") 373 (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)]))))] 374 "" 375 "xshw\t%0,%1") 376 377(define_insn "spu_xswd" 378 [(set (match_operand:V2DI 0 "spu_reg_operand" "=r") 379 (sign_extend:V2DI 380 (vec_select:V2SI 381 (match_operand:V4SI 1 "spu_reg_operand" "r") 382 (parallel [(const_int 1)(const_int 3)]))))] 383 "" 384 "xswd\t%0,%1") 385 386;; or across 387 388(define_insn "spu_orx" 389 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") 390 (unspec:V4SI [(match_operand:V4SI 1 "spu_reg_operand" "r")] UNSPEC_ORX))] 391 "" 392 "orx\t%0,%1") 393 394 395;; compare & halt 396(define_insn "spu_heq" 397 [(unspec_volatile [(match_operand:SI 0 "spu_reg_operand" "r,r") 398 (match_operand:SI 1 "spu_nonmem_operand" "r,K")] UNSPEC_HEQ)] 399 "" 400 "@ 401 heq\t%0,%1 402 heqi\t%0,%1") 403 404(define_insn "spu_hgt" 405 [(unspec_volatile [(match_operand:SI 0 "spu_reg_operand" "r,r") 406 (match_operand:SI 1 "spu_nonmem_operand" "r,K")] UNSPEC_HGT)] 407 "" 408 "@ 409 hgt\t%0,%1 410 hgti\t%0,%1") 411 412(define_insn "spu_hlgt" 413 [(unspec_volatile [(match_operand:SI 0 "spu_reg_operand" "r,r") 414 (match_operand:SI 1 "spu_nonmem_operand" "r,K")] UNSPEC_HLGT)] 415 "" 416 "@ 417 hlgt\t%0,%1 418 hlgti\t%0,%1") 419 420;; branches 421 422;; The description below hides the fact that bisled conditionally 423;; executes the call depending on the value in channel 0. This was 424;; done so that the description would conform to the format of a call 425;; insn. Otherwise (if this were not part of call insn), the link 426;; register, $lr, would not be saved/restored in the prologue/epilogue. 427 428(define_insn "spu_bisled" 429 [(parallel 430 [(call (mem:QI (match_operand:SI 0 "spu_reg_operand" "r")) 431 (const_int 0)) 432 (clobber (reg:SI 0)) 433 (clobber (reg:SI 130)) 434 (use (match_operand:SI 1 "address_operand" "")) 435 (use (const_int 0))])] 436 "" 437 "bisled\t$lr,%0" 438 [(set_attr "type" "br")]) 439 440(define_insn "spu_bisledd" 441 [(parallel 442 [(call (mem:QI (match_operand:SI 0 "spu_reg_operand" "r")) 443 (const_int 0)) 444 (clobber (reg:SI 0)) 445 (clobber (reg:SI 130)) 446 (use (match_operand:SI 1 "address_operand" "")) 447 (use (const_int 1))])] 448 "" 449 "bisledd\t$lr,%0" 450 [(set_attr "type" "br")]) 451 452(define_insn "spu_bislede" 453 [(parallel 454 [(call (mem:QI (match_operand:SI 0 "spu_reg_operand" "r")) 455 (const_int 0)) 456 (clobber (reg:SI 0)) 457 (clobber (reg:SI 130)) 458 (use (match_operand:SI 1 "address_operand" "")) 459 (use (const_int 2))])] 460 "" 461 "bislede\t$lr,%0" 462 [(set_attr "type" "br")]) 463 464;; float convert 465(define_expand "spu_csflt" 466 [(set (match_operand:V4SF 0 "spu_reg_operand") 467 (unspec:V4SF [(match_operand:V4SI 1 "spu_reg_operand") 468 (match_operand:SI 2 "spu_nonmem_operand")] 0 ))] 469 "" 470{ 471 if (GET_CODE (operands[2]) == CONST_INT 472 && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) > 127)) 473 { 474 error ("spu_convtf expects an integer literal in the range [0, 127]."); 475 operands[2] = force_reg (SImode, operands[2]); 476 } 477 if (GET_CODE (operands[2]) != CONST_INT) 478 { 479 rtx exp2; 480 rtx cnv = gen_reg_rtx (V4SFmode); 481 rtx scale = gen_reg_rtx (SImode); 482 rtx op2 = force_reg (SImode, operands[2]); 483 rtx m1 = spu_gen_exp2 (V4SFmode, GEN_INT (-1)); 484 emit_insn (gen_subsi3 (scale, const1_rtx, op2)); 485 exp2 = spu_gen_exp2 (V4SFmode, scale); 486 emit_insn (gen_floatv4siv4sf2_mul (cnv, operands[1], m1)); 487 emit_insn (gen_mulv4sf3 (operands[0], cnv, exp2)); 488 } 489 else 490 { 491 rtx exp2 = spu_gen_exp2 (V4SFmode, operands[2]); 492 emit_insn (gen_floatv4siv4sf2_div (operands[0], operands[1], exp2)); 493 } 494 DONE; 495}) 496 497(define_expand "spu_cflts" 498 [(set (match_operand:V4SI 0 "spu_reg_operand") 499 (unspec:V4SI [(match_operand:V4SF 1 "spu_reg_operand") 500 (match_operand:SI 2 "spu_nonmem_operand")] 0 ))] 501 "" 502{ 503 rtx exp2; 504 if (GET_CODE (operands[2]) == CONST_INT 505 && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) > 127)) 506 { 507 error ("spu_convts expects an integer literal in the range [0, 127]."); 508 operands[2] = force_reg (SImode, operands[2]); 509 } 510 exp2 = spu_gen_exp2 (V4SFmode, operands[2]); 511 if (GET_CODE (operands[2]) != CONST_INT) 512 { 513 rtx mul = gen_reg_rtx (V4SFmode); 514 emit_insn (gen_mulv4sf3 (mul, operands[1], exp2)); 515 emit_insn (gen_fix_truncv4sfv4si2 (operands[0], mul)); 516 } 517 else 518 emit_insn (gen_fix_truncv4sfv4si2_mul (operands[0], operands[1], exp2)); 519 DONE; 520}) 521 522(define_expand "spu_cuflt" 523 [(set (match_operand:V4SF 0 "spu_reg_operand" "=r") 524 (unspec:V4SF [(match_operand:V4SI 1 "spu_reg_operand") 525 (match_operand:SI 2 "spu_nonmem_operand")] 0 ))] 526 "" 527{ 528 if (GET_CODE (operands[2]) == CONST_INT 529 && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) > 127)) 530 { 531 error ("spu_convtf expects an integer literal in the range [0, 127]."); 532 operands[2] = force_reg (SImode, operands[2]); 533 } 534 if (GET_CODE (operands[2]) != CONST_INT) 535 { 536 rtx exp2; 537 rtx cnv = gen_reg_rtx (V4SFmode); 538 rtx scale = gen_reg_rtx (SImode); 539 rtx op2 = force_reg (SImode, operands[2]); 540 rtx m1 = spu_gen_exp2 (V4SFmode, GEN_INT (-1)); 541 emit_insn (gen_subsi3 (scale, const1_rtx, op2)); 542 exp2 = spu_gen_exp2 (V4SFmode, scale); 543 emit_insn (gen_floatunsv4siv4sf2_mul (cnv, operands[1], m1)); 544 emit_insn (gen_mulv4sf3 (operands[0], cnv, exp2)); 545 } 546 else 547 { 548 rtx exp2 = spu_gen_exp2 (V4SFmode, operands[2]); 549 emit_insn (gen_floatunsv4siv4sf2_div (operands[0], operands[1], exp2)); 550 } 551 DONE; 552}) 553 554(define_expand "spu_cfltu" 555 [(set (match_operand:V4SI 0 "spu_reg_operand") 556 (unspec:V4SI [(match_operand:V4SF 1 "spu_reg_operand") 557 (match_operand:SI 2 "spu_nonmem_operand")] 0 ))] 558 "" 559{ 560 rtx exp2; 561 if (GET_CODE (operands[2]) == CONST_INT 562 && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) > 127)) 563 { 564 error ("spu_convtu expects an integer literal in the range [0, 127]."); 565 operands[2] = force_reg (SImode, operands[2]); 566 } 567 exp2 = spu_gen_exp2 (V4SFmode, operands[2]); 568 if (GET_CODE (operands[2]) != CONST_INT) 569 { 570 rtx mul = gen_reg_rtx (V4SFmode); 571 emit_insn (gen_mulv4sf3 (mul, operands[1], exp2)); 572 emit_insn (gen_fixuns_truncv4sfv4si2 (operands[0], mul)); 573 } 574 else 575 emit_insn (gen_fixuns_truncv4sfv4si2_mul (operands[0], operands[1], exp2)); 576 DONE; 577}) 578 579(define_expand "spu_frds" 580 [(set (match_operand:V4SF 0 "spu_reg_operand" "") 581 (vec_select:V4SF 582 (vec_concat:V4SF 583 (float_truncate:V2SF (match_operand:V2DF 1 "spu_reg_operand" "")) 584 (match_dup:V2SF 2)) 585 (parallel [(const_int 0)(const_int 2)(const_int 1)(const_int 3)])))] 586 "" 587 "operands[2] = spu_const(V2SFmode, 0);") 588 589(define_insn "_frds" 590 [(set (match_operand:V4SF 0 "spu_reg_operand" "=r") 591 (vec_select:V4SF 592 (vec_concat:V4SF 593 (float_truncate:V2SF (match_operand:V2DF 1 "spu_reg_operand" "r")) 594 (match_operand:V2SF 2 "vec_imm_operand" "i")) 595 (parallel [(const_int 0)(const_int 2)(const_int 1)(const_int 3)])))] 596 "" 597 "frds\t%0,%1" 598 [(set_attr "type" "fpd")]) 599 600(define_insn "spu_fesd" 601 [(set (match_operand:V2DF 0 "spu_reg_operand" "=r") 602 (float_extend:V2DF 603 (vec_select:V2SF 604 (match_operand:V4SF 1 "spu_reg_operand" "r") 605 (parallel [(const_int 0)(const_int 2)]))))] 606 "" 607 "fesd\t%0,%1" 608 [(set_attr "type" "fpd")]) 609 610;; control 611(define_insn "spu_stop" 612 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "M")] UNSPEC_STOP)] 613 "" 614 "stop\t%0" 615 [(set_attr "type" "br")]) 616 617(define_insn "spu_stopd" 618 [(unspec_volatile [(match_operand:SI 0 "spu_reg_operand" "r") 619 (match_operand:SI 1 "spu_reg_operand" "r") 620 (match_operand:SI 2 "spu_reg_operand" "r")] UNSPEC_STOPD)] 621 "" 622 "stopd\t%0,%1,%2" 623 [(set_attr "type" "br")]) 624 625;; interrupt disable/enable 626(define_expand "spu_idisable" 627 [(parallel 628 [(unspec_volatile [(const_int 0)] UNSPEC_SET_INTR) 629 (clobber (match_dup:SI 0)) 630 (clobber (mem:BLK (scratch)))])] 631 "" 632 "operands[0] = gen_reg_rtx (SImode);") 633 634(define_expand "spu_ienable" 635 [(parallel 636 [(unspec_volatile [(const_int 1)] UNSPEC_SET_INTR) 637 (clobber (match_dup:SI 0)) 638 (clobber (mem:BLK (scratch)))])] 639 "" 640 "operands[0] = gen_reg_rtx (SImode);") 641 642(define_insn "set_intr" 643 [(unspec_volatile [(match_operand 1 "const_int_operand" "i")] UNSPEC_SET_INTR) 644 (clobber (match_operand:SI 0 "spu_reg_operand" "=&r")) 645 (clobber (mem:BLK (scratch)))] 646 "! flag_pic" 647 "ila\t%0,.+8\;bi%I1\t%0" 648 [(set_attr "length" "8") 649 (set_attr "type" "multi0")]) 650 651(define_insn "set_intr_pic" 652 [(unspec_volatile [(match_operand 1 "const_int_operand" "i")] UNSPEC_SET_INTR) 653 (clobber (match_operand:SI 0 "spu_reg_operand" "=&r")) 654 (clobber (mem:BLK (scratch)))] 655 "flag_pic" 656 "brsl\t%0,.+4\;ai\t%0,%0,8\;bi%I1\t%0" 657 [(set_attr "length" "12") 658 (set_attr "type" "multi1")]) 659 660(define_insn "set_intr_cc" 661 [(cond_exec (match_operator 1 "branch_comparison_operator" 662 [(match_operand 2 "spu_reg_operand" "r") 663 (const_int 0)]) 664 (parallel [(unspec_volatile [(match_operand:SI 3 "const_int_operand" "i")] UNSPEC_SET_INTR) 665 (clobber (match_operand:SI 0 "spu_reg_operand" "=&r")) 666 (clobber (mem:BLK (scratch)))]))] 667 "! flag_pic" 668 "ila\t%0,.+8\;bi%b2%b1z%I3\t%2,%0" 669 [(set_attr "length" "8") 670 (set_attr "type" "multi0")]) 671 672(define_insn "set_intr_cc_pic" 673 [(cond_exec (match_operator 1 "branch_comparison_operator" 674 [(match_operand 2 "spu_reg_operand" "r") 675 (const_int 0)]) 676 (parallel [(unspec_volatile [(match_operand:SI 3 "const_int_operand" "i")] UNSPEC_SET_INTR) 677 (clobber (match_operand:SI 0 "spu_reg_operand" "=&r")) 678 (clobber (mem:BLK (scratch)))]))] 679 "flag_pic" 680 "brsl\t%0,.+4\;ai\t%0,%0,8\;bi%b2%b1z%I3\t%2,%0" 681 [(set_attr "length" "12") 682 (set_attr "type" "multi1")]) 683 684(define_insn "set_intr_return" 685 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")] UNSPEC_SET_INTR) 686 (return)] 687 "" 688 "bi%I0\t$lr" 689 [(set_attr "type" "br")]) 690 691(define_peephole2 692 [(parallel 693 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")] UNSPEC_SET_INTR) 694 (clobber (match_operand:SI 1 "spu_reg_operand")) 695 (clobber (mem:BLK (scratch)))]) 696 (use (reg:SI 0)) 697 (return)] 698 "" 699 [(use (reg:SI 0)) 700 (parallel 701 [(unspec_volatile [(match_dup:SI 0)] UNSPEC_SET_INTR) 702 (return)])] 703 "") 704 705;; special purpose registers 706(define_insn "spu_fscrrd" 707 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") 708 (unspec_volatile:V4SI [(const_int 6)] UNSPEC_FSCRRD))] 709 "" 710 "fscrrd\t%0" 711 [(set_attr "type" "spr")]) 712 713(define_insn "spu_fscrwr" 714 [(unspec_volatile [(match_operand:V4SI 0 "spu_reg_operand" "r")] UNSPEC_FSCRWR)] 715 "" 716 "fscrwr\t$0,%0" 717 [(set_attr "type" "spr")]) 718 719(define_insn "spu_mfspr" 720 [(set (match_operand:SI 0 "spu_reg_operand" "=r") 721 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "J")] UNSPEC_MFSPR))] 722 "" 723 "mfspr\t%0,$sp%1" 724 [(set_attr "type" "spr")]) 725 726(define_insn "spu_mtspr" 727 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "J") 728 (match_operand:SI 1 "spu_reg_operand" "r")] UNSPEC_MTSPR)] 729 "" 730 "mtspr\t$sp%0,%1" 731 [(set_attr "type" "spr")]) 732 733;; channels 734(define_expand "spu_rdch" 735 [(set (match_operand:V4SI 0 "spu_reg_operand" "") 736 (unspec_volatile:V4SI [(match_operand:SI 1 "immediate_operand" "")] UNSPEC_RDCH))] 737 "" 738 "{ 739 if (spu_safe_dma (INTVAL (operands[1]))) 740 { 741 emit_insn (gen_spu_rdch_clobber (operands[0], operands[1])); 742 DONE; 743 } 744 }") 745 746(define_expand "spu_rchcnt" 747 [(set (match_operand:SI 0 "spu_reg_operand" "") 748 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "")] UNSPEC_RCHCNT))] 749 "" 750 "{ 751 if (spu_safe_dma (INTVAL (operands[1]))) 752 { 753 emit_insn (gen_spu_rchcnt_clobber (operands[0], operands[1])); 754 DONE; 755 } 756 }") 757 758(define_expand "spu_wrch" 759 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "") 760 (match_operand:V4SI 1 "spu_reg_operand" "")] UNSPEC_WRCH)] 761 "" 762 "{ 763 if (spu_safe_dma (INTVAL (operands[0]))) 764 { 765 emit_insn (gen_spu_wrch_clobber (operands[0], operands[1])); 766 DONE; 767 } 768 }") 769 770(define_insn "spu_rdch_noclobber" 771 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") 772 (unspec_volatile:V4SI [(match_operand:SI 1 "immediate_operand" "J")] UNSPEC_RDCH))] 773 "" 774 "rdch\t%0,$ch%1" 775 [(set_attr "type" "spr")]) 776 777(define_insn "spu_rchcnt_noclobber" 778 [(set (match_operand:SI 0 "spu_reg_operand" "=r") 779 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "J")] UNSPEC_RCHCNT))] 780 "" 781 "rchcnt\t%0,$ch%1" 782 [(set_attr "type" "spr")]) 783 784(define_insn "spu_wrch_noclobber" 785 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "J") 786 (match_operand:V4SI 1 "spu_reg_operand" "r")] UNSPEC_WRCH)] 787 "" 788 "wrch\t$ch%0,%1" 789 [(set_attr "type" "spr")]) 790 791(define_insn "spu_rdch_clobber" 792 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") 793 (unspec_volatile:V4SI [(match_operand:SI 1 "immediate_operand" "J")] UNSPEC_RDCH)) 794 (clobber (mem:BLK (scratch)))] 795 "" 796 "rdch\t%0,$ch%1" 797 [(set_attr "type" "spr")]) 798 799(define_insn "spu_rchcnt_clobber" 800 [(set (match_operand:SI 0 "spu_reg_operand" "=r") 801 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "J")] UNSPEC_RCHCNT)) 802 (clobber (mem:BLK (scratch)))] 803 "" 804 "rchcnt\t%0,$ch%1" 805 [(set_attr "type" "spr")]) 806 807(define_insn "spu_wrch_clobber" 808 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "J") 809 (match_operand:V4SI 1 "spu_reg_operand" "r")] UNSPEC_WRCH) 810 (clobber (mem:BLK (scratch)))] 811 "" 812 "wrch\t$ch%0,%1" 813 [(set_attr "type" "spr")]) 814 815(define_expand "spu_splats" 816 [(set (match_operand 0 "spu_reg_operand" "") 817 (vec_duplicate (match_operand 1 "spu_nonmem_operand" "")))] 818 "" 819 { 820 spu_builtin_splats(operands); 821 DONE; 822 }) 823 824(define_expand "spu_extract" 825 [(set (match_operand 0 "spu_reg_operand" "") 826 (unspec [(match_operand 1 "spu_reg_operand" "") 827 (match_operand 2 "spu_nonmem_operand" "")] 0))] 828 "" 829 { 830 spu_builtin_extract (operands); 831 DONE; 832 }) 833 834(define_expand "spu_insert" 835 [(set (match_operand 0 "spu_reg_operand" "") 836 (unspec [(match_operand 1 "spu_reg_operand" "") 837 (match_operand 2 "spu_reg_operand" "") 838 (match_operand:SI 3 "spu_nonmem_operand" "")] 0))] 839 "" 840 { 841 spu_builtin_insert(operands); 842 DONE; 843 }) 844 845(define_expand "spu_promote" 846 [(set (match_operand 0 "spu_reg_operand" "") 847 (unspec [(match_operand 1 "spu_reg_operand" "") 848 (match_operand:SI 2 "immediate_operand" "")] 0))] 849 "" 850 { 851 spu_builtin_promote(operands); 852 DONE; 853 }) 854 855;; Currently doing nothing with this but expanding its args. 856(define_expand "spu_align_hint" 857 [(unspec [(match_operand:SI 0 "address_operand" "") 858 (match_operand:SI 1 "immediate_operand" "") 859 (match_operand:SI 2 "immediate_operand" "")] 0)] 860 "" 861 { 862 DONE; 863 }) 864 865