Skip to content

Commit 35bf8e7

Browse files
authored
[Support] Add decodeULEB128AndInc/decodeSLEB128AndInc
Many decodeULEB128/decodeSLEB128 users need to increment the pointer. Add helpers to simplify this common pattern. We don't add `end` and `error` parameters at present because many users don't need them. Pull Request: #85739
1 parent 888e284 commit 35bf8e7

File tree

3 files changed

+39
-23
lines changed

3 files changed

+39
-23
lines changed

llvm/include/llvm/Support/LEB128.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,20 @@ inline int64_t decodeSLEB128(const uint8_t *p, unsigned *n = nullptr,
200200
return Value;
201201
}
202202

203+
inline uint64_t decodeULEB128AndInc(const uint8_t *&p) {
204+
unsigned n;
205+
auto ret = decodeULEB128(p, &n);
206+
p += n;
207+
return ret;
208+
}
209+
210+
inline int64_t decodeSLEB128AndInc(const uint8_t *&p) {
211+
unsigned n;
212+
auto ret = decodeSLEB128(p, &n);
213+
p += n;
214+
return ret;
215+
}
216+
203217
/// Utility function to get the size of the ULEB128-encoded value.
204218
extern unsigned getULEB128Size(uint64_t Value);
205219

llvm/unittests/Support/LEB128Test.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,21 @@ TEST(LEB128Test, DecodeInvalidSLEB128) {
242242
#undef EXPECT_INVALID_SLEB128
243243
}
244244

245+
TEST(LEB128Test, DecodeAndInc) {
246+
#define EXPECT_LEB128(FUN, VALUE, SIZE) \
247+
do { \
248+
const uint8_t *V = reinterpret_cast<const uint8_t *>(VALUE), *P = V; \
249+
auto Expected = FUN(P), Actual = FUN##AndInc(P); \
250+
EXPECT_EQ(Actual, Expected); \
251+
EXPECT_EQ(P - V, SIZE); \
252+
} while (0)
253+
EXPECT_LEB128(decodeULEB128, "\x7f", 1);
254+
EXPECT_LEB128(decodeULEB128, "\x80\x01", 2);
255+
EXPECT_LEB128(decodeSLEB128, "\x7f", 1);
256+
EXPECT_LEB128(decodeSLEB128, "\x80\x01", 2);
257+
#undef EXPECT_LEB128
258+
}
259+
245260
TEST(LEB128Test, SLEB128Size) {
246261
// Positive Value Testing Plan:
247262
// (1) 128 ^ n - 1 ........ need (n+1) bytes

llvm/utils/TableGen/DecoderEmitter.cpp

Lines changed: 10 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2283,10 +2283,8 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
22832283
}
22842284
case MCD::OPC_CheckField: {
22852285
// Decode the start value.
2286-
unsigned Len;
2287-
unsigned Start = decodeULEB128(++Ptr, &Len);
2288-
Ptr += Len;
2289-
Len = *Ptr;)";
2286+
unsigned Start = decodeULEB128AndInc(++Ptr);
2287+
unsigned Len = *Ptr;)";
22902288
if (IsVarLenInst)
22912289
OS << "\n makeUp(insn, Start + Len);";
22922290
OS << R"(
@@ -2311,10 +2309,8 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
23112309
break;
23122310
}
23132311
case MCD::OPC_CheckPredicate: {
2314-
unsigned Len;
23152312
// Decode the Predicate Index value.
2316-
unsigned PIdx = decodeULEB128(++Ptr, &Len);
2317-
Ptr += Len;
2313+
unsigned PIdx = decodeULEB128AndInc(++Ptr);
23182314
// NumToSkip is a plain 24-bit integer.
23192315
unsigned NumToSkip = *Ptr++;
23202316
NumToSkip |= (*Ptr++) << 8;
@@ -2330,18 +2326,15 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
23302326
break;
23312327
}
23322328
case MCD::OPC_Decode: {
2333-
unsigned Len;
23342329
// Decode the Opcode value.
2335-
unsigned Opc = decodeULEB128(++Ptr, &Len);
2336-
Ptr += Len;
2337-
unsigned DecodeIdx = decodeULEB128(Ptr, &Len);
2338-
Ptr += Len;
2330+
unsigned Opc = decodeULEB128AndInc(++Ptr);
2331+
unsigned DecodeIdx = decodeULEB128AndInc(Ptr);
23392332
23402333
MI.clear();
23412334
MI.setOpcode(Opc);
23422335
bool DecodeComplete;)";
23432336
if (IsVarLenInst) {
2344-
OS << "\n Len = InstrLenTable[Opc];\n"
2337+
OS << "\n unsigned Len = InstrLenTable[Opc];\n"
23452338
<< " makeUp(insn, Len);";
23462339
}
23472340
OS << R"(
@@ -2354,12 +2347,9 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
23542347
return S;
23552348
}
23562349
case MCD::OPC_TryDecode: {
2357-
unsigned Len;
23582350
// Decode the Opcode value.
2359-
unsigned Opc = decodeULEB128(++Ptr, &Len);
2360-
Ptr += Len;
2361-
unsigned DecodeIdx = decodeULEB128(Ptr, &Len);
2362-
Ptr += Len;
2351+
unsigned Opc = decodeULEB128AndInc(++Ptr);
2352+
unsigned DecodeIdx = decodeULEB128AndInc(Ptr);
23632353
// NumToSkip is a plain 24-bit integer.
23642354
unsigned NumToSkip = *Ptr++;
23652355
NumToSkip |= (*Ptr++) << 8;
@@ -2391,11 +2381,8 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
23912381
}
23922382
case MCD::OPC_SoftFail: {
23932383
// Decode the mask values.
2394-
unsigned Len;
2395-
uint64_t PositiveMask = decodeULEB128(++Ptr, &Len);
2396-
Ptr += Len;
2397-
uint64_t NegativeMask = decodeULEB128(Ptr, &Len);
2398-
Ptr += Len;
2384+
uint64_t PositiveMask = decodeULEB128AndInc(++Ptr);
2385+
uint64_t NegativeMask = decodeULEB128AndInc(Ptr);
23992386
bool Fail = (insn & PositiveMask) != 0 || (~insn & NegativeMask) != 0;
24002387
if (Fail)
24012388
S = MCDisassembler::SoftFail;

0 commit comments

Comments
 (0)