theandrew168 / derzforth

Bare-metal Forth implementation for RISC-V
MIT License
42 stars 5 forks source link

Can beqz simply jump to 0(ra) ? #17

Closed aw closed 2 years ago

aw commented 2 years ago

Hi,

In looking at the functions such as memclr and memcpy, I noticed there's a line like this:

memclr:
    beqz a1, memclr_done  # loop til size == 0
    ...
memclr_done:
    ret

I wonder if it's necessary to jump to a label which only performs a ret .. jalr zero, 0(ra).

Could that label simply be omitted and the code changed to this?:

memclr:
    beqz a1, 0(ra)  # loop til size == 0 then return

I haven't made a PR because I thought maybe there was a reason you did it that way.

theandrew168 commented 2 years ago

Oh nice, I didn't even consider doing it this way. I do think that while this does save an instruction / label, it would make the func less consistent with the others. I use the func, func_loop, func_done setup in a few different places. Unless this shortcut would also work for the others? I'd have to go through em and see. I suppose it'd be fine unless the func does something extra in the func_done label, which some do (dbj2_hash does some finalization, for example).

aw commented 2 years ago

Hi Andrew, I actually tested it and it doesn't work:

ValueError: too many values to unpack (expected 2)

I think it's because beq jumps to an offset whereas jalr performs a jump and link, so we would need to add an instruction to save the ra register.. which defeats the purpose of this optimization.

theandrew168 commented 2 years ago

Ahh, that's good to know! It was a solid idea, though.