Skip to content

Commit

Permalink
Merge pull request #47 from cs-pub-ro/didactic-assembler-patch
Browse files Browse the repository at this point in the history
Patches to bit generation for register sums and other particular cases
  • Loading branch information
Pfat8equalsD authored Dec 10, 2024
2 parents fdeafd7 + ff6f776 commit b72b0f0
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 36 deletions.
62 changes: 34 additions & 28 deletions didasm/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ impl Ir {
};

let (d, reg) = match (op1.clone(), op2.clone()) {
(Some(Reg(_)), Some(Imm(_))|None) => (false, None),
(Some(Reg(r)), _) => (true, Some(r as usize)),
(_, Some(Reg(r))) => (false, Some(r as usize)),
_ => (false, None),
Expand All @@ -169,7 +170,8 @@ impl Ir {
(Some(Reg(_)), Some(Reg(ri))) => (0b11, Some(ri.into()), None),
(Some(Imm(_)), Some(Imm(_))) => {
return Err("Operations between 2 immediate values is not allowed!".to_string());
}
},
(Some(Reg(ri)), Some(Imm(_))|None) => (0b11, Some(ri.into()), None),
(Some(Imm(_)), Some(_)) => {
if matches!(
mnemonic,
Expand Down Expand Up @@ -214,7 +216,7 @@ impl Ir {
}
(Some(RegSum { b, x }), _) | (_, Some(RegSum { b, x })) => (
0b00,
Some(((x as usize) & 0b1) + ((b as usize) & 0b10)),
Some(((x as usize) & 0b1) + (((b as usize) & 0b1) << 1)),
None,
),
(Some(Indexed { x: ri, displacement } | Based { b: ri, displacement }), _)
Expand All @@ -223,16 +225,16 @@ impl Ir {
}
(Some(BasedIndexed { b, x, displacement }), _) | (_, Some(BasedIndexed { b, x, displacement })) => (
0b10,
Some(((x as usize) & 0b1) + ((b as usize) & 0b10)),
Some(((x as usize) & 0b1) + (((b as usize) & 0b1) << 1)),
Some(displacement),
),
(Some(RegSumAutoincrement { b, x }), _) | (_, Some(RegSumAutoincrement { b, x })) => (
0b01,
Some(((x as usize) & 0b1) + ((b as usize) & 0b10)),
Some(((x as usize) & 0b1) + (((b as usize) & 0b1) << 1)),
None,
),
(Some(RegSumAutodecrement { b }), _) | (_, Some(RegSumAutodecrement { b })) => {
(0b01, Some(0b100 + ((b as usize >> 1) & 1)), None)
(0b01, Some(0b100 + ((b as usize) & 1)), None)
}
(Some(Direct(displacement)), _) | (_, Some(Direct(displacement))) => (0b01, Some(0b110), Some(displacement)),
(Some(Indirect(displacement)), _) | (_, Some(Indirect(displacement))) => {
Expand All @@ -241,7 +243,7 @@ impl Ir {
// Cases that should have been placed in _ but explicitly stated
// to utilize the pattern matching mechanism of rust for
// proving completeness on this match
(None | Some(Reg(_) | Imm(_)), None | Some(Reg(_) | Imm(_))) => (0, None, None),
(None | Some(Imm(_)), None | Some(Reg(_) | Imm(_))) => (0, None, None),
};
Ok(Ir {
mnemonic,
Expand Down Expand Up @@ -471,10 +473,11 @@ impl Ir {
opcode.set_mod(m);
let x: Option<u16> = x
.map(|x| {
x.try_into()
.map_err(|_| format!("{x} cannot be converted to unsigned 16 bit"))
})
.transpose()?;
x as u16
// x.try_into()
// .map_err(|_| format!("{x} cannot be converted to unsigned 16 bit"))
});
// .transpose()?;
Ok(FullInstruction {
i: opcode,
displacement: x,
Expand Down Expand Up @@ -544,16 +547,18 @@ impl Ir {
})?);
let x: Option<u16> = x
.map(|x| {
x.try_into()
.map_err(|_| format!("{x} cannot be converted to unsigned 16 bit"))
})
.transpose()?;
x as u16
// x.try_into()
// .map_err(|_| format!("{x} cannot be converted to unsigned 16 bit"))
});
// .transpose()?;
let y: Option<u16> = y
.map(|x| {
x.try_into()
.map_err(|_| format!("{x} cannot be converted to unsigned 16 bit"))
})
.transpose()?;
x as u16
// x.try_into()
// .map_err(|_| format!("{x} cannot be converted to unsigned 16 bit"))
});
// .transpose()?;

Ok(FullInstruction {
i: opcode,
Expand All @@ -577,13 +582,14 @@ impl Ir {
})?);
let x: Option<u16> = x
.map(|x| {
x.try_into()
.map_err(|_| format!("{x} cannot be converted to unsigned 16 bit"))
})
.transpose()?;
let imm = imm
.try_into()
.map_err(|_| format!("{imm} cannot be converted to unsigned 16 bit"))?;
x as u16
// x.try_into()
// .map_err(|_| format!("{x} cannot be converted to unsigned 16 bit"))
});
// .transpose()?;
let imm = imm as u16;
// .try_into()
// .map_err(|_| format!("{imm} cannot be converted to unsigned 16 bit"))?;
Ok(FullInstruction {
i: opcode,
displacement: x,
Expand All @@ -605,9 +611,9 @@ impl Ir {
opcode.set_reg(reg.try_into().map_err(|_| {
"Register enum should always be convertible to u16".to_string()
})?);
let imm = imm
.try_into()
.map_err(|_| format!("{imm} cannot be converted to unsigned 16 bit"))?;
let imm = imm as u16;
// .try_into()
// .map_err(|_| format!("{imm} cannot be converted to unsigned 16 bit"))?;
Ok(FullInstruction {
i: opcode,
displacement: None,
Expand Down
16 changes: 8 additions & 8 deletions didasm/src/tokens.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ impl From<ControlFlowMnemonic> for u16 {
fn from(value: ControlFlowMnemonic) -> Self {
match value {
Call | Ret => 0b100,
Iret | Jmp => 0b010,
Iret | Jmp => 0b101,
Hlt => 0b110,
}
}
Expand Down Expand Up @@ -239,7 +239,7 @@ impl From<Register> for usize {
Ra => 0,
Rb => 1,
Rc => 2,
Is => 3,
Sp => 3,
Xa => 4,
Xb => 5,
Ba => 6,
Expand All @@ -257,7 +257,7 @@ pub enum Register {
Rb,
Rc,
// Stack pointer
Is,
Sp,
// Index register
Xa,
Xb,
Expand Down Expand Up @@ -392,7 +392,7 @@ impl FromStr for Operand {
Regex::new(r"^\[\s*(.+)\s*\]$").expect("Outer brackets regex has a syntax error.")
});
static CHECK_INSIDE_BRACKETS: Lazy<Regex> = Lazy::new(|| {
Regex::new(r"^([a-z0-9_]+)\s*\+\s*([a-z0-9_]+)\s*(?:\+\s*([a-z0-9_]+)|([+\-]))?$")
Regex::new(r"^([a-z0-9_]+)\s*\+\s*(-?[a-z0-9_]+)\s*(?:\+\s*(-?[a-z0-9_]+)|([+\-]))?$")
.expect("Inside brackets regex has a syntax error.")
});
// Easiest case to detect
Expand All @@ -413,7 +413,7 @@ impl FromStr for Operand {
} else if let Some(cap) = CHECK_OUTER_BRACKETS.captures(s) {
let (_, [op]) = cap.extract();
if let Ok(reg) = Register::from_str(op) {
if matches!(reg, Ra | Rb | Rc | Is) {
if matches!(reg, Ra | Rb | Rc | Sp) {
Err(format!(
"{reg} is not supported in indirect register addresing!"
))
Expand Down Expand Up @@ -481,9 +481,9 @@ impl FromStr for Operand {
(Expression(_),_,Some(Expression(_)), _) |
(_, Expression(_), Some(Expression(_)), _)
=> Err("Sum between 2 or more expressions is not supported by the ISA".to_string()),
(Reg(x @ (Ra|Rb|Rc|Is)), _, _, _) |
(_, Reg(x @ (Ra|Rb|Rc|Is)), _, _) |
(_, _, Some(Reg(x @ (Ra|Rb|Rc|Is))), _)
(Reg(x @ (Ra|Rb|Rc|Sp)), _, _, _) |
(_, Reg(x @ (Ra|Rb|Rc|Sp)), _, _) |
(_, _, Some(Reg(x @ (Ra|Rb|Rc|Sp))), _)
=> Err(format!("Register sum syntax does not support register {x}")),
_ => Err("Something went wrong! Report the given instruction to the developer for more specific error messages!".to_string())
}
Expand Down

0 comments on commit b72b0f0

Please sign in to comment.