1
2
3
4
5 package loong64asm
6
7 import (
8 "encoding/binary"
9 "fmt"
10 )
11
12 type instArgs [5]instArg
13
14
15 type instFormat struct {
16 mask uint32
17 value uint32
18 op Op
19
20
21
22
23 args instArgs
24 }
25
26 var (
27 errShort = fmt.Errorf("truncated instruction")
28 errUnknown = fmt.Errorf("unknown instruction")
29 )
30
31 var decoderCover []bool
32
33 func init() {
34 decoderCover = make([]bool, len(instFormats))
35 }
36
37
38 func Decode(src []byte) (inst Inst, err error) {
39 if len(src) < 4 {
40 return Inst{}, errShort
41 }
42
43 x := binary.LittleEndian.Uint32(src)
44
45 Search:
46 for i := range instFormats {
47 f := &instFormats[i]
48
49 if (x & f.mask) != f.value {
50 continue
51 }
52
53
54 var args Args
55 for j, aop := range f.args {
56 if aop == 0 {
57 break
58 }
59
60 arg := decodeArg(aop, x, i)
61 if arg == nil {
62
63 continue Search
64 }
65
66 args[j] = arg
67 }
68
69 decoderCover[i] = true
70 inst = Inst{
71 Op: f.op,
72 Args: args,
73 Enc: x,
74 }
75 return inst, nil
76 }
77
78 return Inst{}, errUnknown
79 }
80
81
82
83 func decodeArg(aop instArg, x uint32, index int) Arg {
84 switch aop {
85 case arg_fd:
86 return F0 + Reg(x&((1<<5)-1))
87
88 case arg_fj:
89 return F0 + Reg((x>>5)&((1<<5)-1))
90
91 case arg_fk:
92 return F0 + Reg((x>>10)&((1<<5)-1))
93
94 case arg_fa:
95 return F0 + Reg((x>>15)&((1<<5)-1))
96
97 case arg_rd:
98 return R0 + Reg(x&((1<<5)-1))
99
100 case arg_rj:
101 return R0 + Reg((x>>5)&((1<<5)-1))
102
103 case arg_rk:
104 return R0 + Reg((x>>10)&((1<<5)-1))
105
106 case arg_fcsr_4_0:
107 return FCSR0 + Fcsr(x&((1<<5)-1))
108
109 case arg_fcsr_9_5:
110 return FCSR0 + Fcsr((x>>5)&((1<<5)-1))
111
112 case arg_cd:
113 return FCC0 + Fcc(x&((1<<3)-1))
114
115 case arg_cj:
116 return FCC0 + Fcc((x>>5)&((1<<3)-1))
117
118 case arg_ca:
119 return FCC0 + Fcc((x>>15)&((1<<3)-1))
120
121 case arg_op_4_0:
122 tmp := x & ((1 << 5) - 1)
123 return Uimm{tmp, false}
124
125 case arg_csr_23_10:
126 tmp := (x >> 10) & ((1 << 14) - 1)
127 return Uimm{tmp, false}
128
129 case arg_sa2_16_15:
130 f := &instFormats[index]
131 tmp := SaSimm((x >> 15) & ((1 << 2) - 1))
132 if (f.op == ALSL_D) || (f.op == ALSL_W) || (f.op == ALSL_WU) {
133 return tmp + 1
134 } else {
135 return tmp + 0
136 }
137
138 case arg_sa3_17_15:
139 return SaSimm((x >> 15) & ((1 << 3) - 1))
140
141 case arg_code_4_0:
142 return CodeSimm(x & ((1 << 5) - 1))
143
144 case arg_code_14_0:
145 return CodeSimm(x & ((1 << 15) - 1))
146
147 case arg_ui5_14_10:
148 tmp := (x >> 10) & ((1 << 5) - 1)
149 return Uimm{tmp, false}
150
151 case arg_ui6_15_10:
152 tmp := (x >> 10) & ((1 << 6) - 1)
153 return Uimm{tmp, false}
154
155 case arg_ui12_21_10:
156 tmp := ((x >> 10) & ((1 << 12) - 1) & 0xfff)
157 return Uimm{tmp, false}
158
159 case arg_lsbw:
160 tmp := (x >> 10) & ((1 << 5) - 1)
161 return Uimm{tmp, false}
162
163 case arg_msbw:
164 tmp := (x >> 16) & ((1 << 5) - 1)
165 return Uimm{tmp, false}
166
167 case arg_lsbd:
168 tmp := (x >> 10) & ((1 << 6) - 1)
169 return Uimm{tmp, false}
170
171 case arg_msbd:
172 tmp := (x >> 16) & ((1 << 6) - 1)
173 return Uimm{tmp, false}
174
175 case arg_hint_4_0:
176 tmp := x & ((1 << 5) - 1)
177 return Uimm{tmp, false}
178
179 case arg_hint_14_0:
180 tmp := x & ((1 << 15) - 1)
181 return Uimm{tmp, false}
182
183 case arg_level_14_0:
184 tmp := x & ((1 << 15) - 1)
185 return Uimm{tmp, false}
186
187 case arg_level_17_10:
188 tmp := (x >> 10) & ((1 << 8) - 1)
189 return Uimm{tmp, false}
190
191 case arg_seq_17_10:
192 tmp := (x >> 10) & ((1 << 8) - 1)
193 return Uimm{tmp, false}
194
195 case arg_si12_21_10:
196 var tmp int16
197
198
199 if (x & 0x200000) == 0x200000 {
200 tmp = int16(((x >> 10) & ((1 << 12) - 1)) | 0xf000)
201 } else {
202 tmp = int16(((x >> 10) & ((1 << 12) - 1)) | 0x0000)
203 }
204 return Simm16{tmp, 12}
205
206 case arg_si14_23_10:
207 var tmp int32
208 if (x & 0x800000) == 0x800000 {
209 tmp = int32((((x >> 10) & ((1 << 14) - 1)) << 2) | 0xffff0000)
210 } else {
211 tmp = int32((((x >> 10) & ((1 << 14) - 1)) << 2) | 0x00000000)
212 }
213 return Simm32{tmp, 14}
214
215 case arg_si16_25_10:
216 var tmp int32
217
218 if (x & 0x2000000) == 0x2000000 {
219 tmp = int32(((x >> 10) & ((1 << 16) - 1)) | 0xffff0000)
220 } else {
221 tmp = int32(((x >> 10) & ((1 << 16) - 1)) | 0x00000000)
222 }
223
224 return Simm32{tmp, 16}
225
226 case arg_si20_24_5:
227 var tmp int32
228 if (x & 0x1000000) == 0x1000000 {
229 tmp = int32(((x >> 5) & ((1 << 20) - 1)) | 0xfff00000)
230 } else {
231 tmp = int32(((x >> 5) & ((1 << 20) - 1)) | 0x00000000)
232 }
233 return Simm32{tmp, 20}
234
235 case arg_offset_20_0:
236 var tmp int32
237
238 if (x & 0x10) == 0x10 {
239 tmp = int32(((((x << 16) | ((x >> 10) & ((1 << 16) - 1))) & ((1 << 21) - 1)) << 2) | 0xff800000)
240 } else {
241 tmp = int32((((x << 16) | ((x >> 10) & ((1 << 16) - 1))) & ((1 << 21) - 1)) << 2)
242 }
243
244 return OffsetSimm{tmp, 21}
245
246 case arg_offset_15_0:
247 var tmp int32
248 if (x & 0x2000000) == 0x2000000 {
249 tmp = int32((((x >> 10) & ((1 << 16) - 1)) << 2) | 0xfffc0000)
250 } else {
251 tmp = int32((((x >> 10) & ((1 << 16) - 1)) << 2) | 0x00000000)
252 }
253
254 return OffsetSimm{tmp, 16}
255
256 case arg_offset_25_0:
257 var tmp int32
258
259 if (x & 0x200) == 0x200 {
260 tmp = int32(((((x << 16) | ((x >> 10) & ((1 << 16) - 1))) & ((1 << 26) - 1)) << 2) | 0xf0000000)
261 } else {
262 tmp = int32(((((x << 16) | ((x >> 10) & ((1 << 16) - 1))) & ((1 << 26) - 1)) << 2) | 0x00000000)
263 }
264
265 return OffsetSimm{tmp, 26}
266 default:
267 return nil
268 }
269 }
270
View as plain text