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