Skip to content

ARM: inner interpreter interworking fix#64

Open
mkobetic wants to merge 1 commit intomainfrom
interworking
Open

ARM: inner interpreter interworking fix#64
mkobetic wants to merge 1 commit intomainfrom
interworking

Conversation

@mkobetic
Copy link
Owner

@mkobetic mkobetic commented Mar 8, 2026

ARM interpreter relies on deprecated behaviour of mov pc, r0 which doesn't seem to trigger interworking even though it should as of ARM7. This PR replaces the use of mov pc, r0 with the correct bx r0 which required some changes, largely making sure that any code-addresses being jumped to (mostly codeword PFAs) have the thumb bit set, so that it doesn't trigger interworking switch.

The right way to ensure the thumb bit seems to be applying the .thumb_func directive to those symbols that should have it. To achieve that the codeword macros (CODEWORD, HEADLESS, ...) are made architecture specific to be able to inject the directive on the ARM side.

There are few additional addresses that aren't handled by the code-word macros :

  • PFA_NOP (created by macro STARDICT)
  • DOCOLON (declared in interpreter.s)
  • synthetic jump address created by DOES>

HEADER and STARDICT macro are now split into a shared common part (HEADERNOPFA and STARTDICTNOPFA) invoked by ARCH specific variants. HEADER is still shared because only codeword macros need to be ARCH specific.

Note that only the bx rN instruction requires these changes, direct label jumps like b DO_NEXT or b DO_EXECUTE are PC relative jumps that don't trigger interworking, therefore labels used in these jumps don't need to be marked as .thumb_funcs. However we need to be careful in the future because the linker can inject a veneer when the jump is too long, that uses a bx jump under the hood, looking something like this:

00008010 <__func_from_arm_veneer>:
    8010: e51ff004    ldr pc, [pc, #-4] ; Load address from literal pool
    8014: 00009000    .word 0x00009000  ; The actual destination

In these cases the target label does need to have the thumb bit set. So it's more futureproof to set the thumbbit in these cases even if it doesn't need to be at the moment. That's why it is applied to DO_NEXT and DO_EXECUTE as well and should probably be applied to any label that is used as a jump target where the distance can possibly become long at some point.


1: @ compiling to ram
.word XT_R_FROM @ get the synthetic jump address from return stack
.word XT_1PLUS @ set the thumb bit on the jump address
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to set the thumb bit on the synthetic jump address

addi s4, s4, 8
.endm

.macro CODEWORD Name, Label
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RV has the original macro definitions that are now ARCH specific


# start of flash dictionary. The 0 is the stop marker.
.macro STARTDICT
.macro STARTDICTNOPFA
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

STARDICT is now ARCH specific so that we can mark PFA_NOP as .thumb_func for ARM

So unfortunately we have add another set of symbols for the functions because of ARM, thus the _\Label symbols.
*/
.macro HEADER Flags, Name, Label, PFA
.macro HEADERNOPFA Flags, Name, Label, PFA
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Splitting off most of the HEADER macro as HEADERNOPFA so that the body doesn't need to be duplicated on the ARM side just to set .thumb_func on the PFA symbol.

.size _\Label, . - _\Label
.endm

.macro CODEWORD Name, Label
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These macros are now ARCH specific

@mkobetic mkobetic force-pushed the interworking branch 2 times, most recently from 78a9a9b to 713c652 Compare March 8, 2026 18:17
.global _start
_start:
ldr r0, =PFA_COLD + 1
ldr r0, =PFA_COLD
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PFA_COLD already has the the thumb-bit set by the CODEWORD macro

.word XT_COMMA
.word XT_DOLITERAL
.word PFA_XDODOES
.word XT_1PLUS @ MUST set the Thumb bit on the jump address!
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PFA_XDODOES already has the thumb bit set

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant