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 "sort"
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 type ocmp []Optab
879
880 func (x ocmp) Len() int {
881 return len(x)
882 }
883
884 func (x ocmp) Swap(i, j int) {
885 x[i], x[j] = x[j], x[i]
886 }
887
888 func (x ocmp) Less(i, j int) bool {
889 p1 := &x[i]
890 p2 := &x[j]
891 n := int(p1.as) - int(p2.as)
892 if n != 0 {
893 return n < 0
894 }
895 n = int(p1.a1) - int(p2.a1)
896 if n != 0 {
897 return n < 0
898 }
899 n = int(p1.a2) - int(p2.a2)
900 if n != 0 {
901 return n < 0
902 }
903 n = int(p1.a3) - int(p2.a3)
904 if n != 0 {
905 return n < 0
906 }
907 return false
908 }
909
910 func opset(a, b0 obj.As) {
911 oprange[a&obj.AMask] = oprange[b0]
912 }
913
914 func buildop(ctxt *obj.Link) {
915 if oprange[AOR&obj.AMask] != nil {
916
917
918
919 return
920 }
921
922 var n int
923
924 for i := 0; i < C_NCLASS; i++ {
925 for n = 0; n < C_NCLASS; n++ {
926 if cmp(n, i) {
927 xcmp[i][n] = true
928 }
929 }
930 }
931 for n = 0; optab[n].as != obj.AXXX; n++ {
932 }
933 sort.Sort(ocmp(optab[:n]))
934 for i := 0; i < n; i++ {
935 r := optab[i].as
936 r0 := r & obj.AMask
937 start := i
938 for optab[i].as == r {
939 i++
940 }
941 oprange[r0] = optab[start:i]
942 i--
943
944 switch r {
945 default:
946 ctxt.Diag("unknown op in build: %v", r)
947 ctxt.DiagFlush()
948 log.Fatalf("bad code")
949
950 case AABSF:
951 opset(AMOVFD, r0)
952 opset(AMOVDF, r0)
953 opset(AMOVWF, r0)
954 opset(AMOVFW, r0)
955 opset(AMOVWD, r0)
956 opset(AMOVDW, r0)
957 opset(ANEGF, r0)
958 opset(ANEGD, r0)
959 opset(AABSD, r0)
960 opset(ATRUNCDW, r0)
961 opset(ATRUNCFW, r0)
962 opset(ASQRTF, r0)
963 opset(ASQRTD, r0)
964
965 case AMOVVF:
966 opset(AMOVVD, r0)
967 opset(AMOVFV, r0)
968 opset(AMOVDV, r0)
969 opset(ATRUNCDV, r0)
970 opset(ATRUNCFV, r0)
971
972 case AADD:
973 opset(ASGT, r0)
974 opset(ASGTU, r0)
975 opset(AADDU, r0)
976
977 case AADDV:
978 opset(AADDVU, r0)
979
980 case AADDF:
981 opset(ADIVF, r0)
982 opset(ADIVD, r0)
983 opset(AMULF, r0)
984 opset(AMULD, r0)
985 opset(ASUBF, r0)
986 opset(ASUBD, r0)
987 opset(AADDD, r0)
988
989 case AAND:
990 opset(AOR, r0)
991 opset(AXOR, r0)
992
993 case ABEQ:
994 opset(ABNE, r0)
995
996 case ABLEZ:
997 opset(ABGEZ, r0)
998 opset(ABGEZAL, r0)
999 opset(ABLTZ, r0)
1000 opset(ABLTZAL, r0)
1001 opset(ABGTZ, r0)
1002
1003 case AMOVB:
1004 opset(AMOVH, r0)
1005
1006 case AMOVBU:
1007 opset(AMOVHU, r0)
1008
1009 case AMUL:
1010 opset(AREM, r0)
1011 opset(AREMU, r0)
1012 opset(ADIVU, r0)
1013 opset(AMULU, r0)
1014 opset(ADIV, r0)
1015 opset(AMADD, r0)
1016 opset(AMSUB, r0)
1017
1018 case AMULV:
1019 opset(ADIVV, r0)
1020 opset(ADIVVU, r0)
1021 opset(AMULVU, r0)
1022 opset(AREMV, r0)
1023 opset(AREMVU, r0)
1024
1025 case ASLL:
1026 opset(ASRL, r0)
1027 opset(ASRA, r0)
1028 opset(AROTR, r0)
1029
1030 case ASLLV:
1031 opset(ASRAV, r0)
1032 opset(ASRLV, r0)
1033 opset(AROTRV, r0)
1034
1035 case ASUB:
1036 opset(ASUBU, r0)
1037 opset(ANOR, r0)
1038
1039 case ASUBV:
1040 opset(ASUBVU, r0)
1041
1042 case ASYSCALL:
1043 opset(ASYNC, r0)
1044 opset(ANOOP, r0)
1045 opset(ATLBP, r0)
1046 opset(ATLBR, r0)
1047 opset(ATLBWI, r0)
1048 opset(ATLBWR, r0)
1049
1050 case ACMPEQF:
1051 opset(ACMPGTF, r0)
1052 opset(ACMPGTD, r0)
1053 opset(ACMPGEF, r0)
1054 opset(ACMPGED, r0)
1055 opset(ACMPEQD, r0)
1056
1057 case ABFPT:
1058 opset(ABFPF, r0)
1059
1060 case AMOVWL:
1061 opset(AMOVWR, r0)
1062
1063 case AMOVVL:
1064 opset(AMOVVR, r0)
1065
1066 case AVMOVB:
1067 opset(AVMOVH, r0)
1068 opset(AVMOVW, r0)
1069 opset(AVMOVD, r0)
1070
1071 case AMOVW,
1072 AMOVD,
1073 AMOVF,
1074 AMOVV,
1075 ABREAK,
1076 ARFE,
1077 AJAL,
1078 AJMP,
1079 AMOVWU,
1080 ALL,
1081 ALLV,
1082 ASC,
1083 ASCV,
1084 ANEGW,
1085 ANEGV,
1086 AWORD,
1087 obj.ANOP,
1088 obj.ATEXT,
1089 obj.AUNDEF,
1090 obj.AFUNCDATA,
1091 obj.APCDATA,
1092 obj.ADUFFZERO,
1093 obj.ADUFFCOPY:
1094 break
1095
1096 case ACMOVN:
1097 opset(ACMOVZ, r0)
1098
1099 case ACMOVT:
1100 opset(ACMOVF, r0)
1101
1102 case ACLO:
1103 opset(ACLZ, r0)
1104
1105 case ATEQ:
1106 opset(ATNE, r0)
1107
1108 case AWSBH:
1109 opset(ASEB, r0)
1110 opset(ASEH, r0)
1111
1112 case ADSBH:
1113 opset(ADSHD, r0)
1114 }
1115 }
1116 }
1117
1118 func OP(x uint32, y uint32) uint32 {
1119 return x<<3 | y<<0
1120 }
1121
1122 func SP(x uint32, y uint32) uint32 {
1123 return x<<29 | y<<26
1124 }
1125
1126 func BCOND(x uint32, y uint32) uint32 {
1127 return x<<19 | y<<16
1128 }
1129
1130 func MMU(x uint32, y uint32) uint32 {
1131 return SP(2, 0) | 16<<21 | x<<3 | y<<0
1132 }
1133
1134 func FPF(x uint32, y uint32) uint32 {
1135 return SP(2, 1) | 16<<21 | x<<3 | y<<0
1136 }
1137
1138 func FPD(x uint32, y uint32) uint32 {
1139 return SP(2, 1) | 17<<21 | x<<3 | y<<0
1140 }
1141
1142 func FPW(x uint32, y uint32) uint32 {
1143 return SP(2, 1) | 20<<21 | x<<3 | y<<0
1144 }
1145
1146 func FPV(x uint32, y uint32) uint32 {
1147 return SP(2, 1) | 21<<21 | x<<3 | y<<0
1148 }
1149
1150 func OP_RRR(op uint32, r1 int16, r2 int16, r3 int16) uint32 {
1151 return op | uint32(r1&31)<<16 | uint32(r2&31)<<21 | uint32(r3&31)<<11
1152 }
1153
1154 func OP_IRR(op uint32, i uint32, r2 int16, r3 int16) uint32 {
1155 return op | i&0xFFFF | uint32(r2&31)<<21 | uint32(r3&31)<<16
1156 }
1157
1158 func OP_SRR(op uint32, s uint32, r2 int16, r3 int16) uint32 {
1159 return op | (s&31)<<6 | uint32(r2&31)<<16 | uint32(r3&31)<<11
1160 }
1161
1162 func OP_FRRR(op uint32, r1 int16, r2 int16, r3 int16) uint32 {
1163 return op | uint32(r1&31)<<16 | uint32(r2&31)<<11 | uint32(r3&31)<<6
1164 }
1165
1166 func OP_JMP(op uint32, i uint32) uint32 {
1167 return op | i&0x3FFFFFF
1168 }
1169
1170 func OP_VI10(op uint32, df uint32, s10 int32, wd uint32, minor uint32) uint32 {
1171 return 0x1e<<26 | (op&7)<<23 | (df&3)<<21 | uint32(s10&0x3FF)<<11 | (wd&31)<<6 | minor&0x3F
1172 }
1173
1174 func OP_VMI10(s10 int32, rs uint32, wd uint32, minor uint32, df uint32) uint32 {
1175 return 0x1e<<26 | uint32(s10&0x3FF)<<16 | (rs&31)<<11 | (wd&31)<<6 | (minor&15)<<2 | df&3
1176 }
1177
1178 func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
1179 o1 := uint32(0)
1180 o2 := uint32(0)
1181 o3 := uint32(0)
1182 o4 := uint32(0)
1183
1184 add := AADDU
1185
1186 if c.ctxt.Arch.Family == sys.MIPS64 {
1187 add = AADDVU
1188 }
1189 switch o.type_ {
1190 default:
1191 c.ctxt.Diag("unknown type %d %v", o.type_)
1192 prasm(p)
1193
1194 case 0:
1195 break
1196
1197 case 1:
1198 a := AOR
1199 if p.As == AMOVW && c.ctxt.Arch.Family == sys.MIPS64 {
1200
1201
1202 a = ASLL
1203 }
1204 o1 = OP_RRR(c.oprrr(a), p.From.Reg, REGZERO, p.To.Reg)
1205
1206 case 2:
1207 r := p.Reg
1208 if p.As == ANEGW || p.As == ANEGV {
1209 r = REGZERO
1210 }
1211 if r == obj.REG_NONE {
1212 r = p.To.Reg
1213 }
1214 o1 = OP_RRR(c.oprrr(p.As), p.From.Reg, r, p.To.Reg)
1215
1216 case 3:
1217 a := add
1218 if o.a1 == C_ANDCON {
1219 a = AOR
1220 }
1221 r := p.From.Reg
1222 if r == obj.REG_NONE {
1223 r = o.param
1224 }
1225 v := c.regoff(&p.From)
1226 o1 = OP_IRR(c.opirr(a), uint32(v), r, p.To.Reg)
1227
1228 case 4:
1229 r := p.Reg
1230 if r == obj.REG_NONE {
1231 r = p.To.Reg
1232 }
1233 v := c.regoff(&p.From)
1234 o1 = OP_IRR(c.opirr(p.As), uint32(v), r, p.To.Reg)
1235
1236 case 5:
1237 o1 = c.oprrr(p.As)
1238
1239 case 6:
1240 v := int32(0)
1241 if p.To.Target() == nil {
1242 v = int32(-4) >> 2
1243 } else {
1244 v = int32(p.To.Target().Pc-p.Pc-4) >> 2
1245 }
1246 if (v<<16)>>16 != v {
1247 c.ctxt.Diag("short branch too far\n%v", p)
1248 }
1249 o1 = OP_IRR(c.opirr(p.As), uint32(v), p.From.Reg, p.Reg)
1250
1251
1252 o2 = 0
1253
1254 case 7:
1255 r := p.To.Reg
1256 if r == obj.REG_NONE {
1257 r = o.param
1258 }
1259 v := c.regoff(&p.To)
1260 o1 = OP_IRR(c.opirr(p.As), uint32(v), r, p.From.Reg)
1261
1262 case 8:
1263 r := p.From.Reg
1264 if r == obj.REG_NONE {
1265 r = o.param
1266 }
1267 v := c.regoff(&p.From)
1268 o1 = OP_IRR(c.opirr(-p.As), uint32(v), r, p.To.Reg)
1269
1270 case 9:
1271 r := p.Reg
1272 if r == obj.REG_NONE {
1273 r = p.To.Reg
1274 }
1275 o1 = OP_RRR(c.oprrr(p.As), r, p.From.Reg, p.To.Reg)
1276
1277 case 10:
1278 v := c.regoff(&p.From)
1279 a := AOR
1280 if v < 0 {
1281 a = AADDU
1282 }
1283 o1 = OP_IRR(c.opirr(a), uint32(v), obj.REG_NONE, REGTMP)
1284 r := p.Reg
1285 if r == obj.REG_NONE {
1286 r = p.To.Reg
1287 }
1288 o2 = OP_RRR(c.oprrr(p.As), REGTMP, r, p.To.Reg)
1289
1290 case 11:
1291 v := int32(0)
1292 if c.aclass(&p.To) == C_SBRA && p.To.Sym == nil && p.As == AJMP {
1293
1294
1295 if p.To.Target() == nil {
1296 v = int32(-4) >> 2
1297 } else {
1298 v = int32(p.To.Target().Pc-p.Pc-4) >> 2
1299 }
1300 if (v<<16)>>16 == v {
1301 o1 = OP_IRR(c.opirr(ABEQ), uint32(v), REGZERO, REGZERO)
1302 break
1303 }
1304 }
1305 if p.To.Target() == nil {
1306 v = int32(p.Pc) >> 2
1307 } else {
1308 v = int32(p.To.Target().Pc) >> 2
1309 }
1310 o1 = OP_JMP(c.opirr(p.As), uint32(v))
1311 if p.To.Sym == nil {
1312 p.To.Sym = c.cursym.Func().Text.From.Sym
1313 p.To.Offset = p.To.Target().Pc
1314 }
1315 rel := obj.Addrel(c.cursym)
1316 rel.Off = int32(c.pc)
1317 rel.Siz = 4
1318 rel.Sym = p.To.Sym
1319 rel.Add = p.To.Offset
1320 if p.As == AJAL {
1321 rel.Type = objabi.R_CALLMIPS
1322 } else {
1323 rel.Type = objabi.R_JMPMIPS
1324 }
1325
1326 case 12:
1327
1328
1329 v := 16
1330 if p.As == AMOVB {
1331 v = 24
1332 }
1333 o1 = OP_SRR(c.opirr(ASLL), uint32(v), p.From.Reg, p.To.Reg)
1334 o2 = OP_SRR(c.opirr(ASRA), uint32(v), p.To.Reg, p.To.Reg)
1335
1336 case 13:
1337 if p.As == AMOVBU {
1338 o1 = OP_IRR(c.opirr(AAND), uint32(0xff), p.From.Reg, p.To.Reg)
1339 } else {
1340 o1 = OP_IRR(c.opirr(AAND), uint32(0xffff), p.From.Reg, p.To.Reg)
1341 }
1342
1343 case 14:
1344
1345
1346 o1 = OP_SRR(c.opirr(-ASLLV), 0, p.From.Reg, p.To.Reg)
1347 o2 = OP_SRR(c.opirr(-ASRLV), 0, p.To.Reg, p.To.Reg)
1348
1349 case 15:
1350 r := p.Reg
1351 if r == obj.REG_NONE {
1352 r = REGZERO
1353 }
1354 v := c.regoff(&p.From)
1355
1356 o1 = OP_IRR(c.opirr(p.As), (uint32(v)&0x3FF)<<6, r, p.To.Reg)
1357
1358 case 16:
1359 r := p.Reg
1360 if r == obj.REG_NONE {
1361 r = p.To.Reg
1362 }
1363 v := c.regoff(&p.From)
1364
1365
1366 if v >= 32 && vshift(p.As) {
1367 o1 = OP_SRR(c.opirr(-p.As), uint32(v-32), r, p.To.Reg)
1368 } else {
1369 o1 = OP_SRR(c.opirr(p.As), uint32(v), r, p.To.Reg)
1370 }
1371
1372 case 17:
1373 o1 = OP_RRR(c.oprrr(p.As), REGZERO, p.From.Reg, p.To.Reg)
1374
1375 case 18:
1376 r := p.Reg
1377 if r == obj.REG_NONE {
1378 r = o.param
1379 }
1380 o1 = OP_RRR(c.oprrr(p.As), obj.REG_NONE, p.To.Reg, r)
1381 if p.As == obj.ACALL {
1382 rel := obj.Addrel(c.cursym)
1383 rel.Off = int32(c.pc)
1384 rel.Siz = 0
1385 rel.Type = objabi.R_CALLIND
1386 }
1387
1388 case 19:
1389
1390
1391 v := c.regoff(&p.From)
1392 o1 = OP_IRR(c.opirr(ALUI), uint32(v>>16), REGZERO, p.To.Reg)
1393 o2 = OP_IRR(c.opirr(AOR), uint32(v), p.To.Reg, p.To.Reg)
1394
1395 case 20:
1396 a := OP(2, 0)
1397 if p.From.Reg == REG_LO {
1398 a = OP(2, 2)
1399 }
1400 o1 = OP_RRR(a, REGZERO, REGZERO, p.To.Reg)
1401
1402 case 21:
1403 a := OP(2, 1)
1404 if p.To.Reg == REG_LO {
1405 a = OP(2, 3)
1406 }
1407 o1 = OP_RRR(a, REGZERO, p.From.Reg, REGZERO)
1408
1409 case 22:
1410 if p.To.Reg != obj.REG_NONE {
1411 r := p.Reg
1412 if r == obj.REG_NONE {
1413 r = p.To.Reg
1414 }
1415 a := SP(3, 4) | 2
1416 o1 = OP_RRR(a, p.From.Reg, r, p.To.Reg)
1417 } else {
1418 o1 = OP_RRR(c.oprrr(p.As), p.From.Reg, p.Reg, REGZERO)
1419 }
1420
1421 case 23:
1422 v := c.regoff(&p.From)
1423 o1 = OP_IRR(c.opirr(ALUI), uint32(v>>16), REGZERO, REGTMP)
1424 o2 = OP_IRR(c.opirr(AOR), uint32(v), REGTMP, REGTMP)
1425 r := p.Reg
1426 if r == obj.REG_NONE {
1427 r = p.To.Reg
1428 }
1429 o3 = OP_RRR(c.oprrr(p.As), REGTMP, r, p.To.Reg)
1430
1431 case 24:
1432 v := c.regoff(&p.From)
1433 o1 = OP_IRR(c.opirr(ALUI), uint32(v>>16), REGZERO, p.To.Reg)
1434
1435 case 25:
1436 v := c.regoff(&p.From)
1437 o1 = OP_IRR(c.opirr(ALUI), uint32(v>>16), REGZERO, REGTMP)
1438 r := p.Reg
1439 if r == obj.REG_NONE {
1440 r = p.To.Reg
1441 }
1442 o2 = OP_RRR(c.oprrr(p.As), REGTMP, r, p.To.Reg)
1443
1444 case 26:
1445 v := c.regoff(&p.From)
1446 o1 = OP_IRR(c.opirr(ALUI), uint32(v>>16), REGZERO, REGTMP)
1447 o2 = OP_IRR(c.opirr(AOR), uint32(v), REGTMP, REGTMP)
1448 r := p.From.Reg
1449 if r == obj.REG_NONE {
1450 r = o.param
1451 }
1452 o3 = OP_RRR(c.oprrr(add), REGTMP, r, p.To.Reg)
1453
1454 case 27:
1455 a := -AMOVF
1456 if p.As == AMOVD {
1457 a = -AMOVD
1458 }
1459 r := p.From.Reg
1460 if r == obj.REG_NONE {
1461 r = o.param
1462 }
1463 v := c.regoff(&p.From)
1464 switch o.size {
1465 case 12:
1466 o1 = OP_IRR(c.opirr(ALUI), uint32((v+1<<15)>>16), REGZERO, REGTMP)
1467 o2 = OP_RRR(c.oprrr(add), r, REGTMP, REGTMP)
1468 o3 = OP_IRR(c.opirr(a), uint32(v), REGTMP, p.To.Reg)
1469
1470 case 4:
1471 o1 = OP_IRR(c.opirr(a), uint32(v), r, p.To.Reg)
1472 }
1473
1474 case 28:
1475 a := AMOVF
1476 if p.As == AMOVD {
1477 a = AMOVD
1478 }
1479 r := p.To.Reg
1480 if r == obj.REG_NONE {
1481 r = o.param
1482 }
1483 v := c.regoff(&p.To)
1484 switch o.size {
1485 case 12:
1486 o1 = OP_IRR(c.opirr(ALUI), uint32((v+1<<15)>>16), REGZERO, REGTMP)
1487 o2 = OP_RRR(c.oprrr(add), r, REGTMP, REGTMP)
1488 o3 = OP_IRR(c.opirr(a), uint32(v), REGTMP, p.From.Reg)
1489
1490 case 4:
1491 o1 = OP_IRR(c.opirr(a), uint32(v), r, p.From.Reg)
1492 }
1493
1494 case 30:
1495 a := SP(2, 1) | (4 << 21)
1496 o1 = OP_RRR(a, p.From.Reg, obj.REG_NONE, p.To.Reg)
1497
1498 case 31:
1499 a := SP(2, 1) | (0 << 21)
1500 o1 = OP_RRR(a, p.To.Reg, obj.REG_NONE, p.From.Reg)
1501
1502 case 32:
1503 r := p.Reg
1504 if r == obj.REG_NONE {
1505 r = p.To.Reg
1506 }
1507 o1 = OP_FRRR(c.oprrr(p.As), p.From.Reg, r, p.To.Reg)
1508
1509 case 33:
1510 o1 = OP_FRRR(c.oprrr(p.As), obj.REG_NONE, p.From.Reg, p.To.Reg)
1511
1512 case 34:
1513 a := AADDU
1514 if o.a1 == C_ANDCON {
1515 a = AOR
1516 }
1517 v := c.regoff(&p.From)
1518 o1 = OP_IRR(c.opirr(a), uint32(v), obj.REG_NONE, REGTMP)
1519 o2 = OP_RRR(SP(2, 1)|(4<<21), REGTMP, obj.REG_NONE, p.To.Reg)
1520
1521 case 35:
1522 r := p.To.Reg
1523 if r == obj.REG_NONE {
1524 r = o.param
1525 }
1526 v := c.regoff(&p.To)
1527 o1 = OP_IRR(c.opirr(ALUI), uint32((v+1<<15)>>16), REGZERO, REGTMP)
1528 o2 = OP_RRR(c.oprrr(add), r, REGTMP, REGTMP)
1529 o3 = OP_IRR(c.opirr(p.As), uint32(v), REGTMP, p.From.Reg)
1530
1531 case 36:
1532 r := p.From.Reg
1533 if r == obj.REG_NONE {
1534 r = o.param
1535 }
1536 v := c.regoff(&p.From)
1537 o1 = OP_IRR(c.opirr(ALUI), uint32((v+1<<15)>>16), REGZERO, REGTMP)
1538 o2 = OP_RRR(c.oprrr(add), r, REGTMP, REGTMP)
1539 o3 = OP_IRR(c.opirr(-p.As), uint32(v), REGTMP, p.To.Reg)
1540
1541 case 37:
1542 a := SP(2, 0) | (4 << 21)
1543 if p.As == AMOVV {
1544 a = SP(2, 0) | (5 << 21)
1545 }
1546 o1 = OP_RRR(a, p.From.Reg, obj.REG_NONE, p.To.Reg)
1547
1548 case 38:
1549 a := SP(2, 0) | (0 << 21)
1550 if p.As == AMOVV {
1551 a = SP(2, 0) | (1 << 21)
1552 }
1553 o1 = OP_RRR(a, p.To.Reg, obj.REG_NONE, p.From.Reg)
1554
1555 case 40:
1556 o1 = uint32(c.regoff(&p.From))
1557
1558 case 41:
1559 o1 = OP_RRR(SP(2, 1)|(6<<21), p.From.Reg, obj.REG_NONE, p.To.Reg)
1560
1561 case 42:
1562 o1 = OP_RRR(SP(2, 1)|(2<<21), p.To.Reg, obj.REG_NONE, p.From.Reg)
1563
1564 case 47:
1565 a := SP(2, 1) | (5 << 21)
1566 o1 = OP_RRR(a, p.From.Reg, obj.REG_NONE, p.To.Reg)
1567
1568 case 48:
1569 a := SP(2, 1) | (1 << 21)
1570 o1 = OP_RRR(a, p.To.Reg, obj.REG_NONE, p.From.Reg)
1571
1572 case 49:
1573 o1 = 52
1574
1575
1576 case 50:
1577 o1 = OP_IRR(c.opirr(ALUI), 0, REGZERO, REGTMP)
1578 rel := obj.Addrel(c.cursym)
1579 rel.Off = int32(c.pc)
1580 rel.Siz = 4
1581 rel.Sym = p.To.Sym
1582 rel.Add = p.To.Offset
1583 rel.Type = objabi.R_ADDRMIPSU
1584 o2 = OP_IRR(c.opirr(p.As), 0, REGTMP, p.From.Reg)
1585 rel2 := obj.Addrel(c.cursym)
1586 rel2.Off = int32(c.pc + 4)
1587 rel2.Siz = 4
1588 rel2.Sym = p.To.Sym
1589 rel2.Add = p.To.Offset
1590 rel2.Type = objabi.R_ADDRMIPS
1591
1592 if o.size == 12 {
1593 o3 = o2
1594 o2 = OP_RRR(c.oprrr(AADDVU), REGSB, REGTMP, REGTMP)
1595 rel2.Off += 4
1596 }
1597
1598 case 51:
1599 o1 = OP_IRR(c.opirr(ALUI), 0, REGZERO, REGTMP)
1600 rel := obj.Addrel(c.cursym)
1601 rel.Off = int32(c.pc)
1602 rel.Siz = 4
1603 rel.Sym = p.From.Sym
1604 rel.Add = p.From.Offset
1605 rel.Type = objabi.R_ADDRMIPSU
1606 o2 = OP_IRR(c.opirr(-p.As), 0, REGTMP, p.To.Reg)
1607 rel2 := obj.Addrel(c.cursym)
1608 rel2.Off = int32(c.pc + 4)
1609 rel2.Siz = 4
1610 rel2.Sym = p.From.Sym
1611 rel2.Add = p.From.Offset
1612 rel2.Type = objabi.R_ADDRMIPS
1613
1614 if o.size == 12 {
1615 o3 = o2
1616 o2 = OP_RRR(c.oprrr(AADDVU), REGSB, REGTMP, REGTMP)
1617 rel2.Off += 4
1618 }
1619
1620 case 52:
1621
1622
1623 o1 = OP_IRR(c.opirr(ALUI), 0, REGZERO, p.To.Reg)
1624 rel := obj.Addrel(c.cursym)
1625 rel.Off = int32(c.pc)
1626 rel.Siz = 4
1627 rel.Sym = p.From.Sym
1628 rel.Add = p.From.Offset
1629 rel.Type = objabi.R_ADDRMIPSU
1630 o2 = OP_IRR(c.opirr(add), 0, p.To.Reg, p.To.Reg)
1631 rel2 := obj.Addrel(c.cursym)
1632 rel2.Off = int32(c.pc + 4)
1633 rel2.Siz = 4
1634 rel2.Sym = p.From.Sym
1635 rel2.Add = p.From.Offset
1636 rel2.Type = objabi.R_ADDRMIPS
1637
1638 if o.size == 12 {
1639 o3 = o2
1640 o2 = OP_RRR(c.oprrr(AADDVU), REGSB, p.To.Reg, p.To.Reg)
1641 rel2.Off += 4
1642 }
1643
1644 case 53:
1645
1646
1647
1648
1649 o1 = (037<<26 + 073) | (29 << 11) | (3 << 16)
1650 o2 = OP_IRR(c.opirr(p.As), 0, REG_R3, p.From.Reg)
1651 rel := obj.Addrel(c.cursym)
1652 rel.Off = int32(c.pc + 4)
1653 rel.Siz = 4
1654 rel.Sym = p.To.Sym
1655 rel.Add = p.To.Offset
1656 rel.Type = objabi.R_ADDRMIPSTLS
1657
1658 case 54:
1659
1660
1661
1662 o1 = (037<<26 + 073) | (29 << 11) | (3 << 16)
1663 o2 = OP_IRR(c.opirr(-p.As), 0, REG_R3, p.To.Reg)
1664 rel := obj.Addrel(c.cursym)
1665 rel.Off = int32(c.pc + 4)
1666 rel.Siz = 4
1667 rel.Sym = p.From.Sym
1668 rel.Add = p.From.Offset
1669 rel.Type = objabi.R_ADDRMIPSTLS
1670
1671 case 55:
1672
1673
1674
1675 o1 = (037<<26 + 073) | (29 << 11) | (3 << 16)
1676 o2 = OP_IRR(c.opirr(add), 0, REG_R3, p.To.Reg)
1677 rel := obj.Addrel(c.cursym)
1678 rel.Off = int32(c.pc + 4)
1679 rel.Siz = 4
1680 rel.Sym = p.From.Sym
1681 rel.Add = p.From.Offset
1682 rel.Type = objabi.R_ADDRMIPSTLS
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