Fix bug on the U-Type, fix bug in the terminal output

This commit is contained in:
Lumi Kalt 2024-01-23 00:59:04 +00:00
parent 1338f93898
commit 650390a676
6 changed files with 66 additions and 24 deletions

View file

@ -266,7 +266,7 @@ impl Env {
} }
} }
Token::Label(name) => { Token::Label(name) => {
self.add_label(&name, i * 4); self.add_label(&name, (i + 1) * 4);
} }
other => { other => {
dbg!(other); dbg!(other);

View file

@ -228,7 +228,7 @@ pub enum Arg {
Immediate, Immediate,
/// always ra /// always ra
Memory, Memory,
// Apperently a symbol is a label but in respect to the current pc // It's just an immediate but different name in the ref sheet
Symbol, Symbol,
} }
@ -373,6 +373,15 @@ pub fn instruction(op: &str) -> Option<(Kind, Vec<Arg>)> {
Kind::Pseudo(Pseudo("bnez")), Kind::Pseudo(Pseudo("bnez")),
vec![Arg::Register(1), Arg::Symbol], vec![Arg::Register(1), Arg::Symbol],
), ),
"j" => (Kind::Pseudo(Pseudo("j")), vec![Arg::Symbol]),
"jal" => (
Kind::J(J {
imm: to_bits(0),
rd: to_bits(0),
opcode: to_bits(0b1101111),
}),
vec![Arg::Register(0), Arg::Symbol],
),
op => unimplemented!("{}", op), op => unimplemented!("{}", op),
}) })
} }
@ -477,12 +486,7 @@ pub fn with((kind, args): (Kind, Vec<Arg>), imm: u32, regs: Vec<u32>) -> (Kind,
} }
Kind::U(u) => ( Kind::U(u) => (
Kind::U(U { Kind::U(U {
imm: { imm: to_bits(imm >> 12), // 31:12
let bits = to_bits::<32>(imm);
let mut imm = [false; 20];
imm.copy_from_slice(&bits[31..=12]);
imm
},
rd: to_bits(regs[0]), rd: to_bits(regs[0]),
opcode: u.opcode, opcode: u.opcode,
}), }),
@ -494,9 +498,9 @@ pub fn with((kind, args): (Kind, Vec<Arg>), imm: u32, regs: Vec<u32>) -> (Kind,
let bits = to_bits::<32>(imm); let bits = to_bits::<32>(imm);
let mut imm = [false; 20]; let mut imm = [false; 20];
imm[19] = bits[20]; imm[19] = bits[20];
imm[18..=9].copy_from_slice(&bits[10..=1]); imm[9..=18].copy_from_slice(&bits[1..=10]);
imm[8] = bits[11]; imm[8] = bits[11];
imm[7..=0].copy_from_slice(&bits[19..=12]); imm[0..=7].copy_from_slice(&bits[12..=19]);
imm imm
}, },
rd: to_bits(regs[0]), rd: to_bits(regs[0]),
@ -536,8 +540,8 @@ pub fn handle_pseudo(
} }
// otherwise, use lui and addi // otherwise, use lui and addi
_ => vec![ _ => vec![
with(get_instruction("lui"), imm >> 12, regs.clone()), with(get_instruction("lui"), imm & 0xfffff000, regs.clone()),
with(get_instruction("addi"), imm & 0xfff, regs), with(get_instruction("addi"), imm & 0x00000fff, regs),
], ],
} }
} }
@ -549,6 +553,10 @@ pub fn handle_pseudo(
// bne ra, x0, imm // bne ra, x0, imm
with(get_instruction("bne"), imm, vec![0, regs[0], 0]), with(get_instruction("bne"), imm, vec![0, regs[0], 0]),
], ],
"j" => vec![
// jal x0, imm
with(get_instruction("jal"), imm, vec![0]),
],
other => { other => {
dbg!(other); dbg!(other);
unimplemented!() unimplemented!()

View file

@ -26,23 +26,23 @@ fn main() -> anyhow::Result<()> {
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();
tokens.iter().enumerate().for_each(|(line, token)| { tokens.iter().for_each(|(token, loc)| {
let token = token.clone(); let token = token.clone();
env.handle_labels(tokens.clone()); env.handle_labels(tokens.clone());
match token.0 { match token.clone() {
Token::Op(..) => match env.assemble_op(token) { Token::Op(..) => match env.assemble_op((token, loc.clone())) {
Ok(op) => { Ok(op) => {
let mut formatted = format!( let mut formatted = format!(
"{:<1$} {2:032b}", "{:<1$} {2:032b}",
lines[line].to_string() + ":", lines[loc.line - 1].to_string() + ":",
size + 3, size + 3,
op[0] op[0]
); );
if op.len() > 1 { if op.len() > 1 {
for op in op[1..].iter() { for op in op[1..].iter() {
formatted += &format!("{:<1$} {2:032b}", "", size + 3, op); formatted += &format!("\n{:<1$} {2:032b}", "", size + 3, op);
} }
} }
println!("{}", formatted); println!("{}", formatted);
@ -65,7 +65,12 @@ fn main() -> anyhow::Result<()> {
} }
}, },
Token::Label(name) => { Token::Label(name) => {
println!("{name}:"); println!(
"{:<1$} <{2:04x}>",
name.clone() + ":",
size + 3,
env.get_label(&name).unwrap()
);
} }
_ => unreachable!(), _ => unreachable!(),
} }

View file

@ -98,6 +98,7 @@ fn parse_line(env: &Env, input: &str, loc: &mut Loc) -> Result<Vec<(Token, Loc)>
let mut num = c.to_string(); let mut num = c.to_string();
while let Some('0'..='9') = chars.peek() { while let Some('0'..='9') = chars.peek() {
num.push(chars.next().unwrap()); num.push(chars.next().unwrap());
loc.end += 1;
} }
Immediate(num.parse::<i32>().unwrap() as u32) Immediate(num.parse::<i32>().unwrap() as u32)
} }

View file

@ -32,6 +32,34 @@ fn nop() {
); );
} }
#[test]
fn lui() {
let env = Env::new();
#[rustfmt::skip]
{
// U-Type
// | imm20 | rd | opcode
// 00000000000000000011 01010 0110111
// 00000011010100101001 01010 0110111
};
// lui a0 13609
assert_eq!(
u32::from_str_radix(
&with(
get_instruction("lui"),
13609 << 12,
vec![env.alias_to_register("a0").unwrap()]
)
.0
.to_string(),
2
)
.unwrap(),
0b00000011010100101001010100110111u32
);
}
#[test] #[test]
fn sb() { fn sb() {
let env = Env::new(); let env = Env::new();

12
test.s
View file

@ -1,10 +1,10 @@
li a0 5 li a0 55743235
li a1 1 li a1 1
# 5!
factorial: factorial:
# beqz a0 end beqz a0 end
mul a1 a1 a0 -1 mul a1 a1 a0
a0 addi a0 a0 -1 addi a0 a0 -1
j factorial
bnez factorial
end: end: