| ... | ... | @@ -588,6 +588,12 @@ pub const DeclGen = struct { |
| 588 | 588 | const info = t.intInfo(self.module.getTarget()); |
| 589 | 589 | return self.context.intType(info.bits); |
| 590 | 590 | }, |
| 591 | .Enum => { |
| 592 | var buffer: Type.Payload.Bits = undefined; |
| 593 | const int_ty = t.enumTagType(&buffer); |
| 594 | const bit_count = int_ty.intInfo(self.module.getTarget()).bits; |
| 595 | return self.context.intType(bit_count); |
| 596 | }, |
| 591 | 597 | .Float => switch (t.floatBits(self.module.getTarget())) { |
| 592 | 598 | 16 => return self.context.halfType(), |
| 593 | 599 | 32 => return self.context.floatType(), |
| ... | ... | @@ -686,7 +692,6 @@ pub const DeclGen = struct { |
| 686 | 692 | |
| 687 | 693 | .BoundFn => @panic("TODO remove BoundFn from the language"), |
| 688 | 694 | |
| 689 | | .Enum, |
| 690 | 695 | .Union, |
| 691 | 696 | .Opaque, |
| 692 | 697 | .Frame, |
| ... | ... | @@ -723,6 +728,17 @@ pub const DeclGen = struct { |
| 723 | 728 | } |
| 724 | 729 | return llvm_int; |
| 725 | 730 | }, |
| 731 | .Enum => { |
| 732 | const llvm_type = try self.llvmType(tv.ty); |
| 733 | const uint: u64 = uint: { |
| 734 | if (tv.val.castTag(.enum_field_index)) |payload| { |
| 735 | break :uint payload.data; |
| 736 | } |
| 737 | break :uint tv.val.toUnsignedInt(); |
| 738 | }; |
| 739 | const llvm_int = llvm_type.constInt(uint, .False); |
| 740 | return llvm_int; |
| 741 | }, |
| 726 | 742 | .Float => { |
| 727 | 743 | if (tv.ty.floatBits(self.module.getTarget()) <= 64) { |
| 728 | 744 | const llvm_ty = try self.llvmType(tv.ty); |
| ... | ... | @@ -907,7 +923,18 @@ pub const DeclGen = struct { |
| 907 | 923 | .ComptimeFloat => unreachable, |
| 908 | 924 | .Type => unreachable, |
| 909 | 925 | .EnumLiteral => unreachable, |
| 910 | | else => return self.todo("implement const of type '{}'", .{tv.ty}), |
| 926 | .Void => unreachable, |
| 927 | .NoReturn => unreachable, |
| 928 | .Undefined => unreachable, |
| 929 | .Null => unreachable, |
| 930 | .BoundFn => unreachable, |
| 931 | .Opaque => unreachable, |
| 932 | |
| 933 | .Union, |
| 934 | .Frame, |
| 935 | .AnyFrame, |
| 936 | .Vector, |
| 937 | => return self.todo("implement const of type '{}'", .{tv.ty}), |
| 911 | 938 | } |
| 912 | 939 | } |
| 913 | 940 | |
| ... | ... | @@ -1195,21 +1222,15 @@ pub const FuncGen = struct { |
| 1195 | 1222 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 1196 | 1223 | const lhs = try self.resolveInst(bin_op.lhs); |
| 1197 | 1224 | const rhs = try self.resolveInst(bin_op.rhs); |
| 1198 | | const inst_ty = self.air.typeOfIndex(inst); |
| 1225 | const operand_ty = self.air.typeOf(bin_op.lhs); |
| 1199 | 1226 | |
| 1200 | | switch (self.air.typeOf(bin_op.lhs).zigTypeTag()) { |
| 1201 | | .Int, .Bool, .Pointer, .ErrorSet => { |
| 1202 | | const is_signed = inst_ty.isSignedInt(); |
| 1203 | | const operation = switch (op) { |
| 1204 | | .eq => .EQ, |
| 1205 | | .neq => .NE, |
| 1206 | | .lt => @as(llvm.IntPredicate, if (is_signed) .SLT else .ULT), |
| 1207 | | .lte => @as(llvm.IntPredicate, if (is_signed) .SLE else .ULE), |
| 1208 | | .gt => @as(llvm.IntPredicate, if (is_signed) .SGT else .UGT), |
| 1209 | | .gte => @as(llvm.IntPredicate, if (is_signed) .SGE else .UGE), |
| 1210 | | }; |
| 1211 | | return self.builder.buildICmp(operation, lhs, rhs, ""); |
| 1227 | const int_ty = switch (operand_ty.zigTypeTag()) { |
| 1228 | .Enum => blk: { |
| 1229 | var buffer: Type.Payload.Bits = undefined; |
| 1230 | const int_ty = operand_ty.enumTagType(&buffer); |
| 1231 | break :blk int_ty; |
| 1212 | 1232 | }, |
| 1233 | .Int, .Bool, .Pointer, .ErrorSet => operand_ty, |
| 1213 | 1234 | .Float => { |
| 1214 | 1235 | const operation: llvm.RealPredicate = switch (op) { |
| 1215 | 1236 | .eq => .OEQ, |
| ... | ... | @@ -1222,7 +1243,17 @@ pub const FuncGen = struct { |
| 1222 | 1243 | return self.builder.buildFCmp(operation, lhs, rhs, ""); |
| 1223 | 1244 | }, |
| 1224 | 1245 | else => unreachable, |
| 1225 | | } |
| 1246 | }; |
| 1247 | const is_signed = int_ty.isSignedInt(); |
| 1248 | const operation = switch (op) { |
| 1249 | .eq => .EQ, |
| 1250 | .neq => .NE, |
| 1251 | .lt => @as(llvm.IntPredicate, if (is_signed) .SLT else .ULT), |
| 1252 | .lte => @as(llvm.IntPredicate, if (is_signed) .SLE else .ULE), |
| 1253 | .gt => @as(llvm.IntPredicate, if (is_signed) .SGT else .UGT), |
| 1254 | .gte => @as(llvm.IntPredicate, if (is_signed) .SGE else .UGE), |
| 1255 | }; |
| 1256 | return self.builder.buildICmp(operation, lhs, rhs, ""); |
| 1226 | 1257 | } |
| 1227 | 1258 | |
| 1228 | 1259 | fn airBlock(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { |