diff options
author | Lulu Cai <cailulu@loongson.cn> | 2024-01-24 17:43:20 +0800 |
---|---|---|
committer | liuzhensong <liuzhensong@loongson.cn> | 2024-03-06 14:47:03 +0800 |
commit | 0e45942b2cad90e32c13b4c8c2c1aea9ba08c497 (patch) | |
tree | 55c94c483ba0e8ac2a3621fbd0f8c65455d236fc /gas | |
parent | 55e01dbd7623941373ee500032119a124fd2d673 (diff) | |
download | gdb-0e45942b2cad90e32c13b4c8c2c1aea9ba08c497.zip gdb-0e45942b2cad90e32c13b4c8c2c1aea9ba08c497.tar.gz gdb-0e45942b2cad90e32c13b4c8c2c1aea9ba08c497.tar.bz2 |
LoongArch: Delete extra instructions when TLS type transition
This modification mainly changes the timing of type transition,
adds relaxation to the old LE instruction sequence, and fixes
bugs in extreme code models.
We strictly distinguish between type transition and relaxation.
Type transition is from one type to another, while relaxation
is the removal of instructions under the same TLS type. Detailed
instructions are as follows:
1. For type transition, only the normal code model of DESC/IE
does type transition, and each relocation is accompanied by a
RELAX relocation. Neither abs nor extreme will do type transition,
and no RELAX relocation will be generated.
The extra instructions when DESC transitions to other TLS types
will be deleted during the type transition.
2. Implemented relaxation for the old LE instruction sequence.
The first two instructions of LE's 32-bit and 64-bit models
use the same relocations and cannot be distinguished based on
relocations. Therefore, for LE's instruction sequence, any code
model will try to relax.
3. Some function names have been adjusted to facilitate understanding,
parameters have been adjusted, and unused macros have been deleted.
Diffstat (limited to 'gas')
-rw-r--r-- | gas/config/tc-loongarch.c | 31 |
1 files changed, 26 insertions, 5 deletions
diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c index de92366..4ba547d 100644 --- a/gas/config/tc-loongarch.c +++ b/gas/config/tc-loongarch.c @@ -716,7 +716,11 @@ loongarch_args_parser_can_match_arg_helper (char esc_ch1, char esc_ch2, if (LARCH_opts.relax && (BFD_RELOC_LARCH_TLS_LE_HI20_R == reloc_type - || BFD_RELOC_LARCH_TLS_LE_LO12_R == reloc_type)) + || BFD_RELOC_LARCH_TLS_LE_LO12_R == reloc_type + || BFD_RELOC_LARCH_TLS_LE_HI20 == reloc_type + || BFD_RELOC_LARCH_TLS_LE_LO12 == reloc_type + || BFD_RELOC_LARCH_TLS_LE64_LO20 == reloc_type + || BFD_RELOC_LARCH_TLS_LE64_HI12 == reloc_type)) { ip->reloc_info[ip->reloc_num].type = BFD_RELOC_LARCH_RELAX; ip->reloc_info[ip->reloc_num].value = const_0; @@ -724,8 +728,12 @@ loongarch_args_parser_can_match_arg_helper (char esc_ch1, char esc_ch2, } /* Only one register macros (used in normal code model) - emit R_LARCH_RELAX. */ + emit R_LARCH_RELAX. + LARCH_opts.ase_labs and LARCH_opts.ase_gabs are used + to generate the code model of absolute addresses, and + we do not relax this code model. */ if (LARCH_opts.relax && (ip->expand_from_macro & 1) + && !(LARCH_opts.ase_labs | LARCH_opts.ase_gabs) && (BFD_RELOC_LARCH_PCALA_HI20 == reloc_type || BFD_RELOC_LARCH_PCALA_LO12 == reloc_type || BFD_RELOC_LARCH_GOT_PC_HI20 == reloc_type @@ -733,7 +741,11 @@ loongarch_args_parser_can_match_arg_helper (char esc_ch1, char esc_ch2, || BFD_RELOC_LARCH_TLS_LD_PC_HI20 == reloc_type || BFD_RELOC_LARCH_TLS_GD_PC_HI20 == reloc_type || BFD_RELOC_LARCH_TLS_DESC_PC_HI20 == reloc_type - || BFD_RELOC_LARCH_TLS_DESC_PC_LO12 == reloc_type)) + || BFD_RELOC_LARCH_TLS_DESC_PC_LO12 == reloc_type + || BFD_RELOC_LARCH_TLS_DESC_LD == reloc_type + || BFD_RELOC_LARCH_TLS_DESC_CALL == reloc_type + || BFD_RELOC_LARCH_TLS_IE_PC_HI20 == reloc_type + || BFD_RELOC_LARCH_TLS_IE_PC_LO12 == reloc_type)) { ip->reloc_info[ip->reloc_num].type = BFD_RELOC_LARCH_RELAX; ip->reloc_info[ip->reloc_num].value = const_0; @@ -1080,7 +1092,11 @@ append_fixp_and_insn (struct loongarch_cl_insn *ip) if (symbol_get_frag (to) == symbol_get_frag (from))) For macro instructions, only the first instruction expanded from macro - need to start a new frag. */ + need to start a new frag. + Since the relocations of the normal code model and the extreme code model + of the old LE instruction sequence are the same, it is impossible to + distinguish which code model it is based on relocation alone, so the + extreme code model has to be relaxed. */ if (LARCH_opts.relax && (BFD_RELOC_LARCH_PCALA_HI20 == reloc_info[0].type || BFD_RELOC_LARCH_GOT_PC_HI20 == reloc_info[0].type @@ -1088,7 +1104,12 @@ append_fixp_and_insn (struct loongarch_cl_insn *ip) || BFD_RELOC_LARCH_TLS_LE_ADD_R == reloc_info[0].type || BFD_RELOC_LARCH_TLS_LD_PC_HI20 == reloc_info[0].type || BFD_RELOC_LARCH_TLS_GD_PC_HI20 == reloc_info[0].type - || BFD_RELOC_LARCH_TLS_DESC_PC_HI20 == reloc_info[0].type)) + || BFD_RELOC_LARCH_TLS_DESC_PC_HI20 == reloc_info[0].type + || BFD_RELOC_LARCH_TLS_IE_PC_HI20 == reloc_info[0].type + || BFD_RELOC_LARCH_TLS_LE_HI20 == reloc_info[0].type + || BFD_RELOC_LARCH_TLS_LE_LO12 == reloc_info[0].type + || BFD_RELOC_LARCH_TLS_LE64_LO20 == reloc_info[0].type + || BFD_RELOC_LARCH_TLS_LE64_HI12 == reloc_info[0].type)) { frag_wane (frag_now); frag_new (0); |