From 935d797fb23937409f4e8d77cf28c662b4114d9e Mon Sep 17 00:00:00 2001 From: GenshinImpactStarts <12211831@mail.sustech.edu.cn> Date: Tue, 16 Apr 2024 01:45:00 +0800 Subject: [PATCH 1/7] refactor(parser): prepare for other extension of RISCV --- .../modules/riscv/basic/interface/parser.rs | 4 +- .../src/modules/riscv/basic/parser/lexer.rs | 391 +----- .../src/modules/riscv/basic/parser/mod.rs | 6 +- .../src/modules/riscv/basic/parser/oplist.rs | 1092 +++-------------- .../src/modules/riscv/basic/parser/parser.rs | 101 +- src-tauri/src/modules/riscv/rv32i/mod.rs | 1 + .../src/modules/riscv/rv32i/parser/lexer.rs | 374 ++++++ .../src/modules/riscv/rv32i/parser/mod.rs | 2 + .../src/modules/riscv/rv32i/parser/oplist.rs | 619 ++++++++++ 9 files changed, 1272 insertions(+), 1318 deletions(-) create mode 100644 src-tauri/src/modules/riscv/rv32i/parser/lexer.rs create mode 100644 src-tauri/src/modules/riscv/rv32i/parser/mod.rs create mode 100644 src-tauri/src/modules/riscv/rv32i/parser/oplist.rs diff --git a/src-tauri/src/modules/riscv/basic/interface/parser.rs b/src-tauri/src/modules/riscv/basic/interface/parser.rs index 51ad8fa8..d4ff90fd 100644 --- a/src-tauri/src/modules/riscv/basic/interface/parser.rs +++ b/src-tauri/src/modules/riscv/basic/interface/parser.rs @@ -10,14 +10,14 @@ pub struct RISCV; pub type ParserRISCVInstOp = RISCVInstruction; -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, PartialEq)] pub enum ParserRISCVInstOpd { Reg(RISCVRegister), Imm(RISCVImmediate), Lbl(ParserRISCVLabel), } -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum ParserRISCVLabel { Text(usize), // ParserResult::text[usize] Data((usize, usize)), // ParserResult::data[usize][usize] diff --git a/src-tauri/src/modules/riscv/basic/parser/lexer.rs b/src-tauri/src/modules/riscv/basic/parser/lexer.rs index 71de2a4f..923f6f11 100644 --- a/src-tauri/src/modules/riscv/basic/parser/lexer.rs +++ b/src-tauri/src/modules/riscv/basic/parser/lexer.rs @@ -1,8 +1,12 @@ use super::super::interface::parser::{ParseRISCVRegisterError, RISCVCsr, RISCVRegister}; +use super::oplist::RISCVOpdSet; use crate::interface::parser::{ParserError, Pos}; use logos::Logos; use std::fmt::Display; +static EXTENSION: [fn(&str) -> Option<&'static dyn RISCVOpToken>; 1] = + [super::super::super::rv32i::parser::lexer::op_lexer]; + #[derive(Debug, PartialEq, Clone, Default)] pub enum LexingError { NumberParseError, @@ -11,6 +15,15 @@ pub enum LexingError { Other, } +pub enum Symbol<'a> { + Label(&'a str), + Op(&'static dyn RISCVOpToken), +} + +pub trait RISCVOpToken { + fn get_opd_set(&self) -> &Vec; +} + pub(super) struct LexerIter<'a> { pub raw: logos::Lexer<'a, RISCVToken<'a>>, } @@ -31,12 +44,10 @@ impl LexerIter<'_> { loop { match self.raw.next() { Some(unit) => match unit { - Ok(token) => { - if token == RISCVToken::Newline { - continue; - } - return Ok(Some(token)); - } + Ok(token) => match token { + RISCVToken::Newline => continue, + _ => return Ok(Some(token)), + }, Err(e) => return Err(self.get_error(e.to_string())), }, None => return Ok(None), @@ -67,9 +78,18 @@ impl LexerIter<'_> { } } -#[derive(Logos, Clone, Copy, Debug, PartialEq)] +fn dispatch_symbol(token: &str) -> Symbol { + for ext in &EXTENSION { + if let Some(op) = ext(token) { + return Symbol::Op(op); + } + } + Symbol::Label(token) +} + +#[derive(Logos)] #[logos(skip r"([ \t\f]+)|(#.*)", error = LexingError, extras = (usize, usize))] -pub(super) enum RISCVToken<'a> { +pub enum RISCVToken<'a> { #[token(",")] Comma, #[token("\n", |lex| lex.extras.0 += 1; lex.extras.1 = lex.span().end;)] @@ -87,8 +107,8 @@ pub(super) enum RISCVToken<'a> { ImmediateFloat(f64), #[regex("\"([^\\\\\"]*\\\\.)*\"")] ImmediateString(&'a str), - #[regex(r"[a-zA-Z_][a-zA-Z0-9_]*")] - Label(&'a str), + #[regex(r"[a-zA-Z_][a-zA-Z0-9_]*", |lex| dispatch_symbol(lex.slice()))] + Symbol(Symbol<'a>), #[regex(r"%[a-zA-Z_][a-zA-Z0-9_]*")] MacroParameter(&'a str), #[token("zero", |lex| lex.slice().parse(), priority = 10)] @@ -146,357 +166,6 @@ pub(super) enum RISCVToken<'a> { Word, #[regex(r"\.[a-zA-Z_][a-zA-Z0-9_]*")] UnknownDirective(&'a str), - #[token("add", |_| RISCVOpToken::Add, priority = 10)] - #[token("addi", |_| RISCVOpToken::Addi ,priority = 10)] - #[token("and", |_| RISCVOpToken::And ,priority = 10)] - #[token("andi", |_| RISCVOpToken::Andi ,priority = 10)] - #[token("auipc", |_| RISCVOpToken::Auipc ,priority = 10)] - #[token("beq", |_| RISCVOpToken::Beq ,priority = 10)] - #[token("bge", |_| RISCVOpToken::Bge ,priority = 10)] - #[token("bgeu", |_| RISCVOpToken::Bgeu ,priority = 10)] - #[token("blt", |_| RISCVOpToken::Blt ,priority = 10)] - #[token("bltu", |_| RISCVOpToken::Bltu ,priority = 10)] - #[token("bne", |_| RISCVOpToken::Bne ,priority = 10)] - #[token("csrrc", |_| RISCVOpToken::Csrrc ,priority = 10)] - #[token("csrrci", |_| RISCVOpToken::Csrrci ,priority = 10)] - #[token("csrrs", |_| RISCVOpToken::Csrrs ,priority = 10)] - #[token("csrrsi", |_| RISCVOpToken::Csrrsi ,priority = 10)] - #[token("csrrw", |_| RISCVOpToken::Csrrw ,priority = 10)] - #[token("csrrwi", |_| RISCVOpToken::Csrrwi ,priority = 10)] - #[token("div", |_| RISCVOpToken::Div ,priority = 10)] - #[token("divu", |_| RISCVOpToken::Divu ,priority = 10)] - #[token("ebreak", |_| RISCVOpToken::Ebreak ,priority = 10)] - #[token("ecall", |_| RISCVOpToken::Ecall ,priority = 10)] - // #[token("fadd.d", priority = 10)] - // #[token("fadd.s", priority = 10)] - // #[token("fclass.d", priority = 10)] - // #[token("fclass.s", priority = 10)] - // #[token("fcvt.d.s", priority = 10)] - // #[token("fcvt.d.w", priority = 10)] - // #[token("fcvt.d.wu", priority = 10)] - // #[token("fcvt.s.d", priority = 10)] - // #[token("fcvt.s.w", priority = 10)] - // #[token("fcvt.s.wu", priority = 10)] - // #[token("fcvt.w.d", priority = 10)] - // #[token("fcvt.w.s", priority = 10)] - // #[token("fcvt.wu.d", priority = 10)] - // #[token("fcvt.wu.s", priority = 10)] - // #[token("fdiv.d", priority = 10)] - // #[token("fdiv.s", priority = 10)] - // #[token("fence", priority = 10)] - // #[token("fence.i", priority = 10)] - // #[token("feq.d", priority = 10)] - // #[token("feq.s", priority = 10)] - // #[token("fld", priority = 10)] - // #[token("fle.d", priority = 10)] - // #[token("fle.s", priority = 10)] - // #[token("flt.d", priority = 10)] - // #[token("flt.s", priority = 10)] - // #[token("flw", priority = 10)] - // #[token("fmadd.d", priority = 10)] - // #[token("fmadd.s", priority = 10)] - // #[token("fmax.d", priority = 10)] - // #[token("fmax.s", priority = 10)] - // #[token("fmin.d", priority = 10)] - // #[token("fmin.s", priority = 10)] - // #[token("fmsub.d", priority = 10)] - // #[token("fmsub.s", priority = 10)] - // #[token("fmul.d", priority = 10)] - // #[token("fmul.s", priority = 10)] - // #[token("fmv.s.x", priority = 10)] - // #[token("fmv.x.s", priority = 10)] - // #[token("fnmadd.d", priority = 10)] - // #[token("fnmadd.s", priority = 10)] - // #[token("fnmsub.d", priority = 10)] - // #[token("fnmsub.s", priority = 10)] - // #[token("fsd", priority = 10)] - // #[token("fsgnj.d", priority = 10)] - // #[token("fsgnj.s", priority = 10)] - // #[token("fsgnjn.d", priority = 10)] - // #[token("fsgnjn.s", priority = 10)] - // #[token("fsgnjx.d", priority = 10)] - // #[token("fsgnjx.s", priority = 10)] - // #[token("fsqrt.d", priority = 10)] - // #[token("fsqrt.s", priority = 10)] - // #[token("fsub.d", priority = 10)] - // #[token("fsub.s", priority = 10)] - // #[token("fsw", priority = 10)] - #[token("jal", |_| RISCVOpToken::Jal, priority = 10)] - #[token("jalr", |_| RISCVOpToken::Jalr, priority = 10)] - #[token("lb", |_| RISCVOpToken::Lb, priority = 10)] - #[token("lbu", |_| RISCVOpToken::Lbu, priority = 10)] - #[token("lh", |_| RISCVOpToken::Lh, priority = 10)] - #[token("lhu", |_| RISCVOpToken::Lhu, priority = 10)] - #[token("lui", |_| RISCVOpToken::Lui, priority = 10)] - #[token("lw", |_| RISCVOpToken::Lw, priority = 10)] - #[token("mul", |_| RISCVOpToken::Mul, priority = 10)] - #[token("mulh", |_| RISCVOpToken::Mulh, priority = 10)] - #[token("mulhsu", |_| RISCVOpToken::Mulhsu, priority = 10)] - #[token("mulhu", |_| RISCVOpToken::Mulhu, priority = 10)] - #[token("or", |_| RISCVOpToken::Or, priority = 10)] - #[token("ori", |_| RISCVOpToken::Ori, priority = 10)] - #[token("rem", |_| RISCVOpToken::Rem, priority = 10)] - #[token("remu", |_| RISCVOpToken::Remu, priority = 10)] - #[token("sb", |_| RISCVOpToken::Sb, priority = 10)] - #[token("sh", |_| RISCVOpToken::Sh, priority = 10)] - #[token("sll", |_| RISCVOpToken::Sll, priority = 10)] - #[token("slli", |_| RISCVOpToken::Slli, priority = 10)] - #[token("slt", |_| RISCVOpToken::Slt, priority = 10)] - #[token("slti", |_| RISCVOpToken::Slti, priority = 10)] - #[token("sltiu", |_| RISCVOpToken::Sltiu, priority = 10)] - #[token("sltu", |_| RISCVOpToken::Sltu, priority = 10)] - #[token("sra", |_| RISCVOpToken::Sra, priority = 10)] - #[token("srai", |_| RISCVOpToken::Srai, priority = 10)] - #[token("srl", |_| RISCVOpToken::Srl, priority = 10)] - #[token("srli", |_| RISCVOpToken::Srli, priority = 10)] - #[token("sub", |_| RISCVOpToken::Sub, priority = 10)] - #[token("sw", |_| RISCVOpToken::Sw, priority = 10)] - #[token("uret", |_| RISCVOpToken::Uret, priority = 10)] - #[token("wfi", |_| RISCVOpToken::Wfi, priority = 10)] - #[token("xor", |_| RISCVOpToken::Xor, priority = 10)] - #[token("xori", |_| RISCVOpToken::Xori, priority = 10)] - #[token("b", |_| RISCVOpToken::B, priority = 10)] - #[token("beqz", |_| RISCVOpToken::Beqz, priority = 10)] - #[token("bgez", |_| RISCVOpToken::Bgez, priority = 10)] - #[token("bgt", |_| RISCVOpToken::Bgt, priority = 10)] - #[token("bgtu", |_| RISCVOpToken::Bgtu, priority = 10)] - #[token("bgtz", |_| RISCVOpToken::Bgtz, priority = 10)] - #[token("ble", |_| RISCVOpToken::Ble, priority = 10)] - #[token("bleu", |_| RISCVOpToken::Bleu, priority = 10)] - #[token("blez", |_| RISCVOpToken::Blez, priority = 10)] - #[token("bltz", |_| RISCVOpToken::Bltz, priority = 10)] - #[token("bnez", |_| RISCVOpToken::Bnez, priority = 10)] - #[token("call", |_| RISCVOpToken::Call, priority = 10)] - #[token("csrc", |_| RISCVOpToken::Csrc, priority = 10)] - #[token("csrci", |_| RISCVOpToken::Csrci, priority = 10)] - #[token("csrr", |_| RISCVOpToken::Csrr, priority = 10)] - #[token("csrs", |_| RISCVOpToken::Csrs, priority = 10)] - #[token("csrsi", |_| RISCVOpToken::Csrsi, priority = 10)] - #[token("csrw", |_| RISCVOpToken::Csrw, priority = 10)] - #[token("csrwi", |_| RISCVOpToken::Csrwi, priority = 10)] - // #[token("fabs.d", |_| RISCVOpToken::FabsD, priority = 10)] - // #[token("fabs.s", |_| RISCVOpToken::FabsS, priority = 10)] - // #[token("fge.d", |_| RISCVOpToken::FgeD, priority = 10)] - // #[token("fge.s", |_| RISCVOpToken::FgeS, priority = 10)] - // #[token("fgt.d", |_| RISCVOpToken::FgtD, priority = 10)] - // #[token("fgt.s", |_| RISCVOpToken::FgtS, priority = 10)] - // #[token("fmv.d", |_| RISCVOpToken::FmvD, priority = 10)] - // #[token("fmv.s", |_| RISCVOpToken::FmvS, priority = 10)] - // #[token("fmv.w.x", |_| RISCVOpToken::FmvWX, priority = 10)] - // #[token("fmv.x.w", |_| RISCVOpToken::FmvXW, priority = 10)] - // #[token("fneg.d", |_| RISCVOpToken::FnegD, priority = 10)] - // #[token("fneg.s", |_| RISCVOpToken::FnegS, priority = 10)] - // #[token("frcsr", |_| RISCVOpToken::Frcsr, priority = 10)] - // #[token("frflags", |_| RISCVOpToken::Frflags, priority = 10)] - // #[token("frrm", |_| RISCVOpToken::Frrm, priority = 10)] - // #[token("frsr", |_| RISCVOpToken::Frsr, priority = 10)] - // #[token("fsflags", |_| RISCVOpToken::Fsflags, priority = 10)] - // #[token("fsrm", |_| RISCVOpToken::Fsrm, priority = 10)] - // #[token("fsrr", |_| RISCVOpToken::Fsrr, priority = 10)] - #[token("j", |_| RISCVOpToken::J, priority = 10)] - #[token("jr", |_| RISCVOpToken::Jr, priority = 10)] - #[token("la", |_| RISCVOpToken::La, priority = 10)] - #[token("li", |_| RISCVOpToken::Li, priority = 10)] - #[token("mv", |_| RISCVOpToken::Mv, priority = 10)] - #[token("neg", |_| RISCVOpToken::Neg, priority = 10)] - #[token("nop", |_| RISCVOpToken::Nop, priority = 10)] - #[token("not", |_| RISCVOpToken::Not, priority = 10)] - #[token("rdcycle", |_| RISCVOpToken::Rdcycle, priority = 10)] - #[token("rdcycleh", |_| RISCVOpToken::Rdcycleh, priority = 10)] - #[token("rdinstret", |_| RISCVOpToken::Rdinstret, priority = 10)] - #[token("rdinstreth", |_| RISCVOpToken::Rdinstreth, priority = 10)] - #[token("rdtime", |_| RISCVOpToken::Rdtime, priority = 10)] - #[token("rdtimeh", |_| RISCVOpToken::Rdtimeh, priority = 10)] - #[token("ret", |_| RISCVOpToken::Ret, priority = 10)] - #[token("seqz", |_| RISCVOpToken::Seqz, priority = 10)] - #[token("sext.b", |_| RISCVOpToken::SextB, priority = 10)] - #[token("sext.h", |_| RISCVOpToken::SextH, priority = 10)] - #[token("sgt", |_| RISCVOpToken::Sgt, priority = 10)] - #[token("sgtu", |_| RISCVOpToken::Sgtu, priority = 10)] - #[token("sgtz", |_| RISCVOpToken::Sgtz, priority = 10)] - #[token("sltz", |_| RISCVOpToken::Sltz, priority = 10)] - #[token("snez", |_| RISCVOpToken::Snez, priority = 10)] - #[token("tail", |_| RISCVOpToken::Tail, priority = 10)] - #[token("zext.b", |_| RISCVOpToken::ZextB, priority = 10)] - #[token("zext.h", |_| RISCVOpToken::ZextH, priority = 10)] - Operator(RISCVOpToken), -} - -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -pub(super) enum RISCVOpToken { - Add, - Addi, - And, - Andi, - Auipc, - Beq, - Bge, - Bgeu, - Blt, - Bltu, - Bne, - Csrrc, - Csrrci, - Csrrs, - Csrrsi, - Csrrw, - Csrrwi, - Div, - Divu, - Ebreak, - Ecall, - FaddD, - FaddS, - FclassD, - FclassS, - FcvtDS, - FcvtDW, - FcvtDWu, - FcvtSD, - FcvtSW, - FcvtSWu, - FcvtWD, - FcvtWS, - FcvtWuD, - FcvtWuS, - FdivD, - FdivS, - Fence, - FenceI, - FeqD, - FeqS, - Fld, - FleD, - FleS, - FltD, - FltS, - Flw, - FmaddD, - FmaddS, - FmaxD, - FmaxS, - FminD, - FminS, - FmsubD, - FmsubS, - FmulD, - FmulS, - FmvSX, - FmvXS, - FnmaddD, - FnmaddS, - FnmsubD, - FnmsubS, - Fsd, - FsgnjD, - FsgnjS, - FsgnjnD, - FsgnjnS, - FsgnjxD, - FsgnjxS, - FsqrtD, - FsqrtS, - FsubD, - FsubS, - Fsw, - Jal, - Jalr, - Lb, - Lbu, - Lh, - Lhu, - Lui, - Lw, - Mul, - Mulh, - Mulhsu, - Mulhu, - Or, - Ori, - Rem, - Remu, - Sb, - Sh, - Sll, - Slli, - Slt, - Slti, - Sltiu, - Sltu, - Sra, - Srai, - Srl, - Srli, - Sub, - Sw, - Uret, - Wfi, - Xor, - Xori, - B, - Beqz, - Bgez, - Bgt, - Bgtu, - Bgtz, - Ble, - Bleu, - Blez, - Bltz, - Bnez, - Call, - Csrc, - Csrci, - Csrr, - Csrs, - Csrsi, - Csrw, - Csrwi, - FabsD, - FabsS, - FgeD, - FgeS, - FgtD, - FgtS, - FmvD, - FmvS, - FmvWX, - FmvXW, - FnegD, - FnegS, - Frcsr, - Frflags, - Frrm, - Frsr, - Fsflags, - Fsrm, - Fsrr, - J, - Jr, - La, - Li, - Mv, - Neg, - Nop, - Not, - Rdcycle, - Rdcycleh, - Rdinstret, - Rdinstreth, - Rdtime, - Rdtimeh, - Ret, - Seqz, - SextB, - SextH, - Sgt, - Sgtu, - Sgtz, - Sltz, - Snez, - Tail, - ZextB, - ZextH, } impl From for LexingError { diff --git a/src-tauri/src/modules/riscv/basic/parser/mod.rs b/src-tauri/src/modules/riscv/basic/parser/mod.rs index 03f1059b..c3d9781f 100644 --- a/src-tauri/src/modules/riscv/basic/parser/mod.rs +++ b/src-tauri/src/modules/riscv/basic/parser/mod.rs @@ -1,5 +1,5 @@ -mod label; -mod lexer; -mod r#macro; +pub(in super::super) mod label; +pub(in super::super) mod lexer; +pub(in super::super) mod r#macro; pub mod oplist; pub mod parser; diff --git a/src-tauri/src/modules/riscv/basic/parser/oplist.rs b/src-tauri/src/modules/riscv/basic/parser/oplist.rs index 5b385917..f337b8ea 100644 --- a/src-tauri/src/modules/riscv/basic/parser/oplist.rs +++ b/src-tauri/src/modules/riscv/basic/parser/oplist.rs @@ -1,12 +1,9 @@ use super::super::interface::parser::{ ParserRISCVInstOp, ParserRISCVInstOpd, RISCVImmediate, RISCVRegister, }; -use super::lexer::RISCVOpToken; -use lazy_static::lazy_static; -use std::collections::HashMap; #[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub(super) enum RISCVImmediateType { +pub enum RISCVImmediateType { U4, U5, U12, @@ -20,7 +17,7 @@ pub(super) enum RISCVImmediateType { } #[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub(super) enum RISCVExpectToken { +pub enum RISCVExpectToken { Comma, LParen, RParen, @@ -30,922 +27,213 @@ pub(super) enum RISCVExpectToken { Lbl, } -pub(super) struct RISCVOpdSetAimOpdIdx { +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct RISCVOpdSetAimOpdIdx { pub idx: usize, pub handler: fn(ParserRISCVInstOpd) -> ParserRISCVInstOpd, } -pub(super) enum RISCVOpdSetAimOpd { +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum RISCVOpdSetAimOpd { Idx(RISCVOpdSetAimOpdIdx), Val(ParserRISCVInstOpd), } -pub(super) struct RISCVOpdSetAim { +#[derive(Clone, Debug)] +pub struct RISCVOpdSetAim { pub op: ParserRISCVInstOp, pub opds: Vec, } -pub(super) struct RISCVOpdSet { - pub hint: &'static str, +#[derive(Clone, Debug)] +pub struct RISCVOpdSet { + pub hint: String, pub tokens: Vec, pub aim_basics: Vec, } -use RISCVExpectToken::*; -use RISCVImmediateType::*; -use RISCVRegister::*; -macro_rules! idx_def { - ($idx:expr) => { - RISCVOpdSetAimOpd::Idx(RISCVOpdSetAimOpdIdx { - idx: $idx, - handler: |opd| opd, - }) - }; -} -macro_rules! idx_low { - ($idx:expr) => { - RISCVOpdSetAimOpd::Idx(RISCVOpdSetAimOpdIdx { - idx: $idx, - handler: |opd| { - if let ParserRISCVInstOpd::Imm(RISCVImmediate::Int(i)) = opd { - if i & 0x800 != 0 { - return ParserRISCVInstOpd::Imm(RISCVImmediate::Int(-(i & 0x7ff))); - } else { - return ParserRISCVInstOpd::Imm(RISCVImmediate::Int(i & 0x7ff)); - } - } else { - return opd; - } - }, - }) - }; -} -macro_rules! idx_high { - ($idx:expr) => { - RISCVOpdSetAimOpd::Idx(RISCVOpdSetAimOpdIdx { - idx: $idx, - handler: |opd| { - if let ParserRISCVInstOpd::Imm(RISCVImmediate::Int(i)) = opd { - if i & 0x800 != 0 { - return ParserRISCVInstOpd::Imm(RISCVImmediate::Int( - ((i as u32 + 0x0000_1000) >> 12) as i128, - )); - } else { - return ParserRISCVInstOpd::Imm(RISCVImmediate::Int( - ((i as u32) >> 12) as i128, - )); - } - } else { - return opd; - } - }, - }) - }; -} -macro_rules! val_reg { - ($reg:expr) => { - RISCVOpdSetAimOpd::Val(ParserRISCVInstOpd::Reg($reg)) - }; -} -macro_rules! val_imm_i { - ($imm:expr) => { - RISCVOpdSetAimOpd::Val(ParserRISCVInstOpd::Imm(RISCVImmediate::Int($imm))) - }; -} -macro_rules! val_imm_f { - ($imm:expr) => { - RISCVOpdSetAimOpd::Val(ParserRISCVInstOpd::Imm(RISCVImmediate::Float($imm))) - }; -} +pub use RISCVExpectToken::*; +pub use RISCVImmediateType::*; +pub use RISCVRegister::*; -macro_rules! reg_reg_any_set_tmpl { - ($inst:expr, $name:expr, $op:expr, $last_opd:expr, $last_opd_str:expr, $descr:expr, $opds:expr) => { - RISCVOpdSet { - hint: concat!($name, " t1, t2, ", $last_opd_str, " (", $descr, ")"), - tokens: vec![Reg, Comma, Reg, Comma, $last_opd], - aim_basics: vec![RISCVOpdSetAim { - op: $inst, - opds: $opds, - }], +// --------------------reg------------------------- +pub fn reg(reg: RISCVRegister) -> RISCVOpdSetAimOpd { + RISCVOpdSetAimOpd::Val(ParserRISCVInstOpd::Reg(reg)) +} +// --------------------imm------------------------- +pub fn imm_i(imm: i128) -> RISCVOpdSetAimOpd { + RISCVOpdSetAimOpd::Val(ParserRISCVInstOpd::Imm(RISCVImmediate::Int(imm))) +} +pub fn imm_f(imm: f64) -> RISCVOpdSetAimOpd { + RISCVOpdSetAimOpd::Val(ParserRISCVInstOpd::Imm(RISCVImmediate::Float(imm))) +} +// --------------------idx------------------------- +pub fn idx(idx: usize) -> RISCVOpdSetAimOpd { + idx_handler(idx, |opd| opd) +} +pub fn idx_handler( + idx: usize, + handler: fn(ParserRISCVInstOpd) -> ParserRISCVInstOpd, +) -> RISCVOpdSetAimOpd { + RISCVOpdSetAimOpd::Idx(RISCVOpdSetAimOpdIdx { idx, handler }) +} +pub fn idx_handler_low(opd: ParserRISCVInstOpd) -> ParserRISCVInstOpd { + if let ParserRISCVInstOpd::Imm(RISCVImmediate::Int(i)) = opd { + if i & 0x800 != 0 { + ParserRISCVInstOpd::Imm(RISCVImmediate::Int(-(i & 0x7ff))) + } else { + ParserRISCVInstOpd::Imm(RISCVImmediate::Int(i & 0x7ff)) } - }; -} -macro_rules! reg_reg_any_set { - ($inst:expr, $name:expr, $op:expr, $last_opd:expr, $last_opd_str:expr) => { - reg_reg_any_set!( - $inst, - $name, - $op, - $last_opd, - $last_opd_str, - concat!("t1 = t2 ", $op, " ", $last_opd_str) - ) - }; - ($inst:expr, $name:expr, $op:expr, $last_opd:expr, $last_opd_str:expr, $descr:expr) => { - reg_reg_any_set_tmpl!( - $inst, - $name, - $op, - $last_opd, - $last_opd_str, - $descr, - vec![idx_def!(0), idx_def!(2), idx_def!(4)] - ) - }; -} -macro_rules! reg_reg_any_inv_set { - ($inst:expr, $name:expr, $op:expr, $last_opd:expr, $last_opd_str:expr) => { - reg_reg_any_set!( - $inst, - $name, - $op, - $last_opd, - $last_opd_str, - concat!("t1 = ", $last_opd_str, " ", $op, " t2") - ) - }; - ($inst:expr, $name:expr, $op:expr, $last_opd:expr, $last_opd_str:expr, $descr:expr) => { - reg_reg_any_set_tmpl!( - $inst, - $name, - $op, - $last_opd, - $last_opd_str, - $descr, - vec![idx_def!(2), idx_def!(0), idx_def!(4)] - ) - }; -} -macro_rules! reg_reg_reg_set { - ($inst:expr, $name:expr, $op:expr) => { - reg_reg_any_set!($inst, $name, $op, Reg, "t3") - }; - ($inst:expr, $name:expr, $op:expr, $reg_name:expr) => { - reg_reg_any_set!($inst, $name, $op, Reg, $reg_name) - }; - ($inst:expr, $name:expr, $op:expr, $reg_name:expr, $descr:expr) => { - reg_reg_any_set!($inst, $name, $op, Reg, $reg_name, $descr) - }; -} -macro_rules! reg_reg_reg_inv_set { - ($inst:expr, $name:expr, $op:expr) => { - reg_reg_any_inv_set!($inst, $name, $op, Reg, "t3") - }; - ($inst:expr, $name:expr, $op:expr, $reg_name:expr) => { - reg_reg_any_inv_set!($inst, $name, $op, Reg, $reg_name) - }; - ($inst:expr, $name:expr, $op:expr, $reg_name:expr, $descr:expr) => { - reg_reg_any_inv_set!($inst, $name, $op, Reg, $reg_name, $descr) - }; -} -macro_rules! no_opd_set { - ($inst:expr, $name:expr) => { - RISCVOpdSet { - hint: $name, - tokens: vec![], - aim_basics: vec![RISCVOpdSetAim { - op: $inst, - opds: vec![], - }], + } else { + opd + } +} +pub fn idx_handler_high(opd: ParserRISCVInstOpd) -> ParserRISCVInstOpd { + if let ParserRISCVInstOpd::Imm(RISCVImmediate::Int(i)) = opd { + if i & 0x800 != 0 { + ParserRISCVInstOpd::Imm(RISCVImmediate::Int( + ((i as u32 + 0x0000_1000) >> 12) as i128, + )) + } else { + ParserRISCVInstOpd::Imm(RISCVImmediate::Int(((i as u32) >> 12) as i128)) } - }; -} -macro_rules! branch_vec_tmpl { - ($inst:expr, $name:expr, $type:expr, $opds:expr, $sign:expr) => { - vec![RISCVOpdSet { - hint: concat!( - $name, - " t1, t2, label (if t1 ", - $type, - " t2 goto label)", - $sign - ), - tokens: vec![Reg, Comma, Reg, Comma, Lbl], - aim_basics: vec![RISCVOpdSetAim { - op: $inst, - opds: $opds, - }], - }] - }; - ($inst:expr, $name:expr, $type:expr, $opds:expr, $sign:expr, $place_holder:expr) => { - vec![RISCVOpdSet { - hint: concat!($name, " t1, label (if t1 ", $type, " 0 goto label)", $sign), - tokens: vec![Reg, Comma, Lbl], - aim_basics: vec![RISCVOpdSetAim { - op: $inst, - opds: $opds, - }], - }] - }; -} -macro_rules! branch_vec { - ($inst:expr, $name:expr, $type:expr, $sign:expr) => { - branch_vec_tmpl!( - $inst, - $name, - $type, - vec![idx_def!(0), idx_def!(2), idx_def!(4)], - $sign - ) - }; -} -macro_rules! branch_inv_vec { - ($inst:expr, $name:expr, $type:expr, $sign:expr) => { - branch_vec_tmpl!( - $inst, - $name, - $type, - vec![idx_def!(2), idx_def!(0), idx_def!(4)], - $sign - ) - }; -} -macro_rules! branch_zero_vec { - ($inst:expr, $name:expr, $type:expr, $sign:expr) => { - branch_vec_tmpl!( - $inst, - $name, - $type, - vec![idx_def!(0), val_reg!(Zero), idx_def!(2)], - $sign, - () - ) - }; -} -macro_rules! branch_zero_inv_vec { - ($inst:expr, $name:expr, $type:expr, $sign:expr) => { - branch_vec_tmpl!( - $inst, - $name, - $type, - vec![val_reg!(Zero), idx_def!(0), idx_def!(0)], - $sign, - () - ) - }; -} -macro_rules! csr_vec { - ($inst:expr, $name:expr, $type:expr, $last_opd:expr, $last_opd_str:expr) => { - vec![RISCVOpdSet { - hint: concat!( - $name, - " t1, csr, ", - $last_opd_str, - " (t1 = csr; csr ", - $type, - $last_opd_str - ), - tokens: vec![Reg, Comma, Csr, Comma, $last_opd], - aim_basics: vec![RISCVOpdSetAim { - op: $inst, - opds: vec![idx_def!(0), idx_def!(2), idx_def!(4)], - }], - }] - }; -} -macro_rules! sl_mem_vec_tmpl { - ($inst:expr, $name:expr, $type:expr, $dst0:expr, $dst1:expr, $dst2:expr, $dst3:expr, $dst4:expr, $src0:expr, $src1:expr, $src2:expr, $src3:expr,$src4:expr) => { - vec![ - RISCVOpdSet { - hint: concat!($name, " t1, -0x1(t2) (", $dst0, " = ", $type, $src0, ")"), - tokens: vec![Reg, Comma, Imm(I12), LParen, Reg, RParen], - aim_basics: vec![RISCVOpdSetAim { - op: $inst, - opds: vec![idx_def!(0), idx_def!(2), idx_def!(4)], - }], - }, - RISCVOpdSet { - hint: concat!($name, " t1, (t2) (", $dst1, " = ", $type, $src1, ")"), - tokens: vec![Reg, Comma, LParen, Reg, RParen], - aim_basics: vec![RISCVOpdSetAim { - op: $inst, - opds: vec![idx_def!(0), val_imm_i!(0), idx_def!(3)], - }], - }, - RISCVOpdSet { - hint: concat!($name, " t1, -0x1 (", $dst2, " = ", $type, $src2, ")"), - tokens: vec![Reg, Comma, Imm(I12)], - aim_basics: vec![RISCVOpdSetAim { - op: $inst, - opds: vec![idx_def!(0), idx_def!(2), val_reg!(Zero)], - }], - }, - RISCVOpdSet { - hint: concat!( - $name, - " t1, 0x100000 (a0 = 0x100000[12:31](i32); ", - $dst3, - " = ", - $type, - $src3, - ")" - ), - tokens: vec![Reg, Comma, Imm(I32)], - aim_basics: vec![ - RISCVOpdSetAim { - op: ParserRISCVInstOp::Lui, - opds: vec![val_reg!(A0), idx_high!(2)], - }, - RISCVOpdSetAim { - op: $inst, - opds: vec![idx_def!(0), idx_low!(2), val_reg!(A0)], - }, - ], - }, - RISCVOpdSet { - hint: concat!($name, " t1, label (", $dst4, " = ", $type, $src4, ")"), - tokens: vec![Reg, Comma, Lbl], - aim_basics: vec![RISCVOpdSetAim { - op: $inst, - opds: vec![idx_def!(0), idx_def!(2)], - }], - }, - ] - }; -} -macro_rules! load_mem_vec { - ($inst:expr, $name:expr, $type:expr) => { - sl_mem_vec_tmpl!( - $inst, - $name, - $type, - "t1", - "t1", - "t1", - "t1", - "t1", - "mem[t2 + -0x1(i12)]", - "mem[t2]", - "mem[-0x1(i12)]", - "mem[a0 + 0x100000[0:11](i32)]", - "mem[label]" - ) - }; -} -macro_rules! store_mem_vec { - ($inst:expr, $name:expr, $type:expr) => { - sl_mem_vec_tmpl!( - $inst, - $name, - $type, - "mem[t2 + -0x1(i12)]", - "mem[t2]", - "mem[-0x1(i12)]", - "mem[a0 + 0x100000[0:11](i32)]", - "mem[label]", - "t1", - "t1", - "t1", - "t1", - "t1" - ) - }; -} - -lazy_static! { - pub(super) static ref OP_LIST: HashMap> = HashMap::from([ - ( - RISCVOpToken::Add, - vec![reg_reg_reg_set!(ParserRISCVInstOp::Add, "add", "+")] - ), - ( - RISCVOpToken::Addi, - vec![ - reg_reg_any_set!(ParserRISCVInstOp::Addi, "addi", "+", Imm(I12), "-0x1(i12)"), - reg_reg_any_set!(ParserRISCVInstOp::Addi, "addi", "+", Lbl, "label[0:11]"), - ] - ), - ( - RISCVOpToken::And, - vec![reg_reg_reg_set!(ParserRISCVInstOp::And, "and", "&")] - ), - ( - RISCVOpToken::Andi, - vec![reg_reg_any_set!( - ParserRISCVInstOp::Andi, - "andi", - "&", - Imm(U12), - "0x1(u12)" - )] - ), - ( - RISCVOpToken::Auipc, - vec![RISCVOpdSet { - hint: "auipc t1, 0x1000 (t1 = pc + 0x1000(u20))", - tokens: vec![Reg, Comma, Imm(U20)], - aim_basics: vec![RISCVOpdSetAim { - op: ParserRISCVInstOp::Auipc, - opds: vec![idx_def!(0), idx_def!(2)], - }], - }] - ), - ( - RISCVOpToken::Beq, - branch_vec!(ParserRISCVInstOp::Beq, "beq", "==", " (signed)") - ), - ( - RISCVOpToken::Bge, - branch_vec!(ParserRISCVInstOp::Bge, "bge", ">=", " (signed)") - ), - ( - RISCVOpToken::Bgeu, - branch_vec!(ParserRISCVInstOp::Bgeu, "bgeu", ">=", " (unsigned)") - ), - ( - RISCVOpToken::Blt, - branch_vec!(ParserRISCVInstOp::Blt, "blt", "<", " (signed)") - ), - ( - RISCVOpToken::Bltu, - branch_vec!(ParserRISCVInstOp::Bltu, "bltu", "<", " (unsigned)") - ), - ( - RISCVOpToken::Bne, - branch_vec!(ParserRISCVInstOp::Bne, "bne", "!=", " (signed)") - ), - ( - RISCVOpToken::Csrrc, - csr_vec!(ParserRISCVInstOp::Csrrc, "csrrc", "&= ~", Reg, "t2") - ), - ( - RISCVOpToken::Csrrci, - csr_vec!( - ParserRISCVInstOp::Csrrci, - "csrrci", - "&= ~", - Imm(U5), - "0x1(u5)" - ) - ), - ( - RISCVOpToken::Csrrs, - csr_vec!(ParserRISCVInstOp::Csrrs, "csrrs", "|= ", Reg, "t2") - ), - ( - RISCVOpToken::Csrrsi, - csr_vec!( - ParserRISCVInstOp::Csrrsi, - "csrrsi", - "|= ", - Imm(U5), - "0x1(u5)" - ) - ), - ( - RISCVOpToken::Csrrw, - csr_vec!(ParserRISCVInstOp::Csrrw, "csrrw", "= ", Reg, "t2") - ), - ( - RISCVOpToken::Csrrwi, - csr_vec!( - ParserRISCVInstOp::Csrrwi, - "csrrwi", - "= ", - Imm(U5), - "0x1(u5)" - ) - ), - (RISCVOpToken::Div, vec![]), - (RISCVOpToken::Divu, vec![]), - ( - RISCVOpToken::Ebreak, - vec![no_opd_set!(ParserRISCVInstOp::Ebreak, "ebreak")] - ), - ( - RISCVOpToken::Ecall, - vec![no_opd_set!(ParserRISCVInstOp::Ecall, "ecall")] - ), - (RISCVOpToken::FaddD, vec![]), - (RISCVOpToken::FaddS, vec![]), - (RISCVOpToken::FclassD, vec![]), - (RISCVOpToken::FclassS, vec![]), - (RISCVOpToken::FcvtDS, vec![]), - (RISCVOpToken::FcvtDW, vec![]), - (RISCVOpToken::FcvtDWu, vec![]), - (RISCVOpToken::FcvtSD, vec![]), - (RISCVOpToken::FcvtSW, vec![]), - (RISCVOpToken::FcvtSWu, vec![]), - (RISCVOpToken::FcvtWD, vec![]), - (RISCVOpToken::FcvtWS, vec![]), - (RISCVOpToken::FcvtWuD, vec![]), - (RISCVOpToken::FcvtWuS, vec![]), - (RISCVOpToken::FdivD, vec![]), - (RISCVOpToken::FdivS, vec![]), - ( - RISCVOpToken::Fence, - vec![RISCVOpdSet { - hint: "fence 0x1(u4), 0x1(u4)", - tokens: vec![Imm(U4), Comma, Imm(U4)], - aim_basics: vec![RISCVOpdSetAim { - op: ParserRISCVInstOp::Fence, - opds: vec![idx_def!(0), idx_def!(2)], - }], - }] - ), - ( - RISCVOpToken::FenceI, - vec![no_opd_set!(ParserRISCVInstOp::FenceI, "fence.i")] - ), - (RISCVOpToken::FeqD, vec![]), - (RISCVOpToken::FeqS, vec![]), - (RISCVOpToken::Fld, vec![]), - (RISCVOpToken::FleD, vec![]), - (RISCVOpToken::FleS, vec![]), - (RISCVOpToken::FltD, vec![]), - (RISCVOpToken::FltS, vec![]), - (RISCVOpToken::Flw, vec![]), - (RISCVOpToken::FmaddD, vec![]), - (RISCVOpToken::FmaddS, vec![]), - (RISCVOpToken::FmaxD, vec![]), - (RISCVOpToken::FmaxS, vec![]), - (RISCVOpToken::FminD, vec![]), - (RISCVOpToken::FminS, vec![]), - (RISCVOpToken::FmsubD, vec![]), - (RISCVOpToken::FmsubS, vec![]), - (RISCVOpToken::FmulD, vec![]), - (RISCVOpToken::FmulS, vec![]), - (RISCVOpToken::FmvSX, vec![]), - (RISCVOpToken::FmvXS, vec![]), - (RISCVOpToken::FnmaddD, vec![]), - (RISCVOpToken::FnmaddS, vec![]), - (RISCVOpToken::FnmsubD, vec![]), - (RISCVOpToken::FnmsubS, vec![]), - (RISCVOpToken::Fsd, vec![]), - (RISCVOpToken::FsgnjD, vec![]), - (RISCVOpToken::FsgnjS, vec![]), - (RISCVOpToken::FsgnjnD, vec![]), - (RISCVOpToken::FsgnjnS, vec![]), - (RISCVOpToken::FsgnjxD, vec![]), - (RISCVOpToken::FsgnjxS, vec![]), - (RISCVOpToken::FsqrtD, vec![]), - (RISCVOpToken::FsqrtS, vec![]), - (RISCVOpToken::FsubD, vec![]), - (RISCVOpToken::FsubS, vec![]), - (RISCVOpToken::Fsw, vec![]), - ( - RISCVOpToken::Jal, - vec![ - RISCVOpdSet { - hint: "jal label (ra = pc + 4; pc = label)", - tokens: vec![Lbl], - aim_basics: vec![RISCVOpdSetAim { - op: ParserRISCVInstOp::Jal, - opds: vec![val_reg!(Ra), idx_def!(0)], - }], - }, - RISCVOpdSet { - hint: "jal t1, label (t1 = pc + 4; pc = label)", - tokens: vec![Reg, Comma, Lbl], - aim_basics: vec![RISCVOpdSetAim { - op: ParserRISCVInstOp::Jal, - opds: vec![idx_def!(0), idx_def!(2)], - }], - }, - ] - ), - ( - RISCVOpToken::Jalr, - vec![ - RISCVOpdSet { - hint: "jalr t1, t2, -0x1 (t1 = pc + 4; pc = t2 + -0x1(i12))", - tokens: vec![Reg, Comma, Reg, Comma, Imm(I12)], - aim_basics: vec![RISCVOpdSetAim { - op: ParserRISCVInstOp::Jalr, - opds: vec![idx_def!(0), idx_def!(2), idx_def!(4)], - }], - }, - RISCVOpdSet { - hint: "jalr t0 (ra = pc + 4; pc = t0)", - tokens: vec![Reg], - aim_basics: vec![RISCVOpdSetAim { - op: ParserRISCVInstOp::Jalr, - opds: vec![val_reg!(Ra), idx_def!(0), val_imm_i!(0)], - }], - }, - RISCVOpdSet { - hint: "jalr t1, -0x1 (ra = pc + 4; pc = t1 + -0x1(i12))", - tokens: vec![Reg, Comma, Imm(I12)], - aim_basics: vec![RISCVOpdSetAim { - op: ParserRISCVInstOp::Jalr, - opds: vec![val_reg!(Ra), idx_def!(0), idx_def!(2)], - }], - }, - RISCVOpdSet { - hint: "jalr t1, -0x1(t2) (t1 = pc + 4; pc = t2 + -0x1(i12))", - tokens: vec![Reg, Comma, Imm(I12), LParen, Reg, RParen], - aim_basics: vec![RISCVOpdSetAim { - op: ParserRISCVInstOp::Jalr, - opds: vec![idx_def!(0), idx_def!(4), idx_def!(2)], - }], - }, - ] - ), - ( - RISCVOpToken::Lb, - load_mem_vec!(ParserRISCVInstOp::Lb, "lb", "(i8)") - ), - ( - RISCVOpToken::Lbu, - load_mem_vec!(ParserRISCVInstOp::Lbu, "lbu", "(u8)") - ), - ( - RISCVOpToken::Lh, - load_mem_vec!(ParserRISCVInstOp::Lh, "lh", "(i16)") - ), - ( - RISCVOpToken::Lhu, - load_mem_vec!(ParserRISCVInstOp::Lhu, "lhu", "(u16)") - ), - ( - RISCVOpToken::Lui, + } else { + opd + } +} +// --------------------expect------------------------- +pub fn expect_opd(opds: Vec) -> Vec { + opds +} +pub fn expect_reg_any(any: RISCVExpectToken) -> Vec { + expect_opd(vec![Reg, Comma, any]) +} +pub fn expect_reg_reg() -> Vec { + expect_reg_any(Reg) +} +pub fn expect_reg_reg_any(any: RISCVExpectToken) -> Vec { + expect_opd(vec![Reg, Comma, Reg, Comma, any]) +} +pub fn expect_reg_reg_reg() -> Vec { + expect_reg_reg_any(Reg) +} +pub fn expect_csr(last_opd: RISCVExpectToken) -> Vec { + expect_opd(vec![Reg, Comma, Csr, Comma, last_opd]) +} +// --------------------basic------------------------- +pub fn basic_op(op: ParserRISCVInstOp, opds: Vec) -> RISCVOpdSetAim { + RISCVOpdSetAim { op, opds } +} +pub fn basic_op_02(op: ParserRISCVInstOp) -> RISCVOpdSetAim { + basic_op(op, vec![idx(0), idx(2)]) +} +pub fn basic_op_20(op: ParserRISCVInstOp) -> RISCVOpdSetAim { + basic_op(op, vec![idx(2), idx(0)]) +} +pub fn basic_op_024(op: ParserRISCVInstOp) -> RISCVOpdSetAim { + basic_op(op, vec![idx(0), idx(2), idx(4)]) +} +pub fn basic_op_042(op: ParserRISCVInstOp) -> RISCVOpdSetAim { + basic_op(op, vec![idx(0), idx(4), idx(2)]) +} +pub fn basic_op_204(op: ParserRISCVInstOp) -> RISCVOpdSetAim { + basic_op(op, vec![idx(2), idx(0), idx(4)]) +} +// --------------------hint------------------------- +pub fn hint_reg_reg_any(name: &str, any: &str, op: &str) -> String { + format!("{} t1, t2, {} (t1 = t2 {} {})", name, any, op, any) +} +pub fn hint_reg_reg_reg(name: &str, op: &str) -> String { + hint_reg_reg_any(name, "t3", op) +} +pub fn hint_branch(name: &str, cmp: &str, sign: &str) -> String { + format!( + "{} t1, t2, label (if t1 {} t2 goto label){}", + name, cmp, sign + ) +} +pub fn hint_branch_zero(name: &str, cmp: &str, sign: &str) -> String { + format!("{} t1, label (if t1 {} 0 goto label){}", name, cmp, sign) +} +pub fn hint_csr(name: &str, op: &str, last_opd: &str) -> String { + format!( + "{} t1, csr, {} (t1 = csr; csr {}{})", + name, last_opd, op, last_opd + ) +} +pub fn hint_set_comparison(op: &str, last_opd: &str, signed: &str) -> String { + format!("t1 = (t2 {} {}){}", op, last_opd, signed) +} +// --------------------set------------------------- +pub fn opd_set( + expect: Vec, + basic: Vec, + hit: String, +) -> RISCVOpdSet { + RISCVOpdSet { + hint: hit, + tokens: expect, + aim_basics: basic, + } +} +pub fn opd_set_no_opd(op: ParserRISCVInstOp, name: &str) -> RISCVOpdSet { + opd_set(vec![], vec![basic_op(op, vec![])], name.to_string()) +} +pub fn opd_set_sl_mem( + op: ParserRISCVInstOp, + name: &str, + unit: &str, + src: [&str; 5], + dst: [&str; 5], +) -> Vec { + vec![ + opd_set( + expect_opd(vec![Reg, Comma, Imm(I12), LParen, Reg, RParen]), + vec![basic_op_024(op)], + format!("{} t1, -0x1(t2) ({} = {}{})", name, dst[0], unit, src[0]), + ), + opd_set( + expect_opd(vec![Reg, Comma, LParen, Reg, RParen]), + vec![basic_op(op, vec![idx(0), imm_i(0), idx(3)])], + format!("{} t1, (t2) ({} = {}{})", name, dst[1], unit, src[1]), + ), + opd_set( + expect_reg_any(Imm(I12)), + vec![basic_op(op, vec![idx(0), idx(2), reg(Zero)])], + format!("{} t1, -0x1 ({} = {}{})", name, dst[2], unit, src[2]), + ), + opd_set( + expect_reg_any(Imm(I32)), vec![ - RISCVOpdSet { - hint: "lui t1, 0x1000 (t1 = 0x1000(u20))", - tokens: vec![Reg, Comma, Imm(U20)], - aim_basics: vec![RISCVOpdSetAim { - op: ParserRISCVInstOp::Lui, - opds: vec![idx_def!(0), idx_def!(2)], - }], - }, - RISCVOpdSet { - hint: "lui t1, label (t1 = label)", - tokens: vec![Reg, Comma, Lbl], - aim_basics: vec![RISCVOpdSetAim { - op: ParserRISCVInstOp::Lui, - opds: vec![idx_def!(0), idx_def!(2)], - }], - }, - ] - ), - ( - RISCVOpToken::Lw, - load_mem_vec!(ParserRISCVInstOp::Lw, "lw", "") - ), - (RISCVOpToken::Mul, vec![]), - (RISCVOpToken::Mulh, vec![]), - (RISCVOpToken::Mulhsu, vec![]), - (RISCVOpToken::Mulhu, vec![]), - ( - RISCVOpToken::Or, - vec![reg_reg_reg_set!(ParserRISCVInstOp::Or, "or", "|")] - ), - ( - RISCVOpToken::Ori, - vec![reg_reg_any_set!( - ParserRISCVInstOp::Ori, - "ori", - "|", - Imm(U12), - "0x1(u12)" - )] - ), - (RISCVOpToken::Rem, vec![]), - (RISCVOpToken::Remu, vec![]), - ( - RISCVOpToken::Sb, - store_mem_vec!(ParserRISCVInstOp::Sb, "sb", "(u8)") - ), - ( - RISCVOpToken::Sh, - store_mem_vec!(ParserRISCVInstOp::Sh, "sh", "(u16)") - ), - ( - RISCVOpToken::Sll, - vec![reg_reg_reg_set!( - ParserRISCVInstOp::Sll, - "sll", - "<<", - "t3[0:4]" - )] - ), - ( - RISCVOpToken::Slli, - vec![reg_reg_any_set!( - ParserRISCVInstOp::Slli, - "slli", - "<<", - Imm(U5), - "0x1(u5)" - )] - ), - ( - RISCVOpToken::Slt, - vec![reg_reg_reg_set!( - ParserRISCVInstOp::Slt, - "slt", - "", - "t3", - "t1 = (t2 < t3) (signed)" - )] - ), - ( - RISCVOpToken::Slti, - vec![reg_reg_any_set!( - ParserRISCVInstOp::Slti, - "slti", - "", - Imm(I12), - "-0x1(i12)", - "t1 = (t2 < -0x1(i12))" - )] - ), - ( - RISCVOpToken::Sltiu, - vec![reg_reg_any_set!( - ParserRISCVInstOp::Sltiu, - "sltiu", - "", - Imm(U12), - "0x1(u12)", - "t1 = (t2 < 0x1(u12))" - )] - ), - ( - RISCVOpToken::Sltu, - vec![reg_reg_reg_set!( - ParserRISCVInstOp::Sltu, - "sltu", - "", - "t3", - "t1 = (t2 < t3) (unsigned)" - )] - ), - ( - RISCVOpToken::Sra, - vec![reg_reg_reg_set!( - ParserRISCVInstOp::Sra, - "sra", - ">>", - "t3[0:4]" - )] - ), - ( - RISCVOpToken::Srai, - vec![reg_reg_any_set!( - ParserRISCVInstOp::Srai, - "srai", - ">>", - Imm(U5), - "0x1(u5)" - )] - ), - ( - RISCVOpToken::Srl, - vec![reg_reg_reg_set!( - ParserRISCVInstOp::Srl, - "srl", - ">>", - "t3[0:4]" - )] - ), - ( - RISCVOpToken::Srli, - vec![reg_reg_any_set!( - ParserRISCVInstOp::Srli, - "srli", - ">>", - Imm(U5), - "0x1(u5)" - )] - ), - ( - RISCVOpToken::Sub, - vec![reg_reg_reg_set!(ParserRISCVInstOp::Sub, "sub", "-")] - ), - ( - RISCVOpToken::Sw, - store_mem_vec!(ParserRISCVInstOp::Sw, "sw", "") - ), - (RISCVOpToken::Uret, vec![]), - (RISCVOpToken::Wfi, vec![]), - ( - RISCVOpToken::Xor, - vec![reg_reg_reg_set!(ParserRISCVInstOp::Xor, "xor", "^")] - ), - ( - RISCVOpToken::Xori, - vec![reg_reg_any_set!( - ParserRISCVInstOp::Xori, - "xori", - "^", - Imm(U12), - "0x1(u12)" - )] - ), - ( - RISCVOpToken::B, - vec![RISCVOpdSet { - hint: "b label (ra = pc + 4; pc = label)", - tokens: vec![Lbl], - aim_basics: vec![RISCVOpdSetAim { - op: ParserRISCVInstOp::Jal, - opds: vec![val_reg!(Ra), idx_def!(0)], - }], - }] - ), - ( - RISCVOpToken::Beqz, - branch_zero_vec!(ParserRISCVInstOp::Beq, "beqz", "==", "") - ), - ( - RISCVOpToken::Bgez, - branch_zero_vec!(ParserRISCVInstOp::Bge, "bgez", ">=", " (signed)") - ), - ( - RISCVOpToken::Bgt, - branch_inv_vec!(ParserRISCVInstOp::Blt, "bgt", ">", " (signed)"), - ), - ( - RISCVOpToken::Bgtu, - branch_inv_vec!(ParserRISCVInstOp::Bltu, "bgtu", ">", " (unsigned)"), - ), - ( - RISCVOpToken::Bgtz, - branch_zero_inv_vec!(ParserRISCVInstOp::Blt, "bgtz", ">", " (signed)") - ), - ( - RISCVOpToken::Ble, - branch_inv_vec!(ParserRISCVInstOp::Bge, "ble", "<=", " (signed)") - ), - ( - RISCVOpToken::Bleu, - branch_inv_vec!(ParserRISCVInstOp::Bgeu, "bleu", "<=", " (unsigned)") - ), - ( - RISCVOpToken::Blez, - branch_zero_inv_vec!(ParserRISCVInstOp::Bge, "blez", "<=", " (signed)") - ), - ( - RISCVOpToken::Bltz, - branch_zero_vec!(ParserRISCVInstOp::Blt, "bltz", "<", " (signed)") - ), - ( - RISCVOpToken::Bnez, - branch_zero_vec!(ParserRISCVInstOp::Bne, "bnez", "!=", "") - ), - (RISCVOpToken::Call, vec![]), - (RISCVOpToken::Csrc, vec![]), - (RISCVOpToken::Csrci, vec![]), - (RISCVOpToken::Csrr, vec![]), - (RISCVOpToken::Csrs, vec![]), - (RISCVOpToken::Csrsi, vec![]), - (RISCVOpToken::Csrw, vec![]), - (RISCVOpToken::Csrwi, vec![]), - (RISCVOpToken::FabsD, vec![]), - (RISCVOpToken::FabsS, vec![]), - (RISCVOpToken::FgeD, vec![]), - (RISCVOpToken::FgeS, vec![]), - (RISCVOpToken::FgtD, vec![]), - (RISCVOpToken::FgtS, vec![]), - (RISCVOpToken::FmvD, vec![]), - (RISCVOpToken::FmvS, vec![]), - (RISCVOpToken::FmvWX, vec![]), - (RISCVOpToken::FmvXW, vec![]), - (RISCVOpToken::FnegD, vec![]), - (RISCVOpToken::FnegS, vec![]), - (RISCVOpToken::Frcsr, vec![]), - (RISCVOpToken::Frflags, vec![]), - (RISCVOpToken::Frrm, vec![]), - (RISCVOpToken::Frsr, vec![]), - (RISCVOpToken::Fsflags, vec![]), - (RISCVOpToken::Fsrm, vec![]), - (RISCVOpToken::Fsrr, vec![]), - (RISCVOpToken::J, vec![]), - (RISCVOpToken::Jr, vec![]), - (RISCVOpToken::La, vec![]), - (RISCVOpToken::Li, vec![]), - (RISCVOpToken::Mv, vec![]), - (RISCVOpToken::Neg, vec![]), - ( - RISCVOpToken::Nop, - vec![RISCVOpdSet { - hint: "nop", - tokens: vec![], - aim_basics: vec![RISCVOpdSetAim { - op: ParserRISCVInstOp::Addi, - opds: vec![val_reg!(Zero), val_reg!(Zero), val_imm_i!(0)], - }], - }] + basic_op( + ParserRISCVInstOp::Lui, + vec![reg(A0), idx_handler(2, idx_handler_high)], + ), + basic_op(op, vec![idx(0), idx_handler(2, idx_handler_low), reg(A0)]), + ], + format!( + "{} t1, 0x100000 (a0 = 0x100000[12:31](i32); {} = {}{})", + name, dst[3], unit, src[3] + ), ), - (RISCVOpToken::Not, vec![]), - (RISCVOpToken::Rdcycle, vec![]), - (RISCVOpToken::Rdcycleh, vec![]), - (RISCVOpToken::Rdinstret, vec![]), - (RISCVOpToken::Rdinstreth, vec![]), - (RISCVOpToken::Rdtime, vec![]), - (RISCVOpToken::Rdtimeh, vec![]), - (RISCVOpToken::Ret, vec![]), - (RISCVOpToken::Seqz, vec![]), - (RISCVOpToken::SextB, vec![]), - (RISCVOpToken::SextH, vec![]), - (RISCVOpToken::Sgt, vec![]), - (RISCVOpToken::Sgtu, vec![]), - (RISCVOpToken::Sgtz, vec![]), - (RISCVOpToken::Sltz, vec![]), - (RISCVOpToken::Snez, vec![]), - (RISCVOpToken::Tail, vec![]), - (RISCVOpToken::ZextB, vec![]), - (RISCVOpToken::ZextH, vec![]), - ]); + opd_set( + expect_reg_any(Lbl), + vec![basic_op_024(op)], + format!("{} t1, label ({} = {}{})", name, dst[4], unit, src[4]), + ), + ] +} +const SL_MEM_REG: [&str; 5] = ["t1", "t1", "t1", "t1", "t1"]; +const SL_MEM_MEM: [&str; 5] = [ + "mem[t2 + -0x1(i12)]", + "mem[t2]", + "mem[-0x1(i12)]", + "mem[a0 + 0x100000[0:11](i32)]", + "mem[label]", +]; +pub fn opd_set_load_mem(op: ParserRISCVInstOp, name: &str, unit: &str) -> Vec { + opd_set_sl_mem(op, name, unit, SL_MEM_MEM, SL_MEM_REG) +} +pub fn opd_set_store_mem(op: ParserRISCVInstOp, name: &str, unit: &str) -> Vec { + opd_set_sl_mem(op, name, unit, SL_MEM_REG, SL_MEM_MEM) } diff --git a/src-tauri/src/modules/riscv/basic/parser/parser.rs b/src-tauri/src/modules/riscv/basic/parser/parser.rs index b02ea2d3..fb3662d7 100644 --- a/src-tauri/src/modules/riscv/basic/parser/parser.rs +++ b/src-tauri/src/modules/riscv/basic/parser/parser.rs @@ -1,9 +1,7 @@ use super::super::interface::parser::*; use super::label::LabelData; -use super::lexer::{LexerIter, RISCVOpToken, RISCVToken}; -use super::oplist::{ - RISCVExpectToken, RISCVImmediateType, RISCVOpdSetAim, RISCVOpdSetAimOpd, OP_LIST, -}; +use super::lexer::{LexerIter, RISCVOpToken, RISCVToken, Symbol}; +use super::oplist::{RISCVExpectToken, RISCVImmediateType, RISCVOpdSetAim, RISCVOpdSetAimOpd}; use super::r#macro::MacroData; use crate::utility::ptr::Ptr; use logos::Logos; @@ -170,9 +168,9 @@ impl RISCVParser { self.label_list.clear(); } - fn in_bound_int(token: RISCVToken, min: i128, max: i128) -> bool { + fn in_bound_int(token: &RISCVToken, min: i128, max: i128) -> bool { match token { - RISCVToken::ImmediateInt(val) => val >= min && val <= max, + RISCVToken::ImmediateInt(val) => *val >= min && *val <= max, _ => false, } } @@ -262,7 +260,7 @@ impl RISCVParser { fn parse_op( &mut self, status_ptr: Ptr, - op: RISCVOpToken, + op: &dyn RISCVOpToken, ) -> Result<(), Vec> { let status = status_ptr.as_mut(); @@ -272,7 +270,7 @@ impl RISCVParser { .get_error("operator in data segment".to_string())); } - let token_sets = OP_LIST.get(&op).unwrap(); + let token_sets = op.get_opd_set(); let token_set_len = token_sets.len(); if token_set_len == 0 { @@ -295,7 +293,7 @@ impl RISCVParser { } while let Some(token) = status.iter.next()? { - if token == RISCVToken::Newline { + if matches!(token, RISCVToken::Newline) { term_by = 1; break; } @@ -315,20 +313,20 @@ impl RISCVParser { Reg => type_fit = matches!(token, RISCVToken::Register(_)), Csr => type_fit = matches!(token, RISCVToken::Csr(_)), Imm(imm_t) => match imm_t { - U4 => type_fit = Self::in_bound_int(token, 0, 0xf), - U5 => type_fit = Self::in_bound_int(token, 0, 0x1f), - U12 => type_fit = Self::in_bound_int(token, 0, 0xfff), - U20 => type_fit = Self::in_bound_int(token, 0, 0xf_ffff), - U32 => type_fit = Self::in_bound_int(token, 0, 0xffff_ffff), - U64 => type_fit = Self::in_bound_int(token, 0, u64::MAX as i128), - I12 => type_fit = Self::in_bound_int(token, -0x800, 0x7ff), - I20 => type_fit = Self::in_bound_int(token, -0x8_0000, 0x7_ffff), - I32 => type_fit = Self::in_bound_int(token, -0x8000_0000, 0x7fff_ffff), + U4 => type_fit = Self::in_bound_int(&token, 0, 0xf), + U5 => type_fit = Self::in_bound_int(&token, 0, 0x1f), + U12 => type_fit = Self::in_bound_int(&token, 0, 0xfff), + U20 => type_fit = Self::in_bound_int(&token, 0, 0xf_ffff), + U32 => type_fit = Self::in_bound_int(&token, 0, 0xffff_ffff), + U64 => type_fit = Self::in_bound_int(&token, 0, u64::MAX as i128), + I12 => type_fit = Self::in_bound_int(&token, -0x800, 0x7ff), + I20 => type_fit = Self::in_bound_int(&token, -0x8_0000, 0x7_ffff), + I32 => type_fit = Self::in_bound_int(&token, -0x8000_0000, 0x7fff_ffff), I64 => { - type_fit = Self::in_bound_int(token, i64::MIN as i128, i64::MAX as i128) + type_fit = Self::in_bound_int(&token, i64::MIN as i128, i64::MAX as i128) } }, - Lbl => type_fit = matches!(token, RISCVToken::Label(_)), + Lbl => type_fit = matches!(token, RISCVToken::Symbol(Symbol::Label(_))), } if !type_fit { token_set_state[i] = 0; @@ -353,7 +351,7 @@ impl RISCVParser { stash_opd.push(Some(ParserRISCVInstOpd::Imm(RISCVImmediate::Int(val)))); stash_label_name.push(String::new()); } - RISCVToken::Label(lbl) => { + RISCVToken::Symbol(Symbol::Label(lbl)) => { stash_opd.push(Some(ParserRISCVInstOpd::Lbl(ParserRISCVLabel::Unknown( status_ptr.as_ref().iter.pos(), )))); @@ -418,7 +416,7 @@ impl RISCVParser { let mut msg = vec!["unmatched operands.\ncandidates are:"]; for opd_set in token_sets { msg.push("\n"); - msg.push(opd_set.hint); + msg.push(&opd_set.hint); } Err(vec![ParserError { pos: op_char_pos, @@ -430,7 +428,7 @@ impl RISCVParser { let mut msg = vec!["unmatched operands.\ncandidates are:"]; for opd_set in token_sets { msg.push("\n"); - msg.push(opd_set.hint); + msg.push(&opd_set.hint); } Err(vec![ParserError { pos: op_char_pos, @@ -457,32 +455,35 @@ impl RISCVParser { | RISCVToken::ImmediateString(_) => { Self::load_data(&mut self.label_list, status, &token) } - RISCVToken::Label(value) => { - let pos = status.iter.pos(); - let next_token = status.iter.next()?; - if status.label_def.is_some() - || next_token.is_none() - || next_token.unwrap() != RISCVToken::Colon - { - return Err(vec![ParserError { - pos, - msg: "unrecognized symbol".to_string(), - }]); - } - let label_name = value.to_string(); - if self.label_list.get(&label_name).is_none() { - self.label_list.insert( - label_name.clone(), - LabelData { - name: label_name.clone(), - def: None, - refs: Vec::new(), - }, - ); + RISCVToken::Symbol(symbol) => match symbol { + Symbol::Label(value) => { + let pos = status.iter.pos(); + let next_token = status.iter.next()?; + if status.label_def.is_some() + || next_token.is_none() + || !matches!(next_token.unwrap(), RISCVToken::Colon) + { + return Err(vec![ParserError { + pos, + msg: "unrecognized symbol".to_string(), + }]); + } + let label_name = value.to_string(); + if self.label_list.get(&label_name).is_none() { + self.label_list.insert( + label_name.clone(), + LabelData { + name: label_name.clone(), + def: None, + refs: Vec::new(), + }, + ); + } + status.label_def = Some(label_name); + Ok(()) } - status.label_def = Some(label_name); - Ok(()) - } + Symbol::Op(op) => self.parse_op(status_ptr, op), + }, RISCVToken::MacroParameter(_) | RISCVToken::Register(_) | RISCVToken::Csr(_) => { Err(status.iter.get_error("unexpected symbol".to_string())) } @@ -538,7 +539,8 @@ impl RISCVParser { RISCVToken::Section => { let next_token = status.iter.next()?; match next_token { - Some(RISCVToken::Label(_)) | Some(RISCVToken::ImmediateString(_)) => Ok(()), + Some(RISCVToken::Symbol(Symbol::Label(_))) + | Some(RISCVToken::ImmediateString(_)) => Ok(()), Some(_) => Err(status.iter.get_error("invalid section name".to_string())), None => Err(status.iter.get_error("missing section name".to_string())), } @@ -581,7 +583,6 @@ impl RISCVParser { RISCVToken::UnknownDirective(_) => { Err(status.iter.get_error("unrecognized directive".to_string())) } - RISCVToken::Operator(op) => self.parse_op(status_ptr, op), } } diff --git a/src-tauri/src/modules/riscv/rv32i/mod.rs b/src-tauri/src/modules/riscv/rv32i/mod.rs index 0b6d2c4e..7b5b2b8a 100644 --- a/src-tauri/src/modules/riscv/rv32i/mod.rs +++ b/src-tauri/src/modules/riscv/rv32i/mod.rs @@ -1 +1,2 @@ pub mod constants; +pub mod parser; diff --git a/src-tauri/src/modules/riscv/rv32i/parser/lexer.rs b/src-tauri/src/modules/riscv/rv32i/parser/lexer.rs new file mode 100644 index 00000000..1fa9af05 --- /dev/null +++ b/src-tauri/src/modules/riscv/rv32i/parser/lexer.rs @@ -0,0 +1,374 @@ +use std::collections::HashMap; + +use super::super::super::basic::parser::lexer::RISCVOpToken; +use super::oplist::{RISCVOpdSet, OP_LIST}; +use lazy_static::lazy_static; + +pub fn op_lexer(op: &str) -> Option<&'static dyn RISCVOpToken> { + match OP_TOKEN.get(op) { + Some(op) => Some(op as &dyn RISCVOpToken), + None => None, + } +} + +lazy_static! { + static ref OP_TOKEN: HashMap<&'static str, RV32IOpToken> = HashMap::from([ + ("add", RV32IOpToken::Add), + ("addi", RV32IOpToken::Addi), + ("and", RV32IOpToken::And), + ("andi", RV32IOpToken::Andi), + ("auipc", RV32IOpToken::Auipc), + ("beq", RV32IOpToken::Beq), + ("bge", RV32IOpToken::Bge), + ("bgeu", RV32IOpToken::Bgeu), + ("blt", RV32IOpToken::Blt), + ("bltu", RV32IOpToken::Bltu), + ("bne", RV32IOpToken::Bne), + ("csrrc", RV32IOpToken::Csrrc), + ("csrrci", RV32IOpToken::Csrrci), + ("csrrs", RV32IOpToken::Csrrs), + ("csrrsi", RV32IOpToken::Csrrsi), + ("csrrw", RV32IOpToken::Csrrw), + ("csrrwi", RV32IOpToken::Csrrwi), + ("div", RV32IOpToken::Div), + ("divu", RV32IOpToken::Divu), + ("ebreak", RV32IOpToken::Ebreak), + ("ecall", RV32IOpToken::Ecall), + ("jal", RV32IOpToken::Jal), + ("jalr", RV32IOpToken::Jalr), + ("lb", RV32IOpToken::Lb), + ("lbu", RV32IOpToken::Lbu), + ("lh", RV32IOpToken::Lh), + ("lhu", RV32IOpToken::Lhu), + ("lui", RV32IOpToken::Lui), + ("lw", RV32IOpToken::Lw), + ("mul", RV32IOpToken::Mul), + ("mulh", RV32IOpToken::Mulh), + ("mulhsu", RV32IOpToken::Mulhsu), + ("mulhu", RV32IOpToken::Mulhu), + ("or", RV32IOpToken::Or), + ("ori", RV32IOpToken::Ori), + ("rem", RV32IOpToken::Rem), + ("remu", RV32IOpToken::Remu), + ("sb", RV32IOpToken::Sb), + ("sh", RV32IOpToken::Sh), + ("sll", RV32IOpToken::Sll), + ("slli", RV32IOpToken::Slli), + ("slt", RV32IOpToken::Slt), + ("slti", RV32IOpToken::Slti), + ("sltiu", RV32IOpToken::Sltiu), + ("sltu", RV32IOpToken::Sltu), + ("sra", RV32IOpToken::Sra), + ("srai", RV32IOpToken::Srai), + ("srl", RV32IOpToken::Srl), + ("srli", RV32IOpToken::Srli), + ("sub", RV32IOpToken::Sub), + ("sw", RV32IOpToken::Sw), + ("uret", RV32IOpToken::Uret), + ("wfi", RV32IOpToken::Wfi), + ("xor", RV32IOpToken::Xor), + ("xori", RV32IOpToken::Xori), + ("b", RV32IOpToken::B), + ("beqz", RV32IOpToken::Beqz), + ("bgez", RV32IOpToken::Bgez), + ("bgt", RV32IOpToken::Bgt), + ("bgtu", RV32IOpToken::Bgtu), + ("bgtz", RV32IOpToken::Bgtz), + ("ble", RV32IOpToken::Ble), + ("bleu", RV32IOpToken::Bleu), + ("blez", RV32IOpToken::Blez), + ("bltz", RV32IOpToken::Bltz), + ("bnez", RV32IOpToken::Bnez), + ("call", RV32IOpToken::Call), + ("csrc", RV32IOpToken::Csrc), + ("csrci", RV32IOpToken::Csrci), + ("csrr", RV32IOpToken::Csrr), + ("csrs", RV32IOpToken::Csrs), + ("csrsi", RV32IOpToken::Csrsi), + ("csrw", RV32IOpToken::Csrw), + ("csrwi", RV32IOpToken::Csrwi), + ("j", RV32IOpToken::J), + ("jr", RV32IOpToken::Jr), + ("la", RV32IOpToken::La), + ("li", RV32IOpToken::Li), + ("mv", RV32IOpToken::Mv), + ("neg", RV32IOpToken::Neg), + ("nop", RV32IOpToken::Nop), + ("not", RV32IOpToken::Not), + ("rdcycle", RV32IOpToken::Rdcycle), + ("rdcycleh", RV32IOpToken::Rdcycleh), + ("rdinstret", RV32IOpToken::Rdinstret), + ("rdinstreth", RV32IOpToken::Rdinstreth), + ("rdtime", RV32IOpToken::Rdtime), + ("rdtimeh", RV32IOpToken::Rdtimeh), + ("ret", RV32IOpToken::Ret), + ("seqz", RV32IOpToken::Seqz), + ("sext.b", RV32IOpToken::SextB), + ("sext.h", RV32IOpToken::SextH), + ("sgt", RV32IOpToken::Sgt), + ("sgtu", RV32IOpToken::Sgtu), + ("sgtz", RV32IOpToken::Sgtz), + ("sltz", RV32IOpToken::Sltz), + ("snez", RV32IOpToken::Snez), + ("tail", RV32IOpToken::Tail), + ("zext.b", RV32IOpToken::ZextB), + ("zext.h", RV32IOpToken::ZextH), + ]); +} + +// #[token("fadd.d", priority = 10)] +// #[token("fadd.s", priority = 10)] +// #[token("fclass.d", priority = 10)] +// #[token("fclass.s", priority = 10)] +// #[token("fcvt.d.s", priority = 10)] +// #[token("fcvt.d.w", priority = 10)] +// #[token("fcvt.d.wu", priority = 10)] +// #[token("fcvt.s.d", priority = 10)] +// #[token("fcvt.s.w", priority = 10)] +// #[token("fcvt.s.wu", priority = 10)] +// #[token("fcvt.w.d", priority = 10)] +// #[token("fcvt.w.s", priority = 10)] +// #[token("fcvt.wu.d", priority = 10)] +// #[token("fcvt.wu.s", priority = 10)] +// #[token("fdiv.d", priority = 10)] +// #[token("fdiv.s", priority = 10)] +// #[token("fence", priority = 10)] +// #[token("fence.i", priority = 10)] +// #[token("feq.d", priority = 10)] +// #[token("feq.s", priority = 10)] +// #[token("fld", priority = 10)] +// #[token("fle.d", priority = 10)] +// #[token("fle.s", priority = 10)] +// #[token("flt.d", priority = 10)] +// #[token("flt.s", priority = 10)] +// #[token("flw", priority = 10)] +// #[token("fmadd.d", priority = 10)] +// #[token("fmadd.s", priority = 10)] +// #[token("fmax.d", priority = 10)] +// #[token("fmax.s", priority = 10)] +// #[token("fmin.d", priority = 10)] +// #[token("fmin.s", priority = 10)] +// #[token("fmsub.d", priority = 10)] +// #[token("fmsub.s", priority = 10)] +// #[token("fmul.d", priority = 10)] +// #[token("fmul.s", priority = 10)] +// #[token("fmv.s.x", priority = 10)] +// #[token("fmv.x.s", priority = 10)] +// #[token("fnmadd.d", priority = 10)] +// #[token("fnmadd.s", priority = 10)] +// #[token("fnmsub.d", priority = 10)] +// #[token("fnmsub.s", priority = 10)] +// #[token("fsd", priority = 10)] +// #[token("fsgnj.d", priority = 10)] +// #[token("fsgnj.s", priority = 10)] +// #[token("fsgnjn.d", priority = 10)] +// #[token("fsgnjn.s", priority = 10)] +// #[token("fsgnjx.d", priority = 10)] +// #[token("fsgnjx.s", priority = 10)] +// #[token("fsqrt.d", priority = 10)] +// #[token("fsqrt.s", priority = 10)] +// #[token("fsub.d", priority = 10)] +// #[token("fsub.s", priority = 10)] +// #[token("fsw", priority = 10)] +// #[token("fabs.d", |_| RISCVOpToken::FabsD, priority = 10)] +// #[token("fabs.s", |_| RISCVOpToken::FabsS, priority = 10)] +// #[token("fge.d", |_| RISCVOpToken::FgeD, priority = 10)] +// #[token("fge.s", |_| RISCVOpToken::FgeS, priority = 10)] +// #[token("fgt.d", |_| RISCVOpToken::FgtD, priority = 10)] +// #[token("fgt.s", |_| RISCVOpToken::FgtS, priority = 10)] +// #[token("fmv.d", |_| RISCVOpToken::FmvD, priority = 10)] +// #[token("fmv.s", |_| RISCVOpToken::FmvS, priority = 10)] +// #[token("fmv.w.x", |_| RISCVOpToken::FmvWX, priority = 10)] +// #[token("fmv.x.w", |_| RISCVOpToken::FmvXW, priority = 10)] +// #[token("fneg.d", |_| RISCVOpToken::FnegD, priority = 10)] +// #[token("fneg.s", |_| RISCVOpToken::FnegS, priority = 10)] +// #[token("frcsr", |_| RISCVOpToken::Frcsr, priority = 10)] +// #[token("frflags", |_| RISCVOpToken::Frflags, priority = 10)] +// #[token("frrm", |_| RISCVOpToken::Frrm, priority = 10)] +// #[token("frsr", |_| RISCVOpToken::Frsr, priority = 10)] +// #[token("fsflags", |_| RISCVOpToken::Fsflags, priority = 10)] +// #[token("fsrm", |_| RISCVOpToken::Fsrm, priority = 10)] +// #[token("fsrr", |_| RISCVOpToken::Fsrr, priority = 10)] + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub enum RV32IOpToken { + Add, + Addi, + And, + Andi, + Auipc, + Beq, + Bge, + Bgeu, + Blt, + Bltu, + Bne, + Csrrc, + Csrrci, + Csrrs, + Csrrsi, + Csrrw, + Csrrwi, + Div, + Divu, + Ebreak, + Ecall, + FaddD, + FaddS, + FclassD, + FclassS, + FcvtDS, + FcvtDW, + FcvtDWu, + FcvtSD, + FcvtSW, + FcvtSWu, + FcvtWD, + FcvtWS, + FcvtWuD, + FcvtWuS, + FdivD, + FdivS, + Fence, + FenceI, + FeqD, + FeqS, + Fld, + FleD, + FleS, + FltD, + FltS, + Flw, + FmaddD, + FmaddS, + FmaxD, + FmaxS, + FminD, + FminS, + FmsubD, + FmsubS, + FmulD, + FmulS, + FmvSX, + FmvXS, + FnmaddD, + FnmaddS, + FnmsubD, + FnmsubS, + Fsd, + FsgnjD, + FsgnjS, + FsgnjnD, + FsgnjnS, + FsgnjxD, + FsgnjxS, + FsqrtD, + FsqrtS, + FsubD, + FsubS, + Fsw, + Jal, + Jalr, + Lb, + Lbu, + Lh, + Lhu, + Lui, + Lw, + Mul, + Mulh, + Mulhsu, + Mulhu, + Or, + Ori, + Rem, + Remu, + Sb, + Sh, + Sll, + Slli, + Slt, + Slti, + Sltiu, + Sltu, + Sra, + Srai, + Srl, + Srli, + Sub, + Sw, + Uret, + Wfi, + Xor, + Xori, + B, + Beqz, + Bgez, + Bgt, + Bgtu, + Bgtz, + Ble, + Bleu, + Blez, + Bltz, + Bnez, + Call, + Csrc, + Csrci, + Csrr, + Csrs, + Csrsi, + Csrw, + Csrwi, + FabsD, + FabsS, + FgeD, + FgeS, + FgtD, + FgtS, + FmvD, + FmvS, + FmvWX, + FmvXW, + FnegD, + FnegS, + Frcsr, + Frflags, + Frrm, + Frsr, + Fsflags, + Fsrm, + Fsrr, + J, + Jr, + La, + Li, + Mv, + Neg, + Nop, + Not, + Rdcycle, + Rdcycleh, + Rdinstret, + Rdinstreth, + Rdtime, + Rdtimeh, + Ret, + Seqz, + SextB, + SextH, + Sgt, + Sgtu, + Sgtz, + Sltz, + Snez, + Tail, + ZextB, + ZextH, +} + +impl RISCVOpToken for RV32IOpToken { + fn get_opd_set(&self) -> &Vec { + &OP_LIST.get(self).unwrap() + } +} diff --git a/src-tauri/src/modules/riscv/rv32i/parser/mod.rs b/src-tauri/src/modules/riscv/rv32i/parser/mod.rs new file mode 100644 index 00000000..fda211a8 --- /dev/null +++ b/src-tauri/src/modules/riscv/rv32i/parser/mod.rs @@ -0,0 +1,2 @@ +pub mod oplist; +pub mod lexer; diff --git a/src-tauri/src/modules/riscv/rv32i/parser/oplist.rs b/src-tauri/src/modules/riscv/rv32i/parser/oplist.rs new file mode 100644 index 00000000..55653542 --- /dev/null +++ b/src-tauri/src/modules/riscv/rv32i/parser/oplist.rs @@ -0,0 +1,619 @@ +use super::super::super::basic::interface::parser::ParserRISCVInstOp; +use super::super::super::basic::parser::oplist::*; +use super::lexer::RV32IOpToken; +use lazy_static::lazy_static; +use std::collections::HashMap; + +pub use super::super::super::basic::parser::oplist::RISCVOpdSet; + +lazy_static! { + pub static ref OP_LIST: HashMap> = HashMap::from([ + ( + RV32IOpToken::Add, + vec![opd_set( + expect_reg_reg_reg(), + vec![basic_op_024(ParserRISCVInstOp::Add)], + hint_reg_reg_reg("add", "+") + )] + ), + ( + RV32IOpToken::Addi, + vec![ + opd_set( + expect_reg_reg_any(Imm(I12)), + vec![basic_op_024(ParserRISCVInstOp::Addi)], + hint_reg_reg_any("addi", "-0x1(i12)", "+") + ), + opd_set( + expect_reg_reg_any(Lbl), + vec![basic_op_024(ParserRISCVInstOp::Addi)], + hint_reg_reg_any("addi", "label[0:11]", "+") + ), + ] + ), + ( + RV32IOpToken::And, + vec![opd_set( + expect_reg_reg_reg(), + vec![basic_op_024(ParserRISCVInstOp::And)], + hint_reg_reg_reg("and", "&") + )] + ), + ( + RV32IOpToken::Andi, + vec![opd_set( + expect_reg_reg_any(Imm(U12)), + vec![basic_op_024(ParserRISCVInstOp::Andi)], + hint_reg_reg_any("andi", "0x1(u12)", "&") + )] + ), + ( + RV32IOpToken::Auipc, + vec![opd_set( + expect_reg_any(Imm(U20)), + vec![basic_op_02(ParserRISCVInstOp::Auipc)], + "auipc t1, 0x1000 (t1 = pc + 0x1000(u20))".to_string() + )] + ), + ( + RV32IOpToken::Beq, + vec![opd_set( + expect_reg_reg_any(Lbl), + vec![basic_op_024(ParserRISCVInstOp::Beq)], + hint_branch("beq", "==", " (signed)") + )] + ), + ( + RV32IOpToken::Bge, + vec![opd_set( + expect_reg_reg_any(Lbl), + vec![basic_op_024(ParserRISCVInstOp::Bge)], + hint_branch("bge", ">=", " (signed)") + )] + ), + ( + RV32IOpToken::Bgeu, + vec![opd_set( + expect_reg_reg_any(Lbl), + vec![basic_op_024(ParserRISCVInstOp::Bgeu)], + hint_branch("bgeu", ">=", " (unsigned)") + )] + ), + ( + RV32IOpToken::Blt, + vec![opd_set( + expect_reg_reg_any(Lbl), + vec![basic_op_024(ParserRISCVInstOp::Blt)], + hint_branch("blt", "<", " (signed)") + )] + ), + ( + RV32IOpToken::Bltu, + vec![opd_set( + expect_reg_reg_any(Lbl), + vec![basic_op_024(ParserRISCVInstOp::Bltu)], + hint_branch("bltu", "<", " (unsigned)") + )] + ), + ( + RV32IOpToken::Bne, + vec![opd_set( + expect_reg_reg_any(Lbl), + vec![basic_op_024(ParserRISCVInstOp::Bne)], + hint_branch("bne", "!=", " (signed)") + )] + ), + ( + RV32IOpToken::Csrrc, + vec![opd_set( + expect_csr(Reg), + vec![basic_op_024(ParserRISCVInstOp::Csrrc)], + hint_csr("csrrc", "&= ~", "t2") + )] + ), + ( + RV32IOpToken::Csrrci, + vec![opd_set( + expect_csr(Imm(U5)), + vec![basic_op_024(ParserRISCVInstOp::Csrrci)], + hint_csr("csrrci", "&= ~", "0x1(u5)") + )] + ), + ( + RV32IOpToken::Csrrs, + vec![opd_set( + expect_csr(Reg), + vec![basic_op_024(ParserRISCVInstOp::Csrrs)], + hint_csr("csrrs", "|=", "t2") + )] + ), + ( + RV32IOpToken::Csrrsi, + vec![opd_set( + expect_csr(Imm(U5)), + vec![basic_op_024(ParserRISCVInstOp::Csrrsi)], + hint_csr("csrrsi", "|=", "0x1(u5)") + )] + ), + ( + RV32IOpToken::Csrrw, + vec![opd_set( + expect_csr(Reg), + vec![basic_op_024(ParserRISCVInstOp::Csrrw)], + hint_csr("csrrw", "=", "t2") + )] + ), + ( + RV32IOpToken::Csrrwi, + vec![opd_set( + expect_csr(Imm(U5)), + vec![basic_op_024(ParserRISCVInstOp::Csrrwi)], + hint_csr("csrrwi", "=", "0x1(u5)") + )] + ), + (RV32IOpToken::Div, vec![]), + (RV32IOpToken::Divu, vec![]), + ( + RV32IOpToken::Ebreak, + vec![opd_set_no_opd(ParserRISCVInstOp::Ebreak, "ebreak")] + ), + ( + RV32IOpToken::Ecall, + vec![opd_set_no_opd(ParserRISCVInstOp::Ecall, "ecall")] + ), + (RV32IOpToken::FaddD, vec![]), + (RV32IOpToken::FaddS, vec![]), + (RV32IOpToken::FclassD, vec![]), + (RV32IOpToken::FclassS, vec![]), + (RV32IOpToken::FcvtDS, vec![]), + (RV32IOpToken::FcvtDW, vec![]), + (RV32IOpToken::FcvtDWu, vec![]), + (RV32IOpToken::FcvtSD, vec![]), + (RV32IOpToken::FcvtSW, vec![]), + (RV32IOpToken::FcvtSWu, vec![]), + (RV32IOpToken::FcvtWD, vec![]), + (RV32IOpToken::FcvtWS, vec![]), + (RV32IOpToken::FcvtWuD, vec![]), + (RV32IOpToken::FcvtWuS, vec![]), + (RV32IOpToken::FdivD, vec![]), + (RV32IOpToken::FdivS, vec![]), + ( + RV32IOpToken::Fence, + vec![opd_set( + expect_opd(vec![Imm(U4), Comma, Imm(U4)]), + vec![basic_op_02(ParserRISCVInstOp::Fence)], + "fence 0x1(u4), 0x1(u4)".to_string() + )] + ), + ( + RV32IOpToken::FenceI, + vec![opd_set_no_opd(ParserRISCVInstOp::FenceI, "fence.i")] + ), + (RV32IOpToken::FeqD, vec![]), + (RV32IOpToken::FeqS, vec![]), + (RV32IOpToken::Fld, vec![]), + (RV32IOpToken::FleD, vec![]), + (RV32IOpToken::FleS, vec![]), + (RV32IOpToken::FltD, vec![]), + (RV32IOpToken::FltS, vec![]), + (RV32IOpToken::Flw, vec![]), + (RV32IOpToken::FmaddD, vec![]), + (RV32IOpToken::FmaddS, vec![]), + (RV32IOpToken::FmaxD, vec![]), + (RV32IOpToken::FmaxS, vec![]), + (RV32IOpToken::FminD, vec![]), + (RV32IOpToken::FminS, vec![]), + (RV32IOpToken::FmsubD, vec![]), + (RV32IOpToken::FmsubS, vec![]), + (RV32IOpToken::FmulD, vec![]), + (RV32IOpToken::FmulS, vec![]), + (RV32IOpToken::FmvSX, vec![]), + (RV32IOpToken::FmvXS, vec![]), + (RV32IOpToken::FnmaddD, vec![]), + (RV32IOpToken::FnmaddS, vec![]), + (RV32IOpToken::FnmsubD, vec![]), + (RV32IOpToken::FnmsubS, vec![]), + (RV32IOpToken::Fsd, vec![]), + (RV32IOpToken::FsgnjD, vec![]), + (RV32IOpToken::FsgnjS, vec![]), + (RV32IOpToken::FsgnjnD, vec![]), + (RV32IOpToken::FsgnjnS, vec![]), + (RV32IOpToken::FsgnjxD, vec![]), + (RV32IOpToken::FsgnjxS, vec![]), + (RV32IOpToken::FsqrtD, vec![]), + (RV32IOpToken::FsqrtS, vec![]), + (RV32IOpToken::FsubD, vec![]), + (RV32IOpToken::FsubS, vec![]), + (RV32IOpToken::Fsw, vec![]), + ( + RV32IOpToken::Jal, + vec![ + opd_set( + expect_opd(vec![Lbl]), + vec![basic_op(ParserRISCVInstOp::Jal, vec![reg(Ra), idx(0)])], + "jal label (ra = pc + 4; pc = label)".to_string() + ), + opd_set( + expect_reg_any(Lbl), + vec![basic_op_02(ParserRISCVInstOp::Jal)], + "jal t1, label (t1 = pc + 4; pc = label)".to_string() + ) + ] + ), + ( + RV32IOpToken::Jalr, + vec![ + opd_set( + expect_reg_reg_any(Imm(I12)), + vec![basic_op_024(ParserRISCVInstOp::Jalr)], + "jalr t1, t2, -0x1(i12) (t1 = pc + 4; pc = t2 + -0x1(i12))".to_string() + ), + opd_set( + expect_opd(vec![Reg]), + vec![basic_op( + ParserRISCVInstOp::Jalr, + vec![reg(Ra), idx(0), imm_i(0)] + )], + "jalr t0 (ra = pc + 4; pc = t0)".to_string() + ), + opd_set( + expect_reg_any(Imm(I12)), + vec![basic_op( + ParserRISCVInstOp::Jalr, + vec![reg(Ra), idx(0), idx(2)] + )], + "jalr t1, -0x1 (ra = pc + 4; pc = t1 + -0x1(i12))".to_string() + ), + opd_set( + expect_opd(vec![Reg, Comma, Imm(I12), LParen, Reg, RParen]), + vec![basic_op_042(ParserRISCVInstOp::Jalr)], + "jalr t1, -0x1(t2) (t1 = pc + 4; pc = t2 + -0x1(i12))".to_string() + ) + ] + ), + ( + RV32IOpToken::Lb, + opd_set_load_mem(ParserRISCVInstOp::Lb, "lb", "(i8)") + ), + ( + RV32IOpToken::Lbu, + opd_set_load_mem(ParserRISCVInstOp::Lbu, "lbu", "(u8)") + ), + ( + RV32IOpToken::Lh, + opd_set_load_mem(ParserRISCVInstOp::Lh, "lh", "(i16)") + ), + ( + RV32IOpToken::Lhu, + opd_set_load_mem(ParserRISCVInstOp::Lhu, "lhu", "(u16)") + ), + ( + RV32IOpToken::Lui, + vec![ + opd_set( + expect_reg_any(Imm(U20)), + vec![basic_op_02(ParserRISCVInstOp::Lui)], + "lui t1, 0x1000 (t1 = 0x1000(u20))".to_string() + ), + opd_set( + expect_reg_any(Lbl), + vec![basic_op_02(ParserRISCVInstOp::Lui)], + "lui t1, label (t1 = label)".to_string() + ) + ] + ), + ( + RV32IOpToken::Lw, + opd_set_load_mem(ParserRISCVInstOp::Lw, "lw", "") + ), + (RV32IOpToken::Mul, vec![]), + (RV32IOpToken::Mulh, vec![]), + (RV32IOpToken::Mulhsu, vec![]), + (RV32IOpToken::Mulhu, vec![]), + ( + RV32IOpToken::Or, + vec![opd_set( + expect_reg_reg_reg(), + vec![basic_op_024(ParserRISCVInstOp::Or)], + hint_reg_reg_reg("or", "|") + ),] + ), + ( + RV32IOpToken::Ori, + vec![opd_set( + expect_reg_reg_any(Imm(U12)), + vec![basic_op_024(ParserRISCVInstOp::Ori)], + hint_reg_reg_any("ori", "0x1(u12)", "|") + )] + ), + (RV32IOpToken::Rem, vec![]), + (RV32IOpToken::Remu, vec![]), + ( + RV32IOpToken::Sb, + opd_set_store_mem(ParserRISCVInstOp::Sb, "sb", "(u8)") + ), + ( + RV32IOpToken::Sh, + opd_set_store_mem(ParserRISCVInstOp::Sh, "sh", "(u16)") + ), + ( + RV32IOpToken::Sll, + vec![opd_set( + expect_reg_reg_reg(), + vec![basic_op_024(ParserRISCVInstOp::Sll)], + hint_reg_reg_any("sll", "<<", "t3[0:4]") + )] + ), + ( + RV32IOpToken::Slli, + vec![opd_set( + expect_reg_reg_any(Imm(U5)), + vec![basic_op_024(ParserRISCVInstOp::Slli)], + hint_reg_reg_any("slli", "<<", "0x1(u5)") + )] + ), + ( + RV32IOpToken::Slt, + vec![opd_set( + expect_reg_reg_reg(), + vec![basic_op_024(ParserRISCVInstOp::Slt)], + hint_set_comparison("<", "t3", " (signed)") + )] + ), + ( + RV32IOpToken::Slti, + vec![opd_set( + expect_reg_reg_any(Imm(I12)), + vec![basic_op_024(ParserRISCVInstOp::Slti)], + hint_set_comparison("<", "-0x1(i12)", " (signed)") + )] + ), + ( + RV32IOpToken::Sltiu, + vec![opd_set( + expect_reg_reg_any(Imm(U12)), + vec![basic_op_024(ParserRISCVInstOp::Sltiu)], + hint_set_comparison("<", "0x1(u12)", " (unsigned)") + )] + ), + ( + RV32IOpToken::Sltu, + vec![opd_set( + expect_reg_reg_reg(), + vec![basic_op_024(ParserRISCVInstOp::Sltu)], + hint_set_comparison("<", "t3", " (unsigned)") + )] + ), + ( + RV32IOpToken::Sra, + vec![opd_set( + expect_reg_reg_reg(), + vec![basic_op_024(ParserRISCVInstOp::Sra)], + hint_reg_reg_any("sra", ">>", "t3[0:4]") + )] + ), + ( + RV32IOpToken::Srai, + vec![opd_set( + expect_reg_reg_any(Imm(U5)), + vec![basic_op_024(ParserRISCVInstOp::Srai)], + hint_reg_reg_any("srai", ">>", "0x1(u5)") + )] + ), + ( + RV32IOpToken::Srl, + vec![opd_set( + expect_reg_reg_reg(), + vec![basic_op_024(ParserRISCVInstOp::Srl)], + hint_reg_reg_any("srl", ">>", "t3[0:4]") + )] + ), + ( + RV32IOpToken::Srli, + vec![opd_set( + expect_reg_reg_any(Imm(U5)), + vec![basic_op_024(ParserRISCVInstOp::Srli)], + hint_reg_reg_any("srli", ">>", "0x1(u5)") + )] + ), + ( + RV32IOpToken::Sub, + vec![opd_set( + expect_reg_reg_reg(), + vec![basic_op_024(ParserRISCVInstOp::Sub)], + hint_reg_reg_reg("sub", "-") + )] + ), + ( + RV32IOpToken::Sw, + opd_set_store_mem(ParserRISCVInstOp::Sw, "sw", "") + ), + (RV32IOpToken::Uret, vec![]), + (RV32IOpToken::Wfi, vec![]), + ( + RV32IOpToken::Xor, + vec![opd_set( + expect_reg_reg_reg(), + vec![basic_op_024(ParserRISCVInstOp::Xor)], + hint_reg_reg_reg("xor", "^") + )] + ), + ( + RV32IOpToken::Xori, + vec![opd_set( + expect_reg_reg_any(Imm(U12)), + vec![basic_op_024(ParserRISCVInstOp::Xori)], + hint_reg_reg_any("xori", "0x1(u12)", "^") + )] + ), + ( + RV32IOpToken::B, + vec![opd_set( + expect_opd(vec![Lbl]), + vec![basic_op(ParserRISCVInstOp::Jal, vec![reg(Ra), idx(0)])], + "b label (ra = pc + 4; pc = label)".to_string() + )] + ), + ( + RV32IOpToken::Beqz, + vec![opd_set( + expect_reg_any(Lbl), + vec![basic_op( + ParserRISCVInstOp::Beq, + vec![idx(0), reg(Zero), idx(2)] + )], + hint_branch_zero("beqz", "==", "") + )] + ), + ( + RV32IOpToken::Bgez, + vec![opd_set( + expect_reg_any(Lbl), + vec![basic_op( + ParserRISCVInstOp::Bge, + vec![idx(0), reg(Zero), idx(2)] + )], + hint_branch_zero("bgez", ">=", " (signed)") + )] + ), + ( + RV32IOpToken::Bgt, + vec![opd_set( + expect_reg_reg_any(Lbl), + vec![basic_op_204(ParserRISCVInstOp::Blt)], + hint_branch("bgt", ">", " (signed)") + )] + ), + ( + RV32IOpToken::Bgtu, + vec![opd_set( + expect_reg_reg_any(Lbl), + vec![basic_op_204(ParserRISCVInstOp::Bltu)], + hint_branch("bgtu", ">", " (unsigned)") + )] + ), + ( + RV32IOpToken::Bgtz, + vec![opd_set( + expect_reg_any(Lbl), + vec![basic_op( + ParserRISCVInstOp::Blt, + vec![reg(Zero), idx(0), idx(2)] + )], + hint_branch_zero("bgtz", ">", " (signed)") + )] + ), + ( + RV32IOpToken::Ble, + vec![opd_set( + expect_reg_reg_any(Lbl), + vec![basic_op_204(ParserRISCVInstOp::Bge)], + hint_branch("ble", "<=", " (signed)") + )] + ), + ( + RV32IOpToken::Bleu, + vec![opd_set( + expect_reg_reg_any(Lbl), + vec![basic_op_204(ParserRISCVInstOp::Bgeu)], + hint_branch("bleu", "<=", " (unsigned)") + )] + ), + ( + RV32IOpToken::Blez, + vec![opd_set( + expect_reg_any(Lbl), + vec![basic_op( + ParserRISCVInstOp::Bge, + vec![reg(Zero), idx(0), idx(2)] + )], + hint_branch_zero("blez", "<=", " (signed)") + )] + ), + ( + RV32IOpToken::Bltz, + vec![opd_set( + expect_reg_any(Lbl), + vec![basic_op( + ParserRISCVInstOp::Blt, + vec![idx(0), reg(Zero), idx(2)] + )], + hint_branch_zero("bltz", "<", " (signed)") + )] + ), + ( + RV32IOpToken::Bnez, + vec![opd_set( + expect_reg_any(Lbl), + vec![basic_op( + ParserRISCVInstOp::Bne, + vec![idx(0), reg(Zero), idx(2)] + )], + hint_branch_zero("bnez", "!=", "") + )] + ), + (RV32IOpToken::Call, vec![]), + (RV32IOpToken::Csrc, vec![]), + (RV32IOpToken::Csrci, vec![]), + (RV32IOpToken::Csrr, vec![]), + (RV32IOpToken::Csrs, vec![]), + (RV32IOpToken::Csrsi, vec![]), + (RV32IOpToken::Csrw, vec![]), + (RV32IOpToken::Csrwi, vec![]), + (RV32IOpToken::FabsD, vec![]), + (RV32IOpToken::FabsS, vec![]), + (RV32IOpToken::FgeD, vec![]), + (RV32IOpToken::FgeS, vec![]), + (RV32IOpToken::FgtD, vec![]), + (RV32IOpToken::FgtS, vec![]), + (RV32IOpToken::FmvD, vec![]), + (RV32IOpToken::FmvS, vec![]), + (RV32IOpToken::FmvWX, vec![]), + (RV32IOpToken::FmvXW, vec![]), + (RV32IOpToken::FnegD, vec![]), + (RV32IOpToken::FnegS, vec![]), + (RV32IOpToken::Frcsr, vec![]), + (RV32IOpToken::Frflags, vec![]), + (RV32IOpToken::Frrm, vec![]), + (RV32IOpToken::Frsr, vec![]), + (RV32IOpToken::Fsflags, vec![]), + (RV32IOpToken::Fsrm, vec![]), + (RV32IOpToken::Fsrr, vec![]), + (RV32IOpToken::J, vec![]), + (RV32IOpToken::Jr, vec![]), + (RV32IOpToken::La, vec![]), + (RV32IOpToken::Li, vec![]), + (RV32IOpToken::Mv, vec![]), + (RV32IOpToken::Neg, vec![]), + ( + RV32IOpToken::Nop, + vec![opd_set( + expect_opd(vec![]), + vec![basic_op( + ParserRISCVInstOp::Addi, + vec![reg(Zero), reg(Zero), imm_i(0)] + )], + "nop".to_string() + )] + ), + (RV32IOpToken::Not, vec![]), + (RV32IOpToken::Rdcycle, vec![]), + (RV32IOpToken::Rdcycleh, vec![]), + (RV32IOpToken::Rdinstret, vec![]), + (RV32IOpToken::Rdinstreth, vec![]), + (RV32IOpToken::Rdtime, vec![]), + (RV32IOpToken::Rdtimeh, vec![]), + (RV32IOpToken::Ret, vec![]), + (RV32IOpToken::Seqz, vec![]), + (RV32IOpToken::SextB, vec![]), + (RV32IOpToken::SextH, vec![]), + (RV32IOpToken::Sgt, vec![]), + (RV32IOpToken::Sgtu, vec![]), + (RV32IOpToken::Sgtz, vec![]), + (RV32IOpToken::Sltz, vec![]), + (RV32IOpToken::Snez, vec![]), + (RV32IOpToken::Tail, vec![]), + (RV32IOpToken::ZextB, vec![]), + (RV32IOpToken::ZextH, vec![]), + ]); +} From 97060b6437df8d92091faace7359c64802da1a1d Mon Sep 17 00:00:00 2001 From: Vollate Date: Tue, 16 Apr 2024 20:54:06 +0800 Subject: [PATCH 2/7] refactor(middleware): shit mountain --- docs/API.md | 6 ++ src-tauri/src/interface/parser.rs | 4 +- src-tauri/src/main.rs | 18 +++-- src-tauri/src/menu/menu_file.rs | 34 +++++++-- src-tauri/src/middleware/backend_test.rs | 1 - src-tauri/src/middleware/frontend_test.rs | 1 - src-tauri/src/middleware/mod.rs | 3 - .../src/modules/riscv/basic/parser/parser.rs | 5 +- .../riscv/middleware.rs} | 52 +++++++------- src-tauri/src/modules/riscv/mod.rs | 1 + src-tauri/src/parser/mod.rs | 1 - src-tauri/src/simulator/mod.rs | 1 - src-tauri/src/test/parser.rs | 2 +- src-tauri/src/types/middleware_types.rs | 39 ++--------- src-tauri/src/utility/state_helper.rs | 69 ++++++++++++------- 15 files changed, 124 insertions(+), 113 deletions(-) delete mode 100644 src-tauri/src/middleware/backend_test.rs delete mode 100644 src-tauri/src/middleware/frontend_test.rs delete mode 100644 src-tauri/src/middleware/mod.rs rename src-tauri/src/{middleware/implementation.rs => modules/riscv/middleware.rs} (77%) delete mode 100644 src-tauri/src/parser/mod.rs delete mode 100644 src-tauri/src/simulator/mod.rs diff --git a/docs/API.md b/docs/API.md index 64b175a9..4d76879b 100644 --- a/docs/API.md +++ b/docs/API.md @@ -59,6 +59,12 @@ change_current_tab(newpath: String) -> bool; 设置新聚焦 tab 的 filepath 当仅后端不存在该 tab 时返回 false,否则返回 true。 +### assemble + +```rust +assemble()-> +``` + ## event ### front_file_open diff --git a/src-tauri/src/interface/parser.rs b/src-tauri/src/interface/parser.rs index c2fbd741..96ca8222 100644 --- a/src-tauri/src/interface/parser.rs +++ b/src-tauri/src/interface/parser.rs @@ -1,8 +1,8 @@ -pub trait Parser: Send + Sync +pub trait Parser< IS>: Send + Sync where IS: ParserInstSet, { - fn parse(&mut self, code: &CODE) -> Result, Vec>; + fn parse(&mut self, code: String) -> Result, Vec>; } // in crate::modules::[instruction_set]::basic::interface::parser diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index bcf2a39d..64050541 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -4,17 +4,14 @@ mod interface; mod io; mod menu; -mod middleware; mod modules; -mod parser; -mod simulator; mod storage; mod test; mod types; mod utility; -use middleware::implementation::tab_management; use types::middleware_types; +use modules::riscv; fn main() { tauri::Builder::default() @@ -36,12 +33,13 @@ fn main() { Ok(()) }) .invoke_handler(tauri::generate_handler![ - tab_management::create_tab, - tab_management::close_tab, - tab_management::change_current_tab, - tab_management::update_tab, - tab_management::read_tab, - tab_management::write_tab + riscv::middleware::tab_management::create_tab, + riscv::middleware::tab_management::close_tab, + riscv::middleware::tab_management::change_current_tab, + riscv::middleware::tab_management::update_tab, + riscv::middleware::tab_management::read_tab, + riscv::middleware::tab_management::write_tab, + riscv::middleware::frontend_api::assemble, ]) .run(tauri::generate_context!()) .expect("error while running tauri application"); diff --git a/src-tauri/src/menu/menu_file.rs b/src-tauri/src/menu/menu_file.rs index cb36e460..74f52495 100644 --- a/src-tauri/src/menu/menu_file.rs +++ b/src-tauri/src/menu/menu_file.rs @@ -1,16 +1,40 @@ +use std::path::Path; + use tauri::{ - api::dialog::{FileDialogBuilder, MessageDialogKind}, - CustomMenuItem, Menu, Submenu, WindowMenuEvent, + api::dialog::{FileDialogBuilder, MessageDialogKind}, CustomMenuItem, Manager, Menu, Submenu, WindowMenuEvent }; use super::display_alert_dialog; use crate::{ io::file_io, - middleware::implementation::tab_management::new_tab, - types::menu_types, - utility::state_helper::{get_current_tab, get_current_tab_name}, + storage::rope_store, + types::{middleware_types::{Tab,TabMap}, menu_types }, + utility::state_helper::event::{get_current_tab, get_current_tab_name, set_current_tab_name }, + modules::riscv::basic::parser::parser::RISCVParser }; + fn new_tab(event: &WindowMenuEvent, file_path: &Path) -> Option { + match rope_store::Text::from_path(file_path) { + Ok(content) => { + let tab_map = event.window().state::(); + let tab = Tab { + text: Box::new(content), + parser: Box::new(RISCVParser::new()), + //assembler: Box::new(Default::default()), + //simulator: Box::new(Default::default()), + }; + tab_map + .tabs + .lock() + .unwrap() + .insert(file_path.to_str().unwrap().to_string(), tab); + set_current_tab_name(&event, file_path.to_str().unwrap()); + None + } + Err(e) => Some(e), + } + } + pub fn new() -> Submenu { Submenu::new( "File", diff --git a/src-tauri/src/middleware/backend_test.rs b/src-tauri/src/middleware/backend_test.rs deleted file mode 100644 index 8b137891..00000000 --- a/src-tauri/src/middleware/backend_test.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src-tauri/src/middleware/frontend_test.rs b/src-tauri/src/middleware/frontend_test.rs deleted file mode 100644 index 8b137891..00000000 --- a/src-tauri/src/middleware/frontend_test.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src-tauri/src/middleware/mod.rs b/src-tauri/src/middleware/mod.rs deleted file mode 100644 index 6ccc2df9..00000000 --- a/src-tauri/src/middleware/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod backend_test; -pub mod frontend_test; -pub mod implementation; diff --git a/src-tauri/src/modules/riscv/basic/parser/parser.rs b/src-tauri/src/modules/riscv/basic/parser/parser.rs index b02ea2d3..a57fd53a 100644 --- a/src-tauri/src/modules/riscv/basic/parser/parser.rs +++ b/src-tauri/src/modules/riscv/basic/parser/parser.rs @@ -14,10 +14,9 @@ pub struct RISCVParser { label_list: BTreeMap, } -impl Parser for RISCVParser { - fn parse(&mut self, code: &ropey::Rope) -> Result, Vec> { +impl Parser< RISCV> for RISCVParser { + fn parse(&mut self, code_str: String) -> Result, Vec> { self.init(); - let code_str = code.to_string(); let mut _status = RISCVParserStatus::new(&code_str); let status_ptr = Ptr::new(&_status); let status = status_ptr.as_mut(); diff --git a/src-tauri/src/middleware/implementation.rs b/src-tauri/src/modules/riscv/middleware.rs similarity index 77% rename from src-tauri/src/middleware/implementation.rs rename to src-tauri/src/modules/riscv/middleware.rs index 6314269f..b146edd8 100644 --- a/src-tauri/src/middleware/implementation.rs +++ b/src-tauri/src/modules/riscv/middleware.rs @@ -1,38 +1,16 @@ pub mod tab_management { - use tauri::{Manager, State, WindowMenuEvent}; + use tauri::State; use crate::{ io::file_io, modules::riscv::basic::interface::parser::RISCVParser, storage::rope_store, types::middleware_types::{CurTabName, Optional, Tab, TabMap}, - utility::state_helper::set_current_tab_name, }; - use std::path::Path; - - pub fn new_tab(event: &WindowMenuEvent, file_path: &Path) -> Option { - match rope_store::Text::from_path(file_path) { - Ok(content) => { - let tab_map = event.window().state::(); - let tab = Tab { - text: Box::new(content), - parser: Box::new(RISCVParser::new()), - //assembler: Box::new(Default::default()), - //simulator: Box::new(Default::default()), - }; - tab_map - .tabs - .lock() - .unwrap() - .insert(file_path.to_str().unwrap().to_string(), tab); - set_current_tab_name(&event, file_path.to_str().unwrap()); - None - } - Err(e) => Some(e), - } - } + + #[tauri::command] pub fn create_tab(tab_map: State, filepath: &str) -> Optional { if tab_map.tabs.lock().unwrap().contains_key(filepath) { @@ -138,4 +116,26 @@ pub mod tab_management { } } -pub mod frontend_api {} +pub mod frontend_api { + use crate::{ + types::middleware_types::{CurTabName, Optional, TabMap}, + utility::state_helper::state::get_current_tab, + }; + use tauri::State; + + #[tauri::command] + pub fn assemble(cur_tab_name: State, tab_map: State) -> Optional { + let tab_ptr = get_current_tab(cur_tab_name, tab_map); + let tab = tab_ptr.as_mut(); + match tab.parser.parse(tab.text.get_string()) { + Ok(ir) => Optional { + success: true, + message: String::new(), + }, + Err(e) => Optional { + success: false, + message: "".to_string(), + }, + } + } +} diff --git a/src-tauri/src/modules/riscv/mod.rs b/src-tauri/src/modules/riscv/mod.rs index 578105c4..e15ebab1 100644 --- a/src-tauri/src/modules/riscv/mod.rs +++ b/src-tauri/src/modules/riscv/mod.rs @@ -1,2 +1,3 @@ pub mod basic; pub mod rv32i; +pub mod middleware; diff --git a/src-tauri/src/parser/mod.rs b/src-tauri/src/parser/mod.rs deleted file mode 100644 index 8b137891..00000000 --- a/src-tauri/src/parser/mod.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src-tauri/src/simulator/mod.rs b/src-tauri/src/simulator/mod.rs deleted file mode 100644 index 8b137891..00000000 --- a/src-tauri/src/simulator/mod.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src-tauri/src/test/parser.rs b/src-tauri/src/test/parser.rs index 0ce6ba13..549be384 100644 --- a/src-tauri/src/test/parser.rs +++ b/src-tauri/src/test/parser.rs @@ -14,6 +14,6 @@ pub fn test_parser() { beq a1, a2, bb\n \ ", ); - let res = p.parse(&rope); + let res = p.parse(rope.to_string()); println!("{:?}", res); } diff --git a/src-tauri/src/types/middleware_types.rs b/src-tauri/src/types/middleware_types.rs index c8699973..2d634d6c 100644 --- a/src-tauri/src/types/middleware_types.rs +++ b/src-tauri/src/types/middleware_types.rs @@ -2,12 +2,13 @@ use crate::interface::{ assembler::Assembler, parser::Parser, simulator::Simulator, storage::MFile, }; -use ropey::Rope; -use serde::{de, Serialize}; + +use serde::Serialize; +use crate::modules::riscv::basic::interface::parser::RISCV; pub struct Tab { pub text: Box>, - pub parser: Box>, + pub parser: Box>, //pub assembler: Box>, //pub simulator: Box>, } @@ -28,35 +29,3 @@ pub struct Optional { pub message: String, } -//pub mod constants { -//pub enum Lint { -//Info, -//Lint, -//Warn, -//Error, -//} - -//pub enum AssemblerOp { -//Assemble, -//Dump, -//DumpAs, -//} - -//pub enum SimulatorOp { -//Run, -//Debug, -//RunStep, -//Redo, -//} - -//pub enum FileOp { -//Save, -//SaveAs, -//Open, -//Close, -//} - -//pub enum WebSocketOp { -//RefreshText, -//} -//} diff --git a/src-tauri/src/utility/state_helper.rs b/src-tauri/src/utility/state_helper.rs index f72569bc..c3a8b5e2 100644 --- a/src-tauri/src/utility/state_helper.rs +++ b/src-tauri/src/utility/state_helper.rs @@ -1,34 +1,55 @@ -use crate::types::middleware_types::{CurTabName, Tab, TabMap}; -use tauri::{Manager, WindowMenuEvent}; +pub mod state { + use super::super::ptr::Ptr; + use crate::types::middleware_types::{CurTabName, Tab, TabMap}; + use tauri::State; -use super::ptr::Ptr; + pub fn get_current_tab_name(cur_tab_name: State) -> String { + cur_tab_name.name.lock().unwrap().clone() + } -pub fn get_current_tab_name(event: &WindowMenuEvent) -> String { - event - .window() - .state::() - .name - .lock() - .unwrap() - .clone() -} + pub fn set_current_tab_name(cur_tab_name: State, new_name: &str) { + let mut name = cur_tab_name.name.lock().unwrap(); + *name = new_name.to_string(); + } -pub fn set_current_tab_name(event: &WindowMenuEvent, new_name: &str) { - let tn = event.window().state::(); - let mut name = tn.name.lock().unwrap(); - *name = new_name.to_string(); + pub fn get_current_tab(cur_tab_name: State, tab_map: State) -> Ptr { + let name = get_current_tab_name(cur_tab_name); + Ptr::new(tab_map.tabs.lock().unwrap().get(&name).unwrap()) + } } -pub fn get_current_tab(event: &WindowMenuEvent) -> Ptr { - let name = get_current_tab_name(&event); - Ptr::new( +pub mod event { + use super::super::ptr::Ptr; + use crate::types::middleware_types::{CurTabName, Tab, TabMap}; + use tauri::{Manager, WindowMenuEvent}; + + pub fn get_current_tab_name(event: &WindowMenuEvent) -> String { event .window() - .state::() - .tabs + .state::() + .name .lock() .unwrap() - .get(&name) - .unwrap(), - ) + .clone() + } + + pub fn set_current_tab_name(event: &WindowMenuEvent, new_name: &str) { + let tn = event.window().state::(); + let mut name = tn.name.lock().unwrap(); + *name = new_name.to_string(); + } + + pub fn get_current_tab(event: &WindowMenuEvent) -> Ptr { + let name = get_current_tab_name(&event); + Ptr::new( + event + .window() + .state::() + .tabs + .lock() + .unwrap() + .get(&name) + .unwrap(), + ) + } } From 475cc4341560ab0e47eb05866b9f965eb953e954 Mon Sep 17 00:00:00 2001 From: GenshinImpactStarts <12211831@mail.sustech.edu.cn> Date: Tue, 16 Apr 2024 22:27:11 +0800 Subject: [PATCH 3/7] feat(utility): add AnyU8 --- src-tauri/src/utility/any.rs | 47 ++++++++++++++++++++++++++++++++++++ src-tauri/src/utility/mod.rs | 1 + 2 files changed, 48 insertions(+) create mode 100644 src-tauri/src/utility/any.rs diff --git a/src-tauri/src/utility/any.rs b/src-tauri/src/utility/any.rs new file mode 100644 index 00000000..dc36b637 --- /dev/null +++ b/src-tauri/src/utility/any.rs @@ -0,0 +1,47 @@ +#[derive(Copy, Clone, PartialEq, Eq, Hash)] +pub struct AnyU8 { + pub type_id: std::any::TypeId, + pub raw_val: u8, +} + +impl AnyU8 { + pub fn from(e: T) -> Self + where + T: Clone + Copy + 'static, + { + assert!(std::mem::size_of::() == 1, "Size of E must be 1"); + unsafe { + AnyU8 { + type_id: std::any::TypeId::of::(), + raw_val: *(&e as *const T as *const u8), + } + } + } + + pub fn is(&self) -> bool + where + T: 'static, + { + self.type_id == std::any::TypeId::of::() + } + + pub fn to(&self) -> Option + where + T: Clone + Copy + 'static, + { + if self.is::() { + Some(unsafe { *(&self.raw_val as *const u8 as *const T) }) + } else { + None + } + } +} + +impl std::fmt::Debug for AnyU8 { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("AnyU8") + .field("type_id", &self.type_id) + .field("raw_val", &self.raw_val) + .finish() + } +} diff --git a/src-tauri/src/utility/mod.rs b/src-tauri/src/utility/mod.rs index b7a78d41..37024522 100644 --- a/src-tauri/src/utility/mod.rs +++ b/src-tauri/src/utility/mod.rs @@ -1,2 +1,3 @@ +pub mod any; pub mod ptr; pub mod state_helper; From 814fa5e7c22c2bea46123f234f9937e442db2154 Mon Sep 17 00:00:00 2001 From: Vollate Date: Tue, 16 Apr 2024 22:27:06 +0800 Subject: [PATCH 4/7] feat(assemble interface): only have parser now --- src-tauri/src/interface/parser.rs | 8 ++- src-tauri/src/interface/storage.rs | 6 +- src-tauri/src/main.rs | 2 +- src-tauri/src/menu/menu_file.rs | 69 +++++++++++-------- .../src/modules/riscv/basic/parser/parser.rs | 2 +- src-tauri/src/modules/riscv/middleware.rs | 17 ++--- src-tauri/src/modules/riscv/mod.rs | 2 +- src-tauri/src/storage/rope_store.rs | 10 ++- src-tauri/src/types/middleware_types.rs | 9 ++- 9 files changed, 76 insertions(+), 49 deletions(-) diff --git a/src-tauri/src/interface/parser.rs b/src-tauri/src/interface/parser.rs index 96ca8222..2080b03d 100644 --- a/src-tauri/src/interface/parser.rs +++ b/src-tauri/src/interface/parser.rs @@ -1,4 +1,6 @@ -pub trait Parser< IS>: Send + Sync +use serde::Serialize; + +pub trait Parser: Send + Sync where IS: ParserInstSet, { @@ -15,7 +17,7 @@ where type Operand; } -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Serialize, Clone, Copy, Debug, PartialEq, Eq)] pub struct Pos(pub usize, pub usize); #[derive(Clone, Debug)] @@ -27,7 +29,7 @@ where pub text: Vec>, } -#[derive(Clone, Debug)] +#[derive(Serialize, Clone, Debug)] pub struct ParserError { pub pos: Pos, pub msg: String, diff --git a/src-tauri/src/interface/storage.rs b/src-tauri/src/interface/storage.rs index 0063212f..821f6dd8 100644 --- a/src-tauri/src/interface/storage.rs +++ b/src-tauri/src/interface/storage.rs @@ -1,5 +1,9 @@ pub trait MFile: Send + Sync { - fn get_string(&self) -> String; + fn is_dirty(&self) -> bool; + + fn set_dirty(&mut self, dirty: bool); + + fn to_string(&self) -> String; fn save(&mut self) -> Option; } diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 64050541..fbfa6c8f 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -10,8 +10,8 @@ mod test; mod types; mod utility; -use types::middleware_types; use modules::riscv; +use types::middleware_types; fn main() { tauri::Builder::default() diff --git a/src-tauri/src/menu/menu_file.rs b/src-tauri/src/menu/menu_file.rs index 74f52495..4863eac0 100644 --- a/src-tauri/src/menu/menu_file.rs +++ b/src-tauri/src/menu/menu_file.rs @@ -1,40 +1,22 @@ use std::path::Path; use tauri::{ - api::dialog::{FileDialogBuilder, MessageDialogKind}, CustomMenuItem, Manager, Menu, Submenu, WindowMenuEvent + api::dialog::{FileDialogBuilder, MessageDialogKind}, + CustomMenuItem, Manager, Menu, Submenu, WindowMenuEvent, }; use super::display_alert_dialog; use crate::{ io::file_io, + modules::riscv::basic::parser::parser::RISCVParser, storage::rope_store, - types::{middleware_types::{Tab,TabMap}, menu_types }, - utility::state_helper::event::{get_current_tab, get_current_tab_name, set_current_tab_name }, - modules::riscv::basic::parser::parser::RISCVParser + types::{ + menu_types, + middleware_types::{Tab, TabMap}, + }, + utility::state_helper::event::{get_current_tab, get_current_tab_name, set_current_tab_name}, }; - fn new_tab(event: &WindowMenuEvent, file_path: &Path) -> Option { - match rope_store::Text::from_path(file_path) { - Ok(content) => { - let tab_map = event.window().state::(); - let tab = Tab { - text: Box::new(content), - parser: Box::new(RISCVParser::new()), - //assembler: Box::new(Default::default()), - //simulator: Box::new(Default::default()), - }; - tab_map - .tabs - .lock() - .unwrap() - .insert(file_path.to_str().unwrap().to_string(), tab); - set_current_tab_name(&event, file_path.to_str().unwrap()); - None - } - Err(e) => Some(e), - } - } - pub fn new() -> Submenu { Submenu::new( "File", @@ -86,7 +68,7 @@ fn open_handler(event: WindowMenuEvent) { |_| {}, ), _ => { - let content = get_current_tab(&event).as_ref().text.get_string(); + let content = get_current_tab(&event).as_ref().text.to_string(); event .window() .emit( @@ -126,7 +108,7 @@ fn save_handler<'a>(event: WindowMenuEvent) { fn save_as_handler(event: WindowMenuEvent) { let tab_ptr = get_current_tab(&event); let tab = tab_ptr.as_ref(); - let content = tab.text.get_string(); + let content = tab.text.to_string(); let picker = tauri::api::dialog::FileDialogBuilder::new(); picker.save_file(move |file_path| match file_path { Some(file_path) => match file_io::write_file(file_path.as_path(), &content) { @@ -150,9 +132,38 @@ fn share_handler(event: WindowMenuEvent) { todo!("Share file with socket"); } -fn close_handler(event: WindowMenuEvent) {} +fn close_handler(event: WindowMenuEvent) { + //TODO: check if the file is dirty +} fn exit_handler(event: WindowMenuEvent) { event.window().close().unwrap(); todo!("check all dirty file before exit"); } + +fn new_tab(event: &WindowMenuEvent, file_path: &Path) -> Option { + match rope_store::Text::from_path(file_path) { + Ok(content) => { + let tab_map = event.window().state::(); + let tab = Tab { + text: Box::new(content), + parser: Box::new(RISCVParser::new()), + //assembler: Box::new(Default::default()), + //simulator: Box::new(Default::default()), + }; + tab_map + .tabs + .lock() + .unwrap() + .insert(file_path.to_str().unwrap().to_string(), tab); + set_current_tab_name(&event, file_path.to_str().unwrap()); + None + } + Err(e) => Some(e), + } +} + +fn dirty_close_checker(event: &WindowMenuEvent, tab: &mut Tab) -> bool { + if tab.text.is_dirty() {} + true +} diff --git a/src-tauri/src/modules/riscv/basic/parser/parser.rs b/src-tauri/src/modules/riscv/basic/parser/parser.rs index a57fd53a..c5c568b1 100644 --- a/src-tauri/src/modules/riscv/basic/parser/parser.rs +++ b/src-tauri/src/modules/riscv/basic/parser/parser.rs @@ -14,7 +14,7 @@ pub struct RISCVParser { label_list: BTreeMap, } -impl Parser< RISCV> for RISCVParser { +impl Parser for RISCVParser { fn parse(&mut self, code_str: String) -> Result, Vec> { self.init(); let mut _status = RISCVParserStatus::new(&code_str); diff --git a/src-tauri/src/modules/riscv/middleware.rs b/src-tauri/src/modules/riscv/middleware.rs index b146edd8..2954f542 100644 --- a/src-tauri/src/modules/riscv/middleware.rs +++ b/src-tauri/src/modules/riscv/middleware.rs @@ -8,9 +8,6 @@ pub mod tab_management { types::middleware_types::{CurTabName, Optional, Tab, TabMap}, }; - - - #[tauri::command] pub fn create_tab(tab_map: State, filepath: &str) -> Optional { if tab_map.tabs.lock().unwrap().contains_key(filepath) { @@ -118,23 +115,23 @@ pub mod tab_management { pub mod frontend_api { use crate::{ - types::middleware_types::{CurTabName, Optional, TabMap}, + types::middleware_types::{AssembleResult, CurTabName, TabMap}, utility::state_helper::state::get_current_tab, }; use tauri::State; #[tauri::command] - pub fn assemble(cur_tab_name: State, tab_map: State) -> Optional { + pub fn assemble(cur_tab_name: State, tab_map: State) -> AssembleResult { let tab_ptr = get_current_tab(cur_tab_name, tab_map); let tab = tab_ptr.as_mut(); - match tab.parser.parse(tab.text.get_string()) { - Ok(ir) => Optional { + match tab.parser.parse(tab.text.to_string()) { + Ok(ir) => AssembleResult { success: true, - message: String::new(), + error: Default::default(), }, - Err(e) => Optional { + Err(e) => AssembleResult { success: false, - message: "".to_string(), + error: e, }, } } diff --git a/src-tauri/src/modules/riscv/mod.rs b/src-tauri/src/modules/riscv/mod.rs index e15ebab1..4a67445c 100644 --- a/src-tauri/src/modules/riscv/mod.rs +++ b/src-tauri/src/modules/riscv/mod.rs @@ -1,3 +1,3 @@ pub mod basic; -pub mod rv32i; pub mod middleware; +pub mod rv32i; diff --git a/src-tauri/src/storage/rope_store.rs b/src-tauri/src/storage/rope_store.rs index c0f4da9b..e7f81946 100644 --- a/src-tauri/src/storage/rope_store.rs +++ b/src-tauri/src/storage/rope_store.rs @@ -12,7 +12,15 @@ pub struct Text { } impl MFile for Text { - fn get_string(&self) -> String { + fn is_dirty(&self) -> bool { + self.dirty + } + + fn set_dirty(&mut self, dirty: bool) { + self.dirty = dirty; + } + + fn to_string(&self) -> String { self.data.as_ref().to_string() } diff --git a/src-tauri/src/types/middleware_types.rs b/src-tauri/src/types/middleware_types.rs index 2d634d6c..2987dd6e 100644 --- a/src-tauri/src/types/middleware_types.rs +++ b/src-tauri/src/types/middleware_types.rs @@ -2,9 +2,8 @@ use crate::interface::{ assembler::Assembler, parser::Parser, simulator::Simulator, storage::MFile, }; - -use serde::Serialize; use crate::modules::riscv::basic::interface::parser::RISCV; +use serde::Serialize; pub struct Tab { pub text: Box>, @@ -13,6 +12,7 @@ pub struct Tab { //pub simulator: Box>, } +use crate::interface::parser::ParserError; use std::{collections::HashMap, sync::Mutex}; pub struct TabMap { @@ -29,3 +29,8 @@ pub struct Optional { pub message: String, } +#[derive(Clone, Serialize)] +pub struct AssembleResult { + pub success: bool, + pub error: Vec, +} From b045ce7cb639394c6556ee08c10cb5ab04190517 Mon Sep 17 00:00:00 2001 From: GenshinImpactStarts <12211831@mail.sustech.edu.cn> Date: Tue, 16 Apr 2024 22:42:52 +0800 Subject: [PATCH 5/7] refactor(parser constant): refactor parser's interface | change constant name --- src-tauri/Cargo.lock | 23 ++ src-tauri/Cargo.toml | 1 + .../modules/riscv/basic/interface/parser.rs | 84 +++++++- .../src/modules/riscv/basic/parser/label.rs | 6 - .../src/modules/riscv/basic/parser/lexer.rs | 46 ++-- .../src/modules/riscv/basic/parser/macro.rs | 32 +-- .../src/modules/riscv/basic/parser/oplist.rs | 94 ++------- .../src/modules/riscv/basic/parser/parser.rs | 27 ++- .../src/modules/riscv/rv32i/constants.rs | 106 ++++++---- .../src/modules/riscv/rv32i/parser/lexer.rs | 20 +- .../src/modules/riscv/rv32i/parser/mod.rs | 2 +- .../src/modules/riscv/rv32i/parser/oplist.rs | 199 ++++++++++++------ 12 files changed, 382 insertions(+), 258 deletions(-) diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 0c9da7b2..32116887 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -2073,6 +2073,7 @@ dependencies = [ "ropey", "serde", "serde_json", + "strum", "tauri", "tauri-build", ] @@ -3246,6 +3247,28 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "strum" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.50", +] + [[package]] name = "syn" version = "1.0.109" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 93f9d8a3..d1ab8172 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -21,6 +21,7 @@ tauri = { version = "1.6.0", features = [ "fs-read-dir", "fs-create-dir", "fs-ex ropey = "1.6.1" logos = "0.14.0" lazy_static = "1.4.0" +strum = { version = "0.26", features = ["derive"] } [features] # this feature is used for production builds or when `devPath` points to the filesystem and the built-in dev server is disabled. diff --git a/src-tauri/src/modules/riscv/basic/interface/parser.rs b/src-tauri/src/modules/riscv/basic/interface/parser.rs index d4ff90fd..5b78a660 100644 --- a/src-tauri/src/modules/riscv/basic/interface/parser.rs +++ b/src-tauri/src/modules/riscv/basic/interface/parser.rs @@ -1,19 +1,28 @@ -pub use super::super::super::rv32i::constants::*; +use crate::utility::any::AnyU8; + pub use super::super::parser::parser::RISCVParser; pub use crate::interface::parser::*; pub const MAX_DATA_SIZE: usize = 0xf_ffff; pub const DATA_CHUNK_RECOMMEND_SIZE: usize = 0x7ff; -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] pub struct RISCV; -pub type ParserRISCVInstOp = RISCVInstruction; +#[derive(Clone, Copy, PartialEq, Eq)] +pub struct ParserRISCVInstOp(AnyU8, &'static str); + +#[derive(Clone, Copy, PartialEq, Eq)] +pub struct ParserRISCVRegister(AnyU8, &'static str); + +pub type ParserRISCVImmediate = super::super::super::rv32i::constants::RISCVImmediate; + +pub type ParserRISCVCsr = super::super::super::rv32i::constants::RISCVCsr; #[derive(Clone, Copy, Debug, PartialEq)] pub enum ParserRISCVInstOpd { - Reg(RISCVRegister), - Imm(RISCVImmediate), + Reg(ParserRISCVRegister), + Imm(ParserRISCVImmediate), Lbl(ParserRISCVLabel), } @@ -24,7 +33,72 @@ pub enum ParserRISCVLabel { Unknown(Pos), // the label position in the code (mustn't exist in the output) } +pub trait ParserRISCVInstOpTrait: Clone + Copy + std::fmt::Debug + PartialEq + Eq { + fn get_name(&self) -> &'static str; +} +pub trait ParserRISCVRegisterTrait: Clone + Copy + std::fmt::Debug + PartialEq + Eq { + fn get_name(&self) -> &'static str; +} + impl ParserInstSet for RISCV { type Operator = ParserRISCVInstOp; type Operand = ParserRISCVInstOpd; } + +// ------------------------- Implementations ------------------------- + +impl From for ParserRISCVInstOp { + fn from(op: T) -> Self { + ParserRISCVInstOp(AnyU8::from(op), op.get_name()) + } +} + +impl ParserRISCVInstOp { + pub fn is(&self) -> bool + where + T: 'static, + { + self.0.is::() + } + + pub fn to(&self) -> Option + where + T: 'static, + { + self.0.to::() + } +} + +impl From for ParserRISCVRegister { + fn from(reg: T) -> Self { + ParserRISCVRegister(AnyU8::from(reg), reg.get_name()) + } +} + +impl ParserRISCVRegister { + pub fn is(&self) -> bool + where + T: 'static, + { + self.0.is::() + } + + pub fn to(&self) -> Option + where + T: 'static, + { + self.0.to::() + } +} + +impl std::fmt::Debug for ParserRISCVInstOp { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(self.1) + } +} + +impl std::fmt::Debug for ParserRISCVRegister { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(self.1) + } +} diff --git a/src-tauri/src/modules/riscv/basic/parser/label.rs b/src-tauri/src/modules/riscv/basic/parser/label.rs index 1bf6214f..2932b0cc 100644 --- a/src-tauri/src/modules/riscv/basic/parser/label.rs +++ b/src-tauri/src/modules/riscv/basic/parser/label.rs @@ -1,12 +1,6 @@ use super::super::super::basic::interface::parser::*; use crate::utility::ptr::Ptr; -#[derive(Clone, Debug)] -pub(super) enum LabelDef { - Text(ParserResultText), - Data(ParserResultData), -} - #[derive(Clone)] pub(super) struct LabelData { pub name: String, diff --git a/src-tauri/src/modules/riscv/basic/parser/lexer.rs b/src-tauri/src/modules/riscv/basic/parser/lexer.rs index 923f6f11..e9db9eb5 100644 --- a/src-tauri/src/modules/riscv/basic/parser/lexer.rs +++ b/src-tauri/src/modules/riscv/basic/parser/lexer.rs @@ -1,28 +1,38 @@ -use super::super::interface::parser::{ParseRISCVRegisterError, RISCVCsr, RISCVRegister}; +use super::super::interface::parser::{ParserRISCVCsr, ParserRISCVRegister}; use super::oplist::RISCVOpdSet; use crate::interface::parser::{ParserError, Pos}; use logos::Logos; use std::fmt::Display; -static EXTENSION: [fn(&str) -> Option<&'static dyn RISCVOpToken>; 1] = - [super::super::super::rv32i::parser::lexer::op_lexer]; +static EXTENSION: [LexerExtension; 1] = [LexerExtension { + name: "rv32i", + parse_op: super::super::super::rv32i::parser::lexer::parse_op, + parse_reg: super::super::super::rv32i::parser::lexer::parse_reg, +}]; + +pub struct LexerExtension { + pub name: &'static str, + pub parse_op: fn(&str) -> Option, + pub parse_reg: fn(&str) -> Option, +} #[derive(Debug, PartialEq, Clone, Default)] pub enum LexingError { NumberParseError, - RegisterParseError, #[default] Other, } pub enum Symbol<'a> { Label(&'a str), - Op(&'static dyn RISCVOpToken), + Op(RISCVOpToken), + Reg(ParserRISCVRegister), } -pub trait RISCVOpToken { +pub trait RISCVOpTokenTrait { fn get_opd_set(&self) -> &Vec; } +pub type RISCVOpToken = &'static dyn RISCVOpTokenTrait; pub(super) struct LexerIter<'a> { pub raw: logos::Lexer<'a, RISCVToken<'a>>, @@ -80,7 +90,10 @@ impl LexerIter<'_> { fn dispatch_symbol(token: &str) -> Symbol { for ext in &EXTENSION { - if let Some(op) = ext(token) { + if let Some(reg) = (ext.parse_reg)(token) { + return Symbol::Reg(reg); + } + if let Some(op) = (ext.parse_op)(token) { return Symbol::Op(op); } } @@ -111,17 +124,7 @@ pub enum RISCVToken<'a> { Symbol(Symbol<'a>), #[regex(r"%[a-zA-Z_][a-zA-Z0-9_]*")] MacroParameter(&'a str), - #[token("zero", |lex| lex.slice().parse(), priority = 10)] - #[token("ra", |lex| lex.slice().parse(), priority = 10)] - #[token("sp", |lex| lex.slice().parse(), priority = 10)] - #[token("gp", |lex| lex.slice().parse(), priority = 10)] - #[token("tp", |lex| lex.slice().parse(), priority = 10)] - #[regex(r"t[0-6]", |lex| lex.slice().parse(), priority = 10)] - #[regex(r"s([0-9]|(1[0-1]))", |lex| lex.slice().parse(), priority = 10)] - #[regex(r"a[0-7]", |lex| lex.slice().parse(), priority = 10)] - #[regex(r"x(([1-2]?[0-9])|(3[0-1]))", |lex| lex.slice().parse(), priority = 10)] - Register(RISCVRegister), - Csr(RISCVCsr), + Csr(ParserRISCVCsr), #[token(".align", priority = 10)] Align, #[token(".ascii", priority = 10)] @@ -180,17 +183,10 @@ impl From for LexingError { } } -impl From for LexingError { - fn from(_: ParseRISCVRegisterError) -> Self { - LexingError::RegisterParseError - } -} - impl Display for LexingError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { LexingError::NumberParseError => write!(f, "Number parse error"), - LexingError::RegisterParseError => write!(f, "Register parse error"), LexingError::Other => write!(f, "unrecognized character"), } } diff --git a/src-tauri/src/modules/riscv/basic/parser/macro.rs b/src-tauri/src/modules/riscv/basic/parser/macro.rs index 1a453de1..902bfc5a 100644 --- a/src-tauri/src/modules/riscv/basic/parser/macro.rs +++ b/src-tauri/src/modules/riscv/basic/parser/macro.rs @@ -15,22 +15,22 @@ pub(super) struct MacroData { pub ret_seg: RISCVSegment, } -impl PartialEq for MacroData { - fn eq(&self, other: &Self) -> bool { - self.name == other.name - } -} +// impl PartialEq for MacroData { +// fn eq(&self, other: &Self) -> bool { +// self.name == other.name +// } +// } -impl Eq for MacroData {} +// impl Eq for MacroData {} -impl PartialOrd for MacroData { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} +// impl PartialOrd for MacroData { +// fn partial_cmp(&self, other: &Self) -> Option { +// Some(self.cmp(other)) +// } +// } -impl Ord for MacroData { - fn cmp(&self, other: &Self) -> std::cmp::Ordering { - self.name.cmp(&other.name) - } -} +// impl Ord for MacroData { +// fn cmp(&self, other: &Self) -> std::cmp::Ordering { +// self.name.cmp(&other.name) +// } +// } diff --git a/src-tauri/src/modules/riscv/basic/parser/oplist.rs b/src-tauri/src/modules/riscv/basic/parser/oplist.rs index f337b8ea..8df43fa4 100644 --- a/src-tauri/src/modules/riscv/basic/parser/oplist.rs +++ b/src-tauri/src/modules/riscv/basic/parser/oplist.rs @@ -1,19 +1,17 @@ +use crate::modules::riscv::basic::interface::parser::ParserRISCVRegisterTrait; + use super::super::interface::parser::{ - ParserRISCVInstOp, ParserRISCVInstOpd, RISCVImmediate, RISCVRegister, + ParserRISCVImmediate, ParserRISCVInstOp, ParserRISCVInstOpd, }; #[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum RISCVImmediateType { +pub enum RISCVExpectImm { U4, U5, U12, U20, - U32, - U64, I12, - I20, I32, - I64, } #[derive(Clone, Copy, Debug, PartialEq, Eq)] @@ -23,7 +21,7 @@ pub enum RISCVExpectToken { RParen, Reg, Csr, - Imm(RISCVImmediateType), + Imm(RISCVExpectImm), Lbl, } @@ -52,20 +50,16 @@ pub struct RISCVOpdSet { pub aim_basics: Vec, } +pub use RISCVExpectImm::*; pub use RISCVExpectToken::*; -pub use RISCVImmediateType::*; -pub use RISCVRegister::*; // --------------------reg------------------------- -pub fn reg(reg: RISCVRegister) -> RISCVOpdSetAimOpd { - RISCVOpdSetAimOpd::Val(ParserRISCVInstOpd::Reg(reg)) +pub fn reg(reg: T) -> RISCVOpdSetAimOpd { + RISCVOpdSetAimOpd::Val(ParserRISCVInstOpd::Reg(reg.into())) } // --------------------imm------------------------- pub fn imm_i(imm: i128) -> RISCVOpdSetAimOpd { - RISCVOpdSetAimOpd::Val(ParserRISCVInstOpd::Imm(RISCVImmediate::Int(imm))) -} -pub fn imm_f(imm: f64) -> RISCVOpdSetAimOpd { - RISCVOpdSetAimOpd::Val(ParserRISCVInstOpd::Imm(RISCVImmediate::Float(imm))) + RISCVOpdSetAimOpd::Val(ParserRISCVInstOpd::Imm(ParserRISCVImmediate::Int(imm))) } // --------------------idx------------------------- pub fn idx(idx: usize) -> RISCVOpdSetAimOpd { @@ -78,24 +72,24 @@ pub fn idx_handler( RISCVOpdSetAimOpd::Idx(RISCVOpdSetAimOpdIdx { idx, handler }) } pub fn idx_handler_low(opd: ParserRISCVInstOpd) -> ParserRISCVInstOpd { - if let ParserRISCVInstOpd::Imm(RISCVImmediate::Int(i)) = opd { + if let ParserRISCVInstOpd::Imm(ParserRISCVImmediate::Int(i)) = opd { if i & 0x800 != 0 { - ParserRISCVInstOpd::Imm(RISCVImmediate::Int(-(i & 0x7ff))) + ParserRISCVInstOpd::Imm(ParserRISCVImmediate::Int(-(i & 0x7ff))) } else { - ParserRISCVInstOpd::Imm(RISCVImmediate::Int(i & 0x7ff)) + ParserRISCVInstOpd::Imm(ParserRISCVImmediate::Int(i & 0x7ff)) } } else { opd } } pub fn idx_handler_high(opd: ParserRISCVInstOpd) -> ParserRISCVInstOpd { - if let ParserRISCVInstOpd::Imm(RISCVImmediate::Int(i)) = opd { + if let ParserRISCVInstOpd::Imm(ParserRISCVImmediate::Int(i)) = opd { if i & 0x800 != 0 { - ParserRISCVInstOpd::Imm(RISCVImmediate::Int( + ParserRISCVInstOpd::Imm(ParserRISCVImmediate::Int( ((i as u32 + 0x0000_1000) >> 12) as i128, )) } else { - ParserRISCVInstOpd::Imm(RISCVImmediate::Int(((i as u32) >> 12) as i128)) + ParserRISCVInstOpd::Imm(ParserRISCVImmediate::Int(((i as u32) >> 12) as i128)) } } else { opd @@ -179,61 +173,3 @@ pub fn opd_set( pub fn opd_set_no_opd(op: ParserRISCVInstOp, name: &str) -> RISCVOpdSet { opd_set(vec![], vec![basic_op(op, vec![])], name.to_string()) } -pub fn opd_set_sl_mem( - op: ParserRISCVInstOp, - name: &str, - unit: &str, - src: [&str; 5], - dst: [&str; 5], -) -> Vec { - vec![ - opd_set( - expect_opd(vec![Reg, Comma, Imm(I12), LParen, Reg, RParen]), - vec![basic_op_024(op)], - format!("{} t1, -0x1(t2) ({} = {}{})", name, dst[0], unit, src[0]), - ), - opd_set( - expect_opd(vec![Reg, Comma, LParen, Reg, RParen]), - vec![basic_op(op, vec![idx(0), imm_i(0), idx(3)])], - format!("{} t1, (t2) ({} = {}{})", name, dst[1], unit, src[1]), - ), - opd_set( - expect_reg_any(Imm(I12)), - vec![basic_op(op, vec![idx(0), idx(2), reg(Zero)])], - format!("{} t1, -0x1 ({} = {}{})", name, dst[2], unit, src[2]), - ), - opd_set( - expect_reg_any(Imm(I32)), - vec![ - basic_op( - ParserRISCVInstOp::Lui, - vec![reg(A0), idx_handler(2, idx_handler_high)], - ), - basic_op(op, vec![idx(0), idx_handler(2, idx_handler_low), reg(A0)]), - ], - format!( - "{} t1, 0x100000 (a0 = 0x100000[12:31](i32); {} = {}{})", - name, dst[3], unit, src[3] - ), - ), - opd_set( - expect_reg_any(Lbl), - vec![basic_op_024(op)], - format!("{} t1, label ({} = {}{})", name, dst[4], unit, src[4]), - ), - ] -} -const SL_MEM_REG: [&str; 5] = ["t1", "t1", "t1", "t1", "t1"]; -const SL_MEM_MEM: [&str; 5] = [ - "mem[t2 + -0x1(i12)]", - "mem[t2]", - "mem[-0x1(i12)]", - "mem[a0 + 0x100000[0:11](i32)]", - "mem[label]", -]; -pub fn opd_set_load_mem(op: ParserRISCVInstOp, name: &str, unit: &str) -> Vec { - opd_set_sl_mem(op, name, unit, SL_MEM_MEM, SL_MEM_REG) -} -pub fn opd_set_store_mem(op: ParserRISCVInstOp, name: &str, unit: &str) -> Vec { - opd_set_sl_mem(op, name, unit, SL_MEM_REG, SL_MEM_MEM) -} diff --git a/src-tauri/src/modules/riscv/basic/parser/parser.rs b/src-tauri/src/modules/riscv/basic/parser/parser.rs index fb3662d7..5fe1debe 100644 --- a/src-tauri/src/modules/riscv/basic/parser/parser.rs +++ b/src-tauri/src/modules/riscv/basic/parser/parser.rs @@ -1,7 +1,7 @@ use super::super::interface::parser::*; use super::label::LabelData; -use super::lexer::{LexerIter, RISCVOpToken, RISCVToken, Symbol}; -use super::oplist::{RISCVExpectToken, RISCVImmediateType, RISCVOpdSetAim, RISCVOpdSetAimOpd}; +use super::lexer::{LexerIter, RISCVOpTokenTrait, RISCVToken, Symbol}; +use super::oplist::{RISCVExpectImm, RISCVExpectToken, RISCVOpdSetAim, RISCVOpdSetAimOpd}; use super::r#macro::MacroData; use crate::utility::ptr::Ptr; use logos::Logos; @@ -75,8 +75,8 @@ impl RISCVParserStatus<'_> { } } +use RISCVExpectImm::*; use RISCVExpectToken::*; -use RISCVImmediateType::*; macro_rules! load_data_helper { ($label_list:expr, $status:expr, $vec:expr) => { @@ -191,7 +191,7 @@ impl RISCVParser { RISCVOpdSetAimOpd::Idx(idx) => { inst.opd.push((idx.handler)(stash_opd[idx.idx].unwrap())) } - RISCVOpdSetAimOpd::Val(val) => inst.opd.push(val.clone()), + RISCVOpdSetAimOpd::Val(val) => inst.opd.push(*val), } } result.text.push(ParserResultText::Text(inst)); @@ -260,7 +260,7 @@ impl RISCVParser { fn parse_op( &mut self, status_ptr: Ptr, - op: &dyn RISCVOpToken, + op: &dyn RISCVOpTokenTrait, ) -> Result<(), Vec> { let status = status_ptr.as_mut(); @@ -310,21 +310,15 @@ impl RISCVParser { Comma => type_fit = matches!(token, RISCVToken::Comma), LParen => type_fit = matches!(token, RISCVToken::LParen), RParen => type_fit = matches!(token, RISCVToken::RParen), - Reg => type_fit = matches!(token, RISCVToken::Register(_)), + Reg => type_fit = matches!(token, RISCVToken::Symbol(Symbol::Reg(_))), Csr => type_fit = matches!(token, RISCVToken::Csr(_)), Imm(imm_t) => match imm_t { U4 => type_fit = Self::in_bound_int(&token, 0, 0xf), U5 => type_fit = Self::in_bound_int(&token, 0, 0x1f), U12 => type_fit = Self::in_bound_int(&token, 0, 0xfff), U20 => type_fit = Self::in_bound_int(&token, 0, 0xf_ffff), - U32 => type_fit = Self::in_bound_int(&token, 0, 0xffff_ffff), - U64 => type_fit = Self::in_bound_int(&token, 0, u64::MAX as i128), I12 => type_fit = Self::in_bound_int(&token, -0x800, 0x7ff), - I20 => type_fit = Self::in_bound_int(&token, -0x8_0000, 0x7_ffff), I32 => type_fit = Self::in_bound_int(&token, -0x8000_0000, 0x7fff_ffff), - I64 => { - type_fit = Self::in_bound_int(&token, i64::MIN as i128, i64::MAX as i128) - } }, Lbl => type_fit = matches!(token, RISCVToken::Symbol(Symbol::Label(_))), } @@ -343,12 +337,14 @@ impl RISCVParser { } // stash operand match token { - RISCVToken::Register(reg) => { + RISCVToken::Symbol(Symbol::Reg(reg)) => { stash_opd.push(Some(ParserRISCVInstOpd::Reg(reg))); stash_label_name.push(String::new()); } RISCVToken::ImmediateInt(val) => { - stash_opd.push(Some(ParserRISCVInstOpd::Imm(RISCVImmediate::Int(val)))); + stash_opd.push(Some(ParserRISCVInstOpd::Imm(ParserRISCVImmediate::Int( + val, + )))); stash_label_name.push(String::new()); } RISCVToken::Symbol(Symbol::Label(lbl)) => { @@ -483,8 +479,9 @@ impl RISCVParser { Ok(()) } Symbol::Op(op) => self.parse_op(status_ptr, op), + Symbol::Reg(_) => Err(status.iter.get_error("unexpected symbol".to_string())), }, - RISCVToken::MacroParameter(_) | RISCVToken::Register(_) | RISCVToken::Csr(_) => { + RISCVToken::MacroParameter(_) | RISCVToken::Csr(_) => { Err(status.iter.get_error("unexpected symbol".to_string())) } RISCVToken::Align => { diff --git a/src-tauri/src/modules/riscv/rv32i/constants.rs b/src-tauri/src/modules/riscv/rv32i/constants.rs index 81472148..69e87500 100644 --- a/src-tauri/src/modules/riscv/rv32i/constants.rs +++ b/src-tauri/src/modules/riscv/rv32i/constants.rs @@ -1,7 +1,11 @@ +use super::super::basic::interface::parser::{ParserRISCVInstOpTrait, ParserRISCVRegisterTrait}; +use lazy_static::lazy_static; +use std::collections::HashMap; use std::str::FromStr; +use strum::{EnumIter, IntoEnumIterator}; -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum RISCVRegister { +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, EnumIter)] +pub enum RV32IRegister { Zero, Ra, Sp, @@ -36,8 +40,8 @@ pub enum RISCVRegister { T6, } -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum RISCVInstruction { +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, EnumIter)] +pub enum RV32IInstruction { Add, Addi, And, @@ -96,46 +100,68 @@ pub enum RISCVImmediate { #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum RISCVCsr {} -pub struct ParseRISCVRegisterError; +pub struct ParseRV32IRegisterError; -impl FromStr for RISCVRegister { - type Err = ParseRISCVRegisterError; +impl FromStr for RV32IRegister { + type Err = ParseRV32IRegisterError; fn from_str(s: &str) -> Result { match s { - "zero" | "x0" => Ok(RISCVRegister::Zero), - "ra" | "x1" => Ok(RISCVRegister::Ra), - "sp" | "x2" => Ok(RISCVRegister::Sp), - "gp" | "x3" => Ok(RISCVRegister::Gp), - "tp" | "x4" => Ok(RISCVRegister::Tp), - "t0" | "x5" => Ok(RISCVRegister::T0), - "t1" | "x6" => Ok(RISCVRegister::T1), - "t2" | "x7" => Ok(RISCVRegister::T2), - "s0" | "x8" => Ok(RISCVRegister::S0), - "s1" | "x9" => Ok(RISCVRegister::S1), - "a0" | "x10" => Ok(RISCVRegister::A0), - "a1" | "x11" => Ok(RISCVRegister::A1), - "a2" | "x12" => Ok(RISCVRegister::A2), - "a3" | "x13" => Ok(RISCVRegister::A3), - "a4" | "x14" => Ok(RISCVRegister::A4), - "a5" | "x15" => Ok(RISCVRegister::A5), - "a6" | "x16" => Ok(RISCVRegister::A6), - "a7" | "x17" => Ok(RISCVRegister::A7), - "s2" | "x18" => Ok(RISCVRegister::S2), - "s3" | "x19" => Ok(RISCVRegister::S3), - "s4" | "x20" => Ok(RISCVRegister::S4), - "s5" | "x21" => Ok(RISCVRegister::S5), - "s6" | "x22" => Ok(RISCVRegister::S6), - "s7" | "x23" => Ok(RISCVRegister::S7), - "s8" | "x24" => Ok(RISCVRegister::S8), - "s9" | "x25" => Ok(RISCVRegister::S9), - "s10" | "x26" => Ok(RISCVRegister::S10), - "s11" | "x27" => Ok(RISCVRegister::S11), - "t3" | "x28" => Ok(RISCVRegister::T3), - "t4" | "x29" => Ok(RISCVRegister::T4), - "t5" | "x30" => Ok(RISCVRegister::T5), - "t6" | "x31" => Ok(RISCVRegister::T6), - _ => Err(ParseRISCVRegisterError), + "zero" | "x0" => Ok(RV32IRegister::Zero), + "ra" | "x1" => Ok(RV32IRegister::Ra), + "sp" | "x2" => Ok(RV32IRegister::Sp), + "gp" | "x3" => Ok(RV32IRegister::Gp), + "tp" | "x4" => Ok(RV32IRegister::Tp), + "t0" | "x5" => Ok(RV32IRegister::T0), + "t1" | "x6" => Ok(RV32IRegister::T1), + "t2" | "x7" => Ok(RV32IRegister::T2), + "s0" | "x8" => Ok(RV32IRegister::S0), + "s1" | "x9" => Ok(RV32IRegister::S1), + "a0" | "x10" => Ok(RV32IRegister::A0), + "a1" | "x11" => Ok(RV32IRegister::A1), + "a2" | "x12" => Ok(RV32IRegister::A2), + "a3" | "x13" => Ok(RV32IRegister::A3), + "a4" | "x14" => Ok(RV32IRegister::A4), + "a5" | "x15" => Ok(RV32IRegister::A5), + "a6" | "x16" => Ok(RV32IRegister::A6), + "a7" | "x17" => Ok(RV32IRegister::A7), + "s2" | "x18" => Ok(RV32IRegister::S2), + "s3" | "x19" => Ok(RV32IRegister::S3), + "s4" | "x20" => Ok(RV32IRegister::S4), + "s5" | "x21" => Ok(RV32IRegister::S5), + "s6" | "x22" => Ok(RV32IRegister::S6), + "s7" | "x23" => Ok(RV32IRegister::S7), + "s8" | "x24" => Ok(RV32IRegister::S8), + "s9" | "x25" => Ok(RV32IRegister::S9), + "s10" | "x26" => Ok(RV32IRegister::S10), + "s11" | "x27" => Ok(RV32IRegister::S11), + "t3" | "x28" => Ok(RV32IRegister::T3), + "t4" | "x29" => Ok(RV32IRegister::T4), + "t5" | "x30" => Ok(RV32IRegister::T5), + "t6" | "x31" => Ok(RV32IRegister::T6), + _ => Err(ParseRV32IRegisterError), } } } + +impl ParserRISCVRegisterTrait for RV32IRegister { + fn get_name(&self) -> &'static str { + RV32I_REGISTER_NAME.get(self).unwrap() + } +} + +impl ParserRISCVInstOpTrait for RV32IInstruction { + fn get_name(&self) -> &'static str { + RV32I_INSTRUCTION_NAME.get(self).unwrap() + } +} + +lazy_static! { + static ref RV32I_REGISTER_NAME: HashMap = + HashMap::from_iter(RV32IRegister::iter().map(|reg| (reg, format!("{:?}", reg)))); +} + +lazy_static! { + static ref RV32I_INSTRUCTION_NAME: HashMap = + HashMap::from_iter(RV32IInstruction::iter().map(|inst| (inst, format!("{:?}", inst)))); +} diff --git a/src-tauri/src/modules/riscv/rv32i/parser/lexer.rs b/src-tauri/src/modules/riscv/rv32i/parser/lexer.rs index 1fa9af05..8dd03ffe 100644 --- a/src-tauri/src/modules/riscv/rv32i/parser/lexer.rs +++ b/src-tauri/src/modules/riscv/rv32i/parser/lexer.rs @@ -1,16 +1,24 @@ -use std::collections::HashMap; - -use super::super::super::basic::parser::lexer::RISCVOpToken; +use super::super::super::basic::interface::parser::ParserRISCVRegister; +use super::super::super::basic::parser::lexer::{RISCVOpToken, RISCVOpTokenTrait}; +use super::super::constants::RV32IRegister; use super::oplist::{RISCVOpdSet, OP_LIST}; use lazy_static::lazy_static; +use std::collections::HashMap; -pub fn op_lexer(op: &str) -> Option<&'static dyn RISCVOpToken> { +pub fn parse_op(op: &str) -> Option { match OP_TOKEN.get(op) { - Some(op) => Some(op as &dyn RISCVOpToken), + Some(op) => Some(op), None => None, } } +pub fn parse_reg(op: &str) -> Option { + match op.parse::() { + Ok(reg) => Some(reg.into()), + Err(_) => None, + } +} + lazy_static! { static ref OP_TOKEN: HashMap<&'static str, RV32IOpToken> = HashMap::from([ ("add", RV32IOpToken::Add), @@ -367,7 +375,7 @@ pub enum RV32IOpToken { ZextH, } -impl RISCVOpToken for RV32IOpToken { +impl RISCVOpTokenTrait for RV32IOpToken { fn get_opd_set(&self) -> &Vec { &OP_LIST.get(self).unwrap() } diff --git a/src-tauri/src/modules/riscv/rv32i/parser/mod.rs b/src-tauri/src/modules/riscv/rv32i/parser/mod.rs index fda211a8..0eb580d3 100644 --- a/src-tauri/src/modules/riscv/rv32i/parser/mod.rs +++ b/src-tauri/src/modules/riscv/rv32i/parser/mod.rs @@ -1,2 +1,2 @@ -pub mod oplist; pub mod lexer; +pub mod oplist; diff --git a/src-tauri/src/modules/riscv/rv32i/parser/oplist.rs b/src-tauri/src/modules/riscv/rv32i/parser/oplist.rs index 55653542..a4175fbd 100644 --- a/src-tauri/src/modules/riscv/rv32i/parser/oplist.rs +++ b/src-tauri/src/modules/riscv/rv32i/parser/oplist.rs @@ -1,18 +1,81 @@ use super::super::super::basic::interface::parser::ParserRISCVInstOp; use super::super::super::basic::parser::oplist::*; +use super::super::constants::{RV32IInstruction, RV32IRegister}; use super::lexer::RV32IOpToken; use lazy_static::lazy_static; use std::collections::HashMap; pub use super::super::super::basic::parser::oplist::RISCVOpdSet; +use RV32IRegister::*; + +// --------------------set------------------------- +pub fn opd_set_sl_mem( + op: ParserRISCVInstOp, + name: &str, + unit: &str, + src: [&str; 5], + dst: [&str; 5], +) -> Vec { + vec![ + opd_set( + expect_opd(vec![Reg, Comma, Imm(I12), LParen, Reg, RParen]), + vec![basic_op_024(op)], + format!("{} t1, -0x1(t2) ({} = {}{})", name, dst[0], unit, src[0]), + ), + opd_set( + expect_opd(vec![Reg, Comma, LParen, Reg, RParen]), + vec![basic_op(op, vec![idx(0), imm_i(0), idx(3)])], + format!("{} t1, (t2) ({} = {}{})", name, dst[1], unit, src[1]), + ), + opd_set( + expect_reg_any(Imm(I12)), + vec![basic_op(op, vec![idx(0), idx(2), reg(Zero)])], + format!("{} t1, -0x1 ({} = {}{})", name, dst[2], unit, src[2]), + ), + opd_set( + expect_reg_any(Imm(I32)), + vec![ + basic_op( + RV32IInstruction::Lui.into(), + vec![reg(A0), idx_handler(2, idx_handler_high)], + ), + basic_op(op, vec![idx(0), idx_handler(2, idx_handler_low), reg(A0)]), + ], + format!( + "{} t1, 0x100000 (a0 = 0x100000[12:31](i32); {} = {}{})", + name, dst[3], unit, src[3] + ), + ), + opd_set( + expect_reg_any(Lbl), + vec![basic_op_024(op)], + format!("{} t1, label ({} = {}{})", name, dst[4], unit, src[4]), + ), + ] +} +const SL_MEM_REG: [&str; 5] = ["t1", "t1", "t1", "t1", "t1"]; +const SL_MEM_MEM: [&str; 5] = [ + "mem[t2 + -0x1(i12)]", + "mem[t2]", + "mem[-0x1(i12)]", + "mem[a0 + 0x100000[0:11](i32)]", + "mem[label]", +]; +pub fn opd_set_load_mem(op: ParserRISCVInstOp, name: &str, unit: &str) -> Vec { + opd_set_sl_mem(op, name, unit, SL_MEM_MEM, SL_MEM_REG) +} +pub fn opd_set_store_mem(op: ParserRISCVInstOp, name: &str, unit: &str) -> Vec { + opd_set_sl_mem(op, name, unit, SL_MEM_REG, SL_MEM_MEM) +} + lazy_static! { pub static ref OP_LIST: HashMap> = HashMap::from([ ( RV32IOpToken::Add, vec![opd_set( expect_reg_reg_reg(), - vec![basic_op_024(ParserRISCVInstOp::Add)], + vec![basic_op_024(RV32IInstruction::Add.into())], hint_reg_reg_reg("add", "+") )] ), @@ -21,12 +84,12 @@ lazy_static! { vec![ opd_set( expect_reg_reg_any(Imm(I12)), - vec![basic_op_024(ParserRISCVInstOp::Addi)], + vec![basic_op_024(RV32IInstruction::Addi.into())], hint_reg_reg_any("addi", "-0x1(i12)", "+") ), opd_set( expect_reg_reg_any(Lbl), - vec![basic_op_024(ParserRISCVInstOp::Addi)], + vec![basic_op_024(RV32IInstruction::Addi.into())], hint_reg_reg_any("addi", "label[0:11]", "+") ), ] @@ -35,7 +98,7 @@ lazy_static! { RV32IOpToken::And, vec![opd_set( expect_reg_reg_reg(), - vec![basic_op_024(ParserRISCVInstOp::And)], + vec![basic_op_024(RV32IInstruction::And.into())], hint_reg_reg_reg("and", "&") )] ), @@ -43,7 +106,7 @@ lazy_static! { RV32IOpToken::Andi, vec![opd_set( expect_reg_reg_any(Imm(U12)), - vec![basic_op_024(ParserRISCVInstOp::Andi)], + vec![basic_op_024(RV32IInstruction::Andi.into())], hint_reg_reg_any("andi", "0x1(u12)", "&") )] ), @@ -51,7 +114,7 @@ lazy_static! { RV32IOpToken::Auipc, vec![opd_set( expect_reg_any(Imm(U20)), - vec![basic_op_02(ParserRISCVInstOp::Auipc)], + vec![basic_op_02(RV32IInstruction::Auipc.into())], "auipc t1, 0x1000 (t1 = pc + 0x1000(u20))".to_string() )] ), @@ -59,7 +122,7 @@ lazy_static! { RV32IOpToken::Beq, vec![opd_set( expect_reg_reg_any(Lbl), - vec![basic_op_024(ParserRISCVInstOp::Beq)], + vec![basic_op_024(RV32IInstruction::Beq.into())], hint_branch("beq", "==", " (signed)") )] ), @@ -67,7 +130,7 @@ lazy_static! { RV32IOpToken::Bge, vec![opd_set( expect_reg_reg_any(Lbl), - vec![basic_op_024(ParserRISCVInstOp::Bge)], + vec![basic_op_024(RV32IInstruction::Bge.into())], hint_branch("bge", ">=", " (signed)") )] ), @@ -75,7 +138,7 @@ lazy_static! { RV32IOpToken::Bgeu, vec![opd_set( expect_reg_reg_any(Lbl), - vec![basic_op_024(ParserRISCVInstOp::Bgeu)], + vec![basic_op_024(RV32IInstruction::Bgeu.into())], hint_branch("bgeu", ">=", " (unsigned)") )] ), @@ -83,7 +146,7 @@ lazy_static! { RV32IOpToken::Blt, vec![opd_set( expect_reg_reg_any(Lbl), - vec![basic_op_024(ParserRISCVInstOp::Blt)], + vec![basic_op_024(RV32IInstruction::Blt.into())], hint_branch("blt", "<", " (signed)") )] ), @@ -91,7 +154,7 @@ lazy_static! { RV32IOpToken::Bltu, vec![opd_set( expect_reg_reg_any(Lbl), - vec![basic_op_024(ParserRISCVInstOp::Bltu)], + vec![basic_op_024(RV32IInstruction::Bltu.into())], hint_branch("bltu", "<", " (unsigned)") )] ), @@ -99,7 +162,7 @@ lazy_static! { RV32IOpToken::Bne, vec![opd_set( expect_reg_reg_any(Lbl), - vec![basic_op_024(ParserRISCVInstOp::Bne)], + vec![basic_op_024(RV32IInstruction::Bne.into())], hint_branch("bne", "!=", " (signed)") )] ), @@ -107,7 +170,7 @@ lazy_static! { RV32IOpToken::Csrrc, vec![opd_set( expect_csr(Reg), - vec![basic_op_024(ParserRISCVInstOp::Csrrc)], + vec![basic_op_024(RV32IInstruction::Csrrc.into())], hint_csr("csrrc", "&= ~", "t2") )] ), @@ -115,7 +178,7 @@ lazy_static! { RV32IOpToken::Csrrci, vec![opd_set( expect_csr(Imm(U5)), - vec![basic_op_024(ParserRISCVInstOp::Csrrci)], + vec![basic_op_024(RV32IInstruction::Csrrci.into())], hint_csr("csrrci", "&= ~", "0x1(u5)") )] ), @@ -123,7 +186,7 @@ lazy_static! { RV32IOpToken::Csrrs, vec![opd_set( expect_csr(Reg), - vec![basic_op_024(ParserRISCVInstOp::Csrrs)], + vec![basic_op_024(RV32IInstruction::Csrrs.into())], hint_csr("csrrs", "|=", "t2") )] ), @@ -131,7 +194,7 @@ lazy_static! { RV32IOpToken::Csrrsi, vec![opd_set( expect_csr(Imm(U5)), - vec![basic_op_024(ParserRISCVInstOp::Csrrsi)], + vec![basic_op_024(RV32IInstruction::Csrrsi.into())], hint_csr("csrrsi", "|=", "0x1(u5)") )] ), @@ -139,7 +202,7 @@ lazy_static! { RV32IOpToken::Csrrw, vec![opd_set( expect_csr(Reg), - vec![basic_op_024(ParserRISCVInstOp::Csrrw)], + vec![basic_op_024(RV32IInstruction::Csrrw.into())], hint_csr("csrrw", "=", "t2") )] ), @@ -147,7 +210,7 @@ lazy_static! { RV32IOpToken::Csrrwi, vec![opd_set( expect_csr(Imm(U5)), - vec![basic_op_024(ParserRISCVInstOp::Csrrwi)], + vec![basic_op_024(RV32IInstruction::Csrrwi.into())], hint_csr("csrrwi", "=", "0x1(u5)") )] ), @@ -155,11 +218,11 @@ lazy_static! { (RV32IOpToken::Divu, vec![]), ( RV32IOpToken::Ebreak, - vec![opd_set_no_opd(ParserRISCVInstOp::Ebreak, "ebreak")] + vec![opd_set_no_opd(RV32IInstruction::Ebreak.into(), "ebreak")] ), ( RV32IOpToken::Ecall, - vec![opd_set_no_opd(ParserRISCVInstOp::Ecall, "ecall")] + vec![opd_set_no_opd(RV32IInstruction::Ecall.into(), "ecall")] ), (RV32IOpToken::FaddD, vec![]), (RV32IOpToken::FaddS, vec![]), @@ -181,13 +244,13 @@ lazy_static! { RV32IOpToken::Fence, vec![opd_set( expect_opd(vec![Imm(U4), Comma, Imm(U4)]), - vec![basic_op_02(ParserRISCVInstOp::Fence)], + vec![basic_op_02(RV32IInstruction::Fence.into())], "fence 0x1(u4), 0x1(u4)".to_string() )] ), ( RV32IOpToken::FenceI, - vec![opd_set_no_opd(ParserRISCVInstOp::FenceI, "fence.i")] + vec![opd_set_no_opd(RV32IInstruction::FenceI.into(), "fence.i")] ), (RV32IOpToken::FeqD, vec![]), (RV32IOpToken::FeqS, vec![]), @@ -230,12 +293,15 @@ lazy_static! { vec![ opd_set( expect_opd(vec![Lbl]), - vec![basic_op(ParserRISCVInstOp::Jal, vec![reg(Ra), idx(0)])], + vec![basic_op( + RV32IInstruction::Jal.into(), + vec![reg(Ra), idx(0)] + )], "jal label (ra = pc + 4; pc = label)".to_string() ), opd_set( expect_reg_any(Lbl), - vec![basic_op_02(ParserRISCVInstOp::Jal)], + vec![basic_op_02(RV32IInstruction::Jal.into())], "jal t1, label (t1 = pc + 4; pc = label)".to_string() ) ] @@ -245,13 +311,13 @@ lazy_static! { vec![ opd_set( expect_reg_reg_any(Imm(I12)), - vec![basic_op_024(ParserRISCVInstOp::Jalr)], + vec![basic_op_024(RV32IInstruction::Jalr.into())], "jalr t1, t2, -0x1(i12) (t1 = pc + 4; pc = t2 + -0x1(i12))".to_string() ), opd_set( expect_opd(vec![Reg]), vec![basic_op( - ParserRISCVInstOp::Jalr, + RV32IInstruction::Jalr.into(), vec![reg(Ra), idx(0), imm_i(0)] )], "jalr t0 (ra = pc + 4; pc = t0)".to_string() @@ -259,52 +325,52 @@ lazy_static! { opd_set( expect_reg_any(Imm(I12)), vec![basic_op( - ParserRISCVInstOp::Jalr, + RV32IInstruction::Jalr.into(), vec![reg(Ra), idx(0), idx(2)] )], "jalr t1, -0x1 (ra = pc + 4; pc = t1 + -0x1(i12))".to_string() ), opd_set( expect_opd(vec![Reg, Comma, Imm(I12), LParen, Reg, RParen]), - vec![basic_op_042(ParserRISCVInstOp::Jalr)], + vec![basic_op_042(RV32IInstruction::Jalr.into())], "jalr t1, -0x1(t2) (t1 = pc + 4; pc = t2 + -0x1(i12))".to_string() ) ] ), ( RV32IOpToken::Lb, - opd_set_load_mem(ParserRISCVInstOp::Lb, "lb", "(i8)") + opd_set_load_mem(RV32IInstruction::Lb.into(), "lb", "(i8)") ), ( RV32IOpToken::Lbu, - opd_set_load_mem(ParserRISCVInstOp::Lbu, "lbu", "(u8)") + opd_set_load_mem(RV32IInstruction::Lbu.into(), "lbu", "(u8)") ), ( RV32IOpToken::Lh, - opd_set_load_mem(ParserRISCVInstOp::Lh, "lh", "(i16)") + opd_set_load_mem(RV32IInstruction::Lh.into(), "lh", "(i16)") ), ( RV32IOpToken::Lhu, - opd_set_load_mem(ParserRISCVInstOp::Lhu, "lhu", "(u16)") + opd_set_load_mem(RV32IInstruction::Lhu.into(), "lhu", "(u16)") ), ( RV32IOpToken::Lui, vec![ opd_set( expect_reg_any(Imm(U20)), - vec![basic_op_02(ParserRISCVInstOp::Lui)], + vec![basic_op_02(RV32IInstruction::Lui.into())], "lui t1, 0x1000 (t1 = 0x1000(u20))".to_string() ), opd_set( expect_reg_any(Lbl), - vec![basic_op_02(ParserRISCVInstOp::Lui)], + vec![basic_op_02(RV32IInstruction::Lui.into())], "lui t1, label (t1 = label)".to_string() ) ] ), ( RV32IOpToken::Lw, - opd_set_load_mem(ParserRISCVInstOp::Lw, "lw", "") + opd_set_load_mem(RV32IInstruction::Lw.into(), "lw", "") ), (RV32IOpToken::Mul, vec![]), (RV32IOpToken::Mulh, vec![]), @@ -314,7 +380,7 @@ lazy_static! { RV32IOpToken::Or, vec![opd_set( expect_reg_reg_reg(), - vec![basic_op_024(ParserRISCVInstOp::Or)], + vec![basic_op_024(RV32IInstruction::Or.into())], hint_reg_reg_reg("or", "|") ),] ), @@ -322,7 +388,7 @@ lazy_static! { RV32IOpToken::Ori, vec![opd_set( expect_reg_reg_any(Imm(U12)), - vec![basic_op_024(ParserRISCVInstOp::Ori)], + vec![basic_op_024(RV32IInstruction::Ori.into())], hint_reg_reg_any("ori", "0x1(u12)", "|") )] ), @@ -330,17 +396,17 @@ lazy_static! { (RV32IOpToken::Remu, vec![]), ( RV32IOpToken::Sb, - opd_set_store_mem(ParserRISCVInstOp::Sb, "sb", "(u8)") + opd_set_store_mem(RV32IInstruction::Sb.into(), "sb", "(u8)") ), ( RV32IOpToken::Sh, - opd_set_store_mem(ParserRISCVInstOp::Sh, "sh", "(u16)") + opd_set_store_mem(RV32IInstruction::Sh.into(), "sh", "(u16)") ), ( RV32IOpToken::Sll, vec![opd_set( expect_reg_reg_reg(), - vec![basic_op_024(ParserRISCVInstOp::Sll)], + vec![basic_op_024(RV32IInstruction::Sll.into())], hint_reg_reg_any("sll", "<<", "t3[0:4]") )] ), @@ -348,7 +414,7 @@ lazy_static! { RV32IOpToken::Slli, vec![opd_set( expect_reg_reg_any(Imm(U5)), - vec![basic_op_024(ParserRISCVInstOp::Slli)], + vec![basic_op_024(RV32IInstruction::Slli.into())], hint_reg_reg_any("slli", "<<", "0x1(u5)") )] ), @@ -356,7 +422,7 @@ lazy_static! { RV32IOpToken::Slt, vec![opd_set( expect_reg_reg_reg(), - vec![basic_op_024(ParserRISCVInstOp::Slt)], + vec![basic_op_024(RV32IInstruction::Slt.into())], hint_set_comparison("<", "t3", " (signed)") )] ), @@ -364,7 +430,7 @@ lazy_static! { RV32IOpToken::Slti, vec![opd_set( expect_reg_reg_any(Imm(I12)), - vec![basic_op_024(ParserRISCVInstOp::Slti)], + vec![basic_op_024(RV32IInstruction::Slti.into())], hint_set_comparison("<", "-0x1(i12)", " (signed)") )] ), @@ -372,7 +438,7 @@ lazy_static! { RV32IOpToken::Sltiu, vec![opd_set( expect_reg_reg_any(Imm(U12)), - vec![basic_op_024(ParserRISCVInstOp::Sltiu)], + vec![basic_op_024(RV32IInstruction::Sltiu.into())], hint_set_comparison("<", "0x1(u12)", " (unsigned)") )] ), @@ -380,7 +446,7 @@ lazy_static! { RV32IOpToken::Sltu, vec![opd_set( expect_reg_reg_reg(), - vec![basic_op_024(ParserRISCVInstOp::Sltu)], + vec![basic_op_024(RV32IInstruction::Sltu.into())], hint_set_comparison("<", "t3", " (unsigned)") )] ), @@ -388,7 +454,7 @@ lazy_static! { RV32IOpToken::Sra, vec![opd_set( expect_reg_reg_reg(), - vec![basic_op_024(ParserRISCVInstOp::Sra)], + vec![basic_op_024(RV32IInstruction::Sra.into())], hint_reg_reg_any("sra", ">>", "t3[0:4]") )] ), @@ -396,7 +462,7 @@ lazy_static! { RV32IOpToken::Srai, vec![opd_set( expect_reg_reg_any(Imm(U5)), - vec![basic_op_024(ParserRISCVInstOp::Srai)], + vec![basic_op_024(RV32IInstruction::Srai.into())], hint_reg_reg_any("srai", ">>", "0x1(u5)") )] ), @@ -404,7 +470,7 @@ lazy_static! { RV32IOpToken::Srl, vec![opd_set( expect_reg_reg_reg(), - vec![basic_op_024(ParserRISCVInstOp::Srl)], + vec![basic_op_024(RV32IInstruction::Srl.into())], hint_reg_reg_any("srl", ">>", "t3[0:4]") )] ), @@ -412,7 +478,7 @@ lazy_static! { RV32IOpToken::Srli, vec![opd_set( expect_reg_reg_any(Imm(U5)), - vec![basic_op_024(ParserRISCVInstOp::Srli)], + vec![basic_op_024(RV32IInstruction::Srli.into())], hint_reg_reg_any("srli", ">>", "0x1(u5)") )] ), @@ -420,13 +486,13 @@ lazy_static! { RV32IOpToken::Sub, vec![opd_set( expect_reg_reg_reg(), - vec![basic_op_024(ParserRISCVInstOp::Sub)], + vec![basic_op_024(RV32IInstruction::Sub.into())], hint_reg_reg_reg("sub", "-") )] ), ( RV32IOpToken::Sw, - opd_set_store_mem(ParserRISCVInstOp::Sw, "sw", "") + opd_set_store_mem(RV32IInstruction::Sw.into(), "sw", "") ), (RV32IOpToken::Uret, vec![]), (RV32IOpToken::Wfi, vec![]), @@ -434,7 +500,7 @@ lazy_static! { RV32IOpToken::Xor, vec![opd_set( expect_reg_reg_reg(), - vec![basic_op_024(ParserRISCVInstOp::Xor)], + vec![basic_op_024(RV32IInstruction::Xor.into())], hint_reg_reg_reg("xor", "^") )] ), @@ -442,7 +508,7 @@ lazy_static! { RV32IOpToken::Xori, vec![opd_set( expect_reg_reg_any(Imm(U12)), - vec![basic_op_024(ParserRISCVInstOp::Xori)], + vec![basic_op_024(RV32IInstruction::Xori.into())], hint_reg_reg_any("xori", "0x1(u12)", "^") )] ), @@ -450,7 +516,10 @@ lazy_static! { RV32IOpToken::B, vec![opd_set( expect_opd(vec![Lbl]), - vec![basic_op(ParserRISCVInstOp::Jal, vec![reg(Ra), idx(0)])], + vec![basic_op( + RV32IInstruction::Jal.into(), + vec![reg(Ra), idx(0)] + )], "b label (ra = pc + 4; pc = label)".to_string() )] ), @@ -459,7 +528,7 @@ lazy_static! { vec![opd_set( expect_reg_any(Lbl), vec![basic_op( - ParserRISCVInstOp::Beq, + RV32IInstruction::Beq.into(), vec![idx(0), reg(Zero), idx(2)] )], hint_branch_zero("beqz", "==", "") @@ -470,7 +539,7 @@ lazy_static! { vec![opd_set( expect_reg_any(Lbl), vec![basic_op( - ParserRISCVInstOp::Bge, + RV32IInstruction::Bge.into(), vec![idx(0), reg(Zero), idx(2)] )], hint_branch_zero("bgez", ">=", " (signed)") @@ -480,7 +549,7 @@ lazy_static! { RV32IOpToken::Bgt, vec![opd_set( expect_reg_reg_any(Lbl), - vec![basic_op_204(ParserRISCVInstOp::Blt)], + vec![basic_op_204(RV32IInstruction::Blt.into())], hint_branch("bgt", ">", " (signed)") )] ), @@ -488,7 +557,7 @@ lazy_static! { RV32IOpToken::Bgtu, vec![opd_set( expect_reg_reg_any(Lbl), - vec![basic_op_204(ParserRISCVInstOp::Bltu)], + vec![basic_op_204(RV32IInstruction::Bltu.into())], hint_branch("bgtu", ">", " (unsigned)") )] ), @@ -497,7 +566,7 @@ lazy_static! { vec![opd_set( expect_reg_any(Lbl), vec![basic_op( - ParserRISCVInstOp::Blt, + RV32IInstruction::Blt.into(), vec![reg(Zero), idx(0), idx(2)] )], hint_branch_zero("bgtz", ">", " (signed)") @@ -507,7 +576,7 @@ lazy_static! { RV32IOpToken::Ble, vec![opd_set( expect_reg_reg_any(Lbl), - vec![basic_op_204(ParserRISCVInstOp::Bge)], + vec![basic_op_204(RV32IInstruction::Bge.into())], hint_branch("ble", "<=", " (signed)") )] ), @@ -515,7 +584,7 @@ lazy_static! { RV32IOpToken::Bleu, vec![opd_set( expect_reg_reg_any(Lbl), - vec![basic_op_204(ParserRISCVInstOp::Bgeu)], + vec![basic_op_204(RV32IInstruction::Bgeu.into())], hint_branch("bleu", "<=", " (unsigned)") )] ), @@ -524,7 +593,7 @@ lazy_static! { vec![opd_set( expect_reg_any(Lbl), vec![basic_op( - ParserRISCVInstOp::Bge, + RV32IInstruction::Bge.into(), vec![reg(Zero), idx(0), idx(2)] )], hint_branch_zero("blez", "<=", " (signed)") @@ -535,7 +604,7 @@ lazy_static! { vec![opd_set( expect_reg_any(Lbl), vec![basic_op( - ParserRISCVInstOp::Blt, + RV32IInstruction::Blt.into(), vec![idx(0), reg(Zero), idx(2)] )], hint_branch_zero("bltz", "<", " (signed)") @@ -546,7 +615,7 @@ lazy_static! { vec![opd_set( expect_reg_any(Lbl), vec![basic_op( - ParserRISCVInstOp::Bne, + RV32IInstruction::Bne.into(), vec![idx(0), reg(Zero), idx(2)] )], hint_branch_zero("bnez", "!=", "") @@ -590,7 +659,7 @@ lazy_static! { vec![opd_set( expect_opd(vec![]), vec![basic_op( - ParserRISCVInstOp::Addi, + RV32IInstruction::Addi.into(), vec![reg(Zero), reg(Zero), imm_i(0)] )], "nop".to_string() From 261bc31ebc162055d5ffa9390f885bce3581bd61 Mon Sep 17 00:00:00 2001 From: GenshinImpactStarts <12211831@mail.sustech.edu.cn> Date: Tue, 16 Apr 2024 23:24:41 +0800 Subject: [PATCH 6/7] feat(parser test): impl trait display | move unit test --- src-tauri/src/interface/parser.rs | 65 +++++++++++++++++++ src-tauri/src/test/parser/mod.rs | 1 + .../src/test/{parser.rs => parser/sample.rs} | 11 +++- 3 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 src-tauri/src/test/parser/mod.rs rename src-tauri/src/test/{parser.rs => parser/sample.rs} (57%) diff --git a/src-tauri/src/interface/parser.rs b/src-tauri/src/interface/parser.rs index 2080b03d..352158d2 100644 --- a/src-tauri/src/interface/parser.rs +++ b/src-tauri/src/interface/parser.rs @@ -59,3 +59,68 @@ where pub op: IS::Operator, pub opd: Vec, } + +impl std::fmt::Display for ParserResult +where + IS: ParserInstSet, +{ + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str( + "ParserResult {\n\ + data:\n", + )?; + for (i, d) in self.data.iter().enumerate() { + write!(f, "{:3} {}\n", i, d.to_string())?; + } + f.write_str("text:\n")?; + for (i, t) in self.text.iter().enumerate() { + write!(f, "{:3} {}\n", i, t.to_string())?; + } + Ok(()) + } +} + +impl std::fmt::Display for ParserResultData { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ParserResultData::Data(data) => { + f.write_str("Data: 0x")?; + for d in data { + write!(f, "{:02x}", d)?; + } + Ok(()) + } + ParserResultData::Align(a) => write!(f, "Align {}", a), + } + } +} + +impl std::fmt::Display for ParserResultText +where + IS: ParserInstSet, +{ + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ParserResultText::Text(inst) => { + write!(f, "{:3}: {:?}", inst.line, inst.op)?; + for opd in &inst.opd { + write!(f, " {:?}", opd)?; + } + Ok(()) + } + ParserResultText::Align(a) => write!(f, "Align {}", a), + } + } +} + +impl std::fmt::Display for ParserError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "line:{} col:{} {}", + self.pos.0 + 1, + self.pos.1 + 1, + self.msg + ) + } +} diff --git a/src-tauri/src/test/parser/mod.rs b/src-tauri/src/test/parser/mod.rs new file mode 100644 index 00000000..ce8e751a --- /dev/null +++ b/src-tauri/src/test/parser/mod.rs @@ -0,0 +1 @@ +pub mod sample; diff --git a/src-tauri/src/test/parser.rs b/src-tauri/src/test/parser/sample.rs similarity index 57% rename from src-tauri/src/test/parser.rs rename to src-tauri/src/test/parser/sample.rs index 549be384..8a1bed36 100644 --- a/src-tauri/src/test/parser.rs +++ b/src-tauri/src/test/parser/sample.rs @@ -1,4 +1,4 @@ -use crate::modules::riscv::basic::interface::parser::{Parser, RISCVParser}; +use crate::modules::riscv::basic::interface::parser::*; pub fn test_parser() { let mut p = RISCVParser::new(); @@ -15,5 +15,12 @@ pub fn test_parser() { ", ); let res = p.parse(rope.to_string()); - println!("{:?}", res); + match res { + Ok(res) => println!("{}", res.to_string()), + Err(err) => { + for e in err { + println!("{}", e.to_string()); + } + } + } } From 015d84bd7b8951ab226f729fdd1b8b3d8ad91d75 Mon Sep 17 00:00:00 2001 From: GenshinImpactStarts <12211831@mail.sustech.edu.cn> Date: Wed, 17 Apr 2024 01:20:22 +0800 Subject: [PATCH 7/7] perf(parser constant): change RISCVImmediate to i32 --- src-tauri/src/interface/parser.rs | 6 ++--- .../src/modules/riscv/basic/parser/oplist.rs | 27 +++++++++---------- .../src/modules/riscv/basic/parser/parser.rs | 4 +-- .../src/modules/riscv/rv32i/constants.rs | 6 +---- 4 files changed, 17 insertions(+), 26 deletions(-) diff --git a/src-tauri/src/interface/parser.rs b/src-tauri/src/interface/parser.rs index 352158d2..d4637685 100644 --- a/src-tauri/src/interface/parser.rs +++ b/src-tauri/src/interface/parser.rs @@ -70,11 +70,11 @@ where data:\n", )?; for (i, d) in self.data.iter().enumerate() { - write!(f, "{:3} {}\n", i, d.to_string())?; + write!(f, "{:3} {}\n", i + 1, d.to_string())?; } f.write_str("text:\n")?; for (i, t) in self.text.iter().enumerate() { - write!(f, "{:3} {}\n", i, t.to_string())?; + write!(f, "{:3} {}\n", i + 1, t.to_string())?; } Ok(()) } @@ -102,7 +102,7 @@ where fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { ParserResultText::Text(inst) => { - write!(f, "{:3}: {:?}", inst.line, inst.op)?; + write!(f, "{:3}: {:?}", inst.line + 1, inst.op)?; for opd in &inst.opd { write!(f, " {:?}", opd)?; } diff --git a/src-tauri/src/modules/riscv/basic/parser/oplist.rs b/src-tauri/src/modules/riscv/basic/parser/oplist.rs index 8df43fa4..c87c747e 100644 --- a/src-tauri/src/modules/riscv/basic/parser/oplist.rs +++ b/src-tauri/src/modules/riscv/basic/parser/oplist.rs @@ -59,7 +59,7 @@ pub fn reg(reg: T) -> RISCVOpdSetAimOpd { } // --------------------imm------------------------- pub fn imm_i(imm: i128) -> RISCVOpdSetAimOpd { - RISCVOpdSetAimOpd::Val(ParserRISCVInstOpd::Imm(ParserRISCVImmediate::Int(imm))) + RISCVOpdSetAimOpd::Val(ParserRISCVInstOpd::Imm(imm as ParserRISCVImmediate)) } // --------------------idx------------------------- pub fn idx(idx: usize) -> RISCVOpdSetAimOpd { @@ -71,26 +71,18 @@ pub fn idx_handler( ) -> RISCVOpdSetAimOpd { RISCVOpdSetAimOpd::Idx(RISCVOpdSetAimOpdIdx { idx, handler }) } +// used with idx_handler_high, i = u20 << 12 + i12, get the i12 imm pub fn idx_handler_low(opd: ParserRISCVInstOpd) -> ParserRISCVInstOpd { - if let ParserRISCVInstOpd::Imm(ParserRISCVImmediate::Int(i)) = opd { - if i & 0x800 != 0 { - ParserRISCVInstOpd::Imm(ParserRISCVImmediate::Int(-(i & 0x7ff))) - } else { - ParserRISCVInstOpd::Imm(ParserRISCVImmediate::Int(i & 0x7ff)) - } + if let ParserRISCVInstOpd::Imm(i) = opd { + ParserRISCVInstOpd::Imm((i & 0x7ff) | -(i & 0x800)) } else { opd } } +// used with idx_handler_low, i = u20 << 12 + i12, get the u20 imm pub fn idx_handler_high(opd: ParserRISCVInstOpd) -> ParserRISCVInstOpd { - if let ParserRISCVInstOpd::Imm(ParserRISCVImmediate::Int(i)) = opd { - if i & 0x800 != 0 { - ParserRISCVInstOpd::Imm(ParserRISCVImmediate::Int( - ((i as u32 + 0x0000_1000) >> 12) as i128, - )) - } else { - ParserRISCVInstOpd::Imm(ParserRISCVImmediate::Int(((i as u32) >> 12) as i128)) - } + if let ParserRISCVInstOpd::Imm(i) = opd { + ParserRISCVInstOpd::Imm((i >> 12) + ((i & 0x800) >> 11)) } else { opd } @@ -118,18 +110,23 @@ pub fn expect_csr(last_opd: RISCVExpectToken) -> Vec { pub fn basic_op(op: ParserRISCVInstOp, opds: Vec) -> RISCVOpdSetAim { RISCVOpdSetAim { op, opds } } +// basic_op op idx(0) idx(2) pub fn basic_op_02(op: ParserRISCVInstOp) -> RISCVOpdSetAim { basic_op(op, vec![idx(0), idx(2)]) } +// basic_op op idx(2) idx(0) pub fn basic_op_20(op: ParserRISCVInstOp) -> RISCVOpdSetAim { basic_op(op, vec![idx(2), idx(0)]) } +// basic_op op idx(0) idx(2) idx(4) pub fn basic_op_024(op: ParserRISCVInstOp) -> RISCVOpdSetAim { basic_op(op, vec![idx(0), idx(2), idx(4)]) } +// basic_op op idx(0) idx(4) idx(2) pub fn basic_op_042(op: ParserRISCVInstOp) -> RISCVOpdSetAim { basic_op(op, vec![idx(0), idx(4), idx(2)]) } +// basic_op op idx(2) idx(0) idx(4) pub fn basic_op_204(op: ParserRISCVInstOp) -> RISCVOpdSetAim { basic_op(op, vec![idx(2), idx(0), idx(4)]) } diff --git a/src-tauri/src/modules/riscv/basic/parser/parser.rs b/src-tauri/src/modules/riscv/basic/parser/parser.rs index 338405ef..c6e23e5b 100644 --- a/src-tauri/src/modules/riscv/basic/parser/parser.rs +++ b/src-tauri/src/modules/riscv/basic/parser/parser.rs @@ -341,9 +341,7 @@ impl RISCVParser { stash_label_name.push(String::new()); } RISCVToken::ImmediateInt(val) => { - stash_opd.push(Some(ParserRISCVInstOpd::Imm(ParserRISCVImmediate::Int( - val, - )))); + stash_opd.push(Some(ParserRISCVInstOpd::Imm(val as ParserRISCVImmediate))); stash_label_name.push(String::new()); } RISCVToken::Symbol(Symbol::Label(lbl)) => { diff --git a/src-tauri/src/modules/riscv/rv32i/constants.rs b/src-tauri/src/modules/riscv/rv32i/constants.rs index 69e87500..3928ed39 100644 --- a/src-tauri/src/modules/riscv/rv32i/constants.rs +++ b/src-tauri/src/modules/riscv/rv32i/constants.rs @@ -91,11 +91,7 @@ pub enum RV32IInstruction { Xori, } -#[derive(Clone, Copy, Debug, PartialEq)] -pub enum RISCVImmediate { - Int(i128), - Float(f64), -} +pub type RISCVImmediate = i32; #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum RISCVCsr {}