1;; Machine Description for Altera Nios II. 2;; Copyright (C) 2012-2022 Free Software Foundation, Inc. 3;; Contributed by Jonah Graham (jgraham@altera.com) and 4;; Will Reece (wreece@altera.com). 5;; Contributed by Mentor Graphics, Inc. 6;; 7;; This file is part of GCC. 8;; 9;; GCC is free software; you can redistribute it and/or modify 10;; it under the terms of the GNU General Public License as published by 11;; the Free Software Foundation; either version 3, or (at your option) 12;; any later version. 13;; 14;; GCC is distributed in the hope that it will be useful, 15;; but WITHOUT ANY WARRANTY; without even the implied warranty of 16;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17;; GNU General Public License for more details. 18;; 19;; You should have received a copy of the GNU General Public License 20;; along with GCC; see the file COPYING3. If not see 21;; <http://www.gnu.org/licenses/>. 22 23;; Register numbers 24(define_constants 25 [ 26 (FIRST_RETVAL_REGNO 2) ; Return value registers 27 (LAST_RETVAL_REGNO 3) ; 28 (FIRST_ARG_REGNO 4) ; Argument registers 29 (LAST_ARG_REGNO 7) ; 30 31 (TP_REGNO 23) ; Thread pointer register 32 (GP_REGNO 26) ; Global pointer register 33 (SP_REGNO 27) ; Stack pointer register 34 (FP_REGNO 28) ; Frame pointer register 35 (EA_REGNO 29) ; Exception return address register 36 (RA_REGNO 31) ; Return address register 37 (LAST_GP_REG 31) ; Last general purpose register 38 39 ;; Target register definitions 40 (STATIC_CHAIN_REGNUM 12) 41 (STACK_POINTER_REGNUM 27) 42 (HARD_FRAME_POINTER_REGNUM 28) 43 (PC_REGNUM 37) 44 (FRAME_POINTER_REGNUM 38) 45 (ARG_POINTER_REGNUM 39) 46 (FIRST_PSEUDO_REGISTER 40) 47 ] 48) 49 50;; Enumeration of UNSPECs 51 52(define_c_enum "unspecv" [ 53 UNSPECV_BLOCKAGE 54 UNSPECV_WRCTL 55 UNSPECV_RDCTL 56 UNSPECV_FWRX 57 UNSPECV_FWRY 58 UNSPECV_FRDXLO 59 UNSPECV_FRDXHI 60 UNSPECV_FRDY 61 UNSPECV_CUSTOM_NXX 62 UNSPECV_CUSTOM_XNXX 63 UNSPECV_LDXIO 64 UNSPECV_STXIO 65 UNSPECV_RDPRS 66 UNSPECV_FLUSHD 67 UNSPECV_FLUSHDA 68 UNSPECV_WRPIE 69 UNSPECV_ENI 70 UNSPECV_LDEX 71 UNSPECV_LDSEX 72 UNSPECV_STEX 73 UNSPECV_STSEX 74]) 75 76(define_c_enum "unspec" [ 77 UNSPEC_FCOS 78 UNSPEC_FSIN 79 UNSPEC_FTAN 80 UNSPEC_FATAN 81 UNSPEC_FEXP 82 UNSPEC_FLOG 83 UNSPEC_ROUND 84 UNSPEC_LOAD_GOT_REGISTER 85 UNSPEC_PIC_SYM 86 UNSPEC_PIC_CALL_SYM 87 UNSPEC_PIC_GOTOFF_SYM 88 UNSPEC_LOAD_TLS_IE 89 UNSPEC_ADD_TLS_LE 90 UNSPEC_ADD_TLS_GD 91 UNSPEC_ADD_TLS_LDM 92 UNSPEC_ADD_TLS_LDO 93 UNSPEC_EH_RETURN 94 UNSPEC_SYNC 95]) 96 97 98;; Instruction scheduler 99 100; No schedule info is currently available, using an assumption that no 101; instruction can use the results of the previous instruction without 102; incuring a stall. 103 104; length of an instruction (in bytes) 105(define_attr "length" "" 106 (if_then_else (match_test "nios2_cdx_narrow_form_p (insn)") 107 (const_int 2) 108 (const_int 4))) 109 110(define_attr "type" 111 "unknown,complex,control,alu,cond_alu,st,ld,stwm,ldwm,push,pop,mul,div,\ 112 custom,add,sub,mov,and,or,xor,neg,not,sll,srl,sra,rol,ror,nop" 113 (const_string "complex")) 114 115(define_asm_attributes 116 [(set_attr "length" "4") 117 (set_attr "type" "complex")]) 118 119(define_automaton "nios2") 120(automata_option "v") 121;(automata_option "no-minimization") 122(automata_option "ndfa") 123 124; The nios2 pipeline is fairly straightforward for the fast model. 125; Every alu operation is pipelined so that an instruction can 126; be issued every cycle. However, there are still potential 127; stalls which this description tries to deal with. 128 129(define_cpu_unit "cpu" "nios2") 130 131(define_insn_reservation "complex" 1 132 (eq_attr "type" "complex") 133 "cpu") 134 135(define_insn_reservation "control" 1 136 (eq_attr "type" "control,pop") 137 "cpu") 138 139(define_insn_reservation "alu" 1 140 (eq_attr "type" "alu,add,sub,mov,and,or,xor,neg,not") 141 "cpu") 142 143(define_insn_reservation "cond_alu" 1 144 (eq_attr "type" "cond_alu") 145 "cpu") 146 147(define_insn_reservation "st" 1 148 (eq_attr "type" "st,stwm,push") 149 "cpu") 150 151(define_insn_reservation "custom" 1 152 (eq_attr "type" "custom") 153 "cpu") 154 155; shifts, muls and lds have three cycle latency 156(define_insn_reservation "ld" 3 157 (eq_attr "type" "ld,ldwm") 158 "cpu") 159 160(define_insn_reservation "shift" 3 161 (eq_attr "type" "sll,srl,sra,rol,ror") 162 "cpu") 163 164(define_insn_reservation "mul" 3 165 (eq_attr "type" "mul") 166 "cpu") 167 168(define_insn_reservation "div" 1 169 (eq_attr "type" "div") 170 "cpu") 171 172(include "predicates.md") 173(include "constraints.md") 174 175 176;; Move instructions 177 178(define_mode_iterator M [QI HI SI]) 179 180(define_expand "mov<mode>" 181 [(set (match_operand:M 0 "nonimmediate_operand" "") 182 (match_operand:M 1 "general_operand" ""))] 183 "" 184{ 185 if (nios2_emit_move_sequence (operands, <MODE>mode)) 186 DONE; 187}) 188 189(define_insn "*high" 190 [(set (match_operand:SI 0 "register_operand" "=r") 191 (high:SI (match_operand:SI 1 "immediate_operand" "i")))] 192 "" 193 "movhi\\t%0, %H1" 194 [(set_attr "type" "alu")]) 195 196(define_insn "*lo_sum" 197 [(set (match_operand:SI 0 "register_operand" "=r") 198 (lo_sum:SI (match_operand:SI 1 "register_operand" "r") 199 (match_operand:SI 2 "immediate_operand" "i")))] 200 "" 201 "addi\\t%0, %1, %L2" 202 [(set_attr "type" "alu")]) 203 204(define_insn_and_split "movqi_internal" 205 [(set (match_operand:QI 0 "nonimmediate_operand" "=m, r,r") 206 (match_operand:QI 1 "general_operand" "rM,m,rI"))] 207 "(register_operand (operands[0], QImode) 208 || reg_or_0_operand (operands[1], QImode))" 209 { 210 switch (which_alternative) 211 { 212 case 0: 213 if (get_attr_length (insn) != 2) 214 return "stb%o0\\t%z1, %0"; 215 else if (const_0_operand (operands[1], QImode)) 216 return "stbz.n\\t%z1, %0"; 217 else 218 return "stb.n\\t%z1, %0"; 219 case 1: 220 return "ldbu%o1%.\\t%0, %1"; 221 case 2: 222 return "mov%i1%.\\t%0, %z1"; 223 default: 224 gcc_unreachable (); 225 } 226 } 227 "(nios2_large_constant_memory_operand_p (operands[0]) 228 || nios2_large_constant_memory_operand_p (operands[1]))" 229 [(set (match_dup 0) (match_dup 1))] 230 { 231 if (nios2_large_constant_memory_operand_p (operands[0])) 232 operands[0] = nios2_split_large_constant_memory_operand (operands[0]); 233 else 234 operands[1] = nios2_split_large_constant_memory_operand (operands[1]); 235 } 236 [(set_attr "type" "st,ld,mov")]) 237 238(define_insn_and_split "movhi_internal" 239 [(set (match_operand:HI 0 "nonimmediate_operand" "=m, r,r") 240 (match_operand:HI 1 "general_operand" "rM,m,rI"))] 241 "(register_operand (operands[0], HImode) 242 || reg_or_0_operand (operands[1], HImode))" 243 { 244 switch (which_alternative) 245 { 246 case 0: 247 return "sth%o0%.\\t%z1, %0"; 248 case 1: 249 return "ldhu%o1%.\\t%0, %1"; 250 case 2: 251 return "mov%i1%.\\t%0, %z1"; 252 default: 253 gcc_unreachable (); 254 } 255 } 256 "(nios2_large_constant_memory_operand_p (operands[0]) 257 || nios2_large_constant_memory_operand_p (operands[1]))" 258 [(set (match_dup 0) (match_dup 1))] 259 { 260 if (nios2_large_constant_memory_operand_p (operands[0])) 261 operands[0] = nios2_split_large_constant_memory_operand (operands[0]); 262 else 263 operands[1] = nios2_split_large_constant_memory_operand (operands[1]); 264 } 265 [(set_attr "type" "st,ld,mov")]) 266 267(define_insn_and_split "movsi_internal" 268 [(set (match_operand:SI 0 "nonimmediate_operand" "=m, r,r, r") 269 (match_operand:SI 1 "general_operand" "rM,m,rIJK,S"))] 270 "(register_operand (operands[0], SImode) 271 || reg_or_0_operand (operands[1], SImode))" 272 { 273 switch (which_alternative) 274 { 275 case 0: 276 if (get_attr_length (insn) != 2) 277 return "stw%o0\\t%z1, %0"; 278 else if (stack_memory_operand (operands[0], SImode)) 279 return "stwsp.n\\t%z1, %0"; 280 else if (const_0_operand (operands[1], SImode)) 281 return "stwz.n\\t%z1, %0"; 282 else 283 return "stw.n\\t%z1, %0"; 284 case 1: 285 if (get_attr_length (insn) != 2) 286 return "ldw%o1\\t%0, %1"; 287 else if (stack_memory_operand (operands[1], SImode)) 288 return "ldwsp.n\\t%0, %1"; 289 else 290 return "ldw.n\\t%0, %1"; 291 case 2: 292 return "mov%i1%.\\t%0, %z1"; 293 case 3: 294 return "addi\\t%0, gp, %%gprel(%1)"; 295 default: 296 gcc_unreachable (); 297 } 298 } 299 "(nios2_large_constant_memory_operand_p (operands[0]) 300 || nios2_large_constant_memory_operand_p (operands[1]) 301 || (nios2_large_constant_p (operands[1]) 302 && !(CONST_INT_P (operands[1]) 303 && (SMALL_INT_UNSIGNED (INTVAL (operands[1])) 304 || UPPER16_INT (INTVAL (operands[1]))))))" 305 [(set (match_dup 0) (match_dup 1))] 306 { 307 if (nios2_large_constant_memory_operand_p (operands[0])) 308 operands[0] = nios2_split_large_constant_memory_operand (operands[0]); 309 else if (nios2_large_constant_memory_operand_p (operands[1])) 310 operands[1] = nios2_split_large_constant_memory_operand (operands[1]); 311 else 312 operands[1] = nios2_split_large_constant (operands[1], operands[0]); 313 } 314 [(set_attr "type" "st,ld,mov,alu")]) 315 316(define_mode_iterator BH [QI HI]) 317(define_mode_iterator BHW [QI HI SI]) 318(define_mode_attr bh [(QI "b") (HI "h")]) 319(define_mode_attr bhw [(QI "b") (HI "h") (SI "w")]) 320(define_mode_attr bhw_uns [(QI "bu") (HI "hu") (SI "w")]) 321 322(define_insn_and_split "ld<bhw_uns>io" 323 [(set (match_operand:BHW 0 "register_operand" "=r") 324 (unspec_volatile:BHW 325 [(match_operand:BHW 1 "ldstio_memory_operand" "w")] UNSPECV_LDXIO))] 326 "" 327 "ld<bhw_uns>io\\t%0, %1" 328 "nios2_large_constant_memory_operand_p (operands[1])" 329 [(set (match_dup 0) 330 (unspec_volatile:BHW [(match_dup 1)] UNSPECV_LDXIO))] 331 { 332 operands[1] = nios2_split_large_constant_memory_operand (operands[1]); 333 } 334 [(set_attr "type" "ld")]) 335 336(define_expand "ld<bh>io" 337 [(set (match_operand:BH 0 "register_operand" "=r") 338 (match_operand:BH 1 "ldstio_memory_operand" "w"))] 339 "" 340{ 341 rtx tmp = gen_reg_rtx (SImode); 342 emit_insn (gen_ld<bh>io_signed (tmp, operands[1])); 343 emit_insn (gen_mov<mode> (operands[0], gen_lowpart (<MODE>mode, tmp))); 344 DONE; 345}) 346 347(define_insn_and_split "ld<bh>io_signed" 348 [(set (match_operand:SI 0 "register_operand" "=r") 349 (sign_extend:SI 350 (unspec_volatile:BH 351 [(match_operand:BH 1 "ldstio_memory_operand" "w")] UNSPECV_LDXIO)))] 352 "" 353 "ld<bh>io\\t%0, %1" 354 "nios2_large_constant_memory_operand_p (operands[1])" 355 [(set (match_dup 0) 356 (sign_extend:SI (unspec_volatile:BH [(match_dup 1)] UNSPECV_LDXIO)))] 357 { 358 operands[1] = nios2_split_large_constant_memory_operand (operands[1]); 359 } 360 [(set_attr "type" "ld")]) 361 362(define_insn_and_split "st<bhw>io" 363 [(set (match_operand:BHW 0 "ldstio_memory_operand" "=w") 364 (unspec_volatile:BHW 365 [(match_operand:BHW 1 "reg_or_0_operand" "rM")] UNSPECV_STXIO))] 366 "" 367 "st<bhw>io\\t%z1, %0" 368 "nios2_large_constant_memory_operand_p (operands[0])" 369 [(set (match_dup 0) (unspec_volatile:BHW [(match_dup 1)] UNSPECV_STXIO))] 370 { 371 operands[0] = nios2_split_large_constant_memory_operand (operands[0]); 372 } 373 [(set_attr "type" "st")]) 374 375 376;; QI to [HI, SI] extension patterns are collected together 377(define_mode_iterator QX [HI SI]) 378 379;; Zero extension patterns 380(define_insn_and_split "zero_extendhisi2" 381 [(set (match_operand:SI 0 "register_operand" "=r,r") 382 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))] 383 "" 384 "@ 385 andi%.\\t%0, %1, 0xffff 386 ldhu%o1%.\\t%0, %1" 387 "nios2_large_constant_memory_operand_p (operands[1])" 388 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))] 389 { 390 operands[1] = nios2_split_large_constant_memory_operand (operands[1]); 391 } 392 [(set_attr "type" "and,ld")]) 393 394(define_insn_and_split "zero_extendqi<mode>2" 395 [(set (match_operand:QX 0 "register_operand" "=r,r") 396 (zero_extend:QX (match_operand:QI 1 "nonimmediate_operand" "r,m")))] 397 "" 398 "@ 399 andi%.\\t%0, %1, 0xff 400 ldbu%o1%.\\t%0, %1" 401 "nios2_large_constant_memory_operand_p (operands[1])" 402 [(set (match_dup 0) (zero_extend:QX (match_dup 1)))] 403 { 404 operands[1] = nios2_split_large_constant_memory_operand (operands[1]); 405 } 406 [(set_attr "type" "and,ld")]) 407 408;; Sign extension patterns 409 410(define_insn_and_split "extendhisi2" 411 [(set (match_operand:SI 0 "register_operand" "=r,r") 412 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))] 413 "" 414 "@ 415 # 416 ldh%o1%.\\t%0, %1" 417 "nios2_large_constant_memory_operand_p (operands[1])" 418 [(set (match_dup 0) (sign_extend:SI (match_dup 1)))] 419 { 420 operands[1] = nios2_split_large_constant_memory_operand (operands[1]); 421 } 422 [(set_attr "type" "alu,ld")]) 423 424(define_insn_and_split "extendqi<mode>2" 425 [(set (match_operand:QX 0 "register_operand" "=r,r") 426 (sign_extend:QX (match_operand:QI 1 "nonimmediate_operand" "r,m")))] 427 "" 428 "@ 429 # 430 ldb%o1%.\\t%0, %1" 431 "nios2_large_constant_memory_operand_p (operands[1])" 432 [(set (match_dup 0) (sign_extend:QX (match_dup 1)))] 433 { 434 operands[1] = nios2_split_large_constant_memory_operand (operands[1]); 435 } 436 [(set_attr "type" "alu,ld")]) 437 438;; Split patterns for register alternative cases. 439(define_split 440 [(set (match_operand:SI 0 "register_operand" "") 441 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))] 442 "reload_completed" 443 [(set (match_dup 0) 444 (and:SI (match_dup 1) (const_int 65535))) 445 (set (match_dup 0) 446 (xor:SI (match_dup 0) (const_int 32768))) 447 (set (match_dup 0) 448 (plus:SI (match_dup 0) (const_int -32768)))] 449 "operands[1] = gen_lowpart (SImode, operands[1]);") 450 451(define_split 452 [(set (match_operand:QX 0 "register_operand" "") 453 (sign_extend:QX (match_operand:QI 1 "register_operand" "")))] 454 "reload_completed" 455 [(set (match_dup 0) 456 (and:SI (match_dup 1) (const_int 255))) 457 (set (match_dup 0) 458 (xor:SI (match_dup 0) (const_int 128))) 459 (set (match_dup 0) 460 (plus:SI (match_dup 0) (const_int -128)))] 461 "operands[0] = gen_lowpart (SImode, operands[0]); 462 operands[1] = gen_lowpart (SImode, operands[1]);") 463 464 465;; Arithmetic Operations 466 467(define_insn "addsi3" 468 [(set (match_operand:SI 0 "register_operand" "=r") 469 (plus:SI (match_operand:SI 1 "register_operand" "%r") 470 (match_operand:SI 2 "add_regimm_operand" "rIT")))] 471 "" 472{ 473 return nios2_add_insn_asm (insn, operands); 474} 475 [(set_attr "type" "add")]) 476 477(define_insn "subsi3" 478 [(set (match_operand:SI 0 "register_operand" "=r") 479 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rM") 480 (match_operand:SI 2 "register_operand" "r")))] 481 "" 482 "sub%.\\t%0, %z1, %2" 483 [(set_attr "type" "sub")]) 484 485(define_insn "mulsi3" 486 [(set (match_operand:SI 0 "register_operand" "=r") 487 (mult:SI (match_operand:SI 1 "register_operand" "%r") 488 (match_operand:SI 2 "arith_operand" "rI")))] 489 "TARGET_HAS_MUL" 490 "mul%i2\\t%0, %1, %z2" 491 [(set_attr "type" "mul")]) 492 493(define_expand "divsi3" 494 [(set (match_operand:SI 0 "register_operand" "=r") 495 (div:SI (match_operand:SI 1 "register_operand" "r") 496 (match_operand:SI 2 "register_operand" "r")))] 497 "" 498{ 499 if (!TARGET_HAS_DIV) 500 { 501 if (TARGET_FAST_SW_DIV) 502 { 503 nios2_emit_expensive_div (operands, SImode); 504 DONE; 505 } 506 else 507 FAIL; 508 } 509}) 510 511(define_insn "divsi3_insn" 512 [(set (match_operand:SI 0 "register_operand" "=r") 513 (div:SI (match_operand:SI 1 "register_operand" "r") 514 (match_operand:SI 2 "register_operand" "r")))] 515 "TARGET_HAS_DIV" 516 "div\\t%0, %1, %2" 517 [(set_attr "type" "div")]) 518 519(define_insn "udivsi3" 520 [(set (match_operand:SI 0 "register_operand" "=r") 521 (udiv:SI (match_operand:SI 1 "register_operand" "r") 522 (match_operand:SI 2 "register_operand" "r")))] 523 "TARGET_HAS_DIV" 524 "divu\\t%0, %1, %2" 525 [(set_attr "type" "div")]) 526 527(define_code_iterator EXTEND [sign_extend zero_extend]) 528(define_code_attr us [(sign_extend "s") (zero_extend "u")]) 529(define_code_attr mul [(sign_extend "mul") (zero_extend "umul")]) 530 531(define_insn "<us>mulsi3_highpart" 532 [(set (match_operand:SI 0 "register_operand" "=r") 533 (truncate:SI 534 (lshiftrt:DI 535 (mult:DI (EXTEND:DI (match_operand:SI 1 "register_operand" "r")) 536 (EXTEND:DI (match_operand:SI 2 "register_operand" "r"))) 537 (const_int 32))))] 538 "TARGET_HAS_MULX" 539 "mulx<us><us>\\t%0, %1, %2" 540 [(set_attr "type" "mul")]) 541 542(define_expand "<mul>sidi3" 543 [(set (match_operand:DI 0 "register_operand" "") 544 (mult:DI (EXTEND:DI (match_operand:SI 1 "register_operand" "")) 545 (EXTEND:DI (match_operand:SI 2 "register_operand" ""))))] 546 "TARGET_HAS_MULX" 547{ 548 rtx hi = gen_reg_rtx (SImode); 549 rtx lo = gen_reg_rtx (SImode); 550 551 emit_insn (gen_<us>mulsi3_highpart (hi, operands[1], operands[2])); 552 emit_insn (gen_mulsi3 (lo, operands[1], operands[2])); 553 emit_move_insn (gen_lowpart (SImode, operands[0]), lo); 554 emit_move_insn (gen_highpart (SImode, operands[0]), hi); 555 DONE; 556}) 557 558 559;; Negate and ones complement 560 561(define_insn "negsi2" 562 [(set (match_operand:SI 0 "register_operand" "=r") 563 (neg:SI (match_operand:SI 1 "register_operand" "r")))] 564 "" 565{ 566 if (get_attr_length (insn) == 2) 567 return "neg.n\\t%0, %1"; 568 else 569 return "sub\\t%0, zero, %1"; 570} 571 [(set_attr "type" "neg")]) 572 573(define_insn "one_cmplsi2" 574 [(set (match_operand:SI 0 "register_operand" "=r") 575 (not:SI (match_operand:SI 1 "register_operand" "r")))] 576 "" 577{ 578 if (get_attr_length (insn) == 2) 579 return "not.n\\t%0, %1"; 580 else 581 return "nor\\t%0, zero, %1"; 582} 583 [(set_attr "type" "not")]) 584 585 586;; Integer logical Operations 587 588(define_insn "andsi3" 589 [(set (match_operand:SI 0 "register_operand" "=r") 590 (and:SI (match_operand:SI 1 "register_operand" "%r") 591 (match_operand:SI 2 "and_operand" "rJKP")))] 592 "" 593 "and%x2%.\\t%0, %1, %y2" 594 [(set_attr "type" "and")]) 595 596(define_code_iterator LOGICAL [ior xor]) 597(define_code_attr logical_asm [(ior "or") (xor "xor")]) 598 599(define_insn "<code>si3" 600 [(set (match_operand:SI 0 "register_operand" "=r") 601 (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r") 602 (match_operand:SI 2 "logical_operand" "rJK")))] 603 "" 604 "<logical_asm>%x2%.\\t%0, %1, %y2" 605 [(set_attr "type" "<logical_asm>")]) 606 607(define_insn "*norsi3" 608 [(set (match_operand:SI 0 "register_operand" "=r") 609 (and:SI (not:SI (match_operand:SI 1 "register_operand" "%r")) 610 (not:SI (match_operand:SI 2 "register_operand" "r"))))] 611 "" 612 "nor\\t%0, %1, %2" 613 [(set_attr "type" "alu")]) 614 615 616;; Shift instructions 617 618(define_code_iterator SHIFT [ashift ashiftrt lshiftrt rotate]) 619(define_code_attr shift_op [(ashift "ashl") (ashiftrt "ashr") 620 (lshiftrt "lshr") (rotate "rotl")]) 621(define_code_attr shift_asm [(ashift "sll") (ashiftrt "sra") 622 (lshiftrt "srl") (rotate "rol")]) 623 624(define_insn "<shift_op>si3" 625 [(set (match_operand:SI 0 "register_operand" "=r") 626 (SHIFT:SI (match_operand:SI 1 "register_operand" "r") 627 (match_operand:SI 2 "shift_operand" "rL")))] 628 "" 629 "<shift_asm>%i2%.\\t%0, %1, %z2" 630 [(set_attr "type" "<shift_asm>")]) 631 632(define_insn "rotrsi3" 633 [(set (match_operand:SI 0 "register_operand" "=r") 634 (rotatert:SI (match_operand:SI 1 "register_operand" "r") 635 (match_operand:SI 2 "register_operand" "r")))] 636 "" 637 "ror\\t%0, %1, %2" 638 [(set_attr "type" "ror")]) 639 640;; Nios II R2 Bit Manipulation Extension (BMX), provides 641;; bit merge/insertion/extraction instructions. 642 643(define_insn "*merge" 644 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") 645 (match_operand:SI 1 "const_shift_operand" "L") 646 (match_operand:SI 2 "const_shift_operand" "L")) 647 (zero_extract:SI (match_operand:SI 3 "register_operand" "r") 648 (match_dup 1) (match_dup 2)))] 649 "TARGET_HAS_BMX" 650{ 651 operands[4] = GEN_INT (INTVAL (operands[1]) + INTVAL (operands[2]) - 1); 652 return "merge\\t%0, %3, %4, %2"; 653} 654 [(set_attr "type" "alu")]) 655 656(define_insn "extzv" 657 [(set (match_operand:SI 0 "register_operand" "=r") 658 (zero_extract:SI (match_operand:SI 1 "register_operand" "r") 659 (match_operand:SI 2 "const_shift_operand" "L") 660 (match_operand:SI 3 "const_shift_operand" "L")))] 661 "TARGET_HAS_BMX" 662{ 663 operands[4] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]) - 1); 664 return "extract\\t%0, %1, %4, %3"; 665} 666 [(set_attr "type" "alu")]) 667 668(define_insn "insv" 669 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") 670 (match_operand:SI 1 "const_shift_operand" "L") 671 (match_operand:SI 2 "const_shift_operand" "L")) 672 (match_operand:SI 3 "reg_or_0_operand" "rM"))] 673 "TARGET_HAS_BMX" 674{ 675 operands[4] = GEN_INT (INTVAL (operands[1]) + INTVAL (operands[2]) - 1); 676 return "insert\\t%0, %z3, %4, %2"; 677} 678 [(set_attr "type" "alu")]) 679 680 681 682;; Floating point instructions 683 684;; Mode iterator for single/double float 685(define_mode_iterator F [SF DF]) 686(define_mode_attr f [(SF "s") (DF "d")]) 687 688;; Basic arithmetic instructions 689(define_code_iterator FOP3 [plus minus mult div]) 690(define_code_attr fop3 [(plus "add") (minus "sub") (mult "mul") (div "div")]) 691 692(define_insn "<fop3><mode>3" 693 [(set (match_operand:F 0 "register_operand" "=r") 694 (FOP3:F (match_operand:F 1 "register_operand" "r") 695 (match_operand:F 2 "register_operand" "r")))] 696 "nios2_fpu_insn_enabled (n2fpu_f<fop3><f>)" 697 { return nios2_fpu_insn_asm (n2fpu_f<fop3><f>); } 698 [(set_attr "type" "custom")]) 699 700;; Floating point min/max operations 701(define_code_iterator SMINMAX [smin smax]) 702(define_code_attr minmax [(smin "min") (smax "max")]) 703(define_insn "<code><mode>3" 704 [(set (match_operand:F 0 "register_operand" "=r") 705 (SMINMAX:F (match_operand:F 1 "register_operand" "r") 706 (match_operand:F 2 "register_operand" "r")))] 707 "nios2_fpu_insn_enabled (n2fpu_f<minmax><f>)" 708 { return nios2_fpu_insn_asm (n2fpu_f<minmax><f>); } 709 [(set_attr "type" "custom")]) 710 711;; These 2-operand FP operations can be collected together 712(define_code_iterator FOP2 [abs neg sqrt]) 713(define_insn "<code><mode>2" 714 [(set (match_operand:F 0 "register_operand" "=r") 715 (FOP2:F (match_operand:F 1 "register_operand" "r")))] 716 "nios2_fpu_insn_enabled (n2fpu_f<code><f>)" 717 { return nios2_fpu_insn_asm (n2fpu_f<code><f>); } 718 [(set_attr "type" "custom")]) 719 720;; X, Y register access instructions 721(define_insn "nios2_fwrx" 722 [(unspec_volatile [(match_operand:DF 0 "register_operand" "r")] UNSPECV_FWRX)] 723 "nios2_fpu_insn_enabled (n2fpu_fwrx)" 724 { return nios2_fpu_insn_asm (n2fpu_fwrx); } 725 [(set_attr "type" "custom")]) 726 727(define_insn "nios2_fwry" 728 [(unspec_volatile [(match_operand:SF 0 "register_operand" "r")] UNSPECV_FWRY)] 729 "nios2_fpu_insn_enabled (n2fpu_fwry)" 730 { return nios2_fpu_insn_asm (n2fpu_fwry); } 731 [(set_attr "type" "custom")]) 732 733;; The X, Y read insns uses an int iterator 734(define_int_iterator UNSPEC_READ_XY [UNSPECV_FRDXLO UNSPECV_FRDXHI 735 UNSPECV_FRDY]) 736(define_int_attr read_xy [(UNSPECV_FRDXLO "frdxlo") (UNSPECV_FRDXHI "frdxhi") 737 (UNSPECV_FRDY "frdy")]) 738(define_insn "nios2_<read_xy>" 739 [(set (match_operand:SF 0 "register_operand" "=r") 740 (unspec_volatile:SF [(const_int 0)] UNSPEC_READ_XY))] 741 "nios2_fpu_insn_enabled (n2fpu_<read_xy>)" 742 { return nios2_fpu_insn_asm (n2fpu_<read_xy>); } 743 [(set_attr "type" "custom")]) 744 745;; Various math functions 746(define_int_iterator MATHFUNC 747 [UNSPEC_FCOS UNSPEC_FSIN UNSPEC_FTAN UNSPEC_FATAN UNSPEC_FEXP UNSPEC_FLOG]) 748(define_int_attr mathfunc [(UNSPEC_FCOS "cos") (UNSPEC_FSIN "sin") 749 (UNSPEC_FTAN "tan") (UNSPEC_FATAN "atan") 750 (UNSPEC_FEXP "exp") (UNSPEC_FLOG "log")]) 751 752(define_insn "<mathfunc><mode>2" 753 [(set (match_operand:F 0 "register_operand" "=r") 754 (unspec:F [(match_operand:F 1 "register_operand" "r")] MATHFUNC))] 755 "nios2_fpu_insn_enabled (n2fpu_f<mathfunc><f>)" 756 { return nios2_fpu_insn_asm (n2fpu_f<mathfunc><f>); } 757 [(set_attr "type" "custom")]) 758 759;; Converting between floating point and fixed point 760 761(define_code_iterator FLOAT [float unsigned_float]) 762(define_code_iterator FIX [fix unsigned_fix]) 763 764(define_code_attr conv_op [(float "float") (unsigned_float "floatuns") 765 (fix "fix") (unsigned_fix "fixuns")]) 766(define_code_attr i [(float "i") (unsigned_float "u") 767 (fix "i") (unsigned_fix "u")]) 768 769;; Integer to float conversions 770(define_insn "<conv_op>si<mode>2" 771 [(set (match_operand:F 0 "register_operand" "=r") 772 (FLOAT:F (match_operand:SI 1 "register_operand" "r")))] 773 "nios2_fpu_insn_enabled (n2fpu_float<i><f>)" 774 { return nios2_fpu_insn_asm (n2fpu_float<i><f>); } 775 [(set_attr "type" "custom")]) 776 777;; Float to integer conversions 778(define_insn "<conv_op>_trunc<mode>si2" 779 [(set (match_operand:SI 0 "register_operand" "=r") 780 (FIX:SI (match_operand:F 1 "general_operand" "r")))] 781 "nios2_fpu_insn_enabled (n2fpu_fix<f><i>)" 782 { return nios2_fpu_insn_asm (n2fpu_fix<f><i>); } 783 [(set_attr "type" "custom")]) 784 785(define_insn "lroundsfsi2" 786 [(set (match_operand:SI 0 "register_operand" "=r") 787 (unspec:SI [(match_operand:SF 1 "general_operand" "r")] UNSPEC_ROUND))] 788 "nios2_fpu_insn_enabled (n2fpu_round)" 789 { return nios2_fpu_insn_asm (n2fpu_round); } 790 [(set_attr "type" "custom")]) 791 792(define_insn "extendsfdf2" 793 [(set (match_operand:DF 0 "register_operand" "=r") 794 (float_extend:DF (match_operand:SF 1 "general_operand" "r")))] 795 "nios2_fpu_insn_enabled (n2fpu_fextsd)" 796 { return nios2_fpu_insn_asm (n2fpu_fextsd); } 797 [(set_attr "type" "custom")]) 798 799(define_insn "truncdfsf2" 800 [(set (match_operand:SF 0 "register_operand" "=r") 801 (float_truncate:SF (match_operand:DF 1 "general_operand" "r")))] 802 "nios2_fpu_insn_enabled (n2fpu_ftruncds)" 803 { return nios2_fpu_insn_asm (n2fpu_ftruncds); } 804 [(set_attr "type" "custom")]) 805 806 807 808;; Prologue, Epilogue and Return 809 810(define_expand "prologue" 811 [(const_int 1)] 812 "" 813{ 814 nios2_expand_prologue (); 815 DONE; 816}) 817 818(define_expand "epilogue" 819 [(return)] 820 "" 821{ 822 nios2_expand_epilogue (false); 823 DONE; 824}) 825 826(define_expand "sibcall_epilogue" 827 [(return)] 828 "" 829{ 830 nios2_expand_epilogue (true); 831 DONE; 832}) 833 834(define_expand "return" 835 [(simple_return)] 836 "nios2_can_use_return_insn ()" 837{ 838 if (nios2_expand_return ()) 839 DONE; 840}) 841 842(define_insn "simple_return" 843 [(simple_return)] 844 "" 845 "ret%." 846 [(set_attr "type" "control")]) 847 848;; Block any insns from being moved before this point, since the 849;; profiling call to mcount can use various registers that aren't 850;; saved or used to pass arguments. 851 852(define_insn "blockage" 853 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)] 854 "" 855 "" 856 [(set_attr "type" "unknown") 857 (set_attr "length" "0")]) 858 859;; This is used in compiling the unwind routines. 860(define_expand "eh_return" 861 [(use (match_operand 0 "general_operand"))] 862 "" 863{ 864 if (GET_MODE (operands[0]) != Pmode) 865 operands[0] = convert_to_mode (Pmode, operands[0], 0); 866 emit_insn (gen_eh_set_ra (operands[0])); 867 DONE; 868}) 869 870;; Modify the return address for EH return. We can't expand this 871;; until we know where it will be put in the stack frame. 872 873(define_insn_and_split "eh_set_ra" 874 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN) 875 (clobber (match_scratch:SI 1 "=&r"))] 876 "" 877 "#" 878 "reload_completed" 879 [(const_int 0)] 880{ 881 nios2_set_return_address (operands[0], operands[1]); 882 DONE; 883}) 884 885 886;; Jumps and calls 887 888; Note that the assembler fixes up any out-of-range branch instructions not 889; caught by the compiler branch shortening code. The sequence emitted by 890; the assembler can be very inefficient, but it is correct for PIC code. 891; For non-PIC we are better off converting to an absolute JMPI. 892; 893; Direct calls and sibcalls use the CALL and JMPI instructions, respectively. 894; These instructions have an immediate operand that specifies the low 28 bits 895; of the PC, effectively allowing direct calls within a 256MB memory segment. 896; Per the Nios II Processor Reference Handbook, the linker is not required to 897; check or adjust for overflow. 898 899(define_insn "indirect_jump" 900 [(set (pc) (match_operand:SI 0 "register_operand" "c"))] 901 "" 902 "jmp%!\\t%0" 903 [(set_attr "type" "control")]) 904 905(define_insn "jump" 906 [(set (pc) 907 (label_ref (match_operand 0 "" "")))] 908 "" 909 { 910 if (get_attr_length (insn) == 2) 911 return "br.n\\t%0"; 912 else if (get_attr_length (insn) == 4) 913 return "br\\t%0"; 914 else 915 return "jmpi\\t%0"; 916 } 917 [(set_attr "type" "control") 918 (set (attr "length") 919 (if_then_else 920 (and (match_test "TARGET_HAS_CDX") 921 (and (ge (minus (match_dup 0) (pc)) (const_int -1022)) 922 (le (minus (match_dup 0) (pc)) (const_int 1022)))) 923 (const_int 2) 924 (if_then_else 925 (ior (match_test "flag_pic") 926 (and (ge (minus (match_dup 0) (pc)) (const_int -32764)) 927 (le (minus (match_dup 0) (pc)) (const_int 32764)))) 928 (const_int 4) 929 (const_int 8))))]) 930 931(define_expand "call" 932 [(parallel [(call (match_operand 0 "" "") 933 (match_operand 1 "" "")) 934 (clobber (reg:SI RA_REGNO))])] 935 "" 936 "nios2_adjust_call_address (&operands[0], NULL_RTX);") 937 938(define_expand "call_value" 939 [(parallel [(set (match_operand 0 "" "") 940 (call (match_operand 1 "" "") 941 (match_operand 2 "" ""))) 942 (clobber (reg:SI RA_REGNO))])] 943 "" 944 "nios2_adjust_call_address (&operands[1], NULL_RTX);") 945 946(define_insn "*call" 947 [(call (mem:QI (match_operand:SI 0 "call_operand" "i,r")) 948 (match_operand 1 "" "")) 949 (clobber (reg:SI RA_REGNO))] 950 "" 951 "@ 952 call\\t%0 953 callr%.\\t%0" 954 [(set_attr "type" "control")]) 955 956(define_insn "*call_value" 957 [(set (match_operand 0 "" "") 958 (call (mem:QI (match_operand:SI 1 "call_operand" "i,r")) 959 (match_operand 2 "" ""))) 960 (clobber (reg:SI RA_REGNO))] 961 "" 962 "@ 963 call\\t%1 964 callr%.\\t%1" 965 [(set_attr "type" "control")]) 966 967(define_expand "sibcall" 968 [(parallel [(call (match_operand 0 "" "") 969 (match_operand 1 "" "")) 970 (return)])] 971 "" 972 "nios2_adjust_call_address (&operands[0], NULL_RTX);") 973 974(define_expand "sibcall_value" 975 [(parallel [(set (match_operand 0 "" "") 976 (call (match_operand 1 "" "") 977 (match_operand 2 "" ""))) 978 (return)])] 979 "" 980 "nios2_adjust_call_address (&operands[1], NULL_RTX);") 981 982(define_insn "sibcall_internal" 983 [(call (mem:QI (match_operand:SI 0 "call_operand" "i,j")) 984 (match_operand 1 "" "")) 985 (return)] 986 "" 987 "@ 988 jmpi\\t%0 989 jmp%!\\t%0" 990 [(set_attr "type" "control")]) 991 992(define_insn "sibcall_value_internal" 993 [(set (match_operand 0 "register_operand" "") 994 (call (mem:QI (match_operand:SI 1 "call_operand" "i,j")) 995 (match_operand 2 "" ""))) 996 (return)] 997 "" 998 "@ 999 jmpi\\t%1 1000 jmp%!\\t%1" 1001 [(set_attr "type" "control")]) 1002 1003(define_expand "tablejump" 1004 [(parallel [(set (pc) (match_operand 0 "register_operand" "r")) 1005 (use (label_ref (match_operand 1 "" "")))])] 1006 "" 1007{ 1008 if (flag_pic) 1009 { 1010 /* Hopefully, CSE will eliminate this copy. */ 1011 rtx reg1 = copy_addr_to_reg (gen_rtx_LABEL_REF (Pmode, operands[1])); 1012 rtx reg2 = gen_reg_rtx (SImode); 1013 1014 emit_insn (gen_addsi3 (reg2, operands[0], reg1)); 1015 operands[0] = reg2; 1016 } 1017}) 1018 1019(define_insn "*tablejump" 1020 [(set (pc) 1021 (match_operand:SI 0 "register_operand" "c")) 1022 (use (label_ref (match_operand 1 "" "")))] 1023 "" 1024 "jmp%!\\t%0" 1025 [(set_attr "type" "control")]) 1026 1027 1028;; cstore, cbranch patterns 1029 1030(define_mode_iterator CM [SI SF DF]) 1031 1032(define_expand "cstore<mode>4" 1033 [(set (match_operand:SI 0 "register_operand" "=r") 1034 (match_operator:SI 1 "expandable_comparison_operator" 1035 [(match_operand:CM 2 "register_operand") 1036 (match_operand:CM 3 "nonmemory_operand")]))] 1037 "" 1038{ 1039 if (!nios2_validate_compare (<MODE>mode, &operands[1], &operands[2], 1040 &operands[3])) 1041 FAIL; 1042}) 1043 1044(define_expand "cbranch<mode>4" 1045 [(set (pc) 1046 (if_then_else 1047 (match_operator 0 "expandable_comparison_operator" 1048 [(match_operand:CM 1 "register_operand") 1049 (match_operand:CM 2 "nonmemory_operand")]) 1050 (label_ref (match_operand 3 "")) 1051 (pc)))] 1052 "" 1053{ 1054 if (!nios2_validate_compare (<MODE>mode, &operands[0], &operands[1], 1055 &operands[2])) 1056 FAIL; 1057 if (GET_MODE_CLASS (<MODE>mode) == MODE_FLOAT 1058 || !reg_or_0_operand (operands[2], <MODE>mode)) 1059 { 1060 rtx condreg = gen_reg_rtx (SImode); 1061 emit_insn (gen_cstore<mode>4 1062 (condreg, operands[0], operands[1], operands[2])); 1063 operands[1] = condreg; 1064 operands[2] = const0_rtx; 1065 operands[0] = gen_rtx_fmt_ee (NE, VOIDmode, condreg, const0_rtx); 1066 } 1067}) 1068 1069(define_insn "nios2_cbranch" 1070 [(set (pc) 1071 (if_then_else 1072 (match_operator 0 "ordered_comparison_operator" 1073 [(match_operand:SI 1 "reg_or_0_operand" "rM") 1074 (match_operand:SI 2 "reg_or_0_operand" "rM")]) 1075 (label_ref (match_operand 3 "" "")) 1076 (pc)))] 1077 "" 1078{ 1079 if (get_attr_length (insn) == 2) 1080 return "b%0z.n\t%z1, %l3"; 1081 else if (get_attr_length (insn) == 4) 1082 return "b%0\t%z1, %z2, %l3"; 1083 else if (get_attr_length (insn) == 6) 1084 return "b%R0z.n\t%z1, .+6;jmpi\t%l3"; 1085 else 1086 return "b%R0\t%z1, %z2, .+8;jmpi\t%l3"; 1087} 1088 [(set_attr "type" "control") 1089 (set (attr "length") 1090 (cond 1091 [(and (match_test "nios2_cdx_narrow_form_p (insn)") 1092 (ge (minus (match_dup 3) (pc)) (const_int -126)) 1093 (le (minus (match_dup 3) (pc)) (const_int 126))) 1094 (const_int 2) 1095 (ior (match_test "flag_pic") 1096 (and (ge (minus (match_dup 3) (pc)) (const_int -32764)) 1097 (le (minus (match_dup 3) (pc)) (const_int 32764)))) 1098 (const_int 4) 1099 (match_test "nios2_cdx_narrow_form_p (insn)") 1100 (const_int 6)] 1101 (const_int 8)))]) 1102 1103;; Floating point comparisons 1104(define_code_iterator FCMP [eq ne gt ge le lt]) 1105(define_insn "nios2_s<code><mode>" 1106 [(set (match_operand:SI 0 "register_operand" "=r") 1107 (FCMP:SI (match_operand:F 1 "register_operand" "r") 1108 (match_operand:F 2 "register_operand" "r")))] 1109 "nios2_fpu_insn_enabled (n2fpu_fcmp<code><f>)" 1110 { return nios2_fpu_insn_asm (n2fpu_fcmp<code><f>); } 1111 [(set_attr "type" "custom")]) 1112 1113;; Integer comparisons 1114 1115(define_code_iterator EQNE [eq ne]) 1116(define_insn "nios2_cmp<code>" 1117 [(set (match_operand:SI 0 "register_operand" "=r") 1118 (EQNE:SI (match_operand:SI 1 "register_operand" "%r") 1119 (match_operand:SI 2 "arith_operand" "rI")))] 1120 "" 1121 "cmp<code>%i2\\t%0, %1, %z2" 1122 [(set_attr "type" "alu")]) 1123 1124(define_code_iterator SCMP [ge lt]) 1125(define_insn "nios2_cmp<code>" 1126 [(set (match_operand:SI 0 "register_operand" "=r") 1127 (SCMP:SI (match_operand:SI 1 "reg_or_0_operand" "rM") 1128 (match_operand:SI 2 "arith_operand" "rI")))] 1129 "" 1130 "cmp<code>%i2\\t%0, %z1, %z2" 1131 [(set_attr "type" "alu")]) 1132 1133(define_code_iterator UCMP [geu ltu]) 1134(define_insn "nios2_cmp<code>" 1135 [(set (match_operand:SI 0 "register_operand" "=r") 1136 (UCMP:SI (match_operand:SI 1 "reg_or_0_operand" "rM") 1137 (match_operand:SI 2 "uns_arith_operand" "rJ")))] 1138 "" 1139 "cmp<code>%u2\\t%0, %z1, %z2" 1140 [(set_attr "type" "alu")]) 1141 1142 1143 1144;; Custom instruction patterns. The operands are intentionally 1145;; mode-less, to serve as generic carriers of all Altera defined 1146;; built-in instruction/function types. 1147 1148(define_insn "custom_nxx" 1149 [(unspec_volatile [(match_operand 0 "custom_insn_opcode" "N") 1150 (match_operand 1 "reg_or_0_operand" "rM") 1151 (match_operand 2 "reg_or_0_operand" "rM")] 1152 UNSPECV_CUSTOM_NXX)] 1153 "" 1154 "custom\\t%0, zero, %z1, %z2" 1155 [(set_attr "type" "custom")]) 1156 1157(define_insn "custom_xnxx" 1158 [(set (match_operand 0 "register_operand" "=r") 1159 (unspec_volatile [(match_operand 1 "custom_insn_opcode" "N") 1160 (match_operand 2 "reg_or_0_operand" "rM") 1161 (match_operand 3 "reg_or_0_operand" "rM")] 1162 UNSPECV_CUSTOM_XNXX))] 1163 "" 1164 "custom\\t%1, %0, %z2, %z3" 1165 [(set_attr "type" "custom")]) 1166 1167 1168;; Misc. patterns 1169 1170(define_insn "nop" 1171 [(const_int 0)] 1172 "" 1173 "nop%." 1174 [(set_attr "type" "nop")]) 1175 1176;; Connect 'sync' to 'memory_barrier' standard expand name 1177(define_expand "memory_barrier" 1178 [(const_int 0)] 1179 "" 1180{ 1181 emit_insn (gen_sync ()); 1182 DONE; 1183}) 1184 1185;; For the nios2 __builtin_sync built-in function 1186(define_expand "sync" 1187 [(set (match_dup 0) 1188 (unspec:BLK [(match_dup 0)] UNSPEC_SYNC))] 1189 "" 1190{ 1191 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); 1192 MEM_VOLATILE_P (operands[0]) = 1; 1193}) 1194 1195(define_insn "*sync_insn" 1196 [(set (match_operand:BLK 0 "" "") 1197 (unspec:BLK [(match_dup 0)] UNSPEC_SYNC))] 1198 "" 1199 "sync" 1200 [(set_attr "type" "control")]) 1201 1202(define_insn "rdctl" 1203 [(set (match_operand:SI 0 "register_operand" "=r") 1204 (unspec_volatile:SI [(match_operand:SI 1 "rdwrctl_operand" "O")] 1205 UNSPECV_RDCTL))] 1206 "" 1207 "rdctl\\t%0, ctl%1" 1208 [(set_attr "type" "control")]) 1209 1210(define_insn "wrctl" 1211 [(unspec_volatile:SI [(match_operand:SI 0 "rdwrctl_operand" "O") 1212 (match_operand:SI 1 "reg_or_0_operand" "rM")] 1213 UNSPECV_WRCTL)] 1214 "" 1215 "wrctl\\tctl%0, %z1" 1216 [(set_attr "type" "control")]) 1217 1218(define_insn "rdprs" 1219 [(set (match_operand:SI 0 "register_operand" "=r") 1220 (unspec_volatile:SI [(match_operand:SI 1 "rdwrctl_operand" "O") 1221 (match_operand:SI 2 "arith_operand" "U")] 1222 UNSPECV_RDPRS))] 1223 "" 1224 "rdprs\\t%0, %1, %2" 1225 [(set_attr "type" "control")]) 1226 1227;; Cache Instructions 1228 1229(define_insn "flushd" 1230 [(unspec_volatile:SI [(match_operand:SI 0 "ldstio_memory_operand" "w")] 1231 UNSPECV_FLUSHD)] 1232 "" 1233 "flushd\\t%0" 1234 [(set_attr "type" "control")]) 1235 1236(define_insn "flushda" 1237 [(unspec_volatile:SI [(match_operand:SI 0 "ldstio_memory_operand" "w")] 1238 UNSPECV_FLUSHDA)] 1239 "" 1240 "flushda\\t%0" 1241 [(set_attr "type" "control")]) 1242 1243;; R2 Instructions 1244 1245(define_insn "wrpie" 1246 [(set (match_operand:SI 0 "register_operand" "=r") 1247 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "r")] 1248 UNSPECV_WRPIE))] 1249 "TARGET_ARCH_R2" 1250 "wrpie\\t%0, %1" 1251 [(set_attr "type" "control")]) 1252 1253(define_insn "eni" 1254 [(unspec:VOID [(match_operand 0 "const_int_operand" "i")] 1255 UNSPECV_ENI)] 1256 "TARGET_ARCH_R2" 1257 "eni\\t%0" 1258 [(set_attr "type" "control")]) 1259 1260;; Trap patterns 1261(define_insn "trap" 1262 [(trap_if (const_int 1) (const_int 3))] 1263 "" 1264 "trap%.\\t3" 1265 [(set_attr "type" "control")]) 1266 1267(define_insn "ctrapsi4" 1268 [(trap_if (match_operator 0 "ordered_comparison_operator" 1269 [(match_operand:SI 1 "reg_or_0_operand" "rM") 1270 (match_operand:SI 2 "reg_or_0_operand" "rM")]) 1271 (match_operand 3 "const_int_operand" "i"))] 1272 "" 1273{ 1274 if (get_attr_length (insn) == 6) 1275 return "b%R0\\t%z1, %z2, 1f\;trap.n\\t%3\;1:"; 1276 else 1277 return "b%R0\\t%z1, %z2, 1f\;trap\\t%3\;1:"; 1278} 1279 [(set_attr "type" "control") 1280 (set (attr "length") 1281 (if_then_else (match_test "nios2_cdx_narrow_form_p (insn)") 1282 (const_int 6) (const_int 8)))]) 1283 1284;; Load the GOT register. 1285(define_insn "load_got_register" 1286 [(set (match_operand:SI 0 "register_operand" "=&r") 1287 (unspec:SI [(const_int 0)] UNSPEC_LOAD_GOT_REGISTER)) 1288 (set (match_operand:SI 1 "register_operand" "=r") 1289 (unspec:SI [(const_int 0)] UNSPEC_LOAD_GOT_REGISTER))] 1290 "" 1291 "nextpc\\t%0 1292\\t1: 1293\\tmovhi\\t%1, %%hiadj(_gp_got - 1b) 1294\\taddi\\t%1, %1, %%lo(_gp_got - 1b)" 1295 [(set_attr "length" "12")]) 1296 1297;; Read thread pointer register 1298(define_expand "get_thread_pointersi" 1299 [(match_operand:SI 0 "register_operand" "=r")] 1300 "TARGET_LINUX_ABI" 1301{ 1302 emit_move_insn (operands[0], gen_rtx_REG (Pmode, TP_REGNO)); 1303 DONE; 1304}) 1305 1306;; Synchronization Primitives 1307(include "sync.md") 1308 1309;; Include the ldwm/stwm/push.n/pop.n patterns and peepholes. 1310(include "ldstwm.md") 1311 1312