summaryrefslogtreecommitdiff
path: root/src/trans/target.hpp
blob: 3433483bbb4b4bbbfea5847aca4b833a858f54c8 (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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
 * MRustC - Rust Compiler
 * - By John Hodge (Mutabah/thePowersGang)
 *
 * trans/target.hpp
 * - Target-specific information
 */
#pragma once

#include <cstddef>
#include <hir/type.hpp>
#include <hir_typeck/static.hpp>

enum class CodegenMode
{
    Gnu11,
    Msvc,
};

// NOTE: The default architecture is an unnamed 32-bit little-endian arch with all types natively aligned
struct TargetArch
{
    ::std::string   m_name;
    unsigned    m_pointer_bits;
    bool    m_big_endian;

    struct Atomics {
        bool u8 = true;
        bool u16 = true;
        bool u32 = true;
        bool u64 = false;
        bool ptr = true;
        Atomics(bool u8 = true, bool u16 = true, bool u32 = true, bool u64 = false, bool ptr = true)
            :u8(u8)
            ,u16(u16)
            ,u32(u32)
            ,u64(u64)
            ,ptr(ptr)
        {
        }
    } m_atomics;

    struct Alignments {
        uint8_t u16;
        uint8_t u32;
        uint8_t u64;
        uint8_t u128;
        uint8_t f32;
        uint8_t f64;
        uint8_t ptr;
        Alignments(uint8_t u16 = 2, uint8_t u32 = 4, uint8_t u64 = 8, uint8_t u128 = 16, uint8_t f32 = 4, uint8_t f64 = 8, uint8_t ptr = 4)
            :u16 (u16)
            ,u32 (u32 )
            ,u64 (u64 )
            ,u128(u128)
            ,f32 (f32 )
            ,f64 (f64 )
            ,ptr (ptr )
        {
        }
    } m_alignments;
};
struct BackendOptsC
{
    CodegenMode m_codegen_mode;
    bool    m_emulated_i128;    // Influences the chosen alignment for i128/u128
    ::std::string   m_c_compiler;   // MSVC arch / GNU triplet
    ::std::vector< ::std::string>   m_compiler_opts;
    ::std::vector< ::std::string>   m_linker_opts;
};
struct TargetSpec
{
    ::std::string   m_family;
    ::std::string   m_os_name;
    ::std::string   m_env_name;

    BackendOptsC    m_backend_c;
    TargetArch  m_arch;
};

struct TypeRepr
{
    size_t  align = 0;
    size_t  size = 0;

    struct FieldPath {
        size_t  index;
        size_t  size;
        ::std::vector<size_t>   sub_fields;
    };
    TAGGED_UNION(VariantMode, None,
    (None, struct {
        }),
    // Tag is a fixed set of values in an offset.
    (Values, struct {
        FieldPath   field;
        ::std::vector<uint64_t> values;
        }),
    // Tag is based on a range of values
    //(Ranges, struct {
    //    size_t  offset;
    //    size_t  size;
    //    ::std::vector<::std::pair<uint64_t,uint64_t>> values;
    //    }),
    // Tag is a boolean based on if a region is zero/non-zero
    // Only valid for two-element enums
    (NonZero, struct {
        FieldPath   field;
        uint8_t zero_variant;
        })
    );
    VariantMode variants;

    struct Field {
        size_t  offset;
        ::HIR::TypeRef  ty;
    };
    ::std::vector<Field>    fields;
};

extern const TargetSpec& Target_GetCurSpec();
extern void Target_SetCfg(const ::std::string& target_name);
extern void Target_ExportCurSpec(const ::std::string& filename);

extern bool Target_GetSizeOf(const Span& sp, const StaticTraitResolve& resolve, const ::HIR::TypeRef& ty, size_t& out_size);
extern bool Target_GetAlignOf(const Span& sp, const StaticTraitResolve& resolve, const ::HIR::TypeRef& ty, size_t& out_align);
extern bool Target_GetSizeAndAlignOf(const Span& sp, const StaticTraitResolve& resolve, const ::HIR::TypeRef& ty, size_t& out_size, size_t& out_align);

extern const TypeRepr* Target_GetTypeRepr(const Span& sp, const StaticTraitResolve& resolve, const ::HIR::TypeRef& ty);

extern const ::HIR::TypeRef& Target_GetInnerType(const Span& sp, const StaticTraitResolve& resolve, const TypeRepr& repr, size_t idx, const ::std::vector<size_t>& sub_fields={}, size_t ofs=0);