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:
Dean authored and GitHub committed 2026-11-02 23:26:58 +13:00
commit da0f097c78
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