| ... | ... | @@ -1381,7 +1381,7 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) InnerError!WValue { |
| 1381 | 1381 | const ret_ty = self.air.typeOf(un_op).childType(); |
| 1382 | 1382 | if (!ret_ty.hasCodeGenBits()) return WValue.none; |
| 1383 | 1383 | |
| 1384 | | if (ret_ty.isSlice() or ret_ty.zigTypeTag() == .ErrorUnion) { |
| 1384 | if (isByRef(ret_ty)) { |
| 1385 | 1385 | try self.emitWValue(operand); |
| 1386 | 1386 | } else { |
| 1387 | 1387 | const result = try self.load(operand, ret_ty, 0); |
| ... | ... | @@ -1521,6 +1521,14 @@ fn store(self: *Self, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerErro |
| 1521 | 1521 | |
| 1522 | 1522 | switch (rhs) { |
| 1523 | 1523 | .constant => { |
| 1524 | if (rhs.constant.val.castTag(.decl_ref)) |_| { |
| 1525 | // retrieve values from memory instead |
| 1526 | const mem_local = try self.allocLocal(Type.usize); |
| 1527 | try self.emitWValue(rhs); |
| 1528 | try self.addLabel(.local_set, mem_local.local); |
| 1529 | try self.store(lhs, mem_local, ty, 0); |
| 1530 | return; |
| 1531 | } |
| 1524 | 1532 | // constant will contain both tag and payload, |
| 1525 | 1533 | // so save those in 2 temporary locals before storing them |
| 1526 | 1534 | // in memory |
| ... | ... | @@ -1616,12 +1624,16 @@ fn store(self: *Self, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerErro |
| 1616 | 1624 | // check if we should pass by pointer or value based on ABI size |
| 1617 | 1625 | // TODO: Implement a way to get ABI values from a given type, |
| 1618 | 1626 | // that is portable across the backend, rather than copying logic. |
| 1619 | | const abi_size = if ((ty.isInt() or ty.isAnyFloat()) and ty.abiSize(self.target) <= 8) |
| 1620 | | @intCast(u8, ty.abiSize(self.target)) |
| 1621 | | else if (ty.zigTypeTag() == .ErrorSet or ty.zigTypeTag() == .Enum or ty.zigTypeTag() == .Bool) |
| 1622 | | @intCast(u8, ty.abiSize(self.target)) |
| 1623 | | else |
| 1624 | | @as(u8, 4); |
| 1627 | const abi_size = switch (ty.zigTypeTag()) { |
| 1628 | .Int, |
| 1629 | .Float, |
| 1630 | .ErrorSet, |
| 1631 | .Enum, |
| 1632 | .Bool, |
| 1633 | .ErrorUnion, |
| 1634 | => @intCast(u8, ty.abiSize(self.target)), |
| 1635 | else => @as(u8, 4), |
| 1636 | }; |
| 1625 | 1637 | const opcode = buildOpcode(.{ |
| 1626 | 1638 | .valtype1 = valtype, |
| 1627 | 1639 | .width = abi_size * 8, // use bitsize instead of byte size |
| ... | ... | @@ -1643,7 +1655,9 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) InnerError!WValue { |
| 1643 | 1655 | if (!ty.hasCodeGenBits()) return WValue{ .none = {} }; |
| 1644 | 1656 | |
| 1645 | 1657 | if (isByRef(ty)) { |
| 1646 | | return operand; |
| 1658 | const new_local = try self.allocStack(ty); |
| 1659 | try self.store(new_local, operand, ty, 0); |
| 1660 | return new_local; |
| 1647 | 1661 | } |
| 1648 | 1662 | |
| 1649 | 1663 | return switch (operand) { |
| ... | ... | @@ -1662,12 +1676,16 @@ fn load(self: *Self, operand: WValue, ty: Type, offset: u32) InnerError!WValue { |
| 1662 | 1676 | .signed; |
| 1663 | 1677 | // TODO: Implement a way to get ABI values from a given type, |
| 1664 | 1678 | // that is portable across the backend, rather than copying logic. |
| 1665 | | const abi_size = if ((ty.isInt() or ty.isAnyFloat()) and ty.abiSize(self.target) <= 8) |
| 1666 | | @intCast(u8, ty.abiSize(self.target)) |
| 1667 | | else if (ty.zigTypeTag() == .ErrorSet or ty.zigTypeTag() == .Enum or ty.zigTypeTag() == .Bool) |
| 1668 | | @intCast(u8, ty.abiSize(self.target)) |
| 1669 | | else |
| 1670 | | @as(u8, 4); |
| 1679 | const abi_size = switch (ty.zigTypeTag()) { |
| 1680 | .Int, |
| 1681 | .Float, |
| 1682 | .ErrorSet, |
| 1683 | .Enum, |
| 1684 | .Bool, |
| 1685 | .ErrorUnion, |
| 1686 | => @intCast(u8, ty.abiSize(self.target)), |
| 1687 | else => @as(u8, 4), |
| 1688 | }; |
| 1671 | 1689 | |
| 1672 | 1690 | const opcode = buildOpcode(.{ |
| 1673 | 1691 | .valtype1 = try self.typeToValtype(ty), |