I spent some time looking at GBA stuff after posting about it a few days ago. It's been so long since I've touched ARM32 that I'd forgotten the insane shit you can do in one instruction, e.g. LDMEQFD SP!, {R0, R2-R5, PC}.
@pervognsen Is that still technically RISC? Or has RISC just shifted its baseline because of how execution architecture has matured?
@nick I'm pretty sure that LDM would have worked as-is with the original ARM1 instruction set so this was there in the beginning. ARM has never been RISC in any meaningful sense. It's a load/store architecture with a bunch of GPRs but that's about it. I guess if you wanted to be snide, you could say that it shares in the earliest RISC tradition of shipping parts of your microarchitecture as the ISA (barrel shifter, predication, etc) like MIPS did with branch delay slots and imprecise exceptions.
@pervognsen @nick FWIW the string-ish multi-loads were in early POWER as well and that was definitely sticker-label RISC
@rygorous @nick The pièce de résistance is combining it with predication and the PC as a pseudo-GPR. Now we're cooking.

@pervognsen @nick reference on early POWER multi-loads https://bitsavers.org/pdf/ibm/IBM_Journal_of_Research_and_Development/341/ibmrd3401E.pdf pp. 7-10 starting with "The RS/6000 architecture has adopted the following strategy for dealing with misaligned data."

Load-multiple section starts. on p. 9 "Another aspect of including string operations..."

@pervognsen @nick I will say that they are IMO bang on the money here on _all_ counts - calling out that

a) mem copies/string copies etc. are important and usually unaligned
b) Alpha-esque "we give you a way to do SWAR loops for this" only gets you so far,
c) for load/store multiple, that function prologues/epilogues are the key use case

other ISAs have struggled to learn that lesson 30 years later...

@rygorous @pervognsen @nick

> The architecture allows for the partial
completion of an operation and thegeneration of an
alignment-check interrupt when the datacrosses a cache-
line boundary. System softwarecan then complete the
instruction by fixing up the affected registersor memory
locations.

this has EINTR vibes

@wolf480pl @rygorous @nick Regarding EINTR vibes, this is also true with something like REP MOVSB at page boundaries if there are soft faults. Or interrupts for that matter, but it happens even with exceptions, analogous to the cache line case.

@pervognsen @rygorous @nick

hmm are there any Unix syscalls that can partially happen and then return EINTR? I guess not... read() and write() can partially complete but then they return a length, and you don't get to know if it was short because of a signal...

so it looks like IBM's string instructions requiring "fixing up registers or memory" is even worse

@pervognsen @rygorous @nick
but my point was more about "it's an edge case we don't want to handle, let's create a new edge case one layer up and let those folks handle it"
@wolf480pl @pervognsen @nick check out how MIPS handles exceptions triggered from branch delay slots one day :P
@wolf480pl @pervognsen @nick (you can't just save the address of the faulting instruction and resume there, because if it's in a branch delay slot, now you end up falling through the branch instead of executing it)

@rygorous @pervognsen @nick
ok so this will probably make anyone who actually knows MIPS cringe, but

if you somehow knew the branch target (maybe it's saved somewhere, next to the faulting instruction's address)

and if branches in delay slots are legal (I'd be impressed if they are)

maybe you could (in pseudocode):

jr $reg_saved_pc
jr $reg_saved_branch_target

?

@wolf480pl @pervognsen @nick branches inside MIPS branch delay slots are not legal, but the branch target address is not saved for you anywhere

@rygorous @pervognsen @nick
bummer

is it legal for an instruction in a branch delay slot to be branch target?

@rygorous @pervognsen @nick
ok, now I'm convinced it's impossible to return from an exception on MIPS

yet they somehow do it so I'll have to look it up

@rygorous @pervognsen @nick
This is smart.

I suspected such a flag would be needed, but I didn't think the "should I subtract 4 or not" logic would be in hardware.

It's the opposite of EINTR, it actively tries to make the upper layer's life easier.

@wolf480pl @pervognsen @nick IIRC it didn't use to be

This is the R3000 version. I believe the R2000 (?) signaled it by setting bit 1 of EPC (which is always 4B aligned otherwise) and expected the handler to fix it up. Something along those lines.

@rygorous @pervognsen @nick
and does setting bit 0 of EPC unlock the secret cow level?

wait no that'd be ARM

@wolf480pl @pervognsen @nick if by secret cow level you mean jazelle, then yes

@rygorous @pervognsen @nick

how

Thumb has 2-byte instructions

@wolf480pl @pervognsen @nick you're right, I misremembered, brain fart.

bit 0 is the Thumb flag, Jazelle is its own other cursed state