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
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
20 changes: 19 additions & 1 deletion llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,8 @@ static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch,
static DecodeStatus decodeCallOperand(MCInst &Inst, uint64_t Imm,
int64_t Address, const void *Decoder) {
assert(isUInt<18>(Imm) && "Invalid immediate");
Inst.addOperand(MCOperand::createImm(SignExtend64<20>(Imm << 2)));
Inst.addOperand(
MCOperand::createImm(SignExtend64<20>(Imm << 2) + (Address & 0x3)));
return MCDisassembler::Success;
}

Expand Down Expand Up @@ -200,6 +201,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 +337,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
104 changes: 74 additions & 30 deletions llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,70 +90,103 @@ void XtensaInstPrinter::printMemOperand(const MCInst *MI, int OpNum,
printOperand(MI, OpNum + 1, OS);
}

void XtensaInstPrinter::printBranchTarget(const MCInst *MI, int OpNum,
raw_ostream &OS) {
void XtensaInstPrinter::printBranchTarget(const MCInst *MI, uint64_t Address,
int OpNum, raw_ostream &O) {
const MCOperand &MC = MI->getOperand(OpNum);
if (MI->getOperand(OpNum).isImm()) {
int64_t Val = MC.getImm() + 4;
OS << ". ";
if (Val > 0)
OS << '+';
OS << Val;
printPCRelImm(Address, Val, O);
} else if (MC.isExpr())
MC.getExpr()->print(OS, &MAI);
MC.getExpr()->print(O, &MAI);
else
llvm_unreachable("Invalid operand");
}

void XtensaInstPrinter::printJumpTarget(const MCInst *MI, int OpNum,
raw_ostream &OS) {
void XtensaInstPrinter::printLoopTarget(const MCInst *MI, uint64_t Address,
int OpNum, raw_ostream &O) {
const MCOperand &MC = MI->getOperand(OpNum);
if (MI->getOperand(OpNum).isImm()) {
int64_t Val = MC.getImm() + 4;
printPCRelImm(Address, Val, O);
} else if (MC.isExpr())
MC.getExpr()->print(O, &MAI, true);
else
llvm_unreachable("Invalid operand");
}

void XtensaInstPrinter::printJumpTarget(const MCInst *MI, uint64_t Address,
int OpNum, raw_ostream &O) {
const MCOperand &MC = MI->getOperand(OpNum);
if (MC.isImm()) {
int64_t Val = MC.getImm() + 4;
OS << ". ";
if (Val > 0)
OS << '+';
OS << Val;
printPCRelImm(Address, Val, O);
} else if (MC.isExpr())
MC.getExpr()->print(OS, &MAI);
MC.getExpr()->print(O, &MAI);
else
llvm_unreachable("Invalid operand");
;
}

void XtensaInstPrinter::printCallOperand(const MCInst *MI, int OpNum,
raw_ostream &OS) {
void XtensaInstPrinter::printCallOperand(const MCInst *MI, uint64_t Address,
int OpNum, raw_ostream &O) {
const MCOperand &MC = MI->getOperand(OpNum);
if (MC.isImm()) {
int64_t Val = MC.getImm() + 4;
OS << ". ";
if (Val > 0)
OS << '+';
OS << Val;
if (PrintBranchImmAsAddress) {
uint64_t Target = Address;
Target &= ~0x3;
Target += Val & (~0x3);
O << formatHex(Target);
} else {
O << ". ";
if (Val > 0)
O << '+';
O << Val;
}
} else if (MC.isExpr())
MC.getExpr()->print(OS, &MAI);
MC.getExpr()->print(O, &MAI);
else
llvm_unreachable("Invalid operand");
}

void XtensaInstPrinter::printL32RTarget(const MCInst *MI, int OpNum,
raw_ostream &O) {
void XtensaInstPrinter::printL32RTarget(const MCInst *MI, uint64_t Address,
int OpNum, raw_ostream &O) {
const MCOperand &MC = MI->getOperand(OpNum);
if (MC.isImm()) {
int64_t Value = MI->getOperand(OpNum).getImm();
int64_t InstrOff = Value & 0x3;
Value -= InstrOff;
assert((Value >= -262144 && Value <= -4) &&
"Invalid argument, value must be in ranges [-262144,-4]");
Value += ((InstrOff + 0x3) & 0x4) - InstrOff;
O << ". ";
O << Value;
if (PrintBranchImmAsAddress) {
uint64_t Target = (Address + 0x3) & (~0x3);
Value &= ~0x3;
Target += Value;
O << formatHex(Target);
} else {
int64_t InstrOff = Value & 0x3;
Value -= InstrOff;
assert((Value >= -262144 && Value <= -4) &&
"Invalid argument, value must be in ranges [-262144,-4]");
Value += ((InstrOff + 0x3) & 0x4) - InstrOff;
printPCRelImm(Address, Value, O);
}
} else if (MC.isExpr())
MC.getExpr()->print(O, &MAI);
else
llvm_unreachable("Invalid operand");
}

void XtensaInstPrinter::printPCRelImm(uint64_t Address, int64_t Offset,
raw_ostream &O) {
if (PrintBranchImmAsAddress) {
uint64_t Target = Address + Offset;
Target &= 0xffffffff;
O << formatHex(Target);
} else {
O << ". ";
if (Offset > 0)
O << '+';
O << Offset;
}
}

void XtensaInstPrinter::printImm8_AsmOperand(const MCInst *MI, int OpNum,
raw_ostream &O) {
if (MI->getOperand(OpNum).isImm()) {
Expand Down Expand Up @@ -404,3 +437,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);
}
16 changes: 12 additions & 4 deletions llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,17 @@ class XtensaInstPrinter : public MCInstPrinter {
// Print various types of operand.
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 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);
void printBranchTarget(const MCInst *MI, uint64_t Address, int OpNum,
raw_ostream &O);
void printLoopTarget(const MCInst *MI, uint64_t Address, int OpNum,
raw_ostream &O);
void printJumpTarget(const MCInst *MI, uint64_t Address, int OpNum,
raw_ostream &O);
void printCallOperand(const MCInst *MI, uint64_t Address, int OpNum,
raw_ostream &O);
void printL32RTarget(const MCInst *MI, uint64_t Address, int OpNum,
raw_ostream &O);
void printPCRelImm(uint64_t Address, int64_t Offset, raw_ostream &O);

void printImm8_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
void printImm8_sh8_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
Expand All @@ -69,6 +76,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
Loading
Loading