summaryrefslogtreecommitdiff
path: root/py/emitnative.c
diff options
context:
space:
mode:
Diffstat (limited to 'py/emitnative.c')
-rw-r--r--py/emitnative.c93
1 files changed, 43 insertions, 50 deletions
diff --git a/py/emitnative.c b/py/emitnative.c
index 5f461ac33..ca6ff8ee9 100644
--- a/py/emitnative.c
+++ b/py/emitnative.c
@@ -669,7 +669,12 @@ STATIC stack_info_t *peek_stack(emit_t *emit, mp_uint_t depth) {
// depth==0 is top, depth==1 is before top, etc
STATIC vtype_kind_t peek_vtype(emit_t *emit, mp_uint_t depth) {
- return peek_stack(emit, depth)->vtype;
+ if (emit->do_viper_types) {
+ return peek_stack(emit, depth)->vtype;
+ } else {
+ // Type is always PYOBJ even if the intermediate stored value is not
+ return VTYPE_PYOBJ;
+ }
}
// pos=1 is TOS, pos=2 is next, etc
@@ -697,6 +702,30 @@ STATIC void need_reg_all(emit_t *emit) {
}
}
+STATIC vtype_kind_t load_reg_stack_imm(emit_t *emit, int reg_dest, const stack_info_t *si, bool convert_to_pyobj) {
+ if (!convert_to_pyobj && emit->do_viper_types) {
+ ASM_MOV_REG_IMM(emit->as, reg_dest, si->data.u_imm);
+ return si->vtype;
+ } else {
+ if (si->vtype == VTYPE_PYOBJ) {
+ ASM_MOV_REG_IMM(emit->as, reg_dest, si->data.u_imm);
+ } else if (si->vtype == VTYPE_BOOL) {
+ if (si->data.u_imm == 0) {
+ ASM_MOV_REG_IMM(emit->as, reg_dest, (mp_uint_t)mp_const_false);
+ } else {
+ ASM_MOV_REG_IMM(emit->as, reg_dest, (mp_uint_t)mp_const_true);
+ }
+ } else if (si->vtype == VTYPE_INT || si->vtype == VTYPE_UINT) {
+ ASM_MOV_REG_IMM(emit->as, reg_dest, (uintptr_t)MP_OBJ_NEW_SMALL_INT(si->data.u_imm));
+ } else if (si->vtype == VTYPE_PTR_NONE) {
+ ASM_MOV_REG_IMM(emit->as, reg_dest, (mp_uint_t)mp_const_none);
+ } else {
+ mp_raise_NotImplementedError("conversion to object");
+ }
+ return VTYPE_PYOBJ;
+ }
+}
+
STATIC void need_stack_settled(emit_t *emit) {
DEBUG_printf(" need_stack_settled; stack_size=%d\n", emit->stack_size);
for (int i = 0; i < emit->stack_size; i++) {
@@ -712,7 +741,8 @@ STATIC void need_stack_settled(emit_t *emit) {
if (si->kind == STACK_IMM) {
DEBUG_printf(" imm(" INT_FMT ") to local(%u)\n", si->data.u_imm, emit->stack_start + i);
si->kind = STACK_VALUE;
- emit_native_mov_state_imm_via(emit, emit->stack_start + i, si->data.u_imm, REG_TEMP0);
+ si->vtype = load_reg_stack_imm(emit, REG_TEMP0, si, false);
+ emit_native_mov_state_reg(emit, emit->stack_start + i, REG_TEMP0);
}
}
}
@@ -734,7 +764,7 @@ STATIC void emit_access_stack(emit_t *emit, int pos, vtype_kind_t *vtype, int re
break;
case STACK_IMM:
- ASM_MOV_REG_IMM(emit->as, reg_dest, si->data.u_imm);
+ *vtype = load_reg_stack_imm(emit, reg_dest, si, false);
break;
}
}
@@ -867,27 +897,8 @@ STATIC void emit_get_stack_pointer_to_reg_for_pop(emit_t *emit, mp_uint_t reg_de
// must convert them to VTYPE_PYOBJ for viper code
if (si->kind == STACK_IMM) {
si->kind = STACK_VALUE;
- switch (si->vtype) {
- case VTYPE_PYOBJ:
- emit_native_mov_state_imm_via(emit, emit->stack_start + emit->stack_size - 1 - i, si->data.u_imm, reg_dest);
- break;
- case VTYPE_BOOL:
- if (si->data.u_imm == 0) {
- emit_native_mov_state_imm_via(emit, emit->stack_start + emit->stack_size - 1 - i, (mp_uint_t)mp_const_false, reg_dest);
- } else {
- emit_native_mov_state_imm_via(emit, emit->stack_start + emit->stack_size - 1 - i, (mp_uint_t)mp_const_true, reg_dest);
- }
- si->vtype = VTYPE_PYOBJ;
- break;
- case VTYPE_INT:
- case VTYPE_UINT:
- emit_native_mov_state_imm_via(emit, emit->stack_start + emit->stack_size - 1 - i, (uintptr_t)MP_OBJ_NEW_SMALL_INT(si->data.u_imm), reg_dest);
- si->vtype = VTYPE_PYOBJ;
- break;
- default:
- // not handled
- mp_raise_NotImplementedError("conversion to object");
- }
+ si->vtype = load_reg_stack_imm(emit, reg_dest, si, true);
+ emit_native_mov_state_reg(emit, emit->stack_start + emit->stack_size - 1 - i, reg_dest);
}
// verify that this value is on the stack
@@ -1221,40 +1232,22 @@ STATIC void emit_native_import(emit_t *emit, qstr qst, int kind) {
STATIC void emit_native_load_const_tok(emit_t *emit, mp_token_kind_t tok) {
DEBUG_printf("load_const_tok(tok=%u)\n", tok);
- emit_native_pre(emit);
- vtype_kind_t vtype;
- mp_uint_t val;
- if (emit->do_viper_types) {
- switch (tok) {
- case MP_TOKEN_KW_NONE: vtype = VTYPE_PTR_NONE; val = 0; break;
- case MP_TOKEN_KW_FALSE: vtype = VTYPE_BOOL; val = 0; break;
- case MP_TOKEN_KW_TRUE: vtype = VTYPE_BOOL; val = 1; break;
- default:
- assert(tok == MP_TOKEN_ELLIPSIS);
- vtype = VTYPE_PYOBJ; val = (mp_uint_t)&mp_const_ellipsis_obj; break;
- }
+ if (tok == MP_TOKEN_ELLIPSIS) {
+ emit_post_push_imm(emit, VTYPE_PYOBJ, (mp_uint_t)MP_OBJ_FROM_PTR(&mp_const_ellipsis_obj));
} else {
- vtype = VTYPE_PYOBJ;
- switch (tok) {
- case MP_TOKEN_KW_NONE: val = (mp_uint_t)mp_const_none; break;
- case MP_TOKEN_KW_FALSE: val = (mp_uint_t)mp_const_false; break;
- case MP_TOKEN_KW_TRUE: val = (mp_uint_t)mp_const_true; break;
- default:
- assert(tok == MP_TOKEN_ELLIPSIS);
- val = (mp_uint_t)&mp_const_ellipsis_obj; break;
+ emit_native_pre(emit);
+ if (tok == MP_TOKEN_KW_NONE) {
+ emit_post_push_imm(emit, VTYPE_PTR_NONE, 0);
+ } else {
+ emit_post_push_imm(emit, VTYPE_BOOL, tok == MP_TOKEN_KW_FALSE ? 0 : 1);
}
}
- emit_post_push_imm(emit, vtype, val);
}
STATIC void emit_native_load_const_small_int(emit_t *emit, mp_int_t arg) {
DEBUG_printf("load_const_small_int(int=" INT_FMT ")\n", arg);
emit_native_pre(emit);
- if (emit->do_viper_types) {
- emit_post_push_imm(emit, VTYPE_INT, arg);
- } else {
- emit_post_push_imm(emit, VTYPE_PYOBJ, (mp_uint_t)MP_OBJ_NEW_SMALL_INT(arg));
- }
+ emit_post_push_imm(emit, VTYPE_INT, arg);
}
STATIC void emit_native_load_const_str(emit_t *emit, qstr qst) {