CMP, CMPU, CMPI, CMPUI
This commit is contained in:
parent
d32b9e7fba
commit
e1499fd5a1
|
@ -1,7 +1,4 @@
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use lasso::Key;
|
|
||||||
|
|
||||||
use {
|
use {
|
||||||
lasso::{Rodeo, Spur},
|
lasso::{Rodeo, Spur},
|
||||||
logos::{Lexer, Logos, Span},
|
logos::{Lexer, Logos, Span},
|
||||||
|
@ -56,8 +53,8 @@ macro_rules! tokendef {
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
tokendef![
|
tokendef![
|
||||||
"nop", "add", "sub", "mul", "rem", "and", "or", "xor", "sl", "sr", "srs",
|
"nop", "add", "sub", "mul", "rem", "and", "or", "xor", "sl", "sr", "srs",
|
||||||
"not", "addf", "subf", "mulf", "divf", "addi", "muli", "remi", "andi",
|
"cmp", "cmpu", "not", "addf", "subf", "mulf", "divf", "addi", "muli", "remi", "andi",
|
||||||
"ori", "xori", "sli", "sri", "srsi", "addfi", "mulfi", "cp", "li", "lb",
|
"ori", "xori", "sli", "sri", "srsi", "cmpi", "cmpui", "addfi", "mulfi", "cp", "li", "lb",
|
||||||
"ld", "lq", "lo", "sb", "sd", "sq", "so", "jmp", "jeq", "jne", "jlt", "jgt",
|
"ld", "lq", "lo", "sb", "sd", "sq", "so", "jmp", "jeq", "jne", "jlt", "jgt",
|
||||||
"jltu", "jgtu", "ret", "ecall",
|
"jltu", "jgtu", "ret", "ecall",
|
||||||
];
|
];
|
||||||
|
@ -116,7 +113,7 @@ pub fn assembly(code: &str, buf: &mut Vec<u8>) -> Result<(), Error> {
|
||||||
self.buf.push(op);
|
self.buf.push(op);
|
||||||
match op {
|
match op {
|
||||||
NOP | RET | ECALL => Ok(()),
|
NOP | RET | ECALL => Ok(()),
|
||||||
ADD..=SRS | ADDF..=DIVF => self.rrr(),
|
ADD..=CMPU | ADDF..=DIVF => self.rrr(),
|
||||||
NOT | CP => self.rr(),
|
NOT | CP => self.rr(),
|
||||||
LI | JMP => self.ri(),
|
LI | JMP => self.ri(),
|
||||||
ADDI..=MULFI | LB..=SO | JEQ..=JGTU => self.rri(),
|
ADDI..=MULFI | LB..=SO | JEQ..=JGTU => self.rri(),
|
||||||
|
|
|
@ -11,58 +11,60 @@ macro_rules! constmod {
|
||||||
constmod!(pub opcode(u8) {
|
constmod!(pub opcode(u8) {
|
||||||
NOP = 0, // N; Do nothing
|
NOP = 0, // N; Do nothing
|
||||||
|
|
||||||
ADD = 1, // RRR; #0 ← #1 + #2
|
ADD = 1, // RRR; #0 ← #1 + #2
|
||||||
SUB = 2, // RRR; #0 ← #1 - #2
|
SUB = 2, // RRR; #0 ← #1 - #2
|
||||||
MUL = 3, // RRR; #0 ← #1 × #2
|
MUL = 3, // RRR; #0 ← #1 × #2
|
||||||
DIV = 4, // RRR; #0 ← #1 ÷ #2
|
DIV = 4, // RRR; #0 ← #1 ÷ #2
|
||||||
REM = 5, // RRR; #0 ← #1 % #2
|
REM = 5, // RRR; #0 ← #1 % #2
|
||||||
AND = 6, // RRR; #0 ← #1 & #2
|
AND = 6, // RRR; #0 ← #1 & #2
|
||||||
OR = 7, // RRR; #0 ← #1 | #2
|
OR = 7, // RRR; #0 ← #1 | #2
|
||||||
XOR = 8, // RRR; #0 ← #1 ^ #2
|
XOR = 8, // RRR; #0 ← #1 ^ #2
|
||||||
SL = 9, // RRR; #0 ← #1 « #2
|
SL = 9, // RRR; #0 ← #1 « #2
|
||||||
SR = 10, // RRR; #0 ← #1 » #2
|
SR = 10, // RRR; #0 ← #1 » #2
|
||||||
SRS = 11, // RRR; #0 ← #1 » #2 (signed)
|
SRS = 11, // RRR; #0 ← #1 » #2 (signed)
|
||||||
NOT = 12, // RR; #0 ← !#1
|
CMP = 12, // RRR; #0 ← #1 <=> #2
|
||||||
|
CMPU = 13, // RRR; #0 ← #1 <=> #2 (unsigned)
|
||||||
|
NOT = 14, // RR; #0 ← !#1
|
||||||
|
|
||||||
ADDF = 13, // RRR; #0 ← #1 +. #2
|
ADDF = 15, // RRR; #0 ← #1 +. #2
|
||||||
SUBF = 14, // RRR; #0 ← #1 +. #2
|
SUBF = 16, // RRR; #0 ← #1 +. #2
|
||||||
MULF = 15, // RRR; #0 ← #1 +. #2
|
MULF = 17, // RRR; #0 ← #1 +. #2
|
||||||
DIVF = 16, // 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
|
ADDFI = 30, // RRI; #0 ← #1 +. imm #2
|
||||||
MULI = 18, // RRI; #0 ← #1 × imm #2
|
MULFI = 31, // 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
|
|
||||||
|
|
||||||
SLI = 23, // RRI; #0 ← #1 « imm #2
|
CP = 32, // RR; Copy #0 ← #1
|
||||||
SRI = 24, // RRI; #0 ← #1 » imm #2
|
LI = 33, // RI; Load immediate, #0 ← imm #1
|
||||||
SRSI = 25, // RRI; #0 ← #1 » imm #2 (signed)
|
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
|
JMP = 42, // RI; Unconditional jump [#0 + imm #1]
|
||||||
MULFI = 27, // RRI; #0 ← #1 *. imm #2
|
JEQ = 43, // RRI; if #0 = #1 → jump imm #2
|
||||||
|
JNE = 44, // RRI; if #0 ≠ #1 → jump imm #2
|
||||||
CP = 28, // RR; Copy #0 ← #1
|
JLT = 45, // RRI; if #0 < #1 → jump imm #2
|
||||||
LI = 29, // RI; Load immediate, #0 ← imm #1
|
JGT = 46, // RRI; if #0 > #1 → jump imm #2
|
||||||
LB = 30, // RRI; Load byte (8 bits), #0 ← [#1 + imm #2]
|
JLTU = 47, // RRI; if #0 < #1 → jump imm #2 (unsigned)
|
||||||
LD = 31, // RRI; Load doublet (16 bits)
|
JGTU = 48, // RRI; if #0 > #1 → jump imm #2 (unsigned)
|
||||||
LQ = 32, // RRI; Load quadlet (32 bits)
|
RET = 49, // N; Return
|
||||||
LO = 33, // RRI; Load octlet (64 bits)
|
ECALL = 50, // N; Issue system call
|
||||||
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
|
|
||||||
});
|
});
|
||||||
|
|
||||||
#[repr(packed)]
|
#[repr(packed)]
|
||||||
|
|
|
@ -41,7 +41,7 @@ pub fn validate(mut program: &[u8]) -> Result<(), Error> {
|
||||||
// N
|
// N
|
||||||
[NOP | RET | ECALL, rest @ ..] => rest,
|
[NOP | RET | ECALL, rest @ ..] => rest,
|
||||||
// RRR
|
// RRR
|
||||||
[ADD..=SRS | ADDF..=DIVF, _, _, _, rest @ ..] => {
|
[ADD..=CMPU | ADDF..=DIVF, _, _, _, rest @ ..] => {
|
||||||
if let Some(n) = reg(&program[1..=3]) {
|
if let Some(n) = reg(&program[1..=3]) {
|
||||||
bail!(InvalidRegister, start, program, n + 1);
|
bail!(InvalidRegister, start, program, n + 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,9 @@ mod value;
|
||||||
macro_rules! param {
|
macro_rules! param {
|
||||||
($self:expr, $ty:ty) => {{
|
($self:expr, $ty:ty) => {{
|
||||||
assert_impl_one!($ty: OpParam);
|
assert_impl_one!($ty: OpParam);
|
||||||
let data = $self.program.as_ptr()
|
let data = $self
|
||||||
|
.program
|
||||||
|
.as_ptr()
|
||||||
.add($self.pc + 1)
|
.add($self.pc + 1)
|
||||||
.cast::<$ty>()
|
.cast::<$ty>()
|
||||||
.read();
|
.read();
|
||||||
|
@ -130,6 +132,20 @@ impl<'a> Vm<'a> {
|
||||||
SL => binary_op!(self, int, ops::Shl::shl),
|
SL => binary_op!(self, int, ops::Shl::shl),
|
||||||
SR => binary_op!(self, int, ops::Shr::shr),
|
SR => binary_op!(self, int, ops::Shr::shr),
|
||||||
SRS => binary_op!(self, sint, 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 => {
|
NOT => {
|
||||||
let param = param!(self, ParamRR);
|
let param = param!(self, ParamRR);
|
||||||
self.write_reg(param.0, (!self.read_reg(param.1).int()).into());
|
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),
|
SRSI => binary_op_imm!(self, sint, ops::Shr::shr),
|
||||||
ADDFI => binary_op_imm!(self, float, ops::Add::add),
|
ADDFI => binary_op_imm!(self, float, ops::Add::add),
|
||||||
MULFI => binary_op_imm!(self, float, ops::Mul::mul),
|
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 => {
|
CP => {
|
||||||
let param = param!(self, ParamRR);
|
let param = param!(self, ParamRR);
|
||||||
self.write_reg(param.0, self.read_reg(param.1));
|
self.write_reg(param.0, self.read_reg(param.1));
|
||||||
|
|
Loading…
Reference in a new issue