Skip to content

Conversation

@andreisfr
Copy link
Contributor

No description provided.

@llvmbot llvmbot added llvm:mc Machine (object) code backend:Xtensa labels Feb 6, 2025
@llvmbot
Copy link
Member

llvmbot commented Feb 6, 2025

@llvm/pr-subscribers-backend-xtensa

Author: Andrei Safronov (andreisfr)

Changes

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

8 Files Affected:

  • (modified) llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp (+16)
  • (modified) llvm/lib/Target/Xtensa/XtensaFeatures.td (+5)
  • (modified) llvm/lib/Target/Xtensa/XtensaISelLowering.cpp (+4)
  • (modified) llvm/lib/Target/Xtensa/XtensaInstrInfo.td (+70)
  • (modified) llvm/lib/Target/Xtensa/XtensaRegisterInfo.td (+18)
  • (modified) llvm/lib/Target/Xtensa/XtensaSubtarget.h (+5)
  • (added) llvm/test/MC/Disassembler/Xtensa/boolean.txt (+59)
  • (added) llvm/test/MC/Xtensa/boolean.s (+52)
diff --git a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
index 7ad8a87ed599ae1..27d1cc9c8177c3c 100644
--- a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
+++ b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
@@ -98,6 +98,22 @@ static DecodeStatus DecodeSRRegisterClass(MCInst &Inst, uint64_t RegNo,
   return MCDisassembler::Fail;
 }
 
+const unsigned 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;
+
+  unsigned 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/XtensaFeatures.td b/llvm/lib/Target/Xtensa/XtensaFeatures.td
index 6f24a674ae0ce20..b0cbeb9456796e5 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 cdf38a06694796a..57f0cbbc36c24ce 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 5ef795a0e5287a3..e52dcbf1377c51b 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,@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 09087edc86712d9..07433331bab92a0 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
 //===----------------------------------------------------------------------===//
@@ -80,3 +81,20 @@ def WINDOWBASE : SRReg<72, "windowbase", ["WINDOWBASE", "72"]>;
 def WINDOWSTART : SRReg<73, "windowstart", ["WINDOWSTART", "73"]>;
 
 def SR :  RegisterClass<"Xtensa", [i32], 32, (add SAR, 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.h b/llvm/lib/Target/Xtensa/XtensaSubtarget.h
index dddc0f7ef605d78..ef83bcc98702779 100644
--- a/llvm/lib/Target/Xtensa/XtensaSubtarget.h
+++ b/llvm/lib/Target/Xtensa/XtensaSubtarget.h
@@ -42,6 +42,9 @@ class XtensaSubtarget : public XtensaGenSubtargetInfo {
   // Enabled Xtensa Windowed Register Option
   bool HasWindowed;
 
+  // Enabled Boolean Option
+  bool HasBoolean;
+
   XtensaSubtarget &initializeSubtargetDependencies(StringRef CPU, StringRef FS);
 
 public:
@@ -69,6 +72,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 000000000000000..5763db6b4f1660b
--- /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 000000000000000..339d036197cf9fa
--- /dev/null
+++ b/llvm/test/MC/Xtensa/boolean.s
@@ -0,0 +1,52 @@
+// NOTE: Assertions have been autogenerated by utils/update_mc_test_checks.py UTC_ARGS: --version 5
+# RUN: llvm-mc %s -triple=xtensa -show-encoding --mattr=+bool \
+# RUN:     | FileCheck -check-prefixes=CHECK,CHECK-INST %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]
+//// NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+// CHECK-INST: {{.*}}

@llvmbot
Copy link
Member

llvmbot commented Feb 6, 2025

@llvm/pr-subscribers-mc

Author: Andrei Safronov (andreisfr)

Changes

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

8 Files Affected:

  • (modified) llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp (+16)
  • (modified) llvm/lib/Target/Xtensa/XtensaFeatures.td (+5)
  • (modified) llvm/lib/Target/Xtensa/XtensaISelLowering.cpp (+4)
  • (modified) llvm/lib/Target/Xtensa/XtensaInstrInfo.td (+70)
  • (modified) llvm/lib/Target/Xtensa/XtensaRegisterInfo.td (+18)
  • (modified) llvm/lib/Target/Xtensa/XtensaSubtarget.h (+5)
  • (added) llvm/test/MC/Disassembler/Xtensa/boolean.txt (+59)
  • (added) llvm/test/MC/Xtensa/boolean.s (+52)
diff --git a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
index 7ad8a87ed599ae1..27d1cc9c8177c3c 100644
--- a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
+++ b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
@@ -98,6 +98,22 @@ static DecodeStatus DecodeSRRegisterClass(MCInst &Inst, uint64_t RegNo,
   return MCDisassembler::Fail;
 }
 
+const unsigned 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;
+
+  unsigned 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/XtensaFeatures.td b/llvm/lib/Target/Xtensa/XtensaFeatures.td
index 6f24a674ae0ce20..b0cbeb9456796e5 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 cdf38a06694796a..57f0cbbc36c24ce 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 5ef795a0e5287a3..e52dcbf1377c51b 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,@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 09087edc86712d9..07433331bab92a0 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
 //===----------------------------------------------------------------------===//
@@ -80,3 +81,20 @@ def WINDOWBASE : SRReg<72, "windowbase", ["WINDOWBASE", "72"]>;
 def WINDOWSTART : SRReg<73, "windowstart", ["WINDOWSTART", "73"]>;
 
 def SR :  RegisterClass<"Xtensa", [i32], 32, (add SAR, 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.h b/llvm/lib/Target/Xtensa/XtensaSubtarget.h
index dddc0f7ef605d78..ef83bcc98702779 100644
--- a/llvm/lib/Target/Xtensa/XtensaSubtarget.h
+++ b/llvm/lib/Target/Xtensa/XtensaSubtarget.h
@@ -42,6 +42,9 @@ class XtensaSubtarget : public XtensaGenSubtargetInfo {
   // Enabled Xtensa Windowed Register Option
   bool HasWindowed;
 
+  // Enabled Boolean Option
+  bool HasBoolean;
+
   XtensaSubtarget &initializeSubtargetDependencies(StringRef CPU, StringRef FS);
 
 public:
@@ -69,6 +72,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 000000000000000..5763db6b4f1660b
--- /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 000000000000000..339d036197cf9fa
--- /dev/null
+++ b/llvm/test/MC/Xtensa/boolean.s
@@ -0,0 +1,52 @@
+// NOTE: Assertions have been autogenerated by utils/update_mc_test_checks.py UTC_ARGS: --version 5
+# RUN: llvm-mc %s -triple=xtensa -show-encoding --mattr=+bool \
+# RUN:     | FileCheck -check-prefixes=CHECK,CHECK-INST %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]
+//// NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+// CHECK-INST: {{.*}}

@andreisfr andreisfr force-pushed the xtensa_boolean_option branch from 2ddca55 to eee6155 Compare February 10, 2025 15:06
@andreisfr andreisfr requested review from MaskRay and arsenm February 10, 2025 15:07
return MCDisassembler::Fail;
}

const unsigned BRDecoderTable[] = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MCPhysReg?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you very much for comments. Fixed.

bool HasWindowed;

// Enabled Boolean Option
bool HasBoolean;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initialize here (the other existing features also should have initialized here)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, I used bool members corresponding to the SubtargetFeatures defined in tablegen.

@andreisfr andreisfr requested a review from arsenm February 15, 2025 12:07
@andreisfr andreisfr merged commit 438b910 into llvm:main Feb 21, 2025
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend:Xtensa llvm:mc Machine (object) code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants