1235633Sdim//===-- 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" 16226890Sdim#include "llvm/CodeGen/MachineBasicBlock.h" 17252723Sdim#include "llvm/IR/Constant.h" 18252723Sdim#include "llvm/IR/Constants.h" 19252723Sdim#include "llvm/IR/GlobalValue.h" 20252723Sdim#include "llvm/IR/Type.h" 21193323Sed#include "llvm/Support/raw_ostream.h" 22198090Srdivacky#include <cstdlib> 23193323Sedusing namespace llvm; 24193323Sed 25226890Sdim//===----------------------------------------------------------------------===// 26226890Sdim// ARMConstantPoolValue 27226890Sdim//===----------------------------------------------------------------------===// 28226890Sdim 29226890SdimARMConstantPoolValue::ARMConstantPoolValue(Type *Ty, unsigned id, 30226890Sdim ARMCP::ARMCPKind kind, 31193323Sed unsigned char PCAdj, 32226890Sdim ARMCP::ARMCPModifier modifier, 33226890Sdim bool addCurrentAddress) 34226890Sdim : MachineConstantPoolValue(Ty), LabelId(id), Kind(kind), 35226890Sdim PCAdjust(PCAdj), Modifier(modifier), 36226890Sdim AddCurrentAddress(addCurrentAddress) {} 37193323Sed 38226890SdimARMConstantPoolValue::ARMConstantPoolValue(LLVMContext &C, unsigned id, 39226890Sdim ARMCP::ARMCPKind kind, 40193323Sed unsigned char PCAdj, 41226890Sdim ARMCP::ARMCPModifier modifier, 42226890Sdim bool addCurrentAddress) 43226890Sdim : MachineConstantPoolValue((Type*)Type::getInt32Ty(C)), 44226890Sdim LabelId(id), Kind(kind), PCAdjust(PCAdj), Modifier(modifier), 45226890Sdim AddCurrentAddress(addCurrentAddress) {} 46193323Sed 47226890SdimARMConstantPoolValue::~ARMConstantPoolValue() {} 48193323Sed 49226890Sdimconst char *ARMConstantPoolValue::getModifierText() const { 50226890Sdim switch (Modifier) { 51226890Sdim // FIXME: Are these case sensitive? It'd be nice to lower-case all the 52226890Sdim // strings if that's legal. 53226890Sdim case ARMCP::no_modifier: return "none"; 54226890Sdim case ARMCP::TLSGD: return "tlsgd"; 55226890Sdim case ARMCP::GOT: return "GOT"; 56226890Sdim case ARMCP::GOTOFF: return "GOTOFF"; 57226890Sdim case ARMCP::GOTTPOFF: return "gottpoff"; 58226890Sdim case ARMCP::TPOFF: return "tpoff"; 59226890Sdim } 60235633Sdim llvm_unreachable("Unknown modifier!"); 61226890Sdim} 62226890Sdim 63226890Sdimint ARMConstantPoolValue::getExistingMachineCPValue(MachineConstantPool *CP, 64226890Sdim unsigned Alignment) { 65235633Sdim llvm_unreachable("Shouldn't be calling this directly!"); 66226890Sdim} 67226890Sdim 68226890Sdimvoid 69226890SdimARMConstantPoolValue::addSelectionDAGCSEId(FoldingSetNodeID &ID) { 70226890Sdim ID.AddInteger(LabelId); 71226890Sdim ID.AddInteger(PCAdjust); 72226890Sdim} 73226890Sdim 74226890Sdimbool 75226890SdimARMConstantPoolValue::hasSameValue(ARMConstantPoolValue *ACPV) { 76226890Sdim if (ACPV->Kind == Kind && 77226890Sdim ACPV->PCAdjust == PCAdjust && 78226890Sdim ACPV->Modifier == Modifier) { 79226890Sdim if (ACPV->LabelId == LabelId) 80226890Sdim return true; 81226890Sdim // Two PC relative constpool entries containing the same GV address or 82226890Sdim // external symbols. FIXME: What about blockaddress? 83226890Sdim if (Kind == ARMCP::CPValue || Kind == ARMCP::CPExtSymbol) 84226890Sdim return true; 85226890Sdim } 86226890Sdim return false; 87226890Sdim} 88226890Sdim 89226890Sdimvoid ARMConstantPoolValue::dump() const { 90226890Sdim errs() << " " << *this; 91226890Sdim} 92226890Sdim 93226890Sdimvoid ARMConstantPoolValue::print(raw_ostream &O) const { 94226890Sdim if (Modifier) O << "(" << getModifierText() << ")"; 95226890Sdim if (PCAdjust != 0) { 96226890Sdim O << "-(LPC" << LabelId << "+" << (unsigned)PCAdjust; 97226890Sdim if (AddCurrentAddress) O << "-."; 98226890Sdim O << ")"; 99226890Sdim } 100226890Sdim} 101226890Sdim 102226890Sdim//===----------------------------------------------------------------------===// 103226890Sdim// ARMConstantPoolConstant 104226890Sdim//===----------------------------------------------------------------------===// 105226890Sdim 106226890SdimARMConstantPoolConstant::ARMConstantPoolConstant(Type *Ty, 107226890Sdim const Constant *C, 108226890Sdim unsigned ID, 109226890Sdim ARMCP::ARMCPKind Kind, 110226890Sdim unsigned char PCAdj, 111226890Sdim ARMCP::ARMCPModifier Modifier, 112226890Sdim bool AddCurrentAddress) 113226890Sdim : ARMConstantPoolValue(Ty, ID, Kind, PCAdj, Modifier, AddCurrentAddress), 114226890Sdim CVal(C) {} 115226890Sdim 116226890SdimARMConstantPoolConstant::ARMConstantPoolConstant(const Constant *C, 117226890Sdim unsigned ID, 118226890Sdim ARMCP::ARMCPKind Kind, 119226890Sdim unsigned char PCAdj, 120226890Sdim ARMCP::ARMCPModifier Modifier, 121226890Sdim bool AddCurrentAddress) 122226890Sdim : ARMConstantPoolValue((Type*)C->getType(), ID, Kind, PCAdj, Modifier, 123226890Sdim AddCurrentAddress), 124226890Sdim CVal(C) {} 125226890Sdim 126226890SdimARMConstantPoolConstant * 127226890SdimARMConstantPoolConstant::Create(const Constant *C, unsigned ID) { 128226890Sdim return new ARMConstantPoolConstant(C, ID, ARMCP::CPValue, 0, 129226890Sdim ARMCP::no_modifier, false); 130226890Sdim} 131226890Sdim 132226890SdimARMConstantPoolConstant * 133226890SdimARMConstantPoolConstant::Create(const GlobalValue *GV, 134226890Sdim ARMCP::ARMCPModifier Modifier) { 135226890Sdim return new ARMConstantPoolConstant((Type*)Type::getInt32Ty(GV->getContext()), 136226890Sdim GV, 0, ARMCP::CPValue, 0, 137226890Sdim Modifier, false); 138226890Sdim} 139226890Sdim 140226890SdimARMConstantPoolConstant * 141226890SdimARMConstantPoolConstant::Create(const Constant *C, unsigned ID, 142226890Sdim ARMCP::ARMCPKind Kind, unsigned char PCAdj) { 143226890Sdim return new ARMConstantPoolConstant(C, ID, Kind, PCAdj, 144226890Sdim ARMCP::no_modifier, false); 145226890Sdim} 146226890Sdim 147226890SdimARMConstantPoolConstant * 148226890SdimARMConstantPoolConstant::Create(const Constant *C, unsigned ID, 149226890Sdim ARMCP::ARMCPKind Kind, unsigned char PCAdj, 150226890Sdim ARMCP::ARMCPModifier Modifier, 151226890Sdim bool AddCurrentAddress) { 152226890Sdim return new ARMConstantPoolConstant(C, ID, Kind, PCAdj, Modifier, 153226890Sdim AddCurrentAddress); 154226890Sdim} 155226890Sdim 156226890Sdimconst GlobalValue *ARMConstantPoolConstant::getGV() const { 157198892Srdivacky return dyn_cast_or_null<GlobalValue>(CVal); 158198892Srdivacky} 159198892Srdivacky 160226890Sdimconst BlockAddress *ARMConstantPoolConstant::getBlockAddress() const { 161198892Srdivacky return dyn_cast_or_null<BlockAddress>(CVal); 162198892Srdivacky} 163198892Srdivacky 164226890Sdimint ARMConstantPoolConstant::getExistingMachineCPValue(MachineConstantPool *CP, 165226890Sdim unsigned Alignment) { 166263509Sdim return getExistingMachineCPValueImpl<ARMConstantPoolConstant>(CP, Alignment); 167226890Sdim} 168226890Sdim 169226890Sdimbool ARMConstantPoolConstant::hasSameValue(ARMConstantPoolValue *ACPV) { 170226890Sdim const ARMConstantPoolConstant *ACPC = dyn_cast<ARMConstantPoolConstant>(ACPV); 171226890Sdim return ACPC && ACPC->CVal == CVal && ARMConstantPoolValue::hasSameValue(ACPV); 172226890Sdim} 173226890Sdim 174226890Sdimvoid ARMConstantPoolConstant::addSelectionDAGCSEId(FoldingSetNodeID &ID) { 175226890Sdim ID.AddPointer(CVal); 176226890Sdim ARMConstantPoolValue::addSelectionDAGCSEId(ID); 177226890Sdim} 178226890Sdim 179226890Sdimvoid ARMConstantPoolConstant::print(raw_ostream &O) const { 180226890Sdim O << CVal->getName(); 181226890Sdim ARMConstantPoolValue::print(O); 182226890Sdim} 183226890Sdim 184226890Sdim//===----------------------------------------------------------------------===// 185226890Sdim// ARMConstantPoolSymbol 186226890Sdim//===----------------------------------------------------------------------===// 187226890Sdim 188226890SdimARMConstantPoolSymbol::ARMConstantPoolSymbol(LLVMContext &C, const char *s, 189226890Sdim unsigned id, 190226890Sdim unsigned char PCAdj, 191226890Sdim ARMCP::ARMCPModifier Modifier, 192226890Sdim bool AddCurrentAddress) 193226890Sdim : ARMConstantPoolValue(C, id, ARMCP::CPExtSymbol, PCAdj, Modifier, 194226890Sdim AddCurrentAddress), 195252723Sdim S(s) {} 196226890Sdim 197226890SdimARMConstantPoolSymbol * 198226890SdimARMConstantPoolSymbol::Create(LLVMContext &C, const char *s, 199226890Sdim unsigned ID, unsigned char PCAdj) { 200226890Sdim return new ARMConstantPoolSymbol(C, s, ID, PCAdj, ARMCP::no_modifier, false); 201226890Sdim} 202226890Sdim 203226890Sdimint ARMConstantPoolSymbol::getExistingMachineCPValue(MachineConstantPool *CP, 204226890Sdim unsigned Alignment) { 205263509Sdim return getExistingMachineCPValueImpl<ARMConstantPoolSymbol>(CP, Alignment); 206193323Sed} 207193323Sed 208226890Sdimbool ARMConstantPoolSymbol::hasSameValue(ARMConstantPoolValue *ACPV) { 209226890Sdim const ARMConstantPoolSymbol *ACPS = dyn_cast<ARMConstantPoolSymbol>(ACPV); 210252723Sdim return ACPS && ACPS->S == S && ARMConstantPoolValue::hasSameValue(ACPV); 211198090Srdivacky} 212198090Srdivacky 213226890Sdimvoid ARMConstantPoolSymbol::addSelectionDAGCSEId(FoldingSetNodeID &ID) { 214252723Sdim ID.AddString(S); 215226890Sdim ARMConstantPoolValue::addSelectionDAGCSEId(ID); 216193323Sed} 217193323Sed 218226890Sdimvoid ARMConstantPoolSymbol::print(raw_ostream &O) const { 219226890Sdim O << S; 220226890Sdim ARMConstantPoolValue::print(O); 221199481Srdivacky} 222199481Srdivacky 223226890Sdim//===----------------------------------------------------------------------===// 224226890Sdim// ARMConstantPoolMBB 225226890Sdim//===----------------------------------------------------------------------===// 226226890Sdim 227226890SdimARMConstantPoolMBB::ARMConstantPoolMBB(LLVMContext &C, 228226890Sdim const MachineBasicBlock *mbb, 229226890Sdim unsigned id, unsigned char PCAdj, 230226890Sdim ARMCP::ARMCPModifier Modifier, 231226890Sdim bool AddCurrentAddress) 232226890Sdim : ARMConstantPoolValue(C, id, ARMCP::CPMachineBasicBlock, PCAdj, 233226890Sdim Modifier, AddCurrentAddress), 234226890Sdim MBB(mbb) {} 235226890Sdim 236226890SdimARMConstantPoolMBB *ARMConstantPoolMBB::Create(LLVMContext &C, 237226890Sdim const MachineBasicBlock *mbb, 238226890Sdim unsigned ID, 239226890Sdim unsigned char PCAdj) { 240226890Sdim return new ARMConstantPoolMBB(C, mbb, ID, PCAdj, ARMCP::no_modifier, false); 241193323Sed} 242193323Sed 243226890Sdimint ARMConstantPoolMBB::getExistingMachineCPValue(MachineConstantPool *CP, 244226890Sdim unsigned Alignment) { 245263509Sdim return getExistingMachineCPValueImpl<ARMConstantPoolMBB>(CP, Alignment); 246193323Sed} 247226890Sdim 248226890Sdimbool ARMConstantPoolMBB::hasSameValue(ARMConstantPoolValue *ACPV) { 249226890Sdim const ARMConstantPoolMBB *ACPMBB = dyn_cast<ARMConstantPoolMBB>(ACPV); 250226890Sdim return ACPMBB && ACPMBB->MBB == MBB && 251226890Sdim ARMConstantPoolValue::hasSameValue(ACPV); 252226890Sdim} 253226890Sdim 254226890Sdimvoid ARMConstantPoolMBB::addSelectionDAGCSEId(FoldingSetNodeID &ID) { 255226890Sdim ID.AddPointer(MBB); 256226890Sdim ARMConstantPoolValue::addSelectionDAGCSEId(ID); 257226890Sdim} 258226890Sdim 259226890Sdimvoid ARMConstantPoolMBB::print(raw_ostream &O) const { 260235633Sdim O << "BB#" << MBB->getNumber(); 261226890Sdim ARMConstantPoolValue::print(O); 262226890Sdim} 263