|
@@ -0,0 +1,159 @@
|
|
|
+use std::collections::HashMap;
|
|
|
+use std::fmt;
|
|
|
+use std::fs::File;
|
|
|
+
|
|
|
+enum UMOp {
|
|
|
+ ConditionalMove(u8, u8, u8),
|
|
|
+ ArrayIndex(u8, u8, u8),
|
|
|
+ ArrayAmend(u8, u8, u8),
|
|
|
+ Add(u8, u8, u8),
|
|
|
+ Mult(u8, u8, u8),
|
|
|
+ Div(u8, u8, u8),
|
|
|
+ NotAnd(u8, u8, u8),
|
|
|
+
|
|
|
+ Halt,
|
|
|
+ Allocate(u8, u8),
|
|
|
+ Abandon(u8),
|
|
|
+ Output(u8),
|
|
|
+ Input(u8),
|
|
|
+ Load(u8, u8),
|
|
|
+
|
|
|
+ Value(u8, u32),
|
|
|
+}
|
|
|
+
|
|
|
+const REGS: [&str; 8] = ["A", "B", "C", "D", "E", "F", "G", "H"];
|
|
|
+
|
|
|
+impl fmt::Display for UMOp {
|
|
|
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
+ let repr = match self {
|
|
|
+ UMOp::ConditionalMove(a, b, c) =>
|
|
|
+ format!("Conditional #{} <- {} ? #{} : #{}",
|
|
|
+ REGS[*a as usize],
|
|
|
+ REGS[*c as usize],
|
|
|
+ REGS[*b as usize],
|
|
|
+ REGS[*a as usize]),
|
|
|
+ UMOp::ArrayIndex(a, b, c) =>
|
|
|
+ format!("ArrIndex #{} <- #{}[#{}]",
|
|
|
+ REGS[*a as usize],
|
|
|
+ REGS[*b as usize],
|
|
|
+ REGS[*c as usize]),
|
|
|
+ UMOp::ArrayAmend(a, b, c) =>
|
|
|
+ format!("ArrAmend #{}[#{}] <- #{}",
|
|
|
+ REGS[*a as usize],
|
|
|
+ REGS[*b as usize],
|
|
|
+ REGS[*c as usize]),
|
|
|
+ UMOp::Add(a, b, c) =>
|
|
|
+ format!("Add #{} <- #{} + #{}",
|
|
|
+ REGS[*a as usize],
|
|
|
+ REGS[*b as usize],
|
|
|
+ REGS[*c as usize]),
|
|
|
+ UMOp::Mult(a, b, c) =>
|
|
|
+ format!("Mult #{} <- #{} * #{}",
|
|
|
+ REGS[*a as usize],
|
|
|
+ REGS[*b as usize],
|
|
|
+ REGS[*c as usize]),
|
|
|
+ UMOp::Div(a, b, c) =>
|
|
|
+ format!("Div #{} <- #{} / #{}",
|
|
|
+ REGS[*a as usize],
|
|
|
+ REGS[*b as usize],
|
|
|
+ REGS[*c as usize]),
|
|
|
+ UMOp::NotAnd(a, b, c) =>
|
|
|
+ format!("NotAnd #{} <- #{} !&& #{}",
|
|
|
+ REGS[*a as usize],
|
|
|
+ REGS[*b as usize],
|
|
|
+ REGS[*c as usize]),
|
|
|
+ UMOp::Halt =>
|
|
|
+ format!("Halt!"),
|
|
|
+ UMOp::Allocate(b, c) =>
|
|
|
+ format!("Alloc #{} <- [#{}]",
|
|
|
+ REGS[*b as usize],
|
|
|
+ REGS[*c as usize]),
|
|
|
+ UMOp::Abandon(c) =>
|
|
|
+ format!("Abandon @#{}",
|
|
|
+ REGS[*c as usize]),
|
|
|
+ UMOp::Output(c) =>
|
|
|
+ format!("Output #{}",
|
|
|
+ REGS[*c as usize]),
|
|
|
+ UMOp::Input(c) =>
|
|
|
+ format!("Output #{} <-",
|
|
|
+ REGS[*c as usize]),
|
|
|
+ UMOp::Load(b, c) =>
|
|
|
+ format!("Load <- #{}[#{}]",
|
|
|
+ REGS[*b as usize],
|
|
|
+ REGS[*c as usize]),
|
|
|
+ UMOp::Value(a, val) =>
|
|
|
+ format!("Value <- #{} <- $#{}",
|
|
|
+ REGS[*a as usize],
|
|
|
+ val),
|
|
|
+ };
|
|
|
+ write!(f, "{}", repr)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+fn num_extract(masks_map: &HashMap<&str, (u32,u32)>,
|
|
|
+ num: u32, mask_name: &str) -> u32 {
|
|
|
+ let masktup = masks_map.get(mask_name).unwrap();
|
|
|
+ (num & masktup.0) >> masktup.1
|
|
|
+}
|
|
|
+
|
|
|
+fn parse_instr(masks_map: HashMap<&str, (u32,u32)>,
|
|
|
+ instr: u32) -> UMOp {
|
|
|
+ let opcode = num_extract(&masks_map, instr, "op_mask");
|
|
|
+ let rega = num_extract(&masks_map, instr, "rega_mask") as u8;
|
|
|
+ let regb = num_extract(&masks_map, instr, "regb_mask") as u8;
|
|
|
+ let regc = num_extract(&masks_map, instr, "regc_mask") as u8;
|
|
|
+ let alta = num_extract(&masks_map, instr, "alta_mask") as u8;
|
|
|
+ let val = num_extract(&masks_map, instr, "val_mask");
|
|
|
+ match opcode {
|
|
|
+ 0 => UMOp::ConditionalMove(rega, regb, regc),
|
|
|
+ 1 => UMOp::ArrayIndex(rega, regb, regc),
|
|
|
+ 2 => UMOp::ArrayAmend(rega, regb, regc),
|
|
|
+ 3 => UMOp::Add(rega, regb, regc),
|
|
|
+ 4 => UMOp::Mult(rega, regb, regc),
|
|
|
+ 5 => UMOp::Div(rega, regb, regc),
|
|
|
+ 6 => UMOp::NotAnd(rega, regb, regc),
|
|
|
+ 7 => UMOp::Halt,
|
|
|
+ 8 => UMOp::Allocate(regb, regc),
|
|
|
+ 9 => UMOp::Abandon(regc),
|
|
|
+ 10 => UMOp::Output(regc),
|
|
|
+ 11 => UMOp::Input(regc),
|
|
|
+ 12 => UMOp::Load(regb, regc),
|
|
|
+ 13 => UMOp::Value(alta, val),
|
|
|
+ _ => panic!("Bad Instruction! ({})", instr)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+fn main() {
|
|
|
+
|
|
|
+ let mut masks_map: HashMap<&str, (u32,u32)> = HashMap::new();
|
|
|
+ masks_map.insert("op_mask", (0b11110000000000000000000000000000, 28));
|
|
|
+ masks_map.insert("rega_mask", (0b00000000000000000000000111000000, 6));
|
|
|
+ masks_map.insert("regb_mask", (0b00000000000000000000000000111000, 3));
|
|
|
+ masks_map.insert("regc_mask", (0b00000000000000000000000000000111, 0));
|
|
|
+ masks_map.insert("alta_mask", (0b00001110000000000000000000000000, 25));
|
|
|
+ masks_map.insert("val_mask", (0b00000001111111111111111111111111, 0));
|
|
|
+
|
|
|
+
|
|
|
+ let mut codexfile = File::open(&Path::new("codex.umz"))
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ let add_instr = 0b00110000000000000000000001010011;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ let full_op = parse_instr(masks_map, add_instr);
|
|
|
+
|
|
|
+
|
|
|
+ println!("Hello, world! - {}", full_op);
|
|
|
+}
|
|
|
+
|
|
|
+
|