From 2294180c3778d0fcfa877818e98c420fcd54bb8a Mon Sep 17 00:00:00 2001 From: johannst Date: Tue, 5 Dec 2023 22:08:06 +0000 Subject: deploy: 7e98f5def5942969f97f5f015e7fb8417793d132 --- src/juicebox_asm/lib.rs.html | 124 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 121 insertions(+), 3 deletions(-) (limited to 'src/juicebox_asm/lib.rs.html') diff --git a/src/juicebox_asm/lib.rs.html b/src/juicebox_asm/lib.rs.html index 4d6d4fe..83c8f81 100644 --- a/src/juicebox_asm/lib.rs.html +++ b/src/juicebox_asm/lib.rs.html @@ -1,4 +1,4 @@ -lib.rs - source
1
+lib.rs - source
1
 2
 3
 4
@@ -408,6 +408,65 @@
 408
 409
 410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
 
//! A simple `x64` jit assembler with a minimal runtime to execute emitted code for fun.
 //!
 //! The following is an fibonacci example implementation.
@@ -471,8 +530,8 @@
 //!     asm.ret();
 //!
 //!     // Move code into executable page and get function pointer to it.
-//!     let rt = Runtime::new(&asm.into_code());
-//!     let fib = unsafe { rt.as_fn::<extern "C" fn(u64) -> u64>() };
+//!     let mut rt = Runtime::new();
+//!     let fib = unsafe { rt.add_code::<extern "C" fn(u64) -> u64>(&asm.into_code()) };
 //!
 //!     for n in 0..15 {
 //!         let fib_jit = fib(n);
@@ -683,6 +742,42 @@
         self.emit(&[opc, modrm]);
     }
 
+    /// Encode a memory-immediate instruction.
+    fn encode_mi<T: Imm>(&mut self, opc: u8, opc_ext: u8, op1: MemOp, op2: T)
+    where
+        Self: EncodeMI<T>,
+    {
+        // MI operand encoding.
+        //   op1 -> modrm.rm
+        //   op2 -> imm
+        let mode = match op1 {
+            MemOp::Indirect(..) => {
+                assert!(!op1.base().need_sib() && !op1.base().is_pc_rel());
+                0b00
+            }
+            MemOp::IndirectDisp(..) => {
+                assert!(!op1.base().need_sib());
+                0b10
+            }
+        };
+
+        let modrm = modrm(
+            mode,             /* mode */
+            opc_ext,          /* reg */
+            op1.base().idx(), /* rm */
+        );
+
+        let prefix = <Self as EncodeMI<T>>::legacy_prefix();
+        let rex = <Self as EncodeMI<T>>::rex(&op1);
+
+        self.emit_optional(&[prefix, rex]);
+        self.emit(&[opc, modrm]);
+        if let MemOp::IndirectDisp(_, disp) = op1 {
+            self.emit(&disp.to_ne_bytes());
+        }
+        self.emit(op2.bytes());
+    }
+
     /// Encode a memory-register instruction.
     fn encode_mr<T: Reg>(&mut self, opc: u8, op1: MemOp, op2: T)
     where
@@ -818,4 +913,27 @@
 }
 impl EncodeMR<Reg32> for Asm {}
 impl EncodeMR<Reg64> for Asm {}
+
+/// Encode helper for memory-immediate instructions.
+trait EncodeMI<T: Imm> {
+    fn legacy_prefix() -> Option<u8> {
+        None
+    }
+
+    fn rex(op1: &MemOp) -> Option<u8> {
+        if op1.base().is_ext() {
+            Some(rex(false, 0, 0, op1.base().idx()))
+        } else {
+            None
+        }
+    }
+}
+
+impl EncodeMI<Imm8> for Asm {}
+impl EncodeMI<Imm16> for Asm {
+    fn legacy_prefix() -> Option<u8> {
+        Some(0x66)
+    }
+}
+impl EncodeMI<Imm32> for Asm {}
 
\ No newline at end of file -- cgit v1.2.3