@@ -22,19 +22,6 @@ using namespace lld;
2222using namespace lld ::elf;
2323
2424namespace {
25- #define LARCH_GET_RD (insn ) (insn & 0x1f )
26- #define LARCH_GET_RJ (insn ) (insn >> 5 & 0x1f )
27- #define LARCH_MK_ADDI_W 0xffc00000
28- #define LARCH_OP_ADDI_W 0x02800000
29- #define LARCH_MK_ADDI_D 0xffc00000
30- #define LARCH_OP_ADDI_D 0x02c00000
31- #define LARCH_MK_PCADDI 0xfe000000
32- #define LARCH_OP_PCADDI 0x18000000
33- #define LARCH_INSN_OPS (insn, op ) ((insn & LARCH_MK_##op) == LARCH_OP_##op)
34- #define LARCH_INSN_ADDI_W (insn ) LARCH_INSN_OPS((insn), ADDI_W)
35- #define LARCH_INSN_ADDI_D (insn ) LARCH_INSN_OPS((insn), ADDI_D)
36- #define LARCH_INSN_PCADDI (insn ) LARCH_INSN_OPS((insn), PCADDI)
37-
3825class LoongArch final : public TargetInfo {
3926public:
4027 LoongArch (Ctx &);
@@ -67,6 +54,7 @@ enum Op {
6754 ADDI_D = 0x02c00000 ,
6855 ANDI = 0x03400000 ,
6956 PCADDU12I = 0x1c000000 ,
57+ PCADDI = 0x18000000 ,
7058 LD_W = 0x28800000 ,
7159 LD_D = 0x28c00000 ,
7260 JIRL = 0x4c000000 ,
@@ -76,7 +64,6 @@ enum Reg {
7664 R_ZERO = 0 ,
7765 R_RA = 1 ,
7866 R_TP = 2 ,
79- R_A0 = 4 ,
8067 R_T0 = 12 ,
8168 R_T1 = 13 ,
8269 R_T2 = 14 ,
@@ -173,6 +160,17 @@ static bool isJirl(uint32_t insn) {
173160 return (insn & 0xfc000000 ) == JIRL;
174161}
175162
163+ static bool isAddi_w (uint32_t insn) { return (insn & 0xffc00000 ) == ADDI_W; }
164+
165+ static bool isAddi_d (uint32_t insn) { return (insn & 0xffc00000 ) == ADDI_D; }
166+
167+ // LoongArch instructions could be divided into a number of kinds based on
168+ // the width of imm and the number of registers. get_rd/get_rj only applies
169+ // to those kinds of instructions that could do relocation.
170+ static uint8_t get_rd (uint32_t insn) { return insn & 0x1f ; }
171+
172+ static uint8_t get_rj (uint32_t insn) { return insn >> 5 & 0x1f ; }
173+
176174static void handleUleb128 (Ctx &ctx, uint8_t *loc, uint64_t val) {
177175 const uint32_t maxcount = 1 + 64 / 7 ;
178176 uint32_t count;
@@ -805,17 +803,16 @@ static void relaxPcalaAddi(const InputSection &sec, size_t i, uint64_t loc,
805803 const int64_t dist = symval - loc;
806804 uint32_t pca = read32le (sec.content ().data () + r_hi.offset );
807805 uint32_t add = read32le (sec.content ().data () + r_hi.offset + 4 );
808- uint32_t rd = LARCH_GET_RD (pca);
806+ uint8_t rd = get_rd (pca);
809807
810- if ((!LARCH_INSN_ADDI_W (add) && !LARCH_INSN_ADDI_D (add)) ||
811- LARCH_GET_RJ (add) != rd || symval & 0x3 /* 4 bytes align */ ||
812- !isInt<22 >(dist))
808+ if ((!isAddi_w (add) && !isAddi_d (add)) || get_rj (add) != rd ||
809+ symval & 0x3 /* not 4 bytes align */ || !isInt<22 >(dist))
813810 return ;
814811
815812 // remove the first insn
816813 sec.relaxAux ->relocTypes [i] = R_LARCH_RELAX;
817814 sec.relaxAux ->relocTypes [i + 2 ] = R_LARCH_PCREL20_S2;
818- sec.relaxAux ->writes .push_back (LARCH_OP_PCADDI | rd); // pcaddi
815+ sec.relaxAux ->writes .push_back (PCADDI | rd); // pcaddi rd, 0
819816 remove = 4 ;
820817}
821818
0 commit comments