| ... | ... | @@ -2166,9 +2166,8 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2166 | 2166 | break :shifted try func.binOp(extended_value, shift_val, int_elem_ty, .shl); |
| 2167 | 2167 | } else extended_value; |
| 2168 | 2168 | const result = try func.binOp(anded, shifted_value, int_elem_ty, .@"or"); |
| 2169 | | std.debug.print("Host: {} ty {} ty {}\n", .{ ptr_info.host_size, int_elem_ty.fmtDebug(), ty.fmtDebug() }); |
| 2170 | 2169 | // lhs is still on the stack |
| 2171 | | try func.store(.stack, result, int_elem_ty, 0); |
| 2170 | try func.store(.stack, result, int_elem_ty, lhs.offset()); |
| 2172 | 2171 | } |
| 2173 | 2172 | |
| 2174 | 2173 | func.finishAir(inst, .none, &.{ bin_op.lhs, bin_op.rhs }); |
| ... | ... | @@ -2284,8 +2283,10 @@ fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2284 | 2283 | const int_elem_ty = Type.initPayload(&int_ty_payload.base); |
| 2285 | 2284 | const shift_val = if (ptr_info.host_size <= 4) |
| 2286 | 2285 | WValue{ .imm32 = ptr_info.bit_offset } |
| 2286 | else if (ptr_info.host_size <= 8) |
| 2287 | WValue{ .imm64 = ptr_info.bit_offset } |
| 2287 | 2288 | else |
| 2288 | | WValue{ .imm64 = ptr_info.bit_offset }; |
| 2289 | return func.fail("TODO: airLoad where ptr to bitfield exceeds 64 bits", .{}); |
| 2289 | 2290 | |
| 2290 | 2291 | const stack_loaded = try func.load(operand, int_elem_ty, 0); |
| 2291 | 2292 | const shifted = try func.binOp(stack_loaded, shift_val, int_elem_ty, .shr); |
| ... | ... | @@ -3213,7 +3214,7 @@ fn airStructFieldPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3213 | 3214 | |
| 3214 | 3215 | const struct_ptr = try func.resolveInst(extra.data.struct_operand); |
| 3215 | 3216 | const struct_ty = func.air.typeOf(extra.data.struct_operand).childType(); |
| 3216 | | const result = try func.structFieldPtr(extra.data.struct_operand, struct_ptr, struct_ty, extra.data.field_index); |
| 3217 | const result = try func.structFieldPtr(inst, extra.data.struct_operand, struct_ptr, struct_ty, extra.data.field_index); |
| 3217 | 3218 | func.finishAir(inst, result, &.{extra.data.struct_operand}); |
| 3218 | 3219 | } |
| 3219 | 3220 | |
| ... | ... | @@ -3223,14 +3224,27 @@ fn airStructFieldPtrIndex(func: *CodeGen, inst: Air.Inst.Index, index: u32) Inne |
| 3223 | 3224 | const struct_ptr = try func.resolveInst(ty_op.operand); |
| 3224 | 3225 | const struct_ty = func.air.typeOf(ty_op.operand).childType(); |
| 3225 | 3226 | |
| 3226 | | const result = try func.structFieldPtr(ty_op.operand, struct_ptr, struct_ty, index); |
| 3227 | const result = try func.structFieldPtr(inst, ty_op.operand, struct_ptr, struct_ty, index); |
| 3227 | 3228 | func.finishAir(inst, result, &.{ty_op.operand}); |
| 3228 | 3229 | } |
| 3229 | 3230 | |
| 3230 | | fn structFieldPtr(func: *CodeGen, ref: Air.Inst.Ref, struct_ptr: WValue, struct_ty: Type, index: u32) InnerError!WValue { |
| 3231 | fn structFieldPtr( |
| 3232 | func: *CodeGen, |
| 3233 | inst: Air.Inst.Index, |
| 3234 | ref: Air.Inst.Ref, |
| 3235 | struct_ptr: WValue, |
| 3236 | struct_ty: Type, |
| 3237 | index: u32, |
| 3238 | ) InnerError!WValue { |
| 3239 | const result_ty = func.air.typeOfIndex(inst); |
| 3231 | 3240 | const offset = switch (struct_ty.containerLayout()) { |
| 3232 | 3241 | .Packed => switch (struct_ty.zigTypeTag()) { |
| 3233 | | .Struct => struct_ty.packedStructFieldByteOffset(index, func.target), |
| 3242 | .Struct => offset: { |
| 3243 | if (result_ty.ptrInfo().data.host_size != 0) { |
| 3244 | break :offset @as(u32, 0); |
| 3245 | } |
| 3246 | break :offset struct_ty.packedStructFieldByteOffset(index, func.target); |
| 3247 | }, |
| 3234 | 3248 | .Union => 0, |
| 3235 | 3249 | else => unreachable, |
| 3236 | 3250 | }, |
| ... | ... | @@ -3266,11 +3280,15 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3266 | 3280 | assert(struct_obj.layout == .Packed); |
| 3267 | 3281 | const offset = struct_obj.packedFieldBitOffset(func.target, field_index); |
| 3268 | 3282 | const backing_ty = struct_obj.backing_int_ty; |
| 3269 | | const wasm_bits = toWasmBits(backing_ty.intInfo(func.target).bits).?; |
| 3283 | const wasm_bits = toWasmBits(backing_ty.intInfo(func.target).bits) orelse { |
| 3284 | return func.fail("TODO: airStructFieldVal for packed structs larger than 128 bits", .{}); |
| 3285 | }; |
| 3270 | 3286 | const const_wvalue = if (wasm_bits == 32) |
| 3271 | 3287 | WValue{ .imm32 = offset } |
| 3288 | else if (wasm_bits == 64) |
| 3289 | WValue{ .imm64 = offset } |
| 3272 | 3290 | else |
| 3273 | | WValue{ .imm64 = offset }; |
| 3291 | return func.fail("TODO: airStructFieldVal for packed structs larger than 64 bits", .{}); |
| 3274 | 3292 | |
| 3275 | 3293 | // for first field we don't require any shifting |
| 3276 | 3294 | const shifted_value = if (offset == 0) |