diff --git a/llvm/test/TableGen/DecoderEmitter/large-islands.td b/llvm/test/TableGen/DecoderEmitter/large-islands.td new file mode 100644 index 000000000000..541cba495dc3 --- /dev/null +++ b/llvm/test/TableGen/DecoderEmitter/large-islands.td @@ -0,0 +1,38 @@ +// RUN: llvm-tblgen -gen-disassembler -I %p/../../../include %s | FileCheck %s + +include "llvm/Target/Target.td" + +class I opcode> : Instruction { + let InOperandList = ins; + let OutOperandList = outs; + + bits<5> dst; + bits<5> src0; + bits<5> src1; + + int Size = 16; + bits<128> Inst; + + let Inst{4...0} = opcode; + let Inst{9...5} = dst; + let Inst{14...10} = src0; + let Inst{19...15} = src1; + + let Inst{127...20} = 0xdeadbeef; +} + +def Reg : Register<"reg">; + +def Regs : RegisterClass<"foo", [i32], 0, (add Reg)>; + +def IAdd : I<(outs Regs:$dst), (ins Regs:$src0, Regs:$src1), 0b10101>; + +// CHECK-LABEL: static const uint8_t DecoderTable128[20] = { +// CHECK-NEXT: OPC_CheckField, 84, 44, 0, // 0: check Inst[127:84] == 0x0 +// CHECK-NEXT: OPC_CheckField, 20, 64, 239, 253, 182, 245, 13, + +def II : InstrInfo; + +def MyTarget : Target { + let InstructionSet = II; +} diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp index 5d41b7dc3c31..664c3009ff50 100644 --- a/llvm/utils/TableGen/DecoderEmitter.cpp +++ b/llvm/utils/TableGen/DecoderEmitter.cpp @@ -656,8 +656,14 @@ static std::vector getIslands(const KnownBits &EncodingBits, if (!IsFiltered && IsKnown) { if (OnIsland) { // Accumulate island bits. - FieldVal |= static_cast(EncodingBits.One[I]) - << (I - StartBit); + const unsigned BitNo = I - StartBit; + FieldVal |= static_cast(EncodingBits.One[I]) << (BitNo); + // If island becomes larger than 64-bits complete the island and start a + // new one + if (BitNo >= 63) { + Islands.push_back({StartBit, 64, FieldVal}); + OnIsland = false; + } } else { // Onto an island. StartBit = I;