| ... | @@ -1329,6 +1329,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { | ... | @@ -1329,6 +1329,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { |
| 1329 | .fptrunc => self.airFptrunc(inst), | 1329 | .fptrunc => self.airFptrunc(inst), |
| 1330 | .fpext => self.airFpext(inst), | 1330 | .fpext => self.airFpext(inst), |
| 1331 | .float_to_int => self.airFloatToInt(inst), | 1331 | .float_to_int => self.airFloatToInt(inst), |
| | 1332 | .int_to_float => self.airIntToFloat(inst), |
| 1332 | .get_union_tag => self.airGetUnionTag(inst), | 1333 | .get_union_tag => self.airGetUnionTag(inst), |
| 1333 | | 1334 | |
| 1334 | // TODO | 1335 | // TODO |
| ... | @@ -1382,6 +1383,8 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { | ... | @@ -1382,6 +1383,8 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { |
| 1382 | .slice_elem_val => self.airSliceElemVal(inst), | 1383 | .slice_elem_val => self.airSliceElemVal(inst), |
| 1383 | .slice_elem_ptr => self.airSliceElemPtr(inst), | 1384 | .slice_elem_ptr => self.airSliceElemPtr(inst), |
| 1384 | .slice_ptr => self.airSlicePtr(inst), | 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 | .store => self.airStore(inst), | 1388 | .store => self.airStore(inst), |
| 1386 | | 1389 | |
| 1387 | .set_union_tag => self.airSetUnionTag(inst), | 1390 | .set_union_tag => self.airSetUnionTag(inst), |
| ... | @@ -1398,8 +1401,10 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { | ... | @@ -1398,8 +1401,10 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { |
| 1398 | .unreach => self.airUnreachable(inst), | 1401 | .unreach => self.airUnreachable(inst), |
| 1399 | | 1402 | |
| 1400 | .wrap_optional => self.airWrapOptional(inst), | 1403 | .wrap_optional => self.airWrapOptional(inst), |
| 1401 | .unwrap_errunion_payload => self.airUnwrapErrUnionPayload(inst), | 1404 | .unwrap_errunion_payload => self.airUnwrapErrUnionPayload(inst, false), |
| 1402 | .unwrap_errunion_err => self.airUnwrapErrUnionError(inst), | 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 | .wrap_errunion_payload => self.airWrapErrUnionPayload(inst), | 1408 | .wrap_errunion_payload => self.airWrapErrUnionPayload(inst), |
| 1404 | .wrap_errunion_err => self.airWrapErrUnionErr(inst), | 1409 | .wrap_errunion_err => self.airWrapErrUnionErr(inst), |
| 1405 | .errunion_payload_ptr_set => self.airErrUnionPayloadPtrSet(inst), | 1410 | .errunion_payload_ptr_set => self.airErrUnionPayloadPtrSet(inst), |
| ... | @@ -1429,8 +1434,6 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { | ... | @@ -1429,8 +1434,6 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { |
| 1429 | .bit_reverse, | 1434 | .bit_reverse, |
| 1430 | .is_err_ptr, | 1435 | .is_err_ptr, |
| 1431 | .is_non_err_ptr, | 1436 | .is_non_err_ptr, |
| 1432 | .unwrap_errunion_payload_ptr, | | |
| 1433 | .unwrap_errunion_err_ptr, | | |
| 1434 | | 1437 | |
| 1435 | .sqrt, | 1438 | .sqrt, |
| 1436 | .sin, | 1439 | .sin, |
| ... | @@ -1446,9 +1449,6 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { | ... | @@ -1446,9 +1449,6 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { |
| 1446 | .round, | 1449 | .round, |
| 1447 | .trunc_float, | 1450 | .trunc_float, |
| 1448 | | 1451 | |
| 1449 | .ptr_slice_len_ptr, | | |
| 1450 | .ptr_slice_ptr_ptr, | | |
| 1451 | .int_to_float, | | |
| 1452 | .cmpxchg_weak, | 1452 | .cmpxchg_weak, |
| 1453 | .cmpxchg_strong, | 1453 | .cmpxchg_strong, |
| 1454 | .fence, | 1454 | .fence, |
| ... | @@ -2560,30 +2560,32 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerError!W | ... | @@ -2560,30 +2560,32 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerError!W |
| 2560 | return is_err_tmp; | 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 | if (self.liveness.isUnused(inst)) return WValue{ .none = {} }; | 2564 | if (self.liveness.isUnused(inst)) return WValue{ .none = {} }; |
| 2565 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 2565 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 2566 | const operand = try self.resolveInst(ty_op.operand); | 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 | const payload_ty = err_ty.errorUnionPayload(); | 2569 | const payload_ty = err_ty.errorUnionPayload(); |
| 2569 | if (!payload_ty.hasRuntimeBits()) return WValue{ .none = {} }; | 2570 | if (!payload_ty.hasRuntimeBits()) return WValue{ .none = {} }; |
| 2570 | const err_align = err_ty.abiAlignment(self.target); | 2571 | const err_align = err_ty.abiAlignment(self.target); |
| 2571 | const set_size = err_ty.errorUnionSet().abiSize(self.target); | 2572 | const set_size = err_ty.errorUnionSet().abiSize(self.target); |
| 2572 | const offset = mem.alignForwardGeneric(u64, set_size, err_align); | 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 | return self.buildPointerOffset(operand, offset, .new); | 2575 | return self.buildPointerOffset(operand, offset, .new); |
| 2575 | } | 2576 | } |
| 2576 | return self.load(operand, payload_ty, @intCast(u32, offset)); | 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 | if (self.liveness.isUnused(inst)) return WValue{ .none = {} }; | 2581 | if (self.liveness.isUnused(inst)) return WValue{ .none = {} }; |
| 2581 | | 2582 | |
| 2582 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 2583 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 2583 | const operand = try self.resolveInst(ty_op.operand); | 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 | const payload_ty = err_ty.errorUnionPayload(); | 2587 | const payload_ty = err_ty.errorUnionPayload(); |
| 2586 | if (!payload_ty.hasRuntimeBits()) { | 2588 | if (op_is_ptr or !payload_ty.hasRuntimeBits()) { |
| 2587 | return operand; | 2589 | return operand; |
| 2588 | } | 2590 | } |
| 2589 | | 2591 | |
| ... | @@ -3231,6 +3233,28 @@ fn airFloatToInt(self: *Self, inst: Air.Inst.Index) InnerError!WValue { | ... | @@ -3231,6 +3233,28 @@ fn airFloatToInt(self: *Self, inst: Air.Inst.Index) InnerError!WValue { |
| 3231 | return result; | 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 | fn airSplat(self: *Self, inst: Air.Inst.Index) InnerError!WValue { | 3258 | fn airSplat(self: *Self, inst: Air.Inst.Index) InnerError!WValue { |
| 3235 | if (self.liveness.isUnused(inst)) return WValue{ .none = {} }; | 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,3 +3706,11 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) InnerError!WValue { |
| 3682 | try self.addLabel(.local_set, result_ptr.local); | 3706 | try self.addLabel(.local_set, result_ptr.local); |
| 3683 | return result_ptr; | 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 | } |