Skip to content

Commit a3afa8c

Browse files
committed
py/emitnative: Implement floor-division and modulo for viper emitter.
1 parent 1b7d6a7 commit a3afa8c

File tree

5 files changed

+67
-0
lines changed

5 files changed

+67
-0
lines changed

py/emitnative.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ STATIC byte mp_f_n_args[MP_F_NUMBER_OF] = {
123123
[MP_F_NEW_CELL] = 1,
124124
[MP_F_MAKE_CLOSURE_FROM_RAW_CODE] = 3,
125125
[MP_F_SETUP_CODE_STATE] = 5,
126+
[MP_F_SMALL_INT_FLOOR_DIVIDE] = 2,
127+
[MP_F_SMALL_INT_MODULO] = 2,
126128
};
127129

128130
#include "py/asmx86.h"
@@ -1843,6 +1845,20 @@ STATIC void emit_native_binary_op(emit_t *emit, mp_binary_op_t op) {
18431845
return;
18441846
}
18451847
#endif
1848+
1849+
// special cases for floor-divide and module because we dispatch to helper functions
1850+
if (op == MP_BINARY_OP_FLOOR_DIVIDE || op == MP_BINARY_OP_INPLACE_FLOOR_DIVIDE
1851+
|| op == MP_BINARY_OP_MODULO || op == MP_BINARY_OP_INPLACE_MODULO) {
1852+
emit_pre_pop_reg_reg(emit, &vtype_rhs, REG_ARG_2, &vtype_lhs, REG_ARG_1);
1853+
if (op == MP_BINARY_OP_FLOOR_DIVIDE || op == MP_BINARY_OP_INPLACE_FLOOR_DIVIDE) {
1854+
emit_call(emit, MP_F_SMALL_INT_FLOOR_DIVIDE);
1855+
} else {
1856+
emit_call(emit, MP_F_SMALL_INT_MODULO);
1857+
}
1858+
emit_post_push_reg(emit, VTYPE_INT, REG_RET);
1859+
return;
1860+
}
1861+
18461862
int reg_rhs = REG_ARG_3;
18471863
emit_pre_pop_reg_flexible(emit, &vtype_rhs, &reg_rhs, REG_RET, REG_ARG_2);
18481864
emit_pre_pop_reg(emit, &vtype_lhs, REG_ARG_2);

py/nativeglue.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <assert.h>
3030

3131
#include "py/runtime.h"
32+
#include "py/smallint.h"
3233
#include "py/emitglue.h"
3334
#include "py/bc.h"
3435

@@ -170,6 +171,8 @@ void *const mp_fun_table[MP_F_NUMBER_OF] = {
170171
mp_obj_new_cell,
171172
mp_make_closure_from_raw_code,
172173
mp_setup_code_state,
174+
mp_small_int_floor_divide,
175+
mp_small_int_modulo,
173176
};
174177

175178
/*

py/runtime0.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,8 @@ typedef enum {
185185
MP_F_NEW_CELL,
186186
MP_F_MAKE_CLOSURE_FROM_RAW_CODE,
187187
MP_F_SETUP_CODE_STATE,
188+
MP_F_SMALL_INT_FLOOR_DIVIDE,
189+
MP_F_SMALL_INT_MODULO,
188190
MP_F_NUMBER_OF,
189191
} mp_fun_kind_t;
190192

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# test floor-division and modulo operators
2+
3+
@micropython.viper
4+
def div(x:int, y:int) -> int:
5+
return x // y
6+
7+
@micropython.viper
8+
def mod(x:int, y:int) -> int:
9+
return x % y
10+
11+
def dm(x, y):
12+
print(div(x, y), mod(x, y))
13+
14+
for x in (-6, 6):
15+
for y in range(-7, 8):
16+
if y == 0:
17+
continue
18+
dm(x, y)
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
0 -6
2+
1 0
3+
1 -1
4+
1 -2
5+
2 0
6+
3 0
7+
6 0
8+
-6 0
9+
-3 0
10+
-2 0
11+
-2 2
12+
-2 4
13+
-1 0
14+
-1 1
15+
-1 -1
16+
-1 0
17+
-2 -4
18+
-2 -2
19+
-2 0
20+
-3 0
21+
-6 0
22+
6 0
23+
3 0
24+
2 0
25+
1 2
26+
1 1
27+
1 0
28+
0 6

0 commit comments

Comments
 (0)