fpa11_cpdt.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:8k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

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