fix(assembler): correct RCALL label offset + accept avr-gcc assembly syntax#8
Merged
Merged
Conversation
…syntax Found via clean-room differential testing against avr-as (assemble + link, so R_AVR_13_PCREL relocations are applied) and avr-gcc -Os -S output. RCALL bug: RCALL with a label operand computed the PC-relative displacement from the current instruction instead of the next one, because it omitted the `byteLoc + 2` reference that RJMP already passed to ConstOrLabel. Only label operands were affected (numeric offsets were already the relative value), so the existing numeric-only tests never caught it. Verified against avr-as: `loop: rcall loop` => ffdf, `rcall fwd; nop; fwd:` => 01d0. avr-gcc / avr-as front-end compatibility (the encoder was already correct; these are front-end gaps that blocked feeding real avr-gcc .S output): - GNU local labels (.L0:, .L2:) are now parsed as labels, not directives; forward references resolve in pass two via the expression evaluator, which now accepts dotted symbol tokens. - GNU `name = value` symbol assignment (no .equ keyword) is supported, e.g. `__SP_H__ = 0x3e`, `.L__stack_usage = 2`. - Negative 8-bit immediates (ldi/subi/sbci/andi/ori/cpi) are accepted via two's complement (avr-as allows -128..255): `ldi r16,-1` => 0fef. - C-style /* ... */ block comments are stripped before parsing (newlines preserved so reported line numbers stay accurate). - '.' location counter in relative branches: `rcall .` / `rjmp .` encode offset 0 (the avr-gcc stack-reserve idiom), matching avr-as. - avr-gcc metadata directives (.file/.section/.type/.size/.ident/.weak/ .globl/.p2align/...) are accepted as no-ops; genuinely unknown directives are still reported as errors. - A numeric symbol used in register position resolves to that register, so avr-gcc's `__zero_reg__ = 1` / `__tmp_reg__ = 0` work as r1/r0. Validation: real avr-gcc -Os -S output for several C programs (GPIO, loops, arithmetic, functions, switch, bit ops) now assembles byte-identical to the GNU toolchain. Remaining gaps (data symbols in .data, libgcc calls) are linker-domain and out of scope for the flat code-image assembler. Adds 12 regression tests. 484 tests pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Deploying avr8sharp-docs with
|
| Latest commit: |
fa10707
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://1d913e31.avr8sharp-docs.pages.dev |
| Branch Preview URL: | https://fix-assembler-rcall-and-gcc.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.
Found via clean-room differential testing: assemble the same source with our assembler and with
avr-as(assemble and link, soR_AVR_13_PCRELrelocations are applied), then compare byte-for-byte. The oracle also runs realavr-gcc -Os -Soutput through both toolchains.Correctness bug: RCALL with a label
RCALLcomputed the PC-relative displacement from the current instruction instead of the next one — it omitted thebyteLoc + 2reference thatRJMPalready passed toConstOrLabel. Only label operands were affected; numeric offsets were already the relative value, which is why the existing numeric-only tests never caught it.loop: rcall loop00 d0ff df✅ nowrcall fwd; nop; fwd:02 d001 d0✅ nowRJMPand everybrXXbranch already matched avr-as and are unchanged.avr-gcc / avr-as front-end compatibility
The instruction encoder was already correct; these were front-end gaps that blocked feeding real
avr-gcc .Soutput:.L0:,.L2:) parsed as labels, not directives; forward references resolve in pass two (the expression evaluator now accepts dotted symbol tokens).name = valueassignment (no.equ):__SP_H__ = 0x3e,.L__stack_usage = 2.ldi r16,-1→0f ef./* … */block comments stripped before parsing (newlines preserved so line numbers stay accurate)..location counter in relative branches:rcall ./rjmp .encode offset 0 (the avr-gcc stack-reserve idiom), matching avr-as..file/.section/.type/.size/.ident/.weak/.globl/.p2align/…) accepted as no-ops; genuinely unknown directives are still reported as errors.__zero_reg__ = 1/__tmp_reg__ = 0work as r1/r0.Validation
Real
avr-gcc -Os -Soutput for several C programs (GPIO, loops, arithmetic, functions, switch, bit ops) now assembles byte-identical to the GNU toolchain (assembled + linked).Remaining gaps are linker-domain and out of scope for the flat code-image assembler: data symbols in
.data/.bss(no RAM-address model) andlibgcccalls (__mulhisi3, …) — both require a linker.Adds 12 regression tests. 484 tests pass (472 previous + 12 new), no regressions.
🤖 Generated with Claude Code