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:
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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++));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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++]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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&
|
||||
|
||||
@@ -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++]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user