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