Nicolas Winkler 5 år sedan
förälder
incheckning
e09336e925
6 ändrade filer med 46 tillägg och 26 borttagningar
  1. 10 8
      src/compile.rs
  2. 3 3
      src/interpret.rs
  3. 6 6
      src/ir.rs
  4. 2 2
      src/main.rs
  5. 21 3
      src/optimize.rs
  6. 4 4
      src/transpile_c.rs

+ 10 - 8
src/compile.rs

@@ -112,11 +112,11 @@ impl ir::ConstVisitor for CodeGenerator {
     }
 
     fn visit_linear_loop(&mut self, l: &Instruction) {
-        if let Instruction::LinearLoop(factors) = l {
+        if let Instruction::LinearLoop{ offset: glob_offset, factors } = l {
             if factors.len() > 1 ||
                 factors.len() >= 1 && !factors.contains_key(&0) {
                 dynasm!(self.buffer
-                    ; mov cl, BYTE [rdi]
+                    ; mov cl, BYTE [rdi + *glob_offset as i32]
                 );
             }
             for (&offset, &factor) in factors {
@@ -124,42 +124,44 @@ impl ir::ConstVisitor for CodeGenerator {
                     continue;
                 }
 
+                let absoff = offset + glob_offset;
+
                 if factor == 0 {
                 }
                 else if factor == 1 {
                     dynasm!(self.buffer
-                        ; add BYTE [rdi + offset as i32], cl
+                        ; add BYTE [rdi + absoff as i32], cl
                     );
                 }
                 else if factor == -1 {
                     dynasm!(self.buffer
-                        ; sub BYTE [rdi + offset as i32], cl
+                        ; sub BYTE [rdi + absoff 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 + offset as i32], bl
+                        ; 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 + offset as i32], bl
+                        ; sub BYTE [rdi + absoff as i32], bl
                     );
                 }
                 else {
                     dynasm!(self.buffer
                         ; mov al, factor as i8
                         ; mul cl
-                        ; add BYTE [rdi + offset as i32], al
+                        ; add BYTE [rdi + absoff as i32], al
                     );
                 }
             }
             dynasm!(self.buffer
-                ; mov BYTE [rdi], 0
+                ; mov BYTE [rdi + *glob_offset as i32], 0
             );
         }
     }

+ 3 - 3
src/interpret.rs

@@ -48,11 +48,11 @@ fn run_instrs(instructions: &Vec<Instruction>, data: &mut Data) {
                 io::stdout().write(&[cell]).unwrap();
                 io::stdout().flush().unwrap();
             },
-            Instruction::LinearLoop(factors) => {
+            Instruction::LinearLoop{ offset: glob_offset, factors } => {
                 assert_eq!(factors.get(&0), Some(&-1));
-                let multiplicator = data.memory[(data.ptr as usize) % len];
+                let multiplicator = data.memory[((data.ptr + glob_offset) as usize) % len];
                 for (offset, value) in factors {
-                    let cell = &mut data.memory[(data.ptr + offset) as usize % len];
+                    let cell = &mut data.memory[(data.ptr + offset + glob_offset) as usize % len];
                     *cell = cell.wrapping_add(multiplicator.wrapping_mul(*value as u8));
                 }
             },

+ 6 - 6
src/ir.rs

@@ -5,7 +5,7 @@ pub enum Instruction {
     Nop,
     Add{ offset: i64, value: i64 },
     Set{ offset: i64, value: i64 },
-    LinearLoop(BTreeMap<i64, i64>),
+    LinearLoop{ offset: i64, factors: BTreeMap<i64, i64> },
     MovePtr(i64),
     Loop(Vec<Instruction>),
     Read(i64),
@@ -34,7 +34,7 @@ impl Instruction {
                 }
             },
             Set{ offset, value } => format!("Set(@{}, {})", offset, value),
-            LinearLoop(map) => {
+            LinearLoop{ offset, factors } => {
                 "LinearLoop".to_string()
             },
             MovePtr(val) => format!("MovePtr({})", val),
@@ -101,9 +101,9 @@ pub trait MutVisitor {
         use self::Instruction::*;
         match inst {
             Nop => self.visit_nop(inst),
-            Add {offset: _, value: _} => self.visit_add(inst),
-            Set {offset: _, value: _} => self.visit_set(inst),
-            LinearLoop (_) => self.visit_linear_loop(inst),
+            Add { offset: _, value: _ } => self.visit_add(inst),
+            Set { offset: _, value: _ } => self.visit_set(inst),
+            LinearLoop { offset: _, factors: _ } => self.visit_linear_loop(inst),
             MovePtr(_) => self.visit_move_ptr(inst),
             Loop(_) => self.visit_loop(inst),
             Read(_) => self.visit_read(inst),
@@ -162,7 +162,7 @@ pub trait ConstVisitor {
             Nop => self.visit_nop(inst),
             Add {offset: _, value: _} => self.visit_add(inst),
             Set {offset: _, value: _} => self.visit_set(inst),
-            LinearLoop (_) => self.visit_linear_loop(inst),
+            LinearLoop { offset: _, factors: _ } => self.visit_linear_loop(inst),
             MovePtr(_) => self.visit_move_ptr(inst),
             Loop(_) => self.visit_loop(inst),
             Read(_) => self.visit_read(inst),

+ 2 - 2
src/main.rs

@@ -42,9 +42,9 @@ fn main() -> io::Result<()> {
         for ref inst in &insts {
             //println!("{}\n", inst.to_string());
         }
-        //println!("{}", transpile_c::transpile_c(&insts));
+        println!("{}", transpile_c::transpile_c(&insts));
 
-        let code = compile::compile(&insts);
+        //let code = compile::compile(&insts);
     }
     else if let Err(msg) = insts {
         println!("error parsing: {}", msg);

+ 21 - 3
src/optimize.rs

@@ -95,7 +95,7 @@ impl<'a> ir::MutVisitor for DfgOptimizer<'a> {
             }
 
             if !dirty && increments.get(&0) == Some(&-1) {
-                std::mem::replace(l, Instruction::LinearLoop(increments));
+                std::mem::replace(l, Instruction::LinearLoop{ offset: 0, factors: increments });
             }
             // set cell at offset 0 to 0
         }
@@ -132,11 +132,13 @@ impl<'a> ir::MutVisitor for DfgOptimizer<'a> {
 
 
 pub struct LinOptimizer {
+    offset: i64
 }
 
 impl LinOptimizer {
     pub fn new() -> Self {
         LinOptimizer {
+            offset: 0
         }
     }
 }
@@ -151,15 +153,24 @@ impl ir::MutVisitor for LinOptimizer {
     }
 
     fn visit_add(&mut self, add: &mut Instruction) {
+        if let Instruction::Add{ offset, value: _value } = add {
+            *offset += self.offset;
+        }
     }
 
     fn visit_set(&mut self, set: &mut Instruction) {
+        if let Instruction::Set{ offset, value: _value } = set {
+            *offset += self.offset;
+        }
     }
 
     fn visit_linear_loop(&mut self, lloop: &'_ mut Instruction) {
     }
 
     fn visit_move_ptr(&mut self, move_ptr: &'_ mut Instruction) {
+        if let Instruction::MovePtr(offset) = move_ptr {
+            self.offset += *offset;
+        }
     }
 
     fn visit_loop(&mut self, l: &mut Instruction) {
@@ -179,6 +190,7 @@ impl ir::MutVisitor for LinOptimizer {
                         },
                         _ => {
                             dirty = true;
+                            break;
                         }
                     }
                 }
@@ -189,12 +201,12 @@ impl ir::MutVisitor for LinOptimizer {
                     if v % 2 != 0 {
                         // cases like [-]
                         // also [---]
-                        std::mem::replace(l, Instruction::Set{ offset: 0, value: 0 });
+                        std::mem::replace(l, Instruction::Set{ offset: self.offset, value: 0 });
                     }
                 }
             }
             else if !dirty && increments.get(&0) == Some(&-1) {
-                std::mem::replace(l, Instruction::LinearLoop(increments));
+                std::mem::replace(l, Instruction::LinearLoop{ offset: self.offset, factors: increments });
             }
 
             // set cell at offset 0 to 0
@@ -202,8 +214,14 @@ impl ir::MutVisitor for LinOptimizer {
     }
 
     fn visit_read(&mut self, read: &'_ mut Instruction) {
+        if let Instruction::Read(offset) = read {
+            *offset += self.offset;
+        }
     }
 
     fn visit_write(&mut self, write: &'_ mut Instruction) {
+        if let Instruction::Write(offset) = write {
+            *offset += self.offset;
+        }
     }
 }

+ 4 - 4
src/transpile_c.rs

@@ -58,7 +58,7 @@ impl ir::ConstVisitor for Transpiler {
     }
 
     fn visit_linear_loop(&mut self, l: &Instruction) {
-        if let Instruction::LinearLoop(factors) = l {
+        if let Instruction::LinearLoop{ offset: glob_offset, factors } = l {
             for (&offset, &factor) in factors {
                 if offset == 0 {
                     continue;
@@ -67,13 +67,13 @@ impl ir::ConstVisitor for Transpiler {
                 if factor == 0 {
                 }
                 else if factor == 1 {
-                    self.code += &format!("buffer[{}] += buffer[0];\n", offset);
+                    self.code += &format!("buffer[{}] += buffer[0];\n", glob_offset + offset);
                 }
                 else if factor == -1 {
-                    self.code += &format!("buffer[{}] -= buffer[0];\n", offset);
+                    self.code += &format!("buffer[{}] -= buffer[0];\n", glob_offset + offset);
                 }
                 else {
-                    self.code += &format!("buffer[{}] += {} * buffer[0];\n", offset, factor);
+                    self.code += &format!("buffer[{}] += {} * buffer[0];\n", glob_offset + offset, factor);
                 }
             }
             self.code += "buffer[0] = 0;\n";