authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2022-10-11 04:51:52-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2022-10-25 05:11:29-04:00
log1dd4a6102ff983c828cdaa3dbadef37272ffce7c
tree4b6ab99bf066ca96f72b7b6fc62f9952db6518b2
parente8bda9eb3ae9634a7b434e59df883ada3fdf8d9d

cbe: implement global assembly


6 files changed, 35 insertions(+), 16 deletions(-)

src/codegen/c.zig+23-8
......@@ -1845,6 +1845,13 @@ pub const DeclGen = struct {
18451845 }
18461846};
18471847
1848pub fn genGlobalAsm(mod: *Module, code: *std.ArrayList(u8)) !void {
1849 var it = mod.global_assembly.valueIterator();
1850 while (it.next()) |asm_source| {
1851 try code.writer().print("__asm({s});\n", .{fmtStringLiteral(asm_source.*)});
1852 }
1853}
1854
18481855pub fn genErrDecls(o: *Object) !void {
18491856 if (o.dg.module.global_error_set.size == 0) return;
18501857 const writer = o.writer();
......@@ -3450,8 +3457,10 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
34503457 try writer.writeAll("{\n");
34513458 f.object.indent_writer.pushIndent();
34523459
3460 const output_locals_begin = f.next_local_index;
3461 f.next_local_index += outputs.len;
34533462 const constraints_extra_begin = extra_i;
3454 for (outputs) |output| {
3463 for (outputs) |output, index| {
34553464 const extra_bytes = std.mem.sliceAsBytes(f.air.extra[extra_i..]);
34563465 const constraint = std.mem.sliceTo(extra_bytes, 0);
34573466 const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0);
......@@ -3461,7 +3470,9 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
34613470
34623471 const output_ty = if (output == .none) inst_ty else f.air.typeOf(output).childType();
34633472 try writer.writeAll("register ");
3464 try f.object.dg.renderTypeAndName(writer, output_ty, .{ .identifier = name }, .Mut, 0);
3473 try f.object.dg.renderTypeAndName(writer, output_ty, .{
3474 .local = output_locals_begin + index,
3475 }, .Mut, 0);
34653476 if (std.mem.startsWith(u8, constraint, "={") and std.mem.endsWith(u8, constraint, "}")) {
34663477 try writer.writeAll(" __asm(\"");
34673478 try writer.writeAll(constraint["={".len .. constraint.len - "}".len]);
......@@ -3475,7 +3486,9 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
34753486 }
34763487 try writer.writeAll(";\n");
34773488 }
3478 for (inputs) |input| {
3489 const input_locals_begin = f.next_local_index;
3490 f.next_local_index += inputs.len;
3491 for (inputs) |input, index| {
34793492 const extra_bytes = std.mem.sliceAsBytes(f.air.extra[extra_i..]);
34803493 const constraint = std.mem.sliceTo(extra_bytes, 0);
34813494 const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0);
......@@ -3485,7 +3498,9 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
34853498
34863499 const input_ty = f.air.typeOf(input);
34873500 try writer.writeAll("register ");
3488 try f.object.dg.renderTypeAndName(writer, input_ty, .{ .identifier = name }, .Const, 0);
3501 try f.object.dg.renderTypeAndName(writer, input_ty, .{
3502 .local = input_locals_begin + index,
3503 }, .Const, 0);
34893504 if (std.mem.startsWith(u8, constraint, "{") and std.mem.endsWith(u8, constraint, "}")) {
34903505 try writer.writeAll(" __asm(\"");
34913506 try writer.writeAll(constraint["{".len .. constraint.len - "}".len]);
......@@ -3524,7 +3539,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
35243539
35253540 if (index > 0) try writer.writeByte(',');
35263541 try writer.print(" {s}(", .{fmtStringLiteral(if (constraint[1] == '{') "=r" else constraint)});
3527 try f.writeCValue(writer, .{ .identifier = name });
3542 try f.writeCValue(writer, .{ .local = output_locals_begin + index });
35283543 try writer.writeByte(')');
35293544 }
35303545 try writer.writeByte(':');
......@@ -3538,7 +3553,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
35383553
35393554 if (index > 0) try writer.writeByte(',');
35403555 try writer.print(" {s}(", .{fmtStringLiteral(if (constraint[0] == '{') "r" else constraint)});
3541 try f.writeCValue(writer, .{ .identifier = name });
3556 try f.writeCValue(writer, .{ .local = input_locals_begin + index });
35423557 try writer.writeByte(')');
35433558 }
35443559 try writer.writeByte(':');
......@@ -3559,7 +3574,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
35593574 try writer.writeAll(");\n");
35603575
35613576 extra_i = constraints_extra_begin;
3562 for (outputs) |output| {
3577 for (outputs) |output, index| {
35633578 const extra_bytes = std.mem.sliceAsBytes(f.air.extra[extra_i..]);
35643579 const constraint = std.mem.sliceTo(extra_bytes, 0);
35653580 const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0);
......@@ -3571,7 +3586,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
35713586 .local_ref = local.local,
35723587 } else try f.resolveInst(output));
35733588 try writer.writeAll(" = ");
3574 try f.writeCValue(writer, .{ .identifier = name });
3589 try f.writeCValue(writer, .{ .local = output_locals_begin + index });
35753590 try writer.writeAll(";\n");
35763591 }
35773592
src/link/C.zig+12-1
......@@ -256,7 +256,7 @@ pub fn flushModule(self: *C, comp: *Compilation, prog_node: *std.Progress.Node)
256256 var f: Flush = .{};
257257 defer f.deinit(gpa);
258258
259 // Covers zig.h and typedef.
259 // Covers zig.h, typedef, and asm.
260260 try f.all_buffers.ensureUnusedCapacity(gpa, 2);
261261
262262 f.appendBufAssumeCapacity(zig_h);
......@@ -264,6 +264,16 @@ pub fn flushModule(self: *C, comp: *Compilation, prog_node: *std.Progress.Node)
264264 const typedef_index = f.all_buffers.items.len;
265265 f.all_buffers.items.len += 1;
266266
267 {
268 var asm_buf = f.asm_buf.toManaged(module.gpa);
269 defer asm_buf.deinit();
270
271 try codegen.genGlobalAsm(module, &asm_buf);
272
273 f.asm_buf = asm_buf.moveToUnmanaged();
274 f.appendBufAssumeCapacity(f.asm_buf.items);
275 }
276
267277 try self.flushErrDecls(&f);
268278
269279 // Typedefs, forward decls, and non-functions first.
......@@ -307,6 +317,7 @@ const Flush = struct {
307317 remaining_decls: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, void) = .{},
308318 typedefs: Typedefs = .{},
309319 typedef_buf: std.ArrayListUnmanaged(u8) = .{},
320 asm_buf: std.ArrayListUnmanaged(u8) = .{},
310321 /// We collect a list of buffers to write, and write them all at once with pwritev 😎
311322 all_buffers: std.ArrayListUnmanaged(std.os.iovec_const) = .{},
312323 /// Keeps track of the total bytes of `all_buffers`.
test/behavior/array.zig-1
......@@ -527,7 +527,6 @@ test "type coercion of anon struct literal to array" {
527527}
528528
529529test "type coercion of pointer to anon struct literal to pointer to array" {
530 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
531530 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
532531 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
533532 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
test/behavior/asm.zig-2
......@@ -18,7 +18,6 @@ comptime {
1818}
1919
2020test "module level assembly" {
21 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
2221 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
2322 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
2423 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
......@@ -50,7 +49,6 @@ test "output constraint modifiers" {
5049}
5150
5251test "alternative constraints" {
53 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
5452 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
5553 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
5654 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
test/behavior/eval.zig-3
......@@ -746,7 +746,6 @@ fn scalar(x: u32) u32 {
746746
747747test "array concatenation peer resolves element types - value" {
748748 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
749 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
750749 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
751750 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
752751
......@@ -781,7 +780,6 @@ test "array concatenation sets the sentinel - value" {
781780 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
782781 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
783782 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
784 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
785783 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
786784 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
787785
......@@ -819,7 +817,6 @@ test "array multiplication sets the sentinel - value" {
819817 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
820818 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
821819 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
822 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
823820 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
824821 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
825822
test/behavior/slice.zig-1
......@@ -533,7 +533,6 @@ test "slice pointer-to-array zero length" {
533533}
534534
535535test "type coercion of pointer to anon struct literal to pointer to slice" {
536 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
537536 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
538537 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
539538 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO