aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorLulu Cai <cailulu@loongson.cn>2024-01-24 17:43:20 +0800
committerliuzhensong <liuzhensong@loongson.cn>2024-03-06 14:47:03 +0800
commit0e45942b2cad90e32c13b4c8c2c1aea9ba08c497 (patch)
tree55c94c483ba0e8ac2a3621fbd0f8c65455d236fc /gas
parent55e01dbd7623941373ee500032119a124fd2d673 (diff)
downloadgdb-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.c31
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);