xref: /OK3568_Linux_fs/kernel/tools/testing/selftests/powerpc/include/instructions.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun #ifndef _SELFTESTS_POWERPC_INSTRUCTIONS_H
3*4882a593Smuzhiyun #define _SELFTESTS_POWERPC_INSTRUCTIONS_H
4*4882a593Smuzhiyun 
5*4882a593Smuzhiyun #include <stdio.h>
6*4882a593Smuzhiyun #include <stdlib.h>
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun /* This defines the "copy" instruction from Power ISA 3.0 Book II, section 4.4. */
9*4882a593Smuzhiyun #define __COPY(RA, RB, L) \
10*4882a593Smuzhiyun 	(0x7c00060c | (RA) << (31-15) | (RB) << (31-20) | (L) << (31-10))
11*4882a593Smuzhiyun #define COPY(RA, RB, L) \
12*4882a593Smuzhiyun 	.long __COPY((RA), (RB), (L))
13*4882a593Smuzhiyun 
copy(void * i)14*4882a593Smuzhiyun static inline void copy(void *i)
15*4882a593Smuzhiyun {
16*4882a593Smuzhiyun 	asm volatile(str(COPY(0, %0, 0))";"
17*4882a593Smuzhiyun 			:
18*4882a593Smuzhiyun 			: "b" (i)
19*4882a593Smuzhiyun 			: "memory"
20*4882a593Smuzhiyun 		    );
21*4882a593Smuzhiyun }
22*4882a593Smuzhiyun 
copy_first(void * i)23*4882a593Smuzhiyun static inline void copy_first(void *i)
24*4882a593Smuzhiyun {
25*4882a593Smuzhiyun 	asm volatile(str(COPY(0, %0, 1))";"
26*4882a593Smuzhiyun 			:
27*4882a593Smuzhiyun 			: "b" (i)
28*4882a593Smuzhiyun 			: "memory"
29*4882a593Smuzhiyun 		    );
30*4882a593Smuzhiyun }
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun /* This defines the "paste" instruction from Power ISA 3.0 Book II, section 4.4. */
33*4882a593Smuzhiyun #define __PASTE(RA, RB, L, RC) \
34*4882a593Smuzhiyun 	(0x7c00070c | (RA) << (31-15) | (RB) << (31-20) | (L) << (31-10) | (RC) << (31-31))
35*4882a593Smuzhiyun #define PASTE(RA, RB, L, RC) \
36*4882a593Smuzhiyun 	.long __PASTE((RA), (RB), (L), (RC))
37*4882a593Smuzhiyun 
paste(void * i)38*4882a593Smuzhiyun static inline int paste(void *i)
39*4882a593Smuzhiyun {
40*4882a593Smuzhiyun 	int cr;
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun 	asm volatile(str(PASTE(0, %1, 0, 0))";"
43*4882a593Smuzhiyun 			"mfcr %0;"
44*4882a593Smuzhiyun 			: "=r" (cr)
45*4882a593Smuzhiyun 			: "b" (i)
46*4882a593Smuzhiyun 			: "memory"
47*4882a593Smuzhiyun 		    );
48*4882a593Smuzhiyun 	return cr;
49*4882a593Smuzhiyun }
50*4882a593Smuzhiyun 
paste_last(void * i)51*4882a593Smuzhiyun static inline int paste_last(void *i)
52*4882a593Smuzhiyun {
53*4882a593Smuzhiyun 	int cr;
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun 	asm volatile(str(PASTE(0, %1, 1, 1))";"
56*4882a593Smuzhiyun 			"mfcr %0;"
57*4882a593Smuzhiyun 			: "=r" (cr)
58*4882a593Smuzhiyun 			: "b" (i)
59*4882a593Smuzhiyun 			: "memory"
60*4882a593Smuzhiyun 		    );
61*4882a593Smuzhiyun 	return cr;
62*4882a593Smuzhiyun }
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun #define PPC_INST_COPY                  __COPY(0, 0, 0)
65*4882a593Smuzhiyun #define PPC_INST_COPY_FIRST            __COPY(0, 0, 1)
66*4882a593Smuzhiyun #define PPC_INST_PASTE                 __PASTE(0, 0, 0, 0)
67*4882a593Smuzhiyun #define PPC_INST_PASTE_LAST            __PASTE(0, 0, 1, 1)
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun /* This defines the prefixed load/store instructions */
70*4882a593Smuzhiyun #ifdef __ASSEMBLY__
71*4882a593Smuzhiyun #  define stringify_in_c(...)	__VA_ARGS__
72*4882a593Smuzhiyun #else
73*4882a593Smuzhiyun #  define __stringify_in_c(...)	#__VA_ARGS__
74*4882a593Smuzhiyun #  define stringify_in_c(...)	__stringify_in_c(__VA_ARGS__) " "
75*4882a593Smuzhiyun #endif
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun #define __PPC_RA(a)	(((a) & 0x1f) << 16)
78*4882a593Smuzhiyun #define __PPC_RS(s)	(((s) & 0x1f) << 21)
79*4882a593Smuzhiyun #define __PPC_RT(t)	__PPC_RS(t)
80*4882a593Smuzhiyun #define __PPC_PREFIX_R(r)	(((r) & 0x1) << 20)
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun #define PPC_PREFIX_MLS			0x06000000
83*4882a593Smuzhiyun #define PPC_PREFIX_8LS			0x04000000
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun #define PPC_INST_LBZ			0x88000000
86*4882a593Smuzhiyun #define PPC_INST_LHZ			0xa0000000
87*4882a593Smuzhiyun #define PPC_INST_LHA			0xa8000000
88*4882a593Smuzhiyun #define PPC_INST_LWZ			0x80000000
89*4882a593Smuzhiyun #define PPC_INST_STB			0x98000000
90*4882a593Smuzhiyun #define PPC_INST_STH			0xb0000000
91*4882a593Smuzhiyun #define PPC_INST_STW			0x90000000
92*4882a593Smuzhiyun #define PPC_INST_STD			0xf8000000
93*4882a593Smuzhiyun #define PPC_INST_LFS			0xc0000000
94*4882a593Smuzhiyun #define PPC_INST_LFD			0xc8000000
95*4882a593Smuzhiyun #define PPC_INST_STFS			0xd0000000
96*4882a593Smuzhiyun #define PPC_INST_STFD			0xd8000000
97*4882a593Smuzhiyun 
98*4882a593Smuzhiyun #define PREFIX_MLS(instr, t, a, r, d)	stringify_in_c(.balign 64, , 4;)		\
99*4882a593Smuzhiyun 					stringify_in_c(.long PPC_PREFIX_MLS |		\
100*4882a593Smuzhiyun 						       __PPC_PREFIX_R(r) |		\
101*4882a593Smuzhiyun 						       (((d) >> 16) & 0x3ffff);)	\
102*4882a593Smuzhiyun 					stringify_in_c(.long (instr)  |			\
103*4882a593Smuzhiyun 						       __PPC_RT(t) |			\
104*4882a593Smuzhiyun 						       __PPC_RA(a) |			\
105*4882a593Smuzhiyun 						       ((d) & 0xffff);\n)
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun #define PREFIX_8LS(instr, t, a, r, d)	stringify_in_c(.balign 64, , 4;)		\
108*4882a593Smuzhiyun 					stringify_in_c(.long PPC_PREFIX_8LS |		\
109*4882a593Smuzhiyun 						       __PPC_PREFIX_R(r) |		\
110*4882a593Smuzhiyun 						       (((d) >> 16) & 0x3ffff);)	\
111*4882a593Smuzhiyun 					stringify_in_c(.long (instr)  |			\
112*4882a593Smuzhiyun 						       __PPC_RT(t) |			\
113*4882a593Smuzhiyun 						       __PPC_RA(a) |			\
114*4882a593Smuzhiyun 						       ((d) & 0xffff);\n)
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun /* Prefixed Integer Load/Store instructions */
117*4882a593Smuzhiyun #define PLBZ(t, a, r, d)		PREFIX_MLS(PPC_INST_LBZ, t, a, r, d)
118*4882a593Smuzhiyun #define PLHZ(t, a, r, d)		PREFIX_MLS(PPC_INST_LHZ, t, a, r, d)
119*4882a593Smuzhiyun #define PLHA(t, a, r, d)		PREFIX_MLS(PPC_INST_LHA, t, a, r, d)
120*4882a593Smuzhiyun #define PLWZ(t, a, r, d)		PREFIX_MLS(PPC_INST_LWZ, t, a, r, d)
121*4882a593Smuzhiyun #define PLWA(t, a, r, d)		PREFIX_8LS(0xa4000000, t, a, r, d)
122*4882a593Smuzhiyun #define PLD(t, a, r, d)			PREFIX_8LS(0xe4000000, t, a, r, d)
123*4882a593Smuzhiyun #define PLQ(t, a, r, d)			PREFIX_8LS(0xe0000000, t, a, r, d)
124*4882a593Smuzhiyun #define PSTB(s, a, r, d)		PREFIX_MLS(PPC_INST_STB, s, a, r, d)
125*4882a593Smuzhiyun #define PSTH(s, a, r, d)		PREFIX_MLS(PPC_INST_STH, s, a, r, d)
126*4882a593Smuzhiyun #define PSTW(s, a, r, d)		PREFIX_MLS(PPC_INST_STW, s, a, r, d)
127*4882a593Smuzhiyun #define PSTD(s, a, r, d)		PREFIX_8LS(0xf4000000, s, a, r, d)
128*4882a593Smuzhiyun #define PSTQ(s, a, r, d)		PREFIX_8LS(0xf0000000, s, a, r, d)
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun /* Prefixed Floating-Point Load/Store Instructions */
131*4882a593Smuzhiyun #define PLFS(frt, a, r, d)		PREFIX_MLS(PPC_INST_LFS, frt, a, r, d)
132*4882a593Smuzhiyun #define PLFD(frt, a, r, d)		PREFIX_MLS(PPC_INST_LFD, frt, a, r, d)
133*4882a593Smuzhiyun #define PSTFS(frs, a, r, d)		PREFIX_MLS(PPC_INST_STFS, frs, a, r, d)
134*4882a593Smuzhiyun #define PSTFD(frs, a, r, d)		PREFIX_MLS(PPC_INST_STFD, frs, a, r, d)
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun /* Prefixed VSX Load/Store Instructions */
137*4882a593Smuzhiyun #define PLXSD(vrt, a, r, d)		PREFIX_8LS(0xa8000000, vrt, a, r, d)
138*4882a593Smuzhiyun #define PLXSSP(vrt, a, r, d)		PREFIX_8LS(0xac000000, vrt, a, r, d)
139*4882a593Smuzhiyun #define PLXV0(s, a, r, d)		PREFIX_8LS(0xc8000000, s, a, r, d)
140*4882a593Smuzhiyun #define PLXV1(s, a, r, d)		PREFIX_8LS(0xcc000000, s, a, r, d)
141*4882a593Smuzhiyun #define PSTXSD(vrs, a, r, d)		PREFIX_8LS(0xb8000000, vrs, a, r, d)
142*4882a593Smuzhiyun #define PSTXSSP(vrs, a, r, d)		PREFIX_8LS(0xbc000000, vrs, a, r, d)
143*4882a593Smuzhiyun #define PSTXV0(s, a, r, d)		PREFIX_8LS(0xd8000000, s, a, r, d)
144*4882a593Smuzhiyun #define PSTXV1(s, a, r, d)		PREFIX_8LS(0xdc000000, s, a, r, d)
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun #endif /* _SELFTESTS_POWERPC_INSTRUCTIONS_H */
147