Use Thumb instructions

This commit is contained in:
George Hilliard 2019-08-07 10:52:52 -05:00
parent 4d6eed43c5
commit b0627d2ba1
4 changed files with 133 additions and 0 deletions

View file

@ -1,4 +1,5 @@
BR2_arm=y
BR2_ARM_INSTRUCTIONS_THUMB=y
BR2_SVN="svn"
BR2_CCACHE=y
BR2_SHARED_STATIC_LIBS=y

View file

@ -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

View file

@ -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

View 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:"