xref: /OK3568_Linux_fs/kernel/arch/arm/nwfpe/fpa11_cpdt.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun     NetWinder Floating Point Emulator
4*4882a593Smuzhiyun     (c) Rebel.com, 1998-1999
5*4882a593Smuzhiyun     (c) Philip Blundell, 1998, 2001
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun     Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun */
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun #include "fpa11.h"
12*4882a593Smuzhiyun #include "softfloat.h"
13*4882a593Smuzhiyun #include "fpopcode.h"
14*4882a593Smuzhiyun #include "fpmodule.h"
15*4882a593Smuzhiyun #include "fpmodule.inl"
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun #include <linux/uaccess.h>
18*4882a593Smuzhiyun 
loadSingle(const unsigned int Fn,const unsigned int __user * pMem)19*4882a593Smuzhiyun static inline void loadSingle(const unsigned int Fn, const unsigned int __user *pMem)
20*4882a593Smuzhiyun {
21*4882a593Smuzhiyun 	FPA11 *fpa11 = GET_FPA11();
22*4882a593Smuzhiyun 	fpa11->fType[Fn] = typeSingle;
23*4882a593Smuzhiyun 	get_user(fpa11->fpreg[Fn].fSingle, pMem);
24*4882a593Smuzhiyun }
25*4882a593Smuzhiyun 
loadDouble(const unsigned int Fn,const unsigned int __user * pMem)26*4882a593Smuzhiyun static inline void loadDouble(const unsigned int Fn, const unsigned int __user *pMem)
27*4882a593Smuzhiyun {
28*4882a593Smuzhiyun 	FPA11 *fpa11 = GET_FPA11();
29*4882a593Smuzhiyun 	unsigned int *p;
30*4882a593Smuzhiyun 	p = (unsigned int *) &fpa11->fpreg[Fn].fDouble;
31*4882a593Smuzhiyun 	fpa11->fType[Fn] = typeDouble;
32*4882a593Smuzhiyun #ifdef __ARMEB__
33*4882a593Smuzhiyun 	get_user(p[0], &pMem[0]);	/* sign & exponent */
34*4882a593Smuzhiyun 	get_user(p[1], &pMem[1]);
35*4882a593Smuzhiyun #else
36*4882a593Smuzhiyun 	get_user(p[0], &pMem[1]);
37*4882a593Smuzhiyun 	get_user(p[1], &pMem[0]);	/* sign & exponent */
38*4882a593Smuzhiyun #endif
39*4882a593Smuzhiyun }
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun #ifdef CONFIG_FPE_NWFPE_XP
loadExtended(const unsigned int Fn,const unsigned int __user * pMem)42*4882a593Smuzhiyun static inline void loadExtended(const unsigned int Fn, const unsigned int __user *pMem)
43*4882a593Smuzhiyun {
44*4882a593Smuzhiyun 	FPA11 *fpa11 = GET_FPA11();
45*4882a593Smuzhiyun 	unsigned int *p;
46*4882a593Smuzhiyun 	p = (unsigned int *) &fpa11->fpreg[Fn].fExtended;
47*4882a593Smuzhiyun 	fpa11->fType[Fn] = typeExtended;
48*4882a593Smuzhiyun 	get_user(p[0], &pMem[0]);	/* sign & exponent */
49*4882a593Smuzhiyun #ifdef __ARMEB__
50*4882a593Smuzhiyun 	get_user(p[1], &pMem[1]);	/* ms bits */
51*4882a593Smuzhiyun 	get_user(p[2], &pMem[2]);	/* ls bits */
52*4882a593Smuzhiyun #else
53*4882a593Smuzhiyun 	get_user(p[1], &pMem[2]);	/* ls bits */
54*4882a593Smuzhiyun 	get_user(p[2], &pMem[1]);	/* ms bits */
55*4882a593Smuzhiyun #endif
56*4882a593Smuzhiyun }
57*4882a593Smuzhiyun #endif
58*4882a593Smuzhiyun 
loadMultiple(const unsigned int Fn,const unsigned int __user * pMem)59*4882a593Smuzhiyun static inline void loadMultiple(const unsigned int Fn, const unsigned int __user *pMem)
60*4882a593Smuzhiyun {
61*4882a593Smuzhiyun 	FPA11 *fpa11 = GET_FPA11();
62*4882a593Smuzhiyun 	register unsigned int *p;
63*4882a593Smuzhiyun 	unsigned long x;
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun 	p = (unsigned int *) &(fpa11->fpreg[Fn]);
66*4882a593Smuzhiyun 	get_user(x, &pMem[0]);
67*4882a593Smuzhiyun 	fpa11->fType[Fn] = (x >> 14) & 0x00000003;
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun 	switch (fpa11->fType[Fn]) {
70*4882a593Smuzhiyun 	case typeSingle:
71*4882a593Smuzhiyun 	case typeDouble:
72*4882a593Smuzhiyun 		{
73*4882a593Smuzhiyun 			get_user(p[0], &pMem[2]);	/* Single */
74*4882a593Smuzhiyun 			get_user(p[1], &pMem[1]);	/* double msw */
75*4882a593Smuzhiyun 			p[2] = 0;			/* empty */
76*4882a593Smuzhiyun 		}
77*4882a593Smuzhiyun 		break;
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun #ifdef CONFIG_FPE_NWFPE_XP
80*4882a593Smuzhiyun 	case typeExtended:
81*4882a593Smuzhiyun 		{
82*4882a593Smuzhiyun 			get_user(p[1], &pMem[2]);
83*4882a593Smuzhiyun 			get_user(p[2], &pMem[1]);	/* msw */
84*4882a593Smuzhiyun 			p[0] = (x & 0x80003fff);
85*4882a593Smuzhiyun 		}
86*4882a593Smuzhiyun 		break;
87*4882a593Smuzhiyun #endif
88*4882a593Smuzhiyun 	}
89*4882a593Smuzhiyun }
90*4882a593Smuzhiyun 
storeSingle(struct roundingData * roundData,const unsigned int Fn,unsigned int __user * pMem)91*4882a593Smuzhiyun static inline void storeSingle(struct roundingData *roundData, const unsigned int Fn, unsigned int __user *pMem)
92*4882a593Smuzhiyun {
93*4882a593Smuzhiyun 	FPA11 *fpa11 = GET_FPA11();
94*4882a593Smuzhiyun 	union {
95*4882a593Smuzhiyun 		float32 f;
96*4882a593Smuzhiyun 		unsigned int i[1];
97*4882a593Smuzhiyun 	} val;
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun 	switch (fpa11->fType[Fn]) {
100*4882a593Smuzhiyun 	case typeDouble:
101*4882a593Smuzhiyun 		val.f = float64_to_float32(roundData, fpa11->fpreg[Fn].fDouble);
102*4882a593Smuzhiyun 		break;
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun #ifdef CONFIG_FPE_NWFPE_XP
105*4882a593Smuzhiyun 	case typeExtended:
106*4882a593Smuzhiyun 		val.f = floatx80_to_float32(roundData, fpa11->fpreg[Fn].fExtended);
107*4882a593Smuzhiyun 		break;
108*4882a593Smuzhiyun #endif
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun 	default:
111*4882a593Smuzhiyun 		val.f = fpa11->fpreg[Fn].fSingle;
112*4882a593Smuzhiyun 	}
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun 	put_user(val.i[0], pMem);
115*4882a593Smuzhiyun }
116*4882a593Smuzhiyun 
storeDouble(struct roundingData * roundData,const unsigned int Fn,unsigned int __user * pMem)117*4882a593Smuzhiyun static inline void storeDouble(struct roundingData *roundData, const unsigned int Fn, unsigned int __user *pMem)
118*4882a593Smuzhiyun {
119*4882a593Smuzhiyun 	FPA11 *fpa11 = GET_FPA11();
120*4882a593Smuzhiyun 	union {
121*4882a593Smuzhiyun 		float64 f;
122*4882a593Smuzhiyun 		unsigned int i[2];
123*4882a593Smuzhiyun 	} val;
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun 	switch (fpa11->fType[Fn]) {
126*4882a593Smuzhiyun 	case typeSingle:
127*4882a593Smuzhiyun 		val.f = float32_to_float64(fpa11->fpreg[Fn].fSingle);
128*4882a593Smuzhiyun 		break;
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun #ifdef CONFIG_FPE_NWFPE_XP
131*4882a593Smuzhiyun 	case typeExtended:
132*4882a593Smuzhiyun 		val.f = floatx80_to_float64(roundData, fpa11->fpreg[Fn].fExtended);
133*4882a593Smuzhiyun 		break;
134*4882a593Smuzhiyun #endif
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun 	default:
137*4882a593Smuzhiyun 		val.f = fpa11->fpreg[Fn].fDouble;
138*4882a593Smuzhiyun 	}
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun #ifdef __ARMEB__
141*4882a593Smuzhiyun 	put_user(val.i[0], &pMem[0]);	/* msw */
142*4882a593Smuzhiyun 	put_user(val.i[1], &pMem[1]);	/* lsw */
143*4882a593Smuzhiyun #else
144*4882a593Smuzhiyun 	put_user(val.i[1], &pMem[0]);	/* msw */
145*4882a593Smuzhiyun 	put_user(val.i[0], &pMem[1]);	/* lsw */
146*4882a593Smuzhiyun #endif
147*4882a593Smuzhiyun }
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun #ifdef CONFIG_FPE_NWFPE_XP
storeExtended(const unsigned int Fn,unsigned int __user * pMem)150*4882a593Smuzhiyun static inline void storeExtended(const unsigned int Fn, unsigned int __user *pMem)
151*4882a593Smuzhiyun {
152*4882a593Smuzhiyun 	FPA11 *fpa11 = GET_FPA11();
153*4882a593Smuzhiyun 	union {
154*4882a593Smuzhiyun 		floatx80 f;
155*4882a593Smuzhiyun 		unsigned int i[3];
156*4882a593Smuzhiyun 	} val;
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun 	switch (fpa11->fType[Fn]) {
159*4882a593Smuzhiyun 	case typeSingle:
160*4882a593Smuzhiyun 		val.f = float32_to_floatx80(fpa11->fpreg[Fn].fSingle);
161*4882a593Smuzhiyun 		break;
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun 	case typeDouble:
164*4882a593Smuzhiyun 		val.f = float64_to_floatx80(fpa11->fpreg[Fn].fDouble);
165*4882a593Smuzhiyun 		break;
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun 	default:
168*4882a593Smuzhiyun 		val.f = fpa11->fpreg[Fn].fExtended;
169*4882a593Smuzhiyun 	}
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun 	put_user(val.i[0], &pMem[0]);	/* sign & exp */
172*4882a593Smuzhiyun #ifdef __ARMEB__
173*4882a593Smuzhiyun 	put_user(val.i[1], &pMem[1]);	/* msw */
174*4882a593Smuzhiyun 	put_user(val.i[2], &pMem[2]);
175*4882a593Smuzhiyun #else
176*4882a593Smuzhiyun 	put_user(val.i[1], &pMem[2]);
177*4882a593Smuzhiyun 	put_user(val.i[2], &pMem[1]);	/* msw */
178*4882a593Smuzhiyun #endif
179*4882a593Smuzhiyun }
180*4882a593Smuzhiyun #endif
181*4882a593Smuzhiyun 
storeMultiple(const unsigned int Fn,unsigned int __user * pMem)182*4882a593Smuzhiyun static inline void storeMultiple(const unsigned int Fn, unsigned int __user *pMem)
183*4882a593Smuzhiyun {
184*4882a593Smuzhiyun 	FPA11 *fpa11 = GET_FPA11();
185*4882a593Smuzhiyun 	register unsigned int nType, *p;
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun 	p = (unsigned int *) &(fpa11->fpreg[Fn]);
188*4882a593Smuzhiyun 	nType = fpa11->fType[Fn];
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun 	switch (nType) {
191*4882a593Smuzhiyun 	case typeSingle:
192*4882a593Smuzhiyun 	case typeDouble:
193*4882a593Smuzhiyun 		{
194*4882a593Smuzhiyun 			put_user(p[0], &pMem[2]);	/* single */
195*4882a593Smuzhiyun 			put_user(p[1], &pMem[1]);	/* double msw */
196*4882a593Smuzhiyun 			put_user(nType << 14, &pMem[0]);
197*4882a593Smuzhiyun 		}
198*4882a593Smuzhiyun 		break;
199*4882a593Smuzhiyun 
200*4882a593Smuzhiyun #ifdef CONFIG_FPE_NWFPE_XP
201*4882a593Smuzhiyun 	case typeExtended:
202*4882a593Smuzhiyun 		{
203*4882a593Smuzhiyun 			put_user(p[2], &pMem[1]);	/* msw */
204*4882a593Smuzhiyun 			put_user(p[1], &pMem[2]);
205*4882a593Smuzhiyun 			put_user((p[0] & 0x80003fff) | (nType << 14), &pMem[0]);
206*4882a593Smuzhiyun 		}
207*4882a593Smuzhiyun 		break;
208*4882a593Smuzhiyun #endif
209*4882a593Smuzhiyun 	}
210*4882a593Smuzhiyun }
211*4882a593Smuzhiyun 
PerformLDF(const unsigned int opcode)212*4882a593Smuzhiyun unsigned int PerformLDF(const unsigned int opcode)
213*4882a593Smuzhiyun {
214*4882a593Smuzhiyun 	unsigned int __user *pBase, *pAddress, *pFinal;
215*4882a593Smuzhiyun 	unsigned int nRc = 1, write_back = WRITE_BACK(opcode);
216*4882a593Smuzhiyun 
217*4882a593Smuzhiyun 	pBase = (unsigned int __user *) readRegister(getRn(opcode));
218*4882a593Smuzhiyun 	if (REG_PC == getRn(opcode)) {
219*4882a593Smuzhiyun 		pBase += 2;
220*4882a593Smuzhiyun 		write_back = 0;
221*4882a593Smuzhiyun 	}
222*4882a593Smuzhiyun 
223*4882a593Smuzhiyun 	pFinal = pBase;
224*4882a593Smuzhiyun 	if (BIT_UP_SET(opcode))
225*4882a593Smuzhiyun 		pFinal += getOffset(opcode);
226*4882a593Smuzhiyun 	else
227*4882a593Smuzhiyun 		pFinal -= getOffset(opcode);
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun 	if (PREINDEXED(opcode))
230*4882a593Smuzhiyun 		pAddress = pFinal;
231*4882a593Smuzhiyun 	else
232*4882a593Smuzhiyun 		pAddress = pBase;
233*4882a593Smuzhiyun 
234*4882a593Smuzhiyun 	switch (opcode & MASK_TRANSFER_LENGTH) {
235*4882a593Smuzhiyun 	case TRANSFER_SINGLE:
236*4882a593Smuzhiyun 		loadSingle(getFd(opcode), pAddress);
237*4882a593Smuzhiyun 		break;
238*4882a593Smuzhiyun 	case TRANSFER_DOUBLE:
239*4882a593Smuzhiyun 		loadDouble(getFd(opcode), pAddress);
240*4882a593Smuzhiyun 		break;
241*4882a593Smuzhiyun #ifdef CONFIG_FPE_NWFPE_XP
242*4882a593Smuzhiyun 	case TRANSFER_EXTENDED:
243*4882a593Smuzhiyun 		loadExtended(getFd(opcode), pAddress);
244*4882a593Smuzhiyun 		break;
245*4882a593Smuzhiyun #endif
246*4882a593Smuzhiyun 	default:
247*4882a593Smuzhiyun 		nRc = 0;
248*4882a593Smuzhiyun 	}
249*4882a593Smuzhiyun 
250*4882a593Smuzhiyun 	if (write_back)
251*4882a593Smuzhiyun 		writeRegister(getRn(opcode), (unsigned long) pFinal);
252*4882a593Smuzhiyun 	return nRc;
253*4882a593Smuzhiyun }
254*4882a593Smuzhiyun 
PerformSTF(const unsigned int opcode)255*4882a593Smuzhiyun unsigned int PerformSTF(const unsigned int opcode)
256*4882a593Smuzhiyun {
257*4882a593Smuzhiyun 	unsigned int __user *pBase, *pAddress, *pFinal;
258*4882a593Smuzhiyun 	unsigned int nRc = 1, write_back = WRITE_BACK(opcode);
259*4882a593Smuzhiyun 	struct roundingData roundData;
260*4882a593Smuzhiyun 
261*4882a593Smuzhiyun 	roundData.mode = SetRoundingMode(opcode);
262*4882a593Smuzhiyun 	roundData.precision = SetRoundingPrecision(opcode);
263*4882a593Smuzhiyun 	roundData.exception = 0;
264*4882a593Smuzhiyun 
265*4882a593Smuzhiyun 	pBase = (unsigned int __user *) readRegister(getRn(opcode));
266*4882a593Smuzhiyun 	if (REG_PC == getRn(opcode)) {
267*4882a593Smuzhiyun 		pBase += 2;
268*4882a593Smuzhiyun 		write_back = 0;
269*4882a593Smuzhiyun 	}
270*4882a593Smuzhiyun 
271*4882a593Smuzhiyun 	pFinal = pBase;
272*4882a593Smuzhiyun 	if (BIT_UP_SET(opcode))
273*4882a593Smuzhiyun 		pFinal += getOffset(opcode);
274*4882a593Smuzhiyun 	else
275*4882a593Smuzhiyun 		pFinal -= getOffset(opcode);
276*4882a593Smuzhiyun 
277*4882a593Smuzhiyun 	if (PREINDEXED(opcode))
278*4882a593Smuzhiyun 		pAddress = pFinal;
279*4882a593Smuzhiyun 	else
280*4882a593Smuzhiyun 		pAddress = pBase;
281*4882a593Smuzhiyun 
282*4882a593Smuzhiyun 	switch (opcode & MASK_TRANSFER_LENGTH) {
283*4882a593Smuzhiyun 	case TRANSFER_SINGLE:
284*4882a593Smuzhiyun 		storeSingle(&roundData, getFd(opcode), pAddress);
285*4882a593Smuzhiyun 		break;
286*4882a593Smuzhiyun 	case TRANSFER_DOUBLE:
287*4882a593Smuzhiyun 		storeDouble(&roundData, getFd(opcode), pAddress);
288*4882a593Smuzhiyun 		break;
289*4882a593Smuzhiyun #ifdef CONFIG_FPE_NWFPE_XP
290*4882a593Smuzhiyun 	case TRANSFER_EXTENDED:
291*4882a593Smuzhiyun 		storeExtended(getFd(opcode), pAddress);
292*4882a593Smuzhiyun 		break;
293*4882a593Smuzhiyun #endif
294*4882a593Smuzhiyun 	default:
295*4882a593Smuzhiyun 		nRc = 0;
296*4882a593Smuzhiyun 	}
297*4882a593Smuzhiyun 
298*4882a593Smuzhiyun 	if (roundData.exception)
299*4882a593Smuzhiyun 		float_raise(roundData.exception);
300*4882a593Smuzhiyun 
301*4882a593Smuzhiyun 	if (write_back)
302*4882a593Smuzhiyun 		writeRegister(getRn(opcode), (unsigned long) pFinal);
303*4882a593Smuzhiyun 	return nRc;
304*4882a593Smuzhiyun }
305*4882a593Smuzhiyun 
PerformLFM(const unsigned int opcode)306*4882a593Smuzhiyun unsigned int PerformLFM(const unsigned int opcode)
307*4882a593Smuzhiyun {
308*4882a593Smuzhiyun 	unsigned int __user *pBase, *pAddress, *pFinal;
309*4882a593Smuzhiyun 	unsigned int i, Fd, write_back = WRITE_BACK(opcode);
310*4882a593Smuzhiyun 
311*4882a593Smuzhiyun 	pBase = (unsigned int __user *) readRegister(getRn(opcode));
312*4882a593Smuzhiyun 	if (REG_PC == getRn(opcode)) {
313*4882a593Smuzhiyun 		pBase += 2;
314*4882a593Smuzhiyun 		write_back = 0;
315*4882a593Smuzhiyun 	}
316*4882a593Smuzhiyun 
317*4882a593Smuzhiyun 	pFinal = pBase;
318*4882a593Smuzhiyun 	if (BIT_UP_SET(opcode))
319*4882a593Smuzhiyun 		pFinal += getOffset(opcode);
320*4882a593Smuzhiyun 	else
321*4882a593Smuzhiyun 		pFinal -= getOffset(opcode);
322*4882a593Smuzhiyun 
323*4882a593Smuzhiyun 	if (PREINDEXED(opcode))
324*4882a593Smuzhiyun 		pAddress = pFinal;
325*4882a593Smuzhiyun 	else
326*4882a593Smuzhiyun 		pAddress = pBase;
327*4882a593Smuzhiyun 
328*4882a593Smuzhiyun 	Fd = getFd(opcode);
329*4882a593Smuzhiyun 	for (i = getRegisterCount(opcode); i > 0; i--) {
330*4882a593Smuzhiyun 		loadMultiple(Fd, pAddress);
331*4882a593Smuzhiyun 		pAddress += 3;
332*4882a593Smuzhiyun 		Fd++;
333*4882a593Smuzhiyun 		if (Fd == 8)
334*4882a593Smuzhiyun 			Fd = 0;
335*4882a593Smuzhiyun 	}
336*4882a593Smuzhiyun 
337*4882a593Smuzhiyun 	if (write_back)
338*4882a593Smuzhiyun 		writeRegister(getRn(opcode), (unsigned long) pFinal);
339*4882a593Smuzhiyun 	return 1;
340*4882a593Smuzhiyun }
341*4882a593Smuzhiyun 
PerformSFM(const unsigned int opcode)342*4882a593Smuzhiyun unsigned int PerformSFM(const unsigned int opcode)
343*4882a593Smuzhiyun {
344*4882a593Smuzhiyun 	unsigned int __user *pBase, *pAddress, *pFinal;
345*4882a593Smuzhiyun 	unsigned int i, Fd, write_back = WRITE_BACK(opcode);
346*4882a593Smuzhiyun 
347*4882a593Smuzhiyun 	pBase = (unsigned int __user *) readRegister(getRn(opcode));
348*4882a593Smuzhiyun 	if (REG_PC == getRn(opcode)) {
349*4882a593Smuzhiyun 		pBase += 2;
350*4882a593Smuzhiyun 		write_back = 0;
351*4882a593Smuzhiyun 	}
352*4882a593Smuzhiyun 
353*4882a593Smuzhiyun 	pFinal = pBase;
354*4882a593Smuzhiyun 	if (BIT_UP_SET(opcode))
355*4882a593Smuzhiyun 		pFinal += getOffset(opcode);
356*4882a593Smuzhiyun 	else
357*4882a593Smuzhiyun 		pFinal -= getOffset(opcode);
358*4882a593Smuzhiyun 
359*4882a593Smuzhiyun 	if (PREINDEXED(opcode))
360*4882a593Smuzhiyun 		pAddress = pFinal;
361*4882a593Smuzhiyun 	else
362*4882a593Smuzhiyun 		pAddress = pBase;
363*4882a593Smuzhiyun 
364*4882a593Smuzhiyun 	Fd = getFd(opcode);
365*4882a593Smuzhiyun 	for (i = getRegisterCount(opcode); i > 0; i--) {
366*4882a593Smuzhiyun 		storeMultiple(Fd, pAddress);
367*4882a593Smuzhiyun 		pAddress += 3;
368*4882a593Smuzhiyun 		Fd++;
369*4882a593Smuzhiyun 		if (Fd == 8)
370*4882a593Smuzhiyun 			Fd = 0;
371*4882a593Smuzhiyun 	}
372*4882a593Smuzhiyun 
373*4882a593Smuzhiyun 	if (write_back)
374*4882a593Smuzhiyun 		writeRegister(getRn(opcode), (unsigned long) pFinal);
375*4882a593Smuzhiyun 	return 1;
376*4882a593Smuzhiyun }
377*4882a593Smuzhiyun 
EmulateCPDT(const unsigned int opcode)378*4882a593Smuzhiyun unsigned int EmulateCPDT(const unsigned int opcode)
379*4882a593Smuzhiyun {
380*4882a593Smuzhiyun 	unsigned int nRc = 0;
381*4882a593Smuzhiyun 
382*4882a593Smuzhiyun 	if (LDF_OP(opcode)) {
383*4882a593Smuzhiyun 		nRc = PerformLDF(opcode);
384*4882a593Smuzhiyun 	} else if (LFM_OP(opcode)) {
385*4882a593Smuzhiyun 		nRc = PerformLFM(opcode);
386*4882a593Smuzhiyun 	} else if (STF_OP(opcode)) {
387*4882a593Smuzhiyun 		nRc = PerformSTF(opcode);
388*4882a593Smuzhiyun 	} else if (SFM_OP(opcode)) {
389*4882a593Smuzhiyun 		nRc = PerformSFM(opcode);
390*4882a593Smuzhiyun 	} else {
391*4882a593Smuzhiyun 		nRc = 0;
392*4882a593Smuzhiyun 	}
393*4882a593Smuzhiyun 
394*4882a593Smuzhiyun 	return nRc;
395*4882a593Smuzhiyun }
396