/*
* @filename PFM_CPUCheck.c
* @brief Platform Function Module:CPU自检
* @details
* 
* @author GT-BU
* @date 2021.05.01
* @version V1.0
* @copyright TCT
* @par 修改日志
* <table>
* <tr><th>Date        <th>Version  <th>Author     <th>Description
* <tr><td>2021.05.01  <td>V1.0     <td>GT-BU      <td>创建初始版本
* </table>
*/
#include "PFM_CPUCheck.h"
#include "PFM_Log.h"


#ifdef WIN32


void PFM_CPUCheck(void)
{

}

#else

/* 寄存器x读写 */
static CM_UINT64 s_asm_x0(CM_UINT64 val);
static CM_UINT64 s_asm_x1(CM_UINT64 val);
static CM_UINT64 s_asm_x2(CM_UINT64 val);
static CM_UINT64 s_asm_x3(CM_UINT64 val);
static CM_UINT64 s_asm_x4(CM_UINT64 val);
static CM_UINT64 s_asm_x5(CM_UINT64 val);
static CM_UINT64 s_asm_x6(CM_UINT64 val);
static CM_UINT64 s_asm_x7(CM_UINT64 val);
static CM_UINT64 s_asm_x8(CM_UINT64 val);
static CM_UINT64 s_asm_x9(CM_UINT64 val);
static CM_UINT64 s_asm_x10(CM_UINT64 val);
static CM_UINT64 s_asm_x11(CM_UINT64 val);
static CM_UINT64 s_asm_x12(CM_UINT64 val);
static CM_UINT64 s_asm_x13(CM_UINT64 val);
static CM_UINT64 s_asm_x14(CM_UINT64 val);
static CM_UINT64 s_asm_x15(CM_UINT64 val);
static CM_UINT64 s_asm_x16(CM_UINT64 val);
static CM_UINT64 s_asm_x17(CM_UINT64 val);
static CM_UINT64 s_asm_x18(CM_UINT64 val);
static CM_UINT64 s_asm_x19(CM_UINT64 val);
static CM_UINT64 s_asm_x20(CM_UINT64 val);
static CM_UINT64 s_asm_x21(CM_UINT64 val);
static CM_UINT64 s_asm_x22(CM_UINT64 val);
static CM_UINT64 s_asm_x23(CM_UINT64 val);
static CM_UINT64 s_asm_x24(CM_UINT64 val);
static CM_UINT64 s_asm_x25(CM_UINT64 val);
static CM_UINT64 s_asm_x26(CM_UINT64 val);
static CM_UINT64 s_asm_x27(CM_UINT64 val);
static CM_UINT64 s_asm_x28(CM_UINT64 val);
static CM_UINT64 s_asm_x29(CM_UINT64 val);
static CM_UINT64 s_asm_x30(CM_UINT64 val);

/* 寄存器读写 */
#define REG_SET_AND_RETURN(val,reg) \
	{\
		register CM_UINT64 rn asm(reg) = (val); \
		CM_UINT64 rd = 0u;\
		__asm__ __volatile__\
		(\
			"mov %1,%0;"\
			:"=r"(rd)\
			:"r"(rn)\
		);\
		return rd;\
	}


/**
 * @brief 寄存器x0自检
 * @param val 写入寄存器的数值
 * @return 从寄存器读出的数值
 * @details
 * 将val写入寄存器再读出
 */
static CM_UINT64 s_asm_x0(CM_UINT64 val) 	REG_SET_AND_RETURN(val,"x0")

/**
 * @brief 寄存器x1自检
 * @param val 写入寄存器的数值
 * @return 从寄存器读出的数值
 * @details
 * 将val写入寄存器再读出
 */
static CM_UINT64 s_asm_x1(CM_UINT64 val) REG_SET_AND_RETURN(val,"x1")
/**
 * @brief 寄存器x2自检
 * @param val 写入寄存器的数值
 * @return 从寄存器读出的数值
 * @details
 * 将val写入寄存器再读出
 */
static CM_UINT64 s_asm_x2(CM_UINT64 val) REG_SET_AND_RETURN(val,"x2")
/**
 * @brief 寄存器x3自检
 * @param val 写入寄存器的数值
 * @return 从寄存器读出的数值
 * @details
 * 将val写入寄存器再读出
 */
static CM_UINT64 s_asm_x3(CM_UINT64 val) REG_SET_AND_RETURN(val,"x3")
/**
 * @brief 寄存器x4自检
 * @param val 写入寄存器的数值
 * @return 从寄存器读出的数值
 * @details
 * 将val写入寄存器再读出
 */
static CM_UINT64 s_asm_x4(CM_UINT64 val) REG_SET_AND_RETURN(val,"x4")
/**
 * @brief 寄存器x5自检
 * @param val 写入寄存器的数值
 * @return 从寄存器读出的数值
 * @details
 * 将val写入寄存器再读出
 */
static CM_UINT64 s_asm_x5(CM_UINT64 val) REG_SET_AND_RETURN(val,"x5")
/**
 * @brief 寄存器x6自检
 * @param val 写入寄存器的数值
 * @return 从寄存器读出的数值
 * @details
 * 将val写入寄存器再读出
 */
static CM_UINT64 s_asm_x6(CM_UINT64 val) REG_SET_AND_RETURN(val,"x6")
/**
 * @brief 寄存器x7自检
 * @param val 写入寄存器的数值
 * @return 从寄存器读出的数值
 * @details
 * 将val写入寄存器再读出
 */
static CM_UINT64 s_asm_x7(CM_UINT64 val) REG_SET_AND_RETURN(val,"x7")
/**
 * @brief 寄存器x8自检
 * @param val 写入寄存器的数值
 * @return 从寄存器读出的数值
 * @details
 * 将val写入寄存器再读出
 */
static CM_UINT64 s_asm_x8(CM_UINT64 val) REG_SET_AND_RETURN(val,"x8")
/**
 * @brief 寄存器x9自检
 * @param val 写入寄存器的数值
 * @return 从寄存器读出的数值
 * @details
 * 将val写入寄存器再读出
 */
static CM_UINT64 s_asm_x9(CM_UINT64 val) REG_SET_AND_RETURN(val,"x9")
/**
 * @brief 寄存器x10自检
 * @param val 写入寄存器的数值
 * @return 从寄存器读出的数值
 * @details
 * 将val写入寄存器再读出
 */
static CM_UINT64 s_asm_x10(CM_UINT64 val) REG_SET_AND_RETURN(val,"x10")
/**
 * @brief 寄存器x11自检
 * @param val 写入寄存器的数值
 * @return 从寄存器读出的数值
 * @details
 * 将val写入寄存器再读出
 */
static CM_UINT64 s_asm_x11(CM_UINT64 val) REG_SET_AND_RETURN(val,"x11")
/**
 * @brief 寄存器x12自检
 * @param val 写入寄存器的数值
 * @return 从寄存器读出的数值
 * @details
 * 将val写入寄存器再读出
 */
static CM_UINT64 s_asm_x12(CM_UINT64 val) REG_SET_AND_RETURN(val,"x12")
/**
 * @brief 寄存器x13自检
 * @param val 写入寄存器的数值
 * @return 从寄存器读出的数值
 * @details
 * 将val写入寄存器再读出
 */
static CM_UINT64 s_asm_x13(CM_UINT64 val) REG_SET_AND_RETURN(val,"x13")
/**
 * @brief 寄存器x14自检
 * @param val 写入寄存器的数值
 * @return 从寄存器读出的数值
 * @details
 * 将val写入寄存器再读出
 */
static CM_UINT64 s_asm_x14(CM_UINT64 val) REG_SET_AND_RETURN(val,"x14")
/**
 * @brief 寄存器x15自检
 * @param val 写入寄存器的数值
 * @return 从寄存器读出的数值
 * @details
 * 将val写入寄存器再读出
 */
static CM_UINT64 s_asm_x15(CM_UINT64 val) REG_SET_AND_RETURN(val,"x15")
/**
 * @brief 寄存器x16自检
 * @param val 写入寄存器的数值
 * @return 从寄存器读出的数值
 * @details
 * 将val写入寄存器再读出
 */
static CM_UINT64 s_asm_x16(CM_UINT64 val) REG_SET_AND_RETURN(val,"x16")
/**
 * @brief 寄存器x17自检
 * @param val 写入寄存器的数值
 * @return 从寄存器读出的数值
 * @details
 * 将val写入寄存器再读出
 */
static CM_UINT64 s_asm_x17(CM_UINT64 val) REG_SET_AND_RETURN(val,"x17")
/**
 * @brief 寄存器x18自检
 * @param val 写入寄存器的数值
 * @return 从寄存器读出的数值
 * @details
 * 将val写入寄存器再读出
 */
static CM_UINT64 s_asm_x18(CM_UINT64 val) REG_SET_AND_RETURN(val,"x18")
/**
 * @brief 寄存器x19自检
 * @param val 写入寄存器的数值
 * @return 从寄存器读出的数值
 * @details
 * 将val写入寄存器再读出
 */
static CM_UINT64 s_asm_x19(CM_UINT64 val) REG_SET_AND_RETURN(val,"x19")
/**
 * @brief 寄存器x20自检
 * @param val 写入寄存器的数值
 * @return 从寄存器读出的数值
 * @details
 * 将val写入寄存器再读出
 */
static CM_UINT64 s_asm_x20(CM_UINT64 val) REG_SET_AND_RETURN(val,"x20")
/**
 * @brief 寄存器x21自检
 * @param val 写入寄存器的数值
 * @return 从寄存器读出的数值
 * @details
 * 将val写入寄存器再读出
 */
static CM_UINT64 s_asm_x21(CM_UINT64 val) REG_SET_AND_RETURN(val,"x21")
/**
 * @brief 寄存器x22自检
 * @param val 写入寄存器的数值
 * @return 从寄存器读出的数值
 * @details
 * 将val写入寄存器再读出
 */
static CM_UINT64 s_asm_x22(CM_UINT64 val) REG_SET_AND_RETURN(val,"x22")
/**
 * @brief 寄存器x23自检
 * @param val 写入寄存器的数值
 * @return 从寄存器读出的数值
 * @details
 * 将val写入寄存器再读出
 */
static CM_UINT64 s_asm_x23(CM_UINT64 val) REG_SET_AND_RETURN(val,"x23")
/**
 * @brief 寄存器x24自检
 * @param val 写入寄存器的数值
 * @return 从寄存器读出的数值
 * @details
 * 将val写入寄存器再读出
 */
static CM_UINT64 s_asm_x24(CM_UINT64 val) REG_SET_AND_RETURN(val,"x24")
/**
 * @brief 寄存器x25自检
 * @param val 写入寄存器的数值
 * @return 从寄存器读出的数值
 * @details
 * 将val写入寄存器再读出
 */
static CM_UINT64 s_asm_x25(CM_UINT64 val) REG_SET_AND_RETURN(val,"x25")
/**
 * @brief 寄存器x26自检
 * @param val 写入寄存器的数值
 * @return 从寄存器读出的数值
 * @details
 * 将val写入寄存器再读出
 */
static CM_UINT64 s_asm_x26(CM_UINT64 val) REG_SET_AND_RETURN(val,"x26")
/**
 * @brief 寄存器x27自检
 * @param val 写入寄存器的数值
 * @return 从寄存器读出的数值
 * @details
 * 将val写入寄存器再读出
 */
static CM_UINT64 s_asm_x27(CM_UINT64 val) REG_SET_AND_RETURN(val,"x27")
/**
 * @brief 寄存器x28自检
 * @param val 写入寄存器的数值
 * @return 从寄存器读出的数值
 * @details
 * 将val写入寄存器再读出
 */
static CM_UINT64 s_asm_x28(CM_UINT64 val) REG_SET_AND_RETURN(val,"x28")
/**
 * @brief 寄存器x28自检
 * @param val 写入寄存器的数值
 * @return 从寄存器读出的数值
 * @details
 * 将val写入寄存器再读出
 */
static CM_UINT64 s_asm_x29(CM_UINT64 val) REG_SET_AND_RETURN(val,"x29")
/* x29是栈帧寄存器，不可用作通用寄存器，不自检 */

/**
 * @brief 寄存器x30自检
 * @param val 写入寄存器的数值
 * @return 从寄存器读出的数值
 * @details
 * 将val写入寄存器再读出
 */
static CM_UINT64 s_asm_x30(CM_UINT64 val) REG_SET_AND_RETURN(val,"x30")

/* 算术运算 */
/* rd = rn + op2 */
static CM_INT64 s_asm_add(CM_INT64 rn, CM_INT64 op2);
/* rd = rn - op */
static CM_INT64 s_asm_sub(CM_INT64 rn, CM_INT64 op2);
/* rd = ra + rn * rm */
static CM_INT64 s_asm_madd(CM_INT64 ra, CM_INT64 rn, CM_INT64 rm);
/* rd = - rn * rm */
static CM_INT64 s_asm_mneg(CM_INT64 rn, CM_INT64 rm);
/* rd = ra - rn * rm */
static CM_INT64 s_asm_msub(CM_INT64 ra, CM_INT64 rn, CM_INT64 rm);
/* rd = rn * rm */
static CM_INT64 s_asm_mul(CM_INT64 rn, CM_INT64 rm);
/* rd = - op2 */
static CM_INT64 s_asm_neg(CM_INT64 op2);
/* rd = rn / rm (有符号数) */
static CM_INT64 s_asm_sdiv(CM_INT64 rn, CM_INT64 rm);
/* rd = rn / rm (无符号数) */
static CM_UINT64 s_asm_udiv(CM_UINT64 rn, CM_UINT64 rm);

/* 逻辑运算 */
/* rd = rn & op2 */
static CM_UINT32 s_asm_and(CM_UINT32 rn, CM_UINT32 op2);
/* rd = rn & ~op2 */
static CM_UINT32 s_asm_bic(CM_UINT32 rn,CM_UINT32 op2);
/* rd = rn ^ ~op2 */
static CM_UINT32 s_asm_eon(CM_UINT32 rn,CM_UINT32 op2);
/* rd = rn ^ op2 */
static CM_UINT32 s_asm_eor(CM_UINT32 rn,CM_UINT32 op2);
/* rd = rn */
static CM_UINT32 s_asm_mov(CM_UINT32 rn);
/* rd = ~op2 */
static CM_UINT32 s_asm_mvn(CM_UINT32 op2);
/* rd = rn | ~op2 */
static CM_UINT32 s_asm_orn(CM_UINT32 rn, CM_UINT32 op2);
/* rd = rn | op2 */
static CM_UINT32 s_asm_orr(CM_UINT32 rn, CM_UINT32 op2);

/* 移位运算 */
/* rd = rn << rm */
static CM_UINT32 s_asm_lsl(CM_UINT32 rn, CM_UINT32 rm);
/* rd = rn >> rm */
static CM_UINT32 s_asm_lsr(CM_UINT32 rn, CM_UINT32 rm);
/* rd = rn >>> rm */
static CM_UINT64 s_asm_ror(CM_UINT64 rn, CM_UINT64 rm);

/* 指令自检 */
static void s_InstructionCheck(void);

/* 寄存器自检 */
static void s_RegCheck(void);

/**
 * @brief CPU自检
 */
void PFM_CPUCheck(void)
{
	/*- 指令自检 */
	s_InstructionCheck();

	/*- 寄存器自检 */
	s_RegCheck();
}

/**
 * @brief 寄存器自检
 */
static void s_RegCheck(void)
{
	/*- 变量初始化 */
    CM_UINT64 rslt[100] = {0u};


    rslt[0] = s_asm_x0((CM_UINT64)0x55u);
    CM_NM_ASSERT(rslt[0] == 0x55u, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[1] = s_asm_x0((CM_UINT64)0xaau);
    CM_NM_ASSERT(rslt[1] == 0xaau, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[2] = s_asm_x1((CM_UINT64)0x55u);
    CM_NM_ASSERT(rslt[2] == 0x55u, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[3] = s_asm_x1((CM_UINT64)0xaau);
    CM_NM_ASSERT(rslt[3] == 0xaau, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[4] = s_asm_x2((CM_UINT64)0x55u);
    CM_NM_ASSERT(rslt[4] == 0x55u, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[5] = s_asm_x2((CM_UINT64)0xaau);
    CM_NM_ASSERT(rslt[5] == 0xaau, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[6] = s_asm_x3((CM_UINT64)0x55u);
    CM_NM_ASSERT(rslt[6] == 0x55u, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[7] = s_asm_x3((CM_UINT64)0xaau);
    CM_NM_ASSERT(rslt[7] == 0xaau, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[8] = s_asm_x4((CM_UINT64)0x55u);
    CM_NM_ASSERT(rslt[8] == 0x55u, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[9] = s_asm_x4((CM_UINT64)0xaau);
    CM_NM_ASSERT(rslt[9] == 0xaau, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[10] = s_asm_x5((CM_UINT64)0x55u);
    CM_NM_ASSERT(rslt[10] == 0x55u, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[11] = s_asm_x5((CM_UINT64)0xaau);
    CM_NM_ASSERT(rslt[11] == 0xaau, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[12] = s_asm_x6((CM_UINT64)0x55u);
    CM_NM_ASSERT(rslt[12] == 0x55u, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[13] = s_asm_x6((CM_UINT64)0xaau);
    CM_NM_ASSERT(rslt[13] == 0xaau, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[14] = s_asm_x7((CM_UINT64)0x55u);
    CM_NM_ASSERT(rslt[14] == 0x55u, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[15] = s_asm_x7((CM_UINT64)0xaau);
    CM_NM_ASSERT(rslt[15] == 0xaau, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[16] = s_asm_x8((CM_UINT64)0x55u);
    CM_NM_ASSERT(rslt[16] == 0x55u, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[17] = s_asm_x8((CM_UINT64)0xaau);
    CM_NM_ASSERT(rslt[17] == 0xaau, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[18] = s_asm_x9((CM_UINT64)0x55u);
    CM_NM_ASSERT(rslt[18] == 0x55u, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[19] = s_asm_x9((CM_UINT64)0xaau);
    CM_NM_ASSERT(rslt[19] == 0xaau, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[20] = s_asm_x10((CM_UINT64)0x55u);
    CM_NM_ASSERT(rslt[20] == 0x55u, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[21] = s_asm_x10((CM_UINT64)0xaau);
    CM_NM_ASSERT(rslt[21] == 0xaau, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[22] = s_asm_x11((CM_UINT64)0x55u);
    CM_NM_ASSERT(rslt[22] == 0x55u, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[23] = s_asm_x11((CM_UINT64)0xaau);
    CM_NM_ASSERT(rslt[23] == 0xaau, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[24] = s_asm_x12((CM_UINT64)0x55u);
    CM_NM_ASSERT(rslt[24] == 0x55u, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[25] = s_asm_x12((CM_UINT64)0xaau);
    CM_NM_ASSERT(rslt[25] == 0xaau, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[26] = s_asm_x13((CM_UINT64)0x55u);
    CM_NM_ASSERT(rslt[26] == 0x55u, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[27] = s_asm_x13((CM_UINT64)0xaau);
    CM_NM_ASSERT(rslt[27] == 0xaau, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[28] = s_asm_x14((CM_UINT64)0x55u);
    CM_NM_ASSERT(rslt[28] == 0x55u, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[29] = s_asm_x14((CM_UINT64)0xaau);
    CM_NM_ASSERT(rslt[29] == 0xaau, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[30] = s_asm_x15((CM_UINT64)0x55u);
    CM_NM_ASSERT(rslt[30] == 0x55u, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[31] = s_asm_x15((CM_UINT64)0xaau);
    CM_NM_ASSERT(rslt[31] == 0xaau, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[32] = s_asm_x16((CM_UINT64)0x55u);
    CM_NM_ASSERT(rslt[32] == 0x55u, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[33] = s_asm_x16((CM_UINT64)0xaau);
    CM_NM_ASSERT(rslt[33] == 0xaau, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[34] = s_asm_x17((CM_UINT64)0x55u);
    CM_NM_ASSERT(rslt[34] == 0x55u, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[35] = s_asm_x17((CM_UINT64)0xaau);
    CM_NM_ASSERT(rslt[35] == 0xaau, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[36] = s_asm_x18((CM_UINT64)0x55u);
    CM_NM_ASSERT(rslt[36] == 0x55u, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[37] = s_asm_x18((CM_UINT64)0xaau);
    CM_NM_ASSERT(rslt[37] == 0xaau, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[38] = s_asm_x19((CM_UINT64)0x55u);
    CM_NM_ASSERT(rslt[38] == 0x55u, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[39] = s_asm_x19((CM_UINT64)0xaau);
    CM_NM_ASSERT(rslt[39] == 0xaau, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[40] = s_asm_x20((CM_UINT64)0x55u);
    CM_NM_ASSERT(rslt[40] == 0x55u, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[41] = s_asm_x20((CM_UINT64)0xaau);
    CM_NM_ASSERT(rslt[41] == 0xaau, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[42] = s_asm_x21((CM_UINT64)0x55u);
    CM_NM_ASSERT(rslt[42] == 0x55u, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[43] = s_asm_x21((CM_UINT64)0xaau);
    CM_NM_ASSERT(rslt[43] == 0xaau, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[44] = s_asm_x22((CM_UINT64)0x55u);
    CM_NM_ASSERT(rslt[44] == 0x55u, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[45] = s_asm_x22((CM_UINT64)0xaau);
    CM_NM_ASSERT(rslt[45] == 0xaau, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[46] = s_asm_x23((CM_UINT64)0x55u);
    CM_NM_ASSERT(rslt[46] == 0x55u, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[47] = s_asm_x23((CM_UINT64)0xaau);
    CM_NM_ASSERT(rslt[47] == 0xaau, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[48] = s_asm_x24((CM_UINT64)0x55u);
    CM_NM_ASSERT(rslt[48] == 0x55u, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[49] = s_asm_x24((CM_UINT64)0xaau);
    CM_NM_ASSERT(rslt[49] == 0xaau, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[50] = s_asm_x25((CM_UINT64)0x55u);
    CM_NM_ASSERT(rslt[50] == 0x55u, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[51] = s_asm_x25((CM_UINT64)0xaau);
    CM_NM_ASSERT(rslt[51] == 0xaau, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[52] = s_asm_x26((CM_UINT64)0x55u);
    CM_NM_ASSERT(rslt[52] == 0x55u, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[53] = s_asm_x26((CM_UINT64)0xaau);
    CM_NM_ASSERT(rslt[53] == 0xaau, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[54] = s_asm_x27((CM_UINT64)0x55u);
    CM_NM_ASSERT(rslt[54] == 0x55u, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[55] = s_asm_x27((CM_UINT64)0xaau);
    CM_NM_ASSERT(rslt[55] == 0xaau, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[56] = s_asm_x28((CM_UINT64)0x55u);
    CM_NM_ASSERT(rslt[56] == 0x55u, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[57] = s_asm_x28((CM_UINT64)0xaau);
    CM_NM_ASSERT(rslt[57] == 0xaau, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    /* x29是栈帧寄存器，不可用作通用寄存器，不自检 */

    rslt[58] = s_asm_x30((CM_UINT64)0x55u);
    CM_NM_ASSERT(rslt[58] == 0x55u, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);

    rslt[59] = s_asm_x30((CM_UINT64)0xaau);
    CM_NM_ASSERT(rslt[59] == 0xaau, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);
}

/**
 * @brief 指令自检
 */
static void s_InstructionCheck(void)
{
	/*- 变量初始化 */
	CM_INT64 rslt[100] = {0};
	/*- 算术运算自检 */
	rslt[0] = s_asm_add((CM_INT64)0x5500550000aa00aa, (CM_INT64)0x00aa00aa55005500);
    CM_NM_ASSERT(rslt[0] == 0x55aa55aa55aa55aa, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);

    rslt[1] = s_asm_sub((CM_INT64)0xaaccaaccaaccaaccU, (CM_INT64)0x33dd33dd33dd33dd);
    CM_NM_ASSERT(rslt[1] == 0x76ef76ef76ef76ef, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);

    rslt[2] = s_asm_madd((CM_INT64)0x33333333, (CM_INT64)0x5555, (CM_INT64)0xaaaa);
    CM_NM_ASSERT(rslt[2] == 0x6c164fa5, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);

    rslt[3] = s_asm_mneg((CM_INT64)0x5a5a,(CM_INT64)0x3c3c);
    CM_NM_ASSERT(rslt[3] == -0x15424518, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);

    rslt[4] = s_asm_msub((CM_INT64)0x7fffffff, (CM_INT64)0xa5a5, (CM_INT64)0x2b2b);
    CM_NM_ASSERT(rslt[4] == 0x64117648, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);

    rslt[5] = s_asm_mul((CM_INT64)0x4567,(CM_INT64)0xabcd);
    CM_NM_ASSERT(rslt[5] == 0x2e93607b, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);

    rslt[6] = s_asm_neg((CM_INT64)0x12345678);
    CM_NM_ASSERT(rslt[6] == -0x12345678, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);

    rslt[7] = s_asm_sdiv((CM_INT64)0x99999999U, (CM_INT64)0x33333333);
    CM_NM_ASSERT(rslt[7] == 3, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);

    rslt[8] = (CM_INT64)s_asm_udiv((CM_UINT64)0xeeeeeeeeU, (CM_UINT64)0x22222222);
    CM_NM_ASSERT(rslt[8] == 7, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);

    /*- 逻辑运算自检 */
    rslt[9] = (CM_INT64)s_asm_and((CM_UINT32)0x5c5c5c5c, (CM_UINT32)0xc5c5c5c5U);
    CM_NM_ASSERT(rslt[9] == 0x44444444, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_2);

    rslt[10] = (CM_INT64)s_asm_bic((CM_UINT32)0x5c5c5c5c, (CM_UINT32)0xc5c5c5c5U);
    CM_NM_ASSERT(rslt[10] == 0x18181818, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_2);

    rslt[11] = (CM_INT64)s_asm_eon((CM_UINT32)0x5c5c5c5c, (CM_UINT32)0xc5c5c5c5U);
    CM_NM_ASSERT(rslt[11] == 0x66666666, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_2);

    rslt[12] = (CM_INT64)s_asm_eor((CM_UINT32)0x5c5c5c5c, (CM_UINT32)0xc5c5c5c5U);
    CM_NM_ASSERT(rslt[12] == (CM_INT64)0x99999999U, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_2);

    rslt[13] =  (CM_INT64)s_asm_mov((CM_UINT32)0x13579bdf);
    CM_NM_ASSERT(rslt[13] == 0x13579bdf, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_2);

    rslt[14] =  (CM_INT64)s_asm_mvn((CM_UINT32)0x13579bdf);
    CM_NM_ASSERT(rslt[14] == (CM_INT64)0xeca86420U, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_2);

    rslt[15] = (CM_INT64)s_asm_orn((CM_UINT32)0x5c5c5c5c, (CM_UINT32)0xc5c5c5c5U);
    CM_NM_ASSERT(rslt[15] == (CM_INT64)0x7e7e7e7e, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_2);

    rslt[16] = (CM_INT64)s_asm_orr((CM_UINT32)0x5c5c5c5c, (CM_UINT32)0xc5c5c5c5U);
    CM_NM_ASSERT(rslt[16] == (CM_INT64)0xddddddddU, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_2);

    /*- 移位运算自检 */
    rslt[17] =(CM_INT64) s_asm_lsl((CM_UINT32)0x0055aa00,(CM_UINT32)4u);
    CM_NM_ASSERT(rslt[17] == (CM_INT64)0x055aa000, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_3);

    rslt[18] = (CM_INT64)s_asm_lsr((CM_UINT32)0x0055aa00,(CM_UINT32)4u);
    CM_NM_ASSERT(rslt[18] == (CM_INT64)0x00055aa0, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_3);

    rslt[19] = (CM_INT64)s_asm_ror((CM_UINT32)0x0055aa00,(CM_UINT32)4u);
    CM_NM_ASSERT(rslt[19] == (CM_INT64)0x00055aa0, CPU_CHECK_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_3);

}

/* 算术运算 */
/* rd = rn + op2 */
static CM_INT64 s_asm_add(CM_INT64 rn, CM_INT64 op2)
{
    CM_INT64 rd = 0;

    /*
     * add rn,op2,rd
     * rd = rn+op2
     */
    __asm__ __volatile__
   	(
   		"add %1,%2,%0;"
   		:"=r"(rd)
		:"r"(rn),"r"(op2)
   	);

    return rd;
}

/* rd = rn - op */
static CM_INT64 s_asm_sub(CM_INT64 rn, CM_INT64 op2)
{
	CM_INT64 rd = 0;

    __asm__ __volatile__
   	(
   		"sub %1,%2,%0;"
   		:"=r"(rd)
		:"r"(op2),"r"(rn)
   	);

    return rd;
}

/* rd = ra + rn * rm */
static CM_INT64 s_asm_madd(CM_INT64 ra, CM_INT64 rn, CM_INT64 rm)
{
	CM_INT64 rd = 0;

    __asm__ __volatile__
   	(
   		"madd %1,%2,%3,%0;"
   		:"=r"(rd)
		:"r"(ra),"r"(rn),"r"(rm)
   	);

    return rd;
}

/* rd = - rn * rm */
static CM_INT64 s_asm_mneg(CM_INT64 rn, CM_INT64 rm)
{
	CM_INT64 rd = 0;

    __asm__ __volatile__
   	(
   		"mneg %1,%2,%0;"
   		:"=r"(rd)
		:"r"(rn),"r"(rm)
   	);

    return rd;
}

/* rd = ra - rn * rm */
static CM_INT64 s_asm_msub(CM_INT64 ra, CM_INT64 rn, CM_INT64 rm)
{
	CM_INT64 rd = 0;

    __asm__ __volatile__
   	(
   		"msub %1,%2,%3,%0;"
   		:"=r"(rd)
		:"r"(ra),"r"(rn),"r"(rm)
   	);

    return rd;
}

/* rd = rn * rm */
static CM_INT64 s_asm_mul(CM_INT64 rn, CM_INT64 rm)
{
	CM_INT64 rd = 0;

    __asm__ __volatile__
   	(
   		"mul %1,%2,%0;"
   		:"=r"(rd)
		:"r"(rn),"r"(rm)
   	);

    return rd;
}

/* rd = - op2 */
static CM_INT64 s_asm_neg(CM_INT64 op2)
{
	CM_INT64 rd = 0;

    __asm__ __volatile__
   	(
   		"neg %1,%0;"
   		:"=r"(rd)
		:"r"(op2)
   	);

    return rd;
}

/* rd = rn / rm (有符号数) */
static CM_INT64 s_asm_sdiv(CM_INT64 rn, CM_INT64 rm)
{
	CM_INT64 rd = 0;

    __asm__ __volatile__
   	(
   		"sdiv %1,%2,%0;"
   		:"=r"(rd)
		:"r"(rm),"r"(rn)
   	);

    return rd;
}

/* rd = rn / rm (无符号数) */
static CM_UINT64 s_asm_udiv(CM_UINT64 rn, CM_UINT64 rm)
{
	CM_UINT64 rd = 0u;

    __asm__ __volatile__
   	(
   		"udiv %1,%2,%0;"
   		:"=r"(rd)
		:"r"(rm),"r"(rn)
   	);

    return rd;
}

/* 逻辑运算 */
/* rd = rn & op2 */
static CM_UINT32 s_asm_and(CM_UINT32 rn, CM_UINT32 op2)
{
    CM_UINT32 rd = 0u;

    __asm__ __volatile__
   	(
   		"and %1,%2,%0;"
   		:"=r"(rd)
		:"r"(rn),"r"(op2)
   	);

    return rd;
}

/* rd = rn & ~op2 */
static CM_UINT32 s_asm_bic(CM_UINT32 rn,CM_UINT32 op2)
{
	 CM_UINT32 rd = 0u;

	__asm__ __volatile__
	(
	 	"bic %1,%2,%0;"
		:"=r"(rd)
		:"r"(op2),"r"(rn)
	);

	return rd;
}

/* rd = rn ^ ~op2 */
static CM_UINT32 s_asm_eon(CM_UINT32 rn,CM_UINT32 op2)
{
	 CM_UINT32 rd = 0u;

	__asm__ __volatile__
	(
	 	"eon %1,%2,%0;"
		:"=r"(rd)
		:"r"(op2),"r"(rn)
	);

	return rd;
}

/* rd = rn ^ op2 */
static CM_UINT32 s_asm_eor(CM_UINT32 rn,CM_UINT32 op2)
{
	 CM_UINT32 rd = 0u;

	__asm__ __volatile__
	(
	 	"eor %1,%2,%0;"
		:"=r"(rd)
		:"r"(op2),"r"(rn)
	);

	return rd;
}

/* rd = rn */
static CM_UINT32 s_asm_mov(CM_UINT32 rn)
{
    CM_UINT32 rd = 0u;

    __asm__ __volatile__
   	(
   		"mov %1,%0;"
   		:"=r"(rd)
		:"r"(rn)
   	);

    return rd;
}

/* rd = ~op2 */
static CM_UINT32 s_asm_mvn(CM_UINT32 op2)
{
    CM_UINT32 rd = 0u;

    __asm__ __volatile__
   	(
   		"mvn %1,%0;"
   		:"=r"(rd)
		:"r"(op2)
   	);

    return rd;
}

/* rd = rn | ~op2 */
static CM_UINT32 s_asm_orn(CM_UINT32 rn, CM_UINT32 op2)
{
    CM_UINT32 rd = 0u;

    __asm__ __volatile__
   	(
   		"orn %1,%2,%0;"
   		:"=r"(rd)
		:"r"(op2),"r"(rn)
   	);

    return rd;
}

/* rd = rn | op2 */
static CM_UINT32 s_asm_orr(CM_UINT32 rn, CM_UINT32 op2)
{
    CM_UINT32 rd = 0u;

    __asm__ __volatile__
   	(
   		"orr %1,%2,%0;"
   		:"=r"(rd)
		:"r"(op2),"r"(rn)
   	);

    return rd;
}

/* 移位运算 */

/* rd = rn << rm */
static CM_UINT32 s_asm_lsl(CM_UINT32 rn, CM_UINT32 rm)
{
	CM_UINT32 rd = 0u;

	__asm__ __volatile__
	(
		"lsl %1,%2,%0;"
		:"=r"(rd)
		:"r"(rm),"r"(rn)
	);

	return rd;
}

/* rd = rn >> rm */
static CM_UINT32 s_asm_lsr(CM_UINT32 rn, CM_UINT32 rm)
{
	CM_UINT32 rd = 0u;

	__asm__ __volatile__
	(
		"lsr %1,%2,%0;"
		:"=r"(rd)
		:"r"(rm),"r"(rn)
	);

	return rd;
}

/* rd = rn >>> rm */
static CM_UINT64 s_asm_ror(CM_UINT64 rn, CM_UINT64 rm)
{
	CM_UINT64 rd = 0u;

	__asm__ __volatile__
	(
		"ror %1,%2,%0;"
		:"=r"(rd)
		:"r"(rm),"r"(rn)
	);

	return rd;
}



#endif



