diff options
author | Evan Cheng <evan.cheng@apple.com> | 2011-01-13 07:58:56 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2011-01-13 07:58:56 +0000 |
commit | 7597212abced110723f2fee985a7d60557c092ec (patch) | |
tree | 5e01be3847a6ec23112b8feb910ac5a2bb6b2fcb /lib/Target/ARM/ARMMCCodeEmitter.cpp | |
parent | 04f5079ca1fd6c46a2b2efc369e293fb6feab793 (diff) | |
download | external_llvm-7597212abced110723f2fee985a7d60557c092ec.tar.gz external_llvm-7597212abced110723f2fee985a7d60557c092ec.tar.bz2 external_llvm-7597212abced110723f2fee985a7d60557c092ec.zip |
Model :upper16: and :lower16: as ARM specific MCTargetExpr. This is a step
in the right direction. It eliminated some hacks and will unblock codegen
work. But it's far from being done. It doesn't reject illegal expressions,
e.g. (FOO - :lower16:BAR). It also doesn't work in Thumb2 mode at all.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123369 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM/ARMMCCodeEmitter.cpp')
-rw-r--r-- | lib/Target/ARM/ARMMCCodeEmitter.cpp | 62 |
1 files changed, 27 insertions, 35 deletions
diff --git a/lib/Target/ARM/ARMMCCodeEmitter.cpp b/lib/Target/ARM/ARMMCCodeEmitter.cpp index 1c6cdad2b9..542d24d055 100644 --- a/lib/Target/ARM/ARMMCCodeEmitter.cpp +++ b/lib/Target/ARM/ARMMCCodeEmitter.cpp @@ -16,6 +16,7 @@ #include "ARMAddressingModes.h" #include "ARMFixupKinds.h" #include "ARMInstrInfo.h" +#include "ARMMCExpr.h" #include "llvm/MC/MCCodeEmitter.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" @@ -53,9 +54,11 @@ public: unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO, SmallVectorImpl<MCFixup> &Fixups) const; - /// getMovtImmOpValue - Return the encoding for the movw/movt pair - uint32_t getMovtImmOpValue(const MCInst &MI, unsigned OpIdx, - 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, @@ -626,19 +629,6 @@ getT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx, return Binary; } -// FIXME: This routine needs to handle more MCExpr types -static const MCSymbolRefExpr *FindLHSymExpr(const MCExpr *E) { - // recurse left child until finding a MCSymbolRefExpr - switch (E->getKind()) { - case MCExpr::SymbolRef: - return cast<MCSymbolRefExpr>(E); - case MCExpr::Binary: - return FindLHSymExpr(cast<MCBinaryExpr>(E)->getLHS()); - default: - return NULL; - } -} - // 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 @@ -652,38 +642,40 @@ static bool EvaluateAsPCRel(const MCExpr *Expr) { } } -uint32_t ARMMCCodeEmitter:: -getMovtImmOpValue(const MCInst &MI, unsigned OpIdx, - SmallVectorImpl<MCFixup> &Fixups) const { +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()) { + if (MO.isImm()) + // Hi / lo 16 bits already extracted during earlier passes. return static_cast<unsigned>(MO.getImm()); - } else if (const MCSymbolRefExpr *Expr = - FindLHSymExpr(MO.getExpr())) { - // FIXME: :lower16: and :upper16: should be applicable to - // to whole expression, not just symbolrefs - // Until that change takes place, this hack is required to - // generate working code. - const MCExpr *OrigExpr = MO.getExpr(); + + // 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 (Expr->getKind()) { + switch (ARM16Expr->getKind()) { default: assert(0 && "Unsupported ARMFixup"); - case MCSymbolRefExpr::VK_ARM_HI16: + case ARMMCExpr::VK_ARM_HI16: Kind = MCFixupKind(ARM::fixup_arm_movt_hi16); - if (EvaluateAsPCRel(OrigExpr)) + if (EvaluateAsPCRel(E)) Kind = MCFixupKind(ARM::fixup_arm_movt_hi16_pcrel); break; - case MCSymbolRefExpr::VK_ARM_LO16: + case ARMMCExpr::VK_ARM_LO16: Kind = MCFixupKind(ARM::fixup_arm_movw_lo16); - if (EvaluateAsPCRel(OrigExpr)) + if (EvaluateAsPCRel(E)) Kind = MCFixupKind(ARM::fixup_arm_movw_lo16_pcrel); break; } - Fixups.push_back(MCFixup::Create(0, OrigExpr, Kind)); + Fixups.push_back(MCFixup::Create(0, E, Kind)); return 0; }; + llvm_unreachable("Unsupported MCExpr type in MCOperand!"); return 0; } @@ -1173,8 +1165,8 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS, case ARMII::Size4Bytes: Size = 4; break; } uint32_t Binary = getBinaryCodeForInstr(MI, Fixups); - // Thumb 32-bit wide instructions need to be have the high order halfword - // emitted first. + // Thumb 32-bit wide instructions need to emit the high order halfword + // first. if (Subtarget.isThumb() && Size == 4) { EmitConstant(Binary >> 16, 2, OS); EmitConstant(Binary & 0xffff, 2, OS); |