1;; Intrinsic patterns description of Andes NDS32 cpu for GNU compiler 2;; Copyright (C) 2012-2019 Free Software Foundation, Inc. 3;; Contributed by Andes Technology Corporation. 4;; 5;; This file is part of GCC. 6;; 7;; GCC is free software; you can redistribute it and/or modify it 8;; under the terms of the GNU General Public License as published 9;; by the Free Software Foundation; either version 3, or (at your 10;; option) any later version. 11;; 12;; GCC is distributed in the hope that it will be useful, but WITHOUT 13;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 15;; License for more details. 16;; 17;; You should have received a copy of the GNU General Public License 18;; along with GCC; see the file COPYING3. If not see 19;; <http://www.gnu.org/licenses/>. 20 21;; ------------------------------------------------------------------------ 22 23;; Register Transfer. 24 25(define_insn "unspec_volatile_mfsr" 26 [(set (match_operand:SI 0 "register_operand" "=r") 27 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_VOLATILE_MFSR))] 28 "" 29 "mfsr\t%0, %V1" 30 [(set_attr "type" "misc") 31 (set_attr "length" "4")] 32) 33 34(define_insn "unspec_volatile_mfusr" 35 [(set (match_operand:SI 0 "register_operand" "=r") 36 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_VOLATILE_MFUSR))] 37 "" 38 "mfusr\t%0, %V1" 39 [(set_attr "type" "misc") 40 (set_attr "length" "4")] 41) 42 43(define_expand "mtsr_isb" 44 [(set (match_operand:SI 0 "register_operand" "") 45 (match_operand:SI 1 "immediate_operand" ""))] 46 "" 47{ 48 emit_insn (gen_unspec_volatile_mtsr (operands[0], operands[1])); 49 emit_insn (gen_unspec_volatile_isb()); 50 DONE; 51}) 52 53(define_expand "mtsr_dsb" 54 [(set (match_operand:SI 0 "register_operand" "") 55 (match_operand:SI 1 "immediate_operand" ""))] 56 "" 57{ 58 emit_insn (gen_unspec_volatile_mtsr (operands[0], operands[1])); 59 emit_insn (gen_unspec_dsb()); 60 DONE; 61}) 62 63(define_insn "unspec_volatile_mtsr" 64 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r") 65 (match_operand:SI 1 "immediate_operand" "i")] UNSPEC_VOLATILE_MTSR)] 66 "" 67 "mtsr\t%0, %V1" 68 [(set_attr "type" "misc") 69 (set_attr "length" "4")] 70) 71 72(define_insn "unspec_volatile_mtusr" 73 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r") 74 (match_operand:SI 1 "immediate_operand" "i")] UNSPEC_VOLATILE_MTUSR)] 75 "" 76 "mtusr\t%0, %V1" 77 [(set_attr "type" "misc") 78 (set_attr "length" "4")] 79) 80 81;; FPU Register Transfer. 82 83(define_insn "unspec_fcpynsd" 84 [(set (match_operand:DF 0 "register_operand" "=f") 85 (unspec:DF [(match_operand:DF 1 "register_operand" "f") 86 (match_operand:DF 2 "register_operand" "f")] UNSPEC_FCPYNSD))] 87 "" 88 "fcpynsd\t%0, %1, %2" 89 [(set_attr "type" "misc") 90 (set_attr "length" "4")] 91) 92 93(define_insn "unspec_fcpynss" 94 [(set (match_operand:SF 0 "register_operand" "=f") 95 (unspec:SF [(match_operand:SF 1 "register_operand" "f") 96 (match_operand:SF 2 "register_operand" "f")] UNSPEC_FCPYNSS))] 97 "" 98 "fcpynss\t%0, %1, %2" 99 [(set_attr "type" "misc") 100 (set_attr "length" "4")] 101) 102 103(define_insn "unspec_fcpysd" 104 [(set (match_operand:DF 0 "register_operand" "=f") 105 (unspec:DF [(match_operand:DF 1 "register_operand" "f") 106 (match_operand:DF 2 "register_operand" "f")] UNSPEC_FCPYSD))] 107 "" 108 "fcpysd\t%0, %1, %2" 109 [(set_attr "type" "misc") 110 (set_attr "length" "4")] 111) 112 113(define_insn "unspec_fcpyss" 114 [(set (match_operand:SF 0 "register_operand" "=f") 115 (unspec:SF [(match_operand:SF 1 "register_operand" "f") 116 (match_operand:SF 2 "register_operand" "f")] UNSPEC_FCPYSS))] 117 "" 118 "fcpyss\t%0, %1, %2" 119 [(set_attr "type" "misc") 120 (set_attr "length" "4")] 121) 122 123(define_insn "unspec_fmfcsr" 124 [(set (match_operand:SI 0 "register_operand" "=r") 125 (unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_FMFCSR))] 126 "" 127 "fmfcsr\t%0" 128 [(set_attr "type" "misc") 129 (set_attr "length" "4")] 130) 131 132(define_insn "unspec_fmtcsr" 133 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_FMTCSR)] 134 "" 135 "fmtcsr\t%0" 136 [(set_attr "type" "misc") 137 (set_attr "length" "4")] 138) 139 140(define_insn "unspec_fmfcfg" 141 [(set (match_operand:SI 0 "register_operand" "=r") 142 (unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_FMFCFG))] 143 "" 144 "fmfcfg\t%0" 145 [(set_attr "type" "misc") 146 (set_attr "length" "4")] 147) 148 149;; ------------------------------------------------------------------------ 150 151;; Interrupt Instructions. 152 153(define_insn "unspec_volatile_setgie_en" 154 [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_SETGIE_EN)] 155 "" 156 "setgie.e" 157 [(set_attr "type" "misc")] 158) 159 160(define_insn "unspec_volatile_setgie_dis" 161 [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_SETGIE_DIS)] 162 "" 163 "setgie.d" 164 [(set_attr "type" "misc")] 165) 166 167(define_expand "unspec_enable_int" 168 [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "")] UNSPEC_VOLATILE_ENABLE_INT)] 169 "" 170{ 171 rtx system_reg; 172 rtx temp_reg = gen_reg_rtx (SImode); 173 174 /* Set system register form nds32_intrinsic_register_names[]. */ 175 if ((INTVAL (operands[0]) >= NDS32_INT_H16) 176 && (INTVAL (operands[0]) <= NDS32_INT_H31)) 177 { 178 system_reg = GEN_INT (__NDS32_REG_INT_MASK2__); 179 operands[0] = GEN_INT (1 << (INTVAL (operands[0]))); 180 } 181 else if ((INTVAL (operands[0]) >= NDS32_INT_H32) 182 && (INTVAL (operands[0]) <= NDS32_INT_H63)) 183 { 184 system_reg = GEN_INT (__NDS32_REG_INT_MASK3__); 185 operands[0] = GEN_INT (1 << (INTVAL (operands[0]) - 32)); 186 } 187 else 188 { 189 system_reg = GEN_INT (__NDS32_REG_INT_MASK__); 190 191 if (INTVAL (operands[0]) == NDS32_INT_SWI) 192 operands[0] = GEN_INT (1 << 16); 193 else if ((INTVAL (operands[0]) >= NDS32_INT_ALZ) 194 && (INTVAL (operands[0]) <= NDS32_INT_DSSIM)) 195 operands[0] = GEN_INT (1 << (INTVAL (operands[0]) - 4)); 196 else 197 operands[0] = GEN_INT (1 << (INTVAL (operands[0]))); 198 } 199 200 emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg)); 201 emit_insn (gen_iorsi3 (temp_reg, temp_reg, operands[0])); 202 emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg)); 203 emit_insn (gen_unspec_dsb ()); 204 DONE; 205}) 206 207(define_expand "unspec_disable_int" 208 [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "")] UNSPEC_VOLATILE_DISABLE_INT)] 209 "" 210{ 211 rtx system_reg; 212 rtx temp_reg = gen_reg_rtx (SImode); 213 214 /* Set system register form nds32_intrinsic_register_names[]. */ 215 if ((INTVAL (operands[0]) >= NDS32_INT_H16) 216 && (INTVAL (operands[0]) <= NDS32_INT_H31)) 217 { 218 system_reg = GEN_INT (__NDS32_REG_INT_MASK2__); 219 operands[0] = GEN_INT (~(1 << INTVAL (operands[0]))); 220 } 221 else if ((INTVAL (operands[0]) >= NDS32_INT_H32) 222 && (INTVAL (operands[0]) <= NDS32_INT_H63)) 223 { 224 system_reg = GEN_INT (__NDS32_REG_INT_MASK3__); 225 operands[0] = GEN_INT (~(1 << (INTVAL (operands[0]) - 32))); 226 } 227 else 228 { 229 system_reg = GEN_INT (__NDS32_REG_INT_MASK__); 230 231 if (INTVAL (operands[0]) == NDS32_INT_SWI) 232 operands[0] = GEN_INT (~(1 << 16)); 233 else if ((INTVAL (operands[0]) >= NDS32_INT_ALZ) 234 && (INTVAL (operands[0]) <= NDS32_INT_DSSIM)) 235 operands[0] = GEN_INT (~(1 << (INTVAL (operands[0]) - 4))); 236 else 237 operands[0] = GEN_INT (~(1 << INTVAL (operands[0]))); 238 } 239 240 emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg)); 241 emit_insn (gen_andsi3 (temp_reg, temp_reg, operands[0])); 242 emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg)); 243 emit_insn (gen_unspec_dsb ()); 244 DONE; 245}) 246 247(define_expand "unspec_set_pending_swint" 248 [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_SET_PENDING_SWINT)] 249 "" 250{ 251 /* Get $INT_PEND system register form nds32_intrinsic_register_names[] */ 252 rtx system_reg = GEN_INT (__NDS32_REG_INT_PEND__); 253 rtx temp_reg = gen_reg_rtx (SImode); 254 255 emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg)); 256 emit_insn (gen_iorsi3 (temp_reg, temp_reg, GEN_INT (65536))); 257 emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg)); 258 emit_insn (gen_unspec_dsb ()); 259 DONE; 260}) 261 262(define_expand "unspec_clr_pending_swint" 263 [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_CLR_PENDING_SWINT)] 264 "" 265{ 266 /* Get $INT_PEND system register form nds32_intrinsic_register_names[] */ 267 rtx system_reg = GEN_INT (__NDS32_REG_INT_PEND__); 268 rtx temp_reg = gen_reg_rtx (SImode); 269 270 emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg)); 271 emit_insn (gen_andsi3 (temp_reg, temp_reg, GEN_INT (~(1 << 16)))); 272 emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg)); 273 emit_insn (gen_unspec_dsb ()); 274 DONE; 275}) 276 277(define_expand "unspec_clr_pending_hwint" 278 [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "")] UNSPEC_VOLATILE_CLR_PENDING_HWINT)] 279 "" 280{ 281 rtx system_reg = NULL_RTX; 282 rtx temp_reg = gen_reg_rtx (SImode); 283 rtx clr_hwint; 284 unsigned offset = 0; 285 286 /* Set system register form nds32_intrinsic_register_names[]. */ 287 if ((INTVAL (operands[0]) >= NDS32_INT_H0) 288 && (INTVAL (operands[0]) <= NDS32_INT_H15)) 289 { 290 system_reg = GEN_INT (__NDS32_REG_INT_PEND__); 291 } 292 else if ((INTVAL (operands[0]) >= NDS32_INT_H16) 293 && (INTVAL (operands[0]) <= NDS32_INT_H31)) 294 { 295 system_reg = GEN_INT (__NDS32_REG_INT_PEND2__); 296 } 297 else if ((INTVAL (operands[0]) >= NDS32_INT_H32) 298 && (INTVAL (operands[0]) <= NDS32_INT_H63)) 299 { 300 system_reg = GEN_INT (__NDS32_REG_INT_PEND3__); 301 offset = 32; 302 } 303 else 304 error ("__nds32__clr_pending_hwint not support NDS32_INT_SWI," 305 " NDS32_INT_ALZ, NDS32_INT_IDIVZE, NDS32_INT_DSSIM"); 306 307 /* $INT_PEND type is write one clear. */ 308 clr_hwint = GEN_INT (1 << (INTVAL (operands[0]) - offset)); 309 310 if (system_reg != NULL_RTX) 311 { 312 emit_move_insn (temp_reg, clr_hwint); 313 emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg)); 314 emit_insn (gen_unspec_dsb ()); 315 } 316 DONE; 317}) 318 319(define_expand "unspec_get_all_pending_int" 320 [(set (match_operand:SI 0 "register_operand" "") 321 (unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_GET_ALL_PENDING_INT))] 322 "" 323{ 324 rtx system_reg = GEN_INT (__NDS32_REG_INT_PEND__); 325 emit_insn (gen_unspec_volatile_mfsr (operands[0], system_reg)); 326 emit_insn (gen_unspec_dsb ()); 327 DONE; 328}) 329 330(define_expand "unspec_get_pending_int" 331 [(set (match_operand:SI 0 "register_operand" "") 332 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "")] UNSPEC_VOLATILE_GET_PENDING_INT))] 333 "" 334{ 335 rtx system_reg = NULL_RTX; 336 337 /* Set system register form nds32_intrinsic_register_names[]. */ 338 if ((INTVAL (operands[1]) >= NDS32_INT_H0) 339 && (INTVAL (operands[1]) <= NDS32_INT_H15)) 340 { 341 system_reg = GEN_INT (__NDS32_REG_INT_PEND__); 342 operands[2] = GEN_INT (31 - INTVAL (operands[1])); 343 } 344 else if (INTVAL (operands[1]) == NDS32_INT_SWI) 345 { 346 system_reg = GEN_INT (__NDS32_REG_INT_PEND__); 347 operands[2] = GEN_INT (15); 348 } 349 else if ((INTVAL (operands[1]) >= NDS32_INT_H16) 350 && (INTVAL (operands[1]) <= NDS32_INT_H31)) 351 { 352 system_reg = GEN_INT (__NDS32_REG_INT_PEND2__); 353 operands[2] = GEN_INT (31 - INTVAL (operands[1])); 354 } 355 else if ((INTVAL (operands[1]) >= NDS32_INT_H32) 356 && (INTVAL (operands[1]) <= NDS32_INT_H63)) 357 { 358 system_reg = GEN_INT (__NDS32_REG_INT_PEND3__); 359 operands[2] = GEN_INT (31 - (INTVAL (operands[1]) - 32)); 360 } 361 else 362 error ("get_pending_int not support NDS32_INT_ALZ," 363 " NDS32_INT_IDIVZE, NDS32_INT_DSSIM"); 364 365 /* mfsr op0, sytem_reg */ 366 if (system_reg != NULL_RTX) 367 { 368 emit_insn (gen_unspec_volatile_mfsr (operands[0], system_reg)); 369 emit_insn (gen_ashlsi3 (operands[0], operands[0], operands[2])); 370 emit_insn (gen_lshrsi3 (operands[0], operands[0], GEN_INT (31))); 371 emit_insn (gen_unspec_dsb ()); 372 } 373 DONE; 374}) 375 376(define_expand "unspec_set_int_priority" 377 [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "") 378 (match_operand:SI 1 "immediate_operand" "")] UNSPEC_VOLATILE_SET_INT_PRIORITY)] 379 "" 380{ 381 rtx system_reg = NULL_RTX; 382 rtx priority = NULL_RTX; 383 rtx mask = NULL_RTX; 384 rtx temp_reg = gen_reg_rtx (SImode); 385 rtx mask_reg = gen_reg_rtx (SImode); 386 rtx set_reg = gen_reg_rtx (SImode); 387 unsigned offset = 0; 388 389 /* Get system register form nds32_intrinsic_register_names[]. */ 390 if (INTVAL (operands[0]) <= NDS32_INT_H15) 391 { 392 system_reg = GEN_INT (__NDS32_REG_INT_PRI__); 393 offset = 0; 394 } 395 else if (INTVAL (operands[0]) >= NDS32_INT_H16 396 && INTVAL (operands[0]) <= NDS32_INT_H31) 397 { 398 system_reg = GEN_INT (__NDS32_REG_INT_PRI2__); 399 /* The $INT_PRI2 first bit correspond to H16, so need 400 subtract 16. */ 401 offset = 16; 402 } 403 else if (INTVAL (operands[0]) >= NDS32_INT_H32 404 && INTVAL (operands[0]) <= NDS32_INT_H47) 405 { 406 system_reg = GEN_INT (__NDS32_REG_INT_PRI3__); 407 /* The $INT_PRI3 first bit correspond to H32, so need 408 subtract 32. */ 409 offset = 32; 410 } 411 else if (INTVAL (operands[0]) >= NDS32_INT_H48 412 && INTVAL (operands[0]) <= NDS32_INT_H63) 413 { 414 system_reg = GEN_INT (__NDS32_REG_INT_PRI4__); 415 /* The $INT_PRI3 first bit correspond to H48, so need 416 subtract 48. */ 417 offset = 48; 418 } 419 else 420 error ("set_int_priority not support NDS32_INT_SWI," 421 " NDS32_INT_ALZ, NDS32_INT_IDIVZE, NDS32_INT_DSSIM"); 422 423 mask = GEN_INT (~(3 << 2 * (INTVAL (operands[0]) - offset))); 424 priority = GEN_INT ((int) (INTVAL (operands[1]) 425 << ((INTVAL (operands[0]) - offset) * 2))); 426 427 if (system_reg != NULL_RTX) 428 { 429 emit_move_insn (mask_reg, mask); 430 emit_move_insn (set_reg, priority); 431 emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg)); 432 emit_insn (gen_andsi3 (temp_reg, temp_reg, mask_reg)); 433 emit_insn (gen_iorsi3 (temp_reg, temp_reg, set_reg)); 434 emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg)); 435 emit_insn (gen_unspec_dsb ()); 436 } 437 DONE; 438}) 439 440(define_expand "unspec_get_int_priority" 441 [(set (match_operand:SI 0 "register_operand" "") 442 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "")] UNSPEC_VOLATILE_GET_INT_PRIORITY))] 443 "" 444{ 445 rtx system_reg = NULL_RTX; 446 rtx priority = NULL_RTX; 447 unsigned offset = 0; 448 449 /* Get system register form nds32_intrinsic_register_names[] */ 450 if (INTVAL (operands[1]) <= NDS32_INT_H15) 451 { 452 system_reg = GEN_INT (__NDS32_REG_INT_PRI__); 453 offset = 0; 454 } 455 else if (INTVAL (operands[1]) >= NDS32_INT_H16 456 && INTVAL (operands[1]) <= NDS32_INT_H31) 457 { 458 system_reg = GEN_INT (__NDS32_REG_INT_PRI2__); 459 /* The $INT_PRI2 first bit correspond to H16, so need 460 subtract 16. */ 461 offset = 16; 462 } 463 else if (INTVAL (operands[1]) >= NDS32_INT_H32 464 && INTVAL (operands[1]) <= NDS32_INT_H47) 465 { 466 system_reg = GEN_INT (__NDS32_REG_INT_PRI3__); 467 /* The $INT_PRI3 first bit correspond to H32, so need 468 subtract 32. */ 469 offset = 32; 470 } 471 else if (INTVAL (operands[1]) >= NDS32_INT_H48 472 && INTVAL (operands[1]) <= NDS32_INT_H63) 473 { 474 system_reg = GEN_INT (__NDS32_REG_INT_PRI4__); 475 /* The $INT_PRI4 first bit correspond to H48, so need 476 subtract 48. */ 477 offset = 48; 478 } 479 else 480 error ("set_int_priority not support NDS32_INT_SWI," 481 " NDS32_INT_ALZ, NDS32_INT_IDIVZE, NDS32_INT_DSSIM"); 482 483 priority = GEN_INT (31 - 2 * (INTVAL (operands[1]) - offset)); 484 485 if (system_reg != NULL_RTX) 486 { 487 emit_insn (gen_unspec_volatile_mfsr (operands[0], system_reg)); 488 emit_insn (gen_ashlsi3 (operands[0], operands[0], priority)); 489 emit_insn (gen_lshrsi3 (operands[0], operands[0], GEN_INT (30))); 490 emit_insn (gen_unspec_dsb ()); 491 } 492 DONE; 493}) 494 495(define_expand "unspec_set_trig_level" 496 [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "")] UNSPEC_VOLATILE_SET_TRIG_LEVEL)] 497 "" 498{ 499 rtx system_reg = NULL_RTX; 500 rtx temp_reg = gen_reg_rtx (SImode); 501 rtx set_level; 502 unsigned offset = 0; 503 504 if (INTVAL (operands[0]) >= NDS32_INT_H0 505 && INTVAL (operands[0]) <= NDS32_INT_H31) 506 { 507 system_reg = GEN_INT (__NDS32_REG_INT_TRIGGER__); 508 offset = 0; 509 } 510 else if (INTVAL (operands[0]) >= NDS32_INT_H32 511 && INTVAL (operands[0]) <= NDS32_INT_H63) 512 { 513 system_reg = GEN_INT (__NDS32_REG_INT_TRIGGER2__); 514 offset = 32; 515 } 516 else 517 error ("__nds32__set_trig_type_level not support NDS32_INT_SWI," 518 " NDS32_INT_ALZ, NDS32_INT_IDIVZE, NDS32_INT_DSSIM"); 519 520 if (system_reg != NULL_RTX) 521 { 522 /* TRIGGER register, 0 mean level triggered and 1 mean edge triggered. */ 523 set_level = GEN_INT (~(1 << (INTVAL (operands[0]) - offset))); 524 525 emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg)); 526 emit_insn (gen_andsi3 (temp_reg, temp_reg, set_level)); 527 emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg)); 528 } 529 DONE; 530}) 531 532(define_expand "unspec_set_trig_edge" 533 [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "")] UNSPEC_VOLATILE_SET_TRIG_EDGE)] 534 "" 535{ 536 rtx system_reg = NULL_RTX; 537 rtx temp_reg = gen_reg_rtx (SImode); 538 rtx set_level; 539 unsigned offset = 0; 540 541 if (INTVAL (operands[0]) >= NDS32_INT_H0 542 && INTVAL (operands[0]) <= NDS32_INT_H31) 543 { 544 system_reg = GEN_INT (__NDS32_REG_INT_TRIGGER__); 545 offset = 0; 546 } 547 else if (INTVAL (operands[0]) >= NDS32_INT_H32 548 && INTVAL (operands[0]) <= NDS32_INT_H63) 549 { 550 system_reg = GEN_INT (__NDS32_REG_INT_TRIGGER2__); 551 offset = 32; 552 } 553 else 554 error ("__nds32__set_trig_type_edge not support NDS32_INT_SWI," 555 " NDS32_INT_ALZ, NDS32_INT_IDIVZE, NDS32_INT_DSSIM"); 556 557 if (system_reg != NULL_RTX) 558 { 559 /* TRIGGER register, 0 mean level triggered and 1 mean edge triggered. */ 560 set_level = GEN_INT ((1 << (INTVAL (operands[0]) - offset))); 561 562 emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg)); 563 emit_insn (gen_iorsi3 (temp_reg, temp_reg, set_level)); 564 emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg)); 565 } 566 DONE; 567}) 568 569(define_expand "unspec_get_trig_type" 570 [(set (match_operand:SI 0 "register_operand" "") 571 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "")] UNSPEC_VOLATILE_GET_TRIG_TYPE))] 572 "" 573{ 574 rtx system_reg = NULL_RTX; 575 rtx trig_type; 576 unsigned offset = 0; 577 578 if (INTVAL (operands[1]) >= NDS32_INT_H0 579 && INTVAL (operands[1]) <= NDS32_INT_H31) 580 { 581 system_reg = GEN_INT (__NDS32_REG_INT_TRIGGER__); 582 offset = 0; 583 } 584 else if (INTVAL (operands[1]) >= NDS32_INT_H32 585 && INTVAL (operands[1]) <= NDS32_INT_H63) 586 { 587 system_reg = GEN_INT (__NDS32_REG_INT_TRIGGER2__); 588 offset = 32; 589 } 590 else 591 error ("__nds32__get_trig_type not support NDS32_INT_SWI," 592 " NDS32_INT_ALZ, NDS32_INT_IDIVZE, NDS32_INT_DSSIM"); 593 594 if (system_reg != NULL_RTX) 595 { 596 trig_type = GEN_INT (31 - (INTVAL (operands[1]) - offset)); 597 598 emit_insn (gen_unspec_volatile_mfsr (operands[0], system_reg)); 599 emit_insn (gen_ashlsi3 (operands[0], operands[0], trig_type)); 600 emit_insn (gen_lshrsi3 (operands[0], operands[0], GEN_INT (31))); 601 emit_insn (gen_unspec_dsb ()); 602 } 603 DONE; 604}) 605 606;; ------------------------------------------------------------------------ 607 608;; Cache Synchronization Instructions 609 610(define_insn "unspec_volatile_isync" 611 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_ISYNC)] 612 "" 613 "isync\t%0" 614 [(set_attr "type" "misc")] 615) 616 617(define_insn "unspec_volatile_isb" 618 [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_ISB)] 619 "" 620 "isb" 621 [(set_attr "type" "misc")] 622) 623 624(define_insn "unspec_dsb" 625 [(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_DSB)] 626 "" 627 "dsb" 628 [(set_attr "type" "misc")] 629) 630 631(define_insn "unspec_msync" 632 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "i")] UNSPEC_VOLATILE_MSYNC)] 633 "" 634 "msync\t%0" 635 [(set_attr "type" "misc")] 636) 637 638(define_insn "unspec_msync_all" 639 [(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_MSYNC_ALL)] 640 "" 641 "msync\tall" 642 [(set_attr "type" "misc")] 643) 644 645(define_insn "unspec_msync_store" 646 [(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_MSYNC_STORE)] 647 "" 648 "msync\tstore" 649 [(set_attr "type" "misc")] 650) 651 652;; Load and Store 653 654(define_insn "unspec_volatile_llw" 655 [(set (match_operand:SI 0 "register_operand" "=r") 656 (unspec_volatile:SI [(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r") 657 (match_operand:SI 2 "register_operand" "r")))] UNSPEC_VOLATILE_LLW))] 658 "" 659 "llw\t%0, [%1 + %2]" 660 [(set_attr "length" "4")] 661) 662 663(define_insn "unspec_lwup" 664 [(set (match_operand:SI 0 "register_operand" "=r") 665 (unspec_volatile:SI [(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r") 666 (match_operand:SI 2 "register_operand" "r")))] UNSPEC_LWUP))] 667 "" 668 "lwup\t%0, [%1 + %2]" 669 [(set_attr "length" "4")] 670) 671 672(define_insn "unspec_lbup" 673 [(set (match_operand:SI 0 "register_operand" "=r") 674 (unspec_volatile:SI [(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r") 675 (match_operand:SI 2 "register_operand" "r")))] UNSPEC_LBUP))] 676 "" 677 "lbup\t%0, [%1 + %2]" 678 [(set_attr "length" "4")] 679) 680 681(define_insn "unspec_volatile_scw" 682 [(set (match_operand:SI 0 "register_operand" "=r") 683 (unspec_volatile:SI [(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r") 684 (match_operand:SI 2 "register_operand" "r"))) 685 (match_operand:SI 3 "register_operand" "0")] UNSPEC_VOLATILE_SCW))] 686 "" 687 "scw\t%0, [%1 + %2]" 688 [(set_attr "length" "4")] 689) 690 691(define_insn "unspec_swup" 692 [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r") 693 (match_operand:SI 1 "register_operand" "r"))) 694 (unspec:SI [(match_operand:SI 2 "register_operand" "r")] UNSPEC_SWUP))] 695 "" 696 "swup\t%2, [%0 + %1]" 697 [(set_attr "length" "4")] 698) 699 700(define_insn "unspec_sbup" 701 [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r") 702 (match_operand:SI 1 "register_operand" "r"))) 703 (unspec:SI [(match_operand:SI 2 "register_operand" "r")] UNSPEC_SBUP))] 704 "" 705 "sbup\t%2, [%0 + %1]" 706 [(set_attr "length" "4")] 707) 708 709;; CCTL 710 711(define_insn "cctl_l1d_invalall" 712 [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_CCTL_L1D_INVALALL)] 713 "" 714 "cctl\tL1D_INVALALL" 715 [(set_attr "type" "mmu")] 716) 717 718(define_insn "cctl_l1d_wball_alvl" 719 [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_CCTL_L1D_WBALL_ALVL)] 720 "" 721 "cctl\tL1D_WBALL, alevel" 722 [(set_attr "type" "mmu")] 723) 724 725(define_insn "cctl_l1d_wball_one_lvl" 726 [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_CCTL_L1D_WBALL_ONE_LVL)] 727 "" 728 "cctl\tL1D_WBALL, 1level" 729 [(set_attr "type" "mmu")] 730) 731 732(define_insn "cctl_idx_read" 733 [(set (match_operand:SI 0 "register_operand" "=r") 734 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "i") 735 (match_operand:SI 2 "register_operand" "r")] UNSPEC_VOLATILE_CCTL_IDX_READ))] 736 "" 737 "cctl\t%0, %2, %X1" 738 [(set_attr "type" "mmu")] 739) 740 741(define_insn "cctl_idx_write" 742 [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i") 743 (match_operand:SI 1 "register_operand" "r") 744 (match_operand:SI 2 "register_operand" "r")] UNSPEC_VOLATILE_CCTL_IDX_WRITE)] 745 "" 746 "cctl\t%1, %2, %W0" 747 [(set_attr "type" "mmu")] 748) 749 750(define_insn "cctl_va_wbinval_l1" 751 [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i") 752 (match_operand:SI 1 "register_operand" "r")] UNSPEC_VOLATILE_CCTL_VA_WBINVAL_L1)] 753 "" 754 "cctl\t%1, %U0, 1level" 755 [(set_attr "type" "mmu")] 756) 757 758(define_insn "cctl_va_wbinval_la" 759 [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i") 760 (match_operand:SI 1 "register_operand" "r")] UNSPEC_VOLATILE_CCTL_VA_WBINVAL_LA)] 761 "" 762 "cctl\t%1, %U0, alevel" 763 [(set_attr "type" "mmu")] 764) 765 766(define_insn "cctl_idx_wbinval" 767 [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i") 768 (match_operand:SI 1 "register_operand" "r")] UNSPEC_VOLATILE_CCTL_IDX_WBINVAL)] 769 "" 770 "cctl\t%1, %T0" 771 [(set_attr "type" "mmu")] 772) 773 774(define_insn "cctl_va_lck" 775 [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i") 776 (match_operand:SI 1 "register_operand" "r")] UNSPEC_VOLATILE_CCTL_VA_LCK)] 777 "" 778 "cctl\t%1, %R0" 779 [(set_attr "type" "mmu")] 780) 781 782;;PREFETCH 783 784(define_insn "prefetch_qw" 785 [(unspec_volatile:QI [(match_operand:SI 0 "register_operand" "r") 786 (match_operand:SI 1 "nonmemory_operand" "r") 787 (match_operand:SI 2 "immediate_operand" "i")] UNSPEC_VOLATILE_DPREF_QW)] 788 "" 789 "dpref\t%Z2, [%0 + %1]" 790 [(set_attr "type" "misc")] 791) 792 793(define_insn "prefetch_hw" 794 [(unspec_volatile:HI [(match_operand:SI 0 "register_operand" "r") 795 (match_operand:SI 1 "nonmemory_operand" "r") 796 (match_operand:SI 2 "immediate_operand" "i")] UNSPEC_VOLATILE_DPREF_HW)] 797 "" 798 "dpref\t%Z2, [%0 + (%1<<1)]" 799 [(set_attr "type" "misc")] 800) 801 802(define_insn "prefetch_w" 803 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" " r, r") 804 (match_operand:SI 1 "nonmemory_operand" "Is15, r") 805 (match_operand:SI 2 "immediate_operand" " i, i")] UNSPEC_VOLATILE_DPREF_W)] 806 "" 807 "@ 808 dprefi.w\t%Z2, [%0 + %1] 809 dpref\t%Z2, [%0 + (%1<<2)]" 810 [(set_attr "type" "misc")] 811) 812 813(define_insn "prefetch_dw" 814 [(unspec_volatile:DI [(match_operand:SI 0 "register_operand" " r, r") 815 (match_operand:SI 1 "nonmemory_operand" "Is15, r") 816 (match_operand:SI 2 "immediate_operand" " i, i")] UNSPEC_VOLATILE_DPREF_DW)] 817 "" 818 "@ 819 dprefi.d\t%Z2, [%0 + %1] 820 dpref\t%Z2, [%0 + (%1<<3)]" 821 [(set_attr "type" "misc")] 822) 823 824;; Performance Extension 825 826(define_expand "unspec_ave" 827 [(match_operand:SI 0 "register_operand" "") 828 (match_operand:SI 1 "register_operand" "") 829 (match_operand:SI 2 "register_operand" "")] 830 "" 831{ 832 emit_insn (gen_ave (operands[0], operands[1], operands[2])); 833 DONE; 834}) 835 836(define_expand "unspec_bclr" 837 [(match_operand:SI 0 "register_operand" "") 838 (match_operand:SI 1 "register_operand" "") 839 (match_operand:SI 2 "immediate_operand" "")] 840 "" 841{ 842 unsigned HOST_WIDE_INT val = ~(1u << UINTVAL (operands[2])); 843 emit_insn (gen_andsi3 (operands[0], operands[1], gen_int_mode (val, SImode))); 844 DONE; 845}) 846 847(define_expand "unspec_bset" 848 [(match_operand:SI 0 "register_operand" "") 849 (match_operand:SI 1 "register_operand" "") 850 (match_operand:SI 2 "immediate_operand" "")] 851 "" 852{ 853 unsigned HOST_WIDE_INT val = 1u << UINTVAL (operands[2]); 854 emit_insn (gen_iorsi3 (operands[0], operands[1], gen_int_mode (val, SImode))); 855 DONE; 856}) 857 858(define_expand "unspec_btgl" 859 [(match_operand:SI 0 "register_operand" "") 860 (match_operand:SI 1 "register_operand" "") 861 (match_operand:SI 2 "immediate_operand" "")] 862 "" 863{ 864 unsigned HOST_WIDE_INT val = 1u << UINTVAL (operands[2]); 865 emit_insn (gen_xorsi3 (operands[0], operands[1], gen_int_mode (val, SImode))); 866 DONE; 867}) 868 869(define_expand "unspec_btst" 870 [(match_operand:SI 0 "register_operand" "") 871 (match_operand:SI 1 "register_operand" "") 872 (match_operand:SI 2 "immediate_operand" "")] 873 "" 874{ 875 emit_insn (gen_btst (operands[0], operands[1], operands[2])); 876 DONE; 877}) 878 879(define_insn "unspec_clip" 880 [(set (match_operand:SI 0 "register_operand" "=r") 881 (unspec:SI [(match_operand:SI 1 "register_operand" "r") 882 (match_operand:SI 2 "immediate_operand" "i")] UNSPEC_CLIP))] 883 "" 884 "clip\t%0, %1, %2" 885 [(set_attr "type" "alu") 886 (set_attr "length" "4")] 887) 888 889(define_insn "unspec_clips" 890 [(set (match_operand:SI 0 "register_operand" "=r") 891 (unspec:SI [(match_operand:SI 1 "register_operand" "r") 892 (match_operand:SI 2 "immediate_operand" "i")] UNSPEC_CLIPS))] 893 "" 894 "clips\t%0, %1, %2" 895 [(set_attr "type" "alu") 896 (set_attr "length" "4")] 897) 898 899(define_insn "unspec_clo" 900 [(set (match_operand:SI 0 "register_operand" "=r") 901 (unspec:SI [(match_operand:SI 1 "register_operand" "r")] UNSPEC_CLO))] 902 "" 903 "clo\t%0, %1" 904 [(set_attr "type" "alu") 905 (set_attr "length" "4")] 906) 907 908(define_insn "unspec_ssabssi2" 909 [(set (match_operand:SI 0 "register_operand" "=r") 910 (ss_abs:SI (match_operand:SI 1 "register_operand" "r")))] 911 "" 912 "abs\t%0, %1" 913 [(set_attr "type" "alu") 914 (set_attr "length" "4")] 915) 916 917;; Performance extension 2 918 919(define_insn "unspec_pbsad" 920 [(set (match_operand:SI 0 "register_operand" "=r") 921 (unspec:SI [(match_operand:SI 1 "register_operand" "r") 922 (match_operand:SI 2 "register_operand" "r")] UNSPEC_PBSAD))] 923 "" 924 "pbsad\t%0, %1, %2" 925 [(set_attr "type" "pbsad") 926 (set_attr "length" "4")] 927) 928 929(define_insn "unspec_pbsada" 930 [(set (match_operand:SI 0 "register_operand" "=r") 931 (unspec:SI [(match_operand:SI 1 "register_operand" "0") 932 (match_operand:SI 2 "register_operand" "r") 933 (match_operand:SI 3 "register_operand" "r")] UNSPEC_PBSADA))] 934 "" 935 "pbsada\t%0, %2, %3" 936 [(set_attr "type" "pbsada") 937 (set_attr "length" "4")] 938) 939 940(define_expand "bse" 941 [(match_operand:SI 0 "register_operand" "") 942 (match_operand:SI 1 "register_operand" "") 943 (match_operand:SI 2 "register_operand" "")] 944 "" 945 { 946 rtx temp0 = gen_reg_rtx (SImode); 947 rtx temp2 = gen_reg_rtx (SImode); 948 949 emit_move_insn (temp0, gen_rtx_MEM (Pmode, operands[0])); 950 emit_move_insn (temp2, gen_rtx_MEM (Pmode, operands[2])); 951 emit_insn (gen_unspec_bse (temp0, operands[1], temp2, temp0, temp2)); 952 emit_move_insn (gen_rtx_MEM (Pmode, operands[0]), temp0); 953 emit_move_insn (gen_rtx_MEM (Pmode, operands[2]), temp2); 954 DONE; 955 } 956) 957 958(define_insn "unspec_bse" 959 [(set (match_operand:SI 0 "register_operand" "=r") 960 (unspec:SI [(match_operand:SI 1 "register_operand" "r") 961 (match_operand:SI 2 "register_operand" "r") 962 (match_operand:SI 3 "register_operand" "0")] UNSPEC_BSE)) 963 (set (match_operand:SI 4 "register_operand" "=2") 964 (unspec:SI [(match_dup 1) 965 (match_dup 2) 966 (match_dup 0)] UNSPEC_BSE_2))] 967 "" 968 "bse\t%0, %1, %2" 969 [(set_attr "type" "alu") 970 (set_attr "length" "4")] 971) 972 973(define_expand "bsp" 974 [(match_operand:SI 0 "register_operand" "") 975 (match_operand:SI 1 "register_operand" "") 976 (match_operand:SI 2 "register_operand" "")] 977 "" 978 { 979 rtx temp0 = gen_reg_rtx (SImode); 980 rtx temp2 = gen_reg_rtx (SImode); 981 982 emit_move_insn (temp0, gen_rtx_MEM (Pmode, operands[0])); 983 emit_move_insn (temp2, gen_rtx_MEM (Pmode, operands[2])); 984 emit_insn (gen_unspec_bsp (temp0, operands[1], temp2, temp0, temp2)); 985 emit_move_insn (gen_rtx_MEM (Pmode, operands[0]), temp0); 986 emit_move_insn (gen_rtx_MEM (Pmode, operands[2]), temp2); 987 DONE; 988 } 989) 990 991(define_insn "unspec_bsp" 992 [(set (match_operand:SI 0 "register_operand" "=r") 993 (unspec:SI [(match_operand:SI 1 "register_operand" "r") 994 (match_operand:SI 2 "register_operand" "r") 995 (match_operand:SI 3 "register_operand" "0")] UNSPEC_BSP)) 996 (set (match_operand:SI 4 "register_operand" "=2") 997 (unspec:SI [(match_dup 1) 998 (match_dup 2) 999 (match_dup 0)] UNSPEC_BSP_2))] 1000 "" 1001 "bsp\t%0, %1, %2" 1002 [(set_attr "type" "alu") 1003 (set_attr "length" "4")] 1004) 1005 1006;; String Extension 1007 1008(define_insn "unspec_ffb" 1009 [(set (match_operand:SI 0 "register_operand" "=r, r") 1010 (unspec:SI [(match_operand:SI 1 "register_operand" "r, r") 1011 (match_operand:SI 2 "nonmemory_operand" "Iu08, r")] UNSPEC_FFB))] 1012 "" 1013 "@ 1014 ffbi\t%0, %1, %2 1015 ffb\t%0, %1, %2" 1016 [(set_attr "type" "alu") 1017 (set_attr "length" "4")] 1018) 1019 1020(define_insn "unspec_ffmism" 1021 [(set (match_operand:SI 0 "register_operand" "=r") 1022 (unspec:SI [(match_operand:SI 1 "register_operand" "r") 1023 (match_operand:SI 2 "register_operand" "r")] UNSPEC_FFMISM))] 1024 "" 1025 "ffmism\t%0, %1, %2" 1026 [(set_attr "type" "alu") 1027 (set_attr "length" "4")] 1028) 1029 1030(define_insn "unspec_flmism" 1031 [(set (match_operand:SI 0 "register_operand" "=r") 1032 (unspec:SI [(match_operand:SI 1 "register_operand" "r") 1033 (match_operand:SI 2 "register_operand" "r")] UNSPEC_FLMISM))] 1034 "" 1035 "flmism\t%0, %1, %2" 1036 [(set_attr "type" "alu") 1037 (set_attr "length" "4")] 1038) 1039 1040;; SATURATION 1041 1042(define_insn "unspec_kaddw" 1043 [(set (match_operand:SI 0 "register_operand" "=r") 1044 (ss_plus:SI (match_operand:SI 1 "register_operand" "r") 1045 (match_operand:SI 2 "register_operand" "r")))] 1046 "" 1047 "kaddw\t%0, %1, %2" 1048 [(set_attr "type" "alu") 1049 (set_attr "length" "4")] 1050) 1051 1052(define_insn "unspec_ksubw" 1053 [(set (match_operand:SI 0 "register_operand" "=r") 1054 (ss_minus:SI (match_operand:SI 1 "register_operand" "r") 1055 (match_operand:SI 2 "register_operand" "r")))] 1056 "" 1057 "ksubw\t%0, %1, %2" 1058 [(set_attr "type" "alu") 1059 (set_attr "length" "4")] 1060) 1061 1062(define_insn "unspec_kaddh" 1063 [(set (match_operand:SI 0 "register_operand" "=r") 1064 (unspec:SI [(match_operand:SI 1 "register_operand" "r") 1065 (match_operand:SI 2 "register_operand" "r")] UNSPEC_KADDH))] 1066 "" 1067 "kaddh\t%0, %1, %2" 1068 [(set_attr "type" "alu") 1069 (set_attr "length" "4")] 1070) 1071 1072(define_insn "unspec_ksubh" 1073 [(set (match_operand:SI 0 "register_operand" "=r") 1074 (unspec:SI [(match_operand:SI 1 "register_operand" "r") 1075 (match_operand:SI 2 "register_operand" "r")] UNSPEC_KSUBH))] 1076 "" 1077 "ksubh\t%0, %1, %2" 1078 [(set_attr "type" "alu") 1079 (set_attr "length" "4")] 1080) 1081 1082(define_insn "unspec_kaddh_dsp" 1083 [(set (match_operand:SI 0 "register_operand" "=r") 1084 (unspec:SI [(plus:SI (match_operand:SI 1 "register_operand" "r") 1085 (match_operand:SI 2 "register_operand" "r")) 1086 (const_int 15)] UNSPEC_CLIPS))] 1087 "NDS32_EXT_DSP_P ()" 1088 "kaddh\t%0, %1, %2" 1089 [(set_attr "type" "alu") 1090 (set_attr "length" "4")] 1091) 1092 1093(define_insn "unspec_ksubh_dsp" 1094 [(set (match_operand:SI 0 "register_operand" "=r") 1095 (unspec:SI [(minus:SI (match_operand:SI 1 "register_operand" "r") 1096 (match_operand:SI 2 "register_operand" "r")) 1097 (const_int 15)] UNSPEC_CLIPS))] 1098 "NDS32_EXT_DSP_P ()" 1099 "ksubh\t%0, %1, %2" 1100 [(set_attr "type" "alu") 1101 (set_attr "length" "4")] 1102) 1103 1104(define_insn "unspec_kdmbb" 1105 [(set (match_operand:V2HI 0 "register_operand" "=r") 1106 (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r") 1107 (match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KDMBB))] 1108 "" 1109 "kdmbb\t%0, %1, %2" 1110 [(set_attr "type" "mul") 1111 (set_attr "length" "4")] 1112) 1113 1114(define_insn "unspec_kdmbt" 1115 [(set (match_operand:V2HI 0 "register_operand" "=r") 1116 (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r") 1117 (match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KDMBT))] 1118 "" 1119 "kdmbt\t%0, %1, %2" 1120 [(set_attr "type" "mul") 1121 (set_attr "length" "4")] 1122) 1123 1124(define_insn "unspec_kdmtb" 1125 [(set (match_operand:V2HI 0 "register_operand" "=r") 1126 (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r") 1127 (match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KDMTB))] 1128 "" 1129 "kdmtb\t%0, %1, %2" 1130 [(set_attr "type" "mul") 1131 (set_attr "length" "4")] 1132) 1133 1134(define_insn "unspec_kdmtt" 1135 [(set (match_operand:V2HI 0 "register_operand" "=r") 1136 (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r") 1137 (match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KDMTT))] 1138 "" 1139 "kdmtt\t%0, %1, %2" 1140 [(set_attr "type" "mul") 1141 (set_attr "length" "4")] 1142) 1143 1144(define_insn "unspec_khmbb" 1145 [(set (match_operand:V2HI 0 "register_operand" "=r") 1146 (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r") 1147 (match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KHMBB))] 1148 "" 1149 "khmbb\t%0, %1, %2" 1150 [(set_attr "type" "mul") 1151 (set_attr "length" "4")] 1152) 1153 1154(define_insn "unspec_khmbt" 1155 [(set (match_operand:V2HI 0 "register_operand" "=r") 1156 (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r") 1157 (match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KHMBT))] 1158 "" 1159 "khmbt\t%0, %1, %2" 1160 [(set_attr "type" "mul") 1161 (set_attr "length" "4")] 1162) 1163 1164(define_insn "unspec_khmtb" 1165 [(set (match_operand:V2HI 0 "register_operand" "=r") 1166 (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r") 1167 (match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KHMTB))] 1168 "" 1169 "khmtb\t%0, %1, %2" 1170 [(set_attr "type" "mul") 1171 (set_attr "length" "4")] 1172) 1173 1174(define_insn "unspec_khmtt" 1175 [(set (match_operand:V2HI 0 "register_operand" "=r") 1176 (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r") 1177 (match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KHMTT))] 1178 "" 1179 "khmtt\t%0, %1, %2" 1180 [(set_attr "type" "mul") 1181 (set_attr "length" "4")] 1182) 1183 1184(define_insn "unspec_kslraw" 1185 [(set (match_operand:SI 0 "register_operand" "=r") 1186 (unspec:SI [(match_operand:SI 1 "register_operand" "r") 1187 (match_operand:SI 2 "register_operand" "r")] UNSPEC_KSLRAW))] 1188 "" 1189 "kslraw\t%0, %1, %2" 1190 [(set_attr "type" "alu") 1191 (set_attr "length" "4")] 1192) 1193 1194(define_insn "unspec_kslrawu" 1195 [(set (match_operand:SI 0 "register_operand" "=r") 1196 (unspec:SI [(match_operand:SI 1 "register_operand" "r") 1197 (match_operand:SI 2 "register_operand" "r")] UNSPEC_KSLRAWU))] 1198 "" 1199 "kslraw.u\t%0, %1, %2" 1200 [(set_attr "type" "alu") 1201 (set_attr "length" "4")] 1202) 1203 1204(define_insn "unspec_volatile_rdov" 1205 [(set (match_operand:SI 0 "register_operand" "=r") 1206 (unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_RDOV))] 1207 "" 1208 "rdov\t%0" 1209 [(set_attr "type" "misc") 1210 (set_attr "length" "4")] 1211) 1212 1213(define_insn "unspec_volatile_clrov" 1214 [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_CLROV)] 1215 "" 1216 "clrov" 1217 [(set_attr "type" "misc") 1218 (set_attr "length" "4")] 1219) 1220 1221;; System 1222 1223(define_insn "unspec_sva" 1224 [(set (match_operand:SI 0 "register_operand" "=r") 1225 (unspec:SI [(match_operand:SI 1 "register_operand" "r") 1226 (match_operand:SI 2 "register_operand" "r")] UNSPEC_SVA))] 1227 "" 1228 "sva\t%0, %1, %2" 1229 [(set_attr "type" "alu") 1230 (set_attr "length" "4")] 1231) 1232 1233(define_insn "unspec_svs" 1234 [(set (match_operand:SI 0 "register_operand" "=r") 1235 (unspec:SI [(match_operand:SI 1 "register_operand" "r") 1236 (match_operand:SI 2 "register_operand" "r")] UNSPEC_SVS))] 1237 "" 1238 "svs\t%0, %1, %2" 1239 [(set_attr "type" "alu") 1240 (set_attr "length" "4")] 1241) 1242 1243(define_insn "unspec_jr_itoff" 1244 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_JR_ITOFF)] 1245 "" 1246 "jr.itoff\t%0" 1247 [(set_attr "type" "misc")] 1248) 1249 1250(define_insn "unspec_jr_toff" 1251 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_JR_TOFF)] 1252 "" 1253 "jr.toff\t%0" 1254 [(set_attr "type" "branch")] 1255) 1256 1257(define_insn "unspec_jral_iton" 1258 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_JRAL_ITON)] 1259 "" 1260 "jral.iton\t%0" 1261 [(set_attr "type" "branch")] 1262) 1263 1264(define_insn "unspec_jral_ton" 1265 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_JRAL_TON)] 1266 "" 1267 "jral.ton\t%0" 1268 [(set_attr "type" "branch")] 1269) 1270 1271(define_insn "unspec_ret_itoff" 1272 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_RET_ITOFF)] 1273 "" 1274 "ret.itoff\t%0" 1275 [(set_attr "type" "branch")] 1276) 1277 1278(define_insn "unspec_ret_toff" 1279 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_RET_TOFF)] 1280 "" 1281 "ret.toff\t%0" 1282 [(set_attr "type" "branch")] 1283) 1284 1285(define_insn "unspec_standby_no_wake_grant" 1286 [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_STANDBY_NO_WAKE_GRANT)] 1287 "" 1288 "standby\tno_wake_grant" 1289 [(set_attr "type" "misc")] 1290) 1291 1292(define_insn "unspec_standby_wake_grant" 1293 [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_STANDBY_WAKE_GRANT)] 1294 "" 1295 "standby\twake_grant" 1296 [(set_attr "type" "misc")] 1297) 1298 1299(define_insn "unspec_standby_wait_done" 1300 [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_STANDBY_WAKE_DONE)] 1301 "" 1302 "standby\twait_done" 1303 [(set_attr "type" "misc")] 1304) 1305 1306(define_insn "unspec_teqz" 1307 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r") 1308 (match_operand:SI 1 "immediate_operand" "i")] UNSPEC_VOLATILE_TEQZ)] 1309 "" 1310 "teqz\t%0, %1" 1311 [(set_attr "type" "misc")] 1312) 1313 1314(define_insn "unspec_tnez" 1315 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r") 1316 (match_operand:SI 1 "immediate_operand" "i")] UNSPEC_VOLATILE_TNEZ)] 1317 "" 1318 "tnez\t%0, %1" 1319 [(set_attr "type" "misc")] 1320) 1321 1322(define_insn "unspec_trap" 1323 [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")] UNSPEC_VOLATILE_TRAP)] 1324 "" 1325 "trap\t%0" 1326 [(set_attr "type" "misc")] 1327) 1328 1329(define_insn "unspec_setend_big" 1330 [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_SETEND_BIG)] 1331 "" 1332 "setend.b" 1333 [(set_attr "type" "misc")] 1334) 1335 1336(define_insn "unspec_setend_little" 1337 [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_SETEND_LITTLE)] 1338 "" 1339 "setend.l" 1340 [(set_attr "type" "misc")] 1341) 1342 1343(define_insn "unspec_break" 1344 [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")] UNSPEC_VOLATILE_BREAK)] 1345 "" 1346 "break\t%0" 1347 [(set_attr "type" "misc")] 1348) 1349 1350(define_insn "unspec_syscall" 1351 [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")] UNSPEC_VOLATILE_SYSCALL)] 1352 "" 1353 "syscall\t%0" 1354 [(set_attr "type" "misc")] 1355) 1356 1357(define_insn "unspec_nop" 1358 [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_NOP)] 1359 "" 1360 "nop" 1361 [(set_attr "type" "misc")] 1362) 1363 1364(define_expand "unspec_get_current_sp" 1365 [(match_operand:SI 0 "register_operand" "")] 1366 "" 1367{ 1368 emit_move_insn (operands[0], gen_rtx_REG (SImode, SP_REGNUM)); 1369 DONE; 1370}) 1371 1372(define_expand "unspec_set_current_sp" 1373 [(match_operand:SI 0 "register_operand" "")] 1374 "" 1375{ 1376 emit_move_insn (gen_rtx_REG (SImode, SP_REGNUM), operands[0]); 1377 DONE; 1378}) 1379 1380(define_expand "unspec_return_address" 1381 [(match_operand:SI 0 "register_operand" "")] 1382 "" 1383{ 1384 emit_move_insn (operands[0], gen_rtx_REG (SImode, LP_REGNUM)); 1385 DONE; 1386}) 1387 1388;; Swap 1389 1390(define_insn "unspec_wsbh" 1391 [(set (match_operand:SI 0 "register_operand" "=r") 1392 (unspec:SI [(match_operand:SI 1 "register_operand" "r")] UNSPEC_WSBH))] 1393 "" 1394 "wsbh\t%0, %1" 1395 [(set_attr "type" "alu") 1396 (set_attr "length" "4")] 1397) 1398 1399;; TLBOP Intrinsic 1400 1401(define_insn "unspec_tlbop_trd" 1402 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_TRD)] 1403 "" 1404 "tlbop\t%0, TRD" 1405 [(set_attr "type" "mmu")] 1406) 1407 1408(define_insn "unspec_tlbop_twr" 1409 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_TWR)] 1410 "" 1411 "tlbop\t%0, TWR" 1412 [(set_attr "type" "mmu")] 1413) 1414 1415(define_insn "unspec_tlbop_rwr" 1416 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_RWR)] 1417 "" 1418 "tlbop\t%0, RWR" 1419 [(set_attr "type" "mmu")] 1420) 1421 1422(define_insn "unspec_tlbop_rwlk" 1423 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_RWLK)] 1424 "" 1425 "tlbop\t%0, RWLK" 1426 [(set_attr "type" "mmu")] 1427) 1428 1429(define_insn "unspec_tlbop_unlk" 1430 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_UNLK)] 1431 "" 1432 "tlbop\t%0, UNLK" 1433 [(set_attr "type" "mmu")] 1434) 1435 1436(define_insn "unspec_tlbop_pb" 1437 [(set (match_operand:SI 0 "register_operand" "=r") 1438 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_PB))] 1439 "" 1440 "tlbop\t%0, %1, PB" 1441 [(set_attr "type" "mmu")] 1442) 1443 1444(define_insn "unspec_tlbop_inv" 1445 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_INV)] 1446 "" 1447 "tlbop\t%0, INV" 1448 [(set_attr "type" "mmu")] 1449) 1450 1451(define_insn "unspec_tlbop_flua" 1452 [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_TLBOP_FLUA)] 1453 "" 1454 "tlbop\tFLUA" 1455 [(set_attr "type" "mmu")] 1456) 1457 1458;;Unaligned Load/Store 1459 1460(define_expand "unaligned_load_hw" 1461 [(set (match_operand:HI 0 "register_operand" "") 1462 (unspec:HI [(mem:HI (match_operand:SI 1 "register_operand" ""))] UNSPEC_UALOAD_HW))] 1463 "" 1464{ 1465 operands[0] = simplify_gen_subreg (SImode, operands[0], 1466 GET_MODE (operands[0]), 0); 1467 if (TARGET_ISA_V3M) 1468 { 1469 nds32_expand_unaligned_load (operands, HImode); 1470 } 1471 else 1472 { 1473 emit_insn (gen_unaligned_load_w (operands[0], 1474 gen_rtx_MEM (SImode, operands[1]))); 1475 1476 if (WORDS_BIG_ENDIAN) 1477 emit_insn (gen_lshrsi3 (operands[0], operands[0], GEN_INT(16))); 1478 else 1479 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0xffff))); 1480 } 1481 1482 DONE; 1483}) 1484 1485(define_expand "unaligned_loadsi" 1486 [(set (match_operand:SI 0 "register_operand" "=r") 1487 (unspec:SI [(mem:SI (match_operand:SI 1 "register_operand" "r"))] UNSPEC_UALOAD_W))] 1488 "" 1489{ 1490 if (flag_unaligned_access) 1491 { 1492 rtx mem = gen_rtx_MEM (SImode, operands[1]); 1493 emit_move_insn (operands[0], mem); 1494 } 1495 else 1496 { 1497 if (TARGET_ISA_V3M) 1498 nds32_expand_unaligned_load (operands, SImode); 1499 else 1500 emit_insn (gen_unaligned_load_w (operands[0], 1501 gen_rtx_MEM (SImode, (operands[1])))); 1502 } 1503 DONE; 1504}) 1505 1506(define_insn "unaligned_load_w" 1507 [(set (match_operand:SI 0 "register_operand" "= r") 1508 (unspec:SI [(match_operand:SI 1 "nds32_lmw_smw_base_operand" " Umw")] UNSPEC_UALOAD_W))] 1509 "" 1510{ 1511 return nds32_output_lmw_single_word (operands); 1512} 1513 [(set_attr "type" "load") 1514 (set_attr "length" "4")] 1515) 1516 1517(define_expand "unaligned_loaddi" 1518 [(set (match_operand:DI 0 "register_operand" "=r") 1519 (unspec:DI [(mem:DI (match_operand:SI 1 "register_operand" "r"))] UNSPEC_UALOAD_DW))] 1520 "" 1521{ 1522 if (TARGET_ISA_V3M) 1523 { 1524 nds32_expand_unaligned_load (operands, DImode); 1525 } 1526 else 1527 emit_insn (gen_unaligned_load_dw (operands[0], operands[1])); 1528 DONE; 1529}) 1530 1531(define_insn "unaligned_load_dw" 1532 [(set (match_operand:DI 0 "register_operand" "=r") 1533 (unspec:DI [(mem:DI (match_operand:SI 1 "register_operand" "r"))] UNSPEC_UALOAD_DW))] 1534 "" 1535{ 1536 rtx otherops[3]; 1537 otherops[0] = gen_rtx_REG (SImode, REGNO (operands[0])); 1538 otherops[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); 1539 otherops[2] = operands[1]; 1540 1541 output_asm_insn ("lmw.bi\t%0, [%2], %1, 0", otherops); 1542 return ""; 1543} 1544 [(set_attr "type" "load") 1545 (set_attr "length" "4")] 1546) 1547 1548(define_expand "unaligned_store_hw" 1549 [(set (mem:SI (match_operand:SI 0 "register_operand" "")) 1550 (unspec:HI [(match_operand:HI 1 "register_operand" "")] UNSPEC_UASTORE_HW))] 1551 "" 1552{ 1553 operands[1] = simplify_gen_subreg (SImode, operands[1], 1554 GET_MODE (operands[1]), 0); 1555 nds32_expand_unaligned_store (operands, HImode); 1556 DONE; 1557}) 1558 1559(define_expand "unaligned_storesi" 1560 [(set (mem:SI (match_operand:SI 0 "register_operand" "r")) 1561 (unspec:SI [(match_operand:SI 1 "register_operand" "r")] UNSPEC_UASTORE_W))] 1562 "" 1563{ 1564 if (flag_unaligned_access) 1565 { 1566 rtx mem = gen_rtx_MEM (SImode, operands[0]); 1567 emit_move_insn (mem, operands[1]); 1568 } 1569 else 1570 { 1571 if (TARGET_ISA_V3M) 1572 nds32_expand_unaligned_store (operands, SImode); 1573 else 1574 emit_insn (gen_unaligned_store_w (gen_rtx_MEM (SImode, operands[0]), 1575 operands[1])); 1576 } 1577 DONE; 1578}) 1579 1580(define_insn "unaligned_store_w" 1581 [(set (match_operand:SI 0 "nds32_lmw_smw_base_operand" "=Umw") 1582 (unspec:SI [(match_operand:SI 1 "register_operand" " r")] UNSPEC_UASTORE_W))] 1583 "" 1584{ 1585 return nds32_output_smw_single_word (operands); 1586} 1587 [(set_attr "type" "store") 1588 (set_attr "length" "4")] 1589) 1590 1591(define_expand "unaligned_storedi" 1592 [(set (mem:DI (match_operand:SI 0 "register_operand" "r")) 1593 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_UASTORE_DW))] 1594 "" 1595{ 1596 if (TARGET_ISA_V3M) 1597 nds32_expand_unaligned_store (operands, DImode); 1598 else 1599 emit_insn (gen_unaligned_store_dw (gen_rtx_MEM (DImode, operands[0]), 1600 operands[1])); 1601 DONE; 1602}) 1603 1604(define_insn "unaligned_store_dw" 1605 [(set (match_operand:DI 0 "nds32_lmw_smw_base_operand" "=Umw") 1606 (unspec:DI [(match_operand:DI 1 "register_operand" " r")] UNSPEC_UASTORE_DW))] 1607 "" 1608{ 1609 return nds32_output_smw_double_word (operands); 1610} 1611 [(set_attr "type" "store") 1612 (set_attr "length" "4")] 1613) 1614 1615(define_expand "unspec_unaligned_feature" 1616 [(set (match_operand:SI 0 "register_operand" "") 1617 (unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_UNALIGNED_FEATURE))] 1618 "" 1619{ 1620 /* Get $MMU_CTL system register form nds32_intrinsic_register_names[] */ 1621 rtx system_reg = GEN_INT (__NDS32_REG_MMU_CTL__); 1622 rtx temp_reg = gen_reg_rtx (SImode); 1623 rtx temp2_reg = gen_reg_rtx (SImode); 1624 1625 emit_insn (gen_unspec_volatile_mfsr (operands[0], system_reg)); 1626 emit_move_insn (temp_reg, operands[0]); 1627 emit_move_insn (temp2_reg, GEN_INT (0x800 << 12)); 1628 emit_insn (gen_iorsi3 (operands[0], operands[0], temp2_reg)); 1629 emit_insn (gen_unspec_volatile_mtsr (operands[0], system_reg)); 1630 emit_insn (gen_unspec_dsb ()); 1631 1632 emit_insn (gen_unspec_volatile_mfsr (operands[0], system_reg)); 1633 emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg)); 1634 emit_insn (gen_unspec_dsb ()); 1635 1636 emit_insn (gen_ashlsi3 (operands[0], operands[0], GEN_INT (8))); 1637 emit_insn (gen_lshrsi3 (operands[0], operands[0], GEN_INT (31))); 1638 DONE; 1639}) 1640 1641(define_expand "unspec_enable_unaligned" 1642 [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_UNALIGNED_FEATURE)] 1643 "" 1644{ 1645 /* Get $MMU_CTL system register form nds32_intrinsic_register_names[] */ 1646 rtx system_reg = GEN_INT (__NDS32_REG_MMU_CTL__); 1647 rtx temp_reg = gen_reg_rtx (SImode); 1648 rtx temp2_reg = gen_reg_rtx (SImode); 1649 emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg)); 1650 emit_move_insn (temp2_reg, GEN_INT (0x800 << 12)); 1651 emit_insn (gen_iorsi3 (temp_reg, temp_reg, temp2_reg)); 1652 emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg)); 1653 emit_insn (gen_unspec_dsb ()); 1654 DONE; 1655}) 1656 1657(define_expand "unspec_disable_unaligned" 1658 [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_UNALIGNED_FEATURE)] 1659 "" 1660{ 1661 /* Get $MMU_CTL system register form nds32_intrinsic_register_names[] */ 1662 rtx system_reg = GEN_INT (__NDS32_REG_MMU_CTL__); 1663 rtx temp_reg = gen_reg_rtx (SImode); 1664 rtx temp2_reg = gen_reg_rtx (SImode); 1665 emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg)); 1666 emit_move_insn (temp2_reg, GEN_INT (0x800 << 12)); 1667 emit_insn (gen_one_cmplsi2 (temp2_reg, temp2_reg)); 1668 emit_insn (gen_andsi3 (temp_reg, temp_reg, temp2_reg)); 1669 emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg)); 1670 emit_insn (gen_unspec_dsb ()); 1671 DONE; 1672}) 1673 1674;; abs alias kabs 1675 1676(define_insn "unspec_kabs" 1677 [(set (match_operand:SI 0 "register_operand" "=r") 1678 (unspec:SI [(match_operand:SI 1 "register_operand" "r")] UNSPEC_KABS))] 1679 "" 1680 "kabs\t%0, %1" 1681 [(set_attr "type" "alu") 1682 (set_attr "length" "4")] 1683) 1684 1685;; ------------------------------------------------------------------------ 1686