aboutsummaryrefslogtreecommitdiff
path: root/src/Air.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-08-07 15:41:52 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-08-07 15:46:53 -0700
commitf81b2531cb4904064446f84a06f6e09e4120e28a (patch)
treee4bac7a1a13c56b728309086d983091e9e009a65 /src/Air.zig
parentade85471e2cdab466ba685a38c2c7949c9dd1632 (diff)
downloadzig-f81b2531cb4904064446f84a06f6e09e4120e28a.tar.gz
zig-f81b2531cb4904064446f84a06f6e09e4120e28a.zip
stage2: pass some pointer tests
* New AIR instructions: ptr_add, ptr_sub, ptr_elem_val, ptr_ptr_elem_val - See the doc comments for details. * Sema: implement runtime pointer arithmetic. * Sema: implement elem_val for many-pointers. * Sema: support coercion from `*[N:s]T` to `[*]T`. * Type: isIndexable handles many-pointers.
Diffstat (limited to 'src/Air.zig')
-rw-r--r--src/Air.zig33
1 files changed, 28 insertions, 5 deletions
diff --git a/src/Air.zig b/src/Air.zig
index d923bf0b02..391683afd5 100644
--- a/src/Air.zig
+++ b/src/Air.zig
@@ -69,6 +69,18 @@ pub const Inst = struct {
/// is the same as both operands.
/// Uses the `bin_op` field.
div,
+ /// Add an offset to a pointer, returning a new pointer.
+ /// The offset is in element type units, not bytes.
+ /// Wrapping is undefined behavior.
+ /// The lhs is the pointer, rhs is the offset. Result type is the same as lhs.
+ /// Uses the `bin_op` field.
+ ptr_add,
+ /// Subtract an offset from a pointer, returning a new pointer.
+ /// The offset is in element type units, not bytes.
+ /// Wrapping is undefined behavior.
+ /// The lhs is the pointer, rhs is the offset. Result type is the same as lhs.
+ /// Uses the `bin_op` field.
+ ptr_sub,
/// Allocates stack local memory.
/// Uses the `ty` field.
alloc,
@@ -264,6 +276,15 @@ pub const Inst = struct {
/// Result type is the element type of the slice operand (2 element type operations).
/// Uses the `bin_op` field.
ptr_slice_elem_val,
+ /// Given a pointer value, and element index, return the element value at that index.
+ /// Result type is the element type of the pointer operand.
+ /// Uses the `bin_op` field.
+ ptr_elem_val,
+ /// Given a pointer to a pointer, and element index, return the element value of the inner
+ /// pointer at that index.
+ /// Result type is the element type of the inner pointer operand.
+ /// Uses the `bin_op` field.
+ ptr_ptr_elem_val,
pub fn fromCmpOp(op: std.math.CompareOperator) Tag {
return switch (op) {
@@ -422,6 +443,8 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
.bit_and,
.bit_or,
.xor,
+ .ptr_add,
+ .ptr_sub,
=> return air.typeOf(datas[inst].bin_op.lhs),
.cmp_lt,
@@ -495,14 +518,14 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
return callee_ty.fnReturnType();
},
- .slice_elem_val => {
+ .slice_elem_val, .ptr_elem_val => {
const slice_ty = air.typeOf(datas[inst].bin_op.lhs);
return slice_ty.elemType();
},
- .ptr_slice_elem_val => {
- const ptr_slice_ty = air.typeOf(datas[inst].bin_op.lhs);
- const slice_ty = ptr_slice_ty.elemType();
- return slice_ty.elemType();
+ .ptr_slice_elem_val, .ptr_ptr_elem_val => {
+ const outer_ptr_ty = air.typeOf(datas[inst].bin_op.lhs);
+ const inner_ptr_ty = outer_ptr_ty.elemType();
+ return inner_ptr_ty.elemType();
},
}
}