[llvm] 438b910 - [Xtensa] Implement Xtensa Boolean Option. (#126022)

via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 21 12:52:09 PST 2025


Author: Andrei Safronov
Date: 2025-02-21T23:52:06+03:00
New Revision: 438b9102534a28d8167831f113f2c180d1703594

URL: https://github.com/llvm/llvm-project/commit/438b9102534a28d8167831f113f2c180d1703594
DIFF: https://github.com/llvm/llvm-project/commit/438b9102534a28d8167831f113f2c180d1703594.diff

LOG: [Xtensa] Implement Xtensa Boolean Option. (#126022)

Added: 
    llvm/test/MC/Disassembler/Xtensa/boolean.txt
    llvm/test/MC/Xtensa/boolean.s

Modified: 
    llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
    llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp
    llvm/lib/Target/Xtensa/XtensaFeatures.td
    llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
    llvm/lib/Target/Xtensa/XtensaInstrInfo.td
    llvm/lib/Target/Xtensa/XtensaRegisterInfo.td
    llvm/lib/Target/Xtensa/XtensaSubtarget.cpp
    llvm/lib/Target/Xtensa/XtensaSubtarget.h

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
index 7ad8a87ed599a..b1027488904df 100644
--- a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
+++ b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
@@ -57,7 +57,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXtensaDisassembler() {
                                          createXtensaDisassembler);
 }
 
-const unsigned ARDecoderTable[] = {
+const MCPhysReg ARDecoderTable[] = {
     Xtensa::A0,  Xtensa::SP,  Xtensa::A2,  Xtensa::A3, Xtensa::A4,  Xtensa::A5,
     Xtensa::A6,  Xtensa::A7,  Xtensa::A8,  Xtensa::A9, Xtensa::A10, Xtensa::A11,
     Xtensa::A12, Xtensa::A13, Xtensa::A14, Xtensa::A15};
@@ -68,12 +68,12 @@ static DecodeStatus DecodeARRegisterClass(MCInst &Inst, uint64_t RegNo,
   if (RegNo >= std::size(ARDecoderTable))
     return MCDisassembler::Fail;
 
-  unsigned Reg = ARDecoderTable[RegNo];
+  MCPhysReg Reg = ARDecoderTable[RegNo];
   Inst.addOperand(MCOperand::createReg(Reg));
   return MCDisassembler::Success;
 }
 
-const unsigned SRDecoderTable[] = {
+const MCPhysReg SRDecoderTable[] = {
     Xtensa::SAR, 3, Xtensa::WINDOWBASE, 72, Xtensa::WINDOWSTART, 73};
 
 static DecodeStatus DecodeSRRegisterClass(MCInst &Inst, uint64_t RegNo,
@@ -84,7 +84,7 @@ static DecodeStatus DecodeSRRegisterClass(MCInst &Inst, uint64_t RegNo,
 
   for (unsigned i = 0; i < std::size(SRDecoderTable); i += 2) {
     if (SRDecoderTable[i + 1] == RegNo) {
-      unsigned Reg = SRDecoderTable[i];
+      MCPhysReg Reg = SRDecoderTable[i];
 
       if (!Xtensa::checkRegister(Reg,
                                  Decoder->getSubtargetInfo().getFeatureBits()))
@@ -98,6 +98,22 @@ static DecodeStatus DecodeSRRegisterClass(MCInst &Inst, uint64_t RegNo,
   return MCDisassembler::Fail;
 }
 
+const MCPhysReg BRDecoderTable[] = {
+    Xtensa::B0,  Xtensa::B1,  Xtensa::B2,  Xtensa::B3, Xtensa::B4,  Xtensa::B5,
+    Xtensa::B6,  Xtensa::B7,  Xtensa::B8,  Xtensa::B9, Xtensa::B10, Xtensa::B11,
+    Xtensa::B12, Xtensa::B13, Xtensa::B14, Xtensa::B15};
+
+static DecodeStatus DecodeBRRegisterClass(MCInst &Inst, uint64_t RegNo,
+                                          uint64_t Address,
+                                          const void *Decoder) {
+  if (RegNo >= std::size(BRDecoderTable))
+    return MCDisassembler::Fail;
+
+  MCPhysReg Reg = BRDecoderTable[RegNo];
+  Inst.addOperand(MCOperand::createReg(Reg));
+  return MCDisassembler::Success;
+}
+
 static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch,
                                      uint64_t Address, uint64_t Offset,
                                      uint64_t InstSize, MCInst &MI,

diff  --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp
index 37dee072e5b3d..adaa9a71a905c 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp
@@ -77,6 +77,8 @@ bool Xtensa::isValidAddrOffsetForOpcode(unsigned Opcode, int64_t Offset) {
 // Verify Special Register
 bool Xtensa::checkRegister(MCRegister RegNo, const FeatureBitset &FeatureBits) {
   switch (RegNo) {
+  case Xtensa::BREG:
+    return FeatureBits[Xtensa::FeatureBoolean];
   case Xtensa::WINDOWBASE:
   case Xtensa::WINDOWSTART:
     return FeatureBits[Xtensa::FeatureWindowed];

diff  --git a/llvm/lib/Target/Xtensa/XtensaFeatures.td b/llvm/lib/Target/Xtensa/XtensaFeatures.td
index 6f24a674ae0ce..b0cbeb9456796 100644
--- a/llvm/lib/Target/Xtensa/XtensaFeatures.td
+++ b/llvm/lib/Target/Xtensa/XtensaFeatures.td
@@ -12,3 +12,8 @@ def FeatureWindowed : SubtargetFeature<"windowed", "HasWindowed", "true",
                                        "Enable Xtensa Windowed Register option">;
 def HasWindowed : Predicate<"Subtarget->hasWindowed()">,
                   AssemblerPredicate<(all_of FeatureWindowed)>;
+
+def FeatureBoolean          : SubtargetFeature<"bool", "HasBoolean", "true",
+                                               "Enable Xtensa Boolean extension">;
+def HasBoolean              : Predicate<"Subtarget->hasBoolean()">,
+                                         AssemblerPredicate<(all_of FeatureBoolean)>;

diff  --git a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
index cdf38a0669479..57f0cbbc36c24 100644
--- a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
+++ b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
@@ -49,6 +49,10 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &TM,
   // Set up the register classes.
   addRegisterClass(MVT::i32, &Xtensa::ARRegClass);
 
+  if (Subtarget.hasBoolean()) {
+    addRegisterClass(MVT::v1i1, &Xtensa::BRRegClass);
+  }
+
   // Set up special registers.
   setStackPointerRegisterToSaveRestore(Xtensa::SP);
 

diff  --git a/llvm/lib/Target/Xtensa/XtensaInstrInfo.td b/llvm/lib/Target/Xtensa/XtensaInstrInfo.td
index 5ef795a0e5287..e52dcbf1377c5 100644
--- a/llvm/lib/Target/Xtensa/XtensaInstrInfo.td
+++ b/llvm/lib/Target/Xtensa/XtensaInstrInfo.td
@@ -779,3 +779,73 @@ def ROTW : RRR_Inst<0x00, 0x00, 0x04, (outs), (ins imm8n_7:$imm),
   let s = 0x0;
   let t = imm{3-0};
 }
+
+//===----------------------------------------------------------------------===//
+// Boolean Instructions
+//===----------------------------------------------------------------------===//
+
+def ALL4 : RRR_Inst<0x00, 0x00, 0x00, (outs BR:$t), (ins BR:$s),
+                   "all4\t$t, $s", []>, Requires<[HasBoolean]> {
+  let r = 0x9;
+}
+
+def ALL8 : RRR_Inst<0x00, 0x00, 0x00, (outs BR:$t), (ins BR:$s),
+                   "all8\t$t, $s", []>, Requires<[HasBoolean]> {
+  let r = 0xB;
+}
+
+def ANDB : RRR_Inst<0x00, 0x02, 0x00, (outs BR:$r), (ins BR:$s, BR:$t),
+                   "andb\t$r, $s, $t", []>, Requires<[HasBoolean]>;
+def ANDBC : RRR_Inst<0x00, 0x02, 0x01, (outs BR:$r), (ins BR:$s, BR:$t),
+                    "andbc\t$r, $s, $t", []>, Requires<[HasBoolean]>;
+def ORB : RRR_Inst<0x00, 0x02, 0x02, (outs BR:$r), (ins BR:$s, BR:$t),
+                  "orb\t$r, $s, $t", []>, Requires<[HasBoolean]>;
+def ORBC : RRR_Inst<0x00, 0x02, 0x03, (outs BR:$r), (ins BR:$s, BR:$t),
+                   "orbc\t$r, $s, $t", []>, Requires<[HasBoolean]>;
+def XORB : RRR_Inst<0x00, 0x02, 0x04, (outs BR:$r), (ins BR:$s, BR:$t),
+                   "xorb\t$r, $s, $t", []>, Requires<[HasBoolean]>;
+
+def ANY4 : RRR_Inst<0x00, 0x00, 0x00, (outs BR:$t), (ins BR:$s),
+                   "any4\t$t, $s", []>, Requires<[HasBoolean]> {
+  let r = 0x8;
+}
+
+def ANY8 : RRR_Inst<0x00, 0x00, 0x00, (outs BR:$t), (ins BR:$s),
+                   "any8\t$t, $s", []>, Requires<[HasBoolean]> {
+  let r = 0xA;
+}
+
+let isBranch = 1, isTerminator = 1, Predicates = [HasBoolean] in {
+  def BT : RRI8_Inst<0x06, (outs), (ins BR:$b, brtarget:$target),
+                    "bt\t$b, $target", []> {
+    bits<8> target;
+    bits<4> b;
+
+    let r = 0x1;
+    let s = b;
+    let t = 0x7;
+    let imm8 = target;
+  }
+
+  def BF : RRI8_Inst<0x06, (outs), (ins BR:$b, brtarget:$target),
+                    "bf\t$b, $target", []> {
+    bits<8> target;
+    bits<4> b;
+
+    let r = 0x0;
+    let s = b;
+    let t = 0x7;
+    let imm8 = target;
+  }
+}
+
+def : InstAlias<"_BT\t$b, $target", (BT BR:$b, brtarget:$target)>;
+def : InstAlias<"_BF\t$b, $target", (BF BR:$b, brtarget:$target)>;
+
+let Constraints = "$dr = $r, at earlyclobber $dr" in {
+  def MOVF : RRR_Inst<0x00, 0x03, 0x0C, (outs AR:$dr), (ins AR:$r, AR:$s, BR:$t),
+                   "movf\t$r, $s, $t", []>, Requires<[HasBoolean]>;
+
+  def MOVT : RRR_Inst<0x00, 0x03, 0x0D, (outs AR:$dr), (ins AR:$r, AR:$s, BR:$t),
+                   "movt\t$r, $s, $t", []>, Requires<[HasBoolean]>;
+}

diff  --git a/llvm/lib/Target/Xtensa/XtensaRegisterInfo.td b/llvm/lib/Target/Xtensa/XtensaRegisterInfo.td
index 09087edc86712..920354ff41ba5 100644
--- a/llvm/lib/Target/Xtensa/XtensaRegisterInfo.td
+++ b/llvm/lib/Target/Xtensa/XtensaRegisterInfo.td
@@ -64,6 +64,7 @@ def A15 : ARReg<15, "a15">, DwarfRegNum<[15]>;
 def AR : RegisterClass<"Xtensa", [i32], 32, (add
   A8, A9, A10, A11, A12, A13, A14, A15,
   A7, A6, A5, A4, A3, A2, A0, SP)>;
+
 //===----------------------------------------------------------------------===//
 // Special-purpose registers
 //===----------------------------------------------------------------------===//
@@ -75,8 +76,29 @@ class SRReg<bits<8> num, string n, list<string> alt = []> : XtensaReg<n> {
 // Shift Amount Register
 def SAR : SRReg<3, "sar", ["SAR","3"]>;
 
+// Boolean Register
+def BREG : SRReg<4, "br", ["BR","4"]>;
+
 // Windowed Register Option registers
 def WINDOWBASE : SRReg<72, "windowbase", ["WINDOWBASE", "72"]>;
 def WINDOWSTART : SRReg<73, "windowstart", ["WINDOWSTART", "73"]>;
 
-def SR :  RegisterClass<"Xtensa", [i32], 32, (add SAR, WINDOWBASE, WINDOWSTART)>;
+def SR :  RegisterClass<"Xtensa", [i32], 32, (add SAR, BREG,
+  WINDOWBASE, WINDOWSTART)>;
+
+//===----------------------------------------------------------------------===//
+// Boolean registers
+//===----------------------------------------------------------------------===//
+class BReg<bits<4> num, string n> : XtensaReg<n> {
+  let HWEncoding{3-0} = num;
+}
+
+foreach i = 0-15 in {
+  def B#i  : BReg<i, "b"#i>;
+}
+
+// Boolean register class
+def BR : RegisterClass<"Xtensa", [v1i1], 8, (add B0, B1,
+  B2, B3, B4, B5, B6, B7, B8, B9, B10, B11, B12, B13, B14, B15)> {
+  let Size = 8;
+}

diff  --git a/llvm/lib/Target/Xtensa/XtensaSubtarget.cpp b/llvm/lib/Target/Xtensa/XtensaSubtarget.cpp
index d6b1b4bc15463..6b1d3255db247 100644
--- a/llvm/lib/Target/Xtensa/XtensaSubtarget.cpp
+++ b/llvm/lib/Target/Xtensa/XtensaSubtarget.cpp
@@ -30,8 +30,6 @@ XtensaSubtarget::initializeSubtargetDependencies(StringRef CPU, StringRef FS) {
     CPUName = "generic";
   }
 
-  HasDensity = false;
-
   // Parse features string.
   ParseSubtargetFeatures(CPUName, CPUName, FS);
   return *this;

diff  --git a/llvm/lib/Target/Xtensa/XtensaSubtarget.h b/llvm/lib/Target/Xtensa/XtensaSubtarget.h
index dddc0f7ef605d..962bed2c2e36f 100644
--- a/llvm/lib/Target/Xtensa/XtensaSubtarget.h
+++ b/llvm/lib/Target/Xtensa/XtensaSubtarget.h
@@ -36,11 +36,10 @@ class XtensaSubtarget : public XtensaGenSubtargetInfo {
   SelectionDAGTargetInfo TSInfo;
   XtensaFrameLowering FrameLowering;
 
-  // Enabled Xtensa Density Option
-  bool HasDensity;
-
-  // Enabled Xtensa Windowed Register Option
-  bool HasWindowed;
+// Bool members corresponding to the SubtargetFeatures defined in tablegen
+#define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER)                    \
+  bool ATTRIBUTE = DEFAULT;
+#include "XtensaGenSubtargetInfo.inc"
 
   XtensaSubtarget &initializeSubtargetDependencies(StringRef CPU, StringRef FS);
 
@@ -69,6 +68,8 @@ class XtensaSubtarget : public XtensaGenSubtargetInfo {
 
   bool hasWindowed() const { return HasWindowed; }
 
+  bool hasBoolean() const { return HasBoolean; }
+
   // Automatically generated by tblgen.
   void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
 };

diff  --git a/llvm/test/MC/Disassembler/Xtensa/boolean.txt b/llvm/test/MC/Disassembler/Xtensa/boolean.txt
new file mode 100644
index 0000000000000..5763db6b4f166
--- /dev/null
+++ b/llvm/test/MC/Disassembler/Xtensa/boolean.txt
@@ -0,0 +1,59 @@
+# NOTE: Assertions have been autogenerated by utils/update_mc_test_checks.py UTC_ARGS: --version 5
+# RUN: llvm-mc -triple=xtensa -mattr=+bool -disassemble %s | FileCheck -check-prefixes=CHECK-BOOLEAN %s
+# RUN: not llvm-mc -triple=xtensa -disassemble %s 2>&1 | FileCheck --implicit-check-not=warning: -check-prefixes=CHECK-CORE %s
+
+## Verify that binary code is correctly disassembled with
+## boolean option enabled. Also verify that dissasembling without
+## boolean option generates warnings.
+
+[0x10,0x94,0x00]
+# CHECK-BOOLEAN: all4	b1, b4
+# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
+
+[0x10,0xb8,0x00]
+# CHECK-BOOLEAN: all8	b1, b8
+# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
+
+[0x30,0x12,0x02]
+# CHECK-BOOLEAN: andb	b1, b2, b3
+# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
+
+[0x30,0x12,0x12]
+# CHECK-BOOLEAN: andbc	b1, b2, b3
+# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
+
+[0x30,0x12,0x22]
+# CHECK-BOOLEAN: orb	b1, b2, b3
+# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
+
+[0x30,0x12,0x32]
+# CHECK-BOOLEAN: orbc	b1, b2, b3
+# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
+
+[0x30,0x12,0x42]
+# CHECK-BOOLEAN: xorb	b1, b2, b3
+# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
+
+[0x10,0x84,0x00]
+# CHECK-BOOLEAN: any4	b1, b4
+# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
+
+[0x10,0xa8,0x00]
+# CHECK-BOOLEAN: any8	b1, b8
+# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
+
+[0x76,0x11,0x10]
+# CHECK-BOOLEAN: bt	b1, . +20
+# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
+
+[0x76,0x00,0x10]
+# CHECK-BOOLEAN: bf	b0, . +20
+# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
+
+[0x10,0x23,0xc3]
+# CHECK-BOOLEAN: movf	a2, a3, b1
+# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
+
+[0x20,0x34,0xd3]
+# CHECK-BOOLEAN: movt	a3, a4, b2
+# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding

diff  --git a/llvm/test/MC/Xtensa/boolean.s b/llvm/test/MC/Xtensa/boolean.s
new file mode 100644
index 0000000000000..6429370558e0c
--- /dev/null
+++ b/llvm/test/MC/Xtensa/boolean.s
@@ -0,0 +1,58 @@
+# RUN: llvm-mc %s -triple=xtensa -show-encoding --mattr=+bool \
+# RUN:     | FileCheck -check-prefixes=CHECK %s
+
+.align	4
+// CHECK: .p2align	4
+
+LBL0:
+// CHECK: LBL0:
+
+all4 b1, b4
+// CHECK: all4	b1, b4                          # encoding: [0x10,0x94,0x00]
+
+all8 b1, b8
+// CHECK: all8	b1, b8                          # encoding: [0x10,0xb8,0x00]
+
+andb b1, b2, b3
+// CHECK: andb	b1, b2, b3                      # encoding: [0x30,0x12,0x02]
+
+andbc b1, b2, b3
+// CHECK: andbc	b1, b2, b3                      # encoding: [0x30,0x12,0x12]
+
+orb b1, b2, b3
+// CHECK: orb	b1, b2, b3                      # encoding: [0x30,0x12,0x22]
+
+orbc b1, b2, b3
+// CHECK: orbc	b1, b2, b3                      # encoding: [0x30,0x12,0x32]
+
+xorb b1, b2, b3
+// CHECK: xorb	b1, b2, b3                      # encoding: [0x30,0x12,0x42]
+
+any4 b1, b4
+// CHECK: any4	b1, b4                          # encoding: [0x10,0x84,0x00]
+
+any8 b1, b8
+// CHECK: any8	b1, b8                          # encoding: [0x10,0xa8,0x00]
+
+bt b1, LBL0
+// CHECK: bt	b1, LBL0                        # encoding: [0x76,0x11,A]
+// CHECK-NEXT: #   fixup A - offset: 0, value: LBL0, kind: fixup_xtensa_branch_8
+
+bf b0, LBL0
+// CHECK: bf	b0, LBL0                        # encoding: [0x76,0x00,A]
+// CHECK-NEXT: #   fixup A - offset: 0, value: LBL0, kind: fixup_xtensa_branch_8
+
+movf a2, a3, b1
+// CHECK: movf	a2, a3, b1                      # encoding: [0x10,0x23,0xc3]
+
+movt a3, a4, b2
+// CHECK: movt	a3, a4, b2                      # encoding: [0x20,0x34,0xd3]
+
+xsr a3, br
+// CHECK: xsr	a3, br                          # encoding: [0x30,0x04,0x61]
+
+xsr.br a3
+// CHECK: xsr	a3, br                          # encoding: [0x30,0x04,0x61]
+
+xsr a3, 4
+// CHECK: xsr	a3, br                          # encoding: [0x30,0x04,0x61]


        


More information about the llvm-commits mailing list