[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