Live data from Hacker News

Solving the Mystery of ARM7TDMI Multiply Carry Flag

bmchtech.github.io

31–35 of 35 posts

Re: Solving the Mystery of ARM7TDMI Multiply Carry Flag

#31
post #5

> Seriously, they decided that the program counter should be a general purpose register. Why??? Don't really understand this reaction. Why not? Seems to make for a nice regular design that the PC is just another register.

The big issue is that it doesn't really need to be a GPR. You never find yourself using the PC in instructions other than in, say, the occasional add instruction for switch case jumptables, or pushes / pops. So it ends up wasting instruction space, when you could've had an additional register, or encoded a zero register (which is what AARCH64 does nowadays).

Funnily enough, for my own toy CPU project I elected to make the program counter a GPR, both readable and writable - because it allowed me to eliminate jump and branch instructions.

Reads from the PC return the address of the next instruction to be executed, so a simple exchange between two registers performs the branch, and supplies the return address. (I did end up special-casing the add instruction so that when adding to the PC the return address ends up in the source register.)

Re: Solving the Mystery of ARM7TDMI Multiply Carry Flag

#32
post #5

> Seriously, they decided that the program counter should be a general purpose register. Why??? Don't really understand this reaction. Why not? Seems to make for a nice regular design that the PC is just another register.

This is one of the features of early ARM cores that show that the thing is not a classical RISC design, but traditional CISC core with RISC-like ISA and optimized internal buses.

Re: Solving the Mystery of ARM7TDMI Multiply Carry Flag

#33
post #30

Earlier quoted context omitted.

The reason why the PC is not normally exposed as a regular register is that the set of operations needed for the PC is different than for the regular registers. There are operations required for the PC that are not needed for regular registers, e.g. conditional add (a.k.a. conditional relative jump), add-and-store and load-and-store (a.k.a. procedure call). On the other hand, there are many operations that are needed…

> The reason why the PC is not normally exposed as a regular register is that the set of operations needed for the PC is different than for the regular registers. I'd add to that, that what you give is the reason it's /okay/ to expose the PC as a special register instead of a GPR. The reason that it's /important/ to is that the PC is accessed on every instruction fetch, so if it's part of a uniform register file, it…

It does not make sense to dedicate full read port for reading PC. Just run a bus directly from the register cells, which is exactly how it is done in ARM7TDMI in question.

Re: Solving the Mystery of ARM7TDMI Multiply Carry Flag

#34
post #33
post #30

Earlier quoted context omitted.

> The reason why the PC is not normally exposed as a regular register is that the set of operations needed for the PC is different than for the regular registers. I'd add to that, that what you give is the reason it's /okay/ to expose the PC as a special register instead of a GPR. The reason that it's /important/ to is that the PC is accessed on every instruction fetch, so if it's part of a uniform register file, it…

It does not make sense to dedicate full read port for reading PC. Just run a bus directly from the register cells, which is exactly how it is done in ARM7TDMI in question.

Sure, but then you're half way to a special purpose register. And then you get to add in the logic to arbitrate writes from the GPR ports with reads from the PC-dedicated port. At which point you have more hardware complexity than just a dedicated SPR.

Re: Solving the Mystery of ARM7TDMI Multiply Carry Flag

#35
post #21

Earlier quoted context omitted.

I'm not really familiar with ARM Asm but do you think that's handwritten Asm that its author overlooked the effects of the carry and it just happened to work, or a clever "emulator trap" added by Nintendo's compiler?

It's handwritten and hand-obfuscated assembly, the author didn't know the effect of the carry but knew it was deterministic; and the code worked. Though it's not clear to me where the corruption after the second MLA instruction comes from, because the second block of three instructions should produce the same output as the first. It is possible that it was copied/pasted incorrectly.

Are you sure it's handwritten or obfuscated?

I remember from when I used to disassemble compiled ARM code (not on the NDS though) that it was common to see CMP, followed by a bunch of instructions with one condition predicate, followed by a bunch of instructions with the opposite predicate.

In this case, it's subtly wrong to use that pattern, but only on older versions of ARM. That could reflect a very sneaky attempt to break emulators… but it could also just be a compiler bug.

That said, I too don't understand how corruption could be produced unless there was a copy/paste mistake.

Post reply on HN