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(define (get-elem unit value nth)
 8  (let ((mask  (- (expt 2 unit) 1))
 9        (shamt (* -1 (* nth unit))))
10    (bitwise-and (arithmetic-shift value shamt) mask)))
11
12(define (get-byte value nth)   (get-elem 8 value nth))
13(define (get-nibble value nth) (get-elem 4 value nth))
14
15(define (byte-swap u32)
16  (bitwise-ior
17    (arithmetic-shift (get-byte u32 0) 24)
18    (arithmetic-shift (get-byte u32 1) 16)
19    (arithmetic-shift (get-byte u32 2) 8)
20    (get-byte u32 3)))
21
22(define (nibble-length number)
23  (let* ((bit-length (integer-length number))
24         (rem (modulo bit-length 4)))
25    (/
26      (if (zero? rem)
27        bit-length
28        (+ (- bit-length rem) 4)) ;; Round to next nibble boundary
29      4)))
30
31(define (nibble-fold proc seed number)
32  (define (recur n)
33    (if (>= n (nibble-length number))
34      seed
35      (proc (get-nibble number n)
36            (recur (+ n 1)))))
37
38  (if (zero? number)
39    (proc 0 seed)
40    (recur 0)))
41
42;;;;
43;; Byte order conversion
44;;;;
45
46(define (le->instr instr)
47  instr)
48
49(define (be->instr instr)
50  (byte-swap instr))
51
52(define (instr->le instr)
53  instr)
54
55(define (instr->be instr)
56  (byte-swap instr))
57
58;;;;
59;; Output format conversion
60;;;;
61
62(define (instr->bin instr)
63  (define (bit->string bit)
64    (if bit "1" "0"))
65
66  (if (negative? instr)
67    (error "not a valid RISC-V instruction")
68    (string-append "#b"
69      (bitwise-fold (lambda (bit output)
70        (string-append (bit->string bit) output)) "" instr))))
71
72(define (instr->hex instr)
73  (define (nibble->string nibble)
74    (vector-ref #(
75      "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "a" "b" "c" "d" "e" "f"
76     ) nibble))
77
78    (if (negative? instr)
79      (error "not a valid RISC-V instruction")
80      (nibble-fold (lambda (nibble str)
81                     (string-append str (nibble->string nibble)))
82                 "#x" instr)))