Annotation of sys/arch/hppa/hppa/fpemu.S, Revision 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