printf implementation

This commit is contained in:
georgemoralis 2023-10-06 14:19:09 +03:00
parent cefd3d95ed
commit 551455e56e
6 changed files with 72 additions and 11 deletions

View file

@ -0,0 +1,9 @@
#include "libc.h"
namespace Emulator::HLE::Libraries::LibC {
PS4_SYSV_ABI int printf(VA_ARGS) {
VA_CTX(ctx);
return printf_ctx(&ctx);
}
}; // namespace Emulator::HLE::Libraries::LibC

View file

@ -0,0 +1,10 @@
#pragma once
#include <types.h>
#include "printf.h"
namespace Emulator::HLE::Libraries::LibC {
//HLE functions
PS4_SYSV_ABI int printf(VA_ARGS);
}

View file

@ -56,6 +56,7 @@
#include <cstdint>
#include "va_ctx.h"
#include <stdio.h>
namespace Emulator::HLE::Libraries::LibC {
// ntoa conversion buffer size, this must be big enough to hold
@ -671,6 +672,14 @@ static inline int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen
return (int)idx;
}
static int printf_ctx(VaCtx* ctx) {
const char* format = vaArgPtr<const char>(&ctx->va_list);
char buffer[256];
int result= _vsnprintf(_out_buffer, buffer, (size_t)-1, format, &ctx->va_list);
puts(buffer);
return result;
}
#if 0
///////////////////////////////////////////////////////

View file

@ -1,4 +1,30 @@
#include <types.h>
#include <xmmintrin.h>
#define VA_ARGS \
uint64_t rdi, uint64_t rsi, uint64_t rdx, uint64_t rcx, uint64_t r8, uint64_t r9, uint64_t overflow_arg_area, __m128 xmm0, __m128 xmm1, \
__m128 xmm2, __m128 xmm3, __m128 xmm4, __m128 xmm5, __m128 xmm6, __m128 xmm7, ...
#define VA_CTX(ctx) \
alignas(16) VaCtx ctx; \
(ctx).reg_save_area.gp[0] = rdi; \
(ctx).reg_save_area.gp[1] = rsi; \
(ctx).reg_save_area.gp[2] = rdx; \
(ctx).reg_save_area.gp[3] = rcx; \
(ctx).reg_save_area.gp[4] = r8; \
(ctx).reg_save_area.gp[5] = r9; \
(ctx).reg_save_area.fp[0] = xmm0; \
(ctx).reg_save_area.fp[1] = xmm1; \
(ctx).reg_save_area.fp[2] = xmm2; \
(ctx).reg_save_area.fp[3] = xmm3; \
(ctx).reg_save_area.fp[4] = xmm4; \
(ctx).reg_save_area.fp[5] = xmm5; \
(ctx).reg_save_area.fp[6] = xmm6; \
(ctx).reg_save_area.fp[7] = xmm7; \
(ctx).va_list.reg_save_area = &(ctx).reg_save_area; \
(ctx).va_list.gp_offset = offsetof(VaRegSave, gp); \
(ctx).va_list.fp_offset = offsetof(VaRegSave, fp); \
(ctx).va_list.overflow_arg_area = &overflow_arg_area;
namespace Emulator::HLE::Libraries::LibC {
@ -11,15 +37,25 @@ struct VaList {
void* reg_save_area;
};
struct VaRegSave {
u64 gp[6];
__m128 fp[8];
};
struct VaCtx {
VaRegSave reg_save_area;
VaList va_list;
};
template <class T, uint32_t Size>
T vaArgRegSaveAreaGp(VaList* l) {
auto* addr = reinterpret_cast<T*>(static_cast<uint8_t*>(l->reg_save_area) + l->gp_offset);
auto* addr = reinterpret_cast<T*>(static_cast<u08*>(l->reg_save_area) + l->gp_offset);
l->gp_offset += Size;
return *addr;
}
template <class T, uint64_t Align, uint64_t Size>
template <class T, u64 Align, u64 Size>
T vaArgOverflowArgArea(VaList* l) {
auto ptr = ((reinterpret_cast<uint64_t>(l->overflow_arg_area) + (Align - 1)) & ~(Align - 1));
auto ptr = ((reinterpret_cast<u64>(l->overflow_arg_area) + (Align - 1)) & ~(Align - 1));
auto* addr = reinterpret_cast<T*>(ptr);
l->overflow_arg_area = reinterpret_cast<void*>(ptr + Size);
return *addr;
@ -27,7 +63,7 @@ T vaArgOverflowArgArea(VaList* l) {
template <class T, uint32_t Size>
T vaArgRegSaveAreaFp(VaList* l) {
auto* addr = reinterpret_cast<T*>(static_cast<uint8_t*>(l->reg_save_area) + l->fp_offset);
auto* addr = reinterpret_cast<T*>(static_cast<u08*>(l->reg_save_area) + l->fp_offset);
l->fp_offset += Size;
return *addr;
}