@;===============================================================================
@;===
@;===	Metrowerks ARM Floating Point Emulation Library 
@;===	Copyright © 1995-2004 Metrowerks Corporation.  All rights reserved.
@;===
@;===	$Date: 2010/04/19 12:20:59 $
@;===	$Revision: 1.1 $
@;===
@;===============================================================================

@;=== FILE: ARMsfpe.pre.s

@;===============================================================================

@/* April 07, 2006, w.ref.t RUN-TIME ABI FOR THE ARM ARCHITECTURE document, changed 
@ * the labels with resp to AEABI standards 
@ */

#define _AEABI


#ifdef _AEABI

#define _dadd     __aeabi_dadd
#define _ddiv     __aeabi_ddiv
#define _dmul     __aeabi_dmul
#define _drsb     __aeabi_drsub
#define _dsub     __aeabi_dsub
#define _d_neg    __aeabi_dneg
#define _deq      __aeabi_dcmpeq
#define _dls      __aeabi_dcmplt
#define _dleq     __aeabi_dcmple
#define _dgeq     __aeabi_dcmpge
#define _dgr      __aeabi_dcmpgt
#define _fadd     __aeabi_fadd 
#define _fdiv     __aeabi_fdiv
#define _fmul     __aeabi_fmul
#define _frsb     __aeabi_frsub
#define _fsub     __aeabi_fsub
#define _f_neg    __aeabi_fneg
#define _feq      __aeabi_fcmpeq
#define _fls      __aeabi_fcmplt 
#define _fleq     __aeabi_fcmple
#define _fgeq     __aeabi_fcmpge
#define _fgr      __aeabi_fcmpgt
#define _d_dtoi   __aeabi_d2iz
#define _d_dtou   __aeabi_d2uiz
#define _d_dtoll  __aeabi_d2lz
#define _d_dtoull __aeabi_d2ulz
#define _f_ftoi   __aeabi_f2iz
#define _f_ftou   __aeabi_f2uiz
#define _f_ftoll  __aeabi_f2lz
#define _f_ftoull __aeabi_f2ulz
#define _d2f      __aeabi_d2f
#define _f2d      __aeabi_f2d
#define _d_itod   __aeabi_i2d
#define _d_utod   __aeabi_ui2d
#define _d_lltod  __aeabi_l2d
#define _d_ulltod __aeabi_ul2d
#define _f_itof   __aeabi_i2f
#define _f_utof   __aeabi_ui2f
#define _f_lltof  __aeabi_l2f
#define _f_ulltof __aeabi_ul2f

#define _ll_mul   __aeabi_lmul
@;#define _ll_mod   __aeabi_ldivmod
@;#define _ull_mod  __aeabi_uldivmod
#define _ll_sll   __aeabi_llsl
#define _ll_sra   __aeabi_llsr

#include "FSL_defines.S"

#endif
	.syntax unified
@.option no_section_resume on

#ifndef ARMSFPE_PRE_H



#define ARMSFPE_PRE_H                     @;define ARMSFPE_PRE_H


#ifdef IEEE_FULL || IEEE_FIXED

        .extern __rt_fp_status_addr

  #endif



@;=============================================================================== 

@;

@@;SCRATCH REGISTERS

#define sreg01 r1                      @@;volatile        same as fy, dxl or dxh

#define sreg02 r2                      @@;volatile        same as dyl or dyh

#define sreg03  r3                      @@;volatile    same as dyl or dyh@;whether to add or sub

#define sreg04  r4                      @@;nonvolatile same as fpstate

#define sreg05  r5                      @@;nonvolatile

#define rscratch  r6                    @@;nonvolatile same as rsign

#define sreg06  r6

@@;@@@ Added next

#define sreg07  r7

#define sreg08  r8                      @@;nonvolatile same as yexp

#define sreg09  r9                      @@;nonvolatile same as fyb

#define sreg10  r10                     @@;nonvolatile same as fr

#define sreg11  r11                     @@;nonvolatile same as drh or dyl

#define sreg12  r12                     @@;nonvolatile same as drh or dyl



@;

@@;FLOATING-POINT NUMBERS

#define fx  r0                          @@;volatile        fp argument x and x mantissa

#define fy  r1                          @@;volatile        fp argument y

#define fr  r10                         @@;nonvolatile fp argument result



  #ifdef BIG_ENDIAN

#define dxh  r0                         @@;volatile        double argument x, hi 32 bits

#define dxl  r1                         @@;volatile        double argument x, lo 32 bits

@@;@@@ Added next four definitions for long long registers

#define llh  r0

#define lll  r1                         @;long long registers for first argument

#define lyh  r2

#define lyl  r3                         @;long long registers for second argument

#define dyh  r2                         @;volatile        double argument y, hi 32 bits

#define dyl  r3                         @;volatile        double argument y, lo 32 bits

#define drh  r12                        @;nonvolatile double argument result, hi 32 bits

#define drl  r11                        @;nonvolatile double argument result, lo 32 bits

  #else

@;@@@ Modified here to take into account the SoftFPA mode

    #ifdef SOFTFPA

@;@@@ In SoftFPA mode double arguments are passed like in the the Big Endian mode

#define dxh  r0                         @;volatile        double argument x, hi 32 bits

#define dxl  r1                         @;volatile        double argument x, lo 32 bits

#define dyh  r2

#define dyl  r3

    #else

#define dxh  r1                         @;volatile        double argument x, hi 32 bits

#define dxl  r0                         @;volatile        double argument x, lo 32 bits

#define dyh  r3

#define dyl  r2 

    #endif

@;@@@ Added next four definitions for long long registers   

#define llh  r1

#define lll  r0                         @;long long registers for first argument

#define lyh  r3

#define lyl  r2                         @;long long registers for second argument

#define drh  r11                        @;nonvolatile double argument result, hi 32 bits

#define drl  r12                        @;nonvolatile double argument result, lo 32 bits

  #endif

@;

@;SIGN

#define rsign  r6                       @;nonvolatile sign of result

@;

@;MANTISSA

#define fyb  r9                         @;nonvolatile y mantissa (x mantissa is unpacked into fr)

@;

@;EXPONENT

#define rexp  r7                        @;nonvolatile exponent of result

#define yexp  r8                        @;nonvolatile same as sreg08@;exponent of y

@;

@;FLOATING-POINT STATUS/ENVIRONMENT

#define vfpstate  r2                    @;volatile    state 0-based code: number - 0, zero - 2, INF - 4, NaN -6

@;                        on converts, may indicate signed/unsigned and length

#define fpstate  r4                     @;nonvolatile state 0-based code: number - 0, zero - 2, INF - 4, NaN -6

@;                        on converts, may indicate signed/unsigned and length

@;

@;FLAGS

@;



@;These flags indicate the type to which a value will be coverted



.equ DST_DBL, 1

.equ DST_FLT, 0

@;

@;===============================================================================

@;CONSTANTS 

@;

#define EXCEPTION_ENABLE_SHIFT 8

#define EXCEPTION_ENABLE_MASK (0x1F << EXCEPTION_ENABLE_SHIFT)


  #if defined(IEEE_FULL) || defined(IEEE_FIXED)



#define INVALID_BIT #0x00000001

#define DIVBYZERO_BIT  #0x00000002

#define OVERFLOW_BIT #0x00000004

#define UNDERFLOW_BIT #0x00000008

#define INEXACT_BIT #0x00000010

#define STICKY_FLAGS_SHIFT 0

#define STICKY_FLAGS_MASK (0x1F << STICKY_FLAGS_SHIFT)



#define ROUND_MODE_MASK #0x00C00000

#define ROUND_MODE_BIT_SHIFT #22

#define FE_TONEAREST #0x00000000          @ ;/* FPSCR bits[23:22] = 0b00 */

#define FE_TOWARDZERO #0x00C00000         @ ;/* FPSCR bits[23:22] = 0b11 */

#define FE_UPWARD #0x00400000            @;/* FPSCR bits[23:22] = 0b01 */

#define FE_DOWNWARD #0x00800000           @;/* FPSCR bits[23:22] = 0b10 */



@;@@@ Added next lines

#define FE_IEEE_MASK_INVALID #0x00000100

#define FE_IEEE_MASK_DIVBYZERO #0x00000200

#define FE_IEEE_MASK_OVERFLOW #0x00000400

#define FE_IEEE_MASK_UNDERFLOW #0x00000800

#define FE_IEEE_MASK_INEXACT #0x00001000


#define FE_EX_RDIR              (-1 << 31)

#define FE_EX_EXCEPT_SHIFT      (26)

#define FE_EX_EXCEPT_MASK       (0x1F << FE_EX_EXCEPT_SHIFT)

#define FE_EX_INEXACT           (0x10 << FE_EX_EXCEPT_SHIFT)

#define FE_EX_UNDERFLOW         (0x08 << FE_EX_EXCEPT_SHIFT)

#define FE_EX_OVERFLOW          (0x04 << FE_EX_EXCEPT_SHIFT)

#define FE_EX_DIVBYZERO         (0x02 << FE_EX_EXCEPT_SHIFT)

#define FE_EX_INVALID           (0x01 << FE_EX_EXCEPT_SHIFT)

#define FE_EX_FLUSHZERO_SHIFT   (24)

#define FE_EX_FLUSHZERO         (1 << FE_EX_FLUSHZERO_SHIFT)

#define FE_EX_ROUND_SHIFT       (22)

#define FE_EX_ROUND_MASK        (3 << FE_EX_ROUND_SHIFT)

#define FE_EX_INTYPE_SHIFT      (7)

#define FE_EX_INTYPE_MASK       (7 << FE_EX_INTYPE_SHIFT)

#define FE_EX_OUTTYPE_SHIFT     (4)

#define FE_EX_OUTTYPE_MASK      (7 << FE_EX_OUTTYPE_SHIFT)

#define FE_EX_TYPE_SHIFT        (4)

#define FE_EX_TYPE_MASK         (7 << FE_EX_TYPE_SHIFT)

#define FE_EX_FN_SHIFT          (0)

#define FE_EX_FN_MASK           (15 << FE_EX_FN_SHIFT)



#define FE_EX_ROUND_NEAREST     (0 << FE_EX_ROUND_SHIFT)

#define FE_EX_ROUND_PLUSINF     (1 << FE_EX_ROUND_SHIFT)

#define FE_EX_ROUND_MINUSINF    (2 << FE_EX_ROUND_SHIFT)

#define FE_EX_ROUND_ZERO        (3 << FE_EX_ROUND_SHIFT)



#define FE_EX_BASETYPE_FLOAT    (0)

#define FE_EX_BASETYPE_DOUBLE   (1)

#define FE_EX_BASETYPE_INT      (4)

#define FE_EX_BASETYPE_LONGLONG (5)

#define FE_EX_BASETYPE_UINT     (6)

#define FE_EX_BASETYPE_ULONGLONG (7)



#define FE_EX_TYPE_FLOAT        (FE_EX_BASETYPE_FLOAT << FE_EX_TYPE_SHIFT)

#define FE_EX_TYPE_DOUBLE       (FE_EX_BASETYPE_DOUBLE << FE_EX_TYPE_SHIFT)

#define FE_EX_TYPE_INT          (FE_EX_BASETYPE_INT << FE_EX_TYPE_SHIFT)

#define FE_EX_TYPE_LONGLONG     (FE_EX_BASETYPE_LONGLONG << FE_EX_TYPE_SHIFT)

#define FE_EX_TYPE_UINT         (FE_EX_BASETYPE_UINT << FE_EX_TYPE_SHIFT)

#define FE_EX_TYPE_ULONGLONG    (FE_EX_BASETYPE_ULONGLONG << FE_EX_TYPE_SHIFT)



#define FE_EX_INTYPE_FLOAT      (FE_EX_BASETYPE_FLOAT << FE_EX_INTYPE_SHIFT)

#define FE_EX_INTYPE_DOUBLE     (FE_EX_BASETYPE_DOUBLE << FE_EX_INTYPE_SHIFT)

#define FE_EX_INTYPE_INT        (FE_EX_BASETYPE_INT << FE_EX_INTYPE_SHIFT)

#define FE_EX_INTYPE_LONGLONG   (FE_EX_BASETYPE_LONGLONG << FE_EX_INTYPE_SHIFT)

#define FE_EX_INTYPE_UINT       (FE_EX_BASETYPE_UINT << FE_EX_INTYPE_SHIFT)

#define FE_EX_INTYPE_ULONGLONG  (FE_EX_BASETYPE_ULONGLONG<<FE_EX_INTYPE_SHIFT)



#define FE_EX_OUTTYPE_FLOAT     (FE_EX_BASETYPE_FLOAT << FE_EX_OUTTYPE_SHIFT)

#define FE_EX_OUTTYPE_DOUBLE    (FE_EX_BASETYPE_DOUBLE << FE_EX_OUTTYPE_SHIFT)

#define FE_EX_OUTTYPE_INT       (FE_EX_BASETYPE_INT << FE_EX_OUTTYPE_SHIFT)

#define FE_EX_OUTTYPE_LONGLONG  (FE_EX_BASETYPE_LONGLONG<<FE_EX_OUTTYPE_SHIFT)

#define FE_EX_OUTTYPE_UINT      (FE_EX_BASETYPE_UINT << FE_EX_OUTTYPE_SHIFT)

#define FE_EX_OUTTYPE_ULONGLONG (FE_EX_BASETYPE_ULONGLONG<<FE_EX_OUTTYPE_SHIFT)



#define FE_EX_FN_ADD            (1 << FE_EX_FN_SHIFT)

#define FE_EX_FN_SUB            (2 << FE_EX_FN_SHIFT)

#define FE_EX_FN_MUL            (3 << FE_EX_FN_SHIFT)

#define FE_EX_FN_DIV            (4 << FE_EX_FN_SHIFT)

#define FE_EX_FN_REM            (5 << FE_EX_FN_SHIFT)

#define FE_EX_FN_RND            (6 << FE_EX_FN_SHIFT)

#define FE_EX_FN_SQRT           (7 << FE_EX_FN_SHIFT)

#define FE_EX_FN_CVT            (8 << FE_EX_FN_SHIFT)

#define FE_EX_FN_CMP            (9 << FE_EX_FN_SHIFT)

#define FE_EX_FN_RAISE          (15 << FE_EX_FN_SHIFT)



#define FE_EX_CMPRET_UNORDERED  (8)

#define FE_EX_CMPRET_LESS       (4)

#define FE_EX_CMPRET_EQUAL      (2)

#define FE_EX_CMPRET_GREATER    (1)





@;Bits separating rounding mode cases

#define CHOP_OR_DOWN_BIT_OFFSET 23

#define CHOP_OR_UP_BIT_OFFSET 22



#define CHOP_OR_DOWN_BIT_MASK #(1 << CHOP_OR_DOWN_BIT_OFFSET)

#define CHOP_OR_UP_BIT_MASK #(1 << CHOP_OR_UP_BIT_OFFSET)



@;#define DIRECTED_BIT_SHIFT #30



@;Bits selecting rounding mode cases

#define UP_OR_NEAR_BIT_MASK #(1 << CHOP_OR_UP_BIT_OFFSET)

#define DOWN_OR_NEAR_BIT_MASK #(1 << CHOP_OR_DOWN_BIT_OFFSET)

#define ZERO_OR_UP_BIT_MASK #(1 << CHOP_OR_DOWN_BIT_OFFSET)

#define ZERO_OR_DOWN_BIT_MASK #(1 << CHOP_OR_UP_BIT_OFFSET)

#define CHOP_OR_DOWN_BIT_SHIFT #31



@;@@@ Added next definitions

    #ifndef IEEE_FIXED

#define OVERFLOW_MASK #0x00000014

#define UNDERFLOW_MASK #0x00000018

    #else                                   @;never set inexact in IEEE_FIXED mode

#define OVERFLOW_MASK #0x00000004

#define UNDERFLOW_MASK #0x00000008

#endif


#ifdef THUMB

Return_lr: .macro

        ldmfd   sp!, {lr}

        bx      lr

        .endm

#else

Return_lr: .macro

        ldmfd   sp!, {pc}

        .endm

    #endif

    

#endif  @;defined(IEEE_FULL) || defined(IEEE_FIXED)

@;===============================================================================

@;Macro definitions

@;



@;MACRO: LFPState       (Load floating point state)

@;DESCRIPTION: Loads the floating point state word from software/hardware FPSCR.

@;PARAMETERS: fpstate_reg - value of FPSCR 

@;            addr_reg    - software fp: address of the software FPSCR

@;                        - hardware fp: not used

@;INPUT:      none

@;OUTPUT:     fpstate_reg, addr_reg (soft fp only)

@;            (if addr_reg==fpstate_reg, the macro returns the value of FPSCR 

@;            and its address is lost)



  #ifdef VFP

LFPState: .macro fpstate_reg, addr_reg

        fmrx    fpstate_reg, FPSCR

        .endm
 #elif __VFPV4__
 
 LFPState: .macro fpstate_reg, addr_reg
 
	vmrs    \fpstate_reg, FPSCR
	
	.endm
	
#elif (IEEE_FULL) || (IEEE_FIXED)

LFPState: .macro fpstate_reg, addr_reg

      .if \addr_reg ==0

        stmfd   sp!, {r1-r3, r12, lr}

        bl      __rt_fp_status_addr

        ldmfd   sp!, {r1-r3, r12, lr}

      .elif \addr_reg ==1

        stmfd   sp!, {r0, r2-r3, r12, lr}

        bl      __rt_fp_status_addr

        mov     r1, r0

        ldmfd   sp!, {r0, r2-r3, r12, lr}

      .elseif \addr_reg == 2

        stmfd   sp!, {r0-r1, r3, r12, lr}

        bl      __rt_fp_status_addr

        mov     r2, r0

        ldmfd   sp!, {r0-r1, r3, r12, lr}

      .elseif \addr_reg == 3

        stmfd   sp!, {r0-r2, r12, lr}

        bl      __rt_fp_status_addr

        mov     r3, r0

        ldmfd   sp!, {r0-r2, r12, lr}

      .elseif \addr_reg == 12

        stmfd   sp!, {r0-r3, lr}

        bl      __rt_fp_status_addr

        mov     r12, r0

        ldmfd   sp!, {r0-r3, lr}

      .elseif \addr_reg == 13

        stmfd   sp!, {r0-r3,r12}

        bl      __rt_fp_status_addr

        mov     lr, r0

        ldmfd   sp!, {r0-r3,r12}

      .else

        stmfd   sp!, {r0-r3, r12, lr}

        bl      __rt_fp_status_addr

        mov     \addr_reg, r0

        ldmfd   sp!, {r0-r3, r12, lr}              

      .endif

       ldr     \fpstate_reg, [\addr_reg]

      .endm

  #endif



  

@;MACRO: StFPState      (Store floating point state)

@;DESCRIPTION: Store state word back to software/hardware FPSCR.

@;PARAMETERS: fpstate_reg - value of FPSCR 

@;            addr_reg    - software fp: address of the software FPSCR

@;                        - hardware fp: not used

@;INPUT:      fpstate_reg, addr_reg (soft fp only)

@;OUTPUT:     none

  #ifdef VFP

StFPState: .macro fpstate_reg, addr_reg 

        fmxr    FPSCR,fpstate_reg

        .endm

  #elif __VFPV4__
StFPState: .macro fpstate_reg, addr_reg 
	
        vmsr    FPSCR,\fpstate_reg

        .endm

  #else if (IEEE_FULL || IEEE_FIXED)

StFPState: .macro fpstate_reg, addr_reg 

        str     \fpstate_reg, [\addr_reg]

        .endm

  #endif



#if defined(IEEE_FULL) || defined(IEEE_FIXED)



@;MACRO: SetInvalid

@;DESCRIPTION: Set the invalid flag.



SetInvalid: .macro fpstate2

        orr     fpstate2,fpstate2,INVALID_BIT

        .endm



@;MACRO: SetInexact

@;DESCRIPTION: Set the inexact flag or jump to __wrap_inexact_handler

@;Modified for user defined handlers



SetInexact: .macro fpstate2

        tst     fpstate2, FE_IEEE_MASK_INEXACT

        bne     __wrap_inexact_handler

        orr     fpstate2, fpstate2, INEXACT_BIT

        .endm



@;MACRO: SetInexactL

@;DESCRIPTION: Set the inexact flag or jump to the specified label

@;Modified for user defined handlers



SetInexactL: .macro fpstate2, where

        tst     fpstate2, FE_IEEE_MASK_INEXACT

        bne     where

        orr     fpstate2, fpstate2, INEXACT_BIT

        .endm



@;MACRO: SetOverflow

@;DESCRIPTION: Set the overflow and inexact flags or jump to __wrap_overflow_handler

@;Modified for user defined handlers



SetOverflow: .macro fpstate2, where

        tst     fpstate2, FE_IEEE_MASK_OVERFLOW

        bne     __wrap_overflow_handler

        orr     fpstate2, fpstate2, OVERFLOW_MASK

        .endm



@;MACRO: SetOverflowL

@;DESCRIPTION: Set the overflow and inexact flags or jump to the specified label

@;Modified for user defined handlers



SetOverflowL: .macro fpstate2, where

        tst     fpstate2, FE_IEEE_MASK_OVERFLOW

        bne     where

        orr     fpstate2, fpstate2, OVERFLOW_MASK

        .endm



@;MACRO: SetUnderflow

@;DESCRIPTION: Set the underflow and inexact flags or jump to __wrap_inexact_handler

@;Modified for user defined handlers



    #ifdef IEEE_FULL

SetUnderflow: .macro fpstate2

        tst     fpstate2, FE_IEEE_MASK_INEXACT

        bne     __wrap_inexact_handler

        orr     fpstate2, fpstate2, UNDERFLOW_MASK

        .endm

    #else

SetUnderflow: .macro fpstate2

        orr     fpstate2, fpstate2, UNDERFLOW_MASK

        .endm

    #endif



@;MACRO: SetDivByZero

@;DESCRIPTION: Set the divide by zero flag.



SetDivByZero: .macro fpstate2

        tst     fpstate2, FE_IEEE_MASK_DIVBYZERO

        bne     __wrap_divbyzero_handler

        orr     fpstate2, fpstate2, DIVBYZERO_BIT

        .endm



@;MACRO: SetInvalidE

@;DESCRIPTION: Set the invalid flag or jump to __wrap_invalid_handler

@;Modified for user defined handlers



SetInvalidE: .macro fpstate2

        tst     fpstate2, FE_IEEE_MASK_INVALID

        bne     __wrap_invalid_handler

        orr     fpstate2,fpstate2,INVALID_BIT

        .endm



@;MACRO: SetInvalidEL

@;DESCRIPTION: Set the invalid flag or jump to the specified label

@;Modified for user defined handlers



SetInvalidEL: .macro fpstate2, label

        tst     fpstate2, FE_IEEE_MASK_INVALID

        bne     label

        orr     fpstate2,fpstate2,INVALID_BIT

        .endm



 #endif                                 @;IEEE_FULL || IEEE_FIXED





@;MACRO: MakeFNaN (Make Floating NaN)

@;DESCRIPTION: Create default float NaN in v0

@;COMPATIBILITY: Sign is always positive in new NaNs, as with PowerPC.

@;



MakeFNaN: .macro

@;@@@ Modified here

        ldr     fx,=0x7fffffff

        .endm



@;MACRO: MakeDNaN (Make Double NaN)

@;DESCRIPTION: Create default double NaN in dxh/dxl

@;COMPATIBILITY: Sign is always positive in new NaNs, as with PowerPC.

@;TRICK: Force the leading fraction bit to be zero, as in MIPS ISA.

@;



MakeDNaN: .macro

@;@@@ Modified here

        mvn     dxl, #0

        bic     dxh, dxl, #0x80000000

        .endm



@;@@@ Added: nomalize macro

Normalize: .macro number, shift

@; #ifndef ARM5

        cmp     \number, #0x00010000

        sublo   \shift, \shift, #16

        movlo   \number, \number, LSL #16

        cmp     \number, #0x01000000

        sublo   \shift, \shift, #8

        movlo   \number, \number, LSL #8

        cmp     \number, #0x10000000

        sublo   \shift, \shift, #4

        movlo   \number, \number, LSL #4

        cmp     \number, #0x40000000

        sublo   \shift, \shift, #2

        movlo   \number, \number, LSL #2

        cmp     \number,#0

        subpl   \shift,\shift, #1

        addpl   \number, \number, \number  @;LSL #1  

@; #else

@;@@@ Add code for ARM5 here

@; #endif

        .endm



@;@@@ Added: nomalize macro

@;@@@ Behaves differently for ARM4T and ARM5

Normalize_a5: .macro number, shift, temp

  #ifndef ARM5

        cmp     \number, #0x00010000

        sublo   \shift, \shift, #16

        movlo   \number, \number, LSL #16

        cmp     \number, #0x01000000

        sublo   \shift, \shift, #8

        movlo   \number, \number, LSL #8

        cmp     \number, #0x10000000

        sublo   \shift, \shift, #4

        movlo   \number, \number, LSL #4

        cmp     \number, #0x40000000

        sublo   \shift, \shift, #2

        movlo   \number, \number, LSL #2

        cmp     \number,#0

        subpl   \shift, \shift, #1

        addpl   \number, \number, \number  @;LSL #1  

  #else

@;@@@ Add code for ARM5 here

        clz     temp, number

        movs    number, number, LSL temp

        sub     shift, shift, temp 

  #endif

        .endm



@;@@@ Added: nomalize macro for special case (shift is a number)

@;@@@ Behaves differently for ARM4T and ARM5

Normalize_num: .macro number, shift, init

  #ifndef ARM5

        mov     \shift, \init

        cmp     \number, #0x00010000

        sublo   \shift, \shift, #16

        movlo   \number, \number, LSL #16

        cmp    \number, #0x01000000

        sublo   \shift, \shift, #8

        movlo   \number, \number, LSL #8

        cmp     \number, #0x10000000

        sublo   \shift, \shift, #4

        movlo   \number, \number, LSL #4

        cmp     \number, #0x40000000

        sublo   \shift, \shift, #2

        movlo   \number, \number, LSL #2

        cmp     \number,#0

        subpl   \shift, \shift, #1

        addpl   \number, \number, \number  @;LSL #1  

  #else

@;@@@ Add code for ARM5 here

        clz     shift, number

        movs    number, number, LSL shift

        rsb     shift, shift, init

  #endif

        .endm





#endif


@/* Chipwerks change record:
@* April 07, 2006 changed the labels with reference to RUN-TIME ABI FOR THE ARM ARCHITECTURE document
@*/	
