Skip to content

Commit 50f918b

Browse files
maciej-czekajgerekon
authored andcommitted
[Xtensa] Add Boolean Extension feature
Boolean Extension support consists of: - v1i1 boolean vector type backed by BR boolean register class - calling convection for boolean variables - boolean instructions implementing logical operators - truncation and zero-extension operations for conversion to scalars - register spill and fill logic
1 parent 9416814 commit 50f918b

13 files changed

+269
-23
lines changed

clang/lib/Basic/Targets/Xtensa.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ bool XtensaTargetInfo::hasFeature(StringRef Feature) const {
7575
return llvm::StringSwitch<bool>(Feature)
7676
.Case("fp", HasFP)
7777
.Case("windowed", HasWindowed)
78+
.Case("bool", HasBoolean)
7879
.Default(false);
7980
}
8081

@@ -84,6 +85,8 @@ bool XtensaTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
8485
for (const auto &Feature : Features) {
8586
if (Feature == "+fp")
8687
HasFP = true;
88+
else if (Feature == "+bool")
89+
HasBoolean = true;
8790
else if (Feature == "+windowed")
8891
HasWindowed = true;
8992
}

clang/lib/Basic/Targets/Xtensa.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class LLVM_LIBRARY_VISIBILITY XtensaTargetInfo : public TargetInfo {
3333
std::string CPU;
3434
bool HasFP = false;
3535
bool HasWindowed = false;
36+
bool HasBoolean = false;
3637

3738
public:
3839
XtensaTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
@@ -49,7 +50,7 @@ class LLVM_LIBRARY_VISIBILITY XtensaTargetInfo : public TargetInfo {
4950
WIntType = UnsignedInt;
5051
UseZeroLengthBitfieldAlignment = true;
5152
MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32;
52-
resetDataLayout("e-m:e-p:32:32-i64:64-i128:128-n32");
53+
resetDataLayout("e-m:e-p:32:32-v1:8:8-i64:64-i128:128-n32");
5354
}
5455

5556
void getTargetDefines(const LangOptions &Opts,

clang/lib/CodeGen/Targets/Xtensa.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,13 @@ ABIArgInfo XtensaABIInfo::classifyArgumentType(QualType Ty,
9898
return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(), Size));
9999
}
100100

101+
// xtbool
102+
if (getTarget().hasFeature("bool") && Size == 1 && Ty->isVectorType()) {
103+
llvm::Type *ResType =
104+
llvm::FixedVectorType::get(llvm::Type::getInt1Ty(getVMContext()), 1);
105+
return ABIArgInfo::getDirect(ResType);
106+
}
107+
101108
// Aggregates which are <= 6*32 will be passed in registers if possible,
102109
// so coerce to integers.
103110
if ((Size <= (MaxNumArgGPRs * 32)) && (!MustUseStack)) {

llvm/lib/Target/Xtensa/XtensaCallingConv.td

+5
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,15 @@
1414
class CCIfAlign<string Align, CCAction A>
1515
: CCIf<!strconcat("ArgFlags.getNonZeroOrigAlign() == ", Align), A>;
1616

17+
class CCIfFeature<string Feature, CCAction A>:
18+
CCIf<!strconcat("State.getMachineFunction().getSubtarget<XtensaSubtarget>().has", Feature, "()"), A>;
19+
1720
//===----------------------------------------------------------------------===//
1821
// Xtensa return value calling convention
1922
//===----------------------------------------------------------------------===//
2023
def RetCC_Xtensa : CallingConv<[
2124
CCIfType<[i1, i8, i16], CCPromoteToType<i32>>,
25+
CCIfFeature<"Boolean",CCIfType<[v1i1], CCAssignToReg<[B0]>>>,
2226
CCIfType<[f32], CCBitConvertToType<i32>>,
2327

2428
//First two return values go in a2, a3, a4, a5
@@ -39,6 +43,7 @@ def CSRWE_Xtensa : CalleeSavedRegs<(add)> {
3943

4044
def RetCCW_Xtensa : CallingConv<[
4145
CCIfType<[i1, i8, i16], CCPromoteToType<i32>>,
46+
CCIfFeature<"Boolean",CCIfType<[v1i1], CCAssignToReg<[B0]>>>,
4247
CCIfType<[f32], CCBitConvertToType<i32>>,
4348

4449
//First two return values go in a10, a11, a12, a13

llvm/lib/Target/Xtensa/XtensaFrameLowering.cpp

+19-2
Original file line numberDiff line numberDiff line change
@@ -375,15 +375,32 @@ void XtensaFrameLowering::processFunctionBeforeFrameFinalized(
375375
MachineFunction &MF, RegScavenger *RS) const {
376376
const XtensaSubtarget &STI = MF.getSubtarget<XtensaSubtarget>();
377377

378+
// Presence of SPILL_* pseudo-instructions requires spill slots
379+
int NeedRegs = 0;
380+
for (const MachineBasicBlock &MBB : MF) {
381+
for (const MachineInstr &MI : MBB) {
382+
unsigned Opcode = MI.getOpcode();
383+
if (Opcode == Xtensa::SPILL_BOOL)
384+
NeedRegs += 1;
385+
386+
if (Opcode == Xtensa::RESTORE_BOOL)
387+
NeedRegs += 3;
388+
}
389+
}
390+
NeedRegs = std::min(16, NeedRegs);
391+
378392
// In WinABI mode add register scavenging slot
379393
// FIXME: It may be posssible to add spill slot by more optimal way
380394
if (STI.isWinABI() &&
381-
(MF.getFrameInfo().estimateStackSize(MF) > STACK_SIZE_THRESHOLD)) {
395+
((MF.getFrameInfo().estimateStackSize(MF) > STACK_SIZE_THRESHOLD) ||
396+
(NeedRegs > 0))) {
382397
MachineFrameInfo &MFI = MF.getFrameInfo();
383398
const TargetRegisterClass &RC = Xtensa::ARRegClass;
384399
const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
385400
unsigned Size = TRI.getSpillSize(RC);
386401
Align Alignment = TRI.getSpillAlign(RC);
387-
RS->addScavengingFrameIndex(MFI.CreateStackObject(Size, Alignment, false));
402+
for (int i = 0; i < NeedRegs; i++)
403+
RS->addScavengingFrameIndex(
404+
MFI.CreateStackObject(Size, Alignment, false));
388405
}
389406
}

llvm/lib/Target/Xtensa/XtensaISelLowering.cpp

+41
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,16 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &tm,
6464
addRegisterClass(MVT::f32, &Xtensa::FPRRegClass);
6565
}
6666

67+
if (Subtarget.hasBoolean()) {
68+
addRegisterClass(MVT::v1i1, &Xtensa::BRRegClass);
69+
setOperationAction(ISD::Constant, MVT::v1i1, Expand);
70+
for (MVT VT : MVT::integer_valuetypes()) {
71+
setLoadExtAction(ISD::SEXTLOAD, VT, MVT::v1i1, Promote);
72+
setLoadExtAction(ISD::ZEXTLOAD, VT, MVT::v1i1, Promote);
73+
setLoadExtAction(ISD::EXTLOAD, VT, MVT::v1i1, Promote);
74+
}
75+
}
76+
6777
// Set up special registers.
6878
setStackPointerRegisterToSaveRestore(Xtensa::SP);
6979

@@ -768,6 +778,11 @@ static bool CC_Xtensa_Custom(unsigned ValNo, MVT ValVT, MVT LocVT,
768778
ISD::ArgFlagsTy ArgFlags, CCState &State) {
769779
static const MCPhysReg IntRegs[] = {Xtensa::A2, Xtensa::A3, Xtensa::A4,
770780
Xtensa::A5, Xtensa::A6, Xtensa::A7};
781+
static const MCPhysReg BoolRegs[] = {
782+
Xtensa::B0, Xtensa::B1, Xtensa::B2, Xtensa::B3,
783+
Xtensa::B4, Xtensa::B5, Xtensa::B6, Xtensa::B7,
784+
Xtensa::B8, Xtensa::B9, Xtensa::B10, Xtensa::B11,
785+
Xtensa::B12, Xtensa::B13, Xtensa::B14, Xtensa::B15};
771786

772787
if (ArgFlags.isByVal()) {
773788
Align ByValAlign = ArgFlags.getNonZeroByValAlign();
@@ -824,6 +839,9 @@ static bool CC_Xtensa_Custom(unsigned ValNo, MVT ValVT, MVT LocVT,
824839
Reg = State.AllocateReg(IntRegs);
825840
State.AllocateReg(IntRegs);
826841
LocVT = MVT::i32;
842+
} else if (ValVT == MVT::v1i1) {
843+
Reg = State.AllocateReg(BoolRegs);
844+
LocVT = ValVT;
827845
} else
828846
llvm_unreachable("Cannot handle this ValVT.");
829847

@@ -918,6 +936,8 @@ SDValue XtensaTargetLowering::LowerFormalArguments(
918936

919937
if (RegVT == MVT::i32) {
920938
RC = &Xtensa::ARRegClass;
939+
} else if (RegVT == MVT::v1i1) {
940+
RC = &Xtensa::BRRegClass;
921941
} else
922942
llvm_unreachable("RegVT not supported by FormalArguments Lowering");
923943

@@ -3403,6 +3423,27 @@ MachineBasicBlock *XtensaTargetLowering::EmitInstrWithCustomInserter(
34033423
}
34043424
return MBB;
34053425
}
3426+
case Xtensa::MOVBA_P: {
3427+
const TargetRegisterClass *AR = getRegClassFor(MVT::i32);
3428+
3429+
Register Dst1 = MRI.createVirtualRegister(AR);
3430+
Register Dst2 = MRI.createVirtualRegister(AR);
3431+
MachineOperand Breg = MI.getOperand(0);
3432+
MachineOperand Src = MI.getOperand(1);
3433+
3434+
/*
3435+
MOVBA_P2 Breg, Dst1, Dest2, Src
3436+
*/
3437+
3438+
BuildMI(*MBB, MI, DL, TII.get(Xtensa::MOVBA_P2), Breg.getReg())
3439+
.addReg(Dst1, RegState::Define | RegState::EarlyClobber)
3440+
.addReg(Dst2, RegState::Define | RegState::EarlyClobber)
3441+
.addReg(Src.getReg());
3442+
3443+
MI.eraseFromParent();
3444+
3445+
return MBB;
3446+
}
34063447
default:
34073448
return EmitDSPInstrWithCustomInserter(MI, MBB, TII, MF, MRI, DL);
34083449
// llvm_unreachable("Unexpected instr type to insert");

llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp

+10-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,13 @@ void XtensaInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
105105
else if (STI.hasSingleFloat() && Xtensa::ARRegClass.contains(SrcReg) &&
106106
Xtensa::FPRRegClass.contains(DestReg))
107107
Opcode = Xtensa::WFR;
108-
else
108+
else if (STI.hasBoolean() && Xtensa::BRRegClass.contains(SrcReg) &&
109+
Xtensa::BRRegClass.contains(DestReg)) {
110+
BuildMI(MBB, MBBI, DL, get(Xtensa::ORB), DestReg)
111+
.addReg(SrcReg, getKillRegState(KillSrc))
112+
.addReg(SrcReg, getKillRegState(KillSrc));
113+
return;
114+
} else
109115
llvm_unreachable("Impossible reg-to-reg copy");
110116

111117
BuildMI(MBB, MBBI, DL, get(Opcode), DestReg)
@@ -148,6 +154,9 @@ void XtensaInstrInfo::getLoadStoreOpcodes(const TargetRegisterClass *RC,
148154
} else if (RC == &Xtensa::FPRRegClass) {
149155
LoadOpcode = Xtensa::LSI;
150156
StoreOpcode = Xtensa::SSI;
157+
} else if (RC == &Xtensa::BRRegClass) {
158+
LoadOpcode = Xtensa::RESTORE_BOOL;
159+
StoreOpcode = Xtensa::SPILL_BOOL;
151160
} else
152161
llvm_unreachable("Unsupported regclass to load or store");
153162
}

llvm/lib/Target/Xtensa/XtensaInstrInfo.td

+66-9
Original file line numberDiff line numberDiff line change
@@ -892,6 +892,11 @@ def ROTW : RRR_Inst<0x00, 0x00, 0x04, (outs), (ins imm8n_7:$imm),
892892
//===----------------------------------------------------------------------===//
893893
// Boolean Instructions
894894
//===----------------------------------------------------------------------===//
895+
class BIN_PAT<SDPatternOperator node, Instruction inst,
896+
ValueType src_vt, ValueType dst_vt = src_vt>
897+
: Pat<(dst_vt (node src_vt:$f1, src_vt:$f2)),
898+
(inst src_vt:$f1, src_vt:$f2)>;
899+
895900

896901
def ALL4 : RRR_Inst<0x00, 0x00, 0x00, (outs BR:$t), (ins BR:$s),
897902
"all4\t$t, $s", []>, Requires<[HasBoolean]> {
@@ -907,6 +912,12 @@ def ANDB : RRR_Inst<0x00, 0x02, 0x00, (outs BR:$r), (ins BR:$s, BR:$t),
907912
"andb\t$r, $s, $t", []>, Requires<[HasBoolean]>;
908913
def ANDBC : RRR_Inst<0x00, 0x02, 0x01, (outs BR:$r), (ins BR:$s, BR:$t),
909914
"andbc\t$r, $s, $t", []>, Requires<[HasBoolean]>;
915+
def ORB : RRR_Inst<0x00, 0x02, 0x02, (outs BR:$r), (ins BR:$s, BR:$t),
916+
"orb\t$r, $s, $t", []>, Requires<[HasBoolean]>;
917+
def ORBC : RRR_Inst<0x00, 0x02, 0x03, (outs BR:$r), (ins BR:$s, BR:$t),
918+
"orbc\t$r, $s, $t", []>, Requires<[HasBoolean]>;
919+
def XORB : RRR_Inst<0x00, 0x02, 0x04, (outs BR:$r), (ins BR:$s, BR:$t),
920+
"xorb\t$r, $s, $t", []>, Requires<[HasBoolean]>;
910921

911922
def ANY4 : RRR_Inst<0x00, 0x00, 0x00, (outs BR:$t), (ins BR:$s),
912923
"any4\t$t, $s", []>, Requires<[HasBoolean]> {
@@ -942,21 +953,67 @@ let isBranch = 1, isTerminator = 1, Predicates = [HasBoolean] in {
942953
}
943954
}
944955

945-
def MOVF : RRR_Inst<0x00, 0x03, 0x0C, (outs AR:$r), (ins AR:$s, BR:$t),
956+
let Constraints = "$dr = $r,@earlyclobber $dr" in {
957+
def MOVF : RRR_Inst<0x00, 0x03, 0x0C, (outs AR:$dr), (ins AR:$r, AR:$s, BR:$t),
946958
"movf\t$r, $s, $t", []>, Requires<[HasBoolean]>;
947-
def MOVT : RRR_Inst<0x00, 0x03, 0x0D, (outs AR:$r), (ins AR:$s, BR:$t),
948-
"movt\t$r, $s, $t", []>, Requires<[HasBoolean]>;
949959

950-
def ORB : RRR_Inst<0x00, 0x02, 0x02, (outs BR:$r), (ins BR:$s, BR:$t),
951-
"orb\t$r, $s, $t", []>, Requires<[HasBoolean]>;
952-
def ORBC : RRR_Inst<0x00, 0x02, 0x03, (outs BR:$r), (ins BR:$s, BR:$t),
953-
"orbc\t$r, $s, $t", []>, Requires<[HasBoolean]>;
954-
def XORB : RRR_Inst<0x00, 0x02, 0x04, (outs BR:$r), (ins BR:$s, BR:$t),
955-
"xorb\t$r, $s, $t", []>, Requires<[HasBoolean]>;
960+
def MOVT : RRR_Inst<0x00, 0x03, 0x0D, (outs AR:$dr), (ins AR:$r, AR:$s, BR:$t),
961+
"movt\t$r, $s, $t", []>, Requires<[HasBoolean]>;
962+
}
956963

957964
def : Pat<(Xtensa_br_t BR:$b, bb:$target), (BT BR:$b, bb:$target)>;
958965
def : Pat<(Xtensa_br_f BR:$b, bb:$target), (BF BR:$b, bb:$target)>;
959966

967+
let Predicates = [HasBoolean] in {
968+
969+
def OR_BR_PAT: BIN_PAT<or,ORB,v1i1>;
970+
def XOR_BR_PAT: BIN_PAT<xor,XORB,v1i1>;
971+
def AND_BR_PAT: BIN_PAT<and,ANDB,v1i1>;
972+
973+
// vselect C T F = C * T + ~C * F
974+
def : Pat<(v1i1 (vselect v1i1:$c, v1i1:$t, v1i1:$f)),
975+
(ORB (ANDB $t, $f), (ANDBC $f, $c))>;
976+
977+
978+
def MOVBA_P2: Pseudo<(outs BR:$r, AR:$x, AR:$y), (ins AR:$s),
979+
"!movba $r, $x, $y, $s", []> {
980+
let Defs = [BREG];
981+
}
982+
983+
def MOVBA_P: Pseudo<(outs BR:$r), (ins AR:$s),
984+
"!movba $r, $s", []> {
985+
let usesCustomInserter = 1;
986+
let Defs = [BREG];
987+
//let Uses = [BREG];
988+
}
989+
990+
def EXTUI_BR_P: Pseudo<(outs AR:$r), (ins AR:$s, BR:$b),
991+
"!extui_br $r, $s, $b", []>;
992+
def SLLI_BR_P: Pseudo<(outs AR:$r), (ins AR:$s, BR:$b),
993+
"!slli_br $r, $s, $b", []>;
994+
995+
def : Pat<(v1i1 (build_vector AR:$a)), (MOVBA_P AR:$a)>;
996+
997+
def : Pat<(i32 (vector_extract (v1i1 BR:$b), (i32 0))),
998+
(EXTUI_BR_P (RSR BREG), BR:$b)>;
999+
1000+
def : Pat<(v1i1 (load addr_ish1:$addr)), (MOVBA_P (L8UI mem8:$addr))>;
1001+
1002+
def : Pat<(store BR:$b, addr_ish1:$addr), (S8I (EXTUI_BR_P (RSR BREG), BR:$b), mem32:$addr)>;
1003+
1004+
def SPILL_BOOL: Pseudo<(outs), (ins BR:$b, mem8:$mem),
1005+
"!spill_bool $b, $mem",[]> {
1006+
let mayStore = 1;
1007+
}
1008+
1009+
def RESTORE_BOOL: Pseudo<(outs BR:$out), (ins mem8:$mem),
1010+
"!restore_bool $out, $mem",[]> {
1011+
let mayLoad = 1;
1012+
let Defs = [BREG];
1013+
}
1014+
}
1015+
1016+
9601017
//===----------------------------------------------------------------------===//
9611018
// Floating-Point Instructions
9621019
//===----------------------------------------------------------------------===//

llvm/lib/Target/Xtensa/XtensaOperators.td

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ def SDT_XtensaSelectCC : SDTypeProfile<1, 5,
2525
SDTCisVT<5, i32>]>;
2626

2727
def SDT_XtensaMOVSP : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisVT<0, i32>]>;
28-
def SDT_XtensaBrBool : SDTypeProfile<0, 2, [SDTCisVT<0, i1>, SDTCisVT<1, OtherVT>]>;
28+
def SDT_XtensaBrBool : SDTypeProfile<0, 2, [SDTCisVT<0, v1i1>, SDTCisVT<1, OtherVT>]>;
2929
def SDT_XtensaBrCCFP : SDTypeProfile<0, 4, [SDTCisVT<0, i32>, SDTCisVT<1, f32>, SDTCisVT<2, f32>, SDTCisVT<3, OtherVT>]>;
30-
def SDT_XtensaCmp : SDTypeProfile<1, 2, [SDTCisVT<0, i1>, SDTCisVT<1, f32>, SDTCisVT<2, f32>]>;
30+
def SDT_XtensaCmp : SDTypeProfile<1, 2, [SDTCisVT<0, v1i1>, SDTCisVT<1, f32>, SDTCisVT<2, f32>]>;
3131
def SDT_XtensaMADD : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>, SDTCisVT<0, f32>]>;
3232
def SDT_XtensaMOVS : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisVT<0, f32>]>;
3333
def SDT_XtensaSelectCCFP : SDTypeProfile<1, 5, [SDTCisSameAs<0, 3>, SDTCisSameAs<1, 2>, SDTCisSameAs<3, 4>, SDTCisVT<5, i32>]>;

0 commit comments

Comments
 (0)