| ... | ... | @@ -14,87 +14,163 @@ const Mir = @import("Mir.zig"); |
| 14 | 14 | air: Air, |
| 15 | 15 | liveness: Liveness, |
| 16 | 16 | gpa: Allocator, |
| 17 | | spork8: *Spork8, |
| 18 | 17 | pt: Zcu.PerThread, |
| 19 | 18 | owner_nav: InternPool.Nav.Index, |
| 20 | 19 | func_index: InternPool.Index, |
| 21 | | mir_instructions: *std.MultiArrayList(Mir.Inst), |
| 20 | mir_instructions: std.MultiArrayList(Mir.Inst), |
| 22 | 21 | /// Contains extra data for MIR |
| 23 | | mir_extra: *std.ArrayListUnmanaged(u32), |
| 24 | | start_mir_extra_off: u32, |
| 25 | | |
| 26 | | pub const Error = error{ |
| 27 | | OutOfMemory, |
| 28 | | /// Compiler was asked to operate on a number larger than supported. |
| 29 | | Overflow, |
| 30 | | /// Indicates the error is already stored in Zcu `failed_codegen`. |
| 31 | | CodegenFail, |
| 32 | | }; |
| 33 | | |
| 34 | | pub const Function = extern struct { |
| 35 | | /// Index into `Spork8.mir_instructions`. |
| 36 | | mir_off: u32, |
| 37 | | /// This is unused except for as a safety slice bound and could be removed. |
| 38 | | mir_len: u32, |
| 39 | | /// Index into `Spork8.mir_extra`. |
| 40 | | mir_extra_off: u32, |
| 41 | | /// This is unused except for as a safety slice bound and could be removed. |
| 42 | | mir_extra_len: u32, |
| 43 | | }; |
| 22 | mir_extra: std.ArrayListUnmanaged(u32), |
| 23 | |
| 24 | pub fn legalizeFeatures(_: *const std.Target) *const Air.Legalize.Features { |
| 25 | return comptime &.initMany(&.{ |
| 26 | .expand_bit_cast_safe, |
| 27 | .expand_int_cast_safe, |
| 28 | .expand_int_from_float_safe, |
| 29 | .expand_int_from_float_optimized_safe, |
| 30 | .expand_add_safe, |
| 31 | .expand_sub_safe, |
| 32 | .expand_mul_safe, |
| 33 | |
| 34 | .expand_packed_load, |
| 35 | .expand_packed_store, |
| 36 | .expand_packed_agg_field_val, |
| 37 | .expand_packed_aggregate_init, |
| 38 | .expand_array_to_vector, |
| 39 | |
| 40 | .scalarize_add, |
| 41 | .scalarize_add_optimized, |
| 42 | .scalarize_add_wrap, |
| 43 | .scalarize_add_sat, |
| 44 | .scalarize_sub, |
| 45 | .scalarize_sub_optimized, |
| 46 | .scalarize_sub_wrap, |
| 47 | .scalarize_sub_sat, |
| 48 | .scalarize_mul, |
| 49 | .scalarize_mul_optimized, |
| 50 | .scalarize_mul_wrap, |
| 51 | .scalarize_mul_sat, |
| 52 | .scalarize_div_float, |
| 53 | .scalarize_div_float_optimized, |
| 54 | .scalarize_div_trunc, |
| 55 | .scalarize_div_trunc_optimized, |
| 56 | .scalarize_div_floor, |
| 57 | .scalarize_div_floor_optimized, |
| 58 | .scalarize_div_ceil, |
| 59 | .scalarize_div_ceil_optimized, |
| 60 | .scalarize_div_exact, |
| 61 | .scalarize_div_exact_optimized, |
| 62 | .scalarize_rem, |
| 63 | .scalarize_rem_optimized, |
| 64 | .scalarize_mod, |
| 65 | .scalarize_mod_optimized, |
| 66 | .scalarize_max, |
| 67 | .scalarize_min, |
| 68 | .scalarize_add_with_overflow, |
| 69 | .scalarize_sub_with_overflow, |
| 70 | .scalarize_mul_with_overflow, |
| 71 | .scalarize_shl_with_overflow, |
| 72 | .scalarize_bit_and, |
| 73 | .scalarize_bit_or, |
| 74 | .scalarize_shr, |
| 75 | .scalarize_shr_exact, |
| 76 | .scalarize_shl, |
| 77 | .scalarize_shl_exact, |
| 78 | .scalarize_shl_sat, |
| 79 | .scalarize_xor, |
| 80 | .scalarize_not, |
| 81 | .scalarize_clz, |
| 82 | .scalarize_ctz, |
| 83 | .scalarize_popcount, |
| 84 | .scalarize_byte_swap, |
| 85 | .scalarize_bit_reverse, |
| 86 | .scalarize_sqrt, |
| 87 | .scalarize_sin, |
| 88 | .scalarize_cos, |
| 89 | .scalarize_tan, |
| 90 | .scalarize_exp, |
| 91 | .scalarize_exp2, |
| 92 | .scalarize_log, |
| 93 | .scalarize_log2, |
| 94 | .scalarize_log10, |
| 95 | .scalarize_abs, |
| 96 | .scalarize_floor, |
| 97 | .scalarize_ceil, |
| 98 | .scalarize_round, |
| 99 | .scalarize_trunc_float, |
| 100 | .scalarize_neg, |
| 101 | .scalarize_neg_optimized, |
| 102 | .scalarize_cmp_vector, |
| 103 | .scalarize_cmp_vector_optimized, |
| 104 | .scalarize_fptrunc, |
| 105 | .scalarize_fpext, |
| 106 | .scalarize_int_cast, |
| 107 | .scalarize_ptr_cast, |
| 108 | .scalarize_ptr_from_int, |
| 109 | .scalarize_int_from_ptr, |
| 110 | .scalarize_trunc, |
| 111 | .scalarize_int_from_float, |
| 112 | .scalarize_int_from_float_optimized, |
| 113 | .scalarize_float_from_int, |
| 114 | .scalarize_reduce, |
| 115 | .scalarize_reduce_optimized, |
| 116 | .scalarize_shuffle_one, |
| 117 | .scalarize_shuffle_two, |
| 118 | .scalarize_select, |
| 119 | .scalarize_mul_add, |
| 120 | |
| 121 | .scalarize_bit_cast_padded_elems, |
| 122 | }); |
| 123 | } |
| 44 | 124 | |
| 45 | | pub fn function( |
| 46 | | spork8: *Spork8, |
| 125 | pub fn generate( |
| 126 | bin_file: *link.File, |
| 47 | 127 | pt: Zcu.PerThread, |
| 48 | 128 | func_index: InternPool.Index, |
| 49 | | air: Air, |
| 50 | | liveness: Liveness, |
| 51 | | ) Error!Function { |
| 129 | air: *const Air, |
| 130 | liveness: *const ?Air.Liveness, |
| 131 | ) link.Error!Mir { |
| 132 | _ = bin_file; |
| 52 | 133 | const zcu = pt.zcu; |
| 53 | 134 | const gpa = zcu.gpa; |
| 54 | | const func_info = zcu.funcInfo(func_index); |
| 135 | const cg = zcu.funcInfo(func_index); |
| 55 | 136 | |
| 56 | 137 | var code_gen: CodeGen = .{ |
| 57 | 138 | .gpa = gpa, |
| 58 | 139 | .pt = pt, |
| 59 | | .air = air, |
| 60 | | .liveness = liveness, |
| 61 | | .owner_nav = func_info.owner_nav, |
| 62 | | .spork8 = spork8, |
| 140 | .air = air.*, |
| 141 | .liveness = liveness.*.?, |
| 142 | .owner_nav = cg.owner_nav, |
| 63 | 143 | .func_index = func_index, |
| 64 | | .mir_instructions = &spork8.mir_instructions, |
| 65 | | .mir_extra = &spork8.mir_extra, |
| 66 | | .start_mir_extra_off = @intCast(spork8.mir_extra.items.len), |
| 144 | .mir_instructions = .empty, |
| 145 | .mir_extra = .empty, |
| 67 | 146 | }; |
| 68 | 147 | defer code_gen.deinit(); |
| 69 | 148 | |
| 70 | | return functionInner(&code_gen) catch |err| switch (err) { |
| 71 | | error.CodegenFail => return error.CodegenFail, |
| 72 | | else => |e| return code_gen.fail("failed to generate function: {s}", .{@errorName(e)}), |
| 149 | return generateInner(&code_gen) catch |err| switch (err) { |
| 150 | error.AlreadyReported, |
| 151 | error.OutOfMemory, |
| 152 | => |e| return e, |
| 73 | 153 | }; |
| 74 | 154 | } |
| 75 | 155 | |
| 76 | | fn deinit(cg: *CodeGen) void { |
| 156 | pub fn deinit(cg: *CodeGen) void { |
| 77 | 157 | cg.* = undefined; |
| 78 | 158 | } |
| 79 | 159 | |
| 80 | 160 | const InnerError = error{ |
| 81 | | CodegenFail, |
| 161 | AlreadyReported, |
| 82 | 162 | OutOfMemory, |
| 83 | 163 | }; |
| 84 | 164 | |
| 85 | | fn functionInner(cg: *CodeGen) InnerError!Function { |
| 86 | | const spork8 = cg.spork8; |
| 87 | | |
| 88 | | const start_mir_off: u32 = @intCast(spork8.mir_instructions.len); |
| 89 | | |
| 165 | fn generateInner(cg: *CodeGen) InnerError!Mir { |
| 90 | 166 | // Generate MIR for function body |
| 91 | 167 | try cg.genBody(cg.air.getMainBody()); |
| 92 | 168 | |
| 169 | try cg.mir_extra.shrinkToLen(cg.gpa); |
| 170 | |
| 93 | 171 | return .{ |
| 94 | | .mir_off = start_mir_off, |
| 95 | | .mir_len = @intCast(spork8.mir_instructions.len - start_mir_off), |
| 96 | | .mir_extra_off = cg.start_mir_extra_off, |
| 97 | | .mir_extra_len = cg.extraLen(), |
| 172 | .instructions = cg.mir_instructions.toOwnedSlice(), |
| 173 | .extra = cg.mir_extra.toOwnedSliceAssert(), |
| 98 | 174 | }; |
| 99 | 175 | } |
| 100 | 176 | |
| ... | ... | @@ -130,8 +206,6 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 130 | 206 | .div_floor, |
| 131 | 207 | .bit_and, |
| 132 | 208 | .bit_or, |
| 133 | | .bool_and, |
| 134 | | .bool_or, |
| 135 | 209 | .rem, |
| 136 | 210 | .mod, |
| 137 | 211 | .shl, |
| ... | ... | @@ -177,13 +251,11 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 177 | 251 | .cmp_neq, |
| 178 | 252 | |
| 179 | 253 | .cmp_vector, |
| 180 | | .cmp_lt_errors_len, |
| 181 | 254 | |
| 182 | 255 | .array_elem_val, |
| 183 | 256 | .array_to_slice, |
| 184 | 257 | .alloc, |
| 185 | 258 | .arg, |
| 186 | | .bitcast, |
| 187 | 259 | .block, |
| 188 | 260 | .trap, |
| 189 | 261 | .breakpoint, |
| ... | ... | @@ -191,7 +263,6 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 191 | 263 | .repeat, |
| 192 | 264 | .switch_dispatch, |
| 193 | 265 | .cond_br, |
| 194 | | .intcast, |
| 195 | 266 | .fptrunc, |
| 196 | 267 | .fpext, |
| 197 | 268 | .int_from_float, |
| ... | ... | @@ -241,7 +312,6 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 241 | 312 | .ret_load, |
| 242 | 313 | .splat, |
| 243 | 314 | .select, |
| 244 | | .shuffle, |
| 245 | 315 | .reduce, |
| 246 | 316 | .aggregate_init, |
| 247 | 317 | .union_init, |
| ... | ... | @@ -266,7 +336,6 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 266 | 336 | .struct_field_ptr_index_1, |
| 267 | 337 | .struct_field_ptr_index_2, |
| 268 | 338 | .struct_field_ptr_index_3, |
| 269 | | .struct_field_val, |
| 270 | 339 | .field_parent_ptr, |
| 271 | 340 | |
| 272 | 341 | .switch_br, |
| ... | ... | @@ -303,7 +372,6 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 303 | 372 | .save_err_return_trace_index, |
| 304 | 373 | .is_named_enum_value, |
| 305 | 374 | .addrspace_cast, |
| 306 | | .vector_store_elem, |
| 307 | 375 | .c_va_arg, |
| 308 | 376 | .c_va_copy, |
| 309 | 377 | .c_va_end, |
| ... | ... | @@ -341,7 +409,31 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 341 | 409 | .add_safe, |
| 342 | 410 | .sub_safe, |
| 343 | 411 | .mul_safe, |
| 344 | | .intcast_safe, |
| 412 | .div_ceil, |
| 413 | .div_ceil_optimized, |
| 414 | .bit_cast, |
| 415 | .bit_cast_safe, |
| 416 | .ptr_cast, |
| 417 | .ptr_from_int, |
| 418 | .int_from_ptr, |
| 419 | .error_cast, |
| 420 | .error_from_int, |
| 421 | .int_from_error, |
| 422 | .union_from_enum, |
| 423 | .int_cast, |
| 424 | .int_cast_safe, |
| 425 | .agg_field_val, |
| 426 | .array_to_vector, |
| 427 | .int_from_float_safe, |
| 428 | .int_from_float_optimized_safe, |
| 429 | .shuffle_one, |
| 430 | .shuffle_two, |
| 431 | .cmp_lte_errors_len, |
| 432 | .runtime_nav_ptr, |
| 433 | .spirv_runtime_array_len, |
| 434 | .legalize_vec_store_elem, |
| 435 | .legalize_vec_elem_val, |
| 436 | .legalize_compiler_rt_call, |
| 345 | 437 | => |tag| return cg.fail("TODO: implement spork8 inst: {s}", .{@tagName(tag)}), |
| 346 | 438 | |
| 347 | 439 | .work_item_id, |
| ... | ... | @@ -356,7 +448,7 @@ fn airUnreachable(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 356 | 448 | _ = inst; |
| 357 | 449 | } |
| 358 | 450 | |
| 359 | | fn fail(cg: *CodeGen, comptime fmt: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } { |
| 451 | fn fail(cg: *CodeGen, comptime fmt: []const u8, args: anytype) error{ OutOfMemory, AlreadyReported } { |
| 360 | 452 | const zcu = cg.pt.zcu; |
| 361 | 453 | const func = zcu.funcInfo(cg.func_index); |
| 362 | 454 | return zcu.codegenFail(func.owner_nav, fmt, args); |