[llvm] [Xtensa] Implement Xtensa Boolean Option. (PR #126022)
Andrei Safronov via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 10 07:06:20 PST 2025
https://github.com/andreisfr updated https://github.com/llvm/llvm-project/pull/126022
>From eee61558f44892eebbb483215db23bb760968883 Mon Sep 17 00:00:00 2001
From: Andrei Safronov <safronov at espressif.com>
Date: Thu, 6 Feb 2025 02:26:37 +0300
Subject: [PATCH] [Xtensa] Implement Xtensa Boolean Option.
---
.../Disassembler/XtensaDisassembler.cpp | 16 +++++
.../MCTargetDesc/XtensaMCTargetDesc.cpp | 2 +
llvm/lib/Target/Xtensa/XtensaFeatures.td | 5 ++
llvm/lib/Target/Xtensa/XtensaISelLowering.cpp | 4 ++
llvm/lib/Target/Xtensa/XtensaInstrInfo.td | 70 +++++++++++++++++++
llvm/lib/Target/Xtensa/XtensaRegisterInfo.td | 24 ++++++-
llvm/lib/Target/Xtensa/XtensaSubtarget.h | 5 ++
llvm/test/MC/Disassembler/Xtensa/boolean.txt | 59 ++++++++++++++++
llvm/test/MC/Xtensa/boolean.s | 58 +++++++++++++++
9 files changed, 242 insertions(+), 1 deletion(-)
create mode 100644 llvm/test/MC/Disassembler/Xtensa/boolean.txt
create mode 100644 llvm/test/MC/Xtensa/boolean.s
diff --git a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
index 7ad8a87ed599ae..27d1cc9c8177c3 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/MCTargetDesc/XtensaMCTargetDesc.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp
index 37dee072e5b3dd..adaa9a71a905cf 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 6f24a674ae0ce2..b0cbeb9456796e 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 cdf38a06694796..57f0cbbc36c24c 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 5ef795a0e5287a..e52dcbf1377c51 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 09087edc86712d..920354ff41ba53 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.h b/llvm/lib/Target/Xtensa/XtensaSubtarget.h
index dddc0f7ef605d7..ef83bcc9870277 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 00000000000000..5763db6b4f1660
--- /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 00000000000000..1bd64b82718d36
--- /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,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]
+
+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