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