|
45 | 45 | #include "builtins.h"
|
46 | 46 | #include "print-tree.h"
|
47 | 47 | #include "attribs.h"
|
| 48 | +#include "target.h" |
48 | 49 |
|
49 | 50 | #include "rust-location.h"
|
50 | 51 | #include "rust-linemap.h"
|
@@ -95,9 +96,104 @@ namespace Backend {
|
95 | 96 |
|
96 | 97 | // Define the built-in functions that are exposed to GCCRust.
|
97 | 98 |
|
| 99 | +// (u, i) X (8, 16, 32, 64, 128) |
| 100 | +tree rust_int_trees[10]; |
| 101 | +const char *rust_int_names[10] |
| 102 | + = {"u8", "u16", "u32", "u64", "u128", "i8", "i16", "i32", "i64", "i128"}; |
| 103 | + |
| 104 | +static void |
| 105 | +setup_normal_integers () |
| 106 | +{ |
| 107 | + // we should have QImode |
| 108 | + rust_int_trees[0] = make_unsigned_type (8); |
| 109 | + rust_int_trees[5] = make_signed_type (8); |
| 110 | + |
| 111 | + // look through integer types intended for C |
| 112 | + const int normal_int_sizes[4] |
| 113 | + = {INT_TYPE_SIZE, SHORT_TYPE_SIZE, LONG_TYPE_SIZE, LONG_LONG_TYPE_SIZE}; |
| 114 | + const tree normal_int_trees[8] |
| 115 | + = {unsigned_type_node, integer_type_node, |
| 116 | + short_unsigned_type_node, short_integer_type_node, |
| 117 | + long_unsigned_type_node, long_integer_type_node, |
| 118 | + long_long_unsigned_type_node, long_long_integer_type_node}; |
| 119 | + |
| 120 | + for (size_t i = 0; i < 4; i++) |
| 121 | + { |
| 122 | + // check for a power of 2 or 0 |
| 123 | + if (normal_int_sizes[i] & (normal_int_sizes[i] - 1)) |
| 124 | + continue; |
| 125 | + |
| 126 | + // assume size is not 0 |
| 127 | + int idx = __builtin_ctz (normal_int_sizes[i]) - 3; |
| 128 | + if (idx < 0 || idx > 5) |
| 129 | + continue; |
| 130 | + |
| 131 | + if (rust_int_trees[idx] != NULL_TREE) |
| 132 | + continue; |
| 133 | + |
| 134 | + rust_int_trees[idx] = normal_int_trees[2 * i]; |
| 135 | + rust_int_trees[5 + idx] = normal_int_trees[2 * i + 1]; |
| 136 | + } |
| 137 | + |
| 138 | + // look through int_n_data for more integer types |
| 139 | + for (size_t i = 0, j = 0; i < 5 && j < NUM_INT_N_ENTS;) |
| 140 | + { |
| 141 | + if (rust_int_trees[i] != NULL_TREE) |
| 142 | + { |
| 143 | + i++; |
| 144 | + continue; |
| 145 | + } |
| 146 | + |
| 147 | + if (!int_n_enabled_p[j] || int_n_data[j].bitsize < (8u << i)) |
| 148 | + { |
| 149 | + j++; |
| 150 | + } |
| 151 | + else if (int_n_data[j].bitsize > (8u << i)) |
| 152 | + { |
| 153 | + i++; |
| 154 | + } |
| 155 | + else |
| 156 | + { |
| 157 | + rust_int_trees[i] = make_unsigned_type (8 << i); |
| 158 | + rust_int_trees[5 + i] = make_signed_type (8 << i); |
| 159 | + i++; |
| 160 | + j++; |
| 161 | + } |
| 162 | + } |
| 163 | + |
| 164 | + // use _BitInt where we have to (and can) |
| 165 | + for (int i = 0; i < 5; i++) |
| 166 | + { |
| 167 | + if (rust_int_trees[i] == NULL_TREE) |
| 168 | + { |
| 169 | + bitint_info b_info; |
| 170 | + if (targetm.c.bitint_type_info (8 << i, &b_info)) |
| 171 | + { |
| 172 | + rust_debug ("filling in integer size %u with _BitInt", 8u << i); |
| 173 | + rust_int_trees[i] = build_bitint_type (8 << i, true); |
| 174 | + rust_int_trees[5 + i] = build_bitint_type (8 << i, false); |
| 175 | + } |
| 176 | + } |
| 177 | + } |
| 178 | + |
| 179 | + // TODO: bootleg _BitInt where necessary? |
| 180 | + |
| 181 | + // not much can be done for now -- fill with error_mark_node |
| 182 | + for (size_t i = 0; i < 10; i++) |
| 183 | + if (rust_int_trees[i] == NULL_TREE) |
| 184 | + rust_int_trees[i] = error_mark_node; |
| 185 | + |
| 186 | + // name types |
| 187 | + for (size_t i = 0; i < 10; i++) |
| 188 | + rust_int_trees[i] |
| 189 | + = named_type (rust_int_names[i], rust_int_trees[i], BUILTINS_LOCATION); |
| 190 | +} |
| 191 | + |
98 | 192 | void
|
99 | 193 | init ()
|
100 | 194 | {
|
| 195 | + setup_normal_integers (); |
| 196 | + |
101 | 197 | /* We need to define the fetch_and_add functions, since we use them
|
102 | 198 | for ++ and --. */
|
103 | 199 | // tree t = this->integer_type (true, BITS_PER_UNIT)->get_tree ();
|
|
0 commit comments