Nicolas Winkler преди 4 години
родител
ревизия
5ca1b1e808
променени са 5 файла, в които са добавени 142 реда и са изтрити 192 реда
  1. 84 186
      src/compile.rs
  2. 18 0
      src/lir.rs
  3. 30 3
      src/main.rs
  4. 9 3
      src/optimize.rs
  5. 1 0
      src/options.rs

+ 84 - 186
src/compile.rs

@@ -126,95 +126,27 @@ impl<'a> ir::ConstVisitor for CodeGenerator<'a> {
 
     fn visit_add(&mut self, add: &'_ Instruction) {
         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) {
         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) {
         if let Instruction::LinearLoop{ offset: glob_offset, factors } = l {
             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 {
                 if offset == 0 {
@@ -222,128 +154,93 @@ impl<'a> ir::ConstVisitor for CodeGenerator<'a> {
                 }
 
                 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
-                        ; 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
-                        ; 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
-                        ; 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
-                        ; 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) {
         if let Instruction::MovePtr(offset) = mp {
+            //println!("lea rdi, [rdi + {}]", *offset as i32);
             dynasm!(self.buffer
                 ; lea rdi, [rdi + *offset as i32]
             );
@@ -390,6 +287,7 @@ impl<'a> ir::ConstVisitor for CodeGenerator<'a> {
                 ; push rdi
                 ; push rsi
                 ; sub rsp, 24
+                ; xor rdx, rdx
                 ; mov dil, BYTE [rdi + *offset as i32]
                 ; mov rax, QWORD putbyte as _
                 ; call rax
@@ -402,7 +300,7 @@ impl<'a> ir::ConstVisitor for CodeGenerator<'a> {
 }
 
 extern "C" fn putbyte(chr: u8) {
-    //print!("{:?}", chr as char);
+    //println!("{:?}", chr);
     std::io::stdout().write(&[chr]).unwrap();
     std::io::stdout().flush().unwrap();
 }

+ 18 - 0
src/lir.rs

@@ -0,0 +1,18 @@
+
+
+pub struct Lir {
+    values: Vec<Value>
+}
+
+pub enum Value {
+    Cell(i64),
+    Const(i64),
+    Operation(Operation),
+}
+
+enum Operation {
+    Add(usize, usize),
+    Sub(usize, usize),
+    Mul(usize, usize)
+}
+

+ 30 - 3
src/main.rs

@@ -53,6 +53,12 @@ fn main() -> io::Result<()> {
                 .short("m")
                 .takes_value(true)
                 .help("defines the cell modulus"))
+                
+        .arg(Arg::with_name("optimize")
+                .long("optimize")
+                .short("O")
+                .takes_value(true)
+                .help("defines the cell modulus"))
         .get_matches();
     
     let mut buffer = String::new();
@@ -84,6 +90,20 @@ fn main() -> io::Result<()> {
         }
     }
 
+
+    let opt_lvl: u64 = if let Some(opt) = matches.value_of("optimize") {
+        match u64::from_str(opt) {
+            Ok(o) => o,
+            Err(_e) => {
+                eprintln!("invalid optimization level '{}'", opt);
+                exit(1)
+            }
+        }
+    }
+    else {
+        0
+    };
+
     let insts = parser::parse(&buffer);
     if let Ok(mut insts) = insts {
         let mut lin_loop_optimizer = optimize::LinOptimizer::new();
@@ -99,9 +119,16 @@ fn main() -> io::Result<()> {
                 //println!("{}\n", inst.to_string());
             //}
             //println!("{}", trans::java::transpile(&insts));
-            //let c = trans::c::transpile_dfg(&dfg);
-            //println!("{}", c);
-            //println!("{}", trans::java::transpile(&insts));
+
+
+            if opt_lvl == 1 {
+                let arena = Arena::new();
+                let dfg = optimize::create_dfg(&mut insts, &arena);
+                let c = trans::c::transpile_dfg(&dfg);
+                println!("{}", c);
+                exit(0);
+            }
+            
             
             match matches.value_of("transpile") {
                 Some(lang) => {

+ 9 - 3
src/optimize.rs

@@ -79,9 +79,15 @@ impl<'a> ir::MutVisitor for DfgOptimizer<'a> {
     fn visit_add(&mut self, add: &mut Instruction) {
         if let Instruction::Add{ offset, value } = add {
             let cell = self.get_cell(*offset);
-            let adder = self.arena.alloc(DfgNode::Const(*value));
-            let addition = self.arena.alloc(DfgNode::Add(cell, adder));
-            self.set_cell(*offset, addition);
+            if let DfgNode::Const(c) = cell {
+                let const_sum = self.arena.alloc(DfgNode::Const(*value + c));
+                self.set_cell(*offset, const_sum);
+            }
+            else {
+                let adder = self.arena.alloc(DfgNode::Const(*value));
+                let addition = self.arena.alloc(DfgNode::Add(cell, adder));
+                self.set_cell(*offset, addition);
+            }
         }
     }
 

+ 1 - 0
src/options.rs

@@ -15,6 +15,7 @@ pub enum CellSize {
 }
 
 
+#[derive(PartialEq, Clone)]
 pub struct Options {
     pub cell_layout: CellLayout,
     pub memory_size: usize,