1# Blackfin testcase for having RETI LSB set correctly when self nested
2# mach: bfin
3# sim: --environment operating
4
5#include "test.h"
6	.include "testutils.inc"
7
8	start
9
10	# Set our handler
11	imm32 P5, EVT11;
12	loadsym R1, _ivg11;
13	[P5] = R1;
14	loadsym R1, _fail_lvl;
15	[P5 + 4] = R1;	/* IVG12 */
16	[P5 + 12] = R1;	/* IVG14 */
17	loadsym R1, _ivg13;
18	[P5 + 8] = R1;
19
20	# Enable self nesting
21	R2 = SYSCFG;
22	BITSET (R2, 2);
23	SYSCFG = R2;
24	CSYNC;
25
26	# Enable IVG11/IVG13/IVG14 but not IVG12
27	cli R3;
28	BITSET (R3, 11);
29	BITCLR (R3, 12);
30	BITSET (R3, 13);
31	BITSET (R3, 14);
32	sti R3;
33
34	# Counter to keep track of nesting depth
35	R7 = 0;
36
37	# Lower ourselves to IVG11
38	loadsym R4, _fail_lvl;
39	RETI = R4;
40	RAISE 11;
41	RAISE 12;
42	RAISE 13;
43	RAISE 14;
44	RTI;
45
46# This IVG makes sure RETI LSB is set correctly on transition in (RAISE)
47_ivg11:
48	R0 = RETI;
49
50	# Make sure we are indeed at IVG11
51	imm32 P0, IPEND;
52	R1 = [P0];
53	CC = BITTST (R1, 11);
54	IF !CC JUMP _fail_lvl;
55
56	# Make sure LSB of RETI is set only on first pass
57	CC = ! BITTST (R0, 0);
58	R1 = CC;
59	CC = R7 == 0;
60	R2 = CC;
61	CC = R1 == R2;
62	IF !CC JUMP _fail_lvl;
63
64	# Nest ourselves a few times
65	R6 = 3;
66	CC = R7 < R6;
67	IF !CC JUMP 1f;
68	[--sp] = RETI;
69	R7 += 1;
70	RAISE 11;
71	MNOP;
72	JUMP _fail_lvl;
73
74	# Move down to IVG13 for next test
751:	loadsym R4, _fail_lvl;
76	RETI = R4;
77	RTI;
78
79# This IVG makes sure RETI LSB is respected on transition out (RTI)
80_ivg13:
81	R0 = RETI;
82
83	# Make sure we are indeed at IVG13
84	imm32 P0, IPEND;
85	R1 = [P0];
86	CC = BITTST (R1, 13);
87	IF !CC JUMP _fail_lvl;
88
89	# RETI LSB should be set when re-entering IVG13
90	CC = ! BITTST (R0, 0);
91	R1 = CC;
92	CC = R7 == R6;
93	R2 = CC;
94	CC = R1 == R2;
95	IF !CC JUMP _fail_lvl;
96
97	# Should get here only after a few IVG11 tests
98	CC = R7 < R6;
99	IF CC JUMP _fail_lvl;
100
101	# Make sure IVG13 isn't pending
102	imm32 P0, ILAT;
103	R1 = [P0];
104	CC = BITTST (R1, 13);
105	IF CC JUMP _fail_lvl;
106
107	# Manually set RETI to with LSB set so we return there
108	R5 = R6;
109	R5 += 3;
110	CC = R7 < R5;
111	IF !CC JUMP 1f;
112	loadsym R1, _ivg13;
113	BITSET (R1, 0);
114	RETI = R1;
115	R7 += 1;
116	RTI;
117
118	# All done!
1191:	dbg_pass
120
121_fail_lvl:
122	dbg_fail;
123