Annotation of qemu/target-arm/nwfpe/fpa11.c, revision 1.1.1.3

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;
1.1.1.2   root       39: CPUARMState* user_registers;
1.1       root       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();
1.1.1.3 ! root       46: 
1.1       root       47:   /* initialize the register type array */
                     48:   for (i=0;i<=7;i++)
                     49:   {
                     50:     fpa11->fType[i] = typeNone;
                     51:   }
1.1.1.3 ! root       52: 
1.1       root       53:   /* FPSR: set system id to FP_EMULATOR, set AC, clear all other bits */
                     54:   fpa11->fpsr = FP_EMULATOR | BIT_AC;
1.1.1.3 ! root       55: 
1.1       root       56:   /* FPCR: set SB, AB and DA bits, clear all others */
                     57: #if 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: #if MAINTAIN_FPCR
                     68:    fpa11->fpcr &= ~MASK_ROUNDING_MODE;
1.1.1.3 ! root       69: #endif
1.1       root       70:    switch (opcode & MASK_ROUNDING_MODE)
                     71:    {
                     72:       default:
                     73:       case ROUND_TO_NEAREST:
                     74:          rounding_mode = float_round_nearest_even;
1.1.1.3 ! root       75: #if MAINTAIN_FPCR
1.1       root       76:          fpa11->fpcr |= ROUND_TO_NEAREST;
1.1.1.3 ! root       77: #endif
1.1       root       78:       break;
1.1.1.3 ! root       79: 
1.1       root       80:       case ROUND_TO_PLUS_INFINITY:
                     81:          rounding_mode = float_round_up;
1.1.1.3 ! root       82: #if MAINTAIN_FPCR
1.1       root       83:          fpa11->fpcr |= ROUND_TO_PLUS_INFINITY;
1.1.1.3 ! root       84: #endif
1.1       root       85:       break;
1.1.1.3 ! root       86: 
1.1       root       87:       case ROUND_TO_MINUS_INFINITY:
                     88:          rounding_mode = float_round_down;
1.1.1.3 ! root       89: #if MAINTAIN_FPCR
1.1       root       90:          fpa11->fpcr |= ROUND_TO_MINUS_INFINITY;
1.1.1.3 ! root       91: #endif
1.1       root       92:       break;
1.1.1.3 ! root       93: 
1.1       root       94:       case ROUND_TO_ZERO:
                     95:          rounding_mode = float_round_to_zero;
1.1.1.3 ! root       96: #if MAINTAIN_FPCR
1.1       root       97:          fpa11->fpcr |= ROUND_TO_ZERO;
1.1.1.3 ! root       98: #endif
1.1       root       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: #if MAINTAIN_FPCR
                    109:    fpa11->fpcr &= ~MASK_ROUNDING_PRECISION;
1.1.1.3 ! root      110: #endif
1.1       root      111:    switch (opcode & MASK_ROUNDING_PRECISION)
                    112:    {
                    113:       case ROUND_SINGLE:
                    114:          rounding_precision = 32;
1.1.1.3 ! root      115: #if MAINTAIN_FPCR
1.1       root      116:          fpa11->fpcr |= ROUND_SINGLE;
1.1.1.3 ! root      117: #endif
1.1       root      118:       break;
1.1.1.3 ! root      119: 
1.1       root      120:       case ROUND_DOUBLE:
                    121:          rounding_precision = 64;
1.1.1.3 ! root      122: #if MAINTAIN_FPCR
1.1       root      123:          fpa11->fpcr |= ROUND_DOUBLE;
1.1.1.3 ! root      124: #endif
1.1       root      125:       break;
1.1.1.3 ! root      126: 
1.1       root      127:       case ROUND_EXTENDED:
                    128:          rounding_precision = 80;
1.1.1.3 ! root      129: #if MAINTAIN_FPCR
1.1       root      130:          fpa11->fpcr |= ROUND_EXTENDED;
1.1.1.3 ! root      131: #endif
1.1       root      132:       break;
1.1.1.3 ! root      133: 
1.1       root      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. */
1.1.1.2   root      140: /* ??? This is not thread safe.  */
                    141: unsigned int EmulateAll(unsigned int opcode, FPA11* qfpa, CPUARMState* qregs)
1.1       root      142: {
                    143:   unsigned int nRc = 0;
                    144: //  unsigned long flags;
1.1.1.3 ! root      145:   FPA11 *fpa11;
1.1       root      146: //  save_flags(flags); sti();
                    147: 
                    148:   qemufpa=qfpa;
                    149:   user_registers=qregs;
1.1.1.3 ! root      150: 
1.1       root      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:   if (TEST_OPCODE(opcode,MASK_CPRT))
                    166:   {
                    167:     //fprintf(stderr,"emulating CPRT\n");
                    168:     /* Emulate conversion opcodes. */
                    169:     /* Emulate register transfer opcodes. */
                    170:     /* Emulate comparison opcodes. */
                    171:     nRc = EmulateCPRT(opcode);
                    172:   }
                    173:   else if (TEST_OPCODE(opcode,MASK_CPDO))
                    174:   {
                    175:     //fprintf(stderr,"emulating CPDO\n");
                    176:     /* Emulate monadic arithmetic opcodes. */
                    177:     /* Emulate dyadic arithmetic opcodes. */
                    178:     nRc = EmulateCPDO(opcode);
                    179:   }
                    180:   else if (TEST_OPCODE(opcode,MASK_CPDT))
                    181:   {
                    182:     //fprintf(stderr,"emulating CPDT\n");
                    183:     /* Emulate load/store opcodes. */
                    184:     /* Emulate load/store multiple opcodes. */
                    185:     nRc = EmulateCPDT(opcode);
                    186:   }
                    187:   else
                    188:   {
                    189:     /* Invalid instruction detected.  Return FALSE. */
                    190:     nRc = 0;
                    191:   }
                    192: 
                    193: //  restore_flags(flags);
                    194: 
                    195:   //printf("returning %d\n",nRc);
                    196:   return(nRc);
                    197: }
                    198: 
                    199: #if 0
                    200: unsigned int EmulateAll1(unsigned int opcode)
                    201: {
                    202:   switch ((opcode >> 24) & 0xf)
                    203:   {
                    204:      case 0xc:
                    205:      case 0xd:
                    206:        if ((opcode >> 20) & 0x1)
                    207:        {
                    208:           switch ((opcode >> 8) & 0xf)
                    209:           {
                    210:              case 0x1: return PerformLDF(opcode); break;
                    211:              case 0x2: return PerformLFM(opcode); break;
                    212:              default: return 0;
                    213:           }
                    214:        }
                    215:        else
                    216:        {
                    217:           switch ((opcode >> 8) & 0xf)
                    218:           {
                    219:              case 0x1: return PerformSTF(opcode); break;
                    220:              case 0x2: return PerformSFM(opcode); break;
                    221:              default: return 0;
                    222:           }
                    223:       }
                    224:      break;
1.1.1.3 ! root      225: 
        !           226:      case 0xe:
1.1       root      227:        if (opcode & 0x10)
                    228:          return EmulateCPDO(opcode);
                    229:        else
                    230:          return EmulateCPRT(opcode);
                    231:      break;
1.1.1.3 ! root      232: 
1.1       root      233:      default: return 0;
                    234:   }
                    235: }
                    236: #endif
                    237: 

unix.superglobalmegacorp.com

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