[英]Can Libffi be built for Cortex-M3?
我正在嘗試使用GCC為Cortex-M3處理器構建外部函數接口庫。 根據http://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html :
-mthumb
生成Thumb指令集的代碼。 默認設置是使用32位ARM指令集。 此選項基於-mcpu = name和-march = name選項自動啟用16位Thumb-1或16/32位混合Thumb-2指令。 此選項不會傳遞給匯編程序。 如果要強制將匯編程序文件解釋為Thumb代碼,請將“.thumb”指令添加到源代碼,或者通過在-Wa前面添加-mthumb選項直接將其傳遞給匯編程序。
我已經嘗試將各種各樣的參數傳遞給匯編程序,似乎無法弄明白。 典型輸出如下:
構建文件:../ source / fif / sysv.S
調用:GCC匯編程序
arm-bare_newlib_cortex_m3_nommu-eabi-gcc -Wa,-mthumb-interwork -I“/ home / neil / m3projects / robovero / firmware / include”-o“source / ffi / sysv.o”“../ sources / fli / sysv .S”
../source/ffi/sysv.S:匯編信息:
../source/ffi/sysv.S:145:錯誤:所選處理器不支持ARM操作碼
../source/ffi/sysv.S:147:錯誤:嘗試在僅限Thumb的處理器上使用ARM指令 - “stmfd sp!,{r0-r3,fp,lr}”
...
我可以在Cortex-M3上使用libffi而不必成為裝配專家嗎?
值得注意的是,當我直接調用arm-bare_newlib_cortex_m3_nommu-eabi時,我會得到不同的錯誤。
我將sysV.S修改為follolwing,錯誤是由“.arm”指令引起的,當使用cortex-m3時,它應該被注釋掉。
#ifdef __ARM_ARCH_7M__ /* cortex-m3 */
#undef __THUMB_INTERWORK__
#endif
#if __ARM_ARCH__ >= 5
# define call_reg(x) blx x
#elif defined (__ARM_ARCH_4T__)
# define call_reg(x) mov lr, pc ; bx x
# if defined(__thumb__) || defined(__THUMB_INTERWORK__)
# define __INTERWORKING__
# endif
#else
# define call_reg(x) mov lr, pc ; mov pc, x
#endif
/* Conditionally compile unwinder directives. */
#ifdef __ARM_EABI__
#define UNWIND
#else
#define UNWIND @
#endif
#if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
.macro ARM_FUNC_START name
.text
.align 0
.thumb
.thumb_func
#ifdef __APPLE__
ENTRY($0)
#else
ENTRY(\name)
#endif
#ifndef __ARM_ARCH_7M__ /* not cortex-m3 */
bx pc
nop
.arm
#endif
UNWIND .fnstart
/* A hook to tell gdb that we've switched to ARM mode. Also used to call
directly from other local arm routines. */
#ifdef __APPLE__
_L__$0:
#else
_L__\name:
#endif
.endm
匯編程序告訴你實際情況 - ARM匯編代碼無法在像M3這樣的Thumb-2處理器上成功運行。 匯編程序無法將ARM指令助記符映射到對Cortex-M3有意義的操作碼。 您需要將程序集文件移植到Thumb-2匯編代碼以使工作正常。 根據原始匯編代碼的作用,您可能會很幸運,並且可以轉而使用C語言,但這可能會讓您受到重大性能損失。
我不想這么說,但這是一次移植工作。 可行,不一定必須是匯編專家,但需要學習一些。 從拇指到手臂很容易,拇指2,我不得不看起來,拇指2的大部分只是拇指指示。 和拇指有一對一的映射到arm指令,但不是相反。 Thumb主要限制您使用所有主要指令的低8位寄存器,使用特殊版本或特殊指令來使用高位寄存器。 因此,許多手臂指令將轉變為多個拇指指令。
最初看看是否有一個構建選項來構建這個包而不使用匯編程序或進入該目錄,看看你是否可以在makefile中做一些事情來使用C程序而不是匯編程序。 我假設使用C有一個嚴重的性能問題,這就是為什么有匯編程序開始。 理論上Thumb2比arm更有效,但這並不一定意味着從arm到thumb2的直接端口。 因此,通過一些經驗,您可以將端口移植到thumb2並保持一些性能。
編輯:
下載了有問題的文件。 前面的定義東西意味着它知道拇指和armv7m。 你是如何到達你改變推動的地方的?
將“-Wa,-mimplicit-it = thumb”添加到gcc CFLAGS以避免“拇指條件指令應該在IT塊中”錯誤
--- libffi.orig/src/arm/sysv.S
+++ libffi/src/arm/sysv.S
@@ -91,6 +91,10 @@
# define __ARM_ARCH__ 7
#endif
+#ifdef __ARM_ARCH_7M__ /* cortex-m3 */
+#undef __THUMB_INTERWORK__
+#endif
+
#if __ARM_ARCH__ >= 5
# define call_reg(x) blx x
#elif defined (__ARM_ARCH_4T__)
@@ -121,9 +125,11 @@
#else
ENTRY(\name)
#endif
+#ifndef __ARM_ARCH_7M__ /* not cortex-m3 */
bx pc
nop
.arm
+#endif
UNWIND .fnstart
/* A hook to tell gdb that we've switched to ARM mode. Also used to call
directly from other local arm routines. */
@@ -164,6 +170,10 @@ _L__\name:
#endif
.endm
+#ifdef __ARM_ARCH_7M__ /* cortex-m3 */
+ .syntax unified
+#endif
+
@ r0: ffi_prep_args
@ r1: &ecif
@ r2: cif->bytes
@@ -180,7 +190,11 @@ ARM_FUNC_START ffi_call_SYSV
UNWIND .setfp fp, sp
@ Make room for all of the new args.
+#ifdef __ARM_ARCH_7M__ /* cortex-m3 */
+ sub sp, sp, r2
+#else
sub sp, fp, r2
+#endif
@ Place all of the ffi_prep_args in position
mov r0, sp
@@ -193,7 +207,12 @@ ARM_FUNC_START ffi_call_SYSV
ldmia sp, {r0-r3}
@ and adjust stack
+#ifdef __ARM_ARCH_7M__ /* cortex-m3 */
+ mov lr, sp
+ sub lr, fp, lr @ cif->bytes == fp - sp
+#else
sub lr, fp, sp @ cif->bytes == fp - sp
+#endif
ldr ip, [fp] @ load fn() in advance
cmp lr, #16
movhs lr, #16
@@ -305,7 +324,13 @@ ARM_FUNC_START ffi_closure_SYSV
beq .Lretlonglong
.Lclosure_epilogue:
add sp, sp, #16
+#ifdef __ARM_ARCH_7M__ /* cortex-m3 */
+ ldr ip, [sp, #4]
+ ldr sp, [sp]
+ mov pc, ip
+#else
ldmfd sp, {sp, pc}
+#endif
.Lretint:
ldr r0, [sp]
b .Lclosure_epilogue
@@ -381,7 +406,12 @@ LSYM(Lbase_args):
ldmia sp, {r0-r3}
@ and adjust stack
+#ifdef __ARM_ARCH_7M__ /* cortex-m3 */
+ mov lr, sp
+ sub lr, ip, lr @ cif->bytes == (fp - 64) - sp
+#else
sub lr, ip, sp @ cif->bytes == (fp - 64) - sp
+#endif
ldr ip, [fp] @ load fn() in advance
cmp lr, #16
movhs lr, #16
@@ -469,7 +499,13 @@ ARM_FUNC_START ffi_closure_VFP
.Lclosure_epilogue_vfp:
add sp, sp, #72
+#ifdef __ARM_ARCH_7M__ /* cortex-m3 */
+ ldr ip, [sp, #4]
+ ldr sp, [sp]
+ mov pc, ip
+#else
ldmfd sp, {sp, pc}
+#endif
.Lretfloat_vfp:
flds s0, [sp]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.