| 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 | 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 | 299 | const alloc_len = if (max_drop_len <= aligned_len - n) |
| 300 | 300 | aligned_len |
| 301 | 301 | else |
| ... | ... | @@ -529,7 +529,7 @@ const WasmPageAllocator = struct { |
| 529 | 529 | |
| 530 | 530 | fn freePages(start: usize, end: usize) void { |
| 531 | 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 | 534 | if (end > extendedOffset()) { |
| 535 | 535 | var new_end = end; |
src/codegen/llvm.zig+12-13| ... | ... | @@ -2331,17 +2331,19 @@ pub const FuncGen = struct { |
| 2331 | 2331 | const air_asm = self.air.extraData(Air.Asm, ty_pl.payload); |
| 2332 | 2332 | const zir = self.dg.decl.getFileScope().zir; |
| 2333 | 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 | 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]); | |
| 2341 | const args = @bitCast([]const Air.Inst.Ref, self.air.extra[air_asm.end + outputs.len ..][0..args_len]); | |
| 2335 | if (!is_volatile and self.liveness.isUnused(inst)) { | |
| 2336 | return null; | |
| 2337 | } | |
| 2338 | const outputs_len = @truncate(u5, extended.small); | |
| 2342 | 2339 | if (outputs_len > 1) { |
| 2343 | 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 | 2348 | var extra_i: usize = zir_extra.end; |
| 2347 | 2349 | const output_constraint: ?[]const u8 = out: { |
| ... | ... | @@ -2354,10 +2356,6 @@ pub const FuncGen = struct { |
| 2354 | 2356 | break :out null; |
| 2355 | 2357 | }; |
| 2356 | 2358 | |
| 2357 | if (!is_volatile and self.liveness.isUnused(inst)) { | |
| 2358 | return null; | |
| 2359 | } | |
| 2360 | ||
| 2361 | 2359 | var llvm_constraints: std.ArrayListUnmanaged(u8) = .{}; |
| 2362 | 2360 | defer llvm_constraints.deinit(self.gpa); |
| 2363 | 2361 | |
| ... | ... | @@ -2365,7 +2363,7 @@ pub const FuncGen = struct { |
| 2365 | 2363 | defer arena_allocator.deinit(); |
| 2366 | 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 | 2367 | const llvm_param_types = try arena.alloc(*const llvm.Type, llvm_params_len); |
| 2370 | 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 | 2375 | if (total_i != 0) { |
| 2378 | 2376 | llvm_constraints.appendAssumeCapacity(','); |
| 2379 | 2377 | } |
| 2380 | llvm_constraints.appendSliceAssumeCapacity(constraint); | |
| 2378 | llvm_constraints.appendAssumeCapacity('='); | |
| 2379 | llvm_constraints.appendSliceAssumeCapacity(constraint[1..]); | |
| 2381 | 2380 | |
| 2382 | 2381 | total_i += 1; |
| 2383 | 2382 | } |
src/print_air.zig+46-3| ... | ... | @@ -370,9 +370,52 @@ const Writer = struct { |
| 370 | 370 | } |
| 371 | 371 | |
| 372 | 372 | fn writeAssembly(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { |
| 373 | _ = w; | |
| 374 | _ = inst; | |
| 375 | try s.writeAll("TODO"); | |
| 373 | const ty_pl = w.air.instructions.items(.data)[inst].ty_pl; | |
| 374 | const air_asm = w.air.extraData(Air.Asm, ty_pl.payload); | |
| 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 | 421 | fn writeDbgStmt(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { |