blob: 0b368953e12478a2afed037a4d78d4686ee86c35 [file] [log] [blame]
Richard Smith6ebe4512012-10-09 19:34:32 +00001//===-- ubsan_value.cc ----------------------------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// Representation of a runtime value, as marshaled from the generated code to
11// the ubsan runtime.
12//
13//===----------------------------------------------------------------------===//
14
15#include "ubsan_value.h"
16
17using namespace __ubsan;
18
19SIntMax Value::getSIntValue() const {
20 CHECK(getType().isSignedIntegerTy());
21 if (isInlineInt()) {
22 // Val was zero-extended to ValueHandle. Sign-extend from original width
23 // to SIntMax.
24 const unsigned ExtraBits =
25 sizeof(SIntMax) * 8 - getType().getIntegerBitWidth();
26 return SIntMax(Val) << ExtraBits >> ExtraBits;
27 }
28 if (getType().getIntegerBitWidth() == 64)
29 return *reinterpret_cast<s64*>(Val);
30#ifdef HAVE_INT128_T
31 if (getType().getIntegerBitWidth() == 128)
32 return *reinterpret_cast<s128*>(Val);
33#endif
34 UNREACHABLE("unexpected bit width");
35}
36
37UIntMax Value::getUIntValue() const {
38 CHECK(getType().isUnsignedIntegerTy());
39 if (isInlineInt())
40 return Val;
41 if (getType().getIntegerBitWidth() == 64)
42 return *reinterpret_cast<u64*>(Val);
43#ifdef HAVE_INT128_T
44 if (getType().getIntegerBitWidth() == 128)
45 return *reinterpret_cast<u128*>(Val);
46#endif
47 UNREACHABLE("unexpected bit width");
48}
49
50UIntMax Value::getPositiveIntValue() const {
51 if (getType().isUnsignedIntegerTy())
52 return getUIntValue();
53 SIntMax Val = getSIntValue();
54 CHECK(Val >= 0);
55 return Val;
56}
57
58/// Get the floating-point value of this object, extended to a long double.
59/// These are always passed by address (our calling convention doesn't allow
60/// them to be passed in floating-point registers, so this has little cost).
Richard Smith58561702012-10-12 22:57:15 +000061FloatMax Value::getFloatValue() const {
Richard Smith6ebe4512012-10-09 19:34:32 +000062 CHECK(getType().isFloatTy());
63 switch (getType().getFloatBitWidth()) {
64#if 0
65 // FIXME: OpenCL / NEON 'half' type. LLVM can't lower the conversion
66 // from this to 'long double'.
67 case 16: return *reinterpret_cast<__fp16*>(Val);
68#endif
69 case 32: return *reinterpret_cast<float*>(Val);
70 case 64: return *reinterpret_cast<double*>(Val);
71 case 80: return *reinterpret_cast<long double*>(Val);
72 case 128: return *reinterpret_cast<long double*>(Val);
73 }
74 UNREACHABLE("unexpected floating point bit width");
75}