Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add bin/oct/hex literals #23

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ name-ext/node_modules/*
*.o
!name-as/.artifacts/*
name-fmt/node_modules/
*.li
name-as/*.li
Binary file modified name-as/.artifacts/mars_output.o
Binary file not shown.
7 changes: 6 additions & 1 deletion name-as/.artifacts/mips_test.asm
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
main:
add $t1,$t2,$t3
add $t0,$t2,$t3
sub $t4, $t5, $t6
sll $s0, $s0, 5
srl $s5, $s7, 10
xor $t7, $t8, $t9
lui $t0, 50
ori $t0, $t1, 50
ori $t0, $t0, 0x50
ori $t0, $t0, 050
ori $t0, $t0, 0b1010
lb $t0, 0x50($t1)
lb $t0, 50($t1)
lb $t0, ($t1)
beq $s0, $s0, test
test:
j test
Expand Down
Binary file modified name-as/.artifacts/mips_test.o
Binary file not shown.
2 changes: 1 addition & 1 deletion name-as/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ run-gnu: build

test: run
$(CARGO) run -- $(GNUCFG) $(INPUT) gnu-$(OUTPUT)
md5sum $(OUTPUT) gnu-$(OUTPUT)
md5sum $(OUTPUT) .artifacts/mars_output.o gnu-$(OUTPUT)

clean:
$(CARGO) clean
Expand Down
63 changes: 48 additions & 15 deletions name-as/src/nma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,24 @@ fn mask_u32(n: u32, x: u8) -> Result<u32, &'static str> {
}
}

fn base_parse(input: &str) -> Result<u32, &'static str> {
if input.starts_with("0x") {
// Hexadecimal
u32::from_str_radix(&input[2..], 16).map_err(|_| "Failed to parse as hexadecimal")
} else if input.starts_with("0b") {
// Binary
u32::from_str_radix(&input[2..], 2).map_err(|_| "Failed to parse as binary")
} else if input.starts_with('0') && input.len() > 1 {
// Octal
u32::from_str_radix(&input[1..], 8).map_err(|_| "Failed to parse as octal")
} else {
// Decimal
input
.parse::<u32>()
.map_err(|_| "Failed to parse as decimal")
}
}

const TEXT_ADDRESS_BASE: u32 = 0x400000;
const MIPS_INSTR_BYTE_WIDTH: u32 = 4;

Expand Down Expand Up @@ -281,8 +299,8 @@ fn assemble_r(r_struct: R, r_args: Vec<&str>) -> Result<u32, &'static str> {
rd = assemble_reg(r_args[0])?;
rs = 0;
rt = assemble_reg(r_args[1])?;
shamt = match r_args[2].parse::<u8>() {
Ok(v) => v,
shamt = match base_parse(r_args[2]) {
Ok(v) => v as u8,
Err(_) => return Err("Failed to parse shamt"),
}
}
Expand Down Expand Up @@ -345,19 +363,28 @@ fn assemble_i(
enforce_length(&i_args, 2)?;
rs = 0;
rt = assemble_reg(i_args[0])?;
imm = match i_args[1].parse::<u16>() {
Ok(v) => v,
imm = match base_parse(i_args[1]) {
Ok(v) => v as u16,
Err(_) => return Err("Failed to parse imm"),
}
}
IForm::RtImmRs => {
enforce_length(&i_args, 3)?;
rt = assemble_reg(i_args[0])?;
imm = match i_args[1].parse::<u16>() {
Ok(v) => v,
// Immediate can default to 0 if not included in instructions
// such as 'ld $t0, ($t1)'
let i_args_catch = if i_args.len() == 2 {
let mut c = i_args.clone();
c.insert(1, "0");
c
} else {
i_args
};
enforce_length(&i_args_catch, 3)?;
rt = assemble_reg(i_args_catch[0])?;
imm = match base_parse(i_args_catch[1]) {
Ok(v) => v as u16,
Err(_) => return Err("Failed to parse imm"),
};
rs = assemble_reg(i_args[2])?;
rs = assemble_reg(i_args_catch[2])?;
}
IForm::RsRtLabel => {
enforce_length(&i_args, 3)?;
Expand All @@ -373,8 +400,8 @@ fn assemble_i(
enforce_length(&i_args, 3)?;
rt = assemble_reg(i_args[0])?;
rs = assemble_reg(i_args[1])?;
imm = match i_args[2].parse::<u16>() {
Ok(v) => v,
imm = match base_parse(i_args[2]) {
Ok(v) => v as u16,
Err(_) => return Err("Failed to parse imm"),
};
}
Expand Down Expand Up @@ -533,8 +560,8 @@ pub fn assemble(program_arguments: &Args) -> Result<(), String> {
if let Ok(instr_info) = r_operation(mnemonic) {
println!("-----------------------------------");
println!(
"[R] {} - shamt [{:x}] - funct [{:x}]",
mnemonic, instr_info.shamt, instr_info.funct
"[R] {} - shamt [{:x}] - funct [{:x}] - args [{:?}]",
mnemonic, instr_info.shamt, instr_info.funct, args
);
match assemble_r(instr_info, args) {
Ok(assembled_r) => {
Expand All @@ -546,7 +573,10 @@ pub fn assemble(program_arguments: &Args) -> Result<(), String> {
}
} else if let Ok(instr_info) = i_operation(mnemonic) {
println!("-----------------------------------");
println!("[I] {} - opcode [{:x}]", mnemonic, instr_info.opcode);
println!(
"[I] {} - opcode [{:x}] - args [{:?}]",
mnemonic, instr_info.opcode, args
);

match assemble_i(instr_info, args, &labels, current_addr) {
Ok(assembled_i) => {
Expand All @@ -558,7 +588,10 @@ pub fn assemble(program_arguments: &Args) -> Result<(), String> {
}
} else if let Ok(instr_info) = j_operation(mnemonic) {
println!("-----------------------------------");
println!("[J] {} - opcode [{:x}]", mnemonic, instr_info.opcode);
println!(
"[J] {} - opcode [{:x}] - args [{:?}]",
mnemonic, instr_info.opcode, args
);

match assemble_j(instr_info, args, &labels) {
Ok(assembled_j) => {
Expand Down
8 changes: 6 additions & 2 deletions name-as/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,22 @@ use pest_derive::Parser;
#[grammar_inline = r#"
alpha = _{ 'a'..'z' | 'A'..'Z' }
digit = _{ '0'..'9' }
hex = _{ "0x" ~ (digit | 'a'..'f' | 'A'..'F')+ }
binary = _{ "0b" ~ ('0'..'1')+ }
decimal = _{ digit+ }
number = { hex | binary | decimal }
WHITESPACE = _{ " " | NEWLINE }

ident = @{ alpha ~ (alpha | digit)* }

label = { ident ~ ":" }

register = @{ "$" ~ ident }
instruction_arg = @{ ident | register | digit+ }
instruction_arg = @{ ident | register | number }
standard_args = _{
instruction_arg ~ ("," ~ WHITESPACE* ~ instruction_arg){, 2}
}
mem_access_args = _{ instruction_arg ~ "," ~ instruction_arg ~ "(" ~ instruction_arg ~ ")" }
mem_access_args = _{ instruction_arg ~ "," ~ number? ~ "(" ~ instruction_arg ~ ")" }
instruction_args = _{ mem_access_args | standard_args }
instruction = { ident ~ instruction_args }

Expand Down