1;; Machine Description for TI PRU. 2;; Copyright (C) 2014-2020 Free Software Foundation, Inc. 3;; Contributed by Dimitar Dimitrov <dimitar@dinux.eu> 4;; Based on the NIOS2 GCC port. 5;; 6;; This file is part of GCC. 7;; 8;; GCC is free software; you can redistribute it and/or modify 9;; it under the terms of the GNU General Public License as published by 10;; the Free Software Foundation; either version 3, or (at your option) 11;; any later version. 12;; 13;; GCC is distributed in the hope that it will be useful, 14;; but WITHOUT ANY WARRANTY; without even the implied warranty of 15;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16;; GNU General Public License for more details. 17;; 18;; You should have received a copy of the GNU General Public License 19;; along with GCC; see the file COPYING3. If not see 20;; <http://www.gnu.org/licenses/>. 21 22;; Register numbers. 23(define_constants 24 [ 25 (FIRST_ARG_REGNUM 56) ; Argument registers. 26 (LAST_ARG_REGNUM 119) ; 27 (FIRST_RETVAL_REGNUM 56) ; Return value registers. 28 (LAST_RETVAL_REGNUM 60) ; 29 (FIRST_CALLEE_SAVED_REGNUM 12) ; Callee saved registers. 30 (LAST_CALEE_SAVED_REGNUM 55) ; 31 (PROLOGUE_TEMP_REGNUM 4) ; Temporary register to use in prologue. 32 33 (RA_REGNUM 14) ; Return address register r3.w2. 34 (FP_REGNUM 16) ; Frame pointer register. 35 (MULDST_REGNUM 104) ; Multiply destination register. 36 (MULSRC0_REGNUM 112) ; Multiply source register. 37 (MULSRC1_REGNUM 116) ; Multiply source register. 38 (LAST_NONIO_GP_REGNUM 119) ; Last non-I/O general purpose register. 39 (LOOPCNTR_REGNUM 128) ; internal LOOP counter register 40 (LAST_GP_REGNUM 132) ; Last general purpose register. 41 42 ;; Target register definitions. 43 (STACK_POINTER_REGNUM 8) 44 (HARD_FRAME_POINTER_REGNUM FP_REGNUM) 45 (PC_REGNUM 132) 46 (FRAME_POINTER_REGNUM 136) 47 (ARG_POINTER_REGNUM 140) 48 (FIRST_PSEUDO_REGISTER 144) 49 ] 50) 51 52;; Enumeration of UNSPECs. 53 54(define_c_enum "unspecv" [ 55 UNSPECV_DELAY_CYCLES_START 56 UNSPECV_DELAY_CYCLES_END 57 UNSPECV_DELAY_CYCLES_2X_HI 58 UNSPECV_DELAY_CYCLES_2X_SI 59 UNSPECV_DELAY_CYCLES_1 60 61 UNSPECV_LOOP_BEGIN 62 UNSPECV_LOOP_END 63 64 UNSPECV_BLOCKAGE 65]) 66 67; Length of an instruction (in bytes). 68(define_attr "length" "" (const_int 4)) 69(define_attr "type" 70 "unknown,complex,control,alu,cond_alu,st,ld,shift" 71 (const_string "complex")) 72 73(define_asm_attributes 74 [(set_attr "length" "4") 75 (set_attr "type" "complex")]) 76 77; There is no pipeline, so our scheduling description is simple. 78(define_automaton "pru") 79(define_cpu_unit "cpu" "pru") 80 81(define_insn_reservation "everything" 1 (match_test "true") "cpu") 82 83(include "predicates.md") 84(include "constraints.md") 85 86;; All supported direct move-modes 87(define_mode_iterator MOV8_16_32 [QI QQ UQQ 88 HI HQ UHQ HA UHA 89 SI SQ USQ SA USA SF SD]) 90 91(define_mode_iterator MOV8_16 [QI QQ UQQ 92 HI HQ UHQ HA UHA]) 93(define_mode_iterator MOV32 [SI SQ USQ SA USA SF SD]) 94(define_mode_iterator MOV64 [DI DF DD DQ UDQ]) 95(define_mode_iterator QISI [QI HI SI]) 96(define_mode_iterator HISI [HI SI]) 97(define_mode_iterator SFDF [SF DF]) 98 99;; EQS0/1 for extension source 0/1 and EQD for extension destination patterns. 100(define_mode_iterator EQS0 [QI HI SI]) 101(define_mode_iterator EQS1 [QI HI SI]) 102(define_mode_iterator EQD [QI HI SI]) 103 104;; GCC sign-extends its integer constants. Hence 0x80 will be represented 105;; as -128 for QI mode and 128 for HI and SI modes. To cope with this, 106;; use different constraints to match UBYTE in different modes. 107;; 108;; Wherever this iterator is used, the corresponding operand has the 'u' 109;; print format modifier. That is how the QI signedness is cured, and 110;; the generated assembly contains unsigned constants. 111;; 112;; If the pattern has no QI operands, then this iterator need not be used. 113;; 114;; Note that we do not require "uhword_constr" since ALU instructions 115;; can use only UBYTE constants. The MOV patterns are already separately 116;; defined for each size, hence no need for an iterator. 117(define_mode_attr ubyte_constr [(QI "O") (HI "I") (SI "I")]) 118 119;; Move instructions 120 121(define_expand "mov<mode>" 122 [(set (match_operand:MOV8_16_32 0 "nonimmediate_operand") 123 (match_operand:MOV8_16_32 1 "general_operand"))] 124 "" 125{ 126 /* It helps to split constant loading and memory access 127 early, so that the LDI/LDI32 instructions can be hoisted 128 outside a loop body. */ 129 if (MEM_P (operands[0])) 130 operands[1] = force_reg (<MODE>mode, operands[1]); 131}) 132 133;; Keep a single pattern for 32 bit MOV operations. LRA requires that the 134;; movXX patterns be unified for any given mode. 135;; 136;; Note: Assume that Program Mem (T constraint) can fit in 16 bits! 137(define_insn "prumov<mode>" 138 [(set (match_operand:MOV32 0 "nonimmediate_operand" "=m,r,r,r,r,r") 139 (match_operand:MOV32 1 "general_operand" "r,m,r,T,J,iF"))] 140 "" 141 "@ 142 sb%B0o\\t%b1, %0, %S0 143 lb%B1o\\t%b0, %1, %S1 144 mov\\t%0, %1 145 ldi\\t%0, %%pmem(%1) 146 ldi\\t%0, %1 147 ldi32\\t%0, %1" 148 [(set_attr "type" "st,ld,alu,alu,alu,alu") 149 (set_attr "length" "4,4,4,4,4,8")]) 150 151 152;; Separate pattern for 8 and 16 bit moves, since LDI32 pseudo instruction 153;; cannot handle byte and word-sized registers. 154;; 155;; Note: Constraint N is fine for both QI and HI mode, since it is used 156;; in the context of 16 bit constant integer. 157(define_insn "prumov<mode>" 158 [(set (match_operand:MOV8_16 0 "nonimmediate_operand" "=m,r,r,r,r") 159 (match_operand:MOV8_16 1 "general_operand" "r,m,r,T,N"))] 160 "" 161 "@ 162 sb%B0o\\t%b1, %0, %S0 163 lb%B1o\\t%b0, %1, %S1 164 mov\\t%0, %1 165 ldi\\t%0, %%pmem(%1) 166 ldi\\t%0, (%1) & 0xffff" 167 [(set_attr "type" "st,ld,alu,alu,alu") 168 (set_attr "length" "4")]) 169 170 171; Pmode is 32 bits for PRU so symbolic constants cannot be 64 bits. Hence 172; this pattern handles only numeric constants. 173; 174; Note: Unlike the arithmetics, here we cannot use "&" output modifier. 175; GCC expects to be able to move registers around "no matter what". 176; Forcing DI reg alignment (akin to microblaze's HARD_REGNO_MODE_OK) 177; does not seem efficient, and will violate TI ABI. 178(define_insn "mov<mode>" 179 [(set (match_operand:MOV64 0 "nonimmediate_operand" "=m,r,r,r,r,r") 180 (match_operand:MOV64 1 "general_operand" "r,m,r,T,J,nF"))] 181 "" 182{ 183 switch (which_alternative) 184 { 185 case 0: 186 return "sb%B0o\\t%b1, %0, %S0"; 187 case 1: 188 return "lb%B1o\\t%b0, %1, %S1"; 189 case 2: 190 /* careful with overlapping source and destination regs. */ 191 gcc_assert (GP_REG_P (REGNO (operands[0]))); 192 gcc_assert (GP_REG_P (REGNO (operands[1]))); 193 if (REGNO (operands[0]) == (REGNO (operands[1]) + 4)) 194 return "mov\\t%N0, %N1\;mov\\t%F0, %F1"; 195 else 196 return "mov\\t%F0, %F1\;mov\\t%N0, %N1"; 197 case 3: 198 return "ldi\\t%F0, %%pmem(%1)\;ldi\\t%N0, 0"; 199 case 4: 200 return "ldi\\t%F0, %1\;ldi\\t%N0, 0"; 201 case 5: 202 return "ldi32\\t%F0, %w1\;ldi32\\t%N0, %W1"; 203 default: 204 gcc_unreachable (); 205 } 206} 207 [(set_attr "type" "st,ld,alu,alu,alu,alu") 208 (set_attr "length" "4,4,8,8,8,16")]) 209 210; 211; load_multiple pattern(s). 212; 213; ??? Due to reload problems with replacing registers inside match_parallel 214; we currently support load_multiple/store_multiple only after reload. 215; 216; Idea taken from the s390 port. 217 218(define_expand "load_multiple" 219 [(match_par_dup 3 [(set (match_operand 0 "") 220 (match_operand 1 "")) 221 (use (match_operand 2 ""))])] 222 "reload_completed" 223{ 224 machine_mode mode; 225 int regno; 226 int count; 227 rtx base_reg; 228 poly_int64 base_offs; 229 int i; 230 231 /* Support only loading a constant number of fixed-point registers from 232 memory. */ 233 if (GET_CODE (operands[2]) != CONST_INT 234 || GET_CODE (operands[1]) != MEM 235 || GET_CODE (operands[0]) != REG) 236 FAIL; 237 238 count = INTVAL (operands[2]); 239 regno = REGNO (operands[0]); 240 mode = GET_MODE (operands[0]); 241 if (mode != QImode) 242 FAIL; 243 244 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count)); 245 246 gcc_assert (!can_create_pseudo_p ()); 247 248 base_reg = strip_offset (XEXP (operands[1], 0), &base_offs); 249 if (GET_CODE (base_reg) != REG) 250 FAIL; 251 252 for (i = 0; i < count; i++) 253 XVECEXP (operands[3], 0, i) 254 = gen_rtx_SET (gen_rtx_REG (mode, regno + i), 255 change_address (operands[1], mode, 256 plus_constant (Pmode, base_reg, 257 base_offs + i * GET_MODE_SIZE (mode)))); 258}) 259 260(define_insn "*pru_load_multiple" 261 [(match_parallel 0 "load_multiple_operation" 262 [(set (match_operand:QI 1 "register_operand" "=r") 263 (match_operand:QI 2 "memory_operand" "m"))])] 264 "reload_completed" 265{ 266 int nregs = XVECLEN (operands[0], 0); 267 operands[0] = GEN_INT (nregs); 268 return "lb%B2o\\t%b1, %2, %0"; 269} 270 [(set_attr "type" "ld")]) 271 272; 273; store multiple pattern(s). 274; 275 276(define_expand "store_multiple" 277 [(match_par_dup 3 [(set (match_operand 0 "") 278 (match_operand 1 "")) 279 (use (match_operand 2 ""))])] 280 "reload_completed" 281{ 282 machine_mode mode; 283 int regno; 284 int count; 285 rtx base_reg; 286 poly_int64 base_offs; 287 int i; 288 289 /* Support only storing a constant number of fixed-point registers to 290 memory. */ 291 if (GET_CODE (operands[2]) != CONST_INT 292 || GET_CODE (operands[0]) != MEM 293 || GET_CODE (operands[1]) != REG) 294 FAIL; 295 296 count = INTVAL (operands[2]); 297 regno = REGNO (operands[1]); 298 mode = GET_MODE (operands[1]); 299 if (mode != QImode) 300 FAIL; 301 302 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count)); 303 304 gcc_assert (!can_create_pseudo_p ()); 305 306 base_reg = strip_offset (XEXP (operands[0], 0), &base_offs); 307 if (GET_CODE (base_reg) != REG) 308 FAIL; 309 310 for (i = 0; i < count; i++) 311 XVECEXP (operands[3], 0, i) 312 = gen_rtx_SET (change_address (operands[0], mode, 313 plus_constant (Pmode, base_reg, 314 base_offs + i * GET_MODE_SIZE (mode))), 315 gen_rtx_REG (mode, regno + i)); 316}) 317 318(define_insn "*pru_store_multiple" 319 [(match_parallel 0 "store_multiple_operation" 320 [(set (match_operand:QI 1 "memory_operand" "=m") 321 (match_operand:QI 2 "register_operand" "r"))])] 322 "reload_completed" 323{ 324 int nregs = XVECLEN (operands[0], 0); 325 operands[0] = GEN_INT (nregs); 326 return "sb%B1o\\t%b2, %1, %0"; 327} 328 [(set_attr "type" "st")]) 329 330;; Zero extension patterns 331;; 332;; Unfortunately we cannot use lbbo to load AND zero-extent a value. 333;; The burst length parameter of the LBBO instruction designates not only 334;; the number of memory data bytes fetched, but also the number of register 335;; byte fields written. 336(define_expand "zero_extend<EQS0:mode><EQD:mode>2" 337 [(set (match_operand:EQD 0 "register_operand") 338 (zero_extend:EQD (match_operand:EQS0 1 "register_operand")))] 339 "" 340 "") 341 342(define_insn "*zero_extend<EQS0:mode><EQD:mode>2" 343 [(set (match_operand:EQD 0 "register_operand" "=r") 344 (zero_extend:EQD (match_operand:EQS0 1 "register_operand" "r")))] 345 "" 346 "mov\\t%0, %1" 347 [(set_attr "type" "alu")]) 348 349;; Sign extension patterns. We have to emulate them due to lack of 350;; signed operations in PRU's ALU. 351 352(define_insn "extend<EQS0:mode><EQD:mode>2" 353 [(set (match_operand:EQD 0 "register_operand" "=r") 354 (sign_extend:EQD (match_operand:EQS0 1 "register_operand" "r")))] 355 "" 356{ 357 return pru_output_sign_extend (operands); 358} 359 [(set_attr "type" "complex") 360 (set_attr "length" "12")]) 361 362;; Bit extraction 363;; We define it solely to allow combine to choose SImode 364;; for word mode when trying to match our cbranch_qbbx_* insn. 365;; 366;; Check how combine.c:make_extraction() uses 367;; get_best_reg_extraction_insn() to select the op size. 368(define_insn "extzv<mode>" 369 [(set (match_operand:QISI 0 "register_operand" "=r") 370 (zero_extract:QISI 371 (match_operand:QISI 1 "register_operand" "r") 372 (match_operand:QISI 2 "const_int_operand" "i") 373 (match_operand:QISI 3 "const_int_operand" "i")))] 374 "" 375 "lsl\\t%0, %1, (%S0 * 8 - %2 - %3)\;lsr\\t%0, %0, (%S0 * 8 - %2)" 376 [(set_attr "type" "complex") 377 (set_attr "length" "8")]) 378 379 380 381;; Arithmetic Operations 382 383(define_expand "add<mode>3" 384 [(set (match_operand:QISI 0 "register_operand") 385 (plus:QISI (match_operand:QISI 1 "register_operand") 386 (match_operand:QISI 2 "nonmemory_operand")))] 387 "" 388 "") 389 390(define_insn "adddi3" 391 [(set (match_operand:DI 0 "register_operand" "=&r,&r,&r") 392 (plus:DI (match_operand:DI 1 "register_operand" "%r,r,r") 393 (match_operand:DI 2 "reg_or_ubyte_operand" "r,I,M")))] 394 "" 395 "@ 396 add\\t%F0, %F1, %F2\;adc\\t%N0, %N1, %N2 397 add\\t%F0, %F1, %2\;adc\\t%N0, %N1, 0 398 sub\\t%F0, %F1, %n2\;suc\\t%N0, %N1, 0" 399 [(set_attr "type" "alu") 400 (set_attr "length" "8")]) 401 402(define_expand "sub<mode>3" 403 [(set (match_operand:QISI 0 "register_operand") 404 (minus:QISI (match_operand:QISI 1 "reg_or_ubyte_operand") 405 (match_operand:QISI 2 "reg_or_ubyte_operand")))] 406 "" 407 "") 408 409(define_insn "subdi3" 410 [(set (match_operand:DI 0 "register_operand" "=&r,&r") 411 (minus:DI (match_operand:DI 1 "reg_or_ubyte_operand" "r,I") 412 (match_operand:DI 2 "register_operand" "r,r")))] 413 "" 414 "@ 415 sub\\t%F0, %F1, %F2\;suc\\t%N0, %N1, %N2 416 rsb\\t%F0, %F2, %1\;rsc\\t%N0, %N2, 0" 417 [(set_attr "type" "alu") 418 (set_attr "length" "8")]) 419 420;; Negate and ones complement 421 422(define_expand "neg<mode>2" 423 [(set (match_operand:QISI 0 "register_operand") 424 (neg:QISI (match_operand:QISI 1 "register_operand")))] 425 "" 426 "") 427 428(define_expand "one_cmpl<mode>2" 429 [(set (match_operand:QISI 0 "register_operand") 430 (not:QISI (match_operand:QISI 1 "register_operand")))] 431 "" 432 "") 433 434;; Integer logical Operations 435;; 436;; TODO - add optimized cases that exploit the fact that we can get away 437;; with a single machine op for special constants, e.g. UBYTE << (0/8/16/24) 438 439(define_code_iterator LOGICAL [and ior xor umin umax]) 440(define_code_attr logical_asm [(and "and") (ior "or") (xor "xor") (umin "min") (umax "max")]) 441 442(define_code_iterator LOGICAL_BITOP [and ior xor]) 443(define_code_attr logical_bitop_asm [(and "and") (ior "or") (xor "xor")]) 444 445(define_expand "<code><mode>3" 446 [(set (match_operand:QISI 0 "register_operand") 447 (LOGICAL:QISI (match_operand:QISI 1 "register_operand") 448 (match_operand:QISI 2 "reg_or_ubyte_operand")))] 449 "" 450 "") 451 452 453;; Shift instructions 454 455(define_code_iterator SHIFT [ashift lshiftrt]) 456(define_code_attr shift_op [(ashift "ashl") (lshiftrt "lshr")]) 457(define_code_attr shift_asm [(ashift "lsl") (lshiftrt "lsr")]) 458 459(define_expand "<shift_op><mode>3" 460 [(set (match_operand:QISI 0 "register_operand") 461 (SHIFT:QISI (match_operand:QISI 1 "register_operand") 462 (match_operand:QISI 2 "shift_operand")))] 463 "" 464 "") 465 466; Expand to a loop of single-position arithmetic shifts, which 467; we can handle. Pseudo code: 468; tmpval = src; 469; QImode cntr = nshifts & 0xff; 470; while (cntr) 471; { 472; tmpval >>= 1; 473; cntr--; 474; } 475; dst = tmpval; 476; 477; Note that the number of shifts is truncated to QImode. This is a fair 478; assumption for a loop-based shifting implementation. 479(define_expand "ashr<mode>3" 480 [(set (match_operand:QISI 0 "register_operand") 481 (ashiftrt:QISI 482 (match_operand:QISI 1 "register_operand") 483 (match_operand:QI 2 "reg_or_const_1_operand")))] 484 "" 485{ 486 rtx dst = operands[0]; 487 rtx src = operands[1]; 488 rtx nshifts = operands[2]; 489 rtx_code_label *loop_label; 490 rtx_code_label *ashr_end_label; 491 rtx test, tmpval, cntr; 492 493 if (const_1_operand (nshifts, VOIDmode)) 494 { 495 emit_insn (gen_ashr<mode>3_single (dst, src, nshifts)); 496 DONE; 497 } 498 499 tmpval = gen_reg_rtx (<MODE>mode); 500 emit_move_insn (tmpval, src); 501 502 cntr = gen_reg_rtx (QImode); 503 emit_move_insn (cntr, nshifts); 504 505 loop_label = gen_label_rtx (); 506 ashr_end_label = gen_label_rtx (); 507 508 emit_label (loop_label); 509 test = gen_rtx_EQ (VOIDmode, cntr, const0_rtx); 510 emit_jump_insn (gen_cbranchqi4 (test, cntr, const0_rtx, ashr_end_label)); 511 512 emit_insn (gen_ashr<mode>3_single (tmpval, tmpval, const1_rtx)); 513 emit_insn (gen_addqi3 (cntr, cntr, GEN_INT (-1))); 514 515 emit_jump_insn (gen_jump (loop_label)); 516 JUMP_LABEL (get_last_insn ()) = loop_label; 517 LABEL_NUSES (loop_label)++; 518 emit_barrier (); 519 520 emit_label (ashr_end_label); 521 522 emit_move_insn (dst, tmpval); 523 524 DONE; 525}) 526 527(define_insn "ashr<mode>3_single" 528 [(set (match_operand:QISI 0 "register_operand" "=r") 529 (ashiftrt:QISI 530 (match_operand:QISI 1 "register_operand" "r") 531 (match_operand:QI 2 "const_1_operand" "P")))] 532 "" 533 "lsr\\t%0, %1, 1\;qbbc LSIGN%=, %0, (%S0 * 8) - 2\;set %0, %0, (%S0 * 8) - 1\;LSIGN%=:" 534 [(set_attr "type" "alu") 535 (set_attr "length" "12")]) 536 537 538;; Include ALU patterns with zero-extension of operands. That's where 539;; the real insns are defined. 540 541(include "alu-zext.md") 542 543;; DI logical ops could be automatically split into WORD-mode ops in 544;; expand_binop(). But then we'll miss an opportunity to use SI mode 545;; operations, since WORD mode for PRU is QI. 546(define_insn "<code>di3" 547 [(set (match_operand:DI 0 "register_operand" "=&r,&r") 548 (LOGICAL_BITOP:DI 549 (match_operand:DI 1 "register_operand" "%r,r") 550 (match_operand:DI 2 "reg_or_ubyte_operand" "r,I")))] 551 "" 552 "@ 553 <logical_bitop_asm>\\t%F0, %F1, %F2\;<logical_bitop_asm>\\t%N0, %N1, %N2 554 <logical_bitop_asm>\\t%F0, %F1, %2\;<logical_bitop_asm>\\t%N0, %N1, 0" 555 [(set_attr "type" "alu") 556 (set_attr "length" "8")]) 557 558 559(define_insn "one_cmpldi2" 560 [(set (match_operand:DI 0 "register_operand" "=r") 561 (not:DI (match_operand:DI 1 "register_operand" "r")))] 562 "" 563{ 564 /* careful with overlapping source and destination regs. */ 565 gcc_assert (GP_REG_P (REGNO (operands[0]))); 566 gcc_assert (GP_REG_P (REGNO (operands[1]))); 567 if (REGNO (operands[0]) == (REGNO (operands[1]) + 4)) 568 return "not\\t%N0, %N1\;not\\t%F0, %F1"; 569 else 570 return "not\\t%F0, %F1\;not\\t%N0, %N1"; 571} 572 [(set_attr "type" "alu") 573 (set_attr "length" "8")]) 574 575;; Multiply instruction. The nop is required to ensure that Rmd0 and Rms0 576;; registers are sampled and multiplication is executed on those values. 577;; Only after that one cycle can xin obtain the result. 578 579(define_insn "mulsi3" 580 [(set (match_operand:SI 0 "pru_muldst_operand" "=Rmd0") 581 (mult:SI (match_operand:SI 1 "pru_mulsrc0_operand" "%Rms0") 582 (match_operand:SI 2 "pru_mulsrc1_operand" "Rms1")))] 583 "" 584 "nop\;xin\\t0, %0, 4" 585 [(set_attr "type" "alu") 586 (set_attr "length" "8")]) 587 588;; Prologue, Epilogue and Return 589 590(define_expand "prologue" 591 [(const_int 1)] 592 "" 593{ 594 pru_expand_prologue (); 595 DONE; 596}) 597 598(define_expand "epilogue" 599 [(return)] 600 "" 601{ 602 pru_expand_epilogue (false); 603 DONE; 604}) 605 606(define_expand "sibcall_epilogue" 607 [(return)] 608 "" 609{ 610 pru_expand_epilogue (true); 611 DONE; 612}) 613 614(define_insn "return" 615 [(simple_return)] 616 "pru_can_use_return_insn ()" 617 "ret") 618 619(define_insn "simple_return" 620 [(simple_return)] 621 "" 622 "ret") 623 624;; Block any insns from being moved before this point, since the 625;; profiling call to mcount can use various registers that aren't 626;; saved or used to pass arguments. 627 628(define_insn "blockage" 629 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)] 630 "" 631 "" 632 [(set_attr "type" "unknown") 633 (set_attr "length" "0")]) 634 635;; Jumps and calls 636 637(define_insn "indirect_jump" 638 [(set (pc) (match_operand:SI 0 "register_operand" "r"))] 639 "" 640 "jmp\\t%0" 641 [(set_attr "type" "control")]) 642 643(define_insn "jump" 644 [(set (pc) 645 (label_ref (match_operand 0)))] 646 "" 647 "jmp\\t%%label(%l0)" 648 [(set_attr "type" "control")]) 649 650 651(define_expand "call" 652 [(parallel [(call (match_operand 0 "") 653 (match_operand 1 "")) 654 (clobber (reg:HI RA_REGNUM))])] 655 "" 656 "") 657 658(define_expand "call_value" 659 [(parallel [(set (match_operand 0 "") 660 (call (match_operand 1 "") 661 (match_operand 2 ""))) 662 (clobber (reg:HI RA_REGNUM))])] 663 "" 664 "") 665 666(define_insn "*call" 667 [(call (mem:SI (match_operand:SI 0 "call_operand" "i,r")) 668 (match_operand 1)) 669 (clobber (reg:HI RA_REGNUM))] 670 "" 671 "@ 672 call\\t%%label(%0) 673 call\\t%0" 674 [(set_attr "type" "control")]) 675 676(define_insn "*call_value" 677 [(set (match_operand 0) 678 (call (mem:SI (match_operand:SI 1 "call_operand" "i,r")) 679 (match_operand 2))) 680 (clobber (reg:HI RA_REGNUM))] 681 "" 682 "@ 683 call\\t%%label(%1) 684 call\\t%1" 685 [(set_attr "type" "control")]) 686 687(define_expand "sibcall" 688 [(parallel [(call (match_operand 0 "") 689 (match_operand 1 "")) 690 (return)])] 691 "" 692 "") 693 694(define_expand "sibcall_value" 695 [(parallel [(set (match_operand 0 "") 696 (call (match_operand 1 "") 697 (match_operand 2 ""))) 698 (return)])] 699 "" 700 "") 701 702(define_insn "*sibcall" 703 [(call (mem:SI (match_operand:SI 0 "call_operand" "i,Rsib")) 704 (match_operand 1)) 705 (return)] 706 "SIBLING_CALL_P (insn)" 707 "@ 708 jmp\\t%%label(%0) 709 jmp\\t%0" 710 [(set_attr "type" "control")]) 711 712(define_insn "*sibcall_value" 713 [(set (match_operand 0 "register_operand" "") 714 (call (mem:SI (match_operand:SI 1 "call_operand" "i,Rsib")) 715 (match_operand 2))) 716 (return)] 717 "SIBLING_CALL_P (insn)" 718 "@ 719 jmp\\t%%label(%1) 720 jmp\\t%1" 721 [(set_attr "type" "control")]) 722 723(define_insn "*tablejump" 724 [(set (pc) 725 (match_operand:SI 0 "register_operand" "r")) 726 (use (label_ref (match_operand 1)))] 727 "" 728 "jmp\\t%0" 729 [(set_attr "type" "control")]) 730 731;; Expand the cbranch pattern in order to assign different constraints for 732;; signed and unsigned comparisons. 733(define_expand "cbranch<mode>4" 734 [(set (pc) 735 (if_then_else 736 (match_operator 0 "ordered_comparison_operator" 737 [(match_operand:QISI 1 "register_operand") 738 (match_operand:QISI 2 "reg_or_const_int_operand")]) 739 (label_ref (match_operand 3 "")) 740 (pc)))] 741 "" 742{ 743 /* Ensure our patterns will be able to handle the particular const_int. */ 744 if (CONST_INT_P (operands[2])) 745 { 746 HOST_WIDE_INT ival = INTVAL (operands[2]); 747 748 /* For signed comparisons, we cannot play games with the const_int's 749 sign. PRU patterns do not support negative integer constants. */ 750 if (pru_signed_cmp_operator (operands[0], VOIDmode) && !UBYTE_INT (ival)) 751 { 752 if (can_create_pseudo_p ()) 753 operands[2] = force_reg (<MODE>mode, operands[2]); 754 else 755 FAIL; 756 } 757 758 /* For unsigned comparisons, be prepared to handle the QI quirk. */ 759 if (pru_cmp_operator (operands[0], VOIDmode) 760 && !const_ubyte_operand (operands[2], <MODE>mode)) 761 { 762 if (can_create_pseudo_p ()) 763 operands[2] = force_reg (<MODE>mode, operands[2]); 764 else 765 FAIL; 766 } 767 } 768}) 769 770(define_insn "cbranch<mode>4_unsigned" 771 [(set (pc) 772 (if_then_else 773 (match_operator 0 "pru_cmp_operator" 774 [(match_operand:QISI 1 "register_operand" "r") 775 (match_operand:QISI 2 "reg_or_ubyte_operand" "r<QISI:ubyte_constr>")]) 776 (label_ref (match_operand 3)) 777 (pc)))] 778 "" 779{ 780 const bool is_near = (get_attr_length (insn) == 4); 781 782 /* PRU comparisons reverse the operand order (OP2 cmp OP1), 783 so swap the condition. */ 784 if (is_near) 785 return "qb%P0\t%l3, %1, %u2"; 786 else 787 return "qb%Q0\t.+8, %1, %u2\;jmp\t%%label(%l3)"; 788} 789 [(set_attr "type" "control") 790 (set (attr "length") 791 (if_then_else 792 (and (ge (minus (match_dup 3) (pc)) (const_int -2040)) 793 (le (minus (match_dup 3) (pc)) (const_int 2036))) 794 (const_int 4) 795 (const_int 8)))]) 796 797;; Unlike ALU operations, the const_int's sign here is important. So we 798;; cannot use ubyte_constr. 799;; 800;; NOTE: The short branch check has no typo! We must be conservative and 801;; take into account the worst case of having a signed comparison with a 802;; "far taken branch" label, which amounts to 7 instructions. 803(define_insn "cbranch<mode>4_signed" 804 [(set (pc) 805 (if_then_else 806 (match_operator 0 "pru_signed_cmp_operator" 807 [(match_operand:QISI 1 "register_operand" "r,r,r") 808 (match_operand:QISI 2 "reg_or_ubyte_operand" "r,Z,I")]) 809 (label_ref (match_operand 3)) 810 (pc)))] 811 "" 812{ 813 const int length = (get_attr_length (insn)); 814 const bool is_near = (length == 20); 815 enum rtx_code code = GET_CODE (operands[0]); 816 817 if (which_alternative == 0) 818 return pru_output_signed_cbranch (operands, is_near); 819 else if (which_alternative == 1 && (code == LT || code == GE)) 820 return pru_output_signed_cbranch_zeroop2 (operands, is_near); 821 else 822 return pru_output_signed_cbranch_ubyteop2 (operands, is_near); 823} 824 [(set_attr "type" "control") 825 (set (attr "length") 826 (if_then_else 827 (and (ge (minus (match_dup 3) (pc)) (const_int -2020)) 828 (le (minus (match_dup 3) (pc)) (const_int 2016))) 829 (const_int 20) 830 (const_int 28)))]) 831 832(define_expand "cbranch<mode>4" 833 [(set (pc) 834 (if_then_else (match_operator 0 "pru_fp_comparison_operator" 835 [(match_operand:SFDF 1 "register_operand") 836 (match_operand:SFDF 2 "register_operand")]) 837 (label_ref (match_operand 3 "")) 838 (pc)))] 839 "" 840{ 841 rtx t = pru_expand_fp_compare (operands[0], VOIDmode); 842 operands[0] = t; 843 operands[1] = XEXP (t, 0); 844 operands[2] = XEXP (t, 1); 845}) 846 847; 848; Bit test branch 849 850(define_code_iterator BIT_TEST [eq ne]) 851(define_code_attr qbbx_op [(eq "qbbc") (ne "qbbs")]) 852(define_code_attr qbbx_negop [(eq "qbbs") (ne "qbbc")]) 853 854(define_insn "cbranch_qbbx_<BIT_TEST:code><EQS0:mode><EQS1:mode><EQD:mode>4" 855 [(set (pc) 856 (if_then_else 857 (BIT_TEST (zero_extract:EQD 858 (match_operand:EQS0 0 "register_operand" "r") 859 (const_int 1) 860 (match_operand:EQS1 1 "reg_or_ubyte_operand" "r<EQS1:ubyte_constr>")) 861 (const_int 0)) 862 (label_ref (match_operand 2)) 863 (pc)))] 864 "" 865{ 866 const int length = (get_attr_length (insn)); 867 const bool is_near = (length == 4); 868 if (is_near) 869 return "<BIT_TEST:qbbx_op>\\t%l2, %0, %u1"; 870 else 871 return "<BIT_TEST:qbbx_negop>\\t.+8, %0, %u1\;jmp\\t%%label(%l2)"; 872} 873 [(set_attr "type" "control") 874 (set (attr "length") 875 (if_then_else 876 (and (ge (minus (match_dup 2) (pc)) (const_int -2048)) 877 (le (minus (match_dup 2) (pc)) (const_int 2044))) 878 (const_int 4) 879 (const_int 8)))]) 880 881;; :::::::::::::::::::: 882;; :: 883;; :: Low Overhead Looping - idea "borrowed" from MEP 884;; :: 885;; :::::::::::::::::::: 886 887;; This insn is volatile because we'd like it to stay in its original 888;; position, just before the loop header. If it stays there, we might 889;; be able to convert it into a "loop" insn. 890(define_insn "doloop_begin_internal<mode>" 891 [(set (match_operand:HISI 0 "register_operand" "=r") 892 (unspec_volatile:HISI 893 [(match_operand:HISI 1 "reg_or_ubyte_operand" "rI") 894 (match_operand 2 "const_int_operand" "")] UNSPECV_LOOP_BEGIN))] 895 "" 896{ 897 gcc_unreachable (); 898}) 899 900(define_expand "doloop_begin" 901 [(use (match_operand 0 "register_operand")) 902 (use (match_operand 1 ""))] 903 "TARGET_OPT_LOOP" 904{ 905 pru_emit_doloop (operands, 0); 906 DONE; 907}) 908 909; Note: "JUMP_INSNs and CALL_INSNs are not allowed to have any output 910; reloads;". Hence this insn must be prepared for a counter that is 911; not a register. 912(define_insn "doloop_end_internal<mode>" 913 [(set (pc) 914 (if_then_else (ne (match_operand:HISI 0 "nonimmediate_operand" "+r,*m") 915 (const_int 1)) 916 (label_ref (match_operand 1)) 917 (pc))) 918 (set (match_dup 0) 919 (plus:HISI (match_dup 0) 920 (const_int -1))) 921 (unspec [(match_operand 2 "const_int_operand" "")] UNSPECV_LOOP_END) 922 (clobber (match_scratch:HISI 3 "=X,&r"))] 923 "" 924{ 925 gcc_unreachable (); 926} 927 ;; Worst case length: 928 ;; 929 ;; lbbo op3_reg, op3_ptr 4' 930 ;; sub <op3_reg>, 1 4 931 ;; qbeq .+8, <op3_reg>, 0 4 932 ;; jmp <op1> 4 933 ;; sbbo op3_reg, op3_ptr 4 934 [(set (attr "length") 935 (if_then_else 936 (and (ge (minus (pc) (match_dup 1)) (const_int 0)) 937 (le (minus (pc) (match_dup 1)) (const_int 1020))) 938 (cond [(eq_attr "alternative" "0") (const_int 4)] 939 (const_int 12)) 940 (cond [(eq_attr "alternative" "0") (const_int 12)] 941 (const_int 20))))]) 942 943(define_expand "doloop_end" 944 [(use (match_operand 0 "nonimmediate_operand")) 945 (use (label_ref (match_operand 1 "")))] 946 "TARGET_OPT_LOOP" 947{ 948 if (GET_CODE (operands[0]) == REG && GET_MODE (operands[0]) == QImode) 949 FAIL; 950 pru_emit_doloop (operands, 1); 951 DONE; 952}) 953 954(define_insn "pruloop<mode>" 955 [(set (reg:HISI LOOPCNTR_REGNUM) 956 (unspec:HISI [(match_operand:HISI 0 "reg_or_ubyte_operand" "rI") 957 (label_ref (match_operand 1))] 958 UNSPECV_LOOP_BEGIN))] 959 "" 960 "loop\\t%l1, %0") 961 962(define_insn "pruloop_end" 963 [(unspec [(const_int 0)] UNSPECV_LOOP_END)] 964 "" 965 "# loop end" 966 [(set_attr "length" "0")]) 967 968 969;; Misc patterns 970 971(define_insn "delay_cycles_start" 972 [(unspec_volatile [(match_operand 0 "immediate_operand" "i")] 973 UNSPECV_DELAY_CYCLES_START)] 974 "" 975 "/* Begin %0 cycle delay. */" 976 [(set_attr "length" "0")]) 977 978(define_insn "delay_cycles_end" 979 [(unspec_volatile [(match_operand 0 "immediate_operand" "i")] 980 UNSPECV_DELAY_CYCLES_END)] 981 "" 982 "/* End %0 cycle delay. */" 983 [(set_attr "length" "0")]) 984 985 986(define_insn "delay_cycles_2x_plus1_hi" 987 [(unspec_volatile [(match_operand:SI 0 "const_uhword_operand" "J")] 988 UNSPECV_DELAY_CYCLES_2X_HI) 989 (clobber (match_scratch:SI 1 "=&r"))] 990 "" 991 "ldi\\t%1, %0\;sub\\t%1, %1, 1\;qbne\\t.-4, %1, 0" 992 [(set_attr "length" "12")]) 993 994 995; Do not use LDI32 here because we do not want 996; to accidentally loose one instruction cycle. 997(define_insn "delay_cycles_2x_plus2_si" 998 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")] 999 UNSPECV_DELAY_CYCLES_2X_SI) 1000 (clobber (match_scratch:SI 1 "=&r"))] 1001 "" 1002 "ldi\\t%1.w0, %L0\;ldi\\t%1.w2, %H0\;sub\\t%1, %1, 1\;qbne\\t.-4, %1, 0" 1003 [(set_attr "length" "16")]) 1004 1005(define_insn "delay_cycles_1" 1006 [(unspec_volatile [(const_int 0) ] UNSPECV_DELAY_CYCLES_1)] 1007 "" 1008 "nop\\t# delay_cycles_1" 1009) 1010 1011 1012(define_insn "nop" 1013 [(const_int 0)] 1014 "" 1015 "nop" 1016 [(set_attr "type" "alu")]) 1017 1018(define_insn "nop_loop_guard" 1019 [(const_int 0)] 1020 "" 1021 "nop\\t# Loop end guard" 1022 [(set_attr "type" "alu")]) 1023