Fix some i128 shift-related bugs in x64 backend.
This fixes #2672 and #2679, and also fixes an incorrect instruction emission (`test` with small immediate) that we had missed earlier. The shift-related fixes have to do with (i) shifts by 0 bits, as a special case that must be handled; and (ii) shifts by a 128-bit amount, which we can handle by just dropping the upper half (we only use 3--7 bits of shift amount). This adjusts the lowerings appropriately, and also adds run-tests to ensure that the lowerings actually execute correctly (previously we only had compile-tests with golden lowerings; I'd like to correct this for more ops eventually, adding run-tests beyond what the Wasm spec and frontend covers).
This commit is contained in:
@@ -1371,7 +1371,7 @@ pub(crate) fn emit(
|
||||
RegMemImm::Imm { simm32 } => {
|
||||
// FIXME JRS 2020Feb11: there are shorter encodings for
|
||||
// cmp $imm, rax/eax/ax/al.
|
||||
let use_imm8 = low8_will_sign_extend_to_32(*simm32);
|
||||
let use_imm8 = is_cmp && low8_will_sign_extend_to_32(*simm32);
|
||||
|
||||
// And also here we use the "normal" G-E ordering.
|
||||
let opcode = if is_cmp {
|
||||
|
||||
@@ -2999,6 +2999,11 @@ fn test_x64_emit() {
|
||||
"48855763",
|
||||
"testq 99(%rdi), %rdx",
|
||||
));
|
||||
insns.push((
|
||||
Inst::test_rmi_r(OperandSize::Size64, RegMemImm::imm(127), rdx),
|
||||
"48F7C27F000000",
|
||||
"testq $127, %rdx",
|
||||
));
|
||||
insns.push((
|
||||
Inst::test_rmi_r(OperandSize::Size64, RegMemImm::imm(76543210), rdx),
|
||||
"48F7C2EAF48F04",
|
||||
|
||||
Reference in New Issue
Block a user