1234353Sdim//===-- ARMConstantPoolValue.cpp - ARM constantpool value -----------------===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// This file implements the ARM specific constantpool value class. 11193323Sed// 12193323Sed//===----------------------------------------------------------------------===// 13193323Sed 14193323Sed#include "ARMConstantPoolValue.h" 15193323Sed#include "llvm/ADT/FoldingSet.h" 16226633Sdim#include "llvm/CodeGen/MachineBasicBlock.h" 17249423Sdim#include "llvm/IR/Constant.h" 18249423Sdim#include "llvm/IR/Constants.h" 19249423Sdim#include "llvm/IR/GlobalValue.h" 20249423Sdim#include "llvm/IR/Type.h" 21193323Sed#include "llvm/Support/raw_ostream.h" 22198090Srdivacky#include <cstdlib> 23193323Sedusing namespace llvm; 24193323Sed 25226633Sdim//===----------------------------------------------------------------------===// 26226633Sdim// ARMConstantPoolValue 27226633Sdim//===----------------------------------------------------------------------===// 28226633Sdim 29226633SdimARMConstantPoolValue::ARMConstantPoolValue(Type *Ty, unsigned id, 30226633Sdim ARMCP::ARMCPKind kind, 31193323Sed unsigned char PCAdj, 32226633Sdim ARMCP::ARMCPModifier modifier, 33226633Sdim bool addCurrentAddress) 34226633Sdim : MachineConstantPoolValue(Ty), LabelId(id), Kind(kind), 35226633Sdim PCAdjust(PCAdj), Modifier(modifier), 36226633Sdim AddCurrentAddress(addCurrentAddress) {} 37193323Sed 38226633SdimARMConstantPoolValue::ARMConstantPoolValue(LLVMContext &C, unsigned id, 39226633Sdim ARMCP::ARMCPKind kind, 40193323Sed unsigned char PCAdj, 41226633Sdim ARMCP::ARMCPModifier modifier, 42226633Sdim bool addCurrentAddress) 43226633Sdim : MachineConstantPoolValue((Type*)Type::getInt32Ty(C)), 44226633Sdim LabelId(id), Kind(kind), PCAdjust(PCAdj), Modifier(modifier), 45226633Sdim AddCurrentAddress(addCurrentAddress) {} 46193323Sed 47226633SdimARMConstantPoolValue::~ARMConstantPoolValue() {} 48193323Sed 49226633Sdimconst char *ARMConstantPoolValue::getModifierText() const { 50226633Sdim switch (Modifier) { 51226633Sdim // FIXME: Are these case sensitive? It'd be nice to lower-case all the 52226633Sdim // strings if that's legal. 53226633Sdim case ARMCP::no_modifier: return "none"; 54226633Sdim case ARMCP::TLSGD: return "tlsgd"; 55296417Sdim case ARMCP::GOT_PREL: return "GOT_PREL"; 56226633Sdim case ARMCP::GOTTPOFF: return "gottpoff"; 57226633Sdim case ARMCP::TPOFF: return "tpoff"; 58226633Sdim } 59234353Sdim llvm_unreachable("Unknown modifier!"); 60226633Sdim} 61226633Sdim 62226633Sdimint ARMConstantPoolValue::getExistingMachineCPValue(MachineConstantPool *CP, 63226633Sdim unsigned Alignment) { 64234353Sdim llvm_unreachable("Shouldn't be calling this directly!"); 65226633Sdim} 66226633Sdim 67226633Sdimvoid 68226633SdimARMConstantPoolValue::addSelectionDAGCSEId(FoldingSetNodeID &ID) { 69226633Sdim ID.AddInteger(LabelId); 70226633Sdim ID.AddInteger(PCAdjust); 71226633Sdim} 72226633Sdim 73226633Sdimbool 74226633SdimARMConstantPoolValue::hasSameValue(ARMConstantPoolValue *ACPV) { 75226633Sdim if (ACPV->Kind == Kind && 76226633Sdim ACPV->PCAdjust == PCAdjust && 77226633Sdim ACPV->Modifier == Modifier) { 78226633Sdim if (ACPV->LabelId == LabelId) 79226633Sdim return true; 80226633Sdim // Two PC relative constpool entries containing the same GV address or 81226633Sdim // external symbols. FIXME: What about blockaddress? 82226633Sdim if (Kind == ARMCP::CPValue || Kind == ARMCP::CPExtSymbol) 83226633Sdim return true; 84226633Sdim } 85226633Sdim return false; 86226633Sdim} 87226633Sdim 88226633Sdimvoid ARMConstantPoolValue::dump() const { 89226633Sdim errs() << " " << *this; 90226633Sdim} 91226633Sdim 92226633Sdimvoid ARMConstantPoolValue::print(raw_ostream &O) const { 93226633Sdim if (Modifier) O << "(" << getModifierText() << ")"; 94226633Sdim if (PCAdjust != 0) { 95226633Sdim O << "-(LPC" << LabelId << "+" << (unsigned)PCAdjust; 96226633Sdim if (AddCurrentAddress) O << "-."; 97226633Sdim O << ")"; 98226633Sdim } 99226633Sdim} 100226633Sdim 101226633Sdim//===----------------------------------------------------------------------===// 102226633Sdim// ARMConstantPoolConstant 103226633Sdim//===----------------------------------------------------------------------===// 104226633Sdim 105226633SdimARMConstantPoolConstant::ARMConstantPoolConstant(Type *Ty, 106226633Sdim const Constant *C, 107226633Sdim unsigned ID, 108226633Sdim ARMCP::ARMCPKind Kind, 109226633Sdim unsigned char PCAdj, 110226633Sdim ARMCP::ARMCPModifier Modifier, 111226633Sdim bool AddCurrentAddress) 112226633Sdim : ARMConstantPoolValue(Ty, ID, Kind, PCAdj, Modifier, AddCurrentAddress), 113226633Sdim CVal(C) {} 114226633Sdim 115226633SdimARMConstantPoolConstant::ARMConstantPoolConstant(const Constant *C, 116226633Sdim unsigned ID, 117226633Sdim ARMCP::ARMCPKind Kind, 118226633Sdim unsigned char PCAdj, 119226633Sdim ARMCP::ARMCPModifier Modifier, 120226633Sdim bool AddCurrentAddress) 121226633Sdim : ARMConstantPoolValue((Type*)C->getType(), ID, Kind, PCAdj, Modifier, 122226633Sdim AddCurrentAddress), 123226633Sdim CVal(C) {} 124226633Sdim 125226633SdimARMConstantPoolConstant * 126226633SdimARMConstantPoolConstant::Create(const Constant *C, unsigned ID) { 127226633Sdim return new ARMConstantPoolConstant(C, ID, ARMCP::CPValue, 0, 128226633Sdim ARMCP::no_modifier, false); 129226633Sdim} 130226633Sdim 131226633SdimARMConstantPoolConstant * 132226633SdimARMConstantPoolConstant::Create(const GlobalValue *GV, 133226633Sdim ARMCP::ARMCPModifier Modifier) { 134226633Sdim return new ARMConstantPoolConstant((Type*)Type::getInt32Ty(GV->getContext()), 135226633Sdim GV, 0, ARMCP::CPValue, 0, 136226633Sdim Modifier, false); 137226633Sdim} 138226633Sdim 139226633SdimARMConstantPoolConstant * 140226633SdimARMConstantPoolConstant::Create(const Constant *C, unsigned ID, 141226633Sdim ARMCP::ARMCPKind Kind, unsigned char PCAdj) { 142226633Sdim return new ARMConstantPoolConstant(C, ID, Kind, PCAdj, 143226633Sdim ARMCP::no_modifier, false); 144226633Sdim} 145226633Sdim 146226633SdimARMConstantPoolConstant * 147226633SdimARMConstantPoolConstant::Create(const Constant *C, unsigned ID, 148226633Sdim ARMCP::ARMCPKind Kind, unsigned char PCAdj, 149226633Sdim ARMCP::ARMCPModifier Modifier, 150226633Sdim bool AddCurrentAddress) { 151226633Sdim return new ARMConstantPoolConstant(C, ID, Kind, PCAdj, Modifier, 152226633Sdim AddCurrentAddress); 153226633Sdim} 154226633Sdim 155226633Sdimconst GlobalValue *ARMConstantPoolConstant::getGV() const { 156198892Srdivacky return dyn_cast_or_null<GlobalValue>(CVal); 157198892Srdivacky} 158198892Srdivacky 159226633Sdimconst BlockAddress *ARMConstantPoolConstant::getBlockAddress() const { 160198892Srdivacky return dyn_cast_or_null<BlockAddress>(CVal); 161198892Srdivacky} 162198892Srdivacky 163226633Sdimint ARMConstantPoolConstant::getExistingMachineCPValue(MachineConstantPool *CP, 164226633Sdim unsigned Alignment) { 165261991Sdim return getExistingMachineCPValueImpl<ARMConstantPoolConstant>(CP, Alignment); 166226633Sdim} 167226633Sdim 168226633Sdimbool ARMConstantPoolConstant::hasSameValue(ARMConstantPoolValue *ACPV) { 169226633Sdim const ARMConstantPoolConstant *ACPC = dyn_cast<ARMConstantPoolConstant>(ACPV); 170226633Sdim return ACPC && ACPC->CVal == CVal && ARMConstantPoolValue::hasSameValue(ACPV); 171226633Sdim} 172226633Sdim 173226633Sdimvoid ARMConstantPoolConstant::addSelectionDAGCSEId(FoldingSetNodeID &ID) { 174226633Sdim ID.AddPointer(CVal); 175226633Sdim ARMConstantPoolValue::addSelectionDAGCSEId(ID); 176226633Sdim} 177226633Sdim 178226633Sdimvoid ARMConstantPoolConstant::print(raw_ostream &O) const { 179226633Sdim O << CVal->getName(); 180226633Sdim ARMConstantPoolValue::print(O); 181226633Sdim} 182226633Sdim 183226633Sdim//===----------------------------------------------------------------------===// 184226633Sdim// ARMConstantPoolSymbol 185226633Sdim//===----------------------------------------------------------------------===// 186226633Sdim 187226633SdimARMConstantPoolSymbol::ARMConstantPoolSymbol(LLVMContext &C, const char *s, 188226633Sdim unsigned id, 189226633Sdim unsigned char PCAdj, 190226633Sdim ARMCP::ARMCPModifier Modifier, 191226633Sdim bool AddCurrentAddress) 192226633Sdim : ARMConstantPoolValue(C, id, ARMCP::CPExtSymbol, PCAdj, Modifier, 193226633Sdim AddCurrentAddress), 194249423Sdim S(s) {} 195226633Sdim 196226633SdimARMConstantPoolSymbol * 197226633SdimARMConstantPoolSymbol::Create(LLVMContext &C, const char *s, 198226633Sdim unsigned ID, unsigned char PCAdj) { 199226633Sdim return new ARMConstantPoolSymbol(C, s, ID, PCAdj, ARMCP::no_modifier, false); 200226633Sdim} 201226633Sdim 202226633Sdimint ARMConstantPoolSymbol::getExistingMachineCPValue(MachineConstantPool *CP, 203226633Sdim unsigned Alignment) { 204261991Sdim return getExistingMachineCPValueImpl<ARMConstantPoolSymbol>(CP, Alignment); 205193323Sed} 206193323Sed 207226633Sdimbool ARMConstantPoolSymbol::hasSameValue(ARMConstantPoolValue *ACPV) { 208226633Sdim const ARMConstantPoolSymbol *ACPS = dyn_cast<ARMConstantPoolSymbol>(ACPV); 209249423Sdim return ACPS && ACPS->S == S && ARMConstantPoolValue::hasSameValue(ACPV); 210198090Srdivacky} 211198090Srdivacky 212226633Sdimvoid ARMConstantPoolSymbol::addSelectionDAGCSEId(FoldingSetNodeID &ID) { 213249423Sdim ID.AddString(S); 214226633Sdim ARMConstantPoolValue::addSelectionDAGCSEId(ID); 215193323Sed} 216193323Sed 217226633Sdimvoid ARMConstantPoolSymbol::print(raw_ostream &O) const { 218226633Sdim O << S; 219226633Sdim ARMConstantPoolValue::print(O); 220199481Srdivacky} 221199481Srdivacky 222226633Sdim//===----------------------------------------------------------------------===// 223226633Sdim// ARMConstantPoolMBB 224226633Sdim//===----------------------------------------------------------------------===// 225226633Sdim 226226633SdimARMConstantPoolMBB::ARMConstantPoolMBB(LLVMContext &C, 227226633Sdim const MachineBasicBlock *mbb, 228226633Sdim unsigned id, unsigned char PCAdj, 229226633Sdim ARMCP::ARMCPModifier Modifier, 230226633Sdim bool AddCurrentAddress) 231226633Sdim : ARMConstantPoolValue(C, id, ARMCP::CPMachineBasicBlock, PCAdj, 232226633Sdim Modifier, AddCurrentAddress), 233226633Sdim MBB(mbb) {} 234226633Sdim 235226633SdimARMConstantPoolMBB *ARMConstantPoolMBB::Create(LLVMContext &C, 236226633Sdim const MachineBasicBlock *mbb, 237226633Sdim unsigned ID, 238226633Sdim unsigned char PCAdj) { 239226633Sdim return new ARMConstantPoolMBB(C, mbb, ID, PCAdj, ARMCP::no_modifier, false); 240193323Sed} 241193323Sed 242226633Sdimint ARMConstantPoolMBB::getExistingMachineCPValue(MachineConstantPool *CP, 243226633Sdim unsigned Alignment) { 244261991Sdim return getExistingMachineCPValueImpl<ARMConstantPoolMBB>(CP, Alignment); 245193323Sed} 246226633Sdim 247226633Sdimbool ARMConstantPoolMBB::hasSameValue(ARMConstantPoolValue *ACPV) { 248226633Sdim const ARMConstantPoolMBB *ACPMBB = dyn_cast<ARMConstantPoolMBB>(ACPV); 249226633Sdim return ACPMBB && ACPMBB->MBB == MBB && 250226633Sdim ARMConstantPoolValue::hasSameValue(ACPV); 251226633Sdim} 252226633Sdim 253226633Sdimvoid ARMConstantPoolMBB::addSelectionDAGCSEId(FoldingSetNodeID &ID) { 254226633Sdim ID.AddPointer(MBB); 255226633Sdim ARMConstantPoolValue::addSelectionDAGCSEId(ID); 256226633Sdim} 257226633Sdim 258226633Sdimvoid ARMConstantPoolMBB::print(raw_ostream &O) const { 259234353Sdim O << "BB#" << MBB->getNumber(); 260226633Sdim ARMConstantPoolValue::print(O); 261226633Sdim} 262