| author | |
| committer | |
| log | 361217bda2b4ce397a2b49ab7613162d1abcab67 |
| tree | bcaaada7ab445f6eaa7724557adb6f3b365a72c4 |
| parent | d949180ab04f550d672e20a8f9bdd6619cc3c05c |
Thanks @g-w1 for the print_air.zig implementation for inline assembly. I
copied it and slightly modified it from your open pull request.3 files changed, 60 insertions(+), 18 deletions(-)
lib/std/heap.zig+2-2| ... | @@ -295,7 +295,7 @@ const PageAllocator = struct { | ... | @@ -295,7 +295,7 @@ const PageAllocator = struct { |
| 295 | } | 295 | } |
| 296 | } | 296 | } |
| 297 | 297 | ||
| 298 | const max_drop_len = alignment - std.math.min(alignment, mem.page_size); | 298 | const max_drop_len = alignment - @minimum(alignment, mem.page_size); |
| 299 | const alloc_len = if (max_drop_len <= aligned_len - n) | 299 | const alloc_len = if (max_drop_len <= aligned_len - n) |
| 300 | aligned_len | 300 | aligned_len |
| 301 | else | 301 | else |
| ... | @@ -529,7 +529,7 @@ const WasmPageAllocator = struct { | ... | @@ -529,7 +529,7 @@ const WasmPageAllocator = struct { |
| 529 | 529 | ||
| 530 | fn freePages(start: usize, end: usize) void { | 530 | fn freePages(start: usize, end: usize) void { |
| 531 | if (start < extendedOffset()) { | 531 | if (start < extendedOffset()) { |
| 532 | conventional.recycle(start, std.math.min(extendedOffset(), end) - start); | 532 | conventional.recycle(start, @minimum(extendedOffset(), end) - start); |
| 533 | } | 533 | } |
| 534 | if (end > extendedOffset()) { | 534 | if (end > extendedOffset()) { |
| 535 | var new_end = end; | 535 | var new_end = end; |
src/codegen/llvm.zig+12-13| ... | @@ -2331,17 +2331,19 @@ pub const FuncGen = struct { | ... | @@ -2331,17 +2331,19 @@ pub const FuncGen = struct { |
| 2331 | const air_asm = self.air.extraData(Air.Asm, ty_pl.payload); | 2331 | const air_asm = self.air.extraData(Air.Asm, ty_pl.payload); |
| 2332 | const zir = self.dg.decl.getFileScope().zir; | 2332 | const zir = self.dg.decl.getFileScope().zir; |
| 2333 | const extended = zir.instructions.items(.data)[air_asm.data.zir_index].extended; | 2333 | const extended = zir.instructions.items(.data)[air_asm.data.zir_index].extended; |
| 2334 | const zir_extra = zir.extraData(Zir.Inst.Asm, extended.operand); | ||
| 2335 | const asm_source = zir.nullTerminatedString(zir_extra.data.asm_source); | ||
| 2336 | const outputs_len = @truncate(u5, extended.small); | ||
| 2337 | const args_len = @truncate(u5, extended.small >> 5); | ||
| 2338 | const clobbers_len = @truncate(u5, extended.small >> 10); | ||
| 2339 | const is_volatile = @truncate(u1, extended.small >> 15) != 0; | 2334 | const is_volatile = @truncate(u1, extended.small >> 15) != 0; |
| 2340 | const outputs = @bitCast([]const Air.Inst.Ref, self.air.extra[air_asm.end..][0..outputs_len]); | 2335 | if (!is_volatile and self.liveness.isUnused(inst)) { |
| 2341 | const args = @bitCast([]const Air.Inst.Ref, self.air.extra[air_asm.end + outputs.len ..][0..args_len]); | 2336 | return null; |
| 2337 | } | ||
| 2338 | const outputs_len = @truncate(u5, extended.small); | ||
| 2342 | if (outputs_len > 1) { | 2339 | if (outputs_len > 1) { |
| 2343 | return self.todo("implement llvm codegen for asm with more than 1 output", .{}); | 2340 | return self.todo("implement llvm codegen for asm with more than 1 output", .{}); |
| 2344 | } | 2341 | } |
| 2342 | const args_len = @truncate(u5, extended.small >> 5); | ||
| 2343 | const clobbers_len = @truncate(u5, extended.small >> 10); | ||
| 2344 | const zir_extra = zir.extraData(Zir.Inst.Asm, extended.operand); | ||
| 2345 | const asm_source = zir.nullTerminatedString(zir_extra.data.asm_source); | ||
| 2346 | const args = @bitCast([]const Air.Inst.Ref, self.air.extra[air_asm.end..][0..args_len]); | ||
| 2345 | 2347 | ||
| 2346 | var extra_i: usize = zir_extra.end; | 2348 | var extra_i: usize = zir_extra.end; |
| 2347 | const output_constraint: ?[]const u8 = out: { | 2349 | const output_constraint: ?[]const u8 = out: { |
| ... | @@ -2354,10 +2356,6 @@ pub const FuncGen = struct { | ... | @@ -2354,10 +2356,6 @@ pub const FuncGen = struct { |
| 2354 | break :out null; | 2356 | break :out null; |
| 2355 | }; | 2357 | }; |
| 2356 | 2358 | ||
| 2357 | if (!is_volatile and self.liveness.isUnused(inst)) { | ||
| 2358 | return null; | ||
| 2359 | } | ||
| 2360 | |||
| 2361 | var llvm_constraints: std.ArrayListUnmanaged(u8) = .{}; | 2359 | var llvm_constraints: std.ArrayListUnmanaged(u8) = .{}; |
| 2362 | defer llvm_constraints.deinit(self.gpa); | 2360 | defer llvm_constraints.deinit(self.gpa); |
| 2363 | 2361 | ||
| ... | @@ -2365,7 +2363,7 @@ pub const FuncGen = struct { | ... | @@ -2365,7 +2363,7 @@ pub const FuncGen = struct { |
| 2365 | defer arena_allocator.deinit(); | 2363 | defer arena_allocator.deinit(); |
| 2366 | const arena = &arena_allocator.allocator; | 2364 | const arena = &arena_allocator.allocator; |
| 2367 | 2365 | ||
| 2368 | const llvm_params_len = args.len + @boolToInt(output_constraint != null); | 2366 | const llvm_params_len = args.len; |
| 2369 | const llvm_param_types = try arena.alloc(*const llvm.Type, llvm_params_len); | 2367 | const llvm_param_types = try arena.alloc(*const llvm.Type, llvm_params_len); |
| 2370 | const llvm_param_values = try arena.alloc(*const llvm.Value, llvm_params_len); | 2368 | const llvm_param_values = try arena.alloc(*const llvm.Value, llvm_params_len); |
| 2371 | 2369 | ||
| ... | @@ -2377,7 +2375,8 @@ pub const FuncGen = struct { | ... | @@ -2377,7 +2375,8 @@ pub const FuncGen = struct { |
| 2377 | if (total_i != 0) { | 2375 | if (total_i != 0) { |
| 2378 | llvm_constraints.appendAssumeCapacity(','); | 2376 | llvm_constraints.appendAssumeCapacity(','); |
| 2379 | } | 2377 | } |
| 2380 | llvm_constraints.appendSliceAssumeCapacity(constraint); | 2378 | llvm_constraints.appendAssumeCapacity('='); |
| 2379 | llvm_constraints.appendSliceAssumeCapacity(constraint[1..]); | ||
| 2381 | 2380 | ||
| 2382 | total_i += 1; | 2381 | total_i += 1; |
| 2383 | } | 2382 | } |
src/print_air.zig+46-3| ... | @@ -370,9 +370,52 @@ const Writer = struct { | ... | @@ -370,9 +370,52 @@ const Writer = struct { |
| 370 | } | 370 | } |
| 371 | 371 | ||
| 372 | fn writeAssembly(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { | 372 | fn writeAssembly(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { |
| 373 | _ = w; | 373 | const ty_pl = w.air.instructions.items(.data)[inst].ty_pl; |
| 374 | _ = inst; | 374 | const air_asm = w.air.extraData(Air.Asm, ty_pl.payload); |
| 375 | try s.writeAll("TODO"); | 375 | const zir = w.zir; |
| 376 | const extended = zir.instructions.items(.data)[air_asm.data.zir_index].extended; | ||
| 377 | const zir_extra = zir.extraData(Zir.Inst.Asm, extended.operand); | ||
| 378 | const asm_source = zir.nullTerminatedString(zir_extra.data.asm_source); | ||
| 379 | const outputs_len = @truncate(u5, extended.small); | ||
| 380 | const args_len = @truncate(u5, extended.small >> 5); | ||
| 381 | const clobbers_len = @truncate(u5, extended.small >> 10); | ||
| 382 | const args = @bitCast([]const Air.Inst.Ref, w.air.extra[air_asm.end..][0..args_len]); | ||
| 383 | |||
| 384 | var extra_i: usize = zir_extra.end; | ||
| 385 | const output_constraint: ?[]const u8 = out: { | ||
| 386 | var i: usize = 0; | ||
| 387 | while (i < outputs_len) : (i += 1) { | ||
| 388 | const output = zir.extraData(Zir.Inst.Asm.Output, extra_i); | ||
| 389 | extra_i = output.end; | ||
| 390 | break :out zir.nullTerminatedString(output.data.constraint); | ||
| 391 | } | ||
| 392 | break :out null; | ||
| 393 | }; | ||
| 394 | |||
| 395 | try s.print("\"{s}\"", .{asm_source}); | ||
| 396 | |||
| 397 | if (output_constraint) |constraint| { | ||
| 398 | const ret_ty = w.air.typeOfIndex(inst); | ||
| 399 | try s.print(", {s} -> {}", .{ constraint, ret_ty }); | ||
| 400 | } | ||
| 401 | |||
| 402 | for (args) |arg| { | ||
| 403 | const input = zir.extraData(Zir.Inst.Asm.Input, extra_i); | ||
| 404 | extra_i = input.end; | ||
| 405 | const constraint = zir.nullTerminatedString(input.data.constraint); | ||
| 406 | |||
| 407 | try s.print(", {s} = (", .{constraint}); | ||
| 408 | try w.writeOperand(s, inst, 0, arg); | ||
| 409 | try s.writeByte(')'); | ||
| 410 | } | ||
| 411 | |||
| 412 | const clobbers = zir.extra[extra_i..][0..clobbers_len]; | ||
| 413 | for (clobbers) |clobber_index| { | ||
| 414 | const clobber = zir.nullTerminatedString(clobber_index); | ||
| 415 | try s.writeAll(", ~{"); | ||
| 416 | try s.writeAll(clobber); | ||
| 417 | try s.writeAll("}"); | ||
| 418 | } | ||
| 376 | } | 419 | } |
| 377 | 420 | ||
| 378 | fn writeDbgStmt(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { | 421 | fn writeDbgStmt(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { |