cpu.test: add test cases for add, ebreak, assembling fragments with llvm
This commit is contained in:
parent
9826230bc4
commit
b5871337ab
84
cpu_test.go
84
cpu_test.go
@ -1,17 +1,91 @@
|
|||||||
package riscvemu
|
package riscvemu
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"os/exec"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCPU(t *testing.T) {
|
// assemble_llvm assembles RISC-V source code with the installed system LLVM
|
||||||
|
// compiler and returns the raw bytes from the resulting .text section.
|
||||||
|
func assemble_llvm(source string) ([]byte, error) {
|
||||||
|
// echo 'nop' | clang --target=riscv32 -march=rv32i -x assembler - -c -o - | llvm-objcopy - /dev/null --dump-section .text=/dev/stdout | xxd
|
||||||
|
|
||||||
|
cmd := exec.Command(`/bin/bash`, `-c`, `/usr/bin/clang --target=riscv32 -march=rv32i -x assembler - -c -o - | /usr/bin/llvm-objcopy - /dev/null --dump-section .text=/dev/stdout`)
|
||||||
|
cmd.Stdin = strings.NewReader(source)
|
||||||
|
|
||||||
|
so_buff := bytes.Buffer{}
|
||||||
|
cmd.Stdout = &so_buff
|
||||||
|
|
||||||
|
err := cmd.Wait()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return so_buff.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func runUntilEbreak(c *CPUState, expect_insns int) error {
|
||||||
|
for i := 0; i < expect_insns-1; i++ {
|
||||||
|
err := c.Step()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err := c.Step()
|
||||||
|
if err != nil {
|
||||||
|
if eb := (ErrBreak{}); errors.As(err, &eb) {
|
||||||
|
return nil // Successfully got EBREAK precisely when wanted
|
||||||
|
}
|
||||||
|
return err // Some other real error
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("Expected EBREAK at instruction count %d, but got %v", expect_insns, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBreak(t *testing.T) {
|
||||||
env := NewVirtualEEI()
|
env := NewVirtualEEI()
|
||||||
_ = env.Write32(0, 0b00000000000100000000000001110011) // EBREAK
|
|
||||||
|
// ebreak
|
||||||
|
_, err := env.WriteAt([]byte{0x73, 0x00, 0x10, 0x00}, 0)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
c := NewCPU(&env)
|
c := NewCPU(&env)
|
||||||
|
|
||||||
err := c.Step()
|
err = c.Step()
|
||||||
panic(err)
|
if err == nil {
|
||||||
|
t.Fatal("expected ErrBreak, got <nil>")
|
||||||
|
}
|
||||||
|
if eb := (ErrBreak{}); !errors.As(err, &eb) {
|
||||||
|
t.Fatalf("expected ErrBreak, got %#v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAdd(t *testing.T) {
|
||||||
|
env := NewVirtualEEI()
|
||||||
|
|
||||||
|
// li a0, 0xffff
|
||||||
|
// ebreak
|
||||||
|
_, err := env.WriteAt([]byte{0x37, 0xc5, 0xad, 0xde, 0x13, 0x05, 0xf5, 0xee, 0x73, 0x00, 0x10, 0x00}, 0)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
c := NewCPU(&env)
|
||||||
|
|
||||||
|
err = runUntilEbreak(&c, 3)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that we managed to load into the register
|
||||||
|
if c.Registers[10] != 0xdeadbeef {
|
||||||
|
t.Errorf("expected register a0 (x10) to contain 0xdeadbeef, got %#v", c.Registers[10])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user