annotate gcc/config/bpf/bpf.md @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
145
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1 ;; Machine description for eBPF.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2 ;; Copyright (C) 2019-2020 Free Software Foundation, Inc.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
4 ;; This file is part of GCC.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
5
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
6 ;; GCC is free software; you can redistribute it and/or modify
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
7 ;; it under the terms of the GNU General Public License as published by
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
8 ;; the Free Software Foundation; either version 3, or (at your option)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
9 ;; any later version.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
10
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
11 ;; GCC is distributed in the hope that it will be useful,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
12 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
13 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
14 ;; GNU General Public License for more details.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
15
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
16 ;; You should have received a copy of the GNU General Public License
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
17 ;; along with GCC; see the file COPYING3. If not see
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
18 ;; <http://www.gnu.org/licenses/>.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
19
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
20 (include "predicates.md")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
21 (include "constraints.md")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
22
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
23 ;;;; Unspecs
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
24
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
25 (define_c_enum "unspec" [
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
26 UNSPEC_LDINDABS
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
27 UNSPEC_XADD
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
28 ])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
29
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
30 ;;;; Constants
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
31
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
32 (define_constants
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
33 [(R0_REGNUM 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
34 (R1_REGNUM 1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
35 (R2_REGNUM 2)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
36 (R3_REGNUM 3)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
37 (R4_REGNUM 4)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
38 (R5_REGNUM 5)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
39 (R6_REGNUM 6)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
40 (R7_REGNUM 7)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
41 (R8_REGNUM 8)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
42 (R9_REGNUM 9)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
43 (R10_REGNUM 10)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
44 (R11_REGNUM 11)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
45 ])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
46
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
47 ;;;; Attributes
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
48
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
49 ;; Instruction classes.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
50 ;; alu 64-bit arithmetic.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
51 ;; alu32 32-bit arithmetic.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
52 ;; end endianness conversion instructions.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
53 ;; ld load instructions.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
54 ;; lddx load 64-bit immediate instruction.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
55 ;; ldx generic load instructions.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
56 ;; st generic store instructions for immediates.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
57 ;; stx generic store instructions.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
58 ;; jmp jump instructions.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
59 ;; xadd atomic exchange-and-add instructions.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
60 ;; multi multiword sequence (or user asm statements).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
61
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
62 (define_attr "type"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
63 "unknown,alu,alu32,end,ld,lddw,ldx,st,stx,jmp,xadd,multi"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
64 (const_string "unknown"))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
65
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
66 ;; Length of instruction in bytes.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
67 (define_attr "length" ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
68 (cond [
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
69 (eq_attr "type" "lddw") (const_int 16)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
70 ] (const_int 8)))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
71
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
72 ;; Describe a user's asm statement.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
73 (define_asm_attributes
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
74 [(set_attr "type" "multi")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
75
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
76 ;;;; Mode attributes and iterators
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
77
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
78 (define_mode_attr mop [(QI "b") (HI "h") (SI "w") (DI "dw")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
79 (SF "w") (DF "dw")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
80 (define_mode_attr mtype [(SI "alu32") (DI "alu")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
81 (define_mode_attr msuffix [(SI "32") (DI "")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
82
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
83 ;;;; NOPs
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
84
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
85 (define_insn "nop"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
86 [(const_int 0)]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
87 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
88 "mov\t%%r0,%%r0"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
89 [(set_attr "type" "alu")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
90
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
91 ;;;; Arithmetic/Logical
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
92
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
93 ;; The arithmetic and logic operations below are defined for SI and DI
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
94 ;; modes. The mode iterator AM is used in order to expand to two
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
95 ;; insns, with the proper modes.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
96 ;;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
97 ;; 32-bit arithmetic (for SI modes) is implemented using the alu32
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
98 ;; instructions.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
99
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
100 (define_mode_iterator AM [SI DI])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
101
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
102 ;;; Addition
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
103 (define_insn "add<AM:mode>3"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
104 [(set (match_operand:AM 0 "register_operand" "=r,r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
105 (plus:AM (match_operand:AM 1 "register_operand" " 0,0")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
106 (match_operand:AM 2 "reg_or_imm_operand" " r,I")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
107 "1"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
108 "add<msuffix>\t%0,%2"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
109 [(set_attr "type" "<mtype>")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
110
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
111 ;;; Subtraction
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
112
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
113 ;; Note that subtractions of constants become additions, so there is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
114 ;; no need to handle immediate operands in the subMODE3 insns.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
115
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
116 (define_insn "sub<AM:mode>3"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
117 [(set (match_operand:AM 0 "register_operand" "=r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
118 (minus:AM (match_operand:AM 1 "register_operand" " 0")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
119 (match_operand:AM 2 "register_operand" " r")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
120 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
121 "sub<msuffix>\t%0,%2"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
122 [(set_attr "type" "<mtype>")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
123
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
124 ;;; Negation
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
125 (define_insn "neg<AM:mode>2"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
126 [(set (match_operand:AM 0 "register_operand" "=r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
127 (neg:AM (match_operand:AM 1 "register_operand" " 0")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
128 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
129 "neg<msuffix>\t%0"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
130 [(set_attr "type" "<mtype>")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
131
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
132 ;;; Multiplication
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
133 (define_insn "mul<AM:mode>3"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
134 [(set (match_operand:AM 0 "register_operand" "=r,r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
135 (mult:AM (match_operand:AM 1 "register_operand" " 0,0")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
136 (match_operand:AM 2 "reg_or_imm_operand" " r,I")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
137 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
138 "mul<msuffix>\t%0,%2"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
139 [(set_attr "type" "<mtype>")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
140
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
141 (define_insn "*mulsidi3_zeroextend"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
142 [(set (match_operand:DI 0 "register_operand" "=r,r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
143 (zero_extend:DI
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
144 (mult:SI (match_operand:SI 1 "register_operand" "0,0")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
145 (match_operand:SI 2 "reg_or_imm_operand" "r,I"))))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
146 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
147 "mul32\t%0,%2"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
148 [(set_attr "type" "alu32")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
149
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
150 ;;; Division
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
151
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
152 ;; Note that eBPF doesn't provide instructions for signed integer
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
153 ;; division.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
154
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
155 (define_insn "udiv<AM:mode>3"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
156 [(set (match_operand:AM 0 "register_operand" "=r,r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
157 (udiv:AM (match_operand:AM 1 "register_operand" " 0,0")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
158 (match_operand:AM 2 "reg_or_imm_operand" "r,I")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
159 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
160 "div<msuffix>\t%0,%2"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
161 [(set_attr "type" "<mtype>")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
162
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
163 ;;; Modulus
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
164
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
165 ;; Note that eBPF doesn't provide instructions for signed integer
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
166 ;; remainder.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
167
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
168 (define_insn "umod<AM:mode>3"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
169 [(set (match_operand:AM 0 "register_operand" "=r,r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
170 (umod:AM (match_operand:AM 1 "register_operand" " 0,0")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
171 (match_operand:AM 2 "reg_or_imm_operand" "r,I")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
172 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
173 "mod<msuffix>\t%0,%2"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
174 [(set_attr "type" "<mtype>")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
175
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
176 ;;; Logical AND
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
177 (define_insn "and<AM:mode>3"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
178 [(set (match_operand:AM 0 "register_operand" "=r,r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
179 (and:AM (match_operand:AM 1 "register_operand" " 0,0")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
180 (match_operand:AM 2 "reg_or_imm_operand" "r,I")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
181 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
182 "and<msuffix>\t%0,%2"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
183 [(set_attr "type" "<mtype>")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
184
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
185 ;;; Logical inclusive-OR
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
186 (define_insn "ior<AM:mode>3"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
187 [(set (match_operand:AM 0 "register_operand" "=r,r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
188 (ior:AM (match_operand:AM 1 "register_operand" " 0,0")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
189 (match_operand:AM 2 "reg_or_imm_operand" "r,I")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
190 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
191 "or<msuffix>\t%0,%2"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
192 [(set_attr "type" "<mtype>")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
193
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
194 ;;; Logical exclusive-OR
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
195 (define_insn "xor<AM:mode>3"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
196 [(set (match_operand:AM 0 "register_operand" "=r,r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
197 (xor:AM (match_operand:AM 1 "register_operand" " 0,0")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
198 (match_operand:AM 2 "reg_or_imm_operand" "r,I")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
199 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
200 "xor<msuffix>\t%0,%2"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
201 [(set_attr "type" "<mtype>")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
202
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
203 ;;;; Conversions
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
204
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
205 ;;; Zero-extensions
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
206
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
207 ;; For register operands smaller than 32-bit zero-extending is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
208 ;; achieved ANDing the value in the source register to a suitable
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
209 ;; mask.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
210 ;;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
211 ;; For register operands bigger or equal than 32-bit, we generate a
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
212 ;; mov32 instruction to zero the high 32-bits of the destination
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
213 ;; register.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
214 ;;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
215 ;; For memory operands, of any width, zero-extending is achieved using
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
216 ;; the ldx{bhwdw} instructions to load the values in registers.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
217
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
218 (define_insn "zero_extendhidi2"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
219 [(set (match_operand:DI 0 "register_operand" "=r,r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
220 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
221 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
222 "@
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
223 and\t%0,0xffff
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
224 ldxh\t%0,%1"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
225 [(set_attr "type" "alu,ldx")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
226
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
227 (define_insn "zero_extendqidi2"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
228 [(set (match_operand:DI 0 "register_operand" "=r,r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
229 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
230 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
231 "@
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
232 and\t%0,0xff
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
233 ldxb\t%0,%1"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
234 [(set_attr "type" "alu,ldx")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
235
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
236 (define_insn "zero_extendsidi2"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
237 [(set (match_operand:DI 0 "register_operand" "=r,r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
238 (zero_extend:DI
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
239 (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
240 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
241 "@
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
242 mov32\t%0,%1
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
243 ldxw\t%0,%1"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
244 [(set_attr "type" "alu,ldx")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
245
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
246 ;;; Sign-extension
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
247
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
248 ;; Sign-extending a 32-bit value into a 64-bit value is achieved using
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
249 ;; shifting, with instructions generated by the expand below.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
250
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
251 (define_expand "extendsidi2"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
252 [(set (match_operand:DI 0 "register_operand")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
253 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
254 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
255 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
256 operands[1] = gen_lowpart (DImode, operands[1]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
257 emit_insn (gen_ashldi3 (operands[0], operands[1], GEN_INT (32)));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
258 emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (32)));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
259 DONE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
260 })
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
261
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
262 ;;;; Data movement
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
263
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
264 (define_mode_iterator MM [QI HI SI DI SF DF])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
265
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
266 (define_expand "mov<MM:mode>"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
267 [(set (match_operand:MM 0 "general_operand")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
268 (match_operand:MM 1 "general_operand"))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
269 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
270 "
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
271 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
272 if (!register_operand(operands[0], <MM:MODE>mode)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
273 && !register_operand(operands[1], <MM:MODE>mode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
274 operands[1] = force_reg (<MM:MODE>mode, operands[1]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
275 }")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
276
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
277 (define_insn "*mov<MM:mode>"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
278 [(set (match_operand:MM 0 "nonimmediate_operand" "=r, r,r,m,m")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
279 (match_operand:MM 1 "mov_src_operand" " m,rI,B,r,I"))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
280 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
281 "@
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
282 ldx<mop>\t%0,%1
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
283 mov\t%0,%1
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
284 lddw\t%0,%1
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
285 stx<mop>\t%0,%1
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
286 st<mop>\t%0,%1"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
287 [(set_attr "type" "ldx,alu,alu,stx,st")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
288
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
289 ;;;; Shifts
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
290
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
291 (define_mode_iterator SIM [SI DI])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
292
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
293 (define_insn "ashr<SIM:mode>3"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
294 [(set (match_operand:SIM 0 "register_operand" "=r,r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
295 (ashiftrt:SIM (match_operand:SIM 1 "register_operand" " 0,0")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
296 (match_operand:SIM 2 "reg_or_imm_operand" " r,I")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
297 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
298 "arsh<msuffix>\t%0,%2"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
299 [(set_attr "type" "<mtype>")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
300
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
301 (define_insn "ashl<SIM:mode>3"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
302 [(set (match_operand:SIM 0 "register_operand" "=r,r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
303 (ashift:SIM (match_operand:SIM 1 "register_operand" " 0,0")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
304 (match_operand:SIM 2 "reg_or_imm_operand" " r,I")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
305 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
306 "lsh<msuffix>\t%0,%2"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
307 [(set_attr "type" "<mtype>")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
308
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
309 (define_insn "lshr<SIM:mode>3"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
310 [(set (match_operand:SIM 0 "register_operand" "=r,r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
311 (lshiftrt:SIM (match_operand:SIM 1 "register_operand" " 0,0")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
312 (match_operand:SIM 2 "reg_or_imm_operand" " r,I")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
313 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
314 "rsh<msuffix>\t%0,%2"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
315 [(set_attr "type" "<mtype>")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
316
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
317 ;;;; Conditional branches
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
318
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
319 ;; The eBPF jump instructions use 64-bit arithmetic when evaluating
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
320 ;; the jump conditions. Therefore we use DI modes below.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
321
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
322 (define_expand "cbranchdi4"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
323 [(set (pc)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
324 (if_then_else (match_operator 0 "comparison_operator"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
325 [(match_operand:DI 1 "register_operand")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
326 (match_operand:DI 2 "reg_or_imm_operand")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
327 (label_ref (match_operand 3 "" ""))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
328 (pc)))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
329 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
330 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
331 if (!ordered_comparison_operator (operands[0], VOIDmode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
332 FAIL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
333 })
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
334
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
335 (define_insn "*branch_on_di"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
336 [(set (pc)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
337 (if_then_else (match_operator 3 "ordered_comparison_operator"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
338 [(match_operand:DI 0 "register_operand" "r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
339 (match_operand:DI 1 "reg_or_imm_operand" "rI")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
340 (label_ref (match_operand 2 "" ""))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
341 (pc)))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
342 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
343 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
344 int code = GET_CODE (operands[3]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
345
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
346 switch (code)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
347 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
348 case EQ: return "jeq\t%0,%1,%2"; break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
349 case NE: return "jne\t%0,%1,%2"; break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
350 case LT: return "jslt\t%0,%1,%2"; break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
351 case LE: return "jsle\t%0,%1,%2"; break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
352 case GT: return "jsgt\t%0,%1,%2"; break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
353 case GE: return "jsge\t%0,%1,%2"; break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
354 case LTU: return "jlt\t%0,%1,%2"; break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
355 case LEU: return "jle\t%0,%1,%2"; break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
356 case GTU: return "jgt\t%0,%1,%2"; break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
357 case GEU: return "jge\t%0,%1,%2"; break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
358 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
359 gcc_unreachable ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
360 return "";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
361 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
362 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
363 [(set_attr "type" "jmp")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
364
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
365 ;;;; Unconditional branches
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
366
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
367 (define_insn "jump"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
368 [(set (pc)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
369 (label_ref (match_operand 0 "" "")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
370 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
371 "ja\t%0"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
372 [(set_attr "type" "jmp")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
373
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
374 ;;;; Function prologue/epilogue
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
375
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
376 (define_insn "exit"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
377 [(simple_return)]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
378 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
379 "exit"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
380 [(set_attr "type" "jmp")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
381
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
382 (define_expand "prologue"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
383 [(const_int 0)]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
384 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
385 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
386 bpf_expand_prologue ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
387 DONE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
388 })
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
389
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
390 (define_expand "epilogue"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
391 [(const_int 0)]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
392 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
393 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
394 bpf_expand_epilogue ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
395 DONE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
396 })
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
397
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
398 ;;;; Function calls
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
399
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
400 (define_expand "call"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
401 [(parallel [(call (match_operand 0 "")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
402 (match_operand 1 ""))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
403 (use (match_operand 2 "")) ;; next_arg_reg
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
404 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
405 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
406 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
407 rtx target = XEXP (operands[0], 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
408 emit_call_insn (gen_call_internal (target, operands[1]));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
409 DONE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
410 })
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
411
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
412 (define_insn "call_internal"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
413 [(call (mem:DI (match_operand:DI 0 "call_operand" "Sr"))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
414 (match_operand:SI 1 "general_operand" ""))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
415 ;; operands[2] is next_arg_register
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
416 ;; operands[3] is struct_value_size_rtx.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
417 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
418 { return bpf_output_call (operands[0]); }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
419 [(set_attr "type" "jmp")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
420
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
421 (define_expand "call_value"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
422 [(parallel [(set (match_operand 0 "")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
423 (call (match_operand 1 "")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
424 (match_operand 2 "")))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
425 (use (match_operand 3 ""))])] ;; next_arg_reg
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
426 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
427 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
428 rtx target = XEXP (operands[1], 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
429 emit_call_insn (gen_call_value_internal (operands[0], target,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
430 operands[2]));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
431 DONE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
432 })
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
433
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
434 (define_insn "call_value_internal"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
435 [(set (match_operand 0 "register_operand" "")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
436 (call (mem:DI (match_operand:DI 1 "call_operand" "Sr"))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
437 (match_operand:SI 2 "general_operand" "")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
438 ;; operands[3] is next_arg_register
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
439 ;; operands[4] is struct_value_size_rtx.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
440 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
441 { return bpf_output_call (operands[1]); }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
442 [(set_attr "type" "jmp")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
443
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
444 (define_insn "sibcall"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
445 [(call (label_ref (match_operand 0 "" ""))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
446 (match_operand:SI 1 "general_operand" ""))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
447 ;; operands[2] is next_arg_register
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
448 ;; operands[3] is struct_value_size_rtx.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
449 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
450 "ja\t%0"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
451 [(set_attr "type" "jmp")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
452
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
453 ;;;; Non-generic load instructions
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
454
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
455 (define_mode_iterator LDM [QI HI SI DI])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
456 (define_mode_attr ldop [(QI "b") (HI "h") (SI "w") (DI "dw")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
457
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
458 (define_insn "ldind<ldop>"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
459 [(set (reg:LDM R0_REGNUM)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
460 (unspec:LDM [(match_operand:DI 0 "register_operand" "r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
461 (match_operand:SI 1 "imm32_operand" "I")]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
462 UNSPEC_LDINDABS))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
463 (clobber (reg:DI R1_REGNUM))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
464 (clobber (reg:DI R2_REGNUM))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
465 (clobber (reg:DI R3_REGNUM))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
466 (clobber (reg:DI R4_REGNUM))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
467 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
468 "ldind<ldop>\t%0,%1"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
469 [(set_attr "type" "ld")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
470
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
471 (define_insn "ldabs<ldop>"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
472 [(set (reg:LDM R0_REGNUM)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
473 (unspec:LDM [(match_operand:SI 0 "imm32_operand" "I")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
474 (match_operand:SI 1 "imm32_operand" "I")]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
475 UNSPEC_LDINDABS))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
476 (clobber (reg:DI R1_REGNUM))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
477 (clobber (reg:DI R2_REGNUM))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
478 (clobber (reg:DI R3_REGNUM))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
479 (clobber (reg:DI R4_REGNUM))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
480 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
481 "ldabs<ldop>\t%0"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
482 [(set_attr "type" "ld")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
483
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
484 ;;;; Atomic increments
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
485
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
486 (define_mode_iterator AMO [SI DI])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
487
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
488 (define_insn "atomic_add<AMO:mode>"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
489 [(set (match_operand:AMO 0 "memory_operand" "+m")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
490 (unspec_volatile:AMO
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
491 [(plus:AMO (match_dup 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
492 (match_operand:AMO 1 "register_operand" "r"))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
493 (match_operand:SI 2 "const_int_operand")] ;; Memory model.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
494 UNSPEC_XADD))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
495 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
496 "xadd<mop>\t%0,%1"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
497 [(set_attr "type" "xadd")])