ARMConstantPoolValue.cpp revision 5405d58e21402a8ba3aaaa580ca65155bee00443
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
2446510a73e977273ec67747eb34cbdb43f815e451Dan GohmanARMConstantPoolValue::ARMConstantPoolValue(const Constant *cval, unsigned id,
253fb2b1ede30193b59a651328a946174196b20610Jim Grosbach                                           ARMCP::ARMCPKind K,
260ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio                                           unsigned char PCAdj,
273a2429a86c50a89c3321c741b85fa7d1fe668b38Jim Grosbach                                           ARMCP::ARMCPModifier Modif,
2864f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio                                           bool AddCA)
29db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  : MachineConstantPoolValue((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,
363a2429a86c50a89c3321c741b85fa7d1fe668b38Jim Grosbach                                           ARMCP::ARMCPModifier Modif,
3764f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio                                           bool AddCA)
38db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  : MachineConstantPoolValue((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
4246510a73e977273ec67747eb34cbdb43f815e451Dan GohmanARMConstantPoolValue::ARMConstantPoolValue(const GlobalValue *gv,
433a2429a86c50a89c3321c741b85fa7d1fe668b38Jim Grosbach                                           ARMCP::ARMCPModifier Modif)
44db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  : MachineConstantPoolValue((Type*)Type::getInt32Ty(gv->getContext())),
4528989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson    CVal(gv), S(NULL), LabelId(0), Kind(ARMCP::CPValue), PCAdjust(0),
46a63bf704b4ebdc109f1514bed82fdad7ad3eb70bJan Wen Voung    Modifier(Modif), AddCurrentAddress(false) {}
47a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
4846510a73e977273ec67747eb34cbdb43f815e451Dan Gohmanconst GlobalValue *ARMConstantPoolValue::getGV() const {
4928989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson  return dyn_cast_or_null<GlobalValue>(CVal);
5028989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson}
5128989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson
5246510a73e977273ec67747eb34cbdb43f815e451Dan Gohmanconst BlockAddress *ARMConstantPoolValue::getBlockAddress() const {
5328989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson  return dyn_cast_or_null<BlockAddress>(CVal);
5428989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson}
5528989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson
56de0e11c8f3f9ad60844c210bf68111db6e25f9a9Evan Chengstatic bool CPV_streq(const char *S1, const char *S2) {
57de0e11c8f3f9ad60844c210bf68111db6e25f9a9Evan Cheng  if (S1 == S2)
58de0e11c8f3f9ad60844c210bf68111db6e25f9a9Evan Cheng    return true;
59de0e11c8f3f9ad60844c210bf68111db6e25f9a9Evan Cheng  if (S1 && S2 && strcmp(S1, S2) == 0)
60de0e11c8f3f9ad60844c210bf68111db6e25f9a9Evan Cheng    return true;
61de0e11c8f3f9ad60844c210bf68111db6e25f9a9Evan Cheng  return false;
62de0e11c8f3f9ad60844c210bf68111db6e25f9a9Evan Cheng}
63de0e11c8f3f9ad60844c210bf68111db6e25f9a9Evan Cheng
64a8e2989ece6dc46df59b0768184028257f913843Evan Chengint ARMConstantPoolValue::getExistingMachineCPValue(MachineConstantPool *CP,
65a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                                    unsigned Alignment) {
661606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng  unsigned AlignMask = Alignment - 1;
67a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const std::vector<MachineConstantPoolEntry> Constants = CP->getConstants();
68a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
69a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (Constants[i].isMachineConstantPoolEntry() &&
701606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng        (Constants[i].getAlignment() & AlignMask) == 0) {
71a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      ARMConstantPoolValue *CPV =
72a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        (ARMConstantPoolValue *)Constants[i].Val.MachineCPVal;
7328989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson      if (CPV->CVal == CVal &&
74c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng          CPV->LabelId == LabelId &&
7578e5c1140adc926e7c004748c1c912bfddd875b4Evan Cheng          CPV->PCAdjust == PCAdjust &&
76de0e11c8f3f9ad60844c210bf68111db6e25f9a9Evan Cheng          CPV_streq(CPV->S, S) &&
773a2429a86c50a89c3321c741b85fa7d1fe668b38Jim Grosbach          CPV->Modifier == Modifier)
78a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        return i;
79a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    }
80a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
81a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
82a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  return -1;
83a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
84a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
85327365e58fd8aa2159be77f86b8017da814c59e1Benjamin KramerARMConstantPoolValue::~ARMConstantPoolValue() {
86f128787f941bb372e80d69b786ed144d8606a292Jim Grosbach  free((void*)S);
87f128787f941bb372e80d69b786ed144d8606a292Jim Grosbach}
88f128787f941bb372e80d69b786ed144d8606a292Jim Grosbach
89a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid
905405d58e21402a8ba3aaaa580ca65155bee00443Jim GrosbachARMConstantPoolValue::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
9128989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson  ID.AddPointer(CVal);
92c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng  ID.AddPointer(S);
93a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  ID.AddInteger(LabelId);
94a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  ID.AddInteger(PCAdjust);
95a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
96a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
9778e5c1140adc926e7c004748c1c912bfddd875b4Evan Chengbool
9878e5c1140adc926e7c004748c1c912bfddd875b4Evan ChengARMConstantPoolValue::hasSameValue(ARMConstantPoolValue *ACPV) {
9978e5c1140adc926e7c004748c1c912bfddd875b4Evan Cheng  if (ACPV->Kind == Kind &&
10078e5c1140adc926e7c004748c1c912bfddd875b4Evan Cheng      ACPV->CVal == CVal &&
10178e5c1140adc926e7c004748c1c912bfddd875b4Evan Cheng      ACPV->PCAdjust == PCAdjust &&
102de0e11c8f3f9ad60844c210bf68111db6e25f9a9Evan Cheng      CPV_streq(ACPV->S, S) &&
1033a2429a86c50a89c3321c741b85fa7d1fe668b38Jim Grosbach      ACPV->Modifier == Modifier) {
10478e5c1140adc926e7c004748c1c912bfddd875b4Evan Cheng    if (ACPV->LabelId == LabelId)
10578e5c1140adc926e7c004748c1c912bfddd875b4Evan Cheng      return true;
10678e5c1140adc926e7c004748c1c912bfddd875b4Evan Cheng    // Two PC relative constpool entries containing the same GV address or
10778e5c1140adc926e7c004748c1c912bfddd875b4Evan Cheng    // external symbols. FIXME: What about blockaddress?
10878e5c1140adc926e7c004748c1c912bfddd875b4Evan Cheng    if (Kind == ARMCP::CPValue || Kind == ARMCP::CPExtSymbol)
10978e5c1140adc926e7c004748c1c912bfddd875b4Evan Cheng      return true;
11078e5c1140adc926e7c004748c1c912bfddd875b4Evan Cheng  }
11178e5c1140adc926e7c004748c1c912bfddd875b4Evan Cheng  return false;
11278e5c1140adc926e7c004748c1c912bfddd875b4Evan Cheng}
11378e5c1140adc926e7c004748c1c912bfddd875b4Evan Cheng
1145be59eace58e5a92bb851c4885f9cea7236ac30fEvan Chengvoid ARMConstantPoolValue::dump() const {
115705e07f578e2b3af47ddab610feb4e7f2d3063a5Chris Lattner  errs() << "  " << *this;
1165be59eace58e5a92bb851c4885f9cea7236ac30fEvan Cheng}
1175be59eace58e5a92bb851c4885f9cea7236ac30fEvan Cheng
1185be59eace58e5a92bb851c4885f9cea7236ac30fEvan Cheng
119944fac71e082cc2664cc71b4d3f6c72bab7143fbChris Lattnervoid ARMConstantPoolValue::print(raw_ostream &O) const {
12028989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson  if (CVal)
12128989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson    O << CVal->getName();
122c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng  else
123c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng    O << S;
1243a2429a86c50a89c3321c741b85fa7d1fe668b38Jim Grosbach  if (Modifier) O << "(" << getModifierText() << ")";
12564f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio  if (PCAdjust != 0) {
12625e04788bfddc54dde7bed65302146b46089a166Evan Cheng    O << "-(LPC" << LabelId << "+" << (unsigned)PCAdjust;
12725e04788bfddc54dde7bed65302146b46089a166Evan Cheng    if (AddCurrentAddress) O << "-.";
12864f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio    O << ")";
12964f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio  }
130a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
131