mirror of
https://github.com/powdr-labs/powdr.git
synced 2026-04-20 03:03:25 -04:00
Merge pull request #278 from chriseth/hi_lo_offsets
Parse hi and lo data reference offsets.
This commit is contained in:
@@ -109,9 +109,14 @@ fn replace_dynamic_label_reference(
|
||||
if instr1.as_str() != "lui" || instr2.as_str() != "addi" {
|
||||
return None;
|
||||
};
|
||||
let [Argument::Register(r1), Argument::Constant(Constant::HiDataRef(label1))] = &args1[..] else { return None; };
|
||||
let [Argument::Register(r2), Argument::Register(r3), Argument::Constant(Constant::LoDataRef(label2))] = &args2[..] else { return None; };
|
||||
if r1 != r3 || label1 != label2 || data_objects.contains_key(label1) {
|
||||
let [Argument::Register(r1), Argument::Constant(Constant::HiDataRef(label1, offset1))] = &args1[..] else { return None; };
|
||||
let [Argument::Register(r2), Argument::Register(r3), Argument::Constant(Constant::LoDataRef(label2, offset2))] = &args2[..] else { return None; };
|
||||
if r1 != r3
|
||||
|| label1 != label2
|
||||
|| *offset1 != 0
|
||||
|| *offset2 != 0
|
||||
|| data_objects.contains_key(label1)
|
||||
{
|
||||
return None;
|
||||
}
|
||||
Some(Statement::Instruction(
|
||||
@@ -216,14 +221,16 @@ fn insert_data_positions(
|
||||
fn replace_data_reference(constant: &mut Constant, data_positions: &BTreeMap<String, u32>) {
|
||||
match constant {
|
||||
Constant::Number(_) => {}
|
||||
Constant::HiDataRef(data) => {
|
||||
Constant::HiDataRef(data, offset) => {
|
||||
if let Some(pos) = data_positions.get(data) {
|
||||
let pos: u32 = pos + *offset as u32;
|
||||
*constant = Constant::Number((pos >> 12) as i64)
|
||||
}
|
||||
// Otherwise, it references a code label
|
||||
}
|
||||
Constant::LoDataRef(data) => {
|
||||
Constant::LoDataRef(data, offset) => {
|
||||
if let Some(pos) = data_positions.get(data) {
|
||||
let pos: u32 = pos + *offset as u32;
|
||||
*constant = Constant::Number((pos & 0xfff) as i64)
|
||||
}
|
||||
// Otherwise, it references a code label
|
||||
@@ -601,8 +608,8 @@ fn argument_to_number(x: &Argument) -> u32 {
|
||||
fn constant_to_number(c: &Constant) -> u32 {
|
||||
match c {
|
||||
Constant::Number(n) => *n as u32,
|
||||
Constant::HiDataRef(n) | Constant::LoDataRef(n) => {
|
||||
panic!("Data reference was not erased during preprocessing: {n}");
|
||||
Constant::HiDataRef(n, off) | Constant::LoDataRef(n, off) => {
|
||||
panic!("Data reference was not erased during preprocessing: {n} + {off}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,11 +103,11 @@ fn disambiguate_constant_if_needed(
|
||||
) -> Constant {
|
||||
match c {
|
||||
Constant::Number(_) => c,
|
||||
Constant::HiDataRef(s) => {
|
||||
Constant::HiDataRef(disambiguate_symbol_if_needed(s, prefix, globals))
|
||||
Constant::HiDataRef(s, offset) => {
|
||||
Constant::HiDataRef(disambiguate_symbol_if_needed(s, prefix, globals), offset)
|
||||
}
|
||||
Constant::LoDataRef(s) => {
|
||||
Constant::LoDataRef(disambiguate_symbol_if_needed(s, prefix, globals))
|
||||
Constant::LoDataRef(s, offset) => {
|
||||
Constant::LoDataRef(disambiguate_symbol_if_needed(s, prefix, globals), offset)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,8 +39,8 @@ impl Register {
|
||||
#[derive(Clone)]
|
||||
pub enum Constant {
|
||||
Number(i64),
|
||||
HiDataRef(String),
|
||||
LoDataRef(String),
|
||||
HiDataRef(String, i64),
|
||||
LoDataRef(String, i64),
|
||||
}
|
||||
|
||||
impl Display for Statement {
|
||||
@@ -70,12 +70,24 @@ impl Display for Constant {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Constant::Number(n) => write!(f, "{n}"),
|
||||
Constant::HiDataRef(sym) => write!(f, "%hi({sym})"),
|
||||
Constant::LoDataRef(sym) => write!(f, "%lo({sym})"),
|
||||
Constant::HiDataRef(sym, offset) => {
|
||||
write!(f, "%hi({sym}{})", format_hi_lo_offset(*offset))
|
||||
}
|
||||
Constant::LoDataRef(sym, offset) => {
|
||||
write!(f, "%lo({sym}{})", format_hi_lo_offset(*offset))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn format_hi_lo_offset(offset: i64) -> String {
|
||||
match offset {
|
||||
0 => String::new(),
|
||||
1.. => format!(" + {offset}"),
|
||||
..=-1 => format!(" - {}", -offset),
|
||||
}
|
||||
}
|
||||
|
||||
fn format_arguments(args: &[Argument]) -> String {
|
||||
args.iter()
|
||||
.map(|a| format!("{a}"))
|
||||
|
||||
@@ -122,7 +122,9 @@ pub fn references_in_statement(statement: &Statement) -> BTreeSet<&str> {
|
||||
Argument::Symbol(s) => Some(s.as_str()),
|
||||
Argument::RegOffset(_, c) | Argument::Constant(c) => match c {
|
||||
Constant::Number(_) => None,
|
||||
Constant::HiDataRef(s) | Constant::LoDataRef(s) => Some(s.as_str()),
|
||||
Constant::HiDataRef(s, _offset) | Constant::LoDataRef(s, _offset) => {
|
||||
Some(s.as_str())
|
||||
}
|
||||
},
|
||||
Argument::Difference(_, _) => todo!(),
|
||||
})
|
||||
@@ -212,8 +214,8 @@ fn apply_replacement_to_instruction(
|
||||
fn apply_replacement_to_constant(c: Constant, replacements: &BTreeMap<&str, &str>) -> Constant {
|
||||
match c {
|
||||
Constant::Number(_) => c,
|
||||
Constant::HiDataRef(s) => Constant::HiDataRef(replace(s, replacements)),
|
||||
Constant::LoDataRef(s) => Constant::LoDataRef(replace(s, replacements)),
|
||||
Constant::HiDataRef(s, off) => Constant::HiDataRef(replace(s, replacements), off),
|
||||
Constant::LoDataRef(s, off) => Constant::LoDataRef(replace(s, replacements), off),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -85,8 +85,14 @@ OffsetRegister: Argument = {
|
||||
|
||||
Constant: Constant = {
|
||||
ConstantExpression => Constant::Number(<>),
|
||||
"%hi(" <Symbol> ")" => Constant::HiDataRef(<>),
|
||||
"%lo(" <Symbol> ")" => Constant::LoDataRef(<>),
|
||||
"%hi(" <arg:HiLowArgument> ")" => Constant::HiDataRef(arg.0, arg.1),
|
||||
"%lo(" <arg:HiLowArgument> ")" => Constant::LoDataRef(arg.0, arg.1),
|
||||
}
|
||||
|
||||
HiLowArgument: (String, i64) = {
|
||||
<Symbol> => (<>, 0),
|
||||
<Symbol> "+" <ConstantExpression> => (<>),
|
||||
<n: Symbol> "-" <o: ConstantExpression> => (n, -o),
|
||||
}
|
||||
|
||||
ConstantExpression: i64 = {
|
||||
|
||||
Reference in New Issue
Block a user