HLE: SVR4 VAList struct added
This commit is contained in:
parent
5a4f085c10
commit
061dadbc61
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
#include "Core/HLE/HLE_VarArgs.h"
|
#include "Core/HLE/HLE_VarArgs.h"
|
||||||
|
|
||||||
|
#include "Common/Logging/Log.h"
|
||||||
|
|
||||||
HLE::SystemVABI::VAList::~VAList() = default;
|
HLE::SystemVABI::VAList::~VAList() = default;
|
||||||
|
|
||||||
u32 HLE::SystemVABI::VAList::GetGPR(u32 gpr) const
|
u32 HLE::SystemVABI::VAList::GetGPR(u32 gpr) const
|
||||||
|
@ -15,3 +17,51 @@ double HLE::SystemVABI::VAList::GetFPR(u32 fpr) const
|
||||||
{
|
{
|
||||||
return rPS0(fpr);
|
return rPS0(fpr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HLE::SystemVABI::VAListStruct::VAListStruct(u32 address)
|
||||||
|
: VAList(0), m_va_list{PowerPC::HostRead_U8(address), PowerPC::HostRead_U8(address + 1),
|
||||||
|
PowerPC::HostRead_U32(address + 4), PowerPC::HostRead_U32(address + 8)},
|
||||||
|
m_address(address), m_has_fpr_area(GetCRBit(6) == 1)
|
||||||
|
{
|
||||||
|
m_stack = m_va_list.overflow_arg_area;
|
||||||
|
m_gpr += m_va_list.gpr;
|
||||||
|
m_fpr += m_va_list.fpr;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 HLE::SystemVABI::VAListStruct::GetGPRArea() const
|
||||||
|
{
|
||||||
|
return m_va_list.reg_save_area;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 HLE::SystemVABI::VAListStruct::GetFPRArea() const
|
||||||
|
{
|
||||||
|
return GetGPRArea() + 4 * 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 HLE::SystemVABI::VAListStruct::GetGPR(u32 gpr) const
|
||||||
|
{
|
||||||
|
if (gpr < 3 || gpr > 10)
|
||||||
|
{
|
||||||
|
ERROR_LOG(OSHLE, "VAListStruct at %08x doesn't have GPR%d!", m_address, gpr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
const u32 gpr_address = Common::AlignUp(GetGPRArea() + 4 * (gpr - 3), 4);
|
||||||
|
return PowerPC::HostRead_U32(gpr_address);
|
||||||
|
}
|
||||||
|
|
||||||
|
double HLE::SystemVABI::VAListStruct::GetFPR(u32 fpr) const
|
||||||
|
{
|
||||||
|
double value = 0.0;
|
||||||
|
|
||||||
|
if (!m_has_fpr_area || fpr < 1 || fpr > 8)
|
||||||
|
{
|
||||||
|
ERROR_LOG(OSHLE, "VAListStruct at %08x doesn't have FPR%d!", m_address, fpr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const u32 fpr_address = Common::AlignUp(GetFPRArea() + 8 * (fpr - 1), 8);
|
||||||
|
const u64 integral = PowerPC::HostRead_U64(fpr_address);
|
||||||
|
std::memcpy(&value, &integral, sizeof(double));
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
|
@ -130,15 +130,48 @@ public:
|
||||||
return static_cast<T>(GetArg<T>());
|
return static_cast<T>(GetArg<T>());
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
u32 m_gpr = 3;
|
u32 m_gpr = 3;
|
||||||
u32 m_fpr = 1;
|
u32 m_fpr = 1;
|
||||||
const u32 m_gpr_max = 10;
|
const u32 m_gpr_max = 10;
|
||||||
const u32 m_fpr_max = 8;
|
const u32 m_fpr_max = 8;
|
||||||
u32 m_stack;
|
u32 m_stack;
|
||||||
|
|
||||||
|
private:
|
||||||
virtual u32 GetGPR(u32 gpr) const;
|
virtual u32 GetGPR(u32 gpr) const;
|
||||||
virtual double GetFPR(u32 fpr) const;
|
virtual double GetFPR(u32 fpr) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// See System V ABI (SVR4) for more details
|
||||||
|
// -> 6-6 Required Routines
|
||||||
|
// -> 3-21 Variable Argument Lists
|
||||||
|
//
|
||||||
|
// Source:
|
||||||
|
// http://refspecs.linux-foundation.org/elf/elfspec_ppc.pdf
|
||||||
|
class VAListStruct : public VAList
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit VAListStruct(u32 address);
|
||||||
|
~VAListStruct() = default;
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct svr4_va_list
|
||||||
|
{
|
||||||
|
u8 gpr;
|
||||||
|
u8 fpr;
|
||||||
|
u32 overflow_arg_area;
|
||||||
|
u32 reg_save_area;
|
||||||
|
};
|
||||||
|
const svr4_va_list m_va_list;
|
||||||
|
const u32 m_address;
|
||||||
|
const bool m_has_fpr_area;
|
||||||
|
|
||||||
|
u32 GetGPRArea() const;
|
||||||
|
u32 GetFPRArea() const;
|
||||||
|
|
||||||
|
u32 GetGPR(u32 gpr) const override;
|
||||||
|
double GetFPR(u32 fpr) const override;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace SystemVABI
|
} // namespace SystemVABI
|
||||||
} // namespace HLE
|
} // namespace HLE
|
||||||
|
|
Loading…
Reference in New Issue