From ef12a4bd05cdd531d9c130763ffb2470e9c0fb54 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 10 Apr 2018 15:06:47 +1000 Subject: [PATCH] py: Refactor how native emitter code is compiled with a file per arch. Instead of emitnative.c having configuration code for each supported architecture, and then compiling this file multiple times with different macros defined, this patch adds a file per architecture with the necessary code to configure the native emitter. These files then #include the emitnative.c file. This simplifies emitnative.c (which is already very large), and simplifies the build system because emitnative.c no longer needs special handling for compilation and qstr extraction. --- py/asmthumb.h | 1 + py/emitnarm.c | 15 ++++++++ py/emitnative.c | 97 +----------------------------------------------- py/emitnthumb.c | 15 ++++++++ py/emitnx64.c | 15 ++++++++ py/emitnx86.c | 67 +++++++++++++++++++++++++++++++++ py/emitnxtensa.c | 15 ++++++++ py/mkrules.mk | 5 +-- py/py.mk | 26 +------------ 9 files changed, 132 insertions(+), 124 deletions(-) create mode 100644 py/emitnarm.c create mode 100644 py/emitnthumb.c create mode 100644 py/emitnx64.c create mode 100644 py/emitnx86.c create mode 100644 py/emitnxtensa.c diff --git a/py/asmthumb.h b/py/asmthumb.h index 552ad75fca..8a7df5d504 100644 --- a/py/asmthumb.h +++ b/py/asmthumb.h @@ -26,6 +26,7 @@ #ifndef MICROPY_INCLUDED_PY_ASMTHUMB_H #define MICROPY_INCLUDED_PY_ASMTHUMB_H +#include #include "py/misc.h" #include "py/asmbase.h" diff --git a/py/emitnarm.c b/py/emitnarm.c new file mode 100644 index 0000000000..1b585f821b --- /dev/null +++ b/py/emitnarm.c @@ -0,0 +1,15 @@ +// ARM specific stuff + +#include "py/mpconfig.h" + +#if MICROPY_EMIT_ARM + +// This is defined so that the assembler exports generic assembler API macros +#define GENERIC_ASM_API (1) +#include "py/asmarm.h" + +#define N_ARM (1) +#define EXPORT_FUN(name) emit_native_arm_##name +#include "py/emitnative.c" + +#endif diff --git a/py/emitnative.c b/py/emitnative.c index 964db95523..7e017ba39f 100644 --- a/py/emitnative.c +++ b/py/emitnative.c @@ -57,14 +57,7 @@ #endif // wrapper around everything in this file -#if (MICROPY_EMIT_X64 && N_X64) \ - || (MICROPY_EMIT_X86 && N_X86) \ - || (MICROPY_EMIT_THUMB && N_THUMB) \ - || (MICROPY_EMIT_ARM && N_ARM) \ - || (MICROPY_EMIT_XTENSA && N_XTENSA) \ - -// this is defined so that the assembler exports generic assembler API macros -#define GENERIC_ASM_API (1) +#if N_X64 || N_X86 || N_THUMB || N_ARM || N_XTENSA // define additional generic helper macros #define ASM_MOV_LOCAL_IMM_VIA(as, local_num, imm, reg_temp) \ @@ -73,94 +66,6 @@ ASM_MOV_LOCAL_REG((as), (local_num), (reg_temp)); \ } while (false) -#if N_X64 - -// x64 specific stuff -#include "py/asmx64.h" -#define EXPORT_FUN(name) emit_native_x64_##name - -#elif N_X86 - -// x86 specific stuff - -STATIC byte mp_f_n_args[MP_F_NUMBER_OF] = { - [MP_F_CONVERT_OBJ_TO_NATIVE] = 2, - [MP_F_CONVERT_NATIVE_TO_OBJ] = 2, - [MP_F_LOAD_NAME] = 1, - [MP_F_LOAD_GLOBAL] = 1, - [MP_F_LOAD_BUILD_CLASS] = 0, - [MP_F_LOAD_ATTR] = 2, - [MP_F_LOAD_METHOD] = 3, - [MP_F_LOAD_SUPER_METHOD] = 2, - [MP_F_STORE_NAME] = 2, - [MP_F_STORE_GLOBAL] = 2, - [MP_F_STORE_ATTR] = 3, - [MP_F_OBJ_SUBSCR] = 3, - [MP_F_OBJ_IS_TRUE] = 1, - [MP_F_UNARY_OP] = 2, - [MP_F_BINARY_OP] = 3, - [MP_F_BUILD_TUPLE] = 2, - [MP_F_BUILD_LIST] = 2, - [MP_F_LIST_APPEND] = 2, - [MP_F_BUILD_MAP] = 1, - [MP_F_STORE_MAP] = 3, -#if MICROPY_PY_BUILTINS_SET - [MP_F_BUILD_SET] = 2, - [MP_F_STORE_SET] = 2, -#endif - [MP_F_MAKE_FUNCTION_FROM_RAW_CODE] = 3, - [MP_F_NATIVE_CALL_FUNCTION_N_KW] = 3, - [MP_F_CALL_METHOD_N_KW] = 3, - [MP_F_CALL_METHOD_N_KW_VAR] = 3, - [MP_F_NATIVE_GETITER] = 2, - [MP_F_NATIVE_ITERNEXT] = 1, - [MP_F_NLR_PUSH] = 1, - [MP_F_NLR_POP] = 0, - [MP_F_NATIVE_RAISE] = 1, - [MP_F_IMPORT_NAME] = 3, - [MP_F_IMPORT_FROM] = 2, - [MP_F_IMPORT_ALL] = 1, -#if MICROPY_PY_BUILTINS_SLICE - [MP_F_NEW_SLICE] = 3, -#endif - [MP_F_UNPACK_SEQUENCE] = 3, - [MP_F_UNPACK_EX] = 3, - [MP_F_DELETE_NAME] = 1, - [MP_F_DELETE_GLOBAL] = 1, - [MP_F_NEW_CELL] = 1, - [MP_F_MAKE_CLOSURE_FROM_RAW_CODE] = 3, - [MP_F_SETUP_CODE_STATE] = 5, - [MP_F_SMALL_INT_FLOOR_DIVIDE] = 2, - [MP_F_SMALL_INT_MODULO] = 2, -}; - -#include "py/asmx86.h" -#define EXPORT_FUN(name) emit_native_x86_##name - -#elif N_THUMB - -// thumb specific stuff -#include "py/asmthumb.h" -#define EXPORT_FUN(name) emit_native_thumb_##name - -#elif N_ARM - -// ARM specific stuff -#include "py/asmarm.h" -#define EXPORT_FUN(name) emit_native_arm_##name - -#elif N_XTENSA - -// Xtensa specific stuff -#include "py/asmxtensa.h" -#define EXPORT_FUN(name) emit_native_xtensa_##name - -#else - -#error unknown native emitter - -#endif - #define EMIT_NATIVE_VIPER_TYPE_ERROR(emit, ...) do { \ *emit->error_slot = mp_obj_new_exception_msg_varg(&mp_type_ViperTypeError, __VA_ARGS__); \ } while (0) diff --git a/py/emitnthumb.c b/py/emitnthumb.c new file mode 100644 index 0000000000..2b68ca3a13 --- /dev/null +++ b/py/emitnthumb.c @@ -0,0 +1,15 @@ +// thumb specific stuff + +#include "py/mpconfig.h" + +#if MICROPY_EMIT_THUMB + +// this is defined so that the assembler exports generic assembler API macros +#define GENERIC_ASM_API (1) +#include "py/asmthumb.h" + +#define N_THUMB (1) +#define EXPORT_FUN(name) emit_native_thumb_##name +#include "py/emitnative.c" + +#endif diff --git a/py/emitnx64.c b/py/emitnx64.c new file mode 100644 index 0000000000..b9800f636e --- /dev/null +++ b/py/emitnx64.c @@ -0,0 +1,15 @@ +// x64 specific stuff + +#include "py/mpconfig.h" + +#if MICROPY_EMIT_X64 + +// This is defined so that the assembler exports generic assembler API macros +#define GENERIC_ASM_API (1) +#include "py/asmx64.h" + +#define N_X64 (1) +#define EXPORT_FUN(name) emit_native_x64_##name +#include "py/emitnative.c" + +#endif diff --git a/py/emitnx86.c b/py/emitnx86.c new file mode 100644 index 0000000000..d4cd24d74f --- /dev/null +++ b/py/emitnx86.c @@ -0,0 +1,67 @@ +// x86 specific stuff + +#include "py/mpconfig.h" + +#if MICROPY_EMIT_X86 + +// This is defined so that the assembler exports generic assembler API macros +#define GENERIC_ASM_API (1) +#include "py/asmx86.h" + +// x86 needs a table to know how many args a given function has +STATIC byte mp_f_n_args[MP_F_NUMBER_OF] = { + [MP_F_CONVERT_OBJ_TO_NATIVE] = 2, + [MP_F_CONVERT_NATIVE_TO_OBJ] = 2, + [MP_F_LOAD_NAME] = 1, + [MP_F_LOAD_GLOBAL] = 1, + [MP_F_LOAD_BUILD_CLASS] = 0, + [MP_F_LOAD_ATTR] = 2, + [MP_F_LOAD_METHOD] = 3, + [MP_F_LOAD_SUPER_METHOD] = 2, + [MP_F_STORE_NAME] = 2, + [MP_F_STORE_GLOBAL] = 2, + [MP_F_STORE_ATTR] = 3, + [MP_F_OBJ_SUBSCR] = 3, + [MP_F_OBJ_IS_TRUE] = 1, + [MP_F_UNARY_OP] = 2, + [MP_F_BINARY_OP] = 3, + [MP_F_BUILD_TUPLE] = 2, + [MP_F_BUILD_LIST] = 2, + [MP_F_LIST_APPEND] = 2, + [MP_F_BUILD_MAP] = 1, + [MP_F_STORE_MAP] = 3, + #if MICROPY_PY_BUILTINS_SET + [MP_F_BUILD_SET] = 2, + [MP_F_STORE_SET] = 2, + #endif + [MP_F_MAKE_FUNCTION_FROM_RAW_CODE] = 3, + [MP_F_NATIVE_CALL_FUNCTION_N_KW] = 3, + [MP_F_CALL_METHOD_N_KW] = 3, + [MP_F_CALL_METHOD_N_KW_VAR] = 3, + [MP_F_NATIVE_GETITER] = 2, + [MP_F_NATIVE_ITERNEXT] = 1, + [MP_F_NLR_PUSH] = 1, + [MP_F_NLR_POP] = 0, + [MP_F_NATIVE_RAISE] = 1, + [MP_F_IMPORT_NAME] = 3, + [MP_F_IMPORT_FROM] = 2, + [MP_F_IMPORT_ALL] = 1, + #if MICROPY_PY_BUILTINS_SLICE + [MP_F_NEW_SLICE] = 3, + #endif + [MP_F_UNPACK_SEQUENCE] = 3, + [MP_F_UNPACK_EX] = 3, + [MP_F_DELETE_NAME] = 1, + [MP_F_DELETE_GLOBAL] = 1, + [MP_F_NEW_CELL] = 1, + [MP_F_MAKE_CLOSURE_FROM_RAW_CODE] = 3, + [MP_F_SETUP_CODE_STATE] = 5, + [MP_F_SMALL_INT_FLOOR_DIVIDE] = 2, + [MP_F_SMALL_INT_MODULO] = 2, +}; + +#define N_X86 (1) +#define EXPORT_FUN(name) emit_native_x86_##name +#include "py/emitnative.c" + +#endif diff --git a/py/emitnxtensa.c b/py/emitnxtensa.c new file mode 100644 index 0000000000..1a423e21eb --- /dev/null +++ b/py/emitnxtensa.c @@ -0,0 +1,15 @@ +// Xtensa specific stuff + +#include "py/mpconfig.h" + +#if MICROPY_EMIT_XTENSA + +// this is defined so that the assembler exports generic assembler API macros +#define GENERIC_ASM_API (1) +#include "py/asmxtensa.h" + +#define N_XTENSA (1) +#define EXPORT_FUN(name) emit_native_xtensa_##name +#include "py/emitnative.c" + +#endif diff --git a/py/mkrules.mk b/py/mkrules.mk index fa7138695d..850c2aa3a6 100644 --- a/py/mkrules.mk +++ b/py/mkrules.mk @@ -46,10 +46,7 @@ vpath %.c . $(TOP) $(BUILD)/%.o: %.c $(call compile_c) -# List all native flags since the current build system doesn't have -# the MicroPython configuration available. However, these flags are -# needed to extract all qstrings -QSTR_GEN_EXTRA_CFLAGS += -DNO_QSTR -DN_X64 -DN_X86 -DN_THUMB -DN_ARM -DN_XTENSA +QSTR_GEN_EXTRA_CFLAGS += -DNO_QSTR QSTR_GEN_EXTRA_CFLAGS += -I$(BUILD)/tmp vpath %.c . $(TOP) diff --git a/py/py.mk b/py/py.mk index 7c4cf82d82..a918135268 100644 --- a/py/py.mk +++ b/py/py.mk @@ -267,8 +267,8 @@ PY_O += $(BUILD)/$(BUILD)/frozen_mpy.o endif # Sources that may contain qstrings -SRC_QSTR_IGNORE = py/nlr% py/emitnx86% py/emitnx64% py/emitnthumb% py/emitnarm% py/emitnxtensa% -SRC_QSTR = $(SRC_MOD) $(filter-out $(SRC_QSTR_IGNORE),$(PY_CORE_O_BASENAME:.o=.c)) py/emitnative.c $(PY_EXTMOD_O_BASENAME:.o=.c) +SRC_QSTR_IGNORE = py/nlr% +SRC_QSTR = $(SRC_MOD) $(filter-out $(SRC_QSTR_IGNORE),$(PY_CORE_O_BASENAME:.o=.c)) $(PY_EXTMOD_O_BASENAME:.o=.c) # Anything that depends on FORCE will be considered out-of-date FORCE: @@ -295,28 +295,6 @@ $(HEADER_BUILD)/qstrdefs.generated.h: $(PY_QSTR_DEFS) $(QSTR_DEFS) $(QSTR_DEFS_C # that the function preludes are of a minimal and predictable form. $(PY_BUILD)/nlr%.o: CFLAGS += -Os -# emitters - -$(PY_BUILD)/emitnx64.o: CFLAGS += -DN_X64 -$(PY_BUILD)/emitnx64.o: py/emitnative.c - $(call compile_c) - -$(PY_BUILD)/emitnx86.o: CFLAGS += -DN_X86 -$(PY_BUILD)/emitnx86.o: py/emitnative.c - $(call compile_c) - -$(PY_BUILD)/emitnthumb.o: CFLAGS += -DN_THUMB -$(PY_BUILD)/emitnthumb.o: py/emitnative.c - $(call compile_c) - -$(PY_BUILD)/emitnarm.o: CFLAGS += -DN_ARM -$(PY_BUILD)/emitnarm.o: py/emitnative.c - $(call compile_c) - -$(PY_BUILD)/emitnxtensa.o: CFLAGS += -DN_XTENSA -$(PY_BUILD)/emitnxtensa.o: py/emitnative.c - $(call compile_c) - # optimising gc for speed; 5ms down to 4ms on pybv2 $(PY_BUILD)/gc.o: CFLAGS += $(CSUPEROPT)