From dfef4249eb289ae53307d61e3bf2d5cc7339748a Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 29 Sep 2014 21:41:41 +0000 Subject: [PATCH] py: Fix viper store on x86; add tests for viper ptr16. --- py/emitnative.c | 15 ++++++++++++++- tests/micropython/viper_ptr16_store.py | 19 +++++++++++++++++++ tests/micropython/viper_ptr16_store.py.exp | 3 +++ 3 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 tests/micropython/viper_ptr16_store.py create mode 100644 tests/micropython/viper_ptr16_store.py.exp diff --git a/py/emitnative.c b/py/emitnative.c index 16f0a08246..504f686bd3 100644 --- a/py/emitnative.c +++ b/py/emitnative.c @@ -1391,7 +1391,10 @@ STATIC void emit_native_store_subscr(emit_t *emit) { assert(vtype_value == VTYPE_PYOBJ); emit_call(emit, MP_F_OBJ_SUBSCR); } else { - // viper call + // viper store + // TODO The different machine architectures have very different + // capabilities and requirements for stores, so probably best to + // write a completely separate store-optimiser for each one. stack_info_t *top = peek_stack(emit, 0); if (top->vtype == VTYPE_INT && top->kind == STACK_IMM) { // index is an immediate @@ -1402,7 +1405,12 @@ STATIC void emit_native_store_subscr(emit_t *emit) { int reg_index = REG_ARG_2; int reg_value = REG_ARG_3; emit_pre_pop_reg_flexible(emit, &vtype_base, ®_base, reg_index, reg_value); + #if N_X86 + // special case: x86 needs byte stores to be from lower 4 regs (REG_ARG_3 is EDX) + emit_pre_pop_reg(emit, &vtype_value, reg_value); + #else emit_pre_pop_reg_flexible(emit, &vtype_value, ®_value, reg_base, reg_index); + #endif switch (vtype_base) { case VTYPE_PTR8: { // pointer to 8-bit memory @@ -1449,7 +1457,12 @@ STATIC void emit_native_store_subscr(emit_t *emit) { int reg_value = REG_ARG_3; emit_pre_pop_reg_flexible(emit, &vtype_index, ®_index, REG_ARG_1, reg_value); emit_pre_pop_reg(emit, &vtype_base, REG_ARG_1); + #if N_X86 + // special case: x86 needs byte stores to be from lower 4 regs (REG_ARG_3 is EDX) + emit_pre_pop_reg(emit, &vtype_value, reg_value); + #else emit_pre_pop_reg_flexible(emit, &vtype_value, ®_value, REG_ARG_1, reg_index); + #endif switch (vtype_base) { case VTYPE_PTR8: { // pointer to 8-bit memory diff --git a/tests/micropython/viper_ptr16_store.py b/tests/micropython/viper_ptr16_store.py new file mode 100644 index 0000000000..94cde2bc65 --- /dev/null +++ b/tests/micropython/viper_ptr16_store.py @@ -0,0 +1,19 @@ +# test ptr16 type + +@micropython.viper +def set(dest:ptr16, val:int): + dest[0] = val + +@micropython.viper +def memset(dest:ptr16, val:int, n:int): + for i in range(n): + dest[i] = val + +b = bytearray(4) +print(b) + +set(b, 0x4242) +print(b) + +memset(b, 0x4343, len(b) // 2) +print(b) diff --git a/tests/micropython/viper_ptr16_store.py.exp b/tests/micropython/viper_ptr16_store.py.exp new file mode 100644 index 0000000000..639a43f8f6 --- /dev/null +++ b/tests/micropython/viper_ptr16_store.py.exp @@ -0,0 +1,3 @@ +bytearray(b'\x00\x00\x00\x00') +bytearray(b'BB\x00\x00') +bytearray(b'CCCC')