From e1499fd5a1672013bbf14ef2b4f2cb29904cd257 Mon Sep 17 00:00:00 2001 From: Erin Date: Fri, 9 Jun 2023 18:25:37 +0200 Subject: [PATCH] CMP, CMPU, CMPI, CMPUI --- hbasm/src/lib.rs | 11 ++--- hbbytecode/src/lib.rs | 98 ++++++++++++++++++++++--------------------- hbvm/src/validate.rs | 2 +- hbvm/src/vm/mod.rs | 29 ++++++++++++- 4 files changed, 83 insertions(+), 57 deletions(-) diff --git a/hbasm/src/lib.rs b/hbasm/src/lib.rs index d36a7c08..0cb18d86 100644 --- a/hbasm/src/lib.rs +++ b/hbasm/src/lib.rs @@ -1,7 +1,4 @@ -use std::collections::{HashMap, HashSet}; - -use lasso::Key; - +use std::collections::HashMap; use { lasso::{Rodeo, Spur}, logos::{Lexer, Logos, Span}, @@ -56,8 +53,8 @@ macro_rules! tokendef { #[rustfmt::skip] tokendef![ "nop", "add", "sub", "mul", "rem", "and", "or", "xor", "sl", "sr", "srs", - "not", "addf", "subf", "mulf", "divf", "addi", "muli", "remi", "andi", - "ori", "xori", "sli", "sri", "srsi", "addfi", "mulfi", "cp", "li", "lb", + "cmp", "cmpu", "not", "addf", "subf", "mulf", "divf", "addi", "muli", "remi", "andi", + "ori", "xori", "sli", "sri", "srsi", "cmpi", "cmpui", "addfi", "mulfi", "cp", "li", "lb", "ld", "lq", "lo", "sb", "sd", "sq", "so", "jmp", "jeq", "jne", "jlt", "jgt", "jltu", "jgtu", "ret", "ecall", ]; @@ -116,7 +113,7 @@ pub fn assembly(code: &str, buf: &mut Vec) -> Result<(), Error> { self.buf.push(op); match op { NOP | RET | ECALL => Ok(()), - ADD..=SRS | ADDF..=DIVF => self.rrr(), + ADD..=CMPU | ADDF..=DIVF => self.rrr(), NOT | CP => self.rr(), LI | JMP => self.ri(), ADDI..=MULFI | LB..=SO | JEQ..=JGTU => self.rri(), diff --git a/hbbytecode/src/lib.rs b/hbbytecode/src/lib.rs index 6e434ff2..eb13eda4 100644 --- a/hbbytecode/src/lib.rs +++ b/hbbytecode/src/lib.rs @@ -11,58 +11,60 @@ macro_rules! constmod { constmod!(pub opcode(u8) { NOP = 0, // N; Do nothing - ADD = 1, // RRR; #0 ← #1 + #2 - SUB = 2, // RRR; #0 ← #1 - #2 - MUL = 3, // RRR; #0 ← #1 × #2 - DIV = 4, // RRR; #0 ← #1 ÷ #2 - REM = 5, // RRR; #0 ← #1 % #2 - AND = 6, // RRR; #0 ← #1 & #2 - OR = 7, // RRR; #0 ← #1 | #2 - XOR = 8, // RRR; #0 ← #1 ^ #2 - SL = 9, // RRR; #0 ← #1 « #2 - SR = 10, // RRR; #0 ← #1 » #2 - SRS = 11, // RRR; #0 ← #1 » #2 (signed) - NOT = 12, // RR; #0 ← !#1 + ADD = 1, // RRR; #0 ← #1 + #2 + SUB = 2, // RRR; #0 ← #1 - #2 + MUL = 3, // RRR; #0 ← #1 × #2 + DIV = 4, // RRR; #0 ← #1 ÷ #2 + REM = 5, // RRR; #0 ← #1 % #2 + AND = 6, // RRR; #0 ← #1 & #2 + OR = 7, // RRR; #0 ← #1 | #2 + XOR = 8, // RRR; #0 ← #1 ^ #2 + SL = 9, // RRR; #0 ← #1 « #2 + SR = 10, // RRR; #0 ← #1 » #2 + SRS = 11, // RRR; #0 ← #1 » #2 (signed) + CMP = 12, // RRR; #0 ← #1 <=> #2 + CMPU = 13, // RRR; #0 ← #1 <=> #2 (unsigned) + NOT = 14, // RR; #0 ← !#1 - ADDF = 13, // RRR; #0 ← #1 +. #2 - SUBF = 14, // RRR; #0 ← #1 +. #2 - MULF = 15, // RRR; #0 ← #1 +. #2 - DIVF = 16, // RRR; #0 ← #1 +. #2 + ADDF = 15, // RRR; #0 ← #1 +. #2 + SUBF = 16, // RRR; #0 ← #1 +. #2 + MULF = 17, // RRR; #0 ← #1 +. #2 + DIVF = 18, // RRR; #0 ← #1 +. #2 + ADDI = 19, // RRI; #0 ← #1 + imm #2 + MULI = 20, // RRI; #0 ← #1 × imm #2 + REMI = 21, // RRI; #0 ← #1 % imm #2 + ANDI = 22, // RRI; #0 ← #1 & imm #2 + ORI = 23, // RRI; #0 ← #1 | imm #2 + XORI = 24, // RRI; #0 ← #1 ^ imm #2 + SLI = 25, // RRI; #0 ← #1 « imm #2 + SRI = 26, // RRI; #0 ← #1 » imm #2 + SRSI = 27, // RRI; #0 ← #1 » imm #2 (signed) + CMPI = 28, // RRI; #0 ← #1 <=> imm #2 + CMPUI = 29, // RRI; #0 ← #1 <=> imm #2 (unsigned) - ADDI = 17, // RRI; #0 ← #1 + imm #2 - MULI = 18, // RRI; #0 ← #1 × imm #2 - REMI = 19, // RRI; #0 ← #1 % imm #2 - ANDI = 20, // RRI; #0 ← #1 & imm #2 - ORI = 21, // RRI; #0 ← #1 | imm #2 - XORI = 22, // RRI; #0 ← #1 ^ imm #2 + ADDFI = 30, // RRI; #0 ← #1 +. imm #2 + MULFI = 31, // RRI; #0 ← #1 *. imm #2 - SLI = 23, // RRI; #0 ← #1 « imm #2 - SRI = 24, // RRI; #0 ← #1 » imm #2 - SRSI = 25, // RRI; #0 ← #1 » imm #2 (signed) + CP = 32, // RR; Copy #0 ← #1 + LI = 33, // RI; Load immediate, #0 ← imm #1 + LB = 34, // RRI; Load byte (8 bits), #0 ← [#1 + imm #2] + LD = 35, // RRI; Load doublet (16 bits) + LQ = 36, // RRI; Load quadlet (32 bits) + LO = 37, // RRI; Load octlet (64 bits) + SB = 38, // RRI; Store byte, [#1 + imm #2] ← #0 + SD = 39, // RRI; Store doublet + SQ = 40, // RRI; Store quadlet + SO = 41, // RRI; Store octlet - ADDFI = 26, // RRI; #0 ← #1 +. imm #2 - MULFI = 27, // RRI; #0 ← #1 *. imm #2 - - CP = 28, // RR; Copy #0 ← #1 - LI = 29, // RI; Load immediate, #0 ← imm #1 - LB = 30, // RRI; Load byte (8 bits), #0 ← [#1 + imm #2] - LD = 31, // RRI; Load doublet (16 bits) - LQ = 32, // RRI; Load quadlet (32 bits) - LO = 33, // RRI; Load octlet (64 bits) - SB = 34, // RRI; Store byte, [#1 + imm #2] ← #0 - SD = 35, // RRI; Store doublet - SQ = 36, // RRI; Store quadlet - SO = 37, // RRI; Store octlet - - JMP = 38, // RI; Unconditional jump [#0 + imm #1] - JEQ = 39, // RRI; if #0 = #1 → jump imm #2 - JNE = 40, // RRI; if #0 ≠ #1 → jump imm #2 - JLT = 41, // RRI; if #0 < #1 → jump imm #2 - JGT = 52, // RRI; if #0 > #1 → jump imm #2 - JLTU = 53, // RRI; if #0 < #1 → jump imm #2 (unsigned) - JGTU = 54, // RRI; if #0 > #1 → jump imm #2 (unsigned) - RET = 55, // N; Return - ECALL = 56, // N; Issue system call + JMP = 42, // RI; Unconditional jump [#0 + imm #1] + JEQ = 43, // RRI; if #0 = #1 → jump imm #2 + JNE = 44, // RRI; if #0 ≠ #1 → jump imm #2 + JLT = 45, // RRI; if #0 < #1 → jump imm #2 + JGT = 46, // RRI; if #0 > #1 → jump imm #2 + JLTU = 47, // RRI; if #0 < #1 → jump imm #2 (unsigned) + JGTU = 48, // RRI; if #0 > #1 → jump imm #2 (unsigned) + RET = 49, // N; Return + ECALL = 50, // N; Issue system call }); #[repr(packed)] diff --git a/hbvm/src/validate.rs b/hbvm/src/validate.rs index 1907b2c6..d58af8df 100644 --- a/hbvm/src/validate.rs +++ b/hbvm/src/validate.rs @@ -41,7 +41,7 @@ pub fn validate(mut program: &[u8]) -> Result<(), Error> { // N [NOP | RET | ECALL, rest @ ..] => rest, // RRR - [ADD..=SRS | ADDF..=DIVF, _, _, _, rest @ ..] => { + [ADD..=CMPU | ADDF..=DIVF, _, _, _, rest @ ..] => { if let Some(n) = reg(&program[1..=3]) { bail!(InvalidRegister, start, program, n + 1); } diff --git a/hbvm/src/vm/mod.rs b/hbvm/src/vm/mod.rs index bf47abb0..170874de 100644 --- a/hbvm/src/vm/mod.rs +++ b/hbvm/src/vm/mod.rs @@ -14,7 +14,9 @@ mod value; macro_rules! param { ($self:expr, $ty:ty) => {{ assert_impl_one!($ty: OpParam); - let data = $self.program.as_ptr() + let data = $self + .program + .as_ptr() .add($self.pc + 1) .cast::<$ty>() .read(); @@ -130,6 +132,20 @@ impl<'a> Vm<'a> { SL => binary_op!(self, int, ops::Shl::shl), SR => binary_op!(self, int, ops::Shr::shr), SRS => binary_op!(self, sint, ops::Shr::shr), + CMP => { + let ParamRRR(tg, a0, a1) = param!(self, ParamRRR); + self.write_reg( + tg, + (self.read_reg(a0).sint().cmp(&self.read_reg(a1).sint()) as i64).into(), + ); + } + CMPU => { + let ParamRRR(tg, a0, a1) = param!(self, ParamRRR); + self.write_reg( + tg, + (self.read_reg(a0).int().cmp(&self.read_reg(a1).int()) as i64).into(), + ); + } NOT => { let param = param!(self, ParamRR); self.write_reg(param.0, (!self.read_reg(param.1).int()).into()); @@ -149,6 +165,17 @@ impl<'a> Vm<'a> { SRSI => binary_op_imm!(self, sint, ops::Shr::shr), ADDFI => binary_op_imm!(self, float, ops::Add::add), MULFI => binary_op_imm!(self, float, ops::Mul::mul), + CMPI => { + let ParamRRI(tg, a0, imm) = param!(self, ParamRRI); + self.write_reg( + tg, + (self.read_reg(a0).sint().cmp(&Value::from(imm).sint()) as i64).into(), + ); + } + CMPUI => { + let ParamRRI(tg, a0, imm) = param!(self, ParamRRI); + self.write_reg(tg, (self.read_reg(a0).int().cmp(&imm) as i64).into()); + } CP => { let param = param!(self, ParamRR); self.write_reg(param.0, self.read_reg(param.1));