| ... | @@ -427,8 +427,35 @@ fn encode(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operan | ... | @@ -427,8 +427,35 @@ fn encode(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operan |
| 427 | lower.result_insts_len += 1; | 427 | lower.result_insts_len += 1; |
| 428 | } | 428 | } |
| 429 | | 429 | |
| | 430 | const inst_tags_len = @typeInfo(Mir.Inst.Tag).@"enum".fields.len; |
| | 431 | const inst_fixes_len = @typeInfo(Mir.Inst.Fixes).@"enum".fields.len; |
| | 432 | /// Lookup table, indexed by `@intFromEnum(inst.tag) * inst_fixes_len + @intFromEnum(fixes)`. |
| | 433 | /// The value is the resulting `Mnemonic`, or `null` if the combination is not valid. |
| | 434 | const mnemonic_table: [inst_tags_len * inst_fixes_len]?Mnemonic = table: { |
| | 435 | @setEvalBranchQuota(80_000); |
| | 436 | var table: [inst_tags_len * inst_fixes_len]?Mnemonic = undefined; |
| | 437 | for (0..inst_fixes_len) |fixes_i| { |
| | 438 | const fixes: Mir.Inst.Fixes = @enumFromInt(fixes_i); |
| | 439 | const prefix, const suffix = affix: { |
| | 440 | const pattern = if (std.mem.indexOfScalar(u8, @tagName(fixes), ' ')) |i| |
| | 441 | @tagName(fixes)[i + 1 ..] |
| | 442 | else |
| | 443 | @tagName(fixes); |
| | 444 | const wildcard_idx = std.mem.indexOfScalar(u8, pattern, '_').?; |
| | 445 | break :affix .{ pattern[0..wildcard_idx], pattern[wildcard_idx + 1 ..] }; |
| | 446 | }; |
| | 447 | for (0..inst_tags_len) |inst_tag_i| { |
| | 448 | const inst_tag: Mir.Inst.Tag = @enumFromInt(inst_tag_i); |
| | 449 | const name = prefix ++ @tagName(inst_tag) ++ suffix; |
| | 450 | const idx = inst_tag_i * inst_fixes_len + fixes_i; |
| | 451 | table[idx] = if (@hasField(Mnemonic, name)) @field(Mnemonic, name) else null; |
| | 452 | } |
| | 453 | } |
| | 454 | break :table table; |
| | 455 | }; |
| | 456 | |
| 430 | fn generic(lower: *Lower, inst: Mir.Inst) Error!void { | 457 | fn generic(lower: *Lower, inst: Mir.Inst) Error!void { |
| 431 | @setEvalBranchQuota(2_800); | 458 | @setEvalBranchQuota(2_000); |
| 432 | const fixes = switch (inst.ops) { | 459 | const fixes = switch (inst.ops) { |
| 433 | .none => inst.data.none.fixes, | 460 | .none => inst.data.none.fixes, |
| 434 | .inst => inst.data.inst.fixes, | 461 | .inst => inst.data.inst.fixes, |
| ... | @@ -457,19 +484,18 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void { | ... | @@ -457,19 +484,18 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void { |
| 457 | else | 484 | else |
| 458 | .none, | 485 | .none, |
| 459 | }, mnemonic: { | 486 | }, mnemonic: { |
| 460 | comptime var max_len = 0; | 487 | if (mnemonic_table[@intFromEnum(inst.tag) * inst_fixes_len + @intFromEnum(fixes)]) |mnemonic| { |
| 461 | inline for (@typeInfo(Mnemonic).@"enum".fields) |field| max_len = @max(field.name.len, max_len); | 488 | break :mnemonic mnemonic; |
| 462 | var buf: [max_len]u8 = undefined; | 489 | } |
| 463 | | 490 | // This combination is invalid; make the theoretical mnemonic name and emit an error with it. |
| 464 | const fixes_name = @tagName(fixes); | 491 | const fixes_name = @tagName(fixes); |
| 465 | const pattern = fixes_name[if (std.mem.indexOfScalar(u8, fixes_name, ' ')) |i| i + " ".len else 0..]; | 492 | const pattern = fixes_name[if (std.mem.indexOfScalar(u8, fixes_name, ' ')) |i| i + " ".len else 0..]; |
| 466 | const wildcard_index = std.mem.indexOfScalar(u8, pattern, '_').?; | 493 | const wildcard_index = std.mem.indexOfScalar(u8, pattern, '_').?; |
| 467 | const parts = .{ pattern[0..wildcard_index], @tagName(inst.tag), pattern[wildcard_index + "_".len ..] }; | 494 | return lower.fail("unsupported mnemonic: '{s}{s}{s}'", .{ |
| 468 | const err_msg = "unsupported mnemonic: "; | 495 | pattern[0..wildcard_index], |
| 469 | const mnemonic = std.fmt.bufPrint(&buf, "{s}{s}{s}", parts) catch | 496 | @tagName(inst.tag), |
| 470 | return lower.fail(err_msg ++ "'{s}{s}{s}'", parts); | 497 | pattern[wildcard_index + "_".len ..], |
| 471 | break :mnemonic std.meta.stringToEnum(Mnemonic, mnemonic) orelse | 498 | }); |
| 472 | return lower.fail(err_msg ++ "'{s}'", .{mnemonic}); | | |
| 473 | }, switch (inst.ops) { | 499 | }, switch (inst.ops) { |
| 474 | .none => &.{}, | 500 | .none => &.{}, |
| 475 | .inst => &.{ | 501 | .inst => &.{ |