diff options
Diffstat (limited to 'llvm/lib/Target/Xtensa/MCTargetDesc')
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. |
