@@ -28,15 +28,16 @@ struct _asm_thumb_t {
2828 uint stack_adjust ;
2929};
3030
31- asm_thumb_t * asm_thumb_new () {
31+ asm_thumb_t * asm_thumb_new (uint max_num_labels ) {
3232 asm_thumb_t * as ;
3333
3434 as = m_new (asm_thumb_t , 1 );
3535 as -> pass = 0 ;
3636 as -> code_offset = 0 ;
3737 as -> code_size = 0 ;
3838 as -> code_base = NULL ;
39- as -> label_offsets = NULL ;
39+ as -> max_num_labels = max_num_labels ;
40+ as -> label_offsets = m_new (int , max_num_labels );
4041 as -> num_locals = 0 ;
4142
4243 return as ;
@@ -65,23 +66,13 @@ void asm_thumb_start_pass(asm_thumb_t *as, int pass) {
6566 as -> pass = pass ;
6667 as -> code_offset = 0 ;
6768 as -> next_label = 1 ;
68- if (pass == ASM_THUMB_PASS_1 ) {
69- as -> max_num_labels = 0 ;
70- } else {
71- if (pass == ASM_THUMB_PASS_2 ) {
72- memset (as -> label_offsets , -1 , as -> max_num_labels * sizeof (int ));
73- }
69+ if (pass == ASM_THUMB_PASS_2 ) {
70+ memset (as -> label_offsets , -1 , as -> max_num_labels * sizeof (int ));
7471 }
7572}
7673
7774void asm_thumb_end_pass (asm_thumb_t * as ) {
78- if (as -> pass == ASM_THUMB_PASS_1 ) {
79- // calculate number of labels need
80- if (as -> next_label > as -> max_num_labels ) {
81- as -> max_num_labels = as -> next_label ;
82- }
83- as -> label_offsets = m_new (int , as -> max_num_labels );
84- } else if (as -> pass == ASM_THUMB_PASS_2 ) {
75+ if (as -> pass == ASM_THUMB_PASS_2 ) {
8576 // calculate size of code in bytes
8677 as -> code_size = as -> code_offset ;
8778 as -> code_base = m_new (byte , as -> code_size );
@@ -226,20 +217,23 @@ int asm_thumb_label_new(asm_thumb_t *as) {
226217}
227218
228219void asm_thumb_label_assign (asm_thumb_t * as , int label ) {
229- if (as -> pass > ASM_THUMB_PASS_1 ) {
230- assert (label < as -> max_num_labels );
231- if (as -> pass == ASM_THUMB_PASS_2 ) {
232- // assign label offset
233- assert (as -> label_offsets [label ] == -1 );
234- as -> label_offsets [label ] = as -> code_offset ;
235- } else if (as -> pass == ASM_THUMB_PASS_3 ) {
236- // ensure label offset has not changed from PASS_2 to PASS_3
237- //printf("l%d: (at %d=%ld)\n", label, as->label_offsets[label], as->code_offset);
238- assert (as -> label_offsets [label ] == as -> code_offset );
239- }
220+ assert (label < as -> max_num_labels );
221+ if (as -> pass == ASM_THUMB_PASS_2 ) {
222+ // assign label offset
223+ assert (as -> label_offsets [label ] == -1 );
224+ as -> label_offsets [label ] = as -> code_offset ;
225+ } else if (as -> pass == ASM_THUMB_PASS_3 ) {
226+ // ensure label offset has not changed from PASS_2 to PASS_3
227+ //printf("l%d: (at %d=%ld)\n", label, as->label_offsets[label], as->code_offset);
228+ assert (as -> label_offsets [label ] == as -> code_offset );
240229 }
241230}
242231
232+ static int get_label_dest (asm_thumb_t * as , int label ) {
233+ assert (label < as -> max_num_labels );
234+ return as -> label_offsets [label ];
235+ }
236+
243237// the i8 value will be zero extended into the r32 register!
244238void asm_thumb_mov_reg_i8 (asm_thumb_t * as , uint rlo_dest , int i8 ) {
245239 assert (rlo_dest < REG_R8 );
@@ -339,23 +333,21 @@ void asm_thumb_ite_ge(asm_thumb_t *as) {
339333#define OP_BW_LO (byte_offset ) (0xb800 | (((byte_offset) >> 1) & 0x07ff))
340334
341335void asm_thumb_b_label (asm_thumb_t * as , int label ) {
342- if (as -> pass > ASM_THUMB_PASS_1 ) {
343- int dest = as -> label_offsets [label ];
344- int rel = dest - as -> code_offset ;
345- rel -= 4 ; // account for instruction prefetch, PC is 4 bytes ahead of this instruction
346- if (dest >= 0 && rel <= -4 ) {
347- // is a backwards jump, so we know the size of the jump on the first pass
348- // calculate rel assuming 12 bit relative jump
349- if (SIGNED_FIT12 (rel )) {
350- asm_thumb_write_op16 (as , OP_B (rel ));
351- } else {
352- goto large_jump ;
353- }
336+ int dest = get_label_dest (as , label );
337+ int rel = dest - as -> code_offset ;
338+ rel -= 4 ; // account for instruction prefetch, PC is 4 bytes ahead of this instruction
339+ if (dest >= 0 && rel <= -4 ) {
340+ // is a backwards jump, so we know the size of the jump on the first pass
341+ // calculate rel assuming 12 bit relative jump
342+ if (SIGNED_FIT12 (rel )) {
343+ asm_thumb_write_op16 (as , OP_B (rel ));
354344 } else {
355- // is a forwards jump, so need to assume it's large
356- large_jump :
357- asm_thumb_write_op32 (as , OP_BW_HI (rel ), OP_BW_LO (rel ));
345+ goto large_jump ;
358346 }
347+ } else {
348+ // is a forwards jump, so need to assume it's large
349+ large_jump :
350+ asm_thumb_write_op32 (as , OP_BW_HI (rel ), OP_BW_LO (rel ));
359351 }
360352}
361353
@@ -372,23 +364,21 @@ void asm_thumb_cmp_reg_bz_label(asm_thumb_t *as, uint rlo, int label) {
372364 asm_thumb_write_op16 (as , OP_CMP_REG_IMM (rlo , 0 ));
373365
374366 // branch if equal
375- if (as -> pass > ASM_THUMB_PASS_1 ) {
376- int dest = as -> label_offsets [label ];
377- int rel = dest - as -> code_offset ;
378- rel -= 4 ; // account for instruction prefetch, PC is 4 bytes ahead of this instruction
379- if (dest >= 0 && rel <= -4 ) {
380- // is a backwards jump, so we know the size of the jump on the first pass
381- // calculate rel assuming 12 bit relative jump
382- if (SIGNED_FIT9 (rel )) {
383- asm_thumb_write_op16 (as , OP_BEQ (rel ));
384- } else {
385- goto large_jump ;
386- }
367+ int dest = get_label_dest (as , label );
368+ int rel = dest - as -> code_offset ;
369+ rel -= 4 ; // account for instruction prefetch, PC is 4 bytes ahead of this instruction
370+ if (dest >= 0 && rel <= -4 ) {
371+ // is a backwards jump, so we know the size of the jump on the first pass
372+ // calculate rel assuming 12 bit relative jump
373+ if (SIGNED_FIT9 (rel )) {
374+ asm_thumb_write_op16 (as , OP_BEQ (rel ));
387375 } else {
388- // is a forwards jump, so need to assume it's large
389- large_jump :
390- asm_thumb_write_op32 (as , OP_BEQW_HI (rel ), OP_BEQW_LO (rel ));
376+ goto large_jump ;
391377 }
378+ } else {
379+ // is a forwards jump, so need to assume it's large
380+ large_jump :
381+ asm_thumb_write_op32 (as , OP_BEQW_HI (rel ), OP_BEQW_LO (rel ));
392382 }
393383}
394384
0 commit comments