Skip analyzer strndup test on hppa*-*-hpux*
[official-gcc.git] / gcc / config / bpf / bpf.md
blob522351a65966a39db43b6e2198f0d25a45a478c5
1 ;; Machine description for eBPF.
2 ;; Copyright (C) 2019-2023 Free Software Foundation, Inc.
4 ;; This file is part of GCC.
6 ;; GCC is free software; you can redistribute it and/or modify
7 ;; it under the terms of the GNU General Public License as published by
8 ;; the Free Software Foundation; either version 3, or (at your option)
9 ;; any later version.
11 ;; GCC is distributed in the hope that it will be useful,
12 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 ;; GNU General Public License for more details.
16 ;; You should have received a copy of the GNU General Public License
17 ;; along with GCC; see the file COPYING3.  If not see
18 ;; <http://www.gnu.org/licenses/>.
20 (include "predicates.md")
21 (include "constraints.md")
23 ;;;; Instruction Scheduler FSM
25 ;; This is just to get INSN_SCHEDULING defined, so that combine does
26 ;; not make paradoxical subregs of memory.  These subregs seems to
27 ;; confuse LRA that ends generating wrong instructions.
29 (define_automaton "frob")
30 (define_cpu_unit "frob_unit" "frob")
31 (define_insn_reservation "frobnicator" 814
32   (const_int 0) "frob_unit")
34 ;;;; Unspecs
36 (define_c_enum "unspec" [
37   UNSPEC_LDINDABS
38   UNSPEC_AADD
39   UNSPEC_AAND
40   UNSPEC_AOR
41   UNSPEC_AXOR
42   UNSPEC_AFADD
43   UNSPEC_AFAND
44   UNSPEC_AFOR
45   UNSPEC_AFXOR
46   UNSPEC_AXCHG
47   UNSPEC_ACMP
48   UNSPEC_CORE_RELOC
51 ;;;; Constants
53 (define_constants
54   [(R0_REGNUM           0)
55    (R1_REGNUM           1)
56    (R2_REGNUM           2)
57    (R3_REGNUM           3)
58    (R4_REGNUM           4)
59    (R5_REGNUM           5)
60    (R6_REGNUM           6)
61    (R7_REGNUM           7)
62    (R8_REGNUM           8)
63    (R9_REGNUM           9)
64    (R10_REGNUM          10)
65    (R11_REGNUM          11)
68 ;;;; Attributes
70 ;; Instruction classes.
71 ;; alu          64-bit arithmetic.
72 ;; alu32        32-bit arithmetic.
73 ;; end          endianness conversion or byte swap instructions.
74 ;; ld           load instructions.
75 ;; lddx         load 64-bit immediate instruction.
76 ;; ldx          generic load instructions.
77 ;; st           generic store instructions for immediates.
78 ;; stx          generic store instructions.
79 ;; jmp          jump instructions.
80 ;; multi        multiword sequence (or user asm statements).
82 (define_attr "type"
83   "unknown,alu,alu32,end,ld,lddw,ldx,st,stx,jmp,multi,atomic"
84   (const_string "unknown"))
86 ;; Length of instruction in bytes.
87 (define_attr "length" ""
88   (cond [
89          (eq_attr "type" "lddw") (const_int 16)
90          ] (const_int 8)))
92 ;; Describe a user's asm statement.
93 (define_asm_attributes
94   [(set_attr "type" "multi")])
96 ;;;; Mode attributes and iterators
98 (define_mode_attr mop [(QI "b") (HI "h") (SI "w") (DI "dw")
99                        (SF "w") (DF "dw")])
100 (define_mode_attr smop [(QI "u8") (HI "u16") (SI "u32") (DI "u64")
101                        (SF "u32") (DF "u64")])
102 (define_mode_attr mtype [(SI "alu32") (DI "alu")])
103 (define_mode_attr msuffix [(SI "32") (DI "")])
105 ;;;; NOPs
107 ;; The Linux kernel verifier performs some optimizations that rely on
108 ;; nop instructions to be encoded as `ja 0', i.e. a jump to offset 0,
109 ;; which actually means to jump to the next instruction, since in BPF
110 ;; offsets are expressed in 64-bit words _minus one_.
112 (define_insn "nop"
113   [(const_int 0)]
114   ""
115   "{ja\t0|goto 0}"
116   [(set_attr "type" "alu")])
118 ;;;; Stack usage
120 (define_expand "allocate_stack"
121   [(match_operand:DI 0 "general_operand" "")
122    (match_operand:DI 1 "general_operand" "")]
123   ""
124   "
126   error (\"BPF does not support dynamic stack allocation\");
127   emit_insn (gen_nop ());
128   DONE;
131 ;;;; Arithmetic/Logical
133 ;; The arithmetic and logic operations below are defined for SI and DI
134 ;; modes.  The mode iterator AM is used in order to expand to two
135 ;; insns, with the proper modes.
137 ;; 32-bit arithmetic (for SI modes) is implemented using the alu32
138 ;; instructions, if available.
140 (define_mode_iterator AM [(SI "bpf_has_alu32") DI])
142 ;;; Addition
143 (define_insn "add<AM:mode>3"
144   [(set (match_operand:AM          0 "register_operand"   "=r,r")
145         (plus:AM (match_operand:AM 1 "register_operand"   " 0,0")
146                  (match_operand:AM 2 "reg_or_imm_operand" " r,I")))]
147   "1"
148   "{add<msuffix>\t%0,%2|%w0 += %w2}"
149   [(set_attr "type" "<mtype>")])
151 ;;; Subtraction
153 ;; Note that subtractions of constants become additions, so there is
154 ;; no need to handle immediate operands in the subMODE3 insns.
156 (define_insn "sub<AM:mode>3"
157   [(set (match_operand:AM          0 "register_operand" "=r")
158         (minus:AM (match_operand:AM 1 "register_operand" " 0")
159                   (match_operand:AM 2 "register_operand" " r")))]
160   ""
161   "{sub<msuffix>\t%0,%2|%w0 -= %w2}"
162   [(set_attr "type" "<mtype>")])
164 ;;; Negation
165 (define_insn "neg<AM:mode>2"
166   [(set (match_operand:AM         0 "register_operand" "=r")
167         (neg:AM (match_operand:AM 1 "register_operand" " 0")))]
168   ""
169   "{neg<msuffix>\t%0|%w0 = -%w1}"
170   [(set_attr "type" "<mtype>")])
172 ;;; Multiplication
173 (define_insn "mul<AM:mode>3"
174   [(set (match_operand:AM          0 "register_operand"   "=r,r")
175         (mult:AM (match_operand:AM 1 "register_operand"   " 0,0")
176                  (match_operand:AM 2 "reg_or_imm_operand" " r,I")))]
177   ""
178   "{mul<msuffix>\t%0,%2|%w0 *= %w2}"
179   [(set_attr "type" "<mtype>")])
181 (define_insn "*mulsidi3_zeroextend"
182   [(set (match_operand:DI          0 "register_operand" "=r,r")
183         (zero_extend:DI
184          (mult:SI (match_operand:SI 1 "register_operand" "0,0")
185                   (match_operand:SI 2 "reg_or_imm_operand" "r,I"))))]
186   ""
187   "{mul32\t%0,%2|%W0 *= %W2}"
188   [(set_attr "type" "alu32")])
190 ;;; Division
192 ;; Note that eBPF <= V3 doesn't provide instructions for signed
193 ;; integer division.
195 (define_insn "udiv<AM:mode>3"
196   [(set (match_operand:AM 0 "register_operand" "=r,r")
197         (udiv:AM (match_operand:AM 1 "register_operand" " 0,0")
198                  (match_operand:AM 2 "reg_or_imm_operand" "r,I")))]
199   ""
200   "{div<msuffix>\t%0,%2|%w0 /= %w2}"
201   [(set_attr "type" "<mtype>")])
203 ;; However, BPF V4 does provide a signed division operator, sdiv.
205 (define_insn "div<AM:mode>3"
206   [(set (match_operand:AM 0 "register_operand" "=r,r")
207         (div:AM (match_operand:AM 1 "register_operand" " 0,0")
208                 (match_operand:AM 2 "reg_or_imm_operand" "r,I")))]
209   "bpf_has_sdiv"
210   "{sdiv<msuffix>\t%0,%2|%w0 s/= %w2}"
211   [(set_attr "type" "<mtype>")])
213 ;;; Modulus
215 ;; Note that eBPF <= V3 doesn't provide instructions for signed
216 ;; integer remainder.
218 (define_insn "umod<AM:mode>3"
219   [(set (match_operand:AM 0 "register_operand" "=r,r")
220         (umod:AM (match_operand:AM 1 "register_operand" " 0,0")
221                  (match_operand:AM 2 "reg_or_imm_operand" "r,I")))]
222   ""
223   "{mod<msuffix>\t%0,%2|%w0 %%= %w2}"
224   [(set_attr "type" "<mtype>")])
226 ;; However, BPF V4 does provide a signed modulus operator, smod.
228 (define_insn "mod<AM:mode>3"
229   [(set (match_operand:AM 0 "register_operand" "=r,r")
230         (mod:AM (match_operand:AM 1 "register_operand" " 0,0")
231                 (match_operand:AM 2 "reg_or_imm_operand" "r,I")))]
232   "bpf_has_sdiv"
233   "{smod<msuffix>\t%0,%2|%w0 s%%= %w2}"
234   [(set_attr "type" "<mtype>")])
236 ;;; Logical AND
237 (define_insn "and<AM:mode>3"
238   [(set (match_operand:AM 0 "register_operand" "=r,r")
239         (and:AM (match_operand:AM 1 "register_operand" " 0,0")
240                 (match_operand:AM 2 "reg_or_imm_operand" "r,I")))]
241   ""
242   "{and<msuffix>\t%0,%2|%w0 &= %w2}"
243   [(set_attr "type" "<mtype>")])
245 ;;; Logical inclusive-OR
246 (define_insn "ior<AM:mode>3"
247   [(set (match_operand:AM 0 "register_operand" "=r,r")
248         (ior:AM (match_operand:AM 1 "register_operand" " 0,0")
249                 (match_operand:AM 2 "reg_or_imm_operand" "r,I")))]
250   ""
251   "{or<msuffix>\t%0,%2|%w0 %|= %w2}"
252   [(set_attr "type" "<mtype>")])
254 ;;; Logical exclusive-OR
255 (define_insn "xor<AM:mode>3"
256   [(set (match_operand:AM 0 "register_operand" "=r,r")
257         (xor:AM (match_operand:AM 1 "register_operand" " 0,0")
258                 (match_operand:AM 2 "reg_or_imm_operand" "r,I")))]
259   ""
260   "{xor<msuffix>\t%0,%2|%w0 ^= %w2}"
261   [(set_attr "type" "<mtype>")])
263 ;;;; Conversions
265 ;;; Zero-extensions
267 ;; For register operands smaller than 32-bit zero-extending is
268 ;; achieved ANDing the value in the source register to a suitable
269 ;; mask.
271 ;; For register operands bigger or equal than 32-bit, we generate a
272 ;; mov32 instruction to zero the high 32-bits of the destination
273 ;; register.
275 ;; For memory operands, of any width, zero-extending is achieved using
276 ;; the ldx{bhwdw} instructions to load the values in registers.
278 (define_insn "zero_extendhidi2"
279   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
280         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "0,r,q")))]
281   ""
282   "@
283    {and\t%0,0xffff|%0 &= 0xffff}
284    {mov\t%0,%1\;and\t%0,0xffff|%0 = %1;%0 &= 0xffff}
285    {ldxh\t%0,%1|%0 = *(u16 *) (%1)}"
286   [(set_attr "type" "alu,alu,ldx")])
288 (define_insn "zero_extendqidi2"
289   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
290         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "0,r,q")))]
291   ""
292   "@
293    {and\t%0,0xff|%0 &= 0xff}
294    {mov\t%0,%1\;and\t%0,0xff|%0 = %1;%0 &= 0xff}
295    {ldxh\t%0,%1|%0 = *(u8 *) (%1)}"
296   [(set_attr "type" "alu,alu,ldx")])
298 (define_insn "zero_extendsidi2"
299   [(set (match_operand:DI 0 "register_operand" "=r,r")
300         (zero_extend:DI
301           (match_operand:SI 1 "nonimmediate_operand" "r,q")))]
302   ""
303   "@
304    * return bpf_has_alu32 ? \"{mov32\t%0,%1|%0 = %1}\" : \"{mov\t%0,%1\;and\t%0,0xffffffff|%0 = %1;%0 &= 0xffffffff}\";
305    {ldxw\t%0,%1|%0 = *(u32 *) (%1)}"
306   [(set_attr "type" "alu,ldx")])
308 ;;; Sign-extension
310 ;; Sign-extending a 32-bit value into a 64-bit value is achieved using
311 ;; shifting, with instructions generated by the expand below.
313 (define_expand "extendsidi2"
314   [(set (match_operand:DI 0 "register_operand")
315         (sign_extend:DI (match_operand:SI 1 "register_operand")))]
316   ""
318   operands[1] = gen_lowpart (DImode, operands[1]);
319   emit_insn (gen_ashldi3 (operands[0], operands[1], GEN_INT (32)));
320   emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (32)));
321   DONE;
324 ;; ISA V4 introduces sign-extending move and load operations.
326 (define_insn "*extendsidi2"
327   [(set (match_operand:DI 0 "register_operand" "=r,r")
328         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,q")))]
329   "bpf_has_smov"
330   "@
331    {movs\t%0,%1,32|%0 = (s32) %1}
332    {ldxsw\t%0,%1|%0 = *(s32 *) (%1)}"
333   [(set_attr "type" "alu,ldx")])
335 (define_insn "extendhidi2"
336   [(set (match_operand:DI 0 "register_operand" "=r,r")
337         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,q")))]
338   "bpf_has_smov"
339   "@
340    {movs\t%0,%1,16|%0 = (s16) %1}
341    {ldxsh\t%0,%1|%0 = *(s16 *) (%1)}"
342   [(set_attr "type" "alu,ldx")])
344 (define_insn "extendqidi2"
345   [(set (match_operand:DI 0 "register_operand" "=r,r")
346         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,q")))]
347   "bpf_has_smov"
348   "@
349    {movs\t%0,%1,8|%0 = (s8) %1}
350    {ldxsb\t%0,%1|%0 = *(s8 *) (%1)}"
351   [(set_attr "type" "alu,ldx")])
353 (define_insn "extendhisi2"
354   [(set (match_operand:SI 0 "register_operand" "=r")
355         (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
356   "bpf_has_smov"
357   "{movs32\t%0,%1,16|%w0 = (s16) %w1}"
358   [(set_attr "type" "alu")])
360 (define_insn "extendqisi2"
361   [(set (match_operand:SI 0 "register_operand" "=r")
362         (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
363   "bpf_has_smov"
364   "{movs32\t%0,%1,8|%w0 = (s8) %w1}"
365   [(set_attr "type" "alu")])
367 ;;;; Data movement
369 (define_mode_iterator MM [QI HI SI DI SF DF])
371 (define_expand "mov<MM:mode>"
372   [(set (match_operand:MM 0 "general_operand")
373         (match_operand:MM 1 "general_operand"))]
374         ""
375         "
377   if (!register_operand(operands[0], <MM:MODE>mode)
378       && !register_operand(operands[1], <MM:MODE>mode))
379     operands[1] = force_reg (<MM:MODE>mode, operands[1]);
382 (define_insn "*mov<MM:mode>"
383   [(set (match_operand:MM 0 "nonimmediate_operand" "=r, r,r,q,q")
384         (match_operand:MM 1 "mov_src_operand"      " q,rI,B,r,I"))]
385   ""
386   "@
387    {ldx<mop>\t%0,%1|%0 = *(<smop> *) (%1)}
388    {mov\t%0,%1|%0 = %1}
389    {lddw\t%0,%1|%0 = %1 ll}
390    {stx<mop>\t%0,%1|*(<smop> *) (%0) = %1}
391    {st<mop>\t%0,%1|*(<smop> *) (%0) = %1}"
392 [(set_attr "type" "ldx,alu,alu,stx,st")])
394 (define_insn "*mov_reloc_core<MM:mode>"
395   [(set (match_operand:MM 0 "nonimmediate_operand" "=r,q,r")
396         (unspec:MM [
397           (match_operand:MM 1 "immediate_operand"  " I,I,B")
398           (match_operand:SI 2 "immediate_operand"  " I,I,I")
399          ] UNSPEC_CORE_RELOC)
400    )]
401   ""
402   "@
403    *return bpf_add_core_reloc (operands, \"{mov\t%0,%1|%0 = %1}\");
404    *return bpf_add_core_reloc (operands, \"{st<mop>\t%0,%1|*(<smop> *) (%0) = %1}\");
405    *return bpf_add_core_reloc (operands, \"{lddw\t%0,%1|%0 = %1 ll}\");"
406   [(set_attr "type" "alu,st,alu")])
408 ;;;; Shifts
410 (define_mode_iterator SIM [(SI "bpf_has_alu32") DI])
412 (define_insn "ashr<SIM:mode>3"
413   [(set (match_operand:SIM 0 "register_operand"                 "=r,r")
414         (ashiftrt:SIM (match_operand:SIM 1 "register_operand"   " 0,0")
415                       (match_operand:SIM 2 "reg_or_imm_operand" " r,I")))]
416   ""
417   "{arsh<msuffix>\t%0,%2|%w0 s>>= %w2}"
418   [(set_attr "type" "<mtype>")])
420 (define_insn "ashl<SIM:mode>3"
421   [(set (match_operand:SIM 0 "register_operand"               "=r,r")
422         (ashift:SIM (match_operand:SIM 1 "register_operand"   " 0,0")
423                     (match_operand:SIM 2 "reg_or_imm_operand" " r,I")))]
424   ""
425   "{lsh<msuffix>\t%0,%2|%w0 <<= %w2}"
426   [(set_attr "type" "<mtype>")])
428 (define_insn "lshr<SIM:mode>3"
429   [(set (match_operand:SIM 0 "register_operand"                 "=r,r")
430         (lshiftrt:SIM (match_operand:SIM 1 "register_operand"   " 0,0")
431                       (match_operand:SIM 2 "reg_or_imm_operand" " r,I")))]
432   ""
433   "{rsh<msuffix>\t%0,%2|%w0 >>= %w2}"
434   [(set_attr "type" "<mtype>")])
436 ;;;; Byte swapping
438 (define_mode_iterator BSM [HI SI DI])
439 (define_mode_attr endmode [(HI "16") (SI "32") (DI "64")])
441 (define_insn "bswap<BSM:mode>2"
442   [(set (match_operand:BSM 0 "register_operand"            "=r")
443         (bswap:BSM (match_operand:BSM 1 "register_operand" " 0")))]
444   ""
446   if (bpf_has_bswap)
447     return "{bswap\t%0, <endmode>|%0 = bswap<endmode> %1}";
448   else
449     {
450       if (TARGET_BIG_ENDIAN)
451         return "{endle\t%0, <endmode>|%0 = le<endmode> %1}";
452       else
453         return "{endbe\t%0, <endmode>|%0 = be<endmode> %1}";
454     }
456   [(set_attr "type" "end")])
458 ;;;; Conditional branches
460 ;; The eBPF jump instructions use 64-bit arithmetic when evaluating
461 ;; the jump conditions.  Therefore we use DI modes below.
463 (define_mode_iterator JM [(SI "bpf_has_jmp32") DI])
465 (define_expand "cbranch<JM:mode>4"
466   [(set (pc)
467         (if_then_else (match_operator 0 "comparison_operator"
468                         [(match_operand:JM 1 "register_operand")
469                          (match_operand:JM 2 "reg_or_imm_operand")])
470                       (label_ref (match_operand 3 "" ""))
471                       (pc)))]
472   ""
474   if (!ordered_comparison_operator (operands[0], VOIDmode))
475     FAIL;
477   bpf_expand_cbranch (<JM:MODE>mode, operands);
480 (define_insn "*branch_on_<JM:mode>"
481   [(set (pc)
482         (if_then_else (match_operator 3 "ordered_comparison_operator"
483                          [(match_operand:JM 0 "register_operand" "r")
484                           (match_operand:JM 1 "reg_or_imm_operand" "rI")])
485                       (label_ref (match_operand 2 "" ""))
486                       (pc)))]
487   ""
489   int code = GET_CODE (operands[3]);
491   switch (code)
492   {
493   case EQ: return  "{jeq<msuffix>\t%0,%1,%2|if %w0 == %w1 goto %2}"; break;
494   case NE: return  "{jne<msuffix>\t%0,%1,%2|if %w0 != %w1 goto %2}"; break;
495   case LT: return  "{jslt<msuffix>\t%0,%1,%2|if %w0 s< %w1 goto %2}"; break;
496   case LE: return  "{jsle<msuffix>\t%0,%1,%2|if %w0 s<= %w1 goto %2}"; break;
497   case GT: return  "{jsgt<msuffix>\t%0,%1,%2|if %w0 s> %w1 goto %2}"; break;
498   case GE: return  "{jsge<msuffix>\t%0,%1,%2|if %w0 s>= %w1 goto %2}"; break;
499   case LTU: return "{jlt<msuffix>\t%0,%1,%2|if %w0 < %w1 goto %2}"; break;
500   case LEU: return "{jle<msuffix>\t%0,%1,%2|if %w0 <= %w1 goto %2}"; break;
501   case GTU: return "{jgt<msuffix>\t%0,%1,%2|if %w0 > %w1 goto %2}"; break;
502   case GEU: return "{jge<msuffix>\t%0,%1,%2|if %w0 >= %w1 goto %2}"; break;
503   default:
504     gcc_unreachable ();
505     return "";
506   }
508   [(set_attr "type" "jmp")])
510 ;;;; Unconditional branches
512 (define_insn "jump"
513   [(set (pc)
514         (label_ref (match_operand 0 "" "")))]
515   ""
516   "{ja\t%0|goto %0}"
517 [(set_attr "type" "jmp")])
519 ;;;; Function prologue/epilogue
521 (define_insn "exit"
522   [(simple_return)]
523   ""
524   "exit"
525   [(set_attr "type" "jmp")])
527 (define_expand "prologue"
528   [(const_int 0)]
529   ""
531   bpf_expand_prologue ();
532   DONE;
535 (define_expand "epilogue"
536   [(const_int 0)]
537   ""
539   bpf_expand_epilogue ();
540   DONE;
543 ;;;; Function calls
545 (define_expand "call"
546   [(parallel [(call (match_operand 0 "")
547                     (match_operand 1 ""))
548               (use (match_operand 2 ""))        ;; next_arg_reg
549               (use (match_operand 3 ""))])]     ;; struct_value_size_rtx
550   ""
552   rtx target = XEXP (operands[0], 0);
553   emit_call_insn (gen_call_internal (target, operands[1]));
554   DONE;
557 (define_insn "call_internal"
558   [(call (mem:DI (match_operand:DI 0 "call_operand" "Sr"))
559          (match_operand:SI 1 "general_operand" ""))]
560   ;; operands[2] is next_arg_register
561   ;; operands[3] is struct_value_size_rtx.
562   ""
563   { return bpf_output_call (operands[0]); }
564   [(set_attr "type" "jmp")])
566 (define_expand "call_value"
567   [(parallel [(set (match_operand 0 "")
568                    (call (match_operand 1 "")
569                          (match_operand 2 "")))
570               (use (match_operand 3 ""))])]             ;; next_arg_reg
571   ""
573   rtx target = XEXP (operands[1], 0);
574   emit_call_insn (gen_call_value_internal (operands[0], target,
575                                            operands[2]));
576   DONE;
579 (define_insn "call_value_internal"
580   [(set (match_operand 0 "register_operand" "")
581         (call (mem:DI (match_operand:DI 1 "call_operand" "Sr"))
582               (match_operand:SI 2 "general_operand" "")))]
583   ;; operands[3] is next_arg_register
584   ;; operands[4] is struct_value_size_rtx.
585   ""
586   { return bpf_output_call (operands[1]); }
587   [(set_attr "type" "jmp")])
589 (define_insn "sibcall"
590   [(call (label_ref (match_operand 0 "" ""))
591          (match_operand:SI 1 "general_operand" ""))]
592   ;; operands[2] is next_arg_register
593   ;; operands[3] is struct_value_size_rtx.
594   ""
595   "{ja\t%0|goto %0}"
596   [(set_attr "type" "jmp")])
598 ;;;; Non-generic load instructions
600 (define_mode_iterator LDM [QI HI SI DI])
601 (define_mode_attr ldop [(QI "b") (HI "h") (SI "w") (DI "dw")])
602 (define_mode_attr pldop [(QI "u8") (HI "u16") (SI "u32") (DI "u64")])
604 (define_insn "ldind<ldop>"
605   [(set (reg:LDM R0_REGNUM)
606         (unspec:LDM [(match_operand:DI 0 "register_operand" "r")
607                     (match_operand:SI 1 "imm32_operand" "I")]
608                     UNSPEC_LDINDABS))
609    (clobber (reg:DI R1_REGNUM))
610    (clobber (reg:DI R2_REGNUM))
611    (clobber (reg:DI R3_REGNUM))
612    (clobber (reg:DI R4_REGNUM))]
613   ""
614   "{ldind<ldop>\t%0,%1|r0 = *(<pldop> *) skb[%0 + %1]}"
615   [(set_attr "type" "ld")])
617 (define_insn "ldabs<ldop>"
618   [(set (reg:LDM R0_REGNUM)
619         (unspec:LDM [(match_operand:SI 0 "imm32_operand" "I")
620                     (match_operand:SI 1 "imm32_operand" "I")]
621                     UNSPEC_LDINDABS))
622    (clobber (reg:DI R1_REGNUM))
623    (clobber (reg:DI R2_REGNUM))
624    (clobber (reg:DI R3_REGNUM))
625    (clobber (reg:DI R4_REGNUM))]
626   ""
627   "{ldabs<ldop>\t%0|r0 = *(<pldop> *) skb[%0]}"
628   [(set_attr "type" "ld")])
630 (include "atomic.md")