/* * return from user-mode exception. * expects new SPSR in R0. R13 must point to ureg->type. */ _rfue: TEXT rfue(SB), 1, $-4 // CPSID // BIC $PsrMbz, R0 /* force little-endian upon return */ MOVW R0, SPSR /* ... */ /* * order on stack is type, psr, pc, but RFEV7 needs pc, psr. * step on type and previous word to hold temporary values. * we could instead change the order in which psr & pc are pushed. */ MOVW 4(R13), R1 /* psr */ MOVW 8(R13), R2 /* pc */ MOVW R2, 4(R13) /* pc */ MOVW R1, 8(R13) /* psr */ MOVM.DB.S (R13), [R0-R14] /* restore user registers */ ADD $4, R13 /* pop type, sp -> pc */ #ifdef OLDWAY ADD $(2*4), R13 /* pop past ureg->{type+psr} to pc */ /* * this used to work on arm arch v[567] and still works on cpu 0. * for some reason it sometimes sets PsrBigend on cpu 1. * Ureg's tail was: * * typedef struct Ureg { * ⋯ * ulong type; /* of exception */ * ulong psr; * ulong pc; /* interrupted addr */ * } Ureg; */ RFE /* MOVM.IA.S.W (R13), [R15] */ #endif // SETEND(0) RFEV7W(13)