assembler: cleanup, robustness, ATmega2560, .rept, data sections#9
Merged
Conversation
PR #6 introduced parallel encoder/directive modules but never wired them into the live assembly path, which is still the legacy OpTable plus inline directive handling in Assembler.cs. The duplication is what allowed the RCALL offset bug to be correct in BranchEncoders.cs yet wrong in the live OpTable. Removed (0 external references, verified by grep across src/ and tests/): - Encoders/{Branch,Arithmetic,LoadStore,BitManip,Misc}Encoders.cs - DirectiveProcessor.cs - AssemblerContext.cs Kept (live): EncoderHelpers.cs (register parsing), Tokenizer.cs, AssemblerIr.cs (SymbolTable/LabelTable/LineTablePassOne). 484 tests pass, no behaviour change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…hrow
- Error messages used the 0-based line index (`Line {idx}`) while the line
table is 1-based, so every diagnostic was off by one. All sites now report
1-based line numbers. Updated the one test that pinned the old value.
- Add TryAssemble(input, out bytes, out errors) and AssembleOrThrow(input)
so callers no longer have to distinguish "empty output" from "errors" by
inspecting a side property. AssembleOrThrow raises AssemblerException, which
carries the collected messages (snapshotted, not the live list).
Adds 5 tests. 488 pass.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The simulator models the ATmega2560 (Arduino Mega) but `.device` only knew ATmega328P and ATtiny85. Adds a full ATmega2560 register map (178 symbols: ports A-L, USART0-3, timers 0-5, SPI, TWI, ADC, EEPROM, external/pin-change interrupts, clock/power control) plus RAMEND/FLASHEND/E2END. Addresses extracted verbatim from avr-libc <avr/iom2560.h> / iomxx0_1.h, using the same convention as the existing definitions: low I/O (data < 0x60) stored as the I/O address, extended I/O (>= 0x60) as the data-space address. Extended-I/O accesses (sts UDR3/PORTL, lds TWBR) were verified byte-identical to avr-as -mmcu=atmega2560. Adds 4 tests. 492 pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The tokenizer now emits a bare '.' as a current-PC token (reusing the Dollar kind the expression evaluator already resolves), so relative branches accept `.+N` / `.-N` operands. Verified byte-identical to avr-as: `rjmp .+2` => 01c0, `rjmp .-2` => ffcf, `rcall .+4` => 02d0. Dotted directives/labels (.L2) are unaffected (still tokenized as before). Adds a test. 493 pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
GNU `.rept <count> ... .endr` blocks are recorded like a macro body and injected <count> times. Composes with the existing \name / @n macro parameter substitution (verified: a .rept around a \reg macro expands correctly and matches avr-as for plain bodies). A stray .endr is reported as an error. Note: \name and @n macro parameters were already supported; this adds the repeat construct. Adds 3 tests. 496 pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… fixes Adds a minimal SRAM data segment so avr-gcc programs that reference global data assemble: - .dseg/.data/.bss/.section .data|.bss switch to a data segment; .cseg/.text switch back. Labels in the data segment, and .comm/.lcomm NAME,SIZE, get sequential SRAM addresses from a simple allocator (base 0x100). Data directives (.byte/.word/...) and .skip/.space/.zero reserve space without emitting code. lds/sts then resolve these symbols. Addresses are self-consistent but are NOT avr-gcc's linker-assigned ones. To support data symbols defined after their use (avr-gcc emits .data last), LDS/STS now defer to pass two like CALL/JMP. Doing so surfaced two latent bugs, both fixed here: - ElementSize concatenated a resolved 4-byte KeyValuePair into a string, so a deferred 4-byte instruction as the LAST line was misread as 2 bytes (affected CALL/JMP too). Now keeps the pair. - _currentSymbolTable was nulled at the end of pass one, so forward-referenced address *expressions* (`lds rN, sym+1`) could not resolve in pass two. It is now restored at the start of pass two. Validated: all six avr-gcc -Os -S sample programs (including a global-pointer one) now assemble. Adds 4 tests. 500 pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Deploying avr8sharp-docs with
|
| Latest commit: |
e148ed9
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://788d7193.avr8sharp-docs.pages.dev |
| Branch Preview URL: | https://improve-assembler-cleanup-an.avr8sharp-docs.pages.dev |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up improvements after the RCALL/front-end fixes (#8). Stacked on #8 — base is
fix/assembler-rcall-and-gcc-frontend; retarget tomainonce #8 merges.Each item was validated with the same clean-room harness (our assembler vs
avr-as/avr-gcc -Os -S, assembled and linked).Maintainability
OpTable+ inline directives inAssembler.cs. That duplication is what let the RCALL bug exist in one path while looking correct in another. DeletedEncoders/{Branch,Arithmetic,LoadStore,BitManip,Misc}Encoders.cs,DirectiveProcessor.cs,AssemblerContext.cs(0 external refs). This also consolidates register parsing onto a single path.Robustness / DX
TryAssemble/AssembleOrThrow. Callers no longer have to distinguish "empty output" from "errors" via a side property;AssembleOrThrowraisesAssemblerExceptioncarrying the messages.Features
<avr/iom2560.h>; extended-I/O accesses verified byte-identical toavr-as -mmcu=atmega2560..location-counter arithmetic (.+N/.-N) in relative branches — matches avr-as..rept N/.endrrepeat blocks; composes with the existing\name/@nmacro parameters..data/.bss/.dseg/.section,.comm/.lcomm,.skip/.space/.zero). Data-segment labels get sequential SRAM addresses (allocator base0x100) solds/stsresolve global-data references. Addresses are self-consistent but not avr-gcc's linker-assigned ones.Latent bugs found & fixed (surfaced by deferring LDS/STS for data forward-refs)
ElementSizeconcatenated a resolved 4-byte pair into a string, so a deferred 4-byte instruction (CALL/JMP/LDS/STS) as the last line was misread as 2 bytes._currentSymbolTablewas nulled at the end of pass one, so forward-referenced address expressions (lds rN, sym+1) could not resolve in pass two. Restored at pass-two start.Validation
All six
avr-gcc -Os -Ssample programs (GPIO, loops, arithmetic, functions, switch, bit ops, and a global-pointer program) assemble. 500 tests pass (+~30 new), no regressions.Intentionally out of scope
call __mulhisi3, …): requires a real linker and the libgcc objects, which a flat code-image assembler for a simulator can't run anyway.🤖 Generated with Claude Code