summaryrefslogtreecommitdiff
path: root/willow/lib/IR/Constant.cpp
blob: b9c15c738e4d0560a54f59ce33db467780becfa0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <willow/IR/Constant.h>
#include <utility>
#include <cassert>
#include <ostream>

namespace willow {

ConstantInt::ConstantInt(Type ty, uint64_t val)
    : Constant(ty, ConstantKind::Int) {
  const size_t w = ty.getNumBits();
  assert(w <= 64 && "Come back when im less lazy");
  // assert(!(val >> w) && "Truncated constant");

  if (w == 64)
    bits = val;
  else {
    const uint64_t m = (uint64_t{1} << w) - 1;
    bits = val & m;
  }
}

int64_t ConstantInt::getSExtVal() const {
  const size_t w = getType().getNumBits();

  if (w == 64)
    return static_cast<int64_t>(bits);

  unsigned sh = 64 - w;
  return (static_cast<int64_t>(bits << sh)) >> sh;
}

size_t ConstantInt::Hash::operator()(const ConstantInt::Key &k) const noexcept {
  auto h1 = std::hash<TypeImpl *>{}(k.ty);
  auto h2 = std::hash<uint64_t>{}(k.bits);

  return h1 ^ (h2 + 0x9e3779b97f4a7c15ULL + (h1 << 6) + (h1 >> 2));
}

} // namespace willow

// TODO
std::ostream &operator<<(std::ostream &os, const willow::Constant &c) {
  if (c.isPoison())
    return os << "poison";

  if (c.isInt()) {
    return os << static_cast<const willow::ConstantInt *>(&c)->getSExtVal();
  }

  std::unreachable();

  return os;
}