Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 34 additions & 33 deletions llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,39 +145,40 @@ struct DecodeRegister {
};

const DecodeRegister SRDecoderTable[] = {
{Xtensa::LBEG, 0}, {Xtensa::LEND, 1},
{Xtensa::LCOUNT, 2}, {Xtensa::SAR, 3},
{Xtensa::BREG, 4}, {Xtensa::LITBASE, 5},
{Xtensa::ACCLO, 16}, {Xtensa::ACCHI, 17},
{Xtensa::M0, 32}, {Xtensa::M1, 33},
{Xtensa::M2, 34}, {Xtensa::M3, 35},
{Xtensa::WINDOWBASE, 72}, {Xtensa::WINDOWSTART, 73},
{Xtensa::IBREAKENABLE, 96}, {Xtensa::MEMCTL, 97},
{Xtensa::DDR, 104}, {Xtensa::IBREAKA0, 128},
{Xtensa::IBREAKA1, 129}, {Xtensa::DBREAKA0, 144},
{Xtensa::DBREAKA1, 145}, {Xtensa::DBREAKC0, 160},
{Xtensa::DBREAKC1, 161}, {Xtensa::CONFIGID0, 176},
{Xtensa::EPC1, 177}, {Xtensa::EPC2, 178},
{Xtensa::EPC3, 179}, {Xtensa::EPC4, 180},
{Xtensa::EPC5, 181}, {Xtensa::EPC6, 182},
{Xtensa::EPC7, 183}, {Xtensa::DEPC, 192},
{Xtensa::EPS2, 194}, {Xtensa::EPS3, 195},
{Xtensa::EPS4, 196}, {Xtensa::EPS5, 197},
{Xtensa::EPS6, 198}, {Xtensa::EPS7, 199},
{Xtensa::CONFIGID1, 208}, {Xtensa::EXCSAVE1, 209},
{Xtensa::EXCSAVE2, 210}, {Xtensa::EXCSAVE3, 211},
{Xtensa::EXCSAVE4, 212}, {Xtensa::EXCSAVE5, 213},
{Xtensa::EXCSAVE6, 214}, {Xtensa::EXCSAVE7, 215},
{Xtensa::CPENABLE, 224}, {Xtensa::INTERRUPT, 226},
{Xtensa::INTCLEAR, 227}, {Xtensa::INTENABLE, 228},
{Xtensa::PS, 230}, {Xtensa::VECBASE, 231},
{Xtensa::EXCCAUSE, 232}, {Xtensa::DEBUGCAUSE, 233},
{Xtensa::CCOUNT, 234}, {Xtensa::PRID, 235},
{Xtensa::ICOUNT, 236}, {Xtensa::ICOUNTLEVEL, 237},
{Xtensa::EXCVADDR, 238}, {Xtensa::CCOMPARE0, 240},
{Xtensa::CCOMPARE1, 241}, {Xtensa::CCOMPARE2, 242},
{Xtensa::MISC0, 244}, {Xtensa::MISC1, 245},
{Xtensa::MISC2, 246}, {Xtensa::MISC3, 247}};
{Xtensa::LBEG, 0}, {Xtensa::LEND, 1},
{Xtensa::LCOUNT, 2}, {Xtensa::SAR, 3},
{Xtensa::BREG, 4}, {Xtensa::LITBASE, 5},
{Xtensa::SCOMPARE1, 12}, {Xtensa::ACCLO, 16},
{Xtensa::ACCHI, 17}, {Xtensa::M0, 32},
{Xtensa::M1, 33}, {Xtensa::M2, 34},
{Xtensa::M3, 35}, {Xtensa::WINDOWBASE, 72},
{Xtensa::WINDOWSTART, 73}, {Xtensa::IBREAKENABLE, 96},
{Xtensa::MEMCTL, 97}, {Xtensa::ATOMCTL, 99},
{Xtensa::DDR, 104}, {Xtensa::IBREAKA0, 128},
{Xtensa::IBREAKA1, 129}, {Xtensa::DBREAKA0, 144},
{Xtensa::DBREAKA1, 145}, {Xtensa::DBREAKC0, 160},
{Xtensa::DBREAKC1, 161}, {Xtensa::CONFIGID0, 176},
{Xtensa::EPC1, 177}, {Xtensa::EPC2, 178},
{Xtensa::EPC3, 179}, {Xtensa::EPC4, 180},
{Xtensa::EPC5, 181}, {Xtensa::EPC6, 182},
{Xtensa::EPC7, 183}, {Xtensa::DEPC, 192},
{Xtensa::EPS2, 194}, {Xtensa::EPS3, 195},
{Xtensa::EPS4, 196}, {Xtensa::EPS5, 197},
{Xtensa::EPS6, 198}, {Xtensa::EPS7, 199},
{Xtensa::CONFIGID1, 208}, {Xtensa::EXCSAVE1, 209},
{Xtensa::EXCSAVE2, 210}, {Xtensa::EXCSAVE3, 211},
{Xtensa::EXCSAVE4, 212}, {Xtensa::EXCSAVE5, 213},
{Xtensa::EXCSAVE6, 214}, {Xtensa::EXCSAVE7, 215},
{Xtensa::CPENABLE, 224}, {Xtensa::INTERRUPT, 226},
{Xtensa::INTCLEAR, 227}, {Xtensa::INTENABLE, 228},
{Xtensa::PS, 230}, {Xtensa::VECBASE, 231},
{Xtensa::EXCCAUSE, 232}, {Xtensa::DEBUGCAUSE, 233},
{Xtensa::CCOUNT, 234}, {Xtensa::PRID, 235},
{Xtensa::ICOUNT, 236}, {Xtensa::ICOUNTLEVEL, 237},
{Xtensa::EXCVADDR, 238}, {Xtensa::CCOMPARE0, 240},
{Xtensa::CCOMPARE1, 241}, {Xtensa::CCOMPARE2, 242},
{Xtensa::MISC0, 244}, {Xtensa::MISC1, 245},
{Xtensa::MISC2, 246}, {Xtensa::MISC3, 247}};

static DecodeStatus DecodeSRRegisterClass(MCInst &Inst, uint64_t RegNo,
uint64_t Address,
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,9 @@ bool Xtensa::checkRegister(MCRegister RegNo, const FeatureBitset &FeatureBits,
case Xtensa::WINDOWBASE:
case Xtensa::WINDOWSTART:
return FeatureBits[Xtensa::FeatureWindowed];
case Xtensa::ATOMCTL:
case Xtensa::SCOMPARE1:
return FeatureBits[Xtensa::FeatureWindowed];
case Xtensa::NoRegister:
return false;
}
Expand Down
16 changes: 16 additions & 0 deletions llvm/lib/Target/Xtensa/XtensaFeatures.td
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,22 @@ def FeatureDiv32 : SubtargetFeature<"div32", "HasDiv32", "true",
def HasDiv32 : Predicate<"Subtarget->hasDiv32()">,
AssemblerPredicate<(all_of FeatureDiv32)>;

def FeatureS32C1I : SubtargetFeature<"s32c1i", "HasS32C1I", "true",
"Enable Xtensa S32C1I option">;
def HasS32C1I : Predicate<"Subtarget->hasS32C1I()">,
AssemblerPredicate<(all_of FeatureS32C1I)>;

// Assume that lock-free native-width atomics are available, even if the target
// and operating system combination would not usually provide them. The user
// is responsible for providing any necessary __sync implementations. Code
// built with this feature is not ABI-compatible with code built without this
// feature, if atomic variables are exposed across the ABI boundary.
def FeatureForcedAtomics : SubtargetFeature<"forced-atomics", "HasForcedAtomics", "true",
"Assume that lock-free native-width atomics are available">;
def HasForcedAtomics : Predicate<"Subtarget->hasForcedAtomics()">,
AssemblerPredicate<(all_of FeatureForcedAtomics)>;
def HasAtomicLdSt : Predicate<"Subtarget->hasS32C1I() || Subtarget->hasForcedAtomics()">;

def FeatureRegionProtection : SubtargetFeature<"regprotect", "HasRegionProtection", "true",
"Enable Xtensa Region Protection option">;
def HasRegionProtection : Predicate<"Subtarget->hasRegionProtection()">,
Expand Down
31 changes: 31 additions & 0 deletions llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,15 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &TM,
// Floating-point truncation and stores need to be done separately.
setTruncStoreAction(MVT::f64, MVT::f32, Expand);

if (Subtarget.hasS32C1I()) {
setMaxAtomicSizeInBitsSupported(32);
setMinCmpXchgSizeInBits(32);
} else if (Subtarget.hasForcedAtomics()) {
setMaxAtomicSizeInBitsSupported(32);
} else {
setMaxAtomicSizeInBitsSupported(0);
}

// Compute derived properties from the register classes
computeRegisterProperties(STI.getRegisterInfo());
}
Expand Down Expand Up @@ -1548,6 +1557,11 @@ const char *XtensaTargetLowering::getTargetNodeName(unsigned Opcode) const {
return nullptr;
}

TargetLowering::AtomicExpansionKind
XtensaTargetLowering::shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const {
return AtomicExpansionKind::CmpXChg;
}

//===----------------------------------------------------------------------===//
// Custom insertion
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -1696,6 +1710,23 @@ MachineBasicBlock *XtensaTargetLowering::EmitInstrWithCustomInserter(

return MBB;
}
case Xtensa::ATOMIC_CMP_SWAP_32_P: {
MachineOperand &R = MI.getOperand(0);
MachineOperand &Addr = MI.getOperand(1);
MachineOperand &Cmp = MI.getOperand(2);
MachineOperand &Swap = MI.getOperand(3);

BuildMI(*MBB, MI, DL, TII.get(Xtensa::WSR), Xtensa::SCOMPARE1)
.addReg(Cmp.getReg());

BuildMI(*MBB, MI, DL, TII.get(Xtensa::S32C1I), R.getReg())
.addReg(Swap.getReg())
.addReg(Addr.getReg())
.addImm(0);

MI.eraseFromParent();
return MBB;
}
default:
llvm_unreachable("Unexpected instr type to insert");
}
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/Target/Xtensa/XtensaISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,12 @@ class XtensaTargetLowering : public TargetLowering {
const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
SelectionDAG &DAG) const override;

bool shouldInsertFencesForAtomic(const Instruction *I) const override {
return true;
Copy link
Contributor

Choose a reason for hiding this comment

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

Should get test coverage in test/Transforms/AtomicExpand

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added test for AtomicExpand pass.

}

AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *) const override;

bool decomposeMulByConstant(LLVMContext &Context, EVT VT,
SDValue C) const override;

Expand Down
42 changes: 42 additions & 0 deletions llvm/lib/Target/Xtensa/XtensaInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,8 @@ def EXTW : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins),
let hasSideEffects = 1;
}

def : Pat<(atomic_fence timm, timm), (MEMW)>;

//===----------------------------------------------------------------------===//
// Illegal instructions
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -1498,6 +1500,46 @@ def RFI : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins uimm4:$imm),
let t = 0x1;
}

//===----------------------------------------------------------------------===//
// S32C1I
//===----------------------------------------------------------------------===//

let mayStore = 1, mayLoad = 1, Predicates = [HasS32C1I] in {
def S32C1I : RRI8_Inst<0x02, (outs AR:$a), (ins AR:$t, mem32:$addr),
"s32c1i\t$t, $addr", []> {
bits<12> addr;

let r = 0x0e;
let Uses = [SCOMPARE1];
let Constraints = "$a = $t";
let imm8{7-0} = addr{11-4};
let s{3-0} = addr{3-0};
}
}

//===----------------------------------------------------------------------===//
// Atomic patterns
//===----------------------------------------------------------------------===//

// Atomic load/store are available under both +s32c1i and +force-atomics.
// Fences will be inserted for atomic load/stores according to the logic in
// XtensaTargetLowering.
let Predicates = [HasAtomicLdSt] in {
def : Pat<(i32 (atomic_load_8 addr_ish1:$addr)), (L8UI addr_ish1:$addr)>;
def : Pat<(i32 (atomic_load_16 addr_ish2:$addr)), (L16UI addr_ish2:$addr)>;
def : Pat<(i32 (atomic_load_32 addr_ish4:$addr)), (L32I addr_ish4:$addr)>;

def : Pat<(atomic_store_8 AR:$t, addr_ish1:$addr), (S8I AR:$t, addr_ish1:$addr)>;
def : Pat<(atomic_store_16 AR:$t, addr_ish2:$addr), (S16I AR:$t, addr_ish2:$addr)>;
def : Pat<(atomic_store_32 AR:$t, addr_ish4:$addr), (S32I AR:$t, addr_ish4:$addr)>;
}

let usesCustomInserter = 1, Predicates = [HasS32C1I] in {
def ATOMIC_CMP_SWAP_32_P : Pseudo<(outs AR:$dst), (ins AR:$ptr, AR:$cmp, AR:$swap),
"!atomic_cmp_swap_32_p, $dst, $ptr, $cmp, $swap",
[(set AR:$dst, (atomic_cmp_swap_i32 AR:$ptr, AR:$cmp, AR:$swap))]>;
}

//===----------------------------------------------------------------------===//
// DSP Instructions
//===----------------------------------------------------------------------===//
Expand Down
10 changes: 8 additions & 2 deletions llvm/lib/Target/Xtensa/XtensaRegisterInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ def SAR : SRReg<3, "sar", ["SAR","3"]>;
// Boolean Register
def BREG : SRReg<4, "br", ["BR","4"]>;

// Expected data value for S32C1I operation
def SCOMPARE1 : SRReg<12, "scompare1", ["SCOMPARE1", "12"]>;

// Literal base
def LITBASE : SRReg<5, "litbase", ["LITBASE", "5"]>;

Expand All @@ -97,6 +100,9 @@ def IBREAKENABLE : SRReg<96, "ibreakenable", ["IBREAKENABLE", "96"]>;
// Memory Control Register
def MEMCTL : SRReg<97, "memctl", ["MEMCTL", "97"]>;

// Atomic Operation Control
def ATOMCTL : SRReg<99, "atomctl", ["ATOMCTL", "99"]>;

def DDR : SRReg<104, "ddr", ["DDR", "104"]>;

// Instuction break address register 0
Expand Down Expand Up @@ -218,8 +224,8 @@ def MR23 : RegisterClass<"Xtensa", [i32], 32, (add M2, M3)>;
def MR : RegisterClass<"Xtensa", [i32], 32, (add MR01, MR23)>;

def SR : RegisterClass<"Xtensa", [i32], 32, (add
LBEG, LEND, LCOUNT, SAR, BREG, LITBASE, ACCLO, ACCHI, MR,
WINDOWBASE, WINDOWSTART, IBREAKENABLE, MEMCTL, DDR, IBREAKA0, IBREAKA1,
LBEG, LEND, LCOUNT, SAR, BREG, SCOMPARE1, LITBASE, ACCLO, ACCHI, MR,
WINDOWBASE, WINDOWSTART, IBREAKENABLE, MEMCTL, ATOMCTL, DDR, IBREAKA0, IBREAKA1,
DBREAKA0, DBREAKA1, DBREAKC0, DBREAKC1, CONFIGID0, EPC1, EPC2, EPC3, EPC4, EPC5,
EPC6, EPC7, DEPC, EPS2, EPS3, EPS4, EPS5, EPS6, EPS7, CONFIGID1, EXCSAVE1, EXCSAVE2,
EXCSAVE3, EXCSAVE4, EXCSAVE5, EXCSAVE6, EXCSAVE7, CPENABLE, INTERRUPT, INTSET, INTCLEAR, INTENABLE,
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/Xtensa/XtensaSubtarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ class XtensaSubtarget : public XtensaGenSubtargetInfo {
bool hasMul32() const { return HasMul32; }
bool hasMul32High() const { return HasMul32High; }
bool hasDiv32() const { return HasDiv32; }
bool hasS32C1I() const { return HasS32C1I; }
bool hasForcedAtomics() const { return HasForcedAtomics; }
bool hasSingleFloat() const { return HasSingleFloat; }
bool hasRegionProtection() const { return HasRegionProtection; }
bool hasRelocatableVector() const { return HasRelocatableVector; }
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/Target/Xtensa/XtensaTargetMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ class XtensaPassConfig : public TargetPassConfig {
}

bool addInstSelector() override;
void addIRPasses() override;
void addPreEmitPass() override;
};
} // end anonymous namespace
Expand All @@ -116,6 +117,11 @@ bool XtensaPassConfig::addInstSelector() {
return false;
}

void XtensaPassConfig::addIRPasses() {
addPass(createAtomicExpandLegacyPass());
TargetPassConfig::addIRPasses();
}

void XtensaPassConfig::addPreEmitPass() { addPass(&BranchRelaxationPassID); }

TargetPassConfig *XtensaTargetMachine::createPassConfig(PassManagerBase &PM) {
Expand Down
Loading