Bladeren bron

somewoh bug

Nicolas Winkler 4 jaren geleden
bovenliggende
commit
bc1d3538ee
5 gewijzigde bestanden met toevoegingen van 209 en 117 verwijderingen
  1. 205 66
      src/compile.rs
  2. 0 47
      src/interpret.rs
  3. 2 2
      src/main.rs
  4. 1 1
      src/optimize.rs
  5. 1 1
      src/options.rs

+ 205 - 66
src/compile.rs

@@ -1,8 +1,9 @@
-use std::i64;
+use std::{i64, i32};
 use super::{ir, optimize};
 use std::io::{Write, Read};
 use std::mem;
 use super::ir::{ConstVisitor, Instruction};
+use super::options::{Options, CellLayout, CellSize};
 //use mmap::{MemoryMap, MapOption};
 
 /*#[cfg(target_os = "windows")]
@@ -22,8 +23,8 @@ pub fn compile_cfg<'a>(cfg: Vec<optimize::DfInstr<'a>>) -> Box<fn (*mut u8) -> (
 }
 
 
-pub fn compile(instrs: &Vec<ir::Instruction>) -> Vec<u8> {
-    let mut cg = CodeGenerator::new();
+pub fn compile_and_run<'a>(instrs: &Vec<ir::Instruction>, opts: &'a Options) -> Vec<u8> {
+    let mut cg = CodeGenerator::<'a>::create(opts);
     cg.initialize();
 
     let entry = cg.buffer.offset();
@@ -42,11 +43,17 @@ pub fn compile(instrs: &Vec<ir::Instruction>) -> Vec<u8> {
     };
 
     //let mut data: Vec<u8> = Vec::with_capacity(100000);
+    let layout = match opts.cell_layout {
+        CellLayout::Trusting => std::alloc::Layout::array::<u8>(opts.memory_size).unwrap(),
+        CellLayout::Wrapping => std::alloc::Layout::array::<u8>(opts.memory_size).unwrap(),
+        CellLayout::Unbounded => std::alloc::Layout::array::<u8>(opts.memory_size).unwrap(),
+    };
     unsafe {
-        //function(&mut *data.into_boxed_slice().as_mut_ptr() as *mut u8);
-        let layout = std::alloc::Layout::new::<[u8; 0x10000]>();
         let mem = std::alloc::alloc_zeroed(layout);
-        function(mem.offset(0x08000));
+        match opts.cell_layout {
+            CellLayout::Trusting => { function(mem.offset(0x80000)); },
+            _ => { function(mem); }
+        }
         std::alloc::dealloc(mem, layout);
     }
 
@@ -55,14 +62,16 @@ pub fn compile(instrs: &Vec<ir::Instruction>) -> Vec<u8> {
     vec![]
 }
 
-pub struct CodeGenerator {
-    pub buffer: dynasmrt::x64::Assembler
+pub struct CodeGenerator<'a> {
+    pub buffer: dynasmrt::x64::Assembler,
+    opts: &'a Options
 }
 
-impl CodeGenerator {
-    pub fn new() -> Self {
+impl<'a> CodeGenerator<'a> {
+    pub fn create(opts: &'a Options) -> Self {
         CodeGenerator {
-            buffer: dynasmrt::x64::Assembler::new().unwrap()
+            buffer: dynasmrt::x64::Assembler::new().unwrap(),
+            opts: opts
         }
     }
 
@@ -109,7 +118,7 @@ impl CodeGenerator {
     }*/
 }
 
-impl ir::ConstVisitor for CodeGenerator {
+impl<'a> ir::ConstVisitor for CodeGenerator<'a> {
     type Ret = ();
 
     fn visit_nop(&mut self, _nop: &Instruction) {
@@ -117,26 +126,95 @@ impl ir::ConstVisitor for CodeGenerator {
 
     fn visit_add(&mut self, add: &'_ Instruction) {
         if let Instruction::Add{ offset, value } = add {
-            dynasm!(self.buffer
-                ; add BYTE [rdi + *offset as i32], *value as i8
-            );
+            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
+                        );
+                    }
+                },
+                _ => {}
+            }
         }
     }
 
     fn visit_set(&mut self, set: &'_ Instruction) {
         if let Instruction::Set{ offset, value } = set {
-            dynasm!(self.buffer
-                ; mov BYTE [rdi + *offset as i32], *value as i8
-            );
+            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
+                    );
+                },
+                _ => {}
+            }
         }
     }
 
     fn visit_linear_loop(&mut self, l: &Instruction) {
         if let Instruction::LinearLoop{ offset: glob_offset, factors } = l {
             if factors.len() > 0 {
-                dynasm!(self.buffer
-                    ; movzx rcx, BYTE [rdi + *glob_offset as i32]
-                );
+                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]
+                        );
+                    },
+                    _ => {}
+                }
             }
             for (&offset, &factor) in factors {
                 if offset == 0 {
@@ -145,61 +223,122 @@ impl ir::ConstVisitor for CodeGenerator {
 
                 let absoff = offset + glob_offset;
 
-                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 == 3 {
-                    dynasm!(self.buffer
-                        ; lea ebx, [rcx + rcx * 2]
-                        ; add BYTE [rdi + absoff as i32], bl
-                    );
+                
+                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
+                        );
+                    },
+                    _ => {}
                 }
-                else if factor == 5 {
-                    dynasm!(self.buffer
-                        ; lea ebx, [rcx + rcx * 4]
-                        ; add BYTE [rdi + absoff as i32], bl
-                    );
-                }
-                else if factor == 9 {
+            }
+            match self.opts.cell_size {
+                CellSize::Bits(8) => {
                     dynasm!(self.buffer
-                        ; lea ebx, [rcx + rcx * 8]
-                        ; add BYTE [rdi + absoff as i32], bl
+                        ; mov BYTE [rdi + *glob_offset as i32], 0
                     );
-                }
-                else if factor.count_ones() == 1 {
+                },
+                CellSize::Bits(16) => {
                     dynasm!(self.buffer
-                        ; mov bl, cl
-                        ; shl bl, factor.trailing_zeros() as i8
-                        ; add BYTE [rdi + absoff as i32], bl
+                        ; mov WORD [rdi + 2 * *glob_offset as i32], 0
                     );
-                }
-                else if (-factor).count_ones() == 1 {
+                },
+                CellSize::Bits(32) => {
                     dynasm!(self.buffer
-                        ; mov bl, cl
-                        ; shl bl, factor.trailing_zeros() as i8
-                        ; sub BYTE [rdi + absoff as i32], bl
+                        ; mov DWORD [rdi + 4 * *glob_offset as i32], 0
                     );
-                }
-                else {
+                },
+                CellSize::Bits(64) => {
                     dynasm!(self.buffer
-                        ; mov al, factor as i8
-                        ; mul cl
-                        ; add BYTE [rdi + absoff as i32], al
+                        ; mov QWORD [rdi + 8 * *glob_offset as i32], 0
                     );
-                }
+                },
+                _ => {}
             }
-            dynasm!(self.buffer
-                ; mov BYTE [rdi + *glob_offset as i32], 0
-            );
         }
     }
 

+ 0 - 47
src/interpret.rs

@@ -124,53 +124,6 @@ pub fn run(instructions: &Vec<Instruction>, opts: &Options) {
 }
 
 
-fn run_instrs<T>(instructions: &Vec<Instruction>, data: &mut Data<T>)
-where
-T: Add<Output=T> + Sub<Output=T> + Mul<Output=T>,
-T: Copy + Eq + CellWrite + CellRead + FromNum
-{
-    let len = data.memory.len();
-    for inst in instructions {
-        match inst {
-            Instruction::Nop => {},
-            Instruction::Add{ offset, value } => {
-                let cell = &mut data.memory[(data.ptr + offset) as usize % len];
-                *cell = *cell + T::from(*value);
-            },
-            Instruction::Set{ offset, value } => {
-                let cell = &mut data.memory[(data.ptr + offset) as usize % len];
-                *cell = T::from(*value);
-            },
-            Instruction::MovePtr(offset) => {
-                data.ptr = data.ptr.wrapping_add(*offset);
-            },
-            Instruction::Loop(instrs) => {
-                while data.memory[data.ptr as usize % len] != T::from(0) {
-                    run_instrs(instrs, data);
-                }
-            },
-            Instruction::Read(offset) => {
-                let cell = &mut data.memory[(data.ptr + offset) as usize % len];
-                cell.read(&mut io::stdin());
-            },
-            Instruction::Write(offset) => {
-                let cell = data.memory[(data.ptr + offset) as usize % len];
-                cell.write(&mut io::stdout());
-            },
-            Instruction::LinearLoop{ offset: glob_offset, factors } => {
-                //assert_eq!(factors.get(&0), Some(&-1));
-                let multiplicator = data.memory[((data.ptr + glob_offset) as usize) % len];
-                for (offset, value) in factors {
-                    let cell = &mut data.memory[(data.ptr + offset + glob_offset) as usize % len];
-                    *cell = *cell + (multiplicator * T::from(*value));
-                }
-                data.memory[((data.ptr + glob_offset) as usize) % len] = T::from(0);
-            },
-        }
-    }
-}
-
-
 fn run_with_funcs<T>(instructions: &Vec<Instruction>,
                  data: &mut Data<T>,
                  add: &dyn Fn(T, T) -> T,

+ 2 - 2
src/main.rs

@@ -1,6 +1,6 @@
 //#![feature(plugin)]
 //#![plugin(dynasm)]
-#![feature(proc_macro_hygiene)]
+//#![feature(proc_macro_hygiene)]
 #[macro_use]
 extern crate dynasm;
 
@@ -123,7 +123,7 @@ fn main() -> io::Result<()> {
                     println!("{}", code);
                 },
                 None => {
-                    let _code = compile::compile(&insts);
+                    let _code = compile::compile_and_run(&insts, &options);
                 }
             }
         }

+ 1 - 1
src/optimize.rs

@@ -154,7 +154,7 @@ impl<'a> ir::MutVisitor for DfgOptimizer<'a> {
 
 
 struct MemoryState {
-    cellStates: BTreeMap<i64, CellState>,
+    cell_states: BTreeMap<i64, CellState>,
     default_cell: CellState
 }
 

+ 1 - 1
src/options.rs

@@ -17,7 +17,7 @@ pub enum CellSize {
 
 pub struct Options {
     pub cell_layout: CellLayout,
-    pub memory_size: i64,
+    pub memory_size: usize,
     pub cell_size: CellSize,
 }