Skip to content

Commit d41b8dc

Browse files
committed
py/emitglue: Fix macro logic that selects cache flushing code.
This fixes a regression made by 9e9da6c. There are two issues here: 1. `MPY_FEATURE_ARCH` and `MP_NATIVE_ARCH_xxx` are not visible in this file because `py/persistentcode.h` is not included. 2. Even if they were visible the macro logic will not work because `MP_NATIVE_ARCH_xxx` are enum values and cannot be used in #if logic. What this means is that the first #if is always true, so there is no cache flushing on ARM (non-Thumb) or RISC-V targets. This breaks native code on, eg, ESP32-P4. The fix here aims to simplify the logic by using built-in compiler defines to select the target: - On an ARM Thumb target with `__ICACHE_PRESENT` enabled, it will flush the cache. - On an ARM (non-Thumb) target, it will prefer `__builtin___clear_cache()` if possible, otherwise it will use inline assembler. - On a RISC-V target, it will use `MP_HAL_CLEAN_DCACHE()` if that macro is defined (that's only on ESP32-P4 at the moment). The logic should be the same as before, except for the cases where an emitter is enabled on a mismatching architecture. For example, if `MICROPY_EMIT_THUMB` and/or `MICROPY_EMIT_INLINE_THUMB` were enabled on a non-Thumb target, previously that will try to generate code to flush caches (which doesn't really make sense), but now it will not. This actually happened for `mpy-cross` which does enable all the emitters, and prior to this fix would follow the Thumb path, but not generate any code because `__ICACHE_PRESENT` is disabled (at least when building `mpy-cross` on x86). Signed-off-by: Damien George <damien@micropython.org>
1 parent 2dc2e30 commit d41b8dc

1 file changed

Lines changed: 4 additions & 4 deletions

File tree

py/emitglue.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,17 +107,17 @@ void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, cons
107107
// Some architectures require flushing/invalidation of the I/D caches,
108108
// so that the generated native code which was created in data RAM will
109109
// be available for execution from instruction RAM.
110-
#if MICROPY_EMIT_THUMB || MICROPY_EMIT_INLINE_THUMB || (MP_NATIVE_ARCH_ARMV6M <= MPY_FEATURE_ARCH && MPY_FEATURE_ARCH <= MP_NATIVE_ARCH_ARMV7EMDP)
110+
#if defined(__thumb__) || defined(__thumb2__)
111111
#if __ICACHE_PRESENT == 1
112112
// Flush D-cache, so the code emitted is stored in RAM.
113113
MP_HAL_CLEAN_DCACHE(fun_data, fun_len);
114114
// Invalidate I-cache, so the newly-created code is reloaded from RAM.
115115
SCB_InvalidateICache();
116116
#endif
117-
#elif MICROPY_EMIT_ARM || (MPY_FEATURE_ARCH == MP_NATIVE_ARCH_ARMV6)
117+
#elif defined(__arm__)
118118
#if (defined(__linux__) && defined(__GNUC__)) || __ARM_ARCH == 7
119119
__builtin___clear_cache((void *)fun_data, (char *)fun_data + fun_len);
120-
#elif defined(__arm__)
120+
#else
121121
// Flush I-cache and D-cache.
122122
asm volatile (
123123
"0:"
@@ -127,7 +127,7 @@ void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, cons
127127
"mcr p15, 0, r0, c7, c7, 0\n" // invalidate I-cache and D-cache
128128
: : : "r0", "cc");
129129
#endif
130-
#elif (MICROPY_EMIT_RV32 || MICROPY_EMIT_INLINE_RV32 || (MPY_FEATURE_ARCH == MP_NATIVE_ARCH_RV32IMC)) && defined(MP_HAL_CLEAN_DCACHE)
130+
#elif defined(__riscv) && defined(MP_HAL_CLEAN_DCACHE)
131131
// Flush the D-cache.
132132
MP_HAL_CLEAN_DCACHE(fun_data, fun_len);
133133
#endif

0 commit comments

Comments
 (0)