Skip to content

Commit 9265e13

Browse files
committed
[assembler] Place default-assigned tags at the end of the RC block.
This matches the behaviour of the TX-2's original M4 assembler, and it's possible that user programs could depend on this (and detect it, for example, by subtracting the addressed of two default-assigned symbols).
1 parent a0891a1 commit 9265e13

File tree

6 files changed

+275
-88
lines changed

6 files changed

+275
-88
lines changed

assembler/src/asmlib/ast.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,10 @@ impl RegistersContaining {
347347
&self.0
348348
}
349349

350+
pub(crate) fn words_mut(&mut self) -> impl Iterator<Item = &mut RegisterContaining> {
351+
self.0.iter_mut()
352+
}
353+
350354
fn symbol_uses(
351355
&self,
352356
block_id: BlockIdentifier,
@@ -359,17 +363,23 @@ impl RegistersContaining {
359363
}
360364

361365
#[derive(Debug, Clone, PartialEq, Eq)]
362-
pub(crate) struct RegisterContaining(Box<TaggedProgramInstruction>);
366+
pub(crate) enum RegisterContaining {
367+
Unallocated(Box<TaggedProgramInstruction>),
368+
Allocated(Address, Box<TaggedProgramInstruction>),
369+
}
363370

364371
impl From<TaggedProgramInstruction> for RegisterContaining {
365372
fn from(inst: TaggedProgramInstruction) -> Self {
366-
Self(Box::new(inst))
373+
RegisterContaining::Unallocated(Box::new(inst))
367374
}
368375
}
369376

370377
impl RegisterContaining {
371378
pub(crate) fn instruction(&self) -> &TaggedProgramInstruction {
372-
&self.0
379+
match self {
380+
RegisterContaining::Unallocated(tpi) => tpi,
381+
RegisterContaining::Allocated(_, tpi) => tpi,
382+
}
373383
}
374384

375385
fn symbol_uses(
@@ -383,7 +393,7 @@ impl RegisterContaining {
383393
// purpose of determining which contexts it has been
384394
// used in.
385395
let mut result = Vec::new();
386-
for symbol_use in self.0.symbol_uses(block_id, block_offset) {
396+
for symbol_use in self.instruction().symbol_uses(block_id, block_offset) {
387397
let (name, span, symbol_definition) = symbol_use;
388398
match symbol_definition {
389399
def @ SymbolUse::Reference(_) => {

assembler/src/asmlib/driver.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ use super::span::*;
2323
use super::state::NumeralMode;
2424
use super::symbol::SymbolName;
2525
use super::symtab::{
26-
BadSymbolDefinition, FinalSymbolDefinition, FinalSymbolTable, FinalSymbolType, LookupOperation,
27-
SymbolDefinition, SymbolTable,
26+
assign_default_rc_word_tags, BadSymbolDefinition, FinalSymbolDefinition, FinalSymbolTable,
27+
FinalSymbolType, LookupOperation, SymbolDefinition, SymbolTable,
2828
};
2929
use super::types::*;
3030
use base::prelude::{Address, IndexBy, Unsigned18Bit, Unsigned36Bit};
@@ -471,7 +471,7 @@ fn assemble_pass3(
471471
};
472472

473473
let Directive {
474-
memory_map,
474+
mut memory_map,
475475
equalities,
476476
entry_point: _,
477477
} = directive;
@@ -500,6 +500,12 @@ fn assemble_pass3(
500500
&mut final_symbols,
501501
)?;
502502

503+
for (_, directive_block) in memory_map.values_mut() {
504+
directive_block.assign_rc_words(symtab, &mut rcblock)?;
505+
}
506+
507+
assign_default_rc_word_tags(symtab, &mut rcblock, &mut final_symbols);
508+
503509
// Emit the binary code.
504510
for (block_id, (maybe_origin, directive_block)) in memory_map.into_iter() {
505511
event!(
@@ -542,12 +548,6 @@ fn assemble_pass3(
542548
};
543549
}
544550

545-
// The evaluation process will have resulted in the computation of
546-
// a default definition for any symbols which were not already
547-
// inserted into final_symbols, so we make sure those are inserted
548-
// now.
549-
final_symbols.import_default_assigned(&*symtab);
550-
551551
// If the RC-word block is non-empty, emit it.
552552
if !rcblock.words.is_empty() {
553553
for (i, (rc_source, word)) in rcblock.words.iter().enumerate() {

assembler/src/asmlib/driver/tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -703,7 +703,7 @@ fn default_assigned_index_register_easy_case() {
703703
let program =
704704
assemble_source("100|STAⱼ 0\nSTAₖ 0\n", Default::default()).expect("program is valid");
705705
dbg!(&program);
706-
assert_eq!(program.chunks.len(), 1);
706+
assert_eq!(program.chunks.len(), 1, "wrong number of program chunks");
707707
assert_eq!(
708708
SymbolicInstruction::try_from(&Instruction::from(program.chunks[0].words[0]))
709709
.expect("instruction 09 shoudl be valid"),

0 commit comments

Comments
 (0)