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 %v", 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 v := c.regoff(&p.To)
1512 o1 = OP_IRR(c.opirr(ALUI), uint32((v+1<<15)>>16), REGZERO, REGTMP)
1513 o2 = OP_RRR(c.oprrr(add), r, REGTMP, REGTMP)
1514 o3 = OP_IRR(c.opirr(p.As), uint32(v), REGTMP, p.From.Reg)
1515
1516 case 36:
1517 r := p.From.Reg
1518 if r == obj.REG_NONE {
1519 r = o.param
1520 }
1521 v := c.regoff(&p.From)
1522 o1 = OP_IRR(c.opirr(ALUI), uint32((v+1<<15)>>16), REGZERO, REGTMP)
1523 o2 = OP_RRR(c.oprrr(add), r, REGTMP, REGTMP)
1524 o3 = OP_IRR(c.opirr(-p.As), uint32(v), REGTMP, p.To.Reg)
1525
1526 case 37:
1527 a := SP(2, 0) | (4 << 21)
1528 if p.As == AMOVV {
1529 a = SP(2, 0) | (5 << 21)
1530 }
1531 o1 = OP_RRR(a, p.From.Reg, obj.REG_NONE, p.To.Reg)
1532
1533 case 38:
1534 a := SP(2, 0) | (0 << 21)
1535 if p.As == AMOVV {
1536 a = SP(2, 0) | (1 << 21)
1537 }
1538 o1 = OP_RRR(a, p.To.Reg, obj.REG_NONE, p.From.Reg)
1539
1540 case 40:
1541 o1 = uint32(c.regoff(&p.From))
1542
1543 case 41:
1544 o1 = OP_RRR(SP(2, 1)|(6<<21), p.From.Reg, obj.REG_NONE, p.To.Reg)
1545
1546 case 42:
1547 o1 = OP_RRR(SP(2, 1)|(2<<21), p.To.Reg, obj.REG_NONE, p.From.Reg)
1548
1549 case 47:
1550 a := SP(2, 1) | (5 << 21)
1551 o1 = OP_RRR(a, p.From.Reg, obj.REG_NONE, p.To.Reg)
1552
1553 case 48:
1554 a := SP(2, 1) | (1 << 21)
1555 o1 = OP_RRR(a, p.To.Reg, obj.REG_NONE, p.From.Reg)
1556
1557 case 49:
1558 o1 = 52
1559
1560
1561 case 50:
1562 o1 = OP_IRR(c.opirr(ALUI), 0, REGZERO, REGTMP)
1563 c.cursym.AddRel(c.ctxt, obj.Reloc{
1564 Type: objabi.R_ADDRMIPSU,
1565 Off: int32(c.pc),
1566 Siz: 4,
1567 Sym: p.To.Sym,
1568 Add: p.To.Offset,
1569 })
1570
1571 o2 = OP_IRR(c.opirr(p.As), 0, REGTMP, p.From.Reg)
1572 off := int32(c.pc + 4)
1573 if o.size == 12 {
1574 o3 = o2
1575 o2 = OP_RRR(c.oprrr(AADDVU), REGSB, REGTMP, REGTMP)
1576 off += 4
1577 }
1578 c.cursym.AddRel(c.ctxt, obj.Reloc{
1579 Type: objabi.R_ADDRMIPS,
1580 Off: off,
1581 Siz: 4,
1582 Sym: p.To.Sym,
1583 Add: p.To.Offset,
1584 })
1585
1586 case 51:
1587 o1 = OP_IRR(c.opirr(ALUI), 0, REGZERO, REGTMP)
1588 c.cursym.AddRel(c.ctxt, obj.Reloc{
1589 Type: objabi.R_ADDRMIPSU,
1590 Off: int32(c.pc),
1591 Siz: 4,
1592 Sym: p.From.Sym,
1593 Add: p.From.Offset,
1594 })
1595
1596 o2 = OP_IRR(c.opirr(-p.As), 0, REGTMP, p.To.Reg)
1597 off := int32(c.pc + 4)
1598 if o.size == 12 {
1599 o3 = o2
1600 o2 = OP_RRR(c.oprrr(AADDVU), REGSB, REGTMP, REGTMP)
1601 off += 4
1602 }
1603 c.cursym.AddRel(c.ctxt, obj.Reloc{
1604 Type: objabi.R_ADDRMIPS,
1605 Off: off,
1606 Siz: 4,
1607 Sym: p.From.Sym,
1608 Add: p.From.Offset,
1609 })
1610
1611 case 52:
1612
1613
1614 o1 = OP_IRR(c.opirr(ALUI), 0, REGZERO, p.To.Reg)
1615 c.cursym.AddRel(c.ctxt, obj.Reloc{
1616 Type: objabi.R_ADDRMIPSU,
1617 Off: int32(c.pc),
1618 Siz: 4,
1619 Sym: p.From.Sym,
1620 Add: p.From.Offset,
1621 })
1622
1623 o2 = OP_IRR(c.opirr(add), 0, p.To.Reg, p.To.Reg)
1624 off := int32(c.pc + 4)
1625 if o.size == 12 {
1626 o3 = o2
1627 o2 = OP_RRR(c.oprrr(AADDVU), REGSB, p.To.Reg, p.To.Reg)
1628 off += 4
1629 }
1630 c.cursym.AddRel(c.ctxt, obj.Reloc{
1631 Type: objabi.R_ADDRMIPS,
1632 Off: off,
1633 Siz: 4,
1634 Sym: p.From.Sym,
1635 Add: p.From.Offset,
1636 })
1637
1638 case 53:
1639
1640
1641
1642
1643 o1 = (037<<26 + 073) | (29 << 11) | (3 << 16)
1644 o2 = OP_IRR(c.opirr(p.As), 0, REG_R3, p.From.Reg)
1645 c.cursym.AddRel(c.ctxt, obj.Reloc{
1646 Type: objabi.R_ADDRMIPSTLS,
1647 Off: int32(c.pc + 4),
1648 Siz: 4,
1649 Sym: p.To.Sym,
1650 Add: p.To.Offset,
1651 })
1652
1653 case 54:
1654
1655
1656
1657 o1 = (037<<26 + 073) | (29 << 11) | (3 << 16)
1658 o2 = OP_IRR(c.opirr(-p.As), 0, REG_R3, p.To.Reg)
1659 c.cursym.AddRel(c.ctxt, obj.Reloc{
1660 Type: objabi.R_ADDRMIPSTLS,
1661 Off: int32(c.pc + 4),
1662 Siz: 4,
1663 Sym: p.From.Sym,
1664 Add: p.From.Offset,
1665 })
1666
1667 case 55:
1668
1669
1670
1671 o1 = (037<<26 + 073) | (29 << 11) | (3 << 16)
1672 o2 = OP_IRR(c.opirr(add), 0, REG_R3, p.To.Reg)
1673 c.cursym.AddRel(c.ctxt, obj.Reloc{
1674 Type: objabi.R_ADDRMIPSTLS,
1675 Off: int32(c.pc + 4),
1676 Siz: 4,
1677 Sym: p.From.Sym,
1678 Add: p.From.Offset,
1679 })
1680
1681 case 56:
1682
1683 v := c.regoff(&p.From)
1684 o1 = OP_VI10(110, c.twobitdf(p.As), v, uint32(p.To.Reg), 7)
1685
1686 case 57:
1687 v := c.lsoffset(p.As, c.regoff(&p.From))
1688 o1 = OP_VMI10(v, uint32(p.From.Reg), uint32(p.To.Reg), 8, c.twobitdf(p.As))
1689
1690 case 58:
1691 v := c.lsoffset(p.As, c.regoff(&p.To))
1692 o1 = OP_VMI10(v, uint32(p.To.Reg), uint32(p.From.Reg), 9, c.twobitdf(p.As))
1693
1694 case 59:
1695 o1 = OP_RRR(c.oprrr(p.As), p.From.Reg, REGZERO, p.To.Reg)
1696 }
1697
1698 out[0] = o1
1699 out[1] = o2
1700 out[2] = o3
1701 out[3] = o4
1702 }
1703
1704 func (c *ctxt0) vregoff(a *obj.Addr) int64 {
1705 c.instoffset = 0
1706 c.aclass(a)
1707 return c.instoffset
1708 }
1709
1710 func (c *ctxt0) regoff(a *obj.Addr) int32 {
1711 return int32(c.vregoff(a))
1712 }
1713
1714 func (c *ctxt0) oprrr(a obj.As) uint32 {
1715 switch a {
1716 case AADD:
1717 return OP(4, 0)
1718 case AADDU:
1719 return OP(4, 1)
1720 case ASGT:
1721 return OP(5, 2)
1722 case ASGTU:
1723 return OP(5, 3)
1724 case AAND:
1725 return OP(4, 4)
1726 case AOR:
1727 return OP(4, 5)
1728 case AXOR:
1729 return OP(4, 6)
1730 case ASUB:
1731 return OP(4, 2)
1732 case ASUBU, ANEGW:
1733 return OP(4, 3)
1734 case ANOR:
1735 return OP(4, 7)
1736 case ASLL:
1737 return OP(0, 4)
1738 case ASRL:
1739 return OP(0, 6)
1740 case ASRA:
1741 return OP(0, 7)
1742 case AROTR:
1743 return OP(8, 6)
1744 case ASLLV:
1745 return OP(2, 4)
1746 case ASRLV:
1747 return OP(2, 6)
1748 case ASRAV:
1749 return OP(2, 7)
1750 case AROTRV:
1751 return OP(10, 6)
1752 case AADDV:
1753 return OP(5, 4)
1754 case AADDVU:
1755 return OP(5, 5)
1756 case ASUBV:
1757 return OP(5, 6)
1758 case ASUBVU, ANEGV:
1759 return OP(5, 7)
1760 case AREM,
1761 ADIV:
1762 return OP(3, 2)
1763 case AREMU,
1764 ADIVU:
1765 return OP(3, 3)
1766 case AMUL:
1767 return OP(3, 0)
1768 case AMULU:
1769 return OP(3, 1)
1770 case AREMV,
1771 ADIVV:
1772 return OP(3, 6)
1773 case AREMVU,
1774 ADIVVU:
1775 return OP(3, 7)
1776 case AMULV:
1777 return OP(3, 4)
1778 case AMULVU:
1779 return OP(3, 5)
1780
1781 case AJMP:
1782 return OP(1, 0)
1783 case AJAL:
1784 return OP(1, 1)
1785
1786 case ABREAK:
1787 return OP(1, 5)
1788 case ASYSCALL:
1789 return OP(1, 4)
1790 case ATLBP:
1791 return MMU(1, 0)
1792 case ATLBR:
1793 return MMU(0, 1)
1794 case ATLBWI:
1795 return MMU(0, 2)
1796 case ATLBWR:
1797 return MMU(0, 6)
1798 case ARFE:
1799 return MMU(2, 0)
1800
1801 case ADIVF:
1802 return FPF(0, 3)
1803 case ADIVD:
1804 return FPD(0, 3)
1805 case AMULF:
1806 return FPF(0, 2)
1807 case AMULD:
1808 return FPD(0, 2)
1809 case ASUBF:
1810 return FPF(0, 1)
1811 case ASUBD:
1812 return FPD(0, 1)
1813 case AADDF:
1814 return FPF(0, 0)
1815 case AADDD:
1816 return FPD(0, 0)
1817 case ATRUNCFV:
1818 return FPF(1, 1)
1819 case ATRUNCDV:
1820 return FPD(1, 1)
1821 case ATRUNCFW:
1822 return FPF(1, 5)
1823 case ATRUNCDW:
1824 return FPD(1, 5)
1825 case AMOVFV:
1826 return FPF(4, 5)
1827 case AMOVDV:
1828 return FPD(4, 5)
1829 case AMOVVF:
1830 return FPV(4, 0)
1831 case AMOVVD:
1832 return FPV(4, 1)
1833 case AMOVFW:
1834 return FPF(4, 4)
1835 case AMOVDW:
1836 return FPD(4, 4)
1837 case AMOVWF:
1838 return FPW(4, 0)
1839 case AMOVDF:
1840 return FPD(4, 0)
1841 case AMOVWD:
1842 return FPW(4, 1)
1843 case AMOVFD:
1844 return FPF(4, 1)
1845 case AABSF:
1846 return FPF(0, 5)
1847 case AABSD:
1848 return FPD(0, 5)
1849 case AMOVF:
1850 return FPF(0, 6)
1851 case AMOVD:
1852 return FPD(0, 6)
1853 case ANEGF:
1854 return FPF(0, 7)
1855 case ANEGD:
1856 return FPD(0, 7)
1857 case ACMPEQF:
1858 return FPF(6, 2)
1859 case ACMPEQD:
1860 return FPD(6, 2)
1861 case ACMPGTF:
1862 return FPF(7, 4)
1863 case ACMPGTD:
1864 return FPD(7, 4)
1865 case ACMPGEF:
1866 return FPF(7, 6)
1867 case ACMPGED:
1868 return FPD(7, 6)
1869
1870 case ASQRTF:
1871 return FPF(0, 4)
1872 case ASQRTD:
1873 return FPD(0, 4)
1874
1875 case ASYNC:
1876 return OP(1, 7)
1877 case ANOOP:
1878 return 0
1879
1880 case ACMOVN:
1881 return OP(1, 3)
1882 case ACMOVZ:
1883 return OP(1, 2)
1884 case ACMOVT:
1885 return OP(0, 1) | (1 << 16)
1886 case ACMOVF:
1887 return OP(0, 1) | (0 << 16)
1888 case ACLO:
1889 return SP(3, 4) | OP(4, 1)
1890 case ACLZ:
1891 return SP(3, 4) | OP(4, 0)
1892 case AMADD:
1893 return SP(3, 4) | OP(0, 0)
1894 case AMSUB:
1895 return SP(3, 4) | OP(0, 4)
1896 case AWSBH:
1897 return SP(3, 7) | OP(20, 0)
1898 case ADSBH:
1899 return SP(3, 7) | OP(20, 4)
1900 case ADSHD:
1901 return SP(3, 7) | OP(44, 4)
1902 case ASEB:
1903 return SP(3, 7) | OP(132, 0)
1904 case ASEH:
1905 return SP(3, 7) | OP(196, 0)
1906 }
1907
1908 if a < 0 {
1909 c.ctxt.Diag("bad rrr opcode -%v", -a)
1910 } else {
1911 c.ctxt.Diag("bad rrr opcode %v", a)
1912 }
1913 return 0
1914 }
1915
1916 func (c *ctxt0) opirr(a obj.As) uint32 {
1917 switch a {
1918 case AADD:
1919 return SP(1, 0)
1920 case AADDU:
1921 return SP(1, 1)
1922 case ASGT:
1923 return SP(1, 2)
1924 case ASGTU:
1925 return SP(1, 3)
1926 case AAND:
1927 return SP(1, 4)
1928 case AOR:
1929 return SP(1, 5)
1930 case AXOR:
1931 return SP(1, 6)
1932 case ALUI:
1933 return SP(1, 7)
1934 case ASLL:
1935 return OP(0, 0)
1936 case ASRL:
1937 return OP(0, 2)
1938 case ASRA:
1939 return OP(0, 3)
1940 case AROTR:
1941 return OP(0, 2) | 1<<21
1942 case AADDV:
1943 return SP(3, 0)
1944 case AADDVU:
1945 return SP(3, 1)
1946
1947 case AJMP:
1948 return SP(0, 2)
1949 case AJAL,
1950 obj.ADUFFZERO,
1951 obj.ADUFFCOPY:
1952 return SP(0, 3)
1953 case ABEQ:
1954 return SP(0, 4)
1955 case -ABEQ:
1956 return SP(2, 4)
1957 case ABNE:
1958 return SP(0, 5)
1959 case -ABNE:
1960 return SP(2, 5)
1961 case ABGEZ:
1962 return SP(0, 1) | BCOND(0, 1)
1963 case -ABGEZ:
1964 return SP(0, 1) | BCOND(0, 3)
1965 case ABGEZAL:
1966 return SP(0, 1) | BCOND(2, 1)
1967 case -ABGEZAL:
1968 return SP(0, 1) | BCOND(2, 3)
1969 case ABGTZ:
1970 return SP(0, 7)
1971 case -ABGTZ:
1972 return SP(2, 7)
1973 case ABLEZ:
1974 return SP(0, 6)
1975 case -ABLEZ:
1976 return SP(2, 6)
1977 case ABLTZ:
1978 return SP(0, 1) | BCOND(0, 0)
1979 case -ABLTZ:
1980 return SP(0, 1) | BCOND(0, 2)
1981 case ABLTZAL:
1982 return SP(0, 1) | BCOND(2, 0)
1983 case -ABLTZAL:
1984 return SP(0, 1) | BCOND(2, 2)
1985 case ABFPT:
1986 return SP(2, 1) | (257 << 16)
1987 case -ABFPT:
1988 return SP(2, 1) | (259 << 16)
1989 case ABFPF:
1990 return SP(2, 1) | (256 << 16)
1991 case -ABFPF:
1992 return SP(2, 1) | (258 << 16)
1993
1994 case AMOVB,
1995 AMOVBU:
1996 return SP(5, 0)
1997 case AMOVH,
1998 AMOVHU:
1999 return SP(5, 1)
2000 case AMOVW,
2001 AMOVWU:
2002 return SP(5, 3)
2003 case AMOVV:
2004 return SP(7, 7)
2005 case AMOVF:
2006 return SP(7, 1)
2007 case AMOVD:
2008 return SP(7, 5)
2009 case AMOVWL:
2010 return SP(5, 2)
2011 case AMOVWR:
2012 return SP(5, 6)
2013 case AMOVVL:
2014 return SP(5, 4)
2015 case AMOVVR:
2016 return SP(5, 5)
2017
2018 case ABREAK:
2019 return SP(5, 7)
2020
2021 case -AMOVWL:
2022 return SP(4, 2)
2023 case -AMOVWR:
2024 return SP(4, 6)
2025 case -AMOVVL:
2026 return SP(3, 2)
2027 case -AMOVVR:
2028 return SP(3, 3)
2029 case -AMOVB:
2030 return SP(4, 0)
2031 case -AMOVBU:
2032 return SP(4, 4)
2033 case -AMOVH:
2034 return SP(4, 1)
2035 case -AMOVHU:
2036 return SP(4, 5)
2037 case -AMOVW:
2038 return SP(4, 3)
2039 case -AMOVWU:
2040 return SP(4, 7)
2041 case -AMOVV:
2042 return SP(6, 7)
2043 case -AMOVF:
2044 return SP(6, 1)
2045 case -AMOVD:
2046 return SP(6, 5)
2047
2048 case ASLLV:
2049 return OP(7, 0)
2050 case ASRLV:
2051 return OP(7, 2)
2052 case ASRAV:
2053 return OP(7, 3)
2054 case AROTRV:
2055 return OP(7, 2) | 1<<21
2056 case -ASLLV:
2057 return OP(7, 4)
2058 case -ASRLV:
2059 return OP(7, 6)
2060 case -ASRAV:
2061 return OP(7, 7)
2062 case -AROTRV:
2063 return OP(7, 6) | 1<<21
2064
2065 case ATEQ:
2066 return OP(6, 4)
2067 case ATNE:
2068 return OP(6, 6)
2069 case -ALL:
2070 return SP(6, 0)
2071 case -ALLV:
2072 return SP(6, 4)
2073 case ASC:
2074 return SP(7, 0)
2075 case ASCV:
2076 return SP(7, 4)
2077 }
2078
2079 if a < 0 {
2080 c.ctxt.Diag("bad irr opcode -%v", -a)
2081 } else {
2082 c.ctxt.Diag("bad irr opcode %v", a)
2083 }
2084 return 0
2085 }
2086
2087 func vshift(a obj.As) bool {
2088 switch a {
2089 case ASLLV,
2090 ASRLV,
2091 ASRAV,
2092 AROTRV:
2093 return true
2094 }
2095 return false
2096 }
2097
2098
2099 func (c *ctxt0) twobitdf(a obj.As) uint32 {
2100 switch a {
2101 case AVMOVB:
2102 return 0
2103 case AVMOVH:
2104 return 1
2105 case AVMOVW:
2106 return 2
2107 case AVMOVD:
2108 return 3
2109 default:
2110 c.ctxt.Diag("unsupported data format %v", a)
2111 }
2112 return 0
2113 }
2114
2115
2116 func (c *ctxt0) lsoffset(a obj.As, o int32) int32 {
2117 var mod int32
2118 switch a {
2119 case AVMOVB:
2120 mod = 1
2121 case AVMOVH:
2122 mod = 2
2123 case AVMOVW:
2124 mod = 4
2125 case AVMOVD:
2126 mod = 8
2127 default:
2128 c.ctxt.Diag("unsupported instruction:%v", a)
2129 }
2130
2131 if o%mod != 0 {
2132 c.ctxt.Diag("invalid offset for %v: %d is not a multiple of %d", a, o, mod)
2133 }
2134
2135 return o / mod
2136 }
2137
View as plain text