[BACK]Return to fpemu.S CVS log [TXT][DIR] Up to [local] / sys / arch / hppa / hppa

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