From 32f0b7942cf44b7a722db30c554cfc70d3f70289 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 13 Feb 2015 10:43:05 +0000 Subject: [PATCH] py: Implement sdiv/udiv for inline Thumb assembler. --- py/emitinlinethumb.c | 11 +++++++++++ py/objfun.c | 2 ++ tests/inlineasm/asmdiv.py | 16 ++++++++++++++++ tests/inlineasm/asmdiv.py.exp | 7 +++++++ 4 files changed, 36 insertions(+) create mode 100644 tests/inlineasm/asmdiv.py create mode 100644 tests/inlineasm/asmdiv.py.exp diff --git a/py/emitinlinethumb.c b/py/emitinlinethumb.c index 737c03c10..d28e015cd 100644 --- a/py/emitinlinethumb.c +++ b/py/emitinlinethumb.c @@ -490,6 +490,17 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a src_b = get_arg_i(emit, op_str, pn_args[2], 0x7); } asm_thumb_format_2(emit->as, op_code, rlo_dest, rlo_src, src_b); + } else if (strcmp(op_str, "sdiv") == 0) { + op_code = 0xfb90; // sdiv high part + mp_uint_t rd, rn, rm; + op_sdiv_udiv: + rd = get_arg_reg(emit, op_str, pn_args[0], 15); + rn = get_arg_reg(emit, op_str, pn_args[1], 15); + rm = get_arg_reg(emit, op_str, pn_args[2], 15); + asm_thumb_op32(emit->as, op_code | rn, 0xf0f0 | (rd << 8) | rm); + } else if (strcmp(op_str, "udiv") == 0) { + op_code = 0xfbb0; // udiv high part + goto op_sdiv_udiv; } else if (strcmp(op_str, "sub") == 0) { op_code = ASM_THUMB_FORMAT_2_SUB; goto op_format_2; diff --git a/py/objfun.c b/py/objfun.c index 28706cc68..75a326c12 100644 --- a/py/objfun.c +++ b/py/objfun.c @@ -431,6 +431,8 @@ STATIC mp_uint_t convert_obj_for_inline_asm(mp_obj_t obj) { return 0; } else if (obj == mp_const_true) { return 1; + } else if (MP_OBJ_IS_TYPE(obj, &mp_type_int)) { + return mp_obj_int_get_truncated(obj); } else if (MP_OBJ_IS_STR(obj)) { // pointer to the string (it's probably constant though!) mp_uint_t l; diff --git a/tests/inlineasm/asmdiv.py b/tests/inlineasm/asmdiv.py new file mode 100644 index 000000000..b97d566eb --- /dev/null +++ b/tests/inlineasm/asmdiv.py @@ -0,0 +1,16 @@ +@micropython.asm_thumb +def sdiv(r0, r1): + sdiv(r0, r0, r1) + +@micropython.asm_thumb +def udiv(r0, r1): + udiv(r0, r0, r1) + +print(sdiv(1234, 3)) +print(sdiv(-1234, 3)) +print(sdiv(1234, -3)) +print(sdiv(-1234, -3)) + +print(udiv(1234, 3)) +print(udiv(0xffffffff, 0x7fffffff)) +print(udiv(0xffffffff, 0xffffffff)) diff --git a/tests/inlineasm/asmdiv.py.exp b/tests/inlineasm/asmdiv.py.exp new file mode 100644 index 000000000..f1b80deb3 --- /dev/null +++ b/tests/inlineasm/asmdiv.py.exp @@ -0,0 +1,7 @@ +411 +-411 +-411 +411 +411 +2 +1