@@ -308,6 +308,39 @@ STATIC const cc_name_t cc_name_table[] = {
308
308
{ ASM_THUMB_CC_LE , "le" },
309
309
};
310
310
311
+ typedef struct _format_4_op_t { byte op ; char name [3 ]; } format_4_op_t ;
312
+ #define X (x ) (((x) >> 4) & 0xff) // only need 1 byte to distinguish these ops
313
+ STATIC const format_4_op_t format_4_op_table [] = {
314
+ { X (ASM_THUMB_FORMAT_4_EOR ), "eor" },
315
+ { X (ASM_THUMB_FORMAT_4_LSL ), "lsl" },
316
+ { X (ASM_THUMB_FORMAT_4_LSR ), "lsr" },
317
+ { X (ASM_THUMB_FORMAT_4_ASR ), "asr" },
318
+ { X (ASM_THUMB_FORMAT_4_ADC ), "adc" },
319
+ { X (ASM_THUMB_FORMAT_4_SBC ), "sbc" },
320
+ { X (ASM_THUMB_FORMAT_4_ROR ), "ror" },
321
+ { X (ASM_THUMB_FORMAT_4_TST ), "tst" },
322
+ { X (ASM_THUMB_FORMAT_4_NEG ), "neg" },
323
+ { X (ASM_THUMB_FORMAT_4_CMP ), "cmp" },
324
+ { X (ASM_THUMB_FORMAT_4_CMN ), "cmn" },
325
+ { X (ASM_THUMB_FORMAT_4_ORR ), "orr" },
326
+ { X (ASM_THUMB_FORMAT_4_MUL ), "mul" },
327
+ { X (ASM_THUMB_FORMAT_4_BIC ), "bic" },
328
+ { X (ASM_THUMB_FORMAT_4_MVN ), "mvn" },
329
+ };
330
+ #undef X
331
+
332
+ typedef struct _format_9_10_op_t { uint16_t op ; char name [5 ]; } format_9_10_op_t ;
333
+ #define X (x ) (x)
334
+ STATIC const format_9_10_op_t format_9_10_op_table [] = {
335
+ { X (ASM_THUMB_FORMAT_9_LDR | ASM_THUMB_FORMAT_9_WORD_TRANSFER ), "ldr" },
336
+ { X (ASM_THUMB_FORMAT_9_LDR | ASM_THUMB_FORMAT_9_BYTE_TRANSFER ), "ldrb" },
337
+ { X (ASM_THUMB_FORMAT_10_LDRH ), "ldrh" },
338
+ { X (ASM_THUMB_FORMAT_9_STR | ASM_THUMB_FORMAT_9_WORD_TRANSFER ), "str" },
339
+ { X (ASM_THUMB_FORMAT_9_STR | ASM_THUMB_FORMAT_9_BYTE_TRANSFER ), "strb" },
340
+ { X (ASM_THUMB_FORMAT_10_STRH ), "strh" },
341
+ };
342
+ #undef X
343
+
311
344
STATIC void emit_inline_thumb_op (emit_inline_asm_t * emit , qstr op , mp_uint_t n_args , mp_parse_node_t * pn_args ) {
312
345
// TODO perhaps make two tables:
313
346
// one_args =
@@ -421,29 +454,6 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a
421
454
mp_uint_t reg_dest = get_arg_reg (emit , op_str , pn_args [0 ], 15 );
422
455
mp_uint_t reg_src = get_arg_reg (emit , op_str , pn_args [1 ], 15 );
423
456
asm_thumb_mov_reg_reg (emit -> as , reg_dest , reg_src );
424
- } else if (strcmp (op_str , "and_" ) == 0 ) {
425
- op_code = ASM_THUMB_FORMAT_4_AND ;
426
- mp_uint_t reg_dest , reg_src ;
427
- op_format_4 :
428
- reg_dest = get_arg_reg (emit , op_str , pn_args [0 ], 7 );
429
- reg_src = get_arg_reg (emit , op_str , pn_args [1 ], 7 );
430
- asm_thumb_format_4 (emit -> as , op_code , reg_dest , reg_src );
431
- // TODO probably uses less ROM if these ops are in a lookup table
432
- } else if (strcmp (op_str , "eor" ) == 0 ) { op_code = ASM_THUMB_FORMAT_4_EOR ; goto op_format_4 ;
433
- } else if (strcmp (op_str , "lsl" ) == 0 ) { op_code = ASM_THUMB_FORMAT_4_LSL ; goto op_format_4 ;
434
- } else if (strcmp (op_str , "lsr" ) == 0 ) { op_code = ASM_THUMB_FORMAT_4_LSR ; goto op_format_4 ;
435
- } else if (strcmp (op_str , "asr" ) == 0 ) { op_code = ASM_THUMB_FORMAT_4_ASR ; goto op_format_4 ;
436
- } else if (strcmp (op_str , "adc" ) == 0 ) { op_code = ASM_THUMB_FORMAT_4_ADC ; goto op_format_4 ;
437
- } else if (strcmp (op_str , "sbc" ) == 0 ) { op_code = ASM_THUMB_FORMAT_4_SBC ; goto op_format_4 ;
438
- } else if (strcmp (op_str , "ror" ) == 0 ) { op_code = ASM_THUMB_FORMAT_4_ROR ; goto op_format_4 ;
439
- } else if (strcmp (op_str , "tst" ) == 0 ) { op_code = ASM_THUMB_FORMAT_4_TST ; goto op_format_4 ;
440
- } else if (strcmp (op_str , "neg" ) == 0 ) { op_code = ASM_THUMB_FORMAT_4_NEG ; goto op_format_4 ;
441
- } else if (strcmp (op_str , "cmp" ) == 0 ) { op_code = ASM_THUMB_FORMAT_4_CMP ; goto op_format_4 ;
442
- } else if (strcmp (op_str , "cmn" ) == 0 ) { op_code = ASM_THUMB_FORMAT_4_CMN ; goto op_format_4 ;
443
- } else if (strcmp (op_str , "orr" ) == 0 ) { op_code = ASM_THUMB_FORMAT_4_ORR ; goto op_format_4 ;
444
- } else if (strcmp (op_str , "mul" ) == 0 ) { op_code = ASM_THUMB_FORMAT_4_MUL ; goto op_format_4 ;
445
- } else if (strcmp (op_str , "bic" ) == 0 ) { op_code = ASM_THUMB_FORMAT_4_BIC ; goto op_format_4 ;
446
- } else if (strcmp (op_str , "mvn" ) == 0 ) { op_code = ASM_THUMB_FORMAT_4_MVN ; goto op_format_4 ;
447
457
} else if (strcmp (op_str , "clz" ) == 0 ) {
448
458
op_code_hi = 0xfab0 ;
449
459
op_code = 0xf080 ;
@@ -457,6 +467,21 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a
457
467
op_code = 0xf0a0 ;
458
468
goto op_clz_rbit ;
459
469
} else {
470
+ if (strcmp (op_str , "and_" ) == 0 ) {
471
+ op_code = ASM_THUMB_FORMAT_4_AND ;
472
+ mp_uint_t reg_dest , reg_src ;
473
+ op_format_4 :
474
+ reg_dest = get_arg_reg (emit , op_str , pn_args [0 ], 7 );
475
+ reg_src = get_arg_reg (emit , op_str , pn_args [1 ], 7 );
476
+ asm_thumb_format_4 (emit -> as , op_code , reg_dest , reg_src );
477
+ }
478
+ // search table
479
+ for (mp_uint_t i = 0 ; i < MP_ARRAY_SIZE (format_4_op_table ); i ++ ) {
480
+ if (strncmp (op_str , format_4_op_table [i ].name , 3 ) == 0 && op_str [3 ] == '\0' ) {
481
+ op_code = 0x4000 | (format_4_op_table [i ].op << 4 );
482
+ goto op_format_4 ;
483
+ }
484
+ }
460
485
goto unknown_op ;
461
486
}
462
487
} else {
@@ -493,38 +518,6 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a
493
518
int i_src = get_arg_i (emit , op_str , pn_args [1 ], 0xffffffff );
494
519
asm_thumb_movw_reg_i16 (emit -> as , reg_dest , i_src & 0xffff );
495
520
asm_thumb_movt_reg_i16 (emit -> as , reg_dest , (i_src >> 16 ) & 0x7fff );
496
- } else if (strcmp (op_str , "ldr" ) == 0 ) {
497
- op_code = ASM_THUMB_FORMAT_9_LDR | ASM_THUMB_FORMAT_9_WORD_TRANSFER ;
498
- mp_uint_t rlo_dest , rlo_base , i5 ;
499
- mp_parse_node_t pn_base , pn_offset ;
500
- op_format_9_10 :
501
- rlo_dest = get_arg_reg (emit , op_str , pn_args [0 ], 7 );
502
- if (get_arg_addr (emit , op_str , pn_args [1 ], & pn_base , & pn_offset )) {
503
- rlo_base = get_arg_reg (emit , op_str , pn_base , 7 );
504
- if (op_code & ASM_THUMB_FORMAT_9_BYTE_TRANSFER ) {
505
- i5 = get_arg_i (emit , op_str , pn_offset , 0x1f );
506
- } else if (op_code & ASM_THUMB_FORMAT_10_STRH ) { // also catches LDRH
507
- i5 = get_arg_i (emit , op_str , pn_offset , 0x3e ) >> 1 ;
508
- } else {
509
- i5 = get_arg_i (emit , op_str , pn_offset , 0x7c ) >> 2 ;
510
- }
511
- asm_thumb_format_9_10 (emit -> as , op_code , rlo_dest , rlo_base , i5 );
512
- }
513
- } else if (strcmp (op_str , "ldrb" ) == 0 ) {
514
- op_code = ASM_THUMB_FORMAT_9_LDR | ASM_THUMB_FORMAT_9_BYTE_TRANSFER ;
515
- goto op_format_9_10 ;
516
- } else if (strcmp (op_str , "ldrh" ) == 0 ) {
517
- op_code = ASM_THUMB_FORMAT_10_LDRH ;
518
- goto op_format_9_10 ;
519
- } else if (strcmp (op_str , "str" ) == 0 ) {
520
- op_code = ASM_THUMB_FORMAT_9_STR | ASM_THUMB_FORMAT_9_WORD_TRANSFER ;
521
- goto op_format_9_10 ;
522
- } else if (strcmp (op_str , "strb" ) == 0 ) {
523
- op_code = ASM_THUMB_FORMAT_9_STR | ASM_THUMB_FORMAT_9_BYTE_TRANSFER ;
524
- goto op_format_9_10 ;
525
- } else if (strcmp (op_str , "strh" ) == 0 ) {
526
- op_code = ASM_THUMB_FORMAT_10_STRH ;
527
- goto op_format_9_10 ;
528
521
} else if (strcmp (op_str , "ldrex" ) == 0 ) {
529
522
mp_uint_t r_dest = get_arg_reg (emit , op_str , pn_args [0 ], 15 );
530
523
mp_parse_node_t pn_base , pn_offset ;
@@ -534,6 +527,28 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a
534
527
asm_thumb_op32 (emit -> as , 0xe850 | r_base , 0x0f00 | (r_dest << 12 ) | i8 );
535
528
}
536
529
} else {
530
+ // search table for ldr/str instructions
531
+ for (mp_uint_t i = 0 ; i < MP_ARRAY_SIZE (format_9_10_op_table ); i ++ ) {
532
+ if (strcmp (op_str , format_9_10_op_table [i ].name ) == 0 ) {
533
+ op_code = format_9_10_op_table [i ].op ;
534
+ mp_parse_node_t pn_base , pn_offset ;
535
+ mp_uint_t rlo_dest = get_arg_reg (emit , op_str , pn_args [0 ], 7 );
536
+ if (get_arg_addr (emit , op_str , pn_args [1 ], & pn_base , & pn_offset )) {
537
+ mp_uint_t rlo_base = get_arg_reg (emit , op_str , pn_base , 7 );
538
+ mp_uint_t i5 ;
539
+ if (op_code & ASM_THUMB_FORMAT_9_BYTE_TRANSFER ) {
540
+ i5 = get_arg_i (emit , op_str , pn_offset , 0x1f );
541
+ } else if (op_code & ASM_THUMB_FORMAT_10_STRH ) { // also catches LDRH
542
+ i5 = get_arg_i (emit , op_str , pn_offset , 0x3e ) >> 1 ;
543
+ } else {
544
+ i5 = get_arg_i (emit , op_str , pn_offset , 0x7c ) >> 2 ;
545
+ }
546
+ asm_thumb_format_9_10 (emit -> as , op_code , rlo_dest , rlo_base , i5 );
547
+ return ;
548
+ }
549
+ break ;
550
+ }
551
+ }
537
552
goto unknown_op ;
538
553
}
539
554
}
0 commit comments