Implementing jal instruction.

This commit is contained in:
Lucas Clemente Vella
2024-01-31 18:34:34 +00:00
parent 66a4da83aa
commit ff1374f0c0
4 changed files with 202 additions and 15 deletions

View File

@@ -1264,8 +1264,20 @@ fn process_instruction(instr: &str, args: &[Argument], coprocessors: &CoProcesso
vec![format!("tmp1 <== jump_dyn({rs});")]
}
"jal" => {
let (_rd, _label) = rl(args);
todo!();
if let [label] = args {
vec![format!(
"x1 <== jump({});",
argument_to_escaped_symbol(label)
)]
} else {
let (rd, label) = rl(args);
let statement = if rd.is_zero() {
format!("tmp1 <== jump({label})")
} else {
format!("{rd} <== jump({label})")
};
vec![statement]
}
}
"jalr" => {
// TODO there is also a form that takes more arguments

View File

@@ -1,10 +1,13 @@
Tests from https://github.com/riscv/riscv-tests/tree/master/isa/
Powdr partially implements riscv32imac userspace ISA. One major difference is
that our zkVM "text" section doesn't have a 1-to-1 correspondence to the RISC-V
instructions section, so we don't support any kind of arithmetic over `.text`
label and addresses, nor alignment or spacing directives in `.text` sections.
Most unsupported instructions are related to this limitation.
that the code in our zkVM is interpreted at a higher abstraction level than the
binary representation of a RISC-V "text" section, and we use code labels as
absolute references, not relative to the PC like in binary format RISC-V. Thus
labels in code sections are treated as opaque values, and we don't support any
kind of arithmetic over `.text` label and addresses, nor alignment or spacing
directives in `.text` sections. Most unsupported instructions are related to
this limitation.
Following there is a list of tests from the test suite that we do not support:
@@ -13,18 +16,13 @@ Following there is a list of tests from the test suite that we do not support:
- auipc
This test is not supported because we don't support any kind of arithmetic over
`.text` label and addresses.
Also, `lla` and `jal` (pseudo-)instructions are not yet implemented.
`.text` label and addresses, nor the `lla` pseudoinstruction.
- fence_i
Our zkVM "text" is static. We don't support dynamic binary code, so it makes no
sense to implement `fence_i` instruction.
- jal
Not yet implemented.
This test is not supported because our zkVM "text" is static: we don't support
dynamic binary code or self modifying programs. Thus, our `fence.i` instruction
is just a nop.
- jalr

View File

@@ -0,0 +1,118 @@
# 0 "sources/jal.S"
# 0 "<built-in>"
# 0 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 0 "<command-line>" 2
# 1 "sources/jal.S"
# See LICENSE for license details.
#*****************************************************************************
# jal.S
#-----------------------------------------------------------------------------
# Test jal instruction.
# 1 "sources/riscv_test.h" 1
# 11 "sources/jal.S" 2
# 1 "sources/test_macros.h" 1
#-----------------------------------------------------------------------
# Helper macros
#-----------------------------------------------------------------------
# 20 "sources/test_macros.h"
# We use a macro hack to simpify code generation for various numbers
# of bubble cycles.
# 36 "sources/test_macros.h"
#-----------------------------------------------------------------------
# RV64UI MACROS
#-----------------------------------------------------------------------
#-----------------------------------------------------------------------
# Tests for instructions with immediate operand
#-----------------------------------------------------------------------
# 92 "sources/test_macros.h"
#-----------------------------------------------------------------------
# Tests for vector config instructions
#-----------------------------------------------------------------------
# 120 "sources/test_macros.h"
#-----------------------------------------------------------------------
# Tests for an instruction with register operands
#-----------------------------------------------------------------------
# 148 "sources/test_macros.h"
#-----------------------------------------------------------------------
# Tests for an instruction with register-register operands
#-----------------------------------------------------------------------
# 242 "sources/test_macros.h"
#-----------------------------------------------------------------------
# Test memory instructions
#-----------------------------------------------------------------------
# 319 "sources/test_macros.h"
#-----------------------------------------------------------------------
# Test branch instructions
#-----------------------------------------------------------------------
# 404 "sources/test_macros.h"
#-----------------------------------------------------------------------
# Test jump instructions
#-----------------------------------------------------------------------
# 433 "sources/test_macros.h"
#-----------------------------------------------------------------------
# RV64UF MACROS
#-----------------------------------------------------------------------
#-----------------------------------------------------------------------
# Tests floating-point instructions
#-----------------------------------------------------------------------
# 569 "sources/test_macros.h"
#-----------------------------------------------------------------------
# Pass and fail code (assumes test num is in x28)
#-----------------------------------------------------------------------
# 581 "sources/test_macros.h"
#-----------------------------------------------------------------------
# Test data section
#-----------------------------------------------------------------------
# 12 "sources/jal.S" 2
.globl __runtime_start; __runtime_start: la x10,__return_pointer; sw x1,0(x10); li x10,0
#-------------------------------------------------------------
# Test 2: Basic test
#-------------------------------------------------------------
test_2:
li x28, 2
li ra, 0
jal x4, target_2
linkaddr_2:
nop
nop
j fail
target_2:
la x2, linkaddr_2
bne x2, x4, fail
#-------------------------------------------------------------
# Test delay slot instructions not executed nor bypassed
#-------------------------------------------------------------
test_3: li x10, 3; ebreak; li ra, 1; jal x0, test_jal_1; addi ra, ra, 1; addi ra, ra, 1; addi ra, ra, 1; addi ra, ra, 1; test_jal_1: addi ra, ra, 1; addi ra, ra, 1;; li x29, 3; li x28, 3; bne ra, x29, fail;
# 50 "sources/jal.S"
bne x0, x28, pass; fail: unimp;; pass: la x10,__return_pointer; lw x1,0(x10); ret;
.data
.balign 4; __return_pointer: .word 0;

View File

@@ -0,0 +1,59 @@
# See LICENSE for license details.
#*****************************************************************************
# jal.S
#-----------------------------------------------------------------------------
#
# Test jal instruction.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV32U
RVTEST_CODE_BEGIN
#-------------------------------------------------------------
# Test 2: Basic test
#-------------------------------------------------------------
test_2:
li TESTNUM, 2
li ra, 0
jal x4, target_2
linkaddr_2:
nop
nop
j fail
target_2:
la x2, linkaddr_2
bne x2, x4, fail
#-------------------------------------------------------------
# Test delay slot instructions not executed nor bypassed
#-------------------------------------------------------------
TEST_CASE( 3, ra, 3, \
li ra, 1; \
jal x0, test_jal_1; \
addi ra, ra, 1; \
addi ra, ra, 1; \
addi ra, ra, 1; \
addi ra, ra, 1; \
test_jal_1: addi ra, ra, 1; \
addi ra, ra, 1; \
)
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END