5959#define REG_TEMP2 (REG_RSI)
6060#define ASM_MOV_REG_TO_LOCAL (reg , local_num ) asm_x64_mov_r64_to_local(emit->as, (reg), (local_num))
6161#define ASM_MOV_IMM_TO_REG (imm , reg ) asm_x64_mov_i64_to_r64_optimised(emit->as, (imm), (reg))
62- #define ASM_MOV_IMM_TO_LOCAL (imm , local_num ) do { asm_x64_mov_i64_to_r64_optimised(emit->as, (imm), REG_RAX) ; asm_x64_mov_r64_to_local(emit->as, REG_RAX , (local_num)); } while (false)
62+ #define ASM_MOV_IMM_TO_LOCAL_USING (imm , local_num , reg_temp ) do { asm_x64_mov_i64_to_r64_optimised(emit->as, (imm), (reg_temp)) ; asm_x64_mov_r64_to_local(emit->as, (reg_temp) , (local_num)); } while (false)
6363#define ASM_MOV_LOCAL_TO_REG (local_num , reg ) asm_x64_mov_local_to_r64(emit->as, (local_num), (reg))
6464#define ASM_MOV_REG_TO_REG (reg_src , reg_dest ) asm_x64_mov_r64_to_r64(emit->as, (reg_src), (reg_dest))
6565#define ASM_MOV_LOCAL_ADDR_TO_REG (local_num , reg ) asm_x64_mov_local_addr_to_r64(emit->as, (local_num), (reg))
8282#define REG_TEMP2 (REG_R2)
8383#define ASM_MOV_REG_TO_LOCAL (reg , local_num ) asm_thumb_mov_local_reg(emit->as, (local_num), (reg))
8484#define ASM_MOV_IMM_TO_REG (imm , reg ) asm_thumb_mov_reg_i32_optimised(emit->as, (reg), (imm))
85- #define ASM_MOV_IMM_TO_LOCAL (imm , local_num ) do { asm_thumb_mov_reg_i32_optimised(emit->as, REG_R0 , (imm)); asm_thumb_mov_local_reg(emit->as, (local_num), REG_R0 ); } while (false)
85+ #define ASM_MOV_IMM_TO_LOCAL_USING (imm , local_num , reg_temp ) do { asm_thumb_mov_reg_i32_optimised(emit->as, (reg_temp) , (imm)); asm_thumb_mov_local_reg(emit->as, (local_num), (reg_temp) ); } while (false)
8686#define ASM_MOV_LOCAL_TO_REG (local_num , reg ) asm_thumb_mov_reg_local(emit->as, (reg), (local_num))
8787#define ASM_MOV_REG_TO_REG (reg_src , reg_dest ) asm_thumb_mov_reg_reg(emit->as, (reg_dest), (reg_src))
8888#define ASM_MOV_LOCAL_ADDR_TO_REG (local_num , reg ) asm_thumb_mov_reg_local_addr(emit->as, (reg), (local_num))
@@ -344,22 +344,14 @@ static void need_reg_single(emit_t *emit, int reg_needed) {
344344 }
345345}
346346
347- static void need_reg_all (emit_t * emit , int num_stack_top_that_must_be_value ) {
347+ static void need_reg_all (emit_t * emit ) {
348348 for (int i = 0 ; i < emit -> stack_size ; i ++ ) {
349349 stack_info_t * si = & emit -> stack_info [i ];
350350 if (si -> kind == STACK_REG ) {
351351 si -> kind = STACK_VALUE ;
352352 ASM_MOV_REG_TO_LOCAL (si -> u_reg , emit -> stack_start + i );
353353 }
354354 }
355- // must do this after making all registers available because ASM_MOV_IMM_TO_LOCAL uses a temporary register
356- for (int i = 0 ; i < num_stack_top_that_must_be_value ; i ++ ) {
357- stack_info_t * si = & emit -> stack_info [emit -> stack_size - 1 - i ];
358- if (si -> kind == STACK_IMM ) {
359- si -> kind = STACK_VALUE ;
360- ASM_MOV_IMM_TO_LOCAL (si -> u_imm , emit -> stack_start + emit -> stack_size - 1 - i );
361- }
362- }
363355}
364356
365357static void emit_pre_pop_reg (emit_t * emit , vtype_kind_t * vtype , int reg_dest ) {
@@ -434,19 +426,26 @@ static void emit_post_push_reg_reg_reg_reg(emit_t *emit, vtype_kind_t vtypea, in
434426}
435427
436428// vtype of all n_pop objects is VTYPE_PYOBJ
429+ // does not use any temporary registers (but may use reg_dest before loading it with stack pointer)
437430static void emit_get_stack_pointer_to_reg_for_pop (emit_t * emit , int reg_dest , int n_pop ) {
438- need_reg_all (emit , n_pop );
431+ need_reg_all (emit );
439432 for (int i = 0 ; i < n_pop ; i ++ ) {
440- assert (emit -> stack_info [emit -> stack_size - 1 - i ].kind == STACK_VALUE );
441- assert (emit -> stack_info [emit -> stack_size - 1 - i ].vtype == VTYPE_PYOBJ );
433+ stack_info_t * si = & emit -> stack_info [emit -> stack_size - 1 - i ];
434+ // must push any imm's to stack
435+ if (si -> kind == STACK_IMM ) {
436+ si -> kind = STACK_VALUE ;
437+ ASM_MOV_IMM_TO_LOCAL_USING (si -> u_imm , emit -> stack_start + emit -> stack_size - 1 - i , reg_dest );
438+ }
439+ assert (si -> kind == STACK_VALUE );
440+ assert (si -> vtype == VTYPE_PYOBJ );
442441 }
443442 ASM_MOV_LOCAL_ADDR_TO_REG (emit -> stack_start + emit -> stack_size - 1 , reg_dest );
444443 adjust_stack (emit , - n_pop );
445444}
446445
447446// vtype of all n_push objects is VTYPE_PYOBJ
448447static void emit_get_stack_pointer_to_reg_for_push (emit_t * emit , int reg_dest , int n_push ) {
449- need_reg_all (emit , 0 );
448+ need_reg_all (emit );
450449 for (int i = 0 ; i < n_push ; i ++ ) {
451450 emit -> stack_info [emit -> stack_size + i ].kind = STACK_VALUE ;
452451 emit -> stack_info [emit -> stack_size + i ].vtype = VTYPE_PYOBJ ;
@@ -464,7 +463,7 @@ static void emit_call(emit_t *emit, rt_fun_kind_t fun_kind, void *fun) {
464463}
465464
466465static void emit_call_with_imm_arg (emit_t * emit , rt_fun_kind_t fun_kind , void * fun , machine_int_t arg_val , int arg_reg ) {
467- need_reg_all (emit , 0 );
466+ need_reg_all (emit );
468467 ASM_MOV_IMM_TO_REG (arg_val , arg_reg );
469468 emit_call (emit , fun_kind , fun );
470469}
@@ -1049,6 +1048,7 @@ static void emit_native_make_closure(emit_t *emit, scope_t *scope, int n_dict_pa
10491048static void emit_native_call_function (emit_t * emit , int n_positional , int n_keyword , bool have_star_arg , bool have_dbl_star_arg ) {
10501049 // call special viper runtime routine with type info for args, and wanted type info for return
10511050 assert (n_keyword == 0 && !have_star_arg && !have_dbl_star_arg );
1051+ /*
10521052 if (n_positional == 0) {
10531053 vtype_kind_t vtype_fun;
10541054 emit_pre_pop_reg(emit, &vtype_fun, REG_ARG_1); // the function
@@ -1068,13 +1068,22 @@ static void emit_native_call_function(emit_t *emit, int n_positional, int n_keyw
10681068 assert(vtype_arg2 == VTYPE_PYOBJ);
10691069 emit_call(emit, RT_F_CALL_FUNCTION_2, rt_call_function_2);
10701070 } else {
1071- assert (0 );
1072- }
1071+ */
1072+ emit_pre (emit );
1073+ if (n_positional != 0 ) {
1074+ emit_get_stack_pointer_to_reg_for_pop (emit , REG_ARG_3 , n_positional ); // pointer to args in reverse order
1075+ }
1076+ vtype_kind_t vtype_fun ;
1077+ emit_pre_pop_reg (emit , & vtype_fun , REG_ARG_1 ); // the function
1078+ assert (vtype_fun == VTYPE_PYOBJ );
1079+ emit_call_with_imm_arg (emit , RT_F_CALL_FUNCTION_N , rt_call_function_n , n_positional , REG_ARG_2 );
1080+ //}
10731081 emit_post_push_reg (emit , VTYPE_PYOBJ , REG_RET );
10741082}
10751083
10761084static void emit_native_call_method (emit_t * emit , int n_positional , int n_keyword , bool have_star_arg , bool have_dbl_star_arg ) {
10771085 assert (n_keyword == 0 && !have_star_arg && !have_dbl_star_arg );
1086+ /*
10781087 if (n_positional == 0) {
10791088 vtype_kind_t vtype_meth, vtype_self;
10801089 emit_pre_pop_reg_reg(emit, &vtype_self, REG_ARG_2, &vtype_meth, REG_ARG_1); // the self object (or NULL), the method
@@ -1089,10 +1098,11 @@ static void emit_native_call_method(emit_t *emit, int n_positional, int n_keywor
10891098 assert(vtype_arg1 == VTYPE_PYOBJ);
10901099 emit_call(emit, RT_F_CALL_METHOD_2, rt_call_method_2);
10911100 } else {
1101+ */
10921102 emit_pre (emit );
10931103 emit_get_stack_pointer_to_reg_for_pop (emit , REG_ARG_2 , n_positional + 2 ); // pointer to items in reverse order, including meth and self
10941104 emit_call_with_imm_arg (emit , RT_F_CALL_METHOD_N , rt_call_method_n , n_positional , REG_ARG_1 );
1095- }
1105+ // }
10961106 emit_post_push_reg (emit , VTYPE_PYOBJ , REG_RET );
10971107}
10981108
0 commit comments