94
94
#define OFFSETOF_OBJ_FUN_BC_GLOBALS (offsetof(mp_obj_fun_bc_t, globals) / sizeof(uintptr_t))
95
95
#define OFFSETOF_OBJ_FUN_BC_CONST_TABLE (offsetof(mp_obj_fun_bc_t, const_table) / sizeof(uintptr_t))
96
96
97
+ // If not already defined, set parent args to same as child call registers
98
+ #ifndef REG_PARENT_RET
99
+ #define REG_PARENT_RET REG_RET
100
+ #define REG_PARENT_ARG_1 REG_ARG_1
101
+ #define REG_PARENT_ARG_2 REG_ARG_2
102
+ #define REG_PARENT_ARG_3 REG_ARG_3
103
+ #define REG_PARENT_ARG_4 REG_ARG_4
104
+ #endif
105
+
97
106
// Word index of nlr_buf_t.ret_val
98
107
#define NLR_BUF_IDX_RET_VAL (1)
99
108
@@ -413,16 +422,16 @@ STATIC void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop
413
422
ASM_ENTRY (emit -> as , emit -> stack_start + emit -> n_state - num_locals_in_regs );
414
423
415
424
#if N_X86
416
- asm_x86_mov_arg_to_r32 (emit -> as , 0 , REG_ARG_1 );
425
+ asm_x86_mov_arg_to_r32 (emit -> as , 0 , REG_PARENT_ARG_1 );
417
426
#endif
418
427
419
428
// Load REG_FUN_TABLE with a pointer to mp_fun_table, found in the const_table
420
- ASM_LOAD_REG_REG_OFFSET (emit -> as , REG_LOCAL_3 , REG_ARG_1 , OFFSETOF_OBJ_FUN_BC_CONST_TABLE );
429
+ ASM_LOAD_REG_REG_OFFSET (emit -> as , REG_LOCAL_3 , REG_PARENT_ARG_1 , OFFSETOF_OBJ_FUN_BC_CONST_TABLE );
421
430
ASM_LOAD_REG_REG_OFFSET (emit -> as , REG_FUN_TABLE , REG_LOCAL_3 , 0 );
422
431
423
432
// Store function object (passed as first arg) to stack if needed
424
433
if (NEED_FUN_OBJ (emit )) {
425
- ASM_MOV_LOCAL_REG (emit -> as , LOCAL_IDX_FUN_OBJ (emit ), REG_ARG_1 );
434
+ ASM_MOV_LOCAL_REG (emit -> as , LOCAL_IDX_FUN_OBJ (emit ), REG_PARENT_ARG_1 );
426
435
}
427
436
428
437
// Put n_args in REG_ARG_1, n_kw in REG_ARG_2, args array in REG_LOCAL_3
@@ -431,9 +440,9 @@ STATIC void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop
431
440
asm_x86_mov_arg_to_r32 (emit -> as , 2 , REG_ARG_2 );
432
441
asm_x86_mov_arg_to_r32 (emit -> as , 3 , REG_LOCAL_3 );
433
442
#else
434
- ASM_MOV_REG_REG (emit -> as , REG_ARG_1 , REG_ARG_2 );
435
- ASM_MOV_REG_REG (emit -> as , REG_ARG_2 , REG_ARG_3 );
436
- ASM_MOV_REG_REG (emit -> as , REG_LOCAL_3 , REG_ARG_4 );
443
+ ASM_MOV_REG_REG (emit -> as , REG_ARG_1 , REG_PARENT_ARG_2 );
444
+ ASM_MOV_REG_REG (emit -> as , REG_ARG_2 , REG_PARENT_ARG_3 );
445
+ ASM_MOV_REG_REG (emit -> as , REG_LOCAL_3 , REG_PARENT_ARG_4 );
437
446
#endif
438
447
439
448
// Check number of args matches this function, and call mp_arg_check_num_sig if not
@@ -482,14 +491,14 @@ STATIC void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop
482
491
#if N_X86
483
492
asm_x86_mov_arg_to_r32 (emit -> as , 0 , REG_GENERATOR_STATE );
484
493
#else
485
- ASM_MOV_REG_REG (emit -> as , REG_GENERATOR_STATE , REG_ARG_1 );
494
+ ASM_MOV_REG_REG (emit -> as , REG_GENERATOR_STATE , REG_PARENT_ARG_1 );
486
495
#endif
487
496
488
497
// Put throw value into LOCAL_IDX_EXC_VAL slot, for yield/yield-from
489
498
#if N_X86
490
- asm_x86_mov_arg_to_r32 (emit -> as , 1 , REG_ARG_2 );
499
+ asm_x86_mov_arg_to_r32 (emit -> as , 1 , REG_PARENT_ARG_2 );
491
500
#endif
492
- ASM_MOV_LOCAL_REG (emit -> as , LOCAL_IDX_EXC_VAL (emit ), REG_ARG_2 );
501
+ ASM_MOV_LOCAL_REG (emit -> as , LOCAL_IDX_EXC_VAL (emit ), REG_PARENT_ARG_2 );
493
502
494
503
// Load REG_FUN_TABLE with a pointer to mp_fun_table, found in the const_table
495
504
ASM_LOAD_REG_REG_OFFSET (emit -> as , REG_TEMP0 , REG_GENERATOR_STATE , LOCAL_IDX_FUN_OBJ (emit ));
@@ -505,29 +514,40 @@ STATIC void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop
505
514
// Prepare incoming arguments for call to mp_setup_code_state
506
515
507
516
#if N_X86
508
- asm_x86_mov_arg_to_r32 (emit -> as , 0 , REG_ARG_1 );
509
- asm_x86_mov_arg_to_r32 (emit -> as , 1 , REG_ARG_2 );
510
- asm_x86_mov_arg_to_r32 (emit -> as , 2 , REG_ARG_3 );
511
- asm_x86_mov_arg_to_r32 (emit -> as , 3 , REG_ARG_4 );
517
+ asm_x86_mov_arg_to_r32 (emit -> as , 0 , REG_PARENT_ARG_1 );
518
+ asm_x86_mov_arg_to_r32 (emit -> as , 1 , REG_PARENT_ARG_2 );
519
+ asm_x86_mov_arg_to_r32 (emit -> as , 2 , REG_PARENT_ARG_3 );
520
+ asm_x86_mov_arg_to_r32 (emit -> as , 3 , REG_PARENT_ARG_4 );
512
521
#endif
513
522
514
523
// Load REG_FUN_TABLE with a pointer to mp_fun_table, found in the const_table
515
- ASM_LOAD_REG_REG_OFFSET (emit -> as , REG_LOCAL_3 , REG_ARG_1 , OFFSETOF_OBJ_FUN_BC_CONST_TABLE );
524
+ ASM_LOAD_REG_REG_OFFSET (emit -> as , REG_LOCAL_3 , REG_PARENT_ARG_1 , OFFSETOF_OBJ_FUN_BC_CONST_TABLE );
516
525
ASM_LOAD_REG_REG_OFFSET (emit -> as , REG_FUN_TABLE , REG_LOCAL_3 , emit -> scope -> num_pos_args + emit -> scope -> num_kwonly_args );
517
526
518
527
// Set code_state.fun_bc
519
- ASM_MOV_LOCAL_REG (emit -> as , LOCAL_IDX_FUN_OBJ (emit ), REG_ARG_1 );
528
+ ASM_MOV_LOCAL_REG (emit -> as , LOCAL_IDX_FUN_OBJ (emit ), REG_PARENT_ARG_1 );
520
529
521
530
// Set code_state.ip (offset from start of this function to prelude info)
522
531
// TODO this encoding may change size in the final pass, need to make it fixed
523
- emit_native_mov_state_imm_via (emit , emit -> code_state_start + OFFSETOF_CODE_STATE_IP , emit -> prelude_offset , REG_ARG_1 );
532
+ emit_native_mov_state_imm_via (emit , emit -> code_state_start + OFFSETOF_CODE_STATE_IP , emit -> prelude_offset , REG_PARENT_ARG_1 );
524
533
525
534
// Set code_state.n_state (only works on little endian targets due to n_state being uint16_t)
526
535
emit_native_mov_state_imm_via (emit , emit -> code_state_start + offsetof(mp_code_state_t , n_state ) / sizeof (uintptr_t ), emit -> n_state , REG_ARG_1 );
527
536
528
537
// Put address of code_state into first arg
529
538
ASM_MOV_REG_LOCAL_ADDR (emit -> as , REG_ARG_1 , emit -> code_state_start );
530
539
540
+ // Copy next 3 args if needed
541
+ #if REG_ARG_2 != REG_PARENT_ARG_2
542
+ ASM_MOV_REG_REG (emit -> as , REG_ARG_2 , REG_PARENT_ARG_2 );
543
+ #endif
544
+ #if REG_ARG_3 != REG_PARENT_ARG_3
545
+ ASM_MOV_REG_REG (emit -> as , REG_ARG_3 , REG_PARENT_ARG_3 );
546
+ #endif
547
+ #if REG_ARG_4 != REG_PARENT_ARG_4
548
+ ASM_MOV_REG_REG (emit -> as , REG_ARG_4 , REG_PARENT_ARG_4 );
549
+ #endif
550
+
531
551
// Call mp_setup_code_state to prepare code_state structure
532
552
#if N_THUMB
533
553
asm_thumb_bl_ind (emit -> as , MP_F_SETUP_CODE_STATE , ASM_THUMB_REG_R4 );
@@ -1174,7 +1194,7 @@ STATIC void emit_native_global_exc_entry(emit_t *emit) {
1174
1194
ASM_STORE_REG_REG_OFFSET (emit -> as , REG_TEMP0 , REG_GENERATOR_STATE , OFFSETOF_CODE_STATE_STATE );
1175
1195
1176
1196
// Load return kind
1177
- ASM_MOV_REG_IMM (emit -> as , REG_RET , MP_VM_RETURN_EXCEPTION );
1197
+ ASM_MOV_REG_IMM (emit -> as , REG_PARENT_RET , MP_VM_RETURN_EXCEPTION );
1178
1198
1179
1199
ASM_EXIT (emit -> as );
1180
1200
} else {
@@ -1229,7 +1249,7 @@ STATIC void emit_native_global_exc_exit(emit_t *emit) {
1229
1249
}
1230
1250
1231
1251
// Load return value
1232
- ASM_MOV_REG_LOCAL (emit -> as , REG_RET , LOCAL_IDX_RET_VAL (emit ));
1252
+ ASM_MOV_REG_LOCAL (emit -> as , REG_PARENT_RET , LOCAL_IDX_RET_VAL (emit ));
1233
1253
}
1234
1254
1235
1255
ASM_EXIT (emit -> as );
@@ -2617,13 +2637,13 @@ STATIC void emit_native_return_value(emit_t *emit) {
2617
2637
if (peek_vtype (emit , 0 ) == VTYPE_PTR_NONE ) {
2618
2638
emit_pre_pop_discard (emit );
2619
2639
if (return_vtype == VTYPE_PYOBJ ) {
2620
- emit_native_mov_reg_const (emit , REG_RET , MP_F_CONST_NONE_OBJ );
2640
+ emit_native_mov_reg_const (emit , REG_PARENT_RET , MP_F_CONST_NONE_OBJ );
2621
2641
} else {
2622
2642
ASM_MOV_REG_IMM (emit -> as , REG_ARG_1 , 0 );
2623
2643
}
2624
2644
} else {
2625
2645
vtype_kind_t vtype ;
2626
- emit_pre_pop_reg (emit , & vtype , return_vtype == VTYPE_PYOBJ ? REG_RET : REG_ARG_1 );
2646
+ emit_pre_pop_reg (emit , & vtype , return_vtype == VTYPE_PYOBJ ? REG_PARENT_RET : REG_ARG_1 );
2627
2647
if (vtype != return_vtype ) {
2628
2648
EMIT_NATIVE_VIPER_TYPE_ERROR (emit ,
2629
2649
"return expected '%q' but got '%q'" ,
@@ -2632,15 +2652,18 @@ STATIC void emit_native_return_value(emit_t *emit) {
2632
2652
}
2633
2653
if (return_vtype != VTYPE_PYOBJ ) {
2634
2654
emit_call_with_imm_arg (emit , MP_F_CONVERT_NATIVE_TO_OBJ , return_vtype , REG_ARG_2 );
2655
+ #if REG_RET != REG_PARENT_ARG_RET
2656
+ ASM_MOV_REG_REG (emit -> as , REG_PARENT_RET , REG_RET );
2657
+ #endif
2635
2658
}
2636
2659
} else {
2637
2660
vtype_kind_t vtype ;
2638
- emit_pre_pop_reg (emit , & vtype , REG_RET );
2661
+ emit_pre_pop_reg (emit , & vtype , REG_PARENT_RET );
2639
2662
assert (vtype == VTYPE_PYOBJ );
2640
2663
}
2641
2664
if (NEED_GLOBAL_EXC_HANDLER (emit )) {
2642
2665
// Save return value for the global exception handler to use
2643
- ASM_MOV_LOCAL_REG (emit -> as , LOCAL_IDX_RET_VAL (emit ), REG_RET );
2666
+ ASM_MOV_LOCAL_REG (emit -> as , LOCAL_IDX_RET_VAL (emit ), REG_PARENT_RET );
2644
2667
}
2645
2668
emit_native_unwind_jump (emit , emit -> exit_label , emit -> exc_stack_size );
2646
2669
emit -> last_emit_was_return_value = true;
0 commit comments