Annotation of qemu/linux-user/arm/nwfpe/fpa11.c, revision 1.1.1.1

1.1       root        1: /*
                      2:     NetWinder Floating Point Emulator
                      3:     (c) Rebel.COM, 1998,1999
                      4: 
                      5:     Direct questions, comments to Scott Bambrough <[email protected]>
                      6: 
                      7:     This program is free software; you can redistribute it and/or modify
                      8:     it under the terms of the GNU General Public License as published by
                      9:     the Free Software Foundation; either version 2 of the License, or
                     10:     (at your option) any later version.
                     11: 
                     12:     This program is distributed in the hope that it will be useful,
                     13:     but WITHOUT ANY WARRANTY; without even the implied warranty of
                     14:     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     15:     GNU General Public License for more details.
                     16: 
                     17:     You should have received a copy of the GNU General Public License
                     18:     along with this program; if not, write to the Free Software
                     19:     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
                     20: */
                     21: 
                     22: #include "fpa11.h"
                     23: 
                     24: #include "fpopcode.h"
                     25: 
                     26: //#include "fpmodule.h"
                     27: //#include "fpmodule.inl"
                     28: 
                     29: //#include <asm/system.h>
                     30: 
                     31: #include <stdio.h>
                     32: 
                     33: /* forward declarations */
                     34: unsigned int EmulateCPDO(const unsigned int);
                     35: unsigned int EmulateCPDT(const unsigned int);
                     36: unsigned int EmulateCPRT(const unsigned int);
                     37: 
                     38: FPA11* qemufpa=0;
                     39: CPUARMState* user_registers;
                     40: 
                     41: /* Reset the FPA11 chip.  Called to initialize and reset the emulator. */
                     42: void resetFPA11(void)
                     43: {
                     44:   int i;
                     45:   FPA11 *fpa11 = GET_FPA11();
                     46: 
                     47:   /* initialize the register type array */
                     48:   for (i=0;i<=7;i++)
                     49:   {
                     50:     fpa11->fType[i] = typeNone;
                     51:   }
                     52: 
                     53:   /* FPSR: set system id to FP_EMULATOR, set AC, clear all other bits */
                     54:   fpa11->fpsr = FP_EMULATOR | BIT_AC;
                     55: 
                     56:   /* FPCR: set SB, AB and DA bits, clear all others */
                     57: #ifdef MAINTAIN_FPCR
                     58:   fpa11->fpcr = MASK_RESET;
                     59: #endif
                     60: }
                     61: 
                     62: void SetRoundingMode(const unsigned int opcode)
                     63: {
                     64:     int rounding_mode;
                     65:    FPA11 *fpa11 = GET_FPA11();
                     66: 
                     67: #ifdef MAINTAIN_FPCR
                     68:    fpa11->fpcr &= ~MASK_ROUNDING_MODE;
                     69: #endif
                     70:    switch (opcode & MASK_ROUNDING_MODE)
                     71:    {
                     72:       default:
                     73:       case ROUND_TO_NEAREST:
                     74:          rounding_mode = float_round_nearest_even;
                     75: #ifdef MAINTAIN_FPCR
                     76:          fpa11->fpcr |= ROUND_TO_NEAREST;
                     77: #endif
                     78:       break;
                     79: 
                     80:       case ROUND_TO_PLUS_INFINITY:
                     81:          rounding_mode = float_round_up;
                     82: #ifdef MAINTAIN_FPCR
                     83:          fpa11->fpcr |= ROUND_TO_PLUS_INFINITY;
                     84: #endif
                     85:       break;
                     86: 
                     87:       case ROUND_TO_MINUS_INFINITY:
                     88:          rounding_mode = float_round_down;
                     89: #ifdef MAINTAIN_FPCR
                     90:          fpa11->fpcr |= ROUND_TO_MINUS_INFINITY;
                     91: #endif
                     92:       break;
                     93: 
                     94:       case ROUND_TO_ZERO:
                     95:          rounding_mode = float_round_to_zero;
                     96: #ifdef MAINTAIN_FPCR
                     97:          fpa11->fpcr |= ROUND_TO_ZERO;
                     98: #endif
                     99:       break;
                    100:   }
                    101:    set_float_rounding_mode(rounding_mode, &fpa11->fp_status);
                    102: }
                    103: 
                    104: void SetRoundingPrecision(const unsigned int opcode)
                    105: {
                    106:     int rounding_precision;
                    107:    FPA11 *fpa11 = GET_FPA11();
                    108: #ifdef MAINTAIN_FPCR
                    109:    fpa11->fpcr &= ~MASK_ROUNDING_PRECISION;
                    110: #endif
                    111:    switch (opcode & MASK_ROUNDING_PRECISION)
                    112:    {
                    113:       case ROUND_SINGLE:
                    114:          rounding_precision = 32;
                    115: #ifdef MAINTAIN_FPCR
                    116:          fpa11->fpcr |= ROUND_SINGLE;
                    117: #endif
                    118:       break;
                    119: 
                    120:       case ROUND_DOUBLE:
                    121:          rounding_precision = 64;
                    122: #ifdef MAINTAIN_FPCR
                    123:          fpa11->fpcr |= ROUND_DOUBLE;
                    124: #endif
                    125:       break;
                    126: 
                    127:       case ROUND_EXTENDED:
                    128:          rounding_precision = 80;
                    129: #ifdef MAINTAIN_FPCR
                    130:          fpa11->fpcr |= ROUND_EXTENDED;
                    131: #endif
                    132:       break;
                    133: 
                    134:       default: rounding_precision = 80;
                    135:   }
                    136:    set_floatx80_rounding_precision(rounding_precision, &fpa11->fp_status);
                    137: }
                    138: 
                    139: /* Emulate the instruction in the opcode. */
                    140: /* ??? This is not thread safe.  */
                    141: unsigned int EmulateAll(unsigned int opcode, FPA11* qfpa, CPUARMState* qregs)
                    142: {
                    143:   unsigned int nRc = 0;
                    144: //  unsigned long flags;
                    145:   FPA11 *fpa11;
                    146: //  save_flags(flags); sti();
                    147: 
                    148:   qemufpa=qfpa;
                    149:   user_registers=qregs;
                    150: 
                    151: #if 0
                    152:   fprintf(stderr,"emulating FP insn 0x%08x, PC=0x%08x\n",
                    153:           opcode, qregs[REG_PC]);
                    154: #endif
                    155:   fpa11 = GET_FPA11();
                    156: 
                    157:   if (fpa11->initflag == 0)            /* good place for __builtin_expect */
                    158:   {
                    159:     resetFPA11();
                    160:     SetRoundingMode(ROUND_TO_NEAREST);
                    161:     SetRoundingPrecision(ROUND_EXTENDED);
                    162:     fpa11->initflag = 1;
                    163:   }
                    164: 
                    165:   set_float_exception_flags(0, &fpa11->fp_status);
                    166: 
                    167:   if (TEST_OPCODE(opcode,MASK_CPRT))
                    168:   {
                    169:     //fprintf(stderr,"emulating CPRT\n");
                    170:     /* Emulate conversion opcodes. */
                    171:     /* Emulate register transfer opcodes. */
                    172:     /* Emulate comparison opcodes. */
                    173:     nRc = EmulateCPRT(opcode);
                    174:   }
                    175:   else if (TEST_OPCODE(opcode,MASK_CPDO))
                    176:   {
                    177:     //fprintf(stderr,"emulating CPDO\n");
                    178:     /* Emulate monadic arithmetic opcodes. */
                    179:     /* Emulate dyadic arithmetic opcodes. */
                    180:     nRc = EmulateCPDO(opcode);
                    181:   }
                    182:   else if (TEST_OPCODE(opcode,MASK_CPDT))
                    183:   {
                    184:     //fprintf(stderr,"emulating CPDT\n");
                    185:     /* Emulate load/store opcodes. */
                    186:     /* Emulate load/store multiple opcodes. */
                    187:     nRc = EmulateCPDT(opcode);
                    188:   }
                    189:   else
                    190:   {
                    191:     /* Invalid instruction detected.  Return FALSE. */
                    192:     nRc = 0;
                    193:   }
                    194: 
                    195: //  restore_flags(flags);
                    196:   if(nRc == 1 && get_float_exception_flags(&fpa11->fp_status))
                    197:   {
                    198:     //printf("fef 0x%x\n",float_exception_flags);
                    199:     nRc=-get_float_exception_flags(&fpa11->fp_status);
                    200:   }
                    201: 
                    202:   //printf("returning %d\n",nRc);
                    203:   return(nRc);
                    204: }
                    205: 
                    206: #if 0
                    207: unsigned int EmulateAll1(unsigned int opcode)
                    208: {
                    209:   switch ((opcode >> 24) & 0xf)
                    210:   {
                    211:      case 0xc:
                    212:      case 0xd:
                    213:        if ((opcode >> 20) & 0x1)
                    214:        {
                    215:           switch ((opcode >> 8) & 0xf)
                    216:           {
                    217:              case 0x1: return PerformLDF(opcode); break;
                    218:              case 0x2: return PerformLFM(opcode); break;
                    219:              default: return 0;
                    220:           }
                    221:        }
                    222:        else
                    223:        {
                    224:           switch ((opcode >> 8) & 0xf)
                    225:           {
                    226:              case 0x1: return PerformSTF(opcode); break;
                    227:              case 0x2: return PerformSFM(opcode); break;
                    228:              default: return 0;
                    229:           }
                    230:       }
                    231:      break;
                    232: 
                    233:      case 0xe:
                    234:        if (opcode & 0x10)
                    235:          return EmulateCPDO(opcode);
                    236:        else
                    237:          return EmulateCPRT(opcode);
                    238:      break;
                    239: 
                    240:      default: return 0;
                    241:   }
                    242: }
                    243: #endif

unix.superglobalmegacorp.com

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