Skip to content

Commit bc1d369

Browse files
committed
py: Fix emitcpy and emitnative's binary_op.
1 parent 8d4ccc4 commit bc1d369

3 files changed

Lines changed: 28 additions & 5 deletions

File tree

py/emitcpy.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,13 @@ static void emit_cpy_unary_op(emit_t *emit, rt_unary_op_t op) {
551551
}
552552

553553
static void emit_cpy_binary_op(emit_t *emit, rt_binary_op_t op) {
554-
emit_pre(emit, -1, 1);
554+
if (op <= RT_BINARY_OP_INPLACE_POWER) {
555+
// CPython uses a byte code for each binary op
556+
emit_pre(emit, -1, 1);
557+
} else {
558+
// CPython uses a byte code plus an argument for compare ops
559+
emit_pre(emit, -1, 3);
560+
}
555561
if (emit->pass == PASS_3) {
556562
switch (op) {
557563
case RT_BINARY_OP_SUBSCR: printf("BINARY_SUBSCR\n"); break;

py/emitnative.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -997,13 +997,29 @@ static void emit_native_binary_op(emit_t *emit, rt_binary_op_t op) {
997997
vtype_kind_t vtype_lhs, vtype_rhs;
998998
emit_pre_pop_reg_reg(emit, &vtype_rhs, REG_ARG_3, &vtype_lhs, REG_ARG_2);
999999
if (vtype_lhs == VTYPE_INT && vtype_rhs == VTYPE_INT) {
1000-
assert(op == RT_BINARY_OP_ADD || op == RT_BINARY_OP_INPLACE_ADD);
1000+
if (op == RT_BINARY_OP_ADD || op == RT_BINARY_OP_INPLACE_ADD) {
10011001
#if N_X64
1002-
asm_x64_add_r64_to_r64(emit->as, REG_ARG_3, REG_ARG_2);
1002+
asm_x64_add_r64_to_r64(emit->as, REG_ARG_3, REG_ARG_2);
10031003
#elif N_THUMB
1004-
asm_thumb_add_reg_reg_reg(emit->as, REG_ARG_2, REG_ARG_2, REG_ARG_3);
1004+
asm_thumb_add_reg_reg_reg(emit->as, REG_ARG_2, REG_ARG_2, REG_ARG_3);
10051005
#endif
1006-
emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2);
1006+
emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2);
1007+
} else if (op == RT_COMPARE_OP_LESS) {
1008+
#if N_X64
1009+
asm_x64_xor_r64_to_r64(emit->as, REG_RET, REG_RET);
1010+
asm_x64_cmp_r64_with_r64(emit->as, REG_ARG_3, REG_ARG_2);
1011+
asm_x64_setcc_r8(emit->as, JCC_JL, REG_RET);
1012+
#elif N_THUMB
1013+
asm_thumb_cmp_reg_reg(emit->as, REG_ARG_2, REG_ARG_3);
1014+
asm_thumb_ite_ge(emit->as);
1015+
asm_thumb_movs_rlo_i8(emit->as, REG_RET, 0); // if r0 >= r1
1016+
asm_thumb_movs_rlo_i8(emit->as, REG_RET, 1); // if r0 < r1
1017+
#endif
1018+
emit_post_push_reg(emit, VTYPE_BOOL, REG_RET);
1019+
} else {
1020+
// TODO other ops not yet implemented
1021+
assert(0);
1022+
}
10071023
} else if (vtype_lhs == VTYPE_PYOBJ && vtype_rhs == VTYPE_PYOBJ) {
10081024
emit_call_with_imm_arg(emit, RT_F_BINARY_OP, rt_binary_op, op, REG_ARG_1);
10091025
emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);

py/runtime0.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ typedef enum {
3131
RT_BINARY_OP_INPLACE_TRUE_DIVIDE,
3232
RT_BINARY_OP_INPLACE_MODULO,
3333
RT_BINARY_OP_INPLACE_POWER,
34+
// TODO probably should rename these COMPARE->BINARY
3435
RT_COMPARE_OP_LESS,
3536
RT_COMPARE_OP_MORE,
3637
RT_COMPARE_OP_EQUAL,

0 commit comments

Comments
 (0)