@@ -561,6 +561,17 @@ STATIC void emit_call_with_imm_arg(emit_t *emit, mp_fun_kind_t fun_kind, void *f
561561#endif
562562}
563563
564+ // the first arg is stored in the code aligned on a machine_uint_t boundary
565+ 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 ) {
566+ need_reg_all (emit );
567+ ASM_MOV_ALIGNED_IMM_TO_REG (arg_val , arg_reg );
568+ #if N_X64
569+ asm_x64_call_ind (emit -> as , fun , REG_RAX );
570+ #elif N_THUMB
571+ asm_thumb_bl_ind (emit -> as , mp_fun_table [fun_kind ], fun_kind , REG_R3 );
572+ #endif
573+ }
574+
564575STATIC 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 ) {
565576 need_reg_all (emit );
566577 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) {
688699 DEBUG_printf ("load_const_int %s\n" , qstr_str (st ));
689700 // for viper: load integer, check fits in 32 bits
690701 emit_native_pre (emit );
691- emit_call_with_imm_arg (emit , MP_F_LOAD_CONST_INT , mp_obj_new_int_from_long_str , qst , REG_ARG_1 );
702+ emit_call_with_imm_arg (emit , MP_F_LOAD_CONST_INT , mp_obj_new_int_from_qstr , qst , REG_ARG_1 );
692703 emit_post_push_reg (emit , VTYPE_PYOBJ , REG_RET );
693704}
694705
@@ -945,6 +956,8 @@ STATIC void emit_native_rot_three(emit_t *emit) {
945956
946957STATIC void emit_native_jump (emit_t * emit , uint label ) {
947958 emit_native_pre (emit );
959+ // need to commit stack because we are jumping elsewhere
960+ need_stack_settled (emit );
948961#if N_X64
949962 asm_x64_jmp_label (emit -> as , label );
950963#elif N_THUMB
@@ -953,21 +966,41 @@ STATIC void emit_native_jump(emit_t *emit, uint label) {
953966 emit_post (emit );
954967}
955968
956- STATIC void emit_native_pop_jump_pre_helper (emit_t * emit , uint label ) {
969+ STATIC void emit_native_jump_helper (emit_t * emit , uint label , bool pop ) {
957970 vtype_kind_t vtype = peek_vtype (emit );
958971 if (vtype == VTYPE_BOOL ) {
959972 emit_pre_pop_reg (emit , & vtype , REG_RET );
973+ if (!pop ) {
974+ adjust_stack (emit , 1 );
975+ }
960976 } else if (vtype == VTYPE_PYOBJ ) {
961977 emit_pre_pop_reg (emit , & vtype , REG_ARG_1 );
962978 emit_call (emit , MP_F_OBJ_IS_TRUE , mp_obj_is_true );
979+ if (!pop ) {
980+ emit_post_push_reg (emit , VTYPE_PYOBJ , REG_RET );
981+ }
963982 } else {
964983 printf ("ViperTypeError: expecting a bool or pyobj, got %d\n" , vtype );
965984 assert (0 );
966985 }
986+ // need to commit stack because we may jump elsewhere
987+ need_stack_settled (emit );
988+ }
989+
990+ STATIC void emit_native_pop_jump_if_true (emit_t * emit , uint label ) {
991+ emit_native_jump_helper (emit , label , true);
992+ #if N_X64
993+ asm_x64_test_r8_with_r8 (emit -> as , REG_RET , REG_RET );
994+ asm_x64_jcc_label (emit -> as , JCC_JNZ , label );
995+ #elif N_THUMB
996+ asm_thumb_cmp_rlo_i8 (emit -> as , REG_RET , 0 );
997+ asm_thumb_bcc_label (emit -> as , THUMB_CC_NE , label );
998+ #endif
999+ emit_post (emit );
9671000}
9681001
9691002STATIC void emit_native_pop_jump_if_false (emit_t * emit , uint label ) {
970- emit_native_pop_jump_pre_helper (emit , label );
1003+ emit_native_jump_helper (emit , label , true );
9711004#if N_X64
9721005 asm_x64_test_r8_with_r8 (emit -> as , REG_RET , REG_RET );
9731006 asm_x64_jcc_label (emit -> as , JCC_JZ , label );
@@ -978,31 +1011,40 @@ STATIC void emit_native_pop_jump_if_false(emit_t *emit, uint label) {
9781011 emit_post (emit );
9791012}
9801013
981- STATIC void emit_native_pop_jump_if_true (emit_t * emit , uint label ) {
982- emit_native_pop_jump_pre_helper (emit , label );
1014+ STATIC void emit_native_jump_if_true_or_pop (emit_t * emit , uint label ) {
1015+ emit_native_jump_helper (emit , label , false );
9831016#if N_X64
9841017 asm_x64_test_r8_with_r8 (emit -> as , REG_RET , REG_RET );
9851018 asm_x64_jcc_label (emit -> as , JCC_JNZ , label );
9861019#elif N_THUMB
9871020 asm_thumb_cmp_rlo_i8 (emit -> as , REG_RET , 0 );
9881021 asm_thumb_bcc_label (emit -> as , THUMB_CC_NE , label );
9891022#endif
1023+ adjust_stack (emit , -1 );
9901024 emit_post (emit );
9911025}
9921026
993- STATIC void emit_native_jump_if_true_or_pop (emit_t * emit , uint label ) {
994- assert (0 );
995- }
9961027STATIC void emit_native_jump_if_false_or_pop (emit_t * emit , uint label ) {
997- assert (0 );
1028+ emit_native_jump_helper (emit , label , false);
1029+ #if N_X64
1030+ asm_x64_test_r8_with_r8 (emit -> as , REG_RET , REG_RET );
1031+ asm_x64_jcc_label (emit -> as , JCC_JZ , label );
1032+ #elif N_THUMB
1033+ asm_thumb_cmp_rlo_i8 (emit -> as , REG_RET , 0 );
1034+ asm_thumb_bcc_label (emit -> as , THUMB_CC_EQ , label );
1035+ #endif
1036+ adjust_stack (emit , -1 );
1037+ emit_post (emit );
9981038}
9991039
10001040STATIC void emit_native_break_loop (emit_t * emit , uint label , int except_depth ) {
10011041 emit_native_jump (emit , label ); // TODO properly
10021042}
1043+
10031044STATIC void emit_native_continue_loop (emit_t * emit , uint label , int except_depth ) {
1004- assert ( 0 );
1045+ emit_native_jump ( emit , label ); // TODO properly
10051046}
1047+
10061048STATIC void emit_native_setup_with (emit_t * emit , uint label ) {
10071049 // not supported, or could be with runtime call
10081050 assert (0 );
@@ -1037,7 +1079,7 @@ STATIC void emit_native_for_iter(emit_t *emit, uint label) {
10371079 emit_access_stack (emit , 1 , & vtype , REG_ARG_1 );
10381080 assert (vtype == VTYPE_PYOBJ );
10391081 emit_call (emit , MP_F_ITERNEXT , mp_iternext );
1040- ASM_MOV_IMM_TO_REG ((machine_uint_t )MP_OBJ_NULL , REG_TEMP1 );
1082+ ASM_MOV_IMM_TO_REG ((machine_uint_t )MP_OBJ_STOP_ITERATION , REG_TEMP1 );
10411083#if N_X64
10421084 asm_x64_cmp_r64_with_r64 (emit -> as , REG_RET , REG_TEMP1 );
10431085 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) {
12031245}
12041246
12051247STATIC void emit_native_unpack_ex (emit_t * emit , int n_left , int n_right ) {
1206- assert (0 );
1248+ // TODO this is untested
1249+ DEBUG_printf ("unpack_ex %d %d\n" , n_left , n_right );
1250+ vtype_kind_t vtype_base ;
1251+ emit_pre_pop_reg (emit , & vtype_base , REG_ARG_1 ); // arg1 = seq
1252+ assert (vtype_base == VTYPE_PYOBJ );
1253+ emit_get_stack_pointer_to_reg_for_push (emit , REG_ARG_3 , n_left + n_right ); // arg3 = dest ptr
1254+ 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
12071255}
12081256
12091257STATIC void emit_native_make_function (emit_t * emit , scope_t * scope , uint n_pos_defaults , uint n_kw_defaults ) {
12101258 // call runtime, with type info for args, or don't support dict/default params, or only support Python objects for them
1211- assert (n_pos_defaults == 0 && n_kw_defaults == 0 );
12121259 emit_native_pre (emit );
1213- 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 );
1260+ if (n_pos_defaults == 0 && n_kw_defaults == 0 ) {
1261+ 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 );
1262+ } else {
1263+ vtype_kind_t vtype_def_tuple , vtype_def_dict ;
1264+ emit_pre_pop_reg_reg (emit , & vtype_def_dict , REG_ARG_3 , & vtype_def_tuple , REG_ARG_2 );
1265+ assert (vtype_def_tuple == VTYPE_PYOBJ );
1266+ assert (vtype_def_dict == VTYPE_PYOBJ );
1267+ 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 );
1268+ }
12141269 emit_post_push_reg (emit , VTYPE_PYOBJ , REG_RET );
12151270}
12161271
0 commit comments