[llvm-commits] [llvm] r135825 - in /llvm/trunk/lib: MC/ Target/ARM/ Target/ARM/InstPrinter/ Target/ARM/MCTargetDesc/
Evan Cheng
evan.cheng at apple.com
Fri Jul 22 17:00:19 PDT 2011
Author: evancheng
Date: Fri Jul 22 19:00:19 2011
New Revision: 135825
URL: http://llvm.org/viewvc/llvm-project?rev=135825&view=rev
Log:
Sink ARM mc routines into MCTargetDesc.
Added:
llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
- copied, changed from r135818, llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp
llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h
- copied, changed from r135818, llvm/trunk/lib/Target/ARM/ARMBaseInfo.h
llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMFixupKinds.h
- copied unchanged from r135818, llvm/trunk/lib/Target/ARM/ARMFixupKinds.h
llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp
- copied, changed from r135818, llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp
llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp
- copied, changed from r135818, llvm/trunk/lib/Target/ARM/ARMMachObjectWriter.cpp
Removed:
llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp
llvm/trunk/lib/Target/ARM/ARMBaseInfo.h
llvm/trunk/lib/Target/ARM/ARMFixupKinds.h
llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp
llvm/trunk/lib/Target/ARM/ARMMachObjectWriter.cpp
Modified:
llvm/trunk/lib/MC/ELFObjectWriter.cpp
llvm/trunk/lib/Target/ARM/ARM.h
llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp
llvm/trunk/lib/Target/ARM/CMakeLists.txt
llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h
llvm/trunk/lib/Target/ARM/MCTargetDesc/CMakeLists.txt
Modified: llvm/trunk/lib/MC/ELFObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/ELFObjectWriter.cpp?rev=135825&r1=135824&r2=135825&view=diff
==============================================================================
--- llvm/trunk/lib/MC/ELFObjectWriter.cpp (original)
+++ llvm/trunk/lib/MC/ELFObjectWriter.cpp Fri Jul 22 19:00:19 2011
@@ -29,7 +29,7 @@
#include "llvm/ADT/Statistic.h"
#include "../Target/X86/X86FixupKinds.h"
-#include "../Target/ARM/ARMFixupKinds.h"
+#include "../Target/ARM/MCTargetDesc/ARMFixupKinds.h"
#include <vector>
using namespace llvm;
Modified: llvm/trunk/lib/Target/ARM/ARM.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARM.h?rev=135825&r1=135824&r2=135825&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARM.h (original)
+++ llvm/trunk/lib/Target/ARM/ARM.h Fri Jul 22 19:00:19 2011
@@ -15,7 +15,7 @@
#ifndef TARGET_ARM_H
#define TARGET_ARM_H
-#include "ARMBaseInfo.h"
+#include "MCTargetDesc/ARMBaseInfo.h"
#include "MCTargetDesc/ARMMCTargetDesc.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
@@ -37,12 +37,6 @@
class TargetAsmBackend;
class formatted_raw_ostream;
-MCCodeEmitter *createARMMCCodeEmitter(const MCInstrInfo &MCII,
- const MCSubtargetInfo &STI,
- MCContext &Ctx);
-
-TargetAsmBackend *createARMAsmBackend(const Target &, const std::string &);
-
FunctionPass *createARMISelDag(ARMBaseTargetMachine &TM,
CodeGenOpt::Level OptLevel);
@@ -61,12 +55,6 @@
void LowerARMMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
ARMAsmPrinter &AP);
-/// createARMMachObjectWriter - Construct an ARM Mach-O object writer.
-MCObjectWriter *createARMMachObjectWriter(raw_ostream &OS,
- bool Is64Bit,
- uint32_t CPUType,
- uint32_t CPUSubtype);
-
} // end namespace llvm;
#endif
Removed: llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp?rev=135824&view=auto
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp (removed)
@@ -1,516 +0,0 @@
-//===-- ARMAsmBackend.cpp - ARM Assembler Backend -------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ARM.h"
-#include "ARMFixupKinds.h"
-#include "MCTargetDesc/ARMAddressingModes.h"
-#include "llvm/ADT/Twine.h"
-#include "llvm/MC/MCAssembler.h"
-#include "llvm/MC/MCDirectives.h"
-#include "llvm/MC/MCELFObjectWriter.h"
-#include "llvm/MC/MCExpr.h"
-#include "llvm/MC/MCMachObjectWriter.h"
-#include "llvm/MC/MCObjectWriter.h"
-#include "llvm/MC/MCSectionELF.h"
-#include "llvm/MC/MCSectionMachO.h"
-#include "llvm/Object/MachOFormat.h"
-#include "llvm/Support/ELF.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetAsmBackend.h"
-#include "llvm/Target/TargetRegistry.h"
-using namespace llvm;
-
-namespace {
-class ARMELFObjectWriter : public MCELFObjectTargetWriter {
-public:
- ARMELFObjectWriter(Triple::OSType OSType)
- : MCELFObjectTargetWriter(/*Is64Bit*/ false, OSType, ELF::EM_ARM,
- /*HasRelocationAddend*/ false) {}
-};
-
-class ARMAsmBackend : public TargetAsmBackend {
- bool isThumbMode; // Currently emitting Thumb code.
-public:
- ARMAsmBackend(const Target &T) : TargetAsmBackend(), isThumbMode(false) {}
-
- unsigned getNumFixupKinds() const { return ARM::NumTargetFixupKinds; }
-
- const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const {
- const static MCFixupKindInfo Infos[ARM::NumTargetFixupKinds] = {
-// This table *must* be in the order that the fixup_* kinds are defined in
-// ARMFixupKinds.h.
-//
-// Name Offset (bits) Size (bits) Flags
-{ "fixup_arm_ldst_pcrel_12", 1, 24, MCFixupKindInfo::FKF_IsPCRel },
-{ "fixup_t2_ldst_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel |
- MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
-{ "fixup_arm_pcrel_10", 1, 24, MCFixupKindInfo::FKF_IsPCRel },
-{ "fixup_t2_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsPCRel |
- MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
-{ "fixup_thumb_adr_pcrel_10",0, 8, MCFixupKindInfo::FKF_IsPCRel |
- MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
-{ "fixup_arm_adr_pcrel_12", 1, 24, MCFixupKindInfo::FKF_IsPCRel },
-{ "fixup_t2_adr_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel |
- MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
-{ "fixup_arm_condbranch", 0, 24, MCFixupKindInfo::FKF_IsPCRel },
-{ "fixup_arm_uncondbranch", 0, 24, MCFixupKindInfo::FKF_IsPCRel },
-{ "fixup_t2_condbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
-{ "fixup_t2_uncondbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
-{ "fixup_arm_thumb_br", 0, 16, MCFixupKindInfo::FKF_IsPCRel },
-{ "fixup_arm_thumb_bl", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
-{ "fixup_arm_thumb_blx", 7, 21, MCFixupKindInfo::FKF_IsPCRel },
-{ "fixup_arm_thumb_cb", 0, 16, MCFixupKindInfo::FKF_IsPCRel },
-{ "fixup_arm_thumb_cp", 1, 8, MCFixupKindInfo::FKF_IsPCRel },
-{ "fixup_arm_thumb_bcc", 0, 8, MCFixupKindInfo::FKF_IsPCRel },
-// movw / movt: 16-bits immediate but scattered into two chunks 0 - 12, 16 - 19.
-{ "fixup_arm_movt_hi16", 0, 20, 0 },
-{ "fixup_arm_movw_lo16", 0, 20, 0 },
-{ "fixup_t2_movt_hi16", 0, 20, 0 },
-{ "fixup_t2_movw_lo16", 0, 20, 0 },
-{ "fixup_arm_movt_hi16_pcrel", 0, 20, MCFixupKindInfo::FKF_IsPCRel },
-{ "fixup_arm_movw_lo16_pcrel", 0, 20, MCFixupKindInfo::FKF_IsPCRel },
-{ "fixup_t2_movt_hi16_pcrel", 0, 20, MCFixupKindInfo::FKF_IsPCRel },
-{ "fixup_t2_movw_lo16_pcrel", 0, 20, MCFixupKindInfo::FKF_IsPCRel },
- };
-
- if (Kind < FirstTargetFixupKind)
- return TargetAsmBackend::getFixupKindInfo(Kind);
-
- assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
- "Invalid kind!");
- return Infos[Kind - FirstTargetFixupKind];
- }
-
- bool MayNeedRelaxation(const MCInst &Inst) const;
-
- void RelaxInstruction(const MCInst &Inst, MCInst &Res) const;
-
- bool WriteNopData(uint64_t Count, MCObjectWriter *OW) const;
-
- void HandleAssemblerFlag(MCAssemblerFlag Flag) {
- switch (Flag) {
- default: break;
- case MCAF_Code16:
- setIsThumb(true);
- break;
- case MCAF_Code32:
- setIsThumb(false);
- break;
- }
- }
-
- unsigned getPointerSize() const { return 4; }
- bool isThumb() const { return isThumbMode; }
- void setIsThumb(bool it) { isThumbMode = it; }
-};
-} // end anonymous namespace
-
-bool ARMAsmBackend::MayNeedRelaxation(const MCInst &Inst) const {
- // FIXME: Thumb targets, different move constant targets..
- return false;
-}
-
-void ARMAsmBackend::RelaxInstruction(const MCInst &Inst, MCInst &Res) const {
- assert(0 && "ARMAsmBackend::RelaxInstruction() unimplemented");
- return;
-}
-
-bool ARMAsmBackend::WriteNopData(uint64_t Count, MCObjectWriter *OW) const {
- if (isThumb()) {
- // FIXME: 0xbf00 is the ARMv7 value. For v6 and before, we'll need to
- // use 0x46c0 (which is a 'mov r8, r8' insn).
- uint64_t NumNops = Count / 2;
- for (uint64_t i = 0; i != NumNops; ++i)
- OW->Write16(0xbf00);
- if (Count & 1)
- OW->Write8(0);
- return true;
- }
- // ARM mode
- uint64_t NumNops = Count / 4;
- for (uint64_t i = 0; i != NumNops; ++i)
- OW->Write32(0xe1a00000);
- switch (Count % 4) {
- default: break; // No leftover bytes to write
- case 1: OW->Write8(0); break;
- case 2: OW->Write16(0); break;
- case 3: OW->Write16(0); OW->Write8(0xa0); break;
- }
-
- return true;
-}
-
-static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
- switch (Kind) {
- default:
- llvm_unreachable("Unknown fixup kind!");
- case FK_Data_1:
- case FK_Data_2:
- case FK_Data_4:
- return Value;
- case ARM::fixup_arm_movt_hi16:
- Value >>= 16;
- // Fallthrough
- case ARM::fixup_arm_movw_lo16:
- case ARM::fixup_arm_movt_hi16_pcrel:
- case ARM::fixup_arm_movw_lo16_pcrel: {
- unsigned Hi4 = (Value & 0xF000) >> 12;
- unsigned Lo12 = Value & 0x0FFF;
- assert ((((int64_t)Value) >= -0x8000) && (((int64_t)Value) <= 0x7fff) &&
- "Out of range pc-relative fixup value!");
- // inst{19-16} = Hi4;
- // inst{11-0} = Lo12;
- Value = (Hi4 << 16) | (Lo12);
- return Value;
- }
- case ARM::fixup_t2_movt_hi16:
- Value >>= 16;
- // Fallthrough
- case ARM::fixup_t2_movw_lo16:
- case ARM::fixup_t2_movt_hi16_pcrel: //FIXME: Shouldn't this be shifted like
- // the other hi16 fixup?
- case ARM::fixup_t2_movw_lo16_pcrel: {
- unsigned Hi4 = (Value & 0xF000) >> 12;
- unsigned i = (Value & 0x800) >> 11;
- unsigned Mid3 = (Value & 0x700) >> 8;
- unsigned Lo8 = Value & 0x0FF;
- // inst{19-16} = Hi4;
- // inst{26} = i;
- // inst{14-12} = Mid3;
- // inst{7-0} = Lo8;
- // The value comes in as the whole thing, not just the portion required
- // for this fixup, so we need to mask off the bits not handled by this
- // portion (lo vs. hi).
- Value &= 0xffff;
- Value = (Hi4 << 16) | (i << 26) | (Mid3 << 12) | (Lo8);
- uint64_t swapped = (Value & 0xFFFF0000) >> 16;
- swapped |= (Value & 0x0000FFFF) << 16;
- return swapped;
- }
- case ARM::fixup_arm_ldst_pcrel_12:
- // ARM PC-relative values are offset by 8.
- Value -= 4;
- // FALLTHROUGH
- case ARM::fixup_t2_ldst_pcrel_12: {
- // Offset by 4, adjusted by two due to the half-word ordering of thumb.
- Value -= 4;
- bool isAdd = true;
- if ((int64_t)Value < 0) {
- Value = -Value;
- isAdd = false;
- }
- assert ((Value < 4096) && "Out of range pc-relative fixup value!");
- Value |= isAdd << 23;
-
- // Same addressing mode as fixup_arm_pcrel_10,
- // but with 16-bit halfwords swapped.
- if (Kind == ARM::fixup_t2_ldst_pcrel_12) {
- uint64_t swapped = (Value & 0xFFFF0000) >> 16;
- swapped |= (Value & 0x0000FFFF) << 16;
- return swapped;
- }
-
- return Value;
- }
- case ARM::fixup_thumb_adr_pcrel_10:
- return ((Value - 4) >> 2) & 0xff;
- case ARM::fixup_arm_adr_pcrel_12: {
- // ARM PC-relative values are offset by 8.
- Value -= 8;
- unsigned opc = 4; // bits {24-21}. Default to add: 0b0100
- if ((int64_t)Value < 0) {
- Value = -Value;
- opc = 2; // 0b0010
- }
- assert(ARM_AM::getSOImmVal(Value) != -1 &&
- "Out of range pc-relative fixup value!");
- // Encode the immediate and shift the opcode into place.
- return ARM_AM::getSOImmVal(Value) | (opc << 21);
- }
-
- case ARM::fixup_t2_adr_pcrel_12: {
- Value -= 4;
- unsigned opc = 0;
- if ((int64_t)Value < 0) {
- Value = -Value;
- opc = 5;
- }
-
- uint32_t out = (opc << 21);
- out |= (Value & 0x800) << 15;
- out |= (Value & 0x700) << 4;
- out |= (Value & 0x0FF);
-
- uint64_t swapped = (out & 0xFFFF0000) >> 16;
- swapped |= (out & 0x0000FFFF) << 16;
- return swapped;
- }
-
- case ARM::fixup_arm_condbranch:
- case ARM::fixup_arm_uncondbranch:
- // These values don't encode the low two bits since they're always zero.
- // Offset by 8 just as above.
- return 0xffffff & ((Value - 8) >> 2);
- case ARM::fixup_t2_uncondbranch: {
- Value = Value - 4;
- Value >>= 1; // Low bit is not encoded.
-
- uint32_t out = 0;
- bool I = Value & 0x800000;
- bool J1 = Value & 0x400000;
- bool J2 = Value & 0x200000;
- J1 ^= I;
- J2 ^= I;
-
- out |= I << 26; // S bit
- out |= !J1 << 13; // J1 bit
- out |= !J2 << 11; // J2 bit
- out |= (Value & 0x1FF800) << 5; // imm6 field
- out |= (Value & 0x0007FF); // imm11 field
-
- uint64_t swapped = (out & 0xFFFF0000) >> 16;
- swapped |= (out & 0x0000FFFF) << 16;
- return swapped;
- }
- case ARM::fixup_t2_condbranch: {
- Value = Value - 4;
- Value >>= 1; // Low bit is not encoded.
-
- uint64_t out = 0;
- out |= (Value & 0x80000) << 7; // S bit
- out |= (Value & 0x40000) >> 7; // J2 bit
- out |= (Value & 0x20000) >> 4; // J1 bit
- out |= (Value & 0x1F800) << 5; // imm6 field
- out |= (Value & 0x007FF); // imm11 field
-
- uint32_t swapped = (out & 0xFFFF0000) >> 16;
- swapped |= (out & 0x0000FFFF) << 16;
- return swapped;
- }
- case ARM::fixup_arm_thumb_bl: {
- // The value doesn't encode the low bit (always zero) and is offset by
- // four. The value is encoded into disjoint bit positions in the destination
- // opcode. x = unchanged, I = immediate value bit, S = sign extension bit
- //
- // BL: xxxxxSIIIIIIIIII xxxxxIIIIIIIIIII
- //
- // Note that the halfwords are stored high first, low second; so we need
- // to transpose the fixup value here to map properly.
- unsigned isNeg = (int64_t(Value - 4) < 0) ? 1 : 0;
- uint32_t Binary = 0;
- Value = 0x3fffff & ((Value - 4) >> 1);
- Binary = (Value & 0x7ff) << 16; // Low imm11 value.
- Binary |= (Value & 0x1ffc00) >> 11; // High imm10 value.
- Binary |= isNeg << 10; // Sign bit.
- return Binary;
- }
- case ARM::fixup_arm_thumb_blx: {
- // The value doesn't encode the low two bits (always zero) and is offset by
- // four (see fixup_arm_thumb_cp). The value is encoded into disjoint bit
- // positions in the destination opcode. x = unchanged, I = immediate value
- // bit, S = sign extension bit, 0 = zero.
- //
- // BLX: xxxxxSIIIIIIIIII xxxxxIIIIIIIIII0
- //
- // Note that the halfwords are stored high first, low second; so we need
- // to transpose the fixup value here to map properly.
- unsigned isNeg = (int64_t(Value-4) < 0) ? 1 : 0;
- uint32_t Binary = 0;
- Value = 0xfffff & ((Value - 2) >> 2);
- Binary = (Value & 0x3ff) << 17; // Low imm10L value.
- Binary |= (Value & 0xffc00) >> 10; // High imm10H value.
- Binary |= isNeg << 10; // Sign bit.
- return Binary;
- }
- case ARM::fixup_arm_thumb_cp:
- // Offset by 4, and don't encode the low two bits. Two bytes of that
- // 'off by 4' is implicitly handled by the half-word ordering of the
- // Thumb encoding, so we only need to adjust by 2 here.
- return ((Value - 2) >> 2) & 0xff;
- case ARM::fixup_arm_thumb_cb: {
- // Offset by 4 and don't encode the lower bit, which is always 0.
- uint32_t Binary = (Value - 4) >> 1;
- return ((Binary & 0x20) << 4) | ((Binary & 0x1f) << 3);
- }
- case ARM::fixup_arm_thumb_br:
- // Offset by 4 and don't encode the lower bit, which is always 0.
- return ((Value - 4) >> 1) & 0x7ff;
- case ARM::fixup_arm_thumb_bcc:
- // Offset by 4 and don't encode the lower bit, which is always 0.
- return ((Value - 4) >> 1) & 0xff;
- case ARM::fixup_arm_pcrel_10:
- Value = Value - 4; // ARM fixups offset by an additional word and don't
- // need to adjust for the half-word ordering.
- // Fall through.
- case ARM::fixup_t2_pcrel_10: {
- // Offset by 4, adjusted by two due to the half-word ordering of thumb.
- Value = Value - 4;
- bool isAdd = true;
- if ((int64_t)Value < 0) {
- Value = -Value;
- isAdd = false;
- }
- // These values don't encode the low two bits since they're always zero.
- Value >>= 2;
- assert ((Value < 256) && "Out of range pc-relative fixup value!");
- Value |= isAdd << 23;
-
- // Same addressing mode as fixup_arm_pcrel_10,
- // but with 16-bit halfwords swapped.
- if (Kind == ARM::fixup_t2_pcrel_10) {
- uint32_t swapped = (Value & 0xFFFF0000) >> 16;
- swapped |= (Value & 0x0000FFFF) << 16;
- return swapped;
- }
-
- return Value;
- }
- }
-}
-
-namespace {
-
-// FIXME: This should be in a separate file.
-// ELF is an ELF of course...
-class ELFARMAsmBackend : public ARMAsmBackend {
-public:
- Triple::OSType OSType;
- ELFARMAsmBackend(const Target &T, Triple::OSType _OSType)
- : ARMAsmBackend(T), OSType(_OSType) { }
-
- void ApplyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
- uint64_t Value) const;
-
- MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
- return createELFObjectWriter(new ARMELFObjectWriter(OSType), OS,
- /*IsLittleEndian*/ true);
- }
-};
-
-// FIXME: Raise this to share code between Darwin and ELF.
-void ELFARMAsmBackend::ApplyFixup(const MCFixup &Fixup, char *Data,
- unsigned DataSize, uint64_t Value) const {
- unsigned NumBytes = 4; // FIXME: 2 for Thumb
- Value = adjustFixupValue(Fixup.getKind(), Value);
- if (!Value) return; // Doesn't change encoding.
-
- unsigned Offset = Fixup.getOffset();
-
- // For each byte of the fragment that the fixup touches, mask in the bits from
- // the fixup value. The Value has been "split up" into the appropriate
- // bitfields above.
- for (unsigned i = 0; i != NumBytes; ++i)
- Data[Offset + i] |= uint8_t((Value >> (i * 8)) & 0xff);
-}
-
-// FIXME: This should be in a separate file.
-class DarwinARMAsmBackend : public ARMAsmBackend {
-public:
- const object::mach::CPUSubtypeARM Subtype;
- DarwinARMAsmBackend(const Target &T, object::mach::CPUSubtypeARM st)
- : ARMAsmBackend(T), Subtype(st) { }
-
- MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
- return createARMMachObjectWriter(OS, /*Is64Bit=*/false,
- object::mach::CTM_ARM,
- Subtype);
- }
-
- void ApplyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
- uint64_t Value) const;
-
- virtual bool doesSectionRequireSymbols(const MCSection &Section) const {
- return false;
- }
-};
-
-/// getFixupKindNumBytes - The number of bytes the fixup may change.
-static unsigned getFixupKindNumBytes(unsigned Kind) {
- switch (Kind) {
- default:
- llvm_unreachable("Unknown fixup kind!");
-
- case FK_Data_1:
- case ARM::fixup_arm_thumb_bcc:
- case ARM::fixup_arm_thumb_cp:
- case ARM::fixup_thumb_adr_pcrel_10:
- return 1;
-
- case FK_Data_2:
- case ARM::fixup_arm_thumb_br:
- case ARM::fixup_arm_thumb_cb:
- return 2;
-
- case ARM::fixup_arm_ldst_pcrel_12:
- case ARM::fixup_arm_pcrel_10:
- case ARM::fixup_arm_adr_pcrel_12:
- case ARM::fixup_arm_condbranch:
- case ARM::fixup_arm_uncondbranch:
- return 3;
-
- case FK_Data_4:
- case ARM::fixup_t2_ldst_pcrel_12:
- case ARM::fixup_t2_condbranch:
- case ARM::fixup_t2_uncondbranch:
- case ARM::fixup_t2_pcrel_10:
- case ARM::fixup_t2_adr_pcrel_12:
- case ARM::fixup_arm_thumb_bl:
- case ARM::fixup_arm_thumb_blx:
- case ARM::fixup_arm_movt_hi16:
- case ARM::fixup_arm_movw_lo16:
- case ARM::fixup_arm_movt_hi16_pcrel:
- case ARM::fixup_arm_movw_lo16_pcrel:
- case ARM::fixup_t2_movt_hi16:
- case ARM::fixup_t2_movw_lo16:
- case ARM::fixup_t2_movt_hi16_pcrel:
- case ARM::fixup_t2_movw_lo16_pcrel:
- return 4;
- }
-}
-
-void DarwinARMAsmBackend::ApplyFixup(const MCFixup &Fixup, char *Data,
- unsigned DataSize, uint64_t Value) const {
- unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind());
- Value = adjustFixupValue(Fixup.getKind(), Value);
- if (!Value) return; // Doesn't change encoding.
-
- unsigned Offset = Fixup.getOffset();
- assert(Offset + NumBytes <= DataSize && "Invalid fixup offset!");
-
- // For each byte of the fragment that the fixup touches, mask in the
- // bits from the fixup value.
- for (unsigned i = 0; i != NumBytes; ++i)
- Data[Offset + i] |= uint8_t((Value >> (i * 8)) & 0xff);
-}
-
-} // end anonymous namespace
-
-TargetAsmBackend *llvm::createARMAsmBackend(const Target &T,
- const std::string &TT) {
- Triple TheTriple(TT);
-
- if (TheTriple.isOSDarwin()) {
- if (TheTriple.getArchName() == "armv4t" ||
- TheTriple.getArchName() == "thumbv4t")
- return new DarwinARMAsmBackend(T, object::mach::CSARM_V4T);
- else if (TheTriple.getArchName() == "armv5e" ||
- TheTriple.getArchName() == "thumbv5e")
- return new DarwinARMAsmBackend(T, object::mach::CSARM_V5TEJ);
- else if (TheTriple.getArchName() == "armv6" ||
- TheTriple.getArchName() == "thumbv6")
- return new DarwinARMAsmBackend(T, object::mach::CSARM_V6);
- return new DarwinARMAsmBackend(T, object::mach::CSARM_V7);
- }
-
- if (TheTriple.isOSWindows())
- assert(0 && "Windows not supported on ARM");
-
- return new ELFARMAsmBackend(T, Triple(TT).getOS());
-}
Removed: llvm/trunk/lib/Target/ARM/ARMBaseInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInfo.h?rev=135824&view=auto
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMBaseInfo.h (original)
+++ llvm/trunk/lib/Target/ARM/ARMBaseInfo.h (removed)
@@ -1,433 +0,0 @@
-//===-- ARMBaseInfo.h - Top level definitions for ARM -------- --*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains small standalone helper functions and enum definitions for
-// the ARM target useful for the compiler back-end and the MC libraries.
-// As such, it deliberately does not include references to LLVM core
-// code gen types, passes, etc..
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef ARMBASEINFO_H
-#define ARMBASEINFO_H
-
-#include "MCTargetDesc/ARMMCTargetDesc.h"
-#include "llvm/Support/ErrorHandling.h"
-
-// Note that the following auto-generated files only defined enum types, and
-// so are safe to include here.
-
-namespace llvm {
-
-// Enums corresponding to ARM condition codes
-namespace ARMCC {
- // The CondCodes constants map directly to the 4-bit encoding of the
- // condition field for predicated instructions.
- enum CondCodes { // Meaning (integer) Meaning (floating-point)
- EQ, // Equal Equal
- NE, // Not equal Not equal, or unordered
- HS, // Carry set >, ==, or unordered
- LO, // Carry clear Less than
- MI, // Minus, negative Less than
- PL, // Plus, positive or zero >, ==, or unordered
- VS, // Overflow Unordered
- VC, // No overflow Not unordered
- HI, // Unsigned higher Greater than, or unordered
- LS, // Unsigned lower or same Less than or equal
- GE, // Greater than or equal Greater than or equal
- LT, // Less than Less than, or unordered
- GT, // Greater than Greater than
- LE, // Less than or equal <, ==, or unordered
- AL // Always (unconditional) Always (unconditional)
- };
-
- inline static CondCodes getOppositeCondition(CondCodes CC) {
- switch (CC) {
- default: llvm_unreachable("Unknown condition code");
- case EQ: return NE;
- case NE: return EQ;
- case HS: return LO;
- case LO: return HS;
- case MI: return PL;
- case PL: return MI;
- case VS: return VC;
- case VC: return VS;
- case HI: return LS;
- case LS: return HI;
- case GE: return LT;
- case LT: return GE;
- case GT: return LE;
- case LE: return GT;
- }
- }
-} // namespace ARMCC
-
-inline static const char *ARMCondCodeToString(ARMCC::CondCodes CC) {
- switch (CC) {
- default: llvm_unreachable("Unknown condition code");
- case ARMCC::EQ: return "eq";
- case ARMCC::NE: return "ne";
- case ARMCC::HS: return "hs";
- case ARMCC::LO: return "lo";
- case ARMCC::MI: return "mi";
- case ARMCC::PL: return "pl";
- case ARMCC::VS: return "vs";
- case ARMCC::VC: return "vc";
- case ARMCC::HI: return "hi";
- case ARMCC::LS: return "ls";
- case ARMCC::GE: return "ge";
- case ARMCC::LT: return "lt";
- case ARMCC::GT: return "gt";
- case ARMCC::LE: return "le";
- case ARMCC::AL: return "al";
- }
-}
-
-namespace ARM_PROC {
- enum IMod {
- IE = 2,
- ID = 3
- };
-
- enum IFlags {
- F = 1,
- I = 2,
- A = 4
- };
-
- inline static const char *IFlagsToString(unsigned val) {
- switch (val) {
- default: llvm_unreachable("Unknown iflags operand");
- case F: return "f";
- case I: return "i";
- case A: return "a";
- }
- }
-
- inline static const char *IModToString(unsigned val) {
- switch (val) {
- default: llvm_unreachable("Unknown imod operand");
- case IE: return "ie";
- case ID: return "id";
- }
- }
-}
-
-namespace ARM_MB {
- // The Memory Barrier Option constants map directly to the 4-bit encoding of
- // the option field for memory barrier operations.
- enum MemBOpt {
- SY = 15,
- ST = 14,
- ISH = 11,
- ISHST = 10,
- NSH = 7,
- NSHST = 6,
- OSH = 3,
- OSHST = 2
- };
-
- inline static const char *MemBOptToString(unsigned val) {
- switch (val) {
- default: llvm_unreachable("Unknown memory operation");
- case SY: return "sy";
- case ST: return "st";
- case ISH: return "ish";
- case ISHST: return "ishst";
- case NSH: return "nsh";
- case NSHST: return "nshst";
- case OSH: return "osh";
- case OSHST: return "oshst";
- }
- }
-} // namespace ARM_MB
-
-/// getARMRegisterNumbering - Given the enum value for some register, e.g.
-/// ARM::LR, return the number that it corresponds to (e.g. 14).
-inline static unsigned getARMRegisterNumbering(unsigned Reg) {
- using namespace ARM;
- switch (Reg) {
- default:
- llvm_unreachable("Unknown ARM register!");
- case R0: case S0: case D0: case Q0: return 0;
- case R1: case S1: case D1: case Q1: return 1;
- case R2: case S2: case D2: case Q2: return 2;
- case R3: case S3: case D3: case Q3: return 3;
- case R4: case S4: case D4: case Q4: return 4;
- case R5: case S5: case D5: case Q5: return 5;
- case R6: case S6: case D6: case Q6: return 6;
- case R7: case S7: case D7: case Q7: return 7;
- case R8: case S8: case D8: case Q8: return 8;
- case R9: case S9: case D9: case Q9: return 9;
- case R10: case S10: case D10: case Q10: return 10;
- case R11: case S11: case D11: case Q11: return 11;
- case R12: case S12: case D12: case Q12: return 12;
- case SP: case S13: case D13: case Q13: return 13;
- case LR: case S14: case D14: case Q14: return 14;
- case PC: case S15: case D15: case Q15: return 15;
-
- case S16: case D16: return 16;
- case S17: case D17: return 17;
- case S18: case D18: return 18;
- case S19: case D19: return 19;
- case S20: case D20: return 20;
- case S21: case D21: return 21;
- case S22: case D22: return 22;
- case S23: case D23: return 23;
- case S24: case D24: return 24;
- case S25: case D25: return 25;
- case S26: case D26: return 26;
- case S27: case D27: return 27;
- case S28: case D28: return 28;
- case S29: case D29: return 29;
- case S30: case D30: return 30;
- case S31: case D31: return 31;
- }
-}
-
-/// ARMII - This namespace holds all of the target specific flags that
-/// instruction info tracks.
-///
-namespace ARMII {
-
- /// ARM Index Modes
- enum IndexMode {
- IndexModeNone = 0,
- IndexModePre = 1,
- IndexModePost = 2,
- IndexModeUpd = 3
- };
-
- /// ARM Addressing Modes
- enum AddrMode {
- AddrModeNone = 0,
- AddrMode1 = 1,
- AddrMode2 = 2,
- AddrMode3 = 3,
- AddrMode4 = 4,
- AddrMode5 = 5,
- AddrMode6 = 6,
- AddrModeT1_1 = 7,
- AddrModeT1_2 = 8,
- AddrModeT1_4 = 9,
- AddrModeT1_s = 10, // i8 * 4 for pc and sp relative data
- AddrModeT2_i12 = 11,
- AddrModeT2_i8 = 12,
- AddrModeT2_so = 13,
- AddrModeT2_pc = 14, // +/- i12 for pc relative data
- AddrModeT2_i8s4 = 15, // i8 * 4
- AddrMode_i12 = 16
- };
-
- inline static const char *AddrModeToString(AddrMode addrmode) {
- switch (addrmode) {
- default: llvm_unreachable("Unknown memory operation");
- case AddrModeNone: return "AddrModeNone";
- case AddrMode1: return "AddrMode1";
- case AddrMode2: return "AddrMode2";
- case AddrMode3: return "AddrMode3";
- case AddrMode4: return "AddrMode4";
- case AddrMode5: return "AddrMode5";
- case AddrMode6: return "AddrMode6";
- case AddrModeT1_1: return "AddrModeT1_1";
- case AddrModeT1_2: return "AddrModeT1_2";
- case AddrModeT1_4: return "AddrModeT1_4";
- case AddrModeT1_s: return "AddrModeT1_s";
- case AddrModeT2_i12: return "AddrModeT2_i12";
- case AddrModeT2_i8: return "AddrModeT2_i8";
- case AddrModeT2_so: return "AddrModeT2_so";
- case AddrModeT2_pc: return "AddrModeT2_pc";
- case AddrModeT2_i8s4: return "AddrModeT2_i8s4";
- case AddrMode_i12: return "AddrMode_i12";
- }
- }
-
- /// Target Operand Flag enum.
- enum TOF {
- //===------------------------------------------------------------------===//
- // ARM Specific MachineOperand flags.
-
- MO_NO_FLAG,
-
- /// MO_LO16 - On a symbol operand, this represents a relocation containing
- /// lower 16 bit of the address. Used only via movw instruction.
- MO_LO16,
-
- /// MO_HI16 - On a symbol operand, this represents a relocation containing
- /// higher 16 bit of the address. Used only via movt instruction.
- MO_HI16,
-
- /// MO_LO16_NONLAZY - On a symbol operand "FOO", this represents a
- /// relocation containing lower 16 bit of the non-lazy-ptr indirect symbol,
- /// i.e. "FOO$non_lazy_ptr".
- /// Used only via movw instruction.
- MO_LO16_NONLAZY,
-
- /// MO_HI16_NONLAZY - On a symbol operand "FOO", this represents a
- /// relocation containing lower 16 bit of the non-lazy-ptr indirect symbol,
- /// i.e. "FOO$non_lazy_ptr". Used only via movt instruction.
- MO_HI16_NONLAZY,
-
- /// MO_LO16_NONLAZY_PIC - On a symbol operand "FOO", this represents a
- /// relocation containing lower 16 bit of the PC relative address of the
- /// non-lazy-ptr indirect symbol, i.e. "FOO$non_lazy_ptr - LABEL".
- /// Used only via movw instruction.
- MO_LO16_NONLAZY_PIC,
-
- /// MO_HI16_NONLAZY_PIC - On a symbol operand "FOO", this represents a
- /// relocation containing lower 16 bit of the PC relative address of the
- /// non-lazy-ptr indirect symbol, i.e. "FOO$non_lazy_ptr - LABEL".
- /// Used only via movt instruction.
- MO_HI16_NONLAZY_PIC,
-
- /// MO_PLT - On a symbol operand, this represents an ELF PLT reference on a
- /// call operand.
- MO_PLT
- };
-
- enum {
- //===------------------------------------------------------------------===//
- // Instruction Flags.
-
- //===------------------------------------------------------------------===//
- // This four-bit field describes the addressing mode used.
- AddrModeMask = 0x1f, // The AddrMode enums are declared in ARMBaseInfo.h
-
- // IndexMode - Unindex, pre-indexed, or post-indexed are valid for load
- // and store ops only. Generic "updating" flag is used for ld/st multiple.
- // The index mode enums are declared in ARMBaseInfo.h
- IndexModeShift = 5,
- IndexModeMask = 3 << IndexModeShift,
-
- //===------------------------------------------------------------------===//
- // Instruction encoding formats.
- //
- FormShift = 7,
- FormMask = 0x3f << FormShift,
-
- // Pseudo instructions
- Pseudo = 0 << FormShift,
-
- // Multiply instructions
- MulFrm = 1 << FormShift,
-
- // Branch instructions
- BrFrm = 2 << FormShift,
- BrMiscFrm = 3 << FormShift,
-
- // Data Processing instructions
- DPFrm = 4 << FormShift,
- DPSoRegFrm = 5 << FormShift,
-
- // Load and Store
- LdFrm = 6 << FormShift,
- StFrm = 7 << FormShift,
- LdMiscFrm = 8 << FormShift,
- StMiscFrm = 9 << FormShift,
- LdStMulFrm = 10 << FormShift,
-
- LdStExFrm = 11 << FormShift,
-
- // Miscellaneous arithmetic instructions
- ArithMiscFrm = 12 << FormShift,
- SatFrm = 13 << FormShift,
-
- // Extend instructions
- ExtFrm = 14 << FormShift,
-
- // VFP formats
- VFPUnaryFrm = 15 << FormShift,
- VFPBinaryFrm = 16 << FormShift,
- VFPConv1Frm = 17 << FormShift,
- VFPConv2Frm = 18 << FormShift,
- VFPConv3Frm = 19 << FormShift,
- VFPConv4Frm = 20 << FormShift,
- VFPConv5Frm = 21 << FormShift,
- VFPLdStFrm = 22 << FormShift,
- VFPLdStMulFrm = 23 << FormShift,
- VFPMiscFrm = 24 << FormShift,
-
- // Thumb format
- ThumbFrm = 25 << FormShift,
-
- // Miscelleaneous format
- MiscFrm = 26 << FormShift,
-
- // NEON formats
- NGetLnFrm = 27 << FormShift,
- NSetLnFrm = 28 << FormShift,
- NDupFrm = 29 << FormShift,
- NLdStFrm = 30 << FormShift,
- N1RegModImmFrm= 31 << FormShift,
- N2RegFrm = 32 << FormShift,
- NVCVTFrm = 33 << FormShift,
- NVDupLnFrm = 34 << FormShift,
- N2RegVShLFrm = 35 << FormShift,
- N2RegVShRFrm = 36 << FormShift,
- N3RegFrm = 37 << FormShift,
- N3RegVShFrm = 38 << FormShift,
- NVExtFrm = 39 << FormShift,
- NVMulSLFrm = 40 << FormShift,
- NVTBLFrm = 41 << FormShift,
-
- //===------------------------------------------------------------------===//
- // Misc flags.
-
- // UnaryDP - Indicates this is a unary data processing instruction, i.e.
- // it doesn't have a Rn operand.
- UnaryDP = 1 << 13,
-
- // Xform16Bit - Indicates this Thumb2 instruction may be transformed into
- // a 16-bit Thumb instruction if certain conditions are met.
- Xform16Bit = 1 << 14,
-
- //===------------------------------------------------------------------===//
- // Code domain.
- DomainShift = 15,
- DomainMask = 7 << DomainShift,
- DomainGeneral = 0 << DomainShift,
- DomainVFP = 1 << DomainShift,
- DomainNEON = 2 << DomainShift,
- DomainNEONA8 = 4 << DomainShift,
-
- //===------------------------------------------------------------------===//
- // Field shifts - such shifts are used to set field while generating
- // machine instructions.
- //
- // FIXME: This list will need adjusting/fixing as the MC code emitter
- // takes shape and the ARMCodeEmitter.cpp bits go away.
- ShiftTypeShift = 4,
-
- M_BitShift = 5,
- ShiftImmShift = 5,
- ShiftShift = 7,
- N_BitShift = 7,
- ImmHiShift = 8,
- SoRotImmShift = 8,
- RegRsShift = 8,
- ExtRotImmShift = 10,
- RegRdLoShift = 12,
- RegRdShift = 12,
- RegRdHiShift = 16,
- RegRnShift = 16,
- S_BitShift = 20,
- W_BitShift = 21,
- AM3_I_BitShift = 22,
- D_BitShift = 22,
- U_BitShift = 23,
- P_BitShift = 24,
- I_BitShift = 25,
- CondShift = 28
- };
-
-} // end namespace ARMII
-
-} // end namespace llvm;
-
-#endif
Removed: llvm/trunk/lib/Target/ARM/ARMFixupKinds.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMFixupKinds.h?rev=135824&view=auto
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMFixupKinds.h (original)
+++ llvm/trunk/lib/Target/ARM/ARMFixupKinds.h (removed)
@@ -1,97 +0,0 @@
-//===-- ARM/ARMFixupKinds.h - ARM Specific Fixup Entries --------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_ARM_ARMFIXUPKINDS_H
-#define LLVM_ARM_ARMFIXUPKINDS_H
-
-#include "llvm/MC/MCFixup.h"
-
-namespace llvm {
-namespace ARM {
-enum Fixups {
- // fixup_arm_ldst_pcrel_12 - 12-bit PC relative relocation for symbol
- // addresses
- fixup_arm_ldst_pcrel_12 = FirstTargetFixupKind,
-
- // fixup_t2_ldst_pcrel_12 - Equivalent to fixup_arm_ldst_pcrel_12, with
- // the 16-bit halfwords reordered.
- fixup_t2_ldst_pcrel_12,
-
- // fixup_arm_pcrel_10 - 10-bit PC relative relocation for symbol addresses
- // used in VFP instructions where the lower 2 bits are not encoded
- // (so it's encoded as an 8-bit immediate).
- fixup_arm_pcrel_10,
- // fixup_t2_pcrel_10 - Equivalent to fixup_arm_pcrel_10, accounting for
- // the short-swapped encoding of Thumb2 instructions.
- fixup_t2_pcrel_10,
- // fixup_thumb_adr_pcrel_10 - 10-bit PC relative relocation for symbol
- // addresses where the lower 2 bits are not encoded (so it's encoded as an
- // 8-bit immediate).
- fixup_thumb_adr_pcrel_10,
- // fixup_arm_adr_pcrel_12 - 12-bit PC relative relocation for the ADR
- // instruction.
- fixup_arm_adr_pcrel_12,
- // fixup_t2_adr_pcrel_12 - 12-bit PC relative relocation for the ADR
- // instruction.
- fixup_t2_adr_pcrel_12,
- // fixup_arm_condbranch - 24-bit PC relative relocation for conditional branch
- // instructions.
- fixup_arm_condbranch,
- // fixup_arm_uncondbranch - 24-bit PC relative relocation for
- // branch instructions. (unconditional)
- fixup_arm_uncondbranch,
- // fixup_t2_condbranch - 20-bit PC relative relocation for Thumb2 direct
- // uconditional branch instructions.
- fixup_t2_condbranch,
- // fixup_t2_uncondbranch - 20-bit PC relative relocation for Thumb2 direct
- // branch unconditional branch instructions.
- fixup_t2_uncondbranch,
-
- // fixup_arm_thumb_br - 12-bit fixup for Thumb B instructions.
- fixup_arm_thumb_br,
-
- // fixup_arm_thumb_bl - Fixup for Thumb BL instructions.
- fixup_arm_thumb_bl,
-
- // fixup_arm_thumb_blx - Fixup for Thumb BLX instructions.
- fixup_arm_thumb_blx,
-
- // fixup_arm_thumb_cb - Fixup for Thumb branch instructions.
- fixup_arm_thumb_cb,
-
- // fixup_arm_thumb_cp - Fixup for Thumb load/store from constant pool instrs.
- fixup_arm_thumb_cp,
-
- // fixup_arm_thumb_bcc - Fixup for Thumb conditional branching instructions.
- fixup_arm_thumb_bcc,
-
- // The next two are for the movt/movw pair
- // the 16bit imm field are split into imm{15-12} and imm{11-0}
- fixup_arm_movt_hi16, // :upper16:
- fixup_arm_movw_lo16, // :lower16:
- fixup_t2_movt_hi16, // :upper16:
- fixup_t2_movw_lo16, // :lower16:
-
- // It is possible to create an "immediate" that happens to be pcrel.
- // movw r0, :lower16:Foo-(Bar+8) and movt r0, :upper16:Foo-(Bar+8)
- // result in different reloc tags than the above two.
- // Needed to support ELF::R_ARM_MOVT_PREL and ELF::R_ARM_MOVW_PREL_NC
- fixup_arm_movt_hi16_pcrel, // :upper16:
- fixup_arm_movw_lo16_pcrel, // :lower16:
- fixup_t2_movt_hi16_pcrel, // :upper16:
- fixup_t2_movw_lo16_pcrel, // :lower16:
-
- // Marker
- LastTargetFixupKind,
- NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
-};
-}
-}
-
-#endif
Removed: llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp?rev=135824&view=auto
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp (removed)
@@ -1,1336 +0,0 @@
-//===-- ARM/ARMMCCodeEmitter.cpp - Convert ARM 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 ARMMCCodeEmitter class.
-//
-//===----------------------------------------------------------------------===//
-
-#define DEBUG_TYPE "mccodeemitter"
-#include "ARM.h"
-#include "ARMFixupKinds.h"
-#include "ARMInstrInfo.h"
-#include "MCTargetDesc/ARMAddressingModes.h"
-#include "MCTargetDesc/ARMMCExpr.h"
-#include "llvm/MC/MCCodeEmitter.h"
-#include "llvm/MC/MCExpr.h"
-#include "llvm/MC/MCInst.h"
-#include "llvm/MC/MCInstrInfo.h"
-#include "llvm/MC/MCSubtargetInfo.h"
-#include "llvm/ADT/APFloat.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/Support/raw_ostream.h"
-
-using namespace llvm;
-
-STATISTIC(MCNumEmitted, "Number of MC instructions emitted.");
-STATISTIC(MCNumCPRelocations, "Number of constant pool relocations created.");
-
-namespace {
-class ARMMCCodeEmitter : public MCCodeEmitter {
- ARMMCCodeEmitter(const ARMMCCodeEmitter &); // DO NOT IMPLEMENT
- void operator=(const ARMMCCodeEmitter &); // DO NOT IMPLEMENT
- const MCInstrInfo &MCII;
- const MCSubtargetInfo &STI;
-
-public:
- ARMMCCodeEmitter(const MCInstrInfo &mcii, const MCSubtargetInfo &sti,
- MCContext &ctx)
- : MCII(mcii), STI(sti) {
- }
-
- ~ARMMCCodeEmitter() {}
-
- bool isThumb() const {
- // FIXME: Can tablegen auto-generate this?
- return (STI.getFeatureBits() & ARM::ModeThumb) != 0;
- }
- bool isThumb2() const {
- return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) != 0;
- }
- bool isTargetDarwin() const {
- Triple TT(STI.getTargetTriple());
- Triple::OSType OS = TT.getOS();
- return OS == Triple::Darwin || OS == Triple::MacOSX || OS == Triple::IOS;
- }
-
- unsigned getMachineSoImmOpValue(unsigned SoImm) const;
-
- // getBinaryCodeForInstr - TableGen'erated function for getting the
- // binary encoding for an instruction.
- unsigned getBinaryCodeForInstr(const MCInst &MI,
- SmallVectorImpl<MCFixup> &Fixups) const;
-
- /// getMachineOpValue - Return binary encoding of operand. If the machine
- /// operand requires relocation, record the relocation and return zero.
- unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO,
- SmallVectorImpl<MCFixup> &Fixups) const;
-
- /// getHiLo16ImmOpValue - Return the encoding for the hi / low 16-bit of
- /// the specified operand. This is used for operands with :lower16: and
- /// :upper16: prefixes.
- uint32_t getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const;
-
- bool EncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx,
- unsigned &Reg, unsigned &Imm,
- SmallVectorImpl<MCFixup> &Fixups) const;
-
- /// getThumbBLTargetOpValue - Return encoding info for Thumb immediate
- /// BL branch target.
- uint32_t getThumbBLTargetOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const;
-
- /// getThumbBLXTargetOpValue - Return encoding info for Thumb immediate
- /// BLX branch target.
- uint32_t getThumbBLXTargetOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const;
-
- /// getThumbBRTargetOpValue - Return encoding info for Thumb branch target.
- uint32_t getThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const;
-
- /// getThumbBCCTargetOpValue - Return encoding info for Thumb branch target.
- uint32_t getThumbBCCTargetOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const;
-
- /// getThumbCBTargetOpValue - Return encoding info for Thumb branch target.
- uint32_t getThumbCBTargetOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const;
-
- /// getBranchTargetOpValue - Return encoding info for 24-bit immediate
- /// branch target.
- uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const;
-
- /// getUnconditionalBranchTargetOpValue - Return encoding info for 24-bit
- /// immediate Thumb2 direct branch target.
- uint32_t getUnconditionalBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const;
-
- /// getARMBranchTargetOpValue - Return encoding info for 24-bit immediate
- /// branch target.
- uint32_t getARMBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const;
-
- /// getAdrLabelOpValue - Return encoding info for 12-bit immediate
- /// ADR label target.
- uint32_t getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const;
- uint32_t getThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const;
- uint32_t getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const;
-
-
- /// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12'
- /// operand.
- uint32_t getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const;
-
- /// getThumbAddrModeRegRegOpValue - Return encoding for 'reg + reg' operand.
- uint32_t getThumbAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups)const;
-
- /// getT2AddrModeImm8s4OpValue - Return encoding info for 'reg +/- imm8<<2'
- /// operand.
- uint32_t getT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const;
-
-
- /// getLdStSORegOpValue - Return encoding info for 'reg +/- reg shop imm'
- /// operand as needed by load/store instructions.
- uint32_t getLdStSORegOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const;
-
- /// getLdStmModeOpValue - Return encoding for load/store multiple mode.
- uint32_t getLdStmModeOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const {
- ARM_AM::AMSubMode Mode = (ARM_AM::AMSubMode)MI.getOperand(OpIdx).getImm();
- switch (Mode) {
- default: assert(0 && "Unknown addressing sub-mode!");
- case ARM_AM::da: return 0;
- case ARM_AM::ia: return 1;
- case ARM_AM::db: return 2;
- case ARM_AM::ib: return 3;
- }
- }
- /// getShiftOp - Return the shift opcode (bit[6:5]) of the immediate value.
- ///
- unsigned getShiftOp(ARM_AM::ShiftOpc ShOpc) const {
- switch (ShOpc) {
- default: llvm_unreachable("Unknown shift opc!");
- case ARM_AM::no_shift:
- case ARM_AM::lsl: return 0;
- case ARM_AM::lsr: return 1;
- case ARM_AM::asr: return 2;
- case ARM_AM::ror:
- case ARM_AM::rrx: return 3;
- }
- return 0;
- }
-
- /// getAddrMode2OpValue - Return encoding for addrmode2 operands.
- uint32_t getAddrMode2OpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const;
-
- /// getAddrMode2OffsetOpValue - Return encoding for am2offset operands.
- uint32_t getAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const;
-
- /// getAddrMode3OffsetOpValue - Return encoding for am3offset operands.
- uint32_t getAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const;
-
- /// getAddrMode3OpValue - Return encoding for addrmode3 operands.
- uint32_t getAddrMode3OpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const;
-
- /// getAddrModeThumbSPOpValue - Return encoding info for 'reg +/- imm12'
- /// operand.
- uint32_t getAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const;
-
- /// getAddrModeISOpValue - Encode the t_addrmode_is# operands.
- uint32_t getAddrModeISOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const;
-
- /// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands.
- uint32_t getAddrModePCOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const;
-
- /// getAddrMode5OpValue - Return encoding info for 'reg +/- imm8' operand.
- uint32_t getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const;
-
- /// getCCOutOpValue - Return encoding of the 's' bit.
- unsigned getCCOutOpValue(const MCInst &MI, unsigned Op,
- SmallVectorImpl<MCFixup> &Fixups) const {
- // The operand is either reg0 or CPSR. The 's' bit is encoded as '0' or
- // '1' respectively.
- return MI.getOperand(Op).getReg() == ARM::CPSR;
- }
-
- /// getSOImmOpValue - Return an encoded 12-bit shifted-immediate value.
- unsigned getSOImmOpValue(const MCInst &MI, unsigned Op,
- SmallVectorImpl<MCFixup> &Fixups) const {
- unsigned SoImm = MI.getOperand(Op).getImm();
- int SoImmVal = ARM_AM::getSOImmVal(SoImm);
- assert(SoImmVal != -1 && "Not a valid so_imm value!");
-
- // Encode rotate_imm.
- unsigned Binary = (ARM_AM::getSOImmValRot((unsigned)SoImmVal) >> 1)
- << ARMII::SoRotImmShift;
-
- // Encode immed_8.
- Binary |= ARM_AM::getSOImmValImm((unsigned)SoImmVal);
- return Binary;
- }
-
- /// getT2SOImmOpValue - Return an encoded 12-bit shifted-immediate value.
- unsigned getT2SOImmOpValue(const MCInst &MI, unsigned Op,
- SmallVectorImpl<MCFixup> &Fixups) const {
- unsigned SoImm = MI.getOperand(Op).getImm();
- unsigned Encoded = ARM_AM::getT2SOImmVal(SoImm);
- assert(Encoded != ~0U && "Not a Thumb2 so_imm value?");
- return Encoded;
- }
-
- unsigned getT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum,
- SmallVectorImpl<MCFixup> &Fixups) const;
- unsigned getT2AddrModeImm8OpValue(const MCInst &MI, unsigned OpNum,
- SmallVectorImpl<MCFixup> &Fixups) const;
- unsigned getT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum,
- SmallVectorImpl<MCFixup> &Fixups) const;
- unsigned getT2AddrModeImm12OffsetOpValue(const MCInst &MI, unsigned OpNum,
- SmallVectorImpl<MCFixup> &Fixups) const;
-
- /// getSORegOpValue - Return an encoded so_reg shifted register value.
- unsigned getSORegRegOpValue(const MCInst &MI, unsigned Op,
- SmallVectorImpl<MCFixup> &Fixups) const;
- unsigned getSORegImmOpValue(const MCInst &MI, unsigned Op,
- SmallVectorImpl<MCFixup> &Fixups) const;
- unsigned getT2SORegOpValue(const MCInst &MI, unsigned Op,
- SmallVectorImpl<MCFixup> &Fixups) const;
-
- unsigned getRotImmOpValue(const MCInst &MI, unsigned Op,
- SmallVectorImpl<MCFixup> &Fixups) const {
- switch (MI.getOperand(Op).getImm()) {
- default: assert (0 && "Not a valid rot_imm value!");
- case 0: return 0;
- case 8: return 1;
- case 16: return 2;
- case 24: return 3;
- }
- }
-
- unsigned getImmMinusOneOpValue(const MCInst &MI, unsigned Op,
- SmallVectorImpl<MCFixup> &Fixups) const {
- return MI.getOperand(Op).getImm() - 1;
- }
-
- unsigned getNEONVcvtImm32OpValue(const MCInst &MI, unsigned Op,
- SmallVectorImpl<MCFixup> &Fixups) const {
- return 64 - MI.getOperand(Op).getImm();
- }
-
- unsigned getBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op,
- SmallVectorImpl<MCFixup> &Fixups) const;
-
- unsigned getMsbOpValue(const MCInst &MI, unsigned Op,
- SmallVectorImpl<MCFixup> &Fixups) const;
-
- unsigned getSsatBitPosValue(const MCInst &MI, unsigned Op,
- SmallVectorImpl<MCFixup> &Fixups) const;
-
- unsigned getRegisterListOpValue(const MCInst &MI, unsigned Op,
- SmallVectorImpl<MCFixup> &Fixups) const;
- unsigned getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op,
- SmallVectorImpl<MCFixup> &Fixups) const;
- unsigned getAddrMode6OneLane32AddressOpValue(const MCInst &MI, unsigned Op,
- SmallVectorImpl<MCFixup> &Fixups) const;
- unsigned getAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op,
- SmallVectorImpl<MCFixup> &Fixups) const;
- unsigned getAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op,
- SmallVectorImpl<MCFixup> &Fixups) const;
-
- unsigned getShiftRight8Imm(const MCInst &MI, unsigned Op,
- SmallVectorImpl<MCFixup> &Fixups) const;
- unsigned getShiftRight16Imm(const MCInst &MI, unsigned Op,
- SmallVectorImpl<MCFixup> &Fixups) const;
- unsigned getShiftRight32Imm(const MCInst &MI, unsigned Op,
- SmallVectorImpl<MCFixup> &Fixups) const;
- unsigned getShiftRight64Imm(const MCInst &MI, unsigned Op,
- SmallVectorImpl<MCFixup> &Fixups) const;
-
- unsigned NEONThumb2DataIPostEncoder(const MCInst &MI,
- unsigned EncodedValue) const;
- unsigned NEONThumb2LoadStorePostEncoder(const MCInst &MI,
- unsigned EncodedValue) const;
- unsigned NEONThumb2DupPostEncoder(const MCInst &MI,
- unsigned EncodedValue) const;
-
- unsigned VFPThumb2PostEncoder(const MCInst &MI,
- unsigned EncodedValue) const;
-
- void EmitByte(unsigned char C, raw_ostream &OS) const {
- OS << (char)C;
- }
-
- void EmitConstant(uint64_t Val, unsigned Size, raw_ostream &OS) const {
- // Output the constant in little endian byte order.
- for (unsigned i = 0; i != Size; ++i) {
- EmitByte(Val & 255, OS);
- Val >>= 8;
- }
- }
-
- void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
- SmallVectorImpl<MCFixup> &Fixups) const;
-};
-
-} // end anonymous namespace
-
-MCCodeEmitter *llvm::createARMMCCodeEmitter(const MCInstrInfo &MCII,
- const MCSubtargetInfo &STI,
- MCContext &Ctx) {
- return new ARMMCCodeEmitter(MCII, STI, Ctx);
-}
-
-/// NEONThumb2DataIPostEncoder - Post-process encoded NEON data-processing
-/// instructions, and rewrite them to their Thumb2 form if we are currently in
-/// Thumb2 mode.
-unsigned ARMMCCodeEmitter::NEONThumb2DataIPostEncoder(const MCInst &MI,
- unsigned EncodedValue) const {
- if (isThumb2()) {
- // NEON Thumb2 data-processsing encodings are very simple: bit 24 is moved
- // to bit 12 of the high half-word (i.e. bit 28), and bits 27-24 are
- // set to 1111.
- unsigned Bit24 = EncodedValue & 0x01000000;
- unsigned Bit28 = Bit24 << 4;
- EncodedValue &= 0xEFFFFFFF;
- EncodedValue |= Bit28;
- EncodedValue |= 0x0F000000;
- }
-
- return EncodedValue;
-}
-
-/// NEONThumb2LoadStorePostEncoder - Post-process encoded NEON load/store
-/// instructions, and rewrite them to their Thumb2 form if we are currently in
-/// Thumb2 mode.
-unsigned ARMMCCodeEmitter::NEONThumb2LoadStorePostEncoder(const MCInst &MI,
- unsigned EncodedValue) const {
- if (isThumb2()) {
- EncodedValue &= 0xF0FFFFFF;
- EncodedValue |= 0x09000000;
- }
-
- return EncodedValue;
-}
-
-/// NEONThumb2DupPostEncoder - Post-process encoded NEON vdup
-/// instructions, and rewrite them to their Thumb2 form if we are currently in
-/// Thumb2 mode.
-unsigned ARMMCCodeEmitter::NEONThumb2DupPostEncoder(const MCInst &MI,
- unsigned EncodedValue) const {
- if (isThumb2()) {
- EncodedValue &= 0x00FFFFFF;
- EncodedValue |= 0xEE000000;
- }
-
- return EncodedValue;
-}
-
-/// VFPThumb2PostEncoder - Post-process encoded VFP instructions and rewrite
-/// them to their Thumb2 form if we are currently in Thumb2 mode.
-unsigned ARMMCCodeEmitter::
-VFPThumb2PostEncoder(const MCInst &MI, unsigned EncodedValue) const {
- if (isThumb2()) {
- EncodedValue &= 0x0FFFFFFF;
- EncodedValue |= 0xE0000000;
- }
- return EncodedValue;
-}
-
-/// getMachineOpValue - Return binary encoding of operand. If the machine
-/// operand requires relocation, record the relocation and return zero.
-unsigned ARMMCCodeEmitter::
-getMachineOpValue(const MCInst &MI, const MCOperand &MO,
- SmallVectorImpl<MCFixup> &Fixups) const {
- if (MO.isReg()) {
- unsigned Reg = MO.getReg();
- unsigned RegNo = getARMRegisterNumbering(Reg);
-
- // Q registers are encoded as 2x their register number.
- switch (Reg) {
- default:
- return RegNo;
- case ARM::Q0: case ARM::Q1: case ARM::Q2: case ARM::Q3:
- case ARM::Q4: case ARM::Q5: case ARM::Q6: case ARM::Q7:
- case ARM::Q8: case ARM::Q9: case ARM::Q10: case ARM::Q11:
- case ARM::Q12: case ARM::Q13: case ARM::Q14: case ARM::Q15:
- return 2 * RegNo;
- }
- } else if (MO.isImm()) {
- return static_cast<unsigned>(MO.getImm());
- } else if (MO.isFPImm()) {
- return static_cast<unsigned>(APFloat(MO.getFPImm())
- .bitcastToAPInt().getHiBits(32).getLimitedValue());
- }
-
- llvm_unreachable("Unable to encode MCOperand!");
- return 0;
-}
-
-/// getAddrModeImmOpValue - Return encoding info for 'reg +/- imm' operand.
-bool ARMMCCodeEmitter::
-EncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx, unsigned &Reg,
- unsigned &Imm, SmallVectorImpl<MCFixup> &Fixups) const {
- const MCOperand &MO = MI.getOperand(OpIdx);
- const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
-
- Reg = getARMRegisterNumbering(MO.getReg());
-
- int32_t SImm = MO1.getImm();
- bool isAdd = true;
-
- // Special value for #-0
- if (SImm == INT32_MIN)
- SImm = 0;
-
- // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
- if (SImm < 0) {
- SImm = -SImm;
- isAdd = false;
- }
-
- Imm = SImm;
- return isAdd;
-}
-
-/// getBranchTargetOpValue - Helper function to get the branch target operand,
-/// which is either an immediate or requires a fixup.
-static uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
- unsigned FixupKind,
- SmallVectorImpl<MCFixup> &Fixups) {
- const MCOperand &MO = MI.getOperand(OpIdx);
-
- // If the destination is an immediate, we have nothing to do.
- if (MO.isImm()) return MO.getImm();
- assert(MO.isExpr() && "Unexpected branch target type!");
- const MCExpr *Expr = MO.getExpr();
- MCFixupKind Kind = MCFixupKind(FixupKind);
- Fixups.push_back(MCFixup::Create(0, Expr, Kind));
-
- // All of the information is in the fixup.
- return 0;
-}
-
-/// getThumbBLTargetOpValue - Return encoding info for immediate branch target.
-uint32_t ARMMCCodeEmitter::
-getThumbBLTargetOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const {
- return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_bl, Fixups);
-}
-
-/// getThumbBLXTargetOpValue - Return encoding info for Thumb immediate
-/// BLX branch target.
-uint32_t ARMMCCodeEmitter::
-getThumbBLXTargetOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const {
- return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_blx, Fixups);
-}
-
-/// getThumbBRTargetOpValue - Return encoding info for Thumb branch target.
-uint32_t ARMMCCodeEmitter::
-getThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const {
- return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_br, Fixups);
-}
-
-/// getThumbBCCTargetOpValue - Return encoding info for Thumb branch target.
-uint32_t ARMMCCodeEmitter::
-getThumbBCCTargetOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const {
- return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_bcc, Fixups);
-}
-
-/// getThumbCBTargetOpValue - Return encoding info for Thumb branch target.
-uint32_t ARMMCCodeEmitter::
-getThumbCBTargetOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const {
- return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_cb, Fixups);
-}
-
-/// Return true if this branch has a non-always predication
-static bool HasConditionalBranch(const MCInst &MI) {
- int NumOp = MI.getNumOperands();
- if (NumOp >= 2) {
- for (int i = 0; i < NumOp-1; ++i) {
- const MCOperand &MCOp1 = MI.getOperand(i);
- const MCOperand &MCOp2 = MI.getOperand(i + 1);
- if (MCOp1.isImm() && MCOp2.isReg() &&
- (MCOp2.getReg() == 0 || MCOp2.getReg() == ARM::CPSR)) {
- if (ARMCC::CondCodes(MCOp1.getImm()) != ARMCC::AL)
- return true;
- }
- }
- }
- return false;
-}
-
-/// getBranchTargetOpValue - Return encoding info for 24-bit immediate branch
-/// target.
-uint32_t ARMMCCodeEmitter::
-getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const {
- // FIXME: This really, really shouldn't use TargetMachine. We don't want
- // coupling between MC and TM anywhere we can help it.
- if (isThumb2())
- return
- ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_condbranch, Fixups);
- return getARMBranchTargetOpValue(MI, OpIdx, Fixups);
-}
-
-/// getBranchTargetOpValue - Return encoding info for 24-bit immediate branch
-/// target.
-uint32_t ARMMCCodeEmitter::
-getARMBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const {
- if (HasConditionalBranch(MI))
- return ::getBranchTargetOpValue(MI, OpIdx,
- ARM::fixup_arm_condbranch, Fixups);
- return ::getBranchTargetOpValue(MI, OpIdx,
- ARM::fixup_arm_uncondbranch, Fixups);
-}
-
-
-
-
-/// getUnconditionalBranchTargetOpValue - Return encoding info for 24-bit
-/// immediate branch target.
-uint32_t ARMMCCodeEmitter::
-getUnconditionalBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const {
- unsigned Val =
- ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_uncondbranch, Fixups);
- bool I = (Val & 0x800000);
- bool J1 = (Val & 0x400000);
- bool J2 = (Val & 0x200000);
- if (I ^ J1)
- Val &= ~0x400000;
- else
- Val |= 0x400000;
-
- if (I ^ J2)
- Val &= ~0x200000;
- else
- Val |= 0x200000;
-
- return Val;
-}
-
-/// getAdrLabelOpValue - Return encoding info for 12-bit immediate ADR label
-/// target.
-uint32_t ARMMCCodeEmitter::
-getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const {
- assert(MI.getOperand(OpIdx).isExpr() && "Unexpected adr target type!");
- return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_adr_pcrel_12,
- Fixups);
-}
-
-/// getAdrLabelOpValue - Return encoding info for 12-bit immediate ADR label
-/// target.
-uint32_t ARMMCCodeEmitter::
-getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const {
- assert(MI.getOperand(OpIdx).isExpr() && "Unexpected adr target type!");
- return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_adr_pcrel_12,
- Fixups);
-}
-
-/// getAdrLabelOpValue - Return encoding info for 8-bit immediate ADR label
-/// target.
-uint32_t ARMMCCodeEmitter::
-getThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const {
- assert(MI.getOperand(OpIdx).isExpr() && "Unexpected adr target type!");
- return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_thumb_adr_pcrel_10,
- Fixups);
-}
-
-/// getThumbAddrModeRegRegOpValue - Return encoding info for 'reg + reg'
-/// operand.
-uint32_t ARMMCCodeEmitter::
-getThumbAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &) const {
- // [Rn, Rm]
- // {5-3} = Rm
- // {2-0} = Rn
- const MCOperand &MO1 = MI.getOperand(OpIdx);
- const MCOperand &MO2 = MI.getOperand(OpIdx + 1);
- unsigned Rn = getARMRegisterNumbering(MO1.getReg());
- unsigned Rm = getARMRegisterNumbering(MO2.getReg());
- return (Rm << 3) | Rn;
-}
-
-/// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' operand.
-uint32_t ARMMCCodeEmitter::
-getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const {
- // {17-13} = reg
- // {12} = (U)nsigned (add == '1', sub == '0')
- // {11-0} = imm12
- unsigned Reg, Imm12;
- bool isAdd = true;
- // If The first operand isn't a register, we have a label reference.
- const MCOperand &MO = MI.getOperand(OpIdx);
- if (!MO.isReg()) {
- Reg = getARMRegisterNumbering(ARM::PC); // Rn is PC.
- Imm12 = 0;
- isAdd = false ; // 'U' bit is set as part of the fixup.
-
- assert(MO.isExpr() && "Unexpected machine operand type!");
- const MCExpr *Expr = MO.getExpr();
-
- MCFixupKind Kind;
- if (isThumb2())
- Kind = MCFixupKind(ARM::fixup_t2_ldst_pcrel_12);
- else
- Kind = MCFixupKind(ARM::fixup_arm_ldst_pcrel_12);
- Fixups.push_back(MCFixup::Create(0, Expr, Kind));
-
- ++MCNumCPRelocations;
- } else
- isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm12, Fixups);
-
- uint32_t Binary = Imm12 & 0xfff;
- // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
- if (isAdd)
- Binary |= (1 << 12);
- Binary |= (Reg << 13);
- return Binary;
-}
-
-/// getT2AddrModeImm8s4OpValue - Return encoding info for
-/// 'reg +/- imm8<<2' operand.
-uint32_t ARMMCCodeEmitter::
-getT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const {
- // {12-9} = reg
- // {8} = (U)nsigned (add == '1', sub == '0')
- // {7-0} = imm8
- unsigned Reg, Imm8;
- bool isAdd = true;
- // If The first operand isn't a register, we have a label reference.
- const MCOperand &MO = MI.getOperand(OpIdx);
- if (!MO.isReg()) {
- Reg = getARMRegisterNumbering(ARM::PC); // Rn is PC.
- Imm8 = 0;
- isAdd = false ; // 'U' bit is set as part of the fixup.
-
- assert(MO.isExpr() && "Unexpected machine operand type!");
- const MCExpr *Expr = MO.getExpr();
- MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_pcrel_10);
- Fixups.push_back(MCFixup::Create(0, Expr, Kind));
-
- ++MCNumCPRelocations;
- } else
- isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups);
-
- uint32_t Binary = (Imm8 >> 2) & 0xff;
- // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
- if (isAdd)
- Binary |= (1 << 8);
- Binary |= (Reg << 9);
- return Binary;
-}
-
-// FIXME: This routine assumes that a binary
-// expression will always result in a PCRel expression
-// In reality, its only true if one or more subexpressions
-// is itself a PCRel (i.e. "." in asm or some other pcrel construct)
-// but this is good enough for now.
-static bool EvaluateAsPCRel(const MCExpr *Expr) {
- switch (Expr->getKind()) {
- default: assert(0 && "Unexpected expression type");
- case MCExpr::SymbolRef: return false;
- case MCExpr::Binary: return true;
- }
-}
-
-uint32_t
-ARMMCCodeEmitter::getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const {
- // {20-16} = imm{15-12}
- // {11-0} = imm{11-0}
- const MCOperand &MO = MI.getOperand(OpIdx);
- if (MO.isImm())
- // Hi / lo 16 bits already extracted during earlier passes.
- return static_cast<unsigned>(MO.getImm());
-
- // Handle :upper16: and :lower16: assembly prefixes.
- const MCExpr *E = MO.getExpr();
- if (E->getKind() == MCExpr::Target) {
- const ARMMCExpr *ARM16Expr = cast<ARMMCExpr>(E);
- E = ARM16Expr->getSubExpr();
-
- MCFixupKind Kind;
- switch (ARM16Expr->getKind()) {
- default: assert(0 && "Unsupported ARMFixup");
- case ARMMCExpr::VK_ARM_HI16:
- if (!isTargetDarwin() && EvaluateAsPCRel(E))
- Kind = MCFixupKind(isThumb2()
- ? ARM::fixup_t2_movt_hi16_pcrel
- : ARM::fixup_arm_movt_hi16_pcrel);
- else
- Kind = MCFixupKind(isThumb2()
- ? ARM::fixup_t2_movt_hi16
- : ARM::fixup_arm_movt_hi16);
- break;
- case ARMMCExpr::VK_ARM_LO16:
- if (!isTargetDarwin() && EvaluateAsPCRel(E))
- Kind = MCFixupKind(isThumb2()
- ? ARM::fixup_t2_movw_lo16_pcrel
- : ARM::fixup_arm_movw_lo16_pcrel);
- else
- Kind = MCFixupKind(isThumb2()
- ? ARM::fixup_t2_movw_lo16
- : ARM::fixup_arm_movw_lo16);
- break;
- }
- Fixups.push_back(MCFixup::Create(0, E, Kind));
- return 0;
- };
-
- llvm_unreachable("Unsupported MCExpr type in MCOperand!");
- return 0;
-}
-
-uint32_t ARMMCCodeEmitter::
-getLdStSORegOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const {
- const MCOperand &MO = MI.getOperand(OpIdx);
- const MCOperand &MO1 = MI.getOperand(OpIdx+1);
- const MCOperand &MO2 = MI.getOperand(OpIdx+2);
- unsigned Rn = getARMRegisterNumbering(MO.getReg());
- unsigned Rm = getARMRegisterNumbering(MO1.getReg());
- unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm());
- bool isAdd = ARM_AM::getAM2Op(MO2.getImm()) == ARM_AM::add;
- ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(MO2.getImm());
- unsigned SBits = getShiftOp(ShOp);
-
- // {16-13} = Rn
- // {12} = isAdd
- // {11-0} = shifter
- // {3-0} = Rm
- // {4} = 0
- // {6-5} = type
- // {11-7} = imm
- uint32_t Binary = Rm;
- Binary |= Rn << 13;
- Binary |= SBits << 5;
- Binary |= ShImm << 7;
- if (isAdd)
- Binary |= 1 << 12;
- return Binary;
-}
-
-uint32_t ARMMCCodeEmitter::
-getAddrMode2OpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const {
- // {17-14} Rn
- // {13} 1 == imm12, 0 == Rm
- // {12} isAdd
- // {11-0} imm12/Rm
- const MCOperand &MO = MI.getOperand(OpIdx);
- unsigned Rn = getARMRegisterNumbering(MO.getReg());
- uint32_t Binary = getAddrMode2OffsetOpValue(MI, OpIdx + 1, Fixups);
- Binary |= Rn << 14;
- return Binary;
-}
-
-uint32_t ARMMCCodeEmitter::
-getAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const {
- // {13} 1 == imm12, 0 == Rm
- // {12} isAdd
- // {11-0} imm12/Rm
- const MCOperand &MO = MI.getOperand(OpIdx);
- const MCOperand &MO1 = MI.getOperand(OpIdx+1);
- unsigned Imm = MO1.getImm();
- bool isAdd = ARM_AM::getAM2Op(Imm) == ARM_AM::add;
- bool isReg = MO.getReg() != 0;
- uint32_t Binary = ARM_AM::getAM2Offset(Imm);
- // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm12
- if (isReg) {
- ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(Imm);
- Binary <<= 7; // Shift amount is bits [11:7]
- Binary |= getShiftOp(ShOp) << 5; // Shift type is bits [6:5]
- Binary |= getARMRegisterNumbering(MO.getReg()); // Rm is bits [3:0]
- }
- return Binary | (isAdd << 12) | (isReg << 13);
-}
-
-uint32_t ARMMCCodeEmitter::
-getAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const {
- // {9} 1 == imm8, 0 == Rm
- // {8} isAdd
- // {7-4} imm7_4/zero
- // {3-0} imm3_0/Rm
- const MCOperand &MO = MI.getOperand(OpIdx);
- const MCOperand &MO1 = MI.getOperand(OpIdx+1);
- unsigned Imm = MO1.getImm();
- bool isAdd = ARM_AM::getAM3Op(Imm) == ARM_AM::add;
- bool isImm = MO.getReg() == 0;
- uint32_t Imm8 = ARM_AM::getAM3Offset(Imm);
- // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm8
- if (!isImm)
- Imm8 = getARMRegisterNumbering(MO.getReg());
- return Imm8 | (isAdd << 8) | (isImm << 9);
-}
-
-uint32_t ARMMCCodeEmitter::
-getAddrMode3OpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const {
- // {13} 1 == imm8, 0 == Rm
- // {12-9} Rn
- // {8} isAdd
- // {7-4} imm7_4/zero
- // {3-0} imm3_0/Rm
- const MCOperand &MO = MI.getOperand(OpIdx);
- const MCOperand &MO1 = MI.getOperand(OpIdx+1);
- const MCOperand &MO2 = MI.getOperand(OpIdx+2);
- unsigned Rn = getARMRegisterNumbering(MO.getReg());
- unsigned Imm = MO2.getImm();
- bool isAdd = ARM_AM::getAM3Op(Imm) == ARM_AM::add;
- bool isImm = MO1.getReg() == 0;
- uint32_t Imm8 = ARM_AM::getAM3Offset(Imm);
- // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm8
- if (!isImm)
- Imm8 = getARMRegisterNumbering(MO1.getReg());
- return (Rn << 9) | Imm8 | (isAdd << 8) | (isImm << 13);
-}
-
-/// getAddrModeThumbSPOpValue - Encode the t_addrmode_sp operands.
-uint32_t ARMMCCodeEmitter::
-getAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const {
- // [SP, #imm]
- // {7-0} = imm8
- const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
- assert(MI.getOperand(OpIdx).getReg() == ARM::SP &&
- "Unexpected base register!");
-
- // The immediate is already shifted for the implicit zeroes, so no change
- // here.
- return MO1.getImm() & 0xff;
-}
-
-/// getAddrModeISOpValue - Encode the t_addrmode_is# operands.
-uint32_t ARMMCCodeEmitter::
-getAddrModeISOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const {
- // [Rn, #imm]
- // {7-3} = imm5
- // {2-0} = Rn
- const MCOperand &MO = MI.getOperand(OpIdx);
- const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
- unsigned Rn = getARMRegisterNumbering(MO.getReg());
- unsigned Imm5 = MO1.getImm();
- return ((Imm5 & 0x1f) << 3) | Rn;
-}
-
-/// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands.
-uint32_t ARMMCCodeEmitter::
-getAddrModePCOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const {
- return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_cp, Fixups);
-}
-
-/// getAddrMode5OpValue - Return encoding info for 'reg +/- imm10' operand.
-uint32_t ARMMCCodeEmitter::
-getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const {
- // {12-9} = reg
- // {8} = (U)nsigned (add == '1', sub == '0')
- // {7-0} = imm8
- unsigned Reg, Imm8;
- bool isAdd;
- // If The first operand isn't a register, we have a label reference.
- const MCOperand &MO = MI.getOperand(OpIdx);
- if (!MO.isReg()) {
- Reg = getARMRegisterNumbering(ARM::PC); // Rn is PC.
- Imm8 = 0;
- isAdd = false; // 'U' bit is handled as part of the fixup.
-
- assert(MO.isExpr() && "Unexpected machine operand type!");
- const MCExpr *Expr = MO.getExpr();
- MCFixupKind Kind;
- if (isThumb2())
- Kind = MCFixupKind(ARM::fixup_t2_pcrel_10);
- else
- Kind = MCFixupKind(ARM::fixup_arm_pcrel_10);
- Fixups.push_back(MCFixup::Create(0, Expr, Kind));
-
- ++MCNumCPRelocations;
- } else {
- EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups);
- isAdd = ARM_AM::getAM5Op(Imm8) == ARM_AM::add;
- }
-
- uint32_t Binary = ARM_AM::getAM5Offset(Imm8);
- // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
- if (isAdd)
- Binary |= (1 << 8);
- Binary |= (Reg << 9);
- return Binary;
-}
-
-unsigned ARMMCCodeEmitter::
-getSORegRegOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const {
- // Sub-operands are [reg, reg, imm]. The first register is Rm, the reg to be
- // shifted. The second is either Rs, the amount to shift by, or reg0 in which
- // case the imm contains the amount to shift by.
- //
- // {3-0} = Rm.
- // {4} = 1 if reg shift, 0 if imm shift
- // {6-5} = type
- // If reg shift:
- // {11-8} = Rs
- // {7} = 0
- // else (imm shift)
- // {11-7} = imm
-
- const MCOperand &MO = MI.getOperand(OpIdx);
- const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
- const MCOperand &MO2 = MI.getOperand(OpIdx + 2);
- ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO2.getImm());
-
- // Encode Rm.
- unsigned Binary = getARMRegisterNumbering(MO.getReg());
-
- // Encode the shift opcode.
- unsigned SBits = 0;
- unsigned Rs = MO1.getReg();
- if (Rs) {
- // Set shift operand (bit[7:4]).
- // LSL - 0001
- // LSR - 0011
- // ASR - 0101
- // ROR - 0111
- switch (SOpc) {
- default: llvm_unreachable("Unknown shift opc!");
- case ARM_AM::lsl: SBits = 0x1; break;
- case ARM_AM::lsr: SBits = 0x3; break;
- case ARM_AM::asr: SBits = 0x5; break;
- case ARM_AM::ror: SBits = 0x7; break;
- }
- }
-
- Binary |= SBits << 4;
-
- // Encode the shift operation Rs or shift_imm (except rrx).
- // Encode Rs bit[11:8].
- assert(ARM_AM::getSORegOffset(MO2.getImm()) == 0);
- return Binary | (getARMRegisterNumbering(Rs) << ARMII::RegRsShift);
-}
-
-unsigned ARMMCCodeEmitter::
-getSORegImmOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const {
- // Sub-operands are [reg, reg, imm]. The first register is Rm, the reg to be
- // shifted. The second is either Rs, the amount to shift by, or reg0 in which
- // case the imm contains the amount to shift by.
- //
- // {3-0} = Rm.
- // {4} = 1 if reg shift, 0 if imm shift
- // {6-5} = type
- // If reg shift:
- // {11-8} = Rs
- // {7} = 0
- // else (imm shift)
- // {11-7} = imm
-
- const MCOperand &MO = MI.getOperand(OpIdx);
- const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
- ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO1.getImm());
-
- // Encode Rm.
- unsigned Binary = getARMRegisterNumbering(MO.getReg());
-
- // Encode the shift opcode.
- unsigned SBits = 0;
-
- // Set shift operand (bit[6:4]).
- // LSL - 000
- // LSR - 010
- // ASR - 100
- // ROR - 110
- // RRX - 110 and bit[11:8] clear.
- switch (SOpc) {
- default: llvm_unreachable("Unknown shift opc!");
- case ARM_AM::lsl: SBits = 0x0; break;
- case ARM_AM::lsr: SBits = 0x2; break;
- case ARM_AM::asr: SBits = 0x4; break;
- case ARM_AM::ror: SBits = 0x6; break;
- case ARM_AM::rrx:
- Binary |= 0x60;
- return Binary;
- }
-
- // Encode shift_imm bit[11:7].
- Binary |= SBits << 4;
- return Binary | ARM_AM::getSORegOffset(MO1.getImm()) << 7;
-}
-
-
-unsigned ARMMCCodeEmitter::
-getT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum,
- SmallVectorImpl<MCFixup> &Fixups) const {
- const MCOperand &MO1 = MI.getOperand(OpNum);
- const MCOperand &MO2 = MI.getOperand(OpNum+1);
- const MCOperand &MO3 = MI.getOperand(OpNum+2);
-
- // Encoded as [Rn, Rm, imm].
- // FIXME: Needs fixup support.
- unsigned Value = getARMRegisterNumbering(MO1.getReg());
- Value <<= 4;
- Value |= getARMRegisterNumbering(MO2.getReg());
- Value <<= 2;
- Value |= MO3.getImm();
-
- return Value;
-}
-
-unsigned ARMMCCodeEmitter::
-getT2AddrModeImm8OpValue(const MCInst &MI, unsigned OpNum,
- SmallVectorImpl<MCFixup> &Fixups) const {
- const MCOperand &MO1 = MI.getOperand(OpNum);
- const MCOperand &MO2 = MI.getOperand(OpNum+1);
-
- // FIXME: Needs fixup support.
- unsigned Value = getARMRegisterNumbering(MO1.getReg());
-
- // Even though the immediate is 8 bits long, we need 9 bits in order
- // to represent the (inverse of the) sign bit.
- Value <<= 9;
- int32_t tmp = (int32_t)MO2.getImm();
- if (tmp < 0)
- tmp = abs(tmp);
- else
- Value |= 256; // Set the ADD bit
- Value |= tmp & 255;
- return Value;
-}
-
-unsigned ARMMCCodeEmitter::
-getT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum,
- SmallVectorImpl<MCFixup> &Fixups) const {
- const MCOperand &MO1 = MI.getOperand(OpNum);
-
- // FIXME: Needs fixup support.
- unsigned Value = 0;
- int32_t tmp = (int32_t)MO1.getImm();
- if (tmp < 0)
- tmp = abs(tmp);
- else
- Value |= 256; // Set the ADD bit
- Value |= tmp & 255;
- return Value;
-}
-
-unsigned ARMMCCodeEmitter::
-getT2AddrModeImm12OffsetOpValue(const MCInst &MI, unsigned OpNum,
- SmallVectorImpl<MCFixup> &Fixups) const {
- const MCOperand &MO1 = MI.getOperand(OpNum);
-
- // FIXME: Needs fixup support.
- unsigned Value = 0;
- int32_t tmp = (int32_t)MO1.getImm();
- if (tmp < 0)
- tmp = abs(tmp);
- else
- Value |= 4096; // Set the ADD bit
- Value |= tmp & 4095;
- return Value;
-}
-
-unsigned ARMMCCodeEmitter::
-getT2SORegOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const {
- // Sub-operands are [reg, imm]. The first register is Rm, the reg to be
- // shifted. The second is the amount to shift by.
- //
- // {3-0} = Rm.
- // {4} = 0
- // {6-5} = type
- // {11-7} = imm
-
- const MCOperand &MO = MI.getOperand(OpIdx);
- const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
- ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO1.getImm());
-
- // Encode Rm.
- unsigned Binary = getARMRegisterNumbering(MO.getReg());
-
- // Encode the shift opcode.
- unsigned SBits = 0;
- // Set shift operand (bit[6:4]).
- // LSL - 000
- // LSR - 010
- // ASR - 100
- // ROR - 110
- switch (SOpc) {
- default: llvm_unreachable("Unknown shift opc!");
- case ARM_AM::lsl: SBits = 0x0; break;
- case ARM_AM::lsr: SBits = 0x2; break;
- case ARM_AM::asr: SBits = 0x4; break;
- case ARM_AM::ror: SBits = 0x6; break;
- }
-
- Binary |= SBits << 4;
- if (SOpc == ARM_AM::rrx)
- return Binary;
-
- // Encode shift_imm bit[11:7].
- return Binary | ARM_AM::getSORegOffset(MO1.getImm()) << 7;
-}
-
-unsigned ARMMCCodeEmitter::
-getBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op,
- SmallVectorImpl<MCFixup> &Fixups) const {
- // 10 bits. lower 5 bits are are the lsb of the mask, high five bits are the
- // msb of the mask.
- const MCOperand &MO = MI.getOperand(Op);
- uint32_t v = ~MO.getImm();
- uint32_t lsb = CountTrailingZeros_32(v);
- uint32_t msb = (32 - CountLeadingZeros_32 (v)) - 1;
- assert (v != 0 && lsb < 32 && msb < 32 && "Illegal bitfield mask!");
- return lsb | (msb << 5);
-}
-
-unsigned ARMMCCodeEmitter::
-getMsbOpValue(const MCInst &MI, unsigned Op,
- SmallVectorImpl<MCFixup> &Fixups) const {
- // MSB - 5 bits.
- uint32_t lsb = MI.getOperand(Op-1).getImm();
- uint32_t width = MI.getOperand(Op).getImm();
- uint32_t msb = lsb+width-1;
- assert (width != 0 && msb < 32 && "Illegal bit width!");
- return msb;
-}
-
-unsigned ARMMCCodeEmitter::
-getRegisterListOpValue(const MCInst &MI, unsigned Op,
- SmallVectorImpl<MCFixup> &Fixups) const {
- // VLDM/VSTM:
- // {12-8} = Vd
- // {7-0} = Number of registers
- //
- // LDM/STM:
- // {15-0} = Bitfield of GPRs.
- unsigned Reg = MI.getOperand(Op).getReg();
- bool SPRRegs = ARM::SPRRegClass.contains(Reg);
- bool DPRRegs = ARM::DPRRegClass.contains(Reg);
-
- unsigned Binary = 0;
-
- if (SPRRegs || DPRRegs) {
- // VLDM/VSTM
- unsigned RegNo = getARMRegisterNumbering(Reg);
- unsigned NumRegs = (MI.getNumOperands() - Op) & 0xff;
- Binary |= (RegNo & 0x1f) << 8;
- if (SPRRegs)
- Binary |= NumRegs;
- else
- Binary |= NumRegs * 2;
- } else {
- for (unsigned I = Op, E = MI.getNumOperands(); I < E; ++I) {
- unsigned RegNo = getARMRegisterNumbering(MI.getOperand(I).getReg());
- Binary |= 1 << RegNo;
- }
- }
-
- return Binary;
-}
-
-/// getAddrMode6AddressOpValue - Encode an addrmode6 register number along
-/// with the alignment operand.
-unsigned ARMMCCodeEmitter::
-getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op,
- SmallVectorImpl<MCFixup> &Fixups) const {
- const MCOperand &Reg = MI.getOperand(Op);
- const MCOperand &Imm = MI.getOperand(Op + 1);
-
- unsigned RegNo = getARMRegisterNumbering(Reg.getReg());
- unsigned Align = 0;
-
- switch (Imm.getImm()) {
- default: break;
- case 2:
- case 4:
- case 8: Align = 0x01; break;
- case 16: Align = 0x02; break;
- case 32: Align = 0x03; break;
- }
-
- return RegNo | (Align << 4);
-}
-
-/// getAddrMode6OneLane32AddressOpValue - Encode an addrmode6 register number
-/// along with the alignment operand for use in VST1 and VLD1 with size 32.
-unsigned ARMMCCodeEmitter::
-getAddrMode6OneLane32AddressOpValue(const MCInst &MI, unsigned Op,
- SmallVectorImpl<MCFixup> &Fixups) const {
- const MCOperand &Reg = MI.getOperand(Op);
- const MCOperand &Imm = MI.getOperand(Op + 1);
-
- unsigned RegNo = getARMRegisterNumbering(Reg.getReg());
- unsigned Align = 0;
-
- switch (Imm.getImm()) {
- default: break;
- case 2:
- case 4:
- case 8:
- case 16: Align = 0x00; break;
- case 32: Align = 0x03; break;
- }
-
- return RegNo | (Align << 4);
-}
-
-
-/// getAddrMode6DupAddressOpValue - Encode an addrmode6 register number and
-/// alignment operand for use in VLD-dup instructions. This is the same as
-/// getAddrMode6AddressOpValue except for the alignment encoding, which is
-/// different for VLD4-dup.
-unsigned ARMMCCodeEmitter::
-getAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op,
- SmallVectorImpl<MCFixup> &Fixups) const {
- const MCOperand &Reg = MI.getOperand(Op);
- const MCOperand &Imm = MI.getOperand(Op + 1);
-
- unsigned RegNo = getARMRegisterNumbering(Reg.getReg());
- unsigned Align = 0;
-
- switch (Imm.getImm()) {
- default: break;
- case 2:
- case 4:
- case 8: Align = 0x01; break;
- case 16: Align = 0x03; break;
- }
-
- return RegNo | (Align << 4);
-}
-
-unsigned ARMMCCodeEmitter::
-getAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op,
- SmallVectorImpl<MCFixup> &Fixups) const {
- const MCOperand &MO = MI.getOperand(Op);
- if (MO.getReg() == 0) return 0x0D;
- return MO.getReg();
-}
-
-unsigned ARMMCCodeEmitter::
-getShiftRight8Imm(const MCInst &MI, unsigned Op,
- SmallVectorImpl<MCFixup> &Fixups) const {
- return 8 - MI.getOperand(Op).getImm();
-}
-
-unsigned ARMMCCodeEmitter::
-getShiftRight16Imm(const MCInst &MI, unsigned Op,
- SmallVectorImpl<MCFixup> &Fixups) const {
- return 16 - MI.getOperand(Op).getImm();
-}
-
-unsigned ARMMCCodeEmitter::
-getShiftRight32Imm(const MCInst &MI, unsigned Op,
- SmallVectorImpl<MCFixup> &Fixups) const {
- return 32 - MI.getOperand(Op).getImm();
-}
-
-unsigned ARMMCCodeEmitter::
-getShiftRight64Imm(const MCInst &MI, unsigned Op,
- SmallVectorImpl<MCFixup> &Fixups) const {
- return 64 - MI.getOperand(Op).getImm();
-}
-
-void ARMMCCodeEmitter::
-EncodeInstruction(const MCInst &MI, raw_ostream &OS,
- SmallVectorImpl<MCFixup> &Fixups) const {
- // Pseudo instructions don't get encoded.
- const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
- uint64_t TSFlags = Desc.TSFlags;
- if ((TSFlags & ARMII::FormMask) == ARMII::Pseudo)
- return;
-
- int Size;
- if (Desc.getSize() == 2 || Desc.getSize() == 4)
- Size = Desc.getSize();
- else
- llvm_unreachable("Unexpected instruction size!");
-
- uint32_t Binary = getBinaryCodeForInstr(MI, Fixups);
- // Thumb 32-bit wide instructions need to emit the high order halfword
- // first.
- if (isThumb() && Size == 4) {
- EmitConstant(Binary >> 16, 2, OS);
- EmitConstant(Binary & 0xffff, 2, OS);
- } else
- EmitConstant(Binary, Size, OS);
- ++MCNumEmitted; // Keep track of the # of mi's emitted.
-}
-
-#include "ARMGenMCCodeEmitter.inc"
Removed: llvm/trunk/lib/Target/ARM/ARMMachObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMMachObjectWriter.cpp?rev=135824&view=auto
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMMachObjectWriter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMMachObjectWriter.cpp (removed)
@@ -1,389 +0,0 @@
-//===-- ARMMachObjectWriter.cpp - ARM Mach Object Writer ------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ARM.h"
-#include "ARMFixupKinds.h"
-#include "llvm/ADT/Twine.h"
-#include "llvm/MC/MCAssembler.h"
-#include "llvm/MC/MCAsmLayout.h"
-#include "llvm/MC/MCMachObjectWriter.h"
-#include "llvm/MC/MCExpr.h"
-#include "llvm/MC/MCFixup.h"
-#include "llvm/MC/MCFixupKindInfo.h"
-#include "llvm/MC/MCValue.h"
-#include "llvm/Object/MachOFormat.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Target/TargetAsmBackend.h"
-using namespace llvm;
-using namespace llvm::object;
-
-namespace {
-class ARMMachObjectWriter : public MCMachObjectTargetWriter {
- void RecordARMScatteredRelocation(MachObjectWriter *Writer,
- const MCAssembler &Asm,
- const MCAsmLayout &Layout,
- const MCFragment *Fragment,
- const MCFixup &Fixup,
- MCValue Target,
- unsigned Log2Size,
- uint64_t &FixedValue);
- void RecordARMMovwMovtRelocation(MachObjectWriter *Writer,
- const MCAssembler &Asm,
- const MCAsmLayout &Layout,
- const MCFragment *Fragment,
- const MCFixup &Fixup, MCValue Target,
- uint64_t &FixedValue);
-
-public:
- ARMMachObjectWriter(bool Is64Bit, uint32_t CPUType,
- uint32_t CPUSubtype)
- : MCMachObjectTargetWriter(Is64Bit, CPUType, CPUSubtype,
- /*UseAggressiveSymbolFolding=*/true) {}
-
- void RecordRelocation(MachObjectWriter *Writer,
- const MCAssembler &Asm, const MCAsmLayout &Layout,
- const MCFragment *Fragment, const MCFixup &Fixup,
- MCValue Target, uint64_t &FixedValue);
-};
-}
-
-static bool getARMFixupKindMachOInfo(unsigned Kind, unsigned &RelocType,
- unsigned &Log2Size) {
- RelocType = unsigned(macho::RIT_Vanilla);
- Log2Size = ~0U;
-
- switch (Kind) {
- default:
- return false;
-
- case FK_Data_1:
- Log2Size = llvm::Log2_32(1);
- return true;
- case FK_Data_2:
- Log2Size = llvm::Log2_32(2);
- return true;
- case FK_Data_4:
- Log2Size = llvm::Log2_32(4);
- return true;
- case FK_Data_8:
- Log2Size = llvm::Log2_32(8);
- return true;
-
- // Handle 24-bit branch kinds.
- case ARM::fixup_arm_ldst_pcrel_12:
- case ARM::fixup_arm_pcrel_10:
- case ARM::fixup_arm_adr_pcrel_12:
- case ARM::fixup_arm_condbranch:
- case ARM::fixup_arm_uncondbranch:
- RelocType = unsigned(macho::RIT_ARM_Branch24Bit);
- // Report as 'long', even though that is not quite accurate.
- Log2Size = llvm::Log2_32(4);
- return true;
-
- // Handle Thumb branches.
- case ARM::fixup_arm_thumb_br:
- RelocType = unsigned(macho::RIT_ARM_ThumbBranch22Bit);
- Log2Size = llvm::Log2_32(2);
- return true;
-
- case ARM::fixup_t2_uncondbranch:
- case ARM::fixup_arm_thumb_bl:
- case ARM::fixup_arm_thumb_blx:
- RelocType = unsigned(macho::RIT_ARM_ThumbBranch22Bit);
- Log2Size = llvm::Log2_32(4);
- return true;
-
- case ARM::fixup_arm_movt_hi16:
- case ARM::fixup_arm_movt_hi16_pcrel:
- case ARM::fixup_t2_movt_hi16:
- case ARM::fixup_t2_movt_hi16_pcrel:
- RelocType = unsigned(macho::RIT_ARM_HalfDifference);
- // Report as 'long', even though that is not quite accurate.
- Log2Size = llvm::Log2_32(4);
- return true;
-
- case ARM::fixup_arm_movw_lo16:
- case ARM::fixup_arm_movw_lo16_pcrel:
- case ARM::fixup_t2_movw_lo16:
- case ARM::fixup_t2_movw_lo16_pcrel:
- RelocType = unsigned(macho::RIT_ARM_Half);
- // Report as 'long', even though that is not quite accurate.
- Log2Size = llvm::Log2_32(4);
- return true;
- }
-}
-
-void ARMMachObjectWriter::
-RecordARMMovwMovtRelocation(MachObjectWriter *Writer,
- const MCAssembler &Asm,
- const MCAsmLayout &Layout,
- const MCFragment *Fragment,
- const MCFixup &Fixup,
- MCValue Target,
- uint64_t &FixedValue) {
- uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset();
- unsigned IsPCRel = Writer->isFixupKindPCRel(Asm, Fixup.getKind());
- unsigned Type = macho::RIT_ARM_Half;
-
- // See <reloc.h>.
- const MCSymbol *A = &Target.getSymA()->getSymbol();
- MCSymbolData *A_SD = &Asm.getSymbolData(*A);
-
- if (!A_SD->getFragment())
- report_fatal_error("symbol '" + A->getName() +
- "' can not be undefined in a subtraction expression");
-
- uint32_t Value = Writer->getSymbolAddress(A_SD, Layout);
- uint32_t Value2 = 0;
- uint64_t SecAddr =
- Writer->getSectionAddress(A_SD->getFragment()->getParent());
- FixedValue += SecAddr;
-
- if (const MCSymbolRefExpr *B = Target.getSymB()) {
- MCSymbolData *B_SD = &Asm.getSymbolData(B->getSymbol());
-
- if (!B_SD->getFragment())
- report_fatal_error("symbol '" + B->getSymbol().getName() +
- "' can not be undefined in a subtraction expression");
-
- // Select the appropriate difference relocation type.
- Type = macho::RIT_ARM_HalfDifference;
- Value2 = Writer->getSymbolAddress(B_SD, Layout);
- FixedValue -= Writer->getSectionAddress(B_SD->getFragment()->getParent());
- }
-
- // Relocations are written out in reverse order, so the PAIR comes first.
- // ARM_RELOC_HALF and ARM_RELOC_HALF_SECTDIFF abuse the r_length field:
- //
- // For these two r_type relocations they always have a pair following them and
- // the r_length bits are used differently. The encoding of the r_length is as
- // follows:
- // low bit of r_length:
- // 0 - :lower16: for movw instructions
- // 1 - :upper16: for movt instructions
- // high bit of r_length:
- // 0 - arm instructions
- // 1 - thumb instructions
- // the other half of the relocated expression is in the following pair
- // relocation entry in the the low 16 bits of r_address field.
- unsigned ThumbBit = 0;
- unsigned MovtBit = 0;
- switch ((unsigned)Fixup.getKind()) {
- default: break;
- case ARM::fixup_arm_movt_hi16:
- case ARM::fixup_arm_movt_hi16_pcrel:
- MovtBit = 1;
- break;
- case ARM::fixup_t2_movt_hi16:
- case ARM::fixup_t2_movt_hi16_pcrel:
- MovtBit = 1;
- // Fallthrough
- case ARM::fixup_t2_movw_lo16:
- case ARM::fixup_t2_movw_lo16_pcrel:
- ThumbBit = 1;
- break;
- }
-
-
- if (Type == macho::RIT_ARM_HalfDifference) {
- uint32_t OtherHalf = MovtBit
- ? (FixedValue & 0xffff) : ((FixedValue & 0xffff0000) >> 16);
-
- macho::RelocationEntry MRE;
- MRE.Word0 = ((OtherHalf << 0) |
- (macho::RIT_Pair << 24) |
- (MovtBit << 28) |
- (ThumbBit << 29) |
- (IsPCRel << 30) |
- macho::RF_Scattered);
- MRE.Word1 = Value2;
- Writer->addRelocation(Fragment->getParent(), MRE);
- }
-
- macho::RelocationEntry MRE;
- MRE.Word0 = ((FixupOffset << 0) |
- (Type << 24) |
- (MovtBit << 28) |
- (ThumbBit << 29) |
- (IsPCRel << 30) |
- macho::RF_Scattered);
- MRE.Word1 = Value;
- Writer->addRelocation(Fragment->getParent(), MRE);
-}
-
-void ARMMachObjectWriter::RecordARMScatteredRelocation(MachObjectWriter *Writer,
- const MCAssembler &Asm,
- const MCAsmLayout &Layout,
- const MCFragment *Fragment,
- const MCFixup &Fixup,
- MCValue Target,
- unsigned Log2Size,
- uint64_t &FixedValue) {
- uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset();
- unsigned IsPCRel = Writer->isFixupKindPCRel(Asm, Fixup.getKind());
- unsigned Type = macho::RIT_Vanilla;
-
- // See <reloc.h>.
- const MCSymbol *A = &Target.getSymA()->getSymbol();
- MCSymbolData *A_SD = &Asm.getSymbolData(*A);
-
- if (!A_SD->getFragment())
- report_fatal_error("symbol '" + A->getName() +
- "' can not be undefined in a subtraction expression");
-
- uint32_t Value = Writer->getSymbolAddress(A_SD, Layout);
- uint64_t SecAddr = Writer->getSectionAddress(A_SD->getFragment()->getParent());
- FixedValue += SecAddr;
- uint32_t Value2 = 0;
-
- if (const MCSymbolRefExpr *B = Target.getSymB()) {
- MCSymbolData *B_SD = &Asm.getSymbolData(B->getSymbol());
-
- if (!B_SD->getFragment())
- report_fatal_error("symbol '" + B->getSymbol().getName() +
- "' can not be undefined in a subtraction expression");
-
- // Select the appropriate difference relocation type.
- Type = macho::RIT_Difference;
- Value2 = Writer->getSymbolAddress(B_SD, Layout);
- FixedValue -= Writer->getSectionAddress(B_SD->getFragment()->getParent());
- }
-
- // Relocations are written out in reverse order, so the PAIR comes first.
- if (Type == macho::RIT_Difference ||
- Type == macho::RIT_Generic_LocalDifference) {
- macho::RelocationEntry MRE;
- MRE.Word0 = ((0 << 0) |
- (macho::RIT_Pair << 24) |
- (Log2Size << 28) |
- (IsPCRel << 30) |
- macho::RF_Scattered);
- MRE.Word1 = Value2;
- Writer->addRelocation(Fragment->getParent(), MRE);
- }
-
- macho::RelocationEntry MRE;
- MRE.Word0 = ((FixupOffset << 0) |
- (Type << 24) |
- (Log2Size << 28) |
- (IsPCRel << 30) |
- macho::RF_Scattered);
- MRE.Word1 = Value;
- Writer->addRelocation(Fragment->getParent(), MRE);
-}
-
-void ARMMachObjectWriter::RecordRelocation(MachObjectWriter *Writer,
- const MCAssembler &Asm,
- const MCAsmLayout &Layout,
- const MCFragment *Fragment,
- const MCFixup &Fixup,
- MCValue Target,
- uint64_t &FixedValue) {
- unsigned IsPCRel = Writer->isFixupKindPCRel(Asm, Fixup.getKind());
- unsigned Log2Size;
- unsigned RelocType = macho::RIT_Vanilla;
- if (!getARMFixupKindMachOInfo(Fixup.getKind(), RelocType, Log2Size)) {
- report_fatal_error("unknown ARM fixup kind!");
- return;
- }
-
- // If this is a difference or a defined symbol plus an offset, then we need a
- // scattered relocation entry. Differences always require scattered
- // relocations.
- if (Target.getSymB()) {
- if (RelocType == macho::RIT_ARM_Half ||
- RelocType == macho::RIT_ARM_HalfDifference)
- return RecordARMMovwMovtRelocation(Writer, Asm, Layout, Fragment, Fixup,
- Target, FixedValue);
- return RecordARMScatteredRelocation(Writer, Asm, Layout, Fragment, Fixup,
- Target, Log2Size, FixedValue);
- }
-
- // Get the symbol data, if any.
- MCSymbolData *SD = 0;
- if (Target.getSymA())
- SD = &Asm.getSymbolData(Target.getSymA()->getSymbol());
-
- // FIXME: For other platforms, we need to use scattered relocations for
- // internal relocations with offsets. If this is an internal relocation with
- // an offset, it also needs a scattered relocation entry.
- //
- // Is this right for ARM?
- uint32_t Offset = Target.getConstant();
- if (IsPCRel && RelocType == macho::RIT_Vanilla)
- Offset += 1 << Log2Size;
- if (Offset && SD && !Writer->doesSymbolRequireExternRelocation(SD))
- return RecordARMScatteredRelocation(Writer, Asm, Layout, Fragment, Fixup,
- Target, Log2Size, FixedValue);
-
- // See <reloc.h>.
- uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset();
- unsigned Index = 0;
- unsigned IsExtern = 0;
- unsigned Type = 0;
-
- if (Target.isAbsolute()) { // constant
- // FIXME!
- report_fatal_error("FIXME: relocations to absolute targets "
- "not yet implemented");
- } else {
- // Resolve constant variables.
- if (SD->getSymbol().isVariable()) {
- int64_t Res;
- if (SD->getSymbol().getVariableValue()->EvaluateAsAbsolute(
- Res, Layout, Writer->getSectionAddressMap())) {
- FixedValue = Res;
- return;
- }
- }
-
- // Check whether we need an external or internal relocation.
- if (Writer->doesSymbolRequireExternRelocation(SD)) {
- IsExtern = 1;
- Index = SD->getIndex();
-
- // For external relocations, make sure to offset the fixup value to
- // compensate for the addend of the symbol address, if it was
- // undefined. This occurs with weak definitions, for example.
- if (!SD->Symbol->isUndefined())
- FixedValue -= Layout.getSymbolOffset(SD);
- } else {
- // The index is the section ordinal (1-based).
- const MCSectionData &SymSD = Asm.getSectionData(
- SD->getSymbol().getSection());
- Index = SymSD.getOrdinal() + 1;
- FixedValue += Writer->getSectionAddress(&SymSD);
- }
- if (IsPCRel)
- FixedValue -= Writer->getSectionAddress(Fragment->getParent());
-
- // The type is determined by the fixup kind.
- Type = RelocType;
- }
-
- // struct relocation_info (8 bytes)
- macho::RelocationEntry MRE;
- MRE.Word0 = FixupOffset;
- MRE.Word1 = ((Index << 0) |
- (IsPCRel << 24) |
- (Log2Size << 25) |
- (IsExtern << 27) |
- (Type << 28));
- Writer->addRelocation(Fragment->getParent(), MRE);
-}
-
-MCObjectWriter *llvm::createARMMachObjectWriter(raw_ostream &OS,
- bool Is64Bit,
- uint32_t CPUType,
- uint32_t CPUSubtype) {
- return createMachObjectWriter(new ARMMachObjectWriter(Is64Bit,
- CPUType,
- CPUSubtype),
- OS, /*IsLittleEndian=*/true);
-}
Modified: llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp?rev=135825&r1=135824&r2=135825&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp Fri Jul 22 19:00:19 2011
@@ -21,43 +21,10 @@
#include "llvm/Target/TargetRegistry.h"
using namespace llvm;
-// This is duplicated code. Refactor this.
-static MCStreamer *createMCStreamer(const Target &T, const std::string &TT,
- MCContext &Ctx, TargetAsmBackend &TAB,
- raw_ostream &OS,
- MCCodeEmitter *Emitter,
- bool RelaxAll,
- bool NoExecStack) {
- Triple TheTriple(TT);
-
- if (TheTriple.isOSDarwin())
- return createMachOStreamer(Ctx, TAB, OS, Emitter, RelaxAll);
-
- if (TheTriple.isOSWindows()) {
- llvm_unreachable("ARM does not support Windows COFF format");
- return NULL;
- }
-
- return createELFStreamer(Ctx, TAB, OS, Emitter, RelaxAll, NoExecStack);
-}
-
extern "C" void LLVMInitializeARMTarget() {
// Register the target.
RegisterTargetMachine<ARMTargetMachine> X(TheARMTarget);
RegisterTargetMachine<ThumbTargetMachine> Y(TheThumbTarget);
-
- // Register the MC Code Emitter
- TargetRegistry::RegisterCodeEmitter(TheARMTarget, createARMMCCodeEmitter);
- TargetRegistry::RegisterCodeEmitter(TheThumbTarget, createARMMCCodeEmitter);
-
- // Register the asm backend.
- TargetRegistry::RegisterAsmBackend(TheARMTarget, createARMAsmBackend);
- TargetRegistry::RegisterAsmBackend(TheThumbTarget, createARMAsmBackend);
-
- // Register the object streamer.
- TargetRegistry::RegisterObjectStreamer(TheARMTarget, createMCStreamer);
- TargetRegistry::RegisterObjectStreamer(TheThumbTarget, createMCStreamer);
-
}
/// TargetMachine ctor - Create an ARM architecture model.
Modified: llvm/trunk/lib/Target/ARM/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/CMakeLists.txt?rev=135825&r1=135824&r2=135825&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/CMakeLists.txt (original)
+++ llvm/trunk/lib/Target/ARM/CMakeLists.txt Fri Jul 22 19:00:19 2011
@@ -15,7 +15,6 @@
tablegen(ARMGenDecoderTables.inc -gen-arm-decoder)
add_llvm_target(ARMCodeGen
- ARMAsmBackend.cpp
ARMAsmPrinter.cpp
ARMBaseInstrInfo.cpp
ARMBaseRegisterInfo.cpp
@@ -32,8 +31,6 @@
ARMISelLowering.cpp
ARMInstrInfo.cpp
ARMJITInfo.cpp
- ARMMachObjectWriter.cpp
- ARMMCCodeEmitter.cpp
ARMLoadStoreOptimizer.cpp
ARMMCInstLower.cpp
ARMRegisterInfo.cpp
Modified: llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp?rev=135825&r1=135824&r2=135825&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp Fri Jul 22 19:00:19 2011
@@ -12,8 +12,8 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "asm-printer"
-#include "ARMBaseInfo.h"
#include "ARMInstPrinter.h"
+#include "MCTargetDesc/ARMBaseInfo.h"
#include "MCTargetDesc/ARMAddressingModes.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCAsmInfo.h"
Copied: llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp (from r135818, llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp?p2=llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp&p1=llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp&r1=135818&r2=135825&rev=135825&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp (original)
+++ llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp Fri Jul 22 19:00:19 2011
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#include "ARM.h"
-#include "ARMFixupKinds.h"
+#include "MCTargetDesc/ARMBaseInfo.h"
+#include "MCTargetDesc/ARMFixupKinds.h"
#include "MCTargetDesc/ARMAddressingModes.h"
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCAssembler.h"
@@ -24,7 +24,6 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetAsmBackend.h"
-#include "llvm/Target/TargetRegistry.h"
using namespace llvm;
namespace {
Copied: llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h (from r135818, llvm/trunk/lib/Target/ARM/ARMBaseInfo.h)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h?p2=llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h&p1=llvm/trunk/lib/Target/ARM/ARMBaseInfo.h&r1=135818&r2=135825&rev=135825&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMBaseInfo.h (original)
+++ llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h Fri Jul 22 19:00:19 2011
@@ -17,7 +17,7 @@
#ifndef ARMBASEINFO_H
#define ARMBASEINFO_H
-#include "MCTargetDesc/ARMMCTargetDesc.h"
+#include "ARMMCTargetDesc.h"
#include "llvm/Support/ErrorHandling.h"
// Note that the following auto-generated files only defined enum types, and
Copied: llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp (from r135818, llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp?p2=llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp&p1=llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp&r1=135818&r2=135825&rev=135825&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp Fri Jul 22 19:00:19 2011
@@ -12,15 +12,16 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "mccodeemitter"
-#include "ARM.h"
-#include "ARMFixupKinds.h"
-#include "ARMInstrInfo.h"
#include "MCTargetDesc/ARMAddressingModes.h"
+#include "MCTargetDesc/ARMBaseInfo.h"
+#include "MCTargetDesc/ARMFixupKinds.h"
#include "MCTargetDesc/ARMMCExpr.h"
+#include "MCTargetDesc/ARMMCTargetDesc.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/Statistic.h"
@@ -285,9 +286,6 @@
unsigned getMsbOpValue(const MCInst &MI, unsigned Op,
SmallVectorImpl<MCFixup> &Fixups) const;
- unsigned getSsatBitPosValue(const MCInst &MI, unsigned Op,
- SmallVectorImpl<MCFixup> &Fixups) const;
-
unsigned getRegisterListOpValue(const MCInst &MI, unsigned Op,
SmallVectorImpl<MCFixup> &Fixups) const;
unsigned getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op,
@@ -1170,11 +1168,9 @@
return msb;
}
-unsigned ARMMCCodeEmitter::
-getSsatBitPosValue(const MCInst &MI, unsigned Op,
- SmallVectorImpl<MCFixup> &Fixups) const {
- // For ssat instructions, the bit position should be encoded decremented by 1
- return MI.getOperand(Op).getImm()-1;
+namespace llvm {
+ // FIXME: TableGen this?
+ extern MCRegisterClass ARMMCRegisterClasses[]; // In ARMGenRegisterInfo.inc.
}
unsigned ARMMCCodeEmitter::
@@ -1187,8 +1183,8 @@
// LDM/STM:
// {15-0} = Bitfield of GPRs.
unsigned Reg = MI.getOperand(Op).getReg();
- bool SPRRegs = ARM::SPRRegClass.contains(Reg);
- bool DPRRegs = ARM::DPRRegClass.contains(Reg);
+ bool SPRRegs = llvm::ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg);
+ bool DPRRegs = llvm::ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg);
unsigned Binary = 0;
Modified: llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp?rev=135825&r1=135824&r2=135825&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp (original)
+++ llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp Fri Jul 22 19:00:19 2011
@@ -15,8 +15,10 @@
#include "ARMMCAsmInfo.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Target/TargetRegistry.h"
+#include "llvm/Support/ErrorHandling.h"
#define GET_REGINFO_MC_DESC
#include "ARMGenRegisterInfo.inc"
@@ -119,8 +121,8 @@
return new ARMELFMCAsmInfo();
}
-MCCodeGenInfo *createARMMCCodeGenInfo(StringRef TT, Reloc::Model RM,
- CodeModel::Model CM) {
+static MCCodeGenInfo *createARMMCCodeGenInfo(StringRef TT, Reloc::Model RM,
+ CodeModel::Model CM) {
MCCodeGenInfo *X = new MCCodeGenInfo();
if (RM == Reloc::Default)
RM = Reloc::DynamicNoPIC;
@@ -128,6 +130,27 @@
return X;
}
+// This is duplicated code. Refactor this.
+static MCStreamer *createMCStreamer(const Target &T, const std::string &TT,
+ MCContext &Ctx, TargetAsmBackend &TAB,
+ raw_ostream &OS,
+ MCCodeEmitter *Emitter,
+ bool RelaxAll,
+ bool NoExecStack) {
+ Triple TheTriple(TT);
+
+ if (TheTriple.isOSDarwin())
+ return createMachOStreamer(Ctx, TAB, OS, Emitter, RelaxAll);
+
+ if (TheTriple.isOSWindows()) {
+ llvm_unreachable("ARM does not support Windows COFF format");
+ return NULL;
+ }
+
+ return createELFStreamer(Ctx, TAB, OS, Emitter, RelaxAll, NoExecStack);
+}
+
+
// Force static initialization.
extern "C" void LLVMInitializeARMTargetMC() {
// Register the MC asm info.
@@ -151,4 +174,16 @@
ARM_MC::createARMMCSubtargetInfo);
TargetRegistry::RegisterMCSubtargetInfo(TheThumbTarget,
ARM_MC::createARMMCSubtargetInfo);
+
+ // Register the MC Code Emitter
+ TargetRegistry::RegisterCodeEmitter(TheARMTarget, createARMMCCodeEmitter);
+ TargetRegistry::RegisterCodeEmitter(TheThumbTarget, createARMMCCodeEmitter);
+
+ // Register the asm backend.
+ TargetRegistry::RegisterAsmBackend(TheARMTarget, createARMAsmBackend);
+ TargetRegistry::RegisterAsmBackend(TheThumbTarget, createARMAsmBackend);
+
+ // Register the object streamer.
+ TargetRegistry::RegisterObjectStreamer(TheARMTarget, createMCStreamer);
+ TargetRegistry::RegisterObjectStreamer(TheThumbTarget, createMCStreamer);
}
Modified: llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h?rev=135825&r1=135824&r2=135825&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h (original)
+++ llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h Fri Jul 22 19:00:19 2011
@@ -17,9 +17,15 @@
#include <string>
namespace llvm {
+class MCCodeEmitter;
+class MCContext;
+class MCInstrInfo;
+class MCObjectWriter;
class MCSubtargetInfo;
-class Target;
class StringRef;
+class Target;
+class TargetAsmBackend;
+class raw_ostream;
extern Target TheARMTarget, TheThumbTarget;
@@ -33,6 +39,18 @@
StringRef FS);
}
+MCCodeEmitter *createARMMCCodeEmitter(const MCInstrInfo &MCII,
+ const MCSubtargetInfo &STI,
+ MCContext &Ctx);
+
+TargetAsmBackend *createARMAsmBackend(const Target&, const std::string &);
+
+/// createARMMachObjectWriter - Construct an ARM Mach-O object writer.
+MCObjectWriter *createARMMachObjectWriter(raw_ostream &OS,
+ bool Is64Bit,
+ uint32_t CPUType,
+ uint32_t CPUSubtype);
+
} // End llvm namespace
// Defines symbolic names for ARM registers. This defines a mapping from
Copied: llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp (from r135818, llvm/trunk/lib/Target/ARM/ARMMachObjectWriter.cpp)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp?p2=llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp&p1=llvm/trunk/lib/Target/ARM/ARMMachObjectWriter.cpp&r1=135818&r2=135825&rev=135825&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMMachObjectWriter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp Fri Jul 22 19:00:19 2011
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#include "ARM.h"
-#include "ARMFixupKinds.h"
+#include "MCTargetDesc/ARMBaseInfo.h"
+#include "MCTargetDesc/ARMFixupKinds.h"
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCAsmLayout.h"
Modified: llvm/trunk/lib/Target/ARM/MCTargetDesc/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/MCTargetDesc/CMakeLists.txt?rev=135825&r1=135824&r2=135825&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/MCTargetDesc/CMakeLists.txt (original)
+++ llvm/trunk/lib/Target/ARM/MCTargetDesc/CMakeLists.txt Fri Jul 22 19:00:19 2011
@@ -1,7 +1,10 @@
add_llvm_library(LLVMARMDesc
+ ARMAsmBackend.cpp
ARMMCTargetDesc.cpp
ARMMCAsmInfo.cpp
+ ARMMCCodeEmitter.cpp
ARMMCExpr.cpp
+ ARMMachObjectWriter.cpp
)
# Hack: we need to include 'main' target directory to grab private headers
More information about the llvm-commits
mailing list