tilde_const.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  1. gb_internal bool cg_is_expr_constant_zero(Ast *expr) {
  2. GB_ASSERT(expr != nullptr);
  3. auto v = exact_value_to_integer(expr->tav.value);
  4. if (v.kind == ExactValue_Integer) {
  5. return big_int_cmp_zero(&v.value_integer) == 0;
  6. }
  7. return false;
  8. }
  9. gb_internal cgValue cg_const_nil(cgModule *m, cgProcedure *p, Type *type) {
  10. GB_ASSERT(m != nullptr);
  11. Type *original_type = type;
  12. type = core_type(type);
  13. i64 size = type_size_of(type);
  14. i64 align = type_align_of(type);
  15. TB_DataType dt = cg_data_type(type);
  16. if (TB_IS_VOID_TYPE(dt)) {
  17. char name[32] = {};
  18. gb_snprintf(name, 31, "cnil$%u", 1+m->const_nil_guid.fetch_add(1));
  19. TB_Global *global = tb_global_create(m->mod, -1, name, cg_debug_type(m, type), TB_LINKAGE_PRIVATE);
  20. tb_global_set_storage(m->mod, tb_module_get_rdata(m->mod), global, size, align, 0);
  21. TB_Symbol *symbol = cast(TB_Symbol *)global;
  22. if (p) {
  23. TB_Node *node = tb_inst_get_symbol_address(p->func, symbol);
  24. return cg_lvalue_addr(node, type);
  25. } else {
  26. return cg_value(symbol, type);
  27. }
  28. }
  29. if (is_type_internally_pointer_like(type)) {
  30. return cg_value(tb_inst_uint(p->func, dt, 0), type);
  31. } else if (is_type_integer(type) || is_type_boolean(type) || is_type_bit_set(type)) {
  32. return cg_value(tb_inst_uint(p->func, dt, 0), type);
  33. } else if (is_type_float(type)) {
  34. switch (size) {
  35. case 2:
  36. return cg_value(tb_inst_uint(p->func, dt, 0), type);
  37. case 4:
  38. return cg_value(tb_inst_float32(p->func, 0), type);
  39. case 8:
  40. return cg_value(tb_inst_float64(p->func, 0), type);
  41. }
  42. }
  43. GB_PANIC("TODO(bill): cg_const_nil %s", type_to_string(original_type));
  44. return {};
  45. }
  46. gb_internal cgValue cg_const_nil(cgProcedure *p, Type *type) {
  47. return cg_const_nil(p->module, p, type);
  48. }
  49. gb_internal TB_Global *cg_global_const_cstring(cgModule *m, String const &str, Type *type) {
  50. char name[32] = {};
  51. gb_snprintf(name, 31, "csb$%u", 1+m->const_nil_guid.fetch_add(1));
  52. TB_Global *global = tb_global_create(m->mod, -1, name, cg_debug_type(m, type), TB_LINKAGE_PRIVATE);
  53. i64 size = str.len+1;
  54. tb_global_set_storage(m->mod, tb_module_get_rdata(m->mod), global, size, 1, 1);
  55. u8 *data = cast(u8 *)tb_global_add_region(m->mod, global, 0, size+1);
  56. gb_memcopy(data, str.text, str.len);
  57. data[str.len] = 0;
  58. return global;
  59. }
  60. gb_internal void cg_write_big_int_at_ptr(void *dst, BigInt const *a, Type *original_type) {
  61. GB_ASSERT(build_context.endian_kind == TargetEndian_Little);
  62. size_t sz = cast(size_t)type_size_of(original_type);
  63. if (big_int_is_zero(a)) {
  64. gb_memset(dst, 0, sz);
  65. return;
  66. }
  67. u64 rop64[4] = {}; // 2 u64 is the maximum we will ever need, so doubling it will be fine :P
  68. u8 *rop = cast(u8 *)rop64;
  69. size_t max_count = 0;
  70. size_t written = 0;
  71. size_t size = 1;
  72. size_t nails = 0;
  73. mp_endian endian = MP_LITTLE_ENDIAN;
  74. max_count = mp_pack_count(a, nails, size);
  75. if (sz < max_count) {
  76. debug_print_big_int(a);
  77. gb_printf_err("%s -> %tu\n", type_to_string(original_type), sz);;
  78. }
  79. GB_ASSERT_MSG(sz >= max_count, "max_count: %tu, sz: %tu, written: %tu, type %s", max_count, sz, written, type_to_string(original_type));
  80. GB_ASSERT(gb_size_of(rop64) >= sz);
  81. mp_err err = mp_pack(rop, sz, &written,
  82. MP_LSB_FIRST,
  83. size, endian, nails,
  84. a);
  85. GB_ASSERT(err == MP_OKAY);
  86. if (!is_type_endian_little(original_type)) {
  87. for (size_t i = 0; i < sz/2; i++) {
  88. u8 tmp = rop[i];
  89. rop[i] = rop[sz-1-i];
  90. rop[sz-1-i] = tmp;
  91. }
  92. }
  93. gb_memcopy(dst, rop, sz);
  94. return;
  95. }
  96. gb_internal void cg_write_int_at_ptr(void *dst, i64 i, Type *original_type) {
  97. ExactValue v = exact_value_i64(i);
  98. cg_write_big_int_at_ptr(dst, &v.value_integer, original_type);
  99. }
  100. gb_internal void cg_write_uint_at_ptr(void *dst, u64 i, Type *original_type) {
  101. ExactValue v = exact_value_u64(i);
  102. cg_write_big_int_at_ptr(dst, &v.value_integer, original_type);
  103. }
  104. gb_internal TB_Global *cg_global_const_string(cgModule *m, String const &str, Type *type) {
  105. if (is_type_cstring(type)) {
  106. return cg_global_const_cstring(m, str, type);
  107. }
  108. GB_ASSERT(is_type_string(type));
  109. char name[32] = {};
  110. gb_snprintf(name, 31, "csl$%u", 1+m->const_nil_guid.fetch_add(1));
  111. TB_Global *global = tb_global_create(m->mod, -1, name, cg_debug_type(m, type), TB_LINKAGE_PRIVATE);
  112. i64 size = type_size_of(type);
  113. i64 align = type_align_of(type);
  114. tb_global_set_storage(m->mod, tb_module_get_rdata(m->mod), global, size, align, 2);
  115. tb_global_add_symbol_reloc(m->mod, global, 0, cast(TB_Symbol *)cg_global_const_cstring(m, str, t_cstring));
  116. void *len_ptr = tb_global_add_region(m->mod, global, build_context.int_size, build_context.int_size);
  117. cg_write_int_at_ptr(len_ptr, str.len, t_int);
  118. return global;
  119. }
  120. gb_internal cgValue cg_const_value(cgModule *m, cgProcedure *p, Type *type, ExactValue const &value, bool allow_local = true) {
  121. TB_Node *node = nullptr;
  122. bool is_local = allow_local && p != nullptr;
  123. gb_unused(is_local);
  124. TB_DataType dt = cg_data_type(type);
  125. switch (value.kind) {
  126. case ExactValue_Invalid:
  127. return cg_const_nil(p, type);
  128. case ExactValue_Typeid:
  129. return cg_typeid(p, value.value_typeid);
  130. case ExactValue_Procedure:
  131. {
  132. Ast *expr = unparen_expr(value.value_procedure);
  133. Entity *e = entity_of_node(expr);
  134. if (e != nullptr) {
  135. cgValue found = cg_find_procedure_value_from_entity(m, e);
  136. GB_ASSERT(are_types_identical(type, found.type));
  137. return found;
  138. }
  139. GB_PANIC("TODO(bill): cg_const_value ExactValue_Procedure");
  140. }
  141. break;
  142. }
  143. Type *original_type = type;
  144. switch (value.kind) {
  145. case ExactValue_Bool:
  146. GB_ASSERT(!TB_IS_VOID_TYPE(dt));
  147. return cg_value(tb_inst_uint(p->func, dt, value.value_bool), type);
  148. case ExactValue_Integer:
  149. GB_ASSERT(!TB_IS_VOID_TYPE(dt));
  150. // GB_ASSERT(dt.raw != TB_TYPE_I128.raw);
  151. if (is_type_unsigned(type)) {
  152. u64 i = exact_value_to_u64(value);
  153. return cg_value(tb_inst_uint(p->func, dt, i), type);
  154. } else {
  155. i64 i = exact_value_to_i64(value);
  156. return cg_value(tb_inst_sint(p->func, dt, i), type);
  157. }
  158. break;
  159. case ExactValue_Float:
  160. GB_ASSERT(!TB_IS_VOID_TYPE(dt));
  161. GB_ASSERT(dt.raw != TB_TYPE_F16.raw);
  162. GB_ASSERT(!is_type_different_to_arch_endianness(type));
  163. {
  164. f64 f = exact_value_to_f64(value);
  165. if (type_size_of(type) == 8) {
  166. return cg_value(tb_inst_float64(p->func, f), type);
  167. } else {
  168. return cg_value(tb_inst_float32(p->func, cast(f32)f), type);
  169. }
  170. }
  171. break;
  172. case ExactValue_String:
  173. {
  174. TB_Symbol *symbol = cast(TB_Symbol *)cg_global_const_string(m, value.value_string, type);
  175. if (p) {
  176. TB_Node *node = tb_inst_get_symbol_address(p->func, symbol);
  177. return cg_lvalue_addr(node, type);
  178. } else {
  179. return cg_value(symbol, type);
  180. }
  181. }
  182. case ExactValue_Pointer:
  183. return cg_value(tb_inst_uint(p->func, dt, exact_value_to_u64(value)), type);
  184. case ExactValue_Compound:
  185. if (is_type_struct(type)) {
  186. ast_node(cl, CompoundLit, value.value_compound);
  187. if (cl->elems.count == 0) {
  188. return cg_const_nil(m, p, original_type);
  189. }
  190. Type *bt = base_type(type);
  191. if (bt->Struct.is_raw_union) {
  192. return cg_const_nil(m, p, original_type);
  193. }
  194. TEMPORARY_ALLOCATOR_GUARD();
  195. isize value_count = bt->Struct.fields.count;
  196. cgValue * values = gb_alloc_array(temporary_allocator(), cgValue, value_count);
  197. bool * visited = gb_alloc_array(temporary_allocator(), bool, value_count);
  198. char name[32] = {};
  199. gb_snprintf(name, 31, "complit$%u", 1+m->const_nil_guid.fetch_add(1));
  200. TB_Global *global = tb_global_create(m->mod, -1, name, cg_debug_type(m, original_type), TB_LINKAGE_PRIVATE);
  201. i64 size = type_size_of(original_type);
  202. i64 align = type_align_of(original_type);
  203. // READ ONLY?
  204. TB_ModuleSection *section = tb_module_get_rdata(m->mod);
  205. tb_global_set_storage(m->mod, section, global, size, align, value_count);
  206. if (cl->elems[0]->kind == Ast_FieldValue) {
  207. // isize elem_count = cl->elems.count;
  208. // for (isize i = 0; i < elem_count; i++) {
  209. // ast_node(fv, FieldValue, cl->elems[i]);
  210. // String name = fv->field->Ident.token.string;
  211. // TypeAndValue tav = fv->value->tav;
  212. // GB_ASSERT(tav.mode != Addressing_Invalid);
  213. // Selection sel = lookup_field(type, name, false);
  214. // GB_ASSERT(!sel.indirect);
  215. // Entity *f = type->Struct.fields[sel.index[0]];
  216. // i32 index = field_remapping[f->Variable.field_index];
  217. // if (elem_type_can_be_constant(f->type)) {
  218. // if (sel.index.count == 1) {
  219. // values[index] = lb_const_value(m, f->type, tav.value, allow_local).value;
  220. // visited[index] = true;
  221. // } else {
  222. // if (!visited[index]) {
  223. // values[index] = lb_const_value(m, f->type, {}, false).value;
  224. // visited[index] = true;
  225. // }
  226. // unsigned idx_list_len = cast(unsigned)sel.index.count-1;
  227. // unsigned *idx_list = gb_alloc_array(temporary_allocator(), unsigned, idx_list_len);
  228. // if (lb_is_nested_possibly_constant(type, sel, fv->value)) {
  229. // bool is_constant = true;
  230. // Type *cv_type = f->type;
  231. // for (isize j = 1; j < sel.index.count; j++) {
  232. // i32 index = sel.index[j];
  233. // Type *cvt = base_type(cv_type);
  234. // if (cvt->kind == Type_Struct) {
  235. // if (cvt->Struct.is_raw_union) {
  236. // // sanity check which should have been caught by `lb_is_nested_possibly_constant`
  237. // is_constant = false;
  238. // break;
  239. // }
  240. // cv_type = cvt->Struct.fields[index]->type;
  241. // if (is_type_struct(cvt)) {
  242. // auto cv_field_remapping = lb_get_struct_remapping(m, cvt);
  243. // unsigned remapped_index = cast(unsigned)cv_field_remapping[index];
  244. // idx_list[j-1] = remapped_index;
  245. // } else {
  246. // idx_list[j-1] = cast(unsigned)index;
  247. // }
  248. // } else if (cvt->kind == Type_Array) {
  249. // cv_type = cvt->Array.elem;
  250. // idx_list[j-1] = cast(unsigned)index;
  251. // } else {
  252. // GB_PANIC("UNKNOWN TYPE: %s", type_to_string(cv_type));
  253. // }
  254. // }
  255. // if (is_constant) {
  256. // LLVMValueRef elem_value = lb_const_value(m, tav.type, tav.value, allow_local).value;
  257. // GB_ASSERT(LLVMIsConstant(elem_value));
  258. // values[index] = LLVMConstInsertValue(values[index], elem_value, idx_list, idx_list_len);
  259. // }
  260. // }
  261. // }
  262. // }
  263. // }
  264. } else {
  265. for_array(i, cl->elems) {
  266. i64 field_index = i;
  267. Ast *elem = cl->elems[i];
  268. TypeAndValue tav = elem->tav;
  269. Entity *f = bt->Struct.fields[field_index];
  270. if (!elem_type_can_be_constant(f->type)) {
  271. continue;
  272. }
  273. i64 offset = bt->Struct.offsets[field_index];
  274. i64 size = type_size_of(f->type);
  275. ExactValue value = {};
  276. if (tav.mode != Addressing_Invalid) {
  277. value = tav.value;
  278. }
  279. GB_ASSERT(is_type_endian_little(f->type));
  280. GB_ASSERT(!is_type_different_to_arch_endianness(type));
  281. if (value.kind != ExactValue_Invalid) {
  282. switch (value.kind) {
  283. case ExactValue_Bool:
  284. {
  285. bool *res = cast(bool *)tb_global_add_region(m->mod, global, offset, size);
  286. *res = !!value.value_bool;
  287. }
  288. break;
  289. case ExactValue_Integer:
  290. {
  291. void *res = tb_global_add_region(m->mod, global, offset, size);
  292. cg_write_big_int_at_ptr(res, &value.value_integer, f->type);
  293. }
  294. break;
  295. case ExactValue_Float:
  296. {
  297. f64 f = exact_value_to_f64(value);
  298. void *res = tb_global_add_region(m->mod, global, offset, size);
  299. switch (size) {
  300. case 2: *(u16 *)res = f32_to_f16(cast(f32)f); break;
  301. case 4: *(f32 *)res = cast(f32)f; break;
  302. case 8: *(f64 *)res = cast(f64)f; break;
  303. }
  304. }
  305. break;
  306. case ExactValue_Pointer:
  307. {
  308. void *res = tb_global_add_region(m->mod, global, offset, size);
  309. *(u64 *)res = exact_value_to_u64(value);
  310. }
  311. break;
  312. case ExactValue_String:
  313. {
  314. TB_Symbol *symbol = cast(TB_Symbol *)cg_global_const_string(m, value.value_string, f->type);
  315. tb_global_add_symbol_reloc(m->mod, global, offset, symbol);
  316. }
  317. break;
  318. case ExactValue_Typeid:
  319. {
  320. void *dst = tb_global_add_region(m->mod, global, offset, size);
  321. u64 id = cg_typeid_as_u64(m, value.value_typeid);
  322. cg_write_uint_at_ptr(dst, id, t_typeid);
  323. }
  324. break;
  325. case ExactValue_Procedure:
  326. GB_PANIC("TODO(bill): nested procedure values/literals\n");
  327. break;
  328. case ExactValue_Compound:
  329. GB_PANIC("TODO(bill): nested compound literals\n");
  330. break;
  331. case ExactValue_Complex:
  332. GB_PANIC("TODO(bill): nested complex literals\n");
  333. break;
  334. case ExactValue_Quaternion:
  335. GB_PANIC("TODO(bill): nested quaternions literals\n");
  336. break;
  337. default:
  338. GB_PANIC("%s", type_to_string(f->type));
  339. break;
  340. }
  341. visited[i] = true;
  342. continue;
  343. }
  344. values[i] = cg_const_value(m, p, f->type, value, allow_local);
  345. visited[i] = true;
  346. }
  347. }
  348. TB_Symbol *symbol = cast(TB_Symbol *)global;
  349. if (p) {
  350. TB_Node *node = tb_inst_get_symbol_address(p->func, symbol);
  351. return cg_lvalue_addr(node, type);
  352. } else {
  353. return cg_value(symbol, type);
  354. }
  355. } else {
  356. GB_PANIC("TODO(bill): constant compound literal for %s", type_to_string(type));
  357. }
  358. break;
  359. }
  360. GB_ASSERT(node != nullptr);
  361. return cg_value(node, type);
  362. }
  363. gb_internal cgValue cg_const_value(cgProcedure *p, Type *type, ExactValue const &value) {
  364. GB_ASSERT(p != nullptr);
  365. return cg_const_value(p->module, p, type, value);
  366. }
  367. gb_internal cgValue cg_const_int(cgProcedure *p, Type *type, i64 i) {
  368. return cg_const_value(p, type, exact_value_i64(i));
  369. }
  370. gb_internal cgValue cg_const_bool(cgProcedure *p, Type *type, bool v) {
  371. return cg_value(tb_inst_bool(p->func, v), type);
  372. }