From f2f0a8eb4795342a985c49d66eeda73d059e6033 Mon Sep 17 00:00:00 2001 From: Johannes Stoelp Date: Mon, 27 Feb 2023 20:22:32 +0100 Subject: Initial support for immediate operands --- src/lib.rs | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) (limited to 'src/lib.rs') diff --git a/src/lib.rs b/src/lib.rs index 7c24704..35f7919 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,9 @@ +mod imm; mod insn; mod reg; +use imm::Imm; +pub use imm::{Imm16, Imm32, Imm64, Imm8}; use reg::Reg; pub use reg::{Reg16, Reg32, Reg64, Reg8}; @@ -92,6 +95,40 @@ impl Asm { self.emit(&[opc, modrm]); } + fn encode_oi(&mut self, opc: u8, op1: T, op2: U) + where + Self: EncodeRI, + { + let opc = opc + (op1.idx() & 0b111); + let prefix = >::legacy_prefix(); + let rex = >::rex(op1); + + self.emit_optional(&[prefix, rex]); + self.emit(&[opc]); + self.emit(&op2.bytes()); + } + + fn encode_ri(&mut self, opc: u8, opc_ext: u8, op1: T, op2: U) + where + Self: EncodeRI, + { + // MI operand encoding. + // op1 -> modrm.rm + // op2 -> modrm.reg + let modrm = modrm( + 0b11, /* mod */ + opc_ext, /* reg */ + op1.idx(), /* rm */ + ); + + let prefix = >::legacy_prefix(); + let rex = >::rex(op1); + + self.emit_optional(&[prefix, rex]); + self.emit(&[opc, modrm]); + self.emit(&op2.bytes()); + } + fn encode_mr(&mut self, opc: u8, op1: MemOp, op2: T) where Self: EncodeMR, @@ -161,6 +198,29 @@ impl EncodeRR for Asm { } impl EncodeRR for Asm {} +trait EncodeRI { + fn legacy_prefix() -> Option { + None + } + + fn rex(op1: T) -> Option { + if op1.need_rex() { + Some(rex(op1.rexw(), 0, 0, op1.idx())) + } else { + None + } + } +} + +impl EncodeRI for Asm {} +impl EncodeRI for Asm {} +impl EncodeRI for Asm { + fn legacy_prefix() -> Option { + Some(0x66) + } +} +impl EncodeRI for Asm {} + trait EncodeMR { fn legacy_prefix() -> Option { None @@ -227,3 +287,27 @@ impl Mov for Asm { self.encode_rm(0x8b, op1, op2); } } + +impl Mov for Asm { + fn mov(&mut self, op1: Reg64, op2: Imm64) { + self.encode_oi(0xb8, op1, op2); + } +} + +impl Mov for Asm { + fn mov(&mut self, op1: Reg32, op2: Imm32) { + self.encode_oi(0xb8, op1, op2); + } +} + +impl Mov for Asm { + fn mov(&mut self, op1: Reg16, op2: Imm16) { + self.encode_oi(0xb8, op1, op2); + } +} + +impl Mov for Asm { + fn mov(&mut self, op1: Reg8, op2: Imm8) { + self.encode_oi(0xb0, op1, op2); + } +} -- cgit v1.2.3