MimIR
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
core.h
Go to the documentation of this file.
1#pragma once
2
3#include <mim/axm.h>
4#include <mim/world.h>
5
7
8namespace mim::plug::core {
9
10constexpr flags_t icmp_mask = 0b00011111; // low 5 bits encode X Y G L E as bits 4..0
11
12/// @name Mode
13///@{
14/// What should happen if Idx arithmetic overflows?
15enum class Mode : nat_t {
16 none = 0, ///< Wrap around.
17 nsw = 1 << 0, ///< No Signed Wrap around.
18 nuw = 1 << 1, ///< No Unsigned Wrap around.
20};
21
22/// Give Mode as mim::plug::core::Mode, mim::nat_t or const Def*.
23using VMode = std::variant<Mode, nat_t, const Def*>;
24
25/// mim::plug::core::VMode -> const Def*.
26inline const Def* mode(World& w, VMode m) {
27 if (auto def = std::get_if<const Def*>(&m)) return *def;
28 if (auto nat = std::get_if<nat_t>(&m)) return w.lit_nat(*nat);
29 return w.lit_nat(std::to_underlying(std::get<Mode>(m)));
30}
31///@}
32
33/// @name core.trait
34///@{
35inline const Def* op(trait o, const Def* type) {
36 World& w = type->world();
37 return w.app(w.annex(o), type);
38}
39///@}
40
41/// @name core.pe
42///@{
43inline const Def* op(pe o, const Def* def) {
44 World& w = def->world();
45 return w.app(w.app(w.annex(o), def->type()), def);
46}
47///@}
48
49/// @name core.bit2
50///@{
51/// Use like this: `a op b = tab[a][b]`
52constexpr std::array<std::array<u64, 2>, 2> make_truth_table(bit2 id) {
53 return {
54 {{sub_t(id) & sub_t(0b0001) ? u64(-1) : 0, sub_t(id) & sub_t(0b0010) ? u64(-1) : 0},
55 {sub_t(id) & sub_t(0b0100) ? u64(-1) : 0, sub_t(id) & sub_t(0b1000) ? u64(-1) : 0}}
56 };
57}
58///@}
59
60} // namespace mim::plug::core
61
62namespace mim {
63
64/// @name is_commutative/is_associative
65///@{
66// clang-format off
67constexpr bool is_commutative(plug::core::nat id) { return id == plug::core::nat ::add || id == plug::core::nat ::mul; }
68constexpr bool is_commutative(plug::core::ncmp id) { return id == plug::core::ncmp:: e || id == plug::core::ncmp:: ne; }
70constexpr bool is_commutative(plug::core::icmp id) { return id == plug::core::icmp:: e || id == plug::core::icmp:: ne; }
71// clang-format on
72
73constexpr bool is_commutative(plug::core::bit2 id) {
74 auto tab = make_truth_table(id);
75 return tab[0][1] == tab[1][0];
76}
77
78constexpr bool is_associative(plug::core::bit2 id) {
79 switch (id) {
87 case plug::core::bit2::f: return true;
88 default: return false;
89 }
90}
91
92// clang-format off
93constexpr bool is_associative(plug::core::nat id) { return is_commutative(id); }
94constexpr bool is_associative(plug::core::ncmp id) { return is_commutative(id); }
95constexpr bool is_associative(plug::core::icmp id) { return is_commutative(id); }
96constexpr bool is_associative(plug::core::wrap id) { return is_commutative(id); }
97// clang-format on
98///@}
99
100} // namespace mim
101
102#ifndef DOXYGEN
103template<>
104struct fe::is_bit_enum<mim::plug::core::Mode> : std::true_type {};
105#endif
Base class for all Defs.
Definition def.h:289
World & world() const noexcept
Definition def.h:1105
const Def * type() const noexcept
Yields the "raw" type of this Def (maybe nullptr).
Definition def.h:1119
The World represents the whole program and manages creation of MimIR nodes (Defs).
Definition world.h:43
The core Plugin
Definition core.h:8
std::variant< Mode, nat_t, const Def * > VMode
Give Mode as mim::plug::core::Mode, mim::nat_t or const Def*.
Definition core.h:23
const Def * op(trait o, const Def *type)
Definition core.h:35
constexpr std::array< std::array< u64, 2 >, 2 > make_truth_table(bit2 id)
Definition core.h:52
constexpr flags_t icmp_mask
Definition core.h:10
@ nuw
No Unsigned Wrap around.
Definition core.h:18
@ none
Wrap around.
Definition core.h:16
@ nsw
No Signed Wrap around.
Definition core.h:17
Definition ast.h:16
u64 nat_t
Definition types.h:37
u8 sub_t
Definition types.h:42
u64 flags_t
Definition types.h:39
constexpr bool is_commutative(Id)
Definition axm.h:171
constexpr bool is_associative(Id id)
Definition axm.h:177
uint64_t u64
Definition types.h:27