aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/Xtensa/MCTargetDesc
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/Xtensa/MCTargetDesc')
-rw-r--r--llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp4
-rw-r--r--llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp24
-rw-r--r--llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.h7
-rw-r--r--llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCCodeEmitter.cpp55
-rw-r--r--llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp42
-rw-r--r--llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.h10
6 files changed, 136 insertions, 6 deletions
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp
index a296a22247a5..c1fb46e69e6f 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp
@@ -88,8 +88,10 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
case FK_Data_8:
return Value;
case Xtensa::fixup_xtensa_branch_6: {
+ if (!Value)
+ return 0;
Value -= 4;
- if (!isInt<6>(Value))
+ if (!isUInt<6>(Value))
Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
unsigned Hi2 = (Value >> 4) & 0x3;
unsigned Lo4 = Value & 0xf;
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp
index fe1dc0e2e483..df8a0854f06f 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp
@@ -74,7 +74,7 @@ void XtensaInstPrinter::printInst(const MCInst *MI, uint64_t Address,
printAnnotation(O, Annot);
}
-void XtensaInstPrinter::printRegName(raw_ostream &O, MCRegister Reg) const {
+void XtensaInstPrinter::printRegName(raw_ostream &O, MCRegister Reg) {
O << getRegisterName(Reg);
}
@@ -242,6 +242,28 @@ void XtensaInstPrinter::printImm1_16_AsmOperand(const MCInst *MI, int OpNum,
printOperand(MI, OpNum, O);
}
+void XtensaInstPrinter::printImm1n_15_AsmOperand(const MCInst *MI, int OpNum,
+ raw_ostream &O) {
+ if (MI->getOperand(OpNum).isImm()) {
+ int64_t Value = MI->getOperand(OpNum).getImm();
+ assert((Value >= -1 && (Value != 0) && Value <= 15) &&
+ "Invalid argument, value must be in ranges <-1,-1> or <1,15>");
+ O << Value;
+ } else
+ printOperand(MI, OpNum, O);
+}
+
+void XtensaInstPrinter::printImm32n_95_AsmOperand(const MCInst *MI, int OpNum,
+ raw_ostream &O) {
+ if (MI->getOperand(OpNum).isImm()) {
+ int64_t Value = MI->getOperand(OpNum).getImm();
+ assert((Value >= -32 && Value <= 95) &&
+ "Invalid argument, value must be in ranges <-32,95>");
+ O << Value;
+ } else
+ printOperand(MI, OpNum, O);
+}
+
void XtensaInstPrinter::printOffset8m8_AsmOperand(const MCInst *MI, int OpNum,
raw_ostream &O) {
if (MI->getOperand(OpNum).isImm()) {
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.h b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.h
index 46a35ae6f4e3..e5bc67869e10 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.h
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.h
@@ -28,7 +28,8 @@ public:
: MCInstPrinter(MAI, MII, MRI) {}
// Automatically generated by tblgen.
- std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
+ std::pair<const char *, uint64_t>
+ getMnemonic(const MCInst &MI) const override;
void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O);
static const char *getRegisterName(MCRegister Reg);
@@ -36,7 +37,7 @@ public:
static void printOperand(const MCOperand &MO, raw_ostream &O);
// Override MCInstPrinter.
- void printRegName(raw_ostream &O, MCRegister Reg) const override;
+ void printRegName(raw_ostream &O, MCRegister Reg) override;
void printInst(const MCInst *MI, uint64_t Address, StringRef Annot,
const MCSubtargetInfo &STI, raw_ostream &O) override;
@@ -57,6 +58,8 @@ private:
void printUimm5_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
void printShimm1_31_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
void printImm1_16_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
+ void printImm1n_15_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
+ void printImm32n_95_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
void printOffset8m8_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
void printOffset8m16_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
void printOffset8m32_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCCodeEmitter.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCCodeEmitter.cpp
index 1afdbb38f957..51d4b8a9cc5f 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCCodeEmitter.cpp
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCCodeEmitter.cpp
@@ -103,6 +103,14 @@ private:
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
+ uint32_t getImm1n_15OpValue(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const;
+
+ uint32_t getImm32n_95OpValue(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const;
+
uint32_t getShimm1_31OpValue(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
@@ -188,6 +196,11 @@ uint32_t XtensaMCCodeEmitter::getBranchTargetEncoding(
Fixups.push_back(MCFixup::create(
0, Expr, MCFixupKind(Xtensa::fixup_xtensa_branch_12), MI.getLoc()));
return 0;
+ case Xtensa::BEQZ_N:
+ case Xtensa::BNEZ_N:
+ Fixups.push_back(MCFixup::create(
+ 0, Expr, MCFixupKind(Xtensa::fixup_xtensa_branch_6), MI.getLoc()));
+ return 0;
default:
Fixups.push_back(MCFixup::create(
0, Expr, MCFixupKind(Xtensa::fixup_xtensa_branch_8), MI.getLoc()));
@@ -255,14 +268,24 @@ XtensaMCCodeEmitter::getMemRegEncoding(const MCInst &MI, unsigned OpNo,
break;
case Xtensa::S32I:
case Xtensa::L32I:
+ case Xtensa::S32I_N:
+ case Xtensa::L32I_N:
if (Res & 0x3) {
report_fatal_error("Unexpected operand value!");
}
Res >>= 2;
break;
}
-
- assert((isUInt<8>(Res)) && "Unexpected operand value!");
+
+ switch (MI.getOpcode()) {
+ case Xtensa::S32I_N:
+ case Xtensa::L32I_N:
+ assert((isUInt<4>(Res)) && "Unexpected operand value!");
+ break;
+ default:
+ assert((isUInt<8>(Res)) && "Unexpected operand value!");
+ break;
+ }
uint32_t OffBits = Res << 4;
uint32_t RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
@@ -355,6 +378,34 @@ XtensaMCCodeEmitter::getImm1_16OpValue(const MCInst &MI, unsigned OpNo,
}
uint32_t
+XtensaMCCodeEmitter::getImm1n_15OpValue(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+ const MCOperand &MO = MI.getOperand(OpNo);
+ int32_t Res = static_cast<int32_t>(MO.getImm());
+
+ assert(((Res >= -1) && (Res <= 15) && (Res != 0)) &&
+ "Unexpected operand value!");
+
+ if (Res < 0)
+ Res = 0;
+
+ return Res;
+}
+
+uint32_t
+XtensaMCCodeEmitter::getImm32n_95OpValue(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+ const MCOperand &MO = MI.getOperand(OpNo);
+ int32_t Res = static_cast<int32_t>(MO.getImm());
+
+ assert(((Res >= -32) && (Res <= 95)) && "Unexpected operand value!");
+
+ return Res;
+}
+
+uint32_t
XtensaMCCodeEmitter::getB4constOpValue(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp
index 2653c293dc0c..fc23c2356825 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp
@@ -32,6 +32,48 @@
using namespace llvm;
+bool Xtensa::isValidAddrOffset(int Scale, int64_t OffsetVal) {
+ bool Valid = false;
+
+ switch (Scale) {
+ case 1:
+ Valid = (OffsetVal >= 0 && OffsetVal <= 255);
+ break;
+ case 2:
+ Valid = (OffsetVal >= 0 && OffsetVal <= 510) && ((OffsetVal & 0x1) == 0);
+ break;
+ case 4:
+ Valid = (OffsetVal >= 0 && OffsetVal <= 1020) && ((OffsetVal & 0x3) == 0);
+ break;
+ default:
+ break;
+ }
+ return Valid;
+}
+
+bool Xtensa::isValidAddrOffsetForOpcode(unsigned Opcode, int64_t Offset) {
+ int Scale = 0;
+
+ switch (Opcode) {
+ case Xtensa::L8UI:
+ case Xtensa::S8I:
+ Scale = 1;
+ break;
+ case Xtensa::L16SI:
+ case Xtensa::L16UI:
+ case Xtensa::S16I:
+ Scale = 2;
+ break;
+ case Xtensa::LEA_ADD:
+ return (Offset >= -128 && Offset <= 127);
+ default:
+ // assume that MI is 32-bit load/store operation
+ Scale = 4;
+ break;
+ }
+ return isValidAddrOffset(Scale, Offset);
+}
+
static MCAsmInfo *createXtensaMCAsmInfo(const MCRegisterInfo &MRI,
const Triple &TT,
const MCTargetOptions &Options) {
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.h b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.h
index 0e075be0df07..6be54867d84a 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.h
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.h
@@ -28,6 +28,7 @@ class MCObjectWriter;
class MCRegisterInfo;
class MCSubtargetInfo;
class MCTargetOptions;
+class MachineInstr;
class StringRef;
class Target;
class raw_ostream;
@@ -43,6 +44,15 @@ MCAsmBackend *createXtensaMCAsmBackend(const Target &T,
const MCTargetOptions &Options);
std::unique_ptr<MCObjectTargetWriter>
createXtensaObjectWriter(uint8_t OSABI, bool IsLittleEndian);
+
+namespace Xtensa {
+// Check address offset for load/store instructions.
+// The offset should be multiple of scale.
+bool isValidAddrOffset(int Scale, int64_t OffsetVal);
+
+// Check address offset for load/store instructions.
+bool isValidAddrOffsetForOpcode(unsigned Opcode, int64_t Offset);
+} // namespace Xtensa
} // end namespace llvm
// Defines symbolic names for Xtensa registers.