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