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