1
2
3
4
5 package riscv64asm
6
7 import (
8 "encoding/binary"
9 "errors"
10 )
11
12 type argTypeList [6]argType
13
14
15 type instFormat struct {
16 mask uint32
17 value uint32
18 op Op
19
20
21
22
23 args argTypeList
24 }
25
26 var (
27 errShort = errors.New("truncated instruction")
28 errUnknown = errors.New("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, error) {
39 length := len(src)
40 if length < 2 {
41 return Inst{}, errShort
42 }
43
44 var x uint32
45
46
47 if src[0]&3 == 3 {
48 if length < 4 {
49 return Inst{}, errShort
50 }
51 length = 4
52 x = binary.LittleEndian.Uint32(src)
53 } else {
54 length = 2
55 x = uint32(binary.LittleEndian.Uint16(src))
56 }
57
58 Search:
59 for i, f := range instFormats {
60 if (x & f.mask) != f.value {
61 continue
62 }
63
64
65 var args Args
66 for j, aop := range f.args {
67 if aop == 0 {
68 break
69 }
70 arg := decodeArg(aop, x, i)
71 if arg == nil && f.op != C_NOP {
72
73 continue Search
74 }
75 args[j] = arg
76 }
77
78 if length == 2 {
79 args = convertCompressedIns(&f, args)
80 }
81
82 decoderCover[i] = true
83 inst := Inst{
84 Op: f.op,
85 Args: args,
86 Enc: x,
87 Len: length,
88 }
89 return inst, nil
90 }
91 return Inst{}, errUnknown
92 }
93
94
95
96 func decodeArg(aop argType, x uint32, index int) Arg {
97 switch aop {
98 case arg_rd:
99 return X0 + Reg((x>>7)&((1<<5)-1))
100
101 case arg_rs1:
102 return X0 + Reg((x>>15)&((1<<5)-1))
103
104 case arg_rs2:
105 return X0 + Reg((x>>20)&((1<<5)-1))
106
107 case arg_rs3:
108 return X0 + Reg((x>>27)&((1<<5)-1))
109
110 case arg_fd:
111 return F0 + Reg((x>>7)&((1<<5)-1))
112
113 case arg_fs1:
114 return F0 + Reg((x>>15)&((1<<5)-1))
115
116 case arg_fs2:
117 return F0 + Reg((x>>20)&((1<<5)-1))
118
119 case arg_fs3:
120 return F0 + Reg((x>>27)&((1<<5)-1))
121
122 case arg_rs1_amo:
123 return AmoReg{X0 + Reg((x>>15)&((1<<5)-1))}
124
125 case arg_rs1_mem:
126 imm := x >> 20
127
128 if imm>>uint32(12-1) == 1 {
129 imm |= 0xfffff << 12
130 }
131 return RegOffset{X0 + Reg((x>>15)&((1<<5)-1)), Simm{int32(imm), true, 12}}
132
133 case arg_rs1_store:
134 imm := (x<<20)>>27 | (x>>25)<<5
135
136 if imm>>uint32(12-1) == 1 {
137 imm |= 0xfffff << 12
138 }
139 return RegOffset{X0 + Reg((x>>15)&((1<<5)-1)), Simm{int32(imm), true, 12}}
140
141 case arg_pred:
142 imm := x << 4 >> 28
143 return MemOrder(uint8(imm))
144
145 case arg_succ:
146 imm := x << 8 >> 28
147 return MemOrder(uint8(imm))
148
149 case arg_csr:
150 imm := x >> 20
151 return CSR(imm)
152
153 case arg_zimm:
154 imm := x << 12 >> 27
155 return Uimm{imm, true}
156
157 case arg_shamt5:
158 imm := x << 7 >> 27
159 return Uimm{imm, false}
160
161 case arg_shamt6:
162 imm := x << 6 >> 26
163 return Uimm{imm, false}
164
165 case arg_imm12:
166 imm := x >> 20
167
168 if imm>>uint32(12-1) == 1 {
169 imm |= 0xfffff << 12
170 }
171 return Simm{int32(imm), true, 12}
172
173 case arg_imm20:
174 imm := x >> 12
175 return Uimm{imm, false}
176
177 case arg_jimm20:
178 imm := (x>>31)<<20 | (x<<1)>>22<<1 | (x<<11)>>31<<11 | (x<<12)>>24<<12
179
180 if imm>>uint32(21-1) == 1 {
181 imm |= 0x7ff << 21
182 }
183 return Simm{int32(imm), true, 21}
184
185 case arg_simm12:
186 imm := (x<<20)>>27 | (x>>25)<<5
187
188 if imm>>uint32(12-1) == 1 {
189 imm |= 0xfffff << 12
190 }
191 return Simm{int32(imm), true, 12}
192
193 case arg_bimm12:
194 imm := (x<<20)>>28<<1 | (x<<1)>>26<<5 | (x<<24)>>31<<11 | (x>>31)<<12
195
196 if imm>>uint32(13-1) == 1 {
197 imm |= 0x7ffff << 13
198 }
199 return Simm{int32(imm), true, 13}
200
201 case arg_rd_p, arg_rs2_p:
202 return X8 + Reg((x>>2)&((1<<3)-1))
203
204 case arg_fd_p, arg_fs2_p:
205 return F8 + Reg((x>>2)&((1<<3)-1))
206
207 case arg_rs1_p, arg_rd_rs1_p:
208 return X8 + Reg((x>>7)&((1<<3)-1))
209
210 case arg_rd_n0, arg_rs1_n0, arg_rd_rs1_n0, arg_c_rs1_n0:
211 if X0+Reg((x>>7)&((1<<5)-1)) == X0 {
212 return nil
213 }
214 return X0 + Reg((x>>7)&((1<<5)-1))
215
216 case arg_c_rs2_n0:
217 if X0+Reg((x>>2)&((1<<5)-1)) == X0 {
218 return nil
219 }
220 return X0 + Reg((x>>2)&((1<<5)-1))
221
222 case arg_c_fs2:
223 return F0 + Reg((x>>2)&((1<<5)-1))
224
225 case arg_c_rs2:
226 return X0 + Reg((x>>2)&((1<<5)-1))
227
228 case arg_rd_n2:
229 if X0+Reg((x>>7)&((1<<5)-1)) == X0 || X0+Reg((x>>7)&((1<<5)-1)) == X2 {
230 return nil
231 }
232 return X0 + Reg((x>>7)&((1<<5)-1))
233
234 case arg_c_imm6:
235 imm := (x<<25)>>27 | (x<<19)>>31<<5
236
237 if imm>>uint32(6-1) == 1 {
238 imm |= 0x3ffffff << 6
239 }
240 return Simm{int32(imm), true, 6}
241
242 case arg_c_nzimm6:
243 imm := (x<<25)>>27 | (x<<19)>>31<<5
244
245 if imm>>uint32(6-1) == 1 {
246 imm |= 0x3ffffff << 6
247 }
248 if int32(imm) == 0 {
249 return nil
250 }
251 return Simm{int32(imm), true, 6}
252
253 case arg_c_nzuimm6:
254 imm := (x<<25)>>27 | (x<<19)>>31<<5
255 if int32(imm) == 0 {
256 return nil
257 }
258 return Uimm{imm, false}
259
260 case arg_c_uimm7:
261 imm := (x<<26)>>31<<6 | (x<<25)>>31<<2 | (x<<19)>>29<<3
262 return Uimm{imm, false}
263
264 case arg_c_uimm8:
265 imm := (x<<25)>>30<<6 | (x<<19)>>29<<3
266 return Uimm{imm, false}
267
268 case arg_c_uimm8sp_s:
269 imm := (x<<23)>>30<<6 | (x<<19)>>28<<2
270 return Uimm{imm, false}
271
272 case arg_c_uimm8sp:
273 imm := (x<<25)>>29<<2 | (x<<19)>>31<<5 | (x<<28)>>30<<6
274 return Uimm{imm, false}
275
276 case arg_c_uimm9sp_s:
277 imm := (x<<22)>>29<<6 | (x<<19)>>29<<3
278 return Uimm{imm, false}
279
280 case arg_c_uimm9sp:
281 imm := (x<<25)>>30<<3 | (x<<19)>>31<<5 | (x<<27)>>29<<6
282 return Uimm{imm, false}
283
284 case arg_c_bimm9:
285 imm := (x<<29)>>31<<5 | (x<<27)>>30<<1 | (x<<25)>>30<<6 | (x<<19)>>31<<8 | (x<<20)>>30<<3
286
287 if imm>>uint32(9-1) == 1 {
288 imm |= 0x7fffff << 9
289 }
290 return Simm{int32(imm), true, 9}
291
292 case arg_c_nzimm10:
293 imm := (x<<29)>>31<<5 | (x<<27)>>30<<7 | (x<<26)>>31<<6 | (x<<25)>>31<<4 | (x<<19)>>31<<9
294
295 if imm>>uint32(10-1) == 1 {
296 imm |= 0x3fffff << 10
297 }
298 if int32(imm) == 0 {
299 return nil
300 }
301 return Simm{int32(imm), true, 10}
302
303 case arg_c_nzuimm10:
304 imm := (x<<26)>>31<<3 | (x<<25)>>31<<2 | (x<<21)>>28<<6 | (x<<19)>>30<<4
305 if int32(imm) == 0 {
306 return nil
307 }
308 return Uimm{imm, false}
309
310 case arg_c_imm12:
311 imm := (x<<29)>>31<<5 | (x<<26)>>28<<1 | (x<<25)>>31<<7 | (x<<24)>>31<<6 | (x<<23)>>31<<10 | (x<<21)>>30<<8 | (x<<20)>>31<<4 | (x<<19)>>31<<11
312
313 if imm>>uint32(12-1) == 1 {
314 imm |= 0xfffff << 12
315 }
316 return Simm{int32(imm), true, 12}
317
318 case arg_c_nzimm18:
319 imm := (x<<25)>>27<<12 | (x<<19)>>31<<17
320
321 if imm>>uint32(18-1) == 1 {
322 imm |= 0x3fff << 18
323 }
324 if int32(imm) == 0 {
325 return nil
326 }
327 return Simm{int32(imm), true, 18}
328
329 default:
330 return nil
331 }
332 }
333
334
335 func convertCompressedIns(f *instFormat, args Args) Args {
336 var newargs Args
337 switch f.op {
338 case C_ADDI4SPN:
339 f.op = ADDI
340 newargs[0] = args[0]
341 newargs[1] = Reg(X2)
342 newargs[2] = Simm{int32(args[1].(Uimm).Imm), true, 12}
343
344 case C_LW:
345 f.op = LW
346 newargs[0] = args[0]
347 newargs[1] = RegOffset{args[1].(Reg), Simm{int32(args[2].(Uimm).Imm), true, 12}}
348
349 case C_SW:
350 f.op = SW
351 newargs[0] = args[1]
352 newargs[1] = RegOffset{args[0].(Reg), Simm{int32(args[2].(Uimm).Imm), true, 12}}
353
354 case C_NOP:
355 f.op = ADDI
356 newargs[0] = X0
357 newargs[1] = X0
358 newargs[2] = Simm{0, true, 12}
359
360 case C_ADDI:
361 f.op = ADDI
362 newargs[0] = args[0]
363 newargs[1] = args[0]
364 newargs[2] = Simm{args[1].(Simm).Imm, true, 12}
365
366 case C_LI:
367 f.op = ADDI
368 newargs[0] = args[0]
369 newargs[1] = Reg(X0)
370 newargs[2] = Simm{args[1].(Simm).Imm, true, 12}
371
372 case C_ADDI16SP:
373 f.op = ADDI
374 newargs[0] = Reg(X2)
375 newargs[1] = Reg(X2)
376 newargs[2] = Simm{args[0].(Simm).Imm, true, 12}
377
378 case C_LUI:
379 f.op = LUI
380 newargs[0] = args[0]
381 newargs[1] = Uimm{uint32(args[1].(Simm).Imm >> 12), false}
382
383 case C_ANDI:
384 f.op = ANDI
385 newargs[0] = args[0]
386 newargs[1] = args[0]
387 newargs[2] = Simm{args[1].(Simm).Imm, true, 12}
388
389 case C_SUB:
390 f.op = SUB
391 newargs[0] = args[0]
392 newargs[1] = args[0]
393 newargs[2] = args[1]
394
395 case C_XOR:
396 f.op = XOR
397 newargs[0] = args[0]
398 newargs[1] = args[0]
399 newargs[2] = args[1]
400
401 case C_OR:
402 f.op = OR
403 newargs[0] = args[0]
404 newargs[1] = args[0]
405 newargs[2] = args[1]
406
407 case C_AND:
408 f.op = AND
409 newargs[0] = args[0]
410 newargs[1] = args[0]
411 newargs[2] = args[1]
412
413 case C_J:
414 f.op = JAL
415 newargs[0] = Reg(X0)
416 newargs[1] = Simm{args[0].(Simm).Imm, true, 21}
417
418 case C_BEQZ:
419 f.op = BEQ
420 newargs[0] = args[0]
421 newargs[1] = Reg(X0)
422 newargs[2] = Simm{args[1].(Simm).Imm, true, 13}
423
424 case C_BNEZ:
425 f.op = BNE
426 newargs[0] = args[0]
427 newargs[1] = Reg(X0)
428 newargs[2] = Simm{args[1].(Simm).Imm, true, 13}
429
430 case C_LWSP:
431 f.op = LW
432 newargs[0] = args[0]
433 newargs[1] = RegOffset{Reg(X2), Simm{int32(args[1].(Uimm).Imm), true, 12}}
434
435 case C_JR:
436 f.op = JALR
437 newargs[0] = Reg(X0)
438 newargs[1] = RegOffset{args[0].(Reg), Simm{0, true, 12}}
439
440 case C_MV:
441 f.op = ADD
442 newargs[0] = args[0]
443 newargs[1] = Reg(X0)
444 newargs[2] = args[1]
445
446 case C_EBREAK:
447 f.op = EBREAK
448
449 case C_JALR:
450 f.op = JALR
451 newargs[0] = Reg(X1)
452 newargs[1] = RegOffset{args[0].(Reg), Simm{0, true, 12}}
453
454 case C_ADD:
455 f.op = ADD
456 newargs[0] = args[0]
457 newargs[1] = args[0]
458 newargs[2] = args[1]
459
460 case C_SWSP:
461 f.op = SW
462 newargs[0] = args[0]
463 newargs[1] = RegOffset{Reg(X2), Simm{int32(args[1].(Uimm).Imm), true, 12}}
464
465
466 case C_LD:
467 f.op = LD
468 newargs[0] = args[0]
469 newargs[1] = RegOffset{args[1].(Reg), Simm{int32(args[2].(Uimm).Imm), true, 12}}
470
471 case C_SD:
472 f.op = SD
473 newargs[0] = args[1]
474 newargs[1] = RegOffset{args[0].(Reg), Simm{int32(args[2].(Uimm).Imm), true, 12}}
475
476 case C_ADDIW:
477 f.op = ADDIW
478 newargs[0] = args[0]
479 newargs[1] = args[0]
480 newargs[2] = Simm{args[1].(Simm).Imm, true, 12}
481
482 case C_SRLI:
483 f.op = SRLI
484 newargs[0] = args[0]
485 newargs[1] = args[0]
486 newargs[2] = args[1]
487
488 case C_SRAI:
489 f.op = SRAI
490 newargs[0] = args[0]
491 newargs[1] = args[0]
492 newargs[2] = args[1]
493
494 case C_SUBW:
495 f.op = SUBW
496 newargs[0] = args[0]
497 newargs[1] = args[0]
498 newargs[2] = args[1]
499
500 case C_ADDW:
501 f.op = ADDW
502 newargs[0] = args[0]
503 newargs[1] = args[0]
504 newargs[2] = args[1]
505
506 case C_SLLI:
507 f.op = SLLI
508 newargs[0] = args[0]
509 newargs[1] = args[0]
510 newargs[2] = args[1]
511
512 case C_LDSP:
513 f.op = LD
514 newargs[0] = args[0]
515 newargs[1] = RegOffset{Reg(X2), Simm{int32(args[1].(Uimm).Imm), true, 12}}
516
517 case C_SDSP:
518 f.op = SD
519 newargs[0] = args[0]
520 newargs[1] = RegOffset{Reg(X2), Simm{int32(args[1].(Uimm).Imm), true, 12}}
521
522
523 case C_FLD:
524 f.op = FLD
525 newargs[0] = args[0]
526 newargs[1] = RegOffset{args[1].(Reg), Simm{int32(args[2].(Uimm).Imm), true, 12}}
527
528 case C_FSD:
529 f.op = FSD
530 newargs[0] = args[1]
531 newargs[1] = RegOffset{args[0].(Reg), Simm{int32(args[2].(Uimm).Imm), true, 12}}
532
533 case C_FLDSP:
534 f.op = FLD
535 newargs[0] = args[0]
536 newargs[1] = RegOffset{Reg(X2), Simm{int32(args[1].(Uimm).Imm), true, 12}}
537
538 case C_FSDSP:
539 f.op = FSD
540 newargs[0] = args[0]
541 newargs[1] = RegOffset{Reg(X2), Simm{int32(args[1].(Uimm).Imm), true, 12}}
542
543 case C_UNIMP:
544 f.op = CSRRW
545 newargs[0] = Reg(X0)
546 newargs[1] = CSR(CYCLE)
547 newargs[2] = Reg(X0)
548 }
549 return newargs
550 }
551
View as plain text