From 5cd8bea55aac47294eb6ae5f905ccd3d87514b11 Mon Sep 17 00:00:00 2001 From: Lucas Clemente Vella Date: Tue, 19 Sep 2023 21:52:22 +0100 Subject: [PATCH] Implemented amoadd.w instruction. --- riscv/src/compiler.rs | 32 ++++- .../instruction_tests/generated/amoadd_w.S | 117 ++++++++++++++++++ .../instruction_tests/sources/amoadd_w.S | 49 ++++++++ 3 files changed, 197 insertions(+), 1 deletion(-) create mode 100644 riscv/tests/instruction_tests/generated/amoadd_w.S create mode 100644 riscv/tests/instruction_tests/sources/amoadd_w.S diff --git a/riscv/src/compiler.rs b/riscv/src/compiler.rs index a7a690acf6..0c6c074918 100644 --- a/riscv/src/compiler.rs +++ b/riscv/src/compiler.rs @@ -71,7 +71,7 @@ impl Architecture for RiscvArchitecture { | "sgtz" | "beq" | "beqz" | "bgeu" | "bltu" | "blt" | "bge" | "bltz" | "blez" | "bgtz" | "bgez" | "bne" | "bnez" | "jal" | "jalr" | "call" | "ecall" | "ebreak" | "lw" | "lb" | "lbu" | "lh" | "lhu" | "sw" | "sh" | "sb" | "nop" | "fence" - | "fence.i" => false, + | "fence.i" | "amoadd.w.rl" | "amoadd.w" => false, "j" | "jr" | "tail" | "ret" | "unimp" => true, _ => { panic!("Unknown instruction: {instr}"); @@ -921,6 +921,18 @@ fn rro(args: &[Argument]) -> (Register, Register, u32) { } } +fn rrro(args: &[Argument]) -> (Register, Register, Register, u32) { + match args { + [Argument::Register(r1), Argument::Register(r2), Argument::RegOffset(off, r3)] => ( + *r1, + *r2, + *r3, + expression_to_number(off.as_ref().unwrap_or(&Expression::Number(0))), + ), + _ => panic!(), + } +} + fn only_if_no_write_to_zero(statement: String, reg: Register) -> Vec { only_if_no_write_to_zero_vec(vec![statement], reg) } @@ -1391,6 +1403,24 @@ fn process_instruction(instr: &str, args: &[Argument]) -> Vec { // atomic and synchronization "fence" | "fence.i" => vec![], + insn if insn.starts_with("amoadd.w") => { + let (rd, rs2, rs1, off) = rrro(args); + assert_eq!(off, 0); + + let rd = if rd.is_zero() { + "tmp2".to_string() + } else { + rd.to_string() + }; + + vec![ + format!("addr <=X= {rs1};"), + format!("{rd} <== mload();"), + format!("tmp1 <== wrap({rd} + {rs2});"), + format!("mstore tmp1;"), + ] + } + _ => { panic!("Unknown instruction: {instr}"); } diff --git a/riscv/tests/instruction_tests/generated/amoadd_w.S b/riscv/tests/instruction_tests/generated/amoadd_w.S new file mode 100644 index 0000000000..be26da30cd --- /dev/null +++ b/riscv/tests/instruction_tests/generated/amoadd_w.S @@ -0,0 +1,117 @@ +# 0 "sources/amoadd_w.S" +# 0 "" +# 0 "" +# 1 "/usr/include/stdc-predef.h" 1 3 4 +# 0 "" 2 +# 1 "sources/amoadd_w.S" +# See LICENSE for license details. + +#***************************************************************************** +# amoadd_w.S +#----------------------------------------------------------------------------- + +# Test amoadd.w instruction. + + +# 1 "sources/riscv_test.h" 1 +# 11 "sources/amoadd_w.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/amoadd_w.S" 2 + + +.globl __runtime_start; __runtime_start: + + test_2: li x10, 2; ebreak; li a0, 0xffffffff80000000; li a1, 0xfffffffffffff800; la a3, amo_operand; sw a0, 0(a3); amoadd.w a4, a1, 0(a3);; li x29, 0xffffffff80000000; li x28, 2; bne a4, x29, fail; + + + + + + + + test_3: li x10, 3; ebreak; lw a5, 0(a3); li x29, 0x000000007ffff800; li x28, 3; bne a5, x29, fail; + + # try again after a cache miss + test_4: li x10, 4; ebreak; li a1, 0xffffffff80000000; amoadd.w a4, a1, 0(a3);; li x29, 0x000000007ffff800; li x28, 4; bne a4, x29, fail; + + + + + test_5: li x10, 5; ebreak; lw a5, 0(a3); li x29, 0xfffffffffffff800; li x28, 5; bne a5, x29, fail; + + bne x0, x28, pass; fail: unimp;; pass: ___pass: j ___pass; + + + + .data +.balign 4; + + + + + + .bss + .align 3 +amo_operand: + .word 0 + .word 0 diff --git a/riscv/tests/instruction_tests/sources/amoadd_w.S b/riscv/tests/instruction_tests/sources/amoadd_w.S new file mode 100644 index 0000000000..4d324710e4 --- /dev/null +++ b/riscv/tests/instruction_tests/sources/amoadd_w.S @@ -0,0 +1,49 @@ +# See LICENSE for license details. + +#***************************************************************************** +# amoadd_w.S +#----------------------------------------------------------------------------- +# +# Test amoadd.w instruction. +# + +#include "riscv_test.h" +#include "test_macros.h" + +RVTEST_RV32U +RVTEST_CODE_BEGIN + + TEST_CASE(2, a4, 0xffffffff80000000, \ + li a0, 0xffffffff80000000; \ + li a1, 0xfffffffffffff800; \ + la a3, amo_operand; \ + sw a0, 0(a3); \ + amoadd.w a4, a1, 0(a3); \ + ) + + TEST_CASE(3, a5, 0x000000007ffff800, lw a5, 0(a3)) + + # try again after a cache miss + TEST_CASE(4, a4, 0x000000007ffff800, \ + li a1, 0xffffffff80000000; \ + amoadd.w a4, a1, 0(a3); \ + ) + + TEST_CASE(5, a5, 0xfffffffffffff800, lw a5, 0(a3)) + + TEST_PASSFAIL + +RVTEST_CODE_END + + .data +RVTEST_DATA_BEGIN + + TEST_DATA + +RVTEST_DATA_END + + .bss + .align 3 +amo_operand: + .word 0 + .word 0