mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-11-07 13:39:55 +00:00
Merge pull request #11107 from AdnanKhan-ak47/feat/relinker-lower-bzhi-bextr
feat(relinker): lower BZHI and BEXTR under --to-rosetta
This commit is contained in:
13 files changed
+861
-10
No files matched your search
@@ -0,0 +1,29 @@
|
||||
#ifndef CODEGEN_X86_BITFIELDLOWERING_HPP
|
||||
#define CODEGEN_X86_BITFIELDLOWERING_HPP
|
||||
|
||||
#include <codegen/x86/StubBodyBuilder.hpp>
|
||||
#include <optional>
|
||||
|
||||
namespace Codegen {
|
||||
|
||||
enum class BitfieldOperation : std::uint8_t {
|
||||
ZeroHigh,
|
||||
Extract,
|
||||
};
|
||||
|
||||
struct BitfieldOperands {
|
||||
BitfieldOperation Operation;
|
||||
std::uint8_t Destination;
|
||||
std::uint8_t Source;
|
||||
std::uint8_t Control;
|
||||
bool Wide;
|
||||
std::optional<MemoryOperand> Memory;
|
||||
};
|
||||
|
||||
[[nodiscard]] const char* BitfieldName(BitfieldOperation operation);
|
||||
[[nodiscard]] std::optional<BitfieldOperands> DecodeBitfield(const std::uint8_t* data, std::size_t length);
|
||||
void EmitBitfield(StubBodyBuilder& body, const BitfieldOperands& operands);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -50,7 +50,10 @@ inline void StackSlot(StubBodyBuilder& body, std::uint8_t opcode, bool wide, std
|
||||
inline std::array<bool, 16> UsedRegisters(std::initializer_list<std::uint8_t> registers, const std::optional<MemoryOperand>& memory) {
|
||||
std::array<bool, 16> used{};
|
||||
used[Stack] = true;
|
||||
for (const auto reg : registers) used[reg] = true;
|
||||
for (const auto reg : registers) {
|
||||
if (reg >= used.size()) throw CodegenException("register index " + std::to_string(reg) + " is out of range");
|
||||
used[reg] = true;
|
||||
}
|
||||
if (!memory) return used;
|
||||
if (memory->Rm == 4) {
|
||||
const auto base = static_cast<std::uint8_t>((memory->Sib & 7) | ((memory->RexIndexBase & 1) << 3));
|
||||
@@ -72,9 +75,9 @@ inline std::uint8_t Scratch(std::array<bool, 16>& used, const char* instruction)
|
||||
throw CodegenException(std::string(instruction) + " has no scratch register");
|
||||
}
|
||||
|
||||
inline void Memory(StubBodyBuilder& body, std::uint8_t opcode, bool wide, const MemoryOperand& memory, std::uint8_t reg, const char* instruction) {
|
||||
inline void Memory(StubBodyBuilder& body, std::uint8_t opcode, bool wide, const MemoryOperand& memory, std::uint8_t reg, const char* instruction, std::int32_t frame = FrameSize) {
|
||||
auto displacement = static_cast<std::int64_t>(memory.Displacement);
|
||||
if (memory.StackBase) displacement += FrameSize;
|
||||
if (memory.StackBase) displacement += frame;
|
||||
const bool address32 = std::find(memory.Prefixes.begin(), memory.Prefixes.end(), 0x67) != memory.Prefixes.end();
|
||||
if (!address32 && displacement > std::numeric_limits<std::int32_t>::max())
|
||||
throw CodegenException(std::string(instruction) + " stack displacement does not fit after spilling");
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
#ifndef CODEGEN_X86_SHIFTLOWERING_HPP
|
||||
#define CODEGEN_X86_SHIFTLOWERING_HPP
|
||||
|
||||
#include <codegen/x86/StubBodyBuilder.hpp>
|
||||
#include <optional>
|
||||
|
||||
namespace Codegen {
|
||||
|
||||
enum class ShiftOperation : std::uint8_t {
|
||||
Left,
|
||||
LogicalRight,
|
||||
ArithmeticRight,
|
||||
RotateRight,
|
||||
};
|
||||
|
||||
struct ShiftOperands {
|
||||
ShiftOperation Operation;
|
||||
std::uint8_t Destination;
|
||||
std::uint8_t Source;
|
||||
std::uint8_t Count;
|
||||
bool Wide;
|
||||
std::optional<MemoryOperand> Memory;
|
||||
};
|
||||
|
||||
[[nodiscard]] const char* ShiftName(ShiftOperation operation);
|
||||
[[nodiscard]] std::optional<ShiftOperands> DecodeShift(const std::uint8_t* data, std::size_t length);
|
||||
void EmitShift(StubBodyBuilder& body, const ShiftOperands& operands);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in new issue
Block a user