Skip to content

Commit 9aa2a52

Browse files
committed
py: Tidy up BINARY_OPs; negation done by special NOT bytecode.
IS_NOT and NOT_IN are now compiled to IS + NOT and IN + NOT, with a new special NOT bytecode.
1 parent 7e5fb24 commit 9aa2a52

17 files changed

Lines changed: 144 additions & 135 deletions

py/bc0.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,9 @@
6363
#define MP_BC_POP_EXCEPT (0x55)
6464
#define MP_BC_UNWIND_JUMP (0x56) // rel byte code offset, 16-bit signed, in excess; then a byte
6565

66-
#define MP_BC_UNARY_OP (0x60) // byte
67-
#define MP_BC_BINARY_OP (0x61) // byte
66+
#define MP_BC_NOT (0x60)
67+
#define MP_BC_UNARY_OP (0x61) // byte
68+
#define MP_BC_BINARY_OP (0x62) // byte
6869

6970
#define MP_BC_BUILD_TUPLE (0x70) // uint
7071
#define MP_BC_BUILD_LIST (0x71) // uint

py/compile.c

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1466,9 +1466,9 @@ void compile_for_stmt_optimised_range(compiler_t *comp, mp_parse_node_t pn_var,
14661466
compile_node(comp, pn_var);
14671467
compile_node(comp, pn_end);
14681468
if (MP_PARSE_NODE_LEAF_ARG(pn_step) >= 0) {
1469-
EMIT_ARG(binary_op, RT_COMPARE_OP_LESS);
1469+
EMIT_ARG(binary_op, RT_BINARY_OP_LESS);
14701470
} else {
1471-
EMIT_ARG(binary_op, RT_COMPARE_OP_MORE);
1471+
EMIT_ARG(binary_op, RT_BINARY_OP_MORE);
14721472
}
14731473
EMIT_ARG(pop_jump_if_true, top_label);
14741474

@@ -1605,7 +1605,7 @@ void compile_try_except(compiler_t *comp, mp_parse_node_t pn_body, int n_except,
16051605
}
16061606
EMIT(dup_top);
16071607
compile_node(comp, pns_exception_expr);
1608-
EMIT_ARG(binary_op, RT_COMPARE_OP_EXCEPTION_MATCH);
1608+
EMIT_ARG(binary_op, RT_BINARY_OP_EXCEPTION_MATCH);
16091609
EMIT_ARG(pop_jump_if_false, end_finally_label);
16101610
}
16111611

@@ -1912,21 +1912,7 @@ void compile_and_test(compiler_t *comp, mp_parse_node_struct_t *pns) {
19121912

19131913
void compile_not_test_2(compiler_t *comp, mp_parse_node_struct_t *pns) {
19141914
compile_node(comp, pns->nodes[0]);
1915-
#if MICROPY_EMIT_CPYTHON
19161915
EMIT_ARG(unary_op, RT_UNARY_OP_NOT);
1917-
#else
1918-
// eliminate use of NOT byte code
1919-
int l_load_false = comp_next_label(comp);
1920-
int l_done = comp_next_label(comp);
1921-
int stack_size = EMIT(get_stack_size);
1922-
EMIT_ARG(pop_jump_if_true, l_load_false);
1923-
EMIT_ARG(load_const_tok, MP_TOKEN_KW_TRUE);
1924-
EMIT_ARG(jump, l_done);
1925-
EMIT_ARG(label_assign, l_load_false);
1926-
EMIT_ARG(load_const_tok, MP_TOKEN_KW_FALSE);
1927-
EMIT_ARG(label_assign, l_done);
1928-
EMIT_ARG(set_stack_size, stack_size); // force stack size since it counts 1 pop and 2 pushes statically, but really it's 1 pop and 1 push dynamically
1929-
#endif
19301916
}
19311917

19321918
void compile_comparison(compiler_t *comp, mp_parse_node_struct_t *pns) {
@@ -1947,26 +1933,26 @@ void compile_comparison(compiler_t *comp, mp_parse_node_struct_t *pns) {
19471933
if (MP_PARSE_NODE_IS_TOKEN(pns->nodes[i])) {
19481934
rt_binary_op_t op;
19491935
switch (MP_PARSE_NODE_LEAF_ARG(pns->nodes[i])) {
1950-
case MP_TOKEN_OP_LESS: op = RT_COMPARE_OP_LESS; break;
1951-
case MP_TOKEN_OP_MORE: op = RT_COMPARE_OP_MORE; break;
1952-
case MP_TOKEN_OP_DBL_EQUAL: op = RT_COMPARE_OP_EQUAL; break;
1953-
case MP_TOKEN_OP_LESS_EQUAL: op = RT_COMPARE_OP_LESS_EQUAL; break;
1954-
case MP_TOKEN_OP_MORE_EQUAL: op = RT_COMPARE_OP_MORE_EQUAL; break;
1955-
case MP_TOKEN_OP_NOT_EQUAL: op = RT_COMPARE_OP_NOT_EQUAL; break;
1956-
case MP_TOKEN_KW_IN: op = RT_COMPARE_OP_IN; break;
1957-
default: assert(0); op = RT_COMPARE_OP_LESS; // shouldn't happen
1936+
case MP_TOKEN_OP_LESS: op = RT_BINARY_OP_LESS; break;
1937+
case MP_TOKEN_OP_MORE: op = RT_BINARY_OP_MORE; break;
1938+
case MP_TOKEN_OP_DBL_EQUAL: op = RT_BINARY_OP_EQUAL; break;
1939+
case MP_TOKEN_OP_LESS_EQUAL: op = RT_BINARY_OP_LESS_EQUAL; break;
1940+
case MP_TOKEN_OP_MORE_EQUAL: op = RT_BINARY_OP_MORE_EQUAL; break;
1941+
case MP_TOKEN_OP_NOT_EQUAL: op = RT_BINARY_OP_NOT_EQUAL; break;
1942+
case MP_TOKEN_KW_IN: op = RT_BINARY_OP_IN; break;
1943+
default: assert(0); op = RT_BINARY_OP_LESS; // shouldn't happen
19581944
}
19591945
EMIT_ARG(binary_op, op);
19601946
} else if (MP_PARSE_NODE_IS_STRUCT(pns->nodes[i])) {
19611947
mp_parse_node_struct_t *pns2 = (mp_parse_node_struct_t*)pns->nodes[i];
19621948
int kind = MP_PARSE_NODE_STRUCT_KIND(pns2);
19631949
if (kind == PN_comp_op_not_in) {
1964-
EMIT_ARG(binary_op, RT_COMPARE_OP_NOT_IN);
1950+
EMIT_ARG(binary_op, RT_BINARY_OP_NOT_IN);
19651951
} else if (kind == PN_comp_op_is) {
19661952
if (MP_PARSE_NODE_IS_NULL(pns2->nodes[0])) {
1967-
EMIT_ARG(binary_op, RT_COMPARE_OP_IS);
1953+
EMIT_ARG(binary_op, RT_BINARY_OP_IS);
19681954
} else {
1969-
EMIT_ARG(binary_op, RT_COMPARE_OP_IS_NOT);
1955+
EMIT_ARG(binary_op, RT_BINARY_OP_IS_NOT);
19701956
}
19711957
} else {
19721958
// shouldn't happen

py/emitbc.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -600,13 +600,32 @@ static void emit_bc_pop_except(emit_t *emit) {
600600
}
601601

602602
static void emit_bc_unary_op(emit_t *emit, rt_unary_op_t op) {
603-
emit_pre(emit, 0);
604-
emit_write_byte_code_byte_byte(emit, MP_BC_UNARY_OP, op);
603+
if (op == RT_UNARY_OP_NOT) {
604+
emit_pre(emit, 0);
605+
emit_write_byte_code_byte_byte(emit, MP_BC_UNARY_OP, RT_UNARY_OP_BOOL);
606+
emit_pre(emit, 0);
607+
emit_write_byte_code_byte(emit, MP_BC_NOT);
608+
} else {
609+
emit_pre(emit, 0);
610+
emit_write_byte_code_byte_byte(emit, MP_BC_UNARY_OP, op);
611+
}
605612
}
606613

607614
static void emit_bc_binary_op(emit_t *emit, rt_binary_op_t op) {
615+
bool invert = false;
616+
if (op == RT_BINARY_OP_NOT_IN) {
617+
invert = true;
618+
op = RT_BINARY_OP_IN;
619+
} else if (op == RT_BINARY_OP_IS_NOT) {
620+
invert = true;
621+
op = RT_BINARY_OP_IS;
622+
}
608623
emit_pre(emit, -1);
609624
emit_write_byte_code_byte_byte(emit, MP_BC_BINARY_OP, op);
625+
if (invert) {
626+
emit_pre(emit, 0);
627+
emit_write_byte_code_byte(emit, MP_BC_NOT);
628+
}
610629
}
611630

612631
static void emit_bc_build_tuple(emit_t *emit, int n_args) {

py/emitcpy.c

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -545,10 +545,10 @@ static void emit_cpy_unary_op(emit_t *emit, rt_unary_op_t op) {
545545
emit_pre(emit, 0, 1);
546546
if (emit->pass == PASS_3) {
547547
switch (op) {
548-
case RT_UNARY_OP_NOT: printf("UNARY_NOT\n"); break;
549548
case RT_UNARY_OP_POSITIVE: printf("UNARY_POSITIVE\n"); break;
550549
case RT_UNARY_OP_NEGATIVE: printf("UNARY_NEGATIVE\n"); break;
551550
case RT_UNARY_OP_INVERT: printf("UNARY_INVERT\n"); break;
551+
case RT_UNARY_OP_NOT: printf("UNARY_NOT\n"); break;
552552
default: assert(0);
553553
}
554554
}
@@ -589,17 +589,17 @@ static void emit_cpy_binary_op(emit_t *emit, rt_binary_op_t op) {
589589
case RT_BINARY_OP_INPLACE_TRUE_DIVIDE: printf("INPLACE_TRUE_DIVIDE\n"); break;
590590
case RT_BINARY_OP_INPLACE_MODULO: printf("INPLACE_MODULO\n"); break;
591591
case RT_BINARY_OP_INPLACE_POWER: printf("INPLACE_POWER\n"); break;
592-
case RT_COMPARE_OP_LESS: printf("COMPARE_OP <\n"); break;
593-
case RT_COMPARE_OP_MORE: printf("COMPARE_OP >\n"); break;
594-
case RT_COMPARE_OP_EQUAL: printf("COMPARE_OP ==\n"); break;
595-
case RT_COMPARE_OP_LESS_EQUAL: printf("COMPARE_OP <=\n"); break;
596-
case RT_COMPARE_OP_MORE_EQUAL: printf("COMPARE_OP >=\n"); break;
597-
case RT_COMPARE_OP_NOT_EQUAL: printf("COMPARE_OP !=\n"); break;
598-
case RT_COMPARE_OP_IN: printf("COMPARE_OP in\n"); break;
599-
case RT_COMPARE_OP_NOT_IN: printf("COMPARE_OP not in\n"); break;
600-
case RT_COMPARE_OP_IS: printf("COMPARE_OP is\n"); break;
601-
case RT_COMPARE_OP_IS_NOT: printf("COMPARE_OP is not\n"); break;
602-
case RT_COMPARE_OP_EXCEPTION_MATCH: printf("COMPARE_OP exception match\n"); break;
592+
case RT_BINARY_OP_LESS: printf("COMPARE_OP <\n"); break;
593+
case RT_BINARY_OP_MORE: printf("COMPARE_OP >\n"); break;
594+
case RT_BINARY_OP_EQUAL: printf("COMPARE_OP ==\n"); break;
595+
case RT_BINARY_OP_LESS_EQUAL: printf("COMPARE_OP <=\n"); break;
596+
case RT_BINARY_OP_MORE_EQUAL: printf("COMPARE_OP >=\n"); break;
597+
case RT_BINARY_OP_NOT_EQUAL: printf("COMPARE_OP !=\n"); break;
598+
case RT_BINARY_OP_IN: printf("COMPARE_OP in\n"); break;
599+
case RT_BINARY_OP_IS: printf("COMPARE_OP is\n"); break;
600+
case RT_BINARY_OP_EXCEPTION_MATCH: printf("COMPARE_OP exception match\n"); break;
601+
case RT_BINARY_OP_NOT_IN: printf("COMPARE_OP not in\n"); break;
602+
case RT_BINARY_OP_IS_NOT: printf("COMPARE_OP is not\n"); break;
603603
default: assert(0);
604604
}
605605
}

py/emitnative.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1017,7 +1017,7 @@ static void emit_native_binary_op(emit_t *emit, rt_binary_op_t op) {
10171017
asm_thumb_add_reg_reg_reg(emit->as, REG_ARG_2, REG_ARG_2, REG_ARG_3);
10181018
#endif
10191019
emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2);
1020-
} else if (op == RT_COMPARE_OP_LESS) {
1020+
} else if (op == RT_BINARY_OP_LESS) {
10211021
#if N_X64
10221022
asm_x64_xor_r64_to_r64(emit->as, REG_RET, REG_RET);
10231023
asm_x64_cmp_r64_with_r64(emit->as, REG_ARG_3, REG_ARG_2);

py/obj.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ bool mp_obj_equal(mp_obj_t o1, mp_obj_t o2) {
116116
// If o2 is long int, dispatch to its virtual methods
117117
mp_obj_base_t *o = o2;
118118
if (o->type->binary_op != NULL) {
119-
mp_obj_t r = o->type->binary_op(RT_COMPARE_OP_EQUAL, o2, o1);
119+
mp_obj_t r = o->type->binary_op(RT_BINARY_OP_EQUAL, o2, o1);
120120
return r == mp_const_true ? true : false;
121121
}
122122
}
@@ -127,7 +127,7 @@ bool mp_obj_equal(mp_obj_t o1, mp_obj_t o2) {
127127
} else {
128128
mp_obj_base_t *o = o1;
129129
if (o->type->binary_op != NULL) {
130-
mp_obj_t r = o->type->binary_op(RT_COMPARE_OP_EQUAL, o1, o2);
130+
mp_obj_t r = o->type->binary_op(RT_BINARY_OP_EQUAL, o1, o2);
131131
if (r != MP_OBJ_NULL) {
132132
return r == mp_const_true ? true : false;
133133
}

py/objdict.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,10 @@ static mp_obj_t dict_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
6565
return elem->value;
6666
}
6767
}
68-
case RT_COMPARE_OP_IN:
69-
case RT_COMPARE_OP_NOT_IN:
68+
case RT_BINARY_OP_IN:
7069
{
7170
mp_map_elem_t *elem = mp_map_lookup(&o->map, rhs_in, MP_MAP_LOOKUP);
72-
return MP_BOOL((op == RT_COMPARE_OP_IN) ^ (elem == NULL));
71+
return MP_BOOL(elem != NULL);
7372
}
7473
default:
7574
// op not supported
@@ -380,7 +379,7 @@ static mp_obj_t dict_view_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
380379
/* only supported for the 'keys' kind until sets and dicts are refactored */
381380
mp_obj_dict_view_t *o = lhs_in;
382381
if (o->kind != MP_DICT_VIEW_KEYS) return NULL;
383-
if (op != RT_COMPARE_OP_IN && op != RT_COMPARE_OP_NOT_IN) return NULL;
382+
if (op != RT_BINARY_OP_IN) return NULL;
384383
return dict_binary_op(op, o->dict, rhs_in);
385384
}
386385

py/objfloat.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,10 @@ mp_obj_t mp_obj_float_binary_op(int op, mp_float_t lhs_val, mp_obj_t rhs_in) {
101101
case RT_BINARY_OP_TRUE_DIVIDE:
102102
case RT_BINARY_OP_INPLACE_TRUE_DIVIDE: lhs_val /= rhs_val; break;
103103

104-
case RT_COMPARE_OP_LESS: return MP_BOOL(lhs_val < rhs_val);
105-
case RT_COMPARE_OP_MORE: return MP_BOOL(lhs_val > rhs_val);
106-
case RT_COMPARE_OP_LESS_EQUAL: return MP_BOOL(lhs_val <= rhs_val);
107-
case RT_COMPARE_OP_MORE_EQUAL: return MP_BOOL(lhs_val >= rhs_val);
104+
case RT_BINARY_OP_LESS: return MP_BOOL(lhs_val < rhs_val);
105+
case RT_BINARY_OP_MORE: return MP_BOOL(lhs_val > rhs_val);
106+
case RT_BINARY_OP_LESS_EQUAL: return MP_BOOL(lhs_val <= rhs_val);
107+
case RT_BINARY_OP_MORE_EQUAL: return MP_BOOL(lhs_val >= rhs_val);
108108

109109
return NULL; // op not supported
110110
}

py/objint_longlong.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,17 +103,17 @@ mp_obj_t int_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
103103
case RT_BINARY_OP_INPLACE_RSHIFT:
104104
lhs->val >>= (int)rhs_val; return lhs;
105105

106-
case RT_COMPARE_OP_LESS:
106+
case RT_BINARY_OP_LESS:
107107
return MP_BOOL(lhs->val < rhs_val);
108-
case RT_COMPARE_OP_MORE:
108+
case RT_BINARY_OP_MORE:
109109
return MP_BOOL(lhs->val > rhs_val);
110-
case RT_COMPARE_OP_LESS_EQUAL:
110+
case RT_BINARY_OP_LESS_EQUAL:
111111
return MP_BOOL(lhs->val <= rhs_val);
112-
case RT_COMPARE_OP_MORE_EQUAL:
112+
case RT_BINARY_OP_MORE_EQUAL:
113113
return MP_BOOL(lhs->val >= rhs_val);
114-
case RT_COMPARE_OP_EQUAL:
114+
case RT_BINARY_OP_EQUAL:
115115
return MP_BOOL(lhs->val == rhs_val);
116-
case RT_COMPARE_OP_NOT_EQUAL:
116+
case RT_BINARY_OP_NOT_EQUAL:
117117
return MP_BOOL(lhs->val != rhs_val);
118118

119119
default:

py/objlist.c

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -67,27 +67,27 @@ static mp_obj_t list_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp
6767
return NULL;
6868
}
6969

70-
// Don't pass RT_COMPARE_OP_NOT_EQUAL here
70+
// Don't pass RT_BINARY_OP_NOT_EQUAL here
7171
static bool list_cmp_helper(int op, mp_obj_t self_in, mp_obj_t another_in) {
7272
assert(MP_OBJ_IS_TYPE(self_in, &list_type));
7373
if (!MP_OBJ_IS_TYPE(another_in, &list_type)) {
7474
return false;
7575
}
7676
mp_obj_list_t *self = self_in;
7777
mp_obj_list_t *another = another_in;
78-
if (op == RT_COMPARE_OP_EQUAL && self->len != another->len) {
78+
if (op == RT_BINARY_OP_EQUAL && self->len != another->len) {
7979
return false;
8080
}
8181

8282
// Let's deal only with > & >=
83-
if (op == RT_COMPARE_OP_LESS || op == RT_COMPARE_OP_LESS_EQUAL) {
83+
if (op == RT_BINARY_OP_LESS || op == RT_BINARY_OP_LESS_EQUAL) {
8484
mp_obj_t t = self;
8585
self = another;
8686
another = t;
87-
if (op == RT_COMPARE_OP_LESS) {
88-
op = RT_COMPARE_OP_MORE;
87+
if (op == RT_BINARY_OP_LESS) {
88+
op = RT_BINARY_OP_MORE;
8989
} else {
90-
op = RT_COMPARE_OP_MORE_EQUAL;
90+
op = RT_BINARY_OP_MORE_EQUAL;
9191
}
9292
}
9393

@@ -96,7 +96,7 @@ static bool list_cmp_helper(int op, mp_obj_t self_in, mp_obj_t another_in) {
9696
bool rel_status;
9797
for (int i = 0; i < len; i++) {
9898
eq_status = mp_obj_equal(self->items[i], another->items[i]);
99-
if (op == RT_COMPARE_OP_EQUAL && !eq_status) {
99+
if (op == RT_BINARY_OP_EQUAL && !eq_status) {
100100
return false;
101101
}
102102
rel_status = (rt_binary_op(op, self->items[i], another->items[i]) == mp_const_true);
@@ -113,7 +113,7 @@ static bool list_cmp_helper(int op, mp_obj_t self_in, mp_obj_t another_in) {
113113
// ... then longer list length wins (we deal only with >)
114114
return false;
115115
}
116-
} else if (op == RT_COMPARE_OP_MORE) {
116+
} else if (op == RT_BINARY_OP_MORE) {
117117
// Otherwise, if we have strict relation, equality means failure
118118
return false;
119119
}
@@ -169,14 +169,14 @@ static mp_obj_t list_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
169169
mp_seq_multiply(o->items, sizeof(*o->items), o->len, n, s->items);
170170
return s;
171171
}
172-
case RT_COMPARE_OP_EQUAL:
173-
case RT_COMPARE_OP_LESS:
174-
case RT_COMPARE_OP_LESS_EQUAL:
175-
case RT_COMPARE_OP_MORE:
176-
case RT_COMPARE_OP_MORE_EQUAL:
172+
case RT_BINARY_OP_EQUAL:
173+
case RT_BINARY_OP_LESS:
174+
case RT_BINARY_OP_LESS_EQUAL:
175+
case RT_BINARY_OP_MORE:
176+
case RT_BINARY_OP_MORE_EQUAL:
177177
return MP_BOOL(list_cmp_helper(op, lhs, rhs));
178-
case RT_COMPARE_OP_NOT_EQUAL:
179-
return MP_BOOL(!list_cmp_helper(RT_COMPARE_OP_EQUAL, lhs, rhs));
178+
case RT_BINARY_OP_NOT_EQUAL:
179+
return MP_BOOL(!list_cmp_helper(RT_BINARY_OP_EQUAL, lhs, rhs));
180180

181181
default:
182182
// op not supported
@@ -237,7 +237,7 @@ static mp_obj_t list_pop(uint n_args, const mp_obj_t *args) {
237237

238238
// TODO make this conform to CPython's definition of sort
239239
static void mp_quicksort(mp_obj_t *head, mp_obj_t *tail, mp_obj_t key_fn, bool reversed) {
240-
int op = reversed ? RT_COMPARE_OP_MORE : RT_COMPARE_OP_LESS;
240+
int op = reversed ? RT_BINARY_OP_MORE : RT_BINARY_OP_LESS;
241241
while (head < tail) {
242242
mp_obj_t *h = head - 1;
243243
mp_obj_t *t = tail;

0 commit comments

Comments
 (0)