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

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: {
1.1.1.2 ! root       34:    target_ulong addr = (target_ulong)(long)pMem;
1.1       root       35:    FPA11 *fpa11 = GET_FPA11();
                     36:    fpa11->fType[Fn] = typeSingle;
1.1.1.2 ! root       37:    fpa11->fpreg[Fn].fSingle = tget32(addr);
1.1       root       38: }
                     39: 
                     40: static inline
                     41: void loadDouble(const unsigned int Fn,const unsigned int *pMem)
                     42: {
1.1.1.2 ! root       43:    target_ulong addr = (target_ulong)(long)pMem;
1.1       root       44:    FPA11 *fpa11 = GET_FPA11();
                     45:    unsigned int *p;
                     46:    p = (unsigned int*)&fpa11->fpreg[Fn].fDouble;
                     47:    fpa11->fType[Fn] = typeDouble;
                     48: #ifdef WORDS_BIGENDIAN
1.1.1.2 ! root       49:    p[0] = tget32(addr); /* sign & exponent */
        !            50:    p[1] = tget32(addr + 4);
1.1       root       51: #else
1.1.1.2 ! root       52:    p[0] = tget32(addr + 4);
        !            53:    p[1] = tget32(addr); /* sign & exponent */
1.1       root       54: #endif
                     55: }   
                     56: 
                     57: static inline
                     58: void loadExtended(const unsigned int Fn,const unsigned int *pMem)
                     59: {
1.1.1.2 ! root       60:    target_ulong addr = (target_ulong)(long)pMem;
1.1       root       61:    FPA11 *fpa11 = GET_FPA11();
                     62:    unsigned int *p;
                     63:    p = (unsigned int*)&fpa11->fpreg[Fn].fExtended;
                     64:    fpa11->fType[Fn] = typeExtended;
1.1.1.2 ! root       65:    p[0] = tget32(addr);  /* sign & exponent */
        !            66:    p[1] = tget32(addr + 8);  /* ls bits */
        !            67:    p[2] = tget32(addr + 4);  /* ms bits */
1.1       root       68: }   
                     69: 
                     70: static inline
                     71: void loadMultiple(const unsigned int Fn,const unsigned int *pMem)
                     72: {
1.1.1.2 ! root       73:    target_ulong addr = (target_ulong)(long)pMem;
1.1       root       74:    FPA11 *fpa11 = GET_FPA11();
                     75:    register unsigned int *p;
                     76:    unsigned long x;
                     77: 
                     78:    p = (unsigned int*)&(fpa11->fpreg[Fn]);
1.1.1.2 ! root       79:    x = tget32(addr);
1.1       root       80:    fpa11->fType[Fn] = (x >> 14) & 0x00000003;
                     81:    
                     82:    switch (fpa11->fType[Fn])
                     83:    {
                     84:       case typeSingle:
                     85:       case typeDouble:
                     86:       {
1.1.1.2 ! root       87:          p[0] = tget32(addr + 8);  /* Single */
        !            88:          p[1] = tget32(addr + 4);  /* double msw */
1.1       root       89:          p[2] = 0;        /* empty */
                     90:       }
                     91:       break; 
                     92:    
                     93:       case typeExtended:
                     94:       {
1.1.1.2 ! root       95:          p[1] = tget32(addr + 8);
        !            96:          p[2] = tget32(addr + 4);  /* msw */
1.1       root       97:          p[0] = (x & 0x80003fff);      
                     98:       }
                     99:       break;
                    100:    }
                    101: }
                    102: 
                    103: static inline
                    104: void storeSingle(const unsigned int Fn,unsigned int *pMem)
                    105: {
1.1.1.2 ! root      106:    target_ulong addr = (target_ulong)(long)pMem;
1.1       root      107:    FPA11 *fpa11 = GET_FPA11();
                    108:    float32 val;
                    109:    register unsigned int *p = (unsigned int*)&val;
                    110:    
                    111:    switch (fpa11->fType[Fn])
                    112:    {
                    113:       case typeDouble: 
                    114:          val = float64_to_float32(fpa11->fpreg[Fn].fDouble, &fpa11->fp_status);
                    115:       break;
                    116: 
                    117:       case typeExtended: 
                    118:          val = floatx80_to_float32(fpa11->fpreg[Fn].fExtended, &fpa11->fp_status);
                    119:       break;
                    120: 
                    121:       default: val = fpa11->fpreg[Fn].fSingle;
                    122:    }
                    123:   
1.1.1.2 ! root      124:    tput32(addr, p[0]);
1.1       root      125: }   
                    126: 
                    127: static inline
                    128: void storeDouble(const unsigned int Fn,unsigned int *pMem)
                    129: {
1.1.1.2 ! root      130:    target_ulong addr = (target_ulong)(long)pMem;
1.1       root      131:    FPA11 *fpa11 = GET_FPA11();
                    132:    float64 val;
                    133:    register unsigned int *p = (unsigned int*)&val;
                    134: 
                    135:    switch (fpa11->fType[Fn])
                    136:    {
                    137:       case typeSingle: 
                    138:          val = float32_to_float64(fpa11->fpreg[Fn].fSingle, &fpa11->fp_status);
                    139:       break;
                    140: 
                    141:       case typeExtended:
                    142:          val = floatx80_to_float64(fpa11->fpreg[Fn].fExtended, &fpa11->fp_status);
                    143:       break;
                    144: 
                    145:       default: val = fpa11->fpreg[Fn].fDouble;
                    146:    }
                    147: #ifdef WORDS_BIGENDIAN
1.1.1.2 ! root      148:    tput32(addr, p[0]); /* msw */
        !           149:    tput32(addr + 4, p[1]);     /* lsw */
1.1       root      150: #else
1.1.1.2 ! root      151:    tput32(addr, p[1]); /* msw */
        !           152:    tput32(addr + 4, p[0]);     /* lsw */
1.1       root      153: #endif
                    154: }   
                    155: 
                    156: static inline
                    157: void storeExtended(const unsigned int Fn,unsigned int *pMem)
                    158: {
1.1.1.2 ! root      159:    target_ulong addr = (target_ulong)(long)pMem;
1.1       root      160:    FPA11 *fpa11 = GET_FPA11();
                    161:    floatx80 val;
                    162:    register unsigned int *p = (unsigned int*)&val;
                    163:    
                    164:    switch (fpa11->fType[Fn])
                    165:    {
                    166:       case typeSingle: 
                    167:          val = float32_to_floatx80(fpa11->fpreg[Fn].fSingle, &fpa11->fp_status);
                    168:       break;
                    169: 
                    170:       case typeDouble: 
                    171:          val = float64_to_floatx80(fpa11->fpreg[Fn].fDouble, &fpa11->fp_status);
                    172:       break;
                    173: 
                    174:       default: val = fpa11->fpreg[Fn].fExtended;
                    175:    }
                    176:    
1.1.1.2 ! root      177:    tput32(addr, p[0]); /* sign & exp */
        !           178:    tput32(addr + 8, p[1]);
        !           179:    tput32(addr + 4, p[2]); /* msw */
1.1       root      180: }   
                    181: 
                    182: static inline
                    183: void storeMultiple(const unsigned int Fn,unsigned int *pMem)
                    184: {
1.1.1.2 ! root      185:    target_ulong addr = (target_ulong)(long)pMem;
1.1       root      186:    FPA11 *fpa11 = GET_FPA11();
                    187:    register unsigned int nType, *p;
                    188:    
                    189:    p = (unsigned int*)&(fpa11->fpreg[Fn]);
                    190:    nType = fpa11->fType[Fn];
                    191:    
                    192:    switch (nType)
                    193:    {
                    194:       case typeSingle:
                    195:       case typeDouble:
                    196:       {
1.1.1.2 ! root      197:         tput32(addr + 8, p[0]); /* single */
        !           198:         tput32(addr + 4, p[1]); /* double msw */
        !           199:         tput32(addr, nType << 14);
1.1       root      200:       }
                    201:       break; 
                    202:    
                    203:       case typeExtended:
                    204:       {
1.1.1.2 ! root      205:         tput32(addr + 4, p[2]); /* msw */
        !           206:         tput32(addr + 8, p[1]);
        !           207:         tput32(addr, (p[0] & 0x80003fff) | (nType << 14));
1.1       root      208:       }
                    209:       break;
                    210:    }
                    211: }
                    212: 
                    213: unsigned int PerformLDF(const unsigned int opcode)
                    214: {
                    215:    unsigned int *pBase, *pAddress, *pFinal, nRc = 1,
                    216:      write_back = WRITE_BACK(opcode);
                    217: 
                    218:    //printk("PerformLDF(0x%08x), Fd = 0x%08x\n",opcode,getFd(opcode));
                    219: 
                    220:    pBase = (unsigned int*)readRegister(getRn(opcode));
                    221:    if (REG_PC == getRn(opcode))
                    222:    {
                    223:      pBase += 2;
                    224:      write_back = 0;
                    225:    }
                    226: 
                    227:    pFinal = pBase;
                    228:    if (BIT_UP_SET(opcode))
                    229:      pFinal += getOffset(opcode);
                    230:    else
                    231:      pFinal -= getOffset(opcode);
                    232: 
                    233:    if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase;
                    234: 
                    235:    switch (opcode & MASK_TRANSFER_LENGTH)
                    236:    {
                    237:       case TRANSFER_SINGLE  : loadSingle(getFd(opcode),pAddress);   break;
                    238:       case TRANSFER_DOUBLE  : loadDouble(getFd(opcode),pAddress);   break;
                    239:       case TRANSFER_EXTENDED: loadExtended(getFd(opcode),pAddress); break;
                    240:       default: nRc = 0;
                    241:    }
                    242:    
                    243:    if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal);
                    244:    return nRc;
                    245: }
                    246: 
                    247: unsigned int PerformSTF(const unsigned int opcode)
                    248: {
                    249:    unsigned int *pBase, *pAddress, *pFinal, nRc = 1,
                    250:      write_back = WRITE_BACK(opcode);
                    251:    
                    252:    //printk("PerformSTF(0x%08x), Fd = 0x%08x\n",opcode,getFd(opcode));
                    253:    SetRoundingMode(ROUND_TO_NEAREST);
                    254:    
                    255:    pBase = (unsigned int*)readRegister(getRn(opcode));
                    256:    if (REG_PC == getRn(opcode))
                    257:    {
                    258:      pBase += 2;
                    259:      write_back = 0;
                    260:    }
                    261: 
                    262:    pFinal = pBase;
                    263:    if (BIT_UP_SET(opcode))
                    264:      pFinal += getOffset(opcode);
                    265:    else
                    266:      pFinal -= getOffset(opcode);
                    267: 
                    268:    if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase;
                    269: 
                    270:    switch (opcode & MASK_TRANSFER_LENGTH)
                    271:    {
                    272:       case TRANSFER_SINGLE  : storeSingle(getFd(opcode),pAddress);   break;
                    273:       case TRANSFER_DOUBLE  : storeDouble(getFd(opcode),pAddress);   break;
                    274:       case TRANSFER_EXTENDED: storeExtended(getFd(opcode),pAddress); break;
                    275:       default: nRc = 0;
                    276:    }
                    277:    
                    278:    if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal);
                    279:    return nRc;
                    280: }
                    281: 
                    282: unsigned int PerformLFM(const unsigned int opcode)
                    283: {
                    284:    unsigned int i, Fd, *pBase, *pAddress, *pFinal,
                    285:      write_back = WRITE_BACK(opcode);
                    286: 
                    287:    pBase = (unsigned int*)readRegister(getRn(opcode));
                    288:    if (REG_PC == getRn(opcode))
                    289:    {
                    290:      pBase += 2;
                    291:      write_back = 0;
                    292:    }
                    293: 
                    294:    pFinal = pBase;
                    295:    if (BIT_UP_SET(opcode))
                    296:      pFinal += getOffset(opcode);
                    297:    else
                    298:      pFinal -= getOffset(opcode);
                    299: 
                    300:    if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase;
                    301: 
                    302:    Fd = getFd(opcode);
                    303:    for (i=getRegisterCount(opcode);i>0;i--)
                    304:    {
                    305:      loadMultiple(Fd,pAddress);
                    306:      pAddress += 3; Fd++;
                    307:      if (Fd == 8) Fd = 0;
                    308:    }
                    309: 
                    310:    if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal);
                    311:    return 1;
                    312: }
                    313: 
                    314: unsigned int PerformSFM(const unsigned int opcode)
                    315: {
                    316:    unsigned int i, Fd, *pBase, *pAddress, *pFinal,
                    317:      write_back = WRITE_BACK(opcode);
                    318:    
                    319:    pBase = (unsigned int*)readRegister(getRn(opcode));
                    320:    if (REG_PC == getRn(opcode))
                    321:    {
                    322:      pBase += 2;
                    323:      write_back = 0;
                    324:    }
                    325:    
                    326:    pFinal = pBase;
                    327:    if (BIT_UP_SET(opcode))
                    328:      pFinal += getOffset(opcode);
                    329:    else
                    330:      pFinal -= getOffset(opcode);
                    331: 
                    332:    if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase;
                    333: 
                    334:    Fd = getFd(opcode);
                    335:    for (i=getRegisterCount(opcode);i>0;i--)
                    336:    {
                    337:      storeMultiple(Fd,pAddress);
                    338:      pAddress += 3; Fd++;
                    339:      if (Fd == 8) Fd = 0;
                    340:    }
                    341: 
                    342:    if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal);
                    343:    return 1;
                    344: }
                    345: 
                    346: #if 1
                    347: unsigned int EmulateCPDT(const unsigned int opcode)
                    348: {
                    349:   unsigned int nRc = 0;
                    350: 
                    351:   //printk("EmulateCPDT(0x%08x)\n",opcode);
                    352:   
                    353:   if (LDF_OP(opcode))
                    354:   {
                    355:     nRc = PerformLDF(opcode);
                    356:   }
                    357:   else if (LFM_OP(opcode))
                    358:   {
                    359:     nRc = PerformLFM(opcode);
                    360:   }
                    361:   else if (STF_OP(opcode))
                    362:   {
                    363:     nRc = PerformSTF(opcode);
                    364:   } 
                    365:   else if (SFM_OP(opcode))
                    366:   {
                    367:     nRc = PerformSFM(opcode);
                    368:   }
                    369:   else
                    370:   {
                    371:     nRc = 0;
                    372:   }
                    373:   
                    374:   return nRc;
                    375: }
                    376: #endif

unix.superglobalmegacorp.com

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