diff options
author | Max Filippov <jcmvbkbc@gmail.com> | 2017-11-09 14:51:18 -0800 |
---|---|---|
committer | Max Filippov <jcmvbkbc@gmail.com> | 2017-11-27 15:11:38 -0800 |
commit | fec68fb168d580c188358347f3834072a8960ddc (patch) | |
tree | 475757da49fe08c0e11f3df2f7a4cba4fe74a87c | |
parent | 120bc8b8b91cba4a8d4092ea0fb3d76bcbe98712 (diff) | |
download | gdb-fec68fb168d580c188358347f3834072a8960ddc.zip gdb-fec68fb168d580c188358347f3834072a8960ddc.tar.gz gdb-fec68fb168d580c188358347f3834072a8960ddc.tar.bz2 |
gas: xtensa: extract jump assembling for trampolines
init_trampoline_frag, add_jump_to_trampoline and xg_relax_trampoline add
a jump to the end of a trampoline frag. Extract it into a separate
funciton and use it in all these places. No functional changes.
gas/
2017-11-27 Max Filippov <jcmvbkbc@gmail.com>
* config/tc-xtensa.c (xg_append_jump): New function.
(xg_relax_trampoline, init_trampoline_frag)
(add_jump_to_trampoline): Replace trampoline jump assembling
code with a call to xg_append_jump.
-rw-r--r-- | gas/ChangeLog | 7 | ||||
-rw-r--r-- | gas/config/tc-xtensa.c | 159 |
2 files changed, 64 insertions, 102 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 683ebbf..d156052 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,5 +1,12 @@ 2017-11-27 Max Filippov <jcmvbkbc@gmail.com> + * config/tc-xtensa.c (xg_append_jump): New function. + (xg_relax_trampoline, init_trampoline_frag) + (add_jump_to_trampoline): Replace trampoline jump assembling + code with a call to xg_append_jump. + +2017-11-27 Max Filippov <jcmvbkbc@gmail.com> + * config/tc-xtensa.c (xg_relax_trampoline): New function. (xtensa_relax_frag): Replace trampoline relaxation code with a call to xg_relax_trampoline. diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c index 087caad..eccf3c3 100644 --- a/gas/config/tc-xtensa.c +++ b/gas/config/tc-xtensa.c @@ -485,6 +485,8 @@ static void xtensa_create_trampoline_frag (bfd_boolean); static void xtensa_maybe_create_trampoline_frag (void); struct trampoline_frag; static int init_trampoline_frag (struct trampoline_frag *); +static fixS *xg_append_jump (fragS *fragP, fixS *jump_around, + symbolS *sym, offsetT offset); static void xtensa_maybe_create_literal_pool_frag (bfd_boolean, bfd_boolean); static bfd_boolean auto_litpools = FALSE; static int auto_litpool_limit = 10000; @@ -9166,13 +9168,10 @@ static bfd_boolean xtensa_add_cached_fixup (fixup_cacheS *cache, fixS *fixP) static void xg_relax_trampoline (fragS *fragP, long stretch, long *new_stretch) { - xtensa_isa isa = xtensa_default_isa; static fixup_cacheS fixup_cache; segment_info_type *seginfo = seg_info (now_seg); int trampaddr = fragP->fr_address + fragP->fr_fix; int searchaddr = trampaddr < J_RANGE ? 0 : trampaddr - J_RANGE; - int slot; - xtensa_format fmt; unsigned i; if (now_seg != fixup_cache.seg || @@ -9203,8 +9202,6 @@ static void xg_relax_trampoline (fragS *fragP, long stretch, long *new_stretch) if (abs (delta) < J_RANGE) continue; - slot = fixP->tc_fix_data.slot; - if (delta > J_RANGE || delta < -1 * J_RANGE) { /* Found an out-of-range jump; scan the list of trampolines for the best match. */ struct trampoline_seg *ts = find_trampoline_seg (now_seg); @@ -9264,55 +9261,26 @@ static void xg_relax_trampoline (fragS *fragP, long stretch, long *new_stretch) if (abs (addr - trampaddr) < J_RANGE) { /* The trampoline is in range of original; fix it! */ fixS *newfixP; - int offset; - TInsn insn; - symbolS *lsym; - fragS *fP; /* The out-of-range jump. */ - - new_stretch += init_trampoline_frag (tf); - offset = fragP->fr_fix; /* Where to assemble the j insn. */ - lsym = fragP->fr_symbol; - fP = fixP->fx_frag; - /* Assemble a jump to the target label here. */ - tinsn_init (&insn); - insn.insn_type = ITYPE_INSN; - insn.opcode = xtensa_j_opcode; - insn.ntok = 1; - set_expr_symbol_offset (&insn.tok[0], lsym, offset); - fmt = xg_get_single_format (xtensa_j_opcode); - tinsn_to_slotbuf (fmt, 0, &insn, trampoline_slotbuf); - xtensa_format_set_slot (isa, fmt, 0, trampoline_buf, trampoline_slotbuf); - xtensa_insnbuf_to_chars (isa, trampoline_buf, (unsigned char *)fragP->fr_literal + offset, 3); - fragP->fr_fix += 3; - fragP->fr_var -= 3; - /* Add a fix-up for the original j insn. */ - newfixP = fix_new (fP, fixP->fx_where, fixP->fx_size, lsym, fragP->fr_fix - 3, TRUE, fixP->fx_r_type); - newfixP->fx_no_overflow = 1; - newfixP->tc_fix_data.X_add_symbol = lsym; - newfixP->tc_fix_data.X_add_number = offset; - newfixP->tc_fix_data.slot = slot; - xtensa_delete_cached_fixup (&fixup_cache, i); - xtensa_add_cached_fixup (&fixup_cache, newfixP); + new_stretch += init_trampoline_frag (tf) + 3; + /* Assemble a jump to the target label in the trampoline frag. */ + newfixP = xg_append_jump (fragP, tf->fixP, + fixP->fx_addsy, fixP->fx_offset); - /* Move the fix-up from the original j insn to this one. */ - fixP->fx_frag = fragP; - fixP->fx_where = fragP->fr_fix - 3; - fixP->fx_size = 3; - fixP->tc_fix_data.slot = 0; - fixP->fx_r_type = BFD_RELOC_XTENSA_SLOT0_OP; + /* Adjust the fixup for the original "j" instruction to + point to the newly added jump. */ + fixP->fx_addsy = fragP->fr_symbol; + fixP->fx_offset = fragP->fr_fix - 3; + fixP->tc_fix_data.X_add_symbol = fragP->fr_symbol; + fixP->tc_fix_data.X_add_number = fragP->fr_fix - 3; - xtensa_add_cached_fixup (&fixup_cache, fixP); + fixP = newfixP; + xtensa_delete_cached_fixup (&fixup_cache, i); + xtensa_add_cached_fixup (&fixup_cache, newfixP); /* re-do current fixup */ --i; - /* Adjust the jump around this trampoline (if present). */ - if (tf->fixP != NULL) - { - tf->fixP->fx_offset += 3; - } - new_stretch += 3; fragP->tc_frag_data.relax_seen = FALSE; /* Need another pass. */ /* Do we have room for more? */ if (fragP->fr_var < 3) @@ -10017,6 +9985,39 @@ check_and_update_trampolines (void) } } +static fixS *xg_append_jump (fragS *fragP, fixS *jump_around, + symbolS *sym, offsetT offset) +{ + fixS *fixP; + TInsn insn; + xtensa_format fmt; + xtensa_isa isa = xtensa_default_isa; + + gas_assert (fragP->fr_var >= 3); + tinsn_init (&insn); + insn.insn_type = ITYPE_INSN; + insn.opcode = xtensa_j_opcode; + insn.ntok = 1; + set_expr_symbol_offset (&insn.tok[0], sym, offset); + fmt = xg_get_single_format (xtensa_j_opcode); + tinsn_to_slotbuf (fmt, 0, &insn, trampoline_slotbuf); + xtensa_format_set_slot (isa, fmt, 0, trampoline_buf, trampoline_slotbuf); + xtensa_insnbuf_to_chars (isa, trampoline_buf, + (unsigned char *)fragP->fr_literal + fragP->fr_fix, 3); + fixP = fix_new (fragP, fragP->fr_fix, 3, sym, offset, TRUE, + BFD_RELOC_XTENSA_SLOT0_OP); + fixP->tc_fix_data.slot = 0; + + fragP->fr_fix += 3; + fragP->fr_var -= 3; + + /* Adjust the jump around this trampoline (if present). */ + if (jump_around) + jump_around->fx_offset += 3; + + return fixP; +} + static int init_trampoline_frag (struct trampoline_frag *trampP) @@ -10028,35 +10029,14 @@ init_trampoline_frag (struct trampoline_frag *trampP) { symbolS *lsym; char label[10 + 2 * sizeof(fp)]; - sprintf (label, ".L0_TR_%p", fp); + sprintf (label, ".L0_TR_%p", fp); lsym = (symbolS *)local_symbol_make (label, now_seg, 0, fp); fp->fr_symbol = lsym; if (trampP->needs_jump_around) { - /* Add a jump around this block of jumps, in case - control flows into this block. */ - fixS *fixP; - TInsn insn; - xtensa_format fmt; - xtensa_isa isa = xtensa_default_isa; - - fp->tc_frag_data.is_insn = 1; - /* Assemble a jump insn. */ - tinsn_init (&insn); - insn.insn_type = ITYPE_INSN; - insn.opcode = xtensa_j_opcode; - insn.ntok = 1; - set_expr_symbol_offset (&insn.tok[0], lsym, 3); - fmt = xg_get_single_format (xtensa_j_opcode); - tinsn_to_slotbuf (fmt, 0, &insn, trampoline_slotbuf); - xtensa_format_set_slot (isa, fmt, 0, trampoline_buf, trampoline_slotbuf); - xtensa_insnbuf_to_chars (isa, trampoline_buf, (unsigned char *)fp->fr_literal, 3); - fp->fr_fix += 3; - fp->fr_var -= 3; + trampP->fixP = xg_append_jump (fp, NULL, lsym, 3); growth = 3; - fixP = fix_new (fp, 0, 3, lsym, 3, TRUE, BFD_RELOC_XTENSA_SLOT0_OP); - trampP->fixP = fixP; } } return growth; @@ -10067,15 +10047,6 @@ static int add_jump_to_trampoline (struct trampoline_frag *trampP, fragS *origfrag) { fragS *tramp = trampP->fragP; - fixS *fixP; - int offset = tramp->fr_fix; /* Where to assemble the j insn. */ - TInsn insn; - symbolS *lsym; - symbolS *tsym; - int toffset; - xtensa_format fmt; - xtensa_isa isa = xtensa_default_isa; - int growth = 0; int i, slot = -1; for (i = 0; i < MAX_SLOTS; ++i) @@ -10087,35 +10058,19 @@ add_jump_to_trampoline (struct trampoline_frag *trampP, fragS *origfrag) gas_assert (slot >= 0 && slot < MAX_SLOTS); - lsym = tramp->fr_symbol; /* Assemble a jump to the target label in the trampoline frag. */ - tsym = origfrag->tc_frag_data.slot_symbols[slot]; - toffset = origfrag-> tc_frag_data.slot_offsets[slot]; - tinsn_init (&insn); - insn.insn_type = ITYPE_INSN; - insn.opcode = xtensa_j_opcode; - insn.ntok = 1; - set_expr_symbol_offset (&insn.tok[0], tsym, toffset); - fmt = xg_get_single_format (xtensa_j_opcode); - tinsn_to_slotbuf (fmt, 0, &insn, trampoline_slotbuf); - xtensa_format_set_slot (isa, fmt, 0, trampoline_buf, trampoline_slotbuf); - xtensa_insnbuf_to_chars (isa, trampoline_buf, (unsigned char *)tramp->fr_literal + offset, 3); - tramp->fr_fix += 3; - tramp->fr_var -= 3; - growth = 3; - /* add a fix-up for the trampoline jump. */ - fixP = fix_new (tramp, tramp->fr_fix - 3, 3, tsym, toffset, TRUE, BFD_RELOC_XTENSA_SLOT0_OP); - /* Modify the jump at the start of this trampoline to point past the newly-added jump. */ - fixP = trampP->fixP; - if (fixP) - fixP->fx_offset += 3; + xg_append_jump (tramp, trampP->fixP, + origfrag->tc_frag_data.slot_symbols[slot], + origfrag->tc_frag_data.slot_offsets[slot]); + /* Modify the original j to point here. */ - origfrag->tc_frag_data.slot_symbols[slot] = lsym; + origfrag->tc_frag_data.slot_symbols[slot] = tramp->fr_symbol; origfrag->tc_frag_data.slot_offsets[slot] = tramp->fr_fix - 3; + /* If trampoline is full, remove it from the list. */ check_and_update_trampolines (); - return growth; + return 3; } |