minor perf improvements

This commit is contained in:
irisz64
2025-07-22 16:40:40 +02:00
parent 46aba5eb99
commit a3b4e2f374
3 changed files with 82 additions and 95 deletions

View File

@@ -35,48 +35,48 @@ void Registers::SetPC32(s32 val) {
} }
template <> template <>
u64 Registers::Read<u64>(size_t idx) { __attribute__((always_inline)) u64 Registers::Read<u64>(size_t idx) {
return idx == 0 ? 0 : gpr[idx]; return gpr[idx];
} }
template <> template <>
s64 Registers::Read<s64>(const size_t idx) { __attribute__((always_inline)) s64 Registers::Read<s64>(const size_t idx) {
return static_cast<s64>(Read<u64>(idx)); return static_cast<s64>(Read<u64>(idx));
} }
template <> template <>
u32 Registers::Read<u32>(size_t idx) { __attribute__((always_inline)) u32 Registers::Read<u32>(size_t idx) {
return idx == 0 ? 0 : gpr[idx]; return gpr[idx];
} }
template <> template <>
s32 Registers::Read<s32>(size_t idx) { __attribute__((always_inline)) s32 Registers::Read<s32>(size_t idx) {
return static_cast<s32>(Read<u32>(idx)); return static_cast<s32>(Read<u32>(idx));
} }
template <> template <>
u16 Registers::Read<u16>(size_t idx) { __attribute__((always_inline)) u16 Registers::Read<u16>(size_t idx) {
return idx == 0 ? 0 : gpr[idx]; return gpr[idx];
} }
template <> template <>
s16 Registers::Read<s16>(size_t idx) { __attribute__((always_inline)) s16 Registers::Read<s16>(size_t idx) {
return static_cast<s16>(Read<u16>(idx)); return static_cast<s16>(Read<u16>(idx));
} }
template <> template <>
u8 Registers::Read<u8>(size_t idx) { __attribute__((always_inline)) u8 Registers::Read<u8>(size_t idx) {
return idx == 0 ? 0 : gpr[idx]; return gpr[idx];
} }
template <> template <>
s8 Registers::Read<s8>(size_t idx) { __attribute__((always_inline)) s8 Registers::Read<s8>(size_t idx) {
return static_cast<s8>(Read<u8>(idx)); return static_cast<s8>(Read<u8>(idx));
} }
#ifndef __aarch64__ #ifndef __aarch64__
template <> template <>
void Registers::Read<u64>(size_t idx, Xbyak::Reg reg) { __attribute__((always_inline)) void Registers::Read<u64>(size_t idx, Xbyak::Reg reg) {
if(IsRegConstant(idx)) { if(IsRegConstant(idx)) {
jit->code.mov(reg.cvt64(), Read<u64>(idx)); jit->code.mov(reg.cvt64(), Read<u64>(idx));
return; return;
@@ -86,7 +86,7 @@ void Registers::Read<u64>(size_t idx, Xbyak::Reg reg) {
} }
template <> template <>
void Registers::Read<s64>(size_t idx, Xbyak::Reg reg) { __attribute__((always_inline)) void Registers::Read<s64>(size_t idx, Xbyak::Reg reg) {
if(IsRegConstant(idx)) { if(IsRegConstant(idx)) {
jit->code.mov(reg.cvt64(), Read<s64>(idx)); jit->code.mov(reg.cvt64(), Read<s64>(idx));
return; return;
@@ -96,7 +96,7 @@ void Registers::Read<s64>(size_t idx, Xbyak::Reg reg) {
} }
template <> template <>
void Registers::Read<u32>(size_t idx, Xbyak::Reg reg) { __attribute__((always_inline)) void Registers::Read<u32>(size_t idx, Xbyak::Reg reg) {
if(IsRegConstant(idx)) { if(IsRegConstant(idx)) {
jit->code.mov(reg.cvt32(), Read<u32>(idx)); jit->code.mov(reg.cvt32(), Read<u32>(idx));
return; return;
@@ -106,7 +106,7 @@ void Registers::Read<u32>(size_t idx, Xbyak::Reg reg) {
} }
template <> template <>
void Registers::Read<s32>(size_t idx, Xbyak::Reg reg) { __attribute__((always_inline)) void Registers::Read<s32>(size_t idx, Xbyak::Reg reg) {
if(IsRegConstant(idx)) { if(IsRegConstant(idx)) {
jit->code.mov(reg.cvt32(), Read<s32>(idx)); jit->code.mov(reg.cvt32(), Read<s32>(idx));
return; return;
@@ -116,7 +116,7 @@ void Registers::Read<s32>(size_t idx, Xbyak::Reg reg) {
} }
template <> template <>
void Registers::Read<u16>(size_t idx, Xbyak::Reg reg) { __attribute__((always_inline)) void Registers::Read<u16>(size_t idx, Xbyak::Reg reg) {
if(IsRegConstant(idx)) { if(IsRegConstant(idx)) {
jit->code.mov(reg.cvt16(), Read<u16>(idx)); jit->code.mov(reg.cvt16(), Read<u16>(idx));
return; return;
@@ -126,7 +126,7 @@ void Registers::Read<u16>(size_t idx, Xbyak::Reg reg) {
} }
template <> template <>
void Registers::Read<s16>(size_t idx, Xbyak::Reg reg) { __attribute__((always_inline)) void Registers::Read<s16>(size_t idx, Xbyak::Reg reg) {
if(IsRegConstant(idx)) { if(IsRegConstant(idx)) {
jit->code.mov(reg.cvt16(), Read<s16>(idx)); jit->code.mov(reg.cvt16(), Read<s16>(idx));
return; return;
@@ -136,7 +136,7 @@ void Registers::Read<s16>(size_t idx, Xbyak::Reg reg) {
} }
template <> template <>
void Registers::Read<u8>(size_t idx, Xbyak::Reg reg) { __attribute__((always_inline)) void Registers::Read<u8>(size_t idx, Xbyak::Reg reg) {
if(IsRegConstant(idx)) { if(IsRegConstant(idx)) {
jit->code.mov(reg.cvt8(), Read<u8>(idx)); jit->code.mov(reg.cvt8(), Read<u8>(idx));
return; return;
@@ -146,7 +146,7 @@ void Registers::Read<u8>(size_t idx, Xbyak::Reg reg) {
} }
template <> template <>
void Registers::Read<s8>(size_t idx, Xbyak::Reg reg) { __attribute__((always_inline)) void Registers::Read<s8>(size_t idx, Xbyak::Reg reg) {
if(IsRegConstant(idx)) { if(IsRegConstant(idx)) {
jit->code.mov(reg.cvt8(), Read<s8>(idx)); jit->code.mov(reg.cvt8(), Read<s8>(idx));
return; return;
@@ -157,199 +157,208 @@ void Registers::Read<s8>(size_t idx, Xbyak::Reg reg) {
#endif #endif
template <> template <>
void Registers::Write<bool>(size_t idx, bool v) { __attribute__((always_inline)) void Registers::Write<bool>(size_t idx, bool v) {
if (idx == 0) if (idx == 0)
return; return;
if (jit) [[unlikely]]
regIsConstant |= (1 << idx);
gpr[idx] = v;
}
template <>
__attribute__((always_inline)) void Registers::Write<u64>(size_t idx, u64 v) {
if (idx == 0)
return;
if (jit) [[unlikely]]
regIsConstant |= (1 << idx); regIsConstant |= (1 << idx);
gpr[idx] = v; gpr[idx] = v;
} }
template <> template <>
void Registers::Write<u64>(size_t idx, u64 v) { __attribute__((always_inline)) void Registers::Write<s64>(size_t idx, s64 v) {
if (idx == 0)
return;
regIsConstant |= (1 << idx);
gpr[idx] = v;
}
template <>
void Registers::Write<s64>(size_t idx, s64 v) {
Write<u64>(idx, v); Write<u64>(idx, v);
} }
template <> template <>
void Registers::Write<u32>(size_t idx, u32 v) { __attribute__((always_inline)) void Registers::Write<u32>(size_t idx, u32 v) {
if (idx == 0) if (idx == 0)
return; return;
if (jit) [[unlikely]]
regIsConstant |= (1 << idx); regIsConstant |= (1 << idx);
gpr[idx] = v; gpr[idx] = v;
} }
template <> template <>
void Registers::Write<s32>(size_t idx, s32 v) { __attribute__((always_inline)) void Registers::Write<s32>(size_t idx, s32 v) {
if (idx == 0) if (idx == 0)
return; return;
if (jit) [[unlikely]]
regIsConstant |= (1 << idx); regIsConstant |= (1 << idx);
gpr[idx] = v; gpr[idx] = v;
} }
template <> template <>
void Registers::Write<u16>(size_t idx, u16 v) { __attribute__((always_inline)) void Registers::Write<u16>(size_t idx, u16 v) {
if (idx == 0) if (idx == 0)
return; return;
if (jit) [[unlikely]]
regIsConstant |= (1 << idx); regIsConstant |= (1 << idx);
gpr[idx] = v; gpr[idx] = v;
} }
template <> template <>
void Registers::Write<s16>(size_t idx, s16 v) { __attribute__((always_inline)) void Registers::Write<s16>(size_t idx, s16 v) {
if (idx == 0) if (idx == 0)
return; return;
if (jit) [[unlikely]]
regIsConstant |= (1 << idx); regIsConstant |= (1 << idx);
gpr[idx] = v; gpr[idx] = v;
} }
template <> template <>
void Registers::Write<u8>(size_t idx, u8 v) { __attribute__((always_inline)) void Registers::Write<u8>(size_t idx, u8 v) {
if (idx == 0) if (idx == 0)
return; return;
if (jit) [[unlikely]]
regIsConstant |= (1 << idx); regIsConstant |= (1 << idx);
gpr[idx] = v; gpr[idx] = v;
} }
template <> template <>
void Registers::Write<s8>(size_t idx, s8 v) { __attribute__((always_inline)) void Registers::Write<s8>(size_t idx, s8 v) {
if (idx == 0) if (idx == 0)
return; return;
if (jit) [[unlikely]]
regIsConstant |= (1 << idx); regIsConstant |= (1 << idx);
gpr[idx] = v; gpr[idx] = v;
} }
#ifndef __aarch64__ #ifndef __aarch64__
template <> template <>
void Registers::Write<bool>(size_t idx, Xbyak::Reg v) { __attribute__((always_inline)) void Registers::Write<bool>(size_t idx, Xbyak::Reg v) {
if (idx == 0) if (idx == 0)
return; return;
regIsConstant &= ~(1 << idx);
if (!jit) if (!jit)
panic("Did you try to call Registers::Write(size_t, *Xbyak::Reg*) from the interpreter?"); panic("Did you try to call Registers::Write(size_t, *Xbyak::Reg*) from the interpreter?");
regIsConstant &= ~(1 << idx);
jit->code.movsx(v.cvt64(), v.cvt8()); jit->code.movsx(v.cvt64(), v.cvt8());
jit->code.mov(jit->GPR<u64>(idx), v); jit->code.mov(jit->GPR<u64>(idx), v);
} }
template <> template <>
void Registers::Write<s8>(size_t idx, Xbyak::Reg v) { __attribute__((always_inline)) void Registers::Write<s8>(size_t idx, Xbyak::Reg v) {
if (idx == 0) if (idx == 0)
return; return;
regIsConstant &= ~(1 << idx);
if (!jit) if (!jit)
panic("Did you try to call Registers::Write(size_t, *Xbyak::Reg*) from the interpreter?"); panic("Did you try to call Registers::Write(size_t, *Xbyak::Reg*) from the interpreter?");
regIsConstant &= ~(1 << idx);
jit->code.movsx(v.cvt64(), v.cvt8()); jit->code.movsx(v.cvt64(), v.cvt8());
jit->code.mov(jit->GPR<u64>(idx), v); jit->code.mov(jit->GPR<u64>(idx), v);
} }
template <> template <>
void Registers::Write<u8>(size_t idx, Xbyak::Reg v) { __attribute__((always_inline)) void Registers::Write<u8>(size_t idx, Xbyak::Reg v) {
if (idx == 0) if (idx == 0)
return; return;
regIsConstant &= ~(1 << idx);
if (!jit) if (!jit)
panic("Did you try to call Registers::Write(size_t, *Xbyak::Reg*) from the interpreter?"); panic("Did you try to call Registers::Write(size_t, *Xbyak::Reg*) from the interpreter?");
regIsConstant &= ~(1 << idx);
jit->code.movzx(v.cvt64(), v.cvt8()); jit->code.movzx(v.cvt64(), v.cvt8());
jit->code.mov(jit->GPR<u64>(idx), v.cvt64()); jit->code.mov(jit->GPR<u64>(idx), v.cvt64());
} }
template <> template <>
void Registers::Write<s16>(size_t idx, Xbyak::Reg v) { __attribute__((always_inline)) void Registers::Write<s16>(size_t idx, Xbyak::Reg v) {
if (idx == 0) if (idx == 0)
return; return;
regIsConstant &= ~(1 << idx);
if (!jit) if (!jit)
panic("Did you try to call Registers::Write(size_t, *Xbyak::Reg*) from the interpreter?"); panic("Did you try to call Registers::Write(size_t, *Xbyak::Reg*) from the interpreter?");
regIsConstant &= ~(1 << idx);
jit->code.movsx(v.cvt64(), v.cvt16()); jit->code.movsx(v.cvt64(), v.cvt16());
jit->code.mov(jit->GPR<u64>(idx), v.cvt64()); jit->code.mov(jit->GPR<u64>(idx), v.cvt64());
} }
template <> template <>
void Registers::Write<u16>(size_t idx, Xbyak::Reg v) { __attribute__((always_inline)) void Registers::Write<u16>(size_t idx, Xbyak::Reg v) {
if (idx == 0) if (idx == 0)
return; return;
regIsConstant &= ~(1 << idx);
if (!jit) if (!jit)
panic("Did you try to call Registers::Write(size_t, *Xbyak::Reg*) from the interpreter?"); panic("Did you try to call Registers::Write(size_t, *Xbyak::Reg*) from the interpreter?");
regIsConstant &= ~(1 << idx);
jit->code.movzx(v.cvt64(), v.cvt16()); jit->code.movzx(v.cvt64(), v.cvt16());
jit->code.mov(jit->GPR<u64>(idx), v.cvt64()); jit->code.mov(jit->GPR<u64>(idx), v.cvt64());
} }
template <> template <>
void Registers::Write<s32>(size_t idx, Xbyak::Reg v) { __attribute__((always_inline)) void Registers::Write<s32>(size_t idx, Xbyak::Reg v) {
if (idx == 0) if (idx == 0)
return; return;
regIsConstant &= ~(1 << idx);
if (!jit) if (!jit)
panic("Did you try to call Registers::Write(size_t, *Xbyak::Reg*) from the interpreter?"); panic("Did you try to call Registers::Write(size_t, *Xbyak::Reg*) from the interpreter?");
regIsConstant &= ~(1 << idx);
jit->code.movsxd(v.cvt64(), v.cvt32()); jit->code.movsxd(v.cvt64(), v.cvt32());
jit->code.mov(jit->GPR<u64>(idx), v.cvt64()); jit->code.mov(jit->GPR<u64>(idx), v.cvt64());
} }
template <> template <>
void Registers::Write<u32>(size_t idx, Xbyak::Reg v) { __attribute__((always_inline)) void Registers::Write<u32>(size_t idx, Xbyak::Reg v) {
if (idx == 0) if (idx == 0)
return; return;
regIsConstant &= ~(1 << idx);
if (!jit) if (!jit)
panic("Did you try to call Registers::Write(size_t, *Xbyak::Reg*) from the interpreter?"); panic("Did you try to call Registers::Write(size_t, *Xbyak::Reg*) from the interpreter?");
regIsConstant &= ~(1 << idx);
jit->code.movzx(v.cvt64(), v.cvt32()); jit->code.movzx(v.cvt64(), v.cvt32());
jit->code.mov(jit->GPR<u64>(idx), v.cvt64()); jit->code.mov(jit->GPR<u64>(idx), v.cvt64());
} }
template <> template <>
void Registers::Write<u64>(size_t idx, Xbyak::Reg v) { __attribute__((always_inline)) void Registers::Write<u64>(size_t idx, Xbyak::Reg v) {
if (idx == 0) if (idx == 0)
return; return;
regIsConstant &= ~(1 << idx);
if (!jit) if (!jit)
panic("Did you try to call Registers::Write(size_t, *Xbyak::Reg*) from the interpreter?"); panic("Did you try to call Registers::Write(size_t, *Xbyak::Reg*) from the interpreter?");
regIsConstant &= ~(1 << idx);
jit->code.mov(jit->GPR<u64>(idx), v.cvt64()); jit->code.mov(jit->GPR<u64>(idx), v.cvt64());
} }
template <> template <>
void Registers::Write<s64>(size_t idx, Xbyak::Reg v) { __attribute__((always_inline)) void Registers::Write<s64>(size_t idx, Xbyak::Reg v) {
Write<u64>(idx, v); Write<u64>(idx, v);
} }
#endif #endif

View File

@@ -66,13 +66,13 @@ struct Registers {
} }
template <typename T> template <typename T>
T Read(size_t); __attribute__((always_inline)) T Read(size_t);
template <typename T> template <typename T>
void Read(size_t, Xbyak::Reg); __attribute__((always_inline)) void Read(size_t, Xbyak::Reg);
template <typename T> template <typename T>
void Write(size_t, T); __attribute__((always_inline)) void Write(size_t, T);
template <typename T> template <typename T>
void Write(size_t, Xbyak::Reg); __attribute__((always_inline)) void Write(size_t, Xbyak::Reg);
std::array<s64, 32> gpr{}; std::array<s64, 32> gpr{};
}; };

View File

@@ -28,33 +28,11 @@ void print(const std::format_string<Args...> fmt, Args... args) {
} }
} }
#define panic(fmt, ...) do \ #define panic(fmt, ...) do { Util::print<Util::Error>("[FATAL] " fmt, __VA_ARGS__); exit(-1); } while(0)
{ \ #define error(fmt, ...) do { Util::print<Util::Error>("[ERROR] " fmt, __VA_ARGS__); } while(0)
Util::print<Util::Error>("[FATAL] " fmt, __VA_ARGS__); \ #define warn(fmt, ...) do { Util::print<Util::Warn>("[WARN] " fmt, __VA_ARGS__); } while(0)
exit(-1); \ #define info(fmt, ...) do { Util::print<Util::Info>("[INFO] " fmt, __VA_ARGS__); } while(0)
} while(0) #define debug(fmt, ...) do { Util::print<Util::Debug>("[DEBUG] " fmt, __VA_ARGS__); } while(0)
#define error(fmt, ...) do \ #define trace(fmt, ...) do { Util::print<Util::Trace>("[TRACE] " fmt, __VA_ARGS__); } while(0)
{ \ #define always(fmt, ...) do { Util::print<Util::Always>(fmt, __VA_ARGS__); } while(0)
Util::print<Util::Error>("[ERROR] " fmt, __VA_ARGS__); \
} while(0)
#define warn(fmt, ...) do \
{ \
Util::print<Util::Warn>("[WARN] " fmt, __VA_ARGS__); \
} while(0)
#define info(fmt, ...) do \
{ \
Util::print<Util::Info>("[INFO] " fmt, __VA_ARGS__); \
} while(0)
#define debug(fmt, ...) do \
{ \
Util::print<Util::Debug>("[DEBUG] " fmt, __VA_ARGS__); \
} while(0)
#define trace(fmt, ...) do \
{ \
Util::print<Util::Trace>("[TRACE] " fmt, __VA_ARGS__); \
} while(0)
#define always(fmt, ...) do \
{ \
Util::print<Util::Always>(fmt, __VA_ARGS__); \
} while(0)
} // namespace Util } // namespace Util