mirror of
https://github.com/powdr-labs/powdr.git
synced 2026-04-20 03:03:25 -04:00
Implementing mulhsu.
Not the most pretty solution, but works.
This commit is contained in:
@@ -67,12 +67,12 @@ impl Architecture for RiscvArchitecture {
|
||||
fn instruction_ends_control_flow(instr: &str) -> bool {
|
||||
match instr {
|
||||
"li" | "lui" | "la" | "mv" | "add" | "addi" | "sub" | "neg" | "mul" | "mulhu"
|
||||
| "divu" | "remu" | "xor" | "xori" | "and" | "andi" | "or" | "ori" | "not" | "slli"
|
||||
| "sll" | "srli" | "srl" | "srai" | "seqz" | "snez" | "slt" | "slti" | "sltu"
|
||||
| "sltiu" | "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" | "amoadd.w" | "amoadd.w.aq" | "amoadd.w.rl"
|
||||
| "mulhsu" | "divu" | "remu" | "xor" | "xori" | "and" | "andi" | "or" | "ori"
|
||||
| "not" | "slli" | "sll" | "srli" | "srl" | "srai" | "seqz" | "snez" | "slt"
|
||||
| "slti" | "sltu" | "sltiu" | "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" | "amoadd.w" | "amoadd.w.aq" | "amoadd.w.rl"
|
||||
| "amoadd.w.aqrl" | "lr.w" | "lr.w.aq" | "lr.w.rl" | "lr.w.aqrl" | "sc.w"
|
||||
| "sc.w.aq" | "sc.w.rl" | "sc.w.aqrl" => false,
|
||||
"j" | "jr" | "tail" | "ret" | "unimp" => true,
|
||||
@@ -904,6 +904,27 @@ fn process_instruction(instr: &str, args: &[Argument]) -> Vec<String> {
|
||||
let (rd, r1, r2) = rrr(args);
|
||||
only_if_no_write_to_zero(format!("tmp1, {rd} <== mul({r1}, {r2});"), rd)
|
||||
}
|
||||
"mulhsu" => {
|
||||
let (rd, r1, r2) = rrr(args);
|
||||
only_if_no_write_to_zero_vec(
|
||||
vec![
|
||||
format!("tmp1 <== to_signed({r1});"),
|
||||
// tmp2 is 1 if tmp1 is non-negative
|
||||
"tmp2 <== is_positive(tmp1 + 1);".into(),
|
||||
// If negative, convert to positive
|
||||
"skip_if_zero 0, tmp2;".into(),
|
||||
"tmp1 <=X= 0 - tmp1;".into(),
|
||||
format!("tmp1, {rd} <== mul(tmp1, {r2});"),
|
||||
// If was negative before, convert back to negative
|
||||
"skip_if_zero (1-tmp2), 2;".into(),
|
||||
"tmp1 <== is_equal_zero(tmp1);".into(),
|
||||
// If the lower bits are zero, return the two's complement,
|
||||
// otherwise return one's complement.
|
||||
format!("{rd} <== wrap_signed(-{rd} - 1 + tmp1);"),
|
||||
],
|
||||
rd,
|
||||
)
|
||||
}
|
||||
"divu" => {
|
||||
let (rd, r1, r2) = rrr(args);
|
||||
only_if_no_write_to_zero(format!("{rd}, tmp1 <== divremu({r1}, {r2});"), rd)
|
||||
|
||||
151
riscv/tests/instruction_tests/generated/mulhsu.S
Normal file
151
riscv/tests/instruction_tests/generated/mulhsu.S
Normal file
@@ -0,0 +1,151 @@
|
||||
# 0 "sources/mulhsu.S"
|
||||
# 0 "<built-in>"
|
||||
# 0 "<command-line>"
|
||||
# 1 "/usr/include/stdc-predef.h" 1 3 4
|
||||
# 0 "<command-line>" 2
|
||||
# 1 "sources/mulhsu.S"
|
||||
# See LICENSE for license details.
|
||||
|
||||
#*****************************************************************************
|
||||
# mulhsu.S
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
# Test mulhsu instruction.
|
||||
|
||||
|
||||
# 1 "sources/riscv_test.h" 1
|
||||
# 11 "sources/mulhsu.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/mulhsu.S" 2
|
||||
|
||||
|
||||
.globl __runtime_start; __runtime_start:
|
||||
|
||||
#-------------------------------------------------------------
|
||||
# Arithmetic tests
|
||||
#-------------------------------------------------------------
|
||||
|
||||
test_2: li x10, 2; ebreak; li x1, 0x00000000; li x2, 0x00000000; mulhsu x3, x1, x2;; li x29, 0x00000000; li x28, 2; bne x3, x29, fail;;
|
||||
test_3: li x10, 3; ebreak; li x1, 0x00000001; li x2, 0x00000001; mulhsu x3, x1, x2;; li x29, 0x00000000; li x28, 3; bne x3, x29, fail;;
|
||||
test_4: li x10, 4; ebreak; li x1, 0x00000003; li x2, 0x00000007; mulhsu x3, x1, x2;; li x29, 0x00000000; li x28, 4; bne x3, x29, fail;;
|
||||
|
||||
test_5: li x10, 5; ebreak; li x1, 0x00000000; li x2, 0xffff8000; mulhsu x3, x1, x2;; li x29, 0x00000000; li x28, 5; bne x3, x29, fail;;
|
||||
test_6: li x10, 6; ebreak; li x1, 0x80000000; li x2, 0x00000000; mulhsu x3, x1, x2;; li x29, 0x00000000; li x28, 6; bne x3, x29, fail;;
|
||||
test_7: li x10, 7; ebreak; li x1, 0x80000000; li x2, 0xffff8000; mulhsu x3, x1, x2;; li x29, 0x80004000; li x28, 7; bne x3, x29, fail;;
|
||||
|
||||
test_30: li x10, 30; ebreak; li x1, 0xaaaaaaab; li x2, 0x0002fe7d; mulhsu x3, x1, x2;; li x29, 0xffff0081; li x28, 30; bne x3, x29, fail;;
|
||||
test_31: li x10, 31; ebreak; li x1, 0x0002fe7d; li x2, 0xaaaaaaab; mulhsu x3, x1, x2;; li x29, 0x0001fefe; li x28, 31; bne x3, x29, fail;;
|
||||
|
||||
test_32: li x10, 32; ebreak; li x1, 0xff000000; li x2, 0xff000000; mulhsu x3, x1, x2;; li x29, 0xff010000; li x28, 32; bne x3, x29, fail;;
|
||||
|
||||
test_33: li x10, 33; ebreak; li x1, 0xffffffff; li x2, 0xffffffff; mulhsu x3, x1, x2;; li x29, 0xffffffff; li x28, 33; bne x3, x29, fail;;
|
||||
test_34: li x10, 34; ebreak; li x1, 0xffffffff; li x2, 0x00000001; mulhsu x3, x1, x2;; li x29, 0xffffffff; li x28, 34; bne x3, x29, fail;;
|
||||
test_35: li x10, 35; ebreak; li x1, 0x00000001; li x2, 0xffffffff; mulhsu x3, x1, x2;; li x29, 0x00000000; li x28, 35; bne x3, x29, fail;;
|
||||
|
||||
#-------------------------------------------------------------
|
||||
# Source/Destination tests
|
||||
#-------------------------------------------------------------
|
||||
|
||||
test_8: li x10, 8; ebreak; li x1, 13<<20; li x2, 11<<20; mulhsu x1, x1, x2;; li x29, 36608; li x28, 8; bne x1, x29, fail;;
|
||||
test_9: li x10, 9; ebreak; li x1, 14<<20; li x2, 11<<20; mulhsu x2, x1, x2;; li x29, 39424; li x28, 9; bne x2, x29, fail;;
|
||||
test_10: li x10, 10; ebreak; li x1, 13<<20; mulhsu x1, x1, x1;; li x29, 43264; li x28, 10; bne x1, x29, fail;;
|
||||
|
||||
#-------------------------------------------------------------
|
||||
# Bypassing tests
|
||||
#-------------------------------------------------------------
|
||||
|
||||
test_11: li x10, 11; ebreak; li x4, 0; test_11_l1: li x1, 13<<20; li x2, 11<<20; mulhsu x3, x1, x2; addi x6, x3, 0; addi x4, x4, 1; li x5, 2; bne x4, x5, test_11_l1; li x29, 36608; li x28, 11; bne x6, x29, fail;;
|
||||
test_12: li x10, 12; ebreak; li x4, 0; test_12_l1: li x1, 14<<20; li x2, 11<<20; mulhsu x3, x1, x2; nop; addi x6, x3, 0; addi x4, x4, 1; li x5, 2; bne x4, x5, test_12_l1; li x29, 39424; li x28, 12; bne x6, x29, fail;;
|
||||
test_13: li x10, 13; ebreak; li x4, 0; test_13_l1: li x1, 15<<20; li x2, 11<<20; mulhsu x3, x1, x2; nop; nop; addi x6, x3, 0; addi x4, x4, 1; li x5, 2; bne x4, x5, test_13_l1; li x29, 42240; li x28, 13; bne x6, x29, fail;;
|
||||
|
||||
test_14: li x10, 14; ebreak; li x4, 0; test_14_l1: li x1, 13<<20; li x2, 11<<20; mulhsu x3, x1, x2; addi x4, x4, 1; li x5, 2; bne x4, x5, test_14_l1; li x29, 36608; li x28, 14; bne x3, x29, fail;;
|
||||
test_15: li x10, 15; ebreak; li x4, 0; test_15_l1: li x1, 14<<20; li x2, 11<<20; nop; mulhsu x3, x1, x2; addi x4, x4, 1; li x5, 2; bne x4, x5, test_15_l1; li x29, 39424; li x28, 15; bne x3, x29, fail;;
|
||||
test_16: li x10, 16; ebreak; li x4, 0; test_16_l1: li x1, 15<<20; li x2, 11<<20; nop; nop; mulhsu x3, x1, x2; addi x4, x4, 1; li x5, 2; bne x4, x5, test_16_l1; li x29, 42240; li x28, 16; bne x3, x29, fail;;
|
||||
test_17: li x10, 17; ebreak; li x4, 0; test_17_l1: li x1, 13<<20; nop; li x2, 11<<20; mulhsu x3, x1, x2; addi x4, x4, 1; li x5, 2; bne x4, x5, test_17_l1; li x29, 36608; li x28, 17; bne x3, x29, fail;;
|
||||
test_18: li x10, 18; ebreak; li x4, 0; test_18_l1: li x1, 14<<20; nop; li x2, 11<<20; nop; mulhsu x3, x1, x2; addi x4, x4, 1; li x5, 2; bne x4, x5, test_18_l1; li x29, 39424; li x28, 18; bne x3, x29, fail;;
|
||||
test_19: li x10, 19; ebreak; li x4, 0; test_19_l1: li x1, 15<<20; nop; nop; li x2, 11<<20; mulhsu x3, x1, x2; addi x4, x4, 1; li x5, 2; bne x4, x5, test_19_l1; li x29, 42240; li x28, 19; bne x3, x29, fail;;
|
||||
|
||||
test_20: li x10, 20; ebreak; li x4, 0; test_20_l1: li x2, 11<<20; li x1, 13<<20; mulhsu x3, x1, x2; addi x4, x4, 1; li x5, 2; bne x4, x5, test_20_l1; li x29, 36608; li x28, 20; bne x3, x29, fail;;
|
||||
test_21: li x10, 21; ebreak; li x4, 0; test_21_l1: li x2, 11<<20; li x1, 14<<20; nop; mulhsu x3, x1, x2; addi x4, x4, 1; li x5, 2; bne x4, x5, test_21_l1; li x29, 39424; li x28, 21; bne x3, x29, fail;;
|
||||
test_22: li x10, 22; ebreak; li x4, 0; test_22_l1: li x2, 11<<20; li x1, 15<<20; nop; nop; mulhsu x3, x1, x2; addi x4, x4, 1; li x5, 2; bne x4, x5, test_22_l1; li x29, 42240; li x28, 22; bne x3, x29, fail;;
|
||||
test_23: li x10, 23; ebreak; li x4, 0; test_23_l1: li x2, 11<<20; nop; li x1, 13<<20; mulhsu x3, x1, x2; addi x4, x4, 1; li x5, 2; bne x4, x5, test_23_l1; li x29, 36608; li x28, 23; bne x3, x29, fail;;
|
||||
test_24: li x10, 24; ebreak; li x4, 0; test_24_l1: li x2, 11<<20; nop; li x1, 14<<20; nop; mulhsu x3, x1, x2; addi x4, x4, 1; li x5, 2; bne x4, x5, test_24_l1; li x29, 39424; li x28, 24; bne x3, x29, fail;;
|
||||
test_25: li x10, 25; ebreak; li x4, 0; test_25_l1: li x2, 11<<20; nop; nop; li x1, 15<<20; mulhsu x3, x1, x2; addi x4, x4, 1; li x5, 2; bne x4, x5, test_25_l1; li x29, 42240; li x28, 25; bne x3, x29, fail;;
|
||||
|
||||
test_26: li x10, 26; ebreak; li x1, 31<<26; mulhsu x2, x0, x1;; li x29, 0; li x28, 26; bne x2, x29, fail;;
|
||||
test_27: li x10, 27; ebreak; li x1, 32<<26; mulhsu x2, x1, x0;; li x29, 0; li x28, 27; bne x2, x29, fail;;
|
||||
test_28: li x10, 28; ebreak; mulhsu x1, x0, x0;; li x29, 0; li x28, 28; bne x1, x29, fail;;
|
||||
test_29: li x10, 29; ebreak; li x1, 33<<20; li x2, 34<<20; mulhsu x0, x1, x2;; li x29, 0; li x28, 29; bne x0, x29, fail;;
|
||||
|
||||
|
||||
|
||||
bne x0, x28, pass; fail: unimp;; pass: ___pass: j ___pass;
|
||||
|
||||
|
||||
|
||||
.data
|
||||
.balign 4;
|
||||
|
||||
|
||||
|
||||
|
||||
83
riscv/tests/instruction_tests/sources/mulhsu.S
Normal file
83
riscv/tests/instruction_tests/sources/mulhsu.S
Normal file
@@ -0,0 +1,83 @@
|
||||
# See LICENSE for license details.
|
||||
|
||||
#*****************************************************************************
|
||||
# mulhsu.S
|
||||
#-----------------------------------------------------------------------------
|
||||
#
|
||||
# Test mulhsu instruction.
|
||||
#
|
||||
|
||||
#include "riscv_test.h"
|
||||
#include "test_macros.h"
|
||||
|
||||
RVTEST_RV32U
|
||||
RVTEST_CODE_BEGIN
|
||||
|
||||
#-------------------------------------------------------------
|
||||
# Arithmetic tests
|
||||
#-------------------------------------------------------------
|
||||
|
||||
TEST_RR_OP( 2, mulhsu, 0x00000000, 0x00000000, 0x00000000 );
|
||||
TEST_RR_OP( 3, mulhsu, 0x00000000, 0x00000001, 0x00000001 );
|
||||
TEST_RR_OP( 4, mulhsu, 0x00000000, 0x00000003, 0x00000007 );
|
||||
|
||||
TEST_RR_OP( 5, mulhsu, 0x00000000, 0x00000000, 0xffff8000 );
|
||||
TEST_RR_OP( 6, mulhsu, 0x00000000, 0x80000000, 0x00000000 );
|
||||
TEST_RR_OP( 7, mulhsu, 0x80004000, 0x80000000, 0xffff8000 );
|
||||
|
||||
TEST_RR_OP(30, mulhsu, 0xffff0081, 0xaaaaaaab, 0x0002fe7d );
|
||||
TEST_RR_OP(31, mulhsu, 0x0001fefe, 0x0002fe7d, 0xaaaaaaab );
|
||||
|
||||
TEST_RR_OP(32, mulhsu, 0xff010000, 0xff000000, 0xff000000 );
|
||||
|
||||
TEST_RR_OP(33, mulhsu, 0xffffffff, 0xffffffff, 0xffffffff );
|
||||
TEST_RR_OP(34, mulhsu, 0xffffffff, 0xffffffff, 0x00000001 );
|
||||
TEST_RR_OP(35, mulhsu, 0x00000000, 0x00000001, 0xffffffff );
|
||||
|
||||
#-------------------------------------------------------------
|
||||
# Source/Destination tests
|
||||
#-------------------------------------------------------------
|
||||
|
||||
TEST_RR_SRC1_EQ_DEST( 8, mulhsu, 36608, 13<<20, 11<<20 );
|
||||
TEST_RR_SRC2_EQ_DEST( 9, mulhsu, 39424, 14<<20, 11<<20 );
|
||||
TEST_RR_SRC12_EQ_DEST( 10, mulhsu, 43264, 13<<20 );
|
||||
|
||||
#-------------------------------------------------------------
|
||||
# Bypassing tests
|
||||
#-------------------------------------------------------------
|
||||
|
||||
TEST_RR_DEST_BYPASS( 11, 0, mulhsu, 36608, 13<<20, 11<<20 );
|
||||
TEST_RR_DEST_BYPASS( 12, 1, mulhsu, 39424, 14<<20, 11<<20 );
|
||||
TEST_RR_DEST_BYPASS( 13, 2, mulhsu, 42240, 15<<20, 11<<20 );
|
||||
|
||||
TEST_RR_SRC12_BYPASS( 14, 0, 0, mulhsu, 36608, 13<<20, 11<<20 );
|
||||
TEST_RR_SRC12_BYPASS( 15, 0, 1, mulhsu, 39424, 14<<20, 11<<20 );
|
||||
TEST_RR_SRC12_BYPASS( 16, 0, 2, mulhsu, 42240, 15<<20, 11<<20 );
|
||||
TEST_RR_SRC12_BYPASS( 17, 1, 0, mulhsu, 36608, 13<<20, 11<<20 );
|
||||
TEST_RR_SRC12_BYPASS( 18, 1, 1, mulhsu, 39424, 14<<20, 11<<20 );
|
||||
TEST_RR_SRC12_BYPASS( 19, 2, 0, mulhsu, 42240, 15<<20, 11<<20 );
|
||||
|
||||
TEST_RR_SRC21_BYPASS( 20, 0, 0, mulhsu, 36608, 13<<20, 11<<20 );
|
||||
TEST_RR_SRC21_BYPASS( 21, 0, 1, mulhsu, 39424, 14<<20, 11<<20 );
|
||||
TEST_RR_SRC21_BYPASS( 22, 0, 2, mulhsu, 42240, 15<<20, 11<<20 );
|
||||
TEST_RR_SRC21_BYPASS( 23, 1, 0, mulhsu, 36608, 13<<20, 11<<20 );
|
||||
TEST_RR_SRC21_BYPASS( 24, 1, 1, mulhsu, 39424, 14<<20, 11<<20 );
|
||||
TEST_RR_SRC21_BYPASS( 25, 2, 0, mulhsu, 42240, 15<<20, 11<<20 );
|
||||
|
||||
TEST_RR_ZEROSRC1( 26, mulhsu, 0, 31<<26 );
|
||||
TEST_RR_ZEROSRC2( 27, mulhsu, 0, 32<<26 );
|
||||
TEST_RR_ZEROSRC12( 28, mulhsu, 0 );
|
||||
TEST_RR_ZERODEST( 29, mulhsu, 33<<20, 34<<20 );
|
||||
|
||||
|
||||
|
||||
TEST_PASSFAIL
|
||||
|
||||
RVTEST_CODE_END
|
||||
|
||||
.data
|
||||
RVTEST_DATA_BEGIN
|
||||
|
||||
TEST_DATA
|
||||
|
||||
RVTEST_DATA_END
|
||||
Reference in New Issue
Block a user