Linux Audio

Check our new training course

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