From 3621c85662e970f5fe1439c3884939cb3ce2c108 Mon Sep 17 00:00:00 2001 From: Charles Averill Date: Fri, 3 Nov 2023 12:26:38 -0500 Subject: [PATCH 1/2] Add bin/oct/hex literals --- .gitignore | 2 +- name-as/.artifacts/mars_output.o | Bin 44 -> 56 bytes name-as/.artifacts/mips_test.asm | 7 +++-- name-as/.artifacts/mips_test.o | Bin 44 -> 56 bytes name-as/Makefile | 2 +- name-as/src/nma.rs | 48 +++++++++++++++++++++++-------- name-as/src/parser.rs | 4 ++- 7 files changed, 46 insertions(+), 17 deletions(-) diff --git a/.gitignore b/.gitignore index 23818eaa..7b4aa614 100644 --- a/.gitignore +++ b/.gitignore @@ -26,4 +26,4 @@ name-ext/node_modules/* *.o !name-as/.artifacts/* name-fmt/node_modules/ -*.li +name-as/*.li diff --git a/name-as/.artifacts/mars_output.o b/name-as/.artifacts/mars_output.o index a76ca6b471edfe554350afeff8899daaf04e5418..5d5bb01d07f20fd6a837bdb0cf9e116e90e115f5 100644 GIT binary patch literal 56 zcmY#z@Mcs>SjXtlD8SIPN}NHhLXz2tfy2g#LBlkFfx}b-h`E3`fI*{?fk8lshe3b? GhSjXtlD8SIPN}NHhLXz2tfy2g#LBkY?8yOe`gg6-lIDnW30LI(~`~Uy| diff --git a/name-as/.artifacts/mips_test.asm b/name-as/.artifacts/mips_test.asm index d2fedd37..fd9926cb 100644 --- a/name-as/.artifacts/mips_test.asm +++ b/name-as/.artifacts/mips_test.asm @@ -1,12 +1,15 @@ 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 - lb $t0, 50($t1) + ori $t0, $t0, 0x50 + ori $t0, $t0, 050 + ori $t0, $t0, 0b1010 + lb $t0, 0x50($t1) beq $s0, $s0, test test: j test diff --git a/name-as/.artifacts/mips_test.o b/name-as/.artifacts/mips_test.o index 7b6ef953cc2c4f63ed6ff5d7e777e79c778b0ab6..5d5bb01d07f20fd6a837bdb0cf9e116e90e115f5 100644 GIT binary patch literal 56 zcmY#z@Mcs>SjXtlD8SIPN}NHhLXz2tfy2g#LBlkFfx}b-h`E3`fI*{?fk8lshe3b? Gh* Result { } } +fn base_parse(input: &str) -> Result { + 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::() + .map_err(|_| "Failed to parse as decimal") + } +} + const TEXT_ADDRESS_BASE: u32 = 0x400000; const MIPS_INSTR_BYTE_WIDTH: u32 = 4; @@ -281,8 +299,8 @@ fn assemble_r(r_struct: R, r_args: Vec<&str>) -> Result { rd = assemble_reg(r_args[0])?; rs = 0; rt = assemble_reg(r_args[1])?; - shamt = match r_args[2].parse::() { - Ok(v) => v, + shamt = match base_parse(r_args[2]) { + Ok(v) => v as u8, Err(_) => return Err("Failed to parse shamt"), } } @@ -345,16 +363,16 @@ fn assemble_i( enforce_length(&i_args, 2)?; rs = 0; rt = assemble_reg(i_args[0])?; - imm = match i_args[1].parse::() { - 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::() { - Ok(v) => v, + imm = match base_parse(i_args[1]) { + Ok(v) => v as u16, Err(_) => return Err("Failed to parse imm"), }; rs = assemble_reg(i_args[2])?; @@ -373,8 +391,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::() { - Ok(v) => v, + imm = match base_parse(i_args[2]) { + Ok(v) => v as u16, Err(_) => return Err("Failed to parse imm"), }; } @@ -533,8 +551,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) => { @@ -546,7 +564,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) => { @@ -558,7 +579,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) => { diff --git a/name-as/src/parser.rs b/name-as/src/parser.rs index 3404f34f..ec791bdb 100644 --- a/name-as/src/parser.rs +++ b/name-as/src/parser.rs @@ -5,6 +5,8 @@ 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')+ } WHITESPACE = _{ " " | NEWLINE } ident = @{ alpha ~ (alpha | digit)* } @@ -12,7 +14,7 @@ ident = @{ alpha ~ (alpha | digit)* } label = { ident ~ ":" } register = @{ "$" ~ ident } -instruction_arg = @{ ident | register | digit+ } +instruction_arg = @{ ident | register | hex+ | binary+ | digit+ } standard_args = _{ instruction_arg ~ ("," ~ WHITESPACE* ~ instruction_arg){, 2} } From 2a44b67ddb5a36f9167caa9d31244a1ff9c36ed2 Mon Sep 17 00:00:00 2001 From: Charles Averill Date: Fri, 3 Nov 2023 12:52:11 -0500 Subject: [PATCH 2/2] Fix memory offsets --- name-as/.artifacts/mars_output.o | Bin 56 -> 64 bytes name-as/.artifacts/mips_test.asm | 2 ++ name-as/src/nma.rs | 17 +++++++++++++---- name-as/src/parser.rs | 6 ++++-- 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/name-as/.artifacts/mars_output.o b/name-as/.artifacts/mars_output.o index 5d5bb01d07f20fd6a837bdb0cf9e116e90e115f5..26487088830a83e3b64ca06207ca24020b7e6876 100644 GIT binary patch delta 25 bcmcC;n4lwK#Guj00LB7Bd<+5{K+FRGIFSQC delta 17 WcmZ>;n4rVMz#t&R!yv!`#5@2M%K@(d diff --git a/name-as/.artifacts/mips_test.asm b/name-as/.artifacts/mips_test.asm index fd9926cb..44f6db3a 100644 --- a/name-as/.artifacts/mips_test.asm +++ b/name-as/.artifacts/mips_test.asm @@ -10,6 +10,8 @@ main: 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 diff --git a/name-as/src/nma.rs b/name-as/src/nma.rs index 7f4777c2..16c1070e 100644 --- a/name-as/src/nma.rs +++ b/name-as/src/nma.rs @@ -369,13 +369,22 @@ fn assemble_i( } } IForm::RtImmRs => { - enforce_length(&i_args, 3)?; - rt = assemble_reg(i_args[0])?; - imm = match base_parse(i_args[1]) { + // 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)?; diff --git a/name-as/src/parser.rs b/name-as/src/parser.rs index ec791bdb..d3eda2dc 100644 --- a/name-as/src/parser.rs +++ b/name-as/src/parser.rs @@ -7,6 +7,8 @@ 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)* } @@ -14,11 +16,11 @@ ident = @{ alpha ~ (alpha | digit)* } label = { ident ~ ":" } register = @{ "$" ~ ident } -instruction_arg = @{ ident | register | hex+ | binary+ | 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 }