Get rid of useless helper functions, show mem addr of ops in the output
This commit is contained in:
parent
650390a676
commit
78165b9b4e
6 changed files with 35 additions and 41 deletions
25
src/env.rs
25
src/env.rs
|
@ -21,6 +21,7 @@ pub struct Env {
|
||||||
registers: [u32; 32],
|
registers: [u32; 32],
|
||||||
pub stack: Vec<u32>, // TODO: Find the size of the stack
|
pub stack: Vec<u32>, // TODO: Find the size of the stack
|
||||||
pub instructions: Vec<u32>,
|
pub instructions: Vec<u32>,
|
||||||
|
pc: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Env {
|
impl Env {
|
||||||
|
@ -71,6 +72,7 @@ impl Env {
|
||||||
registers: [0; 32],
|
registers: [0; 32],
|
||||||
stack: Vec::from([0; 1024]), // 1024 * 64 = 64 KiB stack
|
stack: Vec::from([0; 1024]), // 1024 * 64 = 64 KiB stack
|
||||||
instructions: Vec::new(),
|
instructions: Vec::new(),
|
||||||
|
pc: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,10 +84,7 @@ impl Env {
|
||||||
self.registers[reg as usize]
|
self.registers[reg as usize]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alias_to_register(&self, reg: &str) -> Option<u32> {
|
pub fn str_to_register(&self, reg: &str) -> Option<u32> {
|
||||||
self.register_alias.get(reg).copied()
|
|
||||||
}
|
|
||||||
pub fn xn_to_register(&self, reg: &str) -> Option<u32> {
|
|
||||||
if reg == "x0" {
|
if reg == "x0" {
|
||||||
Some(0)
|
Some(0)
|
||||||
} else if reg.starts_with("x") && !reg[1..].starts_with("0") {
|
} else if reg.starts_with("x") && !reg[1..].starts_with("0") {
|
||||||
|
@ -94,21 +93,9 @@ impl Env {
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
self.register_alias.get(reg).copied()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn reg_to_register(&self, reg: &str) -> Option<u32> {
|
|
||||||
if reg.starts_with("x") {
|
|
||||||
self.xn_to_register(reg)
|
|
||||||
} else {
|
|
||||||
self.alias_to_register(reg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn is_valid_register(&self, reg: &str) -> bool {
|
|
||||||
self.alias_to_register(reg)
|
|
||||||
.or_else(|| self.xn_to_register(reg))
|
|
||||||
.is_some()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_label(&mut self, label: &str, value: u32) {
|
pub fn add_label(&mut self, label: &str, value: u32) {
|
||||||
self.labels.insert(label.to_string(), value);
|
self.labels.insert(label.to_string(), value);
|
||||||
|
@ -164,7 +151,7 @@ impl Env {
|
||||||
}
|
}
|
||||||
Arg::Register(id) => {
|
Arg::Register(id) => {
|
||||||
if let Token::Register(r) = &args[k].0 {
|
if let Token::Register(r) = &args[k].0 {
|
||||||
regs[id] = self.reg_to_register(&r).unwrap();
|
regs[id] = self.str_to_register(&r).unwrap();
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err((
|
Err((
|
||||||
|
@ -181,7 +168,7 @@ impl Env {
|
||||||
if let Token::Memory(i, r) = &args[k].0 {
|
if let Token::Memory(i, r) = &args[k].0 {
|
||||||
if r.is_some() {
|
if r.is_some() {
|
||||||
regs[k] = self
|
regs[k] = self
|
||||||
.reg_to_register(&if let Token::Register(r) =
|
.str_to_register(&if let Token::Register(r) =
|
||||||
*(r.clone().unwrap())
|
*(r.clone().unwrap())
|
||||||
{
|
{
|
||||||
r
|
r
|
||||||
|
|
|
@ -13,7 +13,7 @@ pub enum SyntaxErr {
|
||||||
UnmatchedParen(bool),
|
UnmatchedParen(bool),
|
||||||
UnexpectedChar,
|
UnexpectedChar,
|
||||||
OutsideOp(String),
|
OutsideOp(String),
|
||||||
MemoryInvalidRegister,
|
InvalidRegister,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for SyntaxErr {
|
impl Display for SyntaxErr {
|
||||||
|
@ -22,7 +22,7 @@ impl Display for SyntaxErr {
|
||||||
SyntaxErr::UnmatchedParen(_) => write!(f, "unmatched parenthesis"),
|
SyntaxErr::UnmatchedParen(_) => write!(f, "unmatched parenthesis"),
|
||||||
SyntaxErr::UnexpectedChar => write!(f, "unexpected character"),
|
SyntaxErr::UnexpectedChar => write!(f, "unexpected character"),
|
||||||
SyntaxErr::OutsideOp(kind) => write!(f, "`{kind}` before opcode"),
|
SyntaxErr::OutsideOp(kind) => write!(f, "`{kind}` before opcode"),
|
||||||
SyntaxErr::MemoryInvalidRegister => write!(f, "invalid register"),
|
SyntaxErr::InvalidRegister => write!(f, "invalid register"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ impl SyntaxErr {
|
||||||
SyntaxErr::UnmatchedParen(true) => "add `(` before the register name".to_string(),
|
SyntaxErr::UnmatchedParen(true) => "add `(` before the register name".to_string(),
|
||||||
SyntaxErr::UnexpectedChar => "ensure the input is well-formed".to_string(),
|
SyntaxErr::UnexpectedChar => "ensure the input is well-formed".to_string(),
|
||||||
SyntaxErr::OutsideOp(_) => format!("only add arguments after the opcode"),
|
SyntaxErr::OutsideOp(_) => format!("only add arguments after the opcode"),
|
||||||
SyntaxErr::MemoryInvalidRegister => {
|
SyntaxErr::InvalidRegister => {
|
||||||
"registers are either xN (N < 32 with no leading 0) or the standard aliases"
|
"registers are either xN (N < 32 with no leading 0) or the standard aliases"
|
||||||
.to_string()
|
.to_string()
|
||||||
}
|
}
|
||||||
|
|
15
src/main.rs
15
src/main.rs
|
@ -25,6 +25,7 @@ fn main() -> anyhow::Result<()> {
|
||||||
Ok(tokens) => {
|
Ok(tokens) => {
|
||||||
let lines: Vec<&str> = input.lines().collect();
|
let lines: Vec<&str> = input.lines().collect();
|
||||||
let size = lines.iter().map(|l| l.len()).max().unwrap();
|
let size = lines.iter().map(|l| l.len()).max().unwrap();
|
||||||
|
let mut i = 0;
|
||||||
|
|
||||||
tokens.iter().for_each(|(token, loc)| {
|
tokens.iter().for_each(|(token, loc)| {
|
||||||
let token = token.clone();
|
let token = token.clone();
|
||||||
|
@ -33,16 +34,20 @@ fn main() -> anyhow::Result<()> {
|
||||||
match token.clone() {
|
match token.clone() {
|
||||||
Token::Op(..) => match env.assemble_op((token, loc.clone())) {
|
Token::Op(..) => match env.assemble_op((token, loc.clone())) {
|
||||||
Ok(op) => {
|
Ok(op) => {
|
||||||
|
let addr = (loc.line - 1) * 4;
|
||||||
let mut formatted = format!(
|
let mut formatted = format!(
|
||||||
"{:<1$} {2:032b}",
|
"{:<1$} {3:02x}: {2:032b}",
|
||||||
lines[loc.line - 1].to_string() + ":",
|
lines[loc.line - 1],
|
||||||
size + 3,
|
size + 3,
|
||||||
op[0]
|
op[0],
|
||||||
|
i
|
||||||
);
|
);
|
||||||
|
i += 4;
|
||||||
|
|
||||||
if op.len() > 1 {
|
if op.len() > 1 {
|
||||||
for op in op[1..].iter() {
|
for op in op[1..].iter() {
|
||||||
formatted += &format!("\n{:<1$} {2:032b}", "", size + 3, op);
|
formatted += &format!("\n{:<1$} {3:02x}: {2:032b}", "", size + 3, op, i);
|
||||||
|
i += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
println!("{}", formatted);
|
println!("{}", formatted);
|
||||||
|
@ -66,7 +71,7 @@ fn main() -> anyhow::Result<()> {
|
||||||
},
|
},
|
||||||
Token::Label(name) => {
|
Token::Label(name) => {
|
||||||
println!(
|
println!(
|
||||||
"{:<1$} <{2:04x}>",
|
"{:<1$} <{2:02x}>",
|
||||||
name.clone() + ":",
|
name.clone() + ":",
|
||||||
size + 3,
|
size + 3,
|
||||||
env.get_label(&name).unwrap()
|
env.get_label(&name).unwrap()
|
||||||
|
|
|
@ -130,9 +130,9 @@ fn parse_line(env: &Env, input: &str, loc: &mut Loc) -> Result<Vec<(Token, Loc)>
|
||||||
let end = loc.end + 1;
|
let end = loc.end + 1;
|
||||||
|
|
||||||
let reg = reg.trim();
|
let reg = reg.trim();
|
||||||
if !env.is_valid_register(reg) {
|
if env.str_to_register(reg).is_none() {
|
||||||
let err = Err((
|
let err = Err((
|
||||||
SyntaxErr::MemoryInvalidRegister,
|
SyntaxErr::InvalidRegister,
|
||||||
Loc {
|
Loc {
|
||||||
line: loc.line,
|
line: loc.line,
|
||||||
start,
|
start,
|
||||||
|
@ -233,7 +233,7 @@ fn parse_line(env: &Env, input: &str, loc: &mut Loc) -> Result<Vec<(Token, Loc)>
|
||||||
)]
|
)]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if env.is_valid_register(&name) {
|
if env.str_to_register(&name).is_some() {
|
||||||
return vec![(
|
return vec![(
|
||||||
Token::Error((
|
Token::Error((
|
||||||
SyntaxErr::OutsideOp("register".to_string()),
|
SyntaxErr::OutsideOp("register".to_string()),
|
||||||
|
@ -247,7 +247,7 @@ fn parse_line(env: &Env, input: &str, loc: &mut Loc) -> Result<Vec<(Token, Loc)>
|
||||||
for (token, loc) in group[1..].iter() {
|
for (token, loc) in group[1..].iter() {
|
||||||
match token.clone() {
|
match token.clone() {
|
||||||
Token::Register(name) => {
|
Token::Register(name) => {
|
||||||
if env.is_valid_register(&name) {
|
if env.str_to_register(&name).is_some() {
|
||||||
args.push((token.clone(), loc.clone()));
|
args.push((token.clone(), loc.clone()));
|
||||||
} else {
|
} else {
|
||||||
args.push((Token::Symbol(name.to_owned()), *loc))
|
args.push((Token::Symbol(name.to_owned()), *loc))
|
||||||
|
|
20
src/tests.rs
20
src/tests.rs
|
@ -49,7 +49,7 @@ fn lui() {
|
||||||
&with(
|
&with(
|
||||||
get_instruction("lui"),
|
get_instruction("lui"),
|
||||||
13609 << 12,
|
13609 << 12,
|
||||||
vec![env.alias_to_register("a0").unwrap()]
|
vec![env.str_to_register("a0").unwrap()]
|
||||||
)
|
)
|
||||||
.0
|
.0
|
||||||
.to_string(),
|
.to_string(),
|
||||||
|
@ -78,8 +78,8 @@ fn sb() {
|
||||||
-4i32 as u32, // imm
|
-4i32 as u32, // imm
|
||||||
vec![
|
vec![
|
||||||
0, // rd
|
0, // rd
|
||||||
env.alias_to_register("sp").unwrap(), // ra
|
env.str_to_register("sp").unwrap(), // ra
|
||||||
env.alias_to_register("t5").unwrap() // rb
|
env.str_to_register("t5").unwrap() // rb
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
.0
|
.0
|
||||||
|
@ -108,9 +108,9 @@ fn add() {
|
||||||
get_instruction("add"),
|
get_instruction("add"),
|
||||||
0, // imm
|
0, // imm
|
||||||
vec![
|
vec![
|
||||||
env.alias_to_register("a0").unwrap(), // rd
|
env.str_to_register("a0").unwrap(), // rd
|
||||||
env.alias_to_register("a0").unwrap(), // ra
|
env.str_to_register("a0").unwrap(), // ra
|
||||||
env.alias_to_register("a1").unwrap() // rb
|
env.str_to_register("a1").unwrap() // rb
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
.0
|
.0
|
||||||
|
@ -140,8 +140,8 @@ fn addi() {
|
||||||
get_instruction("addi"),
|
get_instruction("addi"),
|
||||||
1,
|
1,
|
||||||
vec![
|
vec![
|
||||||
env.alias_to_register("a0").unwrap(),
|
env.str_to_register("a0").unwrap(),
|
||||||
env.alias_to_register("a0").unwrap()
|
env.str_to_register("a0").unwrap()
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
.0
|
.0
|
||||||
|
@ -173,8 +173,8 @@ fn beq() {
|
||||||
4,
|
4,
|
||||||
vec![
|
vec![
|
||||||
0, // no rd
|
0, // no rd
|
||||||
env.alias_to_register("a0").unwrap(),
|
env.str_to_register("a0").unwrap(),
|
||||||
env.alias_to_register("a1").unwrap()
|
env.str_to_register("a1").unwrap()
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
.0
|
.0
|
||||||
|
|
2
test.s
2
test.s
|
@ -7,4 +7,6 @@ factorial:
|
||||||
mul a1 a1 a0
|
mul a1 a1 a0
|
||||||
addi a0 a0 -1
|
addi a0 a0 -1
|
||||||
j factorial
|
j factorial
|
||||||
|
|
||||||
end:
|
end:
|
||||||
|
nop
|
||||||
|
|
Loading…
Reference in a new issue