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