1
2
3
4
5 package loong64
6
7 import (
8 "cmd/internal/obj"
9 "cmd/internal/objabi"
10 "fmt"
11 "log"
12 "slices"
13 )
14
15
16
17
18 type ctxt0 struct {
19 ctxt *obj.Link
20 newprog obj.ProgAlloc
21 cursym *obj.LSym
22 autosize int32
23 instoffset int64
24 pc int64
25 }
26
27
28
29 const (
30 FuncAlign = 4
31 loopAlign = 16
32 )
33
34 type Optab struct {
35 as obj.As
36 from1 uint8
37 reg uint8
38 from3 uint8
39 to1 uint8
40 to2 uint8
41 type_ int8
42 size int8
43 param int16
44 flag uint8
45 }
46
47 const (
48 NOTUSETMP = 1 << iota
49
50
51
52 branchLoopHead
53 )
54
55 var optab = []Optab{
56 {obj.ATEXT, C_ADDR, C_NONE, C_NONE, C_TEXTSIZE, C_NONE, 0, 0, 0, 0},
57
58 {AMOVW, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 1, 4, 0, 0},
59 {AMOVV, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 1, 4, 0, 0},
60 {AMOVB, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 12, 8, 0, NOTUSETMP},
61 {AMOVBU, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 13, 4, 0, 0},
62 {AMOVWU, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 14, 8, 0, NOTUSETMP},
63
64 {ASUB, C_REG, C_REG, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
65 {ASUBV, C_REG, C_REG, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
66 {AADD, C_REG, C_REG, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
67 {AADDV, C_REG, C_REG, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
68 {AAND, C_REG, C_REG, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
69 {ASUB, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
70 {ASUBV, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
71 {AADD, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
72 {AADDV, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
73 {AAND, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
74 {ANEGW, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
75 {ANEGV, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
76 {AMASKEQZ, C_REG, C_REG, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
77 {ASLL, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
78 {ASLL, C_REG, C_REG, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
79 {ASLLV, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
80 {ASLLV, C_REG, C_REG, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
81 {AMUL, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
82 {AMUL, C_REG, C_REG, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
83 {AMULV, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
84 {AMULV, C_REG, C_REG, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
85 {AADDF, C_FREG, C_NONE, C_NONE, C_FREG, C_NONE, 2, 4, 0, 0},
86 {AADDF, C_FREG, C_FREG, C_NONE, C_FREG, C_NONE, 2, 4, 0, 0},
87 {ACMPEQF, C_FREG, C_FREG, C_NONE, C_FCCREG, C_NONE, 2, 4, 0, 0},
88
89 {ACLO, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 9, 4, 0, 0},
90 {AABSF, C_FREG, C_NONE, C_NONE, C_FREG, C_NONE, 9, 4, 0, 0},
91 {AMOVVF, C_FREG, C_NONE, C_NONE, C_FREG, C_NONE, 9, 4, 0, 0},
92 {AMOVF, C_FREG, C_NONE, C_NONE, C_FREG, C_NONE, 9, 4, 0, 0},
93 {AMOVD, C_FREG, C_NONE, C_NONE, C_FREG, C_NONE, 9, 4, 0, 0},
94
95 {AMOVW, C_REG, C_NONE, C_NONE, C_SAUTO, C_NONE, 7, 4, REGSP, 0},
96 {AMOVWU, C_REG, C_NONE, C_NONE, C_SAUTO, C_NONE, 7, 4, REGSP, 0},
97 {AMOVV, C_REG, C_NONE, C_NONE, C_SAUTO, C_NONE, 7, 4, REGSP, 0},
98 {AMOVB, C_REG, C_NONE, C_NONE, C_SAUTO, C_NONE, 7, 4, REGSP, 0},
99 {AMOVBU, C_REG, C_NONE, C_NONE, C_SAUTO, C_NONE, 7, 4, REGSP, 0},
100 {AMOVW, C_REG, C_NONE, C_NONE, C_SOREG, C_NONE, 7, 4, REGZERO, 0},
101 {AMOVWU, C_REG, C_NONE, C_NONE, C_SOREG, C_NONE, 7, 4, REGZERO, 0},
102 {AMOVV, C_REG, C_NONE, C_NONE, C_SOREG, C_NONE, 7, 4, REGZERO, 0},
103 {AMOVB, C_REG, C_NONE, C_NONE, C_SOREG, C_NONE, 7, 4, REGZERO, 0},
104 {AMOVBU, C_REG, C_NONE, C_NONE, C_SOREG, C_NONE, 7, 4, REGZERO, 0},
105 {ASC, C_REG, C_NONE, C_NONE, C_SOREG, C_NONE, 7, 4, REGZERO, 0},
106 {ASCV, C_REG, C_NONE, C_NONE, C_SOREG, C_NONE, 7, 4, REGZERO, 0},
107
108 {AMOVW, C_SAUTO, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGSP, 0},
109 {AMOVWU, C_SAUTO, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGSP, 0},
110 {AMOVV, C_SAUTO, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGSP, 0},
111 {AMOVB, C_SAUTO, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGSP, 0},
112 {AMOVBU, C_SAUTO, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGSP, 0},
113 {AMOVW, C_SOREG, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0},
114 {AMOVWU, C_SOREG, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0},
115 {AMOVV, C_SOREG, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0},
116 {AMOVB, C_SOREG, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0},
117 {AMOVBU, C_SOREG, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0},
118 {ALL, C_SOREG, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0},
119 {ALLV, C_SOREG, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0},
120
121 {AMOVW, C_REG, C_NONE, C_NONE, C_LAUTO, C_NONE, 35, 12, REGSP, 0},
122 {AMOVWU, C_REG, C_NONE, C_NONE, C_LAUTO, C_NONE, 35, 12, REGSP, 0},
123 {AMOVV, C_REG, C_NONE, C_NONE, C_LAUTO, C_NONE, 35, 12, REGSP, 0},
124 {AMOVB, C_REG, C_NONE, C_NONE, C_LAUTO, C_NONE, 35, 12, REGSP, 0},
125 {AMOVBU, C_REG, C_NONE, C_NONE, C_LAUTO, C_NONE, 35, 12, REGSP, 0},
126 {AMOVW, C_REG, C_NONE, C_NONE, C_LOREG, C_NONE, 35, 12, REGZERO, 0},
127 {AMOVWU, C_REG, C_NONE, C_NONE, C_LOREG, C_NONE, 35, 12, REGZERO, 0},
128 {AMOVV, C_REG, C_NONE, C_NONE, C_LOREG, C_NONE, 35, 12, REGZERO, 0},
129 {AMOVB, C_REG, C_NONE, C_NONE, C_LOREG, C_NONE, 35, 12, REGZERO, 0},
130 {AMOVBU, C_REG, C_NONE, C_NONE, C_LOREG, C_NONE, 35, 12, REGZERO, 0},
131 {ASC, C_REG, C_NONE, C_NONE, C_LOREG, C_NONE, 35, 12, REGZERO, 0},
132 {AMOVW, C_REG, C_NONE, C_NONE, C_ADDR, C_NONE, 50, 8, 0, 0},
133 {AMOVWU, C_REG, C_NONE, C_NONE, C_ADDR, C_NONE, 50, 8, 0, 0},
134 {AMOVV, C_REG, C_NONE, C_NONE, C_ADDR, C_NONE, 50, 8, 0, 0},
135 {AMOVB, C_REG, C_NONE, C_NONE, C_ADDR, C_NONE, 50, 8, 0, 0},
136 {AMOVBU, C_REG, C_NONE, C_NONE, C_ADDR, C_NONE, 50, 8, 0, 0},
137 {AMOVW, C_REG, C_NONE, C_NONE, C_TLS_LE, C_NONE, 53, 16, 0, 0},
138 {AMOVWU, C_REG, C_NONE, C_NONE, C_TLS_LE, C_NONE, 53, 16, 0, 0},
139 {AMOVV, C_REG, C_NONE, C_NONE, C_TLS_LE, C_NONE, 53, 16, 0, 0},
140 {AMOVB, C_REG, C_NONE, C_NONE, C_TLS_LE, C_NONE, 53, 16, 0, 0},
141 {AMOVBU, C_REG, C_NONE, C_NONE, C_TLS_LE, C_NONE, 53, 16, 0, 0},
142
143 {AMOVW, C_LAUTO, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGSP, 0},
144 {AMOVWU, C_LAUTO, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGSP, 0},
145 {AMOVV, C_LAUTO, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGSP, 0},
146 {AMOVB, C_LAUTO, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGSP, 0},
147 {AMOVBU, C_LAUTO, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGSP, 0},
148 {AMOVW, C_LOREG, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGZERO, 0},
149 {AMOVWU, C_LOREG, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGZERO, 0},
150 {AMOVV, C_LOREG, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGZERO, 0},
151 {AMOVB, C_LOREG, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGZERO, 0},
152 {AMOVBU, C_LOREG, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGZERO, 0},
153 {AMOVW, C_ADDR, C_NONE, C_NONE, C_REG, C_NONE, 51, 8, 0, 0},
154 {AMOVWU, C_ADDR, C_NONE, C_NONE, C_REG, C_NONE, 51, 8, 0, 0},
155 {AMOVV, C_ADDR, C_NONE, C_NONE, C_REG, C_NONE, 51, 8, 0, 0},
156 {AMOVB, C_ADDR, C_NONE, C_NONE, C_REG, C_NONE, 51, 8, 0, 0},
157 {AMOVBU, C_ADDR, C_NONE, C_NONE, C_REG, C_NONE, 51, 8, 0, 0},
158 {AMOVW, C_TLS_LE, C_NONE, C_NONE, C_REG, C_NONE, 54, 16, 0, 0},
159 {AMOVWU, C_TLS_LE, C_NONE, C_NONE, C_REG, C_NONE, 54, 16, 0, 0},
160 {AMOVV, C_TLS_LE, C_NONE, C_NONE, C_REG, C_NONE, 54, 16, 0, 0},
161 {AMOVB, C_TLS_LE, C_NONE, C_NONE, C_REG, C_NONE, 54, 16, 0, 0},
162 {AMOVBU, C_TLS_LE, C_NONE, C_NONE, C_REG, C_NONE, 54, 16, 0, 0},
163
164 {AMOVW, C_SACON, C_NONE, C_NONE, C_REG, C_NONE, 3, 4, REGSP, 0},
165 {AMOVV, C_SACON, C_NONE, C_NONE, C_REG, C_NONE, 3, 4, REGSP, 0},
166 {AMOVW, C_EXTADDR, C_NONE, C_NONE, C_REG, C_NONE, 52, 8, 0, NOTUSETMP},
167 {AMOVV, C_EXTADDR, C_NONE, C_NONE, C_REG, C_NONE, 52, 8, 0, NOTUSETMP},
168
169 {AMOVW, C_LACON, C_NONE, C_NONE, C_REG, C_NONE, 26, 12, REGSP, 0},
170 {AMOVV, C_LACON, C_NONE, C_NONE, C_REG, C_NONE, 26, 12, REGSP, 0},
171 {AMOVW, C_ADDCON, C_NONE, C_NONE, C_REG, C_NONE, 3, 4, REGZERO, 0},
172 {AMOVV, C_ADDCON, C_NONE, C_NONE, C_REG, C_NONE, 3, 4, REGZERO, 0},
173 {AMOVW, C_ANDCON, C_NONE, C_NONE, C_REG, C_NONE, 3, 4, REGZERO, 0},
174 {AMOVV, C_ANDCON, C_NONE, C_NONE, C_REG, C_NONE, 3, 4, REGZERO, 0},
175
176 {AMOVW, C_UCON, C_NONE, C_NONE, C_REG, C_NONE, 24, 4, 0, 0},
177 {AMOVV, C_UCON, C_NONE, C_NONE, C_REG, C_NONE, 24, 4, 0, 0},
178 {AMOVW, C_LCON, C_NONE, C_NONE, C_REG, C_NONE, 19, 8, 0, NOTUSETMP},
179 {AMOVV, C_LCON, C_NONE, C_NONE, C_REG, C_NONE, 19, 8, 0, NOTUSETMP},
180 {AMOVV, C_DCON, C_NONE, C_NONE, C_REG, C_NONE, 59, 16, 0, NOTUSETMP},
181
182 {AADD, C_ADD0CON, C_REG, C_NONE, C_REG, C_NONE, 4, 4, 0, 0},
183 {AADD, C_ADD0CON, C_NONE, C_NONE, C_REG, C_NONE, 4, 4, 0, 0},
184 {AADD, C_ANDCON, C_REG, C_NONE, C_REG, C_NONE, 10, 8, 0, 0},
185 {AADD, C_ANDCON, C_NONE, C_NONE, C_REG, C_NONE, 10, 8, 0, 0},
186
187 {AADDV, C_ADD0CON, C_REG, C_NONE, C_REG, C_NONE, 4, 4, 0, 0},
188 {AADDV, C_ADD0CON, C_NONE, C_NONE, C_REG, C_NONE, 4, 4, 0, 0},
189 {AADDV, C_ANDCON, C_REG, C_NONE, C_REG, C_NONE, 10, 8, 0, 0},
190 {AADDV, C_ANDCON, C_NONE, C_NONE, C_REG, C_NONE, 10, 8, 0, 0},
191
192 {AAND, C_AND0CON, C_REG, C_NONE, C_REG, C_NONE, 4, 4, 0, 0},
193 {AAND, C_AND0CON, C_NONE, C_NONE, C_REG, C_NONE, 4, 4, 0, 0},
194 {AAND, C_ADDCON, C_REG, C_NONE, C_REG, C_NONE, 10, 8, 0, 0},
195 {AAND, C_ADDCON, C_NONE, C_NONE, C_REG, C_NONE, 10, 8, 0, 0},
196
197 {AADD, C_UCON, C_REG, C_NONE, C_REG, C_NONE, 25, 8, 0, 0},
198 {AADD, C_UCON, C_NONE, C_NONE, C_REG, C_NONE, 25, 8, 0, 0},
199 {AADDV, C_UCON, C_REG, C_NONE, C_REG, C_NONE, 25, 8, 0, 0},
200 {AADDV, C_UCON, C_NONE, C_NONE, C_REG, C_NONE, 25, 8, 0, 0},
201 {AAND, C_UCON, C_REG, C_NONE, C_REG, C_NONE, 25, 8, 0, 0},
202 {AAND, C_UCON, C_NONE, C_NONE, C_REG, C_NONE, 25, 8, 0, 0},
203
204 {AADD, C_LCON, C_NONE, C_NONE, C_REG, C_NONE, 23, 12, 0, 0},
205 {AADDV, C_LCON, C_NONE, C_NONE, C_REG, C_NONE, 23, 12, 0, 0},
206 {AAND, C_LCON, C_NONE, C_NONE, C_REG, C_NONE, 23, 12, 0, 0},
207 {AADD, C_LCON, C_REG, C_NONE, C_REG, C_NONE, 23, 12, 0, 0},
208 {AADDV, C_LCON, C_REG, C_NONE, C_REG, C_NONE, 23, 12, 0, 0},
209 {AAND, C_LCON, C_REG, C_NONE, C_REG, C_NONE, 23, 12, 0, 0},
210
211 {AADDV, C_DCON, C_NONE, C_NONE, C_REG, C_NONE, 60, 20, 0, 0},
212 {AADDV, C_DCON, C_REG, C_NONE, C_REG, C_NONE, 60, 20, 0, 0},
213
214 {ASLL, C_SCON, C_REG, C_NONE, C_REG, C_NONE, 16, 4, 0, 0},
215 {ASLL, C_SCON, C_NONE, C_NONE, C_REG, C_NONE, 16, 4, 0, 0},
216
217 {ASLLV, C_SCON, C_REG, C_NONE, C_REG, C_NONE, 16, 4, 0, 0},
218 {ASLLV, C_SCON, C_NONE, C_NONE, C_REG, C_NONE, 16, 4, 0, 0},
219
220 {ABSTRPICKW, C_SCON, C_REG, C_SCON, C_REG, C_NONE, 17, 4, 0, 0},
221 {ABSTRPICKW, C_SCON, C_REG, C_ZCON, C_REG, C_NONE, 17, 4, 0, 0},
222 {ABSTRPICKW, C_ZCON, C_REG, C_ZCON, C_REG, C_NONE, 17, 4, 0, 0},
223
224 {ASYSCALL, C_NONE, C_NONE, C_NONE, C_NONE, C_NONE, 5, 4, 0, 0},
225 {ASYSCALL, C_ANDCON, C_NONE, C_NONE, C_NONE, C_NONE, 5, 4, 0, 0},
226
227 {ABEQ, C_REG, C_REG, C_NONE, C_BRAN, C_NONE, 6, 4, 0, 0},
228 {ABEQ, C_REG, C_NONE, C_NONE, C_BRAN, C_NONE, 6, 4, 0, 0},
229 {ABLEZ, C_REG, C_NONE, C_NONE, C_BRAN, C_NONE, 6, 4, 0, 0},
230 {ABFPT, C_NONE, C_NONE, C_NONE, C_BRAN, C_NONE, 6, 4, 0, NOTUSETMP},
231
232 {AJMP, C_NONE, C_NONE, C_NONE, C_BRAN, C_NONE, 11, 4, 0, 0},
233 {AJAL, C_NONE, C_NONE, C_NONE, C_BRAN, C_NONE, 11, 4, 0, 0},
234
235 {AJMP, C_NONE, C_NONE, C_NONE, C_ZOREG, C_NONE, 18, 4, REGZERO, 0},
236 {AJAL, C_NONE, C_NONE, C_NONE, C_ZOREG, C_NONE, 18, 4, REGLINK, 0},
237
238 {AMOVF, C_SAUTO, C_NONE, C_NONE, C_FREG, C_NONE, 27, 4, REGSP, 0},
239 {AMOVD, C_SAUTO, C_NONE, C_NONE, C_FREG, C_NONE, 27, 4, REGSP, 0},
240 {AMOVF, C_SOREG, C_NONE, C_NONE, C_FREG, C_NONE, 27, 4, REGZERO, 0},
241 {AMOVD, C_SOREG, C_NONE, C_NONE, C_FREG, C_NONE, 27, 4, REGZERO, 0},
242
243 {AMOVF, C_LAUTO, C_NONE, C_NONE, C_FREG, C_NONE, 27, 12, REGSP, 0},
244 {AMOVD, C_LAUTO, C_NONE, C_NONE, C_FREG, C_NONE, 27, 12, REGSP, 0},
245 {AMOVF, C_LOREG, C_NONE, C_NONE, C_FREG, C_NONE, 27, 12, REGZERO, 0},
246 {AMOVD, C_LOREG, C_NONE, C_NONE, C_FREG, C_NONE, 27, 12, REGZERO, 0},
247 {AMOVF, C_ADDR, C_NONE, C_NONE, C_FREG, C_NONE, 51, 8, 0, 0},
248 {AMOVD, C_ADDR, C_NONE, C_NONE, C_FREG, C_NONE, 51, 8, 0, 0},
249
250 {AMOVF, C_FREG, C_NONE, C_NONE, C_SAUTO, C_NONE, 28, 4, REGSP, 0},
251 {AMOVD, C_FREG, C_NONE, C_NONE, C_SAUTO, C_NONE, 28, 4, REGSP, 0},
252 {AMOVF, C_FREG, C_NONE, C_NONE, C_SOREG, C_NONE, 28, 4, REGZERO, 0},
253 {AMOVD, C_FREG, C_NONE, C_NONE, C_SOREG, C_NONE, 28, 4, REGZERO, 0},
254
255 {AMOVF, C_FREG, C_NONE, C_NONE, C_LAUTO, C_NONE, 28, 12, REGSP, 0},
256 {AMOVD, C_FREG, C_NONE, C_NONE, C_LAUTO, C_NONE, 28, 12, REGSP, 0},
257 {AMOVF, C_FREG, C_NONE, C_NONE, C_LOREG, C_NONE, 28, 12, REGZERO, 0},
258 {AMOVD, C_FREG, C_NONE, C_NONE, C_LOREG, C_NONE, 28, 12, REGZERO, 0},
259 {AMOVF, C_FREG, C_NONE, C_NONE, C_ADDR, C_NONE, 50, 8, 0, 0},
260 {AMOVD, C_FREG, C_NONE, C_NONE, C_ADDR, C_NONE, 50, 8, 0, 0},
261
262 {AMOVW, C_REG, C_NONE, C_NONE, C_FREG, C_NONE, 30, 4, 0, 0},
263 {AMOVV, C_REG, C_NONE, C_NONE, C_FREG, C_NONE, 30, 4, 0, 0},
264 {AMOVW, C_FREG, C_NONE, C_NONE, C_REG, C_NONE, 30, 4, 0, 0},
265 {AMOVV, C_FREG, C_NONE, C_NONE, C_REG, C_NONE, 30, 4, 0, 0},
266 {AMOVV, C_FCCREG, C_NONE, C_NONE, C_REG, C_NONE, 30, 4, 0, 0},
267 {AMOVV, C_FCSRREG, C_NONE, C_NONE, C_REG, C_NONE, 30, 4, 0, 0},
268 {AMOVV, C_REG, C_NONE, C_NONE, C_FCCREG, C_NONE, 30, 4, 0, 0},
269 {AMOVV, C_REG, C_NONE, C_NONE, C_FCSRREG, C_NONE, 30, 4, 0, 0},
270 {AMOVV, C_FREG, C_NONE, C_NONE, C_FCCREG, C_NONE, 30, 4, 0, 0},
271 {AMOVV, C_FCCREG, C_NONE, C_NONE, C_FREG, C_NONE, 30, 4, 0, 0},
272
273 {AMOVW, C_ADDCON, C_NONE, C_NONE, C_FREG, C_NONE, 34, 8, 0, 0},
274 {AMOVW, C_ANDCON, C_NONE, C_NONE, C_FREG, C_NONE, 34, 8, 0, 0},
275
276 {AMOVB, C_REG, C_NONE, C_NONE, C_TLS_IE, C_NONE, 56, 16, 0, 0},
277 {AMOVW, C_REG, C_NONE, C_NONE, C_TLS_IE, C_NONE, 56, 16, 0, 0},
278 {AMOVV, C_REG, C_NONE, C_NONE, C_TLS_IE, C_NONE, 56, 16, 0, 0},
279 {AMOVBU, C_REG, C_NONE, C_NONE, C_TLS_IE, C_NONE, 56, 16, 0, 0},
280 {AMOVWU, C_REG, C_NONE, C_NONE, C_TLS_IE, C_NONE, 56, 16, 0, 0},
281
282 {AMOVB, C_TLS_IE, C_NONE, C_NONE, C_REG, C_NONE, 57, 16, 0, 0},
283 {AMOVW, C_TLS_IE, C_NONE, C_NONE, C_REG, C_NONE, 57, 16, 0, 0},
284 {AMOVV, C_TLS_IE, C_NONE, C_NONE, C_REG, C_NONE, 57, 16, 0, 0},
285 {AMOVBU, C_TLS_IE, C_NONE, C_NONE, C_REG, C_NONE, 57, 16, 0, 0},
286 {AMOVWU, C_TLS_IE, C_NONE, C_NONE, C_REG, C_NONE, 57, 16, 0, 0},
287
288 {AWORD, C_LCON, C_NONE, C_NONE, C_NONE, C_NONE, 40, 4, 0, 0},
289 {AWORD, C_DCON, C_NONE, C_NONE, C_NONE, C_NONE, 61, 4, 0, 0},
290
291 {AMOVV, C_GOTADDR, C_NONE, C_NONE, C_REG, C_NONE, 65, 8, 0, 0},
292
293 {ATEQ, C_SCON, C_REG, C_NONE, C_REG, C_NONE, 15, 8, 0, 0},
294 {ATEQ, C_SCON, C_NONE, C_NONE, C_REG, C_NONE, 15, 8, 0, 0},
295
296 {ARDTIMELW, C_NONE, C_NONE, C_NONE, C_REG, C_REG, 62, 4, 0, 0},
297 {AAMSWAPW, C_REG, C_NONE, C_NONE, C_ZOREG, C_REG, 66, 4, 0, 0},
298 {ANOOP, C_NONE, C_NONE, C_NONE, C_NONE, C_NONE, 49, 4, 0, 0},
299
300
301 {AMOVB, C_REG, C_NONE, C_NONE, C_ROFF, C_NONE, 20, 4, 0, 0},
302 {AMOVW, C_REG, C_NONE, C_NONE, C_ROFF, C_NONE, 20, 4, 0, 0},
303 {AMOVV, C_REG, C_NONE, C_NONE, C_ROFF, C_NONE, 20, 4, 0, 0},
304 {AMOVF, C_FREG, C_NONE, C_NONE, C_ROFF, C_NONE, 20, 4, 0, 0},
305 {AMOVD, C_FREG, C_NONE, C_NONE, C_ROFF, C_NONE, 20, 4, 0, 0},
306
307
308 {AMOVB, C_ROFF, C_NONE, C_NONE, C_REG, C_NONE, 21, 4, 0, 0},
309 {AMOVBU, C_ROFF, C_NONE, C_NONE, C_REG, C_NONE, 21, 4, 0, 0},
310 {AMOVW, C_ROFF, C_NONE, C_NONE, C_REG, C_NONE, 21, 4, 0, 0},
311 {AMOVWU, C_ROFF, C_NONE, C_NONE, C_REG, C_NONE, 21, 4, 0, 0},
312 {AMOVV, C_ROFF, C_NONE, C_NONE, C_REG, C_NONE, 21, 4, 0, 0},
313 {AMOVF, C_ROFF, C_NONE, C_NONE, C_FREG, C_NONE, 21, 4, 0, 0},
314 {AMOVD, C_ROFF, C_NONE, C_NONE, C_FREG, C_NONE, 21, 4, 0, 0},
315
316 {obj.APCALIGN, C_SCON, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0},
317 {obj.APCDATA, C_LCON, C_NONE, C_NONE, C_LCON, C_NONE, 0, 0, 0, 0},
318 {obj.APCDATA, C_DCON, C_NONE, C_NONE, C_DCON, C_NONE, 0, 0, 0, 0},
319 {obj.AFUNCDATA, C_SCON, C_NONE, C_NONE, C_ADDR, C_NONE, 0, 0, 0, 0},
320 {obj.ANOP, C_NONE, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0},
321 {obj.ANOP, C_LCON, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0},
322 {obj.ANOP, C_DCON, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0},
323 {obj.ANOP, C_REG, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0},
324 {obj.ANOP, C_FREG, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0},
325 {obj.ADUFFZERO, C_NONE, C_NONE, C_NONE, C_BRAN, C_NONE, 11, 4, 0, 0},
326 {obj.ADUFFCOPY, C_NONE, C_NONE, C_NONE, C_BRAN, C_NONE, 11, 4, 0, 0},
327
328 {obj.AXXX, C_NONE, C_NONE, C_NONE, C_NONE, C_NONE, 0, 4, 0, 0},
329 }
330
331 var atomicInst = map[obj.As]uint32{
332 AAMSWAPB: 0x070B8 << 15,
333 AAMSWAPH: 0x070B9 << 15,
334 AAMSWAPW: 0x070C0 << 15,
335 AAMSWAPV: 0x070C1 << 15,
336 AAMCASB: 0x070B0 << 15,
337 AAMCASH: 0x070B1 << 15,
338 AAMCASW: 0x070B2 << 15,
339 AAMCASV: 0x070B3 << 15,
340 AAMADDW: 0x070C2 << 15,
341 AAMADDV: 0x070C3 << 15,
342 AAMANDW: 0x070C4 << 15,
343 AAMANDV: 0x070C5 << 15,
344 AAMORW: 0x070C6 << 15,
345 AAMORV: 0x070C7 << 15,
346 AAMXORW: 0x070C8 << 15,
347 AAMXORV: 0x070C9 << 15,
348 AAMMAXW: 0x070CA << 15,
349 AAMMAXV: 0x070CB << 15,
350 AAMMINW: 0x070CC << 15,
351 AAMMINV: 0x070CD << 15,
352 AAMMAXWU: 0x070CE << 15,
353 AAMMAXVU: 0x070CF << 15,
354 AAMMINWU: 0x070D0 << 15,
355 AAMMINVU: 0x070D1 << 15,
356 AAMSWAPDBB: 0x070BC << 15,
357 AAMSWAPDBH: 0x070BD << 15,
358 AAMSWAPDBW: 0x070D2 << 15,
359 AAMSWAPDBV: 0x070D3 << 15,
360 AAMCASDBB: 0x070B4 << 15,
361 AAMCASDBH: 0x070B5 << 15,
362 AAMCASDBW: 0x070B6 << 15,
363 AAMCASDBV: 0x070B7 << 15,
364 AAMADDDBW: 0x070D4 << 15,
365 AAMADDDBV: 0x070D5 << 15,
366 AAMANDDBW: 0x070D6 << 15,
367 AAMANDDBV: 0x070D7 << 15,
368 AAMORDBW: 0x070D8 << 15,
369 AAMORDBV: 0x070D9 << 15,
370 AAMXORDBW: 0x070DA << 15,
371 AAMXORDBV: 0x070DB << 15,
372 AAMMAXDBW: 0x070DC << 15,
373 AAMMAXDBV: 0x070DD << 15,
374 AAMMINDBW: 0x070DE << 15,
375 AAMMINDBV: 0x070DF << 15,
376 AAMMAXDBWU: 0x070E0 << 15,
377 AAMMAXDBVU: 0x070E1 << 15,
378 AAMMINDBWU: 0x070E2 << 15,
379 AAMMINDBVU: 0x070E3 << 15,
380 }
381
382 func IsAtomicInst(as obj.As) bool {
383 _, ok := atomicInst[as]
384
385 return ok
386 }
387
388
389
390 func pcAlignPadLength(ctxt *obj.Link, pc int64, alignedValue int64) int {
391 if !((alignedValue&(alignedValue-1) == 0) && 8 <= alignedValue && alignedValue <= 2048) {
392 ctxt.Diag("alignment value of an instruction must be a power of two and in the range [8, 2048], got %d\n", alignedValue)
393 }
394 return int(-pc & (alignedValue - 1))
395 }
396
397 var oprange [ALAST & obj.AMask][]Optab
398
399 var xcmp [C_NCLASS][C_NCLASS]bool
400
401 func span0(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
402 if ctxt.Retpoline {
403 ctxt.Diag("-spectre=ret not supported on loong64")
404 ctxt.Retpoline = false
405 }
406
407 p := cursym.Func().Text
408 if p == nil || p.Link == nil {
409 return
410 }
411
412 c := ctxt0{ctxt: ctxt, newprog: newprog, cursym: cursym, autosize: int32(p.To.Offset + ctxt.Arch.FixedFrameSize)}
413
414 if oprange[AOR&obj.AMask] == nil {
415 c.ctxt.Diag("loong64 ops not initialized, call loong64.buildop first")
416 }
417
418 pc := int64(0)
419 p.Pc = pc
420
421 var m int
422 var o *Optab
423 for p = p.Link; p != nil; p = p.Link {
424 p.Pc = pc
425 o = c.oplook(p)
426 m = int(o.size)
427 if m == 0 {
428 switch p.As {
429 case obj.APCALIGN:
430 alignedValue := p.From.Offset
431 m = pcAlignPadLength(ctxt, pc, alignedValue)
432
433 if int32(alignedValue) > cursym.Func().Align {
434 cursym.Func().Align = int32(alignedValue)
435 }
436 break
437 case obj.ANOP, obj.AFUNCDATA, obj.APCDATA:
438 continue
439 default:
440 c.ctxt.Diag("zero-width instruction\n%v", p)
441 }
442 }
443
444 pc += int64(m)
445 }
446
447 c.cursym.Size = pc
448
449
450
451 for p = c.cursym.Func().Text.Link; p != nil; p = p.Link {
452 if q := p.To.Target(); q != nil && q.Pc < p.Pc {
453 q.Mark |= branchLoopHead
454 }
455 }
456
457
458 for {
459 rescan := false
460 pc = 0
461 prev := c.cursym.Func().Text
462 for p = prev.Link; p != nil; prev, p = p, p.Link {
463 p.Pc = pc
464 o = c.oplook(p)
465
466
467
468
469
470
471
472 if p.Mark&branchLoopHead != 0 && pc&(loopAlign-1) != 0 &&
473 !(prev.As == obj.APCALIGN && prev.From.Offset >= loopAlign) {
474 q := c.newprog()
475 prev.Link = q
476 q.Link = p
477 q.Pc = pc
478 q.As = obj.APCALIGN
479 q.From.Type = obj.TYPE_CONST
480 q.From.Offset = loopAlign
481
482
483
484
485
486
487
488 pc += int64(pcAlignPadLength(ctxt, pc, loopAlign))
489 p.Pc = pc
490 rescan = true
491 }
492
493
494
495
496
497 if o.type_ == 6 && p.To.Target() != nil {
498 otxt := p.To.Target().Pc - pc
499
500
501
502
503
504 bound := int64(1 << (18 - 1))
505
506 switch p.As {
507 case ABFPT, ABFPF:
508 bound = int64(1 << (23 - 1))
509 }
510
511 if otxt < -bound || otxt >= bound {
512 q := c.newprog()
513 q.Link = p.Link
514 p.Link = q
515 q.As = AJMP
516 q.Pos = p.Pos
517 q.To.Type = obj.TYPE_BRANCH
518 q.To.SetTarget(p.To.Target())
519 p.To.SetTarget(q)
520 q = c.newprog()
521 q.Link = p.Link
522 p.Link = q
523 q.As = AJMP
524 q.Pos = p.Pos
525 q.To.Type = obj.TYPE_BRANCH
526 q.To.SetTarget(q.Link.Link)
527 rescan = true
528 }
529 }
530
531 m = int(o.size)
532 if m == 0 {
533 switch p.As {
534 case obj.APCALIGN:
535 alignedValue := p.From.Offset
536 m = pcAlignPadLength(ctxt, pc, alignedValue)
537 break
538 case obj.ANOP, obj.AFUNCDATA, obj.APCDATA:
539 continue
540 default:
541 c.ctxt.Diag("zero-width instruction\n%v", p)
542 }
543 }
544
545 pc += int64(m)
546 }
547
548 c.cursym.Size = pc
549
550 if !rescan {
551 break
552 }
553 }
554
555 pc += -pc & (FuncAlign - 1)
556 c.cursym.Size = pc
557
558
559
560 c.cursym.Grow(c.cursym.Size)
561
562 bp := c.cursym.P
563 var i int32
564 var out [5]uint32
565 for p := c.cursym.Func().Text.Link; p != nil; p = p.Link {
566 c.pc = p.Pc
567 o = c.oplook(p)
568 if int(o.size) > 4*len(out) {
569 log.Fatalf("out array in span0 is too small, need at least %d for %v", o.size/4, p)
570 }
571 if p.As == obj.APCALIGN {
572 alignedValue := p.From.Offset
573 v := pcAlignPadLength(c.ctxt, p.Pc, alignedValue)
574 for i = 0; i < int32(v/4); i++ {
575
576 c.ctxt.Arch.ByteOrder.PutUint32(bp, OP_12IRR(c.opirr(AAND), 0, 0, 0))
577 bp = bp[4:]
578 }
579 continue
580 }
581 c.asmout(p, o, out[:])
582 for i = 0; i < int32(o.size/4); i++ {
583 c.ctxt.Arch.ByteOrder.PutUint32(bp, out[i])
584 bp = bp[4:]
585 }
586 }
587
588
589
590
591
592 obj.MarkUnsafePoints(c.ctxt, c.cursym.Func().Text, c.newprog, c.isUnsafePoint, c.isRestartable)
593 }
594
595
596 func (c *ctxt0) isUnsafePoint(p *obj.Prog) bool {
597
598
599 return p.From.Reg == REGTMP || p.To.Reg == REGTMP || p.Reg == REGTMP
600 }
601
602
603
604 func (c *ctxt0) isRestartable(p *obj.Prog) bool {
605 if c.isUnsafePoint(p) {
606 return false
607 }
608
609
610
611
612
613
614
615 o := c.oplook(p)
616 return o.size > 4 && o.flag&NOTUSETMP == 0
617 }
618
619 func isint32(v int64) bool {
620 return int64(int32(v)) == v
621 }
622
623 func isuint32(v uint64) bool {
624 return uint64(uint32(v)) == v
625 }
626
627 func (c *ctxt0) aclass(a *obj.Addr) int {
628 switch a.Type {
629 case obj.TYPE_NONE:
630 return C_NONE
631
632 case obj.TYPE_REG:
633 return c.rclass(a.Reg)
634
635 case obj.TYPE_MEM:
636 switch a.Name {
637 case obj.NAME_EXTERN,
638 obj.NAME_STATIC:
639 if a.Sym == nil {
640 break
641 }
642 c.instoffset = a.Offset
643 if a.Sym.Type == objabi.STLSBSS {
644 if c.ctxt.Flag_shared {
645 return C_TLS_IE
646 } else {
647 return C_TLS_LE
648 }
649 }
650 return C_ADDR
651
652 case obj.NAME_AUTO:
653 if a.Reg == REGSP {
654
655
656 a.Reg = obj.REG_NONE
657 }
658 c.instoffset = int64(c.autosize) + a.Offset
659 if c.instoffset >= -BIG && c.instoffset < BIG {
660 return C_SAUTO
661 }
662 return C_LAUTO
663
664 case obj.NAME_PARAM:
665 if a.Reg == REGSP {
666
667
668 a.Reg = obj.REG_NONE
669 }
670 c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.Arch.FixedFrameSize
671 if c.instoffset >= -BIG && c.instoffset < BIG {
672 return C_SAUTO
673 }
674 return C_LAUTO
675
676 case obj.NAME_NONE:
677 if a.Index != 0 {
678 if a.Offset != 0 {
679 return C_GOK
680 }
681
682 return C_ROFF
683 }
684
685 c.instoffset = a.Offset
686 if c.instoffset == 0 {
687 return C_ZOREG
688 }
689 if c.instoffset >= -BIG && c.instoffset < BIG {
690 return C_SOREG
691 }
692 return C_LOREG
693
694 case obj.NAME_GOTREF:
695 return C_GOTADDR
696 }
697
698 return C_GOK
699
700 case obj.TYPE_TEXTSIZE:
701 return C_TEXTSIZE
702
703 case obj.TYPE_CONST,
704 obj.TYPE_ADDR:
705 switch a.Name {
706 case obj.NAME_NONE:
707 c.instoffset = a.Offset
708 if a.Reg != 0 {
709 if -BIG <= c.instoffset && c.instoffset <= BIG {
710 return C_SACON
711 }
712 if isint32(c.instoffset) {
713 return C_LACON
714 }
715 return C_DACON
716 }
717
718 case obj.NAME_EXTERN,
719 obj.NAME_STATIC:
720 s := a.Sym
721 if s == nil {
722 return C_GOK
723 }
724
725 c.instoffset = a.Offset
726 if s.Type == objabi.STLSBSS {
727 c.ctxt.Diag("taking address of TLS variable is not supported")
728 }
729 return C_EXTADDR
730
731 case obj.NAME_AUTO:
732 if a.Reg == REGSP {
733
734
735 a.Reg = obj.REG_NONE
736 }
737 c.instoffset = int64(c.autosize) + a.Offset
738 if c.instoffset >= -BIG && c.instoffset < BIG {
739 return C_SACON
740 }
741 return C_LACON
742
743 case obj.NAME_PARAM:
744 if a.Reg == REGSP {
745
746
747 a.Reg = obj.REG_NONE
748 }
749 c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.Arch.FixedFrameSize
750 if c.instoffset >= -BIG && c.instoffset < BIG {
751 return C_SACON
752 }
753 return C_LACON
754
755 default:
756 return C_GOK
757 }
758
759 if c.instoffset != int64(int32(c.instoffset)) {
760 return C_DCON
761 }
762
763 if c.instoffset >= 0 {
764 if c.instoffset == 0 {
765 return C_ZCON
766 }
767 if c.instoffset <= 0x7ff {
768 return C_SCON
769 }
770 if c.instoffset <= 0xfff {
771 return C_ANDCON
772 }
773 if c.instoffset&0xfff == 0 && isuint32(uint64(c.instoffset)) {
774 return C_UCON
775 }
776 if isint32(c.instoffset) || isuint32(uint64(c.instoffset)) {
777 return C_LCON
778 }
779 return C_LCON
780 }
781
782 if c.instoffset >= -0x800 {
783 return C_ADDCON
784 }
785 if c.instoffset&0xfff == 0 && isint32(c.instoffset) {
786 return C_UCON
787 }
788 if isint32(c.instoffset) {
789 return C_LCON
790 }
791 return C_LCON
792
793 case obj.TYPE_BRANCH:
794 return C_BRAN
795 }
796
797 return C_GOK
798 }
799
800
801
802 func (c *ctxt0) rclass(r int16) int {
803 switch {
804 case REG_R0 <= r && r <= REG_R31:
805 return C_REG
806 case REG_F0 <= r && r <= REG_F31:
807 return C_FREG
808 case REG_FCC0 <= r && r <= REG_FCC7:
809 return C_FCCREG
810 case REG_FCSR0 <= r && r <= REG_FCSR3:
811 return C_FCSRREG
812 }
813
814 return C_GOK
815 }
816
817 func oclass(a *obj.Addr) int {
818 return int(a.Class) - 1
819 }
820
821 func prasm(p *obj.Prog) {
822 fmt.Printf("%v\n", p)
823 }
824
825 func (c *ctxt0) oplook(p *obj.Prog) *Optab {
826 if oprange[AOR&obj.AMask] == nil {
827 c.ctxt.Diag("loong64 ops not initialized, call loong64.buildop first")
828 }
829
830 a1 := int(p.Optab)
831 if a1 != 0 {
832 return &optab[a1-1]
833 }
834
835
836 a1 = int(p.From.Class)
837 if a1 == 0 {
838 a1 = c.aclass(&p.From) + 1
839 p.From.Class = int8(a1)
840 }
841 a1--
842
843
844 a4 := int(p.To.Class)
845 if a4 == 0 {
846 a4 = c.aclass(&p.To) + 1
847 p.To.Class = int8(a4)
848 }
849 a4--
850
851
852 a2 := C_NONE
853 if p.Reg != 0 {
854 a2 = c.rclass(p.Reg)
855 }
856
857
858 a5 := C_NONE
859 if p.RegTo2 != 0 {
860 a5 = C_REG
861 }
862
863
864 a3 := C_NONE
865 if len(p.RestArgs) > 0 {
866 a3 = int(p.RestArgs[0].Class)
867 if a3 == 0 {
868 a3 = c.aclass(&p.RestArgs[0].Addr) + 1
869 p.RestArgs[0].Class = int8(a3)
870 }
871 a3--
872 }
873
874 ops := oprange[p.As&obj.AMask]
875 c1 := &xcmp[a1]
876 c4 := &xcmp[a4]
877 for i := range ops {
878 op := &ops[i]
879 if (int(op.reg) == a2) && int(op.from3) == a3 && c1[op.from1] && c4[op.to1] && (int(op.to2) == a5) {
880 p.Optab = uint16(cap(optab) - cap(ops) + i + 1)
881 return op
882 }
883 }
884
885 c.ctxt.Diag("illegal combination %v %v %v %v %v %v", p.As, DRconv(a1), DRconv(a2), DRconv(a3), DRconv(a4), DRconv(a5))
886 prasm(p)
887
888 return &Optab{obj.AUNDEF, C_NONE, C_NONE, C_NONE, C_NONE, C_NONE, 49, 4, 0, 0}
889 }
890
891 func cmp(a int, b int) bool {
892 if a == b {
893 return true
894 }
895 switch a {
896 case C_DCON:
897 if b == C_LCON {
898 return true
899 }
900 fallthrough
901 case C_LCON:
902 if b == C_ZCON || b == C_SCON || b == C_UCON || b == C_ADDCON || b == C_ANDCON {
903 return true
904 }
905
906 case C_ADD0CON:
907 if b == C_ADDCON {
908 return true
909 }
910 fallthrough
911
912 case C_ADDCON:
913 if b == C_ZCON || b == C_SCON {
914 return true
915 }
916
917 case C_AND0CON:
918 if b == C_ANDCON {
919 return true
920 }
921 fallthrough
922
923 case C_ANDCON:
924 if b == C_ZCON || b == C_SCON {
925 return true
926 }
927
928 case C_UCON:
929 if b == C_ZCON {
930 return true
931 }
932
933 case C_SCON:
934 if b == C_ZCON {
935 return true
936 }
937
938 case C_LACON:
939 if b == C_SACON {
940 return true
941 }
942
943 case C_LAUTO:
944 if b == C_SAUTO {
945 return true
946 }
947
948 case C_REG:
949 if b == C_ZCON {
950 return true
951 }
952
953 case C_LOREG:
954 if b == C_ZOREG || b == C_SOREG {
955 return true
956 }
957
958 case C_SOREG:
959 if b == C_ZOREG {
960 return true
961 }
962 }
963
964 return false
965 }
966
967 func ocmp(p1, p2 Optab) int {
968 if p1.as != p2.as {
969 return int(p1.as) - int(p2.as)
970 }
971 if p1.from1 != p2.from1 {
972 return int(p1.from1) - int(p2.from1)
973 }
974 if p1.reg != p2.reg {
975 return int(p1.reg) - int(p2.reg)
976 }
977 if p1.to1 != p2.to1 {
978 return int(p1.to1) - int(p2.to1)
979 }
980 return 0
981 }
982
983 func opset(a, b0 obj.As) {
984 oprange[a&obj.AMask] = oprange[b0]
985 }
986
987 func buildop(ctxt *obj.Link) {
988 if ctxt.DiagFunc == nil {
989 ctxt.DiagFunc = func(format string, args ...interface{}) {
990 log.Printf(format, args...)
991 }
992 }
993
994 if oprange[AOR&obj.AMask] != nil {
995
996
997
998 return
999 }
1000
1001 var n int
1002
1003 for i := 0; i < C_NCLASS; i++ {
1004 for n = 0; n < C_NCLASS; n++ {
1005 if cmp(n, i) {
1006 xcmp[i][n] = true
1007 }
1008 }
1009 }
1010 for n = 0; optab[n].as != obj.AXXX; n++ {
1011 }
1012 slices.SortFunc(optab[:n], ocmp)
1013 for i := 0; i < n; i++ {
1014 r := optab[i].as
1015 r0 := r & obj.AMask
1016 start := i
1017 for optab[i].as == r {
1018 i++
1019 }
1020 oprange[r0] = optab[start:i]
1021 i--
1022
1023 switch r {
1024 default:
1025 ctxt.Diag("unknown op in build: %v", r)
1026 ctxt.DiagFlush()
1027 log.Fatalf("bad code")
1028
1029 case AABSF:
1030 opset(AMOVFD, r0)
1031 opset(AMOVDF, r0)
1032 opset(AMOVWF, r0)
1033 opset(AMOVFW, r0)
1034 opset(AMOVWD, r0)
1035 opset(AMOVDW, r0)
1036 opset(ANEGF, r0)
1037 opset(ANEGD, r0)
1038 opset(AABSD, r0)
1039 opset(ATRUNCDW, r0)
1040 opset(ATRUNCFW, r0)
1041 opset(ASQRTF, r0)
1042 opset(ASQRTD, r0)
1043 opset(AFCLASSF, r0)
1044 opset(AFCLASSD, r0)
1045 opset(AFLOGBF, r0)
1046 opset(AFLOGBD, r0)
1047
1048 case AMOVVF:
1049 opset(AMOVVD, r0)
1050 opset(AMOVFV, r0)
1051 opset(AMOVDV, r0)
1052 opset(ATRUNCDV, r0)
1053 opset(ATRUNCFV, r0)
1054 opset(AFFINTFW, r0)
1055 opset(AFFINTFV, r0)
1056 opset(AFFINTDW, r0)
1057 opset(AFFINTDV, r0)
1058 opset(AFTINTWF, r0)
1059 opset(AFTINTWD, r0)
1060 opset(AFTINTVF, r0)
1061 opset(AFTINTVD, r0)
1062 opset(AFTINTRPWF, r0)
1063 opset(AFTINTRPWD, r0)
1064 opset(AFTINTRPVF, r0)
1065 opset(AFTINTRPVD, r0)
1066 opset(AFTINTRMWF, r0)
1067 opset(AFTINTRMWD, r0)
1068 opset(AFTINTRMVF, r0)
1069 opset(AFTINTRMVD, r0)
1070 opset(AFTINTRZWF, r0)
1071 opset(AFTINTRZWD, r0)
1072 opset(AFTINTRZVF, r0)
1073 opset(AFTINTRZVD, r0)
1074 opset(AFTINTRNEWF, r0)
1075 opset(AFTINTRNEWD, r0)
1076 opset(AFTINTRNEVF, r0)
1077 opset(AFTINTRNEVD, r0)
1078
1079 case AADD:
1080 opset(ASGT, r0)
1081 opset(ASGTU, r0)
1082 opset(AADDU, r0)
1083
1084 case AADDV:
1085 opset(AADDVU, r0)
1086
1087 case AADDF:
1088 opset(ADIVF, r0)
1089 opset(ADIVD, r0)
1090 opset(AMULF, r0)
1091 opset(AMULD, r0)
1092 opset(ASUBF, r0)
1093 opset(ASUBD, r0)
1094 opset(AADDD, r0)
1095 opset(AFMINF, r0)
1096 opset(AFMIND, r0)
1097 opset(AFMAXF, r0)
1098 opset(AFMAXD, r0)
1099 opset(AFCOPYSGF, r0)
1100 opset(AFCOPYSGD, r0)
1101 opset(AFSCALEBF, r0)
1102 opset(AFSCALEBD, r0)
1103
1104 case AAND:
1105 opset(AOR, r0)
1106 opset(AXOR, r0)
1107 opset(AORN, r0)
1108 opset(AANDN, r0)
1109
1110 case ABEQ:
1111 opset(ABNE, r0)
1112 opset(ABLT, r0)
1113 opset(ABGE, r0)
1114 opset(ABGEU, r0)
1115 opset(ABLTU, r0)
1116
1117 case ABLEZ:
1118 opset(ABGEZ, r0)
1119 opset(ABLTZ, r0)
1120 opset(ABGTZ, r0)
1121
1122 case AMOVB:
1123 opset(AMOVH, r0)
1124
1125 case AMOVBU:
1126 opset(AMOVHU, r0)
1127
1128 case AMUL:
1129 opset(AMULU, r0)
1130 opset(AMULH, r0)
1131 opset(AMULHU, r0)
1132 opset(AREM, r0)
1133 opset(AREMU, r0)
1134 opset(ADIV, r0)
1135 opset(ADIVU, r0)
1136
1137 case AMULV:
1138 opset(AMULVU, r0)
1139 opset(AMULHV, r0)
1140 opset(AMULHVU, r0)
1141 opset(AREMV, r0)
1142 opset(AREMVU, r0)
1143 opset(ADIVV, r0)
1144 opset(ADIVVU, r0)
1145
1146 case ASLL:
1147 opset(ASRL, r0)
1148 opset(ASRA, r0)
1149 opset(AROTR, r0)
1150
1151 case ASLLV:
1152 opset(ASRAV, r0)
1153 opset(ASRLV, r0)
1154 opset(AROTRV, r0)
1155
1156 case ABSTRPICKW:
1157 opset(ABSTRPICKV, r0)
1158 opset(ABSTRINSW, r0)
1159 opset(ABSTRINSV, r0)
1160
1161 case ASUB:
1162 opset(ASUBU, r0)
1163 opset(ANOR, r0)
1164
1165 case ASUBV:
1166 opset(ASUBVU, r0)
1167
1168 case ASYSCALL:
1169 opset(ADBAR, r0)
1170 opset(ABREAK, r0)
1171
1172 case ACMPEQF:
1173 opset(ACMPGTF, r0)
1174 opset(ACMPGTD, r0)
1175 opset(ACMPGEF, r0)
1176 opset(ACMPGED, r0)
1177 opset(ACMPEQD, r0)
1178
1179 case ABFPT:
1180 opset(ABFPF, r0)
1181
1182 case AMOVW,
1183 AMOVD,
1184 AMOVF,
1185 AMOVV,
1186 ARFE,
1187 AJAL,
1188 AJMP,
1189 AMOVWU,
1190 ALL,
1191 ALLV,
1192 ASC,
1193 ASCV,
1194 ANEGW,
1195 ANEGV,
1196 AWORD,
1197 obj.ANOP,
1198 obj.ATEXT,
1199 obj.AFUNCDATA,
1200 obj.APCALIGN,
1201 obj.APCDATA,
1202 obj.ADUFFZERO,
1203 obj.ADUFFCOPY:
1204 break
1205
1206 case ARDTIMELW:
1207 opset(ARDTIMEHW, r0)
1208 opset(ARDTIMED, r0)
1209
1210 case ACLO:
1211 opset(ACLZ, r0)
1212 opset(ACPUCFG, r0)
1213
1214 case ATEQ:
1215 opset(ATNE, r0)
1216
1217 case AMASKEQZ:
1218 opset(AMASKNEZ, r0)
1219
1220 case ANOOP:
1221 opset(obj.AUNDEF, r0)
1222
1223 case AAMSWAPW:
1224 for i := range atomicInst {
1225 if i == AAMSWAPW {
1226 continue
1227 }
1228 opset(i, r0)
1229 }
1230 }
1231 }
1232 }
1233
1234
1235
1236
1237 func OP_RRR(op uint32, r1 uint32, r2 uint32, r3 uint32) uint32 {
1238 return op | (r1&0x1F)<<10 | (r2&0x1F)<<5 | (r3&0x1F)<<0
1239 }
1240
1241
1242
1243 func OP_RR(op uint32, r2 uint32, r3 uint32) uint32 {
1244 return op | (r2&0x1F)<<5 | (r3&0x1F)<<0
1245 }
1246
1247 func OP_16IR_5I(op uint32, i uint32, r2 uint32) uint32 {
1248 return op | (i&0xFFFF)<<10 | (r2&0x1F)<<5 | ((i >> 16) & 0x1F)
1249 }
1250
1251 func OP_16IRR(op uint32, i uint32, r2 uint32, r3 uint32) uint32 {
1252 return op | (i&0xFFFF)<<10 | (r2&0x1F)<<5 | (r3&0x1F)<<0
1253 }
1254
1255 func OP_12IRR(op uint32, i uint32, r2 uint32, r3 uint32) uint32 {
1256 return op | (i&0xFFF)<<10 | (r2&0x1F)<<5 | (r3&0x1F)<<0
1257 }
1258
1259 func OP_IR(op uint32, i uint32, r2 uint32) uint32 {
1260 return op | (i&0xFFFFF)<<5 | (r2&0x1F)<<0
1261 }
1262
1263 func OP_15I(op uint32, i uint32) uint32 {
1264 return op | (i&0x7FFF)<<0
1265 }
1266
1267
1268
1269
1270
1271 func OP_IRIR(op uint32, i1 uint32, r2 uint32, i3 uint32, r4 uint32) uint32 {
1272 return op | (i1 << 16) | (r2&0x1F)<<5 | (i3 << 10) | (r4&0x1F)<<0
1273 }
1274
1275
1276 func OP_B_BL(op uint32, i uint32) uint32 {
1277 return op | ((i & 0xFFFF) << 10) | ((i >> 16) & 0x3FF)
1278 }
1279
1280 func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
1281 o1 := uint32(0)
1282 o2 := uint32(0)
1283 o3 := uint32(0)
1284 o4 := uint32(0)
1285 o5 := uint32(0)
1286
1287 add := AADDU
1288 add = AADDVU
1289
1290 switch o.type_ {
1291 default:
1292 c.ctxt.Diag("unknown type %d %v", o.type_)
1293 prasm(p)
1294
1295 case 0:
1296 break
1297
1298 case 1:
1299 a := AOR
1300 if p.As == AMOVW {
1301 a = ASLL
1302 }
1303 o1 = OP_RRR(c.oprrr(a), uint32(REGZERO), uint32(p.From.Reg), uint32(p.To.Reg))
1304
1305 case 2:
1306 r := int(p.Reg)
1307 if p.As == ANEGW || p.As == ANEGV {
1308 r = REGZERO
1309 }
1310 if r == 0 {
1311 r = int(p.To.Reg)
1312 }
1313 o1 = OP_RRR(c.oprrr(p.As), uint32(p.From.Reg), uint32(r), uint32(p.To.Reg))
1314
1315 case 3:
1316 v := c.regoff(&p.From)
1317
1318 r := int(p.From.Reg)
1319 if r == 0 {
1320 r = int(o.param)
1321 }
1322 a := add
1323 if o.from1 == C_ANDCON {
1324 a = AOR
1325 }
1326
1327 o1 = OP_12IRR(c.opirr(a), uint32(v), uint32(r), uint32(p.To.Reg))
1328
1329 case 4:
1330 v := c.regoff(&p.From)
1331
1332 r := int(p.Reg)
1333 if r == 0 {
1334 r = int(p.To.Reg)
1335 }
1336
1337 o1 = OP_12IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg))
1338
1339 case 5:
1340 v := c.regoff(&p.From)
1341 o1 = OP_15I(c.opi(p.As), uint32(v))
1342
1343 case 6:
1344 v := int32(0)
1345 if p.To.Target() != nil {
1346 v = int32(p.To.Target().Pc-p.Pc) >> 2
1347 }
1348 as, rd, rj, width := p.As, p.Reg, p.From.Reg, 16
1349 switch as {
1350 case ABGTZ, ABLEZ:
1351 rd, rj = rj, rd
1352 case ABFPT, ABFPF:
1353 width = 21
1354
1355
1356 rj = REG_FCC0
1357 case ABEQ, ABNE:
1358 if rd == 0 || rd == REGZERO || rj == REGZERO {
1359
1360 width = 21
1361 as = -as
1362 if rj == 0 || rj == REGZERO {
1363 rj = rd
1364 }
1365 }
1366 }
1367 switch width {
1368 case 21:
1369 if (v<<11)>>11 != v {
1370 c.ctxt.Diag("21 bit-width, short branch too far\n%v", p)
1371 }
1372 o1 = OP_16IR_5I(c.opirr(as), uint32(v), uint32(rj))
1373 case 16:
1374 if (v<<16)>>16 != v {
1375 c.ctxt.Diag("16 bit-width, short branch too far\n%v", p)
1376 }
1377 o1 = OP_16IRR(c.opirr(as), uint32(v), uint32(rj), uint32(rd))
1378 default:
1379 c.ctxt.Diag("unexpected branch encoding\n%v", p)
1380 }
1381
1382 case 7:
1383 r := int(p.To.Reg)
1384 if r == 0 {
1385 r = int(o.param)
1386 }
1387 v := c.regoff(&p.To)
1388 o1 = OP_12IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.From.Reg))
1389
1390 case 8:
1391 r := int(p.From.Reg)
1392 if r == 0 {
1393 r = int(o.param)
1394 }
1395 v := c.regoff(&p.From)
1396 o1 = OP_12IRR(c.opirr(-p.As), uint32(v), uint32(r), uint32(p.To.Reg))
1397
1398 case 9:
1399 o1 = OP_RR(c.oprr(p.As), uint32(p.From.Reg), uint32(p.To.Reg))
1400
1401 case 10:
1402 v := c.regoff(&p.From)
1403 a := AOR
1404 if v < 0 {
1405 a = AADDU
1406 }
1407 o1 = OP_12IRR(c.opirr(a), uint32(v), uint32(0), uint32(REGTMP))
1408 r := int(p.Reg)
1409 if r == 0 {
1410 r = int(p.To.Reg)
1411 }
1412 o2 = OP_RRR(c.oprrr(p.As), uint32(REGTMP), uint32(r), uint32(p.To.Reg))
1413
1414 case 11:
1415 v := int32(0)
1416 if p.To.Target() != nil {
1417 v = int32(p.To.Target().Pc-p.Pc) >> 2
1418 }
1419 o1 = OP_B_BL(c.opirr(p.As), uint32(v))
1420 if p.To.Sym != nil {
1421 rel := obj.Addrel(c.cursym)
1422 rel.Off = int32(c.pc)
1423 rel.Siz = 4
1424 rel.Sym = p.To.Sym
1425 rel.Add = p.To.Offset
1426 rel.Type = objabi.R_CALLLOONG64
1427 }
1428
1429 case 12:
1430
1431
1432 v := 16
1433 if p.As == AMOVB {
1434 v = 24
1435 }
1436 o1 = OP_16IRR(c.opirr(ASLL), uint32(v), uint32(p.From.Reg), uint32(p.To.Reg))
1437 o2 = OP_16IRR(c.opirr(ASRA), uint32(v), uint32(p.To.Reg), uint32(p.To.Reg))
1438
1439 case 13:
1440 if p.As == AMOVBU {
1441 o1 = OP_12IRR(c.opirr(AAND), uint32(0xff), uint32(p.From.Reg), uint32(p.To.Reg))
1442 } else {
1443
1444 o1 = (0x33c0 << 10) | ((uint32(p.From.Reg) & 0x1f) << 5) | (uint32(p.To.Reg) & 0x1F)
1445 }
1446
1447 case 14:
1448
1449
1450 o1 = OP_16IRR(c.opirr(ASLLV), uint32(32)&0x3f, uint32(p.From.Reg), uint32(p.To.Reg))
1451 o2 = OP_16IRR(c.opirr(ASRLV), uint32(32)&0x3f, uint32(p.To.Reg), uint32(p.To.Reg))
1452
1453 case 15:
1454 v := c.regoff(&p.From)
1455 r := int(p.Reg)
1456 if r == 0 {
1457 r = REGZERO
1458 }
1459
1467 if p.As == ATEQ {
1468 o1 = OP_16IRR(c.opirr(ABNE), uint32(2), uint32(r), uint32(p.To.Reg))
1469 } else {
1470 o1 = OP_16IRR(c.opirr(ABEQ), uint32(2), uint32(r), uint32(p.To.Reg))
1471 }
1472 o2 = OP_15I(c.opi(ABREAK), uint32(v))
1473
1474 case 16:
1475 v := c.regoff(&p.From)
1476 r := int(p.Reg)
1477 if r == 0 {
1478 r = int(p.To.Reg)
1479 }
1480
1481
1482 if v >= 32 && vshift(p.As) {
1483 o1 = OP_16IRR(c.opirr(p.As), uint32(v)&0x3f, uint32(r), uint32(p.To.Reg))
1484 } else {
1485 o1 = OP_16IRR(c.opirr(p.As), uint32(v)&0x1f, uint32(r), uint32(p.To.Reg))
1486 }
1487
1488 case 17:
1489 rd, rj := p.To.Reg, p.Reg
1490 if rj == obj.REG_NONE {
1491 rj = rd
1492 }
1493 msb, lsb := p.From.Offset, p.GetFrom3().Offset
1494
1495
1496 var b uint32
1497 if p.As == ABSTRPICKW || p.As == ABSTRINSW {
1498 b = 32
1499 } else {
1500 b = 64
1501 }
1502 if lsb < 0 || uint32(lsb) >= b || msb < 0 || uint32(msb) >= b || uint32(lsb) > uint32(msb) {
1503 c.ctxt.Diag("illegal bit number\n%v", p)
1504 }
1505
1506 o1 = OP_IRIR(c.opirir(p.As), uint32(msb), uint32(rj), uint32(lsb), uint32(rd))
1507
1508 case 18:
1509 r := int(p.Reg)
1510 if r == 0 {
1511 r = int(o.param)
1512 }
1513 o1 = OP_RRR(c.oprrr(p.As), uint32(0), uint32(p.To.Reg), uint32(r))
1514 if p.As == obj.ACALL {
1515 rel := obj.Addrel(c.cursym)
1516 rel.Off = int32(c.pc)
1517 rel.Siz = 0
1518 rel.Type = objabi.R_CALLIND
1519 }
1520
1521 case 19:
1522
1523
1524 v := c.regoff(&p.From)
1525 o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(p.To.Reg))
1526 o2 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(p.To.Reg), uint32(p.To.Reg))
1527
1528 case 20:
1529 o1 = OP_RRR(c.oprrr(p.As), uint32(p.To.Index), uint32(p.To.Reg), uint32(p.From.Reg))
1530
1531 case 21:
1532 o1 = OP_RRR(c.oprrr(-p.As), uint32(p.From.Index), uint32(p.From.Reg), uint32(p.To.Reg))
1533
1534 case 23:
1535 v := c.regoff(&p.From)
1536 o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(REGTMP))
1537 o2 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(REGTMP), uint32(REGTMP))
1538 r := int(p.Reg)
1539 if r == 0 {
1540 r = int(p.To.Reg)
1541 }
1542 o3 = OP_RRR(c.oprrr(p.As), uint32(REGTMP), uint32(r), uint32(p.To.Reg))
1543
1544 case 24:
1545 v := c.regoff(&p.From)
1546 o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(p.To.Reg))
1547
1548 case 25:
1549 v := c.regoff(&p.From)
1550 o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(REGTMP))
1551 r := int(p.Reg)
1552 if r == 0 {
1553 r = int(p.To.Reg)
1554 }
1555 o2 = OP_RRR(c.oprrr(p.As), uint32(REGTMP), uint32(r), uint32(p.To.Reg))
1556
1557 case 26:
1558 v := c.regoff(&p.From)
1559 o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(REGTMP))
1560 o2 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(REGTMP), uint32(REGTMP))
1561 r := int(p.From.Reg)
1562 if r == 0 {
1563 r = int(o.param)
1564 }
1565 o3 = OP_RRR(c.oprrr(add), uint32(REGTMP), uint32(r), uint32(p.To.Reg))
1566
1567 case 27:
1568 v := c.regoff(&p.From)
1569 r := int(p.From.Reg)
1570 if r == 0 {
1571 r = int(o.param)
1572 }
1573 switch o.size {
1574 case 12:
1575 o1 = OP_IR(c.opir(ALU12IW), uint32((v+1<<11)>>12), uint32(REGTMP))
1576 o2 = OP_RRR(c.oprrr(add), uint32(r), uint32(REGTMP), uint32(REGTMP))
1577 o3 = OP_12IRR(c.opirr(-p.As), uint32(v), uint32(REGTMP), uint32(p.To.Reg))
1578
1579 case 4:
1580 o1 = OP_12IRR(c.opirr(-p.As), uint32(v), uint32(r), uint32(p.To.Reg))
1581 }
1582
1583 case 28:
1584 v := c.regoff(&p.To)
1585 r := int(p.To.Reg)
1586 if r == 0 {
1587 r = int(o.param)
1588 }
1589 switch o.size {
1590 case 12:
1591 o1 = OP_IR(c.opir(ALU12IW), uint32((v+1<<11)>>12), uint32(REGTMP))
1592 o2 = OP_RRR(c.oprrr(add), uint32(r), uint32(REGTMP), uint32(REGTMP))
1593 o3 = OP_12IRR(c.opirr(p.As), uint32(v), uint32(REGTMP), uint32(p.From.Reg))
1594
1595 case 4:
1596 o1 = OP_12IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.From.Reg))
1597 }
1598
1599 case 30:
1600 a := c.specailFpMovInst(p.As, oclass(&p.From), oclass(&p.To))
1601 o1 = OP_RR(a, uint32(p.From.Reg), uint32(p.To.Reg))
1602
1603 case 34:
1604 v := c.regoff(&p.From)
1605 a := AADDU
1606 if o.from1 == C_ANDCON {
1607 a = AOR
1608 }
1609 a2 := c.specailFpMovInst(p.As, C_REG, oclass(&p.To))
1610 o1 = OP_12IRR(c.opirr(a), uint32(v), uint32(0), uint32(REGTMP))
1611 o2 = OP_RR(a2, uint32(REGTMP), uint32(p.To.Reg))
1612
1613 case 35:
1614 v := c.regoff(&p.To)
1615 r := int(p.To.Reg)
1616 if r == 0 {
1617 r = int(o.param)
1618 }
1619 o1 = OP_IR(c.opir(ALU12IW), uint32((v+1<<11)>>12), uint32(REGTMP))
1620 o2 = OP_RRR(c.oprrr(add), uint32(r), uint32(REGTMP), uint32(REGTMP))
1621 o3 = OP_12IRR(c.opirr(p.As), uint32(v), uint32(REGTMP), uint32(p.From.Reg))
1622
1623 case 36:
1624 v := c.regoff(&p.From)
1625 r := int(p.From.Reg)
1626 if r == 0 {
1627 r = int(o.param)
1628 }
1629 o1 = OP_IR(c.opir(ALU12IW), uint32((v+1<<11)>>12), uint32(REGTMP))
1630 o2 = OP_RRR(c.oprrr(add), uint32(r), uint32(REGTMP), uint32(REGTMP))
1631 o3 = OP_12IRR(c.opirr(-p.As), uint32(v), uint32(REGTMP), uint32(p.To.Reg))
1632
1633 case 40:
1634 o1 = uint32(c.regoff(&p.From))
1635
1636 case 49:
1637 if p.As == ANOOP {
1638
1639 o1 = OP_12IRR(c.opirr(AAND), 0, 0, 0)
1640 } else {
1641
1642 o1 = OP_15I(c.opi(ABREAK), 0)
1643 }
1644
1645
1646 case 50:
1647 o1 = OP_IR(c.opir(APCALAU12I), uint32(0), uint32(REGTMP))
1648 rel := obj.Addrel(c.cursym)
1649 rel.Off = int32(c.pc)
1650 rel.Siz = 4
1651 rel.Sym = p.To.Sym
1652 rel.Add = p.To.Offset
1653 rel.Type = objabi.R_LOONG64_ADDR_HI
1654
1655 o2 = OP_12IRR(c.opirr(p.As), uint32(0), uint32(REGTMP), uint32(p.From.Reg))
1656 rel2 := obj.Addrel(c.cursym)
1657 rel2.Off = int32(c.pc + 4)
1658 rel2.Siz = 4
1659 rel2.Sym = p.To.Sym
1660 rel2.Add = p.To.Offset
1661 rel2.Type = objabi.R_LOONG64_ADDR_LO
1662
1663 case 51:
1664 o1 = OP_IR(c.opir(APCALAU12I), uint32(0), uint32(REGTMP))
1665 rel := obj.Addrel(c.cursym)
1666 rel.Off = int32(c.pc)
1667 rel.Siz = 4
1668 rel.Sym = p.From.Sym
1669 rel.Add = p.From.Offset
1670 rel.Type = objabi.R_LOONG64_ADDR_HI
1671 o2 = OP_12IRR(c.opirr(-p.As), uint32(0), uint32(REGTMP), uint32(p.To.Reg))
1672 rel2 := obj.Addrel(c.cursym)
1673 rel2.Off = int32(c.pc + 4)
1674 rel2.Siz = 4
1675 rel2.Sym = p.From.Sym
1676 rel2.Add = p.From.Offset
1677 rel2.Type = objabi.R_LOONG64_ADDR_LO
1678
1679 case 52:
1680
1681
1682 o1 = OP_IR(c.opir(APCALAU12I), uint32(0), uint32(p.To.Reg))
1683 rel := obj.Addrel(c.cursym)
1684 rel.Off = int32(c.pc)
1685 rel.Siz = 4
1686 rel.Sym = p.From.Sym
1687 rel.Add = p.From.Offset
1688 rel.Type = objabi.R_LOONG64_ADDR_HI
1689 o2 = OP_12IRR(c.opirr(add), uint32(0), uint32(p.To.Reg), uint32(p.To.Reg))
1690 rel2 := obj.Addrel(c.cursym)
1691 rel2.Off = int32(c.pc + 4)
1692 rel2.Siz = 4
1693 rel2.Sym = p.From.Sym
1694 rel2.Add = p.From.Offset
1695 rel2.Type = objabi.R_LOONG64_ADDR_LO
1696
1697 case 53:
1698
1699
1700 o1 = OP_IR(c.opir(ALU12IW), uint32(0), uint32(REGTMP))
1701 rel := obj.Addrel(c.cursym)
1702 rel.Off = int32(c.pc)
1703 rel.Siz = 4
1704 rel.Sym = p.To.Sym
1705 rel.Add = p.To.Offset
1706 rel.Type = objabi.R_LOONG64_TLS_LE_HI
1707 o2 = OP_12IRR(c.opirr(AOR), uint32(0), uint32(REGTMP), uint32(REGTMP))
1708 rel2 := obj.Addrel(c.cursym)
1709 rel2.Off = int32(c.pc + 4)
1710 rel2.Siz = 4
1711 rel2.Sym = p.To.Sym
1712 rel2.Add = p.To.Offset
1713 rel2.Type = objabi.R_LOONG64_TLS_LE_LO
1714 o3 = OP_RRR(c.oprrr(AADDV), uint32(REG_R2), uint32(REGTMP), uint32(REGTMP))
1715 o4 = OP_12IRR(c.opirr(p.As), uint32(0), uint32(REGTMP), uint32(p.From.Reg))
1716
1717 case 54:
1718
1719
1720 o1 = OP_IR(c.opir(ALU12IW), uint32(0), uint32(REGTMP))
1721 rel := obj.Addrel(c.cursym)
1722 rel.Off = int32(c.pc)
1723 rel.Siz = 4
1724 rel.Sym = p.From.Sym
1725 rel.Add = p.From.Offset
1726 rel.Type = objabi.R_LOONG64_TLS_LE_HI
1727 o2 = OP_12IRR(c.opirr(AOR), uint32(0), uint32(REGTMP), uint32(REGTMP))
1728 rel2 := obj.Addrel(c.cursym)
1729 rel2.Off = int32(c.pc + 4)
1730 rel2.Siz = 4
1731 rel2.Sym = p.From.Sym
1732 rel2.Add = p.From.Offset
1733 rel2.Type = objabi.R_LOONG64_TLS_LE_LO
1734 o3 = OP_RRR(c.oprrr(AADDV), uint32(REG_R2), uint32(REGTMP), uint32(REGTMP))
1735 o4 = OP_12IRR(c.opirr(-p.As), uint32(0), uint32(REGTMP), uint32(p.To.Reg))
1736
1737 case 56:
1738 o1 = OP_IR(c.opir(APCALAU12I), uint32(0), uint32(REGTMP))
1739 rel := obj.Addrel(c.cursym)
1740 rel.Off = int32(c.pc)
1741 rel.Siz = 4
1742 rel.Sym = p.To.Sym
1743 rel.Add = 0x0
1744 rel.Type = objabi.R_LOONG64_TLS_IE_HI
1745 o2 = OP_12IRR(c.opirr(-p.As), uint32(0), uint32(REGTMP), uint32(REGTMP))
1746 rel2 := obj.Addrel(c.cursym)
1747 rel2.Off = int32(c.pc + 4)
1748 rel2.Siz = 4
1749 rel2.Sym = p.To.Sym
1750 rel2.Add = 0x0
1751 rel2.Type = objabi.R_LOONG64_TLS_IE_LO
1752 o3 = OP_RRR(c.oprrr(AADDVU), uint32(REGTMP), uint32(REG_R2), uint32(REGTMP))
1753 o4 = OP_12IRR(c.opirr(p.As), uint32(0), uint32(REGTMP), uint32(p.From.Reg))
1754
1755 case 57:
1756 o1 = OP_IR(c.opir(APCALAU12I), uint32(0), uint32(REGTMP))
1757 rel := obj.Addrel(c.cursym)
1758 rel.Off = int32(c.pc)
1759 rel.Siz = 4
1760 rel.Sym = p.From.Sym
1761 rel.Add = 0x0
1762 rel.Type = objabi.R_LOONG64_TLS_IE_HI
1763 o2 = OP_12IRR(c.opirr(-p.As), uint32(0), uint32(REGTMP), uint32(REGTMP))
1764 rel2 := obj.Addrel(c.cursym)
1765 rel2.Off = int32(c.pc + 4)
1766 rel2.Siz = 4
1767 rel2.Sym = p.From.Sym
1768 rel2.Add = 0x0
1769 rel2.Type = objabi.R_LOONG64_TLS_IE_LO
1770 o3 = OP_RRR(c.oprrr(AADDVU), uint32(REGTMP), uint32(REG_R2), uint32(REGTMP))
1771 o4 = OP_12IRR(c.opirr(-p.As), uint32(0), uint32(REGTMP), uint32(p.To.Reg))
1772
1773 case 59:
1774
1775
1776 v := c.vregoff(&p.From)
1777 o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(p.To.Reg))
1778 o2 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(p.To.Reg), uint32(p.To.Reg))
1779 o3 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(p.To.Reg))
1780 o4 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(p.To.Reg), uint32(p.To.Reg))
1781
1782 case 60:
1783 v := c.vregoff(&p.From)
1784 o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(REGTMP))
1785 o2 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(REGTMP), uint32(REGTMP))
1786 o3 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(REGTMP))
1787 o4 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(REGTMP), uint32(REGTMP))
1788 r := int(p.Reg)
1789 if r == 0 {
1790 r = int(p.To.Reg)
1791 }
1792 o5 = OP_RRR(c.oprrr(p.As), uint32(REGTMP), uint32(r), uint32(p.To.Reg))
1793
1794 case 61:
1795 o1 = uint32(c.vregoff(&p.From))
1796 o2 = uint32(c.vregoff(&p.From) >> 32)
1797
1798 case 62:
1799 o1 = OP_RR(c.oprr(p.As), uint32(p.To.Reg), uint32(p.RegTo2))
1800
1801 case 65:
1802 o1 = OP_IR(c.opir(APCALAU12I), uint32(0), uint32(p.To.Reg))
1803 rel := obj.Addrel(c.cursym)
1804 rel.Off = int32(c.pc)
1805 rel.Siz = 4
1806 rel.Sym = p.From.Sym
1807 rel.Type = objabi.R_LOONG64_GOT_HI
1808 rel.Add = 0x0
1809 o2 = OP_12IRR(c.opirr(-p.As), uint32(0), uint32(p.To.Reg), uint32(p.To.Reg))
1810 rel2 := obj.Addrel(c.cursym)
1811 rel2.Off = int32(c.pc + 4)
1812 rel2.Siz = 4
1813 rel2.Sym = p.From.Sym
1814 rel2.Type = objabi.R_LOONG64_GOT_LO
1815 rel2.Add = 0x0
1816
1817 case 66:
1818 rk := p.From.Reg
1819 rj := p.To.Reg
1820 rd := p.RegTo2
1821
1822
1823
1824 if rd == rj || rd == rk {
1825 c.ctxt.Diag("illegal register combination: %v\n", p)
1826 }
1827 o1 = OP_RRR(atomicInst[p.As], uint32(rk), uint32(rj), uint32(rd))
1828 }
1829
1830 out[0] = o1
1831 out[1] = o2
1832 out[2] = o3
1833 out[3] = o4
1834 out[4] = o5
1835 }
1836
1837 func (c *ctxt0) vregoff(a *obj.Addr) int64 {
1838 c.instoffset = 0
1839 c.aclass(a)
1840 return c.instoffset
1841 }
1842
1843 func (c *ctxt0) regoff(a *obj.Addr) int32 {
1844 return int32(c.vregoff(a))
1845 }
1846
1847 func (c *ctxt0) oprrr(a obj.As) uint32 {
1848 switch a {
1849 case AADD:
1850 return 0x20 << 15
1851 case AADDU:
1852 return 0x20 << 15
1853 case ASGT:
1854 return 0x24 << 15
1855 case ASGTU:
1856 return 0x25 << 15
1857 case AMASKEQZ:
1858 return 0x26 << 15
1859 case AMASKNEZ:
1860 return 0x27 << 15
1861 case AAND:
1862 return 0x29 << 15
1863 case AOR:
1864 return 0x2a << 15
1865 case AXOR:
1866 return 0x2b << 15
1867 case AORN:
1868 return 0x2c << 15
1869 case AANDN:
1870 return 0x2d << 15
1871 case ASUB:
1872 return 0x22 << 15
1873 case ASUBU, ANEGW:
1874 return 0x22 << 15
1875 case ANOR:
1876 return 0x28 << 15
1877 case ASLL:
1878 return 0x2e << 15
1879 case ASRL:
1880 return 0x2f << 15
1881 case ASRA:
1882 return 0x30 << 15
1883 case AROTR:
1884 return 0x36 << 15
1885 case ASLLV:
1886 return 0x31 << 15
1887 case ASRLV:
1888 return 0x32 << 15
1889 case ASRAV:
1890 return 0x33 << 15
1891 case AROTRV:
1892 return 0x37 << 15
1893 case AADDV:
1894 return 0x21 << 15
1895 case AADDVU:
1896 return 0x21 << 15
1897 case ASUBV:
1898 return 0x23 << 15
1899 case ASUBVU, ANEGV:
1900 return 0x23 << 15
1901
1902 case AMUL:
1903 return 0x38 << 15
1904 case AMULU:
1905 return 0x38 << 15
1906 case AMULH:
1907 return 0x39 << 15
1908 case AMULHU:
1909 return 0x3a << 15
1910 case AMULV:
1911 return 0x3b << 15
1912 case AMULVU:
1913 return 0x3b << 15
1914 case AMULHV:
1915 return 0x3c << 15
1916 case AMULHVU:
1917 return 0x3d << 15
1918 case ADIV:
1919 return 0x40 << 15
1920 case ADIVU:
1921 return 0x42 << 15
1922 case ADIVV:
1923 return 0x44 << 15
1924 case ADIVVU:
1925 return 0x46 << 15
1926 case AREM:
1927 return 0x41 << 15
1928 case AREMU:
1929 return 0x43 << 15
1930 case AREMV:
1931 return 0x45 << 15
1932 case AREMVU:
1933 return 0x47 << 15
1934
1935 case AJMP:
1936 return 0x13 << 26
1937 case AJAL:
1938 return (0x13 << 26) | 1
1939
1940 case ADIVF:
1941 return 0x20d << 15
1942 case ADIVD:
1943 return 0x20e << 15
1944 case AMULF:
1945 return 0x209 << 15
1946 case AMULD:
1947 return 0x20a << 15
1948 case ASUBF:
1949 return 0x205 << 15
1950 case ASUBD:
1951 return 0x206 << 15
1952 case AADDF:
1953 return 0x201 << 15
1954 case AADDD:
1955 return 0x202 << 15
1956 case ACMPEQF:
1957 return 0x0c1<<20 | 0x4<<15
1958 case ACMPEQD:
1959 return 0x0c2<<20 | 0x4<<15
1960 case ACMPGED:
1961 return 0x0c2<<20 | 0x7<<15
1962 case ACMPGEF:
1963 return 0x0c1<<20 | 0x7<<15
1964 case ACMPGTD:
1965 return 0x0c2<<20 | 0x3<<15
1966 case ACMPGTF:
1967 return 0x0c1<<20 | 0x3<<15
1968 case AFMINF:
1969 return 0x215 << 15
1970 case AFMIND:
1971 return 0x216 << 15
1972 case AFMAXF:
1973 return 0x211 << 15
1974 case AFMAXD:
1975 return 0x212 << 15
1976 case AFSCALEBF:
1977 return 0x221 << 15
1978 case AFSCALEBD:
1979 return 0x222 << 15
1980 case AFCOPYSGF:
1981 return 0x225 << 15
1982 case AFCOPYSGD:
1983 return 0x226 << 15
1984 case -AMOVB:
1985 return 0x07000 << 15
1986 case -AMOVH:
1987 return 0x07008 << 15
1988 case -AMOVW:
1989 return 0x07010 << 15
1990 case -AMOVV:
1991 return 0x07018 << 15
1992 case -AMOVBU:
1993 return 0x07040 << 15
1994 case -AMOVHU:
1995 return 0x07048 << 15
1996 case -AMOVWU:
1997 return 0x07050 << 15
1998 case AMOVB:
1999 return 0x07020 << 15
2000 case AMOVH:
2001 return 0x07028 << 15
2002 case AMOVW:
2003 return 0x07030 << 15
2004 case AMOVV:
2005 return 0x07038 << 15
2006 case -AMOVF:
2007 return 0x07060 << 15
2008 case -AMOVD:
2009 return 0x07068 << 15
2010 case AMOVF:
2011 return 0x07070 << 15
2012 case AMOVD:
2013 return 0x07078 << 15
2014 }
2015
2016 if a < 0 {
2017 c.ctxt.Diag("bad rrr opcode -%v", -a)
2018 } else {
2019 c.ctxt.Diag("bad rrr opcode %v", a)
2020 }
2021 return 0
2022 }
2023
2024 func (c *ctxt0) oprr(a obj.As) uint32 {
2025 switch a {
2026 case ACLO:
2027 return 0x4 << 10
2028 case ACLZ:
2029 return 0x5 << 10
2030 case ACPUCFG:
2031 return 0x1b << 10
2032 case ARDTIMELW:
2033 return 0x18 << 10
2034 case ARDTIMEHW:
2035 return 0x19 << 10
2036 case ARDTIMED:
2037 return 0x1a << 10
2038 case ATRUNCFV:
2039 return 0x46a9 << 10
2040 case ATRUNCDV:
2041 return 0x46aa << 10
2042 case ATRUNCFW:
2043 return 0x46a1 << 10
2044 case ATRUNCDW:
2045 return 0x46a2 << 10
2046 case AMOVFV:
2047 return 0x46c9 << 10
2048 case AMOVDV:
2049 return 0x46ca << 10
2050 case AMOVVF:
2051 return 0x4746 << 10
2052 case AMOVVD:
2053 return 0x474a << 10
2054 case AMOVFW:
2055 return 0x46c1 << 10
2056 case AMOVDW:
2057 return 0x46c2 << 10
2058 case AMOVWF:
2059 return 0x4744 << 10
2060 case AMOVDF:
2061 return 0x4646 << 10
2062 case AMOVWD:
2063 return 0x4748 << 10
2064 case AMOVFD:
2065 return 0x4649 << 10
2066 case AABSF:
2067 return 0x4501 << 10
2068 case AABSD:
2069 return 0x4502 << 10
2070 case AMOVF:
2071 return 0x4525 << 10
2072 case AMOVD:
2073 return 0x4526 << 10
2074 case ANEGF:
2075 return 0x4505 << 10
2076 case ANEGD:
2077 return 0x4506 << 10
2078 case ASQRTF:
2079 return 0x4511 << 10
2080 case ASQRTD:
2081 return 0x4512 << 10
2082 case AFLOGBF:
2083 return 0x4509 << 10
2084 case AFLOGBD:
2085 return 0x450a << 10
2086 case AFCLASSF:
2087 return 0x450d << 10
2088 case AFCLASSD:
2089 return 0x450e << 10
2090 case AFFINTFW:
2091 return 0x4744 << 10
2092 case AFFINTFV:
2093 return 0x4746 << 10
2094 case AFFINTDW:
2095 return 0x4748 << 10
2096 case AFFINTDV:
2097 return 0x474a << 10
2098 case AFTINTWF:
2099 return 0x46c1 << 10
2100 case AFTINTWD:
2101 return 0x46c2 << 10
2102 case AFTINTVF:
2103 return 0x46c9 << 10
2104 case AFTINTVD:
2105 return 0x46ca << 10
2106 case AFTINTRMWF:
2107 return 0x4681 << 10
2108 case AFTINTRMWD:
2109 return 0x4682 << 10
2110 case AFTINTRMVF:
2111 return 0x4689 << 10
2112 case AFTINTRMVD:
2113 return 0x468a << 10
2114 case AFTINTRPWF:
2115 return 0x4691 << 10
2116 case AFTINTRPWD:
2117 return 0x4692 << 10
2118 case AFTINTRPVF:
2119 return 0x4699 << 10
2120 case AFTINTRPVD:
2121 return 0x469a << 10
2122 case AFTINTRZWF:
2123 return 0x46a1 << 10
2124 case AFTINTRZWD:
2125 return 0x46a2 << 10
2126 case AFTINTRZVF:
2127 return 0x46a9 << 10
2128 case AFTINTRZVD:
2129 return 0x46aa << 10
2130 case AFTINTRNEWF:
2131 return 0x46b1 << 10
2132 case AFTINTRNEWD:
2133 return 0x46b2 << 10
2134 case AFTINTRNEVF:
2135 return 0x46b9 << 10
2136 case AFTINTRNEVD:
2137 return 0x46ba << 10
2138 }
2139
2140 c.ctxt.Diag("bad rr opcode %v", a)
2141 return 0
2142 }
2143
2144 func (c *ctxt0) opi(a obj.As) uint32 {
2145 switch a {
2146 case ASYSCALL:
2147 return 0x56 << 15
2148 case ABREAK:
2149 return 0x54 << 15
2150 case ADBAR:
2151 return 0x70e4 << 15
2152 }
2153
2154 c.ctxt.Diag("bad ic opcode %v", a)
2155
2156 return 0
2157 }
2158
2159 func (c *ctxt0) opir(a obj.As) uint32 {
2160 switch a {
2161 case ALU12IW:
2162 return 0x0a << 25
2163 case ALU32ID:
2164 return 0x0b << 25
2165 case APCALAU12I:
2166 return 0x0d << 25
2167 case APCADDU12I:
2168 return 0x0e << 25
2169 }
2170 return 0
2171 }
2172
2173 func (c *ctxt0) opirr(a obj.As) uint32 {
2174 switch a {
2175 case AADD, AADDU:
2176 return 0x00a << 22
2177 case ASGT:
2178 return 0x008 << 22
2179 case ASGTU:
2180 return 0x009 << 22
2181 case AAND:
2182 return 0x00d << 22
2183 case AOR:
2184 return 0x00e << 22
2185 case ALU52ID:
2186 return 0x00c << 22
2187 case AXOR:
2188 return 0x00f << 22
2189 case ASLL:
2190 return 0x00081 << 15
2191 case ASRL:
2192 return 0x00089 << 15
2193 case ASRA:
2194 return 0x00091 << 15
2195 case AROTR:
2196 return 0x00099 << 15
2197 case AADDV:
2198 return 0x00b << 22
2199 case AADDVU:
2200 return 0x00b << 22
2201
2202 case AJMP:
2203 return 0x14 << 26
2204 case AJAL,
2205 obj.ADUFFZERO,
2206 obj.ADUFFCOPY:
2207 return 0x15 << 26
2208
2209 case AJIRL:
2210 return 0x13 << 26
2211 case ABLTU:
2212 return 0x1a << 26
2213 case ABLT, ABLTZ, ABGTZ:
2214 return 0x18 << 26
2215 case ABGEU:
2216 return 0x1b << 26
2217 case ABGE, ABGEZ, ABLEZ:
2218 return 0x19 << 26
2219 case -ABEQ:
2220 return 0x10 << 26
2221 case -ABNE:
2222 return 0x11 << 26
2223 case ABEQ:
2224 return 0x16 << 26
2225 case ABNE:
2226 return 0x17 << 26
2227 case ABFPT:
2228 return 0x12<<26 | 0x1<<8
2229 case ABFPF:
2230 return 0x12<<26 | 0x0<<8
2231
2232 case AMOVB,
2233 AMOVBU:
2234 return 0x0a4 << 22
2235 case AMOVH,
2236 AMOVHU:
2237 return 0x0a5 << 22
2238 case AMOVW,
2239 AMOVWU:
2240 return 0x0a6 << 22
2241 case AMOVV:
2242 return 0x0a7 << 22
2243 case AMOVF:
2244 return 0x0ad << 22
2245 case AMOVD:
2246 return 0x0af << 22
2247 case -AMOVB:
2248 return 0x0a0 << 22
2249 case -AMOVBU:
2250 return 0x0a8 << 22
2251 case -AMOVH:
2252 return 0x0a1 << 22
2253 case -AMOVHU:
2254 return 0x0a9 << 22
2255 case -AMOVW:
2256 return 0x0a2 << 22
2257 case -AMOVWU:
2258 return 0x0aa << 22
2259 case -AMOVV:
2260 return 0x0a3 << 22
2261 case -AMOVF:
2262 return 0x0ac << 22
2263 case -AMOVD:
2264 return 0x0ae << 22
2265
2266 case ASLLV:
2267 return 0x0041 << 16
2268 case ASRLV:
2269 return 0x0045 << 16
2270 case ASRAV:
2271 return 0x0049 << 16
2272 case AROTRV:
2273 return 0x004d << 16
2274 case -ALL:
2275 return 0x020 << 24
2276 case -ALLV:
2277 return 0x022 << 24
2278 case ASC:
2279 return 0x021 << 24
2280 case ASCV:
2281 return 0x023 << 24
2282 }
2283
2284 if a < 0 {
2285 c.ctxt.Diag("bad irr opcode -%v", -a)
2286 } else {
2287 c.ctxt.Diag("bad irr opcode %v", a)
2288 }
2289 return 0
2290 }
2291
2292 func (c *ctxt0) opirir(a obj.As) uint32 {
2293 switch a {
2294 case ABSTRINSW:
2295 return 0x3<<21 | 0x0<<15
2296 case ABSTRINSV:
2297 return 0x2 << 22
2298 case ABSTRPICKW:
2299 return 0x3<<21 | 0x1<<15
2300 case ABSTRPICKV:
2301 return 0x3 << 22
2302 }
2303
2304 return 0
2305 }
2306
2307 func (c *ctxt0) specailFpMovInst(a obj.As, fclass int, tclass int) uint32 {
2308 switch a {
2309 case AMOVV:
2310 switch fclass {
2311 case C_REG:
2312 switch tclass {
2313 case C_FREG:
2314 return 0x452a << 10
2315 case C_FCCREG:
2316 return 0x4536 << 10
2317 case C_FCSRREG:
2318 return 0x4530 << 10
2319 }
2320 case C_FREG:
2321 switch tclass {
2322 case C_REG:
2323 return 0x452e << 10
2324 case C_FCCREG:
2325 return 0x4534 << 10
2326 }
2327 case C_FCCREG:
2328 switch tclass {
2329 case C_REG:
2330 return 0x4537 << 10
2331 case C_FREG:
2332 return 0x4535 << 10
2333 }
2334 case C_FCSRREG:
2335 switch tclass {
2336 case C_REG:
2337 return 0x4532 << 10
2338 }
2339 }
2340
2341 case AMOVW:
2342 switch fclass {
2343 case C_REG:
2344 switch tclass {
2345 case C_FREG:
2346 return 0x4529 << 10
2347 }
2348 case C_FREG:
2349 switch tclass {
2350 case C_REG:
2351 return 0x452d << 10
2352 }
2353 }
2354 }
2355
2356 c.ctxt.Diag("bad class combination: %s %s,%s\n", a, fclass, tclass)
2357
2358 return 0
2359 }
2360
2361 func vshift(a obj.As) bool {
2362 switch a {
2363 case ASLLV,
2364 ASRLV,
2365 ASRAV,
2366 AROTRV:
2367 return true
2368 }
2369 return false
2370 }
2371
View as plain text