customasm
customasm copied to clipboard
Allow aliases for token substitution
I have CPU definition, but for various purposes I want to alias one thing to another. For example, something like this.
subruledef register
{
%r{num: u8} => num
}
#alias reg_a = %r184
This would allow reg_a
to be used anywhere a register would be used. Alternatively, being able to extend an existing subruledef would work as well.
Could you give some syntax examples on the usage of reg_a
? Is it to be used in a rule declaration, or among your user code?
The intent was that it would be used in user code. My main use case is that I'm using customasm for writing microcode for a general microcode engine. For specific architectures that use it, I want to name some of the registers so that I don't need to remember which microarchitectural register maps to which ISA register. I have a few examples here.
https://github.com/EnderShadow/microcode-engine/blob/main/overture.asm https://github.com/EnderShadow/microcode-engine/blob/main/etca_10001E0FF_17_9.asm
In the same repo, I currently get around by using a script to parse #alias lines and do a find-replace in the file before running it through customasm, but I'm not sure how scalable an approach like that is in practice.
Why not just:
#subruledef register
{
%r{num: u8} => num
reg_a => 184`8
}
The reason why I can't do that is because the the microcode definition defines everything that's specific to the microcode engine and nothing more. Implementations of architectures using the microcode engine need registers for specific purposes and duplicating the microcode engine's definition file is not what I want to do. If there was a way to define multiple subrules with the same name and have them get merged, that would be a solution as well.
How about something like:
#const REG_A_VALUE = 184`8
#subruledef register
{
%r{num: u8} => num
reg_a => REG_A_VALUE
}
You can easily redefine constants via a few methods:
- Nest the constant declarations in an
#if
block, and have one of those per architecture; - Override their values directly through the command-line with
-d
, and use different batch scripts for each architecture; - Include architecture-specific files (with just constant declarations) along with your main code file, as in
customasm arch1.asm code.asm
.
That's not a workable solution. As per the linked examples, there architectures using the core source file may not share names of registers and I don't want to pollute the shared definition file with registers that at best will not be used and at worst cause subtle bugs through accidental use of the wrong register.
I see. To work around this on the current version, maybe you could declare your #subruledef
s conditionally instead? Using one of the suggestions from my previous post. For example, declare one #subruledef
per architecture in separate files, and include them conditionally through the command-line.
Though, since right now you can't merge rule blocks under a single name, you'd have to duplicate the common parts. Merging would indeed be a nice feature to have in the future as well.
How about:
#subruledef register_direct
{
r{num: u8} => num
; the other direct register definitions
}
#subruledef register
{
{r: register_direct} => r
{r: register_alias} => r
}
; go on using `register` in your other ruledefs
Then, in your architecture file:
#subruledef register_alias
{
reg_a => 184`8
}
#include "common.asm"