assembler: forward-ref deferral (immediates + data), gs(), comma .set/.equ, ISR error#10
Merged
Merged
Conversation
…omma .set/.equ More clean-room validation against avr-gcc -Os/-O0/-O1/-O2/-O3 -S surfaced three gaps that blocked real compiler output: - Immediate instructions (LDI/SUBI/SBCI/ORI/ANDI/CPI) threw on a forward-referenced symbol operand, so the ubiquitous `ldi rN, lo8(sym)` / `hi8(sym)` failed whenever the symbol (e.g. a global in .data emitted at the end of the file) came later. They now defer to pass two like LDS/STS. After this, the sample program assembles at every optimisation level. - gs(x) is now supported in the expression evaluator: it yields the word address of a symbol (x >> 1) for function pointers / far jumps — verified byte-identical to avr-as `ldi lo8(gs(f))` / `hi8(gs(f))`. (On <=128KW parts it equals pm(); the >128K stub is not needed for the simulated devices.) - .set / .equ now accept the GNU `NAME, VALUE` comma form in addition to the Atmel `NAME = VALUE` form. Known remaining limitations (documented, not fixed here): - `__gcc_isr` pseudo-op: avr-gcc's default -mgas-isr-prologues emits these in ISRs; expanding them is stateful avr-as magic. Compile with -mno-gas-isr-prologues to get explicit push/pop prologues. - .byte/.word with a forward-referenced symbol expression are not deferred. Adds 3 tests. 503 pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Deploying avr8sharp-docs with
|
| Latest commit: |
864c8f1
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://a5b2b861.avr8sharp-docs.pages.dev |
| Branch Preview URL: | https://improve-assembler-forward-re.avr8sharp-docs.pages.dev |
…rrors
- .byte/.word/.dword now defer to pass two when an element is a
forward-referenced symbol expression (the byte count is always known, so
byteOffset still advances eagerly). This makes in-flash jump tables and
PROGMEM data that reference later labels assemble, e.g. `.word gs(.L_case0)`
or `.byte lo8(x), hi8(x)` with x defined below. The three Emit* methods are
unified into one EmitData(unit) + BuildDataBytes helper.
- __gcc_isr now produces an actionable error ("recompile with
-mno-gas-isr-prologues") instead of a generic "Invalid instruction".
Faithfully expanding it would mean replicating gas's stateful register-clobber
optimiser; the -mno-gas-isr-prologues output assembles cleanly today.
- "Invalid instruction" errors now name the offending mnemonic.
Adds 2 tests. 505 pass.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
Two more clean-room validation rounds (compiling programs at -O0…-O3/-Os and probing avr-as constructs) surfaced and closed several gaps that blocked real
avr-gccoutput. All validated againstavr-as/avr-gcc.Fixes
LDI/SUBI/SBCI/ORI/ANDI/CPIthrew on a forward-referenced symbol operand, so the ubiquitousldi rN, lo8(sym)/hi8(sym)failed when the symbol came later (e.g. a global in.dataat the end of the file). They now defer to pass two like LDS/STS. The struct/loop/function sample now assembles at every optimisation level (failed at -O1/-O2/-Os before)..byte/.word/.dwordnow defer the same way, so in-flash jump tables / PROGMEM data referencing later labels assemble (.word gs(.L0),.byte lo8(x), hi8(x)).gs()added to the expression evaluator — a symbol's word address (x >> 1) for function pointers / far jumps; byte-identical to avr-as..set/.equcomma form (NAME, VALUE) accepted in addition toNAME = VALUE.__gcc_isrnow gives an actionable message (recompile with-mno-gas-isr-prologues) instead of "Invalid instruction"; invalid-instruction errors name the mnemonic.Known remaining limitations (documented)
__gcc_isr(avr-gcc default-mgas-isr-prologues): faithfully expanding it means replicating gas's stateful register-clobber optimiser. Workaround-mno-gas-isr-prologuesassembles cleanly today (verified).call __mulhisi3): need a real linker + libgcc objects — irrelevant for a flat-image simulator assembler.0x100), not avr-gcc's linker, so programs using globals assemble + run consistently but aren't byte-identical to avr-gcc on the data-address operands.Validation
505 tests pass (+5 in this PR), no regressions. Samples assemble across all optimisation levels.
🤖 Generated with Claude Code