template <typename Integer>
struct Result<Aapcs32, Integer, typename std::enable_if<
- std::is_integral<Integer>::value>::type>
+ std::is_integral<Integer>::value && (sizeof(Integer) < sizeof(uint32_t))
+ >::type>
{
static void
store(ThreadContext *tc, const Integer &i)
{
- if (sizeof(Integer) < sizeof(uint32_t)) {
- uint32_t val = std::is_signed<Integer>::value ?
- sext<sizeof(Integer) * 8>(i) : i;
- tc->setIntReg(ArmISA::INTREG_R0, val);
- } else if (sizeof(Integer) == sizeof(uint32_t) ||
- std::is_same<Integer, Addr>::value) {
+ uint32_t val = std::is_signed<Integer>::value ?
+ sext<sizeof(Integer) * 8>(i) : i;
+ tc->setIntReg(ArmISA::INTREG_R0, val);
+ }
+};
+
+template <typename Integer>
+struct Result<Aapcs32, Integer, typename std::enable_if<
+ std::is_integral<Integer>::value && (sizeof(Integer) == sizeof(uint32_t))
+ >::type>
+{
+ static void
+ store(ThreadContext *tc, const Integer &i)
+ {
+ tc->setIntReg(ArmISA::INTREG_R0, (uint32_t)i);
+ }
+};
+
+template <typename Integer>
+struct Result<Aapcs32, Integer, typename std::enable_if<
+ std::is_integral<Integer>::value && (sizeof(Integer) == sizeof(uint64_t))
+ >::type>
+{
+ static void
+ store(ThreadContext *tc, const Integer &i)
+ {
+ if (std::is_same<Integer, Addr>::value) {
tc->setIntReg(ArmISA::INTREG_R0, (uint32_t)i);
- } else if (sizeof(Integer) == sizeof(uint64_t)) {
- if (ArmISA::byteOrder(tc) == LittleEndianByteOrder) {
- tc->setIntReg(ArmISA::INTREG_R0, (uint32_t)(i >> 0));
- tc->setIntReg(ArmISA::INTREG_R1, (uint32_t)(i >> 32));
- } else {
- tc->setIntReg(ArmISA::INTREG_R0, (uint32_t)(i >> 32));
- tc->setIntReg(ArmISA::INTREG_R1, (uint32_t)(i >> 0));
- }
+ } else if (ArmISA::byteOrder(tc) == LittleEndianByteOrder) {
+ tc->setIntReg(ArmISA::INTREG_R0, (uint32_t)(i >> 0));
+ tc->setIntReg(ArmISA::INTREG_R1, (uint32_t)(i >> 32));
+ } else {
+ tc->setIntReg(ArmISA::INTREG_R0, (uint32_t)(i >> 32));
+ tc->setIntReg(ArmISA::INTREG_R1, (uint32_t)(i >> 0));
}
}
};
template <typename Integer>
struct Argument<Aapcs32, Integer, typename std::enable_if<
- std::is_integral<Integer>::value>::type> : public Aapcs32ArgumentBase
+ std::is_integral<Integer>::value && (sizeof(Integer) <= sizeof(uint32_t))
+ >::type> : public Aapcs32ArgumentBase
+{
+ static Integer
+ get(ThreadContext *tc, Aapcs32::State &state)
+ {
+ if (state.ncrn <= state.MAX_CRN) {
+ return tc->readIntReg(state.ncrn++);
+ }
+
+ // Max out the ncrn since we effectively exhausted it.
+ state.ncrn = state.MAX_CRN + 1;
+
+ return loadFromStack<Integer>(tc, state);
+ }
+};
+
+template <typename Integer>
+struct Argument<Aapcs32, Integer, typename std::enable_if<
+ std::is_integral<Integer>::value && (sizeof(Integer) > sizeof(uint32_t))
+ >::type> : public Aapcs32ArgumentBase
{
static Integer
get(ThreadContext *tc, Aapcs32::State &state)
{
- if ((sizeof(Integer) <= sizeof(uint32_t) ||
- std::is_same<Integer, Addr>::value) &&
+ if (std::is_same<Integer, Addr>::value &&
state.ncrn <= state.MAX_CRN) {
return tc->readIntReg(state.ncrn++);
}
// This will pick up Addr as well, which should be used for guest pointers.
template <typename Integer>
struct Argument<Aapcs64, Integer, typename std::enable_if<
- std::is_integral<Integer>::value>::type> : public Aapcs64ArgumentBase
+ std::is_integral<Integer>::value && (sizeof(Integer) <= 8)
+ >::type> : public Aapcs64ArgumentBase
{
static Integer
get(ThreadContext *tc, Aapcs64::State &state)
{
- if (sizeof(Integer) <= 8 && state.ngrn <= state.MAX_GRN)
+ if (state.ngrn <= state.MAX_GRN)
return tc->readIntReg(state.ngrn++);
+ // Max out ngrn since we've effectively saturated it.
+ state.ngrn = state.MAX_GRN + 1;
+
+ return loadFromStack<Integer>(tc, state);
+ }
+};
+
+template <typename Integer>
+struct Argument<Aapcs64, Integer, typename std::enable_if<
+ std::is_integral<Integer>::value && (sizeof(Integer) > 8)
+ >::type> : public Aapcs64ArgumentBase
+{
+ static Integer
+ get(ThreadContext *tc, Aapcs64::State &state)
+ {
if (alignof(Integer) == 16 && (state.ngrn % 2))
state.ngrn++;
template <typename Integer>
struct Result<Aapcs64, Integer, typename std::enable_if<
- std::is_integral<Integer>::value>::type>
+ std::is_integral<Integer>::value && (sizeof(Integer) <= 8)
+ >::type>
{
static void
store(ThreadContext *tc, const Integer &i)
{
- if (sizeof(Integer) <= 8) {
- tc->setIntReg(0, i);
- } else {
- tc->setIntReg(0, (uint64_t)i);
- tc->setIntReg(1, (uint64_t)(i >> 64));
- }
+ tc->setIntReg(0, i);
+ }
+};
+
+template <typename Integer>
+struct Result<Aapcs64, Integer, typename std::enable_if<
+ std::is_integral<Integer>::value && (sizeof(Integer) > 8)
+ >::type>
+{
+ static void
+ store(ThreadContext *tc, const Integer &i)
+ {
+ tc->setIntReg(0, (uint64_t)i);
+ tc->setIntReg(1, (uint64_t)(i >> 64));
}
};