Multiple Entry(S) macros with single ExitS in RISC OS sources
WPB (1391) 352 posts |
I’m trying to compile Font Manager with some debugging enabled. But when I enable “debugxx” (set in Fonts01 with all the other debugging options) to make use of “debugpaintparams” in Fonts02, I get a bunch of “ExitS without EntryS” errors. There’s an EntryS as expected at the start of “debugpaintparams”, but then various subroutines are called, eg. dbg_comma, which have an additional “Entry” macro to stack some more registers, and then those subroutines exit via ExitS. So I’m guessing it’s the calls to Entry at the start of the subroutines which make the ExitS macros think they’re being called without a matching EntryS. The question is, then, is it safe to change the Entry calls at the start of the subroutines to EntryS calls, or is there some other macro to use to stack additional registers? I suppose this code hasn’t been re-enabled by anyone since the macros were rewritten subtly and that’s why it’s failing now… Can anyone offer any advice before I go down the rabbit hole of actually trying to follow all those macros!? |
Jeffrey Lee (213) 6048 posts |
Yes, replacing the Entry macros with EntryS is the correct fix. (But dbg_hexnumber will need fixing, see below) ExitS is for routines that preserve flags, while Exit is for routines that don’t preserve flags. On 26bit machines it was fine to use Entry with either Exit or ExitS, because Entry stacks the combined LR+PSR, and the Exit macros can decide whether to use the PSR or ignore it. On 32bit machines preserving the flags needs extra stack space to store the PSR, so EntryS was created in order to make sure it’s stored. EntryS can be followed by either Exit or EntryS (Exit is smart enough to ignore the PSR if you don’t want to restore it), but Entry can only be followed by Exit, because there’s no PSR for ExitS to restore. The only thing you’d really need to look out for when changing code between Entry & EntryS is if it looks like it’s doing something fishy like reaching around at specific offsets in the stack – e.g. dbg_hexnumber is loading from SP+12, expecting to recover the entry R0 value. But with EntryS the PSR gets stored below the entry registers, so instead of grabbing R0 it’ll grab the PSR. Solution: Replace the LDR with “FramLDR R0” (FramLDR/FramSTR are handy macros for grabbing registers from within Entry/EntryS stack frames) |
WPB (1391) 352 posts |
Thanks, Jeffrey. That was very helpful and I’ve got it to build and output what I need via DADebug now. For others looking to understand the macros better, I also found this post of yours very helpful. If you don’t mind me using your wording, I could add this information to the wiki somewhere. My only outstanding query is what is the difference between the three DADebug module variants, DADebug, DADebugD and DADebugSA? I’m guessing the last is “StrongArm”? |
Jeffrey Lee (213) 6048 posts |
Yes, that’s fine.
The scheme used by the build system is that a module with no suffix is a ROM build of the module (attempting to softload it might result in failure), “SA” is a standalone (i.e. softloadable) build (like you might get in !System), and “D” is a softloadable debug build (potentially has debug code enabled, and for C modules it’ll be built with different compiler flags). |
Colin Ferris (399) 1814 posts |
I wonder what ‘Reg’ it uses to store the flags with – a standard flag ‘Reg’ could be handy. Using R14 – would corrupt tracing back code from BL xxx I presume storing the PC and not restoring it – is for backtracing. |
WPB (1391) 352 posts |
Ah, now I know! I was using DADebug straight, so the ROM build. It didn’t seem to mind, but I’ll use SA instead just in case. Thanks for additional info. |
Colin Ferris (399) 1814 posts |
Is there a Macro for saving flags around a SWI ? Err - Save r10,r14 ;********* |
Stuart Swales (8827) 1357 posts |
In general, that’d be a daft thing to do as we encourage checking SWI return flags for error. If Swi WhatEver is something you want do producing debug output, why not just write a macro that does the whole lot in one go? |
Colin Ferris (399) 1814 posts |
When you have a whole row of BLeq/SWIeq,s – it can be tricky to work out the proper path! |
Stuart Swales (8827) 1357 posts |
Something along the lines of this?
Use like:
[Edit: I think this might be the first macro that I have written this century, so buyer beware! I did look at the output :-)] |
Colin Ferris (399) 1814 posts |
Interesting – as you said about returning a error - Orrvs r10,r10,#V_flag |
Colin Ferris (399) 1814 posts |
How about :- Swi Save_Flags And Swi Return_Flags |
Colin Ferris (399) 1814 posts |
Have had a look in the manual about ‘Macros’ could you explain some of the features you have used? REVERSE_CC ? |
Stuart Swales (8827) 1357 posts |
@Colin: REVERSE_CC is an ObjAsm operator (not exclusively used in macros) which creates a condition code string which produces the opposite effect to that specified, so that if you want to execute the wrapped SWI if
gives I nicked that bit from one of Hdr:Macros |
Colin Ferris (399) 1814 posts |
Is there a list of Macros? Rick has a few. Anyone done DATE & TIME of when the code is assembled? Like you can do in BASIC. |
Stuart Swales (8827) 1357 posts |
There’s a helpful list at the top of Hdr:Macros, though as RISC OS has been extended to support different CPU architectures, memory models etc., some that were formerly there have been dispersed into other directories in Hdr:, and of course, more have been added since RISC OS 2 days. Just do a !Find for MACRO in your Hdr directory. If you really want to embed DATE and TIME string (not helpful if you’re trying to create reproducible builds!) then just run a BASIC program to output a file that sets a couple of strings and include that. |
Rick Murray (539) 13840 posts |
Mainly just copies of the BASIC EQUx commands to make it easier to port stuff, which got expanded with EQUSZ (null terminated) and EQUSZ (and aligned afterwards). The others (SETV etc) will be just the same as those available anywhere else. I had to retire PUSH and POP (similar to Entry/Exit) as ObjAsm is too dumb to understand the use of these macros in non-UAL code. Plus, it doesn’t warn about creating macros that have the same name as things it does recognise. Hmm…
And C – the As Stuart says, a little helper program to create some code that is then included with the main code is how I usually handle this (in C and assembler). It gives much more flexibility over the format of the values (if you prefer YYYY/MM/DD or DD Mmm YYYY or time in am/pm or 24h…). |