kerneltest/e32test/mmu/t_imb.cia
author Tom Cosgrove <tom.cosgrove@nokia.com>
Fri, 28 May 2010 16:26:05 +0100
branchRCL_3
changeset 29 743008598095
parent 0 a41df078684a
permissions -rw-r--r--
Fix for bug 2283 (RVCT 4.0 support is missing from PDK 3.0.h) Have multiple extension sections in the bld.inf, one for each version of the compiler. The RVCT version building the tools will build the runtime libraries for its version, but make sure we extract all the other versions from zip archives. Also add the archive for RVCT4.

// Copyright (c) 1995-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\mmu\t_imb.cia
// 
//

#include <e32test.h>
#include <u32std.h>
#include <e32math.h>

#ifdef __CPU_ARM
__NAKED__ TInt Sqrt(TReal& /*aDest*/, const TReal& /*aSrc*/)
	{
	// r0=address of aDest, r1=address of aSrc
	asm("stmfd sp!, {r4-r10,lr} ");
#ifdef __DOUBLE_WORDS_SWAPPED__
	asm("ldmia r1, {r3,r4} ");			// low mant into r4, sign:exp:high mant into r3
#else
	asm("ldr r3, [r1, #4] ");
	asm("ldr r4, [r1, #0] ");
#endif
	asm("bic r5, r3, #0xFF000000 ");
	asm("bic r5, r5, #0x00F00000 ");	// high word of mantissa into r5
	asm("mov r2, r3, lsr #20 ");
	asm("bics r2, r2, #0x800 ");		// exponent now in r2
	asm("beq fastsqrt1 ");				// branch if exponent zero (zero or denormal)
	asm("mov r6, #0xFF ");
	asm("orr r6, r6, #0x700 ");
	asm("cmp r2, r6 ");					// check for infinity or NaN
	asm("beq fastsqrt2 ");				// branch if infinity or NaN
	asm("movs r3, r3 ");				// test sign
	asm("bmi fastsqrtn ");				// branch if negative
	asm("sub r2, r2, #0xFF ");			// unbias the exponent
	asm("sub r2, r2, #0x300 ");			//
	asm("fastsqrtd1: ");
	asm("mov r1, #0x40000000 ");		// value for comparison
	asm("mov r3, #27 ");				// loop counter (number of bits/2)
	asm("movs r2, r2, asr #1 ");		// divide exponent by 2, LSB into CF
	asm("movcs r7, r5, lsl #11 ");		// mantissa into r6,r7 with MSB in MSB of r7
	asm("orrcs r7, r7, r4, lsr #21 ");
	asm("movcs r6, r4, lsl #11 ");
	asm("movcs r4, #0 ");				// r4, r5 will hold result mantissa
	asm("orrcs r7, r7, #0x80000000 ");	// if exponent odd, restore MSB of mantissa
	asm("movcc r7, r5, lsl #12 ");		// mantissa into r6,r7 with MSB in MSB of r7
	asm("orrcc r7, r7, r4, lsr #20 ");	// if exponent even, shift mantissa left an extra
	asm("movcc r6, r4, lsl #12 ");		// place, lose top bit, and
	asm("movcc r4, #1 ");				// set MSB of result, and
	asm("mov r5, #0 ");					// r4, r5 will hold result mantissa
	asm("mov r8, #0 ");					// r8, r9 will be comparison accumulator
	asm("mov r9, #0 ");
	asm("bcc fastsqrt4 ");				// if exponent even, calculate one less bit
										// as result MSB already known

	// Main mantissa square-root loop
	asm("fastsqrt3: ");					// START OF MAIN LOOP
	asm("subs r10, r7, r1 ");			// subtract result:01 from acc:mant
	asm("sbcs r12, r8, r4 ");			// result into r14:r12:r10
	asm("sbcs r14, r9, r5 ");
	asm("movcs r7, r10 ");				// if no borrow replace accumulator with result
	asm("movcs r8, r12 ");
	asm("movcs r9, r14 ");
	asm("adcs r4, r4, r4 ");			// shift result left one, putting in next bit
	asm("adcs r5, r5, r5 ");
	asm("mov r9, r9, lsl #2 ");			// shift acc:mant left by 2 bits
	asm("orr r9, r9, r8, lsr #30 ");
	asm("mov r8, r8, lsl #2 ");
	asm("orr r8, r8, r7, lsr #30 ");
	asm("mov r7, r7, lsl #2 ");
	asm("orr r7, r7, r6, lsr #30 ");
	asm("mov r6, r6, lsl #2 ");
	asm("fastsqrt4: ");					// Come in here if we need to do one less iteration
	asm("subs r10, r7, r1 ");			// subtract result:01 from acc:mant
	asm("sbcs r12, r8, r4 ");			// result into r14:r12:r10
	asm("sbcs r14, r9, r5 ");
	asm("movcs r7, r10 ");				// if no borrow replace accumulator with result
	asm("movcs r8, r12 ");
	asm("movcs r9, r14 ");
	asm("adcs r4, r4, r4 ");			// shift result left one, putting in next bit
	asm("adcs r5, r5, r5 ");
	asm("mov r9, r9, lsl #2 ");			// shift acc:mant left by 2 bits
	asm("orr r9, r9, r8, lsr #30 ");
	asm("mov r8, r8, lsl #2 ");
	asm("orr r8, r8, r7, lsr #30 ");
	asm("mov r7, r7, lsl #2 ");
	asm("orr r7, r7, r6, lsr #30 ");
	asm("mov r6, r6, lsl #2 ");
	asm("subs r3, r3, #1 ");			// decrement loop counter
	asm("bne fastsqrt3 ");				// do necessary number of iterations

	asm("movs r4, r4, lsr #1 ");		// shift result mantissa right 1 place
	asm("orr r4, r4, r5, lsl #31 ");	// LSB (=rounding bit) into carry
	asm("mov r5, r5, lsr #1 ");
	asm("adcs r4, r4, #0 ");			// round the mantissa to 53 bits
	asm("adcs r5, r5, #0 ");
	asm("cmp r5, #0x00200000 ");		// check for mantissa overflow
	asm("addeq r2, r2, #1 ");			// if so, increment exponent - can never overflow
	asm("bic r5, r5, #0x00300000 ");	// remove top bit of mantissa - it is implicit
	asm("add r2, r2, #0xFF ");			// re-bias the exponent
	asm("add r3, r2, #0x300 ");			// and move into r3
	asm("orr r3, r5, r3, lsl #20 ");	// r3 now contains exponent + top of mantissa
	asm("fastsqrt_ok: ");
#ifdef __DOUBLE_WORDS_SWAPPED__
	asm("stmia r0, {r3,r4} ");			// store the result
#else
	asm("str r3, [r0, #4] ");
	asm("str r4, [r0, #0] ");
#endif
	asm("mov r0, #0 ");					// error code KErrNone
	__POPRET("r4-r10,");

	asm("fastsqrt1: ");
	asm("orrs r6, r5, r4 ");			// exponent zero - test mantissa
	asm("beq fastsqrt_ok ");			// if zero, return 0

	asm("movs r3, r3 ");				// denormal - test sign
	asm("bmi fastsqrtn ");				// branch out if negative
	asm("sub r2, r2, #0xFE ");			// unbias the exponent
	asm("sub r2, r2, #0x300 ");			//
	asm("fastsqrtd: ");
	asm("adds r4, r4, r4 ");			// shift mantissa left
	asm("adcs r5, r5, r5 ");
	asm("sub r2, r2, #1 ");				// and decrement exponent
	asm("tst r5, #0x00100000 ");		// test if normalised
	asm("beq fastsqrtd ");				// loop until normalised
	asm("b fastsqrtd1 ");				// now treat as a normalised number
	asm("fastsqrt2: ");					// get here if infinity or NaN
	asm("orrs r6, r5, r4 ");			// if mantissa zero, infinity
	asm("bne fastsqrtnan ");			// branch if not - must be NaN
	asm("movs r3, r3 ");				// test sign of infinity
	asm("bmi fastsqrtn ");				// branch if -ve
#ifdef __DOUBLE_WORDS_SWAPPED__
	asm("stmia r0, {r3,r4} ");			// store the result
#else
	asm("str r3, [r0, #4] ");
	asm("str r4, [r0, #0] ");
#endif
	asm("mov r0, #-9 ");				// return KErrOverflow
	asm("b fastsqrt_end ");

	asm("fastsqrtn: ");					// get here if negative or QNaN operand
	asm("mov r3, #0xFF000000 ");		// generate "real indefinite" QNaN
	asm("orr r3, r3, #0x00F80000 ");	// sign=1, exp=7FF, mantissa = 1000...0
	asm("mov r4, #0 ");
	asm("fastsqrtxa: ");
#ifdef __DOUBLE_WORDS_SWAPPED__
	asm("stmia r0, {r3,r4} ");			// store the result
#else
	asm("str r3, [r0, #4] ");
	asm("str r4, [r0, #0] ");
#endif
	asm("mov r0, #-6 ");				// return KErrArgument
	asm("fastsqrt_end: ");
	__POPRET("r4-r10,");

	asm("fastsqrtnan: ");				// operand is a NaN
	asm("tst r5, #0x00080000 ");		// test MSB of mantissa
	asm("bne fastsqrtn ");				// if set it is a QNaN - so return "real indefinite"
	asm("bic r3, r3, #0x00080000 ");	// else convert SNaN to QNaN
	asm("b fastsqrtxa ");				// and return KErrArgument

	asm("Sqrt__FRdRCd_end: ");

	}

__NAKED__ TUint Sqrt_Length()
	{
	asm("adr r0, Sqrt__FRdRCd_end ");
	asm("adr r1, Sqrt__FRdRCd ");
	asm("sub r0, r0, r1 ");
	__JUMP(,lr);
	}

__NAKED__ TInt Divide(TRealX& /*aDividend*/, const TRealX& /*aDivisor*/)
	{
	asm("stmfd sp!, {r0,r4-r9,lr} ");
	asm("ldmia r1, {r4,r5,r6} ");
	asm("ldmia r0, {r1,r2,r3} ");
	asm("bl TRealXDivide ");
	asm("ldmfd sp!, {r0,r4-r9,lr} ");
	asm("stmia r0, {r1,r2,r3} ");
	asm("mov r0, r12 ");
	__JUMP(,lr);

	// TRealX division r1,r2,r3 / r4,r5,r6 result in r1,r2,r3
	// Error code returned in r12
	// Registers r0-r9,r12 modified
	// NB This function is purely internal to EUSER and therefore IS ONLY EVER CALLED IN ARM MODE.
	asm("TRealXDivide: ");
	asm("mov r12, #0 ");					// initialise return value to KErrNone
	asm("bic r3, r3, #0x300 ");				// clear rounding flags
	asm("tst r6, #1 ");
	asm("eorne r3, r3, #1 ");				// Exclusive-OR signs
	asm("cmn r3, #0x10000 ");				// check if dividend is NaN or infinity
	asm("bcs TRealXDivide1 ");				// branch if it is
	asm("cmn r6, #0x10000 ");				// check if divisor is NaN or infinity
	asm("bcs TRealXDivide2 ");				// branch if it is
	asm("cmp r6, #0x10000 ");				// check if divisor zero
	asm("bcc TRealXDivide3 ");				// branch if it is
	asm("cmp r3, #0x10000 ");				// check if dividend zero
	__JUMP(cc,lr);					// if zero, exit
	asm("tst r3, #1 ");
	asm("orrne lr, lr, #1 ");				// save sign in bottom bit of lr

	// calculate result exponent
	asm("mov r0, r3, lsr #16 ");			// r0=dividend exponent
	asm("sub r0, r0, r6, lsr #16 ");		// r0=dividend exponent - divisor exponent
	asm("add r0, r0, #0x7F00 ");
	asm("add r0, r0, #0x00FF ");			// r0 now contains result exponent
	asm("mov r6, r1 ");						// move dividend into r6,r7,r8
	asm("mov r7, r2 ");
	asm("mov r8, #0 ");						// use r8 to hold extra bit shifted up
											// r2:r1 will hold result mantissa
	asm("mov r2, #1 ");						// we will make sure first bit is 1
	asm("cmp r7, r5 ");						// compare dividend mantissa to divisor mantissa
	asm("cmpeq r6, r4 ");
	asm("bcs TRealXDivide4 ");				// branch if dividend >= divisor
	asm("adds r6, r6, r6 ");				// else shift dividend left one
	asm("adcs r7, r7, r7 ");				// ignore carry here
	asm("sub r0, r0, #1 ");					// decrement result exponent by one
	asm("TRealXDivide4: ");
	asm("subs r6, r6, r4 ");				// subtract divisor from dividend
	asm("sbcs r7, r7, r5 ");

	// Main mantissa division code
	// First calculate the top 32 bits of the result
	// Top bit is 1, do 10 lots of 3 bits the one more bit
	asm("mov r12, #10 ");
	asm("TRealXDivide5: ");
	asm("adds r6, r6, r6 ");				// shift accumulator left by one
	asm("adcs r7, r7, r7 ");
	asm("adcs r8, r8, r8 ");
	asm("subs r9, r6, r4 ");				// subtract divisor from accumulator, result in r9,r3
	asm("sbcs r3, r7, r5 ");
	asm("movccs r8, r8, lsr #1 ");			// if borrow, check for carry from shift
	asm("movcs r6, r9 ");					// if no borrow, replace accumulator with result
	asm("movcs r7, r3 ");
	asm("adcs r2, r2, r2 ");				// shift in new result bit
	asm("adds r6, r6, r6 ");				// shift accumulator left by one
	asm("adcs r7, r7, r7 ");
	asm("adcs r8, r8, r8 ");
	asm("subs r9, r6, r4 ");				// subtract divisor from accumulator, result in r9,r3
	asm("sbcs r3, r7, r5 ");
	asm("movccs r8, r8, lsr #1 ");			// if borrow, check for carry from shift
	asm("movcs r6, r9 ");					// if no borrow, replace accumulator with result
	asm("movcs r7, r3 ");
	asm("adcs r2, r2, r2 ");				// shift in new result bit
	asm("adds r6, r6, r6 ");				// shift accumulator left by one
	asm("adcs r7, r7, r7 ");
	asm("adcs r8, r8, r8 ");
	asm("subs r9, r6, r4 ");				// subtract divisor from accumulator, result in r9,r3
	asm("sbcs r3, r7, r5 ");
	asm("movccs r8, r8, lsr #1 ");			// if borrow, check for carry from shift
	asm("movcs r6, r9 ");					// if no borrow, replace accumulator with result
	asm("movcs r7, r3 ");
	asm("adcs r2, r2, r2 ");				// shift in new result bit
	asm("subs r12, r12, #1 ");
	asm("bne TRealXDivide5 ");				// iterate the loop
	asm("adds r6, r6, r6 ");				// shift accumulator left by one
	asm("adcs r7, r7, r7 ");
	asm("adcs r8, r8, r8 ");
	asm("subs r9, r6, r4 ");				// subtract divisor from accumulator, result in r9,r3
	asm("sbcs r3, r7, r5 ");
	asm("movccs r8, r8, lsr #1 ");			// if borrow, check for carry from shift
	asm("movcs r6, r9 ");					// if no borrow, replace accumulator with result
	asm("movcs r7, r3 ");
	asm("adcs r2, r2, r2 ");				// shift in new result bit - now have 32 bits

	// Now calculate the bottom 32 bits of the result
	// Do 8 lots of 4 bits
	asm("mov r12, #8 ");
	asm("TRealXDivide5a: ");
	asm("adds r6, r6, r6 ");				// shift accumulator left by one
	asm("adcs r7, r7, r7 ");
	asm("adcs r8, r8, r8 ");
	asm("subs r9, r6, r4 ");				// subtract divisor from accumulator, result in r9,r3
	asm("sbcs r3, r7, r5 ");
	asm("movccs r8, r8, lsr #1 ");			// if borrow, check for carry from shift
	asm("movcs r6, r9 ");					// if no borrow, replace accumulator with result
	asm("movcs r7, r3 ");
	asm("adcs r1, r1, r1 ");				// shift in new result bit
	asm("adds r6, r6, r6 ");				// shift accumulator left by one
	asm("adcs r7, r7, r7 ");
	asm("adcs r8, r8, r8 ");
	asm("subs r9, r6, r4 ");				// subtract divisor from accumulator, result in r9,r3
	asm("sbcs r3, r7, r5 ");
	asm("movccs r8, r8, lsr #1 ");			// if borrow, check for carry from shift
	asm("movcs r6, r9 ");					// if no borrow, replace accumulator with result
	asm("movcs r7, r3 ");
	asm("adcs r1, r1, r1 ");				// shift in new result bit
	asm("adds r6, r6, r6 ");				// shift accumulator left by one
	asm("adcs r7, r7, r7 ");
	asm("adcs r8, r8, r8 ");
	asm("subs r9, r6, r4 ");				// subtract divisor from accumulator, result in r9,r3
	asm("sbcs r3, r7, r5 ");
	asm("movccs r8, r8, lsr #1 ");			// if borrow, check for carry from shift
	asm("movcs r6, r9 ");					// if no borrow, replace accumulator with result
	asm("movcs r7, r3 ");
	asm("adcs r1, r1, r1 ");				// shift in new result bit
	asm("adds r6, r6, r6 ");				// shift accumulator left by one
	asm("adcs r7, r7, r7 ");
	asm("adcs r8, r8, r8 ");
	asm("subs r9, r6, r4 ");				// subtract divisor from accumulator, result in r9,r3
	asm("sbcs r3, r7, r5 ");
	asm("movccs r8, r8, lsr #1 ");			// if borrow, check for carry from shift
	asm("movcs r6, r9 ");					// if no borrow, replace accumulator with result
	asm("movcs r7, r3 ");
	asm("adcs r1, r1, r1 ");				// shift in new result bit
	asm("subs r12, r12, #1 ");
	asm("bne TRealXDivide5a ");				// iterate the loop

	// r2:r1 now contains a 64-bit normalised mantissa
	// need to do rounding now
	asm("and r3, lr, #1 ");					// result sign back into r3
	asm("orrs r9, r6, r7 ");				// check if accumulator zero
	asm("beq TRealXDivide6 ");				// if it is, result is exact, else generate next bit
	asm("adds r6, r6, r6 ");				// shift accumulator left by one
	asm("adcs r7, r7, r7 ");
	asm("adcs r8, r8, r8 ");
	asm("subs r6, r6, r4 ");				// subtract divisor from accumulator
	asm("sbcs r7, r7, r5 ");
	asm("movccs r8, r8, lsr #1 ");			// if borrow, check for carry from shift
	asm("orrcc r3, r3, #0x100 ");			// if borrow, round down and set round-down flag
	asm("bcc TRealXDivide6 ");
	asm("orrs r9, r6, r7 ");				// if no borrow, check if exactly half-way
	asm("moveqs r9, r1, lsr #1 ");			// if exactly half-way, round to even
	asm("orrcc r3, r3, #0x100 ");			// if C=0, round result down and set round-down flag
	asm("bcc TRealXDivide6 ");
	asm("orr r3, r3, #0x200 ");				// else set round-up flag
	asm("adds r1, r1, #1 ");				// and round mantissa up
	asm("adcs r2, r2, #0 ");
	asm("movcs r2, #0x80000000 ");			// if carry, mantissa = 80000000 00000000
	asm("addcs r0, r0, #1 ");				// and increment exponent

	// check for overflow or underflow and assemble final result
	asm("TRealXDivide6: ");
	asm("add r4, r0, #1 ");					// need to add 1 to get usable threshold
	asm("cmp r4, #0x10000 ");				// check if exponent >= 0xFFFF
	asm("bge TRealXMultiply6 ");			// if so, overflow
	asm("cmp r0, #0 ");						// check for underflow
	asm("orrgt r3, r3, r0, lsl #16 ");		// if no underflow, result exponent into r3, ...
	asm("movgt r12, #0 ");					// ... return KErrNone ...
	__JUMP(gt,lr);

	// underflow
	asm("and r3, r3, #1 ");					// set exponent=0, keep sign
	asm("mvn r12, #9 ");					// return KErrUnderflow
	__JUMP(,lr);

	// come here if divisor is zero, dividend finite
	asm("TRealXDivide3: ");
	asm("cmp r3, #0x10000 ");				// check if dividend also zero
	asm("bcc TRealXRealIndefinite ");		// if so, return 'real indefinite'
	asm("orr r3, r3, #0xFF000000 ");		// else return infinity with xor sign
	asm("orr r3, r3, #0x00FF0000 ");
	asm("mov r2, #0x80000000 ");
	asm("mov r1, #0 ");
	asm("mvn r12, #40 ");					// return KErrDivideByZero
	__JUMP(,lr);

	// Dividend is NaN or infinity
	asm("TRealXDivide1: ");
	asm("cmp r2, #0x80000000 ");			// check for infinity
	asm("cmpeq r1, #0 ");
	asm("bne TRealXBinOpNan ");				// branch if NaN
	asm("cmn r6, #0x10000 ");				// check 2nd operand for NaN/infinity
	asm("mvncc r12, #8 ");					// if not, return KErrOverflow
	__JUMP(cc,lr);

	// Dividend=infinity, divisor=NaN or infinity
	asm("cmp r5, #0x80000000 ");			// check 2nd operand for infinity
	asm("cmpeq r4, #0 ");
	asm("bne TRealXBinOpNan ");				// branch if NaN
	asm("b TRealXRealIndefinite ");			// else return 'real indefinite'

	// Divisor is NaN or infinity, dividend finite
	asm("TRealXDivide2: ");
	asm("cmp r5, #0x80000000 ");			// check for infinity
	asm("cmpeq r4, #0 ");
	asm("bne TRealXBinOpNan ");				// branch if NaN
	asm("and r3, r3, #1 ");					// else return zero with xor sign
	__JUMP(,lr);

	asm("TRealXBinOpNan: ");				// generic routine to process NaNs in binary
											// operations
	asm("cmn r3, #0x10000 ");				// check if first operand is NaN
	asm("movcc r0, r1 ");					// if not, swap the operands
	asm("movcc r1, r4 ");
	asm("movcc r4, r0 ");
	asm("movcc r0, r2 ");
	asm("movcc r2, r5 ");
	asm("movcc r5, r0 ");
	asm("movcc r0, r3 ");
	asm("movcc r3, r6 ");
	asm("movcc r6, r0 ");
	asm("cmn r6, #0x10000 ");				// both operands NaNs?
	asm("bcc TRealXBinOpNan1 ");			// skip if not
	asm("cmp r2, r5 ");						// if so, compare the significands
	asm("cmpeq r1, r4 ");
	asm("movcc r1, r4 ");					// r1,r2,r3 will get NaN with larger significand
	asm("movcc r2, r5 ");
	asm("movcc r3, r6 ");
	asm("TRealXBinOpNan1: ");
	asm("orr r2, r2, #0x40000000 ");		// convert an SNaN to a QNaN
	asm("mvn r12, #5 ");					// return KErrArgument
	__JUMP(,lr);

	// Return 'real indefinite'
	asm("TRealXRealIndefinite: ");
	asm("ldr r3, __RealIndefiniteExponent ");
	asm("mov r2, #0xC0000000 ");
	asm("mov r1, #0 ");
	asm("mvn r12, #5 ");					// return KErrArgument
	__JUMP(,lr);

	// overflow
	asm("TRealXMultiply6: ");
	asm("bic r3, r3, #0x0000FF00 ");		// clear rounding flags
	asm("orr r3, r3, #0xFF000000 ");		// make exponent FFFF for infinity
	asm("orr r3, r3, #0x00FF0000 ");
	asm("mov r2, #0x80000000 ");			// mantissa = 80000000 00000000
	asm("mov r1, #0 ");
	asm("mvn r12, #8 ");					// return KErrOverflow
	__JUMP(,lr);

	asm("__RealIndefiniteExponent: ");
	asm(".word 0xFFFF0001 ");

	asm("Divide__FR6TRealXRC6TRealX_end: ");
	}

__NAKED__ TUint Divide_Length()
	{
	asm("adr r0, Divide__FR6TRealXRC6TRealX_end ");
	asm("adr r1, Divide__FR6TRealXRC6TRealX ");
	asm("sub r0, r0, r1 ");
	__JUMP(,lr);
	}

__NAKED__ TInt SDummy(TInt)
	{
	__JUMP(,lr);
	asm("SDummy__Fi_end: ");
	}

__NAKED__ TUint SDummy_Length()
	{
	asm("adr r0, SDummy__Fi_end ");
	asm("adr r1, SDummy__Fi ");
	asm("sub r0, r0, r1 ");
	__JUMP(,lr);
	}

__NAKED__ TInt Increment(TInt)
	{
	asm("add r0, r0, #1 ");
	__JUMP(,lr);
	asm("Increment__Fi_end: ");
	}

__NAKED__ TUint Increment_Length()
	{
	asm("adr r0, Increment__Fi_end ");
	asm("adr r1, Increment__Fi ");
	asm("sub r0, r0, r1 ");
	__JUMP(,lr);
	}

#endif