1/* 2 * return from user-mode exception. 3 * expects new SPSR in R0. R13 must point to ureg->type. 4 */ 5_rfue: 6TEXT rfue(SB), 1, $-4 7// CPSID 8// BIC $PsrMbz, R0 /* force little-endian upon return */ 9 MOVW R0, SPSR /* ... */ 10 11 /* 12 * order on stack is type, psr, pc, but RFEV7 needs pc, psr. 13 * step on type and previous word to hold temporary values. 14 * we could instead change the order in which psr & pc are pushed. 15 */ 16 MOVW 4(R13), R1 /* psr */ 17 MOVW 8(R13), R2 /* pc */ 18 MOVW R2, 4(R13) /* pc */ 19 MOVW R1, 8(R13) /* psr */ 20 21 MOVM.DB.S (R13), [R0-R14] /* restore user registers */ 22 ADD $4, R13 /* pop type, sp -> pc */ 23 24#ifdef OLDWAY 25 ADD $(2*4), R13 /* pop past ureg->{type+psr} to pc */ 26 /* 27 * this used to work on arm arch v[567] and still works on cpu 0. 28 * for some reason it sometimes sets PsrBigend on cpu 1. 29 * Ureg's tail was: 30 * 31 * typedef struct Ureg { 32 * ⋯ 33 * ulong type; /* of exception */ 34 * ulong psr; 35 * ulong pc; /* interrupted addr */ 36 * } Ureg; 37 */ 38 RFE /* MOVM.IA.S.W (R13), [R15] */ 39#endif 40// SETEND(0) 41 RFEV7W(13) 42