diff options
| author | Jim Grosbach <grosbach@apple.com> | 2010-11-04 01:12:30 +0000 | 
|---|---|---|
| committer | Jim Grosbach <grosbach@apple.com> | 2010-11-04 01:12:30 +0000 | 
| commit | 0fb841fd195aac6b7c55ab6d8e0136e0df1a8373 (patch) | |
| tree | 93016c29096ca98a14231ce0477dc9b9ccb47c9a | |
| parent | c002463ac46c4b98a3b59375ce92ee85224e0702 (diff) | |
| download | bcm5719-llvm-0fb841fd195aac6b7c55ab6d8e0136e0df1a8373.tar.gz bcm5719-llvm-0fb841fd195aac6b7c55ab6d8e0136e0df1a8373.zip | |
Add ARM fixup info for load/store label references. Probably will need a bit of
tweaking when we start using it for object file emission or JIT, but it's a
start.
llvm-svn: 118221
| -rw-r--r-- | llvm/lib/Target/ARM/ARMFixupKinds.h | 28 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMMCCodeEmitter.cpp | 81 | 
2 files changed, 79 insertions, 30 deletions
| diff --git a/llvm/lib/Target/ARM/ARMFixupKinds.h b/llvm/lib/Target/ARM/ARMFixupKinds.h new file mode 100644 index 00000000000..3d91d52a6b6 --- /dev/null +++ b/llvm/lib/Target/ARM/ARMFixupKinds.h @@ -0,0 +1,28 @@ +//===-- 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_pcrel_12 - 12-bit PC relative relocation for symbol addresses +  fixup_arm_pcrel_12 = FirstTargetFixupKind, +  // fixup_arm_vfp_pcrel_12 - 12-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_vfp_pcrel_12 +}; +} +} + +#endif diff --git a/llvm/lib/Target/ARM/ARMMCCodeEmitter.cpp b/llvm/lib/Target/ARM/ARMMCCodeEmitter.cpp index efa9677194b..296a5c9ce36 100644 --- a/llvm/lib/Target/ARM/ARMMCCodeEmitter.cpp +++ b/llvm/lib/Target/ARM/ARMMCCodeEmitter.cpp @@ -14,6 +14,7 @@  #define DEBUG_TYPE "arm-emitter"  #include "ARM.h"  #include "ARMAddressingModes.h" +#include "ARMFixupKinds.h"  #include "ARMInstrInfo.h"  #include "llvm/MC/MCCodeEmitter.h"  #include "llvm/MC/MCExpr.h" @@ -22,7 +23,8 @@  #include "llvm/Support/raw_ostream.h"  using namespace llvm; -STATISTIC(MCNumEmitted, "Number of MC instructions emitted"); +STATISTIC(MCNumEmitted, "Number of MC instructions emitted."); +STATISTIC(MCNumCPRelocations, "Number of constant pool relocations created.");  namespace {  class ARMMCCodeEmitter : public MCCodeEmitter { @@ -39,6 +41,21 @@ public:    ~ARMMCCodeEmitter() {} +  unsigned getNumFixupKinds() const { return 2; } + +  const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const { +    const static MCFixupKindInfo Infos[] = { +      { "fixup_arm_pcrel_12", 2, 12, MCFixupKindInfo::FKF_IsPCRel }, +      { "fixup_arm_vfp_pcrel_12", 3, 8, MCFixupKindInfo::FKF_IsPCRel }, +    }; + +    if (Kind < FirstTargetFixupKind) +      return MCCodeEmitter::getFixupKindInfo(Kind); + +    assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && +           "Invalid kind!"); +    return Infos[Kind - FirstTargetFixupKind]; +  }    unsigned getMachineSoImmOpValue(unsigned SoImm) const;    // getBinaryCodeForInstr - TableGen'erated function for getting the @@ -123,27 +140,14 @@ public:    unsigned getAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op,                                       SmallVectorImpl<MCFixup> &Fixups) const; -  unsigned getNumFixupKinds() const { -    assert(0 && "ARMMCCodeEmitter::getNumFixupKinds() not yet implemented."); -    return 0; -  } - -  const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const { -    static MCFixupKindInfo rtn; -    assert(0 && "ARMMCCodeEmitter::getFixupKindInfo() not yet implemented."); -    return rtn; -  } - -  void EmitByte(unsigned char C, unsigned &CurByte, raw_ostream &OS) const { +  void EmitByte(unsigned char C, raw_ostream &OS) const {      OS << (char)C; -    ++CurByte;    } -  void EmitConstant(uint64_t Val, unsigned Size, unsigned &CurByte, -                    raw_ostream &OS) const { +  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, CurByte, OS); +      EmitByte(Val & 255, OS);        Val >>= 8;      }    } @@ -199,14 +203,6 @@ EncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx, unsigned &Reg,    const MCOperand &MO  = MI.getOperand(OpIdx);    const MCOperand &MO1 = MI.getOperand(OpIdx + 1); -  // If The first operand isn't a register, we have a label reference. -  if (!MO.isReg()) { -    Reg = ARM::PC;              // Rn is PC. -    Imm = 0; -    // FIXME: Add a fixup referencing the label. -    return true; -  } -    Reg = getARMRegisterNumbering(MO.getReg());    int32_t SImm = MO1.getImm(); @@ -234,7 +230,21 @@ getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,    // {12}    = (U)nsigned (add == '1', sub == '0')    // {11-0}  = imm12    unsigned Reg, Imm12; -  bool isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm12, Fixups); +  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 = ARM::PC;              // Rn is PC. +    Imm12 = 0; + +    assert(MO.isExpr() && "Unexpected machine operand type!"); +    const MCExpr *Expr = MO.getExpr(); +    MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_pcrel_12); +    Fixups.push_back(MCFixup::Create(0, Expr, Kind)); + +    ++MCNumCPRelocations; +  } else +    isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm12, Fixups);    if (Reg == ARM::PC)      return ARM::PC << 13;       // Rn is PC; @@ -255,7 +265,20 @@ getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,    // {8}    = (U)nsigned (add == '1', sub == '0')    // {7-0}  = imm8    unsigned Reg, Imm8; -  EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups); +  // If The first operand isn't a register, we have a label reference. +  const MCOperand &MO = MI.getOperand(OpIdx); +  if (!MO.isReg()) { +    Reg = ARM::PC;              // Rn is PC. +    Imm8 = 0; + +    assert(MO.isExpr() && "Unexpected machine operand type!"); +    const MCExpr *Expr = MO.getExpr(); +    MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_vfp_pcrel_12); +    Fixups.push_back(MCFixup::Create(0, Expr, Kind)); + +    ++MCNumCPRelocations; +  } else +    EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups);    if (Reg == ARM::PC)      return ARM::PC << 9;        // Rn is PC; @@ -403,9 +426,7 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS,    if ((Desc.TSFlags & ARMII::FormMask) == ARMII::Pseudo)      return; -  // Keep track of the current byte being emitted. -  unsigned CurByte = 0; -  EmitConstant(getBinaryCodeForInstr(MI, Fixups), 4, CurByte, OS); +  EmitConstant(getBinaryCodeForInstr(MI, Fixups), 4, OS);    ++MCNumEmitted;  // Keep track of the # of mi's emitted.  } | 

