ARM Cortex M33:使用MAC指令UMLAL时出现微小错误

问题描述

我正在实现一个加密库,该库针对ARM Cortex M-0架构进行了优化的组装,其中包括使用乘累加宏的多个单元,该宏使用32x32-> 32位乘法。

我正在使用支持32x32-> 64乘法的M-33。因此,我首先通过用正确的64位变体(UMULL)替换了32位乘法(和某些加法运算)来优化算法。但是,Cortex M33还支持用于64位MAC(UMLAL)的单个指令。当我使用此指令时,结果是正确的,除了2位:0xe5c528f b ,0xc5abc3f c (第11和第12个值)。

使用UMLAL错误的结果:

   umlal_result = 
  {0xb45deb28,0xeb23a781,0xec09b357,0xe561f5f5,0x1e3fa5d2,0x828ad2db,0x60c67a8a,0xd2850733,0xad1de690,0x6e1ceba1,0xe5c528fb,0xc5abc3fc,0x2f648d3b,0xe13039aa,0x58cc1ff4,0x1d7521f1}

右边的那个(UMULL):

  umull_result = 
  {0xb45deb28,0xe5c528fc,0xc5abc3fb,0x1d7521f1}

我尝试调试该问题,但找不到原因。所以我的问题是,可能是什么问题?在我看来,以上两个示例是等效的,影响相同的标志。显然,情况并非如此。我的猜测是所有修改都需要定位在mulacc宏中,因为它仅需要2 * 32位输入并作为MAC结果输出64位,并且当然会更新所需的标志。我正在使用的所有数字均未签名。

任何建议将不胜感激。

EDIT2:包含所有必需的.S文件(用于umlal,umull版本)和用于调用它们的主要功能的测试代码

karatsuba_umull.S文件

.macro mulacc
 @fixed: 64-bit multiply for Cortex M-33
    umull r6,r0,r1,r2

    mov r7,#0
    add r5,r5,r6
    adc r4,r4,r0
    adc r3,r3,r7
.endm

.macro loadAndAdd reg,idx
.if \reg == sp || \reg == r0
   ldr r6,[\reg,#\idx*4]
.else
   mov r0,\reg
   ldr r6,[r0,#\idx*4]
.endif
   add r5,r6
   adc r4,r7
.endm

.macro loadAndSub reg,#\idx*4]
.endif
   sub r5,r6
   sbc r4,r7
.endm

.macro loadAndAddIfCarry carryReg,opReg,idx
   ldr r0,[\opReg,#\idx*4]
   mov r1,\carryReg
   and r0,r1
   add r5,r0 @ tässä pitäisi olla 1? umuls mid kohta 7
   adc r4,r7
.endm

.macro loadMultiply regA,regB,idxA,idxB
.if \regA == sp
   ldr r1,[sp,#\idxA*4]
.else
   mov r1,\regA
   ldr r1,[r1,#\idxA*4]
.endif
.if \regB == sp
   ldr r2,#\idxB*4]
.else
   mov r2,\regB
   ldr r2,[r2,#\idxB*4]
.endif
   mulacc
.endm

.macro storeAndShiftAcc regDst,idx
.if \regDst == sp || \regDst == r0
   str r5,[\regDst,#\idx*4]
.else
   mov r6,\regDst
   str r5,[r6,#\idx*4]
.endif
   mov r5,r4
   mov r4,r3
   asr r3,#32
.endm

.macro storeRemAcc regDst,idx1,idx2
.if \regDst == sp
   str r5,#\idx1*4]
   str r4,#\idx2*4]
.else
   mov r6,#\idx2*4]
.endif
.endm

.macro resetAccumulator
   ldr r3,=0
   mov r4,r3
   mov r5,r3
.endm

.macro multiplyLow
   loadMultiply r8,r9,0
   storeAndShiftAcc r10,0

   loadMultiply r9,r8,1,0
   loadMultiply r9,1
   storeAndShiftAcc r10,1

   loadMultiply r8,2,0
   loadMultiply r8,1
   loadMultiply r8,2
   storeAndShiftAcc r10,2

   loadMultiply r9,3,2
   loadMultiply r8,3

   loadMultiply r9,3
   loadMultiply r9,2
   loadMultiply r9,1
   storeAndShiftAcc sp,8

   loadMultiply r8,3
   loadMultiply r8,2
   storeAndShiftAcc sp,9

   loadMultiply r9,3
   storeRemAcc sp,10,11
.endm

.macro multiplyHigh
   loadMultiply r8,4,4
   storeAndShiftAcc r10,8

   loadMultiply r9,5,4
   loadMultiply r9,5
   storeAndShiftAcc r10,9

   loadMultiply r8,6,4
   loadMultiply r8,5
   loadMultiply r8,6
   storeAndShiftAcc r10,10

   loadMultiply r9,7,6
   loadMultiply r8,11

   loadMultiply r9,7
   loadMultiply r9,6
   loadMultiply r9,12

   loadMultiply r8,7
   loadMultiply r8,13

   loadMultiply r9,7
   storeRemAcc r10,14,15
.endm

.macro multiplyMiddle
   mov r7,#0
   mov r0,r10
   loadAndAdd sp,8
   loadAndSub r0,0
   asr r3,#32
   loadMultiply sp,sp,4

   mov r0,9
   loadAndSub r0,1
   asr r3,4
   loadMultiply sp,5

   mov r0,10
   loadAndSub r0,2
   asr r3,5
   loadMultiply sp,6

   mov r0,11
   loadAndSub r0,3
   asr r3,6
   loadMultiply sp,7
   storeAndShiftAcc r10,7

   loadAndAddIfCarry  r11,4
   loadAndAddIfCarry r12,0
   mov r0,r10
   loadAndAdd r0,12
   loadAndSub sp,8
   asr r3,8

   loadAndAddIfCarry  r11,5
   loadAndAddIfCarry r12,1
   mov r0,13
   loadAndSub sp,9
   asr r3,9

   loadAndAddIfCarry  r11,6
   loadAndAddIfCarry r12,2 @ r4 = 1 with umuls
   mov r0,14
   loadAndSub sp,10
   asr r3,10

   loadAndAddIfCarry  r11,7
   loadAndAddIfCarry r12,3
   mov r0,15
   loadAndSub sp,11
   asr r3,#32
   storeAndShiftAcc r0,11

   addCarries
   loadRegAndAdd r1,12
   str r5,#12*4]
   mov r5,r4
   loadRegAndAddNoAcc r1,13
   str r5,#13*4]
   loadRegAndAddCarry r1,14
   str r5,#14*4]
   loadRegAndAddCarry r1,15
   str r5,#15*4]
.endm

.macro loadRegAndAddCarry baseReg,idx
   ldr r5,[\baseReg,#\idx*4]
   adc r5,r7
.endm

.macro loadRegAndAddNoAcc baseReg,idx
   ldr r6,#\idx*4]
   add r5,r6
.endm

.macro loadRegAndAdd baseReg,r7
.endm

.macro addCarries
   mov r6,r11
   mov r0,r12
   and r6,r6,r0
   neg r6,r6
   add r5,r7
   mov r1,r10
.endm

.macro sumA
   @ to use: r3,r7
   ldm r1,{r0,r2,r7}

   add r4,r0
   adc r5,r1
   adc r6,r2
   adc r7,r7,r3

   sbc r3,r3
   mvn r3,r3
   mov r11,r3

   mov r1,sp
   stm r1,{r4,r7}
.endm

.macro sumB
   @ to use: r3,r9
   ldm r1,r3
   mov r12,r3

   add r1,#16
   stm r1,r7}
.endm

.global bi_multiply_cm0_umull
.type bi_multiply_cm0_umull,function
.text 1
.thumb

@ res:          r0
@ operand a:    r1
@ operand b:    r2
bi_multiply_cm0_umull:
   push {r4,lr}
   mov r4,r8
   mov r5,r9
   mov r6,r10
   mov r7,r11
   push {r4,r7}
   mov r4,r12
   push {r4}

   sub sp,#64

   mov r8,r1
   mov r9,r2
   mov r10,r0

   sumA
   sumB

   resetAccumulator

   multiplyLow

   resetAccumulator

   multiplyHigh

   resetAccumulator

   multiplyMiddle

   add sp,#64

   pop {r4}
   mov r12,r4
   pop {r4,r7}
   mov r8,r4
   mov r9,r5
   mov r10,r6
   mov r11,r7
   pop {r4,pc}

karatsuba_umlal.S文件

.macro mulacc
@ fixed: 64-bit multiply for Cortex M-33
    umlal r5,#0
    adc r3,r7

.endm

.macro loadAndAdd reg,r7}
.endm

.global bi_multiply_cm0_umlal
.type bi_multiply_cm0_umlal,function
.text 1
.thumb

@ res:          r0
@ operand a:    r1
@ operand b:    r2
bi_multiply_cm0_umlal:
   push {r4,pc}

用于调用的最小测试函数(mainfunc.c)

#include <stdio.h>
#include <inttypes.h>

#define FP_WORDS 8

typedef uint32_t word_t;
typedef word_t bigint_t[FP_WORDS];

static const bigint_t var_a = { 0x52766F6A,0xACBDC62E,0x32D23576,0x600D522F,0x19049F3B,0xC4B0D05E,0xC0FE0998,0xB70E64D5 };

static const bigint_t var_b = { 0x8FE44968,0xDEF5AF3C,0x3D568ABD,0x09372473,0x9AF4FFC7,0x3A822C26,0x522D6E14,0x2DAAB214 };

void bi_multiply_cm0_umull(word_t res[2*FP_WORDS],bigint_t a,bigint_t b);
void bi_multiply_cm0_umlal(word_t res[2*FP_WORDS],bigint_t b);

int main()
{
    word_t res_umull[2*FP_WORDS],res_umlal[2*FP_WORDS];
    bi_multiply_cm0_umull(res_umull,var_a,var_b);
    bi_multiply_cm0_umlal(res_umlal,var_b);

    return 0;
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...