On 11/4/21 10:05 AM, Warner Losh wrote:
> + /*
> + * Make sure T mode matches the PC's notion of thumb mode, although
> + * FreeBSD lets the processor sort this out, so we may need remove
> + * this check, or generate a signal...
> + */
> + if (!!(tswap32(gr[TARGET_REG_PC]) & 1) != !!(cpsr & CPSR_T)) {
> + return -TARGET_EINVAL;
> + }
I've had a read through the Arm ARM for "movs pc, lr", which is how swi_exit returns to
userspace:
CPSRWriteByInstr(SPSR[], '1111', TRUE);
...
BranchWritePC(result);
So the CPSR gets written first, which sets the T bit, and thus the result of
CurrentInstrSet(), then
BranchWritePC(bits(32) address)
if CurrentInstrSet() == InstrSet_ARM then
if ArchVersion() < 6 && address<1:0> != '00' then UNPREDICTABLE;
BranchTo(address<31:2>:'00');
...
else
BranchTo(address<31:1>:'0');
> + env->regs[15] = tswap32(gr[TARGET_REG_PC]);
So this should mask the low 1 or 2 bits depending on cpsr & CPSR_T.
Will do. Thanks for all the patient explanations.
Warner
r~