[llvm] [Hexagon] Provide a custom decoder for Y4_crswap10 (PR #153849)

Sergei Barannikov via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 15 18:41:07 PDT 2025


https://github.com/s-barannikov updated https://github.com/llvm/llvm-project/pull/153849

>From 99a754290e8597c60538b3182bb6f93f8c97df16 Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Fri, 15 Aug 2025 21:07:18 +0300
Subject: [PATCH 1/2] [Hexagon] Provide a custom decoder for Y4_crswap10

Auto-generated decoder fails to add the $sgp10 operand
because it has no encoding bits.
Provide a custom decoder function that adds the operand.

Fixes #153829.
---
 .../Hexagon/Disassembler/HexagonDisassembler.cpp  | 15 +++++++++++++++
 llvm/lib/Target/Hexagon/HexagonDepInstrFormats.td |  1 -
 llvm/lib/Target/Hexagon/HexagonDepInstrInfo.td    |  2 ++
 llvm/test/MC/Hexagon/system-inst.s                |  3 +++
 4 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp b/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp
index 22cff7c80fa01..fcda20dc78d15 100644
--- a/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp
+++ b/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp
@@ -172,6 +172,11 @@ static DecodeStatus s32_0ImmDecoder(MCInst &MI, unsigned tmp,
                                     const MCDisassembler *Decoder);
 static DecodeStatus brtargetDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
                                     const MCDisassembler *Decoder);
+
+static DecodeStatus decodeCRSWAP10(MCInst &Inst, unsigned Bits,
+                                   uint64_t Address,
+                                   const MCDisassembler *Decoder);
+
 #include "HexagonDepDecoders.inc"
 #include "HexagonGenDisassemblerTables.inc"
 
@@ -841,6 +846,16 @@ static DecodeStatus brtargetDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
   return MCDisassembler::Success;
 }
 
+static DecodeStatus decodeCRSWAP10(MCInst &Inst, unsigned int Bits,
+                                   uint64_t Address,
+                                   const MCDisassembler *Decoder) {
+  unsigned RegNo = fieldFromInstruction(Bits, 16, 5);
+  DecodeDoubleRegsRegisterClass(Inst, RegNo, Address, Decoder);
+  DecodeDoubleRegsRegisterClass(Inst, RegNo, Address, Decoder);
+  Inst.addOperand(MCOperand::createReg(Hexagon::SGP1_0));
+  return MCDisassembler::Success;
+}
+
 static const uint16_t SysRegDecoderTable[] = {
     Hexagon::SGP0,       Hexagon::SGP1,      Hexagon::STID,
     Hexagon::ELR,        Hexagon::BADVA0,    Hexagon::BADVA1,
diff --git a/llvm/lib/Target/Hexagon/HexagonDepInstrFormats.td b/llvm/lib/Target/Hexagon/HexagonDepInstrFormats.td
index 75e87c95f2c48..661b948346126 100644
--- a/llvm/lib/Target/Hexagon/HexagonDepInstrFormats.td
+++ b/llvm/lib/Target/Hexagon/HexagonDepInstrFormats.td
@@ -3049,7 +3049,6 @@ class Enc_cf1927 : OpcodeHexagon {
 class Enc_d0fe02 : OpcodeHexagon {
   bits <5> Rxx32;
   let Inst{20-16} = Rxx32{4-0};
-  bits <0> sgp10;
 }
 class Enc_d15d19 : OpcodeHexagon {
   bits <1> Mu2;
diff --git a/llvm/lib/Target/Hexagon/HexagonDepInstrInfo.td b/llvm/lib/Target/Hexagon/HexagonDepInstrInfo.td
index ae96753f40cf2..993db0344e1fd 100644
--- a/llvm/lib/Target/Hexagon/HexagonDepInstrInfo.td
+++ b/llvm/lib/Target/Hexagon/HexagonDepInstrInfo.td
@@ -41176,6 +41176,8 @@ let Inst{31-21} = 0b01101101100;
 let Uses = [SGP0, SGP1];
 let Defs = [SGP0, SGP1];
 let Constraints = "$Rxx32 = $Rxx32in";
+// $sgp10 operand has no encoding bits, we have to add the operand manually.
+let DecoderMethod = "decodeCRSWAP10";
 }
 def Y4_l2fetch : HInst<
 (outs),
diff --git a/llvm/test/MC/Hexagon/system-inst.s b/llvm/test/MC/Hexagon/system-inst.s
index 7bc1533598532..07f7ca0acb2dc 100644
--- a/llvm/test/MC/Hexagon/system-inst.s
+++ b/llvm/test/MC/Hexagon/system-inst.s
@@ -89,6 +89,9 @@ crswap(r12,sgp0)
 #CHECK: 652dc000 { crswap(r13,sgp1) }
 crswap(r13,sgp1)
 
+#CHECK: 6d8ec000 { crswap(r15:14,s1:0) }
+crswap(r15:14,sgp1:0)
+
 #CHECK: 660fc00e { r14 = getimask(r15) }
 r14=getimask(r15)
 

>From 5bdf27222da751d9f56b9ab58adbc23ce59b8522 Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Sat, 16 Aug 2025 04:39:24 +0300
Subject: [PATCH 2/2] Move the workaround to
 HexagonDisassembler::getSingleInstrcution

---
 .../Disassembler/HexagonDisassembler.cpp       | 18 +++---------------
 .../Target/Hexagon/HexagonDepInstrFormats.td   |  1 +
 llvm/lib/Target/Hexagon/HexagonDepInstrInfo.td |  2 --
 3 files changed, 4 insertions(+), 17 deletions(-)

diff --git a/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp b/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp
index fcda20dc78d15..bcddb540d35dc 100644
--- a/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp
+++ b/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp
@@ -172,11 +172,6 @@ static DecodeStatus s32_0ImmDecoder(MCInst &MI, unsigned tmp,
                                     const MCDisassembler *Decoder);
 static DecodeStatus brtargetDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
                                     const MCDisassembler *Decoder);
-
-static DecodeStatus decodeCRSWAP10(MCInst &Inst, unsigned Bits,
-                                   uint64_t Address,
-                                   const MCDisassembler *Decoder);
-
 #include "HexagonDepDecoders.inc"
 #include "HexagonGenDisassemblerTables.inc"
 
@@ -531,6 +526,9 @@ DecodeStatus HexagonDisassembler::getSingleInstruction(MCInst &MI, MCInst &MCB,
     MI.insert(MI.begin() + 1,
               MCOperand::createExpr(MCConstantExpr::create(-1, getContext())));
     break;
+  case Hexagon::Y4_crswap10:
+    MI.addOperand(MCOperand::createReg(Hexagon::SGP1_0));
+    break;
   default:
     break;
   }
@@ -846,16 +844,6 @@ static DecodeStatus brtargetDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
   return MCDisassembler::Success;
 }
 
-static DecodeStatus decodeCRSWAP10(MCInst &Inst, unsigned int Bits,
-                                   uint64_t Address,
-                                   const MCDisassembler *Decoder) {
-  unsigned RegNo = fieldFromInstruction(Bits, 16, 5);
-  DecodeDoubleRegsRegisterClass(Inst, RegNo, Address, Decoder);
-  DecodeDoubleRegsRegisterClass(Inst, RegNo, Address, Decoder);
-  Inst.addOperand(MCOperand::createReg(Hexagon::SGP1_0));
-  return MCDisassembler::Success;
-}
-
 static const uint16_t SysRegDecoderTable[] = {
     Hexagon::SGP0,       Hexagon::SGP1,      Hexagon::STID,
     Hexagon::ELR,        Hexagon::BADVA0,    Hexagon::BADVA1,
diff --git a/llvm/lib/Target/Hexagon/HexagonDepInstrFormats.td b/llvm/lib/Target/Hexagon/HexagonDepInstrFormats.td
index 661b948346126..75e87c95f2c48 100644
--- a/llvm/lib/Target/Hexagon/HexagonDepInstrFormats.td
+++ b/llvm/lib/Target/Hexagon/HexagonDepInstrFormats.td
@@ -3049,6 +3049,7 @@ class Enc_cf1927 : OpcodeHexagon {
 class Enc_d0fe02 : OpcodeHexagon {
   bits <5> Rxx32;
   let Inst{20-16} = Rxx32{4-0};
+  bits <0> sgp10;
 }
 class Enc_d15d19 : OpcodeHexagon {
   bits <1> Mu2;
diff --git a/llvm/lib/Target/Hexagon/HexagonDepInstrInfo.td b/llvm/lib/Target/Hexagon/HexagonDepInstrInfo.td
index 993db0344e1fd..ae96753f40cf2 100644
--- a/llvm/lib/Target/Hexagon/HexagonDepInstrInfo.td
+++ b/llvm/lib/Target/Hexagon/HexagonDepInstrInfo.td
@@ -41176,8 +41176,6 @@ let Inst{31-21} = 0b01101101100;
 let Uses = [SGP0, SGP1];
 let Defs = [SGP0, SGP1];
 let Constraints = "$Rxx32 = $Rxx32in";
-// $sgp10 operand has no encoding bits, we have to add the operand manually.
-let DecoderMethod = "decodeCRSWAP10";
 }
 def Y4_l2fetch : HInst<
 (outs),



More information about the llvm-commits mailing list