Skip to content

Commit eb19efb

Browse files
committed
Simplify and improve function & method calling.
1 parent 5609cca commit eb19efb

5 files changed

Lines changed: 156 additions & 173 deletions

File tree

py/emitbc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
#include "scope.h"
1414
#include "runtime.h"
1515
#include "emit.h"
16-
#include "vm.h"
16+
#include "bc.h"
1717

1818
struct _emit_t {
1919
pass_kind_t pass;

py/emitnative.c

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
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))
@@ -82,7 +82,7 @@
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

365357
static 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)
437430
static 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
448447
static 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

466465
static 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
10491048
static 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

10761084
static 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

Comments
 (0)