mpw/toolbox/stackframe.h

81 lines
1.9 KiB
C
Raw Normal View History

2013-02-15 05:00:15 +00:00
#ifndef __StackFrame_h__
#define __StackFrame_h__
#include <cstdint>
2014-11-21 14:50:56 +00:00
#include <utility>
2013-02-15 05:00:15 +00:00
//
template<unsigned N>
void ToolReturn(uint32_t sp, uint32_t value)
{
if (sp == -1) sp = cpuGetAReg(7);
2013-02-15 05:00:15 +00:00
static_assert(N == 2 || N == 4, "Invalid Return Size");
if (N == 4)
{
memoryWriteLong(value, sp);
}
if (N == 2)
{
memoryWriteWord(value, sp);
}
}
// pre-define these templates to prevent instantiation errors.
template<int Bytes, int Offset, typename... Args>
2014-11-21 14:50:56 +00:00
uint32_t StackFrame__(uint32_t sp, uint32_t &x, Args&&... args);
template<int Bytes, int Offset, typename... Args>
2014-11-21 14:50:56 +00:00
uint32_t StackFrame__(uint32_t sp, uint16_t &x, Args&&... args);
2015-01-05 18:11:50 +00:00
template<int Bytes, int Offset, typename... Args>
uint32_t StackFrame__(uint32_t sp, uint8_t &x, Args&&... args);
template<int Bytes, int Offset>
uint32_t StackFrame__(uint32_t sp);
2013-02-15 05:00:15 +00:00
template<int Bytes, int Offset>
uint32_t StackFrame__(uint32_t sp)
{
static_assert(Offset == 0, "Invalid Stack Size");
cpuSetAReg(7, sp + Bytes);
return sp + Bytes;
}
template<int Bytes, int Offset, typename... Args>
2014-11-21 14:50:56 +00:00
uint32_t StackFrame__(uint32_t sp, uint32_t &x, Args&&... args)
2013-02-15 05:00:15 +00:00
{
x = memoryReadLong(sp + Offset - 4);
2014-11-21 14:50:56 +00:00
return StackFrame__<Bytes, Offset - 4>(sp, std::forward<Args>(args)...);
2013-02-15 05:00:15 +00:00
}
template<int Bytes, int Offset, typename... Args>
2014-11-21 14:50:56 +00:00
uint32_t StackFrame__(uint32_t sp, uint16_t &x, Args&&... args)
2013-02-15 05:00:15 +00:00
{
x = memoryReadWord(sp + Offset - 2);
2014-11-21 14:50:56 +00:00
return StackFrame__<Bytes, Offset - 2>(sp, std::forward<Args>(args)...);
2013-02-15 05:00:15 +00:00
}
2015-01-05 18:11:50 +00:00
template<int Bytes, int Offset, typename... Args>
uint32_t StackFrame__(uint32_t sp, uint8_t &x, Args&&... args)
{
// byte pushes as 2 bytes with 1 garbage byte
x = memoryReadByte(sp + Offset - 2);
return StackFrame__<Bytes, Offset - 2>(sp, std::forward<Args>(args)...);
}
2013-02-15 05:00:15 +00:00
template<int Bytes, typename... Args>
2014-11-21 14:50:56 +00:00
uint32_t StackFrame(Args&&... args)
2013-02-15 05:00:15 +00:00
{
uint32_t sp = cpuGetAReg(7);
2014-11-21 14:50:56 +00:00
return StackFrame__<Bytes, Bytes>(sp, std::forward<Args>(args)...);
2013-02-15 05:00:15 +00:00
}
#endif