riscv-utils

Scheme utility procedures for the RISC-V instruction set architecture

git clone https://git.8pit.net/riscv-utils.git

 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))))