Skip to content

Commit

Permalink
assembler: Add CFI (Zicfiss/Zicfilp) instructions
Browse files Browse the repository at this point in the history
May as well, since they've been ratified.
  • Loading branch information
lioncash committed Oct 29, 2024
1 parent 82637c5 commit c7101a5
Show file tree
Hide file tree
Showing 7 changed files with 175 additions and 0 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ Includes both 32-bit and 64-bit instructions in the following:
| Zicbom | 1.0 |
| Zicbop | 1.0 |
| Zicboz | 1.0 |
| Zicfilp | 1.0 |
| Zicfiss | 1.0 |
| Zicond | 1.0.1 |
| Zicsr | 2.0 |
| Zifencei | 2.0 |
Expand Down
11 changes: 11 additions & 0 deletions include/biscuit/assembler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -813,6 +813,17 @@ class Assembler {
void PREFETCH_R(GPR rs, int32_t offset = 0) noexcept;
void PREFETCH_W(GPR rs, int32_t offset = 0) noexcept;

// Control Flow Integrity Extension Instructions (Zicfiss and Zicfilp)

void SSAMOSWAP_D(Ordering ordering, GPR rd, GPR rs2, GPR rs1) noexcept;
void SSAMOSWAP_W(Ordering ordering, GPR rd, GPR rs2, GPR rs1) noexcept;
void SSRDP(GPR rd) noexcept;
void SSPOPCHK(GPR rs2) noexcept;
void SSPUSH(GPR rs2) noexcept;
void C_SSPOPCHK() noexcept;
void C_SSPUSH() noexcept;
void LPAD(int32_t imm) noexcept;

// Privileged Instructions

void HFENCE_GVMA(GPR rs1, GPR rs2) noexcept;
Expand Down
2 changes: 2 additions & 0 deletions include/biscuit/csr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ enum class CSR : uint32_t {
FRM = 0x002, // Floating-point Dynamic Rounding Mode
FCSR = 0x003, // Floating-point Control and Status Register (frm + fflags)

SSP = 0x011, // Shadow stack pointer

JVT = 0x017, // Table jump base vector and control register

Cycle = 0xC00, // Cycle counter for RDCYCLE instruction.
Expand Down
25 changes: 25 additions & 0 deletions src/assembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1258,6 +1258,31 @@ void Assembler::PREFETCH_W(GPR rs, int32_t offset) noexcept {
EmitIType(m_buffer, static_cast<uint32_t>(offset) | 0b11, rs, 0b110, x0, 0b0010011);
}

// Control flow integrity instructions

void Assembler::SSAMOSWAP_D(Ordering ordering, GPR rd, GPR rs2, GPR rs1) noexcept {
BISCUIT_ASSERT(IsRV64(m_features));
EmitAtomic(m_buffer, 0b01001, ordering, rs2, rs1, 0b011, rd, 0b0101111);
}
void Assembler::SSAMOSWAP_W(Ordering ordering, GPR rd, GPR rs2, GPR rs1) noexcept {
EmitAtomic(m_buffer, 0b01001, ordering, rs2, rs1, 0b010, rd, 0b0101111);
}
void Assembler::SSRDP(GPR rd) noexcept {
BISCUIT_ASSERT(rd != x0);
EmitMOP_R(m_buffer, 28, rd, x0);
}
void Assembler::SSPOPCHK(GPR rs) noexcept {
BISCUIT_ASSERT(rs == x1 || rs == x5);
EmitMOP_R(m_buffer, 28, x0, rs);
}
void Assembler::SSPUSH(GPR rs) noexcept {
BISCUIT_ASSERT(rs == x1 || rs == x5);
EmitMOP_RR(m_buffer, 7, x0, x0, rs);
}
void Assembler::LPAD(int32_t imm) noexcept {
EmitUType(m_buffer, static_cast<uint32_t>(imm), x0, 0b0010111);
}

// Privileged Instructions

void Assembler::HFENCE_GVMA(GPR rs1, GPR rs2) noexcept {
Expand Down
9 changes: 9 additions & 0 deletions src/assembler_compressed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -689,4 +689,13 @@ void Assembler::CM_PUSH(PushPopList reg_list, int32_t stack_adj) noexcept {
EmitCMPPType(m_buffer, 0b101110, 0b00, reg_list, stack_adj, 0b10, m_features);
}

// Control Flow Integrity Extension Instructions

void Assembler::C_SSPOPCHK() noexcept {
EmitCMOP(m_buffer, 5);
}
void Assembler::C_SSPUSH() noexcept {
EmitCMOP(m_buffer, 1);
}

} // namespace biscuit
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ project(biscuit_tests)
add_executable(${PROJECT_NAME}
src/assembler_bfloat_tests.cpp
src/assembler_branch_tests.cpp
src/assembler_cfi_tests.cpp
src/assembler_cmo_tests.cpp
src/assembler_privileged_tests.cpp
src/assembler_rv32i_tests.cpp
Expand Down
125 changes: 125 additions & 0 deletions tests/src/assembler_cfi_tests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
#include <catch/catch.hpp>

#include <biscuit/assembler.hpp>

#include "assembler_test_utils.hpp"

using namespace biscuit;

TEST_CASE("SSAMOSWAP.D", "[Zicfiss]") {
uint32_t value = 0;
auto as = MakeAssembler64(value);

as.SSAMOSWAP_D(Ordering::None, x31, x7, x15);
REQUIRE(value == 0x4877BFAF);

as.RewindBuffer();

as.SSAMOSWAP_D(Ordering::AQ, x31, x7, x15);
REQUIRE(value == 0x4C77BFAF);

as.RewindBuffer();

as.SSAMOSWAP_D(Ordering::RL, x31, x7, x15);
REQUIRE(value == 0x4A77BFAF);

as.RewindBuffer();

as.SSAMOSWAP_D(Ordering::AQRL, x31, x7, x15);
REQUIRE(value == 0x4E77BFAF);
}

TEST_CASE("SSAMOSWAP.W", "[Zicfiss]") {
uint32_t value = 0;
auto as = MakeAssembler32(value);

as.SSAMOSWAP_W(Ordering::None, x31, x7, x15);
REQUIRE(value == 0x4877AFAF);

as.RewindBuffer();

as.SSAMOSWAP_W(Ordering::AQ, x31, x7, x15);
REQUIRE(value == 0x4C77AFAF);

as.RewindBuffer();

as.SSAMOSWAP_W(Ordering::RL, x31, x7, x15);
REQUIRE(value == 0x4A77AFAF);

as.RewindBuffer();

as.SSAMOSWAP_W(Ordering::AQRL, x31, x7, x15);
REQUIRE(value == 0x4E77AFAF);
}

TEST_CASE("SSRDP", "[Zicfiss]") {
uint32_t value = 0;
auto as = MakeAssembler32(value);

for (uint32_t i = 1; i <= 31; i++) {
as.SSRDP(GPR{i});
REQUIRE(value == (0xCDC04073U | (i << 7)));

as.RewindBuffer();
}
}

TEST_CASE("SSPOPCHK", "[Zicfiss]") {
uint32_t value = 0;
auto as = MakeAssembler32(value);

as.SSPOPCHK(x1);
REQUIRE(value == 0xCDC0C073);

as.RewindBuffer();

as.SSPOPCHK(x5);
REQUIRE(value == 0xCDC2C073);
}

TEST_CASE("C.SSPOPCHK", "[Zicfiss]") {
uint16_t value = 0;
auto as = MakeAssembler32(value);

as.C_SSPOPCHK();
REQUIRE(value == 0x6281U);
}

TEST_CASE("SSPUSH", "[Zicfiss]") {
uint32_t value = 0;
auto as = MakeAssembler32(value);

as.SSPUSH(x1);
REQUIRE(value == 0xCE104073);

as.RewindBuffer();

as.SSPUSH(x5);
REQUIRE(value == 0xCE504073);
}

TEST_CASE("C.SSPUSH", "[Zicfiss]") {
uint16_t value = 0;
auto as = MakeAssembler32(value);

as.C_SSPUSH();
REQUIRE(value == 0x6081U);
}

TEST_CASE("LPAD", "[Zicfilp]") {
uint32_t value = 0;
auto as = MakeAssembler32(value);

as.LPAD(-1);
REQUIRE(value == 0xFFFFF017);

as.RewindBuffer();

as.LPAD(0);
REQUIRE(value == 0x00000017);

as.RewindBuffer();

as.LPAD(0x00FF00FF);
REQUIRE(value == 0xF00FF017);
}

0 comments on commit c7101a5

Please sign in to comment.