vdiv.c 4.32 KB
#include <stdio.h>
#include "vudefs.h"

char *Templ_div_frmt = "( %2d, %s, $26, $v%-d, $v%-d, $v%-d, $v%-d, $v%-d, $v%-d, $v%-d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d)\n";

i32
get_div_result(div_in,sqrt,sp)
i32 div_in;
int sqrt, sp;
  {
     i32 in_data,result;
     int j, found_1,lshift,romdata,rshift,addr;

     in_data = div_in;
     if (sp && div_in<0) in_data = -in_data;
     if (!sp && div_in<0)  
	 if (div_in>=-32768)
		in_data = -in_data;
	 else
		in_data = ~in_data;

	found_1 = 0;
	lshift= 0;
	for (j=0; j<32; j++)
	  if ((in_data & 1<<(31-j)) && !found_1) 
	    {
	      lshift=  j;
	      found_1 =1;
	    }
	addr = ((in_data<<lshift)&0x7fc00000) >> 22;

	if (sqrt) addr = (addr|0x200)&0x3fe | (lshift%2);  

	romdata = rom[addr];	

	rshift = (sqrt) ? (~lshift & 0x1f)/2 : (~lshift & 0x1f);

	result = (0x40000000 | (romdata<<14))>> rshift ;

	if (div_in<0) result = ~result;

        /*
        printf("div_data=0x%08x, result=0x%08x\n", div_in,result);
        */

	/* Final fix to handle corner cases*/
	if (div_in==0) 
	   result = 0x7fffffff;
	else
	if (div_in==0xffff8000) 
	   result = 0xffff0000;

	return (result);
 }

divide(fp)
FILE *fp;
  {
    int         i,j,sp,sqrt,dp_chain,div_vs;
    i32         result,indata;

    sp = optab[opindex].enu_name==SP_RECP||optab[opindex].enu_name==SP_SQRT;

    sqrt = optab[opindex].enu_name==SP_SQRT||optab[opindex].enu_name==DP_SQRT||
           optab[opindex].enu_name==DP_SQRT_CHAIN;

    dp_chain = optab[opindex].enu_name==DP_RECP_CHAIN||
	       optab[opindex].enu_name==DP_SQRT_CHAIN;

    div_vs = (regtab[SRC].rnum)%8;

    el = el & 0x7;

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


      indata = (sp && (div_in[i]&0x8000)) ? 0xffff0000|(div_in[i]&0xffff) : div_in[i]; 

      result = get_div_result(indata,sqrt,sp);
      
      div_out[i] = result;
      div_vsl[i] = (div_vs + i)%8;  
      div_vsh[i] = (div_vs + i + div_vsh_offset)%8;
      div_ell[i] = (el + i)%8;
      div_elh[i] = (el + i + div_elh_offset)%8;

      vtl[div_ell[i]] = indata&0xffff; 
      vth[div_elh[i]] = (sp) ? ~indata&0xffff : (div_in[i]>>16)&0xffff; 

      vdl[div_vsl[i]] = result&0xffff;
      vdh[div_vsh[i]] = result>>16; 

      }

       if (data_pntr < (2048 - 100))
         {
           /* initidLize data segment starting at data_pntr */
           /* SRC, TRGT, RES, RES_ACCH, RES_ACCM, RES_ACCL */
           for (i=0;i<8;i++) {data[data_pntr++] = vth[i];}
           for (i=0;i<8;i++) {data[data_pntr++] = vtl[i];}
           for (i=0;i<8;i++) {data[data_pntr++] = vdh[i];}
           for (i=0;i<8;i++) {data[data_pntr++] = vdl[i];}
         }

	if (sp)
         fprintf(fp,"Check_sp");
	else 
	if (dp_chain)
         fprintf(fp,"Check_dp_chain");
	else 
         fprintf(fp,"Check_dp");

         fprintf(fp,Templ_div_frmt,
                        test_num,
			optab[opindex].op_tmplt,
                        regtab[VTH].rnum,
                        regtab[VTL].rnum,
                        regtab[VDH].rnum,
                        regtab[VDL].rnum,
                        regtab[VDH_Exp].rnum,
                        regtab[VDL_Exp].rnum,
                        regtab[TEMP].rnum,
                        div_elh[0],
                        div_elh[1],
                        div_elh[2],
                        div_elh[3],
                        div_elh[4],
                        div_elh[5],
                        div_elh[6],
                        div_elh[7],

                        div_ell[0],
                        div_ell[1],
                        div_ell[2],
                        div_ell[3],
                        div_ell[4],
                        div_ell[5],
                        div_ell[6],
                        div_ell[7],

                        div_vsh[0],
                        div_vsh[1],
                        div_vsh[2],
                        div_vsh[3],
                        div_vsh[4],
                        div_vsh[5],
                        div_vsh[6],
                        div_vsh[7],

                        div_vsl[0],
                        div_vsl[1],
                        div_vsl[2],
                        div_vsl[3],
                        div_vsl[4],
                        div_vsl[5],
                        div_vsl[6],
                        div_vsl[7]
                );

  }