【发布时间】:2016-03-19 10:53:38
【问题描述】:
我正在尝试在 ARM Cortex-a8 上的 ARM 程序集中实现一个将 32 位操作数与 256 位操作数相乘的函数。问题是我的寄存器用完了,我不知道如何减少这里使用的寄存器的数量。这是我的功能:
typedef struct UN_256fe{
uint32_t uint32[8];
}UN_256fe;
typedef struct UN_288bite{
uint32_t uint32[9];
}UN_288bite;
void multiply32x256(uint32_t A, UN_256fe* B, UN_288bite* res){
asm (
"umull r3, r4, %9, %10;\n\t"
"mov %0, r3; \n\t"/*res->uint32[0] = r3*/
"umull r3, r5, %9, %11;\n\t"
"adds r6, r3, r4; \n\t"/*res->uint32[1] = r3 + r4*/
"mov %1, r6; \n\t"
"umull r3, r4, %9, %12;\n\t"
"adcs r6, r5, r3; \n\t"
"mov %2, r6; \n\t"/*res->uint32[2] = r6*/
"umull r3, r5, %9, %13;\n\t"
"adcs r6, r3, r4; \n\t"
"mov %3, r6; \n\t"/*res->uint32[3] = r6*/
"umull r3, r4, %9, %14;\n\t"
"adcs r6, r3, r5; \n\t"
"mov %4, r6; \n\t"/*res->uint32[4] = r6*/
"umull r3, r5, %9, %15;\n\t"
"adcs r6, r3, r4; \n\t"
"mov %5, r6; \n\t"/*res->uint32[5] = r6*/
"umull r3, r4, %9, %16;\n\t"
"adcs r6, r3, r5; \n\t"
"mov %6, r6; \n\t"/*res->uint32[6] = r6*/
"umull r3, r5, %9, %17;\n\t"
"adcs r6, r3, r4; \n\t"
"mov %7, r6; \n\t"/*res->uint32[7] = r6*/
"adc r6, r5, #0 ; \n\t"
"mov %8, r6; \n\t"/*res->uint32[8] = r6*/
: "=r"(res->uint32[8]), "=r"(res->uint32[7]), "=r"(res->uint32[6]), "=r"(res->uint32[5]), "=r"(res->uint32[4]),
"=r"(res->uint32[3]), "=r"(res->uint32[2]), "=r"(res->uint32[1]), "=r"(res->uint32[0])
: "r"(A), "r"(B->uint32[7]), "r"(B->uint32[6]), "r"(B->uint32[5]),
"r"(B->uint32[4]), "r"(B->uint32[3]), "r"(B->uint32[2]), "r"(B->uint32[1]), "r"(B->uint32[0]), "r"(temp)
: "r3", "r4", "r5", "r6", "cc", "memory");
}
EDIT-1:我根据第一条评论更新了我的clobber列表,但我仍然收到同样的错误
【问题讨论】:
-
你的 asm 语句有更大的问题。您需要将您在 asm 语句中明确指定的所有寄存器添加到 clobber 列表(还需要包括“cc”)。这些 clobber 加上保存输入和输出操作数所需的所有寄存器(也需要标记为 early clobber)意味着您使用的寄存器比 ARM 更多。你上次的尝试只是让问题变得更糟。
-
@RossRidge 有什么方法可以在我的输入之前使用另一个符号而不是
"r"并获得正确的结果?我的意思是"g"或"m"? -
您确实需要一个循环[迭代计数为 8],而不是您正在做的事情。重新考虑:如果你的输入向量中有 20,000 个元素,你会怎么做?您需要 reg 表示标量
A值,reg 表示Bptr,reg 表示resptr,reg 表示迭代计数,以及您需要执行 umull 等的任何其他 reg。 al [可能另外 4-6] 在每次循环迭代中,所以总数约为 10。事实上,向量大小为 2-3 的 regs 用完了,更不用说 8 了。为了让你的向量算法直截了当,如何编写一个 C fnc 来执行此操作[也可以作为你 asm fnc 的参考]。
标签: c gcc arm inline-assembly