mirror of
https://github.com/NaC-L/Mergen.git
synced 2026-05-12 09:40:34 +00:00
lifter: accept Register64/Memory64 source for punpcklqdq
Iced classifies operand types by the bytes the instruction actually accesses, not by physical register width. PUNPCKLQDQ only reads the low 64 bits of its second operand, so Iced reports Register64 (or Memory64 for the m128 form) for a source whose physical encoding is `xmm/m128`. The lift handler's accept check rejected anything other than Register128/Memory128 and fell through to the not_implemented exit, so every `punpcklqdq xmm, xmm/m128` site lowered to a bogus `call @not_implemented; ret` instead of the unpack semantic. Widen the accept set to Register64 and Memory64 too. The body already truncates the source to i64 before OR'ing it into the high half of the result, so a 64-bit-typed source is semantically identical to a 128-bit one for this handler. Fixes the two pre-existing oracle test failures `punpcklqdq_xmm0_xmm1_basic` and `punpcklqdq_xmm0_xmm1_zero_upper_from_zero_source`. `python test.py all` stays at 244/244, confirming no semantic regressions.
This commit is contained in:
@@ -210,9 +210,17 @@ MERGEN_LIFTER_DEFINITION_TEMPLATES(void)::lift_punpcklqdq() {
|
||||
LLVMContext& context = builder->getContext();
|
||||
auto destinationType = instruction.types[0];
|
||||
auto sourceType = instruction.types[1];
|
||||
// Iced classifies the source operand by the bytes the instruction actually
|
||||
// accesses, not by the physical register width. PUNPCKLQDQ only reads the
|
||||
// low 64 bits of its second operand, so Iced reports Register64/Memory64
|
||||
// even though the encoding is `xmm/m128`. Accept both shapes -- the
|
||||
// body below truncates to i64 anyway, so a 64-bit-typed source is
|
||||
// semantically identical to a 128-bit one for this handler.
|
||||
bool destinationIsXmm = destinationType == OperandType::Register128;
|
||||
bool sourceIsXmm = sourceType == OperandType::Register128 ||
|
||||
sourceType == OperandType::Memory128;
|
||||
sourceType == OperandType::Register64 ||
|
||||
sourceType == OperandType::Memory128 ||
|
||||
sourceType == OperandType::Memory64;
|
||||
if (!destinationIsXmm || !sourceIsXmm) {
|
||||
Function* externFunc = cast<Function>(
|
||||
fnc->getParent()
|
||||
|
||||
Reference in New Issue
Block a user