Skip to content

Commit 65f01cb

Browse files
committed
py/ports/amiga: Wire 68k native emitter into build and fix big-endian n_state.
- py/mpconfig.h, py/emit.h, py/compile.c: add MICROPY_EMIT_68K option and hook it into the emitter dispatch alongside existing architectures. - py/py.mk: include emit68k.c in the build when MICROPY_EMIT_68K is set. - py/persistentcode.h: add MP_NATIVE_ARCH_68K enum value. - py/emitnative.c: add N_68K guards for big-endian n_state initialisation (shift value left 16 bits so the uint16_t lands in the correct bytes of the code_state word), 68k register-local table (D7 only; A2/A3 are address registers and cannot hold arithmetic locals), and Scc-based comparison sequences for the binary-op path. - ports/amiga/mpconfigport.h: set MICROPY_EMIT_68K=1 and keep MICROPY_PERSISTENT_CODE_LOAD_NATIVE=0 (loading pre-compiled native .mpy files is not yet supported).
1 parent 42beaae commit 65f01cb

7 files changed

Lines changed: 63 additions & 3 deletions

File tree

ports/amiga/mpconfigport.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@
4646
// Scheduler is used by asyncio and ussl callbacks; disable for now.
4747
#define MICROPY_ENABLE_SCHEDULER (0)
4848

49+
// Native code emitter for Motorola 68020
50+
#define MICROPY_EMIT_68K (1)
51+
// Loading pre-compiled native .mpy files is not yet supported on this port.
52+
#define MICROPY_PERSISTENT_CODE_LOAD_NATIVE (0)
53+
4954
// Amiga-specific module
5055
#define MICROPY_PY_AMIGA (1)
5156

py/compile.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ static const emit_method_table_t *emit_native_table[] = {
123123
#define NATIVE_EMITTER(f) emit_native_xtensawin_##f
124124
#elif MICROPY_EMIT_RV32
125125
#define NATIVE_EMITTER(f) emit_native_rv32_##f
126+
#elif MICROPY_EMIT_68K
127+
#define NATIVE_EMITTER(f) emit_native_68k_##f
126128
#elif MICROPY_EMIT_NATIVE_DEBUG
127129
#define NATIVE_EMITTER(f) emit_native_debug_##f
128130
#else

py/emit.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ extern const emit_method_table_t emit_native_arm_method_table;
205205
extern const emit_method_table_t emit_native_xtensa_method_table;
206206
extern const emit_method_table_t emit_native_xtensawin_method_table;
207207
extern const emit_method_table_t emit_native_rv32_method_table;
208+
extern const emit_method_table_t emit_native_68k_method_table;
208209
extern const emit_method_table_t emit_native_debug_method_table;
209210

210211
extern const mp_emit_method_table_id_ops_t mp_emit_bc_method_table_load_id_ops;

py/emitnative.c

Lines changed: 49 additions & 2 deletions
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 || N_DEBUG
62+
#if N_X64 || N_X86 || N_THUMB || N_ARM || N_XTENSA || N_XTENSAWIN || N_RV32 || N_68K || N_DEBUG
6363

6464
// C stack layout for native functions:
6565
// 0: nlr_buf_t [optional]
@@ -147,7 +147,21 @@
147147
#define LOCAL_IDX_GEN_PC(emit) ((emit)->code_state_start + OFFSETOF_CODE_STATE_IP)
148148
#define LOCAL_IDX_LOCAL_VAR(emit, local_num) ((emit)->stack_start + (emit)->n_state - 1 - (local_num))
149149

150+
#if N_68K
151+
152+
// 68k: REG_LOCAL_1=D7 is the only data register safe for cached locals.
153+
// REG_LOCAL_2=A2 and REG_LOCAL_3=A3 are address registers; emitnative.c
154+
// may apply arithmetic to local-variable registers, which is invalid on An.
150155
#if MICROPY_PERSISTENT_CODE_SAVE
156+
#define REG_GENERATOR_STATE (REG_LOCAL_2)
157+
#define REG_QSTR_TABLE (REG_LOCAL_3)
158+
#else
159+
#define REG_GENERATOR_STATE (REG_LOCAL_2)
160+
#endif
161+
#define MAX_REGS_FOR_LOCAL_VARS (1)
162+
static const uint8_t reg_local_table[MAX_REGS_FOR_LOCAL_VARS] = {REG_LOCAL_1};
163+
164+
#elif MICROPY_PERSISTENT_CODE_SAVE
151165

152166
// When building with the ability to save native code to .mpy files:
153167
// - Qstrs are indirect via qstr_table, and REG_LOCAL_3 always points to qstr_table.
@@ -625,8 +639,16 @@ static void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop
625639
// Set code_state.fun_bc
626640
ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_FUN_OBJ(emit), REG_PARENT_ARG_1);
627641

628-
// Set code_state.n_state (only works on little endian targets due to n_state being uint16_t)
642+
// Set code_state.n_state.
643+
// n_state is a uint16_t, but the emitter writes a full uintptr_t-sized slot.
644+
// On little-endian the value naturally lands in the correct bytes.
645+
// On big-endian (N_68K) the uint16_t occupies the upper half of the word,
646+
// so shift the value left by 16 to place it in the correct byte positions.
647+
#if N_68K
648+
emit_native_mov_state_imm_via(emit, emit->code_state_start + OFFSETOF_CODE_STATE_N_STATE, (mp_uint_t)emit->n_state << 16, REG_ARG_1);
649+
#else
629650
emit_native_mov_state_imm_via(emit, emit->code_state_start + OFFSETOF_CODE_STATE_N_STATE, emit->n_state, REG_ARG_1);
651+
#endif
630652

631653
// Put address of code_state into first arg
632654
ASM_MOV_REG_LOCAL_ADDR(emit->as, REG_ARG_1, emit->code_state_start);
@@ -2624,6 +2646,31 @@ static void emit_native_binary_op(emit_t *emit, mp_binary_op_t op) {
26242646
default:
26252647
break;
26262648
}
2649+
#elif N_68K
2650+
// CMP.L reg_rhs, REG_ARG_2 → sets flags for REG_ARG_2 - reg_rhs.
2651+
// Scc REG_RET sets byte to 0xFF (true) or 0x00 (false).
2652+
// ANDI.L #1 extracts the boolean into bits 31:0 of REG_RET.
2653+
{
2654+
static const uint8_t ops[6 + 6] = {
2655+
// unsigned (CMP: REG_ARG_2 - reg_rhs)
2656+
ASM_68K_CC_CS, // LESS (carry set = below)
2657+
ASM_68K_CC_HI, // MORE (above)
2658+
ASM_68K_CC_EQ, // EQUAL
2659+
ASM_68K_CC_LS, // LESS_EQUAL (below or same)
2660+
ASM_68K_CC_CC, // MORE_EQUAL (carry clear = above or same)
2661+
ASM_68K_CC_NE, // NOT_EQUAL
2662+
// signed
2663+
ASM_68K_CC_LT, // LESS
2664+
ASM_68K_CC_GT, // MORE
2665+
ASM_68K_CC_EQ, // EQUAL
2666+
ASM_68K_CC_LE, // LESS_EQUAL
2667+
ASM_68K_CC_GE, // MORE_EQUAL
2668+
ASM_68K_CC_NE, // NOT_EQUAL
2669+
};
2670+
asm_68k_cmp_reg_reg(emit->as, REG_ARG_2, reg_rhs);
2671+
asm_68k_scc_dreg(emit->as, ops[op_idx], REG_RET);
2672+
asm_68k_andi_l(emit->as, REG_RET, 1);
2673+
}
26272674
#elif N_DEBUG
26282675
asm_debug_setcc_reg_reg_reg(emit->as, op_idx, REG_RET, REG_ARG_2, reg_rhs);
26292676
#else

py/mpconfig.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,7 @@ typedef uint64_t mp_uint_t;
536536
#endif
537537

538538
// Convenience definition for whether any native emitter is enabled
539-
#define MICROPY_EMIT_NATIVE (MICROPY_EMIT_X64 || MICROPY_EMIT_X86 || MICROPY_EMIT_THUMB || MICROPY_EMIT_ARM || MICROPY_EMIT_XTENSA || MICROPY_EMIT_XTENSAWIN || MICROPY_EMIT_RV32 || MICROPY_EMIT_NATIVE_DEBUG)
539+
#define MICROPY_EMIT_NATIVE (MICROPY_EMIT_X64 || MICROPY_EMIT_X86 || MICROPY_EMIT_THUMB || MICROPY_EMIT_ARM || MICROPY_EMIT_XTENSA || MICROPY_EMIT_XTENSAWIN || MICROPY_EMIT_RV32 || MICROPY_EMIT_68K || MICROPY_EMIT_NATIVE_DEBUG)
540540

541541
// Some architectures cannot read byte-wise from executable memory. In this case
542542
// the prelude for a native function (which usually sits after the machine code)

py/persistentcode.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@
8383
#else
8484
#error "Unsupported RISC-V architecture."
8585
#endif
86+
#elif defined(__mc68020__) || defined(__m68k__)
87+
#define MPY_FEATURE_ARCH (MP_NATIVE_ARCH_68K)
8688
#else
8789
#error "Unsupported native architecture."
8890
#endif
@@ -116,6 +118,7 @@ enum {
116118
MP_NATIVE_ARCH_XTENSAWIN,
117119
MP_NATIVE_ARCH_RV32IMC,
118120
MP_NATIVE_ARCH_RV64IMC,
121+
MP_NATIVE_ARCH_68K,
119122
MP_NATIVE_ARCH_DEBUG, // this entry should always be last
120123
};
121124

py/py.mk

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ PY_CORE_O_BASENAME = $(addprefix py/,\
126126
asmrv32.o \
127127
emitnrv32.o \
128128
emitinlinerv32.o \
129+
asm68k.o \
130+
emit68k.o \
129131
emitndebug.o \
130132
formatfloat.o \
131133
parsenumbase.o \

0 commit comments

Comments
 (0)