forked from moonpower/azahar-UWP
shader_jit_a64: Compact host executable memory (#230)
* common/aarch64: Allow generic code generator types Use the templated `BasicCodeGenerator` type rather than the specialized `CodeGenerator` type. Allows `VectorCodeGenerator` to work with these functions. * common/aarch64: Add `VectorCodeGenerator` to `CallFarFunction` `VectorCodeGenerator` will always do far-calls since we cannot resolve any absolute addresses here. * shader_jit_a64: Implement position-independent VectorCodeGenerator Generates more position-independent assembly to allow for code to be generated within a resizable vector before copying into executable memory, allowing for more compact memory allocations and usage rather than a statically defined worst-case for all-cases. `VectorCodeGenerator` will need to generate position-independent code rather than use absolute addresses. Assumes all far function calls in the case of `VectorCodeGenerator` to use absolute addresses rather than potentially use a relative `BL` branch after memory relocation.
This commit is contained in:
@@ -78,7 +78,8 @@ inline ABIFrameInfo ABI_CalculateFrameSize(std::bitset<64> regs, std::size_t fra
|
||||
return ABIFrameInfo{static_cast<u32>(total_size), static_cast<u32>(fprs_base_subtraction)};
|
||||
}
|
||||
|
||||
inline void ABI_PushRegisters(oaknut::CodeGenerator& code, std::bitset<64> regs,
|
||||
template <typename Policy>
|
||||
inline void ABI_PushRegisters(oaknut::BasicCodeGenerator<Policy>& code, std::bitset<64> regs,
|
||||
std::size_t frame_size = 0) {
|
||||
using namespace oaknut;
|
||||
using namespace oaknut::util;
|
||||
@@ -137,7 +138,8 @@ inline void ABI_PushRegisters(oaknut::CodeGenerator& code, std::bitset<64> regs,
|
||||
}
|
||||
}
|
||||
|
||||
inline void ABI_PopRegisters(oaknut::CodeGenerator& code, std::bitset<64> regs,
|
||||
template <typename Policy>
|
||||
inline void ABI_PopRegisters(oaknut::BasicCodeGenerator<Policy>& code, std::bitset<64> regs,
|
||||
std::size_t frame_size = 0) {
|
||||
using namespace oaknut;
|
||||
using namespace oaknut::util;
|
||||
|
||||
@@ -38,6 +38,16 @@ inline void CallFarFunction(oaknut::CodeGenerator& code, const T f) {
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void CallFarFunction(oaknut::VectorCodeGenerator& code, const T f) {
|
||||
static_assert(std::is_pointer_v<T>, "Argument must be a (function) pointer.");
|
||||
// X16(IP0) and X17(IP1) is the standard veneer register
|
||||
// LR is also available as an intermediate register
|
||||
// https://developer.arm.com/documentation/102374/0101/Procedure-Call-Standard
|
||||
code.MOVP2R(oaknut::util::X16, reinterpret_cast<const void*>(f));
|
||||
code.BLR(oaknut::util::X16);
|
||||
}
|
||||
|
||||
} // namespace Common::A64
|
||||
|
||||
#endif // CITRA_ARCH(arm64)
|
||||
|
||||
Reference in New Issue
Block a user