diff options
Diffstat (limited to 'py')
| -rw-r--r-- | py/emitinlinethumb.c | 95 | ||||
| -rw-r--r-- | py/qstrdefs.h | 44 | 
2 files changed, 92 insertions, 47 deletions
| diff --git a/py/emitinlinethumb.c b/py/emitinlinethumb.c index c31a931c2..90a68caa6 100644 --- a/py/emitinlinethumb.c +++ b/py/emitinlinethumb.c @@ -392,15 +392,16 @@ STATIC const format_4_op_t format_4_op_table[] = {  };  #undef X -typedef struct _format_9_10_op_t { uint16_t op; char name[5]; } format_9_10_op_t; +// name is actually a qstr, which should fit in 16 bits +typedef struct _format_9_10_op_t { uint16_t op; uint16_t name; } format_9_10_op_t;  #define X(x) (x)  STATIC const format_9_10_op_t format_9_10_op_table[] = { -    { X(ASM_THUMB_FORMAT_9_LDR | ASM_THUMB_FORMAT_9_WORD_TRANSFER), "ldr" }, -    { X(ASM_THUMB_FORMAT_9_LDR | ASM_THUMB_FORMAT_9_BYTE_TRANSFER), "ldrb" }, -    { X(ASM_THUMB_FORMAT_10_LDRH), "ldrh" }, -    { X(ASM_THUMB_FORMAT_9_STR | ASM_THUMB_FORMAT_9_WORD_TRANSFER), "str" }, -    { X(ASM_THUMB_FORMAT_9_STR | ASM_THUMB_FORMAT_9_BYTE_TRANSFER), "strb" }, -    { X(ASM_THUMB_FORMAT_10_STRH), "strh" }, +    { X(ASM_THUMB_FORMAT_9_LDR | ASM_THUMB_FORMAT_9_WORD_TRANSFER), MP_QSTR_ldr }, +    { X(ASM_THUMB_FORMAT_9_LDR | ASM_THUMB_FORMAT_9_BYTE_TRANSFER), MP_QSTR_ldrb }, +    { X(ASM_THUMB_FORMAT_10_LDRH), MP_QSTR_ldrh }, +    { X(ASM_THUMB_FORMAT_9_STR | ASM_THUMB_FORMAT_9_WORD_TRANSFER), MP_QSTR_str }, +    { X(ASM_THUMB_FORMAT_9_STR | ASM_THUMB_FORMAT_9_BYTE_TRANSFER), MP_QSTR_strb }, +    { X(ASM_THUMB_FORMAT_10_STRH), MP_QSTR_strh },  };  #undef X @@ -437,7 +438,7 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a          // floating point operations          if (n_args == 2) {              mp_uint_t op_code = 0x0ac0, op_code_hi; -            if (strcmp(op_str, "vcmp") == 0) { +            if (op == MP_QSTR_vcmp) {                  op_code_hi = 0xeeb4;                  op_vfp_twoargs:;                  mp_uint_t vd = get_arg_vfpreg(emit, op_str, pn_args[0]); @@ -445,20 +446,20 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a                  asm_thumb_op32(emit->as,                      op_code_hi | ((vd & 1) << 6),                      op_code | ((vd & 0x1e) << 11) | ((vm & 1) << 5) | (vm & 0x1e) >> 1); -            } else if (strcmp(op_str, "vsqrt") == 0) { +            } else if (op == MP_QSTR_vsqrt) {                  op_code_hi = 0xeeb1;                  goto op_vfp_twoargs; -            } else if (strcmp(op_str, "vneg") == 0) { +            } else if (op == MP_QSTR_vneg) {                  op_code_hi = 0xeeb1;                  op_code = 0x0a40;                  goto op_vfp_twoargs; -            } else if (strcmp(op_str, "vcvt_f32_s32") == 0) { +            } else if (op == MP_QSTR_vcvt_f32_s32) {                  op_code_hi = 0xeeb8; // int to float                  goto op_vfp_twoargs; -            } else if (strcmp(op_str, "vcvt_s32_f32") == 0) { +            } else if (op == MP_QSTR_vcvt_s32_f32) {                  op_code_hi = 0xeebd; // float to int                  goto op_vfp_twoargs; -            } else if (strcmp(op_str, "vmrs") == 0) { +            } else if (op == MP_QSTR_vmrs) {                  mp_uint_t reg_dest;                  const char *reg_str0 = get_arg_str(pn_args[0]);                  if (strcmp(reg_str0, "APSR_nzcv") == 0) { @@ -473,7 +474,7 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a                  } else {                      goto unknown_op;                  } -            } else if (strcmp(op_str, "vmov") == 0) { +            } else if (op == MP_QSTR_vmov) {                  op_code_hi = 0xee00;                  mp_uint_t r_arm, vm;                  const char *reg_str = get_arg_str(pn_args[0]); @@ -488,7 +489,7 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a                  asm_thumb_op32(emit->as,                      op_code_hi | ((vm & 0x1e) >> 1),                      0x0a10 | (r_arm << 12) | ((vm & 1) << 7)); -            } else if (strcmp(op_str, "vldr") == 0) { +            } else if (op == MP_QSTR_vldr) {                  op_code_hi = 0xed90;                  op_vldr_vstr:;                  mp_uint_t vd = get_arg_vfpreg(emit, op_str, pn_args[0]); @@ -501,7 +502,7 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a                          op_code_hi | rlo_base | ((vd & 1) << 6),                          0x0a00 | ((vd & 0x1e) << 11) | i8);                  } -            } else if (strcmp(op_str, "vstr") == 0) { +            } else if (op == MP_QSTR_vstr) {                  op_code_hi = 0xed80;                  goto op_vldr_vstr;              } else { @@ -529,26 +530,26 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a      } else      #endif      if (n_args == 0) { -        if (strcmp(op_str, "nop") == 0) { +        if (op == MP_QSTR_nop) {              asm_thumb_op16(emit->as, ASM_THUMB_OP_NOP); -        } else if (strcmp(op_str, "wfi") == 0) { +        } else if (op == MP_QSTR_wfi) {              asm_thumb_op16(emit->as, ASM_THUMB_OP_WFI);          } else {              goto unknown_op;          }      } else if (n_args == 1) { -        if (strcmp(op_str, "b") == 0) { +        if (op == MP_QSTR_b) {              int label_num = get_arg_label(emit, op_str, pn_args[0]);              if (!asm_thumb_b_n_label(emit->as, label_num)) {                  goto branch_not_in_range;              } -        } else if (strcmp(op_str, "bl") == 0) { +        } else if (op == MP_QSTR_bl) {              int label_num = get_arg_label(emit, op_str, pn_args[0]);              if (!asm_thumb_bl_label(emit->as, label_num)) {                  goto branch_not_in_range;              } -        } else if (strcmp(op_str, "bx") == 0) { +        } else if (op == MP_QSTR_bx) {              mp_uint_t r = get_arg_reg(emit, op_str, pn_args[0], 15);              asm_thumb_op16(emit->as, 0x4700 | (r << 3));          } else if (op_str[0] == 'b' && (op_len == 3 @@ -600,13 +601,13 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a                  }              }              asm_thumb_it_cc(emit->as, cc, it_mask); -        } else if (strcmp(op_str, "cpsid") == 0) { +        } else if (op == MP_QSTR_cpsid) {              // TODO check pn_args[0] == i              asm_thumb_op16(emit->as, ASM_THUMB_OP_CPSID_I); -        } else if (strcmp(op_str, "cpsie") == 0) { +        } else if (op == MP_QSTR_cpsie) {              // TODO check pn_args[0] == i              asm_thumb_op16(emit->as, ASM_THUMB_OP_CPSIE_I); -        } else if (strcmp(op_str, "push") == 0) { +        } else if (op == MP_QSTR_push) {              mp_uint_t reglist = get_arg_reglist(emit, op_str, pn_args[0]);              if ((reglist & 0xff00) == 0) {                  asm_thumb_op16(emit->as, 0xb400 | reglist); @@ -616,7 +617,7 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a                  }                  asm_thumb_op32(emit->as, 0xe92d, reglist);              } -        } else if (strcmp(op_str, "pop") == 0) { +        } else if (op == MP_QSTR_pop) {              mp_uint_t reglist = get_arg_reglist(emit, op_str, pn_args[0]);              if ((reglist & 0xff00) == 0) {                  asm_thumb_op16(emit->as, 0xbc00 | reglist); @@ -634,11 +635,11 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a          if (MP_PARSE_NODE_IS_ID(pn_args[1])) {              // second arg is a register (or should be)              mp_uint_t op_code, op_code_hi; -            if (strcmp(op_str, "mov") == 0) { +            if (op == MP_QSTR_mov) {                  mp_uint_t reg_dest = get_arg_reg(emit, op_str, pn_args[0], 15);                  mp_uint_t reg_src = get_arg_reg(emit, op_str, pn_args[1], 15);                  asm_thumb_mov_reg_reg(emit->as, reg_dest, reg_src); -            } else if (ARMV7M && strcmp(op_str, "clz") == 0) { +            } else if (ARMV7M && op == MP_QSTR_clz) {                  op_code_hi = 0xfab0;                  op_code = 0xf080;                  mp_uint_t rd, rm; @@ -646,16 +647,16 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a                  rd = get_arg_reg(emit, op_str, pn_args[0], 15);                  rm = get_arg_reg(emit, op_str, pn_args[1], 15);                  asm_thumb_op32(emit->as, op_code_hi | rm, op_code | (rd << 8) | rm); -            } else if (ARMV7M && strcmp(op_str, "rbit") == 0) { +            } else if (ARMV7M && op == MP_QSTR_rbit) {                  op_code_hi = 0xfa90;                  op_code = 0xf0a0;                  goto op_clz_rbit; -            } else if (ARMV7M && strcmp(op_str, "mrs") == 0){ +            } else if (ARMV7M && op == MP_QSTR_mrs){                  mp_uint_t reg_dest = get_arg_reg(emit, op_str, pn_args[0], 12);                  mp_uint_t reg_src = get_arg_special_reg(emit, op_str, pn_args[1]);                  asm_thumb_op32(emit->as, 0xf3ef, 0x8000 | (reg_dest << 8) | reg_src);              } else { -                if (strcmp(op_str, "and_") == 0) { +                if (op == MP_QSTR_and_) {                      op_code = ASM_THUMB_FORMAT_4_AND;                      mp_uint_t reg_dest, reg_src;                      op_format_4: @@ -676,39 +677,39 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a          } else {              // second arg is not a register              mp_uint_t op_code; -            if (strcmp(op_str, "mov") == 0) { +            if (op == MP_QSTR_mov) {                  op_code = ASM_THUMB_FORMAT_3_MOV;                  mp_uint_t rlo_dest, i8_src;                  op_format_3:                  rlo_dest = get_arg_reg(emit, op_str, pn_args[0], 7);                  i8_src = get_arg_i(emit, op_str, pn_args[1], 0xff);                  asm_thumb_format_3(emit->as, op_code, rlo_dest, i8_src); -            } else if (strcmp(op_str, "cmp") == 0) { +            } else if (op == MP_QSTR_cmp) {                  op_code = ASM_THUMB_FORMAT_3_CMP;                  goto op_format_3; -            } else if (strcmp(op_str, "add") == 0) { +            } else if (op == MP_QSTR_add) {                  op_code = ASM_THUMB_FORMAT_3_ADD;                  goto op_format_3; -            } else if (strcmp(op_str, "sub") == 0) { +            } else if (op == MP_QSTR_sub) {                  op_code = ASM_THUMB_FORMAT_3_SUB;                  goto op_format_3; -            } else if (ARMV7M && strcmp(op_str, "movw") == 0) { +            } else if (ARMV7M && op == MP_QSTR_movw) {                  op_code = ASM_THUMB_OP_MOVW;                  mp_uint_t reg_dest;                  op_movw_movt:                  reg_dest = get_arg_reg(emit, op_str, pn_args[0], 15);                  int i_src = get_arg_i(emit, op_str, pn_args[1], 0xffff);                  asm_thumb_mov_reg_i16(emit->as, op_code, reg_dest, i_src); -            } else if (ARMV7M && strcmp(op_str, "movt") == 0) { +            } else if (ARMV7M && op == MP_QSTR_movt) {                  op_code = ASM_THUMB_OP_MOVT;                  goto op_movw_movt; -            } else if (ARMV7M && strcmp(op_str, "movwt") == 0) { +            } else if (ARMV7M && op == MP_QSTR_movwt) {                  // this is a convenience instruction                  mp_uint_t reg_dest = get_arg_reg(emit, op_str, pn_args[0], 15);                  uint32_t i_src = get_arg_i(emit, op_str, pn_args[1], 0xffffffff);                  asm_thumb_mov_reg_i16(emit->as, ASM_THUMB_OP_MOVW, reg_dest, i_src & 0xffff);                  asm_thumb_mov_reg_i16(emit->as, ASM_THUMB_OP_MOVT, reg_dest, (i_src >> 16) & 0xffff); -            } else if (ARMV7M && strcmp(op_str, "ldrex") == 0) { +            } else if (ARMV7M && op == MP_QSTR_ldrex) {                  mp_uint_t r_dest = get_arg_reg(emit, op_str, pn_args[0], 15);                  mp_parse_node_t pn_base, pn_offset;                  if (get_arg_addr(emit, op_str, pn_args[1], &pn_base, &pn_offset)) { @@ -719,7 +720,7 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a              } else {                  // search table for ldr/str instructions                  for (mp_uint_t i = 0; i < MP_ARRAY_SIZE(format_9_10_op_table); i++) { -                    if (strcmp(op_str, format_9_10_op_table[i].name) == 0) { +                    if (op == format_9_10_op_table[i].name) {                          op_code = format_9_10_op_table[i].op;                          mp_parse_node_t pn_base, pn_offset;                          mp_uint_t rlo_dest = get_arg_reg(emit, op_str, pn_args[0], 7); @@ -745,7 +746,7 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a      } else if (n_args == 3) {          mp_uint_t op_code; -        if (strcmp(op_str, "lsl") == 0) { +        if (op == MP_QSTR_lsl) {              op_code = ASM_THUMB_FORMAT_1_LSL;              mp_uint_t rlo_dest, rlo_src, i5;              op_format_1: @@ -753,13 +754,13 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a              rlo_src = get_arg_reg(emit, op_str, pn_args[1], 7);              i5 = get_arg_i(emit, op_str, pn_args[2], 0x1f);              asm_thumb_format_1(emit->as, op_code, rlo_dest, rlo_src, i5); -        } else if (strcmp(op_str, "lsr") == 0) { +        } else if (op == MP_QSTR_lsr) {              op_code = ASM_THUMB_FORMAT_1_LSR;              goto op_format_1; -        } else if (strcmp(op_str, "asr") == 0) { +        } else if (op == MP_QSTR_asr) {              op_code = ASM_THUMB_FORMAT_1_ASR;              goto op_format_1; -        } else if (strcmp(op_str, "add") == 0) { +        } else if (op == MP_QSTR_add) {              op_code = ASM_THUMB_FORMAT_2_ADD;              mp_uint_t rlo_dest, rlo_src;              op_format_2: @@ -774,7 +775,7 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a                  src_b = get_arg_i(emit, op_str, pn_args[2], 0x7);              }              asm_thumb_format_2(emit->as, op_code, rlo_dest, rlo_src, src_b); -        } else if (ARMV7M && strcmp(op_str, "sdiv") == 0) { +        } else if (ARMV7M && op == MP_QSTR_sdiv) {              op_code = 0xfb90; // sdiv high part              mp_uint_t rd, rn, rm;              op_sdiv_udiv: @@ -782,13 +783,13 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a              rn = get_arg_reg(emit, op_str, pn_args[1], 15);              rm = get_arg_reg(emit, op_str, pn_args[2], 15);              asm_thumb_op32(emit->as, op_code | rn, 0xf0f0 | (rd << 8) | rm); -        } else if (ARMV7M && strcmp(op_str, "udiv") == 0) { +        } else if (ARMV7M && op == MP_QSTR_udiv) {              op_code = 0xfbb0; // udiv high part              goto op_sdiv_udiv; -        } else if (strcmp(op_str, "sub") == 0) { +        } else if (op == MP_QSTR_sub) {              op_code = ASM_THUMB_FORMAT_2_SUB;              goto op_format_2; -        } else if (ARMV7M && strcmp(op_str, "strex") == 0) { +        } else if (ARMV7M && op == MP_QSTR_strex) {              mp_uint_t r_dest = get_arg_reg(emit, op_str, pn_args[0], 15);              mp_uint_t r_src = get_arg_reg(emit, op_str, pn_args[1], 15);              mp_parse_node_t pn_base, pn_offset; diff --git a/py/qstrdefs.h b/py/qstrdefs.h index ad57dd390..ac0703a52 100644 --- a/py/qstrdefs.h +++ b/py/qstrdefs.h @@ -114,6 +114,50 @@ Q(label)  Q(align)  Q(data)  Q(uint) +Q(nop) +Q(mov) +Q(and_) +Q(cmp) +Q(add) +Q(sub) +Q(lsl) +Q(lsr) +Q(asr) +Q(ldr) +Q(ldrb) +Q(ldrh) +Q(str) +Q(strb) +Q(strh) +Q(b) +Q(bl) +Q(bx) +Q(push) +Q(pop) +Q(cpsid) +Q(cpsie) +Q(wfi) +Q(clz) +Q(rbit) +Q(movw) +Q(movt) +Q(movwt) +Q(mrs) +Q(sdiv) +Q(udiv) +Q(ldrex) +Q(strex) +#if MICROPY_EMIT_INLINE_THUMB_FLOAT +Q(vcmp) +Q(vneg) +Q(vcvt_f32_s32) +Q(vcvt_s32_f32) +Q(vsqrt) +Q(vmov) +Q(vmrs) +Q(vldr) +Q(vstr) +#endif  #endif  Q(builtins) | 
