| ... | @@ -792,43 +792,45 @@ pub const Context = struct { | ... | @@ -792,43 +792,45 @@ pub const Context = struct { |
| 792 | fn genInst(self: *Context, inst: Air.Inst.Index) !WValue { | 792 | fn genInst(self: *Context, inst: Air.Inst.Index) !WValue { |
| 793 | const air_tags = self.air.instructions.items(.tag); | 793 | const air_tags = self.air.instructions.items(.tag); |
| 794 | return switch (air_tags[inst]) { | 794 | return switch (air_tags[inst]) { |
| 795 | .add => self.genBinOp(inst, .add), | 795 | .add => self.airBinOp(inst, .add), |
| 796 | .alloc => self.genAlloc(inst), | 796 | .sub => self.airBinOp(inst, .sub), |
| 797 | .arg => self.genArg(inst), | 797 | .mul => self.airBinOp(inst, .mul), |
| 798 | .bit_and => self.genBinOp(inst, .@"and"), | 798 | .div => self.airBinOp(inst, .div), |
| 799 | .bitcast => self.genBitcast(inst), | 799 | .bit_and => self.airBinOp(inst, .@"and"), |
| 800 | .bit_or => self.genBinOp(inst, .@"or"), | 800 | .bit_or => self.airBinOp(inst, .@"or"), |
| 801 | .block => self.genBlock(inst), | 801 | .bool_and => self.airBinOp(inst, .@"and"), |
| 802 | .bool_and => self.genBinOp(inst, .@"and"), | 802 | .bool_or => self.airBinOp(inst, .@"or"), |
| 803 | .bool_or => self.genBinOp(inst, .@"or"), | 803 | .xor => self.airBinOp(inst, .xor), |
| 804 | .breakpoint => self.genBreakpoint(inst), | 804 | |
| 805 | .br => self.genBr(inst), | 805 | .cmp_eq => self.airCmp(inst, .eq), |
| 806 | .call => self.genCall(inst), | 806 | .cmp_gte => self.airCmp(inst, .gte), |
| 807 | .cmp_eq => self.genCmp(inst, .eq), | 807 | .cmp_gt => self.airCmp(inst, .gt), |
| 808 | .cmp_gte => self.genCmp(inst, .gte), | 808 | .cmp_lte => self.airCmp(inst, .lte), |
| 809 | .cmp_gt => self.genCmp(inst, .gt), | 809 | .cmp_lt => self.airCmp(inst, .lt), |
| 810 | .cmp_lte => self.genCmp(inst, .lte), | 810 | .cmp_neq => self.airCmp(inst, .neq), |
| 811 | .cmp_lt => self.genCmp(inst, .lt), | 811 | |
| 812 | .cmp_neq => self.genCmp(inst, .neq), | 812 | .alloc => self.airAlloc(inst), |
| 813 | .cond_br => self.genCondBr(inst), | 813 | .arg => self.airArg(inst), |
| | 814 | .bitcast => self.airBitcast(inst), |
| | 815 | .block => self.airBlock(inst), |
| | 816 | .breakpoint => self.airBreakpoint(inst), |
| | 817 | .br => self.airBr(inst), |
| | 818 | .call => self.airCall(inst), |
| | 819 | .cond_br => self.airCondBr(inst), |
| 814 | .constant => unreachable, | 820 | .constant => unreachable, |
| 815 | .dbg_stmt => WValue.none, | 821 | .dbg_stmt => WValue.none, |
| 816 | .div => self.genBinOp(inst, .div), | 822 | .is_err => self.airIsErr(inst, .i32_ne), |
| 817 | .is_err => self.genIsErr(inst, .i32_ne), | 823 | .is_non_err => self.airIsErr(inst, .i32_eq), |
| 818 | .is_non_err => self.genIsErr(inst, .i32_eq), | 824 | .load => self.airLoad(inst), |
| 819 | .load => self.genLoad(inst), | 825 | .loop => self.airLoop(inst), |
| 820 | .loop => self.genLoop(inst), | 826 | .not => self.airNot(inst), |
| 821 | .mul => self.genBinOp(inst, .mul), | 827 | .ret => self.airRet(inst), |
| 822 | .not => self.genNot(inst), | 828 | .store => self.airStore(inst), |
| 823 | .ret => self.genRet(inst), | 829 | .struct_field_ptr => self.airStructFieldPtr(inst), |
| 824 | .store => self.genStore(inst), | 830 | .switch_br => self.airSwitchBr(inst), |
| 825 | .struct_field_ptr => self.genStructFieldPtr(inst), | 831 | .unreach => self.airUnreachable(inst), |
| 826 | .sub => self.genBinOp(inst, .sub), | 832 | .unwrap_errunion_payload => self.airUnwrapErrUnionPayload(inst), |
| 827 | .switch_br => self.genSwitchBr(inst), | 833 | .wrap_errunion_payload => self.airWrapErrUnionPayload(inst), |
| 828 | .unreach => self.genUnreachable(inst), | | |
| 829 | .unwrap_errunion_payload => self.genUnwrapErrUnionPayload(inst), | | |
| 830 | .wrap_errunion_payload => self.genWrapErrUnionPayload(inst), | | |
| 831 | .xor => self.genBinOp(inst, .xor), | | |
| 832 | else => |tag| self.fail("TODO: Implement wasm inst: {s}", .{@tagName(tag)}), | 834 | else => |tag| self.fail("TODO: Implement wasm inst: {s}", .{@tagName(tag)}), |
| 833 | }; | 835 | }; |
| 834 | } | 836 | } |
| ... | @@ -840,7 +842,7 @@ pub const Context = struct { | ... | @@ -840,7 +842,7 @@ pub const Context = struct { |
| 840 | } | 842 | } |
| 841 | } | 843 | } |
| 842 | | 844 | |
| 843 | fn genRet(self: *Context, inst: Air.Inst.Index) InnerError!WValue { | 845 | fn airRet(self: *Context, inst: Air.Inst.Index) InnerError!WValue { |
| 844 | const un_op = self.air.instructions.items(.data)[inst].un_op; | 846 | const un_op = self.air.instructions.items(.data)[inst].un_op; |
| 845 | const operand = self.resolveInst(un_op); | 847 | const operand = self.resolveInst(un_op); |
| 846 | try self.emitWValue(operand); | 848 | try self.emitWValue(operand); |
| ... | @@ -848,7 +850,7 @@ pub const Context = struct { | ... | @@ -848,7 +850,7 @@ pub const Context = struct { |
| 848 | return .none; | 850 | return .none; |
| 849 | } | 851 | } |
| 850 | | 852 | |
| 851 | fn genCall(self: *Context, inst: Air.Inst.Index) InnerError!WValue { | 853 | fn airCall(self: *Context, inst: Air.Inst.Index) InnerError!WValue { |
| 852 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; | 854 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; |
| 853 | const extra = self.air.extraData(Air.Call, pl_op.payload); | 855 | const extra = self.air.extraData(Air.Call, pl_op.payload); |
| 854 | const args = self.air.extra[extra.end..][0..extra.data.args_len]; | 856 | const args = self.air.extra[extra.end..][0..extra.data.args_len]; |
| ... | @@ -882,12 +884,12 @@ pub const Context = struct { | ... | @@ -882,12 +884,12 @@ pub const Context = struct { |
| 882 | return .none; | 884 | return .none; |
| 883 | } | 885 | } |
| 884 | | 886 | |
| 885 | fn genAlloc(self: *Context, inst: Air.Inst.Index) InnerError!WValue { | 887 | fn airAlloc(self: *Context, inst: Air.Inst.Index) InnerError!WValue { |
| 886 | const elem_type = self.air.typeOfIndex(inst).elemType(); | 888 | const elem_type = self.air.typeOfIndex(inst).elemType(); |
| 887 | return self.allocLocal(elem_type); | 889 | return self.allocLocal(elem_type); |
| 888 | } | 890 | } |
| 889 | | 891 | |
| 890 | fn genStore(self: *Context, inst: Air.Inst.Index) InnerError!WValue { | 892 | fn airStore(self: *Context, inst: Air.Inst.Index) InnerError!WValue { |
| 891 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; | 893 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 892 | const writer = self.code.writer(); | 894 | const writer = self.code.writer(); |
| 893 | | 895 | |
| ... | @@ -926,19 +928,19 @@ pub const Context = struct { | ... | @@ -926,19 +928,19 @@ pub const Context = struct { |
| 926 | return .none; | 928 | return .none; |
| 927 | } | 929 | } |
| 928 | | 930 | |
| 929 | fn genLoad(self: *Context, inst: Air.Inst.Index) InnerError!WValue { | 931 | fn airLoad(self: *Context, inst: Air.Inst.Index) InnerError!WValue { |
| 930 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 932 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 931 | return self.resolveInst(ty_op.operand); | 933 | return self.resolveInst(ty_op.operand); |
| 932 | } | 934 | } |
| 933 | | 935 | |
| 934 | fn genArg(self: *Context, inst: Air.Inst.Index) InnerError!WValue { | 936 | fn airArg(self: *Context, inst: Air.Inst.Index) InnerError!WValue { |
| 935 | _ = inst; | 937 | _ = inst; |
| 936 | // arguments share the index with locals | 938 | // arguments share the index with locals |
| 937 | defer self.local_index += 1; | 939 | defer self.local_index += 1; |
| 938 | return WValue{ .local = self.local_index }; | 940 | return WValue{ .local = self.local_index }; |
| 939 | } | 941 | } |
| 940 | | 942 | |
| 941 | fn genBinOp(self: *Context, inst: Air.Inst.Index, op: Op) InnerError!WValue { | 943 | fn airBinOp(self: *Context, inst: Air.Inst.Index, op: Op) InnerError!WValue { |
| 942 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; | 944 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 943 | const lhs = self.resolveInst(bin_op.lhs); | 945 | const lhs = self.resolveInst(bin_op.lhs); |
| 944 | const rhs = self.resolveInst(bin_op.rhs); | 946 | const rhs = self.resolveInst(bin_op.rhs); |
| ... | @@ -1074,7 +1076,7 @@ pub const Context = struct { | ... | @@ -1074,7 +1076,7 @@ pub const Context = struct { |
| 1074 | } | 1076 | } |
| 1075 | } | 1077 | } |
| 1076 | | 1078 | |
| 1077 | fn genBlock(self: *Context, inst: Air.Inst.Index) InnerError!WValue { | 1079 | fn airBlock(self: *Context, inst: Air.Inst.Index) InnerError!WValue { |
| 1078 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 1080 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 1079 | const block_ty = try self.genBlockType(self.air.getRefType(ty_pl.ty)); | 1081 | const block_ty = try self.genBlockType(self.air.getRefType(ty_pl.ty)); |
| 1080 | const extra = self.air.extraData(Air.Block, ty_pl.payload); | 1082 | const extra = self.air.extraData(Air.Block, ty_pl.payload); |
| ... | @@ -1108,7 +1110,7 @@ pub const Context = struct { | ... | @@ -1108,7 +1110,7 @@ pub const Context = struct { |
| 1108 | self.block_depth -= 1; | 1110 | self.block_depth -= 1; |
| 1109 | } | 1111 | } |
| 1110 | | 1112 | |
| 1111 | fn genLoop(self: *Context, inst: Air.Inst.Index) InnerError!WValue { | 1113 | fn airLoop(self: *Context, inst: Air.Inst.Index) InnerError!WValue { |
| 1112 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 1114 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 1113 | const loop = self.air.extraData(Air.Block, ty_pl.payload); | 1115 | const loop = self.air.extraData(Air.Block, ty_pl.payload); |
| 1114 | const body = self.air.extra[loop.end..][0..loop.data.body_len]; | 1116 | const body = self.air.extra[loop.end..][0..loop.data.body_len]; |
| ... | @@ -1127,7 +1129,7 @@ pub const Context = struct { | ... | @@ -1127,7 +1129,7 @@ pub const Context = struct { |
| 1127 | return .none; | 1129 | return .none; |
| 1128 | } | 1130 | } |
| 1129 | | 1131 | |
| 1130 | fn genCondBr(self: *Context, inst: Air.Inst.Index) InnerError!WValue { | 1132 | fn airCondBr(self: *Context, inst: Air.Inst.Index) InnerError!WValue { |
| 1131 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; | 1133 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; |
| 1132 | const condition = self.resolveInst(pl_op.operand); | 1134 | const condition = self.resolveInst(pl_op.operand); |
| 1133 | const extra = self.air.extraData(Air.CondBr, pl_op.payload); | 1135 | const extra = self.air.extraData(Air.CondBr, pl_op.payload); |
| ... | @@ -1166,7 +1168,7 @@ pub const Context = struct { | ... | @@ -1166,7 +1168,7 @@ pub const Context = struct { |
| 1166 | return .none; | 1168 | return .none; |
| 1167 | } | 1169 | } |
| 1168 | | 1170 | |
| 1169 | fn genCmp(self: *Context, inst: Air.Inst.Index, op: std.math.CompareOperator) InnerError!WValue { | 1171 | fn airCmp(self: *Context, inst: Air.Inst.Index, op: std.math.CompareOperator) InnerError!WValue { |
| 1170 | // save offset, so potential conditions can insert blocks in front of | 1172 | // save offset, so potential conditions can insert blocks in front of |
| 1171 | // the comparison that we can later jump back to | 1173 | // the comparison that we can later jump back to |
| 1172 | const offset = self.code.items.len; | 1174 | const offset = self.code.items.len; |
| ... | @@ -1202,7 +1204,7 @@ pub const Context = struct { | ... | @@ -1202,7 +1204,7 @@ pub const Context = struct { |
| 1202 | return WValue{ .code_offset = offset }; | 1204 | return WValue{ .code_offset = offset }; |
| 1203 | } | 1205 | } |
| 1204 | | 1206 | |
| 1205 | fn genBr(self: *Context, inst: Air.Inst.Index) InnerError!WValue { | 1207 | fn airBr(self: *Context, inst: Air.Inst.Index) InnerError!WValue { |
| 1206 | const br = self.air.instructions.items(.data)[inst].br; | 1208 | const br = self.air.instructions.items(.data)[inst].br; |
| 1207 | | 1209 | |
| 1208 | // if operand has codegen bits we should break with a value | 1210 | // if operand has codegen bits we should break with a value |
| ... | @@ -1220,7 +1222,7 @@ pub const Context = struct { | ... | @@ -1220,7 +1222,7 @@ pub const Context = struct { |
| 1220 | return .none; | 1222 | return .none; |
| 1221 | } | 1223 | } |
| 1222 | | 1224 | |
| 1223 | fn genNot(self: *Context, inst: Air.Inst.Index) InnerError!WValue { | 1225 | fn airNot(self: *Context, inst: Air.Inst.Index) InnerError!WValue { |
| 1224 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 1226 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 1225 | const offset = self.code.items.len; | 1227 | const offset = self.code.items.len; |
| 1226 | | 1228 | |
| ... | @@ -1238,7 +1240,7 @@ pub const Context = struct { | ... | @@ -1238,7 +1240,7 @@ pub const Context = struct { |
| 1238 | return WValue{ .code_offset = offset }; | 1240 | return WValue{ .code_offset = offset }; |
| 1239 | } | 1241 | } |
| 1240 | | 1242 | |
| 1241 | fn genBreakpoint(self: *Context, inst: Air.Inst.Index) InnerError!WValue { | 1243 | fn airBreakpoint(self: *Context, inst: Air.Inst.Index) InnerError!WValue { |
| 1242 | _ = self; | 1244 | _ = self; |
| 1243 | _ = inst; | 1245 | _ = inst; |
| 1244 | // unsupported by wasm itself. Can be implemented once we support DWARF | 1246 | // unsupported by wasm itself. Can be implemented once we support DWARF |
| ... | @@ -1246,18 +1248,18 @@ pub const Context = struct { | ... | @@ -1246,18 +1248,18 @@ pub const Context = struct { |
| 1246 | return .none; | 1248 | return .none; |
| 1247 | } | 1249 | } |
| 1248 | | 1250 | |
| 1249 | fn genUnreachable(self: *Context, inst: Air.Inst.Index) InnerError!WValue { | 1251 | fn airUnreachable(self: *Context, inst: Air.Inst.Index) InnerError!WValue { |
| 1250 | _ = inst; | 1252 | _ = inst; |
| 1251 | try self.code.append(wasm.opcode(.@"unreachable")); | 1253 | try self.code.append(wasm.opcode(.@"unreachable")); |
| 1252 | return .none; | 1254 | return .none; |
| 1253 | } | 1255 | } |
| 1254 | | 1256 | |
| 1255 | fn genBitcast(self: *Context, inst: Air.Inst.Index) InnerError!WValue { | 1257 | fn airBitcast(self: *Context, inst: Air.Inst.Index) InnerError!WValue { |
| 1256 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 1258 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 1257 | return self.resolveInst(ty_op.operand); | 1259 | return self.resolveInst(ty_op.operand); |
| 1258 | } | 1260 | } |
| 1259 | | 1261 | |
| 1260 | fn genStructFieldPtr(self: *Context, inst: Air.Inst.Index) InnerError!WValue { | 1262 | fn airStructFieldPtr(self: *Context, inst: Air.Inst.Index) InnerError!WValue { |
| 1261 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 1263 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 1262 | const extra = self.air.extraData(Air.StructField, ty_pl.payload); | 1264 | const extra = self.air.extraData(Air.StructField, ty_pl.payload); |
| 1263 | const struct_ptr = self.resolveInst(extra.data.struct_ptr); | 1265 | const struct_ptr = self.resolveInst(extra.data.struct_ptr); |
| ... | @@ -1265,7 +1267,7 @@ pub const Context = struct { | ... | @@ -1265,7 +1267,7 @@ pub const Context = struct { |
| 1265 | return WValue{ .local = struct_ptr.multi_value.index + @intCast(u32, extra.data.field_index) }; | 1267 | return WValue{ .local = struct_ptr.multi_value.index + @intCast(u32, extra.data.field_index) }; |
| 1266 | } | 1268 | } |
| 1267 | | 1269 | |
| 1268 | fn genSwitchBr(self: *Context, inst: Air.Inst.Index) InnerError!WValue { | 1270 | fn airSwitchBr(self: *Context, inst: Air.Inst.Index) InnerError!WValue { |
| 1269 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; | 1271 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; |
| 1270 | const extra = self.air.extraData(Air.SwitchBr, pl_op.payload); | 1272 | const extra = self.air.extraData(Air.SwitchBr, pl_op.payload); |
| 1271 | const cases = self.air.extra[extra.end..][0..extra.data.cases_len]; | 1273 | const cases = self.air.extra[extra.end..][0..extra.data.cases_len]; |
| ... | @@ -1319,7 +1321,7 @@ pub const Context = struct { | ... | @@ -1319,7 +1321,7 @@ pub const Context = struct { |
| 1319 | return .none; | 1321 | return .none; |
| 1320 | } | 1322 | } |
| 1321 | | 1323 | |
| 1322 | fn genIsErr(self: *Context, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerError!WValue { | 1324 | fn airIsErr(self: *Context, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerError!WValue { |
| 1323 | const un_op = self.air.instructions.items(.data)[inst].un_op; | 1325 | const un_op = self.air.instructions.items(.data)[inst].un_op; |
| 1324 | const operand = self.resolveInst(un_op); | 1326 | const operand = self.resolveInst(un_op); |
| 1325 | const offset = self.code.items.len; | 1327 | const offset = self.code.items.len; |
| ... | @@ -1336,7 +1338,7 @@ pub const Context = struct { | ... | @@ -1336,7 +1338,7 @@ pub const Context = struct { |
| 1336 | return WValue{ .code_offset = offset }; | 1338 | return WValue{ .code_offset = offset }; |
| 1337 | } | 1339 | } |
| 1338 | | 1340 | |
| 1339 | fn genUnwrapErrUnionPayload(self: *Context, inst: Air.Inst.Index) InnerError!WValue { | 1341 | fn airUnwrapErrUnionPayload(self: *Context, inst: Air.Inst.Index) InnerError!WValue { |
| 1340 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 1342 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 1341 | const operand = self.resolveInst(ty_op.operand); | 1343 | const operand = self.resolveInst(ty_op.operand); |
| 1342 | // The index of multi_value contains the error code. To get the initial index of the payload we get | 1344 | // The index of multi_value contains the error code. To get the initial index of the payload we get |
| ... | @@ -1346,7 +1348,7 @@ pub const Context = struct { | ... | @@ -1346,7 +1348,7 @@ pub const Context = struct { |
| 1346 | return WValue{ .local = operand.multi_value.index + 1 }; | 1348 | return WValue{ .local = operand.multi_value.index + 1 }; |
| 1347 | } | 1349 | } |
| 1348 | | 1350 | |
| 1349 | fn genWrapErrUnionPayload(self: *Context, inst: Air.Inst.Index) InnerError!WValue { | 1351 | fn airWrapErrUnionPayload(self: *Context, inst: Air.Inst.Index) InnerError!WValue { |
| 1350 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 1352 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 1351 | return self.resolveInst(ty_op.operand); | 1353 | return self.resolveInst(ty_op.operand); |
| 1352 | } | 1354 | } |