ARMConstantPoolValue.cpp revision 78e5c1140adc926e7c004748c1c912bfddd875b4
1a8e2989ece6dc46df59b0768184028257f913843Evan Cheng//===- ARMConstantPoolValue.cpp - ARM constantpool value --------*- C++ -*-===//
2a8e2989ece6dc46df59b0768184028257f913843Evan Cheng//
3a8e2989ece6dc46df59b0768184028257f913843Evan Cheng//                     The LLVM Compiler Infrastructure
4a8e2989ece6dc46df59b0768184028257f913843Evan Cheng//
54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source
64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details.
7a8e2989ece6dc46df59b0768184028257f913843Evan Cheng//
8a8e2989ece6dc46df59b0768184028257f913843Evan Cheng//===----------------------------------------------------------------------===//
9a8e2989ece6dc46df59b0768184028257f913843Evan Cheng//
10a8e2989ece6dc46df59b0768184028257f913843Evan Cheng// This file implements the ARM specific constantpool value class.
11a8e2989ece6dc46df59b0768184028257f913843Evan Cheng//
12a8e2989ece6dc46df59b0768184028257f913843Evan Cheng//===----------------------------------------------------------------------===//
13a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
14a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "ARMConstantPoolValue.h"
15a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "llvm/ADT/FoldingSet.h"
1628989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson#include "llvm/Constant.h"
1728989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson#include "llvm/Constants.h"
18a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "llvm/GlobalValue.h"
19c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng#include "llvm/Type.h"
20944fac71e082cc2664cc71b4d3f6c72bab7143fbChris Lattner#include "llvm/Support/raw_ostream.h"
21f128787f941bb372e80d69b786ed144d8606a292Jim Grosbach#include <cstdlib>
22a8e2989ece6dc46df59b0768184028257f913843Evan Chengusing namespace llvm;
23a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
2428989a8ddc665dce4dde368e8c000a5769871b63Bob WilsonARMConstantPoolValue::ARMConstantPoolValue(Constant *cval, unsigned id,
253fb2b1ede30193b59a651328a946174196b20610Jim Grosbach                                           ARMCP::ARMCPKind K,
260ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio                                           unsigned char PCAdj,
2764f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio                                           const char *Modif,
2864f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio                                           bool AddCA)
2928989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson  : MachineConstantPoolValue((const Type*)cval->getType()),
3028989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson    CVal(cval), S(NULL), LabelId(id), Kind(K), PCAdjust(PCAdj),
3164f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio    Modifier(Modif), AddCurrentAddress(AddCA) {}
32c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng
331d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen AndersonARMConstantPoolValue::ARMConstantPoolValue(LLVMContext &C,
341d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson                                           const char *s, unsigned id,
350ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio                                           unsigned char PCAdj,
3664f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio                                           const char *Modif,
3764f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio                                           bool AddCA)
381d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson  : MachineConstantPoolValue((const Type*)Type::getInt32Ty(C)),
3928989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson    CVal(NULL), S(strdup(s)), LabelId(id), Kind(ARMCP::CPExtSymbol),
4028989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson    PCAdjust(PCAdj), Modifier(Modif), AddCurrentAddress(AddCA) {}
410ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio
42e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan ChengARMConstantPoolValue::ARMConstantPoolValue(GlobalValue *gv, const char *Modif)
431d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson  : MachineConstantPoolValue((const Type*)Type::getInt32Ty(gv->getContext())),
4428989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson    CVal(gv), S(NULL), LabelId(0), Kind(ARMCP::CPValue), PCAdjust(0),
450ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio    Modifier(Modif) {}
46a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
4728989a8ddc665dce4dde368e8c000a5769871b63Bob WilsonGlobalValue *ARMConstantPoolValue::getGV() const {
4828989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson  return dyn_cast_or_null<GlobalValue>(CVal);
4928989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson}
5028989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson
5128989a8ddc665dce4dde368e8c000a5769871b63Bob WilsonBlockAddress *ARMConstantPoolValue::getBlockAddress() const {
5228989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson  return dyn_cast_or_null<BlockAddress>(CVal);
5328989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson}
5428989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson
55a8e2989ece6dc46df59b0768184028257f913843Evan Chengint ARMConstantPoolValue::getExistingMachineCPValue(MachineConstantPool *CP,
56a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                                    unsigned Alignment) {
571606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng  unsigned AlignMask = Alignment - 1;
58a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const std::vector<MachineConstantPoolEntry> Constants = CP->getConstants();
59a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
60a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (Constants[i].isMachineConstantPoolEntry() &&
611606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng        (Constants[i].getAlignment() & AlignMask) == 0) {
62a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      ARMConstantPoolValue *CPV =
63a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        (ARMConstantPoolValue *)Constants[i].Val.MachineCPVal;
6428989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson      if (CPV->CVal == CVal &&
65c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng          CPV->LabelId == LabelId &&
6678e5c1140adc926e7c004748c1c912bfddd875b4Evan Cheng          CPV->PCAdjust == PCAdjust &&
6778e5c1140adc926e7c004748c1c912bfddd875b4Evan Cheng          (CPV->S == S || strcmp(CPV->S, S) == 0) &&
6878e5c1140adc926e7c004748c1c912bfddd875b4Evan Cheng          (CPV->Modifier == Modifier || strcmp(CPV->Modifier, Modifier) == 0))
69a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        return i;
70a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    }
71a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
72a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
73a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  return -1;
74a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
75a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
76327365e58fd8aa2159be77f86b8017da814c59e1Benjamin KramerARMConstantPoolValue::~ARMConstantPoolValue() {
77f128787f941bb372e80d69b786ed144d8606a292Jim Grosbach  free((void*)S);
78f128787f941bb372e80d69b786ed144d8606a292Jim Grosbach}
79f128787f941bb372e80d69b786ed144d8606a292Jim Grosbach
80a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid
81a8e2989ece6dc46df59b0768184028257f913843Evan ChengARMConstantPoolValue::AddSelectionDAGCSEId(FoldingSetNodeID &ID) {
8228989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson  ID.AddPointer(CVal);
83c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng  ID.AddPointer(S);
84a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  ID.AddInteger(LabelId);
85a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  ID.AddInteger(PCAdjust);
86a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
87a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
8878e5c1140adc926e7c004748c1c912bfddd875b4Evan Chengbool
8978e5c1140adc926e7c004748c1c912bfddd875b4Evan ChengARMConstantPoolValue::hasSameValue(ARMConstantPoolValue *ACPV) {
9078e5c1140adc926e7c004748c1c912bfddd875b4Evan Cheng  if (ACPV->Kind == Kind &&
9178e5c1140adc926e7c004748c1c912bfddd875b4Evan Cheng      ACPV->CVal == CVal &&
9278e5c1140adc926e7c004748c1c912bfddd875b4Evan Cheng      ACPV->PCAdjust == PCAdjust &&
9378e5c1140adc926e7c004748c1c912bfddd875b4Evan Cheng      (ACPV->S == S || strcmp(ACPV->S, S) == 0) &&
9478e5c1140adc926e7c004748c1c912bfddd875b4Evan Cheng      (ACPV->Modifier == Modifier || strcmp(ACPV->Modifier, Modifier) == 0)) {
9578e5c1140adc926e7c004748c1c912bfddd875b4Evan Cheng    if (ACPV->LabelId == LabelId)
9678e5c1140adc926e7c004748c1c912bfddd875b4Evan Cheng      return true;
9778e5c1140adc926e7c004748c1c912bfddd875b4Evan Cheng    // Two PC relative constpool entries containing the same GV address or
9878e5c1140adc926e7c004748c1c912bfddd875b4Evan Cheng    // external symbols. FIXME: What about blockaddress?
9978e5c1140adc926e7c004748c1c912bfddd875b4Evan Cheng    if (Kind == ARMCP::CPValue || Kind == ARMCP::CPExtSymbol)
10078e5c1140adc926e7c004748c1c912bfddd875b4Evan Cheng      return true;
10178e5c1140adc926e7c004748c1c912bfddd875b4Evan Cheng  }
10278e5c1140adc926e7c004748c1c912bfddd875b4Evan Cheng  return false;
10378e5c1140adc926e7c004748c1c912bfddd875b4Evan Cheng}
10478e5c1140adc926e7c004748c1c912bfddd875b4Evan Cheng
1055be59eace58e5a92bb851c4885f9cea7236ac30fEvan Chengvoid ARMConstantPoolValue::dump() const {
106705e07f578e2b3af47ddab610feb4e7f2d3063a5Chris Lattner  errs() << "  " << *this;
1075be59eace58e5a92bb851c4885f9cea7236ac30fEvan Cheng}
1085be59eace58e5a92bb851c4885f9cea7236ac30fEvan Cheng
1095be59eace58e5a92bb851c4885f9cea7236ac30fEvan Cheng
110944fac71e082cc2664cc71b4d3f6c72bab7143fbChris Lattnervoid ARMConstantPoolValue::print(raw_ostream &O) const {
11128989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson  if (CVal)
11228989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson    O << CVal->getName();
113c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng  else
114c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng    O << S;
1150ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio  if (Modifier) O << "(" << Modifier << ")";
11664f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio  if (PCAdjust != 0) {
11725e04788bfddc54dde7bed65302146b46089a166Evan Cheng    O << "-(LPC" << LabelId << "+" << (unsigned)PCAdjust;
11825e04788bfddc54dde7bed65302146b46089a166Evan Cheng    if (AddCurrentAddress) O << "-.";
11964f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio    O << ")";
12064f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio  }
121a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
122