| ... | ... | @@ -568,6 +568,28 @@ pub const DeclGen = struct { |
| 568 | 568 | try self.addBytes(std.mem.asBytes(&int_bits)[0..@intCast(usize, len)]); |
| 569 | 569 | } |
| 570 | 570 | |
| 571 | fn addFloat(self: *@This(), ty: Type, val: Value) !void { |
| 572 | const target = self.dg.getTarget(); |
| 573 | const len = ty.abiSize(target); |
| 574 | |
| 575 | // TODO: Swap endianess if the compiler is big endian. |
| 576 | switch (ty.floatBits(target)) { |
| 577 | 16 => { |
| 578 | const float_bits = val.toFloat(f16); |
| 579 | try self.addBytes(std.mem.asBytes(&float_bits)[0..@intCast(usize, len)]); |
| 580 | }, |
| 581 | 32 => { |
| 582 | const float_bits = val.toFloat(f32); |
| 583 | try self.addBytes(std.mem.asBytes(&float_bits)[0..@intCast(usize, len)]); |
| 584 | }, |
| 585 | 64 => { |
| 586 | const float_bits = val.toFloat(f64); |
| 587 | try self.addBytes(std.mem.asBytes(&float_bits)[0..@intCast(usize, len)]); |
| 588 | }, |
| 589 | else => unreachable, |
| 590 | } |
| 591 | } |
| 592 | |
| 571 | 593 | fn addDeclRef(self: *@This(), ty: Type, decl_index: Decl.Index) !void { |
| 572 | 594 | const dg = self.dg; |
| 573 | 595 | |
| ... | ... | @@ -618,6 +640,7 @@ pub const DeclGen = struct { |
| 618 | 640 | |
| 619 | 641 | switch (ty.zigTypeTag()) { |
| 620 | 642 | .Int => try self.addInt(ty, val), |
| 643 | .Float => try self.addFloat(ty, val), |
| 621 | 644 | .Bool => try self.addConstBool(val.toBool()), |
| 622 | 645 | .Array => switch (val.tag()) { |
| 623 | 646 | .aggregate => { |
| ... | ... | @@ -1690,6 +1713,8 @@ pub const DeclGen = struct { |
| 1690 | 1713 | |
| 1691 | 1714 | .bitcast => try self.airBitcast(inst), |
| 1692 | 1715 | .intcast, .trunc => try self.airIntcast(inst), |
| 1716 | .int_to_float => try self.airIntToFloat(inst), |
| 1717 | .float_to_int => try self.airFloatToInt(inst), |
| 1693 | 1718 | .not => try self.airNot(inst), |
| 1694 | 1719 | |
| 1695 | 1720 | .slice_ptr => try self.airSliceField(inst, 0), |
| ... | ... | @@ -2095,6 +2120,57 @@ pub const DeclGen = struct { |
| 2095 | 2120 | return result_id; |
| 2096 | 2121 | } |
| 2097 | 2122 | |
| 2123 | fn airIntToFloat(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 2124 | if (self.liveness.isUnused(inst)) return null; |
| 2125 | |
| 2126 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 2127 | const operand_ty = self.air.typeOf(ty_op.operand); |
| 2128 | const operand_id = try self.resolve(ty_op.operand); |
| 2129 | const operand_info = try self.arithmeticTypeInfo(operand_ty); |
| 2130 | const dest_ty = self.air.typeOfIndex(inst); |
| 2131 | const dest_ty_id = try self.resolveTypeId(dest_ty); |
| 2132 | |
| 2133 | const result_id = self.spv.allocId(); |
| 2134 | switch (operand_info.signedness) { |
| 2135 | .signed => try self.func.body.emit(self.spv.gpa, .OpConvertSToF, .{ |
| 2136 | .id_result_type = dest_ty_id, |
| 2137 | .id_result = result_id, |
| 2138 | .signed_value = operand_id, |
| 2139 | }), |
| 2140 | .unsigned => try self.func.body.emit(self.spv.gpa, .OpConvertUToF, .{ |
| 2141 | .id_result_type = dest_ty_id, |
| 2142 | .id_result = result_id, |
| 2143 | .unsigned_value = operand_id, |
| 2144 | }), |
| 2145 | } |
| 2146 | return result_id; |
| 2147 | } |
| 2148 | |
| 2149 | fn airFloatToInt(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 2150 | if (self.liveness.isUnused(inst)) return null; |
| 2151 | |
| 2152 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 2153 | const operand_id = try self.resolve(ty_op.operand); |
| 2154 | const dest_ty = self.air.typeOfIndex(inst); |
| 2155 | const dest_info = try self.arithmeticTypeInfo(dest_ty); |
| 2156 | const dest_ty_id = try self.resolveTypeId(dest_ty); |
| 2157 | |
| 2158 | const result_id = self.spv.allocId(); |
| 2159 | switch (dest_info.signedness) { |
| 2160 | .signed => try self.func.body.emit(self.spv.gpa, .OpConvertFToS, .{ |
| 2161 | .id_result_type = dest_ty_id, |
| 2162 | .id_result = result_id, |
| 2163 | .float_value = operand_id, |
| 2164 | }), |
| 2165 | .unsigned => try self.func.body.emit(self.spv.gpa, .OpConvertFToU, .{ |
| 2166 | .id_result_type = dest_ty_id, |
| 2167 | .id_result = result_id, |
| 2168 | .float_value = operand_id, |
| 2169 | }), |
| 2170 | } |
| 2171 | return result_id; |
| 2172 | } |
| 2173 | |
| 2098 | 2174 | fn airNot(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 2099 | 2175 | if (self.liveness.isUnused(inst)) return null; |
| 2100 | 2176 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |