1use std::collections::HashMap;
2
3use lib_rv32_common::{constants::*, parse_int};
4
5use crate::error::AssemblerError;
6
7#[macro_export]
10macro_rules! tokenize {
11 ($s:expr) => {
12 $s.replace(",", " ")
13 .replace("\n", " ")
14 .replace("(", " ")
15 .replace(")", " ")
16 .to_ascii_lowercase()
17 .split_whitespace()
18 .map(|s| s.to_owned())
19 .collect();
20 };
21}
22
23pub fn match_opcode(op: &str) -> Result<u8, AssemblerError> {
25 let opcode = match op {
26 "add" | "sub" | "sll" | "slt" | "sltu" | "xor" | "sra" | "or" | "and" => OPCODE_ARITHMETIC,
27 "addi" | "slli" | "slti" | "xori" | "srai" | "ori" | "andi" => OPCODE_ARITHMETIC_IMM,
28 "lui" => OPCODE_LUI,
29 "auipc" => OPCODE_AUIPC,
30 "jal" => OPCODE_JAL,
31 "jalr" => OPCODE_JALR,
32 "beq" | "bne" | "blt" | "bge" | "bgeu" => OPCODE_BRANCH,
33 "lb" | "lbu" | "lh" | "lhu" | "lw" => OPCODE_LOAD,
34 "sb" | "sh" | "sw" => OPCODE_STORE,
35 _ => return Err(AssemblerError::InvalidOperationError),
36 };
37 Ok(opcode)
38}
39
40pub fn match_register(reg: &str) -> Result<u8, AssemblerError> {
42 if reg.starts_with('x') {
43 match reg.strip_prefix('x').unwrap().parse() {
44 Ok(n) => Ok(n),
45 Err(_) => Err(AssemblerError::NoSuchRegisterError),
46 }
47 } else {
48 match REG_NAMES.iter().position(|e| *e == reg) {
49 Some(n) => Ok(n as u8),
50 None => Err(AssemblerError::NoSuchRegisterError),
51 }
52 }
53}
54
55pub fn parse_imm(s: &str, labels: &HashMap<String, u32>, pc: u32) -> Result<u32, AssemblerError> {
57 let num = parse_int!(i64, s);
58 match num {
59 Err(_) => {
60 let label = labels.get(s);
61 if let Some(v) = label {
62 Ok((*v).wrapping_sub(pc))
63 } else {
64 Err(AssemblerError::InvalidImmediateError)
65 }
66 }
67 Ok(d) => Ok(d as u32),
68 }
69}
70
71#[macro_export]
73macro_rules! match_func3 {
74 ($t:expr) => {
75 match $t {
76 "beq" => FUNC3_BEQ,
77 "bne" => FUNC3_BNE,
78 "blt" => FUNC3_BLT,
79 "bge" => FUNC3_BGE,
80 "bltu" => FUNC3_BLTU,
81 "bgeu" => FUNC3_BGEU,
82 "lb" => FUNC3_LB,
83 "lbu" => FUNC3_LBU,
84 "lh" => FUNC3_LH,
85 "lhu" => FUNC3_LHU,
86 "lw" => FUNC3_LW,
87 "sb" => FUNC3_SB,
88 "sh" => FUNC3_SH,
89 "sw" => FUNC3_SW,
90 "add" | "addi" | "sub" => FUNC3_ADD_SUB,
91 "sll" | "slli" => FUNC3_SLL,
92 "slt" | "slti" => FUNC3_SLT,
93 "sltu" => FUNC3_SLTU,
94 "xor" | "xori" => FUNC3_XOR,
95 "sra" | "srai" | "srl" | "srli" => FUNC3_SR,
96 "or" | "ori" => FUNC3_OR,
97 "and" | "andi" => FUNC3_AND,
98 _ => unreachable!(),
99 }
100 };
101}
102
103#[macro_export]
105macro_rules! match_func7 {
106 ($t:expr) => {
107 match $t {
108 "add" | "addi" => FUNC7_ADD,
109 "sub" => FUNC7_SUB,
110 "sra" | "srai" => FUNC7_SRA,
111 "srl" | "srli" => FUNC7_SRL,
112 _ => unreachable!(),
113 }
114 };
115}