-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathoptimize.rs
More file actions
40 lines (34 loc) · 1.36 KB
/
optimize.rs
File metadata and controls
40 lines (34 loc) · 1.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
use tiny_elf::asm::{Mnemonic, Program};
pub trait Optimize {
fn optimize(self) -> Self;
}
/// Optimizes the assembly instructions of a [`Program`]
impl Optimize for Program {
fn optimize(mut self) -> Self {
use tiny_elf::asm::{Immediate::*, Mnemonic::*, Operand::*};
let mut instructions = Vec::new();
let mut last: Option<Mnemonic> = None;
for inst in self.instructions {
let new_inst = match (&last, inst) {
// inc/dev is faster then add/sub 1
(_, Add(r, Imm(Imm8(1) | Imm16(1) | Imm32(1)))) => Inc(r),
(_, Sub(r, Imm(Imm8(1) | Imm16(1) | Imm32(1)))) => Dec(r),
// add/sub 0 is useless
(_, Add(_, Imm(Imm8(0) | Imm16(0) | Imm32(0)))) => continue,
(_, Sub(_, Imm(Imm8(0) | Imm16(0) | Imm32(0)))) => continue,
// xor is faster than mov 0
(_, Mov(r, Imm(Imm8(0) | Imm16(0) | Imm32(0)))) => Xor(r, r.into()),
// push then pop essentially means mov
(Some(Push(o)), Pop(r)) => {
instructions.pop();
Mov(r, o.clone())
}
(_, i) => i,
};
last = Some(new_inst.clone());
instructions.push(new_inst)
}
self.instructions = instructions;
self
}
}