aboutsummaryrefslogtreecommitdiffstats
path: root/README.md
blob: 55e53754c7fb323b9c1a0665dfc09c06440b9658 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# SubV

This is a wip clone of [SubX][mu] for the RISC-V RV31I base ISA.

    $ <label_test.subv ./format.py | ./survey.py | ./pack.py | ./elf.py >out.elf
    $ ./qemu.sh out.elf

## Status

Features:

- ELF output: ✔️
- Free arg order: ❌
- SubX cross-asm: ❌

Instruction Groups:

- OP-IMM: ✔️✔️
- OP: ✔️❌
- LUI: ✔️✔️
- AIUPC: ✔️❌
- JAL: ✔️✔️
- JALR: ✔️❌
- BRANCH: ❌❌
- LOAD: ✔️❌
- STORE: ✔️✔️

(✔️❌: implemented but untested)

## Pipeline

back to front:

- `elf.py`: takes hex bytes and segment headers, outputs an ELF file
- `pack.py`: packs bitfields (`3/3 1/1 f/4`) into hex bytes (`fb`)
- `survey.py`: replaces label references by their addresses
- `format.py`: checks op-arguments and chops and orders arguments into ISA formats

and now front to back with a little example:

    $ ./format.py <ex.subv   >ex.format
    $ ./survey.py <ex.format >ex.survey
    $ ./pack.py   <ex.survey >ex.pack
    $ ./elf.py    <ex.pack   >ex.elf
    $ ./qemu.sh ex.elf

`ex.subv`: hand-writable.

    == code 0x80000000
    # repeatedly print "Hi\\n"
    main:
      # load 0x10010000 (UART0) into t0
      37/lui 5/rd/t0 0x10010/imm20
      # store 0x48 (H) in UART0+0
      13/opi 0/subop/add 6/rd/t1 0/rs/x0 48/imm12
      23/store 2/subop/word 5/rs/t0 6/rs/t1 0/off12
      # store 0x69 (i) in UART0+0
      13/opi 0/subop/add 6/rd/t1 0/rs/x0 69/imm12
      23/store 2/subop/word 5/rs/t0 6/rs/t1 0/off12
      # store 0x0a (\n) in UART0+0
      13/opi 0/subop/add 6/rd/t1 0/rs/x0 0a/imm12
      23/store 2/subop/word 5/rs/t0 6/rs/t1 0/off12
      # jump back up to the top
      6f/jal 0/rd/x0 main/off21

`ex.format`: arguments sliced and diced and put into the ISA order.

    == code 0x80000000
    # repeatedly print "Hi\n"
    main:
    # load 0x10010000 (UART0) into t0
    37/7 05/5 10010/20
    # store 0x48 (H) in UART0+0
    13/7 06/5 00/3 00/5 48/12
    23/7 00/5 02/3 05/5 06/5 00/7
    # store 0x69 (i) in UART0+0
    13/7 06/5 00/3 00/5 69/12
    23/7 00/5 02/3 05/5 06/5 00/7
    # store 0x0a (\n) in UART0+0
    13/7 06/5 00/3 00/5 0a/12
    23/7 00/5 02/3 05/5 06/5 00/7
    # jump back up to the top
    6f/7 00/5 main/8/off21>>12 main/1/off21>>11 main/10/off21>>1 main/1/off21>>20

`ex.survey`: labels resolved, ready to be packed into hex format

    == code 0x80000000
    37/7 05/5 10010/20
    13/7 06/5 00/3 00/5 48/12
    23/7 00/5 02/3 05/5 06/5 00/7
    13/7 06/5 00/3 00/5 69/12
    23/7 00/5 02/3 05/5 06/5 00/7
    13/7 06/5 00/3 00/5 0a/12
    23/7 00/5 02/3 05/5 06/5 00/7
    6f/7 00/5 ff/8 01/1 3f2/10 01/1

`ex.pack`: fully packed, ready to run bare-metal

    == code 0x80000000
    b7 02 01 10
    13 03 80 04
    23 a0 62 00
    13 03 90 06
    23 a0 62 00
    13 03 a0 00
    23 a0 62 00
    6f f0 5f fe

`ex.elf`: binary file for use with `qemu` (see next section).

## Debugging

You can hook gdb into `qemu` using the `-s` flag, and make it halt on start
using the `-S` flag. `gdb` can be attached using `target remote localhost:1234`:

    $ ./qemu.sh out.elf -S -s
    # in another terminal
    $ riscv32-elf-gdb -iex "target remote localhost:1234"
    layout asm # show assembly trace
    nexti      # step forward one instruction
    c          # free-run forward

[mu]: https://github.com/akkartik/mu