@@ -2259,15 +2259,38 @@ static void emit_native_pop_except_jump(emit_t *emit, mp_uint_t label, bool with
22592259}
22602260
22612261static void emit_native_unary_op (emit_t * emit , mp_unary_op_t op ) {
2262- vtype_kind_t vtype ;
2263- emit_pre_pop_reg (emit , & vtype , REG_ARG_2 );
2264- if (vtype == VTYPE_PYOBJ ) {
2262+ vtype_kind_t vtype = peek_vtype (emit , 0 );
2263+ if (vtype == VTYPE_INT || vtype == VTYPE_UINT ) {
2264+ if (op == MP_UNARY_OP_POSITIVE ) {
2265+ // No-operation, just leave the argument on the stack.
2266+ } else if (op == MP_UNARY_OP_NEGATIVE ) {
2267+ int reg = REG_RET ;
2268+ emit_pre_pop_reg_flexible (emit , & vtype , & reg , reg , reg );
2269+ ASM_NEG_REG (emit -> as , reg );
2270+ emit_post_push_reg (emit , vtype , reg );
2271+ } else if (op == MP_UNARY_OP_INVERT ) {
2272+ #ifdef ASM_NOT_REG
2273+ int reg = REG_RET ;
2274+ emit_pre_pop_reg_flexible (emit , & vtype , & reg , reg , reg );
2275+ ASM_NOT_REG (emit -> as , reg );
2276+ #else
2277+ int reg = REG_RET ;
2278+ emit_pre_pop_reg_flexible (emit , & vtype , & reg , REG_ARG_1 , reg );
2279+ ASM_MOV_REG_IMM (emit -> as , REG_ARG_1 , -1 );
2280+ ASM_XOR_REG_REG (emit -> as , reg , REG_ARG_1 );
2281+ #endif
2282+ emit_post_push_reg (emit , vtype , reg );
2283+ } else {
2284+ EMIT_NATIVE_VIPER_TYPE_ERROR (emit ,
2285+ MP_ERROR_TEXT ("'not' not implemented" ), mp_binary_op_method_name [op ]);
2286+ }
2287+ } else if (vtype == VTYPE_PYOBJ ) {
2288+ emit_pre_pop_reg (emit , & vtype , REG_ARG_2 );
22652289 emit_call_with_imm_arg (emit , MP_F_UNARY_OP , op , REG_ARG_1 );
22662290 emit_post_push_reg (emit , VTYPE_PYOBJ , REG_RET );
22672291 } else {
2268- adjust_stack (emit , 1 );
22692292 EMIT_NATIVE_VIPER_TYPE_ERROR (emit ,
2270- MP_ERROR_TEXT ("unary op %q not implemented " ), mp_unary_op_method_name [ op ] );
2293+ MP_ERROR_TEXT ("can't do unary op of '%q' " ), vtype_to_qstr ( vtype ) );
22712294 }
22722295}
22732296
0 commit comments