diff -r 000000000000 -r a41df078684a kerneltest/e32test/system/t_atomic.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/system/t_atomic.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,1622 @@ +// Copyright (c) 2008-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: +// e32test\system\t_atomic.cpp +// +// + +#define __E32TEST_EXTENSION__ + +#include +#include +#include +#include "u32std.h" +#include +#include + +RTest test(_L("T_ATOMIC")); + +#include "t_atomic.h" + +#ifdef __EPOC32__ +RTestAtomic DD; +#endif + +extern "C" { +extern const char* FuncName[]; +extern const PFV AtomicFuncPtr[]; +extern const PFV ControlFuncPtr[]; +extern const TUint FuncAttr[]; +} + +class TestOverflowTruncate2 : public TDes16Overflow + { +public: + virtual void Overflow(TDes16 &aDes); + }; + +void TestOverflowTruncate2::Overflow(TDes16& /*aDes*/) + { + } + +void UPrintf(const char* aFmt, ...) + { + // Print to a console screen. + TestOverflowTruncate2 overflow; + VA_LIST list; + VA_START(list, aFmt); + TBuf8<256> fmtBuf8((const TUint8*)aFmt); + TBuf<256> buf; + buf.AppendFormatList(fmtBuf8.Expand(), list, &overflow); + test.Printf(_L("%S\n"),&buf); + } + +/****************************************************************************** + * Single thread normal operation tests + ******************************************************************************/ +template +struct TD + { + T i0; + T i1; + T i2; + T i3; + TInt iF; + TInt iPadding; + }; + +struct TDG : public TDGBase + { + void Set(const TD aTD8, TInt aOrd); + void Set(const TD aTD16, TInt aOrd); + void Set(const TD aTD32, TInt aOrd); + void Set(const TD aTD64, TInt aOrd); + + TInt ExecuteUser(); + TInt ExecuteKernel(); + }; + +TInt GetAtomicFuncIndex(TInt aFunc, TInt aSize, TInt aOrd) + { + test_NotNegative(aFunc); + test_Compare(aFunc,<,EAtomicFuncN); + test_NotNegative(aOrd); + test_Compare(aOrd,<,4); + aFunc *= 4; + switch(aSize) + { + case 1: break; + case 2: aFunc += INDEXES_PER_SIZE; break; + case 4: aFunc += 2*INDEXES_PER_SIZE; break; + case 8: aFunc += 3*INDEXES_PER_SIZE; break; + default: test_Equal(8,aSize); break; + } + aFunc += aOrd; + if (AtomicFuncPtr[aFunc]) + return aFunc; + return -1; + } + +void TDG::Set(const TD aTD8, TInt aOrd) + { + i0 = aTD8.i0; + i1 = aTD8.i1; + i2 = aTD8.i2; + i3 = aTD8.i3; + iIndex = GetAtomicFuncIndex(aTD8.iF, 1, aOrd); +#ifdef __EXTRA_DEBUG__ + DEBUGPRINT(" 8: iF=%2d aOrd=%1d -> %d", aTD8.iF, aOrd, iIndex); +#endif + } + +void TDG::Set(const TD aTD16, TInt aOrd) + { + i0 = aTD16.i0; + i1 = aTD16.i1; + i2 = aTD16.i2; + i3 = aTD16.i3; + iIndex = GetAtomicFuncIndex(aTD16.iF, 2, aOrd); +#ifdef __EXTRA_DEBUG__ + DEBUGPRINT("16: iF=%2d aOrd=%1d -> %d", aTD16.iF, aOrd, iIndex); +#endif + } + +void TDG::Set(const TD aTD32, TInt aOrd) + { + i0 = aTD32.i0; + i1 = aTD32.i1; + i2 = aTD32.i2; + i3 = aTD32.i3; + iIndex = GetAtomicFuncIndex(aTD32.iF, 4, aOrd); +#ifdef __EXTRA_DEBUG__ + DEBUGPRINT("32: iF=%2d aOrd=%1d -> %d", aTD32.iF, aOrd, iIndex); +#endif + } + +void TDG::Set(const TD aTD64, TInt aOrd) + { + i0 = aTD64.i0; + i1 = aTD64.i1; + i2 = aTD64.i2; + i3 = aTD64.i3; + iIndex = GetAtomicFuncIndex(aTD64.iF, 8, aOrd); +#ifdef __EXTRA_DEBUG__ + DEBUGPRINT("64: iF=%2d aOrd=%1d -> %d", aTD64.iF, aOrd, iIndex); +#endif + } + +TInt TDG::ExecuteUser() + { + return Execute(); + } + +#ifdef __EPOC32__ +TInt TDG::ExecuteKernel() + { + return DD.TDGExecuteK(*this); + } +#endif + + +#define DCL_TEST_BLOCK(type,name) \ + static const TD name[] = +#define DCL_TEST1(type,func,a0) \ + { (type)(a0), (type)(0), (type)(0), (type)(0), (EAtomicFunc##func), 0 } +#define DCL_TEST2(type,func,a0,a1) \ + { (type)(a0), (type)(a1), (type)(0), (type)(0), (EAtomicFunc##func), 0 } +#define DCL_TEST3(type,func,a0,a1,a2) \ + { (type)(a0), (type)(a1), (type)(a2), (type)(0), (EAtomicFunc##func), 0 } +#define DCL_TEST4(type,func,a0,a1,a2,a3) \ + { (type)(a0), (type)(a1), (type)(a2), (type)(a3), (EAtomicFunc##func), 0 } + +DCL_TEST_BLOCK(TUint8,TestData8) + { + DCL_TEST1(TUint8, LOAD, 0x00), + DCL_TEST1(TUint8, LOAD, 0xFF), + + DCL_TEST2(TUint8, STORE, 0xBB, 0x00), + DCL_TEST2(TUint8, STORE, 0xBB, 0xFF), + + DCL_TEST2(TUint8, SWP, 0xBB, 0x00), + DCL_TEST2(TUint8, SWP, 0xBB, 0xFF), + DCL_TEST2(TUint8, SWP, 0x55, 0x00), + DCL_TEST2(TUint8, SWP, 0x55, 0xFF), + + DCL_TEST2(TUint8, ADD, 0x00, 0x01), + DCL_TEST2(TUint8, ADD, 0xFF, 0x01), + DCL_TEST2(TUint8, ADD, 0xFE, 0x01), + DCL_TEST2(TUint8, ADD, 0xFE, 0x02), + DCL_TEST2(TUint8, ADD, 0xFE, 0x03), + DCL_TEST2(TUint8, ADD, 0x12, 0x23), + + DCL_TEST2(TUint8, AND, 0x00, 0x01), + DCL_TEST2(TUint8, AND, 0xFF, 0x01), + DCL_TEST2(TUint8, AND, 0xFE, 0x01), + DCL_TEST2(TUint8, AND, 0xFE, 0xFF), + DCL_TEST2(TUint8, AND, 0xFE, 0x03), + DCL_TEST2(TUint8, AND, 0x5F, 0xAF), + + DCL_TEST2(TUint8, IOR, 0x00, 0x01), + DCL_TEST2(TUint8, IOR, 0xFF, 0x01), + DCL_TEST2(TUint8, IOR, 0xFE, 0x01), + DCL_TEST2(TUint8, IOR, 0x0D, 0x5F), + DCL_TEST2(TUint8, IOR, 0x30, 0x03), + DCL_TEST2(TUint8, IOR, 0x5F, 0xAF), + + DCL_TEST2(TUint8, XOR, 0x00, 0x01), + DCL_TEST2(TUint8, XOR, 0xFF, 0x01), + DCL_TEST2(TUint8, XOR, 0xFE, 0x01), + DCL_TEST2(TUint8, XOR, 0xFE, 0xFF), + DCL_TEST2(TUint8, XOR, 0xFE, 0x03), + DCL_TEST2(TUint8, XOR, 0x5F, 0xAF), + + DCL_TEST3(TUint8, AXO, 0x00, 0xFF, 0x00), + DCL_TEST3(TUint8, AXO, 0x00, 0xFF, 0x33), + DCL_TEST3(TUint8, AXO, 0x00, 0xFF, 0x7D), + DCL_TEST3(TUint8, AXO, 0x00, 0xFF, 0xBB), + DCL_TEST3(TUint8, AXO, 0xAA, 0x00, 0x00), + DCL_TEST3(TUint8, AXO, 0xAA, 0x00, 0x33), + DCL_TEST3(TUint8, AXO, 0xAA, 0x00, 0x7D), + DCL_TEST3(TUint8, AXO, 0xAA, 0x00, 0xBB), + DCL_TEST3(TUint8, AXO, 0xAA, 0x33, 0xF0), + DCL_TEST3(TUint8, AXO, 0xAA, 0x33, 0x0F), + DCL_TEST3(TUint8, AXO, 0xAA, 0xCC, 0xF0), + DCL_TEST3(TUint8, AXO, 0xAA, 0xCC, 0x0F), + + DCL_TEST3(TUint8, CAS, 0x00, 0xFF, 0xEE), + DCL_TEST3(TUint8, CAS, 0x00, 0x01, 0x11), + DCL_TEST3(TUint8, CAS, 0x00, 0x00, 0xEE), + DCL_TEST3(TUint8, CAS, 0x00, 0x00, 0x23), + DCL_TEST3(TUint8, CAS, 0x2A, 0xFF, 0x2B), + DCL_TEST3(TUint8, CAS, 0x2A, 0x01, 0x2B), + DCL_TEST3(TUint8, CAS, 0x2A, 0x2A, 0x2B), + DCL_TEST3(TUint8, CAS, 0x2A, 0x2A, 0x3B), + + DCL_TEST4(TUint8, TAU, 0x00, 0x00, 0x02, 0x03), + DCL_TEST4(TUint8, TAU, 0x01, 0x00, 0x02, 0x03), + DCL_TEST4(TUint8, TAU, 0xFF, 0x00, 0x02, 0x03), + DCL_TEST4(TUint8, TAU, 0x00, 0x01, 0x02, 0x03), + DCL_TEST4(TUint8, TAU, 0x01, 0x01, 0x02, 0x03), + DCL_TEST4(TUint8, TAU, 0x02, 0x01, 0x02, 0x03), + DCL_TEST4(TUint8, TAU, 0xFF, 0x01, 0x02, 0x03), + DCL_TEST4(TUint8, TAU, 0xFE, 0xFE, 0x23, 0x0B), + DCL_TEST4(TUint8, TAU, 0xEE, 0xFE, 0x23, 0x0B), + DCL_TEST4(TUint8, TAU, 0xFF, 0xFE, 0x23, 0x0B), + DCL_TEST4(TUint8, TAU, 0x00, 0xFE, 0x23, 0x0B), + DCL_TEST4(TUint8, TAU, 0xFE, 0xFE, 0x80, 0x7F), + DCL_TEST4(TUint8, TAU, 0xEE, 0xFE, 0x80, 0x7F), + DCL_TEST4(TUint8, TAU, 0xFF, 0xFE, 0x80, 0x7F), + DCL_TEST4(TUint8, TAU, 0x00, 0xFE, 0x80, 0x7F), + DCL_TEST4(TUint8, TAU, 0xFE, 0x80, 0x81, 0x7E), + DCL_TEST4(TUint8, TAU, 0x7F, 0x80, 0x81, 0x7E), + DCL_TEST4(TUint8, TAU, 0x80, 0x80, 0x81, 0x7E), + DCL_TEST4(TUint8, TAU, 0x81, 0x80, 0x81, 0x7E), + DCL_TEST4(TUint8, TAU, 0x00, 0x80, 0x81, 0x7E), + DCL_TEST4(TUint8, TAU, 0x7E, 0x7F, 0x81, 0x7E), + DCL_TEST4(TUint8, TAU, 0x7F, 0x7F, 0x81, 0x7E), + DCL_TEST4(TUint8, TAU, 0x80, 0x7F, 0x81, 0x7E), + DCL_TEST4(TUint8, TAU, 0x81, 0x7F, 0x81, 0x7E), + DCL_TEST4(TUint8, TAU, 0x00, 0x7F, 0x81, 0x7E), + + DCL_TEST4(TUint8, TAS, 0x00, 0x00, 0x02, 0x03), + DCL_TEST4(TUint8, TAS, 0x01, 0x00, 0x02, 0x03), + DCL_TEST4(TUint8, TAS, 0xFF, 0x00, 0x02, 0x03), + DCL_TEST4(TUint8, TAS, 0x00, 0x01, 0x02, 0x03), + DCL_TEST4(TUint8, TAS, 0x01, 0x01, 0x02, 0x03), + DCL_TEST4(TUint8, TAS, 0x02, 0x01, 0x02, 0x03), + DCL_TEST4(TUint8, TAS, 0xFF, 0x01, 0x02, 0x03), + DCL_TEST4(TUint8, TAS, 0xFE, 0xFE, 0x23, 0x0B), + DCL_TEST4(TUint8, TAS, 0xEE, 0xFE, 0x23, 0x0B), + DCL_TEST4(TUint8, TAS, 0xFF, 0xFE, 0x23, 0x0B), + DCL_TEST4(TUint8, TAS, 0x00, 0xFE, 0x23, 0x0B), + DCL_TEST4(TUint8, TAS, 0xFE, 0xFE, 0x80, 0x7F), + DCL_TEST4(TUint8, TAS, 0xEE, 0xFE, 0x80, 0x7F), + DCL_TEST4(TUint8, TAS, 0xFF, 0xFE, 0x80, 0x7F), + DCL_TEST4(TUint8, TAS, 0x00, 0xFE, 0x80, 0x7F), + DCL_TEST4(TUint8, TAS, 0xFE, 0x80, 0x81, 0x7E), + DCL_TEST4(TUint8, TAS, 0x7F, 0x80, 0x81, 0x7E), + DCL_TEST4(TUint8, TAS, 0x80, 0x80, 0x81, 0x7E), + DCL_TEST4(TUint8, TAS, 0x81, 0x80, 0x81, 0x7E), + DCL_TEST4(TUint8, TAS, 0x00, 0x80, 0x81, 0x7E), + DCL_TEST4(TUint8, TAS, 0x7E, 0x7F, 0x81, 0x7E), + DCL_TEST4(TUint8, TAS, 0x7F, 0x7F, 0x81, 0x7E), + DCL_TEST4(TUint8, TAS, 0x80, 0x7F, 0x81, 0x7E), + DCL_TEST4(TUint8, TAS, 0x81, 0x7F, 0x81, 0x7E), + DCL_TEST4(TUint8, TAS, 0x00, 0x7F, 0x81, 0x7E) + }; + +DCL_TEST_BLOCK(TUint16,TestData16) + { + DCL_TEST1(TUint16, LOAD, 0x0055), + DCL_TEST1(TUint16, LOAD, 0xFFAA), + + DCL_TEST2(TUint16, STORE, 0xBBBB, 0x0055), + DCL_TEST2(TUint16, STORE, 0xBBBB, 0xFFAA), + + DCL_TEST2(TUint16, SWP, 0xBBCC, 0x0055), + DCL_TEST2(TUint16, SWP, 0xBBCC, 0xFFAA), + DCL_TEST2(TUint16, SWP, 0x55AA, 0x0033), + DCL_TEST2(TUint16, SWP, 0x55AA, 0xFFCC), + + DCL_TEST2(TUint16, ADD, 0x0000, 0x0001), + DCL_TEST2(TUint16, ADD, 0xFFFF, 0x0001), + DCL_TEST2(TUint16, ADD, 0xFFFE, 0x0001), + DCL_TEST2(TUint16, ADD, 0xFFFE, 0x0002), + DCL_TEST2(TUint16, ADD, 0xFFFE, 0x0003), + DCL_TEST2(TUint16, ADD, 0x0012, 0x0023), + DCL_TEST2(TUint16, ADD, 0x0012, 0xBCFF), + + DCL_TEST2(TUint16, AND, 0x0000, 0x0001), + DCL_TEST2(TUint16, AND, 0xFFFF, 0x0001), + DCL_TEST2(TUint16, AND, 0xFFFE, 0x0001), + DCL_TEST2(TUint16, AND, 0xFFFE, 0xFFFF), + DCL_TEST2(TUint16, AND, 0xFFFE, 0x0F03), + DCL_TEST2(TUint16, AND, 0xBC5F, 0x14AF), + + DCL_TEST2(TUint16, IOR, 0x0000, 0x0001), + DCL_TEST2(TUint16, IOR, 0xFFFF, 0x0001), + DCL_TEST2(TUint16, IOR, 0xFFFE, 0x0001), + DCL_TEST2(TUint16, IOR, 0x000D, 0x005F), + DCL_TEST2(TUint16, IOR, 0x8030, 0x0803), + DCL_TEST2(TUint16, IOR, 0x145F, 0x56AF), + + DCL_TEST2(TUint16, XOR, 0x0000, 0x0001), + DCL_TEST2(TUint16, XOR, 0xFFFF, 0x0001), + DCL_TEST2(TUint16, XOR, 0xFFFE, 0x0001), + DCL_TEST2(TUint16, XOR, 0xFFFE, 0xFFFF), + DCL_TEST2(TUint16, XOR, 0xFFFE, 0x0003), + DCL_TEST2(TUint16, XOR, 0x145F, 0xBCAF), + + DCL_TEST3(TUint16, AXO, 0x0000, 0xFFFF, 0x0000), + DCL_TEST3(TUint16, AXO, 0x0000, 0xFFFF, 0x6633), + DCL_TEST3(TUint16, AXO, 0x0000, 0xFFFF, 0x827D), + DCL_TEST3(TUint16, AXO, 0x0000, 0xFFFF, 0xCCBB), + DCL_TEST3(TUint16, AXO, 0xAAAA, 0x0000, 0x0000), + DCL_TEST3(TUint16, AXO, 0xAAAA, 0x0000, 0x6633), + DCL_TEST3(TUint16, AXO, 0xAAAA, 0x0000, 0x827D), + DCL_TEST3(TUint16, AXO, 0xAAAA, 0x0000, 0xCCBB), + DCL_TEST3(TUint16, AXO, 0xAAAA, 0xCC33, 0x0FF0), + DCL_TEST3(TUint16, AXO, 0xAAAA, 0xCC33, 0xF00F), + DCL_TEST3(TUint16, AXO, 0xAAAA, 0x33CC, 0x0FF0), + DCL_TEST3(TUint16, AXO, 0xAAAA, 0x33CC, 0xF00F), + + DCL_TEST3(TUint16, CAS, 0x0000, 0x00FF, 0x99EE), + DCL_TEST3(TUint16, CAS, 0x0000, 0x0001, 0x7711), + DCL_TEST3(TUint16, CAS, 0x0000, 0x0000, 0x99EE), + DCL_TEST3(TUint16, CAS, 0x0000, 0x0000, 0x1123), + DCL_TEST3(TUint16, CAS, 0x832A, 0xFFFF, 0x832B), + DCL_TEST3(TUint16, CAS, 0x832A, 0x0001, 0x832B), + DCL_TEST3(TUint16, CAS, 0x832A, 0x822A, 0x832B), + DCL_TEST3(TUint16, CAS, 0x832A, 0x832B, 0x943B), + DCL_TEST3(TUint16, CAS, 0x832A, 0x832A, 0x832B), + DCL_TEST3(TUint16, CAS, 0x832A, 0x832A, 0x943B), + + DCL_TEST4(TUint16, TAU, 0x0000, 0x0000, 0x0002, 0x0003), + DCL_TEST4(TUint16, TAU, 0x0001, 0x0000, 0x0002, 0x0003), + DCL_TEST4(TUint16, TAU, 0xFFFF, 0x0000, 0x0002, 0x0003), + DCL_TEST4(TUint16, TAU, 0x0000, 0x0001, 0x0002, 0x0003), + DCL_TEST4(TUint16, TAU, 0x0001, 0x0001, 0x0002, 0x0003), + DCL_TEST4(TUint16, TAU, 0x0002, 0x0001, 0x0002, 0x0003), + DCL_TEST4(TUint16, TAU, 0xFFFF, 0x0001, 0x0002, 0x0003), + DCL_TEST4(TUint16, TAU, 0xFFFE, 0xFFFE, 0x1023, 0x000B), + DCL_TEST4(TUint16, TAU, 0xFFEE, 0xFFFE, 0x1423, 0x000B), + DCL_TEST4(TUint16, TAU, 0xFFFF, 0xFFFE, 0x1423, 0x000B), + DCL_TEST4(TUint16, TAU, 0x0000, 0xFFFE, 0x1423, 0x000B), + DCL_TEST4(TUint16, TAU, 0xFFFE, 0xFFFE, 0x8000, 0x7FFF), + DCL_TEST4(TUint16, TAU, 0xFFEE, 0xFFFE, 0x8000, 0x7FFF), + DCL_TEST4(TUint16, TAU, 0xFFFF, 0xFFFE, 0x8000, 0x7FFF), + DCL_TEST4(TUint16, TAU, 0x0000, 0xFFFE, 0x8000, 0x7FFF), + DCL_TEST4(TUint16, TAU, 0xFFFE, 0x8000, 0x8001, 0x7FFE), + DCL_TEST4(TUint16, TAU, 0x7FFF, 0x8000, 0x8001, 0x7FFE), + DCL_TEST4(TUint16, TAU, 0x8000, 0x8000, 0x8001, 0x7FFE), + DCL_TEST4(TUint16, TAU, 0x8001, 0x8000, 0x8001, 0x7FFE), + DCL_TEST4(TUint16, TAU, 0x0000, 0x8000, 0x8001, 0x7FFE), + DCL_TEST4(TUint16, TAU, 0x7FFE, 0x7FFF, 0x8001, 0x7FFE), + DCL_TEST4(TUint16, TAU, 0x7FFF, 0x7FFF, 0x8001, 0x7FFE), + DCL_TEST4(TUint16, TAU, 0x8000, 0x7FFF, 0x8001, 0x7FFE), + DCL_TEST4(TUint16, TAU, 0x8001, 0x7FFF, 0x8001, 0x7FFE), + DCL_TEST4(TUint16, TAU, 0x0000, 0x7FFF, 0x8001, 0x7FFE), + + DCL_TEST4(TUint16, TAS, 0x0000, 0x0000, 0x0002, 0x0003), + DCL_TEST4(TUint16, TAS, 0x0001, 0x0000, 0x0002, 0x0003), + DCL_TEST4(TUint16, TAS, 0xFFFF, 0x0000, 0x0002, 0x0003), + DCL_TEST4(TUint16, TAS, 0x0000, 0x0001, 0x0002, 0x0003), + DCL_TEST4(TUint16, TAS, 0x0001, 0x0001, 0x0002, 0x0003), + DCL_TEST4(TUint16, TAS, 0x0002, 0x0001, 0x0002, 0x0003), + DCL_TEST4(TUint16, TAS, 0xFFFF, 0x0001, 0x0002, 0x0003), + DCL_TEST4(TUint16, TAS, 0xFFFE, 0xFFFE, 0x1023, 0x000B), + DCL_TEST4(TUint16, TAS, 0xFFEE, 0xFFFE, 0x1423, 0x000B), + DCL_TEST4(TUint16, TAS, 0xFFFF, 0xFFFE, 0x1423, 0x000B), + DCL_TEST4(TUint16, TAS, 0x0000, 0xFFFE, 0x1423, 0x000B), + DCL_TEST4(TUint16, TAS, 0xFFFE, 0xFFFE, 0x8000, 0x7FFF), + DCL_TEST4(TUint16, TAS, 0xFFEE, 0xFFFE, 0x8000, 0x7FFF), + DCL_TEST4(TUint16, TAS, 0xFFFF, 0xFFFE, 0x8000, 0x7FFF), + DCL_TEST4(TUint16, TAS, 0x0000, 0xFFFE, 0x8000, 0x7FFF), + DCL_TEST4(TUint16, TAS, 0xFFFE, 0x8000, 0x8001, 0x7FFE), + DCL_TEST4(TUint16, TAS, 0x7FFF, 0x8000, 0x8001, 0x7FFE), + DCL_TEST4(TUint16, TAS, 0x8000, 0x8000, 0x8001, 0x7FFE), + DCL_TEST4(TUint16, TAS, 0x8001, 0x8000, 0x8001, 0x7FFE), + DCL_TEST4(TUint16, TAS, 0x0000, 0x8000, 0x8001, 0x7FFE), + DCL_TEST4(TUint16, TAS, 0x7FFE, 0x7FFF, 0x8001, 0x7FFE), + DCL_TEST4(TUint16, TAS, 0x7FFF, 0x7FFF, 0x8001, 0x7FFE), + DCL_TEST4(TUint16, TAS, 0x8000, 0x7FFF, 0x8001, 0x7FFE), + DCL_TEST4(TUint16, TAS, 0x8001, 0x7FFF, 0x8001, 0x7FFE), + DCL_TEST4(TUint16, TAS, 0x0000, 0x7FFF, 0x8001, 0x7FFE) + }; + +DCL_TEST_BLOCK(TUint32,TestData32) + { + DCL_TEST1(TUint32, LOAD, 0x00334455), + DCL_TEST1(TUint32, LOAD, 0xFFCCBBAA), + + DCL_TEST2(TUint32, STORE, 0xBBBBBBBB, 0x00334455), + DCL_TEST2(TUint32, STORE, 0xBBBBBBBB, 0xFFCCBBAA), + + DCL_TEST2(TUint32, SWP, 0xBB1234CC, 0x00EDCB55), + DCL_TEST2(TUint32, SWP, 0xBB1234CC, 0xFF9876AA), + DCL_TEST2(TUint32, SWP, 0x551971AA, 0x00112233), + DCL_TEST2(TUint32, SWP, 0x551971AA, 0xFFEEDDCC), + + DCL_TEST2(TUint32, ADD, 0x00000000, 0x00000001), + DCL_TEST2(TUint32, ADD, 0xFFFFFFFF, 0x00000001), + DCL_TEST2(TUint32, ADD, 0xFFFFFFFE, 0x00000001), + DCL_TEST2(TUint32, ADD, 0xFFFFFFFE, 0x00000002), + DCL_TEST2(TUint32, ADD, 0xFFFFFFFE, 0x00000003), + DCL_TEST2(TUint32, ADD, 0x00009912, 0x00000023), + DCL_TEST2(TUint32, ADD, 0x00009912, 0x4937BCFF), + + DCL_TEST2(TUint32, AND, 0x00000000, 0x00000001), + DCL_TEST2(TUint32, AND, 0xFFFFFFFF, 0x00000001), + DCL_TEST2(TUint32, AND, 0xFFFFFFFE, 0x00000001), + DCL_TEST2(TUint32, AND, 0xFFFFFFFE, 0xFFFFFFFF), + DCL_TEST2(TUint32, AND, 0xFFFFFFFE, 0x00000F03), + DCL_TEST2(TUint32, AND, 0xEDCBBC5F, 0xDCBA14AF), + + DCL_TEST2(TUint32, IOR, 0x00000000, 0x00000001), + DCL_TEST2(TUint32, IOR, 0xFFFFFFFF, 0x00000001), + DCL_TEST2(TUint32, IOR, 0xFFFFFFFE, 0x00000001), + DCL_TEST2(TUint32, IOR, 0x0000000D, 0x0000005F), + DCL_TEST2(TUint32, IOR, 0x80000030, 0x00000803), + DCL_TEST2(TUint32, IOR, 0x89AB145F, 0x415256AF), + + DCL_TEST2(TUint32, XOR, 0x00000000, 0x00000001), + DCL_TEST2(TUint32, XOR, 0xFFFFFFFF, 0x00000001), + DCL_TEST2(TUint32, XOR, 0xFFFFFFFE, 0x00000001), + DCL_TEST2(TUint32, XOR, 0xFFFFFFFE, 0xFFFFFFFF), + DCL_TEST2(TUint32, XOR, 0xFFFFFFFE, 0x00000003), + DCL_TEST2(TUint32, XOR, 0x89AB145F, 0x4152BCAF), + + DCL_TEST3(TUint32, AXO, 0x00000000, 0xFFFFFFFF, 0x00000000), + DCL_TEST3(TUint32, AXO, 0x00000000, 0xFFFFFFFF, 0x99CC6633), + DCL_TEST3(TUint32, AXO, 0x00000000, 0xFFFFFFFF, 0x8000027D), + DCL_TEST3(TUint32, AXO, 0x00000000, 0xFFFFFFFF, 0xEEDDCCBB), + DCL_TEST3(TUint32, AXO, 0xAAAAAAAA, 0x00000000, 0x00000000), + DCL_TEST3(TUint32, AXO, 0xAAAAAAAA, 0x00000000, 0x99CC6633), + DCL_TEST3(TUint32, AXO, 0xAAAAAAAA, 0x00000000, 0x8000027D), + DCL_TEST3(TUint32, AXO, 0xAAAAAAAA, 0x00000000, 0xEEDDCCBB), + DCL_TEST3(TUint32, AXO, 0xAAAAAAAA, 0x9966CC33, 0x0FF00FF0), + DCL_TEST3(TUint32, AXO, 0xAAAAAAAA, 0x9966CC33, 0xF00FF00F), + DCL_TEST3(TUint32, AXO, 0xAAAAAAAA, 0x669933CC, 0x0FF00FF0), + DCL_TEST3(TUint32, AXO, 0xAAAAAAAA, 0x669933CC, 0xF00FF00F), + + DCL_TEST3(TUint32, CAS, 0x00000000, 0x000000FF, 0x99ABCDEE), + DCL_TEST3(TUint32, CAS, 0x00000000, 0x00000001, 0x7FFFF711), + DCL_TEST3(TUint32, CAS, 0x00000000, 0x00000000, 0x99ABCDEE), + DCL_TEST3(TUint32, CAS, 0x00000000, 0x00000000, 0x11234567), + DCL_TEST3(TUint32, CAS, 0x8000032A, 0xFFFFFFFF, 0x8000032B), + DCL_TEST3(TUint32, CAS, 0x8000032A, 0x00000001, 0x8000032B), + DCL_TEST3(TUint32, CAS, 0x8000032A, 0x8000022A, 0x8000032B), + DCL_TEST3(TUint32, CAS, 0x8000032A, 0x8000032B, 0x943BFCD1), + DCL_TEST3(TUint32, CAS, 0x8000032A, 0x8000032A, 0x8000032B), + DCL_TEST3(TUint32, CAS, 0x8000032A, 0x8000032A, 0x943BFCD1), + + DCL_TEST4(TUint32, TAU, 0x00000000, 0x00000000, 0x00000002, 0x00000003), + DCL_TEST4(TUint32, TAU, 0x00000001, 0x00000000, 0x00000002, 0x00000003), + DCL_TEST4(TUint32, TAU, 0xFFFFFFFF, 0x00000000, 0x00000002, 0x00000003), + DCL_TEST4(TUint32, TAU, 0x00000000, 0x00000001, 0x00000002, 0x00000003), + DCL_TEST4(TUint32, TAU, 0x00000001, 0x00000001, 0x00000002, 0x00000003), + DCL_TEST4(TUint32, TAU, 0x00000002, 0x00000001, 0x00000002, 0x00000003), + DCL_TEST4(TUint32, TAU, 0xFFFFFFFF, 0x00000001, 0x00000002, 0x00000003), + DCL_TEST4(TUint32, TAU, 0xFFFFFFFE, 0xFFFFFFFE, 0x1023144F, 0x0000000B), + DCL_TEST4(TUint32, TAU, 0xFFFFFFEE, 0xFFFFFFFE, 0x1423144F, 0x0000000B), + DCL_TEST4(TUint32, TAU, 0xFFFFFFFF, 0xFFFFFFFE, 0x1423144F, 0x0000000B), + DCL_TEST4(TUint32, TAU, 0x00000000, 0xFFFFFFFE, 0x1423144F, 0x0000000B), + DCL_TEST4(TUint32, TAU, 0xFFFFFFFE, 0xFFFFFFFE, 0x80000000, 0x7FFFFFFF), + DCL_TEST4(TUint32, TAU, 0xFFFFFFEE, 0xFFFFFFFE, 0x80000000, 0x7FFFFFFF), + DCL_TEST4(TUint32, TAU, 0xFFFFFFFF, 0xFFFFFFFE, 0x80000000, 0x7FFFFFFF), + DCL_TEST4(TUint32, TAU, 0x00000000, 0xFFFFFFFE, 0x80000000, 0x7FFFFFFF), + DCL_TEST4(TUint32, TAU, 0xFFFFFFFE, 0x80000000, 0x80000001, 0x7FFFFFFE), + DCL_TEST4(TUint32, TAU, 0x7FFFFFFF, 0x80000000, 0x80000001, 0x7FFFFFFE), + DCL_TEST4(TUint32, TAU, 0x80000000, 0x80000000, 0x80000001, 0x7FFFFFFE), + DCL_TEST4(TUint32, TAU, 0x80000001, 0x80000000, 0x80000001, 0x7FFFFFFE), + DCL_TEST4(TUint32, TAU, 0x00000000, 0x80000000, 0x80000001, 0x7FFFFFFE), + DCL_TEST4(TUint32, TAU, 0x7FFFFFFE, 0x7FFFFFFF, 0x80000001, 0x7FFFFFFE), + DCL_TEST4(TUint32, TAU, 0x7FFFFFFF, 0x7FFFFFFF, 0x80000001, 0x7FFFFFFE), + DCL_TEST4(TUint32, TAU, 0x80000000, 0x7FFFFFFF, 0x80000001, 0x7FFFFFFE), + DCL_TEST4(TUint32, TAU, 0x80000001, 0x7FFFFFFF, 0x80000001, 0x7FFFFFFE), + DCL_TEST4(TUint32, TAU, 0x00000000, 0x7FFFFFFF, 0x80000001, 0x7FFFFFFE), + + DCL_TEST4(TUint32, TAS, 0x00000000, 0x00000000, 0x00000002, 0x00000003), + DCL_TEST4(TUint32, TAS, 0x00000001, 0x00000000, 0x00000002, 0x00000003), + DCL_TEST4(TUint32, TAS, 0xFFFFFFFF, 0x00000000, 0x00000002, 0x00000003), + DCL_TEST4(TUint32, TAS, 0x00000000, 0x00000001, 0x00000002, 0x00000003), + DCL_TEST4(TUint32, TAS, 0x00000001, 0x00000001, 0x00000002, 0x00000003), + DCL_TEST4(TUint32, TAS, 0x00000002, 0x00000001, 0x00000002, 0x00000003), + DCL_TEST4(TUint32, TAS, 0xFFFFFFFF, 0x00000001, 0x00000002, 0x00000003), + DCL_TEST4(TUint32, TAS, 0xFFFFFFFE, 0xFFFFFFFE, 0x1023144F, 0x0000000B), + DCL_TEST4(TUint32, TAS, 0xFFFFFFEE, 0xFFFFFFFE, 0x1423144F, 0x0000000B), + DCL_TEST4(TUint32, TAS, 0xFFFFFFFF, 0xFFFFFFFE, 0x1423144F, 0x0000000B), + DCL_TEST4(TUint32, TAS, 0x00000000, 0xFFFFFFFE, 0x1423144F, 0x0000000B), + DCL_TEST4(TUint32, TAS, 0xFFFFFFFE, 0xFFFFFFFE, 0x80000000, 0x7FFFFFFF), + DCL_TEST4(TUint32, TAS, 0xFFFFFFEE, 0xFFFFFFFE, 0x80000000, 0x7FFFFFFF), + DCL_TEST4(TUint32, TAS, 0xFFFFFFFF, 0xFFFFFFFE, 0x80000000, 0x7FFFFFFF), + DCL_TEST4(TUint32, TAS, 0x00000000, 0xFFFFFFFE, 0x80000000, 0x7FFFFFFF), + DCL_TEST4(TUint32, TAS, 0xFFFFFFFE, 0x80000000, 0x80000001, 0x7FFFFFFE), + DCL_TEST4(TUint32, TAS, 0x7FFFFFFF, 0x80000000, 0x80000001, 0x7FFFFFFE), + DCL_TEST4(TUint32, TAS, 0x80000000, 0x80000000, 0x80000001, 0x7FFFFFFE), + DCL_TEST4(TUint32, TAS, 0x80000001, 0x80000000, 0x80000001, 0x7FFFFFFE), + DCL_TEST4(TUint32, TAS, 0x00000000, 0x80000000, 0x80000001, 0x7FFFFFFE), + DCL_TEST4(TUint32, TAS, 0x7FFFFFFE, 0x7FFFFFFF, 0x80000001, 0x7FFFFFFE), + DCL_TEST4(TUint32, TAS, 0x7FFFFFFF, 0x7FFFFFFF, 0x80000001, 0x7FFFFFFE), + DCL_TEST4(TUint32, TAS, 0x80000000, 0x7FFFFFFF, 0x80000001, 0x7FFFFFFE), + DCL_TEST4(TUint32, TAS, 0x80000001, 0x7FFFFFFF, 0x80000001, 0x7FFFFFFE), + DCL_TEST4(TUint32, TAS, 0x00000000, 0x7FFFFFFF, 0x80000001, 0x7FFFFFFE) + }; + +DCL_TEST_BLOCK(TUint64,TestData64) + { + DCL_TEST1(TUint64, LOAD, MAKE_TUINT64(0x00000000,0x00000000)), + DCL_TEST1(TUint64, LOAD, MAKE_TUINT64(0xFEDCBA98,0x76543210)), + + DCL_TEST2(TUint64, STORE, MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0xFCD1CC9F,0xDB27CC8B)), + DCL_TEST2(TUint64, STORE, MAKE_TUINT64(0xFEDCBA98,0x76543210), MAKE_TUINT64(0x06931471,0x80559945)), + + DCL_TEST2(TUint64, SWP, MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0xFCD1CC9F,0xDB27CC8B)), + DCL_TEST2(TUint64, SWP, MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xFCD1CC9F,0xDB27CC8B)), + DCL_TEST2(TUint64, SWP, MAKE_TUINT64(0xDEADBEEF,0xBAD0BEEF), MAKE_TUINT64(0x06931471,0x80559945)), + DCL_TEST2(TUint64, SWP, MAKE_TUINT64(0xFEDCBA98,0x76543210), MAKE_TUINT64(0x06931471,0x80559945)), + + DCL_TEST2(TUint64, ADD, MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0x00000000,0x00000001)), + DCL_TEST2(TUint64, ADD, MAKE_TUINT64(0x00000000,0xFFFFFFFF), MAKE_TUINT64(0x00000000,0x00000001)), + DCL_TEST2(TUint64, ADD, MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0xFCD1CC9F,0xDB27CC8B)), + DCL_TEST2(TUint64, ADD, MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xFCD1CC9F,0xDB27CC8B)), + + DCL_TEST2(TUint64, AND, MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0x00000000,0x00000001)), + DCL_TEST2(TUint64, AND, MAKE_TUINT64(0x00000000,0xFFFFFFFF), MAKE_TUINT64(0x00000000,0x00000001)), + DCL_TEST2(TUint64, AND, MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0xFCD1CC9F,0xDB27CC8B)), + DCL_TEST2(TUint64, AND, MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xFCD1CC9F,0xDB27CC8B)), + + DCL_TEST2(TUint64, IOR, MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0x00000000,0x00000001)), + DCL_TEST2(TUint64, IOR, MAKE_TUINT64(0x00000000,0xFFFFFFFF), MAKE_TUINT64(0x00000000,0x00000001)), + DCL_TEST2(TUint64, IOR, MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0xFCD1CC9F,0xDB27CC8B)), + DCL_TEST2(TUint64, IOR, MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xFCD1CC9F,0xDB27CC8B)), + DCL_TEST2(TUint64, IOR, MAKE_TUINT64(0x11111111,0x22222222), MAKE_TUINT64(0x44444444,0x55555555)), + + DCL_TEST2(TUint64, XOR, MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0x00000000,0x00000001)), + DCL_TEST2(TUint64, XOR, MAKE_TUINT64(0x00000000,0xFFFFFFFF), MAKE_TUINT64(0x00000000,0x00000001)), + DCL_TEST2(TUint64, XOR, MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0xFCD1CC9F,0xDB27CC8B)), + DCL_TEST2(TUint64, XOR, MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xFCD1CC9F,0xDB27CC8B)), + DCL_TEST2(TUint64, XOR, MAKE_TUINT64(0x11111111,0x22222222), MAKE_TUINT64(0x44444444,0x77777777)), + + DCL_TEST3(TUint64, AXO, MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0xFFFFFFFF,0xFFFFFFFF), MAKE_TUINT64(0x00000000,0x00000001)), + DCL_TEST3(TUint64, AXO, MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0xFFFFFFFF,0xFFFFFFFF), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED)), + DCL_TEST3(TUint64, AXO, MAKE_TUINT64(0xFFFFFFFF,0xFFFFFFFF), MAKE_TUINT64(0xFFFFFFFF,0xFFFFFFFF), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED)), + DCL_TEST3(TUint64, AXO, MAKE_TUINT64(0xFFFFFFFF,0xFFFFFFFF), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED)), + DCL_TEST3(TUint64, AXO, MAKE_TUINT64(0xFFFFFFFF,0xFFFFFFFF), MAKE_TUINT64(0xFACEFEED,0xFEEDFACE), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED)), + DCL_TEST3(TUint64, AXO, MAKE_TUINT64(0xBAD8BEEF,0xDEADDEAD), MAKE_TUINT64(0xFACEFEED,0xFEEDFACE), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED)), + + DCL_TEST3(TUint64, CAS, MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0x00000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED)), + DCL_TEST3(TUint64, CAS, MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0x00000001,0x00000000), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED)), + DCL_TEST3(TUint64, CAS, MAKE_TUINT64(0x00000000,0x00000001), MAKE_TUINT64(0x00000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED)), + DCL_TEST3(TUint64, CAS, MAKE_TUINT64(0x00000000,0x00000001), MAKE_TUINT64(0x00000001,0x00000000), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED)), + DCL_TEST3(TUint64, CAS, MAKE_TUINT64(0x00000001,0x00000000), MAKE_TUINT64(0x00000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED)), + DCL_TEST3(TUint64, CAS, MAKE_TUINT64(0x00000001,0x00000000), MAKE_TUINT64(0x00000001,0x00000000), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED)), + + DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0x00000000,0x00000001), MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0xFFFFFFFF,0xFFFFFFFF), MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0x00000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0x00000000,0x00000001), MAKE_TUINT64(0x00000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0x00000000,0x00000002), MAKE_TUINT64(0x00000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0xFFFFFFFF,0xFFFFFFFF), MAKE_TUINT64(0x00000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0xFFFFFFFF,0x00000000), MAKE_TUINT64(0x00000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0x80000000,0x00000000), MAKE_TUINT64(0x80000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0x80000000,0x00000001), MAKE_TUINT64(0x80000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0x80000000,0x00000002), MAKE_TUINT64(0x80000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0x7FFFFFFF,0xFFFFFFFF), MAKE_TUINT64(0x80000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0x7FFFFFFF,0x00000000), MAKE_TUINT64(0x80000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0x7FFFFFFF,0x80000001), MAKE_TUINT64(0x7FFFFFFF,0x80000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0x7FFFFFFF,0x80000000), MAKE_TUINT64(0x7FFFFFFF,0x80000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0x7FFFFFFF,0x80000002), MAKE_TUINT64(0x7FFFFFFF,0x80000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0x7FFFFFFF,0xFFFFFFFF), MAKE_TUINT64(0x7FFFFFFF,0x80000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0x7FFFFFFF,0x7FFFFFFF), MAKE_TUINT64(0x7FFFFFFF,0x80000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0x80000000,0x00000000), MAKE_TUINT64(0x7FFFFFFF,0x80000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0x80000000,0x80000000), MAKE_TUINT64(0x7FFFFFFF,0x80000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0x80000000,0x80000001), MAKE_TUINT64(0x7FFFFFFF,0x80000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0x80000000,0x80000002), MAKE_TUINT64(0x7FFFFFFF,0x80000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + + DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0x00000000,0x00000001), MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0xFFFFFFFF,0xFFFFFFFF), MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0x00000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0x00000000,0x00000001), MAKE_TUINT64(0x00000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0x00000000,0x00000002), MAKE_TUINT64(0x00000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0xFFFFFFFF,0xFFFFFFFF), MAKE_TUINT64(0x00000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0xFFFFFFFF,0x00000000), MAKE_TUINT64(0x00000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0x80000000,0x00000000), MAKE_TUINT64(0x80000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0x80000000,0x00000001), MAKE_TUINT64(0x80000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0x80000000,0x00000002), MAKE_TUINT64(0x80000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0x7FFFFFFF,0xFFFFFFFF), MAKE_TUINT64(0x80000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0x7FFFFFFF,0x00000000), MAKE_TUINT64(0x80000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0x7FFFFFFF,0x80000001), MAKE_TUINT64(0x7FFFFFFF,0x80000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0x7FFFFFFF,0x80000000), MAKE_TUINT64(0x7FFFFFFF,0x80000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0x7FFFFFFF,0x80000002), MAKE_TUINT64(0x7FFFFFFF,0x80000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0x7FFFFFFF,0xFFFFFFFF), MAKE_TUINT64(0x7FFFFFFF,0x80000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0x7FFFFFFF,0x7FFFFFFF), MAKE_TUINT64(0x7FFFFFFF,0x80000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0x80000000,0x00000000), MAKE_TUINT64(0x7FFFFFFF,0x80000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0x80000000,0x80000000), MAKE_TUINT64(0x7FFFFFFF,0x80000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0x80000000,0x80000001), MAKE_TUINT64(0x7FFFFFFF,0x80000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), + DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0x80000000,0x80000002), MAKE_TUINT64(0x7FFFFFFF,0x80000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)) + }; + + + +template +void DoTestBlock(const TD* aTests, TInt aCount) + { + const TD* p = aTests; + const TD* e = aTests + aCount; + for (; p fname; + fname.Copy(fname8); + test.Printf(_L("%S\n"), &fname); +#endif + TInt res; + res = tdg.ExecuteUser(); + if (res!=0) + { + tdg.Dump("ExecuteUser"); + test.Printf(_L("FAIL %d\n"),res); + test(0); + } +#ifdef __EPOC32__ +#ifdef __EXTRA_DEBUG__ + test.Printf(_L("%S K\n"), &fname); +#endif + res = tdg.ExecuteKernel(); + if (res!=0) + { + tdg.Dump("ExecuteKernel"); + test.Printf(_L("FAIL %d\n"),res); + test(0); + } +#endif + } + } + } + +#define DO_TEST_BLOCK(type,array) \ + DoTestBlock(&(array)[0],(TInt)(sizeof(array)/sizeof(TD))) + +void TestSingleThread() + { + test.Next(_L("8 bit, single thread")); + DO_TEST_BLOCK(TUint8, TestData8); + test.Next(_L("16 bit, single thread")); + DO_TEST_BLOCK(TUint16, TestData16); + test.Next(_L("32 bit, single thread")); + DO_TEST_BLOCK(TUint32, TestData32); + test.Next(_L("64 bit, single thread")); + DO_TEST_BLOCK(TUint64, TestData64); + } + + + +/****************************************************************************** + * Test invalid address handling when called from user mode + ******************************************************************************/ +const TLinAddr KSpecialAddr = 0x100u; +const TInt KIndexRead = -1; +const TInt KIndexReadWrite = -2; + +struct TE + { + static TInt Execute(TInt aIndex, TAny* aPtr1, TAny* aPtr2, TInt aResult); + TInt DoExecute(); + static TInt ThreadFn(TAny*); + + TInt iIndex; + TAny* iPtr1; + TAny* iPtr2; + }; + +template TInt DoLoadErrorTest(TInt aIndex, const T* aPtr) + { + typename TLoadFn::F atomic = (typename TLoadFn::F)AtomicFuncPtr[aIndex]; + atomic(aPtr); + return 0; + } + +template TInt DoRmw1ErrorTest(TInt aIndex, T* aPtr) + { + typename TRmw1Fn::F atomic = (typename TRmw1Fn::F)AtomicFuncPtr[aIndex]; + T a1 = 0; + atomic(aPtr, a1); + return 0; + } + +template TInt DoRmw2ErrorTest(TInt aIndex, T* aPtr) + { + typename TRmw2Fn::F atomic = (typename TRmw2Fn::F)AtomicFuncPtr[aIndex]; + T a1 = 0; + T a2 = 0; + atomic(aPtr, a1, a2); + return 0; + } + +template TInt DoRmw3ErrorTest(TInt aIndex, T* aPtr) + { + typename TRmw3Fn::F atomic = (typename TRmw3Fn::F)AtomicFuncPtr[aIndex]; + T a1 = 0; + T a2 = 0; + T a3 = 0; + atomic(aPtr, a1, a2, a3); + return 0; + } + +template TInt DoCasErrorTest(TInt aIndex, T* aPtr1, T* aPtr2) + { + typename TCasFn::F atomic = (typename TCasFn::F)AtomicFuncPtr[aIndex]; + TLinAddr a1 = (TLinAddr)aPtr1; + TLinAddr a2 = (TLinAddr)aPtr2; + T reg; + T exp; + T f; + memset(&f, 0xbb, sizeof(T)); + if ((a1&~0xff)==KSpecialAddr) + { + memset(®, (a1&0xff), sizeof(T)); + aPtr1 = ® + } + if ((a2&~0xff)==KSpecialAddr) + { + memset(&exp, (a2&0xff), sizeof(T)); + aPtr2 = &exp; + } + TInt r = atomic(aPtr1, aPtr2, f); + return r ? 1 : 0; + } + +TInt TE::DoExecute() + { + if (iIndex == KIndexRead) + { + return *(volatile TUint8*)iPtr1; + } + if (iIndex == KIndexReadWrite) + { + volatile TUint8* p = (volatile TUint8*)iPtr1; + TUint8 x = *p; + *p = x; + return 0; + } + TUint attr = FuncAttr[iIndex]; + TInt type = ATTR_TO_TYPE(attr); + TInt size = ATTR_TO_SIZE(attr); + if (type==EFuncTypeInvalid) + return KErrNotSupported; + TInt res; + switch (type) + { + case EFuncTypeLoad: + { + switch (size) + { + case 1: res = DoLoadErrorTest(iIndex, (TUint8*)iPtr1); break; + case 2: res = DoLoadErrorTest(iIndex, (TUint16*)iPtr1); break; + case 4: res = DoLoadErrorTest(iIndex, (TUint32*)iPtr1); break; + case 8: res = DoLoadErrorTest(iIndex, (TUint64*)iPtr1); break; + default: res = KErrNotSupported; break; + } + break; + } + case EFuncTypeRmw1: + { + switch (size) + { + case 1: res = DoRmw1ErrorTest(iIndex, (TUint8*)iPtr1); break; + case 2: res = DoRmw1ErrorTest(iIndex, (TUint16*)iPtr1); break; + case 4: res = DoRmw1ErrorTest(iIndex, (TUint32*)iPtr1); break; + case 8: res = DoRmw1ErrorTest(iIndex, (TUint64*)iPtr1); break; + default: res = KErrNotSupported; break; + } + break; + } + case EFuncTypeRmw2: + { + switch (size) + { + case 1: res = DoRmw2ErrorTest(iIndex, (TUint8*)iPtr1); break; + case 2: res = DoRmw2ErrorTest(iIndex, (TUint16*)iPtr1); break; + case 4: res = DoRmw2ErrorTest(iIndex, (TUint32*)iPtr1); break; + case 8: res = DoRmw2ErrorTest(iIndex, (TUint64*)iPtr1); break; + default: res = KErrNotSupported; break; + } + break; + } + case EFuncTypeRmw3: + { + switch (size) + { + case 1: res = DoRmw3ErrorTest(iIndex, (TUint8*)iPtr1); break; + case 2: res = DoRmw3ErrorTest(iIndex, (TUint16*)iPtr1); break; + case 4: res = DoRmw3ErrorTest(iIndex, (TUint32*)iPtr1); break; + case 8: res = DoRmw3ErrorTest(iIndex, (TUint64*)iPtr1); break; + default: res = KErrNotSupported; break; + } + break; + } + case EFuncTypeCas: + { + switch (size) + { + case 1: res = DoCasErrorTest(iIndex, (TUint8*)iPtr1, (TUint8*)iPtr2); break; + case 2: res = DoCasErrorTest(iIndex, (TUint16*)iPtr1, (TUint16*)iPtr2); break; + case 4: res = DoCasErrorTest(iIndex, (TUint32*)iPtr1, (TUint32*)iPtr2); break; + case 8: res = DoCasErrorTest(iIndex, (TUint64*)iPtr1, (TUint64*)iPtr2); break; + default: res = KErrNotSupported; break; + } + break; + } + default: + res = KErrNotSupported; + break; + } + return res; + } + +TInt TE::ThreadFn(TAny* aPtr) + { + return ((TE*)aPtr)->DoExecute(); + } + +_LIT(KLitKERNEXEC,"KERN-EXEC"); +TInt TE::Execute(TInt aIndex, TAny* aPtr1, TAny* aPtr2, TInt aResult) + { + DEBUGPRINT("I=%3d P1=%08x P2=%08x R=%d", aIndex, aPtr1, aPtr2, aResult); + TE te; + te.iIndex = aIndex; + te.iPtr1 = aPtr1; + te.iPtr2 = aPtr2; + RThread t; + TInt r = t.Create(KNullDesC, &ThreadFn, 0x1000, 0, &te); + test_KErrNone(r); + TRequestStatus s; + t.Logon(s); + test_Equal(KRequestPending, s.Int()); + TBool jit = User::JustInTime(); + User::SetJustInTime(EFalse); + t.Resume(); + User::WaitForRequest(s); + User::SetJustInTime(jit); + TInt xt = t.ExitType(); + TInt xr = t.ExitReason(); + const TDesC& xc = t.ExitCategory(); + DEBUGPRINT("Exit type: %d,%d,%S", xt, xr, &xc); + TInt res = KErrNone; + if (aResult == KErrUnknown) + { + if (xt==EExitPanic) + { + test_Equal(ECausedException, xr); + test(xc==KLitKERNEXEC); + res = KErrDied; + } + else + test_Equal(EExitKill, xt); + } + else if (aResult == KErrDied) + { + test_Equal(EExitPanic, xt); + test_Equal(ECausedException, xr); + test(xc==KLitKERNEXEC); + } + else + { + test_Equal(EExitKill, xt); + test_Equal(aResult, xr); + } + CLOSE_AND_WAIT(t); + return res; + } + +TInt ThreadAlign(TAny*) + { + TUint32 array[2]; + TUint32* p = (TUint32*)(((TLinAddr)array)+1); + *p = 5; + return KErrNone; + } + +const TUint64 Zero = UI64LIT(0); +const TUint64 BFBF = UI64LIT(0xbfbfbfbfbfbfbfbf); + +void TestInvalidAddresses() + { + TAny* bad_addr[11]; + TInt c = 0; + TInt read_only = 0; + TInt alignmentEnd = 0; + TInt mminfo = UserSvr::HalFunction(EHalGroupKernel, EKernelHalMemModelInfo, 0, 0); +// TInt mmtype = mminfo & EMemModelTypeMask; +#ifdef __EPOC32__ + if (mminfo & EMemModelAttrWriteProt) + { + bad_addr[c++] = (TAny*)UserSvr::RomHeaderAddress(); + bad_addr[c++] = (TAny*)&Zero; + bad_addr[c++] = (TAny*)&BFBF; + read_only = c; + } +#endif + if (mminfo & EMemModelAttrNonExProt) + { + bad_addr[c++] = 0; // address 0 is read only on ARM7 cores, nonexistent on others + if (TE::Execute(KIndexRead, 0, 0, KErrUnknown)==KErrNone) + read_only = c; // address 0 is readable + TLinAddr nonex = 0; + do { + nonex += 0x1000; + } while (TE::Execute(KIndexRead, (TAny*)nonex, 0, KErrUnknown)==KErrNone); + bad_addr[c++] = (TAny*)nonex; + } +#ifdef __EPOC32__ + if (mminfo & EMemModelAttrKernProt) + { + bad_addr[c++] = DD.KernelMemoryAddress(); + } + // If alignment checking is enabled add alignment tests for 64 bit. + TUint64A alignArray[2]; + RThread t; + TInt r = t.Create(KNullDesC, &ThreadAlign, 0x1000, 0, NULL); + test_KErrNone(r); + TRequestStatus s; + t.Logon(s); + test_Equal(KRequestPending, s.Int()); + TBool jit = User::JustInTime(); + User::SetJustInTime(EFalse); + t.Resume(); + User::WaitForRequest(s); + User::SetJustInTime(jit); + TInt xt = t.ExitType(); + TInt xr = t.ExitReason(); + const TDesC& xc = t.ExitCategory(); + if (EExitPanic == xt) + {// Took an alignment fault so add alignment test. + test_Equal(ECausedException, xr); + test(xc==KLitKERNEXEC); + alignmentEnd = c; + bad_addr[alignmentEnd++] = (TAny*)(((TUint)&alignArray[0]) + 1); + bad_addr[alignmentEnd++] = (TAny*)(((TUint)&alignArray[0]) + 2); + bad_addr[alignmentEnd++] = (TAny*)(((TUint)&alignArray[0]) + 4); + } + +#endif + TInt i; + TInt allBadAddr = (alignmentEnd)? c+3 : c; + DEBUGPRINT("%d invalid addresses", allBadAddr); + for (i=0; i < allBadAddr; ++i) + { + if (i= 3)) || defined(__EABI__) + if (ATTR_TO_SIZE(attr) == 8) + { + for (i = c; i < alignmentEnd; i++) + {// 64 bit unaligned accesses should cause exceptions if + // alignment checking is enabled. + TE::Execute(ix, bad_addr[i], 0, KErrDied); + } + } +#endif + } + } + + + +/****************************************************************************** + * Multiple thread normal operation tests + ******************************************************************************/ +class CThread; +class CThreads : public CBase + { +public: + static CThreads* New(); + CThreads(); + ~CThreads(); + CThread* NewThread(TInt aId); + void StartTest(TInt aIndex, TBool aKernel); + void StopTest(); + void Finish(); + TUint32 DoCasTest(TInt aIndex, TBool aKernel, TUint32 aFailLimit); + void DoRmwTest(TInt aIndex, TBool aKernel, TInt aTime); + inline TInt NumCpus() const {return iNumCpus;} +private: + TInt iNumCpus; + TInt iNumThreads; + CThread* iThreads[KMaxThreads]; + RSemaphore iSem; + volatile TInt iIndex; + volatile TBool iKernel; + volatile TBool iStop; + volatile TUint64 iReg; + TInt iFailCount; + TInt iTimeslice; +private: + friend class CThread; + }; + +class CThread : public CBase + { +private: + CThread(); + ~CThread(); + static TInt ThreadFunction(TAny*); + TInt Run(); + TInt Create(); + void Start(); + void DoTest(); + TUint64 Random(); + void Kick(); +private: + RThread iThread; + TInt iId; + CThreads* iThreads; + TRequestStatus iStatus; + TBool iStarted; + TPerThread iPerThread; + TUint64 iSeed; +private: + friend class CThreads; + }; + +CThreads::CThreads() + { + iNumCpus = UserSvr::HalFunction(EHalGroupKernel, EKernelHalNumLogicalCpus, 0, 0); + iNumThreads = iNumCpus; + if (iNumThreads<2) + iNumThreads=2; + TInt khz; + TInt r = HAL::Get(HAL::ECPUSpeed, khz); + if (r==KErrNone) + iTimeslice = Max(10000000/khz, 100); + else if (r==KErrNotSupported) + iTimeslice = 227; + else + User::Panic(_L("TIMESLICE"),r); + } + +CThreads::~CThreads() + { + TInt i; + for (i=0; iiSem.CreateLocal(0); + TInt i; + for (i=0; iiNumThreads && r==KErrNone; ++i) + { + p->iThreads[i] = p->NewThread(i); + if (!p->iThreads[i]) + r = KErrNoMemory; + } + if (r!=KErrNone) + { + delete p; + return 0; + } + p->iStop = ETrue; + for (i=0; iiNumThreads; ++i) + p->iThreads[i]->Start(); + } + return p; + } + +CThread* CThreads::NewThread(TInt aId) + { + CThread* t = new CThread; + if (t) + { + t->iId = aId; + t->iThreads = this; + TInt r = t->Create(); + if (r!=KErrNone) + { + delete t; + t = 0; + } + } + return t; + } + +void CThreads::StartTest(TInt aIndex, TBool aKernel) + { + iIndex = aIndex; + iKernel = aKernel; + iReg = 0; + iStop = EFalse; +#ifdef __EPOC32__ + if (iKernel) + DD.Initialise(iReg); +#endif + TInt i; + for (i=0; iKick(); + } + +void CThreads::StopTest() + { + iStop = ETrue; + TInt i; + for (i=0; iKick(); + iSem.Wait(); + } + test(iFailCount==0); + } + +TUint32 CThreads::DoCasTest(TInt aIndex, TBool aKernel, TUint32 aFailLimit) + { + TInt i; + test.Printf(_L("DoCasTest I=%d K=%1d F=%d\n"), aIndex, aKernel, aFailLimit); + TUint32 initial = User::FastCounter(); + StartTest(aIndex, aKernel); + FOREVER + { + User::AfterHighRes(1000000); + TUint64 minf = 0; + --minf; + for (i=0; iiPerThread.iDiff, t->iPerThread.iFailCount); + TUint64 f = t->iPerThread.iFailCount; + if (f=TUint64(aFailLimit)) + break; + if (iNumCpus>1) // 1 second is enough for SMP, except on VMPlayer + break; + } + StopTest(); + TUint32 final = User::FastCounter(); + TUint32 time = final - initial; + test.Printf(_L("Time %d\n"), time); + TUint64 total = 0; + TUint64 txor = 0; + for (i=0; iiPerThread.iDiff, t->iPerThread.iFailCount); + total += t->iPerThread.iDiff; + txor ^= t->iPerThread.iXor; + } + TUint size = ATTR_TO_SIZE(FuncAttr[aIndex]); + TUint64 expected = 0; + switch (size) + { + case 1: expected = Transform::F_iter(0, total); break; + case 2: expected = Transform::F_iter(0, total); break; + case 4: expected = Transform::F_iter(0, total); break; + case 8: expected = Transform::F_iter(0, total); break; + } + test.Printf(_L("Total iterations %lu\n"), total); + test.Printf(_L("Expected result %08x %08x\n"), I64HIGH(expected), I64LOW(expected)); + test.Printf(_L("Actual result %08x %08x\n"), I64HIGH(iReg), I64LOW(iReg)); + test.Printf(_L("Tot. XOR result %08x %08x\n"), I64HIGH(txor), I64LOW(txor)); +// test(expected==iReg); +// test(expected==txor); + if (expected!=iReg || expected!=txor) + { + test.Printf(_L("***FAIL***\n")); + ++iFailCount; + } + return time; + } + +void CThreads::DoRmwTest(TInt aIndex, TBool aKernel, TInt aTime) + { + TInt i; + test.Printf(_L("DoRmwTest I=%d K=%1d T=%d\n"), aIndex, aKernel, aTime); + StartTest(aIndex, aKernel); + User::AfterHighRes(aTime); + StopTest(); + TUint64 total = 0; + TUint64 txor = 0; + for (i=0; iiPerThread.iCount, t->iPerThread.iDiff, t->iPerThread.iXor); + total += t->iPerThread.iDiff; + txor ^= t->iPerThread.iXor; + } + TUint size = ATTR_TO_SIZE(FuncAttr[aIndex]); + switch (size) + { + case 1: + { + TUint8 expected = (TUint8)total; + TUint8 exor = (TUint8)txor; + TUint8 got = (TUint8)iReg; + test.Printf(_L("Expected %02x Got %02x XOR %02x\n"), expected, got, exor); +// test(expected==got && exor==got); + if (expected!=got || exor!=got) + { + test.Printf(_L("***FAIL***\n")); + ++iFailCount; + } + break; + } + case 2: + { + TUint16 expected = (TUint16)total; + TUint16 exor = (TUint16)txor; + TUint16 got = (TUint16)iReg; + test.Printf(_L("Expected %04x Got %04x XOR %04x\n"), expected, got, exor); +// test(expected==got && exor==got); + if (expected!=got || exor!=got) + { + test.Printf(_L("***FAIL***\n")); + ++iFailCount; + } + break; + } + case 4: + { + TUint32 expected = (TUint32)total; + TUint32 exor = (TUint32)txor; + TUint32 got = (TUint32)iReg; + test.Printf(_L("Expected %08x Got %08x XOR %08x\n"), expected, got, exor); +// test(expected==got && exor==got); + if (expected!=got || exor!=got) + { + test.Printf(_L("***FAIL***\n")); + ++iFailCount; + } + break; + } + case 8: + { + TUint64 expected = total; + test.Printf(_L("Expected result %08x %08x\n"), I64HIGH(expected), I64LOW(expected)); + test.Printf(_L("Actual result %08x %08x\n"), I64HIGH(iReg), I64LOW(iReg)); + test.Printf(_L("Tot. XOR result %08x %08x\n"), I64HIGH(txor), I64LOW(txor)); +// test(expected==iReg && expected==txor); + if (expected!=iReg || expected!=txor) + { + test.Printf(_L("***FAIL***\n")); + ++iFailCount; + } + break; + } + } + } + +CThread::CThread() + { + } + +CThread::~CThread() + { + TInt h = iThread.Handle(); + if (h && h!=KCurrentThreadHandle) + { + if (!iStarted) + iThread.Kill(0); + User::WaitForRequest(iStatus); + } + iThread.Close(); + } + +TInt CThread::Create() + { + TInt r = iThread.Create(KNullDesC, &ThreadFunction, 0x2000, 0, this); + if (r==KErrNone) + { + iThread.Logon(iStatus); + if (iStatus.Int() != KRequestPending) + r = iStatus.Int(); + } + return r; + } + +void CThread::Start() + { + iThread.Resume(); + iThreads->iSem.Wait(); + } + +void CThread::Kick() + { + TRequestStatus s; + TRequestStatus* pS = &s; + iThread.RequestComplete(pS,0); + } + +TInt CThread::ThreadFunction(TAny* aPtr) + { + return ((CThread*)aPtr)->Run(); + } + +TInt CThread::Run() + { +#ifdef __EPOC32__ + DD.SetCurrentThreadTimeslice(iThreads->iTimeslice); +#endif + RThread().SetPriority(EPriorityLess); + FOREVER + { + if (iThreads->iStop) + { + iThreads->iSem.Signal(); + if (iThreads->iNumCpus > 1) + RThread().SetPriority(EPriorityAbsoluteHigh); // encourage spreading out of threads between CPUs + User::WaitForAnyRequest(); + if (iThreads->iIndex<0) + break; + if (iThreads->iNumCpus > 1) + { + TUint32 tick = User::NTickCount(); + while(User::NTickCount()-tick < 2) {} // spin to discourage putting other threads on this CPU + RThread().SetPriority(EPriorityLess); + } + } + DoTest(); + } + iThreads->iSem.Signal(); + return 0; + } + +TUint64 CThread::Random() + { + iSeed = Transform::F(iSeed); + return iSeed; + } + +void CThread::DoTest() + { + iPerThread.iDiff = 0; + iPerThread.iXor = 0; + iPerThread.iFailCount = 0; + iPerThread.iCount = 0; + TInt index = iThreads->iIndex; + TAny* p = (TAny*)&iThreads->iReg; +#ifdef __EPOC32__ + TBool kernel = iThreads->iKernel; + if (kernel) + { + DD.SwitchExecTables(iId); + RTestAtomic::SetThreadInfo(iPerThread); + } + TInt iter = 0; +#endif + iSeed = iId; + while (!iThreads->iStop) + { + TAtomicAction action; + action.i0 = Random(); + action.i1 = Random(); + action.i2 = Random(); + action.iIndex = index; + action.iThread = iId; +#ifdef __EPOC32__ + if (kernel) + { + RTestAtomic::AtomicAction(action); + } + else +#endif + DoAtomicAction(p, &iPerThread, action); +#ifdef __EPOC32__ + if (kernel && ++iter==1024) + { + iter = 0; + RTestAtomic::GetThreadInfo(iPerThread); + } +#endif + } +#ifdef __EPOC32__ + if (kernel) + { + RTestAtomic::GetThreadInfo(iPerThread); + RTestAtomic::RestoreExecTable(); + } +#endif + } + +void TestMultipleThreads() + { + CThreads* p = CThreads::New(); + test(p!=0); + + TInt KRequiredRetries = 1000; + if (p->NumCpus()==1) + KRequiredRetries = 10; + + TUint32 time; + TUint32 total_time = 0; + TUint32 total_time_k = 0; + TUint32 count = 0; + TInt ix; + for (ix=0; ixNumCpus()==1) + { + TUint ord = ATTR_TO_ORD(attr); + if (ord != EOrderOrdered) + continue; + } + if (type==EFuncTypeInvalid) + continue; + if (func!=TUint(EAtomicFuncCAS)) + continue; + time = p->DoCasTest(ix, EFalse, KRequiredRetries); + total_time += time; + ++count; + time = p->DoCasTest(ix, ETrue, KRequiredRetries); + total_time_k += time; + } + TUint32 avg_time = total_time / count; + TUint32 avg_time_k = total_time_k / count; + TUint32 fcf=0; + TInt r = HAL::Get(HAL::EFastCounterFrequency, (TInt&)fcf); + test_KErrNone(r); + test.Printf(_L("FastCounterFrequency = %u\n"), fcf); + TUint64 avg_time_us64(avg_time); + avg_time_us64*=UI64LIT(1000000); + avg_time_us64/=TUint64(fcf); + TInt avg_time_us = KMaxTInt; + TInt avg_time_k_us = KMaxTInt; + if (avg_time_us64NumCpus()==1) ? 15*1000*1000 : 4*1000*1000; + + for (ix=0; ixNumCpus()==1) + { + TUint ord = ATTR_TO_ORD(attr); + if (ord != EOrderOrdered) + continue; + } + if (type==EFuncTypeInvalid) + continue; + if (func=TUint(EAtomicFuncCAS)) + continue; + if (func==TUint(EAtomicFuncIOR)) // can only test AND and IOR together + continue; + p->DoRmwTest(ix, EFalse, Min(avg_time_us,limit_us)); + p->DoRmwTest(ix, ETrue, Min(avg_time_k_us,limit_us)); + } + + p->Finish(); + delete p; + } + + + +/****************************************************************************** + * Main + ******************************************************************************/ +TInt E32Main() + { + test.Title(); + test.Start(_L("Opening device driver")); +#ifdef __EPOC32__ + TInt r; + r = User::LoadLogicalDevice(KAtomicTestLddName); + test(r==KErrNone||r==KErrAlreadyExists); + r = DD.Open(); + test_KErrNone(r); +#endif + test.Next(_L("Testing atomic operations ...")); + test.Next(_L("Single thread, normal operation")); + TestSingleThread(); + test.Next(_L("Single thread, bad addresses")); + TestInvalidAddresses(); + test.Next(_L("Multiple threads")); + TestMultipleThreads(); + test.End(); + return 0; + } +