Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
TASTE
uPython-mirror
Commits
a32c1e41
Commit
a32c1e41
authored
May 07, 2014
by
Damien George
Browse files
py: Improve native emitter; now supports more opcodes.
parent
36db6bcf
Changes
8
Hide whitespace changes
Inline
Side-by-side
py/emitnative.c
View file @
a32c1e41
...
...
@@ -561,6 +561,17 @@ STATIC void emit_call_with_imm_arg(emit_t *emit, mp_fun_kind_t fun_kind, void *f
#endif
}
// the first arg is stored in the code aligned on a machine_uint_t boundary
STATIC
void
emit_call_with_imm_arg_aligned
(
emit_t
*
emit
,
mp_fun_kind_t
fun_kind
,
void
*
fun
,
machine_int_t
arg_val
,
int
arg_reg
)
{
need_reg_all
(
emit
);
ASM_MOV_ALIGNED_IMM_TO_REG
(
arg_val
,
arg_reg
);
#if N_X64
asm_x64_call_ind
(
emit
->
as
,
fun
,
REG_RAX
);
#elif N_THUMB
asm_thumb_bl_ind
(
emit
->
as
,
mp_fun_table
[
fun_kind
],
fun_kind
,
REG_R3
);
#endif
}
STATIC
void
emit_call_with_2_imm_args
(
emit_t
*
emit
,
mp_fun_kind_t
fun_kind
,
void
*
fun
,
machine_int_t
arg_val1
,
int
arg_reg1
,
machine_int_t
arg_val2
,
int
arg_reg2
)
{
need_reg_all
(
emit
);
ASM_MOV_IMM_TO_REG
(
arg_val1
,
arg_reg1
);
...
...
@@ -688,7 +699,7 @@ STATIC void emit_native_load_const_int(emit_t *emit, qstr qst) {
DEBUG_printf
(
"load_const_int %s
\n
"
,
qstr_str
(
st
));
// for viper: load integer, check fits in 32 bits
emit_native_pre
(
emit
);
emit_call_with_imm_arg
(
emit
,
MP_F_LOAD_CONST_INT
,
mp_obj_new_int_from_
long_
str
,
qst
,
REG_ARG_1
);
emit_call_with_imm_arg
(
emit
,
MP_F_LOAD_CONST_INT
,
mp_obj_new_int_from_
q
str
,
qst
,
REG_ARG_1
);
emit_post_push_reg
(
emit
,
VTYPE_PYOBJ
,
REG_RET
);
}
...
...
@@ -945,6 +956,8 @@ STATIC void emit_native_rot_three(emit_t *emit) {
STATIC
void
emit_native_jump
(
emit_t
*
emit
,
uint
label
)
{
emit_native_pre
(
emit
);
// need to commit stack because we are jumping elsewhere
need_stack_settled
(
emit
);
#if N_X64
asm_x64_jmp_label
(
emit
->
as
,
label
);
#elif N_THUMB
...
...
@@ -953,21 +966,41 @@ STATIC void emit_native_jump(emit_t *emit, uint label) {
emit_post
(
emit
);
}
STATIC
void
emit_native_
pop_jump_pre
_helper
(
emit_t
*
emit
,
uint
label
)
{
STATIC
void
emit_native_
jump
_helper
(
emit_t
*
emit
,
uint
label
,
bool
pop
)
{
vtype_kind_t
vtype
=
peek_vtype
(
emit
);
if
(
vtype
==
VTYPE_BOOL
)
{
emit_pre_pop_reg
(
emit
,
&
vtype
,
REG_RET
);
if
(
!
pop
)
{
adjust_stack
(
emit
,
1
);
}
}
else
if
(
vtype
==
VTYPE_PYOBJ
)
{
emit_pre_pop_reg
(
emit
,
&
vtype
,
REG_ARG_1
);
emit_call
(
emit
,
MP_F_OBJ_IS_TRUE
,
mp_obj_is_true
);
if
(
!
pop
)
{
emit_post_push_reg
(
emit
,
VTYPE_PYOBJ
,
REG_RET
);
}
}
else
{
printf
(
"ViperTypeError: expecting a bool or pyobj, got %d
\n
"
,
vtype
);
assert
(
0
);
}
// need to commit stack because we may jump elsewhere
need_stack_settled
(
emit
);
}
STATIC
void
emit_native_pop_jump_if_true
(
emit_t
*
emit
,
uint
label
)
{
emit_native_jump_helper
(
emit
,
label
,
true
);
#if N_X64
asm_x64_test_r8_with_r8
(
emit
->
as
,
REG_RET
,
REG_RET
);
asm_x64_jcc_label
(
emit
->
as
,
JCC_JNZ
,
label
);
#elif N_THUMB
asm_thumb_cmp_rlo_i8
(
emit
->
as
,
REG_RET
,
0
);
asm_thumb_bcc_label
(
emit
->
as
,
THUMB_CC_NE
,
label
);
#endif
emit_post
(
emit
);
}
STATIC
void
emit_native_pop_jump_if_false
(
emit_t
*
emit
,
uint
label
)
{
emit_native_
pop_jump_pre
_helper
(
emit
,
label
);
emit_native_
jump
_helper
(
emit
,
label
,
true
);
#if N_X64
asm_x64_test_r8_with_r8
(
emit
->
as
,
REG_RET
,
REG_RET
);
asm_x64_jcc_label
(
emit
->
as
,
JCC_JZ
,
label
);
...
...
@@ -978,8 +1011,8 @@ STATIC void emit_native_pop_jump_if_false(emit_t *emit, uint label) {
emit_post
(
emit
);
}
STATIC
void
emit_native_
pop_
jump_if_true
(
emit_t
*
emit
,
uint
label
)
{
emit_native_
pop_jump_pre
_helper
(
emit
,
label
);
STATIC
void
emit_native_jump_if_true
_or_pop
(
emit_t
*
emit
,
uint
label
)
{
emit_native_
jump
_helper
(
emit
,
label
,
false
);
#if N_X64
asm_x64_test_r8_with_r8
(
emit
->
as
,
REG_RET
,
REG_RET
);
asm_x64_jcc_label
(
emit
->
as
,
JCC_JNZ
,
label
);
...
...
@@ -987,22 +1020,31 @@ STATIC void emit_native_pop_jump_if_true(emit_t *emit, uint label) {
asm_thumb_cmp_rlo_i8
(
emit
->
as
,
REG_RET
,
0
);
asm_thumb_bcc_label
(
emit
->
as
,
THUMB_CC_NE
,
label
);
#endif
adjust_stack
(
emit
,
-
1
);
emit_post
(
emit
);
}
STATIC
void
emit_native_jump_if_true_or_pop
(
emit_t
*
emit
,
uint
label
)
{
assert
(
0
);
}
STATIC
void
emit_native_jump_if_false_or_pop
(
emit_t
*
emit
,
uint
label
)
{
assert
(
0
);
emit_native_jump_helper
(
emit
,
label
,
false
);
#if N_X64
asm_x64_test_r8_with_r8
(
emit
->
as
,
REG_RET
,
REG_RET
);
asm_x64_jcc_label
(
emit
->
as
,
JCC_JZ
,
label
);
#elif N_THUMB
asm_thumb_cmp_rlo_i8
(
emit
->
as
,
REG_RET
,
0
);
asm_thumb_bcc_label
(
emit
->
as
,
THUMB_CC_EQ
,
label
);
#endif
adjust_stack
(
emit
,
-
1
);
emit_post
(
emit
);
}
STATIC
void
emit_native_break_loop
(
emit_t
*
emit
,
uint
label
,
int
except_depth
)
{
emit_native_jump
(
emit
,
label
);
// TODO properly
}
STATIC
void
emit_native_continue_loop
(
emit_t
*
emit
,
uint
label
,
int
except_depth
)
{
assert
(
0
);
emit_native_jump
(
emit
,
label
);
// TODO properly
}
STATIC
void
emit_native_setup_with
(
emit_t
*
emit
,
uint
label
)
{
// not supported, or could be with runtime call
assert
(
0
);
...
...
@@ -1037,7 +1079,7 @@ STATIC void emit_native_for_iter(emit_t *emit, uint label) {
emit_access_stack
(
emit
,
1
,
&
vtype
,
REG_ARG_1
);
assert
(
vtype
==
VTYPE_PYOBJ
);
emit_call
(
emit
,
MP_F_ITERNEXT
,
mp_iternext
);
ASM_MOV_IMM_TO_REG
((
machine_uint_t
)
MP_OBJ_
NULL
,
REG_TEMP1
);
ASM_MOV_IMM_TO_REG
((
machine_uint_t
)
MP_OBJ_
STOP_ITERATION
,
REG_TEMP1
);
#if N_X64
asm_x64_cmp_r64_with_r64
(
emit
->
as
,
REG_RET
,
REG_TEMP1
);
asm_x64_jcc_label
(
emit
->
as
,
JCC_JE
,
label
);
...
...
@@ -1203,14 +1245,27 @@ STATIC void emit_native_unpack_sequence(emit_t *emit, int n_args) {
}
STATIC
void
emit_native_unpack_ex
(
emit_t
*
emit
,
int
n_left
,
int
n_right
)
{
assert
(
0
);
// TODO this is untested
DEBUG_printf
(
"unpack_ex %d %d
\n
"
,
n_left
,
n_right
);
vtype_kind_t
vtype_base
;
emit_pre_pop_reg
(
emit
,
&
vtype_base
,
REG_ARG_1
);
// arg1 = seq
assert
(
vtype_base
==
VTYPE_PYOBJ
);
emit_get_stack_pointer_to_reg_for_push
(
emit
,
REG_ARG_3
,
n_left
+
n_right
);
// arg3 = dest ptr
emit_call_with_imm_arg
(
emit
,
MP_F_UNPACK_EX
,
mp_unpack_ex
,
n_left
+
n_right
,
REG_ARG_2
);
// arg2 = n_left + n_right
}
STATIC
void
emit_native_make_function
(
emit_t
*
emit
,
scope_t
*
scope
,
uint
n_pos_defaults
,
uint
n_kw_defaults
)
{
// call runtime, with type info for args, or don't support dict/default params, or only support Python objects for them
assert
(
n_pos_defaults
==
0
&&
n_kw_defaults
==
0
);
emit_native_pre
(
emit
);
emit_call_with_3_imm_args_and_first_aligned
(
emit
,
MP_F_MAKE_FUNCTION_FROM_RAW_CODE
,
mp_make_function_from_raw_code
,
(
machine_uint_t
)
scope
->
raw_code
,
REG_ARG_1
,
(
machine_uint_t
)
MP_OBJ_NULL
,
REG_ARG_2
,
(
machine_uint_t
)
MP_OBJ_NULL
,
REG_ARG_3
);
if
(
n_pos_defaults
==
0
&&
n_kw_defaults
==
0
)
{
emit_call_with_3_imm_args_and_first_aligned
(
emit
,
MP_F_MAKE_FUNCTION_FROM_RAW_CODE
,
mp_make_function_from_raw_code
,
(
machine_uint_t
)
scope
->
raw_code
,
REG_ARG_1
,
(
machine_uint_t
)
MP_OBJ_NULL
,
REG_ARG_2
,
(
machine_uint_t
)
MP_OBJ_NULL
,
REG_ARG_3
);
}
else
{
vtype_kind_t
vtype_def_tuple
,
vtype_def_dict
;
emit_pre_pop_reg_reg
(
emit
,
&
vtype_def_dict
,
REG_ARG_3
,
&
vtype_def_tuple
,
REG_ARG_2
);
assert
(
vtype_def_tuple
==
VTYPE_PYOBJ
);
assert
(
vtype_def_dict
==
VTYPE_PYOBJ
);
emit_call_with_imm_arg_aligned
(
emit
,
MP_F_MAKE_FUNCTION_FROM_RAW_CODE
,
mp_make_function_from_raw_code
,
(
machine_uint_t
)
scope
->
raw_code
,
REG_ARG_1
);
}
emit_post_push_reg
(
emit
,
VTYPE_PYOBJ
,
REG_RET
);
}
...
...
py/obj.h
View file @
a32c1e41
...
...
@@ -370,7 +370,7 @@ mp_obj_t mp_obj_new_bool(bool value);
mp_obj_t
mp_obj_new_cell
(
mp_obj_t
obj
);
mp_obj_t
mp_obj_new_int
(
machine_int_t
value
);
mp_obj_t
mp_obj_new_int_from_uint
(
machine_uint_t
value
);
mp_obj_t
mp_obj_new_int_from_
long_str
(
const
char
*
s
);
mp_obj_t
mp_obj_new_int_from_
qstr
(
qstr
qst
);
mp_obj_t
mp_obj_new_int_from_ll
(
long
long
val
);
// this must return a multi-precision integer object (or raise an overflow exception)
mp_obj_t
mp_obj_new_str
(
const
byte
*
data
,
uint
len
,
bool
make_qstr_if_not_already
);
mp_obj_t
mp_obj_new_bytes
(
const
byte
*
data
,
uint
len
);
...
...
py/objint.c
View file @
a32c1e41
...
...
@@ -228,7 +228,7 @@ mp_obj_t mp_obj_int_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
}
// This is called only with strings whose value doesn't fit in SMALL_INT
mp_obj_t
mp_obj_new_int_from_
long_str
(
const
char
*
s
)
{
mp_obj_t
mp_obj_new_int_from_
qstr
(
qstr
qst
)
{
nlr_raise
(
mp_obj_new_exception_msg
(
&
mp_type_OverflowError
,
"long int not supported in this build"
));
return
mp_const_none
;
}
...
...
py/objint_longlong.c
View file @
a32c1e41
...
...
@@ -161,7 +161,8 @@ mp_obj_t mp_obj_new_int_from_ll(long long val) {
return
o
;
}
mp_obj_t
mp_obj_new_int_from_long_str
(
const
char
*
s
)
{
mp_obj_t
mp_obj_new_int_from_qstr
(
qstr
qst
)
{
const
char
*
s
=
qstr_str
(
qst
);
long
long
v
;
char
*
end
;
// TODO: this doesn't handle Python hacked 0o octal syntax
...
...
py/objint_mpz.c
View file @
a32c1e41
...
...
@@ -260,9 +260,10 @@ mp_obj_t mp_obj_new_int_from_uint(machine_uint_t value) {
return
mp_obj_new_int_from_ll
(
value
);
}
mp_obj_t
mp_obj_new_int_from_
long_str
(
const
cha
r
*
st
r
)
{
mp_obj_t
mp_obj_new_int_from_
qstr
(
qst
r
q
st
)
{
mp_obj_int_t
*
o
=
mp_obj_int_new_mpz
();
uint
len
=
strlen
(
str
);
uint
len
;
const
char
*
str
=
(
const
char
*
)
qstr_data
(
qst
,
&
len
);
int
base
=
0
;
int
skip
=
mp_parse_num_base
(
str
,
len
,
&
base
);
str
+=
skip
;
...
...
py/runtime.c
View file @
a32c1e41
...
...
@@ -1132,7 +1132,7 @@ void *m_malloc_fail(int num_bytes) {
// these must correspond to the respective enum
void
*
const
mp_fun_table
[
MP_F_NUMBER_OF
]
=
{
mp_load_const_dec
,
mp_obj_new_int_from_
long_
str
,
mp_obj_new_int_from_
q
str
,
mp_load_const_str
,
mp_load_name
,
mp_load_global
,
...
...
@@ -1162,6 +1162,7 @@ void *const mp_fun_table[MP_F_NUMBER_OF] = {
mp_import_all
,
mp_obj_new_slice
,
mp_unpack_sequence
,
mp_unpack_ex
,
};
/*
...
...
py/runtime0.h
View file @
a32c1e41
...
...
@@ -121,6 +121,7 @@ typedef enum {
MP_F_IMPORT_ALL
,
MP_F_NEW_SLICE
,
MP_F_UNPACK_SEQUENCE
,
MP_F_UNPACK_EX
,
MP_F_NUMBER_OF
,
}
mp_fun_kind_t
;
...
...
py/vm.c
View file @
a32c1e41
...
...
@@ -314,7 +314,7 @@ dispatch_loop:
ENTRY
(
MP_BC_LOAD_CONST_INT
)
:
DECODE_QSTR
;
PUSH
(
mp_obj_new_int_from_
long_str
(
qstr_
str
(
qst
))
)
;
PUSH
(
mp_obj_new_int_from_
q
str
(
qst
));
DISPATCH
();
ENTRY
(
MP_BC_LOAD_CONST_DEC
)
:
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment