From 21b01eb899545d759d1230177918fda0fa9f08b4 Mon Sep 17 00:00:00 2001 From: Yuanhsi Chung Date: Tue, 2 Jan 2024 12:35:04 +0800 Subject: [PATCH 1/3] Fix issue #258 --- src/isa/rv_i_ext.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/isa/rv_i_ext.h b/src/isa/rv_i_ext.h index 98ee6106..9d9bc202 100644 --- a/src/isa/rv_i_ext.h +++ b/src/isa/rv_i_ext.h @@ -271,7 +271,7 @@ struct Ecall : public Instr { namespace TypeU { -/// A RISC-V immediate field with an input width of 32 bits. +/// A RISC-V immediate field with an input width of 20 bits. /// Used in U-Type instructions. /// /// It is defined as: @@ -280,7 +280,7 @@ namespace TypeU { constexpr static unsigned VALID_INDEX = 1; template struct ImmU - : public ImmSym, symbolType> { + : public ImmSym, symbolType> { static_assert(index == VALID_INDEX, "Invalid token index"); }; From 85e406b9d59e4f27b4ae5140f6d87600478fe998 Mon Sep 17 00:00:00 2001 From: Yuanhsi Chung Date: Thu, 4 Jan 2024 16:24:56 +0800 Subject: [PATCH 2/3] Add imm bit range testing for RV32I --- test/tst_assembler.cpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/test/tst_assembler.cpp b/test/tst_assembler.cpp index 0970a8f4..fac4d8a8 100644 --- a/test/tst_assembler.cpp +++ b/test/tst_assembler.cpp @@ -41,6 +41,7 @@ private slots: void tst_invalidreg(); void tst_expression(); void tst_invalidLabel(); + void tst_immBitRange(); void tst_directives(); void tst_stringDirectives(); void tst_riscv(); @@ -253,6 +254,34 @@ void tst_Assembler::tst_invalidLabel() { testAssemble(QStringList() << "addi a0 a0 (a", Expect::Fail); } +void tst_Assembler::tst_immBitRange() { + // [ILS]-type : 12 bits imm (ImmCommon12, ImmS) + testAssemble(QStringList() << "addi a0 x0 0x0FFF", Expect::Success); + testAssemble(QStringList() << "addi a0 x0 0x1000", Expect::Fail); + testAssemble(QStringList() << "lw a0 0x0FFF(x0)", Expect::Success); + testAssemble(QStringList() << "lw a0 0x1000(x0)", Expect::Fail); + testAssemble(QStringList() << "sw a0 0x0FFF(x0)", Expect::Success); + testAssemble(QStringList() << "sw a0 0x1000(x0)", Expect::Fail); + // I-type (Shift): 5 bits imm (ImmIShift32) + testAssemble(QStringList() << "slli a1 a0 0b11111", Expect::Success); + testAssemble(QStringList() << "slli a1 a0 0b111111", Expect::Fail); + // U-type: 20 bits imm (ImmU) + testAssemble(QStringList() << "lui a0 0x0FFFFF", Expect::Success); + testAssemble(QStringList() << "lui a0 0x100000", Expect::Fail); + testAssemble(QStringList() << "auipc a0 0x0FFFFF", Expect::Success); + testAssemble(QStringList() << "auipc a0 0x100000", Expect::Fail); + // J-type: 21 bits imm (ImmJ) + testAssemble(QStringList() << "jal x0 0x1FFFFF", Expect::Success); + testAssemble(QStringList() << "jal x0 0x200000", Expect::Fail); + // B-type: 13 bits imm (ImmB) + testAssemble(QStringList() << "beq a0 x0 0x1FFF", Expect::Success); + testAssemble(QStringList() << "beq a0 x0 0x2000", Expect::Fail); + // pseudo: 32 bits imm + testAssemble(QStringList() << "li a0 0xFFFFFFFF", Expect::Success); + testAssemble(QStringList() << "li a0 0x100000000", Expect::Fail); + // TODO: 64b and [CM]-ext +} + void tst_Assembler::tst_benchmarkNew() { auto isa = std::make_shared>(QStringList()); auto assembler = ISA_Assembler(isa); From cbf75be7ee77a3600d948e86476dba323a32b2c1 Mon Sep 17 00:00:00 2001 From: Yuanhsi Chung Date: Thu, 25 Jan 2024 15:38:15 +0800 Subject: [PATCH 3/3] Fix immediate width of ImmJ and ImmB --- src/isa/rv_i_ext.h | 8 ++++---- test/tst_assembler.cpp | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/isa/rv_i_ext.h b/src/isa/rv_i_ext.h index 9d9bc202..302b446e 100644 --- a/src/isa/rv_i_ext.h +++ b/src/isa/rv_i_ext.h @@ -309,7 +309,7 @@ struct Lui : public Instr { namespace TypeJ { -/// A RISC-V signed immediate field with an input width of 21 bits. +/// A RISC-V signed immediate field with an input width of 20 bits. /// Used in J-Type instructions. /// /// It is defined as: @@ -321,7 +321,7 @@ namespace TypeJ { /// - Imm[0] = 0 constexpr static unsigned VALID_INDEX = 1; template -struct ImmJ : public ImmSym, ImmPart<12, 12, 19>, ImmPart<11, 20, 20>, ImmPart<1, 21, 30>>, SymbolType::Relative> { @@ -489,7 +489,7 @@ enum class Funct3 { BGEU = 0b111 }; -/// A RISC-V signed immediate field with an input width of 13 bits. +/// A RISC-V signed immediate field with an input width of 12 bits. /// Used in B-Type instructions. /// /// It is defined as: @@ -500,7 +500,7 @@ enum class Funct3 { /// - Imm[0] = 0 constexpr static unsigned VALID_INDEX = 2; template -struct ImmB : public ImmSym, ImmPart<11, 7, 7>, ImmPart<5, 25, 30>, ImmPart<1, 8, 11>>, SymbolType::Relative> { diff --git a/test/tst_assembler.cpp b/test/tst_assembler.cpp index fac4d8a8..654bbd84 100644 --- a/test/tst_assembler.cpp +++ b/test/tst_assembler.cpp @@ -270,12 +270,12 @@ void tst_Assembler::tst_immBitRange() { testAssemble(QStringList() << "lui a0 0x100000", Expect::Fail); testAssemble(QStringList() << "auipc a0 0x0FFFFF", Expect::Success); testAssemble(QStringList() << "auipc a0 0x100000", Expect::Fail); - // J-type: 21 bits imm (ImmJ) - testAssemble(QStringList() << "jal x0 0x1FFFFF", Expect::Success); - testAssemble(QStringList() << "jal x0 0x200000", Expect::Fail); - // B-type: 13 bits imm (ImmB) - testAssemble(QStringList() << "beq a0 x0 0x1FFF", Expect::Success); - testAssemble(QStringList() << "beq a0 x0 0x2000", Expect::Fail); + // J-type: 20 bits imm (ImmJ) + testAssemble(QStringList() << "jal x0 0x0FFFFF", Expect::Success); + testAssemble(QStringList() << "jal x0 0x100000", Expect::Fail); + // B-type: 12 bits imm (ImmB) + testAssemble(QStringList() << "beq a0 x0 0x0FFF", Expect::Success); + testAssemble(QStringList() << "beq a0 x0 0x1000", Expect::Fail); // pseudo: 32 bits imm testAssemble(QStringList() << "li a0 0xFFFFFFFF", Expect::Success); testAssemble(QStringList() << "li a0 0x100000000", Expect::Fail);