diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-07-23 22:23:03 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-07-23 22:42:31 -0700 |
| commit | 7b8cb881df7e034a8626caabf355055ee81a0fef (patch) | |
| tree | e56858cd22ccf90217a49c51c7d8ff7df49ab0f3 /src/codegen.zig | |
| parent | f9798108f8434f277de6089502446f2544ee98b3 (diff) | |
| download | zig-7b8cb881df7e034a8626caabf355055ee81a0fef.tar.gz zig-7b8cb881df7e034a8626caabf355055ee81a0fef.zip | |
stage2: improvements towards `zig test`
* There is now a main_pkg in addition to root_pkg. They are usually the
same. When using `zig test`, main_pkg is the user's source file and
root_pkg has the test runner.
* scanDecl no longer looks for test decls outside the package being
tested. honoring `--test-filter` is still TODO.
* test runner main function has a void return value rather than
`anyerror!void`
* Sema is improved to generate better AIR for for loops on slices.
* Sema: fix incorrect capacity calculation in zirBoolBr
* Sema: add compile errors for trying to use slice fields as an lvalue.
* Sema: fix type coercion for error unions
* Sema: fix analyzeVarRef generating garbage AIR
* C codegen: fix renderValue for error unions with 0 bit payload
* C codegen: implement function pointer calls
* CLI: fix usage text
Adds 4 new AIR instructions:
* slice_len, slice_ptr: to get the ptr and len fields of a slice.
* slice_elem_val, ptr_slice_elem_val: to get the element value of
a slice, and a pointer to a slice.
AstGen gains a new functionality:
* One of the unused flags of struct decls is now used to indicate
structs that are known to have non-zero size based on the AST alone.
Diffstat (limited to 'src/codegen.zig')
| -rw-r--r-- | src/codegen.zig | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/src/codegen.zig b/src/codegen.zig index 0a3169bb9b..c2504f26a8 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -853,6 +853,11 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { .struct_field_ptr=> try self.airStructFieldPtr(inst), .switch_br => try self.airSwitch(inst), .varptr => try self.airVarPtr(inst), + .slice_ptr => try self.airSlicePtr(inst), + .slice_len => try self.airSliceLen(inst), + + .slice_elem_val => try self.airSliceElemVal(inst), + .ptr_slice_elem_val => try self.airPtrSliceElemVal(inst), .constant => unreachable, // excluded from function bodies .const_ty => unreachable, // excluded from function bodies @@ -1333,6 +1338,38 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { return self.finishAir(inst, result, .{ .none, .none, .none }); } + fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void { + const ty_op = self.air.instructions.items(.data)[inst].ty_op; + const result: MCValue = if (self.liveness.isUnused(inst)) .dead else switch (arch) { + else => return self.fail("TODO implement slice_ptr for {}", .{self.target.cpu.arch}), + }; + return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); + } + + fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void { + const ty_op = self.air.instructions.items(.data)[inst].ty_op; + const result: MCValue = if (self.liveness.isUnused(inst)) .dead else switch (arch) { + else => return self.fail("TODO implement slice_len for {}", .{self.target.cpu.arch}), + }; + return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); + } + + fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { + const bin_op = self.air.instructions.items(.data)[inst].bin_op; + const result: MCValue = if (self.liveness.isUnused(inst)) .dead else switch (arch) { + else => return self.fail("TODO implement slice_elem_val for {}", .{self.target.cpu.arch}), + }; + return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); + } + + fn airPtrSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { + const bin_op = self.air.instructions.items(.data)[inst].bin_op; + const result: MCValue = if (self.liveness.isUnused(inst)) .dead else switch (arch) { + else => return self.fail("TODO implement ptr_slice_elem_val for {}", .{self.target.cpu.arch}), + }; + return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); + } + fn reuseOperand(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, op_index: Liveness.OperandInt, mcv: MCValue) bool { if (!self.liveness.operandDies(inst, op_index)) return false; |
