#include #include #include #include #include #include #include CPS_START_NAMESPACE using namespace std; const char * FP_FORMAT_NAME[] = { "n/a", "AUTOMATIC", "TIDSP32", "IEEE32", "IEEE32BIG", "IEEE32LITTLE", "IEEE64", "IEEE64BIG", "IEEE64LITTLE" }; const int FP_FORMAT_ENTRIES = sizeof(FP_FORMAT_NAME)/sizeof(FP_FORMAT_NAME[0]); FPConv::FPConv() : fileFormat(FP_UNKNOWN), cname("FPConv"), sim_qcdsp(0) { testHostFormat(); } FPConv::~FPConv() { } const char * FPConv::name(const enum FP_FORMAT format) { return FP_FORMAT_NAME[int(format)]; } char * FPConv::file2host(char * hbuf, const char * fdat, const int fdat_len)const { const char * fname = "file2host()"; // trivial case if(hostFormat == fileFormat) { memcpy(hbuf,fdat,fdat_len*size(hostFormat)); return hbuf; } // need conversion // 1. adjust endian if(big_endian(hostFormat) != big_endian(fileFormat)) { if(size(fileFormat) == 8) byterevn64((type64*)fdat,fdat_len); else byterevn((type32*)fdat,fdat_len); } // 2. distinguish by host format if(hostFormat == FP_TIDSP32) { // host ti if(size(fileFormat) == 4) { ieee2ti((type32*)fdat, fdat_len); copy32((type32*)hbuf, (type32*)fdat, fdat_len); } else { ERR.NotImplemented(cname,fname,"Read IEEE64 on QCDSP not implemented!\n"); // return 0; } } else if(size(hostFormat) == 4) { // host ieee32 if(fileFormat==FP_TIDSP32) { ti2ieee((type32*)fdat, fdat_len); copy32((type32*)hbuf, (type32*)fdat, fdat_len); } else if(size(fileFormat) == 4) copy32((type32*)hbuf, (type32*)fdat, fdat_len); else conv64to32((type32*)hbuf, (type64*)fdat, fdat_len); } else { // host ieee64 if(fileFormat == FP_TIDSP32) { ti2ieee((type32*)fdat, fdat_len); conv32to64((type64*)hbuf, (type32*)fdat, fdat_len); } else if(size(fileFormat) == 4) conv32to64((type64*)hbuf, (type32*)fdat, fdat_len); else copy64((type64*)hbuf, (type64*)fdat, fdat_len); } return hbuf; } char * FPConv::host2file(char *fbuf, const char * hdat, const int hdat_len) const{ const char * fname = "host2file"; // trivial case if(hostFormat == fileFormat) { memcpy(fbuf,hdat,hdat_len*size(fileFormat)); return fbuf; } // need conversion // 1. distinguish by host format if(hostFormat == FP_TIDSP32) { // host ti if(size(fileFormat) == 4) { copy32((type32*)fbuf, (type32*)hdat, hdat_len); ti2ieee((type32*)fbuf, hdat_len); } else { ERR.NotImplemented(cname,fname, "Write IEEE64 on QCDSP : not implemented!\n"); // return 0; } } else if(size(hostFormat) == 4) { // host ieee32 if(fileFormat==FP_TIDSP32) { copy32((type32*)fbuf, (type32*)hdat, hdat_len); ieee2ti((type32*)fbuf, hdat_len); } else if(size(fileFormat) == 4) copy32((type32*)fbuf, (type32*)hdat, hdat_len); else conv32to64((type64*)fbuf, (type32*)hdat, hdat_len); } else { // host ieee64 if(fileFormat == FP_TIDSP32) { conv64to32((type32*)fbuf, (type64*)hdat, hdat_len); ieee2ti((type32*)fbuf, hdat_len); } else if(size(fileFormat) == 4) conv64to32((type32*)fbuf, (type64*)hdat, hdat_len); else copy64((type64*)fbuf, (type64*)hdat, hdat_len); } // 2. adjust endian if(big_endian(hostFormat) != big_endian(fileFormat)) { if(size(fileFormat) == 8) byterevn64((type64*)fbuf,hdat_len); else byterevn((type32*)fbuf,hdat_len); } return fbuf; } void FPConv::byterevn(type32 w[], int n) const{ /* char * buf = (char*)w; cout << "First 16 bytes: "; for(int i=0;i<16;i++) cout << hex << (unsigned int)buf[i] << " "; cout << dec << endl; */ // cout << "Byte reverse 32 bits" << endl; register type32 oldv, newv; for(int i=0;i>= 8; } w[i] = newv; } /* cout << "First 16 bytes: "; for(int i=0;i<16;i++) cout << hex << (unsigned int)buf[i] << " "; cout << dec << endl; */ } void FPConv::byterevn64(type64 w[], int n) const{ /* char * buf = (char*)w; cout << "First 16 bytes: "; for(int i=0;i<16;i++) cout << hex << (unsigned int)buf[i] << " "; cout << dec << endl; */ // cout << "Byte reverse 64 bits" << endl; register type64 oldv, newv; for(int i=0;i>= 8; } w[i] = newv; } /* cout << "First 16 bytes: "; for(int i=0;i<16;i++) cout << hex << (unsigned int)buf[i] << " "; cout << dec << endl; */ } void FPConv::conv64to32(type32 tgt[], type64 src[], int n) const{ // cout << "Conversion 64 ==> 32" << endl; double *s = (double*)src; float *t = (float*)tgt; for(int i=0;i 64 " << endl; float *s = (float*) src; double *t = (double*)tgt; for(int i=0;i IEEE32 // TMS320C30-IEEE Floating-Point Format Converter // c.f Texas Instruments Application Report SPR400 // N.B. This report has several typos. // x-th bit of tmp #define tmpB(x) ( tmp>>(x)&1 ) //#define DEB(x) printf("%s\n",(x)) #define DEB(x) void FPConv::ti2ieee(type32 *ti, int Num) const{ register type32 tmp, tisave; type32 sign(0); type32 expo(0); type32 sfct(0); type32 sign_ti; type32 expo_ti; type32 sfct_ti; type32 EXP80_81, EXP7F, MANT0; int i; for(i=0;i> 24; sfct_ti= tmp & 0x007fffff; EXP80_81 = (expo_ti == 0x80) || (expo_ti == 0x81); EXP7F = expo_ti == 0x7f; MANT0 = (sfct_ti == 0) ; // printf("expo_ti = %d EXP80_81 = %d",expo_ti,EXP80_81); // CASE6 Positive number >= 2^{-126} // = !EXP80_81 & !ti(23) if( !EXP80_81 && !sign_ti ){ DEB("C6"); sign= sign_ti; expo= expo_ti + 0x7f; sfct= sfct_ti; } // CASE7 Positive number [2^{-127}, (2-2^{-23}) 2^{-127}] else if( EXP80_81 && tmpB(24) && !sign_ti ){ DEB("C7"); sign= sign_ti; expo= 0; sfct= sfct_ti/2+0x400000; } // CASE8 zero else if( EXP80_81 && !tmpB(24) ){ DEB("C8"); sign= 0; expo= 0; sfct= 0; } // CASE9 Negative number [(-2-2^{-23}) 2^{-127}, (-1-2^{-23}) 2^{-127}] else if( EXP80_81 && tmpB(23) && !MANT0 ){ DEB("C9"); sign= sign_ti; expo= 0; sfct= (0x800000-sfct_ti)/2+0x400000; } // CASE10 Negative number [- 2^{127}, -2^{-126}] else if( !(EXP80_81 && !tmpB(24)) && !EXP7F && tmpB(23) && MANT0 ){ DEB("C10"); sign= sign_ti; expo= expo_ti+0x80; sfct= 0; } // CASE11 Negative number (- 2^{128}, -2^{-126}) else if( !EXP80_81 && sign_ti && !MANT0 ){ DEB("C11"); sign= sign_ti; expo= expo_ti+0x7f; sfct= 0x800000-sfct_ti; } // CASE12 Negative number - 2^{128} else if( EXP7F && sign_ti && MANT0 ){ DEB("C12"); sign= sign_ti; expo= 0xff; sfct= 0; } else { DEB("UNSUPPORTED"); printf("unsupported bit pattern %x\n",(int)tmp); exit(-13); } // IEEE FP format : // 31 30 23 22 0 // | sign | expo | sfct | sign = sign << 31; expo = (expo << 23) & 0x7f800000; sfct = sfct & 0x7fffff; *(ti+i) = sign | expo | sfct; } } void FPConv::ieee2ti(type32 *ti, int Num) const{ const char * fname = "ieee2ti()"; ERR.NotImplemented(cname,fname); exit(13); } CPS_END_NAMESPACE