hlorenzi / customasm

💻 An assembler for custom, user-defined instruction sets! https://hlorenzi.github.io/customasm/web/
Apache License 2.0
719 stars 56 forks source link

Move multiple defintion problem #44

Closed aslak3 closed 1 year ago

aslak3 commented 4 years ago

My processor has a "push multiple registers" opcode, a bit like MOVEM on the 68K. I'm struggling to represent it, since though I've defined a token:

    {
            r0 = 1
            r1 = 2
            r2 = 4
            r3 = 8
            r4 = 16
            r5 = 32
            r6 = 64
            r7 = 128
    }

I can't then do:

    popmulti r1+r2,(r7)

Is there a solution to this, without defining all 256 combinations. :-)

moonheart08 commented 4 years ago

For now, I don't think so(?), so the best way would just be to use 0b0000_0000, and just remember which bit is which reg which isn't too hard.

aslak3 commented 4 years ago

Yes, it's not too bad. Hopefully it'll support this kind of thing soon.

I guess I could feed my assembly through CPP and use some macros.

pol-rivero commented 4 years ago

One way you could do this is by defining the registers as constants and then asking for an integer as the register list.

R0 = 1
R1 = 2
R2 = 4
R3 = 8
R4 = 16
R5 = 32
R6 = 64
R7 = 128

#cpudef "test"
{
    #bits 8

    #tokendef REG
    {
        r0 = 1
        r1 = 2
        r2 = 4
        r3 = 8
        r4 = 16
        r5 = 32
        r6 = 64
        r7 = 128
    }

    popmulti {register_list: u8}, ( {ea: REG} ) -> 0xABCD @ register_list @ ea[7:0]

}

This way popmulti R0+R1+R3+R4+R5+R6,(r7) becomes 0xABCD7B80.

You can also define the constants in lowercase and it would work fine in most cases, but if you've got an instruction with the same mnemonic and multiple addressing modes (like if both mov r0, r3 and mov r0, 123 are legal) you should keep them uppercase or the assembler will get confused. Also, if you don't need your instruction to use the + sign and you are willing to be more flexible, you could do stuff like popmulti ALL_REGS - R3, (r7) (with ALL_REGS = 0xFF) or typing the registers out of order. However, I would recommend using the | sign instead of +, in case you accidentally type a register twice (popmulti R1 + R1, (r7) gets interpreted as R2 since 2+2=4, popmulti R1 | R1, (r7) gets reduced to just R1 since 2|2=2).

aslak3 commented 4 years ago

That works well, thanks! Much easier then bringing out CPP. Using an or to bring them together seems the sensible approach.

I'm not sure if there's a general solution to this case.

Man, I might have a reason to learn Rust now.

hlorenzi commented 1 year ago

I'm closing this since it can be achieve like p-rivero suggested or with recursive rules in newer versions! Feel free to open this issue again if you still need help.