Annotation of qemu/target-arm/nwfpe/fpa11_cpdt.c, revision 1.1.1.1

1.1       root        1: /*
                      2:     NetWinder Floating Point Emulator
                      3:     (c) Rebel.com, 1998-1999
                      4:     (c) Philip Blundell, 1998
                      5: 
                      6:     Direct questions, comments to Scott Bambrough <[email protected]>
                      7: 
                      8:     This program is free software; you can redistribute it and/or modify
                      9:     it under the terms of the GNU General Public License as published by
                     10:     the Free Software Foundation; either version 2 of the License, or
                     11:     (at your option) any later version.
                     12: 
                     13:     This program is distributed in the hope that it will be useful,
                     14:     but WITHOUT ANY WARRANTY; without even the implied warranty of
                     15:     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     16:     GNU General Public License for more details.
                     17: 
                     18:     You should have received a copy of the GNU General Public License
                     19:     along with this program; if not, write to the Free Software
                     20:     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
                     21: */
                     22: 
                     23: #include "fpa11.h"
                     24: #include "softfloat.h"
                     25: #include "fpopcode.h"
                     26: //#include "fpmodule.h"
                     27: //#include "fpmodule.inl"
                     28: 
                     29: //#include <asm/uaccess.h>
                     30: 
                     31: static inline
                     32: void loadSingle(const unsigned int Fn,const unsigned int *pMem)
                     33: {
                     34:    FPA11 *fpa11 = GET_FPA11();
                     35:    fpa11->fType[Fn] = typeSingle;
                     36:    get_user(fpa11->fpreg[Fn].fSingle, pMem);
                     37: }
                     38: 
                     39: static inline
                     40: void loadDouble(const unsigned int Fn,const unsigned int *pMem)
                     41: {
                     42:    FPA11 *fpa11 = GET_FPA11();
                     43:    unsigned int *p;
                     44:    p = (unsigned int*)&fpa11->fpreg[Fn].fDouble;
                     45:    fpa11->fType[Fn] = typeDouble;
                     46: #ifdef WORDS_BIGENDIAN
                     47:    get_user(p[0], &pMem[0]); /* sign & exponent */
                     48:    get_user(p[1], &pMem[1]);
                     49: #else
                     50:    get_user(p[0], &pMem[1]);
                     51:    get_user(p[1], &pMem[0]); /* sign & exponent */
                     52: #endif
                     53: }   
                     54: 
                     55: static inline
                     56: void loadExtended(const unsigned int Fn,const unsigned int *pMem)
                     57: {
                     58:    FPA11 *fpa11 = GET_FPA11();
                     59:    unsigned int *p;
                     60:    p = (unsigned int*)&fpa11->fpreg[Fn].fExtended;
                     61:    fpa11->fType[Fn] = typeExtended;
                     62:    get_user(p[0], &pMem[0]);  /* sign & exponent */
                     63:    get_user(p[1], &pMem[2]);  /* ls bits */
                     64:    get_user(p[2], &pMem[1]);  /* ms bits */
                     65: }   
                     66: 
                     67: static inline
                     68: void loadMultiple(const unsigned int Fn,const unsigned int *pMem)
                     69: {
                     70:    FPA11 *fpa11 = GET_FPA11();
                     71:    register unsigned int *p;
                     72:    unsigned long x;
                     73: 
                     74:    p = (unsigned int*)&(fpa11->fpreg[Fn]);
                     75:    get_user(x, &pMem[0]);
                     76:    fpa11->fType[Fn] = (x >> 14) & 0x00000003;
                     77:    
                     78:    switch (fpa11->fType[Fn])
                     79:    {
                     80:       case typeSingle:
                     81:       case typeDouble:
                     82:       {
                     83:          get_user(p[0], &pMem[2]);  /* Single */
                     84:          get_user(p[1], &pMem[1]);  /* double msw */
                     85:          p[2] = 0;        /* empty */
                     86:       }
                     87:       break; 
                     88:    
                     89:       case typeExtended:
                     90:       {
                     91:          get_user(p[1], &pMem[2]);
                     92:          get_user(p[2], &pMem[1]);  /* msw */
                     93:          p[0] = (x & 0x80003fff);      
                     94:       }
                     95:       break;
                     96:    }
                     97: }
                     98: 
                     99: static inline
                    100: void storeSingle(const unsigned int Fn,unsigned int *pMem)
                    101: {
                    102:    FPA11 *fpa11 = GET_FPA11();
                    103:    float32 val;
                    104:    register unsigned int *p = (unsigned int*)&val;
                    105:    
                    106:    switch (fpa11->fType[Fn])
                    107:    {
                    108:       case typeDouble: 
                    109:          val = float64_to_float32(fpa11->fpreg[Fn].fDouble, &fpa11->fp_status);
                    110:       break;
                    111: 
                    112:       case typeExtended: 
                    113:          val = floatx80_to_float32(fpa11->fpreg[Fn].fExtended, &fpa11->fp_status);
                    114:       break;
                    115: 
                    116:       default: val = fpa11->fpreg[Fn].fSingle;
                    117:    }
                    118:   
                    119:    put_user(p[0], pMem);
                    120: }   
                    121: 
                    122: static inline
                    123: void storeDouble(const unsigned int Fn,unsigned int *pMem)
                    124: {
                    125:    FPA11 *fpa11 = GET_FPA11();
                    126:    float64 val;
                    127:    register unsigned int *p = (unsigned int*)&val;
                    128: 
                    129:    switch (fpa11->fType[Fn])
                    130:    {
                    131:       case typeSingle: 
                    132:          val = float32_to_float64(fpa11->fpreg[Fn].fSingle, &fpa11->fp_status);
                    133:       break;
                    134: 
                    135:       case typeExtended:
                    136:          val = floatx80_to_float64(fpa11->fpreg[Fn].fExtended, &fpa11->fp_status);
                    137:       break;
                    138: 
                    139:       default: val = fpa11->fpreg[Fn].fDouble;
                    140:    }
                    141: #ifdef WORDS_BIGENDIAN
                    142:    put_user(p[0], &pMem[0]);   /* msw */
                    143:    put_user(p[1], &pMem[1]);   /* lsw */
                    144: #else
                    145:    put_user(p[1], &pMem[0]);   /* msw */
                    146:    put_user(p[0], &pMem[1]);   /* lsw */
                    147: #endif
                    148: }   
                    149: 
                    150: static inline
                    151: void storeExtended(const unsigned int Fn,unsigned int *pMem)
                    152: {
                    153:    FPA11 *fpa11 = GET_FPA11();
                    154:    floatx80 val;
                    155:    register unsigned int *p = (unsigned int*)&val;
                    156:    
                    157:    switch (fpa11->fType[Fn])
                    158:    {
                    159:       case typeSingle: 
                    160:          val = float32_to_floatx80(fpa11->fpreg[Fn].fSingle, &fpa11->fp_status);
                    161:       break;
                    162: 
                    163:       case typeDouble: 
                    164:          val = float64_to_floatx80(fpa11->fpreg[Fn].fDouble, &fpa11->fp_status);
                    165:       break;
                    166: 
                    167:       default: val = fpa11->fpreg[Fn].fExtended;
                    168:    }
                    169:    
                    170:    put_user(p[0], &pMem[0]); /* sign & exp */
                    171:    put_user(p[1], &pMem[2]);
                    172:    put_user(p[2], &pMem[1]); /* msw */
                    173: }   
                    174: 
                    175: static inline
                    176: void storeMultiple(const unsigned int Fn,unsigned int *pMem)
                    177: {
                    178:    FPA11 *fpa11 = GET_FPA11();
                    179:    register unsigned int nType, *p;
                    180:    
                    181:    p = (unsigned int*)&(fpa11->fpreg[Fn]);
                    182:    nType = fpa11->fType[Fn];
                    183:    
                    184:    switch (nType)
                    185:    {
                    186:       case typeSingle:
                    187:       case typeDouble:
                    188:       {
                    189:         put_user(p[0], &pMem[2]); /* single */
                    190:         put_user(p[1], &pMem[1]); /* double msw */
                    191:         put_user(nType << 14, &pMem[0]);
                    192:       }
                    193:       break; 
                    194:    
                    195:       case typeExtended:
                    196:       {
                    197:         put_user(p[2], &pMem[1]); /* msw */
                    198:         put_user(p[1], &pMem[2]);
                    199:         put_user((p[0] & 0x80003fff) | (nType << 14), &pMem[0]);
                    200:       }
                    201:       break;
                    202:    }
                    203: }
                    204: 
                    205: unsigned int PerformLDF(const unsigned int opcode)
                    206: {
                    207:    unsigned int *pBase, *pAddress, *pFinal, nRc = 1,
                    208:      write_back = WRITE_BACK(opcode);
                    209: 
                    210:    //printk("PerformLDF(0x%08x), Fd = 0x%08x\n",opcode,getFd(opcode));
                    211: 
                    212:    pBase = (unsigned int*)readRegister(getRn(opcode));
                    213:    if (REG_PC == getRn(opcode))
                    214:    {
                    215:      pBase += 2;
                    216:      write_back = 0;
                    217:    }
                    218: 
                    219:    pFinal = pBase;
                    220:    if (BIT_UP_SET(opcode))
                    221:      pFinal += getOffset(opcode);
                    222:    else
                    223:      pFinal -= getOffset(opcode);
                    224: 
                    225:    if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase;
                    226: 
                    227:    switch (opcode & MASK_TRANSFER_LENGTH)
                    228:    {
                    229:       case TRANSFER_SINGLE  : loadSingle(getFd(opcode),pAddress);   break;
                    230:       case TRANSFER_DOUBLE  : loadDouble(getFd(opcode),pAddress);   break;
                    231:       case TRANSFER_EXTENDED: loadExtended(getFd(opcode),pAddress); break;
                    232:       default: nRc = 0;
                    233:    }
                    234:    
                    235:    if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal);
                    236:    return nRc;
                    237: }
                    238: 
                    239: unsigned int PerformSTF(const unsigned int opcode)
                    240: {
                    241:    unsigned int *pBase, *pAddress, *pFinal, nRc = 1,
                    242:      write_back = WRITE_BACK(opcode);
                    243:    
                    244:    //printk("PerformSTF(0x%08x), Fd = 0x%08x\n",opcode,getFd(opcode));
                    245:    SetRoundingMode(ROUND_TO_NEAREST);
                    246:    
                    247:    pBase = (unsigned int*)readRegister(getRn(opcode));
                    248:    if (REG_PC == getRn(opcode))
                    249:    {
                    250:      pBase += 2;
                    251:      write_back = 0;
                    252:    }
                    253: 
                    254:    pFinal = pBase;
                    255:    if (BIT_UP_SET(opcode))
                    256:      pFinal += getOffset(opcode);
                    257:    else
                    258:      pFinal -= getOffset(opcode);
                    259: 
                    260:    if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase;
                    261: 
                    262:    switch (opcode & MASK_TRANSFER_LENGTH)
                    263:    {
                    264:       case TRANSFER_SINGLE  : storeSingle(getFd(opcode),pAddress);   break;
                    265:       case TRANSFER_DOUBLE  : storeDouble(getFd(opcode),pAddress);   break;
                    266:       case TRANSFER_EXTENDED: storeExtended(getFd(opcode),pAddress); break;
                    267:       default: nRc = 0;
                    268:    }
                    269:    
                    270:    if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal);
                    271:    return nRc;
                    272: }
                    273: 
                    274: unsigned int PerformLFM(const unsigned int opcode)
                    275: {
                    276:    unsigned int i, Fd, *pBase, *pAddress, *pFinal,
                    277:      write_back = WRITE_BACK(opcode);
                    278: 
                    279:    pBase = (unsigned int*)readRegister(getRn(opcode));
                    280:    if (REG_PC == getRn(opcode))
                    281:    {
                    282:      pBase += 2;
                    283:      write_back = 0;
                    284:    }
                    285: 
                    286:    pFinal = pBase;
                    287:    if (BIT_UP_SET(opcode))
                    288:      pFinal += getOffset(opcode);
                    289:    else
                    290:      pFinal -= getOffset(opcode);
                    291: 
                    292:    if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase;
                    293: 
                    294:    Fd = getFd(opcode);
                    295:    for (i=getRegisterCount(opcode);i>0;i--)
                    296:    {
                    297:      loadMultiple(Fd,pAddress);
                    298:      pAddress += 3; Fd++;
                    299:      if (Fd == 8) Fd = 0;
                    300:    }
                    301: 
                    302:    if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal);
                    303:    return 1;
                    304: }
                    305: 
                    306: unsigned int PerformSFM(const unsigned int opcode)
                    307: {
                    308:    unsigned int i, Fd, *pBase, *pAddress, *pFinal,
                    309:      write_back = WRITE_BACK(opcode);
                    310:    
                    311:    pBase = (unsigned int*)readRegister(getRn(opcode));
                    312:    if (REG_PC == getRn(opcode))
                    313:    {
                    314:      pBase += 2;
                    315:      write_back = 0;
                    316:    }
                    317:    
                    318:    pFinal = pBase;
                    319:    if (BIT_UP_SET(opcode))
                    320:      pFinal += getOffset(opcode);
                    321:    else
                    322:      pFinal -= getOffset(opcode);
                    323: 
                    324:    if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase;
                    325: 
                    326:    Fd = getFd(opcode);
                    327:    for (i=getRegisterCount(opcode);i>0;i--)
                    328:    {
                    329:      storeMultiple(Fd,pAddress);
                    330:      pAddress += 3; Fd++;
                    331:      if (Fd == 8) Fd = 0;
                    332:    }
                    333: 
                    334:    if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal);
                    335:    return 1;
                    336: }
                    337: 
                    338: #if 1
                    339: unsigned int EmulateCPDT(const unsigned int opcode)
                    340: {
                    341:   unsigned int nRc = 0;
                    342: 
                    343:   //printk("EmulateCPDT(0x%08x)\n",opcode);
                    344:   
                    345:   if (LDF_OP(opcode))
                    346:   {
                    347:     nRc = PerformLDF(opcode);
                    348:   }
                    349:   else if (LFM_OP(opcode))
                    350:   {
                    351:     nRc = PerformLFM(opcode);
                    352:   }
                    353:   else if (STF_OP(opcode))
                    354:   {
                    355:     nRc = PerformSTF(opcode);
                    356:   } 
                    357:   else if (SFM_OP(opcode))
                    358:   {
                    359:     nRc = PerformSFM(opcode);
                    360:   }
                    361:   else
                    362:   {
                    363:     nRc = 0;
                    364:   }
                    365:   
                    366:   return nRc;
                    367: }
                    368: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.