diff --git a/py/asmthumb.c b/py/asmthumb.c
index 3fcd28a91d34d0178b1c3227a4aed3a8a1d45da4..f37b1ff8fe3700dd4eca418450a6ade76609d7a9 100644
--- a/py/asmthumb.c
+++ b/py/asmthumb.c
@@ -275,6 +275,12 @@ void asm_thumb_mov_reg_reg(asm_thumb_t *as, uint reg_dest, uint reg_src) {
     asm_thumb_write_op16(as, 0x4600 | op_lo);
 }
 
+#define OP_ADD_REG_REG_REG(rlo_dest, rlo_src_a, rlo_src_b) (0x1800 | ((rlo_src_b) << 6) | ((rlo_src_a) << 3) | (rlo_dest))
+
+void asm_thumb_add_reg_reg_reg(asm_thumb_t *as, uint rlo_dest, uint rlo_src_a, uint rlo_src_b) {
+    asm_thumb_write_op16(as, OP_ADD_REG_REG_REG(rlo_dest, rlo_src_a, rlo_src_b));
+}
+
 #define OP_SUBS_RLO_RLO_I3(rlo_dest, rlo_src, i3_src) (0x1e00 | ((i3_src) << 6) | ((rlo_src) << 3) | (rlo_dest))
 
 void asm_thumb_subs_rlo_rlo_i3(asm_thumb_t *as, uint rlo_dest, uint rlo_src, int i3_src) {
@@ -283,6 +289,12 @@ void asm_thumb_subs_rlo_rlo_i3(asm_thumb_t *as, uint rlo_dest, uint rlo_src, int
     asm_thumb_write_op16(as, OP_SUBS_RLO_RLO_I3(rlo_dest, rlo_src, i3_src));
 }
 
+#define OP_CMP_REG_REG(rlo_a, rlo_b) (0x4280 | ((rlo_b) << 3) | (rlo_a))
+
+void asm_thumb_cmp_reg_reg(asm_thumb_t *as, uint rlo_a, uint rlo_b) {
+    asm_thumb_write_op16(as, OP_CMP_REG_REG(rlo_a, rlo_b));
+}
+
 #define OP_CMP_RLO_I8(rlo, i8) (0x2800 | ((rlo) << 8) | (i8))
 
 void asm_thumb_cmp_rlo_i8(asm_thumb_t *as, uint rlo, int i8) {
@@ -290,6 +302,10 @@ void asm_thumb_cmp_rlo_i8(asm_thumb_t *as, uint rlo, int i8) {
     asm_thumb_write_op16(as, OP_CMP_RLO_I8(rlo, i8));
 }
 
+void asm_thumb_ite_ge(asm_thumb_t *as) {
+    asm_thumb_write_op16(as, 0xbfac);
+}
+
 #define OP_B_N(byte_offset) (0xe000 | (((byte_offset) >> 1) & 0x07ff))
 
 void asm_thumb_b_n(asm_thumb_t *as, int label) {
@@ -360,22 +376,6 @@ void asm_thumb_mov_reg_local_addr(asm_thumb_t *as, uint rlo_dest, int local_num)
     asm_thumb_write_op16(as, OP_ADD_REG_SP_OFFSET(rlo_dest, word_offset));
 }
 
-#define OP_ADD_REG_REG_REG(rlo_dest, rlo_src_a, rlo_src_b) (0x1800 | ((rlo_src_b) << 6) | ((rlo_src_a) << 3) | (rlo_dest))
-
-void asm_thumb_add_reg_reg_reg(asm_thumb_t *as, uint rlo_dest, uint rlo_src_a, uint rlo_src_b) {
-    asm_thumb_write_op16(as, OP_ADD_REG_REG_REG(rlo_dest, rlo_src_a, rlo_src_b));
-}
-
-#define OP_CMP_REG_REG(rlo_a, rlo_b) (0x4280 | ((rlo_b) << 3) | (rlo_a))
-
-void asm_thumb_cmp_reg_reg(asm_thumb_t *as, uint rlo_a, uint rlo_b) {
-    asm_thumb_write_op16(as, OP_CMP_REG_REG(rlo_a, rlo_b));
-}
-
-void asm_thumb_ite_ge(asm_thumb_t *as) {
-    asm_thumb_write_op16(as, 0xbfac);
-}
-
 // this could be wrong, because it should have a range of +/- 16MiB...
 #define OP_BW_HI(byte_offset) (0xf000 | (((byte_offset) >> 12) & 0x07ff))
 #define OP_BW_LO(byte_offset) (0xb800 | (((byte_offset) >> 1) & 0x07ff))
diff --git a/py/asmthumb.h b/py/asmthumb.h
index dcd9c2e3ad1c35422c696ff699d4a6334e4e0131..60a86ea50b70ab8f1d6793921a3ba1819a58da9a 100644
--- a/py/asmthumb.h
+++ b/py/asmthumb.h
@@ -62,8 +62,11 @@ void asm_thumb_movs_rlo_i8(asm_thumb_t *as, uint rlo_dest, int i8_src);
 void asm_thumb_movw_reg_i16(asm_thumb_t *as, uint reg_dest, int i16_src);
 void asm_thumb_movt_reg_i16(asm_thumb_t *as, uint reg_dest, int i16_src);
 void asm_thumb_mov_reg_reg(asm_thumb_t *as, uint reg_dest, uint reg_src);
+void asm_thumb_add_reg_reg_reg(asm_thumb_t *as, uint rlo_dest, uint rlo_src_a, uint rlo_src_b);
 void asm_thumb_subs_rlo_rlo_i3(asm_thumb_t *as, uint rlo_dest, uint rlo_src, int i3_src);
+void asm_thumb_cmp_reg_reg(asm_thumb_t *as, uint rlo_a, uint rlo_b);
 void asm_thumb_cmp_rlo_i8(asm_thumb_t *as, uint rlo, int i8);
+void asm_thumb_ite_ge(asm_thumb_t *as);
 void asm_thumb_b_n(asm_thumb_t *as, int label);
 void asm_thumb_bcc_n(asm_thumb_t *as, int cond, int label);
 
@@ -73,10 +76,6 @@ void asm_thumb_mov_local_reg(asm_thumb_t *as, int local_num_dest, uint rlo_src);
 void asm_thumb_mov_reg_local(asm_thumb_t *as, uint rlo_dest, int local_num); // convenience
 void asm_thumb_mov_reg_local_addr(asm_thumb_t *as, uint rlo_dest, int local_num); // convenience
 
-void asm_thumb_add_reg_reg_reg(asm_thumb_t *as, uint rlo_dest, uint rlo_src_a, uint rlo_src_b); // convenience ?
-void asm_thumb_cmp_reg_reg(asm_thumb_t *as, uint rlo_a, uint rlo_b); // convenience ?
-void asm_thumb_ite_ge(asm_thumb_t *as); // convenience ?
-
 void asm_thumb_b_label(asm_thumb_t *as, int label); // convenience ?
 void asm_thumb_bcc_label(asm_thumb_t *as, int cc, int label); // convenience: picks narrow or wide branch
 void asm_thumb_bl_ind(asm_thumb_t *as, void *fun_ptr, uint fun_id, uint reg_temp); // convenience ?
diff --git a/py/emitinlinethumb.c b/py/emitinlinethumb.c
index 9ea2cc24bc1b46038086b763877be666b00553cd..c5136ab371900dba91828aa737ffa2dfcf1305fe 100644
--- a/py/emitinlinethumb.c
+++ b/py/emitinlinethumb.c
@@ -81,45 +81,36 @@ STATIC void emit_inline_thumb_label(emit_inline_asm_t *emit, int label_num, qstr
     asm_thumb_label_assign(emit->as, label_num);
 }
 
-STATIC bool check_n_arg(qstr op, int n_args, int wanted_n_args) {
-    if (wanted_n_args == n_args) {
-        return true;
-    } else {
-        printf("SyntaxError: '%s' expects %d arguments'\n", qstr_str(op), wanted_n_args);
-        return false;
-    }
-}
-
-STATIC uint get_arg_rlo(qstr op, mp_parse_node_t *pn_args, int wanted_arg_num) {
+STATIC uint get_arg_rlo(const char *op, mp_parse_node_t *pn_args, int wanted_arg_num) {
     if (!MP_PARSE_NODE_IS_ID(pn_args[wanted_arg_num])) {
-        printf("SyntaxError: '%s' expects a register in position %d\n", qstr_str(op), wanted_arg_num);
+        printf("SyntaxError: '%s' expects a register in position %d\n", op, wanted_arg_num);
         return 0;
     }
     qstr reg_qstr = MP_PARSE_NODE_LEAF_ARG(pn_args[wanted_arg_num]);
     const char *reg_str = qstr_str(reg_qstr);
     if (!(strlen(reg_str) == 2 && reg_str[0] == 'r' && ('0' <= reg_str[1] && reg_str[1] <= '7'))) {
-        printf("SyntaxError: '%s' expects a register in position %d\n", qstr_str(op), wanted_arg_num);
+        printf("SyntaxError: '%s' expects a register in position %d\n", op, wanted_arg_num);
         return 0;
     }
     return reg_str[1] - '0';
 }
 
-STATIC int get_arg_i(qstr op, mp_parse_node_t *pn_args, int wanted_arg_num, int fit_mask) {
+STATIC int get_arg_i(const char *op, mp_parse_node_t *pn_args, int wanted_arg_num, int fit_mask) {
     if (!MP_PARSE_NODE_IS_SMALL_INT(pn_args[wanted_arg_num])) {
-        printf("SyntaxError: '%s' expects an integer in position %d\n", qstr_str(op), wanted_arg_num);
+        printf("SyntaxError: '%s' expects an integer in position %d\n", op, wanted_arg_num);
         return 0;
     }
     int i = MP_PARSE_NODE_LEAF_SMALL_INT(pn_args[wanted_arg_num]);
     if ((i & (~fit_mask)) != 0) {
-        printf("SyntaxError: '%s' integer 0x%x does not fit in mask 0x%x\n", qstr_str(op), i, fit_mask);
+        printf("SyntaxError: '%s' integer 0x%x does not fit in mask 0x%x\n", op, i, fit_mask);
         return 0;
     }
     return i;
 }
 
-STATIC int get_arg_label(emit_inline_asm_t *emit, qstr op, mp_parse_node_t *pn_args, int wanted_arg_num) {
+STATIC int get_arg_label(emit_inline_asm_t *emit, const char *op, mp_parse_node_t *pn_args, int wanted_arg_num) {
     if (!MP_PARSE_NODE_IS_ID(pn_args[wanted_arg_num])) {
-        printf("SyntaxError: '%s' expects a label in position %d\n", qstr_str(op), wanted_arg_num);
+        printf("SyntaxError: '%s' expects a label in position %d\n", op, wanted_arg_num);
         return 0;
     }
     qstr label_qstr = MP_PARSE_NODE_LEAF_ARG(pn_args[wanted_arg_num]);
@@ -135,6 +126,24 @@ STATIC int get_arg_label(emit_inline_asm_t *emit, qstr op, mp_parse_node_t *pn_a
     return 0;
 }
 
+typedef struct _cc_name_t { byte cc; byte name[2]; } cc_name_t;
+STATIC const cc_name_t cc_name_table[] = {
+    {THUMB_CC_EQ, "eq"},
+    {THUMB_CC_NE, "ne"},
+    {THUMB_CC_CS, "cs"},
+    {THUMB_CC_CC, "cc"},
+    {THUMB_CC_MI, "mi"},
+    {THUMB_CC_PL, "pl"},
+    {THUMB_CC_VS, "vs"},
+    {THUMB_CC_VC, "vc"},
+    {THUMB_CC_HI, "hi"},
+    {THUMB_CC_LS, "ls"},
+    {THUMB_CC_GE, "ge"},
+    {THUMB_CC_LT, "lt"},
+    {THUMB_CC_GT, "gt"},
+    {THUMB_CC_LE, "le"},
+};
+
 STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, int n_args, mp_parse_node_t *pn_args) {
     // TODO perhaps make two tables:
     // one_args =
@@ -146,60 +155,86 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, int n_args, m
     // three_args =
     // "subs", RLO, RLO, I3, asm_thumb_subs_reg_reg_i3
 
-    // 1 arg
-    if (strcmp(qstr_str(op), "b") == 0) {
-        if (!check_n_arg(op, n_args, 1)) {
-            return;
-        }
-        int label_num = get_arg_label(emit, op, pn_args, 0);
-        // TODO check that this succeeded, ie branch was within range
-        asm_thumb_b_n(emit->as, label_num);
-    } else if (strcmp(qstr_str(op), "bgt") == 0) {
-        if (!check_n_arg(op, n_args, 1)) {
-            return;
-        }
-        int label_num = get_arg_label(emit, op, pn_args, 0);
-        // TODO check that this succeeded, ie branch was within range
-        asm_thumb_bcc_n(emit->as, THUMB_CC_GT, label_num);
-
-    // 2 args
-    } else if (strcmp(qstr_str(op), "movs") == 0) {
-        if (!check_n_arg(op, n_args, 2)) {
-            return;
+    const char *op_str = qstr_str(op);
+    uint op_len = strlen(op_str);
+
+    if (n_args == 0) {
+        if (strcmp(op_str, "ite.ge") == 0) { // TODO correct name for this op?
+            asm_thumb_ite_ge(emit->as);
+        } else {
+            goto unknown_op;
         }
-        uint rlo_dest = get_arg_rlo(op, pn_args, 0);
-        int i_src = get_arg_i(op, pn_args, 1, 0xff);
-        asm_thumb_movs_rlo_i8(emit->as, rlo_dest, i_src);
-    } else if (strcmp(qstr_str(op), "movw") == 0) {
-        if (!check_n_arg(op, n_args, 2)) {
-            return;
+
+    } else if (n_args == 1) {
+        if (strcmp(op_str, "b") == 0) {
+            int label_num = get_arg_label(emit, op_str, pn_args, 0);
+            // TODO check that this succeeded, ie branch was within range
+            asm_thumb_b_n(emit->as, label_num);
+        } else if (op_str[0] == 'b' && op_len == 3) {
+            uint cc = -1;
+            for (uint i = 0; i < (sizeof cc_name_table) / (sizeof cc_name_table[0]); i++) {
+                if (op_str[1] == cc_name_table[i].name[0] && op_str[2] == cc_name_table[i].name[1]) {
+                    cc = cc_name_table[i].cc;
+                }
+            }
+            if (cc == -1) {
+                goto unknown_op;
+            }
+            int label_num = get_arg_label(emit, op_str, pn_args, 0);
+            // TODO check that this succeeded, ie branch was within range
+            asm_thumb_bcc_n(emit->as, cc, label_num);
+        } else {
+            goto unknown_op;
         }
-        uint rlo_dest = get_arg_rlo(op, pn_args, 0); // TODO can be reg lo or hi
-        int i_src = get_arg_i(op, pn_args, 1, 0xffff);
-        asm_thumb_movw_reg_i16(emit->as, rlo_dest, i_src);
-    } else if (strcmp(qstr_str(op), "cmp") == 0) {
-        if (!check_n_arg(op, n_args, 2)) {
-            return;
+
+    } else if (n_args == 2) {
+        if (strcmp(op_str, "mov") == 0) {
+            uint rlo_dest = get_arg_rlo(op_str, pn_args, 0);
+            uint rlo_src = get_arg_rlo(op_str, pn_args, 1);
+            asm_thumb_mov_reg_reg(emit->as, rlo_dest, rlo_src);
+        } else if (strcmp(op_str, "movs") == 0) {
+            uint rlo_dest = get_arg_rlo(op_str, pn_args, 0);
+            int i_src = get_arg_i(op_str, pn_args, 1, 0xff);
+            asm_thumb_movs_rlo_i8(emit->as, rlo_dest, i_src);
+        } else if (strcmp(op_str, "movw") == 0) {
+            uint rlo_dest = get_arg_rlo(op_str, pn_args, 0); // TODO can be reg lo or hi
+            int i_src = get_arg_i(op_str, pn_args, 1, 0xffff);
+            asm_thumb_movw_reg_i16(emit->as, rlo_dest, i_src);
+        } else if (strcmp(op_str, "movt") == 0) {
+            uint rlo_dest = get_arg_rlo(op_str, pn_args, 0); // TODO can be reg lo or hi
+            int i_src = get_arg_i(op_str, pn_args, 1, 0xffff);
+            asm_thumb_movt_reg_i16(emit->as, rlo_dest, i_src);
+        } else if (strcmp(op_str, "cmp") == 0) {
+            uint rlo = get_arg_rlo(op_str, pn_args, 0);
+            int i8 = get_arg_i(op_str, pn_args, 1, 0xff);
+            asm_thumb_cmp_rlo_i8(emit->as, rlo, i8);
+        } else {
+            goto unknown_op;
         }
-        uint rlo = get_arg_rlo(op, pn_args, 0);
-        int i8 = get_arg_i(op, pn_args, 1, 0xff);
-        asm_thumb_cmp_rlo_i8(emit->as, rlo, i8);
-
-    // 3 args
-    } else if (strcmp(qstr_str(op), "subs") == 0) {
-        if (!check_n_arg(op, n_args, 3)) {
-            return;
+
+    } else if (n_args == 3) {
+        if (strcmp(op_str, "add") == 0) {
+            uint rlo_dest = get_arg_rlo(op_str, pn_args, 0);
+            uint rlo_src_a = get_arg_rlo(op_str, pn_args, 1);
+            uint rlo_src_b = get_arg_rlo(op_str, pn_args, 2);
+            asm_thumb_add_reg_reg_reg(emit->as, rlo_dest, rlo_src_a, rlo_src_b);
+        } else if (strcmp(op_str, "subs") == 0) {
+            uint rlo_dest = get_arg_rlo(op_str, pn_args, 0);
+            uint rlo_src = get_arg_rlo(op_str, pn_args, 1);
+            int i3_src = get_arg_i(op_str, pn_args, 2, 0x7);
+            asm_thumb_subs_rlo_rlo_i3(emit->as, rlo_dest, rlo_src, i3_src);
+        } else {
+            goto unknown_op;
         }
-        uint rlo_dest = get_arg_rlo(op, pn_args, 0);
-        uint rlo_src = get_arg_rlo(op, pn_args, 1);
-        int i3_src = get_arg_i(op, pn_args, 2, 0x7);
-        asm_thumb_subs_rlo_rlo_i3(emit->as, rlo_dest, rlo_src, i3_src);
 
-    // unknown op
     } else {
-        printf("SyntaxError: unsupported ARM Thumb instruction '%s'\n", qstr_str(op));
-        return;
+        goto unknown_op;
     }
+
+    return;
+
+unknown_op:
+    printf("SyntaxError: unsupported ARM Thumb instruction '%s' with %d arguments\n", op_str, n_args);
 }
 
 const emit_inline_asm_method_table_t emit_inline_thumb_method_table = {