nds32-intrinsic.c revision 1.4
1/* Intrinsic functions of Andes NDS32 cpu for GNU compiler 2 Copyright (C) 2012-2018 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#define IN_TARGET_CODE 1 24 25#include "config.h" 26#include "system.h" 27#include "coretypes.h" 28#include "backend.h" 29#include "target.h" 30#include "rtl.h" 31#include "memmodel.h" 32#include "emit-rtl.h" 33#include "tree.h" 34#include "memmodel.h" 35#include "optabs.h" /* For GEN_FCN. */ 36#include "diagnostic-core.h" 37#include "stor-layout.h" 38#include "expr.h" 39#include "langhooks.h" /* For add_builtin_function(). */ 40#include "recog.h" 41#include "explow.h" 42 43/* ------------------------------------------------------------------------ */ 44 45/* Read the requested argument from the EXP given by INDEX. 46 Return the value as an rtx. */ 47static rtx 48nds32_read_argument (tree exp, unsigned int index) 49{ 50 return expand_normal (CALL_EXPR_ARG (exp, index)); 51} 52 53/* Return a legitimate rtx for instruction ICODE's return value. Use TARGET 54 if it's not null, has the right mode, and satisfies operand 0's 55 predicate. */ 56static rtx 57nds32_legitimize_target (enum insn_code icode, rtx target) 58{ 59 enum machine_mode mode = insn_data[icode].operand[0].mode; 60 61 if (! target 62 || GET_MODE (target) != mode 63 || ! (*insn_data[icode].operand[0].predicate) (target, mode)) 64 return gen_reg_rtx (mode); 65 else 66 return target; 67} 68 69/* Given that ARG is being passed as operand OPNUM to instruction ICODE, 70 check whether ARG satisfies the operand's constraints. If it doesn't, 71 copy ARG to a temporary register and return that. Otherwise return ARG 72 itself. */ 73static rtx 74nds32_legitimize_argument (enum insn_code icode, int opnum, rtx arg) 75{ 76 enum machine_mode mode = insn_data[icode].operand[opnum].mode; 77 78 if ((*insn_data[icode].operand[opnum].predicate) (arg, mode)) 79 return arg; 80 else if (VECTOR_MODE_P (mode) && CONST_INT_P (arg)) 81 { 82 /* Handle CONST_INT covert to CONST_VECTOR. */ 83 int nunits = GET_MODE_NUNITS (mode); 84 int i, shift = 0; 85 rtvec v = rtvec_alloc (nunits); 86 int val = INTVAL (arg); 87 enum machine_mode val_mode = (mode == V4QImode) ? QImode : HImode; 88 int shift_acc = (val_mode == QImode) ? 8 : 16; 89 int mask = (val_mode == QImode) ? 0xff : 0xffff; 90 int tmp_val = val; 91 92 if (TARGET_BIG_ENDIAN) 93 for (i = 0; i < nunits; i++) 94 { 95 tmp_val = (val >> shift) & mask; 96 RTVEC_ELT (v, nunits - i - 1) = gen_int_mode (tmp_val, val_mode); 97 shift += shift_acc; 98 } 99 else 100 for (i = 0; i < nunits; i++) 101 { 102 tmp_val = (val >> shift) & mask; 103 RTVEC_ELT (v, i) = gen_int_mode (tmp_val, val_mode); 104 shift += shift_acc; 105 } 106 107 return copy_to_mode_reg (mode, gen_rtx_CONST_VECTOR (mode, v)); 108 } 109 else 110 { 111 rtx tmp_rtx = gen_reg_rtx (mode); 112 convert_move (tmp_rtx, arg, false); 113 return tmp_rtx; 114 } 115} 116 117/* Return true if OPVAL can be used for operand OPNUM of instruction ICODE. 118 The instruction should require a constant operand of some sort. The 119 function prints an error if OPVAL is not valid. */ 120static int 121nds32_check_constant_argument (enum insn_code icode, int opnum, rtx opval, 122 const char *name) 123{ 124 if (GET_CODE (opval) != CONST_INT) 125 { 126 error ("invalid argument to built-in function %s", name); 127 return false; 128 } 129 if (! (*insn_data[icode].operand[opnum].predicate) (opval, VOIDmode)) 130 { 131 error ("constant argument out of range for %s", name); 132 133 return false; 134 } 135 return true; 136} 137 138/* Expand builtins that return target. */ 139static rtx 140nds32_expand_noarg_builtin (enum insn_code icode, rtx target) 141{ 142 rtx pat; 143 144 target = nds32_legitimize_target (icode, target); 145 146 /* Emit and return the new instruction. */ 147 pat = GEN_FCN (icode) (target); 148 if (! pat) 149 return NULL_RTX; 150 151 emit_insn (pat); 152 return target; 153} 154 155/* Expand builtins that take one operand. */ 156static rtx 157nds32_expand_unop_builtin (enum insn_code icode, tree exp, rtx target, 158 bool return_p) 159{ 160 rtx pat; 161 rtx op0 = nds32_read_argument (exp, 0); 162 int op0_num = return_p ? 1 : 0; 163 164 if (return_p) 165 target = nds32_legitimize_target (icode, target); 166 167 op0 = nds32_legitimize_argument (icode, op0_num, op0); 168 169 /* Emit and return the new instruction. */ 170 if (return_p) 171 pat = GEN_FCN (icode) (target, op0); 172 else 173 pat = GEN_FCN (icode) (op0); 174 175 if (! pat) 176 return NULL_RTX; 177 178 emit_insn (pat); 179 return target; 180} 181 182/* Expand builtins that take one operands and the first is immediate. */ 183static rtx 184nds32_expand_unopimm_builtin (enum insn_code icode, tree exp, rtx target, 185 bool return_p, const char *name) 186{ 187 rtx pat; 188 rtx op0 = nds32_read_argument (exp, 0); 189 int op0_num = return_p ? 1 : 0; 190 191 if (return_p) 192 target = nds32_legitimize_target (icode, target); 193 194 if (!nds32_check_constant_argument (icode, op0_num, op0, name)) 195 return NULL_RTX; 196 197 op0 = nds32_legitimize_argument (icode, op0_num, op0); 198 199 /* Emit and return the new instruction. */ 200 if (return_p) 201 pat = GEN_FCN (icode) (target, op0); 202 else 203 pat = GEN_FCN (icode) (op0); 204 205 if (! pat) 206 return NULL_RTX; 207 208 emit_insn (pat); 209 return target; 210} 211 212/* Expand builtins that take two operands. */ 213static rtx 214nds32_expand_binop_builtin (enum insn_code icode, tree exp, rtx target, 215 bool return_p) 216{ 217 rtx pat; 218 rtx op0 = nds32_read_argument (exp, 0); 219 rtx op1 = nds32_read_argument (exp, 1); 220 int op0_num = return_p ? 1 : 0; 221 int op1_num = return_p ? 2 : 1; 222 223 if (return_p) 224 target = nds32_legitimize_target (icode, target); 225 226 op0 = nds32_legitimize_argument (icode, op0_num, op0); 227 op1 = nds32_legitimize_argument (icode, op1_num, op1); 228 229 /* Emit and return the new instruction. */ 230 if (return_p) 231 pat = GEN_FCN (icode) (target, op0, op1); 232 else 233 pat = GEN_FCN (icode) (op0, op1); 234 235 if (! pat) 236 return NULL_RTX; 237 238 emit_insn (pat); 239 return target; 240} 241 242/* Expand builtins that take two operands and the second is immediate. */ 243static rtx 244nds32_expand_binopimm_builtin (enum insn_code icode, tree exp, rtx target, 245 bool return_p, const char *name) 246{ 247 rtx pat; 248 rtx op0 = nds32_read_argument (exp, 0); 249 rtx op1 = nds32_read_argument (exp, 1); 250 int op0_num = return_p ? 1 : 0; 251 int op1_num = return_p ? 2 : 1; 252 253 if (return_p) 254 target = nds32_legitimize_target (icode, target); 255 256 if (!nds32_check_constant_argument (icode, op1_num, op1, name)) 257 return NULL_RTX; 258 259 op0 = nds32_legitimize_argument (icode, op0_num, op0); 260 op1 = nds32_legitimize_argument (icode, op1_num, op1); 261 262 /* Emit and return the new instruction. */ 263 if (return_p) 264 pat = GEN_FCN (icode) (target, op0, op1); 265 else 266 pat = GEN_FCN (icode) (op0, op1); 267 268 if (! pat) 269 return NULL_RTX; 270 271 emit_insn (pat); 272 return target; 273} 274 275/* Expand builtins that take three operands. */ 276static rtx 277nds32_expand_triop_builtin (enum insn_code icode, tree exp, rtx target, 278 bool return_p) 279{ 280 rtx pat; 281 rtx op0 = nds32_read_argument (exp, 0); 282 rtx op1 = nds32_read_argument (exp, 1); 283 rtx op2 = nds32_read_argument (exp, 2); 284 int op0_num = return_p ? 1 : 0; 285 int op1_num = return_p ? 2 : 1; 286 int op2_num = return_p ? 3 : 2; 287 288 if (return_p) 289 target = nds32_legitimize_target (icode, target); 290 291 op0 = nds32_legitimize_argument (icode, op0_num, op0); 292 op1 = nds32_legitimize_argument (icode, op1_num, op1); 293 op2 = nds32_legitimize_argument (icode, op2_num, op2); 294 295 /* Emit and return the new instruction. */ 296 if (return_p) 297 pat = GEN_FCN (icode) (target, op0, op1, op2); 298 else 299 pat = GEN_FCN (icode) (op0, op1, op2); 300 301 if (! pat) 302 return NULL_RTX; 303 304 emit_insn (pat); 305 return target; 306} 307 308/* Expand builtins that take three operands and the third is immediate. */ 309static rtx 310nds32_expand_triopimm_builtin (enum insn_code icode, tree exp, rtx target, 311 bool return_p, const char *name) 312{ 313 rtx pat; 314 rtx op0 = nds32_read_argument (exp, 0); 315 rtx op1 = nds32_read_argument (exp, 1); 316 rtx op2 = nds32_read_argument (exp, 2); 317 int op0_num = return_p ? 1 : 0; 318 int op1_num = return_p ? 2 : 1; 319 int op2_num = return_p ? 3 : 2; 320 321 if (return_p) 322 target = nds32_legitimize_target (icode, target); 323 324 if (!nds32_check_constant_argument (icode, op2_num, op2, name)) 325 return NULL_RTX; 326 327 op0 = nds32_legitimize_argument (icode, op0_num, op0); 328 op1 = nds32_legitimize_argument (icode, op1_num, op1); 329 op2 = nds32_legitimize_argument (icode, op2_num, op2); 330 331 /* Emit and return the new instruction. */ 332 if (return_p) 333 pat = GEN_FCN (icode) (target, op0, op1, op2); 334 else 335 pat = GEN_FCN (icode) (op0, op1, op2); 336 337 if (! pat) 338 return NULL_RTX; 339 340 emit_insn (pat); 341 return target; 342} 343 344/* Expand builtins for load. */ 345static rtx 346nds32_expand_builtin_load (enum insn_code icode, tree exp, rtx target) 347{ 348 /* Load address format is [$ra + $rb], 349 but input arguments not enough, 350 so we need another temp register as $rb. 351 Generating assembly code: 352 movi $temp, 0 353 llw $rt, [$ra + $temp] */ 354 rtx pat; 355 rtx op0 = nds32_read_argument (exp, 0); 356 rtx addr_helper = gen_reg_rtx (insn_data[icode].operand[1].mode); 357 358 target = nds32_legitimize_target (icode, target); 359 op0 = nds32_legitimize_argument (icode, 1, op0); 360 361 /* Emit and return the new instruction. */ 362 pat = GEN_FCN (icode) (target, op0, addr_helper); 363 if (!pat) 364 return NULL_RTX; 365 366 emit_move_insn (addr_helper, GEN_INT (0)); 367 emit_insn (pat); 368 return target; 369} 370 371/* Expand builtins for store. */ 372static rtx 373nds32_expand_builtin_store (enum insn_code icode, tree exp, rtx target) 374{ 375 /* Store address format is [$ra + $rb], 376 but input arguments not enough, 377 so we need another temp register as $rb. 378 Generating assembly code: 379 movi $temp, 0 380 store $rt, [$ra + $temp] */ 381 rtx pat; 382 rtx op0 = nds32_read_argument (exp, 0); 383 rtx op1 = nds32_read_argument (exp, 1); 384 rtx addr_helper = gen_reg_rtx (insn_data[icode].operand[1].mode); 385 386 op0 = nds32_legitimize_argument (icode, 0, op0); 387 op1 = nds32_legitimize_argument (icode, 2, op1); 388 389 /* Emit and return the new instruction. */ 390 pat = GEN_FCN (icode) (op0, addr_helper, op1); 391 if (! pat) 392 return NULL_RTX; 393 394 emit_move_insn (addr_helper, GEN_INT (0)); 395 emit_insn (pat); 396 return target; 397} 398 399/* Expand cctl builtins. */ 400static rtx 401nds32_expand_cctl_builtin (enum insn_code icode, tree exp, rtx target, 402 bool return_p, const char *name) 403{ 404 rtx pat; 405 rtx op0 = nds32_read_argument (exp, 0); 406 rtx op1 = nds32_read_argument (exp, 1); 407 int op0_num = return_p ? 1 : 0; 408 int op1_num = return_p ? 2 : 1; 409 410 if (return_p) 411 target = nds32_legitimize_target (icode, target); 412 413 if (!nds32_check_constant_argument (icode, op0_num, op0, name)) 414 return NULL_RTX; 415 416 op0 = nds32_legitimize_argument (icode, op0_num, op0); 417 op1 = nds32_legitimize_argument (icode, op1_num, op1); 418 419 /* Emit and return the new instruction. */ 420 if (icode == CODE_FOR_cctl_idx_write) 421 { 422 /* cctl_idx_write is three argument, 423 so create operand2 for cctl_idx_write pattern. */ 424 rtx op2 = nds32_read_argument (exp, 2); 425 op2 = nds32_legitimize_argument (icode, 2, op2); 426 pat = GEN_FCN (icode) (op0, op1, op2); 427 } 428 else if (return_p) 429 pat = GEN_FCN (icode) (target, op0, op1); 430 else 431 pat = GEN_FCN (icode) (op0, op1); 432 433 if (! pat) 434 return NULL_RTX; 435 436 emit_insn (pat); 437 return target; 438} 439 440/* Expand scw builtins. */ 441static rtx 442nds32_expand_scw_builtin (enum insn_code icode, tree exp, rtx target) 443{ 444 /* SCW address format is [$ra + $rb], but input arguments not enough, 445 so we need another temp register as $rb. 446 Generating assembly code: 447 movi $temp, 0 448 scw $rt, [$ra + $temp] */ 449 rtx pat; 450 rtx op0 = nds32_read_argument (exp, 0); 451 rtx op1 = nds32_read_argument (exp, 1); 452 rtx addr_helper = gen_reg_rtx (insn_data[icode].operand[1].mode); 453 454 target = nds32_legitimize_target (icode, target); 455 op0 = nds32_legitimize_argument (icode, 1, op0); 456 op1 = nds32_legitimize_argument (icode, 2, op1); 457 458 /* Emit and return the new instruction. */ 459 pat = GEN_FCN (icode) (target, op0, addr_helper, target); 460 461 if (!pat) 462 return NULL_RTX; 463 464 emit_move_insn (addr_helper, GEN_INT (0)); 465 emit_move_insn (target, op1); 466 emit_insn (pat); 467 return target; 468} 469 470/* Expand set int priority builtins. */ 471static rtx 472nds32_expand_priority_builtin (enum insn_code icode, tree exp, rtx target, 473 const char *name) 474{ 475 rtx pat; 476 rtx op0 = nds32_read_argument (exp, 0); 477 rtx op1 = nds32_read_argument (exp, 1); 478 479 /* set_int_priority intrinsic function that two arguments are immediate, 480 so check whether auguments are immedite. */ 481 482 if (!nds32_check_constant_argument (icode, 0, op0, name)) 483 return NULL_RTX; 484 485 if (!nds32_check_constant_argument (icode, 1, op1, name)) 486 return NULL_RTX; 487 488 op0 = nds32_legitimize_argument (icode, 0, op0); 489 op1 = nds32_legitimize_argument (icode, 1, op1); 490 491 /* Emit and return the new instruction. */ 492 pat = GEN_FCN (icode) (op0, op1); 493 494 if (! pat) 495 return NULL_RTX; 496 497 emit_insn (pat); 498 return target; 499} 500 501struct builtin_description 502{ 503 const enum insn_code icode; 504 const char *name; 505 enum nds32_builtins code; 506 bool return_p; 507}; 508 509#define NDS32_BUILTIN(code, string, builtin) \ 510 { CODE_FOR_##code, "__nds32__" string, \ 511 NDS32_BUILTIN_##builtin, true }, 512 513#define NDS32_NO_TARGET_BUILTIN(code, string, builtin) \ 514 { CODE_FOR_##code, "__nds32__" string, \ 515 NDS32_BUILTIN_##builtin, false }, 516 517/* Intrinsics that no argument, and that return value. */ 518static struct builtin_description bdesc_noarg[] = 519{ 520 NDS32_BUILTIN(unspec_fmfcfg, "fmfcfg", FMFCFG) 521 NDS32_BUILTIN(unspec_fmfcsr, "fmfcsr", FMFCSR) 522 NDS32_BUILTIN(unspec_get_current_sp, "get_current_sp", GET_CURRENT_SP) 523 NDS32_BUILTIN(unspec_return_address, "return_address", RETURN_ADDRESS) 524 NDS32_BUILTIN(unspec_get_all_pending_int, "get_all_pending_int", 525 GET_ALL_PENDING_INT) 526 NDS32_BUILTIN(unspec_unaligned_feature, "unaligned_feature", 527 UNALIGNED_FEATURE) 528 NDS32_NO_TARGET_BUILTIN(unspec_enable_unaligned, "enable_unaligned", 529 ENABLE_UNALIGNED) 530 NDS32_NO_TARGET_BUILTIN(unspec_disable_unaligned, "disable_unaligned", 531 DISABLE_UNALIGNED) 532}; 533 534/* Intrinsics that take just one argument. */ 535static struct builtin_description bdesc_1arg[] = 536{ 537 NDS32_BUILTIN(unspec_ssabssi2, "abs", ABS) 538 NDS32_BUILTIN(clzsi2, "clz", CLZ) 539 NDS32_BUILTIN(unspec_clo, "clo", CLO) 540 NDS32_BUILTIN(unspec_wsbh, "wsbh", WSBH) 541 NDS32_BUILTIN(unspec_tlbop_pb, "tlbop_pb",TLBOP_PB) 542 NDS32_BUILTIN(unaligned_load_hw, "unaligned_load_hw", UALOAD_HW) 543 NDS32_BUILTIN(unaligned_loadsi, "unaligned_load_w", UALOAD_W) 544 NDS32_BUILTIN(unaligned_loaddi, "unaligned_load_dw", UALOAD_DW) 545 NDS32_NO_TARGET_BUILTIN(unspec_volatile_isync, "isync", ISYNC) 546 NDS32_NO_TARGET_BUILTIN(unspec_fmtcsr, "fmtcsr", FMTCSR) 547 NDS32_NO_TARGET_BUILTIN(unspec_jr_itoff, "jr_itoff", JR_ITOFF) 548 NDS32_NO_TARGET_BUILTIN(unspec_jr_toff, "jr_toff", JR_TOFF) 549 NDS32_NO_TARGET_BUILTIN(unspec_jral_ton, "jral_ton", JRAL_TON) 550 NDS32_NO_TARGET_BUILTIN(unspec_ret_toff, "ret_toff", RET_TOFF) 551 NDS32_NO_TARGET_BUILTIN(unspec_jral_iton, "jral_iton",JRAL_ITON) 552 NDS32_NO_TARGET_BUILTIN(unspec_tlbop_trd, "tlbop_trd", TLBOP_TRD) 553 NDS32_NO_TARGET_BUILTIN(unspec_tlbop_twr, "tlbop_twr", TLBOP_TWR) 554 NDS32_NO_TARGET_BUILTIN(unspec_tlbop_rwr, "tlbop_rwr", TLBOP_RWR) 555 NDS32_NO_TARGET_BUILTIN(unspec_tlbop_rwlk, "tlbop_rwlk", TLBOP_RWLK) 556 NDS32_NO_TARGET_BUILTIN(unspec_tlbop_unlk, "tlbop_unlk", TLBOP_UNLK) 557 NDS32_NO_TARGET_BUILTIN(unspec_tlbop_inv, "tlbop_inv", TLBOP_INV) 558 NDS32_NO_TARGET_BUILTIN(unspec_ret_itoff, "ret_itoff", RET_ITOFF) 559 NDS32_NO_TARGET_BUILTIN(unspec_set_current_sp, 560 "set_current_sp", SET_CURRENT_SP) 561}; 562 563/* Intrinsics that take just one argument. and the argument is immediate. */ 564static struct builtin_description bdesc_1argimm[] = 565{ 566 NDS32_BUILTIN(unspec_volatile_mfsr, "mfsr", MFSR) 567 NDS32_BUILTIN(unspec_volatile_mfusr, "mfsr", MFUSR) 568 NDS32_BUILTIN(unspec_get_pending_int, "get_pending_int", GET_PENDING_INT) 569 NDS32_BUILTIN(unspec_get_int_priority, "get_int_priority", GET_INT_PRIORITY) 570 NDS32_NO_TARGET_BUILTIN(unspec_trap, "trap", TRAP) 571 NDS32_NO_TARGET_BUILTIN(unspec_break, "break", BREAK) 572 NDS32_NO_TARGET_BUILTIN(unspec_syscall, "syscall", SYSCALL) 573 NDS32_NO_TARGET_BUILTIN(unspec_enable_int, "enable_int", ENABLE_INT) 574 NDS32_NO_TARGET_BUILTIN(unspec_disable_int, "disable_int", DISABLE_INT) 575 NDS32_NO_TARGET_BUILTIN(unspec_clr_pending_hwint, "clr_pending_hwint", 576 CLR_PENDING_HWINT) 577 NDS32_NO_TARGET_BUILTIN(unspec_set_trig_level, "set_trig_level", 578 SET_TRIG_LEVEL) 579 NDS32_NO_TARGET_BUILTIN(unspec_set_trig_edge, "set_trig_edge", 580 SET_TRIG_EDGE) 581 NDS32_BUILTIN(unspec_get_trig_type, "get_trig_type", GET_TRIG_TYPE) 582}; 583 584/* Intrinsics that take two arguments. */ 585static struct builtin_description bdesc_2arg[] = 586{ 587 NDS32_BUILTIN(unspec_fcpynss, "fcpynss", FCPYNSS) 588 NDS32_BUILTIN(unspec_fcpyss, "fcpyss", FCPYSS) 589 NDS32_BUILTIN(unspec_fcpynsd, "fcpynsd", FCPYNSD) 590 NDS32_BUILTIN(unspec_fcpysd, "fcpysd", FCPYSD) 591 NDS32_BUILTIN(unspec_ave, "ave", AVE) 592 NDS32_BUILTIN(unspec_pbsad, "pbsad", PBSAD) 593 NDS32_BUILTIN(unspec_ffb, "ffb", FFB) 594 NDS32_BUILTIN(unspec_ffmism, "ffmsim", FFMISM) 595 NDS32_BUILTIN(unspec_flmism, "flmism", FLMISM) 596 NDS32_BUILTIN(rotrsi3, "rotr", ROTR) 597 NDS32_BUILTIN(unspec_sva, "sva", SVA) 598 NDS32_BUILTIN(unspec_svs, "svs", SVS) 599 NDS32_NO_TARGET_BUILTIN(mtsr_isb, "mtsr_isb", MTSR_ISB) 600 NDS32_NO_TARGET_BUILTIN(mtsr_dsb, "mtsr_dsb", MTSR_DSB) 601 NDS32_NO_TARGET_BUILTIN(unspec_volatile_mtsr, "mtsr", MTSR) 602 NDS32_NO_TARGET_BUILTIN(unspec_volatile_mtusr, "mtusr", MTUSR) 603 NDS32_NO_TARGET_BUILTIN(unaligned_store_hw, "unaligned_store_hw", UASTORE_HW) 604 NDS32_NO_TARGET_BUILTIN(unaligned_storesi, "unaligned_store_hw", UASTORE_W) 605 NDS32_NO_TARGET_BUILTIN(unaligned_storedi, "unaligned_store_hw", UASTORE_DW) 606 607}; 608 609/* Two-argument intrinsics with an immediate second argument. */ 610static struct builtin_description bdesc_2argimm[] = 611{ 612 NDS32_BUILTIN(unspec_bclr, "bclr", BCLR) 613 NDS32_BUILTIN(unspec_bset, "bset", BSET) 614 NDS32_BUILTIN(unspec_btgl, "btgl", BTGL) 615 NDS32_BUILTIN(unspec_btst, "btst", BTST) 616 NDS32_BUILTIN(unspec_clip, "clip", CLIP) 617 NDS32_BUILTIN(unspec_clips, "clips", CLIPS) 618 NDS32_NO_TARGET_BUILTIN(unspec_teqz, "teqz", TEQZ) 619 NDS32_NO_TARGET_BUILTIN(unspec_tnez, "tnez", TNEZ) 620}; 621 622/* Intrinsics that take three arguments. */ 623static struct builtin_description bdesc_3arg[] = 624{ 625 NDS32_BUILTIN(unspec_pbsada, "pbsada", PBSADA) 626 NDS32_NO_TARGET_BUILTIN(bse, "bse", BSE) 627 NDS32_NO_TARGET_BUILTIN(bsp, "bsp", BSP) 628}; 629 630/* Three-argument intrinsics with an immediate third argument. */ 631static struct builtin_description bdesc_3argimm[] = 632{ 633 NDS32_NO_TARGET_BUILTIN(prefetch_qw, "prefetch_qw", DPREF_QW) 634 NDS32_NO_TARGET_BUILTIN(prefetch_hw, "prefetch_hw", DPREF_HW) 635 NDS32_NO_TARGET_BUILTIN(prefetch_w, "prefetch_w", DPREF_W) 636 NDS32_NO_TARGET_BUILTIN(prefetch_dw, "prefetch_dw", DPREF_DW) 637}; 638 639/* Intrinsics that load a value. */ 640static struct builtin_description bdesc_load[] = 641{ 642 NDS32_BUILTIN(unspec_volatile_llw, "llw", LLW) 643 NDS32_BUILTIN(unspec_lwup, "lwup", LWUP) 644 NDS32_BUILTIN(unspec_lbup, "lbup", LBUP) 645}; 646 647/* Intrinsics that store a value. */ 648static struct builtin_description bdesc_store[] = 649{ 650 NDS32_BUILTIN(unspec_swup, "swup", SWUP) 651 NDS32_BUILTIN(unspec_sbup, "sbup", SBUP) 652}; 653 654static struct builtin_description bdesc_cctl[] = 655{ 656 NDS32_BUILTIN(cctl_idx_read, "cctl_idx_read", CCTL_IDX_READ) 657 NDS32_NO_TARGET_BUILTIN(cctl_idx_write, "cctl_idx_write", CCTL_IDX_WRITE) 658 NDS32_NO_TARGET_BUILTIN(cctl_va_lck, "cctl_va_lck", CCTL_VA_LCK) 659 NDS32_NO_TARGET_BUILTIN(cctl_idx_wbinval, 660 "cctl_idx_wbinval", CCTL_IDX_WBINVAL) 661 NDS32_NO_TARGET_BUILTIN(cctl_va_wbinval_l1, 662 "cctl_va_wbinval_l1", CCTL_VA_WBINVAL_L1) 663 NDS32_NO_TARGET_BUILTIN(cctl_va_wbinval_la, 664 "cctl_va_wbinval_la", CCTL_VA_WBINVAL_LA) 665}; 666 667rtx 668nds32_expand_builtin_impl (tree exp, 669 rtx target, 670 rtx subtarget ATTRIBUTE_UNUSED, 671 enum machine_mode mode ATTRIBUTE_UNUSED, 672 int ignore ATTRIBUTE_UNUSED) 673{ 674 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); 675 unsigned int fcode = DECL_FUNCTION_CODE (fndecl); 676 unsigned i; 677 struct builtin_description *d; 678 679 switch (fcode) 680 { 681 /* FPU Register Transfer. */ 682 case NDS32_BUILTIN_FMFCFG: 683 case NDS32_BUILTIN_FMFCSR: 684 case NDS32_BUILTIN_FMTCSR: 685 case NDS32_BUILTIN_FCPYNSS: 686 case NDS32_BUILTIN_FCPYSS: 687 /* Both v3s and v3f toolchains define TARGET_FPU_SINGLE. */ 688 if (!TARGET_FPU_SINGLE) 689 { 690 error ("this builtin function is only available " 691 "on the v3s or v3f toolchain"); 692 return NULL_RTX; 693 } 694 break; 695 696 /* FPU Register Transfer. */ 697 case NDS32_BUILTIN_FCPYNSD: 698 case NDS32_BUILTIN_FCPYSD: 699 /* Only v3f toolchain defines TARGET_FPU_DOUBLE. */ 700 if (!TARGET_FPU_DOUBLE) 701 { 702 error ("this builtin function is only available " 703 "on the v3f toolchain"); 704 return NULL_RTX; 705 } 706 break; 707 708 /* Load and Store */ 709 case NDS32_BUILTIN_LLW: 710 case NDS32_BUILTIN_LWUP: 711 case NDS32_BUILTIN_LBUP: 712 case NDS32_BUILTIN_SCW: 713 case NDS32_BUILTIN_SWUP: 714 case NDS32_BUILTIN_SBUP: 715 if (TARGET_ISA_V3M) 716 { 717 error ("this builtin function not support " 718 "on the v3m toolchain"); 719 return NULL_RTX; 720 } 721 break; 722 723 /* Performance Extension */ 724 case NDS32_BUILTIN_ABS: 725 case NDS32_BUILTIN_AVE: 726 case NDS32_BUILTIN_BCLR: 727 case NDS32_BUILTIN_BSET: 728 case NDS32_BUILTIN_BTGL: 729 case NDS32_BUILTIN_BTST: 730 case NDS32_BUILTIN_CLIP: 731 case NDS32_BUILTIN_CLIPS: 732 case NDS32_BUILTIN_CLZ: 733 case NDS32_BUILTIN_CLO: 734 if (!TARGET_EXT_PERF) 735 { 736 error ("don't support performance extension instructions"); 737 return NULL_RTX; 738 } 739 break; 740 741 /* Performance Extension 2 */ 742 case NDS32_BUILTIN_PBSAD: 743 case NDS32_BUILTIN_PBSADA: 744 case NDS32_BUILTIN_BSE: 745 case NDS32_BUILTIN_BSP: 746 if (!TARGET_EXT_PERF2) 747 { 748 error ("don't support performance extension " 749 "version 2 instructions"); 750 return NULL_RTX; 751 } 752 break; 753 754 /* String Extension */ 755 case NDS32_BUILTIN_FFB: 756 case NDS32_BUILTIN_FFMISM: 757 case NDS32_BUILTIN_FLMISM: 758 if (!TARGET_EXT_STRING) 759 { 760 error ("don't support string extension instructions"); 761 return NULL_RTX; 762 } 763 break; 764 765 default: 766 break; 767 } 768 769 /* Since there are no result and operands, we can simply emit this rtx. */ 770 switch (fcode) 771 { 772 case NDS32_BUILTIN_ISB: 773 emit_insn (gen_unspec_volatile_isb ()); 774 return target; 775 case NDS32_BUILTIN_DSB: 776 emit_insn (gen_unspec_dsb ()); 777 return target; 778 case NDS32_BUILTIN_MSYNC_ALL: 779 emit_insn (gen_unspec_msync_all ()); 780 return target; 781 case NDS32_BUILTIN_MSYNC_STORE: 782 emit_insn (gen_unspec_msync_store ()); 783 return target; 784 case NDS32_BUILTIN_SETGIE_EN: 785 emit_insn (gen_unspec_volatile_setgie_en ()); 786 emit_insn (gen_unspec_dsb ()); 787 return target; 788 case NDS32_BUILTIN_SETGIE_DIS: 789 emit_insn (gen_unspec_volatile_setgie_dis ()); 790 emit_insn (gen_unspec_dsb ()); 791 return target; 792 case NDS32_BUILTIN_GIE_DIS: 793 emit_insn (gen_unspec_volatile_setgie_dis ()); 794 emit_insn (gen_unspec_dsb ()); 795 return target; 796 case NDS32_BUILTIN_GIE_EN: 797 emit_insn (gen_unspec_volatile_setgie_en ()); 798 emit_insn (gen_unspec_dsb ()); 799 return target; 800 case NDS32_BUILTIN_SET_PENDING_SWINT: 801 emit_insn (gen_unspec_set_pending_swint ()); 802 return target; 803 case NDS32_BUILTIN_CLR_PENDING_SWINT: 804 emit_insn (gen_unspec_clr_pending_swint ()); 805 return target; 806 case NDS32_BUILTIN_CCTL_L1D_INVALALL: 807 emit_insn (gen_cctl_l1d_invalall()); 808 return target; 809 case NDS32_BUILTIN_CCTL_L1D_WBALL_ALVL: 810 emit_insn (gen_cctl_l1d_wball_alvl()); 811 return target; 812 case NDS32_BUILTIN_CCTL_L1D_WBALL_ONE_LVL: 813 emit_insn (gen_cctl_l1d_wball_one_lvl()); 814 return target; 815 case NDS32_BUILTIN_STANDBY_NO_WAKE_GRANT: 816 emit_insn (gen_unspec_standby_no_wake_grant ()); 817 return target; 818 case NDS32_BUILTIN_STANDBY_WAKE_GRANT: 819 emit_insn (gen_unspec_standby_wake_grant ()); 820 return target; 821 case NDS32_BUILTIN_STANDBY_WAKE_DONE: 822 emit_insn (gen_unspec_standby_wait_done ()); 823 return target; 824 case NDS32_BUILTIN_SETEND_BIG: 825 emit_insn (gen_unspec_setend_big ()); 826 return target; 827 case NDS32_BUILTIN_SETEND_LITTLE: 828 emit_insn (gen_unspec_setend_little ()); 829 return target; 830 case NDS32_BUILTIN_NOP: 831 emit_insn (gen_unspec_nop ()); 832 return target; 833 case NDS32_BUILTIN_SCHE_BARRIER: 834 emit_insn (gen_blockage ()); 835 return target; 836 case NDS32_BUILTIN_TLBOP_FLUA: 837 emit_insn (gen_unspec_tlbop_flua ()); 838 return target; 839 case NDS32_BUILTIN_SCW: 840 return nds32_expand_scw_builtin (CODE_FOR_unspec_volatile_scw, 841 exp, target); 842 case NDS32_BUILTIN_SET_INT_PRIORITY: 843 return nds32_expand_priority_builtin (CODE_FOR_unspec_set_int_priority, 844 exp, target, 845 "__nds32__set_int_priority"); 846 return target; 847 default: 848 break; 849 } 850 851 /* Expand groups of builtins. */ 852 for (i = 0, d = bdesc_noarg; i < ARRAY_SIZE (bdesc_noarg); i++, d++) 853 if (d->code == fcode) 854 return nds32_expand_noarg_builtin (d->icode, target); 855 856 for (i = 0, d = bdesc_1arg; i < ARRAY_SIZE (bdesc_1arg); i++, d++) 857 if (d->code == fcode) 858 return nds32_expand_unop_builtin (d->icode, exp, target, d->return_p); 859 860 for (i = 0, d = bdesc_1argimm; i < ARRAY_SIZE (bdesc_1argimm); i++, d++) 861 if (d->code == fcode) 862 return nds32_expand_unopimm_builtin (d->icode, exp, target, 863 d->return_p, d->name); 864 865 for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++) 866 if (d->code == fcode) 867 return nds32_expand_binop_builtin (d->icode, exp, target, d->return_p); 868 869 for (i = 0, d = bdesc_2argimm; i < ARRAY_SIZE (bdesc_2argimm); i++, d++) 870 if (d->code == fcode) 871 return nds32_expand_binopimm_builtin (d->icode, exp, target, 872 d->return_p, d->name); 873 874 for (i = 0, d = bdesc_3arg; i < ARRAY_SIZE (bdesc_3arg); i++, d++) 875 if (d->code == fcode) 876 return nds32_expand_triop_builtin (d->icode, exp, target, d->return_p); 877 878 for (i = 0, d = bdesc_3argimm; i < ARRAY_SIZE (bdesc_3argimm); i++, d++) 879 if (d->code == fcode) 880 return nds32_expand_triopimm_builtin (d->icode, exp, target, 881 d->return_p, d->name); 882 883 for (i = 0, d = bdesc_load; i < ARRAY_SIZE (bdesc_load); i++, d++) 884 if (d->code == fcode) 885 return nds32_expand_builtin_load (d->icode, exp, target); 886 887 for (i = 0, d = bdesc_store; i < ARRAY_SIZE (bdesc_store); i++, d++) 888 if (d->code == fcode) 889 return nds32_expand_builtin_store (d->icode, exp, target); 890 891 for (i = 0, d = bdesc_cctl; i < ARRAY_SIZE (bdesc_cctl); i++, d++) 892 if (d->code == fcode) 893 return nds32_expand_cctl_builtin (d->icode, exp, target, 894 d->return_p, d->name); 895 896 return NULL_RTX; 897} 898 899static GTY(()) tree nds32_builtin_decls[NDS32_BUILTIN_COUNT]; 900 901/* Return the NDS32 builtin for CODE. */ 902tree 903nds32_builtin_decl_impl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED) 904{ 905 if (code >= NDS32_BUILTIN_COUNT) 906 return error_mark_node; 907 908 return nds32_builtin_decls[code]; 909} 910 911void 912nds32_init_builtins_impl (void) 913{ 914#define ADD_NDS32_BUILTIN0(NAME, RET_TYPE, CODE) \ 915 nds32_builtin_decls[NDS32_BUILTIN_ ## CODE] = \ 916 add_builtin_function ("__builtin_nds32_" NAME, \ 917 build_function_type_list (RET_TYPE##_type_node, \ 918 NULL_TREE), \ 919 NDS32_BUILTIN_ ## CODE, BUILT_IN_MD, NULL, NULL_TREE) 920 921#define ADD_NDS32_BUILTIN1(NAME, RET_TYPE, ARG_TYPE, CODE) \ 922 nds32_builtin_decls[NDS32_BUILTIN_ ## CODE] = \ 923 add_builtin_function ("__builtin_nds32_" NAME, \ 924 build_function_type_list (RET_TYPE##_type_node, \ 925 ARG_TYPE##_type_node, \ 926 NULL_TREE), \ 927 NDS32_BUILTIN_ ## CODE, BUILT_IN_MD, NULL, NULL_TREE) 928 929#define ADD_NDS32_BUILTIN2(NAME, RET_TYPE, ARG_TYPE1, ARG_TYPE2, CODE) \ 930 nds32_builtin_decls[NDS32_BUILTIN_ ## CODE] = \ 931 add_builtin_function ("__builtin_nds32_" NAME, \ 932 build_function_type_list (RET_TYPE##_type_node, \ 933 ARG_TYPE1##_type_node,\ 934 ARG_TYPE2##_type_node,\ 935 NULL_TREE), \ 936 NDS32_BUILTIN_ ## CODE, BUILT_IN_MD, NULL, NULL_TREE) 937 938#define ADD_NDS32_BUILTIN3(NAME, RET_TYPE, \ 939 ARG_TYPE1, ARG_TYPE2, ARG_TYPE3, CODE) \ 940 nds32_builtin_decls[NDS32_BUILTIN_ ## CODE] = \ 941 add_builtin_function ("__builtin_nds32_" NAME, \ 942 build_function_type_list (RET_TYPE##_type_node, \ 943 ARG_TYPE1##_type_node,\ 944 ARG_TYPE2##_type_node,\ 945 ARG_TYPE3##_type_node,\ 946 NULL_TREE), \ 947 NDS32_BUILTIN_ ## CODE, BUILT_IN_MD, NULL, NULL_TREE) 948 949 /* Looking for return type and argument can be found in tree.h file. */ 950 tree ptr_uchar_type_node = build_pointer_type (unsigned_char_type_node); 951 tree ptr_ushort_type_node = build_pointer_type (short_unsigned_type_node); 952 tree ptr_uint_type_node = build_pointer_type (unsigned_type_node); 953 tree ptr_ulong_type_node = build_pointer_type (long_long_unsigned_type_node); 954 955 /* Cache. */ 956 ADD_NDS32_BUILTIN1 ("isync", void, ptr_uint, ISYNC); 957 ADD_NDS32_BUILTIN0 ("isb", void, ISB); 958 ADD_NDS32_BUILTIN0 ("dsb", void, DSB); 959 ADD_NDS32_BUILTIN0 ("msync_all", void, MSYNC_ALL); 960 ADD_NDS32_BUILTIN0 ("msync_store", void, MSYNC_STORE); 961 962 /* Register Transfer. */ 963 ADD_NDS32_BUILTIN1 ("mfsr", unsigned, integer, MFSR); 964 ADD_NDS32_BUILTIN1 ("mfusr", unsigned, integer, MFUSR); 965 ADD_NDS32_BUILTIN2 ("mtsr", void, unsigned, integer, MTSR); 966 ADD_NDS32_BUILTIN2 ("mtsr_isb", void, unsigned, integer, MTSR_ISB); 967 ADD_NDS32_BUILTIN2 ("mtsr_dsb", void, unsigned, integer, MTSR_DSB); 968 ADD_NDS32_BUILTIN2 ("mtusr", void, unsigned, integer, MTUSR); 969 970 /* FPU Register Transfer. */ 971 ADD_NDS32_BUILTIN0 ("fmfcsr", unsigned, FMFCSR); 972 ADD_NDS32_BUILTIN1 ("fmtcsr", void, unsigned, FMTCSR); 973 ADD_NDS32_BUILTIN0 ("fmfcfg", unsigned, FMFCFG); 974 ADD_NDS32_BUILTIN2 ("fcpyss", float, float, float, FCPYSS); 975 ADD_NDS32_BUILTIN2 ("fcpynss", float, float, float, FCPYNSS); 976 ADD_NDS32_BUILTIN2 ("fcpysd", double, double, double, FCPYSD); 977 ADD_NDS32_BUILTIN2 ("fcpynsd", double, double, double, FCPYNSD); 978 979 /* Interrupt. */ 980 ADD_NDS32_BUILTIN0 ("setgie_en", void, SETGIE_EN); 981 ADD_NDS32_BUILTIN0 ("setgie_dis", void, SETGIE_DIS); 982 ADD_NDS32_BUILTIN0 ("gie_en", void, GIE_EN); 983 ADD_NDS32_BUILTIN0 ("gie_dis", void, GIE_DIS); 984 ADD_NDS32_BUILTIN1 ("enable_int", void, integer, ENABLE_INT); 985 ADD_NDS32_BUILTIN1 ("disable_int", void, integer, DISABLE_INT); 986 ADD_NDS32_BUILTIN0 ("set_pending_swint", void, SET_PENDING_SWINT); 987 ADD_NDS32_BUILTIN0 ("clr_pending_swint", void, CLR_PENDING_SWINT); 988 ADD_NDS32_BUILTIN0 ("get_all_pending_int", unsigned, GET_ALL_PENDING_INT); 989 ADD_NDS32_BUILTIN1 ("get_pending_int", unsigned, integer, GET_PENDING_INT); 990 ADD_NDS32_BUILTIN1 ("get_int_priority", unsigned, integer, GET_INT_PRIORITY); 991 ADD_NDS32_BUILTIN2 ("set_int_priority", void, integer, integer, 992 SET_INT_PRIORITY); 993 ADD_NDS32_BUILTIN1 ("clr_pending_hwint", void, integer, CLR_PENDING_HWINT); 994 ADD_NDS32_BUILTIN1 ("set_trig_level", void, integer, SET_TRIG_LEVEL); 995 ADD_NDS32_BUILTIN1 ("set_trig_edge", void, integer, SET_TRIG_EDGE); 996 ADD_NDS32_BUILTIN1 ("get_trig_type", unsigned, integer, GET_TRIG_TYPE); 997 998 /* Load and Store */ 999 ADD_NDS32_BUILTIN1 ("llw", unsigned, ptr_uint, LLW); 1000 ADD_NDS32_BUILTIN1 ("lwup", unsigned, ptr_uint, LWUP); 1001 ADD_NDS32_BUILTIN1 ("lbup", char, ptr_uchar, LBUP); 1002 ADD_NDS32_BUILTIN2 ("scw", unsigned, ptr_uint, unsigned, SCW); 1003 ADD_NDS32_BUILTIN2 ("swup", void, ptr_uint, unsigned, SWUP); 1004 ADD_NDS32_BUILTIN2 ("sbup", void, ptr_uchar, char, SBUP); 1005 1006 /* CCTL */ 1007 ADD_NDS32_BUILTIN0 ("cctl_l1d_invalall", void, CCTL_L1D_INVALALL); 1008 ADD_NDS32_BUILTIN0 ("cctl_l1d_wball_alvl", void, CCTL_L1D_WBALL_ALVL); 1009 ADD_NDS32_BUILTIN0 ("cctl_l1d_wball_one_lvl", void, CCTL_L1D_WBALL_ONE_LVL); 1010 ADD_NDS32_BUILTIN2 ("cctl_va_lck", void, integer, ptr_uint, CCTL_VA_LCK); 1011 ADD_NDS32_BUILTIN2 ("cctl_idx_wbinval", void, integer, unsigned, 1012 CCTL_IDX_WBINVAL); 1013 ADD_NDS32_BUILTIN2 ("cctl_va_wbinval_l1", void, integer, ptr_uint, 1014 CCTL_VA_WBINVAL_L1); 1015 ADD_NDS32_BUILTIN2 ("cctl_va_wbinval_la", void, integer, ptr_uint, 1016 CCTL_VA_WBINVAL_LA); 1017 ADD_NDS32_BUILTIN2 ("cctl_idx_read", unsigned, integer, unsigned, 1018 CCTL_IDX_READ); 1019 ADD_NDS32_BUILTIN3 ("cctl_idx_write", void, integer, unsigned, unsigned, 1020 CCTL_IDX_WRITE); 1021 1022 /* PREFETCH */ 1023 ADD_NDS32_BUILTIN3 ("dpref_qw", void, ptr_uchar, unsigned, integer, DPREF_QW); 1024 ADD_NDS32_BUILTIN3 ("dpref_hw", void, ptr_ushort, unsigned, integer, 1025 DPREF_HW); 1026 ADD_NDS32_BUILTIN3 ("dpref_w", void, ptr_uint, unsigned, integer, DPREF_W); 1027 ADD_NDS32_BUILTIN3 ("dpref_dw", void, ptr_ulong, unsigned, integer, DPREF_DW); 1028 1029 /* Performance Extension */ 1030 ADD_NDS32_BUILTIN1 ("pe_abs", integer, integer, ABS); 1031 ADD_NDS32_BUILTIN2 ("pe_ave", integer, integer, integer, AVE); 1032 ADD_NDS32_BUILTIN2 ("pe_bclr", unsigned, unsigned, unsigned, BCLR); 1033 ADD_NDS32_BUILTIN2 ("pe_bset", unsigned, unsigned, unsigned, BSET); 1034 ADD_NDS32_BUILTIN2 ("pe_btgl", unsigned, unsigned, unsigned, BTGL); 1035 ADD_NDS32_BUILTIN2 ("pe_btst", unsigned, unsigned, unsigned, BTST); 1036 ADD_NDS32_BUILTIN2 ("pe_clip", unsigned, integer, unsigned, CLIP); 1037 ADD_NDS32_BUILTIN2 ("pe_clips", integer, integer, unsigned, CLIPS); 1038 ADD_NDS32_BUILTIN1 ("pe_clz", unsigned, unsigned, CLZ); 1039 ADD_NDS32_BUILTIN1 ("pe_clo", unsigned, unsigned, CLO); 1040 1041 /* Performance Extension 2 */ 1042 ADD_NDS32_BUILTIN3 ("pe2_bse", void, ptr_uint, unsigned, ptr_uint, BSE); 1043 ADD_NDS32_BUILTIN3 ("pe2_bsp", void, ptr_uint, unsigned, ptr_uint, BSP); 1044 ADD_NDS32_BUILTIN2 ("pe2_pbsad", unsigned, unsigned, unsigned, PBSAD); 1045 ADD_NDS32_BUILTIN3 ("pe2_pbsada", unsigned, unsigned, unsigned, unsigned, 1046 PBSADA); 1047 1048 /* String Extension */ 1049 ADD_NDS32_BUILTIN2 ("se_ffb", integer, unsigned, unsigned, FFB); 1050 ADD_NDS32_BUILTIN2 ("se_ffmism", integer, unsigned, unsigned, FFMISM); 1051 ADD_NDS32_BUILTIN2 ("se_flmism", integer, unsigned, unsigned, FLMISM); 1052 1053 1054 /* ROTR */ 1055 ADD_NDS32_BUILTIN2 ("rotr", unsigned, unsigned, unsigned, ROTR); 1056 1057 /* Swap */ 1058 ADD_NDS32_BUILTIN1 ("wsbh", unsigned, unsigned, WSBH); 1059 1060 /* System */ 1061 ADD_NDS32_BUILTIN2 ("svs", unsigned, integer, integer, SVS); 1062 ADD_NDS32_BUILTIN2 ("sva", unsigned, integer, integer, SVA); 1063 ADD_NDS32_BUILTIN1 ("jr_itoff", void, unsigned, JR_ITOFF); 1064 ADD_NDS32_BUILTIN1 ("jr_toff", void, unsigned, JR_TOFF); 1065 ADD_NDS32_BUILTIN1 ("jral_iton", void, unsigned, JRAL_ITON); 1066 ADD_NDS32_BUILTIN1 ("jral_ton", void, unsigned, JRAL_TON); 1067 ADD_NDS32_BUILTIN1 ("ret_itoff", void, unsigned, RET_ITOFF); 1068 ADD_NDS32_BUILTIN1 ("ret_toff", void, unsigned, RET_TOFF); 1069 ADD_NDS32_BUILTIN0 ("standby_no_wake_grant", void, STANDBY_NO_WAKE_GRANT); 1070 ADD_NDS32_BUILTIN0 ("standby_wake_grant", void, STANDBY_WAKE_GRANT); 1071 ADD_NDS32_BUILTIN0 ("standby_wait_done", void, STANDBY_WAKE_DONE); 1072 ADD_NDS32_BUILTIN1 ("break", void, unsigned, BREAK); 1073 ADD_NDS32_BUILTIN1 ("syscall", void, unsigned, SYSCALL); 1074 ADD_NDS32_BUILTIN0 ("nop", void, NOP); 1075 ADD_NDS32_BUILTIN0 ("get_current_sp", unsigned, GET_CURRENT_SP); 1076 ADD_NDS32_BUILTIN1 ("set_current_sp", void, unsigned, SET_CURRENT_SP); 1077 ADD_NDS32_BUILTIN2 ("teqz", void, unsigned, unsigned, TEQZ); 1078 ADD_NDS32_BUILTIN2 ("tnez", void, unsigned, unsigned, TNEZ); 1079 ADD_NDS32_BUILTIN1 ("trap", void, unsigned, TRAP); 1080 ADD_NDS32_BUILTIN0 ("return_address", unsigned, RETURN_ADDRESS); 1081 ADD_NDS32_BUILTIN0 ("setend_big", void, SETEND_BIG); 1082 ADD_NDS32_BUILTIN0 ("setend_little", void, SETEND_LITTLE); 1083 1084 /* Schedule Barrier */ 1085 ADD_NDS32_BUILTIN0 ("schedule_barrier", void, SCHE_BARRIER); 1086 1087 /* TLBOP */ 1088 ADD_NDS32_BUILTIN1 ("tlbop_trd", void, unsigned, TLBOP_TRD); 1089 ADD_NDS32_BUILTIN1 ("tlbop_twr", void, unsigned, TLBOP_TWR); 1090 ADD_NDS32_BUILTIN1 ("tlbop_rwr", void, unsigned, TLBOP_RWR); 1091 ADD_NDS32_BUILTIN1 ("tlbop_rwlk", void, unsigned, TLBOP_RWLK); 1092 ADD_NDS32_BUILTIN1 ("tlbop_unlk", void, unsigned, TLBOP_UNLK); 1093 ADD_NDS32_BUILTIN1 ("tlbop_pb", unsigned, unsigned, TLBOP_PB); 1094 ADD_NDS32_BUILTIN1 ("tlbop_inv", void, unsigned, TLBOP_INV); 1095 ADD_NDS32_BUILTIN0 ("tlbop_flua", void, TLBOP_FLUA); 1096 1097 /* Unaligned Load/Store */ 1098 ADD_NDS32_BUILTIN1 ("unaligned_load_hw", short_unsigned, ptr_ushort, 1099 UALOAD_HW); 1100 ADD_NDS32_BUILTIN1 ("unaligned_load_w", unsigned, ptr_uint, UALOAD_W); 1101 ADD_NDS32_BUILTIN1 ("unaligned_load_dw", long_long_unsigned, ptr_ulong, 1102 UALOAD_DW); 1103 ADD_NDS32_BUILTIN2 ("unaligned_store_hw", void, ptr_ushort, short_unsigned, 1104 UASTORE_HW); 1105 ADD_NDS32_BUILTIN2 ("unaligned_store_w", void, ptr_uint, unsigned, UASTORE_W); 1106 ADD_NDS32_BUILTIN2 ("unaligned_store_dw", void, ptr_ulong, long_long_unsigned, 1107 UASTORE_DW); 1108 ADD_NDS32_BUILTIN0 ("unaligned_feature", unsigned, UNALIGNED_FEATURE); 1109 ADD_NDS32_BUILTIN0 ("enable_unaligned", void, ENABLE_UNALIGNED); 1110 ADD_NDS32_BUILTIN0 ("disable_unaligned", void, DISABLE_UNALIGNED); 1111 1112} 1113