summaryrefslogtreecommitdiff
path: root/sys/src/9/teg2/notes/bug.rfe
blob: c9577a41078db73d7befed6fb87da65790c9ae8e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/*
 * 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)