C/C++将int转换为short和inline asm(特定于ARM)

Pav*_*l P 9 c c++ arm inline-assembly

这不是一个微不足道的问题.
注意:我不需要意见或建议使用纯asm.我实际上需要完成我正在谈论的内容:在将结果分配给short int时,在没有此符号的情况下获取内联asm /零扩展optcode.

我正在处理一个滥用16位短路的库,我正在优化它.我需要使用内联asm添加一些优化函数.问题是在很多地方将函数的结果赋给short int.也就是说,编译器生成第u个或第s个arm操作码.

我的目标是避免这个问题,并确保不会生成这个无用的操作码.首先,我需要定义我的优化函数来返回short int.这样,如果将其分配给int或short int,则不会有额外的操作码来转换结果.

问题是我不知道如何跳过编译器在我自己的函数中生成的int-> short转换.
愚蠢的演员:*(short*)(void*)&value不起作用.编译器要么开始更多地解决堆栈制作问题,要么仍然使用相同的sxth来对结果进行签名扩展.

我为多个编译器编译,我能够为arm的armcc编译器解决它,但我不能用GCC完成它(我用4.4.3或4.6.3编译).使用armcc我在内联asm语句中使用短类型.在gcc中,即使我使用短编译器仍因某种原因认为需要符号扩展.

这是一个简单的代码片段,我无法与GCC合作,有关如何使其工作的任何建议?对于这个简单的例子,我将使用clz指令:

示例文件test.c文件:

static __inline short CLZ(int n)
{
    short ret;
#ifdef __GNUC__
    __asm__("clz %0, %1" : "=r"(ret) : "r"(n));
#else
    __asm { clz ret, n; }
#endif
    return ret;
}

//test function
short test_clz(int n)
{
    return CLZ(n);
}
Run Code Online (Sandbox Code Playgroud)



这是我用armcc -c -O3得到的预期结果:

test_clz:
    CLZ      r0,r0
    BX       lr
Run Code Online (Sandbox Code Playgroud)

这是GCC -c -O3给我的不可接受的结果:

test_clz:
    clz r0, r0
    sxth    r0, r0
    bx  lr
Run Code Online (Sandbox Code Playgroud)

另请注意,如果使用内部变量int ret;而不是short ret;armcc 重写CLZ ,则会生成与GCC相同的结果.

用gcc或armcc获取asm输出的快速行:
gcc -O3 -c test.c -o test.o && objdump -d test.o > test.s
armcc -O3 --arm --asm -c test.c

old*_*mer 6

编译器改变了.特别是gcc,你今天想出的技巧明天或昨天都不会工作.并且不会在编译器(armcc,clang等)之间保持一致.

1)取下短裤并更换一下,然后将其翻过来,这是一个选择,这是最不痛苦的解决方案.

2)如果你想要特定的asm,写下特定的asm,不要乱七八糟.也是一种选择.

虽然编写一致编译的代码非常有可能比其他代码更好,但是你总是无法获得所需的代码序列,而不是始终如一.从长远来看,你正在伤害自己,即使是写自己的asm解决方案.你实际上正在寻找的解决方案是通过代码并用ints替换short,这将生成代码,这些代码将比那里的short更好地编译.它将花费更少的时间,并且在编译器改变时不必每隔几个月重写一次.

要一劳永逸地完全控制它将编译为asm或反汇编并删除有问题的指令,将函数保留在asm中.快速,轻松地完成任务,会让你想要删除这个开销,只留下一些不太可维护的东西.实际上,因为你有armcc做你想要的东西在armcc中编译为asm然后修补它为gnu汇编程序习惯的愚蠢,并使用它作为一个解决方案(可能写asm组装arm工具和gnu,至少在手臂广告时代,在我失去对工具的访问之前没有多少时间).

有很多方法可以得到你提供的确切结果,以便给出你所追求的确切结果,但是我怀疑你是怎么回事,你会写出两行asm并完成了.我的猜测是你试图在一个函数中内联一些东西(大于CLZ),同时仍然称它为一个简短的,当调用它时int会给你你想要的东西,而没有内联asm.(我仍然无法看到内联asm如何在短时间内实现和测试所需的时间比更改变量声明更少,更不用说键入,读取和测试的代码量相同).

所以这是你的现实:

1)与短裤及其副作用共存

2)将它们改为整数

花几天,几周或几个月做某事并不是什么大问题.大多数情况下,需要数天,数周,数月才能避免做某事.无论如何你必须这样做,所以现在你有2xdays,2xweeks,2xmonths ......你必须或者应该测试它,不管是什么解决方案,你正在改变代码,所以这不是一个变化因素决策.使用内联asm攻击编译器是最高的风险,如果测试确实在时间等式中有所不同,那么应该导致最多的测试.需要一些gcc版本,再加上每6个月重新测试一次.

通常,asm解决方案是在abi改变时,重新测试之间可能是10年,并且当我们将64位改为128位时,修复C将是20年.但32位到64位的转换仍在继续,我们还没有启动ARM 32到64位的转换/混合(不会放弃所有64位的32位臂处理器,两者都将保留).后端将会有一段时间的混乱,我现在不会和他们一起玩游戏.制作干净,便携,C,你不依赖于代码中int的大小(假设/要求最小32但确保它是64位清洁)是你最便宜的解决方案.