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 "github.com/twitchyliquid64/golang-asm/obj"
34 "github.com/twitchyliquid64/golang-asm/objabi"
35 "github.com/twitchyliquid64/golang-asm/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
1026 case ASLLV:
1027 opset(ASRAV, r0)
1028 opset(ASRLV, r0)
1029
1030 case ASUB:
1031 opset(ASUBU, r0)
1032 opset(ANOR, r0)
1033
1034 case ASUBV:
1035 opset(ASUBVU, r0)
1036
1037 case ASYSCALL:
1038 opset(ASYNC, r0)
1039 opset(ANOOP, r0)
1040 opset(ATLBP, r0)
1041 opset(ATLBR, r0)
1042 opset(ATLBWI, r0)
1043 opset(ATLBWR, r0)
1044
1045 case ACMPEQF:
1046 opset(ACMPGTF, r0)
1047 opset(ACMPGTD, r0)
1048 opset(ACMPGEF, r0)
1049 opset(ACMPGED, r0)
1050 opset(ACMPEQD, r0)
1051
1052 case ABFPT:
1053 opset(ABFPF, r0)
1054
1055 case AMOVWL:
1056 opset(AMOVWR, r0)
1057
1058 case AMOVVL:
1059 opset(AMOVVR, r0)
1060
1061 case AVMOVB:
1062 opset(AVMOVH, r0)
1063 opset(AVMOVW, r0)
1064 opset(AVMOVD, r0)
1065
1066 case AMOVW,
1067 AMOVD,
1068 AMOVF,
1069 AMOVV,
1070 ABREAK,
1071 ARFE,
1072 AJAL,
1073 AJMP,
1074 AMOVWU,
1075 ALL,
1076 ALLV,
1077 ASC,
1078 ASCV,
1079 ANEGW,
1080 ANEGV,
1081 AWORD,
1082 obj.ANOP,
1083 obj.ATEXT,
1084 obj.AUNDEF,
1085 obj.AFUNCDATA,
1086 obj.APCDATA,
1087 obj.ADUFFZERO,
1088 obj.ADUFFCOPY:
1089 break
1090
1091 case ACMOVN:
1092 opset(ACMOVZ, r0)
1093
1094 case ACMOVT:
1095 opset(ACMOVF, r0)
1096
1097 case ACLO:
1098 opset(ACLZ, r0)
1099
1100 case ATEQ:
1101 opset(ATNE, r0)
1102 }
1103 }
1104 }
1105
1106 func OP(x uint32, y uint32) uint32 {
1107 return x<<3 | y<<0
1108 }
1109
1110 func SP(x uint32, y uint32) uint32 {
1111 return x<<29 | y<<26
1112 }
1113
1114 func BCOND(x uint32, y uint32) uint32 {
1115 return x<<19 | y<<16
1116 }
1117
1118 func MMU(x uint32, y uint32) uint32 {
1119 return SP(2, 0) | 16<<21 | x<<3 | y<<0
1120 }
1121
1122 func FPF(x uint32, y uint32) uint32 {
1123 return SP(2, 1) | 16<<21 | x<<3 | y<<0
1124 }
1125
1126 func FPD(x uint32, y uint32) uint32 {
1127 return SP(2, 1) | 17<<21 | x<<3 | y<<0
1128 }
1129
1130 func FPW(x uint32, y uint32) uint32 {
1131 return SP(2, 1) | 20<<21 | x<<3 | y<<0
1132 }
1133
1134 func FPV(x uint32, y uint32) uint32 {
1135 return SP(2, 1) | 21<<21 | x<<3 | y<<0
1136 }
1137
1138 func OP_RRR(op uint32, r1 uint32, r2 uint32, r3 uint32) uint32 {
1139 return op | (r1&31)<<16 | (r2&31)<<21 | (r3&31)<<11
1140 }
1141
1142 func OP_IRR(op uint32, i uint32, r2 uint32, r3 uint32) uint32 {
1143 return op | i&0xFFFF | (r2&31)<<21 | (r3&31)<<16
1144 }
1145
1146 func OP_SRR(op uint32, s uint32, r2 uint32, r3 uint32) uint32 {
1147 return op | (s&31)<<6 | (r2&31)<<16 | (r3&31)<<11
1148 }
1149
1150 func OP_FRRR(op uint32, r1 uint32, r2 uint32, r3 uint32) uint32 {
1151 return op | (r1&31)<<16 | (r2&31)<<11 | (r3&31)<<6
1152 }
1153
1154 func OP_JMP(op uint32, i uint32) uint32 {
1155 return op | i&0x3FFFFFF
1156 }
1157
1158 func OP_VI10(op uint32, df uint32, s10 int32, wd uint32, minor uint32) uint32 {
1159 return 0x1e<<26 | (op&7)<<23 | (df&3)<<21 | uint32(s10&0x3FF)<<11 | (wd&31)<<6 | minor&0x3F
1160 }
1161
1162 func OP_VMI10(s10 int32, rs uint32, wd uint32, minor uint32, df uint32) uint32 {
1163 return 0x1e<<26 | uint32(s10&0x3FF)<<16 | (rs&31)<<11 | (wd&31)<<6 | (minor&15)<<2 | df&3
1164 }
1165
1166 func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
1167 o1 := uint32(0)
1168 o2 := uint32(0)
1169 o3 := uint32(0)
1170 o4 := uint32(0)
1171
1172 add := AADDU
1173
1174 if c.ctxt.Arch.Family == sys.MIPS64 {
1175 add = AADDVU
1176 }
1177 switch o.type_ {
1178 default:
1179 c.ctxt.Diag("unknown type %d %v", o.type_)
1180 prasm(p)
1181
1182 case 0:
1183 break
1184
1185 case 1:
1186 a := AOR
1187 if p.As == AMOVW && c.ctxt.Arch.Family == sys.MIPS64 {
1188
1189
1190 a = ASLL
1191 }
1192 o1 = OP_RRR(c.oprrr(a), uint32(p.From.Reg), uint32(REGZERO), uint32(p.To.Reg))
1193
1194 case 2:
1195 r := int(p.Reg)
1196 if p.As == ANEGW || p.As == ANEGV {
1197 r = REGZERO
1198 }
1199 if r == 0 {
1200 r = int(p.To.Reg)
1201 }
1202 o1 = OP_RRR(c.oprrr(p.As), uint32(p.From.Reg), uint32(r), uint32(p.To.Reg))
1203
1204 case 3:
1205 v := c.regoff(&p.From)
1206
1207 r := int(p.From.Reg)
1208 if r == 0 {
1209 r = int(o.param)
1210 }
1211 a := add
1212 if o.a1 == C_ANDCON {
1213 a = AOR
1214 }
1215
1216 o1 = OP_IRR(c.opirr(a), uint32(v), uint32(r), uint32(p.To.Reg))
1217
1218 case 4:
1219 v := c.regoff(&p.From)
1220
1221 r := int(p.Reg)
1222 if r == 0 {
1223 r = int(p.To.Reg)
1224 }
1225
1226 o1 = OP_IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg))
1227
1228 case 5:
1229 o1 = c.oprrr(p.As)
1230
1231 case 6:
1232 v := int32(0)
1233 if p.To.Target() == nil {
1234 v = int32(-4) >> 2
1235 } else {
1236 v = int32(p.To.Target().Pc-p.Pc-4) >> 2
1237 }
1238 if (v<<16)>>16 != v {
1239 c.ctxt.Diag("short branch too far\n%v", p)
1240 }
1241 o1 = OP_IRR(c.opirr(p.As), uint32(v), uint32(p.From.Reg), uint32(p.Reg))
1242
1243
1244 o2 = 0
1245
1246 case 7:
1247 r := int(p.To.Reg)
1248 if r == 0 {
1249 r = int(o.param)
1250 }
1251 v := c.regoff(&p.To)
1252 o1 = OP_IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.From.Reg))
1253
1254 case 8:
1255 r := int(p.From.Reg)
1256 if r == 0 {
1257 r = int(o.param)
1258 }
1259 v := c.regoff(&p.From)
1260 o1 = OP_IRR(c.opirr(-p.As), uint32(v), uint32(r), uint32(p.To.Reg))
1261
1262 case 9:
1263 r := int(p.Reg)
1264
1265 if r == 0 {
1266 r = int(p.To.Reg)
1267 }
1268 o1 = OP_RRR(c.oprrr(p.As), uint32(r), uint32(p.From.Reg), uint32(p.To.Reg))
1269
1270 case 10:
1271 v := c.regoff(&p.From)
1272 a := AOR
1273 if v < 0 {
1274 a = AADDU
1275 }
1276 o1 = OP_IRR(c.opirr(a), uint32(v), uint32(0), uint32(REGTMP))
1277 r := int(p.Reg)
1278 if r == 0 {
1279 r = int(p.To.Reg)
1280 }
1281 o2 = OP_RRR(c.oprrr(p.As), uint32(REGTMP), uint32(r), uint32(p.To.Reg))
1282
1283 case 11:
1284 v := int32(0)
1285 if c.aclass(&p.To) == C_SBRA && p.To.Sym == nil && p.As == AJMP {
1286
1287
1288 if p.To.Target() == nil {
1289 v = int32(-4) >> 2
1290 } else {
1291 v = int32(p.To.Target().Pc-p.Pc-4) >> 2
1292 }
1293 if (v<<16)>>16 == v {
1294 o1 = OP_IRR(c.opirr(ABEQ), uint32(v), uint32(REGZERO), uint32(REGZERO))
1295 break
1296 }
1297 }
1298 if p.To.Target() == nil {
1299 v = int32(p.Pc) >> 2
1300 } else {
1301 v = int32(p.To.Target().Pc) >> 2
1302 }
1303 o1 = OP_JMP(c.opirr(p.As), uint32(v))
1304 if p.To.Sym == nil {
1305 p.To.Sym = c.cursym.Func.Text.From.Sym
1306 p.To.Offset = p.To.Target().Pc
1307 }
1308 rel := obj.Addrel(c.cursym)
1309 rel.Off = int32(c.pc)
1310 rel.Siz = 4
1311 rel.Sym = p.To.Sym
1312 rel.Add = p.To.Offset
1313 if p.As == AJAL {
1314 rel.Type = objabi.R_CALLMIPS
1315 } else {
1316 rel.Type = objabi.R_JMPMIPS
1317 }
1318
1319 case 12:
1320
1321
1322 v := 16
1323 if p.As == AMOVB {
1324 v = 24
1325 }
1326 o1 = OP_SRR(c.opirr(ASLL), uint32(v), uint32(p.From.Reg), uint32(p.To.Reg))
1327 o2 = OP_SRR(c.opirr(ASRA), uint32(v), uint32(p.To.Reg), uint32(p.To.Reg))
1328
1329 case 13:
1330 if p.As == AMOVBU {
1331 o1 = OP_IRR(c.opirr(AAND), uint32(0xff), uint32(p.From.Reg), uint32(p.To.Reg))
1332 } else {
1333 o1 = OP_IRR(c.opirr(AAND), uint32(0xffff), uint32(p.From.Reg), uint32(p.To.Reg))
1334 }
1335
1336 case 14:
1337
1338
1339 o1 = OP_SRR(c.opirr(-ASLLV), uint32(0), uint32(p.From.Reg), uint32(p.To.Reg))
1340 o2 = OP_SRR(c.opirr(-ASRLV), uint32(0), uint32(p.To.Reg), uint32(p.To.Reg))
1341
1342 case 15:
1343 v := c.regoff(&p.From)
1344 r := int(p.Reg)
1345 if r == 0 {
1346 r = REGZERO
1347 }
1348
1349 o1 = OP_IRR(c.opirr(p.As), (uint32(v)&0x3FF)<<6, uint32(r), uint32(p.To.Reg))
1350
1351 case 16:
1352 v := c.regoff(&p.From)
1353 r := int(p.Reg)
1354 if r == 0 {
1355 r = int(p.To.Reg)
1356 }
1357
1358
1359 if v >= 32 && vshift(p.As) {
1360 o1 = OP_SRR(c.opirr(-p.As), uint32(v-32), uint32(r), uint32(p.To.Reg))
1361 } else {
1362 o1 = OP_SRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg))
1363 }
1364
1365 case 17:
1366 o1 = OP_RRR(c.oprrr(p.As), uint32(REGZERO), uint32(p.From.Reg), uint32(p.To.Reg))
1367
1368 case 18:
1369 r := int(p.Reg)
1370 if r == 0 {
1371 r = int(o.param)
1372 }
1373 o1 = OP_RRR(c.oprrr(p.As), uint32(0), uint32(p.To.Reg), uint32(r))
1374 if p.As == obj.ACALL {
1375 rel := obj.Addrel(c.cursym)
1376 rel.Off = int32(c.pc)
1377 rel.Siz = 0
1378 rel.Type = objabi.R_CALLIND
1379 }
1380
1381 case 19:
1382
1383
1384 v := c.regoff(&p.From)
1385 o1 = OP_IRR(c.opirr(ALUI), uint32(v>>16), uint32(REGZERO), uint32(p.To.Reg))
1386 o2 = OP_IRR(c.opirr(AOR), uint32(v), uint32(p.To.Reg), uint32(p.To.Reg))
1387
1388 case 20:
1389 a := OP(2, 0)
1390 if p.From.Reg == REG_LO {
1391 a = OP(2, 2)
1392 }
1393 o1 = OP_RRR(a, uint32(REGZERO), uint32(REGZERO), uint32(p.To.Reg))
1394
1395 case 21:
1396 a := OP(2, 1)
1397 if p.To.Reg == REG_LO {
1398 a = OP(2, 3)
1399 }
1400 o1 = OP_RRR(a, uint32(REGZERO), uint32(p.From.Reg), uint32(REGZERO))
1401
1402 case 22:
1403 if p.To.Reg != 0 {
1404 r := int(p.Reg)
1405 if r == 0 {
1406 r = int(p.To.Reg)
1407 }
1408 a := SP(3, 4) | 2
1409 o1 = OP_RRR(a, uint32(p.From.Reg), uint32(r), uint32(p.To.Reg))
1410 } else {
1411 o1 = OP_RRR(c.oprrr(p.As), uint32(p.From.Reg), uint32(p.Reg), uint32(REGZERO))
1412 }
1413
1414 case 23:
1415 v := c.regoff(&p.From)
1416 o1 = OP_IRR(c.opirr(ALUI), uint32(v>>16), uint32(REGZERO), uint32(REGTMP))
1417 o2 = OP_IRR(c.opirr(AOR), uint32(v), uint32(REGTMP), uint32(REGTMP))
1418 r := int(p.Reg)
1419 if r == 0 {
1420 r = int(p.To.Reg)
1421 }
1422 o3 = OP_RRR(c.oprrr(p.As), uint32(REGTMP), uint32(r), uint32(p.To.Reg))
1423
1424 case 24:
1425 v := c.regoff(&p.From)
1426 o1 = OP_IRR(c.opirr(ALUI), uint32(v>>16), uint32(REGZERO), uint32(p.To.Reg))
1427
1428 case 25:
1429 v := c.regoff(&p.From)
1430 o1 = OP_IRR(c.opirr(ALUI), uint32(v>>16), uint32(REGZERO), uint32(REGTMP))
1431 r := int(p.Reg)
1432 if r == 0 {
1433 r = int(p.To.Reg)
1434 }
1435 o2 = OP_RRR(c.oprrr(p.As), uint32(REGTMP), uint32(r), uint32(p.To.Reg))
1436
1437 case 26:
1438 v := c.regoff(&p.From)
1439 o1 = OP_IRR(c.opirr(ALUI), uint32(v>>16), uint32(REGZERO), uint32(REGTMP))
1440 o2 = OP_IRR(c.opirr(AOR), uint32(v), uint32(REGTMP), uint32(REGTMP))
1441 r := int(p.From.Reg)
1442 if r == 0 {
1443 r = int(o.param)
1444 }
1445 o3 = OP_RRR(c.oprrr(add), uint32(REGTMP), uint32(r), uint32(p.To.Reg))
1446
1447 case 27:
1448 v := c.regoff(&p.From)
1449 r := int(p.From.Reg)
1450 if r == 0 {
1451 r = int(o.param)
1452 }
1453 a := -AMOVF
1454 if p.As == AMOVD {
1455 a = -AMOVD
1456 }
1457 switch o.size {
1458 case 12:
1459 o1 = OP_IRR(c.opirr(ALUI), uint32((v+1<<15)>>16), uint32(REGZERO), uint32(REGTMP))
1460 o2 = OP_RRR(c.oprrr(add), uint32(r), uint32(REGTMP), uint32(REGTMP))
1461 o3 = OP_IRR(c.opirr(a), uint32(v), uint32(REGTMP), uint32(p.To.Reg))
1462
1463 case 4:
1464 o1 = OP_IRR(c.opirr(a), uint32(v), uint32(r), uint32(p.To.Reg))
1465 }
1466
1467 case 28:
1468 v := c.regoff(&p.To)
1469 r := int(p.To.Reg)
1470 if r == 0 {
1471 r = int(o.param)
1472 }
1473 a := AMOVF
1474 if p.As == AMOVD {
1475 a = AMOVD
1476 }
1477 switch o.size {
1478 case 12:
1479 o1 = OP_IRR(c.opirr(ALUI), uint32((v+1<<15)>>16), uint32(REGZERO), uint32(REGTMP))
1480 o2 = OP_RRR(c.oprrr(add), uint32(r), uint32(REGTMP), uint32(REGTMP))
1481 o3 = OP_IRR(c.opirr(a), uint32(v), uint32(REGTMP), uint32(p.From.Reg))
1482
1483 case 4:
1484 o1 = OP_IRR(c.opirr(a), uint32(v), uint32(r), uint32(p.From.Reg))
1485 }
1486
1487 case 30:
1488 a := SP(2, 1) | (4 << 21)
1489 o1 = OP_RRR(a, uint32(p.From.Reg), uint32(0), uint32(p.To.Reg))
1490
1491 case 31:
1492 a := SP(2, 1) | (0 << 21)
1493 o1 = OP_RRR(a, uint32(p.To.Reg), uint32(0), uint32(p.From.Reg))
1494
1495 case 32:
1496 r := int(p.Reg)
1497 if r == 0 {
1498 r = int(p.To.Reg)
1499 }
1500 o1 = OP_FRRR(c.oprrr(p.As), uint32(p.From.Reg), uint32(r), uint32(p.To.Reg))
1501
1502 case 33:
1503 o1 = OP_FRRR(c.oprrr(p.As), uint32(0), uint32(p.From.Reg), uint32(p.To.Reg))
1504
1505 case 34:
1506 v := c.regoff(&p.From)
1507 a := AADDU
1508 if o.a1 == C_ANDCON {
1509 a = AOR
1510 }
1511 o1 = OP_IRR(c.opirr(a), uint32(v), uint32(0), uint32(REGTMP))
1512 o2 = OP_RRR(SP(2, 1)|(4<<21), uint32(REGTMP), uint32(0), uint32(p.To.Reg))
1513
1514 case 35:
1515 v := c.regoff(&p.To)
1516 r := int(p.To.Reg)
1517 if r == 0 {
1518 r = int(o.param)
1519 }
1520 o1 = OP_IRR(c.opirr(ALUI), uint32((v+1<<15)>>16), uint32(REGZERO), uint32(REGTMP))
1521 o2 = OP_RRR(c.oprrr(add), uint32(r), uint32(REGTMP), uint32(REGTMP))
1522 o3 = OP_IRR(c.opirr(p.As), uint32(v), uint32(REGTMP), uint32(p.From.Reg))
1523
1524 case 36:
1525 v := c.regoff(&p.From)
1526 r := int(p.From.Reg)
1527 if r == 0 {
1528 r = int(o.param)
1529 }
1530 o1 = OP_IRR(c.opirr(ALUI), uint32((v+1<<15)>>16), uint32(REGZERO), uint32(REGTMP))
1531 o2 = OP_RRR(c.oprrr(add), uint32(r), uint32(REGTMP), uint32(REGTMP))
1532 o3 = OP_IRR(c.opirr(-p.As), uint32(v), uint32(REGTMP), uint32(p.To.Reg))
1533
1534 case 37:
1535 a := SP(2, 0) | (4 << 21)
1536 if p.As == AMOVV {
1537 a = SP(2, 0) | (5 << 21)
1538 }
1539 o1 = OP_RRR(a, uint32(p.From.Reg), uint32(0), uint32(p.To.Reg))
1540
1541 case 38:
1542 a := SP(2, 0) | (0 << 21)
1543 if p.As == AMOVV {
1544 a = SP(2, 0) | (1 << 21)
1545 }
1546 o1 = OP_RRR(a, uint32(p.To.Reg), uint32(0), uint32(p.From.Reg))
1547
1548 case 40:
1549 o1 = uint32(c.regoff(&p.From))
1550
1551 case 41:
1552 o1 = OP_RRR(SP(2, 1)|(6<<21), uint32(p.From.Reg), uint32(0), uint32(p.To.Reg))
1553
1554 case 42:
1555 o1 = OP_RRR(SP(2, 1)|(2<<21), uint32(p.To.Reg), uint32(0), uint32(p.From.Reg))
1556
1557 case 47:
1558 a := SP(2, 1) | (5 << 21)
1559 o1 = OP_RRR(a, uint32(p.From.Reg), uint32(0), uint32(p.To.Reg))
1560
1561 case 48:
1562 a := SP(2, 1) | (1 << 21)
1563 o1 = OP_RRR(a, uint32(p.To.Reg), uint32(0), uint32(p.From.Reg))
1564
1565 case 49:
1566 o1 = 52
1567
1568
1569 case 50:
1570 o1 = OP_IRR(c.opirr(ALUI), uint32(0), uint32(REGZERO), uint32(REGTMP))
1571 rel := obj.Addrel(c.cursym)
1572 rel.Off = int32(c.pc)
1573 rel.Siz = 4
1574 rel.Sym = p.To.Sym
1575 rel.Add = p.To.Offset
1576 rel.Type = objabi.R_ADDRMIPSU
1577 o2 = OP_IRR(c.opirr(p.As), uint32(0), uint32(REGTMP), uint32(p.From.Reg))
1578 rel2 := obj.Addrel(c.cursym)
1579 rel2.Off = int32(c.pc + 4)
1580 rel2.Siz = 4
1581 rel2.Sym = p.To.Sym
1582 rel2.Add = p.To.Offset
1583 rel2.Type = objabi.R_ADDRMIPS
1584
1585 if o.size == 12 {
1586 o3 = o2
1587 o2 = OP_RRR(c.oprrr(AADDVU), uint32(REGSB), uint32(REGTMP), uint32(REGTMP))
1588 rel2.Off += 4
1589 }
1590
1591 case 51:
1592 o1 = OP_IRR(c.opirr(ALUI), uint32(0), uint32(REGZERO), uint32(REGTMP))
1593 rel := obj.Addrel(c.cursym)
1594 rel.Off = int32(c.pc)
1595 rel.Siz = 4
1596 rel.Sym = p.From.Sym
1597 rel.Add = p.From.Offset
1598 rel.Type = objabi.R_ADDRMIPSU
1599 o2 = OP_IRR(c.opirr(-p.As), uint32(0), uint32(REGTMP), uint32(p.To.Reg))
1600 rel2 := obj.Addrel(c.cursym)
1601 rel2.Off = int32(c.pc + 4)
1602 rel2.Siz = 4
1603 rel2.Sym = p.From.Sym
1604 rel2.Add = p.From.Offset
1605 rel2.Type = objabi.R_ADDRMIPS
1606
1607 if o.size == 12 {
1608 o3 = o2
1609 o2 = OP_RRR(c.oprrr(AADDVU), uint32(REGSB), uint32(REGTMP), uint32(REGTMP))
1610 rel2.Off += 4
1611 }
1612
1613 case 52:
1614
1615
1616 o1 = OP_IRR(c.opirr(ALUI), uint32(0), uint32(REGZERO), uint32(p.To.Reg))
1617 rel := obj.Addrel(c.cursym)
1618 rel.Off = int32(c.pc)
1619 rel.Siz = 4
1620 rel.Sym = p.From.Sym
1621 rel.Add = p.From.Offset
1622 rel.Type = objabi.R_ADDRMIPSU
1623 o2 = OP_IRR(c.opirr(add), uint32(0), uint32(p.To.Reg), uint32(p.To.Reg))
1624 rel2 := obj.Addrel(c.cursym)
1625 rel2.Off = int32(c.pc + 4)
1626 rel2.Siz = 4
1627 rel2.Sym = p.From.Sym
1628 rel2.Add = p.From.Offset
1629 rel2.Type = objabi.R_ADDRMIPS
1630
1631 if o.size == 12 {
1632 o3 = o2
1633 o2 = OP_RRR(c.oprrr(AADDVU), uint32(REGSB), uint32(p.To.Reg), uint32(p.To.Reg))
1634 rel2.Off += 4
1635 }
1636
1637 case 53:
1638
1639
1640
1641
1642 o1 = (037<<26 + 073) | (29 << 11) | (3 << 16)
1643 o2 = OP_IRR(c.opirr(p.As), uint32(0), uint32(REG_R3), uint32(p.From.Reg))
1644 rel := obj.Addrel(c.cursym)
1645 rel.Off = int32(c.pc + 4)
1646 rel.Siz = 4
1647 rel.Sym = p.To.Sym
1648 rel.Add = p.To.Offset
1649 rel.Type = objabi.R_ADDRMIPSTLS
1650
1651 case 54:
1652
1653
1654
1655 o1 = (037<<26 + 073) | (29 << 11) | (3 << 16)
1656 o2 = OP_IRR(c.opirr(-p.As), uint32(0), uint32(REG_R3), uint32(p.To.Reg))
1657 rel := obj.Addrel(c.cursym)
1658 rel.Off = int32(c.pc + 4)
1659 rel.Siz = 4
1660 rel.Sym = p.From.Sym
1661 rel.Add = p.From.Offset
1662 rel.Type = objabi.R_ADDRMIPSTLS
1663
1664 case 55:
1665
1666
1667
1668 o1 = (037<<26 + 073) | (29 << 11) | (3 << 16)
1669 o2 = OP_IRR(c.opirr(add), uint32(0), uint32(REG_R3), uint32(p.To.Reg))
1670 rel := obj.Addrel(c.cursym)
1671 rel.Off = int32(c.pc + 4)
1672 rel.Siz = 4
1673 rel.Sym = p.From.Sym
1674 rel.Add = p.From.Offset
1675 rel.Type = objabi.R_ADDRMIPSTLS
1676
1677 case 56:
1678
1679 v := c.regoff(&p.From)
1680 o1 = OP_VI10(110, c.twobitdf(p.As), v, uint32(p.To.Reg), 7)
1681
1682 case 57:
1683 v := c.lsoffset(p.As, c.regoff(&p.From))
1684 o1 = OP_VMI10(v, uint32(p.From.Reg), uint32(p.To.Reg), 8, c.twobitdf(p.As))
1685
1686 case 58:
1687 v := c.lsoffset(p.As, c.regoff(&p.To))
1688 o1 = OP_VMI10(v, uint32(p.To.Reg), uint32(p.From.Reg), 9, c.twobitdf(p.As))
1689 }
1690
1691 out[0] = o1
1692 out[1] = o2
1693 out[2] = o3
1694 out[3] = o4
1695 }
1696
1697 func (c *ctxt0) vregoff(a *obj.Addr) int64 {
1698 c.instoffset = 0
1699 c.aclass(a)
1700 return c.instoffset
1701 }
1702
1703 func (c *ctxt0) regoff(a *obj.Addr) int32 {
1704 return int32(c.vregoff(a))
1705 }
1706
1707 func (c *ctxt0) oprrr(a obj.As) uint32 {
1708 switch a {
1709 case AADD:
1710 return OP(4, 0)
1711 case AADDU:
1712 return OP(4, 1)
1713 case ASGT:
1714 return OP(5, 2)
1715 case ASGTU:
1716 return OP(5, 3)
1717 case AAND:
1718 return OP(4, 4)
1719 case AOR:
1720 return OP(4, 5)
1721 case AXOR:
1722 return OP(4, 6)
1723 case ASUB:
1724 return OP(4, 2)
1725 case ASUBU, ANEGW:
1726 return OP(4, 3)
1727 case ANOR:
1728 return OP(4, 7)
1729 case ASLL:
1730 return OP(0, 4)
1731 case ASRL:
1732 return OP(0, 6)
1733 case ASRA:
1734 return OP(0, 7)
1735 case ASLLV:
1736 return OP(2, 4)
1737 case ASRLV:
1738 return OP(2, 6)
1739 case ASRAV:
1740 return OP(2, 7)
1741 case AADDV:
1742 return OP(5, 4)
1743 case AADDVU:
1744 return OP(5, 5)
1745 case ASUBV:
1746 return OP(5, 6)
1747 case ASUBVU, ANEGV:
1748 return OP(5, 7)
1749 case AREM,
1750 ADIV:
1751 return OP(3, 2)
1752 case AREMU,
1753 ADIVU:
1754 return OP(3, 3)
1755 case AMUL:
1756 return OP(3, 0)
1757 case AMULU:
1758 return OP(3, 1)
1759 case AREMV,
1760 ADIVV:
1761 return OP(3, 6)
1762 case AREMVU,
1763 ADIVVU:
1764 return OP(3, 7)
1765 case AMULV:
1766 return OP(3, 4)
1767 case AMULVU:
1768 return OP(3, 5)
1769
1770 case AJMP:
1771 return OP(1, 0)
1772 case AJAL:
1773 return OP(1, 1)
1774
1775 case ABREAK:
1776 return OP(1, 5)
1777 case ASYSCALL:
1778 return OP(1, 4)
1779 case ATLBP:
1780 return MMU(1, 0)
1781 case ATLBR:
1782 return MMU(0, 1)
1783 case ATLBWI:
1784 return MMU(0, 2)
1785 case ATLBWR:
1786 return MMU(0, 6)
1787 case ARFE:
1788 return MMU(2, 0)
1789
1790 case ADIVF:
1791 return FPF(0, 3)
1792 case ADIVD:
1793 return FPD(0, 3)
1794 case AMULF:
1795 return FPF(0, 2)
1796 case AMULD:
1797 return FPD(0, 2)
1798 case ASUBF:
1799 return FPF(0, 1)
1800 case ASUBD:
1801 return FPD(0, 1)
1802 case AADDF:
1803 return FPF(0, 0)
1804 case AADDD:
1805 return FPD(0, 0)
1806 case ATRUNCFV:
1807 return FPF(1, 1)
1808 case ATRUNCDV:
1809 return FPD(1, 1)
1810 case ATRUNCFW:
1811 return FPF(1, 5)
1812 case ATRUNCDW:
1813 return FPD(1, 5)
1814 case AMOVFV:
1815 return FPF(4, 5)
1816 case AMOVDV:
1817 return FPD(4, 5)
1818 case AMOVVF:
1819 return FPV(4, 0)
1820 case AMOVVD:
1821 return FPV(4, 1)
1822 case AMOVFW:
1823 return FPF(4, 4)
1824 case AMOVDW:
1825 return FPD(4, 4)
1826 case AMOVWF:
1827 return FPW(4, 0)
1828 case AMOVDF:
1829 return FPD(4, 0)
1830 case AMOVWD:
1831 return FPW(4, 1)
1832 case AMOVFD:
1833 return FPF(4, 1)
1834 case AABSF:
1835 return FPF(0, 5)
1836 case AABSD:
1837 return FPD(0, 5)
1838 case AMOVF:
1839 return FPF(0, 6)
1840 case AMOVD:
1841 return FPD(0, 6)
1842 case ANEGF:
1843 return FPF(0, 7)
1844 case ANEGD:
1845 return FPD(0, 7)
1846 case ACMPEQF:
1847 return FPF(6, 2)
1848 case ACMPEQD:
1849 return FPD(6, 2)
1850 case ACMPGTF:
1851 return FPF(7, 4)
1852 case ACMPGTD:
1853 return FPD(7, 4)
1854 case ACMPGEF:
1855 return FPF(7, 6)
1856 case ACMPGED:
1857 return FPD(7, 6)
1858
1859 case ASQRTF:
1860 return FPF(0, 4)
1861 case ASQRTD:
1862 return FPD(0, 4)
1863
1864 case ASYNC:
1865 return OP(1, 7)
1866 case ANOOP:
1867 return 0
1868
1869 case ACMOVN:
1870 return OP(1, 3)
1871 case ACMOVZ:
1872 return OP(1, 2)
1873 case ACMOVT:
1874 return OP(0, 1) | (1 << 16)
1875 case ACMOVF:
1876 return OP(0, 1) | (0 << 16)
1877 case ACLO:
1878 return SP(3, 4) | OP(4, 1)
1879 case ACLZ:
1880 return SP(3, 4) | OP(4, 0)
1881 case AMADD:
1882 return SP(3, 4) | OP(0, 0)
1883 case AMSUB:
1884 return SP(3, 4) | OP(0, 4)
1885 }
1886
1887 if a < 0 {
1888 c.ctxt.Diag("bad rrr opcode -%v", -a)
1889 } else {
1890 c.ctxt.Diag("bad rrr opcode %v", a)
1891 }
1892 return 0
1893 }
1894
1895 func (c *ctxt0) opirr(a obj.As) uint32 {
1896 switch a {
1897 case AADD:
1898 return SP(1, 0)
1899 case AADDU:
1900 return SP(1, 1)
1901 case ASGT:
1902 return SP(1, 2)
1903 case ASGTU:
1904 return SP(1, 3)
1905 case AAND:
1906 return SP(1, 4)
1907 case AOR:
1908 return SP(1, 5)
1909 case AXOR:
1910 return SP(1, 6)
1911 case ALUI:
1912 return SP(1, 7)
1913 case ASLL:
1914 return OP(0, 0)
1915 case ASRL:
1916 return OP(0, 2)
1917 case ASRA:
1918 return OP(0, 3)
1919 case AADDV:
1920 return SP(3, 0)
1921 case AADDVU:
1922 return SP(3, 1)
1923
1924 case AJMP:
1925 return SP(0, 2)
1926 case AJAL,
1927 obj.ADUFFZERO,
1928 obj.ADUFFCOPY:
1929 return SP(0, 3)
1930 case ABEQ:
1931 return SP(0, 4)
1932 case -ABEQ:
1933 return SP(2, 4)
1934 case ABNE:
1935 return SP(0, 5)
1936 case -ABNE:
1937 return SP(2, 5)
1938 case ABGEZ:
1939 return SP(0, 1) | BCOND(0, 1)
1940 case -ABGEZ:
1941 return SP(0, 1) | BCOND(0, 3)
1942 case ABGEZAL:
1943 return SP(0, 1) | BCOND(2, 1)
1944 case -ABGEZAL:
1945 return SP(0, 1) | BCOND(2, 3)
1946 case ABGTZ:
1947 return SP(0, 7)
1948 case -ABGTZ:
1949 return SP(2, 7)
1950 case ABLEZ:
1951 return SP(0, 6)
1952 case -ABLEZ:
1953 return SP(2, 6)
1954 case ABLTZ:
1955 return SP(0, 1) | BCOND(0, 0)
1956 case -ABLTZ:
1957 return SP(0, 1) | BCOND(0, 2)
1958 case ABLTZAL:
1959 return SP(0, 1) | BCOND(2, 0)
1960 case -ABLTZAL:
1961 return SP(0, 1) | BCOND(2, 2)
1962 case ABFPT:
1963 return SP(2, 1) | (257 << 16)
1964 case -ABFPT:
1965 return SP(2, 1) | (259 << 16)
1966 case ABFPF:
1967 return SP(2, 1) | (256 << 16)
1968 case -ABFPF:
1969 return SP(2, 1) | (258 << 16)
1970
1971 case AMOVB,
1972 AMOVBU:
1973 return SP(5, 0)
1974 case AMOVH,
1975 AMOVHU:
1976 return SP(5, 1)
1977 case AMOVW,
1978 AMOVWU:
1979 return SP(5, 3)
1980 case AMOVV:
1981 return SP(7, 7)
1982 case AMOVF:
1983 return SP(7, 1)
1984 case AMOVD:
1985 return SP(7, 5)
1986 case AMOVWL:
1987 return SP(5, 2)
1988 case AMOVWR:
1989 return SP(5, 6)
1990 case AMOVVL:
1991 return SP(5, 4)
1992 case AMOVVR:
1993 return SP(5, 5)
1994
1995 case ABREAK:
1996 return SP(5, 7)
1997
1998 case -AMOVWL:
1999 return SP(4, 2)
2000 case -AMOVWR:
2001 return SP(4, 6)
2002 case -AMOVVL:
2003 return SP(3, 2)
2004 case -AMOVVR:
2005 return SP(3, 3)
2006 case -AMOVB:
2007 return SP(4, 0)
2008 case -AMOVBU:
2009 return SP(4, 4)
2010 case -AMOVH:
2011 return SP(4, 1)
2012 case -AMOVHU:
2013 return SP(4, 5)
2014 case -AMOVW:
2015 return SP(4, 3)
2016 case -AMOVWU:
2017 return SP(4, 7)
2018 case -AMOVV:
2019 return SP(6, 7)
2020 case -AMOVF:
2021 return SP(6, 1)
2022 case -AMOVD:
2023 return SP(6, 5)
2024
2025 case ASLLV:
2026 return OP(7, 0)
2027 case ASRLV:
2028 return OP(7, 2)
2029 case ASRAV:
2030 return OP(7, 3)
2031 case -ASLLV:
2032 return OP(7, 4)
2033 case -ASRLV:
2034 return OP(7, 6)
2035 case -ASRAV:
2036 return OP(7, 7)
2037
2038 case ATEQ:
2039 return OP(6, 4)
2040 case ATNE:
2041 return OP(6, 6)
2042 case -ALL:
2043 return SP(6, 0)
2044 case -ALLV:
2045 return SP(6, 4)
2046 case ASC:
2047 return SP(7, 0)
2048 case ASCV:
2049 return SP(7, 4)
2050 }
2051
2052 if a < 0 {
2053 c.ctxt.Diag("bad irr opcode -%v", -a)
2054 } else {
2055 c.ctxt.Diag("bad irr opcode %v", a)
2056 }
2057 return 0
2058 }
2059
2060 func vshift(a obj.As) bool {
2061 switch a {
2062 case ASLLV,
2063 ASRLV,
2064 ASRAV:
2065 return true
2066 }
2067 return false
2068 }
2069
2070
2071 func (c *ctxt0) twobitdf(a obj.As) uint32 {
2072 switch a {
2073 case AVMOVB:
2074 return 0
2075 case AVMOVH:
2076 return 1
2077 case AVMOVW:
2078 return 2
2079 case AVMOVD:
2080 return 3
2081 default:
2082 c.ctxt.Diag("unsupported data format %v", a)
2083 }
2084 return 0
2085 }
2086
2087
2088 func (c *ctxt0) lsoffset(a obj.As, o int32) int32 {
2089 var mod int32
2090 switch a {
2091 case AVMOVB:
2092 mod = 1
2093 case AVMOVH:
2094 mod = 2
2095 case AVMOVW:
2096 mod = 4
2097 case AVMOVD:
2098 mod = 8
2099 default:
2100 c.ctxt.Diag("unsupported instruction:%v", a)
2101 }
2102
2103 if o%mod != 0 {
2104 c.ctxt.Diag("invalid offset for %v: %d is not a multiple of %d", a, o, mod)
2105 }
2106
2107 return o / mod
2108 }
2109
View as plain text