标签: arm

如何影响Android/ARM目标的Delphi XEx代码生成?

更新2017-05-17.我不再为出现此问题的公司工作,也无法访问Delphi XEx.当我在那里时,问题通过迁移到混合FPC + GCC(Pascal + C)来解决,NEON内在函数用于某些例程,它们有所不同.(强烈建议使用FPC + GCC,因为它可以使用标准工具,特别是Valgrind.)如果有人能够通过可靠的示例演示他们如何实际能够从Delphi XEx生成优化的ARM代码,我很高兴接受答案.


Embarcadero的Delphi编译器使用LLVM后端为Android设备生成本机ARM代码.我有大量的Pascal代码需要编译到Android应用程序中,我想知道如何使Delphi生成更高效的代码.现在,我甚至都没有谈论自动SIMD优化等高级功能,只是关于生成合理的代码.当然必须有一种方法将参数传递给LLVM端,或以某种方式影响结果?通常,任何编译器都会有很多选项来影响代码编译和优化,但是Delphi的ARM目标似乎只是"优化开/关"就是这样.

LLVM应该能够产生合理紧密且合理的代码,但似乎Delphi以一种奇怪的方式使用它的设施.Delphi希望非常频繁地使用堆栈,它通常只利用处理器的寄存器r0-r3作为临时变量.也许是最疯狂的,似乎是将正常的32位整数加载为四个1字节的加载操作.如何让Delphi产生更好的ARM代码,而且没有逐字节麻烦的Android?

起初我认为逐字节加载是用于从big-endian交换字节顺序,但事实并非如此,它实际上只是加载一个带有4个单字节加载的32位数字.*可能是加载完整的32位而不进行未对齐的字大小的内存加载.(是否应该避免这是另一回事,这将暗示整个事情是编译器错误)*

让我们来看看这个简单的函数:

function ReadInteger(APInteger : PInteger) : Integer;
begin
  Result := APInteger^;
end;
Run Code Online (Sandbox Code Playgroud)

即使启用了优化,带有更新包1的Delphi XE7以及XE6也会为该功能生成以下ARM汇编代码:

Disassembly of section .text._ZN16Uarmcodetestform11ReadIntegerEPi:

00000000 <_ZN16Uarmcodetestform11ReadIntegerEPi>:
   0:   b580        push    {r7, lr}
   2:   466f        mov r7, sp
   4:   b083        sub sp, #12
   6:   9002        str r0, [sp, #8]
   8:   78c1        ldrb    r1, [r0, #3]
   a:   7882        ldrb    r2, [r0, #2]
   c:   ea42 2101   orr.w   r1, r2, r1, lsl #8
  10:   7842        ldrb    r2, [r0, #1] …
Run Code Online (Sandbox Code Playgroud)

delphi android arm llvm android-ndk

263
推荐指数
1
解决办法
1万
查看次数

ARM体系结构与x86有何不同?

是否特别设计的x86架构可以与键盘配合使用,而ARM希望是移动设备?两者之间的主要区别是什么?

x86 arm

154
推荐指数
5
解决办法
15万
查看次数

为什么在armeabi代码上使用armeabi-v7a代码?

在我当前的项目中,我使用了多个.so文件.这些位于armeabi和armeabi-v7a文件夹中.不幸的是,其中一个.so文件是6MB,我需要减小文件大小.我想使用armeabi文件并删除armeabi-v7a文件夹,而不是有一个胖的APK文件.

根据NDK文档,armeabi-v7a代码是扩展的armeabi代码,可以包含额外的CPU指令.这一切都超出了我的专业知识,但我怀疑为什么人们想要同时拥有armeabi-v7a和armeabi代码.两者都有充分的理由,对吗?

在我的测试设备上,这一切看起来都很好.这些都有ARM v7 CPU.假设现在一切正常可以安全吗?

android arm android-ndk armv7

139
推荐指数
3
解决办法
10万
查看次数

快速查找C数组中是否存在值?

我有一个具有时间要求严格的ISR的嵌入式应用程序需要迭代256个大小的数组(最好是1024,但256是最小的),并检查一个值是否与数组内容匹配.如果bool是这样,A 将设置为true.

微控制器是NXP LPC4357,ARM Cortex M4内核,编译器是GCC.我已经结合优化级别2(3更慢)并将功能放在RAM而不是闪存中.我还使用指针算法和for循环,它进行向下计数而不是向上(检查是否i!=0比检查是否更快i<256).总而言之,我的最终持续时间为12.5μs,必须大幅度降低才能实现.这是我现在使用的(伪)代码:

uint32_t i;
uint32_t *array_ptr = &theArray[0];
uint32_t compareVal = 0x1234ABCD;
bool validFlag = false;

for (i=256; i!=0; i--)
{
    if (compareVal == *array_ptr++)
    {
         validFlag = true;
         break;
     }
}
Run Code Online (Sandbox Code Playgroud)

什么是绝对最快的方法呢?允许使用内联汇编.其他'不太优雅'的技巧也是允许的.

c embedded optimization assembly arm

124
推荐指数
9
解决办法
1万
查看次数

如何在我的Linux主机上安装Raspberry Pi交叉编译器?

我正在尝试为我的Ubuntu机器上的Raspberry Pi进行交叉编译.

在我最初的尝试中,我使用的是arm-linux-gnueabi编译器,它可以在Ubuntu repo中找到.我得到了这个工作.我能够构建所有依赖项并在我的cmake项目中使用交叉编译器.

但是,我相信我应该使用hf版本,所以我切换到arm-linux-gnueabihf.然后我意识到这不适用于Raspberry Pi,因为它是armv6.

经过一些谷歌搜索后,我找到了GitHub预先构建的工具链.

我下载了工具链,但我真的不明白如何"安装"它.我将文件解压缩到我的主目录.目录结构如下所示:

/gcc-linearo-arm-linux-gnueabihf-raspbian
    /arm-linux-gnueabihf
        /bin
            (contains g++, gcc, etc)
        /lib
            (contains libstdc++ library)
    /bin
        (contains arm-linux-gnueabihf-g++, arm-linux-gnueabihf-...)
    /lib
        (gcc lib stuff)
Run Code Online (Sandbox Code Playgroud)

如果我将目录更改为INNER bin文件夹,我可以从终端编译测试程序,没有任何问题.

~/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/
arm-linux-gnueabihf/bin$ g++ test.cpp -o test
Run Code Online (Sandbox Code Playgroud)

然后我尝试在OUTER bin文件夹中编译测试程序,该文件夹包含工具的前缀版本.

 ~/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin$ 
 arm-linux-gnueabihf-g++ test.cpp -o test
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试使用编译器时(从内部bin目录之外),它无法找到工具链附带的libstdc ++共享库:

arm-linux-gnueabihf-gcc: error while loading shared libraries: 
libstdc++.so.6: cannot open shared object file: No such file or directory.
Run Code Online (Sandbox Code Playgroud)

此外,我希望能够使用编译器而无需导航到bin目录.所以我尝试添加OUTER bin目录(因为我想要前缀版本)和两个lib目录到我的PATH:

export PATH=$PATH:~/tools/.../bin
export PATH=$PATH:~/tools/.../lib
export PATH=$PATH:~/tools/.../.../lib
Run Code Online (Sandbox Code Playgroud)

但是,这会导致相同的错误.我应该如何"安装"工具链,以便我可以随处使用工具链,就像我使用Ubuntu repo中的交叉编译器一样?

c++ linux arm cross-compiling raspberry-pi

107
推荐指数
4
解决办法
12万
查看次数

硬浮点数和软浮点数之间有什么区别?

当我用我的交叉工具链编译C代码时,链接器打印警告页面,说我的可执行文件使用硬浮动,但我的libc使用软浮动.有什么不同?

c linux floating-point arm libc

95
推荐指数
5
解决办法
6万
查看次数

Mac M1 上的 Docker 给出:“请求的映像的平台 (linux/amd64) 与检测到的主机平台不匹配”

我想在 MacBook M1 上运行 docker 容器Ganache,但出现以下错误:

The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
Run Code Online (Sandbox Code Playgroud)

在此行之后,不会再发生任何其他事情,并且整个过程被卡住,尽管根据活动监视器,qemu-system-aarch64 正在 100% CPU 上运行,直到我按CTRL+ C

我的 docker 文件来自此存储库。遇到相同的问题后,我尝试找出根本原因,并提出了会遇到相同错误的最小设置。

这是以下的输出docker-compose up --build

Building ganache
Sending build context to Docker daemon  196.6kB
Step 1/17 : FROM trufflesuite/ganache-cli:v6.9.1
 ---> 40b011a5f8e5
Step 2/17 : LABEL Unlock <ops@unlock-protocol.com>
 ---> Using cache
 ---> aad8a72dac4e
Step 3/17 : RUN apk add --no-cache …
Run Code Online (Sandbox Code Playgroud)

arm docker docker-compose apple-m1

94
推荐指数
4
解决办法
14万
查看次数

ELF文件和bin文件有什么区别?

编译器生成的最终图像包含bin文件和扩展加载器格式ELf文件,两者之间有什么区别,尤其是ELF文件的实用程序.

arm elf

89
推荐指数
3
解决办法
8万
查看次数

arm64和armhf有什么区别?

覆盆子裨类型3具有64位CPU,但它的体系结构是不arm64而是armhf.arm64和之间有什么区别armhf

linux debian arm arm64

80
推荐指数
3
解决办法
9万
查看次数

什么可能导致P/Invoke参数在传递时出现故障?

这是一个特别在ARM上发生的问题,而不是在x86或x64上.我有这个用户报告的问题,并且能够通过Windows IoT在Raspberry Pi 2上使用UWP重现它.我在使用不匹配的调用约定之前已经看到过这种问题,但是我在P/Invoke声明中指定了Cdecl,我尝试在原生端显式添加__cdecl并获得相同的结果.这是一些信息:

P/Invoke声明(参考):

[DllImport(Constants.DllName, CallingConvention = CallingConvention.Cdecl)]
public static extern FLSliceResult FLEncoder_Finish(FLEncoder* encoder, FLError* outError);
Run Code Online (Sandbox Code Playgroud)

C#结构(参考):

internal unsafe partial struct FLSliceResult
{
    public void* buf;
    private UIntPtr _size;

    public ulong size
    {
        get {
            return _size.ToUInt64();
        }
        set {
            _size = (UIntPtr)value;
        }
    }
}

internal enum FLError
{
    NoError = 0,
    MemoryError,
    OutOfRange,
    InvalidData,
    EncodeError,
    JSONError,
    UnknownValue,
    InternalError,
    NotFound,
    SharedKeysStateError,
}

internal unsafe struct FLEncoder
{
}
Run Code Online (Sandbox Code Playgroud)

C头中的函数(参考)

FLSliceResult FLEncoder_Finish(FLEncoder, FLError*); …
Run Code Online (Sandbox Code Playgroud)

c# windows pinvoke arm uwp

80
推荐指数
1
解决办法
2095
查看次数