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