1(import srfi-151)
2
3;;;;
4;; Utility procedures
5;;;;
6
7;; The bit-field procedure from SRFI-151 returns a bit field in the
8;; interval [start, end - 1]. Contrary to bit-field, instr-field returns
9;; a field in the interval [start, end] to allow using the same notation
10;; as used by the RISC-V specification.
11(define (instr-field instr start end)
12 (bit-field instr start (+ end 1)))
13
14;; https://en.wikipedia.org/wiki/Two%27s_complement#Converting_from_two's_complement_representation
15(define (from-twocomp numbits input)
16 (let ((mask (expt 2 (- numbits 1))))
17 (+ (* -1 (bitwise-and input mask))
18 (bitwise-and input (bitwise-not mask)))))
19
20;;;;
21;; Instruction fields
22;;;;
23
24(define (instr-opcode instr)
25 (instr-field instr 0 6))
26
27(define (instr-funct3 instr)
28 (instr-field instr 12 14))
29
30(define (instr-funct7 instr)
31 (instr-field instr 25 31))
32
33(define (instr-rs1 instr)
34 (instr-field instr 15 19))
35
36(define (instr-rs2 instr)
37 (instr-field instr 20 24))
38
39(define (instr-rd instr)
40 (instr-field instr 7 11))
41
42;;;;
43;; Instruction immediates
44;;;
45
46(define (instr-i-imm instr)
47 (from-twocomp 12
48 (instr-field instr 20 31)))
49
50(define (instr-s-imm instr)
51 (from-twocomp 12
52 (bitwise-ior
53 (arithmetic-shift (instr-field instr 25 31) 5)
54 (instr-field instr 7 11))))
55
56(define (instr-b-imm instr)
57 (from-twocomp 12
58 (bitwise-ior
59 (arithmetic-shift (instr-field instr 31 31) 12)
60 (arithmetic-shift (instr-field instr 7 7) 11)
61 (arithmetic-shift (instr-field instr 25 30) 5)
62 (arithmetic-shift (instr-field instr 8 11) 1))))
63
64(define (instr-u-imm instr)
65 (instr-field instr 12 31))
66
67(define (instr-j-imm instr)
68 (from-twocomp 20
69 (bitwise-ior
70 (arithmetic-shift (instr-field instr 31 31) 20)
71 (arithmetic-shift (instr-field instr 19 12) 12)
72 (arithmetic-shift (instr-field instr 20 20) 11)
73 (arithmetic-shift (instr-field instr 21 30) 1))))