|
140 | 140 | #define ASM_SUB_REG_REG(as, reg_dest, reg_src) asm_x64_sub_r64_r64((as), (reg_dest), (reg_src)) |
141 | 141 |
|
142 | 142 | #define ASM_LOAD_REG_REG(as, reg_dest, reg_base) asm_x64_mov_mem64_to_r64((as), (reg_base), 0, (reg_dest)) |
| 143 | +#define ASM_LOAD_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) asm_x64_mov_mem64_to_r64((as), (reg_base), 8 * (word_offset), (reg_dest)) |
143 | 144 | #define ASM_LOAD8_REG_REG(as, reg_dest, reg_base) asm_x64_mov_mem8_to_r64zx((as), (reg_base), 0, (reg_dest)) |
144 | 145 | #define ASM_LOAD16_REG_REG(as, reg_dest, reg_base) asm_x64_mov_mem16_to_r64zx((as), (reg_base), 0, (reg_dest)) |
145 | 146 |
|
146 | 147 | #define ASM_STORE_REG_REG(as, reg_src, reg_base) asm_x64_mov_r64_to_mem64((as), (reg_src), (reg_base), 0) |
| 148 | +#define ASM_STORE_REG_REG_OFFSET(as, reg_src, reg_base, word_offset) asm_x64_mov_r64_to_mem64((as), (reg_src), (reg_base), 8 * (word_offset)) |
147 | 149 | #define ASM_STORE8_REG_REG(as, reg_src, reg_base) asm_x64_mov_r8_to_mem8((as), (reg_src), (reg_base), 0) |
148 | 150 | #define ASM_STORE16_REG_REG(as, reg_src, reg_base) asm_x64_mov_r16_to_mem16((as), (reg_src), (reg_base), 0) |
149 | 151 |
|
@@ -353,10 +355,12 @@ STATIC byte mp_f_n_args[MP_F_NUMBER_OF] = { |
353 | 355 | #define ASM_SUB_REG_REG(as, reg_dest, reg_src) asm_thumb_sub_rlo_rlo_rlo((as), (reg_dest), (reg_dest), (reg_src)) |
354 | 356 |
|
355 | 357 | #define ASM_LOAD_REG_REG(as, reg_dest, reg_base) asm_thumb_ldr_rlo_rlo_i5((as), (reg_dest), (reg_base), 0) |
| 358 | +#define ASM_LOAD_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) asm_thumb_ldr_rlo_rlo_i5((as), (reg_dest), (reg_base), (word_offset)) |
356 | 359 | #define ASM_LOAD8_REG_REG(as, reg_dest, reg_base) asm_thumb_ldrb_rlo_rlo_i5((as), (reg_dest), (reg_base), 0) |
357 | 360 | #define ASM_LOAD16_REG_REG(as, reg_dest, reg_base) asm_thumb_ldrh_rlo_rlo_i5((as), (reg_dest), (reg_base), 0) |
358 | 361 |
|
359 | 362 | #define ASM_STORE_REG_REG(as, reg_src, reg_base) asm_thumb_str_rlo_rlo_i5((as), (reg_src), (reg_base), 0) |
| 363 | +#define ASM_STORE_REG_REG_OFFSET(as, reg_src, reg_base, word_offset) asm_thumb_str_rlo_rlo_i5((as), (reg_src), (reg_base), (word_offset)) |
360 | 364 | #define ASM_STORE8_REG_REG(as, reg_src, reg_base) asm_thumb_strb_rlo_rlo_i5((as), (reg_src), (reg_base), 0) |
361 | 365 | #define ASM_STORE16_REG_REG(as, reg_src, reg_base) asm_thumb_strh_rlo_rlo_i5((as), (reg_src), (reg_base), 0) |
362 | 366 |
|
@@ -547,6 +551,8 @@ STATIC void emit_native_set_native_type(emit_t *emit, mp_uint_t op, mp_uint_t ar |
547 | 551 | } |
548 | 552 | } |
549 | 553 |
|
| 554 | +STATIC void emit_post_push_reg(emit_t *emit, vtype_kind_t vtype, int reg); |
| 555 | +STATIC void emit_native_store_fast(emit_t *emit, qstr qst, mp_uint_t local_num); |
550 | 556 | STATIC void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) { |
551 | 557 | DEBUG_printf("start_pass(pass=%u, scope=%p)\n", pass, scope); |
552 | 558 |
|
@@ -669,6 +675,16 @@ STATIC void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop |
669 | 675 | #else |
670 | 676 | #error not implemented |
671 | 677 | #endif |
| 678 | + |
| 679 | + // initialise closed over variables |
| 680 | + for (int i = 0; i < scope->id_info_len; i++) { |
| 681 | + id_info_t *id = &scope->id_info[i]; |
| 682 | + if (id->kind == ID_INFO_KIND_CELL) { |
| 683 | + ASM_CALL_IND(emit->as, mp_fun_table[MP_F_NEW_CELL], MP_F_NEW_CELL); |
| 684 | + emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); |
| 685 | + emit_native_store_fast(emit, id->qst, id->local_num); |
| 686 | + } |
| 687 | + } |
672 | 688 | } |
673 | 689 |
|
674 | 690 | STATIC void emit_native_end_pass(emit_t *emit) { |
@@ -1224,12 +1240,15 @@ STATIC void emit_native_load_fast(emit_t *emit, qstr qst, mp_uint_t local_num) { |
1224 | 1240 | } |
1225 | 1241 |
|
1226 | 1242 | STATIC void emit_native_load_deref(emit_t *emit, qstr qst, mp_uint_t local_num) { |
1227 | | - // not implemented |
1228 | | - // in principle could support this quite easily (ldr r0, [r0, #0]) and then get closed over variables! |
1229 | | - (void)emit; |
1230 | | - (void)qst; |
1231 | | - (void)local_num; |
1232 | | - assert(0); |
| 1243 | + DEBUG_printf("load_deref(%s, " UINT_FMT ")\n", qstr_str(qst), local_num); |
| 1244 | + need_reg_single(emit, REG_RET, 0); |
| 1245 | + emit_native_load_fast(emit, qst, local_num); |
| 1246 | + vtype_kind_t vtype; |
| 1247 | + int reg_base = REG_RET; |
| 1248 | + emit_pre_pop_reg_flexible(emit, &vtype, ®_base, -1, -1); |
| 1249 | + ASM_LOAD_REG_REG_OFFSET(emit->as, REG_RET, reg_base, 1); |
| 1250 | + // closed over vars are always Python objects |
| 1251 | + emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); |
1233 | 1252 | } |
1234 | 1253 |
|
1235 | 1254 | STATIC void emit_native_load_name(emit_t *emit, qstr qst) { |
@@ -1446,11 +1465,17 @@ STATIC void emit_native_store_fast(emit_t *emit, qstr qst, mp_uint_t local_num) |
1446 | 1465 | } |
1447 | 1466 |
|
1448 | 1467 | STATIC void emit_native_store_deref(emit_t *emit, qstr qst, mp_uint_t local_num) { |
1449 | | - // not implemented |
1450 | | - (void)emit; |
1451 | | - (void)qst; |
1452 | | - (void)local_num; |
1453 | | - assert(0); |
| 1468 | + DEBUG_printf("store_deref(%s, " UINT_FMT ")\n", qstr_str(qst), local_num); |
| 1469 | + need_reg_single(emit, REG_TEMP0, 0); |
| 1470 | + need_reg_single(emit, REG_TEMP1, 0); |
| 1471 | + emit_native_load_fast(emit, qst, local_num); |
| 1472 | + vtype_kind_t vtype; |
| 1473 | + int reg_base = REG_TEMP0; |
| 1474 | + emit_pre_pop_reg_flexible(emit, &vtype, ®_base, -1, -1); |
| 1475 | + int reg_src = REG_TEMP1; |
| 1476 | + emit_pre_pop_reg_flexible(emit, &vtype, ®_src, reg_base, reg_base); |
| 1477 | + ASM_STORE_REG_REG_OFFSET(emit->as, reg_src, reg_base, 1); |
| 1478 | + emit_post(emit); |
1454 | 1479 | } |
1455 | 1480 |
|
1456 | 1481 | STATIC void emit_native_store_name(emit_t *emit, qstr qst) { |
@@ -2133,12 +2158,17 @@ STATIC void emit_native_make_function(emit_t *emit, scope_t *scope, mp_uint_t n_ |
2133 | 2158 | } |
2134 | 2159 |
|
2135 | 2160 | STATIC void emit_native_make_closure(emit_t *emit, scope_t *scope, mp_uint_t n_closed_over, mp_uint_t n_pos_defaults, mp_uint_t n_kw_defaults) { |
2136 | | - (void)emit; |
2137 | | - (void)scope; |
2138 | | - (void)n_closed_over; |
2139 | | - (void)n_pos_defaults; |
2140 | | - (void)n_kw_defaults; |
2141 | | - assert(0); |
| 2161 | + emit_native_pre(emit); |
| 2162 | + if (n_pos_defaults == 0 && n_kw_defaults == 0) { |
| 2163 | + emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_3, n_closed_over); |
| 2164 | + ASM_MOV_IMM_TO_REG(emit->as, n_closed_over, REG_ARG_2); |
| 2165 | + } else { |
| 2166 | + emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_3, n_closed_over + 2); |
| 2167 | + ASM_MOV_IMM_TO_REG(emit->as, 0x100 | n_closed_over, REG_ARG_2); |
| 2168 | + } |
| 2169 | + ASM_MOV_ALIGNED_IMM_TO_REG(emit->as, (mp_uint_t)scope->raw_code, REG_ARG_1); |
| 2170 | + ASM_CALL_IND(emit->as, mp_fun_table[MP_F_MAKE_CLOSURE_FROM_RAW_CODE], MP_F_MAKE_CLOSURE_FROM_RAW_CODE); |
| 2171 | + emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); |
2142 | 2172 | } |
2143 | 2173 |
|
2144 | 2174 | STATIC void emit_native_call_function(emit_t *emit, mp_uint_t n_positional, mp_uint_t n_keyword, mp_uint_t star_flags) { |
|
0 commit comments