Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions mpy-cross/mpconfigport.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

#define MICROPY_ALLOC_PATH_MAX (PATH_MAX)
#define MICROPY_PERSISTENT_CODE_LOAD (0)
#define MICROPY_PERSISTENT_CODE_LOAD_NATIVE (0)
#define MICROPY_PERSISTENT_CODE_SAVE (1)

#ifndef MICROPY_PERSISTENT_CODE_SAVE_FILE
Expand Down
2 changes: 1 addition & 1 deletion py/bc.c
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ void mp_setup_code_state(mp_code_state_t *code_state, size_t n_args, size_t n_kw
mp_setup_code_state_helper(code_state, n_args, n_kw, args);
}

#if MICROPY_EMIT_NATIVE
#if MICROPY_ENABLE_NATIVE_CODE
// On entry code_state should be allocated somewhere (stack/heap) and
// contain the following valid entries:
// - code_state->fun_bc should contain a pointer to the function object
Expand Down
13 changes: 8 additions & 5 deletions py/emitglue.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ void mp_emit_glue_assign_bytecode(mp_raw_code_t *rc, const byte *code,
#endif
}

#if MICROPY_EMIT_MACHINE_CODE
#if MICROPY_EMIT_INLINE_ASM || MICROPY_ENABLE_NATIVE_CODE
void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, const void *fun_data, mp_uint_t fun_len,
mp_raw_code_t **children,
#if MICROPY_PERSISTENT_CODE_SAVE
Expand All @@ -113,15 +113,18 @@ void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, cons
// Some architectures require flushing/invalidation of the I/D caches,
// so that the generated native code which was created in data RAM will
// be available for execution from instruction RAM.
#if MICROPY_EMIT_THUMB || MICROPY_EMIT_INLINE_THUMB
// CIRCUITPY-CHANGE: MP_NATIVE_ARCH_* are enum values, always 0 to the
// preprocessor, and MPY_FEATURE_ARCH is not defined here; test the
// compiler target instead.
#if MICROPY_EMIT_THUMB || MICROPY_EMIT_INLINE_THUMB || (MICROPY_PERSISTENT_CODE_LOAD_NATIVE && (defined(__thumb__) || defined(__thumb2__)))
// CIRCUITPY-CHANGE: prevent warning
#if defined(__ICACHE_PRESENT) && __ICACHE_PRESENT == 1
// Flush D-cache, so the code emitted is stored in RAM.
MP_HAL_CLEAN_DCACHE(fun_data, fun_len);
// Invalidate I-cache, so the newly-created code is reloaded from RAM.
SCB_InvalidateICache();
#endif
#elif MICROPY_EMIT_ARM
#elif MICROPY_EMIT_ARM || (MICROPY_PERSISTENT_CODE_LOAD_NATIVE && defined(__arm__) && !defined(__thumb__))
#if (defined(__linux__) && defined(__GNUC__)) || __ARM_ARCH == 7
__builtin___clear_cache((void *)fun_data, (char *)fun_data + fun_len);
#elif defined(__arm__)
Expand All @@ -134,7 +137,7 @@ void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, cons
"mcr p15, 0, r0, c7, c7, 0\n" // invalidate I-cache and D-cache
: : : "r0", "cc");
#endif
#elif (MICROPY_EMIT_RV32 || MICROPY_EMIT_INLINE_RV32) && defined(MP_HAL_CLEAN_DCACHE)
#elif (MICROPY_EMIT_RV32 || MICROPY_EMIT_INLINE_RV32 || (MICROPY_PERSISTENT_CODE_LOAD_NATIVE && defined(__riscv))) && defined(MP_HAL_CLEAN_DCACHE)
// Flush the D-cache.
MP_HAL_CLEAN_DCACHE(fun_data, fun_len);
#endif
Expand Down Expand Up @@ -219,7 +222,7 @@ mp_obj_t mp_make_function_from_proto_fun(mp_proto_fun_t proto_fun, const mp_modu
// make the function, depending on the raw code kind
mp_obj_t fun;
switch (rc->kind) {
#if MICROPY_EMIT_NATIVE
#if MICROPY_ENABLE_NATIVE_CODE
case MP_CODE_NATIVE_PY:
fun = mp_obj_new_fun_native(def_args, rc->fun_data, context, rc->children);
// Check for a generator function, and if so change the type of the object
Expand Down
4 changes: 2 additions & 2 deletions py/emitglue.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ typedef struct _mp_raw_code_t {
#if MICROPY_PERSISTENT_CODE_SAVE
uint32_t fun_data_len; // for mp_raw_code_save
uint16_t n_children;
#if MICROPY_EMIT_MACHINE_CODE
#if MICROPY_EMIT_INLINE_ASM || MICROPY_ENABLE_NATIVE_CODE
uint16_t prelude_offset;
#endif
#if MICROPY_PY_SYS_SETTRACE
Expand Down Expand Up @@ -116,7 +116,7 @@ typedef struct _mp_raw_code_truncated_t {
#if MICROPY_PERSISTENT_CODE_SAVE
uint32_t fun_data_len;
uint16_t n_children;
#if MICROPY_EMIT_MACHINE_CODE
#if MICROPY_EMIT_INLINE_ASM || MICROPY_ENABLE_NATIVE_CODE
uint16_t prelude_offset;
#endif
#if MICROPY_PY_SYS_SETTRACE
Expand Down
15 changes: 12 additions & 3 deletions py/mpconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,11 @@ typedef uint64_t mp_uint_t;
#define MICROPY_PERSISTENT_CODE_LOAD (0)
#endif

// Whether to support loading of persistent native code
#ifndef MICROPY_PERSISTENT_CODE_LOAD_NATIVE
#define MICROPY_PERSISTENT_CODE_LOAD_NATIVE (MICROPY_EMIT_MACHINE_CODE)
#endif

// Whether to support saving of persistent code, i.e. for mpy-cross to
// generate .mpy files. Enabling this enables additional metadata on raw code
// objects which is also required for sys.settrace.
Expand All @@ -446,7 +451,7 @@ typedef uint64_t mp_uint_t;
// Whether generated code can persist independently of the VM/runtime instance
// This is enabled automatically when needed by other features
#ifndef MICROPY_PERSISTENT_CODE
#define MICROPY_PERSISTENT_CODE (MICROPY_PERSISTENT_CODE_LOAD || MICROPY_PERSISTENT_CODE_SAVE || MICROPY_MODULE_FROZEN_MPY)
#define MICROPY_PERSISTENT_CODE (MICROPY_PERSISTENT_CODE_LOAD || MICROPY_PERSISTENT_CODE_LOAD_NATIVE || MICROPY_PERSISTENT_CODE_SAVE || MICROPY_MODULE_FROZEN_MPY)
#endif

// Whether bytecode uses a qstr_table to map internal qstr indices in the bytecode
Expand Down Expand Up @@ -546,6 +551,10 @@ typedef uint64_t mp_uint_t;
// Convenience definition for whether any native or inline assembler emitter is enabled
#define MICROPY_EMIT_MACHINE_CODE (MICROPY_EMIT_NATIVE || MICROPY_EMIT_INLINE_ASM)

// Convenience definition for whether native code has to be dealt with (either
// generated or loaded from a file). This does not cover inline asm code.
#define MICROPY_ENABLE_NATIVE_CODE (MICROPY_EMIT_NATIVE || MICROPY_PERSISTENT_CODE_LOAD_NATIVE)

/*****************************************************************************/
/* Compiler configuration */

Expand Down Expand Up @@ -2327,7 +2336,7 @@ typedef time_t mp_timestamp_t;
// can be overridden if needed by defining both MICROPY_PERSISTENT_CODE_TRACK_FUN_DATA
// and MICROPY_PERSISTENT_CODE_TRACK_BSS_RODATA.
#ifndef MICROPY_PERSISTENT_CODE_TRACK_FUN_DATA
#if MICROPY_EMIT_MACHINE_CODE && MICROPY_PERSISTENT_CODE_LOAD
#if (MICROPY_EMIT_INLINE_ASM || MICROPY_ENABLE_NATIVE_CODE) && MICROPY_PERSISTENT_CODE_LOAD
// Pointer tracking is required when loading native code is enabled.
#if defined(MP_PLAT_ALLOC_EXEC) || defined(MP_PLAT_COMMIT_EXEC)
// If a port defined a custom allocator or commit function for native text, then the
Expand All @@ -2348,7 +2357,7 @@ typedef time_t mp_timestamp_t;
#define MICROPY_PERSISTENT_CODE_TRACK_FUN_DATA (1)
#define MICROPY_PERSISTENT_CODE_TRACK_BSS_RODATA (0)
#endif
#else // MICROPY_EMIT_MACHINE_CODE && MICROPY_PERSISTENT_CODE_LOAD
#else // (MICROPY_EMIT_INLINE_ASM || MICROPY_ENABLE_NATIVE_CODE) && MICROPY_PERSISTENT_CODE_LOAD
// Pointer tracking not needed when loading native code is disabled.
#define MICROPY_PERSISTENT_CODE_TRACK_FUN_DATA (0)
#define MICROPY_PERSISTENT_CODE_TRACK_BSS_RODATA (0)
Expand Down
10 changes: 5 additions & 5 deletions py/nativeglue.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
#define DEBUG_printf(...) (void)0
#endif

#if MICROPY_EMIT_NATIVE
#if MICROPY_ENABLE_NATIVE_CODE

int mp_native_type_from_qstr(qstr qst) {
switch (qst) {
Expand Down Expand Up @@ -93,7 +93,7 @@ mp_uint_t mp_native_from_obj(mp_obj_t obj, mp_uint_t type) {

#endif

#if MICROPY_EMIT_MACHINE_CODE
#if MICROPY_EMIT_INLINE_ASM || MICROPY_ENABLE_NATIVE_CODE

// convert a native value to a MicroPython object based on type
mp_obj_t mp_native_to_obj(mp_uint_t val, mp_uint_t type) {
Expand All @@ -117,7 +117,7 @@ mp_obj_t mp_native_to_obj(mp_uint_t val, mp_uint_t type) {

#endif

#if MICROPY_EMIT_NATIVE && !MICROPY_DYNAMIC_COMPILER
#if MICROPY_ENABLE_NATIVE_CODE && !MICROPY_DYNAMIC_COMPILER

#if !MICROPY_PY_BUILTINS_SET
mp_obj_t mp_obj_new_set(size_t n_args, mp_obj_t *items) {
Expand Down Expand Up @@ -359,8 +359,8 @@ const mp_fun_table_t mp_fun_table = {
&mp_stream_write_obj,
};

#elif MICROPY_EMIT_NATIVE && MICROPY_DYNAMIC_COMPILER
#elif MICROPY_ENABLE_NATIVE_CODE && MICROPY_DYNAMIC_COMPILER

const int mp_fun_table;

#endif // MICROPY_EMIT_NATIVE
#endif // MICROPY_ENABLE_NATIVE_CODE
4 changes: 2 additions & 2 deletions py/nativeglue.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,9 +184,9 @@ typedef struct _mp_fun_table_t {
const mp_obj_fun_builtin_var_t *stream_write_obj;
} mp_fun_table_t;

#if (MICROPY_EMIT_NATIVE && !MICROPY_DYNAMIC_COMPILER) || MICROPY_ENABLE_DYNRUNTIME
#if (MICROPY_ENABLE_NATIVE_CODE && !MICROPY_DYNAMIC_COMPILER) || MICROPY_ENABLE_DYNRUNTIME
extern const mp_fun_table_t mp_fun_table;
#elif MICROPY_EMIT_NATIVE && MICROPY_DYNAMIC_COMPILER
#elif MICROPY_ENABLE_NATIVE_CODE && MICROPY_DYNAMIC_COMPILER
// In dynamic-compiler mode eliminate dependency on entries in mp_fun_table.
// This only needs to be an independent pointer, content doesn't matter.
extern const int mp_fun_table;
Expand Down
10 changes: 3 additions & 7 deletions py/objfun.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ qstr mp_obj_fun_get_name(mp_const_obj_t fun_in) {
const mp_obj_fun_bc_t *fun = MP_OBJ_TO_PTR(fun_in);
const byte *bc = fun->bytecode;

#if MICROPY_EMIT_NATIVE
#if MICROPY_ENABLE_NATIVE_CODE
if (fun->base.type == &mp_type_fun_native || fun->base.type == &mp_type_native_gen_wrap) {
bc = mp_obj_fun_native_get_prelude_ptr(fun);
}
Expand Down Expand Up @@ -448,7 +448,7 @@ mp_obj_t mp_obj_new_fun_bc(const mp_obj_t *def_args, const byte *code, const mp_
/******************************************************************************/
/* native functions */

#if MICROPY_EMIT_NATIVE
#if MICROPY_ENABLE_NATIVE_CODE

// CIRCUITPY-CHANGE: PLACE_IN_ITCM
static mp_obj_t PLACE_IN_ITCM(fun_native_call)(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
Expand Down Expand Up @@ -478,13 +478,9 @@ MP_DEFINE_CONST_OBJ_TYPE(
call, fun_native_call
);

#endif // MICROPY_EMIT_NATIVE

/******************************************************************************/
/* viper functions */

#if MICROPY_EMIT_NATIVE

static mp_obj_t fun_viper_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_cstack_check();
mp_obj_fun_bc_t *self = MP_OBJ_TO_PTR(self_in);
Expand All @@ -499,7 +495,7 @@ MP_DEFINE_CONST_OBJ_TYPE(
call, fun_viper_call
);

#endif // MICROPY_EMIT_NATIVE
#endif // MICROPY_ENABLE_NATIVE_CODE

/******************************************************************************/
/* inline assembler functions */
Expand Down
2 changes: 1 addition & 1 deletion py/objfun.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ typedef struct _mp_obj_fun_asm_t {
mp_obj_t mp_obj_new_fun_bc(const mp_obj_t *def_args, const byte *code, const mp_module_context_t *cm, struct _mp_raw_code_t *const *raw_code_table);
void mp_obj_fun_bc_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest);

#if MICROPY_EMIT_NATIVE
#if MICROPY_ENABLE_NATIVE_CODE

static inline mp_obj_t mp_obj_new_fun_native(const mp_obj_t *def_args, const void *fun_data, const mp_module_context_t *mc, struct _mp_raw_code_t *const *child_table) {
mp_obj_fun_bc_t *o = (mp_obj_fun_bc_t *)MP_OBJ_TO_PTR(mp_obj_new_fun_bc(def_args, (const byte *)fun_data, mc, child_table));
Expand Down
10 changes: 5 additions & 5 deletions py/objgenerator.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ MP_DEFINE_CONST_OBJ_TYPE(
/******************************************************************************/
// native generator wrapper

#if MICROPY_EMIT_NATIVE
#if MICROPY_ENABLE_NATIVE_CODE

// Based on mp_obj_gen_instance_t.
typedef struct _mp_obj_gen_instance_native_t {
Expand Down Expand Up @@ -184,7 +184,7 @@ MP_DEFINE_CONST_OBJ_TYPE(
);
#endif

#endif // MICROPY_EMIT_NATIVE
#endif // MICROPY_ENABLE_NATIVE_CODE

/******************************************************************************/
/* generator instance */
Expand Down Expand Up @@ -237,7 +237,7 @@ mp_vm_return_kind_t mp_obj_gen_resume(mp_obj_t self_in, mp_obj_t send_value, mp_

// If the generator is started, allow sending a value.
void *state_start = self->code_state.state - 1;
#if MICROPY_EMIT_NATIVE
#if MICROPY_ENABLE_NATIVE_CODE
if (self->code_state.exc_sp_idx == MP_CODE_STATE_EXC_SP_IDX_SENTINEL) {
state_start = ((mp_obj_gen_instance_native_t *)self)->code_state.state - 1;
}
Expand All @@ -259,7 +259,7 @@ mp_vm_return_kind_t mp_obj_gen_resume(mp_obj_t self_in, mp_obj_t send_value, mp_

mp_vm_return_kind_t ret_kind;

#if MICROPY_EMIT_NATIVE
#if MICROPY_ENABLE_NATIVE_CODE
if (self->code_state.exc_sp_idx == MP_CODE_STATE_EXC_SP_IDX_SENTINEL) {
// A native generator.
typedef uintptr_t (*mp_fun_native_gen_t)(void *, mp_obj_t);
Expand Down Expand Up @@ -297,7 +297,7 @@ mp_vm_return_kind_t mp_obj_gen_resume(mp_obj_t self_in, mp_obj_t send_value, mp_

case MP_VM_RETURN_EXCEPTION: {
self->code_state.ip = 0;
#if MICROPY_EMIT_NATIVE
#if MICROPY_ENABLE_NATIVE_CODE
if (self->code_state.exc_sp_idx == MP_CODE_STATE_EXC_SP_IDX_SENTINEL) {
*ret_val = ((mp_obj_gen_instance_native_t *)self)->code_state.state[0];
} else
Expand Down
14 changes: 7 additions & 7 deletions py/persistentcode.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ typedef struct _bytecode_prelude_t {
static int read_byte(mp_reader_t *reader);
static size_t read_uint(mp_reader_t *reader);

#if MICROPY_EMIT_MACHINE_CODE
#if MICROPY_EMIT_INLINE_ASM || MICROPY_ENABLE_NATIVE_CODE

#if MICROPY_PERSISTENT_CODE_TRACK_FUN_DATA || MICROPY_PERSISTENT_CODE_TRACK_BSS_RODATA

Expand Down Expand Up @@ -229,7 +229,7 @@ static mp_obj_t mp_obj_new_str_static(const mp_obj_type_t *type, const byte *dat

static mp_obj_t load_obj(mp_reader_t *reader) {
byte obj_type = read_byte(reader);
#if MICROPY_EMIT_MACHINE_CODE
#if MICROPY_EMIT_INLINE_ASM || MICROPY_ENABLE_NATIVE_CODE
if (obj_type == MP_PERSISTENT_OBJ_FUN_TABLE) {
return MP_OBJ_FROM_PTR(&mp_fun_table);
} else
Expand Down Expand Up @@ -302,14 +302,14 @@ static mp_raw_code_t *load_raw_code(mp_reader_t *reader, mp_module_context_t *co
bool has_children = !!(kind_len & 4);
size_t fun_data_len = kind_len >> 3;

#if !MICROPY_EMIT_MACHINE_CODE
#if !(MICROPY_EMIT_INLINE_ASM || MICROPY_ENABLE_NATIVE_CODE)
if (kind != MP_CODE_BYTECODE) {
mp_raise_ValueError(MP_ERROR_TEXT("incompatible .mpy file"));
}
#endif

uint8_t *fun_data = NULL;
#if MICROPY_EMIT_MACHINE_CODE
#if MICROPY_EMIT_INLINE_ASM || MICROPY_ENABLE_NATIVE_CODE
size_t prelude_offset = 0;
mp_uint_t native_scope_flags = 0;
mp_uint_t native_n_pos_args = 0;
Expand All @@ -329,7 +329,7 @@ static mp_raw_code_t *load_raw_code(mp_reader_t *reader, mp_module_context_t *co
read_bytes(reader, fun_data, fun_data_len);
}

#if MICROPY_EMIT_MACHINE_CODE
#if MICROPY_EMIT_INLINE_ASM || MICROPY_ENABLE_NATIVE_CODE
} else {
// Allocate memory for native data and load it
size_t fun_alloc;
Expand All @@ -356,7 +356,7 @@ static mp_raw_code_t *load_raw_code(mp_reader_t *reader, mp_module_context_t *co
size_t n_children = 0;
mp_raw_code_t **children = NULL;

#if MICROPY_EMIT_MACHINE_CODE
#if MICROPY_EMIT_INLINE_ASM || MICROPY_ENABLE_NATIVE_CODE
// Load optional BSS/rodata for viper.
uint8_t *rodata = NULL;
uint8_t *bss = NULL;
Expand Down Expand Up @@ -411,7 +411,7 @@ static mp_raw_code_t *load_raw_code(mp_reader_t *reader, mp_module_context_t *co
#endif
scope_flags);

#if MICROPY_EMIT_MACHINE_CODE
#if MICROPY_EMIT_INLINE_ASM || MICROPY_ENABLE_NATIVE_CODE
} else {
const uint8_t *prelude_ptr = NULL;
#if MICROPY_EMIT_NATIVE_PRELUDE_SEPARATE_FROM_MACHINE_CODE
Expand Down
Loading
Loading