Skip to content

Commit 6f6b247

Browse files
committed
Support Zbs.
1 parent 0cef58f commit 6f6b247

File tree

4 files changed

+104
-2
lines changed

4 files changed

+104
-2
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ The assembler only supports what the emulator implements. Per the [unprivileged
2626

2727
- Zba 1.0.0 (address generation instructions)
2828

29+
- Zbs 1.0.0 (single-bit instructions)
30+
2931
Further extensions are not supported, notably instructions for hardware multiplication and division (M) and hardware floats (F, D).
3032

3133
Compressed instructions are supported in the sense that the assembler will encode regular instructions like `add` and `lbu` into the compressed form when compression is enabled. The mnemonics for the compressed instructions like `c.add` and `c.lbu` are not supported. Instructions that only exist in compressed instruction extensions like `c.lwsp` can be written as `lwsp` or `c.lwsp`.
@@ -54,7 +56,7 @@ The assembler does not consider whether the target architecture is 32-bit or 64-
5456

5557
Therefore the assembler also has a `--64` flag to explicitly set the target architecture to RV64I. When combined with the `--compress` flag it will instruct the assembler to not compress `jal`.
5658

57-
The `*.c` files contain equivalent C solutions that can be put in [Compiler Explorer](https://gcc.godbolt.org/) with compiler set to `RISC-V (32-bits) gcc` or `RISC-V rv32gc clang` or corresponding 64-bit version, and flags set to `--std=c23 -Os -march=rv32id_zba_zicond` or `--std=c23 -Os -march=rv64id_zba_zicond`. Note that the assembler programs are hand-written and will not exactly match the compiler's output.
59+
The `*.c` files contain equivalent C solutions that can be put in [Compiler Explorer](https://gcc.godbolt.org/) with compiler set to `RISC-V (32-bits) gcc` or `RISC-V rv32gc clang` or corresponding 64-bit version, and flags set to `--std=c23 -Os -march=rv32id_zba_zbs_zicond` or `--std=c23 -Os -march=rv64id_zba_zbs_zicond`. Note that the assembler programs are hand-written and will not exactly match the compiler's output.
5860

5961
The emulator has the Level Input and Level Output wired up to memory address `2^32 - 1`, which is why the assembler programs refer to `-1(zero)` and the C programs refer to `IO = (volatile uint8_t*)(intptr_t)-1;`.
6062

freestanding/riscv64-arnavion-none-elf.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"data-layout": "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128",
88
"eh-frame-header": false,
99
"emit-debug-gdb-scripts": false,
10-
"features": "+forced-atomics,+zba,+zca,+zcb,+zicond,+zicsr,+zicntr",
10+
"features": "+forced-atomics,+zba,+zbs,+zca,+zcb,+zicond,+zicsr,+zicntr",
1111
"linker": "rust-lld",
1212
"linker-flavor": "gnu-lld",
1313
"llvm-target": "riscv64",

src/instruction.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -853,15 +853,33 @@ instructions! {
853853
#[u("auipc", Auipc)]
854854
Auipc { dest: Register, imm: i32 },
855855

856+
#[r("bclr", Op)]
857+
BClr { dest: Register, src1: Register, src2: Register },
858+
859+
#[i("bclri", OpImm)]
860+
BClri { dest: Register, src: Register, shamt: i32 },
861+
856862
#[b("beq", Branch)]
857863
Beq { src1: Register, src2: Register, offset: i32 },
858864

865+
#[r("bext", Op)]
866+
BExt { dest: Register, src1: Register, src2: Register },
867+
868+
#[i("bexti", OpImm)]
869+
BExti { dest: Register, src: Register, shamt: i32 },
870+
859871
#[b("bge", Branch)]
860872
Bge { src1: Register, src2: Register, offset: i32 },
861873

862874
#[b("bgeu", Branch)]
863875
Bgeu { src1: Register, src2: Register, offset: i32 },
864876

877+
#[r("binv", Op)]
878+
BInv { dest: Register, src1: Register, src2: Register },
879+
880+
#[i("binvi", OpImm)]
881+
BInvi { dest: Register, src: Register, shamt: i32 },
882+
865883
#[b("blt", Branch)]
866884
Blt { src1: Register, src2: Register, offset: i32 },
867885

@@ -871,6 +889,12 @@ instructions! {
871889
#[b("bne", Branch)]
872890
Bne { src1: Register, src2: Register, offset: i32 },
873891

892+
#[r("bset", Op)]
893+
BSet { dest: Register, src1: Register, src2: Register },
894+
895+
#[i("bseti", OpImm)]
896+
BSeti { dest: Register, src: Register, shamt: i32 },
897+
874898
#[r("czero.eqz", Op)]
875899
CZeroEqz { dest: Register, src1: Register, src2: Register },
876900

@@ -2237,12 +2261,20 @@ funct! {
22372261
Addw = 0b000,
22382262
And = 0b111,
22392263
Andi = 0b111,
2264+
BClr = 0b001,
2265+
BClri = 0b001,
2266+
BExt = 0b101,
2267+
BExti = 0b101,
22402268
Beq = 0b000,
22412269
Bge = 0b101,
22422270
Bgeu = 0b111,
2271+
BInv = 0b001,
2272+
BInvi = 0b001,
22432273
Blt = 0b100,
22442274
Bltu = 0b110,
22452275
Bne = 0b001,
2276+
BSet = 0b001,
2277+
BSeti = 0b001,
22462278
Csrrc = 0b011,
22472279
Csrrci = 0b111,
22482280
Csrrs = 0b010,
@@ -2303,6 +2335,14 @@ funct! {
23032335
Adduw = 0b000_0100,
23042336
Addw = 0b000_0000,
23052337
And = 0b000_0000,
2338+
BClr = 0b010_0100,
2339+
BClri = 0b010_0100,
2340+
BExt = 0b010_0100,
2341+
BExti = 0b010_0100,
2342+
BInv = 0b011_0100,
2343+
BInvi = 0b011_0100,
2344+
BSet = 0b001_0100,
2345+
BSeti = 0b001_0100,
23062346
CZeroEqz = 0b000_0111,
23072347
CZeroNez = 0b000_0111,
23082348
Or = 0b000_0000,

src/lib.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,12 +156,22 @@ mod tests {
156156
("auipc a0, -11", &[(0x5517, Some(0xffff))]),
157157
("auipc a0, 11", &[(0xb517, Some(0x0000))]),
158158

159+
("bclr a0, a1, a2", &[(0x9533, Some(0x48c5))]),
160+
161+
("bclri a0, a1, 11", &[(0x9513, Some(0x48b5))]),
162+
("bclri a0, a1, 31", &[(0x9513, Some(0x49f5))]),
163+
159164
("beq a0, a1, -4", &[(0x0ee3, Some(0xfeb5))]),
160165
("beq a0, a1, 44", &[(0x0663, Some(0x02b5))]),
161166

162167
("beqz a0, -4", &[(0x0ee3, Some(0xfe05))]),
163168
("beqz a0, 28", &[(0x0e63, Some(0x0005))]),
164169

170+
("bext a0, a1, a2", &[(0xd533, Some(0x48c5))]),
171+
172+
("bexti a0, a1, 11", &[(0xd513, Some(0x48b5))]),
173+
("bexti a0, a1, 31", &[(0xd513, Some(0x49f5))]),
174+
165175
("bge a0, a1, -12", &[(0x5ae3, Some(0xfeb5))]),
166176
("bge a0, a1, 36", &[(0x5263, Some(0x02b5))]),
167177

@@ -180,6 +190,11 @@ mod tests {
180190
("bgtz a0, -4", &[(0x4ee3, Some(0xfea0))]),
181191
("bgtz a0, 12", &[(0x4663, Some(0x00a0))]),
182192

193+
("binv a0, a1, a2", &[(0x9533, Some(0x68c5))]),
194+
195+
("binvi a0, a1, 11", &[(0x9513, Some(0x68b5))]),
196+
("binvi a0, a1, 31", &[(0x9513, Some(0x69f5))]),
197+
183198
("ble a0, a1, -20", &[(0xd6e3, Some(0xfea5))]),
184199
("ble a0, a1, 12", &[(0xd663, Some(0x00a5))]),
185200

@@ -204,6 +219,11 @@ mod tests {
204219
("bnez a0, -28", &[(0x12e3, Some(0xfe05))]),
205220
("bnez a0, 4", &[(0x1263, Some(0x0005))]),
206221

222+
("bset a0, a1, a2", &[(0x9533, Some(0x28c5))]),
223+
224+
("bseti a0, a1, 11", &[(0x9513, Some(0x28b5))]),
225+
("bseti a0, a1, 31", &[(0x9513, Some(0x29f5))]),
226+
207227
("call -4", &[(0x0097, Some(0x0000)), (0x80e7, Some(0xffc0))]),
208228
("call 24", &[(0x0097, Some(0x0000)), (0x80e7, Some(0x0180))]),
209229
("call a0, -20", &[(0x0517, Some(0x0000)), (0x0567, Some(0xfec5))]),
@@ -605,6 +625,14 @@ mod tests {
605625

606626
("addw a0, a1, a2", &[(0x853b, Some(0x00c5))]),
607627

628+
("bclri a0, a1, 63", &[(0x9513, Some(0x4bf5))]),
629+
630+
("bexti a0, a1, 63", &[(0xd513, Some(0x4bf5))]),
631+
632+
("binvi a0, a1, 63", &[(0x9513, Some(0x6bf5))]),
633+
634+
("bseti a0, a1, 63", &[(0x9513, Some(0x2bf5))]),
635+
608636
("ld a0, -36", &[(0x0517, Some(0x0000)), (0x3503, Some(0xfdc5))]),
609637
("ld a0, 72", &[(0x0517, Some(0x0000)), (0x3503, Some(0x0485))]),
610638
("ld a0, -11(a1)", &[(0xb503, Some(0xff55))]),
@@ -766,10 +794,34 @@ mod tests {
766794
sh1add a0, a1, a2
767795
sh2add a0, a1, a2
768796
sh3add a0, a1, a2
797+
bclri a0, a1, 0
798+
bclri a0, a1, 31
799+
bseti a0, a1, 0
800+
bseti a0, a1, 31
801+
binvi a0, a1, 0
802+
binvi a0, a1, 31
803+
bexti a0, a1, 0
804+
bexti a0, a1, 31
805+
bclr a0, a1, a2
806+
bset a0, a1, a2
807+
binv a0, a1, a2
808+
bext a0, a1, a2
769809
", &[
770810
(0xa533, 0x20c5),
771811
(0xc533, 0x20c5),
772812
(0xe533, 0x20c5),
813+
(0x9513, 0x4805),
814+
(0x9513, 0x49f5),
815+
(0x9513, 0x2805),
816+
(0x9513, 0x29f5),
817+
(0x9513, 0x6805),
818+
(0x9513, 0x69f5),
819+
(0xd513, 0x4805),
820+
(0xd513, 0x49f5),
821+
(0x9533, 0x48c5),
822+
(0x9533, 0x28c5),
823+
(0x9533, 0x68c5),
824+
(0xd533, 0x48c5),
773825
]),
774826

775827
// bge.s
@@ -1405,13 +1457,21 @@ mod tests {
14051457
add.uw a0, a1, a2
14061458
zext.w a0, a1
14071459
slli.uw a0, a1, 2
1460+
bclri a0, a1, 63
1461+
bseti a0, a1, 63
1462+
binvi a0, a1, 63
1463+
bexti a0, a1, 63
14081464
", &[
14091465
(0xa53b, 0x20c5),
14101466
(0xc53b, 0x20c5),
14111467
(0xe53b, 0x20c5),
14121468
(0x853b, 0x08c5),
14131469
(0x853b, 0x0805),
14141470
(0x951b, 0x0825),
1471+
(0x9513, 0x4bf5),
1472+
(0x9513, 0x2bf5),
1473+
(0x9513, 0x6bf5),
1474+
(0xd513, 0x4bf5),
14151475
]),
14161476

14171477
// csr.s

0 commit comments

Comments
 (0)