authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-03-04 16:20:31-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-03-04 16:20:31-05:00
loge7f128c2051b086cdb1c03da041745b560bbaa3e
tree89d06ee67639dfa0260c5beabc344fb33099df0d
parentc9d990d79083f117564837f762c3e225d7fbc5cf
parent4eb3f50fcf6fcfb6b8013571be00b9eeeb909833
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #14782 from r00ster91/trap

add `@trap` builtin

28 files changed, 203 insertions(+), 34 deletions(-)

doc/langref.html.in+16-1
...@@ -7818,12 +7818,14 @@ comptime {...@@ -7818,12 +7818,14 @@ comptime {
7818 <p>7818 <p>
7819 This function inserts a platform-specific debug trap instruction which causes7819 This function inserts a platform-specific debug trap instruction which causes
7820 debuggers to break there.7820 debuggers to break there.
7821 Unlike for {#syntax#}@trap(){#endsyntax#}, execution may continue after this point if the program is resumed.
7821 </p>7822 </p>
7822 <p>7823 <p>
7823 This function is only valid within function scope.7824 This function is only valid within function scope.
7824 </p>7825 </p>
78257826 {#see_also|@trap#}
7826 {#header_close#}7827 {#header_close#}
7828
7827 {#header_open|@mulAdd#}7829 {#header_open|@mulAdd#}
7828 <pre>{#syntax#}@mulAdd(comptime T: type, a: T, b: T, c: T) T{#endsyntax#}</pre>7830 <pre>{#syntax#}@mulAdd(comptime T: type, a: T, b: T, c: T) T{#endsyntax#}</pre>
7829 <p>7831 <p>
...@@ -9393,6 +9395,19 @@ fn List(comptime T: type) type {...@@ -9393,6 +9395,19 @@ fn List(comptime T: type) type {
9393 </p>9395 </p>
9394 {#header_close#}9396 {#header_close#}
93959397
9398 {#header_open|@trap#}
9399 <pre>{#syntax#}@trap() noreturn{#endsyntax#}</pre>
9400 <p>
9401 This function inserts a platform-specific trap/jam instruction which can be used to exit the program abnormally.
9402 This may be implemented by explicitly emitting an invalid instruction which may cause an illegal instruction exception of some sort.
9403 Unlike for {#syntax#}@breakpoint(){#endsyntax#}, execution does not continue after this point.
9404 </p>
9405 <p>
9406 This function is only valid within function scope.
9407 </p>
9408 {#see_also|@breakpoint#}
9409 {#header_close#}
9410
9396 {#header_open|@truncate#}9411 {#header_open|@truncate#}
9397 <pre>{#syntax#}@truncate(comptime T: type, integer: anytype) T{#endsyntax#}</pre>9412 <pre>{#syntax#}@truncate(comptime T: type, integer: anytype) T{#endsyntax#}</pre>
9398 <p>9413 <p>
lib/docs/main.js-4
...@@ -1187,10 +1187,6 @@ const NAV_MODES = {...@@ -1187,10 +1187,6 @@ const NAV_MODES = {
1187 payloadHtml += "panic";1187 payloadHtml += "panic";
1188 break;1188 break;
1189 }1189 }
1190 case "set_cold": {
1191 payloadHtml += "setCold";
1192 break;
1193 }
1194 case "set_runtime_safety": {1190 case "set_runtime_safety": {
1195 payloadHtml += "setRuntimeSafety";1191 payloadHtml += "setRuntimeSafety";
1196 break;1192 break;
lib/zig.h+8-2
...@@ -180,10 +180,16 @@ typedef char bool;...@@ -180,10 +180,16 @@ typedef char bool;
180#define zig_export(sig, symbol, name) __asm(name " = " symbol)180#define zig_export(sig, symbol, name) __asm(name " = " symbol)
181#endif181#endif
182182
183#if zig_has_builtin(trap)
184#define zig_trap() __builtin_trap()
185#elif defined(__i386__) || defined(__x86_64__)
186#define zig_trap() __asm__ volatile("ud2");
187#else
188#define zig_trap() raise(SIGILL)
189#endif
190
183#if zig_has_builtin(debugtrap)191#if zig_has_builtin(debugtrap)
184#define zig_breakpoint() __builtin_debugtrap()192#define zig_breakpoint() __builtin_debugtrap()
185#elif zig_has_builtin(trap) || defined(zig_gnuc)
186#define zig_breakpoint() __builtin_trap()
187#elif defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__)193#elif defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__)
188#define zig_breakpoint() __debugbreak()194#define zig_breakpoint() __debugbreak()
189#elif defined(__i386__) || defined(__x86_64__)195#elif defined(__i386__) || defined(__x86_64__)
src/Air.zig+9-1
...@@ -232,7 +232,14 @@ pub const Inst = struct {...@@ -232,7 +232,14 @@ pub const Inst = struct {
232 /// Result type is always noreturn; no instructions in a block follow this one.232 /// Result type is always noreturn; no instructions in a block follow this one.
233 /// Uses the `br` field.233 /// Uses the `br` field.
234 br,234 br,
235 /// Lowers to a hardware trap instruction, or the next best thing.235 /// Lowers to a trap/jam instruction causing program abortion.
236 /// This may lower to an instruction known to be invalid.
237 /// Sometimes, for the lack of a better instruction, `trap` and `breakpoint` may compile down to the same code.
238 /// Result type is always noreturn; no instructions in a block follow this one.
239 trap,
240 /// Lowers to a trap instruction causing debuggers to break here, or the next best thing.
241 /// The debugger or something else may allow the program to resume after this point.
242 /// Sometimes, for the lack of a better instruction, `trap` and `breakpoint` may compile down to the same code.
236 /// Result type is always void.243 /// Result type is always void.
237 breakpoint,244 breakpoint,
238 /// Yields the return address of the current function.245 /// Yields the return address of the current function.
...@@ -1186,6 +1193,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {...@@ -1186,6 +1193,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
1186 .ret,1193 .ret,
1187 .ret_load,1194 .ret_load,
1188 .unreach,1195 .unreach,
1196 .trap,
1189 => return Type.initTag(.noreturn),1197 => return Type.initTag(.noreturn),
11901198
1191 .breakpoint,1199 .breakpoint,
src/AstGen.zig+17-4
...@@ -2609,8 +2609,9 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As...@@ -2609,8 +2609,9 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As
2609 .extended => switch (gz.astgen.instructions.items(.data)[inst].extended.opcode) {2609 .extended => switch (gz.astgen.instructions.items(.data)[inst].extended.opcode) {
2610 .breakpoint,2610 .breakpoint,
2611 .fence,2611 .fence,
2612 .set_align_stack,
2613 .set_float_mode,2612 .set_float_mode,
2613 .set_align_stack,
2614 .set_cold,
2614 => break :b true,2615 => break :b true,
2615 else => break :b false,2616 else => break :b false,
2616 },2617 },
...@@ -2630,6 +2631,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As...@@ -2630,6 +2631,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As
2630 .repeat_inline,2631 .repeat_inline,
2631 .panic,2632 .panic,
2632 .panic_comptime,2633 .panic_comptime,
2634 .trap,
2633 .check_comptime_control_flow,2635 .check_comptime_control_flow,
2634 => {2636 => {
2635 noreturn_src_node = statement;2637 noreturn_src_node = statement;
...@@ -2658,7 +2660,6 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As...@@ -2658,7 +2660,6 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As
2658 .validate_struct_init_comptime,2660 .validate_struct_init_comptime,
2659 .validate_array_init,2661 .validate_array_init,
2660 .validate_array_init_comptime,2662 .validate_array_init_comptime,
2661 .set_cold,
2662 .set_runtime_safety,2663 .set_runtime_safety,
2663 .closure_capture,2664 .closure_capture,
2664 .memcpy,2665 .memcpy,
...@@ -8081,6 +8082,14 @@ fn builtinCall(...@@ -8081,6 +8082,14 @@ fn builtinCall(
8081 });8082 });
8082 return rvalue(gz, ri, result, node);8083 return rvalue(gz, ri, result, node);
8083 },8084 },
8085 .set_cold => {
8086 const order = try expr(gz, scope, ri, params[0]);
8087 const result = try gz.addExtendedPayload(.set_cold, Zir.Inst.UnNode{
8088 .node = gz.nodeIndexToRelative(node),
8089 .operand = order,
8090 });
8091 return rvalue(gz, ri, result, node);
8092 },
80848093
8085 .src => {8094 .src => {
8086 const token_starts = tree.tokens.items(.start);8095 const token_starts = tree.tokens.items(.start);
...@@ -8100,7 +8109,7 @@ fn builtinCall(...@@ -8100,7 +8109,7 @@ fn builtinCall(
8100 .error_return_trace => return rvalue(gz, ri, try gz.addNodeExtended(.error_return_trace, node), node),8109 .error_return_trace => return rvalue(gz, ri, try gz.addNodeExtended(.error_return_trace, node), node),
8101 .frame => return rvalue(gz, ri, try gz.addNodeExtended(.frame, node), node),8110 .frame => return rvalue(gz, ri, try gz.addNodeExtended(.frame, node), node),
8102 .frame_address => return rvalue(gz, ri, try gz.addNodeExtended(.frame_address, node), node),8111 .frame_address => return rvalue(gz, ri, try gz.addNodeExtended(.frame_address, node), node),
8103 .breakpoint => return rvalue(gz, ri, try gz.addNodeExtended(.breakpoint, node), node),8112 .breakpoint => return rvalue(gz, ri, try gz.addNodeExtended(.breakpoint, node), node),
81048113
8105 .type_info => return simpleUnOpType(gz, scope, ri, node, params[0], .type_info),8114 .type_info => return simpleUnOpType(gz, scope, ri, node, params[0], .type_info),
8106 .size_of => return simpleUnOpType(gz, scope, ri, node, params[0], .size_of),8115 .size_of => return simpleUnOpType(gz, scope, ri, node, params[0], .size_of),
...@@ -8114,7 +8123,6 @@ fn builtinCall(...@@ -8114,7 +8123,6 @@ fn builtinCall(
8114 .bool_to_int => return simpleUnOp(gz, scope, ri, node, bool_ri, params[0], .bool_to_int),8123 .bool_to_int => return simpleUnOp(gz, scope, ri, node, bool_ri, params[0], .bool_to_int),
8115 .embed_file => return simpleUnOp(gz, scope, ri, node, .{ .rl = .{ .ty = .const_slice_u8_type } }, params[0], .embed_file),8124 .embed_file => return simpleUnOp(gz, scope, ri, node, .{ .rl = .{ .ty = .const_slice_u8_type } }, params[0], .embed_file),
8116 .error_name => return simpleUnOp(gz, scope, ri, node, .{ .rl = .{ .ty = .anyerror_type } }, params[0], .error_name),8125 .error_name => return simpleUnOp(gz, scope, ri, node, .{ .rl = .{ .ty = .anyerror_type } }, params[0], .error_name),
8117 .set_cold => return simpleUnOp(gz, scope, ri, node, bool_ri, params[0], .set_cold),
8118 .set_runtime_safety => return simpleUnOp(gz, scope, ri, node, bool_ri, params[0], .set_runtime_safety),8126 .set_runtime_safety => return simpleUnOp(gz, scope, ri, node, bool_ri, params[0], .set_runtime_safety),
8119 .sqrt => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .sqrt),8127 .sqrt => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .sqrt),
8120 .sin => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .sin),8128 .sin => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .sin),
...@@ -8174,6 +8182,11 @@ fn builtinCall(...@@ -8174,6 +8182,11 @@ fn builtinCall(
8174 try emitDbgNode(gz, node);8182 try emitDbgNode(gz, node);
8175 return simpleUnOp(gz, scope, ri, node, .{ .rl = .{ .ty = .const_slice_u8_type } }, params[0], if (gz.force_comptime) .panic_comptime else .panic);8183 return simpleUnOp(gz, scope, ri, node, .{ .rl = .{ .ty = .const_slice_u8_type } }, params[0], if (gz.force_comptime) .panic_comptime else .panic);
8176 },8184 },
8185 .trap => {
8186 try emitDbgNode(gz, node);
8187 _ = try gz.addNode(.trap, node);
8188 return rvalue(gz, ri, .void_value, node);
8189 },
8177 .error_to_int => {8190 .error_to_int => {
8178 const operand = try expr(gz, scope, .{ .rl = .none }, params[0]);8191 const operand = try expr(gz, scope, .{ .rl = .none }, params[0]);
8179 const result = try gz.addExtendedPayload(.error_to_int, Zir.Inst.UnNode{8192 const result = try gz.addExtendedPayload(.error_to_int, Zir.Inst.UnNode{
src/Autodoc.zig-1
...@@ -1338,7 +1338,6 @@ fn walkInstruction(...@@ -1338,7 +1338,6 @@ fn walkInstruction(
1338 .embed_file,1338 .embed_file,
1339 .error_name,1339 .error_name,
1340 .panic,1340 .panic,
1341 .set_cold, // @check
1342 .set_runtime_safety, // @check1341 .set_runtime_safety, // @check
1343 .sqrt,1342 .sqrt,
1344 .sin,1343 .sin,
src/BuiltinFn.zig+8
...@@ -109,6 +109,7 @@ pub const Tag = enum {...@@ -109,6 +109,7 @@ pub const Tag = enum {
109 sub_with_overflow,109 sub_with_overflow,
110 tag_name,110 tag_name,
111 This,111 This,
112 trap,
112 truncate,113 truncate,
113 Type,114 Type,
114 type_info,115 type_info,
...@@ -915,6 +916,13 @@ pub const list = list: {...@@ -915,6 +916,13 @@ pub const list = list: {
915 .param_count = 0,916 .param_count = 0,
916 },917 },
917 },918 },
919 .{
920 "@trap",
921 .{
922 .tag = .trap,
923 .param_count = 0,
924 },
925 },
918 .{926 .{
919 "@truncate",927 "@truncate",
920 .{928 .{
src/Liveness.zig+2
...@@ -226,6 +226,7 @@ pub fn categorizeOperand(...@@ -226,6 +226,7 @@ pub fn categorizeOperand(
226 .ret_ptr,226 .ret_ptr,
227 .constant,227 .constant,
228 .const_ty,228 .const_ty,
229 .trap,
229 .breakpoint,230 .breakpoint,
230 .dbg_stmt,231 .dbg_stmt,
231 .dbg_inline_begin,232 .dbg_inline_begin,
...@@ -848,6 +849,7 @@ fn analyzeInst(...@@ -848,6 +849,7 @@ fn analyzeInst(
848 .ret_ptr,849 .ret_ptr,
849 .constant,850 .constant,
850 .const_ty,851 .const_ty,
852 .trap,
851 .breakpoint,853 .breakpoint,
852 .dbg_stmt,854 .dbg_stmt,
853 .dbg_inline_begin,855 .dbg_inline_begin,
src/Sema.zig+18-9
...@@ -1101,6 +1101,7 @@ fn analyzeBodyInner(...@@ -1101,6 +1101,7 @@ fn analyzeBodyInner(
1101 .@"unreachable" => break sema.zirUnreachable(block, inst),1101 .@"unreachable" => break sema.zirUnreachable(block, inst),
1102 .panic => break sema.zirPanic(block, inst, false),1102 .panic => break sema.zirPanic(block, inst, false),
1103 .panic_comptime => break sema.zirPanic(block, inst, true),1103 .panic_comptime => break sema.zirPanic(block, inst, true),
1104 .trap => break sema.zirTrap(block, inst),
1104 // zig fmt: on1105 // zig fmt: on
11051106
1106 .extended => ext: {1107 .extended => ext: {
...@@ -1167,6 +1168,11 @@ fn analyzeBodyInner(...@@ -1167,6 +1168,11 @@ fn analyzeBodyInner(
1167 i += 1;1168 i += 1;
1168 continue;1169 continue;
1169 },1170 },
1171 .set_cold => {
1172 try sema.zirSetCold(block, extended);
1173 i += 1;
1174 continue;
1175 },
1170 .breakpoint => {1176 .breakpoint => {
1171 if (!block.is_comptime) {1177 if (!block.is_comptime) {
1172 _ = try block.addNoOp(.breakpoint);1178 _ = try block.addNoOp(.breakpoint);
...@@ -1304,11 +1310,6 @@ fn analyzeBodyInner(...@@ -1304,11 +1310,6 @@ fn analyzeBodyInner(
1304 i += 1;1310 i += 1;
1305 continue;1311 continue;
1306 },1312 },
1307 .set_cold => {
1308 try sema.zirSetCold(block, inst);
1309 i += 1;
1310 continue;
1311 },
1312 .set_runtime_safety => {1313 .set_runtime_safety => {
1313 try sema.zirSetRuntimeSafety(block, inst);1314 try sema.zirSetRuntimeSafety(block, inst);
1314 i += 1;1315 i += 1;
...@@ -5144,6 +5145,14 @@ fn zirPanic(sema: *Sema, block: *Block, inst: Zir.Inst.Index, force_comptime: bo...@@ -5144,6 +5145,14 @@ fn zirPanic(sema: *Sema, block: *Block, inst: Zir.Inst.Index, force_comptime: bo
5144 return always_noreturn;5145 return always_noreturn;
5145}5146}
51465147
5148fn zirTrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index {
5149 const src_node = sema.code.instructions.items(.data)[inst].node;
5150 const src = LazySrcLoc.nodeOffset(src_node);
5151 sema.src = src;
5152 _ = try block.addNoOp(.trap);
5153 return always_noreturn;
5154}
5155
5147fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {5156fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
5148 const tracy = trace(@src());5157 const tracy = trace(@src());
5149 defer tracy.end();5158 defer tracy.end();
...@@ -5721,10 +5730,10 @@ fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst...@@ -5721,10 +5730,10 @@ fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst
5721 gop.value_ptr.* = .{ .alignment = alignment, .src = src };5730 gop.value_ptr.* = .{ .alignment = alignment, .src = src };
5722}5731}
57235732
5724fn zirSetCold(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {5733fn zirSetCold(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
5725 const inst_data = sema.code.instructions.items(.data)[inst].un_node;5734 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
5726 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };5735 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
5727 const is_cold = try sema.resolveConstBool(block, operand_src, inst_data.operand, "operand to @setCold must be comptime-known");5736 const is_cold = try sema.resolveConstBool(block, operand_src, extra.operand, "operand to @setCold must be comptime-known");
5728 const func = sema.func orelse return; // does nothing outside a function5737 const func = sema.func orelse return; // does nothing outside a function
5729 func.is_cold = is_cold;5738 func.is_cold = is_cold;
5730}5739}
src/Zir.zig+13-8
...@@ -617,7 +617,7 @@ pub const Inst = struct {...@@ -617,7 +617,7 @@ pub const Inst = struct {
617 /// Uses the `un_node` field.617 /// Uses the `un_node` field.
618 typeof_log2_int_type,618 typeof_log2_int_type,
619 /// Asserts control-flow will not reach this instruction (`unreachable`).619 /// Asserts control-flow will not reach this instruction (`unreachable`).
620 /// Uses the `unreachable` union field.620 /// Uses the `@"unreachable"` union field.
621 @"unreachable",621 @"unreachable",
622 /// Bitwise XOR. `^`622 /// Bitwise XOR. `^`
623 /// Uses the `pl_node` union field. Payload is `Bin`.623 /// Uses the `pl_node` union field. Payload is `Bin`.
...@@ -808,8 +808,9 @@ pub const Inst = struct {...@@ -808,8 +808,9 @@ pub const Inst = struct {
808 panic,808 panic,
809 /// Same as `panic` but forces comptime.809 /// Same as `panic` but forces comptime.
810 panic_comptime,810 panic_comptime,
811 /// Implement builtin `@setCold`. Uses `un_node`.811 /// Implements `@trap`.
812 set_cold,812 /// Uses the `node` field.
813 trap,
813 /// Implement builtin `@setRuntimeSafety`. Uses `un_node`.814 /// Implement builtin `@setRuntimeSafety`. Uses `un_node`.
814 set_runtime_safety,815 set_runtime_safety,
815 /// Implement builtin `@sqrt`. Uses `un_node`.816 /// Implement builtin `@sqrt`. Uses `un_node`.
...@@ -1187,7 +1188,6 @@ pub const Inst = struct {...@@ -1187,7 +1188,6 @@ pub const Inst = struct {
1187 .bool_to_int,1188 .bool_to_int,
1188 .embed_file,1189 .embed_file,
1189 .error_name,1190 .error_name,
1190 .set_cold,
1191 .set_runtime_safety,1191 .set_runtime_safety,
1192 .sqrt,1192 .sqrt,
1193 .sin,1193 .sin,
...@@ -1277,6 +1277,7 @@ pub const Inst = struct {...@@ -1277,6 +1277,7 @@ pub const Inst = struct {
1277 .repeat_inline,1277 .repeat_inline,
1278 .panic,1278 .panic,
1279 .panic_comptime,1279 .panic_comptime,
1280 .trap,
1280 .check_comptime_control_flow,1281 .check_comptime_control_flow,
1281 => true,1282 => true,
1282 };1283 };
...@@ -1323,7 +1324,6 @@ pub const Inst = struct {...@@ -1323,7 +1324,6 @@ pub const Inst = struct {
1323 .validate_deref,1324 .validate_deref,
1324 .@"export",1325 .@"export",
1325 .export_value,1326 .export_value,
1326 .set_cold,
1327 .set_runtime_safety,1327 .set_runtime_safety,
1328 .memcpy,1328 .memcpy,
1329 .memset,1329 .memset,
...@@ -1553,6 +1553,7 @@ pub const Inst = struct {...@@ -1553,6 +1553,7 @@ pub const Inst = struct {
1553 .repeat_inline,1553 .repeat_inline,
1554 .panic,1554 .panic,
1555 .panic_comptime,1555 .panic_comptime,
1556 .trap,
1556 .for_len,1557 .for_len,
1557 .@"try",1558 .@"try",
1558 .try_ptr,1559 .try_ptr,
...@@ -1561,7 +1562,7 @@ pub const Inst = struct {...@@ -1561,7 +1562,7 @@ pub const Inst = struct {
1561 => false,1562 => false,
15621563
1563 .extended => switch (data.extended.opcode) {1564 .extended => switch (data.extended.opcode) {
1564 .breakpoint, .fence => true,1565 .fence, .set_cold, .breakpoint => true,
1565 else => false,1566 else => false,
1566 },1567 },
1567 };1568 };
...@@ -1750,7 +1751,7 @@ pub const Inst = struct {...@@ -1750,7 +1751,7 @@ pub const Inst = struct {
1750 .error_name = .un_node,1751 .error_name = .un_node,
1751 .panic = .un_node,1752 .panic = .un_node,
1752 .panic_comptime = .un_node,1753 .panic_comptime = .un_node,
1753 .set_cold = .un_node,1754 .trap = .node,
1754 .set_runtime_safety = .un_node,1755 .set_runtime_safety = .un_node,
1755 .sqrt = .un_node,1756 .sqrt = .un_node,
1756 .sin = .un_node,1757 .sin = .un_node,
...@@ -1979,11 +1980,15 @@ pub const Inst = struct {...@@ -1979,11 +1980,15 @@ pub const Inst = struct {
1979 /// Implement builtin `@setAlignStack`.1980 /// Implement builtin `@setAlignStack`.
1980 /// `operand` is payload index to `UnNode`.1981 /// `operand` is payload index to `UnNode`.
1981 set_align_stack,1982 set_align_stack,
1983 /// Implements `@setCold`.
1984 /// `operand` is payload index to `UnNode`.
1985 set_cold,
1982 /// Implements the `@errSetCast` builtin.1986 /// Implements the `@errSetCast` builtin.
1983 /// `operand` is payload index to `BinNode`. `lhs` is dest type, `rhs` is operand.1987 /// `operand` is payload index to `BinNode`. `lhs` is dest type, `rhs` is operand.
1984 err_set_cast,1988 err_set_cast,
1985 /// `operand` is payload index to `UnNode`.1989 /// `operand` is payload index to `UnNode`.
1986 await_nosuspend,1990 await_nosuspend,
1991 /// Implements `@breakpoint`.
1987 /// `operand` is `src_node: i32`.1992 /// `operand` is `src_node: i32`.
1988 breakpoint,1993 breakpoint,
1989 /// Implements the `@select` builtin.1994 /// Implements the `@select` builtin.
...@@ -1997,7 +2002,7 @@ pub const Inst = struct {...@@ -1997,7 +2002,7 @@ pub const Inst = struct {
1997 int_to_error,2002 int_to_error,
1998 /// Implement builtin `@Type`.2003 /// Implement builtin `@Type`.
1999 /// `operand` is payload index to `UnNode`.2004 /// `operand` is payload index to `UnNode`.
2000 /// `small` contains `NameStrategy2005 /// `small` contains `NameStrategy`.
2001 reify,2006 reify,
2002 /// Implements the `@asyncCall` builtin.2007 /// Implements the `@asyncCall` builtin.
2003 /// `operand` is payload index to `AsyncCall`.2008 /// `operand` is payload index to `AsyncCall`.
src/arch/aarch64/CodeGen.zig+10-1
...@@ -733,6 +733,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -733,6 +733,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
733 .bitcast => try self.airBitCast(inst),733 .bitcast => try self.airBitCast(inst),
734 .block => try self.airBlock(inst),734 .block => try self.airBlock(inst),
735 .br => try self.airBr(inst),735 .br => try self.airBr(inst),
736 .trap => try self.airTrap(),
736 .breakpoint => try self.airBreakpoint(),737 .breakpoint => try self.airBreakpoint(),
737 .ret_addr => try self.airRetAddr(inst),738 .ret_addr => try self.airRetAddr(inst),
738 .frame_addr => try self.airFrameAddress(inst),739 .frame_addr => try self.airFrameAddress(inst),
...@@ -4194,10 +4195,18 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {...@@ -4194,10 +4195,18 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
4194 return self.finishAir(inst, result, .{ .none, .none, .none });4195 return self.finishAir(inst, result, .{ .none, .none, .none });
4195}4196}
41964197
4198fn airTrap(self: *Self) !void {
4199 _ = try self.addInst(.{
4200 .tag = .brk,
4201 .data = .{ .imm16 = 0x0001 },
4202 });
4203 return self.finishAirBookkeeping();
4204}
4205
4197fn airBreakpoint(self: *Self) !void {4206fn airBreakpoint(self: *Self) !void {
4198 _ = try self.addInst(.{4207 _ = try self.addInst(.{
4199 .tag = .brk,4208 .tag = .brk,
4200 .data = .{ .imm16 = 1 },4209 .data = .{ .imm16 = 0xf000 },
4201 });4210 });
4202 return self.finishAirBookkeeping();4211 return self.finishAirBookkeeping();
4203}4212}
src/arch/arm/CodeGen.zig+9
...@@ -717,6 +717,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -717,6 +717,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
717 .bitcast => try self.airBitCast(inst),717 .bitcast => try self.airBitCast(inst),
718 .block => try self.airBlock(inst),718 .block => try self.airBlock(inst),
719 .br => try self.airBr(inst),719 .br => try self.airBr(inst),
720 .trap => try self.airTrap(),
720 .breakpoint => try self.airBreakpoint(),721 .breakpoint => try self.airBreakpoint(),
721 .ret_addr => try self.airRetAddr(inst),722 .ret_addr => try self.airRetAddr(inst),
722 .frame_addr => try self.airFrameAddress(inst),723 .frame_addr => try self.airFrameAddress(inst),
...@@ -4142,6 +4143,14 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {...@@ -4142,6 +4143,14 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
4142 return self.finishAir(inst, result, .{ .none, .none, .none });4143 return self.finishAir(inst, result, .{ .none, .none, .none });
4143}4144}
41444145
4146fn airTrap(self: *Self) !void {
4147 _ = try self.addInst(.{
4148 .tag = .undefined_instruction,
4149 .data = .{ .nop = {} },
4150 });
4151 return self.finishAirBookkeeping();
4152}
4153
4145fn airBreakpoint(self: *Self) !void {4154fn airBreakpoint(self: *Self) !void {
4146 _ = try self.addInst(.{4155 _ = try self.addInst(.{
4147 .tag = .bkpt,4156 .tag = .bkpt,
src/arch/arm/Emit.zig+7-2
...@@ -1,4 +1,4 @@...@@ -1,4 +1,4 @@
1//! This file contains the functionality for lowering AArch64 MIR into1//! This file contains the functionality for lowering AArch32 MIR into
2//! machine code2//! machine code
33
4const Emit = @This();4const Emit = @This();
...@@ -15,7 +15,7 @@ const Target = std.Target;...@@ -15,7 +15,7 @@ const Target = std.Target;
15const assert = std.debug.assert;15const assert = std.debug.assert;
16const Instruction = bits.Instruction;16const Instruction = bits.Instruction;
17const Register = bits.Register;17const Register = bits.Register;
18const log = std.log.scoped(.aarch64_emit);18const log = std.log.scoped(.aarch32_emit);
19const DebugInfoOutput = @import("../../codegen.zig").DebugInfoOutput;19const DebugInfoOutput = @import("../../codegen.zig").DebugInfoOutput;
20const CodeGen = @import("CodeGen.zig");20const CodeGen = @import("CodeGen.zig");
2121
...@@ -100,6 +100,7 @@ pub fn emitMir(...@@ -100,6 +100,7 @@ pub fn emitMir(
100100
101 .b => try emit.mirBranch(inst),101 .b => try emit.mirBranch(inst),
102102
103 .undefined_instruction => try emit.mirUndefinedInstruction(),
103 .bkpt => try emit.mirExceptionGeneration(inst),104 .bkpt => try emit.mirExceptionGeneration(inst),
104105
105 .blx => try emit.mirBranchExchange(inst),106 .blx => try emit.mirBranchExchange(inst),
...@@ -494,6 +495,10 @@ fn mirBranch(emit: *Emit, inst: Mir.Inst.Index) !void {...@@ -494,6 +495,10 @@ fn mirBranch(emit: *Emit, inst: Mir.Inst.Index) !void {
494 }495 }
495}496}
496497
498fn mirUndefinedInstruction(emit: *Emit) !void {
499 try emit.writeInstruction(Instruction.undefinedInstruction());
500}
501
497fn mirExceptionGeneration(emit: *Emit, inst: Mir.Inst.Index) !void {502fn mirExceptionGeneration(emit: *Emit, inst: Mir.Inst.Index) !void {
498 const tag = emit.mir.instructions.items(.tag)[inst];503 const tag = emit.mir.instructions.items(.tag)[inst];
499 const imm16 = emit.mir.instructions.items(.data)[inst].imm16;504 const imm16 = emit.mir.instructions.items(.data)[inst].imm16;
src/arch/arm/Mir.zig+2
...@@ -35,6 +35,8 @@ pub const Inst = struct {...@@ -35,6 +35,8 @@ pub const Inst = struct {
35 asr,35 asr,
36 /// Branch36 /// Branch
37 b,37 b,
38 /// Undefined instruction
39 undefined_instruction,
38 /// Breakpoint40 /// Breakpoint
39 bkpt,41 bkpt,
40 /// Branch with Link and Exchange42 /// Branch with Link and Exchange
src/arch/arm/bits.zig+11
...@@ -307,6 +307,9 @@ pub const Instruction = union(enum) {...@@ -307,6 +307,9 @@ pub const Instruction = union(enum) {
307 fixed: u4 = 0b1111,307 fixed: u4 = 0b1111,
308 cond: u4,308 cond: u4,
309 },309 },
310 undefined_instruction: packed struct {
311 imm32: u32 = 0xe7ffdefe,
312 },
310 breakpoint: packed struct {313 breakpoint: packed struct {
311 imm4: u4,314 imm4: u4,
312 fixed_1: u4 = 0b0111,315 fixed_1: u4 = 0b0111,
...@@ -613,6 +616,7 @@ pub const Instruction = union(enum) {...@@ -613,6 +616,7 @@ pub const Instruction = union(enum) {
613 .branch => |v| @bitCast(u32, v),616 .branch => |v| @bitCast(u32, v),
614 .branch_exchange => |v| @bitCast(u32, v),617 .branch_exchange => |v| @bitCast(u32, v),
615 .supervisor_call => |v| @bitCast(u32, v),618 .supervisor_call => |v| @bitCast(u32, v),
619 .undefined_instruction => |v| v.imm32,
616 .breakpoint => |v| @intCast(u32, v.imm4) | (@intCast(u32, v.fixed_1) << 4) | (@intCast(u32, v.imm12) << 8) | (@intCast(u32, v.fixed_2_and_cond) << 20),620 .breakpoint => |v| @intCast(u32, v.imm4) | (@intCast(u32, v.fixed_1) << 4) | (@intCast(u32, v.imm12) << 8) | (@intCast(u32, v.fixed_2_and_cond) << 20),
617 };621 };
618 }622 }
...@@ -890,6 +894,13 @@ pub const Instruction = union(enum) {...@@ -890,6 +894,13 @@ pub const Instruction = union(enum) {
890 };894 };
891 }895 }
892896
897 // This instruction has no official mnemonic equivalent so it is public as-is.
898 pub fn undefinedInstruction() Instruction {
899 return Instruction{
900 .undefined_instruction = .{},
901 };
902 }
903
893 fn breakpoint(imm: u16) Instruction {904 fn breakpoint(imm: u16) Instruction {
894 return Instruction{905 return Instruction{
895 .breakpoint = .{906 .breakpoint = .{
src/arch/riscv64/CodeGen.zig+9
...@@ -547,6 +547,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -547,6 +547,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
547 .bitcast => try self.airBitCast(inst),547 .bitcast => try self.airBitCast(inst),
548 .block => try self.airBlock(inst),548 .block => try self.airBlock(inst),
549 .br => try self.airBr(inst),549 .br => try self.airBr(inst),
550 .trap => try self.airTrap(),
550 .breakpoint => try self.airBreakpoint(),551 .breakpoint => try self.airBreakpoint(),
551 .ret_addr => try self.airRetAddr(inst),552 .ret_addr => try self.airRetAddr(inst),
552 .frame_addr => try self.airFrameAddress(inst),553 .frame_addr => try self.airFrameAddress(inst),
...@@ -1649,6 +1650,14 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {...@@ -1649,6 +1650,14 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
1649 return self.finishAir(inst, mcv, .{ .none, .none, .none });1650 return self.finishAir(inst, mcv, .{ .none, .none, .none });
1650}1651}
16511652
1653fn airTrap(self: *Self) !void {
1654 _ = try self.addInst(.{
1655 .tag = .unimp,
1656 .data = .{ .nop = {} },
1657 });
1658 return self.finishAirBookkeeping();
1659}
1660
1652fn airBreakpoint(self: *Self) !void {1661fn airBreakpoint(self: *Self) !void {
1653 _ = try self.addInst(.{1662 _ = try self.addInst(.{
1654 .tag = .ebreak,1663 .tag = .ebreak,
src/arch/riscv64/Emit.zig+2
...@@ -51,6 +51,7 @@ pub fn emitMir(...@@ -51,6 +51,7 @@ pub fn emitMir(
5151
52 .ebreak => try emit.mirSystem(inst),52 .ebreak => try emit.mirSystem(inst),
53 .ecall => try emit.mirSystem(inst),53 .ecall => try emit.mirSystem(inst),
54 .unimp => try emit.mirSystem(inst),
5455
55 .dbg_line => try emit.mirDbgLine(inst),56 .dbg_line => try emit.mirDbgLine(inst),
5657
...@@ -153,6 +154,7 @@ fn mirSystem(emit: *Emit, inst: Mir.Inst.Index) !void {...@@ -153,6 +154,7 @@ fn mirSystem(emit: *Emit, inst: Mir.Inst.Index) !void {
153 switch (tag) {154 switch (tag) {
154 .ebreak => try emit.writeInstruction(Instruction.ebreak),155 .ebreak => try emit.writeInstruction(Instruction.ebreak),
155 .ecall => try emit.writeInstruction(Instruction.ecall),156 .ecall => try emit.writeInstruction(Instruction.ecall),
157 .unimp => try emit.writeInstruction(Instruction.unimp),
156 else => unreachable,158 else => unreachable,
157 }159 }
158}160}
src/arch/riscv64/Mir.zig+1
...@@ -32,6 +32,7 @@ pub const Inst = struct {...@@ -32,6 +32,7 @@ pub const Inst = struct {
32 dbg_epilogue_begin,32 dbg_epilogue_begin,
33 /// Pseudo-instruction: Update debug line33 /// Pseudo-instruction: Update debug line
34 dbg_line,34 dbg_line,
35 unimp,
35 ebreak,36 ebreak,
36 ecall,37 ecall,
37 jalr,38 jalr,
src/arch/riscv64/bits.zig+1
...@@ -380,6 +380,7 @@ pub const Instruction = union(enum) {...@@ -380,6 +380,7 @@ pub const Instruction = union(enum) {
380380
381 pub const ecall = iType(0b1110011, 0b000, .zero, .zero, 0x000);381 pub const ecall = iType(0b1110011, 0b000, .zero, .zero, 0x000);
382 pub const ebreak = iType(0b1110011, 0b000, .zero, .zero, 0x001);382 pub const ebreak = iType(0b1110011, 0b000, .zero, .zero, 0x001);
383 pub const unimp = iType(0, 0, .zero, .zero, 0);
383};384};
384385
385pub const Register = enum(u6) {386pub const Register = enum(u6) {
src/arch/sparc64/CodeGen.zig+16
...@@ -562,6 +562,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -562,6 +562,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
562 .bitcast => try self.airBitCast(inst),562 .bitcast => try self.airBitCast(inst),
563 .block => try self.airBlock(inst),563 .block => try self.airBlock(inst),
564 .br => try self.airBr(inst),564 .br => try self.airBr(inst),
565 .trap => try self.airTrap(),
565 .breakpoint => try self.airBreakpoint(),566 .breakpoint => try self.airBreakpoint(),
566 .ret_addr => @panic("TODO try self.airRetAddr(inst)"),567 .ret_addr => @panic("TODO try self.airRetAddr(inst)"),
567 .frame_addr => @panic("TODO try self.airFrameAddress(inst)"),568 .frame_addr => @panic("TODO try self.airFrameAddress(inst)"),
...@@ -1156,6 +1157,21 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void {...@@ -1156,6 +1157,21 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void {
1156 return self.finishAir(inst, .dead, .{ branch.operand, .none, .none });1157 return self.finishAir(inst, .dead, .{ branch.operand, .none, .none });
1157}1158}
11581159
1160fn airTrap(self: *Self) !void {
1161 // ta 0x05
1162 _ = try self.addInst(.{
1163 .tag = .tcc,
1164 .data = .{
1165 .trap = .{
1166 .is_imm = true,
1167 .cond = .al,
1168 .rs2_or_imm = .{ .imm = 0x05 },
1169 },
1170 },
1171 });
1172 return self.finishAirBookkeeping();
1173}
1174
1159fn airBreakpoint(self: *Self) !void {1175fn airBreakpoint(self: *Self) !void {
1160 // ta 0x011176 // ta 0x01
1161 _ = try self.addInst(.{1177 _ = try self.addInst(.{
src/arch/wasm/CodeGen.zig+7
...@@ -1827,6 +1827,7 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -1827,6 +1827,7 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
1827 .arg => func.airArg(inst),1827 .arg => func.airArg(inst),
1828 .bitcast => func.airBitcast(inst),1828 .bitcast => func.airBitcast(inst),
1829 .block => func.airBlock(inst),1829 .block => func.airBlock(inst),
1830 .trap => func.airTrap(inst),
1830 .breakpoint => func.airBreakpoint(inst),1831 .breakpoint => func.airBreakpoint(inst),
1831 .br => func.airBr(inst),1832 .br => func.airBr(inst),
1832 .bool_to_int => func.airBoolToInt(inst),1833 .bool_to_int => func.airBoolToInt(inst),
...@@ -3287,9 +3288,15 @@ fn airNot(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3287,9 +3288,15 @@ fn airNot(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3287 func.finishAir(inst, result, &.{ty_op.operand});3288 func.finishAir(inst, result, &.{ty_op.operand});
3288}3289}
32893290
3291fn airTrap(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3292 try func.addTag(.@"unreachable");
3293 func.finishAir(inst, .none, &.{});
3294}
3295
3290fn airBreakpoint(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {3296fn airBreakpoint(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3291 // unsupported by wasm itfunc. Can be implemented once we support DWARF3297 // unsupported by wasm itfunc. Can be implemented once we support DWARF
3292 // for wasm3298 // for wasm
3299 try func.addTag(.@"unreachable");
3293 func.finishAir(inst, .none, &.{});3300 func.finishAir(inst, .none, &.{});
3294}3301}
32953302
src/arch/x86_64/CodeGen.zig+10
...@@ -634,6 +634,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -634,6 +634,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
634 .bitcast => try self.airBitCast(inst),634 .bitcast => try self.airBitCast(inst),
635 .block => try self.airBlock(inst),635 .block => try self.airBlock(inst),
636 .br => try self.airBr(inst),636 .br => try self.airBr(inst),
637 .trap => try self.airTrap(),
637 .breakpoint => try self.airBreakpoint(),638 .breakpoint => try self.airBreakpoint(),
638 .ret_addr => try self.airRetAddr(inst),639 .ret_addr => try self.airRetAddr(inst),
639 .frame_addr => try self.airFrameAddress(inst),640 .frame_addr => try self.airFrameAddress(inst),
...@@ -3913,6 +3914,15 @@ fn genVarDbgInfo(...@@ -3913,6 +3914,15 @@ fn genVarDbgInfo(
3913 }3914 }
3914}3915}
39153916
3917fn airTrap(self: *Self) !void {
3918 _ = try self.addInst(.{
3919 .tag = .ud,
3920 .ops = Mir.Inst.Ops.encode(.{}),
3921 .data = undefined,
3922 });
3923 return self.finishAirBookkeeping();
3924}
3925
3916fn airBreakpoint(self: *Self) !void {3926fn airBreakpoint(self: *Self) !void {
3917 _ = try self.addInst(.{3927 _ = try self.addInst(.{
3918 .tag = .interrupt,3928 .tag = .interrupt,
src/arch/x86_64/Emit.zig+7
...@@ -166,6 +166,7 @@ pub fn lowerMir(emit: *Emit) InnerError!void {...@@ -166,6 +166,7 @@ pub fn lowerMir(emit: *Emit) InnerError!void {
166166
167 .@"test" => try emit.mirTest(inst),167 .@"test" => try emit.mirTest(inst),
168168
169 .ud => try emit.mirUndefinedInstruction(),
169 .interrupt => try emit.mirInterrupt(inst),170 .interrupt => try emit.mirInterrupt(inst),
170 .nop => {}, // just skip it171 .nop => {}, // just skip it
171172
...@@ -234,6 +235,10 @@ fn fixupRelocs(emit: *Emit) InnerError!void {...@@ -234,6 +235,10 @@ fn fixupRelocs(emit: *Emit) InnerError!void {
234 }235 }
235}236}
236237
238fn mirUndefinedInstruction(emit: *Emit) InnerError!void {
239 return lowerToZoEnc(.ud2, emit.code);
240}
241
237fn mirInterrupt(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {242fn mirInterrupt(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
238 const tag = emit.mir.instructions.items(.tag)[inst];243 const tag = emit.mir.instructions.items(.tag)[inst];
239 assert(tag == .interrupt);244 assert(tag == .interrupt);
...@@ -1279,6 +1284,7 @@ const Tag = enum {...@@ -1279,6 +1284,7 @@ const Tag = enum {
1279 push,1284 push,
1280 pop,1285 pop,
1281 @"test",1286 @"test",
1287 ud2,
1282 int3,1288 int3,
1283 nop,1289 nop,
1284 imul,1290 imul,
...@@ -1571,6 +1577,7 @@ inline fn getOpCode(tag: Tag, enc: Encoding, is_one_byte: bool) OpCode {...@@ -1571,6 +1577,7 @@ inline fn getOpCode(tag: Tag, enc: Encoding, is_one_byte: bool) OpCode {
1571 .zo => return switch (tag) {1577 .zo => return switch (tag) {
1572 .ret_near => OpCode.init(&.{0xc3}),1578 .ret_near => OpCode.init(&.{0xc3}),
1573 .ret_far => OpCode.init(&.{0xcb}),1579 .ret_far => OpCode.init(&.{0xcb}),
1580 .ud2 => OpCode.init(&.{ 0x0F, 0x0B }),
1574 .int3 => OpCode.init(&.{0xcc}),1581 .int3 => OpCode.init(&.{0xcc}),
1575 .nop => OpCode.init(&.{0x90}),1582 .nop => OpCode.init(&.{0x90}),
1576 .syscall => OpCode.init(&.{ 0x0f, 0x05 }),1583 .syscall => OpCode.init(&.{ 0x0f, 0x05 }),
src/arch/x86_64/Mir.zig+3
...@@ -329,6 +329,9 @@ pub const Inst = struct {...@@ -329,6 +329,9 @@ pub const Inst = struct {
329 /// TODO handle more cases329 /// TODO handle more cases
330 @"test",330 @"test",
331331
332 /// Undefined Instruction
333 ud,
334
332 /// Breakpoint form:335 /// Breakpoint form:
333 /// 0b00 int3336 /// 0b00 int3
334 interrupt,337 interrupt,
src/codegen/c.zig+6
...@@ -2741,6 +2741,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,...@@ -2741,6 +2741,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,
2741 .const_ty => unreachable, // excluded from function bodies2741 .const_ty => unreachable, // excluded from function bodies
2742 .arg => try airArg(f, inst),2742 .arg => try airArg(f, inst),
27432743
2744 .trap => try airTrap(f.object.writer()),
2744 .breakpoint => try airBreakpoint(f.object.writer()),2745 .breakpoint => try airBreakpoint(f.object.writer()),
2745 .ret_addr => try airRetAddr(f, inst),2746 .ret_addr => try airRetAddr(f, inst),
2746 .frame_addr => try airFrameAddress(f, inst),2747 .frame_addr => try airFrameAddress(f, inst),
...@@ -4428,6 +4429,11 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4428,6 +4429,11 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {
4428 return local;4429 return local;
4429}4430}
44304431
4432fn airTrap(writer: anytype) !CValue {
4433 try writer.writeAll("zig_trap();\n");
4434 return .none;
4435}
4436
4431fn airBreakpoint(writer: anytype) !CValue {4437fn airBreakpoint(writer: anytype) !CValue {
4432 try writer.writeAll("zig_breakpoint();\n");4438 try writer.writeAll("zig_breakpoint();\n");
4433 return .none;4439 return .none;
src/codegen/llvm.zig+8
...@@ -4590,6 +4590,7 @@ pub const FuncGen = struct {...@@ -4590,6 +4590,7 @@ pub const FuncGen = struct {
4590 .block => try self.airBlock(inst),4590 .block => try self.airBlock(inst),
4591 .br => try self.airBr(inst),4591 .br => try self.airBr(inst),
4592 .switch_br => try self.airSwitchBr(inst),4592 .switch_br => try self.airSwitchBr(inst),
4593 .trap => try self.airTrap(inst),
4593 .breakpoint => try self.airBreakpoint(inst),4594 .breakpoint => try self.airBreakpoint(inst),
4594 .ret_addr => try self.airRetAddr(inst),4595 .ret_addr => try self.airRetAddr(inst),
4595 .frame_addr => try self.airFrameAddress(inst),4596 .frame_addr => try self.airFrameAddress(inst),
...@@ -8256,6 +8257,13 @@ pub const FuncGen = struct {...@@ -8256,6 +8257,13 @@ pub const FuncGen = struct {
8256 return fg.load(ptr, ptr_ty);8257 return fg.load(ptr, ptr_ty);
8257 }8258 }
82588259
8260 fn airTrap(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8261 _ = inst;
8262 const llvm_fn = self.getIntrinsic("llvm.trap", &.{});
8263 _ = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, undefined, 0, .Cold, .Auto, "");
8264 return null;
8265 }
8266
8259 fn airBreakpoint(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {8267 fn airBreakpoint(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8260 _ = inst;8268 _ = inst;
8261 const llvm_fn = self.getIntrinsic("llvm.debugtrap", &.{});8269 const llvm_fn = self.getIntrinsic("llvm.debugtrap", &.{});
src/print_air.zig+1
...@@ -194,6 +194,7 @@ const Writer = struct {...@@ -194,6 +194,7 @@ const Writer = struct {
194 .c_va_end,194 .c_va_end,
195 => try w.writeUnOp(s, inst),195 => try w.writeUnOp(s, inst),
196196
197 .trap,
197 .breakpoint,198 .breakpoint,
198 .unreach,199 .unreach,
199 .ret_addr,200 .ret_addr,
src/print_zir.zig+2-1
...@@ -196,7 +196,6 @@ const Writer = struct {...@@ -196,7 +196,6 @@ const Writer = struct {
196 .error_name,196 .error_name,
197 .panic,197 .panic,
198 .panic_comptime,198 .panic_comptime,
199 .set_cold,
200 .set_runtime_safety,199 .set_runtime_safety,
201 .sqrt,200 .sqrt,
202 .sin,201 .sin,
...@@ -411,6 +410,7 @@ const Writer = struct {...@@ -411,6 +410,7 @@ const Writer = struct {
411 .alloc_inferred_comptime_mut,410 .alloc_inferred_comptime_mut,
412 .ret_ptr,411 .ret_ptr,
413 .ret_type,412 .ret_type,
413 .trap,
414 => try self.writeNode(stream, inst),414 => try self.writeNode(stream, inst),
415415
416 .error_value,416 .error_value,
...@@ -503,6 +503,7 @@ const Writer = struct {...@@ -503,6 +503,7 @@ const Writer = struct {
503 .fence,503 .fence,
504 .set_float_mode,504 .set_float_mode,
505 .set_align_stack,505 .set_align_stack,
506 .set_cold,
506 .wasm_memory_size,507 .wasm_memory_size,
507 .error_to_int,508 .error_to_int,
508 .int_to_error,509 .int_to_error,