Skip to content

Commit 438b910

Browse files
authored
[Xtensa] Implement Xtensa Boolean Option. (#126022)
1 parent 210ecfd commit 438b910

File tree

10 files changed

+247
-12
lines changed

10 files changed

+247
-12
lines changed

llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXtensaDisassembler() {
5757
createXtensaDisassembler);
5858
}
5959

60-
const unsigned ARDecoderTable[] = {
60+
const MCPhysReg ARDecoderTable[] = {
6161
Xtensa::A0, Xtensa::SP, Xtensa::A2, Xtensa::A3, Xtensa::A4, Xtensa::A5,
6262
Xtensa::A6, Xtensa::A7, Xtensa::A8, Xtensa::A9, Xtensa::A10, Xtensa::A11,
6363
Xtensa::A12, Xtensa::A13, Xtensa::A14, Xtensa::A15};
@@ -68,12 +68,12 @@ static DecodeStatus DecodeARRegisterClass(MCInst &Inst, uint64_t RegNo,
6868
if (RegNo >= std::size(ARDecoderTable))
6969
return MCDisassembler::Fail;
7070

71-
unsigned Reg = ARDecoderTable[RegNo];
71+
MCPhysReg Reg = ARDecoderTable[RegNo];
7272
Inst.addOperand(MCOperand::createReg(Reg));
7373
return MCDisassembler::Success;
7474
}
7575

76-
const unsigned SRDecoderTable[] = {
76+
const MCPhysReg SRDecoderTable[] = {
7777
Xtensa::SAR, 3, Xtensa::WINDOWBASE, 72, Xtensa::WINDOWSTART, 73};
7878

7979
static DecodeStatus DecodeSRRegisterClass(MCInst &Inst, uint64_t RegNo,
@@ -84,7 +84,7 @@ static DecodeStatus DecodeSRRegisterClass(MCInst &Inst, uint64_t RegNo,
8484

8585
for (unsigned i = 0; i < std::size(SRDecoderTable); i += 2) {
8686
if (SRDecoderTable[i + 1] == RegNo) {
87-
unsigned Reg = SRDecoderTable[i];
87+
MCPhysReg Reg = SRDecoderTable[i];
8888

8989
if (!Xtensa::checkRegister(Reg,
9090
Decoder->getSubtargetInfo().getFeatureBits()))
@@ -98,6 +98,22 @@ static DecodeStatus DecodeSRRegisterClass(MCInst &Inst, uint64_t RegNo,
9898
return MCDisassembler::Fail;
9999
}
100100

101+
const MCPhysReg BRDecoderTable[] = {
102+
Xtensa::B0, Xtensa::B1, Xtensa::B2, Xtensa::B3, Xtensa::B4, Xtensa::B5,
103+
Xtensa::B6, Xtensa::B7, Xtensa::B8, Xtensa::B9, Xtensa::B10, Xtensa::B11,
104+
Xtensa::B12, Xtensa::B13, Xtensa::B14, Xtensa::B15};
105+
106+
static DecodeStatus DecodeBRRegisterClass(MCInst &Inst, uint64_t RegNo,
107+
uint64_t Address,
108+
const void *Decoder) {
109+
if (RegNo >= std::size(BRDecoderTable))
110+
return MCDisassembler::Fail;
111+
112+
MCPhysReg Reg = BRDecoderTable[RegNo];
113+
Inst.addOperand(MCOperand::createReg(Reg));
114+
return MCDisassembler::Success;
115+
}
116+
101117
static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch,
102118
uint64_t Address, uint64_t Offset,
103119
uint64_t InstSize, MCInst &MI,

llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ bool Xtensa::isValidAddrOffsetForOpcode(unsigned Opcode, int64_t Offset) {
7777
// Verify Special Register
7878
bool Xtensa::checkRegister(MCRegister RegNo, const FeatureBitset &FeatureBits) {
7979
switch (RegNo) {
80+
case Xtensa::BREG:
81+
return FeatureBits[Xtensa::FeatureBoolean];
8082
case Xtensa::WINDOWBASE:
8183
case Xtensa::WINDOWSTART:
8284
return FeatureBits[Xtensa::FeatureWindowed];

llvm/lib/Target/Xtensa/XtensaFeatures.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,8 @@ def FeatureWindowed : SubtargetFeature<"windowed", "HasWindowed", "true",
1212
"Enable Xtensa Windowed Register option">;
1313
def HasWindowed : Predicate<"Subtarget->hasWindowed()">,
1414
AssemblerPredicate<(all_of FeatureWindowed)>;
15+
16+
def FeatureBoolean : SubtargetFeature<"bool", "HasBoolean", "true",
17+
"Enable Xtensa Boolean extension">;
18+
def HasBoolean : Predicate<"Subtarget->hasBoolean()">,
19+
AssemblerPredicate<(all_of FeatureBoolean)>;

llvm/lib/Target/Xtensa/XtensaISelLowering.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &TM,
4949
// Set up the register classes.
5050
addRegisterClass(MVT::i32, &Xtensa::ARRegClass);
5151

52+
if (Subtarget.hasBoolean()) {
53+
addRegisterClass(MVT::v1i1, &Xtensa::BRRegClass);
54+
}
55+
5256
// Set up special registers.
5357
setStackPointerRegisterToSaveRestore(Xtensa::SP);
5458

llvm/lib/Target/Xtensa/XtensaInstrInfo.td

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -779,3 +779,73 @@ def ROTW : RRR_Inst<0x00, 0x00, 0x04, (outs), (ins imm8n_7:$imm),
779779
let s = 0x0;
780780
let t = imm{3-0};
781781
}
782+
783+
//===----------------------------------------------------------------------===//
784+
// Boolean Instructions
785+
//===----------------------------------------------------------------------===//
786+
787+
def ALL4 : RRR_Inst<0x00, 0x00, 0x00, (outs BR:$t), (ins BR:$s),
788+
"all4\t$t, $s", []>, Requires<[HasBoolean]> {
789+
let r = 0x9;
790+
}
791+
792+
def ALL8 : RRR_Inst<0x00, 0x00, 0x00, (outs BR:$t), (ins BR:$s),
793+
"all8\t$t, $s", []>, Requires<[HasBoolean]> {
794+
let r = 0xB;
795+
}
796+
797+
def ANDB : RRR_Inst<0x00, 0x02, 0x00, (outs BR:$r), (ins BR:$s, BR:$t),
798+
"andb\t$r, $s, $t", []>, Requires<[HasBoolean]>;
799+
def ANDBC : RRR_Inst<0x00, 0x02, 0x01, (outs BR:$r), (ins BR:$s, BR:$t),
800+
"andbc\t$r, $s, $t", []>, Requires<[HasBoolean]>;
801+
def ORB : RRR_Inst<0x00, 0x02, 0x02, (outs BR:$r), (ins BR:$s, BR:$t),
802+
"orb\t$r, $s, $t", []>, Requires<[HasBoolean]>;
803+
def ORBC : RRR_Inst<0x00, 0x02, 0x03, (outs BR:$r), (ins BR:$s, BR:$t),
804+
"orbc\t$r, $s, $t", []>, Requires<[HasBoolean]>;
805+
def XORB : RRR_Inst<0x00, 0x02, 0x04, (outs BR:$r), (ins BR:$s, BR:$t),
806+
"xorb\t$r, $s, $t", []>, Requires<[HasBoolean]>;
807+
808+
def ANY4 : RRR_Inst<0x00, 0x00, 0x00, (outs BR:$t), (ins BR:$s),
809+
"any4\t$t, $s", []>, Requires<[HasBoolean]> {
810+
let r = 0x8;
811+
}
812+
813+
def ANY8 : RRR_Inst<0x00, 0x00, 0x00, (outs BR:$t), (ins BR:$s),
814+
"any8\t$t, $s", []>, Requires<[HasBoolean]> {
815+
let r = 0xA;
816+
}
817+
818+
let isBranch = 1, isTerminator = 1, Predicates = [HasBoolean] in {
819+
def BT : RRI8_Inst<0x06, (outs), (ins BR:$b, brtarget:$target),
820+
"bt\t$b, $target", []> {
821+
bits<8> target;
822+
bits<4> b;
823+
824+
let r = 0x1;
825+
let s = b;
826+
let t = 0x7;
827+
let imm8 = target;
828+
}
829+
830+
def BF : RRI8_Inst<0x06, (outs), (ins BR:$b, brtarget:$target),
831+
"bf\t$b, $target", []> {
832+
bits<8> target;
833+
bits<4> b;
834+
835+
let r = 0x0;
836+
let s = b;
837+
let t = 0x7;
838+
let imm8 = target;
839+
}
840+
}
841+
842+
def : InstAlias<"_BT\t$b, $target", (BT BR:$b, brtarget:$target)>;
843+
def : InstAlias<"_BF\t$b, $target", (BF BR:$b, brtarget:$target)>;
844+
845+
let Constraints = "$dr = $r,@earlyclobber $dr" in {
846+
def MOVF : RRR_Inst<0x00, 0x03, 0x0C, (outs AR:$dr), (ins AR:$r, AR:$s, BR:$t),
847+
"movf\t$r, $s, $t", []>, Requires<[HasBoolean]>;
848+
849+
def MOVT : RRR_Inst<0x00, 0x03, 0x0D, (outs AR:$dr), (ins AR:$r, AR:$s, BR:$t),
850+
"movt\t$r, $s, $t", []>, Requires<[HasBoolean]>;
851+
}

llvm/lib/Target/Xtensa/XtensaRegisterInfo.td

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ def A15 : ARReg<15, "a15">, DwarfRegNum<[15]>;
6464
def AR : RegisterClass<"Xtensa", [i32], 32, (add
6565
A8, A9, A10, A11, A12, A13, A14, A15,
6666
A7, A6, A5, A4, A3, A2, A0, SP)>;
67+
6768
//===----------------------------------------------------------------------===//
6869
// Special-purpose registers
6970
//===----------------------------------------------------------------------===//
@@ -75,8 +76,29 @@ class SRReg<bits<8> num, string n, list<string> alt = []> : XtensaReg<n> {
7576
// Shift Amount Register
7677
def SAR : SRReg<3, "sar", ["SAR","3"]>;
7778

79+
// Boolean Register
80+
def BREG : SRReg<4, "br", ["BR","4"]>;
81+
7882
// Windowed Register Option registers
7983
def WINDOWBASE : SRReg<72, "windowbase", ["WINDOWBASE", "72"]>;
8084
def WINDOWSTART : SRReg<73, "windowstart", ["WINDOWSTART", "73"]>;
8185

82-
def SR : RegisterClass<"Xtensa", [i32], 32, (add SAR, WINDOWBASE, WINDOWSTART)>;
86+
def SR : RegisterClass<"Xtensa", [i32], 32, (add SAR, BREG,
87+
WINDOWBASE, WINDOWSTART)>;
88+
89+
//===----------------------------------------------------------------------===//
90+
// Boolean registers
91+
//===----------------------------------------------------------------------===//
92+
class BReg<bits<4> num, string n> : XtensaReg<n> {
93+
let HWEncoding{3-0} = num;
94+
}
95+
96+
foreach i = 0-15 in {
97+
def B#i : BReg<i, "b"#i>;
98+
}
99+
100+
// Boolean register class
101+
def BR : RegisterClass<"Xtensa", [v1i1], 8, (add B0, B1,
102+
B2, B3, B4, B5, B6, B7, B8, B9, B10, B11, B12, B13, B14, B15)> {
103+
let Size = 8;
104+
}

llvm/lib/Target/Xtensa/XtensaSubtarget.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@ XtensaSubtarget::initializeSubtargetDependencies(StringRef CPU, StringRef FS) {
3030
CPUName = "generic";
3131
}
3232

33-
HasDensity = false;
34-
3533
// Parse features string.
3634
ParseSubtargetFeatures(CPUName, CPUName, FS);
3735
return *this;

llvm/lib/Target/Xtensa/XtensaSubtarget.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,10 @@ class XtensaSubtarget : public XtensaGenSubtargetInfo {
3636
SelectionDAGTargetInfo TSInfo;
3737
XtensaFrameLowering FrameLowering;
3838

39-
// Enabled Xtensa Density Option
40-
bool HasDensity;
41-
42-
// Enabled Xtensa Windowed Register Option
43-
bool HasWindowed;
39+
// Bool members corresponding to the SubtargetFeatures defined in tablegen
40+
#define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \
41+
bool ATTRIBUTE = DEFAULT;
42+
#include "XtensaGenSubtargetInfo.inc"
4443

4544
XtensaSubtarget &initializeSubtargetDependencies(StringRef CPU, StringRef FS);
4645

@@ -69,6 +68,8 @@ class XtensaSubtarget : public XtensaGenSubtargetInfo {
6968

7069
bool hasWindowed() const { return HasWindowed; }
7170

71+
bool hasBoolean() const { return HasBoolean; }
72+
7273
// Automatically generated by tblgen.
7374
void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
7475
};
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mc_test_checks.py UTC_ARGS: --version 5
2+
# RUN: llvm-mc -triple=xtensa -mattr=+bool -disassemble %s | FileCheck -check-prefixes=CHECK-BOOLEAN %s
3+
# RUN: not llvm-mc -triple=xtensa -disassemble %s 2>&1 | FileCheck --implicit-check-not=warning: -check-prefixes=CHECK-CORE %s
4+
5+
## Verify that binary code is correctly disassembled with
6+
## boolean option enabled. Also verify that dissasembling without
7+
## boolean option generates warnings.
8+
9+
[0x10,0x94,0x00]
10+
# CHECK-BOOLEAN: all4 b1, b4
11+
# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
12+
13+
[0x10,0xb8,0x00]
14+
# CHECK-BOOLEAN: all8 b1, b8
15+
# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
16+
17+
[0x30,0x12,0x02]
18+
# CHECK-BOOLEAN: andb b1, b2, b3
19+
# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
20+
21+
[0x30,0x12,0x12]
22+
# CHECK-BOOLEAN: andbc b1, b2, b3
23+
# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
24+
25+
[0x30,0x12,0x22]
26+
# CHECK-BOOLEAN: orb b1, b2, b3
27+
# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
28+
29+
[0x30,0x12,0x32]
30+
# CHECK-BOOLEAN: orbc b1, b2, b3
31+
# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
32+
33+
[0x30,0x12,0x42]
34+
# CHECK-BOOLEAN: xorb b1, b2, b3
35+
# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
36+
37+
[0x10,0x84,0x00]
38+
# CHECK-BOOLEAN: any4 b1, b4
39+
# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
40+
41+
[0x10,0xa8,0x00]
42+
# CHECK-BOOLEAN: any8 b1, b8
43+
# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
44+
45+
[0x76,0x11,0x10]
46+
# CHECK-BOOLEAN: bt b1, . +20
47+
# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
48+
49+
[0x76,0x00,0x10]
50+
# CHECK-BOOLEAN: bf b0, . +20
51+
# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
52+
53+
[0x10,0x23,0xc3]
54+
# CHECK-BOOLEAN: movf a2, a3, b1
55+
# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
56+
57+
[0x20,0x34,0xd3]
58+
# CHECK-BOOLEAN: movt a3, a4, b2
59+
# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding

llvm/test/MC/Xtensa/boolean.s

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# RUN: llvm-mc %s -triple=xtensa -show-encoding --mattr=+bool \
2+
# RUN: | FileCheck -check-prefixes=CHECK %s
3+
4+
.align 4
5+
// CHECK: .p2align 4
6+
7+
LBL0:
8+
// CHECK: LBL0:
9+
10+
all4 b1, b4
11+
// CHECK: all4 b1, b4 # encoding: [0x10,0x94,0x00]
12+
13+
all8 b1, b8
14+
// CHECK: all8 b1, b8 # encoding: [0x10,0xb8,0x00]
15+
16+
andb b1, b2, b3
17+
// CHECK: andb b1, b2, b3 # encoding: [0x30,0x12,0x02]
18+
19+
andbc b1, b2, b3
20+
// CHECK: andbc b1, b2, b3 # encoding: [0x30,0x12,0x12]
21+
22+
orb b1, b2, b3
23+
// CHECK: orb b1, b2, b3 # encoding: [0x30,0x12,0x22]
24+
25+
orbc b1, b2, b3
26+
// CHECK: orbc b1, b2, b3 # encoding: [0x30,0x12,0x32]
27+
28+
xorb b1, b2, b3
29+
// CHECK: xorb b1, b2, b3 # encoding: [0x30,0x12,0x42]
30+
31+
any4 b1, b4
32+
// CHECK: any4 b1, b4 # encoding: [0x10,0x84,0x00]
33+
34+
any8 b1, b8
35+
// CHECK: any8 b1, b8 # encoding: [0x10,0xa8,0x00]
36+
37+
bt b1, LBL0
38+
// CHECK: bt b1, LBL0 # encoding: [0x76,0x11,A]
39+
// CHECK-NEXT: # fixup A - offset: 0, value: LBL0, kind: fixup_xtensa_branch_8
40+
41+
bf b0, LBL0
42+
// CHECK: bf b0, LBL0 # encoding: [0x76,0x00,A]
43+
// CHECK-NEXT: # fixup A - offset: 0, value: LBL0, kind: fixup_xtensa_branch_8
44+
45+
movf a2, a3, b1
46+
// CHECK: movf a2, a3, b1 # encoding: [0x10,0x23,0xc3]
47+
48+
movt a3, a4, b2
49+
// CHECK: movt a3, a4, b2 # encoding: [0x20,0x34,0xd3]
50+
51+
xsr a3, br
52+
// CHECK: xsr a3, br # encoding: [0x30,0x04,0x61]
53+
54+
xsr.br a3
55+
// CHECK: xsr a3, br # encoding: [0x30,0x04,0x61]
56+
57+
xsr a3, 4
58+
// CHECK: xsr a3, br # encoding: [0x30,0x04,0x61]

0 commit comments

Comments
 (0)