aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJohannes Stoelp <johannes.stoelp@gmail.com>2023-02-27 21:16:40 +0100
committerJohannes Stoelp <johannes.stoelp@gmail.com>2023-02-27 21:16:40 +0100
commitab5711a77e2a6872ca1392c1dbc2f545f7d3ab3b (patch)
tree0ecab4660bbbf0faeb5199bbc80ee53243d641ee
parent957663f5d483b1abaa3f5af25e32c274218319d5 (diff)
downloadjuicebox-asm-ab5711a77e2a6872ca1392c1dbc2f545f7d3ab3b.tar.gz
juicebox-asm-ab5711a77e2a6872ca1392c1dbc2f545f7d3ab3b.zip
Add ADD, DEC, TEST, RET instructions
-rw-r--r--src/insn.rs16
-rw-r--r--src/insn/add.rs7
-rw-r--r--src/insn/dec.rs7
-rw-r--r--src/insn/ret.rs7
-rw-r--r--src/insn/test.rs7
-rw-r--r--src/lib.rs24
-rw-r--r--src/prelude.rs2
7 files changed, 67 insertions, 3 deletions
diff --git a/src/insn.rs b/src/insn.rs
index c0bcc4e..2bfaf18 100644
--- a/src/insn.rs
+++ b/src/insn.rs
@@ -1,5 +1,21 @@
+mod add;
+mod dec;
mod mov;
+mod ret;
+mod test;
+
+pub trait Add<T, U> {
+ fn add(&mut self, op1: T, op2: U);
+}
+
+pub trait Dec<T> {
+ fn dec(&mut self, op1: T);
+}
pub trait Mov<T, U> {
fn mov(&mut self, op1: T, op2: U);
}
+
+pub trait Test<T, U> {
+ fn test(&mut self, op1: T, op2: U);
+}
diff --git a/src/insn/add.rs b/src/insn/add.rs
new file mode 100644
index 0000000..b8456c4
--- /dev/null
+++ b/src/insn/add.rs
@@ -0,0 +1,7 @@
+use crate::prelude::*;
+
+impl Add<Reg64, Reg64> for Asm {
+ fn add(&mut self, op1: Reg64, op2: Reg64) {
+ self.encode_rr(0x01, op1, op2);
+ }
+}
diff --git a/src/insn/dec.rs b/src/insn/dec.rs
new file mode 100644
index 0000000..7de5a54
--- /dev/null
+++ b/src/insn/dec.rs
@@ -0,0 +1,7 @@
+use crate::prelude::*;
+
+impl Dec<Reg64> for Asm {
+ fn dec(&mut self, op1: Reg64) {
+ self.encode_r(0xff, 1, op1);
+ }
+}
diff --git a/src/insn/ret.rs b/src/insn/ret.rs
new file mode 100644
index 0000000..74086d8
--- /dev/null
+++ b/src/insn/ret.rs
@@ -0,0 +1,7 @@
+use crate::Asm;
+
+impl Asm {
+ pub fn ret(&mut self) {
+ self.emit(&[0xc3]);
+ }
+}
diff --git a/src/insn/test.rs b/src/insn/test.rs
new file mode 100644
index 0000000..1319e3f
--- /dev/null
+++ b/src/insn/test.rs
@@ -0,0 +1,7 @@
+use crate::prelude::*;
+
+impl Test<Reg64, Reg64> for Asm {
+ fn test(&mut self, op1: Reg64, op2: Reg64) {
+ self.encode_rr(0x85, op1, op2);
+ }
+}
diff --git a/src/lib.rs b/src/lib.rs
index e38da14..27164ad 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -107,8 +107,8 @@ impl Asm {
Self: EncodeRI<T>,
{
// MI operand encoding.
- // op1 -> modrm.rm
- // op2 -> modrm.reg
+ // op1 -> modrm.rm
+ // opc extension -> modrm.reg
let modrm = modrm(
0b11, /* mod */
opc_ext, /* reg */
@@ -123,6 +123,26 @@ impl Asm {
self.emit(op2.bytes());
}
+ fn encode_r<T: Reg>(&mut self, opc: u8, opc_ext: u8, op1: T)
+ where
+ Self: EncodeRI<T>,
+ {
+ // M operand encoding.
+ // op1 -> modrm.rm
+ // opc extension -> modrm.reg
+ let modrm = modrm(
+ 0b11, /* mod */
+ opc_ext, /* reg */
+ op1.idx(), /* rm */
+ );
+
+ let prefix = <Self as EncodeRI<T>>::legacy_prefix();
+ let rex = <Self as EncodeRI<T>>::rex(op1);
+
+ self.emit_optional(&[prefix, rex]);
+ self.emit(&[opc, modrm]);
+ }
+
fn encode_mr<T: Reg>(&mut self, opc: u8, op1: MemOp, op2: T)
where
Self: EncodeMR<T>,
diff --git a/src/prelude.rs b/src/prelude.rs
index d1cd794..bca972f 100644
--- a/src/prelude.rs
+++ b/src/prelude.rs
@@ -3,4 +3,4 @@ pub use crate::MemOp;
pub use crate::{Imm16, Imm32, Imm64, Imm8};
pub use crate::{Reg16, Reg32, Reg64, Reg8};
-pub use crate::insn::{Add, Mov};
+pub use crate::insn::{Add, Dec, Mov, Test};