py/emitnative: Consolidate use of stacked immediate values to one func.

This commit adds the helper function load_reg_stack_imm() which deals with
constant immediate values and converting them to Python objects if needed.
pull/1/head
Damien George 2018-10-14 22:58:27 +11:00
parent 759853f2a1
commit 175739cd37
1 changed files with 43 additions and 50 deletions

View File

@ -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) {