Use Thumb instructions
This commit is contained in:
parent
4d6eed43c5
commit
b0627d2ba1
4 changed files with 133 additions and 0 deletions
|
@ -1,4 +1,5 @@
|
||||||
BR2_arm=y
|
BR2_arm=y
|
||||||
|
BR2_ARM_INSTRUCTIONS_THUMB=y
|
||||||
BR2_SVN="svn"
|
BR2_SVN="svn"
|
||||||
BR2_CCACHE=y
|
BR2_CCACHE=y
|
||||||
BR2_SHARED_STATIC_LIBS=y
|
BR2_SHARED_STATIC_LIBS=y
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
commit 34c04d2319cdfae01ed7bf7f9e341d69b86d751a
|
||||||
|
Author: Damien George <damien.p.george@gmail.com>
|
||||||
|
Date: Mon Jun 17 23:19:34 2019 +1000
|
||||||
|
|
||||||
|
py/nlrthumb: Save and restore VFP registers s16-s21 when CPU has them.
|
||||||
|
|
||||||
|
These s16-s21 registers are used by gcc so need to be saved. Future
|
||||||
|
versions of gcc (beyond v9.1.0), or other compilers, may eventually need
|
||||||
|
additional registers saved/restored.
|
||||||
|
|
||||||
|
See issue #4844.
|
||||||
|
|
||||||
|
diff --git a/py/nlr.h b/py/nlr.h
|
||||||
|
index 90595a12d..8ce5cf0f4 100644
|
||||||
|
--- a/py/nlr.h
|
||||||
|
+++ b/py/nlr.h
|
||||||
|
@@ -54,7 +54,14 @@
|
||||||
|
#endif
|
||||||
|
#elif defined(__thumb2__) || defined(__thumb__) || defined(__arm__)
|
||||||
|
#define MICROPY_NLR_THUMB (1)
|
||||||
|
- #define MICROPY_NLR_NUM_REGS (10)
|
||||||
|
+ #if defined(__SOFTFP__)
|
||||||
|
+ #define MICROPY_NLR_NUM_REGS (10)
|
||||||
|
+ #else
|
||||||
|
+ // With hardware FP registers s16-s31 are callee save so in principle
|
||||||
|
+ // should be saved and restored by the NLR code. gcc only uses s16-s21
|
||||||
|
+ // so only save/restore those as an optimisation.
|
||||||
|
+ #define MICROPY_NLR_NUM_REGS (10 + 6)
|
||||||
|
+ #endif
|
||||||
|
#elif defined(__xtensa__)
|
||||||
|
#define MICROPY_NLR_XTENSA (1)
|
||||||
|
#define MICROPY_NLR_NUM_REGS (10)
|
||||||
|
diff --git a/py/nlrthumb.c b/py/nlrthumb.c
|
||||||
|
index 99061e62c..32fa6b117 100644
|
||||||
|
--- a/py/nlrthumb.c
|
||||||
|
+++ b/py/nlrthumb.c
|
||||||
|
@@ -63,6 +63,11 @@ __attribute__((naked)) unsigned int nlr_push(nlr_buf_t *nlr) {
|
||||||
|
"str r10, [r0, #36] \n" // store r10 into nlr_buf
|
||||||
|
"str r11, [r0, #40] \n" // store r11 into nlr_buf
|
||||||
|
"str r13, [r0, #44] \n" // store r13=sp into nlr_buf
|
||||||
|
+ #if MICROPY_NLR_NUM_REGS == 16
|
||||||
|
+ "vstr d8, [r0, #48] \n" // store s16-s17 into nlr_buf
|
||||||
|
+ "vstr d9, [r0, #56] \n" // store s18-s19 into nlr_buf
|
||||||
|
+ "vstr d10, [r0, #64] \n" // store s20-s21 into nlr_buf
|
||||||
|
+ #endif
|
||||||
|
"str lr, [r0, #8] \n" // store lr into nlr_buf
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@@ -116,6 +121,11 @@ NORETURN void nlr_jump(void *val) {
|
||||||
|
"ldr r10, [r0, #36] \n" // load r10 from nlr_buf
|
||||||
|
"ldr r11, [r0, #40] \n" // load r11 from nlr_buf
|
||||||
|
"ldr r13, [r0, #44] \n" // load r13=sp from nlr_buf
|
||||||
|
+ #if MICROPY_NLR_NUM_REGS == 16
|
||||||
|
+ "vldr d8, [r0, #48] \n" // load s16-s17 from nlr_buf
|
||||||
|
+ "vldr d9, [r0, #56] \n" // load s18-s19 from nlr_buf
|
||||||
|
+ "vldr d10, [r0, #64] \n" // load s20-s21 from nlr_buf
|
||||||
|
+ #endif
|
||||||
|
"ldr lr, [r0, #8] \n" // load lr from nlr_buf
|
||||||
|
#endif
|
||||||
|
"movs r0, #1 \n" // return 1, non-local return
|
|
@ -0,0 +1,45 @@
|
||||||
|
commit f3a5b313e55e8853928702eec16c932481f370fc
|
||||||
|
Author: David Lechner <david@pybricks.com>
|
||||||
|
Date: Thu Jun 27 16:43:05 2019 -0500
|
||||||
|
|
||||||
|
py/nlrthumb: Check __thumb2__ instead of __ARM_ARCH_6M__.
|
||||||
|
|
||||||
|
This fixes compiling for older architectures (e.g. armv5tej).
|
||||||
|
|
||||||
|
According to [1], the limit of R0-R7 for the STR and LDR instructions is
|
||||||
|
tied to the Thumb instruction set and not any specific processor
|
||||||
|
architectures.
|
||||||
|
|
||||||
|
[1]: http://www.keil.com/support/man/docs/armasm/armasm_dom1361289906890.htm
|
||||||
|
|
||||||
|
diff --git a/py/nlrthumb.c b/py/nlrthumb.c
|
||||||
|
index 32fa6b117..eef05229d 100644
|
||||||
|
--- a/py/nlrthumb.c
|
||||||
|
+++ b/py/nlrthumb.c
|
||||||
|
@@ -44,7 +44,7 @@ __attribute__((naked)) unsigned int nlr_push(nlr_buf_t *nlr) {
|
||||||
|
"str r6, [r0, #20] \n" // store r6 into nlr_buf
|
||||||
|
"str r7, [r0, #24] \n" // store r7 into nlr_buf
|
||||||
|
|
||||||
|
-#if defined(__ARM_ARCH_6M__)
|
||||||
|
+#if !defined(__thumb2__)
|
||||||
|
"mov r1, r8 \n"
|
||||||
|
"str r1, [r0, #28] \n" // store r8 into nlr_buf
|
||||||
|
"mov r1, r9 \n"
|
||||||
|
@@ -71,7 +71,7 @@ __attribute__((naked)) unsigned int nlr_push(nlr_buf_t *nlr) {
|
||||||
|
"str lr, [r0, #8] \n" // store lr into nlr_buf
|
||||||
|
#endif
|
||||||
|
|
||||||
|
-#if defined(__ARM_ARCH_6M__)
|
||||||
|
+#if !defined(__thumb2__)
|
||||||
|
"ldr r1, nlr_push_tail_var \n"
|
||||||
|
"bx r1 \n" // do the rest in C
|
||||||
|
".align 2 \n"
|
||||||
|
@@ -102,7 +102,7 @@ NORETURN void nlr_jump(void *val) {
|
||||||
|
"ldr r6, [r0, #20] \n" // load r6 from nlr_buf
|
||||||
|
"ldr r7, [r0, #24] \n" // load r7 from nlr_buf
|
||||||
|
|
||||||
|
-#if defined(__ARM_ARCH_6M__)
|
||||||
|
+#if !defined(__thumb2__)
|
||||||
|
"ldr r1, [r0, #28] \n" // load r8 from nlr_buf
|
||||||
|
"mov r8, r1 \n"
|
||||||
|
"ldr r1, [r0, #32] \n" // load r9 from nlr_buf
|
27
patches/micropython/0003-use-clear_cache-on-linux-gcc.patch
Normal file
27
patches/micropython/0003-use-clear_cache-on-linux-gcc.patch
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
commit 62b00dd5d8cd6207147d37222e1c249ef6381841
|
||||||
|
Author: David Lechner <david@pybricks.com>
|
||||||
|
Date: Thu Jun 27 13:36:15 2019 -0500
|
||||||
|
|
||||||
|
py/asmarm: Use __clear_cache on Linux/GCC when creating new asm code.
|
||||||
|
|
||||||
|
Comes from https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/caches-and-self-modifying-code
|
||||||
|
|
||||||
|
This fixes a crash when running MicroPython using qemu-arm.
|
||||||
|
|
||||||
|
diff --git a/py/asmarm.c b/py/asmarm.c
|
||||||
|
index f2221f8a9..2a84f985b 100644
|
||||||
|
--- a/py/asmarm.c
|
||||||
|
+++ b/py/asmarm.c
|
||||||
|
@@ -40,7 +40,11 @@
|
||||||
|
|
||||||
|
void asm_arm_end_pass(asm_arm_t *as) {
|
||||||
|
if (as->base.pass == MP_ASM_PASS_EMIT) {
|
||||||
|
-#ifdef __arm__
|
||||||
|
+#if defined(__linux__) && defined(__GNUC__)
|
||||||
|
+ char *start = mp_asm_base_get_code(&as->base);
|
||||||
|
+ char *end = start + mp_asm_base_get_code_size(&as->base);
|
||||||
|
+ __clear_cache(start, end);
|
||||||
|
+#elif defined(__arm__)
|
||||||
|
// flush I- and D-cache
|
||||||
|
asm volatile(
|
||||||
|
"0:"
|
Loading…
Reference in a new issue