PowerPC moving to variable SPR

依然范特西╮ 提交于 2019-12-04 11:40:00

The reason you can't do it is that the instruction architecture doesn't accept register-indirect as an addressing mode for the register parameter. Honestly, I've never seen a machine architecture that does, as the number of registers is usually fairly small, so the register is encoded as part of the instruction itself. If you really don't like the solution you've got, you can try to synthesize the instruction yourself (take the base opcode, see where the register specifier goes and OR in the appropriate value), then execute it. Depending on your OS and compiler, this may not be possible (self-modifying code is often taboo).

Does it make the code cleaner if you write the jump table in assembly? Maybe pass in the SPR specifier (assuming it's a zero-based integer, or can be coerced into one), shift it left to get the offset into the jump table, then jump into the table, which would be a sequence of

MTPSR PSRx, val
RET
MTPSR PSRx+1, val
RET

I don't know what counts as "cleaner" to you, just thought I'd throw that out. Note that you might have to pad with NOPs to get everything aligned, I don't have a PowerPC manual so I have no idea what the instruction sizes or alignment requirements are.

I found a rather elegant solution to this using the stringizer macro:

#define stringify(s) tostring(s)

#define tostring(s) #s

#define mfspr(rn) ({unsigned int rval; \ asm volatile("mfspr %0," stringify(rn) \ : "=r" (rval)); rval;})

#define mtspr(rn, v) asm volatile("mtspr " stringify(rn) ",%0" : : "r" (v))

This is from the U-Boot code for the PowerPC.

This seems like a bizarre thing to do, but if you're convinced you need to do this for some reason then you'll need to implement a jump table or sequence of conditionals whereby you test rA and jump to the appropriate hard-coded mtspr instruction. You'll need to think about how you handle invalid SPR numbers too.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!