Skip to content

Commit 9dbc787

Browse files
committed
py/emitndebug: Add native debug emitter.
This emitter prints out pseudo-machine instructions, instead of the usual output of the native emitter. It can be enabled on any port via `MICROPY_EMIT_NATIVE_DEBUG` (make sure other native emitters are disabled) but the easiest way to use it is with mpy-cross: $ mpy-cross -march=debug file.py Signed-off-by: Damien George <[email protected]>
1 parent e2ae03e commit 9dbc787

11 files changed

+315
-4
lines changed

mpy-cross/main.c

+5-2
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ static void stdout_print_strn(void *env, const char *str, size_t len) {
5454
(void)dummy;
5555
}
5656

57-
static const mp_print_t mp_stdout_print = {NULL, stdout_print_strn};
57+
const mp_print_t mp_stdout_print = {NULL, stdout_print_strn};
5858

5959
static void stderr_print_strn(void *env, const char *str, size_t len) {
6060
(void)env;
@@ -130,7 +130,7 @@ static int usage(char **argv) {
130130
"Target specific options:\n"
131131
"-msmall-int-bits=number : set the maximum bits used to encode a small-int\n"
132132
"-march=<arch> : set architecture for native emitter;\n"
133-
" x86, x64, armv6, armv6m, armv7m, armv7em, armv7emsp, armv7emdp, xtensa, xtensawin, rv32imc\n"
133+
" x86, x64, armv6, armv6m, armv7m, armv7em, armv7emsp, armv7emdp, xtensa, xtensawin, rv32imc, debug\n"
134134
"\n"
135135
"Implementation specific options:\n", argv[0]
136136
);
@@ -316,6 +316,9 @@ MP_NOINLINE int main_(int argc, char **argv) {
316316
} else if (strcmp(arch, "rv32imc") == 0) {
317317
mp_dynamic_compiler.native_arch = MP_NATIVE_ARCH_RV32IMC;
318318
mp_dynamic_compiler.nlr_buf_num_regs = MICROPY_NLR_NUM_REGS_RV32I;
319+
} else if (strcmp(arch, "debug") == 0) {
320+
mp_dynamic_compiler.native_arch = MP_NATIVE_ARCH_DEBUG;
321+
mp_dynamic_compiler.nlr_buf_num_regs = 0;
319322
} else if (strcmp(arch, "host") == 0) {
320323
#if defined(__i386__) || defined(_M_IX86)
321324
mp_dynamic_compiler.native_arch = MP_NATIVE_ARCH_X86;

mpy-cross/mpconfigport.h

+4
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@
4747
#define MICROPY_EMIT_INLINE_XTENSA (1)
4848
#define MICROPY_EMIT_XTENSAWIN (1)
4949
#define MICROPY_EMIT_RV32 (1)
50+
#define MICROPY_EMIT_NATIVE_DEBUG (1)
51+
#define MICROPY_EMIT_NATIVE_DEBUG_PRINTER (&mp_stdout_print)
5052

5153
#define MICROPY_DYNAMIC_COMPILER (1)
5254
#define MICROPY_COMP_CONST_FOLDING (1)
@@ -164,3 +166,5 @@ typedef int ssize_t;
164166
typedef mp_off_t off_t;
165167

166168
#endif
169+
170+
extern const struct _mp_print_t mp_stdout_print;

py/asmbase.c

+6
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "py/obj.h"
3131
#include "py/misc.h"
3232
#include "py/asmbase.h"
33+
#include "py/persistentcode.h"
3334

3435
#if MICROPY_EMIT_MACHINE_CODE
3536

@@ -91,6 +92,11 @@ void mp_asm_base_label_assign(mp_asm_base_t *as, size_t label) {
9192
} else {
9293
// ensure label offset has not changed from PASS_COMPUTE to PASS_EMIT
9394
assert(as->label_offsets[label] == as->code_offset);
95+
#if MICROPY_DYNAMIC_COMPILER && MICROPY_EMIT_NATIVE_DEBUG
96+
if (mp_dynamic_compiler.native_arch == MP_NATIVE_ARCH_DEBUG) {
97+
mp_printf(MICROPY_EMIT_NATIVE_DEBUG_PRINTER, "label(label_%u)\n", (unsigned int)label);
98+
}
99+
#endif
94100
}
95101
}
96102

py/compile.c

+3
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ static const emit_method_table_t *emit_native_table[] = {
103103
&emit_native_xtensa_method_table,
104104
&emit_native_xtensawin_method_table,
105105
&emit_native_rv32_method_table,
106+
&emit_native_debug_method_table,
106107
};
107108

108109
#elif MICROPY_EMIT_NATIVE
@@ -121,6 +122,8 @@ static const emit_method_table_t *emit_native_table[] = {
121122
#define NATIVE_EMITTER(f) emit_native_xtensawin_##f
122123
#elif MICROPY_EMIT_RV32
123124
#define NATIVE_EMITTER(f) emit_native_rv32_##f
125+
#elif MICROPY_EMIT_NATIVE_DEBUG
126+
#define NATIVE_EMITTER(f) emit_native_debug_##f
124127
#else
125128
#error "unknown native emitter"
126129
#endif

py/emit.h

+3
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ extern const emit_method_table_t emit_native_arm_method_table;
202202
extern const emit_method_table_t emit_native_xtensa_method_table;
203203
extern const emit_method_table_t emit_native_xtensawin_method_table;
204204
extern const emit_method_table_t emit_native_rv32_method_table;
205+
extern const emit_method_table_t emit_native_debug_method_table;
205206

206207
extern const mp_emit_method_table_id_ops_t mp_emit_bc_method_table_load_id_ops;
207208
extern const mp_emit_method_table_id_ops_t mp_emit_bc_method_table_store_id_ops;
@@ -215,6 +216,7 @@ emit_t *emit_native_arm_new(mp_emit_common_t *emit_common, mp_obj_t *error_slot,
215216
emit_t *emit_native_xtensa_new(mp_emit_common_t *emit_common, mp_obj_t *error_slot, uint *label_slot, mp_uint_t max_num_labels);
216217
emit_t *emit_native_xtensawin_new(mp_emit_common_t *emit_common, mp_obj_t *error_slot, uint *label_slot, mp_uint_t max_num_labels);
217218
emit_t *emit_native_rv32_new(mp_emit_common_t *emit_common, mp_obj_t *error_slot, uint *label_slot, mp_uint_t max_num_labels);
219+
emit_t *emit_native_debug_new(mp_emit_common_t *emit_common, mp_obj_t *error_slot, uint *label_slot, mp_uint_t max_num_labels);
218220

219221
void emit_bc_set_max_num_labels(emit_t *emit, mp_uint_t max_num_labels);
220222

@@ -226,6 +228,7 @@ void emit_native_arm_free(emit_t *emit);
226228
void emit_native_xtensa_free(emit_t *emit);
227229
void emit_native_xtensawin_free(emit_t *emit);
228230
void emit_native_rv32_free(emit_t *emit);
231+
void emit_native_debug_free(emit_t *emit);
229232

230233
void mp_emit_bc_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope);
231234
bool mp_emit_bc_end_pass(emit_t *emit);

py/emitnative.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
#endif
6060

6161
// wrapper around everything in this file
62-
#if N_X64 || N_X86 || N_THUMB || N_ARM || N_XTENSA || N_XTENSAWIN || N_RV32
62+
#if N_X64 || N_X86 || N_THUMB || N_ARM || N_XTENSA || N_XTENSAWIN || N_RV32 || N_DEBUG
6363

6464
// C stack layout for native functions:
6565
// 0: nlr_buf_t [optional]
@@ -348,6 +348,8 @@ static void emit_native_mov_reg_state_addr(emit_t *emit, int reg_dest, int local
348348
static void emit_native_mov_reg_qstr(emit_t *emit, int arg_reg, qstr qst) {
349349
#if MICROPY_PERSISTENT_CODE_SAVE
350350
ASM_LOAD16_REG_REG_OFFSET(emit->as, arg_reg, REG_QSTR_TABLE, mp_emit_common_use_qstr(emit->emit_common, qst));
351+
#elif defined(ASM_MOV_REG_QSTR)
352+
ASM_MOV_REG_QSTR(emit->as, arg_reg, qst);
351353
#else
352354
ASM_MOV_REG_IMM(emit->as, arg_reg, qst);
353355
#endif
@@ -2604,6 +2606,8 @@ static void emit_native_binary_op(emit_t *emit, mp_binary_op_t op) {
26042606
default:
26052607
break;
26062608
}
2609+
#elif N_DEBUG
2610+
asm_debug_setcc_reg_reg_reg(emit->as, op_idx, REG_RET, REG_ARG_2, reg_rhs);
26072611
#else
26082612
#error not implemented
26092613
#endif

0 commit comments

Comments
 (0)