sim: adding constructor to GuestAddr

A constructor is added to GuestAddr as suggested in the pull request
feedback. This allows a cast conversion from uint64_t GuestAddr. Hence,
the casting from uint64_t to GuestAddr by reinterpret_cast is removed
(was added in a previous commit).

using namespace pseudo_inst is also removed as requested.

Comments are added to GuestAddr.

Change-Id: Ib76de2bff285f4e53ad03361969c27f7bb2dfe9e
This commit is contained in:
Robert Hauser
2024-03-30 20:09:18 +00:00
parent 0b45be7720
commit f9a9e50007
8 changed files with 39 additions and 42 deletions

View File

@@ -55,8 +55,6 @@ struct RegABI64 : public GenericSyscallABI64
namespace guest_abi
{
using namespace pseudo_inst;
template <typename ABI, typename Arg>
struct Argument<ABI, Arg,
typename std::enable_if_t<
@@ -74,22 +72,22 @@ struct Argument<ABI, Arg,
"Ran out of syscall argument registers.");
auto low = ABI::ArgumentRegs[state++];
auto high = ABI::ArgumentRegs[state++];
return (Arg) ABI::mergeRegs(tc, low, high);
return (Arg)ABI::mergeRegs(tc, low, high);
}
};
template <>
struct Argument<ArmISA::RegABI32, GuestAddr>
struct Argument<ArmISA::RegABI32, pseudo_inst::GuestAddr>
{
using ABI = ArmISA::RegABI32;
using Arg = pseudo_inst::GuestAddr;
static GuestAddr
static Arg
get(ThreadContext *tc, typename ABI::State &state)
{
panic_if(state + 1 >= ABI::ArgumentRegs.size(),
"Ran out of syscall argument registers.");
auto arg = bits(tc->getReg(ABI::ArgumentRegs[state++]), 31, 0);
return *reinterpret_cast<GuestAddr*>(&arg);
return (Arg)bits(tc->getReg(ABI::ArgumentRegs[state++]), 31, 0);
}
};

View File

@@ -603,36 +603,33 @@ std::ostream &operator << (
namespace guest_abi
{
using namespace pseudo_inst;
template <typename Arg>
struct Argument<ArmSemihosting::Abi64, Arg,
typename std::enable_if_t<
(std::is_integral_v<Arg> || std::is_same<Arg,GuestAddr>::value)>>
(std::is_integral_v<Arg> ||
std::is_same<Arg,pseudo_inst::GuestAddr>::value)>>
{
static Arg
get(ThreadContext *tc, ArmSemihosting::Abi64::State &state)
{
auto arg = state.get(tc);
return *reinterpret_cast<Arg*>(&arg);
return (Arg)state.get(tc);
}
};
template <typename Arg>
struct Argument<ArmSemihosting::Abi32, Arg,
typename std::enable_if_t<
(std::is_integral_v<Arg> || std::is_same<Arg,GuestAddr>::value)>>
(std::is_integral_v<Arg> ||
std::is_same<Arg,pseudo_inst::GuestAddr>::value)>>
{
static Arg
get(ThreadContext *tc, ArmSemihosting::Abi32::State &state)
{
if (std::is_signed_v<Arg>) {
auto arg = sext<32>(state.get(tc));
return *reinterpret_cast<Arg*>(&arg);
return (Arg)sext<32>(state.get(tc));
}
else {
auto arg = state.get(tc);
return *reinterpret_cast<Arg*>(&arg);
return (Arg)state.get(tc);
}
}
};

View File

@@ -54,7 +54,6 @@ struct RegABI32 : public GenericSyscallABI32
namespace guest_abi
{
using namespace pseudo_inst;
// This method will be used if the size of argument type of function is
// greater than 4 byte for Riscv 32.
@@ -79,18 +78,18 @@ struct Argument<ABI, Arg,
// This method will be used for RV32 pointers.
template <>
struct Argument<RiscvISA::RegABI32, GuestAddr>
struct Argument<RiscvISA::RegABI32, pseudo_inst::GuestAddr>
{
using ABI = RiscvISA::RegABI32;
using Arg = pseudo_inst::GuestAddr;
static GuestAddr
static Arg
get(ThreadContext *tc, typename ABI::State &state)
{
panic_if(state >= ABI::ArgumentRegs.size(),
"Ran out of syscall argument registers.");
auto arg = bits(tc->getReg(ABI::ArgumentRegs[state++]), 31, 0);
return *reinterpret_cast<GuestAddr*>(&arg);
return (Arg)bits(tc->getReg(ABI::ArgumentRegs[state++]), 31, 0);
}
};

View File

@@ -44,8 +44,6 @@ struct SparcPseudoInstABI
namespace guest_abi
{
using namespace pseudo_inst;
template <typename T>
struct Result<SparcPseudoInstABI, T>
{
@@ -71,14 +69,15 @@ struct Argument<SparcPseudoInstABI, uint64_t>
};
template <>
struct Argument<SparcPseudoInstABI, GuestAddr>
struct Argument<SparcPseudoInstABI, pseudo_inst::GuestAddr>
{
static GuestAddr
using Arg = pseudo_inst::GuestAddr;
static Arg
get(ThreadContext *tc, SparcPseudoInstABI::State &state)
{
panic_if(state >= 6, "Too many psuedo inst arguments.");
auto arg = tc->getReg(SparcISA::int_reg::o(state++));
return *reinterpret_cast<GuestAddr*>(&arg);
return (Arg)tc->getReg(SparcISA::int_reg::o(state++));
}
};

View File

@@ -50,8 +50,6 @@ struct X86PseudoInstABI
namespace guest_abi
{
using namespace pseudo_inst;
template <typename T>
struct Result<X86PseudoInstABI, T>
{
@@ -88,9 +86,11 @@ struct Argument<X86PseudoInstABI, uint64_t>
};
template <>
struct Argument<X86PseudoInstABI, GuestAddr>
struct Argument<X86PseudoInstABI, pseudo_inst::GuestAddr>
{
static GuestAddr
using Arg = pseudo_inst::GuestAddr;
static Arg
get(ThreadContext *tc, X86PseudoInstABI::State &state)
{
// The first 6 integer arguments are passed in registers, the rest
@@ -105,8 +105,7 @@ struct Argument<X86PseudoInstABI, GuestAddr>
int_reg::Rcx, int_reg::R8, int_reg::R9
};
auto arg = tc->getReg(int_reg_map[state++]);
return *reinterpret_cast<GuestAddr*>(&arg);
return (Arg)tc->getReg(int_reg_map[state++]);
}
};

View File

@@ -169,8 +169,7 @@ template <typename ABI, typename Arg>
static Arg
getArgument(ThreadContext *tc, typename ABI::State &state)
{
auto arg = Argument<ABI, Arg>::get(tc, state);
return *reinterpret_cast<Arg*>(&arg);
return (Arg)Argument<ABI, Arg>::get(tc, state);
}
} // namespace guest_abi

View File

@@ -64,9 +64,17 @@ decodeAddrOffset(Addr offset, uint8_t &func)
func = bits(offset, 15, 8);
}
/**
* This struct wrapper for Addr enables m5ops for systems with 32 bit pointer,
* since it allows to distinguish between address arguments and native C++
* types. GuestAddr is only a temporary solution and will likely replaced in
* the future.
*/
struct GuestAddr
{
uint64_t addr;
Addr addr;
/** Constructor is necessary to cast from uint64_t to GuestAddr. */
GuestAddr(Addr _addr) : addr(_addr) {}
};
inline std::ostream&

View File

@@ -79,22 +79,20 @@ struct GenericSyscallABI32 : public GenericSyscallABI
namespace guest_abi
{
using namespace pseudo_inst;
// For 64 bit systems, return syscall args directly.
template <typename ABI, typename Arg>
struct Argument<ABI, Arg,
typename std::enable_if_t<
std::is_base_of_v<GenericSyscallABI64, ABI> &&
(std::is_integral_v<Arg> || std::is_same<Arg,GuestAddr>::value)>>
(std::is_integral_v<Arg> ||
std::is_same<Arg,pseudo_inst::GuestAddr>::value)>>
{
static Arg
get(ThreadContext *tc, typename ABI::State &state)
{
panic_if(state >= ABI::ArgumentRegs.size(),
"Ran out of syscall argument registers.");
auto arg = tc->getReg(ABI::ArgumentRegs[state++]);
return *reinterpret_cast<Arg*>(&arg);
return (Arg)tc->getReg(ABI::ArgumentRegs[state++]);
}
};