[llvm] ff25800 - [Xtensa 10/10] Add relaxations and fixups. Add rest part of Xtensa Core Instructions
via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 26 04:39:03 PST 2022
Author: Andrei Safronov
Date: 2022-12-26T13:30:51+01:00
New Revision: ff25800d4ba0b577a44dc918da7a1fb3c29fdb13
URL: https://github.com/llvm/llvm-project/commit/ff25800d4ba0b577a44dc918da7a1fb3c29fdb13
DIFF: https://github.com/llvm/llvm-project/commit/ff25800d4ba0b577a44dc918da7a1fb3c29fdb13.diff
LOG: [Xtensa 10/10] Add relaxations and fixups. Add rest part of Xtensa Core Instructions
Add branch/jump/call/l32r instructions and fixups support. Add R_XTENSA_32/R_XTENSA_SLOT0_OP
relocations in object files generation. Modify tests to support new instructions.
Add tests for relocations and fixups.
Differential Revision: https://reviews.llvm.org/D64836
Added:
llvm/lib/Target/Xtensa/MCTargetDesc/XtensaFixupKinds.h
llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCExpr.cpp
llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCExpr.h
llvm/test/MC/Xtensa/Core/branch.s
llvm/test/MC/Xtensa/Core/call-jump.s
llvm/test/MC/Xtensa/Relocations/fixups-diagnostics.s
llvm/test/MC/Xtensa/Relocations/fixups.s
llvm/test/MC/Xtensa/Relocations/relocations.s
Modified:
llvm/lib/Target/Xtensa/AsmParser/XtensaAsmParser.cpp
llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
llvm/lib/Target/Xtensa/MCTargetDesc/CMakeLists.txt
llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp
llvm/lib/Target/Xtensa/MCTargetDesc/XtensaELFObjectWriter.cpp
llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp
llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.h
llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCCodeEmitter.cpp
llvm/lib/Target/Xtensa/XtensaInstrInfo.td
llvm/lib/Target/Xtensa/XtensaOperands.td
llvm/test/MC/Xtensa/Core/invalid.s
Removed:
################################################################################
diff --git a/llvm/lib/Target/Xtensa/AsmParser/XtensaAsmParser.cpp b/llvm/lib/Target/Xtensa/AsmParser/XtensaAsmParser.cpp
index 363a77536f0f..1bf2f3cbc284 100644
--- a/llvm/lib/Target/Xtensa/AsmParser/XtensaAsmParser.cpp
+++ b/llvm/lib/Target/Xtensa/AsmParser/XtensaAsmParser.cpp
@@ -15,6 +15,7 @@
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
#include "llvm/MC/MCParser/MCTargetAsmParser.h"
@@ -63,6 +64,7 @@ class XtensaAsmParser : public MCTargetAsmParser {
SMLoc &EndLoc) override {
return MatchOperand_NoMatch;
}
+ OperandMatchResultTy parsePCRelTarget(OperandVector &Operands);
public:
enum XtensaMatchResultTy {
@@ -180,6 +182,66 @@ struct XtensaOperand : public MCParsedAsmOperand {
bool isImm1_16() const { return isImm(1, 16); }
+ bool isB4const() const {
+ if (Kind != Immediate)
+ return false;
+ if (auto *CE = dyn_cast<MCConstantExpr>(getImm())) {
+ int64_t Value = CE->getValue();
+ switch (Value) {
+ case -1:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 10:
+ case 12:
+ case 16:
+ case 32:
+ case 64:
+ case 128:
+ case 256:
+ return true;
+ default:
+ return false;
+ }
+ }
+ return false;
+ }
+
+ bool isB4constu() const {
+ if (Kind != Immediate)
+ return false;
+ if (auto *CE = dyn_cast<MCConstantExpr>(getImm())) {
+ int64_t Value = CE->getValue();
+ switch (Value) {
+ case 32768:
+ case 65536:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 10:
+ case 12:
+ case 16:
+ case 32:
+ case 64:
+ case 128:
+ case 256:
+ return true;
+ default:
+ return false;
+ }
+ }
+ return false;
+ }
+
/// 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
@@ -328,6 +390,12 @@ bool XtensaAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
"expected immediate in range [-32768, 32512], first 8 bits "
"should be zero");
+ case Match_InvalidB4const:
+ return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
+ "expected b4const immediate");
+ case Match_InvalidB4constu:
+ return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
+ "expected b4constu immediate");
case Match_InvalidImm12:
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
"expected immediate in range [-2048, 2047]");
@@ -366,6 +434,30 @@ bool XtensaAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
report_fatal_error("Unknown match type detected!");
}
+OperandMatchResultTy
+XtensaAsmParser::parsePCRelTarget(OperandVector &Operands) {
+ MCAsmParser &Parser = getParser();
+ LLVM_DEBUG(dbgs() << "parsePCRelTarget\n");
+
+ SMLoc S = getLexer().getLoc();
+
+ // Expressions are acceptable
+ const MCExpr *Expr = nullptr;
+ if (Parser.parseExpression(Expr)) {
+ // We have no way of knowing if a symbol was consumed so we must ParseFail
+ return MatchOperand_ParseFail;
+ }
+
+ // Currently not support constants
+ if (Expr->getKind() == MCExpr::ExprKind::Constant) {
+ Error(getLoc(), "unknown operand");
+ return MatchOperand_ParseFail;
+ }
+
+ Operands.push_back(XtensaOperand::createImm(Expr, S, getLexer().getLoc()));
+ return MatchOperand_Success;
+}
+
bool XtensaAsmParser::parseRegister(MCRegister &RegNo, SMLoc &StartLoc,
SMLoc &EndLoc) {
const AsmToken &Tok = getParser().getTok();
@@ -486,6 +578,18 @@ XtensaAsmParser::parseOperandWithModifier(OperandVector &Operands) {
/// If operand was parsed, returns false, else true.
bool XtensaAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic,
bool SR) {
+ // Check if the current operand has a custom associated parser, if so, try to
+ // custom parse the operand, or fallback to the general approach.
+ OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
+ if (ResTy == MatchOperand_Success)
+ return false;
+
+ // If there wasn't a custom match, try the generic matcher below. Otherwise,
+ // there was a match, but an error occurred, in which case, just return that
+ // the operand parsing failed.
+ if (ResTy == MatchOperand_ParseFail)
+ return true;
+
// Attempt to parse token as register
if (parseRegister(Operands, true, SR) == MatchOperand_Success)
return false;
diff --git a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
index dfa677789d1a..3e68a955daa4 100644
--- a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
+++ b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
@@ -94,6 +94,59 @@ static DecodeStatus DecodeSRRegisterClass(MCInst &Inst, uint64_t RegNo,
return MCDisassembler::Fail;
}
+static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch,
+ uint64_t Address, uint64_t Offset,
+ uint64_t InstSize, MCInst &MI,
+ const void *Decoder) {
+ const MCDisassembler *Dis = static_cast<const MCDisassembler *>(Decoder);
+ return Dis->tryAddingSymbolicOperand(MI, Value, Address, isBranch, Offset, /*OpSize=*/0,
+ InstSize);
+}
+
+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)));
+ return MCDisassembler::Success;
+}
+
+static DecodeStatus decodeJumpOperand(MCInst &Inst, uint64_t Imm,
+ int64_t Address, const void *Decoder) {
+ assert(isUInt<18>(Imm) && "Invalid immediate");
+ Inst.addOperand(MCOperand::createImm(SignExtend64<18>(Imm)));
+ return MCDisassembler::Success;
+}
+
+static DecodeStatus decodeBranchOperand(MCInst &Inst, uint64_t Imm,
+ int64_t Address, const void *Decoder) {
+ switch (Inst.getOpcode()) {
+ case Xtensa::BEQZ:
+ case Xtensa::BGEZ:
+ case Xtensa::BLTZ:
+ case Xtensa::BNEZ:
+ assert(isUInt<12>(Imm) && "Invalid immediate");
+ if (!tryAddingSymbolicOperand(SignExtend64<12>(Imm) + 4 + Address, true,
+ Address, 0, 3, Inst, Decoder))
+ Inst.addOperand(MCOperand::createImm(SignExtend64<12>(Imm)));
+ break;
+ default:
+ assert(isUInt<8>(Imm) && "Invalid immediate");
+ if (!tryAddingSymbolicOperand(SignExtend64<8>(Imm) + 4 + Address, true,
+ Address, 0, 3, Inst, Decoder))
+ Inst.addOperand(MCOperand::createImm(SignExtend64<8>(Imm)));
+ }
+ return MCDisassembler::Success;
+}
+
+static DecodeStatus decodeL32ROperand(MCInst &Inst, uint64_t Imm,
+ int64_t Address, const void *Decoder) {
+
+ assert(isUInt<16>(Imm) && "Invalid immediate");
+ Inst.addOperand(MCOperand::createImm(
+ SignExtend64<17>((Imm << 2) + 0x40000 + (Address & 0x3))));
+ return MCDisassembler::Success;
+}
+
static DecodeStatus decodeImm8Operand(MCInst &Inst, uint64_t Imm,
int64_t Address, const void *Decoder) {
assert(isUInt<8>(Imm) && "Invalid immediate");
@@ -145,6 +198,27 @@ static DecodeStatus decodeShimm1_31Operand(MCInst &Inst, uint64_t Imm,
return MCDisassembler::Success;
}
+static int64_t TableB4const[16] = {-1, 1, 2, 3, 4, 5, 6, 7,
+ 8, 10, 12, 16, 32, 64, 128, 256};
+static DecodeStatus decodeB4constOperand(MCInst &Inst, uint64_t Imm,
+ int64_t Address, const void *Decoder) {
+ assert(isUInt<4>(Imm) && "Invalid immediate");
+
+ Inst.addOperand(MCOperand::createImm(TableB4const[Imm]));
+ return MCDisassembler::Success;
+}
+
+static int64_t TableB4constu[16] = {32768, 65536, 2, 3, 4, 5, 6, 7,
+ 8, 10, 12, 16, 32, 64, 128, 256};
+static DecodeStatus decodeB4constuOperand(MCInst &Inst, uint64_t Imm,
+ int64_t Address,
+ const void *Decoder) {
+ assert(isUInt<4>(Imm) && "Invalid immediate");
+
+ Inst.addOperand(MCOperand::createImm(TableB4constu[Imm]));
+ return MCDisassembler::Success;
+}
+
static DecodeStatus decodeMem8Operand(MCInst &Inst, uint64_t Imm,
int64_t Address, const void *Decoder) {
assert(isUInt<12>(Imm) && "Invalid immediate");
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/CMakeLists.txt b/llvm/lib/Target/Xtensa/MCTargetDesc/CMakeLists.txt
index 3dad67b1e9a6..6841b44f9d56 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/CMakeLists.txt
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/CMakeLists.txt
@@ -4,6 +4,7 @@ add_llvm_component_library(LLVMXtensaDesc
XtensaInstPrinter.cpp
XtensaMCAsmInfo.cpp
XtensaMCCodeEmitter.cpp
+ XtensaMCExpr.cpp
XtensaMCTargetDesc.cpp
LINK_COMPONENTS
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp
index 7f711993dd5c..61417a2f2455 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp
@@ -8,6 +8,7 @@
//
//===----------------------------------------------------------------------===//
+#include "MCTargetDesc/XtensaFixupKinds.h"
#include "MCTargetDesc/XtensaMCTargetDesc.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAssembler.h"
@@ -31,7 +32,9 @@ class XtensaMCAsmBackend : public MCAsmBackend {
XtensaMCAsmBackend(uint8_t osABI, bool isLE)
: MCAsmBackend(support::little), OSABI(osABI), IsLittleEndian(isLE) {}
- unsigned getNumFixupKinds() const override { return 1; }
+ unsigned getNumFixupKinds() const override {
+ return Xtensa::NumTargetFixupKinds;
+ }
const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override;
void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
const MCValue &Target, MutableArrayRef<char> Data,
@@ -55,13 +58,113 @@ class XtensaMCAsmBackend : public MCAsmBackend {
const MCFixupKindInfo &
XtensaMCAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
- return MCAsmBackend::getFixupKindInfo(MCFixupKind::FK_NONE);
+ const static MCFixupKindInfo Infos[Xtensa::NumTargetFixupKinds] = {
+ // name offset bits flags
+ {"fixup_xtensa_branch_6", 0, 16, MCFixupKindInfo::FKF_IsPCRel},
+ {"fixup_xtensa_branch_8", 16, 8, MCFixupKindInfo::FKF_IsPCRel},
+ {"fixup_xtensa_branch_12", 12, 12, MCFixupKindInfo::FKF_IsPCRel},
+ {"fixup_xtensa_jump_18", 6, 18, MCFixupKindInfo::FKF_IsPCRel},
+ {"fixup_xtensa_call_18", 6, 18,
+ MCFixupKindInfo::FKF_IsPCRel |
+ MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
+ {"fixup_xtensa_l32r_16", 8, 16,
+ MCFixupKindInfo::FKF_IsPCRel |
+ MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}};
+
+ if (Kind < FirstTargetFixupKind)
+ return MCAsmBackend::getFixupKindInfo(Kind);
+ assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
+ "Invalid kind!");
+ return Infos[Kind - FirstTargetFixupKind];
+}
+
+static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
+ MCContext &Ctx) {
+ unsigned Kind = Fixup.getKind();
+ switch (Kind) {
+ default:
+ llvm_unreachable("Unknown fixup kind!");
+ case FK_Data_1:
+ case FK_Data_2:
+ case FK_Data_4:
+ case FK_Data_8:
+ return Value;
+ case Xtensa::fixup_xtensa_branch_6: {
+ Value -= 4;
+ if (!isInt<6>(Value))
+ Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
+ unsigned Hi2 = (Value >> 4) & 0x3;
+ unsigned Lo4 = Value & 0xf;
+ return (Hi2 << 4) | (Lo4 << 12);
+ }
+ case Xtensa::fixup_xtensa_branch_8:
+ Value -= 4;
+ if (!isInt<8>(Value))
+ Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
+ return (Value & 0xff);
+ case Xtensa::fixup_xtensa_branch_12:
+ Value -= 4;
+ if (!isInt<12>(Value))
+ Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
+ return (Value & 0xfff);
+ case Xtensa::fixup_xtensa_jump_18:
+ Value -= 4;
+ if (!isInt<18>(Value))
+ Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
+ return (Value & 0x3ffff);
+ case Xtensa::fixup_xtensa_call_18:
+ Value -= 4;
+ if (!isInt<20>(Value))
+ Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
+ if (Value & 0x3)
+ Ctx.reportError(Fixup.getLoc(), "fixup value must be 4-byte aligned");
+ return (Value & 0xffffc) >> 2;
+ case Xtensa::fixup_xtensa_l32r_16:
+ unsigned Offset = Fixup.getOffset();
+ if (Offset & 0x3)
+ Value -= 4;
+ if (!isInt<18>(Value) && (Value & 0x20000))
+ Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
+ if (Value & 0x3)
+ Ctx.reportError(Fixup.getLoc(), "fixup value must be 4-byte aligned");
+ return (Value & 0x3fffc) >> 2;
+ }
}
+
+static unsigned getSize(unsigned Kind) {
+ switch (Kind) {
+ default:
+ return 3;
+ case MCFixupKind::FK_Data_4:
+ return 4;
+ case Xtensa::fixup_xtensa_branch_6:
+ return 2;
+ }
+}
+
void XtensaMCAsmBackend::applyFixup(const MCAssembler &Asm,
const MCFixup &Fixup, const MCValue &Target,
MutableArrayRef<char> Data, uint64_t Value,
bool IsResolved,
- const MCSubtargetInfo *STI) const {}
+ const MCSubtargetInfo *STI) const {
+ MCContext &Ctx = Asm.getContext();
+ MCFixupKindInfo Info = getFixupKindInfo(Fixup.getKind());
+
+ Value = adjustFixupValue(Fixup, Value, Ctx);
+
+ // Shift the value into position.
+ Value <<= Info.TargetOffset;
+
+ if (!Value)
+ return; // Doesn't change encoding.
+
+ unsigned Offset = Fixup.getOffset();
+ unsigned FullSize = getSize(Fixup.getKind());
+
+ for (unsigned i = 0; i != FullSize; ++i) {
+ Data[Offset + i] |= uint8_t((Value >> (i * 8)) & 0xff);
+ }
+}
bool XtensaMCAsmBackend::mayNeedRelaxation(const MCInst &Inst,
const MCSubtargetInfo &STI) const {
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaELFObjectWriter.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaELFObjectWriter.cpp
index d407e188ab81..7788790ee66c 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaELFObjectWriter.cpp
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaELFObjectWriter.cpp
@@ -46,7 +46,13 @@ XtensaObjectWriter::~XtensaObjectWriter() {}
unsigned XtensaObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
const MCFixup &Fixup,
bool IsPCRel) const {
- report_fatal_error("invalid fixup kind!");
+
+ switch ((unsigned)Fixup.getKind()) {
+ case FK_Data_4:
+ return ELF::R_XTENSA_32;
+ default:
+ return ELF::R_XTENSA_SLOT0_OP;
+ }
}
std::unique_ptr<MCObjectTargetWriter>
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaFixupKinds.h b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaFixupKinds.h
new file mode 100644
index 000000000000..57b114e709a8
--- /dev/null
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaFixupKinds.h
@@ -0,0 +1,32 @@
+//===-- XtensaMCFixups.h - Xtensa-specific fixup entries --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_XTENSA_MCTARGETDESC_XTENSAMCFIXUPS_H
+#define LLVM_LIB_TARGET_XTENSA_MCTARGETDESC_XTENSAMCFIXUPS_H
+
+#include "llvm/MC/MCFixup.h"
+
+namespace llvm {
+namespace Xtensa {
+enum FixupKind {
+ fixup_xtensa_branch_6 = FirstTargetFixupKind,
+ fixup_xtensa_branch_8,
+ fixup_xtensa_branch_12,
+ fixup_xtensa_jump_18,
+ fixup_xtensa_call_18,
+ fixup_xtensa_l32r_16,
+ fixup_xtensa_invalid,
+ LastTargetFixupKind,
+ NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
+};
+} // end namespace Xtensa
+} // end namespace llvm
+
+#endif // LLVM_LIB_TARGET_XTENSA_MCTARGETDESC_XTENSAMCFIXUPS_H
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp
index 47a17a2cd74d..ed802f762fe7 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp
@@ -89,6 +89,70 @@ void XtensaInstPrinter::printMemOperand(const MCInst *MI, int OpNum,
printOperand(MI, OpNum + 1, OS);
}
+void XtensaInstPrinter::printBranchTarget(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 << ". ";
+ 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);
+ if (MC.isImm()) {
+ int64_t Val = MC.getImm() + 4;
+ OS << ". ";
+ if (Val > 0)
+ OS << '+';
+ OS << Val;
+ } else if (MC.isExpr())
+ MC.getExpr()->print(OS, &MAI, true);
+ else
+ llvm_unreachable("Invalid operand");
+ ;
+}
+
+void XtensaInstPrinter::printCallOperand(const MCInst *MI, int OpNum,
+ raw_ostream &OS) {
+ const MCOperand &MC = MI->getOperand(OpNum);
+ if (MC.isImm()) {
+ int64_t Val = MC.getImm() + 4;
+ OS << ". ";
+ if (Val > 0)
+ OS << '+';
+ OS << Val;
+ } else if (MC.isExpr())
+ MC.getExpr()->print(OS, &MAI, true);
+ else
+ llvm_unreachable("Invalid operand");
+}
+
+void XtensaInstPrinter::printL32RTarget(const MCInst *MI, 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;
+ } else if (MC.isExpr())
+ MC.getExpr()->print(O, &MAI, true);
+ else
+ llvm_unreachable("Invalid operand");
+}
+
void XtensaInstPrinter::printImm8_AsmOperand(const MCInst *MI, int OpNum,
raw_ostream &O) {
if (MI->getOperand(OpNum).isImm()) {
@@ -221,3 +285,65 @@ void XtensaInstPrinter::printOffset4m32_AsmOperand(const MCInst *MI, int OpNum,
} else
printOperand(MI, OpNum, O);
}
+
+void XtensaInstPrinter::printB4const_AsmOperand(const MCInst *MI, int OpNum,
+ raw_ostream &O) {
+ if (MI->getOperand(OpNum).isImm()) {
+ int64_t Value = MI->getOperand(OpNum).getImm();
+
+ switch (Value) {
+ case -1:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 10:
+ case 12:
+ case 16:
+ case 32:
+ case 64:
+ case 128:
+ case 256:
+ break;
+ default:
+ assert((0) && "Invalid B4const argument");
+ }
+ O << Value;
+ } else
+ printOperand(MI, OpNum, O);
+}
+
+void XtensaInstPrinter::printB4constu_AsmOperand(const MCInst *MI, int OpNum,
+ raw_ostream &O) {
+ if (MI->getOperand(OpNum).isImm()) {
+ int64_t Value = MI->getOperand(OpNum).getImm();
+
+ switch (Value) {
+ case 32768:
+ case 65536:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 10:
+ case 12:
+ case 16:
+ case 32:
+ case 64:
+ case 128:
+ case 256:
+ break;
+ default:
+ assert((0) && "Invalid B4constu argument");
+ }
+ O << Value;
+ } else
+ printOperand(MI, OpNum, O);
+}
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.h b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.h
index 5d62a9c3011f..ebbfda967f26 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.h
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.h
@@ -44,6 +44,10 @@ 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 printImm8_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
void printImm8_sh8_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
@@ -57,6 +61,8 @@ class XtensaInstPrinter : public MCInstPrinter {
void printOffset8m16_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
void printOffset8m32_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
void printOffset4m32_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);
};
} // end namespace llvm
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCCodeEmitter.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCCodeEmitter.cpp
index c52bfd33ce6b..1ef5b110c927 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCCodeEmitter.cpp
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCCodeEmitter.cpp
@@ -12,6 +12,8 @@
//
//===----------------------------------------------------------------------===//
+#include "MCTargetDesc/XtensaFixupKinds.h"
+#include "MCTargetDesc/XtensaMCExpr.h"
#include "MCTargetDesc/XtensaMCTargetDesc.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
@@ -20,6 +22,10 @@
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
+#define GET_INSTRMAP_INFO
+#include "XtensaGenInstrInfo.inc"
+#undef GET_INSTRMAP_INFO
+
using namespace llvm;
#define DEBUG_TYPE "mccodeemitter"
@@ -53,6 +59,22 @@ class XtensaMCCodeEmitter : public MCCodeEmitter {
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
+ uint32_t getJumpTargetEncoding(const MCInst &MI, unsigned int OpNum,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const;
+
+ uint32_t getBranchTargetEncoding(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;
+
+ uint32_t getL32RTargetEncoding(const MCInst &MI, unsigned OpNum,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const;
+
uint32_t getMemRegEncoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
@@ -84,6 +106,14 @@ class XtensaMCCodeEmitter : public MCCodeEmitter {
uint32_t getShimm1_31OpValue(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
+
+ uint32_t getB4constOpValue(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const;
+
+ uint32_t getB4constuOpValue(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const;
};
} // namespace
@@ -126,6 +156,85 @@ XtensaMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO,
return 0;
}
+uint32_t
+XtensaMCCodeEmitter::getJumpTargetEncoding(const MCInst &MI, unsigned int OpNum,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+ const MCOperand &MO = MI.getOperand(OpNum);
+
+ if (MO.isImm())
+ return MO.getImm();
+
+ const MCExpr *Expr = MO.getExpr();
+ Fixups.push_back(MCFixup::create(
+ 0, Expr, MCFixupKind(Xtensa::fixup_xtensa_jump_18), MI.getLoc()));
+ return 0;
+}
+
+uint32_t XtensaMCCodeEmitter::getBranchTargetEncoding(
+ 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());
+
+ const MCExpr *Expr = MO.getExpr();
+ switch (MI.getOpcode()) {
+ case Xtensa::BEQZ:
+ case Xtensa::BGEZ:
+ case Xtensa::BLTZ:
+ case Xtensa::BNEZ:
+ Fixups.push_back(MCFixup::create(
+ 0, Expr, MCFixupKind(Xtensa::fixup_xtensa_branch_12), MI.getLoc()));
+ return 0;
+ default:
+ Fixups.push_back(MCFixup::create(
+ 0, Expr, MCFixupKind(Xtensa::fixup_xtensa_branch_8), MI.getLoc()));
+ return 0;
+ }
+}
+
+uint32_t
+XtensaMCCodeEmitter::getCallEncoding(const MCInst &MI, unsigned int OpNum,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+ const MCOperand &MO = MI.getOperand(OpNum);
+ if (MO.isImm()) {
+ int32_t Res = MO.getImm();
+ if (Res & 0x3) {
+ llvm_unreachable("Unexpected operand value!");
+ }
+ Res >>= 2;
+ return Res;
+ }
+
+ assert((MO.isExpr()) && "Unexpected operand value!");
+ const MCExpr *Expr = MO.getExpr();
+ Fixups.push_back(MCFixup::create(
+ 0, Expr, MCFixupKind(Xtensa::fixup_xtensa_call_18), MI.getLoc()));
+ return 0;
+}
+
+uint32_t
+XtensaMCCodeEmitter::getL32RTargetEncoding(const MCInst &MI, unsigned OpNum,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+ const MCOperand &MO = MI.getOperand(OpNum);
+ if (MO.isImm()) {
+ int32_t Res = MO.getImm();
+ // We don't check first 2 bits, because in these bits we could store first 2
+ // bits of instruction address
+ Res >>= 2;
+ return Res;
+ }
+
+ assert((MO.isExpr()) && "Unexpected operand value!");
+
+ Fixups.push_back(MCFixup::create(
+ 0, MO.getExpr(), MCFixupKind(Xtensa::fixup_xtensa_l32r_16), MI.getLoc()));
+ return 0;
+}
+
uint32_t
XtensaMCCodeEmitter::getMemRegEncoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
@@ -243,4 +352,102 @@ XtensaMCCodeEmitter::getImm1_16OpValue(const MCInst &MI, unsigned OpNo,
return (Res - 1);
}
+
+uint32_t
+XtensaMCCodeEmitter::getB4constOpValue(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());
+
+ switch (Res) {
+ case 0xffffffff:
+ Res = 0;
+ break;
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ break;
+ case 10:
+ Res = 9;
+ break;
+ case 12:
+ Res = 10;
+ break;
+ case 16:
+ Res = 11;
+ break;
+ case 32:
+ Res = 12;
+ break;
+ case 64:
+ Res = 13;
+ break;
+ case 128:
+ Res = 14;
+ break;
+ case 256:
+ Res = 15;
+ break;
+ default:
+ llvm_unreachable("Unexpected operand value!");
+ }
+
+ return Res;
+}
+
+uint32_t
+XtensaMCCodeEmitter::getB4constuOpValue(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());
+
+ switch (Res) {
+ case 32768:
+ Res = 0;
+ break;
+ case 65536:
+ Res = 1;
+ break;
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ break;
+ case 10:
+ Res = 9;
+ break;
+ case 12:
+ Res = 10;
+ break;
+ case 16:
+ Res = 11;
+ break;
+ case 32:
+ Res = 12;
+ break;
+ case 64:
+ Res = 13;
+ break;
+ case 128:
+ Res = 14;
+ break;
+ case 256:
+ Res = 15;
+ break;
+ default:
+ llvm_unreachable("Unexpected operand value!");
+ }
+
+ return Res;
+}
#include "XtensaGenMCCodeEmitter.inc"
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCExpr.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCExpr.cpp
new file mode 100644
index 000000000000..cafd8b7e2978
--- /dev/null
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCExpr.cpp
@@ -0,0 +1,63 @@
+//===-- XtensaMCExpr.cpp - Xtensa specific MC expression classes ----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the implementation of the assembly expression modifiers
+// accepted by the Xtensa architecture
+//
+//===----------------------------------------------------------------------===//
+
+#include "XtensaMCExpr.h"
+#include "llvm/MC/MCAssembler.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCSymbolELF.h"
+#include "llvm/MC/MCValue.h"
+#include "llvm/Object/ELF.h"
+#include "llvm/Support/ErrorHandling.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "xtensamcexpr"
+
+const XtensaMCExpr *XtensaMCExpr::create(const MCExpr *Expr, VariantKind Kind,
+ MCContext &Ctx) {
+ return new (Ctx) XtensaMCExpr(Expr, Kind);
+}
+
+void XtensaMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {
+ bool HasVariant = getKind() != VK_Xtensa_None;
+ if (HasVariant)
+ OS << '%' << getVariantKindName(getKind()) << '(';
+ Expr->print(OS, MAI);
+ if (HasVariant)
+ OS << ')';
+}
+
+bool XtensaMCExpr::evaluateAsRelocatableImpl(MCValue &Res,
+ const MCAsmLayout *Layout,
+ const MCFixup *Fixup) const {
+ return getSubExpr()->evaluateAsRelocatable(Res, Layout, Fixup);
+}
+
+void XtensaMCExpr::visitUsedExpr(MCStreamer &Streamer) const {
+ Streamer.visitUsedExpr(*getSubExpr());
+}
+
+XtensaMCExpr::VariantKind XtensaMCExpr::getVariantKindForName(StringRef name) {
+ return StringSwitch<XtensaMCExpr::VariantKind>(name).Default(
+ VK_Xtensa_Invalid);
+}
+
+StringRef XtensaMCExpr::getVariantKindName(VariantKind Kind) {
+ switch (Kind) {
+ default:
+ llvm_unreachable("Invalid ELF symbol kind");
+ }
+}
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCExpr.h b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCExpr.h
new file mode 100644
index 000000000000..4cc78fe26b05
--- /dev/null
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCExpr.h
@@ -0,0 +1,58 @@
+//===-- XtensaMCExpr.h - Xtensa specific MC expression classes --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes Xtensa-specific MCExprs
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_XTENSA_MCTARGETDESC_XTENSAMCEXPR_H
+#define LLVM_LIB_TARGET_XTENSA_MCTARGETDESC_XTENSAMCEXPR_H
+
+#include "llvm/MC/MCExpr.h"
+
+namespace llvm {
+
+class StringRef;
+class XtensaMCExpr : public MCTargetExpr {
+public:
+ enum VariantKind { VK_Xtensa_None, VK_Xtensa_Invalid };
+
+private:
+ const MCExpr *Expr;
+ const VariantKind Kind;
+
+ explicit XtensaMCExpr(const MCExpr *Expr, VariantKind Kind)
+ : Expr(Expr), Kind(Kind) {}
+
+public:
+ static const XtensaMCExpr *create(const MCExpr *Expr, VariantKind Kind,
+ MCContext &Ctx);
+
+ VariantKind getKind() const { return Kind; }
+
+ const MCExpr *getSubExpr() const { return Expr; }
+
+ void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override;
+ bool evaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout,
+ const MCFixup *Fixup) const override;
+ void visitUsedExpr(MCStreamer &Streamer) const override;
+ MCFragment *findAssociatedFragment() const override {
+ return getSubExpr()->findAssociatedFragment();
+ }
+
+ void fixELFSymbolsInTLSFixups(MCAssembler &Asm) const override {}
+
+ static VariantKind getVariantKindForName(StringRef name);
+ static StringRef getVariantKindName(VariantKind Kind);
+};
+
+} // end namespace llvm.
+
+#endif // LLVM_LIB_TARGET_XTENSA_MCTARGETDESC_XTENSAMCEXPR_H
diff --git a/llvm/lib/Target/Xtensa/XtensaInstrInfo.td b/llvm/lib/Target/Xtensa/XtensaInstrInfo.td
index c9dd5d32a25e..268a9943d8c1 100644
--- a/llvm/lib/Target/Xtensa/XtensaInstrInfo.td
+++ b/llvm/lib/Target/Xtensa/XtensaInstrInfo.td
@@ -232,6 +232,208 @@ def S8I : Store_II8<0x04, "s8i", truncstorei8, addr_ish1, mem8>;
def S16I : Store_II8<0x05, "s16i", truncstorei16, addr_ish2, mem16>;
def S32I : Store_II8<0x06, "s32i", store, addr_ish4, mem32>;
+def L32R : RI16_Inst<0x01, (outs AR:$t), (ins L32Rtarget:$label),
+ "l32r\t$t, $label", []> {
+ bits<16> label;
+ let imm16 = label;
+}
+
+//===----------------------------------------------------------------------===//
+// Conditional branch instructions
+//===----------------------------------------------------------------------===//
+let isBranch = 1, isTerminator = 1 in {
+ class Branch_RR<bits<4> oper, string instrAsm, CondCode CC>
+ : RRI8_Inst<0x07, (outs),
+ (ins AR:$s, AR:$t, brtarget:$target),
+ instrAsm#"\t$s, $t, $target",
+ [(brcc CC, AR:$s, AR:$t, bb:$target)]> {
+ bits<8> target;
+
+ let r = oper;
+ let imm8 = target;
+ }
+
+ class Branch_RI<bits<4> oper, string instrAsm, CondCode CC>
+ : RRI8_Inst<0x06, (outs),
+ (ins AR:$s, b4const:$imm, brtarget:$target),
+ instrAsm#"\t$s, $imm, $target",
+ [(brcc CC, AR:$s, b4const:$imm, bb:$target)]> {
+ bits<4> imm;
+ bits<8> target;
+
+ let t = oper;
+ let r = imm;
+ let imm8 = target;
+ }
+
+ class Branch_RIU<bits<4> oper, string instrAsm, CondCode CC>
+ : RRI8_Inst<0x06, (outs),
+ (ins AR:$s, b4constu:$imm, brtarget:$target),
+ instrAsm#"\t$s, $imm, $target",
+ [(brcc CC, AR:$s, b4constu:$imm, bb:$target)]> {
+ bits<4> imm;
+ bits<8> target;
+
+ let t = oper;
+ let r = imm;
+ let imm8 = target;
+ }
+
+ class Branch_RZ<bits<2> n, bits<2> m, string instrAsm, CondCode CC>
+ : BRI12_Inst<0x06, n, m, (outs),
+ (ins AR:$s, brtarget:$target),
+ instrAsm#"\t$s, $target",
+ [(brcc CC, AR:$s, (i32 0), bb:$target)]> {
+ bits<12> target;
+
+ let imm12 = target;
+ }
+}
+
+def BEQ : Branch_RR<0x01, "beq", SETEQ>;
+def BNE : Branch_RR<0x09, "bne", SETNE>;
+def BGE : Branch_RR<0x0A, "bge", SETGE>;
+def BLT : Branch_RR<0x02, "blt", SETLT>;
+def BGEU : Branch_RR<0x0B, "bgeu", SETUGE>;
+def BLTU : Branch_RR<0x03, "bltu", SETULT>;
+
+def BEQI : Branch_RI<0x02, "beqi", SETEQ>;
+def BNEI : Branch_RI<0x06, "bnei", SETNE>;
+def BGEI : Branch_RI<0x0E, "bgei", SETGE>;
+def BLTI : Branch_RI<0x0A, "blti", SETLT>;
+def BGEUI : Branch_RIU<0x0F, "bgeui", SETUGE>;
+def BLTUI : Branch_RIU<0x0B, "bltui", SETULT>;
+
+def BEQZ : Branch_RZ<0x01, 0x00, "beqz", SETEQ>;
+def BNEZ : Branch_RZ<0x01, 0x01, "bnez", SETNE>;
+def BGEZ : Branch_RZ<0x01, 0x03, "bgez", SETGE>;
+def BLTZ : Branch_RZ<0x01, 0x02, "bltz", SETLT>;
+
+def BALL : RRI8_Inst<0x07, (outs),
+ (ins AR:$s, AR:$t, brtarget:$target),
+ "ball\t$s, $t, $target", []> {
+ bits<8> target;
+
+ let r = 0x04;
+ let imm8 = target;
+}
+
+def BANY : RRI8_Inst<0x07, (outs),
+ (ins AR:$s, AR:$t, brtarget:$target),
+ "bany\t$s, $t, $target", []> {
+ bits<8> target;
+
+ let r = 0x08;
+ let imm8 = target;
+}
+
+def BBC : RRI8_Inst<0x07, (outs),
+ (ins AR:$s, AR:$t, brtarget:$target),
+ "bbc\t$s, $t, $target", []> {
+ bits<8> target;
+
+ let r = 0x05;
+ let imm8 = target;
+}
+
+def BBS : RRI8_Inst<0x07, (outs),
+ (ins AR:$s, AR:$t, brtarget:$target),
+ "bbs\t$s, $t, $target", []> {
+ bits<8> target;
+
+ let r = 0x0d;
+ let imm8 = target;
+}
+
+def BNALL : RRI8_Inst<0x07, (outs),
+ (ins AR:$s, AR:$t, brtarget:$target),
+ "bnall\t$s, $t, $target", []> {
+ bits<8> target;
+
+ let r = 0x0c;
+ let imm8 = target;
+}
+
+def BNONE : RRI8_Inst<0x07, (outs),
+ (ins AR:$s, AR:$t, brtarget:$target),
+ "bnone\t$s, $t, $target", []> {
+ bits<8> target;
+
+ let r = 0x00;
+ let imm8 = target;
+}
+
+def BBCI : RRI8_Inst<0x07, (outs),
+ (ins AR:$s, uimm5:$imm, brtarget:$target),
+ "bbci\t$s, $imm, $target", []> {
+ bits<8> target;
+ bits<5> imm;
+
+ let r{3-1} = 0x3;
+ let r{0} = imm{4};
+ let t{3-0} = imm{3-0};
+ let imm8 = target;
+}
+
+def BBSI : RRI8_Inst<0x07, (outs),
+ (ins AR:$s, uimm5:$imm, brtarget:$target),
+ "bbsi\t$s, $imm, $target", []> {
+ bits<8> target;
+ bits<5> imm;
+
+ let r{3-1} = 0x7;
+ let r{0} = imm{4};
+ let t{3-0} = imm{3-0};
+ let imm8 = target;
+}
+
+//===----------------------------------------------------------------------===//
+// Call and jump instructions
+//===----------------------------------------------------------------------===//
+
+let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
+ def J : CALL_Inst<0x06, (outs), (ins jumptarget:$offset),
+ "j\t$offset",
+ [(br bb:$offset)]> {
+ let n = 0x0;
+ }
+
+ def JX : CALLX_Inst<0x00, 0x00, 0x00, (outs), (ins AR:$s),
+ "jx\t$s",
+ [(brind AR:$s)]> {
+ let m = 0x2;
+ let n = 0x2;
+ let r = 0;
+ let isIndirectBranch = 1;
+ }
+}
+
+let isCall = 1, Defs = [A0] in {
+ def CALL0 : CALL_Inst<0x05, (outs), (ins pcrel32call:$offset),
+ "call0\t$offset", []> {
+ let n = 0;
+ }
+
+ def CALLX0 : CALLX_Inst<0x00, 0x00, 0x00, (outs), (ins AR:$s),
+ "callx0\t$s", []> {
+ let m = 0x3;
+ let n = 0x0;
+ let r = 0;
+ }
+}
+
+let isReturn = 1, isTerminator = 1,
+ isBarrier = 1, Uses = [A0] in {
+
+ def RET : CALLX_Inst<0x00, 0x00, 0x00, (outs), (ins),
+ "ret", []> {
+ let m = 0x2;
+ let n = 0x0;
+ let s = 0;
+ let r = 0;
+ }
+}
+
//===----------------------------------------------------------------------===//
// Mem barrier instructions
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/Xtensa/XtensaOperands.td b/llvm/lib/Target/Xtensa/XtensaOperands.td
index 3f73f91fe16e..7a1a2e86e8c2 100644
--- a/llvm/lib/Target/Xtensa/XtensaOperands.td
+++ b/llvm/lib/Target/Xtensa/XtensaOperands.td
@@ -102,6 +102,36 @@ def Offset4m32_AsmOperand : ImmAsmOperand<"Offset4m32">;
def offset4m32 : Immediate<i32,
[{ return Imm >= 0 && Imm <= 60 && (Imm & 0x3 == 0); }],
"Offset4m32_AsmOperand">;
+
+// b4const predicate - Branch Immediate 4-bit signed operand
+def B4const_AsmOperand: ImmAsmOperand<"B4const">;
+def b4const: Immediate<i32,
+ [{ switch (Imm) {
+ case -1: case 1: case 2: case 3: case 4:
+ case 5: case 6: case 7: case 8: case 10: case 12:
+ case 16: case 32: case 64: case 128: case 256: return 1;
+ default: return 0;
+ }
+ }],
+ "B4const_AsmOperand"> {
+ let EncoderMethod = "getB4constOpValue";
+ let DecoderMethod = "decodeB4constOperand";
+}
+
+// b4constu predicate - Branch Immediate 4-bit unsigned operand
+def B4constu_AsmOperand: ImmAsmOperand<"B4constu">;
+def b4constu: Immediate<i32,
+ [{ switch (Imm) {
+ case 32768: case 65536: case 2: case 3: case 4:
+ case 5: case 6: case 7: case 8: case 10: case 12:
+ case 16: case 32: case 64: case 128: case 256: return 1;
+ default: return 0;
+ }
+ }],
+ "B4constu_AsmOperand"> {
+ let EncoderMethod = "getB4constuOpValue";
+ let DecoderMethod = "decodeB4constuOperand";
+}
//===----------------------------------------------------------------------===//
// Memory address operands
//===----------------------------------------------------------------------===//
@@ -133,3 +163,41 @@ def mem32n : mem<offset4m32> {
def addr_ish1 : ComplexPattern<iPTR, 2, "selectMemRegAddrISH1", [frameindex]>;
def addr_ish2 : ComplexPattern<iPTR, 2, "selectMemRegAddrISH2", [frameindex]>;
def addr_ish4 : ComplexPattern<iPTR, 2, "selectMemRegAddrISH4", [frameindex]>;
+
+//===----------------------------------------------------------------------===//
+// Symbolic address operands
+//===----------------------------------------------------------------------===//
+def XtensaPCRelTargetAsmOperand : AsmOperandClass {
+ let Name = "PCRelTarget";
+ let ParserMethod = "parsePCRelTarget";
+ let PredicateMethod = "isImm";
+ let RenderMethod = "addImmOperands";
+}
+
+def pcrel32call : Operand<iPTR> {
+ let PrintMethod = "printCallOperand";
+ let EncoderMethod = "getCallEncoding";
+ let DecoderMethod = "decodeCallOperand";
+ let ParserMatchClass = XtensaPCRelTargetAsmOperand;
+}
+
+def brtarget : Operand<OtherVT> {
+ let PrintMethod = "printBranchTarget";
+ let EncoderMethod = "getBranchTargetEncoding";
+ let DecoderMethod = "decodeBranchOperand";
+ let ParserMatchClass = XtensaPCRelTargetAsmOperand;
+}
+
+def jumptarget : Operand<OtherVT> {
+ let PrintMethod = "printJumpTarget";
+ let EncoderMethod = "getJumpTargetEncoding";
+ let DecoderMethod = "decodeJumpOperand";
+ let ParserMatchClass = XtensaPCRelTargetAsmOperand;
+}
+
+def L32Rtarget : Operand<OtherVT> {
+ let PrintMethod = "printL32RTarget";
+ let EncoderMethod = "getL32RTargetEncoding";
+ let DecoderMethod = "decodeL32ROperand";
+ let ParserMatchClass = XtensaPCRelTargetAsmOperand;
+}
diff --git a/llvm/test/MC/Xtensa/Core/branch.s b/llvm/test/MC/Xtensa/Core/branch.s
new file mode 100644
index 000000000000..7e9ba5f71334
--- /dev/null
+++ b/llvm/test/MC/Xtensa/Core/branch.s
@@ -0,0 +1,153 @@
+# RUN: llvm-mc %s -triple=xtensa -show-encoding \
+# RUN: | FileCheck -check-prefixes=CHECK,CHECK-INST %s
+
+
+.align 4
+LBL0:
+
+# Instruction format RRI8
+# CHECK-INST: ball a1, a3, LBL0
+# CHECK: encoding: [0x37,0x41,A]
+ball a1, a3, LBL0
+
+# Instruction format RRI8
+# CHECK-INST: bany a8, a13, LBL0
+# CHECK: encoding: [0xd7,0x88,A]
+bany a8, a13, LBL0
+
+# Instruction format RRI8
+# CHECK-INST: bbc a8, a7, LBL0
+# CHECK: encoding: [0x77,0x58,A]
+bbc a8, a7, LBL0
+
+# Instruction format RRI8
+# CHECK-INST: bbci a3, 16, LBL0
+# CHECK: encoding: [0x07,0x73,A]
+bbci a3, 16, LBL0
+
+# CHECK-INST: bbci a3, 16, LBL0
+# CHECK: encoding: [0x07,0x73,A]
+bbci a3, (16), LBL0
+
+# Instruction format RRI8
+# CHECK-INST: bbs a12, a5, LBL0
+# CHECK: encoding: [0x57,0xdc,A]
+bbs a12, a5, LBL0
+
+# Instruction format RRI8
+# CHECK-INST: bbsi a3, 16, LBL0
+# CHECK: encoding: [0x07,0xf3,A]
+bbsi a3, 16, LBL0
+
+# Instruction format RRI8
+# CHECK-INST: bnall a7, a3, LBL0
+# CHECK: encoding: [0x37,0xc7,A]
+bnall a7, a3, LBL0
+
+# Instruction format RRI8
+# CHECK-INST: bnone a2, a4, LBL0
+# CHECK: encoding: [0x47,0x02,A]
+bnone a2, a4, LBL0
+
+# Instruction format RRI8
+# CHECK-INST: beq a1, a2, LBL0
+# CHECK: encoding: [0x27,0x11,A]
+beq a1, a2, LBL0
+
+# CHECK-INST: beq a11, a5, LBL0
+# CHECK: encoding: [0x57,0x1b,A]
+beq a11, a5, LBL0
+
+# Instruction format BRI8
+# CHECK-INST: beqi a1, 256, LBL0
+# CHECK: encoding: [0x26,0xf1,A]
+beqi a1, 256, LBL0
+
+# CHECK-INST: beqi a11, -1, LBL0
+# CHECK: encoding: [0x26,0x0b,A]
+beqi a11, -1, LBL0
+
+# Instruction format BRI12
+# CHECK-INST: beqz a8, LBL0
+# CHECK: encoding: [0x16,0bAAAA1000,A]
+beqz a8, LBL0
+
+# Instruction format RRI8
+# CHECK-INST: bge a14, a2, LBL0
+# CHECK: encoding: [0x27,0xae,A]
+bge a14, a2, LBL0
+
+# Instruction format BRI8
+# CHECK-INST: bgei a11, -1, LBL0
+# CHECK: encoding: [0xe6,0x0b,A]
+bgei a11, -1, LBL0
+
+# CHECK-INST: bgei a11, 128, LBL0
+# CHECK: encoding: [0xe6,0xeb,A]
+bgei a11, 128, LBL0
+
+# Instruction format RRI8
+# CHECK-INST: bgeu a14, a2, LBL0
+# CHECK: encoding: [0x27,0xbe,A]
+bgeu a14, a2, LBL0
+
+# CHECK-INST: bgeu a13, a1, LBL0
+# CHECK: encoding: [0x17,0xbd,A]
+bgeu a13, a1, LBL0
+
+# Instruction format BRI8
+# CHECK-INST: bgeui a9, 32768, LBL0
+# CHECK: encoding: [0xf6,0x09,A]
+bgeui a9, 32768, LBL0
+
+# CHECK-INST: bgeui a7, 65536, LBL0
+# CHECK: encoding: [0xf6,0x17,A]
+bgeui a7, 65536, LBL0
+
+# CHECK-INST: bgeui a7, 64, LBL0
+# CHECK: encoding: [0xf6,0xd7,A]
+bgeui a7, 64, LBL0
+
+# Instruction format BRI12
+# CHECK-INST: bgez a8, LBL0
+# CHECK: encoding: [0xd6,0bAAAA1000,A]
+bgez a8, LBL0
+
+# Instruction format RRI8
+# CHECK-INST: blt a14, a2, LBL0
+# CHECK: encoding: [0x27,0x2e,A]
+blt a14, a2, LBL0
+
+# Instruction format BRI8
+# CHECK-INST: blti a12, -1, LBL0
+# CHECK: encoding: [0xa6,0x0c,A]
+blti a12, -1, LBL0
+
+# CHECK-INST: blti a0, 32, LBL0
+# CHECK: encoding: [0xa6,0xc0,A]
+blti a0, 32, LBL0
+
+# Instruction format BRI8
+# CHECK-INST: bltui a7, 16, LBL0
+# CHECK: encoding: [0xb6,0xb7,A]
+bltui a7, 16, LBL0
+
+# Instruction format BRI12
+# CHECK-INST: bltz a6, LBL0
+# CHECK: encoding: [0x96,0bAAAA0110,A]
+bltz a6, LBL0
+
+# Instruction format RRI8
+# CHECK-INST: bne a3, a4, LBL0
+# CHECK: encoding: [0x47,0x93,A]
+bne a3, a4, LBL0
+
+# Instruction format BRI8
+# CHECK-INST: bnei a5, 12, LBL0
+# CHECK: encoding: [0x66,0xa5,A]
+bnei a5, 12, LBL0
+
+# Instruction format BRI12
+# CHECK-INST: bnez a5, LBL0
+# CHECK: encoding: [0x56,0bAAAA0101,A]
+bnez a5, LBL0
diff --git a/llvm/test/MC/Xtensa/Core/call-jump.s b/llvm/test/MC/Xtensa/Core/call-jump.s
new file mode 100644
index 000000000000..2e47a0eb4748
--- /dev/null
+++ b/llvm/test/MC/Xtensa/Core/call-jump.s
@@ -0,0 +1,31 @@
+# RUN: llvm-mc %s -triple=xtensa -show-encoding \
+# RUN: | FileCheck -check-prefixes=CHECK,CHECK-INST %s
+
+
+.align 4
+LBL0:
+
+# Instruction format CALL
+# CHECK-INST: call0 LBL0
+# CHECK: encoding: [0bAA000101,A,A]
+call0 LBL0
+
+# Instruction format CALLX
+# CHECK-INST: callx0 a1
+# CHECK: encoding: [0xc0,0x01,0x00]
+callx0 a1
+
+# Instruction format CALL
+# CHECK-INST: j LBL0
+# CHECK: encoding: [0bAA000110,A,A]
+j LBL0
+
+# Instruction format CALLX
+# CHECK-INST: jx a2
+# CHECK: encoding: [0xa0,0x02,0x00]
+jx a2
+
+# Instruction format CALLX
+# CHECK-INST: ret
+# CHECK: encoding: [0x80,0x00,0x00]
+ret
diff --git a/llvm/test/MC/Xtensa/Core/invalid.s b/llvm/test/MC/Xtensa/Core/invalid.s
index 910e7a36ae4b..d3d8fba8169a 100644
--- a/llvm/test/MC/Xtensa/Core/invalid.s
+++ b/llvm/test/MC/Xtensa/Core/invalid.s
@@ -48,6 +48,14 @@ l16si a1, a2, 512
l32i a1, a2, 1024
# CHECK: :[[#@LINE-1]]:14: error: expected immediate in range [0, 1020], first 2 bits should be zero
+# b4const
+beqi a1, 257, LBL0
+# CHECK: :[[#@LINE-1]]:10: error: expected b4const immediate
+
+# b4constu
+bgeui a9, 32000, LBL0
+# CHECK: :[[#@LINE-1]]:11: error: expected b4constu immediate
+
# Invalid number of operands
addi a1, a2
# CHECK: :[[#@LINE-1]]:1: error: too few operands for instruction
@@ -85,6 +93,17 @@ wsr.uregister a2
wsr a2, uregister
# CHECK: :[[#@LINE-1]]:9: error: invalid operand for instruction
+# Instruction format BRI12
+beqz b1, LBL0
+# CHECK: :[[#@LINE-1]]:6: error: invalid operand for instruction
+# Instruction format BRI8
+bltui r7, 16, LBL0
+# CHECK: :[[#@LINE-1]]:7: error: invalid operand for instruction
+
+# Instruction format CALLX
+callx0 r10
+# CHECK: :[[#@LINE-1]]:8: error: invalid operand for instruction
+
# Check invalid operands order for
diff erent formats
# Instruction format RRI8
addi a1, 10, a2
@@ -93,3 +112,13 @@ addi a1, 10, a2
# Instruction format RSR
wsr sar, a2
# CHECK: :[[#@LINE-1]]:5: error: invalid operand for instruction
+
+# Instruction format BRI12
+beqz LBL0, a2
+# CHECK: :[[#@LINE-1]]:6: error: invalid operand for instruction
+
+# Instruction format BRI8
+bltui 16, a7, LBL0
+# CHECK: :[[#@LINE-1]]:7: error: invalid operand for instruction
+bltui a7, LBL0, 16
+# CHECK: :[[#@LINE-1]]:19: error: unknown operand
diff --git a/llvm/test/MC/Xtensa/Relocations/fixups-diagnostics.s b/llvm/test/MC/Xtensa/Relocations/fixups-diagnostics.s
new file mode 100644
index 000000000000..e0eac900552c
--- /dev/null
+++ b/llvm/test/MC/Xtensa/Relocations/fixups-diagnostics.s
@@ -0,0 +1,14 @@
+# RUN: not llvm-mc -triple xtensa -filetype obj < %s -o /dev/null 2>&1 | FileCheck %s
+
+ .align 4
+
+ beq a0, a1, LBL1 # CHECK: :[[@LINE]]:3: error: fixup value out of range
+LBL0:
+ beqz a0, LBL2 # CHECK: :[[@LINE]]:3: error: fixup value out of range
+
+ call0 LBL0 # CHECK: :[[@LINE]]:3: error: fixup value must be 4-byte aligned
+
+ .space 1<<8
+LBL1:
+ .space 1<<12
+LBL2:
diff --git a/llvm/test/MC/Xtensa/Relocations/fixups.s b/llvm/test/MC/Xtensa/Relocations/fixups.s
new file mode 100644
index 000000000000..cd76f2a23322
--- /dev/null
+++ b/llvm/test/MC/Xtensa/Relocations/fixups.s
@@ -0,0 +1,54 @@
+# RUN: llvm-mc -triple xtensa < %s -show-encoding \
+# RUN: | FileCheck -check-prefix=CHECK-FIXUP %s
+# RUN: llvm-mc -filetype=obj -triple xtensa < %s \
+# RUN: | llvm-objdump -d - | FileCheck -check-prefix=CHECK-INSTR %s
+
+
+# Checks that fixups that can be resolved within the same object file are
+# applied correctly
+.align 4
+LBL0:
+
+.fill 12
+
+beq a0, a1, LBL0
+# CHECK-FIXUP: fixup A - offset: 0, value: LBL0, kind: fixup_xtensa_branch_8
+# CHECK-INSTR: beq a0, a1, . -12
+
+beq a0, a1, LBL1
+# CHECK-FIXUP: fixup A - offset: 0, value: LBL1, kind: fixup_xtensa_branch_8
+# CHECK-INSTR: beq a0, a1, . +24
+
+beqz a2, LBL0
+# CHECK-FIXUP: fixup A - offset: 0, value: LBL0, kind: fixup_xtensa_branch_12
+# CHECK-INSTR: beqz a2, . -18
+
+beqz a2, LBL1
+# CHECK-FIXUP: fixup A - offset: 0, value: LBL1, kind: fixup_xtensa_branch_12
+# CHECK-INSTR: beqz a2, . +18
+
+call0 LBL0
+# CHECK-FIXUP: fixup A - offset: 0, value: LBL0, kind: fixup_xtensa_call_18
+# CHECK-INSTR: call0 . -24
+
+call0 LBL2
+# CHECK-FIXUP: fixup A - offset: 0, value: LBL2, kind: fixup_xtensa_call_18
+# CHECK-INSTR: call0 . +2056
+
+j LBL0
+# CHECK-FIXUP: fixup A - offset: 0, value: LBL0, kind: fixup_xtensa_jump_18
+# CHECK-INSTR: j . -30
+
+j LBL2
+# CHECK-FIXUP: fixup A - offset: 0, value: LBL2, kind: fixup_xtensa_jump_18
+# CHECK-INSTR: j . +2047
+
+l32r a1, LBL0
+# CHECK-FIXUP: fixup A - offset: 0, value: LBL0, kind: fixup_xtensa_l32r_16
+# CHECK-INSTR: l32r a1, . -36
+
+LBL1:
+
+.fill 2041
+
+LBL2:
diff --git a/llvm/test/MC/Xtensa/Relocations/relocations.s b/llvm/test/MC/Xtensa/Relocations/relocations.s
new file mode 100644
index 000000000000..19c2e1635250
--- /dev/null
+++ b/llvm/test/MC/Xtensa/Relocations/relocations.s
@@ -0,0 +1,177 @@
+# RUN: llvm-mc -triple xtensa < %s -show-encoding \
+# RUN: | FileCheck -check-prefix=INSTR -check-prefix=FIXUP %s
+# RUN: llvm-mc -filetype=obj -triple xtensa < %s \
+# RUN: | llvm-readobj -r - | FileCheck -check-prefix=RELOC %s
+
+# Check prefixes:
+# RELOC - Check the relocation in the object.
+# FIXUP - Check the fixup on the instruction.
+# INSTR - Check the instruction is handled properly by the ASMPrinter
+
+.long func
+# RELOC: R_XTENSA_32 func
+
+ball a1, a3, func
+# RELOC: R_XTENSA_SLOT0_OP
+# INST: ball a1, a3, func
+# FIXUP: fixup A - offset: 0, value: func, kind: fixup_xtensa_branch_8
+
+bany a8, a13, func
+# RELOC: R_XTENSA_SLOT0_OP
+# INST: bany a8, a13, func
+# FIXUP: fixup A - offset: 0, value: func, kind: fixup_xtensa_branch_8
+
+bbc a8, a7, func
+# RELOC: R_XTENSA_SLOT0_OP
+# INST: bbc a8, a7, func
+# FIXUP: fixup A - offset: 0, value: func, kind: fixup_xtensa_branch_8
+
+bbci a3, 16, func
+# RELOC: R_XTENSA_SLOT0_OP
+# INST: bbci a3, 16, func
+# FIXUP: fixup A - offset: 0, value: func, kind: fixup_xtensa_branch_8
+
+bbs a12, a5, func
+# RELOC: R_XTENSA_SLOT0_OP
+# INST: bbs a12, a5, func
+# FIXUP: fixup A - offset: 0, value: func, kind: fixup_xtensa_branch_8
+
+bbsi a3, 16, func
+# RELOC: R_XTENSA_SLOT0_OP
+# INST: bbsi a3, 16, func
+# FIXUP: fixup A - offset: 0, value: func, kind: fixup_xtensa_branch_8
+
+bnall a7, a3, func
+# RELOC: R_XTENSA_SLOT0_OP
+# INST: bnall a7, a3, func
+# FIXUP: fixup A - offset: 0, value: func, kind: fixup_xtensa_branch_8
+
+bnone a2, a4, func
+# RELOC: R_XTENSA_SLOT0_OP
+# INST: bnone a2, a4, func
+# FIXUP: fixup A - offset: 0, value: func, kind: fixup_xtensa_branch_8
+
+beq a1, a2, func
+# RELOC: R_XTENSA_SLOT0_OP
+# INST: beq a1, a2, func
+# FIXUP: fixup A - offset: 0, value: func, kind: fixup_xtensa_branch_8
+
+beq a11, a5, func
+# RELOC: R_XTENSA_SLOT0_OP
+# INST: beq a11, a5, func
+# FIXUP: fixup A - offset: 0, value: func, kind: fixup_xtensa_branch_8
+
+beqi a1, 256, func
+# RELOC: R_XTENSA_SLOT0_OP
+# INST: beqi a1, 256, func
+# FIXUP: fixup A - offset: 0, value: func, kind: fixup_xtensa_branch_8
+
+beqi a11, -1, func
+# RELOC: R_XTENSA_SLOT0_OP
+# INST: beqi a11, -1, func
+# FIXUP: fixup A - offset: 0, value: func, kind: fixup_xtensa_branch_8
+
+beqz a8, func
+# RELOC: R_XTENSA_SLOT0_OP
+# INST: beqz a8, func
+# FIXUP: fixup A - offset: 0, value: func, kind: fixup_xtensa_branch_12
+
+bge a14, a2, func
+# RELOC: R_XTENSA_SLOT0_OP
+# INST: bge a14, a2, func
+# FIXUP: fixup A - offset: 0, value: func, kind: fixup_xtensa_branch_8
+
+bgei a11, -1, func
+# RELOC: R_XTENSA_SLOT0_OP
+# INST: bgei a11, -1, func
+# FIXUP: fixup A - offset: 0, value: func, kind: fixup_xtensa_branch_8
+
+bgei a11, 128, func
+# RELOC: R_XTENSA_SLOT0_OP
+# INST: bgei a11, 128, func
+# FIXUP: fixup A - offset: 0, value: func, kind: fixup_xtensa_branch_8
+
+bgeu a14, a2, func
+# RELOC: R_XTENSA_SLOT0_OP
+# INST: bgeu a14, a2, func
+# FIXUP: fixup A - offset: 0, value: func, kind: fixup_xtensa_branch_8
+
+bgeui a9, 32768, func
+# RELOC: R_XTENSA_SLOT0_OP
+# INST: bgeui a9, 32768, func
+# FIXUP: fixup A - offset: 0, value: func, kind: fixup_xtensa_branch_8
+
+bgeui a7, 65536, func
+# RELOC: R_XTENSA_SLOT0_OP
+# INST: bgeui a7, 65536, func
+# FIXUP: fixup A - offset: 0, value: func, kind: fixup_xtensa_branch_8
+
+bgeui a7, 64, func
+# RELOC: R_XTENSA_SLOT0_OP
+# INST: bgeui a7, 64, func
+# FIXUP: fixup A - offset: 0, value: func, kind: fixup_xtensa_branch_8
+
+bgez a8, func
+# RELOC: R_XTENSA_SLOT0_OP
+# INST: bgez a8, func
+# FIXUP: fixup A - offset: 0, value: func, kind: fixup_xtensa_branch_12
+
+blt a14, a2, func
+# RELOC: R_XTENSA_SLOT0_OP
+# INST: blt a14, a2, func
+# FIXUP: fixup A - offset: 0, value: func, kind: fixup_xtensa_branch_8
+
+blti a12, -1, func
+# RELOC: R_XTENSA_SLOT0_OP
+# INST: blti a12, -1, func
+# FIXUP: fixup A - offset: 0, value: func, kind: fixup_xtensa_branch_8
+
+blti a0, 32, func
+# RELOC: R_XTENSA_SLOT0_OP
+# INST: blti a0, 32, func
+# FIXUP: fixup A - offset: 0, value: func, kind: fixup_xtensa_branch_8
+
+bgeu a13, a1, func
+# RELOC: R_XTENSA_SLOT0_OP
+# INST: bgeu a13, a1, func
+# FIXUP: fixup A - offset: 0, value: func, kind: fixup_xtensa_branch_8
+
+bltui a7, 16, func
+# RELOC: R_XTENSA_SLOT0_OP
+# INST: bltui a7, 16, func
+# FIXUP: fixup A - offset: 0, value: func, kind: fixup_xtensa_branch_8
+
+bltz a6, func
+# RELOC: R_XTENSA_SLOT0_OP
+# INST: bltz a6, func
+# FIXUP: fixup A - offset: 0, value: func, kind: fixup_xtensa_branch_12
+
+bne a3, a4, func
+# RELOC: R_XTENSA_SLOT0_OP
+# INST: bne a3, a4, func
+# FIXUP: fixup A - offset: 0, value: func, kind: fixup_xtensa_branch_8
+
+bnei a5, 12, func
+# RELOC: R_XTENSA_SLOT0_OP
+# INST: bnei a5, 12, func
+# FIXUP: fixup A - offset: 0, value: func, kind: fixup_xtensa_branch_8
+
+bnez a5, func
+# RELOC: R_XTENSA_SLOT0_OP
+# INST: bnez a5, func
+# FIXUP: fixup A - offset: 0, value: func, kind: fixup_xtensa_branch_12
+
+call0 func
+# RELOC: R_XTENSA_SLOT0_OP
+# INST: call0 func
+# FIXUP: fixup A - offset: 0, value: func, kind: fixup_xtensa_call_18
+
+j func
+# RELOC: R_XTENSA_SLOT0_OP
+# INSTR: j func
+# FIXUP: fixup A - offset: 0, value: func, kind: fixup_xtensa_jump_18
+
+l32r a6, func
+# RELOC: R_XTENSA_SLOT0_OP
+# INSTR: l32r a6, func
+# FIXUP: fixup A - offset: 0, value: func, kind: fixup_xtensa_l32r_16
More information about the llvm-commits
mailing list