blob: ee7d43e919004a9b81cb1f1cca6c2450d1f1a52f [file] [log] [blame]
Chris Lattner2f7c9632001-06-06 20:29:01 +00001//===- ConstantHandling.cpp - Implement ConstantHandling.h ----------------===//
2//
3// This file implements the various intrinsic operations, on constant values.
4//
5//===----------------------------------------------------------------------===//
6
Chris Lattner65b529f2002-04-08 20:18:09 +00007#include "llvm/ConstantHandling.h"
Chris Lattner0a144ad2002-05-03 21:41:07 +00008#include <cmath>
Chris Lattnerd42d4922001-06-30 04:36:40 +00009
Chris Lattner61607ee2001-09-09 21:01:20 +000010AnnotationID ConstRules::AID(AnnotationManager::getID("opt::ConstRules",
11 &ConstRules::find));
12
Chris Lattner2f7c9632001-06-06 20:29:01 +000013//===----------------------------------------------------------------------===//
14// TemplateRules Class
15//===----------------------------------------------------------------------===//
16//
17// TemplateRules - Implement a subclass of ConstRules that provides all
18// operations as noops. All other rules classes inherit from this class so
19// that if functionality is needed in the future, it can simply be added here
20// and to ConstRules without changing anything else...
21//
22// This class also provides subclasses with typesafe implementations of methods
23// so that don't have to do type casting.
24//
25template<class ArgType, class SubClassName>
26class TemplateRules : public ConstRules {
27
28 //===--------------------------------------------------------------------===//
29 // Redirecting functions that cast to the appropriate types
30 //===--------------------------------------------------------------------===//
31
Chris Lattner3462ae32001-12-03 22:26:30 +000032 virtual Constant *op_not(const Constant *V) const {
Chris Lattner2f7c9632001-06-06 20:29:01 +000033 return SubClassName::Not((const ArgType *)V);
34 }
35
36
Chris Lattner3462ae32001-12-03 22:26:30 +000037 virtual Constant *add(const Constant *V1,
38 const Constant *V2) const {
Chris Lattner2f7c9632001-06-06 20:29:01 +000039 return SubClassName::Add((const ArgType *)V1, (const ArgType *)V2);
40 }
41
Chris Lattner3462ae32001-12-03 22:26:30 +000042 virtual Constant *sub(const Constant *V1,
43 const Constant *V2) const {
Chris Lattner2f7c9632001-06-06 20:29:01 +000044 return SubClassName::Sub((const ArgType *)V1, (const ArgType *)V2);
45 }
46
Chris Lattner3462ae32001-12-03 22:26:30 +000047 virtual Constant *mul(const Constant *V1,
48 const Constant *V2) const {
Chris Lattner4f6031f2001-07-20 19:15:36 +000049 return SubClassName::Mul((const ArgType *)V1, (const ArgType *)V2);
50 }
Chris Lattneraf259a72002-04-07 08:10:14 +000051 virtual Constant *div(const Constant *V1,
52 const Constant *V2) const {
53 return SubClassName::Div((const ArgType *)V1, (const ArgType *)V2);
54 }
Chris Lattner0a144ad2002-05-03 21:41:07 +000055 virtual Constant *rem(const Constant *V1,
56 const Constant *V2) const {
57 return SubClassName::Rem((const ArgType *)V1, (const ArgType *)V2);
58 }
Chris Lattner6670d862002-05-06 03:00:54 +000059 virtual Constant *shl(const Constant *V1,
60 const Constant *V2) const {
61 return SubClassName::Shl((const ArgType *)V1, (const ArgType *)V2);
62 }
63 virtual Constant *shr(const Constant *V1,
64 const Constant *V2) const {
65 return SubClassName::Shr((const ArgType *)V1, (const ArgType *)V2);
66 }
Chris Lattner4f6031f2001-07-20 19:15:36 +000067
Chris Lattner3462ae32001-12-03 22:26:30 +000068 virtual ConstantBool *lessthan(const Constant *V1,
69 const Constant *V2) const {
Chris Lattner2f7c9632001-06-06 20:29:01 +000070 return SubClassName::LessThan((const ArgType *)V1, (const ArgType *)V2);
71 }
72
Chris Lattner55406842001-07-21 19:10:49 +000073 // Casting operators. ick
Chris Lattner3462ae32001-12-03 22:26:30 +000074 virtual ConstantBool *castToBool(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +000075 return SubClassName::CastToBool((const ArgType*)V);
76 }
Chris Lattner3462ae32001-12-03 22:26:30 +000077 virtual ConstantSInt *castToSByte(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +000078 return SubClassName::CastToSByte((const ArgType*)V);
79 }
Chris Lattner3462ae32001-12-03 22:26:30 +000080 virtual ConstantUInt *castToUByte(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +000081 return SubClassName::CastToUByte((const ArgType*)V);
82 }
Chris Lattner3462ae32001-12-03 22:26:30 +000083 virtual ConstantSInt *castToShort(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +000084 return SubClassName::CastToShort((const ArgType*)V);
85 }
Chris Lattner3462ae32001-12-03 22:26:30 +000086 virtual ConstantUInt *castToUShort(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +000087 return SubClassName::CastToUShort((const ArgType*)V);
88 }
Chris Lattner3462ae32001-12-03 22:26:30 +000089 virtual ConstantSInt *castToInt(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +000090 return SubClassName::CastToInt((const ArgType*)V);
91 }
Chris Lattner3462ae32001-12-03 22:26:30 +000092 virtual ConstantUInt *castToUInt(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +000093 return SubClassName::CastToUInt((const ArgType*)V);
94 }
Chris Lattner3462ae32001-12-03 22:26:30 +000095 virtual ConstantSInt *castToLong(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +000096 return SubClassName::CastToLong((const ArgType*)V);
97 }
Chris Lattner3462ae32001-12-03 22:26:30 +000098 virtual ConstantUInt *castToULong(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +000099 return SubClassName::CastToULong((const ArgType*)V);
100 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000101 virtual ConstantFP *castToFloat(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +0000102 return SubClassName::CastToFloat((const ArgType*)V);
103 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000104 virtual ConstantFP *castToDouble(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +0000105 return SubClassName::CastToDouble((const ArgType*)V);
106 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000107 virtual ConstantPointer *castToPointer(const Constant *V,
108 const PointerType *Ty) const {
Chris Lattner977f0042001-11-01 05:55:13 +0000109 return SubClassName::CastToPointer((const ArgType*)V, Ty);
110 }
Chris Lattner55406842001-07-21 19:10:49 +0000111
Chris Lattner2f7c9632001-06-06 20:29:01 +0000112 //===--------------------------------------------------------------------===//
113 // Default "noop" implementations
114 //===--------------------------------------------------------------------===//
115
Chris Lattner3462ae32001-12-03 22:26:30 +0000116 inline static Constant *Not(const ArgType *V) { return 0; }
Chris Lattner2f7c9632001-06-06 20:29:01 +0000117
Chris Lattner3462ae32001-12-03 22:26:30 +0000118 inline static Constant *Add(const ArgType *V1, const ArgType *V2) {
Chris Lattner2f7c9632001-06-06 20:29:01 +0000119 return 0;
120 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000121 inline static Constant *Sub(const ArgType *V1, const ArgType *V2) {
Chris Lattner2f7c9632001-06-06 20:29:01 +0000122 return 0;
123 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000124 inline static Constant *Mul(const ArgType *V1, const ArgType *V2) {
Chris Lattner4f6031f2001-07-20 19:15:36 +0000125 return 0;
126 }
Chris Lattneraf259a72002-04-07 08:10:14 +0000127 inline static Constant *Div(const ArgType *V1, const ArgType *V2) {
128 return 0;
129 }
Chris Lattner0a144ad2002-05-03 21:41:07 +0000130 inline static Constant *Rem(const ArgType *V1, const ArgType *V2) {
131 return 0;
132 }
Chris Lattner6670d862002-05-06 03:00:54 +0000133 inline static Constant *Shl(const ArgType *V1, const ArgType *V2) {
134 return 0;
135 }
136 inline static Constant *Shr(const ArgType *V1, const ArgType *V2) {
137 return 0;
138 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000139 inline static ConstantBool *LessThan(const ArgType *V1, const ArgType *V2) {
Chris Lattner2f7c9632001-06-06 20:29:01 +0000140 return 0;
141 }
Chris Lattner55406842001-07-21 19:10:49 +0000142
143 // Casting operators. ick
Chris Lattner3462ae32001-12-03 22:26:30 +0000144 inline static ConstantBool *CastToBool (const Constant *V) { return 0; }
145 inline static ConstantSInt *CastToSByte (const Constant *V) { return 0; }
146 inline static ConstantUInt *CastToUByte (const Constant *V) { return 0; }
147 inline static ConstantSInt *CastToShort (const Constant *V) { return 0; }
148 inline static ConstantUInt *CastToUShort(const Constant *V) { return 0; }
149 inline static ConstantSInt *CastToInt (const Constant *V) { return 0; }
150 inline static ConstantUInt *CastToUInt (const Constant *V) { return 0; }
151 inline static ConstantSInt *CastToLong (const Constant *V) { return 0; }
152 inline static ConstantUInt *CastToULong (const Constant *V) { return 0; }
153 inline static ConstantFP *CastToFloat (const Constant *V) { return 0; }
154 inline static ConstantFP *CastToDouble(const Constant *V) { return 0; }
155 inline static ConstantPointer *CastToPointer(const Constant *,
156 const PointerType *) {return 0;}
Chris Lattner2f7c9632001-06-06 20:29:01 +0000157};
158
159
160
161//===----------------------------------------------------------------------===//
162// EmptyRules Class
163//===----------------------------------------------------------------------===//
164//
165// EmptyRules provides a concrete base class of ConstRules that does nothing
166//
Chris Lattner3462ae32001-12-03 22:26:30 +0000167struct EmptyRules : public TemplateRules<Constant, EmptyRules> {
Chris Lattner61607ee2001-09-09 21:01:20 +0000168};
Chris Lattner2f7c9632001-06-06 20:29:01 +0000169
170
171
172//===----------------------------------------------------------------------===//
173// BoolRules Class
174//===----------------------------------------------------------------------===//
175//
176// BoolRules provides a concrete base class of ConstRules for the 'bool' type.
177//
Chris Lattner3462ae32001-12-03 22:26:30 +0000178struct BoolRules : public TemplateRules<ConstantBool, BoolRules> {
Chris Lattner2f7c9632001-06-06 20:29:01 +0000179
Chris Lattner3462ae32001-12-03 22:26:30 +0000180 inline static Constant *Not(const ConstantBool *V) {
181 return ConstantBool::get(!V->getValue());
Chris Lattner2f7c9632001-06-06 20:29:01 +0000182 }
183
Chris Lattner3462ae32001-12-03 22:26:30 +0000184 inline static Constant *Or(const ConstantBool *V1,
185 const ConstantBool *V2) {
186 return ConstantBool::get(V1->getValue() | V2->getValue());
Chris Lattner2f7c9632001-06-06 20:29:01 +0000187 }
188
Chris Lattner3462ae32001-12-03 22:26:30 +0000189 inline static Constant *And(const ConstantBool *V1,
190 const ConstantBool *V2) {
191 return ConstantBool::get(V1->getValue() & V2->getValue());
Chris Lattner2f7c9632001-06-06 20:29:01 +0000192 }
Chris Lattner61607ee2001-09-09 21:01:20 +0000193};
Chris Lattner2f7c9632001-06-06 20:29:01 +0000194
195
196//===----------------------------------------------------------------------===//
Chris Lattner977f0042001-11-01 05:55:13 +0000197// PointerRules Class
198//===----------------------------------------------------------------------===//
199//
200// PointerRules provides a concrete base class of ConstRules for pointer types
201//
Chris Lattner3462ae32001-12-03 22:26:30 +0000202struct PointerRules : public TemplateRules<ConstantPointer, PointerRules> {
203 inline static ConstantBool *CastToBool (const Constant *V) {
204 if (V->isNullValue()) return ConstantBool::False;
Chris Lattner977f0042001-11-01 05:55:13 +0000205 return 0; // Can't const prop other types of pointers
206 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000207 inline static ConstantSInt *CastToSByte (const Constant *V) {
208 if (V->isNullValue()) return ConstantSInt::get(Type::SByteTy, 0);
Chris Lattner977f0042001-11-01 05:55:13 +0000209 return 0; // Can't const prop other types of pointers
210 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000211 inline static ConstantUInt *CastToUByte (const Constant *V) {
212 if (V->isNullValue()) return ConstantUInt::get(Type::UByteTy, 0);
Chris Lattner977f0042001-11-01 05:55:13 +0000213 return 0; // Can't const prop other types of pointers
214 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000215 inline static ConstantSInt *CastToShort (const Constant *V) {
216 if (V->isNullValue()) return ConstantSInt::get(Type::ShortTy, 0);
Chris Lattner977f0042001-11-01 05:55:13 +0000217 return 0; // Can't const prop other types of pointers
218 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000219 inline static ConstantUInt *CastToUShort(const Constant *V) {
220 if (V->isNullValue()) return ConstantUInt::get(Type::UShortTy, 0);
Chris Lattner977f0042001-11-01 05:55:13 +0000221 return 0; // Can't const prop other types of pointers
222 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000223 inline static ConstantSInt *CastToInt (const Constant *V) {
224 if (V->isNullValue()) return ConstantSInt::get(Type::IntTy, 0);
Chris Lattner977f0042001-11-01 05:55:13 +0000225 return 0; // Can't const prop other types of pointers
226 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000227 inline static ConstantUInt *CastToUInt (const Constant *V) {
228 if (V->isNullValue()) return ConstantUInt::get(Type::UIntTy, 0);
Chris Lattner977f0042001-11-01 05:55:13 +0000229 return 0; // Can't const prop other types of pointers
230 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000231 inline static ConstantSInt *CastToLong (const Constant *V) {
232 if (V->isNullValue()) return ConstantSInt::get(Type::LongTy, 0);
Chris Lattner977f0042001-11-01 05:55:13 +0000233 return 0; // Can't const prop other types of pointers
234 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000235 inline static ConstantUInt *CastToULong (const Constant *V) {
236 if (V->isNullValue()) return ConstantUInt::get(Type::ULongTy, 0);
Chris Lattner977f0042001-11-01 05:55:13 +0000237 return 0; // Can't const prop other types of pointers
238 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000239 inline static ConstantFP *CastToFloat (const Constant *V) {
240 if (V->isNullValue()) return ConstantFP::get(Type::FloatTy, 0);
Chris Lattner977f0042001-11-01 05:55:13 +0000241 return 0; // Can't const prop other types of pointers
242 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000243 inline static ConstantFP *CastToDouble(const Constant *V) {
244 if (V->isNullValue()) return ConstantFP::get(Type::DoubleTy, 0);
Chris Lattner977f0042001-11-01 05:55:13 +0000245 return 0; // Can't const prop other types of pointers
246 }
247
Chris Lattner3462ae32001-12-03 22:26:30 +0000248 inline static ConstantPointer *CastToPointer(const ConstantPointer *V,
249 const PointerType *PTy) {
Chris Lattner62af86e2002-05-03 20:09:52 +0000250 if (V->getType() == PTy)
251 return const_cast<ConstantPointer*>(V); // Allow cast %PTy %ptr to %PTy
Chris Lattner977f0042001-11-01 05:55:13 +0000252 if (V->isNullValue())
Chris Lattner3462ae32001-12-03 22:26:30 +0000253 return ConstantPointerNull::get(PTy);
Chris Lattner977f0042001-11-01 05:55:13 +0000254 return 0; // Can't const prop other types of pointers
255 }
256};
257
258
259//===----------------------------------------------------------------------===//
Chris Lattner2f7c9632001-06-06 20:29:01 +0000260// DirectRules Class
261//===----------------------------------------------------------------------===//
262//
263// DirectRules provides a concrete base classes of ConstRules for a variety of
264// different types. This allows the C++ compiler to automatically generate our
265// constant handling operations in a typesafe and accurate manner.
266//
Chris Lattner0a144ad2002-05-03 21:41:07 +0000267template<class ConstantClass, class BuiltinType, Type **Ty, class SuperClass>
268struct DirectRules : public TemplateRules<ConstantClass, SuperClass> {
Chris Lattner3462ae32001-12-03 22:26:30 +0000269 inline static Constant *Add(const ConstantClass *V1,
270 const ConstantClass *V2) {
Chris Lattner2f7c9632001-06-06 20:29:01 +0000271 BuiltinType Result = (BuiltinType)V1->getValue() +
272 (BuiltinType)V2->getValue();
Chris Lattner3462ae32001-12-03 22:26:30 +0000273 return ConstantClass::get(*Ty, Result);
Chris Lattner2f7c9632001-06-06 20:29:01 +0000274 }
275
Chris Lattner3462ae32001-12-03 22:26:30 +0000276 inline static Constant *Sub(const ConstantClass *V1,
277 const ConstantClass *V2) {
Chris Lattner2f7c9632001-06-06 20:29:01 +0000278 BuiltinType Result = (BuiltinType)V1->getValue() -
279 (BuiltinType)V2->getValue();
Chris Lattner3462ae32001-12-03 22:26:30 +0000280 return ConstantClass::get(*Ty, Result);
Chris Lattner2f7c9632001-06-06 20:29:01 +0000281 }
282
Chris Lattner3462ae32001-12-03 22:26:30 +0000283 inline static Constant *Mul(const ConstantClass *V1,
284 const ConstantClass *V2) {
Chris Lattner4f6031f2001-07-20 19:15:36 +0000285 BuiltinType Result = (BuiltinType)V1->getValue() *
286 (BuiltinType)V2->getValue();
Chris Lattner3462ae32001-12-03 22:26:30 +0000287 return ConstantClass::get(*Ty, Result);
Chris Lattner4f6031f2001-07-20 19:15:36 +0000288 }
289
Chris Lattner0a144ad2002-05-03 21:41:07 +0000290 inline static Constant *Div(const ConstantClass *V1,
Chris Lattneraf259a72002-04-07 08:10:14 +0000291 const ConstantClass *V2) {
Chris Lattner0a144ad2002-05-03 21:41:07 +0000292 if (V2->isNullValue()) return 0;
Chris Lattneraf259a72002-04-07 08:10:14 +0000293 BuiltinType Result = (BuiltinType)V1->getValue() /
294 (BuiltinType)V2->getValue();
295 return ConstantClass::get(*Ty, Result);
296 }
297
Chris Lattner3462ae32001-12-03 22:26:30 +0000298 inline static ConstantBool *LessThan(const ConstantClass *V1,
299 const ConstantClass *V2) {
Chris Lattner2f7c9632001-06-06 20:29:01 +0000300 bool Result = (BuiltinType)V1->getValue() < (BuiltinType)V2->getValue();
Chris Lattner3462ae32001-12-03 22:26:30 +0000301 return ConstantBool::get(Result);
Chris Lattner2f7c9632001-06-06 20:29:01 +0000302 }
Chris Lattner55406842001-07-21 19:10:49 +0000303
Chris Lattner3462ae32001-12-03 22:26:30 +0000304 inline static ConstantPointer *CastToPointer(const ConstantClass *V,
305 const PointerType *PTy) {
Chris Lattner977f0042001-11-01 05:55:13 +0000306 if (V->isNullValue()) // Is it a FP or Integral null value?
Chris Lattner3462ae32001-12-03 22:26:30 +0000307 return ConstantPointerNull::get(PTy);
Chris Lattner977f0042001-11-01 05:55:13 +0000308 return 0; // Can't const prop other types of pointers
309 }
310
Chris Lattner55406842001-07-21 19:10:49 +0000311 // Casting operators. ick
312#define DEF_CAST(TYPE, CLASS, CTYPE) \
Chris Lattner3462ae32001-12-03 22:26:30 +0000313 inline static CLASS *CastTo##TYPE (const ConstantClass *V) { \
Chris Lattnerbbb22962001-09-07 16:40:34 +0000314 return CLASS::get(Type::TYPE##Ty, (CTYPE)(BuiltinType)V->getValue()); \
Chris Lattner55406842001-07-21 19:10:49 +0000315 }
316
Chris Lattner3462ae32001-12-03 22:26:30 +0000317 DEF_CAST(Bool , ConstantBool, bool)
318 DEF_CAST(SByte , ConstantSInt, signed char)
319 DEF_CAST(UByte , ConstantUInt, unsigned char)
320 DEF_CAST(Short , ConstantSInt, signed short)
321 DEF_CAST(UShort, ConstantUInt, unsigned short)
322 DEF_CAST(Int , ConstantSInt, signed int)
323 DEF_CAST(UInt , ConstantUInt, unsigned int)
324 DEF_CAST(Long , ConstantSInt, int64_t)
325 DEF_CAST(ULong , ConstantUInt, uint64_t)
326 DEF_CAST(Float , ConstantFP , float)
327 DEF_CAST(Double, ConstantFP , double)
Chris Lattner55406842001-07-21 19:10:49 +0000328#undef DEF_CAST
Chris Lattner2f7c9632001-06-06 20:29:01 +0000329};
330
Chris Lattner62af86e2002-05-03 20:09:52 +0000331
332//===----------------------------------------------------------------------===//
333// DirectIntRules Class
334//===----------------------------------------------------------------------===//
335//
336// DirectIntRules provides implementations of functions that are valid on
337// integer types, but not all types in general.
338//
339template <class ConstantClass, class BuiltinType, Type **Ty>
Chris Lattner0a144ad2002-05-03 21:41:07 +0000340struct DirectIntRules
341 : public DirectRules<ConstantClass, BuiltinType, Ty,
342 DirectIntRules<ConstantClass, BuiltinType, Ty> > {
Chris Lattner62af86e2002-05-03 20:09:52 +0000343 inline static Constant *Not(const ConstantClass *V) {
344 return ConstantClass::get(*Ty, ~(BuiltinType)V->getValue());;
345 }
Chris Lattner0a144ad2002-05-03 21:41:07 +0000346
347 inline static Constant *Rem(const ConstantClass *V1,
348 const ConstantClass *V2) {
349 if (V2->isNullValue()) return 0;
350 BuiltinType Result = (BuiltinType)V1->getValue() %
351 (BuiltinType)V2->getValue();
352 return ConstantClass::get(*Ty, Result);
353 }
Chris Lattner6670d862002-05-06 03:00:54 +0000354
355 inline static Constant *Shl(const ConstantClass *V1,
356 const ConstantClass *V2) {
357 BuiltinType Result = (BuiltinType)V1->getValue() <<
358 (BuiltinType)V2->getValue();
359 return ConstantClass::get(*Ty, Result);
360 }
361
362 inline static Constant *Shr(const ConstantClass *V1,
363 const ConstantClass *V2) {
364 BuiltinType Result = (BuiltinType)V1->getValue() >>
365 (BuiltinType)V2->getValue();
366 return ConstantClass::get(*Ty, Result);
367 }
Chris Lattner0a144ad2002-05-03 21:41:07 +0000368};
369
370
371//===----------------------------------------------------------------------===//
372// DirectFPRules Class
373//===----------------------------------------------------------------------===//
374//
375// DirectFPRules provides implementations of functions that are valid on
376// floating point types, but not all types in general.
377//
378template <class ConstantClass, class BuiltinType, Type **Ty>
379struct DirectFPRules
380 : public DirectRules<ConstantClass, BuiltinType, Ty,
381 DirectFPRules<ConstantClass, BuiltinType, Ty> > {
382 inline static Constant *Rem(const ConstantClass *V1,
383 const ConstantClass *V2) {
384 if (V2->isNullValue()) return 0;
385 BuiltinType Result = std::fmod((BuiltinType)V1->getValue(),
386 (BuiltinType)V2->getValue());
387 return ConstantClass::get(*Ty, Result);
388 }
Chris Lattner62af86e2002-05-03 20:09:52 +0000389};
390
391
Chris Lattner2f7c9632001-06-06 20:29:01 +0000392//===----------------------------------------------------------------------===//
393// DirectRules Subclasses
394//===----------------------------------------------------------------------===//
395//
396// Given the DirectRules class we can now implement lots of types with little
397// code. Thank goodness C++ compilers are great at stomping out layers of
398// templates... can you imagine having to do this all by hand? (/me is lazy :)
399//
Chris Lattner2f7c9632001-06-06 20:29:01 +0000400
401// ConstRules::find - Return the constant rules that take care of the specified
Chris Lattner61607ee2001-09-09 21:01:20 +0000402// type.
Chris Lattner2f7c9632001-06-06 20:29:01 +0000403//
Chris Lattner61607ee2001-09-09 21:01:20 +0000404Annotation *ConstRules::find(AnnotationID AID, const Annotable *TyA, void *) {
405 assert(AID == ConstRules::AID && "Bad annotation for factory!");
Chris Lattner8f191122001-10-01 18:26:53 +0000406 const Type *Ty = cast<Type>((const Value*)TyA);
Chris Lattner61607ee2001-09-09 21:01:20 +0000407
Chris Lattner2f7c9632001-06-06 20:29:01 +0000408 switch (Ty->getPrimitiveID()) {
Chris Lattner977f0042001-11-01 05:55:13 +0000409 case Type::BoolTyID: return new BoolRules();
410 case Type::PointerTyID: return new PointerRules();
Chris Lattner61607ee2001-09-09 21:01:20 +0000411 case Type::SByteTyID:
Chris Lattner62af86e2002-05-03 20:09:52 +0000412 return new DirectIntRules<ConstantSInt, signed char , &Type::SByteTy>();
Chris Lattner61607ee2001-09-09 21:01:20 +0000413 case Type::UByteTyID:
Chris Lattner62af86e2002-05-03 20:09:52 +0000414 return new DirectIntRules<ConstantUInt, unsigned char , &Type::UByteTy>();
Chris Lattner61607ee2001-09-09 21:01:20 +0000415 case Type::ShortTyID:
Chris Lattner62af86e2002-05-03 20:09:52 +0000416 return new DirectIntRules<ConstantSInt, signed short, &Type::ShortTy>();
Chris Lattner61607ee2001-09-09 21:01:20 +0000417 case Type::UShortTyID:
Chris Lattner62af86e2002-05-03 20:09:52 +0000418 return new DirectIntRules<ConstantUInt, unsigned short, &Type::UShortTy>();
Chris Lattner61607ee2001-09-09 21:01:20 +0000419 case Type::IntTyID:
Chris Lattner62af86e2002-05-03 20:09:52 +0000420 return new DirectIntRules<ConstantSInt, signed int , &Type::IntTy>();
Chris Lattner61607ee2001-09-09 21:01:20 +0000421 case Type::UIntTyID:
Chris Lattner62af86e2002-05-03 20:09:52 +0000422 return new DirectIntRules<ConstantUInt, unsigned int , &Type::UIntTy>();
Chris Lattner61607ee2001-09-09 21:01:20 +0000423 case Type::LongTyID:
Chris Lattner62af86e2002-05-03 20:09:52 +0000424 return new DirectIntRules<ConstantSInt, int64_t , &Type::LongTy>();
Chris Lattner61607ee2001-09-09 21:01:20 +0000425 case Type::ULongTyID:
Chris Lattner62af86e2002-05-03 20:09:52 +0000426 return new DirectIntRules<ConstantUInt, uint64_t , &Type::ULongTy>();
Chris Lattner61607ee2001-09-09 21:01:20 +0000427 case Type::FloatTyID:
Chris Lattner0a144ad2002-05-03 21:41:07 +0000428 return new DirectFPRules<ConstantFP , float , &Type::FloatTy>();
Chris Lattner61607ee2001-09-09 21:01:20 +0000429 case Type::DoubleTyID:
Chris Lattner0a144ad2002-05-03 21:41:07 +0000430 return new DirectFPRules<ConstantFP , double , &Type::DoubleTy>();
Chris Lattner61607ee2001-09-09 21:01:20 +0000431 default:
432 return new EmptyRules();
Chris Lattner2f7c9632001-06-06 20:29:01 +0000433 }
Chris Lattner2f7c9632001-06-06 20:29:01 +0000434}