kerneltest/f32test/math/t_gen.cpp
author Slion
Tue, 08 Dec 2009 08:11:42 +0100
branchanywhere
changeset 19 f6d3d9676ee4
parent 0 a41df078684a
permissions -rw-r--r--
Trying to figure out how to implement my WINC like compatibility layer. Going the emulation way is probably not so smart. We should not use the kernel but rather hook native functions in the Exec calls.

// Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of the License "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
// f32test\math\t_gen.cpp
// Generates files to be used in testing whether arithmetic in TReal32 and TReal64 gives
// exactly the same results using the MSDEV complier as on the rack.
// 
//

#include <e32test.h>
#include <f32file.h>
#include <e32svr.h>
#include "../server/t_server.h"
#include "t_math.h"

GLDEF_D RTest test(_L("T_GEN"));

LOCAL_D const TFileName pathName = _L("C:\\F32-TST\\E32-MATH\\");
LOCAL_D	TBuf<0x100> buf;
LOCAL_D	TBuf8<0x100> buf8;


#define __GENERATE_SPECIAL_VALUES
#ifdef __GENERATE_SPECIAL_VALUES

LOCAL_D	RFile fspw;	// file for special values for WINS
LOCAL_D	RFile fspa;	// file for special values for ARM

LOCAL_D const TFileName fileNameWSp = _L("T_VALS.HWG");
LOCAL_D const TFileName fileNameASp = _L("T_VALS.HAG");

LOCAL_C void appendConstTI64(TPtrC aName,TReal64* aVal)
	{
	// for WINS 
	buf=_L("");
	buf.AppendFormat(_L("const TInt64 %S = TInt64(0x%x,0x%x);\n"),&aName,*(((TUint32*)aVal) + 1),*(TUint32*)aVal);
	buf8.Copy(buf);	// Unicode
	fspw.Write(buf8);
	// for ARM
	buf=_L("");
	buf.AppendFormat(_L("const TInt64 %S = TInt64(0x%x,0x%x);\n"),&aName,*(TUint32*)aVal,*(((TUint32*)aVal) + 1));
	buf8.Copy(buf);
	fspa.Write(buf8);
	}

LOCAL_C void appendConstTI32x(TPtrC aName,TReal32* aVal)
	{
	// for WINS and ARM
	buf=_L("");
	buf.AppendFormat(_L("const TInt32x %S = TInt32x(0x%x);\n"),&aName,*(TUint32*)aVal);
	buf8.Copy(buf);	// Unicode
	fspw.Write(buf8);	
	fspa.Write(buf8);	
	}

LOCAL_C void appendConstTR64(TPtrC aName,TPtrC aIntName)
	{
	// for WINS and ARM
	buf=_L("");
	buf.AppendFormat(_L("const TReal64 %S = *(TReal64*)&%S;\n"),&aName,&aIntName);
	buf8.Copy(buf);	// Unicode
	fspw.Write(buf8);
	fspa.Write(buf8);
	}

LOCAL_C void appendConstTR32(TPtrC aName,TPtrC aIntName)
	{
	// for WINS and ARM
	buf=_L("");
	buf.AppendFormat(_L("const TReal32 %S = *(TReal32*)&%S;\n"),&aName,&aIntName);
	buf8.Copy(buf);
	fspw.Write(buf8);	
	fspa.Write(buf8);	
	}

LOCAL_C void appendConstTR(TPtrC aName,TPtrC a64Name)
	{ 
	// for WINS and ARM
	buf=_L("");
	buf.AppendFormat(_L("const TReal %S = TReal(%S);\n"),&aName,&a64Name);
	buf8.Copy(buf);	// Unicode
	fspw.Write(buf8);	
	fspa.Write(buf8);	
	}

LOCAL_C void appendStart()
	{
	// for WINS
	fspw.Write(_L8("/* Generated by \\E32\\TMATH\\T_GEN.MAK for WINS (little-endian doubles) */\n\n"));
	fspw.Write(_L8("#include <e32std.h>\n\n"));
	fspw.Write(_L8("class TInt32x\n{\npublic:\n"));
	fspw.Write(_L8("TInt32x(TInt32 aInt) {iInt=aInt;}\n"));
	fspw.Write(_L8("public:\nTInt32 iInt;\n};\n\n"));

	// for ARM
	fspa.Write(_L8("/* Generated by \\E32\\TMATH\\T_GEN.MAK for ARM (big-endian doubles)*/\n\n"));
	fspa.Write(_L8("#include <e32std.h>\n\n"));
	fspa.Write(_L8("class TInt32x\n{\npublic:\n"));
	fspa.Write(_L8("TInt32x(TInt32 aInt) {iInt=aInt;}\n"));
	fspa.Write(_L8("public:\nTInt32 iInt;\n};\n\n"));
	}

LOCAL_C void generateSpecialValues()
//
// The following are to avoid the errors in the compiler in converting from string
// to floating point
//
// Initialise max/min values and square roots and write to header files
//
	{

	TReal64 minTReal32in64;
	SReal64 *p64=(SReal64*)&minTReal32in64;
	p64->sign=0;
	p64->exp=0x381;
	p64->msm=0;
	p64->lsm=0;

	TReal64 maxTReal32in64;
	p64=(SReal64*)&maxTReal32in64;
	p64->sign=0;
	p64->exp=0x47E;
	p64->msm=0xfffff;
	p64->lsm=0xe0000000;

	TReal64 sqrtMaxTReal64;		
	const TReal64 arg1=KMaxTReal64-1.0E+299;		// Take off this to avoid overflow
	TInt ret=Math::Sqrt(sqrtMaxTReal64,arg1);
	TReal64 sqrtMinTReal64;
	const TReal64 arg2=KMinTReal64;
	ret=Math::Sqrt(sqrtMinTReal64,arg2);

	TReal64 sqrtMaxTReal32in64,sqrtMinTReal32in64; 

	TReal64 negZeroTReal64;
	p64=(SReal64*)&negZeroTReal64;
	p64->sign=1;
	p64->exp=0;
	p64->msm=0;
	p64->lsm=0;

	TReal64 posInfTReal64;
	p64=(SReal64*)&posInfTReal64;
	p64->sign=0;
	p64->exp=KTReal64SpecialExponent;
	p64->msm=0;
	p64->lsm=0;

	TReal64 negInfTReal64;
	p64=(SReal64*)&negInfTReal64;
	p64->sign=1;
	p64->exp=KTReal64SpecialExponent;
	p64->msm=0;
	p64->lsm=0;

	TReal64 NaNTReal64;
	p64=(SReal64*)&NaNTReal64;
	p64->sign=0;
	p64->exp=KTReal64SpecialExponent;
	p64->msm=0xfffffu;
	p64->lsm=0xffffffffu;

	TReal32 sqrtMaxTReal32;
	const TReal arg3=maxTReal32in64-1.0E+32f;		// Take off this to avoid overflow
	ret=Math::Sqrt(sqrtMaxTReal32in64,arg3);
	sqrtMaxTReal32=TReal32(sqrtMaxTReal32in64);
	
	TReal32 sqrtMinTReal32;
	const TReal arg4=minTReal32in64;
	ret=Math::Sqrt(sqrtMinTReal32in64,arg4);
	sqrtMinTReal32=TReal32(sqrtMinTReal32in64);

	TReal32 negZeroTReal32;
	SReal32 *p32=(SReal32*)&negZeroTReal32;
	p32->sign=1;
	p32->exp=0;
	p32->man=0;	

	appendStart();

	appendConstTI64(_L("minTReal32in64"),&minTReal32in64);
	appendConstTI64(_L("maxTReal32in64"),&maxTReal32in64);
	appendConstTI64(_L("sqrtMaxTReal64"),&sqrtMaxTReal64);
	appendConstTI64(_L("sqrtMinTReal64"),&sqrtMinTReal64);
	appendConstTI64(_L("negZeroTReal64"),&negZeroTReal64);
	appendConstTI64(_L("posInfTReal64"),&posInfTReal64);
	appendConstTI64(_L("negInfTReal64"),&negInfTReal64);
	appendConstTI64(_L("NaNTReal64"),&NaNTReal64);

	appendConstTI32x(_L("sqrtMaxTReal32"),&sqrtMaxTReal32);
	appendConstTI32x(_L("sqrtMinTReal32"),&sqrtMinTReal32);
	appendConstTI32x(_L("negZeroTReal32"),&negZeroTReal32);

	appendConstTR64(_L("KMinTReal32in64"),_L("minTReal32in64"));
	appendConstTR64(_L("KMaxTReal32in64"),_L("maxTReal32in64"));
	appendConstTR64(_L("KSqrtMaxTReal64"),_L("sqrtMaxTReal64"));
	appendConstTR64(_L("KSqrtMinTReal64"),_L("sqrtMinTReal64"));
	appendConstTR64(_L("KNegZeroTReal64"),_L("negZeroTReal64"));
	appendConstTR64(_L("KPosInfTReal64"),_L("posInfTReal64"));
	appendConstTR64(_L("KNegInfTReal64"),_L("negInfTReal64"));
	appendConstTR64(_L("KNaNTReal64"),_L("NaNTReal64"));
	
	appendConstTR32(_L("KSqrtMaxTReal32"),_L("sqrtMaxTReal32"));
	appendConstTR32(_L("KSqrtMinTReal32"),_L("sqrtMinTReal32"));
	appendConstTR32(_L("KNegZeroTReal32"),_L("negZeroTReal32"));

	appendConstTR(_L("KMinTReal32inTReal"),_L("KMinTReal32in64"));
	appendConstTR(_L("KMaxTReal32inTReal"),_L("KMaxTReal32in64"));
	appendConstTR(_L("KNegZeroTReal"),_L("KNegZeroTReal64"));
	}

#endif

//#define __GENERATE_TR64 
#ifdef __GENERATE_TR64

// Data for tests from T_R64DTA.cpp 
GLREF_D TReal64 addInput[];
GLREF_D TReal64 subInput[];
GLREF_D TReal64 multInput[];
GLREF_D TReal64 divInput[];
GLREF_D TReal64 unaryInput[];
GLREF_D TReal64 incDecInput[];
GLREF_D TInt sizeAdd;
GLREF_D TInt sizeSub;
GLREF_D TInt sizeMult;
GLREF_D TInt sizeDiv;
GLREF_D TInt sizeUnary;
GLREF_D TInt sizeIncDec;

LOCAL_D	RFile fw;	// file for WINS
LOCAL_D RFile fa;	// file for ARM
LOCAL_D const TFileName fileNameW64 = _L("T_REAL64.HWG");
LOCAL_D const TFileName fileNameA64 = _L("T_REAL64.HAG");

LOCAL_C void appendArrayName64(TDesC& aName)
	{
	buf=_L("");
	buf.AppendFormat(_L("const TInt64 %S[] = \n{\n"),&aName);
	fw.Write(buf);
	fa.Write(buf);
	}

LOCAL_C void appendValue64(TReal64* aVal)
	{
	buf=_L("");
	buf.AppendFormat(_L("	TInt64(0x%x,0x%x),\n"),*(((TUint32*)aVal) + 1),*(TUint32*)aVal);
	fw.Write(buf);
	buf=_L("");
	buf.AppendFormat(_L("	TInt64(0x%x,0x%x),\n"),*(TUint32*)aVal,*(((TUint32*)aVal) + 1));
	fa.Write(buf);
	}

LOCAL_C void appendArrayTerm()
	{
	buf=_L("};\n\n");
	fw.Write(buf);
	fa.Write(buf);
	}

LOCAL_C void createAddArray()
//
// Writes an array of results of additions to the header file
//
	{
	TInt ii;
	TReal64 ff;

	appendArrayName64(_L("addArray"));
	for (ii=0; ii<sizeAdd-1; ii++)
		{
		ff=addInput[ii]+addInput[ii+1];
		appendValue64(&ff);
		}
	appendArrayTerm();
	}

LOCAL_C void createSubArray()
//
// Writes an array of results of subtractions to the header file
//
	{
	TInt ii;
	TReal64 ff;

	appendArrayName64(_L("subArray"));
	for (ii=0; ii<sizeSub-1; ii++)
		{
		ff=subInput[ii]-subInput[ii+1];
		appendValue64(&ff);
		}
	appendArrayTerm();
	} 

LOCAL_C void createMultArray()
//
// Writes an array of results of multiplications to the header file
//
	{
	TInt ii;
	TReal64 ff;

	appendArrayName64(_L("multArray"));
	for (ii=0; ii<sizeMult-1; ii++)
		{
		ff=multInput[ii]*multInput[ii+1];
		appendValue64(&ff);
		}
	appendArrayTerm();
	} 

LOCAL_C void createDivArray()
//
// Writes an array of results of divisions to the header file
//
	{
	TInt ii;
	TReal64 ff;

	appendArrayName64(_L("divArray"));
	for (ii=0; ii<sizeDiv-1; ii++)
		{
		if (divInput[ii+1]!=0)
			{
			ff=divInput[ii]/divInput[ii+1];
			appendValue64(&ff);
			}
		}
	appendArrayTerm();
	} 

LOCAL_C void createUnaryArray()
//
// Writes an array of results of unary operations to the header file
//
	{
	TReal64 f;

	appendArrayName64(_L("unaryArray"));
	for (TInt ii=0; ii<sizeUnary; ii++)
		{
		f=-unaryInput[ii];
		appendValue64(&f);
		}
	appendArrayTerm();
	} 

LOCAL_C void createIncDecArrays()
//
// Writes an array of results of pre and post increment and decrement operations to the
// header file
//
	{
	TInt ii;
	TReal64 f;

	// Generate arrays for exact tests

	appendArrayName64(_L("preIncArray1"));
	for (ii=0; ii<sizeIncDec; ii++)
		{
		f=incDecInput[ii];
		++f;
		appendValue64(&f);
		}
	appendArrayTerm();

	appendArrayName64(_L("preIncArray2"));
	for (ii=0; ii<sizeIncDec; ii++)
		{
		f=incDecInput[ii];
		++f;
		++f;
		appendValue64(&f);
		}
	appendArrayTerm();

	appendArrayName64(_L("preDecArray1"));
	for (ii=0; ii<sizeIncDec; ii++)
		{
		f=incDecInput[ii];
		--f;
		appendValue64(&f);
		}
	appendArrayTerm();

	appendArrayName64(_L("preDecArray2"));
	for (ii=0; ii<sizeIncDec; ii++)
		{
		f=incDecInput[ii];
		--f;
		--f;
		appendValue64(&f);
		}
	appendArrayTerm();

	appendArrayName64(_L("postIncArray1"));
	for (ii=0; ii<sizeIncDec; ii++)
		{
		f=incDecInput[ii];
		f++;
		appendValue64(&f);
		}
	appendArrayTerm();

	appendArrayName64(_L("postIncArray2"));
	for (ii=0; ii<sizeIncDec; ii++)
		{
		f=incDecInput[ii];
		f++;
		f++;
		appendValue64(&f);
		}
	appendArrayTerm();

	appendArrayName64(_L("postDecArray1"));
	for (ii=0; ii<sizeIncDec; ii++)
		{
		f=incDecInput[ii];
		f--;
		appendValue64(&f);
		}
	appendArrayTerm();
	
	appendArrayName64(_L("postDecArray2"));
	for (ii=0; ii<sizeIncDec; ii++)
		{
		f=incDecInput[ii];
		f--;
		f--;
		appendValue64(&f);
		}
	appendArrayTerm();
	} 

LOCAL_C void createArrays()
//
// Create and append to header file all arrays required for T_R64.CPP tests
//
	{
	createAddArray();
	createSubArray();
	createMultArray();
	createDivArray();
	createUnaryArray();
	createIncDecArrays();
	}
#endif

GLDEF_C void CallTestsL(void)
//
// Generate TReal64s (and special values if required) and write to header files
//
    {

	test.Title();

#ifdef __GENERATE_TR64
	TFileName msg;
	msg=_L("Generating Maths constants to header files:\n ");
	msg+=pathName;
	msg+=fileNameW64;
	msg+=_L(" and ");
	msg+=fileNameA64;
	test.Start(msg);
#endif

	TInt r=TheFs.MkDirAll(pathName);
	test(r==KErrNone || r==KErrAlreadyExists);
	test(TheFs.SetSessionPath(pathName)==KErrNone);

#ifdef __GENERATE_TR64
	test(fw.Replace(TheFs,fileNameW64,EFileWrite)==KErrNone);
	test(fa.Replace(TheFs,fileNameA64,EFileWrite)==KErrNone);
	test.Next(_L("Generating TReal64s"));
	fw.Write(_L("// Generated by \\E32\\TMATH\\T_GEN.MAK for WINS (little-endian doubles)\n\n"));
	fa.Write(_L("// Generated by \\E32\\TMATH\\T_GEN.MAK for ARM (big-endian doubles)\n\n"));
	createArrays();
	fw.Close();
	fa.Close();
#endif

#ifdef __GENERATE_SPECIAL_VALUES
	test(fspw.Replace(TheFs,fileNameWSp,EFileWrite)==KErrNone);
	test(fspa.Replace(TheFs,fileNameASp,EFileWrite)==KErrNone);
	test.Start(_L("Generate header file of special values for use in maths testing"));
	generateSpecialValues();
	test.Next(_L("Done - now closing files"));
	fspw.Close();
	fspa.Close();
#endif


	test.End();

	return;
    }