1(import srfi-151)
2
3;; Size of instruction in bits.
4;; XXX: Compressed instructions currently not supported.
5(define INSTR_SIZE 32)
6
7;; Wrapper around bit-field to support the imm[end:start]
8;; syntax used in the RISC-V specification.
9(define (imm-field instr end start)
10 (bit-field instr start (+ end 1)))
11(define (imm-field-single instr pos)
12 (imm-field instr pos pos))
13
14(define (to-twocomp numbits input)
15 (let ((max (/ (expt 2 numbits) 2)))
16 (if (or (>= input max)
17 (< input (* -1 max)))
18 (error "given signed value too large for field")
19 (if (negative? input)
20 (+ (expt 2 numbits) input)
21 input))))
22
23(define (new-field value size position)
24 (if (> value (- (expt 2 size) 1))
25 (error "given value too large for field")
26 (arithmetic-shift value position)))
27
28(define-syntax new-instr
29 (syntax-rules (field)
30 ((new-instr N (field val siz))
31 (new-field val siz (- N siz)))
32 ((new-instr N (field val siz) fields ...)
33 (bitwise-ior
34 (new-instr N (field val siz))
35 (new-instr (- N siz) fields ...)))))
36
37(define (r-type opcode funct3 funct7
38 rs1 rs2 rd)
39 (new-instr INSTR_SIZE
40 (field funct7 7)
41 (field rs2 5)
42 (field rs1 5)
43 (field funct3 3)
44 (field rd 5)
45 (field opcode 7)))
46
47(define (i-type opcode funct3 rs1 rd imm)
48 (let ((imm-signed (to-twocomp 12 imm)))
49 (new-instr INSTR_SIZE
50 (field imm-signed 12)
51 (field rs1 5)
52 (field funct3 3)
53 (field rd 5)
54 (field opcode 7))))
55
56(define (s-type opcode funct3 rs1 rs2 imm)
57 (let ((imm-signed (to-twocomp 12 imm)))
58 (new-instr INSTR_SIZE
59 (field (imm-field imm-signed 11 5) 7)
60 (field rs2 5)
61 (field rs1 5)
62 (field funct3 3)
63 (field (imm-field imm-signed 4 0) 5)
64 (field opcode 7))))
65
66(define (b-type opcode funct3 rs1 rs2 imm)
67 (let ((imm-signed (to-twocomp 12 imm)))
68 (new-instr INSTR_SIZE
69 (field (imm-field-single imm-signed 12) 1)
70 (field (imm-field imm-signed 10 5) 6)
71 (field rs2 5)
72 (field rs1 5)
73 (field funct3 3)
74 (field (imm-field imm-signed 4 1) 4)
75 (field (imm-field-single imm-signed 11) 1)
76 (field opcode 7))))
77
78(define (u-type opcode rd imm)
79 (new-instr INSTR_SIZE
80 (field imm 20)
81 (field rd 5)
82 (field opcode 7)))
83
84(define (j-type opcode rd imm)
85 (new-instr INSTR_SIZE
86 (field (imm-field-single imm 20) 1)
87 (field (imm-field imm 10 1) 10)
88 (field (imm-field-single imm 11) 1)
89 (field (imm-field imm 19 12) 8)
90 (field rd 5)
91 (field opcode 7)))