|
@@ -1,23 +1,32 @@
|
|
|
use std::i64;
|
|
|
-use super::ir;
|
|
|
+use super::{ir, optimize};
|
|
|
use std::io::{Write, Read};
|
|
|
use std::mem;
|
|
|
-use super::ir::{MutVisitor, Instruction};
|
|
|
+use super::ir::{ConstVisitor, Instruction};
|
|
|
|
|
|
#[cfg(target_os = "windows")]
|
|
|
use winapi::um::memoryapi::VirtualAlloc;
|
|
|
#[cfg(target_os = "windows")]
|
|
|
use winapi::um::winnt::{MEM_COMMIT, PAGE_EXECUTE_READWRITE};
|
|
|
-
|
|
|
use dynasmrt::{DynasmApi, DynasmLabelApi};
|
|
|
|
|
|
-pub fn compile(mut instrs: Vec<ir::Instruction>) -> Vec<u8> {
|
|
|
+pub enum Storation {
|
|
|
+ Register(&'static str),
|
|
|
+ Stack(i64),
|
|
|
+}
|
|
|
+
|
|
|
+pub fn compile_cfg<'a>(cfg: Vec<optimize::DfInstr<'a>>) -> Box<fn (*mut u8) -> ()> {
|
|
|
+ Box::new(|_| {})
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+pub fn compile(instrs: &Vec<ir::Instruction>) -> Vec<u8> {
|
|
|
let mut cg = CodeGenerator::new();
|
|
|
cg.initialize();
|
|
|
|
|
|
let entry = cg.buffer.offset();
|
|
|
|
|
|
- cg.visit_instructions(&mut instrs);
|
|
|
+ cg.visit_instructions(instrs);
|
|
|
cg.buffer.commit();
|
|
|
cg.finalize();
|
|
|
let buf = cg.buffer.finalize().unwrap();
|
|
@@ -30,10 +39,10 @@ pub fn compile(mut instrs: Vec<ir::Instruction>) -> Vec<u8> {
|
|
|
mem::transmute(buf.ptr(entry))
|
|
|
};
|
|
|
|
|
|
- let mut data: Vec<u8> = Vec::with_capacity(100000);
|
|
|
+ //let mut data: Vec<u8> = Vec::with_capacity(100000);
|
|
|
unsafe {
|
|
|
//function(&mut *data.into_boxed_slice().as_mut_ptr() as *mut u8);
|
|
|
- function(std::alloc::alloc_zeroed(std::alloc::Layout::new::<[u8; 1000]>()));
|
|
|
+ function(std::alloc::alloc_zeroed(std::alloc::Layout::new::<[u8; 100000]>()));
|
|
|
}
|
|
|
|
|
|
//cg.into_vec()
|
|
@@ -80,37 +89,37 @@ impl CodeGenerator {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl ir::MutVisitor for CodeGenerator {
|
|
|
+impl ir::ConstVisitor for CodeGenerator {
|
|
|
type Ret = ();
|
|
|
|
|
|
- fn visit_nop(&mut self, nop: &mut Instruction) {
|
|
|
+ fn visit_nop(&mut self, nop: &Instruction) {
|
|
|
}
|
|
|
|
|
|
- fn visit_add(&mut self, add: &'_ mut Instruction) {
|
|
|
+ fn visit_add(&mut self, add: &'_ Instruction) {
|
|
|
if let Instruction::Add{ offset, value } = add {
|
|
|
dynasm!(self.buffer
|
|
|
- ; add BYTE [rdi + rsi + *offset as i32], *value as i8
|
|
|
+ ; add BYTE [rdi + *offset as i32], *value as i8
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- fn visit_set(&mut self, set: &'_ mut Instruction) {
|
|
|
+ fn visit_set(&mut self, set: &'_ Instruction) {
|
|
|
if let Instruction::Set{ offset, value } = set {
|
|
|
dynasm!(self.buffer
|
|
|
- ; mov BYTE [rdi + rsi + *offset as i32], *value as i8
|
|
|
+ ; mov BYTE [rdi + *offset as i32], *value as i8
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- fn visit_linear_loop(&mut self, l: &mut Instruction) {
|
|
|
+ fn visit_linear_loop(&mut self, l: &Instruction) {
|
|
|
if let Instruction::LinearLoop(factors) = l {
|
|
|
if factors.len() > 1 ||
|
|
|
factors.len() >= 1 && !factors.contains_key(&0) {
|
|
|
dynasm!(self.buffer
|
|
|
- ; mov cl, BYTE [rdi + rsi]
|
|
|
+ ; mov cl, BYTE [rdi]
|
|
|
);
|
|
|
}
|
|
|
- for (&offset, &mut factor) in factors {
|
|
|
+ for (&offset, &factor) in factors {
|
|
|
if offset == 0 {
|
|
|
continue;
|
|
|
}
|
|
@@ -119,71 +128,69 @@ impl ir::MutVisitor for CodeGenerator {
|
|
|
}
|
|
|
else if factor == 1 {
|
|
|
dynasm!(self.buffer
|
|
|
- ; add BYTE [rdi + rsi + offset as i32], cl
|
|
|
+ ; add BYTE [rdi + offset as i32], cl
|
|
|
);
|
|
|
}
|
|
|
else if factor == -1 {
|
|
|
dynasm!(self.buffer
|
|
|
- ; sub BYTE [rdi + rsi + offset as i32], cl
|
|
|
+ ; sub BYTE [rdi + offset as i32], cl
|
|
|
);
|
|
|
}
|
|
|
else if factor.count_ones() == 1 {
|
|
|
dynasm!(self.buffer
|
|
|
; mov bl, cl
|
|
|
; shl bl, factor.trailing_zeros() as i8
|
|
|
- ; add BYTE [rdi + rsi + offset as i32], bl
|
|
|
+ ; add BYTE [rdi + offset as i32], bl
|
|
|
);
|
|
|
}
|
|
|
else if (-factor).count_ones() == 1 {
|
|
|
dynasm!(self.buffer
|
|
|
; mov bl, cl
|
|
|
; shl bl, factor.trailing_zeros() as i8
|
|
|
- ; sub BYTE [rdi + rsi + offset as i32], bl
|
|
|
+ ; sub BYTE [rdi + offset as i32], bl
|
|
|
);
|
|
|
}
|
|
|
else {
|
|
|
dynasm!(self.buffer
|
|
|
; mov al, factor as i8
|
|
|
; mul cl
|
|
|
- ; add BYTE [rdi + rsi + offset as i32], al
|
|
|
+ ; add BYTE [rdi + offset as i32], al
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
dynasm!(self.buffer
|
|
|
- ; mov BYTE [rdi + rsi], 0
|
|
|
+ ; mov BYTE [rdi], 0
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- fn visit_move_ptr(&mut self, mp: &'_ mut Instruction) {
|
|
|
+ fn visit_move_ptr(&mut self, mp: &Instruction) {
|
|
|
if let Instruction::MovePtr(offset) = mp {
|
|
|
dynasm!(self.buffer
|
|
|
- ; add rsi, DWORD *offset as i32
|
|
|
+ ; lea rdi, [rdi + *offset as i32]
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- fn visit_loop(&mut self, l: &mut Instruction) {
|
|
|
+ fn visit_loop(&mut self, l: &Instruction) {
|
|
|
if let Instruction::Loop(insts) = l {
|
|
|
let begin = self.buffer.new_dynamic_label();
|
|
|
let end = self.buffer.new_dynamic_label();
|
|
|
dynasm!(self.buffer
|
|
|
- ; mov al, BYTE [rdi + rsi]
|
|
|
- ; test al, al
|
|
|
+ ; cmp BYTE [rdi], 0
|
|
|
; jz => end
|
|
|
; => begin
|
|
|
);
|
|
|
self.visit_instructions(insts);
|
|
|
dynasm!(self.buffer
|
|
|
- ; mov al, BYTE [rdi + rsi]
|
|
|
- ; test al, al
|
|
|
+ ; cmp BYTE [rdi], 0
|
|
|
; jnz => begin
|
|
|
; => end
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- fn visit_read(&mut self, r: &mut Instruction) {
|
|
|
+ fn visit_read(&mut self, r: &Instruction) {
|
|
|
if let Instruction::Read(offset) = r {
|
|
|
dynasm!(self.buffer
|
|
|
; push rdi
|
|
@@ -194,18 +201,18 @@ impl ir::MutVisitor for CodeGenerator {
|
|
|
; add rsp, 24
|
|
|
; pop rsi
|
|
|
; pop rdi
|
|
|
- ; mov BYTE [rdi + rsi + *offset as i32], al
|
|
|
+ ; mov BYTE [rdi + *offset as i32], al
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- fn visit_write(&mut self, w: &mut Instruction) {
|
|
|
+ fn visit_write(&mut self, w: &Instruction) {
|
|
|
if let Instruction::Write(offset) = w {
|
|
|
dynasm!(self.buffer
|
|
|
; push rdi
|
|
|
; push rsi
|
|
|
; sub rsp, 24
|
|
|
- ; mov dil, BYTE [rdi + rsi + *offset as i32]
|
|
|
+ ; mov dil, BYTE [rdi + *offset as i32]
|
|
|
; mov rax, QWORD putbyte as _
|
|
|
; call rax
|
|
|
; add rsp, 24
|