1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 package mips
31
32 import (
33 "cmd/internal/obj"
34 "cmd/internal/objabi"
35 "cmd/internal/sys"
36 "fmt"
37 "log"
38 "slices"
39 )
40
41
42
43
44 type ctxt0 struct {
45 ctxt *obj.Link
46 newprog obj.ProgAlloc
47 cursym *obj.LSym
48 autosize int32
49 instoffset int64
50 pc int64
51 }
52
53
54
55 const (
56 mips64FuncAlign = 8
57 )
58
59 const (
60 r0iszero = 1
61 )
62
63 type Optab struct {
64 as obj.As
65 a1 uint8
66 a2 uint8
67 a3 uint8
68 type_ int8
69 size int8
70 param int16
71 family sys.ArchFamily
72 flag uint8
73 }
74
75 const (
76
77 NOTUSETMP = 1 << iota
78 )
79
80 var optab = []Optab{
81 {obj.ATEXT, C_LEXT, C_NONE, C_TEXTSIZE, 0, 0, 0, sys.MIPS64, 0},
82 {obj.ATEXT, C_ADDR, C_NONE, C_TEXTSIZE, 0, 0, 0, 0, 0},
83
84 {AMOVW, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0},
85 {AMOVV, C_REG, C_NONE, C_REG, 1, 4, 0, sys.MIPS64, 0},
86 {AMOVB, C_REG, C_NONE, C_REG, 12, 8, 0, 0, NOTUSETMP},
87 {AMOVBU, C_REG, C_NONE, C_REG, 13, 4, 0, 0, 0},
88 {AMOVWU, C_REG, C_NONE, C_REG, 14, 8, 0, sys.MIPS64, NOTUSETMP},
89
90 {ASUB, C_REG, C_REG, C_REG, 2, 4, 0, 0, 0},
91 {ASUBV, C_REG, C_REG, C_REG, 2, 4, 0, sys.MIPS64, 0},
92 {AADD, C_REG, C_REG, C_REG, 2, 4, 0, 0, 0},
93 {AADDV, C_REG, C_REG, C_REG, 2, 4, 0, sys.MIPS64, 0},
94 {AAND, C_REG, C_REG, C_REG, 2, 4, 0, 0, 0},
95 {ASUB, C_REG, C_NONE, C_REG, 2, 4, 0, 0, 0},
96 {ASUBV, C_REG, C_NONE, C_REG, 2, 4, 0, sys.MIPS64, 0},
97 {AADD, C_REG, C_NONE, C_REG, 2, 4, 0, 0, 0},
98 {AADDV, C_REG, C_NONE, C_REG, 2, 4, 0, sys.MIPS64, 0},
99 {AAND, C_REG, C_NONE, C_REG, 2, 4, 0, 0, 0},
100 {ACMOVN, C_REG, C_REG, C_REG, 2, 4, 0, 0, 0},
101 {ANEGW, C_REG, C_NONE, C_REG, 2, 4, 0, 0, 0},
102 {ANEGV, C_REG, C_NONE, C_REG, 2, 4, 0, sys.MIPS64, 0},
103
104 {ASLL, C_REG, C_NONE, C_REG, 9, 4, 0, 0, 0},
105 {ASLL, C_REG, C_REG, C_REG, 9, 4, 0, 0, 0},
106 {ASLLV, C_REG, C_NONE, C_REG, 9, 4, 0, sys.MIPS64, 0},
107 {ASLLV, C_REG, C_REG, C_REG, 9, 4, 0, sys.MIPS64, 0},
108 {ACLO, C_REG, C_NONE, C_REG, 9, 4, 0, 0, 0},
109
110 {AADDF, C_FREG, C_NONE, C_FREG, 32, 4, 0, 0, 0},
111 {AADDF, C_FREG, C_REG, C_FREG, 32, 4, 0, 0, 0},
112 {ACMPEQF, C_FREG, C_REG, C_NONE, 32, 4, 0, 0, 0},
113 {AABSF, C_FREG, C_NONE, C_FREG, 33, 4, 0, 0, 0},
114 {AMOVVF, C_FREG, C_NONE, C_FREG, 33, 4, 0, sys.MIPS64, 0},
115 {AMOVF, C_FREG, C_NONE, C_FREG, 33, 4, 0, 0, 0},
116 {AMOVD, C_FREG, C_NONE, C_FREG, 33, 4, 0, 0, 0},
117
118 {AMOVW, C_REG, C_NONE, C_SEXT, 7, 4, REGSB, sys.MIPS64, 0},
119 {AMOVWU, C_REG, C_NONE, C_SEXT, 7, 4, REGSB, sys.MIPS64, 0},
120 {AMOVV, C_REG, C_NONE, C_SEXT, 7, 4, REGSB, sys.MIPS64, 0},
121 {AMOVB, C_REG, C_NONE, C_SEXT, 7, 4, REGSB, sys.MIPS64, 0},
122 {AMOVBU, C_REG, C_NONE, C_SEXT, 7, 4, REGSB, sys.MIPS64, 0},
123 {AMOVWL, C_REG, C_NONE, C_SEXT, 7, 4, REGSB, sys.MIPS64, 0},
124 {AMOVVL, C_REG, C_NONE, C_SEXT, 7, 4, REGSB, sys.MIPS64, 0},
125 {AMOVW, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP, 0, 0},
126 {AMOVWU, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP, sys.MIPS64, 0},
127 {AMOVV, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP, sys.MIPS64, 0},
128 {AMOVB, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP, 0, 0},
129 {AMOVBU, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP, 0, 0},
130 {AMOVWL, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP, 0, 0},
131 {AMOVVL, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP, sys.MIPS64, 0},
132 {AMOVW, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO, 0, 0},
133 {AMOVWU, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO, sys.MIPS64, 0},
134 {AMOVV, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO, sys.MIPS64, 0},
135 {AMOVB, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO, 0, 0},
136 {AMOVBU, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO, 0, 0},
137 {AMOVWL, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO, 0, 0},
138 {AMOVVL, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO, sys.MIPS64, 0},
139 {ASC, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO, 0, 0},
140 {ASCV, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO, sys.MIPS64, 0},
141
142 {AMOVW, C_SEXT, C_NONE, C_REG, 8, 4, REGSB, sys.MIPS64, 0},
143 {AMOVWU, C_SEXT, C_NONE, C_REG, 8, 4, REGSB, sys.MIPS64, 0},
144 {AMOVV, C_SEXT, C_NONE, C_REG, 8, 4, REGSB, sys.MIPS64, 0},
145 {AMOVB, C_SEXT, C_NONE, C_REG, 8, 4, REGSB, sys.MIPS64, 0},
146 {AMOVBU, C_SEXT, C_NONE, C_REG, 8, 4, REGSB, sys.MIPS64, 0},
147 {AMOVWL, C_SEXT, C_NONE, C_REG, 8, 4, REGSB, sys.MIPS64, 0},
148 {AMOVVL, C_SEXT, C_NONE, C_REG, 8, 4, REGSB, sys.MIPS64, 0},
149 {AMOVW, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP, 0, 0},
150 {AMOVWU, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP, sys.MIPS64, 0},
151 {AMOVV, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP, sys.MIPS64, 0},
152 {AMOVB, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP, 0, 0},
153 {AMOVBU, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP, 0, 0},
154 {AMOVWL, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP, 0, 0},
155 {AMOVVL, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP, sys.MIPS64, 0},
156 {AMOVW, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO, 0, 0},
157 {AMOVWU, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO, sys.MIPS64, 0},
158 {AMOVV, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO, sys.MIPS64, 0},
159 {AMOVB, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO, 0, 0},
160 {AMOVBU, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO, 0, 0},
161 {AMOVWL, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO, 0, 0},
162 {AMOVVL, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO, sys.MIPS64, 0},
163 {ALL, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO, 0, 0},
164 {ALLV, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO, sys.MIPS64, 0},
165
166 {AMOVW, C_REG, C_NONE, C_LEXT, 35, 12, REGSB, sys.MIPS64, 0},
167 {AMOVWU, C_REG, C_NONE, C_LEXT, 35, 12, REGSB, sys.MIPS64, 0},
168 {AMOVV, C_REG, C_NONE, C_LEXT, 35, 12, REGSB, sys.MIPS64, 0},
169 {AMOVB, C_REG, C_NONE, C_LEXT, 35, 12, REGSB, sys.MIPS64, 0},
170 {AMOVBU, C_REG, C_NONE, C_LEXT, 35, 12, REGSB, sys.MIPS64, 0},
171 {AMOVW, C_REG, C_NONE, C_LAUTO, 35, 12, REGSP, 0, 0},
172 {AMOVWU, C_REG, C_NONE, C_LAUTO, 35, 12, REGSP, sys.MIPS64, 0},
173 {AMOVV, C_REG, C_NONE, C_LAUTO, 35, 12, REGSP, sys.MIPS64, 0},
174 {AMOVB, C_REG, C_NONE, C_LAUTO, 35, 12, REGSP, 0, 0},
175 {AMOVBU, C_REG, C_NONE, C_LAUTO, 35, 12, REGSP, 0, 0},
176 {AMOVW, C_REG, C_NONE, C_LOREG, 35, 12, REGZERO, 0, 0},
177 {AMOVWU, C_REG, C_NONE, C_LOREG, 35, 12, REGZERO, sys.MIPS64, 0},
178 {AMOVV, C_REG, C_NONE, C_LOREG, 35, 12, REGZERO, sys.MIPS64, 0},
179 {AMOVB, C_REG, C_NONE, C_LOREG, 35, 12, REGZERO, 0, 0},
180 {AMOVBU, C_REG, C_NONE, C_LOREG, 35, 12, REGZERO, 0, 0},
181 {ASC, C_REG, C_NONE, C_LOREG, 35, 12, REGZERO, 0, 0},
182 {AMOVW, C_REG, C_NONE, C_ADDR, 50, 8, 0, sys.MIPS, 0},
183 {AMOVW, C_REG, C_NONE, C_ADDR, 50, 12, 0, sys.MIPS64, 0},
184 {AMOVWU, C_REG, C_NONE, C_ADDR, 50, 12, 0, sys.MIPS64, 0},
185 {AMOVV, C_REG, C_NONE, C_ADDR, 50, 12, 0, sys.MIPS64, 0},
186 {AMOVB, C_REG, C_NONE, C_ADDR, 50, 8, 0, sys.MIPS, 0},
187 {AMOVB, C_REG, C_NONE, C_ADDR, 50, 12, 0, sys.MIPS64, 0},
188 {AMOVBU, C_REG, C_NONE, C_ADDR, 50, 8, 0, sys.MIPS, 0},
189 {AMOVBU, C_REG, C_NONE, C_ADDR, 50, 12, 0, sys.MIPS64, 0},
190 {AMOVW, C_REG, C_NONE, C_TLS, 53, 8, 0, 0, NOTUSETMP},
191 {AMOVWU, C_REG, C_NONE, C_TLS, 53, 8, 0, sys.MIPS64, NOTUSETMP},
192 {AMOVV, C_REG, C_NONE, C_TLS, 53, 8, 0, sys.MIPS64, NOTUSETMP},
193 {AMOVB, C_REG, C_NONE, C_TLS, 53, 8, 0, 0, NOTUSETMP},
194 {AMOVBU, C_REG, C_NONE, C_TLS, 53, 8, 0, 0, NOTUSETMP},
195
196 {AMOVW, C_LEXT, C_NONE, C_REG, 36, 12, REGSB, sys.MIPS64, 0},
197 {AMOVWU, C_LEXT, C_NONE, C_REG, 36, 12, REGSB, sys.MIPS64, 0},
198 {AMOVV, C_LEXT, C_NONE, C_REG, 36, 12, REGSB, sys.MIPS64, 0},
199 {AMOVB, C_LEXT, C_NONE, C_REG, 36, 12, REGSB, sys.MIPS64, 0},
200 {AMOVBU, C_LEXT, C_NONE, C_REG, 36, 12, REGSB, sys.MIPS64, 0},
201 {AMOVW, C_LAUTO, C_NONE, C_REG, 36, 12, REGSP, 0, 0},
202 {AMOVWU, C_LAUTO, C_NONE, C_REG, 36, 12, REGSP, sys.MIPS64, 0},
203 {AMOVV, C_LAUTO, C_NONE, C_REG, 36, 12, REGSP, sys.MIPS64, 0},
204 {AMOVB, C_LAUTO, C_NONE, C_REG, 36, 12, REGSP, 0, 0},
205 {AMOVBU, C_LAUTO, C_NONE, C_REG, 36, 12, REGSP, 0, 0},
206 {AMOVW, C_LOREG, C_NONE, C_REG, 36, 12, REGZERO, 0, 0},
207 {AMOVWU, C_LOREG, C_NONE, C_REG, 36, 12, REGZERO, sys.MIPS64, 0},
208 {AMOVV, C_LOREG, C_NONE, C_REG, 36, 12, REGZERO, sys.MIPS64, 0},
209 {AMOVB, C_LOREG, C_NONE, C_REG, 36, 12, REGZERO, 0, 0},
210 {AMOVBU, C_LOREG, C_NONE, C_REG, 36, 12, REGZERO, 0, 0},
211 {AMOVW, C_ADDR, C_NONE, C_REG, 51, 8, 0, sys.MIPS, 0},
212 {AMOVW, C_ADDR, C_NONE, C_REG, 51, 12, 0, sys.MIPS64, 0},
213 {AMOVWU, C_ADDR, C_NONE, C_REG, 51, 12, 0, sys.MIPS64, 0},
214 {AMOVV, C_ADDR, C_NONE, C_REG, 51, 12, 0, sys.MIPS64, 0},
215 {AMOVB, C_ADDR, C_NONE, C_REG, 51, 8, 0, sys.MIPS, 0},
216 {AMOVB, C_ADDR, C_NONE, C_REG, 51, 12, 0, sys.MIPS64, 0},
217 {AMOVBU, C_ADDR, C_NONE, C_REG, 51, 8, 0, sys.MIPS, 0},
218 {AMOVBU, C_ADDR, C_NONE, C_REG, 51, 12, 0, sys.MIPS64, 0},
219 {AMOVW, C_TLS, C_NONE, C_REG, 54, 8, 0, 0, NOTUSETMP},
220 {AMOVWU, C_TLS, C_NONE, C_REG, 54, 8, 0, sys.MIPS64, NOTUSETMP},
221 {AMOVV, C_TLS, C_NONE, C_REG, 54, 8, 0, sys.MIPS64, NOTUSETMP},
222 {AMOVB, C_TLS, C_NONE, C_REG, 54, 8, 0, 0, NOTUSETMP},
223 {AMOVBU, C_TLS, C_NONE, C_REG, 54, 8, 0, 0, NOTUSETMP},
224
225 {AMOVW, C_SECON, C_NONE, C_REG, 3, 4, REGSB, sys.MIPS64, 0},
226 {AMOVV, C_SECON, C_NONE, C_REG, 3, 4, REGSB, sys.MIPS64, 0},
227 {AMOVW, C_SACON, C_NONE, C_REG, 3, 4, REGSP, 0, 0},
228 {AMOVV, C_SACON, C_NONE, C_REG, 3, 4, REGSP, sys.MIPS64, 0},
229 {AMOVW, C_LECON, C_NONE, C_REG, 52, 8, REGSB, sys.MIPS, NOTUSETMP},
230 {AMOVW, C_LECON, C_NONE, C_REG, 52, 12, REGSB, sys.MIPS64, NOTUSETMP},
231 {AMOVV, C_LECON, C_NONE, C_REG, 52, 12, REGSB, sys.MIPS64, NOTUSETMP},
232
233 {AMOVW, C_LACON, C_NONE, C_REG, 26, 12, REGSP, 0, 0},
234 {AMOVV, C_LACON, C_NONE, C_REG, 26, 12, REGSP, sys.MIPS64, 0},
235 {AMOVW, C_ADDCON, C_NONE, C_REG, 3, 4, REGZERO, 0, 0},
236 {AMOVV, C_ADDCON, C_NONE, C_REG, 3, 4, REGZERO, sys.MIPS64, 0},
237 {AMOVW, C_ANDCON, C_NONE, C_REG, 3, 4, REGZERO, 0, 0},
238 {AMOVV, C_ANDCON, C_NONE, C_REG, 3, 4, REGZERO, sys.MIPS64, 0},
239 {AMOVW, C_STCON, C_NONE, C_REG, 55, 8, 0, 0, NOTUSETMP},
240 {AMOVV, C_STCON, C_NONE, C_REG, 55, 8, 0, sys.MIPS64, NOTUSETMP},
241
242 {AMOVW, C_UCON, C_NONE, C_REG, 24, 4, 0, 0, 0},
243 {AMOVV, C_UCON, C_NONE, C_REG, 24, 4, 0, sys.MIPS64, 0},
244 {AMOVW, C_LCON, C_NONE, C_REG, 19, 8, 0, 0, NOTUSETMP},
245 {AMOVV, C_LCON, C_NONE, C_REG, 19, 8, 0, sys.MIPS64, NOTUSETMP},
246
247 {AMOVW, C_HI, C_NONE, C_REG, 20, 4, 0, 0, 0},
248 {AMOVV, C_HI, C_NONE, C_REG, 20, 4, 0, sys.MIPS64, 0},
249 {AMOVW, C_LO, C_NONE, C_REG, 20, 4, 0, 0, 0},
250 {AMOVV, C_LO, C_NONE, C_REG, 20, 4, 0, sys.MIPS64, 0},
251 {AMOVW, C_REG, C_NONE, C_HI, 21, 4, 0, 0, 0},
252 {AMOVV, C_REG, C_NONE, C_HI, 21, 4, 0, sys.MIPS64, 0},
253 {AMOVW, C_REG, C_NONE, C_LO, 21, 4, 0, 0, 0},
254 {AMOVV, C_REG, C_NONE, C_LO, 21, 4, 0, sys.MIPS64, 0},
255
256 {AMUL, C_REG, C_REG, C_NONE, 22, 4, 0, 0, 0},
257 {AMUL, C_REG, C_REG, C_REG, 22, 4, 0, 0, 0},
258 {AMULV, C_REG, C_REG, C_NONE, 22, 4, 0, sys.MIPS64, 0},
259
260 {AADD, C_ADD0CON, C_REG, C_REG, 4, 4, 0, 0, 0},
261 {AADD, C_ADD0CON, C_NONE, C_REG, 4, 4, 0, 0, 0},
262 {AADD, C_ANDCON, C_REG, C_REG, 10, 8, 0, 0, 0},
263 {AADD, C_ANDCON, C_NONE, C_REG, 10, 8, 0, 0, 0},
264
265 {AADDV, C_ADD0CON, C_REG, C_REG, 4, 4, 0, sys.MIPS64, 0},
266 {AADDV, C_ADD0CON, C_NONE, C_REG, 4, 4, 0, sys.MIPS64, 0},
267 {AADDV, C_ANDCON, C_REG, C_REG, 10, 8, 0, sys.MIPS64, 0},
268 {AADDV, C_ANDCON, C_NONE, C_REG, 10, 8, 0, sys.MIPS64, 0},
269
270 {AAND, C_AND0CON, C_REG, C_REG, 4, 4, 0, 0, 0},
271 {AAND, C_AND0CON, C_NONE, C_REG, 4, 4, 0, 0, 0},
272 {AAND, C_ADDCON, C_REG, C_REG, 10, 8, 0, 0, 0},
273 {AAND, C_ADDCON, C_NONE, C_REG, 10, 8, 0, 0, 0},
274
275 {AADD, C_UCON, C_REG, C_REG, 25, 8, 0, 0, 0},
276 {AADD, C_UCON, C_NONE, C_REG, 25, 8, 0, 0, 0},
277 {AADDV, C_UCON, C_REG, C_REG, 25, 8, 0, sys.MIPS64, 0},
278 {AADDV, C_UCON, C_NONE, C_REG, 25, 8, 0, sys.MIPS64, 0},
279 {AAND, C_UCON, C_REG, C_REG, 25, 8, 0, 0, 0},
280 {AAND, C_UCON, C_NONE, C_REG, 25, 8, 0, 0, 0},
281
282 {AADD, C_LCON, C_NONE, C_REG, 23, 12, 0, 0, 0},
283 {AADDV, C_LCON, C_NONE, C_REG, 23, 12, 0, sys.MIPS64, 0},
284 {AAND, C_LCON, C_NONE, C_REG, 23, 12, 0, 0, 0},
285 {AADD, C_LCON, C_REG, C_REG, 23, 12, 0, 0, 0},
286 {AADDV, C_LCON, C_REG, C_REG, 23, 12, 0, sys.MIPS64, 0},
287 {AAND, C_LCON, C_REG, C_REG, 23, 12, 0, 0, 0},
288
289 {ASLL, C_SCON, C_REG, C_REG, 16, 4, 0, 0, 0},
290 {ASLL, C_SCON, C_NONE, C_REG, 16, 4, 0, 0, 0},
291
292 {ASLLV, C_SCON, C_REG, C_REG, 16, 4, 0, sys.MIPS64, 0},
293 {ASLLV, C_SCON, C_NONE, C_REG, 16, 4, 0, sys.MIPS64, 0},
294
295 {ASYSCALL, C_NONE, C_NONE, C_NONE, 5, 4, 0, 0, 0},
296
297 {ABEQ, C_REG, C_REG, C_SBRA, 6, 4, 0, 0, 0},
298 {ABEQ, C_REG, C_NONE, C_SBRA, 6, 4, 0, 0, 0},
299 {ABLEZ, C_REG, C_NONE, C_SBRA, 6, 4, 0, 0, 0},
300 {ABFPT, C_NONE, C_NONE, C_SBRA, 6, 8, 0, 0, NOTUSETMP},
301
302 {AJMP, C_NONE, C_NONE, C_LBRA, 11, 4, 0, 0, 0},
303 {AJAL, C_NONE, C_NONE, C_LBRA, 11, 4, 0, 0, 0},
304
305 {AJMP, C_NONE, C_NONE, C_ZOREG, 18, 4, REGZERO, 0, 0},
306 {AJAL, C_NONE, C_NONE, C_ZOREG, 18, 4, REGLINK, 0, 0},
307
308 {AMOVW, C_SEXT, C_NONE, C_FREG, 27, 4, REGSB, sys.MIPS64, 0},
309 {AMOVF, C_SEXT, C_NONE, C_FREG, 27, 4, REGSB, sys.MIPS64, 0},
310 {AMOVD, C_SEXT, C_NONE, C_FREG, 27, 4, REGSB, sys.MIPS64, 0},
311 {AMOVW, C_SAUTO, C_NONE, C_FREG, 27, 4, REGSP, sys.MIPS64, 0},
312 {AMOVF, C_SAUTO, C_NONE, C_FREG, 27, 4, REGSP, 0, 0},
313 {AMOVD, C_SAUTO, C_NONE, C_FREG, 27, 4, REGSP, 0, 0},
314 {AMOVW, C_SOREG, C_NONE, C_FREG, 27, 4, REGZERO, sys.MIPS64, 0},
315 {AMOVF, C_SOREG, C_NONE, C_FREG, 27, 4, REGZERO, 0, 0},
316 {AMOVD, C_SOREG, C_NONE, C_FREG, 27, 4, REGZERO, 0, 0},
317
318 {AMOVW, C_LEXT, C_NONE, C_FREG, 27, 12, REGSB, sys.MIPS64, 0},
319 {AMOVF, C_LEXT, C_NONE, C_FREG, 27, 12, REGSB, sys.MIPS64, 0},
320 {AMOVD, C_LEXT, C_NONE, C_FREG, 27, 12, REGSB, sys.MIPS64, 0},
321 {AMOVW, C_LAUTO, C_NONE, C_FREG, 27, 12, REGSP, sys.MIPS64, 0},
322 {AMOVF, C_LAUTO, C_NONE, C_FREG, 27, 12, REGSP, 0, 0},
323 {AMOVD, C_LAUTO, C_NONE, C_FREG, 27, 12, REGSP, 0, 0},
324 {AMOVW, C_LOREG, C_NONE, C_FREG, 27, 12, REGZERO, sys.MIPS64, 0},
325 {AMOVF, C_LOREG, C_NONE, C_FREG, 27, 12, REGZERO, 0, 0},
326 {AMOVD, C_LOREG, C_NONE, C_FREG, 27, 12, REGZERO, 0, 0},
327 {AMOVF, C_ADDR, C_NONE, C_FREG, 51, 8, 0, sys.MIPS, 0},
328 {AMOVF, C_ADDR, C_NONE, C_FREG, 51, 12, 0, sys.MIPS64, 0},
329 {AMOVD, C_ADDR, C_NONE, C_FREG, 51, 8, 0, sys.MIPS, 0},
330 {AMOVD, C_ADDR, C_NONE, C_FREG, 51, 12, 0, sys.MIPS64, 0},
331
332 {AMOVW, C_FREG, C_NONE, C_SEXT, 28, 4, REGSB, sys.MIPS64, 0},
333 {AMOVF, C_FREG, C_NONE, C_SEXT, 28, 4, REGSB, sys.MIPS64, 0},
334 {AMOVD, C_FREG, C_NONE, C_SEXT, 28, 4, REGSB, sys.MIPS64, 0},
335 {AMOVW, C_FREG, C_NONE, C_SAUTO, 28, 4, REGSP, sys.MIPS64, 0},
336 {AMOVF, C_FREG, C_NONE, C_SAUTO, 28, 4, REGSP, 0, 0},
337 {AMOVD, C_FREG, C_NONE, C_SAUTO, 28, 4, REGSP, 0, 0},
338 {AMOVW, C_FREG, C_NONE, C_SOREG, 28, 4, REGZERO, sys.MIPS64, 0},
339 {AMOVF, C_FREG, C_NONE, C_SOREG, 28, 4, REGZERO, 0, 0},
340 {AMOVD, C_FREG, C_NONE, C_SOREG, 28, 4, REGZERO, 0, 0},
341
342 {AMOVW, C_FREG, C_NONE, C_LEXT, 28, 12, REGSB, sys.MIPS64, 0},
343 {AMOVF, C_FREG, C_NONE, C_LEXT, 28, 12, REGSB, sys.MIPS64, 0},
344 {AMOVD, C_FREG, C_NONE, C_LEXT, 28, 12, REGSB, sys.MIPS64, 0},
345 {AMOVW, C_FREG, C_NONE, C_LAUTO, 28, 12, REGSP, sys.MIPS64, 0},
346 {AMOVF, C_FREG, C_NONE, C_LAUTO, 28, 12, REGSP, 0, 0},
347 {AMOVD, C_FREG, C_NONE, C_LAUTO, 28, 12, REGSP, 0, 0},
348 {AMOVW, C_FREG, C_NONE, C_LOREG, 28, 12, REGZERO, sys.MIPS64, 0},
349 {AMOVF, C_FREG, C_NONE, C_LOREG, 28, 12, REGZERO, 0, 0},
350 {AMOVD, C_FREG, C_NONE, C_LOREG, 28, 12, REGZERO, 0, 0},
351 {AMOVF, C_FREG, C_NONE, C_ADDR, 50, 8, 0, sys.MIPS, 0},
352 {AMOVF, C_FREG, C_NONE, C_ADDR, 50, 12, 0, sys.MIPS64, 0},
353 {AMOVD, C_FREG, C_NONE, C_ADDR, 50, 8, 0, sys.MIPS, 0},
354 {AMOVD, C_FREG, C_NONE, C_ADDR, 50, 12, 0, sys.MIPS64, 0},
355
356 {AMOVW, C_REG, C_NONE, C_FREG, 30, 4, 0, 0, 0},
357 {AMOVW, C_FREG, C_NONE, C_REG, 31, 4, 0, 0, 0},
358 {AMOVV, C_REG, C_NONE, C_FREG, 47, 4, 0, sys.MIPS64, 0},
359 {AMOVV, C_FREG, C_NONE, C_REG, 48, 4, 0, sys.MIPS64, 0},
360
361 {AMOVW, C_ADDCON, C_NONE, C_FREG, 34, 8, 0, sys.MIPS64, 0},
362 {AMOVW, C_ANDCON, C_NONE, C_FREG, 34, 8, 0, sys.MIPS64, 0},
363
364 {AMOVW, C_REG, C_NONE, C_MREG, 37, 4, 0, 0, 0},
365 {AMOVV, C_REG, C_NONE, C_MREG, 37, 4, 0, sys.MIPS64, 0},
366 {AMOVW, C_MREG, C_NONE, C_REG, 38, 4, 0, 0, 0},
367 {AMOVV, C_MREG, C_NONE, C_REG, 38, 4, 0, sys.MIPS64, 0},
368
369 {AWORD, C_LCON, C_NONE, C_NONE, 40, 4, 0, 0, 0},
370
371 {AMOVW, C_REG, C_NONE, C_FCREG, 41, 4, 0, 0, 0},
372 {AMOVV, C_REG, C_NONE, C_FCREG, 41, 4, 0, sys.MIPS64, 0},
373 {AMOVW, C_FCREG, C_NONE, C_REG, 42, 4, 0, 0, 0},
374 {AMOVV, C_FCREG, C_NONE, C_REG, 42, 4, 0, sys.MIPS64, 0},
375
376 {ATEQ, C_SCON, C_REG, C_REG, 15, 4, 0, 0, 0},
377 {ATEQ, C_SCON, C_NONE, C_REG, 15, 4, 0, 0, 0},
378 {ACMOVT, C_REG, C_NONE, C_REG, 17, 4, 0, 0, 0},
379
380 {AVMOVB, C_SCON, C_NONE, C_WREG, 56, 4, 0, sys.MIPS64, 0},
381 {AVMOVB, C_ADDCON, C_NONE, C_WREG, 56, 4, 0, sys.MIPS64, 0},
382 {AVMOVB, C_SOREG, C_NONE, C_WREG, 57, 4, 0, sys.MIPS64, 0},
383 {AVMOVB, C_WREG, C_NONE, C_SOREG, 58, 4, 0, sys.MIPS64, 0},
384
385 {AWSBH, C_REG, C_NONE, C_REG, 59, 4, 0, 0, 0},
386 {ADSBH, C_REG, C_NONE, C_REG, 59, 4, 0, sys.MIPS64, 0},
387
388 {ABREAK, C_REG, C_NONE, C_SEXT, 7, 4, REGSB, sys.MIPS64, 0},
389 {ABREAK, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP, sys.MIPS64, 0},
390 {ABREAK, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO, sys.MIPS64, 0},
391 {ABREAK, C_NONE, C_NONE, C_NONE, 5, 4, 0, 0, 0},
392
393 {obj.AUNDEF, C_NONE, C_NONE, C_NONE, 49, 4, 0, 0, 0},
394 {obj.APCDATA, C_LCON, C_NONE, C_LCON, 0, 0, 0, 0, 0},
395 {obj.AFUNCDATA, C_SCON, C_NONE, C_ADDR, 0, 0, 0, 0, 0},
396 {obj.ANOP, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0, 0},
397 {obj.ANOP, C_LCON, C_NONE, C_NONE, 0, 0, 0, 0, 0},
398 {obj.ANOP, C_REG, C_NONE, C_NONE, 0, 0, 0, 0, 0},
399 {obj.ANOP, C_FREG, C_NONE, C_NONE, 0, 0, 0, 0, 0},
400 {obj.ADUFFZERO, C_NONE, C_NONE, C_LBRA, 11, 4, 0, 0, 0},
401 {obj.ADUFFCOPY, C_NONE, C_NONE, C_LBRA, 11, 4, 0, 0, 0},
402
403 {obj.AXXX, C_NONE, C_NONE, C_NONE, 0, 4, 0, 0, 0},
404 }
405
406 var oprange [ALAST & obj.AMask][]Optab
407
408 var xcmp [C_NCLASS][C_NCLASS]bool
409
410 func span0(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
411 if ctxt.Retpoline {
412 ctxt.Diag("-spectre=ret not supported on mips")
413 ctxt.Retpoline = false
414 }
415
416 p := cursym.Func().Text
417 if p == nil || p.Link == nil {
418 return
419 }
420
421 c := ctxt0{ctxt: ctxt, newprog: newprog, cursym: cursym, autosize: int32(p.To.Offset + ctxt.Arch.FixedFrameSize)}
422
423 if oprange[AOR&obj.AMask] == nil {
424 c.ctxt.Diag("mips ops not initialized, call mips.buildop first")
425 }
426
427 pc := int64(0)
428 p.Pc = pc
429
430 var m int
431 var o *Optab
432 for p = p.Link; p != nil; p = p.Link {
433 p.Pc = pc
434 o = c.oplook(p)
435 m = int(o.size)
436 if m == 0 {
437 if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA {
438 c.ctxt.Diag("zero-width instruction\n%v", p)
439 }
440 continue
441 }
442
443 pc += int64(m)
444 }
445
446 c.cursym.Size = pc
447
448
454 bflag := 1
455
456 var otxt int64
457 var q *obj.Prog
458 for bflag != 0 {
459 bflag = 0
460 pc = 0
461 for p = c.cursym.Func().Text.Link; p != nil; p = p.Link {
462 p.Pc = pc
463 o = c.oplook(p)
464
465
466 if o.type_ == 6 && p.To.Target() != nil {
467 otxt = p.To.Target().Pc - pc
468 if otxt < -(1<<17)+10 || otxt >= (1<<17)-10 {
469 q = c.newprog()
470 q.Link = p.Link
471 p.Link = q
472 q.As = AJMP
473 q.Pos = p.Pos
474 q.To.Type = obj.TYPE_BRANCH
475 q.To.SetTarget(p.To.Target())
476 p.To.SetTarget(q)
477 q = c.newprog()
478 q.Link = p.Link
479 p.Link = q
480 q.As = AJMP
481 q.Pos = p.Pos
482 q.To.Type = obj.TYPE_BRANCH
483 q.To.SetTarget(q.Link.Link)
484
485 c.addnop(p.Link)
486 c.addnop(p)
487 bflag = 1
488 }
489 }
490
491 m = int(o.size)
492 if m == 0 {
493 if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA {
494 c.ctxt.Diag("zero-width instruction\n%v", p)
495 }
496 continue
497 }
498
499 pc += int64(m)
500 }
501
502 c.cursym.Size = pc
503 }
504 if c.ctxt.Arch.Family == sys.MIPS64 {
505 pc += -pc & (mips64FuncAlign - 1)
506 }
507 c.cursym.Size = pc
508
509
512
513 c.cursym.Grow(c.cursym.Size)
514
515 bp := c.cursym.P
516 var i int32
517 var out [4]uint32
518 for p := c.cursym.Func().Text.Link; p != nil; p = p.Link {
519 c.pc = p.Pc
520 o = c.oplook(p)
521 if int(o.size) > 4*len(out) {
522 log.Fatalf("out array in span0 is too small, need at least %d for %v", o.size/4, p)
523 }
524 c.asmout(p, o, out[:])
525 for i = 0; i < int32(o.size/4); i++ {
526 c.ctxt.Arch.ByteOrder.PutUint32(bp, out[i])
527 bp = bp[4:]
528 }
529 }
530
531
532
533
534
535 obj.MarkUnsafePoints(c.ctxt, c.cursym.Func().Text, c.newprog, c.isUnsafePoint, c.isRestartable)
536 }
537
538
539 func (c *ctxt0) isUnsafePoint(p *obj.Prog) bool {
540
541
542 return p.From.Reg == REGTMP || p.To.Reg == REGTMP || p.Reg == REGTMP
543 }
544
545
546
547 func (c *ctxt0) isRestartable(p *obj.Prog) bool {
548 if c.isUnsafePoint(p) {
549 return false
550 }
551
552
553
554
555
556
557
558 o := c.oplook(p)
559 return o.size > 4 && o.flag&NOTUSETMP == 0
560 }
561
562 func isint32(v int64) bool {
563 return int64(int32(v)) == v
564 }
565
566 func isuint32(v uint64) bool {
567 return uint64(uint32(v)) == v
568 }
569
570 func (c *ctxt0) aclass(a *obj.Addr) int {
571 switch a.Type {
572 case obj.TYPE_NONE:
573 return C_NONE
574
575 case obj.TYPE_REG:
576 if REG_R0 <= a.Reg && a.Reg <= REG_R31 {
577 return C_REG
578 }
579 if REG_F0 <= a.Reg && a.Reg <= REG_F31 {
580 return C_FREG
581 }
582 if REG_M0 <= a.Reg && a.Reg <= REG_M31 {
583 return C_MREG
584 }
585 if REG_FCR0 <= a.Reg && a.Reg <= REG_FCR31 {
586 return C_FCREG
587 }
588 if REG_W0 <= a.Reg && a.Reg <= REG_W31 {
589 return C_WREG
590 }
591 if a.Reg == REG_LO {
592 return C_LO
593 }
594 if a.Reg == REG_HI {
595 return C_HI
596 }
597 return C_GOK
598
599 case obj.TYPE_MEM:
600 switch a.Name {
601 case obj.NAME_EXTERN,
602 obj.NAME_STATIC:
603 if a.Sym == nil {
604 break
605 }
606 c.instoffset = a.Offset
607 if a.Sym != nil {
608 if a.Sym.Type == objabi.STLSBSS {
609 return C_TLS
610 }
611 return C_ADDR
612 }
613 return C_LEXT
614
615 case obj.NAME_AUTO:
616 if a.Reg == REGSP {
617
618
619 a.Reg = obj.REG_NONE
620 }
621 c.instoffset = int64(c.autosize) + a.Offset
622 if c.instoffset >= -BIG && c.instoffset < BIG {
623 return C_SAUTO
624 }
625 return C_LAUTO
626
627 case obj.NAME_PARAM:
628 if a.Reg == REGSP {
629
630
631 a.Reg = obj.REG_NONE
632 }
633 c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.Arch.FixedFrameSize
634 if c.instoffset >= -BIG && c.instoffset < BIG {
635 return C_SAUTO
636 }
637 return C_LAUTO
638
639 case obj.NAME_NONE:
640 c.instoffset = a.Offset
641 if c.instoffset == 0 {
642 return C_ZOREG
643 }
644 if c.instoffset >= -BIG && c.instoffset < BIG {
645 return C_SOREG
646 }
647 return C_LOREG
648 }
649
650 return C_GOK
651
652 case obj.TYPE_TEXTSIZE:
653 return C_TEXTSIZE
654
655 case obj.TYPE_CONST,
656 obj.TYPE_ADDR:
657 switch a.Name {
658 case obj.NAME_NONE:
659 c.instoffset = a.Offset
660 if a.Reg != obj.REG_NONE {
661 if -BIG <= c.instoffset && c.instoffset <= BIG {
662 return C_SACON
663 }
664 if isint32(c.instoffset) {
665 return C_LACON
666 }
667 return C_DACON
668 }
669
670 case obj.NAME_EXTERN,
671 obj.NAME_STATIC:
672 s := a.Sym
673 if s == nil {
674 return C_GOK
675 }
676
677 c.instoffset = a.Offset
678 if s.Type == objabi.STLSBSS {
679 return C_STCON
680 }
681 return C_LECON
682
683 case obj.NAME_AUTO:
684 if a.Reg == REGSP {
685
686
687 a.Reg = obj.REG_NONE
688 }
689 c.instoffset = int64(c.autosize) + a.Offset
690 if c.instoffset >= -BIG && c.instoffset < BIG {
691 return C_SACON
692 }
693 return C_LACON
694
695 case obj.NAME_PARAM:
696 if a.Reg == REGSP {
697
698
699 a.Reg = obj.REG_NONE
700 }
701 c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.Arch.FixedFrameSize
702 if c.instoffset >= -BIG && c.instoffset < BIG {
703 return C_SACON
704 }
705 return C_LACON
706
707 default:
708 return C_GOK
709 }
710
711 if c.instoffset >= 0 {
712 if c.instoffset == 0 {
713 return C_ZCON
714 }
715 if c.instoffset <= 0x7fff {
716 return C_SCON
717 }
718 if c.instoffset <= 0xffff {
719 return C_ANDCON
720 }
721 if c.instoffset&0xffff == 0 && isuint32(uint64(c.instoffset)) {
722 return C_UCON
723 }
724 if isint32(c.instoffset) || isuint32(uint64(c.instoffset)) {
725 return C_LCON
726 }
727 return C_LCON
728 }
729
730 if c.instoffset >= -0x8000 {
731 return C_ADDCON
732 }
733 if c.instoffset&0xffff == 0 && isint32(c.instoffset) {
734 return C_UCON
735 }
736 if isint32(c.instoffset) {
737 return C_LCON
738 }
739 return C_LCON
740
741 case obj.TYPE_BRANCH:
742 return C_SBRA
743 }
744
745 return C_GOK
746 }
747
748 func prasm(p *obj.Prog) {
749 fmt.Printf("%v\n", p)
750 }
751
752 func (c *ctxt0) oplook(p *obj.Prog) *Optab {
753 if oprange[AOR&obj.AMask] == nil {
754 c.ctxt.Diag("mips ops not initialized, call mips.buildop first")
755 }
756
757 a1 := int(p.Optab)
758 if a1 != 0 {
759 return &optab[a1-1]
760 }
761 a1 = int(p.From.Class)
762 if a1 == 0 {
763 a1 = c.aclass(&p.From) + 1
764 p.From.Class = int8(a1)
765 }
766
767 a1--
768 a3 := int(p.To.Class)
769 if a3 == 0 {
770 a3 = c.aclass(&p.To) + 1
771 p.To.Class = int8(a3)
772 }
773
774 a3--
775 a2 := C_NONE
776 if p.Reg != obj.REG_NONE {
777 a2 = C_REG
778 }
779
780 ops := oprange[p.As&obj.AMask]
781 c1 := &xcmp[a1]
782 c3 := &xcmp[a3]
783 for i := range ops {
784 op := &ops[i]
785 if int(op.a2) == a2 && c1[op.a1] && c3[op.a3] && (op.family == 0 || c.ctxt.Arch.Family == op.family) {
786 p.Optab = uint16(cap(optab) - cap(ops) + i + 1)
787 return op
788 }
789 }
790
791 c.ctxt.Diag("illegal combination %v %v %v %v", p.As, DRconv(a1), DRconv(a2), DRconv(a3))
792 prasm(p)
793
794 return &Optab{obj.AUNDEF, C_NONE, C_NONE, C_NONE, 49, 4, 0, 0, 0}
795 }
796
797 func cmp(a int, b int) bool {
798 if a == b {
799 return true
800 }
801 switch a {
802 case C_LCON:
803 if b == C_ZCON || b == C_SCON || b == C_UCON || b == C_ADDCON || b == C_ANDCON {
804 return true
805 }
806
807 case C_ADD0CON:
808 if b == C_ADDCON {
809 return true
810 }
811 fallthrough
812
813 case C_ADDCON:
814 if b == C_ZCON || b == C_SCON {
815 return true
816 }
817
818 case C_AND0CON:
819 if b == C_ANDCON {
820 return true
821 }
822 fallthrough
823
824 case C_ANDCON:
825 if b == C_ZCON || b == C_SCON {
826 return true
827 }
828
829 case C_UCON:
830 if b == C_ZCON {
831 return true
832 }
833
834 case C_SCON:
835 if b == C_ZCON {
836 return true
837 }
838
839 case C_LACON:
840 if b == C_SACON {
841 return true
842 }
843
844 case C_LBRA:
845 if b == C_SBRA {
846 return true
847 }
848
849 case C_LEXT:
850 if b == C_SEXT {
851 return true
852 }
853
854 case C_LAUTO:
855 if b == C_SAUTO {
856 return true
857 }
858
859 case C_REG:
860 if b == C_ZCON {
861 return r0iszero != 0
862 }
863
864 case C_LOREG:
865 if b == C_ZOREG || b == C_SOREG {
866 return true
867 }
868
869 case C_SOREG:
870 if b == C_ZOREG {
871 return true
872 }
873 }
874
875 return false
876 }
877
878 func ocmp(p1, p2 Optab) int {
879 if p1.as != p2.as {
880 return int(p1.as) - int(p2.as)
881 }
882 if p1.a1 != p2.a1 {
883 return int(p1.a1) - int(p2.a1)
884 }
885 if p1.a2 != p2.a2 {
886 return int(p1.a2) - int(p2.a2)
887 }
888 if p1.a3 != p2.a3 {
889 return int(p1.a3) - int(p2.a3)
890 }
891 return 0
892 }
893
894 func opset(a, b0 obj.As) {
895 oprange[a&obj.AMask] = oprange[b0]
896 }
897
898 func buildop(ctxt *obj.Link) {
899 if oprange[AOR&obj.AMask] != nil {
900
901
902
903 return
904 }
905
906 var n int
907
908 for i := 0; i < C_NCLASS; i++ {
909 for n = 0; n < C_NCLASS; n++ {
910 if cmp(n, i) {
911 xcmp[i][n] = true
912 }
913 }
914 }
915 for n = 0; optab[n].as != obj.AXXX; n++ {
916 }
917 slices.SortFunc(optab[:n], ocmp)
918 for i := 0; i < n; i++ {
919 r := optab[i].as
920 r0 := r & obj.AMask
921 start := i
922 for optab[i].as == r {
923 i++
924 }
925 oprange[r0] = optab[start:i]
926 i--
927
928 switch r {
929 default:
930 ctxt.Diag("unknown op in build: %v", r)
931 ctxt.DiagFlush()
932 log.Fatalf("bad code")
933
934 case AABSF:
935 opset(AMOVFD, r0)
936 opset(AMOVDF, r0)
937 opset(AMOVWF, r0)
938 opset(AMOVFW, r0)
939 opset(AMOVWD, r0)
940 opset(AMOVDW, r0)
941 opset(ANEGF, r0)
942 opset(ANEGD, r0)
943 opset(AABSD, r0)
944 opset(ATRUNCDW, r0)
945 opset(ATRUNCFW, r0)
946 opset(ASQRTF, r0)
947 opset(ASQRTD, r0)
948
949 case AMOVVF:
950 opset(AMOVVD, r0)
951 opset(AMOVFV, r0)
952 opset(AMOVDV, r0)
953 opset(ATRUNCDV, r0)
954 opset(ATRUNCFV, r0)
955
956 case AADD:
957 opset(ASGT, r0)
958 opset(ASGTU, r0)
959 opset(AADDU, r0)
960
961 case AADDV:
962 opset(AADDVU, r0)
963
964 case AADDF:
965 opset(ADIVF, r0)
966 opset(ADIVD, r0)
967 opset(AMULF, r0)
968 opset(AMULD, r0)
969 opset(ASUBF, r0)
970 opset(ASUBD, r0)
971 opset(AADDD, r0)
972
973 case AAND:
974 opset(AOR, r0)
975 opset(AXOR, r0)
976
977 case ABEQ:
978 opset(ABNE, r0)
979
980 case ABLEZ:
981 opset(ABGEZ, r0)
982 opset(ABGEZAL, r0)
983 opset(ABLTZ, r0)
984 opset(ABLTZAL, r0)
985 opset(ABGTZ, r0)
986
987 case AMOVB:
988 opset(AMOVH, r0)
989
990 case AMOVBU:
991 opset(AMOVHU, r0)
992
993 case AMUL:
994 opset(AREM, r0)
995 opset(AREMU, r0)
996 opset(ADIVU, r0)
997 opset(AMULU, r0)
998 opset(ADIV, r0)
999 opset(AMADD, r0)
1000 opset(AMSUB, r0)
1001
1002 case AMULV:
1003 opset(ADIVV, r0)
1004 opset(ADIVVU, r0)
1005 opset(AMULVU, r0)
1006 opset(AREMV, r0)
1007 opset(AREMVU, r0)
1008
1009 case ASLL:
1010 opset(ASRL, r0)
1011 opset(ASRA, r0)
1012 opset(AROTR, r0)
1013
1014 case ASLLV:
1015 opset(ASRAV, r0)
1016 opset(ASRLV, r0)
1017 opset(AROTRV, r0)
1018
1019 case ASUB:
1020 opset(ASUBU, r0)
1021 opset(ANOR, r0)
1022
1023 case ASUBV:
1024 opset(ASUBVU, r0)
1025
1026 case ASYSCALL:
1027 opset(ASYNC, r0)
1028 opset(ANOOP, r0)
1029 opset(ATLBP, r0)
1030 opset(ATLBR, r0)
1031 opset(ATLBWI, r0)
1032 opset(ATLBWR, r0)
1033
1034 case ACMPEQF:
1035 opset(ACMPGTF, r0)
1036 opset(ACMPGTD, r0)
1037 opset(ACMPGEF, r0)
1038 opset(ACMPGED, r0)
1039 opset(ACMPEQD, r0)
1040
1041 case ABFPT:
1042 opset(ABFPF, r0)
1043
1044 case AMOVWL:
1045 opset(AMOVWR, r0)
1046
1047 case AMOVVL:
1048 opset(AMOVVR, r0)
1049
1050 case AVMOVB:
1051 opset(AVMOVH, r0)
1052 opset(AVMOVW, r0)
1053 opset(AVMOVD, r0)
1054
1055 case AMOVW,
1056 AMOVD,
1057 AMOVF,
1058 AMOVV,
1059 ABREAK,
1060 ARFE,
1061 AJAL,
1062 AJMP,
1063 AMOVWU,
1064 ALL,
1065 ALLV,
1066 ASC,
1067 ASCV,
1068 ANEGW,
1069 ANEGV,
1070 AWORD,
1071 obj.ANOP,
1072 obj.ATEXT,
1073 obj.AUNDEF,
1074 obj.AFUNCDATA,
1075 obj.APCDATA,
1076 obj.ADUFFZERO,
1077 obj.ADUFFCOPY:
1078 break
1079
1080 case ACMOVN:
1081 opset(ACMOVZ, r0)
1082
1083 case ACMOVT:
1084 opset(ACMOVF, r0)
1085
1086 case ACLO:
1087 opset(ACLZ, r0)
1088
1089 case ATEQ:
1090 opset(ATNE, r0)
1091
1092 case AWSBH:
1093 opset(ASEB, r0)
1094 opset(ASEH, r0)
1095
1096 case ADSBH:
1097 opset(ADSHD, r0)
1098 }
1099 }
1100 }
1101
1102 func OP(x uint32, y uint32) uint32 {
1103 return x<<3 | y<<0
1104 }
1105
1106 func SP(x uint32, y uint32) uint32 {
1107 return x<<29 | y<<26
1108 }
1109
1110 func BCOND(x uint32, y uint32) uint32 {
1111 return x<<19 | y<<16
1112 }
1113
1114 func MMU(x uint32, y uint32) uint32 {
1115 return SP(2, 0) | 16<<21 | x<<3 | y<<0
1116 }
1117
1118 func FPF(x uint32, y uint32) uint32 {
1119 return SP(2, 1) | 16<<21 | x<<3 | y<<0
1120 }
1121
1122 func FPD(x uint32, y uint32) uint32 {
1123 return SP(2, 1) | 17<<21 | x<<3 | y<<0
1124 }
1125
1126 func FPW(x uint32, y uint32) uint32 {
1127 return SP(2, 1) | 20<<21 | x<<3 | y<<0
1128 }
1129
1130 func FPV(x uint32, y uint32) uint32 {
1131 return SP(2, 1) | 21<<21 | x<<3 | y<<0
1132 }
1133
1134 func OP_RRR(op uint32, r1 int16, r2 int16, r3 int16) uint32 {
1135 return op | uint32(r1&31)<<16 | uint32(r2&31)<<21 | uint32(r3&31)<<11
1136 }
1137
1138 func OP_IRR(op uint32, i uint32, r2 int16, r3 int16) uint32 {
1139 return op | i&0xFFFF | uint32(r2&31)<<21 | uint32(r3&31)<<16
1140 }
1141
1142 func OP_SRR(op uint32, s uint32, r2 int16, r3 int16) uint32 {
1143 return op | (s&31)<<6 | uint32(r2&31)<<16 | uint32(r3&31)<<11
1144 }
1145
1146 func OP_FRRR(op uint32, r1 int16, r2 int16, r3 int16) uint32 {
1147 return op | uint32(r1&31)<<16 | uint32(r2&31)<<11 | uint32(r3&31)<<6
1148 }
1149
1150 func OP_JMP(op uint32, i uint32) uint32 {
1151 return op | i&0x3FFFFFF
1152 }
1153
1154 func OP_VI10(op uint32, df uint32, s10 int32, wd uint32, minor uint32) uint32 {
1155 return 0x1e<<26 | (op&7)<<23 | (df&3)<<21 | uint32(s10&0x3FF)<<11 | (wd&31)<<6 | minor&0x3F
1156 }
1157
1158 func OP_VMI10(s10 int32, rs uint32, wd uint32, minor uint32, df uint32) uint32 {
1159 return 0x1e<<26 | uint32(s10&0x3FF)<<16 | (rs&31)<<11 | (wd&31)<<6 | (minor&15)<<2 | df&3
1160 }
1161
1162 func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
1163 o1 := uint32(0)
1164 o2 := uint32(0)
1165 o3 := uint32(0)
1166 o4 := uint32(0)
1167
1168 add := AADDU
1169
1170 if c.ctxt.Arch.Family == sys.MIPS64 {
1171 add = AADDVU
1172 }
1173 switch o.type_ {
1174 default:
1175 c.ctxt.Diag("unknown type %d", o.type_)
1176 prasm(p)
1177
1178 case 0:
1179 break
1180
1181 case 1:
1182 a := AOR
1183 if p.As == AMOVW && c.ctxt.Arch.Family == sys.MIPS64 {
1184
1185
1186 a = ASLL
1187 }
1188 o1 = OP_RRR(c.oprrr(a), p.From.Reg, REGZERO, p.To.Reg)
1189
1190 case 2:
1191 r := p.Reg
1192 if p.As == ANEGW || p.As == ANEGV {
1193 r = REGZERO
1194 }
1195 if r == obj.REG_NONE {
1196 r = p.To.Reg
1197 }
1198 o1 = OP_RRR(c.oprrr(p.As), p.From.Reg, r, p.To.Reg)
1199
1200 case 3:
1201 a := add
1202 if o.a1 == C_ANDCON {
1203 a = AOR
1204 }
1205 r := p.From.Reg
1206 if r == obj.REG_NONE {
1207 r = o.param
1208 }
1209 v := c.regoff(&p.From)
1210 o1 = OP_IRR(c.opirr(a), uint32(v), r, p.To.Reg)
1211
1212 case 4:
1213 r := p.Reg
1214 if r == obj.REG_NONE {
1215 r = p.To.Reg
1216 }
1217 v := c.regoff(&p.From)
1218 o1 = OP_IRR(c.opirr(p.As), uint32(v), r, p.To.Reg)
1219
1220 case 5:
1221 o1 = c.oprrr(p.As)
1222
1223 case 6:
1224 v := int32(0)
1225 if p.To.Target() == nil {
1226 v = int32(-4) >> 2
1227 } else {
1228 v = int32(p.To.Target().Pc-p.Pc-4) >> 2
1229 }
1230 if (v<<16)>>16 != v {
1231 c.ctxt.Diag("short branch too far\n%v", p)
1232 }
1233 o1 = OP_IRR(c.opirr(p.As), uint32(v), p.From.Reg, p.Reg)
1234
1235
1236 o2 = 0
1237
1238 case 7:
1239 r := p.To.Reg
1240 if r == obj.REG_NONE {
1241 r = o.param
1242 }
1243 v := c.regoff(&p.To)
1244 o1 = OP_IRR(c.opirr(p.As), uint32(v), r, p.From.Reg)
1245
1246 case 8:
1247 r := p.From.Reg
1248 if r == obj.REG_NONE {
1249 r = o.param
1250 }
1251 v := c.regoff(&p.From)
1252 o1 = OP_IRR(c.opirr(-p.As), uint32(v), r, p.To.Reg)
1253
1254 case 9:
1255 r := p.Reg
1256 if r == obj.REG_NONE {
1257 r = p.To.Reg
1258 }
1259 o1 = OP_RRR(c.oprrr(p.As), r, p.From.Reg, p.To.Reg)
1260
1261 case 10:
1262 v := c.regoff(&p.From)
1263 a := AOR
1264 if v < 0 {
1265 a = AADDU
1266 }
1267 o1 = OP_IRR(c.opirr(a), uint32(v), obj.REG_NONE, REGTMP)
1268 r := p.Reg
1269 if r == obj.REG_NONE {
1270 r = p.To.Reg
1271 }
1272 o2 = OP_RRR(c.oprrr(p.As), REGTMP, r, p.To.Reg)
1273
1274 case 11:
1275 v := int32(0)
1276 if c.aclass(&p.To) == C_SBRA && p.To.Sym == nil && p.As == AJMP {
1277
1278
1279 if p.To.Target() == nil {
1280 v = int32(-4) >> 2
1281 } else {
1282 v = int32(p.To.Target().Pc-p.Pc-4) >> 2
1283 }
1284 if (v<<16)>>16 == v {
1285 o1 = OP_IRR(c.opirr(ABEQ), uint32(v), REGZERO, REGZERO)
1286 break
1287 }
1288 }
1289 if p.To.Target() == nil {
1290 v = int32(p.Pc) >> 2
1291 } else {
1292 v = int32(p.To.Target().Pc) >> 2
1293 }
1294 o1 = OP_JMP(c.opirr(p.As), uint32(v))
1295 if p.To.Sym == nil {
1296 p.To.Sym = c.cursym.Func().Text.From.Sym
1297 p.To.Offset = p.To.Target().Pc
1298 }
1299 typ := objabi.R_JMPMIPS
1300 if p.As == AJAL {
1301 typ = objabi.R_CALLMIPS
1302 }
1303 c.cursym.AddRel(c.ctxt, obj.Reloc{
1304 Type: typ,
1305 Off: int32(c.pc),
1306 Siz: 4,
1307 Sym: p.To.Sym,
1308 Add: p.To.Offset,
1309 })
1310
1311 case 12:
1312
1313
1314 v := 16
1315 if p.As == AMOVB {
1316 v = 24
1317 }
1318 o1 = OP_SRR(c.opirr(ASLL), uint32(v), p.From.Reg, p.To.Reg)
1319 o2 = OP_SRR(c.opirr(ASRA), uint32(v), p.To.Reg, p.To.Reg)
1320
1321 case 13:
1322 if p.As == AMOVBU {
1323 o1 = OP_IRR(c.opirr(AAND), uint32(0xff), p.From.Reg, p.To.Reg)
1324 } else {
1325 o1 = OP_IRR(c.opirr(AAND), uint32(0xffff), p.From.Reg, p.To.Reg)
1326 }
1327
1328 case 14:
1329
1330
1331 o1 = OP_SRR(c.opirr(-ASLLV), 0, p.From.Reg, p.To.Reg)
1332 o2 = OP_SRR(c.opirr(-ASRLV), 0, p.To.Reg, p.To.Reg)
1333
1334 case 15:
1335 r := p.Reg
1336 if r == obj.REG_NONE {
1337 r = REGZERO
1338 }
1339 v := c.regoff(&p.From)
1340
1341 o1 = OP_IRR(c.opirr(p.As), (uint32(v)&0x3FF)<<6, r, p.To.Reg)
1342
1343 case 16:
1344 r := p.Reg
1345 if r == obj.REG_NONE {
1346 r = p.To.Reg
1347 }
1348 v := c.regoff(&p.From)
1349
1350
1351 if v >= 32 && vshift(p.As) {
1352 o1 = OP_SRR(c.opirr(-p.As), uint32(v-32), r, p.To.Reg)
1353 } else {
1354 o1 = OP_SRR(c.opirr(p.As), uint32(v), r, p.To.Reg)
1355 }
1356
1357 case 17:
1358 o1 = OP_RRR(c.oprrr(p.As), REGZERO, p.From.Reg, p.To.Reg)
1359
1360 case 18:
1361 r := p.Reg
1362 if r == obj.REG_NONE {
1363 r = o.param
1364 }
1365 o1 = OP_RRR(c.oprrr(p.As), obj.REG_NONE, p.To.Reg, r)
1366 if p.As == obj.ACALL {
1367 c.cursym.AddRel(c.ctxt, obj.Reloc{
1368 Type: objabi.R_CALLIND,
1369 Off: int32(c.pc),
1370 })
1371 }
1372
1373 case 19:
1374
1375
1376 v := c.regoff(&p.From)
1377 o1 = OP_IRR(c.opirr(ALUI), uint32(v>>16), REGZERO, p.To.Reg)
1378 o2 = OP_IRR(c.opirr(AOR), uint32(v), p.To.Reg, p.To.Reg)
1379
1380 case 20:
1381 a := OP(2, 0)
1382 if p.From.Reg == REG_LO {
1383 a = OP(2, 2)
1384 }
1385 o1 = OP_RRR(a, REGZERO, REGZERO, p.To.Reg)
1386
1387 case 21:
1388 a := OP(2, 1)
1389 if p.To.Reg == REG_LO {
1390 a = OP(2, 3)
1391 }
1392 o1 = OP_RRR(a, REGZERO, p.From.Reg, REGZERO)
1393
1394 case 22:
1395 if p.To.Reg != obj.REG_NONE {
1396 r := p.Reg
1397 if r == obj.REG_NONE {
1398 r = p.To.Reg
1399 }
1400 a := SP(3, 4) | 2
1401 o1 = OP_RRR(a, p.From.Reg, r, p.To.Reg)
1402 } else {
1403 o1 = OP_RRR(c.oprrr(p.As), p.From.Reg, p.Reg, REGZERO)
1404 }
1405
1406 case 23:
1407 v := c.regoff(&p.From)
1408 o1 = OP_IRR(c.opirr(ALUI), uint32(v>>16), REGZERO, REGTMP)
1409 o2 = OP_IRR(c.opirr(AOR), uint32(v), REGTMP, REGTMP)
1410 r := p.Reg
1411 if r == obj.REG_NONE {
1412 r = p.To.Reg
1413 }
1414 o3 = OP_RRR(c.oprrr(p.As), REGTMP, r, p.To.Reg)
1415
1416 case 24:
1417 v := c.regoff(&p.From)
1418 o1 = OP_IRR(c.opirr(ALUI), uint32(v>>16), REGZERO, p.To.Reg)
1419
1420 case 25:
1421 v := c.regoff(&p.From)
1422 o1 = OP_IRR(c.opirr(ALUI), uint32(v>>16), REGZERO, REGTMP)
1423 r := p.Reg
1424 if r == obj.REG_NONE {
1425 r = p.To.Reg
1426 }
1427 o2 = OP_RRR(c.oprrr(p.As), REGTMP, r, p.To.Reg)
1428
1429 case 26:
1430 v := c.regoff(&p.From)
1431 o1 = OP_IRR(c.opirr(ALUI), uint32(v>>16), REGZERO, REGTMP)
1432 o2 = OP_IRR(c.opirr(AOR), uint32(v), REGTMP, REGTMP)
1433 r := p.From.Reg
1434 if r == obj.REG_NONE {
1435 r = o.param
1436 }
1437 o3 = OP_RRR(c.oprrr(add), REGTMP, r, p.To.Reg)
1438
1439 case 27:
1440 a := -AMOVF
1441 if p.As == AMOVD {
1442 a = -AMOVD
1443 }
1444 r := p.From.Reg
1445 if r == obj.REG_NONE {
1446 r = o.param
1447 }
1448 v := c.regoff(&p.From)
1449 switch o.size {
1450 case 12:
1451 o1 = OP_IRR(c.opirr(ALUI), uint32((v+1<<15)>>16), REGZERO, REGTMP)
1452 o2 = OP_RRR(c.oprrr(add), r, REGTMP, REGTMP)
1453 o3 = OP_IRR(c.opirr(a), uint32(v), REGTMP, p.To.Reg)
1454
1455 case 4:
1456 o1 = OP_IRR(c.opirr(a), uint32(v), r, p.To.Reg)
1457 }
1458
1459 case 28:
1460 a := AMOVF
1461 if p.As == AMOVD {
1462 a = AMOVD
1463 }
1464 r := p.To.Reg
1465 if r == obj.REG_NONE {
1466 r = o.param
1467 }
1468 v := c.regoff(&p.To)
1469 switch o.size {
1470 case 12:
1471 o1 = OP_IRR(c.opirr(ALUI), uint32((v+1<<15)>>16), REGZERO, REGTMP)
1472 o2 = OP_RRR(c.oprrr(add), r, REGTMP, REGTMP)
1473 o3 = OP_IRR(c.opirr(a), uint32(v), REGTMP, p.From.Reg)
1474
1475 case 4:
1476 o1 = OP_IRR(c.opirr(a), uint32(v), r, p.From.Reg)
1477 }
1478
1479 case 30:
1480 a := SP(2, 1) | (4 << 21)
1481 o1 = OP_RRR(a, p.From.Reg, obj.REG_NONE, p.To.Reg)
1482
1483 case 31:
1484 a := SP(2, 1) | (0 << 21)
1485 o1 = OP_RRR(a, p.To.Reg, obj.REG_NONE, p.From.Reg)
1486
1487 case 32:
1488 r := p.Reg
1489 if r == obj.REG_NONE {
1490 r = p.To.Reg
1491 }
1492 o1 = OP_FRRR(c.oprrr(p.As), p.From.Reg, r, p.To.Reg)
1493
1494 case 33:
1495 o1 = OP_FRRR(c.oprrr(p.As), obj.REG_NONE, p.From.Reg, p.To.Reg)
1496
1497 case 34:
1498 a := AADDU
1499 if o.a1 == C_ANDCON {
1500 a = AOR
1501 }
1502 v := c.regoff(&p.From)
1503 o1 = OP_IRR(c.opirr(a), uint32(v), obj.REG_NONE, REGTMP)
1504 o2 = OP_RRR(SP(2, 1)|(4<<21), REGTMP, obj.REG_NONE, p.To.Reg)
1505
1506 case 35:
1507 r := p.To.Reg
1508 if r == obj.REG_NONE {
1509 r = o.param
1510 }
1511 if p.From.Reg == REGTMP {
1512 c.ctxt.Diag("cannot store REGTMP to large offset (REGTMP needed for address materialization): %v", p)
1513 }
1514 v := c.regoff(&p.To)
1515 o1 = OP_IRR(c.opirr(ALUI), uint32((v+1<<15)>>16), REGZERO, REGTMP)
1516 o2 = OP_RRR(c.oprrr(add), r, REGTMP, REGTMP)
1517 o3 = OP_IRR(c.opirr(p.As), uint32(v), REGTMP, p.From.Reg)
1518
1519 case 36:
1520 r := p.From.Reg
1521 if r == obj.REG_NONE {
1522 r = o.param
1523 }
1524 v := c.regoff(&p.From)
1525 o1 = OP_IRR(c.opirr(ALUI), uint32((v+1<<15)>>16), REGZERO, REGTMP)
1526 o2 = OP_RRR(c.oprrr(add), r, REGTMP, REGTMP)
1527 o3 = OP_IRR(c.opirr(-p.As), uint32(v), REGTMP, p.To.Reg)
1528
1529 case 37:
1530 a := SP(2, 0) | (4 << 21)
1531 if p.As == AMOVV {
1532 a = SP(2, 0) | (5 << 21)
1533 }
1534 o1 = OP_RRR(a, p.From.Reg, obj.REG_NONE, p.To.Reg)
1535
1536 case 38:
1537 a := SP(2, 0) | (0 << 21)
1538 if p.As == AMOVV {
1539 a = SP(2, 0) | (1 << 21)
1540 }
1541 o1 = OP_RRR(a, p.To.Reg, obj.REG_NONE, p.From.Reg)
1542
1543 case 40:
1544 o1 = uint32(c.regoff(&p.From))
1545
1546 case 41:
1547 o1 = OP_RRR(SP(2, 1)|(6<<21), p.From.Reg, obj.REG_NONE, p.To.Reg)
1548
1549 case 42:
1550 o1 = OP_RRR(SP(2, 1)|(2<<21), p.To.Reg, obj.REG_NONE, p.From.Reg)
1551
1552 case 47:
1553 a := SP(2, 1) | (5 << 21)
1554 o1 = OP_RRR(a, p.From.Reg, obj.REG_NONE, p.To.Reg)
1555
1556 case 48:
1557 a := SP(2, 1) | (1 << 21)
1558 o1 = OP_RRR(a, p.To.Reg, obj.REG_NONE, p.From.Reg)
1559
1560 case 49:
1561 o1 = 52
1562
1563
1564 case 50:
1565 o1 = OP_IRR(c.opirr(ALUI), 0, REGZERO, REGTMP)
1566 c.cursym.AddRel(c.ctxt, obj.Reloc{
1567 Type: objabi.R_ADDRMIPSU,
1568 Off: int32(c.pc),
1569 Siz: 4,
1570 Sym: p.To.Sym,
1571 Add: p.To.Offset,
1572 })
1573
1574 o2 = OP_IRR(c.opirr(p.As), 0, REGTMP, p.From.Reg)
1575 off := int32(c.pc + 4)
1576 if o.size == 12 {
1577 o3 = o2
1578 o2 = OP_RRR(c.oprrr(AADDVU), REGSB, REGTMP, REGTMP)
1579 off += 4
1580 }
1581 c.cursym.AddRel(c.ctxt, obj.Reloc{
1582 Type: objabi.R_ADDRMIPS,
1583 Off: off,
1584 Siz: 4,
1585 Sym: p.To.Sym,
1586 Add: p.To.Offset,
1587 })
1588
1589 case 51:
1590 o1 = OP_IRR(c.opirr(ALUI), 0, REGZERO, REGTMP)
1591 c.cursym.AddRel(c.ctxt, obj.Reloc{
1592 Type: objabi.R_ADDRMIPSU,
1593 Off: int32(c.pc),
1594 Siz: 4,
1595 Sym: p.From.Sym,
1596 Add: p.From.Offset,
1597 })
1598
1599 o2 = OP_IRR(c.opirr(-p.As), 0, REGTMP, p.To.Reg)
1600 off := int32(c.pc + 4)
1601 if o.size == 12 {
1602 o3 = o2
1603 o2 = OP_RRR(c.oprrr(AADDVU), REGSB, REGTMP, REGTMP)
1604 off += 4
1605 }
1606 c.cursym.AddRel(c.ctxt, obj.Reloc{
1607 Type: objabi.R_ADDRMIPS,
1608 Off: off,
1609 Siz: 4,
1610 Sym: p.From.Sym,
1611 Add: p.From.Offset,
1612 })
1613
1614 case 52:
1615
1616
1617 o1 = OP_IRR(c.opirr(ALUI), 0, REGZERO, p.To.Reg)
1618 c.cursym.AddRel(c.ctxt, obj.Reloc{
1619 Type: objabi.R_ADDRMIPSU,
1620 Off: int32(c.pc),
1621 Siz: 4,
1622 Sym: p.From.Sym,
1623 Add: p.From.Offset,
1624 })
1625
1626 o2 = OP_IRR(c.opirr(add), 0, p.To.Reg, p.To.Reg)
1627 off := int32(c.pc + 4)
1628 if o.size == 12 {
1629 o3 = o2
1630 o2 = OP_RRR(c.oprrr(AADDVU), REGSB, p.To.Reg, p.To.Reg)
1631 off += 4
1632 }
1633 c.cursym.AddRel(c.ctxt, obj.Reloc{
1634 Type: objabi.R_ADDRMIPS,
1635 Off: off,
1636 Siz: 4,
1637 Sym: p.From.Sym,
1638 Add: p.From.Offset,
1639 })
1640
1641 case 53:
1642
1643
1644
1645
1646 o1 = (037<<26 + 073) | (29 << 11) | (3 << 16)
1647 o2 = OP_IRR(c.opirr(p.As), 0, REG_R3, p.From.Reg)
1648 c.cursym.AddRel(c.ctxt, obj.Reloc{
1649 Type: objabi.R_ADDRMIPSTLS,
1650 Off: int32(c.pc + 4),
1651 Siz: 4,
1652 Sym: p.To.Sym,
1653 Add: p.To.Offset,
1654 })
1655
1656 case 54:
1657
1658
1659
1660 o1 = (037<<26 + 073) | (29 << 11) | (3 << 16)
1661 o2 = OP_IRR(c.opirr(-p.As), 0, REG_R3, p.To.Reg)
1662 c.cursym.AddRel(c.ctxt, obj.Reloc{
1663 Type: objabi.R_ADDRMIPSTLS,
1664 Off: int32(c.pc + 4),
1665 Siz: 4,
1666 Sym: p.From.Sym,
1667 Add: p.From.Offset,
1668 })
1669
1670 case 55:
1671
1672
1673
1674 o1 = (037<<26 + 073) | (29 << 11) | (3 << 16)
1675 o2 = OP_IRR(c.opirr(add), 0, REG_R3, p.To.Reg)
1676 c.cursym.AddRel(c.ctxt, obj.Reloc{
1677 Type: objabi.R_ADDRMIPSTLS,
1678 Off: int32(c.pc + 4),
1679 Siz: 4,
1680 Sym: p.From.Sym,
1681 Add: p.From.Offset,
1682 })
1683
1684 case 56:
1685
1686 v := c.regoff(&p.From)
1687 o1 = OP_VI10(110, c.twobitdf(p.As), v, uint32(p.To.Reg), 7)
1688
1689 case 57:
1690 v := c.lsoffset(p.As, c.regoff(&p.From))
1691 o1 = OP_VMI10(v, uint32(p.From.Reg), uint32(p.To.Reg), 8, c.twobitdf(p.As))
1692
1693 case 58:
1694 v := c.lsoffset(p.As, c.regoff(&p.To))
1695 o1 = OP_VMI10(v, uint32(p.To.Reg), uint32(p.From.Reg), 9, c.twobitdf(p.As))
1696
1697 case 59:
1698 o1 = OP_RRR(c.oprrr(p.As), p.From.Reg, REGZERO, p.To.Reg)
1699 }
1700
1701 out[0] = o1
1702 out[1] = o2
1703 out[2] = o3
1704 out[3] = o4
1705 }
1706
1707 func (c *ctxt0) vregoff(a *obj.Addr) int64 {
1708 c.instoffset = 0
1709 c.aclass(a)
1710 return c.instoffset
1711 }
1712
1713 func (c *ctxt0) regoff(a *obj.Addr) int32 {
1714 return int32(c.vregoff(a))
1715 }
1716
1717 func (c *ctxt0) oprrr(a obj.As) uint32 {
1718 switch a {
1719 case AADD:
1720 return OP(4, 0)
1721 case AADDU:
1722 return OP(4, 1)
1723 case ASGT:
1724 return OP(5, 2)
1725 case ASGTU:
1726 return OP(5, 3)
1727 case AAND:
1728 return OP(4, 4)
1729 case AOR:
1730 return OP(4, 5)
1731 case AXOR:
1732 return OP(4, 6)
1733 case ASUB:
1734 return OP(4, 2)
1735 case ASUBU, ANEGW:
1736 return OP(4, 3)
1737 case ANOR:
1738 return OP(4, 7)
1739 case ASLL:
1740 return OP(0, 4)
1741 case ASRL:
1742 return OP(0, 6)
1743 case ASRA:
1744 return OP(0, 7)
1745 case AROTR:
1746 return OP(8, 6)
1747 case ASLLV:
1748 return OP(2, 4)
1749 case ASRLV:
1750 return OP(2, 6)
1751 case ASRAV:
1752 return OP(2, 7)
1753 case AROTRV:
1754 return OP(10, 6)
1755 case AADDV:
1756 return OP(5, 4)
1757 case AADDVU:
1758 return OP(5, 5)
1759 case ASUBV:
1760 return OP(5, 6)
1761 case ASUBVU, ANEGV:
1762 return OP(5, 7)
1763 case AREM,
1764 ADIV:
1765 return OP(3, 2)
1766 case AREMU,
1767 ADIVU:
1768 return OP(3, 3)
1769 case AMUL:
1770 return OP(3, 0)
1771 case AMULU:
1772 return OP(3, 1)
1773 case AREMV,
1774 ADIVV:
1775 return OP(3, 6)
1776 case AREMVU,
1777 ADIVVU:
1778 return OP(3, 7)
1779 case AMULV:
1780 return OP(3, 4)
1781 case AMULVU:
1782 return OP(3, 5)
1783
1784 case AJMP:
1785 return OP(1, 0)
1786 case AJAL:
1787 return OP(1, 1)
1788
1789 case ABREAK:
1790 return OP(1, 5)
1791 case ASYSCALL:
1792 return OP(1, 4)
1793 case ATLBP:
1794 return MMU(1, 0)
1795 case ATLBR:
1796 return MMU(0, 1)
1797 case ATLBWI:
1798 return MMU(0, 2)
1799 case ATLBWR:
1800 return MMU(0, 6)
1801 case ARFE:
1802 return MMU(2, 0)
1803
1804 case ADIVF:
1805 return FPF(0, 3)
1806 case ADIVD:
1807 return FPD(0, 3)
1808 case AMULF:
1809 return FPF(0, 2)
1810 case AMULD:
1811 return FPD(0, 2)
1812 case ASUBF:
1813 return FPF(0, 1)
1814 case ASUBD:
1815 return FPD(0, 1)
1816 case AADDF:
1817 return FPF(0, 0)
1818 case AADDD:
1819 return FPD(0, 0)
1820 case ATRUNCFV:
1821 return FPF(1, 1)
1822 case ATRUNCDV:
1823 return FPD(1, 1)
1824 case ATRUNCFW:
1825 return FPF(1, 5)
1826 case ATRUNCDW:
1827 return FPD(1, 5)
1828 case AMOVFV:
1829 return FPF(4, 5)
1830 case AMOVDV:
1831 return FPD(4, 5)
1832 case AMOVVF:
1833 return FPV(4, 0)
1834 case AMOVVD:
1835 return FPV(4, 1)
1836 case AMOVFW:
1837 return FPF(4, 4)
1838 case AMOVDW:
1839 return FPD(4, 4)
1840 case AMOVWF:
1841 return FPW(4, 0)
1842 case AMOVDF:
1843 return FPD(4, 0)
1844 case AMOVWD:
1845 return FPW(4, 1)
1846 case AMOVFD:
1847 return FPF(4, 1)
1848 case AABSF:
1849 return FPF(0, 5)
1850 case AABSD:
1851 return FPD(0, 5)
1852 case AMOVF:
1853 return FPF(0, 6)
1854 case AMOVD:
1855 return FPD(0, 6)
1856 case ANEGF:
1857 return FPF(0, 7)
1858 case ANEGD:
1859 return FPD(0, 7)
1860 case ACMPEQF:
1861 return FPF(6, 2)
1862 case ACMPEQD:
1863 return FPD(6, 2)
1864 case ACMPGTF:
1865 return FPF(7, 4)
1866 case ACMPGTD:
1867 return FPD(7, 4)
1868 case ACMPGEF:
1869 return FPF(7, 6)
1870 case ACMPGED:
1871 return FPD(7, 6)
1872
1873 case ASQRTF:
1874 return FPF(0, 4)
1875 case ASQRTD:
1876 return FPD(0, 4)
1877
1878 case ASYNC:
1879 return OP(1, 7)
1880 case ANOOP:
1881 return 0
1882
1883 case ACMOVN:
1884 return OP(1, 3)
1885 case ACMOVZ:
1886 return OP(1, 2)
1887 case ACMOVT:
1888 return OP(0, 1) | (1 << 16)
1889 case ACMOVF:
1890 return OP(0, 1) | (0 << 16)
1891 case ACLO:
1892 return SP(3, 4) | OP(4, 1)
1893 case ACLZ:
1894 return SP(3, 4) | OP(4, 0)
1895 case AMADD:
1896 return SP(3, 4) | OP(0, 0)
1897 case AMSUB:
1898 return SP(3, 4) | OP(0, 4)
1899 case AWSBH:
1900 return SP(3, 7) | OP(20, 0)
1901 case ADSBH:
1902 return SP(3, 7) | OP(20, 4)
1903 case ADSHD:
1904 return SP(3, 7) | OP(44, 4)
1905 case ASEB:
1906 return SP(3, 7) | OP(132, 0)
1907 case ASEH:
1908 return SP(3, 7) | OP(196, 0)
1909 }
1910
1911 if a < 0 {
1912 c.ctxt.Diag("bad rrr opcode -%v", -a)
1913 } else {
1914 c.ctxt.Diag("bad rrr opcode %v", a)
1915 }
1916 return 0
1917 }
1918
1919 func (c *ctxt0) opirr(a obj.As) uint32 {
1920 switch a {
1921 case AADD:
1922 return SP(1, 0)
1923 case AADDU:
1924 return SP(1, 1)
1925 case ASGT:
1926 return SP(1, 2)
1927 case ASGTU:
1928 return SP(1, 3)
1929 case AAND:
1930 return SP(1, 4)
1931 case AOR:
1932 return SP(1, 5)
1933 case AXOR:
1934 return SP(1, 6)
1935 case ALUI:
1936 return SP(1, 7)
1937 case ASLL:
1938 return OP(0, 0)
1939 case ASRL:
1940 return OP(0, 2)
1941 case ASRA:
1942 return OP(0, 3)
1943 case AROTR:
1944 return OP(0, 2) | 1<<21
1945 case AADDV:
1946 return SP(3, 0)
1947 case AADDVU:
1948 return SP(3, 1)
1949
1950 case AJMP:
1951 return SP(0, 2)
1952 case AJAL,
1953 obj.ADUFFZERO,
1954 obj.ADUFFCOPY:
1955 return SP(0, 3)
1956 case ABEQ:
1957 return SP(0, 4)
1958 case -ABEQ:
1959 return SP(2, 4)
1960 case ABNE:
1961 return SP(0, 5)
1962 case -ABNE:
1963 return SP(2, 5)
1964 case ABGEZ:
1965 return SP(0, 1) | BCOND(0, 1)
1966 case -ABGEZ:
1967 return SP(0, 1) | BCOND(0, 3)
1968 case ABGEZAL:
1969 return SP(0, 1) | BCOND(2, 1)
1970 case -ABGEZAL:
1971 return SP(0, 1) | BCOND(2, 3)
1972 case ABGTZ:
1973 return SP(0, 7)
1974 case -ABGTZ:
1975 return SP(2, 7)
1976 case ABLEZ:
1977 return SP(0, 6)
1978 case -ABLEZ:
1979 return SP(2, 6)
1980 case ABLTZ:
1981 return SP(0, 1) | BCOND(0, 0)
1982 case -ABLTZ:
1983 return SP(0, 1) | BCOND(0, 2)
1984 case ABLTZAL:
1985 return SP(0, 1) | BCOND(2, 0)
1986 case -ABLTZAL:
1987 return SP(0, 1) | BCOND(2, 2)
1988 case ABFPT:
1989 return SP(2, 1) | (257 << 16)
1990 case -ABFPT:
1991 return SP(2, 1) | (259 << 16)
1992 case ABFPF:
1993 return SP(2, 1) | (256 << 16)
1994 case -ABFPF:
1995 return SP(2, 1) | (258 << 16)
1996
1997 case AMOVB,
1998 AMOVBU:
1999 return SP(5, 0)
2000 case AMOVH,
2001 AMOVHU:
2002 return SP(5, 1)
2003 case AMOVW,
2004 AMOVWU:
2005 return SP(5, 3)
2006 case AMOVV:
2007 return SP(7, 7)
2008 case AMOVF:
2009 return SP(7, 1)
2010 case AMOVD:
2011 return SP(7, 5)
2012 case AMOVWL:
2013 return SP(5, 2)
2014 case AMOVWR:
2015 return SP(5, 6)
2016 case AMOVVL:
2017 return SP(5, 4)
2018 case AMOVVR:
2019 return SP(5, 5)
2020
2021 case ABREAK:
2022 return SP(5, 7)
2023
2024 case -AMOVWL:
2025 return SP(4, 2)
2026 case -AMOVWR:
2027 return SP(4, 6)
2028 case -AMOVVL:
2029 return SP(3, 2)
2030 case -AMOVVR:
2031 return SP(3, 3)
2032 case -AMOVB:
2033 return SP(4, 0)
2034 case -AMOVBU:
2035 return SP(4, 4)
2036 case -AMOVH:
2037 return SP(4, 1)
2038 case -AMOVHU:
2039 return SP(4, 5)
2040 case -AMOVW:
2041 return SP(4, 3)
2042 case -AMOVWU:
2043 return SP(4, 7)
2044 case -AMOVV:
2045 return SP(6, 7)
2046 case -AMOVF:
2047 return SP(6, 1)
2048 case -AMOVD:
2049 return SP(6, 5)
2050
2051 case ASLLV:
2052 return OP(7, 0)
2053 case ASRLV:
2054 return OP(7, 2)
2055 case ASRAV:
2056 return OP(7, 3)
2057 case AROTRV:
2058 return OP(7, 2) | 1<<21
2059 case -ASLLV:
2060 return OP(7, 4)
2061 case -ASRLV:
2062 return OP(7, 6)
2063 case -ASRAV:
2064 return OP(7, 7)
2065 case -AROTRV:
2066 return OP(7, 6) | 1<<21
2067
2068 case ATEQ:
2069 return OP(6, 4)
2070 case ATNE:
2071 return OP(6, 6)
2072 case -ALL:
2073 return SP(6, 0)
2074 case -ALLV:
2075 return SP(6, 4)
2076 case ASC:
2077 return SP(7, 0)
2078 case ASCV:
2079 return SP(7, 4)
2080 }
2081
2082 if a < 0 {
2083 c.ctxt.Diag("bad irr opcode -%v", -a)
2084 } else {
2085 c.ctxt.Diag("bad irr opcode %v", a)
2086 }
2087 return 0
2088 }
2089
2090 func vshift(a obj.As) bool {
2091 switch a {
2092 case ASLLV,
2093 ASRLV,
2094 ASRAV,
2095 AROTRV:
2096 return true
2097 }
2098 return false
2099 }
2100
2101
2102 func (c *ctxt0) twobitdf(a obj.As) uint32 {
2103 switch a {
2104 case AVMOVB:
2105 return 0
2106 case AVMOVH:
2107 return 1
2108 case AVMOVW:
2109 return 2
2110 case AVMOVD:
2111 return 3
2112 default:
2113 c.ctxt.Diag("unsupported data format %v", a)
2114 }
2115 return 0
2116 }
2117
2118
2119 func (c *ctxt0) lsoffset(a obj.As, o int32) int32 {
2120 var mod int32
2121 switch a {
2122 case AVMOVB:
2123 mod = 1
2124 case AVMOVH:
2125 mod = 2
2126 case AVMOVW:
2127 mod = 4
2128 case AVMOVD:
2129 mod = 8
2130 default:
2131 c.ctxt.Diag("unsupported instruction:%v", a)
2132 }
2133
2134 if o%mod != 0 {
2135 c.ctxt.Diag("invalid offset for %v: %d is not a multiple of %d", a, o, mod)
2136 }
2137
2138 return o / mod
2139 }
2140
View as plain text