|
@@ -126,95 +126,27 @@ impl<'a> ir::ConstVisitor for CodeGenerator<'a> {
|
|
|
|
|
|
fn visit_add(&mut self, add: &'_ Instruction) {
|
|
fn visit_add(&mut self, add: &'_ Instruction) {
|
|
if let Instruction::Add{ offset, value } = add {
|
|
if let Instruction::Add{ offset, value } = add {
|
|
- match self.opts.cell_size {
|
|
|
|
- CellSize::Bits(8) => {
|
|
|
|
- dynasm!(self.buffer
|
|
|
|
- ; add BYTE [rdi + *offset as i32], *value as i8
|
|
|
|
- );
|
|
|
|
- },
|
|
|
|
- CellSize::Bits(16) => {
|
|
|
|
- dynasm!(self.buffer
|
|
|
|
- ; add WORD [rdi + *offset as i32], *value as i16
|
|
|
|
- );
|
|
|
|
- },
|
|
|
|
- CellSize::Bits(32) => {
|
|
|
|
- dynasm!(self.buffer
|
|
|
|
- ; add DWORD [rdi + *offset as i32], *value as i32
|
|
|
|
- );
|
|
|
|
- },
|
|
|
|
- CellSize::Bits(64) => {
|
|
|
|
- if *value > i32::MAX as _ || *value < i32::MIN as _ {
|
|
|
|
- dynasm!(self.buffer
|
|
|
|
- ; mov rcx, QWORD *value
|
|
|
|
- ; add QWORD [rdi + *offset as i32], rcx
|
|
|
|
- );
|
|
|
|
- }
|
|
|
|
- else {
|
|
|
|
- dynasm!(self.buffer
|
|
|
|
- ; add QWORD [rdi + *offset as i32], *value as i32
|
|
|
|
- );
|
|
|
|
- }
|
|
|
|
- },
|
|
|
|
- _ => {}
|
|
|
|
- }
|
|
|
|
|
|
+ dynasm!(self.buffer
|
|
|
|
+ ; add BYTE [rdi + *offset as i32], *value as i8
|
|
|
|
+ );
|
|
|
|
+
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
fn visit_set(&mut self, set: &'_ Instruction) {
|
|
fn visit_set(&mut self, set: &'_ Instruction) {
|
|
if let Instruction::Set{ offset, value } = set {
|
|
if let Instruction::Set{ offset, value } = set {
|
|
- match self.opts.cell_size {
|
|
|
|
- CellSize::Bits(8) => {
|
|
|
|
- dynasm!(self.buffer
|
|
|
|
- ; mov BYTE [rdi + *offset as i32], *value as i8
|
|
|
|
- );
|
|
|
|
- },
|
|
|
|
- CellSize::Bits(16) => {
|
|
|
|
- dynasm!(self.buffer
|
|
|
|
- ; mov WORD [rdi + *offset as i32], *value as i16
|
|
|
|
- );
|
|
|
|
- },
|
|
|
|
- CellSize::Bits(32) => {
|
|
|
|
- dynasm!(self.buffer
|
|
|
|
- ; mov DWORD [rdi + *offset as i32], *value as i32
|
|
|
|
- );
|
|
|
|
- },
|
|
|
|
- CellSize::Bits(64) => {
|
|
|
|
- dynasm!(self.buffer
|
|
|
|
- ; mov rcx, QWORD *value
|
|
|
|
- ; mov QWORD [rdi + *offset as i32], rcx
|
|
|
|
- );
|
|
|
|
- },
|
|
|
|
- _ => {}
|
|
|
|
- }
|
|
|
|
|
|
+ dynasm!(self.buffer
|
|
|
|
+ ; mov BYTE [rdi + *offset as i32], *value as i8
|
|
|
|
+ );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
fn visit_linear_loop(&mut self, l: &Instruction) {
|
|
fn visit_linear_loop(&mut self, l: &Instruction) {
|
|
if let Instruction::LinearLoop{ offset: glob_offset, factors } = l {
|
|
if let Instruction::LinearLoop{ offset: glob_offset, factors } = l {
|
|
if factors.len() > 0 {
|
|
if factors.len() > 0 {
|
|
- match self.opts.cell_size {
|
|
|
|
- CellSize::Bits(8) => {
|
|
|
|
- dynasm!(self.buffer
|
|
|
|
- ; movzx rcx, BYTE [rdi + *glob_offset as i32]
|
|
|
|
- );
|
|
|
|
- },
|
|
|
|
- CellSize::Bits(16) => {
|
|
|
|
- dynasm!(self.buffer
|
|
|
|
- ; movzx rcx, WORD [rdi + 2 * *glob_offset as i32]
|
|
|
|
- );
|
|
|
|
- },
|
|
|
|
- CellSize::Bits(32) => {
|
|
|
|
- dynasm!(self.buffer
|
|
|
|
- ; mov ecx, DWORD [rdi + 4 * *glob_offset as i32]
|
|
|
|
- );
|
|
|
|
- },
|
|
|
|
- CellSize::Bits(64) => {
|
|
|
|
- dynasm!(self.buffer
|
|
|
|
- ; mov rcx, QWORD [rdi + 8 * *glob_offset as i32]
|
|
|
|
- );
|
|
|
|
- },
|
|
|
|
- _ => {}
|
|
|
|
- }
|
|
|
|
|
|
+ dynasm!(self.buffer
|
|
|
|
+ ; movzx rcx, BYTE [rdi + *glob_offset as i32]
|
|
|
|
+ );
|
|
}
|
|
}
|
|
for (&offset, &factor) in factors {
|
|
for (&offset, &factor) in factors {
|
|
if offset == 0 {
|
|
if offset == 0 {
|
|
@@ -222,128 +154,93 @@ impl<'a> ir::ConstVisitor for CodeGenerator<'a> {
|
|
}
|
|
}
|
|
|
|
|
|
let absoff = offset + glob_offset;
|
|
let absoff = offset + glob_offset;
|
|
-
|
|
|
|
-
|
|
|
|
- match self.opts.cell_size {
|
|
|
|
- CellSize::Bits(8) => {
|
|
|
|
- if factor == 0 {
|
|
|
|
- }
|
|
|
|
- else if factor == 1 {
|
|
|
|
- dynasm!(self.buffer
|
|
|
|
- ; add BYTE [rdi + absoff as i32], cl
|
|
|
|
- );
|
|
|
|
- }
|
|
|
|
- else if factor == -1 {
|
|
|
|
- dynasm!(self.buffer
|
|
|
|
- ; sub BYTE [rdi + absoff as i32], cl
|
|
|
|
- );
|
|
|
|
- }
|
|
|
|
- else if factor == 2 {
|
|
|
|
- dynasm!(self.buffer
|
|
|
|
- ; lea ebx, [rcx + rcx]
|
|
|
|
- ; add BYTE [rdi + absoff as i32], bl
|
|
|
|
- );
|
|
|
|
- }
|
|
|
|
- else if factor == 3 {
|
|
|
|
- dynasm!(self.buffer
|
|
|
|
- ; lea ebx, [rcx + rcx * 2]
|
|
|
|
- ; add BYTE [rdi + absoff as i32], bl
|
|
|
|
- );
|
|
|
|
- }
|
|
|
|
- else if factor == 5 {
|
|
|
|
- dynasm!(self.buffer
|
|
|
|
- ; lea ebx, [rcx + rcx * 4]
|
|
|
|
- ; add BYTE [rdi + absoff as i32], bl
|
|
|
|
- );
|
|
|
|
- }
|
|
|
|
- else if factor == 7 {
|
|
|
|
- dynasm!(self.buffer
|
|
|
|
- ; lea ebx, [0 + rcx * 8]
|
|
|
|
- ; sub ebx, ecx
|
|
|
|
- ; add BYTE [rdi + absoff as i32], bl
|
|
|
|
- );
|
|
|
|
- }
|
|
|
|
- else if factor == 9 {
|
|
|
|
- dynasm!(self.buffer
|
|
|
|
- ; lea ebx, [rcx + rcx * 8]
|
|
|
|
- ; add BYTE [rdi + absoff as i32], bl
|
|
|
|
- );
|
|
|
|
- }
|
|
|
|
- else if factor.count_ones() == 1 {
|
|
|
|
- dynasm!(self.buffer
|
|
|
|
- ; mov bl, cl
|
|
|
|
- ; shl bl, factor.trailing_zeros() as i8
|
|
|
|
- ; add BYTE [rdi + absoff 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 + absoff as i32], bl
|
|
|
|
- );
|
|
|
|
- }
|
|
|
|
- else {
|
|
|
|
- dynasm!(self.buffer
|
|
|
|
- //; mov al, factor as i8
|
|
|
|
- ; imul eax, ecx, factor as _
|
|
|
|
- ; add al, BYTE [rdi + absoff as i32]
|
|
|
|
- ; mov BYTE [rdi + absoff as i32], al
|
|
|
|
- );
|
|
|
|
- }
|
|
|
|
- },
|
|
|
|
- CellSize::Bits(16) => {
|
|
|
|
- dynasm!(self.buffer
|
|
|
|
- ; imul eax, ecx, factor as _
|
|
|
|
- ; add ax, WORD [rdi + 2 * absoff as i32]
|
|
|
|
- ; mov WORD [rdi + 2 * absoff as i32], ax
|
|
|
|
- );
|
|
|
|
- },
|
|
|
|
- CellSize::Bits(32) => {
|
|
|
|
- dynasm!(self.buffer
|
|
|
|
- ; imul rax, rcx, factor as _
|
|
|
|
- ; add eax, DWORD [rdi + 4 * absoff as i32]
|
|
|
|
- ; mov DWORD [rdi + 4 * absoff as i32], eax
|
|
|
|
- );
|
|
|
|
- },
|
|
|
|
- CellSize::Bits(64) => {
|
|
|
|
- dynasm!(self.buffer
|
|
|
|
- ; imul rax, rcx, factor as _
|
|
|
|
- ; add rax, QWORD [rdi + 8 * absoff as i32]
|
|
|
|
- ; mov QWORD [rdi + 8 * absoff as i32], rax
|
|
|
|
- );
|
|
|
|
- },
|
|
|
|
- _ => {}
|
|
|
|
|
|
+ if factor == 0 {
|
|
}
|
|
}
|
|
- }
|
|
|
|
- match self.opts.cell_size {
|
|
|
|
- CellSize::Bits(8) => {
|
|
|
|
|
|
+ else if factor == 1 {
|
|
|
|
+ //println!("add BYTE [rdi + {}], cl", absoff as i32);
|
|
|
|
+ dynasm!(self.buffer
|
|
|
|
+ ; add BYTE [rdi + absoff as i32], cl
|
|
|
|
+ );
|
|
|
|
+ }
|
|
|
|
+ else if factor == -1 {
|
|
|
|
+ //println!("sub BYTE [rdi + {}], cl", absoff as i32);
|
|
|
|
+ dynasm!(self.buffer
|
|
|
|
+ ; sub BYTE [rdi + absoff as i32], cl
|
|
|
|
+ );
|
|
|
|
+ }
|
|
|
|
+ /*else if factor == 2 {
|
|
|
|
+ //println!("; some ins (factor = {})", factor);
|
|
|
|
+ dynasm!(self.buffer
|
|
|
|
+ ; lea ebx, [rcx + rcx]
|
|
|
|
+ ; add BYTE [rdi + absoff as i32], bl
|
|
|
|
+ );
|
|
|
|
+ }*/
|
|
|
|
+ else if factor == 3 {
|
|
|
|
+ //println!("; some ins (factor = {})", factor);
|
|
dynasm!(self.buffer
|
|
dynasm!(self.buffer
|
|
- ; mov BYTE [rdi + *glob_offset as i32], 0
|
|
|
|
|
|
+ ; lea ebx, [rcx + rcx * 2]
|
|
|
|
+ ; add BYTE [rdi + absoff as i32], bl
|
|
);
|
|
);
|
|
- },
|
|
|
|
- CellSize::Bits(16) => {
|
|
|
|
|
|
+ }
|
|
|
|
+ else if factor == 5 {
|
|
|
|
+ //println!("; some ins (factor = {})", factor);
|
|
dynasm!(self.buffer
|
|
dynasm!(self.buffer
|
|
- ; mov WORD [rdi + 2 * *glob_offset as i32], 0
|
|
|
|
|
|
+ ; lea ebx, [rcx + rcx * 4]
|
|
|
|
+ ; add BYTE [rdi + absoff as i32], bl
|
|
);
|
|
);
|
|
- },
|
|
|
|
- CellSize::Bits(32) => {
|
|
|
|
|
|
+ }
|
|
|
|
+ /*else if factor == 7 {
|
|
|
|
+ //println!("; some ins (factor = {})", factor);
|
|
dynasm!(self.buffer
|
|
dynasm!(self.buffer
|
|
- ; mov DWORD [rdi + 4 * *glob_offset as i32], 0
|
|
|
|
|
|
+ ; lea ebx, [0 + rcx * 8]
|
|
|
|
+ ; sub ebx, ecx
|
|
|
|
+ ; add BYTE [rdi + absoff as i32], bl
|
|
);
|
|
);
|
|
- },
|
|
|
|
- CellSize::Bits(64) => {
|
|
|
|
|
|
+ }*/
|
|
|
|
+ else if factor == 9 {
|
|
|
|
+ //println!("; some ins (factor = {})", factor);
|
|
dynasm!(self.buffer
|
|
dynasm!(self.buffer
|
|
- ; mov QWORD [rdi + 8 * *glob_offset as i32], 0
|
|
|
|
|
|
+ ; lea ebx, [rcx + rcx * 8]
|
|
|
|
+ ; add BYTE [rdi + absoff as i32], bl
|
|
);
|
|
);
|
|
- },
|
|
|
|
- _ => {}
|
|
|
|
|
|
+ }
|
|
|
|
+ else if factor.count_ones() == 1 {
|
|
|
|
+ //println!("; some ins (factor = {})", factor);
|
|
|
|
+ dynasm!(self.buffer
|
|
|
|
+ ; mov bl, cl
|
|
|
|
+ ; shl bl, factor.trailing_zeros() as i8
|
|
|
|
+ ; add BYTE [rdi + absoff as i32], bl
|
|
|
|
+ );
|
|
|
|
+ }
|
|
|
|
+ else if (-factor).count_ones() == 1 {
|
|
|
|
+ //println!("; some ins (factor = {})", factor);
|
|
|
|
+ dynasm!(self.buffer
|
|
|
|
+ ; mov bl, cl
|
|
|
|
+ ; shl bl, factor.trailing_zeros() as i8
|
|
|
|
+ ; sub BYTE [rdi + absoff as i32], bl
|
|
|
|
+ );
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ //println!("; some ins (factor = {})", factor);
|
|
|
|
+ dynasm!(self.buffer
|
|
|
|
+ ; mov al, factor as i8
|
|
|
|
+ ; mul cl
|
|
|
|
+ ; add BYTE [rdi + absoff as i32], al
|
|
|
|
+ //; imul eax, ecx, factor as _
|
|
|
|
+ //; add al, BYTE [rdi + absoff as i32]
|
|
|
|
+ //; mov BYTE [rdi + absoff as i32], al
|
|
|
|
+ );
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
+ dynasm!(self.buffer
|
|
|
|
+ ; mov BYTE [rdi + *glob_offset as i32], 0
|
|
|
|
+ );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
fn visit_move_ptr(&mut self, mp: &Instruction) {
|
|
fn visit_move_ptr(&mut self, mp: &Instruction) {
|
|
if let Instruction::MovePtr(offset) = mp {
|
|
if let Instruction::MovePtr(offset) = mp {
|
|
|
|
+ //println!("lea rdi, [rdi + {}]", *offset as i32);
|
|
dynasm!(self.buffer
|
|
dynasm!(self.buffer
|
|
; lea rdi, [rdi + *offset as i32]
|
|
; lea rdi, [rdi + *offset as i32]
|
|
);
|
|
);
|
|
@@ -390,6 +287,7 @@ impl<'a> ir::ConstVisitor for CodeGenerator<'a> {
|
|
; push rdi
|
|
; push rdi
|
|
; push rsi
|
|
; push rsi
|
|
; sub rsp, 24
|
|
; sub rsp, 24
|
|
|
|
+ ; xor rdx, rdx
|
|
; mov dil, BYTE [rdi + *offset as i32]
|
|
; mov dil, BYTE [rdi + *offset as i32]
|
|
; mov rax, QWORD putbyte as _
|
|
; mov rax, QWORD putbyte as _
|
|
; call rax
|
|
; call rax
|
|
@@ -402,7 +300,7 @@ impl<'a> ir::ConstVisitor for CodeGenerator<'a> {
|
|
}
|
|
}
|
|
|
|
|
|
extern "C" fn putbyte(chr: u8) {
|
|
extern "C" fn putbyte(chr: u8) {
|
|
- //print!("{:?}", chr as char);
|
|
|
|
|
|
+ //println!("{:?}", chr);
|
|
std::io::stdout().write(&[chr]).unwrap();
|
|
std::io::stdout().write(&[chr]).unwrap();
|
|
std::io::stdout().flush().unwrap();
|
|
std::io::stdout().flush().unwrap();
|
|
}
|
|
}
|