Port of MicroPython to the mbed platform. See micropython-repl for an interactive program.

Dependents:   micropython-repl

This a port of MicroPython to the mbed Classic platform.

This provides an interpreter running on the board's USB serial connection.

Getting Started

Import the micropython-repl program into your IDE workspace on developer.mbed.org. Compile and download to your board. Connect to the USB serial port in your usual manner. You should get a startup message similar to the following:

  MicroPython v1.7-155-gdddcdd8 on 2016-04-23; K64F with ARM
  Type "help()" for more information.
  >>>

Then you can start using micropython. For example:

  >>> from mbed import DigitalOut
  >>> from pins import LED1
  >>> led = DigitalOut(LED1)
  >>> led.write(1)

Requirements

You need approximately 100K of flash memory, so this will be no good for boards with smaller amounts of storage.

Caveats

This can be considered an alpha release of the port; things may not work; APIs may change in later releases. It is NOT an official part part the micropython project, so if anything doesn't work, blame me. If it does work, most of the credit is due to micropython.

  • Only a few of the mbed classes are available in micropython so far, and not all methods of those that are.
  • Only a few boards have their full range of pin names available; for others, only a few standard ones (USBTX, USBRX, LED1) are implemented.
  • The garbage collector is not yet implemented. The interpreter will gradually consume memory and then fail.
  • Exceptions from the mbed classes are not yet handled.
  • Asynchronous processing (e.g. events on inputs) is not supported.

Credits

  • Damien P. George and other contributors who created micropython.
  • Colin Hogben, author of this port.
Committer:
pythontech
Date:
Sat Apr 16 17:11:56 2016 +0000
Revision:
0:5868e8752d44
Split off library from repl

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pythontech 0:5868e8752d44 1 /*
pythontech 0:5868e8752d44 2 * This file is part of the Micro Python project, http://micropython.org/
pythontech 0:5868e8752d44 3 *
pythontech 0:5868e8752d44 4 * The MIT License (MIT)
pythontech 0:5868e8752d44 5 *
pythontech 0:5868e8752d44 6 * Copyright (c) 2013, 2014 Damien P. George
pythontech 0:5868e8752d44 7 *
pythontech 0:5868e8752d44 8 * Permission is hereby granted, free of charge, to any person obtaining a copy
pythontech 0:5868e8752d44 9 * of this software and associated documentation files (the "Software"), to deal
pythontech 0:5868e8752d44 10 * in the Software without restriction, including without limitation the rights
pythontech 0:5868e8752d44 11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
pythontech 0:5868e8752d44 12 * copies of the Software, and to permit persons to whom the Software is
pythontech 0:5868e8752d44 13 * furnished to do so, subject to the following conditions:
pythontech 0:5868e8752d44 14 *
pythontech 0:5868e8752d44 15 * The above copyright notice and this permission notice shall be included in
pythontech 0:5868e8752d44 16 * all copies or substantial portions of the Software.
pythontech 0:5868e8752d44 17 *
pythontech 0:5868e8752d44 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
pythontech 0:5868e8752d44 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
pythontech 0:5868e8752d44 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
pythontech 0:5868e8752d44 21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
pythontech 0:5868e8752d44 22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
pythontech 0:5868e8752d44 23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
pythontech 0:5868e8752d44 24 * THE SOFTWARE.
pythontech 0:5868e8752d44 25 */
pythontech 0:5868e8752d44 26
pythontech 0:5868e8752d44 27 // Essentially normal Python has 1 type: Python objects
pythontech 0:5868e8752d44 28 // Viper has more than 1 type, and is just a more complicated (a superset of) Python.
pythontech 0:5868e8752d44 29 // If you declare everything in Viper as a Python object (ie omit type decls) then
pythontech 0:5868e8752d44 30 // it should in principle be exactly the same as Python native.
pythontech 0:5868e8752d44 31 // Having types means having more opcodes, like binary_op_nat_nat, binary_op_nat_obj etc.
pythontech 0:5868e8752d44 32 // In practice we won't have a VM but rather do this in asm which is actually very minimal.
pythontech 0:5868e8752d44 33
pythontech 0:5868e8752d44 34 // Because it breaks strict Python equivalence it should be a completely separate
pythontech 0:5868e8752d44 35 // decorator. It breaks equivalence because overflow on integers wraps around.
pythontech 0:5868e8752d44 36 // It shouldn't break equivalence if you don't use the new types, but since the
pythontech 0:5868e8752d44 37 // type decls might be used in normal Python for other reasons, it's probably safest,
pythontech 0:5868e8752d44 38 // cleanest and clearest to make it a separate decorator.
pythontech 0:5868e8752d44 39
pythontech 0:5868e8752d44 40 // Actually, it does break equivalence because integers default to native integers,
pythontech 0:5868e8752d44 41 // not Python objects.
pythontech 0:5868e8752d44 42
pythontech 0:5868e8752d44 43 // for x in l[0:8]: can be compiled into a native loop if l has pointer type
pythontech 0:5868e8752d44 44
pythontech 0:5868e8752d44 45 #include <stdio.h>
pythontech 0:5868e8752d44 46 #include <string.h>
pythontech 0:5868e8752d44 47 #include <assert.h>
pythontech 0:5868e8752d44 48
pythontech 0:5868e8752d44 49 #include "py/nlr.h"
pythontech 0:5868e8752d44 50 #include "py/emit.h"
pythontech 0:5868e8752d44 51 #include "py/bc.h"
pythontech 0:5868e8752d44 52
pythontech 0:5868e8752d44 53 #if 0 // print debugging info
pythontech 0:5868e8752d44 54 #define DEBUG_PRINT (1)
pythontech 0:5868e8752d44 55 #define DEBUG_printf DEBUG_printf
pythontech 0:5868e8752d44 56 #else // don't print debugging info
pythontech 0:5868e8752d44 57 #define DEBUG_printf(...) (void)0
pythontech 0:5868e8752d44 58 #endif
pythontech 0:5868e8752d44 59
pythontech 0:5868e8752d44 60 // wrapper around everything in this file
pythontech 0:5868e8752d44 61 #if (MICROPY_EMIT_X64 && N_X64) \
pythontech 0:5868e8752d44 62 || (MICROPY_EMIT_X86 && N_X86) \
pythontech 0:5868e8752d44 63 || (MICROPY_EMIT_THUMB && N_THUMB) \
pythontech 0:5868e8752d44 64 || (MICROPY_EMIT_ARM && N_ARM)
pythontech 0:5868e8752d44 65
pythontech 0:5868e8752d44 66 #if N_X64
pythontech 0:5868e8752d44 67
pythontech 0:5868e8752d44 68 // x64 specific stuff
pythontech 0:5868e8752d44 69
pythontech 0:5868e8752d44 70 #include "py/asmx64.h"
pythontech 0:5868e8752d44 71
pythontech 0:5868e8752d44 72 #define EXPORT_FUN(name) emit_native_x64_##name
pythontech 0:5868e8752d44 73
pythontech 0:5868e8752d44 74 #define ASM_WORD_SIZE (8)
pythontech 0:5868e8752d44 75
pythontech 0:5868e8752d44 76 #define REG_RET ASM_X64_REG_RAX
pythontech 0:5868e8752d44 77 #define REG_ARG_1 ASM_X64_REG_RDI
pythontech 0:5868e8752d44 78 #define REG_ARG_2 ASM_X64_REG_RSI
pythontech 0:5868e8752d44 79 #define REG_ARG_3 ASM_X64_REG_RDX
pythontech 0:5868e8752d44 80 #define REG_ARG_4 ASM_X64_REG_RCX
pythontech 0:5868e8752d44 81 #define REG_ARG_5 ASM_X64_REG_R08
pythontech 0:5868e8752d44 82
pythontech 0:5868e8752d44 83 // caller-save
pythontech 0:5868e8752d44 84 #define REG_TEMP0 ASM_X64_REG_RAX
pythontech 0:5868e8752d44 85 #define REG_TEMP1 ASM_X64_REG_RDI
pythontech 0:5868e8752d44 86 #define REG_TEMP2 ASM_X64_REG_RSI
pythontech 0:5868e8752d44 87
pythontech 0:5868e8752d44 88 // callee-save
pythontech 0:5868e8752d44 89 #define REG_LOCAL_1 ASM_X64_REG_RBX
pythontech 0:5868e8752d44 90 #define REG_LOCAL_2 ASM_X64_REG_R12
pythontech 0:5868e8752d44 91 #define REG_LOCAL_3 ASM_X64_REG_R13
pythontech 0:5868e8752d44 92 #define REG_LOCAL_NUM (3)
pythontech 0:5868e8752d44 93
pythontech 0:5868e8752d44 94 #define ASM_PASS_COMPUTE ASM_X64_PASS_COMPUTE
pythontech 0:5868e8752d44 95 #define ASM_PASS_EMIT ASM_X64_PASS_EMIT
pythontech 0:5868e8752d44 96
pythontech 0:5868e8752d44 97 #define ASM_T asm_x64_t
pythontech 0:5868e8752d44 98 #define ASM_NEW asm_x64_new
pythontech 0:5868e8752d44 99 #define ASM_FREE asm_x64_free
pythontech 0:5868e8752d44 100 #define ASM_GET_CODE asm_x64_get_code
pythontech 0:5868e8752d44 101 #define ASM_GET_CODE_POS asm_x64_get_code_pos
pythontech 0:5868e8752d44 102 #define ASM_GET_CODE_SIZE asm_x64_get_code_size
pythontech 0:5868e8752d44 103 #define ASM_START_PASS asm_x64_start_pass
pythontech 0:5868e8752d44 104 #define ASM_END_PASS asm_x64_end_pass
pythontech 0:5868e8752d44 105 #define ASM_ENTRY asm_x64_entry
pythontech 0:5868e8752d44 106 #define ASM_EXIT asm_x64_exit
pythontech 0:5868e8752d44 107
pythontech 0:5868e8752d44 108 #define ASM_ALIGN asm_x64_align
pythontech 0:5868e8752d44 109 #define ASM_DATA asm_x64_data
pythontech 0:5868e8752d44 110
pythontech 0:5868e8752d44 111 #define ASM_LABEL_ASSIGN asm_x64_label_assign
pythontech 0:5868e8752d44 112 #define ASM_JUMP asm_x64_jmp_label
pythontech 0:5868e8752d44 113 #define ASM_JUMP_IF_REG_ZERO(as, reg, label) \
pythontech 0:5868e8752d44 114 do { \
pythontech 0:5868e8752d44 115 asm_x64_test_r8_with_r8(as, reg, reg); \
pythontech 0:5868e8752d44 116 asm_x64_jcc_label(as, ASM_X64_CC_JZ, label); \
pythontech 0:5868e8752d44 117 } while (0)
pythontech 0:5868e8752d44 118 #define ASM_JUMP_IF_REG_NONZERO(as, reg, label) \
pythontech 0:5868e8752d44 119 do { \
pythontech 0:5868e8752d44 120 asm_x64_test_r8_with_r8(as, reg, reg); \
pythontech 0:5868e8752d44 121 asm_x64_jcc_label(as, ASM_X64_CC_JNZ, label); \
pythontech 0:5868e8752d44 122 } while (0)
pythontech 0:5868e8752d44 123 #define ASM_JUMP_IF_REG_EQ(as, reg1, reg2, label) \
pythontech 0:5868e8752d44 124 do { \
pythontech 0:5868e8752d44 125 asm_x64_cmp_r64_with_r64(as, reg1, reg2); \
pythontech 0:5868e8752d44 126 asm_x64_jcc_label(as, ASM_X64_CC_JE, label); \
pythontech 0:5868e8752d44 127 } while (0)
pythontech 0:5868e8752d44 128 #define ASM_CALL_IND(as, ptr, idx) asm_x64_call_ind(as, ptr, ASM_X64_REG_RAX)
pythontech 0:5868e8752d44 129
pythontech 0:5868e8752d44 130 #define ASM_MOV_REG_TO_LOCAL asm_x64_mov_r64_to_local
pythontech 0:5868e8752d44 131 #define ASM_MOV_IMM_TO_REG asm_x64_mov_i64_to_r64_optimised
pythontech 0:5868e8752d44 132 #define ASM_MOV_ALIGNED_IMM_TO_REG asm_x64_mov_i64_to_r64_aligned
pythontech 0:5868e8752d44 133 #define ASM_MOV_IMM_TO_LOCAL_USING(as, imm, local_num, reg_temp) \
pythontech 0:5868e8752d44 134 do { \
pythontech 0:5868e8752d44 135 asm_x64_mov_i64_to_r64_optimised(as, (imm), (reg_temp)); \
pythontech 0:5868e8752d44 136 asm_x64_mov_r64_to_local(as, (reg_temp), (local_num)); \
pythontech 0:5868e8752d44 137 } while (false)
pythontech 0:5868e8752d44 138 #define ASM_MOV_LOCAL_TO_REG asm_x64_mov_local_to_r64
pythontech 0:5868e8752d44 139 #define ASM_MOV_REG_REG(as, reg_dest, reg_src) asm_x64_mov_r64_r64((as), (reg_dest), (reg_src))
pythontech 0:5868e8752d44 140 #define ASM_MOV_LOCAL_ADDR_TO_REG asm_x64_mov_local_addr_to_r64
pythontech 0:5868e8752d44 141
pythontech 0:5868e8752d44 142 #define ASM_LSL_REG(as, reg) asm_x64_shl_r64_cl((as), (reg))
pythontech 0:5868e8752d44 143 #define ASM_ASR_REG(as, reg) asm_x64_sar_r64_cl((as), (reg))
pythontech 0:5868e8752d44 144 #define ASM_OR_REG_REG(as, reg_dest, reg_src) asm_x64_or_r64_r64((as), (reg_dest), (reg_src))
pythontech 0:5868e8752d44 145 #define ASM_XOR_REG_REG(as, reg_dest, reg_src) asm_x64_xor_r64_r64((as), (reg_dest), (reg_src))
pythontech 0:5868e8752d44 146 #define ASM_AND_REG_REG(as, reg_dest, reg_src) asm_x64_and_r64_r64((as), (reg_dest), (reg_src))
pythontech 0:5868e8752d44 147 #define ASM_ADD_REG_REG(as, reg_dest, reg_src) asm_x64_add_r64_r64((as), (reg_dest), (reg_src))
pythontech 0:5868e8752d44 148 #define ASM_SUB_REG_REG(as, reg_dest, reg_src) asm_x64_sub_r64_r64((as), (reg_dest), (reg_src))
pythontech 0:5868e8752d44 149 #define ASM_MUL_REG_REG(as, reg_dest, reg_src) asm_x64_mul_r64_r64((as), (reg_dest), (reg_src))
pythontech 0:5868e8752d44 150
pythontech 0:5868e8752d44 151 #define ASM_LOAD_REG_REG(as, reg_dest, reg_base) asm_x64_mov_mem64_to_r64((as), (reg_base), 0, (reg_dest))
pythontech 0:5868e8752d44 152 #define ASM_LOAD_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) asm_x64_mov_mem64_to_r64((as), (reg_base), 8 * (word_offset), (reg_dest))
pythontech 0:5868e8752d44 153 #define ASM_LOAD8_REG_REG(as, reg_dest, reg_base) asm_x64_mov_mem8_to_r64zx((as), (reg_base), 0, (reg_dest))
pythontech 0:5868e8752d44 154 #define ASM_LOAD16_REG_REG(as, reg_dest, reg_base) asm_x64_mov_mem16_to_r64zx((as), (reg_base), 0, (reg_dest))
pythontech 0:5868e8752d44 155 #define ASM_LOAD32_REG_REG(as, reg_dest, reg_base) asm_x64_mov_mem32_to_r64zx((as), (reg_base), 0, (reg_dest))
pythontech 0:5868e8752d44 156
pythontech 0:5868e8752d44 157 #define ASM_STORE_REG_REG(as, reg_src, reg_base) asm_x64_mov_r64_to_mem64((as), (reg_src), (reg_base), 0)
pythontech 0:5868e8752d44 158 #define ASM_STORE_REG_REG_OFFSET(as, reg_src, reg_base, word_offset) asm_x64_mov_r64_to_mem64((as), (reg_src), (reg_base), 8 * (word_offset))
pythontech 0:5868e8752d44 159 #define ASM_STORE8_REG_REG(as, reg_src, reg_base) asm_x64_mov_r8_to_mem8((as), (reg_src), (reg_base), 0)
pythontech 0:5868e8752d44 160 #define ASM_STORE16_REG_REG(as, reg_src, reg_base) asm_x64_mov_r16_to_mem16((as), (reg_src), (reg_base), 0)
pythontech 0:5868e8752d44 161 #define ASM_STORE32_REG_REG(as, reg_src, reg_base) asm_x64_mov_r32_to_mem32((as), (reg_src), (reg_base), 0)
pythontech 0:5868e8752d44 162
pythontech 0:5868e8752d44 163 #elif N_X86
pythontech 0:5868e8752d44 164
pythontech 0:5868e8752d44 165 // x86 specific stuff
pythontech 0:5868e8752d44 166
pythontech 0:5868e8752d44 167 #include "py/asmx86.h"
pythontech 0:5868e8752d44 168
pythontech 0:5868e8752d44 169 STATIC byte mp_f_n_args[MP_F_NUMBER_OF] = {
pythontech 0:5868e8752d44 170 [MP_F_CONVERT_OBJ_TO_NATIVE] = 2,
pythontech 0:5868e8752d44 171 [MP_F_CONVERT_NATIVE_TO_OBJ] = 2,
pythontech 0:5868e8752d44 172 [MP_F_LOAD_NAME] = 1,
pythontech 0:5868e8752d44 173 [MP_F_LOAD_GLOBAL] = 1,
pythontech 0:5868e8752d44 174 [MP_F_LOAD_BUILD_CLASS] = 0,
pythontech 0:5868e8752d44 175 [MP_F_LOAD_ATTR] = 2,
pythontech 0:5868e8752d44 176 [MP_F_LOAD_METHOD] = 3,
pythontech 0:5868e8752d44 177 [MP_F_STORE_NAME] = 2,
pythontech 0:5868e8752d44 178 [MP_F_STORE_GLOBAL] = 2,
pythontech 0:5868e8752d44 179 [MP_F_STORE_ATTR] = 3,
pythontech 0:5868e8752d44 180 [MP_F_OBJ_SUBSCR] = 3,
pythontech 0:5868e8752d44 181 [MP_F_OBJ_IS_TRUE] = 1,
pythontech 0:5868e8752d44 182 [MP_F_UNARY_OP] = 2,
pythontech 0:5868e8752d44 183 [MP_F_BINARY_OP] = 3,
pythontech 0:5868e8752d44 184 [MP_F_BUILD_TUPLE] = 2,
pythontech 0:5868e8752d44 185 [MP_F_BUILD_LIST] = 2,
pythontech 0:5868e8752d44 186 [MP_F_LIST_APPEND] = 2,
pythontech 0:5868e8752d44 187 [MP_F_BUILD_MAP] = 1,
pythontech 0:5868e8752d44 188 [MP_F_STORE_MAP] = 3,
pythontech 0:5868e8752d44 189 #if MICROPY_PY_BUILTINS_SET
pythontech 0:5868e8752d44 190 [MP_F_BUILD_SET] = 2,
pythontech 0:5868e8752d44 191 [MP_F_STORE_SET] = 2,
pythontech 0:5868e8752d44 192 #endif
pythontech 0:5868e8752d44 193 [MP_F_MAKE_FUNCTION_FROM_RAW_CODE] = 3,
pythontech 0:5868e8752d44 194 [MP_F_NATIVE_CALL_FUNCTION_N_KW] = 3,
pythontech 0:5868e8752d44 195 [MP_F_CALL_METHOD_N_KW] = 3,
pythontech 0:5868e8752d44 196 [MP_F_CALL_METHOD_N_KW_VAR] = 3,
pythontech 0:5868e8752d44 197 [MP_F_GETITER] = 1,
pythontech 0:5868e8752d44 198 [MP_F_ITERNEXT] = 1,
pythontech 0:5868e8752d44 199 [MP_F_NLR_PUSH] = 1,
pythontech 0:5868e8752d44 200 [MP_F_NLR_POP] = 0,
pythontech 0:5868e8752d44 201 [MP_F_NATIVE_RAISE] = 1,
pythontech 0:5868e8752d44 202 [MP_F_IMPORT_NAME] = 3,
pythontech 0:5868e8752d44 203 [MP_F_IMPORT_FROM] = 2,
pythontech 0:5868e8752d44 204 [MP_F_IMPORT_ALL] = 1,
pythontech 0:5868e8752d44 205 #if MICROPY_PY_BUILTINS_SLICE
pythontech 0:5868e8752d44 206 [MP_F_NEW_SLICE] = 3,
pythontech 0:5868e8752d44 207 #endif
pythontech 0:5868e8752d44 208 [MP_F_UNPACK_SEQUENCE] = 3,
pythontech 0:5868e8752d44 209 [MP_F_UNPACK_EX] = 3,
pythontech 0:5868e8752d44 210 [MP_F_DELETE_NAME] = 1,
pythontech 0:5868e8752d44 211 [MP_F_DELETE_GLOBAL] = 1,
pythontech 0:5868e8752d44 212 [MP_F_NEW_CELL] = 1,
pythontech 0:5868e8752d44 213 [MP_F_MAKE_CLOSURE_FROM_RAW_CODE] = 3,
pythontech 0:5868e8752d44 214 [MP_F_SETUP_CODE_STATE] = 5,
pythontech 0:5868e8752d44 215 };
pythontech 0:5868e8752d44 216
pythontech 0:5868e8752d44 217 #define EXPORT_FUN(name) emit_native_x86_##name
pythontech 0:5868e8752d44 218
pythontech 0:5868e8752d44 219 #define ASM_WORD_SIZE (4)
pythontech 0:5868e8752d44 220
pythontech 0:5868e8752d44 221 #define REG_RET ASM_X86_REG_EAX
pythontech 0:5868e8752d44 222 #define REG_ARG_1 ASM_X86_REG_ARG_1
pythontech 0:5868e8752d44 223 #define REG_ARG_2 ASM_X86_REG_ARG_2
pythontech 0:5868e8752d44 224 #define REG_ARG_3 ASM_X86_REG_ARG_3
pythontech 0:5868e8752d44 225 #define REG_ARG_4 ASM_X86_REG_ARG_4
pythontech 0:5868e8752d44 226 #define REG_ARG_5 ASM_X86_REG_ARG_5
pythontech 0:5868e8752d44 227
pythontech 0:5868e8752d44 228 // caller-save, so can be used as temporaries
pythontech 0:5868e8752d44 229 #define REG_TEMP0 ASM_X86_REG_EAX
pythontech 0:5868e8752d44 230 #define REG_TEMP1 ASM_X86_REG_ECX
pythontech 0:5868e8752d44 231 #define REG_TEMP2 ASM_X86_REG_EDX
pythontech 0:5868e8752d44 232
pythontech 0:5868e8752d44 233 // callee-save, so can be used as locals
pythontech 0:5868e8752d44 234 #define REG_LOCAL_1 ASM_X86_REG_EBX
pythontech 0:5868e8752d44 235 #define REG_LOCAL_2 ASM_X86_REG_ESI
pythontech 0:5868e8752d44 236 #define REG_LOCAL_3 ASM_X86_REG_EDI
pythontech 0:5868e8752d44 237 #define REG_LOCAL_NUM (3)
pythontech 0:5868e8752d44 238
pythontech 0:5868e8752d44 239 #define ASM_PASS_COMPUTE ASM_X86_PASS_COMPUTE
pythontech 0:5868e8752d44 240 #define ASM_PASS_EMIT ASM_X86_PASS_EMIT
pythontech 0:5868e8752d44 241
pythontech 0:5868e8752d44 242 #define ASM_T asm_x86_t
pythontech 0:5868e8752d44 243 #define ASM_NEW asm_x86_new
pythontech 0:5868e8752d44 244 #define ASM_FREE asm_x86_free
pythontech 0:5868e8752d44 245 #define ASM_GET_CODE asm_x86_get_code
pythontech 0:5868e8752d44 246 #define ASM_GET_CODE_POS asm_x86_get_code_pos
pythontech 0:5868e8752d44 247 #define ASM_GET_CODE_SIZE asm_x86_get_code_size
pythontech 0:5868e8752d44 248 #define ASM_START_PASS asm_x86_start_pass
pythontech 0:5868e8752d44 249 #define ASM_END_PASS asm_x86_end_pass
pythontech 0:5868e8752d44 250 #define ASM_ENTRY asm_x86_entry
pythontech 0:5868e8752d44 251 #define ASM_EXIT asm_x86_exit
pythontech 0:5868e8752d44 252
pythontech 0:5868e8752d44 253 #define ASM_ALIGN asm_x86_align
pythontech 0:5868e8752d44 254 #define ASM_DATA asm_x86_data
pythontech 0:5868e8752d44 255
pythontech 0:5868e8752d44 256 #define ASM_LABEL_ASSIGN asm_x86_label_assign
pythontech 0:5868e8752d44 257 #define ASM_JUMP asm_x86_jmp_label
pythontech 0:5868e8752d44 258 #define ASM_JUMP_IF_REG_ZERO(as, reg, label) \
pythontech 0:5868e8752d44 259 do { \
pythontech 0:5868e8752d44 260 asm_x86_test_r8_with_r8(as, reg, reg); \
pythontech 0:5868e8752d44 261 asm_x86_jcc_label(as, ASM_X86_CC_JZ, label); \
pythontech 0:5868e8752d44 262 } while (0)
pythontech 0:5868e8752d44 263 #define ASM_JUMP_IF_REG_NONZERO(as, reg, label) \
pythontech 0:5868e8752d44 264 do { \
pythontech 0:5868e8752d44 265 asm_x86_test_r8_with_r8(as, reg, reg); \
pythontech 0:5868e8752d44 266 asm_x86_jcc_label(as, ASM_X86_CC_JNZ, label); \
pythontech 0:5868e8752d44 267 } while (0)
pythontech 0:5868e8752d44 268 #define ASM_JUMP_IF_REG_EQ(as, reg1, reg2, label) \
pythontech 0:5868e8752d44 269 do { \
pythontech 0:5868e8752d44 270 asm_x86_cmp_r32_with_r32(as, reg1, reg2); \
pythontech 0:5868e8752d44 271 asm_x86_jcc_label(as, ASM_X86_CC_JE, label); \
pythontech 0:5868e8752d44 272 } while (0)
pythontech 0:5868e8752d44 273 #define ASM_CALL_IND(as, ptr, idx) asm_x86_call_ind(as, ptr, mp_f_n_args[idx], ASM_X86_REG_EAX)
pythontech 0:5868e8752d44 274
pythontech 0:5868e8752d44 275 #define ASM_MOV_REG_TO_LOCAL asm_x86_mov_r32_to_local
pythontech 0:5868e8752d44 276 #define ASM_MOV_IMM_TO_REG asm_x86_mov_i32_to_r32
pythontech 0:5868e8752d44 277 #define ASM_MOV_ALIGNED_IMM_TO_REG asm_x86_mov_i32_to_r32_aligned
pythontech 0:5868e8752d44 278 #define ASM_MOV_IMM_TO_LOCAL_USING(as, imm, local_num, reg_temp) \
pythontech 0:5868e8752d44 279 do { \
pythontech 0:5868e8752d44 280 asm_x86_mov_i32_to_r32(as, (imm), (reg_temp)); \
pythontech 0:5868e8752d44 281 asm_x86_mov_r32_to_local(as, (reg_temp), (local_num)); \
pythontech 0:5868e8752d44 282 } while (false)
pythontech 0:5868e8752d44 283 #define ASM_MOV_LOCAL_TO_REG asm_x86_mov_local_to_r32
pythontech 0:5868e8752d44 284 #define ASM_MOV_REG_REG(as, reg_dest, reg_src) asm_x86_mov_r32_r32((as), (reg_dest), (reg_src))
pythontech 0:5868e8752d44 285 #define ASM_MOV_LOCAL_ADDR_TO_REG asm_x86_mov_local_addr_to_r32
pythontech 0:5868e8752d44 286
pythontech 0:5868e8752d44 287 #define ASM_LSL_REG(as, reg) asm_x86_shl_r32_cl((as), (reg))
pythontech 0:5868e8752d44 288 #define ASM_ASR_REG(as, reg) asm_x86_sar_r32_cl((as), (reg))
pythontech 0:5868e8752d44 289 #define ASM_OR_REG_REG(as, reg_dest, reg_src) asm_x86_or_r32_r32((as), (reg_dest), (reg_src))
pythontech 0:5868e8752d44 290 #define ASM_XOR_REG_REG(as, reg_dest, reg_src) asm_x86_xor_r32_r32((as), (reg_dest), (reg_src))
pythontech 0:5868e8752d44 291 #define ASM_AND_REG_REG(as, reg_dest, reg_src) asm_x86_and_r32_r32((as), (reg_dest), (reg_src))
pythontech 0:5868e8752d44 292 #define ASM_ADD_REG_REG(as, reg_dest, reg_src) asm_x86_add_r32_r32((as), (reg_dest), (reg_src))
pythontech 0:5868e8752d44 293 #define ASM_SUB_REG_REG(as, reg_dest, reg_src) asm_x86_sub_r32_r32((as), (reg_dest), (reg_src))
pythontech 0:5868e8752d44 294 #define ASM_MUL_REG_REG(as, reg_dest, reg_src) asm_x86_mul_r32_r32((as), (reg_dest), (reg_src))
pythontech 0:5868e8752d44 295
pythontech 0:5868e8752d44 296 #define ASM_LOAD_REG_REG(as, reg_dest, reg_base) asm_x86_mov_mem32_to_r32((as), (reg_base), 0, (reg_dest))
pythontech 0:5868e8752d44 297 #define ASM_LOAD_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) asm_x86_mov_mem32_to_r32((as), (reg_base), 4 * (word_offset), (reg_dest))
pythontech 0:5868e8752d44 298 #define ASM_LOAD8_REG_REG(as, reg_dest, reg_base) asm_x86_mov_mem8_to_r32zx((as), (reg_base), 0, (reg_dest))
pythontech 0:5868e8752d44 299 #define ASM_LOAD16_REG_REG(as, reg_dest, reg_base) asm_x86_mov_mem16_to_r32zx((as), (reg_base), 0, (reg_dest))
pythontech 0:5868e8752d44 300 #define ASM_LOAD32_REG_REG(as, reg_dest, reg_base) asm_x86_mov_mem32_to_r32((as), (reg_base), 0, (reg_dest))
pythontech 0:5868e8752d44 301
pythontech 0:5868e8752d44 302 #define ASM_STORE_REG_REG(as, reg_src, reg_base) asm_x86_mov_r32_to_mem32((as), (reg_src), (reg_base), 0)
pythontech 0:5868e8752d44 303 #define ASM_STORE_REG_REG_OFFSET(as, reg_src, reg_base, word_offset) asm_x86_mov_r32_to_mem32((as), (reg_src), (reg_base), 4 * (word_offset))
pythontech 0:5868e8752d44 304 #define ASM_STORE8_REG_REG(as, reg_src, reg_base) asm_x86_mov_r8_to_mem8((as), (reg_src), (reg_base), 0)
pythontech 0:5868e8752d44 305 #define ASM_STORE16_REG_REG(as, reg_src, reg_base) asm_x86_mov_r16_to_mem16((as), (reg_src), (reg_base), 0)
pythontech 0:5868e8752d44 306 #define ASM_STORE32_REG_REG(as, reg_src, reg_base) asm_x86_mov_r32_to_mem32((as), (reg_src), (reg_base), 0)
pythontech 0:5868e8752d44 307
pythontech 0:5868e8752d44 308 #elif N_THUMB
pythontech 0:5868e8752d44 309
pythontech 0:5868e8752d44 310 // thumb specific stuff
pythontech 0:5868e8752d44 311
pythontech 0:5868e8752d44 312 #include "py/asmthumb.h"
pythontech 0:5868e8752d44 313
pythontech 0:5868e8752d44 314 #define EXPORT_FUN(name) emit_native_thumb_##name
pythontech 0:5868e8752d44 315
pythontech 0:5868e8752d44 316 #define ASM_WORD_SIZE (4)
pythontech 0:5868e8752d44 317
pythontech 0:5868e8752d44 318 #define REG_RET ASM_THUMB_REG_R0
pythontech 0:5868e8752d44 319 #define REG_ARG_1 ASM_THUMB_REG_R0
pythontech 0:5868e8752d44 320 #define REG_ARG_2 ASM_THUMB_REG_R1
pythontech 0:5868e8752d44 321 #define REG_ARG_3 ASM_THUMB_REG_R2
pythontech 0:5868e8752d44 322 #define REG_ARG_4 ASM_THUMB_REG_R3
pythontech 0:5868e8752d44 323 // rest of args go on stack
pythontech 0:5868e8752d44 324
pythontech 0:5868e8752d44 325 #define REG_TEMP0 ASM_THUMB_REG_R0
pythontech 0:5868e8752d44 326 #define REG_TEMP1 ASM_THUMB_REG_R1
pythontech 0:5868e8752d44 327 #define REG_TEMP2 ASM_THUMB_REG_R2
pythontech 0:5868e8752d44 328
pythontech 0:5868e8752d44 329 #define REG_LOCAL_1 ASM_THUMB_REG_R4
pythontech 0:5868e8752d44 330 #define REG_LOCAL_2 ASM_THUMB_REG_R5
pythontech 0:5868e8752d44 331 #define REG_LOCAL_3 ASM_THUMB_REG_R6
pythontech 0:5868e8752d44 332 #define REG_LOCAL_NUM (3)
pythontech 0:5868e8752d44 333
pythontech 0:5868e8752d44 334 #define ASM_PASS_COMPUTE ASM_THUMB_PASS_COMPUTE
pythontech 0:5868e8752d44 335 #define ASM_PASS_EMIT ASM_THUMB_PASS_EMIT
pythontech 0:5868e8752d44 336
pythontech 0:5868e8752d44 337 #define ASM_T asm_thumb_t
pythontech 0:5868e8752d44 338 #define ASM_NEW asm_thumb_new
pythontech 0:5868e8752d44 339 #define ASM_FREE asm_thumb_free
pythontech 0:5868e8752d44 340 #define ASM_GET_CODE asm_thumb_get_code
pythontech 0:5868e8752d44 341 #define ASM_GET_CODE_POS asm_thumb_get_code_pos
pythontech 0:5868e8752d44 342 #define ASM_GET_CODE_SIZE asm_thumb_get_code_size
pythontech 0:5868e8752d44 343 #define ASM_START_PASS asm_thumb_start_pass
pythontech 0:5868e8752d44 344 #define ASM_END_PASS asm_thumb_end_pass
pythontech 0:5868e8752d44 345 #define ASM_ENTRY asm_thumb_entry
pythontech 0:5868e8752d44 346 #define ASM_EXIT asm_thumb_exit
pythontech 0:5868e8752d44 347
pythontech 0:5868e8752d44 348 #define ASM_ALIGN asm_thumb_align
pythontech 0:5868e8752d44 349 #define ASM_DATA asm_thumb_data
pythontech 0:5868e8752d44 350
pythontech 0:5868e8752d44 351 #define ASM_LABEL_ASSIGN asm_thumb_label_assign
pythontech 0:5868e8752d44 352 #define ASM_JUMP asm_thumb_b_label
pythontech 0:5868e8752d44 353 #define ASM_JUMP_IF_REG_ZERO(as, reg, label) \
pythontech 0:5868e8752d44 354 do { \
pythontech 0:5868e8752d44 355 asm_thumb_cmp_rlo_i8(as, reg, 0); \
pythontech 0:5868e8752d44 356 asm_thumb_bcc_label(as, ASM_THUMB_CC_EQ, label); \
pythontech 0:5868e8752d44 357 } while (0)
pythontech 0:5868e8752d44 358 #define ASM_JUMP_IF_REG_NONZERO(as, reg, label) \
pythontech 0:5868e8752d44 359 do { \
pythontech 0:5868e8752d44 360 asm_thumb_cmp_rlo_i8(as, reg, 0); \
pythontech 0:5868e8752d44 361 asm_thumb_bcc_label(as, ASM_THUMB_CC_NE, label); \
pythontech 0:5868e8752d44 362 } while (0)
pythontech 0:5868e8752d44 363 #define ASM_JUMP_IF_REG_EQ(as, reg1, reg2, label) \
pythontech 0:5868e8752d44 364 do { \
pythontech 0:5868e8752d44 365 asm_thumb_cmp_rlo_rlo(as, reg1, reg2); \
pythontech 0:5868e8752d44 366 asm_thumb_bcc_label(as, ASM_THUMB_CC_EQ, label); \
pythontech 0:5868e8752d44 367 } while (0)
pythontech 0:5868e8752d44 368 #define ASM_CALL_IND(as, ptr, idx) asm_thumb_bl_ind(as, ptr, idx, ASM_THUMB_REG_R3)
pythontech 0:5868e8752d44 369
pythontech 0:5868e8752d44 370 #define ASM_MOV_REG_TO_LOCAL(as, reg, local_num) asm_thumb_mov_local_reg(as, (local_num), (reg))
pythontech 0:5868e8752d44 371 #define ASM_MOV_IMM_TO_REG(as, imm, reg) asm_thumb_mov_reg_i32_optimised(as, (reg), (imm))
pythontech 0:5868e8752d44 372 #define ASM_MOV_ALIGNED_IMM_TO_REG(as, imm, reg) asm_thumb_mov_reg_i32_aligned(as, (reg), (imm))
pythontech 0:5868e8752d44 373 #define ASM_MOV_IMM_TO_LOCAL_USING(as, imm, local_num, reg_temp) \
pythontech 0:5868e8752d44 374 do { \
pythontech 0:5868e8752d44 375 asm_thumb_mov_reg_i32_optimised(as, (reg_temp), (imm)); \
pythontech 0:5868e8752d44 376 asm_thumb_mov_local_reg(as, (local_num), (reg_temp)); \
pythontech 0:5868e8752d44 377 } while (false)
pythontech 0:5868e8752d44 378 #define ASM_MOV_LOCAL_TO_REG(as, local_num, reg) asm_thumb_mov_reg_local(as, (reg), (local_num))
pythontech 0:5868e8752d44 379 #define ASM_MOV_REG_REG(as, reg_dest, reg_src) asm_thumb_mov_reg_reg((as), (reg_dest), (reg_src))
pythontech 0:5868e8752d44 380 #define ASM_MOV_LOCAL_ADDR_TO_REG(as, local_num, reg) asm_thumb_mov_reg_local_addr(as, (reg), (local_num))
pythontech 0:5868e8752d44 381
pythontech 0:5868e8752d44 382 #define ASM_LSL_REG_REG(as, reg_dest, reg_shift) asm_thumb_format_4((as), ASM_THUMB_FORMAT_4_LSL, (reg_dest), (reg_shift))
pythontech 0:5868e8752d44 383 #define ASM_ASR_REG_REG(as, reg_dest, reg_shift) asm_thumb_format_4((as), ASM_THUMB_FORMAT_4_ASR, (reg_dest), (reg_shift))
pythontech 0:5868e8752d44 384 #define ASM_OR_REG_REG(as, reg_dest, reg_src) asm_thumb_format_4((as), ASM_THUMB_FORMAT_4_ORR, (reg_dest), (reg_src))
pythontech 0:5868e8752d44 385 #define ASM_XOR_REG_REG(as, reg_dest, reg_src) asm_thumb_format_4((as), ASM_THUMB_FORMAT_4_EOR, (reg_dest), (reg_src))
pythontech 0:5868e8752d44 386 #define ASM_AND_REG_REG(as, reg_dest, reg_src) asm_thumb_format_4((as), ASM_THUMB_FORMAT_4_AND, (reg_dest), (reg_src))
pythontech 0:5868e8752d44 387 #define ASM_ADD_REG_REG(as, reg_dest, reg_src) asm_thumb_add_rlo_rlo_rlo((as), (reg_dest), (reg_dest), (reg_src))
pythontech 0:5868e8752d44 388 #define ASM_SUB_REG_REG(as, reg_dest, reg_src) asm_thumb_sub_rlo_rlo_rlo((as), (reg_dest), (reg_dest), (reg_src))
pythontech 0:5868e8752d44 389 #define ASM_MUL_REG_REG(as, reg_dest, reg_src) asm_thumb_format_4((as), ASM_THUMB_FORMAT_4_MUL, (reg_dest), (reg_src))
pythontech 0:5868e8752d44 390
pythontech 0:5868e8752d44 391 #define ASM_LOAD_REG_REG(as, reg_dest, reg_base) asm_thumb_ldr_rlo_rlo_i5((as), (reg_dest), (reg_base), 0)
pythontech 0:5868e8752d44 392 #define ASM_LOAD_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) asm_thumb_ldr_rlo_rlo_i5((as), (reg_dest), (reg_base), (word_offset))
pythontech 0:5868e8752d44 393 #define ASM_LOAD8_REG_REG(as, reg_dest, reg_base) asm_thumb_ldrb_rlo_rlo_i5((as), (reg_dest), (reg_base), 0)
pythontech 0:5868e8752d44 394 #define ASM_LOAD16_REG_REG(as, reg_dest, reg_base) asm_thumb_ldrh_rlo_rlo_i5((as), (reg_dest), (reg_base), 0)
pythontech 0:5868e8752d44 395 #define ASM_LOAD32_REG_REG(as, reg_dest, reg_base) asm_thumb_ldr_rlo_rlo_i5((as), (reg_dest), (reg_base), 0)
pythontech 0:5868e8752d44 396
pythontech 0:5868e8752d44 397 #define ASM_STORE_REG_REG(as, reg_src, reg_base) asm_thumb_str_rlo_rlo_i5((as), (reg_src), (reg_base), 0)
pythontech 0:5868e8752d44 398 #define ASM_STORE_REG_REG_OFFSET(as, reg_src, reg_base, word_offset) asm_thumb_str_rlo_rlo_i5((as), (reg_src), (reg_base), (word_offset))
pythontech 0:5868e8752d44 399 #define ASM_STORE8_REG_REG(as, reg_src, reg_base) asm_thumb_strb_rlo_rlo_i5((as), (reg_src), (reg_base), 0)
pythontech 0:5868e8752d44 400 #define ASM_STORE16_REG_REG(as, reg_src, reg_base) asm_thumb_strh_rlo_rlo_i5((as), (reg_src), (reg_base), 0)
pythontech 0:5868e8752d44 401 #define ASM_STORE32_REG_REG(as, reg_src, reg_base) asm_thumb_str_rlo_rlo_i5((as), (reg_src), (reg_base), 0)
pythontech 0:5868e8752d44 402
pythontech 0:5868e8752d44 403 #elif N_ARM
pythontech 0:5868e8752d44 404
pythontech 0:5868e8752d44 405 // ARM specific stuff
pythontech 0:5868e8752d44 406
pythontech 0:5868e8752d44 407 #include "py/asmarm.h"
pythontech 0:5868e8752d44 408
pythontech 0:5868e8752d44 409 #define ASM_WORD_SIZE (4)
pythontech 0:5868e8752d44 410
pythontech 0:5868e8752d44 411 #define EXPORT_FUN(name) emit_native_arm_##name
pythontech 0:5868e8752d44 412
pythontech 0:5868e8752d44 413 #define REG_RET ASM_ARM_REG_R0
pythontech 0:5868e8752d44 414 #define REG_ARG_1 ASM_ARM_REG_R0
pythontech 0:5868e8752d44 415 #define REG_ARG_2 ASM_ARM_REG_R1
pythontech 0:5868e8752d44 416 #define REG_ARG_3 ASM_ARM_REG_R2
pythontech 0:5868e8752d44 417 #define REG_ARG_4 ASM_ARM_REG_R3
pythontech 0:5868e8752d44 418
pythontech 0:5868e8752d44 419 #define REG_TEMP0 ASM_ARM_REG_R0
pythontech 0:5868e8752d44 420 #define REG_TEMP1 ASM_ARM_REG_R1
pythontech 0:5868e8752d44 421 #define REG_TEMP2 ASM_ARM_REG_R2
pythontech 0:5868e8752d44 422
pythontech 0:5868e8752d44 423 #define REG_LOCAL_1 ASM_ARM_REG_R4
pythontech 0:5868e8752d44 424 #define REG_LOCAL_2 ASM_ARM_REG_R5
pythontech 0:5868e8752d44 425 #define REG_LOCAL_3 ASM_ARM_REG_R6
pythontech 0:5868e8752d44 426 #define REG_LOCAL_NUM (3)
pythontech 0:5868e8752d44 427
pythontech 0:5868e8752d44 428 #define ASM_PASS_COMPUTE ASM_ARM_PASS_COMPUTE
pythontech 0:5868e8752d44 429 #define ASM_PASS_EMIT ASM_ARM_PASS_EMIT
pythontech 0:5868e8752d44 430
pythontech 0:5868e8752d44 431 #define ASM_T asm_arm_t
pythontech 0:5868e8752d44 432 #define ASM_NEW asm_arm_new
pythontech 0:5868e8752d44 433 #define ASM_FREE asm_arm_free
pythontech 0:5868e8752d44 434 #define ASM_GET_CODE asm_arm_get_code
pythontech 0:5868e8752d44 435 #define ASM_GET_CODE_POS asm_arm_get_code_pos
pythontech 0:5868e8752d44 436 #define ASM_GET_CODE_SIZE asm_arm_get_code_size
pythontech 0:5868e8752d44 437 #define ASM_START_PASS asm_arm_start_pass
pythontech 0:5868e8752d44 438 #define ASM_END_PASS asm_arm_end_pass
pythontech 0:5868e8752d44 439 #define ASM_ENTRY asm_arm_entry
pythontech 0:5868e8752d44 440 #define ASM_EXIT asm_arm_exit
pythontech 0:5868e8752d44 441
pythontech 0:5868e8752d44 442 #define ASM_ALIGN asm_arm_align
pythontech 0:5868e8752d44 443 #define ASM_DATA asm_arm_data
pythontech 0:5868e8752d44 444
pythontech 0:5868e8752d44 445 #define ASM_LABEL_ASSIGN asm_arm_label_assign
pythontech 0:5868e8752d44 446 #define ASM_JUMP asm_arm_b_label
pythontech 0:5868e8752d44 447 #define ASM_JUMP_IF_REG_ZERO(as, reg, label) \
pythontech 0:5868e8752d44 448 do { \
pythontech 0:5868e8752d44 449 asm_arm_cmp_reg_i8(as, reg, 0); \
pythontech 0:5868e8752d44 450 asm_arm_bcc_label(as, ASM_ARM_CC_EQ, label); \
pythontech 0:5868e8752d44 451 } while (0)
pythontech 0:5868e8752d44 452 #define ASM_JUMP_IF_REG_NONZERO(as, reg, label) \
pythontech 0:5868e8752d44 453 do { \
pythontech 0:5868e8752d44 454 asm_arm_cmp_reg_i8(as, reg, 0); \
pythontech 0:5868e8752d44 455 asm_arm_bcc_label(as, ASM_ARM_CC_NE, label); \
pythontech 0:5868e8752d44 456 } while (0)
pythontech 0:5868e8752d44 457 #define ASM_JUMP_IF_REG_EQ(as, reg1, reg2, label) \
pythontech 0:5868e8752d44 458 do { \
pythontech 0:5868e8752d44 459 asm_arm_cmp_reg_reg(as, reg1, reg2); \
pythontech 0:5868e8752d44 460 asm_arm_bcc_label(as, ASM_ARM_CC_EQ, label); \
pythontech 0:5868e8752d44 461 } while (0)
pythontech 0:5868e8752d44 462 #define ASM_CALL_IND(as, ptr, idx) asm_arm_bl_ind(as, ptr, idx, ASM_ARM_REG_R3)
pythontech 0:5868e8752d44 463
pythontech 0:5868e8752d44 464 #define ASM_MOV_REG_TO_LOCAL(as, reg, local_num) asm_arm_mov_local_reg(as, (local_num), (reg))
pythontech 0:5868e8752d44 465 #define ASM_MOV_IMM_TO_REG(as, imm, reg) asm_arm_mov_reg_i32(as, (reg), (imm))
pythontech 0:5868e8752d44 466 #define ASM_MOV_ALIGNED_IMM_TO_REG(as, imm, reg) asm_arm_mov_reg_i32(as, (reg), (imm))
pythontech 0:5868e8752d44 467 #define ASM_MOV_IMM_TO_LOCAL_USING(as, imm, local_num, reg_temp) \
pythontech 0:5868e8752d44 468 do { \
pythontech 0:5868e8752d44 469 asm_arm_mov_reg_i32(as, (reg_temp), (imm)); \
pythontech 0:5868e8752d44 470 asm_arm_mov_local_reg(as, (local_num), (reg_temp)); \
pythontech 0:5868e8752d44 471 } while (false)
pythontech 0:5868e8752d44 472 #define ASM_MOV_LOCAL_TO_REG(as, local_num, reg) asm_arm_mov_reg_local(as, (reg), (local_num))
pythontech 0:5868e8752d44 473 #define ASM_MOV_REG_REG(as, reg_dest, reg_src) asm_arm_mov_reg_reg((as), (reg_dest), (reg_src))
pythontech 0:5868e8752d44 474 #define ASM_MOV_LOCAL_ADDR_TO_REG(as, local_num, reg) asm_arm_mov_reg_local_addr(as, (reg), (local_num))
pythontech 0:5868e8752d44 475
pythontech 0:5868e8752d44 476 #define ASM_LSL_REG_REG(as, reg_dest, reg_shift) asm_arm_lsl_reg_reg((as), (reg_dest), (reg_shift))
pythontech 0:5868e8752d44 477 #define ASM_ASR_REG_REG(as, reg_dest, reg_shift) asm_arm_asr_reg_reg((as), (reg_dest), (reg_shift))
pythontech 0:5868e8752d44 478 #define ASM_OR_REG_REG(as, reg_dest, reg_src) asm_arm_orr_reg_reg_reg((as), (reg_dest), (reg_dest), (reg_src))
pythontech 0:5868e8752d44 479 #define ASM_XOR_REG_REG(as, reg_dest, reg_src) asm_arm_eor_reg_reg_reg((as), (reg_dest), (reg_dest), (reg_src))
pythontech 0:5868e8752d44 480 #define ASM_AND_REG_REG(as, reg_dest, reg_src) asm_arm_and_reg_reg_reg((as), (reg_dest), (reg_dest), (reg_src))
pythontech 0:5868e8752d44 481 #define ASM_ADD_REG_REG(as, reg_dest, reg_src) asm_arm_add_reg_reg_reg((as), (reg_dest), (reg_dest), (reg_src))
pythontech 0:5868e8752d44 482 #define ASM_SUB_REG_REG(as, reg_dest, reg_src) asm_arm_sub_reg_reg_reg((as), (reg_dest), (reg_dest), (reg_src))
pythontech 0:5868e8752d44 483 #define ASM_MUL_REG_REG(as, reg_dest, reg_src) asm_arm_mul_reg_reg_reg((as), (reg_dest), (reg_dest), (reg_src))
pythontech 0:5868e8752d44 484
pythontech 0:5868e8752d44 485 #define ASM_LOAD_REG_REG(as, reg_dest, reg_base) asm_arm_ldr_reg_reg((as), (reg_dest), (reg_base), 0)
pythontech 0:5868e8752d44 486 #define ASM_LOAD_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) asm_arm_ldr_reg_reg((as), (reg_dest), (reg_base), 4 * (word_offset))
pythontech 0:5868e8752d44 487 #define ASM_LOAD8_REG_REG(as, reg_dest, reg_base) asm_arm_ldrb_reg_reg((as), (reg_dest), (reg_base))
pythontech 0:5868e8752d44 488 #define ASM_LOAD16_REG_REG(as, reg_dest, reg_base) asm_arm_ldrh_reg_reg((as), (reg_dest), (reg_base))
pythontech 0:5868e8752d44 489 #define ASM_LOAD32_REG_REG(as, reg_dest, reg_base) asm_arm_ldr_reg_reg((as), (reg_dest), (reg_base), 0)
pythontech 0:5868e8752d44 490
pythontech 0:5868e8752d44 491 #define ASM_STORE_REG_REG(as, reg_value, reg_base) asm_arm_str_reg_reg((as), (reg_value), (reg_base), 0)
pythontech 0:5868e8752d44 492 #define ASM_STORE_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) asm_arm_str_reg_reg((as), (reg_dest), (reg_base), 4 * (word_offset))
pythontech 0:5868e8752d44 493 #define ASM_STORE8_REG_REG(as, reg_value, reg_base) asm_arm_strb_reg_reg((as), (reg_value), (reg_base))
pythontech 0:5868e8752d44 494 #define ASM_STORE16_REG_REG(as, reg_value, reg_base) asm_arm_strh_reg_reg((as), (reg_value), (reg_base))
pythontech 0:5868e8752d44 495 #define ASM_STORE32_REG_REG(as, reg_value, reg_base) asm_arm_str_reg_reg((as), (reg_value), (reg_base), 0)
pythontech 0:5868e8752d44 496
pythontech 0:5868e8752d44 497 #else
pythontech 0:5868e8752d44 498
pythontech 0:5868e8752d44 499 #error unknown native emitter
pythontech 0:5868e8752d44 500
pythontech 0:5868e8752d44 501 #endif
pythontech 0:5868e8752d44 502
pythontech 0:5868e8752d44 503 #define EMIT_NATIVE_VIPER_TYPE_ERROR(emit, ...) do { \
pythontech 0:5868e8752d44 504 *emit->error_slot = mp_obj_new_exception_msg_varg(&mp_type_ViperTypeError, __VA_ARGS__); \
pythontech 0:5868e8752d44 505 } while (0)
pythontech 0:5868e8752d44 506
pythontech 0:5868e8752d44 507 typedef enum {
pythontech 0:5868e8752d44 508 STACK_VALUE,
pythontech 0:5868e8752d44 509 STACK_REG,
pythontech 0:5868e8752d44 510 STACK_IMM,
pythontech 0:5868e8752d44 511 } stack_info_kind_t;
pythontech 0:5868e8752d44 512
pythontech 0:5868e8752d44 513 // these enums must be distinct and the bottom 4 bits
pythontech 0:5868e8752d44 514 // must correspond to the correct MP_NATIVE_TYPE_xxx value
pythontech 0:5868e8752d44 515 typedef enum {
pythontech 0:5868e8752d44 516 VTYPE_PYOBJ = 0x00 | MP_NATIVE_TYPE_OBJ,
pythontech 0:5868e8752d44 517 VTYPE_BOOL = 0x00 | MP_NATIVE_TYPE_BOOL,
pythontech 0:5868e8752d44 518 VTYPE_INT = 0x00 | MP_NATIVE_TYPE_INT,
pythontech 0:5868e8752d44 519 VTYPE_UINT = 0x00 | MP_NATIVE_TYPE_UINT,
pythontech 0:5868e8752d44 520 VTYPE_PTR = 0x00 | MP_NATIVE_TYPE_PTR,
pythontech 0:5868e8752d44 521 VTYPE_PTR8 = 0x00 | MP_NATIVE_TYPE_PTR8,
pythontech 0:5868e8752d44 522 VTYPE_PTR16 = 0x00 | MP_NATIVE_TYPE_PTR16,
pythontech 0:5868e8752d44 523 VTYPE_PTR32 = 0x00 | MP_NATIVE_TYPE_PTR32,
pythontech 0:5868e8752d44 524
pythontech 0:5868e8752d44 525 VTYPE_PTR_NONE = 0x50 | MP_NATIVE_TYPE_PTR,
pythontech 0:5868e8752d44 526
pythontech 0:5868e8752d44 527 VTYPE_UNBOUND = 0x60 | MP_NATIVE_TYPE_OBJ,
pythontech 0:5868e8752d44 528 VTYPE_BUILTIN_CAST = 0x70 | MP_NATIVE_TYPE_OBJ,
pythontech 0:5868e8752d44 529 } vtype_kind_t;
pythontech 0:5868e8752d44 530
pythontech 0:5868e8752d44 531 STATIC qstr vtype_to_qstr(vtype_kind_t vtype) {
pythontech 0:5868e8752d44 532 switch (vtype) {
pythontech 0:5868e8752d44 533 case VTYPE_PYOBJ: return MP_QSTR_object;
pythontech 0:5868e8752d44 534 case VTYPE_BOOL: return MP_QSTR_bool;
pythontech 0:5868e8752d44 535 case VTYPE_INT: return MP_QSTR_int;
pythontech 0:5868e8752d44 536 case VTYPE_UINT: return MP_QSTR_uint;
pythontech 0:5868e8752d44 537 case VTYPE_PTR: return MP_QSTR_ptr;
pythontech 0:5868e8752d44 538 case VTYPE_PTR8: return MP_QSTR_ptr8;
pythontech 0:5868e8752d44 539 case VTYPE_PTR16: return MP_QSTR_ptr16;
pythontech 0:5868e8752d44 540 case VTYPE_PTR32: return MP_QSTR_ptr32;
pythontech 0:5868e8752d44 541 case VTYPE_PTR_NONE: default: return MP_QSTR_None;
pythontech 0:5868e8752d44 542 }
pythontech 0:5868e8752d44 543 }
pythontech 0:5868e8752d44 544
pythontech 0:5868e8752d44 545 typedef struct _stack_info_t {
pythontech 0:5868e8752d44 546 vtype_kind_t vtype;
pythontech 0:5868e8752d44 547 stack_info_kind_t kind;
pythontech 0:5868e8752d44 548 union {
pythontech 0:5868e8752d44 549 int u_reg;
pythontech 0:5868e8752d44 550 mp_int_t u_imm;
pythontech 0:5868e8752d44 551 } data;
pythontech 0:5868e8752d44 552 } stack_info_t;
pythontech 0:5868e8752d44 553
pythontech 0:5868e8752d44 554 struct _emit_t {
pythontech 0:5868e8752d44 555 mp_obj_t *error_slot;
pythontech 0:5868e8752d44 556 int pass;
pythontech 0:5868e8752d44 557
pythontech 0:5868e8752d44 558 bool do_viper_types;
pythontech 0:5868e8752d44 559
pythontech 0:5868e8752d44 560 vtype_kind_t return_vtype;
pythontech 0:5868e8752d44 561
pythontech 0:5868e8752d44 562 mp_uint_t local_vtype_alloc;
pythontech 0:5868e8752d44 563 vtype_kind_t *local_vtype;
pythontech 0:5868e8752d44 564
pythontech 0:5868e8752d44 565 mp_uint_t stack_info_alloc;
pythontech 0:5868e8752d44 566 stack_info_t *stack_info;
pythontech 0:5868e8752d44 567 vtype_kind_t saved_stack_vtype;
pythontech 0:5868e8752d44 568
pythontech 0:5868e8752d44 569 int prelude_offset;
pythontech 0:5868e8752d44 570 int const_table_offset;
pythontech 0:5868e8752d44 571 int n_state;
pythontech 0:5868e8752d44 572 int stack_start;
pythontech 0:5868e8752d44 573 int stack_size;
pythontech 0:5868e8752d44 574
pythontech 0:5868e8752d44 575 bool last_emit_was_return_value;
pythontech 0:5868e8752d44 576
pythontech 0:5868e8752d44 577 scope_t *scope;
pythontech 0:5868e8752d44 578
pythontech 0:5868e8752d44 579 ASM_T *as;
pythontech 0:5868e8752d44 580 };
pythontech 0:5868e8752d44 581
pythontech 0:5868e8752d44 582 emit_t *EXPORT_FUN(new)(mp_obj_t *error_slot, mp_uint_t max_num_labels) {
pythontech 0:5868e8752d44 583 emit_t *emit = m_new0(emit_t, 1);
pythontech 0:5868e8752d44 584 emit->error_slot = error_slot;
pythontech 0:5868e8752d44 585 emit->as = ASM_NEW(max_num_labels);
pythontech 0:5868e8752d44 586 return emit;
pythontech 0:5868e8752d44 587 }
pythontech 0:5868e8752d44 588
pythontech 0:5868e8752d44 589 void EXPORT_FUN(free)(emit_t *emit) {
pythontech 0:5868e8752d44 590 ASM_FREE(emit->as, false);
pythontech 0:5868e8752d44 591 m_del(vtype_kind_t, emit->local_vtype, emit->local_vtype_alloc);
pythontech 0:5868e8752d44 592 m_del(stack_info_t, emit->stack_info, emit->stack_info_alloc);
pythontech 0:5868e8752d44 593 m_del_obj(emit_t, emit);
pythontech 0:5868e8752d44 594 }
pythontech 0:5868e8752d44 595
pythontech 0:5868e8752d44 596 STATIC void emit_native_set_native_type(emit_t *emit, mp_uint_t op, mp_uint_t arg1, qstr arg2) {
pythontech 0:5868e8752d44 597 switch (op) {
pythontech 0:5868e8752d44 598 case MP_EMIT_NATIVE_TYPE_ENABLE:
pythontech 0:5868e8752d44 599 emit->do_viper_types = arg1;
pythontech 0:5868e8752d44 600 break;
pythontech 0:5868e8752d44 601
pythontech 0:5868e8752d44 602 default: {
pythontech 0:5868e8752d44 603 vtype_kind_t type;
pythontech 0:5868e8752d44 604 switch (arg2) {
pythontech 0:5868e8752d44 605 case MP_QSTR_object: type = VTYPE_PYOBJ; break;
pythontech 0:5868e8752d44 606 case MP_QSTR_bool: type = VTYPE_BOOL; break;
pythontech 0:5868e8752d44 607 case MP_QSTR_int: type = VTYPE_INT; break;
pythontech 0:5868e8752d44 608 case MP_QSTR_uint: type = VTYPE_UINT; break;
pythontech 0:5868e8752d44 609 case MP_QSTR_ptr: type = VTYPE_PTR; break;
pythontech 0:5868e8752d44 610 case MP_QSTR_ptr8: type = VTYPE_PTR8; break;
pythontech 0:5868e8752d44 611 case MP_QSTR_ptr16: type = VTYPE_PTR16; break;
pythontech 0:5868e8752d44 612 case MP_QSTR_ptr32: type = VTYPE_PTR32; break;
pythontech 0:5868e8752d44 613 default: EMIT_NATIVE_VIPER_TYPE_ERROR(emit, "unknown type '%q'", arg2); return;
pythontech 0:5868e8752d44 614 }
pythontech 0:5868e8752d44 615 if (op == MP_EMIT_NATIVE_TYPE_RETURN) {
pythontech 0:5868e8752d44 616 emit->return_vtype = type;
pythontech 0:5868e8752d44 617 } else {
pythontech 0:5868e8752d44 618 assert(arg1 < emit->local_vtype_alloc);
pythontech 0:5868e8752d44 619 emit->local_vtype[arg1] = type;
pythontech 0:5868e8752d44 620 }
pythontech 0:5868e8752d44 621 break;
pythontech 0:5868e8752d44 622 }
pythontech 0:5868e8752d44 623 }
pythontech 0:5868e8752d44 624 }
pythontech 0:5868e8752d44 625
pythontech 0:5868e8752d44 626 STATIC void emit_pre_pop_reg(emit_t *emit, vtype_kind_t *vtype, int reg_dest);
pythontech 0:5868e8752d44 627 STATIC void emit_post_push_reg(emit_t *emit, vtype_kind_t vtype, int reg);
pythontech 0:5868e8752d44 628 STATIC void emit_native_load_fast(emit_t *emit, qstr qst, mp_uint_t local_num);
pythontech 0:5868e8752d44 629 STATIC void emit_native_store_fast(emit_t *emit, qstr qst, mp_uint_t local_num);
pythontech 0:5868e8752d44 630
pythontech 0:5868e8752d44 631 #define STATE_START (sizeof(mp_code_state) / sizeof(mp_uint_t))
pythontech 0:5868e8752d44 632
pythontech 0:5868e8752d44 633 STATIC void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) {
pythontech 0:5868e8752d44 634 DEBUG_printf("start_pass(pass=%u, scope=%p)\n", pass, scope);
pythontech 0:5868e8752d44 635
pythontech 0:5868e8752d44 636 emit->pass = pass;
pythontech 0:5868e8752d44 637 emit->stack_start = 0;
pythontech 0:5868e8752d44 638 emit->stack_size = 0;
pythontech 0:5868e8752d44 639 emit->last_emit_was_return_value = false;
pythontech 0:5868e8752d44 640 emit->scope = scope;
pythontech 0:5868e8752d44 641
pythontech 0:5868e8752d44 642 // allocate memory for keeping track of the types of locals
pythontech 0:5868e8752d44 643 if (emit->local_vtype_alloc < scope->num_locals) {
pythontech 0:5868e8752d44 644 emit->local_vtype = m_renew(vtype_kind_t, emit->local_vtype, emit->local_vtype_alloc, scope->num_locals);
pythontech 0:5868e8752d44 645 emit->local_vtype_alloc = scope->num_locals;
pythontech 0:5868e8752d44 646 }
pythontech 0:5868e8752d44 647
pythontech 0:5868e8752d44 648 // allocate memory for keeping track of the objects on the stack
pythontech 0:5868e8752d44 649 // XXX don't know stack size on entry, and it should be maximum over all scopes
pythontech 0:5868e8752d44 650 // XXX this is such a big hack and really needs to be fixed
pythontech 0:5868e8752d44 651 if (emit->stack_info == NULL) {
pythontech 0:5868e8752d44 652 emit->stack_info_alloc = scope->stack_size + 200;
pythontech 0:5868e8752d44 653 emit->stack_info = m_new(stack_info_t, emit->stack_info_alloc);
pythontech 0:5868e8752d44 654 }
pythontech 0:5868e8752d44 655
pythontech 0:5868e8752d44 656 // set default type for return
pythontech 0:5868e8752d44 657 emit->return_vtype = VTYPE_PYOBJ;
pythontech 0:5868e8752d44 658
pythontech 0:5868e8752d44 659 // set default type for arguments
pythontech 0:5868e8752d44 660 mp_uint_t num_args = emit->scope->num_pos_args + emit->scope->num_kwonly_args;
pythontech 0:5868e8752d44 661 if (scope->scope_flags & MP_SCOPE_FLAG_VARARGS) {
pythontech 0:5868e8752d44 662 num_args += 1;
pythontech 0:5868e8752d44 663 }
pythontech 0:5868e8752d44 664 if (scope->scope_flags & MP_SCOPE_FLAG_VARKEYWORDS) {
pythontech 0:5868e8752d44 665 num_args += 1;
pythontech 0:5868e8752d44 666 }
pythontech 0:5868e8752d44 667 for (mp_uint_t i = 0; i < num_args; i++) {
pythontech 0:5868e8752d44 668 emit->local_vtype[i] = VTYPE_PYOBJ;
pythontech 0:5868e8752d44 669 }
pythontech 0:5868e8752d44 670
pythontech 0:5868e8752d44 671 // local variables begin unbound, and have unknown type
pythontech 0:5868e8752d44 672 for (mp_uint_t i = num_args; i < emit->local_vtype_alloc; i++) {
pythontech 0:5868e8752d44 673 emit->local_vtype[i] = VTYPE_UNBOUND;
pythontech 0:5868e8752d44 674 }
pythontech 0:5868e8752d44 675
pythontech 0:5868e8752d44 676 // values on stack begin unbound
pythontech 0:5868e8752d44 677 for (mp_uint_t i = 0; i < emit->stack_info_alloc; i++) {
pythontech 0:5868e8752d44 678 emit->stack_info[i].kind = STACK_VALUE;
pythontech 0:5868e8752d44 679 emit->stack_info[i].vtype = VTYPE_UNBOUND;
pythontech 0:5868e8752d44 680 }
pythontech 0:5868e8752d44 681
pythontech 0:5868e8752d44 682 ASM_START_PASS(emit->as, pass == MP_PASS_EMIT ? ASM_PASS_EMIT : ASM_PASS_COMPUTE);
pythontech 0:5868e8752d44 683
pythontech 0:5868e8752d44 684 // generate code for entry to function
pythontech 0:5868e8752d44 685
pythontech 0:5868e8752d44 686 if (emit->do_viper_types) {
pythontech 0:5868e8752d44 687
pythontech 0:5868e8752d44 688 // right now we have a restriction of maximum of 4 arguments
pythontech 0:5868e8752d44 689 if (scope->num_pos_args >= 5) {
pythontech 0:5868e8752d44 690 EMIT_NATIVE_VIPER_TYPE_ERROR(emit, "Viper functions don't currently support more than 4 arguments");
pythontech 0:5868e8752d44 691 return;
pythontech 0:5868e8752d44 692 }
pythontech 0:5868e8752d44 693
pythontech 0:5868e8752d44 694 // entry to function
pythontech 0:5868e8752d44 695 int num_locals = 0;
pythontech 0:5868e8752d44 696 if (pass > MP_PASS_SCOPE) {
pythontech 0:5868e8752d44 697 num_locals = scope->num_locals - REG_LOCAL_NUM;
pythontech 0:5868e8752d44 698 if (num_locals < 0) {
pythontech 0:5868e8752d44 699 num_locals = 0;
pythontech 0:5868e8752d44 700 }
pythontech 0:5868e8752d44 701 emit->stack_start = num_locals;
pythontech 0:5868e8752d44 702 num_locals += scope->stack_size;
pythontech 0:5868e8752d44 703 }
pythontech 0:5868e8752d44 704 ASM_ENTRY(emit->as, num_locals);
pythontech 0:5868e8752d44 705
pythontech 0:5868e8752d44 706 // TODO don't load r7 if we don't need it
pythontech 0:5868e8752d44 707 #if N_THUMB
pythontech 0:5868e8752d44 708 asm_thumb_mov_reg_i32(emit->as, ASM_THUMB_REG_R7, (mp_uint_t)mp_fun_table);
pythontech 0:5868e8752d44 709 #elif N_ARM
pythontech 0:5868e8752d44 710 asm_arm_mov_reg_i32(emit->as, ASM_ARM_REG_R7, (mp_uint_t)mp_fun_table);
pythontech 0:5868e8752d44 711 #endif
pythontech 0:5868e8752d44 712
pythontech 0:5868e8752d44 713 #if N_X86
pythontech 0:5868e8752d44 714 for (int i = 0; i < scope->num_pos_args; i++) {
pythontech 0:5868e8752d44 715 if (i == 0) {
pythontech 0:5868e8752d44 716 asm_x86_mov_arg_to_r32(emit->as, i, REG_LOCAL_1);
pythontech 0:5868e8752d44 717 } else if (i == 1) {
pythontech 0:5868e8752d44 718 asm_x86_mov_arg_to_r32(emit->as, i, REG_LOCAL_2);
pythontech 0:5868e8752d44 719 } else if (i == 2) {
pythontech 0:5868e8752d44 720 asm_x86_mov_arg_to_r32(emit->as, i, REG_LOCAL_3);
pythontech 0:5868e8752d44 721 } else {
pythontech 0:5868e8752d44 722 asm_x86_mov_arg_to_r32(emit->as, i, REG_TEMP0);
pythontech 0:5868e8752d44 723 asm_x86_mov_r32_to_local(emit->as, REG_TEMP0, i - REG_LOCAL_NUM);
pythontech 0:5868e8752d44 724 }
pythontech 0:5868e8752d44 725 }
pythontech 0:5868e8752d44 726 #else
pythontech 0:5868e8752d44 727 for (int i = 0; i < scope->num_pos_args; i++) {
pythontech 0:5868e8752d44 728 if (i == 0) {
pythontech 0:5868e8752d44 729 ASM_MOV_REG_REG(emit->as, REG_LOCAL_1, REG_ARG_1);
pythontech 0:5868e8752d44 730 } else if (i == 1) {
pythontech 0:5868e8752d44 731 ASM_MOV_REG_REG(emit->as, REG_LOCAL_2, REG_ARG_2);
pythontech 0:5868e8752d44 732 } else if (i == 2) {
pythontech 0:5868e8752d44 733 ASM_MOV_REG_REG(emit->as, REG_LOCAL_3, REG_ARG_3);
pythontech 0:5868e8752d44 734 } else if (i == 3) {
pythontech 0:5868e8752d44 735 ASM_MOV_REG_TO_LOCAL(emit->as, REG_ARG_4, i - REG_LOCAL_NUM);
pythontech 0:5868e8752d44 736 } else {
pythontech 0:5868e8752d44 737 // TODO not implemented
pythontech 0:5868e8752d44 738 assert(0);
pythontech 0:5868e8752d44 739 }
pythontech 0:5868e8752d44 740 }
pythontech 0:5868e8752d44 741 #endif
pythontech 0:5868e8752d44 742
pythontech 0:5868e8752d44 743 } else {
pythontech 0:5868e8752d44 744 // work out size of state (locals plus stack)
pythontech 0:5868e8752d44 745 emit->n_state = scope->num_locals + scope->stack_size;
pythontech 0:5868e8752d44 746
pythontech 0:5868e8752d44 747 // allocate space on C-stack for code_state structure, which includes state
pythontech 0:5868e8752d44 748 ASM_ENTRY(emit->as, STATE_START + emit->n_state);
pythontech 0:5868e8752d44 749
pythontech 0:5868e8752d44 750 // TODO don't load r7 if we don't need it
pythontech 0:5868e8752d44 751 #if N_THUMB
pythontech 0:5868e8752d44 752 asm_thumb_mov_reg_i32(emit->as, ASM_THUMB_REG_R7, (mp_uint_t)mp_fun_table);
pythontech 0:5868e8752d44 753 #elif N_ARM
pythontech 0:5868e8752d44 754 asm_arm_mov_reg_i32(emit->as, ASM_ARM_REG_R7, (mp_uint_t)mp_fun_table);
pythontech 0:5868e8752d44 755 #endif
pythontech 0:5868e8752d44 756
pythontech 0:5868e8752d44 757 // prepare incoming arguments for call to mp_setup_code_state
pythontech 0:5868e8752d44 758 #if N_X86
pythontech 0:5868e8752d44 759 asm_x86_mov_arg_to_r32(emit->as, 0, REG_ARG_2);
pythontech 0:5868e8752d44 760 asm_x86_mov_arg_to_r32(emit->as, 1, REG_ARG_3);
pythontech 0:5868e8752d44 761 asm_x86_mov_arg_to_r32(emit->as, 2, REG_ARG_4);
pythontech 0:5868e8752d44 762 asm_x86_mov_arg_to_r32(emit->as, 3, REG_ARG_5);
pythontech 0:5868e8752d44 763 #else
pythontech 0:5868e8752d44 764 #if N_THUMB
pythontech 0:5868e8752d44 765 ASM_MOV_REG_REG(emit->as, ASM_THUMB_REG_R4, REG_ARG_4);
pythontech 0:5868e8752d44 766 #elif N_ARM
pythontech 0:5868e8752d44 767 ASM_MOV_REG_REG(emit->as, ASM_ARM_REG_R4, REG_ARG_4);
pythontech 0:5868e8752d44 768 #else
pythontech 0:5868e8752d44 769 ASM_MOV_REG_REG(emit->as, REG_ARG_5, REG_ARG_4);
pythontech 0:5868e8752d44 770 #endif
pythontech 0:5868e8752d44 771 ASM_MOV_REG_REG(emit->as, REG_ARG_4, REG_ARG_3);
pythontech 0:5868e8752d44 772 ASM_MOV_REG_REG(emit->as, REG_ARG_3, REG_ARG_2);
pythontech 0:5868e8752d44 773 ASM_MOV_REG_REG(emit->as, REG_ARG_2, REG_ARG_1);
pythontech 0:5868e8752d44 774 #endif
pythontech 0:5868e8752d44 775
pythontech 0:5868e8752d44 776 // set code_state.ip (offset from start of this function to prelude info)
pythontech 0:5868e8752d44 777 // XXX this encoding may change size
pythontech 0:5868e8752d44 778 ASM_MOV_IMM_TO_LOCAL_USING(emit->as, emit->prelude_offset, offsetof(mp_code_state, ip) / sizeof(mp_uint_t), REG_ARG_1);
pythontech 0:5868e8752d44 779
pythontech 0:5868e8752d44 780 // set code_state.n_state
pythontech 0:5868e8752d44 781 ASM_MOV_IMM_TO_LOCAL_USING(emit->as, emit->n_state, offsetof(mp_code_state, n_state) / sizeof(mp_uint_t), REG_ARG_1);
pythontech 0:5868e8752d44 782
pythontech 0:5868e8752d44 783 // put address of code_state into first arg
pythontech 0:5868e8752d44 784 ASM_MOV_LOCAL_ADDR_TO_REG(emit->as, 0, REG_ARG_1);
pythontech 0:5868e8752d44 785
pythontech 0:5868e8752d44 786 // call mp_setup_code_state to prepare code_state structure
pythontech 0:5868e8752d44 787 #if N_THUMB
pythontech 0:5868e8752d44 788 asm_thumb_op16(emit->as, 0xb400 | (1 << ASM_THUMB_REG_R4)); // push 5th arg
pythontech 0:5868e8752d44 789 asm_thumb_bl_ind(emit->as, mp_fun_table[MP_F_SETUP_CODE_STATE], MP_F_SETUP_CODE_STATE, ASM_THUMB_REG_R4);
pythontech 0:5868e8752d44 790 asm_thumb_op16(emit->as, 0xbc00 | (1 << REG_RET)); // pop dummy (was 5th arg)
pythontech 0:5868e8752d44 791 #elif N_ARM
pythontech 0:5868e8752d44 792 asm_arm_push(emit->as, 1 << ASM_ARM_REG_R4); // push 5th arg
pythontech 0:5868e8752d44 793 asm_arm_bl_ind(emit->as, mp_fun_table[MP_F_SETUP_CODE_STATE], MP_F_SETUP_CODE_STATE, ASM_ARM_REG_R4);
pythontech 0:5868e8752d44 794 asm_arm_pop(emit->as, 1 << REG_RET); // pop dummy (was 5th arg)
pythontech 0:5868e8752d44 795 #else
pythontech 0:5868e8752d44 796 ASM_CALL_IND(emit->as, mp_fun_table[MP_F_SETUP_CODE_STATE], MP_F_SETUP_CODE_STATE);
pythontech 0:5868e8752d44 797 #endif
pythontech 0:5868e8752d44 798
pythontech 0:5868e8752d44 799 // cache some locals in registers
pythontech 0:5868e8752d44 800 if (scope->num_locals > 0) {
pythontech 0:5868e8752d44 801 ASM_MOV_LOCAL_TO_REG(emit->as, STATE_START + emit->n_state - 1 - 0, REG_LOCAL_1);
pythontech 0:5868e8752d44 802 if (scope->num_locals > 1) {
pythontech 0:5868e8752d44 803 ASM_MOV_LOCAL_TO_REG(emit->as, STATE_START + emit->n_state - 1 - 1, REG_LOCAL_2);
pythontech 0:5868e8752d44 804 if (scope->num_locals > 2) {
pythontech 0:5868e8752d44 805 ASM_MOV_LOCAL_TO_REG(emit->as, STATE_START + emit->n_state - 1 - 2, REG_LOCAL_3);
pythontech 0:5868e8752d44 806 }
pythontech 0:5868e8752d44 807 }
pythontech 0:5868e8752d44 808 }
pythontech 0:5868e8752d44 809
pythontech 0:5868e8752d44 810 // set the type of closed over variables
pythontech 0:5868e8752d44 811 for (mp_uint_t i = 0; i < scope->id_info_len; i++) {
pythontech 0:5868e8752d44 812 id_info_t *id = &scope->id_info[i];
pythontech 0:5868e8752d44 813 if (id->kind == ID_INFO_KIND_CELL) {
pythontech 0:5868e8752d44 814 emit->local_vtype[id->local_num] = VTYPE_PYOBJ;
pythontech 0:5868e8752d44 815 }
pythontech 0:5868e8752d44 816 }
pythontech 0:5868e8752d44 817 }
pythontech 0:5868e8752d44 818
pythontech 0:5868e8752d44 819 }
pythontech 0:5868e8752d44 820
pythontech 0:5868e8752d44 821 STATIC void emit_native_end_pass(emit_t *emit) {
pythontech 0:5868e8752d44 822 if (!emit->last_emit_was_return_value) {
pythontech 0:5868e8752d44 823 ASM_EXIT(emit->as);
pythontech 0:5868e8752d44 824 }
pythontech 0:5868e8752d44 825
pythontech 0:5868e8752d44 826 if (!emit->do_viper_types) {
pythontech 0:5868e8752d44 827 emit->prelude_offset = ASM_GET_CODE_POS(emit->as);
pythontech 0:5868e8752d44 828 ASM_DATA(emit->as, 1, emit->scope->scope_flags);
pythontech 0:5868e8752d44 829 ASM_DATA(emit->as, 1, emit->scope->num_pos_args);
pythontech 0:5868e8752d44 830 ASM_DATA(emit->as, 1, emit->scope->num_kwonly_args);
pythontech 0:5868e8752d44 831 ASM_DATA(emit->as, 1, emit->scope->num_def_pos_args);
pythontech 0:5868e8752d44 832
pythontech 0:5868e8752d44 833 // write code info
pythontech 0:5868e8752d44 834 #if MICROPY_PERSISTENT_CODE
pythontech 0:5868e8752d44 835 ASM_DATA(emit->as, 1, 5);
pythontech 0:5868e8752d44 836 ASM_DATA(emit->as, 1, emit->scope->simple_name);
pythontech 0:5868e8752d44 837 ASM_DATA(emit->as, 1, emit->scope->simple_name >> 8);
pythontech 0:5868e8752d44 838 ASM_DATA(emit->as, 1, emit->scope->source_file);
pythontech 0:5868e8752d44 839 ASM_DATA(emit->as, 1, emit->scope->source_file >> 8);
pythontech 0:5868e8752d44 840 #else
pythontech 0:5868e8752d44 841 ASM_DATA(emit->as, 1, 1);
pythontech 0:5868e8752d44 842 #endif
pythontech 0:5868e8752d44 843
pythontech 0:5868e8752d44 844 // bytecode prelude: initialise closed over variables
pythontech 0:5868e8752d44 845 for (int i = 0; i < emit->scope->id_info_len; i++) {
pythontech 0:5868e8752d44 846 id_info_t *id = &emit->scope->id_info[i];
pythontech 0:5868e8752d44 847 if (id->kind == ID_INFO_KIND_CELL) {
pythontech 0:5868e8752d44 848 assert(id->local_num < 255);
pythontech 0:5868e8752d44 849 ASM_DATA(emit->as, 1, id->local_num); // write the local which should be converted to a cell
pythontech 0:5868e8752d44 850 }
pythontech 0:5868e8752d44 851 }
pythontech 0:5868e8752d44 852 ASM_DATA(emit->as, 1, 255); // end of list sentinel
pythontech 0:5868e8752d44 853
pythontech 0:5868e8752d44 854 ASM_ALIGN(emit->as, ASM_WORD_SIZE);
pythontech 0:5868e8752d44 855 emit->const_table_offset = ASM_GET_CODE_POS(emit->as);
pythontech 0:5868e8752d44 856
pythontech 0:5868e8752d44 857 // write argument names as qstr objects
pythontech 0:5868e8752d44 858 // see comment in corresponding part of emitbc.c about the logic here
pythontech 0:5868e8752d44 859 for (int i = 0; i < emit->scope->num_pos_args + emit->scope->num_kwonly_args; i++) {
pythontech 0:5868e8752d44 860 qstr qst = MP_QSTR__star_;
pythontech 0:5868e8752d44 861 for (int j = 0; j < emit->scope->id_info_len; ++j) {
pythontech 0:5868e8752d44 862 id_info_t *id = &emit->scope->id_info[j];
pythontech 0:5868e8752d44 863 if ((id->flags & ID_FLAG_IS_PARAM) && id->local_num == i) {
pythontech 0:5868e8752d44 864 qst = id->qst;
pythontech 0:5868e8752d44 865 break;
pythontech 0:5868e8752d44 866 }
pythontech 0:5868e8752d44 867 }
pythontech 0:5868e8752d44 868 ASM_DATA(emit->as, ASM_WORD_SIZE, (mp_uint_t)MP_OBJ_NEW_QSTR(qst));
pythontech 0:5868e8752d44 869 }
pythontech 0:5868e8752d44 870
pythontech 0:5868e8752d44 871 }
pythontech 0:5868e8752d44 872
pythontech 0:5868e8752d44 873 ASM_END_PASS(emit->as);
pythontech 0:5868e8752d44 874
pythontech 0:5868e8752d44 875 // check stack is back to zero size
pythontech 0:5868e8752d44 876 if (emit->stack_size != 0) {
pythontech 0:5868e8752d44 877 mp_printf(&mp_plat_print, "ERROR: stack size not back to zero; got %d\n", emit->stack_size);
pythontech 0:5868e8752d44 878 }
pythontech 0:5868e8752d44 879
pythontech 0:5868e8752d44 880 if (emit->pass == MP_PASS_EMIT) {
pythontech 0:5868e8752d44 881 void *f = ASM_GET_CODE(emit->as);
pythontech 0:5868e8752d44 882 mp_uint_t f_len = ASM_GET_CODE_SIZE(emit->as);
pythontech 0:5868e8752d44 883
pythontech 0:5868e8752d44 884 // compute type signature
pythontech 0:5868e8752d44 885 // note that the lower 4 bits of a vtype are tho correct MP_NATIVE_TYPE_xxx
pythontech 0:5868e8752d44 886 mp_uint_t type_sig = emit->return_vtype & 0xf;
pythontech 0:5868e8752d44 887 for (mp_uint_t i = 0; i < emit->scope->num_pos_args; i++) {
pythontech 0:5868e8752d44 888 type_sig |= (emit->local_vtype[i] & 0xf) << (i * 4 + 4);
pythontech 0:5868e8752d44 889 }
pythontech 0:5868e8752d44 890
pythontech 0:5868e8752d44 891 mp_emit_glue_assign_native(emit->scope->raw_code,
pythontech 0:5868e8752d44 892 emit->do_viper_types ? MP_CODE_NATIVE_VIPER : MP_CODE_NATIVE_PY,
pythontech 0:5868e8752d44 893 f, f_len, (mp_uint_t*)((byte*)f + emit->const_table_offset),
pythontech 0:5868e8752d44 894 emit->scope->num_pos_args, emit->scope->scope_flags, type_sig);
pythontech 0:5868e8752d44 895 }
pythontech 0:5868e8752d44 896 }
pythontech 0:5868e8752d44 897
pythontech 0:5868e8752d44 898 STATIC bool emit_native_last_emit_was_return_value(emit_t *emit) {
pythontech 0:5868e8752d44 899 return emit->last_emit_was_return_value;
pythontech 0:5868e8752d44 900 }
pythontech 0:5868e8752d44 901
pythontech 0:5868e8752d44 902 STATIC void adjust_stack(emit_t *emit, mp_int_t stack_size_delta) {
pythontech 0:5868e8752d44 903 assert((mp_int_t)emit->stack_size + stack_size_delta >= 0);
pythontech 0:5868e8752d44 904 emit->stack_size += stack_size_delta;
pythontech 0:5868e8752d44 905 if (emit->pass > MP_PASS_SCOPE && emit->stack_size > emit->scope->stack_size) {
pythontech 0:5868e8752d44 906 emit->scope->stack_size = emit->stack_size;
pythontech 0:5868e8752d44 907 }
pythontech 0:5868e8752d44 908 #ifdef DEBUG_PRINT
pythontech 0:5868e8752d44 909 DEBUG_printf(" adjust_stack; stack_size=%d+%d; stack now:", emit->stack_size - stack_size_delta, stack_size_delta);
pythontech 0:5868e8752d44 910 for (int i = 0; i < emit->stack_size; i++) {
pythontech 0:5868e8752d44 911 stack_info_t *si = &emit->stack_info[i];
pythontech 0:5868e8752d44 912 DEBUG_printf(" (v=%d k=%d %d)", si->vtype, si->kind, si->data.u_reg);
pythontech 0:5868e8752d44 913 }
pythontech 0:5868e8752d44 914 DEBUG_printf("\n");
pythontech 0:5868e8752d44 915 #endif
pythontech 0:5868e8752d44 916 }
pythontech 0:5868e8752d44 917
pythontech 0:5868e8752d44 918 STATIC void emit_native_adjust_stack_size(emit_t *emit, mp_int_t delta) {
pythontech 0:5868e8752d44 919 DEBUG_printf("adjust_stack_size(" INT_FMT ")\n", delta);
pythontech 0:5868e8752d44 920 // If we are adjusting the stack in a positive direction (pushing) then we
pythontech 0:5868e8752d44 921 // need to fill in values for the stack kind and vtype of the newly-pushed
pythontech 0:5868e8752d44 922 // entries. These should be set to "value" (ie not reg or imm) because we
pythontech 0:5868e8752d44 923 // should only need to adjust the stack due to a jump to this part in the
pythontech 0:5868e8752d44 924 // code (and hence we have settled the stack before the jump).
pythontech 0:5868e8752d44 925 for (mp_int_t i = 0; i < delta; i++) {
pythontech 0:5868e8752d44 926 stack_info_t *si = &emit->stack_info[emit->stack_size + i];
pythontech 0:5868e8752d44 927 si->kind = STACK_VALUE;
pythontech 0:5868e8752d44 928 // TODO we don't know the vtype to use here. At the moment this is a
pythontech 0:5868e8752d44 929 // hack to get the case of multi comparison working.
pythontech 0:5868e8752d44 930 if (delta == 1) {
pythontech 0:5868e8752d44 931 si->vtype = emit->saved_stack_vtype;
pythontech 0:5868e8752d44 932 } else {
pythontech 0:5868e8752d44 933 si->vtype = VTYPE_PYOBJ;
pythontech 0:5868e8752d44 934 }
pythontech 0:5868e8752d44 935 }
pythontech 0:5868e8752d44 936 adjust_stack(emit, delta);
pythontech 0:5868e8752d44 937 }
pythontech 0:5868e8752d44 938
pythontech 0:5868e8752d44 939 STATIC void emit_native_set_source_line(emit_t *emit, mp_uint_t source_line) {
pythontech 0:5868e8752d44 940 (void)emit;
pythontech 0:5868e8752d44 941 (void)source_line;
pythontech 0:5868e8752d44 942 }
pythontech 0:5868e8752d44 943
pythontech 0:5868e8752d44 944 /*
pythontech 0:5868e8752d44 945 STATIC void emit_pre_raw(emit_t *emit, int stack_size_delta) {
pythontech 0:5868e8752d44 946 adjust_stack(emit, stack_size_delta);
pythontech 0:5868e8752d44 947 emit->last_emit_was_return_value = false;
pythontech 0:5868e8752d44 948 }
pythontech 0:5868e8752d44 949 */
pythontech 0:5868e8752d44 950
pythontech 0:5868e8752d44 951 // this must be called at start of emit functions
pythontech 0:5868e8752d44 952 STATIC void emit_native_pre(emit_t *emit) {
pythontech 0:5868e8752d44 953 emit->last_emit_was_return_value = false;
pythontech 0:5868e8752d44 954 // settle the stack
pythontech 0:5868e8752d44 955 /*
pythontech 0:5868e8752d44 956 if (regs_needed != 0) {
pythontech 0:5868e8752d44 957 for (int i = 0; i < emit->stack_size; i++) {
pythontech 0:5868e8752d44 958 switch (emit->stack_info[i].kind) {
pythontech 0:5868e8752d44 959 case STACK_VALUE:
pythontech 0:5868e8752d44 960 break;
pythontech 0:5868e8752d44 961
pythontech 0:5868e8752d44 962 case STACK_REG:
pythontech 0:5868e8752d44 963 // TODO only push reg if in regs_needed
pythontech 0:5868e8752d44 964 emit->stack_info[i].kind = STACK_VALUE;
pythontech 0:5868e8752d44 965 ASM_MOV_REG_TO_LOCAL(emit->as, emit->stack_info[i].data.u_reg, emit->stack_start + i);
pythontech 0:5868e8752d44 966 break;
pythontech 0:5868e8752d44 967
pythontech 0:5868e8752d44 968 case STACK_IMM:
pythontech 0:5868e8752d44 969 // don't think we ever need to push imms for settling
pythontech 0:5868e8752d44 970 //ASM_MOV_IMM_TO_LOCAL(emit->last_imm, emit->stack_start + i);
pythontech 0:5868e8752d44 971 break;
pythontech 0:5868e8752d44 972 }
pythontech 0:5868e8752d44 973 }
pythontech 0:5868e8752d44 974 }
pythontech 0:5868e8752d44 975 */
pythontech 0:5868e8752d44 976 }
pythontech 0:5868e8752d44 977
pythontech 0:5868e8752d44 978 // depth==0 is top, depth==1 is before top, etc
pythontech 0:5868e8752d44 979 STATIC stack_info_t *peek_stack(emit_t *emit, mp_uint_t depth) {
pythontech 0:5868e8752d44 980 return &emit->stack_info[emit->stack_size - 1 - depth];
pythontech 0:5868e8752d44 981 }
pythontech 0:5868e8752d44 982
pythontech 0:5868e8752d44 983 // depth==0 is top, depth==1 is before top, etc
pythontech 0:5868e8752d44 984 STATIC vtype_kind_t peek_vtype(emit_t *emit, mp_uint_t depth) {
pythontech 0:5868e8752d44 985 return peek_stack(emit, depth)->vtype;
pythontech 0:5868e8752d44 986 }
pythontech 0:5868e8752d44 987
pythontech 0:5868e8752d44 988 // pos=1 is TOS, pos=2 is next, etc
pythontech 0:5868e8752d44 989 // use pos=0 for no skipping
pythontech 0:5868e8752d44 990 STATIC void need_reg_single(emit_t *emit, int reg_needed, int skip_stack_pos) {
pythontech 0:5868e8752d44 991 skip_stack_pos = emit->stack_size - skip_stack_pos;
pythontech 0:5868e8752d44 992 for (int i = 0; i < emit->stack_size; i++) {
pythontech 0:5868e8752d44 993 if (i != skip_stack_pos) {
pythontech 0:5868e8752d44 994 stack_info_t *si = &emit->stack_info[i];
pythontech 0:5868e8752d44 995 if (si->kind == STACK_REG && si->data.u_reg == reg_needed) {
pythontech 0:5868e8752d44 996 si->kind = STACK_VALUE;
pythontech 0:5868e8752d44 997 ASM_MOV_REG_TO_LOCAL(emit->as, si->data.u_reg, emit->stack_start + i);
pythontech 0:5868e8752d44 998 }
pythontech 0:5868e8752d44 999 }
pythontech 0:5868e8752d44 1000 }
pythontech 0:5868e8752d44 1001 }
pythontech 0:5868e8752d44 1002
pythontech 0:5868e8752d44 1003 STATIC void need_reg_all(emit_t *emit) {
pythontech 0:5868e8752d44 1004 for (int i = 0; i < emit->stack_size; i++) {
pythontech 0:5868e8752d44 1005 stack_info_t *si = &emit->stack_info[i];
pythontech 0:5868e8752d44 1006 if (si->kind == STACK_REG) {
pythontech 0:5868e8752d44 1007 si->kind = STACK_VALUE;
pythontech 0:5868e8752d44 1008 ASM_MOV_REG_TO_LOCAL(emit->as, si->data.u_reg, emit->stack_start + i);
pythontech 0:5868e8752d44 1009 }
pythontech 0:5868e8752d44 1010 }
pythontech 0:5868e8752d44 1011 }
pythontech 0:5868e8752d44 1012
pythontech 0:5868e8752d44 1013 STATIC void need_stack_settled(emit_t *emit) {
pythontech 0:5868e8752d44 1014 DEBUG_printf(" need_stack_settled; stack_size=%d\n", emit->stack_size);
pythontech 0:5868e8752d44 1015 for (int i = 0; i < emit->stack_size; i++) {
pythontech 0:5868e8752d44 1016 stack_info_t *si = &emit->stack_info[i];
pythontech 0:5868e8752d44 1017 if (si->kind == STACK_REG) {
pythontech 0:5868e8752d44 1018 DEBUG_printf(" reg(%u) to local(%u)\n", si->data.u_reg, emit->stack_start + i);
pythontech 0:5868e8752d44 1019 si->kind = STACK_VALUE;
pythontech 0:5868e8752d44 1020 ASM_MOV_REG_TO_LOCAL(emit->as, si->data.u_reg, emit->stack_start + i);
pythontech 0:5868e8752d44 1021 }
pythontech 0:5868e8752d44 1022 }
pythontech 0:5868e8752d44 1023 for (int i = 0; i < emit->stack_size; i++) {
pythontech 0:5868e8752d44 1024 stack_info_t *si = &emit->stack_info[i];
pythontech 0:5868e8752d44 1025 if (si->kind == STACK_IMM) {
pythontech 0:5868e8752d44 1026 DEBUG_printf(" imm(" INT_FMT ") to local(%u)\n", si->data.u_imm, emit->stack_start + i);
pythontech 0:5868e8752d44 1027 si->kind = STACK_VALUE;
pythontech 0:5868e8752d44 1028 ASM_MOV_IMM_TO_LOCAL_USING(emit->as, si->data.u_imm, emit->stack_start + i, REG_TEMP0);
pythontech 0:5868e8752d44 1029 }
pythontech 0:5868e8752d44 1030 }
pythontech 0:5868e8752d44 1031 }
pythontech 0:5868e8752d44 1032
pythontech 0:5868e8752d44 1033 // pos=1 is TOS, pos=2 is next, etc
pythontech 0:5868e8752d44 1034 STATIC void emit_access_stack(emit_t *emit, int pos, vtype_kind_t *vtype, int reg_dest) {
pythontech 0:5868e8752d44 1035 need_reg_single(emit, reg_dest, pos);
pythontech 0:5868e8752d44 1036 stack_info_t *si = &emit->stack_info[emit->stack_size - pos];
pythontech 0:5868e8752d44 1037 *vtype = si->vtype;
pythontech 0:5868e8752d44 1038 switch (si->kind) {
pythontech 0:5868e8752d44 1039 case STACK_VALUE:
pythontech 0:5868e8752d44 1040 ASM_MOV_LOCAL_TO_REG(emit->as, emit->stack_start + emit->stack_size - pos, reg_dest);
pythontech 0:5868e8752d44 1041 break;
pythontech 0:5868e8752d44 1042
pythontech 0:5868e8752d44 1043 case STACK_REG:
pythontech 0:5868e8752d44 1044 if (si->data.u_reg != reg_dest) {
pythontech 0:5868e8752d44 1045 ASM_MOV_REG_REG(emit->as, reg_dest, si->data.u_reg);
pythontech 0:5868e8752d44 1046 }
pythontech 0:5868e8752d44 1047 break;
pythontech 0:5868e8752d44 1048
pythontech 0:5868e8752d44 1049 case STACK_IMM:
pythontech 0:5868e8752d44 1050 ASM_MOV_IMM_TO_REG(emit->as, si->data.u_imm, reg_dest);
pythontech 0:5868e8752d44 1051 break;
pythontech 0:5868e8752d44 1052 }
pythontech 0:5868e8752d44 1053 }
pythontech 0:5868e8752d44 1054
pythontech 0:5868e8752d44 1055 // does an efficient X=pop(); discard(); push(X)
pythontech 0:5868e8752d44 1056 // needs a (non-temp) register in case the poped element was stored in the stack
pythontech 0:5868e8752d44 1057 STATIC void emit_fold_stack_top(emit_t *emit, int reg_dest) {
pythontech 0:5868e8752d44 1058 stack_info_t *si = &emit->stack_info[emit->stack_size - 2];
pythontech 0:5868e8752d44 1059 si[0] = si[1];
pythontech 0:5868e8752d44 1060 if (si->kind == STACK_VALUE) {
pythontech 0:5868e8752d44 1061 // if folded element was on the stack we need to put it in a register
pythontech 0:5868e8752d44 1062 ASM_MOV_LOCAL_TO_REG(emit->as, emit->stack_start + emit->stack_size - 1, reg_dest);
pythontech 0:5868e8752d44 1063 si->kind = STACK_REG;
pythontech 0:5868e8752d44 1064 si->data.u_reg = reg_dest;
pythontech 0:5868e8752d44 1065 }
pythontech 0:5868e8752d44 1066 adjust_stack(emit, -1);
pythontech 0:5868e8752d44 1067 }
pythontech 0:5868e8752d44 1068
pythontech 0:5868e8752d44 1069 // If stacked value is in a register and the register is not r1 or r2, then
pythontech 0:5868e8752d44 1070 // *reg_dest is set to that register. Otherwise the value is put in *reg_dest.
pythontech 0:5868e8752d44 1071 STATIC void emit_pre_pop_reg_flexible(emit_t *emit, vtype_kind_t *vtype, int *reg_dest, int not_r1, int not_r2) {
pythontech 0:5868e8752d44 1072 emit->last_emit_was_return_value = false;
pythontech 0:5868e8752d44 1073 stack_info_t *si = peek_stack(emit, 0);
pythontech 0:5868e8752d44 1074 if (si->kind == STACK_REG && si->data.u_reg != not_r1 && si->data.u_reg != not_r2) {
pythontech 0:5868e8752d44 1075 *vtype = si->vtype;
pythontech 0:5868e8752d44 1076 *reg_dest = si->data.u_reg;
pythontech 0:5868e8752d44 1077 need_reg_single(emit, *reg_dest, 1);
pythontech 0:5868e8752d44 1078 } else {
pythontech 0:5868e8752d44 1079 emit_access_stack(emit, 1, vtype, *reg_dest);
pythontech 0:5868e8752d44 1080 }
pythontech 0:5868e8752d44 1081 adjust_stack(emit, -1);
pythontech 0:5868e8752d44 1082 }
pythontech 0:5868e8752d44 1083
pythontech 0:5868e8752d44 1084 STATIC void emit_pre_pop_discard(emit_t *emit) {
pythontech 0:5868e8752d44 1085 emit->last_emit_was_return_value = false;
pythontech 0:5868e8752d44 1086 adjust_stack(emit, -1);
pythontech 0:5868e8752d44 1087 }
pythontech 0:5868e8752d44 1088
pythontech 0:5868e8752d44 1089 STATIC void emit_pre_pop_reg(emit_t *emit, vtype_kind_t *vtype, int reg_dest) {
pythontech 0:5868e8752d44 1090 emit->last_emit_was_return_value = false;
pythontech 0:5868e8752d44 1091 emit_access_stack(emit, 1, vtype, reg_dest);
pythontech 0:5868e8752d44 1092 adjust_stack(emit, -1);
pythontech 0:5868e8752d44 1093 }
pythontech 0:5868e8752d44 1094
pythontech 0:5868e8752d44 1095 STATIC void emit_pre_pop_reg_reg(emit_t *emit, vtype_kind_t *vtypea, int rega, vtype_kind_t *vtypeb, int regb) {
pythontech 0:5868e8752d44 1096 emit_pre_pop_reg(emit, vtypea, rega);
pythontech 0:5868e8752d44 1097 emit_pre_pop_reg(emit, vtypeb, regb);
pythontech 0:5868e8752d44 1098 }
pythontech 0:5868e8752d44 1099
pythontech 0:5868e8752d44 1100 STATIC void emit_pre_pop_reg_reg_reg(emit_t *emit, vtype_kind_t *vtypea, int rega, vtype_kind_t *vtypeb, int regb, vtype_kind_t *vtypec, int regc) {
pythontech 0:5868e8752d44 1101 emit_pre_pop_reg(emit, vtypea, rega);
pythontech 0:5868e8752d44 1102 emit_pre_pop_reg(emit, vtypeb, regb);
pythontech 0:5868e8752d44 1103 emit_pre_pop_reg(emit, vtypec, regc);
pythontech 0:5868e8752d44 1104 }
pythontech 0:5868e8752d44 1105
pythontech 0:5868e8752d44 1106 STATIC void emit_post(emit_t *emit) {
pythontech 0:5868e8752d44 1107 (void)emit;
pythontech 0:5868e8752d44 1108 }
pythontech 0:5868e8752d44 1109
pythontech 0:5868e8752d44 1110 STATIC void emit_post_top_set_vtype(emit_t *emit, vtype_kind_t new_vtype) {
pythontech 0:5868e8752d44 1111 stack_info_t *si = &emit->stack_info[emit->stack_size - 1];
pythontech 0:5868e8752d44 1112 si->vtype = new_vtype;
pythontech 0:5868e8752d44 1113 }
pythontech 0:5868e8752d44 1114
pythontech 0:5868e8752d44 1115 STATIC void emit_post_push_reg(emit_t *emit, vtype_kind_t vtype, int reg) {
pythontech 0:5868e8752d44 1116 stack_info_t *si = &emit->stack_info[emit->stack_size];
pythontech 0:5868e8752d44 1117 si->vtype = vtype;
pythontech 0:5868e8752d44 1118 si->kind = STACK_REG;
pythontech 0:5868e8752d44 1119 si->data.u_reg = reg;
pythontech 0:5868e8752d44 1120 adjust_stack(emit, 1);
pythontech 0:5868e8752d44 1121 }
pythontech 0:5868e8752d44 1122
pythontech 0:5868e8752d44 1123 STATIC void emit_post_push_imm(emit_t *emit, vtype_kind_t vtype, mp_int_t imm) {
pythontech 0:5868e8752d44 1124 stack_info_t *si = &emit->stack_info[emit->stack_size];
pythontech 0:5868e8752d44 1125 si->vtype = vtype;
pythontech 0:5868e8752d44 1126 si->kind = STACK_IMM;
pythontech 0:5868e8752d44 1127 si->data.u_imm = imm;
pythontech 0:5868e8752d44 1128 adjust_stack(emit, 1);
pythontech 0:5868e8752d44 1129 }
pythontech 0:5868e8752d44 1130
pythontech 0:5868e8752d44 1131 STATIC void emit_post_push_reg_reg(emit_t *emit, vtype_kind_t vtypea, int rega, vtype_kind_t vtypeb, int regb) {
pythontech 0:5868e8752d44 1132 emit_post_push_reg(emit, vtypea, rega);
pythontech 0:5868e8752d44 1133 emit_post_push_reg(emit, vtypeb, regb);
pythontech 0:5868e8752d44 1134 }
pythontech 0:5868e8752d44 1135
pythontech 0:5868e8752d44 1136 STATIC void emit_post_push_reg_reg_reg(emit_t *emit, vtype_kind_t vtypea, int rega, vtype_kind_t vtypeb, int regb, vtype_kind_t vtypec, int regc) {
pythontech 0:5868e8752d44 1137 emit_post_push_reg(emit, vtypea, rega);
pythontech 0:5868e8752d44 1138 emit_post_push_reg(emit, vtypeb, regb);
pythontech 0:5868e8752d44 1139 emit_post_push_reg(emit, vtypec, regc);
pythontech 0:5868e8752d44 1140 }
pythontech 0:5868e8752d44 1141
pythontech 0:5868e8752d44 1142 STATIC void emit_post_push_reg_reg_reg_reg(emit_t *emit, vtype_kind_t vtypea, int rega, vtype_kind_t vtypeb, int regb, vtype_kind_t vtypec, int regc, vtype_kind_t vtyped, int regd) {
pythontech 0:5868e8752d44 1143 emit_post_push_reg(emit, vtypea, rega);
pythontech 0:5868e8752d44 1144 emit_post_push_reg(emit, vtypeb, regb);
pythontech 0:5868e8752d44 1145 emit_post_push_reg(emit, vtypec, regc);
pythontech 0:5868e8752d44 1146 emit_post_push_reg(emit, vtyped, regd);
pythontech 0:5868e8752d44 1147 }
pythontech 0:5868e8752d44 1148
pythontech 0:5868e8752d44 1149 STATIC void emit_call(emit_t *emit, mp_fun_kind_t fun_kind) {
pythontech 0:5868e8752d44 1150 need_reg_all(emit);
pythontech 0:5868e8752d44 1151 ASM_CALL_IND(emit->as, mp_fun_table[fun_kind], fun_kind);
pythontech 0:5868e8752d44 1152 }
pythontech 0:5868e8752d44 1153
pythontech 0:5868e8752d44 1154 STATIC void emit_call_with_imm_arg(emit_t *emit, mp_fun_kind_t fun_kind, mp_int_t arg_val, int arg_reg) {
pythontech 0:5868e8752d44 1155 need_reg_all(emit);
pythontech 0:5868e8752d44 1156 ASM_MOV_IMM_TO_REG(emit->as, arg_val, arg_reg);
pythontech 0:5868e8752d44 1157 ASM_CALL_IND(emit->as, mp_fun_table[fun_kind], fun_kind);
pythontech 0:5868e8752d44 1158 }
pythontech 0:5868e8752d44 1159
pythontech 0:5868e8752d44 1160 // the first arg is stored in the code aligned on a mp_uint_t boundary
pythontech 0:5868e8752d44 1161 STATIC void emit_call_with_imm_arg_aligned(emit_t *emit, mp_fun_kind_t fun_kind, mp_int_t arg_val, int arg_reg) {
pythontech 0:5868e8752d44 1162 need_reg_all(emit);
pythontech 0:5868e8752d44 1163 ASM_MOV_ALIGNED_IMM_TO_REG(emit->as, arg_val, arg_reg);
pythontech 0:5868e8752d44 1164 ASM_CALL_IND(emit->as, mp_fun_table[fun_kind], fun_kind);
pythontech 0:5868e8752d44 1165 }
pythontech 0:5868e8752d44 1166
pythontech 0:5868e8752d44 1167 STATIC void emit_call_with_2_imm_args(emit_t *emit, mp_fun_kind_t fun_kind, mp_int_t arg_val1, int arg_reg1, mp_int_t arg_val2, int arg_reg2) {
pythontech 0:5868e8752d44 1168 need_reg_all(emit);
pythontech 0:5868e8752d44 1169 ASM_MOV_IMM_TO_REG(emit->as, arg_val1, arg_reg1);
pythontech 0:5868e8752d44 1170 ASM_MOV_IMM_TO_REG(emit->as, arg_val2, arg_reg2);
pythontech 0:5868e8752d44 1171 ASM_CALL_IND(emit->as, mp_fun_table[fun_kind], fun_kind);
pythontech 0:5868e8752d44 1172 }
pythontech 0:5868e8752d44 1173
pythontech 0:5868e8752d44 1174 // the first arg is stored in the code aligned on a mp_uint_t boundary
pythontech 0:5868e8752d44 1175 STATIC void emit_call_with_3_imm_args_and_first_aligned(emit_t *emit, mp_fun_kind_t fun_kind, mp_int_t arg_val1, int arg_reg1, mp_int_t arg_val2, int arg_reg2, mp_int_t arg_val3, int arg_reg3) {
pythontech 0:5868e8752d44 1176 need_reg_all(emit);
pythontech 0:5868e8752d44 1177 ASM_MOV_ALIGNED_IMM_TO_REG(emit->as, arg_val1, arg_reg1);
pythontech 0:5868e8752d44 1178 ASM_MOV_IMM_TO_REG(emit->as, arg_val2, arg_reg2);
pythontech 0:5868e8752d44 1179 ASM_MOV_IMM_TO_REG(emit->as, arg_val3, arg_reg3);
pythontech 0:5868e8752d44 1180 ASM_CALL_IND(emit->as, mp_fun_table[fun_kind], fun_kind);
pythontech 0:5868e8752d44 1181 }
pythontech 0:5868e8752d44 1182
pythontech 0:5868e8752d44 1183 // vtype of all n_pop objects is VTYPE_PYOBJ
pythontech 0:5868e8752d44 1184 // Will convert any items that are not VTYPE_PYOBJ to this type and put them back on the stack.
pythontech 0:5868e8752d44 1185 // If any conversions of non-immediate values are needed, then it uses REG_ARG_1, REG_ARG_2 and REG_RET.
pythontech 0:5868e8752d44 1186 // Otherwise, it does not use any temporary registers (but may use reg_dest before loading it with stack pointer).
pythontech 0:5868e8752d44 1187 STATIC void emit_get_stack_pointer_to_reg_for_pop(emit_t *emit, mp_uint_t reg_dest, mp_uint_t n_pop) {
pythontech 0:5868e8752d44 1188 need_reg_all(emit);
pythontech 0:5868e8752d44 1189
pythontech 0:5868e8752d44 1190 // First, store any immediate values to their respective place on the stack.
pythontech 0:5868e8752d44 1191 for (mp_uint_t i = 0; i < n_pop; i++) {
pythontech 0:5868e8752d44 1192 stack_info_t *si = &emit->stack_info[emit->stack_size - 1 - i];
pythontech 0:5868e8752d44 1193 // must push any imm's to stack
pythontech 0:5868e8752d44 1194 // must convert them to VTYPE_PYOBJ for viper code
pythontech 0:5868e8752d44 1195 if (si->kind == STACK_IMM) {
pythontech 0:5868e8752d44 1196 si->kind = STACK_VALUE;
pythontech 0:5868e8752d44 1197 switch (si->vtype) {
pythontech 0:5868e8752d44 1198 case VTYPE_PYOBJ:
pythontech 0:5868e8752d44 1199 ASM_MOV_IMM_TO_LOCAL_USING(emit->as, si->data.u_imm, emit->stack_start + emit->stack_size - 1 - i, reg_dest);
pythontech 0:5868e8752d44 1200 break;
pythontech 0:5868e8752d44 1201 case VTYPE_BOOL:
pythontech 0:5868e8752d44 1202 if (si->data.u_imm == 0) {
pythontech 0:5868e8752d44 1203 ASM_MOV_IMM_TO_LOCAL_USING(emit->as, (mp_uint_t)mp_const_false, emit->stack_start + emit->stack_size - 1 - i, reg_dest);
pythontech 0:5868e8752d44 1204 } else {
pythontech 0:5868e8752d44 1205 ASM_MOV_IMM_TO_LOCAL_USING(emit->as, (mp_uint_t)mp_const_true, emit->stack_start + emit->stack_size - 1 - i, reg_dest);
pythontech 0:5868e8752d44 1206 }
pythontech 0:5868e8752d44 1207 si->vtype = VTYPE_PYOBJ;
pythontech 0:5868e8752d44 1208 break;
pythontech 0:5868e8752d44 1209 case VTYPE_INT:
pythontech 0:5868e8752d44 1210 case VTYPE_UINT:
pythontech 0:5868e8752d44 1211 ASM_MOV_IMM_TO_LOCAL_USING(emit->as, (si->data.u_imm << 1) | 1, emit->stack_start + emit->stack_size - 1 - i, reg_dest);
pythontech 0:5868e8752d44 1212 si->vtype = VTYPE_PYOBJ;
pythontech 0:5868e8752d44 1213 break;
pythontech 0:5868e8752d44 1214 default:
pythontech 0:5868e8752d44 1215 // not handled
pythontech 0:5868e8752d44 1216 assert(0);
pythontech 0:5868e8752d44 1217 }
pythontech 0:5868e8752d44 1218 }
pythontech 0:5868e8752d44 1219
pythontech 0:5868e8752d44 1220 // verify that this value is on the stack
pythontech 0:5868e8752d44 1221 assert(si->kind == STACK_VALUE);
pythontech 0:5868e8752d44 1222 }
pythontech 0:5868e8752d44 1223
pythontech 0:5868e8752d44 1224 // Second, convert any non-VTYPE_PYOBJ to that type.
pythontech 0:5868e8752d44 1225 for (mp_uint_t i = 0; i < n_pop; i++) {
pythontech 0:5868e8752d44 1226 stack_info_t *si = &emit->stack_info[emit->stack_size - 1 - i];
pythontech 0:5868e8752d44 1227 if (si->vtype != VTYPE_PYOBJ) {
pythontech 0:5868e8752d44 1228 mp_uint_t local_num = emit->stack_start + emit->stack_size - 1 - i;
pythontech 0:5868e8752d44 1229 ASM_MOV_LOCAL_TO_REG(emit->as, local_num, REG_ARG_1);
pythontech 0:5868e8752d44 1230 emit_call_with_imm_arg(emit, MP_F_CONVERT_NATIVE_TO_OBJ, si->vtype, REG_ARG_2); // arg2 = type
pythontech 0:5868e8752d44 1231 ASM_MOV_REG_TO_LOCAL(emit->as, REG_RET, local_num);
pythontech 0:5868e8752d44 1232 si->vtype = VTYPE_PYOBJ;
pythontech 0:5868e8752d44 1233 DEBUG_printf(" convert_native_to_obj(local_num=" UINT_FMT ")\n", local_num);
pythontech 0:5868e8752d44 1234 }
pythontech 0:5868e8752d44 1235 }
pythontech 0:5868e8752d44 1236
pythontech 0:5868e8752d44 1237 // Adujust the stack for a pop of n_pop items, and load the stack pointer into reg_dest.
pythontech 0:5868e8752d44 1238 adjust_stack(emit, -n_pop);
pythontech 0:5868e8752d44 1239 ASM_MOV_LOCAL_ADDR_TO_REG(emit->as, emit->stack_start + emit->stack_size, reg_dest);
pythontech 0:5868e8752d44 1240 }
pythontech 0:5868e8752d44 1241
pythontech 0:5868e8752d44 1242 // vtype of all n_push objects is VTYPE_PYOBJ
pythontech 0:5868e8752d44 1243 STATIC void emit_get_stack_pointer_to_reg_for_push(emit_t *emit, mp_uint_t reg_dest, mp_uint_t n_push) {
pythontech 0:5868e8752d44 1244 need_reg_all(emit);
pythontech 0:5868e8752d44 1245 for (mp_uint_t i = 0; i < n_push; i++) {
pythontech 0:5868e8752d44 1246 emit->stack_info[emit->stack_size + i].kind = STACK_VALUE;
pythontech 0:5868e8752d44 1247 emit->stack_info[emit->stack_size + i].vtype = VTYPE_PYOBJ;
pythontech 0:5868e8752d44 1248 }
pythontech 0:5868e8752d44 1249 ASM_MOV_LOCAL_ADDR_TO_REG(emit->as, emit->stack_start + emit->stack_size, reg_dest);
pythontech 0:5868e8752d44 1250 adjust_stack(emit, n_push);
pythontech 0:5868e8752d44 1251 }
pythontech 0:5868e8752d44 1252
pythontech 0:5868e8752d44 1253 STATIC void emit_native_label_assign(emit_t *emit, mp_uint_t l) {
pythontech 0:5868e8752d44 1254 DEBUG_printf("label_assign(" UINT_FMT ")\n", l);
pythontech 0:5868e8752d44 1255 emit_native_pre(emit);
pythontech 0:5868e8752d44 1256 // need to commit stack because we can jump here from elsewhere
pythontech 0:5868e8752d44 1257 need_stack_settled(emit);
pythontech 0:5868e8752d44 1258 ASM_LABEL_ASSIGN(emit->as, l);
pythontech 0:5868e8752d44 1259 emit_post(emit);
pythontech 0:5868e8752d44 1260 }
pythontech 0:5868e8752d44 1261
pythontech 0:5868e8752d44 1262 STATIC void emit_native_import_name(emit_t *emit, qstr qst) {
pythontech 0:5868e8752d44 1263 DEBUG_printf("import_name %s\n", qstr_str(qst));
pythontech 0:5868e8752d44 1264 vtype_kind_t vtype_fromlist;
pythontech 0:5868e8752d44 1265 vtype_kind_t vtype_level;
pythontech 0:5868e8752d44 1266 emit_pre_pop_reg_reg(emit, &vtype_fromlist, REG_ARG_2, &vtype_level, REG_ARG_3); // arg2 = fromlist, arg3 = level
pythontech 0:5868e8752d44 1267 assert(vtype_fromlist == VTYPE_PYOBJ);
pythontech 0:5868e8752d44 1268 assert(vtype_level == VTYPE_PYOBJ);
pythontech 0:5868e8752d44 1269 emit_call_with_imm_arg(emit, MP_F_IMPORT_NAME, qst, REG_ARG_1); // arg1 = import name
pythontech 0:5868e8752d44 1270 emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
pythontech 0:5868e8752d44 1271 }
pythontech 0:5868e8752d44 1272
pythontech 0:5868e8752d44 1273 STATIC void emit_native_import_from(emit_t *emit, qstr qst) {
pythontech 0:5868e8752d44 1274 DEBUG_printf("import_from %s\n", qstr_str(qst));
pythontech 0:5868e8752d44 1275 emit_native_pre(emit);
pythontech 0:5868e8752d44 1276 vtype_kind_t vtype_module;
pythontech 0:5868e8752d44 1277 emit_access_stack(emit, 1, &vtype_module, REG_ARG_1); // arg1 = module
pythontech 0:5868e8752d44 1278 assert(vtype_module == VTYPE_PYOBJ);
pythontech 0:5868e8752d44 1279 emit_call_with_imm_arg(emit, MP_F_IMPORT_FROM, qst, REG_ARG_2); // arg2 = import name
pythontech 0:5868e8752d44 1280 emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
pythontech 0:5868e8752d44 1281 }
pythontech 0:5868e8752d44 1282
pythontech 0:5868e8752d44 1283 STATIC void emit_native_import_star(emit_t *emit) {
pythontech 0:5868e8752d44 1284 DEBUG_printf("import_star\n");
pythontech 0:5868e8752d44 1285 vtype_kind_t vtype_module;
pythontech 0:5868e8752d44 1286 emit_pre_pop_reg(emit, &vtype_module, REG_ARG_1); // arg1 = module
pythontech 0:5868e8752d44 1287 assert(vtype_module == VTYPE_PYOBJ);
pythontech 0:5868e8752d44 1288 emit_call(emit, MP_F_IMPORT_ALL);
pythontech 0:5868e8752d44 1289 emit_post(emit);
pythontech 0:5868e8752d44 1290 }
pythontech 0:5868e8752d44 1291
pythontech 0:5868e8752d44 1292 STATIC void emit_native_load_const_tok(emit_t *emit, mp_token_kind_t tok) {
pythontech 0:5868e8752d44 1293 DEBUG_printf("load_const_tok(tok=%u)\n", tok);
pythontech 0:5868e8752d44 1294 emit_native_pre(emit);
pythontech 0:5868e8752d44 1295 vtype_kind_t vtype;
pythontech 0:5868e8752d44 1296 mp_uint_t val;
pythontech 0:5868e8752d44 1297 if (emit->do_viper_types) {
pythontech 0:5868e8752d44 1298 switch (tok) {
pythontech 0:5868e8752d44 1299 case MP_TOKEN_KW_NONE: vtype = VTYPE_PTR_NONE; val = 0; break;
pythontech 0:5868e8752d44 1300 case MP_TOKEN_KW_FALSE: vtype = VTYPE_BOOL; val = 0; break;
pythontech 0:5868e8752d44 1301 case MP_TOKEN_KW_TRUE: vtype = VTYPE_BOOL; val = 1; break;
pythontech 0:5868e8752d44 1302 no_other_choice1:
pythontech 0:5868e8752d44 1303 case MP_TOKEN_ELLIPSIS: vtype = VTYPE_PYOBJ; val = (mp_uint_t)&mp_const_ellipsis_obj; break;
pythontech 0:5868e8752d44 1304 default: assert(0); goto no_other_choice1; // to help flow control analysis
pythontech 0:5868e8752d44 1305 }
pythontech 0:5868e8752d44 1306 } else {
pythontech 0:5868e8752d44 1307 vtype = VTYPE_PYOBJ;
pythontech 0:5868e8752d44 1308 switch (tok) {
pythontech 0:5868e8752d44 1309 case MP_TOKEN_KW_NONE: val = (mp_uint_t)mp_const_none; break;
pythontech 0:5868e8752d44 1310 case MP_TOKEN_KW_FALSE: val = (mp_uint_t)mp_const_false; break;
pythontech 0:5868e8752d44 1311 case MP_TOKEN_KW_TRUE: val = (mp_uint_t)mp_const_true; break;
pythontech 0:5868e8752d44 1312 no_other_choice2:
pythontech 0:5868e8752d44 1313 case MP_TOKEN_ELLIPSIS: val = (mp_uint_t)&mp_const_ellipsis_obj; break;
pythontech 0:5868e8752d44 1314 default: assert(0); goto no_other_choice2; // to help flow control analysis
pythontech 0:5868e8752d44 1315 }
pythontech 0:5868e8752d44 1316 }
pythontech 0:5868e8752d44 1317 emit_post_push_imm(emit, vtype, val);
pythontech 0:5868e8752d44 1318 }
pythontech 0:5868e8752d44 1319
pythontech 0:5868e8752d44 1320 STATIC void emit_native_load_const_small_int(emit_t *emit, mp_int_t arg) {
pythontech 0:5868e8752d44 1321 DEBUG_printf("load_const_small_int(int=" INT_FMT ")\n", arg);
pythontech 0:5868e8752d44 1322 emit_native_pre(emit);
pythontech 0:5868e8752d44 1323 if (emit->do_viper_types) {
pythontech 0:5868e8752d44 1324 emit_post_push_imm(emit, VTYPE_INT, arg);
pythontech 0:5868e8752d44 1325 } else {
pythontech 0:5868e8752d44 1326 emit_post_push_imm(emit, VTYPE_PYOBJ, (mp_uint_t)MP_OBJ_NEW_SMALL_INT(arg));
pythontech 0:5868e8752d44 1327 }
pythontech 0:5868e8752d44 1328 }
pythontech 0:5868e8752d44 1329
pythontech 0:5868e8752d44 1330 STATIC void emit_native_load_const_str(emit_t *emit, qstr qst) {
pythontech 0:5868e8752d44 1331 emit_native_pre(emit);
pythontech 0:5868e8752d44 1332 // TODO: Eventually we want to be able to work with raw pointers in viper to
pythontech 0:5868e8752d44 1333 // do native array access. For now we just load them as any other object.
pythontech 0:5868e8752d44 1334 /*
pythontech 0:5868e8752d44 1335 if (emit->do_viper_types) {
pythontech 0:5868e8752d44 1336 // not implemented properly
pythontech 0:5868e8752d44 1337 // load a pointer to the asciiz string?
pythontech 0:5868e8752d44 1338 assert(0);
pythontech 0:5868e8752d44 1339 emit_post_push_imm(emit, VTYPE_PTR, (mp_uint_t)qstr_str(qst));
pythontech 0:5868e8752d44 1340 } else
pythontech 0:5868e8752d44 1341 */
pythontech 0:5868e8752d44 1342 {
pythontech 0:5868e8752d44 1343 emit_post_push_imm(emit, VTYPE_PYOBJ, (mp_uint_t)MP_OBJ_NEW_QSTR(qst));
pythontech 0:5868e8752d44 1344 }
pythontech 0:5868e8752d44 1345 }
pythontech 0:5868e8752d44 1346
pythontech 0:5868e8752d44 1347 STATIC void emit_native_load_const_obj(emit_t *emit, mp_obj_t obj) {
pythontech 0:5868e8752d44 1348 emit_native_pre(emit);
pythontech 0:5868e8752d44 1349 need_reg_single(emit, REG_RET, 0);
pythontech 0:5868e8752d44 1350 ASM_MOV_ALIGNED_IMM_TO_REG(emit->as, (mp_uint_t)obj, REG_RET);
pythontech 0:5868e8752d44 1351 emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
pythontech 0:5868e8752d44 1352 }
pythontech 0:5868e8752d44 1353
pythontech 0:5868e8752d44 1354 STATIC void emit_native_load_null(emit_t *emit) {
pythontech 0:5868e8752d44 1355 emit_native_pre(emit);
pythontech 0:5868e8752d44 1356 emit_post_push_imm(emit, VTYPE_PYOBJ, 0);
pythontech 0:5868e8752d44 1357 }
pythontech 0:5868e8752d44 1358
pythontech 0:5868e8752d44 1359 STATIC void emit_native_load_fast(emit_t *emit, qstr qst, mp_uint_t local_num) {
pythontech 0:5868e8752d44 1360 DEBUG_printf("load_fast(%s, " UINT_FMT ")\n", qstr_str(qst), local_num);
pythontech 0:5868e8752d44 1361 vtype_kind_t vtype = emit->local_vtype[local_num];
pythontech 0:5868e8752d44 1362 if (vtype == VTYPE_UNBOUND) {
pythontech 0:5868e8752d44 1363 EMIT_NATIVE_VIPER_TYPE_ERROR(emit, "local '%q' used before type known", qst);
pythontech 0:5868e8752d44 1364 }
pythontech 0:5868e8752d44 1365 emit_native_pre(emit);
pythontech 0:5868e8752d44 1366 if (local_num == 0) {
pythontech 0:5868e8752d44 1367 emit_post_push_reg(emit, vtype, REG_LOCAL_1);
pythontech 0:5868e8752d44 1368 } else if (local_num == 1) {
pythontech 0:5868e8752d44 1369 emit_post_push_reg(emit, vtype, REG_LOCAL_2);
pythontech 0:5868e8752d44 1370 } else if (local_num == 2) {
pythontech 0:5868e8752d44 1371 emit_post_push_reg(emit, vtype, REG_LOCAL_3);
pythontech 0:5868e8752d44 1372 } else {
pythontech 0:5868e8752d44 1373 need_reg_single(emit, REG_TEMP0, 0);
pythontech 0:5868e8752d44 1374 if (emit->do_viper_types) {
pythontech 0:5868e8752d44 1375 ASM_MOV_LOCAL_TO_REG(emit->as, local_num - REG_LOCAL_NUM, REG_TEMP0);
pythontech 0:5868e8752d44 1376 } else {
pythontech 0:5868e8752d44 1377 ASM_MOV_LOCAL_TO_REG(emit->as, STATE_START + emit->n_state - 1 - local_num, REG_TEMP0);
pythontech 0:5868e8752d44 1378 }
pythontech 0:5868e8752d44 1379 emit_post_push_reg(emit, vtype, REG_TEMP0);
pythontech 0:5868e8752d44 1380 }
pythontech 0:5868e8752d44 1381 }
pythontech 0:5868e8752d44 1382
pythontech 0:5868e8752d44 1383 STATIC void emit_native_load_deref(emit_t *emit, qstr qst, mp_uint_t local_num) {
pythontech 0:5868e8752d44 1384 DEBUG_printf("load_deref(%s, " UINT_FMT ")\n", qstr_str(qst), local_num);
pythontech 0:5868e8752d44 1385 need_reg_single(emit, REG_RET, 0);
pythontech 0:5868e8752d44 1386 emit_native_load_fast(emit, qst, local_num);
pythontech 0:5868e8752d44 1387 vtype_kind_t vtype;
pythontech 0:5868e8752d44 1388 int reg_base = REG_RET;
pythontech 0:5868e8752d44 1389 emit_pre_pop_reg_flexible(emit, &vtype, &reg_base, -1, -1);
pythontech 0:5868e8752d44 1390 ASM_LOAD_REG_REG_OFFSET(emit->as, REG_RET, reg_base, 1);
pythontech 0:5868e8752d44 1391 // closed over vars are always Python objects
pythontech 0:5868e8752d44 1392 emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
pythontech 0:5868e8752d44 1393 }
pythontech 0:5868e8752d44 1394
pythontech 0:5868e8752d44 1395 STATIC void emit_native_load_name(emit_t *emit, qstr qst) {
pythontech 0:5868e8752d44 1396 DEBUG_printf("load_name(%s)\n", qstr_str(qst));
pythontech 0:5868e8752d44 1397 emit_native_pre(emit);
pythontech 0:5868e8752d44 1398 emit_call_with_imm_arg(emit, MP_F_LOAD_NAME, qst, REG_ARG_1);
pythontech 0:5868e8752d44 1399 emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
pythontech 0:5868e8752d44 1400 }
pythontech 0:5868e8752d44 1401
pythontech 0:5868e8752d44 1402 STATIC void emit_native_load_global(emit_t *emit, qstr qst) {
pythontech 0:5868e8752d44 1403 DEBUG_printf("load_global(%s)\n", qstr_str(qst));
pythontech 0:5868e8752d44 1404 emit_native_pre(emit);
pythontech 0:5868e8752d44 1405 // check for builtin casting operators
pythontech 0:5868e8752d44 1406 if (emit->do_viper_types && qst == MP_QSTR_int) {
pythontech 0:5868e8752d44 1407 emit_post_push_imm(emit, VTYPE_BUILTIN_CAST, VTYPE_INT);
pythontech 0:5868e8752d44 1408 } else if (emit->do_viper_types && qst == MP_QSTR_uint) {
pythontech 0:5868e8752d44 1409 emit_post_push_imm(emit, VTYPE_BUILTIN_CAST, VTYPE_UINT);
pythontech 0:5868e8752d44 1410 } else if (emit->do_viper_types && qst == MP_QSTR_ptr) {
pythontech 0:5868e8752d44 1411 emit_post_push_imm(emit, VTYPE_BUILTIN_CAST, VTYPE_PTR);
pythontech 0:5868e8752d44 1412 } else if (emit->do_viper_types && qst == MP_QSTR_ptr8) {
pythontech 0:5868e8752d44 1413 emit_post_push_imm(emit, VTYPE_BUILTIN_CAST, VTYPE_PTR8);
pythontech 0:5868e8752d44 1414 } else if (emit->do_viper_types && qst == MP_QSTR_ptr16) {
pythontech 0:5868e8752d44 1415 emit_post_push_imm(emit, VTYPE_BUILTIN_CAST, VTYPE_PTR16);
pythontech 0:5868e8752d44 1416 } else if (emit->do_viper_types && qst == MP_QSTR_ptr32) {
pythontech 0:5868e8752d44 1417 emit_post_push_imm(emit, VTYPE_BUILTIN_CAST, VTYPE_PTR32);
pythontech 0:5868e8752d44 1418 } else {
pythontech 0:5868e8752d44 1419 emit_call_with_imm_arg(emit, MP_F_LOAD_GLOBAL, qst, REG_ARG_1);
pythontech 0:5868e8752d44 1420 emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
pythontech 0:5868e8752d44 1421 }
pythontech 0:5868e8752d44 1422 }
pythontech 0:5868e8752d44 1423
pythontech 0:5868e8752d44 1424 STATIC void emit_native_load_attr(emit_t *emit, qstr qst) {
pythontech 0:5868e8752d44 1425 // depends on type of subject:
pythontech 0:5868e8752d44 1426 // - integer, function, pointer to integers: error
pythontech 0:5868e8752d44 1427 // - pointer to structure: get member, quite easy
pythontech 0:5868e8752d44 1428 // - Python object: call mp_load_attr, and needs to be typed to convert result
pythontech 0:5868e8752d44 1429 vtype_kind_t vtype_base;
pythontech 0:5868e8752d44 1430 emit_pre_pop_reg(emit, &vtype_base, REG_ARG_1); // arg1 = base
pythontech 0:5868e8752d44 1431 assert(vtype_base == VTYPE_PYOBJ);
pythontech 0:5868e8752d44 1432 emit_call_with_imm_arg(emit, MP_F_LOAD_ATTR, qst, REG_ARG_2); // arg2 = attribute name
pythontech 0:5868e8752d44 1433 emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
pythontech 0:5868e8752d44 1434 }
pythontech 0:5868e8752d44 1435
pythontech 0:5868e8752d44 1436 STATIC void emit_native_load_method(emit_t *emit, qstr qst) {
pythontech 0:5868e8752d44 1437 vtype_kind_t vtype_base;
pythontech 0:5868e8752d44 1438 emit_pre_pop_reg(emit, &vtype_base, REG_ARG_1); // arg1 = base
pythontech 0:5868e8752d44 1439 assert(vtype_base == VTYPE_PYOBJ);
pythontech 0:5868e8752d44 1440 emit_get_stack_pointer_to_reg_for_push(emit, REG_ARG_3, 2); // arg3 = dest ptr
pythontech 0:5868e8752d44 1441 emit_call_with_imm_arg(emit, MP_F_LOAD_METHOD, qst, REG_ARG_2); // arg2 = method name
pythontech 0:5868e8752d44 1442 }
pythontech 0:5868e8752d44 1443
pythontech 0:5868e8752d44 1444 STATIC void emit_native_load_build_class(emit_t *emit) {
pythontech 0:5868e8752d44 1445 emit_native_pre(emit);
pythontech 0:5868e8752d44 1446 emit_call(emit, MP_F_LOAD_BUILD_CLASS);
pythontech 0:5868e8752d44 1447 emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
pythontech 0:5868e8752d44 1448 }
pythontech 0:5868e8752d44 1449
pythontech 0:5868e8752d44 1450 STATIC void emit_native_load_subscr(emit_t *emit) {
pythontech 0:5868e8752d44 1451 DEBUG_printf("load_subscr\n");
pythontech 0:5868e8752d44 1452 // need to compile: base[index]
pythontech 0:5868e8752d44 1453
pythontech 0:5868e8752d44 1454 // pop: index, base
pythontech 0:5868e8752d44 1455 // optimise case where index is an immediate
pythontech 0:5868e8752d44 1456 vtype_kind_t vtype_base = peek_vtype(emit, 1);
pythontech 0:5868e8752d44 1457
pythontech 0:5868e8752d44 1458 if (vtype_base == VTYPE_PYOBJ) {
pythontech 0:5868e8752d44 1459 // standard Python subscr
pythontech 0:5868e8752d44 1460 // TODO factor this implicit cast code with other uses of it
pythontech 0:5868e8752d44 1461 vtype_kind_t vtype_index = peek_vtype(emit, 0);
pythontech 0:5868e8752d44 1462 if (vtype_index == VTYPE_PYOBJ) {
pythontech 0:5868e8752d44 1463 emit_pre_pop_reg(emit, &vtype_index, REG_ARG_2);
pythontech 0:5868e8752d44 1464 } else {
pythontech 0:5868e8752d44 1465 emit_pre_pop_reg(emit, &vtype_index, REG_ARG_1);
pythontech 0:5868e8752d44 1466 emit_call_with_imm_arg(emit, MP_F_CONVERT_NATIVE_TO_OBJ, vtype_index, REG_ARG_2); // arg2 = type
pythontech 0:5868e8752d44 1467 ASM_MOV_REG_REG(emit->as, REG_ARG_2, REG_RET);
pythontech 0:5868e8752d44 1468 }
pythontech 0:5868e8752d44 1469 emit_pre_pop_reg(emit, &vtype_base, REG_ARG_1);
pythontech 0:5868e8752d44 1470 emit_call_with_imm_arg(emit, MP_F_OBJ_SUBSCR, (mp_uint_t)MP_OBJ_SENTINEL, REG_ARG_3);
pythontech 0:5868e8752d44 1471 emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
pythontech 0:5868e8752d44 1472 } else {
pythontech 0:5868e8752d44 1473 // viper load
pythontech 0:5868e8752d44 1474 // TODO The different machine architectures have very different
pythontech 0:5868e8752d44 1475 // capabilities and requirements for loads, so probably best to
pythontech 0:5868e8752d44 1476 // write a completely separate load-optimiser for each one.
pythontech 0:5868e8752d44 1477 stack_info_t *top = peek_stack(emit, 0);
pythontech 0:5868e8752d44 1478 if (top->vtype == VTYPE_INT && top->kind == STACK_IMM) {
pythontech 0:5868e8752d44 1479 // index is an immediate
pythontech 0:5868e8752d44 1480 mp_int_t index_value = top->data.u_imm;
pythontech 0:5868e8752d44 1481 emit_pre_pop_discard(emit); // discard index
pythontech 0:5868e8752d44 1482 int reg_base = REG_ARG_1;
pythontech 0:5868e8752d44 1483 int reg_index = REG_ARG_2;
pythontech 0:5868e8752d44 1484 emit_pre_pop_reg_flexible(emit, &vtype_base, &reg_base, reg_index, reg_index);
pythontech 0:5868e8752d44 1485 switch (vtype_base) {
pythontech 0:5868e8752d44 1486 case VTYPE_PTR8: {
pythontech 0:5868e8752d44 1487 // pointer to 8-bit memory
pythontech 0:5868e8752d44 1488 // TODO optimise to use thumb ldrb r1, [r2, r3]
pythontech 0:5868e8752d44 1489 if (index_value != 0) {
pythontech 0:5868e8752d44 1490 // index is non-zero
pythontech 0:5868e8752d44 1491 #if N_THUMB
pythontech 0:5868e8752d44 1492 if (index_value > 0 && index_value < 32) {
pythontech 0:5868e8752d44 1493 asm_thumb_ldrb_rlo_rlo_i5(emit->as, REG_RET, reg_base, index_value);
pythontech 0:5868e8752d44 1494 break;
pythontech 0:5868e8752d44 1495 }
pythontech 0:5868e8752d44 1496 #endif
pythontech 0:5868e8752d44 1497 ASM_MOV_IMM_TO_REG(emit->as, index_value, reg_index);
pythontech 0:5868e8752d44 1498 ASM_ADD_REG_REG(emit->as, reg_index, reg_base); // add index to base
pythontech 0:5868e8752d44 1499 reg_base = reg_index;
pythontech 0:5868e8752d44 1500 }
pythontech 0:5868e8752d44 1501 ASM_LOAD8_REG_REG(emit->as, REG_RET, reg_base); // load from (base+index)
pythontech 0:5868e8752d44 1502 break;
pythontech 0:5868e8752d44 1503 }
pythontech 0:5868e8752d44 1504 case VTYPE_PTR16: {
pythontech 0:5868e8752d44 1505 // pointer to 16-bit memory
pythontech 0:5868e8752d44 1506 if (index_value != 0) {
pythontech 0:5868e8752d44 1507 // index is a non-zero immediate
pythontech 0:5868e8752d44 1508 #if N_THUMB
pythontech 0:5868e8752d44 1509 if (index_value > 0 && index_value < 32) {
pythontech 0:5868e8752d44 1510 asm_thumb_ldrh_rlo_rlo_i5(emit->as, REG_RET, reg_base, index_value);
pythontech 0:5868e8752d44 1511 break;
pythontech 0:5868e8752d44 1512 }
pythontech 0:5868e8752d44 1513 #endif
pythontech 0:5868e8752d44 1514 ASM_MOV_IMM_TO_REG(emit->as, index_value << 1, reg_index);
pythontech 0:5868e8752d44 1515 ASM_ADD_REG_REG(emit->as, reg_index, reg_base); // add 2*index to base
pythontech 0:5868e8752d44 1516 reg_base = reg_index;
pythontech 0:5868e8752d44 1517 }
pythontech 0:5868e8752d44 1518 ASM_LOAD16_REG_REG(emit->as, REG_RET, reg_base); // load from (base+2*index)
pythontech 0:5868e8752d44 1519 break;
pythontech 0:5868e8752d44 1520 }
pythontech 0:5868e8752d44 1521 case VTYPE_PTR32: {
pythontech 0:5868e8752d44 1522 // pointer to 32-bit memory
pythontech 0:5868e8752d44 1523 if (index_value != 0) {
pythontech 0:5868e8752d44 1524 // index is a non-zero immediate
pythontech 0:5868e8752d44 1525 #if N_THUMB
pythontech 0:5868e8752d44 1526 if (index_value > 0 && index_value < 32) {
pythontech 0:5868e8752d44 1527 asm_thumb_ldr_rlo_rlo_i5(emit->as, REG_RET, reg_base, index_value);
pythontech 0:5868e8752d44 1528 break;
pythontech 0:5868e8752d44 1529 }
pythontech 0:5868e8752d44 1530 #endif
pythontech 0:5868e8752d44 1531 ASM_MOV_IMM_TO_REG(emit->as, index_value << 2, reg_index);
pythontech 0:5868e8752d44 1532 ASM_ADD_REG_REG(emit->as, reg_index, reg_base); // add 4*index to base
pythontech 0:5868e8752d44 1533 reg_base = reg_index;
pythontech 0:5868e8752d44 1534 }
pythontech 0:5868e8752d44 1535 ASM_LOAD32_REG_REG(emit->as, REG_RET, reg_base); // load from (base+4*index)
pythontech 0:5868e8752d44 1536 break;
pythontech 0:5868e8752d44 1537 }
pythontech 0:5868e8752d44 1538 default:
pythontech 0:5868e8752d44 1539 EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
pythontech 0:5868e8752d44 1540 "can't load from '%q'", vtype_to_qstr(vtype_base));
pythontech 0:5868e8752d44 1541 }
pythontech 0:5868e8752d44 1542 } else {
pythontech 0:5868e8752d44 1543 // index is not an immediate
pythontech 0:5868e8752d44 1544 vtype_kind_t vtype_index;
pythontech 0:5868e8752d44 1545 int reg_index = REG_ARG_2;
pythontech 0:5868e8752d44 1546 emit_pre_pop_reg_flexible(emit, &vtype_index, &reg_index, REG_ARG_1, REG_ARG_1);
pythontech 0:5868e8752d44 1547 emit_pre_pop_reg(emit, &vtype_base, REG_ARG_1);
pythontech 0:5868e8752d44 1548 if (vtype_index != VTYPE_INT && vtype_index != VTYPE_UINT) {
pythontech 0:5868e8752d44 1549 EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
pythontech 0:5868e8752d44 1550 "can't load with '%q' index", vtype_to_qstr(vtype_index));
pythontech 0:5868e8752d44 1551 }
pythontech 0:5868e8752d44 1552 switch (vtype_base) {
pythontech 0:5868e8752d44 1553 case VTYPE_PTR8: {
pythontech 0:5868e8752d44 1554 // pointer to 8-bit memory
pythontech 0:5868e8752d44 1555 // TODO optimise to use thumb ldrb r1, [r2, r3]
pythontech 0:5868e8752d44 1556 ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
pythontech 0:5868e8752d44 1557 ASM_LOAD8_REG_REG(emit->as, REG_RET, REG_ARG_1); // store value to (base+index)
pythontech 0:5868e8752d44 1558 break;
pythontech 0:5868e8752d44 1559 }
pythontech 0:5868e8752d44 1560 case VTYPE_PTR16: {
pythontech 0:5868e8752d44 1561 // pointer to 16-bit memory
pythontech 0:5868e8752d44 1562 ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
pythontech 0:5868e8752d44 1563 ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
pythontech 0:5868e8752d44 1564 ASM_LOAD16_REG_REG(emit->as, REG_RET, REG_ARG_1); // load from (base+2*index)
pythontech 0:5868e8752d44 1565 break;
pythontech 0:5868e8752d44 1566 }
pythontech 0:5868e8752d44 1567 case VTYPE_PTR32: {
pythontech 0:5868e8752d44 1568 // pointer to word-size memory
pythontech 0:5868e8752d44 1569 ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
pythontech 0:5868e8752d44 1570 ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
pythontech 0:5868e8752d44 1571 ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
pythontech 0:5868e8752d44 1572 ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
pythontech 0:5868e8752d44 1573 ASM_LOAD32_REG_REG(emit->as, REG_RET, REG_ARG_1); // load from (base+4*index)
pythontech 0:5868e8752d44 1574 break;
pythontech 0:5868e8752d44 1575 }
pythontech 0:5868e8752d44 1576 default:
pythontech 0:5868e8752d44 1577 EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
pythontech 0:5868e8752d44 1578 "can't load from '%q'", vtype_to_qstr(vtype_base));
pythontech 0:5868e8752d44 1579 }
pythontech 0:5868e8752d44 1580 }
pythontech 0:5868e8752d44 1581 emit_post_push_reg(emit, VTYPE_INT, REG_RET);
pythontech 0:5868e8752d44 1582 }
pythontech 0:5868e8752d44 1583 }
pythontech 0:5868e8752d44 1584
pythontech 0:5868e8752d44 1585 STATIC void emit_native_store_fast(emit_t *emit, qstr qst, mp_uint_t local_num) {
pythontech 0:5868e8752d44 1586 vtype_kind_t vtype;
pythontech 0:5868e8752d44 1587 if (local_num == 0) {
pythontech 0:5868e8752d44 1588 emit_pre_pop_reg(emit, &vtype, REG_LOCAL_1);
pythontech 0:5868e8752d44 1589 } else if (local_num == 1) {
pythontech 0:5868e8752d44 1590 emit_pre_pop_reg(emit, &vtype, REG_LOCAL_2);
pythontech 0:5868e8752d44 1591 } else if (local_num == 2) {
pythontech 0:5868e8752d44 1592 emit_pre_pop_reg(emit, &vtype, REG_LOCAL_3);
pythontech 0:5868e8752d44 1593 } else {
pythontech 0:5868e8752d44 1594 emit_pre_pop_reg(emit, &vtype, REG_TEMP0);
pythontech 0:5868e8752d44 1595 if (emit->do_viper_types) {
pythontech 0:5868e8752d44 1596 ASM_MOV_REG_TO_LOCAL(emit->as, REG_TEMP0, local_num - REG_LOCAL_NUM);
pythontech 0:5868e8752d44 1597 } else {
pythontech 0:5868e8752d44 1598 ASM_MOV_REG_TO_LOCAL(emit->as, REG_TEMP0, STATE_START + emit->n_state - 1 - local_num);
pythontech 0:5868e8752d44 1599 }
pythontech 0:5868e8752d44 1600 }
pythontech 0:5868e8752d44 1601 emit_post(emit);
pythontech 0:5868e8752d44 1602
pythontech 0:5868e8752d44 1603 // check types
pythontech 0:5868e8752d44 1604 if (emit->local_vtype[local_num] == VTYPE_UNBOUND) {
pythontech 0:5868e8752d44 1605 // first time this local is assigned, so give it a type of the object stored in it
pythontech 0:5868e8752d44 1606 emit->local_vtype[local_num] = vtype;
pythontech 0:5868e8752d44 1607 } else if (emit->local_vtype[local_num] != vtype) {
pythontech 0:5868e8752d44 1608 // type of local is not the same as object stored in it
pythontech 0:5868e8752d44 1609 EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
pythontech 0:5868e8752d44 1610 "local '%q' has type '%q' but source is '%q'",
pythontech 0:5868e8752d44 1611 qst, vtype_to_qstr(emit->local_vtype[local_num]), vtype_to_qstr(vtype));
pythontech 0:5868e8752d44 1612 }
pythontech 0:5868e8752d44 1613 }
pythontech 0:5868e8752d44 1614
pythontech 0:5868e8752d44 1615 STATIC void emit_native_store_deref(emit_t *emit, qstr qst, mp_uint_t local_num) {
pythontech 0:5868e8752d44 1616 DEBUG_printf("store_deref(%s, " UINT_FMT ")\n", qstr_str(qst), local_num);
pythontech 0:5868e8752d44 1617 need_reg_single(emit, REG_TEMP0, 0);
pythontech 0:5868e8752d44 1618 need_reg_single(emit, REG_TEMP1, 0);
pythontech 0:5868e8752d44 1619 emit_native_load_fast(emit, qst, local_num);
pythontech 0:5868e8752d44 1620 vtype_kind_t vtype;
pythontech 0:5868e8752d44 1621 int reg_base = REG_TEMP0;
pythontech 0:5868e8752d44 1622 emit_pre_pop_reg_flexible(emit, &vtype, &reg_base, -1, -1);
pythontech 0:5868e8752d44 1623 int reg_src = REG_TEMP1;
pythontech 0:5868e8752d44 1624 emit_pre_pop_reg_flexible(emit, &vtype, &reg_src, reg_base, reg_base);
pythontech 0:5868e8752d44 1625 ASM_STORE_REG_REG_OFFSET(emit->as, reg_src, reg_base, 1);
pythontech 0:5868e8752d44 1626 emit_post(emit);
pythontech 0:5868e8752d44 1627 }
pythontech 0:5868e8752d44 1628
pythontech 0:5868e8752d44 1629 STATIC void emit_native_store_name(emit_t *emit, qstr qst) {
pythontech 0:5868e8752d44 1630 // mp_store_name, but needs conversion of object (maybe have mp_viper_store_name(obj, type))
pythontech 0:5868e8752d44 1631 vtype_kind_t vtype;
pythontech 0:5868e8752d44 1632 emit_pre_pop_reg(emit, &vtype, REG_ARG_2);
pythontech 0:5868e8752d44 1633 assert(vtype == VTYPE_PYOBJ);
pythontech 0:5868e8752d44 1634 emit_call_with_imm_arg(emit, MP_F_STORE_NAME, qst, REG_ARG_1); // arg1 = name
pythontech 0:5868e8752d44 1635 emit_post(emit);
pythontech 0:5868e8752d44 1636 }
pythontech 0:5868e8752d44 1637
pythontech 0:5868e8752d44 1638 STATIC void emit_native_store_global(emit_t *emit, qstr qst) {
pythontech 0:5868e8752d44 1639 vtype_kind_t vtype = peek_vtype(emit, 0);
pythontech 0:5868e8752d44 1640 if (vtype == VTYPE_PYOBJ) {
pythontech 0:5868e8752d44 1641 emit_pre_pop_reg(emit, &vtype, REG_ARG_2);
pythontech 0:5868e8752d44 1642 } else {
pythontech 0:5868e8752d44 1643 emit_pre_pop_reg(emit, &vtype, REG_ARG_1);
pythontech 0:5868e8752d44 1644 emit_call_with_imm_arg(emit, MP_F_CONVERT_NATIVE_TO_OBJ, vtype, REG_ARG_2); // arg2 = type
pythontech 0:5868e8752d44 1645 ASM_MOV_REG_REG(emit->as, REG_ARG_2, REG_RET);
pythontech 0:5868e8752d44 1646 }
pythontech 0:5868e8752d44 1647 emit_call_with_imm_arg(emit, MP_F_STORE_GLOBAL, qst, REG_ARG_1); // arg1 = name
pythontech 0:5868e8752d44 1648 emit_post(emit);
pythontech 0:5868e8752d44 1649 }
pythontech 0:5868e8752d44 1650
pythontech 0:5868e8752d44 1651 STATIC void emit_native_store_attr(emit_t *emit, qstr qst) {
pythontech 0:5868e8752d44 1652 vtype_kind_t vtype_base, vtype_val;
pythontech 0:5868e8752d44 1653 emit_pre_pop_reg_reg(emit, &vtype_base, REG_ARG_1, &vtype_val, REG_ARG_3); // arg1 = base, arg3 = value
pythontech 0:5868e8752d44 1654 assert(vtype_base == VTYPE_PYOBJ);
pythontech 0:5868e8752d44 1655 assert(vtype_val == VTYPE_PYOBJ);
pythontech 0:5868e8752d44 1656 emit_call_with_imm_arg(emit, MP_F_STORE_ATTR, qst, REG_ARG_2); // arg2 = attribute name
pythontech 0:5868e8752d44 1657 emit_post(emit);
pythontech 0:5868e8752d44 1658 }
pythontech 0:5868e8752d44 1659
pythontech 0:5868e8752d44 1660 STATIC void emit_native_store_subscr(emit_t *emit) {
pythontech 0:5868e8752d44 1661 DEBUG_printf("store_subscr\n");
pythontech 0:5868e8752d44 1662 // need to compile: base[index] = value
pythontech 0:5868e8752d44 1663
pythontech 0:5868e8752d44 1664 // pop: index, base, value
pythontech 0:5868e8752d44 1665 // optimise case where index is an immediate
pythontech 0:5868e8752d44 1666 vtype_kind_t vtype_base = peek_vtype(emit, 1);
pythontech 0:5868e8752d44 1667
pythontech 0:5868e8752d44 1668 if (vtype_base == VTYPE_PYOBJ) {
pythontech 0:5868e8752d44 1669 // standard Python subscr
pythontech 0:5868e8752d44 1670 vtype_kind_t vtype_index = peek_vtype(emit, 0);
pythontech 0:5868e8752d44 1671 vtype_kind_t vtype_value = peek_vtype(emit, 2);
pythontech 0:5868e8752d44 1672 if (vtype_index != VTYPE_PYOBJ || vtype_value != VTYPE_PYOBJ) {
pythontech 0:5868e8752d44 1673 // need to implicitly convert non-objects to objects
pythontech 0:5868e8752d44 1674 // TODO do this properly
pythontech 0:5868e8752d44 1675 emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_1, 3);
pythontech 0:5868e8752d44 1676 adjust_stack(emit, 3);
pythontech 0:5868e8752d44 1677 }
pythontech 0:5868e8752d44 1678 emit_pre_pop_reg_reg_reg(emit, &vtype_index, REG_ARG_2, &vtype_base, REG_ARG_1, &vtype_value, REG_ARG_3);
pythontech 0:5868e8752d44 1679 emit_call(emit, MP_F_OBJ_SUBSCR);
pythontech 0:5868e8752d44 1680 } else {
pythontech 0:5868e8752d44 1681 // viper store
pythontech 0:5868e8752d44 1682 // TODO The different machine architectures have very different
pythontech 0:5868e8752d44 1683 // capabilities and requirements for stores, so probably best to
pythontech 0:5868e8752d44 1684 // write a completely separate store-optimiser for each one.
pythontech 0:5868e8752d44 1685 stack_info_t *top = peek_stack(emit, 0);
pythontech 0:5868e8752d44 1686 if (top->vtype == VTYPE_INT && top->kind == STACK_IMM) {
pythontech 0:5868e8752d44 1687 // index is an immediate
pythontech 0:5868e8752d44 1688 mp_int_t index_value = top->data.u_imm;
pythontech 0:5868e8752d44 1689 emit_pre_pop_discard(emit); // discard index
pythontech 0:5868e8752d44 1690 vtype_kind_t vtype_value;
pythontech 0:5868e8752d44 1691 int reg_base = REG_ARG_1;
pythontech 0:5868e8752d44 1692 int reg_index = REG_ARG_2;
pythontech 0:5868e8752d44 1693 int reg_value = REG_ARG_3;
pythontech 0:5868e8752d44 1694 emit_pre_pop_reg_flexible(emit, &vtype_base, &reg_base, reg_index, reg_value);
pythontech 0:5868e8752d44 1695 #if N_X86
pythontech 0:5868e8752d44 1696 // special case: x86 needs byte stores to be from lower 4 regs (REG_ARG_3 is EDX)
pythontech 0:5868e8752d44 1697 emit_pre_pop_reg(emit, &vtype_value, reg_value);
pythontech 0:5868e8752d44 1698 #else
pythontech 0:5868e8752d44 1699 emit_pre_pop_reg_flexible(emit, &vtype_value, &reg_value, reg_base, reg_index);
pythontech 0:5868e8752d44 1700 #endif
pythontech 0:5868e8752d44 1701 if (vtype_value != VTYPE_BOOL && vtype_value != VTYPE_INT && vtype_value != VTYPE_UINT) {
pythontech 0:5868e8752d44 1702 EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
pythontech 0:5868e8752d44 1703 "can't store '%q'", vtype_to_qstr(vtype_value));
pythontech 0:5868e8752d44 1704 }
pythontech 0:5868e8752d44 1705 switch (vtype_base) {
pythontech 0:5868e8752d44 1706 case VTYPE_PTR8: {
pythontech 0:5868e8752d44 1707 // pointer to 8-bit memory
pythontech 0:5868e8752d44 1708 // TODO optimise to use thumb strb r1, [r2, r3]
pythontech 0:5868e8752d44 1709 if (index_value != 0) {
pythontech 0:5868e8752d44 1710 // index is non-zero
pythontech 0:5868e8752d44 1711 #if N_THUMB
pythontech 0:5868e8752d44 1712 if (index_value > 0 && index_value < 32) {
pythontech 0:5868e8752d44 1713 asm_thumb_strb_rlo_rlo_i5(emit->as, reg_value, reg_base, index_value);
pythontech 0:5868e8752d44 1714 break;
pythontech 0:5868e8752d44 1715 }
pythontech 0:5868e8752d44 1716 #endif
pythontech 0:5868e8752d44 1717 ASM_MOV_IMM_TO_REG(emit->as, index_value, reg_index);
pythontech 0:5868e8752d44 1718 #if N_ARM
pythontech 0:5868e8752d44 1719 asm_arm_strb_reg_reg_reg(emit->as, reg_value, reg_base, reg_index);
pythontech 0:5868e8752d44 1720 return;
pythontech 0:5868e8752d44 1721 #endif
pythontech 0:5868e8752d44 1722 ASM_ADD_REG_REG(emit->as, reg_index, reg_base); // add index to base
pythontech 0:5868e8752d44 1723 reg_base = reg_index;
pythontech 0:5868e8752d44 1724 }
pythontech 0:5868e8752d44 1725 ASM_STORE8_REG_REG(emit->as, reg_value, reg_base); // store value to (base+index)
pythontech 0:5868e8752d44 1726 break;
pythontech 0:5868e8752d44 1727 }
pythontech 0:5868e8752d44 1728 case VTYPE_PTR16: {
pythontech 0:5868e8752d44 1729 // pointer to 16-bit memory
pythontech 0:5868e8752d44 1730 if (index_value != 0) {
pythontech 0:5868e8752d44 1731 // index is a non-zero immediate
pythontech 0:5868e8752d44 1732 #if N_THUMB
pythontech 0:5868e8752d44 1733 if (index_value > 0 && index_value < 32) {
pythontech 0:5868e8752d44 1734 asm_thumb_strh_rlo_rlo_i5(emit->as, reg_value, reg_base, index_value);
pythontech 0:5868e8752d44 1735 break;
pythontech 0:5868e8752d44 1736 }
pythontech 0:5868e8752d44 1737 #endif
pythontech 0:5868e8752d44 1738 ASM_MOV_IMM_TO_REG(emit->as, index_value << 1, reg_index);
pythontech 0:5868e8752d44 1739 #if N_ARM
pythontech 0:5868e8752d44 1740 asm_arm_strh_reg_reg_reg(emit->as, reg_value, reg_base, reg_index);
pythontech 0:5868e8752d44 1741 return;
pythontech 0:5868e8752d44 1742 #endif
pythontech 0:5868e8752d44 1743 ASM_ADD_REG_REG(emit->as, reg_index, reg_base); // add 2*index to base
pythontech 0:5868e8752d44 1744 reg_base = reg_index;
pythontech 0:5868e8752d44 1745 }
pythontech 0:5868e8752d44 1746 ASM_STORE16_REG_REG(emit->as, reg_value, reg_base); // store value to (base+2*index)
pythontech 0:5868e8752d44 1747 break;
pythontech 0:5868e8752d44 1748 }
pythontech 0:5868e8752d44 1749 case VTYPE_PTR32: {
pythontech 0:5868e8752d44 1750 // pointer to 32-bit memory
pythontech 0:5868e8752d44 1751 if (index_value != 0) {
pythontech 0:5868e8752d44 1752 // index is a non-zero immediate
pythontech 0:5868e8752d44 1753 #if N_THUMB
pythontech 0:5868e8752d44 1754 if (index_value > 0 && index_value < 32) {
pythontech 0:5868e8752d44 1755 asm_thumb_str_rlo_rlo_i5(emit->as, reg_value, reg_base, index_value);
pythontech 0:5868e8752d44 1756 break;
pythontech 0:5868e8752d44 1757 }
pythontech 0:5868e8752d44 1758 #endif
pythontech 0:5868e8752d44 1759 ASM_MOV_IMM_TO_REG(emit->as, index_value << 2, reg_index);
pythontech 0:5868e8752d44 1760 #if N_ARM
pythontech 0:5868e8752d44 1761 asm_arm_str_reg_reg_reg(emit->as, reg_value, reg_base, reg_index);
pythontech 0:5868e8752d44 1762 return;
pythontech 0:5868e8752d44 1763 #endif
pythontech 0:5868e8752d44 1764 ASM_ADD_REG_REG(emit->as, reg_index, reg_base); // add 4*index to base
pythontech 0:5868e8752d44 1765 reg_base = reg_index;
pythontech 0:5868e8752d44 1766 }
pythontech 0:5868e8752d44 1767 ASM_STORE32_REG_REG(emit->as, reg_value, reg_base); // store value to (base+4*index)
pythontech 0:5868e8752d44 1768 break;
pythontech 0:5868e8752d44 1769 }
pythontech 0:5868e8752d44 1770 default:
pythontech 0:5868e8752d44 1771 EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
pythontech 0:5868e8752d44 1772 "can't store to '%q'", vtype_to_qstr(vtype_base));
pythontech 0:5868e8752d44 1773 }
pythontech 0:5868e8752d44 1774 } else {
pythontech 0:5868e8752d44 1775 // index is not an immediate
pythontech 0:5868e8752d44 1776 vtype_kind_t vtype_index, vtype_value;
pythontech 0:5868e8752d44 1777 int reg_index = REG_ARG_2;
pythontech 0:5868e8752d44 1778 int reg_value = REG_ARG_3;
pythontech 0:5868e8752d44 1779 emit_pre_pop_reg_flexible(emit, &vtype_index, &reg_index, REG_ARG_1, reg_value);
pythontech 0:5868e8752d44 1780 emit_pre_pop_reg(emit, &vtype_base, REG_ARG_1);
pythontech 0:5868e8752d44 1781 if (vtype_index != VTYPE_INT && vtype_index != VTYPE_UINT) {
pythontech 0:5868e8752d44 1782 EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
pythontech 0:5868e8752d44 1783 "can't store with '%q' index", vtype_to_qstr(vtype_index));
pythontech 0:5868e8752d44 1784 }
pythontech 0:5868e8752d44 1785 #if N_X86
pythontech 0:5868e8752d44 1786 // special case: x86 needs byte stores to be from lower 4 regs (REG_ARG_3 is EDX)
pythontech 0:5868e8752d44 1787 emit_pre_pop_reg(emit, &vtype_value, reg_value);
pythontech 0:5868e8752d44 1788 #else
pythontech 0:5868e8752d44 1789 emit_pre_pop_reg_flexible(emit, &vtype_value, &reg_value, REG_ARG_1, reg_index);
pythontech 0:5868e8752d44 1790 #endif
pythontech 0:5868e8752d44 1791 if (vtype_value != VTYPE_BOOL && vtype_value != VTYPE_INT && vtype_value != VTYPE_UINT) {
pythontech 0:5868e8752d44 1792 EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
pythontech 0:5868e8752d44 1793 "can't store '%q'", vtype_to_qstr(vtype_value));
pythontech 0:5868e8752d44 1794 }
pythontech 0:5868e8752d44 1795 switch (vtype_base) {
pythontech 0:5868e8752d44 1796 case VTYPE_PTR8: {
pythontech 0:5868e8752d44 1797 // pointer to 8-bit memory
pythontech 0:5868e8752d44 1798 // TODO optimise to use thumb strb r1, [r2, r3]
pythontech 0:5868e8752d44 1799 #if N_ARM
pythontech 0:5868e8752d44 1800 asm_arm_strb_reg_reg_reg(emit->as, reg_value, REG_ARG_1, reg_index);
pythontech 0:5868e8752d44 1801 break;
pythontech 0:5868e8752d44 1802 #endif
pythontech 0:5868e8752d44 1803 ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
pythontech 0:5868e8752d44 1804 ASM_STORE8_REG_REG(emit->as, reg_value, REG_ARG_1); // store value to (base+index)
pythontech 0:5868e8752d44 1805 break;
pythontech 0:5868e8752d44 1806 }
pythontech 0:5868e8752d44 1807 case VTYPE_PTR16: {
pythontech 0:5868e8752d44 1808 // pointer to 16-bit memory
pythontech 0:5868e8752d44 1809 #if N_ARM
pythontech 0:5868e8752d44 1810 asm_arm_strh_reg_reg_reg(emit->as, reg_value, REG_ARG_1, reg_index);
pythontech 0:5868e8752d44 1811 break;
pythontech 0:5868e8752d44 1812 #endif
pythontech 0:5868e8752d44 1813 ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
pythontech 0:5868e8752d44 1814 ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
pythontech 0:5868e8752d44 1815 ASM_STORE16_REG_REG(emit->as, reg_value, REG_ARG_1); // store value to (base+2*index)
pythontech 0:5868e8752d44 1816 break;
pythontech 0:5868e8752d44 1817 }
pythontech 0:5868e8752d44 1818 case VTYPE_PTR32: {
pythontech 0:5868e8752d44 1819 // pointer to 32-bit memory
pythontech 0:5868e8752d44 1820 #if N_ARM
pythontech 0:5868e8752d44 1821 asm_arm_str_reg_reg_reg(emit->as, reg_value, REG_ARG_1, reg_index);
pythontech 0:5868e8752d44 1822 break;
pythontech 0:5868e8752d44 1823 #endif
pythontech 0:5868e8752d44 1824 ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
pythontech 0:5868e8752d44 1825 ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
pythontech 0:5868e8752d44 1826 ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
pythontech 0:5868e8752d44 1827 ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
pythontech 0:5868e8752d44 1828 ASM_STORE32_REG_REG(emit->as, reg_value, REG_ARG_1); // store value to (base+4*index)
pythontech 0:5868e8752d44 1829 break;
pythontech 0:5868e8752d44 1830 }
pythontech 0:5868e8752d44 1831 default:
pythontech 0:5868e8752d44 1832 EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
pythontech 0:5868e8752d44 1833 "can't store to '%q'", vtype_to_qstr(vtype_base));
pythontech 0:5868e8752d44 1834 }
pythontech 0:5868e8752d44 1835 }
pythontech 0:5868e8752d44 1836
pythontech 0:5868e8752d44 1837 }
pythontech 0:5868e8752d44 1838 }
pythontech 0:5868e8752d44 1839
pythontech 0:5868e8752d44 1840 STATIC void emit_native_delete_fast(emit_t *emit, qstr qst, mp_uint_t local_num) {
pythontech 0:5868e8752d44 1841 // TODO: This is not compliant implementation. We could use MP_OBJ_SENTINEL
pythontech 0:5868e8752d44 1842 // to mark deleted vars but then every var would need to be checked on
pythontech 0:5868e8752d44 1843 // each access. Very inefficient, so just set value to None to enable GC.
pythontech 0:5868e8752d44 1844 emit_native_load_const_tok(emit, MP_TOKEN_KW_NONE);
pythontech 0:5868e8752d44 1845 emit_native_store_fast(emit, qst, local_num);
pythontech 0:5868e8752d44 1846 }
pythontech 0:5868e8752d44 1847
pythontech 0:5868e8752d44 1848 STATIC void emit_native_delete_deref(emit_t *emit, qstr qst, mp_uint_t local_num) {
pythontech 0:5868e8752d44 1849 // TODO implement me!
pythontech 0:5868e8752d44 1850 (void)emit;
pythontech 0:5868e8752d44 1851 (void)qst;
pythontech 0:5868e8752d44 1852 (void)local_num;
pythontech 0:5868e8752d44 1853 }
pythontech 0:5868e8752d44 1854
pythontech 0:5868e8752d44 1855 STATIC void emit_native_delete_name(emit_t *emit, qstr qst) {
pythontech 0:5868e8752d44 1856 emit_native_pre(emit);
pythontech 0:5868e8752d44 1857 emit_call_with_imm_arg(emit, MP_F_DELETE_NAME, qst, REG_ARG_1);
pythontech 0:5868e8752d44 1858 emit_post(emit);
pythontech 0:5868e8752d44 1859 }
pythontech 0:5868e8752d44 1860
pythontech 0:5868e8752d44 1861 STATIC void emit_native_delete_global(emit_t *emit, qstr qst) {
pythontech 0:5868e8752d44 1862 emit_native_pre(emit);
pythontech 0:5868e8752d44 1863 emit_call_with_imm_arg(emit, MP_F_DELETE_GLOBAL, qst, REG_ARG_1);
pythontech 0:5868e8752d44 1864 emit_post(emit);
pythontech 0:5868e8752d44 1865 }
pythontech 0:5868e8752d44 1866
pythontech 0:5868e8752d44 1867 STATIC void emit_native_delete_attr(emit_t *emit, qstr qst) {
pythontech 0:5868e8752d44 1868 vtype_kind_t vtype_base;
pythontech 0:5868e8752d44 1869 emit_pre_pop_reg(emit, &vtype_base, REG_ARG_1); // arg1 = base
pythontech 0:5868e8752d44 1870 assert(vtype_base == VTYPE_PYOBJ);
pythontech 0:5868e8752d44 1871 emit_call_with_2_imm_args(emit, MP_F_STORE_ATTR, qst, REG_ARG_2, (mp_uint_t)MP_OBJ_NULL, REG_ARG_3); // arg2 = attribute name, arg3 = value (null for delete)
pythontech 0:5868e8752d44 1872 emit_post(emit);
pythontech 0:5868e8752d44 1873 }
pythontech 0:5868e8752d44 1874
pythontech 0:5868e8752d44 1875 STATIC void emit_native_delete_subscr(emit_t *emit) {
pythontech 0:5868e8752d44 1876 vtype_kind_t vtype_index, vtype_base;
pythontech 0:5868e8752d44 1877 emit_pre_pop_reg_reg(emit, &vtype_index, REG_ARG_2, &vtype_base, REG_ARG_1); // index, base
pythontech 0:5868e8752d44 1878 assert(vtype_index == VTYPE_PYOBJ);
pythontech 0:5868e8752d44 1879 assert(vtype_base == VTYPE_PYOBJ);
pythontech 0:5868e8752d44 1880 emit_call_with_imm_arg(emit, MP_F_OBJ_SUBSCR, (mp_uint_t)MP_OBJ_NULL, REG_ARG_3);
pythontech 0:5868e8752d44 1881 }
pythontech 0:5868e8752d44 1882
pythontech 0:5868e8752d44 1883 STATIC void emit_native_dup_top(emit_t *emit) {
pythontech 0:5868e8752d44 1884 DEBUG_printf("dup_top\n");
pythontech 0:5868e8752d44 1885 vtype_kind_t vtype;
pythontech 0:5868e8752d44 1886 int reg = REG_TEMP0;
pythontech 0:5868e8752d44 1887 emit_pre_pop_reg_flexible(emit, &vtype, &reg, -1, -1);
pythontech 0:5868e8752d44 1888 emit_post_push_reg_reg(emit, vtype, reg, vtype, reg);
pythontech 0:5868e8752d44 1889 }
pythontech 0:5868e8752d44 1890
pythontech 0:5868e8752d44 1891 STATIC void emit_native_dup_top_two(emit_t *emit) {
pythontech 0:5868e8752d44 1892 vtype_kind_t vtype0, vtype1;
pythontech 0:5868e8752d44 1893 emit_pre_pop_reg_reg(emit, &vtype0, REG_TEMP0, &vtype1, REG_TEMP1);
pythontech 0:5868e8752d44 1894 emit_post_push_reg_reg_reg_reg(emit, vtype1, REG_TEMP1, vtype0, REG_TEMP0, vtype1, REG_TEMP1, vtype0, REG_TEMP0);
pythontech 0:5868e8752d44 1895 }
pythontech 0:5868e8752d44 1896
pythontech 0:5868e8752d44 1897 STATIC void emit_native_pop_top(emit_t *emit) {
pythontech 0:5868e8752d44 1898 DEBUG_printf("pop_top\n");
pythontech 0:5868e8752d44 1899 emit_pre_pop_discard(emit);
pythontech 0:5868e8752d44 1900 emit_post(emit);
pythontech 0:5868e8752d44 1901 }
pythontech 0:5868e8752d44 1902
pythontech 0:5868e8752d44 1903 STATIC void emit_native_rot_two(emit_t *emit) {
pythontech 0:5868e8752d44 1904 DEBUG_printf("rot_two\n");
pythontech 0:5868e8752d44 1905 vtype_kind_t vtype0, vtype1;
pythontech 0:5868e8752d44 1906 emit_pre_pop_reg_reg(emit, &vtype0, REG_TEMP0, &vtype1, REG_TEMP1);
pythontech 0:5868e8752d44 1907 emit_post_push_reg_reg(emit, vtype0, REG_TEMP0, vtype1, REG_TEMP1);
pythontech 0:5868e8752d44 1908 }
pythontech 0:5868e8752d44 1909
pythontech 0:5868e8752d44 1910 STATIC void emit_native_rot_three(emit_t *emit) {
pythontech 0:5868e8752d44 1911 DEBUG_printf("rot_three\n");
pythontech 0:5868e8752d44 1912 vtype_kind_t vtype0, vtype1, vtype2;
pythontech 0:5868e8752d44 1913 emit_pre_pop_reg_reg_reg(emit, &vtype0, REG_TEMP0, &vtype1, REG_TEMP1, &vtype2, REG_TEMP2);
pythontech 0:5868e8752d44 1914 emit_post_push_reg_reg_reg(emit, vtype0, REG_TEMP0, vtype2, REG_TEMP2, vtype1, REG_TEMP1);
pythontech 0:5868e8752d44 1915 }
pythontech 0:5868e8752d44 1916
pythontech 0:5868e8752d44 1917 STATIC void emit_native_jump(emit_t *emit, mp_uint_t label) {
pythontech 0:5868e8752d44 1918 DEBUG_printf("jump(label=" UINT_FMT ")\n", label);
pythontech 0:5868e8752d44 1919 emit_native_pre(emit);
pythontech 0:5868e8752d44 1920 // need to commit stack because we are jumping elsewhere
pythontech 0:5868e8752d44 1921 need_stack_settled(emit);
pythontech 0:5868e8752d44 1922 ASM_JUMP(emit->as, label);
pythontech 0:5868e8752d44 1923 emit_post(emit);
pythontech 0:5868e8752d44 1924 }
pythontech 0:5868e8752d44 1925
pythontech 0:5868e8752d44 1926 STATIC void emit_native_jump_helper(emit_t *emit, bool pop) {
pythontech 0:5868e8752d44 1927 vtype_kind_t vtype = peek_vtype(emit, 0);
pythontech 0:5868e8752d44 1928 if (vtype == VTYPE_PYOBJ) {
pythontech 0:5868e8752d44 1929 emit_pre_pop_reg(emit, &vtype, REG_ARG_1);
pythontech 0:5868e8752d44 1930 if (!pop) {
pythontech 0:5868e8752d44 1931 adjust_stack(emit, 1);
pythontech 0:5868e8752d44 1932 }
pythontech 0:5868e8752d44 1933 emit_call(emit, MP_F_OBJ_IS_TRUE);
pythontech 0:5868e8752d44 1934 } else {
pythontech 0:5868e8752d44 1935 emit_pre_pop_reg(emit, &vtype, REG_RET);
pythontech 0:5868e8752d44 1936 if (!pop) {
pythontech 0:5868e8752d44 1937 adjust_stack(emit, 1);
pythontech 0:5868e8752d44 1938 }
pythontech 0:5868e8752d44 1939 if (!(vtype == VTYPE_BOOL || vtype == VTYPE_INT || vtype == VTYPE_UINT)) {
pythontech 0:5868e8752d44 1940 EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
pythontech 0:5868e8752d44 1941 "can't implicitly convert '%q' to 'bool'", vtype_to_qstr(vtype));
pythontech 0:5868e8752d44 1942 }
pythontech 0:5868e8752d44 1943 }
pythontech 0:5868e8752d44 1944 // For non-pop need to save the vtype so that emit_native_adjust_stack_size
pythontech 0:5868e8752d44 1945 // can use it. This is a bit of a hack.
pythontech 0:5868e8752d44 1946 if (!pop) {
pythontech 0:5868e8752d44 1947 emit->saved_stack_vtype = vtype;
pythontech 0:5868e8752d44 1948 }
pythontech 0:5868e8752d44 1949 // need to commit stack because we may jump elsewhere
pythontech 0:5868e8752d44 1950 need_stack_settled(emit);
pythontech 0:5868e8752d44 1951 }
pythontech 0:5868e8752d44 1952
pythontech 0:5868e8752d44 1953 STATIC void emit_native_pop_jump_if(emit_t *emit, bool cond, mp_uint_t label) {
pythontech 0:5868e8752d44 1954 DEBUG_printf("pop_jump_if(cond=%u, label=" UINT_FMT ")\n", cond, label);
pythontech 0:5868e8752d44 1955 emit_native_jump_helper(emit, true);
pythontech 0:5868e8752d44 1956 if (cond) {
pythontech 0:5868e8752d44 1957 ASM_JUMP_IF_REG_NONZERO(emit->as, REG_RET, label);
pythontech 0:5868e8752d44 1958 } else {
pythontech 0:5868e8752d44 1959 ASM_JUMP_IF_REG_ZERO(emit->as, REG_RET, label);
pythontech 0:5868e8752d44 1960 }
pythontech 0:5868e8752d44 1961 emit_post(emit);
pythontech 0:5868e8752d44 1962 }
pythontech 0:5868e8752d44 1963
pythontech 0:5868e8752d44 1964 STATIC void emit_native_jump_if_or_pop(emit_t *emit, bool cond, mp_uint_t label) {
pythontech 0:5868e8752d44 1965 DEBUG_printf("jump_if_or_pop(cond=%u, label=" UINT_FMT ")\n", cond, label);
pythontech 0:5868e8752d44 1966 emit_native_jump_helper(emit, false);
pythontech 0:5868e8752d44 1967 if (cond) {
pythontech 0:5868e8752d44 1968 ASM_JUMP_IF_REG_NONZERO(emit->as, REG_RET, label);
pythontech 0:5868e8752d44 1969 } else {
pythontech 0:5868e8752d44 1970 ASM_JUMP_IF_REG_ZERO(emit->as, REG_RET, label);
pythontech 0:5868e8752d44 1971 }
pythontech 0:5868e8752d44 1972 adjust_stack(emit, -1);
pythontech 0:5868e8752d44 1973 emit_post(emit);
pythontech 0:5868e8752d44 1974 }
pythontech 0:5868e8752d44 1975
pythontech 0:5868e8752d44 1976 STATIC void emit_native_break_loop(emit_t *emit, mp_uint_t label, mp_uint_t except_depth) {
pythontech 0:5868e8752d44 1977 (void)except_depth;
pythontech 0:5868e8752d44 1978 emit_native_jump(emit, label & ~MP_EMIT_BREAK_FROM_FOR); // TODO properly
pythontech 0:5868e8752d44 1979 }
pythontech 0:5868e8752d44 1980
pythontech 0:5868e8752d44 1981 STATIC void emit_native_continue_loop(emit_t *emit, mp_uint_t label, mp_uint_t except_depth) {
pythontech 0:5868e8752d44 1982 (void)except_depth;
pythontech 0:5868e8752d44 1983 emit_native_jump(emit, label); // TODO properly
pythontech 0:5868e8752d44 1984 }
pythontech 0:5868e8752d44 1985
pythontech 0:5868e8752d44 1986 STATIC void emit_native_setup_with(emit_t *emit, mp_uint_t label) {
pythontech 0:5868e8752d44 1987 // the context manager is on the top of the stack
pythontech 0:5868e8752d44 1988 // stack: (..., ctx_mgr)
pythontech 0:5868e8752d44 1989
pythontech 0:5868e8752d44 1990 // get __exit__ method
pythontech 0:5868e8752d44 1991 vtype_kind_t vtype;
pythontech 0:5868e8752d44 1992 emit_access_stack(emit, 1, &vtype, REG_ARG_1); // arg1 = ctx_mgr
pythontech 0:5868e8752d44 1993 assert(vtype == VTYPE_PYOBJ);
pythontech 0:5868e8752d44 1994 emit_get_stack_pointer_to_reg_for_push(emit, REG_ARG_3, 2); // arg3 = dest ptr
pythontech 0:5868e8752d44 1995 emit_call_with_imm_arg(emit, MP_F_LOAD_METHOD, MP_QSTR___exit__, REG_ARG_2);
pythontech 0:5868e8752d44 1996 // stack: (..., ctx_mgr, __exit__, self)
pythontech 0:5868e8752d44 1997
pythontech 0:5868e8752d44 1998 emit_pre_pop_reg(emit, &vtype, REG_ARG_3); // self
pythontech 0:5868e8752d44 1999 emit_pre_pop_reg(emit, &vtype, REG_ARG_2); // __exit__
pythontech 0:5868e8752d44 2000 emit_pre_pop_reg(emit, &vtype, REG_ARG_1); // ctx_mgr
pythontech 0:5868e8752d44 2001 emit_post_push_reg(emit, vtype, REG_ARG_2); // __exit__
pythontech 0:5868e8752d44 2002 emit_post_push_reg(emit, vtype, REG_ARG_3); // self
pythontech 0:5868e8752d44 2003 // stack: (..., __exit__, self)
pythontech 0:5868e8752d44 2004 // REG_ARG_1=ctx_mgr
pythontech 0:5868e8752d44 2005
pythontech 0:5868e8752d44 2006 // get __enter__ method
pythontech 0:5868e8752d44 2007 emit_get_stack_pointer_to_reg_for_push(emit, REG_ARG_3, 2); // arg3 = dest ptr
pythontech 0:5868e8752d44 2008 emit_call_with_imm_arg(emit, MP_F_LOAD_METHOD, MP_QSTR___enter__, REG_ARG_2); // arg2 = method name
pythontech 0:5868e8752d44 2009 // stack: (..., __exit__, self, __enter__, self)
pythontech 0:5868e8752d44 2010
pythontech 0:5868e8752d44 2011 // call __enter__ method
pythontech 0:5868e8752d44 2012 emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_3, 2); // pointer to items, including meth and self
pythontech 0:5868e8752d44 2013 emit_call_with_2_imm_args(emit, MP_F_CALL_METHOD_N_KW, 0, REG_ARG_1, 0, REG_ARG_2);
pythontech 0:5868e8752d44 2014 emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); // push return value of __enter__
pythontech 0:5868e8752d44 2015 // stack: (..., __exit__, self, as_value)
pythontech 0:5868e8752d44 2016
pythontech 0:5868e8752d44 2017 // need to commit stack because we may jump elsewhere
pythontech 0:5868e8752d44 2018 need_stack_settled(emit);
pythontech 0:5868e8752d44 2019 emit_get_stack_pointer_to_reg_for_push(emit, REG_ARG_1, sizeof(nlr_buf_t) / sizeof(mp_uint_t)); // arg1 = pointer to nlr buf
pythontech 0:5868e8752d44 2020 emit_call(emit, MP_F_NLR_PUSH);
pythontech 0:5868e8752d44 2021 ASM_JUMP_IF_REG_NONZERO(emit->as, REG_RET, label);
pythontech 0:5868e8752d44 2022
pythontech 0:5868e8752d44 2023 emit_access_stack(emit, sizeof(nlr_buf_t) / sizeof(mp_uint_t) + 1, &vtype, REG_RET); // access return value of __enter__
pythontech 0:5868e8752d44 2024 emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); // push return value of __enter__
pythontech 0:5868e8752d44 2025 // stack: (..., __exit__, self, as_value, nlr_buf, as_value)
pythontech 0:5868e8752d44 2026 }
pythontech 0:5868e8752d44 2027
pythontech 0:5868e8752d44 2028 STATIC void emit_native_with_cleanup(emit_t *emit, mp_uint_t label) {
pythontech 0:5868e8752d44 2029 // note: label+1 is available as an auxiliary label
pythontech 0:5868e8752d44 2030
pythontech 0:5868e8752d44 2031 // stack: (..., __exit__, self, as_value, nlr_buf)
pythontech 0:5868e8752d44 2032 emit_native_pre(emit);
pythontech 0:5868e8752d44 2033 emit_call(emit, MP_F_NLR_POP);
pythontech 0:5868e8752d44 2034 adjust_stack(emit, -(mp_int_t)(sizeof(nlr_buf_t) / sizeof(mp_uint_t)) - 1);
pythontech 0:5868e8752d44 2035 // stack: (..., __exit__, self)
pythontech 0:5868e8752d44 2036
pythontech 0:5868e8752d44 2037 // call __exit__
pythontech 0:5868e8752d44 2038 emit_post_push_imm(emit, VTYPE_PYOBJ, (mp_uint_t)mp_const_none);
pythontech 0:5868e8752d44 2039 emit_post_push_imm(emit, VTYPE_PYOBJ, (mp_uint_t)mp_const_none);
pythontech 0:5868e8752d44 2040 emit_post_push_imm(emit, VTYPE_PYOBJ, (mp_uint_t)mp_const_none);
pythontech 0:5868e8752d44 2041 emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_3, 5);
pythontech 0:5868e8752d44 2042 emit_call_with_2_imm_args(emit, MP_F_CALL_METHOD_N_KW, 3, REG_ARG_1, 0, REG_ARG_2);
pythontech 0:5868e8752d44 2043
pythontech 0:5868e8752d44 2044 // jump to after with cleanup nlr_catch block
pythontech 0:5868e8752d44 2045 adjust_stack(emit, 1); // dummy nlr_buf.prev
pythontech 0:5868e8752d44 2046 emit_native_load_const_tok(emit, MP_TOKEN_KW_NONE); // nlr_buf.ret_val = no exception
pythontech 0:5868e8752d44 2047 emit_native_jump(emit, label + 1);
pythontech 0:5868e8752d44 2048
pythontech 0:5868e8752d44 2049 // nlr_catch
pythontech 0:5868e8752d44 2050 emit_native_label_assign(emit, label);
pythontech 0:5868e8752d44 2051
pythontech 0:5868e8752d44 2052 // adjust stack counter for: __exit__, self, as_value
pythontech 0:5868e8752d44 2053 adjust_stack(emit, 3);
pythontech 0:5868e8752d44 2054 // stack: (..., __exit__, self, as_value, nlr_buf.prev, nlr_buf.ret_val)
pythontech 0:5868e8752d44 2055
pythontech 0:5868e8752d44 2056 vtype_kind_t vtype;
pythontech 0:5868e8752d44 2057 emit_pre_pop_reg(emit, &vtype, REG_ARG_1); // get the thrown value (exc)
pythontech 0:5868e8752d44 2058 adjust_stack(emit, -2); // discard nlr_buf.prev and as_value
pythontech 0:5868e8752d44 2059 // stack: (..., __exit__, self)
pythontech 0:5868e8752d44 2060 // REG_ARG_1=exc
pythontech 0:5868e8752d44 2061
pythontech 0:5868e8752d44 2062 emit_pre_pop_reg(emit, &vtype, REG_ARG_2); // self
pythontech 0:5868e8752d44 2063 emit_pre_pop_reg(emit, &vtype, REG_ARG_3); // __exit__
pythontech 0:5868e8752d44 2064 adjust_stack(emit, 1); // dummy nlr_buf.prev
pythontech 0:5868e8752d44 2065 emit_post_push_reg(emit, vtype, REG_ARG_1); // push exc to save it for later
pythontech 0:5868e8752d44 2066 emit_post_push_reg(emit, vtype, REG_ARG_3); // __exit__
pythontech 0:5868e8752d44 2067 emit_post_push_reg(emit, vtype, REG_ARG_2); // self
pythontech 0:5868e8752d44 2068 // stack: (..., exc, __exit__, self)
pythontech 0:5868e8752d44 2069 // REG_ARG_1=exc
pythontech 0:5868e8752d44 2070
pythontech 0:5868e8752d44 2071 ASM_LOAD_REG_REG_OFFSET(emit->as, REG_ARG_2, REG_ARG_1, 0); // get type(exc)
pythontech 0:5868e8752d44 2072 emit_post_push_reg(emit, VTYPE_PYOBJ, REG_ARG_2); // push type(exc)
pythontech 0:5868e8752d44 2073 emit_post_push_reg(emit, VTYPE_PYOBJ, REG_ARG_1); // push exc value
pythontech 0:5868e8752d44 2074 emit_post_push_imm(emit, VTYPE_PYOBJ, (mp_uint_t)mp_const_none); // traceback info
pythontech 0:5868e8752d44 2075 // stack: (..., exc, __exit__, self, type(exc), exc, traceback)
pythontech 0:5868e8752d44 2076
pythontech 0:5868e8752d44 2077 // call __exit__ method
pythontech 0:5868e8752d44 2078 emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_3, 5);
pythontech 0:5868e8752d44 2079 emit_call_with_2_imm_args(emit, MP_F_CALL_METHOD_N_KW, 3, REG_ARG_1, 0, REG_ARG_2);
pythontech 0:5868e8752d44 2080 // stack: (..., exc)
pythontech 0:5868e8752d44 2081
pythontech 0:5868e8752d44 2082 // if REG_RET is true then we need to replace top-of-stack with None (swallow exception)
pythontech 0:5868e8752d44 2083 if (REG_ARG_1 != REG_RET) {
pythontech 0:5868e8752d44 2084 ASM_MOV_REG_REG(emit->as, REG_ARG_1, REG_RET);
pythontech 0:5868e8752d44 2085 }
pythontech 0:5868e8752d44 2086 emit_call(emit, MP_F_OBJ_IS_TRUE);
pythontech 0:5868e8752d44 2087 ASM_JUMP_IF_REG_ZERO(emit->as, REG_RET, label + 1);
pythontech 0:5868e8752d44 2088
pythontech 0:5868e8752d44 2089 // replace exc with None
pythontech 0:5868e8752d44 2090 emit_pre_pop_discard(emit);
pythontech 0:5868e8752d44 2091 emit_post_push_imm(emit, VTYPE_PYOBJ, (mp_uint_t)mp_const_none);
pythontech 0:5868e8752d44 2092
pythontech 0:5868e8752d44 2093 // end of with cleanup nlr_catch block
pythontech 0:5868e8752d44 2094 emit_native_label_assign(emit, label + 1);
pythontech 0:5868e8752d44 2095 }
pythontech 0:5868e8752d44 2096
pythontech 0:5868e8752d44 2097 STATIC void emit_native_setup_except(emit_t *emit, mp_uint_t label) {
pythontech 0:5868e8752d44 2098 emit_native_pre(emit);
pythontech 0:5868e8752d44 2099 // need to commit stack because we may jump elsewhere
pythontech 0:5868e8752d44 2100 need_stack_settled(emit);
pythontech 0:5868e8752d44 2101 emit_get_stack_pointer_to_reg_for_push(emit, REG_ARG_1, sizeof(nlr_buf_t) / sizeof(mp_uint_t)); // arg1 = pointer to nlr buf
pythontech 0:5868e8752d44 2102 emit_call(emit, MP_F_NLR_PUSH);
pythontech 0:5868e8752d44 2103 ASM_JUMP_IF_REG_NONZERO(emit->as, REG_RET, label);
pythontech 0:5868e8752d44 2104 emit_post(emit);
pythontech 0:5868e8752d44 2105 }
pythontech 0:5868e8752d44 2106
pythontech 0:5868e8752d44 2107 STATIC void emit_native_setup_finally(emit_t *emit, mp_uint_t label) {
pythontech 0:5868e8752d44 2108 emit_native_setup_except(emit, label);
pythontech 0:5868e8752d44 2109 }
pythontech 0:5868e8752d44 2110
pythontech 0:5868e8752d44 2111 STATIC void emit_native_end_finally(emit_t *emit) {
pythontech 0:5868e8752d44 2112 // logic:
pythontech 0:5868e8752d44 2113 // exc = pop_stack
pythontech 0:5868e8752d44 2114 // if exc == None: pass
pythontech 0:5868e8752d44 2115 // else: raise exc
pythontech 0:5868e8752d44 2116 // the check if exc is None is done in the MP_F_NATIVE_RAISE stub
pythontech 0:5868e8752d44 2117 vtype_kind_t vtype;
pythontech 0:5868e8752d44 2118 emit_pre_pop_reg(emit, &vtype, REG_ARG_1); // get nlr_buf.ret_val
pythontech 0:5868e8752d44 2119 emit_pre_pop_discard(emit); // discard nlr_buf.prev
pythontech 0:5868e8752d44 2120 emit_call(emit, MP_F_NATIVE_RAISE);
pythontech 0:5868e8752d44 2121 emit_post(emit);
pythontech 0:5868e8752d44 2122 }
pythontech 0:5868e8752d44 2123
pythontech 0:5868e8752d44 2124 STATIC void emit_native_get_iter(emit_t *emit) {
pythontech 0:5868e8752d44 2125 // perhaps the difficult one, as we want to rewrite for loops using native code
pythontech 0:5868e8752d44 2126 // in cases where we iterate over a Python object, can we use normal runtime calls?
pythontech 0:5868e8752d44 2127
pythontech 0:5868e8752d44 2128 vtype_kind_t vtype;
pythontech 0:5868e8752d44 2129 emit_pre_pop_reg(emit, &vtype, REG_ARG_1);
pythontech 0:5868e8752d44 2130 assert(vtype == VTYPE_PYOBJ);
pythontech 0:5868e8752d44 2131 emit_call(emit, MP_F_GETITER);
pythontech 0:5868e8752d44 2132 emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
pythontech 0:5868e8752d44 2133 }
pythontech 0:5868e8752d44 2134
pythontech 0:5868e8752d44 2135 STATIC void emit_native_for_iter(emit_t *emit, mp_uint_t label) {
pythontech 0:5868e8752d44 2136 emit_native_pre(emit);
pythontech 0:5868e8752d44 2137 vtype_kind_t vtype;
pythontech 0:5868e8752d44 2138 emit_access_stack(emit, 1, &vtype, REG_ARG_1);
pythontech 0:5868e8752d44 2139 assert(vtype == VTYPE_PYOBJ);
pythontech 0:5868e8752d44 2140 emit_call(emit, MP_F_ITERNEXT);
pythontech 0:5868e8752d44 2141 ASM_MOV_IMM_TO_REG(emit->as, (mp_uint_t)MP_OBJ_STOP_ITERATION, REG_TEMP1);
pythontech 0:5868e8752d44 2142 ASM_JUMP_IF_REG_EQ(emit->as, REG_RET, REG_TEMP1, label);
pythontech 0:5868e8752d44 2143 emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
pythontech 0:5868e8752d44 2144 }
pythontech 0:5868e8752d44 2145
pythontech 0:5868e8752d44 2146 STATIC void emit_native_for_iter_end(emit_t *emit) {
pythontech 0:5868e8752d44 2147 // adjust stack counter (we get here from for_iter ending, which popped the value for us)
pythontech 0:5868e8752d44 2148 emit_native_pre(emit);
pythontech 0:5868e8752d44 2149 adjust_stack(emit, -1);
pythontech 0:5868e8752d44 2150 emit_post(emit);
pythontech 0:5868e8752d44 2151 }
pythontech 0:5868e8752d44 2152
pythontech 0:5868e8752d44 2153 STATIC void emit_native_pop_block(emit_t *emit) {
pythontech 0:5868e8752d44 2154 emit_native_pre(emit);
pythontech 0:5868e8752d44 2155 emit_call(emit, MP_F_NLR_POP);
pythontech 0:5868e8752d44 2156 adjust_stack(emit, -(mp_int_t)(sizeof(nlr_buf_t) / sizeof(mp_uint_t)) + 1);
pythontech 0:5868e8752d44 2157 emit_post(emit);
pythontech 0:5868e8752d44 2158 }
pythontech 0:5868e8752d44 2159
pythontech 0:5868e8752d44 2160 STATIC void emit_native_pop_except(emit_t *emit) {
pythontech 0:5868e8752d44 2161 (void)emit;
pythontech 0:5868e8752d44 2162 /*
pythontech 0:5868e8752d44 2163 emit_native_pre(emit);
pythontech 0:5868e8752d44 2164 emit_call(emit, MP_F_NLR_POP);
pythontech 0:5868e8752d44 2165 adjust_stack(emit, -(mp_int_t)(sizeof(nlr_buf_t) / sizeof(mp_uint_t)));
pythontech 0:5868e8752d44 2166 emit_post(emit);
pythontech 0:5868e8752d44 2167 */
pythontech 0:5868e8752d44 2168 }
pythontech 0:5868e8752d44 2169
pythontech 0:5868e8752d44 2170 STATIC void emit_native_unary_op(emit_t *emit, mp_unary_op_t op) {
pythontech 0:5868e8752d44 2171 vtype_kind_t vtype;
pythontech 0:5868e8752d44 2172 emit_pre_pop_reg(emit, &vtype, REG_ARG_2);
pythontech 0:5868e8752d44 2173 if (vtype == VTYPE_PYOBJ) {
pythontech 0:5868e8752d44 2174 emit_call_with_imm_arg(emit, MP_F_UNARY_OP, op, REG_ARG_1);
pythontech 0:5868e8752d44 2175 emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
pythontech 0:5868e8752d44 2176 } else {
pythontech 0:5868e8752d44 2177 adjust_stack(emit, 1);
pythontech 0:5868e8752d44 2178 EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
pythontech 0:5868e8752d44 2179 "unary op %q not implemented", mp_unary_op_method_name[op]);
pythontech 0:5868e8752d44 2180 }
pythontech 0:5868e8752d44 2181 }
pythontech 0:5868e8752d44 2182
pythontech 0:5868e8752d44 2183 STATIC void emit_native_binary_op(emit_t *emit, mp_binary_op_t op) {
pythontech 0:5868e8752d44 2184 DEBUG_printf("binary_op(" UINT_FMT ")\n", op);
pythontech 0:5868e8752d44 2185 vtype_kind_t vtype_lhs = peek_vtype(emit, 1);
pythontech 0:5868e8752d44 2186 vtype_kind_t vtype_rhs = peek_vtype(emit, 0);
pythontech 0:5868e8752d44 2187 if (vtype_lhs == VTYPE_INT && vtype_rhs == VTYPE_INT) {
pythontech 0:5868e8752d44 2188 #if N_X64 || N_X86
pythontech 0:5868e8752d44 2189 // special cases for x86 and shifting
pythontech 0:5868e8752d44 2190 if (op == MP_BINARY_OP_LSHIFT
pythontech 0:5868e8752d44 2191 || op == MP_BINARY_OP_INPLACE_LSHIFT
pythontech 0:5868e8752d44 2192 || op == MP_BINARY_OP_RSHIFT
pythontech 0:5868e8752d44 2193 || op == MP_BINARY_OP_INPLACE_RSHIFT) {
pythontech 0:5868e8752d44 2194 #if N_X64
pythontech 0:5868e8752d44 2195 emit_pre_pop_reg_reg(emit, &vtype_rhs, ASM_X64_REG_RCX, &vtype_lhs, REG_RET);
pythontech 0:5868e8752d44 2196 #else
pythontech 0:5868e8752d44 2197 emit_pre_pop_reg_reg(emit, &vtype_rhs, ASM_X86_REG_ECX, &vtype_lhs, REG_RET);
pythontech 0:5868e8752d44 2198 #endif
pythontech 0:5868e8752d44 2199 if (op == MP_BINARY_OP_LSHIFT || op == MP_BINARY_OP_INPLACE_LSHIFT) {
pythontech 0:5868e8752d44 2200 ASM_LSL_REG(emit->as, REG_RET);
pythontech 0:5868e8752d44 2201 } else {
pythontech 0:5868e8752d44 2202 ASM_ASR_REG(emit->as, REG_RET);
pythontech 0:5868e8752d44 2203 }
pythontech 0:5868e8752d44 2204 emit_post_push_reg(emit, VTYPE_INT, REG_RET);
pythontech 0:5868e8752d44 2205 return;
pythontech 0:5868e8752d44 2206 }
pythontech 0:5868e8752d44 2207 #endif
pythontech 0:5868e8752d44 2208 int reg_rhs = REG_ARG_3;
pythontech 0:5868e8752d44 2209 emit_pre_pop_reg_flexible(emit, &vtype_rhs, &reg_rhs, REG_RET, REG_ARG_2);
pythontech 0:5868e8752d44 2210 emit_pre_pop_reg(emit, &vtype_lhs, REG_ARG_2);
pythontech 0:5868e8752d44 2211 if (0) {
pythontech 0:5868e8752d44 2212 // dummy
pythontech 0:5868e8752d44 2213 #if !(N_X64 || N_X86)
pythontech 0:5868e8752d44 2214 } else if (op == MP_BINARY_OP_LSHIFT || op == MP_BINARY_OP_INPLACE_LSHIFT) {
pythontech 0:5868e8752d44 2215 ASM_LSL_REG_REG(emit->as, REG_ARG_2, reg_rhs);
pythontech 0:5868e8752d44 2216 emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2);
pythontech 0:5868e8752d44 2217 } else if (op == MP_BINARY_OP_RSHIFT || op == MP_BINARY_OP_INPLACE_RSHIFT) {
pythontech 0:5868e8752d44 2218 ASM_ASR_REG_REG(emit->as, REG_ARG_2, reg_rhs);
pythontech 0:5868e8752d44 2219 emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2);
pythontech 0:5868e8752d44 2220 #endif
pythontech 0:5868e8752d44 2221 } else if (op == MP_BINARY_OP_OR || op == MP_BINARY_OP_INPLACE_OR) {
pythontech 0:5868e8752d44 2222 ASM_OR_REG_REG(emit->as, REG_ARG_2, reg_rhs);
pythontech 0:5868e8752d44 2223 emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2);
pythontech 0:5868e8752d44 2224 } else if (op == MP_BINARY_OP_XOR || op == MP_BINARY_OP_INPLACE_XOR) {
pythontech 0:5868e8752d44 2225 ASM_XOR_REG_REG(emit->as, REG_ARG_2, reg_rhs);
pythontech 0:5868e8752d44 2226 emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2);
pythontech 0:5868e8752d44 2227 } else if (op == MP_BINARY_OP_AND || op == MP_BINARY_OP_INPLACE_AND) {
pythontech 0:5868e8752d44 2228 ASM_AND_REG_REG(emit->as, REG_ARG_2, reg_rhs);
pythontech 0:5868e8752d44 2229 emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2);
pythontech 0:5868e8752d44 2230 } else if (op == MP_BINARY_OP_ADD || op == MP_BINARY_OP_INPLACE_ADD) {
pythontech 0:5868e8752d44 2231 ASM_ADD_REG_REG(emit->as, REG_ARG_2, reg_rhs);
pythontech 0:5868e8752d44 2232 emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2);
pythontech 0:5868e8752d44 2233 } else if (op == MP_BINARY_OP_SUBTRACT || op == MP_BINARY_OP_INPLACE_SUBTRACT) {
pythontech 0:5868e8752d44 2234 ASM_SUB_REG_REG(emit->as, REG_ARG_2, reg_rhs);
pythontech 0:5868e8752d44 2235 emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2);
pythontech 0:5868e8752d44 2236 } else if (op == MP_BINARY_OP_MULTIPLY || op == MP_BINARY_OP_INPLACE_MULTIPLY) {
pythontech 0:5868e8752d44 2237 ASM_MUL_REG_REG(emit->as, REG_ARG_2, reg_rhs);
pythontech 0:5868e8752d44 2238 emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2);
pythontech 0:5868e8752d44 2239 } else if (MP_BINARY_OP_LESS <= op && op <= MP_BINARY_OP_NOT_EQUAL) {
pythontech 0:5868e8752d44 2240 // comparison ops are (in enum order):
pythontech 0:5868e8752d44 2241 // MP_BINARY_OP_LESS
pythontech 0:5868e8752d44 2242 // MP_BINARY_OP_MORE
pythontech 0:5868e8752d44 2243 // MP_BINARY_OP_EQUAL
pythontech 0:5868e8752d44 2244 // MP_BINARY_OP_LESS_EQUAL
pythontech 0:5868e8752d44 2245 // MP_BINARY_OP_MORE_EQUAL
pythontech 0:5868e8752d44 2246 // MP_BINARY_OP_NOT_EQUAL
pythontech 0:5868e8752d44 2247 need_reg_single(emit, REG_RET, 0);
pythontech 0:5868e8752d44 2248 #if N_X64
pythontech 0:5868e8752d44 2249 asm_x64_xor_r64_r64(emit->as, REG_RET, REG_RET);
pythontech 0:5868e8752d44 2250 asm_x64_cmp_r64_with_r64(emit->as, reg_rhs, REG_ARG_2);
pythontech 0:5868e8752d44 2251 static byte ops[6] = {
pythontech 0:5868e8752d44 2252 ASM_X64_CC_JL,
pythontech 0:5868e8752d44 2253 ASM_X64_CC_JG,
pythontech 0:5868e8752d44 2254 ASM_X64_CC_JE,
pythontech 0:5868e8752d44 2255 ASM_X64_CC_JLE,
pythontech 0:5868e8752d44 2256 ASM_X64_CC_JGE,
pythontech 0:5868e8752d44 2257 ASM_X64_CC_JNE,
pythontech 0:5868e8752d44 2258 };
pythontech 0:5868e8752d44 2259 asm_x64_setcc_r8(emit->as, ops[op - MP_BINARY_OP_LESS], REG_RET);
pythontech 0:5868e8752d44 2260 #elif N_X86
pythontech 0:5868e8752d44 2261 asm_x86_xor_r32_r32(emit->as, REG_RET, REG_RET);
pythontech 0:5868e8752d44 2262 asm_x86_cmp_r32_with_r32(emit->as, reg_rhs, REG_ARG_2);
pythontech 0:5868e8752d44 2263 static byte ops[6] = {
pythontech 0:5868e8752d44 2264 ASM_X86_CC_JL,
pythontech 0:5868e8752d44 2265 ASM_X86_CC_JG,
pythontech 0:5868e8752d44 2266 ASM_X86_CC_JE,
pythontech 0:5868e8752d44 2267 ASM_X86_CC_JLE,
pythontech 0:5868e8752d44 2268 ASM_X86_CC_JGE,
pythontech 0:5868e8752d44 2269 ASM_X86_CC_JNE,
pythontech 0:5868e8752d44 2270 };
pythontech 0:5868e8752d44 2271 asm_x86_setcc_r8(emit->as, ops[op - MP_BINARY_OP_LESS], REG_RET);
pythontech 0:5868e8752d44 2272 #elif N_THUMB
pythontech 0:5868e8752d44 2273 asm_thumb_cmp_rlo_rlo(emit->as, REG_ARG_2, reg_rhs);
pythontech 0:5868e8752d44 2274 static uint16_t ops[6] = {
pythontech 0:5868e8752d44 2275 ASM_THUMB_OP_ITE_GE,
pythontech 0:5868e8752d44 2276 ASM_THUMB_OP_ITE_GT,
pythontech 0:5868e8752d44 2277 ASM_THUMB_OP_ITE_EQ,
pythontech 0:5868e8752d44 2278 ASM_THUMB_OP_ITE_GT,
pythontech 0:5868e8752d44 2279 ASM_THUMB_OP_ITE_GE,
pythontech 0:5868e8752d44 2280 ASM_THUMB_OP_ITE_EQ,
pythontech 0:5868e8752d44 2281 };
pythontech 0:5868e8752d44 2282 static byte ret[6] = { 0, 1, 1, 0, 1, 0, };
pythontech 0:5868e8752d44 2283 asm_thumb_op16(emit->as, ops[op - MP_BINARY_OP_LESS]);
pythontech 0:5868e8752d44 2284 asm_thumb_mov_rlo_i8(emit->as, REG_RET, ret[op - MP_BINARY_OP_LESS]);
pythontech 0:5868e8752d44 2285 asm_thumb_mov_rlo_i8(emit->as, REG_RET, ret[op - MP_BINARY_OP_LESS] ^ 1);
pythontech 0:5868e8752d44 2286 #elif N_ARM
pythontech 0:5868e8752d44 2287 asm_arm_cmp_reg_reg(emit->as, REG_ARG_2, reg_rhs);
pythontech 0:5868e8752d44 2288 static uint ccs[6] = {
pythontech 0:5868e8752d44 2289 ASM_ARM_CC_LT,
pythontech 0:5868e8752d44 2290 ASM_ARM_CC_GT,
pythontech 0:5868e8752d44 2291 ASM_ARM_CC_EQ,
pythontech 0:5868e8752d44 2292 ASM_ARM_CC_LE,
pythontech 0:5868e8752d44 2293 ASM_ARM_CC_GE,
pythontech 0:5868e8752d44 2294 ASM_ARM_CC_NE,
pythontech 0:5868e8752d44 2295 };
pythontech 0:5868e8752d44 2296 asm_arm_setcc_reg(emit->as, REG_RET, ccs[op - MP_BINARY_OP_LESS]);
pythontech 0:5868e8752d44 2297 #else
pythontech 0:5868e8752d44 2298 #error not implemented
pythontech 0:5868e8752d44 2299 #endif
pythontech 0:5868e8752d44 2300 emit_post_push_reg(emit, VTYPE_BOOL, REG_RET);
pythontech 0:5868e8752d44 2301 } else {
pythontech 0:5868e8752d44 2302 // TODO other ops not yet implemented
pythontech 0:5868e8752d44 2303 adjust_stack(emit, 1);
pythontech 0:5868e8752d44 2304 EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
pythontech 0:5868e8752d44 2305 "binary op %q not implemented", mp_binary_op_method_name[op]);
pythontech 0:5868e8752d44 2306 }
pythontech 0:5868e8752d44 2307 } else if (vtype_lhs == VTYPE_PYOBJ && vtype_rhs == VTYPE_PYOBJ) {
pythontech 0:5868e8752d44 2308 emit_pre_pop_reg_reg(emit, &vtype_rhs, REG_ARG_3, &vtype_lhs, REG_ARG_2);
pythontech 0:5868e8752d44 2309 bool invert = false;
pythontech 0:5868e8752d44 2310 if (op == MP_BINARY_OP_NOT_IN) {
pythontech 0:5868e8752d44 2311 invert = true;
pythontech 0:5868e8752d44 2312 op = MP_BINARY_OP_IN;
pythontech 0:5868e8752d44 2313 } else if (op == MP_BINARY_OP_IS_NOT) {
pythontech 0:5868e8752d44 2314 invert = true;
pythontech 0:5868e8752d44 2315 op = MP_BINARY_OP_IS;
pythontech 0:5868e8752d44 2316 }
pythontech 0:5868e8752d44 2317 emit_call_with_imm_arg(emit, MP_F_BINARY_OP, op, REG_ARG_1);
pythontech 0:5868e8752d44 2318 if (invert) {
pythontech 0:5868e8752d44 2319 ASM_MOV_REG_REG(emit->as, REG_ARG_2, REG_RET);
pythontech 0:5868e8752d44 2320 emit_call_with_imm_arg(emit, MP_F_UNARY_OP, MP_UNARY_OP_NOT, REG_ARG_1);
pythontech 0:5868e8752d44 2321 }
pythontech 0:5868e8752d44 2322 emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
pythontech 0:5868e8752d44 2323 } else {
pythontech 0:5868e8752d44 2324 adjust_stack(emit, -1);
pythontech 0:5868e8752d44 2325 EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
pythontech 0:5868e8752d44 2326 "can't do binary op between '%q' and '%q'",
pythontech 0:5868e8752d44 2327 vtype_to_qstr(vtype_lhs), vtype_to_qstr(vtype_rhs));
pythontech 0:5868e8752d44 2328 }
pythontech 0:5868e8752d44 2329 }
pythontech 0:5868e8752d44 2330
pythontech 0:5868e8752d44 2331 STATIC void emit_native_build_tuple(emit_t *emit, mp_uint_t n_args) {
pythontech 0:5868e8752d44 2332 // for viper: call runtime, with types of args
pythontech 0:5868e8752d44 2333 // if wrapped in byte_array, or something, allocates memory and fills it
pythontech 0:5868e8752d44 2334 emit_native_pre(emit);
pythontech 0:5868e8752d44 2335 emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_2, n_args); // pointer to items
pythontech 0:5868e8752d44 2336 emit_call_with_imm_arg(emit, MP_F_BUILD_TUPLE, n_args, REG_ARG_1);
pythontech 0:5868e8752d44 2337 emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); // new tuple
pythontech 0:5868e8752d44 2338 }
pythontech 0:5868e8752d44 2339
pythontech 0:5868e8752d44 2340 STATIC void emit_native_build_list(emit_t *emit, mp_uint_t n_args) {
pythontech 0:5868e8752d44 2341 emit_native_pre(emit);
pythontech 0:5868e8752d44 2342 emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_2, n_args); // pointer to items
pythontech 0:5868e8752d44 2343 emit_call_with_imm_arg(emit, MP_F_BUILD_LIST, n_args, REG_ARG_1);
pythontech 0:5868e8752d44 2344 emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); // new list
pythontech 0:5868e8752d44 2345 }
pythontech 0:5868e8752d44 2346
pythontech 0:5868e8752d44 2347 STATIC void emit_native_list_append(emit_t *emit, mp_uint_t list_index) {
pythontech 0:5868e8752d44 2348 // only used in list comprehension
pythontech 0:5868e8752d44 2349 vtype_kind_t vtype_list, vtype_item;
pythontech 0:5868e8752d44 2350 emit_pre_pop_reg(emit, &vtype_item, REG_ARG_2);
pythontech 0:5868e8752d44 2351 emit_access_stack(emit, list_index, &vtype_list, REG_ARG_1);
pythontech 0:5868e8752d44 2352 assert(vtype_list == VTYPE_PYOBJ);
pythontech 0:5868e8752d44 2353 assert(vtype_item == VTYPE_PYOBJ);
pythontech 0:5868e8752d44 2354 emit_call(emit, MP_F_LIST_APPEND);
pythontech 0:5868e8752d44 2355 emit_post(emit);
pythontech 0:5868e8752d44 2356 }
pythontech 0:5868e8752d44 2357
pythontech 0:5868e8752d44 2358 STATIC void emit_native_build_map(emit_t *emit, mp_uint_t n_args) {
pythontech 0:5868e8752d44 2359 emit_native_pre(emit);
pythontech 0:5868e8752d44 2360 emit_call_with_imm_arg(emit, MP_F_BUILD_MAP, n_args, REG_ARG_1);
pythontech 0:5868e8752d44 2361 emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); // new map
pythontech 0:5868e8752d44 2362 }
pythontech 0:5868e8752d44 2363
pythontech 0:5868e8752d44 2364 STATIC void emit_native_store_map(emit_t *emit) {
pythontech 0:5868e8752d44 2365 vtype_kind_t vtype_key, vtype_value, vtype_map;
pythontech 0:5868e8752d44 2366 emit_pre_pop_reg_reg_reg(emit, &vtype_key, REG_ARG_2, &vtype_value, REG_ARG_3, &vtype_map, REG_ARG_1); // key, value, map
pythontech 0:5868e8752d44 2367 assert(vtype_key == VTYPE_PYOBJ);
pythontech 0:5868e8752d44 2368 assert(vtype_value == VTYPE_PYOBJ);
pythontech 0:5868e8752d44 2369 assert(vtype_map == VTYPE_PYOBJ);
pythontech 0:5868e8752d44 2370 emit_call(emit, MP_F_STORE_MAP);
pythontech 0:5868e8752d44 2371 emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); // map
pythontech 0:5868e8752d44 2372 }
pythontech 0:5868e8752d44 2373
pythontech 0:5868e8752d44 2374 STATIC void emit_native_map_add(emit_t *emit, mp_uint_t map_index) {
pythontech 0:5868e8752d44 2375 // only used in list comprehension
pythontech 0:5868e8752d44 2376 vtype_kind_t vtype_map, vtype_key, vtype_value;
pythontech 0:5868e8752d44 2377 emit_pre_pop_reg_reg(emit, &vtype_key, REG_ARG_2, &vtype_value, REG_ARG_3);
pythontech 0:5868e8752d44 2378 emit_access_stack(emit, map_index, &vtype_map, REG_ARG_1);
pythontech 0:5868e8752d44 2379 assert(vtype_map == VTYPE_PYOBJ);
pythontech 0:5868e8752d44 2380 assert(vtype_key == VTYPE_PYOBJ);
pythontech 0:5868e8752d44 2381 assert(vtype_value == VTYPE_PYOBJ);
pythontech 0:5868e8752d44 2382 emit_call(emit, MP_F_STORE_MAP);
pythontech 0:5868e8752d44 2383 emit_post(emit);
pythontech 0:5868e8752d44 2384 }
pythontech 0:5868e8752d44 2385
pythontech 0:5868e8752d44 2386 #if MICROPY_PY_BUILTINS_SET
pythontech 0:5868e8752d44 2387 STATIC void emit_native_build_set(emit_t *emit, mp_uint_t n_args) {
pythontech 0:5868e8752d44 2388 emit_native_pre(emit);
pythontech 0:5868e8752d44 2389 emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_2, n_args); // pointer to items
pythontech 0:5868e8752d44 2390 emit_call_with_imm_arg(emit, MP_F_BUILD_SET, n_args, REG_ARG_1);
pythontech 0:5868e8752d44 2391 emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); // new set
pythontech 0:5868e8752d44 2392 }
pythontech 0:5868e8752d44 2393
pythontech 0:5868e8752d44 2394 STATIC void emit_native_set_add(emit_t *emit, mp_uint_t set_index) {
pythontech 0:5868e8752d44 2395 // only used in set comprehension
pythontech 0:5868e8752d44 2396 vtype_kind_t vtype_set, vtype_item;
pythontech 0:5868e8752d44 2397 emit_pre_pop_reg(emit, &vtype_item, REG_ARG_2);
pythontech 0:5868e8752d44 2398 emit_access_stack(emit, set_index, &vtype_set, REG_ARG_1);
pythontech 0:5868e8752d44 2399 assert(vtype_set == VTYPE_PYOBJ);
pythontech 0:5868e8752d44 2400 assert(vtype_item == VTYPE_PYOBJ);
pythontech 0:5868e8752d44 2401 emit_call(emit, MP_F_STORE_SET);
pythontech 0:5868e8752d44 2402 emit_post(emit);
pythontech 0:5868e8752d44 2403 }
pythontech 0:5868e8752d44 2404 #endif
pythontech 0:5868e8752d44 2405
pythontech 0:5868e8752d44 2406 #if MICROPY_PY_BUILTINS_SLICE
pythontech 0:5868e8752d44 2407 STATIC void emit_native_build_slice(emit_t *emit, mp_uint_t n_args) {
pythontech 0:5868e8752d44 2408 DEBUG_printf("build_slice %d\n", n_args);
pythontech 0:5868e8752d44 2409 if (n_args == 2) {
pythontech 0:5868e8752d44 2410 vtype_kind_t vtype_start, vtype_stop;
pythontech 0:5868e8752d44 2411 emit_pre_pop_reg_reg(emit, &vtype_stop, REG_ARG_2, &vtype_start, REG_ARG_1); // arg1 = start, arg2 = stop
pythontech 0:5868e8752d44 2412 assert(vtype_start == VTYPE_PYOBJ);
pythontech 0:5868e8752d44 2413 assert(vtype_stop == VTYPE_PYOBJ);
pythontech 0:5868e8752d44 2414 emit_call_with_imm_arg(emit, MP_F_NEW_SLICE, (mp_uint_t)mp_const_none, REG_ARG_3); // arg3 = step
pythontech 0:5868e8752d44 2415 emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
pythontech 0:5868e8752d44 2416 } else {
pythontech 0:5868e8752d44 2417 assert(n_args == 3);
pythontech 0:5868e8752d44 2418 vtype_kind_t vtype_start, vtype_stop, vtype_step;
pythontech 0:5868e8752d44 2419 emit_pre_pop_reg_reg_reg(emit, &vtype_step, REG_ARG_3, &vtype_stop, REG_ARG_2, &vtype_start, REG_ARG_1); // arg1 = start, arg2 = stop, arg3 = step
pythontech 0:5868e8752d44 2420 assert(vtype_start == VTYPE_PYOBJ);
pythontech 0:5868e8752d44 2421 assert(vtype_stop == VTYPE_PYOBJ);
pythontech 0:5868e8752d44 2422 assert(vtype_step == VTYPE_PYOBJ);
pythontech 0:5868e8752d44 2423 emit_call(emit, MP_F_NEW_SLICE);
pythontech 0:5868e8752d44 2424 emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
pythontech 0:5868e8752d44 2425 }
pythontech 0:5868e8752d44 2426 }
pythontech 0:5868e8752d44 2427 #endif
pythontech 0:5868e8752d44 2428
pythontech 0:5868e8752d44 2429 STATIC void emit_native_unpack_sequence(emit_t *emit, mp_uint_t n_args) {
pythontech 0:5868e8752d44 2430 DEBUG_printf("unpack_sequence %d\n", n_args);
pythontech 0:5868e8752d44 2431 vtype_kind_t vtype_base;
pythontech 0:5868e8752d44 2432 emit_pre_pop_reg(emit, &vtype_base, REG_ARG_1); // arg1 = seq
pythontech 0:5868e8752d44 2433 assert(vtype_base == VTYPE_PYOBJ);
pythontech 0:5868e8752d44 2434 emit_get_stack_pointer_to_reg_for_push(emit, REG_ARG_3, n_args); // arg3 = dest ptr
pythontech 0:5868e8752d44 2435 emit_call_with_imm_arg(emit, MP_F_UNPACK_SEQUENCE, n_args, REG_ARG_2); // arg2 = n_args
pythontech 0:5868e8752d44 2436 }
pythontech 0:5868e8752d44 2437
pythontech 0:5868e8752d44 2438 STATIC void emit_native_unpack_ex(emit_t *emit, mp_uint_t n_left, mp_uint_t n_right) {
pythontech 0:5868e8752d44 2439 DEBUG_printf("unpack_ex %d %d\n", n_left, n_right);
pythontech 0:5868e8752d44 2440 vtype_kind_t vtype_base;
pythontech 0:5868e8752d44 2441 emit_pre_pop_reg(emit, &vtype_base, REG_ARG_1); // arg1 = seq
pythontech 0:5868e8752d44 2442 assert(vtype_base == VTYPE_PYOBJ);
pythontech 0:5868e8752d44 2443 emit_get_stack_pointer_to_reg_for_push(emit, REG_ARG_3, n_left + n_right + 1); // arg3 = dest ptr
pythontech 0:5868e8752d44 2444 emit_call_with_imm_arg(emit, MP_F_UNPACK_EX, n_left | (n_right << 8), REG_ARG_2); // arg2 = n_left + n_right
pythontech 0:5868e8752d44 2445 }
pythontech 0:5868e8752d44 2446
pythontech 0:5868e8752d44 2447 STATIC void emit_native_make_function(emit_t *emit, scope_t *scope, mp_uint_t n_pos_defaults, mp_uint_t n_kw_defaults) {
pythontech 0:5868e8752d44 2448 // call runtime, with type info for args, or don't support dict/default params, or only support Python objects for them
pythontech 0:5868e8752d44 2449 emit_native_pre(emit);
pythontech 0:5868e8752d44 2450 if (n_pos_defaults == 0 && n_kw_defaults == 0) {
pythontech 0:5868e8752d44 2451 emit_call_with_3_imm_args_and_first_aligned(emit, MP_F_MAKE_FUNCTION_FROM_RAW_CODE, (mp_uint_t)scope->raw_code, REG_ARG_1, (mp_uint_t)MP_OBJ_NULL, REG_ARG_2, (mp_uint_t)MP_OBJ_NULL, REG_ARG_3);
pythontech 0:5868e8752d44 2452 } else {
pythontech 0:5868e8752d44 2453 vtype_kind_t vtype_def_tuple, vtype_def_dict;
pythontech 0:5868e8752d44 2454 emit_pre_pop_reg_reg(emit, &vtype_def_dict, REG_ARG_3, &vtype_def_tuple, REG_ARG_2);
pythontech 0:5868e8752d44 2455 assert(vtype_def_tuple == VTYPE_PYOBJ);
pythontech 0:5868e8752d44 2456 assert(vtype_def_dict == VTYPE_PYOBJ);
pythontech 0:5868e8752d44 2457 emit_call_with_imm_arg_aligned(emit, MP_F_MAKE_FUNCTION_FROM_RAW_CODE, (mp_uint_t)scope->raw_code, REG_ARG_1);
pythontech 0:5868e8752d44 2458 }
pythontech 0:5868e8752d44 2459 emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
pythontech 0:5868e8752d44 2460 }
pythontech 0:5868e8752d44 2461
pythontech 0:5868e8752d44 2462 STATIC void emit_native_make_closure(emit_t *emit, scope_t *scope, mp_uint_t n_closed_over, mp_uint_t n_pos_defaults, mp_uint_t n_kw_defaults) {
pythontech 0:5868e8752d44 2463 emit_native_pre(emit);
pythontech 0:5868e8752d44 2464 if (n_pos_defaults == 0 && n_kw_defaults == 0) {
pythontech 0:5868e8752d44 2465 emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_3, n_closed_over);
pythontech 0:5868e8752d44 2466 ASM_MOV_IMM_TO_REG(emit->as, n_closed_over, REG_ARG_2);
pythontech 0:5868e8752d44 2467 } else {
pythontech 0:5868e8752d44 2468 emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_3, n_closed_over + 2);
pythontech 0:5868e8752d44 2469 ASM_MOV_IMM_TO_REG(emit->as, 0x100 | n_closed_over, REG_ARG_2);
pythontech 0:5868e8752d44 2470 }
pythontech 0:5868e8752d44 2471 ASM_MOV_ALIGNED_IMM_TO_REG(emit->as, (mp_uint_t)scope->raw_code, REG_ARG_1);
pythontech 0:5868e8752d44 2472 ASM_CALL_IND(emit->as, mp_fun_table[MP_F_MAKE_CLOSURE_FROM_RAW_CODE], MP_F_MAKE_CLOSURE_FROM_RAW_CODE);
pythontech 0:5868e8752d44 2473 emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
pythontech 0:5868e8752d44 2474 }
pythontech 0:5868e8752d44 2475
pythontech 0:5868e8752d44 2476 STATIC void emit_native_call_function(emit_t *emit, mp_uint_t n_positional, mp_uint_t n_keyword, mp_uint_t star_flags) {
pythontech 0:5868e8752d44 2477 DEBUG_printf("call_function(n_pos=" UINT_FMT ", n_kw=" UINT_FMT ", star_flags=" UINT_FMT ")\n", n_positional, n_keyword, star_flags);
pythontech 0:5868e8752d44 2478
pythontech 0:5868e8752d44 2479 // TODO: in viper mode, call special runtime routine with type info for args,
pythontech 0:5868e8752d44 2480 // and wanted type info for return, to remove need for boxing/unboxing
pythontech 0:5868e8752d44 2481
pythontech 0:5868e8752d44 2482 emit_native_pre(emit);
pythontech 0:5868e8752d44 2483 vtype_kind_t vtype_fun = peek_vtype(emit, n_positional + 2 * n_keyword);
pythontech 0:5868e8752d44 2484 if (vtype_fun == VTYPE_BUILTIN_CAST) {
pythontech 0:5868e8752d44 2485 // casting operator
pythontech 0:5868e8752d44 2486 assert(n_positional == 1 && n_keyword == 0);
pythontech 0:5868e8752d44 2487 assert(!star_flags);
pythontech 0:5868e8752d44 2488 DEBUG_printf(" cast to %d\n", vtype_fun);
pythontech 0:5868e8752d44 2489 vtype_kind_t vtype_cast = peek_stack(emit, 1)->data.u_imm;
pythontech 0:5868e8752d44 2490 switch (peek_vtype(emit, 0)) {
pythontech 0:5868e8752d44 2491 case VTYPE_PYOBJ: {
pythontech 0:5868e8752d44 2492 vtype_kind_t vtype;
pythontech 0:5868e8752d44 2493 emit_pre_pop_reg(emit, &vtype, REG_ARG_1);
pythontech 0:5868e8752d44 2494 emit_pre_pop_discard(emit);
pythontech 0:5868e8752d44 2495 emit_call_with_imm_arg(emit, MP_F_CONVERT_OBJ_TO_NATIVE, vtype_cast, REG_ARG_2); // arg2 = type
pythontech 0:5868e8752d44 2496 emit_post_push_reg(emit, vtype_cast, REG_RET);
pythontech 0:5868e8752d44 2497 break;
pythontech 0:5868e8752d44 2498 }
pythontech 0:5868e8752d44 2499 case VTYPE_BOOL:
pythontech 0:5868e8752d44 2500 case VTYPE_INT:
pythontech 0:5868e8752d44 2501 case VTYPE_UINT:
pythontech 0:5868e8752d44 2502 case VTYPE_PTR:
pythontech 0:5868e8752d44 2503 case VTYPE_PTR8:
pythontech 0:5868e8752d44 2504 case VTYPE_PTR16:
pythontech 0:5868e8752d44 2505 case VTYPE_PTR32:
pythontech 0:5868e8752d44 2506 case VTYPE_PTR_NONE:
pythontech 0:5868e8752d44 2507 emit_fold_stack_top(emit, REG_ARG_1);
pythontech 0:5868e8752d44 2508 emit_post_top_set_vtype(emit, vtype_cast);
pythontech 0:5868e8752d44 2509 break;
pythontech 0:5868e8752d44 2510 default:
pythontech 0:5868e8752d44 2511 assert(!"TODO: convert obj to int");
pythontech 0:5868e8752d44 2512 }
pythontech 0:5868e8752d44 2513 } else {
pythontech 0:5868e8752d44 2514 assert(vtype_fun == VTYPE_PYOBJ);
pythontech 0:5868e8752d44 2515 if (star_flags) {
pythontech 0:5868e8752d44 2516 emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_3, n_positional + 2 * n_keyword + 3); // pointer to args
pythontech 0:5868e8752d44 2517 emit_call_with_2_imm_args(emit, MP_F_CALL_METHOD_N_KW_VAR, 0, REG_ARG_1, n_positional | (n_keyword << 8), REG_ARG_2);
pythontech 0:5868e8752d44 2518 emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
pythontech 0:5868e8752d44 2519 } else {
pythontech 0:5868e8752d44 2520 if (n_positional != 0 || n_keyword != 0) {
pythontech 0:5868e8752d44 2521 emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_3, n_positional + 2 * n_keyword); // pointer to args
pythontech 0:5868e8752d44 2522 }
pythontech 0:5868e8752d44 2523 emit_pre_pop_reg(emit, &vtype_fun, REG_ARG_1); // the function
pythontech 0:5868e8752d44 2524 emit_call_with_imm_arg(emit, MP_F_NATIVE_CALL_FUNCTION_N_KW, n_positional | (n_keyword << 8), REG_ARG_2);
pythontech 0:5868e8752d44 2525 emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
pythontech 0:5868e8752d44 2526 }
pythontech 0:5868e8752d44 2527 }
pythontech 0:5868e8752d44 2528 }
pythontech 0:5868e8752d44 2529
pythontech 0:5868e8752d44 2530 STATIC void emit_native_call_method(emit_t *emit, mp_uint_t n_positional, mp_uint_t n_keyword, mp_uint_t star_flags) {
pythontech 0:5868e8752d44 2531 if (star_flags) {
pythontech 0:5868e8752d44 2532 emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_3, n_positional + 2 * n_keyword + 4); // pointer to args
pythontech 0:5868e8752d44 2533 emit_call_with_2_imm_args(emit, MP_F_CALL_METHOD_N_KW_VAR, 1, REG_ARG_1, n_positional | (n_keyword << 8), REG_ARG_2);
pythontech 0:5868e8752d44 2534 emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
pythontech 0:5868e8752d44 2535 } else {
pythontech 0:5868e8752d44 2536 emit_native_pre(emit);
pythontech 0:5868e8752d44 2537 emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_3, 2 + n_positional + 2 * n_keyword); // pointer to items, including meth and self
pythontech 0:5868e8752d44 2538 emit_call_with_2_imm_args(emit, MP_F_CALL_METHOD_N_KW, n_positional, REG_ARG_1, n_keyword, REG_ARG_2);
pythontech 0:5868e8752d44 2539 emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
pythontech 0:5868e8752d44 2540 }
pythontech 0:5868e8752d44 2541 }
pythontech 0:5868e8752d44 2542
pythontech 0:5868e8752d44 2543 STATIC void emit_native_return_value(emit_t *emit) {
pythontech 0:5868e8752d44 2544 DEBUG_printf("return_value\n");
pythontech 0:5868e8752d44 2545 if (emit->do_viper_types) {
pythontech 0:5868e8752d44 2546 if (peek_vtype(emit, 0) == VTYPE_PTR_NONE) {
pythontech 0:5868e8752d44 2547 emit_pre_pop_discard(emit);
pythontech 0:5868e8752d44 2548 if (emit->return_vtype == VTYPE_PYOBJ) {
pythontech 0:5868e8752d44 2549 ASM_MOV_IMM_TO_REG(emit->as, (mp_uint_t)mp_const_none, REG_RET);
pythontech 0:5868e8752d44 2550 } else {
pythontech 0:5868e8752d44 2551 ASM_MOV_IMM_TO_REG(emit->as, 0, REG_RET);
pythontech 0:5868e8752d44 2552 }
pythontech 0:5868e8752d44 2553 } else {
pythontech 0:5868e8752d44 2554 vtype_kind_t vtype;
pythontech 0:5868e8752d44 2555 emit_pre_pop_reg(emit, &vtype, REG_RET);
pythontech 0:5868e8752d44 2556 if (vtype != emit->return_vtype) {
pythontech 0:5868e8752d44 2557 EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
pythontech 0:5868e8752d44 2558 "return expected '%q' but got '%q'",
pythontech 0:5868e8752d44 2559 vtype_to_qstr(emit->return_vtype), vtype_to_qstr(vtype));
pythontech 0:5868e8752d44 2560 }
pythontech 0:5868e8752d44 2561 }
pythontech 0:5868e8752d44 2562 } else {
pythontech 0:5868e8752d44 2563 vtype_kind_t vtype;
pythontech 0:5868e8752d44 2564 emit_pre_pop_reg(emit, &vtype, REG_RET);
pythontech 0:5868e8752d44 2565 assert(vtype == VTYPE_PYOBJ);
pythontech 0:5868e8752d44 2566 }
pythontech 0:5868e8752d44 2567 emit->last_emit_was_return_value = true;
pythontech 0:5868e8752d44 2568 //ASM_BREAK_POINT(emit->as); // to insert a break-point for debugging
pythontech 0:5868e8752d44 2569 ASM_EXIT(emit->as);
pythontech 0:5868e8752d44 2570 }
pythontech 0:5868e8752d44 2571
pythontech 0:5868e8752d44 2572 STATIC void emit_native_raise_varargs(emit_t *emit, mp_uint_t n_args) {
pythontech 0:5868e8752d44 2573 assert(n_args == 1);
pythontech 0:5868e8752d44 2574 vtype_kind_t vtype_exc;
pythontech 0:5868e8752d44 2575 emit_pre_pop_reg(emit, &vtype_exc, REG_ARG_1); // arg1 = object to raise
pythontech 0:5868e8752d44 2576 if (vtype_exc != VTYPE_PYOBJ) {
pythontech 0:5868e8752d44 2577 EMIT_NATIVE_VIPER_TYPE_ERROR(emit, "must raise an object");
pythontech 0:5868e8752d44 2578 }
pythontech 0:5868e8752d44 2579 // TODO probably make this 1 call to the runtime (which could even call convert, native_raise(obj, type))
pythontech 0:5868e8752d44 2580 emit_call(emit, MP_F_NATIVE_RAISE);
pythontech 0:5868e8752d44 2581 }
pythontech 0:5868e8752d44 2582
pythontech 0:5868e8752d44 2583 STATIC void emit_native_yield_value(emit_t *emit) {
pythontech 0:5868e8752d44 2584 // not supported (for now)
pythontech 0:5868e8752d44 2585 (void)emit;
pythontech 0:5868e8752d44 2586 assert(0);
pythontech 0:5868e8752d44 2587 }
pythontech 0:5868e8752d44 2588 STATIC void emit_native_yield_from(emit_t *emit) {
pythontech 0:5868e8752d44 2589 // not supported (for now)
pythontech 0:5868e8752d44 2590 (void)emit;
pythontech 0:5868e8752d44 2591 assert(0);
pythontech 0:5868e8752d44 2592 }
pythontech 0:5868e8752d44 2593
pythontech 0:5868e8752d44 2594 STATIC void emit_native_start_except_handler(emit_t *emit) {
pythontech 0:5868e8752d44 2595 // This instruction follows an nlr_pop, so the stack counter is back to zero, when really
pythontech 0:5868e8752d44 2596 // it should be up by a whole nlr_buf_t. We then want to pop the nlr_buf_t here, but save
pythontech 0:5868e8752d44 2597 // the first 2 elements, so we can get the thrown value.
pythontech 0:5868e8752d44 2598 adjust_stack(emit, 1);
pythontech 0:5868e8752d44 2599 vtype_kind_t vtype_nlr;
pythontech 0:5868e8752d44 2600 emit_pre_pop_reg(emit, &vtype_nlr, REG_ARG_1); // get the thrown value
pythontech 0:5868e8752d44 2601 emit_pre_pop_discard(emit); // discard the linked-list pointer in the nlr_buf
pythontech 0:5868e8752d44 2602 emit_post_push_reg_reg_reg(emit, VTYPE_PYOBJ, REG_ARG_1, VTYPE_PYOBJ, REG_ARG_1, VTYPE_PYOBJ, REG_ARG_1); // push the 3 exception items
pythontech 0:5868e8752d44 2603 }
pythontech 0:5868e8752d44 2604
pythontech 0:5868e8752d44 2605 STATIC void emit_native_end_except_handler(emit_t *emit) {
pythontech 0:5868e8752d44 2606 adjust_stack(emit, -1);
pythontech 0:5868e8752d44 2607 }
pythontech 0:5868e8752d44 2608
pythontech 0:5868e8752d44 2609 const emit_method_table_t EXPORT_FUN(method_table) = {
pythontech 0:5868e8752d44 2610 emit_native_set_native_type,
pythontech 0:5868e8752d44 2611 emit_native_start_pass,
pythontech 0:5868e8752d44 2612 emit_native_end_pass,
pythontech 0:5868e8752d44 2613 emit_native_last_emit_was_return_value,
pythontech 0:5868e8752d44 2614 emit_native_adjust_stack_size,
pythontech 0:5868e8752d44 2615 emit_native_set_source_line,
pythontech 0:5868e8752d44 2616
pythontech 0:5868e8752d44 2617 {
pythontech 0:5868e8752d44 2618 emit_native_load_fast,
pythontech 0:5868e8752d44 2619 emit_native_load_deref,
pythontech 0:5868e8752d44 2620 emit_native_load_name,
pythontech 0:5868e8752d44 2621 emit_native_load_global,
pythontech 0:5868e8752d44 2622 },
pythontech 0:5868e8752d44 2623 {
pythontech 0:5868e8752d44 2624 emit_native_store_fast,
pythontech 0:5868e8752d44 2625 emit_native_store_deref,
pythontech 0:5868e8752d44 2626 emit_native_store_name,
pythontech 0:5868e8752d44 2627 emit_native_store_global,
pythontech 0:5868e8752d44 2628 },
pythontech 0:5868e8752d44 2629 {
pythontech 0:5868e8752d44 2630 emit_native_delete_fast,
pythontech 0:5868e8752d44 2631 emit_native_delete_deref,
pythontech 0:5868e8752d44 2632 emit_native_delete_name,
pythontech 0:5868e8752d44 2633 emit_native_delete_global,
pythontech 0:5868e8752d44 2634 },
pythontech 0:5868e8752d44 2635
pythontech 0:5868e8752d44 2636 emit_native_label_assign,
pythontech 0:5868e8752d44 2637 emit_native_import_name,
pythontech 0:5868e8752d44 2638 emit_native_import_from,
pythontech 0:5868e8752d44 2639 emit_native_import_star,
pythontech 0:5868e8752d44 2640 emit_native_load_const_tok,
pythontech 0:5868e8752d44 2641 emit_native_load_const_small_int,
pythontech 0:5868e8752d44 2642 emit_native_load_const_str,
pythontech 0:5868e8752d44 2643 emit_native_load_const_obj,
pythontech 0:5868e8752d44 2644 emit_native_load_null,
pythontech 0:5868e8752d44 2645 emit_native_load_attr,
pythontech 0:5868e8752d44 2646 emit_native_load_method,
pythontech 0:5868e8752d44 2647 emit_native_load_build_class,
pythontech 0:5868e8752d44 2648 emit_native_load_subscr,
pythontech 0:5868e8752d44 2649 emit_native_store_attr,
pythontech 0:5868e8752d44 2650 emit_native_store_subscr,
pythontech 0:5868e8752d44 2651 emit_native_delete_attr,
pythontech 0:5868e8752d44 2652 emit_native_delete_subscr,
pythontech 0:5868e8752d44 2653 emit_native_dup_top,
pythontech 0:5868e8752d44 2654 emit_native_dup_top_two,
pythontech 0:5868e8752d44 2655 emit_native_pop_top,
pythontech 0:5868e8752d44 2656 emit_native_rot_two,
pythontech 0:5868e8752d44 2657 emit_native_rot_three,
pythontech 0:5868e8752d44 2658 emit_native_jump,
pythontech 0:5868e8752d44 2659 emit_native_pop_jump_if,
pythontech 0:5868e8752d44 2660 emit_native_jump_if_or_pop,
pythontech 0:5868e8752d44 2661 emit_native_break_loop,
pythontech 0:5868e8752d44 2662 emit_native_continue_loop,
pythontech 0:5868e8752d44 2663 emit_native_setup_with,
pythontech 0:5868e8752d44 2664 emit_native_with_cleanup,
pythontech 0:5868e8752d44 2665 emit_native_setup_except,
pythontech 0:5868e8752d44 2666 emit_native_setup_finally,
pythontech 0:5868e8752d44 2667 emit_native_end_finally,
pythontech 0:5868e8752d44 2668 emit_native_get_iter,
pythontech 0:5868e8752d44 2669 emit_native_for_iter,
pythontech 0:5868e8752d44 2670 emit_native_for_iter_end,
pythontech 0:5868e8752d44 2671 emit_native_pop_block,
pythontech 0:5868e8752d44 2672 emit_native_pop_except,
pythontech 0:5868e8752d44 2673 emit_native_unary_op,
pythontech 0:5868e8752d44 2674 emit_native_binary_op,
pythontech 0:5868e8752d44 2675 emit_native_build_tuple,
pythontech 0:5868e8752d44 2676 emit_native_build_list,
pythontech 0:5868e8752d44 2677 emit_native_list_append,
pythontech 0:5868e8752d44 2678 emit_native_build_map,
pythontech 0:5868e8752d44 2679 emit_native_store_map,
pythontech 0:5868e8752d44 2680 emit_native_map_add,
pythontech 0:5868e8752d44 2681 #if MICROPY_PY_BUILTINS_SET
pythontech 0:5868e8752d44 2682 emit_native_build_set,
pythontech 0:5868e8752d44 2683 emit_native_set_add,
pythontech 0:5868e8752d44 2684 #endif
pythontech 0:5868e8752d44 2685 #if MICROPY_PY_BUILTINS_SLICE
pythontech 0:5868e8752d44 2686 emit_native_build_slice,
pythontech 0:5868e8752d44 2687 #endif
pythontech 0:5868e8752d44 2688 emit_native_unpack_sequence,
pythontech 0:5868e8752d44 2689 emit_native_unpack_ex,
pythontech 0:5868e8752d44 2690 emit_native_make_function,
pythontech 0:5868e8752d44 2691 emit_native_make_closure,
pythontech 0:5868e8752d44 2692 emit_native_call_function,
pythontech 0:5868e8752d44 2693 emit_native_call_method,
pythontech 0:5868e8752d44 2694 emit_native_return_value,
pythontech 0:5868e8752d44 2695 emit_native_raise_varargs,
pythontech 0:5868e8752d44 2696 emit_native_yield_value,
pythontech 0:5868e8752d44 2697 emit_native_yield_from,
pythontech 0:5868e8752d44 2698
pythontech 0:5868e8752d44 2699 emit_native_start_except_handler,
pythontech 0:5868e8752d44 2700 emit_native_end_except_handler,
pythontech 0:5868e8752d44 2701 };
pythontech 0:5868e8752d44 2702
pythontech 0:5868e8752d44 2703 #endif