Repository: bytecodealliance/wasmtime
Pull request #8976 (2024-07-19 16:27:58)

x64: Fix encoding of adc/sbb with immediate operands
This isn't reachable from Cranelift today but in some various testing this is one of the issues I encountered. This fixes apparent copy/paste bugs with the `Adc` and `Sbb` instructions with immediate operands.

<!--
Please make sure you include the following information:

- If this work has been discussed elsewhere, please include a link to that
  conversation. If it was discussed in an issue, just mention "issue #...".

- Explain why this change is needed. If the details are in an issue already,
  this can be brief.

Our development process is documented in the Wasmtime book:
https://docs.wasmtime.dev/contributing-development-process.html

Please ensure all communication follows the code of conduct:
https://github.com/bytecodealliance/wasmtime/blob/main/CODE_OF_CONDUCT.md
-->



Patch:
diff --git a/cranelift/codegen/src/isa/x64/inst/emit.rs b/cranelift/codegen/src/isa/x64/inst/emit.rs
index 25534059d..5c5ea82c1 100644
--- a/cranelift/codegen/src/isa/x64/inst/emit.rs
+++ b/cranelift/codegen/src/isa/x64/inst/emit.rs
@@ -165,9 +165,9 @@ pub(crate) fn emit(
             let mut rex = RexFlags::from(*size);
             let (opcode_r, opcode_m, subopcode_i) = match op {
                 AluRmiROpcode::Add => (0x01, 0x03, 0),
-                AluRmiROpcode::Adc => (0x11, 0x03, 0),
+                AluRmiROpcode::Adc => (0x11, 0x03, 2),
                 AluRmiROpcode::Sub => (0x29, 0x2B, 5),
-                AluRmiROpcode::Sbb => (0x19, 0x2B, 5),
+                AluRmiROpcode::Sbb => (0x19, 0x2B, 3),
                 AluRmiROpcode::And => (0x21, 0x23, 4),
                 AluRmiROpcode::Or => (0x09, 0x0B, 1),
                 AluRmiROpcode::Xor => (0x31, 0x33, 6),
diff --git a/winch/codegen/src/isa/x64/regs.rs b/winch/codegen/src/isa/x64/regs.rs
index 69e796246..0118f8b97 100644
--- a/winch/codegen/src/isa/x64/regs.rs
+++ b/winch/codegen/src/isa/x64/regs.rs
@@ -99,18 +99,6 @@ pub(crate) fn scratch() -> Reg {
     r11()
 }
 
-/// This register is used as a scratch register, in the context of trampolines only,
-/// where we assume that callee-saved registers are given the correct handling
-/// according to the system ABI. r12 is chosen given that it's a callee-saved,
-/// non-argument register.
-///
-/// In the context of all other internal functions, this register is not excluded
-/// from register allocation, so no extra assumptions should be made regarding
-/// its availability.
-pub(crate) fn argv() -> Reg {
-    r12()
-}
-
 fn fpr(enc: u8) -> Reg {
     Reg::new(PReg::new(enc as usize, RegClass::Float))
 }


Test patch:
diff --git a/cranelift/codegen/src/isa/x64/inst/emit_tests.rs b/cranelift/codegen/src/isa/x64/inst/emit_tests.rs
index 2b53fae95..5dd3dd505 100644
--- a/cranelift/codegen/src/isa/x64/inst/emit_tests.rs
+++ b/cranelift/codegen/src/isa/x64/inst/emit_tests.rs
@@ -1632,6 +1632,36 @@ fn test_x64_emit() {
         "4520FF",
         "andb    %r15b, %r15b, %r15b",
     ));
+    insns.push((
+        Inst::alu_rmi_r(
+            OperandSize::Size32,
+            AluRmiROpcode::Sbb,
+            RegMemImm::reg(r14),
+            w_r15,
+        ),
+        "4519F7",
+        "sbbl    %r15d, %r14d, %r15d",
+    ));
+    insns.push((
+        Inst::alu_rmi_r(
+            OperandSize::Size64,
+            AluRmiROpcode::Sbb,
+            RegMemImm::imm(0),
+            w_r15,
+        ),
+        "4983DF00",
+        "sbbq    %r15, $0, %r15",
+    ));
+    insns.push((
+        Inst::alu_rmi_r(
+            OperandSize::Size64,
+            AluRmiROpcode::Adc,
+            RegMemImm::imm(0),
+            w_r15,
+        ),
+        "4983D700",
+        "adcq    %r15, $0, %r15",
+    ));
 
     // ========================================================
     // AluRM