Annotation of qemu/target-arm/nwfpe/fpa11_cpdt.c, revision 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.