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

unix.superglobalmegacorp.com

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