Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
5 changes: 5 additions & 0 deletions llvm/lib/Target/Xtensa/AsmParser/XtensaAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,8 @@ struct XtensaOperand : public MCParsedAsmOperand {
return false;
}

bool isimm7_22() const { return isImm(7, 22); }

/// getStartLoc - Gets location of the first token of this operand
SMLoc getStartLoc() const override { return StartLoc; }
/// getEndLoc - Gets location of the last token of this operand
Expand Down Expand Up @@ -538,6 +540,9 @@ bool XtensaAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
"expected immediate in range [0, 32760], first 3 bits "
"should be zero");
case Match_Invalidimm7_22:
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
"expected immediate in range [7, 22]");
}

report_fatal_error("Unknown match type detected!");
Expand Down
17 changes: 17 additions & 0 deletions llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,16 @@ static DecodeStatus decodeBranchOperand(MCInst &Inst, uint64_t Imm,
return MCDisassembler::Success;
}

static DecodeStatus decodeLoopOperand(MCInst &Inst, uint64_t Imm,
int64_t Address, const void *Decoder) {

assert(isUInt<8>(Imm) && "Invalid immediate");
if (!tryAddingSymbolicOperand(Imm + 4 + Address, true, Address, 0, 3, Inst,
Decoder))
Inst.addOperand(MCOperand::createImm(Imm));
return MCDisassembler::Success;
}

static DecodeStatus decodeL32ROperand(MCInst &Inst, uint64_t Imm,
int64_t Address, const void *Decoder) {

Expand Down Expand Up @@ -326,6 +336,13 @@ static DecodeStatus decodeB4constuOperand(MCInst &Inst, uint64_t Imm,
return MCDisassembler::Success;
}

static DecodeStatus decodeImm7_22Operand(MCInst &Inst, uint64_t Imm,
int64_t Address, const void *Decoder) {
assert(isUInt<4>(Imm) && "Invalid immediate");
Inst.addOperand(MCOperand::createImm(Imm + 7));
return MCDisassembler::Success;
}

static DecodeStatus decodeMem8Operand(MCInst &Inst, uint64_t Imm,
int64_t Address, const void *Decoder) {
assert(isUInt<12>(Imm) && "Invalid immediate");
Expand Down
8 changes: 7 additions & 1 deletion llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ XtensaMCAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
{"fixup_xtensa_l32r_16", 8, 16,
MCFixupKindInfo::FKF_IsPCRel |
MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}};
MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
{"fixup_xtensa_loop_8", 16, 8, MCFixupKindInfo::FKF_IsPCRel}};

if (Kind < FirstTargetFixupKind)
return MCAsmBackend::getFixupKindInfo(Kind);
Expand Down Expand Up @@ -116,6 +117,11 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
if (Value & 0x3)
Ctx.reportError(Fixup.getLoc(), "fixup value must be 4-byte aligned");
return (Value & 0xffffc) >> 2;
case Xtensa::fixup_xtensa_loop_8:
Value -= 4;
if (!isUInt<8>(Value))
Ctx.reportError(Fixup.getLoc(), "loop fixup value out of range");
return (Value & 0xff);
case Xtensa::fixup_xtensa_l32r_16:
unsigned Offset = Fixup.getOffset();
if (Offset & 0x3)
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/Xtensa/MCTargetDesc/XtensaFixupKinds.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ enum FixupKind {
fixup_xtensa_jump_18,
fixup_xtensa_call_18,
fixup_xtensa_l32r_16,
fixup_xtensa_loop_8,
fixup_xtensa_invalid,
LastTargetFixupKind,
NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
Expand Down
26 changes: 26 additions & 0 deletions llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,21 @@ void XtensaInstPrinter::printBranchTarget(const MCInst *MI, int OpNum,
llvm_unreachable("Invalid operand");
}

void XtensaInstPrinter::printLoopTarget(const MCInst *MI, int OpNum,
raw_ostream &OS) {
const MCOperand &MC = MI->getOperand(OpNum);
if (MI->getOperand(OpNum).isImm()) {
int64_t Val = MC.getImm() + 4;
OS << ". ";
Copy link
Member

Choose a reason for hiding this comment

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

If the operand is an address, you'd need OPERAND_PCREL. See https://reviews.llvm.org/D72172

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@MaskRay , thank you very much for comments. I fixed descriptions for several address operands (added OPERAND_PCREL to descriptions), could you PTAL?

if (Val > 0)
OS << '+';
OS << Val;
} else if (MC.isExpr())
MC.getExpr()->print(OS, &MAI, true);
else
llvm_unreachable("Invalid operand");
}

void XtensaInstPrinter::printJumpTarget(const MCInst *MI, int OpNum,
raw_ostream &OS) {
const MCOperand &MC = MI->getOperand(OpNum);
Expand Down Expand Up @@ -404,3 +419,14 @@ void XtensaInstPrinter::printB4constu_AsmOperand(const MCInst *MI, int OpNum,
} else
printOperand(MI, OpNum, O);
}

void XtensaInstPrinter::printImm7_22_AsmOperand(const MCInst *MI, int OpNum,
raw_ostream &O) {
if (MI->getOperand(OpNum).isImm()) {
int64_t Value = MI->getOperand(OpNum).getImm();
assert((Value >= 7 && Value <= 22) &&
"Invalid argument, value must be in range <7,22>");
O << Value;
} else
printOperand(MI, OpNum, O);
}
2 changes: 2 additions & 0 deletions llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class XtensaInstPrinter : public MCInstPrinter {
void printOperand(const MCInst *MI, int OpNum, raw_ostream &O);
void printMemOperand(const MCInst *MI, int OpNUm, raw_ostream &O);
void printBranchTarget(const MCInst *MI, int OpNum, raw_ostream &O);
void printLoopTarget(const MCInst *MI, int OpNum, raw_ostream &O);
void printJumpTarget(const MCInst *MI, int OpNum, raw_ostream &O);
void printCallOperand(const MCInst *MI, int OpNum, raw_ostream &O);
void printL32RTarget(const MCInst *MI, int OpNum, raw_ostream &O);
Expand All @@ -69,6 +70,7 @@ class XtensaInstPrinter : public MCInstPrinter {
void printEntry_Imm12_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
void printB4const_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
void printB4constu_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
void printImm7_22_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
};
} // end namespace llvm

Expand Down
38 changes: 38 additions & 0 deletions llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCCodeEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ class XtensaMCCodeEmitter : public MCCodeEmitter {
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;

uint32_t getLoopTargetEncoding(const MCInst &MI, unsigned int OpNum,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;

uint32_t getCallEncoding(const MCInst &MI, unsigned int OpNum,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
Expand Down Expand Up @@ -134,6 +138,10 @@ class XtensaMCCodeEmitter : public MCCodeEmitter {
uint32_t getB4constuOpValue(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;

uint32_t getImm7_22OpValue(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
};
} // namespace

Expand Down Expand Up @@ -220,6 +228,23 @@ uint32_t XtensaMCCodeEmitter::getBranchTargetEncoding(
}
}

uint32_t
XtensaMCCodeEmitter::getLoopTargetEncoding(const MCInst &MI, unsigned int OpNum,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
const MCOperand &MO = MI.getOperand(OpNum);
if (MO.isImm())
return static_cast<uint32_t>(MO.getImm());

assert((MO.isExpr()) && "Unexpected operand value!");

const MCExpr *Expr = MO.getExpr();

Fixups.push_back(MCFixup::create(
0, Expr, MCFixupKind(Xtensa::fixup_xtensa_loop_8), MI.getLoc()));
return 0;
}

uint32_t
XtensaMCCodeEmitter::getCallEncoding(const MCInst &MI, unsigned int OpNum,
SmallVectorImpl<MCFixup> &Fixups,
Expand Down Expand Up @@ -554,4 +579,17 @@ XtensaMCCodeEmitter::getB4constuOpValue(const MCInst &MI, unsigned OpNo,

return Res;
}

uint32_t
XtensaMCCodeEmitter::getImm7_22OpValue(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
const MCOperand &MO = MI.getOperand(OpNo);
uint32_t res = static_cast<uint32_t>(MO.getImm());

res -= 7;
assert(((res & 0xf) == res) && "Unexpected operand value!");

return res;
}
#include "XtensaGenMCCodeEmitter.inc"
4 changes: 4 additions & 0 deletions llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ bool Xtensa::checkRegister(MCRegister RegNo, const FeatureBitset &FeatureBits) {
switch (RegNo) {
case Xtensa::BREG:
return FeatureBits[Xtensa::FeatureBoolean];
case Xtensa::LBEG:
case Xtensa::LEND:
case Xtensa::LCOUNT:
return FeatureBits[Xtensa::FeatureLoop];
case Xtensa::WINDOWBASE:
case Xtensa::WINDOWSTART:
return FeatureBits[Xtensa::FeatureWindowed];
Expand Down
25 changes: 25 additions & 0 deletions llvm/lib/Target/Xtensa/XtensaFeatures.td
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,28 @@ def FeatureBoolean : SubtargetFeature<"bool", "HasBoolean", "true",
"Enable Xtensa Boolean extension">;
def HasBoolean : Predicate<"Subtarget->hasBoolean()">,
AssemblerPredicate<(all_of FeatureBoolean)>;

def FeatureLoop : SubtargetFeature<"loop", "HasLoop", "true",
"Enable Xtensa Loop extension">;
def HasLoop : Predicate<"Subtarget->hasLoop()">,
AssemblerPredicate<(all_of FeatureLoop)>;

def FeatureSEXT : SubtargetFeature<"sext", "HasSEXT", "true",
"Enable Xtensa Sign Extend option">;
def HasSEXT : Predicate<"Subtarget->hasSEXT()">,
AssemblerPredicate<(all_of FeatureSEXT)>;

def FeatureCLAMPS : SubtargetFeature<"clamps", "HasCLAMPS", "true",
"Enable Xtensa CLAMPS option">;
def HasCLAMPS : Predicate<"Subtarget->hasCLAMPS()">,
AssemblerPredicate<(all_of FeatureCLAMPS)>;

def FeatureNSA : SubtargetFeature<"nsa", "HasNSA", "true",
"Enable Xtensa NSA option">;
def HasNSA : Predicate<"Subtarget->hasNSA()">,
AssemblerPredicate<(all_of FeatureNSA)>;

def FeatureMINMAX : SubtargetFeature<"minmax", "HasMINMAX", "true",
"Enable Xtensa MINMAX option">;
def HasMINMAX : Predicate<"Subtarget->hasMINMAX()">,
AssemblerPredicate<(all_of FeatureMINMAX)>;
7 changes: 5 additions & 2 deletions llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &TM,
setBooleanContents(ZeroOrOneBooleanContent);

setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8, Expand);
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16, Expand);
setOperationAction(ISD::SIGN_EXTEND_INREG, {MVT::i8, MVT::i16},
Subtarget.hasSEXT() ? Legal : Expand);

setOperationAction(ISD::BITCAST, MVT::i32, Expand);
setOperationAction(ISD::BITCAST, MVT::f32, Expand);
Expand Down Expand Up @@ -141,6 +141,9 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i32, Expand);
setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i32, Expand);

setOperationAction({ISD::SMIN, ISD::SMAX, ISD::UMIN, ISD::UMAX}, MVT::i32,
Subtarget.hasMINMAX() ? Legal : Expand);

// Implement custom stack allocations
setOperationAction(ISD::DYNAMIC_STACKALLOC, PtrVT, Custom);
// Implement custom stack save and restore
Expand Down
88 changes: 88 additions & 0 deletions llvm/lib/Target/Xtensa/XtensaInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -868,6 +868,94 @@ let Constraints = "$dr = $r,@earlyclobber $dr" in {
"movt\t$r, $s, $t", []>, Requires<[HasBoolean]>;
}

//===----------------------------------------------------------------------===//
// SEXT Instruction
//===----------------------------------------------------------------------===//

def SEXT : RRR_Inst<0x00, 0x03, 0x02, (outs AR:$r), (ins AR:$s, imm7_22:$imm),
"sext\t$r, $s, $imm", []>, Requires<[HasSEXT]> {
bits<4> imm;

let t = imm;
}

def : Pat<(i32 (sext_inreg AR:$s, i8)), (SEXT AR:$s, (i32 7))>;
def : Pat<(i32 (sext_inreg AR:$s, i16)), (SEXT AR:$s, (i32 15))>;

//===----------------------------------------------------------------------===//
// CLAMPS Instruction
//===----------------------------------------------------------------------===//

def CLAMPS : RRR_Inst<0x00, 0x03, 0x03, (outs AR:$r), (ins AR:$s, imm7_22:$imm),
"clamps\t$r, $s, $imm", []>, Requires<[HasCLAMPS]> {
bits<4> imm;

let t = imm;
}

//===----------------------------------------------------------------------===//
// NSA Instructions
//===----------------------------------------------------------------------===//

def NSA : RRR_Inst<0x00, 0x00, 0x04, (outs AR:$t), (ins AR:$s),
"nsa\t$t, $s", []>, Requires<[HasNSA]> {
let r = 0xE;
}

def NSAU : RRR_Inst<0x00, 0x00, 0x04, (outs AR:$t), (ins AR:$s),
"nsau\t$t, $s",
[(set AR:$t, (ctlz AR:$s))]>, Requires<[HasNSA]> {
let r = 0xF;
}

//===----------------------------------------------------------------------===//
// MINMAX Instructions
//===----------------------------------------------------------------------===//

let Predicates = [HasMINMAX] in {
def MIN : ArithLogic_RRR<0x04, 0x03, "min", smin, 1>;
def MAX : ArithLogic_RRR<0x05, 0x03, "max", smax, 1>;
def MINU : ArithLogic_RRR<0x06, 0x03, "minu", umin, 1>;
def MAXU : ArithLogic_RRR<0x07, 0x03, "maxu", umax, 1>;
}

//===----------------------------------------------------------------------===//
// Loop Instructions
//===----------------------------------------------------------------------===//

def LOOP : RRI8_Inst<0x06, (outs), (ins AR:$s, ltarget:$target),
"loop\t$s, $target", []>, Requires<[HasLoop]> {
bits<8> target;

let r = 0x08;
let t = 0x07;
let imm8 = target;
}

def : InstAlias<"_loop\t$s, $target", (LOOP AR:$s, ltarget:$target)>;

def LOOPGTZ : RRI8_Inst<0x06, (outs), (ins AR:$s, ltarget:$target),
"loopgtz\t$s, $target", []>, Requires<[HasLoop]> {
bits<8> target;

let r = 0x0A;
let t = 0x07;
let imm8 = target;
}

def : InstAlias<"_loopgtz\t$s, $target", (LOOPGTZ AR:$s, ltarget:$target)>;

def LOOPNEZ : RRI8_Inst<0x06, (outs), (ins AR:$s, ltarget:$target),
"loopnez\t$s, $target", []>, Requires<[HasLoop]> {
bits<8> target;

let r = 0x09;
let t = 0x07;
let imm8 = target;
}

def : InstAlias<"_loopnez\t$s, $target", (LOOPNEZ AR:$s, ltarget:$target)>;

//===----------------------------------------------------------------------===//
// DSP Instructions
//===----------------------------------------------------------------------===//
Expand Down
15 changes: 15 additions & 0 deletions llvm/lib/Target/Xtensa/XtensaOperands.td
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,14 @@ def b4constu: Immediate<i32,
let EncoderMethod = "getB4constuOpValue";
let DecoderMethod = "decodeB4constuOperand";
}

// imm7_22 predicate - Immediate in the range [7,22] for sign extend and clamps
def Imm7_22_AsmOperand: ImmAsmOperand<"imm7_22">;
def imm7_22: Immediate<i32, [{ return Imm >= 7 && Imm <= 22; }], "Imm7_22_AsmOperand"> {
let EncoderMethod = "getImm7_22OpValue";
let DecoderMethod = "decodeImm7_22Operand";
}

//===----------------------------------------------------------------------===//
// Memory address operands
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -230,6 +238,13 @@ def jumptarget : Operand<OtherVT> {
let ParserMatchClass = XtensaPCRelTargetAsmOperand;
}

def ltarget : Operand<OtherVT> {
let PrintMethod = "printLoopTarget";
let EncoderMethod = "getLoopTargetEncoding";
let DecoderMethod = "decodeLoopOperand";
let ParserMatchClass = XtensaPCRelTargetAsmOperand;
}

def L32Rtarget : Operand<i32> {
let PrintMethod = "printL32RTarget";
let EncoderMethod = "getL32RTargetEncoding";
Expand Down
Loading