| ... | ... | @@ -1329,6 +1329,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { |
| 1329 | 1329 | .fptrunc => self.airFptrunc(inst), |
| 1330 | 1330 | .fpext => self.airFpext(inst), |
| 1331 | 1331 | .float_to_int => self.airFloatToInt(inst), |
| 1332 | .int_to_float => self.airIntToFloat(inst), |
| 1332 | 1333 | .get_union_tag => self.airGetUnionTag(inst), |
| 1333 | 1334 | |
| 1334 | 1335 | // TODO |
| ... | ... | @@ -1382,6 +1383,8 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { |
| 1382 | 1383 | .slice_elem_val => self.airSliceElemVal(inst), |
| 1383 | 1384 | .slice_elem_ptr => self.airSliceElemPtr(inst), |
| 1384 | 1385 | .slice_ptr => self.airSlicePtr(inst), |
| 1386 | .ptr_slice_len_ptr => self.airPtrSliceFieldPtr(inst, self.ptrSize()), |
| 1387 | .ptr_slice_ptr_ptr => self.airPtrSliceFieldPtr(inst, 0), |
| 1385 | 1388 | .store => self.airStore(inst), |
| 1386 | 1389 | |
| 1387 | 1390 | .set_union_tag => self.airSetUnionTag(inst), |
| ... | ... | @@ -1398,8 +1401,10 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { |
| 1398 | 1401 | .unreach => self.airUnreachable(inst), |
| 1399 | 1402 | |
| 1400 | 1403 | .wrap_optional => self.airWrapOptional(inst), |
| 1401 | | .unwrap_errunion_payload => self.airUnwrapErrUnionPayload(inst), |
| 1402 | | .unwrap_errunion_err => self.airUnwrapErrUnionError(inst), |
| 1404 | .unwrap_errunion_payload => self.airUnwrapErrUnionPayload(inst, false), |
| 1405 | .unwrap_errunion_payload_ptr => self.airUnwrapErrUnionPayload(inst, true), |
| 1406 | .unwrap_errunion_err => self.airUnwrapErrUnionError(inst, false), |
| 1407 | .unwrap_errunion_err_ptr => self.airUnwrapErrUnionError(inst, true), |
| 1403 | 1408 | .wrap_errunion_payload => self.airWrapErrUnionPayload(inst), |
| 1404 | 1409 | .wrap_errunion_err => self.airWrapErrUnionErr(inst), |
| 1405 | 1410 | .errunion_payload_ptr_set => self.airErrUnionPayloadPtrSet(inst), |
| ... | ... | @@ -1429,8 +1434,6 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { |
| 1429 | 1434 | .bit_reverse, |
| 1430 | 1435 | .is_err_ptr, |
| 1431 | 1436 | .is_non_err_ptr, |
| 1432 | | .unwrap_errunion_payload_ptr, |
| 1433 | | .unwrap_errunion_err_ptr, |
| 1434 | 1437 | |
| 1435 | 1438 | .sqrt, |
| 1436 | 1439 | .sin, |
| ... | ... | @@ -1446,9 +1449,6 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { |
| 1446 | 1449 | .round, |
| 1447 | 1450 | .trunc_float, |
| 1448 | 1451 | |
| 1449 | | .ptr_slice_len_ptr, |
| 1450 | | .ptr_slice_ptr_ptr, |
| 1451 | | .int_to_float, |
| 1452 | 1452 | .cmpxchg_weak, |
| 1453 | 1453 | .cmpxchg_strong, |
| 1454 | 1454 | .fence, |
| ... | ... | @@ -2560,30 +2560,32 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerError!W |
| 2560 | 2560 | return is_err_tmp; |
| 2561 | 2561 | } |
| 2562 | 2562 | |
| 2563 | | fn airUnwrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) InnerError!WValue { |
| 2563 | fn airUnwrapErrUnionPayload(self: *Self, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!WValue { |
| 2564 | 2564 | if (self.liveness.isUnused(inst)) return WValue{ .none = {} }; |
| 2565 | 2565 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 2566 | 2566 | const operand = try self.resolveInst(ty_op.operand); |
| 2567 | | const err_ty = self.air.typeOf(ty_op.operand); |
| 2567 | const op_ty = self.air.typeOf(ty_op.operand); |
| 2568 | const err_ty = if (op_is_ptr) op_ty.childType() else op_ty; |
| 2568 | 2569 | const payload_ty = err_ty.errorUnionPayload(); |
| 2569 | 2570 | if (!payload_ty.hasRuntimeBits()) return WValue{ .none = {} }; |
| 2570 | 2571 | const err_align = err_ty.abiAlignment(self.target); |
| 2571 | 2572 | const set_size = err_ty.errorUnionSet().abiSize(self.target); |
| 2572 | 2573 | const offset = mem.alignForwardGeneric(u64, set_size, err_align); |
| 2573 | | if (isByRef(payload_ty, self.target)) { |
| 2574 | if (op_is_ptr or isByRef(payload_ty, self.target)) { |
| 2574 | 2575 | return self.buildPointerOffset(operand, offset, .new); |
| 2575 | 2576 | } |
| 2576 | 2577 | return self.load(operand, payload_ty, @intCast(u32, offset)); |
| 2577 | 2578 | } |
| 2578 | 2579 | |
| 2579 | | fn airUnwrapErrUnionError(self: *Self, inst: Air.Inst.Index) InnerError!WValue { |
| 2580 | fn airUnwrapErrUnionError(self: *Self, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!WValue { |
| 2580 | 2581 | if (self.liveness.isUnused(inst)) return WValue{ .none = {} }; |
| 2581 | 2582 | |
| 2582 | 2583 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 2583 | 2584 | const operand = try self.resolveInst(ty_op.operand); |
| 2584 | | const err_ty = self.air.typeOf(ty_op.operand); |
| 2585 | const op_ty = self.air.typeOf(ty_op.operand); |
| 2586 | const err_ty = if (op_is_ptr) op_ty.childType() else op_ty; |
| 2585 | 2587 | const payload_ty = err_ty.errorUnionPayload(); |
| 2586 | | if (!payload_ty.hasRuntimeBits()) { |
| 2588 | if (op_is_ptr or !payload_ty.hasRuntimeBits()) { |
| 2587 | 2589 | return operand; |
| 2588 | 2590 | } |
| 2589 | 2591 | |
| ... | ... | @@ -3231,6 +3233,28 @@ fn airFloatToInt(self: *Self, inst: Air.Inst.Index) InnerError!WValue { |
| 3231 | 3233 | return result; |
| 3232 | 3234 | } |
| 3233 | 3235 | |
| 3236 | fn airIntToFloat(self: *Self, inst: Air.Inst.Index) InnerError!WValue { |
| 3237 | if (self.liveness.isUnused(inst)) return WValue{ .none = {} }; |
| 3238 | |
| 3239 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 3240 | const operand = try self.resolveInst(ty_op.operand); |
| 3241 | const dest_ty = self.air.typeOfIndex(inst); |
| 3242 | const op_ty = self.air.typeOf(ty_op.operand); |
| 3243 | |
| 3244 | try self.emitWValue(operand); |
| 3245 | const op = buildOpcode(.{ |
| 3246 | .op = .convert, |
| 3247 | .valtype1 = typeToValtype(dest_ty, self.target), |
| 3248 | .valtype2 = typeToValtype(op_ty, self.target), |
| 3249 | .signedness = if (op_ty.isSignedInt()) .signed else .unsigned, |
| 3250 | }); |
| 3251 | try self.addTag(Mir.Inst.Tag.fromOpcode(op)); |
| 3252 | |
| 3253 | const result = try self.allocLocal(dest_ty); |
| 3254 | try self.addLabel(.local_set, result.local); |
| 3255 | return result; |
| 3256 | } |
| 3257 | |
| 3234 | 3258 | fn airSplat(self: *Self, inst: Air.Inst.Index) InnerError!WValue { |
| 3235 | 3259 | if (self.liveness.isUnused(inst)) return WValue{ .none = {} }; |
| 3236 | 3260 | |
| ... | ... | @@ -3682,3 +3706,11 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) InnerError!WValue { |
| 3682 | 3706 | try self.addLabel(.local_set, result_ptr.local); |
| 3683 | 3707 | return result_ptr; |
| 3684 | 3708 | } |
| 3709 | |
| 3710 | fn airPtrSliceFieldPtr(self: *Self, inst: Air.Inst.Index, offset: u32) InnerError!WValue { |
| 3711 | if (self.liveness.isUnused(inst)) return WValue{ .none = {} }; |
| 3712 | |
| 3713 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 3714 | const slice_ptr = try self.resolveInst(ty_op.operand); |
| 3715 | return self.buildPointerOffset(slice_ptr, offset, .new); |
| 3716 | } |