2013-05-07 00:15:19 +08:00
|
|
|
//===-- SystemZMCCodeEmitter.cpp - Convert SystemZ code to machine code ---===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file implements the SystemZMCCodeEmitter class.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "MCTargetDesc/SystemZMCFixups.h"
|
2017-01-25 06:10:43 +08:00
|
|
|
#include "MCTargetDesc/SystemZMCTargetDesc.h"
|
|
|
|
#include "llvm/ADT/SmallVector.h"
|
2013-05-07 00:15:19 +08:00
|
|
|
#include "llvm/MC/MCCodeEmitter.h"
|
|
|
|
#include "llvm/MC/MCContext.h"
|
|
|
|
#include "llvm/MC/MCExpr.h"
|
2017-01-25 06:10:43 +08:00
|
|
|
#include "llvm/MC/MCFixup.h"
|
2015-05-16 05:58:42 +08:00
|
|
|
#include "llvm/MC/MCInst.h"
|
2013-05-07 00:15:19 +08:00
|
|
|
#include "llvm/MC/MCInstrInfo.h"
|
2015-05-16 05:58:42 +08:00
|
|
|
#include "llvm/MC/MCRegisterInfo.h"
|
2017-01-25 06:10:43 +08:00
|
|
|
#include "llvm/MC/MCSubtargetInfo.h"
|
|
|
|
#include "llvm/Support/ErrorHandling.h"
|
|
|
|
#include "llvm/Support/raw_ostream.h"
|
|
|
|
#include <cassert>
|
|
|
|
#include <cstdint>
|
2013-05-07 00:15:19 +08:00
|
|
|
|
|
|
|
using namespace llvm;
|
|
|
|
|
2014-04-22 10:41:26 +08:00
|
|
|
#define DEBUG_TYPE "mccodeemitter"
|
|
|
|
|
2013-05-07 00:15:19 +08:00
|
|
|
namespace {
|
2017-01-25 06:10:43 +08:00
|
|
|
|
2013-05-07 00:15:19 +08:00
|
|
|
class SystemZMCCodeEmitter : public MCCodeEmitter {
|
|
|
|
const MCInstrInfo &MCII;
|
|
|
|
MCContext &Ctx;
|
|
|
|
|
|
|
|
public:
|
|
|
|
SystemZMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx)
|
|
|
|
: MCII(mcii), Ctx(ctx) {
|
|
|
|
}
|
|
|
|
|
2017-01-25 06:10:43 +08:00
|
|
|
~SystemZMCCodeEmitter() override = default;
|
2013-05-07 00:15:19 +08:00
|
|
|
|
|
|
|
// OVerride MCCodeEmitter.
|
2015-05-16 03:13:16 +08:00
|
|
|
void encodeInstruction(const MCInst &MI, raw_ostream &OS,
|
2014-03-06 20:03:36 +08:00
|
|
|
SmallVectorImpl<MCFixup> &Fixups,
|
|
|
|
const MCSubtargetInfo &STI) const override;
|
2013-05-07 00:15:19 +08:00
|
|
|
|
|
|
|
private:
|
|
|
|
// Automatically generated by TableGen.
|
|
|
|
uint64_t getBinaryCodeForInstr(const MCInst &MI,
|
2014-01-29 07:13:18 +08:00
|
|
|
SmallVectorImpl<MCFixup> &Fixups,
|
|
|
|
const MCSubtargetInfo &STI) const;
|
2013-05-07 00:15:19 +08:00
|
|
|
|
|
|
|
// Called by the TableGen code to get the binary encoding of operand
|
|
|
|
// MO in MI. Fixups is the list of fixups against MI.
|
2013-05-14 17:28:21 +08:00
|
|
|
uint64_t getMachineOpValue(const MCInst &MI, const MCOperand &MO,
|
2014-01-29 07:13:18 +08:00
|
|
|
SmallVectorImpl<MCFixup> &Fixups,
|
|
|
|
const MCSubtargetInfo &STI) const;
|
2013-05-07 00:15:19 +08:00
|
|
|
|
2013-05-14 17:28:21 +08:00
|
|
|
// Called by the TableGen code to get the binary encoding of an address.
|
2013-07-02 22:56:45 +08:00
|
|
|
// The index or length, if any, is encoded first, followed by the base,
|
2013-05-14 17:28:21 +08:00
|
|
|
// followed by the displacement. In a 20-bit displacement,
|
|
|
|
// the low 12 bits are encoded before the high 8 bits.
|
|
|
|
uint64_t getBDAddr12Encoding(const MCInst &MI, unsigned OpNum,
|
2014-01-29 07:13:18 +08:00
|
|
|
SmallVectorImpl<MCFixup> &Fixups,
|
|
|
|
const MCSubtargetInfo &STI) const;
|
2013-05-14 17:28:21 +08:00
|
|
|
uint64_t getBDAddr20Encoding(const MCInst &MI, unsigned OpNum,
|
2014-01-29 07:13:18 +08:00
|
|
|
SmallVectorImpl<MCFixup> &Fixups,
|
|
|
|
const MCSubtargetInfo &STI) const;
|
2013-05-14 17:28:21 +08:00
|
|
|
uint64_t getBDXAddr12Encoding(const MCInst &MI, unsigned OpNum,
|
2014-01-29 07:13:18 +08:00
|
|
|
SmallVectorImpl<MCFixup> &Fixups,
|
|
|
|
const MCSubtargetInfo &STI) const;
|
2013-05-14 17:28:21 +08:00
|
|
|
uint64_t getBDXAddr20Encoding(const MCInst &MI, unsigned OpNum,
|
2014-01-29 07:13:18 +08:00
|
|
|
SmallVectorImpl<MCFixup> &Fixups,
|
|
|
|
const MCSubtargetInfo &STI) const;
|
2017-05-10 20:42:45 +08:00
|
|
|
uint64_t getBDLAddr12Len4Encoding(const MCInst &MI, unsigned OpNum,
|
|
|
|
SmallVectorImpl<MCFixup> &Fixups,
|
|
|
|
const MCSubtargetInfo &STI) const;
|
2013-07-02 22:56:45 +08:00
|
|
|
uint64_t getBDLAddr12Len8Encoding(const MCInst &MI, unsigned OpNum,
|
2014-01-29 07:13:18 +08:00
|
|
|
SmallVectorImpl<MCFixup> &Fixups,
|
|
|
|
const MCSubtargetInfo &STI) const;
|
2016-10-31 22:21:36 +08:00
|
|
|
uint64_t getBDRAddr12Encoding(const MCInst &MI, unsigned OpNum,
|
|
|
|
SmallVectorImpl<MCFixup> &Fixups,
|
|
|
|
const MCSubtargetInfo &STI) const;
|
2015-05-06 03:23:40 +08:00
|
|
|
uint64_t getBDVAddr12Encoding(const MCInst &MI, unsigned OpNum,
|
|
|
|
SmallVectorImpl<MCFixup> &Fixups,
|
|
|
|
const MCSubtargetInfo &STI) const;
|
2013-05-14 17:28:21 +08:00
|
|
|
|
2013-05-07 00:15:19 +08:00
|
|
|
// Operand OpNum of MI needs a PC-relative fixup of kind Kind at
|
|
|
|
// Offset bytes from the start of MI. Add the fixup to Fixups
|
|
|
|
// and return the in-place addend, which since we're a RELA target
|
2015-02-18 17:11:36 +08:00
|
|
|
// is always 0. If AllowTLS is true and optional operand OpNum + 1
|
|
|
|
// is present, also emit a TLS call fixup for it.
|
2013-05-14 17:28:21 +08:00
|
|
|
uint64_t getPCRelEncoding(const MCInst &MI, unsigned OpNum,
|
2013-05-07 00:15:19 +08:00
|
|
|
SmallVectorImpl<MCFixup> &Fixups,
|
2015-02-18 17:11:36 +08:00
|
|
|
unsigned Kind, int64_t Offset,
|
|
|
|
bool AllowTLS) const;
|
2013-05-07 00:15:19 +08:00
|
|
|
|
2013-05-14 17:28:21 +08:00
|
|
|
uint64_t getPC16DBLEncoding(const MCInst &MI, unsigned OpNum,
|
2014-01-29 07:13:18 +08:00
|
|
|
SmallVectorImpl<MCFixup> &Fixups,
|
|
|
|
const MCSubtargetInfo &STI) const {
|
2015-02-18 17:11:36 +08:00
|
|
|
return getPCRelEncoding(MI, OpNum, Fixups,
|
|
|
|
SystemZ::FK_390_PC16DBL, 2, false);
|
2013-05-07 00:15:19 +08:00
|
|
|
}
|
2013-05-14 17:28:21 +08:00
|
|
|
uint64_t getPC32DBLEncoding(const MCInst &MI, unsigned OpNum,
|
2014-01-29 07:13:18 +08:00
|
|
|
SmallVectorImpl<MCFixup> &Fixups,
|
|
|
|
const MCSubtargetInfo &STI) const {
|
2015-02-18 17:11:36 +08:00
|
|
|
return getPCRelEncoding(MI, OpNum, Fixups,
|
|
|
|
SystemZ::FK_390_PC32DBL, 2, false);
|
|
|
|
}
|
|
|
|
uint64_t getPC16DBLTLSEncoding(const MCInst &MI, unsigned OpNum,
|
|
|
|
SmallVectorImpl<MCFixup> &Fixups,
|
|
|
|
const MCSubtargetInfo &STI) const {
|
|
|
|
return getPCRelEncoding(MI, OpNum, Fixups,
|
|
|
|
SystemZ::FK_390_PC16DBL, 2, true);
|
|
|
|
}
|
|
|
|
uint64_t getPC32DBLTLSEncoding(const MCInst &MI, unsigned OpNum,
|
|
|
|
SmallVectorImpl<MCFixup> &Fixups,
|
|
|
|
const MCSubtargetInfo &STI) const {
|
|
|
|
return getPCRelEncoding(MI, OpNum, Fixups,
|
|
|
|
SystemZ::FK_390_PC32DBL, 2, true);
|
2013-05-07 00:15:19 +08:00
|
|
|
}
|
2016-11-28 22:01:51 +08:00
|
|
|
uint64_t getPC12DBLBPPEncoding(const MCInst &MI, unsigned OpNum,
|
|
|
|
SmallVectorImpl<MCFixup> &Fixups,
|
|
|
|
const MCSubtargetInfo &STI) const {
|
|
|
|
return getPCRelEncoding(MI, OpNum, Fixups,
|
|
|
|
SystemZ::FK_390_PC12DBL, 1, false);
|
|
|
|
}
|
|
|
|
uint64_t getPC16DBLBPPEncoding(const MCInst &MI, unsigned OpNum,
|
|
|
|
SmallVectorImpl<MCFixup> &Fixups,
|
|
|
|
const MCSubtargetInfo &STI) const {
|
|
|
|
return getPCRelEncoding(MI, OpNum, Fixups,
|
|
|
|
SystemZ::FK_390_PC16DBL, 4, false);
|
|
|
|
}
|
|
|
|
uint64_t getPC24DBLBPPEncoding(const MCInst &MI, unsigned OpNum,
|
|
|
|
SmallVectorImpl<MCFixup> &Fixups,
|
|
|
|
const MCSubtargetInfo &STI) const {
|
|
|
|
return getPCRelEncoding(MI, OpNum, Fixups,
|
|
|
|
SystemZ::FK_390_PC24DBL, 3, false);
|
|
|
|
}
|
Check that emitted instructions meet their predicates on all targets except ARM, Mips, and X86.
Summary:
* ARM is omitted from this patch because this check appears to expose bugs in this target.
* Mips is omitted from this patch because this check either detects bugs or deliberate
emission of instructions that don't satisfy their predicates. One deliberate
use is the SYNC instruction where the version with an operand is correctly
defined as requiring MIPS32 while the version without an operand is defined
as an alias of 'SYNC 0' and requires MIPS2.
* X86 is omitted from this patch because it doesn't use the tablegen-erated
MCCodeEmitter infrastructure.
Patches for ARM and Mips will follow.
Depends on D25617
Reviewers: tstellarAMD, jmolloy
Subscribers: wdng, jmolloy, aemerson, rengolin, arsenm, jyknight, nemanjai, nhaehnle, tstellarAMD, llvm-commits
Differential Revision: https://reviews.llvm.org/D25618
llvm-svn: 287439
2016-11-19 21:05:44 +08:00
|
|
|
|
|
|
|
private:
|
|
|
|
uint64_t computeAvailableFeatures(const FeatureBitset &FB) const;
|
|
|
|
void verifyInstructionPredicates(const MCInst &MI,
|
|
|
|
uint64_t AvailableFeatures) const;
|
2013-05-07 00:15:19 +08:00
|
|
|
};
|
|
|
|
|
2017-01-25 06:10:43 +08:00
|
|
|
} // end anonymous namespace
|
2013-05-07 00:15:19 +08:00
|
|
|
|
|
|
|
void SystemZMCCodeEmitter::
|
2015-05-16 03:13:16 +08:00
|
|
|
encodeInstruction(const MCInst &MI, raw_ostream &OS,
|
2014-01-29 07:13:07 +08:00
|
|
|
SmallVectorImpl<MCFixup> &Fixups,
|
|
|
|
const MCSubtargetInfo &STI) const {
|
Check that emitted instructions meet their predicates on all targets except ARM, Mips, and X86.
Summary:
* ARM is omitted from this patch because this check appears to expose bugs in this target.
* Mips is omitted from this patch because this check either detects bugs or deliberate
emission of instructions that don't satisfy their predicates. One deliberate
use is the SYNC instruction where the version with an operand is correctly
defined as requiring MIPS32 while the version without an operand is defined
as an alias of 'SYNC 0' and requires MIPS2.
* X86 is omitted from this patch because it doesn't use the tablegen-erated
MCCodeEmitter infrastructure.
Patches for ARM and Mips will follow.
Depends on D25617
Reviewers: tstellarAMD, jmolloy
Subscribers: wdng, jmolloy, aemerson, rengolin, arsenm, jyknight, nemanjai, nhaehnle, tstellarAMD, llvm-commits
Differential Revision: https://reviews.llvm.org/D25618
llvm-svn: 287439
2016-11-19 21:05:44 +08:00
|
|
|
verifyInstructionPredicates(MI,
|
|
|
|
computeAvailableFeatures(STI.getFeatureBits()));
|
|
|
|
|
2014-01-29 07:13:18 +08:00
|
|
|
uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
|
2013-05-07 00:15:19 +08:00
|
|
|
unsigned Size = MCII.get(MI.getOpcode()).getSize();
|
|
|
|
// Big-endian insertion of Size bytes.
|
|
|
|
unsigned ShiftValue = (Size * 8) - 8;
|
|
|
|
for (unsigned I = 0; I != Size; ++I) {
|
|
|
|
OS << uint8_t(Bits >> ShiftValue);
|
|
|
|
ShiftValue -= 8;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-14 17:28:21 +08:00
|
|
|
uint64_t SystemZMCCodeEmitter::
|
2013-05-07 00:15:19 +08:00
|
|
|
getMachineOpValue(const MCInst &MI, const MCOperand &MO,
|
2014-01-29 07:13:18 +08:00
|
|
|
SmallVectorImpl<MCFixup> &Fixups,
|
|
|
|
const MCSubtargetInfo &STI) const {
|
2013-05-07 00:15:19 +08:00
|
|
|
if (MO.isReg())
|
2013-06-18 15:20:20 +08:00
|
|
|
return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
|
2013-05-07 00:15:19 +08:00
|
|
|
if (MO.isImm())
|
2013-05-14 17:28:21 +08:00
|
|
|
return static_cast<uint64_t>(MO.getImm());
|
2013-05-07 00:15:19 +08:00
|
|
|
llvm_unreachable("Unexpected operand type!");
|
|
|
|
}
|
|
|
|
|
2013-05-14 17:28:21 +08:00
|
|
|
uint64_t SystemZMCCodeEmitter::
|
|
|
|
getBDAddr12Encoding(const MCInst &MI, unsigned OpNum,
|
2014-01-29 07:13:18 +08:00
|
|
|
SmallVectorImpl<MCFixup> &Fixups,
|
|
|
|
const MCSubtargetInfo &STI) const {
|
|
|
|
uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI);
|
|
|
|
uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups, STI);
|
2013-05-14 17:28:21 +08:00
|
|
|
assert(isUInt<4>(Base) && isUInt<12>(Disp));
|
|
|
|
return (Base << 12) | Disp;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t SystemZMCCodeEmitter::
|
|
|
|
getBDAddr20Encoding(const MCInst &MI, unsigned OpNum,
|
2014-01-29 07:13:18 +08:00
|
|
|
SmallVectorImpl<MCFixup> &Fixups,
|
|
|
|
const MCSubtargetInfo &STI) const {
|
|
|
|
uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI);
|
|
|
|
uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups, STI);
|
2013-05-14 17:28:21 +08:00
|
|
|
assert(isUInt<4>(Base) && isInt<20>(Disp));
|
|
|
|
return (Base << 20) | ((Disp & 0xfff) << 8) | ((Disp & 0xff000) >> 12);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t SystemZMCCodeEmitter::
|
|
|
|
getBDXAddr12Encoding(const MCInst &MI, unsigned OpNum,
|
2014-01-29 07:13:18 +08:00
|
|
|
SmallVectorImpl<MCFixup> &Fixups,
|
|
|
|
const MCSubtargetInfo &STI) const {
|
|
|
|
uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI);
|
|
|
|
uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups, STI);
|
|
|
|
uint64_t Index = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups, STI);
|
2013-05-14 17:28:21 +08:00
|
|
|
assert(isUInt<4>(Base) && isUInt<12>(Disp) && isUInt<4>(Index));
|
|
|
|
return (Index << 16) | (Base << 12) | Disp;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t SystemZMCCodeEmitter::
|
|
|
|
getBDXAddr20Encoding(const MCInst &MI, unsigned OpNum,
|
2014-01-29 07:13:18 +08:00
|
|
|
SmallVectorImpl<MCFixup> &Fixups,
|
|
|
|
const MCSubtargetInfo &STI) const {
|
|
|
|
uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI);
|
|
|
|
uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups, STI);
|
|
|
|
uint64_t Index = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups, STI);
|
2013-05-14 17:28:21 +08:00
|
|
|
assert(isUInt<4>(Base) && isInt<20>(Disp) && isUInt<4>(Index));
|
|
|
|
return (Index << 24) | (Base << 20) | ((Disp & 0xfff) << 8)
|
|
|
|
| ((Disp & 0xff000) >> 12);
|
|
|
|
}
|
|
|
|
|
2017-05-10 20:42:45 +08:00
|
|
|
uint64_t SystemZMCCodeEmitter::
|
|
|
|
getBDLAddr12Len4Encoding(const MCInst &MI, unsigned OpNum,
|
|
|
|
SmallVectorImpl<MCFixup> &Fixups,
|
|
|
|
const MCSubtargetInfo &STI) const {
|
|
|
|
uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI);
|
|
|
|
uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups, STI);
|
|
|
|
uint64_t Len = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups, STI) - 1;
|
|
|
|
assert(isUInt<4>(Base) && isUInt<12>(Disp) && isUInt<4>(Len));
|
|
|
|
return (Len << 16) | (Base << 12) | Disp;
|
|
|
|
}
|
|
|
|
|
2013-07-02 22:56:45 +08:00
|
|
|
uint64_t SystemZMCCodeEmitter::
|
|
|
|
getBDLAddr12Len8Encoding(const MCInst &MI, unsigned OpNum,
|
2014-01-29 07:13:18 +08:00
|
|
|
SmallVectorImpl<MCFixup> &Fixups,
|
|
|
|
const MCSubtargetInfo &STI) const {
|
|
|
|
uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI);
|
|
|
|
uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups, STI);
|
|
|
|
uint64_t Len = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups, STI) - 1;
|
2013-07-02 22:56:45 +08:00
|
|
|
assert(isUInt<4>(Base) && isUInt<12>(Disp) && isUInt<8>(Len));
|
|
|
|
return (Len << 16) | (Base << 12) | Disp;
|
|
|
|
}
|
|
|
|
|
2016-10-31 22:21:36 +08:00
|
|
|
uint64_t SystemZMCCodeEmitter::
|
|
|
|
getBDRAddr12Encoding(const MCInst &MI, unsigned OpNum,
|
|
|
|
SmallVectorImpl<MCFixup> &Fixups,
|
|
|
|
const MCSubtargetInfo &STI) const {
|
|
|
|
uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI);
|
|
|
|
uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups, STI);
|
|
|
|
uint64_t Len = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups, STI);
|
|
|
|
assert(isUInt<4>(Base) && isUInt<12>(Disp) && isUInt<4>(Len));
|
|
|
|
return (Len << 16) | (Base << 12) | Disp;
|
|
|
|
}
|
|
|
|
|
2015-05-06 03:23:40 +08:00
|
|
|
uint64_t SystemZMCCodeEmitter::
|
|
|
|
getBDVAddr12Encoding(const MCInst &MI, unsigned OpNum,
|
|
|
|
SmallVectorImpl<MCFixup> &Fixups,
|
|
|
|
const MCSubtargetInfo &STI) const {
|
|
|
|
uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI);
|
|
|
|
uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups, STI);
|
|
|
|
uint64_t Index = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups, STI);
|
|
|
|
assert(isUInt<4>(Base) && isUInt<12>(Disp) && isUInt<5>(Index));
|
|
|
|
return (Index << 16) | (Base << 12) | Disp;
|
|
|
|
}
|
|
|
|
|
2013-05-14 17:28:21 +08:00
|
|
|
uint64_t
|
|
|
|
SystemZMCCodeEmitter::getPCRelEncoding(const MCInst &MI, unsigned OpNum,
|
2013-05-07 00:15:19 +08:00
|
|
|
SmallVectorImpl<MCFixup> &Fixups,
|
2015-02-18 17:11:36 +08:00
|
|
|
unsigned Kind, int64_t Offset,
|
|
|
|
bool AllowTLS) const {
|
2013-05-07 00:15:19 +08:00
|
|
|
const MCOperand &MO = MI.getOperand(OpNum);
|
2013-05-14 17:47:26 +08:00
|
|
|
const MCExpr *Expr;
|
2013-05-07 00:15:19 +08:00
|
|
|
if (MO.isImm())
|
2015-05-30 09:25:56 +08:00
|
|
|
Expr = MCConstantExpr::create(MO.getImm() + Offset, Ctx);
|
2013-05-14 17:47:26 +08:00
|
|
|
else {
|
|
|
|
Expr = MO.getExpr();
|
|
|
|
if (Offset) {
|
|
|
|
// The operand value is relative to the start of MI, but the fixup
|
|
|
|
// is relative to the operand field itself, which is Offset bytes
|
|
|
|
// into MI. Add Offset to the relocation value to cancel out
|
|
|
|
// this difference.
|
2015-05-30 09:25:56 +08:00
|
|
|
const MCExpr *OffsetExpr = MCConstantExpr::create(Offset, Ctx);
|
|
|
|
Expr = MCBinaryExpr::createAdd(Expr, OffsetExpr, Ctx);
|
2013-05-14 17:47:26 +08:00
|
|
|
}
|
2013-05-07 00:15:19 +08:00
|
|
|
}
|
2015-05-16 03:13:05 +08:00
|
|
|
Fixups.push_back(MCFixup::create(Offset, Expr, (MCFixupKind)Kind));
|
2015-02-18 17:11:36 +08:00
|
|
|
|
|
|
|
// Output the fixup for the TLS marker if present.
|
|
|
|
if (AllowTLS && OpNum + 1 < MI.getNumOperands()) {
|
|
|
|
const MCOperand &MOTLS = MI.getOperand(OpNum + 1);
|
2015-05-16 03:13:05 +08:00
|
|
|
Fixups.push_back(MCFixup::create(0, MOTLS.getExpr(),
|
2015-02-18 17:11:36 +08:00
|
|
|
(MCFixupKind)SystemZ::FK_390_TLS_CALL));
|
|
|
|
}
|
2013-05-07 00:15:19 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
Check that emitted instructions meet their predicates on all targets except ARM, Mips, and X86.
Summary:
* ARM is omitted from this patch because this check appears to expose bugs in this target.
* Mips is omitted from this patch because this check either detects bugs or deliberate
emission of instructions that don't satisfy their predicates. One deliberate
use is the SYNC instruction where the version with an operand is correctly
defined as requiring MIPS32 while the version without an operand is defined
as an alias of 'SYNC 0' and requires MIPS2.
* X86 is omitted from this patch because it doesn't use the tablegen-erated
MCCodeEmitter infrastructure.
Patches for ARM and Mips will follow.
Depends on D25617
Reviewers: tstellarAMD, jmolloy
Subscribers: wdng, jmolloy, aemerson, rengolin, arsenm, jyknight, nemanjai, nhaehnle, tstellarAMD, llvm-commits
Differential Revision: https://reviews.llvm.org/D25618
llvm-svn: 287439
2016-11-19 21:05:44 +08:00
|
|
|
#define ENABLE_INSTR_PREDICATE_VERIFIER
|
2013-05-07 00:15:19 +08:00
|
|
|
#include "SystemZGenMCCodeEmitter.inc"
|
2017-01-25 06:10:43 +08:00
|
|
|
|
|
|
|
MCCodeEmitter *llvm::createSystemZMCCodeEmitter(const MCInstrInfo &MCII,
|
|
|
|
const MCRegisterInfo &MRI,
|
|
|
|
MCContext &Ctx) {
|
|
|
|
return new SystemZMCCodeEmitter(MCII, Ctx);
|
|
|
|
}
|