diff options
author | Damien George <damien.p.george@gmail.com> | 2014-01-11 09:47:06 +0000 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2014-01-11 09:47:06 +0000 |
commit | bc1d36924d616ca58f47142e1eb20146d9f253e7 (patch) | |
tree | a7b100da7eb049d6774c6bad427f4f1056cdd564 /py | |
parent | 8d4ccc49ed8bca34579982a5a96b2b50da86d985 (diff) | |
download | micropython-bc1d36924d616ca58f47142e1eb20146d9f253e7.tar.gz micropython-bc1d36924d616ca58f47142e1eb20146d9f253e7.zip |
py: Fix emitcpy and emitnative's binary_op.
Diffstat (limited to 'py')
-rw-r--r-- | py/emitcpy.c | 8 | ||||
-rw-r--r-- | py/emitnative.c | 24 | ||||
-rw-r--r-- | py/runtime0.h | 1 |
3 files changed, 28 insertions, 5 deletions
diff --git a/py/emitcpy.c b/py/emitcpy.c index dfc851d2ed..ee96e589a3 100644 --- a/py/emitcpy.c +++ b/py/emitcpy.c @@ -551,7 +551,13 @@ static void emit_cpy_unary_op(emit_t *emit, rt_unary_op_t op) { } static void emit_cpy_binary_op(emit_t *emit, rt_binary_op_t op) { - emit_pre(emit, -1, 1); + if (op <= RT_BINARY_OP_INPLACE_POWER) { + // CPython uses a byte code for each binary op + emit_pre(emit, -1, 1); + } else { + // CPython uses a byte code plus an argument for compare ops + emit_pre(emit, -1, 3); + } if (emit->pass == PASS_3) { switch (op) { case RT_BINARY_OP_SUBSCR: printf("BINARY_SUBSCR\n"); break; diff --git a/py/emitnative.c b/py/emitnative.c index 8a6bd8f2d0..7ba4d07599 100644 --- a/py/emitnative.c +++ b/py/emitnative.c @@ -997,13 +997,29 @@ static void emit_native_binary_op(emit_t *emit, rt_binary_op_t op) { vtype_kind_t vtype_lhs, vtype_rhs; emit_pre_pop_reg_reg(emit, &vtype_rhs, REG_ARG_3, &vtype_lhs, REG_ARG_2); if (vtype_lhs == VTYPE_INT && vtype_rhs == VTYPE_INT) { - assert(op == RT_BINARY_OP_ADD || op == RT_BINARY_OP_INPLACE_ADD); + if (op == RT_BINARY_OP_ADD || op == RT_BINARY_OP_INPLACE_ADD) { #if N_X64 - asm_x64_add_r64_to_r64(emit->as, REG_ARG_3, REG_ARG_2); + asm_x64_add_r64_to_r64(emit->as, REG_ARG_3, REG_ARG_2); #elif N_THUMB - asm_thumb_add_reg_reg_reg(emit->as, REG_ARG_2, REG_ARG_2, REG_ARG_3); + asm_thumb_add_reg_reg_reg(emit->as, REG_ARG_2, REG_ARG_2, REG_ARG_3); #endif - emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2); + emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2); + } else if (op == RT_COMPARE_OP_LESS) { +#if N_X64 + asm_x64_xor_r64_to_r64(emit->as, REG_RET, REG_RET); + asm_x64_cmp_r64_with_r64(emit->as, REG_ARG_3, REG_ARG_2); + asm_x64_setcc_r8(emit->as, JCC_JL, REG_RET); +#elif N_THUMB + asm_thumb_cmp_reg_reg(emit->as, REG_ARG_2, REG_ARG_3); + asm_thumb_ite_ge(emit->as); + asm_thumb_movs_rlo_i8(emit->as, REG_RET, 0); // if r0 >= r1 + asm_thumb_movs_rlo_i8(emit->as, REG_RET, 1); // if r0 < r1 +#endif + emit_post_push_reg(emit, VTYPE_BOOL, REG_RET); + } else { + // TODO other ops not yet implemented + assert(0); + } } else if (vtype_lhs == VTYPE_PYOBJ && vtype_rhs == VTYPE_PYOBJ) { emit_call_with_imm_arg(emit, RT_F_BINARY_OP, rt_binary_op, op, REG_ARG_1); emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); diff --git a/py/runtime0.h b/py/runtime0.h index 641fdaa9c6..4fdcdc3cc9 100644 --- a/py/runtime0.h +++ b/py/runtime0.h @@ -31,6 +31,7 @@ typedef enum { RT_BINARY_OP_INPLACE_TRUE_DIVIDE, RT_BINARY_OP_INPLACE_MODULO, RT_BINARY_OP_INPLACE_POWER, + // TODO probably should rename these COMPARE->BINARY RT_COMPARE_OP_LESS, RT_COMPARE_OP_MORE, RT_COMPARE_OP_EQUAL, |