diff --git a/core/inst_handlers/rv64/a/RvaInsts.cpp b/core/inst_handlers/rv64/a/RvaInsts.cpp index a04fb9d..6754c2b 100644 --- a/core/inst_handlers/rv64/a/RvaInsts.cpp +++ b/core/inst_handlers/rv64/a/RvaInsts.cpp @@ -1,4 +1,5 @@ #include "core/inst_handlers/rv64/a/RvaInsts.hpp" +#include "core/inst_handlers/rv64/a/inst_helpers.hpp" #include "include/ActionTags.hpp" #include "core/ActionGroup.hpp" @@ -166,467 +167,239 @@ namespace atlas nullptr, "sc_w", ActionTags::EXECUTE_TAG)); } - ActionGroup* RvaInsts::amoadd_w_64_compute_address_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::amoadd_d_64_compute_address_handler(atlas::AtlasState* state) { - (void)state; - return nullptr; + return compute_address_handler(state); } - ActionGroup* RvaInsts::amoadd_w_64_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::amoadd_d_64_handler(atlas::AtlasState* state) { - (void)state; - /////////////////////////////////////////////////////////////////////// - // START OF SPIKE CODE - - // require_extension('A'); - // WRITE_RD(sext32(MMU.amo(RS1, [&](uint32_t lhs) { return lhs + RS2; }))); - - // END OF SPIKE CODE - /////////////////////////////////////////////////////////////////////// - return nullptr; + return amo_handler(state); } - ActionGroup* RvaInsts::amomaxu_w_64_compute_address_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::amoadd_w_64_compute_address_handler(atlas::AtlasState* state) { - (void)state; - return nullptr; + return compute_address_handler(state); } - ActionGroup* RvaInsts::amomaxu_w_64_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::amoadd_w_64_handler(atlas::AtlasState* state) { - (void)state; - /////////////////////////////////////////////////////////////////////// - // START OF SPIKE CODE - - // require_extension('A'); - // WRITE_RD(sext32(MMU.amo(RS1, [&](uint32_t lhs) { return std::max(lhs, - // uint32_t(RS2)); }))); - - // END OF SPIKE CODE - /////////////////////////////////////////////////////////////////////// - return nullptr; + return amo_handler(state); } - ActionGroup* RvaInsts::amoadd_d_64_compute_address_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::amoand_d_64_compute_address_handler(atlas::AtlasState* state) { - (void)state; - return nullptr; + return compute_address_handler(state); } - ActionGroup* RvaInsts::amoadd_d_64_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::amoand_d_64_handler(atlas::AtlasState* state) { - (void)state; - /////////////////////////////////////////////////////////////////////// - // START OF SPIKE CODE - - // require_extension('A'); - // require_rv64; - // WRITE_RD(MMU.amo(RS1, [&](uint64_t lhs) { return lhs + RS2; })); - - // END OF SPIKE CODE - /////////////////////////////////////////////////////////////////////// - return nullptr; + return amo_handler(state); } - ActionGroup* RvaInsts::amominu_d_64_compute_address_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::amoand_w_64_compute_address_handler(atlas::AtlasState* state) { - (void)state; - return nullptr; + return compute_address_handler(state); } - ActionGroup* RvaInsts::amominu_d_64_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::amoand_w_64_handler(atlas::AtlasState* state) { - (void)state; - /////////////////////////////////////////////////////////////////////// - // START OF SPIKE CODE - - // require_extension('A'); - // require_rv64; - // WRITE_RD(MMU.amo(RS1, [&](uint64_t lhs) { return std::min(lhs, RS2); })); - - // END OF SPIKE CODE - /////////////////////////////////////////////////////////////////////// - return nullptr; + return amo_handler(state); } - ActionGroup* RvaInsts::amominu_w_64_compute_address_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::amomax_d_64_compute_address_handler(atlas::AtlasState* state) { - (void)state; - return nullptr; + return compute_address_handler(state); } - ActionGroup* RvaInsts::amominu_w_64_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::amomax_d_64_handler(atlas::AtlasState* state) { - (void)state; - /////////////////////////////////////////////////////////////////////// - // START OF SPIKE CODE - - // require_extension('A'); - // WRITE_RD(sext32(MMU.amo(RS1, [&](uint32_t lhs) { return std::min(lhs, - // uint32_t(RS2)); }))); - - // END OF SPIKE CODE - /////////////////////////////////////////////////////////////////////// - return nullptr; + return amo_handler(state); } - ActionGroup* RvaInsts::amoor_d_64_compute_address_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::amomax_w_64_compute_address_handler(atlas::AtlasState* state) { - (void)state; - return nullptr; + return compute_address_handler(state); } - ActionGroup* RvaInsts::amoor_d_64_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::amomax_w_64_handler(atlas::AtlasState* state) { - (void)state; - /////////////////////////////////////////////////////////////////////// - // START OF SPIKE CODE - - // require_extension('A'); - // require_rv64; - // WRITE_RD(MMU.amo(RS1, [&](uint64_t lhs) { return lhs | RS2; })); - - // END OF SPIKE CODE - /////////////////////////////////////////////////////////////////////// - return nullptr; + return amo_handler(state); } - ActionGroup* RvaInsts::amoxor_d_64_compute_address_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::amomaxu_d_64_compute_address_handler(atlas::AtlasState* state) { - (void)state; - return nullptr; + return compute_address_handler(state); } - ActionGroup* RvaInsts::amoxor_d_64_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::amomaxu_d_64_handler(atlas::AtlasState* state) { - (void)state; - /////////////////////////////////////////////////////////////////////// - // START OF SPIKE CODE - - // require_extension('A'); - // require_rv64; - // WRITE_RD(MMU.amo(RS1, [&](uint64_t lhs) { return lhs ^ RS2; })); - - // END OF SPIKE CODE - /////////////////////////////////////////////////////////////////////// - return nullptr; + return amo_handler(state); } - ActionGroup* RvaInsts::amoswap_w_64_compute_address_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::amomaxu_w_64_compute_address_handler(atlas::AtlasState* state) { - (void)state; - return nullptr; + return compute_address_handler(state); } - ActionGroup* RvaInsts::amoswap_w_64_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::amomaxu_w_64_handler(atlas::AtlasState* state) { - (void)state; - /////////////////////////////////////////////////////////////////////// - // START OF SPIKE CODE - - // require_extension('A'); - // WRITE_RD(sext32(MMU.amo(RS1, [&](uint32_t UNUSED lhs) { return RS2; }))); - - // END OF SPIKE CODE - /////////////////////////////////////////////////////////////////////// - return nullptr; + return amo_handler(state); } - ActionGroup* RvaInsts::lr_d_64_compute_address_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::amomin_d_64_compute_address_handler(atlas::AtlasState* state) { - (void)state; - return nullptr; + return compute_address_handler(state); } - ActionGroup* RvaInsts::lr_d_64_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::amomin_d_64_handler(atlas::AtlasState* state) { - (void)state; - /////////////////////////////////////////////////////////////////////// - // START OF SPIKE CODE - - // require_extension('A'); - // require_rv64; - // WRITE_RD(MMU.load_reserved(RS1)); - - // END OF SPIKE CODE - /////////////////////////////////////////////////////////////////////// - return nullptr; + return amo_handler(state); } - ActionGroup* RvaInsts::amoor_w_64_compute_address_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::amomin_w_64_compute_address_handler(atlas::AtlasState* state) { - (void)state; - return nullptr; + return compute_address_handler(state); } - ActionGroup* RvaInsts::amoor_w_64_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::amomin_w_64_handler(atlas::AtlasState* state) { - (void)state; - /////////////////////////////////////////////////////////////////////// - // START OF SPIKE CODE - - // require_extension('A'); - // WRITE_RD(sext32(MMU.amo(RS1, [&](uint32_t lhs) { return lhs | RS2; }))); - - // END OF SPIKE CODE - /////////////////////////////////////////////////////////////////////// - return nullptr; + return amo_handler(state); } - ActionGroup* RvaInsts::amomaxu_d_64_compute_address_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::amominu_d_64_compute_address_handler(atlas::AtlasState* state) { - (void)state; - return nullptr; + return compute_address_handler(state); } - ActionGroup* RvaInsts::amomaxu_d_64_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::amominu_d_64_handler(atlas::AtlasState* state) { - (void)state; - /////////////////////////////////////////////////////////////////////// - // START OF SPIKE CODE - - // require_extension('A'); - // require_rv64; - // WRITE_RD(MMU.amo(RS1, [&](uint64_t lhs) { return std::max(lhs, RS2); })); - - // END OF SPIKE CODE - /////////////////////////////////////////////////////////////////////// - return nullptr; + return amo_handler(state); } - ActionGroup* RvaInsts::amoswap_d_64_compute_address_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::amominu_w_64_compute_address_handler(atlas::AtlasState* state) { - (void)state; - return nullptr; + return compute_address_handler(state); } - ActionGroup* RvaInsts::amoswap_d_64_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::amominu_w_64_handler(atlas::AtlasState* state) { - (void)state; - /////////////////////////////////////////////////////////////////////// - // START OF SPIKE CODE - - // require_extension('A'); - // require_rv64; - // WRITE_RD(MMU.amo(RS1, [&](uint64_t UNUSED lhs) { return RS2; })); - - // END OF SPIKE CODE - /////////////////////////////////////////////////////////////////////// - return nullptr; + return amo_handler(state); } - ActionGroup* RvaInsts::amomax_w_64_compute_address_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::amoor_d_64_compute_address_handler(atlas::AtlasState* state) { - (void)state; - return nullptr; + return compute_address_handler(state); } - ActionGroup* RvaInsts::amomax_w_64_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::amoor_d_64_handler(atlas::AtlasState* state) { - (void)state; - /////////////////////////////////////////////////////////////////////// - // START OF SPIKE CODE - - // require_extension('A'); - // WRITE_RD(sext32(MMU.amo(RS1, [&](int32_t lhs) { return std::max(lhs, - // int32_t(RS2)); }))); - - // END OF SPIKE CODE - /////////////////////////////////////////////////////////////////////// - return nullptr; + return amo_handler(state); } - ActionGroup* RvaInsts::amomin_d_64_compute_address_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::amoor_w_64_compute_address_handler(atlas::AtlasState* state) { - (void)state; - return nullptr; + return compute_address_handler(state); } - ActionGroup* RvaInsts::amomin_d_64_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::amoor_w_64_handler(atlas::AtlasState* state) { - (void)state; - /////////////////////////////////////////////////////////////////////// - // START OF SPIKE CODE - - // require_extension('A'); - // require_rv64; - // WRITE_RD(MMU.amo(RS1, [&](int64_t lhs) { return std::min(lhs, int64_t(RS2)); - // })); - - // END OF SPIKE CODE - /////////////////////////////////////////////////////////////////////// - return nullptr; + return amo_handler(state); } - ActionGroup* RvaInsts::amoxor_w_64_compute_address_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::amoswap_d_64_compute_address_handler(atlas::AtlasState* state) { - (void)state; - return nullptr; + return compute_address_handler(state); } - ActionGroup* RvaInsts::amoxor_w_64_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::amoswap_d_64_handler(atlas::AtlasState* state) { - (void)state; - /////////////////////////////////////////////////////////////////////// - // START OF SPIKE CODE - - // require_extension('A'); - // WRITE_RD(sext32(MMU.amo(RS1, [&](uint32_t lhs) { return lhs ^ RS2; }))); - - // END OF SPIKE CODE - /////////////////////////////////////////////////////////////////////// - return nullptr; + return amo_handler(state); } - ActionGroup* RvaInsts::sc_w_64_compute_address_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::amoswap_w_64_compute_address_handler(atlas::AtlasState* state) { - (void)state; - return nullptr; + return compute_address_handler(state); } - ActionGroup* RvaInsts::sc_w_64_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::amoswap_w_64_handler(atlas::AtlasState* state) { - (void)state; - /////////////////////////////////////////////////////////////////////// - // START OF SPIKE CODE - - // require_extension('A'); - - // bool have_reservation = MMU.store_conditional(RS1, RS2); - - // WRITE_RD(!have_reservation); - - // END OF SPIKE CODE - /////////////////////////////////////////////////////////////////////// - return nullptr; + return amo_handler(state); } - ActionGroup* RvaInsts::amoand_d_64_compute_address_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::amoxor_d_64_compute_address_handler(atlas::AtlasState* state) { - (void)state; - return nullptr; + return compute_address_handler(state); } - ActionGroup* RvaInsts::amoand_d_64_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::amoxor_d_64_handler(atlas::AtlasState* state) { - (void)state; - /////////////////////////////////////////////////////////////////////// - // START OF SPIKE CODE - - // require_extension('A'); - // require_rv64; - // WRITE_RD(MMU.amo(RS1, [&](uint64_t lhs) { return lhs & RS2; })); - - // END OF SPIKE CODE - /////////////////////////////////////////////////////////////////////// - return nullptr; + return amo_handler(state); } - ActionGroup* RvaInsts::amomin_w_64_compute_address_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::amoxor_w_64_compute_address_handler(atlas::AtlasState* state) { - (void)state; - return nullptr; + return compute_address_handler(state); } - ActionGroup* RvaInsts::amomin_w_64_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::amoxor_w_64_handler(atlas::AtlasState* state) { - (void)state; - /////////////////////////////////////////////////////////////////////// - // START OF SPIKE CODE - - // require_extension('A'); - // WRITE_RD(sext32(MMU.amo(RS1, [&](int32_t lhs) { return std::min(lhs, - // int32_t(RS2)); }))); - - // END OF SPIKE CODE - /////////////////////////////////////////////////////////////////////// - return nullptr; + return amo_handler(state); } - ActionGroup* RvaInsts::amoand_w_64_compute_address_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::lr_d_64_compute_address_handler(atlas::AtlasState* state) { - (void)state; - return nullptr; + return compute_address_handler(state); } - ActionGroup* RvaInsts::amoand_w_64_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::lr_d_64_handler(atlas::AtlasState* state) { - (void)state; - /////////////////////////////////////////////////////////////////////// - // START OF SPIKE CODE - - // require_extension('A'); - // WRITE_RD(sext32(MMU.amo(RS1, [&](uint32_t lhs) { return lhs & RS2; }))); - - // END OF SPIKE CODE - /////////////////////////////////////////////////////////////////////// + const AtlasInstPtr & inst = state->getCurrentInst(); + const uint64_t paddr = state->getTranslationState()->getTranslationResult().getPaddr(); + const uint64_t rd_val = state->readMemory(paddr); + inst->getRd()->write(rd_val); return nullptr; } - ActionGroup* RvaInsts::amomax_d_64_compute_address_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::lr_w_64_compute_address_handler(atlas::AtlasState* state) { - (void)state; - return nullptr; + return compute_address_handler(state); } - ActionGroup* RvaInsts::amomax_d_64_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::lr_w_64_handler(atlas::AtlasState* state) { - (void)state; - /////////////////////////////////////////////////////////////////////// - // START OF SPIKE CODE - - // require_extension('A'); - // require_rv64; - // WRITE_RD(MMU.amo(RS1, [&](int64_t lhs) { return std::max(lhs, int64_t(RS2)); - // })); - - // END OF SPIKE CODE - /////////////////////////////////////////////////////////////////////// + const AtlasInstPtr & inst = state->getCurrentInst(); + const uint64_t paddr = state->getTranslationState()->getTranslationResult().getPaddr(); + const uint64_t rd_val = signExtend(state->readMemory(paddr)); + inst->getRd()->write(rd_val); return nullptr; } - ActionGroup* RvaInsts::lr_w_64_compute_address_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::sc_d_64_compute_address_handler(atlas::AtlasState* state) { - (void)state; - return nullptr; + return compute_address_handler(state); } - ActionGroup* RvaInsts::lr_w_64_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::sc_d_64_handler(atlas::AtlasState* state) { - (void)state; - /////////////////////////////////////////////////////////////////////// - // START OF SPIKE CODE - - // require_extension('A'); - // WRITE_RD(MMU.load_reserved(RS1)); - - // END OF SPIKE CODE - /////////////////////////////////////////////////////////////////////// + const AtlasInstPtr & inst = state->getCurrentInst(); + const uint64_t rs2_val = inst->getRs2()->read(); + const uint64_t paddr = state->getTranslationState()->getTranslationResult().getPaddr(); + state->writeMemory(paddr, rs2_val); return nullptr; } - ActionGroup* RvaInsts::sc_d_64_compute_address_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::sc_w_64_compute_address_handler(atlas::AtlasState* state) { - (void)state; - return nullptr; + return compute_address_handler(state); } - ActionGroup* RvaInsts::sc_d_64_handler(atlas::AtlasState* state) + ActionGroup* RvaInsts::sc_w_64_handler(atlas::AtlasState* state) { - (void)state; - /////////////////////////////////////////////////////////////////////// - // START OF SPIKE CODE - - // require_extension('A'); - // require_rv64; - - // bool have_reservation = MMU.store_conditional(RS1, RS2); - - // WRITE_RD(!have_reservation); - - // END OF SPIKE CODE - /////////////////////////////////////////////////////////////////////// + const AtlasInstPtr & inst = state->getCurrentInst(); + const uint64_t rs2_val = inst->getRs2()->read(); + const uint64_t paddr = state->getTranslationState()->getTranslationResult().getPaddr(); + state->writeMemory(paddr, rs2_val); return nullptr; } - } // namespace atlas \ No newline at end of file diff --git a/core/inst_handlers/rv64/a/inst_helpers.hpp b/core/inst_handlers/rv64/a/inst_helpers.hpp new file mode 100644 index 0000000..6c5a99a --- /dev/null +++ b/core/inst_handlers/rv64/a/inst_helpers.hpp @@ -0,0 +1,74 @@ +#pragma once +#include "core/AtlasState.hpp" +#include "core/AtlasInst.hpp" +#include "include/AtlasUtils.hpp" + +namespace atlas +{ + class ActionGroup; + + using W = uint32_t; + using D = uint64_t; + + template ActionGroup* compute_address_handler(AtlasState* state) + { + static_assert(std::is_same::value || std::is_same::value); + + const AtlasInstPtr & inst = state->getCurrentInst(); + const T rs1_val = inst->getRs1()->read(); + constexpr uint32_t IMM_SIZE = 12; + const T imm = inst->hasImmediate() ? inst->getSignExtendedImmediate() : 0; + const T vaddr = rs1_val + imm; + state->getTranslationState()->makeTranslationRequest(vaddr, sizeof(T)); + return nullptr; + } + + template class BinaryOp, bool U = true> + ActionGroup* amo_handler(atlas::AtlasState* state) + { + static_assert(std::is_same::value || std::is_same::value); + static_assert(std::is_same::value || std::is_same::value); + static_assert(sizeof(RV) >= sizeof(SIZE)); + + using Op = + typename std::conditional::value, + typename std::conditional::type, + typename std::conditional::type>::type; + + BinaryOp binary_op; + const AtlasInstPtr & inst = state->getCurrentInst(); + const RV paddr = state->getTranslationState()->getTranslationResult().getPaddr(); + RV rd_val = 0; + if constexpr (sizeof(RV) > sizeof(SIZE)) + { + rd_val = signExtend(state->readMemory(paddr)); + } + else + { + rd_val = state->readMemory(paddr); + } + inst->getRd()->write(rd_val); + const RV rs2_val = inst->getRs2()->read(); + state->writeMemory(paddr, binary_op(rd_val, rs2_val)); + return nullptr; + } + + template struct MaxFunctor + { + constexpr T operator()(const T & lhs, const T & rhs) const { return lhs > rhs ? lhs : rhs; } + }; + + template struct MinFunctor + { + constexpr T operator()(const T & lhs, const T & rhs) const { return lhs > rhs ? rhs : lhs; } + }; + + template struct SwapFunctor + { + constexpr T operator()(const T & lhs, const T & rhs) const + { + (void)lhs; + return rhs; + } + }; +} // namespace atlas \ No newline at end of file