Example #1
0
float32 helper_fdiv_FT(CPUSH4State *env, float32 t0, float32 t1)
{
    set_float_exception_flags(0, &env->fp_status);
    t0 = float32_div(t0, t1, &env->fp_status);
    update_fpscr(env, GETPC());
    return t0;
}
Example #2
0
uint32_t helper_fdiv_FT(uint32_t t0, uint32_t t1)
{
    CPU_FloatU f0, f1;
    f0.l = t0;
    f1.l = t1;
    f0.f = float32_div(f0.f, f1.f, &env->fp_status);
    return f0.l;
}
Example #3
0
/* 32-bit FP division RM */
void HELPER(deb)(CPUS390XState *env, uint32_t f1, uint32_t val)
{
    float32 v1 = env->fregs[f1].l.upper;
    CPU_FloatU v2;

    v2.l = val;
    HELPER_LOG("%s: dividing 0x%d from f%d by 0x%d\n", __func__,
               v1, f1, v2.f);
    env->fregs[f1].l.upper = float32_div(v1, v2.f, &env->fpu_status);
}
Example #4
0
uint32_t helper_fdiv(CPUMBState *env, uint32_t a, uint32_t b)
{
    CPU_FloatU fd, fa, fb;
    int flags;

    set_float_exception_flags(0, &env->fp_status);
    fa.l = a;
    fb.l = b;
    fd.f = float32_div(fb.f, fa.f, &env->fp_status);
    flags = get_float_exception_flags(&env->fp_status);
    update_fpu_flags(env, flags);

    return fd.l;
}
Example #5
0
/* 32-bit FP division RR */
void HELPER(debr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
{
    env->fregs[f1].l.upper = float32_div(env->fregs[f1].l.upper,
                                         env->fregs[f2].l.upper,
                                         &env->fpu_status);
}
Example #6
0
int arop(int count, int op) {
float32 f1, f2, f3, f4;
int	i;
int	fp;
char	*mode;
int	add=0;
int	sub=0;
int	mul=0;
int	div=0;
int	oper;
int	err;
int	err_count=0;

if(!quiet) printf("\nGenerating %0d Arithmetic test vectors ...\n",count);

if(append)	mode = "a";
else		mode = "w";
if(ofile==0)	ofile = "ar.hex";

fp = fopen(ofile,mode);
if(fp == 0) {
	printf("ERROR: Could not create file '%s'.\n",ofile);
	return(-1);
   }

if(!quiet) {
	if(op & 0x1)	printf("Add OP\n");
	if(op & 0x2)	printf("Sub OP\n");
	if(op & 0x4)	printf("Mul OP\n");
	if(op & 0x8)	printf("Div OP\n");
   }

if(op & 0x1)	add=1;
if(op & 0x2)	sub=1;
if(op & 0x4)	mul=1;
if(op & 0x8)	div=1;

f1 = get_pat(0);	// Initialize pattern generator ...

for(i=0;i<count;i++) {

	err = 0;

	if(pat>0) {
		f1 = get_pat(1);
		f2 = get_pat(2);
	   } else {
		f1 = get_fp();
		f2 = get_fp();
	   }


	if(rall)	float_rounding_mode = (rand() % 4);


	oper = -1;
	while(oper == -1) {
	float_exception_flags = 0;	// Reset Exceptions

		if( (rand() % 4)==3 & div) {
			oper = 8;
			f3 = float32_div( f1, f2);
			float_exception_flags = 0;	// Reset Exceptions
			f3 = float32_div( f1, f2);

			//*( (float *) &f4 ) = *( (float *) &f1 ) / *( (float *) &f2 );
			//if( f4 != f3) {
			//	err = 1;
			//	printf("FP Div Error: %x - %x: System: %x Lib: %x\n",f1, f2, f4, f3);
			//   }
		   }

		if( (rand() % 4)==2 & mul) {
			oper = 4;
			f3 = float32_mul( f1, f2);
			float_exception_flags = 0;	// Reset Exceptions
			f3 = float32_mul( f1, f2);

			//*( (float *) &f4 ) = *( (float *) &f1 ) * *( (float *) &f2 );
			//if( f4 != f3) {
			//	err = 1;
			//	printf("FP Mul Error: %x - %x: System: %x Lib: %x\n",f1, f2, f4, f3);
			//   }
		   }

		if( (rand() % 4)==1 & sub) {
			oper = 2;
			f3 = float32_sub( f1, f2);
			float_exception_flags = 0;	// Reset Exceptions
			f3 = float32_sub( f1, f2);

			//*( (float *) &f4 ) = *( (float *) &f1 ) - *( (float *) &f2 );
			//if( f4 != f3) {
			//	err = 1;
			//	printf("FP Sub Error: %x - %x: System: %x Lib: %x\n",f1, f2, f4, f3);
			//   }
		   }

		if( (rand() % 4)==0 & add) {
			oper = 1;
			f3 = float32_add( f1, f2);
			float_exception_flags = 0;	// Reset Exceptions
			f3 = float32_add( f1, f2);

			//*( (float *) &f4 ) = *( (float *) &f1 ) + *( (float *) &f2 );
			//if( f4 != f3) {
			//	err = 1;
			//	printf("FP Add Error: %x - %x: System: %x Lib: %x\n",f1, f2, f4, f3);
			//   }
		   }

	   }

	if(err)		err_count++;

	if(!err) {

		//if(float_exception_flags != 0)
		//	printf("Exceptions: %x\n",float_exception_flags);
	
	
		if(verb)	printf("rmode: %01x, except: %02x, oper: %01x opa: %08x, opb: %08x res: %08x\n", float_rounding_mode, float_exception_flags, oper, f1, f2, f3);
		fprintf(fp,"%01x%02x%01x%08x%08x%08x\n", float_rounding_mode, float_exception_flags, oper, f1, f2, f3);
	   }
	else {
		printf("\t Vecor mismatch between library and system calculations. This Vector\n");
		printf("\t will not be placed in to vector file ...\n");
	}

   }


close(fp);

if(!quiet) {
	printf("Found %d errors\n",err_count);
	printf("Wrote %d vectors from total %d specified.\n", (count-err_count), count);
	
	printf("\n ... f2i done.\n");
   }
return(0);
}
Example #7
0
static void fpgen_rm_reg(m68000_base_device *m68k, UINT16 w2)
{
	int ea = m68k->ir & 0x3f;
	int rm = (w2 >> 14) & 0x1;
	int src = (w2 >> 10) & 0x7;
	int dst = (w2 >>  7) & 0x7;
	int opmode = w2 & 0x7f;
	floatx80 source;

	// fmovecr #$f, fp0 f200 5c0f

	if (rm)
	{
		switch (src)
		{
			case 0:     // Long-Word Integer
			{
				INT32 d = READ_EA_32(m68k, ea);
				source = int32_to_floatx80(d);
				break;
			}
			case 1:     // Single-precision Real
			{
				UINT32 d = READ_EA_32(m68k, ea);
				source = float32_to_floatx80(d);
				break;
			}
			case 2:     // Extended-precision Real
			{
				source = READ_EA_FPE(m68k, ea);
				break;
			}
			case 3:     // Packed-decimal Real
			{
				source = READ_EA_PACK(m68k, ea);
				break;
			}
			case 4:     // Word Integer
			{
				INT16 d = READ_EA_16(m68k, ea);
				source = int32_to_floatx80((INT32)d);
				break;
			}
			case 5:     // Double-precision Real
			{
				UINT64 d = READ_EA_64(m68k, ea);

				source = float64_to_floatx80(d);
				break;
			}
			case 6:     // Byte Integer
			{
				INT8 d = READ_EA_8(m68k, ea);
				source = int32_to_floatx80((INT32)d);
				break;
			}
			case 7:     // FMOVECR load from constant ROM
			{
				switch (w2 & 0x7f)
				{
					case 0x0:   // Pi
						source.high = 0x4000;
						source.low = U64(0xc90fdaa22168c235);
						break;

					case 0xb:   // log10(2)
						source.high = 0x3ffd;
						source.low = U64(0x9a209a84fbcff798);
						break;

					case 0xc:   // e
						source.high = 0x4000;
						source.low = U64(0xadf85458a2bb4a9b);
						break;

					case 0xd:   // log2(e)
						source.high = 0x3fff;
						source.low = U64(0xb8aa3b295c17f0bc);
						break;

					case 0xe:   // log10(e)
						source.high = 0x3ffd;
						source.low = U64(0xde5bd8a937287195);
						break;

					case 0xf:   // 0.0
						source = int32_to_floatx80((INT32)0);
						break;

					case 0x30:  // ln(2)
						source.high = 0x3ffe;
						source.low = U64(0xb17217f7d1cf79ac);
						break;

					case 0x31:  // ln(10)
						source.high = 0x4000;
						source.low = U64(0x935d8dddaaa8ac17);
						break;

					case 0x32:  // 1 (or 100?  manuals are unclear, but 1 would make more sense)
						source = int32_to_floatx80((INT32)1);
						break;

					case 0x33:  // 10^1
						source = int32_to_floatx80((INT32)10);
						break;

					case 0x34:  // 10^2
						source = int32_to_floatx80((INT32)10*10);
						break;

					case 0x35:  // 10^4
						source = int32_to_floatx80((INT32)1000*10);
						break;

					case 0x36:  // 1.0e8
						source = int32_to_floatx80((INT32)10000000*10);
						break;

					case 0x37:  // 1.0e16 - can't get the right precision from INT32 so go "direct" with constants from h/w
						source.high = 0x4034;
						source.low = U64(0x8e1bc9bf04000000);
						break;

					case 0x38:  // 1.0e32
						source.high = 0x4069;
						source.low = U64(0x9dc5ada82b70b59e);
						break;

					case 0x39:  // 1.0e64
						source.high = 0x40d3;
						source.low = U64(0xc2781f49ffcfa6d5);
						break;

					case 0x3a:  // 1.0e128
						source.high = 0x41a8;
						source.low = U64(0x93ba47c980e98ce0);
						break;

					case 0x3b:  // 1.0e256
						source.high = 0x4351;
						source.low = U64(0xaa7eebfb9df9de8e);
						break;

					case 0x3c:  // 1.0e512
						source.high = 0x46a3;
						source.low = U64(0xe319a0aea60e91c7);
						break;

					case 0x3d:  // 1.0e1024
						source.high = 0x4d48;
						source.low = U64(0xc976758681750c17);
						break;

					case 0x3e:  // 1.0e2048
						source.high = 0x5a92;
						source.low = U64(0x9e8b3b5dc53d5de5);
						break;

					case 0x3f:  // 1.0e4096
						source.high = 0x7525;
						source.low = U64(0xc46052028a20979b);
						break;

					default:
						fatalerror("fmove_rm_reg: unknown constant ROM offset %x at %08x\n", w2&0x7f, REG_PC(m68k)-4);
						break;
				}

				// handle it right here, the usual opmode bits aren't valid in the FMOVECR case
				REG_FP(m68k)[dst] = source;
				m68k->remaining_cycles -= 4;
				return;
			}
			default:    fatalerror("fmove_rm_reg: invalid source specifier %x at %08X\n", src, REG_PC(m68k)-4);
		}
	}
	else
	{
		source = REG_FP(m68k)[src];
	}



	switch (opmode)
	{
		case 0x00:      // FMOVE
		{
			REG_FP(m68k)[dst] = source;
			SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
			m68k->remaining_cycles -= 4;
			break;
		}
		case 0x01:      // FINT
		{
			INT32 temp;
			temp = floatx80_to_int32(source);
			REG_FP(m68k)[dst] = int32_to_floatx80(temp);
			break;
		}
		case 0x03:      // FINTRZ
		{
			INT32 temp;
			temp = floatx80_to_int32_round_to_zero(source);
			REG_FP(m68k)[dst] = int32_to_floatx80(temp);
			break;
		}
		case 0x04:      // FSQRT
		{
			REG_FP(m68k)[dst] = floatx80_sqrt(source);
			SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
			m68k->remaining_cycles -= 109;
			break;
		}
		case 0x06:      // FLOGNP1
		{
			REG_FP(m68k)[dst] = floatx80_flognp1 (source);
			SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
			m68k->remaining_cycles -= 594; // for MC68881
			break;
		}
		case 0x0e:      // FSIN
		{
			REG_FP(m68k)[dst] = source;
			floatx80_fsin(REG_FP(m68k)[dst]);
			SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
			m68k->remaining_cycles -= 75;
			break;
		}
		case 0x0f:      // FTAN
		{
			REG_FP(m68k)[dst] = source;
			floatx80_ftan(REG_FP(m68k)[dst]);
			SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
			m68k->remaining_cycles -= 75;
			break;
		}
		case 0x14:      // FLOGN
		{
			REG_FP(m68k)[dst] = floatx80_flogn (source);
			SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
			m68k->remaining_cycles -= 548; // for MC68881
			break;
		}
		case 0x15:      // FLOG10
		{
			REG_FP(m68k)[dst] = floatx80_flog10 (source);
			SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
			m68k->remaining_cycles -= 604; // for MC68881
			break;
		}
		case 0x16:      // FLOG2
		{
			REG_FP(m68k)[dst] = floatx80_flog2 (source);
			SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
			m68k->remaining_cycles -= 604; // for MC68881
			break;
		}
		case 0x18:      // FABS
		{
			REG_FP(m68k)[dst] = source;
			REG_FP(m68k)[dst].high &= 0x7fff;
			SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
			m68k->remaining_cycles -= 3;
			break;
		}
		case 0x1a:      // FNEG
		{
			REG_FP(m68k)[dst] = source;
			REG_FP(m68k)[dst].high ^= 0x8000;
			SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
			m68k->remaining_cycles -= 3;
			break;
		}
		case 0x1d:      // FCOS
		{
			REG_FP(m68k)[dst] = source;
			floatx80_fcos(REG_FP(m68k)[dst]);
			SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
			m68k->remaining_cycles -= 75;
			break;
		}
		case 0x1e:      // FGETEXP
		{
			INT16 temp2;

			temp2 = source.high;    // get the exponent
			temp2 -= 0x3fff;    // take off the bias
			REG_FP(m68k)[dst] = double_to_fx80((double)temp2);
			SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
			m68k->remaining_cycles -= 6;
			break;
		}
		case 0x20:      // FDIV
		{
			REG_FP(m68k)[dst] = floatx80_div(REG_FP(m68k)[dst], source);
			m68k->remaining_cycles -= 43;
			break;
		}
		case 0x22:      // FADD
		{
			REG_FP(m68k)[dst] = floatx80_add(REG_FP(m68k)[dst], source);
			SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
			m68k->remaining_cycles -= 9;
			break;
		}
		case 0x23:      // FMUL
		{
			REG_FP(m68k)[dst] = floatx80_mul(REG_FP(m68k)[dst], source);
			SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
			m68k->remaining_cycles -= 11;
			break;
		}
		case 0x24:      // FSGLDIV
		{
			float32 a = floatx80_to_float32( REG_FP(m68k)[dst] );
			float32 b = floatx80_to_float32( source );
			REG_FP(m68k)[dst] = float32_to_floatx80( float32_div(a, b) );
			m68k->remaining_cycles -= 43; //  // ? (value is from FDIV)
			break;
		}
		case 0x25:      // FREM
		{
			REG_FP(m68k)[dst] = floatx80_rem(REG_FP(m68k)[dst], source);
			SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
			m68k->remaining_cycles -= 43;   // guess
			break;
		}
		case 0x27:      // FSGLMUL
		{
			float32 a = floatx80_to_float32( REG_FP(m68k)[dst] );
			float32 b = floatx80_to_float32( source );
			REG_FP(m68k)[dst] = float32_to_floatx80( float32_mul(a, b) );
			SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
			m68k->remaining_cycles -= 11; // ? (value is from FMUL)
			break;
		}
		case 0x28:      // FSUB
		{
			REG_FP(m68k)[dst] = floatx80_sub(REG_FP(m68k)[dst], source);
			SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
			m68k->remaining_cycles -= 9;
			break;
		}
		case 0x38:      // FCMP
		{
			floatx80 res;
			res = floatx80_sub(REG_FP(m68k)[dst], source);
			SET_CONDITION_CODES(m68k, res);
			m68k->remaining_cycles -= 7;
			break;
		}
		case 0x3a:      // FTST
		{
			floatx80 res;
			res = source;
			SET_CONDITION_CODES(m68k, res);
			m68k->remaining_cycles -= 7;
			break;
		}

		default:    fatalerror("fpgen_rm_reg: unimplemented opmode %02X at %08X\n", opmode, REG_PPC(m68k));
	}
}
Example #8
0
float32 __divsf3(float32 A, float32 B)
{
	return float32_div(A, B);
}
Example #9
0
static float32 float32_rdv(struct roundingData *roundData, float32 rFn, float32 rFm)
{
    return float32_div(roundData, rFm, rFn);
}
Example #10
0
unsigned int SingleCPDO(const unsigned int opcode)
{
   FPA11 *fpa11 = GET_FPA11();
   float32 rFm, rFn = float32_zero;
   unsigned int Fd, Fm, Fn, nRc = 1;

   Fm = getFm(opcode);
   if (CONSTANT_FM(opcode))
   {
     rFm = getSingleConstant(Fm);
   }
   else
   {
     switch (fpa11->fType[Fm])
     {
        case typeSingle:
          rFm = fpa11->fpreg[Fm].fSingle;
        break;

        default: return 0;
     }
   }

   if (!MONADIC_INSTRUCTION(opcode))
   {
      Fn = getFn(opcode);
      switch (fpa11->fType[Fn])
      {
        case typeSingle:
          rFn = fpa11->fpreg[Fn].fSingle;
        break;

        default: return 0;
      }
   }

   Fd = getFd(opcode);
   switch (opcode & MASK_ARITHMETIC_OPCODE)
   {
      /* dyadic opcodes */
      case ADF_CODE:
         fpa11->fpreg[Fd].fSingle = float32_add(rFn,rFm, &fpa11->fp_status);
      break;

      case MUF_CODE:
      case FML_CODE:
        fpa11->fpreg[Fd].fSingle = float32_mul(rFn,rFm, &fpa11->fp_status);
      break;

      case SUF_CODE:
         fpa11->fpreg[Fd].fSingle = float32_sub(rFn,rFm, &fpa11->fp_status);
      break;

      case RSF_CODE:
         fpa11->fpreg[Fd].fSingle = float32_sub(rFm,rFn, &fpa11->fp_status);
      break;

      case DVF_CODE:
      case FDV_CODE:
         fpa11->fpreg[Fd].fSingle = float32_div(rFn,rFm, &fpa11->fp_status);
      break;

      case RDF_CODE:
      case FRD_CODE:
         fpa11->fpreg[Fd].fSingle = float32_div(rFm,rFn, &fpa11->fp_status);
      break;

#if 0
      case POW_CODE:
         fpa11->fpreg[Fd].fSingle = float32_pow(rFn,rFm);
      break;

      case RPW_CODE:
         fpa11->fpreg[Fd].fSingle = float32_pow(rFm,rFn);
      break;
#endif

      case RMF_CODE:
         fpa11->fpreg[Fd].fSingle = float32_rem(rFn,rFm, &fpa11->fp_status);
      break;

#if 0
      case POL_CODE:
         fpa11->fpreg[Fd].fSingle = float32_pol(rFn,rFm);
      break;
#endif

      /* monadic opcodes */
      case MVF_CODE:
         fpa11->fpreg[Fd].fSingle = rFm;
      break;

      case MNF_CODE:
         fpa11->fpreg[Fd].fSingle = float32_chs(rFm);
      break;

      case ABS_CODE:
         fpa11->fpreg[Fd].fSingle = float32_abs(rFm);
      break;

      case RND_CODE:
      case URD_CODE:
         fpa11->fpreg[Fd].fSingle = float32_round_to_int(rFm, &fpa11->fp_status);
      break;

      case SQT_CODE:
         fpa11->fpreg[Fd].fSingle = float32_sqrt(rFm, &fpa11->fp_status);
      break;

#if 0
      case LOG_CODE:
         fpa11->fpreg[Fd].fSingle = float32_log(rFm);
      break;

      case LGN_CODE:
         fpa11->fpreg[Fd].fSingle = float32_ln(rFm);
      break;

      case EXP_CODE:
         fpa11->fpreg[Fd].fSingle = float32_exp(rFm);
      break;

      case SIN_CODE:
         fpa11->fpreg[Fd].fSingle = float32_sin(rFm);
      break;

      case COS_CODE:
         fpa11->fpreg[Fd].fSingle = float32_cos(rFm);
      break;

      case TAN_CODE:
         fpa11->fpreg[Fd].fSingle = float32_tan(rFm);
      break;

      case ASN_CODE:
         fpa11->fpreg[Fd].fSingle = float32_arcsin(rFm);
      break;

      case ACS_CODE:
         fpa11->fpreg[Fd].fSingle = float32_arccos(rFm);
      break;

      case ATN_CODE:
         fpa11->fpreg[Fd].fSingle = float32_arctan(rFm);
      break;
#endif

      case NRM_CODE:
      break;

      default:
      {
        nRc = 0;
      }
   }

   if (0 != nRc) fpa11->fType[Fd] = typeSingle;
   return nRc;
}
Example #11
0
float32 float32_pol(float32 rFn,float32 rFm)
{
  return float32_arctan(float32_div(rFn,rFm));
}
Example #12
0
float32 float32_tan(float32 rFm)
{
  return float32_div(float32_sin(rFm),float32_cos(rFm));
}
Example #13
0
float32 float32_log(float32 rFm)
{
  return float32_div(float32_ln(rFm),getSingleConstant(7));
}
Example #14
0
float32 __aeabi_fdiv(float32 a, float32 b)
{
	return float32_div(a, b);
}