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"; 55226633Sdim case ARMCP::GOT: return "GOT"; 56226633Sdim case ARMCP::GOTOFF: return "GOTOFF"; 57226633Sdim case ARMCP::GOTTPOFF: return "gottpoff"; 58226633Sdim case ARMCP::TPOFF: return "tpoff"; 59226633Sdim } 60234353Sdim llvm_unreachable("Unknown modifier!"); 61226633Sdim} 62226633Sdim 63226633Sdimint ARMConstantPoolValue::getExistingMachineCPValue(MachineConstantPool *CP, 64226633Sdim unsigned Alignment) { 65234353Sdim llvm_unreachable("Shouldn't be calling this directly!"); 66226633Sdim} 67226633Sdim 68226633Sdimvoid 69226633SdimARMConstantPoolValue::addSelectionDAGCSEId(FoldingSetNodeID &ID) { 70226633Sdim ID.AddInteger(LabelId); 71226633Sdim ID.AddInteger(PCAdjust); 72226633Sdim} 73226633Sdim 74226633Sdimbool 75226633SdimARMConstantPoolValue::hasSameValue(ARMConstantPoolValue *ACPV) { 76226633Sdim if (ACPV->Kind == Kind && 77226633Sdim ACPV->PCAdjust == PCAdjust && 78226633Sdim ACPV->Modifier == Modifier) { 79226633Sdim if (ACPV->LabelId == LabelId) 80226633Sdim return true; 81226633Sdim // Two PC relative constpool entries containing the same GV address or 82226633Sdim // external symbols. FIXME: What about blockaddress? 83226633Sdim if (Kind == ARMCP::CPValue || Kind == ARMCP::CPExtSymbol) 84226633Sdim return true; 85226633Sdim } 86226633Sdim return false; 87226633Sdim} 88226633Sdim 89226633Sdimvoid ARMConstantPoolValue::dump() const { 90226633Sdim errs() << " " << *this; 91226633Sdim} 92226633Sdim 93226633Sdimvoid ARMConstantPoolValue::print(raw_ostream &O) const { 94226633Sdim if (Modifier) O << "(" << getModifierText() << ")"; 95226633Sdim if (PCAdjust != 0) { 96226633Sdim O << "-(LPC" << LabelId << "+" << (unsigned)PCAdjust; 97226633Sdim if (AddCurrentAddress) O << "-."; 98226633Sdim O << ")"; 99226633Sdim } 100226633Sdim} 101226633Sdim 102226633Sdim//===----------------------------------------------------------------------===// 103226633Sdim// ARMConstantPoolConstant 104226633Sdim//===----------------------------------------------------------------------===// 105226633Sdim 106226633SdimARMConstantPoolConstant::ARMConstantPoolConstant(Type *Ty, 107226633Sdim const Constant *C, 108226633Sdim unsigned ID, 109226633Sdim ARMCP::ARMCPKind Kind, 110226633Sdim unsigned char PCAdj, 111226633Sdim ARMCP::ARMCPModifier Modifier, 112226633Sdim bool AddCurrentAddress) 113226633Sdim : ARMConstantPoolValue(Ty, ID, Kind, PCAdj, Modifier, AddCurrentAddress), 114226633Sdim CVal(C) {} 115226633Sdim 116226633SdimARMConstantPoolConstant::ARMConstantPoolConstant(const Constant *C, 117226633Sdim unsigned ID, 118226633Sdim ARMCP::ARMCPKind Kind, 119226633Sdim unsigned char PCAdj, 120226633Sdim ARMCP::ARMCPModifier Modifier, 121226633Sdim bool AddCurrentAddress) 122226633Sdim : ARMConstantPoolValue((Type*)C->getType(), ID, Kind, PCAdj, Modifier, 123226633Sdim AddCurrentAddress), 124226633Sdim CVal(C) {} 125226633Sdim 126226633SdimARMConstantPoolConstant * 127226633SdimARMConstantPoolConstant::Create(const Constant *C, unsigned ID) { 128226633Sdim return new ARMConstantPoolConstant(C, ID, ARMCP::CPValue, 0, 129226633Sdim ARMCP::no_modifier, false); 130226633Sdim} 131226633Sdim 132226633SdimARMConstantPoolConstant * 133226633SdimARMConstantPoolConstant::Create(const GlobalValue *GV, 134226633Sdim ARMCP::ARMCPModifier Modifier) { 135226633Sdim return new ARMConstantPoolConstant((Type*)Type::getInt32Ty(GV->getContext()), 136226633Sdim GV, 0, ARMCP::CPValue, 0, 137226633Sdim Modifier, false); 138226633Sdim} 139226633Sdim 140226633SdimARMConstantPoolConstant * 141226633SdimARMConstantPoolConstant::Create(const Constant *C, unsigned ID, 142226633Sdim ARMCP::ARMCPKind Kind, unsigned char PCAdj) { 143226633Sdim return new ARMConstantPoolConstant(C, ID, Kind, PCAdj, 144226633Sdim ARMCP::no_modifier, false); 145226633Sdim} 146226633Sdim 147226633SdimARMConstantPoolConstant * 148226633SdimARMConstantPoolConstant::Create(const Constant *C, unsigned ID, 149226633Sdim ARMCP::ARMCPKind Kind, unsigned char PCAdj, 150226633Sdim ARMCP::ARMCPModifier Modifier, 151226633Sdim bool AddCurrentAddress) { 152226633Sdim return new ARMConstantPoolConstant(C, ID, Kind, PCAdj, Modifier, 153226633Sdim AddCurrentAddress); 154226633Sdim} 155226633Sdim 156226633Sdimconst GlobalValue *ARMConstantPoolConstant::getGV() const { 157198892Srdivacky return dyn_cast_or_null<GlobalValue>(CVal); 158198892Srdivacky} 159198892Srdivacky 160226633Sdimconst BlockAddress *ARMConstantPoolConstant::getBlockAddress() const { 161198892Srdivacky return dyn_cast_or_null<BlockAddress>(CVal); 162198892Srdivacky} 163198892Srdivacky 164226633Sdimint ARMConstantPoolConstant::getExistingMachineCPValue(MachineConstantPool *CP, 165226633Sdim unsigned Alignment) { 166263508Sdim return getExistingMachineCPValueImpl<ARMConstantPoolConstant>(CP, Alignment); 167226633Sdim} 168226633Sdim 169226633Sdimbool ARMConstantPoolConstant::hasSameValue(ARMConstantPoolValue *ACPV) { 170226633Sdim const ARMConstantPoolConstant *ACPC = dyn_cast<ARMConstantPoolConstant>(ACPV); 171226633Sdim return ACPC && ACPC->CVal == CVal && ARMConstantPoolValue::hasSameValue(ACPV); 172226633Sdim} 173226633Sdim 174226633Sdimvoid ARMConstantPoolConstant::addSelectionDAGCSEId(FoldingSetNodeID &ID) { 175226633Sdim ID.AddPointer(CVal); 176226633Sdim ARMConstantPoolValue::addSelectionDAGCSEId(ID); 177226633Sdim} 178226633Sdim 179226633Sdimvoid ARMConstantPoolConstant::print(raw_ostream &O) const { 180226633Sdim O << CVal->getName(); 181226633Sdim ARMConstantPoolValue::print(O); 182226633Sdim} 183226633Sdim 184226633Sdim//===----------------------------------------------------------------------===// 185226633Sdim// ARMConstantPoolSymbol 186226633Sdim//===----------------------------------------------------------------------===// 187226633Sdim 188226633SdimARMConstantPoolSymbol::ARMConstantPoolSymbol(LLVMContext &C, const char *s, 189226633Sdim unsigned id, 190226633Sdim unsigned char PCAdj, 191226633Sdim ARMCP::ARMCPModifier Modifier, 192226633Sdim bool AddCurrentAddress) 193226633Sdim : ARMConstantPoolValue(C, id, ARMCP::CPExtSymbol, PCAdj, Modifier, 194226633Sdim AddCurrentAddress), 195249423Sdim S(s) {} 196226633Sdim 197226633SdimARMConstantPoolSymbol * 198226633SdimARMConstantPoolSymbol::Create(LLVMContext &C, const char *s, 199226633Sdim unsigned ID, unsigned char PCAdj) { 200226633Sdim return new ARMConstantPoolSymbol(C, s, ID, PCAdj, ARMCP::no_modifier, false); 201226633Sdim} 202226633Sdim 203226633Sdimint ARMConstantPoolSymbol::getExistingMachineCPValue(MachineConstantPool *CP, 204226633Sdim unsigned Alignment) { 205263508Sdim return getExistingMachineCPValueImpl<ARMConstantPoolSymbol>(CP, Alignment); 206193323Sed} 207193323Sed 208226633Sdimbool ARMConstantPoolSymbol::hasSameValue(ARMConstantPoolValue *ACPV) { 209226633Sdim const ARMConstantPoolSymbol *ACPS = dyn_cast<ARMConstantPoolSymbol>(ACPV); 210249423Sdim return ACPS && ACPS->S == S && ARMConstantPoolValue::hasSameValue(ACPV); 211198090Srdivacky} 212198090Srdivacky 213226633Sdimvoid ARMConstantPoolSymbol::addSelectionDAGCSEId(FoldingSetNodeID &ID) { 214249423Sdim ID.AddString(S); 215226633Sdim ARMConstantPoolValue::addSelectionDAGCSEId(ID); 216193323Sed} 217193323Sed 218226633Sdimvoid ARMConstantPoolSymbol::print(raw_ostream &O) const { 219226633Sdim O << S; 220226633Sdim ARMConstantPoolValue::print(O); 221199481Srdivacky} 222199481Srdivacky 223226633Sdim//===----------------------------------------------------------------------===// 224226633Sdim// ARMConstantPoolMBB 225226633Sdim//===----------------------------------------------------------------------===// 226226633Sdim 227226633SdimARMConstantPoolMBB::ARMConstantPoolMBB(LLVMContext &C, 228226633Sdim const MachineBasicBlock *mbb, 229226633Sdim unsigned id, unsigned char PCAdj, 230226633Sdim ARMCP::ARMCPModifier Modifier, 231226633Sdim bool AddCurrentAddress) 232226633Sdim : ARMConstantPoolValue(C, id, ARMCP::CPMachineBasicBlock, PCAdj, 233226633Sdim Modifier, AddCurrentAddress), 234226633Sdim MBB(mbb) {} 235226633Sdim 236226633SdimARMConstantPoolMBB *ARMConstantPoolMBB::Create(LLVMContext &C, 237226633Sdim const MachineBasicBlock *mbb, 238226633Sdim unsigned ID, 239226633Sdim unsigned char PCAdj) { 240226633Sdim return new ARMConstantPoolMBB(C, mbb, ID, PCAdj, ARMCP::no_modifier, false); 241193323Sed} 242193323Sed 243226633Sdimint ARMConstantPoolMBB::getExistingMachineCPValue(MachineConstantPool *CP, 244226633Sdim unsigned Alignment) { 245263508Sdim return getExistingMachineCPValueImpl<ARMConstantPoolMBB>(CP, Alignment); 246193323Sed} 247226633Sdim 248226633Sdimbool ARMConstantPoolMBB::hasSameValue(ARMConstantPoolValue *ACPV) { 249226633Sdim const ARMConstantPoolMBB *ACPMBB = dyn_cast<ARMConstantPoolMBB>(ACPV); 250226633Sdim return ACPMBB && ACPMBB->MBB == MBB && 251226633Sdim ARMConstantPoolValue::hasSameValue(ACPV); 252226633Sdim} 253226633Sdim 254226633Sdimvoid ARMConstantPoolMBB::addSelectionDAGCSEId(FoldingSetNodeID &ID) { 255226633Sdim ID.AddPointer(MBB); 256226633Sdim ARMConstantPoolValue::addSelectionDAGCSEId(ID); 257226633Sdim} 258226633Sdim 259226633Sdimvoid ARMConstantPoolMBB::print(raw_ostream &O) const { 260234353Sdim O << "BB#" << MBB->getNumber(); 261226633Sdim ARMConstantPoolValue::print(O); 262226633Sdim} 263