Annotation of sys/arch/hppa/hppa/fpemu.S, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: fpemu.S,v 1.12 2004/06/02 18:31:14 mickey Exp $ */
2:
3: /*
4: * Copyright (c) 2000-2004 Michael Shalayeff
5: * All rights reserved.
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
15: *
16: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19: * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
20: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22: * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
25: * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26: * THE POSSIBILITY OF SUCH DAMAGE.
27: */
28:
29: #include <machine/asm.h>
30: #include <machine/cpu.h>
31: #include "assym.h"
32:
33: #define FPEMU_VERSION (1 << 11)
34:
35: #define FP_TABLE2(name,ep0,ep1,ep2,ep3) \
36: ldil L%$fpemu_tbl$name, t1 ! \
37: ldo R%$fpemu_tbl$name(t1), t1 ! \
38: ldwx,s r1(t1), t2 ! \
39: bv r0(t2) ! \
40: copy r0, ret0 ! \
41: .label $fpemu_tbl$name ! \
42: .import __CONCAT(__CONCAT(ep0,_),name), code ! \
43: .import __CONCAT(__CONCAT(ep1,_),name), code ! \
44: .import __CONCAT(__CONCAT(ep2,_),name), code ! \
45: .import __CONCAT(__CONCAT(ep3,_),name), code ! \
46: .word __CONCAT(__CONCAT(ep0,_),name), __CONCAT(__CONCAT(ep1,_),name), __CONCAT(__CONCAT(ep2,_),name), __CONCAT(__CONCAT(ep3,_),name)
47:
48: #define FP_TABLE3(name,ep0,ep1,ep2,ep3,ep4,ep5,ep6,ep7,ep8,ep9,epa,epb,epc,epd,epe,epf) \
49: ldil L%$fpemu_tbl$name, t1 ! \
50: ldo R%$fpemu_tbl$name(t1), t1 ! \
51: ldwx,s r1(t1), t2 ! \
52: bv r0(t2) ! \
53: nop ! \
54: .label $fpemu_tbl$name ! \
55: .import __CONCAT(__CONCAT(ep0,_),name), code ! \
56: .import __CONCAT(__CONCAT(ep1,_),name), code ! \
57: .import __CONCAT(__CONCAT(ep2,_),name), code ! \
58: .import __CONCAT(__CONCAT(ep3,_),name), code ! \
59: .import __CONCAT(__CONCAT(ep4,_),name), code ! \
60: .import __CONCAT(__CONCAT(ep5,_),name), code ! \
61: .import __CONCAT(__CONCAT(ep6,_),name), code ! \
62: .import __CONCAT(__CONCAT(ep7,_),name), code ! \
63: .import __CONCAT(__CONCAT(ep8,_),name), code ! \
64: .import __CONCAT(__CONCAT(ep9,_),name), code ! \
65: .import __CONCAT(__CONCAT(epa,_),name), code ! \
66: .import __CONCAT(__CONCAT(epb,_),name), code ! \
67: .import __CONCAT(__CONCAT(epc,_),name), code ! \
68: .import __CONCAT(__CONCAT(epd,_),name), code ! \
69: .import __CONCAT(__CONCAT(epe,_),name), code ! \
70: .import __CONCAT(__CONCAT(epf,_),name), code ! \
71: .word __CONCAT(__CONCAT(ep0,_),name), __CONCAT(__CONCAT(ep1,_),name), __CONCAT(__CONCAT(ep2,_),name), __CONCAT(__CONCAT(ep3,_),name), __CONCAT(__CONCAT(ep4,_),name), __CONCAT(__CONCAT(ep5,_),name), __CONCAT(__CONCAT(ep6,_),name), __CONCAT(__CONCAT(ep7,_),name), __CONCAT(__CONCAT(ep8,_),name), __CONCAT(__CONCAT(ep9,_),name), __CONCAT(__CONCAT(epa,_),name), __CONCAT(__CONCAT(epb,_),name), __CONCAT(__CONCAT(epc,_),name), __CONCAT(__CONCAT(epd,_),name), __CONCAT(__CONCAT(epe,_),name), __CONCAT(__CONCAT(epf,_),name)
72:
73: .text
74: /*
75: * fpu_emulate(iir,0,fpregs)
76: */
77: LEAF_ENTRY(fpu_emulate)
78:
79: copy arg0, t4
80: extru arg0, 18, 3, r31
81: extru arg0, 20, 2, r1
82: extru arg0, 22, 2, t3
83: subi,<> 1, t3, r0
84: extru arg0, 16, 2, r31
85:
86: /*
87: * theoreticaly we would need to determine the fpu instruction
88: * exception type (there could be 4 of those, but stick w/
89: * non-timex fpus for now.
90: */
91: extru,<> arg0, 10, 5, t1
92: ldi 32, t1 /* fpemu zero reg */
93: extru,<> arg0, 31, 5, t2
94: b,n $fpemu_nzt
95: nop
96: /*comib,=,n 2, t3, $fpemu_exit*/
97: nop
98: $fpemu_nzt
99: /*
100: * arg0 -- source register (address)
101: * arg1 -- fpregs context
102: * arg2 -- target register (address)
103: * arg3 -- fpregs context
104: * t3 -- class
105: * r31 -- subop
106: * r1 -- format specifier
107: * (t4 -- copy of arg0, ie iir)
108: */
109: copy arg2, arg3
110: copy arg2, arg1
111: sh3add t1, arg2, arg0
112: sh3add t2, arg2, arg2
113: stw r0, 32*8+0(arg1) /* make sure zero reg is zero */
114: stw r0, 32*8+4(arg1)
115:
116: extru,= t4, 24, 1, r0 /* adjust for the L in source */
117: addi 4, arg0, arg0
118:
119: comib,=,n 2, t3, $fpemu0c_2
120: nop
121:
122: extru,= t4, 24, 1, r0 /* adjust for the L in target */
123: addi 4, arg2, arg2
124:
125: comib,=,n 0, t3, $fpemu0c_0
126: comib,=,n 1, t3, $fpemu0c_1
127: comib,=,n 3, t3, $fpemu0c_3
128:
129: $fpemu0c_0
130: comib,=,n 2, r1, $fpemu_exit
131:
132: comib,=,n 0, r31, $fpemu0c_0_0
133: comib,=,n 1, r31, $fpemu_exit
134: comib,=,n 2, r31, $fpemu0c_0_2
135: comib,=,n 3, r31, $fpemu0c_0_3
136: comib,=,n 4, r31, $fpemu0c_0_4
137: comib,=,n 5, r31, $fpemu0c_0_5
138: comib,=,n 6, r31, $fpemu_exit
139: comib,=,n 7, r31, $fpemu_exit
140:
141: $fpemu0c_0_0
142: ldi FPEMU_VERSION, t4
143: stw t4, 0(arg3)
144: bv 0(rp)
145: copy r0, ret0
146:
147: $fpemu0c_0_2 /* fcpy */
148: subi 3, r1, r1
149: ldw 0*4(arg0), t1
150: ldw 1*4(arg0), t2
151: ldw 2*4(arg0), t3
152: blr,n r1, r0
153: ldw 3*4(arg0), t4
154: stw t3, 2*4(arg2)
155: stw t4, 3*4(arg2)
156: nop
157: nop
158: nop
159: stw t2, 1*4(arg2)
160: stw t1, 0*4(arg2)
161: bv 0(rp)
162: copy r0, ret0
163:
164: $fpemu0c_0_3 /* fabs */
165: subi 3, r1, r1
166: ldw 0*4(arg0), t1
167: ldw 1*4(arg0), t2
168: ldw 2*4(arg0), t3
169: ldw 3*4(arg0), t4
170: blr,n r1, r0
171: depi 0, 0, 1, t1
172: stw t3, 2*4(arg2)
173: stw t4, 3*4(arg2)
174: nop
175: nop
176: nop
177: stw t2, 1*4(arg2)
178: stw t1, 0*4(arg2)
179: bv 0(rp)
180: copy r0, ret0
181:
182: $fpemu0c_0_4 /* fsqrt */
183: /* quad not implemented */
184: FP_TABLE2(fsqrt,sgl,dbl,invalid,invalid)
185:
186: $fpemu0c_0_5 /* frnd */
187: /* quad not implemented */
188: FP_TABLE2(frnd,sgl,dbl,invalid,quad)
189:
190: $fpemu0c_1
191: extru t4, 20, 4, r1
192: comib,=,n 0, r31, $fpemu0c_1_0
193: comib,=,n 1, r31, $fpemu0c_1_1
194: comib,=,n 2, r31, $fpemu0c_1_2
195: comib,=,n 3, r31, $fpemu0c_1_3
196:
197: $fpemu0c_1_0 /* fcnvff */
198: FP_TABLE3(fcnvff, invalid, dbl_to_sgl, invalid, quad_to_sgl, sgl_to_dbl, invalid, invalid, quad_to_dbl, invalid, invalid, invalid, invalid, sgl_to_quad, dbl_to_quad, invalid, invalid)
199:
200: $fpemu0c_1_1 /* fcnvxf */
201: FP_TABLE3(fcnvxf, sgl_to_sgl, dbl_to_sgl, invalid, quad_to_sgl, sgl_to_dbl, dbl_to_dbl, invalid, quad_to_dbl, invalid, invalid, invalid, invalid, sgl_to_quad, dbl_to_quad, invalid, quad_to_quad)
202:
203: $fpemu0c_1_2 /* fcnvfx */
204: FP_TABLE3(fcnvfx, sgl_to_sgl, dbl_to_sgl, invalid, quad_to_sgl, sgl_to_dbl, dbl_to_dbl, invalid, quad_to_dbl, invalid, invalid, invalid, invalid, sgl_to_quad, dbl_to_quad, invalid, quad_to_quad)
205:
206: $fpemu0c_1_3 /* fcnvfxt */
207: FP_TABLE3(fcnvfxt, sgl_to_sgl, dbl_to_sgl, invalid, quad_to_sgl, sgl_to_dbl, dbl_to_dbl, invalid, quad_to_dbl, invalid, invalid, invalid, invalid, sgl_to_quad, dbl_to_quad, invalid, quad_to_quad)
208:
209: $fpemu0c_2
210: comib,=,n 1, r31, $fpemu0c_2_1
211: comib,<>,n 0, r31, $fpemu_exit
212:
213: $fpemu0c_2_0
214: extru,<> t4, 15, 5, t1
215: ldi 32, t1
216: sh3add t1, arg3, arg1
217: extru,= t4, 19, 1, r0 /* see if it's the L reg */
218: addi 4, arg1, arg1
219: extru t4, 31, 5, arg2
220: FP_TABLE2(fcmp,sgl,dbl,invalid,invalid)
221:
222: $fpemu0c_2_1
223: comib,<>,n 0, r1, $fpemu_exit
224:
225: /* XXX timex is much more compilicated */
226: ldw 0(arg3), t1
227: ldi 0, ret0
228: extru,<> t1, 5, 1, r0
229: bv,n r0(rp)
230:
231: /* advance the pcqueue */
232: mtctl r0, pcsq
233: mfctl pcsq, t2
234: mtctl t2, pcsq
235: mtctl t2, pcsq
236: mtctl r0, pcoq
237: mfctl pcoq, t2
238: mtctl t2, pcoq
239: ldo 4(t2), t2
240: bv r0(rp)
241: mtctl t2, pcoq
242:
243: $fpemu0c_3
244: extru,<> t4, 15, 5, t1
245: ldi 32, t1
246: extru,= t4, 19, 1, r0 /* see if it's the L reg */
247: addi 4, arg1, arg1
248: blr r31, r0
249: nop
250:
251: b $fpemu0c_3_0
252: sh3add t1, arg1, arg1
253: b $fpemu0c_3_1
254: sh3add t1, arg1, arg1
255: b $fpemu0c_3_2
256: sh3add t1, arg1, arg1
257: b $fpemu0c_3_3
258: sh3add t1, arg1, arg1
259: b $fpemu0c_3_4
260: sh3add t1, arg1, arg1
261: b $fpemu_exit
262: sh3add t1, arg1, arg1
263: b $fpemu_exit
264: sh3add t1, arg1, arg1
265: b $fpemu_exit
266: sh3add t1, arg1, arg1
267:
268: $fpemu0c_3_0 /* fadd */
269: FP_TABLE2(fadd,sgl,dbl,invalid,invalid)
270:
271: $fpemu0c_3_1 /* fsub */
272: FP_TABLE2(fsub,sgl,dbl,invalid,invalid)
273:
274: $fpemu0c_3_2 /* fmpy/xmpy */
275: bb,>= t4, 23, $fpemu0c_3_2_f
276: nop
277:
278: FP_TABLE2(xmpy,s,u,s,u)
279: $fpemu0c_3_2_f
280: FP_TABLE2(fmpy,sgl,dbl,invalid,invalid)
281:
282: $fpemu0c_3_3 /* fdiv */
283: FP_TABLE2(fdiv,sgl,dbl,invalid,invalid)
284:
285: $fpemu0c_3_4 /* frem */
286: FP_TABLE2(frem,sgl,dbl,invalid,invalid)
287:
288: .export $fpemu_exit, code
289: $fpemu_exit
290: /* these look very ugly, but we don't want to mess up w/ m4 just
291: * for the sake of overall world prettieness value growth XXX */
292: invalid_fsqrt
293: invalid_frnd
294: invalid_fcnvff
295: sgl_to_quad_fcnvff
296: dbl_to_quad_fcnvff
297: quad_to_sgl_fcnvff
298: quad_to_dbl_fcnvff
299: invalid_fcnvxf
300: sgl_to_quad_fcnvxf
301: dbl_to_quad_fcnvxf
302: quad_to_sgl_fcnvxf
303: quad_to_dbl_fcnvxf
304: quad_to_quad_fcnvxf
305: invalid_fcnvfx
306: sgl_to_quad_fcnvfx
307: dbl_to_quad_fcnvfx
308: quad_to_sgl_fcnvfx
309: quad_to_dbl_fcnvfx
310: quad_to_quad_fcnvfx
311: invalid_fcnvfxt
312: sgl_to_quad_fcnvfxt
313: dbl_to_quad_fcnvfxt
314: quad_to_sgl_fcnvfxt
315: quad_to_dbl_fcnvfxt
316: quad_to_quad_fcnvfxt
317: invalid_fcmp
318: invalid_fadd
319: invalid_fsub
320: invalid_fmpy
321: invalid_fdiv
322: invalid_frem
323: bv 0(rp)
324: ldi HPPA_FPU_ILL, ret0
325: EXIT(fpu_emulate)
326:
327: .end
CVSweb