Update ARM_CRx_No_GIC port (#1101)

This PR makes the following improvements to the ARM_CRx_No_GIC port-

1. Remove inline assembly and move all the assembly code to the portASM.S
    file.

2. Add support for configUSE_TASK_FPU_SUPPORT -
   - When configUSE_TASK_FPU_SUPPORT is defined to 1, tasks are created
      without floating point context. Tasks that want to use floating point, need
      to call portTASK_USES_FLOATING_POINT(). This is the current behavior.
   - When configUSE_TASK_FPU_SUPPORT is defined to 2, each task is created
      with a floating point context.
  If left undefined, configUSE_TASK_FPU_SUPPORT defaults to 1 for backward compatibility.

3. The application writer can now implement vApplicationSVCHandler to handle the
    SVC calls raised within the application. SVC 0 is used for the yield kernel operation
    and the application can use all the SVC calls other than 0.

Signed-off-by: kar-rahul-aws <karahulx@amazon.com>
diff --git a/portable/GCC/ARM_CRx_No_GIC/port.c b/portable/GCC/ARM_CRx_No_GIC/port.c
index 7294fb7..bd5a19a 100644
--- a/portable/GCC/ARM_CRx_No_GIC/port.c
+++ b/portable/GCC/ARM_CRx_No_GIC/port.c
@@ -28,6 +28,7 @@
 
 /* Standard includes. */
 #include <stdlib.h>
+#include <string.h>
 
 /* Scheduler includes. */
 #include "FreeRTOS.h"
@@ -80,13 +81,22 @@
     #define portTASK_RETURN_ADDRESS    prvTaskExitError
 #endif
 
+/* The space on the stack required to hold the FPU registers. */
+#if ( configFPU_D32 == 1 )
+    #define portFPU_REGISTER_WORDS     ( ( 32 * 2 ) + 1 ) /* D0-D31 and FPSCR. */
+#else
+    #define portFPU_REGISTER_WORDS     ( ( 16 * 2 ) + 1 ) /* D0-D15 and FPSCR. */
+#endif /* configFPU_D32 */
+
 /*-----------------------------------------------------------*/
 
 /*
- * Starts the first task executing.  This function is necessarily written in
- * assembly code so is implemented in portASM.s.
+ * These functions are necessarily written in assembly code, so are implemented
+ * in portASM.S.
  */
 extern void vPortRestoreTaskContext( void );
+extern void vPortInitialiseFPSCR( void );
+extern uint32_t ulReadAPSR( void );
 
 /*
  * Used to catch tasks that attempt to return from their implementing function.
@@ -184,12 +194,33 @@
     /* The task will start with a critical nesting count of 0 as interrupts are
      * enabled. */
     *pxTopOfStack = portNO_CRITICAL_NESTING;
-    pxTopOfStack--;
 
-    /* The task will start without a floating point context.  A task that uses
-     * the floating point hardware must call vPortTaskUsesFPU() before executing
-     * any floating point instructions. */
-    *pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
+    #if ( configUSE_TASK_FPU_SUPPORT == 1 )
+    {
+        /* The task will start without a floating point context.  A task that uses
+         * the floating point hardware must call vPortTaskUsesFPU() before executing
+         * any floating point instructions. */
+        pxTopOfStack--;
+        *pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
+    }
+    #elif ( configUSE_TASK_FPU_SUPPORT == 2 )
+    {
+        /* The task will start with a floating point context.  Leave enough
+         * space for the registers - and ensure they are initialised to 0. */
+        pxTopOfStack -= portFPU_REGISTER_WORDS;
+        memset( pxTopOfStack, 0x00, portFPU_REGISTER_WORDS * sizeof( StackType_t ) );
+
+        /* Initialise the slot containing ulPortTaskHasFPUContext to true as
+         * the task starts with a floating point context. */
+        pxTopOfStack--;
+        *pxTopOfStack = pdTRUE;
+        ulPortTaskHasFPUContext = pdTRUE;
+    }
+    #else
+    {
+        #error "Invalid configUSE_TASK_FPU_SUPPORT value - configUSE_TASK_FPU_SUPPORT must be set to 1, 2, or left undefined."
+    }
+    #endif /* if ( configUSE_TASK_FPU_SUPPORT == 1 ) */
 
     return pxTopOfStack;
 }
@@ -218,7 +249,7 @@
 
     /* Only continue if the CPU is not in User mode.  The CPU must be in a
      * Privileged mode for the scheduler to start. */
-    __asm volatile ( "MRS %0, APSR" : "=r" ( ulAPSR )::"memory" );
+    ulAPSR = ulReadAPSR();
 
     ulAPSR &= portAPSR_MODE_BITS_MASK;
     configASSERT( ulAPSR != portAPSR_USER_MODE );
@@ -310,15 +341,17 @@
 }
 /*-----------------------------------------------------------*/
 
-void vPortTaskUsesFPU( void )
-{
-    uint32_t ulInitialFPSCR = 0;
+#if ( configUSE_TASK_FPU_SUPPORT != 2 )
 
-    /* A task is registering the fact that it needs an FPU context.  Set the
-     * FPU flag (which is saved as part of the task context). */
-    ulPortTaskHasFPUContext = pdTRUE;
+    void vPortTaskUsesFPU( void )
+    {
+        /* A task is registering the fact that it needs an FPU context.  Set the
+         * FPU flag (which is saved as part of the task context). */
+        ulPortTaskHasFPUContext = pdTRUE;
 
-    /* Initialise the floating point status register. */
-    __asm volatile ( "FMXR  FPSCR, %0" ::"r" ( ulInitialFPSCR ) : "memory" );
-}
+        /* Initialise the floating point status register. */
+        vPortInitialiseFPSCR();
+    }
+
+#endif /* configUSE_TASK_FPU_SUPPORT */
 /*-----------------------------------------------------------*/
diff --git a/portable/GCC/ARM_CRx_No_GIC/portASM.S b/portable/GCC/ARM_CRx_No_GIC/portASM.S
index 349a940..9945fc2 100644
--- a/portable/GCC/ARM_CRx_No_GIC/portASM.S
+++ b/portable/GCC/ARM_CRx_No_GIC/portASM.S
@@ -28,14 +28,14 @@
 
     .text
     .arm
+    .syntax unified
 
-    .set SYS_MODE,  0x1f
-    .set SVC_MODE,  0x13
-    .set IRQ_MODE,  0x12
+    .set SYS_MODE,   0x1f
+    .set SVC_MODE,   0x13
+    .set IRQ_MODE,   0x12
+    .set CPSR_I_BIT, 0x80
 
     /* Variables and functions. */
-    .extern ulMaxAPIPriorityMask
-    .extern _freertos_vector_table
     .extern pxCurrentTCB
     .extern vTaskSwitchContext
     .extern vApplicationIRQHandler
@@ -47,29 +47,38 @@
     .global FreeRTOS_IRQ_Handler
     .global FreeRTOS_SVC_Handler
     .global vPortRestoreTaskContext
+    .global vPortInitialiseFPSCR
+    .global ulReadAPSR
+    .global vPortYield
+    .global vPortEnableInterrupts
+    .global vPortDisableInterrupts
+    .global ulPortSetInterruptMaskFromISR
+    .global ulPortCountLeadingZeros
 
+    .weak   vApplicationSVCHandler
+/*-----------------------------------------------------------*/
 
 .macro portSAVE_CONTEXT
 
     /* Save the LR and SPSR onto the system mode stack before switching to
-    system mode to save the remaining system mode registers. */
-    SRSDB   sp!, #SYS_MODE
+     * system mode to save the remaining system mode registers. */
+    SRSDB   SP!, #SYS_MODE
     CPS     #SYS_MODE
     PUSH    {R0-R12, R14}
 
     /* Push the critical nesting count. */
-    LDR     R2, ulCriticalNestingConst
+    LDR     R2, =ulCriticalNesting
     LDR     R1, [R2]
     PUSH    {R1}
 
     /* Does the task have a floating point context that needs saving?  If
-    ulPortTaskHasFPUContext is 0 then no. */
-    LDR     R2, ulPortTaskHasFPUContextConst
+     * ulPortTaskHasFPUContext is 0 then no. */
+    LDR     R2, =ulPortTaskHasFPUContext
     LDR     R3, [R2]
     CMP     R3, #0
 
     /* Save the floating point context, if any. */
-    FMRXNE  R1,  FPSCR
+    VMRSNE  R1,  FPSCR
     VPUSHNE {D0-D15}
 #if configFPU_D32 == 1
     VPUSHNE {D16-D31}
@@ -80,24 +89,24 @@
     PUSH    {R3}
 
     /* Save the stack pointer in the TCB. */
-    LDR     R0, pxCurrentTCBConst
+    LDR     R0, =pxCurrentTCB
     LDR     R1, [R0]
     STR     SP, [R1]
 
     .endm
 
-; /**********************************************************************/
+/*-----------------------------------------------------------*/
 
 .macro portRESTORE_CONTEXT
 
     /* Set the SP to point to the stack of the task being restored. */
-    LDR     R0, pxCurrentTCBConst
+    LDR     R0, =pxCurrentTCB
     LDR     R1, [R0]
     LDR     SP, [R1]
 
     /* Is there a floating point context to restore?  If the restored
-    ulPortTaskHasFPUContext is zero then no. */
-    LDR     R0, ulPortTaskHasFPUContextConst
+     * ulPortTaskHasFPUContext is zero then no. */
+    LDR     R0, =ulPortTaskHasFPUContext
     POP     {R1}
     STR     R1, [R0]
     CMP     R1, #0
@@ -111,7 +120,7 @@
     VMSRNE  FPSCR, R0
 
     /* Restore the critical section nesting depth. */
-    LDR     R0, ulCriticalNestingConst
+    LDR     R0, =ulCriticalNesting
     POP     {R1}
     STR     R1, [R0]
 
@@ -120,29 +129,17 @@
     POP     {R0-R12, R14}
 
     /* Return to the task code, loading CPSR on the way. */
-    RFEIA   sp!
+    RFEIA   SP!
 
     .endm
 
+/*-----------------------------------------------------------*/
 
-
-
-/******************************************************************************
- * SVC handler is used to yield.
- *****************************************************************************/
-.align 4
-.type FreeRTOS_SVC_Handler, %function
-FreeRTOS_SVC_Handler:
-    /* Save the context of the current task and select a new task to run. */
-    portSAVE_CONTEXT
-    LDR R0, vTaskSwitchContextConst
-    BLX R0
-    portRESTORE_CONTEXT
-
-
-/******************************************************************************
+/*
+ * void vPortRestoreTaskContext( void );
+ *
  * vPortRestoreTaskContext is used to start the scheduler.
- *****************************************************************************/
+ */
 .align 4
 .type vPortRestoreTaskContext, %function
 vPortRestoreTaskContext:
@@ -150,72 +147,212 @@
     CPS     #SYS_MODE
     portRESTORE_CONTEXT
 
+/*-----------------------------------------------------------*/
+
+/*
+ * void vPortInitialiseFPSCR( void );
+ *
+ * vPortInitialiseFPSCR is used to initialize the FPSCR register.
+ */
+.align 4
+.type vPortInitialiseFPSCR, %function
+vPortInitialiseFPSCR:
+    MOV     R0, #0
+    VMSR    FPSCR, R0
+    BX      LR
+
+/*-----------------------------------------------------------*/
+
+/*
+ * uint32_t ulReadAPSR( void );
+ *
+ * ulReadAPSR is used to read the value of APSR context.
+ */
+.align 4
+.type ulReadAPSR, %function
+ulReadAPSR:
+    MRS R0, APSR
+    BX  LR
+
+/*-----------------------------------------------------------*/
+
+/*
+ * void vPortYield( void );
+ */
+.align 4
+.type vPortYield, %function
+vPortYield:
+    SVC 0
+    ISB
+    BX  LR
+
+/*-----------------------------------------------------------*/
+
+/*
+ * void vPortEnableInterrupts( void );
+ */
+.align 4
+.type vPortEnableInterrupts, %function
+vPortEnableInterrupts:
+    CPSIE   I
+    BX      LR
+
+/*-----------------------------------------------------------*/
+
+/*
+ * void vPortDisableInterrupts( void );
+ */
+.align 4
+.type vPortDisableInterrupts, %function
+vPortDisableInterrupts:
+    CPSID    I
+    DSB
+    ISB
+    BX      LR
+
+/*-----------------------------------------------------------*/
+
+/*
+ * uint32_t ulPortSetInterruptMaskFromISR( void );
+ */
+.align 4
+.type ulPortSetInterruptMaskFromISR, %function
+ulPortSetInterruptMaskFromISR:
+    MRS     R0, CPSR
+    AND     R0, R0, #CPSR_I_BIT
+    CPSID   I
+    DSB
+    ISB
+    BX      LR
+
+/*-----------------------------------------------------------*/
+
+/*
+ * void vApplicationSVCHandler( uint32_t ulSvcNumber );
+ */
+.align 4
+.type vApplicationSVCHandler, %function
+vApplicationSVCHandler:
+    B vApplicationSVCHandler
+
+/*-----------------------------------------------------------*/
+
+/*
+ * UBaseType_t ulPortCountLeadingZeros( UBaseType_t ulBitmap );
+ *
+ * According to the Procedure Call Standard for the ARM Architecture (AAPCS):
+ * - Parameter ulBitmap is passed in R0.
+ * - Return value must be in R0.
+ */
+.align 4
+.type ulPortCountLeadingZeros, %function
+ulPortCountLeadingZeros:
+    CLZ     R0, R0
+    BX      LR
+
+/*-----------------------------------------------------------*/
+
+/*
+ * SVC handler is used to yield.
+ */
+.align 4
+.type FreeRTOS_SVC_Handler, %function
+FreeRTOS_SVC_Handler:
+    PUSH    { R0-R1 }
+
+    /* ---------------------------- Get Caller SVC Number ---------------------------- */
+    MRS     R0, SPSR               /* R0 = CPSR at the time of SVC. */
+    TST     R0, #0x20              /* Check Thumb bit (5) in CPSR. */
+    LDRHNE  R0, [LR, #-0x2]        /* If Thumb, load halfword. */
+    BICNE   R0, R0, #0xFF00        /* And extract immidiate field (i.e. SVC number). */
+    LDREQ   R0, [LR, #-0x4]        /* If ARM, load word. */
+    BICEQ   R0, R0, #0xFF000000    /* And extract immidiate field (i.e. SVC number). */
+
+    /* --------------------------------- SVC Routing --------------------------------- */
+    CMP     R0, #0
+    BEQ     svcPortYield
+    BNE     svcApplicationCall
+
+svcPortYield:
+    POP     { R0-R1 }
+    portSAVE_CONTEXT
+    BLX     vTaskSwitchContext
+    portRESTORE_CONTEXT
+
+svcApplicationCall:
+    POP     { R0-R1 }
+    portSAVE_CONTEXT
+    BLX     vApplicationSVCHandler
+    portRESTORE_CONTEXT
+
+/*-----------------------------------------------------------*/
+
 .align 4
 .type FreeRTOS_IRQ_Handler, %function
 FreeRTOS_IRQ_Handler:
     /* Return to the interrupted instruction. */
-    SUB     lr, lr, #4
+    SUB     LR, LR, #4
 
     /* Push the return address and SPSR. */
-    PUSH    {lr}
-    MRS     lr, SPSR
-    PUSH    {lr}
+    PUSH    {LR}
+    MRS     LR, SPSR
+    PUSH    {LR}
 
     /* Change to supervisor mode to allow reentry. */
-    CPS     #0x13
+    CPS     #SVC_MODE
 
     /* Push used registers. */
-    PUSH    {r0-r3, r12}
+    PUSH    {R0-R3, R12}
 
     /* Increment nesting count.  r3 holds the address of ulPortInterruptNesting
-    for future use.  r1 holds the original ulPortInterruptNesting value for
-    future use. */
-    LDR     r3, ulPortInterruptNestingConst
-    LDR     r1, [r3]
-    ADD     r0, r1, #1
-    STR     r0, [r3]
+     * for future use.  r1 holds the original ulPortInterruptNesting value for
+     * future use. */
+    LDR     R3, =ulPortInterruptNesting
+    LDR     R1, [R3]
+    ADD     R0, R1, #1
+    STR     R0, [R3]
 
     /* Ensure bit 2 of the stack pointer is clear.  r2 holds the bit 2 value for
-    future use. */
-    MOV     r0, sp
-    AND     r2, r0, #4
-    SUB     sp, sp, r2
+     * future use. */
+    MOV     R0, SP
+    AND     R2, R0, #4
+    SUB     SP, SP, R2
 
     /* Call the interrupt handler. */
-    PUSH    {r0-r3, lr}
-    LDR     r1, vApplicationIRQHandlerConst
-    BLX     r1
-    POP     {r0-r3, lr}
-    ADD     sp, sp, r2
+    PUSH    {R0-R3, LR}
+    BLX     vApplicationIRQHandler
+    POP     {R0-R3, LR}
+    ADD     SP, SP, R2
 
+    /* Disable IRQs incase vApplicationIRQHandler enabled them for re-entry. */
     CPSID   i
     DSB
     ISB
 
     /* Write to the EOI register. */
-    LDR     r0, ulICCEOIRConst
-    LDR     r2, [r0]
-    STR     r0, [r2]
+    LDR     R0, =ulICCEOIR
+    LDR     R2, [R0]
+    STR     R0, [R2]
 
     /* Restore the old nesting count. */
-    STR     r1, [r3]
+    STR     R1, [R3]
 
     /* A context switch is never performed if the nesting count is not 0. */
-    CMP     r1, #0
+    CMP     R1, #0
     BNE     exit_without_switch
 
     /* Did the interrupt request a context switch?  r1 holds the address of
-    ulPortYieldRequired and r0 the value of ulPortYieldRequired for future
-    use. */
-    LDR     r1, ulPortYieldRequiredConst
-    LDR     r0, [r1]
-    CMP     r0, #0
+     * ulPortYieldRequired and r0 the value of ulPortYieldRequired for future
+     * use. */
+    LDR     R1, =ulPortYieldRequired
+    LDR     R0, [R1]
+    CMP     R0, #0
     BNE     switch_before_exit
 
 exit_without_switch:
     /* No context switch.  Restore used registers, LR_irq and SPSR before
-    returning. */
-    POP     {r0-r3, r12}
+     * returning. */
+    POP     {R0-R3, R12}
     CPS     #IRQ_MODE
     POP     {LR}
     MSR     SPSR_cxsf, LR
@@ -224,13 +361,13 @@
 
 switch_before_exit:
     /* A context switch is to be performed.  Clear the context switch pending
-    flag. */
-    MOV     r0, #0
-    STR     r0, [r1]
+     * flag. */
+    MOV     R0, #0
+    STR     R0, [R1]
 
     /* Restore used registers, LR-irq and SPSR before saving the context
-    to the task stack. */
-    POP     {r0-r3, r12}
+     * to the task stack. */
+    POP     {R0-R3, R12}
     CPS     #IRQ_MODE
     POP     {LR}
     MSR     SPSR_cxsf, LR
@@ -238,23 +375,15 @@
     portSAVE_CONTEXT
 
     /* Call the function that selects the new task to execute.
-    vTaskSwitchContext() if vTaskSwitchContext() uses LDRD or STRD
-    instructions, or 8 byte aligned stack allocated data.  LR does not need
-    saving as a new LR will be loaded by portRESTORE_CONTEXT anyway. */
-    LDR     R0, vTaskSwitchContextConst
-    BLX     R0
+     * vTaskSwitchContext() if vTaskSwitchContext() uses LDRD or STRD
+     * instructions, or 8 byte aligned stack allocated data.  LR does not need
+     * saving as a new LR will be loaded by portRESTORE_CONTEXT anyway. */
+    BLX     vTaskSwitchContext
 
     /* Restore the context of, and branch to, the task selected to execute
-    next. */
+     * next. */
     portRESTORE_CONTEXT
 
-ulICCEOIRConst: .word ulICCEOIR
-pxCurrentTCBConst: .word pxCurrentTCB
-ulCriticalNestingConst: .word ulCriticalNesting
-ulPortTaskHasFPUContextConst: .word ulPortTaskHasFPUContext
-vTaskSwitchContextConst: .word vTaskSwitchContext
-vApplicationIRQHandlerConst: .word vApplicationIRQHandler
-ulPortInterruptNestingConst: .word ulPortInterruptNesting
-ulPortYieldRequiredConst: .word ulPortYieldRequired
+/*-----------------------------------------------------------*/
 
 .end
diff --git a/portable/GCC/ARM_CRx_No_GIC/portmacro.h b/portable/GCC/ARM_CRx_No_GIC/portmacro.h
index 5a9ae26..b29bd9b 100644
--- a/portable/GCC/ARM_CRx_No_GIC/portmacro.h
+++ b/portable/GCC/ARM_CRx_No_GIC/portmacro.h
@@ -59,7 +59,7 @@
 typedef unsigned long    UBaseType_t;
 
 typedef uint32_t         TickType_t;
-#define portMAX_DELAY              ( TickType_t ) 0xffffffffUL
+#define portMAX_DELAY    ( TickType_t ) 0xffffffffUL
 
 /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
  * not need to be guarded with a critical section. */
@@ -88,47 +88,31 @@
     }
 
 #define portYIELD_FROM_ISR( x )    portEND_SWITCHING_ISR( x )
-#define portYIELD()                 \
-    __asm volatile ( "SWI 0     \n" \
-                     "ISB         " ::: "memory" );
 
+void vPortYield( void );
 
-/*-----------------------------------------------------------
-* Critical section control
-*----------------------------------------------------------*/
+#define portYIELD()     vPortYield();
+
+/*-----------------------------------------------------------*/
+
+/*
+ * Critical section management.
+ */
 
 extern void vPortEnterCritical( void );
 extern void vPortExitCritical( void );
-extern uint32_t ulPortSetInterruptMask( void );
-extern void vPortClearInterruptMask( uint32_t ulNewMaskValue );
-extern void vPortInstallFreeRTOSVectorTable( void );
-
-/* The I bit within the CPSR. */
-#define portINTERRUPT_ENABLE_BIT    ( 1 << 7 )
+extern void vPortEnableInterrupts( void );
+extern void vPortDisableInterrupts( void );
+extern uint32_t ulPortSetInterruptMaskFromISR( void );
 
 /* In the absence of a priority mask register, these functions and macros
  * globally enable and disable interrupts. */
-#define portENTER_CRITICAL()       vPortEnterCritical();
-#define portEXIT_CRITICAL()        vPortExitCritical();
-#define portENABLE_INTERRUPTS()    __asm volatile ( "CPSIE i   \n" ::: "memory" );
-#define portDISABLE_INTERRUPTS()    \
-    __asm volatile ( "CPSID i   \n" \
-                     "DSB       \n" \
-                     "ISB         " ::: "memory" );
-
-__attribute__( ( always_inline ) ) static __inline uint32_t portINLINE_SET_INTERRUPT_MASK_FROM_ISR( void )
-{
-    volatile uint32_t ulCPSR;
-
-    __asm volatile ( "MRS %0, CPSR" : "=r" ( ulCPSR )::"memory" );
-
-    ulCPSR &= portINTERRUPT_ENABLE_BIT;
-    portDISABLE_INTERRUPTS();
-    return ulCPSR;
-}
-
-#define portSET_INTERRUPT_MASK_FROM_ISR()         portINLINE_SET_INTERRUPT_MASK_FROM_ISR()
-#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x )    do { if( x == 0 ) portENABLE_INTERRUPTS( ); } while( 0 )
+#define portENTER_CRITICAL()                    vPortEnterCritical();
+#define portEXIT_CRITICAL()                     vPortExitCritical();
+#define portENABLE_INTERRUPTS()                 vPortEnableInterrupts();
+#define portDISABLE_INTERRUPTS()                vPortDisableInterrupts();
+#define portSET_INTERRUPT_MASK_FROM_ISR()       ulPortSetInterruptMaskFromISR();
+#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x )  do { if( x == 0 ) portENABLE_INTERRUPTS(); } while( 0 )
 
 /*-----------------------------------------------------------*/
 
@@ -148,9 +132,27 @@
  * handler for whichever peripheral is used to generate the RTOS tick. */
 void FreeRTOS_Tick_Handler( void );
 
-/* Any task that uses the floating point unit MUST call vPortTaskUsesFPU()
- * before any floating point instructions are executed. */
-void vPortTaskUsesFPU( void );
+/**
+ * @brief Returns the number of leading zeros in a 32 bit variable.
+ *
+ * @param[in] ulBitmap 32-Bit number to count leading zeros in.
+ *
+ * @return The number of leading zeros in ulBitmap.
+ */
+UBaseType_t ulPortCountLeadingZeros( UBaseType_t ulBitmap );
+
+/* If configUSE_TASK_FPU_SUPPORT is set to 1 (or left undefined) then tasks are
+ * created without an FPU context and must call vPortTaskUsesFPU() to give
+ * themselves an FPU context before using any FPU instructions.  If
+ * configUSE_TASK_FPU_SUPPORT is set to 2 then all tasks will have an FPU
+ * context by default. */
+#if ( configUSE_TASK_FPU_SUPPORT != 2 )
+    void vPortTaskUsesFPU( void );
+#else
+    /* Each task has an FPU context already, so define this function as a
+     * no-op. */
+    #define vPortTaskUsesFPU()
+#endif
 #define portTASK_USES_FLOATING_POINT()    vPortTaskUsesFPU()
 
 #define portLOWEST_INTERRUPT_PRIORITY           ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL )
@@ -163,19 +165,15 @@
 
 #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
 
-/* Store/clear the ready priorities in a bit map. */
+    /* Store, clear and get the ready priorities in a bit map. */
     #define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities )    ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
     #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities )     ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
-
-/*-----------------------------------------------------------*/
-
-    #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities )    uxTopPriority = ( 31UL - ( uint32_t ) __builtin_clz( uxReadyPriorities ) )
+    #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities )  uxTopPriority = ( 31UL - ulPortCountLeadingZeros( ( uxTopReadyPriority ) ) )
 
 #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
 
 #define portNOP()               __asm volatile ( "NOP" )
-#define portINLINE    __inline
-
+#define portINLINE              __inline
 #define portMEMORY_BARRIER()    __asm volatile ( "" ::: "memory" )
 
 /* *INDENT-OFF* */