Add support for casting operators
[oota-llvm.git] / lib / VMCore / iMemory.cpp
1 //===-- iMemory.cpp - Implement Memory instructions --------------*- C++ -*--=//
2 //
3 // This file implements the various memory related classes defined in iMemory.h
4 //
5 //===----------------------------------------------------------------------===//
6
7 #include "llvm/iMemory.h"
8 #include "llvm/ConstPoolVals.h"
9
10 //===----------------------------------------------------------------------===//
11 //                        MemAccessInst Implementation
12 //===----------------------------------------------------------------------===//
13
14 // getIndexedType - Returns the type of the element that would be loaded with
15 // a load instruction with the specified parameters.
16 //
17 // A null type is returned if the indices are invalid for the specified 
18 // pointer type.
19 //
20 /* static */
21 const Type* MemAccessInst::getIndexedType(const Type *Ptr, 
22                                         const vector<ConstPoolVal*> &Idx,
23                                         bool AllowStructLeaf = false) {
24   if (!Ptr->isPointerType()) return 0;   // Type isn't a pointer type!
25  
26   // Get the type pointed to...
27   Ptr = ((const PointerType*)Ptr)->getValueType();
28   
29   if (Ptr->isStructType()) {
30     unsigned CurIDX = 0;
31     while (Ptr->isStructType()) {
32       if (Idx.size() == CurIDX) 
33         return AllowStructLeaf ? Ptr : 0;   // Can't load a whole structure!?!?
34       if (Idx[CurIDX]->getType() != Type::UByteTy) return 0; // Illegal idx
35       unsigned NextIdx = ((ConstPoolUInt*)Idx[CurIDX++])->getValue();
36       
37       const StructType *ST = (const StructType *)Ptr;
38       Ptr = ST->getElementTypes()[NextIdx];
39     }
40     return Ptr;
41   } else if (Ptr->isArrayType()) {
42     assert(0 && "Loading from arrays not implemented yet!");
43   } else {
44     return (Idx.size() == 0) ? Ptr : 0;  // Load directly through ptr
45   }
46 }
47
48 /* static */
49 unsigned int
50 MemAccessInst::getIndexedOfsetForTarget(const Type *Ptr, 
51                                         const vector<ConstPoolVal*> &Idx,
52                                         const TargetMachine& targetMachine)
53 {
54   if (!Ptr->isPointerType())
55     return 0;                           // Type isn't a pointer type!
56  
57   unsigned int curOffset = 0;
58   
59   // Get the type pointed to...
60   Ptr = ((const PointerType*) Ptr)->getValueType();
61   
62   if (Ptr->isStructType()) {
63     unsigned CurIDX = 0;                // which element of Idx vector
64     while (Ptr->isStructType()) {
65       const StructType * SPtr = (StructType *) Ptr;
66       
67       if (Idx.size() == CurIDX) 
68         break;
69       
70       assert (Idx[CurIDX]->getType() == Type::UByteTy && "Illegal struct idx");
71       unsigned NextIdx = ((ConstPoolUInt*)Idx[CurIDX++])->getValue();
72       
73       // add the offset for the current element
74       curOffset += SPtr->getElementOffset(NextIdx, targetMachine);
75       
76       // and update Ptr to refer to current element
77       Ptr = SPtr->getElementTypes()[NextIdx];
78     }
79     return curOffset;
80   } else if (Ptr->isArrayType()) {
81     assert(0 && "Loading from arrays not implemented yet!");
82   } else {
83     assert (Idx.size() == 0 && "Indexing type that is not struct or array?");
84     return 0;                           // Load directly through ptr
85   }
86 }
87   
88
89 //===----------------------------------------------------------------------===//
90 //                           LoadInst Implementation
91 //===----------------------------------------------------------------------===//
92
93 LoadInst::LoadInst(Value *Ptr, const vector<ConstPoolVal*> &Idx,
94                    const string &Name = "")
95   : MemAccessInst(getIndexedType(Ptr->getType(), Idx), Load, Idx, Name)
96 {
97   assert(getIndexedType(Ptr->getType(), Idx) && "Load operands invalid!");
98   Operands.reserve(1+Idx.size());
99   Operands.push_back(Use(Ptr, this));
100   
101   for (unsigned i = 0, E = Idx.size(); i != E; ++i)
102     Operands.push_back(Use(Idx[i], this));
103   
104 }
105
106
107 //===----------------------------------------------------------------------===//
108 //                           StoreInst Implementation
109 //===----------------------------------------------------------------------===//
110
111 StoreInst::StoreInst(Value *Val, Value *Ptr, const vector<ConstPoolVal*> &Idx,
112                      const string &Name = "")
113   : MemAccessInst(Type::VoidTy, Store, Idx, Name) {
114   assert(getIndexedType(Ptr->getType(), Idx) && "Store operands invalid!");
115   
116   Operands.reserve(2+Idx.size());
117   Operands.push_back(Use(Val, this));
118   Operands.push_back(Use(Ptr, this));
119
120   for (unsigned i = 0, E = Idx.size(); i != E; ++i)
121     Operands.push_back(Use(Idx[i], this));
122 }
123
124
125 //===----------------------------------------------------------------------===//
126 //                       GetElementPtrInst Implementation
127 //===----------------------------------------------------------------------===//
128
129 GetElementPtrInst::GetElementPtrInst(Value *Ptr, 
130                                      const vector<ConstPoolVal*> &Idx,
131                                      const string &Name = "")
132   : MemAccessInst(PointerType::getPointerType(getIndexedType(Ptr->getType(),
133                                                              Idx, true)),
134                   GetElementPtr, Idx, Name) {
135   assert(getIndexedType(Ptr->getType(), Idx, true) && "gep operands invalid!");
136   Operands.reserve(1+Idx.size());
137   Operands.push_back(Use(Ptr, this));
138
139   for (unsigned i = 0, E = Idx.size(); i != E; ++i)
140     Operands.push_back(Use(Idx[i], this));
141 }
142
143 bool GetElementPtrInst::isStructSelector() const {
144   return ((PointerType*)Operands[0]->getType())->getValueType()->isStructType();
145 }