Shop OBEX P1 Docs P2 Docs Learn Events
Flag abuse and ""extended"" flag register set — Parallax Forums

Flag abuse and ""extended"" flag register set

As it turns out, it's possible to implement every necessary operation to pretend the GPR are just additional flag registers. This enables some neat tricks with conditionals/etc. I figured this out while working on the LLVM backend, and used it to tell LLVM a bit of a white lie, so it thinks the P2 has a nice 514 flag registers, not two. Should net some better codegen around flag handling (especially boolean logic) if I do this right. (The generated code for the P2's regfile is also an additional 5000 lines longer. Tablegen description remains under 100 lines.)

' XOR flag, flag
modc 0b0110 ' C = C ^ Z
modz 0b0110 ' Z = C ^ Z
' XOR flag, reg[0]
testb reg, #0 xorc ' C = C ^ reg[0]
testb reg, #0 xorz ' Z = Z ^ reg[0]
' XOR reg[0], flag
' The first and only non-trivial one. I thought it wouldn't work at first.
' Thanks to Wuerful_21 for telling me about this; I didn't think to abuse predicates!
if_c xor reg, #1 ' reg[0] = reg[0] ^ C
if_z xor reg, #1 ' reg[0] = reg[0] ^ Z
' XOR reg[0], reg[0]
' I couldn't think of a 1 instr solution to this, nor a 'don't clobber other regs' solution.
' In the LLVM backend, I simply opt to clobber the whole register to do it in 1 instr.
xor reg, reg
' NOT flag
modc 0b1010 ' C = !C
modz 0b1010 ' Z = !Z
' NOT reg[0]
xor reg, #1


' Doing the above for all other bitwise ops is left as an exercise for the reader. (It's pretty easy)

Comments

  • evanhevanh Posts: 15,916

    My favourite abuse is RET WCZ in leaf routines. Then I can use the flags in higher level loops without needing to explicitly preserve them.

  • I wonder if a set of pseudo-instructions could be nice for this. The LLVM backend I'm writing does exactly that, providing the following pseudo-instrs:

    bit: Any GPR, or a flag register.
    ANDB bitd, bits
    ANDNB bitd, bits
    ORB bitd, bits
    XORB bitd, bits
    SETB bitd, bits
    
Sign In or Register to comment.