customasm icon indicating copy to clipboard operation
customasm copied to clipboard

Allow aliases for token substitution

Open EnderShadow opened this issue 1 year ago • 8 comments

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.

EnderShadow avatar Feb 23 '24 21:02 EnderShadow

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?

hlorenzi avatar Feb 25 '24 19:02 hlorenzi

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.

EnderShadow avatar Feb 25 '24 21:02 EnderShadow

Why not just:

#subruledef register
{
    %r{num: u8} => num
    reg_a => 184`8
}

MineRobber9000 avatar Feb 26 '24 06:02 MineRobber9000

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.

EnderShadow avatar Feb 26 '24 08:02 EnderShadow

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.

hlorenzi avatar Feb 26 '24 17:02 hlorenzi

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.

EnderShadow avatar Feb 26 '24 18:02 EnderShadow

I see. To work around this on the current version, maybe you could declare your #subruledefs 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.

hlorenzi avatar Feb 27 '24 00:02 hlorenzi

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"

MineRobber9000 avatar Feb 27 '24 10:02 MineRobber9000