Skip to content

Commit 8a79a6c

Browse files
committed
[lld][Xtensa] Fix loop instruction relocation
1 parent 7059b6d commit 8a79a6c

File tree

1 file changed

+29
-3
lines changed

1 file changed

+29
-3
lines changed

lld/ELF/Arch/Xtensa.cpp

+29-3
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,31 @@ static inline bool isRRI8Branch(uint8_t *loc) {
105105
// instructions: bgeui, bltui
106106
if ((loc[0] & 0b1011'1111) == 0b1011'0110)
107107
return true;
108-
// instruction: bt
109-
if ((loc[0] & 0b0111'1111) == 0b0111'0110)
110-
return true;
108+
if ((loc[0] & 0b0111'1111) == 0b0111'0110) {
109+
// instruction: bf
110+
if ((loc[1] & 0b1111'0000) == 0b0000'0000)
111+
return true;
112+
// instruction: bt
113+
if ((loc[1] & 0b1111'0000) == 0b0001'0000)
114+
return true;
115+
}
116+
// some other instruction
117+
return false;
118+
}
119+
120+
static inline bool isLoop(uint8_t *loc) {
121+
// instructions: loop, loopgtz, loopnez
122+
if ((loc[0] & 0b1111'1111) == 0b0111'0110) {
123+
// instruction: loop
124+
if ((loc[1] & 0b1111'0000) == 0b1000'0000)
125+
return true;
126+
// instruction: loopgtz
127+
if ((loc[1] & 0b1111'0000) == 0b1010'0000)
128+
return true;
129+
// instruction: loopnez
130+
if ((loc[1] & 0b1111'0000) == 0b1001'0000)
131+
return true;
132+
}
111133
// some other instruction
112134
return false;
113135
}
@@ -151,6 +173,10 @@ void Xtensa::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
151173
uint64_t v = val - 4;
152174
checkInt(loc, static_cast<int64_t>(v), 8, rel);
153175
loc[2] = v & 0xff;
176+
} else if (isLoop(loc)) { // loop instructions
177+
uint64_t v = val - 4;
178+
checkUInt(loc, v, 8, rel);
179+
loc[2] = v & 0xff;
154180
} else if ((loc[0] & 0b1000'1111) == 0b1000'1100) { // RI16 format: beqz.n, bnez.n
155181
uint64_t v = val - 4;
156182
checkUInt(loc, v, 6, rel);

0 commit comments

Comments
 (0)