1# Blackfin testcase for push/pop multiples instructions
2# mach: bfin
3
4	.include "testutils.inc"
5
6	# Tests follow the pattern:
7	#  - do the push multiple
8	#  - write a garbage value to all registers pushed
9	#  - do the pop multiple
10	#  - check all registers popped against known values
11
12	start
13
14	# Repeat the same operation multiple times, so this:
15	#	do_x moo, R, 1
16	# becomes this:
17	#	moo R1, 0x11111111
18	#	moo R0, 0x00000000
19	.macro _do_x func:req, reg:req, max:req, x:req
20	.ifle (\max - \x)
21	\func \reg\()\x, 0x\x\x\x\x\x\x\x\x
22	.endif
23	.endm
24	.macro do_x func:req, reg:req, max:req
25	.ifc \reg, R
26	_do_x \func, \reg, \max, 7
27	_do_x \func, \reg, \max, 6
28	.endif
29	_do_x \func, \reg, \max, 5
30	_do_x \func, \reg, \max, 4
31	_do_x \func, \reg, \max, 3
32	_do_x \func, \reg, \max, 2
33	_do_x \func, \reg, \max, 1
34	_do_x \func, \reg, \max, 0
35	.endm
36
37	# Keep the garbage value in I0
38	.macro loadi reg:req, val:req
39	\reg = I0;
40	.endm
41	imm32 I0, 0xAABCDEFF
42
43	#
44	# Test push/pop multiples with (R7:x) syntax
45	#
46
47	_push_r_tests:
48
49	# initialize all Rx regs with a known value
50	do_x imm32, R, 0
51
52	.macro checkr tochk:req, val:req
53	P0 = \tochk;
54	imm32 P1, \val
55	CC = P0 == P1;
56	IF !CC JUMP 8f;
57	.endm
58
59	.macro pushr maxr:req
60	_push_r\maxr:
61	[--SP] = (R7:\maxr);
62	do_x loadi, R, \maxr
63	(R7:\maxr) = [SP++];
64	do_x checkr, R, \maxr
65	# need to do a long jump to avoid PCREL issues
66	jump 9f;
67	8: jump.l 1f;
68	9:
69	.endm
70
71	pushr 7
72	pushr 6
73	pushr 5
74	pushr 4
75	pushr 3
76	pushr 2
77	pushr 1
78	pushr 0
79
80	#
81	# Test push/pop multiples with (P5:x) syntax
82	#
83
84	_push_p_tests:
85
86	# initialize all Px regs with a known value
87	do_x imm32, P, 0
88
89	.macro checkp tochk:req, val:req
90	R0 = \tochk;
91	imm32 R1, \val
92	CC = R0 == R1;
93	IF !CC JUMP 8f;
94	.endm
95
96	.macro pushp maxp:req
97	_push_p\maxp:
98	[--SP] = (P5:\maxp);
99	do_x loadi, P, \maxp
100	(P5:\maxp) = [SP++];
101	do_x checkp, P, \maxp
102	# need to do a long jump to avoid PCREL issues
103	jump 9f;
104	8: jump.l 1f;
105	9:
106	.endm
107
108	# checkp func clobbers R0/R1
109	L0 = R0;
110	L1 = R1;
111	pushp 5
112	pushp 4
113	pushp 3
114	pushp 2
115	pushp 1
116	pushp 0
117	R0 = L0;
118	R1 = L1;
119
120	#
121	# Test push/pop multiples with (R7:x, P5:x) syntax
122	#
123
124	_push_rp_tests:
125
126	.macro _pushrp maxr:req, maxp:req
127	_push_r\maxr\()_p\maxp:
128	[--SP] = (R7:\maxr, P5:\maxp);
129	do_x loadi, R, \maxr
130	do_x loadi, P, \maxp
131	(R7:\maxr, P5:\maxp) = [SP++];
132	# checkr func clobbers P0/P1
133	L0 = P0;
134	L1 = P1;
135	do_x checkr, R, \maxr
136	P1 = L1;
137	P0 = L0;
138	# checkp func clobbers R0/R1
139	L0 = R0;
140	L1 = R1;
141	do_x checkp, P, \maxp
142	R0 = L0;
143	R1 = L1;
144	# need to do a long jump to avoid PCREL issues
145	jump 9f;
146	8: jump.l 1f;
147	9:
148	.endm
149	.macro pushrp maxr:req
150	_pushrp \maxr, 5
151	_pushrp \maxr, 4
152	_pushrp \maxr, 3
153	_pushrp \maxr, 2
154	_pushrp \maxr, 1
155	_pushrp \maxr, 0
156	.endm
157
158	pushrp 7
159	pushrp 6
160	pushrp 5
161	pushrp 4
162	pushrp 3
163	pushrp 2
164	pushrp 1
165	pushrp 0
166
167	pass
1681:
169	fail
170