Skip to content

Conversation

s-barannikov
Copy link
Contributor

tmp is always of integer type, so we can use bitwise OR and shift.

@llvmbot llvmbot added tablegen llvm:mc Machine (object) code labels Sep 17, 2025
@llvmbot
Copy link
Member

llvmbot commented Sep 17, 2025

@llvm/pr-subscribers-llvm-mc

@llvm/pr-subscribers-tablegen

Author: Sergei Barannikov (s-barannikov)

Changes

tmp is always of integer type, so we can use bitwise OR and shift.


Full diff: https://github.com/llvm/llvm-project/pull/159353.diff

5 Files Affected:

  • (modified) llvm/include/llvm/MC/MCDecoder.h (-14)
  • (modified) llvm/test/TableGen/BitOffsetDecoder.td (+2-2)
  • (modified) llvm/test/TableGen/DecoderEmitter/VarLenDecoder.td (+2-2)
  • (modified) llvm/test/TableGen/DecoderEmitter/operand-decoder.td (+7-7)
  • (modified) llvm/utils/TableGen/DecoderEmitter.cpp (+7-3)
diff --git a/llvm/include/llvm/MC/MCDecoder.h b/llvm/include/llvm/MC/MCDecoder.h
index 87df6c10d8bb2..175f6a9591558 100644
--- a/llvm/include/llvm/MC/MCDecoder.h
+++ b/llvm/include/llvm/MC/MCDecoder.h
@@ -58,20 +58,6 @@ uint64_t fieldFromInstruction(const std::bitset<N> &Insn, unsigned StartBit,
   return ((Insn >> StartBit) & Mask).to_ullong();
 }
 
-// Helper function for inserting bits extracted from an encoded instruction into
-// an integer-typed field.
-template <typename IntType>
-static std::enable_if_t<std::is_integral_v<IntType>, void>
-insertBits(IntType &field, IntType bits, unsigned startBit, unsigned numBits) {
-  // Check that no bit beyond numBits is set, so that a simple bitwise |
-  // is sufficient.
-  assert((~(((IntType)1 << numBits) - 1) & bits) == 0 &&
-         "bits has more than numBits bits set");
-  assert(startBit + numBits <= sizeof(IntType) * 8);
-  (void)numBits;
-  field |= bits << startBit;
-}
-
 } // namespace llvm::MCD
 
 #endif // LLVM_MC_MCDECODER_H
diff --git a/llvm/test/TableGen/BitOffsetDecoder.td b/llvm/test/TableGen/BitOffsetDecoder.td
index 04d6e164d0eee..f94e8d4f09789 100644
--- a/llvm/test/TableGen/BitOffsetDecoder.td
+++ b/llvm/test/TableGen/BitOffsetDecoder.td
@@ -59,6 +59,6 @@ def baz : Instruction {
 
 // CHECK: tmp = fieldFromInstruction(insn, 8, 7);
 // CHECK: tmp = fieldFromInstruction(insn, 8, 8) << 3;
-// CHECK: insertBits(tmp, fieldFromInstruction(insn, 8, 4), 7, 4);
-// CHECK: insertBits(tmp, fieldFromInstruction(insn, 12, 4), 3, 4);
+// CHECK: tmp |= fieldFromInstruction(insn, 8, 4) << 7;
+// CHECK: tmp |= fieldFromInstruction(insn, 12, 4) << 3;
 // CHECK: tmp = fieldFromInstruction(insn, 8, 8) << 4;
diff --git a/llvm/test/TableGen/DecoderEmitter/VarLenDecoder.td b/llvm/test/TableGen/DecoderEmitter/VarLenDecoder.td
index 0d913dc7587ed..d046c1a192111 100644
--- a/llvm/test/TableGen/DecoderEmitter/VarLenDecoder.td
+++ b/llvm/test/TableGen/DecoderEmitter/VarLenDecoder.td
@@ -81,8 +81,8 @@ def FOO32 : MyVarInst<MemOp32> {
 // CHECK-NEXT: tmp = fieldFromInstruction(insn, 0, 3);
 // CHECK-NEXT: if (!Check(S, myCustomDecoder(MI, tmp, Address, Decoder))) { return MCDisassembler::Fail; }
 // CHECK-NEXT: tmp = 0x0;
-// CHECK-NEXT: insertBits(tmp, fieldFromInstruction(insn, 11, 16), 16, 16);
-// CHECK-NEXT: insertBits(tmp, fieldFromInstruction(insn, 27, 16), 0, 16);
+// CHECK-NEXT: tmp |= fieldFromInstruction(insn, 11, 16) << 16;
+// CHECK-NEXT: tmp |= fieldFromInstruction(insn, 27, 16);
 // CHECK-NEXT: MI.addOperand(MCOperand::createImm(tmp));
 // CHECK-NEXT: return S;
 
diff --git a/llvm/test/TableGen/DecoderEmitter/operand-decoder.td b/llvm/test/TableGen/DecoderEmitter/operand-decoder.td
index f281996cf9a86..c6ec2ee1a4db4 100644
--- a/llvm/test/TableGen/DecoderEmitter/operand-decoder.td
+++ b/llvm/test/TableGen/DecoderEmitter/operand-decoder.td
@@ -17,25 +17,25 @@ def MyTarget : Target {
 // CHECK-NEXT:    tmp = fieldFromInstruction(insn, 2, 4);
 // CHECK-NEXT:    MI.addOperand(MCOperand::createImm(tmp));
 // CHECK-NEXT:    tmp = 0x0;
-// CHECK-NEXT:    insertBits(tmp, fieldFromInstruction(insn, 0, 2), 0, 2);
-// CHECK-NEXT:    insertBits(tmp, fieldFromInstruction(insn, 6, 2), 2, 2);
+// CHECK-NEXT:    tmp |= fieldFromInstruction(insn, 0, 2);
+// CHECK-NEXT:    tmp |= fieldFromInstruction(insn, 6, 2) << 2;
 // CHECK-NEXT:    MI.addOperand(MCOperand::createImm(tmp));
 // CHECK-NEXT:    tmp = 0x0;
 // CHECK-NEXT:    MI.addOperand(MCOperand::createImm(tmp));
 // CHECK-NEXT:    tmp = fieldFromInstruction(insn, 13, 2) << 1;
 // CHECK-NEXT:    MI.addOperand(MCOperand::createImm(tmp));
 // CHECK-NEXT:    tmp = 0x0;
-// CHECK-NEXT:    insertBits(tmp, fieldFromInstruction(insn, 17, 1), 1, 1);
-// CHECK-NEXT:    insertBits(tmp, fieldFromInstruction(insn, 19, 1), 3, 1);
+// CHECK-NEXT:    tmp |= fieldFromInstruction(insn, 17, 1) << 1;
+// CHECK-NEXT:    tmp |= fieldFromInstruction(insn, 19, 1) << 3;
 // CHECK-NEXT:    MI.addOperand(MCOperand::createImm(tmp));
 // CHECK-NEXT:    tmp = 0x5;
 // CHECK-NEXT:    MI.addOperand(MCOperand::createImm(tmp));
 // CHECK-NEXT:    tmp = 0x2;
-// CHECK-NEXT:    insertBits(tmp, fieldFromInstruction(insn, 26, 2), 2, 2);
+// CHECK-NEXT:    tmp |= fieldFromInstruction(insn, 26, 2) << 2;
 // CHECK-NEXT:    MI.addOperand(MCOperand::createImm(tmp));
 // CHECK-NEXT:    tmp = 0xa;
-// CHECK-NEXT:    insertBits(tmp, fieldFromInstruction(insn, 28, 1), 0, 1);
-// CHECK-NEXT:    insertBits(tmp, fieldFromInstruction(insn, 30, 1), 2, 1);
+// CHECK-NEXT:    tmp |= fieldFromInstruction(insn, 28, 1);
+// CHECK-NEXT:    tmp |= fieldFromInstruction(insn, 30, 1) << 2;
 // CHECK-NEXT:    MI.addOperand(MCOperand::createImm(tmp));
 // CHECK-NEXT:    return S;
 
diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp
index fc22c9d18d821..fadb95e651dcc 100644
--- a/llvm/utils/TableGen/DecoderEmitter.cpp
+++ b/llvm/utils/TableGen/DecoderEmitter.cpp
@@ -1041,9 +1041,13 @@ static void emitBinaryParser(raw_ostream &OS, indent Indent,
     // insert the variable parts into it.
     OS << Indent << "tmp = " << format_hex(OpInfo.InitValue.value_or(0), 0)
        << ";\n";
-    for (auto [Base, Width, Offset] : OpInfo.fields())
-      OS << Indent << "insertBits(tmp, fieldFromInstruction(insn, " << Base
-         << ", " << Width << "), " << Offset << ", " << Width << ");\n";
+    for (auto [Base, Width, Offset] : OpInfo.fields()) {
+      OS << Indent << "tmp |= fieldFromInstruction(insn, " << Base << ", "
+         << Width << ")";
+      if (Offset)
+        OS << " << " << Offset;
+      OS << ";\n";
+    }
   }
 
   StringRef Decoder = OpInfo.Decoder;

@s-barannikov s-barannikov enabled auto-merge (squash) September 17, 2025 13:17
@s-barannikov s-barannikov merged commit db204d9 into llvm:main Sep 17, 2025
9 checks passed
@s-barannikov s-barannikov deleted the tablegen/decoder/inline-insert-bits branch September 17, 2025 13:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
llvm:mc Machine (object) code tablegen
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants