diff --git a/Makefile b/Makefile index c5746db..a50667d 100644 --- a/Makefile +++ b/Makefile @@ -15,6 +15,11 @@ rv32imac_tests.bin: rv32imac_tests.elf run: rv32imac_tests.bin $(EMULATOR) rv32imac_tests.bin + @echo "Testing standard ebreak..." + @echo "115 0 16 0" | awk -f amach.awk 2>&1 | grep -q "Fatal: EBREAK" + @echo "Testing compressed c.ebreak..." + @echo "2 144" | awk -f amach.awk 2>&1 | grep -q "Fatal: EBREAK" + @echo "All EBREAK tests PASSED!" clean: rm -f rv32imac_tests.elf rv32imac_tests.bin diff --git a/README.md b/README.md index 359c27b..172a61b 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ POSIXLY_CORRECT=1 awk -f amach.awk [-v LVA=...] -- path/to/program.dec ## Support -Currently, A-machine only supports the **unprivileged** RV32IMAC instruction set with a few additional `ecall` syscalls: 63 (sys_read, for fd 0 only), 64 (sys_write, for fd 1 and 2 only) and 93 (sys_exit). For completeness, `fence` instruction is also supported but yields a no-op. +Currently, A-machine only supports the **unprivileged** RV32IMAC instruction set with a few additional `ecall` syscalls: 63 (sys_read, for fd 0 only), 64 (sys_write, for fd 1 and 2 only) and 93 (sys_exit). For completeness, `fence` instruction is also supported but yields a no-op, and both `ebreak` and `c.ebreak` are supported to halt execution with a debug message. ## Plans (from higher to lower priority) diff --git a/amach.awk b/amach.awk index ca39d04..fa3a712 100644 --- a/amach.awk +++ b/amach.awk @@ -170,6 +170,7 @@ function amach_imm(opcode, f3, rd, rs1, immval, r1, ur1, shamt) { pc = r1 + immval } else if(opcode == 115) { # 0x73, system call / csr if(immval == 0) handle_ecall(getreg(17), getreg(10), getreg(11), getreg(12), getreg(13), getreg(14), getreg(15)) + else if(immval == 1) trapout(sprintf("EBREAK at 0x%X", pc-4)) else trapout(sprintf("Unimplemented external system call at 0x%X", pc-4)) } else trapout(sprintf("Illegal instruction at 0x%X", pc-4)) } @@ -317,9 +318,8 @@ function amach_comp(instr, op, f3, b12, r11_7, r9_7, r6_2, r4_2, shamt, imm, ba } else setreg(r11_7, getreg(r6_2)) # C.MV } else { if(r6_2 == 0) { - if(r11_7 == 0) { # C.EBREAK - trapout(sprintf("EBREAK at 0x%X", pc-2)) - } else { # C.JALR + if(r11_7 == 0) trapout(sprintf("EBREAK at 0x%X", pc-2)) # C.EBREAK + else { # C.JALR imm = getreg(r11_7) setreg(1, pc) pc = imm diff --git a/rv32imac_tests.bin b/rv32imac_tests.bin index 1b576fa..0ce71c1 100755 Binary files a/rv32imac_tests.bin and b/rv32imac_tests.bin differ diff --git a/rv32imac_tests.s b/rv32imac_tests.s index ecd3059..a8b8393 100644 --- a/rv32imac_tests.s +++ b/rv32imac_tests.s @@ -795,6 +795,12 @@ _start: li a7, 93 ecall + # Unreachable: placed to verify standard/compressed ebreak compilation + ebreak + .option rvc + c.ebreak + .option norvc + report_error: la a0, str_some_failed jal print_string