From 77a0e50298d074f7e30d11116c8172f03877312f Mon Sep 17 00:00:00 2001 From: Arseniy Poroshin Date: Tue, 26 Mar 2024 22:39:43 +0000 Subject: [PATCH 001/129] fix comments in core:container/queue. --- core/container/queue/queue.odin | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/container/queue/queue.odin b/core/container/queue/queue.odin index e46dccb33..e7a60dde0 100644 --- a/core/container/queue/queue.odin +++ b/core/container/queue/queue.odin @@ -189,7 +189,7 @@ pop_front_safe :: proc(q: ^$Q/Queue($T)) -> (elem: T, ok: bool) { return } -// Push multiple elements to the front of the queue +// Push multiple elements to the back of the queue push_back_elems :: proc(q: ^$Q/Queue($T), elems: ..T) -> (ok: bool, err: runtime.Allocator_Error) { n := uint(builtin.len(elems)) if space(q^) < int(n) { @@ -241,7 +241,7 @@ clear :: proc(q: ^$Q/Queue($T)) { } -// Internal growinh procedure +// Internal growing procedure _grow :: proc(q: ^$Q/Queue($T), min_capacity: uint = 0) -> runtime.Allocator_Error { new_capacity := max(min_capacity, uint(8), uint(builtin.len(q.data))*2) n := uint(builtin.len(q.data)) From 805bb69c6c8e3aa275ab42ba6878a7e02653e441 Mon Sep 17 00:00:00 2001 From: Artsiom Babukh Date: Sun, 28 Apr 2024 15:27:34 +0000 Subject: [PATCH 002/129] Fix typo in core_builtin --- base/runtime/core_builtin.odin | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/base/runtime/core_builtin.odin b/base/runtime/core_builtin.odin index 00c30d3fd..7f8c2b91f 100644 --- a/base/runtime/core_builtin.odin +++ b/base/runtime/core_builtin.odin @@ -65,7 +65,7 @@ copy :: proc{copy_slice, copy_from_string} // with the old value, and reducing the length of the dynamic array by 1. // // Note: This is an O(1) operation. -// Note: If you the elements to remain in their order, use `ordered_remove`. +// Note: If you want the elements to remain in their order, use `ordered_remove`. // Note: If the index is out of bounds, this procedure will panic. @builtin unordered_remove :: proc(array: ^$D/[dynamic]$T, index: int, loc := #caller_location) #no_bounds_check { @@ -79,7 +79,7 @@ unordered_remove :: proc(array: ^$D/[dynamic]$T, index: int, loc := #caller_loca // `ordered_remove` removed the element at the specified `index` whilst keeping the order of the other elements. // // Note: This is an O(N) operation. -// Note: If you the elements do not have to remain in their order, prefer `unordered_remove`. +// Note: If the elements do not have to remain in their order, prefer `unordered_remove`. // Note: If the index is out of bounds, this procedure will panic. @builtin ordered_remove :: proc(array: ^$D/[dynamic]$T, index: int, loc := #caller_location) #no_bounds_check { From 2918baa3e860601d0cd5933a6caed237f11acea9 Mon Sep 17 00:00:00 2001 From: Timo Date: Mon, 29 Apr 2024 20:22:53 +0200 Subject: [PATCH 003/129] Update builder.odin Modify documentation-text for procedure write_f64 : change type f32 to f64 --- core/strings/builder.odin | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/strings/builder.odin b/core/strings/builder.odin index 72eb815f9..267feeba1 100644 --- a/core/strings/builder.odin +++ b/core/strings/builder.odin @@ -709,11 +709,11 @@ write_f32 :: proc(b: ^Builder, f: f32, fmt: byte, always_signed := false) -> (n: return write_string(b, s) } /* -Writes a f32 value to the Builder and returns the number of characters written +Writes a f64 value to the Builder and returns the number of characters written Inputs: - b: A pointer to the Builder -- f: The f32 value to be appended +- f: The f64 value to be appended - fmt: The format byte - always_signed: Optional boolean flag to always include the sign From a7a6ff8c693be92929327660fd446dfc0af62e01 Mon Sep 17 00:00:00 2001 From: korvahkh <92224397+korvahkh@users.noreply.github.com> Date: Mon, 27 May 2024 16:59:46 -0500 Subject: [PATCH 004/129] encoding/json: Fix struct marshal() emitting comma after omitted field Previously: ```odin package main import "core:fmt" import "core:encoding/json" T :: struct { a: string `json:",omitempty"`, b: string, } main :: proc() { data, _ := json.marshal(T{b = "foo"}) fmt.println(string(data)) } ``` would output: ``` {,"b":"foo"} ``` which is not correct. Also cleaned up some whitespace while I'm at it. --- core/encoding/json/marshal.odin | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/core/encoding/json/marshal.odin b/core/encoding/json/marshal.odin index 4f5b50ec5..b41a76856 100644 --- a/core/encoding/json/marshal.odin +++ b/core/encoding/json/marshal.odin @@ -25,7 +25,7 @@ Marshal_Options :: struct { spec: Specification, // Use line breaks & tabs/spaces - pretty: bool, + pretty: bool, // Use spaces for indentation instead of tabs use_spaces: bool, @@ -34,7 +34,7 @@ Marshal_Options :: struct { spaces: int, // Output uint as hex in JSON5 & MJSON - write_uint_as_hex: bool, + write_uint_as_hex: bool, // If spec is MJSON and this is true, then keys will be quoted. // @@ -138,7 +138,7 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err: // allow uints to be printed as hex if opt.write_uint_as_hex && (opt.spec == .JSON5 || opt.spec == .MJSON) { switch i in a { - case u8, u16, u32, u64, u128: + case u8, u16, u32, u64, u128: s = strconv.append_bits_128(buf[:], u, 16, info.signed, 8*ti.size, "0123456789abcdef", { .Prefix }) case: @@ -239,7 +239,7 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err: case runtime.Type_Info_Array: opt_write_start(w, opt, '[') or_return for i in 0.. (err: case runtime.Type_Info_Enumerated_Array: opt_write_start(w, opt, '[') or_return for i in 0.. (err: opt_write_start(w, opt, '[') or_return array := cast(^mem.Raw_Dynamic_Array)v.data for i in 0.. (err: opt_write_start(w, opt, '[') or_return slice := cast(^mem.Raw_Slice)v.data for i in 0.. (err: for bucket_index in 0.. (err: slice.sort_by(sorted[:], proc(i, j: Entry) -> bool { return i.key < j.key }) for s, i in sorted { - opt_write_iteration(w, opt, i) or_return + opt_write_iteration(w, opt, i == 0) or_return opt_write_key(w, opt, s.key) or_return marshal_to_writer(w, s.value, opt) or_return } @@ -405,6 +405,7 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err: marshal_struct_fields :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err: Marshal_Error) { ti := runtime.type_info_base(type_info_of(v.id)) info := ti.variant.(runtime.Type_Info_Struct) + first_iteration := true for name, i in info.names { omitempty := false @@ -424,7 +425,8 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err: continue } - opt_write_iteration(w, opt, i) or_return + opt_write_iteration(w, opt, first_iteration) or_return + first_iteration = false if json_name != "" { opt_write_key(w, opt, json_name) or_return } else { @@ -588,10 +590,10 @@ opt_write_start :: proc(w: io.Writer, opt: ^Marshal_Options, c: byte) -> (err: i } // insert comma separation and write indentations -opt_write_iteration :: proc(w: io.Writer, opt: ^Marshal_Options, iteration: int) -> (err: io.Error) { +opt_write_iteration :: proc(w: io.Writer, opt: ^Marshal_Options, first_iteration: bool) -> (err: io.Error) { switch opt.spec { - case .JSON, .JSON5: - if iteration > 0 { + case .JSON, .JSON5: + if !first_iteration { io.write_byte(w, ',') or_return if opt.pretty { @@ -601,8 +603,8 @@ opt_write_iteration :: proc(w: io.Writer, opt: ^Marshal_Options, iteration: int) opt_write_indentation(w, opt) or_return - case .MJSON: - if iteration > 0 { + case .MJSON: + if !first_iteration { // on pretty no commas necessary if opt.pretty { io.write_byte(w, '\n') or_return From ca481dc52d86a6856abba7481bc849a864f0183d Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Fri, 14 Jun 2024 11:51:03 -0400 Subject: [PATCH 005/129] Fix displaying error on wrong line with token at EOL Previously, this would get a token on text like "\n*\n" where `*` is the token's position, and it would advance off that line. --- src/parser.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/parser.cpp b/src/parser.cpp index 0cd96f5b5..468f4749f 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -51,6 +51,12 @@ gb_internal gbString get_file_line_as_string(TokenPos const &pos, i32 *offset_) u8 *line_start = pos_offset; u8 *line_end = pos_offset; + + if (offset > 0 && *line_start == '\n') { + // Prevent an error token that starts at the boundary of a line that + // leads to an empty line from advancing off its line. + line_start -= 1; + } while (line_start >= start) { if (*line_start == '\n') { line_start += 1; From 8626d38db10f134f97ea36d34ceda072a137e779 Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Fri, 14 Jun 2024 13:02:54 -0400 Subject: [PATCH 006/129] Fix displaying emptiness when error is on first line --- src/parser.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/parser.cpp b/src/parser.cpp index 468f4749f..2f764c753 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -64,6 +64,11 @@ gb_internal gbString get_file_line_as_string(TokenPos const &pos, i32 *offset_) } line_start -= 1; } + if (line_start == start - 1) { + // Prevent an error on the first line from stepping behind the boundary + // of the text. + line_start += 1; + } while (line_end < end) { if (*line_end == '\n') { From 582154f20d44ebf724301316e8cf27b1c768b7ee Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Fri, 14 Jun 2024 15:44:50 -0400 Subject: [PATCH 007/129] Remove unused code from tokenizer --- src/tokenizer.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index f7751d840..236bc84a8 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -777,7 +777,6 @@ gb_internal void tokenizer_get_token(Tokenizer *t, Token *token, int repeat=0) { case '`': // Raw String Literal case '"': // String Literal { - bool has_carriage_return = false; i32 success; Rune quote = curr_rune; token->kind = Token_String; @@ -807,9 +806,6 @@ gb_internal void tokenizer_get_token(Tokenizer *t, Token *token, int repeat=0) { if (r == quote) { break; } - if (r == '\r') { - has_carriage_return = true; - } } } token->string.len = t->curr - token->string.text; From d4e2fa037797c026a1b7803f1514a87792af8888 Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Fri, 14 Jun 2024 16:50:28 -0400 Subject: [PATCH 008/129] Refactor `show_error_on_line` This should adequately solve any issues with Unicode alignment by sidestepping the issue entirely. With this change, we make use of the built-in ANSI facilities of the terminal to underline the text. If the terminal does not support underlining, there are still the fallback bold markers at the start and end of error locations. --- src/check_stmt.cpp | 18 +-- src/error.cpp | 328 +++++++++++++++++++++++++++++++++++---------- 2 files changed, 259 insertions(+), 87 deletions(-) diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index f2e3b0242..c369ba098 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -582,28 +582,20 @@ gb_internal Type *check_assignment_variable(CheckerContext *ctx, Operand *lhs, O isize offset = show_error_on_line(e->token.pos, token_pos_end(e->token)); if (offset < 0) { if (is_type_map(e->type)) { - error_line("\tSuggestion: Did you mean? 'for key, &%.*s in ...'\n", LIT(e->token.string)); + error_line("\t\tSuggestion: Did you mean? 'for key, &%.*s in ...'\n", LIT(e->token.string)); } else { - error_line("\tSuggestion: Did you mean? 'for &%.*s in ...'\n", LIT(e->token.string)); + error_line("\t\tSuggestion: Did you mean? 'for &%.*s in ...'\n", LIT(e->token.string)); } } else { - error_line("\t"); - for (isize i = 0; i < offset-1; i++) { - error_line(" "); - } - error_line("'%.*s' is immutable, declare it as '&%.*s' to make it mutable\n", LIT(e->token.string), LIT(e->token.string)); + error_line("\t\t'%.*s' is immutable, declare it as '&%.*s' to make it mutable\n", LIT(e->token.string), LIT(e->token.string)); } } else if (e && e->flags & EntityFlag_SwitchValue) { isize offset = show_error_on_line(e->token.pos, token_pos_end(e->token)); if (offset < 0) { - error_line("\tSuggestion: Did you mean? 'switch &%.*s in ...'\n", LIT(e->token.string)); + error_line("\t\tSuggestion: Did you mean? 'switch &%.*s in ...'\n", LIT(e->token.string)); } else { - error_line("\t"); - for (isize i = 0; i < offset-1; i++) { - error_line(" "); - } - error_line("'%.*s' is immutable, declare it as '&%.*s' to make it mutable\n", LIT(e->token.string), LIT(e->token.string)); + error_line("\t\t'%.*s' is immutable, declare it as '&%.*s' to make it mutable\n", LIT(e->token.string), LIT(e->token.string)); } } } diff --git a/src/error.cpp b/src/error.cpp index 03d96219b..26b4106a0 100644 --- a/src/error.cpp +++ b/src/error.cpp @@ -237,6 +237,7 @@ enum TerminalColour { TerminalColour_Blue, TerminalColour_Purple, TerminalColour_Black, + TerminalColour_Grey, }; gb_internal void terminal_set_colours(TerminalStyle style, TerminalColour foreground) { @@ -256,6 +257,7 @@ gb_internal void terminal_set_colours(TerminalStyle style, TerminalColour foregr case TerminalColour_Blue: error_out("\x1b[%s;34m", ss); break; case TerminalColour_Purple: error_out("\x1b[%s;35m", ss); break; case TerminalColour_Black: error_out("\x1b[%s;30m", ss); break; + case TerminalColour_Grey: error_out("\x1b[%s;90m", ss); break; } } } @@ -272,85 +274,263 @@ gb_internal isize show_error_on_line(TokenPos const &pos, TokenPos end) { return -1; } - i32 offset = 0; - gbString the_line = get_file_line_as_string(pos, &offset); + i32 error_start_index_bytes = 0; + gbString the_line = get_file_line_as_string(pos, &error_start_index_bytes); defer (gb_string_free(the_line)); - if (the_line != nullptr) { - char const *line_text = the_line; - isize line_len = gb_string_length(the_line); - - // TODO(bill): This assumes ASCII - - enum { - MAX_LINE_LENGTH = 80, - MAX_TAB_WIDTH = 8, - ELLIPSIS_PADDING = 8, // `... ...` - MAX_LINE_LENGTH_PADDED = MAX_LINE_LENGTH-MAX_TAB_WIDTH-ELLIPSIS_PADDING, - }; - - i32 error_length = gb_max(end.offset - pos.offset, 1); - - error_out("\t"); - - terminal_set_colours(TerminalStyle_Bold, TerminalColour_White); - - - isize squiggle_extra = 0; - - if (line_len > MAX_LINE_LENGTH_PADDED) { - i32 left = MAX_TAB_WIDTH; - i32 diff = gb_max(offset-left, 0); - if (diff > 0) { - line_text += diff; - line_len -= diff; - offset = left + ELLIPSIS_PADDING/2; - } - if (line_len > MAX_LINE_LENGTH_PADDED) { - line_len = MAX_LINE_LENGTH_PADDED; - if (error_length > line_len-left) { - error_length = cast(i32)line_len - left; - squiggle_extra = 1; - } - } - if (diff > 0) { - error_out("... %.*s ...", cast(i32)line_len, line_text); - } else { - error_out("%.*s ...", cast(i32)line_len, line_text); - } - } else { - error_out("%.*s", cast(i32)line_len, line_text); - } - error_out("\n\t"); - - for (i32 i = 0; i < offset; i++) { - error_out(" "); - } - - terminal_set_colours(TerminalStyle_Bold, TerminalColour_Green); - - error_out("^"); - if (end.file_id == pos.file_id) { - if (end.line > pos.line) { - for (i32 i = offset; i < line_len; i++) { - error_out("~"); - } - } else if (end.line == pos.line && end.column > pos.column) { - for (i32 i = 1; i < error_length-1+squiggle_extra; i++) { - error_out("~"); - } - if (error_length > 1 && squiggle_extra == 0) { - error_out("^"); - } - } - } - + if (the_line == nullptr || gb_string_length(the_line) == 0) { + terminal_set_colours(TerminalStyle_Normal, TerminalColour_Grey); + error_out("\t( empty line )\n"); terminal_reset_colours(); - error_out("\n"); - return offset; + // Preserve the old return behaviour. Even if we can't guarantee the + // exact visual space offset, there are two places that check this to + // change what sort of suggestion they offer. + if (the_line == nullptr) { + return -1; + } else { + return cast(isize)error_start_index_bytes; + } } - return -1; + + // Specfically use basic ASCII arrows here, in case the terminal + // doesn't support anything fancy. This is meant to be a good fallback. + char const *mark_error_sign = "><"; + char const *open_error_sign = ">>"; + char const *close_error_sign = "<<"; + const TerminalColour marker_colour = TerminalColour_Yellow; + + // ANSI SGR: + // 0 = Reset. + // 58:5:2 = Underline colour, 8-bit, green. (non-standard) + // 4:3 = Wiggly underline. (non-standard) + char const *wiggly_underline_sgr = ""; + char const *disable_underline_sgr = ""; + if (has_ansi_terminal_colours()) { + wiggly_underline_sgr = "\x1b[0;58:5:2;4:3m"; + disable_underline_sgr = "\x1b[24m"; + } + + // These two will be used like an Odin slice later. + char const *line_text = the_line; + i32 line_length_bytes = cast(i32)gb_string_length(the_line); + + // NOTE(Feoramund): The numbers below are in Unicode codepoints + // (or runes), not visual glyph width. Calculating the visual width of + // a cluster of Unicode codepoints is vexing, and `utf8proc_charwidth` + // is inadequate. + // + // We're counting codepoints here so we don't slice one down the + // middle during truncation. It will still look strange if we slice + // a cluster down the middle. (i.e. a letter and a combining diacritic) + // + // Luckily, if our assumption about 1 codepoint == 1 glyph is wrong, + // we only suffer a shorter or longer line displayed in total, but all + // of our highlighting and marking will be precise. + // (Unless there's an invalid Unicode codepoint, in which case, no guarantees.) + // + // The line will be longer if a codepoint occupies more than one space + // (CJK in most cases) and shorter if a codepoint is invisible or is + // a type of joiner or combining codepoint. + // + // If we get a complete Unicode glyph counter, it would be as simple as + // replacing `utf8_decode` below to make all of this work perfectly. + + enum { + MAX_LINE_LENGTH = 80, + MAX_TAB_WIDTH = 8, + ELLIPSIS_PADDING = 8, // `... ...` + MAX_MARK_WIDTH = 4, // `><` or `>>` and `<<` + MIN_LEFT_VIEW = 8, + + // A rough estimate of how many characters we'll insert, at most: + MAX_INSERTED_WIDTH = MAX_TAB_WIDTH + ELLIPSIS_PADDING + MAX_MARK_WIDTH, + + MAX_LINE_LENGTH_PADDED = MAX_LINE_LENGTH - MAX_INSERTED_WIDTH, + }; + + // For the purposes of truncating long lines, we calculate how many + // runes the line is composed of, first. We'll take note of at which + // rune index the error starts, too. + i32 error_start_index_runes = 0; + + i32 line_length_runes = 0; + for (i32 i = 0; i < line_length_bytes; /**/) { + Rune rune; + + if (i == error_start_index_bytes) { + error_start_index_runes = line_length_runes; + } + + i32 bytes_read = cast(i32)utf8_decode(cast(const u8 *)line_text + i, line_length_bytes - i, &rune); + if (rune == GB_RUNE_INVALID || bytes_read <= 0) { + // Bail out; we won't even try to truncate the line later. + line_length_runes = 0; + break; + } + + line_length_runes += 1; + i += bytes_read; + } + + if (error_start_index_runes == 0 && error_start_index_bytes != 0 && line_length_runes != 0) { + // The error index in runes was not found, but we did find a valid Unicode string. + // + // This is an edge case where the error is sitting on a newline or the + // end of the line, as that is the only location we could not have checked. + error_start_index_runes = line_length_runes; + } + + error_out("\t"); + + bool show_right_ellipsis = false; + + if (line_length_runes > MAX_LINE_LENGTH_PADDED) { + // Now that we know the line is over the length limit, we have to + // compose a runic window in which to display the error. + i32 window_width = MAX_LINE_LENGTH_PADDED; + + i32 extend_right = 0; + i32 extend_left = 0; + if (error_start_index_runes + window_width > line_length_runes - 1) { + // Trade space from the right to the left. + extend_right = line_length_runes - error_start_index_runes; + extend_left = window_width - extend_right; + } else if (MIN_LEFT_VIEW - error_start_index_runes > 0) { + // Trade space from the left to the right. + extend_left = error_start_index_runes; + extend_right = window_width - extend_left; + } else { + // Square in the middle somewhere. + extend_left = MIN_LEFT_VIEW; + extend_right = window_width - extend_left; + } + + i32 window_right_runes = gb_min(error_start_index_runes + extend_right, line_length_runes); + i32 window_left_runes = gb_max(0, error_start_index_runes - extend_left); + + i32 window_right_bytes = 0; + i32 window_left_bytes = 0; + + i32 i_runes = 0; + for (i32 i = 0; i < line_length_bytes; /**/) { + if (i_runes == window_left_runes ) { window_left_bytes = i; } + if (i_runes == window_right_runes) { window_right_bytes = i; } + + // No need for error-checking. + // + // We've already validated the string at this point, otherwise + // `line_length_runes` would be 0, and we would not have + // entered this block. + i32 bytes_read = cast(i32)utf8_decode(cast(const u8 *)line_text + i, line_length_bytes - i, nullptr); + + i_runes += 1; + i += bytes_read; + } + + if (window_right_bytes == 0) { + // The end of the window is the end of the line. + window_right_bytes = line_length_bytes; + } + + GB_ASSERT_MSG(window_right_runes >= window_left_runes, "Error line truncation window has wrong rune indices. (left, right: %i, %i)", window_left_runes, window_right_runes); + GB_ASSERT_MSG(window_right_bytes >= window_left_bytes, "Error line truncation window has wrong byte indices. (left, right: %i, %i)", window_left_bytes, window_right_bytes); + + if (window_right_bytes != line_length_bytes) { + show_right_ellipsis = true; + } + + // The text will advance; all indices and lengths will become relative. + // We must keep our other iterators in sync. + // NOTE: Uncomment the rune versions if they ever get used beyond this point. + + // Close the window, going left. + line_length_bytes = window_right_bytes; + + // Adjust the slice of text. In Odin, this would be: + // `line_text = line_text[window_left_bytes:]` + line_text += window_left_bytes; + line_length_bytes -= window_left_bytes; + // line_length_runes -= window_left_runes; + GB_ASSERT_MSG(line_length_bytes >= 0, "Bounds-checking error: line_length_bytes"); + + // Part of advancing `line_text`: + error_start_index_bytes -= window_left_bytes; + // error_start_index_runes -= window_left_runes; + GB_ASSERT_MSG(error_start_index_bytes >= 0, "Bounds-checking error: error_start_index_bytes"); + + if (window_left_bytes > 0) { + error_out("... "); + } + } + + // Start printing code. + + terminal_set_colours(TerminalStyle_Normal, TerminalColour_White); + error_out("%.*s", error_start_index_bytes, line_text); + + // Odin-like: `line_text = line_text[error_start_index_bytes:]` + line_text += error_start_index_bytes; + line_length_bytes -= error_start_index_bytes; + GB_ASSERT_MSG(line_length_bytes >= 0, "Bounds-checking error: line_length_bytes"); + + if (end.file_id == pos.file_id) { + // The error has an endpoint. + terminal_set_colours(TerminalStyle_Bold, marker_colour); + error_out(open_error_sign); + + if (end.line > pos.line) { + // Error goes to next line. + error_out(wiggly_underline_sgr); + error_out("%.*s", line_length_bytes, line_text); + + error_out(disable_underline_sgr); + + // Always show the ellipsis in this case + show_right_ellipsis = true; + + } else if (end.line == pos.line && end.column > pos.column) { + // Error terminates before line end. + i32 error_length_bytes = gb_min(end.column - pos.column, line_length_bytes); + + error_out(wiggly_underline_sgr); + error_out("%.*s", error_length_bytes, line_text); + line_text += error_length_bytes; + line_length_bytes -= error_length_bytes; + GB_ASSERT_MSG(line_length_bytes >= 0, "Bounds-checking error: line_length_bytes"); + + error_out(disable_underline_sgr); + + if (!show_right_ellipsis) { + // The line hasn't been truncated; show the end marker. + terminal_set_colours(TerminalStyle_Bold, marker_colour); + error_out(close_error_sign); + } + + terminal_set_colours(TerminalStyle_Normal, TerminalColour_White); + error_out("%.*s", line_length_bytes, line_text); + } + + } else { + // The error is at one spot; no range known. + terminal_set_colours(TerminalStyle_Bold, marker_colour); + error_out(mark_error_sign); + + terminal_set_colours(TerminalStyle_Normal, TerminalColour_White); + error_out("%.*s", line_length_bytes, line_text); + } + + if (show_right_ellipsis) { + error_out(" ..."); + } + + // NOTE(Feoramund): Specifically print a newline, then reset colours, + // instead of the other way around. Otherwise the printing mechanism + // will collapse the newline for reasons currently beyond my ken. + error_out("\n"); + terminal_reset_colours(); + + return error_start_index_bytes; } gb_internal void error_out_empty(void) { From 4dacddd85e07af165df5093e14f3f1a767cf63d1 Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Thu, 20 Jun 2024 22:57:55 -0400 Subject: [PATCH 009/129] Add `core:encoding/uuid` --- core/encoding/uuid/LICENSE | 28 ++++ core/encoding/uuid/definitions.odin | 59 +++++++ core/encoding/uuid/doc.odin | 15 ++ core/encoding/uuid/generation.odin | 159 +++++++++++++++++++ core/encoding/uuid/reading.odin | 97 +++++++++++ core/encoding/uuid/writing.odin | 61 +++++++ examples/all/all_main.odin | 2 + tests/core/encoding/uuid/test_core_uuid.odin | 118 ++++++++++++++ tests/core/normal.odin | 1 + 9 files changed, 540 insertions(+) create mode 100644 core/encoding/uuid/LICENSE create mode 100644 core/encoding/uuid/definitions.odin create mode 100644 core/encoding/uuid/doc.odin create mode 100644 core/encoding/uuid/generation.odin create mode 100644 core/encoding/uuid/reading.odin create mode 100644 core/encoding/uuid/writing.odin create mode 100644 tests/core/encoding/uuid/test_core_uuid.odin diff --git a/core/encoding/uuid/LICENSE b/core/encoding/uuid/LICENSE new file mode 100644 index 000000000..e4e21e62d --- /dev/null +++ b/core/encoding/uuid/LICENSE @@ -0,0 +1,28 @@ +BSD 3-Clause License + +Copyright (c) 2024, Feoramund + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/core/encoding/uuid/definitions.odin b/core/encoding/uuid/definitions.odin new file mode 100644 index 000000000..5bb104cb2 --- /dev/null +++ b/core/encoding/uuid/definitions.odin @@ -0,0 +1,59 @@ +package uuid + +// A RFC 4122 Universally Unique Identifier +Identifier :: struct #raw_union { + integer: u128be, + bytes: [16]u8, +} + +EXPECTED_LENGTH :: 8 + 4 + 4 + 4 + 12 + 4 + +VERSION_BYTE_INDEX :: 6 +VARIANT_BYTE_INDEX :: 8 + +Read_Error :: enum { + None, + Invalid_Length, + Invalid_Hexadecimal, + Invalid_Separator, +} + +Variant_Type :: enum { + Unknown, + Reserved_Apollo_NCS, // 0b0xx + RFC_4122, // 0b10x + Reserved_Microsoft_COM, // 0b110 + Reserved_Future, // 0b111 +} + +// Name string is a URL. +Namespace_DNS := Identifier { + bytes = { + 0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, + 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8, + }, +} + +// Name string is a fully-qualified domain name. +Namespace_URL := Identifier { + bytes = { + 0x6b, 0xa7, 0xb8, 0x11, 0x9d, 0xad, 0x11, 0xd1, + 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8, + }, +} + +// Name string is an ISO OID. +Namespace_OID := Identifier { + bytes = { + 0x6b, 0xa7, 0xb8, 0x12, 0x9d, 0xad, 0x11, 0xd1, + 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8, + }, +} + +// Name string is an X.500 DN (in DER or a text output format). +Namespace_X500 := Identifier { + bytes = { + 0x6b, 0xa7, 0xb8, 0x14, 0x9d, 0xad, 0x11, 0xd1, + 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8, + }, +} diff --git a/core/encoding/uuid/doc.odin b/core/encoding/uuid/doc.odin new file mode 100644 index 000000000..a05698955 --- /dev/null +++ b/core/encoding/uuid/doc.odin @@ -0,0 +1,15 @@ +/* +package uuid implements Universally Unique Identifiers according to the +standard outlined in RFC 4122. + +See here for more information: https://www.rfc-editor.org/rfc/rfc4122.html + +Generation of versions 1 and 2 (the MAC address-based versions) are not yet +implemented. + +The UUIDs are textually represented and read in the following string format: +`00000000-0000-4000-8000-000000000000` + +Outside of string representations, they are represented in memory by a 128-bit structure. +*/ +package uuid diff --git a/core/encoding/uuid/generation.odin b/core/encoding/uuid/generation.odin new file mode 100644 index 000000000..fe05d3ebd --- /dev/null +++ b/core/encoding/uuid/generation.odin @@ -0,0 +1,159 @@ +package uuid + +import "core:crypto/legacy/md5" +import "core:crypto/legacy/sha1" +import "core:math/rand" +import "core:mem" + +/* +Generate a version 3 UUID. + +This UUID is generated from a name within a namespace. +MD5 is used to hash the name with the namespace to produce the UUID. + +Inputs: +- namespace: Another `Identifier` that is used to represent the underlying namespace. + This can be any one of the `Namespace_*` values provided in this package. +- name: The byte slice used to generate the name on top of the namespace. + +Returns: +- result: The generated UUID. +*/ +generate_v3_bytes :: proc( + namespace: Identifier, + name: []byte, +) -> ( + result: Identifier, +) { + namespace := namespace + + ctx: md5.Context + md5.init(&ctx) + md5.update(&ctx, namespace.bytes[:]) + md5.update(&ctx, name) + md5.final(&ctx, result.bytes[:]) + + result.bytes[VERSION_BYTE_INDEX] &= 0x0F + result.bytes[VERSION_BYTE_INDEX] |= 0x30 + + result.bytes[VARIANT_BYTE_INDEX] &= 0x3F + result.bytes[VARIANT_BYTE_INDEX] |= 0x80 + + return +} + +/* +Generate a version 3 UUID. + +This UUID is generated from a name within a namespace. +MD5 is used to hash the name with the namespace to produce the UUID. + +Inputs: +- namespace: Another `Identifier` that is used to represent the underlying namespace. + This can be any one of the `Namespace_*` values provided in this package. +- name: The string used to generate the name on top of the namespace. + +Returns: +- result: The generated UUID. +*/ +generate_v3_string :: proc( + namespace: Identifier, + name: string, +) -> ( + result: Identifier, +) { + return generate_v3_bytes(namespace, transmute([]byte)name) +} + +generate_v3 :: proc { + generate_v3_bytes, + generate_v3_string, +} + +/* +Generate a version 4 UUID. + +This UUID will be pseudorandom, save for 6 pre-determined version and variant bits. + +Returns: +- result: The generated UUID. +*/ +generate_v4 :: proc() -> (result: Identifier) { + result.integer = transmute(u128be)rand.uint128() + + result.bytes[VERSION_BYTE_INDEX] &= 0x0F + result.bytes[VERSION_BYTE_INDEX] |= 0x40 + + result.bytes[VARIANT_BYTE_INDEX] &= 0x3F + result.bytes[VARIANT_BYTE_INDEX] |= 0x80 + + return +} + +/* +Generate a version 5 UUID. + +This UUID is generated from a name within a namespace. +SHA1 is used to hash the name with the namespace to produce the UUID. + +Inputs: +- namespace: Another `Identifier` that is used to represent the underlying namespace. + This can be any one of the `Namespace_*` values provided in this package. +- name: The byte slice used to generate the name on top of the namespace. + +Returns: +- result: The generated UUID. +*/ +generate_v5_bytes :: proc( + namespace: Identifier, + name: []byte, +) -> ( + result: Identifier, +) { + namespace := namespace + digest: [sha1.DIGEST_SIZE]byte + + ctx: sha1.Context + sha1.init(&ctx) + sha1.update(&ctx, namespace.bytes[:]) + sha1.update(&ctx, name) + sha1.final(&ctx, digest[:]) + + mem.copy_non_overlapping(&result.bytes, &digest, 16) + + result.bytes[VERSION_BYTE_INDEX] &= 0x0F + result.bytes[VERSION_BYTE_INDEX] |= 0x50 + + result.bytes[VARIANT_BYTE_INDEX] &= 0x3F + result.bytes[VARIANT_BYTE_INDEX] |= 0x80 + + return +} + +/* +Generate a version 5 UUID. + +This UUID is generated from a name within a namespace. +SHA1 is used to hash the name with the namespace to produce the UUID. + +Inputs: +- namespace: Another `Identifier` that is used to represent the underlying namespace. + This can be any one of the `Namespace_*` values provided in this package. +- name: The string used to generate the name on top of the namespace. + +Returns: +- result: The generated UUID. +*/ +generate_v5_string :: proc( + namespace: Identifier, + name: string, +) -> ( + result: Identifier, +) { + return generate_v5_bytes(namespace, transmute([]byte)name) +} + +generate_v5 :: proc { + generate_v5_bytes, + generate_v5_string, +} diff --git a/core/encoding/uuid/reading.odin b/core/encoding/uuid/reading.odin new file mode 100644 index 000000000..7f3d30ab2 --- /dev/null +++ b/core/encoding/uuid/reading.odin @@ -0,0 +1,97 @@ +package uuid + +/* +Convert a string to a UUID. + +Inputs: +- str: A string in the 8-4-4-4-12 format. + +Returns: +- id: The converted identifier, or `nil` if there is an error. +- error: A description of the error, or `nil` if successful. +*/ +read :: proc "contextless" (str: string) -> (id: Identifier, error: Read_Error) #no_bounds_check { + // Only exact-length strings are acceptable. + if len(str) != EXPECTED_LENGTH { + return {}, .Invalid_Length + } + + // Check ahead to see if the separators are in the right places. + if str[8] != '-' || str[13] != '-' || str[18] != '-' || str[23] != '-' { + return {}, .Invalid_Separator + } + + read_nibble :: proc "contextless" (nibble: u8) -> u8 { + switch nibble { + case '0' ..= '9': + return nibble - '0' + case 'A' ..= 'F': + return nibble - 'A' + 10 + case 'a' ..= 'f': + return nibble - 'a' + 10 + case: + // Return an error value. + return 0xFF + } + } + + index := 0 + octet_index := 0 + + CHUNKS :: [5]int{8, 4, 4, 4, 12} + + for chunk in CHUNKS { + for i := index; i < index + chunk; i += 2 { + high := read_nibble(str[i]) + low := read_nibble(str[i + 1]) + + if high | low > 0xF { + return {}, .Invalid_Hexadecimal + } + + id.bytes[octet_index] = low | high << 4 + octet_index += 1 + } + + index += chunk + 1 + } + + return +} + +/* +Get the version of a UUID. + +Inputs: +- id: The identifier. + +Returns: +- number: The version number. +*/ +version :: proc "contextless" (id: Identifier) -> (number: int) #no_bounds_check { + return cast(int)(id.bytes[VERSION_BYTE_INDEX] & 0xF0 >> 4) +} + +/* +Get the variant of a UUID. + +Inputs: +- id: The identifier. + +Returns: +- variant: The variant type. +*/ +variant :: proc "contextless" (id: Identifier) -> (variant: Variant_Type) #no_bounds_check { + switch { + case id.bytes[VARIANT_BYTE_INDEX] & 0x80 == 0: + return .Reserved_Apollo_NCS + case id.bytes[VARIANT_BYTE_INDEX] & 0xC0 == 0x80: + return .RFC_4122 + case id.bytes[VARIANT_BYTE_INDEX] & 0xE0 == 0xC0: + return .Reserved_Microsoft_COM + case id.bytes[VARIANT_BYTE_INDEX] & 0xF0 == 0xE0: + return .Reserved_Future + case: + return .Unknown + } +} diff --git a/core/encoding/uuid/writing.odin b/core/encoding/uuid/writing.odin new file mode 100644 index 000000000..c13d700a8 --- /dev/null +++ b/core/encoding/uuid/writing.odin @@ -0,0 +1,61 @@ +package uuid + +import "base:runtime" +import "core:io" +import "core:strconv" +import "core:strings" + +/* +Write a UUID in the 8-4-4-4-12 format. + +Inputs: +- w: A writable stream. +- id: The identifier to convert. +*/ +write :: proc(w: io.Writer, id: Identifier) #no_bounds_check { + write_octet :: proc (w: io.Writer, octet: u8) { + high_nibble := octet >> 4 + low_nibble := octet & 0xF + + io.write_byte(w, strconv.digits[high_nibble]) + io.write_byte(w, strconv.digits[low_nibble]) + } + + for index in 0 ..< 4 { write_octet(w, id.bytes[index]) } + io.write_byte(w, '-') + for index in 4 ..< 6 { write_octet(w, id.bytes[index]) } + io.write_byte(w, '-') + for index in 6 ..< 8 { write_octet(w, id.bytes[index]) } + io.write_byte(w, '-') + for index in 8 ..< 10 { write_octet(w, id.bytes[index]) } + io.write_byte(w, '-') + for index in 10 ..< 16 { write_octet(w, id.bytes[index]) } +} + +/* +Convert a UUID to a string in the 8-4-4-4-12 format. + +*Allocates Using Provided Allocator* + +Inputs: +- id: The identifier to convert. +- allocator: (default: context.allocator) +- loc: The caller location for debugging purposes (default: #caller_location) + +Returns: +- str: The allocated and converted string. +- error: An optional allocator error if one occured, `nil` otherwise. +*/ +to_string :: proc( + id: Identifier, + allocator := context.allocator, + loc := #caller_location, +) -> ( + str: string, + error: runtime.Allocator_Error, +) #optional_allocator_error { + buf := make([]byte, EXPECTED_LENGTH, allocator, loc) or_return + builder := strings.builder_from_bytes(buf[:]) + write(strings.to_writer(&builder), id) + return strings.to_string(builder), nil +} diff --git a/examples/all/all_main.odin b/examples/all/all_main.odin index 5202d72be..d39fbe79f 100644 --- a/examples/all/all_main.odin +++ b/examples/all/all_main.odin @@ -62,6 +62,7 @@ import varint "core:encoding/varint" import xml "core:encoding/xml" import endian "core:encoding/endian" import cbor "core:encoding/cbor" +import uuid "core:encoding/uuid" import fmt "core:fmt" import hash "core:hash" @@ -237,6 +238,7 @@ _ :: datetime _ :: flags _ :: sysinfo _ :: unicode +_ :: uuid _ :: utf8 _ :: utf8string _ :: utf16 diff --git a/tests/core/encoding/uuid/test_core_uuid.odin b/tests/core/encoding/uuid/test_core_uuid.odin new file mode 100644 index 000000000..3d1eb1db0 --- /dev/null +++ b/tests/core/encoding/uuid/test_core_uuid.odin @@ -0,0 +1,118 @@ +package test_core_uuid + +import "core:testing" +import "core:encoding/uuid" + +@(test) +test_version_and_variant :: proc(t: ^testing.T) { + v3 := uuid.generate_v3(uuid.Namespace_DNS, "") + v4 := uuid.generate_v4() + v5 := uuid.generate_v5(uuid.Namespace_DNS, "") + + testing.expect_value(t, uuid.version(v3), 3) + testing.expect_value(t, uuid.variant(v3), uuid.Variant_Type.RFC_4122) + testing.expect_value(t, uuid.version(v4), 4) + testing.expect_value(t, uuid.variant(v4), uuid.Variant_Type.RFC_4122) + testing.expect_value(t, uuid.version(v5), 5) + testing.expect_value(t, uuid.variant(v5), uuid.Variant_Type.RFC_4122) +} + +@(test) +test_namespaced_uuids :: proc(t: ^testing.T) { + TEST_NAME :: "0123456789ABCDEF0123456789ABCDEF" + + Expected_Result :: struct { + namespace: uuid.Identifier, + v3, v5: string, + } + + Expected_Results := [?]Expected_Result { + { uuid.Namespace_DNS, "80147f37-36db-3b82-b78f-810c3c6504ba", "18394c41-13a2-593f-abf2-a63e163c2860" }, + { uuid.Namespace_URL, "8136789b-8e16-3fbd-800b-1587e2f22521", "07337422-eb77-5fd3-99af-c7f59e641e13" }, + { uuid.Namespace_OID, "adbb95bc-ea50-3226-9a75-20c34a6030f8", "24db9b0f-70b8-53c4-a301-f695ce17276d" }, + { uuid.Namespace_X500, "a8965ad1-0e54-3d65-b933-8b7cca8e8313", "3012bf2d-fac4-5187-9825-493e6636b936" }, + } + + for exp in Expected_Results { + v3 := uuid.generate_v3(exp.namespace, TEST_NAME) + v5 := uuid.generate_v5(exp.namespace, TEST_NAME) + + v3_str := uuid.to_string(v3) + defer delete(v3_str) + + v5_str := uuid.to_string(v5) + defer delete(v5_str) + + testing.expect_value(t, v3_str, exp.v3) + testing.expect_value(t, v5_str, exp.v5) + } +} + +@(test) +test_writing :: proc(t: ^testing.T) { + id: uuid.Identifier + + for &b, i in id.bytes { + b = u8(i) + } + + s := uuid.to_string(id) + defer delete(s) + + testing.expect_value(t, s, "00010203-0405-0607-0809-0a0b0c0d0e0f") +} + +@(test) +test_reading :: proc(t: ^testing.T) { + id, err := uuid.read("00010203-0405-0607-0809-0a0b0c0d0e0f") + testing.expect_value(t, err, nil) + + for b, i in id.bytes { + testing.expect_value(t, b, u8(i)) + } +} + +@(test) +test_reading_errors :: proc(t: ^testing.T) { + { + BAD_STRING :: "|.......@....@....@....@............" + _, err := uuid.read(BAD_STRING) + testing.expect_value(t, err, uuid.Read_Error.Invalid_Separator) + } + + { + BAD_STRING :: "|.......-....-....-....-............" + _, err := uuid.read(BAD_STRING) + testing.expect_value(t, err, uuid.Read_Error.Invalid_Hexadecimal) + } + + { + BAD_STRING :: ".......-....-....-....-............" + _, err := uuid.read(BAD_STRING) + testing.expect_value(t, err, uuid.Read_Error.Invalid_Length) + } + + { + BAD_STRING :: "|.......-....-....-....-............|" + _, err := uuid.read(BAD_STRING) + testing.expect_value(t, err, uuid.Read_Error.Invalid_Length) + } + + { + BAD_STRING :: "00000000-0000-0000-0000-0000000000001" + _, err := uuid.read(BAD_STRING) + testing.expect_value(t, err, uuid.Read_Error.Invalid_Length) + } + + { + BAD_STRING :: "00000000000000000000000000000000" + _, err := uuid.read(BAD_STRING) + testing.expect_value(t, err, uuid.Read_Error.Invalid_Length) + } + + { + OK_STRING :: "00000000-0000-0000-0000-000000000000" + _, err := uuid.read(OK_STRING) + testing.expect_value(t, err, nil) + } +} diff --git a/tests/core/normal.odin b/tests/core/normal.odin index a84420cca..065090be3 100644 --- a/tests/core/normal.odin +++ b/tests/core/normal.odin @@ -17,6 +17,7 @@ download_assets :: proc() { @(require) import "encoding/hex" @(require) import "encoding/hxa" @(require) import "encoding/json" +@(require) import "encoding/uuid" @(require) import "encoding/varint" @(require) import "encoding/xml" @(require) import "flags" From 31873ed46625823bae8d7f9b1883597ea1e1c351 Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Fri, 21 Jun 2024 09:44:39 -0400 Subject: [PATCH 010/129] Fix wrong comments --- core/encoding/uuid/definitions.odin | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/encoding/uuid/definitions.odin b/core/encoding/uuid/definitions.odin index 5bb104cb2..a1862a3fd 100644 --- a/core/encoding/uuid/definitions.odin +++ b/core/encoding/uuid/definitions.odin @@ -26,7 +26,7 @@ Variant_Type :: enum { Reserved_Future, // 0b111 } -// Name string is a URL. +// Name string is a fully-qualified domain name. Namespace_DNS := Identifier { bytes = { 0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, @@ -34,7 +34,7 @@ Namespace_DNS := Identifier { }, } -// Name string is a fully-qualified domain name. +// Name string is a URL. Namespace_URL := Identifier { bytes = { 0x6b, 0xa7, 0xb8, 0x11, 0x9d, 0xad, 0x11, 0xd1, From 6da99b888a4974fbdd2fcb7d04f12342fc1c8bb2 Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Fri, 21 Jun 2024 09:56:41 -0400 Subject: [PATCH 011/129] Make UUID `Identfier` only a distinct byte array --- core/encoding/uuid/definitions.odin | 29 +++++----------- core/encoding/uuid/generation.odin | 35 ++++++++++---------- core/encoding/uuid/reading.odin | 12 +++---- core/encoding/uuid/writing.odin | 10 +++--- tests/core/encoding/uuid/test_core_uuid.odin | 4 +-- 5 files changed, 40 insertions(+), 50 deletions(-) diff --git a/core/encoding/uuid/definitions.odin b/core/encoding/uuid/definitions.odin index a1862a3fd..a5cbf9c38 100644 --- a/core/encoding/uuid/definitions.odin +++ b/core/encoding/uuid/definitions.odin @@ -1,10 +1,7 @@ package uuid // A RFC 4122 Universally Unique Identifier -Identifier :: struct #raw_union { - integer: u128be, - bytes: [16]u8, -} +Identifier :: distinct [16]u8 EXPECTED_LENGTH :: 8 + 4 + 4 + 4 + 12 + 4 @@ -28,32 +25,24 @@ Variant_Type :: enum { // Name string is a fully-qualified domain name. Namespace_DNS := Identifier { - bytes = { - 0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, - 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8, - }, + 0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, + 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8, } // Name string is a URL. Namespace_URL := Identifier { - bytes = { - 0x6b, 0xa7, 0xb8, 0x11, 0x9d, 0xad, 0x11, 0xd1, - 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8, - }, + 0x6b, 0xa7, 0xb8, 0x11, 0x9d, 0xad, 0x11, 0xd1, + 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8, } // Name string is an ISO OID. Namespace_OID := Identifier { - bytes = { - 0x6b, 0xa7, 0xb8, 0x12, 0x9d, 0xad, 0x11, 0xd1, - 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8, - }, + 0x6b, 0xa7, 0xb8, 0x12, 0x9d, 0xad, 0x11, 0xd1, + 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8, } // Name string is an X.500 DN (in DER or a text output format). Namespace_X500 := Identifier { - bytes = { - 0x6b, 0xa7, 0xb8, 0x14, 0x9d, 0xad, 0x11, 0xd1, - 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8, - }, + 0x6b, 0xa7, 0xb8, 0x14, 0x9d, 0xad, 0x11, 0xd1, + 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8, } diff --git a/core/encoding/uuid/generation.odin b/core/encoding/uuid/generation.odin index fe05d3ebd..9b790714c 100644 --- a/core/encoding/uuid/generation.odin +++ b/core/encoding/uuid/generation.odin @@ -29,15 +29,15 @@ generate_v3_bytes :: proc( ctx: md5.Context md5.init(&ctx) - md5.update(&ctx, namespace.bytes[:]) + md5.update(&ctx, namespace[:]) md5.update(&ctx, name) - md5.final(&ctx, result.bytes[:]) + md5.final(&ctx, result[:]) - result.bytes[VERSION_BYTE_INDEX] &= 0x0F - result.bytes[VERSION_BYTE_INDEX] |= 0x30 + result[VERSION_BYTE_INDEX] &= 0x0F + result[VERSION_BYTE_INDEX] |= 0x30 - result.bytes[VARIANT_BYTE_INDEX] &= 0x3F - result.bytes[VARIANT_BYTE_INDEX] |= 0x80 + result[VARIANT_BYTE_INDEX] &= 0x3F + result[VARIANT_BYTE_INDEX] |= 0x80 return } @@ -79,13 +79,14 @@ Returns: - result: The generated UUID. */ generate_v4 :: proc() -> (result: Identifier) { - result.integer = transmute(u128be)rand.uint128() + bytes_generated := rand.read(result[:]) + assert(bytes_generated == 16, "RNG failed to generate 16 bytes for UUID v4.") - result.bytes[VERSION_BYTE_INDEX] &= 0x0F - result.bytes[VERSION_BYTE_INDEX] |= 0x40 + result[VERSION_BYTE_INDEX] &= 0x0F + result[VERSION_BYTE_INDEX] |= 0x40 - result.bytes[VARIANT_BYTE_INDEX] &= 0x3F - result.bytes[VARIANT_BYTE_INDEX] |= 0x80 + result[VARIANT_BYTE_INDEX] &= 0x3F + result[VARIANT_BYTE_INDEX] |= 0x80 return } @@ -115,17 +116,17 @@ generate_v5_bytes :: proc( ctx: sha1.Context sha1.init(&ctx) - sha1.update(&ctx, namespace.bytes[:]) + sha1.update(&ctx, namespace[:]) sha1.update(&ctx, name) sha1.final(&ctx, digest[:]) - mem.copy_non_overlapping(&result.bytes, &digest, 16) + mem.copy_non_overlapping(&result, &digest, 16) - result.bytes[VERSION_BYTE_INDEX] &= 0x0F - result.bytes[VERSION_BYTE_INDEX] |= 0x50 + result[VERSION_BYTE_INDEX] &= 0x0F + result[VERSION_BYTE_INDEX] |= 0x50 - result.bytes[VARIANT_BYTE_INDEX] &= 0x3F - result.bytes[VARIANT_BYTE_INDEX] |= 0x80 + result[VARIANT_BYTE_INDEX] &= 0x3F + result[VARIANT_BYTE_INDEX] |= 0x80 return } diff --git a/core/encoding/uuid/reading.odin b/core/encoding/uuid/reading.odin index 7f3d30ab2..0c0274e53 100644 --- a/core/encoding/uuid/reading.odin +++ b/core/encoding/uuid/reading.odin @@ -49,7 +49,7 @@ read :: proc "contextless" (str: string) -> (id: Identifier, error: Read_Error) return {}, .Invalid_Hexadecimal } - id.bytes[octet_index] = low | high << 4 + id[octet_index] = low | high << 4 octet_index += 1 } @@ -69,7 +69,7 @@ Returns: - number: The version number. */ version :: proc "contextless" (id: Identifier) -> (number: int) #no_bounds_check { - return cast(int)(id.bytes[VERSION_BYTE_INDEX] & 0xF0 >> 4) + return cast(int)(id[VERSION_BYTE_INDEX] & 0xF0 >> 4) } /* @@ -83,13 +83,13 @@ Returns: */ variant :: proc "contextless" (id: Identifier) -> (variant: Variant_Type) #no_bounds_check { switch { - case id.bytes[VARIANT_BYTE_INDEX] & 0x80 == 0: + case id[VARIANT_BYTE_INDEX] & 0x80 == 0: return .Reserved_Apollo_NCS - case id.bytes[VARIANT_BYTE_INDEX] & 0xC0 == 0x80: + case id[VARIANT_BYTE_INDEX] & 0xC0 == 0x80: return .RFC_4122 - case id.bytes[VARIANT_BYTE_INDEX] & 0xE0 == 0xC0: + case id[VARIANT_BYTE_INDEX] & 0xE0 == 0xC0: return .Reserved_Microsoft_COM - case id.bytes[VARIANT_BYTE_INDEX] & 0xF0 == 0xE0: + case id[VARIANT_BYTE_INDEX] & 0xF0 == 0xE0: return .Reserved_Future case: return .Unknown diff --git a/core/encoding/uuid/writing.odin b/core/encoding/uuid/writing.odin index c13d700a8..45096e84f 100644 --- a/core/encoding/uuid/writing.odin +++ b/core/encoding/uuid/writing.odin @@ -21,15 +21,15 @@ write :: proc(w: io.Writer, id: Identifier) #no_bounds_check { io.write_byte(w, strconv.digits[low_nibble]) } - for index in 0 ..< 4 { write_octet(w, id.bytes[index]) } + for index in 0 ..< 4 { write_octet(w, id[index]) } io.write_byte(w, '-') - for index in 4 ..< 6 { write_octet(w, id.bytes[index]) } + for index in 4 ..< 6 { write_octet(w, id[index]) } io.write_byte(w, '-') - for index in 6 ..< 8 { write_octet(w, id.bytes[index]) } + for index in 6 ..< 8 { write_octet(w, id[index]) } io.write_byte(w, '-') - for index in 8 ..< 10 { write_octet(w, id.bytes[index]) } + for index in 8 ..< 10 { write_octet(w, id[index]) } io.write_byte(w, '-') - for index in 10 ..< 16 { write_octet(w, id.bytes[index]) } + for index in 10 ..< 16 { write_octet(w, id[index]) } } /* diff --git a/tests/core/encoding/uuid/test_core_uuid.odin b/tests/core/encoding/uuid/test_core_uuid.odin index 3d1eb1db0..717c5599d 100644 --- a/tests/core/encoding/uuid/test_core_uuid.odin +++ b/tests/core/encoding/uuid/test_core_uuid.odin @@ -52,7 +52,7 @@ test_namespaced_uuids :: proc(t: ^testing.T) { test_writing :: proc(t: ^testing.T) { id: uuid.Identifier - for &b, i in id.bytes { + for &b, i in id { b = u8(i) } @@ -67,7 +67,7 @@ test_reading :: proc(t: ^testing.T) { id, err := uuid.read("00010203-0405-0607-0809-0a0b0c0d0e0f") testing.expect_value(t, err, nil) - for b, i in id.bytes { + for b, i in id { testing.expect_value(t, b, u8(i)) } } From fee81985b4b7ade3cddc7038360efcd32555d879 Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Fri, 21 Jun 2024 09:59:57 -0400 Subject: [PATCH 012/129] Make UUID namespaces `@(rodata)` --- core/encoding/uuid/definitions.odin | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/encoding/uuid/definitions.odin b/core/encoding/uuid/definitions.odin index a5cbf9c38..1208e26f4 100644 --- a/core/encoding/uuid/definitions.odin +++ b/core/encoding/uuid/definitions.odin @@ -24,24 +24,28 @@ Variant_Type :: enum { } // Name string is a fully-qualified domain name. +@(rodata) Namespace_DNS := Identifier { 0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8, } // Name string is a URL. +@(rodata) Namespace_URL := Identifier { 0x6b, 0xa7, 0xb8, 0x11, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8, } // Name string is an ISO OID. +@(rodata) Namespace_OID := Identifier { 0x6b, 0xa7, 0xb8, 0x12, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8, } // Name string is an X.500 DN (in DER or a text output format). +@(rodata) Namespace_X500 := Identifier { 0x6b, 0xa7, 0xb8, 0x14, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8, From 4cfbd83b10ff17b6c7ca4b01dac249bfbea0da84 Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Fri, 21 Jun 2024 12:04:45 -0400 Subject: [PATCH 013/129] Add version 7 UUID generation --- core/encoding/uuid/definitions.odin | 5 ++ core/encoding/uuid/generation.odin | 84 ++++++++++++++++++++ core/encoding/uuid/reading.odin | 31 ++++++++ tests/core/encoding/uuid/test_core_uuid.odin | 32 +++++++- 4 files changed, 151 insertions(+), 1 deletion(-) diff --git a/core/encoding/uuid/definitions.odin b/core/encoding/uuid/definitions.odin index 1208e26f4..b54965e23 100644 --- a/core/encoding/uuid/definitions.odin +++ b/core/encoding/uuid/definitions.odin @@ -8,6 +8,11 @@ EXPECTED_LENGTH :: 8 + 4 + 4 + 4 + 12 + 4 VERSION_BYTE_INDEX :: 6 VARIANT_BYTE_INDEX :: 8 +VERSION_7_TIME_MASK :: 0xffffffff_ffff0000_00000000_00000000 +VERSION_7_TIME_SHIFT :: 80 +VERSION_7_COUNTER_MASK :: 0x00000000_00000fff_00000000_00000000 +VERSION_7_COUNTER_SHIFT :: 64 + Read_Error :: enum { None, Invalid_Length, diff --git a/core/encoding/uuid/generation.odin b/core/encoding/uuid/generation.odin index 9b790714c..7fe0bbd13 100644 --- a/core/encoding/uuid/generation.odin +++ b/core/encoding/uuid/generation.odin @@ -4,6 +4,7 @@ import "core:crypto/legacy/md5" import "core:crypto/legacy/sha1" import "core:math/rand" import "core:mem" +import "core:time" /* Generate a version 3 UUID. @@ -158,3 +159,86 @@ generate_v5 :: proc { generate_v5_bytes, generate_v5_string, } + +/* +Generate a version 7 UUID. + +This UUID will be pseudorandom, save for 6 pre-determined version and variant +bits and a 48 bit timestamp. + +It is designed with time-based sorting in mind, such as for database usage, as +the highest bits are allocated from the timestamp of when it is created. + +Returns: +- result: The generated UUID. +*/ +generate_v7 :: proc() -> (result: Identifier) { + unix_time_in_milliseconds := time.to_unix_nanoseconds(time.now()) / 1e6 + + temporary := cast(u128be)unix_time_in_milliseconds << VERSION_7_TIME_SHIFT + + bytes_generated := rand.read(result[6:]) + assert(bytes_generated == 10, "RNG failed to generate 10 bytes for UUID v7.") + + result |= transmute(Identifier)temporary + + result[VERSION_BYTE_INDEX] &= 0x0F + result[VERSION_BYTE_INDEX] |= 0x70 + + result[VARIANT_BYTE_INDEX] &= 0x3F + result[VARIANT_BYTE_INDEX] |= 0x80 + + return +} + +/* +Generate a version 7 UUID with an incremented counter. + +This UUID will be pseudorandom, save for 6 pre-determined version and variant +bits, a 48 bit timestamp, and 12 bits of counter state. + +It is designed with time-based sorting in mind, such as for database usage, as +the highest bits are allocated from the timestamp of when it is created. + +This procedure is preferable if you are generating hundreds or thousands of +UUIDs as a batch within the span of a millisecond. Do note that the counter +only has 12 bits of state, thus `counter` cannot exceed the number 4,095. + +Example: + + import "core:uuid" + + // Create a batch of UUIDs all at once. + batch: [dynamic]uuid.Identifier + + for i: u16 = 0; i < 1000; i += 1 { + my_uuid := uuid.generate_v7_counter(i) + append(&batch, my_uuid) + } + +Inputs: +- counter: A 12-bit value, incremented each time a UUID is generated in a batch. + +Returns: +- result: The generated UUID. +*/ +generate_v7_counter :: proc(counter: u16) -> (result: Identifier) { + assert(counter <= 0x0fff, "This implementation of the version 7 UUID does not support counters in excess of 12 bits (4,095).") + unix_time_in_milliseconds := time.to_unix_nanoseconds(time.now()) / 1e6 + + temporary := cast(u128be)unix_time_in_milliseconds << VERSION_7_TIME_SHIFT + temporary |= cast(u128be)counter << VERSION_7_COUNTER_SHIFT + + bytes_generated := rand.read(result[8:]) + assert(bytes_generated == 8, "RNG failed to generate 8 bytes for UUID v7.") + + result |= transmute(Identifier)temporary + + result[VERSION_BYTE_INDEX] &= 0x0F + result[VERSION_BYTE_INDEX] |= 0x70 + + result[VARIANT_BYTE_INDEX] &= 0x3F + result[VARIANT_BYTE_INDEX] |= 0x80 + + return +} diff --git a/core/encoding/uuid/reading.odin b/core/encoding/uuid/reading.odin index 0c0274e53..c72f5791e 100644 --- a/core/encoding/uuid/reading.odin +++ b/core/encoding/uuid/reading.odin @@ -95,3 +95,34 @@ variant :: proc "contextless" (id: Identifier) -> (variant: Variant_Type) #no_bo return .Unknown } } + +/* +Get the timestamp of a version 7 UUID. + +Inputs: +- id: The identifier. + +Returns: +- timestamp: The timestamp, in milliseconds since the UNIX epoch. +*/ +time_v7 :: proc "contextless" (id: Identifier) -> (timestamp: u64) { + time_bits := transmute(u128be)id & VERSION_7_TIME_MASK + return cast(u64)(time_bits >> VERSION_7_TIME_SHIFT) +} + +/* +Get the 12-bit counter value of a version 7 UUID. + +The UUID must have been generated with a counter, otherwise this procedure will +return random bits. + +Inputs: +- id: The identifier. + +Returns: +- counter: The 12-bit counter value. +*/ +counter_v7 :: proc "contextless" (id: Identifier) -> (counter: u16) { + counter_bits := transmute(u128be)id & VERSION_7_COUNTER_MASK + return cast(u16)(counter_bits >> VERSION_7_COUNTER_SHIFT) +} diff --git a/tests/core/encoding/uuid/test_core_uuid.odin b/tests/core/encoding/uuid/test_core_uuid.odin index 717c5599d..b5e8e90cc 100644 --- a/tests/core/encoding/uuid/test_core_uuid.odin +++ b/tests/core/encoding/uuid/test_core_uuid.odin @@ -1,13 +1,16 @@ package test_core_uuid -import "core:testing" import "core:encoding/uuid" +import "core:log" +import "core:testing" +import "core:time" @(test) test_version_and_variant :: proc(t: ^testing.T) { v3 := uuid.generate_v3(uuid.Namespace_DNS, "") v4 := uuid.generate_v4() v5 := uuid.generate_v5(uuid.Namespace_DNS, "") + v7 := uuid.generate_v7() testing.expect_value(t, uuid.version(v3), 3) testing.expect_value(t, uuid.variant(v3), uuid.Variant_Type.RFC_4122) @@ -15,6 +18,8 @@ test_version_and_variant :: proc(t: ^testing.T) { testing.expect_value(t, uuid.variant(v4), uuid.Variant_Type.RFC_4122) testing.expect_value(t, uuid.version(v5), 5) testing.expect_value(t, uuid.variant(v5), uuid.Variant_Type.RFC_4122) + testing.expect_value(t, uuid.version(v7), 7) + testing.expect_value(t, uuid.variant(v7), uuid.Variant_Type.RFC_4122) } @(test) @@ -48,6 +53,31 @@ test_namespaced_uuids :: proc(t: ^testing.T) { } } +@(test) +test_v7 :: proc(t: ^testing.T) { + v7_a := uuid.generate_v7() + time.sleep(10 * time.Millisecond) + v7_b := uuid.generate_v7() + time.sleep(10 * time.Millisecond) + v7_c := uuid.generate_v7() + + time_bits_a := uuid.time_v7(v7_a) + time_bits_b := uuid.time_v7(v7_b) + time_bits_c := uuid.time_v7(v7_c) + + log.debugf("A: %02x, %i", v7_a, time_bits_a) + log.debugf("B: %02x, %i", v7_b, time_bits_b) + log.debugf("C: %02x, %i", v7_c, time_bits_c) + + testing.expect(t, time_bits_b > time_bits_a, "The time bits on the later-generated v7 UUID are lesser than the earlier UUID.") + testing.expect(t, time_bits_c > time_bits_b, "The time bits on the later-generated v7 UUID are lesser than the earlier UUID.") + testing.expect(t, time_bits_c > time_bits_a, "The time bits on the later-generated v7 UUID are lesser than the earlier UUID.") + + v7_with_counter := uuid.generate_v7_counter(0x555) + log.debugf("D: %02x", v7_with_counter) + testing.expect_value(t, uuid.counter_v7(v7_with_counter), 0x555) +} + @(test) test_writing :: proc(t: ^testing.T) { id: uuid.Identifier From 525bfca4ef53916ca99f0c5cd4a1371ba6756c95 Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Fri, 21 Jun 2024 17:55:27 -0400 Subject: [PATCH 014/129] Add version 1 UUID generation --- core/encoding/uuid/definitions.odin | 3 ++ core/encoding/uuid/generation.odin | 44 ++++++++++++++++ core/encoding/uuid/reading.odin | 55 ++++++++++++++++++++ tests/core/encoding/uuid/test_core_uuid.odin | 31 +++++++++++ 4 files changed, 133 insertions(+) diff --git a/core/encoding/uuid/definitions.odin b/core/encoding/uuid/definitions.odin index b54965e23..a63e72693 100644 --- a/core/encoding/uuid/definitions.odin +++ b/core/encoding/uuid/definitions.odin @@ -8,6 +8,9 @@ EXPECTED_LENGTH :: 8 + 4 + 4 + 4 + 12 + 4 VERSION_BYTE_INDEX :: 6 VARIANT_BYTE_INDEX :: 8 +// The number of 100-nanosecond intervals between 1582-10-15 and 1970-01-01. +HNS_INTERVALS_BETWEEN_GREG_AND_UNIX :: 141427 * 24 * 60 * 60 * 1000 * 1000 * 10 + VERSION_7_TIME_MASK :: 0xffffffff_ffff0000_00000000_00000000 VERSION_7_TIME_SHIFT :: 80 VERSION_7_COUNTER_MASK :: 0x00000000_00000fff_00000000_00000000 diff --git a/core/encoding/uuid/generation.odin b/core/encoding/uuid/generation.odin index 7fe0bbd13..29944dcb5 100644 --- a/core/encoding/uuid/generation.odin +++ b/core/encoding/uuid/generation.odin @@ -6,6 +6,50 @@ import "core:math/rand" import "core:mem" import "core:time" +/* +Generate a version 1 UUID. + +Inputs: +- clock_seq: The clock sequence, a number which must be initialized to a random number once in the lifetime of a system. +- node: An optional 48-bit spatially unique identifier, specified to be the IEEE 802 address of the system. + If one is not provided or available, 48 bits of random state will take its place. + +Returns: +- result: The generated UUID. +*/ +generate_v1 :: proc(clock_seq: u16, node: Maybe([6]u8) = nil) -> (result: Identifier) { + assert(clock_seq <= 0x3FFF, "The clock sequence can only hold 14 bits of data; no number greater than 16,383.") + unix_time_in_hns_intervals := time.to_unix_nanoseconds(time.now()) / 100 + timestamp := cast(u64le)(HNS_INTERVALS_BETWEEN_GREG_AND_UNIX + unix_time_in_hns_intervals) + timestamp_octets := transmute([8]u8)timestamp + + result[0] = timestamp_octets[0] + result[1] = timestamp_octets[1] + result[2] = timestamp_octets[2] + result[3] = timestamp_octets[3] + result[4] = timestamp_octets[4] + result[5] = timestamp_octets[5] + + result[6] = timestamp_octets[6] >> 4 + result[7] = timestamp_octets[6] << 4 | timestamp_octets[7] + + if realized_node, ok := node.?; ok { + mutable_node := realized_node + mem.copy_non_overlapping(&result[10], &mutable_node[0], 6) + } else { + bytes_generated := rand.read(result[10:]) + assert(bytes_generated == 6, "RNG failed to generate 6 bytes for UUID v1.") + } + + result[VERSION_BYTE_INDEX] |= 0x10 + result[VARIANT_BYTE_INDEX] |= 0x80 + + result[8] |= cast(u8)(clock_seq & 0x3F00 >> 8) + result[9] = cast(u8)clock_seq + + return +} + /* Generate a version 3 UUID. diff --git a/core/encoding/uuid/reading.odin b/core/encoding/uuid/reading.odin index c72f5791e..f31ae2bcd 100644 --- a/core/encoding/uuid/reading.odin +++ b/core/encoding/uuid/reading.odin @@ -1,5 +1,7 @@ package uuid +import "base:runtime" + /* Convert a string to a UUID. @@ -96,6 +98,59 @@ variant :: proc "contextless" (id: Identifier) -> (variant: Variant_Type) #no_bo } } +/* +Get the clock sequence of a version 1 UUID. + +Inputs: +- id: The identifier. + +Returns: +- clock_seq: The 14-bit clock sequence field. +*/ +clock_seq :: proc "contextless" (id: Identifier) -> (clock_seq: u16) { + return cast(u16)id[9] | cast(u16)id[8] & 0x3F << 8 +} + +/* +Get the node of a version 1 UUID. + +Inputs: +- id: The identifier. + +Returns: +- node: The 48-bit spatially unique identifier. +*/ +node :: proc "contextless" (id: Identifier) -> (node: [6]u8) { + mutable_id := id + runtime.mem_copy_non_overlapping(&node, &mutable_id[10], 6) + return +} + +/* +Get the timestamp of a version 1 UUID. + +Inputs: +- id: The identifier. + +Returns: +- timestamp: The timestamp, in 100-nanosecond intervals since 1582-10-15. +*/ +time_v1 :: proc "contextless" (id: Identifier) -> (timestamp: u64) { + timestamp_octets: [8]u8 + + timestamp_octets[0] = id[0] + timestamp_octets[1] = id[1] + timestamp_octets[2] = id[2] + timestamp_octets[3] = id[3] + timestamp_octets[4] = id[4] + timestamp_octets[5] = id[5] + + timestamp_octets[6] = id[6] << 4 | id[7] >> 4 + timestamp_octets[7] = id[7] & 0xF + + return cast(u64)transmute(u64le)timestamp_octets +} + /* Get the timestamp of a version 7 UUID. diff --git a/tests/core/encoding/uuid/test_core_uuid.odin b/tests/core/encoding/uuid/test_core_uuid.odin index b5e8e90cc..f934d13dc 100644 --- a/tests/core/encoding/uuid/test_core_uuid.odin +++ b/tests/core/encoding/uuid/test_core_uuid.odin @@ -7,11 +7,14 @@ import "core:time" @(test) test_version_and_variant :: proc(t: ^testing.T) { + v1 := uuid.generate_v1(0) v3 := uuid.generate_v3(uuid.Namespace_DNS, "") v4 := uuid.generate_v4() v5 := uuid.generate_v5(uuid.Namespace_DNS, "") v7 := uuid.generate_v7() + testing.expect_value(t, uuid.version(v1), 1) + testing.expect_value(t, uuid.variant(v1), uuid.Variant_Type.RFC_4122) testing.expect_value(t, uuid.version(v3), 3) testing.expect_value(t, uuid.variant(v3), uuid.Variant_Type.RFC_4122) testing.expect_value(t, uuid.version(v4), 4) @@ -53,6 +56,34 @@ test_namespaced_uuids :: proc(t: ^testing.T) { } } +@(test) +test_v1 :: proc(t: ^testing.T) { + CLOCK :: 0x3A1A + v1_a := uuid.generate_v1(CLOCK) + time.sleep(10 * time.Millisecond) + v1_b := uuid.generate_v1(CLOCK) + time.sleep(10 * time.Millisecond) + v1_c := uuid.generate_v1(CLOCK) + + testing.expect_value(t, uuid.clock_seq(v1_a), CLOCK) + + time_bits_a := uuid.time_v1(v1_a) + time_bits_b := uuid.time_v1(v1_b) + time_bits_c := uuid.time_v1(v1_c) + + time_a := time.Time { _nsec = cast(i64)((time_bits_a - uuid.HNS_INTERVALS_BETWEEN_GREG_AND_UNIX) * 100) } + time_b := time.Time { _nsec = cast(i64)((time_bits_b - uuid.HNS_INTERVALS_BETWEEN_GREG_AND_UNIX) * 100) } + time_c := time.Time { _nsec = cast(i64)((time_bits_c - uuid.HNS_INTERVALS_BETWEEN_GREG_AND_UNIX) * 100) } + + log.debugf("A: %02x, %i, %v", v1_a, time_bits_a, time_a) + log.debugf("B: %02x, %i, %v", v1_b, time_bits_b, time_b) + log.debugf("C: %02x, %i, %v", v1_c, time_bits_c, time_c) + + testing.expect(t, time_bits_b > time_bits_a, "The time bits on the later-generated v1 UUID are lesser than the earlier UUID.") + testing.expect(t, time_bits_c > time_bits_b, "The time bits on the later-generated v1 UUID are lesser than the earlier UUID.") + testing.expect(t, time_bits_c > time_bits_a, "The time bits on the later-generated v1 UUID are lesser than the earlier UUID.") +} + @(test) test_v7 :: proc(t: ^testing.T) { v7_a := uuid.generate_v7() From 9866b54d59721d62137f2a8279f015aeef0f7a4f Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Sat, 22 Jun 2024 12:54:39 -0400 Subject: [PATCH 015/129] Add version 6 UUID generation --- core/encoding/uuid/generation.odin | 46 ++++++++++++++++++++ core/encoding/uuid/reading.odin | 20 ++++++++- tests/core/encoding/uuid/test_core_uuid.odin | 31 +++++++++++++ 3 files changed, 96 insertions(+), 1 deletion(-) diff --git a/core/encoding/uuid/generation.odin b/core/encoding/uuid/generation.odin index 29944dcb5..08fd84c0c 100644 --- a/core/encoding/uuid/generation.odin +++ b/core/encoding/uuid/generation.odin @@ -204,6 +204,52 @@ generate_v5 :: proc { generate_v5_string, } +/* +Generate a version 6 UUID. + +Inputs: +- clock_seq: The clock sequence from version 1, now made optional. + If unspecified, it will be replaced with random bits. +- node: An optional 48-bit spatially unique identifier, specified to be the IEEE 802 address of the system. + If one is not provided or available, 48 bits of random state will take its place. + +Returns: +- result: The generated UUID. +*/ +generate_v6 :: proc(clock_seq: Maybe(u16) = nil, node: Maybe([6]u8) = nil) -> (result: Identifier) { + unix_time_in_hns_intervals := time.to_unix_nanoseconds(time.now()) / 100 + + timestamp := cast(u128be)(HNS_INTERVALS_BETWEEN_GREG_AND_UNIX + unix_time_in_hns_intervals) + + result |= transmute(Identifier)(timestamp & 0x0FFFFFFF_FFFFF000 << 68) + result |= transmute(Identifier)(timestamp & 0x00000000_00000FFF << 64) + + if realized_clock_seq, ok := clock_seq.?; ok { + assert(realized_clock_seq <= 0x3FFF, "The clock sequence can only hold 14 bits of data, therefore no number greater than 16,383.") + result[8] |= cast(u8)(realized_clock_seq & 0x3F00 >> 8) + result[9] = cast(u8)realized_clock_seq + } else { + temporary: [2]u8 + bytes_generated := rand.read(temporary[:]) + assert(bytes_generated == 2, "RNG failed to generate 2 bytes for UUID v1.") + result[8] |= cast(u8)temporary[0] & 0x3F + result[9] = cast(u8)temporary[1] + } + + if realized_node, ok := node.?; ok { + mutable_node := realized_node + mem.copy_non_overlapping(&result[10], &mutable_node[0], 6) + } else { + bytes_generated := rand.read(result[10:]) + assert(bytes_generated == 6, "RNG failed to generate 6 bytes for UUID v1.") + } + + result[VERSION_BYTE_INDEX] |= 0x60 + result[VARIANT_BYTE_INDEX] |= 0x80 + + return +} + /* Generate a version 7 UUID. diff --git a/core/encoding/uuid/reading.odin b/core/encoding/uuid/reading.odin index f31ae2bcd..3b2c48011 100644 --- a/core/encoding/uuid/reading.odin +++ b/core/encoding/uuid/reading.odin @@ -99,7 +99,7 @@ variant :: proc "contextless" (id: Identifier) -> (variant: Variant_Type) #no_bo } /* -Get the clock sequence of a version 1 UUID. +Get the clock sequence of a version 1 or version 6 UUID. Inputs: - id: The identifier. @@ -151,6 +151,24 @@ time_v1 :: proc "contextless" (id: Identifier) -> (timestamp: u64) { return cast(u64)transmute(u64le)timestamp_octets } +/* +Get the timestamp of a version 6 UUID. + +Inputs: +- id: The identifier. + +Returns: +- timestamp: The timestamp, in 100-nanosecond intervals since 1582-10-15. +*/ +time_v6 :: proc "contextless" (id: Identifier) -> (timestamp: u64) { + temporary := transmute(u128be)id + + timestamp |= cast(u64)(temporary & 0xFFFFFFFF_FFFF0000_00000000_00000000 >> 68) + timestamp |= cast(u64)(temporary & 0x00000000_00000FFF_00000000_00000000 >> 64) + + return timestamp +} + /* Get the timestamp of a version 7 UUID. diff --git a/tests/core/encoding/uuid/test_core_uuid.odin b/tests/core/encoding/uuid/test_core_uuid.odin index f934d13dc..90e299143 100644 --- a/tests/core/encoding/uuid/test_core_uuid.odin +++ b/tests/core/encoding/uuid/test_core_uuid.odin @@ -11,6 +11,7 @@ test_version_and_variant :: proc(t: ^testing.T) { v3 := uuid.generate_v3(uuid.Namespace_DNS, "") v4 := uuid.generate_v4() v5 := uuid.generate_v5(uuid.Namespace_DNS, "") + v6 := uuid.generate_v6() v7 := uuid.generate_v7() testing.expect_value(t, uuid.version(v1), 1) @@ -21,6 +22,8 @@ test_version_and_variant :: proc(t: ^testing.T) { testing.expect_value(t, uuid.variant(v4), uuid.Variant_Type.RFC_4122) testing.expect_value(t, uuid.version(v5), 5) testing.expect_value(t, uuid.variant(v5), uuid.Variant_Type.RFC_4122) + testing.expect_value(t, uuid.version(v6), 6) + testing.expect_value(t, uuid.variant(v6), uuid.Variant_Type.RFC_4122) testing.expect_value(t, uuid.version(v7), 7) testing.expect_value(t, uuid.variant(v7), uuid.Variant_Type.RFC_4122) } @@ -84,6 +87,34 @@ test_v1 :: proc(t: ^testing.T) { testing.expect(t, time_bits_c > time_bits_a, "The time bits on the later-generated v1 UUID are lesser than the earlier UUID.") } +@(test) +test_v6 :: proc(t: ^testing.T) { + CLOCK :: 0x3A1A + v6_a := uuid.generate_v6(CLOCK) + time.sleep(10 * time.Millisecond) + v6_b := uuid.generate_v6(CLOCK) + time.sleep(10 * time.Millisecond) + v6_c := uuid.generate_v6(CLOCK) + + testing.expect_value(t, uuid.clock_seq(v6_a), CLOCK) + + time_bits_a := uuid.time_v6(v6_a) + time_bits_b := uuid.time_v6(v6_b) + time_bits_c := uuid.time_v6(v6_c) + + time_a := time.Time { _nsec = cast(i64)((time_bits_a - uuid.HNS_INTERVALS_BETWEEN_GREG_AND_UNIX) * 100) } + time_b := time.Time { _nsec = cast(i64)((time_bits_b - uuid.HNS_INTERVALS_BETWEEN_GREG_AND_UNIX) * 100) } + time_c := time.Time { _nsec = cast(i64)((time_bits_c - uuid.HNS_INTERVALS_BETWEEN_GREG_AND_UNIX) * 100) } + + log.debugf("A: %02x, %i, %v", v6_a, time_bits_a, time_a) + log.debugf("B: %02x, %i, %v", v6_b, time_bits_b, time_b) + log.debugf("C: %02x, %i, %v", v6_c, time_bits_c, time_c) + + testing.expect(t, time_bits_b > time_bits_a, "The time bits on the later-generated v6 UUID are lesser than the earlier UUID.") + testing.expect(t, time_bits_c > time_bits_b, "The time bits on the later-generated v6 UUID are lesser than the earlier UUID.") + testing.expect(t, time_bits_c > time_bits_a, "The time bits on the later-generated v6 UUID are lesser than the earlier UUID.") +} + @(test) test_v7 :: proc(t: ^testing.T) { v7_a := uuid.generate_v7() From 3aa232a894340ea13d2fc57090c8ad149f5c482a Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Sat, 22 Jun 2024 13:04:21 -0400 Subject: [PATCH 016/129] Move v3 and v5 UUID procs to `uuid/legacy` --- core/encoding/uuid/generation.odin | 135 ----------------- core/encoding/uuid/legacy/legacy.odin | 150 +++++++++++++++++++ examples/all/all_main.odin | 2 + tests/core/encoding/uuid/test_core_uuid.odin | 11 +- 4 files changed, 158 insertions(+), 140 deletions(-) create mode 100644 core/encoding/uuid/legacy/legacy.odin diff --git a/core/encoding/uuid/generation.odin b/core/encoding/uuid/generation.odin index 08fd84c0c..2ca5d0e5f 100644 --- a/core/encoding/uuid/generation.odin +++ b/core/encoding/uuid/generation.odin @@ -1,7 +1,5 @@ package uuid -import "core:crypto/legacy/md5" -import "core:crypto/legacy/sha1" import "core:math/rand" import "core:mem" import "core:time" @@ -50,71 +48,6 @@ generate_v1 :: proc(clock_seq: u16, node: Maybe([6]u8) = nil) -> (result: Identi return } -/* -Generate a version 3 UUID. - -This UUID is generated from a name within a namespace. -MD5 is used to hash the name with the namespace to produce the UUID. - -Inputs: -- namespace: Another `Identifier` that is used to represent the underlying namespace. - This can be any one of the `Namespace_*` values provided in this package. -- name: The byte slice used to generate the name on top of the namespace. - -Returns: -- result: The generated UUID. -*/ -generate_v3_bytes :: proc( - namespace: Identifier, - name: []byte, -) -> ( - result: Identifier, -) { - namespace := namespace - - ctx: md5.Context - md5.init(&ctx) - md5.update(&ctx, namespace[:]) - md5.update(&ctx, name) - md5.final(&ctx, result[:]) - - result[VERSION_BYTE_INDEX] &= 0x0F - result[VERSION_BYTE_INDEX] |= 0x30 - - result[VARIANT_BYTE_INDEX] &= 0x3F - result[VARIANT_BYTE_INDEX] |= 0x80 - - return -} - -/* -Generate a version 3 UUID. - -This UUID is generated from a name within a namespace. -MD5 is used to hash the name with the namespace to produce the UUID. - -Inputs: -- namespace: Another `Identifier` that is used to represent the underlying namespace. - This can be any one of the `Namespace_*` values provided in this package. -- name: The string used to generate the name on top of the namespace. - -Returns: -- result: The generated UUID. -*/ -generate_v3_string :: proc( - namespace: Identifier, - name: string, -) -> ( - result: Identifier, -) { - return generate_v3_bytes(namespace, transmute([]byte)name) -} - -generate_v3 :: proc { - generate_v3_bytes, - generate_v3_string, -} - /* Generate a version 4 UUID. @@ -136,74 +69,6 @@ generate_v4 :: proc() -> (result: Identifier) { return } -/* -Generate a version 5 UUID. - -This UUID is generated from a name within a namespace. -SHA1 is used to hash the name with the namespace to produce the UUID. - -Inputs: -- namespace: Another `Identifier` that is used to represent the underlying namespace. - This can be any one of the `Namespace_*` values provided in this package. -- name: The byte slice used to generate the name on top of the namespace. - -Returns: -- result: The generated UUID. -*/ -generate_v5_bytes :: proc( - namespace: Identifier, - name: []byte, -) -> ( - result: Identifier, -) { - namespace := namespace - digest: [sha1.DIGEST_SIZE]byte - - ctx: sha1.Context - sha1.init(&ctx) - sha1.update(&ctx, namespace[:]) - sha1.update(&ctx, name) - sha1.final(&ctx, digest[:]) - - mem.copy_non_overlapping(&result, &digest, 16) - - result[VERSION_BYTE_INDEX] &= 0x0F - result[VERSION_BYTE_INDEX] |= 0x50 - - result[VARIANT_BYTE_INDEX] &= 0x3F - result[VARIANT_BYTE_INDEX] |= 0x80 - - return -} - -/* -Generate a version 5 UUID. - -This UUID is generated from a name within a namespace. -SHA1 is used to hash the name with the namespace to produce the UUID. - -Inputs: -- namespace: Another `Identifier` that is used to represent the underlying namespace. - This can be any one of the `Namespace_*` values provided in this package. -- name: The string used to generate the name on top of the namespace. - -Returns: -- result: The generated UUID. -*/ -generate_v5_string :: proc( - namespace: Identifier, - name: string, -) -> ( - result: Identifier, -) { - return generate_v5_bytes(namespace, transmute([]byte)name) -} - -generate_v5 :: proc { - generate_v5_bytes, - generate_v5_string, -} - /* Generate a version 6 UUID. diff --git a/core/encoding/uuid/legacy/legacy.odin b/core/encoding/uuid/legacy/legacy.odin new file mode 100644 index 000000000..44057f1f8 --- /dev/null +++ b/core/encoding/uuid/legacy/legacy.odin @@ -0,0 +1,150 @@ +/* +package uuid/legacy implements versions 3 and 5 of UUID generation, both of +which are using hashing algorithms (MD5 and SHA1, respectively) that are known +these days to no longer be secure. +*/ +package uuid_legacy + +import "base:runtime" +import "core:crypto/legacy/md5" +import "core:crypto/legacy/sha1" +import "core:encoding/uuid" + +Identifier :: uuid.Identifier +VERSION_BYTE_INDEX :: uuid.VERSION_BYTE_INDEX +VARIANT_BYTE_INDEX :: uuid.VARIANT_BYTE_INDEX + + +/* +Generate a version 3 UUID. + +This UUID is generated from a name within a namespace. +MD5 is used to hash the name with the namespace to produce the UUID. + +Inputs: +- namespace: Another `Identifier` that is used to represent the underlying namespace. + This can be any one of the `Namespace_*` values provided in the `uuid` package. +- name: The byte slice used to generate the name on top of the namespace. + +Returns: +- result: The generated UUID. +*/ +generate_v3_bytes :: proc( + namespace: Identifier, + name: []byte, +) -> ( + result: Identifier, +) { + namespace := namespace + + ctx: md5.Context + md5.init(&ctx) + md5.update(&ctx, namespace[:]) + md5.update(&ctx, name) + md5.final(&ctx, result[:]) + + result[VERSION_BYTE_INDEX] &= 0x0F + result[VERSION_BYTE_INDEX] |= 0x30 + + result[VARIANT_BYTE_INDEX] &= 0x3F + result[VARIANT_BYTE_INDEX] |= 0x80 + + return +} + +/* +Generate a version 3 UUID. + +This UUID is generated from a name within a namespace. +MD5 is used to hash the name with the namespace to produce the UUID. + +Inputs: +- namespace: Another `Identifier` that is used to represent the underlying namespace. + This can be any one of the `Namespace_*` values provided in the `uuid` package. +- name: The string used to generate the name on top of the namespace. + +Returns: +- result: The generated UUID. +*/ +generate_v3_string :: proc( + namespace: Identifier, + name: string, +) -> ( + result: Identifier, +) { + return generate_v3_bytes(namespace, transmute([]byte)name) +} + +generate_v3 :: proc { + generate_v3_bytes, + generate_v3_string, +} + +/* +Generate a version 5 UUID. + +This UUID is generated from a name within a namespace. +SHA1 is used to hash the name with the namespace to produce the UUID. + +Inputs: +- namespace: Another `Identifier` that is used to represent the underlying namespace. + This can be any one of the `Namespace_*` values provided in the `uuid` package. +- name: The byte slice used to generate the name on top of the namespace. + +Returns: +- result: The generated UUID. +*/ +generate_v5_bytes :: proc( + namespace: Identifier, + name: []byte, +) -> ( + result: Identifier, +) { + namespace := namespace + digest: [sha1.DIGEST_SIZE]byte + + ctx: sha1.Context + sha1.init(&ctx) + sha1.update(&ctx, namespace[:]) + sha1.update(&ctx, name) + sha1.final(&ctx, digest[:]) + + runtime.mem_copy_non_overlapping(&result, &digest, 16) + + result[VERSION_BYTE_INDEX] &= 0x0F + result[VERSION_BYTE_INDEX] |= 0x50 + + result[VARIANT_BYTE_INDEX] &= 0x3F + result[VARIANT_BYTE_INDEX] |= 0x80 + + return +} + +/* +Generate a version 5 UUID. + +This UUID is generated from a name within a namespace. +SHA1 is used to hash the name with the namespace to produce the UUID. + +Inputs: +- namespace: Another `Identifier` that is used to represent the underlying namespace. + This can be any one of the `Namespace_*` values provided in the `uuid` package. +- name: The string used to generate the name on top of the namespace. + +Returns: +- result: The generated UUID. +*/ +generate_v5_string :: proc( + namespace: Identifier, + name: string, +) -> ( + result: Identifier, +) { + return generate_v5_bytes(namespace, transmute([]byte)name) +} + +generate_v5 :: proc { + generate_v5_bytes, + generate_v5_string, +} + diff --git a/examples/all/all_main.odin b/examples/all/all_main.odin index d39fbe79f..9c0d28a91 100644 --- a/examples/all/all_main.odin +++ b/examples/all/all_main.odin @@ -63,6 +63,7 @@ import xml "core:encoding/xml" import endian "core:encoding/endian" import cbor "core:encoding/cbor" import uuid "core:encoding/uuid" +import uuid_legacy "core:encoding/uuid/legacy" import fmt "core:fmt" import hash "core:hash" @@ -239,6 +240,7 @@ _ :: flags _ :: sysinfo _ :: unicode _ :: uuid +_ :: uuid_legacy _ :: utf8 _ :: utf8string _ :: utf16 diff --git a/tests/core/encoding/uuid/test_core_uuid.odin b/tests/core/encoding/uuid/test_core_uuid.odin index 90e299143..fc2615fe0 100644 --- a/tests/core/encoding/uuid/test_core_uuid.odin +++ b/tests/core/encoding/uuid/test_core_uuid.odin @@ -1,6 +1,7 @@ package test_core_uuid import "core:encoding/uuid" +import uuid_legacy "core:encoding/uuid/legacy" import "core:log" import "core:testing" import "core:time" @@ -8,9 +9,9 @@ import "core:time" @(test) test_version_and_variant :: proc(t: ^testing.T) { v1 := uuid.generate_v1(0) - v3 := uuid.generate_v3(uuid.Namespace_DNS, "") + v3 := uuid_legacy.generate_v3(uuid.Namespace_DNS, "") v4 := uuid.generate_v4() - v5 := uuid.generate_v5(uuid.Namespace_DNS, "") + v5 := uuid_legacy.generate_v5(uuid.Namespace_DNS, "") v6 := uuid.generate_v6() v7 := uuid.generate_v7() @@ -29,7 +30,7 @@ test_version_and_variant :: proc(t: ^testing.T) { } @(test) -test_namespaced_uuids :: proc(t: ^testing.T) { +test_legacy_namespaced_uuids :: proc(t: ^testing.T) { TEST_NAME :: "0123456789ABCDEF0123456789ABCDEF" Expected_Result :: struct { @@ -45,8 +46,8 @@ test_namespaced_uuids :: proc(t: ^testing.T) { } for exp in Expected_Results { - v3 := uuid.generate_v3(exp.namespace, TEST_NAME) - v5 := uuid.generate_v5(exp.namespace, TEST_NAME) + v3 := uuid_legacy.generate_v3(exp.namespace, TEST_NAME) + v5 := uuid_legacy.generate_v5(exp.namespace, TEST_NAME) v3_str := uuid.to_string(v3) defer delete(v3_str) From fcdba334ea764edb5fe1e325cc5527e9495a6f55 Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Sat, 22 Jun 2024 13:21:48 -0400 Subject: [PATCH 017/129] Require CSPRNG in UUID generation where applicable --- core/encoding/uuid/definitions.odin | 3 +++ core/encoding/uuid/generation.odin | 12 +++++++++--- tests/core/encoding/uuid/test_core_uuid.odin | 9 +++++++++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/core/encoding/uuid/definitions.odin b/core/encoding/uuid/definitions.odin index a63e72693..6810b1cb6 100644 --- a/core/encoding/uuid/definitions.odin +++ b/core/encoding/uuid/definitions.odin @@ -16,6 +16,9 @@ VERSION_7_TIME_SHIFT :: 80 VERSION_7_COUNTER_MASK :: 0x00000000_00000fff_00000000_00000000 VERSION_7_COUNTER_SHIFT :: 64 +@(private) +NO_CSPRNG_ERROR :: "The context random generator is not cryptographic. See the documentation for an example of how to set one up." + Read_Error :: enum { None, Invalid_Length, diff --git a/core/encoding/uuid/generation.odin b/core/encoding/uuid/generation.odin index 2ca5d0e5f..1afa810a2 100644 --- a/core/encoding/uuid/generation.odin +++ b/core/encoding/uuid/generation.odin @@ -1,7 +1,7 @@ package uuid +import "base:runtime" import "core:math/rand" -import "core:mem" import "core:time" /* @@ -33,8 +33,9 @@ generate_v1 :: proc(clock_seq: u16, node: Maybe([6]u8) = nil) -> (result: Identi if realized_node, ok := node.?; ok { mutable_node := realized_node - mem.copy_non_overlapping(&result[10], &mutable_node[0], 6) + runtime.mem_copy_non_overlapping(&result[10], &mutable_node[0], 6) } else { + assert(.Cryptographic in runtime.random_generator_query_info(context.random_generator), NO_CSPRNG_ERROR) bytes_generated := rand.read(result[10:]) assert(bytes_generated == 6, "RNG failed to generate 6 bytes for UUID v1.") } @@ -57,6 +58,7 @@ Returns: - result: The generated UUID. */ generate_v4 :: proc() -> (result: Identifier) { + assert(.Cryptographic in runtime.random_generator_query_info(context.random_generator), NO_CSPRNG_ERROR) bytes_generated := rand.read(result[:]) assert(bytes_generated == 16, "RNG failed to generate 16 bytes for UUID v4.") @@ -94,6 +96,7 @@ generate_v6 :: proc(clock_seq: Maybe(u16) = nil, node: Maybe([6]u8) = nil) -> (r result[8] |= cast(u8)(realized_clock_seq & 0x3F00 >> 8) result[9] = cast(u8)realized_clock_seq } else { + assert(.Cryptographic in runtime.random_generator_query_info(context.random_generator), NO_CSPRNG_ERROR) temporary: [2]u8 bytes_generated := rand.read(temporary[:]) assert(bytes_generated == 2, "RNG failed to generate 2 bytes for UUID v1.") @@ -103,8 +106,9 @@ generate_v6 :: proc(clock_seq: Maybe(u16) = nil, node: Maybe([6]u8) = nil) -> (r if realized_node, ok := node.?; ok { mutable_node := realized_node - mem.copy_non_overlapping(&result[10], &mutable_node[0], 6) + runtime.mem_copy_non_overlapping(&result[10], &mutable_node[0], 6) } else { + assert(.Cryptographic in runtime.random_generator_query_info(context.random_generator), NO_CSPRNG_ERROR) bytes_generated := rand.read(result[10:]) assert(bytes_generated == 6, "RNG failed to generate 6 bytes for UUID v1.") } @@ -128,6 +132,7 @@ Returns: - result: The generated UUID. */ generate_v7 :: proc() -> (result: Identifier) { + assert(.Cryptographic in runtime.random_generator_query_info(context.random_generator), NO_CSPRNG_ERROR) unix_time_in_milliseconds := time.to_unix_nanoseconds(time.now()) / 1e6 temporary := cast(u128be)unix_time_in_milliseconds << VERSION_7_TIME_SHIFT @@ -178,6 +183,7 @@ Returns: - result: The generated UUID. */ generate_v7_counter :: proc(counter: u16) -> (result: Identifier) { + assert(.Cryptographic in runtime.random_generator_query_info(context.random_generator), NO_CSPRNG_ERROR) assert(counter <= 0x0fff, "This implementation of the version 7 UUID does not support counters in excess of 12 bits (4,095).") unix_time_in_milliseconds := time.to_unix_nanoseconds(time.now()) / 1e6 diff --git a/tests/core/encoding/uuid/test_core_uuid.odin b/tests/core/encoding/uuid/test_core_uuid.odin index fc2615fe0..a8f563e13 100644 --- a/tests/core/encoding/uuid/test_core_uuid.odin +++ b/tests/core/encoding/uuid/test_core_uuid.odin @@ -1,5 +1,6 @@ package test_core_uuid +import "core:crypto" import "core:encoding/uuid" import uuid_legacy "core:encoding/uuid/legacy" import "core:log" @@ -8,6 +9,8 @@ import "core:time" @(test) test_version_and_variant :: proc(t: ^testing.T) { + context.random_generator = crypto.random_generator() + v1 := uuid.generate_v1(0) v3 := uuid_legacy.generate_v3(uuid.Namespace_DNS, "") v4 := uuid.generate_v4() @@ -62,6 +65,8 @@ test_legacy_namespaced_uuids :: proc(t: ^testing.T) { @(test) test_v1 :: proc(t: ^testing.T) { + context.random_generator = crypto.random_generator() + CLOCK :: 0x3A1A v1_a := uuid.generate_v1(CLOCK) time.sleep(10 * time.Millisecond) @@ -90,6 +95,8 @@ test_v1 :: proc(t: ^testing.T) { @(test) test_v6 :: proc(t: ^testing.T) { + context.random_generator = crypto.random_generator() + CLOCK :: 0x3A1A v6_a := uuid.generate_v6(CLOCK) time.sleep(10 * time.Millisecond) @@ -118,6 +125,8 @@ test_v6 :: proc(t: ^testing.T) { @(test) test_v7 :: proc(t: ^testing.T) { + context.random_generator = crypto.random_generator() + v7_a := uuid.generate_v7() time.sleep(10 * time.Millisecond) v7_b := uuid.generate_v7() From ea771d0cb77254f3dd78e2c13230390b50cb2228 Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Sat, 22 Jun 2024 13:30:06 -0400 Subject: [PATCH 018/129] Update `uuid` package documentation --- core/encoding/uuid/doc.odin | 47 ++++++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/core/encoding/uuid/doc.odin b/core/encoding/uuid/doc.odin index a05698955..6fa375b72 100644 --- a/core/encoding/uuid/doc.odin +++ b/core/encoding/uuid/doc.odin @@ -1,15 +1,46 @@ /* package uuid implements Universally Unique Identifiers according to the -standard outlined in RFC 4122. - -See here for more information: https://www.rfc-editor.org/rfc/rfc4122.html - -Generation of versions 1 and 2 (the MAC address-based versions) are not yet -implemented. +standard originally outlined in RFC 4122 with additions from RFC 9562. The UUIDs are textually represented and read in the following string format: -`00000000-0000-4000-8000-000000000000` +`00000000-0000-v000-V000-000000000000` -Outside of string representations, they are represented in memory by a 128-bit structure. +`v` is where the version bits reside, and `V` is where the variant bits reside. +The meaning of the other bits is version-dependent. + +Outside of string representations, UUIDs are represented in memory by a 128-bit +structure organized as an array of 16 bytes. + + +Of the UUID versions which may make use of random number generation, a +requirement is placed upon them that the underlying generator be +cryptographically-secure, per RFC 9562's suggestion. + +- Version 1 without a node argument. +- Version 4 in all cases. +- Version 6 without either a clock or node argument. +- Version 7 in all cases. + +Here's an example of how to set up one: + + import "core:crypto" + import "core:encoding/uuid" + + main :: proc() { + my_uuid: uuid.Identifier + + { + // This scope will have a CSPRNG. + context.random_generator = crypto.random_generator() + my_uuid = uuid.generate_v7() + } + + // Back to the default random number generator. + } + + +For more information on the specifications, see here: +- https://www.rfc-editor.org/rfc/rfc4122.html +- https://www.rfc-editor.org/rfc/rfc9562.html */ package uuid From 9b265b2309089656250fd001a61a379e160fa64f Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Sat, 22 Jun 2024 14:29:16 -0400 Subject: [PATCH 019/129] Improve time-related API in `uuid` package - Let timestamps be specified by the user. - Change `time_v*` to `raw_time_v*` and implement an API that returns timestamps from the `time` package. --- core/encoding/uuid/generation.odin | 50 +++++---- core/encoding/uuid/reading.odin | 63 ++++++++++-- tests/core/encoding/uuid/test_core_uuid.odin | 101 +++++++++---------- 3 files changed, 134 insertions(+), 80 deletions(-) diff --git a/core/encoding/uuid/generation.odin b/core/encoding/uuid/generation.odin index 1afa810a2..bf41b4a8c 100644 --- a/core/encoding/uuid/generation.odin +++ b/core/encoding/uuid/generation.odin @@ -11,25 +11,27 @@ Inputs: - clock_seq: The clock sequence, a number which must be initialized to a random number once in the lifetime of a system. - node: An optional 48-bit spatially unique identifier, specified to be the IEEE 802 address of the system. If one is not provided or available, 48 bits of random state will take its place. +- timestamp: A timestamp from the `core:time` package, or `nil` to use the current time. Returns: - result: The generated UUID. */ -generate_v1 :: proc(clock_seq: u16, node: Maybe([6]u8) = nil) -> (result: Identifier) { +generate_v1 :: proc(clock_seq: u16, node: Maybe([6]u8) = nil, timestamp: Maybe(time.Time) = nil) -> (result: Identifier) { assert(clock_seq <= 0x3FFF, "The clock sequence can only hold 14 bits of data; no number greater than 16,383.") - unix_time_in_hns_intervals := time.to_unix_nanoseconds(time.now()) / 100 - timestamp := cast(u64le)(HNS_INTERVALS_BETWEEN_GREG_AND_UNIX + unix_time_in_hns_intervals) - timestamp_octets := transmute([8]u8)timestamp + unix_time_in_hns_intervals := time.to_unix_nanoseconds(timestamp.? or_else time.now()) / 100 - result[0] = timestamp_octets[0] - result[1] = timestamp_octets[1] - result[2] = timestamp_octets[2] - result[3] = timestamp_octets[3] - result[4] = timestamp_octets[4] - result[5] = timestamp_octets[5] + uuid_timestamp := cast(u64le)(HNS_INTERVALS_BETWEEN_GREG_AND_UNIX + unix_time_in_hns_intervals) + uuid_timestamp_octets := transmute([8]u8)uuid_timestamp - result[6] = timestamp_octets[6] >> 4 - result[7] = timestamp_octets[6] << 4 | timestamp_octets[7] + result[0] = uuid_timestamp_octets[0] + result[1] = uuid_timestamp_octets[1] + result[2] = uuid_timestamp_octets[2] + result[3] = uuid_timestamp_octets[3] + result[4] = uuid_timestamp_octets[4] + result[5] = uuid_timestamp_octets[5] + + result[6] = uuid_timestamp_octets[6] >> 4 + result[7] = uuid_timestamp_octets[6] << 4 | uuid_timestamp_octets[7] if realized_node, ok := node.?; ok { mutable_node := realized_node @@ -79,12 +81,13 @@ Inputs: If unspecified, it will be replaced with random bits. - node: An optional 48-bit spatially unique identifier, specified to be the IEEE 802 address of the system. If one is not provided or available, 48 bits of random state will take its place. +- timestamp: A timestamp from the `core:time` package, or `nil` to use the current time. Returns: - result: The generated UUID. */ -generate_v6 :: proc(clock_seq: Maybe(u16) = nil, node: Maybe([6]u8) = nil) -> (result: Identifier) { - unix_time_in_hns_intervals := time.to_unix_nanoseconds(time.now()) / 100 +generate_v6 :: proc(clock_seq: Maybe(u16) = nil, node: Maybe([6]u8) = nil, timestamp: Maybe(time.Time) = nil) -> (result: Identifier) { + unix_time_in_hns_intervals := time.to_unix_nanoseconds(timestamp.? or_else time.now()) / 100 timestamp := cast(u128be)(HNS_INTERVALS_BETWEEN_GREG_AND_UNIX + unix_time_in_hns_intervals) @@ -128,12 +131,15 @@ bits and a 48 bit timestamp. It is designed with time-based sorting in mind, such as for database usage, as the highest bits are allocated from the timestamp of when it is created. +Inputs: +- timestamp: A timestamp from the `core:time` package, or `nil` to use the current time. + Returns: - result: The generated UUID. */ -generate_v7 :: proc() -> (result: Identifier) { +generate_v7_basic :: proc(timestamp: Maybe(time.Time) = nil) -> (result: Identifier) { assert(.Cryptographic in runtime.random_generator_query_info(context.random_generator), NO_CSPRNG_ERROR) - unix_time_in_milliseconds := time.to_unix_nanoseconds(time.now()) / 1e6 + unix_time_in_milliseconds := time.to_unix_nanoseconds(timestamp.? or_else time.now()) / 1e6 temporary := cast(u128be)unix_time_in_milliseconds << VERSION_7_TIME_SHIFT @@ -152,7 +158,7 @@ generate_v7 :: proc() -> (result: Identifier) { } /* -Generate a version 7 UUID with an incremented counter. +Generate a version 7 UUID that has an incremented counter. This UUID will be pseudorandom, save for 6 pre-determined version and variant bits, a 48 bit timestamp, and 12 bits of counter state. @@ -178,14 +184,15 @@ Example: Inputs: - counter: A 12-bit value, incremented each time a UUID is generated in a batch. +- timestamp: A timestamp from the `core:time` package, or `nil` to use the current time. Returns: - result: The generated UUID. */ -generate_v7_counter :: proc(counter: u16) -> (result: Identifier) { +generate_v7_with_counter :: proc(counter: u16, timestamp: Maybe(time.Time) = nil) -> (result: Identifier) { assert(.Cryptographic in runtime.random_generator_query_info(context.random_generator), NO_CSPRNG_ERROR) assert(counter <= 0x0fff, "This implementation of the version 7 UUID does not support counters in excess of 12 bits (4,095).") - unix_time_in_milliseconds := time.to_unix_nanoseconds(time.now()) / 1e6 + unix_time_in_milliseconds := time.to_unix_nanoseconds(timestamp.? or_else time.now()) / 1e6 temporary := cast(u128be)unix_time_in_milliseconds << VERSION_7_TIME_SHIFT temporary |= cast(u128be)counter << VERSION_7_COUNTER_SHIFT @@ -203,3 +210,8 @@ generate_v7_counter :: proc(counter: u16) -> (result: Identifier) { return } + +generate_v7 :: proc { + generate_v7_basic, + generate_v7_with_counter, +} diff --git a/core/encoding/uuid/reading.odin b/core/encoding/uuid/reading.odin index 3b2c48011..c32f69eb7 100644 --- a/core/encoding/uuid/reading.odin +++ b/core/encoding/uuid/reading.odin @@ -1,6 +1,7 @@ package uuid import "base:runtime" +import "core:time" /* Convert a string to a UUID. @@ -127,7 +128,7 @@ node :: proc "contextless" (id: Identifier) -> (node: [6]u8) { } /* -Get the timestamp of a version 1 UUID. +Get the raw timestamp of a version 1 UUID. Inputs: - id: The identifier. @@ -135,7 +136,7 @@ Inputs: Returns: - timestamp: The timestamp, in 100-nanosecond intervals since 1582-10-15. */ -time_v1 :: proc "contextless" (id: Identifier) -> (timestamp: u64) { +raw_time_v1 :: proc "contextless" (id: Identifier) -> (timestamp: u64) { timestamp_octets: [8]u8 timestamp_octets[0] = id[0] @@ -151,6 +152,39 @@ time_v1 :: proc "contextless" (id: Identifier) -> (timestamp: u64) { return cast(u64)transmute(u64le)timestamp_octets } + +/* +Get the timestamp of a version 1 UUID. + +Inputs: +- id: The identifier. + +Returns: +- timestamp: The timestamp of the UUID. +*/ +time_v1 :: proc "contextless" (id: Identifier) -> (timestamp: time.Time) { + delta := cast(time.Duration)(raw_time_v1(id) - HNS_INTERVALS_BETWEEN_GREG_AND_UNIX) * 100 + return time.time_add({}, delta) +} + +/* +Get the raw timestamp of a version 6 UUID. + +Inputs: +- id: The identifier. + +Returns: +- timestamp: The timestamp, in 100-nanosecond intervals since 1582-10-15. +*/ +raw_time_v6 :: proc "contextless" (id: Identifier) -> (timestamp: u64) { + temporary := transmute(u128be)id + + timestamp |= cast(u64)(temporary & 0xFFFFFFFF_FFFF0000_00000000_00000000 >> 68) + timestamp |= cast(u64)(temporary & 0x00000000_00000FFF_00000000_00000000 >> 64) + + return timestamp +} + /* Get the timestamp of a version 6 UUID. @@ -160,13 +194,23 @@ Inputs: Returns: - timestamp: The timestamp, in 100-nanosecond intervals since 1582-10-15. */ -time_v6 :: proc "contextless" (id: Identifier) -> (timestamp: u64) { - temporary := transmute(u128be)id +time_v6 :: proc "contextless" (id: Identifier) -> (timestamp: time.Time) { + delta := cast(time.Duration)(raw_time_v6(id) - HNS_INTERVALS_BETWEEN_GREG_AND_UNIX) * 100 + return time.time_add({}, delta) +} - timestamp |= cast(u64)(temporary & 0xFFFFFFFF_FFFF0000_00000000_00000000 >> 68) - timestamp |= cast(u64)(temporary & 0x00000000_00000FFF_00000000_00000000 >> 64) +/* +Get the raw timestamp of a version 7 UUID. - return timestamp +Inputs: +- id: The identifier. + +Returns: +- timestamp: The timestamp, in milliseconds since the UNIX epoch. +*/ +raw_time_v7 :: proc "contextless" (id: Identifier) -> (timestamp: u64) { + time_bits := transmute(u128be)id & VERSION_7_TIME_MASK + return cast(u64)(time_bits >> VERSION_7_TIME_SHIFT) } /* @@ -178,9 +222,8 @@ Inputs: Returns: - timestamp: The timestamp, in milliseconds since the UNIX epoch. */ -time_v7 :: proc "contextless" (id: Identifier) -> (timestamp: u64) { - time_bits := transmute(u128be)id & VERSION_7_TIME_MASK - return cast(u64)(time_bits >> VERSION_7_TIME_SHIFT) +time_v7 :: proc "contextless" (id: Identifier) -> (timestamp: time.Time) { + return time.time_add({}, cast(time.Duration)(raw_time_v7(id) * 1e6)) } /* diff --git a/tests/core/encoding/uuid/test_core_uuid.odin b/tests/core/encoding/uuid/test_core_uuid.odin index a8f563e13..c7beb67d3 100644 --- a/tests/core/encoding/uuid/test_core_uuid.odin +++ b/tests/core/encoding/uuid/test_core_uuid.odin @@ -67,87 +67,86 @@ test_legacy_namespaced_uuids :: proc(t: ^testing.T) { test_v1 :: proc(t: ^testing.T) { context.random_generator = crypto.random_generator() + point_a := time.time_add({}, 1 * time.Second) + point_b := time.time_add({}, 3 * time.Second) + point_c := time.time_add({}, 5 * time.Second) + CLOCK :: 0x3A1A - v1_a := uuid.generate_v1(CLOCK) - time.sleep(10 * time.Millisecond) - v1_b := uuid.generate_v1(CLOCK) - time.sleep(10 * time.Millisecond) - v1_c := uuid.generate_v1(CLOCK) + v1_a := uuid.generate_v1(CLOCK, nil, point_a) + v1_b := uuid.generate_v1(CLOCK, nil, point_b) + v1_c := uuid.generate_v1(CLOCK, nil, point_c) testing.expect_value(t, uuid.clock_seq(v1_a), CLOCK) - time_bits_a := uuid.time_v1(v1_a) - time_bits_b := uuid.time_v1(v1_b) - time_bits_c := uuid.time_v1(v1_c) + time_a := uuid.time_v1(v1_a) + time_b := uuid.time_v1(v1_b) + time_c := uuid.time_v1(v1_c) - time_a := time.Time { _nsec = cast(i64)((time_bits_a - uuid.HNS_INTERVALS_BETWEEN_GREG_AND_UNIX) * 100) } - time_b := time.Time { _nsec = cast(i64)((time_bits_b - uuid.HNS_INTERVALS_BETWEEN_GREG_AND_UNIX) * 100) } - time_c := time.Time { _nsec = cast(i64)((time_bits_c - uuid.HNS_INTERVALS_BETWEEN_GREG_AND_UNIX) * 100) } + log.debugf("A: %02x, %v", v1_a, time_a) + log.debugf("B: %02x, %v", v1_b, time_b) + log.debugf("C: %02x, %v", v1_c, time_c) - log.debugf("A: %02x, %i, %v", v1_a, time_bits_a, time_a) - log.debugf("B: %02x, %i, %v", v1_b, time_bits_b, time_b) - log.debugf("C: %02x, %i, %v", v1_c, time_bits_c, time_c) - - testing.expect(t, time_bits_b > time_bits_a, "The time bits on the later-generated v1 UUID are lesser than the earlier UUID.") - testing.expect(t, time_bits_c > time_bits_b, "The time bits on the later-generated v1 UUID are lesser than the earlier UUID.") - testing.expect(t, time_bits_c > time_bits_a, "The time bits on the later-generated v1 UUID are lesser than the earlier UUID.") + testing.expect(t, time.diff(time_a, time_b) > 0, "The time on the later-generated v1 UUID is earlier than its successor.") + testing.expect(t, time.diff(time_b, time_c) > 0, "The time on the later-generated v1 UUID is earlier than its successor.") + testing.expect(t, time.diff(time_a, time_c) > 0, "The time on the later-generated v1 UUID is earlier than its successor.") } @(test) test_v6 :: proc(t: ^testing.T) { context.random_generator = crypto.random_generator() + point_a := time.time_add({}, 1 * time.Second) + point_b := time.time_add({}, 3 * time.Second) + point_c := time.time_add({}, 5 * time.Second) + CLOCK :: 0x3A1A - v6_a := uuid.generate_v6(CLOCK) - time.sleep(10 * time.Millisecond) - v6_b := uuid.generate_v6(CLOCK) - time.sleep(10 * time.Millisecond) - v6_c := uuid.generate_v6(CLOCK) + v6_a := uuid.generate_v6(CLOCK, nil, point_a) + v6_b := uuid.generate_v6(CLOCK, nil, point_b) + v6_c := uuid.generate_v6(CLOCK, nil, point_c) testing.expect_value(t, uuid.clock_seq(v6_a), CLOCK) - time_bits_a := uuid.time_v6(v6_a) - time_bits_b := uuid.time_v6(v6_b) - time_bits_c := uuid.time_v6(v6_c) + time_a := uuid.time_v6(v6_a) + time_b := uuid.time_v6(v6_b) + time_c := uuid.time_v6(v6_c) - time_a := time.Time { _nsec = cast(i64)((time_bits_a - uuid.HNS_INTERVALS_BETWEEN_GREG_AND_UNIX) * 100) } - time_b := time.Time { _nsec = cast(i64)((time_bits_b - uuid.HNS_INTERVALS_BETWEEN_GREG_AND_UNIX) * 100) } - time_c := time.Time { _nsec = cast(i64)((time_bits_c - uuid.HNS_INTERVALS_BETWEEN_GREG_AND_UNIX) * 100) } + log.debugf("A: %02x, %v", v6_a, time_a) + log.debugf("B: %02x, %v", v6_b, time_b) + log.debugf("C: %02x, %v", v6_c, time_c) - log.debugf("A: %02x, %i, %v", v6_a, time_bits_a, time_a) - log.debugf("B: %02x, %i, %v", v6_b, time_bits_b, time_b) - log.debugf("C: %02x, %i, %v", v6_c, time_bits_c, time_c) - - testing.expect(t, time_bits_b > time_bits_a, "The time bits on the later-generated v6 UUID are lesser than the earlier UUID.") - testing.expect(t, time_bits_c > time_bits_b, "The time bits on the later-generated v6 UUID are lesser than the earlier UUID.") - testing.expect(t, time_bits_c > time_bits_a, "The time bits on the later-generated v6 UUID are lesser than the earlier UUID.") + testing.expect(t, time.diff(time_a, time_b) > 0, "The time on the later-generated v6 UUID is earlier than its successor.") + testing.expect(t, time.diff(time_b, time_c) > 0, "The time on the later-generated v6 UUID is earlier than its successor.") + testing.expect(t, time.diff(time_a, time_c) > 0, "The time on the later-generated v6 UUID is earlier than its successor.") } @(test) test_v7 :: proc(t: ^testing.T) { context.random_generator = crypto.random_generator() - v7_a := uuid.generate_v7() - time.sleep(10 * time.Millisecond) - v7_b := uuid.generate_v7() - time.sleep(10 * time.Millisecond) - v7_c := uuid.generate_v7() + point_a := time.time_add({}, 1 * time.Second) + point_b := time.time_add({}, 3 * time.Second) + point_c := time.time_add({}, 5 * time.Second) - time_bits_a := uuid.time_v7(v7_a) - time_bits_b := uuid.time_v7(v7_b) - time_bits_c := uuid.time_v7(v7_c) + v7_a := uuid.generate_v7(point_a) + v7_b := uuid.generate_v7(point_b) + v7_c := uuid.generate_v7(point_c) - log.debugf("A: %02x, %i", v7_a, time_bits_a) - log.debugf("B: %02x, %i", v7_b, time_bits_b) - log.debugf("C: %02x, %i", v7_c, time_bits_c) + time_a := uuid.time_v7(v7_a) + time_b := uuid.time_v7(v7_b) + time_c := uuid.time_v7(v7_c) - testing.expect(t, time_bits_b > time_bits_a, "The time bits on the later-generated v7 UUID are lesser than the earlier UUID.") - testing.expect(t, time_bits_c > time_bits_b, "The time bits on the later-generated v7 UUID are lesser than the earlier UUID.") - testing.expect(t, time_bits_c > time_bits_a, "The time bits on the later-generated v7 UUID are lesser than the earlier UUID.") + log.debugf("A: %02x, %v", v7_a, time_a) + log.debugf("B: %02x, %v", v7_b, time_b) + log.debugf("C: %02x, %v", v7_c, time_c) - v7_with_counter := uuid.generate_v7_counter(0x555) + testing.expect(t, time.diff(time_a, time_b) > 0, "The time on the later-generated v7 UUID is earlier than its successor.") + testing.expect(t, time.diff(time_b, time_c) > 0, "The time on the later-generated v7 UUID is earlier than its successor.") + testing.expect(t, time.diff(time_a, time_c) > 0, "The time on the later-generated v7 UUID is earlier than its successor.") + + v7_with_counter := uuid.generate_v7(0x555) log.debugf("D: %02x", v7_with_counter) testing.expect_value(t, uuid.counter_v7(v7_with_counter), 0x555) + } @(test) From 9b3a104640f518f21a83ae2c9784cd8601589880 Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Sat, 22 Jun 2024 14:38:45 -0400 Subject: [PATCH 020/129] Add buffer-based `to_string` to `uuid` package --- core/encoding/uuid/writing.odin | 31 +++++++++++++++++++- tests/core/encoding/uuid/test_core_uuid.odin | 11 +++++-- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/core/encoding/uuid/writing.odin b/core/encoding/uuid/writing.odin index 45096e84f..27dc789c2 100644 --- a/core/encoding/uuid/writing.odin +++ b/core/encoding/uuid/writing.odin @@ -46,7 +46,7 @@ Returns: - str: The allocated and converted string. - error: An optional allocator error if one occured, `nil` otherwise. */ -to_string :: proc( +to_string_allocated :: proc( id: Identifier, allocator := context.allocator, loc := #caller_location, @@ -59,3 +59,32 @@ to_string :: proc( write(strings.to_writer(&builder), id) return strings.to_string(builder), nil } + +/* +Convert a UUID to a string in the 8-4-4-4-12 format. + +Inputs: +- id: The identifier to convert. +- buffer: A byte buffer to store the result. Must be at least 32 bytes large. +- loc: The caller location for debugging purposes (default: #caller_location) + +Returns: +- str: The converted string which will be stored in `buffer`. +*/ +to_string_buffer :: proc( + id: Identifier, + buffer: []byte, + loc := #caller_location, +) -> ( + str: string, +) { + assert(len(buffer) >= EXPECTED_LENGTH, "The buffer provided is not at least 32 bytes large.", loc) + builder := strings.builder_from_bytes(buffer) + write(strings.to_writer(&builder), id) + return strings.to_string(builder) +} + +to_string :: proc { + to_string_allocated, + to_string_buffer, +} diff --git a/tests/core/encoding/uuid/test_core_uuid.odin b/tests/core/encoding/uuid/test_core_uuid.odin index c7beb67d3..460e4259b 100644 --- a/tests/core/encoding/uuid/test_core_uuid.odin +++ b/tests/core/encoding/uuid/test_core_uuid.odin @@ -157,10 +157,15 @@ test_writing :: proc(t: ^testing.T) { b = u8(i) } - s := uuid.to_string(id) - defer delete(s) + buf: [uuid.EXPECTED_LENGTH]u8 - testing.expect_value(t, s, "00010203-0405-0607-0809-0a0b0c0d0e0f") + s_alloc := uuid.to_string(id) + defer delete(s_alloc) + + s_buf := uuid.to_string(id, buf[:]) + + testing.expect_value(t, s_alloc, "00010203-0405-0607-0809-0a0b0c0d0e0f") + testing.expect_value(t, s_buf, "00010203-0405-0607-0809-0a0b0c0d0e0f") } @(test) From 95a9c9b016ab36110f7313105915ab45fea75ca3 Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Sat, 22 Jun 2024 14:40:09 -0400 Subject: [PATCH 021/129] Fix indentation --- tests/core/encoding/uuid/test_core_uuid.odin | 174 +++++++++---------- 1 file changed, 87 insertions(+), 87 deletions(-) diff --git a/tests/core/encoding/uuid/test_core_uuid.odin b/tests/core/encoding/uuid/test_core_uuid.odin index 460e4259b..f50aca963 100644 --- a/tests/core/encoding/uuid/test_core_uuid.odin +++ b/tests/core/encoding/uuid/test_core_uuid.odin @@ -11,56 +11,56 @@ import "core:time" test_version_and_variant :: proc(t: ^testing.T) { context.random_generator = crypto.random_generator() - v1 := uuid.generate_v1(0) - v3 := uuid_legacy.generate_v3(uuid.Namespace_DNS, "") - v4 := uuid.generate_v4() - v5 := uuid_legacy.generate_v5(uuid.Namespace_DNS, "") - v6 := uuid.generate_v6() - v7 := uuid.generate_v7() + v1 := uuid.generate_v1(0) + v3 := uuid_legacy.generate_v3(uuid.Namespace_DNS, "") + v4 := uuid.generate_v4() + v5 := uuid_legacy.generate_v5(uuid.Namespace_DNS, "") + v6 := uuid.generate_v6() + v7 := uuid.generate_v7() - testing.expect_value(t, uuid.version(v1), 1) - testing.expect_value(t, uuid.variant(v1), uuid.Variant_Type.RFC_4122) - testing.expect_value(t, uuid.version(v3), 3) - testing.expect_value(t, uuid.variant(v3), uuid.Variant_Type.RFC_4122) - testing.expect_value(t, uuid.version(v4), 4) - testing.expect_value(t, uuid.variant(v4), uuid.Variant_Type.RFC_4122) - testing.expect_value(t, uuid.version(v5), 5) - testing.expect_value(t, uuid.variant(v5), uuid.Variant_Type.RFC_4122) - testing.expect_value(t, uuid.version(v6), 6) - testing.expect_value(t, uuid.variant(v6), uuid.Variant_Type.RFC_4122) - testing.expect_value(t, uuid.version(v7), 7) - testing.expect_value(t, uuid.variant(v7), uuid.Variant_Type.RFC_4122) + testing.expect_value(t, uuid.version(v1), 1) + testing.expect_value(t, uuid.variant(v1), uuid.Variant_Type.RFC_4122) + testing.expect_value(t, uuid.version(v3), 3) + testing.expect_value(t, uuid.variant(v3), uuid.Variant_Type.RFC_4122) + testing.expect_value(t, uuid.version(v4), 4) + testing.expect_value(t, uuid.variant(v4), uuid.Variant_Type.RFC_4122) + testing.expect_value(t, uuid.version(v5), 5) + testing.expect_value(t, uuid.variant(v5), uuid.Variant_Type.RFC_4122) + testing.expect_value(t, uuid.version(v6), 6) + testing.expect_value(t, uuid.variant(v6), uuid.Variant_Type.RFC_4122) + testing.expect_value(t, uuid.version(v7), 7) + testing.expect_value(t, uuid.variant(v7), uuid.Variant_Type.RFC_4122) } @(test) test_legacy_namespaced_uuids :: proc(t: ^testing.T) { - TEST_NAME :: "0123456789ABCDEF0123456789ABCDEF" + TEST_NAME :: "0123456789ABCDEF0123456789ABCDEF" - Expected_Result :: struct { - namespace: uuid.Identifier, - v3, v5: string, - } + Expected_Result :: struct { + namespace: uuid.Identifier, + v3, v5: string, + } - Expected_Results := [?]Expected_Result { - { uuid.Namespace_DNS, "80147f37-36db-3b82-b78f-810c3c6504ba", "18394c41-13a2-593f-abf2-a63e163c2860" }, - { uuid.Namespace_URL, "8136789b-8e16-3fbd-800b-1587e2f22521", "07337422-eb77-5fd3-99af-c7f59e641e13" }, - { uuid.Namespace_OID, "adbb95bc-ea50-3226-9a75-20c34a6030f8", "24db9b0f-70b8-53c4-a301-f695ce17276d" }, - { uuid.Namespace_X500, "a8965ad1-0e54-3d65-b933-8b7cca8e8313", "3012bf2d-fac4-5187-9825-493e6636b936" }, - } + Expected_Results := [?]Expected_Result { + { uuid.Namespace_DNS, "80147f37-36db-3b82-b78f-810c3c6504ba", "18394c41-13a2-593f-abf2-a63e163c2860" }, + { uuid.Namespace_URL, "8136789b-8e16-3fbd-800b-1587e2f22521", "07337422-eb77-5fd3-99af-c7f59e641e13" }, + { uuid.Namespace_OID, "adbb95bc-ea50-3226-9a75-20c34a6030f8", "24db9b0f-70b8-53c4-a301-f695ce17276d" }, + { uuid.Namespace_X500, "a8965ad1-0e54-3d65-b933-8b7cca8e8313", "3012bf2d-fac4-5187-9825-493e6636b936" }, + } - for exp in Expected_Results { - v3 := uuid_legacy.generate_v3(exp.namespace, TEST_NAME) - v5 := uuid_legacy.generate_v5(exp.namespace, TEST_NAME) + for exp in Expected_Results { + v3 := uuid_legacy.generate_v3(exp.namespace, TEST_NAME) + v5 := uuid_legacy.generate_v5(exp.namespace, TEST_NAME) - v3_str := uuid.to_string(v3) - defer delete(v3_str) + v3_str := uuid.to_string(v3) + defer delete(v3_str) - v5_str := uuid.to_string(v5) - defer delete(v5_str) + v5_str := uuid.to_string(v5) + defer delete(v5_str) - testing.expect_value(t, v3_str, exp.v3) - testing.expect_value(t, v5_str, exp.v5) - } + testing.expect_value(t, v3_str, exp.v3) + testing.expect_value(t, v5_str, exp.v5) + } } @(test) @@ -151,74 +151,74 @@ test_v7 :: proc(t: ^testing.T) { @(test) test_writing :: proc(t: ^testing.T) { - id: uuid.Identifier + id: uuid.Identifier - for &b, i in id { - b = u8(i) - } + for &b, i in id { + b = u8(i) + } buf: [uuid.EXPECTED_LENGTH]u8 - s_alloc := uuid.to_string(id) - defer delete(s_alloc) + s_alloc := uuid.to_string(id) + defer delete(s_alloc) s_buf := uuid.to_string(id, buf[:]) - testing.expect_value(t, s_alloc, "00010203-0405-0607-0809-0a0b0c0d0e0f") - testing.expect_value(t, s_buf, "00010203-0405-0607-0809-0a0b0c0d0e0f") + testing.expect_value(t, s_alloc, "00010203-0405-0607-0809-0a0b0c0d0e0f") + testing.expect_value(t, s_buf, "00010203-0405-0607-0809-0a0b0c0d0e0f") } @(test) test_reading :: proc(t: ^testing.T) { - id, err := uuid.read("00010203-0405-0607-0809-0a0b0c0d0e0f") - testing.expect_value(t, err, nil) + id, err := uuid.read("00010203-0405-0607-0809-0a0b0c0d0e0f") + testing.expect_value(t, err, nil) - for b, i in id { - testing.expect_value(t, b, u8(i)) - } + for b, i in id { + testing.expect_value(t, b, u8(i)) + } } @(test) test_reading_errors :: proc(t: ^testing.T) { - { - BAD_STRING :: "|.......@....@....@....@............" - _, err := uuid.read(BAD_STRING) - testing.expect_value(t, err, uuid.Read_Error.Invalid_Separator) - } + { + BAD_STRING :: "|.......@....@....@....@............" + _, err := uuid.read(BAD_STRING) + testing.expect_value(t, err, uuid.Read_Error.Invalid_Separator) + } - { - BAD_STRING :: "|.......-....-....-....-............" - _, err := uuid.read(BAD_STRING) - testing.expect_value(t, err, uuid.Read_Error.Invalid_Hexadecimal) - } + { + BAD_STRING :: "|.......-....-....-....-............" + _, err := uuid.read(BAD_STRING) + testing.expect_value(t, err, uuid.Read_Error.Invalid_Hexadecimal) + } - { - BAD_STRING :: ".......-....-....-....-............" - _, err := uuid.read(BAD_STRING) - testing.expect_value(t, err, uuid.Read_Error.Invalid_Length) - } + { + BAD_STRING :: ".......-....-....-....-............" + _, err := uuid.read(BAD_STRING) + testing.expect_value(t, err, uuid.Read_Error.Invalid_Length) + } - { - BAD_STRING :: "|.......-....-....-....-............|" - _, err := uuid.read(BAD_STRING) - testing.expect_value(t, err, uuid.Read_Error.Invalid_Length) - } + { + BAD_STRING :: "|.......-....-....-....-............|" + _, err := uuid.read(BAD_STRING) + testing.expect_value(t, err, uuid.Read_Error.Invalid_Length) + } - { - BAD_STRING :: "00000000-0000-0000-0000-0000000000001" - _, err := uuid.read(BAD_STRING) - testing.expect_value(t, err, uuid.Read_Error.Invalid_Length) - } + { + BAD_STRING :: "00000000-0000-0000-0000-0000000000001" + _, err := uuid.read(BAD_STRING) + testing.expect_value(t, err, uuid.Read_Error.Invalid_Length) + } - { - BAD_STRING :: "00000000000000000000000000000000" - _, err := uuid.read(BAD_STRING) - testing.expect_value(t, err, uuid.Read_Error.Invalid_Length) - } + { + BAD_STRING :: "00000000000000000000000000000000" + _, err := uuid.read(BAD_STRING) + testing.expect_value(t, err, uuid.Read_Error.Invalid_Length) + } - { - OK_STRING :: "00000000-0000-0000-0000-000000000000" - _, err := uuid.read(OK_STRING) - testing.expect_value(t, err, nil) - } + { + OK_STRING :: "00000000-0000-0000-0000-000000000000" + _, err := uuid.read(OK_STRING) + testing.expect_value(t, err, nil) + } } From 8b8f8c7f7d8fd9184e376a119730ad392d3aa4d1 Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Sat, 22 Jun 2024 15:07:29 -0400 Subject: [PATCH 022/129] Address minor organizational issues --- core/encoding/uuid/definitions.odin | 4 ++++ core/encoding/uuid/generation.odin | 32 ++++++++++++++--------------- core/encoding/uuid/reading.odin | 2 +- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/core/encoding/uuid/definitions.odin b/core/encoding/uuid/definitions.odin index 6810b1cb6..fe13ca99a 100644 --- a/core/encoding/uuid/definitions.odin +++ b/core/encoding/uuid/definitions.odin @@ -18,6 +18,10 @@ VERSION_7_COUNTER_SHIFT :: 64 @(private) NO_CSPRNG_ERROR :: "The context random generator is not cryptographic. See the documentation for an example of how to set one up." +@(private) +BIG_CLOCK_ERROR :: "The clock sequence can only hold 14 bits of data, therefore no number greater than 16,383 (0x3FFF)." +@(private) +VERSION_7_BIG_COUNTER_ERROR :: "This implementation of the version 7 UUID counter can only hold 12 bits of data, therefore no number greater than 4,095 (0xFFF)." Read_Error :: enum { None, diff --git a/core/encoding/uuid/generation.odin b/core/encoding/uuid/generation.odin index bf41b4a8c..427d5243e 100644 --- a/core/encoding/uuid/generation.odin +++ b/core/encoding/uuid/generation.odin @@ -17,7 +17,7 @@ Returns: - result: The generated UUID. */ generate_v1 :: proc(clock_seq: u16, node: Maybe([6]u8) = nil, timestamp: Maybe(time.Time) = nil) -> (result: Identifier) { - assert(clock_seq <= 0x3FFF, "The clock sequence can only hold 14 bits of data; no number greater than 16,383.") + assert(clock_seq <= 0x3FFF, BIG_CLOCK_ERROR) unix_time_in_hns_intervals := time.to_unix_nanoseconds(timestamp.? or_else time.now()) / 100 uuid_timestamp := cast(u64le)(HNS_INTERVALS_BETWEEN_GREG_AND_UNIX + unix_time_in_hns_intervals) @@ -89,13 +89,15 @@ Returns: generate_v6 :: proc(clock_seq: Maybe(u16) = nil, node: Maybe([6]u8) = nil, timestamp: Maybe(time.Time) = nil) -> (result: Identifier) { unix_time_in_hns_intervals := time.to_unix_nanoseconds(timestamp.? or_else time.now()) / 100 - timestamp := cast(u128be)(HNS_INTERVALS_BETWEEN_GREG_AND_UNIX + unix_time_in_hns_intervals) + uuid_timestamp := cast(u128be)(HNS_INTERVALS_BETWEEN_GREG_AND_UNIX + unix_time_in_hns_intervals) - result |= transmute(Identifier)(timestamp & 0x0FFFFFFF_FFFFF000 << 68) - result |= transmute(Identifier)(timestamp & 0x00000000_00000FFF << 64) + result = transmute(Identifier)( + uuid_timestamp & 0x0FFFFFFF_FFFFF000 << 68 | + uuid_timestamp & 0x00000000_00000FFF << 64 + ) if realized_clock_seq, ok := clock_seq.?; ok { - assert(realized_clock_seq <= 0x3FFF, "The clock sequence can only hold 14 bits of data, therefore no number greater than 16,383.") + assert(realized_clock_seq <= 0x3FFF, BIG_CLOCK_ERROR) result[8] |= cast(u8)(realized_clock_seq & 0x3F00 >> 8) result[9] = cast(u8)realized_clock_seq } else { @@ -126,7 +128,7 @@ generate_v6 :: proc(clock_seq: Maybe(u16) = nil, node: Maybe([6]u8) = nil, times Generate a version 7 UUID. This UUID will be pseudorandom, save for 6 pre-determined version and variant -bits and a 48 bit timestamp. +bits and a 48-bit timestamp. It is designed with time-based sorting in mind, such as for database usage, as the highest bits are allocated from the timestamp of when it is created. @@ -141,13 +143,11 @@ generate_v7_basic :: proc(timestamp: Maybe(time.Time) = nil) -> (result: Identif assert(.Cryptographic in runtime.random_generator_query_info(context.random_generator), NO_CSPRNG_ERROR) unix_time_in_milliseconds := time.to_unix_nanoseconds(timestamp.? or_else time.now()) / 1e6 - temporary := cast(u128be)unix_time_in_milliseconds << VERSION_7_TIME_SHIFT + result = transmute(Identifier)(cast(u128be)unix_time_in_milliseconds << VERSION_7_TIME_SHIFT) bytes_generated := rand.read(result[6:]) assert(bytes_generated == 10, "RNG failed to generate 10 bytes for UUID v7.") - result |= transmute(Identifier)temporary - result[VERSION_BYTE_INDEX] &= 0x0F result[VERSION_BYTE_INDEX] |= 0x70 @@ -161,7 +161,7 @@ generate_v7_basic :: proc(timestamp: Maybe(time.Time) = nil) -> (result: Identif Generate a version 7 UUID that has an incremented counter. This UUID will be pseudorandom, save for 6 pre-determined version and variant -bits, a 48 bit timestamp, and 12 bits of counter state. +bits, a 48-bit timestamp, and 12 bits of counter state. It is designed with time-based sorting in mind, such as for database usage, as the highest bits are allocated from the timestamp of when it is created. @@ -183,7 +183,7 @@ Example: } Inputs: -- counter: A 12-bit value, incremented each time a UUID is generated in a batch. +- counter: A 12-bit value which should be incremented each time a UUID is generated in a batch. - timestamp: A timestamp from the `core:time` package, or `nil` to use the current time. Returns: @@ -191,17 +191,17 @@ Returns: */ generate_v7_with_counter :: proc(counter: u16, timestamp: Maybe(time.Time) = nil) -> (result: Identifier) { assert(.Cryptographic in runtime.random_generator_query_info(context.random_generator), NO_CSPRNG_ERROR) - assert(counter <= 0x0fff, "This implementation of the version 7 UUID does not support counters in excess of 12 bits (4,095).") + assert(counter <= 0x0fff, VERSION_7_BIG_COUNTER_ERROR) unix_time_in_milliseconds := time.to_unix_nanoseconds(timestamp.? or_else time.now()) / 1e6 - temporary := cast(u128be)unix_time_in_milliseconds << VERSION_7_TIME_SHIFT - temporary |= cast(u128be)counter << VERSION_7_COUNTER_SHIFT + result = transmute(Identifier)( + cast(u128be)unix_time_in_milliseconds << VERSION_7_TIME_SHIFT | + cast(u128be)counter << VERSION_7_COUNTER_SHIFT + ) bytes_generated := rand.read(result[8:]) assert(bytes_generated == 8, "RNG failed to generate 8 bytes for UUID v7.") - result |= transmute(Identifier)temporary - result[VERSION_BYTE_INDEX] &= 0x0F result[VERSION_BYTE_INDEX] |= 0x70 diff --git a/core/encoding/uuid/reading.odin b/core/encoding/uuid/reading.odin index c32f69eb7..d41606f63 100644 --- a/core/encoding/uuid/reading.odin +++ b/core/encoding/uuid/reading.odin @@ -113,7 +113,7 @@ clock_seq :: proc "contextless" (id: Identifier) -> (clock_seq: u16) { } /* -Get the node of a version 1 UUID. +Get the node of a version 1 or version 6 UUID. Inputs: - id: The identifier. From 339b2b23f695fb22d2b91fc79f75a288b27a9572 Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Sat, 22 Jun 2024 15:14:14 -0400 Subject: [PATCH 023/129] Add `unsafe_write` to `uuid` package --- core/encoding/uuid/writing.odin | 49 ++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/core/encoding/uuid/writing.odin b/core/encoding/uuid/writing.odin index 27dc789c2..499cba72b 100644 --- a/core/encoding/uuid/writing.odin +++ b/core/encoding/uuid/writing.odin @@ -8,12 +8,53 @@ import "core:strings" /* Write a UUID in the 8-4-4-4-12 format. +This procedure performs error checking with every byte written. + +If you can guarantee beforehand that your stream has enough space to hold the +UUID (32 bytes), then it is better to use `unsafe_write` instead as that will +be faster. + +Inputs: +- w: A writable stream. +- id: The identifier to convert. + +Returns: +- error: An `io` error, if one occurred, otherwise `nil`. +*/ +write :: proc(w: io.Writer, id: Identifier) -> (error: io.Error) #no_bounds_check { + write_octet :: proc (w: io.Writer, octet: u8) -> io.Error #no_bounds_check { + high_nibble := octet >> 4 + low_nibble := octet & 0xF + + io.write_byte(w, strconv.digits[high_nibble]) or_return + io.write_byte(w, strconv.digits[low_nibble]) or_return + return nil + } + + for index in 0 ..< 4 { write_octet(w, id[index]) or_return } + io.write_byte(w, '-') or_return + for index in 4 ..< 6 { write_octet(w, id[index]) or_return } + io.write_byte(w, '-') or_return + for index in 6 ..< 8 { write_octet(w, id[index]) or_return } + io.write_byte(w, '-') or_return + for index in 8 ..< 10 { write_octet(w, id[index]) or_return } + io.write_byte(w, '-') or_return + for index in 10 ..< 16 { write_octet(w, id[index]) or_return } + + return nil +} + +/* +Write a UUID in the 8-4-4-4-12 format. + +This procedure performs no error checking on the underlying stream. + Inputs: - w: A writable stream. - id: The identifier to convert. */ -write :: proc(w: io.Writer, id: Identifier) #no_bounds_check { - write_octet :: proc (w: io.Writer, octet: u8) { +unsafe_write :: proc(w: io.Writer, id: Identifier) #no_bounds_check { + write_octet :: proc (w: io.Writer, octet: u8) #no_bounds_check { high_nibble := octet >> 4 low_nibble := octet & 0xF @@ -56,7 +97,7 @@ to_string_allocated :: proc( ) #optional_allocator_error { buf := make([]byte, EXPECTED_LENGTH, allocator, loc) or_return builder := strings.builder_from_bytes(buf[:]) - write(strings.to_writer(&builder), id) + unsafe_write(strings.to_writer(&builder), id) return strings.to_string(builder), nil } @@ -80,7 +121,7 @@ to_string_buffer :: proc( ) { assert(len(buffer) >= EXPECTED_LENGTH, "The buffer provided is not at least 32 bytes large.", loc) builder := strings.builder_from_bytes(buffer) - write(strings.to_writer(&builder), id) + unsafe_write(strings.to_writer(&builder), id) return strings.to_string(builder) } From f6344577d3cf89bf1be6675bf34e8dd03752c9e1 Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Sat, 22 Jun 2024 15:30:47 -0400 Subject: [PATCH 024/129] Add UUID sorting tests --- tests/core/encoding/uuid/test_core_uuid.odin | 125 +++++++++++++++++++ 1 file changed, 125 insertions(+) diff --git a/tests/core/encoding/uuid/test_core_uuid.odin b/tests/core/encoding/uuid/test_core_uuid.odin index f50aca963..9f2d9c312 100644 --- a/tests/core/encoding/uuid/test_core_uuid.odin +++ b/tests/core/encoding/uuid/test_core_uuid.odin @@ -4,6 +4,7 @@ import "core:crypto" import "core:encoding/uuid" import uuid_legacy "core:encoding/uuid/legacy" import "core:log" +import "core:slice" import "core:testing" import "core:time" @@ -146,7 +147,131 @@ test_v7 :: proc(t: ^testing.T) { v7_with_counter := uuid.generate_v7(0x555) log.debugf("D: %02x", v7_with_counter) testing.expect_value(t, uuid.counter_v7(v7_with_counter), 0x555) +} +@(test) +test_sorting_v1 :: proc(t: ^testing.T) { + // This test is to make sure that the v1 UUIDs do _not_ sort. + // They are incapable of sorting properly by the nature their time bit ordering. + // + // Something is very strange if they do sort correctly. + point_a := time.time_add({}, 1 * time.Second) + point_b := time.time_add({}, 3 * time.Second) + point_c := time.time_add({}, 5 * time.Second) + point_d := time.time_add({}, 7 * time.Second) + point_e := time.time_add({}, 11 * time.Second) + + mac: [6]byte + v1_a := uuid.generate_v1(0, mac, point_a) + v1_b := uuid.generate_v1(0, mac, point_b) + v1_c := uuid.generate_v1(0, mac, point_c) + v1_d := uuid.generate_v1(0, mac, point_d) + v1_e := uuid.generate_v1(0, mac, point_e) + + sort_test := [5]u128be { + transmute(u128be)v1_e, + transmute(u128be)v1_a, + transmute(u128be)v1_d, + transmute(u128be)v1_b, + transmute(u128be)v1_c, + } + + log.debugf("Before: %x", sort_test) + slice.sort(sort_test[:]) + log.debugf("After: %x", sort_test) + + ERROR :: "v1 UUIDs are sorting by time, despite this not being possible." + + testing.expect(t, sort_test[0] != transmute(u128be)v1_a, ERROR) + testing.expect(t, sort_test[1] != transmute(u128be)v1_b, ERROR) + testing.expect(t, sort_test[2] != transmute(u128be)v1_c, ERROR) + testing.expect(t, sort_test[3] != transmute(u128be)v1_d, ERROR) + testing.expect(t, sort_test[4] != transmute(u128be)v1_e, ERROR) +} + +@(test) +test_sorting_v6 :: proc(t: ^testing.T) { + context.random_generator = crypto.random_generator() + + point_a := time.time_add({}, 1 * time.Second) + point_b := time.time_add({}, 3 * time.Second) + point_c := time.time_add({}, 5 * time.Second) + point_d := time.time_add({}, 7 * time.Second) + point_e := time.time_add({}, 11 * time.Second) + + mac: [6]byte + v6_a := uuid.generate_v6(0, mac, point_a) + v6_b := uuid.generate_v6(0, mac, point_b) + v6_c := uuid.generate_v6(0, mac, point_c) + v6_d := uuid.generate_v6(0, mac, point_d) + v6_e := uuid.generate_v6(0, mac, point_e) + + sort_test := [5]u128be { + transmute(u128be)v6_e, + transmute(u128be)v6_a, + transmute(u128be)v6_d, + transmute(u128be)v6_b, + transmute(u128be)v6_c, + } + + log.debugf("Before: %x", sort_test) + slice.sort(sort_test[:]) + log.debugf("After: %x", sort_test) + + ERROR :: "v6 UUIDs are failing to sort properly." + + testing.expect(t, sort_test[0] < sort_test[1], ERROR) + testing.expect(t, sort_test[1] < sort_test[2], ERROR) + testing.expect(t, sort_test[2] < sort_test[3], ERROR) + testing.expect(t, sort_test[3] < sort_test[4], ERROR) + + testing.expect(t, sort_test[0] == transmute(u128be)v6_a, ERROR) + testing.expect(t, sort_test[1] == transmute(u128be)v6_b, ERROR) + testing.expect(t, sort_test[2] == transmute(u128be)v6_c, ERROR) + testing.expect(t, sort_test[3] == transmute(u128be)v6_d, ERROR) + testing.expect(t, sort_test[4] == transmute(u128be)v6_e, ERROR) +} + +@(test) +test_sorting_v7 :: proc(t: ^testing.T) { + context.random_generator = crypto.random_generator() + + point_a := time.time_add({}, 1 * time.Second) + point_b := time.time_add({}, 3 * time.Second) + point_c := time.time_add({}, 5 * time.Second) + point_d := time.time_add({}, 7 * time.Second) + point_e := time.time_add({}, 11 * time.Second) + + v7_a := uuid.generate_v7(point_a) + v7_b := uuid.generate_v7(point_b) + v7_c := uuid.generate_v7(point_c) + v7_d := uuid.generate_v7(point_d) + v7_e := uuid.generate_v7(point_e) + + sort_test := [5]u128be { + transmute(u128be)v7_e, + transmute(u128be)v7_a, + transmute(u128be)v7_d, + transmute(u128be)v7_b, + transmute(u128be)v7_c, + } + + log.debugf("Before: %x", sort_test) + slice.sort(sort_test[:]) + log.debugf("After: %x", sort_test) + + ERROR :: "v7 UUIDs are failing to sort properly." + + testing.expect(t, sort_test[0] < sort_test[1], ERROR) + testing.expect(t, sort_test[1] < sort_test[2], ERROR) + testing.expect(t, sort_test[2] < sort_test[3], ERROR) + testing.expect(t, sort_test[3] < sort_test[4], ERROR) + + testing.expect(t, sort_test[0] == transmute(u128be)v7_a, ERROR) + testing.expect(t, sort_test[1] == transmute(u128be)v7_b, ERROR) + testing.expect(t, sort_test[2] == transmute(u128be)v7_c, ERROR) + testing.expect(t, sort_test[3] == transmute(u128be)v7_d, ERROR) + testing.expect(t, sort_test[4] == transmute(u128be)v7_e, ERROR) } @(test) From d559feb7011fd1c75ae66c9aed38536dcd41a2cf Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Sat, 22 Jun 2024 15:49:48 -0400 Subject: [PATCH 025/129] Add `uuid` test for timestamps --- tests/core/encoding/uuid/test_core_uuid.odin | 48 ++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/tests/core/encoding/uuid/test_core_uuid.odin b/tests/core/encoding/uuid/test_core_uuid.odin index 9f2d9c312..895de3863 100644 --- a/tests/core/encoding/uuid/test_core_uuid.odin +++ b/tests/core/encoding/uuid/test_core_uuid.odin @@ -33,6 +33,54 @@ test_version_and_variant :: proc(t: ^testing.T) { testing.expect_value(t, uuid.variant(v7), uuid.Variant_Type.RFC_4122) } +@(test) +test_timestamps :: proc(t: ^testing.T) { + // This test makes sure that timestamps are recoverable and have not been + // overwritten by neighboring bits, taking into account precision loss. + context.random_generator = crypto.random_generator() + + N :: max(i64) + + max_time := time.Time { N } + + mac: [6]byte + v1 := uuid.generate_v1(0, mac, max_time) + v6 := uuid.generate_v6(0, mac, max_time) + v7 := uuid.generate_v7(max_time) + // The counter version keeps its time in the same place as the basic version, + // this is just for the sake of completeness. + v7_counter := uuid.generate_v7(0, max_time) + + v1_time := uuid.time_v1(v1) + v6_time := uuid.time_v6(v6) + v7_time := uuid.time_v7(v7) + v7_counter_time := uuid.time_v7(v7_counter) + + // I hope the compiler doesn't ever optimize this out. + max_time_hns_resolution := time.Time { N / 100 * 100 } + max_time_ms_resolution := time.Time { N / 1e6 * 1e6 } + + testing.expectf(t, + time.diff(max_time_hns_resolution, v1_time) == 0, + "v1 UUID timestamp is invalid, expected %x, got %x", + max_time_hns_resolution, v1_time) + + testing.expectf(t, + time.diff(max_time_hns_resolution, v6_time) == 0, + "v6 UUID timestamp is invalid, expected %x, got %x", + max_time_hns_resolution, v6_time) + + testing.expectf(t, + time.diff(max_time_ms_resolution, v7_time) == 0, + "v7 UUID timestamp is invalid, expected %x, got %x", + max_time_ms_resolution, v7_time) + + testing.expectf(t, + time.diff(max_time_ms_resolution, v7_counter_time) == 0, + "v7 UUID (with counter) timestamp is invalid, expected %x, got %x", + max_time_ms_resolution, v7_counter_time) +} + @(test) test_legacy_namespaced_uuids :: proc(t: ^testing.T) { TEST_NAME :: "0123456789ABCDEF0123456789ABCDEF" From 859cbf7d72ffc080f6e0224980bbed7458f1d07e Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Sat, 22 Jun 2024 15:54:15 -0400 Subject: [PATCH 026/129] Test if v1 and v6 UUID `node` is set correctly --- tests/core/encoding/uuid/test_core_uuid.odin | 26 +++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/tests/core/encoding/uuid/test_core_uuid.odin b/tests/core/encoding/uuid/test_core_uuid.odin index 895de3863..3a0d621ca 100644 --- a/tests/core/encoding/uuid/test_core_uuid.odin +++ b/tests/core/encoding/uuid/test_core_uuid.odin @@ -121,12 +121,19 @@ test_v1 :: proc(t: ^testing.T) { point_c := time.time_add({}, 5 * time.Second) CLOCK :: 0x3A1A - v1_a := uuid.generate_v1(CLOCK, nil, point_a) - v1_b := uuid.generate_v1(CLOCK, nil, point_b) - v1_c := uuid.generate_v1(CLOCK, nil, point_c) + mac := [6]u8{0xFF, 0x10, 0xAA, 0x55, 0x01, 0xFF} + + v1_a := uuid.generate_v1(CLOCK, mac, point_a) + v1_b := uuid.generate_v1(CLOCK, mac, point_b) + v1_c := uuid.generate_v1(CLOCK, mac, point_c) testing.expect_value(t, uuid.clock_seq(v1_a), CLOCK) + extracted_mac := uuid.node(v1_a) + for i in 0 ..< len(mac) { + testing.expect(t, mac[i] == extracted_mac[i]) + } + time_a := uuid.time_v1(v1_a) time_b := uuid.time_v1(v1_b) time_c := uuid.time_v1(v1_c) @@ -149,12 +156,19 @@ test_v6 :: proc(t: ^testing.T) { point_c := time.time_add({}, 5 * time.Second) CLOCK :: 0x3A1A - v6_a := uuid.generate_v6(CLOCK, nil, point_a) - v6_b := uuid.generate_v6(CLOCK, nil, point_b) - v6_c := uuid.generate_v6(CLOCK, nil, point_c) + mac := [6]u8{0xFF, 0x10, 0xAA, 0x55, 0x01, 0xFF} + + v6_a := uuid.generate_v6(CLOCK, mac, point_a) + v6_b := uuid.generate_v6(CLOCK, mac, point_b) + v6_c := uuid.generate_v6(CLOCK, mac, point_c) testing.expect_value(t, uuid.clock_seq(v6_a), CLOCK) + extracted_mac := uuid.node(v6_a) + for i in 0 ..< len(mac) { + testing.expect(t, mac[i] == extracted_mac[i]) + } + time_a := uuid.time_v6(v6_a) time_b := uuid.time_v6(v6_b) time_c := uuid.time_v6(v6_c) From e9b882be058f08f014ea0e598c18b5df05a86a8a Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Sat, 22 Jun 2024 16:51:37 -0400 Subject: [PATCH 027/129] Add vendor-specific version 8 UUID generation (hashing) --- core/encoding/uuid/generation.odin | 116 +++++++++++++++++++ tests/core/encoding/uuid/test_core_uuid.odin | 14 +++ 2 files changed, 130 insertions(+) diff --git a/core/encoding/uuid/generation.odin b/core/encoding/uuid/generation.odin index 427d5243e..cf29df378 100644 --- a/core/encoding/uuid/generation.odin +++ b/core/encoding/uuid/generation.odin @@ -1,6 +1,7 @@ package uuid import "base:runtime" +import "core:crypto/hash" import "core:math/rand" import "core:time" @@ -215,3 +216,118 @@ generate_v7 :: proc { generate_v7_basic, generate_v7_with_counter, } + +/* +Generate a version 8 UUID using a specific hashing algorithm. + +This UUID is generated by hashing a name with a namespace. + +Note that all version 8 UUIDs are for experimental or vendor-specific use +cases, per the specification. This use case in particular is for offering a +non-legacy alternative to UUID versions 3 and 5. + +Inputs: +- namespace: An `Identifier` that is used to represent the underlying namespace. + This can be any one of the `Namespace_*` values provided in this package. +- name: The byte slice which will be hashed with the namespace. +- algorithm: A hashing algorithm from `core:crypto/hash`. + +Returns: +- result: The generated UUID. + +Example: + import "core:crypto/hash" + import "core:encoding/uuid" + import "core:fmt" + + main :: proc() { + my_uuid := uuid.generate_v8_hash(uuid.Namespace_DNS, "www.odin-lang.org", .SHA256) + my_uuid_string := uuid.to_string(my_uuid, context.temp_allocator) + fmt.println(my_uuid_string) + } + +Output: + + 3730f688-4bff-8dce-9cbf-74a3960c5703 + +*/ +generate_v8_hash_bytes :: proc( + namespace: Identifier, + name: []byte, + algorithm: hash.Algorithm, +) -> ( + result: Identifier, +) { + // 128 bytes should be enough for the foreseeable future. + digest: [128]byte + + assert(hash.DIGEST_SIZES[algorithm] >= 16, "Per RFC 9562, the hashing algorithm used must generate a digest of 128 bits or larger.") + assert(hash.DIGEST_SIZES[algorithm] < len(digest), "Digest size is too small for this algorithm. The buffer must be increased.") + + hash_context: hash.Context + hash.init(&hash_context, algorithm) + + mutable_namespace := namespace + hash.update(&hash_context, mutable_namespace[:]) + hash.update(&hash_context, name[:]) + hash.final(&hash_context, digest[:]) + + runtime.mem_copy_non_overlapping(&result, &digest, 16) + + result[VERSION_BYTE_INDEX] &= 0x0F + result[VERSION_BYTE_INDEX] |= 0x80 + + result[VARIANT_BYTE_INDEX] &= 0x3F + result[VARIANT_BYTE_INDEX] |= 0x80 + + return +} + +/* +Generate a version 8 UUID using a specific hashing algorithm. + +This UUID is generated by hashing a name with a namespace. + +Note that all version 8 UUIDs are for experimental or vendor-specific use +cases, per the specification. This use case in particular is for offering a +non-legacy alternative to UUID versions 3 and 5. + +Inputs: +- namespace: An `Identifier` that is used to represent the underlying namespace. + This can be any one of the `Namespace_*` values provided in this package. +- name: The string which will be hashed with the namespace. +- algorithm: A hashing algorithm from `core:crypto/hash`. + +Returns: +- result: The generated UUID. + +Example: + import "core:crypto/hash" + import "core:encoding/uuid" + import "core:fmt" + + main :: proc() { + my_uuid := uuid.generate_v8_hash(uuid.Namespace_DNS, "www.odin-lang.org", .SHA256) + my_uuid_string := uuid.to_string(my_uuid, context.temp_allocator) + fmt.println(my_uuid_string) + } + +Output: + + 3730f688-4bff-8dce-9cbf-74a3960c5703 + +*/ +generate_v8_hash_string :: proc( + namespace: Identifier, + name: string, + algorithm: hash.Algorithm, +) -> ( + result: Identifier, +) { + return generate_v8_hash_bytes(namespace, transmute([]byte)name, algorithm) +} + +generate_v8_hash :: proc { + generate_v8_hash_bytes, + generate_v8_hash_string, +} diff --git a/tests/core/encoding/uuid/test_core_uuid.odin b/tests/core/encoding/uuid/test_core_uuid.odin index 3a0d621ca..aeb73c841 100644 --- a/tests/core/encoding/uuid/test_core_uuid.odin +++ b/tests/core/encoding/uuid/test_core_uuid.odin @@ -18,6 +18,7 @@ test_version_and_variant :: proc(t: ^testing.T) { v5 := uuid_legacy.generate_v5(uuid.Namespace_DNS, "") v6 := uuid.generate_v6() v7 := uuid.generate_v7() + v8 := uuid.generate_v8_hash(uuid.Namespace_DNS, "", .SHA512) testing.expect_value(t, uuid.version(v1), 1) testing.expect_value(t, uuid.variant(v1), uuid.Variant_Type.RFC_4122) @@ -31,6 +32,8 @@ test_version_and_variant :: proc(t: ^testing.T) { testing.expect_value(t, uuid.variant(v6), uuid.Variant_Type.RFC_4122) testing.expect_value(t, uuid.version(v7), 7) testing.expect_value(t, uuid.variant(v7), uuid.Variant_Type.RFC_4122) + testing.expect_value(t, uuid.version(v8), 8) + testing.expect_value(t, uuid.variant(v8), uuid.Variant_Type.RFC_4122) } @(test) @@ -81,6 +84,17 @@ test_timestamps :: proc(t: ^testing.T) { max_time_ms_resolution, v7_counter_time) } +@(test) +test_v8_hash_implementation :: proc(t: ^testing.T) { + // This example and its results are derived from RFC 9562. + // https://www.rfc-editor.org/rfc/rfc9562.html#name-example-of-a-uuidv8-value-n + + id := uuid.generate_v8_hash(uuid.Namespace_DNS, "www.example.com", .SHA256) + id_str := uuid.to_string(id) + defer delete(id_str) + testing.expect_value(t, id_str, "5c146b14-3c52-8afd-938a-375d0df1fbf6") +} + @(test) test_legacy_namespaced_uuids :: proc(t: ^testing.T) { TEST_NAME :: "0123456789ABCDEF0123456789ABCDEF" From 5a75cac5b9d9173d2d2f23baf189dacb21f8ae83 Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Sat, 22 Jun 2024 17:06:32 -0400 Subject: [PATCH 028/129] Add API for creating custom version 8 UUIDs --- core/encoding/uuid/stamping.odin | 89 ++++++++++++++++++++ tests/core/encoding/uuid/test_core_uuid.odin | 20 ++++- 2 files changed, 106 insertions(+), 3 deletions(-) create mode 100644 core/encoding/uuid/stamping.odin diff --git a/core/encoding/uuid/stamping.odin b/core/encoding/uuid/stamping.odin new file mode 100644 index 000000000..0c07725c3 --- /dev/null +++ b/core/encoding/uuid/stamping.odin @@ -0,0 +1,89 @@ +package uuid + +import "base:runtime" + +/* +Stamp a 128-bit integer as being a valid version 8 UUID. + +Per the specification, all version 8 UUIDs are either for experimental or +vendor-specific purposes. This procedure allows for converting arbitrary data +into custom UUIDs. + +Inputs: +- integer: Any integer type. + +Returns: +- result: A valid version 8 UUID. +*/ +stamp_v8_int :: proc(#any_int integer: u128) -> (result: Identifier) { + result = transmute(Identifier)cast(u128be)integer + + result[VERSION_BYTE_INDEX] &= 0x0F + result[VERSION_BYTE_INDEX] |= 0x80 + + result[VARIANT_BYTE_INDEX] &= 0x3F + result[VARIANT_BYTE_INDEX] |= 0x80 + + return +} + +/* +Stamp an array of 16 bytes as being a valid version 8 UUID. + +Per the specification, all version 8 UUIDs are either for experimental or +vendor-specific purposes. This procedure allows for converting arbitrary data +into custom UUIDs. + +Inputs: +- array: An array of 16 bytes. + +Returns: +- result: A valid version 8 UUID. +*/ +stamp_v8_array :: proc(array: [16]u8) -> (result: Identifier) { + result = transmute(Identifier)array + + result[VERSION_BYTE_INDEX] &= 0x0F + result[VERSION_BYTE_INDEX] |= 0x80 + + result[VARIANT_BYTE_INDEX] &= 0x3F + result[VARIANT_BYTE_INDEX] |= 0x80 + + return +} + +/* +Stamp a slice of bytes as being a valid version 8 UUID. + +If the slice is less than 16 bytes long, the data available will be used. +If it is longer than 16 bytes, only the first 16 will be used. + +This procedure does not modify the underlying slice. + +Per the specification, all version 8 UUIDs are either for experimental or +vendor-specific purposes. This procedure allows for converting arbitrary data +into custom UUIDs. + +Inputs: +- slice: A slice of bytes. + +Returns: +- result: A valid version 8 UUID. +*/ +stamp_v8_slice :: proc(slice: []u8) -> (result: Identifier) { + runtime.mem_copy_non_overlapping(&result, &slice[0], min(16, len(slice))) + + result[VERSION_BYTE_INDEX] &= 0x0F + result[VERSION_BYTE_INDEX] |= 0x80 + + result[VARIANT_BYTE_INDEX] &= 0x3F + result[VARIANT_BYTE_INDEX] |= 0x80 + + return +} + +stamp_v8 :: proc { + stamp_v8_int, + stamp_v8_array, + stamp_v8_slice, +} diff --git a/tests/core/encoding/uuid/test_core_uuid.odin b/tests/core/encoding/uuid/test_core_uuid.odin index aeb73c841..9f66b316d 100644 --- a/tests/core/encoding/uuid/test_core_uuid.odin +++ b/tests/core/encoding/uuid/test_core_uuid.odin @@ -18,7 +18,13 @@ test_version_and_variant :: proc(t: ^testing.T) { v5 := uuid_legacy.generate_v5(uuid.Namespace_DNS, "") v6 := uuid.generate_v6() v7 := uuid.generate_v7() - v8 := uuid.generate_v8_hash(uuid.Namespace_DNS, "", .SHA512) + + _v8_array: [16]u8 = 0xff + v8_int := uuid.stamp_v8(max(u128)) + v8_array := uuid.stamp_v8(_v8_array) + v8_slice := uuid.stamp_v8(_v8_array[:]) + + v8_hash := uuid.generate_v8_hash(uuid.Namespace_DNS, "", .SHA512) testing.expect_value(t, uuid.version(v1), 1) testing.expect_value(t, uuid.variant(v1), uuid.Variant_Type.RFC_4122) @@ -32,8 +38,16 @@ test_version_and_variant :: proc(t: ^testing.T) { testing.expect_value(t, uuid.variant(v6), uuid.Variant_Type.RFC_4122) testing.expect_value(t, uuid.version(v7), 7) testing.expect_value(t, uuid.variant(v7), uuid.Variant_Type.RFC_4122) - testing.expect_value(t, uuid.version(v8), 8) - testing.expect_value(t, uuid.variant(v8), uuid.Variant_Type.RFC_4122) + + testing.expect_value(t, uuid.version(v8_int), 8) + testing.expect_value(t, uuid.variant(v8_int), uuid.Variant_Type.RFC_4122) + testing.expect_value(t, uuid.version(v8_array), 8) + testing.expect_value(t, uuid.variant(v8_array), uuid.Variant_Type.RFC_4122) + testing.expect_value(t, uuid.version(v8_slice), 8) + testing.expect_value(t, uuid.variant(v8_slice), uuid.Variant_Type.RFC_4122) + + testing.expect_value(t, uuid.version(v8_hash), 8) + testing.expect_value(t, uuid.variant(v8_hash), uuid.Variant_Type.RFC_4122) } @(test) From 4481f9c695061782f8ff086fc13c58f13ab43023 Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Sat, 22 Jun 2024 17:07:18 -0400 Subject: [PATCH 029/129] Clarify some `uuid` legacy documentation --- core/encoding/uuid/legacy/legacy.odin | 28 ++++++++++++--------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/core/encoding/uuid/legacy/legacy.odin b/core/encoding/uuid/legacy/legacy.odin index 44057f1f8..d5f3df617 100644 --- a/core/encoding/uuid/legacy/legacy.odin +++ b/core/encoding/uuid/legacy/legacy.odin @@ -18,13 +18,12 @@ VARIANT_BYTE_INDEX :: uuid.VARIANT_BYTE_INDEX /* Generate a version 3 UUID. -This UUID is generated from a name within a namespace. -MD5 is used to hash the name with the namespace to produce the UUID. +This UUID is generated with a MD5 hash of a name and a namespace. Inputs: -- namespace: Another `Identifier` that is used to represent the underlying namespace. +- namespace: An `Identifier` that is used to represent the underlying namespace. This can be any one of the `Namespace_*` values provided in the `uuid` package. -- name: The byte slice used to generate the name on top of the namespace. +- name: The byte slice which will be hashed with the namespace. Returns: - result: The generated UUID. @@ -55,13 +54,12 @@ generate_v3_bytes :: proc( /* Generate a version 3 UUID. -This UUID is generated from a name within a namespace. -MD5 is used to hash the name with the namespace to produce the UUID. +This UUID is generated with a MD5 hash of a name and a namespace. Inputs: -- namespace: Another `Identifier` that is used to represent the underlying namespace. +- namespace: An `Identifier` that is used to represent the underlying namespace. This can be any one of the `Namespace_*` values provided in the `uuid` package. -- name: The string used to generate the name on top of the namespace. +- name: The string which will be hashed with the namespace. Returns: - result: The generated UUID. @@ -83,13 +81,12 @@ generate_v3 :: proc { /* Generate a version 5 UUID. -This UUID is generated from a name within a namespace. -SHA1 is used to hash the name with the namespace to produce the UUID. +This UUID is generated with a SHA1 hash of a name and a namespace. Inputs: -- namespace: Another `Identifier` that is used to represent the underlying namespace. +- namespace: An `Identifier` that is used to represent the underlying namespace. This can be any one of the `Namespace_*` values provided in the `uuid` package. -- name: The byte slice used to generate the name on top of the namespace. +- name: The byte slice which will be hashed with the namespace. Returns: - result: The generated UUID. @@ -123,13 +120,12 @@ generate_v5_bytes :: proc( /* Generate a version 5 UUID. -This UUID is generated from a name within a namespace. -SHA1 is used to hash the name with the namespace to produce the UUID. +This UUID is generated with a SHA1 hash of a name and a namespace. Inputs: -- namespace: Another `Identifier` that is used to represent the underlying namespace. +- namespace: An `Identifier` that is used to represent the underlying namespace. This can be any one of the `Namespace_*` values provided in the `uuid` package. -- name: The string used to generate the name on top of the namespace. +- name: The string which will be hashed with the namespace. Returns: - result: The generated UUID. From 8a4a3ed66e9fc2e4ecc398acb616a6c3b756515e Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Sat, 22 Jun 2024 17:58:42 -0400 Subject: [PATCH 030/129] Change how `Time` is constructed in `uuid` --- core/encoding/uuid/reading.odin | 8 ++-- tests/core/encoding/uuid/test_core_uuid.odin | 48 ++++++++++---------- 2 files changed, 27 insertions(+), 29 deletions(-) diff --git a/core/encoding/uuid/reading.odin b/core/encoding/uuid/reading.odin index d41606f63..ab08300b0 100644 --- a/core/encoding/uuid/reading.odin +++ b/core/encoding/uuid/reading.odin @@ -163,8 +163,7 @@ Returns: - timestamp: The timestamp of the UUID. */ time_v1 :: proc "contextless" (id: Identifier) -> (timestamp: time.Time) { - delta := cast(time.Duration)(raw_time_v1(id) - HNS_INTERVALS_BETWEEN_GREG_AND_UNIX) * 100 - return time.time_add({}, delta) + return { _nsec = cast(i64)(raw_time_v1(id) - HNS_INTERVALS_BETWEEN_GREG_AND_UNIX) * 100 } } /* @@ -195,8 +194,7 @@ Returns: - timestamp: The timestamp, in 100-nanosecond intervals since 1582-10-15. */ time_v6 :: proc "contextless" (id: Identifier) -> (timestamp: time.Time) { - delta := cast(time.Duration)(raw_time_v6(id) - HNS_INTERVALS_BETWEEN_GREG_AND_UNIX) * 100 - return time.time_add({}, delta) + return { _nsec = cast(i64)(raw_time_v6(id) - HNS_INTERVALS_BETWEEN_GREG_AND_UNIX) * 100 } } /* @@ -223,7 +221,7 @@ Returns: - timestamp: The timestamp, in milliseconds since the UNIX epoch. */ time_v7 :: proc "contextless" (id: Identifier) -> (timestamp: time.Time) { - return time.time_add({}, cast(time.Duration)(raw_time_v7(id) * 1e6)) + return { _nsec = cast(i64)raw_time_v7(id) * 1e6 } } /* diff --git a/tests/core/encoding/uuid/test_core_uuid.odin b/tests/core/encoding/uuid/test_core_uuid.odin index 9f66b316d..619534a7f 100644 --- a/tests/core/encoding/uuid/test_core_uuid.odin +++ b/tests/core/encoding/uuid/test_core_uuid.odin @@ -144,9 +144,9 @@ test_legacy_namespaced_uuids :: proc(t: ^testing.T) { test_v1 :: proc(t: ^testing.T) { context.random_generator = crypto.random_generator() - point_a := time.time_add({}, 1 * time.Second) - point_b := time.time_add({}, 3 * time.Second) - point_c := time.time_add({}, 5 * time.Second) + point_a := time.unix(1, 0) + point_b := time.unix(3, 0) + point_c := time.unix(5, 0) CLOCK :: 0x3A1A mac := [6]u8{0xFF, 0x10, 0xAA, 0x55, 0x01, 0xFF} @@ -179,9 +179,9 @@ test_v1 :: proc(t: ^testing.T) { test_v6 :: proc(t: ^testing.T) { context.random_generator = crypto.random_generator() - point_a := time.time_add({}, 1 * time.Second) - point_b := time.time_add({}, 3 * time.Second) - point_c := time.time_add({}, 5 * time.Second) + point_a := time.unix(1, 0) + point_b := time.unix(3, 0) + point_c := time.unix(5, 0) CLOCK :: 0x3A1A mac := [6]u8{0xFF, 0x10, 0xAA, 0x55, 0x01, 0xFF} @@ -214,9 +214,9 @@ test_v6 :: proc(t: ^testing.T) { test_v7 :: proc(t: ^testing.T) { context.random_generator = crypto.random_generator() - point_a := time.time_add({}, 1 * time.Second) - point_b := time.time_add({}, 3 * time.Second) - point_c := time.time_add({}, 5 * time.Second) + point_a := time.unix(1, 0) + point_b := time.unix(3, 0) + point_c := time.unix(5, 0) v7_a := uuid.generate_v7(point_a) v7_b := uuid.generate_v7(point_b) @@ -245,11 +245,11 @@ test_sorting_v1 :: proc(t: ^testing.T) { // They are incapable of sorting properly by the nature their time bit ordering. // // Something is very strange if they do sort correctly. - point_a := time.time_add({}, 1 * time.Second) - point_b := time.time_add({}, 3 * time.Second) - point_c := time.time_add({}, 5 * time.Second) - point_d := time.time_add({}, 7 * time.Second) - point_e := time.time_add({}, 11 * time.Second) + point_a := time.unix(1, 0) + point_b := time.unix(3, 0) + point_c := time.unix(5, 0) + point_d := time.unix(7, 0) + point_e := time.unix(11, 0) mac: [6]byte v1_a := uuid.generate_v1(0, mac, point_a) @@ -283,11 +283,11 @@ test_sorting_v1 :: proc(t: ^testing.T) { test_sorting_v6 :: proc(t: ^testing.T) { context.random_generator = crypto.random_generator() - point_a := time.time_add({}, 1 * time.Second) - point_b := time.time_add({}, 3 * time.Second) - point_c := time.time_add({}, 5 * time.Second) - point_d := time.time_add({}, 7 * time.Second) - point_e := time.time_add({}, 11 * time.Second) + point_a := time.unix(1, 0) + point_b := time.unix(3, 0) + point_c := time.unix(5, 0) + point_d := time.unix(7, 0) + point_e := time.unix(11, 0) mac: [6]byte v6_a := uuid.generate_v6(0, mac, point_a) @@ -326,11 +326,11 @@ test_sorting_v6 :: proc(t: ^testing.T) { test_sorting_v7 :: proc(t: ^testing.T) { context.random_generator = crypto.random_generator() - point_a := time.time_add({}, 1 * time.Second) - point_b := time.time_add({}, 3 * time.Second) - point_c := time.time_add({}, 5 * time.Second) - point_d := time.time_add({}, 7 * time.Second) - point_e := time.time_add({}, 11 * time.Second) + point_a := time.unix(1, 0) + point_b := time.unix(3, 0) + point_c := time.unix(5, 0) + point_d := time.unix(7, 0) + point_e := time.unix(11, 0) v7_a := uuid.generate_v7(point_a) v7_b := uuid.generate_v7(point_b) From ca58d7771b3964e47779b1aad7bfb4c29a17f43a Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Sat, 22 Jun 2024 18:36:42 -0400 Subject: [PATCH 031/129] Use new API `from_nanoseconds` in `uuid` --- core/encoding/uuid/reading.odin | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/encoding/uuid/reading.odin b/core/encoding/uuid/reading.odin index ab08300b0..c91c82465 100644 --- a/core/encoding/uuid/reading.odin +++ b/core/encoding/uuid/reading.odin @@ -163,7 +163,7 @@ Returns: - timestamp: The timestamp of the UUID. */ time_v1 :: proc "contextless" (id: Identifier) -> (timestamp: time.Time) { - return { _nsec = cast(i64)(raw_time_v1(id) - HNS_INTERVALS_BETWEEN_GREG_AND_UNIX) * 100 } + return time.from_nanoseconds(cast(i64)(raw_time_v1(id) - HNS_INTERVALS_BETWEEN_GREG_AND_UNIX) * 100) } /* @@ -194,7 +194,7 @@ Returns: - timestamp: The timestamp, in 100-nanosecond intervals since 1582-10-15. */ time_v6 :: proc "contextless" (id: Identifier) -> (timestamp: time.Time) { - return { _nsec = cast(i64)(raw_time_v6(id) - HNS_INTERVALS_BETWEEN_GREG_AND_UNIX) * 100 } + return time.from_nanoseconds(cast(i64)(raw_time_v6(id) - HNS_INTERVALS_BETWEEN_GREG_AND_UNIX) * 100) } /* @@ -221,7 +221,7 @@ Returns: - timestamp: The timestamp, in milliseconds since the UNIX epoch. */ time_v7 :: proc "contextless" (id: Identifier) -> (timestamp: time.Time) { - return { _nsec = cast(i64)raw_time_v7(id) * 1e6 } + return time.from_nanoseconds(cast(i64)raw_time_v7(id) * 1e6) } /* From 18dadd94e3a91d1eed5938f4998b8b7a71765afb Mon Sep 17 00:00:00 2001 From: Tadeo hepperle Date: Wed, 26 Jun 2024 19:30:21 +0200 Subject: [PATCH 032/129] fix proc parsing --- .../vulkan/_gen/create_vulkan_odin_wrapper.py | 20 +++++++++---------- vendor/vulkan/procedures.odin | 6 +++--- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py b/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py index 65f53758f..2d4d078fa 100644 --- a/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py +++ b/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py @@ -94,15 +94,13 @@ def convert_type(t, prev_name, curr_name): if t == "": return t + if t.startswith("const"): + t = convert_type(t[6:], prev_name, curr_name) + elif t.endswith("*"): - elem = "" pointer = "^" - if t.startswith("const"): - ttype = t[6:len(t)-1] - elem = convert_type(ttype, prev_name, curr_name) - else: - ttype = t[:len(t)-1] - elem = convert_type(ttype, prev_name, curr_name) + ttype = t[:len(t)-1] + elem = convert_type(ttype, prev_name, curr_name) if curr_name.endswith("s") or curr_name.endswith("Table"): if prev_name.endswith("Count") or prev_name.endswith("Counts"): @@ -625,12 +623,14 @@ def parse_procedures(f): for rt, name, fields in data: proc_name = no_vk(name) - pf = [] prev_name = "" - for type_, fname in re.findall(r"(?:\s*|)(.+?)\s*(\w+)(?:,|$)", fields): + for type_, fname, array_len in re.findall(r"(?:\s*|)(.+?)\s*(\w+)(?:\[(\d+)\])?(?:,|$)", fields): curr_name = fix_arg(fname) - pf.append((do_type(type_, prev_name, curr_name), curr_name)) + ty = do_type(type_, prev_name, curr_name) + if array_len != "": + ty = f"^{ty}[{array_len}]" + pf.append((ty, curr_name)) prev_name = curr_name data_fields = ', '.join(["{}: {}".format(n, t) for t, n in pf if t != ""]) diff --git a/vendor/vulkan/procedures.odin b/vendor/vulkan/procedures.odin index 9a27b4f79..bc3ced3dc 100644 --- a/vendor/vulkan/procedures.odin +++ b/vendor/vulkan/procedures.odin @@ -259,7 +259,7 @@ ProcCmdResolveImage2KHR :: #type proc "system ProcCmdSetAlphaToCoverageEnableEXT :: #type proc "system" (commandBuffer: CommandBuffer, alphaToCoverageEnable: b32) ProcCmdSetAlphaToOneEnableEXT :: #type proc "system" (commandBuffer: CommandBuffer, alphaToOneEnable: b32) ProcCmdSetAttachmentFeedbackLoopEnableEXT :: #type proc "system" (commandBuffer: CommandBuffer, aspectMask: ImageAspectFlags) -ProcCmdSetBlendConstants :: #type proc "system" (commandBuffer: CommandBuffer) +ProcCmdSetBlendConstants :: #type proc "system" (commandBuffer: CommandBuffer, blendConstants: ^f32[4]) ProcCmdSetCheckpointNV :: #type proc "system" (commandBuffer: CommandBuffer, pCheckpointMarker: rawptr) ProcCmdSetCoarseSampleOrderNV :: #type proc "system" (commandBuffer: CommandBuffer, sampleOrderType: CoarseSampleOrderTypeNV, customSampleOrderCount: u32, pCustomSampleOrders: [^]CoarseSampleOrderCustomNV) ProcCmdSetColorBlendAdvancedEXT :: #type proc "system" (commandBuffer: CommandBuffer, firstAttachment: u32, attachmentCount: u32, pColorBlendAdvanced: ^ColorBlendAdvancedEXT) @@ -302,8 +302,8 @@ ProcCmdSetEvent2KHR :: #type proc "system ProcCmdSetExclusiveScissorEnableNV :: #type proc "system" (commandBuffer: CommandBuffer, firstExclusiveScissor: u32, exclusiveScissorCount: u32, pExclusiveScissorEnables: [^]b32) ProcCmdSetExclusiveScissorNV :: #type proc "system" (commandBuffer: CommandBuffer, firstExclusiveScissor: u32, exclusiveScissorCount: u32, pExclusiveScissors: [^]Rect2D) ProcCmdSetExtraPrimitiveOverestimationSizeEXT :: #type proc "system" (commandBuffer: CommandBuffer, extraPrimitiveOverestimationSize: f32) -ProcCmdSetFragmentShadingRateEnumNV :: #type proc "system" (commandBuffer: CommandBuffer, shadingRate: FragmentShadingRateNV) -ProcCmdSetFragmentShadingRateKHR :: #type proc "system" (commandBuffer: CommandBuffer, pFragmentSize: ^Extent2D) +ProcCmdSetFragmentShadingRateEnumNV :: #type proc "system" (commandBuffer: CommandBuffer, shadingRate: FragmentShadingRateNV, combinerOps: ^FragmentShadingRateCombinerOpKHR[2]) +ProcCmdSetFragmentShadingRateKHR :: #type proc "system" (commandBuffer: CommandBuffer, pFragmentSize: ^Extent2D, combinerOps: ^FragmentShadingRateCombinerOpKHR[2]) ProcCmdSetFrontFace :: #type proc "system" (commandBuffer: CommandBuffer, frontFace: FrontFace) ProcCmdSetFrontFaceEXT :: #type proc "system" (commandBuffer: CommandBuffer, frontFace: FrontFace) ProcCmdSetLineRasterizationModeEXT :: #type proc "system" (commandBuffer: CommandBuffer, lineRasterizationMode: LineRasterizationModeEXT) From b834bd32f5837edb8ef8325889e1da10737af8c3 Mon Sep 17 00:00:00 2001 From: Tadeo hepperle Date: Wed, 26 Jun 2024 20:31:43 +0200 Subject: [PATCH 033/129] fix typo --- vendor/vulkan/_gen/create_vulkan_odin_wrapper.py | 2 +- vendor/vulkan/procedures.odin | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py b/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py index 2d4d078fa..caebe56a7 100644 --- a/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py +++ b/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py @@ -629,7 +629,7 @@ def parse_procedures(f): curr_name = fix_arg(fname) ty = do_type(type_, prev_name, curr_name) if array_len != "": - ty = f"^{ty}[{array_len}]" + ty = f"^[{array_len}]{ty}" pf.append((ty, curr_name)) prev_name = curr_name diff --git a/vendor/vulkan/procedures.odin b/vendor/vulkan/procedures.odin index bc3ced3dc..bec421f29 100644 --- a/vendor/vulkan/procedures.odin +++ b/vendor/vulkan/procedures.odin @@ -259,7 +259,7 @@ ProcCmdResolveImage2KHR :: #type proc "system ProcCmdSetAlphaToCoverageEnableEXT :: #type proc "system" (commandBuffer: CommandBuffer, alphaToCoverageEnable: b32) ProcCmdSetAlphaToOneEnableEXT :: #type proc "system" (commandBuffer: CommandBuffer, alphaToOneEnable: b32) ProcCmdSetAttachmentFeedbackLoopEnableEXT :: #type proc "system" (commandBuffer: CommandBuffer, aspectMask: ImageAspectFlags) -ProcCmdSetBlendConstants :: #type proc "system" (commandBuffer: CommandBuffer, blendConstants: ^f32[4]) +ProcCmdSetBlendConstants :: #type proc "system" (commandBuffer: CommandBuffer, blendConstants: ^[4]f32) ProcCmdSetCheckpointNV :: #type proc "system" (commandBuffer: CommandBuffer, pCheckpointMarker: rawptr) ProcCmdSetCoarseSampleOrderNV :: #type proc "system" (commandBuffer: CommandBuffer, sampleOrderType: CoarseSampleOrderTypeNV, customSampleOrderCount: u32, pCustomSampleOrders: [^]CoarseSampleOrderCustomNV) ProcCmdSetColorBlendAdvancedEXT :: #type proc "system" (commandBuffer: CommandBuffer, firstAttachment: u32, attachmentCount: u32, pColorBlendAdvanced: ^ColorBlendAdvancedEXT) @@ -302,8 +302,8 @@ ProcCmdSetEvent2KHR :: #type proc "system ProcCmdSetExclusiveScissorEnableNV :: #type proc "system" (commandBuffer: CommandBuffer, firstExclusiveScissor: u32, exclusiveScissorCount: u32, pExclusiveScissorEnables: [^]b32) ProcCmdSetExclusiveScissorNV :: #type proc "system" (commandBuffer: CommandBuffer, firstExclusiveScissor: u32, exclusiveScissorCount: u32, pExclusiveScissors: [^]Rect2D) ProcCmdSetExtraPrimitiveOverestimationSizeEXT :: #type proc "system" (commandBuffer: CommandBuffer, extraPrimitiveOverestimationSize: f32) -ProcCmdSetFragmentShadingRateEnumNV :: #type proc "system" (commandBuffer: CommandBuffer, shadingRate: FragmentShadingRateNV, combinerOps: ^FragmentShadingRateCombinerOpKHR[2]) -ProcCmdSetFragmentShadingRateKHR :: #type proc "system" (commandBuffer: CommandBuffer, pFragmentSize: ^Extent2D, combinerOps: ^FragmentShadingRateCombinerOpKHR[2]) +ProcCmdSetFragmentShadingRateEnumNV :: #type proc "system" (commandBuffer: CommandBuffer, shadingRate: FragmentShadingRateNV, combinerOps: ^[2]FragmentShadingRateCombinerOpKHR) +ProcCmdSetFragmentShadingRateKHR :: #type proc "system" (commandBuffer: CommandBuffer, pFragmentSize: ^Extent2D, combinerOps: ^[2]FragmentShadingRateCombinerOpKHR) ProcCmdSetFrontFace :: #type proc "system" (commandBuffer: CommandBuffer, frontFace: FrontFace) ProcCmdSetFrontFaceEXT :: #type proc "system" (commandBuffer: CommandBuffer, frontFace: FrontFace) ProcCmdSetLineRasterizationModeEXT :: #type proc "system" (commandBuffer: CommandBuffer, lineRasterizationMode: LineRasterizationModeEXT) From aa27cd4b0b7876d028f66fdc92a4636eb9c1dc90 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Thu, 27 Jun 2024 16:14:16 +0200 Subject: [PATCH 034/129] Allow core:odin to parse @(require) import --- core/odin/ast/ast.odin | 1 + core/odin/parser/parser.odin | 3 +++ 2 files changed, 4 insertions(+) diff --git a/core/odin/ast/ast.odin b/core/odin/ast/ast.odin index 229f03d3d..92d00b47c 100644 --- a/core/odin/ast/ast.odin +++ b/core/odin/ast/ast.odin @@ -513,6 +513,7 @@ Package_Decl :: struct { Import_Decl :: struct { using node: Decl, docs: ^Comment_Group, + attributes: [dynamic]^Attribute, // dynamic as parsing will add to them lazily is_using: bool, import_tok: tokenizer.Token, name: tokenizer.Token, diff --git a/core/odin/parser/parser.odin b/core/odin/parser/parser.odin index 6b0aa2888..03fb4d66d 100644 --- a/core/odin/parser/parser.odin +++ b/core/odin/parser/parser.odin @@ -1103,6 +1103,9 @@ parse_attribute :: proc(p: ^Parser, tok: tokenizer.Token, open_kind, close_kind: case ^ast.Foreign_Import_Decl: if d.docs == nil { d.docs = docs } append(&d.attributes, attribute) + case ^ast.Import_Decl: + if d.docs == nil { d.docs = docs } + append(&d.attributes, attribute) case: error(p, decl.pos, "expected a value or foreign declaration after an attribute") free(attribute) From 1c199f52d623898dd68405558e9694a6a6fc60a7 Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Thu, 27 Jun 2024 19:17:07 +0200 Subject: [PATCH 035/129] tlsf: destroy first pool & properly zero memory --- core/mem/tlsf/tlsf.odin | 13 +++++++++---- core/mem/tlsf/tlsf_internal.odin | 4 ++-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/core/mem/tlsf/tlsf.odin b/core/mem/tlsf/tlsf.odin index 76ecbb4b1..8ec5f52b7 100644 --- a/core/mem/tlsf/tlsf.odin +++ b/core/mem/tlsf/tlsf.odin @@ -97,6 +97,10 @@ init :: proc{init_from_buffer, init_from_allocator} destroy :: proc(control: ^Allocator) { if control == nil { return } + if control.pool.allocator.procedure != nil { + runtime.delete(control.pool.data, control.pool.allocator) + } + // No need to call `pool_remove` or anything, as they're they're embedded in the backing memory. // We do however need to free the `Pool` tracking entities and the backing memory itself. // As `Allocator` is embedded in the first backing slice, the `control` pointer will be @@ -132,8 +136,9 @@ allocator_proc :: proc(allocator_data: rawptr, mode: runtime.Allocator_Mode, return nil, nil case .Free_All: - clear(control) - return nil, nil + // NOTE: this doesn't work right at the moment, Jeroen has it on his to-do list :) + // clear(control) + return nil, .Mode_Not_Implemented case .Resize: return resize(control, old_memory, uint(old_size), uint(size), uint(alignment)) @@ -144,7 +149,7 @@ allocator_proc :: proc(allocator_data: rawptr, mode: runtime.Allocator_Mode, case .Query_Features: set := (^runtime.Allocator_Mode_Set)(old_memory) if set != nil { - set^ = {.Alloc, .Alloc_Non_Zeroed, .Free, .Free_All, .Resize, .Resize_Non_Zeroed, .Query_Features} + set^ = {.Alloc, .Alloc_Non_Zeroed, .Free, /* .Free_All, */ .Resize, .Resize_Non_Zeroed, .Query_Features} } return nil, nil @@ -153,4 +158,4 @@ allocator_proc :: proc(allocator_data: rawptr, mode: runtime.Allocator_Mode, } return nil, nil -} \ No newline at end of file +} diff --git a/core/mem/tlsf/tlsf_internal.odin b/core/mem/tlsf/tlsf_internal.odin index 6f33e516c..9b270d338 100644 --- a/core/mem/tlsf/tlsf_internal.odin +++ b/core/mem/tlsf/tlsf_internal.odin @@ -630,7 +630,7 @@ alloc_bytes_non_zeroed :: proc(control: ^Allocator, size: uint, align: uint) -> @(require_results) alloc_bytes :: proc(control: ^Allocator, size: uint, align: uint) -> (res: []byte, err: runtime.Allocator_Error) { res, err = alloc_bytes_non_zeroed(control, size, align) - if err != nil { + if err == nil { intrinsics.mem_zero(raw_data(res), len(res)) } return @@ -735,4 +735,4 @@ resize_non_zeroed :: proc(control: ^Allocator, ptr: rawptr, old_size, new_size: block_trim_used(control, block, adjust) res = ([^]byte)(ptr)[:new_size] return -} \ No newline at end of file +} From a0a48bfe3440a844b3ce2c9e14369e99f50faeae Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Thu, 27 Jun 2024 21:56:26 +0200 Subject: [PATCH 036/129] Fix alignment. --- core/container/rbtree/rbtree.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/container/rbtree/rbtree.odin b/core/container/rbtree/rbtree.odin index 57a68a948..090551367 100644 --- a/core/container/rbtree/rbtree.odin +++ b/core/container/rbtree/rbtree.odin @@ -29,7 +29,7 @@ Tree :: struct($Key: typeid, $Value: typeid) { _root: ^Node(Key, Value), _node_allocator: runtime.Allocator, - _cmp_fn: proc(Key, Key) -> Ordering, + _cmp_fn: proc(Key, Key) -> Ordering, _size: int, } From f22754fc9036cf3c0bb5707e000c5055607ba374 Mon Sep 17 00:00:00 2001 From: jason Date: Thu, 27 Jun 2024 16:29:47 -0400 Subject: [PATCH 037/129] sys/linux: fix some syscalls and types; add more to Sig_Action and Sig_Info; Pid int->i32 --- core/sys/linux/bits.odin | 113 +++++++++++++++++++++++++------------- core/sys/linux/sys.odin | 47 ++++++++++------ core/sys/linux/types.odin | 96 +++++++++++++++++++++++++------- 3 files changed, 181 insertions(+), 75 deletions(-) diff --git a/core/sys/linux/bits.odin b/core/sys/linux/bits.odin index cfae06013..bf7ab4fae 100644 --- a/core/sys/linux/bits.odin +++ b/core/sys/linux/bits.odin @@ -150,44 +150,66 @@ Errno :: enum i32 { RDONLY flag is not present, because it has the value of 0, i.e. it is the default, unless WRONLY or RDWR is specified. */ -Open_Flags_Bits :: enum { - WRONLY = 0, - RDWR = 1, - CREAT = 6, - EXCL = 7, - NOCTTY = 8, - TRUNC = 9, - APPEND = 10, - NONBLOCK = 11, - DSYNC = 12, - ASYNC = 13, - DIRECT = 14, - LARGEFILE = 15, - DIRECTORY = 16, - NOFOLLOW = 17, - NOATIME = 18, - CLOEXEC = 19, - PATH = 21, -} +when ODIN_ARCH != .arm64 && ODIN_ARCH != .arm32 { + Open_Flags_Bits :: enum { + WRONLY = 0, + RDWR = 1, + CREAT = 6, + EXCL = 7, + NOCTTY = 8, + TRUNC = 9, + APPEND = 10, + NONBLOCK = 11, + DSYNC = 12, + ASYNC = 13, + DIRECT = 14, + LARGEFILE = 15, + DIRECTORY = 16, + NOFOLLOW = 17, + NOATIME = 18, + CLOEXEC = 19, + PATH = 21, + } + // https://github.com/torvalds/linux/blob/7367539ad4b0f8f9b396baf02110962333719a48/include/uapi/asm-generic/fcntl.h#L19 + #assert(1 << uint(Open_Flags_Bits.WRONLY) == 0o0000000_1) + #assert(1 << uint(Open_Flags_Bits.RDWR) == 0o0000000_2) + #assert(1 << uint(Open_Flags_Bits.CREAT) == 0o00000_100) + #assert(1 << uint(Open_Flags_Bits.EXCL) == 0o00000_200) + #assert(1 << uint(Open_Flags_Bits.NOCTTY) == 0o00000_400) + #assert(1 << uint(Open_Flags_Bits.TRUNC) == 0o0000_1000) + #assert(1 << uint(Open_Flags_Bits.APPEND) == 0o0000_2000) + #assert(1 << uint(Open_Flags_Bits.NONBLOCK) == 0o0000_4000) + #assert(1 << uint(Open_Flags_Bits.DSYNC) == 0o000_10000) + #assert(1 << uint(Open_Flags_Bits.ASYNC) == 0o000_20000) + #assert(1 << uint(Open_Flags_Bits.DIRECT) == 0o000_40000) + #assert(1 << uint(Open_Flags_Bits.LARGEFILE) == 0o00_100000) + #assert(1 << uint(Open_Flags_Bits.DIRECTORY) == 0o00_200000) + #assert(1 << uint(Open_Flags_Bits.NOFOLLOW) == 0o00_400000) + #assert(1 << uint(Open_Flags_Bits.NOATIME) == 0o0_1000000) + #assert(1 << uint(Open_Flags_Bits.CLOEXEC) == 0o0_2000000) + #assert(1 << uint(Open_Flags_Bits.PATH) == 0o_10000000) -// https://github.com/torvalds/linux/blob/7367539ad4b0f8f9b396baf02110962333719a48/include/uapi/asm-generic/fcntl.h#L19 -#assert(1 << uint(Open_Flags_Bits.WRONLY) == 0o0000000_1) -#assert(1 << uint(Open_Flags_Bits.RDWR) == 0o0000000_2) -#assert(1 << uint(Open_Flags_Bits.CREAT) == 0o00000_100) -#assert(1 << uint(Open_Flags_Bits.EXCL) == 0o00000_200) -#assert(1 << uint(Open_Flags_Bits.NOCTTY) == 0o00000_400) -#assert(1 << uint(Open_Flags_Bits.TRUNC) == 0o0000_1000) -#assert(1 << uint(Open_Flags_Bits.APPEND) == 0o0000_2000) -#assert(1 << uint(Open_Flags_Bits.NONBLOCK) == 0o0000_4000) -#assert(1 << uint(Open_Flags_Bits.DSYNC) == 0o000_10000) -#assert(1 << uint(Open_Flags_Bits.ASYNC) == 0o000_20000) -#assert(1 << uint(Open_Flags_Bits.DIRECT) == 0o000_40000) -#assert(1 << uint(Open_Flags_Bits.LARGEFILE) == 0o00_100000) -#assert(1 << uint(Open_Flags_Bits.DIRECTORY) == 0o00_200000) -#assert(1 << uint(Open_Flags_Bits.NOFOLLOW) == 0o00_400000) -#assert(1 << uint(Open_Flags_Bits.NOATIME) == 0o0_1000000) -#assert(1 << uint(Open_Flags_Bits.CLOEXEC) == 0o0_2000000) -#assert(1 << uint(Open_Flags_Bits.PATH) == 0o_10000000) +} else { + Open_Flags_Bits :: enum { + WRONLY = 0, + RDWR = 1, + CREAT = 6, + EXCL = 7, + NOCTTY = 8, + TRUNC = 9, + APPEND = 10, + NONBLOCK = 11, + DSYNC = 12, + ASYNC = 13, + DIRECTORY = 14, + NOFOLLOW = 15, + DIRECT = 16, + LARGEFILE = 17, + NOATIME = 18, + CLOEXEC = 19, + PATH = 21, + } +} /* Bits for FD_Flags bitset @@ -867,7 +889,7 @@ Wait_Option :: enum { WSTOPPED = 1, WEXITED = 2, WCONTINUED = 3, - WNOWAIT = 24, + WNOWAIT = 24, // // For processes created using clone __WNOTHREAD = 29, __WALL = 30, @@ -946,9 +968,22 @@ Sig_Stack_Flag :: enum i32 { AUTODISARM = 31, } +Sig_Action_Flag :: enum u32 { + NOCLDSTOP = 0, + NOCLDWAIT = 1, + SIGINFO = 2, + UNSUPPORTED = 10, + EXPOSE_TAGBITS = 11, + RESTORER = 26, + ONSTACK = 27, + RESTART = 28, + NODEFER = 30, + RESETHAND = 31, +} + /* Type of socket to create - - For TCP you want to use SOCK_STREAM + - For TCP you want to use SOCK_STREAM - For UDP you want to use SOCK_DGRAM Also see `Protocol` */ diff --git a/core/sys/linux/sys.odin b/core/sys/linux/sys.odin index 171829cde..ed40719bf 100644 --- a/core/sys/linux/sys.odin +++ b/core/sys/linux/sys.odin @@ -69,7 +69,7 @@ close :: proc "contextless" (fd: Fd) -> (Errno) { stat :: proc "contextless" (filename: cstring, stat: ^Stat) -> (Errno) { when size_of(int) == 8 { when ODIN_ARCH == .arm64 { - ret := syscall(SYS_fstatat, AT_FDCWD, cast(rawptr) filename, stat) + ret := syscall(SYS_fstatat, AT_FDCWD, cast(rawptr) filename, stat, 0) return Errno(-ret) } else { ret := syscall(SYS_stat, cast(rawptr) filename, stat) @@ -200,10 +200,25 @@ brk :: proc "contextless" (addr: uintptr) -> (Errno) { return Errno(-ret) } +/* + Returns from signal handlers on some archs. +*/ +rt_sigreturn :: proc "c" () -> ! { + intrinsics.syscall(uintptr(SYS_rt_sigreturn)) + unreachable() +} + /* Alter an action taken by a process. */ -rt_sigaction :: proc "contextless" (sig: Signal, sigaction: ^Sig_Action, old_sigaction: ^Sig_Action) -> Errno { +rt_sigaction :: proc "contextless" (sig: Signal, sigaction: ^Sig_Action($T), old_sigaction: ^Sig_Action) -> Errno { + // NOTE(jason): It appears that the restorer is required for i386 and amd64 + when ODIN_ARCH == .i386 || ODIN_ARCH == .amd64 { + sigaction.flags += {.RESTORER} + } + if sigaction != nil && sigaction.restorer == nil && .RESTORER in sigaction.flags { + sigaction.restorer = rt_sigreturn + } ret := syscall(SYS_rt_sigaction, sig, sigaction, old_sigaction, size_of(Sig_Set)) return Errno(-ret) } @@ -1123,7 +1138,7 @@ ftruncate :: proc "contextless" (fd: Fd, length: i64) -> (Errno) { ret := syscall(SYS_ftruncate64, fd, compat64_arg_pair(length)) return Errno(-ret) } else { - ret := syscall(SYS_truncate, fd, compat64_arg_pair(length)) + ret := syscall(SYS_ftruncate, fd, compat64_arg_pair(length)) return Errno(-ret) } } @@ -1231,7 +1246,7 @@ creat :: proc "contextless" (name: cstring, mode: Mode) -> (Fd, Errno) { */ link :: proc "contextless" (target: cstring, linkpath: cstring) -> (Errno) { when ODIN_ARCH == .arm64 { - ret := syscall(SYS_linkat, AT_FDCWD, cast(rawptr) target, AT_FDCWD, cast(rawptr) linkpath) + ret := syscall(SYS_linkat, AT_FDCWD, cast(rawptr) target, AT_FDCWD, cast(rawptr) linkpath, 0) return Errno(-ret) } else { ret := syscall(SYS_link, cast(rawptr) target, cast(rawptr) linkpath) @@ -1261,7 +1276,7 @@ unlink :: proc "contextless" (name: cstring) -> (Errno) { */ symlink :: proc "contextless" (target: cstring, linkpath: cstring) -> (Errno) { when ODIN_ARCH == .arm64 { - ret := syscall(SYS_symlinkat, AT_FDCWD, cast(rawptr) target, cast(rawptr) linkpath) + ret := syscall(SYS_symlinkat, cast(rawptr) target, AT_FDCWD, cast(rawptr) linkpath) return Errno(-ret) } else { ret := syscall(SYS_symlink, cast(rawptr) target, cast(rawptr) linkpath) @@ -1291,7 +1306,7 @@ readlink :: proc "contextless" (name: cstring, buf: []u8) -> (int, Errno) { */ chmod :: proc "contextless" (name: cstring, mode: Mode) -> (Errno) { when ODIN_ARCH == .arm64 { - ret := syscall(SYS_fchmodat, cast(rawptr) name, transmute(u32) mode, 0) + ret := syscall(SYS_fchmodat, AT_FDCWD, cast(rawptr) name, transmute(u32) mode) return Errno(-ret) } else { ret := syscall(SYS_chmod, cast(rawptr) name, transmute(u32) mode) @@ -2476,8 +2491,8 @@ tgkill :: proc "contextless" (tgid, tid: Pid, sig: Signal) -> (Errno) { Wait on process, process group or pid file descriptor. Available since Linux 2.6.10. */ -waitid :: proc "contextless" (id_type: Id_Type, id: Id, sig_info: ^Sig_Info, options: Wait_Options) -> (Errno) { - ret := syscall(SYS_waitid, id_type, id, sig_info, transmute(i32) options) +waitid :: proc "contextless" (id_type: Id_Type, id: Id, sig_info: ^Sig_Info, options: Wait_Options, rusage: ^RUsage) -> (Errno) { + ret := syscall(SYS_waitid, id_type, id, sig_info, transmute(i32) options, rusage) return Errno(-ret) } @@ -2504,7 +2519,7 @@ waitid :: proc "contextless" (id_type: Id_Type, id: Id, sig_info: ^Sig_Info, opt Available since Linux 2.6.16. */ openat :: proc "contextless" (fd: Fd, name: cstring, flags: Open_Flags, mode: Mode = {}) -> (Fd, Errno) { - ret := syscall(SYS_openat, fd, AT_FDCWD, transmute(uintptr) name, transmute(u32) mode) + ret := syscall(SYS_openat, fd, transmute(uintptr) name, transmute(u32) flags, transmute(u32) mode) return errno_unwrap(ret, Fd) } @@ -2583,8 +2598,8 @@ linkat :: proc "contextless" (target_dirfd: Fd, oldpath: cstring, link_dirfd: Fd Create a symbolic link at specified dirfd. Available since Linux 2.6.16. */ -symlinkat :: proc "contextless" (dirfd: Fd, target: cstring, linkpath: cstring) -> (Errno) { - ret := syscall(SYS_symlinkat, dirfd, cast(rawptr) target, cast(rawptr) linkpath) +symlinkat :: proc "contextless" (target: cstring, dirfd: Fd, linkpath: cstring) -> (Errno) { + ret := syscall(SYS_symlinkat, cast(rawptr) target, dirfd, cast(rawptr) linkpath) return Errno(-ret) } @@ -2619,13 +2634,13 @@ faccessat :: proc "contextless" (dirfd: Fd, name: cstring, mode: Mode = F_OK) -> Wait for events on a file descriptor. Available since Linux 2.6.16. */ -ppoll :: proc "contextless" (fds: []Poll_Fd, timeout: ^Time_Spec, sigmask: ^Sig_Set) -> (Errno) { +ppoll :: proc "contextless" (fds: []Poll_Fd, timeout: ^Time_Spec, sigmask: ^Sig_Set) -> (i32, Errno) { when size_of(int) == 8 { ret := syscall(SYS_ppoll, raw_data(fds), len(fds), timeout, sigmask, size_of(Sig_Set)) - return Errno(-ret) + return errno_unwrap(ret, i32) } else { ret := syscall(SYS_ppoll_time64, raw_data(fds), len(fds), timeout, sigmask, size_of(Sig_Set)) - return Errno(-ret) + return errno_unwrap(ret, i32) } } @@ -2808,8 +2823,8 @@ getrandom :: proc "contextless" (buf: []u8, flags: Get_Random_Flags) -> (int, Er Execute program relative to a directory file descriptor. Available since Linux 3.19. */ -execveat :: proc "contextless" (dirfd: Fd, name: cstring, argv: [^]cstring, envp: [^]cstring) -> (Errno) { - ret := syscall(SYS_execveat, dirfd, cast(rawptr) name, cast(rawptr) argv, cast(rawptr) envp) +execveat :: proc "contextless" (dirfd: Fd, name: cstring, argv: [^]cstring, envp: [^]cstring, flags: FD_Flags = {}) -> (Errno) { + ret := syscall(SYS_execveat, dirfd, cast(rawptr) name, cast(rawptr) argv, cast(rawptr) envp, transmute(i32) flags) return Errno(-ret) } diff --git a/core/sys/linux/types.odin b/core/sys/linux/types.odin index 5053e1e1c..e3fe67a9b 100644 --- a/core/sys/linux/types.odin +++ b/core/sys/linux/types.odin @@ -18,7 +18,7 @@ Gid :: distinct u32 /* Type for Process IDs, Thread IDs, Thread group ID. */ -Pid :: distinct int +Pid :: distinct i32 /* Type for any of: pid, pidfd, pgid. @@ -89,11 +89,11 @@ FD_Flags :: bit_set[FD_Flags_Bits; i32] Represents file's permission and status bits **Example:** When you're passing a value of this type the recommended usage is: - + ``` linux.Mode{.S_IXOTH, .S_IROTH} | linux.S_IRWXU | linux.S_IRWXG ``` - + This would generate a mode that has full permissions for the file's owner and group, and only "read" and "execute" bits for others. @@ -151,9 +151,9 @@ when ODIN_ARCH == .amd64 { size: i64, blksize: uint, blocks: u64, - atim: Time_Spec, - mtim: Time_Spec, - ctim: Time_Spec, + atime: Time_Spec, + mtime: Time_Spec, + ctime: Time_Spec, ino: Inode, } } @@ -495,16 +495,15 @@ Pid_FD_Flags :: bit_set[Pid_FD_Flags_Bits; i32] // 1. Odin's bitfields start from 0, whereas signals start from 1 // 2. It's unclear how bitfields act in terms of ABI (are they an array of ints or an array of longs?). // it makes a difference because ARM is big endian. -@private _SIGSET_NWORDS :: (1024 / (8 * size_of(uint))) +@private _SIGSET_NWORDS :: (8 / size_of(uint)) Sig_Set :: [_SIGSET_NWORDS]uint @private SI_MAX_SIZE :: 128 -@private SI_ARCH_PREAMBLE :: 3 * size_of(i32) -@private SI_PAD_SIZE :: (SI_MAX_SIZE - SI_ARCH_PREAMBLE) / size_of(i32) -@private SI_TIMER_PAD_SIZE :: size_of(Uid) - size_of(i32) +@private SI_ARCH_PREAMBLE :: 4 * size_of(i32) +@private SI_PAD_SIZE :: SI_MAX_SIZE - SI_ARCH_PREAMBLE Sig_Handler_Fn :: #type proc "c" (sig: Signal) -Sig_Restore_Fn :: #type proc "c" () +Sig_Restore_Fn :: #type proc "c" () -> ! Sig_Info :: struct #packed { signo: Signal, @@ -518,8 +517,9 @@ Sig_Info :: struct #packed { uid: Uid, /* sender's uid */ }, using _timer: struct { - timerid: i32, /* timer id */ + timerid: i32, /* timer id */ overrun: i32, /* overrun count */ + value: Sig_Val, /* timer value */ }, /* POSIX.1b signals */ using _rt: struct { @@ -528,8 +528,8 @@ Sig_Info :: struct #packed { }, /* SIGCHLD */ using _sigchld: struct { - _pid1: Pid, /* which child */ - _uid1: Uid, /* sender's uid */ + _pid1: Pid, /* which child */ + _uid1: Uid, /* sender's uid */ status: i32, /* exit code */ utime: uint, stime: uint, //clock_t @@ -537,7 +537,24 @@ Sig_Info :: struct #packed { /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ using _sigfault: struct { addr: rawptr, /* faulting insn/memory ref. */ - addr_lsb: i16, /* LSB of the reported address */ + using _: struct #raw_union { + trapno: i32, /* Trap number that caused signal */ + addr_lsb: i16, /* LSB of the reported address */ + using _addr_bnd: struct { + _pad2: u64, + lower: rawptr, /* lower bound during fault */ + upper: rawptr, /* upper bound during fault */ + }, + using _addr_pkey: struct { + _pad3: u64, + pkey: u32, /* protection key on PTE that faulted */ + }, + using _perf: struct { + perf_data: u64, + perf_type: u32, + perf_flags: u32, + }, + }, }, /* SIGPOLL */ using _sigpoll: struct { @@ -547,12 +564,43 @@ Sig_Info :: struct #packed { /* SIGSYS */ using _sigsys: struct { call_addr: rawptr, /* calling user insn */ - syscall: i32, /* triggering system call number */ - arch: u32, /* AUDIT_ARCH_* of syscall */ + syscall: i32, /* triggering system call number */ + arch: u32, /* AUDIT_ARCH_* of syscall */ }, }, } +#assert(size_of(Sig_Info) == 128) +when ODIN_ARCH == .amd64 || ODIN_ARCH == .arm64 { + #assert(offset_of(Sig_Info, signo) == 0x00) + #assert(offset_of(Sig_Info, errno) == 0x04) + #assert(offset_of(Sig_Info, code) == 0x08) + #assert(offset_of(Sig_Info, pid) == 0x10) + #assert(offset_of(Sig_Info, uid) == 0x14) + #assert(offset_of(Sig_Info, timerid) == 0x10) + #assert(offset_of(Sig_Info, overrun) == 0x14) + #assert(offset_of(Sig_Info, value) == 0x18) + #assert(offset_of(Sig_Info, status) == 0x18) + #assert(offset_of(Sig_Info, utime) == 0x20) + #assert(offset_of(Sig_Info, stime) == 0x28) + #assert(offset_of(Sig_Info, addr) == 0x10) + #assert(offset_of(Sig_Info, addr_lsb) == 0x18) + #assert(offset_of(Sig_Info, trapno) == 0x18) + #assert(offset_of(Sig_Info, lower) == 0x20) + #assert(offset_of(Sig_Info, upper) == 0x28) + #assert(offset_of(Sig_Info, pkey) == 0x20) + #assert(offset_of(Sig_Info, perf_data) == 0x18) + #assert(offset_of(Sig_Info, perf_type) == 0x20) + #assert(offset_of(Sig_Info, perf_flags) == 0x24) + #assert(offset_of(Sig_Info, band) == 0x10) + #assert(offset_of(Sig_Info, fd) == 0x18) + #assert(offset_of(Sig_Info, call_addr) == 0x10) + #assert(offset_of(Sig_Info, syscall) == 0x18) + #assert(offset_of(Sig_Info, arch) == 0x1C) +} else { + // TODO +} + SIGEV_MAX_SIZE :: 64 SIGEV_PAD_SIZE :: ((SIGEV_MAX_SIZE-size_of(i32)*2+size_of(Sig_Val))/size_of(i32)) @@ -583,12 +631,20 @@ Sig_Stack :: struct { size: uintptr, } +Sig_Action_Special :: enum uint { + SIG_DFL = 0, + SIG_IGN = 1, + SIG_ERR = ~uint(0), +} + +Sig_Action_Flags :: bit_set[Sig_Action_Flag; uint] Sig_Action :: struct($T: typeid) { using _u: struct #raw_union { handler: Sig_Handler_Fn, sigaction: #type proc "c" (sig: Signal, si: ^Sig_Info, ctx: ^T), + special: Sig_Action_Special, }, - flags: uint, + flags: Sig_Action_Flags, restorer: Sig_Restore_Fn, mask: Sig_Set, } @@ -733,7 +789,7 @@ RLimit :: struct { /* Structure representing how much of each resource got used. -*/ +*/ RUsage :: struct { utime: Time_Val, stime: Time_Val, @@ -813,7 +869,7 @@ when size_of(int) == 8 || ODIN_ARCH == .i386 { cpid: Pid, lpid: Pid, nattach: uint, - _: [2]uint, + _: [2]uint, } } From f24f72c280df305175653f912f1a7a078c2d101b Mon Sep 17 00:00:00 2001 From: jason Date: Thu, 27 Jun 2024 17:14:48 -0400 Subject: [PATCH 038/129] convert all to use sys/linux over sys/unix; new implementations for pipe, process and env --- core/os/os2/env_linux.odin | 219 +++++++++++++++- core/os/os2/errors.odin | 16 ++ core/os/os2/errors_linux.odin | 287 +++++++++++---------- core/os/os2/file.odin | 7 +- core/os/os2/file_linux.odin | 388 ++++++++++++++++------------ core/os/os2/heap_linux.odin | 28 +- core/os/os2/path_linux.odin | 156 +++++------ core/os/os2/pipe_linux.odin | 12 +- core/os/os2/process.odin | 88 ++++--- core/os/os2/process_linux.odin | 428 +++++++++++++++++++++++++++++++ core/os/os2/process_windows.odin | 67 +++++ core/os/os2/stat_linux.odin | 116 ++------- 12 files changed, 1269 insertions(+), 543 deletions(-) create mode 100644 core/os/os2/process_linux.odin create mode 100644 core/os/os2/process_windows.odin diff --git a/core/os/os2/env_linux.odin b/core/os/os2/env_linux.odin index eb463f22c..99dd00d90 100644 --- a/core/os/os2/env_linux.odin +++ b/core/os/os2/env_linux.odin @@ -2,29 +2,230 @@ package os2 import "base:runtime" +import "base:intrinsics" + +import "core:sync" +import "core:slice" +import "core:strings" + +// TODO: IF NO_CRT: +// Override the libc environment functions' weak linkage to +// allow us to interact with 3rd party code that DOES link +// to libc. Otherwise, our environment can be out of sync. +// ELSE: +// Just use the libc. + +NOT_FOUND :: -1 + +// the environment is a 0 delimited list of = strings +_env: [dynamic]string + +_env_mutex: sync.Mutex + +// We need to be able to figure out if the environment variable +// is contained in the original environment or not. This also +// serves as a flag to determine if we have built _env. +_org_env_begin: uintptr +_org_env_end: uintptr + +// Returns value + index location into _env +// or -1 if not found +_lookup :: proc(key: string) -> (value: string, idx: int) { + sync.mutex_lock(&_env_mutex) + defer sync.mutex_unlock(&_env_mutex) + + for entry, i in _env { + if k, v := _kv_from_entry(entry); k == key { + return v, i + } + } + return "", -1 +} _lookup_env :: proc(key: string, allocator: runtime.Allocator) -> (value: string, found: bool) { - //TODO + if _org_env_begin == 0 { + _build_env() + } + + if v, idx := _lookup(key); idx != -1 { + found = true + value, _ = clone_string(v, allocator) + } return } -_set_env :: proc(key, value: string) -> bool { - //TODO - return false +_set_env :: proc(key, v_new: string) -> bool { + if _org_env_begin == 0 { + _build_env() + } + + // all key values are stored as "key=value\x00" + kv_size := len(key) + len(v_new) + 2 + if v_curr, idx := _lookup(key); idx != NOT_FOUND { + if v_curr == v_new { + return true + } + sync.mutex_lock(&_env_mutex) + defer sync.mutex_unlock(&_env_mutex) + + unordered_remove(&_env, idx) + + if !_is_in_org_env(v_curr) { + // We allocated this key-value. Possibly resize and + // overwrite the value only. Otherwise, treat as if it + // wasn't in the environment in the first place. + k_addr, v_addr := _kv_addr_from_val(v_curr, key) + if len(v_new) > len(v_curr) { + k_addr = ([^]u8)(heap_resize(k_addr, kv_size)) + if k_addr == nil { + return false + } + v_addr = &k_addr[len(key) + 1] + } + intrinsics.mem_copy_non_overlapping(v_addr, raw_data(v_new), len(v_new)) + v_addr[len(v_new)] = 0 + + append(&_env, string(k_addr[:kv_size])) + return true + } + } + + k_addr := ([^]u8)(heap_alloc(kv_size)) + if k_addr == nil { + return false + } + intrinsics.mem_copy_non_overlapping(k_addr, raw_data(key), len(key)) + k_addr[len(key)] = '=' + + val_slice := k_addr[len(key) + 1:] + intrinsics.mem_copy_non_overlapping(&val_slice[0], raw_data(v_new), len(v_new)) + val_slice[len(v_new)] = 0 + + sync.mutex_lock(&_env_mutex) + append(&_env, string(k_addr[:kv_size - 1])) + sync.mutex_unlock(&_env_mutex) + return true } _unset_env :: proc(key: string) -> bool { - //TODO - return false + if _org_env_begin == 0 { + _build_env() + } + + v: string + i: int + if v, i = _lookup(key); i == -1 { + return false + } + + sync.mutex_lock(&_env_mutex) + unordered_remove(&_env, i) + sync.mutex_unlock(&_env_mutex) + + if _is_in_org_env(v) { + return true + } + + // if we got this far, the envrionment variable + // existed AND was allocated by us. + k_addr, _ := _kv_addr_from_val(v, key) + heap_free(k_addr) + return true } _clear_env :: proc() { - //TODO + sync.mutex_lock(&_env_mutex) + defer sync.mutex_unlock(&_env_mutex) + + for kv in _env { + if !_is_in_org_env(kv) { + heap_free(raw_data(kv)) + } + } + clear(&_env) + + // nothing resides in the original environment either + _org_env_begin = ~uintptr(0) + _org_env_end = ~uintptr(0) } _environ :: proc(allocator: runtime.Allocator) -> []string { - //TODO - return nil + if _org_env_begin == 0 { + _build_env() + } + env := make([]string, len(_env), allocator) + + sync.mutex_lock(&_env_mutex) + defer sync.mutex_unlock(&_env_mutex) + for entry, i in _env { + env[i], _ = clone_string(entry, allocator) + } + return env } +// The entire environment is stored as 0 terminated strings, +// so there is no need to clone/free individual variables +export_cstring_environment :: proc(allocator: runtime.Allocator) -> []cstring { + if _org_env_begin == 0 { + // The environment has not been modified, so we can just + // send the original environment + org_env := _get_original_env() + n: int + for ; org_env[n] != nil; n += 1 {} + return slice.clone(org_env[:n + 1], allocator) + } + // NOTE: already terminated by nil pointer via + 1 + env := make([]cstring, len(_env) + 1, allocator) + + sync.mutex_lock(&_env_mutex) + defer sync.mutex_unlock(&_env_mutex) + for entry, i in _env { + env[i] = cstring(raw_data(entry)) + } + return env +} + +_build_env :: proc() { + sync.mutex_lock(&_env_mutex) + defer sync.mutex_unlock(&_env_mutex) + if _org_env_begin != 0 { + return + } + + _env = make(type_of(_env), heap_allocator()) + cstring_env := _get_original_env() + _org_env_begin = uintptr(rawptr(cstring_env[0])) + for i := 0; cstring_env[i] != nil; i += 1 { + bytes := ([^]u8)(cstring_env[i]) + n := len(cstring_env[i]) + _org_env_end = uintptr(&bytes[n]) + append(&_env, string(bytes[:n])) + } +} + +_get_original_env :: #force_inline proc() -> [^]cstring { + // essentially &argv[argc] which should be a nil pointer! + #no_bounds_check env: [^]cstring = &runtime.args__[len(runtime.args__)] + assert(env[0] == nil) + return &env[1] +} + +_kv_from_entry :: #force_inline proc(entry: string) -> (k, v: string) { + eq_idx := strings.index_byte(entry, '=') + if eq_idx == -1 { + return entry, "" + } + return entry[:eq_idx], entry[eq_idx + 1:] +} + +_kv_addr_from_val :: #force_inline proc(val: string, key: string) -> ([^]u8, [^]u8) { + v_addr := raw_data(val) + k_addr := ([^]u8)(&v_addr[-(len(key) + 1)]) + return k_addr, v_addr +} + +_is_in_org_env :: #force_inline proc(env_data: string) -> bool { + addr := uintptr(raw_data(env_data)) + return addr >= _org_env_begin && addr < _org_env_end +} diff --git a/core/os/os2/errors.odin b/core/os/os2/errors.odin index 2c570170d..f7cfdbd3d 100644 --- a/core/os/os2/errors.odin +++ b/core/os/os2/errors.odin @@ -99,3 +99,19 @@ error_string :: proc(ferr: Error) -> string { return "unknown error" } + +print_error :: proc(ferr: Error, msg: string) { + TEMP_ALLOCATOR_GUARD() + err_str := error_string(ferr) + + // msg + ": " + err_str + '\n' + length := len(msg) + 2 + len(err_str) + 1 + buf := make([]u8, length, temp_allocator()) + + copy(buf, msg) + buf[len(msg)] = ':' + buf[len(msg) + 1] = ' ' + copy(buf[len(msg) + 2:], err_str) + buf[length - 1] = '\n' + write(stderr, buf) +} diff --git a/core/os/os2/errors_linux.odin b/core/os/os2/errors_linux.odin index 053256fbd..503f10671 100644 --- a/core/os/os2/errors_linux.odin +++ b/core/os/os2/errors_linux.odin @@ -1,145 +1,164 @@ //+private package os2 -import "core:sys/unix" +import "core:sys/linux" -EPERM :: 1 -ENOENT :: 2 -ESRCH :: 3 -EINTR :: 4 -EIO :: 5 -ENXIO :: 6 -EBADF :: 9 -EAGAIN :: 11 -ENOMEM :: 12 -EACCES :: 13 -EFAULT :: 14 -EEXIST :: 17 -ENODEV :: 19 -ENOTDIR :: 20 -EISDIR :: 21 -EINVAL :: 22 -ENFILE :: 23 -EMFILE :: 24 -ETXTBSY :: 26 -EFBIG :: 27 -ENOSPC :: 28 -ESPIPE :: 29 -EROFS :: 30 -EPIPE :: 32 -ERANGE :: 34 /* Result too large */ -EDEADLK :: 35 /* Resource deadlock would occur */ -ENAMETOOLONG :: 36 /* File name too long */ -ENOLCK :: 37 /* No record locks available */ -ENOSYS :: 38 /* Invalid system call number */ -ENOTEMPTY :: 39 /* Directory not empty */ -ELOOP :: 40 /* Too many symbolic links encountered */ -EWOULDBLOCK :: EAGAIN /* Operation would block */ -ENOMSG :: 42 /* No message of desired type */ -EIDRM :: 43 /* Identifier removed */ -ECHRNG :: 44 /* Channel number out of range */ -EL2NSYNC :: 45 /* Level 2 not synchronized */ -EL3HLT :: 46 /* Level 3 halted */ -EL3RST :: 47 /* Level 3 reset */ -ELNRNG :: 48 /* Link number out of range */ -EUNATCH :: 49 /* Protocol driver not attached */ -ENOCSI :: 50 /* No CSI structure available */ -EL2HLT :: 51 /* Level 2 halted */ -EBADE :: 52 /* Invalid exchange */ -EBADR :: 53 /* Invalid request descriptor */ -EXFULL :: 54 /* Exchange full */ -ENOANO :: 55 /* No anode */ -EBADRQC :: 56 /* Invalid request code */ -EBADSLT :: 57 /* Invalid slot */ -EDEADLOCK :: EDEADLK -EBFONT :: 59 /* Bad font file format */ -ENOSTR :: 60 /* Device not a stream */ -ENODATA :: 61 /* No data available */ -ETIME :: 62 /* Timer expired */ -ENOSR :: 63 /* Out of streams resources */ -ENONET :: 64 /* Machine is not on the network */ -ENOPKG :: 65 /* Package not installed */ -EREMOTE :: 66 /* Object is remote */ -ENOLINK :: 67 /* Link has been severed */ -EADV :: 68 /* Advertise error */ -ESRMNT :: 69 /* Srmount error */ -ECOMM :: 70 /* Communication error on send */ -EPROTO :: 71 /* Protocol error */ -EMULTIHOP :: 72 /* Multihop attempted */ -EDOTDOT :: 73 /* RFS specific error */ -EBADMSG :: 74 /* Not a data message */ -EOVERFLOW :: 75 /* Value too large for defined data type */ -ENOTUNIQ :: 76 /* Name not unique on network */ -EBADFD :: 77 /* File descriptor in bad state */ -EREMCHG :: 78 /* Remote address changed */ -ELIBACC :: 79 /* Can not access a needed shared library */ -ELIBBAD :: 80 /* Accessing a corrupted shared library */ -ELIBSCN :: 81 /* .lib section in a.out corrupted */ -ELIBMAX :: 82 /* Attempting to link in too many shared libraries */ -ELIBEXEC :: 83 /* Cannot exec a shared library directly */ -EILSEQ :: 84 /* Illegal byte sequence */ -ERESTART :: 85 /* Interrupted system call should be restarted */ -ESTRPIPE :: 86 /* Streams pipe error */ -EUSERS :: 87 /* Too many users */ -ENOTSOCK :: 88 /* Socket operation on non-socket */ -EDESTADDRREQ :: 89 /* Destination address required */ -EMSGSIZE :: 90 /* Message too long */ -EPROTOTYPE :: 91 /* Protocol wrong type for socket */ -ENOPROTOOPT :: 92 /* Protocol not available */ -EPROTONOSUPPORT:: 93 /* Protocol not supported */ -ESOCKTNOSUPPORT:: 94 /* Socket type not supported */ -EOPNOTSUPP :: 95 /* Operation not supported on transport endpoint */ -EPFNOSUPPORT :: 96 /* Protocol family not supported */ -EAFNOSUPPORT :: 97 /* Address family not supported by protocol */ -EADDRINUSE :: 98 /* Address already in use */ -EADDRNOTAVAIL :: 99 /* Cannot assign requested address */ -ENETDOWN :: 100 /* Network is down */ -ENETUNREACH :: 101 /* Network is unreachable */ -ENETRESET :: 102 /* Network dropped connection because of reset */ -ECONNABORTED :: 103 /* Software caused connection abort */ -ECONNRESET :: 104 /* Connection reset by peer */ -ENOBUFS :: 105 /* No buffer space available */ -EISCONN :: 106 /* Transport endpoint is already connected */ -ENOTCONN :: 107 /* Transport endpoint is not connected */ -ESHUTDOWN :: 108 /* Cannot send after transport endpoint shutdown */ -ETOOMANYREFS :: 109 /* Too many references: cannot splice */ -ETIMEDOUT :: 110 /* Connection timed out */ -ECONNREFUSED :: 111 /* Connection refused */ -EHOSTDOWN :: 112 /* Host is down */ -EHOSTUNREACH :: 113 /* No route to host */ -EALREADY :: 114 /* Operation already in progress */ -EINPROGRESS :: 115 /* Operation now in progress */ -ESTALE :: 116 /* Stale file handle */ -EUCLEAN :: 117 /* Structure needs cleaning */ -ENOTNAM :: 118 /* Not a XENIX named type file */ -ENAVAIL :: 119 /* No XENIX semaphores available */ -EISNAM :: 120 /* Is a named type file */ -EREMOTEIO :: 121 /* Remote I/O error */ -EDQUOT :: 122 /* Quota exceeded */ -ENOMEDIUM :: 123 /* No medium found */ -EMEDIUMTYPE :: 124 /* Wrong medium type */ -ECANCELED :: 125 /* Operation Canceled */ -ENOKEY :: 126 /* Required key not available */ -EKEYEXPIRED :: 127 /* Key has expired */ -EKEYREVOKED :: 128 /* Key has been revoked */ -EKEYREJECTED :: 129 /* Key was rejected by service */ -EOWNERDEAD :: 130 /* Owner died */ -ENOTRECOVERABLE:: 131 /* State not recoverable */ -ERFKILL :: 132 /* Operation not possible due to RF-kill */ -EHWPOISON :: 133 /* Memory page has hardware error */ +_errno_strings : [int(max(linux.Errno)) + 1]string = { + linux.Errno.NONE = "Success", + linux.Errno.EPERM = "Operation not permitted", + linux.Errno.ENOENT = "No such file or directory", + linux.Errno.ESRCH = "No such process", + linux.Errno.EINTR = "Interrupted system call", + linux.Errno.EIO = "Input/output error", + linux.Errno.ENXIO = "No such device or address", + linux.Errno.E2BIG = "Argument list too long", + linux.Errno.ENOEXEC = "Exec format error", + linux.Errno.EBADF = "Bad file descriptor", + linux.Errno.ECHILD = "No child processes", + linux.Errno.EAGAIN = "Resource temporarily unavailable", + linux.Errno.ENOMEM = "Cannot allocate memory", + linux.Errno.EACCES = "Permission denied", + linux.Errno.EFAULT = "Bad address", + linux.Errno.ENOTBLK = "Block device required", + linux.Errno.EBUSY = "Device or resource busy", + linux.Errno.EEXIST = "File exists", + linux.Errno.EXDEV = "Invalid cross-device link", + linux.Errno.ENODEV = "No such device", + linux.Errno.ENOTDIR = "Not a directory", + linux.Errno.EISDIR = "Is a directory", + linux.Errno.EINVAL = "Invalid argument", + linux.Errno.ENFILE = "Too many open files in system", + linux.Errno.EMFILE = "Too many open files", + linux.Errno.ENOTTY = "Inappropriate ioctl for device", + linux.Errno.ETXTBSY = "Text file busy", + linux.Errno.EFBIG = "File too large", + linux.Errno.ENOSPC = "No space left on device", + linux.Errno.ESPIPE = "Illegal seek", + linux.Errno.EROFS = "Read-only file system", + linux.Errno.EMLINK = "Too many links", + linux.Errno.EPIPE = "Broken pipe", + linux.Errno.EDOM = "Numerical argument out of domain", + linux.Errno.ERANGE = "Numerical result out of range", + linux.Errno.EDEADLK = "Resource deadlock avoided", + linux.Errno.ENAMETOOLONG = "File name too long", + linux.Errno.ENOLCK = "No locks available", + linux.Errno.ENOSYS = "Function not implemented", + linux.Errno.ENOTEMPTY = "Directory not empty", + linux.Errno.ELOOP = "Too many levels of symbolic links", + 41 = "Unknown Error (41)", + linux.Errno.ENOMSG = "No message of desired type", + linux.Errno.EIDRM = "Identifier removed", + linux.Errno.ECHRNG = "Channel number out of range", + linux.Errno.EL2NSYNC = "Level 2 not synchronized", + linux.Errno.EL3HLT = "Level 3 halted", + linux.Errno.EL3RST = "Level 3 reset", + linux.Errno.ELNRNG = "Link number out of range", + linux.Errno.EUNATCH = "Protocol driver not attached", + linux.Errno.ENOCSI = "No CSI structure available", + linux.Errno.EL2HLT = "Level 2 halted", + linux.Errno.EBADE = "Invalid exchange", + linux.Errno.EBADR = "Invalid request descriptor", + linux.Errno.EXFULL = "Exchange full", + linux.Errno.ENOANO = "No anode", + linux.Errno.EBADRQC = "Invalid request code", + linux.Errno.EBADSLT = "Invalid slot", + 58 = "Unknown Error (58)", + linux.Errno.EBFONT = "Bad font file format", + linux.Errno.ENOSTR = "Device not a stream", + linux.Errno.ENODATA = "No data available", + linux.Errno.ETIME = "Timer expired", + linux.Errno.ENOSR = "Out of streams resources", + linux.Errno.ENONET = "Machine is not on the network", + linux.Errno.ENOPKG = "Package not installed", + linux.Errno.EREMOTE = "Object is remote", + linux.Errno.ENOLINK = "Link has been severed", + linux.Errno.EADV = "Advertise error", + linux.Errno.ESRMNT = "Srmount error", + linux.Errno.ECOMM = "Communication error on send", + linux.Errno.EPROTO = "Protocol error", + linux.Errno.EMULTIHOP = "Multihop attempted", + linux.Errno.EDOTDOT = "RFS specific error", + linux.Errno.EBADMSG = "Bad message", + linux.Errno.EOVERFLOW = "Value too large for defined data type", + linux.Errno.ENOTUNIQ = "Name not unique on network", + linux.Errno.EBADFD = "File descriptor in bad state", + linux.Errno.EREMCHG = "Remote address changed", + linux.Errno.ELIBACC = "Can not access a needed shared library", + linux.Errno.ELIBBAD = "Accessing a corrupted shared library", + linux.Errno.ELIBSCN = ".lib section in a.out corrupted", + linux.Errno.ELIBMAX = "Attempting to link in too many shared libraries", + linux.Errno.ELIBEXEC = "Cannot exec a shared library directly", + linux.Errno.EILSEQ = "Invalid or incomplete multibyte or wide character", + linux.Errno.ERESTART = "Interrupted system call should be restarted", + linux.Errno.ESTRPIPE = "Streams pipe error", + linux.Errno.EUSERS = "Too many users", + linux.Errno.ENOTSOCK = "Socket operation on non-socket", + linux.Errno.EDESTADDRREQ = "Destination address required", + linux.Errno.EMSGSIZE = "Message too long", + linux.Errno.EPROTOTYPE = "Protocol wrong type for socket", + linux.Errno.ENOPROTOOPT = "Protocol not available", + linux.Errno.EPROTONOSUPPORT = "Protocol not supported", + linux.Errno.ESOCKTNOSUPPORT = "Socket type not supported", + linux.Errno.EOPNOTSUPP = "Operation not supported", + linux.Errno.EPFNOSUPPORT = "Protocol family not supported", + linux.Errno.EAFNOSUPPORT = "Address family not supported by protocol", + linux.Errno.EADDRINUSE = "Address already in use", + linux.Errno.EADDRNOTAVAIL = "Cannot assign requested address", + linux.Errno.ENETDOWN = "Network is down", + linux.Errno.ENETUNREACH = "Network is unreachable", + linux.Errno.ENETRESET = "Network dropped connection on reset", + linux.Errno.ECONNABORTED = "Software caused connection abort", + linux.Errno.ECONNRESET = "Connection reset by peer", + linux.Errno.ENOBUFS = "No buffer space available", + linux.Errno.EISCONN = "Transport endpoint is already connected", + linux.Errno.ENOTCONN = "Transport endpoint is not connected", + linux.Errno.ESHUTDOWN = "Cannot send after transport endpoint shutdown", + linux.Errno.ETOOMANYREFS = "Too many references: cannot splice", + linux.Errno.ETIMEDOUT = "Connection timed out", + linux.Errno.ECONNREFUSED = "Connection refused", + linux.Errno.EHOSTDOWN = "Host is down", + linux.Errno.EHOSTUNREACH = "No route to host", + linux.Errno.EALREADY = "Operation already in progress", + linux.Errno.EINPROGRESS = "Operation now in progress", + linux.Errno.ESTALE = "Stale file handle", + linux.Errno.EUCLEAN = "Structure needs cleaning", + linux.Errno.ENOTNAM = "Not a XENIX named type file", + linux.Errno.ENAVAIL = "No XENIX semaphores available", + linux.Errno.EISNAM = "Is a named type file", + linux.Errno.EREMOTEIO = "Remote I/O error", + linux.Errno.EDQUOT = "Disk quota exceeded", + linux.Errno.ENOMEDIUM = "No medium found", + linux.Errno.EMEDIUMTYPE = "Wrong medium type", + linux.Errno.ECANCELED = "Operation canceled", + linux.Errno.ENOKEY = "Required key not available", + linux.Errno.EKEYEXPIRED = "Key has expired", + linux.Errno.EKEYREVOKED = "Key has been revoked", + linux.Errno.EKEYREJECTED = "Key was rejected by service", + linux.Errno.EOWNERDEAD = "Owner died", + linux.Errno.ENOTRECOVERABLE = "State not recoverable", + linux.Errno.ERFKILL = "Operation not possible due to RF-kill", + linux.Errno.EHWPOISON = "Memory page has hardware error", +} + + +_get_platform_error :: proc(errno: linux.Errno) -> Error { + #partial switch errno { + case .NONE: + return nil + case .EPERM: + return .Permission_Denied + case .EEXIST: + return .Exist + case .ENOENT: + return .Not_Exist + } -_get_platform_error :: proc(res: int) -> Error { - errno := unix.get_errno(res) return Platform_Error(i32(errno)) } -_ok_or_error :: proc(res: int) -> Error { - return res >= 0 ? nil : _get_platform_error(res) -} - _error_string :: proc(errno: i32) -> string { - if errno == 0 { - return "" + if errno >= 0 && errno <= i32(max(linux.Errno)) { + return _errno_strings[errno] } - return "Error" + return "Unknown Error" } diff --git a/core/os/os2/file.odin b/core/os/os2/file.odin index 4f4bd942e..98cfc0815 100644 --- a/core/os/os2/file.odin +++ b/core/os/os2/file.odin @@ -46,10 +46,9 @@ O_SPARSE :: File_Flags{.Sparse} O_CLOEXEC :: File_Flags{.Close_On_Exec} - -stdin: ^File = nil // OS-Specific -stdout: ^File = nil // OS-Specific -stderr: ^File = nil // OS-Specific +stdin: ^File = &_stdin +stdout: ^File = &_stdout +stderr: ^File = &_stderr @(require_results) diff --git a/core/os/os2/file_linux.odin b/core/os/os2/file_linux.odin index 8f298be88..062c4aa0a 100644 --- a/core/os/os2/file_linux.odin +++ b/core/os/os2/file_linux.odin @@ -1,39 +1,60 @@ //+private package os2 -import "base:runtime" import "core:io" import "core:time" -import "core:sys/unix" - -INVALID_HANDLE :: -1 - -_O_RDONLY :: 0o00000000 -_O_WRONLY :: 0o00000001 -_O_RDWR :: 0o00000002 -_O_CREAT :: 0o00000100 -_O_EXCL :: 0o00000200 -_O_NOCTTY :: 0o00000400 -_O_TRUNC :: 0o00001000 -_O_APPEND :: 0o00002000 -_O_NONBLOCK :: 0o00004000 -_O_LARGEFILE :: 0o00100000 -_O_DIRECTORY :: 0o00200000 -_O_NOFOLLOW :: 0o00400000 -_O_SYNC :: 0o04010000 -_O_CLOEXEC :: 0o02000000 -_O_PATH :: 0o10000000 - -_AT_FDCWD :: -100 - -_CSTRING_NAME_HEAP_THRESHOLD :: 512 +import "base:runtime" +import "core:sys/linux" _File :: struct { name: string, - fd: int, + fd: linux.Fd, allocator: runtime.Allocator, } +_stdin : File = { + impl = { + name = "/proc/self/fd/0", + fd = 0, + allocator = _file_allocator(), + }, + stream = { + procedure = _file_stream_proc, + }, +} +_stdout : File = { + impl = { + name = "/proc/self/fd/1", + fd = 1, + allocator = _file_allocator(), + }, + stream = { + procedure = _file_stream_proc, + }, +} +_stderr : File = { + impl = { + name = "/proc/self/fd/2", + fd = 2, + allocator = _file_allocator(), + }, + stream = { + procedure = _file_stream_proc, + }, +} + +@init +_standard_stream_init :: proc() { + // cannot define these manually because cyclic reference + _stdin.stream.data = &_stdin + _stdout.stream.data = &_stdout + _stderr.stream.data = &_stderr +} + +_file_allocator :: proc() -> runtime.Allocator { + return heap_allocator() +} + _open :: proc(name: string, flags: File_Flags, perm: File_Mode) -> (f: ^File, err: Error) { TEMP_ALLOCATOR_GUARD() name_cstr := temp_cstring(name) or_return @@ -41,40 +62,48 @@ _open :: proc(name: string, flags: File_Flags, perm: File_Mode) -> (f: ^File, er // Just default to using O_NOCTTY because needing to open a controlling // terminal would be incredibly rare. This has no effect on files while // allowing us to open serial devices. - flags_i: int = _O_NOCTTY + sys_flags: linux.Open_Flags = {.NOCTTY} switch flags & O_RDONLY|O_WRONLY|O_RDWR { - case O_RDONLY: flags_i = _O_RDONLY - case O_WRONLY: flags_i = _O_WRONLY - case O_RDWR: flags_i = _O_RDWR + case O_RDONLY: + case O_WRONLY: sys_flags += {.WRONLY} + case O_RDWR: sys_flags += {.RDWR} } - if .Append in flags { flags_i |= _O_APPEND } - if .Create in flags { flags_i |= _O_CREAT } - if .Excl in flags { flags_i |= _O_EXCL } - if .Sync in flags { flags_i |= _O_SYNC } - if .Trunc in flags { flags_i |= _O_TRUNC } - if .Close_On_Exec in flags { flags_i |= _O_CLOEXEC } + if .Append in flags { sys_flags += {.APPEND} } + if .Create in flags { sys_flags += {.CREAT} } + if .Excl in flags { sys_flags += {.EXCL} } + if .Sync in flags { sys_flags += {.DSYNC} } + if .Trunc in flags { sys_flags += {.TRUNC} } + if .Close_On_Exec in flags { sys_flags += {.CLOEXEC} } - fd := unix.sys_open(name_cstr, flags_i, uint(perm)) - if fd < 0 { - return nil, _get_platform_error(fd) + fd, errno := linux.open(name_cstr, sys_flags, transmute(linux.Mode)(u32(perm))) + if errno != .NONE { + return nil, _get_platform_error(errno) } return _new_file(uintptr(fd), name), nil } -_new_file :: proc(fd: uintptr, _: string) -> ^File { +_new_file :: proc(fd: uintptr, _: string = "") -> ^File { file := new(File, file_allocator()) - file.impl.fd = int(fd) - file.impl.allocator = file_allocator() - file.impl.name = _get_full_path(file.impl.fd, file.impl.allocator) - file.stream = { - data = file, - procedure = _file_stream_proc, - } + _construct_file(file, fd, "") return file } +_construct_file :: proc(file: ^File, fd: uintptr, _: string = "") { + file^ = { + impl = { + fd = linux.Fd(fd), + allocator = file_allocator(), + name = _get_full_path(file.impl.fd, file.impl.allocator), + }, + stream = { + data = file, + procedure = _file_stream_proc, + }, + } +} + _destroy :: proc(f: ^File) -> Error { if f == nil { return nil @@ -86,12 +115,15 @@ _destroy :: proc(f: ^File) -> Error { _close :: proc(f: ^File) -> Error { - if f != nil { - res := unix.sys_close(f.impl.fd) - _destroy(f) - return _ok_or_error(res) + if f == nil { + return nil } - return nil + errno := linux.close(f.impl.fd) + if errno == .EBADF { // avoid possible double free + return _get_platform_error(errno) + } + _destroy(f) + return _get_platform_error(errno) } _fd :: proc(f: ^File) -> uintptr { @@ -106,20 +138,32 @@ _name :: proc(f: ^File) -> string { } _seek :: proc(f: ^File, offset: i64, whence: io.Seek_From) -> (ret: i64, err: Error) { - res := unix.sys_lseek(f.impl.fd, offset, int(whence)) - if res < 0 { - return -1, _get_platform_error(int(res)) + n, errno := linux.lseek(f.impl.fd, offset, linux.Seek_Whence(whence)) + if errno != .NONE { + return -1, _get_platform_error(errno) } - return res, nil + return n, nil } _read :: proc(f: ^File, p: []byte) -> (i64, Error) { if len(p) == 0 { return 0, nil } - n := unix.sys_read(f.impl.fd, &p[0], len(p)) - if n < 0 { - return -1, _get_platform_error(n) + n, errno := linux.read(f.impl.fd, p[:]) + if errno != .NONE { + return -1, _get_platform_error(errno) + } + return i64(n), n == 0 ? io.Error.EOF : nil +} + +_read_at :: proc(f: ^File, p: []byte, offset: i64) -> (i64, Error) { + if offset < 0 { + return 0, .Invalid_Offset + } + + n, errno := linux.pread(f.impl.fd, p[:], offset) + if errno != .NONE { + return -1, _get_platform_error(errno) } if n == 0 { return 0, .EOF @@ -127,91 +171,67 @@ _read :: proc(f: ^File, p: []byte) -> (i64, Error) { return i64(n), nil } -_read_at :: proc(f: ^File, p: []byte, offset: i64) -> (n: i64, err: Error) { - if offset < 0 { - return 0, .Invalid_Offset - } - - b, offset := p, offset - for len(b) > 0 { - m := unix.sys_pread(f.impl.fd, &b[0], len(b), offset) - if m < 0 { - return -1, _get_platform_error(m) - } - if m == 0 { - return 0, .EOF - } - n += i64(m) - b = b[m:] - offset += i64(m) - } - return -} - _write :: proc(f: ^File, p: []byte) -> (i64, Error) { if len(p) == 0 { return 0, nil } - n := unix.sys_write(f.impl.fd, &p[0], uint(len(p))) - if n < 0 { - return -1, _get_platform_error(n) + n, errno := linux.write(f.impl.fd, p[:]) + if errno != .NONE { + return -1, _get_platform_error(errno) } return i64(n), nil } -_write_at :: proc(f: ^File, p: []byte, offset: i64) -> (n: i64, err: Error) { +_write_at :: proc(f: ^File, p: []byte, offset: i64) -> (i64, Error) { if offset < 0 { return 0, .Invalid_Offset } - b, offset := p, offset - for len(b) > 0 { - m := unix.sys_pwrite(f.impl.fd, &b[0], len(b), offset) - if m < 0 { - return -1, _get_platform_error(m) - } - n += i64(m) - b = b[m:] - offset += i64(m) + n, errno := linux.pwrite(f.impl.fd, p[:], offset) + if errno != .NONE { + return -1, _get_platform_error(errno) } - return + return i64(n), nil } _file_size :: proc(f: ^File) -> (n: i64, err: Error) { - s: _Stat = --- - res := unix.sys_fstat(f.impl.fd, &s) - if res < 0 { - return -1, _get_platform_error(res) + s: linux.Stat = --- + errno := linux.fstat(f.impl.fd, &s) + if errno != .NONE { + return -1, _get_platform_error(errno) } - return s.size, nil + return i64(s.size), nil } _sync :: proc(f: ^File) -> Error { - return _ok_or_error(unix.sys_fsync(f.impl.fd)) + return _get_platform_error(linux.fsync(f.impl.fd)) } _flush :: proc(f: ^File) -> Error { - return _ok_or_error(unix.sys_fsync(f.impl.fd)) + return _get_platform_error(linux.fsync(f.impl.fd)) } _truncate :: proc(f: ^File, size: i64) -> Error { - return _ok_or_error(unix.sys_ftruncate(f.impl.fd, size)) + return _get_platform_error(linux.ftruncate(f.impl.fd, size)) } _remove :: proc(name: string) -> Error { TEMP_ALLOCATOR_GUARD() name_cstr := temp_cstring(name) or_return - fd := unix.sys_open(name_cstr, int(File_Flags.Read)) - if fd < 0 { - return _get_platform_error(fd) + fd, errno := linux.open(name_cstr, {.NOFOLLOW}) + #partial switch (errno) { + case .ELOOP: /* symlink */ + case .NONE: + defer linux.close(fd) + if _is_dir_fd(fd) { + return _get_platform_error(linux.rmdir(name_cstr)) + } + case: + return _get_platform_error(errno) } - defer unix.sys_close(fd) - if _is_dir_fd(fd) { - return _ok_or_error(unix.sys_rmdir(name_cstr)) - } - return _ok_or_error(unix.sys_unlink(name_cstr)) + return _get_platform_error(linux.unlink(name_cstr)) } _rename :: proc(old_name, new_name: string) -> Error { @@ -219,7 +239,7 @@ _rename :: proc(old_name, new_name: string) -> Error { old_name_cstr := temp_cstring(old_name) or_return new_name_cstr := temp_cstring(new_name) or_return - return _ok_or_error(unix.sys_rename(old_name_cstr, new_name_cstr)) + return _get_platform_error(linux.rename(old_name_cstr, new_name_cstr)) } _link :: proc(old_name, new_name: string) -> Error { @@ -227,148 +247,194 @@ _link :: proc(old_name, new_name: string) -> Error { old_name_cstr := temp_cstring(old_name) or_return new_name_cstr := temp_cstring(new_name) or_return - return _ok_or_error(unix.sys_link(old_name_cstr, new_name_cstr)) + return _get_platform_error(linux.link(old_name_cstr, new_name_cstr)) } _symlink :: proc(old_name, new_name: string) -> Error { TEMP_ALLOCATOR_GUARD() old_name_cstr := temp_cstring(old_name) or_return new_name_cstr := temp_cstring(new_name) or_return - - return _ok_or_error(unix.sys_symlink(old_name_cstr, new_name_cstr)) + return _get_platform_error(linux.symlink(old_name_cstr, new_name_cstr)) } _read_link_cstr :: proc(name_cstr: cstring, allocator: runtime.Allocator) -> (string, Error) { bufsz : uint = 256 buf := make([]byte, bufsz, allocator) for { - rc := unix.sys_readlink(name_cstr, &buf[0], bufsz) - if rc < 0 { - delete(buf) - return "", _get_platform_error(rc) - } else if rc == int(bufsz) { + sz, errno := linux.readlink(name_cstr, buf[:]) + if errno != .NONE { + delete(buf, allocator) + return "", _get_platform_error(errno) + } else if sz == int(bufsz) { bufsz *= 2 - delete(buf) + delete(buf, allocator) buf = make([]byte, bufsz, allocator) } else { - return string(buf[:rc]), nil + return string(buf[:sz]), nil } } } -_read_link :: proc(name: string, allocator: runtime.Allocator) -> (path: string, err: Error) { +_read_link :: proc(name: string, allocator: runtime.Allocator) -> (s: string, e: Error) { TEMP_ALLOCATOR_GUARD() name_cstr := temp_cstring(name) or_return return _read_link_cstr(name_cstr, allocator) } -_unlink :: proc(name: string) -> Error { - TEMP_ALLOCATOR_GUARD() - name_cstr := temp_cstring(name) or_return - return _ok_or_error(unix.sys_unlink(name_cstr)) -} - _chdir :: proc(name: string) -> Error { TEMP_ALLOCATOR_GUARD() name_cstr := temp_cstring(name) or_return - return _ok_or_error(unix.sys_chdir(name_cstr)) + return _get_platform_error(linux.chdir(name_cstr)) } _fchdir :: proc(f: ^File) -> Error { - return _ok_or_error(unix.sys_fchdir(f.impl.fd)) + return _get_platform_error(linux.fchdir(f.impl.fd)) } _chmod :: proc(name: string, mode: File_Mode) -> Error { TEMP_ALLOCATOR_GUARD() name_cstr := temp_cstring(name) or_return - return _ok_or_error(unix.sys_chmod(name_cstr, uint(mode))) + return _get_platform_error(linux.chmod(name_cstr, transmute(linux.Mode)(u32(mode)))) } _fchmod :: proc(f: ^File, mode: File_Mode) -> Error { - return _ok_or_error(unix.sys_fchmod(f.impl.fd, uint(mode))) + return _get_platform_error(linux.fchmod(f.impl.fd, transmute(linux.Mode)(u32(mode)))) } // NOTE: will throw error without super user priviledges _chown :: proc(name: string, uid, gid: int) -> Error { TEMP_ALLOCATOR_GUARD() name_cstr := temp_cstring(name) or_return - return _ok_or_error(unix.sys_chown(name_cstr, uid, gid)) + return _get_platform_error(linux.chown(name_cstr, linux.Uid(uid), linux.Gid(gid))) } // NOTE: will throw error without super user priviledges _lchown :: proc(name: string, uid, gid: int) -> Error { TEMP_ALLOCATOR_GUARD() name_cstr := temp_cstring(name) or_return - return _ok_or_error(unix.sys_lchown(name_cstr, uid, gid)) + return _get_platform_error(linux.lchown(name_cstr, linux.Uid(uid), linux.Gid(gid))) } // NOTE: will throw error without super user priviledges _fchown :: proc(f: ^File, uid, gid: int) -> Error { - return _ok_or_error(unix.sys_fchown(f.impl.fd, uid, gid)) + return _get_platform_error(linux.fchown(f.impl.fd, linux.Uid(uid), linux.Gid(gid))) } _chtimes :: proc(name: string, atime, mtime: time.Time) -> Error { TEMP_ALLOCATOR_GUARD() name_cstr := temp_cstring(name) or_return - times := [2]Unix_File_Time { - { atime._nsec, 0 }, - { mtime._nsec, 0 }, + times := [2]linux.Time_Spec { + { + uint(atime._nsec) / uint(time.Second), + uint(atime._nsec) % uint(time.Second), + }, + { + uint(mtime._nsec) / uint(time.Second), + uint(mtime._nsec) % uint(time.Second), + }, } - return _ok_or_error(unix.sys_utimensat(_AT_FDCWD, name_cstr, ×, 0)) + return _get_platform_error(linux.utimensat(linux.AT_FDCWD, name_cstr, ×[0], nil)) } _fchtimes :: proc(f: ^File, atime, mtime: time.Time) -> Error { - times := [2]Unix_File_Time { - { atime._nsec, 0 }, - { mtime._nsec, 0 }, + times := [2]linux.Time_Spec { + { + uint(atime._nsec) / uint(time.Second), + uint(atime._nsec) % uint(time.Second), + }, + { + uint(mtime._nsec) / uint(time.Second), + uint(mtime._nsec) % uint(time.Second), + }, } - return _ok_or_error(unix.sys_utimensat(f.impl.fd, nil, ×, 0)) + return _get_platform_error(linux.utimensat(f.impl.fd, nil, ×[0], nil)) } _exists :: proc(name: string) -> bool { TEMP_ALLOCATOR_GUARD() name_cstr, _ := temp_cstring(name) - return unix.sys_access(name_cstr, F_OK) == 0 + res, errno := linux.access(name_cstr, linux.F_OK) + return !res && errno == .NONE } _is_file :: proc(name: string) -> bool { TEMP_ALLOCATOR_GUARD() name_cstr, _ := temp_cstring(name) - s: _Stat - res := unix.sys_stat(name_cstr, &s) - if res < 0 { + s: linux.Stat + if linux.stat(name_cstr, &s) != .NONE { return false } - return S_ISREG(s.mode) + return linux.S_ISREG(s.mode) } -_is_file_fd :: proc(fd: int) -> bool { - s: _Stat - res := unix.sys_fstat(fd, &s) - if res < 0 { // error +_is_file_fd :: proc(fd: linux.Fd) -> bool { + s: linux.Stat + if linux.fstat(fd, &s) != .NONE { return false } - return S_ISREG(s.mode) + return linux.S_ISREG(s.mode) } _is_dir :: proc(name: string) -> bool { TEMP_ALLOCATOR_GUARD() name_cstr, _ := temp_cstring(name) - s: _Stat - res := unix.sys_stat(name_cstr, &s) - if res < 0 { + s: linux.Stat + if linux.stat(name_cstr, &s) != .NONE { return false } - return S_ISDIR(s.mode) + return linux.S_ISDIR(s.mode) } -_is_dir_fd :: proc(fd: int) -> bool { - s: _Stat - res := unix.sys_fstat(fd, &s) - if res < 0 { // error +_is_dir_fd :: proc(fd: linux.Fd) -> bool { + s: linux.Stat + if linux.fstat(fd, &s) != .NONE { return false } - return S_ISDIR(s.mode) + return linux.S_ISDIR(s.mode) +} + +/* Certain files in the Linux file system are not actual + * files (e.g. everything in /proc/). Therefore, the + * read_entire_file procs fail to actually read anything + * since these "files" stat to a size of 0. Here, we just + * read until there is nothing left. + */ +_read_entire_pseudo_file :: proc { _read_entire_pseudo_file_string, _read_entire_pseudo_file_cstring } + +_read_entire_pseudo_file_string :: proc(name: string, allocator: runtime.Allocator) -> (b: []u8, e: Error) { + name_cstr := clone_to_cstring(name, allocator) or_return + defer delete(name, allocator) + return _read_entire_pseudo_file_cstring(name_cstr, allocator) +} + +_read_entire_pseudo_file_cstring :: proc(name: cstring, allocator: runtime.Allocator) -> ([]u8, Error) { + fd, errno := linux.open(name, {}) + if errno != .NONE { + return nil, _get_platform_error(errno) + } + defer linux.close(fd) + + BUF_SIZE_STEP :: 128 + contents := make([dynamic]u8, 0, BUF_SIZE_STEP, allocator) + + n: int + i: int + for { + resize(&contents, i + BUF_SIZE_STEP) + n, errno = linux.read(fd, contents[i:i+BUF_SIZE_STEP]) + if errno != .NONE { + delete(contents) + return nil, _get_platform_error(errno) + } + if n < BUF_SIZE_STEP { + break + } + i += BUF_SIZE_STEP + } + + resize(&contents, i + n) + + return contents[:], nil } @(private="package") diff --git a/core/os/os2/heap_linux.odin b/core/os/os2/heap_linux.odin index bb4acba13..11cf5ab41 100644 --- a/core/os/os2/heap_linux.odin +++ b/core/os/os2/heap_linux.odin @@ -1,7 +1,7 @@ //+private package os2 -import "core:sys/unix" +import "core:sys/linux" import "core:sync" import "core:mem" @@ -97,9 +97,8 @@ CURRENTLY_ACTIVE :: (^^Region)(~uintptr(0)) FREE_LIST_ENTRIES_PER_BLOCK :: BLOCK_SIZE / size_of(u16) -MMAP_FLAGS :: unix.MAP_ANONYMOUS | unix.MAP_PRIVATE -MMAP_PROT :: unix.PROT_READ | unix.PROT_WRITE - +MMAP_FLAGS : linux.Map_Flags : {.ANONYMOUS, .PRIVATE} +MMAP_PROT : linux.Mem_Protection : {.READ, .WRITE} @thread_local _local_region: ^Region global_regions: ^Region @@ -324,11 +323,11 @@ heap_free :: proc(memory: rawptr) { // Regions // _new_region :: proc() -> ^Region #no_bounds_check { - res := unix.sys_mmap(nil, uint(SIZE_OF_REGION), MMAP_PROT, MMAP_FLAGS, -1, 0) - if res < 0 { + ptr, errno := linux.mmap(0, uint(SIZE_OF_REGION), MMAP_PROT, MMAP_FLAGS, -1, 0) + if errno != .NONE { return nil } - new_region := (^Region)(uintptr(res)) + new_region := (^Region)(ptr) new_region.hdr.local_addr = CURRENTLY_ACTIVE new_region.hdr.reset_addr = &_local_region @@ -634,8 +633,8 @@ _region_free_list_remove :: proc(region: ^Region, free_idx: u16) #no_bounds_chec // _direct_mmap_alloc :: proc(size: int) -> rawptr { mmap_size := _round_up_to_nearest(size + BLOCK_SIZE, PAGE_SIZE) - new_allocation := unix.sys_mmap(nil, uint(mmap_size), MMAP_PROT, MMAP_FLAGS, -1, 0) - if new_allocation < 0 && new_allocation > -4096 { + new_allocation, errno := linux.mmap(0, uint(mmap_size), MMAP_PROT, MMAP_FLAGS, -1, 0) + if errno != .NONE { return nil } @@ -655,13 +654,8 @@ _direct_mmap_resize :: proc(alloc: ^Allocation_Header, new_size: int) -> rawptr return mem.ptr_offset(alloc, 1) } - new_allocation := unix.sys_mremap( - alloc, - uint(old_mmap_size), - uint(new_mmap_size), - unix.MREMAP_MAYMOVE, - ) - if new_allocation < 0 && new_allocation > -4096 { + new_allocation, errno := linux.mremap(alloc, uint(old_mmap_size), uint(new_mmap_size), {.MAYMOVE}) + if errno != .NONE { return nil } @@ -702,7 +696,7 @@ _direct_mmap_to_region :: proc(alloc: ^Allocation_Header, new_size: int) -> rawp _direct_mmap_free :: proc(alloc: ^Allocation_Header) { requested := int(alloc.requested & REQUESTED_MASK) mmap_size := _round_up_to_nearest(requested + BLOCK_SIZE, PAGE_SIZE) - unix.sys_munmap(alloc, uint(mmap_size)) + linux.munmap(alloc, uint(mmap_size)) } // diff --git a/core/os/os2/path_linux.odin b/core/os/os2/path_linux.odin index 81176c219..3c08eedee 100644 --- a/core/os/os2/path_linux.odin +++ b/core/os/os2/path_linux.odin @@ -3,104 +3,89 @@ package os2 import "core:strconv" import "base:runtime" -import "core:sys/unix" +import "core:sys/linux" _Path_Separator :: '/' _Path_Separator_String :: "/" _Path_List_Separator :: ':' -_S_IFMT :: 0o170000 // Type of file mask -_S_IFIFO :: 0o010000 // Named pipe (fifo) -_S_IFCHR :: 0o020000 // Character special -_S_IFDIR :: 0o040000 // Directory -_S_IFBLK :: 0o060000 // Block special -_S_IFREG :: 0o100000 // Regular -_S_IFLNK :: 0o120000 // Symbolic link -_S_IFSOCK :: 0o140000 // Socket - -_OPENDIR_FLAGS :: _O_RDONLY|_O_NONBLOCK|_O_DIRECTORY|_O_LARGEFILE|_O_CLOEXEC +_OPENDIR_FLAGS : linux.Open_Flags : {.NONBLOCK, .DIRECTORY, .LARGEFILE, .CLOEXEC} _is_path_separator :: proc(c: byte) -> bool { return c == '/' } _mkdir :: proc(path: string, perm: File_Mode) -> Error { - // NOTE: These modes would require sys_mknod, however, that would require - // additional arguments to this function. + // TODO: These modes would require mknod, however, that would also + // require additional arguments to this function.. if perm & (File_Mode_Named_Pipe | File_Mode_Device | File_Mode_Char_Device | File_Mode_Sym_Link) != 0 { return .Invalid_Argument } TEMP_ALLOCATOR_GUARD() path_cstr := temp_cstring(path) or_return - return _ok_or_error(unix.sys_mkdir(path_cstr, uint(perm & 0o777))) + return _get_platform_error(linux.mkdir(path_cstr, transmute(linux.Mode)(u32(perm) & 0o777))) } _mkdir_all :: proc(path: string, perm: File_Mode) -> Error { - _mkdirat :: proc(dfd: int, path: []u8, perm: int, has_created: ^bool) -> Error { - if len(path) == 0 { - return _ok_or_error(unix.sys_close(dfd)) - } + mkdirat :: proc(dfd: linux.Fd, path: []u8, perm: int, has_created: ^bool) -> Error { i: int - for /**/; i < len(path) - 1 && path[i] != '/'; i += 1 {} + for ; i < len(path) - 1 && path[i] != '/'; i += 1 {} + if i == 0 { + return _get_platform_error(linux.close(dfd)) + } path[i] = 0 - new_dfd := unix.sys_openat(dfd, cstring(&path[0]), _OPENDIR_FLAGS) - switch new_dfd { - case -ENOENT: - if res := unix.sys_mkdirat(dfd, cstring(&path[0]), uint(perm)); res < 0 { - return _get_platform_error(res) + new_dfd, errno := linux.openat(dfd, cstring(&path[0]), _OPENDIR_FLAGS) + #partial switch errno { + case .ENOENT: + if errno = linux.mkdirat(dfd, cstring(&path[0]), transmute(linux.Mode)(u32(perm))); errno != .NONE { + return _get_platform_error(errno) } has_created^ = true - if new_dfd = unix.sys_openat(dfd, cstring(&path[0]), _OPENDIR_FLAGS); new_dfd < 0 { - return _get_platform_error(new_dfd) + if new_dfd, errno = linux.openat(dfd, cstring(&path[0]), _OPENDIR_FLAGS); errno != .NONE { + return _get_platform_error(errno) } fallthrough - case 0: - if res := unix.sys_close(dfd); res < 0 { - return _get_platform_error(res) + case .NONE: + if errno = linux.close(dfd); errno != .NONE { + return _get_platform_error(errno) } // skip consecutive '/' for i += 1; i < len(path) && path[i] == '/'; i += 1 {} - return _mkdirat(new_dfd, path[i:], perm, has_created) + return mkdirat(new_dfd, path[i:], perm, has_created) case: - return _get_platform_error(new_dfd) + return _get_platform_error(errno) } unreachable() } + // TODO if perm & (File_Mode_Named_Pipe | File_Mode_Device | File_Mode_Char_Device | File_Mode_Sym_Link) != 0 { return .Invalid_Argument } TEMP_ALLOCATOR_GUARD() - // need something we can edit, and use to generate cstrings - allocated: bool - path_bytes: []u8 - if len(path) > _CSTRING_NAME_HEAP_THRESHOLD { - allocated = true - path_bytes = make([]u8, len(path) + 1) - } else { - path_bytes = make([]u8, len(path) + 1, temp_allocator()) - } + path_bytes := make([]u8, len(path) + 1, temp_allocator()) - // NULL terminate the byte slice to make it a valid cstring + // zero terminate the byte slice to make it a valid cstring copy(path_bytes, path) path_bytes[len(path)] = 0 - dfd: int + dfd: linux.Fd + errno: linux.Errno if path_bytes[0] == '/' { - dfd = unix.sys_open("/", _OPENDIR_FLAGS) + dfd, errno = linux.open("/", _OPENDIR_FLAGS) path_bytes = path_bytes[1:] } else { - dfd = unix.sys_open(".", _OPENDIR_FLAGS) + dfd, errno = linux.open(".", _OPENDIR_FLAGS) } - if dfd < 0 { - return _get_platform_error(dfd) + if errno != .NONE { + return _get_platform_error(errno) } has_created: bool - _mkdirat(dfd, path_bytes, int(perm & 0o777), &has_created) or_return + mkdirat(dfd, path_bytes, int(perm & 0o777), &has_created) or_return if has_created { return nil } @@ -119,28 +104,28 @@ dirent64 :: struct { _remove_all :: proc(path: string) -> Error { DT_DIR :: 4 - _remove_all_dir :: proc(dfd: int) -> Error { + remove_all_dir :: proc(dfd: linux.Fd) -> Error { n := 64 buf := make([]u8, n) defer delete(buf) loop: for { - getdents_res := unix.sys_getdents64(dfd, &buf[0], n) - switch getdents_res { - case -EINVAL: + buflen, errno := linux.getdents(dfd, buf[:]) + #partial switch errno { + case .EINVAL: delete(buf) n *= 2 buf = make([]u8, n) continue loop - case -4096..<0: - return _get_platform_error(getdents_res) - case 0: - break loop + case .NONE: + if buflen == 0 { break loop } + case: + return _get_platform_error(errno) } d: ^dirent64 - for i := 0; i < getdents_res; i += int(d.d_reclen) { + for i := 0; i < buflen; i += int(d.d_reclen) { d = (^dirent64)(rawptr(&buf[i])) d_name_cstr := cstring(&d.d_name[0]) @@ -156,23 +141,22 @@ _remove_all :: proc(path: string) -> Error { continue } - unlink_res: int - switch d.d_type { case DT_DIR: - new_dfd := unix.sys_openat(dfd, d_name_cstr, _OPENDIR_FLAGS) - if new_dfd < 0 { - return _get_platform_error(new_dfd) + new_dfd: linux.Fd + new_dfd, errno = linux.openat(dfd, d_name_cstr, _OPENDIR_FLAGS) + if errno != .NONE { + return _get_platform_error(errno) } - defer unix.sys_close(new_dfd) - _remove_all_dir(new_dfd) or_return - unlink_res = unix.sys_unlinkat(dfd, d_name_cstr, int(unix.AT_REMOVEDIR)) + defer linux.close(new_dfd) + remove_all_dir(new_dfd) or_return + errno = linux.unlinkat(dfd, d_name_cstr, {.REMOVEDIR}) case: - unlink_res = unix.sys_unlinkat(dfd, d_name_cstr) + errno = linux.unlinkat(dfd, d_name_cstr, nil) } - if unlink_res < 0 { - return _get_platform_error(unlink_res) + if errno != .NONE { + return _get_platform_error(errno) } } } @@ -182,17 +166,19 @@ _remove_all :: proc(path: string) -> Error { TEMP_ALLOCATOR_GUARD() path_cstr := temp_cstring(path) or_return - fd := unix.sys_open(path_cstr, _OPENDIR_FLAGS) - switch fd { - case -ENOTDIR: - return _ok_or_error(unix.sys_unlink(path_cstr)) - case -4096..<0: - return _get_platform_error(fd) + fd, errno := linux.open(path_cstr, _OPENDIR_FLAGS) + #partial switch errno { + case .NONE: + break + case .ENOTDIR: + return _get_platform_error(linux.unlink(path_cstr)) + case: + return _get_platform_error(errno) } - defer unix.sys_close(fd) - _remove_all_dir(fd) or_return - return _ok_or_error(unix.sys_rmdir(path_cstr)) + defer linux.close(fd) + remove_all_dir(fd) or_return + return _get_platform_error(linux.rmdir(path_cstr)) } _getwd :: proc(allocator: runtime.Allocator) -> (string, Error) { @@ -203,13 +189,12 @@ _getwd :: proc(allocator: runtime.Allocator) -> (string, Error) { PATH_MAX :: 4096 buf := make([dynamic]u8, PATH_MAX, allocator) for { - #no_bounds_check res := unix.sys_getcwd(&buf[0], uint(len(buf))) - - if res >= 0 { - return string_from_null_terminated_bytes(buf[:]), nil + #no_bounds_check n, errno := linux.getcwd(buf[:]) + if errno == .NONE { + return string(buf[:n-1]), nil } - if res != -ERANGE { - return "", _get_platform_error(res) + if errno != .ERANGE { + return "", _get_platform_error(errno) } resize(&buf, len(buf)+PATH_MAX) } @@ -218,16 +203,16 @@ _getwd :: proc(allocator: runtime.Allocator) -> (string, Error) { _setwd :: proc(dir: string) -> Error { dir_cstr := temp_cstring(dir) or_return - return _ok_or_error(unix.sys_chdir(dir_cstr)) + return _get_platform_error(linux.chdir(dir_cstr)) } -_get_full_path :: proc(fd: int, allocator: runtime.Allocator) -> string { +_get_full_path :: proc(fd: linux.Fd, allocator: runtime.Allocator) -> string { PROC_FD_PATH :: "/proc/self/fd/" buf: [32]u8 copy(buf[:], PROC_FD_PATH) - strconv.itoa(buf[len(PROC_FD_PATH):], fd) + strconv.itoa(buf[len(PROC_FD_PATH):], int(fd)) fullpath: string err: Error @@ -236,4 +221,3 @@ _get_full_path :: proc(fd: int, allocator: runtime.Allocator) -> string { } return fullpath } - diff --git a/core/os/os2/pipe_linux.odin b/core/os/os2/pipe_linux.odin index b66ff9663..5d42cca78 100644 --- a/core/os/os2/pipe_linux.odin +++ b/core/os/os2/pipe_linux.odin @@ -1,7 +1,17 @@ //+private package os2 +import "core:sys/linux" + _pipe :: proc() -> (r, w: ^File, err: Error) { - return nil, nil, nil + fds: [2]linux.Fd + errno := linux.pipe2(&fds, {.CLOEXEC}) + if errno != .NONE { + return nil, nil,_get_platform_error(errno) + } + + r = _new_file(uintptr(fds[0])) + w = _new_file(uintptr(fds[1])) + return } diff --git a/core/os/os2/process.odin b/core/os/os2/process.odin index 862434b7b..099d1c19e 100644 --- a/core/os/os2/process.odin +++ b/core/os/os2/process.odin @@ -2,36 +2,42 @@ package os2 import "core:sync" import "core:time" -import "base:runtime" +import "core:c" -args: []string +args: []string = _alloc_command_line_arguments() exit :: proc "contextless" (code: int) -> ! { - runtime.trap() + _exit(code) } +@(require_results) get_uid :: proc() -> int { - return -1 + return _get_uid() } +@(require_results) get_euid :: proc() -> int { - return -1 + return _get_euid() } +@(require_results) get_gid :: proc() -> int { - return -1 + return _get_gid() } +@(require_results) get_egid :: proc() -> int { - return -1 + return _get_euid() } +@(require_results) get_pid :: proc() -> int { - return -1 + return _get_pid() } +@(require_results) get_ppid :: proc() -> int { - return -1 + return _get_ppid() } @@ -46,16 +52,12 @@ Process :: struct { Process_Attributes :: struct { dir: string, env: []string, - files: []^File, + stdin: ^File, + stdout: ^File, + stderr: ^File, sys: ^Process_Attributes_OS_Specific, } -Process_Attributes_OS_Specific :: struct{} - -Process_Error :: enum { - None, -} - Process_State :: struct { pid: int, exit_code: int, @@ -66,37 +68,53 @@ Process_State :: struct { sys: rawptr, } -Signal :: #type proc() - -Kill: Signal = nil -Interrupt: Signal = nil - - -find_process :: proc(pid: int) -> (^Process, Process_Error) { - return nil, .None +Signal :: enum { + Abort, + Floating_Point_Exception, + Illegal_Instruction, + Interrupt, + Segmentation_Fault, + Termination, } - -process_start :: proc(name: string, argv: []string, attr: ^Process_Attributes) -> (^Process, Process_Error) { - return nil, .None +Signal_Handler_Proc :: #type proc "c" (c.int) +Signal_Handler_Special :: enum { + Default, + Ignore, } -process_release :: proc(p: ^Process) -> Process_Error { - return .None +Signal_Handler :: union { + Signal_Handler_Proc, + Signal_Handler_Special, } -process_kill :: proc(p: ^Process) -> Process_Error { - return .None +@(require_results) +process_find :: proc(pid: int) -> (Process, Error) { + return _process_find(pid) } -process_signal :: proc(p: ^Process, sig: Signal) -> Process_Error { - return .None +@(require_results) +process_get_state :: proc(p: Process) -> (Process_State, Error) { + return _process_get_state(p) } -process_wait :: proc(p: ^Process) -> (Process_State, Process_Error) { - return {}, .None +@(require_results) +process_start :: proc(name: string, argv: []string, attr: ^Process_Attributes = nil) -> (Process, Error) { + return _process_start(name, argv, attr) } +process_release :: proc(p: ^Process) -> Error { + return _process_release(p) +} +process_kill :: proc(p: ^Process) -> Error { + return _process_kill(p) +} +process_signal :: proc(sig: Signal, h: Signal_Handler) -> Error { + return _process_signal(sig, h) +} +process_wait :: proc(p: ^Process, t: time.Duration = time.MAX_DURATION) -> (Process_State, Error) { + return _process_wait(p, t) +} diff --git a/core/os/os2/process_linux.odin b/core/os/os2/process_linux.odin new file mode 100644 index 000000000..0484615ec --- /dev/null +++ b/core/os/os2/process_linux.odin @@ -0,0 +1,428 @@ +//+private +package os2 + +import "base:runtime" + +import "core:fmt" +import "core:mem" +import "core:time" +import "core:strings" +import "core:strconv" +import "core:sys/linux" +import "core:path/filepath" + +_alloc_command_line_arguments :: proc() -> []string { + res := make([]string, len(runtime.args__), heap_allocator()) + for arg, i in runtime.args__ { + res[i] = string(arg) + } + return res +} + +_exit :: proc "contextless" (code: int) -> ! { + linux.exit_group(i32(code)) +} + +_get_uid :: proc() -> int { + return int(linux.getuid()) +} + +_get_euid :: proc() -> int { + return int(linux.geteuid()) +} + +_get_gid :: proc() -> int { + return int(linux.getgid()) +} + +_get_egid :: proc() -> int { + return int(linux.getegid()) +} + +_get_pid :: proc() -> int { + return int(linux.getpid()) +} + +_get_ppid :: proc() -> int { + return int(linux.getppid()) +} + +Process_Attributes_OS_Specific :: struct {} + +_process_find :: proc(pid: int) -> (Process, Error) { + TEMP_ALLOCATOR_GUARD() + pid_path := fmt.ctprintf("/proc/%d", pid) + + p: Process + dir_fd: linux.Fd + errno: linux.Errno + + #partial switch dir_fd, errno = linux.open(pid_path, _OPENDIR_FLAGS); errno { + case .NONE: + linux.close(dir_fd) + p.pid = pid + return p, nil + case .ENOTDIR: + return p, .Invalid_Dir + case .ENOENT: + return p, .Not_Exist + } + return p, _get_platform_error(errno) +} + +_process_get_state :: proc(p: Process) -> (state: Process_State, err: Error) { + TEMP_ALLOCATOR_GUARD() + + stat_name := fmt.ctprintf("/proc/%d/stat", p.pid) + stat_buf: []u8 + stat_buf, err = _read_entire_pseudo_file(stat_name, temp_allocator()) + + if err != nil { + return + } + + idx := strings.last_index_byte(string(stat_buf), ')') + stats := string(stat_buf[idx + 2:]) + + // utime and stime are the 12 and 13th items, respectively + // skip the first 11 items here. + for i := 0; i < 11; i += 1 { + stats = stats[strings.index_byte(stats, ' ') + 1:] + } + + idx = strings.index_byte(stats, ' ') + utime_str := stats[:idx] + + stats = stats[idx + 1:] + stime_str := stats[:strings.index_byte(stats, ' ')] + + utime, _ := strconv.parse_int(utime_str, 10) + stime, _ := strconv.parse_int(stime_str, 10) + + // NOTE: Assuming HZ of 100, 1 jiffy == 10 ms + state.user_time = time.Duration(utime) * 10 * time.Millisecond + state.system_time = time.Duration(stime) * 10 * time.Millisecond + + return +} + +_process_start :: proc(name: string, argv: []string, attr: ^Process_Attributes) -> (child: Process, err: Error) { + TEMP_ALLOCATOR_GUARD() + + dir_fd := linux.AT_FDCWD + errno: linux.Errno + if attr != nil && attr.dir != "" { + dir_cstr := temp_cstring(attr.dir) or_return + if dir_fd, errno = linux.open(dir_cstr, _OPENDIR_FLAGS); errno != .NONE { + return child, _get_platform_error(errno) + } + } + + // search PATH if just a plain name is provided + executable: cstring + if !strings.contains_rune(name, '/') { + path_env := get_env("PATH", temp_allocator()) + path_dirs := filepath.split_list(path_env, temp_allocator()) + found: bool + for dir in path_dirs { + executable = fmt.ctprintf("%s/%s", dir, name) + fail: bool + if fail, errno = linux.faccessat(dir_fd, executable, linux.F_OK); errno == .NONE && !fail { + found = true + break + } + } + if !found { + // check in cwd to match windows behavior + executable = fmt.ctprintf("./%s", name) + fail: bool + if fail, errno = linux.faccessat(dir_fd, executable, linux.F_OK); errno != .NONE || fail { + return child, .Not_Exist + } + } + } else { + executable = temp_cstring(name) or_return + } + + not_exec: bool + if not_exec, errno = linux.faccessat(dir_fd, executable, linux.F_OK | linux.X_OK); errno != .NONE || not_exec { + return child, errno == .NONE ? .Permission_Denied : _get_platform_error(errno) + } + + // args and environment need to be a list of cstrings + // that are terminated by a nil pointer. + // The first argument is a copy of the executable name. + cargs := make([]cstring, len(argv) + 2, temp_allocator()) + cargs[0] = executable + for i := 0; i < len(argv); i += 1 { + cargs[i + 1] = temp_cstring(argv[i]) or_return + } + + // Use current process's environment if attributes not provided + env: [^]cstring + if attr == nil { + // take this process's current environment + env = raw_data(export_cstring_environment(temp_allocator())) + } else { + cenv := make([]cstring, len(attr.env) + 1, temp_allocator()) + for i := 0; i < len(attr.env); i += 1 { + cenv[i] = temp_cstring(attr.env[i]) or_return + } + env = &cenv[0] + } + + // TODO: This is the traditional textbook implementation with fork. + // A more efficient implementation with vfork: + // + // 1. retrieve signal handlers + // 2. block all signals + // 3. allocate some stack space + // 4. vfork (waits for child exit or execve); In child: + // a. set child signal handlers + // b. set up any necessary pipes + // c. execve + // 5. restore signal handlers + // + stdin_fds: [2]linux.Fd + stdout_fds: [2]linux.Fd + stderr_fds: [2]linux.Fd + if attr != nil && attr.stdin != nil { + if errno = linux.pipe2(&stdin_fds, nil); errno != .NONE { + return child, _get_platform_error(errno) + } + } + if attr != nil && attr.stdout != nil { + if errno = linux.pipe2(&stdout_fds, nil); errno != .NONE { + return child, _get_platform_error(errno) + } + } + if attr != nil && attr.stderr != nil { + if errno = linux.pipe2(&stderr_fds, nil); errno != .NONE { + return child, _get_platform_error(errno) + } + } + + pid: linux.Pid + if pid, errno = linux.fork(); errno != .NONE { + return child, _get_platform_error(errno) + } + + IN :: 1 + OUT :: 0 + + STDIN :: linux.Fd(0) + STDOUT :: linux.Fd(1) + STDERR :: linux.Fd(2) + + if pid == 0 { + // in child process now + if attr != nil && attr.stdin != nil { + if linux.close(stdin_fds[IN]) != .NONE { linux.exit(1) } + if _, errno = linux.dup2(stdin_fds[OUT], STDIN); errno != .NONE { linux.exit(1) } + if linux.close(stdin_fds[OUT]) != .NONE { linux.exit(1) } + } + if attr != nil && attr.stdout != nil { + if linux.close(stdout_fds[OUT]) != .NONE { linux.exit(1) } + if _, errno = linux.dup2(stdout_fds[IN], STDOUT); errno != .NONE { linux.exit(1) } + if linux.close(stdout_fds[IN]) != .NONE { linux.exit(1) } + } + if attr != nil && attr.stderr != nil { + if linux.close(stderr_fds[OUT]) != .NONE { linux.exit(1) } + if _, errno = linux.dup2(stderr_fds[IN], STDERR); errno != .NONE { linux.exit(1) } + if linux.close(stderr_fds[IN]) != .NONE { linux.exit(1) } + } + + if errno = linux.execveat(dir_fd, executable, &cargs[OUT], env); errno != .NONE { + print_error(_get_platform_error(errno), string(executable)) + panic("execve failed to replace process") + } + unreachable() + } + + // in parent process + if attr != nil && attr.stdin != nil { + linux.close(stdin_fds[OUT]) + _construct_file(attr.stdin, uintptr(stdin_fds[IN])) + } + if attr != nil && attr.stdout != nil { + linux.close(stdout_fds[IN]) + _construct_file(attr.stdout, uintptr(stdout_fds[OUT])) + } + if attr != nil && attr.stderr != nil { + linux.close(stderr_fds[IN]) + _construct_file(attr.stderr, uintptr(stderr_fds[OUT])) + } + + child.pid = int(pid) + return child, nil +} + +_process_release :: proc(p: ^Process) -> Error { + // We didn't allocate... + return nil +} + +_process_kill :: proc(p: ^Process) -> Error { + res := linux.kill(linux.Pid(p.pid), .SIGKILL) + return _get_platform_error(res) +} + +_process_signal :: proc(sig: Signal, h: Signal_Handler) -> Error { + signo: linux.Signal + switch sig { + case .Abort: signo = .SIGABRT + case .Floating_Point_Exception: signo = .SIGFPE + case .Illegal_Instruction: signo = .SIGILL + case .Interrupt: signo = .SIGINT + case .Segmentation_Fault: signo = .SIGSEGV + case .Termination: signo = .SIGTERM + } + + sigact: linux.Sig_Action(int) + old: ^linux.Sig_Action(int) = nil + + switch v in h { + case Signal_Handler_Special: + switch v { + case .Default: + sigact.special = .SIG_DFL + case .Ignore: + sigact.special = .SIG_IGN + } + case Signal_Handler_Proc: + sigact.handler = (linux.Sig_Handler_Fn)(v) + } + + return _get_platform_error(linux.rt_sigaction(signo, &sigact, old)) +} + +_process_wait :: proc(p: ^Process, t: time.Duration) -> (state: Process_State, err: Error) { + safe_state :: proc(p: Process, state: Process_State = {}) -> (Process_State, Error) { + // process_get_state can fail, so we don't want to return it directly. + if new_state, err := _process_get_state(p); err == nil { + return new_state, nil + } + return state, nil + } + + state.pid = p.pid + + options: linux.Wait_Options + big_if: if t == 0 { + options += {.WNOHANG} + } else if t != time.MAX_DURATION { + ts: linux.Time_Spec = { + time_sec = uint(t / time.Second), + time_nsec = uint(t % time.Second), + } + + @static has_pidfd_open: bool = true + + // pidfd_open is fairly new, so don't error out on ENOSYS + pid_fd: linux.Pid_FD + errno: linux.Errno + if has_pidfd_open { + pid_fd, errno = linux.pidfd_open(linux.Pid(p.pid), nil) + if errno != .NONE && errno != .ENOSYS { + return state, _get_platform_error(errno) + } + } + + if has_pidfd_open && errno != .ENOSYS { + defer linux.close(linux.Fd(pid_fd)) + pollfd: [1]linux.Poll_Fd = { + { + fd = linux.Fd(pid_fd), + events = {.IN}, + }, + } + for { + n, e := linux.ppoll(pollfd[:], &ts, nil) + if e == .EINTR { + continue + } + if e != .NONE { + return state, _get_platform_error(errno) + } + if n == 0 { + return safe_state(p^, state) + } + break + } + } else { + has_pidfd_open = false + mask: bit_set[0..=63] + mask += { int(linux.Signal.SIGCHLD) - 1 } + + org_sigset: linux.Sig_Set + sigset: linux.Sig_Set + mem.copy(&sigset, &mask, size_of(mask)) + errno = linux.rt_sigprocmask(.SIG_BLOCK, &sigset, &org_sigset) + if errno != .NONE { + return state, _get_platform_error(errno) + } + defer linux.rt_sigprocmask(.SIG_SETMASK, &org_sigset, nil) + + // In case there was a signal handler on SIGCHLD, avoid race + // condition by checking wait first. + options += {.WNOHANG} + waitid_options := options + {.WNOWAIT, .WEXITED} + info: linux.Sig_Info + errno = linux.waitid(.PID, linux.Id(p.pid), &info, waitid_options, nil) + if errno == .NONE && info.code != 0 { + break big_if + } + + loop: for { + sigset = {} + mem.copy(&sigset, &mask, size_of(mask)) + + _, errno = linux.rt_sigtimedwait(&sigset, &info, &ts) + #partial switch errno { + case .EAGAIN: // timeout + return safe_state(p^, state) + case .EINVAL: + return state, _get_platform_error(errno) + case .EINTR: + continue + case: + if int(info.pid) == p.pid { + break loop + } + } + } + } + } + + state, _ = safe_state(p^, state) + + status: u32 + errno: linux.Errno = .EINTR + for errno == .EINTR { + _, errno = linux.wait4(linux.Pid(p.pid), &status, options, nil) + if errno != .NONE { + return state, _get_platform_error(errno) + } + } + + // terminated by exit + if linux.WIFEXITED(status) { + p.is_done = true + state.exited = true + state.exit_code = int(linux.WEXITSTATUS(status)) + state.success = state.exit_code == 0 + return state, nil + } + + // terminated by signal + if linux.WIFSIGNALED(status) { + // NOTE: what's the correct behavior here?? + p.is_done = true + state.exited = false + state.exit_code = int(linux.WTERMSIG(status)) + state.success = false + return state, nil + } + + return safe_state(p^, state) +} diff --git a/core/os/os2/process_windows.odin b/core/os/os2/process_windows.odin new file mode 100644 index 000000000..4b5e4bc02 --- /dev/null +++ b/core/os/os2/process_windows.odin @@ -0,0 +1,67 @@ +//+private +package os2 + +import "core:runtime" +import "core:time" + +_alloc_command_line_arguments :: proc() -> []string { + return nil +} + +_exit :: proc "contextless" (_: int) -> ! { + runtime.trap() +} + +_get_uid :: proc() -> int { + return -1 +} + +_get_euid :: proc() -> int { + return -1 +} + +_get_gid :: proc() -> int { + return -1 +} + +_get_egid :: proc() -> int { + return -1 +} + +_get_pid :: proc() -> int { + return -1 +} + +_get_ppid :: proc() -> int { + return -1 +} + +Process_Attributes_OS_Specific :: struct{} + +_process_find :: proc(pid: int) -> (Process, Error) { + return Process{}, nil +} + +_process_get_state :: proc(p: Process) -> (Process_State, Error) { + return Process_State{}, nil +} + +_process_start :: proc(name: string, argv: []string, attr: ^Process_Attributes) -> (Process, Error) { + return Process{}, nil +} + +_process_release :: proc(p: ^Process) -> Error { + return nil +} + +_process_kill :: proc(p: ^Process) -> Error { + return nil +} + +_process_signal :: proc(sig: Signal, handler: Signal_Handler) -> Error { + return nil +} + +_process_wait :: proc(p: ^Process, t: time.Duration) -> (Process_State, Error) { + return Process_State{}, nil +} diff --git a/core/os/os2/stat_linux.odin b/core/os/os2/stat_linux.odin index dc287cafe..c0b3088b4 100644 --- a/core/os/os2/stat_linux.odin +++ b/core/os/os2/stat_linux.odin @@ -3,108 +3,32 @@ package os2 import "core:time" import "base:runtime" -import "core:sys/unix" +import "core:sys/linux" import "core:path/filepath" -// File type -S_IFMT :: 0o170000 // Type of file mask -S_IFIFO :: 0o010000 // Named pipe (fifo) -S_IFCHR :: 0o020000 // Character special -S_IFDIR :: 0o040000 // Directory -S_IFBLK :: 0o060000 // Block special -S_IFREG :: 0o100000 // Regular -S_IFLNK :: 0o120000 // Symbolic link -S_IFSOCK :: 0o140000 // Socket - -// File mode -// Read, write, execute/search by owner -S_IRWXU :: 0o0700 // RWX mask for owner -S_IRUSR :: 0o0400 // R for owner -S_IWUSR :: 0o0200 // W for owner -S_IXUSR :: 0o0100 // X for owner - - // Read, write, execute/search by group -S_IRWXG :: 0o0070 // RWX mask for group -S_IRGRP :: 0o0040 // R for group -S_IWGRP :: 0o0020 // W for group -S_IXGRP :: 0o0010 // X for group - - // Read, write, execute/search by others -S_IRWXO :: 0o0007 // RWX mask for other -S_IROTH :: 0o0004 // R for other -S_IWOTH :: 0o0002 // W for other -S_IXOTH :: 0o0001 // X for other - -S_ISUID :: 0o4000 // Set user id on execution -S_ISGID :: 0o2000 // Set group id on execution -S_ISVTX :: 0o1000 // Directory restrcted delete - - -S_ISLNK :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFLNK } -S_ISREG :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFREG } -S_ISDIR :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFDIR } -S_ISCHR :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFCHR } -S_ISBLK :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFBLK } -S_ISFIFO :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFIFO } -S_ISSOCK :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFSOCK } - -F_OK :: 0 // Test for file existance -X_OK :: 1 // Test for execute permission -W_OK :: 2 // Test for write permission -R_OK :: 4 // Test for read permission - -@private -Unix_File_Time :: struct { - seconds: i64, - nanoseconds: i64, -} - -@private -_Stat :: struct { - device_id: u64, // ID of device containing file - serial: u64, // File serial number - nlink: u64, // Number of hard links - mode: u32, // Mode of the file - uid: u32, // User ID of the file's owner - gid: u32, // Group ID of the file's group - _padding: i32, // 32 bits of padding - rdev: u64, // Device ID, if device - size: i64, // Size of the file, in bytes - block_size: i64, // Optimal bllocksize for I/O - blocks: i64, // Number of 512-byte blocks allocated - - last_access: Unix_File_Time, // Time of last access - modified: Unix_File_Time, // Time of last modification - status_change: Unix_File_Time, // Time of last status change - - _reserve1, - _reserve2, - _reserve3: i64, -} - - _fstat :: proc(f: ^File, allocator: runtime.Allocator) -> (File_Info, Error) { return _fstat_internal(f.impl.fd, allocator) } -_fstat_internal :: proc(fd: int, allocator: runtime.Allocator) -> (File_Info, Error) { - s: _Stat - result := unix.sys_fstat(fd, &s) - if result < 0 { - return {}, _get_platform_error(result) +_fstat_internal :: proc(fd: linux.Fd, allocator: runtime.Allocator) -> (File_Info, Error) { + s: linux.Stat + errno := linux.fstat(fd, &s) + if errno != .NONE { + return {}, _get_platform_error(errno) } // TODO: As of Linux 4.11, the new statx syscall can retrieve creation_time fi := File_Info { fullpath = _get_full_path(fd, allocator), name = "", - size = s.size, + size = i64(s.size), mode = 0, - is_directory = S_ISDIR(s.mode), - modification_time = time.Time {s.modified.seconds}, - access_time = time.Time {s.last_access.seconds}, - creation_time = time.Time{0}, // regular stat does not provide this + is_directory = linux.S_ISDIR(s.mode), + modification_time = time.Time {i64(s.mtime.time_sec) * i64(time.Second) + i64(s.mtime.time_nsec)}, + access_time = time.Time {i64(s.atime.time_sec) * i64(time.Second) + i64(s.atime.time_nsec)}, + creation_time = time.Time{i64(s.ctime.time_sec) * i64(time.Second) + i64(s.ctime.time_nsec)}, // regular stat does not provide this } + fi.creation_time = fi.modification_time fi.name = filepath.base(fi.fullpath) return fi, nil @@ -115,11 +39,11 @@ _stat :: proc(name: string, allocator: runtime.Allocator) -> (fi: File_Info, err TEMP_ALLOCATOR_GUARD() name_cstr := temp_cstring(name) or_return - fd := unix.sys_open(name_cstr, _O_RDONLY) - if fd < 0 { - return {}, _get_platform_error(fd) + fd, errno := linux.open(name_cstr, {}) + if errno != .NONE { + return {}, _get_platform_error(errno) } - defer unix.sys_close(fd) + defer linux.close(fd) return _fstat_internal(fd, allocator) } @@ -127,11 +51,11 @@ _lstat :: proc(name: string, allocator: runtime.Allocator) -> (fi: File_Info, er TEMP_ALLOCATOR_GUARD() name_cstr := temp_cstring(name) or_return - fd := unix.sys_open(name_cstr, _O_RDONLY | _O_PATH | _O_NOFOLLOW) - if fd < 0 { - return {}, _get_platform_error(fd) + fd, errno := linux.open(name_cstr, {.PATH, .NOFOLLOW}) + if errno != .NONE { + return {}, _get_platform_error(errno) } - defer unix.sys_close(fd) + defer linux.close(fd) return _fstat_internal(fd, allocator) } From 58cd75350b635fe796586b0cbf73fac4bb864d30 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Thu, 27 Jun 2024 23:21:58 +0200 Subject: [PATCH 039/129] Allow `ODIN_CLANG_PATH=clang-path` overrides Link using `clang`, unless overridden by `ODIN_CLANG_PATH` environment variable. Fixes #3783 --- src/linker.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/linker.cpp b/src/linker.cpp index 9eed14ea9..b9769e0e7 100644 --- a/src/linker.cpp +++ b/src/linker.cpp @@ -578,9 +578,16 @@ gb_internal i32 linker_stage(LinkerData *gen) { } } - gbString link_command_line = gb_string_make(heap_allocator(), "clang -Wno-unused-command-line-argument "); + // Link using `clang`, unless overridden by `ODIN_CLANG_PATH` environment variable. + const char* clang_path = gb_get_env("ODIN_CLANG_PATH", permanent_allocator()); + if (clang_path == NULL) { + clang_path = "clang"; + } + + gbString link_command_line = gb_string_make(heap_allocator(), clang_path); defer (gb_string_free(link_command_line)); + link_command_line = gb_string_appendc(link_command_line, " -Wno-unused-command-line-argument "); link_command_line = gb_string_appendc(link_command_line, object_files); link_command_line = gb_string_append_fmt(link_command_line, " -o \"%.*s\" ", LIT(output_filename)); link_command_line = gb_string_append_fmt(link_command_line, " %s ", platform_lib_str); From 140ee036cef1857feca1444178a3700108e61698 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Thu, 27 Jun 2024 23:29:36 +0200 Subject: [PATCH 040/129] wasm error is no longer relevant --- src/check_decl.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 818556951..b5307838c 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1320,9 +1320,9 @@ gb_internal void check_global_variable_decl(CheckerContext *ctx, Entity *&e, Ast error(e->token, "A foreign variable declaration cannot have a default value"); } init_entity_foreign_library(ctx, e); - if (is_arch_wasm()) { - error(e->token, "A foreign variable declaration are not allowed for the '%.*s' architecture", LIT(target_arch_names[build_context.metrics.arch])); - } + // if (is_arch_wasm()) { + // error(e->token, "A foreign variable declaration are not allowed for the '%.*s' architecture", LIT(target_arch_names[build_context.metrics.arch])); + // } } if (ac.link_name.len > 0) { e->Variable.link_name = ac.link_name; From ed7d34beb0d39ae8ae0fce43513fae809bca8ba4 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Fri, 28 Jun 2024 00:39:51 +0200 Subject: [PATCH 041/129] Avoid sporadic wasm crash --- src/llvm_backend.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 04c4ce244..d119633ec 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -3218,7 +3218,7 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { LLVMSetExternallyInitialized(g.value, true); lb_add_foreign_library_path(m, e->Variable.foreign_library); - lb_set_wasm_import_attributes(g.value, e, name); + // lb_set_wasm_import_attributes(g.value, e, name); } else { LLVMSetInitializer(g.value, LLVMConstNull(lb_type(m, e->type))); } From b79d7e69177ccbc25b75f1aa7a90a62f64c6cee1 Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Fri, 28 Jun 2024 01:16:26 +0200 Subject: [PATCH 042/129] disallow non-global foreign import of variables on wasm --- src/build_settings.cpp | 4 +++- src/check_decl.cpp | 8 ++++---- src/llvm_backend.cpp | 2 -- src/llvm_backend_proc.cpp | 2 +- src/llvm_backend_utility.cpp | 2 +- src/tilde.cpp | 1 - 6 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 0495cf3b5..1988e9cac 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -2053,10 +2053,12 @@ gb_internal void init_build_context(TargetMetrics *cross_target, Subtarget subta gbString link_flags = gb_string_make(heap_allocator(), " "); // link_flags = gb_string_appendc(link_flags, "--export-all "); // link_flags = gb_string_appendc(link_flags, "--export-table "); - link_flags = gb_string_appendc(link_flags, "--allow-undefined "); // if (bc->metrics.arch == TargetArch_wasm64) { // link_flags = gb_string_appendc(link_flags, "-mwasm64 "); // } + if (bc->metrics.os != TargetOs_orca) { + link_flags = gb_string_appendc(link_flags, "--allow-undefined "); + } if (bc->no_entry_point || bc->metrics.os == TargetOs_orca) { link_flags = gb_string_appendc(link_flags, "--no-entry "); } diff --git a/src/check_decl.cpp b/src/check_decl.cpp index b5307838c..883cfcba9 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -709,7 +709,7 @@ gb_internal Entity *init_entity_foreign_library(CheckerContext *ctx, Entity *e) } if (ident == nullptr) { - error(e->token, "foreign entiies must declare which library they are from"); + error(e->token, "foreign entities must declare which library they are from"); } else if (ident->kind != Ast_Ident) { error(ident, "foreign library names must be an identifier"); } else { @@ -1320,9 +1320,9 @@ gb_internal void check_global_variable_decl(CheckerContext *ctx, Entity *&e, Ast error(e->token, "A foreign variable declaration cannot have a default value"); } init_entity_foreign_library(ctx, e); - // if (is_arch_wasm()) { - // error(e->token, "A foreign variable declaration are not allowed for the '%.*s' architecture", LIT(target_arch_names[build_context.metrics.arch])); - // } + if (is_arch_wasm() && e->Variable.foreign_library != nullptr) { + error(e->token, "A foreign variable declaration can not be scoped to a module and must be declared in a 'foreign {' (without a library) block"); + } } if (ac.link_name.len > 0) { e->Variable.link_name = ac.link_name; diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index d119633ec..92c8138c5 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -3217,8 +3217,6 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { LLVMSetDLLStorageClass(g.value, LLVMDLLImportStorageClass); LLVMSetExternallyInitialized(g.value, true); lb_add_foreign_library_path(m, e->Variable.foreign_library); - - // lb_set_wasm_import_attributes(g.value, e, name); } else { LLVMSetInitializer(g.value, LLVMConstNull(lb_type(m, e->type))); } diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 958b4fd38..68ba4f74e 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -233,7 +233,7 @@ gb_internal lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool i if (p->is_foreign) { - lb_set_wasm_import_attributes(p->value, entity, p->name); + lb_set_wasm_procedure_import_attributes(p->value, entity, p->name); } diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp index 94153e233..98ed0c57e 100644 --- a/src/llvm_backend_utility.cpp +++ b/src/llvm_backend_utility.cpp @@ -2018,7 +2018,7 @@ gb_internal LLVMValueRef llvm_get_inline_asm(LLVMTypeRef func_type, String const } -gb_internal void lb_set_wasm_import_attributes(LLVMValueRef value, Entity *entity, String import_name) { +gb_internal void lb_set_wasm_procedure_import_attributes(LLVMValueRef value, Entity *entity, String import_name) { if (!is_arch_wasm()) { return; } diff --git a/src/tilde.cpp b/src/tilde.cpp index 4fc7d1c9b..f6fed0f9a 100644 --- a/src/tilde.cpp +++ b/src/tilde.cpp @@ -363,7 +363,6 @@ gb_internal bool cg_global_variables_create(cgModule *m, Array if (is_foreign) { linkage = TB_LINKAGE_PUBLIC; // lb_add_foreign_library_path(m, e->Variable.foreign_library); - // lb_set_wasm_import_attributes(g.value, e, name); } else if (is_export) { linkage = TB_LINKAGE_PUBLIC; } From 0a504c26478229c9ce5065b2926cf9a3d97b0e45 Mon Sep 17 00:00:00 2001 From: Matthew Pohlmann Date: Thu, 27 Jun 2024 21:41:48 -0700 Subject: [PATCH 043/129] Some fixes to wgpu_native. 1. LogCallback should have the "c" calling convention and takes a userdata pointer like other callbacks. 2. DevicePoll's wrappedSubmissionIndex argument is an optional in/out parameter. The previous wrapper method was broken since it passed a non-nil structure to the underlying API with invalid members. --- vendor/wgpu/wgpu_native.odin | 11 ++--------- vendor/wgpu/wgpu_native_types.odin | 2 +- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/vendor/wgpu/wgpu_native.odin b/vendor/wgpu/wgpu_native.odin index 2b10e3c17..7c106a452 100644 --- a/vendor/wgpu/wgpu_native.odin +++ b/vendor/wgpu/wgpu_native.odin @@ -29,10 +29,9 @@ foreign { RawQueueSubmitForIndex :: proc(queue: Queue, commandCount: uint, commands: [^]CommandBuffer) -> SubmissionIndex --- // Returns true if the queue is empty, or false if there are more queue submissions still in flight. - @(link_name="wgpuDevicePoll") - RawDevicePoll :: proc(device: Device, wait: b32, /* NULLABLE */ wrappedSubmissionIndex: /* const */ ^WrappedSubmissionIndex) -> b32 --- + DevicePoll :: proc(device: Device, wait: b32, /* NULLABLE */ wrappedSubmissionIndex: /* const */ ^WrappedSubmissionIndex = nil) -> b32 --- - SetLogCallback :: proc "odin" (callback: LogCallback) --- + SetLogCallback :: proc(callback: LogCallback, userdata: rawptr) --- SetLogLevel :: proc(level: LogLevel) --- @@ -67,9 +66,3 @@ InstanceEnumerateAdapters :: proc(instance: Instance, options: ^InstanceEnumerat QueueSubmitForIndex :: proc(queue: Queue, commands: []CommandBuffer) -> SubmissionIndex { return RawQueueSubmitForIndex(queue, len(commands), raw_data(commands)) } - -DevicePoll :: proc(device: Device, wait: b32) -> (wrappedSubmissionIndex: WrappedSubmissionIndex, ok: bool) { - ok = bool(RawDevicePoll(device, wait, &wrappedSubmissionIndex)) - return -} - diff --git a/vendor/wgpu/wgpu_native_types.odin b/vendor/wgpu/wgpu_native_types.odin index b0837198f..441cbdec6 100644 --- a/vendor/wgpu/wgpu_native_types.odin +++ b/vendor/wgpu/wgpu_native_types.odin @@ -182,7 +182,7 @@ SurfaceConfigurationExtras :: struct { desiredMaximumFrameLatency: i32, } -LogCallback :: #type proc "odin" (level: LogLevel, message: cstring) +LogCallback :: #type proc "c" (level: LogLevel, message: cstring, userdata: rawptr) // Wrappers From 4bf9de72370d4ab0a8dcea0a09b1eaa30aa0de7f Mon Sep 17 00:00:00 2001 From: Matthew Pohlmann Date: Thu, 27 Jun 2024 21:53:16 -0700 Subject: [PATCH 044/129] SupportedLimitsExtras.chain should be a ChainedStructOut to properly chain from SupportedLimits --- vendor/wgpu/wgpu_native_types.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/wgpu/wgpu_native_types.odin b/vendor/wgpu/wgpu_native_types.odin index 441cbdec6..2133fdd50 100644 --- a/vendor/wgpu/wgpu_native_types.odin +++ b/vendor/wgpu/wgpu_native_types.odin @@ -79,7 +79,7 @@ RequiredLimitsExtras :: struct { } SupportedLimitsExtras :: struct { - using chain: ChainedStruct, + using chain: ChainedStructOut, limits: NativeLimits, } From f883cd5053f7fb0774e81f30da12825481114f69 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 28 Jun 2024 08:33:12 +0100 Subject: [PATCH 045/129] Initialize default `context` in `heap_allocator_other.odin` --- base/runtime/heap_allocator_other.odin | 3 +++ 1 file changed, 3 insertions(+) diff --git a/base/runtime/heap_allocator_other.odin b/base/runtime/heap_allocator_other.odin index d387aada2..8a7ad1a47 100644 --- a/base/runtime/heap_allocator_other.odin +++ b/base/runtime/heap_allocator_other.odin @@ -3,13 +3,16 @@ package runtime _heap_alloc :: proc "contextless" (size: int, zero_memory := true) -> rawptr { + context = default_context() unimplemented("base:runtime 'heap_alloc' procedure is not supported on this platform") } _heap_resize :: proc "contextless" (ptr: rawptr, new_size: int) -> rawptr { + context = default_context() unimplemented("base:runtime 'heap_resize' procedure is not supported on this platform") } _heap_free :: proc "contextless" (ptr: rawptr) { + context = default_context() unimplemented("base:runtime 'heap_free' procedure is not supported on this platform") } From 52ea63f89c7d7c9ff081ab678f9c206e9775a032 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 28 Jun 2024 08:43:25 +0100 Subject: [PATCH 046/129] Fix #3471 --- src/types.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/types.cpp b/src/types.cpp index 97e8267a3..323c06580 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -3224,7 +3224,7 @@ gb_internal Selection lookup_field_with_selection(Type *type_, String field_name } } if (type->kind == Type_Struct) { - wait_signal_until_available(&type->Struct.fields_wait_signal); + // wait_signal_until_available(&type->Struct.fields_wait_signal); isize field_count = type->Struct.fields.count; if (field_count != 0) for_array(i, type->Struct.fields) { Entity *f = type->Struct.fields[i]; @@ -3254,7 +3254,7 @@ gb_internal Selection lookup_field_with_selection(Type *type_, String field_name } if (type->kind == Type_Struct) { - wait_signal_until_available(&type->Struct.fields_wait_signal); + // wait_signal_until_available(&type->Struct.fields_wait_signal); Scope *s = type->Struct.scope; if (s != nullptr) { Entity *found = scope_lookup_current(s, field_name); From 06ff08b9cf50760d17cd49bee0670fa27782aff5 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 28 Jun 2024 08:53:05 +0100 Subject: [PATCH 047/129] Fix #3820 --- src/llvm_backend_expr.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index a23f8cfbe..52dad6547 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -3283,7 +3283,8 @@ gb_internal lbValue lb_build_expr_internal(lbProcedure *p, Ast *expr) { Type *type = type_of_expr(expr); GB_ASSERT_MSG(tv.mode != Addressing_Invalid, "invalid expression '%s' (tv.mode = %d, tv.type = %s) @ %s\n Current Proc: %.*s : %s", expr_to_string(expr), tv.mode, type_to_string(tv.type), token_pos_to_string(expr_pos), LIT(p->name), type_to_string(p->type)); - if (tv.value.kind != ExactValue_Invalid) { + + if (tv.value.kind != ExactValue_Invalid && !is_type_union(type)) { // NOTE(bill): The commented out code below is just for debug purposes only // if (is_type_untyped(type)) { // gb_printf_err("%s %s : %s @ %p\n", token_pos_to_string(expr_pos), expr_to_string(expr), type_to_string(expr->tav.type), expr); From 0c8a81d298797b19e382ec6b2cfea87c448c1ac8 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 28 Jun 2024 08:57:31 +0100 Subject: [PATCH 048/129] Fix #3819 --- src/linker.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/linker.cpp b/src/linker.cpp index b9769e0e7..371736743 100644 --- a/src/linker.cpp +++ b/src/linker.cpp @@ -70,11 +70,23 @@ gb_internal i32 linker_stage(LinkerData *gen) { if (is_arch_wasm()) { timings_start_section(timings, str_lit("wasm-ld")); + gbString lib_str = gb_string_make(heap_allocator(), ""); + gbString extra_orca_flags = gb_string_make(temporary_allocator(), ""); gbString inputs = gb_string_make(temporary_allocator(), ""); inputs = gb_string_append_fmt(inputs, "\"%.*s.o\"", LIT(output_filename)); + + for (Entity *e : gen->foreign_libraries) { + GB_ASSERT(e->kind == Entity_LibraryName); + // NOTE(bill): Add these before the linking values + String extra_linker_flags = string_trim_whitespace(e->LibraryName.extra_linker_flags); + if (extra_linker_flags.len != 0) { + lib_str = gb_string_append_fmt(lib_str, " %.*s", LIT(extra_linker_flags)); + } + } + if (build_context.metrics.os == TargetOs_orca) { gbString orca_sdk_path = gb_string_make(temporary_allocator(), ""); if (!system_exec_command_line_app_output("orca sdk-path", &orca_sdk_path)) { @@ -93,16 +105,18 @@ gb_internal i32 linker_stage(LinkerData *gen) { #if defined(GB_SYSTEM_WINDOWS) result = system_exec_command_line_app("wasm-ld", - "\"%.*s\\bin\\wasm-ld\" %s -o \"%.*s\" %.*s %.*s %s", + "\"%.*s\\bin\\wasm-ld\" %s -o \"%.*s\" %.*s %.*s %s %s", LIT(build_context.ODIN_ROOT), inputs, LIT(output_filename), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags), + lib_str, extra_orca_flags); #else result = system_exec_command_line_app("wasm-ld", - "wasm-ld %s -o \"%.*s\" %.*s %.*s %s", + "wasm-ld %s -o \"%.*s\" %.*s %.*s %s %s", inputs, LIT(output_filename), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags), + lib_str, extra_orca_flags); #endif return result; From 5a9698e8cb8701b122cb484d5fef7e878dae6974 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 28 Jun 2024 09:08:57 +0100 Subject: [PATCH 049/129] Properly fix #3820 --- src/check_expr.cpp | 9 ++++-- src/llvm_backend_expr.cpp | 59 +++++++++++++++++++++++++++++---------- 2 files changed, 52 insertions(+), 16 deletions(-) diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 27e750668..891378b99 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -4431,9 +4431,14 @@ gb_internal void convert_to_typed(CheckerContext *c, Operand *operand, Type *tar defer (gb_string_free(type_str)); if (valid_count == 1) { + Type *new_type = t->Union.variants[first_success_index]; + target_type = new_type; + if (is_type_union(new_type)) { + convert_to_typed(c, operand, new_type); + break; + } + operand->type = new_type; operand->mode = Addressing_Value; - operand->type = t->Union.variants[first_success_index]; - target_type = t->Union.variants[first_success_index]; break; } else if (valid_count > 1) { ERROR_BLOCK(); diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index 52dad6547..46b8fa3cb 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -2044,13 +2044,6 @@ gb_internal lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) { } if (is_type_union(dst)) { - for (Type *vt : dst->Union.variants) { - if (are_types_identical(vt, src_type)) { - lbAddr parent = lb_add_local_generated(p, t, true); - lb_emit_store_union_variant(p, parent.addr, value, vt); - return lb_addr_load(p, parent); - } - } if (dst->Union.variants.count == 1) { Type *vt = dst->Union.variants[0]; if (internal_check_is_assignable_to(src_type, vt)) { @@ -2060,6 +2053,50 @@ gb_internal lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) { return lb_addr_load(p, parent); } } + for (Type *vt : dst->Union.variants) { + if (are_types_identical(src_type, vt)) { + lbAddr parent = lb_add_local_generated(p, t, true); + lb_emit_store_union_variant(p, parent.addr, value, vt); + return lb_addr_load(p, parent); + } + } + ValidIndexAndScore *valids = gb_alloc_array(temporary_allocator(), ValidIndexAndScore, dst->Union.variants.count); + isize valid_count = 0; + isize first_success_index = -1; + for_array(i, dst->Union.variants) { + Type *vt = dst->Union.variants[i]; + i64 score = 0; + if (internal_check_is_assignable_to(src_type, vt)) { + valids[valid_count].index = i; + valids[valid_count].score = score; + valid_count += 1; + if (first_success_index < 0) { + first_success_index = i; + } + } + } + if (valid_count > 1) { + gb_sort_array(valids, valid_count, valid_index_and_score_cmp); + i64 best_score = valids[0].score; + for (isize i = 1; i < valid_count; i++) { + auto v = valids[i]; + if (best_score > v.score) { + valid_count = i; + break; + } + best_score = v.score; + } + first_success_index = valids[0].index; + } + + if (valid_count == 1) { + Type *vt = dst->Union.variants[first_success_index]; + value = lb_emit_conv(p, value, vt); + lbAddr parent = lb_add_local_generated(p, t, true); + lb_emit_store_union_variant(p, parent.addr, value, vt); + return lb_addr_load(p, parent); + } + } // NOTE(bill): This has to be done before 'Pointer <-> Pointer' as it's @@ -3284,13 +3321,7 @@ gb_internal lbValue lb_build_expr_internal(lbProcedure *p, Ast *expr) { GB_ASSERT_MSG(tv.mode != Addressing_Invalid, "invalid expression '%s' (tv.mode = %d, tv.type = %s) @ %s\n Current Proc: %.*s : %s", expr_to_string(expr), tv.mode, type_to_string(tv.type), token_pos_to_string(expr_pos), LIT(p->name), type_to_string(p->type)); - if (tv.value.kind != ExactValue_Invalid && !is_type_union(type)) { - // NOTE(bill): The commented out code below is just for debug purposes only - // if (is_type_untyped(type)) { - // gb_printf_err("%s %s : %s @ %p\n", token_pos_to_string(expr_pos), expr_to_string(expr), type_to_string(expr->tav.type), expr); - // GB_PANIC("%s\n", type_to_string(tv.type)); - // } - + if (tv.value.kind != ExactValue_Invalid) { // NOTE(bill): Short on constant values return lb_const_value(p->module, type, tv.value); } else if (tv.mode == Addressing_Type) { From 862a04376f589b23c34700d8e7c746048741e19f Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 28 Jun 2024 09:16:01 +0100 Subject: [PATCH 050/129] Improve tokenizing wrong number literals --- src/parser.cpp | 12 +++++++++++- src/tokenizer.cpp | 1 + 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/parser.cpp b/src/parser.cpp index 0cd96f5b5..0364e2c2b 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -718,7 +718,17 @@ gb_internal ExactValue exact_value_from_token(AstFile *f, Token const &token) { } ExactValue value = exact_value_from_basic_literal(token.kind, s); if (value.kind == ExactValue_Invalid) { - syntax_error(token, "Invalid token literal"); + switch (token.kind) { + case Token_Integer: + syntax_error(token, "Invalid integer literal"); + break; + case Token_Float: + syntax_error(token, "Invalid float literal"); + break; + default: + syntax_error(token, "Invalid token literal"); + break; + } } return value; } diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index f7751d840..1a37043d7 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -433,6 +433,7 @@ gb_internal gb_inline i32 digit_value(Rune r) { } gb_internal gb_inline void scan_mantissa(Tokenizer *t, i32 base) { + base = 16; // always check for any possible letter while (digit_value(t->curr_rune) < base || t->curr_rune == '_') { advance_to_next_rune(t); } From dde7cb6e7f1c9196286c924fae9e06f6a8f9b43f Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 28 Jun 2024 09:21:33 +0100 Subject: [PATCH 051/129] Improve error message for #3754 --- src/tokenizer.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index 1a37043d7..8458062b6 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -470,6 +470,7 @@ gb_internal void scan_number_to_token(Tokenizer *t, Token *token, bool seen_deci advance_to_next_rune(t); scan_mantissa(t, 2); if (t->curr - prev <= 2) { + tokenizer_err(t, "Invalid binary integer"); token->kind = Token_Invalid; } goto end; @@ -477,6 +478,7 @@ gb_internal void scan_number_to_token(Tokenizer *t, Token *token, bool seen_deci advance_to_next_rune(t); scan_mantissa(t, 8); if (t->curr - prev <= 2) { + tokenizer_err(t, "Invalid octal integer"); token->kind = Token_Invalid; } goto end; @@ -484,6 +486,7 @@ gb_internal void scan_number_to_token(Tokenizer *t, Token *token, bool seen_deci advance_to_next_rune(t); scan_mantissa(t, 10); if (t->curr - prev <= 2) { + tokenizer_err(t, "Invalid explicitly decimal integer"); token->kind = Token_Invalid; } goto end; @@ -491,6 +494,7 @@ gb_internal void scan_number_to_token(Tokenizer *t, Token *token, bool seen_deci advance_to_next_rune(t); scan_mantissa(t, 12); if (t->curr - prev <= 2) { + tokenizer_err(t, "Invalid dozenal integer"); token->kind = Token_Invalid; } goto end; @@ -498,6 +502,7 @@ gb_internal void scan_number_to_token(Tokenizer *t, Token *token, bool seen_deci advance_to_next_rune(t); scan_mantissa(t, 16); if (t->curr - prev <= 2) { + tokenizer_err(t, "Invalid hexadecimal integer"); token->kind = Token_Invalid; } goto end; @@ -506,6 +511,7 @@ gb_internal void scan_number_to_token(Tokenizer *t, Token *token, bool seen_deci advance_to_next_rune(t); scan_mantissa(t, 16); if (t->curr - prev <= 2) { + tokenizer_err(t, "Invalid hexadecimal float"); token->kind = Token_Invalid; } else { u8 *start = prev+2; From 35651cfc173bc42f1afc19c4e2cec46501808dd0 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 28 Jun 2024 09:24:34 +0100 Subject: [PATCH 052/129] Improve tokenization for false integer literals but not effect possible float literals --- src/tokenizer.cpp | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index 8458062b6..2af41b881 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -432,8 +432,10 @@ gb_internal gb_inline i32 digit_value(Rune r) { return 16; // NOTE(bill): Larger than highest possible } -gb_internal gb_inline void scan_mantissa(Tokenizer *t, i32 base) { - base = 16; // always check for any possible letter +gb_internal gb_inline void scan_mantissa(Tokenizer *t, i32 base, bool force_base) { + if (!force_base) { + base = 16; // always check for any possible letter + } while (digit_value(t->curr_rune) < base || t->curr_rune == '_') { advance_to_next_rune(t); } @@ -458,7 +460,7 @@ gb_internal void scan_number_to_token(Tokenizer *t, Token *token, bool seen_deci token->string.len += 1; token->pos.column -= 1; token->kind = Token_Float; - scan_mantissa(t, 10); + scan_mantissa(t, 10, true); goto exponent; } @@ -468,7 +470,7 @@ gb_internal void scan_number_to_token(Tokenizer *t, Token *token, bool seen_deci switch (t->curr_rune) { case 'b': // Binary advance_to_next_rune(t); - scan_mantissa(t, 2); + scan_mantissa(t, 2, false); if (t->curr - prev <= 2) { tokenizer_err(t, "Invalid binary integer"); token->kind = Token_Invalid; @@ -476,7 +478,7 @@ gb_internal void scan_number_to_token(Tokenizer *t, Token *token, bool seen_deci goto end; case 'o': // Octal advance_to_next_rune(t); - scan_mantissa(t, 8); + scan_mantissa(t, 8, false); if (t->curr - prev <= 2) { tokenizer_err(t, "Invalid octal integer"); token->kind = Token_Invalid; @@ -484,7 +486,7 @@ gb_internal void scan_number_to_token(Tokenizer *t, Token *token, bool seen_deci goto end; case 'd': // Decimal advance_to_next_rune(t); - scan_mantissa(t, 10); + scan_mantissa(t, 10, false); if (t->curr - prev <= 2) { tokenizer_err(t, "Invalid explicitly decimal integer"); token->kind = Token_Invalid; @@ -492,7 +494,7 @@ gb_internal void scan_number_to_token(Tokenizer *t, Token *token, bool seen_deci goto end; case 'z': // Dozenal advance_to_next_rune(t); - scan_mantissa(t, 12); + scan_mantissa(t, 12, false); if (t->curr - prev <= 2) { tokenizer_err(t, "Invalid dozenal integer"); token->kind = Token_Invalid; @@ -500,7 +502,7 @@ gb_internal void scan_number_to_token(Tokenizer *t, Token *token, bool seen_deci goto end; case 'x': // Hexadecimal advance_to_next_rune(t); - scan_mantissa(t, 16); + scan_mantissa(t, 16, false); if (t->curr - prev <= 2) { tokenizer_err(t, "Invalid hexadecimal integer"); token->kind = Token_Invalid; @@ -509,7 +511,7 @@ gb_internal void scan_number_to_token(Tokenizer *t, Token *token, bool seen_deci case 'h': // Hexadecimal Float token->kind = Token_Float; advance_to_next_rune(t); - scan_mantissa(t, 16); + scan_mantissa(t, 16, false); if (t->curr - prev <= 2) { tokenizer_err(t, "Invalid hexadecimal float"); token->kind = Token_Invalid; @@ -534,12 +536,12 @@ gb_internal void scan_number_to_token(Tokenizer *t, Token *token, bool seen_deci } goto end; default: - scan_mantissa(t, 10); + scan_mantissa(t, 10, true); goto fraction; } } - scan_mantissa(t, 10); + scan_mantissa(t, 10, true); fraction: @@ -551,7 +553,7 @@ fraction: advance_to_next_rune(t); token->kind = Token_Float; - scan_mantissa(t, 10); + scan_mantissa(t, 10, true); } exponent: @@ -561,7 +563,7 @@ exponent: if (t->curr_rune == '-' || t->curr_rune == '+') { advance_to_next_rune(t); } - scan_mantissa(t, 10); + scan_mantissa(t, 10, false); } switch (t->curr_rune) { From 67e9a6fd9bedf92498f41aa206d042566ad43595 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 28 Jun 2024 10:04:08 +0100 Subject: [PATCH 053/129] Improve error reporting on "Failed to parse fail" and show the line error if possible --- src/parser.cpp | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/parser.cpp b/src/parser.cpp index 0364e2c2b..0e971f792 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -35,18 +35,38 @@ gb_internal gbString get_file_line_as_string(TokenPos const &pos, i32 *offset_) if (file == nullptr) { return nullptr; } - isize offset = pos.offset; - u8 *start = file->tokenizer.start; u8 *end = file->tokenizer.end; if (start == end) { return nullptr; } + + isize offset = pos.offset; + if (pos.line != 0 && offset == 0) { + for (i32 i = 1; i < pos.line; i++) { + while (start+offset < end) { + u8 c = start[offset++]; + if (c == '\n') { + break; + } + } + } + for (i32 i = 1; i < pos.column; i++) { + u8 *ptr = start+offset; + u8 c = *ptr; + if (c & 0x80) { + offset += utf8_decode(ptr, end-ptr, nullptr); + } else { + offset++; + } + } + } + + isize len = end-start; if (len < offset) { return nullptr; } - u8 *pos_offset = start+offset; u8 *line_start = pos_offset; @@ -70,6 +90,7 @@ gb_internal gbString get_file_line_as_string(TokenPos const &pos, i32 *offset_) if (offset_) *offset_ = cast(i32)(pos_offset - the_line.text); + return gb_string_make_length(heap_allocator(), the_line.text, the_line.len); } @@ -5417,6 +5438,7 @@ gb_internal WORKER_TASK_PROC(parser_worker_proc) { gb_internal void parser_add_file_to_process(Parser *p, AstPackage *pkg, FileInfo fi, TokenPos pos) { ImportedFile f = {pkg, fi, pos, p->file_to_process_count++}; + f.pos.file_id = cast(i32)(f.index+1); auto wd = gb_alloc_item(permanent_allocator(), ParserWorkerData); wd->parser = p; wd->imported_file = f; @@ -5453,6 +5475,7 @@ gb_internal WORKER_TASK_PROC(foreign_file_worker_proc) { gb_internal void parser_add_foreign_file_to_process(Parser *p, AstPackage *pkg, AstForeignFileKind kind, FileInfo fi, TokenPos pos) { // TODO(bill): Use a better allocator ImportedFile f = {pkg, fi, pos, p->file_to_process_count++}; + f.pos.file_id = cast(i32)(f.index+1); auto wd = gb_alloc_item(permanent_allocator(), ForeignFileWorkerData); wd->parser = p; wd->imported_file = f; From ec38215842e75eeba5e10f1f8a1419b872eb6af9 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 28 Jun 2024 10:09:46 +0100 Subject: [PATCH 054/129] Fix #3803 --- src/check_type.cpp | 8 +++++--- src/checker.cpp | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/check_type.cpp b/src/check_type.cpp index c56c8a739..7fd9b379a 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -335,7 +335,7 @@ bool check_constant_parameter_value(Type *type, Ast *expr) { gb_internal Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *polymorphic_params, bool *is_polymorphic_, - Ast *node, Array *poly_operands) { + Array *poly_operands) { Type *polymorphic_params_type = nullptr; GB_ASSERT(is_polymorphic_ != nullptr); @@ -643,13 +643,14 @@ gb_internal void check_struct_type(CheckerContext *ctx, Type *struct_type, Ast * context = str_lit("struct #raw_union"); } + struct_type->Struct.node = node; struct_type->Struct.scope = ctx->scope; struct_type->Struct.is_packed = st->is_packed; struct_type->Struct.is_no_copy = st->is_no_copy; struct_type->Struct.polymorphic_params = check_record_polymorphic_params( ctx, st->polymorphic_params, &struct_type->Struct.is_polymorphic, - node, poly_operands + poly_operands ); wait_signal_set(&struct_type->Struct.polymorphic_wait_signal); @@ -696,11 +697,12 @@ gb_internal void check_union_type(CheckerContext *ctx, Type *union_type, Ast *no ast_node(ut, UnionType, node); + union_type->Union.node = node; union_type->Union.scope = ctx->scope; union_type->Union.polymorphic_params = check_record_polymorphic_params( ctx, ut->polymorphic_params, &union_type->Union.is_polymorphic, - node, poly_operands + poly_operands ); wait_signal_set(&union_type->Union.polymorphic_wait_signal); diff --git a/src/checker.cpp b/src/checker.cpp index fdf5a8b7d..8ccdcb9f7 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -346,6 +346,7 @@ gb_internal Scope *scope_of_node(Ast *node) { gb_internal void check_open_scope(CheckerContext *c, Ast *node) { node = unparen_expr(node); + GB_ASSERT(node != nullptr); GB_ASSERT(node->kind == Ast_Invalid || is_ast_stmt(node) || is_ast_type(node)); From 9a4ffa79db65c565c7de96dcd1f59ebb64ee0532 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 28 Jun 2024 10:17:00 +0100 Subject: [PATCH 055/129] Add missing libraries to examples/all --- examples/all/all_main.odin | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/examples/all/all_main.odin b/examples/all/all_main.odin index 9c0d28a91..eefb29aa8 100644 --- a/examples/all/all_main.odin +++ b/examples/all/all_main.odin @@ -49,19 +49,21 @@ import tuplehash "core:crypto/tuplehash" import x25519 "core:crypto/x25519" import pe "core:debug/pe" +import trace "core:debug/trace" import dynlib "core:dynlib" import net "core:net" +import ansi "core:encoding/ansi" import base32 "core:encoding/base32" import base64 "core:encoding/base64" +import cbor "core:encoding/cbor" import csv "core:encoding/csv" +import endian "core:encoding/endian" import hxa "core:encoding/hxa" import json "core:encoding/json" import varint "core:encoding/varint" import xml "core:encoding/xml" -import endian "core:encoding/endian" -import cbor "core:encoding/cbor" import uuid "core:encoding/uuid" import uuid_legacy "core:encoding/uuid/legacy" @@ -70,6 +72,7 @@ import hash "core:hash" import xxhash "core:hash/xxhash" import image "core:image" +import bmp "core:image/bmp" import netpbm "core:image/netpbm" import png "core:image/png" import qoi "core:image/qoi" @@ -91,6 +94,7 @@ import ease "core:math/ease" import cmplx "core:math/cmplx" import mem "core:mem" +import tlsf "core:mem/tlsf" import virtual "core:mem/virtual" import ast "core:odin/ast" @@ -105,6 +109,8 @@ import os "core:os" import slashpath "core:path/slashpath" import filepath "core:path/filepath" +import relative "core:relative" + import reflect "core:reflect" import runtime "base:runtime" import simd "core:simd" @@ -115,11 +121,13 @@ import strconv "core:strconv" import strings "core:strings" import sync "core:sync" import testing "core:testing" -import scanner "core:text/scanner" + +import edit "core:text/edit" import i18n "core:text/i18n" import match "core:text/match" +import scanner "core:text/scanner" import table "core:text/table" -import edit "core:text/edit" + import thread "core:thread" import time "core:time" import datetime "core:time/datetime" @@ -176,8 +184,10 @@ _ :: sm3 _ :: tuplehash _ :: x25519 _ :: pe +_ :: trace _ :: dynlib _ :: net +_ :: ansi _ :: base32 _ :: base64 _ :: csv @@ -191,6 +201,7 @@ _ :: fmt _ :: hash _ :: xxhash _ :: image +_ :: bmp _ :: netpbm _ :: png _ :: qoi @@ -209,6 +220,7 @@ _ :: rand _ :: ease _ :: cmplx _ :: mem +_ :: tlsf _ :: virtual _ :: ast _ :: doc_format @@ -218,6 +230,7 @@ _ :: os _ :: spall _ :: slashpath _ :: filepath +_ :: relative _ :: reflect _ :: runtime _ :: simd From e15c5c4692adb746bff6e7f85ca653b59ccb5384 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 28 Jun 2024 10:32:16 +0100 Subject: [PATCH 056/129] Fix missing import --- core/debug/trace/trace_nil.odin | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/debug/trace/trace_nil.odin b/core/debug/trace/trace_nil.odin index 40478898b..33cf31364 100644 --- a/core/debug/trace/trace_nil.odin +++ b/core/debug/trace/trace_nil.odin @@ -1,6 +1,8 @@ //+build !windows !linux !darwin package debug_trace +import "base:runtime" + _Context :: struct { } From bef3ca98f03ed5ff77b2a8b67975ec3e4cfded6a Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 28 Jun 2024 11:01:57 +0100 Subject: [PATCH 057/129] Fix signature --- core/debug/trace/trace_nil.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/debug/trace/trace_nil.odin b/core/debug/trace/trace_nil.odin index 33cf31364..a7f5c10fd 100644 --- a/core/debug/trace/trace_nil.odin +++ b/core/debug/trace/trace_nil.odin @@ -12,7 +12,7 @@ _init :: proc(ctx: ^Context) -> (ok: bool) { _destroy :: proc(ctx: ^Context) -> bool { return true } -_frames :: proc(ctx: ^Context, skip: uint, allocator: runtime.Allocator) -> []Frame { +_frames :: proc(ctx: ^Context, skip: uint, frames_buffer: []Frame) -> []Frame { return nil } _resolve :: proc(ctx: ^Context, frame: Frame, allocator: runtime.Allocator) -> (result: runtime.Source_Code_Location) { From 1747fdc3f0a88ddf851c5b2a58c4f2e04e532b84 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 28 Jun 2024 11:07:54 +0100 Subject: [PATCH 058/129] Fix signature --- core/debug/trace/trace_nil.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/debug/trace/trace_nil.odin b/core/debug/trace/trace_nil.odin index a7f5c10fd..8611d7726 100644 --- a/core/debug/trace/trace_nil.odin +++ b/core/debug/trace/trace_nil.odin @@ -15,6 +15,6 @@ _destroy :: proc(ctx: ^Context) -> bool { _frames :: proc(ctx: ^Context, skip: uint, frames_buffer: []Frame) -> []Frame { return nil } -_resolve :: proc(ctx: ^Context, frame: Frame, allocator: runtime.Allocator) -> (result: runtime.Source_Code_Location) { +_resolve :: proc(ctx: ^Context, frame: Frame, allocator: runtime.Allocator) -> (result: Frame_Location) { return } From 17efb87eef5c24bdc95da8b2406e4bde13941251 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 28 Jun 2024 11:44:05 +0100 Subject: [PATCH 059/129] Add `-custom-attribute` --- src/build_settings.cpp | 4 ++++ src/checker.cpp | 5 +++-- src/main.cpp | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 1988e9cac..4b348256b 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -862,6 +862,8 @@ struct BuildContext { bool keep_object_files; bool disallow_do; + StringSet custom_attributes; + bool strict_style; bool ignore_warnings; @@ -1882,6 +1884,8 @@ gb_internal void init_build_context(TargetMetrics *cross_target, Subtarget subta bc->thread_count = gb_max(bc->affinity.thread_count, 1); } + string_set_init(&bc->custom_attributes); + bc->ODIN_VENDOR = str_lit("odin"); bc->ODIN_VERSION = ODIN_VERSION; bc->ODIN_ROOT = odin_root_dir(); diff --git a/src/checker.cpp b/src/checker.cpp index 8ccdcb9f7..734659510 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -3900,10 +3900,11 @@ gb_internal void check_decl_attributes(CheckerContext *c, Array const &at } if (!proc(c, elem, name, value, ac)) { - if (!build_context.ignore_unknown_attributes) { + if (!build_context.ignore_unknown_attributes && + !string_set_exists(&build_context.custom_attributes, name)) { ERROR_BLOCK(); error(elem, "Unknown attribute element name '%.*s'", LIT(name)); - error_line("\tDid you forget to use build flag '-ignore-unknown-attributes'?\n"); + error_line("\tDid you forget to use the build flag '-ignore-unknown-attributes' or '-custom-attribute:%.*s'?\n", LIT(name)); } } } diff --git a/src/main.cpp b/src/main.cpp index 1896dd0b7..b24796559 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -301,6 +301,7 @@ enum BuildFlagKind { BuildFlag_VetStyle, BuildFlag_VetSemicolon, + BuildFlag_CustomAttribute, BuildFlag_IgnoreUnknownAttributes, BuildFlag_ExtraLinkerFlags, BuildFlag_ExtraAssemblerFlags, @@ -499,6 +500,7 @@ gb_internal bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_VetStyle, str_lit("vet-style"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_VetSemicolon, str_lit("vet-semicolon"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_CustomAttribute, str_lit("custom-attribute"), BuildFlagParam_String, Command__does_check, true); add_flag(&build_flags, BuildFlag_IgnoreUnknownAttributes, str_lit("ignore-unknown-attributes"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_ExtraLinkerFlags, str_lit("extra-linker-flags"), BuildFlagParam_String, Command__does_build); add_flag(&build_flags, BuildFlag_ExtraAssemblerFlags, str_lit("extra-assembler-flags"), BuildFlagParam_String, Command__does_build); @@ -1151,6 +1153,29 @@ gb_internal bool parse_build_flags(Array args) { case BuildFlag_VetStyle: build_context.vet_flags |= VetFlag_Style; break; case BuildFlag_VetSemicolon: build_context.vet_flags |= VetFlag_Semicolon; break; + case BuildFlag_CustomAttribute: + { + GB_ASSERT(value.kind == ExactValue_String); + String val = value.value_string; + String_Iterator it = {val, 0}; + for (;;) { + String attr = string_split_iterator(&it, ','); + if (attr.len == 0) { + break; + } + + attr = string_trim_whitespace(attr); + if (!string_is_valid_identifier(attr)) { + gb_printf_err("-custom-attribute '%.*s' must be a valid identifier\n", LIT(attr)); + bad_flags = true; + continue; + } + + string_set_add(&build_context.custom_attributes, attr); + } + } + break; + case BuildFlag_IgnoreUnknownAttributes: build_context.ignore_unknown_attributes = true; break; @@ -2221,6 +2246,15 @@ gb_internal void print_show_help(String const arg0, String const &command) { } if (check) { + print_usage_line(1, "-custom-attribute:"); + print_usage_line(2, "Add a custom attribute which will be ignored if it is unknown."); + print_usage_line(2, "This can be used with metaprogramming tools."); + print_usage_line(2, "Examples:"); + print_usage_line(3, "-custom-attribute:my_tag"); + print_usage_line(3, "-custom-attribute:my_tag,the_other_thing"); + print_usage_line(3, "-custom-attribute:my_tag -custom-attribute:the_other_thing"); + print_usage_line(0, ""); + print_usage_line(1, "-ignore-unknown-attributes"); print_usage_line(2, "Ignores unknown attributes."); print_usage_line(2, "This can be used with metaprogramming tools."); From a15cbc474dd163457bb4677113ec0ee6cb9a12eb Mon Sep 17 00:00:00 2001 From: jason Date: Fri, 28 Jun 2024 07:45:24 -0400 Subject: [PATCH 060/129] change error strings to an enumerated array in rodata; print_error takes a file argument --- core/os/os2/errors.odin | 4 +- core/os/os2/errors_linux.odin | 273 +++++++++++++++++---------------- core/os/os2/process_linux.odin | 2 +- core/sys/linux/bits.odin | 2 + 4 files changed, 142 insertions(+), 139 deletions(-) diff --git a/core/os/os2/errors.odin b/core/os/os2/errors.odin index f7cfdbd3d..51d8314b4 100644 --- a/core/os/os2/errors.odin +++ b/core/os/os2/errors.odin @@ -100,7 +100,7 @@ error_string :: proc(ferr: Error) -> string { return "unknown error" } -print_error :: proc(ferr: Error, msg: string) { +print_error :: proc(f: ^File, ferr: Error, msg: string) { TEMP_ALLOCATOR_GUARD() err_str := error_string(ferr) @@ -113,5 +113,5 @@ print_error :: proc(ferr: Error, msg: string) { buf[len(msg) + 1] = ' ' copy(buf[len(msg) + 2:], err_str) buf[length - 1] = '\n' - write(stderr, buf) + write(f, buf) } diff --git a/core/os/os2/errors_linux.odin b/core/os/os2/errors_linux.odin index 503f10671..d7234ce8b 100644 --- a/core/os/os2/errors_linux.odin +++ b/core/os/os2/errors_linux.odin @@ -3,141 +3,142 @@ package os2 import "core:sys/linux" -_errno_strings : [int(max(linux.Errno)) + 1]string = { - linux.Errno.NONE = "Success", - linux.Errno.EPERM = "Operation not permitted", - linux.Errno.ENOENT = "No such file or directory", - linux.Errno.ESRCH = "No such process", - linux.Errno.EINTR = "Interrupted system call", - linux.Errno.EIO = "Input/output error", - linux.Errno.ENXIO = "No such device or address", - linux.Errno.E2BIG = "Argument list too long", - linux.Errno.ENOEXEC = "Exec format error", - linux.Errno.EBADF = "Bad file descriptor", - linux.Errno.ECHILD = "No child processes", - linux.Errno.EAGAIN = "Resource temporarily unavailable", - linux.Errno.ENOMEM = "Cannot allocate memory", - linux.Errno.EACCES = "Permission denied", - linux.Errno.EFAULT = "Bad address", - linux.Errno.ENOTBLK = "Block device required", - linux.Errno.EBUSY = "Device or resource busy", - linux.Errno.EEXIST = "File exists", - linux.Errno.EXDEV = "Invalid cross-device link", - linux.Errno.ENODEV = "No such device", - linux.Errno.ENOTDIR = "Not a directory", - linux.Errno.EISDIR = "Is a directory", - linux.Errno.EINVAL = "Invalid argument", - linux.Errno.ENFILE = "Too many open files in system", - linux.Errno.EMFILE = "Too many open files", - linux.Errno.ENOTTY = "Inappropriate ioctl for device", - linux.Errno.ETXTBSY = "Text file busy", - linux.Errno.EFBIG = "File too large", - linux.Errno.ENOSPC = "No space left on device", - linux.Errno.ESPIPE = "Illegal seek", - linux.Errno.EROFS = "Read-only file system", - linux.Errno.EMLINK = "Too many links", - linux.Errno.EPIPE = "Broken pipe", - linux.Errno.EDOM = "Numerical argument out of domain", - linux.Errno.ERANGE = "Numerical result out of range", - linux.Errno.EDEADLK = "Resource deadlock avoided", - linux.Errno.ENAMETOOLONG = "File name too long", - linux.Errno.ENOLCK = "No locks available", - linux.Errno.ENOSYS = "Function not implemented", - linux.Errno.ENOTEMPTY = "Directory not empty", - linux.Errno.ELOOP = "Too many levels of symbolic links", - 41 = "Unknown Error (41)", - linux.Errno.ENOMSG = "No message of desired type", - linux.Errno.EIDRM = "Identifier removed", - linux.Errno.ECHRNG = "Channel number out of range", - linux.Errno.EL2NSYNC = "Level 2 not synchronized", - linux.Errno.EL3HLT = "Level 3 halted", - linux.Errno.EL3RST = "Level 3 reset", - linux.Errno.ELNRNG = "Link number out of range", - linux.Errno.EUNATCH = "Protocol driver not attached", - linux.Errno.ENOCSI = "No CSI structure available", - linux.Errno.EL2HLT = "Level 2 halted", - linux.Errno.EBADE = "Invalid exchange", - linux.Errno.EBADR = "Invalid request descriptor", - linux.Errno.EXFULL = "Exchange full", - linux.Errno.ENOANO = "No anode", - linux.Errno.EBADRQC = "Invalid request code", - linux.Errno.EBADSLT = "Invalid slot", - 58 = "Unknown Error (58)", - linux.Errno.EBFONT = "Bad font file format", - linux.Errno.ENOSTR = "Device not a stream", - linux.Errno.ENODATA = "No data available", - linux.Errno.ETIME = "Timer expired", - linux.Errno.ENOSR = "Out of streams resources", - linux.Errno.ENONET = "Machine is not on the network", - linux.Errno.ENOPKG = "Package not installed", - linux.Errno.EREMOTE = "Object is remote", - linux.Errno.ENOLINK = "Link has been severed", - linux.Errno.EADV = "Advertise error", - linux.Errno.ESRMNT = "Srmount error", - linux.Errno.ECOMM = "Communication error on send", - linux.Errno.EPROTO = "Protocol error", - linux.Errno.EMULTIHOP = "Multihop attempted", - linux.Errno.EDOTDOT = "RFS specific error", - linux.Errno.EBADMSG = "Bad message", - linux.Errno.EOVERFLOW = "Value too large for defined data type", - linux.Errno.ENOTUNIQ = "Name not unique on network", - linux.Errno.EBADFD = "File descriptor in bad state", - linux.Errno.EREMCHG = "Remote address changed", - linux.Errno.ELIBACC = "Can not access a needed shared library", - linux.Errno.ELIBBAD = "Accessing a corrupted shared library", - linux.Errno.ELIBSCN = ".lib section in a.out corrupted", - linux.Errno.ELIBMAX = "Attempting to link in too many shared libraries", - linux.Errno.ELIBEXEC = "Cannot exec a shared library directly", - linux.Errno.EILSEQ = "Invalid or incomplete multibyte or wide character", - linux.Errno.ERESTART = "Interrupted system call should be restarted", - linux.Errno.ESTRPIPE = "Streams pipe error", - linux.Errno.EUSERS = "Too many users", - linux.Errno.ENOTSOCK = "Socket operation on non-socket", - linux.Errno.EDESTADDRREQ = "Destination address required", - linux.Errno.EMSGSIZE = "Message too long", - linux.Errno.EPROTOTYPE = "Protocol wrong type for socket", - linux.Errno.ENOPROTOOPT = "Protocol not available", - linux.Errno.EPROTONOSUPPORT = "Protocol not supported", - linux.Errno.ESOCKTNOSUPPORT = "Socket type not supported", - linux.Errno.EOPNOTSUPP = "Operation not supported", - linux.Errno.EPFNOSUPPORT = "Protocol family not supported", - linux.Errno.EAFNOSUPPORT = "Address family not supported by protocol", - linux.Errno.EADDRINUSE = "Address already in use", - linux.Errno.EADDRNOTAVAIL = "Cannot assign requested address", - linux.Errno.ENETDOWN = "Network is down", - linux.Errno.ENETUNREACH = "Network is unreachable", - linux.Errno.ENETRESET = "Network dropped connection on reset", - linux.Errno.ECONNABORTED = "Software caused connection abort", - linux.Errno.ECONNRESET = "Connection reset by peer", - linux.Errno.ENOBUFS = "No buffer space available", - linux.Errno.EISCONN = "Transport endpoint is already connected", - linux.Errno.ENOTCONN = "Transport endpoint is not connected", - linux.Errno.ESHUTDOWN = "Cannot send after transport endpoint shutdown", - linux.Errno.ETOOMANYREFS = "Too many references: cannot splice", - linux.Errno.ETIMEDOUT = "Connection timed out", - linux.Errno.ECONNREFUSED = "Connection refused", - linux.Errno.EHOSTDOWN = "Host is down", - linux.Errno.EHOSTUNREACH = "No route to host", - linux.Errno.EALREADY = "Operation already in progress", - linux.Errno.EINPROGRESS = "Operation now in progress", - linux.Errno.ESTALE = "Stale file handle", - linux.Errno.EUCLEAN = "Structure needs cleaning", - linux.Errno.ENOTNAM = "Not a XENIX named type file", - linux.Errno.ENAVAIL = "No XENIX semaphores available", - linux.Errno.EISNAM = "Is a named type file", - linux.Errno.EREMOTEIO = "Remote I/O error", - linux.Errno.EDQUOT = "Disk quota exceeded", - linux.Errno.ENOMEDIUM = "No medium found", - linux.Errno.EMEDIUMTYPE = "Wrong medium type", - linux.Errno.ECANCELED = "Operation canceled", - linux.Errno.ENOKEY = "Required key not available", - linux.Errno.EKEYEXPIRED = "Key has expired", - linux.Errno.EKEYREVOKED = "Key has been revoked", - linux.Errno.EKEYREJECTED = "Key was rejected by service", - linux.Errno.EOWNERDEAD = "Owner died", - linux.Errno.ENOTRECOVERABLE = "State not recoverable", - linux.Errno.ERFKILL = "Operation not possible due to RF-kill", - linux.Errno.EHWPOISON = "Memory page has hardware error", +@(rodata) +_errno_strings : [linux.Errno]string = { + .NONE = "Success", + .EPERM = "Operation not permitted", + .ENOENT = "No such file or directory", + .ESRCH = "No such process", + .EINTR = "Interrupted system call", + .EIO = "Input/output error", + .ENXIO = "No such device or address", + .E2BIG = "Argument list too long", + .ENOEXEC = "Exec format error", + .EBADF = "Bad file descriptor", + .ECHILD = "No child processes", + .EAGAIN = "Resource temporarily unavailable", + .ENOMEM = "Cannot allocate memory", + .EACCES = "Permission denied", + .EFAULT = "Bad address", + .ENOTBLK = "Block device required", + .EBUSY = "Device or resource busy", + .EEXIST = "File exists", + .EXDEV = "Invalid cross-device link", + .ENODEV = "No such device", + .ENOTDIR = "Not a directory", + .EISDIR = "Is a directory", + .EINVAL = "Invalid argument", + .ENFILE = "Too many open files in system", + .EMFILE = "Too many open files", + .ENOTTY = "Inappropriate ioctl for device", + .ETXTBSY = "Text file busy", + .EFBIG = "File too large", + .ENOSPC = "No space left on device", + .ESPIPE = "Illegal seek", + .EROFS = "Read-only file system", + .EMLINK = "Too many links", + .EPIPE = "Broken pipe", + .EDOM = "Numerical argument out of domain", + .ERANGE = "Numerical result out of range", + .EDEADLK = "Resource deadlock avoided", + .ENAMETOOLONG = "File name too long", + .ENOLCK = "No locks available", + .ENOSYS = "Function not implemented", + .ENOTEMPTY = "Directory not empty", + .ELOOP = "Too many levels of symbolic links", + .EUNKNOWN_41 = "Unknown Error (41)", + .ENOMSG = "No message of desired type", + .EIDRM = "Identifier removed", + .ECHRNG = "Channel number out of range", + .EL2NSYNC = "Level 2 not synchronized", + .EL3HLT = "Level 3 halted", + .EL3RST = "Level 3 reset", + .ELNRNG = "Link number out of range", + .EUNATCH = "Protocol driver not attached", + .ENOCSI = "No CSI structure available", + .EL2HLT = "Level 2 halted", + .EBADE = "Invalid exchange", + .EBADR = "Invalid request descriptor", + .EXFULL = "Exchange full", + .ENOANO = "No anode", + .EBADRQC = "Invalid request code", + .EBADSLT = "Invalid slot", + .EUNKNOWN_58 = "Unknown Error (58)", + .EBFONT = "Bad font file format", + .ENOSTR = "Device not a stream", + .ENODATA = "No data available", + .ETIME = "Timer expired", + .ENOSR = "Out of streams resources", + .ENONET = "Machine is not on the network", + .ENOPKG = "Package not installed", + .EREMOTE = "Object is remote", + .ENOLINK = "Link has been severed", + .EADV = "Advertise error", + .ESRMNT = "Srmount error", + .ECOMM = "Communication error on send", + .EPROTO = "Protocol error", + .EMULTIHOP = "Multihop attempted", + .EDOTDOT = "RFS specific error", + .EBADMSG = "Bad message", + .EOVERFLOW = "Value too large for defined data type", + .ENOTUNIQ = "Name not unique on network", + .EBADFD = "File descriptor in bad state", + .EREMCHG = "Remote address changed", + .ELIBACC = "Can not access a needed shared library", + .ELIBBAD = "Accessing a corrupted shared library", + .ELIBSCN = ".lib section in a.out corrupted", + .ELIBMAX = "Attempting to link in too many shared libraries", + .ELIBEXEC = "Cannot exec a shared library directly", + .EILSEQ = "Invalid or incomplete multibyte or wide character", + .ERESTART = "Interrupted system call should be restarted", + .ESTRPIPE = "Streams pipe error", + .EUSERS = "Too many users", + .ENOTSOCK = "Socket operation on non-socket", + .EDESTADDRREQ = "Destination address required", + .EMSGSIZE = "Message too long", + .EPROTOTYPE = "Protocol wrong type for socket", + .ENOPROTOOPT = "Protocol not available", + .EPROTONOSUPPORT = "Protocol not supported", + .ESOCKTNOSUPPORT = "Socket type not supported", + .EOPNOTSUPP = "Operation not supported", + .EPFNOSUPPORT = "Protocol family not supported", + .EAFNOSUPPORT = "Address family not supported by protocol", + .EADDRINUSE = "Address already in use", + .EADDRNOTAVAIL = "Cannot assign requested address", + .ENETDOWN = "Network is down", + .ENETUNREACH = "Network is unreachable", + .ENETRESET = "Network dropped connection on reset", + .ECONNABORTED = "Software caused connection abort", + .ECONNRESET = "Connection reset by peer", + .ENOBUFS = "No buffer space available", + .EISCONN = "Transport endpoint is already connected", + .ENOTCONN = "Transport endpoint is not connected", + .ESHUTDOWN = "Cannot send after transport endpoint shutdown", + .ETOOMANYREFS = "Too many references: cannot splice", + .ETIMEDOUT = "Connection timed out", + .ECONNREFUSED = "Connection refused", + .EHOSTDOWN = "Host is down", + .EHOSTUNREACH = "No route to host", + .EALREADY = "Operation already in progress", + .EINPROGRESS = "Operation now in progress", + .ESTALE = "Stale file handle", + .EUCLEAN = "Structure needs cleaning", + .ENOTNAM = "Not a XENIX named type file", + .ENAVAIL = "No XENIX semaphores available", + .EISNAM = "Is a named type file", + .EREMOTEIO = "Remote I/O error", + .EDQUOT = "Disk quota exceeded", + .ENOMEDIUM = "No medium found", + .EMEDIUMTYPE = "Wrong medium type", + .ECANCELED = "Operation canceled", + .ENOKEY = "Required key not available", + .EKEYEXPIRED = "Key has expired", + .EKEYREVOKED = "Key has been revoked", + .EKEYREJECTED = "Key was rejected by service", + .EOWNERDEAD = "Owner died", + .ENOTRECOVERABLE = "State not recoverable", + .ERFKILL = "Operation not possible due to RF-kill", + .EHWPOISON = "Memory page has hardware error", } @@ -158,7 +159,7 @@ _get_platform_error :: proc(errno: linux.Errno) -> Error { _error_string :: proc(errno: i32) -> string { if errno >= 0 && errno <= i32(max(linux.Errno)) { - return _errno_strings[errno] + return _errno_strings[linux.Errno(errno)] } return "Unknown Error" } diff --git a/core/os/os2/process_linux.odin b/core/os/os2/process_linux.odin index 0484615ec..aec838d9d 100644 --- a/core/os/os2/process_linux.odin +++ b/core/os/os2/process_linux.odin @@ -233,7 +233,7 @@ _process_start :: proc(name: string, argv: []string, attr: ^Process_Attributes) } if errno = linux.execveat(dir_fd, executable, &cargs[OUT], env); errno != .NONE { - print_error(_get_platform_error(errno), string(executable)) + print_error(stderr, _get_platform_error(errno), string(executable)) panic("execve failed to replace process") } unreachable() diff --git a/core/sys/linux/bits.odin b/core/sys/linux/bits.odin index bf7ab4fae..bd686ed63 100644 --- a/core/sys/linux/bits.odin +++ b/core/sys/linux/bits.odin @@ -48,6 +48,7 @@ Errno :: enum i32 { ENOSYS = 38, ENOTEMPTY = 39, ELOOP = 40, + EUNKNOWN_41 = 41, ENOMSG = 42, EIDRM = 43, ECHRNG = 44, @@ -64,6 +65,7 @@ Errno :: enum i32 { ENOANO = 55, EBADRQC = 56, EBADSLT = 57, + EUNKNOWN_58 = 58, EBFONT = 59, ENOSTR = 60, ENODATA = 61, From dc954307d71b1602e50310d578070cb1547780e7 Mon Sep 17 00:00:00 2001 From: jason Date: Fri, 28 Jun 2024 07:55:33 -0400 Subject: [PATCH 061/129] fix assumption about std handles in os2/file.odin --- core/os/os2/file.odin | 8 +++----- core/os/os2/file_linux.odin | 4 ++++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/core/os/os2/file.odin b/core/os/os2/file.odin index 98cfc0815..236423163 100644 --- a/core/os/os2/file.odin +++ b/core/os/os2/file.odin @@ -45,11 +45,9 @@ O_TRUNC :: File_Flags{.Trunc} O_SPARSE :: File_Flags{.Sparse} O_CLOEXEC :: File_Flags{.Close_On_Exec} - -stdin: ^File = &_stdin -stdout: ^File = &_stdout -stderr: ^File = &_stderr - +stdin: ^File = nil // OS-Specific +stdout: ^File = nil // OS-Specific +stderr: ^File = nil // OS-Specific @(require_results) create :: proc(name: string) -> (^File, Error) { diff --git a/core/os/os2/file_linux.odin b/core/os/os2/file_linux.odin index 062c4aa0a..8e7db9751 100644 --- a/core/os/os2/file_linux.odin +++ b/core/os/os2/file_linux.odin @@ -49,6 +49,10 @@ _standard_stream_init :: proc() { _stdin.stream.data = &_stdin _stdout.stream.data = &_stdout _stderr.stream.data = &_stderr + + stdin = &_stdin + stdout = &_stdout + stderr = &_stderr } _file_allocator :: proc() -> runtime.Allocator { From 6a894195cbcf2caab2d84d75cc33f933e2390774 Mon Sep 17 00:00:00 2001 From: jason Date: Fri, 28 Jun 2024 09:45:22 -0400 Subject: [PATCH 062/129] revert os2/process --- core/os/os2/process.odin | 88 +++---- core/os/os2/process_linux.odin | 428 ------------------------------- core/os/os2/process_windows.odin | 67 ----- 3 files changed, 35 insertions(+), 548 deletions(-) delete mode 100644 core/os/os2/process_linux.odin delete mode 100644 core/os/os2/process_windows.odin diff --git a/core/os/os2/process.odin b/core/os/os2/process.odin index 099d1c19e..862434b7b 100644 --- a/core/os/os2/process.odin +++ b/core/os/os2/process.odin @@ -2,42 +2,36 @@ package os2 import "core:sync" import "core:time" -import "core:c" +import "base:runtime" -args: []string = _alloc_command_line_arguments() +args: []string exit :: proc "contextless" (code: int) -> ! { - _exit(code) + runtime.trap() } -@(require_results) get_uid :: proc() -> int { - return _get_uid() + return -1 } -@(require_results) get_euid :: proc() -> int { - return _get_euid() + return -1 } -@(require_results) get_gid :: proc() -> int { - return _get_gid() + return -1 } -@(require_results) get_egid :: proc() -> int { - return _get_euid() + return -1 } -@(require_results) get_pid :: proc() -> int { - return _get_pid() + return -1 } -@(require_results) get_ppid :: proc() -> int { - return _get_ppid() + return -1 } @@ -52,12 +46,16 @@ Process :: struct { Process_Attributes :: struct { dir: string, env: []string, - stdin: ^File, - stdout: ^File, - stderr: ^File, + files: []^File, sys: ^Process_Attributes_OS_Specific, } +Process_Attributes_OS_Specific :: struct{} + +Process_Error :: enum { + None, +} + Process_State :: struct { pid: int, exit_code: int, @@ -68,53 +66,37 @@ Process_State :: struct { sys: rawptr, } -Signal :: enum { - Abort, - Floating_Point_Exception, - Illegal_Instruction, - Interrupt, - Segmentation_Fault, - Termination, +Signal :: #type proc() + +Kill: Signal = nil +Interrupt: Signal = nil + + +find_process :: proc(pid: int) -> (^Process, Process_Error) { + return nil, .None } -Signal_Handler_Proc :: #type proc "c" (c.int) -Signal_Handler_Special :: enum { - Default, - Ignore, + +process_start :: proc(name: string, argv: []string, attr: ^Process_Attributes) -> (^Process, Process_Error) { + return nil, .None } -Signal_Handler :: union { - Signal_Handler_Proc, - Signal_Handler_Special, +process_release :: proc(p: ^Process) -> Process_Error { + return .None } -@(require_results) -process_find :: proc(pid: int) -> (Process, Error) { - return _process_find(pid) +process_kill :: proc(p: ^Process) -> Process_Error { + return .None } -@(require_results) -process_get_state :: proc(p: Process) -> (Process_State, Error) { - return _process_get_state(p) +process_signal :: proc(p: ^Process, sig: Signal) -> Process_Error { + return .None } -@(require_results) -process_start :: proc(name: string, argv: []string, attr: ^Process_Attributes = nil) -> (Process, Error) { - return _process_start(name, argv, attr) +process_wait :: proc(p: ^Process) -> (Process_State, Process_Error) { + return {}, .None } -process_release :: proc(p: ^Process) -> Error { - return _process_release(p) -} -process_kill :: proc(p: ^Process) -> Error { - return _process_kill(p) -} -process_signal :: proc(sig: Signal, h: Signal_Handler) -> Error { - return _process_signal(sig, h) -} -process_wait :: proc(p: ^Process, t: time.Duration = time.MAX_DURATION) -> (Process_State, Error) { - return _process_wait(p, t) -} diff --git a/core/os/os2/process_linux.odin b/core/os/os2/process_linux.odin deleted file mode 100644 index aec838d9d..000000000 --- a/core/os/os2/process_linux.odin +++ /dev/null @@ -1,428 +0,0 @@ -//+private -package os2 - -import "base:runtime" - -import "core:fmt" -import "core:mem" -import "core:time" -import "core:strings" -import "core:strconv" -import "core:sys/linux" -import "core:path/filepath" - -_alloc_command_line_arguments :: proc() -> []string { - res := make([]string, len(runtime.args__), heap_allocator()) - for arg, i in runtime.args__ { - res[i] = string(arg) - } - return res -} - -_exit :: proc "contextless" (code: int) -> ! { - linux.exit_group(i32(code)) -} - -_get_uid :: proc() -> int { - return int(linux.getuid()) -} - -_get_euid :: proc() -> int { - return int(linux.geteuid()) -} - -_get_gid :: proc() -> int { - return int(linux.getgid()) -} - -_get_egid :: proc() -> int { - return int(linux.getegid()) -} - -_get_pid :: proc() -> int { - return int(linux.getpid()) -} - -_get_ppid :: proc() -> int { - return int(linux.getppid()) -} - -Process_Attributes_OS_Specific :: struct {} - -_process_find :: proc(pid: int) -> (Process, Error) { - TEMP_ALLOCATOR_GUARD() - pid_path := fmt.ctprintf("/proc/%d", pid) - - p: Process - dir_fd: linux.Fd - errno: linux.Errno - - #partial switch dir_fd, errno = linux.open(pid_path, _OPENDIR_FLAGS); errno { - case .NONE: - linux.close(dir_fd) - p.pid = pid - return p, nil - case .ENOTDIR: - return p, .Invalid_Dir - case .ENOENT: - return p, .Not_Exist - } - return p, _get_platform_error(errno) -} - -_process_get_state :: proc(p: Process) -> (state: Process_State, err: Error) { - TEMP_ALLOCATOR_GUARD() - - stat_name := fmt.ctprintf("/proc/%d/stat", p.pid) - stat_buf: []u8 - stat_buf, err = _read_entire_pseudo_file(stat_name, temp_allocator()) - - if err != nil { - return - } - - idx := strings.last_index_byte(string(stat_buf), ')') - stats := string(stat_buf[idx + 2:]) - - // utime and stime are the 12 and 13th items, respectively - // skip the first 11 items here. - for i := 0; i < 11; i += 1 { - stats = stats[strings.index_byte(stats, ' ') + 1:] - } - - idx = strings.index_byte(stats, ' ') - utime_str := stats[:idx] - - stats = stats[idx + 1:] - stime_str := stats[:strings.index_byte(stats, ' ')] - - utime, _ := strconv.parse_int(utime_str, 10) - stime, _ := strconv.parse_int(stime_str, 10) - - // NOTE: Assuming HZ of 100, 1 jiffy == 10 ms - state.user_time = time.Duration(utime) * 10 * time.Millisecond - state.system_time = time.Duration(stime) * 10 * time.Millisecond - - return -} - -_process_start :: proc(name: string, argv: []string, attr: ^Process_Attributes) -> (child: Process, err: Error) { - TEMP_ALLOCATOR_GUARD() - - dir_fd := linux.AT_FDCWD - errno: linux.Errno - if attr != nil && attr.dir != "" { - dir_cstr := temp_cstring(attr.dir) or_return - if dir_fd, errno = linux.open(dir_cstr, _OPENDIR_FLAGS); errno != .NONE { - return child, _get_platform_error(errno) - } - } - - // search PATH if just a plain name is provided - executable: cstring - if !strings.contains_rune(name, '/') { - path_env := get_env("PATH", temp_allocator()) - path_dirs := filepath.split_list(path_env, temp_allocator()) - found: bool - for dir in path_dirs { - executable = fmt.ctprintf("%s/%s", dir, name) - fail: bool - if fail, errno = linux.faccessat(dir_fd, executable, linux.F_OK); errno == .NONE && !fail { - found = true - break - } - } - if !found { - // check in cwd to match windows behavior - executable = fmt.ctprintf("./%s", name) - fail: bool - if fail, errno = linux.faccessat(dir_fd, executable, linux.F_OK); errno != .NONE || fail { - return child, .Not_Exist - } - } - } else { - executable = temp_cstring(name) or_return - } - - not_exec: bool - if not_exec, errno = linux.faccessat(dir_fd, executable, linux.F_OK | linux.X_OK); errno != .NONE || not_exec { - return child, errno == .NONE ? .Permission_Denied : _get_platform_error(errno) - } - - // args and environment need to be a list of cstrings - // that are terminated by a nil pointer. - // The first argument is a copy of the executable name. - cargs := make([]cstring, len(argv) + 2, temp_allocator()) - cargs[0] = executable - for i := 0; i < len(argv); i += 1 { - cargs[i + 1] = temp_cstring(argv[i]) or_return - } - - // Use current process's environment if attributes not provided - env: [^]cstring - if attr == nil { - // take this process's current environment - env = raw_data(export_cstring_environment(temp_allocator())) - } else { - cenv := make([]cstring, len(attr.env) + 1, temp_allocator()) - for i := 0; i < len(attr.env); i += 1 { - cenv[i] = temp_cstring(attr.env[i]) or_return - } - env = &cenv[0] - } - - // TODO: This is the traditional textbook implementation with fork. - // A more efficient implementation with vfork: - // - // 1. retrieve signal handlers - // 2. block all signals - // 3. allocate some stack space - // 4. vfork (waits for child exit or execve); In child: - // a. set child signal handlers - // b. set up any necessary pipes - // c. execve - // 5. restore signal handlers - // - stdin_fds: [2]linux.Fd - stdout_fds: [2]linux.Fd - stderr_fds: [2]linux.Fd - if attr != nil && attr.stdin != nil { - if errno = linux.pipe2(&stdin_fds, nil); errno != .NONE { - return child, _get_platform_error(errno) - } - } - if attr != nil && attr.stdout != nil { - if errno = linux.pipe2(&stdout_fds, nil); errno != .NONE { - return child, _get_platform_error(errno) - } - } - if attr != nil && attr.stderr != nil { - if errno = linux.pipe2(&stderr_fds, nil); errno != .NONE { - return child, _get_platform_error(errno) - } - } - - pid: linux.Pid - if pid, errno = linux.fork(); errno != .NONE { - return child, _get_platform_error(errno) - } - - IN :: 1 - OUT :: 0 - - STDIN :: linux.Fd(0) - STDOUT :: linux.Fd(1) - STDERR :: linux.Fd(2) - - if pid == 0 { - // in child process now - if attr != nil && attr.stdin != nil { - if linux.close(stdin_fds[IN]) != .NONE { linux.exit(1) } - if _, errno = linux.dup2(stdin_fds[OUT], STDIN); errno != .NONE { linux.exit(1) } - if linux.close(stdin_fds[OUT]) != .NONE { linux.exit(1) } - } - if attr != nil && attr.stdout != nil { - if linux.close(stdout_fds[OUT]) != .NONE { linux.exit(1) } - if _, errno = linux.dup2(stdout_fds[IN], STDOUT); errno != .NONE { linux.exit(1) } - if linux.close(stdout_fds[IN]) != .NONE { linux.exit(1) } - } - if attr != nil && attr.stderr != nil { - if linux.close(stderr_fds[OUT]) != .NONE { linux.exit(1) } - if _, errno = linux.dup2(stderr_fds[IN], STDERR); errno != .NONE { linux.exit(1) } - if linux.close(stderr_fds[IN]) != .NONE { linux.exit(1) } - } - - if errno = linux.execveat(dir_fd, executable, &cargs[OUT], env); errno != .NONE { - print_error(stderr, _get_platform_error(errno), string(executable)) - panic("execve failed to replace process") - } - unreachable() - } - - // in parent process - if attr != nil && attr.stdin != nil { - linux.close(stdin_fds[OUT]) - _construct_file(attr.stdin, uintptr(stdin_fds[IN])) - } - if attr != nil && attr.stdout != nil { - linux.close(stdout_fds[IN]) - _construct_file(attr.stdout, uintptr(stdout_fds[OUT])) - } - if attr != nil && attr.stderr != nil { - linux.close(stderr_fds[IN]) - _construct_file(attr.stderr, uintptr(stderr_fds[OUT])) - } - - child.pid = int(pid) - return child, nil -} - -_process_release :: proc(p: ^Process) -> Error { - // We didn't allocate... - return nil -} - -_process_kill :: proc(p: ^Process) -> Error { - res := linux.kill(linux.Pid(p.pid), .SIGKILL) - return _get_platform_error(res) -} - -_process_signal :: proc(sig: Signal, h: Signal_Handler) -> Error { - signo: linux.Signal - switch sig { - case .Abort: signo = .SIGABRT - case .Floating_Point_Exception: signo = .SIGFPE - case .Illegal_Instruction: signo = .SIGILL - case .Interrupt: signo = .SIGINT - case .Segmentation_Fault: signo = .SIGSEGV - case .Termination: signo = .SIGTERM - } - - sigact: linux.Sig_Action(int) - old: ^linux.Sig_Action(int) = nil - - switch v in h { - case Signal_Handler_Special: - switch v { - case .Default: - sigact.special = .SIG_DFL - case .Ignore: - sigact.special = .SIG_IGN - } - case Signal_Handler_Proc: - sigact.handler = (linux.Sig_Handler_Fn)(v) - } - - return _get_platform_error(linux.rt_sigaction(signo, &sigact, old)) -} - -_process_wait :: proc(p: ^Process, t: time.Duration) -> (state: Process_State, err: Error) { - safe_state :: proc(p: Process, state: Process_State = {}) -> (Process_State, Error) { - // process_get_state can fail, so we don't want to return it directly. - if new_state, err := _process_get_state(p); err == nil { - return new_state, nil - } - return state, nil - } - - state.pid = p.pid - - options: linux.Wait_Options - big_if: if t == 0 { - options += {.WNOHANG} - } else if t != time.MAX_DURATION { - ts: linux.Time_Spec = { - time_sec = uint(t / time.Second), - time_nsec = uint(t % time.Second), - } - - @static has_pidfd_open: bool = true - - // pidfd_open is fairly new, so don't error out on ENOSYS - pid_fd: linux.Pid_FD - errno: linux.Errno - if has_pidfd_open { - pid_fd, errno = linux.pidfd_open(linux.Pid(p.pid), nil) - if errno != .NONE && errno != .ENOSYS { - return state, _get_platform_error(errno) - } - } - - if has_pidfd_open && errno != .ENOSYS { - defer linux.close(linux.Fd(pid_fd)) - pollfd: [1]linux.Poll_Fd = { - { - fd = linux.Fd(pid_fd), - events = {.IN}, - }, - } - for { - n, e := linux.ppoll(pollfd[:], &ts, nil) - if e == .EINTR { - continue - } - if e != .NONE { - return state, _get_platform_error(errno) - } - if n == 0 { - return safe_state(p^, state) - } - break - } - } else { - has_pidfd_open = false - mask: bit_set[0..=63] - mask += { int(linux.Signal.SIGCHLD) - 1 } - - org_sigset: linux.Sig_Set - sigset: linux.Sig_Set - mem.copy(&sigset, &mask, size_of(mask)) - errno = linux.rt_sigprocmask(.SIG_BLOCK, &sigset, &org_sigset) - if errno != .NONE { - return state, _get_platform_error(errno) - } - defer linux.rt_sigprocmask(.SIG_SETMASK, &org_sigset, nil) - - // In case there was a signal handler on SIGCHLD, avoid race - // condition by checking wait first. - options += {.WNOHANG} - waitid_options := options + {.WNOWAIT, .WEXITED} - info: linux.Sig_Info - errno = linux.waitid(.PID, linux.Id(p.pid), &info, waitid_options, nil) - if errno == .NONE && info.code != 0 { - break big_if - } - - loop: for { - sigset = {} - mem.copy(&sigset, &mask, size_of(mask)) - - _, errno = linux.rt_sigtimedwait(&sigset, &info, &ts) - #partial switch errno { - case .EAGAIN: // timeout - return safe_state(p^, state) - case .EINVAL: - return state, _get_platform_error(errno) - case .EINTR: - continue - case: - if int(info.pid) == p.pid { - break loop - } - } - } - } - } - - state, _ = safe_state(p^, state) - - status: u32 - errno: linux.Errno = .EINTR - for errno == .EINTR { - _, errno = linux.wait4(linux.Pid(p.pid), &status, options, nil) - if errno != .NONE { - return state, _get_platform_error(errno) - } - } - - // terminated by exit - if linux.WIFEXITED(status) { - p.is_done = true - state.exited = true - state.exit_code = int(linux.WEXITSTATUS(status)) - state.success = state.exit_code == 0 - return state, nil - } - - // terminated by signal - if linux.WIFSIGNALED(status) { - // NOTE: what's the correct behavior here?? - p.is_done = true - state.exited = false - state.exit_code = int(linux.WTERMSIG(status)) - state.success = false - return state, nil - } - - return safe_state(p^, state) -} diff --git a/core/os/os2/process_windows.odin b/core/os/os2/process_windows.odin deleted file mode 100644 index 4b5e4bc02..000000000 --- a/core/os/os2/process_windows.odin +++ /dev/null @@ -1,67 +0,0 @@ -//+private -package os2 - -import "core:runtime" -import "core:time" - -_alloc_command_line_arguments :: proc() -> []string { - return nil -} - -_exit :: proc "contextless" (_: int) -> ! { - runtime.trap() -} - -_get_uid :: proc() -> int { - return -1 -} - -_get_euid :: proc() -> int { - return -1 -} - -_get_gid :: proc() -> int { - return -1 -} - -_get_egid :: proc() -> int { - return -1 -} - -_get_pid :: proc() -> int { - return -1 -} - -_get_ppid :: proc() -> int { - return -1 -} - -Process_Attributes_OS_Specific :: struct{} - -_process_find :: proc(pid: int) -> (Process, Error) { - return Process{}, nil -} - -_process_get_state :: proc(p: Process) -> (Process_State, Error) { - return Process_State{}, nil -} - -_process_start :: proc(name: string, argv: []string, attr: ^Process_Attributes) -> (Process, Error) { - return Process{}, nil -} - -_process_release :: proc(p: ^Process) -> Error { - return nil -} - -_process_kill :: proc(p: ^Process) -> Error { - return nil -} - -_process_signal :: proc(sig: Signal, handler: Signal_Handler) -> Error { - return nil -} - -_process_wait :: proc(p: ^Process, t: time.Duration) -> (Process_State, Error) { - return Process_State{}, nil -} From 2af121752aac9def728618bd4e2cbc9d90693e7e Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Fri, 28 Jun 2024 11:34:35 -0400 Subject: [PATCH 063/129] Require `base:runtime` import in `core:math/linalg` --- core/math/linalg/general.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/math/linalg/general.odin b/core/math/linalg/general.odin index 37c0447cb..90fe7332c 100644 --- a/core/math/linalg/general.odin +++ b/core/math/linalg/general.odin @@ -3,7 +3,7 @@ package linalg import "core:math" import "base:builtin" import "base:intrinsics" -import "base:runtime" +@require import "base:runtime" // Generic From 574342af6fd8822a983cc99bafcfdc34e8e7793c Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Fri, 28 Jun 2024 15:58:22 -0400 Subject: [PATCH 064/129] Let `-vet` be used with `-define:ODIN_TEST_NAMES` --- core/testing/runner.odin | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/testing/runner.odin b/core/testing/runner.odin index 3510856c7..fffbb648c 100644 --- a/core/testing/runner.odin +++ b/core/testing/runner.odin @@ -198,8 +198,11 @@ runner :: proc(internal_tests: []Internal_Test) -> bool { } } + // `-vet` needs parameters to be shadowed by themselves first as an + // explicit declaration, to allow the next line to work. + internal_tests := internal_tests // Intentional shadow with user-specified tests. - internal_tests := select_internal_tests[:] + internal_tests = select_internal_tests[:] } total_failure_count := 0 From 929cc48703e30913cf17330bcf3f77dd0909ee57 Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Fri, 28 Jun 2024 19:03:43 -0400 Subject: [PATCH 065/129] Merge Darwin signals into other UNIX-likes They're all the same. --- core/c/libc/signal.odin | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/core/c/libc/signal.odin b/core/c/libc/signal.odin index 1489779fe..c447e3cc3 100644 --- a/core/c/libc/signal.odin +++ b/core/c/libc/signal.odin @@ -34,20 +34,7 @@ when ODIN_OS == .Windows { SIGTERM :: 15 } -when ODIN_OS == .Linux || ODIN_OS == .FreeBSD || ODIN_OS == .Haiku || ODIN_OS == .OpenBSD || ODIN_OS == .NetBSD { - SIG_ERR :: rawptr(~uintptr(0)) - SIG_DFL :: rawptr(uintptr(0)) - SIG_IGN :: rawptr(uintptr(1)) - - SIGABRT :: 6 - SIGFPE :: 8 - SIGILL :: 4 - SIGINT :: 2 - SIGSEGV :: 11 - SIGTERM :: 15 -} - -when ODIN_OS == .Darwin { +when ODIN_OS == .Linux || ODIN_OS == .FreeBSD || ODIN_OS == .Haiku || ODIN_OS == .OpenBSD || ODIN_OS == .NetBSD || ODIN_OS == .Darwin { SIG_ERR :: rawptr(~uintptr(0)) SIG_DFL :: rawptr(uintptr(0)) SIG_IGN :: rawptr(uintptr(1)) From 13539d3be1f3398f1a2152197dabd8a13456d540 Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Fri, 28 Jun 2024 19:05:20 -0400 Subject: [PATCH 066/129] Catch `SIGTRAP` in the test runner Fixes `panic` for Darwin. --- core/testing/signal_handler.odin | 1 + core/testing/signal_handler_libc.odin | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/core/testing/signal_handler.odin b/core/testing/signal_handler.odin index 891f6bbb6..0b06852ce 100644 --- a/core/testing/signal_handler.odin +++ b/core/testing/signal_handler.odin @@ -9,6 +9,7 @@ Stop_Reason :: enum { Illegal_Instruction, Arithmetic_Error, Segmentation_Fault, + Unhandled_Trap, } test_assertion_failure_proc :: proc(prefix, message: string, loc: runtime.Source_Code_Location) -> ! { diff --git a/core/testing/signal_handler_libc.odin b/core/testing/signal_handler_libc.odin index 0ab34776e..d89d84fae 100644 --- a/core/testing/signal_handler_libc.odin +++ b/core/testing/signal_handler_libc.odin @@ -19,6 +19,11 @@ import "core:os" @(private="file", thread_local) local_test_index: libc.sig_atomic_t +// Windows does not appear to have a SIGTRAP, so this is defined here, instead +// of in the libc package, just so there's no confusion about it being +// available there. +SIGTRAP :: 5 + @(private="file") stop_runner_callback :: proc "c" (sig: libc.int) { prev := intrinsics.atomic_add(&stop_runner_flag, 1) @@ -110,6 +115,10 @@ _setup_signal_handler :: proc() { // For tests: // Catch asserts and panics. libc.signal(libc.SIGILL, stop_test_callback) + when ODIN_OS == .Linux || ODIN_OS == .FreeBSD || ODIN_OS == .Haiku || ODIN_OS == .OpenBSD || ODIN_OS == .NetBSD || ODIN_OS == .Darwin { + // Catch panics on Darwin and unhandled calls to `debug_trap`. + libc.signal(SIGTRAP, stop_test_callback) + } // Catch arithmetic errors. libc.signal(libc.SIGFPE, stop_test_callback) // Catch segmentation faults (illegal memory access). @@ -141,6 +150,7 @@ _should_stop_test :: proc() -> (test_index: int, reason: Stop_Reason, ok: bool) case libc.SIGFPE: reason = .Arithmetic_Error case libc.SIGILL: reason = .Illegal_Instruction case libc.SIGSEGV: reason = .Segmentation_Fault + case SIGTRAP: reason = .Unhandled_Trap } ok = true } From 0ea0fac2f9c7bbcb1382b3326d83057847c944eb Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Fri, 28 Jun 2024 19:15:40 -0400 Subject: [PATCH 067/129] Call `pthread_cancel` on Darwin, with advisory comment --- core/thread/thread_unix.odin | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/core/thread/thread_unix.odin b/core/thread/thread_unix.odin index 5291917da..2218afdd3 100644 --- a/core/thread/thread_unix.odin +++ b/core/thread/thread_unix.odin @@ -23,10 +23,8 @@ _create :: proc(procedure: Thread_Proc, priority: Thread_Priority) -> ^Thread { __unix_thread_entry_proc :: proc "c" (t: rawptr) -> rawptr { t := (^Thread)(t) - when ODIN_OS != .Darwin { - // We need to give the thread a moment to start up before we enable cancellation. - can_set_thread_cancel_state := unix.pthread_setcancelstate(unix.PTHREAD_CANCEL_ENABLE, nil) == 0 - } + // We need to give the thread a moment to start up before we enable cancellation. + can_set_thread_cancel_state := unix.pthread_setcancelstate(unix.PTHREAD_CANCEL_ENABLE, nil) == 0 sync.lock(&t.mutex) @@ -42,12 +40,10 @@ _create :: proc(procedure: Thread_Proc, priority: Thread_Priority) -> ^Thread { return nil } - when ODIN_OS != .Darwin { - // Enable thread's cancelability. - if can_set_thread_cancel_state { - unix.pthread_setcanceltype (unix.PTHREAD_CANCEL_ASYNCHRONOUS, nil) - unix.pthread_setcancelstate(unix.PTHREAD_CANCEL_ENABLE, nil) - } + // Enable thread's cancelability. + if can_set_thread_cancel_state { + unix.pthread_setcanceltype (unix.PTHREAD_CANCEL_ASYNCHRONOUS, nil) + unix.pthread_setcancelstate(unix.PTHREAD_CANCEL_ENABLE, nil) } { @@ -169,10 +165,17 @@ _destroy :: proc(t: ^Thread) { } _terminate :: proc(t: ^Thread, exit_code: int) { - // `pthread_cancel` is unreliable on Darwin for unknown reasons. - when ODIN_OS != .Darwin { - unix.pthread_cancel(t.unix_thread) - } + // NOTE(Feoramund): For thread cancellation to succeed on BSDs and + // possibly Darwin systems, the thread must call one of the pthread + // cancelation points at some point after this. + // + // The most obvious one of these is `pthread_cancel`, but there is an + // entire list of functions that act as cancelation points available in the + // pthreads manual page. + // + // This is in contrast to behavior I have seen on Linux where the thread is + // just terminated. + unix.pthread_cancel(t.unix_thread) } _yield :: proc() { From 6496432b8056eeecd9ba396148f7c458a5cc02ac Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Fri, 28 Jun 2024 22:49:24 -0400 Subject: [PATCH 068/129] Add `-vet-identical-cast` --- src/build_settings.cpp | 5 ++++- src/check_expr.cpp | 23 +++++++++++++++++++++-- src/main.cpp | 7 +++++++ 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 4b348256b..f44179da0 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -742,10 +742,11 @@ enum VetFlags : u64 { VetFlag_UnusedVariables = 1u<<5, VetFlag_UnusedImports = 1u<<6, VetFlag_Deprecated = 1u<<7, + VetFlag_IdenticalCast = 1u<<8, VetFlag_Unused = VetFlag_UnusedVariables|VetFlag_UnusedImports, - VetFlag_All = VetFlag_Unused|VetFlag_Shadowing|VetFlag_UsingStmt|VetFlag_Deprecated, + VetFlag_All = VetFlag_Unused|VetFlag_Shadowing|VetFlag_UsingStmt|VetFlag_Deprecated|VetFlag_IdenticalCast, VetFlag_Using = VetFlag_UsingStmt|VetFlag_UsingParam, }; @@ -769,6 +770,8 @@ u64 get_vet_flag_from_name(String const &name) { return VetFlag_Semicolon; } else if (name == "deprecated") { return VetFlag_Deprecated; + } else if (name == "identical-cast") { + return VetFlag_IdenticalCast; } return VetFlag_NONE; } diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 891378b99..7d2f10c95 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -3310,7 +3310,7 @@ gb_internal bool check_cast_internal(CheckerContext *c, Operand *x, Type *type) } -gb_internal void check_cast(CheckerContext *c, Operand *x, Type *type) { +gb_internal void check_cast(CheckerContext *c, Operand *x, Type *type, bool forbid_identical = false) { if (!is_operand_value(*x)) { error(x->expr, "Only values can be casted"); x->mode = Addressing_Invalid; @@ -3382,6 +3382,25 @@ gb_internal void check_cast(CheckerContext *c, Operand *x, Type *type) { add_package_dependency(c, "runtime", "gnu_f2h_ieee", REQUIRE); } } + if (forbid_identical && check_vet_flags(c) & VetFlag_IdenticalCast) { + Type *src_exact = x->type; + Type *dst_exact = type; + + if (src_exact != nullptr && + dst_exact != nullptr && + // If we check polymorphic procedures, we risk erring on + // identical casts that cannot be foreseen or otherwise + // forbidden, so just skip them. + (c->curr_proc_sig == nullptr || !is_type_polymorphic(c->curr_proc_sig)) && + src_exact == dst_exact) + { + gbString oper_str = expr_to_string(x->expr); + gbString to_type = type_to_string(dst_exact); + error(x->expr, "Unneeded cast of `%s` to identical type `%s`", oper_str, to_type); + gb_string_free(oper_str); + gb_string_free(to_type); + } + } } x->type = type; @@ -10718,7 +10737,7 @@ gb_internal ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast check_transmute(c, node, o, type); break; case Token_cast: - check_cast(c, o, type); + check_cast(c, o, type, true); break; default: error(node, "Invalid AST: Invalid casting expression"); diff --git a/src/main.cpp b/src/main.cpp index b24796559..aa701b61b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -300,6 +300,7 @@ enum BuildFlagKind { BuildFlag_VetUsingParam, BuildFlag_VetStyle, BuildFlag_VetSemicolon, + BuildFlag_VetIdenticalCast, BuildFlag_CustomAttribute, BuildFlag_IgnoreUnknownAttributes, @@ -499,6 +500,7 @@ gb_internal bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_VetUsingParam, str_lit("vet-using-param"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_VetStyle, str_lit("vet-style"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_VetSemicolon, str_lit("vet-semicolon"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_VetIdenticalCast, str_lit("vet-identical-cast"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_CustomAttribute, str_lit("custom-attribute"), BuildFlagParam_String, Command__does_check, true); add_flag(&build_flags, BuildFlag_IgnoreUnknownAttributes, str_lit("ignore-unknown-attributes"), BuildFlagParam_None, Command__does_check); @@ -1152,6 +1154,7 @@ gb_internal bool parse_build_flags(Array args) { case BuildFlag_VetUsingParam: build_context.vet_flags |= VetFlag_UsingParam; break; case BuildFlag_VetStyle: build_context.vet_flags |= VetFlag_Style; break; case BuildFlag_VetSemicolon: build_context.vet_flags |= VetFlag_Semicolon; break; + case BuildFlag_VetIdenticalCast: build_context.vet_flags |= VetFlag_IdenticalCast; break; case BuildFlag_CustomAttribute: { @@ -2243,6 +2246,10 @@ gb_internal void print_show_help(String const arg0, String const &command) { print_usage_line(1, "-vet-semicolon"); print_usage_line(2, "Errs on unneeded semicolons."); print_usage_line(0, ""); + + print_usage_line(1, "-vet-identical-cast"); + print_usage_line(2, "Errs on casting a value to its own type."); + print_usage_line(0, ""); } if (check) { From b3caae6db4da4b604d5812d587b773674d72ccf3 Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Fri, 28 Jun 2024 22:49:48 -0400 Subject: [PATCH 069/129] Keep `-vet` happy --- core/encoding/uuid/generation.odin | 4 ++-- core/flags/internal_rtti.odin | 2 +- core/os/os_darwin.odin | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core/encoding/uuid/generation.odin b/core/encoding/uuid/generation.odin index cf29df378..7c9d4b80c 100644 --- a/core/encoding/uuid/generation.odin +++ b/core/encoding/uuid/generation.odin @@ -106,8 +106,8 @@ generate_v6 :: proc(clock_seq: Maybe(u16) = nil, node: Maybe([6]u8) = nil, times temporary: [2]u8 bytes_generated := rand.read(temporary[:]) assert(bytes_generated == 2, "RNG failed to generate 2 bytes for UUID v1.") - result[8] |= cast(u8)temporary[0] & 0x3F - result[9] = cast(u8)temporary[1] + result[8] |= temporary[0] & 0x3F + result[9] = temporary[1] } if realized_node, ok := node.?; ok { diff --git a/core/flags/internal_rtti.odin b/core/flags/internal_rtti.odin index c9b1f59fd..f19f52ba5 100644 --- a/core/flags/internal_rtti.odin +++ b/core/flags/internal_rtti.odin @@ -184,7 +184,7 @@ parse_and_set_pointer_by_base_type :: proc(ptr: rawptr, str: string, type_info: case 16: (cast(^u16) ptr)^ = cast(u16) value case 32: (cast(^u32) ptr)^ = cast(u32) value case 64: (cast(^u64) ptr)^ = cast(u64) value - case 128: (cast(^u128) ptr)^ = cast(u128) value + case 128: (cast(^u128) ptr)^ = value } } diff --git a/core/os/os_darwin.odin b/core/os/os_darwin.odin index 877a90bf1..b1fde77b3 100644 --- a/core/os/os_darwin.odin +++ b/core/os/os_darwin.odin @@ -555,7 +555,7 @@ open :: proc(path: string, flags: int = O_RDWR, mode: int = 0) -> (Handle, Errno err := fchmod(handle, cast(u16)mode) if err != 0 { _unix_close(handle) - return INVALID_HANDLE, cast(Errno)err + return INVALID_HANDLE, err } } From 679f9b4e413fb1cd9aad953cc7a7a287f5abf226 Mon Sep 17 00:00:00 2001 From: Karl Zylinski Date: Sat, 29 Jun 2024 08:23:39 +0200 Subject: [PATCH 070/129] Made default capacity of dynamic arrays more consistent. Before this if you do `arr: [dynamic]int` and then append to arr, then it will have capacity 8. But if you did `arr := make([dynamic]int, context.temp_allocator)` then arr would have capacity 16. Now both `arr: [dynamic]int` and `arr := make([dynamic]int, context.temp_allocator)` will resut in arr having zero 0. The only reason to use `make` without an explicit len or cap now is because you want to set it up for a non-default allocator. After the first call to `append` it will now in both cases have capacity 8. I also updated the documentation on the strings builder, both to reflect this, and also to fix it incorrectly saying that len would be 'max(16,len)', which wasn't true even before these changes. --- base/runtime/core_builtin.odin | 10 +++++----- base/runtime/core_builtin_soa.odin | 7 ++++--- core/strings/builder.odin | 12 ++++++------ 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/base/runtime/core_builtin.odin b/base/runtime/core_builtin.odin index 7758b29a5..4601bca9d 100644 --- a/base/runtime/core_builtin.odin +++ b/base/runtime/core_builtin.odin @@ -268,7 +268,7 @@ new_clone :: proc(data: $T, allocator := context.allocator, loc := #caller_locat return } -DEFAULT_RESERVE_CAPACITY :: 16 +DEFAULT_DYNAMIC_ARRAY_CAPACITY :: 8 @(require_results) make_aligned :: proc($T: typeid/[]$E, #any_int len: int, alignment: int, allocator := context.allocator, loc := #caller_location) -> (T, Allocator_Error) #optional_allocator_error { @@ -295,7 +295,7 @@ make_slice :: proc($T: typeid/[]$E, #any_int len: int, allocator := context.allo // Note: Prefer using the procedure group `make`. @(builtin, require_results) make_dynamic_array :: proc($T: typeid/[dynamic]$E, allocator := context.allocator, loc := #caller_location) -> (T, Allocator_Error) #optional_allocator_error { - return make_dynamic_array_len_cap(T, 0, DEFAULT_RESERVE_CAPACITY, allocator, loc) + return make_dynamic_array_len_cap(T, 0, 0, allocator, loc) } // `make_dynamic_array_len` allocates and initializes a dynamic array. Like `new`, the first argument is a type, not a value. // Unlike `new`, `make`'s return value is the same as the type of its argument, not a pointer to it. @@ -423,8 +423,8 @@ _append_elem :: #force_inline proc(array: ^$T/[dynamic]$E, arg: E, should_zero: return 1, nil } else { if cap(array) < len(array)+1 { - // Same behavior as _append_elems but there's only one arg, so we always just add 8. - cap := 2 * cap(array) + 8 + // Same behavior as _append_elems but there's only one arg, so we always just add DEFAULT_DYNAMIC_ARRAY_CAPACITY. + cap := 2 * cap(array) + DEFAULT_DYNAMIC_ARRAY_CAPACITY // do not 'or_return' here as it could be a partial success if should_zero { @@ -473,7 +473,7 @@ _append_elems :: #force_inline proc(array: ^$T/[dynamic]$E, should_zero: bool, l return arg_len, nil } else { if cap(array) < len(array)+arg_len { - cap := 2 * cap(array) + max(8, arg_len) + cap := 2 * cap(array) + max(DEFAULT_DYNAMIC_ARRAY_CAPACITY, arg_len) // do not 'or_return' here as it could be a partial success if should_zero { diff --git a/base/runtime/core_builtin_soa.odin b/base/runtime/core_builtin_soa.odin index 547df0a2b..816df13e2 100644 --- a/base/runtime/core_builtin_soa.odin +++ b/base/runtime/core_builtin_soa.odin @@ -147,7 +147,7 @@ make_soa_slice :: proc($T: typeid/#soa[]$E, length: int, allocator := context.al @(builtin, require_results) make_soa_dynamic_array :: proc($T: typeid/#soa[dynamic]$E, allocator := context.allocator, loc := #caller_location) -> (array: T, err: Allocator_Error) #optional_allocator_error { context.allocator = allocator - reserve_soa(&array, DEFAULT_RESERVE_CAPACITY, loc) or_return + reserve_soa(&array, 0, loc) or_return return array, nil } @@ -280,7 +280,8 @@ append_soa_elem :: proc(array: ^$T/#soa[dynamic]$E, arg: E, loc := #caller_locat } if cap(array) <= len(array) + 1 { - cap := 2 * cap(array) + 8 + // Same behavior as append_soa_elems but there's only one arg, so we always just add DEFAULT_DYNAMIC_ARRAY_CAPACITY. + cap := 2 * cap(array) + DEFAULT_DYNAMIC_ARRAY_CAPACITY err = reserve_soa(array, cap, loc) // do not 'or_return' here as it could be a partial success } @@ -337,7 +338,7 @@ append_soa_elems :: proc(array: ^$T/#soa[dynamic]$E, args: ..E, loc := #caller_l } if cap(array) <= len(array)+arg_len { - cap := 2 * cap(array) + max(8, arg_len) + cap := 2 * cap(array) + max(DEFAULT_DYNAMIC_ARRAY_CAPACITY, arg_len) err = reserve_soa(array, cap, loc) // do not 'or_return' here as it could be a partial success } arg_len = min(cap(array)-len(array), arg_len) diff --git a/core/strings/builder.odin b/core/strings/builder.odin index 33054a8a9..6bb0b2018 100644 --- a/core/strings/builder.odin +++ b/core/strings/builder.odin @@ -24,7 +24,7 @@ Builder :: struct { buf: [dynamic]byte, } /* -Produces a Builder with a default length of 0 and cap of 16 +Produces an empty Builder *Allocates Using Provided Allocator* @@ -39,7 +39,7 @@ builder_make_none :: proc(allocator := context.allocator, loc := #caller_locatio return Builder{buf=make([dynamic]byte, allocator, loc) or_return }, nil } /* -Produces a Builder with a specified length and cap of max(16,len) byte buffer +Produces a Builder with specified length and capacity `len`. *Allocates Using Provided Allocator* @@ -55,7 +55,7 @@ builder_make_len :: proc(len: int, allocator := context.allocator, loc := #calle return Builder{buf=make([dynamic]byte, len, allocator, loc) or_return }, nil } /* -Produces a Builder with a specified length and cap +Produces a Builder with specified length `len` and capacity `cap`. *Allocates Using Provided Allocator* @@ -103,7 +103,7 @@ builder_make :: proc{ builder_make_len_cap, } /* -Initializes a Builder with a length of 0 and cap of 16 +Initializes an empty Builder It replaces the existing `buf` *Allocates Using Provided Allocator* @@ -121,7 +121,7 @@ builder_init_none :: proc(b: ^Builder, allocator := context.allocator, loc := #c return b, nil } /* -Initializes a Builder with a specified length and cap, which is max(len,16) +Initializes a Builder with specified length and capacity `len`. It replaces the existing `buf` *Allocates Using Provided Allocator* @@ -140,7 +140,7 @@ builder_init_len :: proc(b: ^Builder, len: int, allocator := context.allocator, return b, nil } /* -Initializes a Builder with a specified length and cap +Initializes a Builder with specified length `len` and capacity `cap`. It replaces the existing `buf` Inputs: From 906afa41544c692f65467f1dba546a6ca4e71f1d Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 29 Jun 2024 10:13:15 +0100 Subject: [PATCH 071/129] Allow for `when x in y {` (minor oversight in syntax) --- core/odin/parser/parser.odin | 5 +++++ src/parser.cpp | 3 +++ 2 files changed, 8 insertions(+) diff --git a/core/odin/parser/parser.odin b/core/odin/parser/parser.odin index 03fb4d66d..715b96d84 100644 --- a/core/odin/parser/parser.odin +++ b/core/odin/parser/parser.odin @@ -689,7 +689,12 @@ parse_when_stmt :: proc(p: ^Parser) -> ^ast.When_Stmt { prev_level := p.expr_level p.expr_level = -1 + prev_allow_in_expr := p.allow_in_expr + p.allow_in_expr = true + cond = parse_expr(p, false) + + p.allow_in_expr = prev_allow_in_expr p.expr_level = prev_level if cond == nil { diff --git a/src/parser.cpp b/src/parser.cpp index 0e971f792..b1a179573 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -4573,9 +4573,12 @@ gb_internal Ast *parse_when_stmt(AstFile *f) { isize prev_level = f->expr_level; f->expr_level = -1; + bool prev_allow_in_expr = f->allow_in_expr; + f->allow_in_expr = true; cond = parse_expr(f, false); + f->allow_in_expr = prev_allow_in_expr; f->expr_level = prev_level; if (cond == nullptr) { From f974002839d3332a4a6f636c93d08e4b039c36bc Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 29 Jun 2024 10:47:09 +0100 Subject: [PATCH 072/129] Use `f32` operations rather than `f16` in `complex32` and `quaternion64` to improve accuracy and performance --- base/runtime/internal.odin | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/base/runtime/internal.odin b/base/runtime/internal.odin index 378eea256..369df05ad 100644 --- a/base/runtime/internal.odin +++ b/base/runtime/internal.odin @@ -642,21 +642,24 @@ abs_quaternion256 :: #force_inline proc "contextless" (x: quaternion256) -> f64 quo_complex32 :: proc "contextless" (n, m: complex32) -> complex32 { - e, f: f16 + nr, ni := f32(real(n)), f32(imag(n)) + mr, mi := f32(real(m)), f32(imag(m)) - if abs(real(m)) >= abs(imag(m)) { - ratio := imag(m) / real(m) - denom := real(m) + ratio*imag(m) - e = (real(n) + imag(n)*ratio) / denom - f = (imag(n) - real(n)*ratio) / denom + e, f: f32 + + if abs(mr) >= abs(mi) { + ratio := mi / mr + denom := mr + ratio*mi + e = (nr + ni*ratio) / denom + f = (ni - nr*ratio) / denom } else { - ratio := real(m) / imag(m) - denom := imag(m) + ratio*real(m) - e = (real(n)*ratio + imag(n)) / denom - f = (imag(n)*ratio - real(n)) / denom + ratio := mr / mi + denom := mi + ratio*mr + e = (nr*ratio + ni) / denom + f = (ni*ratio - nr) / denom } - return complex(e, f) + return complex(f16(e), f16(f)) } @@ -697,15 +700,15 @@ quo_complex128 :: proc "contextless" (n, m: complex128) -> complex128 { } mul_quaternion64 :: proc "contextless" (q, r: quaternion64) -> quaternion64 { - q0, q1, q2, q3 := real(q), imag(q), jmag(q), kmag(q) - r0, r1, r2, r3 := real(r), imag(r), jmag(r), kmag(r) + q0, q1, q2, q3 := f32(real(q)), f32(imag(q)), f32(jmag(q)), f32(kmag(q)) + r0, r1, r2, r3 := f32(real(r)), f32(imag(r)), f32(jmag(r)), f32(kmag(r)) t0 := r0*q0 - r1*q1 - r2*q2 - r3*q3 t1 := r0*q1 + r1*q0 - r2*q3 + r3*q2 t2 := r0*q2 + r1*q3 + r2*q0 - r3*q1 t3 := r0*q3 - r1*q2 + r2*q1 + r3*q0 - return quaternion(w=t0, x=t1, y=t2, z=t3) + return quaternion(w=f16(t0), x=f16(t1), y=f16(t2), z=f16(t3)) } mul_quaternion128 :: proc "contextless" (q, r: quaternion128) -> quaternion128 { @@ -733,8 +736,8 @@ mul_quaternion256 :: proc "contextless" (q, r: quaternion256) -> quaternion256 { } quo_quaternion64 :: proc "contextless" (q, r: quaternion64) -> quaternion64 { - q0, q1, q2, q3 := real(q), imag(q), jmag(q), kmag(q) - r0, r1, r2, r3 := real(r), imag(r), jmag(r), kmag(r) + q0, q1, q2, q3 := f32(real(q)), f32(imag(q)), f32(jmag(q)), f32(kmag(q)) + r0, r1, r2, r3 := f32(real(r)), f32(imag(r)), f32(jmag(r)), f32(kmag(r)) invmag2 := 1.0 / (r0*r0 + r1*r1 + r2*r2 + r3*r3) @@ -743,7 +746,7 @@ quo_quaternion64 :: proc "contextless" (q, r: quaternion64) -> quaternion64 { t2 := (r0*q2 - r1*q3 - r2*q0 + r3*q1) * invmag2 t3 := (r0*q3 + r1*q2 + r2*q1 - r3*q0) * invmag2 - return quaternion(w=t0, x=t1, y=t2, z=t3) + return quaternion(w=f16(t0), x=f16(t1), y=f16(t2), z=f16(t3)) } quo_quaternion128 :: proc "contextless" (q, r: quaternion128) -> quaternion128 { From 55e9b8d994061d81a23e051999751a36dc456489 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 29 Jun 2024 10:48:41 +0100 Subject: [PATCH 073/129] Use explicit calling conventions --- base/runtime/internal.odin | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/base/runtime/internal.odin b/base/runtime/internal.odin index 369df05ad..2cdac306a 100644 --- a/base/runtime/internal.odin +++ b/base/runtime/internal.odin @@ -29,7 +29,7 @@ is_power_of_two_int :: #force_inline proc "contextless" (x: int) -> bool { return (x & (x-1)) == 0 } -align_forward_int :: #force_inline proc(ptr, align: int) -> int { +align_forward_int :: #force_inline proc "odin" (ptr, align: int) -> int { assert(is_power_of_two_int(align)) p := ptr @@ -47,7 +47,7 @@ is_power_of_two_uint :: #force_inline proc "contextless" (x: uint) -> bool { return (x & (x-1)) == 0 } -align_forward_uint :: #force_inline proc(ptr, align: uint) -> uint { +align_forward_uint :: #force_inline proc "odin" (ptr, align: uint) -> uint { assert(is_power_of_two_uint(align)) p := ptr @@ -65,7 +65,7 @@ is_power_of_two_uintptr :: #force_inline proc "contextless" (x: uintptr) -> bool return (x & (x-1)) == 0 } -align_forward_uintptr :: #force_inline proc(ptr, align: uintptr) -> uintptr { +align_forward_uintptr :: #force_inline proc "odin" (ptr, align: uintptr) -> uintptr { assert(is_power_of_two_uintptr(align)) p := ptr @@ -1034,7 +1034,7 @@ divti3 :: proc "c" (a, b: i128) -> i128 { @(link_name="__fixdfti", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE) -fixdfti :: proc(a: u64) -> i128 { +fixdfti :: proc "c" (a: u64) -> i128 { significandBits :: 52 typeWidth :: (size_of(u64)*8) exponentBits :: (typeWidth - significandBits - 1) From 52aa7085e4e072fde519856b520555d08ef0835c Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 29 Jun 2024 11:09:54 +0100 Subject: [PATCH 074/129] Use `f32` as the immediate type for addition and subtraction for `complex32`/`quaternion64` --- src/llvm_backend_expr.cpp | 64 +++++++++++++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 13 deletions(-) diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index 46b8fa3cb..bcacc0537 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -1127,12 +1127,21 @@ gb_internal lbValue lb_emit_arith(lbProcedure *p, TokenKind op, lbValue lhs, lbV switch (op) { case Token_Add: - real = lb_emit_arith(p, Token_Add, a, c, ft); - imag = lb_emit_arith(p, Token_Add, b, d, ft); - break; case Token_Sub: - real = lb_emit_arith(p, Token_Sub, a, c, ft); - imag = lb_emit_arith(p, Token_Sub, b, d, ft); + if (type_size_of(ft) == 2) { + a = lb_emit_conv(p, a, t_f32); + b = lb_emit_conv(p, b, t_f32); + c = lb_emit_conv(p, c, t_f32); + d = lb_emit_conv(p, d, t_f32); + real = lb_emit_arith(p, op, a, c, t_f32); + imag = lb_emit_arith(p, op, b, d, t_f32); + + real = lb_emit_conv(p, real, ft); + imag = lb_emit_conv(p, imag, ft); + } else { + real = lb_emit_arith(p, op, a, c, ft); + imag = lb_emit_arith(p, op, b, d, ft); + } break; case Token_Mul: { lbValue x = lb_emit_arith(p, Token_Mul, a, c, ft); @@ -1156,6 +1165,11 @@ gb_internal lbValue lb_emit_arith(lbProcedure *p, TokenKind op, lbValue lhs, lbV Type *ft = base_complex_elem_type(type); if (op == Token_Add || op == Token_Sub) { + Type *immediate_type = ft; + if (type_size_of(ft) == 2) { + immediate_type = t_f32; + } + lbAddr res = lb_add_local_generated(p, type, false); // NOTE: initialized in full later lbValue x0 = lb_emit_struct_ev(p, lhs, 0); lbValue x1 = lb_emit_struct_ev(p, lhs, 1); @@ -1167,15 +1181,39 @@ gb_internal lbValue lb_emit_arith(lbProcedure *p, TokenKind op, lbValue lhs, lbV lbValue y2 = lb_emit_struct_ev(p, rhs, 2); lbValue y3 = lb_emit_struct_ev(p, rhs, 3); - lbValue z0 = lb_emit_arith(p, op, x0, y0, ft); - lbValue z1 = lb_emit_arith(p, op, x1, y1, ft); - lbValue z2 = lb_emit_arith(p, op, x2, y2, ft); - lbValue z3 = lb_emit_arith(p, op, x3, y3, ft); + if (immediate_type != ft) { + x0 = lb_emit_conv(p, x0, immediate_type); + x1 = lb_emit_conv(p, x1, immediate_type); + x2 = lb_emit_conv(p, x2, immediate_type); + x3 = lb_emit_conv(p, x3, immediate_type); - lb_emit_store(p, lb_emit_struct_ep(p, res.addr, 0), z0); - lb_emit_store(p, lb_emit_struct_ep(p, res.addr, 1), z1); - lb_emit_store(p, lb_emit_struct_ep(p, res.addr, 2), z2); - lb_emit_store(p, lb_emit_struct_ep(p, res.addr, 3), z3); + y0 = lb_emit_conv(p, y0, immediate_type); + y1 = lb_emit_conv(p, y1, immediate_type); + y2 = lb_emit_conv(p, y2, immediate_type); + y3 = lb_emit_conv(p, y3, immediate_type); + } + + lbValue z0 = lb_emit_arith(p, op, x0, y0, immediate_type); + lbValue z1 = lb_emit_arith(p, op, x1, y1, immediate_type); + lbValue z2 = lb_emit_arith(p, op, x2, y2, immediate_type); + lbValue z3 = lb_emit_arith(p, op, x3, y3, immediate_type); + + lbValue d0 = lb_emit_struct_ep(p, res.addr, 0); + lbValue d1 = lb_emit_struct_ep(p, res.addr, 1); + lbValue d2 = lb_emit_struct_ep(p, res.addr, 2); + lbValue d3 = lb_emit_struct_ep(p, res.addr, 3); + + if (immediate_type != ft) { + d0 = lb_emit_conv(p, d0, ft); + d1 = lb_emit_conv(p, d1, ft); + d2 = lb_emit_conv(p, d2, ft); + d3 = lb_emit_conv(p, d3, ft); + } + + lb_emit_store(p, d0, z0); + lb_emit_store(p, d1, z1); + lb_emit_store(p, d2, z2); + lb_emit_store(p, d3, z3); return lb_addr_load(p, res); } else if (op == Token_Mul) { From 704530497b166dfa6fcee8f2c95a9e492a78a024 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 29 Jun 2024 11:44:45 +0100 Subject: [PATCH 075/129] Rename `-vet-identical-cast` to `-vet-cast`; with minor code clean up --- src/build_settings.cpp | 8 ++++---- src/check_expr.cpp | 16 ++++++++-------- src/main.cpp | 10 +++++----- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/build_settings.cpp b/src/build_settings.cpp index f44179da0..f9c426487 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -742,11 +742,11 @@ enum VetFlags : u64 { VetFlag_UnusedVariables = 1u<<5, VetFlag_UnusedImports = 1u<<6, VetFlag_Deprecated = 1u<<7, - VetFlag_IdenticalCast = 1u<<8, + VetFlag_Cast = 1u<<8, VetFlag_Unused = VetFlag_UnusedVariables|VetFlag_UnusedImports, - VetFlag_All = VetFlag_Unused|VetFlag_Shadowing|VetFlag_UsingStmt|VetFlag_Deprecated|VetFlag_IdenticalCast, + VetFlag_All = VetFlag_Unused|VetFlag_Shadowing|VetFlag_UsingStmt|VetFlag_Deprecated|VetFlag_Cast, VetFlag_Using = VetFlag_UsingStmt|VetFlag_UsingParam, }; @@ -770,8 +770,8 @@ u64 get_vet_flag_from_name(String const &name) { return VetFlag_Semicolon; } else if (name == "deprecated") { return VetFlag_Deprecated; - } else if (name == "identical-cast") { - return VetFlag_IdenticalCast; + } else if (name == "cast") { + return VetFlag_Cast; } return VetFlag_NONE; } diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 7d2f10c95..2fa491417 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -3382,18 +3382,18 @@ gb_internal void check_cast(CheckerContext *c, Operand *x, Type *type, bool forb add_package_dependency(c, "runtime", "gnu_f2h_ieee", REQUIRE); } } - if (forbid_identical && check_vet_flags(c) & VetFlag_IdenticalCast) { + // If we check polymorphic procedures, we risk erring on + // identical casts that cannot be foreseen or otherwise + // forbidden, so just skip them. + if (forbid_identical && check_vet_flags(c) & VetFlag_Cast && + (c->curr_proc_sig == nullptr || !is_type_polymorphic(c->curr_proc_sig))) { Type *src_exact = x->type; Type *dst_exact = type; if (src_exact != nullptr && - dst_exact != nullptr && - // If we check polymorphic procedures, we risk erring on - // identical casts that cannot be foreseen or otherwise - // forbidden, so just skip them. - (c->curr_proc_sig == nullptr || !is_type_polymorphic(c->curr_proc_sig)) && - src_exact == dst_exact) - { + dst_exact != nullptr && + are_types_identical(src_exact, dst_exact) + ) { gbString oper_str = expr_to_string(x->expr); gbString to_type = type_to_string(dst_exact); error(x->expr, "Unneeded cast of `%s` to identical type `%s`", oper_str, to_type); diff --git a/src/main.cpp b/src/main.cpp index aa701b61b..62aeccaf5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -300,7 +300,7 @@ enum BuildFlagKind { BuildFlag_VetUsingParam, BuildFlag_VetStyle, BuildFlag_VetSemicolon, - BuildFlag_VetIdenticalCast, + BuildFlag_VetCast, BuildFlag_CustomAttribute, BuildFlag_IgnoreUnknownAttributes, @@ -500,7 +500,7 @@ gb_internal bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_VetUsingParam, str_lit("vet-using-param"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_VetStyle, str_lit("vet-style"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_VetSemicolon, str_lit("vet-semicolon"), BuildFlagParam_None, Command__does_check); - add_flag(&build_flags, BuildFlag_VetIdenticalCast, str_lit("vet-identical-cast"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_VetCast, str_lit("vet-cast"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_CustomAttribute, str_lit("custom-attribute"), BuildFlagParam_String, Command__does_check, true); add_flag(&build_flags, BuildFlag_IgnoreUnknownAttributes, str_lit("ignore-unknown-attributes"), BuildFlagParam_None, Command__does_check); @@ -1154,7 +1154,7 @@ gb_internal bool parse_build_flags(Array args) { case BuildFlag_VetUsingParam: build_context.vet_flags |= VetFlag_UsingParam; break; case BuildFlag_VetStyle: build_context.vet_flags |= VetFlag_Style; break; case BuildFlag_VetSemicolon: build_context.vet_flags |= VetFlag_Semicolon; break; - case BuildFlag_VetIdenticalCast: build_context.vet_flags |= VetFlag_IdenticalCast; break; + case BuildFlag_VetCast: build_context.vet_flags |= VetFlag_Cast; break; case BuildFlag_CustomAttribute: { @@ -2247,8 +2247,8 @@ gb_internal void print_show_help(String const arg0, String const &command) { print_usage_line(2, "Errs on unneeded semicolons."); print_usage_line(0, ""); - print_usage_line(1, "-vet-identical-cast"); - print_usage_line(2, "Errs on casting a value to its own type."); + print_usage_line(1, "-vet-cast"); + print_usage_line(2, "Errs on casting a value to its own type or using `transmute` rather than `cast`."); print_usage_line(0, ""); } From 4b71c47fd5e70f0f96e139e17637cf5de1beb2fc Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 29 Jun 2024 12:02:31 +0100 Subject: [PATCH 076/129] Check for unneeded `transmute` with `-vet-cast` --- base/runtime/random_generator.odin | 2 +- core/compress/shoco/shoco.odin | 9 ++--- core/crypto/_edwards25519/edwards25519.odin | 4 +- .../_edwards25519/edwards25519_scalar.odin | 4 +- core/crypto/_fiat/field_curve25519/field.odin | 4 +- core/crypto/_fiat/field_poly1305/field.odin | 4 +- core/crypto/kmac/kmac.odin | 10 ++--- core/crypto/legacy/keccak/keccak.odin | 10 ++--- core/crypto/ristretto255/ristretto255.odin | 6 +-- .../ristretto255/ristretto255_scalar.odin | 2 +- core/crypto/sha3/sha3.odin | 10 ++--- core/crypto/shake/shake.odin | 16 ++++---- core/crypto/tuplehash/tuplehash.odin | 14 +++---- core/image/qoi/qoi.odin | 6 +-- core/os/os_darwin.odin | 4 +- core/os/os_freebsd.odin | 4 +- core/os/os_linux.odin | 3 +- core/sys/info/cpu_intel.odin | 2 +- core/sys/linux/wrappers.odin | 4 +- src/check_expr.cpp | 38 +++++++++++++------ 20 files changed, 82 insertions(+), 74 deletions(-) diff --git a/base/runtime/random_generator.odin b/base/runtime/random_generator.odin index 95ba6ece9..94201efac 100644 --- a/base/runtime/random_generator.odin +++ b/base/runtime/random_generator.odin @@ -89,7 +89,7 @@ default_random_generator_proc :: proc(data: rawptr, mode: Random_Generator_Mode, switch len(p) { case size_of(u64): // Fast path for a 64-bit destination. - intrinsics.unaligned_store(transmute(^u64)raw_data(p), read_u64(r)) + intrinsics.unaligned_store((^u64)(raw_data(p)), read_u64(r)) case: // All other cases. pos := i8(0) diff --git a/core/compress/shoco/shoco.odin b/core/compress/shoco/shoco.odin index 3c1f412ba..c0259ff75 100644 --- a/core/compress/shoco/shoco.odin +++ b/core/compress/shoco/shoco.odin @@ -274,12 +274,9 @@ compress_string_to_buffer :: proc(input: string, output: []u8, model := DEFAULT_ out_ptr := raw_data(output[out:]) switch pack.bytes_packed { - case 4: - intrinsics.unaligned_store(transmute(^u32)out_ptr, code) - case 2: - intrinsics.unaligned_store(transmute(^u16)out_ptr, u16(code)) - case 1: - intrinsics.unaligned_store(transmute(^u8)out_ptr, u8(code)) + case 4: intrinsics.unaligned_store((^u32)(out_ptr), code) + case 2: intrinsics.unaligned_store((^u16)(out_ptr), u16(code)) + case 1: intrinsics.unaligned_store( (^u8)(out_ptr), u8(code)) case: return out, .Unknown_Compression_Method } diff --git a/core/crypto/_edwards25519/edwards25519.odin b/core/crypto/_edwards25519/edwards25519.odin index 952bb9ef8..6495f7a3a 100644 --- a/core/crypto/_edwards25519/edwards25519.odin +++ b/core/crypto/_edwards25519/edwards25519.odin @@ -110,7 +110,7 @@ ge_set_bytes :: proc "contextless" (ge: ^Group_Element, b: []byte) -> bool { if len(b) != 32 { intrinsics.trap() } - b_ := transmute(^[32]byte)(raw_data(b)) + b_ := (^[32]byte)(raw_data(b)) // Do the work in a scratch element, so that ge is unchanged on // failure. @@ -169,7 +169,7 @@ ge_bytes :: proc "contextless" (ge: ^Group_Element, dst: []byte) { if len(dst) != 32 { intrinsics.trap() } - dst_ := transmute(^[32]byte)(raw_data(dst)) + dst_ := (^[32]byte)(raw_data(dst)) // Convert the element to affine (x, y) representation. x, y, z_inv: field.Tight_Field_Element = ---, ---, --- diff --git a/core/crypto/_edwards25519/edwards25519_scalar.odin b/core/crypto/_edwards25519/edwards25519_scalar.odin index 2644fe5f7..e21fa3755 100644 --- a/core/crypto/_edwards25519/edwards25519_scalar.odin +++ b/core/crypto/_edwards25519/edwards25519_scalar.odin @@ -28,7 +28,7 @@ sc_set_bytes :: proc "contextless" (sc: ^Scalar, b: []byte) -> bool { if len(b) != 32 { intrinsics.trap() } - b_ := transmute(^[32]byte)(raw_data(b)) + b_ := (^[32]byte)(raw_data(b)) return field.fe_from_bytes(sc, b_) } @@ -36,7 +36,7 @@ sc_set_bytes_rfc8032 :: proc "contextless" (sc: ^Scalar, b: []byte) { if len(b) != 32 { intrinsics.trap() } - b_ := transmute(^[32]byte)(raw_data(b)) + b_ := (^[32]byte)(raw_data(b)) field.fe_from_bytes_rfc8032(sc, b_) } diff --git a/core/crypto/_fiat/field_curve25519/field.odin b/core/crypto/_fiat/field_curve25519/field.odin index 8a8202ac4..04fc87659 100644 --- a/core/crypto/_fiat/field_curve25519/field.odin +++ b/core/crypto/_fiat/field_curve25519/field.odin @@ -6,13 +6,13 @@ import "core:mem" fe_relax_cast :: #force_inline proc "contextless" ( arg1: ^Tight_Field_Element, ) -> ^Loose_Field_Element { - return transmute(^Loose_Field_Element)(arg1) + return (^Loose_Field_Element)(arg1) } fe_tighten_cast :: #force_inline proc "contextless" ( arg1: ^Loose_Field_Element, ) -> ^Tight_Field_Element { - return transmute(^Tight_Field_Element)(arg1) + return (^Tight_Field_Element)(arg1) } fe_clear :: proc "contextless" ( diff --git a/core/crypto/_fiat/field_poly1305/field.odin b/core/crypto/_fiat/field_poly1305/field.odin index c50a56b0c..b12046858 100644 --- a/core/crypto/_fiat/field_poly1305/field.odin +++ b/core/crypto/_fiat/field_poly1305/field.odin @@ -7,13 +7,13 @@ import "core:mem" fe_relax_cast :: #force_inline proc "contextless" ( arg1: ^Tight_Field_Element, ) -> ^Loose_Field_Element { - return transmute(^Loose_Field_Element)(arg1) + return (^Loose_Field_Element)(arg1) } fe_tighten_cast :: #force_inline proc "contextless" ( arg1: ^Loose_Field_Element, ) -> ^Tight_Field_Element { - return transmute(^Tight_Field_Element)(arg1) + return (^Tight_Field_Element)(arg1) } fe_from_bytes :: #force_inline proc "contextless" ( diff --git a/core/crypto/kmac/kmac.odin b/core/crypto/kmac/kmac.odin index e5be6f91b..711f459b3 100644 --- a/core/crypto/kmac/kmac.odin +++ b/core/crypto/kmac/kmac.odin @@ -61,7 +61,7 @@ init_256 :: proc(ctx: ^Context, key, domain_sep: []byte) { update :: proc(ctx: ^Context, data: []byte) { assert(ctx.is_initialized) - shake.write(transmute(^shake.Context)(ctx), data) + shake.write((^shake.Context)(ctx), data) } // final finalizes the Context, writes the tag to dst, and calls reset @@ -75,7 +75,7 @@ final :: proc(ctx: ^Context, dst: []byte) { panic("crypto/kmac: invalid KMAC tag_size, too short") } - _sha3.final_cshake(transmute(^_sha3.Context)(ctx), dst) + _sha3.final_cshake((^_sha3.Context)(ctx), dst) } // clone clones the Context other into ctx. @@ -84,7 +84,7 @@ clone :: proc(ctx, other: ^Context) { return } - shake.clone(transmute(^shake.Context)(ctx), transmute(^shake.Context)(other)) + shake.clone((^shake.Context)(ctx), (^shake.Context)(other)) } // reset sanitizes the Context. The Context must be re-initialized to @@ -94,7 +94,7 @@ reset :: proc(ctx: ^Context) { return } - shake.reset(transmute(^shake.Context)(ctx)) + shake.reset((^shake.Context)(ctx)) } @(private) @@ -107,7 +107,7 @@ _init_kmac :: proc(ctx: ^Context, key, s: []byte, sec_strength: int) { panic("crypto/kmac: invalid KMAC key, too short") } - ctx_ := transmute(^_sha3.Context)(ctx) + ctx_ := (^_sha3.Context)(ctx) _sha3.init_cshake(ctx_, N_KMAC, s, sec_strength) _sha3.bytepad(ctx_, [][]byte{key}, _sha3.rate_cshake(sec_strength)) } diff --git a/core/crypto/legacy/keccak/keccak.odin b/core/crypto/legacy/keccak/keccak.odin index 7813a1ab4..6ca66b7ca 100644 --- a/core/crypto/legacy/keccak/keccak.odin +++ b/core/crypto/legacy/keccak/keccak.odin @@ -66,12 +66,12 @@ init_512 :: proc(ctx: ^Context) { @(private) _init :: proc(ctx: ^Context) { ctx.dsbyte = _sha3.DS_KECCAK - _sha3.init(transmute(^_sha3.Context)(ctx)) + _sha3.init((^_sha3.Context)(ctx)) } // update adds more data to the Context. update :: proc(ctx: ^Context, data: []byte) { - _sha3.update(transmute(^_sha3.Context)(ctx), data) + _sha3.update((^_sha3.Context)(ctx), data) } // final finalizes the Context, writes the digest to hash, and calls @@ -80,16 +80,16 @@ update :: proc(ctx: ^Context, data: []byte) { // Iff finalize_clone is set, final will work on a copy of the Context, // which is useful for for calculating rolling digests. final :: proc(ctx: ^Context, hash: []byte, finalize_clone: bool = false) { - _sha3.final(transmute(^_sha3.Context)(ctx), hash, finalize_clone) + _sha3.final((^_sha3.Context)(ctx), hash, finalize_clone) } // clone clones the Context other into ctx. clone :: proc(ctx, other: ^Context) { - _sha3.clone(transmute(^_sha3.Context)(ctx), transmute(^_sha3.Context)(other)) + _sha3.clone((^_sha3.Context)(ctx), (^_sha3.Context)(other)) } // reset sanitizes the Context. The Context must be re-initialized to // be used again. reset :: proc(ctx: ^Context) { - _sha3.reset(transmute(^_sha3.Context)(ctx)) + _sha3.reset((^_sha3.Context)(ctx)) } diff --git a/core/crypto/ristretto255/ristretto255.odin b/core/crypto/ristretto255/ristretto255.odin index d1f2b6ee5..3a2307da0 100644 --- a/core/crypto/ristretto255/ristretto255.odin +++ b/core/crypto/ristretto255/ristretto255.odin @@ -112,7 +112,7 @@ ge_set_bytes :: proc "contextless" (ge: ^Group_Element, b: []byte) -> bool { return false } - b_ := transmute(^[32]byte)(raw_data(b)) + b_ := (^[32]byte)(raw_data(b)) s: field.Tight_Field_Element = --- defer field.fe_clear(&s) @@ -297,7 +297,7 @@ ge_bytes :: proc(ge: ^Group_Element, dst: []byte) { // 2. Return the 32-byte little-endian encoding of s. More // specifically, this is the encoding of the canonical // representation of s as an integer between 0 and p-1, inclusive. - dst_ := transmute(^[32]byte)(raw_data(dst)) + dst_ := (^[32]byte)(raw_data(dst)) field.fe_to_bytes(dst_, &tmp) field.fe_clear_vec([]^field.Tight_Field_Element{&u1, &u2, &tmp, &z_inv, &ix0, &iy0, &x, &y}) @@ -417,7 +417,7 @@ ge_is_identity :: proc(ge: ^Group_Element) -> int { @(private) ge_map :: proc "contextless" (ge: ^Group_Element, b: []byte) { - b_ := transmute(^[32]byte)(raw_data(b)) + b_ := (^[32]byte)(raw_data(b)) // The MAP function is defined on 32-byte strings as: // diff --git a/core/crypto/ristretto255/ristretto255_scalar.odin b/core/crypto/ristretto255/ristretto255_scalar.odin index f581e5963..1ecb490e0 100644 --- a/core/crypto/ristretto255/ristretto255_scalar.odin +++ b/core/crypto/ristretto255/ristretto255_scalar.odin @@ -46,7 +46,7 @@ sc_set_bytes_wide :: proc(sc: ^Scalar, b: []byte) { panic("crypto/ristretto255: invalid wide input size") } - b_ := transmute(^[WIDE_SCALAR_SIZE]byte)(raw_data(b)) + b_ := (^[WIDE_SCALAR_SIZE]byte)(raw_data(b)) grp.sc_set_bytes_wide(sc, b_) } diff --git a/core/crypto/sha3/sha3.odin b/core/crypto/sha3/sha3.odin index bc3e6e846..78057f1ca 100644 --- a/core/crypto/sha3/sha3.odin +++ b/core/crypto/sha3/sha3.odin @@ -68,12 +68,12 @@ init_512 :: proc(ctx: ^Context) { @(private) _init :: proc(ctx: ^Context) { ctx.dsbyte = _sha3.DS_SHA3 - _sha3.init(transmute(^_sha3.Context)(ctx)) + _sha3.init((^_sha3.Context)(ctx)) } // update adds more data to the Context. update :: proc(ctx: ^Context, data: []byte) { - _sha3.update(transmute(^_sha3.Context)(ctx), data) + _sha3.update((^_sha3.Context)(ctx), data) } // final finalizes the Context, writes the digest to hash, and calls @@ -82,16 +82,16 @@ update :: proc(ctx: ^Context, data: []byte) { // Iff finalize_clone is set, final will work on a copy of the Context, // which is useful for for calculating rolling digests. final :: proc(ctx: ^Context, hash: []byte, finalize_clone: bool = false) { - _sha3.final(transmute(^_sha3.Context)(ctx), hash, finalize_clone) + _sha3.final((^_sha3.Context)(ctx), hash, finalize_clone) } // clone clones the Context other into ctx. clone :: proc(ctx, other: ^Context) { - _sha3.clone(transmute(^_sha3.Context)(ctx), transmute(^_sha3.Context)(other)) + _sha3.clone((^_sha3.Context)(ctx), (^_sha3.Context)(other)) } // reset sanitizes the Context. The Context must be re-initialized to // be used again. reset :: proc(ctx: ^Context) { - _sha3.reset(transmute(^_sha3.Context)(ctx)) + _sha3.reset((^_sha3.Context)(ctx)) } diff --git a/core/crypto/shake/shake.odin b/core/crypto/shake/shake.odin index 7da427485..4160f4cf9 100644 --- a/core/crypto/shake/shake.odin +++ b/core/crypto/shake/shake.odin @@ -24,35 +24,35 @@ Context :: distinct _sha3.Context // init_128 initializes a Context for SHAKE128. init_128 :: proc(ctx: ^Context) { - _sha3.init_cshake(transmute(^_sha3.Context)(ctx), nil, nil, 128) + _sha3.init_cshake((^_sha3.Context)(ctx), nil, nil, 128) } // init_256 initializes a Context for SHAKE256. init_256 :: proc(ctx: ^Context) { - _sha3.init_cshake(transmute(^_sha3.Context)(ctx), nil, nil, 256) + _sha3.init_cshake((^_sha3.Context)(ctx), nil, nil, 256) } // init_cshake_128 initializes a Context for cSHAKE128. init_cshake_128 :: proc(ctx: ^Context, domain_sep: []byte) { - _sha3.init_cshake(transmute(^_sha3.Context)(ctx), nil, domain_sep, 128) + _sha3.init_cshake((^_sha3.Context)(ctx), nil, domain_sep, 128) } // init_cshake_256 initializes a Context for cSHAKE256. init_cshake_256 :: proc(ctx: ^Context, domain_sep: []byte) { - _sha3.init_cshake(transmute(^_sha3.Context)(ctx), nil, domain_sep, 256) + _sha3.init_cshake((^_sha3.Context)(ctx), nil, domain_sep, 256) } // write writes more data into the SHAKE instance. This MUST not be called // after any reads have been done, and attempts to do so will panic. write :: proc(ctx: ^Context, data: []byte) { - _sha3.update(transmute(^_sha3.Context)(ctx), data) + _sha3.update((^_sha3.Context)(ctx), data) } // read reads output from the SHAKE instance. There is no practical upper // limit to the amount of data that can be read from SHAKE. After read has // been called one or more times, further calls to write will panic. read :: proc(ctx: ^Context, dst: []byte) { - ctx_ := transmute(^_sha3.Context)(ctx) + ctx_ := (^_sha3.Context)(ctx) if !ctx.is_finalized { _sha3.shake_xof(ctx_) } @@ -62,11 +62,11 @@ read :: proc(ctx: ^Context, dst: []byte) { // clone clones the Context other into ctx. clone :: proc(ctx, other: ^Context) { - _sha3.clone(transmute(^_sha3.Context)(ctx), transmute(^_sha3.Context)(other)) + _sha3.clone((^_sha3.Context)(ctx), (^_sha3.Context)(other)) } // reset sanitizes the Context. The Context must be re-initialized to // be used again. reset :: proc(ctx: ^Context) { - _sha3.reset(transmute(^_sha3.Context)(ctx)) + _sha3.reset((^_sha3.Context)(ctx)) } diff --git a/core/crypto/tuplehash/tuplehash.odin b/core/crypto/tuplehash/tuplehash.odin index baba1ce59..ed0a3aa87 100644 --- a/core/crypto/tuplehash/tuplehash.odin +++ b/core/crypto/tuplehash/tuplehash.odin @@ -13,19 +13,19 @@ Context :: distinct _sha3.Context // init_128 initializes a Context for TupleHash128 or TupleHashXOF128. init_128 :: proc(ctx: ^Context, domain_sep: []byte) { - _sha3.init_cshake(transmute(^_sha3.Context)(ctx), N_TUPLEHASH, domain_sep, 128) + _sha3.init_cshake((^_sha3.Context)(ctx), N_TUPLEHASH, domain_sep, 128) } // init_256 initializes a Context for TupleHash256 or TupleHashXOF256. init_256 :: proc(ctx: ^Context, domain_sep: []byte) { - _sha3.init_cshake(transmute(^_sha3.Context)(ctx), N_TUPLEHASH, domain_sep, 256) + _sha3.init_cshake((^_sha3.Context)(ctx), N_TUPLEHASH, domain_sep, 256) } // write_element writes a tuple element into the TupleHash or TupleHashXOF // instance. This MUST not be called after any reads have been done, and // any attempts to do so will panic. write_element :: proc(ctx: ^Context, data: []byte) { - _, _ = _sha3.encode_string(transmute(^_sha3.Context)(ctx), data) + _, _ = _sha3.encode_string((^_sha3.Context)(ctx), data) } // final finalizes the Context, writes the digest to hash, and calls @@ -34,7 +34,7 @@ write_element :: proc(ctx: ^Context, data: []byte) { // Iff finalize_clone is set, final will work on a copy of the Context, // which is useful for for calculating rolling digests. final :: proc(ctx: ^Context, hash: []byte, finalize_clone: bool = false) { - _sha3.final_cshake(transmute(^_sha3.Context)(ctx), hash, finalize_clone) + _sha3.final_cshake((^_sha3.Context)(ctx), hash, finalize_clone) } // read reads output from the TupleHashXOF instance. There is no practical @@ -42,7 +42,7 @@ final :: proc(ctx: ^Context, hash: []byte, finalize_clone: bool = false) { // After read has been called one or more times, further calls to // write_element will panic. read :: proc(ctx: ^Context, dst: []byte) { - ctx_ := transmute(^_sha3.Context)(ctx) + ctx_ := (^_sha3.Context)(ctx) if !ctx.is_finalized { _sha3.encode_byte_len(ctx_, 0, false) // right_encode _sha3.shake_xof(ctx_) @@ -53,13 +53,13 @@ read :: proc(ctx: ^Context, dst: []byte) { // clone clones the Context other into ctx. clone :: proc(ctx, other: ^Context) { - _sha3.clone(transmute(^_sha3.Context)(ctx), transmute(^_sha3.Context)(other)) + _sha3.clone((^_sha3.Context)(ctx), (^_sha3.Context)(other)) } // reset sanitizes the Context. The Context must be re-initialized to // be used again. reset :: proc(ctx: ^Context) { - _sha3.reset(transmute(^_sha3.Context)(ctx)) + _sha3.reset((^_sha3.Context)(ctx)) } @(private) diff --git a/core/image/qoi/qoi.odin b/core/image/qoi/qoi.odin index 061943f68..15ed449da 100644 --- a/core/image/qoi/qoi.odin +++ b/core/image/qoi/qoi.odin @@ -139,15 +139,13 @@ save_to_buffer :: proc(output: ^bytes.Buffer, img: ^Image, options := Options{} } else { // Write RGB literal output.buf[written] = u8(QOI_Opcode_Tag.RGB) - pix_bytes := transmute([4]u8)pix - copy(output.buf[written + 1:], pix_bytes[:3]) + copy(output.buf[written + 1:], pix[:3]) written += 4 } } else { // Write RGBA literal output.buf[written] = u8(QOI_Opcode_Tag.RGBA) - pix_bytes := transmute([4]u8)pix - copy(output.buf[written + 1:], pix_bytes[:]) + copy(output.buf[written + 1:], pix[:]) written += 5 } } diff --git a/core/os/os_darwin.odin b/core/os/os_darwin.odin index b1fde77b3..75a1f6a29 100644 --- a/core/os/os_darwin.odin +++ b/core/os/os_darwin.odin @@ -883,8 +883,8 @@ absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Errno) { } defer _unix_free(path_ptr) - path_cstr := transmute(cstring)path_ptr - path = strings.clone( string(path_cstr) ) + path_cstr := cast(cstring)path_ptr + path = strings.clone(string(path_cstr)) return path, ERROR_NONE } diff --git a/core/os/os_freebsd.odin b/core/os/os_freebsd.odin index 8fe179478..97165b262 100644 --- a/core/os/os_freebsd.odin +++ b/core/os/os_freebsd.odin @@ -648,8 +648,8 @@ absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Errno) { } defer _unix_free(path_ptr) - path_cstr := transmute(cstring)path_ptr - path = strings.clone( string(path_cstr) ) + + path = strings.clone(string(cstring(path_ptr))) return path, ERROR_NONE } diff --git a/core/os/os_linux.odin b/core/os/os_linux.odin index 545349bc5..ebc1b3600 100644 --- a/core/os/os_linux.odin +++ b/core/os/os_linux.odin @@ -890,8 +890,7 @@ absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Errno) { } defer _unix_free(path_ptr) - path_cstr := transmute(cstring)path_ptr - path = strings.clone( string(path_cstr) ) + path = strings.clone(string(cstring(path_ptr))) return path, ERROR_NONE } diff --git a/core/sys/info/cpu_intel.odin b/core/sys/info/cpu_intel.odin index 63af853d0..73d4c15e7 100644 --- a/core/sys/info/cpu_intel.odin +++ b/core/sys/info/cpu_intel.odin @@ -117,7 +117,7 @@ init_cpu_name :: proc "c" () { return } - _buf := transmute(^[0x12]u32)&_cpu_name_buf + _buf := (^[0x12]u32)(&_cpu_name_buf) _buf[ 0], _buf[ 1], _buf[ 2], _buf[ 3] = cpuid(0x8000_0002, 0) _buf[ 4], _buf[ 5], _buf[ 6], _buf[ 7] = cpuid(0x8000_0003, 0) _buf[ 8], _buf[ 9], _buf[10], _buf[11] = cpuid(0x8000_0004, 0) diff --git a/core/sys/linux/wrappers.odin b/core/sys/linux/wrappers.odin index 13073315d..95c818b9d 100644 --- a/core/sys/linux/wrappers.odin +++ b/core/sys/linux/wrappers.odin @@ -85,13 +85,13 @@ dirent_iterate_buf :: proc "contextless" (buf: []u8, offs: ^int) -> (d: ^Dirent, /// Obtain the name of dirent as a string /// The lifetime of the string is bound to the lifetime of the provided dirent structure dirent_name :: proc "contextless" (dirent: ^Dirent) -> string #no_bounds_check { - str := transmute([^]u8) &dirent.name + str := ([^]u8)(&dirent.name) // Note(flysand): The string size calculated above applies only to the ideal case // we subtract 1 byte from the string size, because a null terminator is guaranteed // to be present. But! That said, the dirents are aligned to 8 bytes and the padding // between the null terminator and the start of the next struct may be not initialized // which means we also have to scan these garbage bytes. - str_size := (cast(int) dirent.reclen) - 1 - cast(int) offset_of(Dirent, name) + str_size := int(dirent.reclen) - 1 - cast(int)offset_of(Dirent, name) // This skips *only* over the garbage, since if we're not garbage we're at nul terminator, // which skips this loop for str[str_size] != 0 { diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 2fa491417..45500e79a 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -3396,7 +3396,7 @@ gb_internal void check_cast(CheckerContext *c, Operand *x, Type *type, bool forb ) { gbString oper_str = expr_to_string(x->expr); gbString to_type = type_to_string(dst_exact); - error(x->expr, "Unneeded cast of `%s` to identical type `%s`", oper_str, to_type); + error(x->expr, "Unneeded cast of '%s' to identical type '%s'", oper_str, to_type); gb_string_free(oper_str); gb_string_free(to_type); } @@ -3406,22 +3406,13 @@ gb_internal void check_cast(CheckerContext *c, Operand *x, Type *type, bool forb x->type = type; } -gb_internal bool check_transmute(CheckerContext *c, Ast *node, Operand *o, Type *t) { +gb_internal bool check_transmute(CheckerContext *c, Ast *node, Operand *o, Type *t, bool forbid_identical = false) { if (!is_operand_value(*o)) { error(o->expr, "'transmute' can only be applied to values"); o->mode = Addressing_Invalid; return false; } - // if (o->mode == Addressing_Constant) { - // gbString expr_str = expr_to_string(o->expr); - // error(o->expr, "Cannot transmute a constant expression: '%s'", expr_str); - // gb_string_free(expr_str); - // o->mode = Addressing_Invalid; - // o->expr = node; - // return false; - // } - Type *src_t = o->type; Type *dst_t = t; Type *src_bt = base_type(src_t); @@ -3504,6 +3495,29 @@ gb_internal bool check_transmute(CheckerContext *c, Ast *node, Operand *o, Type return true; } } + } else { + // If we check polymorphic procedures, we risk erring on + // identical casts that cannot be foreseen or otherwise + // forbidden, so just skip them. + if (forbid_identical && check_vet_flags(c) & VetFlag_Cast && + (c->curr_proc_sig == nullptr || !is_type_polymorphic(c->curr_proc_sig))) { + bool is_runtime = false; + if (c->pkg && (c->pkg->kind == Package_Runtime || c->pkg->kind == Package_Builtin)) { + is_runtime = true; + } + if (are_types_identical(src_t, dst_t) && !is_runtime) { + gbString oper_str = expr_to_string(o->expr); + gbString to_type = type_to_string(dst_t); + error(o->expr, "Unneeded transmute of '%s' to identical type '%s'", oper_str, to_type); + gb_string_free(oper_str); + gb_string_free(to_type); + } else if (is_type_internally_pointer_like(src_t) && + is_type_internally_pointer_like(dst_t)) { + gbString to_type = type_to_string(dst_t); + error(o->expr, "Use of 'transmute' where 'cast' would be preferred since the types are pointer-like", to_type); + gb_string_free(to_type); + } + } } o->mode = Addressing_Value; @@ -10734,7 +10748,7 @@ gb_internal ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast if (o->mode != Addressing_Invalid) { switch (tc->token.kind) { case Token_transmute: - check_transmute(c, node, o, type); + check_transmute(c, node, o, type, true); break; case Token_cast: check_cast(c, o, type, true); From d6b8544f508183871b636f8742ba813863d036f3 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 29 Jun 2024 12:04:31 +0100 Subject: [PATCH 077/129] Add internal flag for testing stuff --- src/build_settings.cpp | 1 + src/check_builtin.cpp | 12 +++++++----- src/main.cpp | 5 +++++ 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/build_settings.cpp b/src/build_settings.cpp index f9c426487..47a29a461 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -878,6 +878,7 @@ struct BuildContext { bool ignore_lazy; bool ignore_llvm_build; + bool ignore_panic; bool ignore_microsoft_magic; bool linker_map_file; diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index 47abd42cf..c1422e80e 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -1726,11 +1726,13 @@ gb_internal bool check_builtin_procedure_directive(CheckerContext *c, Operand *o gb_string_free(str); return false; } - error(call, "Compile time panic: %.*s", LIT(operand->value.value_string)); - if (c->proc_name != "") { - gbString str = type_to_string(c->curr_proc_sig); - error_line("\tCalled within '%.*s' :: %s\n", LIT(c->proc_name), str); - gb_string_free(str); + if (!build_context.ignore_panic) { + error(call, "Compile time panic: %.*s", LIT(operand->value.value_string)); + if (c->proc_name != "") { + gbString str = type_to_string(c->curr_proc_sig); + error_line("\tCalled within '%.*s' :: %s\n", LIT(c->proc_name), str); + gb_string_free(str); + } } operand->type = t_invalid; operand->mode = Addressing_NoValue; diff --git a/src/main.cpp b/src/main.cpp index 62aeccaf5..c1ec77ec4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -345,6 +345,7 @@ enum BuildFlagKind { // internal use only BuildFlag_InternalIgnoreLazy, BuildFlag_InternalIgnoreLLVMBuild, + BuildFlag_InternalIgnorePanic, BuildFlag_Tilde, @@ -543,6 +544,7 @@ gb_internal bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_InternalIgnoreLazy, str_lit("internal-ignore-lazy"), BuildFlagParam_None, Command_all); add_flag(&build_flags, BuildFlag_InternalIgnoreLLVMBuild, str_lit("internal-ignore-llvm-build"),BuildFlagParam_None, Command_all); + add_flag(&build_flags, BuildFlag_InternalIgnorePanic, str_lit("internal-ignore-panic"), BuildFlagParam_None, Command_all); #if ALLOW_TILDE add_flag(&build_flags, BuildFlag_Tilde, str_lit("tilde"), BuildFlagParam_None, Command__does_build); @@ -1352,6 +1354,9 @@ gb_internal bool parse_build_flags(Array args) { case BuildFlag_InternalIgnoreLLVMBuild: build_context.ignore_llvm_build = true; break; + case BuildFlag_InternalIgnorePanic: + build_context.ignore_panic = true; + break; case BuildFlag_Tilde: build_context.tilde_backend = true; break; From c18c0a3364bb6008e59ac2a0428610caba2cc583 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 29 Jun 2024 12:07:21 +0100 Subject: [PATCH 078/129] Adhere to `-vet-cast` --- core/os/os_openbsd.odin | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/os/os_openbsd.odin b/core/os/os_openbsd.odin index 182d97979..a3b74a524 100644 --- a/core/os/os_openbsd.odin +++ b/core/os/os_openbsd.odin @@ -610,8 +610,7 @@ absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Errno) { } defer _unix_free(path_ptr) - path_cstr := transmute(cstring)path_ptr - path = strings.clone( string(path_cstr) ) + path = strings.clone(string(cstring(path_ptr))) return path, ERROR_NONE } From e46d772b6d01d06d7186438cadb61a0a30f17371 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 29 Jun 2024 12:13:41 +0100 Subject: [PATCH 079/129] Add check for integer casts --- src/check_expr.cpp | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 45500e79a..6b11a9d08 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -3505,17 +3505,24 @@ gb_internal bool check_transmute(CheckerContext *c, Ast *node, Operand *o, Type if (c->pkg && (c->pkg->kind == Package_Runtime || c->pkg->kind == Package_Builtin)) { is_runtime = true; } - if (are_types_identical(src_t, dst_t) && !is_runtime) { - gbString oper_str = expr_to_string(o->expr); - gbString to_type = type_to_string(dst_t); - error(o->expr, "Unneeded transmute of '%s' to identical type '%s'", oper_str, to_type); - gb_string_free(oper_str); - gb_string_free(to_type); + if (are_types_identical(src_t, dst_t)) { + if (!is_runtime) { + gbString oper_str = expr_to_string(o->expr); + gbString to_type = type_to_string(dst_t); + error(o->expr, "Unneeded transmute of '%s' to identical type '%s'", oper_str, to_type); + gb_string_free(oper_str); + gb_string_free(to_type); + } } else if (is_type_internally_pointer_like(src_t) && is_type_internally_pointer_like(dst_t)) { - gbString to_type = type_to_string(dst_t); - error(o->expr, "Use of 'transmute' where 'cast' would be preferred since the types are pointer-like", to_type); + error(o->expr, "Use of 'transmute' where 'cast' would be preferred since the types are pointer-like"); + } else if (is_type_integer(src_t) && is_type_integer(dst_t) && + types_have_same_internal_endian(src_t, dst_t)) { + gbString oper_type = type_to_string(src_t); + gbString to_type = type_to_string(dst_t); + error(o->expr, "Use of 'transmute' where 'cast' would be preferred since both are integers of the same endianness, from '%s' to '%s'", oper_type, to_type); gb_string_free(to_type); + gb_string_free(oper_type); } } } From b9861a0cf6b6bc9e5b02beca8481f1f884821a15 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 29 Jun 2024 12:14:21 +0100 Subject: [PATCH 080/129] cast to transmute --- core/os/os_netbsd.odin | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/os/os_netbsd.odin b/core/os/os_netbsd.odin index c0f237bf5..c8f10d1da 100644 --- a/core/os/os_netbsd.odin +++ b/core/os/os_netbsd.odin @@ -658,8 +658,7 @@ absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Errno) { } defer _unix_free(path_ptr) - path_cstr := transmute(cstring)path_ptr - path = strings.clone( string(path_cstr) ) + path = strings.clone(string(cstring(path_ptr))) return path, ERROR_NONE } From 706adb12323016999692ff6acb62d39d6dc91299 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 29 Jun 2024 12:16:43 +0100 Subject: [PATCH 081/129] Update for `transmute` `-vet-cast` --- base/runtime/internal.odin | 12 ++++++------ base/runtime/udivmod128.odin | 6 +++--- core/compress/shoco/shoco.odin | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/base/runtime/internal.odin b/base/runtime/internal.odin index 2cdac306a..203ee2873 100644 --- a/base/runtime/internal.odin +++ b/base/runtime/internal.odin @@ -1015,21 +1015,21 @@ modti3 :: proc "c" (a, b: i128) -> i128 { bn := (b ~ s_b) - s_b r: u128 = --- - _ = udivmod128(transmute(u128)an, transmute(u128)bn, &r) - return (transmute(i128)r ~ s_a) - s_a + _ = udivmod128(u128(an), u128(bn), &r) + return (i128(r) ~ s_a) - s_a } @(link_name="__divmodti4", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE) divmodti4 :: proc "c" (a, b: i128, rem: ^i128) -> i128 { - u := udivmod128(transmute(u128)a, transmute(u128)b, cast(^u128)rem) - return transmute(i128)u + u := udivmod128(u128(a), u128(b), (^u128)(rem)) + return i128(u) } @(link_name="__divti3", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE) divti3 :: proc "c" (a, b: i128) -> i128 { - u := udivmodti4(transmute(u128)a, transmute(u128)b, nil) - return transmute(i128)u + u := udivmodti4(u128(a), u128(b), nil) + return i128(u) } diff --git a/base/runtime/udivmod128.odin b/base/runtime/udivmod128.odin index eceb815bf..8cc70df55 100644 --- a/base/runtime/udivmod128.odin +++ b/base/runtime/udivmod128.odin @@ -58,7 +58,7 @@ udivmod128 :: proc "c" (a, b: u128, rem: ^u128) -> u128 { return u128(n[high] >> _ctz(d[high])) } - sr = transmute(u32)(i32(_clz(d[high])) - i32(_clz(n[high]))) + sr = u32(i32(_clz(d[high])) - i32(_clz(n[high]))) if sr > U64_BITS - 2 { if rem != nil { rem^ = a @@ -107,7 +107,7 @@ udivmod128 :: proc "c" (a, b: u128, rem: ^u128) -> u128 { r[low] = n[high] >> (sr - U64_BITS) } } else { - sr = transmute(u32)(i32(_clz(d[high])) - i32(_clz(n[high]))) + sr = u32(i32(_clz(d[high])) - i32(_clz(n[high]))) if sr > U64_BITS - 1 { if rem != nil { @@ -143,7 +143,7 @@ udivmod128 :: proc "c" (a, b: u128, rem: ^u128) -> u128 { r_all = transmute(u128)r s := i128(b - r_all - 1) >> (U128_BITS - 1) carry = u32(s & 1) - r_all -= b & transmute(u128)s + r_all -= b & u128(s) r = transmute([2]u64)r_all } diff --git a/core/compress/shoco/shoco.odin b/core/compress/shoco/shoco.odin index c0259ff75..269dd8875 100644 --- a/core/compress/shoco/shoco.odin +++ b/core/compress/shoco/shoco.odin @@ -98,7 +98,7 @@ decompress_slice_to_output_buffer :: proc(input: []u8, output: []u8, model := DE validate_model(model) or_return for inp < inp_end { - val := transmute(i8)input[inp] + val := i8(input[inp]) mark := int(-1) for val < 0 { From c88a1bef91c56e8b2732077965381156032805d3 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 29 Jun 2024 12:40:04 +0100 Subject: [PATCH 082/129] Add another `-vet-cast` check --- base/runtime/internal.odin | 1 + core/encoding/uuid/stamping.odin | 2 +- core/net/addr.odin | 7 +++---- core/net/socket_linux.odin | 4 ++-- src/check_expr.cpp | 22 +++++++++++----------- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/base/runtime/internal.odin b/base/runtime/internal.odin index 203ee2873..1a97ade09 100644 --- a/base/runtime/internal.odin +++ b/base/runtime/internal.odin @@ -1,3 +1,4 @@ +//+vet !cast package runtime import "base:intrinsics" diff --git a/core/encoding/uuid/stamping.odin b/core/encoding/uuid/stamping.odin index 0c07725c3..3ca61fe44 100644 --- a/core/encoding/uuid/stamping.odin +++ b/core/encoding/uuid/stamping.odin @@ -41,7 +41,7 @@ Returns: - result: A valid version 8 UUID. */ stamp_v8_array :: proc(array: [16]u8) -> (result: Identifier) { - result = transmute(Identifier)array + result = Identifier(array) result[VERSION_BYTE_INDEX] &= 0x0F result[VERSION_BYTE_INDEX] |= 0x80 diff --git a/core/net/addr.odin b/core/net/addr.odin index c01724d99..eed3fb3b9 100644 --- a/core/net/addr.odin +++ b/core/net/addr.odin @@ -370,7 +370,7 @@ parse_ip6_address :: proc(address_and_maybe_port: string) -> (addr: IP6_Address, val |= u16(ipv4[3]) piece_values[7] = u16be(val) } - return transmute(IP6_Address)piece_values, true + return IP6_Address(piece_values), true } /* @@ -522,10 +522,9 @@ address_to_string :: proc(addr: Address, allocator := context.temp_allocator) -> run := Zero_Run{-1, -1} best := Zero_Run{-1, -1} - addr := transmute([8]u16be)v last := u16be(1) - for val, i in addr { + for val, i in v { /* If we encounter adjacent zeroes, then start a new run if not already in one. Also remember the rightmost index regardless, because it'll be the new @@ -559,7 +558,7 @@ address_to_string :: proc(addr: Address, allocator := context.temp_allocator) -> last = val } - for val, i in addr { + for val, i in v { if best.start == i || best.end == i { // For the left and right side of the best zero run, print a `:`. fmt.sbprint(&b, ":") diff --git a/core/net/socket_linux.odin b/core/net/socket_linux.odin index a4d75b92b..dc960a5fb 100644 --- a/core/net/socket_linux.odin +++ b/core/net/socket_linux.odin @@ -80,14 +80,14 @@ _unwrap_os_addr :: proc "contextless" (endpoint: Endpoint)->(linux.Sock_Addr_Any ipv4 = { sin_family = .INET, sin_port = u16be(endpoint.port), - sin_addr = transmute([4]u8) endpoint.address.(IP4_Address), + sin_addr = ([4]u8)(endpoint.address.(IP4_Address)), }, } case IP6_Address: return { ipv6 = { sin6_port = u16be(endpoint.port), - sin6_addr = transmute([16]u8) endpoint.address.(IP6_Address), + sin6_addr = transmute([16]u8)endpoint.address.(IP6_Address), sin6_family = .INET6, }, } diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 6b11a9d08..7107c5712 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -3501,21 +3501,21 @@ gb_internal bool check_transmute(CheckerContext *c, Ast *node, Operand *o, Type // forbidden, so just skip them. if (forbid_identical && check_vet_flags(c) & VetFlag_Cast && (c->curr_proc_sig == nullptr || !is_type_polymorphic(c->curr_proc_sig))) { - bool is_runtime = false; - if (c->pkg && (c->pkg->kind == Package_Runtime || c->pkg->kind == Package_Builtin)) { - is_runtime = true; - } if (are_types_identical(src_t, dst_t)) { - if (!is_runtime) { - gbString oper_str = expr_to_string(o->expr); - gbString to_type = type_to_string(dst_t); - error(o->expr, "Unneeded transmute of '%s' to identical type '%s'", oper_str, to_type); - gb_string_free(oper_str); - gb_string_free(to_type); - } + gbString oper_str = expr_to_string(o->expr); + gbString to_type = type_to_string(dst_t); + error(o->expr, "Unneeded transmute of '%s' to identical type '%s'", oper_str, to_type); + gb_string_free(oper_str); + gb_string_free(to_type); } else if (is_type_internally_pointer_like(src_t) && is_type_internally_pointer_like(dst_t)) { error(o->expr, "Use of 'transmute' where 'cast' would be preferred since the types are pointer-like"); + } else if (are_types_identical(src_bt, dst_bt)) { + gbString oper_str = expr_to_string(o->expr); + gbString to_type = type_to_string(dst_t); + error(o->expr, "Unneeded transmute of '%s' to identical type '%s'", oper_str, to_type); + gb_string_free(oper_str); + gb_string_free(to_type); } else if (is_type_integer(src_t) && is_type_integer(dst_t) && types_have_same_internal_endian(src_t, dst_t)) { gbString oper_type = type_to_string(src_t); From 913c08a33e293518b1cfe7fdab55d559ba8042d6 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 29 Jun 2024 12:56:46 +0100 Subject: [PATCH 083/129] Add `bit_field` to demo.odin --- examples/demo/demo.odin | 45 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/examples/demo/demo.odin b/examples/demo/demo.odin index b3c627808..531538697 100644 --- a/examples/demo/demo.odin +++ b/examples/demo/demo.odin @@ -2550,6 +2550,50 @@ matrix_type :: proc() { // matrix_minor(m) } +bit_field_type :: proc() { + fmt.println("\n# bit_field type") + // A `bit_field` is a record type in Odin that is akin to a bit-packed struct. + // IMPORTNAT NOTE: `bit_field` is NOT equivalent to `bit_set` as it has different sematics and use cases. + + { + // `bit_field` fields are accessed by using a dot: + Foo :: bit_field u16 { // backing type must be an integer or array of integers + x: i32 | 3, // signed integers will be signed extended on use + y: u16 | 2 + 3, // general expressions + z: My_Enum | SOME_CONSTANT, // ability to define the bit-width elsewhere + w: bool | 2 when SOME_CONSTANT > 10 else 1, + } + + v := Foo{} + v.x = 3 // truncates the value to fit into 3 bits + fmt.println(v.x) // accessing will convert `v.x` to an `i32` and do an appropriate sign extension + + + My_Enum :: enum u8 {A, B, C, D} + SOME_CONSTANT :: 7 + } + + { + // A `bit_field` is different from a struct in that you must specify the backing type. + // This backing type must be an integer or a fixed-length array of integers. + // This is useful if ther eneeds to be a specific alignment or access pattern for the record. + + Bar :: bit_field u32 {} + Baz :: bit_field [4]u8 {} + } + + // IMPORTANT NOTES: + // * If _all_ of the fields in a bit_field are 1-bit in size and they are all booleans, + // please consider using a `bit_set` instead. + // * Odin's `bit_field` and C's bit-fields might not be compatible + // * Odin's `bit_field`s have a well defined layout (Least-Significant-Bit) + // * C's bit-fields on `struct`s are undefined and are not portable across targets and compilers + // * A `bit_field`'s field type can only be one of the following: + // * Integer + // * Boolean + // * Enum +} + main :: proc() { /* For More Odin Examples - https://github.com/odin-lang/examples @@ -2595,5 +2639,6 @@ main :: proc() { or_break_and_or_continue_operators() arbitrary_precision_mathematics() matrix_type() + bit_field_type() } } From ff2d04231389742e3f78bacc1c5e065d87a180fa Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 29 Jun 2024 13:54:15 +0100 Subject: [PATCH 084/129] Remove unneeded `transmute` --- base/runtime/wasm_allocator.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/runtime/wasm_allocator.odin b/base/runtime/wasm_allocator.odin index 6bca0b3d6..366dc2e44 100644 --- a/base/runtime/wasm_allocator.odin +++ b/base/runtime/wasm_allocator.odin @@ -495,7 +495,7 @@ claim_more_memory :: proc(a: ^WASM_Allocator, num_bytes: uint) -> bool { // we can just extend the spill. spill_end := uintptr(raw_data(a.spill)) + uintptr(len(a.spill)) if spill_end == uintptr(raw_data(allocated)) { - raw_spill := transmute(^Raw_Slice)(&a.spill) + raw_spill := (^Raw_Slice)(&a.spill) raw_spill.len += len(allocated) } else { // Otherwise, we have to "waste" the previous spill. From a935ade0d2a6a1cc7936f3ff8f45aaf8aca7df94 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 29 Jun 2024 16:18:07 +0100 Subject: [PATCH 085/129] Keep `-sanitize:address` happy with `bit_field` loads --- src/llvm_backend_general.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index 03d0f8b32..ebf721691 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -791,6 +791,7 @@ gb_internal void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value) { lb_emit_runtime_call(p, "__write_bits", args); } else if ((addr.bitfield.bit_offset % 8) == 0 && (addr.bitfield.bit_size % 8) == 0) { + gb_printf_err("Here!\n"); lbValue src = lb_address_from_load_or_generate_local(p, value); lbValue byte_offset = lb_const_int(p->module, t_uintptr, addr.bitfield.bit_offset/8); @@ -1162,7 +1163,7 @@ gb_internal lbValue lb_addr_load(lbProcedure *p, lbAddr const &addr) { lbValue copy_size = byte_size; lbValue src_offset = lb_emit_conv(p, src, t_u8_ptr); src_offset = lb_emit_ptr_offset(p, src_offset, byte_offset); - if (addr.bitfield.bit_offset + dst_byte_size <= total_bitfield_bit_size) { + if (addr.bitfield.bit_offset + 8*dst_byte_size <= total_bitfield_bit_size) { do_mask = true; copy_size = lb_const_int(p->module, t_uintptr, dst_byte_size); } From 6db748b4a434ae6002cd1e818b2f2cee5e70ffd4 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 29 Jun 2024 16:18:43 +0100 Subject: [PATCH 086/129] Remove debug message --- src/llvm_backend_general.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index ebf721691..c2ae5de74 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -791,7 +791,6 @@ gb_internal void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value) { lb_emit_runtime_call(p, "__write_bits", args); } else if ((addr.bitfield.bit_offset % 8) == 0 && (addr.bitfield.bit_size % 8) == 0) { - gb_printf_err("Here!\n"); lbValue src = lb_address_from_load_or_generate_local(p, value); lbValue byte_offset = lb_const_int(p->module, t_uintptr, addr.bitfield.bit_offset/8); From 7f05b4caf2e921c02996e1eb357f5988e67df831 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 29 Jun 2024 18:43:09 +0100 Subject: [PATCH 087/129] Fix generation for unicode entities --- core/encoding/entity/generated.odin | 9632 ++++++++--------- core/unicode/tools/generate_entity_table.odin | 6 +- 2 files changed, 4819 insertions(+), 4819 deletions(-) diff --git a/core/encoding/entity/generated.odin b/core/encoding/entity/generated.odin index d2acde20d..0c4742149 100644 --- a/core/encoding/entity/generated.odin +++ b/core/encoding/entity/generated.odin @@ -61,5026 +61,5026 @@ named_xml_entity_to_rune :: proc(name: string) -> (decoded: rune, ok: bool) { case 'A': switch name { - case "AElig": // LATIN CAPITAL LETTER AE - return rune(0xc6), true - case "AMP": // AMPERSAND - return rune(0x26), true - case "Aacgr": // GREEK CAPITAL LETTER ALPHA WITH TONOS - return rune(0x0386), true - case "Aacute": // LATIN CAPITAL LETTER A WITH ACUTE - return rune(0xc1), true - case "Abreve": // LATIN CAPITAL LETTER A WITH BREVE - return rune(0x0102), true - case "Acirc": // LATIN CAPITAL LETTER A WITH CIRCUMFLEX - return rune(0xc2), true - case "Acy": // CYRILLIC CAPITAL LETTER A - return rune(0x0410), true - case "Afr": // MATHEMATICAL FRAKTUR CAPITAL A - return rune(0x01d504), true - case "Agr": // GREEK CAPITAL LETTER ALPHA - return rune(0x0391), true - case "Agrave": // LATIN CAPITAL LETTER A WITH GRAVE - return rune(0xc0), true - case "Alpha": // GREEK CAPITAL LETTER ALPHA - return rune(0x0391), true - case "Amacr": // LATIN CAPITAL LETTER A WITH MACRON - return rune(0x0100), true - case "And": // DOUBLE LOGICAL AND - return rune(0x2a53), true - case "Aogon": // LATIN CAPITAL LETTER A WITH OGONEK - return rune(0x0104), true - case "Aopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL A - return rune(0x01d538), true - case "ApplyFunction": // FUNCTION APPLICATION - return rune(0x2061), true - case "Aring": // LATIN CAPITAL LETTER A WITH RING ABOVE - return rune(0xc5), true - case "Ascr": // MATHEMATICAL SCRIPT CAPITAL A - return rune(0x01d49c), true - case "Assign": // COLON EQUALS - return rune(0x2254), true - case "Ast": // TWO ASTERISKS ALIGNED VERTICALLY - return rune(0x2051), true - case "Atilde": // LATIN CAPITAL LETTER A WITH TILDE - return rune(0xc3), true - case "Auml": // LATIN CAPITAL LETTER A WITH DIAERESIS - return rune(0xc4), true + case "AElig": // LATIN CAPITAL LETTER AE + return rune(0xc6), true + case "AMP": // AMPERSAND + return rune(0x26), true + case "Aacgr": // GREEK CAPITAL LETTER ALPHA WITH TONOS + return rune(0x0386), true + case "Aacute": // LATIN CAPITAL LETTER A WITH ACUTE + return rune(0xc1), true + case "Abreve": // LATIN CAPITAL LETTER A WITH BREVE + return rune(0x0102), true + case "Acirc": // LATIN CAPITAL LETTER A WITH CIRCUMFLEX + return rune(0xc2), true + case "Acy": // CYRILLIC CAPITAL LETTER A + return rune(0x0410), true + case "Afr": // MATHEMATICAL FRAKTUR CAPITAL A + return rune(0x01d504), true + case "Agr": // GREEK CAPITAL LETTER ALPHA + return rune(0x0391), true + case "Agrave": // LATIN CAPITAL LETTER A WITH GRAVE + return rune(0xc0), true + case "Alpha": // GREEK CAPITAL LETTER ALPHA + return rune(0x0391), true + case "Amacr": // LATIN CAPITAL LETTER A WITH MACRON + return rune(0x0100), true + case "And": // DOUBLE LOGICAL AND + return rune(0x2a53), true + case "Aogon": // LATIN CAPITAL LETTER A WITH OGONEK + return rune(0x0104), true + case "Aopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL A + return rune(0x01d538), true + case "ApplyFunction": // FUNCTION APPLICATION + return rune(0x2061), true + case "Aring": // LATIN CAPITAL LETTER A WITH RING ABOVE + return rune(0xc5), true + case "Ascr": // MATHEMATICAL SCRIPT CAPITAL A + return rune(0x01d49c), true + case "Assign": // COLON EQUALS + return rune(0x2254), true + case "Ast": // TWO ASTERISKS ALIGNED VERTICALLY + return rune(0x2051), true + case "Atilde": // LATIN CAPITAL LETTER A WITH TILDE + return rune(0xc3), true + case "Auml": // LATIN CAPITAL LETTER A WITH DIAERESIS + return rune(0xc4), true } case 'B': switch name { - case "Backslash": // SET MINUS - return rune(0x2216), true - case "Barint": // INTEGRAL WITH DOUBLE STROKE - return rune(0x2a0e), true - case "Barv": // SHORT DOWN TACK WITH OVERBAR - return rune(0x2ae7), true - case "Barwed": // PERSPECTIVE - return rune(0x2306), true - case "Barwedl": // LOGICAL AND WITH DOUBLE OVERBAR - return rune(0x2a5e), true - case "Bcy": // CYRILLIC CAPITAL LETTER BE - return rune(0x0411), true - case "Because": // BECAUSE - return rune(0x2235), true - case "Bernoullis": // SCRIPT CAPITAL B - return rune(0x212c), true - case "Beta": // GREEK CAPITAL LETTER BETA - return rune(0x0392), true - case "Bfr": // MATHEMATICAL FRAKTUR CAPITAL B - return rune(0x01d505), true - case "Bgr": // GREEK CAPITAL LETTER BETA - return rune(0x0392), true - case "Bopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL B - return rune(0x01d539), true - case "Breve": // BREVE - return rune(0x02d8), true - case "Bscr": // SCRIPT CAPITAL B - return rune(0x212c), true - case "Bumpeq": // GEOMETRICALLY EQUIVALENT TO - return rune(0x224e), true - case "Bvert": // BOX DRAWINGS LIGHT TRIPLE DASH VERTICAL - return rune(0x2506), true + case "Backslash": // SET MINUS + return rune(0x2216), true + case "Barint": // INTEGRAL WITH DOUBLE STROKE + return rune(0x2a0e), true + case "Barv": // SHORT DOWN TACK WITH OVERBAR + return rune(0x2ae7), true + case "Barwed": // PERSPECTIVE + return rune(0x2306), true + case "Barwedl": // LOGICAL AND WITH DOUBLE OVERBAR + return rune(0x2a5e), true + case "Bcy": // CYRILLIC CAPITAL LETTER BE + return rune(0x0411), true + case "Because": // BECAUSE + return rune(0x2235), true + case "Bernoullis": // SCRIPT CAPITAL B + return rune(0x212c), true + case "Beta": // GREEK CAPITAL LETTER BETA + return rune(0x0392), true + case "Bfr": // MATHEMATICAL FRAKTUR CAPITAL B + return rune(0x01d505), true + case "Bgr": // GREEK CAPITAL LETTER BETA + return rune(0x0392), true + case "Bopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL B + return rune(0x01d539), true + case "Breve": // BREVE + return rune(0x02d8), true + case "Bscr": // SCRIPT CAPITAL B + return rune(0x212c), true + case "Bumpeq": // GEOMETRICALLY EQUIVALENT TO + return rune(0x224e), true + case "Bvert": // BOX DRAWINGS LIGHT TRIPLE DASH VERTICAL + return rune(0x2506), true } case 'C': switch name { - case "CHcy": // CYRILLIC CAPITAL LETTER CHE - return rune(0x0427), true - case "COPY": // COPYRIGHT SIGN - return rune(0xa9), true - case "Cacute": // LATIN CAPITAL LETTER C WITH ACUTE - return rune(0x0106), true - case "Cap": // DOUBLE INTERSECTION - return rune(0x22d2), true - case "CapitalDifferentialD": // DOUBLE-STRUCK ITALIC CAPITAL D - return rune(0x2145), true - case "Cayleys": // BLACK-LETTER CAPITAL C - return rune(0x212d), true - case "Ccaron": // LATIN CAPITAL LETTER C WITH CARON - return rune(0x010c), true - case "Ccedil": // LATIN CAPITAL LETTER C WITH CEDILLA - return rune(0xc7), true - case "Ccirc": // LATIN CAPITAL LETTER C WITH CIRCUMFLEX - return rune(0x0108), true - case "Cconint": // VOLUME INTEGRAL - return rune(0x2230), true - case "Cdot": // LATIN CAPITAL LETTER C WITH DOT ABOVE - return rune(0x010a), true - case "Cedilla": // CEDILLA - return rune(0xb8), true - case "CenterDot": // MIDDLE DOT - return rune(0xb7), true - case "Cfr": // BLACK-LETTER CAPITAL C - return rune(0x212d), true - case "Chi": // GREEK CAPITAL LETTER CHI - return rune(0x03a7), true - case "CircleDot": // CIRCLED DOT OPERATOR - return rune(0x2299), true - case "CircleMinus": // CIRCLED MINUS - return rune(0x2296), true - case "CirclePlus": // CIRCLED PLUS - return rune(0x2295), true - case "CircleTimes": // CIRCLED TIMES - return rune(0x2297), true - case "ClockwiseContourIntegral": // CLOCKWISE CONTOUR INTEGRAL - return rune(0x2232), true - case "CloseCurlyDoubleQuote": // RIGHT DOUBLE QUOTATION MARK - return rune(0x201d), true - case "CloseCurlyQuote": // RIGHT SINGLE QUOTATION MARK - return rune(0x2019), true - case "Colon": // PROPORTION - return rune(0x2237), true - case "Colone": // DOUBLE COLON EQUAL - return rune(0x2a74), true - case "Congruent": // IDENTICAL TO - return rune(0x2261), true - case "Conint": // SURFACE INTEGRAL - return rune(0x222f), true - case "ContourIntegral": // CONTOUR INTEGRAL - return rune(0x222e), true - case "Copf": // DOUBLE-STRUCK CAPITAL C - return rune(0x2102), true - case "Coproduct": // N-ARY COPRODUCT - return rune(0x2210), true - case "CounterClockwiseContourIntegral": // ANTICLOCKWISE CONTOUR INTEGRAL - return rune(0x2233), true - case "Cross": // VECTOR OR CROSS PRODUCT - return rune(0x2a2f), true - case "Cscr": // MATHEMATICAL SCRIPT CAPITAL C - return rune(0x01d49e), true - case "Cup": // DOUBLE UNION - return rune(0x22d3), true - case "CupCap": // EQUIVALENT TO - return rune(0x224d), true + case "CHcy": // CYRILLIC CAPITAL LETTER CHE + return rune(0x0427), true + case "COPY": // COPYRIGHT SIGN + return rune(0xa9), true + case "Cacute": // LATIN CAPITAL LETTER C WITH ACUTE + return rune(0x0106), true + case "Cap": // DOUBLE INTERSECTION + return rune(0x22d2), true + case "CapitalDifferentialD": // DOUBLE-STRUCK ITALIC CAPITAL D + return rune(0x2145), true + case "Cayleys": // BLACK-LETTER CAPITAL C + return rune(0x212d), true + case "Ccaron": // LATIN CAPITAL LETTER C WITH CARON + return rune(0x010c), true + case "Ccedil": // LATIN CAPITAL LETTER C WITH CEDILLA + return rune(0xc7), true + case "Ccirc": // LATIN CAPITAL LETTER C WITH CIRCUMFLEX + return rune(0x0108), true + case "Cconint": // VOLUME INTEGRAL + return rune(0x2230), true + case "Cdot": // LATIN CAPITAL LETTER C WITH DOT ABOVE + return rune(0x010a), true + case "Cedilla": // CEDILLA + return rune(0xb8), true + case "CenterDot": // MIDDLE DOT + return rune(0xb7), true + case "Cfr": // BLACK-LETTER CAPITAL C + return rune(0x212d), true + case "Chi": // GREEK CAPITAL LETTER CHI + return rune(0x03a7), true + case "CircleDot": // CIRCLED DOT OPERATOR + return rune(0x2299), true + case "CircleMinus": // CIRCLED MINUS + return rune(0x2296), true + case "CirclePlus": // CIRCLED PLUS + return rune(0x2295), true + case "CircleTimes": // CIRCLED TIMES + return rune(0x2297), true + case "ClockwiseContourIntegral": // CLOCKWISE CONTOUR INTEGRAL + return rune(0x2232), true + case "CloseCurlyDoubleQuote": // RIGHT DOUBLE QUOTATION MARK + return rune(0x201d), true + case "CloseCurlyQuote": // RIGHT SINGLE QUOTATION MARK + return rune(0x2019), true + case "Colon": // PROPORTION + return rune(0x2237), true + case "Colone": // DOUBLE COLON EQUAL + return rune(0x2a74), true + case "Congruent": // IDENTICAL TO + return rune(0x2261), true + case "Conint": // SURFACE INTEGRAL + return rune(0x222f), true + case "ContourIntegral": // CONTOUR INTEGRAL + return rune(0x222e), true + case "Copf": // DOUBLE-STRUCK CAPITAL C + return rune(0x2102), true + case "Coproduct": // N-ARY COPRODUCT + return rune(0x2210), true + case "CounterClockwiseContourIntegral": // ANTICLOCKWISE CONTOUR INTEGRAL + return rune(0x2233), true + case "Cross": // VECTOR OR CROSS PRODUCT + return rune(0x2a2f), true + case "Cscr": // MATHEMATICAL SCRIPT CAPITAL C + return rune(0x01d49e), true + case "Cup": // DOUBLE UNION + return rune(0x22d3), true + case "CupCap": // EQUIVALENT TO + return rune(0x224d), true } case 'D': switch name { - case "DD": // DOUBLE-STRUCK ITALIC CAPITAL D - return rune(0x2145), true - case "DDotrahd": // RIGHTWARDS ARROW WITH DOTTED STEM - return rune(0x2911), true - case "DJcy": // CYRILLIC CAPITAL LETTER DJE - return rune(0x0402), true - case "DScy": // CYRILLIC CAPITAL LETTER DZE - return rune(0x0405), true - case "DZcy": // CYRILLIC CAPITAL LETTER DZHE - return rune(0x040f), true - case "Dagger": // DOUBLE DAGGER - return rune(0x2021), true - case "Darr": // DOWNWARDS TWO HEADED ARROW - return rune(0x21a1), true - case "Dashv": // VERTICAL BAR DOUBLE LEFT TURNSTILE - return rune(0x2ae4), true - case "Dcaron": // LATIN CAPITAL LETTER D WITH CARON - return rune(0x010e), true - case "Dcy": // CYRILLIC CAPITAL LETTER DE - return rune(0x0414), true - case "Del": // NABLA - return rune(0x2207), true - case "Delta": // GREEK CAPITAL LETTER DELTA - return rune(0x0394), true - case "Dfr": // MATHEMATICAL FRAKTUR CAPITAL D - return rune(0x01d507), true - case "Dgr": // GREEK CAPITAL LETTER DELTA - return rune(0x0394), true - case "DiacriticalAcute": // ACUTE ACCENT - return rune(0xb4), true - case "DiacriticalDot": // DOT ABOVE - return rune(0x02d9), true - case "DiacriticalDoubleAcute": // DOUBLE ACUTE ACCENT - return rune(0x02dd), true - case "DiacriticalGrave": // GRAVE ACCENT - return rune(0x60), true - case "DiacriticalTilde": // SMALL TILDE - return rune(0x02dc), true - case "Diamond": // DIAMOND OPERATOR - return rune(0x22c4), true - case "DifferentialD": // DOUBLE-STRUCK ITALIC SMALL D - return rune(0x2146), true - case "Dopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL D - return rune(0x01d53b), true - case "Dot": // DIAERESIS - return rune(0xa8), true - case "DotDot": // COMBINING FOUR DOTS ABOVE - return rune(0x20dc), true - case "DotEqual": // APPROACHES THE LIMIT - return rune(0x2250), true - case "DoubleContourIntegral": // SURFACE INTEGRAL - return rune(0x222f), true - case "DoubleDot": // DIAERESIS - return rune(0xa8), true - case "DoubleDownArrow": // DOWNWARDS DOUBLE ARROW - return rune(0x21d3), true - case "DoubleLeftArrow": // LEFTWARDS DOUBLE ARROW - return rune(0x21d0), true - case "DoubleLeftRightArrow": // LEFT RIGHT DOUBLE ARROW - return rune(0x21d4), true - case "DoubleLeftTee": // VERTICAL BAR DOUBLE LEFT TURNSTILE - return rune(0x2ae4), true - case "DoubleLongLeftArrow": // LONG LEFTWARDS DOUBLE ARROW - return rune(0x27f8), true - case "DoubleLongLeftRightArrow": // LONG LEFT RIGHT DOUBLE ARROW - return rune(0x27fa), true - case "DoubleLongRightArrow": // LONG RIGHTWARDS DOUBLE ARROW - return rune(0x27f9), true - case "DoubleRightArrow": // RIGHTWARDS DOUBLE ARROW - return rune(0x21d2), true - case "DoubleRightTee": // TRUE - return rune(0x22a8), true - case "DoubleUpArrow": // UPWARDS DOUBLE ARROW - return rune(0x21d1), true - case "DoubleUpDownArrow": // UP DOWN DOUBLE ARROW - return rune(0x21d5), true - case "DoubleVerticalBar": // PARALLEL TO - return rune(0x2225), true - case "DownArrow": // DOWNWARDS ARROW - return rune(0x2193), true - case "DownArrowBar": // DOWNWARDS ARROW TO BAR - return rune(0x2913), true - case "DownArrowUpArrow": // DOWNWARDS ARROW LEFTWARDS OF UPWARDS ARROW - return rune(0x21f5), true - case "DownBreve": // COMBINING INVERTED BREVE - return rune(0x0311), true - case "DownLeftRightVector": // LEFT BARB DOWN RIGHT BARB DOWN HARPOON - return rune(0x2950), true - case "DownLeftTeeVector": // LEFTWARDS HARPOON WITH BARB DOWN FROM BAR - return rune(0x295e), true - case "DownLeftVector": // LEFTWARDS HARPOON WITH BARB DOWNWARDS - return rune(0x21bd), true - case "DownLeftVectorBar": // LEFTWARDS HARPOON WITH BARB DOWN TO BAR - return rune(0x2956), true - case "DownRightTeeVector": // RIGHTWARDS HARPOON WITH BARB DOWN FROM BAR - return rune(0x295f), true - case "DownRightVector": // RIGHTWARDS HARPOON WITH BARB DOWNWARDS - return rune(0x21c1), true - case "DownRightVectorBar": // RIGHTWARDS HARPOON WITH BARB DOWN TO BAR - return rune(0x2957), true - case "DownTee": // DOWN TACK - return rune(0x22a4), true - case "DownTeeArrow": // DOWNWARDS ARROW FROM BAR - return rune(0x21a7), true - case "Downarrow": // DOWNWARDS DOUBLE ARROW - return rune(0x21d3), true - case "Dscr": // MATHEMATICAL SCRIPT CAPITAL D - return rune(0x01d49f), true - case "Dstrok": // LATIN CAPITAL LETTER D WITH STROKE - return rune(0x0110), true + case "DD": // DOUBLE-STRUCK ITALIC CAPITAL D + return rune(0x2145), true + case "DDotrahd": // RIGHTWARDS ARROW WITH DOTTED STEM + return rune(0x2911), true + case "DJcy": // CYRILLIC CAPITAL LETTER DJE + return rune(0x0402), true + case "DScy": // CYRILLIC CAPITAL LETTER DZE + return rune(0x0405), true + case "DZcy": // CYRILLIC CAPITAL LETTER DZHE + return rune(0x040f), true + case "Dagger": // DOUBLE DAGGER + return rune(0x2021), true + case "Darr": // DOWNWARDS TWO HEADED ARROW + return rune(0x21a1), true + case "Dashv": // VERTICAL BAR DOUBLE LEFT TURNSTILE + return rune(0x2ae4), true + case "Dcaron": // LATIN CAPITAL LETTER D WITH CARON + return rune(0x010e), true + case "Dcy": // CYRILLIC CAPITAL LETTER DE + return rune(0x0414), true + case "Del": // NABLA + return rune(0x2207), true + case "Delta": // GREEK CAPITAL LETTER DELTA + return rune(0x0394), true + case "Dfr": // MATHEMATICAL FRAKTUR CAPITAL D + return rune(0x01d507), true + case "Dgr": // GREEK CAPITAL LETTER DELTA + return rune(0x0394), true + case "DiacriticalAcute": // ACUTE ACCENT + return rune(0xb4), true + case "DiacriticalDot": // DOT ABOVE + return rune(0x02d9), true + case "DiacriticalDoubleAcute": // DOUBLE ACUTE ACCENT + return rune(0x02dd), true + case "DiacriticalGrave": // GRAVE ACCENT + return rune(0x60), true + case "DiacriticalTilde": // SMALL TILDE + return rune(0x02dc), true + case "Diamond": // DIAMOND OPERATOR + return rune(0x22c4), true + case "DifferentialD": // DOUBLE-STRUCK ITALIC SMALL D + return rune(0x2146), true + case "Dopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL D + return rune(0x01d53b), true + case "Dot": // DIAERESIS + return rune(0xa8), true + case "DotDot": // COMBINING FOUR DOTS ABOVE + return rune(0x20dc), true + case "DotEqual": // APPROACHES THE LIMIT + return rune(0x2250), true + case "DoubleContourIntegral": // SURFACE INTEGRAL + return rune(0x222f), true + case "DoubleDot": // DIAERESIS + return rune(0xa8), true + case "DoubleDownArrow": // DOWNWARDS DOUBLE ARROW + return rune(0x21d3), true + case "DoubleLeftArrow": // LEFTWARDS DOUBLE ARROW + return rune(0x21d0), true + case "DoubleLeftRightArrow": // LEFT RIGHT DOUBLE ARROW + return rune(0x21d4), true + case "DoubleLeftTee": // VERTICAL BAR DOUBLE LEFT TURNSTILE + return rune(0x2ae4), true + case "DoubleLongLeftArrow": // LONG LEFTWARDS DOUBLE ARROW + return rune(0x27f8), true + case "DoubleLongLeftRightArrow": // LONG LEFT RIGHT DOUBLE ARROW + return rune(0x27fa), true + case "DoubleLongRightArrow": // LONG RIGHTWARDS DOUBLE ARROW + return rune(0x27f9), true + case "DoubleRightArrow": // RIGHTWARDS DOUBLE ARROW + return rune(0x21d2), true + case "DoubleRightTee": // TRUE + return rune(0x22a8), true + case "DoubleUpArrow": // UPWARDS DOUBLE ARROW + return rune(0x21d1), true + case "DoubleUpDownArrow": // UP DOWN DOUBLE ARROW + return rune(0x21d5), true + case "DoubleVerticalBar": // PARALLEL TO + return rune(0x2225), true + case "DownArrow": // DOWNWARDS ARROW + return rune(0x2193), true + case "DownArrowBar": // DOWNWARDS ARROW TO BAR + return rune(0x2913), true + case "DownArrowUpArrow": // DOWNWARDS ARROW LEFTWARDS OF UPWARDS ARROW + return rune(0x21f5), true + case "DownBreve": // COMBINING INVERTED BREVE + return rune(0x0311), true + case "DownLeftRightVector": // LEFT BARB DOWN RIGHT BARB DOWN HARPOON + return rune(0x2950), true + case "DownLeftTeeVector": // LEFTWARDS HARPOON WITH BARB DOWN FROM BAR + return rune(0x295e), true + case "DownLeftVector": // LEFTWARDS HARPOON WITH BARB DOWNWARDS + return rune(0x21bd), true + case "DownLeftVectorBar": // LEFTWARDS HARPOON WITH BARB DOWN TO BAR + return rune(0x2956), true + case "DownRightTeeVector": // RIGHTWARDS HARPOON WITH BARB DOWN FROM BAR + return rune(0x295f), true + case "DownRightVector": // RIGHTWARDS HARPOON WITH BARB DOWNWARDS + return rune(0x21c1), true + case "DownRightVectorBar": // RIGHTWARDS HARPOON WITH BARB DOWN TO BAR + return rune(0x2957), true + case "DownTee": // DOWN TACK + return rune(0x22a4), true + case "DownTeeArrow": // DOWNWARDS ARROW FROM BAR + return rune(0x21a7), true + case "Downarrow": // DOWNWARDS DOUBLE ARROW + return rune(0x21d3), true + case "Dscr": // MATHEMATICAL SCRIPT CAPITAL D + return rune(0x01d49f), true + case "Dstrok": // LATIN CAPITAL LETTER D WITH STROKE + return rune(0x0110), true } case 'E': switch name { - case "EEacgr": // GREEK CAPITAL LETTER ETA WITH TONOS - return rune(0x0389), true - case "EEgr": // GREEK CAPITAL LETTER ETA - return rune(0x0397), true - case "ENG": // LATIN CAPITAL LETTER ENG - return rune(0x014a), true - case "ETH": // LATIN CAPITAL LETTER ETH - return rune(0xd0), true - case "Eacgr": // GREEK CAPITAL LETTER EPSILON WITH TONOS - return rune(0x0388), true - case "Eacute": // LATIN CAPITAL LETTER E WITH ACUTE - return rune(0xc9), true - case "Ecaron": // LATIN CAPITAL LETTER E WITH CARON - return rune(0x011a), true - case "Ecirc": // LATIN CAPITAL LETTER E WITH CIRCUMFLEX - return rune(0xca), true - case "Ecy": // CYRILLIC CAPITAL LETTER E - return rune(0x042d), true - case "Edot": // LATIN CAPITAL LETTER E WITH DOT ABOVE - return rune(0x0116), true - case "Efr": // MATHEMATICAL FRAKTUR CAPITAL E - return rune(0x01d508), true - case "Egr": // GREEK CAPITAL LETTER EPSILON - return rune(0x0395), true - case "Egrave": // LATIN CAPITAL LETTER E WITH GRAVE - return rune(0xc8), true - case "Element": // ELEMENT OF - return rune(0x2208), true - case "Emacr": // LATIN CAPITAL LETTER E WITH MACRON - return rune(0x0112), true - case "EmptySmallSquare": // WHITE MEDIUM SQUARE - return rune(0x25fb), true - case "EmptyVerySmallSquare": // WHITE SMALL SQUARE - return rune(0x25ab), true - case "Eogon": // LATIN CAPITAL LETTER E WITH OGONEK - return rune(0x0118), true - case "Eopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL E - return rune(0x01d53c), true - case "Epsilon": // GREEK CAPITAL LETTER EPSILON - return rune(0x0395), true - case "Equal": // TWO CONSECUTIVE EQUALS SIGNS - return rune(0x2a75), true - case "EqualTilde": // MINUS TILDE - return rune(0x2242), true - case "Equilibrium": // RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON - return rune(0x21cc), true - case "Escr": // SCRIPT CAPITAL E - return rune(0x2130), true - case "Esim": // EQUALS SIGN ABOVE TILDE OPERATOR - return rune(0x2a73), true - case "Eta": // GREEK CAPITAL LETTER ETA - return rune(0x0397), true - case "Euml": // LATIN CAPITAL LETTER E WITH DIAERESIS - return rune(0xcb), true - case "Exists": // THERE EXISTS - return rune(0x2203), true - case "ExponentialE": // DOUBLE-STRUCK ITALIC SMALL E - return rune(0x2147), true + case "EEacgr": // GREEK CAPITAL LETTER ETA WITH TONOS + return rune(0x0389), true + case "EEgr": // GREEK CAPITAL LETTER ETA + return rune(0x0397), true + case "ENG": // LATIN CAPITAL LETTER ENG + return rune(0x014a), true + case "ETH": // LATIN CAPITAL LETTER ETH + return rune(0xd0), true + case "Eacgr": // GREEK CAPITAL LETTER EPSILON WITH TONOS + return rune(0x0388), true + case "Eacute": // LATIN CAPITAL LETTER E WITH ACUTE + return rune(0xc9), true + case "Ecaron": // LATIN CAPITAL LETTER E WITH CARON + return rune(0x011a), true + case "Ecirc": // LATIN CAPITAL LETTER E WITH CIRCUMFLEX + return rune(0xca), true + case "Ecy": // CYRILLIC CAPITAL LETTER E + return rune(0x042d), true + case "Edot": // LATIN CAPITAL LETTER E WITH DOT ABOVE + return rune(0x0116), true + case "Efr": // MATHEMATICAL FRAKTUR CAPITAL E + return rune(0x01d508), true + case "Egr": // GREEK CAPITAL LETTER EPSILON + return rune(0x0395), true + case "Egrave": // LATIN CAPITAL LETTER E WITH GRAVE + return rune(0xc8), true + case "Element": // ELEMENT OF + return rune(0x2208), true + case "Emacr": // LATIN CAPITAL LETTER E WITH MACRON + return rune(0x0112), true + case "EmptySmallSquare": // WHITE MEDIUM SQUARE + return rune(0x25fb), true + case "EmptyVerySmallSquare": // WHITE SMALL SQUARE + return rune(0x25ab), true + case "Eogon": // LATIN CAPITAL LETTER E WITH OGONEK + return rune(0x0118), true + case "Eopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL E + return rune(0x01d53c), true + case "Epsilon": // GREEK CAPITAL LETTER EPSILON + return rune(0x0395), true + case "Equal": // TWO CONSECUTIVE EQUALS SIGNS + return rune(0x2a75), true + case "EqualTilde": // MINUS TILDE + return rune(0x2242), true + case "Equilibrium": // RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON + return rune(0x21cc), true + case "Escr": // SCRIPT CAPITAL E + return rune(0x2130), true + case "Esim": // EQUALS SIGN ABOVE TILDE OPERATOR + return rune(0x2a73), true + case "Eta": // GREEK CAPITAL LETTER ETA + return rune(0x0397), true + case "Euml": // LATIN CAPITAL LETTER E WITH DIAERESIS + return rune(0xcb), true + case "Exists": // THERE EXISTS + return rune(0x2203), true + case "ExponentialE": // DOUBLE-STRUCK ITALIC SMALL E + return rune(0x2147), true } case 'F': switch name { - case "Fcy": // CYRILLIC CAPITAL LETTER EF - return rune(0x0424), true - case "Ffr": // MATHEMATICAL FRAKTUR CAPITAL F - return rune(0x01d509), true - case "FilledSmallSquare": // BLACK MEDIUM SQUARE - return rune(0x25fc), true - case "FilledVerySmallSquare": // BLACK SMALL SQUARE - return rune(0x25aa), true - case "Fopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL F - return rune(0x01d53d), true - case "ForAll": // FOR ALL - return rune(0x2200), true - case "Fouriertrf": // SCRIPT CAPITAL F - return rune(0x2131), true - case "Fscr": // SCRIPT CAPITAL F - return rune(0x2131), true + case "Fcy": // CYRILLIC CAPITAL LETTER EF + return rune(0x0424), true + case "Ffr": // MATHEMATICAL FRAKTUR CAPITAL F + return rune(0x01d509), true + case "FilledSmallSquare": // BLACK MEDIUM SQUARE + return rune(0x25fc), true + case "FilledVerySmallSquare": // BLACK SMALL SQUARE + return rune(0x25aa), true + case "Fopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL F + return rune(0x01d53d), true + case "ForAll": // FOR ALL + return rune(0x2200), true + case "Fouriertrf": // SCRIPT CAPITAL F + return rune(0x2131), true + case "Fscr": // SCRIPT CAPITAL F + return rune(0x2131), true } case 'G': switch name { - case "GJcy": // CYRILLIC CAPITAL LETTER GJE - return rune(0x0403), true - case "GT": // GREATER-THAN SIGN - return rune(0x3e), true - case "Game": // TURNED SANS-SERIF CAPITAL G - return rune(0x2141), true - case "Gamma": // GREEK CAPITAL LETTER GAMMA - return rune(0x0393), true - case "Gammad": // GREEK LETTER DIGAMMA - return rune(0x03dc), true - case "Gbreve": // LATIN CAPITAL LETTER G WITH BREVE - return rune(0x011e), true - case "Gcedil": // LATIN CAPITAL LETTER G WITH CEDILLA - return rune(0x0122), true - case "Gcirc": // LATIN CAPITAL LETTER G WITH CIRCUMFLEX - return rune(0x011c), true - case "Gcy": // CYRILLIC CAPITAL LETTER GHE - return rune(0x0413), true - case "Gdot": // LATIN CAPITAL LETTER G WITH DOT ABOVE - return rune(0x0120), true - case "Gfr": // MATHEMATICAL FRAKTUR CAPITAL G - return rune(0x01d50a), true - case "Gg": // VERY MUCH GREATER-THAN - return rune(0x22d9), true - case "Ggr": // GREEK CAPITAL LETTER GAMMA - return rune(0x0393), true - case "Gopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL G - return rune(0x01d53e), true - case "GreaterEqual": // GREATER-THAN OR EQUAL TO - return rune(0x2265), true - case "GreaterEqualLess": // GREATER-THAN EQUAL TO OR LESS-THAN - return rune(0x22db), true - case "GreaterFullEqual": // GREATER-THAN OVER EQUAL TO - return rune(0x2267), true - case "GreaterGreater": // DOUBLE NESTED GREATER-THAN - return rune(0x2aa2), true - case "GreaterLess": // GREATER-THAN OR LESS-THAN - return rune(0x2277), true - case "GreaterSlantEqual": // GREATER-THAN OR SLANTED EQUAL TO - return rune(0x2a7e), true - case "GreaterTilde": // GREATER-THAN OR EQUIVALENT TO - return rune(0x2273), true - case "Gscr": // MATHEMATICAL SCRIPT CAPITAL G - return rune(0x01d4a2), true - case "Gt": // MUCH GREATER-THAN - return rune(0x226b), true + case "GJcy": // CYRILLIC CAPITAL LETTER GJE + return rune(0x0403), true + case "GT": // GREATER-THAN SIGN + return rune(0x3e), true + case "Game": // TURNED SANS-SERIF CAPITAL G + return rune(0x2141), true + case "Gamma": // GREEK CAPITAL LETTER GAMMA + return rune(0x0393), true + case "Gammad": // GREEK LETTER DIGAMMA + return rune(0x03dc), true + case "Gbreve": // LATIN CAPITAL LETTER G WITH BREVE + return rune(0x011e), true + case "Gcedil": // LATIN CAPITAL LETTER G WITH CEDILLA + return rune(0x0122), true + case "Gcirc": // LATIN CAPITAL LETTER G WITH CIRCUMFLEX + return rune(0x011c), true + case "Gcy": // CYRILLIC CAPITAL LETTER GHE + return rune(0x0413), true + case "Gdot": // LATIN CAPITAL LETTER G WITH DOT ABOVE + return rune(0x0120), true + case "Gfr": // MATHEMATICAL FRAKTUR CAPITAL G + return rune(0x01d50a), true + case "Gg": // VERY MUCH GREATER-THAN + return rune(0x22d9), true + case "Ggr": // GREEK CAPITAL LETTER GAMMA + return rune(0x0393), true + case "Gopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL G + return rune(0x01d53e), true + case "GreaterEqual": // GREATER-THAN OR EQUAL TO + return rune(0x2265), true + case "GreaterEqualLess": // GREATER-THAN EQUAL TO OR LESS-THAN + return rune(0x22db), true + case "GreaterFullEqual": // GREATER-THAN OVER EQUAL TO + return rune(0x2267), true + case "GreaterGreater": // DOUBLE NESTED GREATER-THAN + return rune(0x2aa2), true + case "GreaterLess": // GREATER-THAN OR LESS-THAN + return rune(0x2277), true + case "GreaterSlantEqual": // GREATER-THAN OR SLANTED EQUAL TO + return rune(0x2a7e), true + case "GreaterTilde": // GREATER-THAN OR EQUIVALENT TO + return rune(0x2273), true + case "Gscr": // MATHEMATICAL SCRIPT CAPITAL G + return rune(0x01d4a2), true + case "Gt": // MUCH GREATER-THAN + return rune(0x226b), true } case 'H': switch name { - case "HARDcy": // CYRILLIC CAPITAL LETTER HARD SIGN - return rune(0x042a), true - case "Hacek": // CARON - return rune(0x02c7), true - case "Hat": // CIRCUMFLEX ACCENT - return rune(0x5e), true - case "Hcirc": // LATIN CAPITAL LETTER H WITH CIRCUMFLEX - return rune(0x0124), true - case "Hfr": // BLACK-LETTER CAPITAL H - return rune(0x210c), true - case "HilbertSpace": // SCRIPT CAPITAL H - return rune(0x210b), true - case "Hopf": // DOUBLE-STRUCK CAPITAL H - return rune(0x210d), true - case "HorizontalLine": // BOX DRAWINGS LIGHT HORIZONTAL - return rune(0x2500), true - case "Hscr": // SCRIPT CAPITAL H - return rune(0x210b), true - case "Hstrok": // LATIN CAPITAL LETTER H WITH STROKE - return rune(0x0126), true - case "HumpDownHump": // GEOMETRICALLY EQUIVALENT TO - return rune(0x224e), true - case "HumpEqual": // DIFFERENCE BETWEEN - return rune(0x224f), true + case "HARDcy": // CYRILLIC CAPITAL LETTER HARD SIGN + return rune(0x042a), true + case "Hacek": // CARON + return rune(0x02c7), true + case "Hat": // CIRCUMFLEX ACCENT + return rune(0x5e), true + case "Hcirc": // LATIN CAPITAL LETTER H WITH CIRCUMFLEX + return rune(0x0124), true + case "Hfr": // BLACK-LETTER CAPITAL H + return rune(0x210c), true + case "HilbertSpace": // SCRIPT CAPITAL H + return rune(0x210b), true + case "Hopf": // DOUBLE-STRUCK CAPITAL H + return rune(0x210d), true + case "HorizontalLine": // BOX DRAWINGS LIGHT HORIZONTAL + return rune(0x2500), true + case "Hscr": // SCRIPT CAPITAL H + return rune(0x210b), true + case "Hstrok": // LATIN CAPITAL LETTER H WITH STROKE + return rune(0x0126), true + case "HumpDownHump": // GEOMETRICALLY EQUIVALENT TO + return rune(0x224e), true + case "HumpEqual": // DIFFERENCE BETWEEN + return rune(0x224f), true } case 'I': switch name { - case "IEcy": // CYRILLIC CAPITAL LETTER IE - return rune(0x0415), true - case "IJlig": // LATIN CAPITAL LIGATURE IJ - return rune(0x0132), true - case "IOcy": // CYRILLIC CAPITAL LETTER IO - return rune(0x0401), true - case "Iacgr": // GREEK CAPITAL LETTER IOTA WITH TONOS - return rune(0x038a), true - case "Iacute": // LATIN CAPITAL LETTER I WITH ACUTE - return rune(0xcd), true - case "Icirc": // LATIN CAPITAL LETTER I WITH CIRCUMFLEX - return rune(0xce), true - case "Icy": // CYRILLIC CAPITAL LETTER I - return rune(0x0418), true - case "Idigr": // GREEK CAPITAL LETTER IOTA WITH DIALYTIKA - return rune(0x03aa), true - case "Idot": // LATIN CAPITAL LETTER I WITH DOT ABOVE - return rune(0x0130), true - case "Ifr": // BLACK-LETTER CAPITAL I - return rune(0x2111), true - case "Igr": // GREEK CAPITAL LETTER IOTA - return rune(0x0399), true - case "Igrave": // LATIN CAPITAL LETTER I WITH GRAVE - return rune(0xcc), true - case "Im": // BLACK-LETTER CAPITAL I - return rune(0x2111), true - case "Imacr": // LATIN CAPITAL LETTER I WITH MACRON - return rune(0x012a), true - case "ImaginaryI": // DOUBLE-STRUCK ITALIC SMALL I - return rune(0x2148), true - case "Implies": // RIGHTWARDS DOUBLE ARROW - return rune(0x21d2), true - case "Int": // DOUBLE INTEGRAL - return rune(0x222c), true - case "Integral": // INTEGRAL - return rune(0x222b), true - case "Intersection": // N-ARY INTERSECTION - return rune(0x22c2), true - case "InvisibleComma": // INVISIBLE SEPARATOR - return rune(0x2063), true - case "InvisibleTimes": // INVISIBLE TIMES - return rune(0x2062), true - case "Iogon": // LATIN CAPITAL LETTER I WITH OGONEK - return rune(0x012e), true - case "Iopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL I - return rune(0x01d540), true - case "Iota": // GREEK CAPITAL LETTER IOTA - return rune(0x0399), true - case "Iscr": // SCRIPT CAPITAL I - return rune(0x2110), true - case "Itilde": // LATIN CAPITAL LETTER I WITH TILDE - return rune(0x0128), true - case "Iukcy": // CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I - return rune(0x0406), true - case "Iuml": // LATIN CAPITAL LETTER I WITH DIAERESIS - return rune(0xcf), true + case "IEcy": // CYRILLIC CAPITAL LETTER IE + return rune(0x0415), true + case "IJlig": // LATIN CAPITAL LIGATURE IJ + return rune(0x0132), true + case "IOcy": // CYRILLIC CAPITAL LETTER IO + return rune(0x0401), true + case "Iacgr": // GREEK CAPITAL LETTER IOTA WITH TONOS + return rune(0x038a), true + case "Iacute": // LATIN CAPITAL LETTER I WITH ACUTE + return rune(0xcd), true + case "Icirc": // LATIN CAPITAL LETTER I WITH CIRCUMFLEX + return rune(0xce), true + case "Icy": // CYRILLIC CAPITAL LETTER I + return rune(0x0418), true + case "Idigr": // GREEK CAPITAL LETTER IOTA WITH DIALYTIKA + return rune(0x03aa), true + case "Idot": // LATIN CAPITAL LETTER I WITH DOT ABOVE + return rune(0x0130), true + case "Ifr": // BLACK-LETTER CAPITAL I + return rune(0x2111), true + case "Igr": // GREEK CAPITAL LETTER IOTA + return rune(0x0399), true + case "Igrave": // LATIN CAPITAL LETTER I WITH GRAVE + return rune(0xcc), true + case "Im": // BLACK-LETTER CAPITAL I + return rune(0x2111), true + case "Imacr": // LATIN CAPITAL LETTER I WITH MACRON + return rune(0x012a), true + case "ImaginaryI": // DOUBLE-STRUCK ITALIC SMALL I + return rune(0x2148), true + case "Implies": // RIGHTWARDS DOUBLE ARROW + return rune(0x21d2), true + case "Int": // DOUBLE INTEGRAL + return rune(0x222c), true + case "Integral": // INTEGRAL + return rune(0x222b), true + case "Intersection": // N-ARY INTERSECTION + return rune(0x22c2), true + case "InvisibleComma": // INVISIBLE SEPARATOR + return rune(0x2063), true + case "InvisibleTimes": // INVISIBLE TIMES + return rune(0x2062), true + case "Iogon": // LATIN CAPITAL LETTER I WITH OGONEK + return rune(0x012e), true + case "Iopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL I + return rune(0x01d540), true + case "Iota": // GREEK CAPITAL LETTER IOTA + return rune(0x0399), true + case "Iscr": // SCRIPT CAPITAL I + return rune(0x2110), true + case "Itilde": // LATIN CAPITAL LETTER I WITH TILDE + return rune(0x0128), true + case "Iukcy": // CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I + return rune(0x0406), true + case "Iuml": // LATIN CAPITAL LETTER I WITH DIAERESIS + return rune(0xcf), true } case 'J': switch name { - case "Jcirc": // LATIN CAPITAL LETTER J WITH CIRCUMFLEX - return rune(0x0134), true - case "Jcy": // CYRILLIC CAPITAL LETTER SHORT I - return rune(0x0419), true - case "Jfr": // MATHEMATICAL FRAKTUR CAPITAL J - return rune(0x01d50d), true - case "Jopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL J - return rune(0x01d541), true - case "Jscr": // MATHEMATICAL SCRIPT CAPITAL J - return rune(0x01d4a5), true - case "Jsercy": // CYRILLIC CAPITAL LETTER JE - return rune(0x0408), true - case "Jukcy": // CYRILLIC CAPITAL LETTER UKRAINIAN IE - return rune(0x0404), true + case "Jcirc": // LATIN CAPITAL LETTER J WITH CIRCUMFLEX + return rune(0x0134), true + case "Jcy": // CYRILLIC CAPITAL LETTER SHORT I + return rune(0x0419), true + case "Jfr": // MATHEMATICAL FRAKTUR CAPITAL J + return rune(0x01d50d), true + case "Jopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL J + return rune(0x01d541), true + case "Jscr": // MATHEMATICAL SCRIPT CAPITAL J + return rune(0x01d4a5), true + case "Jsercy": // CYRILLIC CAPITAL LETTER JE + return rune(0x0408), true + case "Jukcy": // CYRILLIC CAPITAL LETTER UKRAINIAN IE + return rune(0x0404), true } case 'K': switch name { - case "KHcy": // CYRILLIC CAPITAL LETTER HA - return rune(0x0425), true - case "KHgr": // GREEK CAPITAL LETTER CHI - return rune(0x03a7), true - case "KJcy": // CYRILLIC CAPITAL LETTER KJE - return rune(0x040c), true - case "Kappa": // GREEK CAPITAL LETTER KAPPA - return rune(0x039a), true - case "Kcedil": // LATIN CAPITAL LETTER K WITH CEDILLA - return rune(0x0136), true - case "Kcy": // CYRILLIC CAPITAL LETTER KA - return rune(0x041a), true - case "Kfr": // MATHEMATICAL FRAKTUR CAPITAL K - return rune(0x01d50e), true - case "Kgr": // GREEK CAPITAL LETTER KAPPA - return rune(0x039a), true - case "Kopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL K - return rune(0x01d542), true - case "Kscr": // MATHEMATICAL SCRIPT CAPITAL K - return rune(0x01d4a6), true + case "KHcy": // CYRILLIC CAPITAL LETTER HA + return rune(0x0425), true + case "KHgr": // GREEK CAPITAL LETTER CHI + return rune(0x03a7), true + case "KJcy": // CYRILLIC CAPITAL LETTER KJE + return rune(0x040c), true + case "Kappa": // GREEK CAPITAL LETTER KAPPA + return rune(0x039a), true + case "Kcedil": // LATIN CAPITAL LETTER K WITH CEDILLA + return rune(0x0136), true + case "Kcy": // CYRILLIC CAPITAL LETTER KA + return rune(0x041a), true + case "Kfr": // MATHEMATICAL FRAKTUR CAPITAL K + return rune(0x01d50e), true + case "Kgr": // GREEK CAPITAL LETTER KAPPA + return rune(0x039a), true + case "Kopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL K + return rune(0x01d542), true + case "Kscr": // MATHEMATICAL SCRIPT CAPITAL K + return rune(0x01d4a6), true } case 'L': switch name { - case "LJcy": // CYRILLIC CAPITAL LETTER LJE - return rune(0x0409), true - case "LT": // LESS-THAN SIGN - return rune(0x3c), true - case "Lacute": // LATIN CAPITAL LETTER L WITH ACUTE - return rune(0x0139), true - case "Lambda": // GREEK CAPITAL LETTER LAMDA - return rune(0x039b), true - case "Lang": // MATHEMATICAL LEFT DOUBLE ANGLE BRACKET - return rune(0x27ea), true - case "Laplacetrf": // SCRIPT CAPITAL L - return rune(0x2112), true - case "Larr": // LEFTWARDS TWO HEADED ARROW - return rune(0x219e), true - case "Lcaron": // LATIN CAPITAL LETTER L WITH CARON - return rune(0x013d), true - case "Lcedil": // LATIN CAPITAL LETTER L WITH CEDILLA - return rune(0x013b), true - case "Lcy": // CYRILLIC CAPITAL LETTER EL - return rune(0x041b), true - case "LeftAngleBracket": // MATHEMATICAL LEFT ANGLE BRACKET - return rune(0x27e8), true - case "LeftArrow": // LEFTWARDS ARROW - return rune(0x2190), true - case "LeftArrowBar": // LEFTWARDS ARROW TO BAR - return rune(0x21e4), true - case "LeftArrowRightArrow": // LEFTWARDS ARROW OVER RIGHTWARDS ARROW - return rune(0x21c6), true - case "LeftCeiling": // LEFT CEILING - return rune(0x2308), true - case "LeftDoubleBracket": // MATHEMATICAL LEFT WHITE SQUARE BRACKET - return rune(0x27e6), true - case "LeftDownTeeVector": // DOWNWARDS HARPOON WITH BARB LEFT FROM BAR - return rune(0x2961), true - case "LeftDownVector": // DOWNWARDS HARPOON WITH BARB LEFTWARDS - return rune(0x21c3), true - case "LeftDownVectorBar": // DOWNWARDS HARPOON WITH BARB LEFT TO BAR - return rune(0x2959), true - case "LeftFloor": // LEFT FLOOR - return rune(0x230a), true - case "LeftRightArrow": // LEFT RIGHT ARROW - return rune(0x2194), true - case "LeftRightVector": // LEFT BARB UP RIGHT BARB UP HARPOON - return rune(0x294e), true - case "LeftTee": // LEFT TACK - return rune(0x22a3), true - case "LeftTeeArrow": // LEFTWARDS ARROW FROM BAR - return rune(0x21a4), true - case "LeftTeeVector": // LEFTWARDS HARPOON WITH BARB UP FROM BAR - return rune(0x295a), true - case "LeftTriangle": // NORMAL SUBGROUP OF - return rune(0x22b2), true - case "LeftTriangleBar": // LEFT TRIANGLE BESIDE VERTICAL BAR - return rune(0x29cf), true - case "LeftTriangleEqual": // NORMAL SUBGROUP OF OR EQUAL TO - return rune(0x22b4), true - case "LeftUpDownVector": // UP BARB LEFT DOWN BARB LEFT HARPOON - return rune(0x2951), true - case "LeftUpTeeVector": // UPWARDS HARPOON WITH BARB LEFT FROM BAR - return rune(0x2960), true - case "LeftUpVector": // UPWARDS HARPOON WITH BARB LEFTWARDS - return rune(0x21bf), true - case "LeftUpVectorBar": // UPWARDS HARPOON WITH BARB LEFT TO BAR - return rune(0x2958), true - case "LeftVector": // LEFTWARDS HARPOON WITH BARB UPWARDS - return rune(0x21bc), true - case "LeftVectorBar": // LEFTWARDS HARPOON WITH BARB UP TO BAR - return rune(0x2952), true - case "Leftarrow": // LEFTWARDS DOUBLE ARROW - return rune(0x21d0), true - case "Leftrightarrow": // LEFT RIGHT DOUBLE ARROW - return rune(0x21d4), true - case "LessEqualGreater": // LESS-THAN EQUAL TO OR GREATER-THAN - return rune(0x22da), true - case "LessFullEqual": // LESS-THAN OVER EQUAL TO - return rune(0x2266), true - case "LessGreater": // LESS-THAN OR GREATER-THAN - return rune(0x2276), true - case "LessLess": // DOUBLE NESTED LESS-THAN - return rune(0x2aa1), true - case "LessSlantEqual": // LESS-THAN OR SLANTED EQUAL TO - return rune(0x2a7d), true - case "LessTilde": // LESS-THAN OR EQUIVALENT TO - return rune(0x2272), true - case "Lfr": // MATHEMATICAL FRAKTUR CAPITAL L - return rune(0x01d50f), true - case "Lgr": // GREEK CAPITAL LETTER LAMDA - return rune(0x039b), true - case "Ll": // VERY MUCH LESS-THAN - return rune(0x22d8), true - case "Lleftarrow": // LEFTWARDS TRIPLE ARROW - return rune(0x21da), true - case "Lmidot": // LATIN CAPITAL LETTER L WITH MIDDLE DOT - return rune(0x013f), true - case "LongLeftArrow": // LONG LEFTWARDS ARROW - return rune(0x27f5), true - case "LongLeftRightArrow": // LONG LEFT RIGHT ARROW - return rune(0x27f7), true - case "LongRightArrow": // LONG RIGHTWARDS ARROW - return rune(0x27f6), true - case "Longleftarrow": // LONG LEFTWARDS DOUBLE ARROW - return rune(0x27f8), true - case "Longleftrightarrow": // LONG LEFT RIGHT DOUBLE ARROW - return rune(0x27fa), true - case "Longrightarrow": // LONG RIGHTWARDS DOUBLE ARROW - return rune(0x27f9), true - case "Lopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL L - return rune(0x01d543), true - case "LowerLeftArrow": // SOUTH WEST ARROW - return rune(0x2199), true - case "LowerRightArrow": // SOUTH EAST ARROW - return rune(0x2198), true - case "Lscr": // SCRIPT CAPITAL L - return rune(0x2112), true - case "Lsh": // UPWARDS ARROW WITH TIP LEFTWARDS - return rune(0x21b0), true - case "Lstrok": // LATIN CAPITAL LETTER L WITH STROKE - return rune(0x0141), true - case "Lt": // MUCH LESS-THAN - return rune(0x226a), true - case "Ltbar": // DOUBLE NESTED LESS-THAN WITH UNDERBAR - return rune(0x2aa3), true + case "LJcy": // CYRILLIC CAPITAL LETTER LJE + return rune(0x0409), true + case "LT": // LESS-THAN SIGN + return rune(0x3c), true + case "Lacute": // LATIN CAPITAL LETTER L WITH ACUTE + return rune(0x0139), true + case "Lambda": // GREEK CAPITAL LETTER LAMDA + return rune(0x039b), true + case "Lang": // MATHEMATICAL LEFT DOUBLE ANGLE BRACKET + return rune(0x27ea), true + case "Laplacetrf": // SCRIPT CAPITAL L + return rune(0x2112), true + case "Larr": // LEFTWARDS TWO HEADED ARROW + return rune(0x219e), true + case "Lcaron": // LATIN CAPITAL LETTER L WITH CARON + return rune(0x013d), true + case "Lcedil": // LATIN CAPITAL LETTER L WITH CEDILLA + return rune(0x013b), true + case "Lcy": // CYRILLIC CAPITAL LETTER EL + return rune(0x041b), true + case "LeftAngleBracket": // MATHEMATICAL LEFT ANGLE BRACKET + return rune(0x27e8), true + case "LeftArrow": // LEFTWARDS ARROW + return rune(0x2190), true + case "LeftArrowBar": // LEFTWARDS ARROW TO BAR + return rune(0x21e4), true + case "LeftArrowRightArrow": // LEFTWARDS ARROW OVER RIGHTWARDS ARROW + return rune(0x21c6), true + case "LeftCeiling": // LEFT CEILING + return rune(0x2308), true + case "LeftDoubleBracket": // MATHEMATICAL LEFT WHITE SQUARE BRACKET + return rune(0x27e6), true + case "LeftDownTeeVector": // DOWNWARDS HARPOON WITH BARB LEFT FROM BAR + return rune(0x2961), true + case "LeftDownVector": // DOWNWARDS HARPOON WITH BARB LEFTWARDS + return rune(0x21c3), true + case "LeftDownVectorBar": // DOWNWARDS HARPOON WITH BARB LEFT TO BAR + return rune(0x2959), true + case "LeftFloor": // LEFT FLOOR + return rune(0x230a), true + case "LeftRightArrow": // LEFT RIGHT ARROW + return rune(0x2194), true + case "LeftRightVector": // LEFT BARB UP RIGHT BARB UP HARPOON + return rune(0x294e), true + case "LeftTee": // LEFT TACK + return rune(0x22a3), true + case "LeftTeeArrow": // LEFTWARDS ARROW FROM BAR + return rune(0x21a4), true + case "LeftTeeVector": // LEFTWARDS HARPOON WITH BARB UP FROM BAR + return rune(0x295a), true + case "LeftTriangle": // NORMAL SUBGROUP OF + return rune(0x22b2), true + case "LeftTriangleBar": // LEFT TRIANGLE BESIDE VERTICAL BAR + return rune(0x29cf), true + case "LeftTriangleEqual": // NORMAL SUBGROUP OF OR EQUAL TO + return rune(0x22b4), true + case "LeftUpDownVector": // UP BARB LEFT DOWN BARB LEFT HARPOON + return rune(0x2951), true + case "LeftUpTeeVector": // UPWARDS HARPOON WITH BARB LEFT FROM BAR + return rune(0x2960), true + case "LeftUpVector": // UPWARDS HARPOON WITH BARB LEFTWARDS + return rune(0x21bf), true + case "LeftUpVectorBar": // UPWARDS HARPOON WITH BARB LEFT TO BAR + return rune(0x2958), true + case "LeftVector": // LEFTWARDS HARPOON WITH BARB UPWARDS + return rune(0x21bc), true + case "LeftVectorBar": // LEFTWARDS HARPOON WITH BARB UP TO BAR + return rune(0x2952), true + case "Leftarrow": // LEFTWARDS DOUBLE ARROW + return rune(0x21d0), true + case "Leftrightarrow": // LEFT RIGHT DOUBLE ARROW + return rune(0x21d4), true + case "LessEqualGreater": // LESS-THAN EQUAL TO OR GREATER-THAN + return rune(0x22da), true + case "LessFullEqual": // LESS-THAN OVER EQUAL TO + return rune(0x2266), true + case "LessGreater": // LESS-THAN OR GREATER-THAN + return rune(0x2276), true + case "LessLess": // DOUBLE NESTED LESS-THAN + return rune(0x2aa1), true + case "LessSlantEqual": // LESS-THAN OR SLANTED EQUAL TO + return rune(0x2a7d), true + case "LessTilde": // LESS-THAN OR EQUIVALENT TO + return rune(0x2272), true + case "Lfr": // MATHEMATICAL FRAKTUR CAPITAL L + return rune(0x01d50f), true + case "Lgr": // GREEK CAPITAL LETTER LAMDA + return rune(0x039b), true + case "Ll": // VERY MUCH LESS-THAN + return rune(0x22d8), true + case "Lleftarrow": // LEFTWARDS TRIPLE ARROW + return rune(0x21da), true + case "Lmidot": // LATIN CAPITAL LETTER L WITH MIDDLE DOT + return rune(0x013f), true + case "LongLeftArrow": // LONG LEFTWARDS ARROW + return rune(0x27f5), true + case "LongLeftRightArrow": // LONG LEFT RIGHT ARROW + return rune(0x27f7), true + case "LongRightArrow": // LONG RIGHTWARDS ARROW + return rune(0x27f6), true + case "Longleftarrow": // LONG LEFTWARDS DOUBLE ARROW + return rune(0x27f8), true + case "Longleftrightarrow": // LONG LEFT RIGHT DOUBLE ARROW + return rune(0x27fa), true + case "Longrightarrow": // LONG RIGHTWARDS DOUBLE ARROW + return rune(0x27f9), true + case "Lopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL L + return rune(0x01d543), true + case "LowerLeftArrow": // SOUTH WEST ARROW + return rune(0x2199), true + case "LowerRightArrow": // SOUTH EAST ARROW + return rune(0x2198), true + case "Lscr": // SCRIPT CAPITAL L + return rune(0x2112), true + case "Lsh": // UPWARDS ARROW WITH TIP LEFTWARDS + return rune(0x21b0), true + case "Lstrok": // LATIN CAPITAL LETTER L WITH STROKE + return rune(0x0141), true + case "Lt": // MUCH LESS-THAN + return rune(0x226a), true + case "Ltbar": // DOUBLE NESTED LESS-THAN WITH UNDERBAR + return rune(0x2aa3), true } case 'M': switch name { - case "Map": // RIGHTWARDS TWO-HEADED ARROW FROM BAR - return rune(0x2905), true - case "Mapfrom": // LEFTWARDS DOUBLE ARROW FROM BAR - return rune(0x2906), true - case "Mapto": // RIGHTWARDS DOUBLE ARROW FROM BAR - return rune(0x2907), true - case "Mcy": // CYRILLIC CAPITAL LETTER EM - return rune(0x041c), true - case "MediumSpace": // MEDIUM MATHEMATICAL SPACE - return rune(0x205f), true - case "Mellintrf": // SCRIPT CAPITAL M - return rune(0x2133), true - case "Mfr": // MATHEMATICAL FRAKTUR CAPITAL M - return rune(0x01d510), true - case "Mgr": // GREEK CAPITAL LETTER MU - return rune(0x039c), true - case "MinusPlus": // MINUS-OR-PLUS SIGN - return rune(0x2213), true - case "Mopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL M - return rune(0x01d544), true - case "Mscr": // SCRIPT CAPITAL M - return rune(0x2133), true - case "Mu": // GREEK CAPITAL LETTER MU - return rune(0x039c), true + case "Map": // RIGHTWARDS TWO-HEADED ARROW FROM BAR + return rune(0x2905), true + case "Mapfrom": // LEFTWARDS DOUBLE ARROW FROM BAR + return rune(0x2906), true + case "Mapto": // RIGHTWARDS DOUBLE ARROW FROM BAR + return rune(0x2907), true + case "Mcy": // CYRILLIC CAPITAL LETTER EM + return rune(0x041c), true + case "MediumSpace": // MEDIUM MATHEMATICAL SPACE + return rune(0x205f), true + case "Mellintrf": // SCRIPT CAPITAL M + return rune(0x2133), true + case "Mfr": // MATHEMATICAL FRAKTUR CAPITAL M + return rune(0x01d510), true + case "Mgr": // GREEK CAPITAL LETTER MU + return rune(0x039c), true + case "MinusPlus": // MINUS-OR-PLUS SIGN + return rune(0x2213), true + case "Mopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL M + return rune(0x01d544), true + case "Mscr": // SCRIPT CAPITAL M + return rune(0x2133), true + case "Mu": // GREEK CAPITAL LETTER MU + return rune(0x039c), true } case 'N': switch name { - case "NJcy": // CYRILLIC CAPITAL LETTER NJE - return rune(0x040a), true - case "Nacute": // LATIN CAPITAL LETTER N WITH ACUTE - return rune(0x0143), true - case "Ncaron": // LATIN CAPITAL LETTER N WITH CARON - return rune(0x0147), true - case "Ncedil": // LATIN CAPITAL LETTER N WITH CEDILLA - return rune(0x0145), true - case "Ncy": // CYRILLIC CAPITAL LETTER EN - return rune(0x041d), true - case "NegativeMediumSpace": // ZERO WIDTH SPACE - return rune(0x200b), true - case "NegativeThickSpace": // ZERO WIDTH SPACE - return rune(0x200b), true - case "NegativeThinSpace": // ZERO WIDTH SPACE - return rune(0x200b), true - case "NegativeVeryThinSpace": // ZERO WIDTH SPACE - return rune(0x200b), true - case "NestedGreaterGreater": // MUCH GREATER-THAN - return rune(0x226b), true - case "NestedLessLess": // MUCH LESS-THAN - return rune(0x226a), true - case "NewLine": // LINE FEED (LF) - return rune(0x0a), true - case "Nfr": // MATHEMATICAL FRAKTUR CAPITAL N - return rune(0x01d511), true - case "Ngr": // GREEK CAPITAL LETTER NU - return rune(0x039d), true - case "NoBreak": // WORD JOINER - return rune(0x2060), true - case "NonBreakingSpace": // NO-BREAK SPACE - return rune(0xa0), true - case "Nopf": // DOUBLE-STRUCK CAPITAL N - return rune(0x2115), true - case "Not": // DOUBLE STROKE NOT SIGN - return rune(0x2aec), true - case "NotCongruent": // NOT IDENTICAL TO - return rune(0x2262), true - case "NotCupCap": // NOT EQUIVALENT TO - return rune(0x226d), true - case "NotDoubleVerticalBar": // NOT PARALLEL TO - return rune(0x2226), true - case "NotElement": // NOT AN ELEMENT OF - return rune(0x2209), true - case "NotEqual": // NOT EQUAL TO - return rune(0x2260), true - case "NotEqualTilde": // MINUS TILDE with slash - return rune(0x2242), true - case "NotExists": // THERE DOES NOT EXIST - return rune(0x2204), true - case "NotGreater": // NOT GREATER-THAN - return rune(0x226f), true - case "NotGreaterEqual": // NEITHER GREATER-THAN NOR EQUAL TO - return rune(0x2271), true - case "NotGreaterFullEqual": // GREATER-THAN OVER EQUAL TO with slash - return rune(0x2267), true - case "NotGreaterGreater": // MUCH GREATER THAN with slash - return rune(0x226b), true - case "NotGreaterLess": // NEITHER GREATER-THAN NOR LESS-THAN - return rune(0x2279), true - case "NotGreaterSlantEqual": // GREATER-THAN OR SLANTED EQUAL TO with slash - return rune(0x2a7e), true - case "NotGreaterTilde": // NEITHER GREATER-THAN NOR EQUIVALENT TO - return rune(0x2275), true - case "NotHumpDownHump": // GEOMETRICALLY EQUIVALENT TO with slash - return rune(0x224e), true - case "NotHumpEqual": // DIFFERENCE BETWEEN with slash - return rune(0x224f), true - case "NotLeftTriangle": // NOT NORMAL SUBGROUP OF - return rune(0x22ea), true - case "NotLeftTriangleBar": // LEFT TRIANGLE BESIDE VERTICAL BAR with slash - return rune(0x29cf), true - case "NotLeftTriangleEqual": // NOT NORMAL SUBGROUP OF OR EQUAL TO - return rune(0x22ec), true - case "NotLess": // NOT LESS-THAN - return rune(0x226e), true - case "NotLessEqual": // NEITHER LESS-THAN NOR EQUAL TO - return rune(0x2270), true - case "NotLessGreater": // NEITHER LESS-THAN NOR GREATER-THAN - return rune(0x2278), true - case "NotLessLess": // MUCH LESS THAN with slash - return rune(0x226a), true - case "NotLessSlantEqual": // LESS-THAN OR SLANTED EQUAL TO with slash - return rune(0x2a7d), true - case "NotLessTilde": // NEITHER LESS-THAN NOR EQUIVALENT TO - return rune(0x2274), true - case "NotNestedGreaterGreater": // DOUBLE NESTED GREATER-THAN with slash - return rune(0x2aa2), true - case "NotNestedLessLess": // DOUBLE NESTED LESS-THAN with slash - return rune(0x2aa1), true - case "NotPrecedes": // DOES NOT PRECEDE - return rune(0x2280), true - case "NotPrecedesEqual": // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN with slash - return rune(0x2aaf), true - case "NotPrecedesSlantEqual": // DOES NOT PRECEDE OR EQUAL - return rune(0x22e0), true - case "NotReverseElement": // DOES NOT CONTAIN AS MEMBER - return rune(0x220c), true - case "NotRightTriangle": // DOES NOT CONTAIN AS NORMAL SUBGROUP - return rune(0x22eb), true - case "NotRightTriangleBar": // VERTICAL BAR BESIDE RIGHT TRIANGLE with slash - return rune(0x29d0), true - case "NotRightTriangleEqual": // DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL - return rune(0x22ed), true - case "NotSquareSubset": // SQUARE IMAGE OF with slash - return rune(0x228f), true - case "NotSquareSubsetEqual": // NOT SQUARE IMAGE OF OR EQUAL TO - return rune(0x22e2), true - case "NotSquareSuperset": // SQUARE ORIGINAL OF with slash - return rune(0x2290), true - case "NotSquareSupersetEqual": // NOT SQUARE ORIGINAL OF OR EQUAL TO - return rune(0x22e3), true - case "NotSubset": // SUBSET OF with vertical line - return rune(0x2282), true - case "NotSubsetEqual": // NEITHER A SUBSET OF NOR EQUAL TO - return rune(0x2288), true - case "NotSucceeds": // DOES NOT SUCCEED - return rune(0x2281), true - case "NotSucceedsEqual": // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN with slash - return rune(0x2ab0), true - case "NotSucceedsSlantEqual": // DOES NOT SUCCEED OR EQUAL - return rune(0x22e1), true - case "NotSucceedsTilde": // SUCCEEDS OR EQUIVALENT TO with slash - return rune(0x227f), true - case "NotSuperset": // SUPERSET OF with vertical line - return rune(0x2283), true - case "NotSupersetEqual": // NEITHER A SUPERSET OF NOR EQUAL TO - return rune(0x2289), true - case "NotTilde": // NOT TILDE - return rune(0x2241), true - case "NotTildeEqual": // NOT ASYMPTOTICALLY EQUAL TO - return rune(0x2244), true - case "NotTildeFullEqual": // NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO - return rune(0x2247), true - case "NotTildeTilde": // NOT ALMOST EQUAL TO - return rune(0x2249), true - case "NotVerticalBar": // DOES NOT DIVIDE - return rune(0x2224), true - case "Nscr": // MATHEMATICAL SCRIPT CAPITAL N - return rune(0x01d4a9), true - case "Ntilde": // LATIN CAPITAL LETTER N WITH TILDE - return rune(0xd1), true - case "Nu": // GREEK CAPITAL LETTER NU - return rune(0x039d), true + case "NJcy": // CYRILLIC CAPITAL LETTER NJE + return rune(0x040a), true + case "Nacute": // LATIN CAPITAL LETTER N WITH ACUTE + return rune(0x0143), true + case "Ncaron": // LATIN CAPITAL LETTER N WITH CARON + return rune(0x0147), true + case "Ncedil": // LATIN CAPITAL LETTER N WITH CEDILLA + return rune(0x0145), true + case "Ncy": // CYRILLIC CAPITAL LETTER EN + return rune(0x041d), true + case "NegativeMediumSpace": // ZERO WIDTH SPACE + return rune(0x200b), true + case "NegativeThickSpace": // ZERO WIDTH SPACE + return rune(0x200b), true + case "NegativeThinSpace": // ZERO WIDTH SPACE + return rune(0x200b), true + case "NegativeVeryThinSpace": // ZERO WIDTH SPACE + return rune(0x200b), true + case "NestedGreaterGreater": // MUCH GREATER-THAN + return rune(0x226b), true + case "NestedLessLess": // MUCH LESS-THAN + return rune(0x226a), true + case "NewLine": // LINE FEED (LF) + return rune(0x0a), true + case "Nfr": // MATHEMATICAL FRAKTUR CAPITAL N + return rune(0x01d511), true + case "Ngr": // GREEK CAPITAL LETTER NU + return rune(0x039d), true + case "NoBreak": // WORD JOINER + return rune(0x2060), true + case "NonBreakingSpace": // NO-BREAK SPACE + return rune(0xa0), true + case "Nopf": // DOUBLE-STRUCK CAPITAL N + return rune(0x2115), true + case "Not": // DOUBLE STROKE NOT SIGN + return rune(0x2aec), true + case "NotCongruent": // NOT IDENTICAL TO + return rune(0x2262), true + case "NotCupCap": // NOT EQUIVALENT TO + return rune(0x226d), true + case "NotDoubleVerticalBar": // NOT PARALLEL TO + return rune(0x2226), true + case "NotElement": // NOT AN ELEMENT OF + return rune(0x2209), true + case "NotEqual": // NOT EQUAL TO + return rune(0x2260), true + case "NotEqualTilde": // MINUS TILDE with slash + return rune(0x2242), true + case "NotExists": // THERE DOES NOT EXIST + return rune(0x2204), true + case "NotGreater": // NOT GREATER-THAN + return rune(0x226f), true + case "NotGreaterEqual": // NEITHER GREATER-THAN NOR EQUAL TO + return rune(0x2271), true + case "NotGreaterFullEqual": // GREATER-THAN OVER EQUAL TO with slash + return rune(0x2267), true + case "NotGreaterGreater": // MUCH GREATER THAN with slash + return rune(0x226b), true + case "NotGreaterLess": // NEITHER GREATER-THAN NOR LESS-THAN + return rune(0x2279), true + case "NotGreaterSlantEqual": // GREATER-THAN OR SLANTED EQUAL TO with slash + return rune(0x2a7e), true + case "NotGreaterTilde": // NEITHER GREATER-THAN NOR EQUIVALENT TO + return rune(0x2275), true + case "NotHumpDownHump": // GEOMETRICALLY EQUIVALENT TO with slash + return rune(0x224e), true + case "NotHumpEqual": // DIFFERENCE BETWEEN with slash + return rune(0x224f), true + case "NotLeftTriangle": // NOT NORMAL SUBGROUP OF + return rune(0x22ea), true + case "NotLeftTriangleBar": // LEFT TRIANGLE BESIDE VERTICAL BAR with slash + return rune(0x29cf), true + case "NotLeftTriangleEqual": // NOT NORMAL SUBGROUP OF OR EQUAL TO + return rune(0x22ec), true + case "NotLess": // NOT LESS-THAN + return rune(0x226e), true + case "NotLessEqual": // NEITHER LESS-THAN NOR EQUAL TO + return rune(0x2270), true + case "NotLessGreater": // NEITHER LESS-THAN NOR GREATER-THAN + return rune(0x2278), true + case "NotLessLess": // MUCH LESS THAN with slash + return rune(0x226a), true + case "NotLessSlantEqual": // LESS-THAN OR SLANTED EQUAL TO with slash + return rune(0x2a7d), true + case "NotLessTilde": // NEITHER LESS-THAN NOR EQUIVALENT TO + return rune(0x2274), true + case "NotNestedGreaterGreater": // DOUBLE NESTED GREATER-THAN with slash + return rune(0x2aa2), true + case "NotNestedLessLess": // DOUBLE NESTED LESS-THAN with slash + return rune(0x2aa1), true + case "NotPrecedes": // DOES NOT PRECEDE + return rune(0x2280), true + case "NotPrecedesEqual": // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN with slash + return rune(0x2aaf), true + case "NotPrecedesSlantEqual": // DOES NOT PRECEDE OR EQUAL + return rune(0x22e0), true + case "NotReverseElement": // DOES NOT CONTAIN AS MEMBER + return rune(0x220c), true + case "NotRightTriangle": // DOES NOT CONTAIN AS NORMAL SUBGROUP + return rune(0x22eb), true + case "NotRightTriangleBar": // VERTICAL BAR BESIDE RIGHT TRIANGLE with slash + return rune(0x29d0), true + case "NotRightTriangleEqual": // DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL + return rune(0x22ed), true + case "NotSquareSubset": // SQUARE IMAGE OF with slash + return rune(0x228f), true + case "NotSquareSubsetEqual": // NOT SQUARE IMAGE OF OR EQUAL TO + return rune(0x22e2), true + case "NotSquareSuperset": // SQUARE ORIGINAL OF with slash + return rune(0x2290), true + case "NotSquareSupersetEqual": // NOT SQUARE ORIGINAL OF OR EQUAL TO + return rune(0x22e3), true + case "NotSubset": // SUBSET OF with vertical line + return rune(0x2282), true + case "NotSubsetEqual": // NEITHER A SUBSET OF NOR EQUAL TO + return rune(0x2288), true + case "NotSucceeds": // DOES NOT SUCCEED + return rune(0x2281), true + case "NotSucceedsEqual": // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN with slash + return rune(0x2ab0), true + case "NotSucceedsSlantEqual": // DOES NOT SUCCEED OR EQUAL + return rune(0x22e1), true + case "NotSucceedsTilde": // SUCCEEDS OR EQUIVALENT TO with slash + return rune(0x227f), true + case "NotSuperset": // SUPERSET OF with vertical line + return rune(0x2283), true + case "NotSupersetEqual": // NEITHER A SUPERSET OF NOR EQUAL TO + return rune(0x2289), true + case "NotTilde": // NOT TILDE + return rune(0x2241), true + case "NotTildeEqual": // NOT ASYMPTOTICALLY EQUAL TO + return rune(0x2244), true + case "NotTildeFullEqual": // NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO + return rune(0x2247), true + case "NotTildeTilde": // NOT ALMOST EQUAL TO + return rune(0x2249), true + case "NotVerticalBar": // DOES NOT DIVIDE + return rune(0x2224), true + case "Nscr": // MATHEMATICAL SCRIPT CAPITAL N + return rune(0x01d4a9), true + case "Ntilde": // LATIN CAPITAL LETTER N WITH TILDE + return rune(0xd1), true + case "Nu": // GREEK CAPITAL LETTER NU + return rune(0x039d), true } case 'O': switch name { - case "OElig": // LATIN CAPITAL LIGATURE OE - return rune(0x0152), true - case "OHacgr": // GREEK CAPITAL LETTER OMEGA WITH TONOS - return rune(0x038f), true - case "OHgr": // GREEK CAPITAL LETTER OMEGA - return rune(0x03a9), true - case "Oacgr": // GREEK CAPITAL LETTER OMICRON WITH TONOS - return rune(0x038c), true - case "Oacute": // LATIN CAPITAL LETTER O WITH ACUTE - return rune(0xd3), true - case "Ocirc": // LATIN CAPITAL LETTER O WITH CIRCUMFLEX - return rune(0xd4), true - case "Ocy": // CYRILLIC CAPITAL LETTER O - return rune(0x041e), true - case "Odblac": // LATIN CAPITAL LETTER O WITH DOUBLE ACUTE - return rune(0x0150), true - case "Ofr": // MATHEMATICAL FRAKTUR CAPITAL O - return rune(0x01d512), true - case "Ogr": // GREEK CAPITAL LETTER OMICRON - return rune(0x039f), true - case "Ograve": // LATIN CAPITAL LETTER O WITH GRAVE - return rune(0xd2), true - case "Omacr": // LATIN CAPITAL LETTER O WITH MACRON - return rune(0x014c), true - case "Omega": // GREEK CAPITAL LETTER OMEGA - return rune(0x03a9), true - case "Omicron": // GREEK CAPITAL LETTER OMICRON - return rune(0x039f), true - case "Oopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL O - return rune(0x01d546), true - case "OpenCurlyDoubleQuote": // LEFT DOUBLE QUOTATION MARK - return rune(0x201c), true - case "OpenCurlyQuote": // LEFT SINGLE QUOTATION MARK - return rune(0x2018), true - case "Or": // DOUBLE LOGICAL OR - return rune(0x2a54), true - case "Oscr": // MATHEMATICAL SCRIPT CAPITAL O - return rune(0x01d4aa), true - case "Oslash": // LATIN CAPITAL LETTER O WITH STROKE - return rune(0xd8), true - case "Otilde": // LATIN CAPITAL LETTER O WITH TILDE - return rune(0xd5), true - case "Otimes": // MULTIPLICATION SIGN IN DOUBLE CIRCLE - return rune(0x2a37), true - case "Ouml": // LATIN CAPITAL LETTER O WITH DIAERESIS - return rune(0xd6), true - case "OverBar": // OVERLINE - return rune(0x203e), true - case "OverBrace": // TOP CURLY BRACKET - return rune(0x23de), true - case "OverBracket": // TOP SQUARE BRACKET - return rune(0x23b4), true - case "OverParenthesis": // TOP PARENTHESIS - return rune(0x23dc), true + case "OElig": // LATIN CAPITAL LIGATURE OE + return rune(0x0152), true + case "OHacgr": // GREEK CAPITAL LETTER OMEGA WITH TONOS + return rune(0x038f), true + case "OHgr": // GREEK CAPITAL LETTER OMEGA + return rune(0x03a9), true + case "Oacgr": // GREEK CAPITAL LETTER OMICRON WITH TONOS + return rune(0x038c), true + case "Oacute": // LATIN CAPITAL LETTER O WITH ACUTE + return rune(0xd3), true + case "Ocirc": // LATIN CAPITAL LETTER O WITH CIRCUMFLEX + return rune(0xd4), true + case "Ocy": // CYRILLIC CAPITAL LETTER O + return rune(0x041e), true + case "Odblac": // LATIN CAPITAL LETTER O WITH DOUBLE ACUTE + return rune(0x0150), true + case "Ofr": // MATHEMATICAL FRAKTUR CAPITAL O + return rune(0x01d512), true + case "Ogr": // GREEK CAPITAL LETTER OMICRON + return rune(0x039f), true + case "Ograve": // LATIN CAPITAL LETTER O WITH GRAVE + return rune(0xd2), true + case "Omacr": // LATIN CAPITAL LETTER O WITH MACRON + return rune(0x014c), true + case "Omega": // GREEK CAPITAL LETTER OMEGA + return rune(0x03a9), true + case "Omicron": // GREEK CAPITAL LETTER OMICRON + return rune(0x039f), true + case "Oopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL O + return rune(0x01d546), true + case "OpenCurlyDoubleQuote": // LEFT DOUBLE QUOTATION MARK + return rune(0x201c), true + case "OpenCurlyQuote": // LEFT SINGLE QUOTATION MARK + return rune(0x2018), true + case "Or": // DOUBLE LOGICAL OR + return rune(0x2a54), true + case "Oscr": // MATHEMATICAL SCRIPT CAPITAL O + return rune(0x01d4aa), true + case "Oslash": // LATIN CAPITAL LETTER O WITH STROKE + return rune(0xd8), true + case "Otilde": // LATIN CAPITAL LETTER O WITH TILDE + return rune(0xd5), true + case "Otimes": // MULTIPLICATION SIGN IN DOUBLE CIRCLE + return rune(0x2a37), true + case "Ouml": // LATIN CAPITAL LETTER O WITH DIAERESIS + return rune(0xd6), true + case "OverBar": // OVERLINE + return rune(0x203e), true + case "OverBrace": // TOP CURLY BRACKET + return rune(0x23de), true + case "OverBracket": // TOP SQUARE BRACKET + return rune(0x23b4), true + case "OverParenthesis": // TOP PARENTHESIS + return rune(0x23dc), true } case 'P': switch name { - case "PHgr": // GREEK CAPITAL LETTER PHI - return rune(0x03a6), true - case "PSgr": // GREEK CAPITAL LETTER PSI - return rune(0x03a8), true - case "PartialD": // PARTIAL DIFFERENTIAL - return rune(0x2202), true - case "Pcy": // CYRILLIC CAPITAL LETTER PE - return rune(0x041f), true - case "Pfr": // MATHEMATICAL FRAKTUR CAPITAL P - return rune(0x01d513), true - case "Pgr": // GREEK CAPITAL LETTER PI - return rune(0x03a0), true - case "Phi": // GREEK CAPITAL LETTER PHI - return rune(0x03a6), true - case "Pi": // GREEK CAPITAL LETTER PI - return rune(0x03a0), true - case "PlusMinus": // PLUS-MINUS SIGN - return rune(0xb1), true - case "Poincareplane": // BLACK-LETTER CAPITAL H - return rune(0x210c), true - case "Popf": // DOUBLE-STRUCK CAPITAL P - return rune(0x2119), true - case "Pr": // DOUBLE PRECEDES - return rune(0x2abb), true - case "Precedes": // PRECEDES - return rune(0x227a), true - case "PrecedesEqual": // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN - return rune(0x2aaf), true - case "PrecedesSlantEqual": // PRECEDES OR EQUAL TO - return rune(0x227c), true - case "PrecedesTilde": // PRECEDES OR EQUIVALENT TO - return rune(0x227e), true - case "Prime": // DOUBLE PRIME - return rune(0x2033), true - case "Product": // N-ARY PRODUCT - return rune(0x220f), true - case "Proportion": // PROPORTION - return rune(0x2237), true - case "Proportional": // PROPORTIONAL TO - return rune(0x221d), true - case "Pscr": // MATHEMATICAL SCRIPT CAPITAL P - return rune(0x01d4ab), true - case "Psi": // GREEK CAPITAL LETTER PSI - return rune(0x03a8), true + case "PHgr": // GREEK CAPITAL LETTER PHI + return rune(0x03a6), true + case "PSgr": // GREEK CAPITAL LETTER PSI + return rune(0x03a8), true + case "PartialD": // PARTIAL DIFFERENTIAL + return rune(0x2202), true + case "Pcy": // CYRILLIC CAPITAL LETTER PE + return rune(0x041f), true + case "Pfr": // MATHEMATICAL FRAKTUR CAPITAL P + return rune(0x01d513), true + case "Pgr": // GREEK CAPITAL LETTER PI + return rune(0x03a0), true + case "Phi": // GREEK CAPITAL LETTER PHI + return rune(0x03a6), true + case "Pi": // GREEK CAPITAL LETTER PI + return rune(0x03a0), true + case "PlusMinus": // PLUS-MINUS SIGN + return rune(0xb1), true + case "Poincareplane": // BLACK-LETTER CAPITAL H + return rune(0x210c), true + case "Popf": // DOUBLE-STRUCK CAPITAL P + return rune(0x2119), true + case "Pr": // DOUBLE PRECEDES + return rune(0x2abb), true + case "Precedes": // PRECEDES + return rune(0x227a), true + case "PrecedesEqual": // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN + return rune(0x2aaf), true + case "PrecedesSlantEqual": // PRECEDES OR EQUAL TO + return rune(0x227c), true + case "PrecedesTilde": // PRECEDES OR EQUIVALENT TO + return rune(0x227e), true + case "Prime": // DOUBLE PRIME + return rune(0x2033), true + case "Product": // N-ARY PRODUCT + return rune(0x220f), true + case "Proportion": // PROPORTION + return rune(0x2237), true + case "Proportional": // PROPORTIONAL TO + return rune(0x221d), true + case "Pscr": // MATHEMATICAL SCRIPT CAPITAL P + return rune(0x01d4ab), true + case "Psi": // GREEK CAPITAL LETTER PSI + return rune(0x03a8), true } case 'Q': switch name { - case "QUOT": // QUOTATION MARK - return rune(0x22), true - case "Qfr": // MATHEMATICAL FRAKTUR CAPITAL Q - return rune(0x01d514), true - case "Qopf": // DOUBLE-STRUCK CAPITAL Q - return rune(0x211a), true - case "Qscr": // MATHEMATICAL SCRIPT CAPITAL Q - return rune(0x01d4ac), true + case "QUOT": // QUOTATION MARK + return rune(0x22), true + case "Qfr": // MATHEMATICAL FRAKTUR CAPITAL Q + return rune(0x01d514), true + case "Qopf": // DOUBLE-STRUCK CAPITAL Q + return rune(0x211a), true + case "Qscr": // MATHEMATICAL SCRIPT CAPITAL Q + return rune(0x01d4ac), true } case 'R': switch name { - case "RBarr": // RIGHTWARDS TWO-HEADED TRIPLE DASH ARROW - return rune(0x2910), true - case "REG": // REGISTERED SIGN - return rune(0xae), true - case "Racute": // LATIN CAPITAL LETTER R WITH ACUTE - return rune(0x0154), true - case "Rang": // MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET - return rune(0x27eb), true - case "Rarr": // RIGHTWARDS TWO HEADED ARROW - return rune(0x21a0), true - case "Rarrtl": // RIGHTWARDS TWO-HEADED ARROW WITH TAIL - return rune(0x2916), true - case "Rcaron": // LATIN CAPITAL LETTER R WITH CARON - return rune(0x0158), true - case "Rcedil": // LATIN CAPITAL LETTER R WITH CEDILLA - return rune(0x0156), true - case "Rcy": // CYRILLIC CAPITAL LETTER ER - return rune(0x0420), true - case "Re": // BLACK-LETTER CAPITAL R - return rune(0x211c), true - case "ReverseElement": // CONTAINS AS MEMBER - return rune(0x220b), true - case "ReverseEquilibrium": // LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON - return rune(0x21cb), true - case "ReverseUpEquilibrium": // DOWNWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT - return rune(0x296f), true - case "Rfr": // BLACK-LETTER CAPITAL R - return rune(0x211c), true - case "Rgr": // GREEK CAPITAL LETTER RHO - return rune(0x03a1), true - case "Rho": // GREEK CAPITAL LETTER RHO - return rune(0x03a1), true - case "RightAngleBracket": // MATHEMATICAL RIGHT ANGLE BRACKET - return rune(0x27e9), true - case "RightArrow": // RIGHTWARDS ARROW - return rune(0x2192), true - case "RightArrowBar": // RIGHTWARDS ARROW TO BAR - return rune(0x21e5), true - case "RightArrowLeftArrow": // RIGHTWARDS ARROW OVER LEFTWARDS ARROW - return rune(0x21c4), true - case "RightCeiling": // RIGHT CEILING - return rune(0x2309), true - case "RightDoubleBracket": // MATHEMATICAL RIGHT WHITE SQUARE BRACKET - return rune(0x27e7), true - case "RightDownTeeVector": // DOWNWARDS HARPOON WITH BARB RIGHT FROM BAR - return rune(0x295d), true - case "RightDownVector": // DOWNWARDS HARPOON WITH BARB RIGHTWARDS - return rune(0x21c2), true - case "RightDownVectorBar": // DOWNWARDS HARPOON WITH BARB RIGHT TO BAR - return rune(0x2955), true - case "RightFloor": // RIGHT FLOOR - return rune(0x230b), true - case "RightTee": // RIGHT TACK - return rune(0x22a2), true - case "RightTeeArrow": // RIGHTWARDS ARROW FROM BAR - return rune(0x21a6), true - case "RightTeeVector": // RIGHTWARDS HARPOON WITH BARB UP FROM BAR - return rune(0x295b), true - case "RightTriangle": // CONTAINS AS NORMAL SUBGROUP - return rune(0x22b3), true - case "RightTriangleBar": // VERTICAL BAR BESIDE RIGHT TRIANGLE - return rune(0x29d0), true - case "RightTriangleEqual": // CONTAINS AS NORMAL SUBGROUP OR EQUAL TO - return rune(0x22b5), true - case "RightUpDownVector": // UP BARB RIGHT DOWN BARB RIGHT HARPOON - return rune(0x294f), true - case "RightUpTeeVector": // UPWARDS HARPOON WITH BARB RIGHT FROM BAR - return rune(0x295c), true - case "RightUpVector": // UPWARDS HARPOON WITH BARB RIGHTWARDS - return rune(0x21be), true - case "RightUpVectorBar": // UPWARDS HARPOON WITH BARB RIGHT TO BAR - return rune(0x2954), true - case "RightVector": // RIGHTWARDS HARPOON WITH BARB UPWARDS - return rune(0x21c0), true - case "RightVectorBar": // RIGHTWARDS HARPOON WITH BARB UP TO BAR - return rune(0x2953), true - case "Rightarrow": // RIGHTWARDS DOUBLE ARROW - return rune(0x21d2), true - case "Ropf": // DOUBLE-STRUCK CAPITAL R - return rune(0x211d), true - case "RoundImplies": // RIGHT DOUBLE ARROW WITH ROUNDED HEAD - return rune(0x2970), true - case "Rrightarrow": // RIGHTWARDS TRIPLE ARROW - return rune(0x21db), true - case "Rscr": // SCRIPT CAPITAL R - return rune(0x211b), true - case "Rsh": // UPWARDS ARROW WITH TIP RIGHTWARDS - return rune(0x21b1), true - case "RuleDelayed": // RULE-DELAYED - return rune(0x29f4), true + case "RBarr": // RIGHTWARDS TWO-HEADED TRIPLE DASH ARROW + return rune(0x2910), true + case "REG": // REGISTERED SIGN + return rune(0xae), true + case "Racute": // LATIN CAPITAL LETTER R WITH ACUTE + return rune(0x0154), true + case "Rang": // MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET + return rune(0x27eb), true + case "Rarr": // RIGHTWARDS TWO HEADED ARROW + return rune(0x21a0), true + case "Rarrtl": // RIGHTWARDS TWO-HEADED ARROW WITH TAIL + return rune(0x2916), true + case "Rcaron": // LATIN CAPITAL LETTER R WITH CARON + return rune(0x0158), true + case "Rcedil": // LATIN CAPITAL LETTER R WITH CEDILLA + return rune(0x0156), true + case "Rcy": // CYRILLIC CAPITAL LETTER ER + return rune(0x0420), true + case "Re": // BLACK-LETTER CAPITAL R + return rune(0x211c), true + case "ReverseElement": // CONTAINS AS MEMBER + return rune(0x220b), true + case "ReverseEquilibrium": // LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON + return rune(0x21cb), true + case "ReverseUpEquilibrium": // DOWNWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT + return rune(0x296f), true + case "Rfr": // BLACK-LETTER CAPITAL R + return rune(0x211c), true + case "Rgr": // GREEK CAPITAL LETTER RHO + return rune(0x03a1), true + case "Rho": // GREEK CAPITAL LETTER RHO + return rune(0x03a1), true + case "RightAngleBracket": // MATHEMATICAL RIGHT ANGLE BRACKET + return rune(0x27e9), true + case "RightArrow": // RIGHTWARDS ARROW + return rune(0x2192), true + case "RightArrowBar": // RIGHTWARDS ARROW TO BAR + return rune(0x21e5), true + case "RightArrowLeftArrow": // RIGHTWARDS ARROW OVER LEFTWARDS ARROW + return rune(0x21c4), true + case "RightCeiling": // RIGHT CEILING + return rune(0x2309), true + case "RightDoubleBracket": // MATHEMATICAL RIGHT WHITE SQUARE BRACKET + return rune(0x27e7), true + case "RightDownTeeVector": // DOWNWARDS HARPOON WITH BARB RIGHT FROM BAR + return rune(0x295d), true + case "RightDownVector": // DOWNWARDS HARPOON WITH BARB RIGHTWARDS + return rune(0x21c2), true + case "RightDownVectorBar": // DOWNWARDS HARPOON WITH BARB RIGHT TO BAR + return rune(0x2955), true + case "RightFloor": // RIGHT FLOOR + return rune(0x230b), true + case "RightTee": // RIGHT TACK + return rune(0x22a2), true + case "RightTeeArrow": // RIGHTWARDS ARROW FROM BAR + return rune(0x21a6), true + case "RightTeeVector": // RIGHTWARDS HARPOON WITH BARB UP FROM BAR + return rune(0x295b), true + case "RightTriangle": // CONTAINS AS NORMAL SUBGROUP + return rune(0x22b3), true + case "RightTriangleBar": // VERTICAL BAR BESIDE RIGHT TRIANGLE + return rune(0x29d0), true + case "RightTriangleEqual": // CONTAINS AS NORMAL SUBGROUP OR EQUAL TO + return rune(0x22b5), true + case "RightUpDownVector": // UP BARB RIGHT DOWN BARB RIGHT HARPOON + return rune(0x294f), true + case "RightUpTeeVector": // UPWARDS HARPOON WITH BARB RIGHT FROM BAR + return rune(0x295c), true + case "RightUpVector": // UPWARDS HARPOON WITH BARB RIGHTWARDS + return rune(0x21be), true + case "RightUpVectorBar": // UPWARDS HARPOON WITH BARB RIGHT TO BAR + return rune(0x2954), true + case "RightVector": // RIGHTWARDS HARPOON WITH BARB UPWARDS + return rune(0x21c0), true + case "RightVectorBar": // RIGHTWARDS HARPOON WITH BARB UP TO BAR + return rune(0x2953), true + case "Rightarrow": // RIGHTWARDS DOUBLE ARROW + return rune(0x21d2), true + case "Ropf": // DOUBLE-STRUCK CAPITAL R + return rune(0x211d), true + case "RoundImplies": // RIGHT DOUBLE ARROW WITH ROUNDED HEAD + return rune(0x2970), true + case "Rrightarrow": // RIGHTWARDS TRIPLE ARROW + return rune(0x21db), true + case "Rscr": // SCRIPT CAPITAL R + return rune(0x211b), true + case "Rsh": // UPWARDS ARROW WITH TIP RIGHTWARDS + return rune(0x21b1), true + case "RuleDelayed": // RULE-DELAYED + return rune(0x29f4), true } case 'S': switch name { - case "SHCHcy": // CYRILLIC CAPITAL LETTER SHCHA - return rune(0x0429), true - case "SHcy": // CYRILLIC CAPITAL LETTER SHA - return rune(0x0428), true - case "SOFTcy": // CYRILLIC CAPITAL LETTER SOFT SIGN - return rune(0x042c), true - case "Sacute": // LATIN CAPITAL LETTER S WITH ACUTE - return rune(0x015a), true - case "Sc": // DOUBLE SUCCEEDS - return rune(0x2abc), true - case "Scaron": // LATIN CAPITAL LETTER S WITH CARON - return rune(0x0160), true - case "Scedil": // LATIN CAPITAL LETTER S WITH CEDILLA - return rune(0x015e), true - case "Scirc": // LATIN CAPITAL LETTER S WITH CIRCUMFLEX - return rune(0x015c), true - case "Scy": // CYRILLIC CAPITAL LETTER ES - return rune(0x0421), true - case "Sfr": // MATHEMATICAL FRAKTUR CAPITAL S - return rune(0x01d516), true - case "Sgr": // GREEK CAPITAL LETTER SIGMA - return rune(0x03a3), true - case "ShortDownArrow": // DOWNWARDS ARROW - return rune(0x2193), true - case "ShortLeftArrow": // LEFTWARDS ARROW - return rune(0x2190), true - case "ShortRightArrow": // RIGHTWARDS ARROW - return rune(0x2192), true - case "ShortUpArrow": // UPWARDS ARROW - return rune(0x2191), true - case "Sigma": // GREEK CAPITAL LETTER SIGMA - return rune(0x03a3), true - case "SmallCircle": // RING OPERATOR - return rune(0x2218), true - case "Sopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL S - return rune(0x01d54a), true - case "Sqrt": // SQUARE ROOT - return rune(0x221a), true - case "Square": // WHITE SQUARE - return rune(0x25a1), true - case "SquareIntersection": // SQUARE CAP - return rune(0x2293), true - case "SquareSubset": // SQUARE IMAGE OF - return rune(0x228f), true - case "SquareSubsetEqual": // SQUARE IMAGE OF OR EQUAL TO - return rune(0x2291), true - case "SquareSuperset": // SQUARE ORIGINAL OF - return rune(0x2290), true - case "SquareSupersetEqual": // SQUARE ORIGINAL OF OR EQUAL TO - return rune(0x2292), true - case "SquareUnion": // SQUARE CUP - return rune(0x2294), true - case "Sscr": // MATHEMATICAL SCRIPT CAPITAL S - return rune(0x01d4ae), true - case "Star": // STAR OPERATOR - return rune(0x22c6), true - case "Sub": // DOUBLE SUBSET - return rune(0x22d0), true - case "Subset": // DOUBLE SUBSET - return rune(0x22d0), true - case "SubsetEqual": // SUBSET OF OR EQUAL TO - return rune(0x2286), true - case "Succeeds": // SUCCEEDS - return rune(0x227b), true - case "SucceedsEqual": // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN - return rune(0x2ab0), true - case "SucceedsSlantEqual": // SUCCEEDS OR EQUAL TO - return rune(0x227d), true - case "SucceedsTilde": // SUCCEEDS OR EQUIVALENT TO - return rune(0x227f), true - case "SuchThat": // CONTAINS AS MEMBER - return rune(0x220b), true - case "Sum": // N-ARY SUMMATION - return rune(0x2211), true - case "Sup": // DOUBLE SUPERSET - return rune(0x22d1), true - case "Superset": // SUPERSET OF - return rune(0x2283), true - case "SupersetEqual": // SUPERSET OF OR EQUAL TO - return rune(0x2287), true - case "Supset": // DOUBLE SUPERSET - return rune(0x22d1), true + case "SHCHcy": // CYRILLIC CAPITAL LETTER SHCHA + return rune(0x0429), true + case "SHcy": // CYRILLIC CAPITAL LETTER SHA + return rune(0x0428), true + case "SOFTcy": // CYRILLIC CAPITAL LETTER SOFT SIGN + return rune(0x042c), true + case "Sacute": // LATIN CAPITAL LETTER S WITH ACUTE + return rune(0x015a), true + case "Sc": // DOUBLE SUCCEEDS + return rune(0x2abc), true + case "Scaron": // LATIN CAPITAL LETTER S WITH CARON + return rune(0x0160), true + case "Scedil": // LATIN CAPITAL LETTER S WITH CEDILLA + return rune(0x015e), true + case "Scirc": // LATIN CAPITAL LETTER S WITH CIRCUMFLEX + return rune(0x015c), true + case "Scy": // CYRILLIC CAPITAL LETTER ES + return rune(0x0421), true + case "Sfr": // MATHEMATICAL FRAKTUR CAPITAL S + return rune(0x01d516), true + case "Sgr": // GREEK CAPITAL LETTER SIGMA + return rune(0x03a3), true + case "ShortDownArrow": // DOWNWARDS ARROW + return rune(0x2193), true + case "ShortLeftArrow": // LEFTWARDS ARROW + return rune(0x2190), true + case "ShortRightArrow": // RIGHTWARDS ARROW + return rune(0x2192), true + case "ShortUpArrow": // UPWARDS ARROW + return rune(0x2191), true + case "Sigma": // GREEK CAPITAL LETTER SIGMA + return rune(0x03a3), true + case "SmallCircle": // RING OPERATOR + return rune(0x2218), true + case "Sopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL S + return rune(0x01d54a), true + case "Sqrt": // SQUARE ROOT + return rune(0x221a), true + case "Square": // WHITE SQUARE + return rune(0x25a1), true + case "SquareIntersection": // SQUARE CAP + return rune(0x2293), true + case "SquareSubset": // SQUARE IMAGE OF + return rune(0x228f), true + case "SquareSubsetEqual": // SQUARE IMAGE OF OR EQUAL TO + return rune(0x2291), true + case "SquareSuperset": // SQUARE ORIGINAL OF + return rune(0x2290), true + case "SquareSupersetEqual": // SQUARE ORIGINAL OF OR EQUAL TO + return rune(0x2292), true + case "SquareUnion": // SQUARE CUP + return rune(0x2294), true + case "Sscr": // MATHEMATICAL SCRIPT CAPITAL S + return rune(0x01d4ae), true + case "Star": // STAR OPERATOR + return rune(0x22c6), true + case "Sub": // DOUBLE SUBSET + return rune(0x22d0), true + case "Subset": // DOUBLE SUBSET + return rune(0x22d0), true + case "SubsetEqual": // SUBSET OF OR EQUAL TO + return rune(0x2286), true + case "Succeeds": // SUCCEEDS + return rune(0x227b), true + case "SucceedsEqual": // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN + return rune(0x2ab0), true + case "SucceedsSlantEqual": // SUCCEEDS OR EQUAL TO + return rune(0x227d), true + case "SucceedsTilde": // SUCCEEDS OR EQUIVALENT TO + return rune(0x227f), true + case "SuchThat": // CONTAINS AS MEMBER + return rune(0x220b), true + case "Sum": // N-ARY SUMMATION + return rune(0x2211), true + case "Sup": // DOUBLE SUPERSET + return rune(0x22d1), true + case "Superset": // SUPERSET OF + return rune(0x2283), true + case "SupersetEqual": // SUPERSET OF OR EQUAL TO + return rune(0x2287), true + case "Supset": // DOUBLE SUPERSET + return rune(0x22d1), true } case 'T': switch name { - case "THORN": // LATIN CAPITAL LETTER THORN - return rune(0xde), true - case "THgr": // GREEK CAPITAL LETTER THETA - return rune(0x0398), true - case "TRADE": // TRADE MARK SIGN - return rune(0x2122), true - case "TSHcy": // CYRILLIC CAPITAL LETTER TSHE - return rune(0x040b), true - case "TScy": // CYRILLIC CAPITAL LETTER TSE - return rune(0x0426), true - case "Tab": // CHARACTER TABULATION - return rune(0x09), true - case "Tau": // GREEK CAPITAL LETTER TAU - return rune(0x03a4), true - case "Tcaron": // LATIN CAPITAL LETTER T WITH CARON - return rune(0x0164), true - case "Tcedil": // LATIN CAPITAL LETTER T WITH CEDILLA - return rune(0x0162), true - case "Tcy": // CYRILLIC CAPITAL LETTER TE - return rune(0x0422), true - case "Tfr": // MATHEMATICAL FRAKTUR CAPITAL T - return rune(0x01d517), true - case "Tgr": // GREEK CAPITAL LETTER TAU - return rune(0x03a4), true - case "Therefore": // THEREFORE - return rune(0x2234), true - case "Theta": // GREEK CAPITAL LETTER THETA - return rune(0x0398), true - case "Thetav": // GREEK CAPITAL THETA SYMBOL - return rune(0x03f4), true - case "ThickSpace": // space of width 5/18 em - return rune(0x205f), true - case "ThinSpace": // THIN SPACE - return rune(0x2009), true - case "Tilde": // TILDE OPERATOR - return rune(0x223c), true - case "TildeEqual": // ASYMPTOTICALLY EQUAL TO - return rune(0x2243), true - case "TildeFullEqual": // APPROXIMATELY EQUAL TO - return rune(0x2245), true - case "TildeTilde": // ALMOST EQUAL TO - return rune(0x2248), true - case "Topf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL T - return rune(0x01d54b), true - case "TripleDot": // COMBINING THREE DOTS ABOVE - return rune(0x20db), true - case "Tscr": // MATHEMATICAL SCRIPT CAPITAL T - return rune(0x01d4af), true - case "Tstrok": // LATIN CAPITAL LETTER T WITH STROKE - return rune(0x0166), true + case "THORN": // LATIN CAPITAL LETTER THORN + return rune(0xde), true + case "THgr": // GREEK CAPITAL LETTER THETA + return rune(0x0398), true + case "TRADE": // TRADE MARK SIGN + return rune(0x2122), true + case "TSHcy": // CYRILLIC CAPITAL LETTER TSHE + return rune(0x040b), true + case "TScy": // CYRILLIC CAPITAL LETTER TSE + return rune(0x0426), true + case "Tab": // CHARACTER TABULATION + return rune(0x09), true + case "Tau": // GREEK CAPITAL LETTER TAU + return rune(0x03a4), true + case "Tcaron": // LATIN CAPITAL LETTER T WITH CARON + return rune(0x0164), true + case "Tcedil": // LATIN CAPITAL LETTER T WITH CEDILLA + return rune(0x0162), true + case "Tcy": // CYRILLIC CAPITAL LETTER TE + return rune(0x0422), true + case "Tfr": // MATHEMATICAL FRAKTUR CAPITAL T + return rune(0x01d517), true + case "Tgr": // GREEK CAPITAL LETTER TAU + return rune(0x03a4), true + case "Therefore": // THEREFORE + return rune(0x2234), true + case "Theta": // GREEK CAPITAL LETTER THETA + return rune(0x0398), true + case "Thetav": // GREEK CAPITAL THETA SYMBOL + return rune(0x03f4), true + case "ThickSpace": // space of width 5/18 em + return rune(0x205f), true + case "ThinSpace": // THIN SPACE + return rune(0x2009), true + case "Tilde": // TILDE OPERATOR + return rune(0x223c), true + case "TildeEqual": // ASYMPTOTICALLY EQUAL TO + return rune(0x2243), true + case "TildeFullEqual": // APPROXIMATELY EQUAL TO + return rune(0x2245), true + case "TildeTilde": // ALMOST EQUAL TO + return rune(0x2248), true + case "Topf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL T + return rune(0x01d54b), true + case "TripleDot": // COMBINING THREE DOTS ABOVE + return rune(0x20db), true + case "Tscr": // MATHEMATICAL SCRIPT CAPITAL T + return rune(0x01d4af), true + case "Tstrok": // LATIN CAPITAL LETTER T WITH STROKE + return rune(0x0166), true } case 'U': switch name { - case "Uacgr": // GREEK CAPITAL LETTER UPSILON WITH TONOS - return rune(0x038e), true - case "Uacute": // LATIN CAPITAL LETTER U WITH ACUTE - return rune(0xda), true - case "Uarr": // UPWARDS TWO HEADED ARROW - return rune(0x219f), true - case "Uarrocir": // UPWARDS TWO-HEADED ARROW FROM SMALL CIRCLE - return rune(0x2949), true - case "Ubrcy": // CYRILLIC CAPITAL LETTER SHORT U - return rune(0x040e), true - case "Ubreve": // LATIN CAPITAL LETTER U WITH BREVE - return rune(0x016c), true - case "Ucirc": // LATIN CAPITAL LETTER U WITH CIRCUMFLEX - return rune(0xdb), true - case "Ucy": // CYRILLIC CAPITAL LETTER U - return rune(0x0423), true - case "Udblac": // LATIN CAPITAL LETTER U WITH DOUBLE ACUTE - return rune(0x0170), true - case "Udigr": // GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA - return rune(0x03ab), true - case "Ufr": // MATHEMATICAL FRAKTUR CAPITAL U - return rune(0x01d518), true - case "Ugr": // GREEK CAPITAL LETTER UPSILON - return rune(0x03a5), true - case "Ugrave": // LATIN CAPITAL LETTER U WITH GRAVE - return rune(0xd9), true - case "Umacr": // LATIN CAPITAL LETTER U WITH MACRON - return rune(0x016a), true - case "UnderBar": // LOW LINE - return rune(0x5f), true - case "UnderBrace": // BOTTOM CURLY BRACKET - return rune(0x23df), true - case "UnderBracket": // BOTTOM SQUARE BRACKET - return rune(0x23b5), true - case "UnderParenthesis": // BOTTOM PARENTHESIS - return rune(0x23dd), true - case "Union": // N-ARY UNION - return rune(0x22c3), true - case "UnionPlus": // MULTISET UNION - return rune(0x228e), true - case "Uogon": // LATIN CAPITAL LETTER U WITH OGONEK - return rune(0x0172), true - case "Uopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL U - return rune(0x01d54c), true - case "UpArrow": // UPWARDS ARROW - return rune(0x2191), true - case "UpArrowBar": // UPWARDS ARROW TO BAR - return rune(0x2912), true - case "UpArrowDownArrow": // UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW - return rune(0x21c5), true - case "UpDownArrow": // UP DOWN ARROW - return rune(0x2195), true - case "UpEquilibrium": // UPWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT - return rune(0x296e), true - case "UpTee": // UP TACK - return rune(0x22a5), true - case "UpTeeArrow": // UPWARDS ARROW FROM BAR - return rune(0x21a5), true - case "Uparrow": // UPWARDS DOUBLE ARROW - return rune(0x21d1), true - case "Updownarrow": // UP DOWN DOUBLE ARROW - return rune(0x21d5), true - case "UpperLeftArrow": // NORTH WEST ARROW - return rune(0x2196), true - case "UpperRightArrow": // NORTH EAST ARROW - return rune(0x2197), true - case "Upsi": // GREEK UPSILON WITH HOOK SYMBOL - return rune(0x03d2), true - case "Upsilon": // GREEK CAPITAL LETTER UPSILON - return rune(0x03a5), true - case "Uring": // LATIN CAPITAL LETTER U WITH RING ABOVE - return rune(0x016e), true - case "Uscr": // MATHEMATICAL SCRIPT CAPITAL U - return rune(0x01d4b0), true - case "Utilde": // LATIN CAPITAL LETTER U WITH TILDE - return rune(0x0168), true - case "Uuml": // LATIN CAPITAL LETTER U WITH DIAERESIS - return rune(0xdc), true + case "Uacgr": // GREEK CAPITAL LETTER UPSILON WITH TONOS + return rune(0x038e), true + case "Uacute": // LATIN CAPITAL LETTER U WITH ACUTE + return rune(0xda), true + case "Uarr": // UPWARDS TWO HEADED ARROW + return rune(0x219f), true + case "Uarrocir": // UPWARDS TWO-HEADED ARROW FROM SMALL CIRCLE + return rune(0x2949), true + case "Ubrcy": // CYRILLIC CAPITAL LETTER SHORT U + return rune(0x040e), true + case "Ubreve": // LATIN CAPITAL LETTER U WITH BREVE + return rune(0x016c), true + case "Ucirc": // LATIN CAPITAL LETTER U WITH CIRCUMFLEX + return rune(0xdb), true + case "Ucy": // CYRILLIC CAPITAL LETTER U + return rune(0x0423), true + case "Udblac": // LATIN CAPITAL LETTER U WITH DOUBLE ACUTE + return rune(0x0170), true + case "Udigr": // GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA + return rune(0x03ab), true + case "Ufr": // MATHEMATICAL FRAKTUR CAPITAL U + return rune(0x01d518), true + case "Ugr": // GREEK CAPITAL LETTER UPSILON + return rune(0x03a5), true + case "Ugrave": // LATIN CAPITAL LETTER U WITH GRAVE + return rune(0xd9), true + case "Umacr": // LATIN CAPITAL LETTER U WITH MACRON + return rune(0x016a), true + case "UnderBar": // LOW LINE + return rune(0x5f), true + case "UnderBrace": // BOTTOM CURLY BRACKET + return rune(0x23df), true + case "UnderBracket": // BOTTOM SQUARE BRACKET + return rune(0x23b5), true + case "UnderParenthesis": // BOTTOM PARENTHESIS + return rune(0x23dd), true + case "Union": // N-ARY UNION + return rune(0x22c3), true + case "UnionPlus": // MULTISET UNION + return rune(0x228e), true + case "Uogon": // LATIN CAPITAL LETTER U WITH OGONEK + return rune(0x0172), true + case "Uopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL U + return rune(0x01d54c), true + case "UpArrow": // UPWARDS ARROW + return rune(0x2191), true + case "UpArrowBar": // UPWARDS ARROW TO BAR + return rune(0x2912), true + case "UpArrowDownArrow": // UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW + return rune(0x21c5), true + case "UpDownArrow": // UP DOWN ARROW + return rune(0x2195), true + case "UpEquilibrium": // UPWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT + return rune(0x296e), true + case "UpTee": // UP TACK + return rune(0x22a5), true + case "UpTeeArrow": // UPWARDS ARROW FROM BAR + return rune(0x21a5), true + case "Uparrow": // UPWARDS DOUBLE ARROW + return rune(0x21d1), true + case "Updownarrow": // UP DOWN DOUBLE ARROW + return rune(0x21d5), true + case "UpperLeftArrow": // NORTH WEST ARROW + return rune(0x2196), true + case "UpperRightArrow": // NORTH EAST ARROW + return rune(0x2197), true + case "Upsi": // GREEK UPSILON WITH HOOK SYMBOL + return rune(0x03d2), true + case "Upsilon": // GREEK CAPITAL LETTER UPSILON + return rune(0x03a5), true + case "Uring": // LATIN CAPITAL LETTER U WITH RING ABOVE + return rune(0x016e), true + case "Uscr": // MATHEMATICAL SCRIPT CAPITAL U + return rune(0x01d4b0), true + case "Utilde": // LATIN CAPITAL LETTER U WITH TILDE + return rune(0x0168), true + case "Uuml": // LATIN CAPITAL LETTER U WITH DIAERESIS + return rune(0xdc), true } case 'V': switch name { - case "VDash": // DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE - return rune(0x22ab), true - case "Vbar": // DOUBLE UP TACK - return rune(0x2aeb), true - case "Vcy": // CYRILLIC CAPITAL LETTER VE - return rune(0x0412), true - case "Vdash": // FORCES - return rune(0x22a9), true - case "Vdashl": // LONG DASH FROM LEFT MEMBER OF DOUBLE VERTICAL - return rune(0x2ae6), true - case "Vee": // N-ARY LOGICAL OR - return rune(0x22c1), true - case "Verbar": // DOUBLE VERTICAL LINE - return rune(0x2016), true - case "Vert": // DOUBLE VERTICAL LINE - return rune(0x2016), true - case "VerticalBar": // DIVIDES - return rune(0x2223), true - case "VerticalLine": // VERTICAL LINE - return rune(0x7c), true - case "VerticalSeparator": // LIGHT VERTICAL BAR - return rune(0x2758), true - case "VerticalTilde": // WREATH PRODUCT - return rune(0x2240), true - case "VeryThinSpace": // HAIR SPACE - return rune(0x200a), true - case "Vfr": // MATHEMATICAL FRAKTUR CAPITAL V - return rune(0x01d519), true - case "Vopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL V - return rune(0x01d54d), true - case "Vscr": // MATHEMATICAL SCRIPT CAPITAL V - return rune(0x01d4b1), true - case "Vvdash": // TRIPLE VERTICAL BAR RIGHT TURNSTILE - return rune(0x22aa), true + case "VDash": // DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE + return rune(0x22ab), true + case "Vbar": // DOUBLE UP TACK + return rune(0x2aeb), true + case "Vcy": // CYRILLIC CAPITAL LETTER VE + return rune(0x0412), true + case "Vdash": // FORCES + return rune(0x22a9), true + case "Vdashl": // LONG DASH FROM LEFT MEMBER OF DOUBLE VERTICAL + return rune(0x2ae6), true + case "Vee": // N-ARY LOGICAL OR + return rune(0x22c1), true + case "Verbar": // DOUBLE VERTICAL LINE + return rune(0x2016), true + case "Vert": // DOUBLE VERTICAL LINE + return rune(0x2016), true + case "VerticalBar": // DIVIDES + return rune(0x2223), true + case "VerticalLine": // VERTICAL LINE + return rune(0x7c), true + case "VerticalSeparator": // LIGHT VERTICAL BAR + return rune(0x2758), true + case "VerticalTilde": // WREATH PRODUCT + return rune(0x2240), true + case "VeryThinSpace": // HAIR SPACE + return rune(0x200a), true + case "Vfr": // MATHEMATICAL FRAKTUR CAPITAL V + return rune(0x01d519), true + case "Vopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL V + return rune(0x01d54d), true + case "Vscr": // MATHEMATICAL SCRIPT CAPITAL V + return rune(0x01d4b1), true + case "Vvdash": // TRIPLE VERTICAL BAR RIGHT TURNSTILE + return rune(0x22aa), true } case 'W': switch name { - case "Wcirc": // LATIN CAPITAL LETTER W WITH CIRCUMFLEX - return rune(0x0174), true - case "Wedge": // N-ARY LOGICAL AND - return rune(0x22c0), true - case "Wfr": // MATHEMATICAL FRAKTUR CAPITAL W - return rune(0x01d51a), true - case "Wopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL W - return rune(0x01d54e), true - case "Wscr": // MATHEMATICAL SCRIPT CAPITAL W - return rune(0x01d4b2), true + case "Wcirc": // LATIN CAPITAL LETTER W WITH CIRCUMFLEX + return rune(0x0174), true + case "Wedge": // N-ARY LOGICAL AND + return rune(0x22c0), true + case "Wfr": // MATHEMATICAL FRAKTUR CAPITAL W + return rune(0x01d51a), true + case "Wopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL W + return rune(0x01d54e), true + case "Wscr": // MATHEMATICAL SCRIPT CAPITAL W + return rune(0x01d4b2), true } case 'X': switch name { - case "Xfr": // MATHEMATICAL FRAKTUR CAPITAL X - return rune(0x01d51b), true - case "Xgr": // GREEK CAPITAL LETTER XI - return rune(0x039e), true - case "Xi": // GREEK CAPITAL LETTER XI - return rune(0x039e), true - case "Xopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL X - return rune(0x01d54f), true - case "Xscr": // MATHEMATICAL SCRIPT CAPITAL X - return rune(0x01d4b3), true + case "Xfr": // MATHEMATICAL FRAKTUR CAPITAL X + return rune(0x01d51b), true + case "Xgr": // GREEK CAPITAL LETTER XI + return rune(0x039e), true + case "Xi": // GREEK CAPITAL LETTER XI + return rune(0x039e), true + case "Xopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL X + return rune(0x01d54f), true + case "Xscr": // MATHEMATICAL SCRIPT CAPITAL X + return rune(0x01d4b3), true } case 'Y': switch name { - case "YAcy": // CYRILLIC CAPITAL LETTER YA - return rune(0x042f), true - case "YIcy": // CYRILLIC CAPITAL LETTER YI - return rune(0x0407), true - case "YUcy": // CYRILLIC CAPITAL LETTER YU - return rune(0x042e), true - case "Yacute": // LATIN CAPITAL LETTER Y WITH ACUTE - return rune(0xdd), true - case "Ycirc": // LATIN CAPITAL LETTER Y WITH CIRCUMFLEX - return rune(0x0176), true - case "Ycy": // CYRILLIC CAPITAL LETTER YERU - return rune(0x042b), true - case "Yfr": // MATHEMATICAL FRAKTUR CAPITAL Y - return rune(0x01d51c), true - case "Yopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL Y - return rune(0x01d550), true - case "Yscr": // MATHEMATICAL SCRIPT CAPITAL Y - return rune(0x01d4b4), true - case "Yuml": // LATIN CAPITAL LETTER Y WITH DIAERESIS - return rune(0x0178), true + case "YAcy": // CYRILLIC CAPITAL LETTER YA + return rune(0x042f), true + case "YIcy": // CYRILLIC CAPITAL LETTER YI + return rune(0x0407), true + case "YUcy": // CYRILLIC CAPITAL LETTER YU + return rune(0x042e), true + case "Yacute": // LATIN CAPITAL LETTER Y WITH ACUTE + return rune(0xdd), true + case "Ycirc": // LATIN CAPITAL LETTER Y WITH CIRCUMFLEX + return rune(0x0176), true + case "Ycy": // CYRILLIC CAPITAL LETTER YERU + return rune(0x042b), true + case "Yfr": // MATHEMATICAL FRAKTUR CAPITAL Y + return rune(0x01d51c), true + case "Yopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL Y + return rune(0x01d550), true + case "Yscr": // MATHEMATICAL SCRIPT CAPITAL Y + return rune(0x01d4b4), true + case "Yuml": // LATIN CAPITAL LETTER Y WITH DIAERESIS + return rune(0x0178), true } case 'Z': switch name { - case "ZHcy": // CYRILLIC CAPITAL LETTER ZHE - return rune(0x0416), true - case "Zacute": // LATIN CAPITAL LETTER Z WITH ACUTE - return rune(0x0179), true - case "Zcaron": // LATIN CAPITAL LETTER Z WITH CARON - return rune(0x017d), true - case "Zcy": // CYRILLIC CAPITAL LETTER ZE - return rune(0x0417), true - case "Zdot": // LATIN CAPITAL LETTER Z WITH DOT ABOVE - return rune(0x017b), true - case "ZeroWidthSpace": // ZERO WIDTH SPACE - return rune(0x200b), true - case "Zeta": // GREEK CAPITAL LETTER ZETA - return rune(0x0396), true - case "Zfr": // BLACK-LETTER CAPITAL Z - return rune(0x2128), true - case "Zgr": // GREEK CAPITAL LETTER ZETA - return rune(0x0396), true - case "Zopf": // DOUBLE-STRUCK CAPITAL Z - return rune(0x2124), true - case "Zscr": // MATHEMATICAL SCRIPT CAPITAL Z - return rune(0x01d4b5), true + case "ZHcy": // CYRILLIC CAPITAL LETTER ZHE + return rune(0x0416), true + case "Zacute": // LATIN CAPITAL LETTER Z WITH ACUTE + return rune(0x0179), true + case "Zcaron": // LATIN CAPITAL LETTER Z WITH CARON + return rune(0x017d), true + case "Zcy": // CYRILLIC CAPITAL LETTER ZE + return rune(0x0417), true + case "Zdot": // LATIN CAPITAL LETTER Z WITH DOT ABOVE + return rune(0x017b), true + case "ZeroWidthSpace": // ZERO WIDTH SPACE + return rune(0x200b), true + case "Zeta": // GREEK CAPITAL LETTER ZETA + return rune(0x0396), true + case "Zfr": // BLACK-LETTER CAPITAL Z + return rune(0x2128), true + case "Zgr": // GREEK CAPITAL LETTER ZETA + return rune(0x0396), true + case "Zopf": // DOUBLE-STRUCK CAPITAL Z + return rune(0x2124), true + case "Zscr": // MATHEMATICAL SCRIPT CAPITAL Z + return rune(0x01d4b5), true } case 'a': switch name { - case "aacgr": // GREEK SMALL LETTER ALPHA WITH TONOS - return rune(0x03ac), true - case "aacute": // LATIN SMALL LETTER A WITH ACUTE - return rune(0xe1), true - case "abreve": // LATIN SMALL LETTER A WITH BREVE - return rune(0x0103), true - case "ac": // INVERTED LAZY S - return rune(0x223e), true - case "acE": // INVERTED LAZY S with double underline - return rune(0x223e), true - case "acd": // SINE WAVE - return rune(0x223f), true - case "acirc": // LATIN SMALL LETTER A WITH CIRCUMFLEX - return rune(0xe2), true - case "actuary": // COMBINING ANNUITY SYMBOL - return rune(0x20e7), true - case "acute": // ACUTE ACCENT - return rune(0xb4), true - case "acy": // CYRILLIC SMALL LETTER A - return rune(0x0430), true - case "aelig": // LATIN SMALL LETTER AE - return rune(0xe6), true - case "af": // FUNCTION APPLICATION - return rune(0x2061), true - case "afr": // MATHEMATICAL FRAKTUR SMALL A - return rune(0x01d51e), true - case "agr": // GREEK SMALL LETTER ALPHA - return rune(0x03b1), true - case "agrave": // LATIN SMALL LETTER A WITH GRAVE - return rune(0xe0), true - case "alefsym": // ALEF SYMBOL - return rune(0x2135), true - case "aleph": // ALEF SYMBOL - return rune(0x2135), true - case "alpha": // GREEK SMALL LETTER ALPHA - return rune(0x03b1), true - case "amacr": // LATIN SMALL LETTER A WITH MACRON - return rune(0x0101), true - case "amalg": // AMALGAMATION OR COPRODUCT - return rune(0x2a3f), true - case "amp": // AMPERSAND - return rune(0x26), true - case "and": // LOGICAL AND - return rune(0x2227), true - case "andand": // TWO INTERSECTING LOGICAL AND - return rune(0x2a55), true - case "andd": // LOGICAL AND WITH HORIZONTAL DASH - return rune(0x2a5c), true - case "andslope": // SLOPING LARGE AND - return rune(0x2a58), true - case "andv": // LOGICAL AND WITH MIDDLE STEM - return rune(0x2a5a), true - case "ang": // ANGLE - return rune(0x2220), true - case "ang90": // RIGHT ANGLE - return rune(0x221f), true - case "angdnl": // TURNED ANGLE - return rune(0x29a2), true - case "angdnr": // ACUTE ANGLE - return rune(0x299f), true - case "ange": // ANGLE WITH UNDERBAR - return rune(0x29a4), true - case "angle": // ANGLE - return rune(0x2220), true - case "angles": // ANGLE WITH S INSIDE - return rune(0x299e), true - case "angmsd": // MEASURED ANGLE - return rune(0x2221), true - case "angmsdaa": // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND RIGHT - return rune(0x29a8), true - case "angmsdab": // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND LEFT - return rune(0x29a9), true - case "angmsdac": // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND RIGHT - return rune(0x29aa), true - case "angmsdad": // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND LEFT - return rune(0x29ab), true - case "angmsdae": // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND UP - return rune(0x29ac), true - case "angmsdaf": // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND UP - return rune(0x29ad), true - case "angmsdag": // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND DOWN - return rune(0x29ae), true - case "angmsdah": // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND DOWN - return rune(0x29af), true - case "angrt": // RIGHT ANGLE - return rune(0x221f), true - case "angrtvb": // RIGHT ANGLE WITH ARC - return rune(0x22be), true - case "angrtvbd": // MEASURED RIGHT ANGLE WITH DOT - return rune(0x299d), true - case "angsph": // SPHERICAL ANGLE - return rune(0x2222), true - case "angst": // LATIN CAPITAL LETTER A WITH RING ABOVE - return rune(0xc5), true - case "angupl": // REVERSED ANGLE - return rune(0x29a3), true - case "angzarr": // RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW - return rune(0x237c), true - case "aogon": // LATIN SMALL LETTER A WITH OGONEK - return rune(0x0105), true - case "aopf": // MATHEMATICAL DOUBLE-STRUCK SMALL A - return rune(0x01d552), true - case "ap": // ALMOST EQUAL TO - return rune(0x2248), true - case "apE": // APPROXIMATELY EQUAL OR EQUAL TO - return rune(0x2a70), true - case "apacir": // ALMOST EQUAL TO WITH CIRCUMFLEX ACCENT - return rune(0x2a6f), true - case "ape": // ALMOST EQUAL OR EQUAL TO - return rune(0x224a), true - case "apid": // TRIPLE TILDE - return rune(0x224b), true - case "apos": // APOSTROPHE - return rune(0x27), true - case "approx": // ALMOST EQUAL TO - return rune(0x2248), true - case "approxeq": // ALMOST EQUAL OR EQUAL TO - return rune(0x224a), true - case "aring": // LATIN SMALL LETTER A WITH RING ABOVE - return rune(0xe5), true - case "arrllsr": // LEFTWARDS ARROW ABOVE SHORT RIGHTWARDS ARROW - return rune(0x2943), true - case "arrlrsl": // RIGHTWARDS ARROW ABOVE SHORT LEFTWARDS ARROW - return rune(0x2942), true - case "arrsrll": // SHORT RIGHTWARDS ARROW ABOVE LEFTWARDS ARROW - return rune(0x2944), true - case "ascr": // MATHEMATICAL SCRIPT SMALL A - return rune(0x01d4b6), true - case "ast": // ASTERISK - return rune(0x2a), true - case "astb": // SQUARED ASTERISK - return rune(0x29c6), true - case "asymp": // ALMOST EQUAL TO - return rune(0x2248), true - case "asympeq": // EQUIVALENT TO - return rune(0x224d), true - case "atilde": // LATIN SMALL LETTER A WITH TILDE - return rune(0xe3), true - case "auml": // LATIN SMALL LETTER A WITH DIAERESIS - return rune(0xe4), true - case "awconint": // ANTICLOCKWISE CONTOUR INTEGRAL - return rune(0x2233), true - case "awint": // ANTICLOCKWISE INTEGRATION - return rune(0x2a11), true + case "aacgr": // GREEK SMALL LETTER ALPHA WITH TONOS + return rune(0x03ac), true + case "aacute": // LATIN SMALL LETTER A WITH ACUTE + return rune(0xe1), true + case "abreve": // LATIN SMALL LETTER A WITH BREVE + return rune(0x0103), true + case "ac": // INVERTED LAZY S + return rune(0x223e), true + case "acE": // INVERTED LAZY S with double underline + return rune(0x223e), true + case "acd": // SINE WAVE + return rune(0x223f), true + case "acirc": // LATIN SMALL LETTER A WITH CIRCUMFLEX + return rune(0xe2), true + case "actuary": // COMBINING ANNUITY SYMBOL + return rune(0x20e7), true + case "acute": // ACUTE ACCENT + return rune(0xb4), true + case "acy": // CYRILLIC SMALL LETTER A + return rune(0x0430), true + case "aelig": // LATIN SMALL LETTER AE + return rune(0xe6), true + case "af": // FUNCTION APPLICATION + return rune(0x2061), true + case "afr": // MATHEMATICAL FRAKTUR SMALL A + return rune(0x01d51e), true + case "agr": // GREEK SMALL LETTER ALPHA + return rune(0x03b1), true + case "agrave": // LATIN SMALL LETTER A WITH GRAVE + return rune(0xe0), true + case "alefsym": // ALEF SYMBOL + return rune(0x2135), true + case "aleph": // ALEF SYMBOL + return rune(0x2135), true + case "alpha": // GREEK SMALL LETTER ALPHA + return rune(0x03b1), true + case "amacr": // LATIN SMALL LETTER A WITH MACRON + return rune(0x0101), true + case "amalg": // AMALGAMATION OR COPRODUCT + return rune(0x2a3f), true + case "amp": // AMPERSAND + return rune(0x26), true + case "and": // LOGICAL AND + return rune(0x2227), true + case "andand": // TWO INTERSECTING LOGICAL AND + return rune(0x2a55), true + case "andd": // LOGICAL AND WITH HORIZONTAL DASH + return rune(0x2a5c), true + case "andslope": // SLOPING LARGE AND + return rune(0x2a58), true + case "andv": // LOGICAL AND WITH MIDDLE STEM + return rune(0x2a5a), true + case "ang": // ANGLE + return rune(0x2220), true + case "ang90": // RIGHT ANGLE + return rune(0x221f), true + case "angdnl": // TURNED ANGLE + return rune(0x29a2), true + case "angdnr": // ACUTE ANGLE + return rune(0x299f), true + case "ange": // ANGLE WITH UNDERBAR + return rune(0x29a4), true + case "angle": // ANGLE + return rune(0x2220), true + case "angles": // ANGLE WITH S INSIDE + return rune(0x299e), true + case "angmsd": // MEASURED ANGLE + return rune(0x2221), true + case "angmsdaa": // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND RIGHT + return rune(0x29a8), true + case "angmsdab": // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND LEFT + return rune(0x29a9), true + case "angmsdac": // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND RIGHT + return rune(0x29aa), true + case "angmsdad": // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND LEFT + return rune(0x29ab), true + case "angmsdae": // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND UP + return rune(0x29ac), true + case "angmsdaf": // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND UP + return rune(0x29ad), true + case "angmsdag": // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND DOWN + return rune(0x29ae), true + case "angmsdah": // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND DOWN + return rune(0x29af), true + case "angrt": // RIGHT ANGLE + return rune(0x221f), true + case "angrtvb": // RIGHT ANGLE WITH ARC + return rune(0x22be), true + case "angrtvbd": // MEASURED RIGHT ANGLE WITH DOT + return rune(0x299d), true + case "angsph": // SPHERICAL ANGLE + return rune(0x2222), true + case "angst": // LATIN CAPITAL LETTER A WITH RING ABOVE + return rune(0xc5), true + case "angupl": // REVERSED ANGLE + return rune(0x29a3), true + case "angzarr": // RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW + return rune(0x237c), true + case "aogon": // LATIN SMALL LETTER A WITH OGONEK + return rune(0x0105), true + case "aopf": // MATHEMATICAL DOUBLE-STRUCK SMALL A + return rune(0x01d552), true + case "ap": // ALMOST EQUAL TO + return rune(0x2248), true + case "apE": // APPROXIMATELY EQUAL OR EQUAL TO + return rune(0x2a70), true + case "apacir": // ALMOST EQUAL TO WITH CIRCUMFLEX ACCENT + return rune(0x2a6f), true + case "ape": // ALMOST EQUAL OR EQUAL TO + return rune(0x224a), true + case "apid": // TRIPLE TILDE + return rune(0x224b), true + case "apos": // APOSTROPHE + return rune(0x27), true + case "approx": // ALMOST EQUAL TO + return rune(0x2248), true + case "approxeq": // ALMOST EQUAL OR EQUAL TO + return rune(0x224a), true + case "aring": // LATIN SMALL LETTER A WITH RING ABOVE + return rune(0xe5), true + case "arrllsr": // LEFTWARDS ARROW ABOVE SHORT RIGHTWARDS ARROW + return rune(0x2943), true + case "arrlrsl": // RIGHTWARDS ARROW ABOVE SHORT LEFTWARDS ARROW + return rune(0x2942), true + case "arrsrll": // SHORT RIGHTWARDS ARROW ABOVE LEFTWARDS ARROW + return rune(0x2944), true + case "ascr": // MATHEMATICAL SCRIPT SMALL A + return rune(0x01d4b6), true + case "ast": // ASTERISK + return rune(0x2a), true + case "astb": // SQUARED ASTERISK + return rune(0x29c6), true + case "asymp": // ALMOST EQUAL TO + return rune(0x2248), true + case "asympeq": // EQUIVALENT TO + return rune(0x224d), true + case "atilde": // LATIN SMALL LETTER A WITH TILDE + return rune(0xe3), true + case "auml": // LATIN SMALL LETTER A WITH DIAERESIS + return rune(0xe4), true + case "awconint": // ANTICLOCKWISE CONTOUR INTEGRAL + return rune(0x2233), true + case "awint": // ANTICLOCKWISE INTEGRATION + return rune(0x2a11), true } case 'b': switch name { - case "b.Delta": // MATHEMATICAL BOLD CAPITAL DELTA - return rune(0x01d6ab), true - case "b.Gamma": // MATHEMATICAL BOLD CAPITAL GAMMA - return rune(0x01d6aa), true - case "b.Gammad": // MATHEMATICAL BOLD CAPITAL DIGAMMA - return rune(0x01d7ca), true - case "b.Lambda": // MATHEMATICAL BOLD CAPITAL LAMDA - return rune(0x01d6b2), true - case "b.Omega": // MATHEMATICAL BOLD CAPITAL OMEGA - return rune(0x01d6c0), true - case "b.Phi": // MATHEMATICAL BOLD CAPITAL PHI - return rune(0x01d6bd), true - case "b.Pi": // MATHEMATICAL BOLD CAPITAL PI - return rune(0x01d6b7), true - case "b.Psi": // MATHEMATICAL BOLD CAPITAL PSI - return rune(0x01d6bf), true - case "b.Sigma": // MATHEMATICAL BOLD CAPITAL SIGMA - return rune(0x01d6ba), true - case "b.Theta": // MATHEMATICAL BOLD CAPITAL THETA - return rune(0x01d6af), true - case "b.Upsi": // MATHEMATICAL BOLD CAPITAL UPSILON - return rune(0x01d6bc), true - case "b.Xi": // MATHEMATICAL BOLD CAPITAL XI - return rune(0x01d6b5), true - case "b.alpha": // MATHEMATICAL BOLD SMALL ALPHA - return rune(0x01d6c2), true - case "b.beta": // MATHEMATICAL BOLD SMALL BETA - return rune(0x01d6c3), true - case "b.chi": // MATHEMATICAL BOLD SMALL CHI - return rune(0x01d6d8), true - case "b.delta": // MATHEMATICAL BOLD SMALL DELTA - return rune(0x01d6c5), true - case "b.epsi": // MATHEMATICAL BOLD SMALL EPSILON - return rune(0x01d6c6), true - case "b.epsiv": // MATHEMATICAL BOLD EPSILON SYMBOL - return rune(0x01d6dc), true - case "b.eta": // MATHEMATICAL BOLD SMALL ETA - return rune(0x01d6c8), true - case "b.gamma": // MATHEMATICAL BOLD SMALL GAMMA - return rune(0x01d6c4), true - case "b.gammad": // MATHEMATICAL BOLD SMALL DIGAMMA - return rune(0x01d7cb), true - case "b.iota": // MATHEMATICAL BOLD SMALL IOTA - return rune(0x01d6ca), true - case "b.kappa": // MATHEMATICAL BOLD SMALL KAPPA - return rune(0x01d6cb), true - case "b.kappav": // MATHEMATICAL BOLD KAPPA SYMBOL - return rune(0x01d6de), true - case "b.lambda": // MATHEMATICAL BOLD SMALL LAMDA - return rune(0x01d6cc), true - case "b.mu": // MATHEMATICAL BOLD SMALL MU - return rune(0x01d6cd), true - case "b.nu": // MATHEMATICAL BOLD SMALL NU - return rune(0x01d6ce), true - case "b.omega": // MATHEMATICAL BOLD SMALL OMEGA - return rune(0x01d6da), true - case "b.phi": // MATHEMATICAL BOLD SMALL PHI - return rune(0x01d6d7), true - case "b.phiv": // MATHEMATICAL BOLD PHI SYMBOL - return rune(0x01d6df), true - case "b.pi": // MATHEMATICAL BOLD SMALL PI - return rune(0x01d6d1), true - case "b.piv": // MATHEMATICAL BOLD PI SYMBOL - return rune(0x01d6e1), true - case "b.psi": // MATHEMATICAL BOLD SMALL PSI - return rune(0x01d6d9), true - case "b.rho": // MATHEMATICAL BOLD SMALL RHO - return rune(0x01d6d2), true - case "b.rhov": // MATHEMATICAL BOLD RHO SYMBOL - return rune(0x01d6e0), true - case "b.sigma": // MATHEMATICAL BOLD SMALL SIGMA - return rune(0x01d6d4), true - case "b.sigmav": // MATHEMATICAL BOLD SMALL FINAL SIGMA - return rune(0x01d6d3), true - case "b.tau": // MATHEMATICAL BOLD SMALL TAU - return rune(0x01d6d5), true - case "b.thetas": // MATHEMATICAL BOLD SMALL THETA - return rune(0x01d6c9), true - case "b.thetav": // MATHEMATICAL BOLD THETA SYMBOL - return rune(0x01d6dd), true - case "b.upsi": // MATHEMATICAL BOLD SMALL UPSILON - return rune(0x01d6d6), true - case "b.xi": // MATHEMATICAL BOLD SMALL XI - return rune(0x01d6cf), true - case "b.zeta": // MATHEMATICAL BOLD SMALL ZETA - return rune(0x01d6c7), true - case "bNot": // REVERSED DOUBLE STROKE NOT SIGN - return rune(0x2aed), true - case "backcong": // ALL EQUAL TO - return rune(0x224c), true - case "backepsilon": // GREEK REVERSED LUNATE EPSILON SYMBOL - return rune(0x03f6), true - case "backprime": // REVERSED PRIME - return rune(0x2035), true - case "backsim": // REVERSED TILDE - return rune(0x223d), true - case "backsimeq": // REVERSED TILDE EQUALS - return rune(0x22cd), true - case "barV": // DOUBLE DOWN TACK - return rune(0x2aea), true - case "barvee": // NOR - return rune(0x22bd), true - case "barwed": // PROJECTIVE - return rune(0x2305), true - case "barwedge": // PROJECTIVE - return rune(0x2305), true - case "bbrk": // BOTTOM SQUARE BRACKET - return rune(0x23b5), true - case "bbrktbrk": // BOTTOM SQUARE BRACKET OVER TOP SQUARE BRACKET - return rune(0x23b6), true - case "bcong": // ALL EQUAL TO - return rune(0x224c), true - case "bcy": // CYRILLIC SMALL LETTER BE - return rune(0x0431), true - case "bdlhar": // DOWNWARDS HARPOON WITH BARB LEFT FROM BAR - return rune(0x2961), true - case "bdquo": // DOUBLE LOW-9 QUOTATION MARK - return rune(0x201e), true - case "bdrhar": // DOWNWARDS HARPOON WITH BARB RIGHT FROM BAR - return rune(0x295d), true - case "becaus": // BECAUSE - return rune(0x2235), true - case "because": // BECAUSE - return rune(0x2235), true - case "bemptyv": // REVERSED EMPTY SET - return rune(0x29b0), true - case "bepsi": // GREEK REVERSED LUNATE EPSILON SYMBOL - return rune(0x03f6), true - case "bernou": // SCRIPT CAPITAL B - return rune(0x212c), true - case "beta": // GREEK SMALL LETTER BETA - return rune(0x03b2), true - case "beth": // BET SYMBOL - return rune(0x2136), true - case "between": // BETWEEN - return rune(0x226c), true - case "bfr": // MATHEMATICAL FRAKTUR SMALL B - return rune(0x01d51f), true - case "bgr": // GREEK SMALL LETTER BETA - return rune(0x03b2), true - case "bigcap": // N-ARY INTERSECTION - return rune(0x22c2), true - case "bigcirc": // LARGE CIRCLE - return rune(0x25ef), true - case "bigcup": // N-ARY UNION - return rune(0x22c3), true - case "bigodot": // N-ARY CIRCLED DOT OPERATOR - return rune(0x2a00), true - case "bigoplus": // N-ARY CIRCLED PLUS OPERATOR - return rune(0x2a01), true - case "bigotimes": // N-ARY CIRCLED TIMES OPERATOR - return rune(0x2a02), true - case "bigsqcup": // N-ARY SQUARE UNION OPERATOR - return rune(0x2a06), true - case "bigstar": // BLACK STAR - return rune(0x2605), true - case "bigtriangledown": // WHITE DOWN-POINTING TRIANGLE - return rune(0x25bd), true - case "bigtriangleup": // WHITE UP-POINTING TRIANGLE - return rune(0x25b3), true - case "biguplus": // N-ARY UNION OPERATOR WITH PLUS - return rune(0x2a04), true - case "bigvee": // N-ARY LOGICAL OR - return rune(0x22c1), true - case "bigwedge": // N-ARY LOGICAL AND - return rune(0x22c0), true - case "bkarow": // RIGHTWARDS DOUBLE DASH ARROW - return rune(0x290d), true - case "blacklozenge": // BLACK LOZENGE - return rune(0x29eb), true - case "blacksquare": // BLACK SMALL SQUARE - return rune(0x25aa), true - case "blacktriangle": // BLACK UP-POINTING SMALL TRIANGLE - return rune(0x25b4), true - case "blacktriangledown": // BLACK DOWN-POINTING SMALL TRIANGLE - return rune(0x25be), true - case "blacktriangleleft": // BLACK LEFT-POINTING SMALL TRIANGLE - return rune(0x25c2), true - case "blacktriangleright": // BLACK RIGHT-POINTING SMALL TRIANGLE - return rune(0x25b8), true - case "blank": // BLANK SYMBOL - return rune(0x2422), true - case "bldhar": // LEFTWARDS HARPOON WITH BARB DOWN FROM BAR - return rune(0x295e), true - case "blk12": // MEDIUM SHADE - return rune(0x2592), true - case "blk14": // LIGHT SHADE - return rune(0x2591), true - case "blk34": // DARK SHADE - return rune(0x2593), true - case "block": // FULL BLOCK - return rune(0x2588), true - case "bluhar": // LEFTWARDS HARPOON WITH BARB UP FROM BAR - return rune(0x295a), true - case "bne": // EQUALS SIGN with reverse slash - return rune(0x3d), true - case "bnequiv": // IDENTICAL TO with reverse slash - return rune(0x2261), true - case "bnot": // REVERSED NOT SIGN - return rune(0x2310), true - case "bopf": // MATHEMATICAL DOUBLE-STRUCK SMALL B - return rune(0x01d553), true - case "bot": // UP TACK - return rune(0x22a5), true - case "bottom": // UP TACK - return rune(0x22a5), true - case "bowtie": // BOWTIE - return rune(0x22c8), true - case "boxDL": // BOX DRAWINGS DOUBLE DOWN AND LEFT - return rune(0x2557), true - case "boxDR": // BOX DRAWINGS DOUBLE DOWN AND RIGHT - return rune(0x2554), true - case "boxDl": // BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE - return rune(0x2556), true - case "boxDr": // BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE - return rune(0x2553), true - case "boxH": // BOX DRAWINGS DOUBLE HORIZONTAL - return rune(0x2550), true - case "boxHD": // BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - return rune(0x2566), true - case "boxHU": // BOX DRAWINGS DOUBLE UP AND HORIZONTAL - return rune(0x2569), true - case "boxHd": // BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE - return rune(0x2564), true - case "boxHu": // BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE - return rune(0x2567), true - case "boxUL": // BOX DRAWINGS DOUBLE UP AND LEFT - return rune(0x255d), true - case "boxUR": // BOX DRAWINGS DOUBLE UP AND RIGHT - return rune(0x255a), true - case "boxUl": // BOX DRAWINGS UP DOUBLE AND LEFT SINGLE - return rune(0x255c), true - case "boxUr": // BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE - return rune(0x2559), true - case "boxV": // BOX DRAWINGS DOUBLE VERTICAL - return rune(0x2551), true - case "boxVH": // BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - return rune(0x256c), true - case "boxVL": // BOX DRAWINGS DOUBLE VERTICAL AND LEFT - return rune(0x2563), true - case "boxVR": // BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - return rune(0x2560), true - case "boxVh": // BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE - return rune(0x256b), true - case "boxVl": // BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE - return rune(0x2562), true - case "boxVr": // BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE - return rune(0x255f), true - case "boxbox": // TWO JOINED SQUARES - return rune(0x29c9), true - case "boxdL": // BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE - return rune(0x2555), true - case "boxdR": // BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE - return rune(0x2552), true - case "boxdl": // BOX DRAWINGS LIGHT DOWN AND LEFT - return rune(0x2510), true - case "boxdr": // BOX DRAWINGS LIGHT DOWN AND RIGHT - return rune(0x250c), true - case "boxh": // BOX DRAWINGS LIGHT HORIZONTAL - return rune(0x2500), true - case "boxhD": // BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE - return rune(0x2565), true - case "boxhU": // BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE - return rune(0x2568), true - case "boxhd": // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - return rune(0x252c), true - case "boxhu": // BOX DRAWINGS LIGHT UP AND HORIZONTAL - return rune(0x2534), true - case "boxminus": // SQUARED MINUS - return rune(0x229f), true - case "boxplus": // SQUARED PLUS - return rune(0x229e), true - case "boxtimes": // SQUARED TIMES - return rune(0x22a0), true - case "boxuL": // BOX DRAWINGS UP SINGLE AND LEFT DOUBLE - return rune(0x255b), true - case "boxuR": // BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE - return rune(0x2558), true - case "boxul": // BOX DRAWINGS LIGHT UP AND LEFT - return rune(0x2518), true - case "boxur": // BOX DRAWINGS LIGHT UP AND RIGHT - return rune(0x2514), true - case "boxv": // BOX DRAWINGS LIGHT VERTICAL - return rune(0x2502), true - case "boxvH": // BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE - return rune(0x256a), true - case "boxvL": // BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE - return rune(0x2561), true - case "boxvR": // BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE - return rune(0x255e), true - case "boxvh": // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - return rune(0x253c), true - case "boxvl": // BOX DRAWINGS LIGHT VERTICAL AND LEFT - return rune(0x2524), true - case "boxvr": // BOX DRAWINGS LIGHT VERTICAL AND RIGHT - return rune(0x251c), true - case "bprime": // REVERSED PRIME - return rune(0x2035), true - case "brdhar": // RIGHTWARDS HARPOON WITH BARB DOWN FROM BAR - return rune(0x295f), true - case "breve": // BREVE - return rune(0x02d8), true - case "bruhar": // RIGHTWARDS HARPOON WITH BARB UP FROM BAR - return rune(0x295b), true - case "brvbar": // BROKEN BAR - return rune(0xa6), true - case "bscr": // MATHEMATICAL SCRIPT SMALL B - return rune(0x01d4b7), true - case "bsemi": // REVERSED SEMICOLON - return rune(0x204f), true - case "bsim": // REVERSED TILDE - return rune(0x223d), true - case "bsime": // REVERSED TILDE EQUALS - return rune(0x22cd), true - case "bsol": // REVERSE SOLIDUS - return rune(0x5c), true - case "bsolb": // SQUARED FALLING DIAGONAL SLASH - return rune(0x29c5), true - case "bsolhsub": // REVERSE SOLIDUS PRECEDING SUBSET - return rune(0x27c8), true - case "btimes": // SEMIDIRECT PRODUCT WITH BOTTOM CLOSED - return rune(0x2a32), true - case "bulhar": // UPWARDS HARPOON WITH BARB LEFT FROM BAR - return rune(0x2960), true - case "bull": // BULLET - return rune(0x2022), true - case "bullet": // BULLET - return rune(0x2022), true - case "bump": // GEOMETRICALLY EQUIVALENT TO - return rune(0x224e), true - case "bumpE": // EQUALS SIGN WITH BUMPY ABOVE - return rune(0x2aae), true - case "bumpe": // DIFFERENCE BETWEEN - return rune(0x224f), true - case "bumpeq": // DIFFERENCE BETWEEN - return rune(0x224f), true - case "burhar": // UPWARDS HARPOON WITH BARB RIGHT FROM BAR - return rune(0x295c), true + case "b.Delta": // MATHEMATICAL BOLD CAPITAL DELTA + return rune(0x01d6ab), true + case "b.Gamma": // MATHEMATICAL BOLD CAPITAL GAMMA + return rune(0x01d6aa), true + case "b.Gammad": // MATHEMATICAL BOLD CAPITAL DIGAMMA + return rune(0x01d7ca), true + case "b.Lambda": // MATHEMATICAL BOLD CAPITAL LAMDA + return rune(0x01d6b2), true + case "b.Omega": // MATHEMATICAL BOLD CAPITAL OMEGA + return rune(0x01d6c0), true + case "b.Phi": // MATHEMATICAL BOLD CAPITAL PHI + return rune(0x01d6bd), true + case "b.Pi": // MATHEMATICAL BOLD CAPITAL PI + return rune(0x01d6b7), true + case "b.Psi": // MATHEMATICAL BOLD CAPITAL PSI + return rune(0x01d6bf), true + case "b.Sigma": // MATHEMATICAL BOLD CAPITAL SIGMA + return rune(0x01d6ba), true + case "b.Theta": // MATHEMATICAL BOLD CAPITAL THETA + return rune(0x01d6af), true + case "b.Upsi": // MATHEMATICAL BOLD CAPITAL UPSILON + return rune(0x01d6bc), true + case "b.Xi": // MATHEMATICAL BOLD CAPITAL XI + return rune(0x01d6b5), true + case "b.alpha": // MATHEMATICAL BOLD SMALL ALPHA + return rune(0x01d6c2), true + case "b.beta": // MATHEMATICAL BOLD SMALL BETA + return rune(0x01d6c3), true + case "b.chi": // MATHEMATICAL BOLD SMALL CHI + return rune(0x01d6d8), true + case "b.delta": // MATHEMATICAL BOLD SMALL DELTA + return rune(0x01d6c5), true + case "b.epsi": // MATHEMATICAL BOLD SMALL EPSILON + return rune(0x01d6c6), true + case "b.epsiv": // MATHEMATICAL BOLD EPSILON SYMBOL + return rune(0x01d6dc), true + case "b.eta": // MATHEMATICAL BOLD SMALL ETA + return rune(0x01d6c8), true + case "b.gamma": // MATHEMATICAL BOLD SMALL GAMMA + return rune(0x01d6c4), true + case "b.gammad": // MATHEMATICAL BOLD SMALL DIGAMMA + return rune(0x01d7cb), true + case "b.iota": // MATHEMATICAL BOLD SMALL IOTA + return rune(0x01d6ca), true + case "b.kappa": // MATHEMATICAL BOLD SMALL KAPPA + return rune(0x01d6cb), true + case "b.kappav": // MATHEMATICAL BOLD KAPPA SYMBOL + return rune(0x01d6de), true + case "b.lambda": // MATHEMATICAL BOLD SMALL LAMDA + return rune(0x01d6cc), true + case "b.mu": // MATHEMATICAL BOLD SMALL MU + return rune(0x01d6cd), true + case "b.nu": // MATHEMATICAL BOLD SMALL NU + return rune(0x01d6ce), true + case "b.omega": // MATHEMATICAL BOLD SMALL OMEGA + return rune(0x01d6da), true + case "b.phi": // MATHEMATICAL BOLD SMALL PHI + return rune(0x01d6d7), true + case "b.phiv": // MATHEMATICAL BOLD PHI SYMBOL + return rune(0x01d6df), true + case "b.pi": // MATHEMATICAL BOLD SMALL PI + return rune(0x01d6d1), true + case "b.piv": // MATHEMATICAL BOLD PI SYMBOL + return rune(0x01d6e1), true + case "b.psi": // MATHEMATICAL BOLD SMALL PSI + return rune(0x01d6d9), true + case "b.rho": // MATHEMATICAL BOLD SMALL RHO + return rune(0x01d6d2), true + case "b.rhov": // MATHEMATICAL BOLD RHO SYMBOL + return rune(0x01d6e0), true + case "b.sigma": // MATHEMATICAL BOLD SMALL SIGMA + return rune(0x01d6d4), true + case "b.sigmav": // MATHEMATICAL BOLD SMALL FINAL SIGMA + return rune(0x01d6d3), true + case "b.tau": // MATHEMATICAL BOLD SMALL TAU + return rune(0x01d6d5), true + case "b.thetas": // MATHEMATICAL BOLD SMALL THETA + return rune(0x01d6c9), true + case "b.thetav": // MATHEMATICAL BOLD THETA SYMBOL + return rune(0x01d6dd), true + case "b.upsi": // MATHEMATICAL BOLD SMALL UPSILON + return rune(0x01d6d6), true + case "b.xi": // MATHEMATICAL BOLD SMALL XI + return rune(0x01d6cf), true + case "b.zeta": // MATHEMATICAL BOLD SMALL ZETA + return rune(0x01d6c7), true + case "bNot": // REVERSED DOUBLE STROKE NOT SIGN + return rune(0x2aed), true + case "backcong": // ALL EQUAL TO + return rune(0x224c), true + case "backepsilon": // GREEK REVERSED LUNATE EPSILON SYMBOL + return rune(0x03f6), true + case "backprime": // REVERSED PRIME + return rune(0x2035), true + case "backsim": // REVERSED TILDE + return rune(0x223d), true + case "backsimeq": // REVERSED TILDE EQUALS + return rune(0x22cd), true + case "barV": // DOUBLE DOWN TACK + return rune(0x2aea), true + case "barvee": // NOR + return rune(0x22bd), true + case "barwed": // PROJECTIVE + return rune(0x2305), true + case "barwedge": // PROJECTIVE + return rune(0x2305), true + case "bbrk": // BOTTOM SQUARE BRACKET + return rune(0x23b5), true + case "bbrktbrk": // BOTTOM SQUARE BRACKET OVER TOP SQUARE BRACKET + return rune(0x23b6), true + case "bcong": // ALL EQUAL TO + return rune(0x224c), true + case "bcy": // CYRILLIC SMALL LETTER BE + return rune(0x0431), true + case "bdlhar": // DOWNWARDS HARPOON WITH BARB LEFT FROM BAR + return rune(0x2961), true + case "bdquo": // DOUBLE LOW-9 QUOTATION MARK + return rune(0x201e), true + case "bdrhar": // DOWNWARDS HARPOON WITH BARB RIGHT FROM BAR + return rune(0x295d), true + case "becaus": // BECAUSE + return rune(0x2235), true + case "because": // BECAUSE + return rune(0x2235), true + case "bemptyv": // REVERSED EMPTY SET + return rune(0x29b0), true + case "bepsi": // GREEK REVERSED LUNATE EPSILON SYMBOL + return rune(0x03f6), true + case "bernou": // SCRIPT CAPITAL B + return rune(0x212c), true + case "beta": // GREEK SMALL LETTER BETA + return rune(0x03b2), true + case "beth": // BET SYMBOL + return rune(0x2136), true + case "between": // BETWEEN + return rune(0x226c), true + case "bfr": // MATHEMATICAL FRAKTUR SMALL B + return rune(0x01d51f), true + case "bgr": // GREEK SMALL LETTER BETA + return rune(0x03b2), true + case "bigcap": // N-ARY INTERSECTION + return rune(0x22c2), true + case "bigcirc": // LARGE CIRCLE + return rune(0x25ef), true + case "bigcup": // N-ARY UNION + return rune(0x22c3), true + case "bigodot": // N-ARY CIRCLED DOT OPERATOR + return rune(0x2a00), true + case "bigoplus": // N-ARY CIRCLED PLUS OPERATOR + return rune(0x2a01), true + case "bigotimes": // N-ARY CIRCLED TIMES OPERATOR + return rune(0x2a02), true + case "bigsqcup": // N-ARY SQUARE UNION OPERATOR + return rune(0x2a06), true + case "bigstar": // BLACK STAR + return rune(0x2605), true + case "bigtriangledown": // WHITE DOWN-POINTING TRIANGLE + return rune(0x25bd), true + case "bigtriangleup": // WHITE UP-POINTING TRIANGLE + return rune(0x25b3), true + case "biguplus": // N-ARY UNION OPERATOR WITH PLUS + return rune(0x2a04), true + case "bigvee": // N-ARY LOGICAL OR + return rune(0x22c1), true + case "bigwedge": // N-ARY LOGICAL AND + return rune(0x22c0), true + case "bkarow": // RIGHTWARDS DOUBLE DASH ARROW + return rune(0x290d), true + case "blacklozenge": // BLACK LOZENGE + return rune(0x29eb), true + case "blacksquare": // BLACK SMALL SQUARE + return rune(0x25aa), true + case "blacktriangle": // BLACK UP-POINTING SMALL TRIANGLE + return rune(0x25b4), true + case "blacktriangledown": // BLACK DOWN-POINTING SMALL TRIANGLE + return rune(0x25be), true + case "blacktriangleleft": // BLACK LEFT-POINTING SMALL TRIANGLE + return rune(0x25c2), true + case "blacktriangleright": // BLACK RIGHT-POINTING SMALL TRIANGLE + return rune(0x25b8), true + case "blank": // BLANK SYMBOL + return rune(0x2422), true + case "bldhar": // LEFTWARDS HARPOON WITH BARB DOWN FROM BAR + return rune(0x295e), true + case "blk12": // MEDIUM SHADE + return rune(0x2592), true + case "blk14": // LIGHT SHADE + return rune(0x2591), true + case "blk34": // DARK SHADE + return rune(0x2593), true + case "block": // FULL BLOCK + return rune(0x2588), true + case "bluhar": // LEFTWARDS HARPOON WITH BARB UP FROM BAR + return rune(0x295a), true + case "bne": // EQUALS SIGN with reverse slash + return rune(0x3d), true + case "bnequiv": // IDENTICAL TO with reverse slash + return rune(0x2261), true + case "bnot": // REVERSED NOT SIGN + return rune(0x2310), true + case "bopf": // MATHEMATICAL DOUBLE-STRUCK SMALL B + return rune(0x01d553), true + case "bot": // UP TACK + return rune(0x22a5), true + case "bottom": // UP TACK + return rune(0x22a5), true + case "bowtie": // BOWTIE + return rune(0x22c8), true + case "boxDL": // BOX DRAWINGS DOUBLE DOWN AND LEFT + return rune(0x2557), true + case "boxDR": // BOX DRAWINGS DOUBLE DOWN AND RIGHT + return rune(0x2554), true + case "boxDl": // BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + return rune(0x2556), true + case "boxDr": // BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + return rune(0x2553), true + case "boxH": // BOX DRAWINGS DOUBLE HORIZONTAL + return rune(0x2550), true + case "boxHD": // BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + return rune(0x2566), true + case "boxHU": // BOX DRAWINGS DOUBLE UP AND HORIZONTAL + return rune(0x2569), true + case "boxHd": // BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + return rune(0x2564), true + case "boxHu": // BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + return rune(0x2567), true + case "boxUL": // BOX DRAWINGS DOUBLE UP AND LEFT + return rune(0x255d), true + case "boxUR": // BOX DRAWINGS DOUBLE UP AND RIGHT + return rune(0x255a), true + case "boxUl": // BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + return rune(0x255c), true + case "boxUr": // BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + return rune(0x2559), true + case "boxV": // BOX DRAWINGS DOUBLE VERTICAL + return rune(0x2551), true + case "boxVH": // BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + return rune(0x256c), true + case "boxVL": // BOX DRAWINGS DOUBLE VERTICAL AND LEFT + return rune(0x2563), true + case "boxVR": // BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + return rune(0x2560), true + case "boxVh": // BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + return rune(0x256b), true + case "boxVl": // BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + return rune(0x2562), true + case "boxVr": // BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + return rune(0x255f), true + case "boxbox": // TWO JOINED SQUARES + return rune(0x29c9), true + case "boxdL": // BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + return rune(0x2555), true + case "boxdR": // BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + return rune(0x2552), true + case "boxdl": // BOX DRAWINGS LIGHT DOWN AND LEFT + return rune(0x2510), true + case "boxdr": // BOX DRAWINGS LIGHT DOWN AND RIGHT + return rune(0x250c), true + case "boxh": // BOX DRAWINGS LIGHT HORIZONTAL + return rune(0x2500), true + case "boxhD": // BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + return rune(0x2565), true + case "boxhU": // BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + return rune(0x2568), true + case "boxhd": // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + return rune(0x252c), true + case "boxhu": // BOX DRAWINGS LIGHT UP AND HORIZONTAL + return rune(0x2534), true + case "boxminus": // SQUARED MINUS + return rune(0x229f), true + case "boxplus": // SQUARED PLUS + return rune(0x229e), true + case "boxtimes": // SQUARED TIMES + return rune(0x22a0), true + case "boxuL": // BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + return rune(0x255b), true + case "boxuR": // BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + return rune(0x2558), true + case "boxul": // BOX DRAWINGS LIGHT UP AND LEFT + return rune(0x2518), true + case "boxur": // BOX DRAWINGS LIGHT UP AND RIGHT + return rune(0x2514), true + case "boxv": // BOX DRAWINGS LIGHT VERTICAL + return rune(0x2502), true + case "boxvH": // BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + return rune(0x256a), true + case "boxvL": // BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + return rune(0x2561), true + case "boxvR": // BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + return rune(0x255e), true + case "boxvh": // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + return rune(0x253c), true + case "boxvl": // BOX DRAWINGS LIGHT VERTICAL AND LEFT + return rune(0x2524), true + case "boxvr": // BOX DRAWINGS LIGHT VERTICAL AND RIGHT + return rune(0x251c), true + case "bprime": // REVERSED PRIME + return rune(0x2035), true + case "brdhar": // RIGHTWARDS HARPOON WITH BARB DOWN FROM BAR + return rune(0x295f), true + case "breve": // BREVE + return rune(0x02d8), true + case "bruhar": // RIGHTWARDS HARPOON WITH BARB UP FROM BAR + return rune(0x295b), true + case "brvbar": // BROKEN BAR + return rune(0xa6), true + case "bscr": // MATHEMATICAL SCRIPT SMALL B + return rune(0x01d4b7), true + case "bsemi": // REVERSED SEMICOLON + return rune(0x204f), true + case "bsim": // REVERSED TILDE + return rune(0x223d), true + case "bsime": // REVERSED TILDE EQUALS + return rune(0x22cd), true + case "bsol": // REVERSE SOLIDUS + return rune(0x5c), true + case "bsolb": // SQUARED FALLING DIAGONAL SLASH + return rune(0x29c5), true + case "bsolhsub": // REVERSE SOLIDUS PRECEDING SUBSET + return rune(0x27c8), true + case "btimes": // SEMIDIRECT PRODUCT WITH BOTTOM CLOSED + return rune(0x2a32), true + case "bulhar": // UPWARDS HARPOON WITH BARB LEFT FROM BAR + return rune(0x2960), true + case "bull": // BULLET + return rune(0x2022), true + case "bullet": // BULLET + return rune(0x2022), true + case "bump": // GEOMETRICALLY EQUIVALENT TO + return rune(0x224e), true + case "bumpE": // EQUALS SIGN WITH BUMPY ABOVE + return rune(0x2aae), true + case "bumpe": // DIFFERENCE BETWEEN + return rune(0x224f), true + case "bumpeq": // DIFFERENCE BETWEEN + return rune(0x224f), true + case "burhar": // UPWARDS HARPOON WITH BARB RIGHT FROM BAR + return rune(0x295c), true } case 'c': switch name { - case "cacute": // LATIN SMALL LETTER C WITH ACUTE - return rune(0x0107), true - case "cap": // INTERSECTION - return rune(0x2229), true - case "capand": // INTERSECTION WITH LOGICAL AND - return rune(0x2a44), true - case "capbrcup": // INTERSECTION ABOVE BAR ABOVE UNION - return rune(0x2a49), true - case "capcap": // INTERSECTION BESIDE AND JOINED WITH INTERSECTION - return rune(0x2a4b), true - case "capcup": // INTERSECTION ABOVE UNION - return rune(0x2a47), true - case "capdot": // INTERSECTION WITH DOT - return rune(0x2a40), true - case "capint": // INTEGRAL WITH INTERSECTION - return rune(0x2a19), true - case "caps": // INTERSECTION with serifs - return rune(0x2229), true - case "caret": // CARET INSERTION POINT - return rune(0x2041), true - case "caron": // CARON - return rune(0x02c7), true - case "ccaps": // CLOSED INTERSECTION WITH SERIFS - return rune(0x2a4d), true - case "ccaron": // LATIN SMALL LETTER C WITH CARON - return rune(0x010d), true - case "ccedil": // LATIN SMALL LETTER C WITH CEDILLA - return rune(0xe7), true - case "ccirc": // LATIN SMALL LETTER C WITH CIRCUMFLEX - return rune(0x0109), true - case "ccups": // CLOSED UNION WITH SERIFS - return rune(0x2a4c), true - case "ccupssm": // CLOSED UNION WITH SERIFS AND SMASH PRODUCT - return rune(0x2a50), true - case "cdot": // LATIN SMALL LETTER C WITH DOT ABOVE - return rune(0x010b), true - case "cedil": // CEDILLA - return rune(0xb8), true - case "cemptyv": // EMPTY SET WITH SMALL CIRCLE ABOVE - return rune(0x29b2), true - case "cent": // CENT SIGN - return rune(0xa2), true - case "centerdot": // MIDDLE DOT - return rune(0xb7), true - case "cfr": // MATHEMATICAL FRAKTUR SMALL C - return rune(0x01d520), true - case "chcy": // CYRILLIC SMALL LETTER CHE - return rune(0x0447), true - case "check": // CHECK MARK - return rune(0x2713), true - case "checkmark": // CHECK MARK - return rune(0x2713), true - case "chi": // GREEK SMALL LETTER CHI - return rune(0x03c7), true - case "cir": // WHITE CIRCLE - return rune(0x25cb), true - case "cirE": // CIRCLE WITH TWO HORIZONTAL STROKES TO THE RIGHT - return rune(0x29c3), true - case "cirb": // SQUARED SMALL CIRCLE - return rune(0x29c7), true - case "circ": // MODIFIER LETTER CIRCUMFLEX ACCENT - return rune(0x02c6), true - case "circeq": // RING EQUAL TO - return rune(0x2257), true - case "circlearrowleft": // ANTICLOCKWISE OPEN CIRCLE ARROW - return rune(0x21ba), true - case "circlearrowright": // CLOCKWISE OPEN CIRCLE ARROW - return rune(0x21bb), true - case "circledR": // REGISTERED SIGN - return rune(0xae), true - case "circledS": // CIRCLED LATIN CAPITAL LETTER S - return rune(0x24c8), true - case "circledast": // CIRCLED ASTERISK OPERATOR - return rune(0x229b), true - case "circledcirc": // CIRCLED RING OPERATOR - return rune(0x229a), true - case "circleddash": // CIRCLED DASH - return rune(0x229d), true - case "cirdarr": // WHITE CIRCLE WITH DOWN ARROW - return rune(0x29ec), true - case "cire": // RING EQUAL TO - return rune(0x2257), true - case "cirerr": // ERROR-BARRED WHITE CIRCLE - return rune(0x29f2), true - case "cirfdarr": // BLACK CIRCLE WITH DOWN ARROW - return rune(0x29ed), true - case "cirferr": // ERROR-BARRED BLACK CIRCLE - return rune(0x29f3), true - case "cirfnint": // CIRCULATION FUNCTION - return rune(0x2a10), true - case "cirmid": // VERTICAL LINE WITH CIRCLE ABOVE - return rune(0x2aef), true - case "cirscir": // CIRCLE WITH SMALL CIRCLE TO THE RIGHT - return rune(0x29c2), true - case "closur": // CLOSE UP - return rune(0x2050), true - case "clubs": // BLACK CLUB SUIT - return rune(0x2663), true - case "clubsuit": // BLACK CLUB SUIT - return rune(0x2663), true - case "colon": // COLON - return rune(0x3a), true - case "colone": // COLON EQUALS - return rune(0x2254), true - case "coloneq": // COLON EQUALS - return rune(0x2254), true - case "comma": // COMMA - return rune(0x2c), true - case "commat": // COMMERCIAL AT - return rune(0x40), true - case "comp": // COMPLEMENT - return rune(0x2201), true - case "compfn": // RING OPERATOR - return rune(0x2218), true - case "complement": // COMPLEMENT - return rune(0x2201), true - case "complexes": // DOUBLE-STRUCK CAPITAL C - return rune(0x2102), true - case "cong": // APPROXIMATELY EQUAL TO - return rune(0x2245), true - case "congdot": // CONGRUENT WITH DOT ABOVE - return rune(0x2a6d), true - case "conint": // CONTOUR INTEGRAL - return rune(0x222e), true - case "copf": // MATHEMATICAL DOUBLE-STRUCK SMALL C - return rune(0x01d554), true - case "coprod": // N-ARY COPRODUCT - return rune(0x2210), true - case "copy": // COPYRIGHT SIGN - return rune(0xa9), true - case "copysr": // SOUND RECORDING COPYRIGHT - return rune(0x2117), true - case "crarr": // DOWNWARDS ARROW WITH CORNER LEFTWARDS - return rune(0x21b5), true - case "cross": // BALLOT X - return rune(0x2717), true - case "cscr": // MATHEMATICAL SCRIPT SMALL C - return rune(0x01d4b8), true - case "csub": // CLOSED SUBSET - return rune(0x2acf), true - case "csube": // CLOSED SUBSET OR EQUAL TO - return rune(0x2ad1), true - case "csup": // CLOSED SUPERSET - return rune(0x2ad0), true - case "csupe": // CLOSED SUPERSET OR EQUAL TO - return rune(0x2ad2), true - case "ctdot": // MIDLINE HORIZONTAL ELLIPSIS - return rune(0x22ef), true - case "cudarrl": // RIGHT-SIDE ARC CLOCKWISE ARROW - return rune(0x2938), true - case "cudarrr": // ARROW POINTING RIGHTWARDS THEN CURVING DOWNWARDS - return rune(0x2935), true - case "cuepr": // EQUAL TO OR PRECEDES - return rune(0x22de), true - case "cuesc": // EQUAL TO OR SUCCEEDS - return rune(0x22df), true - case "cularr": // ANTICLOCKWISE TOP SEMICIRCLE ARROW - return rune(0x21b6), true - case "cularrp": // TOP ARC ANTICLOCKWISE ARROW WITH PLUS - return rune(0x293d), true - case "cup": // UNION - return rune(0x222a), true - case "cupbrcap": // UNION ABOVE BAR ABOVE INTERSECTION - return rune(0x2a48), true - case "cupcap": // UNION ABOVE INTERSECTION - return rune(0x2a46), true - case "cupcup": // UNION BESIDE AND JOINED WITH UNION - return rune(0x2a4a), true - case "cupdot": // MULTISET MULTIPLICATION - return rune(0x228d), true - case "cupint": // INTEGRAL WITH UNION - return rune(0x2a1a), true - case "cupor": // UNION WITH LOGICAL OR - return rune(0x2a45), true - case "cupre": // PRECEDES OR EQUAL TO - return rune(0x227c), true - case "cups": // UNION with serifs - return rune(0x222a), true - case "curarr": // CLOCKWISE TOP SEMICIRCLE ARROW - return rune(0x21b7), true - case "curarrm": // TOP ARC CLOCKWISE ARROW WITH MINUS - return rune(0x293c), true - case "curlyeqprec": // EQUAL TO OR PRECEDES - return rune(0x22de), true - case "curlyeqsucc": // EQUAL TO OR SUCCEEDS - return rune(0x22df), true - case "curlyvee": // CURLY LOGICAL OR - return rune(0x22ce), true - case "curlywedge": // CURLY LOGICAL AND - return rune(0x22cf), true - case "curren": // CURRENCY SIGN - return rune(0xa4), true - case "curvearrowleft": // ANTICLOCKWISE TOP SEMICIRCLE ARROW - return rune(0x21b6), true - case "curvearrowright": // CLOCKWISE TOP SEMICIRCLE ARROW - return rune(0x21b7), true - case "cuvee": // CURLY LOGICAL OR - return rune(0x22ce), true - case "cuwed": // CURLY LOGICAL AND - return rune(0x22cf), true - case "cwconint": // CLOCKWISE CONTOUR INTEGRAL - return rune(0x2232), true - case "cwint": // CLOCKWISE INTEGRAL - return rune(0x2231), true - case "cylcty": // CYLINDRICITY - return rune(0x232d), true + case "cacute": // LATIN SMALL LETTER C WITH ACUTE + return rune(0x0107), true + case "cap": // INTERSECTION + return rune(0x2229), true + case "capand": // INTERSECTION WITH LOGICAL AND + return rune(0x2a44), true + case "capbrcup": // INTERSECTION ABOVE BAR ABOVE UNION + return rune(0x2a49), true + case "capcap": // INTERSECTION BESIDE AND JOINED WITH INTERSECTION + return rune(0x2a4b), true + case "capcup": // INTERSECTION ABOVE UNION + return rune(0x2a47), true + case "capdot": // INTERSECTION WITH DOT + return rune(0x2a40), true + case "capint": // INTEGRAL WITH INTERSECTION + return rune(0x2a19), true + case "caps": // INTERSECTION with serifs + return rune(0x2229), true + case "caret": // CARET INSERTION POINT + return rune(0x2041), true + case "caron": // CARON + return rune(0x02c7), true + case "ccaps": // CLOSED INTERSECTION WITH SERIFS + return rune(0x2a4d), true + case "ccaron": // LATIN SMALL LETTER C WITH CARON + return rune(0x010d), true + case "ccedil": // LATIN SMALL LETTER C WITH CEDILLA + return rune(0xe7), true + case "ccirc": // LATIN SMALL LETTER C WITH CIRCUMFLEX + return rune(0x0109), true + case "ccups": // CLOSED UNION WITH SERIFS + return rune(0x2a4c), true + case "ccupssm": // CLOSED UNION WITH SERIFS AND SMASH PRODUCT + return rune(0x2a50), true + case "cdot": // LATIN SMALL LETTER C WITH DOT ABOVE + return rune(0x010b), true + case "cedil": // CEDILLA + return rune(0xb8), true + case "cemptyv": // EMPTY SET WITH SMALL CIRCLE ABOVE + return rune(0x29b2), true + case "cent": // CENT SIGN + return rune(0xa2), true + case "centerdot": // MIDDLE DOT + return rune(0xb7), true + case "cfr": // MATHEMATICAL FRAKTUR SMALL C + return rune(0x01d520), true + case "chcy": // CYRILLIC SMALL LETTER CHE + return rune(0x0447), true + case "check": // CHECK MARK + return rune(0x2713), true + case "checkmark": // CHECK MARK + return rune(0x2713), true + case "chi": // GREEK SMALL LETTER CHI + return rune(0x03c7), true + case "cir": // WHITE CIRCLE + return rune(0x25cb), true + case "cirE": // CIRCLE WITH TWO HORIZONTAL STROKES TO THE RIGHT + return rune(0x29c3), true + case "cirb": // SQUARED SMALL CIRCLE + return rune(0x29c7), true + case "circ": // MODIFIER LETTER CIRCUMFLEX ACCENT + return rune(0x02c6), true + case "circeq": // RING EQUAL TO + return rune(0x2257), true + case "circlearrowleft": // ANTICLOCKWISE OPEN CIRCLE ARROW + return rune(0x21ba), true + case "circlearrowright": // CLOCKWISE OPEN CIRCLE ARROW + return rune(0x21bb), true + case "circledR": // REGISTERED SIGN + return rune(0xae), true + case "circledS": // CIRCLED LATIN CAPITAL LETTER S + return rune(0x24c8), true + case "circledast": // CIRCLED ASTERISK OPERATOR + return rune(0x229b), true + case "circledcirc": // CIRCLED RING OPERATOR + return rune(0x229a), true + case "circleddash": // CIRCLED DASH + return rune(0x229d), true + case "cirdarr": // WHITE CIRCLE WITH DOWN ARROW + return rune(0x29ec), true + case "cire": // RING EQUAL TO + return rune(0x2257), true + case "cirerr": // ERROR-BARRED WHITE CIRCLE + return rune(0x29f2), true + case "cirfdarr": // BLACK CIRCLE WITH DOWN ARROW + return rune(0x29ed), true + case "cirferr": // ERROR-BARRED BLACK CIRCLE + return rune(0x29f3), true + case "cirfnint": // CIRCULATION FUNCTION + return rune(0x2a10), true + case "cirmid": // VERTICAL LINE WITH CIRCLE ABOVE + return rune(0x2aef), true + case "cirscir": // CIRCLE WITH SMALL CIRCLE TO THE RIGHT + return rune(0x29c2), true + case "closur": // CLOSE UP + return rune(0x2050), true + case "clubs": // BLACK CLUB SUIT + return rune(0x2663), true + case "clubsuit": // BLACK CLUB SUIT + return rune(0x2663), true + case "colon": // COLON + return rune(0x3a), true + case "colone": // COLON EQUALS + return rune(0x2254), true + case "coloneq": // COLON EQUALS + return rune(0x2254), true + case "comma": // COMMA + return rune(0x2c), true + case "commat": // COMMERCIAL AT + return rune(0x40), true + case "comp": // COMPLEMENT + return rune(0x2201), true + case "compfn": // RING OPERATOR + return rune(0x2218), true + case "complement": // COMPLEMENT + return rune(0x2201), true + case "complexes": // DOUBLE-STRUCK CAPITAL C + return rune(0x2102), true + case "cong": // APPROXIMATELY EQUAL TO + return rune(0x2245), true + case "congdot": // CONGRUENT WITH DOT ABOVE + return rune(0x2a6d), true + case "conint": // CONTOUR INTEGRAL + return rune(0x222e), true + case "copf": // MATHEMATICAL DOUBLE-STRUCK SMALL C + return rune(0x01d554), true + case "coprod": // N-ARY COPRODUCT + return rune(0x2210), true + case "copy": // COPYRIGHT SIGN + return rune(0xa9), true + case "copysr": // SOUND RECORDING COPYRIGHT + return rune(0x2117), true + case "crarr": // DOWNWARDS ARROW WITH CORNER LEFTWARDS + return rune(0x21b5), true + case "cross": // BALLOT X + return rune(0x2717), true + case "cscr": // MATHEMATICAL SCRIPT SMALL C + return rune(0x01d4b8), true + case "csub": // CLOSED SUBSET + return rune(0x2acf), true + case "csube": // CLOSED SUBSET OR EQUAL TO + return rune(0x2ad1), true + case "csup": // CLOSED SUPERSET + return rune(0x2ad0), true + case "csupe": // CLOSED SUPERSET OR EQUAL TO + return rune(0x2ad2), true + case "ctdot": // MIDLINE HORIZONTAL ELLIPSIS + return rune(0x22ef), true + case "cudarrl": // RIGHT-SIDE ARC CLOCKWISE ARROW + return rune(0x2938), true + case "cudarrr": // ARROW POINTING RIGHTWARDS THEN CURVING DOWNWARDS + return rune(0x2935), true + case "cuepr": // EQUAL TO OR PRECEDES + return rune(0x22de), true + case "cuesc": // EQUAL TO OR SUCCEEDS + return rune(0x22df), true + case "cularr": // ANTICLOCKWISE TOP SEMICIRCLE ARROW + return rune(0x21b6), true + case "cularrp": // TOP ARC ANTICLOCKWISE ARROW WITH PLUS + return rune(0x293d), true + case "cup": // UNION + return rune(0x222a), true + case "cupbrcap": // UNION ABOVE BAR ABOVE INTERSECTION + return rune(0x2a48), true + case "cupcap": // UNION ABOVE INTERSECTION + return rune(0x2a46), true + case "cupcup": // UNION BESIDE AND JOINED WITH UNION + return rune(0x2a4a), true + case "cupdot": // MULTISET MULTIPLICATION + return rune(0x228d), true + case "cupint": // INTEGRAL WITH UNION + return rune(0x2a1a), true + case "cupor": // UNION WITH LOGICAL OR + return rune(0x2a45), true + case "cupre": // PRECEDES OR EQUAL TO + return rune(0x227c), true + case "cups": // UNION with serifs + return rune(0x222a), true + case "curarr": // CLOCKWISE TOP SEMICIRCLE ARROW + return rune(0x21b7), true + case "curarrm": // TOP ARC CLOCKWISE ARROW WITH MINUS + return rune(0x293c), true + case "curlyeqprec": // EQUAL TO OR PRECEDES + return rune(0x22de), true + case "curlyeqsucc": // EQUAL TO OR SUCCEEDS + return rune(0x22df), true + case "curlyvee": // CURLY LOGICAL OR + return rune(0x22ce), true + case "curlywedge": // CURLY LOGICAL AND + return rune(0x22cf), true + case "curren": // CURRENCY SIGN + return rune(0xa4), true + case "curvearrowleft": // ANTICLOCKWISE TOP SEMICIRCLE ARROW + return rune(0x21b6), true + case "curvearrowright": // CLOCKWISE TOP SEMICIRCLE ARROW + return rune(0x21b7), true + case "cuvee": // CURLY LOGICAL OR + return rune(0x22ce), true + case "cuwed": // CURLY LOGICAL AND + return rune(0x22cf), true + case "cwconint": // CLOCKWISE CONTOUR INTEGRAL + return rune(0x2232), true + case "cwint": // CLOCKWISE INTEGRAL + return rune(0x2231), true + case "cylcty": // CYLINDRICITY + return rune(0x232d), true } case 'd': switch name { - case "dAarr": // DOWNWARDS TRIPLE ARROW - return rune(0x290b), true - case "dArr": // DOWNWARDS DOUBLE ARROW - return rune(0x21d3), true - case "dHar": // DOWNWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT - return rune(0x2965), true - case "dagger": // DAGGER - return rune(0x2020), true - case "dalembrt": // SQUARE WITH CONTOURED OUTLINE - return rune(0x29e0), true - case "daleth": // DALET SYMBOL - return rune(0x2138), true - case "darr": // DOWNWARDS ARROW - return rune(0x2193), true - case "darr2": // DOWNWARDS PAIRED ARROWS - return rune(0x21ca), true - case "darrb": // DOWNWARDS ARROW TO BAR - return rune(0x2913), true - case "darrln": // DOWNWARDS ARROW WITH HORIZONTAL STROKE - return rune(0x2908), true - case "dash": // HYPHEN - return rune(0x2010), true - case "dashV": // DOUBLE VERTICAL BAR LEFT TURNSTILE - return rune(0x2ae3), true - case "dashv": // LEFT TACK - return rune(0x22a3), true - case "dbkarow": // RIGHTWARDS TRIPLE DASH ARROW - return rune(0x290f), true - case "dblac": // DOUBLE ACUTE ACCENT - return rune(0x02dd), true - case "dcaron": // LATIN SMALL LETTER D WITH CARON - return rune(0x010f), true - case "dcy": // CYRILLIC SMALL LETTER DE - return rune(0x0434), true - case "dd": // DOUBLE-STRUCK ITALIC SMALL D - return rune(0x2146), true - case "ddagger": // DOUBLE DAGGER - return rune(0x2021), true - case "ddarr": // DOWNWARDS PAIRED ARROWS - return rune(0x21ca), true - case "ddotseq": // EQUALS SIGN WITH TWO DOTS ABOVE AND TWO DOTS BELOW - return rune(0x2a77), true - case "deg": // DEGREE SIGN - return rune(0xb0), true - case "delta": // GREEK SMALL LETTER DELTA - return rune(0x03b4), true - case "demptyv": // EMPTY SET WITH OVERBAR - return rune(0x29b1), true - case "dfisht": // DOWN FISH TAIL - return rune(0x297f), true - case "dfr": // MATHEMATICAL FRAKTUR SMALL D - return rune(0x01d521), true - case "dgr": // GREEK SMALL LETTER DELTA - return rune(0x03b4), true - case "dharl": // DOWNWARDS HARPOON WITH BARB LEFTWARDS - return rune(0x21c3), true - case "dharr": // DOWNWARDS HARPOON WITH BARB RIGHTWARDS - return rune(0x21c2), true - case "diam": // DIAMOND OPERATOR - return rune(0x22c4), true - case "diamdarr": // BLACK DIAMOND WITH DOWN ARROW - return rune(0x29ea), true - case "diamerr": // ERROR-BARRED WHITE DIAMOND - return rune(0x29f0), true - case "diamerrf": // ERROR-BARRED BLACK DIAMOND - return rune(0x29f1), true - case "diamond": // DIAMOND OPERATOR - return rune(0x22c4), true - case "diamondsuit": // BLACK DIAMOND SUIT - return rune(0x2666), true - case "diams": // BLACK DIAMOND SUIT - return rune(0x2666), true - case "die": // DIAERESIS - return rune(0xa8), true - case "digamma": // GREEK SMALL LETTER DIGAMMA - return rune(0x03dd), true - case "disin": // ELEMENT OF WITH LONG HORIZONTAL STROKE - return rune(0x22f2), true - case "div": // DIVISION SIGN - return rune(0xf7), true - case "divide": // DIVISION SIGN - return rune(0xf7), true - case "divideontimes": // DIVISION TIMES - return rune(0x22c7), true - case "divonx": // DIVISION TIMES - return rune(0x22c7), true - case "djcy": // CYRILLIC SMALL LETTER DJE - return rune(0x0452), true - case "dlarr": // SOUTH WEST ARROW - return rune(0x2199), true - case "dlcorn": // BOTTOM LEFT CORNER - return rune(0x231e), true - case "dlcrop": // BOTTOM LEFT CROP - return rune(0x230d), true - case "dlharb": // DOWNWARDS HARPOON WITH BARB LEFT TO BAR - return rune(0x2959), true - case "dollar": // DOLLAR SIGN - return rune(0x24), true - case "dopf": // MATHEMATICAL DOUBLE-STRUCK SMALL D - return rune(0x01d555), true - case "dot": // DOT ABOVE - return rune(0x02d9), true - case "doteq": // APPROACHES THE LIMIT - return rune(0x2250), true - case "doteqdot": // GEOMETRICALLY EQUAL TO - return rune(0x2251), true - case "dotminus": // DOT MINUS - return rune(0x2238), true - case "dotplus": // DOT PLUS - return rune(0x2214), true - case "dotsquare": // SQUARED DOT OPERATOR - return rune(0x22a1), true - case "doublebarwedge": // PERSPECTIVE - return rune(0x2306), true - case "downarrow": // DOWNWARDS ARROW - return rune(0x2193), true - case "downdownarrows": // DOWNWARDS PAIRED ARROWS - return rune(0x21ca), true - case "downharpoonleft": // DOWNWARDS HARPOON WITH BARB LEFTWARDS - return rune(0x21c3), true - case "downharpoonright": // DOWNWARDS HARPOON WITH BARB RIGHTWARDS - return rune(0x21c2), true - case "drarr": // SOUTH EAST ARROW - return rune(0x2198), true - case "drbkarow": // RIGHTWARDS TWO-HEADED TRIPLE DASH ARROW - return rune(0x2910), true - case "drcorn": // BOTTOM RIGHT CORNER - return rune(0x231f), true - case "drcrop": // BOTTOM RIGHT CROP - return rune(0x230c), true - case "drharb": // DOWNWARDS HARPOON WITH BARB RIGHT TO BAR - return rune(0x2955), true - case "dscr": // MATHEMATICAL SCRIPT SMALL D - return rune(0x01d4b9), true - case "dscy": // CYRILLIC SMALL LETTER DZE - return rune(0x0455), true - case "dsol": // SOLIDUS WITH OVERBAR - return rune(0x29f6), true - case "dstrok": // LATIN SMALL LETTER D WITH STROKE - return rune(0x0111), true - case "dtdot": // DOWN RIGHT DIAGONAL ELLIPSIS - return rune(0x22f1), true - case "dtri": // WHITE DOWN-POINTING SMALL TRIANGLE - return rune(0x25bf), true - case "dtrif": // BLACK DOWN-POINTING SMALL TRIANGLE - return rune(0x25be), true - case "dtrilf": // DOWN-POINTING TRIANGLE WITH LEFT HALF BLACK - return rune(0x29e8), true - case "dtrirf": // DOWN-POINTING TRIANGLE WITH RIGHT HALF BLACK - return rune(0x29e9), true - case "duarr": // DOWNWARDS ARROW LEFTWARDS OF UPWARDS ARROW - return rune(0x21f5), true - case "duhar": // DOWNWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT - return rune(0x296f), true - case "dumap": // DOUBLE-ENDED MULTIMAP - return rune(0x29df), true - case "dwangle": // OBLIQUE ANGLE OPENING UP - return rune(0x29a6), true - case "dzcy": // CYRILLIC SMALL LETTER DZHE - return rune(0x045f), true - case "dzigrarr": // LONG RIGHTWARDS SQUIGGLE ARROW - return rune(0x27ff), true + case "dAarr": // DOWNWARDS TRIPLE ARROW + return rune(0x290b), true + case "dArr": // DOWNWARDS DOUBLE ARROW + return rune(0x21d3), true + case "dHar": // DOWNWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT + return rune(0x2965), true + case "dagger": // DAGGER + return rune(0x2020), true + case "dalembrt": // SQUARE WITH CONTOURED OUTLINE + return rune(0x29e0), true + case "daleth": // DALET SYMBOL + return rune(0x2138), true + case "darr": // DOWNWARDS ARROW + return rune(0x2193), true + case "darr2": // DOWNWARDS PAIRED ARROWS + return rune(0x21ca), true + case "darrb": // DOWNWARDS ARROW TO BAR + return rune(0x2913), true + case "darrln": // DOWNWARDS ARROW WITH HORIZONTAL STROKE + return rune(0x2908), true + case "dash": // HYPHEN + return rune(0x2010), true + case "dashV": // DOUBLE VERTICAL BAR LEFT TURNSTILE + return rune(0x2ae3), true + case "dashv": // LEFT TACK + return rune(0x22a3), true + case "dbkarow": // RIGHTWARDS TRIPLE DASH ARROW + return rune(0x290f), true + case "dblac": // DOUBLE ACUTE ACCENT + return rune(0x02dd), true + case "dcaron": // LATIN SMALL LETTER D WITH CARON + return rune(0x010f), true + case "dcy": // CYRILLIC SMALL LETTER DE + return rune(0x0434), true + case "dd": // DOUBLE-STRUCK ITALIC SMALL D + return rune(0x2146), true + case "ddagger": // DOUBLE DAGGER + return rune(0x2021), true + case "ddarr": // DOWNWARDS PAIRED ARROWS + return rune(0x21ca), true + case "ddotseq": // EQUALS SIGN WITH TWO DOTS ABOVE AND TWO DOTS BELOW + return rune(0x2a77), true + case "deg": // DEGREE SIGN + return rune(0xb0), true + case "delta": // GREEK SMALL LETTER DELTA + return rune(0x03b4), true + case "demptyv": // EMPTY SET WITH OVERBAR + return rune(0x29b1), true + case "dfisht": // DOWN FISH TAIL + return rune(0x297f), true + case "dfr": // MATHEMATICAL FRAKTUR SMALL D + return rune(0x01d521), true + case "dgr": // GREEK SMALL LETTER DELTA + return rune(0x03b4), true + case "dharl": // DOWNWARDS HARPOON WITH BARB LEFTWARDS + return rune(0x21c3), true + case "dharr": // DOWNWARDS HARPOON WITH BARB RIGHTWARDS + return rune(0x21c2), true + case "diam": // DIAMOND OPERATOR + return rune(0x22c4), true + case "diamdarr": // BLACK DIAMOND WITH DOWN ARROW + return rune(0x29ea), true + case "diamerr": // ERROR-BARRED WHITE DIAMOND + return rune(0x29f0), true + case "diamerrf": // ERROR-BARRED BLACK DIAMOND + return rune(0x29f1), true + case "diamond": // DIAMOND OPERATOR + return rune(0x22c4), true + case "diamondsuit": // BLACK DIAMOND SUIT + return rune(0x2666), true + case "diams": // BLACK DIAMOND SUIT + return rune(0x2666), true + case "die": // DIAERESIS + return rune(0xa8), true + case "digamma": // GREEK SMALL LETTER DIGAMMA + return rune(0x03dd), true + case "disin": // ELEMENT OF WITH LONG HORIZONTAL STROKE + return rune(0x22f2), true + case "div": // DIVISION SIGN + return rune(0xf7), true + case "divide": // DIVISION SIGN + return rune(0xf7), true + case "divideontimes": // DIVISION TIMES + return rune(0x22c7), true + case "divonx": // DIVISION TIMES + return rune(0x22c7), true + case "djcy": // CYRILLIC SMALL LETTER DJE + return rune(0x0452), true + case "dlarr": // SOUTH WEST ARROW + return rune(0x2199), true + case "dlcorn": // BOTTOM LEFT CORNER + return rune(0x231e), true + case "dlcrop": // BOTTOM LEFT CROP + return rune(0x230d), true + case "dlharb": // DOWNWARDS HARPOON WITH BARB LEFT TO BAR + return rune(0x2959), true + case "dollar": // DOLLAR SIGN + return rune(0x24), true + case "dopf": // MATHEMATICAL DOUBLE-STRUCK SMALL D + return rune(0x01d555), true + case "dot": // DOT ABOVE + return rune(0x02d9), true + case "doteq": // APPROACHES THE LIMIT + return rune(0x2250), true + case "doteqdot": // GEOMETRICALLY EQUAL TO + return rune(0x2251), true + case "dotminus": // DOT MINUS + return rune(0x2238), true + case "dotplus": // DOT PLUS + return rune(0x2214), true + case "dotsquare": // SQUARED DOT OPERATOR + return rune(0x22a1), true + case "doublebarwedge": // PERSPECTIVE + return rune(0x2306), true + case "downarrow": // DOWNWARDS ARROW + return rune(0x2193), true + case "downdownarrows": // DOWNWARDS PAIRED ARROWS + return rune(0x21ca), true + case "downharpoonleft": // DOWNWARDS HARPOON WITH BARB LEFTWARDS + return rune(0x21c3), true + case "downharpoonright": // DOWNWARDS HARPOON WITH BARB RIGHTWARDS + return rune(0x21c2), true + case "drarr": // SOUTH EAST ARROW + return rune(0x2198), true + case "drbkarow": // RIGHTWARDS TWO-HEADED TRIPLE DASH ARROW + return rune(0x2910), true + case "drcorn": // BOTTOM RIGHT CORNER + return rune(0x231f), true + case "drcrop": // BOTTOM RIGHT CROP + return rune(0x230c), true + case "drharb": // DOWNWARDS HARPOON WITH BARB RIGHT TO BAR + return rune(0x2955), true + case "dscr": // MATHEMATICAL SCRIPT SMALL D + return rune(0x01d4b9), true + case "dscy": // CYRILLIC SMALL LETTER DZE + return rune(0x0455), true + case "dsol": // SOLIDUS WITH OVERBAR + return rune(0x29f6), true + case "dstrok": // LATIN SMALL LETTER D WITH STROKE + return rune(0x0111), true + case "dtdot": // DOWN RIGHT DIAGONAL ELLIPSIS + return rune(0x22f1), true + case "dtri": // WHITE DOWN-POINTING SMALL TRIANGLE + return rune(0x25bf), true + case "dtrif": // BLACK DOWN-POINTING SMALL TRIANGLE + return rune(0x25be), true + case "dtrilf": // DOWN-POINTING TRIANGLE WITH LEFT HALF BLACK + return rune(0x29e8), true + case "dtrirf": // DOWN-POINTING TRIANGLE WITH RIGHT HALF BLACK + return rune(0x29e9), true + case "duarr": // DOWNWARDS ARROW LEFTWARDS OF UPWARDS ARROW + return rune(0x21f5), true + case "duhar": // DOWNWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT + return rune(0x296f), true + case "dumap": // DOUBLE-ENDED MULTIMAP + return rune(0x29df), true + case "dwangle": // OBLIQUE ANGLE OPENING UP + return rune(0x29a6), true + case "dzcy": // CYRILLIC SMALL LETTER DZHE + return rune(0x045f), true + case "dzigrarr": // LONG RIGHTWARDS SQUIGGLE ARROW + return rune(0x27ff), true } case 'e': switch name { - case "eDDot": // EQUALS SIGN WITH TWO DOTS ABOVE AND TWO DOTS BELOW - return rune(0x2a77), true - case "eDot": // GEOMETRICALLY EQUAL TO - return rune(0x2251), true - case "eacgr": // GREEK SMALL LETTER EPSILON WITH TONOS - return rune(0x03ad), true - case "eacute": // LATIN SMALL LETTER E WITH ACUTE - return rune(0xe9), true - case "easter": // EQUALS WITH ASTERISK - return rune(0x2a6e), true - case "ecaron": // LATIN SMALL LETTER E WITH CARON - return rune(0x011b), true - case "ecir": // RING IN EQUAL TO - return rune(0x2256), true - case "ecirc": // LATIN SMALL LETTER E WITH CIRCUMFLEX - return rune(0xea), true - case "ecolon": // EQUALS COLON - return rune(0x2255), true - case "ecy": // CYRILLIC SMALL LETTER E - return rune(0x044d), true - case "edot": // LATIN SMALL LETTER E WITH DOT ABOVE - return rune(0x0117), true - case "ee": // DOUBLE-STRUCK ITALIC SMALL E - return rune(0x2147), true - case "eeacgr": // GREEK SMALL LETTER ETA WITH TONOS - return rune(0x03ae), true - case "eegr": // GREEK SMALL LETTER ETA - return rune(0x03b7), true - case "efDot": // APPROXIMATELY EQUAL TO OR THE IMAGE OF - return rune(0x2252), true - case "efr": // MATHEMATICAL FRAKTUR SMALL E - return rune(0x01d522), true - case "eg": // DOUBLE-LINE EQUAL TO OR GREATER-THAN - return rune(0x2a9a), true - case "egr": // GREEK SMALL LETTER EPSILON - return rune(0x03b5), true - case "egrave": // LATIN SMALL LETTER E WITH GRAVE - return rune(0xe8), true - case "egs": // SLANTED EQUAL TO OR GREATER-THAN - return rune(0x2a96), true - case "egsdot": // SLANTED EQUAL TO OR GREATER-THAN WITH DOT INSIDE - return rune(0x2a98), true - case "el": // DOUBLE-LINE EQUAL TO OR LESS-THAN - return rune(0x2a99), true - case "elinters": // ELECTRICAL INTERSECTION - return rune(0x23e7), true - case "ell": // SCRIPT SMALL L - return rune(0x2113), true - case "els": // SLANTED EQUAL TO OR LESS-THAN - return rune(0x2a95), true - case "elsdot": // SLANTED EQUAL TO OR LESS-THAN WITH DOT INSIDE - return rune(0x2a97), true - case "emacr": // LATIN SMALL LETTER E WITH MACRON - return rune(0x0113), true - case "empty": // EMPTY SET - return rune(0x2205), true - case "emptyset": // EMPTY SET - return rune(0x2205), true - case "emptyv": // EMPTY SET - return rune(0x2205), true - case "emsp": // EM SPACE - return rune(0x2003), true - case "emsp13": // THREE-PER-EM SPACE - return rune(0x2004), true - case "emsp14": // FOUR-PER-EM SPACE - return rune(0x2005), true - case "eng": // LATIN SMALL LETTER ENG - return rune(0x014b), true - case "ensp": // EN SPACE - return rune(0x2002), true - case "eogon": // LATIN SMALL LETTER E WITH OGONEK - return rune(0x0119), true - case "eopf": // MATHEMATICAL DOUBLE-STRUCK SMALL E - return rune(0x01d556), true - case "epar": // EQUAL AND PARALLEL TO - return rune(0x22d5), true - case "eparsl": // EQUALS SIGN AND SLANTED PARALLEL - return rune(0x29e3), true - case "eplus": // EQUALS SIGN ABOVE PLUS SIGN - return rune(0x2a71), true - case "epsi": // GREEK SMALL LETTER EPSILON - return rune(0x03b5), true - case "epsilon": // GREEK SMALL LETTER EPSILON - return rune(0x03b5), true - case "epsis": // GREEK LUNATE EPSILON SYMBOL - return rune(0x03f5), true - case "epsiv": // GREEK LUNATE EPSILON SYMBOL - return rune(0x03f5), true - case "eqcirc": // RING IN EQUAL TO - return rune(0x2256), true - case "eqcolon": // EQUALS COLON - return rune(0x2255), true - case "eqeq": // TWO CONSECUTIVE EQUALS SIGNS - return rune(0x2a75), true - case "eqsim": // MINUS TILDE - return rune(0x2242), true - case "eqslantgtr": // SLANTED EQUAL TO OR GREATER-THAN - return rune(0x2a96), true - case "eqslantless": // SLANTED EQUAL TO OR LESS-THAN - return rune(0x2a95), true - case "equals": // EQUALS SIGN - return rune(0x3d), true - case "equest": // QUESTIONED EQUAL TO - return rune(0x225f), true - case "equiv": // IDENTICAL TO - return rune(0x2261), true - case "equivDD": // EQUIVALENT WITH FOUR DOTS ABOVE - return rune(0x2a78), true - case "eqvparsl": // IDENTICAL TO AND SLANTED PARALLEL - return rune(0x29e5), true - case "erDot": // IMAGE OF OR APPROXIMATELY EQUAL TO - return rune(0x2253), true - case "erarr": // EQUALS SIGN ABOVE RIGHTWARDS ARROW - return rune(0x2971), true - case "escr": // SCRIPT SMALL E - return rune(0x212f), true - case "esdot": // APPROACHES THE LIMIT - return rune(0x2250), true - case "esim": // MINUS TILDE - return rune(0x2242), true - case "eta": // GREEK SMALL LETTER ETA - return rune(0x03b7), true - case "eth": // LATIN SMALL LETTER ETH - return rune(0xf0), true - case "euml": // LATIN SMALL LETTER E WITH DIAERESIS - return rune(0xeb), true - case "euro": // EURO SIGN - return rune(0x20ac), true - case "excl": // EXCLAMATION MARK - return rune(0x21), true - case "exist": // THERE EXISTS - return rune(0x2203), true - case "expectation": // SCRIPT CAPITAL E - return rune(0x2130), true - case "exponentiale": // DOUBLE-STRUCK ITALIC SMALL E - return rune(0x2147), true + case "eDDot": // EQUALS SIGN WITH TWO DOTS ABOVE AND TWO DOTS BELOW + return rune(0x2a77), true + case "eDot": // GEOMETRICALLY EQUAL TO + return rune(0x2251), true + case "eacgr": // GREEK SMALL LETTER EPSILON WITH TONOS + return rune(0x03ad), true + case "eacute": // LATIN SMALL LETTER E WITH ACUTE + return rune(0xe9), true + case "easter": // EQUALS WITH ASTERISK + return rune(0x2a6e), true + case "ecaron": // LATIN SMALL LETTER E WITH CARON + return rune(0x011b), true + case "ecir": // RING IN EQUAL TO + return rune(0x2256), true + case "ecirc": // LATIN SMALL LETTER E WITH CIRCUMFLEX + return rune(0xea), true + case "ecolon": // EQUALS COLON + return rune(0x2255), true + case "ecy": // CYRILLIC SMALL LETTER E + return rune(0x044d), true + case "edot": // LATIN SMALL LETTER E WITH DOT ABOVE + return rune(0x0117), true + case "ee": // DOUBLE-STRUCK ITALIC SMALL E + return rune(0x2147), true + case "eeacgr": // GREEK SMALL LETTER ETA WITH TONOS + return rune(0x03ae), true + case "eegr": // GREEK SMALL LETTER ETA + return rune(0x03b7), true + case "efDot": // APPROXIMATELY EQUAL TO OR THE IMAGE OF + return rune(0x2252), true + case "efr": // MATHEMATICAL FRAKTUR SMALL E + return rune(0x01d522), true + case "eg": // DOUBLE-LINE EQUAL TO OR GREATER-THAN + return rune(0x2a9a), true + case "egr": // GREEK SMALL LETTER EPSILON + return rune(0x03b5), true + case "egrave": // LATIN SMALL LETTER E WITH GRAVE + return rune(0xe8), true + case "egs": // SLANTED EQUAL TO OR GREATER-THAN + return rune(0x2a96), true + case "egsdot": // SLANTED EQUAL TO OR GREATER-THAN WITH DOT INSIDE + return rune(0x2a98), true + case "el": // DOUBLE-LINE EQUAL TO OR LESS-THAN + return rune(0x2a99), true + case "elinters": // ELECTRICAL INTERSECTION + return rune(0x23e7), true + case "ell": // SCRIPT SMALL L + return rune(0x2113), true + case "els": // SLANTED EQUAL TO OR LESS-THAN + return rune(0x2a95), true + case "elsdot": // SLANTED EQUAL TO OR LESS-THAN WITH DOT INSIDE + return rune(0x2a97), true + case "emacr": // LATIN SMALL LETTER E WITH MACRON + return rune(0x0113), true + case "empty": // EMPTY SET + return rune(0x2205), true + case "emptyset": // EMPTY SET + return rune(0x2205), true + case "emptyv": // EMPTY SET + return rune(0x2205), true + case "emsp": // EM SPACE + return rune(0x2003), true + case "emsp13": // THREE-PER-EM SPACE + return rune(0x2004), true + case "emsp14": // FOUR-PER-EM SPACE + return rune(0x2005), true + case "eng": // LATIN SMALL LETTER ENG + return rune(0x014b), true + case "ensp": // EN SPACE + return rune(0x2002), true + case "eogon": // LATIN SMALL LETTER E WITH OGONEK + return rune(0x0119), true + case "eopf": // MATHEMATICAL DOUBLE-STRUCK SMALL E + return rune(0x01d556), true + case "epar": // EQUAL AND PARALLEL TO + return rune(0x22d5), true + case "eparsl": // EQUALS SIGN AND SLANTED PARALLEL + return rune(0x29e3), true + case "eplus": // EQUALS SIGN ABOVE PLUS SIGN + return rune(0x2a71), true + case "epsi": // GREEK SMALL LETTER EPSILON + return rune(0x03b5), true + case "epsilon": // GREEK SMALL LETTER EPSILON + return rune(0x03b5), true + case "epsis": // GREEK LUNATE EPSILON SYMBOL + return rune(0x03f5), true + case "epsiv": // GREEK LUNATE EPSILON SYMBOL + return rune(0x03f5), true + case "eqcirc": // RING IN EQUAL TO + return rune(0x2256), true + case "eqcolon": // EQUALS COLON + return rune(0x2255), true + case "eqeq": // TWO CONSECUTIVE EQUALS SIGNS + return rune(0x2a75), true + case "eqsim": // MINUS TILDE + return rune(0x2242), true + case "eqslantgtr": // SLANTED EQUAL TO OR GREATER-THAN + return rune(0x2a96), true + case "eqslantless": // SLANTED EQUAL TO OR LESS-THAN + return rune(0x2a95), true + case "equals": // EQUALS SIGN + return rune(0x3d), true + case "equest": // QUESTIONED EQUAL TO + return rune(0x225f), true + case "equiv": // IDENTICAL TO + return rune(0x2261), true + case "equivDD": // EQUIVALENT WITH FOUR DOTS ABOVE + return rune(0x2a78), true + case "eqvparsl": // IDENTICAL TO AND SLANTED PARALLEL + return rune(0x29e5), true + case "erDot": // IMAGE OF OR APPROXIMATELY EQUAL TO + return rune(0x2253), true + case "erarr": // EQUALS SIGN ABOVE RIGHTWARDS ARROW + return rune(0x2971), true + case "escr": // SCRIPT SMALL E + return rune(0x212f), true + case "esdot": // APPROACHES THE LIMIT + return rune(0x2250), true + case "esim": // MINUS TILDE + return rune(0x2242), true + case "eta": // GREEK SMALL LETTER ETA + return rune(0x03b7), true + case "eth": // LATIN SMALL LETTER ETH + return rune(0xf0), true + case "euml": // LATIN SMALL LETTER E WITH DIAERESIS + return rune(0xeb), true + case "euro": // EURO SIGN + return rune(0x20ac), true + case "excl": // EXCLAMATION MARK + return rune(0x21), true + case "exist": // THERE EXISTS + return rune(0x2203), true + case "expectation": // SCRIPT CAPITAL E + return rune(0x2130), true + case "exponentiale": // DOUBLE-STRUCK ITALIC SMALL E + return rune(0x2147), true } case 'f': switch name { - case "fallingdotseq": // APPROXIMATELY EQUAL TO OR THE IMAGE OF - return rune(0x2252), true - case "fbowtie": // BLACK BOWTIE - return rune(0x29d3), true - case "fcy": // CYRILLIC SMALL LETTER EF - return rune(0x0444), true - case "fdiag": // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT - return rune(0x2572), true - case "fdiordi": // FALLING DIAGONAL CROSSING RISING DIAGONAL - return rune(0x292c), true - case "fdonearr": // FALLING DIAGONAL CROSSING NORTH EAST ARROW - return rune(0x292f), true - case "female": // FEMALE SIGN - return rune(0x2640), true - case "ffilig": // LATIN SMALL LIGATURE FFI - return rune(0xfb03), true - case "fflig": // LATIN SMALL LIGATURE FF - return rune(0xfb00), true - case "ffllig": // LATIN SMALL LIGATURE FFL - return rune(0xfb04), true - case "ffr": // MATHEMATICAL FRAKTUR SMALL F - return rune(0x01d523), true - case "fhrglass": // BLACK HOURGLASS - return rune(0x29d7), true - case "filig": // LATIN SMALL LIGATURE FI - return rune(0xfb01), true - case "fjlig": // fj ligature - return rune(0x66), true - case "flat": // MUSIC FLAT SIGN - return rune(0x266d), true - case "fllig": // LATIN SMALL LIGATURE FL - return rune(0xfb02), true - case "fltns": // WHITE PARALLELOGRAM - return rune(0x25b1), true - case "fnof": // LATIN SMALL LETTER F WITH HOOK - return rune(0x0192), true - case "fopf": // MATHEMATICAL DOUBLE-STRUCK SMALL F - return rune(0x01d557), true - case "forall": // FOR ALL - return rune(0x2200), true - case "fork": // PITCHFORK - return rune(0x22d4), true - case "forkv": // ELEMENT OF OPENING DOWNWARDS - return rune(0x2ad9), true - case "fpartint": // FINITE PART INTEGRAL - return rune(0x2a0d), true - case "frac12": // VULGAR FRACTION ONE HALF - return rune(0xbd), true - case "frac13": // VULGAR FRACTION ONE THIRD - return rune(0x2153), true - case "frac14": // VULGAR FRACTION ONE QUARTER - return rune(0xbc), true - case "frac15": // VULGAR FRACTION ONE FIFTH - return rune(0x2155), true - case "frac16": // VULGAR FRACTION ONE SIXTH - return rune(0x2159), true - case "frac18": // VULGAR FRACTION ONE EIGHTH - return rune(0x215b), true - case "frac23": // VULGAR FRACTION TWO THIRDS - return rune(0x2154), true - case "frac25": // VULGAR FRACTION TWO FIFTHS - return rune(0x2156), true - case "frac34": // VULGAR FRACTION THREE QUARTERS - return rune(0xbe), true - case "frac35": // VULGAR FRACTION THREE FIFTHS - return rune(0x2157), true - case "frac38": // VULGAR FRACTION THREE EIGHTHS - return rune(0x215c), true - case "frac45": // VULGAR FRACTION FOUR FIFTHS - return rune(0x2158), true - case "frac56": // VULGAR FRACTION FIVE SIXTHS - return rune(0x215a), true - case "frac58": // VULGAR FRACTION FIVE EIGHTHS - return rune(0x215d), true - case "frac78": // VULGAR FRACTION SEVEN EIGHTHS - return rune(0x215e), true - case "frasl": // FRACTION SLASH - return rune(0x2044), true - case "frown": // FROWN - return rune(0x2322), true - case "fscr": // MATHEMATICAL SCRIPT SMALL F - return rune(0x01d4bb), true + case "fallingdotseq": // APPROXIMATELY EQUAL TO OR THE IMAGE OF + return rune(0x2252), true + case "fbowtie": // BLACK BOWTIE + return rune(0x29d3), true + case "fcy": // CYRILLIC SMALL LETTER EF + return rune(0x0444), true + case "fdiag": // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT + return rune(0x2572), true + case "fdiordi": // FALLING DIAGONAL CROSSING RISING DIAGONAL + return rune(0x292c), true + case "fdonearr": // FALLING DIAGONAL CROSSING NORTH EAST ARROW + return rune(0x292f), true + case "female": // FEMALE SIGN + return rune(0x2640), true + case "ffilig": // LATIN SMALL LIGATURE FFI + return rune(0xfb03), true + case "fflig": // LATIN SMALL LIGATURE FF + return rune(0xfb00), true + case "ffllig": // LATIN SMALL LIGATURE FFL + return rune(0xfb04), true + case "ffr": // MATHEMATICAL FRAKTUR SMALL F + return rune(0x01d523), true + case "fhrglass": // BLACK HOURGLASS + return rune(0x29d7), true + case "filig": // LATIN SMALL LIGATURE FI + return rune(0xfb01), true + case "fjlig": // fj ligature + return rune(0x66), true + case "flat": // MUSIC FLAT SIGN + return rune(0x266d), true + case "fllig": // LATIN SMALL LIGATURE FL + return rune(0xfb02), true + case "fltns": // WHITE PARALLELOGRAM + return rune(0x25b1), true + case "fnof": // LATIN SMALL LETTER F WITH HOOK + return rune(0x0192), true + case "fopf": // MATHEMATICAL DOUBLE-STRUCK SMALL F + return rune(0x01d557), true + case "forall": // FOR ALL + return rune(0x2200), true + case "fork": // PITCHFORK + return rune(0x22d4), true + case "forkv": // ELEMENT OF OPENING DOWNWARDS + return rune(0x2ad9), true + case "fpartint": // FINITE PART INTEGRAL + return rune(0x2a0d), true + case "frac12": // VULGAR FRACTION ONE HALF + return rune(0xbd), true + case "frac13": // VULGAR FRACTION ONE THIRD + return rune(0x2153), true + case "frac14": // VULGAR FRACTION ONE QUARTER + return rune(0xbc), true + case "frac15": // VULGAR FRACTION ONE FIFTH + return rune(0x2155), true + case "frac16": // VULGAR FRACTION ONE SIXTH + return rune(0x2159), true + case "frac18": // VULGAR FRACTION ONE EIGHTH + return rune(0x215b), true + case "frac23": // VULGAR FRACTION TWO THIRDS + return rune(0x2154), true + case "frac25": // VULGAR FRACTION TWO FIFTHS + return rune(0x2156), true + case "frac34": // VULGAR FRACTION THREE QUARTERS + return rune(0xbe), true + case "frac35": // VULGAR FRACTION THREE FIFTHS + return rune(0x2157), true + case "frac38": // VULGAR FRACTION THREE EIGHTHS + return rune(0x215c), true + case "frac45": // VULGAR FRACTION FOUR FIFTHS + return rune(0x2158), true + case "frac56": // VULGAR FRACTION FIVE SIXTHS + return rune(0x215a), true + case "frac58": // VULGAR FRACTION FIVE EIGHTHS + return rune(0x215d), true + case "frac78": // VULGAR FRACTION SEVEN EIGHTHS + return rune(0x215e), true + case "frasl": // FRACTION SLASH + return rune(0x2044), true + case "frown": // FROWN + return rune(0x2322), true + case "fscr": // MATHEMATICAL SCRIPT SMALL F + return rune(0x01d4bb), true } case 'g': switch name { - case "gE": // GREATER-THAN OVER EQUAL TO - return rune(0x2267), true - case "gEl": // GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN - return rune(0x2a8c), true - case "gacute": // LATIN SMALL LETTER G WITH ACUTE - return rune(0x01f5), true - case "gamma": // GREEK SMALL LETTER GAMMA - return rune(0x03b3), true - case "gammad": // GREEK SMALL LETTER DIGAMMA - return rune(0x03dd), true - case "gap": // GREATER-THAN OR APPROXIMATE - return rune(0x2a86), true - case "gbreve": // LATIN SMALL LETTER G WITH BREVE - return rune(0x011f), true - case "gcedil": // LATIN SMALL LETTER G WITH CEDILLA - return rune(0x0123), true - case "gcirc": // LATIN SMALL LETTER G WITH CIRCUMFLEX - return rune(0x011d), true - case "gcy": // CYRILLIC SMALL LETTER GHE - return rune(0x0433), true - case "gdot": // LATIN SMALL LETTER G WITH DOT ABOVE - return rune(0x0121), true - case "ge": // GREATER-THAN OR EQUAL TO - return rune(0x2265), true - case "gel": // GREATER-THAN EQUAL TO OR LESS-THAN - return rune(0x22db), true - case "geq": // GREATER-THAN OR EQUAL TO - return rune(0x2265), true - case "geqq": // GREATER-THAN OVER EQUAL TO - return rune(0x2267), true - case "geqslant": // GREATER-THAN OR SLANTED EQUAL TO - return rune(0x2a7e), true - case "ges": // GREATER-THAN OR SLANTED EQUAL TO - return rune(0x2a7e), true - case "gescc": // GREATER-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL - return rune(0x2aa9), true - case "gesdot": // GREATER-THAN OR SLANTED EQUAL TO WITH DOT INSIDE - return rune(0x2a80), true - case "gesdoto": // GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE - return rune(0x2a82), true - case "gesdotol": // GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE LEFT - return rune(0x2a84), true - case "gesl": // GREATER-THAN slanted EQUAL TO OR LESS-THAN - return rune(0x22db), true - case "gesles": // GREATER-THAN ABOVE SLANTED EQUAL ABOVE LESS-THAN ABOVE SLANTED EQUAL - return rune(0x2a94), true - case "gfr": // MATHEMATICAL FRAKTUR SMALL G - return rune(0x01d524), true - case "gg": // MUCH GREATER-THAN - return rune(0x226b), true - case "ggg": // VERY MUCH GREATER-THAN - return rune(0x22d9), true - case "ggr": // GREEK SMALL LETTER GAMMA - return rune(0x03b3), true - case "gimel": // GIMEL SYMBOL - return rune(0x2137), true - case "gjcy": // CYRILLIC SMALL LETTER GJE - return rune(0x0453), true - case "gl": // GREATER-THAN OR LESS-THAN - return rune(0x2277), true - case "glE": // GREATER-THAN ABOVE LESS-THAN ABOVE DOUBLE-LINE EQUAL - return rune(0x2a92), true - case "gla": // GREATER-THAN BESIDE LESS-THAN - return rune(0x2aa5), true - case "glj": // GREATER-THAN OVERLAPPING LESS-THAN - return rune(0x2aa4), true - case "gnE": // GREATER-THAN BUT NOT EQUAL TO - return rune(0x2269), true - case "gnap": // GREATER-THAN AND NOT APPROXIMATE - return rune(0x2a8a), true - case "gnapprox": // GREATER-THAN AND NOT APPROXIMATE - return rune(0x2a8a), true - case "gne": // GREATER-THAN AND SINGLE-LINE NOT EQUAL TO - return rune(0x2a88), true - case "gneq": // GREATER-THAN AND SINGLE-LINE NOT EQUAL TO - return rune(0x2a88), true - case "gneqq": // GREATER-THAN BUT NOT EQUAL TO - return rune(0x2269), true - case "gnsim": // GREATER-THAN BUT NOT EQUIVALENT TO - return rune(0x22e7), true - case "gopf": // MATHEMATICAL DOUBLE-STRUCK SMALL G - return rune(0x01d558), true - case "grave": // GRAVE ACCENT - return rune(0x60), true - case "gscr": // SCRIPT SMALL G - return rune(0x210a), true - case "gsdot": // GREATER-THAN WITH DOT - return rune(0x22d7), true - case "gsim": // GREATER-THAN OR EQUIVALENT TO - return rune(0x2273), true - case "gsime": // GREATER-THAN ABOVE SIMILAR OR EQUAL - return rune(0x2a8e), true - case "gsiml": // GREATER-THAN ABOVE SIMILAR ABOVE LESS-THAN - return rune(0x2a90), true - case "gt": // GREATER-THAN SIGN - return rune(0x3e), true - case "gtcc": // GREATER-THAN CLOSED BY CURVE - return rune(0x2aa7), true - case "gtcir": // GREATER-THAN WITH CIRCLE INSIDE - return rune(0x2a7a), true - case "gtdot": // GREATER-THAN WITH DOT - return rune(0x22d7), true - case "gtlPar": // DOUBLE LEFT ARC GREATER-THAN BRACKET - return rune(0x2995), true - case "gtquest": // GREATER-THAN WITH QUESTION MARK ABOVE - return rune(0x2a7c), true - case "gtrapprox": // GREATER-THAN OR APPROXIMATE - return rune(0x2a86), true - case "gtrarr": // GREATER-THAN ABOVE RIGHTWARDS ARROW - return rune(0x2978), true - case "gtrdot": // GREATER-THAN WITH DOT - return rune(0x22d7), true - case "gtreqless": // GREATER-THAN EQUAL TO OR LESS-THAN - return rune(0x22db), true - case "gtreqqless": // GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN - return rune(0x2a8c), true - case "gtrless": // GREATER-THAN OR LESS-THAN - return rune(0x2277), true - case "gtrpar": // SPHERICAL ANGLE OPENING LEFT - return rune(0x29a0), true - case "gtrsim": // GREATER-THAN OR EQUIVALENT TO - return rune(0x2273), true - case "gvertneqq": // GREATER-THAN BUT NOT EQUAL TO - with vertical stroke - return rune(0x2269), true - case "gvnE": // GREATER-THAN BUT NOT EQUAL TO - with vertical stroke - return rune(0x2269), true + case "gE": // GREATER-THAN OVER EQUAL TO + return rune(0x2267), true + case "gEl": // GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN + return rune(0x2a8c), true + case "gacute": // LATIN SMALL LETTER G WITH ACUTE + return rune(0x01f5), true + case "gamma": // GREEK SMALL LETTER GAMMA + return rune(0x03b3), true + case "gammad": // GREEK SMALL LETTER DIGAMMA + return rune(0x03dd), true + case "gap": // GREATER-THAN OR APPROXIMATE + return rune(0x2a86), true + case "gbreve": // LATIN SMALL LETTER G WITH BREVE + return rune(0x011f), true + case "gcedil": // LATIN SMALL LETTER G WITH CEDILLA + return rune(0x0123), true + case "gcirc": // LATIN SMALL LETTER G WITH CIRCUMFLEX + return rune(0x011d), true + case "gcy": // CYRILLIC SMALL LETTER GHE + return rune(0x0433), true + case "gdot": // LATIN SMALL LETTER G WITH DOT ABOVE + return rune(0x0121), true + case "ge": // GREATER-THAN OR EQUAL TO + return rune(0x2265), true + case "gel": // GREATER-THAN EQUAL TO OR LESS-THAN + return rune(0x22db), true + case "geq": // GREATER-THAN OR EQUAL TO + return rune(0x2265), true + case "geqq": // GREATER-THAN OVER EQUAL TO + return rune(0x2267), true + case "geqslant": // GREATER-THAN OR SLANTED EQUAL TO + return rune(0x2a7e), true + case "ges": // GREATER-THAN OR SLANTED EQUAL TO + return rune(0x2a7e), true + case "gescc": // GREATER-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL + return rune(0x2aa9), true + case "gesdot": // GREATER-THAN OR SLANTED EQUAL TO WITH DOT INSIDE + return rune(0x2a80), true + case "gesdoto": // GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE + return rune(0x2a82), true + case "gesdotol": // GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE LEFT + return rune(0x2a84), true + case "gesl": // GREATER-THAN slanted EQUAL TO OR LESS-THAN + return rune(0x22db), true + case "gesles": // GREATER-THAN ABOVE SLANTED EQUAL ABOVE LESS-THAN ABOVE SLANTED EQUAL + return rune(0x2a94), true + case "gfr": // MATHEMATICAL FRAKTUR SMALL G + return rune(0x01d524), true + case "gg": // MUCH GREATER-THAN + return rune(0x226b), true + case "ggg": // VERY MUCH GREATER-THAN + return rune(0x22d9), true + case "ggr": // GREEK SMALL LETTER GAMMA + return rune(0x03b3), true + case "gimel": // GIMEL SYMBOL + return rune(0x2137), true + case "gjcy": // CYRILLIC SMALL LETTER GJE + return rune(0x0453), true + case "gl": // GREATER-THAN OR LESS-THAN + return rune(0x2277), true + case "glE": // GREATER-THAN ABOVE LESS-THAN ABOVE DOUBLE-LINE EQUAL + return rune(0x2a92), true + case "gla": // GREATER-THAN BESIDE LESS-THAN + return rune(0x2aa5), true + case "glj": // GREATER-THAN OVERLAPPING LESS-THAN + return rune(0x2aa4), true + case "gnE": // GREATER-THAN BUT NOT EQUAL TO + return rune(0x2269), true + case "gnap": // GREATER-THAN AND NOT APPROXIMATE + return rune(0x2a8a), true + case "gnapprox": // GREATER-THAN AND NOT APPROXIMATE + return rune(0x2a8a), true + case "gne": // GREATER-THAN AND SINGLE-LINE NOT EQUAL TO + return rune(0x2a88), true + case "gneq": // GREATER-THAN AND SINGLE-LINE NOT EQUAL TO + return rune(0x2a88), true + case "gneqq": // GREATER-THAN BUT NOT EQUAL TO + return rune(0x2269), true + case "gnsim": // GREATER-THAN BUT NOT EQUIVALENT TO + return rune(0x22e7), true + case "gopf": // MATHEMATICAL DOUBLE-STRUCK SMALL G + return rune(0x01d558), true + case "grave": // GRAVE ACCENT + return rune(0x60), true + case "gscr": // SCRIPT SMALL G + return rune(0x210a), true + case "gsdot": // GREATER-THAN WITH DOT + return rune(0x22d7), true + case "gsim": // GREATER-THAN OR EQUIVALENT TO + return rune(0x2273), true + case "gsime": // GREATER-THAN ABOVE SIMILAR OR EQUAL + return rune(0x2a8e), true + case "gsiml": // GREATER-THAN ABOVE SIMILAR ABOVE LESS-THAN + return rune(0x2a90), true + case "gt": // GREATER-THAN SIGN + return rune(0x3e), true + case "gtcc": // GREATER-THAN CLOSED BY CURVE + return rune(0x2aa7), true + case "gtcir": // GREATER-THAN WITH CIRCLE INSIDE + return rune(0x2a7a), true + case "gtdot": // GREATER-THAN WITH DOT + return rune(0x22d7), true + case "gtlPar": // DOUBLE LEFT ARC GREATER-THAN BRACKET + return rune(0x2995), true + case "gtquest": // GREATER-THAN WITH QUESTION MARK ABOVE + return rune(0x2a7c), true + case "gtrapprox": // GREATER-THAN OR APPROXIMATE + return rune(0x2a86), true + case "gtrarr": // GREATER-THAN ABOVE RIGHTWARDS ARROW + return rune(0x2978), true + case "gtrdot": // GREATER-THAN WITH DOT + return rune(0x22d7), true + case "gtreqless": // GREATER-THAN EQUAL TO OR LESS-THAN + return rune(0x22db), true + case "gtreqqless": // GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN + return rune(0x2a8c), true + case "gtrless": // GREATER-THAN OR LESS-THAN + return rune(0x2277), true + case "gtrpar": // SPHERICAL ANGLE OPENING LEFT + return rune(0x29a0), true + case "gtrsim": // GREATER-THAN OR EQUIVALENT TO + return rune(0x2273), true + case "gvertneqq": // GREATER-THAN BUT NOT EQUAL TO - with vertical stroke + return rune(0x2269), true + case "gvnE": // GREATER-THAN BUT NOT EQUAL TO - with vertical stroke + return rune(0x2269), true } case 'h': switch name { - case "hArr": // LEFT RIGHT DOUBLE ARROW - return rune(0x21d4), true - case "hairsp": // HAIR SPACE - return rune(0x200a), true - case "half": // VULGAR FRACTION ONE HALF - return rune(0xbd), true - case "hamilt": // SCRIPT CAPITAL H - return rune(0x210b), true - case "hardcy": // CYRILLIC SMALL LETTER HARD SIGN - return rune(0x044a), true - case "harr": // LEFT RIGHT ARROW - return rune(0x2194), true - case "harrcir": // LEFT RIGHT ARROW THROUGH SMALL CIRCLE - return rune(0x2948), true - case "harrw": // LEFT RIGHT WAVE ARROW - return rune(0x21ad), true - case "hbar": // PLANCK CONSTANT OVER TWO PI - return rune(0x210f), true - case "hcirc": // LATIN SMALL LETTER H WITH CIRCUMFLEX - return rune(0x0125), true - case "hearts": // BLACK HEART SUIT - return rune(0x2665), true - case "heartsuit": // BLACK HEART SUIT - return rune(0x2665), true - case "hellip": // HORIZONTAL ELLIPSIS - return rune(0x2026), true - case "hercon": // HERMITIAN CONJUGATE MATRIX - return rune(0x22b9), true - case "hfr": // MATHEMATICAL FRAKTUR SMALL H - return rune(0x01d525), true - case "hksearow": // SOUTH EAST ARROW WITH HOOK - return rune(0x2925), true - case "hkswarow": // SOUTH WEST ARROW WITH HOOK - return rune(0x2926), true - case "hoarr": // LEFT RIGHT OPEN-HEADED ARROW - return rune(0x21ff), true - case "homtht": // HOMOTHETIC - return rune(0x223b), true - case "hookleftarrow": // LEFTWARDS ARROW WITH HOOK - return rune(0x21a9), true - case "hookrightarrow": // RIGHTWARDS ARROW WITH HOOK - return rune(0x21aa), true - case "hopf": // MATHEMATICAL DOUBLE-STRUCK SMALL H - return rune(0x01d559), true - case "horbar": // HORIZONTAL BAR - return rune(0x2015), true - case "hrglass": // WHITE HOURGLASS - return rune(0x29d6), true - case "hscr": // MATHEMATICAL SCRIPT SMALL H - return rune(0x01d4bd), true - case "hslash": // PLANCK CONSTANT OVER TWO PI - return rune(0x210f), true - case "hstrok": // LATIN SMALL LETTER H WITH STROKE - return rune(0x0127), true - case "htimes": // VECTOR OR CROSS PRODUCT - return rune(0x2a2f), true - case "hybull": // HYPHEN BULLET - return rune(0x2043), true - case "hyphen": // HYPHEN - return rune(0x2010), true + case "hArr": // LEFT RIGHT DOUBLE ARROW + return rune(0x21d4), true + case "hairsp": // HAIR SPACE + return rune(0x200a), true + case "half": // VULGAR FRACTION ONE HALF + return rune(0xbd), true + case "hamilt": // SCRIPT CAPITAL H + return rune(0x210b), true + case "hardcy": // CYRILLIC SMALL LETTER HARD SIGN + return rune(0x044a), true + case "harr": // LEFT RIGHT ARROW + return rune(0x2194), true + case "harrcir": // LEFT RIGHT ARROW THROUGH SMALL CIRCLE + return rune(0x2948), true + case "harrw": // LEFT RIGHT WAVE ARROW + return rune(0x21ad), true + case "hbar": // PLANCK CONSTANT OVER TWO PI + return rune(0x210f), true + case "hcirc": // LATIN SMALL LETTER H WITH CIRCUMFLEX + return rune(0x0125), true + case "hearts": // BLACK HEART SUIT + return rune(0x2665), true + case "heartsuit": // BLACK HEART SUIT + return rune(0x2665), true + case "hellip": // HORIZONTAL ELLIPSIS + return rune(0x2026), true + case "hercon": // HERMITIAN CONJUGATE MATRIX + return rune(0x22b9), true + case "hfr": // MATHEMATICAL FRAKTUR SMALL H + return rune(0x01d525), true + case "hksearow": // SOUTH EAST ARROW WITH HOOK + return rune(0x2925), true + case "hkswarow": // SOUTH WEST ARROW WITH HOOK + return rune(0x2926), true + case "hoarr": // LEFT RIGHT OPEN-HEADED ARROW + return rune(0x21ff), true + case "homtht": // HOMOTHETIC + return rune(0x223b), true + case "hookleftarrow": // LEFTWARDS ARROW WITH HOOK + return rune(0x21a9), true + case "hookrightarrow": // RIGHTWARDS ARROW WITH HOOK + return rune(0x21aa), true + case "hopf": // MATHEMATICAL DOUBLE-STRUCK SMALL H + return rune(0x01d559), true + case "horbar": // HORIZONTAL BAR + return rune(0x2015), true + case "hrglass": // WHITE HOURGLASS + return rune(0x29d6), true + case "hscr": // MATHEMATICAL SCRIPT SMALL H + return rune(0x01d4bd), true + case "hslash": // PLANCK CONSTANT OVER TWO PI + return rune(0x210f), true + case "hstrok": // LATIN SMALL LETTER H WITH STROKE + return rune(0x0127), true + case "htimes": // VECTOR OR CROSS PRODUCT + return rune(0x2a2f), true + case "hybull": // HYPHEN BULLET + return rune(0x2043), true + case "hyphen": // HYPHEN + return rune(0x2010), true } case 'i': switch name { - case "iacgr": // GREEK SMALL LETTER IOTA WITH TONOS - return rune(0x03af), true - case "iacute": // LATIN SMALL LETTER I WITH ACUTE - return rune(0xed), true - case "ic": // INVISIBLE SEPARATOR - return rune(0x2063), true - case "icirc": // LATIN SMALL LETTER I WITH CIRCUMFLEX - return rune(0xee), true - case "icy": // CYRILLIC SMALL LETTER I - return rune(0x0438), true - case "idiagr": // GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS - return rune(0x0390), true - case "idigr": // GREEK SMALL LETTER IOTA WITH DIALYTIKA - return rune(0x03ca), true - case "iecy": // CYRILLIC SMALL LETTER IE - return rune(0x0435), true - case "iexcl": // INVERTED EXCLAMATION MARK - return rune(0xa1), true - case "iff": // LEFT RIGHT DOUBLE ARROW - return rune(0x21d4), true - case "ifr": // MATHEMATICAL FRAKTUR SMALL I - return rune(0x01d526), true - case "igr": // GREEK SMALL LETTER IOTA - return rune(0x03b9), true - case "igrave": // LATIN SMALL LETTER I WITH GRAVE - return rune(0xec), true - case "ii": // DOUBLE-STRUCK ITALIC SMALL I - return rune(0x2148), true - case "iiiint": // QUADRUPLE INTEGRAL OPERATOR - return rune(0x2a0c), true - case "iiint": // TRIPLE INTEGRAL - return rune(0x222d), true - case "iinfin": // INCOMPLETE INFINITY - return rune(0x29dc), true - case "iiota": // TURNED GREEK SMALL LETTER IOTA - return rune(0x2129), true - case "ijlig": // LATIN SMALL LIGATURE IJ - return rune(0x0133), true - case "imacr": // LATIN SMALL LETTER I WITH MACRON - return rune(0x012b), true - case "image": // BLACK-LETTER CAPITAL I - return rune(0x2111), true - case "imagline": // SCRIPT CAPITAL I - return rune(0x2110), true - case "imagpart": // BLACK-LETTER CAPITAL I - return rune(0x2111), true - case "imath": // LATIN SMALL LETTER DOTLESS I - return rune(0x0131), true - case "imof": // IMAGE OF - return rune(0x22b7), true - case "imped": // LATIN CAPITAL LETTER Z WITH STROKE - return rune(0x01b5), true - case "in": // ELEMENT OF - return rune(0x2208), true - case "incare": // CARE OF - return rune(0x2105), true - case "infin": // INFINITY - return rune(0x221e), true - case "infintie": // TIE OVER INFINITY - return rune(0x29dd), true - case "inodot": // LATIN SMALL LETTER DOTLESS I - return rune(0x0131), true - case "int": // INTEGRAL - return rune(0x222b), true - case "intcal": // INTERCALATE - return rune(0x22ba), true - case "integers": // DOUBLE-STRUCK CAPITAL Z - return rune(0x2124), true - case "intercal": // INTERCALATE - return rune(0x22ba), true - case "intlarhk": // INTEGRAL WITH LEFTWARDS ARROW WITH HOOK - return rune(0x2a17), true - case "intprod": // INTERIOR PRODUCT - return rune(0x2a3c), true - case "iocy": // CYRILLIC SMALL LETTER IO - return rune(0x0451), true - case "iogon": // LATIN SMALL LETTER I WITH OGONEK - return rune(0x012f), true - case "iopf": // MATHEMATICAL DOUBLE-STRUCK SMALL I - return rune(0x01d55a), true - case "iota": // GREEK SMALL LETTER IOTA - return rune(0x03b9), true - case "iprod": // INTERIOR PRODUCT - return rune(0x2a3c), true - case "iprodr": // RIGHTHAND INTERIOR PRODUCT - return rune(0x2a3d), true - case "iquest": // INVERTED QUESTION MARK - return rune(0xbf), true - case "iscr": // MATHEMATICAL SCRIPT SMALL I - return rune(0x01d4be), true - case "isin": // ELEMENT OF - return rune(0x2208), true - case "isinE": // ELEMENT OF WITH TWO HORIZONTAL STROKES - return rune(0x22f9), true - case "isindot": // ELEMENT OF WITH DOT ABOVE - return rune(0x22f5), true - case "isins": // SMALL ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE - return rune(0x22f4), true - case "isinsv": // ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE - return rune(0x22f3), true - case "isinv": // ELEMENT OF - return rune(0x2208), true - case "isinvb": // ELEMENT OF WITH UNDERBAR - return rune(0x22f8), true - case "it": // INVISIBLE TIMES - return rune(0x2062), true - case "itilde": // LATIN SMALL LETTER I WITH TILDE - return rune(0x0129), true - case "iukcy": // CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I - return rune(0x0456), true - case "iuml": // LATIN SMALL LETTER I WITH DIAERESIS - return rune(0xef), true + case "iacgr": // GREEK SMALL LETTER IOTA WITH TONOS + return rune(0x03af), true + case "iacute": // LATIN SMALL LETTER I WITH ACUTE + return rune(0xed), true + case "ic": // INVISIBLE SEPARATOR + return rune(0x2063), true + case "icirc": // LATIN SMALL LETTER I WITH CIRCUMFLEX + return rune(0xee), true + case "icy": // CYRILLIC SMALL LETTER I + return rune(0x0438), true + case "idiagr": // GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS + return rune(0x0390), true + case "idigr": // GREEK SMALL LETTER IOTA WITH DIALYTIKA + return rune(0x03ca), true + case "iecy": // CYRILLIC SMALL LETTER IE + return rune(0x0435), true + case "iexcl": // INVERTED EXCLAMATION MARK + return rune(0xa1), true + case "iff": // LEFT RIGHT DOUBLE ARROW + return rune(0x21d4), true + case "ifr": // MATHEMATICAL FRAKTUR SMALL I + return rune(0x01d526), true + case "igr": // GREEK SMALL LETTER IOTA + return rune(0x03b9), true + case "igrave": // LATIN SMALL LETTER I WITH GRAVE + return rune(0xec), true + case "ii": // DOUBLE-STRUCK ITALIC SMALL I + return rune(0x2148), true + case "iiiint": // QUADRUPLE INTEGRAL OPERATOR + return rune(0x2a0c), true + case "iiint": // TRIPLE INTEGRAL + return rune(0x222d), true + case "iinfin": // INCOMPLETE INFINITY + return rune(0x29dc), true + case "iiota": // TURNED GREEK SMALL LETTER IOTA + return rune(0x2129), true + case "ijlig": // LATIN SMALL LIGATURE IJ + return rune(0x0133), true + case "imacr": // LATIN SMALL LETTER I WITH MACRON + return rune(0x012b), true + case "image": // BLACK-LETTER CAPITAL I + return rune(0x2111), true + case "imagline": // SCRIPT CAPITAL I + return rune(0x2110), true + case "imagpart": // BLACK-LETTER CAPITAL I + return rune(0x2111), true + case "imath": // LATIN SMALL LETTER DOTLESS I + return rune(0x0131), true + case "imof": // IMAGE OF + return rune(0x22b7), true + case "imped": // LATIN CAPITAL LETTER Z WITH STROKE + return rune(0x01b5), true + case "in": // ELEMENT OF + return rune(0x2208), true + case "incare": // CARE OF + return rune(0x2105), true + case "infin": // INFINITY + return rune(0x221e), true + case "infintie": // TIE OVER INFINITY + return rune(0x29dd), true + case "inodot": // LATIN SMALL LETTER DOTLESS I + return rune(0x0131), true + case "int": // INTEGRAL + return rune(0x222b), true + case "intcal": // INTERCALATE + return rune(0x22ba), true + case "integers": // DOUBLE-STRUCK CAPITAL Z + return rune(0x2124), true + case "intercal": // INTERCALATE + return rune(0x22ba), true + case "intlarhk": // INTEGRAL WITH LEFTWARDS ARROW WITH HOOK + return rune(0x2a17), true + case "intprod": // INTERIOR PRODUCT + return rune(0x2a3c), true + case "iocy": // CYRILLIC SMALL LETTER IO + return rune(0x0451), true + case "iogon": // LATIN SMALL LETTER I WITH OGONEK + return rune(0x012f), true + case "iopf": // MATHEMATICAL DOUBLE-STRUCK SMALL I + return rune(0x01d55a), true + case "iota": // GREEK SMALL LETTER IOTA + return rune(0x03b9), true + case "iprod": // INTERIOR PRODUCT + return rune(0x2a3c), true + case "iprodr": // RIGHTHAND INTERIOR PRODUCT + return rune(0x2a3d), true + case "iquest": // INVERTED QUESTION MARK + return rune(0xbf), true + case "iscr": // MATHEMATICAL SCRIPT SMALL I + return rune(0x01d4be), true + case "isin": // ELEMENT OF + return rune(0x2208), true + case "isinE": // ELEMENT OF WITH TWO HORIZONTAL STROKES + return rune(0x22f9), true + case "isindot": // ELEMENT OF WITH DOT ABOVE + return rune(0x22f5), true + case "isins": // SMALL ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE + return rune(0x22f4), true + case "isinsv": // ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE + return rune(0x22f3), true + case "isinv": // ELEMENT OF + return rune(0x2208), true + case "isinvb": // ELEMENT OF WITH UNDERBAR + return rune(0x22f8), true + case "it": // INVISIBLE TIMES + return rune(0x2062), true + case "itilde": // LATIN SMALL LETTER I WITH TILDE + return rune(0x0129), true + case "iukcy": // CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + return rune(0x0456), true + case "iuml": // LATIN SMALL LETTER I WITH DIAERESIS + return rune(0xef), true } case 'j': switch name { - case "jcirc": // LATIN SMALL LETTER J WITH CIRCUMFLEX - return rune(0x0135), true - case "jcy": // CYRILLIC SMALL LETTER SHORT I - return rune(0x0439), true - case "jfr": // MATHEMATICAL FRAKTUR SMALL J - return rune(0x01d527), true - case "jmath": // LATIN SMALL LETTER DOTLESS J - return rune(0x0237), true - case "jnodot": // LATIN SMALL LETTER DOTLESS J - return rune(0x0237), true - case "jopf": // MATHEMATICAL DOUBLE-STRUCK SMALL J - return rune(0x01d55b), true - case "jscr": // MATHEMATICAL SCRIPT SMALL J - return rune(0x01d4bf), true - case "jsercy": // CYRILLIC SMALL LETTER JE - return rune(0x0458), true - case "jukcy": // CYRILLIC SMALL LETTER UKRAINIAN IE - return rune(0x0454), true + case "jcirc": // LATIN SMALL LETTER J WITH CIRCUMFLEX + return rune(0x0135), true + case "jcy": // CYRILLIC SMALL LETTER SHORT I + return rune(0x0439), true + case "jfr": // MATHEMATICAL FRAKTUR SMALL J + return rune(0x01d527), true + case "jmath": // LATIN SMALL LETTER DOTLESS J + return rune(0x0237), true + case "jnodot": // LATIN SMALL LETTER DOTLESS J + return rune(0x0237), true + case "jopf": // MATHEMATICAL DOUBLE-STRUCK SMALL J + return rune(0x01d55b), true + case "jscr": // MATHEMATICAL SCRIPT SMALL J + return rune(0x01d4bf), true + case "jsercy": // CYRILLIC SMALL LETTER JE + return rune(0x0458), true + case "jukcy": // CYRILLIC SMALL LETTER UKRAINIAN IE + return rune(0x0454), true } case 'k': switch name { - case "kappa": // GREEK SMALL LETTER KAPPA - return rune(0x03ba), true - case "kappav": // GREEK KAPPA SYMBOL - return rune(0x03f0), true - case "kcedil": // LATIN SMALL LETTER K WITH CEDILLA - return rune(0x0137), true - case "kcy": // CYRILLIC SMALL LETTER KA - return rune(0x043a), true - case "kfr": // MATHEMATICAL FRAKTUR SMALL K - return rune(0x01d528), true - case "kgr": // GREEK SMALL LETTER KAPPA - return rune(0x03ba), true - case "kgreen": // LATIN SMALL LETTER KRA - return rune(0x0138), true - case "khcy": // CYRILLIC SMALL LETTER HA - return rune(0x0445), true - case "khgr": // GREEK SMALL LETTER CHI - return rune(0x03c7), true - case "kjcy": // CYRILLIC SMALL LETTER KJE - return rune(0x045c), true - case "kopf": // MATHEMATICAL DOUBLE-STRUCK SMALL K - return rune(0x01d55c), true - case "koppa": // GREEK LETTER KOPPA - return rune(0x03de), true - case "kscr": // MATHEMATICAL SCRIPT SMALL K - return rune(0x01d4c0), true + case "kappa": // GREEK SMALL LETTER KAPPA + return rune(0x03ba), true + case "kappav": // GREEK KAPPA SYMBOL + return rune(0x03f0), true + case "kcedil": // LATIN SMALL LETTER K WITH CEDILLA + return rune(0x0137), true + case "kcy": // CYRILLIC SMALL LETTER KA + return rune(0x043a), true + case "kfr": // MATHEMATICAL FRAKTUR SMALL K + return rune(0x01d528), true + case "kgr": // GREEK SMALL LETTER KAPPA + return rune(0x03ba), true + case "kgreen": // LATIN SMALL LETTER KRA + return rune(0x0138), true + case "khcy": // CYRILLIC SMALL LETTER HA + return rune(0x0445), true + case "khgr": // GREEK SMALL LETTER CHI + return rune(0x03c7), true + case "kjcy": // CYRILLIC SMALL LETTER KJE + return rune(0x045c), true + case "kopf": // MATHEMATICAL DOUBLE-STRUCK SMALL K + return rune(0x01d55c), true + case "koppa": // GREEK LETTER KOPPA + return rune(0x03de), true + case "kscr": // MATHEMATICAL SCRIPT SMALL K + return rune(0x01d4c0), true } case 'l': switch name { - case "lAarr": // LEFTWARDS TRIPLE ARROW - return rune(0x21da), true - case "lArr": // LEFTWARDS DOUBLE ARROW - return rune(0x21d0), true - case "lAtail": // LEFTWARDS DOUBLE ARROW-TAIL - return rune(0x291b), true - case "lBarr": // LEFTWARDS TRIPLE DASH ARROW - return rune(0x290e), true - case "lE": // LESS-THAN OVER EQUAL TO - return rune(0x2266), true - case "lEg": // LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN - return rune(0x2a8b), true - case "lHar": // LEFTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB DOWN - return rune(0x2962), true - case "lacute": // LATIN SMALL LETTER L WITH ACUTE - return rune(0x013a), true - case "laemptyv": // EMPTY SET WITH LEFT ARROW ABOVE - return rune(0x29b4), true - case "lagran": // SCRIPT CAPITAL L - return rune(0x2112), true - case "lambda": // GREEK SMALL LETTER LAMDA - return rune(0x03bb), true - case "lang": // MATHEMATICAL LEFT ANGLE BRACKET - return rune(0x27e8), true - case "langd": // LEFT ANGLE BRACKET WITH DOT - return rune(0x2991), true - case "langle": // MATHEMATICAL LEFT ANGLE BRACKET - return rune(0x27e8), true - case "lap": // LESS-THAN OR APPROXIMATE - return rune(0x2a85), true - case "laquo": // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - return rune(0xab), true - case "larr": // LEFTWARDS ARROW - return rune(0x2190), true - case "larr2": // LEFTWARDS PAIRED ARROWS - return rune(0x21c7), true - case "larrb": // LEFTWARDS ARROW TO BAR - return rune(0x21e4), true - case "larrbfs": // LEFTWARDS ARROW FROM BAR TO BLACK DIAMOND - return rune(0x291f), true - case "larrfs": // LEFTWARDS ARROW TO BLACK DIAMOND - return rune(0x291d), true - case "larrhk": // LEFTWARDS ARROW WITH HOOK - return rune(0x21a9), true - case "larrlp": // LEFTWARDS ARROW WITH LOOP - return rune(0x21ab), true - case "larrpl": // LEFT-SIDE ARC ANTICLOCKWISE ARROW - return rune(0x2939), true - case "larrsim": // LEFTWARDS ARROW ABOVE TILDE OPERATOR - return rune(0x2973), true - case "larrtl": // LEFTWARDS ARROW WITH TAIL - return rune(0x21a2), true - case "lat": // LARGER THAN - return rune(0x2aab), true - case "latail": // LEFTWARDS ARROW-TAIL - return rune(0x2919), true - case "late": // LARGER THAN OR EQUAL TO - return rune(0x2aad), true - case "lates": // LARGER THAN OR slanted EQUAL - return rune(0x2aad), true - case "lbarr": // LEFTWARDS DOUBLE DASH ARROW - return rune(0x290c), true - case "lbbrk": // LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT - return rune(0x2772), true - case "lbrace": // LEFT CURLY BRACKET - return rune(0x7b), true - case "lbrack": // LEFT SQUARE BRACKET - return rune(0x5b), true - case "lbrke": // LEFT SQUARE BRACKET WITH UNDERBAR - return rune(0x298b), true - case "lbrksld": // LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER - return rune(0x298f), true - case "lbrkslu": // LEFT SQUARE BRACKET WITH TICK IN TOP CORNER - return rune(0x298d), true - case "lcaron": // LATIN SMALL LETTER L WITH CARON - return rune(0x013e), true - case "lcedil": // LATIN SMALL LETTER L WITH CEDILLA - return rune(0x013c), true - case "lceil": // LEFT CEILING - return rune(0x2308), true - case "lcub": // LEFT CURLY BRACKET - return rune(0x7b), true - case "lcy": // CYRILLIC SMALL LETTER EL - return rune(0x043b), true - case "ldca": // ARROW POINTING DOWNWARDS THEN CURVING LEFTWARDS - return rune(0x2936), true - case "ldharb": // LEFTWARDS HARPOON WITH BARB DOWN TO BAR - return rune(0x2956), true - case "ldot": // LESS-THAN WITH DOT - return rune(0x22d6), true - case "ldquo": // LEFT DOUBLE QUOTATION MARK - return rune(0x201c), true - case "ldquor": // DOUBLE LOW-9 QUOTATION MARK - return rune(0x201e), true - case "ldrdhar": // LEFTWARDS HARPOON WITH BARB DOWN ABOVE RIGHTWARDS HARPOON WITH BARB DOWN - return rune(0x2967), true - case "ldrdshar": // LEFT BARB DOWN RIGHT BARB DOWN HARPOON - return rune(0x2950), true - case "ldrushar": // LEFT BARB DOWN RIGHT BARB UP HARPOON - return rune(0x294b), true - case "ldsh": // DOWNWARDS ARROW WITH TIP LEFTWARDS - return rune(0x21b2), true - case "le": // LESS-THAN OR EQUAL TO - return rune(0x2264), true - case "leftarrow": // LEFTWARDS ARROW - return rune(0x2190), true - case "leftarrowtail": // LEFTWARDS ARROW WITH TAIL - return rune(0x21a2), true - case "leftharpoondown": // LEFTWARDS HARPOON WITH BARB DOWNWARDS - return rune(0x21bd), true - case "leftharpoonup": // LEFTWARDS HARPOON WITH BARB UPWARDS - return rune(0x21bc), true - case "leftleftarrows": // LEFTWARDS PAIRED ARROWS - return rune(0x21c7), true - case "leftrightarrow": // LEFT RIGHT ARROW - return rune(0x2194), true - case "leftrightarrows": // LEFTWARDS ARROW OVER RIGHTWARDS ARROW - return rune(0x21c6), true - case "leftrightharpoons": // LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON - return rune(0x21cb), true - case "leftrightsquigarrow": // LEFT RIGHT WAVE ARROW - return rune(0x21ad), true - case "leftthreetimes": // LEFT SEMIDIRECT PRODUCT - return rune(0x22cb), true - case "leg": // LESS-THAN EQUAL TO OR GREATER-THAN - return rune(0x22da), true - case "leq": // LESS-THAN OR EQUAL TO - return rune(0x2264), true - case "leqq": // LESS-THAN OVER EQUAL TO - return rune(0x2266), true - case "leqslant": // LESS-THAN OR SLANTED EQUAL TO - return rune(0x2a7d), true - case "les": // LESS-THAN OR SLANTED EQUAL TO - return rune(0x2a7d), true - case "lescc": // LESS-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL - return rune(0x2aa8), true - case "lesdot": // LESS-THAN OR SLANTED EQUAL TO WITH DOT INSIDE - return rune(0x2a7f), true - case "lesdoto": // LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE - return rune(0x2a81), true - case "lesdotor": // LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE RIGHT - return rune(0x2a83), true - case "lesg": // LESS-THAN slanted EQUAL TO OR GREATER-THAN - return rune(0x22da), true - case "lesges": // LESS-THAN ABOVE SLANTED EQUAL ABOVE GREATER-THAN ABOVE SLANTED EQUAL - return rune(0x2a93), true - case "lessapprox": // LESS-THAN OR APPROXIMATE - return rune(0x2a85), true - case "lessdot": // LESS-THAN WITH DOT - return rune(0x22d6), true - case "lesseqgtr": // LESS-THAN EQUAL TO OR GREATER-THAN - return rune(0x22da), true - case "lesseqqgtr": // LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN - return rune(0x2a8b), true - case "lessgtr": // LESS-THAN OR GREATER-THAN - return rune(0x2276), true - case "lesssim": // LESS-THAN OR EQUIVALENT TO - return rune(0x2272), true - case "lfbowtie": // BOWTIE WITH LEFT HALF BLACK - return rune(0x29d1), true - case "lfisht": // LEFT FISH TAIL - return rune(0x297c), true - case "lfloor": // LEFT FLOOR - return rune(0x230a), true - case "lfr": // MATHEMATICAL FRAKTUR SMALL L - return rune(0x01d529), true - case "lftimes": // TIMES WITH LEFT HALF BLACK - return rune(0x29d4), true - case "lg": // LESS-THAN OR GREATER-THAN - return rune(0x2276), true - case "lgE": // LESS-THAN ABOVE GREATER-THAN ABOVE DOUBLE-LINE EQUAL - return rune(0x2a91), true - case "lgr": // GREEK SMALL LETTER LAMDA - return rune(0x03bb), true - case "lhard": // LEFTWARDS HARPOON WITH BARB DOWNWARDS - return rune(0x21bd), true - case "lharu": // LEFTWARDS HARPOON WITH BARB UPWARDS - return rune(0x21bc), true - case "lharul": // LEFTWARDS HARPOON WITH BARB UP ABOVE LONG DASH - return rune(0x296a), true - case "lhblk": // LOWER HALF BLOCK - return rune(0x2584), true - case "ljcy": // CYRILLIC SMALL LETTER LJE - return rune(0x0459), true - case "ll": // MUCH LESS-THAN - return rune(0x226a), true - case "llarr": // LEFTWARDS PAIRED ARROWS - return rune(0x21c7), true - case "llcorner": // BOTTOM LEFT CORNER - return rune(0x231e), true - case "llhard": // LEFTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH - return rune(0x296b), true - case "lltri": // LOWER LEFT TRIANGLE - return rune(0x25fa), true - case "lltrif": // BLACK LOWER LEFT TRIANGLE - return rune(0x25e3), true - case "lmidot": // LATIN SMALL LETTER L WITH MIDDLE DOT - return rune(0x0140), true - case "lmoust": // UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION - return rune(0x23b0), true - case "lmoustache": // UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION - return rune(0x23b0), true - case "lnE": // LESS-THAN BUT NOT EQUAL TO - return rune(0x2268), true - case "lnap": // LESS-THAN AND NOT APPROXIMATE - return rune(0x2a89), true - case "lnapprox": // LESS-THAN AND NOT APPROXIMATE - return rune(0x2a89), true - case "lne": // LESS-THAN AND SINGLE-LINE NOT EQUAL TO - return rune(0x2a87), true - case "lneq": // LESS-THAN AND SINGLE-LINE NOT EQUAL TO - return rune(0x2a87), true - case "lneqq": // LESS-THAN BUT NOT EQUAL TO - return rune(0x2268), true - case "lnsim": // LESS-THAN BUT NOT EQUIVALENT TO - return rune(0x22e6), true - case "loang": // MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET - return rune(0x27ec), true - case "loarr": // LEFTWARDS OPEN-HEADED ARROW - return rune(0x21fd), true - case "lobrk": // MATHEMATICAL LEFT WHITE SQUARE BRACKET - return rune(0x27e6), true - case "locub": // LEFT WHITE CURLY BRACKET - return rune(0x2983), true - case "longleftarrow": // LONG LEFTWARDS ARROW - return rune(0x27f5), true - case "longleftrightarrow": // LONG LEFT RIGHT ARROW - return rune(0x27f7), true - case "longmapsto": // LONG RIGHTWARDS ARROW FROM BAR - return rune(0x27fc), true - case "longrightarrow": // LONG RIGHTWARDS ARROW - return rune(0x27f6), true - case "looparrowleft": // LEFTWARDS ARROW WITH LOOP - return rune(0x21ab), true - case "looparrowright": // RIGHTWARDS ARROW WITH LOOP - return rune(0x21ac), true - case "lopar": // LEFT WHITE PARENTHESIS - return rune(0x2985), true - case "lopf": // MATHEMATICAL DOUBLE-STRUCK SMALL L - return rune(0x01d55d), true - case "loplus": // PLUS SIGN IN LEFT HALF CIRCLE - return rune(0x2a2d), true - case "lotimes": // MULTIPLICATION SIGN IN LEFT HALF CIRCLE - return rune(0x2a34), true - case "lowast": // LOW ASTERISK - return rune(0x204e), true - case "lowbar": // LOW LINE - return rune(0x5f), true - case "lowint": // INTEGRAL WITH UNDERBAR - return rune(0x2a1c), true - case "loz": // LOZENGE - return rune(0x25ca), true - case "lozenge": // LOZENGE - return rune(0x25ca), true - case "lozf": // BLACK LOZENGE - return rune(0x29eb), true - case "lpar": // LEFT PARENTHESIS - return rune(0x28), true - case "lpargt": // SPHERICAL ANGLE OPENING LEFT - return rune(0x29a0), true - case "lparlt": // LEFT ARC LESS-THAN BRACKET - return rune(0x2993), true - case "lrarr": // LEFTWARDS ARROW OVER RIGHTWARDS ARROW - return rune(0x21c6), true - case "lrarr2": // LEFTWARDS ARROW OVER RIGHTWARDS ARROW - return rune(0x21c6), true - case "lrcorner": // BOTTOM RIGHT CORNER - return rune(0x231f), true - case "lrhar": // LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON - return rune(0x21cb), true - case "lrhar2": // LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON - return rune(0x21cb), true - case "lrhard": // RIGHTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH - return rune(0x296d), true - case "lrm": // LEFT-TO-RIGHT MARK - return rune(0x200e), true - case "lrtri": // RIGHT TRIANGLE - return rune(0x22bf), true - case "lsaquo": // SINGLE LEFT-POINTING ANGLE QUOTATION MARK - return rune(0x2039), true - case "lscr": // MATHEMATICAL SCRIPT SMALL L - return rune(0x01d4c1), true - case "lsh": // UPWARDS ARROW WITH TIP LEFTWARDS - return rune(0x21b0), true - case "lsim": // LESS-THAN OR EQUIVALENT TO - return rune(0x2272), true - case "lsime": // LESS-THAN ABOVE SIMILAR OR EQUAL - return rune(0x2a8d), true - case "lsimg": // LESS-THAN ABOVE SIMILAR ABOVE GREATER-THAN - return rune(0x2a8f), true - case "lsqb": // LEFT SQUARE BRACKET - return rune(0x5b), true - case "lsquo": // LEFT SINGLE QUOTATION MARK - return rune(0x2018), true - case "lsquor": // SINGLE LOW-9 QUOTATION MARK - return rune(0x201a), true - case "lstrok": // LATIN SMALL LETTER L WITH STROKE - return rune(0x0142), true - case "lt": // LESS-THAN SIGN - return rune(0x3c), true - case "ltcc": // LESS-THAN CLOSED BY CURVE - return rune(0x2aa6), true - case "ltcir": // LESS-THAN WITH CIRCLE INSIDE - return rune(0x2a79), true - case "ltdot": // LESS-THAN WITH DOT - return rune(0x22d6), true - case "lthree": // LEFT SEMIDIRECT PRODUCT - return rune(0x22cb), true - case "ltimes": // LEFT NORMAL FACTOR SEMIDIRECT PRODUCT - return rune(0x22c9), true - case "ltlarr": // LESS-THAN ABOVE LEFTWARDS ARROW - return rune(0x2976), true - case "ltquest": // LESS-THAN WITH QUESTION MARK ABOVE - return rune(0x2a7b), true - case "ltrPar": // DOUBLE RIGHT ARC LESS-THAN BRACKET - return rune(0x2996), true - case "ltri": // WHITE LEFT-POINTING SMALL TRIANGLE - return rune(0x25c3), true - case "ltrie": // NORMAL SUBGROUP OF OR EQUAL TO - return rune(0x22b4), true - case "ltrif": // BLACK LEFT-POINTING SMALL TRIANGLE - return rune(0x25c2), true - case "ltrivb": // LEFT TRIANGLE BESIDE VERTICAL BAR - return rune(0x29cf), true - case "luharb": // LEFTWARDS HARPOON WITH BARB UP TO BAR - return rune(0x2952), true - case "lurdshar": // LEFT BARB UP RIGHT BARB DOWN HARPOON - return rune(0x294a), true - case "luruhar": // LEFTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB UP - return rune(0x2966), true - case "lurushar": // LEFT BARB UP RIGHT BARB UP HARPOON - return rune(0x294e), true - case "lvertneqq": // LESS-THAN BUT NOT EQUAL TO - with vertical stroke - return rune(0x2268), true - case "lvnE": // LESS-THAN BUT NOT EQUAL TO - with vertical stroke - return rune(0x2268), true + case "lAarr": // LEFTWARDS TRIPLE ARROW + return rune(0x21da), true + case "lArr": // LEFTWARDS DOUBLE ARROW + return rune(0x21d0), true + case "lAtail": // LEFTWARDS DOUBLE ARROW-TAIL + return rune(0x291b), true + case "lBarr": // LEFTWARDS TRIPLE DASH ARROW + return rune(0x290e), true + case "lE": // LESS-THAN OVER EQUAL TO + return rune(0x2266), true + case "lEg": // LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN + return rune(0x2a8b), true + case "lHar": // LEFTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB DOWN + return rune(0x2962), true + case "lacute": // LATIN SMALL LETTER L WITH ACUTE + return rune(0x013a), true + case "laemptyv": // EMPTY SET WITH LEFT ARROW ABOVE + return rune(0x29b4), true + case "lagran": // SCRIPT CAPITAL L + return rune(0x2112), true + case "lambda": // GREEK SMALL LETTER LAMDA + return rune(0x03bb), true + case "lang": // MATHEMATICAL LEFT ANGLE BRACKET + return rune(0x27e8), true + case "langd": // LEFT ANGLE BRACKET WITH DOT + return rune(0x2991), true + case "langle": // MATHEMATICAL LEFT ANGLE BRACKET + return rune(0x27e8), true + case "lap": // LESS-THAN OR APPROXIMATE + return rune(0x2a85), true + case "laquo": // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + return rune(0xab), true + case "larr": // LEFTWARDS ARROW + return rune(0x2190), true + case "larr2": // LEFTWARDS PAIRED ARROWS + return rune(0x21c7), true + case "larrb": // LEFTWARDS ARROW TO BAR + return rune(0x21e4), true + case "larrbfs": // LEFTWARDS ARROW FROM BAR TO BLACK DIAMOND + return rune(0x291f), true + case "larrfs": // LEFTWARDS ARROW TO BLACK DIAMOND + return rune(0x291d), true + case "larrhk": // LEFTWARDS ARROW WITH HOOK + return rune(0x21a9), true + case "larrlp": // LEFTWARDS ARROW WITH LOOP + return rune(0x21ab), true + case "larrpl": // LEFT-SIDE ARC ANTICLOCKWISE ARROW + return rune(0x2939), true + case "larrsim": // LEFTWARDS ARROW ABOVE TILDE OPERATOR + return rune(0x2973), true + case "larrtl": // LEFTWARDS ARROW WITH TAIL + return rune(0x21a2), true + case "lat": // LARGER THAN + return rune(0x2aab), true + case "latail": // LEFTWARDS ARROW-TAIL + return rune(0x2919), true + case "late": // LARGER THAN OR EQUAL TO + return rune(0x2aad), true + case "lates": // LARGER THAN OR slanted EQUAL + return rune(0x2aad), true + case "lbarr": // LEFTWARDS DOUBLE DASH ARROW + return rune(0x290c), true + case "lbbrk": // LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT + return rune(0x2772), true + case "lbrace": // LEFT CURLY BRACKET + return rune(0x7b), true + case "lbrack": // LEFT SQUARE BRACKET + return rune(0x5b), true + case "lbrke": // LEFT SQUARE BRACKET WITH UNDERBAR + return rune(0x298b), true + case "lbrksld": // LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER + return rune(0x298f), true + case "lbrkslu": // LEFT SQUARE BRACKET WITH TICK IN TOP CORNER + return rune(0x298d), true + case "lcaron": // LATIN SMALL LETTER L WITH CARON + return rune(0x013e), true + case "lcedil": // LATIN SMALL LETTER L WITH CEDILLA + return rune(0x013c), true + case "lceil": // LEFT CEILING + return rune(0x2308), true + case "lcub": // LEFT CURLY BRACKET + return rune(0x7b), true + case "lcy": // CYRILLIC SMALL LETTER EL + return rune(0x043b), true + case "ldca": // ARROW POINTING DOWNWARDS THEN CURVING LEFTWARDS + return rune(0x2936), true + case "ldharb": // LEFTWARDS HARPOON WITH BARB DOWN TO BAR + return rune(0x2956), true + case "ldot": // LESS-THAN WITH DOT + return rune(0x22d6), true + case "ldquo": // LEFT DOUBLE QUOTATION MARK + return rune(0x201c), true + case "ldquor": // DOUBLE LOW-9 QUOTATION MARK + return rune(0x201e), true + case "ldrdhar": // LEFTWARDS HARPOON WITH BARB DOWN ABOVE RIGHTWARDS HARPOON WITH BARB DOWN + return rune(0x2967), true + case "ldrdshar": // LEFT BARB DOWN RIGHT BARB DOWN HARPOON + return rune(0x2950), true + case "ldrushar": // LEFT BARB DOWN RIGHT BARB UP HARPOON + return rune(0x294b), true + case "ldsh": // DOWNWARDS ARROW WITH TIP LEFTWARDS + return rune(0x21b2), true + case "le": // LESS-THAN OR EQUAL TO + return rune(0x2264), true + case "leftarrow": // LEFTWARDS ARROW + return rune(0x2190), true + case "leftarrowtail": // LEFTWARDS ARROW WITH TAIL + return rune(0x21a2), true + case "leftharpoondown": // LEFTWARDS HARPOON WITH BARB DOWNWARDS + return rune(0x21bd), true + case "leftharpoonup": // LEFTWARDS HARPOON WITH BARB UPWARDS + return rune(0x21bc), true + case "leftleftarrows": // LEFTWARDS PAIRED ARROWS + return rune(0x21c7), true + case "leftrightarrow": // LEFT RIGHT ARROW + return rune(0x2194), true + case "leftrightarrows": // LEFTWARDS ARROW OVER RIGHTWARDS ARROW + return rune(0x21c6), true + case "leftrightharpoons": // LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON + return rune(0x21cb), true + case "leftrightsquigarrow": // LEFT RIGHT WAVE ARROW + return rune(0x21ad), true + case "leftthreetimes": // LEFT SEMIDIRECT PRODUCT + return rune(0x22cb), true + case "leg": // LESS-THAN EQUAL TO OR GREATER-THAN + return rune(0x22da), true + case "leq": // LESS-THAN OR EQUAL TO + return rune(0x2264), true + case "leqq": // LESS-THAN OVER EQUAL TO + return rune(0x2266), true + case "leqslant": // LESS-THAN OR SLANTED EQUAL TO + return rune(0x2a7d), true + case "les": // LESS-THAN OR SLANTED EQUAL TO + return rune(0x2a7d), true + case "lescc": // LESS-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL + return rune(0x2aa8), true + case "lesdot": // LESS-THAN OR SLANTED EQUAL TO WITH DOT INSIDE + return rune(0x2a7f), true + case "lesdoto": // LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE + return rune(0x2a81), true + case "lesdotor": // LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE RIGHT + return rune(0x2a83), true + case "lesg": // LESS-THAN slanted EQUAL TO OR GREATER-THAN + return rune(0x22da), true + case "lesges": // LESS-THAN ABOVE SLANTED EQUAL ABOVE GREATER-THAN ABOVE SLANTED EQUAL + return rune(0x2a93), true + case "lessapprox": // LESS-THAN OR APPROXIMATE + return rune(0x2a85), true + case "lessdot": // LESS-THAN WITH DOT + return rune(0x22d6), true + case "lesseqgtr": // LESS-THAN EQUAL TO OR GREATER-THAN + return rune(0x22da), true + case "lesseqqgtr": // LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN + return rune(0x2a8b), true + case "lessgtr": // LESS-THAN OR GREATER-THAN + return rune(0x2276), true + case "lesssim": // LESS-THAN OR EQUIVALENT TO + return rune(0x2272), true + case "lfbowtie": // BOWTIE WITH LEFT HALF BLACK + return rune(0x29d1), true + case "lfisht": // LEFT FISH TAIL + return rune(0x297c), true + case "lfloor": // LEFT FLOOR + return rune(0x230a), true + case "lfr": // MATHEMATICAL FRAKTUR SMALL L + return rune(0x01d529), true + case "lftimes": // TIMES WITH LEFT HALF BLACK + return rune(0x29d4), true + case "lg": // LESS-THAN OR GREATER-THAN + return rune(0x2276), true + case "lgE": // LESS-THAN ABOVE GREATER-THAN ABOVE DOUBLE-LINE EQUAL + return rune(0x2a91), true + case "lgr": // GREEK SMALL LETTER LAMDA + return rune(0x03bb), true + case "lhard": // LEFTWARDS HARPOON WITH BARB DOWNWARDS + return rune(0x21bd), true + case "lharu": // LEFTWARDS HARPOON WITH BARB UPWARDS + return rune(0x21bc), true + case "lharul": // LEFTWARDS HARPOON WITH BARB UP ABOVE LONG DASH + return rune(0x296a), true + case "lhblk": // LOWER HALF BLOCK + return rune(0x2584), true + case "ljcy": // CYRILLIC SMALL LETTER LJE + return rune(0x0459), true + case "ll": // MUCH LESS-THAN + return rune(0x226a), true + case "llarr": // LEFTWARDS PAIRED ARROWS + return rune(0x21c7), true + case "llcorner": // BOTTOM LEFT CORNER + return rune(0x231e), true + case "llhard": // LEFTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH + return rune(0x296b), true + case "lltri": // LOWER LEFT TRIANGLE + return rune(0x25fa), true + case "lltrif": // BLACK LOWER LEFT TRIANGLE + return rune(0x25e3), true + case "lmidot": // LATIN SMALL LETTER L WITH MIDDLE DOT + return rune(0x0140), true + case "lmoust": // UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION + return rune(0x23b0), true + case "lmoustache": // UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION + return rune(0x23b0), true + case "lnE": // LESS-THAN BUT NOT EQUAL TO + return rune(0x2268), true + case "lnap": // LESS-THAN AND NOT APPROXIMATE + return rune(0x2a89), true + case "lnapprox": // LESS-THAN AND NOT APPROXIMATE + return rune(0x2a89), true + case "lne": // LESS-THAN AND SINGLE-LINE NOT EQUAL TO + return rune(0x2a87), true + case "lneq": // LESS-THAN AND SINGLE-LINE NOT EQUAL TO + return rune(0x2a87), true + case "lneqq": // LESS-THAN BUT NOT EQUAL TO + return rune(0x2268), true + case "lnsim": // LESS-THAN BUT NOT EQUIVALENT TO + return rune(0x22e6), true + case "loang": // MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET + return rune(0x27ec), true + case "loarr": // LEFTWARDS OPEN-HEADED ARROW + return rune(0x21fd), true + case "lobrk": // MATHEMATICAL LEFT WHITE SQUARE BRACKET + return rune(0x27e6), true + case "locub": // LEFT WHITE CURLY BRACKET + return rune(0x2983), true + case "longleftarrow": // LONG LEFTWARDS ARROW + return rune(0x27f5), true + case "longleftrightarrow": // LONG LEFT RIGHT ARROW + return rune(0x27f7), true + case "longmapsto": // LONG RIGHTWARDS ARROW FROM BAR + return rune(0x27fc), true + case "longrightarrow": // LONG RIGHTWARDS ARROW + return rune(0x27f6), true + case "looparrowleft": // LEFTWARDS ARROW WITH LOOP + return rune(0x21ab), true + case "looparrowright": // RIGHTWARDS ARROW WITH LOOP + return rune(0x21ac), true + case "lopar": // LEFT WHITE PARENTHESIS + return rune(0x2985), true + case "lopf": // MATHEMATICAL DOUBLE-STRUCK SMALL L + return rune(0x01d55d), true + case "loplus": // PLUS SIGN IN LEFT HALF CIRCLE + return rune(0x2a2d), true + case "lotimes": // MULTIPLICATION SIGN IN LEFT HALF CIRCLE + return rune(0x2a34), true + case "lowast": // LOW ASTERISK + return rune(0x204e), true + case "lowbar": // LOW LINE + return rune(0x5f), true + case "lowint": // INTEGRAL WITH UNDERBAR + return rune(0x2a1c), true + case "loz": // LOZENGE + return rune(0x25ca), true + case "lozenge": // LOZENGE + return rune(0x25ca), true + case "lozf": // BLACK LOZENGE + return rune(0x29eb), true + case "lpar": // LEFT PARENTHESIS + return rune(0x28), true + case "lpargt": // SPHERICAL ANGLE OPENING LEFT + return rune(0x29a0), true + case "lparlt": // LEFT ARC LESS-THAN BRACKET + return rune(0x2993), true + case "lrarr": // LEFTWARDS ARROW OVER RIGHTWARDS ARROW + return rune(0x21c6), true + case "lrarr2": // LEFTWARDS ARROW OVER RIGHTWARDS ARROW + return rune(0x21c6), true + case "lrcorner": // BOTTOM RIGHT CORNER + return rune(0x231f), true + case "lrhar": // LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON + return rune(0x21cb), true + case "lrhar2": // LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON + return rune(0x21cb), true + case "lrhard": // RIGHTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH + return rune(0x296d), true + case "lrm": // LEFT-TO-RIGHT MARK + return rune(0x200e), true + case "lrtri": // RIGHT TRIANGLE + return rune(0x22bf), true + case "lsaquo": // SINGLE LEFT-POINTING ANGLE QUOTATION MARK + return rune(0x2039), true + case "lscr": // MATHEMATICAL SCRIPT SMALL L + return rune(0x01d4c1), true + case "lsh": // UPWARDS ARROW WITH TIP LEFTWARDS + return rune(0x21b0), true + case "lsim": // LESS-THAN OR EQUIVALENT TO + return rune(0x2272), true + case "lsime": // LESS-THAN ABOVE SIMILAR OR EQUAL + return rune(0x2a8d), true + case "lsimg": // LESS-THAN ABOVE SIMILAR ABOVE GREATER-THAN + return rune(0x2a8f), true + case "lsqb": // LEFT SQUARE BRACKET + return rune(0x5b), true + case "lsquo": // LEFT SINGLE QUOTATION MARK + return rune(0x2018), true + case "lsquor": // SINGLE LOW-9 QUOTATION MARK + return rune(0x201a), true + case "lstrok": // LATIN SMALL LETTER L WITH STROKE + return rune(0x0142), true + case "lt": // LESS-THAN SIGN + return rune(0x3c), true + case "ltcc": // LESS-THAN CLOSED BY CURVE + return rune(0x2aa6), true + case "ltcir": // LESS-THAN WITH CIRCLE INSIDE + return rune(0x2a79), true + case "ltdot": // LESS-THAN WITH DOT + return rune(0x22d6), true + case "lthree": // LEFT SEMIDIRECT PRODUCT + return rune(0x22cb), true + case "ltimes": // LEFT NORMAL FACTOR SEMIDIRECT PRODUCT + return rune(0x22c9), true + case "ltlarr": // LESS-THAN ABOVE LEFTWARDS ARROW + return rune(0x2976), true + case "ltquest": // LESS-THAN WITH QUESTION MARK ABOVE + return rune(0x2a7b), true + case "ltrPar": // DOUBLE RIGHT ARC LESS-THAN BRACKET + return rune(0x2996), true + case "ltri": // WHITE LEFT-POINTING SMALL TRIANGLE + return rune(0x25c3), true + case "ltrie": // NORMAL SUBGROUP OF OR EQUAL TO + return rune(0x22b4), true + case "ltrif": // BLACK LEFT-POINTING SMALL TRIANGLE + return rune(0x25c2), true + case "ltrivb": // LEFT TRIANGLE BESIDE VERTICAL BAR + return rune(0x29cf), true + case "luharb": // LEFTWARDS HARPOON WITH BARB UP TO BAR + return rune(0x2952), true + case "lurdshar": // LEFT BARB UP RIGHT BARB DOWN HARPOON + return rune(0x294a), true + case "luruhar": // LEFTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB UP + return rune(0x2966), true + case "lurushar": // LEFT BARB UP RIGHT BARB UP HARPOON + return rune(0x294e), true + case "lvertneqq": // LESS-THAN BUT NOT EQUAL TO - with vertical stroke + return rune(0x2268), true + case "lvnE": // LESS-THAN BUT NOT EQUAL TO - with vertical stroke + return rune(0x2268), true } case 'm': switch name { - case "mDDot": // GEOMETRIC PROPORTION - return rune(0x223a), true - case "macr": // MACRON - return rune(0xaf), true - case "male": // MALE SIGN - return rune(0x2642), true - case "malt": // MALTESE CROSS - return rune(0x2720), true - case "maltese": // MALTESE CROSS - return rune(0x2720), true - case "map": // RIGHTWARDS ARROW FROM BAR - return rune(0x21a6), true - case "mapsto": // RIGHTWARDS ARROW FROM BAR - return rune(0x21a6), true - case "mapstodown": // DOWNWARDS ARROW FROM BAR - return rune(0x21a7), true - case "mapstoleft": // LEFTWARDS ARROW FROM BAR - return rune(0x21a4), true - case "mapstoup": // UPWARDS ARROW FROM BAR - return rune(0x21a5), true - case "marker": // BLACK VERTICAL RECTANGLE - return rune(0x25ae), true - case "mcomma": // MINUS SIGN WITH COMMA ABOVE - return rune(0x2a29), true - case "mcy": // CYRILLIC SMALL LETTER EM - return rune(0x043c), true - case "mdash": // EM DASH - return rune(0x2014), true - case "measuredangle": // MEASURED ANGLE - return rune(0x2221), true - case "mfr": // MATHEMATICAL FRAKTUR SMALL M - return rune(0x01d52a), true - case "mgr": // GREEK SMALL LETTER MU - return rune(0x03bc), true - case "mho": // INVERTED OHM SIGN - return rune(0x2127), true - case "micro": // MICRO SIGN - return rune(0xb5), true - case "mid": // DIVIDES - return rune(0x2223), true - case "midast": // ASTERISK - return rune(0x2a), true - case "midcir": // VERTICAL LINE WITH CIRCLE BELOW - return rune(0x2af0), true - case "middot": // MIDDLE DOT - return rune(0xb7), true - case "minus": // MINUS SIGN - return rune(0x2212), true - case "minusb": // SQUARED MINUS - return rune(0x229f), true - case "minusd": // DOT MINUS - return rune(0x2238), true - case "minusdu": // MINUS SIGN WITH DOT BELOW - return rune(0x2a2a), true - case "mlcp": // TRANSVERSAL INTERSECTION - return rune(0x2adb), true - case "mldr": // HORIZONTAL ELLIPSIS - return rune(0x2026), true - case "mnplus": // MINUS-OR-PLUS SIGN - return rune(0x2213), true - case "models": // MODELS - return rune(0x22a7), true - case "mopf": // MATHEMATICAL DOUBLE-STRUCK SMALL M - return rune(0x01d55e), true - case "mp": // MINUS-OR-PLUS SIGN - return rune(0x2213), true - case "mscr": // MATHEMATICAL SCRIPT SMALL M - return rune(0x01d4c2), true - case "mstpos": // INVERTED LAZY S - return rune(0x223e), true - case "mu": // GREEK SMALL LETTER MU - return rune(0x03bc), true - case "multimap": // MULTIMAP - return rune(0x22b8), true - case "mumap": // MULTIMAP - return rune(0x22b8), true + case "mDDot": // GEOMETRIC PROPORTION + return rune(0x223a), true + case "macr": // MACRON + return rune(0xaf), true + case "male": // MALE SIGN + return rune(0x2642), true + case "malt": // MALTESE CROSS + return rune(0x2720), true + case "maltese": // MALTESE CROSS + return rune(0x2720), true + case "map": // RIGHTWARDS ARROW FROM BAR + return rune(0x21a6), true + case "mapsto": // RIGHTWARDS ARROW FROM BAR + return rune(0x21a6), true + case "mapstodown": // DOWNWARDS ARROW FROM BAR + return rune(0x21a7), true + case "mapstoleft": // LEFTWARDS ARROW FROM BAR + return rune(0x21a4), true + case "mapstoup": // UPWARDS ARROW FROM BAR + return rune(0x21a5), true + case "marker": // BLACK VERTICAL RECTANGLE + return rune(0x25ae), true + case "mcomma": // MINUS SIGN WITH COMMA ABOVE + return rune(0x2a29), true + case "mcy": // CYRILLIC SMALL LETTER EM + return rune(0x043c), true + case "mdash": // EM DASH + return rune(0x2014), true + case "measuredangle": // MEASURED ANGLE + return rune(0x2221), true + case "mfr": // MATHEMATICAL FRAKTUR SMALL M + return rune(0x01d52a), true + case "mgr": // GREEK SMALL LETTER MU + return rune(0x03bc), true + case "mho": // INVERTED OHM SIGN + return rune(0x2127), true + case "micro": // MICRO SIGN + return rune(0xb5), true + case "mid": // DIVIDES + return rune(0x2223), true + case "midast": // ASTERISK + return rune(0x2a), true + case "midcir": // VERTICAL LINE WITH CIRCLE BELOW + return rune(0x2af0), true + case "middot": // MIDDLE DOT + return rune(0xb7), true + case "minus": // MINUS SIGN + return rune(0x2212), true + case "minusb": // SQUARED MINUS + return rune(0x229f), true + case "minusd": // DOT MINUS + return rune(0x2238), true + case "minusdu": // MINUS SIGN WITH DOT BELOW + return rune(0x2a2a), true + case "mlcp": // TRANSVERSAL INTERSECTION + return rune(0x2adb), true + case "mldr": // HORIZONTAL ELLIPSIS + return rune(0x2026), true + case "mnplus": // MINUS-OR-PLUS SIGN + return rune(0x2213), true + case "models": // MODELS + return rune(0x22a7), true + case "mopf": // MATHEMATICAL DOUBLE-STRUCK SMALL M + return rune(0x01d55e), true + case "mp": // MINUS-OR-PLUS SIGN + return rune(0x2213), true + case "mscr": // MATHEMATICAL SCRIPT SMALL M + return rune(0x01d4c2), true + case "mstpos": // INVERTED LAZY S + return rune(0x223e), true + case "mu": // GREEK SMALL LETTER MU + return rune(0x03bc), true + case "multimap": // MULTIMAP + return rune(0x22b8), true + case "mumap": // MULTIMAP + return rune(0x22b8), true } case 'n': switch name { - case "nGg": // VERY MUCH GREATER-THAN with slash - return rune(0x22d9), true - case "nGt": // MUCH GREATER THAN with vertical line - return rune(0x226b), true - case "nGtv": // MUCH GREATER THAN with slash - return rune(0x226b), true - case "nLeftarrow": // LEFTWARDS DOUBLE ARROW WITH STROKE - return rune(0x21cd), true - case "nLeftrightarrow": // LEFT RIGHT DOUBLE ARROW WITH STROKE - return rune(0x21ce), true - case "nLl": // VERY MUCH LESS-THAN with slash - return rune(0x22d8), true - case "nLt": // MUCH LESS THAN with vertical line - return rune(0x226a), true - case "nLtv": // MUCH LESS THAN with slash - return rune(0x226a), true - case "nRightarrow": // RIGHTWARDS DOUBLE ARROW WITH STROKE - return rune(0x21cf), true - case "nVDash": // NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE - return rune(0x22af), true - case "nVdash": // DOES NOT FORCE - return rune(0x22ae), true - case "nabla": // NABLA - return rune(0x2207), true - case "nacute": // LATIN SMALL LETTER N WITH ACUTE - return rune(0x0144), true - case "nang": // ANGLE with vertical line - return rune(0x2220), true - case "nap": // NOT ALMOST EQUAL TO - return rune(0x2249), true - case "napE": // APPROXIMATELY EQUAL OR EQUAL TO with slash - return rune(0x2a70), true - case "napid": // TRIPLE TILDE with slash - return rune(0x224b), true - case "napos": // LATIN SMALL LETTER N PRECEDED BY APOSTROPHE - return rune(0x0149), true - case "napprox": // NOT ALMOST EQUAL TO - return rune(0x2249), true - case "natur": // MUSIC NATURAL SIGN - return rune(0x266e), true - case "natural": // MUSIC NATURAL SIGN - return rune(0x266e), true - case "naturals": // DOUBLE-STRUCK CAPITAL N - return rune(0x2115), true - case "nbsp": // NO-BREAK SPACE - return rune(0xa0), true - case "nbump": // GEOMETRICALLY EQUIVALENT TO with slash - return rune(0x224e), true - case "nbumpe": // DIFFERENCE BETWEEN with slash - return rune(0x224f), true - case "ncap": // INTERSECTION WITH OVERBAR - return rune(0x2a43), true - case "ncaron": // LATIN SMALL LETTER N WITH CARON - return rune(0x0148), true - case "ncedil": // LATIN SMALL LETTER N WITH CEDILLA - return rune(0x0146), true - case "ncong": // NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO - return rune(0x2247), true - case "ncongdot": // CONGRUENT WITH DOT ABOVE with slash - return rune(0x2a6d), true - case "ncup": // UNION WITH OVERBAR - return rune(0x2a42), true - case "ncy": // CYRILLIC SMALL LETTER EN - return rune(0x043d), true - case "ndash": // EN DASH - return rune(0x2013), true - case "ne": // NOT EQUAL TO - return rune(0x2260), true - case "neArr": // NORTH EAST DOUBLE ARROW - return rune(0x21d7), true - case "nearhk": // NORTH EAST ARROW WITH HOOK - return rune(0x2924), true - case "nearr": // NORTH EAST ARROW - return rune(0x2197), true - case "nearrow": // NORTH EAST ARROW - return rune(0x2197), true - case "nedot": // APPROACHES THE LIMIT with slash - return rune(0x2250), true - case "neonwarr": // NORTH EAST ARROW CROSSING NORTH WEST ARROW - return rune(0x2931), true - case "neosearr": // NORTH EAST ARROW CROSSING SOUTH EAST ARROW - return rune(0x292e), true - case "nequiv": // NOT IDENTICAL TO - return rune(0x2262), true - case "nesear": // NORTH EAST ARROW AND SOUTH EAST ARROW - return rune(0x2928), true - case "nesim": // MINUS TILDE with slash - return rune(0x2242), true - case "neswsarr": // NORTH EAST AND SOUTH WEST ARROW - return rune(0x2922), true - case "nexist": // THERE DOES NOT EXIST - return rune(0x2204), true - case "nexists": // THERE DOES NOT EXIST - return rune(0x2204), true - case "nfr": // MATHEMATICAL FRAKTUR SMALL N - return rune(0x01d52b), true - case "ngE": // GREATER-THAN OVER EQUAL TO with slash - return rune(0x2267), true - case "nge": // NEITHER GREATER-THAN NOR EQUAL TO - return rune(0x2271), true - case "ngeq": // NEITHER GREATER-THAN NOR EQUAL TO - return rune(0x2271), true - case "ngeqq": // GREATER-THAN OVER EQUAL TO with slash - return rune(0x2267), true - case "ngeqslant": // GREATER-THAN OR SLANTED EQUAL TO with slash - return rune(0x2a7e), true - case "nges": // GREATER-THAN OR SLANTED EQUAL TO with slash - return rune(0x2a7e), true - case "ngr": // GREEK SMALL LETTER NU - return rune(0x03bd), true - case "ngsim": // NEITHER GREATER-THAN NOR EQUIVALENT TO - return rune(0x2275), true - case "ngt": // NOT GREATER-THAN - return rune(0x226f), true - case "ngtr": // NOT GREATER-THAN - return rune(0x226f), true - case "nhArr": // LEFT RIGHT DOUBLE ARROW WITH STROKE - return rune(0x21ce), true - case "nharr": // LEFT RIGHT ARROW WITH STROKE - return rune(0x21ae), true - case "nhpar": // PARALLEL WITH HORIZONTAL STROKE - return rune(0x2af2), true - case "ni": // CONTAINS AS MEMBER - return rune(0x220b), true - case "nis": // SMALL CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE - return rune(0x22fc), true - case "nisd": // CONTAINS WITH LONG HORIZONTAL STROKE - return rune(0x22fa), true - case "niv": // CONTAINS AS MEMBER - return rune(0x220b), true - case "njcy": // CYRILLIC SMALL LETTER NJE - return rune(0x045a), true - case "nlArr": // LEFTWARDS DOUBLE ARROW WITH STROKE - return rune(0x21cd), true - case "nlE": // LESS-THAN OVER EQUAL TO with slash - return rune(0x2266), true - case "nlarr": // LEFTWARDS ARROW WITH STROKE - return rune(0x219a), true - case "nldr": // TWO DOT LEADER - return rune(0x2025), true - case "nle": // NEITHER LESS-THAN NOR EQUAL TO - return rune(0x2270), true - case "nleftarrow": // LEFTWARDS ARROW WITH STROKE - return rune(0x219a), true - case "nleftrightarrow": // LEFT RIGHT ARROW WITH STROKE - return rune(0x21ae), true - case "nleq": // NEITHER LESS-THAN NOR EQUAL TO - return rune(0x2270), true - case "nleqq": // LESS-THAN OVER EQUAL TO with slash - return rune(0x2266), true - case "nleqslant": // LESS-THAN OR SLANTED EQUAL TO with slash - return rune(0x2a7d), true - case "nles": // LESS-THAN OR SLANTED EQUAL TO with slash - return rune(0x2a7d), true - case "nless": // NOT LESS-THAN - return rune(0x226e), true - case "nlsim": // NEITHER LESS-THAN NOR EQUIVALENT TO - return rune(0x2274), true - case "nlt": // NOT LESS-THAN - return rune(0x226e), true - case "nltri": // NOT NORMAL SUBGROUP OF - return rune(0x22ea), true - case "nltrie": // NOT NORMAL SUBGROUP OF OR EQUAL TO - return rune(0x22ec), true - case "nltrivb": // LEFT TRIANGLE BESIDE VERTICAL BAR with slash - return rune(0x29cf), true - case "nmid": // DOES NOT DIVIDE - return rune(0x2224), true - case "nopf": // MATHEMATICAL DOUBLE-STRUCK SMALL N - return rune(0x01d55f), true - case "not": // NOT SIGN - return rune(0xac), true - case "notin": // NOT AN ELEMENT OF - return rune(0x2209), true - case "notinE": // ELEMENT OF WITH TWO HORIZONTAL STROKES with slash - return rune(0x22f9), true - case "notindot": // ELEMENT OF WITH DOT ABOVE with slash - return rune(0x22f5), true - case "notinva": // NOT AN ELEMENT OF - return rune(0x2209), true - case "notinvb": // SMALL ELEMENT OF WITH OVERBAR - return rune(0x22f7), true - case "notinvc": // ELEMENT OF WITH OVERBAR - return rune(0x22f6), true - case "notni": // DOES NOT CONTAIN AS MEMBER - return rune(0x220c), true - case "notniva": // DOES NOT CONTAIN AS MEMBER - return rune(0x220c), true - case "notnivb": // SMALL CONTAINS WITH OVERBAR - return rune(0x22fe), true - case "notnivc": // CONTAINS WITH OVERBAR - return rune(0x22fd), true - case "npar": // NOT PARALLEL TO - return rune(0x2226), true - case "nparallel": // NOT PARALLEL TO - return rune(0x2226), true - case "nparsl": // DOUBLE SOLIDUS OPERATOR with reverse slash - return rune(0x2afd), true - case "npart": // PARTIAL DIFFERENTIAL with slash - return rune(0x2202), true - case "npolint": // LINE INTEGRATION NOT INCLUDING THE POLE - return rune(0x2a14), true - case "npr": // DOES NOT PRECEDE - return rune(0x2280), true - case "nprcue": // DOES NOT PRECEDE OR EQUAL - return rune(0x22e0), true - case "npre": // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN with slash - return rune(0x2aaf), true - case "nprec": // DOES NOT PRECEDE - return rune(0x2280), true - case "npreceq": // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN with slash - return rune(0x2aaf), true - case "nprsim": // PRECEDES OR EQUIVALENT TO with slash - return rune(0x227e), true - case "nrArr": // RIGHTWARDS DOUBLE ARROW WITH STROKE - return rune(0x21cf), true - case "nrarr": // RIGHTWARDS ARROW WITH STROKE - return rune(0x219b), true - case "nrarrc": // WAVE ARROW POINTING DIRECTLY RIGHT with slash - return rune(0x2933), true - case "nrarrw": // RIGHTWARDS WAVE ARROW with slash - return rune(0x219d), true - case "nrightarrow": // RIGHTWARDS ARROW WITH STROKE - return rune(0x219b), true - case "nrtri": // DOES NOT CONTAIN AS NORMAL SUBGROUP - return rune(0x22eb), true - case "nrtrie": // DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL - return rune(0x22ed), true - case "nsGt": // DOUBLE NESTED GREATER-THAN with slash - return rune(0x2aa2), true - case "nsLt": // DOUBLE NESTED LESS-THAN with slash - return rune(0x2aa1), true - case "nsc": // DOES NOT SUCCEED - return rune(0x2281), true - case "nsccue": // DOES NOT SUCCEED OR EQUAL - return rune(0x22e1), true - case "nsce": // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN with slash - return rune(0x2ab0), true - case "nscr": // MATHEMATICAL SCRIPT SMALL N - return rune(0x01d4c3), true - case "nscsim": // SUCCEEDS OR EQUIVALENT TO with slash - return rune(0x227f), true - case "nshortmid": // DOES NOT DIVIDE - return rune(0x2224), true - case "nshortparallel": // NOT PARALLEL TO - return rune(0x2226), true - case "nsim": // NOT TILDE - return rune(0x2241), true - case "nsime": // NOT ASYMPTOTICALLY EQUAL TO - return rune(0x2244), true - case "nsimeq": // NOT ASYMPTOTICALLY EQUAL TO - return rune(0x2244), true - case "nsmid": // DOES NOT DIVIDE - return rune(0x2224), true - case "nspar": // NOT PARALLEL TO - return rune(0x2226), true - case "nsqsub": // SQUARE IMAGE OF with slash - return rune(0x228f), true - case "nsqsube": // NOT SQUARE IMAGE OF OR EQUAL TO - return rune(0x22e2), true - case "nsqsup": // SQUARE ORIGINAL OF with slash - return rune(0x2290), true - case "nsqsupe": // NOT SQUARE ORIGINAL OF OR EQUAL TO - return rune(0x22e3), true - case "nsub": // NOT A SUBSET OF - return rune(0x2284), true - case "nsubE": // SUBSET OF ABOVE EQUALS SIGN with slash - return rune(0x2ac5), true - case "nsube": // NEITHER A SUBSET OF NOR EQUAL TO - return rune(0x2288), true - case "nsubset": // SUBSET OF with vertical line - return rune(0x2282), true - case "nsubseteq": // NEITHER A SUBSET OF NOR EQUAL TO - return rune(0x2288), true - case "nsubseteqq": // SUBSET OF ABOVE EQUALS SIGN with slash - return rune(0x2ac5), true - case "nsucc": // DOES NOT SUCCEED - return rune(0x2281), true - case "nsucceq": // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN with slash - return rune(0x2ab0), true - case "nsup": // NOT A SUPERSET OF - return rune(0x2285), true - case "nsupE": // SUPERSET OF ABOVE EQUALS SIGN with slash - return rune(0x2ac6), true - case "nsupe": // NEITHER A SUPERSET OF NOR EQUAL TO - return rune(0x2289), true - case "nsupset": // SUPERSET OF with vertical line - return rune(0x2283), true - case "nsupseteq": // NEITHER A SUPERSET OF NOR EQUAL TO - return rune(0x2289), true - case "nsupseteqq": // SUPERSET OF ABOVE EQUALS SIGN with slash - return rune(0x2ac6), true - case "ntgl": // NEITHER GREATER-THAN NOR LESS-THAN - return rune(0x2279), true - case "ntilde": // LATIN SMALL LETTER N WITH TILDE - return rune(0xf1), true - case "ntlg": // NEITHER LESS-THAN NOR GREATER-THAN - return rune(0x2278), true - case "ntriangleleft": // NOT NORMAL SUBGROUP OF - return rune(0x22ea), true - case "ntrianglelefteq": // NOT NORMAL SUBGROUP OF OR EQUAL TO - return rune(0x22ec), true - case "ntriangleright": // DOES NOT CONTAIN AS NORMAL SUBGROUP - return rune(0x22eb), true - case "ntrianglerighteq": // DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL - return rune(0x22ed), true - case "nu": // GREEK SMALL LETTER NU - return rune(0x03bd), true - case "num": // NUMBER SIGN - return rune(0x23), true - case "numero": // NUMERO SIGN - return rune(0x2116), true - case "numsp": // FIGURE SPACE - return rune(0x2007), true - case "nvDash": // NOT TRUE - return rune(0x22ad), true - case "nvHarr": // LEFT RIGHT DOUBLE ARROW WITH VERTICAL STROKE - return rune(0x2904), true - case "nvap": // EQUIVALENT TO with vertical line - return rune(0x224d), true - case "nvbrtri": // VERTICAL BAR BESIDE RIGHT TRIANGLE with slash - return rune(0x29d0), true - case "nvdash": // DOES NOT PROVE - return rune(0x22ac), true - case "nvge": // GREATER-THAN OR EQUAL TO with vertical line - return rune(0x2265), true - case "nvgt": // GREATER-THAN SIGN with vertical line - return rune(0x3e), true - case "nvinfin": // INFINITY NEGATED WITH VERTICAL BAR - return rune(0x29de), true - case "nvlArr": // LEFTWARDS DOUBLE ARROW WITH VERTICAL STROKE - return rune(0x2902), true - case "nvle": // LESS-THAN OR EQUAL TO with vertical line - return rune(0x2264), true - case "nvlt": // LESS-THAN SIGN with vertical line - return rune(0x3c), true - case "nvltrie": // NORMAL SUBGROUP OF OR EQUAL TO with vertical line - return rune(0x22b4), true - case "nvrArr": // RIGHTWARDS DOUBLE ARROW WITH VERTICAL STROKE - return rune(0x2903), true - case "nvrtrie": // CONTAINS AS NORMAL SUBGROUP OR EQUAL TO with vertical line - return rune(0x22b5), true - case "nvsim": // TILDE OPERATOR with vertical line - return rune(0x223c), true - case "nwArr": // NORTH WEST DOUBLE ARROW - return rune(0x21d6), true - case "nwarhk": // NORTH WEST ARROW WITH HOOK - return rune(0x2923), true - case "nwarr": // NORTH WEST ARROW - return rune(0x2196), true - case "nwarrow": // NORTH WEST ARROW - return rune(0x2196), true - case "nwnear": // NORTH WEST ARROW AND NORTH EAST ARROW - return rune(0x2927), true - case "nwonearr": // NORTH WEST ARROW CROSSING NORTH EAST ARROW - return rune(0x2932), true - case "nwsesarr": // NORTH WEST AND SOUTH EAST ARROW - return rune(0x2921), true + case "nGg": // VERY MUCH GREATER-THAN with slash + return rune(0x22d9), true + case "nGt": // MUCH GREATER THAN with vertical line + return rune(0x226b), true + case "nGtv": // MUCH GREATER THAN with slash + return rune(0x226b), true + case "nLeftarrow": // LEFTWARDS DOUBLE ARROW WITH STROKE + return rune(0x21cd), true + case "nLeftrightarrow": // LEFT RIGHT DOUBLE ARROW WITH STROKE + return rune(0x21ce), true + case "nLl": // VERY MUCH LESS-THAN with slash + return rune(0x22d8), true + case "nLt": // MUCH LESS THAN with vertical line + return rune(0x226a), true + case "nLtv": // MUCH LESS THAN with slash + return rune(0x226a), true + case "nRightarrow": // RIGHTWARDS DOUBLE ARROW WITH STROKE + return rune(0x21cf), true + case "nVDash": // NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE + return rune(0x22af), true + case "nVdash": // DOES NOT FORCE + return rune(0x22ae), true + case "nabla": // NABLA + return rune(0x2207), true + case "nacute": // LATIN SMALL LETTER N WITH ACUTE + return rune(0x0144), true + case "nang": // ANGLE with vertical line + return rune(0x2220), true + case "nap": // NOT ALMOST EQUAL TO + return rune(0x2249), true + case "napE": // APPROXIMATELY EQUAL OR EQUAL TO with slash + return rune(0x2a70), true + case "napid": // TRIPLE TILDE with slash + return rune(0x224b), true + case "napos": // LATIN SMALL LETTER N PRECEDED BY APOSTROPHE + return rune(0x0149), true + case "napprox": // NOT ALMOST EQUAL TO + return rune(0x2249), true + case "natur": // MUSIC NATURAL SIGN + return rune(0x266e), true + case "natural": // MUSIC NATURAL SIGN + return rune(0x266e), true + case "naturals": // DOUBLE-STRUCK CAPITAL N + return rune(0x2115), true + case "nbsp": // NO-BREAK SPACE + return rune(0xa0), true + case "nbump": // GEOMETRICALLY EQUIVALENT TO with slash + return rune(0x224e), true + case "nbumpe": // DIFFERENCE BETWEEN with slash + return rune(0x224f), true + case "ncap": // INTERSECTION WITH OVERBAR + return rune(0x2a43), true + case "ncaron": // LATIN SMALL LETTER N WITH CARON + return rune(0x0148), true + case "ncedil": // LATIN SMALL LETTER N WITH CEDILLA + return rune(0x0146), true + case "ncong": // NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO + return rune(0x2247), true + case "ncongdot": // CONGRUENT WITH DOT ABOVE with slash + return rune(0x2a6d), true + case "ncup": // UNION WITH OVERBAR + return rune(0x2a42), true + case "ncy": // CYRILLIC SMALL LETTER EN + return rune(0x043d), true + case "ndash": // EN DASH + return rune(0x2013), true + case "ne": // NOT EQUAL TO + return rune(0x2260), true + case "neArr": // NORTH EAST DOUBLE ARROW + return rune(0x21d7), true + case "nearhk": // NORTH EAST ARROW WITH HOOK + return rune(0x2924), true + case "nearr": // NORTH EAST ARROW + return rune(0x2197), true + case "nearrow": // NORTH EAST ARROW + return rune(0x2197), true + case "nedot": // APPROACHES THE LIMIT with slash + return rune(0x2250), true + case "neonwarr": // NORTH EAST ARROW CROSSING NORTH WEST ARROW + return rune(0x2931), true + case "neosearr": // NORTH EAST ARROW CROSSING SOUTH EAST ARROW + return rune(0x292e), true + case "nequiv": // NOT IDENTICAL TO + return rune(0x2262), true + case "nesear": // NORTH EAST ARROW AND SOUTH EAST ARROW + return rune(0x2928), true + case "nesim": // MINUS TILDE with slash + return rune(0x2242), true + case "neswsarr": // NORTH EAST AND SOUTH WEST ARROW + return rune(0x2922), true + case "nexist": // THERE DOES NOT EXIST + return rune(0x2204), true + case "nexists": // THERE DOES NOT EXIST + return rune(0x2204), true + case "nfr": // MATHEMATICAL FRAKTUR SMALL N + return rune(0x01d52b), true + case "ngE": // GREATER-THAN OVER EQUAL TO with slash + return rune(0x2267), true + case "nge": // NEITHER GREATER-THAN NOR EQUAL TO + return rune(0x2271), true + case "ngeq": // NEITHER GREATER-THAN NOR EQUAL TO + return rune(0x2271), true + case "ngeqq": // GREATER-THAN OVER EQUAL TO with slash + return rune(0x2267), true + case "ngeqslant": // GREATER-THAN OR SLANTED EQUAL TO with slash + return rune(0x2a7e), true + case "nges": // GREATER-THAN OR SLANTED EQUAL TO with slash + return rune(0x2a7e), true + case "ngr": // GREEK SMALL LETTER NU + return rune(0x03bd), true + case "ngsim": // NEITHER GREATER-THAN NOR EQUIVALENT TO + return rune(0x2275), true + case "ngt": // NOT GREATER-THAN + return rune(0x226f), true + case "ngtr": // NOT GREATER-THAN + return rune(0x226f), true + case "nhArr": // LEFT RIGHT DOUBLE ARROW WITH STROKE + return rune(0x21ce), true + case "nharr": // LEFT RIGHT ARROW WITH STROKE + return rune(0x21ae), true + case "nhpar": // PARALLEL WITH HORIZONTAL STROKE + return rune(0x2af2), true + case "ni": // CONTAINS AS MEMBER + return rune(0x220b), true + case "nis": // SMALL CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE + return rune(0x22fc), true + case "nisd": // CONTAINS WITH LONG HORIZONTAL STROKE + return rune(0x22fa), true + case "niv": // CONTAINS AS MEMBER + return rune(0x220b), true + case "njcy": // CYRILLIC SMALL LETTER NJE + return rune(0x045a), true + case "nlArr": // LEFTWARDS DOUBLE ARROW WITH STROKE + return rune(0x21cd), true + case "nlE": // LESS-THAN OVER EQUAL TO with slash + return rune(0x2266), true + case "nlarr": // LEFTWARDS ARROW WITH STROKE + return rune(0x219a), true + case "nldr": // TWO DOT LEADER + return rune(0x2025), true + case "nle": // NEITHER LESS-THAN NOR EQUAL TO + return rune(0x2270), true + case "nleftarrow": // LEFTWARDS ARROW WITH STROKE + return rune(0x219a), true + case "nleftrightarrow": // LEFT RIGHT ARROW WITH STROKE + return rune(0x21ae), true + case "nleq": // NEITHER LESS-THAN NOR EQUAL TO + return rune(0x2270), true + case "nleqq": // LESS-THAN OVER EQUAL TO with slash + return rune(0x2266), true + case "nleqslant": // LESS-THAN OR SLANTED EQUAL TO with slash + return rune(0x2a7d), true + case "nles": // LESS-THAN OR SLANTED EQUAL TO with slash + return rune(0x2a7d), true + case "nless": // NOT LESS-THAN + return rune(0x226e), true + case "nlsim": // NEITHER LESS-THAN NOR EQUIVALENT TO + return rune(0x2274), true + case "nlt": // NOT LESS-THAN + return rune(0x226e), true + case "nltri": // NOT NORMAL SUBGROUP OF + return rune(0x22ea), true + case "nltrie": // NOT NORMAL SUBGROUP OF OR EQUAL TO + return rune(0x22ec), true + case "nltrivb": // LEFT TRIANGLE BESIDE VERTICAL BAR with slash + return rune(0x29cf), true + case "nmid": // DOES NOT DIVIDE + return rune(0x2224), true + case "nopf": // MATHEMATICAL DOUBLE-STRUCK SMALL N + return rune(0x01d55f), true + case "not": // NOT SIGN + return rune(0xac), true + case "notin": // NOT AN ELEMENT OF + return rune(0x2209), true + case "notinE": // ELEMENT OF WITH TWO HORIZONTAL STROKES with slash + return rune(0x22f9), true + case "notindot": // ELEMENT OF WITH DOT ABOVE with slash + return rune(0x22f5), true + case "notinva": // NOT AN ELEMENT OF + return rune(0x2209), true + case "notinvb": // SMALL ELEMENT OF WITH OVERBAR + return rune(0x22f7), true + case "notinvc": // ELEMENT OF WITH OVERBAR + return rune(0x22f6), true + case "notni": // DOES NOT CONTAIN AS MEMBER + return rune(0x220c), true + case "notniva": // DOES NOT CONTAIN AS MEMBER + return rune(0x220c), true + case "notnivb": // SMALL CONTAINS WITH OVERBAR + return rune(0x22fe), true + case "notnivc": // CONTAINS WITH OVERBAR + return rune(0x22fd), true + case "npar": // NOT PARALLEL TO + return rune(0x2226), true + case "nparallel": // NOT PARALLEL TO + return rune(0x2226), true + case "nparsl": // DOUBLE SOLIDUS OPERATOR with reverse slash + return rune(0x2afd), true + case "npart": // PARTIAL DIFFERENTIAL with slash + return rune(0x2202), true + case "npolint": // LINE INTEGRATION NOT INCLUDING THE POLE + return rune(0x2a14), true + case "npr": // DOES NOT PRECEDE + return rune(0x2280), true + case "nprcue": // DOES NOT PRECEDE OR EQUAL + return rune(0x22e0), true + case "npre": // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN with slash + return rune(0x2aaf), true + case "nprec": // DOES NOT PRECEDE + return rune(0x2280), true + case "npreceq": // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN with slash + return rune(0x2aaf), true + case "nprsim": // PRECEDES OR EQUIVALENT TO with slash + return rune(0x227e), true + case "nrArr": // RIGHTWARDS DOUBLE ARROW WITH STROKE + return rune(0x21cf), true + case "nrarr": // RIGHTWARDS ARROW WITH STROKE + return rune(0x219b), true + case "nrarrc": // WAVE ARROW POINTING DIRECTLY RIGHT with slash + return rune(0x2933), true + case "nrarrw": // RIGHTWARDS WAVE ARROW with slash + return rune(0x219d), true + case "nrightarrow": // RIGHTWARDS ARROW WITH STROKE + return rune(0x219b), true + case "nrtri": // DOES NOT CONTAIN AS NORMAL SUBGROUP + return rune(0x22eb), true + case "nrtrie": // DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL + return rune(0x22ed), true + case "nsGt": // DOUBLE NESTED GREATER-THAN with slash + return rune(0x2aa2), true + case "nsLt": // DOUBLE NESTED LESS-THAN with slash + return rune(0x2aa1), true + case "nsc": // DOES NOT SUCCEED + return rune(0x2281), true + case "nsccue": // DOES NOT SUCCEED OR EQUAL + return rune(0x22e1), true + case "nsce": // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN with slash + return rune(0x2ab0), true + case "nscr": // MATHEMATICAL SCRIPT SMALL N + return rune(0x01d4c3), true + case "nscsim": // SUCCEEDS OR EQUIVALENT TO with slash + return rune(0x227f), true + case "nshortmid": // DOES NOT DIVIDE + return rune(0x2224), true + case "nshortparallel": // NOT PARALLEL TO + return rune(0x2226), true + case "nsim": // NOT TILDE + return rune(0x2241), true + case "nsime": // NOT ASYMPTOTICALLY EQUAL TO + return rune(0x2244), true + case "nsimeq": // NOT ASYMPTOTICALLY EQUAL TO + return rune(0x2244), true + case "nsmid": // DOES NOT DIVIDE + return rune(0x2224), true + case "nspar": // NOT PARALLEL TO + return rune(0x2226), true + case "nsqsub": // SQUARE IMAGE OF with slash + return rune(0x228f), true + case "nsqsube": // NOT SQUARE IMAGE OF OR EQUAL TO + return rune(0x22e2), true + case "nsqsup": // SQUARE ORIGINAL OF with slash + return rune(0x2290), true + case "nsqsupe": // NOT SQUARE ORIGINAL OF OR EQUAL TO + return rune(0x22e3), true + case "nsub": // NOT A SUBSET OF + return rune(0x2284), true + case "nsubE": // SUBSET OF ABOVE EQUALS SIGN with slash + return rune(0x2ac5), true + case "nsube": // NEITHER A SUBSET OF NOR EQUAL TO + return rune(0x2288), true + case "nsubset": // SUBSET OF with vertical line + return rune(0x2282), true + case "nsubseteq": // NEITHER A SUBSET OF NOR EQUAL TO + return rune(0x2288), true + case "nsubseteqq": // SUBSET OF ABOVE EQUALS SIGN with slash + return rune(0x2ac5), true + case "nsucc": // DOES NOT SUCCEED + return rune(0x2281), true + case "nsucceq": // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN with slash + return rune(0x2ab0), true + case "nsup": // NOT A SUPERSET OF + return rune(0x2285), true + case "nsupE": // SUPERSET OF ABOVE EQUALS SIGN with slash + return rune(0x2ac6), true + case "nsupe": // NEITHER A SUPERSET OF NOR EQUAL TO + return rune(0x2289), true + case "nsupset": // SUPERSET OF with vertical line + return rune(0x2283), true + case "nsupseteq": // NEITHER A SUPERSET OF NOR EQUAL TO + return rune(0x2289), true + case "nsupseteqq": // SUPERSET OF ABOVE EQUALS SIGN with slash + return rune(0x2ac6), true + case "ntgl": // NEITHER GREATER-THAN NOR LESS-THAN + return rune(0x2279), true + case "ntilde": // LATIN SMALL LETTER N WITH TILDE + return rune(0xf1), true + case "ntlg": // NEITHER LESS-THAN NOR GREATER-THAN + return rune(0x2278), true + case "ntriangleleft": // NOT NORMAL SUBGROUP OF + return rune(0x22ea), true + case "ntrianglelefteq": // NOT NORMAL SUBGROUP OF OR EQUAL TO + return rune(0x22ec), true + case "ntriangleright": // DOES NOT CONTAIN AS NORMAL SUBGROUP + return rune(0x22eb), true + case "ntrianglerighteq": // DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL + return rune(0x22ed), true + case "nu": // GREEK SMALL LETTER NU + return rune(0x03bd), true + case "num": // NUMBER SIGN + return rune(0x23), true + case "numero": // NUMERO SIGN + return rune(0x2116), true + case "numsp": // FIGURE SPACE + return rune(0x2007), true + case "nvDash": // NOT TRUE + return rune(0x22ad), true + case "nvHarr": // LEFT RIGHT DOUBLE ARROW WITH VERTICAL STROKE + return rune(0x2904), true + case "nvap": // EQUIVALENT TO with vertical line + return rune(0x224d), true + case "nvbrtri": // VERTICAL BAR BESIDE RIGHT TRIANGLE with slash + return rune(0x29d0), true + case "nvdash": // DOES NOT PROVE + return rune(0x22ac), true + case "nvge": // GREATER-THAN OR EQUAL TO with vertical line + return rune(0x2265), true + case "nvgt": // GREATER-THAN SIGN with vertical line + return rune(0x3e), true + case "nvinfin": // INFINITY NEGATED WITH VERTICAL BAR + return rune(0x29de), true + case "nvlArr": // LEFTWARDS DOUBLE ARROW WITH VERTICAL STROKE + return rune(0x2902), true + case "nvle": // LESS-THAN OR EQUAL TO with vertical line + return rune(0x2264), true + case "nvlt": // LESS-THAN SIGN with vertical line + return rune(0x3c), true + case "nvltrie": // NORMAL SUBGROUP OF OR EQUAL TO with vertical line + return rune(0x22b4), true + case "nvrArr": // RIGHTWARDS DOUBLE ARROW WITH VERTICAL STROKE + return rune(0x2903), true + case "nvrtrie": // CONTAINS AS NORMAL SUBGROUP OR EQUAL TO with vertical line + return rune(0x22b5), true + case "nvsim": // TILDE OPERATOR with vertical line + return rune(0x223c), true + case "nwArr": // NORTH WEST DOUBLE ARROW + return rune(0x21d6), true + case "nwarhk": // NORTH WEST ARROW WITH HOOK + return rune(0x2923), true + case "nwarr": // NORTH WEST ARROW + return rune(0x2196), true + case "nwarrow": // NORTH WEST ARROW + return rune(0x2196), true + case "nwnear": // NORTH WEST ARROW AND NORTH EAST ARROW + return rune(0x2927), true + case "nwonearr": // NORTH WEST ARROW CROSSING NORTH EAST ARROW + return rune(0x2932), true + case "nwsesarr": // NORTH WEST AND SOUTH EAST ARROW + return rune(0x2921), true } case 'o': switch name { - case "oS": // CIRCLED LATIN CAPITAL LETTER S - return rune(0x24c8), true - case "oacgr": // GREEK SMALL LETTER OMICRON WITH TONOS - return rune(0x03cc), true - case "oacute": // LATIN SMALL LETTER O WITH ACUTE - return rune(0xf3), true - case "oast": // CIRCLED ASTERISK OPERATOR - return rune(0x229b), true - case "obsol": // CIRCLED REVERSE SOLIDUS - return rune(0x29b8), true - case "ocir": // CIRCLED RING OPERATOR - return rune(0x229a), true - case "ocirc": // LATIN SMALL LETTER O WITH CIRCUMFLEX - return rune(0xf4), true - case "ocy": // CYRILLIC SMALL LETTER O - return rune(0x043e), true - case "odash": // CIRCLED DASH - return rune(0x229d), true - case "odblac": // LATIN SMALL LETTER O WITH DOUBLE ACUTE - return rune(0x0151), true - case "odiv": // CIRCLED DIVISION SIGN - return rune(0x2a38), true - case "odot": // CIRCLED DOT OPERATOR - return rune(0x2299), true - case "odsold": // CIRCLED ANTICLOCKWISE-ROTATED DIVISION SIGN - return rune(0x29bc), true - case "oelig": // LATIN SMALL LIGATURE OE - return rune(0x0153), true - case "ofcir": // CIRCLED BULLET - return rune(0x29bf), true - case "ofr": // MATHEMATICAL FRAKTUR SMALL O - return rune(0x01d52c), true - case "ogon": // OGONEK - return rune(0x02db), true - case "ogr": // GREEK SMALL LETTER OMICRON - return rune(0x03bf), true - case "ograve": // LATIN SMALL LETTER O WITH GRAVE - return rune(0xf2), true - case "ogt": // CIRCLED GREATER-THAN - return rune(0x29c1), true - case "ohacgr": // GREEK SMALL LETTER OMEGA WITH TONOS - return rune(0x03ce), true - case "ohbar": // CIRCLE WITH HORIZONTAL BAR - return rune(0x29b5), true - case "ohgr": // GREEK SMALL LETTER OMEGA - return rune(0x03c9), true - case "ohm": // GREEK CAPITAL LETTER OMEGA - return rune(0x03a9), true - case "oint": // CONTOUR INTEGRAL - return rune(0x222e), true - case "olarr": // ANTICLOCKWISE OPEN CIRCLE ARROW - return rune(0x21ba), true - case "olcir": // CIRCLED WHITE BULLET - return rune(0x29be), true - case "olcross": // CIRCLE WITH SUPERIMPOSED X - return rune(0x29bb), true - case "oline": // OVERLINE - return rune(0x203e), true - case "olt": // CIRCLED LESS-THAN - return rune(0x29c0), true - case "omacr": // LATIN SMALL LETTER O WITH MACRON - return rune(0x014d), true - case "omega": // GREEK SMALL LETTER OMEGA - return rune(0x03c9), true - case "omicron": // GREEK SMALL LETTER OMICRON - return rune(0x03bf), true - case "omid": // CIRCLED VERTICAL BAR - return rune(0x29b6), true - case "ominus": // CIRCLED MINUS - return rune(0x2296), true - case "oopf": // MATHEMATICAL DOUBLE-STRUCK SMALL O - return rune(0x01d560), true - case "opar": // CIRCLED PARALLEL - return rune(0x29b7), true - case "operp": // CIRCLED PERPENDICULAR - return rune(0x29b9), true - case "opfgamma": // DOUBLE-STRUCK SMALL GAMMA - return rune(0x213d), true - case "opfpi": // DOUBLE-STRUCK CAPITAL PI - return rune(0x213f), true - case "opfsum": // DOUBLE-STRUCK N-ARY SUMMATION - return rune(0x2140), true - case "oplus": // CIRCLED PLUS - return rune(0x2295), true - case "or": // LOGICAL OR - return rune(0x2228), true - case "orarr": // CLOCKWISE OPEN CIRCLE ARROW - return rune(0x21bb), true - case "ord": // LOGICAL OR WITH HORIZONTAL DASH - return rune(0x2a5d), true - case "order": // SCRIPT SMALL O - return rune(0x2134), true - case "orderof": // SCRIPT SMALL O - return rune(0x2134), true - case "ordf": // FEMININE ORDINAL INDICATOR - return rune(0xaa), true - case "ordm": // MASCULINE ORDINAL INDICATOR - return rune(0xba), true - case "origof": // ORIGINAL OF - return rune(0x22b6), true - case "oror": // TWO INTERSECTING LOGICAL OR - return rune(0x2a56), true - case "orslope": // SLOPING LARGE OR - return rune(0x2a57), true - case "orv": // LOGICAL OR WITH MIDDLE STEM - return rune(0x2a5b), true - case "oscr": // SCRIPT SMALL O - return rune(0x2134), true - case "oslash": // LATIN SMALL LETTER O WITH STROKE - return rune(0xf8), true - case "osol": // CIRCLED DIVISION SLASH - return rune(0x2298), true - case "otilde": // LATIN SMALL LETTER O WITH TILDE - return rune(0xf5), true - case "otimes": // CIRCLED TIMES - return rune(0x2297), true - case "otimesas": // CIRCLED MULTIPLICATION SIGN WITH CIRCUMFLEX ACCENT - return rune(0x2a36), true - case "ouml": // LATIN SMALL LETTER O WITH DIAERESIS - return rune(0xf6), true - case "ovbar": // APL FUNCTIONAL SYMBOL CIRCLE STILE - return rune(0x233d), true - case "ovrbrk": // TOP SQUARE BRACKET - return rune(0x23b4), true - case "ovrcub": // TOP CURLY BRACKET - return rune(0x23de), true - case "ovrpar": // TOP PARENTHESIS - return rune(0x23dc), true - case "oxuarr": // UP ARROW THROUGH CIRCLE - return rune(0x29bd), true + case "oS": // CIRCLED LATIN CAPITAL LETTER S + return rune(0x24c8), true + case "oacgr": // GREEK SMALL LETTER OMICRON WITH TONOS + return rune(0x03cc), true + case "oacute": // LATIN SMALL LETTER O WITH ACUTE + return rune(0xf3), true + case "oast": // CIRCLED ASTERISK OPERATOR + return rune(0x229b), true + case "obsol": // CIRCLED REVERSE SOLIDUS + return rune(0x29b8), true + case "ocir": // CIRCLED RING OPERATOR + return rune(0x229a), true + case "ocirc": // LATIN SMALL LETTER O WITH CIRCUMFLEX + return rune(0xf4), true + case "ocy": // CYRILLIC SMALL LETTER O + return rune(0x043e), true + case "odash": // CIRCLED DASH + return rune(0x229d), true + case "odblac": // LATIN SMALL LETTER O WITH DOUBLE ACUTE + return rune(0x0151), true + case "odiv": // CIRCLED DIVISION SIGN + return rune(0x2a38), true + case "odot": // CIRCLED DOT OPERATOR + return rune(0x2299), true + case "odsold": // CIRCLED ANTICLOCKWISE-ROTATED DIVISION SIGN + return rune(0x29bc), true + case "oelig": // LATIN SMALL LIGATURE OE + return rune(0x0153), true + case "ofcir": // CIRCLED BULLET + return rune(0x29bf), true + case "ofr": // MATHEMATICAL FRAKTUR SMALL O + return rune(0x01d52c), true + case "ogon": // OGONEK + return rune(0x02db), true + case "ogr": // GREEK SMALL LETTER OMICRON + return rune(0x03bf), true + case "ograve": // LATIN SMALL LETTER O WITH GRAVE + return rune(0xf2), true + case "ogt": // CIRCLED GREATER-THAN + return rune(0x29c1), true + case "ohacgr": // GREEK SMALL LETTER OMEGA WITH TONOS + return rune(0x03ce), true + case "ohbar": // CIRCLE WITH HORIZONTAL BAR + return rune(0x29b5), true + case "ohgr": // GREEK SMALL LETTER OMEGA + return rune(0x03c9), true + case "ohm": // GREEK CAPITAL LETTER OMEGA + return rune(0x03a9), true + case "oint": // CONTOUR INTEGRAL + return rune(0x222e), true + case "olarr": // ANTICLOCKWISE OPEN CIRCLE ARROW + return rune(0x21ba), true + case "olcir": // CIRCLED WHITE BULLET + return rune(0x29be), true + case "olcross": // CIRCLE WITH SUPERIMPOSED X + return rune(0x29bb), true + case "oline": // OVERLINE + return rune(0x203e), true + case "olt": // CIRCLED LESS-THAN + return rune(0x29c0), true + case "omacr": // LATIN SMALL LETTER O WITH MACRON + return rune(0x014d), true + case "omega": // GREEK SMALL LETTER OMEGA + return rune(0x03c9), true + case "omicron": // GREEK SMALL LETTER OMICRON + return rune(0x03bf), true + case "omid": // CIRCLED VERTICAL BAR + return rune(0x29b6), true + case "ominus": // CIRCLED MINUS + return rune(0x2296), true + case "oopf": // MATHEMATICAL DOUBLE-STRUCK SMALL O + return rune(0x01d560), true + case "opar": // CIRCLED PARALLEL + return rune(0x29b7), true + case "operp": // CIRCLED PERPENDICULAR + return rune(0x29b9), true + case "opfgamma": // DOUBLE-STRUCK SMALL GAMMA + return rune(0x213d), true + case "opfpi": // DOUBLE-STRUCK CAPITAL PI + return rune(0x213f), true + case "opfsum": // DOUBLE-STRUCK N-ARY SUMMATION + return rune(0x2140), true + case "oplus": // CIRCLED PLUS + return rune(0x2295), true + case "or": // LOGICAL OR + return rune(0x2228), true + case "orarr": // CLOCKWISE OPEN CIRCLE ARROW + return rune(0x21bb), true + case "ord": // LOGICAL OR WITH HORIZONTAL DASH + return rune(0x2a5d), true + case "order": // SCRIPT SMALL O + return rune(0x2134), true + case "orderof": // SCRIPT SMALL O + return rune(0x2134), true + case "ordf": // FEMININE ORDINAL INDICATOR + return rune(0xaa), true + case "ordm": // MASCULINE ORDINAL INDICATOR + return rune(0xba), true + case "origof": // ORIGINAL OF + return rune(0x22b6), true + case "oror": // TWO INTERSECTING LOGICAL OR + return rune(0x2a56), true + case "orslope": // SLOPING LARGE OR + return rune(0x2a57), true + case "orv": // LOGICAL OR WITH MIDDLE STEM + return rune(0x2a5b), true + case "oscr": // SCRIPT SMALL O + return rune(0x2134), true + case "oslash": // LATIN SMALL LETTER O WITH STROKE + return rune(0xf8), true + case "osol": // CIRCLED DIVISION SLASH + return rune(0x2298), true + case "otilde": // LATIN SMALL LETTER O WITH TILDE + return rune(0xf5), true + case "otimes": // CIRCLED TIMES + return rune(0x2297), true + case "otimesas": // CIRCLED MULTIPLICATION SIGN WITH CIRCUMFLEX ACCENT + return rune(0x2a36), true + case "ouml": // LATIN SMALL LETTER O WITH DIAERESIS + return rune(0xf6), true + case "ovbar": // APL FUNCTIONAL SYMBOL CIRCLE STILE + return rune(0x233d), true + case "ovrbrk": // TOP SQUARE BRACKET + return rune(0x23b4), true + case "ovrcub": // TOP CURLY BRACKET + return rune(0x23de), true + case "ovrpar": // TOP PARENTHESIS + return rune(0x23dc), true + case "oxuarr": // UP ARROW THROUGH CIRCLE + return rune(0x29bd), true } case 'p': switch name { - case "par": // PARALLEL TO - return rune(0x2225), true - case "para": // PILCROW SIGN - return rune(0xb6), true - case "parallel": // PARALLEL TO - return rune(0x2225), true - case "parsim": // PARALLEL WITH TILDE OPERATOR - return rune(0x2af3), true - case "parsl": // DOUBLE SOLIDUS OPERATOR - return rune(0x2afd), true - case "part": // PARTIAL DIFFERENTIAL - return rune(0x2202), true - case "pcy": // CYRILLIC SMALL LETTER PE - return rune(0x043f), true - case "percnt": // PERCENT SIGN - return rune(0x25), true - case "period": // FULL STOP - return rune(0x2e), true - case "permil": // PER MILLE SIGN - return rune(0x2030), true - case "perp": // UP TACK - return rune(0x22a5), true - case "pertenk": // PER TEN THOUSAND SIGN - return rune(0x2031), true - case "pfr": // MATHEMATICAL FRAKTUR SMALL P - return rune(0x01d52d), true - case "pgr": // GREEK SMALL LETTER PI - return rune(0x03c0), true - case "phgr": // GREEK SMALL LETTER PHI - return rune(0x03c6), true - case "phi": // GREEK SMALL LETTER PHI - return rune(0x03c6), true - case "phis": // GREEK PHI SYMBOL - return rune(0x03d5), true - case "phiv": // GREEK PHI SYMBOL - return rune(0x03d5), true - case "phmmat": // SCRIPT CAPITAL M - return rune(0x2133), true - case "phone": // BLACK TELEPHONE - return rune(0x260e), true - case "pi": // GREEK SMALL LETTER PI - return rune(0x03c0), true - case "pitchfork": // PITCHFORK - return rune(0x22d4), true - case "piv": // GREEK PI SYMBOL - return rune(0x03d6), true - case "planck": // PLANCK CONSTANT OVER TWO PI - return rune(0x210f), true - case "planckh": // PLANCK CONSTANT - return rune(0x210e), true - case "plankv": // PLANCK CONSTANT OVER TWO PI - return rune(0x210f), true - case "plus": // PLUS SIGN - return rune(0x2b), true - case "plusacir": // PLUS SIGN WITH CIRCUMFLEX ACCENT ABOVE - return rune(0x2a23), true - case "plusb": // SQUARED PLUS - return rune(0x229e), true - case "pluscir": // PLUS SIGN WITH SMALL CIRCLE ABOVE - return rune(0x2a22), true - case "plusdo": // DOT PLUS - return rune(0x2214), true - case "plusdu": // PLUS SIGN WITH DOT BELOW - return rune(0x2a25), true - case "pluse": // PLUS SIGN ABOVE EQUALS SIGN - return rune(0x2a72), true - case "plusmn": // PLUS-MINUS SIGN - return rune(0xb1), true - case "plussim": // PLUS SIGN WITH TILDE BELOW - return rune(0x2a26), true - case "plustrif": // PLUS SIGN WITH BLACK TRIANGLE - return rune(0x2a28), true - case "plustwo": // PLUS SIGN WITH SUBSCRIPT TWO - return rune(0x2a27), true - case "pm": // PLUS-MINUS SIGN - return rune(0xb1), true - case "pointint": // INTEGRAL AROUND A POINT OPERATOR - return rune(0x2a15), true - case "popf": // MATHEMATICAL DOUBLE-STRUCK SMALL P - return rune(0x01d561), true - case "pound": // POUND SIGN - return rune(0xa3), true - case "pr": // PRECEDES - return rune(0x227a), true - case "prE": // PRECEDES ABOVE EQUALS SIGN - return rune(0x2ab3), true - case "prap": // PRECEDES ABOVE ALMOST EQUAL TO - return rune(0x2ab7), true - case "prcue": // PRECEDES OR EQUAL TO - return rune(0x227c), true - case "pre": // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN - return rune(0x2aaf), true - case "prec": // PRECEDES - return rune(0x227a), true - case "precapprox": // PRECEDES ABOVE ALMOST EQUAL TO - return rune(0x2ab7), true - case "preccurlyeq": // PRECEDES OR EQUAL TO - return rune(0x227c), true - case "preceq": // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN - return rune(0x2aaf), true - case "precnapprox": // PRECEDES ABOVE NOT ALMOST EQUAL TO - return rune(0x2ab9), true - case "precneqq": // PRECEDES ABOVE NOT EQUAL TO - return rune(0x2ab5), true - case "precnsim": // PRECEDES BUT NOT EQUIVALENT TO - return rune(0x22e8), true - case "precsim": // PRECEDES OR EQUIVALENT TO - return rune(0x227e), true - case "prime": // PRIME - return rune(0x2032), true - case "primes": // DOUBLE-STRUCK CAPITAL P - return rune(0x2119), true - case "prnE": // PRECEDES ABOVE NOT EQUAL TO - return rune(0x2ab5), true - case "prnap": // PRECEDES ABOVE NOT ALMOST EQUAL TO - return rune(0x2ab9), true - case "prnsim": // PRECEDES BUT NOT EQUIVALENT TO - return rune(0x22e8), true - case "prod": // N-ARY PRODUCT - return rune(0x220f), true - case "profalar": // ALL AROUND-PROFILE - return rune(0x232e), true - case "profline": // ARC - return rune(0x2312), true - case "profsurf": // SEGMENT - return rune(0x2313), true - case "prop": // PROPORTIONAL TO - return rune(0x221d), true - case "propto": // PROPORTIONAL TO - return rune(0x221d), true - case "prsim": // PRECEDES OR EQUIVALENT TO - return rune(0x227e), true - case "prurel": // PRECEDES UNDER RELATION - return rune(0x22b0), true - case "pscr": // MATHEMATICAL SCRIPT SMALL P - return rune(0x01d4c5), true - case "psgr": // GREEK SMALL LETTER PSI - return rune(0x03c8), true - case "psi": // GREEK SMALL LETTER PSI - return rune(0x03c8), true - case "puncsp": // PUNCTUATION SPACE - return rune(0x2008), true + case "par": // PARALLEL TO + return rune(0x2225), true + case "para": // PILCROW SIGN + return rune(0xb6), true + case "parallel": // PARALLEL TO + return rune(0x2225), true + case "parsim": // PARALLEL WITH TILDE OPERATOR + return rune(0x2af3), true + case "parsl": // DOUBLE SOLIDUS OPERATOR + return rune(0x2afd), true + case "part": // PARTIAL DIFFERENTIAL + return rune(0x2202), true + case "pcy": // CYRILLIC SMALL LETTER PE + return rune(0x043f), true + case "percnt": // PERCENT SIGN + return rune(0x25), true + case "period": // FULL STOP + return rune(0x2e), true + case "permil": // PER MILLE SIGN + return rune(0x2030), true + case "perp": // UP TACK + return rune(0x22a5), true + case "pertenk": // PER TEN THOUSAND SIGN + return rune(0x2031), true + case "pfr": // MATHEMATICAL FRAKTUR SMALL P + return rune(0x01d52d), true + case "pgr": // GREEK SMALL LETTER PI + return rune(0x03c0), true + case "phgr": // GREEK SMALL LETTER PHI + return rune(0x03c6), true + case "phi": // GREEK SMALL LETTER PHI + return rune(0x03c6), true + case "phis": // GREEK PHI SYMBOL + return rune(0x03d5), true + case "phiv": // GREEK PHI SYMBOL + return rune(0x03d5), true + case "phmmat": // SCRIPT CAPITAL M + return rune(0x2133), true + case "phone": // BLACK TELEPHONE + return rune(0x260e), true + case "pi": // GREEK SMALL LETTER PI + return rune(0x03c0), true + case "pitchfork": // PITCHFORK + return rune(0x22d4), true + case "piv": // GREEK PI SYMBOL + return rune(0x03d6), true + case "planck": // PLANCK CONSTANT OVER TWO PI + return rune(0x210f), true + case "planckh": // PLANCK CONSTANT + return rune(0x210e), true + case "plankv": // PLANCK CONSTANT OVER TWO PI + return rune(0x210f), true + case "plus": // PLUS SIGN + return rune(0x2b), true + case "plusacir": // PLUS SIGN WITH CIRCUMFLEX ACCENT ABOVE + return rune(0x2a23), true + case "plusb": // SQUARED PLUS + return rune(0x229e), true + case "pluscir": // PLUS SIGN WITH SMALL CIRCLE ABOVE + return rune(0x2a22), true + case "plusdo": // DOT PLUS + return rune(0x2214), true + case "plusdu": // PLUS SIGN WITH DOT BELOW + return rune(0x2a25), true + case "pluse": // PLUS SIGN ABOVE EQUALS SIGN + return rune(0x2a72), true + case "plusmn": // PLUS-MINUS SIGN + return rune(0xb1), true + case "plussim": // PLUS SIGN WITH TILDE BELOW + return rune(0x2a26), true + case "plustrif": // PLUS SIGN WITH BLACK TRIANGLE + return rune(0x2a28), true + case "plustwo": // PLUS SIGN WITH SUBSCRIPT TWO + return rune(0x2a27), true + case "pm": // PLUS-MINUS SIGN + return rune(0xb1), true + case "pointint": // INTEGRAL AROUND A POINT OPERATOR + return rune(0x2a15), true + case "popf": // MATHEMATICAL DOUBLE-STRUCK SMALL P + return rune(0x01d561), true + case "pound": // POUND SIGN + return rune(0xa3), true + case "pr": // PRECEDES + return rune(0x227a), true + case "prE": // PRECEDES ABOVE EQUALS SIGN + return rune(0x2ab3), true + case "prap": // PRECEDES ABOVE ALMOST EQUAL TO + return rune(0x2ab7), true + case "prcue": // PRECEDES OR EQUAL TO + return rune(0x227c), true + case "pre": // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN + return rune(0x2aaf), true + case "prec": // PRECEDES + return rune(0x227a), true + case "precapprox": // PRECEDES ABOVE ALMOST EQUAL TO + return rune(0x2ab7), true + case "preccurlyeq": // PRECEDES OR EQUAL TO + return rune(0x227c), true + case "preceq": // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN + return rune(0x2aaf), true + case "precnapprox": // PRECEDES ABOVE NOT ALMOST EQUAL TO + return rune(0x2ab9), true + case "precneqq": // PRECEDES ABOVE NOT EQUAL TO + return rune(0x2ab5), true + case "precnsim": // PRECEDES BUT NOT EQUIVALENT TO + return rune(0x22e8), true + case "precsim": // PRECEDES OR EQUIVALENT TO + return rune(0x227e), true + case "prime": // PRIME + return rune(0x2032), true + case "primes": // DOUBLE-STRUCK CAPITAL P + return rune(0x2119), true + case "prnE": // PRECEDES ABOVE NOT EQUAL TO + return rune(0x2ab5), true + case "prnap": // PRECEDES ABOVE NOT ALMOST EQUAL TO + return rune(0x2ab9), true + case "prnsim": // PRECEDES BUT NOT EQUIVALENT TO + return rune(0x22e8), true + case "prod": // N-ARY PRODUCT + return rune(0x220f), true + case "profalar": // ALL AROUND-PROFILE + return rune(0x232e), true + case "profline": // ARC + return rune(0x2312), true + case "profsurf": // SEGMENT + return rune(0x2313), true + case "prop": // PROPORTIONAL TO + return rune(0x221d), true + case "propto": // PROPORTIONAL TO + return rune(0x221d), true + case "prsim": // PRECEDES OR EQUIVALENT TO + return rune(0x227e), true + case "prurel": // PRECEDES UNDER RELATION + return rune(0x22b0), true + case "pscr": // MATHEMATICAL SCRIPT SMALL P + return rune(0x01d4c5), true + case "psgr": // GREEK SMALL LETTER PSI + return rune(0x03c8), true + case "psi": // GREEK SMALL LETTER PSI + return rune(0x03c8), true + case "puncsp": // PUNCTUATION SPACE + return rune(0x2008), true } case 'q': switch name { - case "qfr": // MATHEMATICAL FRAKTUR SMALL Q - return rune(0x01d52e), true - case "qint": // QUADRUPLE INTEGRAL OPERATOR - return rune(0x2a0c), true - case "qopf": // MATHEMATICAL DOUBLE-STRUCK SMALL Q - return rune(0x01d562), true - case "qprime": // QUADRUPLE PRIME - return rune(0x2057), true - case "qscr": // MATHEMATICAL SCRIPT SMALL Q - return rune(0x01d4c6), true - case "quaternions": // DOUBLE-STRUCK CAPITAL H - return rune(0x210d), true - case "quatint": // QUATERNION INTEGRAL OPERATOR - return rune(0x2a16), true - case "quest": // QUESTION MARK - return rune(0x3f), true - case "questeq": // QUESTIONED EQUAL TO - return rune(0x225f), true - case "quot": // QUOTATION MARK - return rune(0x22), true + case "qfr": // MATHEMATICAL FRAKTUR SMALL Q + return rune(0x01d52e), true + case "qint": // QUADRUPLE INTEGRAL OPERATOR + return rune(0x2a0c), true + case "qopf": // MATHEMATICAL DOUBLE-STRUCK SMALL Q + return rune(0x01d562), true + case "qprime": // QUADRUPLE PRIME + return rune(0x2057), true + case "qscr": // MATHEMATICAL SCRIPT SMALL Q + return rune(0x01d4c6), true + case "quaternions": // DOUBLE-STRUCK CAPITAL H + return rune(0x210d), true + case "quatint": // QUATERNION INTEGRAL OPERATOR + return rune(0x2a16), true + case "quest": // QUESTION MARK + return rune(0x3f), true + case "questeq": // QUESTIONED EQUAL TO + return rune(0x225f), true + case "quot": // QUOTATION MARK + return rune(0x22), true } case 'r': switch name { - case "rAarr": // RIGHTWARDS TRIPLE ARROW - return rune(0x21db), true - case "rArr": // RIGHTWARDS DOUBLE ARROW - return rune(0x21d2), true - case "rAtail": // RIGHTWARDS DOUBLE ARROW-TAIL - return rune(0x291c), true - case "rBarr": // RIGHTWARDS TRIPLE DASH ARROW - return rune(0x290f), true - case "rHar": // RIGHTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB DOWN - return rune(0x2964), true - case "race": // REVERSED TILDE with underline - return rune(0x223d), true - case "racute": // LATIN SMALL LETTER R WITH ACUTE - return rune(0x0155), true - case "radic": // SQUARE ROOT - return rune(0x221a), true - case "raemptyv": // EMPTY SET WITH RIGHT ARROW ABOVE - return rune(0x29b3), true - case "rang": // MATHEMATICAL RIGHT ANGLE BRACKET - return rune(0x27e9), true - case "rangd": // RIGHT ANGLE BRACKET WITH DOT - return rune(0x2992), true - case "range": // REVERSED ANGLE WITH UNDERBAR - return rune(0x29a5), true - case "rangle": // MATHEMATICAL RIGHT ANGLE BRACKET - return rune(0x27e9), true - case "raquo": // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - return rune(0xbb), true - case "rarr": // RIGHTWARDS ARROW - return rune(0x2192), true - case "rarr2": // RIGHTWARDS PAIRED ARROWS - return rune(0x21c9), true - case "rarr3": // THREE RIGHTWARDS ARROWS - return rune(0x21f6), true - case "rarrap": // RIGHTWARDS ARROW ABOVE ALMOST EQUAL TO - return rune(0x2975), true - case "rarrb": // RIGHTWARDS ARROW TO BAR - return rune(0x21e5), true - case "rarrbfs": // RIGHTWARDS ARROW FROM BAR TO BLACK DIAMOND - return rune(0x2920), true - case "rarrc": // WAVE ARROW POINTING DIRECTLY RIGHT - return rune(0x2933), true - case "rarrfs": // RIGHTWARDS ARROW TO BLACK DIAMOND - return rune(0x291e), true - case "rarrhk": // RIGHTWARDS ARROW WITH HOOK - return rune(0x21aa), true - case "rarrlp": // RIGHTWARDS ARROW WITH LOOP - return rune(0x21ac), true - case "rarrpl": // RIGHTWARDS ARROW WITH PLUS BELOW - return rune(0x2945), true - case "rarrsim": // RIGHTWARDS ARROW ABOVE TILDE OPERATOR - return rune(0x2974), true - case "rarrtl": // RIGHTWARDS ARROW WITH TAIL - return rune(0x21a3), true - case "rarrw": // RIGHTWARDS WAVE ARROW - return rune(0x219d), true - case "rarrx": // RIGHTWARDS ARROW THROUGH X - return rune(0x2947), true - case "ratail": // RIGHTWARDS ARROW-TAIL - return rune(0x291a), true - case "ratio": // RATIO - return rune(0x2236), true - case "rationals": // DOUBLE-STRUCK CAPITAL Q - return rune(0x211a), true - case "rbarr": // RIGHTWARDS DOUBLE DASH ARROW - return rune(0x290d), true - case "rbbrk": // LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT - return rune(0x2773), true - case "rbrace": // RIGHT CURLY BRACKET - return rune(0x7d), true - case "rbrack": // RIGHT SQUARE BRACKET - return rune(0x5d), true - case "rbrke": // RIGHT SQUARE BRACKET WITH UNDERBAR - return rune(0x298c), true - case "rbrksld": // RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER - return rune(0x298e), true - case "rbrkslu": // RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER - return rune(0x2990), true - case "rcaron": // LATIN SMALL LETTER R WITH CARON - return rune(0x0159), true - case "rcedil": // LATIN SMALL LETTER R WITH CEDILLA - return rune(0x0157), true - case "rceil": // RIGHT CEILING - return rune(0x2309), true - case "rcub": // RIGHT CURLY BRACKET - return rune(0x7d), true - case "rcy": // CYRILLIC SMALL LETTER ER - return rune(0x0440), true - case "rdca": // ARROW POINTING DOWNWARDS THEN CURVING RIGHTWARDS - return rune(0x2937), true - case "rdharb": // RIGHTWARDS HARPOON WITH BARB DOWN TO BAR - return rune(0x2957), true - case "rdiag": // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT - return rune(0x2571), true - case "rdiofdi": // RISING DIAGONAL CROSSING FALLING DIAGONAL - return rune(0x292b), true - case "rdldhar": // RIGHTWARDS HARPOON WITH BARB DOWN ABOVE LEFTWARDS HARPOON WITH BARB DOWN - return rune(0x2969), true - case "rdosearr": // RISING DIAGONAL CROSSING SOUTH EAST ARROW - return rune(0x2930), true - case "rdquo": // RIGHT DOUBLE QUOTATION MARK - return rune(0x201d), true - case "rdquor": // RIGHT DOUBLE QUOTATION MARK - return rune(0x201d), true - case "rdsh": // DOWNWARDS ARROW WITH TIP RIGHTWARDS - return rune(0x21b3), true - case "real": // BLACK-LETTER CAPITAL R - return rune(0x211c), true - case "realine": // SCRIPT CAPITAL R - return rune(0x211b), true - case "realpart": // BLACK-LETTER CAPITAL R - return rune(0x211c), true - case "reals": // DOUBLE-STRUCK CAPITAL R - return rune(0x211d), true - case "rect": // WHITE RECTANGLE - return rune(0x25ad), true - case "reg": // REGISTERED SIGN - return rune(0xae), true - case "rfbowtie": // BOWTIE WITH RIGHT HALF BLACK - return rune(0x29d2), true - case "rfisht": // RIGHT FISH TAIL - return rune(0x297d), true - case "rfloor": // RIGHT FLOOR - return rune(0x230b), true - case "rfr": // MATHEMATICAL FRAKTUR SMALL R - return rune(0x01d52f), true - case "rftimes": // TIMES WITH RIGHT HALF BLACK - return rune(0x29d5), true - case "rgr": // GREEK SMALL LETTER RHO - return rune(0x03c1), true - case "rhard": // RIGHTWARDS HARPOON WITH BARB DOWNWARDS - return rune(0x21c1), true - case "rharu": // RIGHTWARDS HARPOON WITH BARB UPWARDS - return rune(0x21c0), true - case "rharul": // RIGHTWARDS HARPOON WITH BARB UP ABOVE LONG DASH - return rune(0x296c), true - case "rho": // GREEK SMALL LETTER RHO - return rune(0x03c1), true - case "rhov": // GREEK RHO SYMBOL - return rune(0x03f1), true - case "rightarrow": // RIGHTWARDS ARROW - return rune(0x2192), true - case "rightarrowtail": // RIGHTWARDS ARROW WITH TAIL - return rune(0x21a3), true - case "rightharpoondown": // RIGHTWARDS HARPOON WITH BARB DOWNWARDS - return rune(0x21c1), true - case "rightharpoonup": // RIGHTWARDS HARPOON WITH BARB UPWARDS - return rune(0x21c0), true - case "rightleftarrows": // RIGHTWARDS ARROW OVER LEFTWARDS ARROW - return rune(0x21c4), true - case "rightleftharpoons": // RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON - return rune(0x21cc), true - case "rightrightarrows": // RIGHTWARDS PAIRED ARROWS - return rune(0x21c9), true - case "rightsquigarrow": // RIGHTWARDS WAVE ARROW - return rune(0x219d), true - case "rightthreetimes": // RIGHT SEMIDIRECT PRODUCT - return rune(0x22cc), true - case "rimply": // RIGHT DOUBLE ARROW WITH ROUNDED HEAD - return rune(0x2970), true - case "ring": // RING ABOVE - return rune(0x02da), true - case "risingdotseq": // IMAGE OF OR APPROXIMATELY EQUAL TO - return rune(0x2253), true - case "rlarr": // RIGHTWARDS ARROW OVER LEFTWARDS ARROW - return rune(0x21c4), true - case "rlarr2": // RIGHTWARDS ARROW OVER LEFTWARDS ARROW - return rune(0x21c4), true - case "rlhar": // RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON - return rune(0x21cc), true - case "rlhar2": // RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON - return rune(0x21cc), true - case "rlm": // RIGHT-TO-LEFT MARK - return rune(0x200f), true - case "rmoust": // UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION - return rune(0x23b1), true - case "rmoustache": // UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION - return rune(0x23b1), true - case "rnmid": // DOES NOT DIVIDE WITH REVERSED NEGATION SLASH - return rune(0x2aee), true - case "roang": // MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET - return rune(0x27ed), true - case "roarr": // RIGHTWARDS OPEN-HEADED ARROW - return rune(0x21fe), true - case "robrk": // MATHEMATICAL RIGHT WHITE SQUARE BRACKET - return rune(0x27e7), true - case "rocub": // RIGHT WHITE CURLY BRACKET - return rune(0x2984), true - case "ropar": // RIGHT WHITE PARENTHESIS - return rune(0x2986), true - case "ropf": // MATHEMATICAL DOUBLE-STRUCK SMALL R - return rune(0x01d563), true - case "roplus": // PLUS SIGN IN RIGHT HALF CIRCLE - return rune(0x2a2e), true - case "rotimes": // MULTIPLICATION SIGN IN RIGHT HALF CIRCLE - return rune(0x2a35), true - case "rpar": // RIGHT PARENTHESIS - return rune(0x29), true - case "rpargt": // RIGHT ARC GREATER-THAN BRACKET - return rune(0x2994), true - case "rppolint": // LINE INTEGRATION WITH RECTANGULAR PATH AROUND POLE - return rune(0x2a12), true - case "rrarr": // RIGHTWARDS PAIRED ARROWS - return rune(0x21c9), true - case "rsaquo": // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK - return rune(0x203a), true - case "rscr": // MATHEMATICAL SCRIPT SMALL R - return rune(0x01d4c7), true - case "rsh": // UPWARDS ARROW WITH TIP RIGHTWARDS - return rune(0x21b1), true - case "rsolbar": // REVERSE SOLIDUS WITH HORIZONTAL STROKE - return rune(0x29f7), true - case "rsqb": // RIGHT SQUARE BRACKET - return rune(0x5d), true - case "rsquo": // RIGHT SINGLE QUOTATION MARK - return rune(0x2019), true - case "rsquor": // RIGHT SINGLE QUOTATION MARK - return rune(0x2019), true - case "rthree": // RIGHT SEMIDIRECT PRODUCT - return rune(0x22cc), true - case "rtimes": // RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT - return rune(0x22ca), true - case "rtri": // WHITE RIGHT-POINTING SMALL TRIANGLE - return rune(0x25b9), true - case "rtrie": // CONTAINS AS NORMAL SUBGROUP OR EQUAL TO - return rune(0x22b5), true - case "rtrif": // BLACK RIGHT-POINTING SMALL TRIANGLE - return rune(0x25b8), true - case "rtriltri": // RIGHT TRIANGLE ABOVE LEFT TRIANGLE - return rune(0x29ce), true - case "ruharb": // RIGHTWARDS HARPOON WITH BARB UP TO BAR - return rune(0x2953), true - case "ruluhar": // RIGHTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB UP - return rune(0x2968), true - case "rx": // PRESCRIPTION TAKE - return rune(0x211e), true + case "rAarr": // RIGHTWARDS TRIPLE ARROW + return rune(0x21db), true + case "rArr": // RIGHTWARDS DOUBLE ARROW + return rune(0x21d2), true + case "rAtail": // RIGHTWARDS DOUBLE ARROW-TAIL + return rune(0x291c), true + case "rBarr": // RIGHTWARDS TRIPLE DASH ARROW + return rune(0x290f), true + case "rHar": // RIGHTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB DOWN + return rune(0x2964), true + case "race": // REVERSED TILDE with underline + return rune(0x223d), true + case "racute": // LATIN SMALL LETTER R WITH ACUTE + return rune(0x0155), true + case "radic": // SQUARE ROOT + return rune(0x221a), true + case "raemptyv": // EMPTY SET WITH RIGHT ARROW ABOVE + return rune(0x29b3), true + case "rang": // MATHEMATICAL RIGHT ANGLE BRACKET + return rune(0x27e9), true + case "rangd": // RIGHT ANGLE BRACKET WITH DOT + return rune(0x2992), true + case "range": // REVERSED ANGLE WITH UNDERBAR + return rune(0x29a5), true + case "rangle": // MATHEMATICAL RIGHT ANGLE BRACKET + return rune(0x27e9), true + case "raquo": // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + return rune(0xbb), true + case "rarr": // RIGHTWARDS ARROW + return rune(0x2192), true + case "rarr2": // RIGHTWARDS PAIRED ARROWS + return rune(0x21c9), true + case "rarr3": // THREE RIGHTWARDS ARROWS + return rune(0x21f6), true + case "rarrap": // RIGHTWARDS ARROW ABOVE ALMOST EQUAL TO + return rune(0x2975), true + case "rarrb": // RIGHTWARDS ARROW TO BAR + return rune(0x21e5), true + case "rarrbfs": // RIGHTWARDS ARROW FROM BAR TO BLACK DIAMOND + return rune(0x2920), true + case "rarrc": // WAVE ARROW POINTING DIRECTLY RIGHT + return rune(0x2933), true + case "rarrfs": // RIGHTWARDS ARROW TO BLACK DIAMOND + return rune(0x291e), true + case "rarrhk": // RIGHTWARDS ARROW WITH HOOK + return rune(0x21aa), true + case "rarrlp": // RIGHTWARDS ARROW WITH LOOP + return rune(0x21ac), true + case "rarrpl": // RIGHTWARDS ARROW WITH PLUS BELOW + return rune(0x2945), true + case "rarrsim": // RIGHTWARDS ARROW ABOVE TILDE OPERATOR + return rune(0x2974), true + case "rarrtl": // RIGHTWARDS ARROW WITH TAIL + return rune(0x21a3), true + case "rarrw": // RIGHTWARDS WAVE ARROW + return rune(0x219d), true + case "rarrx": // RIGHTWARDS ARROW THROUGH X + return rune(0x2947), true + case "ratail": // RIGHTWARDS ARROW-TAIL + return rune(0x291a), true + case "ratio": // RATIO + return rune(0x2236), true + case "rationals": // DOUBLE-STRUCK CAPITAL Q + return rune(0x211a), true + case "rbarr": // RIGHTWARDS DOUBLE DASH ARROW + return rune(0x290d), true + case "rbbrk": // LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT + return rune(0x2773), true + case "rbrace": // RIGHT CURLY BRACKET + return rune(0x7d), true + case "rbrack": // RIGHT SQUARE BRACKET + return rune(0x5d), true + case "rbrke": // RIGHT SQUARE BRACKET WITH UNDERBAR + return rune(0x298c), true + case "rbrksld": // RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER + return rune(0x298e), true + case "rbrkslu": // RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER + return rune(0x2990), true + case "rcaron": // LATIN SMALL LETTER R WITH CARON + return rune(0x0159), true + case "rcedil": // LATIN SMALL LETTER R WITH CEDILLA + return rune(0x0157), true + case "rceil": // RIGHT CEILING + return rune(0x2309), true + case "rcub": // RIGHT CURLY BRACKET + return rune(0x7d), true + case "rcy": // CYRILLIC SMALL LETTER ER + return rune(0x0440), true + case "rdca": // ARROW POINTING DOWNWARDS THEN CURVING RIGHTWARDS + return rune(0x2937), true + case "rdharb": // RIGHTWARDS HARPOON WITH BARB DOWN TO BAR + return rune(0x2957), true + case "rdiag": // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT + return rune(0x2571), true + case "rdiofdi": // RISING DIAGONAL CROSSING FALLING DIAGONAL + return rune(0x292b), true + case "rdldhar": // RIGHTWARDS HARPOON WITH BARB DOWN ABOVE LEFTWARDS HARPOON WITH BARB DOWN + return rune(0x2969), true + case "rdosearr": // RISING DIAGONAL CROSSING SOUTH EAST ARROW + return rune(0x2930), true + case "rdquo": // RIGHT DOUBLE QUOTATION MARK + return rune(0x201d), true + case "rdquor": // RIGHT DOUBLE QUOTATION MARK + return rune(0x201d), true + case "rdsh": // DOWNWARDS ARROW WITH TIP RIGHTWARDS + return rune(0x21b3), true + case "real": // BLACK-LETTER CAPITAL R + return rune(0x211c), true + case "realine": // SCRIPT CAPITAL R + return rune(0x211b), true + case "realpart": // BLACK-LETTER CAPITAL R + return rune(0x211c), true + case "reals": // DOUBLE-STRUCK CAPITAL R + return rune(0x211d), true + case "rect": // WHITE RECTANGLE + return rune(0x25ad), true + case "reg": // REGISTERED SIGN + return rune(0xae), true + case "rfbowtie": // BOWTIE WITH RIGHT HALF BLACK + return rune(0x29d2), true + case "rfisht": // RIGHT FISH TAIL + return rune(0x297d), true + case "rfloor": // RIGHT FLOOR + return rune(0x230b), true + case "rfr": // MATHEMATICAL FRAKTUR SMALL R + return rune(0x01d52f), true + case "rftimes": // TIMES WITH RIGHT HALF BLACK + return rune(0x29d5), true + case "rgr": // GREEK SMALL LETTER RHO + return rune(0x03c1), true + case "rhard": // RIGHTWARDS HARPOON WITH BARB DOWNWARDS + return rune(0x21c1), true + case "rharu": // RIGHTWARDS HARPOON WITH BARB UPWARDS + return rune(0x21c0), true + case "rharul": // RIGHTWARDS HARPOON WITH BARB UP ABOVE LONG DASH + return rune(0x296c), true + case "rho": // GREEK SMALL LETTER RHO + return rune(0x03c1), true + case "rhov": // GREEK RHO SYMBOL + return rune(0x03f1), true + case "rightarrow": // RIGHTWARDS ARROW + return rune(0x2192), true + case "rightarrowtail": // RIGHTWARDS ARROW WITH TAIL + return rune(0x21a3), true + case "rightharpoondown": // RIGHTWARDS HARPOON WITH BARB DOWNWARDS + return rune(0x21c1), true + case "rightharpoonup": // RIGHTWARDS HARPOON WITH BARB UPWARDS + return rune(0x21c0), true + case "rightleftarrows": // RIGHTWARDS ARROW OVER LEFTWARDS ARROW + return rune(0x21c4), true + case "rightleftharpoons": // RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON + return rune(0x21cc), true + case "rightrightarrows": // RIGHTWARDS PAIRED ARROWS + return rune(0x21c9), true + case "rightsquigarrow": // RIGHTWARDS WAVE ARROW + return rune(0x219d), true + case "rightthreetimes": // RIGHT SEMIDIRECT PRODUCT + return rune(0x22cc), true + case "rimply": // RIGHT DOUBLE ARROW WITH ROUNDED HEAD + return rune(0x2970), true + case "ring": // RING ABOVE + return rune(0x02da), true + case "risingdotseq": // IMAGE OF OR APPROXIMATELY EQUAL TO + return rune(0x2253), true + case "rlarr": // RIGHTWARDS ARROW OVER LEFTWARDS ARROW + return rune(0x21c4), true + case "rlarr2": // RIGHTWARDS ARROW OVER LEFTWARDS ARROW + return rune(0x21c4), true + case "rlhar": // RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON + return rune(0x21cc), true + case "rlhar2": // RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON + return rune(0x21cc), true + case "rlm": // RIGHT-TO-LEFT MARK + return rune(0x200f), true + case "rmoust": // UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION + return rune(0x23b1), true + case "rmoustache": // UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION + return rune(0x23b1), true + case "rnmid": // DOES NOT DIVIDE WITH REVERSED NEGATION SLASH + return rune(0x2aee), true + case "roang": // MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET + return rune(0x27ed), true + case "roarr": // RIGHTWARDS OPEN-HEADED ARROW + return rune(0x21fe), true + case "robrk": // MATHEMATICAL RIGHT WHITE SQUARE BRACKET + return rune(0x27e7), true + case "rocub": // RIGHT WHITE CURLY BRACKET + return rune(0x2984), true + case "ropar": // RIGHT WHITE PARENTHESIS + return rune(0x2986), true + case "ropf": // MATHEMATICAL DOUBLE-STRUCK SMALL R + return rune(0x01d563), true + case "roplus": // PLUS SIGN IN RIGHT HALF CIRCLE + return rune(0x2a2e), true + case "rotimes": // MULTIPLICATION SIGN IN RIGHT HALF CIRCLE + return rune(0x2a35), true + case "rpar": // RIGHT PARENTHESIS + return rune(0x29), true + case "rpargt": // RIGHT ARC GREATER-THAN BRACKET + return rune(0x2994), true + case "rppolint": // LINE INTEGRATION WITH RECTANGULAR PATH AROUND POLE + return rune(0x2a12), true + case "rrarr": // RIGHTWARDS PAIRED ARROWS + return rune(0x21c9), true + case "rsaquo": // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + return rune(0x203a), true + case "rscr": // MATHEMATICAL SCRIPT SMALL R + return rune(0x01d4c7), true + case "rsh": // UPWARDS ARROW WITH TIP RIGHTWARDS + return rune(0x21b1), true + case "rsolbar": // REVERSE SOLIDUS WITH HORIZONTAL STROKE + return rune(0x29f7), true + case "rsqb": // RIGHT SQUARE BRACKET + return rune(0x5d), true + case "rsquo": // RIGHT SINGLE QUOTATION MARK + return rune(0x2019), true + case "rsquor": // RIGHT SINGLE QUOTATION MARK + return rune(0x2019), true + case "rthree": // RIGHT SEMIDIRECT PRODUCT + return rune(0x22cc), true + case "rtimes": // RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT + return rune(0x22ca), true + case "rtri": // WHITE RIGHT-POINTING SMALL TRIANGLE + return rune(0x25b9), true + case "rtrie": // CONTAINS AS NORMAL SUBGROUP OR EQUAL TO + return rune(0x22b5), true + case "rtrif": // BLACK RIGHT-POINTING SMALL TRIANGLE + return rune(0x25b8), true + case "rtriltri": // RIGHT TRIANGLE ABOVE LEFT TRIANGLE + return rune(0x29ce), true + case "ruharb": // RIGHTWARDS HARPOON WITH BARB UP TO BAR + return rune(0x2953), true + case "ruluhar": // RIGHTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB UP + return rune(0x2968), true + case "rx": // PRESCRIPTION TAKE + return rune(0x211e), true } case 's': switch name { - case "sacute": // LATIN SMALL LETTER S WITH ACUTE - return rune(0x015b), true - case "samalg": // N-ARY COPRODUCT - return rune(0x2210), true - case "sampi": // GREEK LETTER SAMPI - return rune(0x03e0), true - case "sbquo": // SINGLE LOW-9 QUOTATION MARK - return rune(0x201a), true - case "sbsol": // SMALL REVERSE SOLIDUS - return rune(0xfe68), true - case "sc": // SUCCEEDS - return rune(0x227b), true - case "scE": // SUCCEEDS ABOVE EQUALS SIGN - return rune(0x2ab4), true - case "scap": // SUCCEEDS ABOVE ALMOST EQUAL TO - return rune(0x2ab8), true - case "scaron": // LATIN SMALL LETTER S WITH CARON - return rune(0x0161), true - case "sccue": // SUCCEEDS OR EQUAL TO - return rune(0x227d), true - case "sce": // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN - return rune(0x2ab0), true - case "scedil": // LATIN SMALL LETTER S WITH CEDILLA - return rune(0x015f), true - case "scirc": // LATIN SMALL LETTER S WITH CIRCUMFLEX - return rune(0x015d), true - case "scnE": // SUCCEEDS ABOVE NOT EQUAL TO - return rune(0x2ab6), true - case "scnap": // SUCCEEDS ABOVE NOT ALMOST EQUAL TO - return rune(0x2aba), true - case "scnsim": // SUCCEEDS BUT NOT EQUIVALENT TO - return rune(0x22e9), true - case "scpolint": // LINE INTEGRATION WITH SEMICIRCULAR PATH AROUND POLE - return rune(0x2a13), true - case "scsim": // SUCCEEDS OR EQUIVALENT TO - return rune(0x227f), true - case "scy": // CYRILLIC SMALL LETTER ES - return rune(0x0441), true - case "sdot": // DOT OPERATOR - return rune(0x22c5), true - case "sdotb": // SQUARED DOT OPERATOR - return rune(0x22a1), true - case "sdote": // EQUALS SIGN WITH DOT BELOW - return rune(0x2a66), true - case "seArr": // SOUTH EAST DOUBLE ARROW - return rune(0x21d8), true - case "searhk": // SOUTH EAST ARROW WITH HOOK - return rune(0x2925), true - case "searr": // SOUTH EAST ARROW - return rune(0x2198), true - case "searrow": // SOUTH EAST ARROW - return rune(0x2198), true - case "sect": // SECTION SIGN - return rune(0xa7), true - case "semi": // SEMICOLON - return rune(0x3b), true - case "seonearr": // SOUTH EAST ARROW CROSSING NORTH EAST ARROW - return rune(0x292d), true - case "seswar": // SOUTH EAST ARROW AND SOUTH WEST ARROW - return rune(0x2929), true - case "setminus": // SET MINUS - return rune(0x2216), true - case "setmn": // SET MINUS - return rune(0x2216), true - case "sext": // SIX POINTED BLACK STAR - return rune(0x2736), true - case "sfgr": // GREEK SMALL LETTER FINAL SIGMA - return rune(0x03c2), true - case "sfr": // MATHEMATICAL FRAKTUR SMALL S - return rune(0x01d530), true - case "sfrown": // FROWN - return rune(0x2322), true - case "sgr": // GREEK SMALL LETTER SIGMA - return rune(0x03c3), true - case "sharp": // MUSIC SHARP SIGN - return rune(0x266f), true - case "shchcy": // CYRILLIC SMALL LETTER SHCHA - return rune(0x0449), true - case "shcy": // CYRILLIC SMALL LETTER SHA - return rune(0x0448), true - case "shortmid": // DIVIDES - return rune(0x2223), true - case "shortparallel": // PARALLEL TO - return rune(0x2225), true - case "shuffle": // SHUFFLE PRODUCT - return rune(0x29e2), true - case "shy": // SOFT HYPHEN - return rune(0xad), true - case "sigma": // GREEK SMALL LETTER SIGMA - return rune(0x03c3), true - case "sigmaf": // GREEK SMALL LETTER FINAL SIGMA - return rune(0x03c2), true - case "sigmav": // GREEK SMALL LETTER FINAL SIGMA - return rune(0x03c2), true - case "sim": // TILDE OPERATOR - return rune(0x223c), true - case "simdot": // TILDE OPERATOR WITH DOT ABOVE - return rune(0x2a6a), true - case "sime": // ASYMPTOTICALLY EQUAL TO - return rune(0x2243), true - case "simeq": // ASYMPTOTICALLY EQUAL TO - return rune(0x2243), true - case "simg": // SIMILAR OR GREATER-THAN - return rune(0x2a9e), true - case "simgE": // SIMILAR ABOVE GREATER-THAN ABOVE EQUALS SIGN - return rune(0x2aa0), true - case "siml": // SIMILAR OR LESS-THAN - return rune(0x2a9d), true - case "simlE": // SIMILAR ABOVE LESS-THAN ABOVE EQUALS SIGN - return rune(0x2a9f), true - case "simne": // APPROXIMATELY BUT NOT ACTUALLY EQUAL TO - return rune(0x2246), true - case "simplus": // PLUS SIGN WITH TILDE ABOVE - return rune(0x2a24), true - case "simrarr": // TILDE OPERATOR ABOVE RIGHTWARDS ARROW - return rune(0x2972), true - case "slarr": // LEFTWARDS ARROW - return rune(0x2190), true - case "slint": // INTEGRAL AVERAGE WITH SLASH - return rune(0x2a0f), true - case "smallsetminus": // SET MINUS - return rune(0x2216), true - case "smashp": // SMASH PRODUCT - return rune(0x2a33), true - case "smeparsl": // EQUALS SIGN AND SLANTED PARALLEL WITH TILDE ABOVE - return rune(0x29e4), true - case "smid": // DIVIDES - return rune(0x2223), true - case "smile": // SMILE - return rune(0x2323), true - case "smt": // SMALLER THAN - return rune(0x2aaa), true - case "smte": // SMALLER THAN OR EQUAL TO - return rune(0x2aac), true - case "smtes": // SMALLER THAN OR slanted EQUAL - return rune(0x2aac), true - case "softcy": // CYRILLIC SMALL LETTER SOFT SIGN - return rune(0x044c), true - case "sol": // SOLIDUS - return rune(0x2f), true - case "solb": // SQUARED RISING DIAGONAL SLASH - return rune(0x29c4), true - case "solbar": // APL FUNCTIONAL SYMBOL SLASH BAR - return rune(0x233f), true - case "sopf": // MATHEMATICAL DOUBLE-STRUCK SMALL S - return rune(0x01d564), true - case "spades": // BLACK SPADE SUIT - return rune(0x2660), true - case "spadesuit": // BLACK SPADE SUIT - return rune(0x2660), true - case "spar": // PARALLEL TO - return rune(0x2225), true - case "sqcap": // SQUARE CAP - return rune(0x2293), true - case "sqcaps": // SQUARE CAP with serifs - return rune(0x2293), true - case "sqcup": // SQUARE CUP - return rune(0x2294), true - case "sqcups": // SQUARE CUP with serifs - return rune(0x2294), true - case "sqsub": // SQUARE IMAGE OF - return rune(0x228f), true - case "sqsube": // SQUARE IMAGE OF OR EQUAL TO - return rune(0x2291), true - case "sqsubset": // SQUARE IMAGE OF - return rune(0x228f), true - case "sqsubseteq": // SQUARE IMAGE OF OR EQUAL TO - return rune(0x2291), true - case "sqsup": // SQUARE ORIGINAL OF - return rune(0x2290), true - case "sqsupe": // SQUARE ORIGINAL OF OR EQUAL TO - return rune(0x2292), true - case "sqsupset": // SQUARE ORIGINAL OF - return rune(0x2290), true - case "sqsupseteq": // SQUARE ORIGINAL OF OR EQUAL TO - return rune(0x2292), true - case "squ": // WHITE SQUARE - return rune(0x25a1), true - case "square": // WHITE SQUARE - return rune(0x25a1), true - case "squarf": // BLACK SMALL SQUARE - return rune(0x25aa), true - case "squb": // SQUARED SQUARE - return rune(0x29c8), true - case "squerr": // ERROR-BARRED WHITE SQUARE - return rune(0x29ee), true - case "squf": // BLACK SMALL SQUARE - return rune(0x25aa), true - case "squferr": // ERROR-BARRED BLACK SQUARE - return rune(0x29ef), true - case "srarr": // RIGHTWARDS ARROW - return rune(0x2192), true - case "sscr": // MATHEMATICAL SCRIPT SMALL S - return rune(0x01d4c8), true - case "ssetmn": // SET MINUS - return rune(0x2216), true - case "ssmile": // SMILE - return rune(0x2323), true - case "sstarf": // STAR OPERATOR - return rune(0x22c6), true - case "star": // WHITE STAR - return rune(0x2606), true - case "starf": // BLACK STAR - return rune(0x2605), true - case "stigma": // GREEK LETTER STIGMA - return rune(0x03da), true - case "straightepsilon": // GREEK LUNATE EPSILON SYMBOL - return rune(0x03f5), true - case "straightphi": // GREEK PHI SYMBOL - return rune(0x03d5), true - case "strns": // MACRON - return rune(0xaf), true - case "sub": // SUBSET OF - return rune(0x2282), true - case "subE": // SUBSET OF ABOVE EQUALS SIGN - return rune(0x2ac5), true - case "subdot": // SUBSET WITH DOT - return rune(0x2abd), true - case "sube": // SUBSET OF OR EQUAL TO - return rune(0x2286), true - case "subedot": // SUBSET OF OR EQUAL TO WITH DOT ABOVE - return rune(0x2ac3), true - case "submult": // SUBSET WITH MULTIPLICATION SIGN BELOW - return rune(0x2ac1), true - case "subnE": // SUBSET OF ABOVE NOT EQUAL TO - return rune(0x2acb), true - case "subne": // SUBSET OF WITH NOT EQUAL TO - return rune(0x228a), true - case "subplus": // SUBSET WITH PLUS SIGN BELOW - return rune(0x2abf), true - case "subrarr": // SUBSET ABOVE RIGHTWARDS ARROW - return rune(0x2979), true - case "subset": // SUBSET OF - return rune(0x2282), true - case "subseteq": // SUBSET OF OR EQUAL TO - return rune(0x2286), true - case "subseteqq": // SUBSET OF ABOVE EQUALS SIGN - return rune(0x2ac5), true - case "subsetneq": // SUBSET OF WITH NOT EQUAL TO - return rune(0x228a), true - case "subsetneqq": // SUBSET OF ABOVE NOT EQUAL TO - return rune(0x2acb), true - case "subsim": // SUBSET OF ABOVE TILDE OPERATOR - return rune(0x2ac7), true - case "subsub": // SUBSET ABOVE SUBSET - return rune(0x2ad5), true - case "subsup": // SUBSET ABOVE SUPERSET - return rune(0x2ad3), true - case "succ": // SUCCEEDS - return rune(0x227b), true - case "succapprox": // SUCCEEDS ABOVE ALMOST EQUAL TO - return rune(0x2ab8), true - case "succcurlyeq": // SUCCEEDS OR EQUAL TO - return rune(0x227d), true - case "succeq": // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN - return rune(0x2ab0), true - case "succnapprox": // SUCCEEDS ABOVE NOT ALMOST EQUAL TO - return rune(0x2aba), true - case "succneqq": // SUCCEEDS ABOVE NOT EQUAL TO - return rune(0x2ab6), true - case "succnsim": // SUCCEEDS BUT NOT EQUIVALENT TO - return rune(0x22e9), true - case "succsim": // SUCCEEDS OR EQUIVALENT TO - return rune(0x227f), true - case "sum": // N-ARY SUMMATION - return rune(0x2211), true - case "sumint": // SUMMATION WITH INTEGRAL - return rune(0x2a0b), true - case "sung": // EIGHTH NOTE - return rune(0x266a), true - case "sup": // SUPERSET OF - return rune(0x2283), true - case "sup1": // SUPERSCRIPT ONE - return rune(0xb9), true - case "sup2": // SUPERSCRIPT TWO - return rune(0xb2), true - case "sup3": // SUPERSCRIPT THREE - return rune(0xb3), true - case "supE": // SUPERSET OF ABOVE EQUALS SIGN - return rune(0x2ac6), true - case "supdot": // SUPERSET WITH DOT - return rune(0x2abe), true - case "supdsub": // SUPERSET BESIDE AND JOINED BY DASH WITH SUBSET - return rune(0x2ad8), true - case "supe": // SUPERSET OF OR EQUAL TO - return rune(0x2287), true - case "supedot": // SUPERSET OF OR EQUAL TO WITH DOT ABOVE - return rune(0x2ac4), true - case "suphsol": // SUPERSET PRECEDING SOLIDUS - return rune(0x27c9), true - case "suphsub": // SUPERSET BESIDE SUBSET - return rune(0x2ad7), true - case "suplarr": // SUPERSET ABOVE LEFTWARDS ARROW - return rune(0x297b), true - case "supmult": // SUPERSET WITH MULTIPLICATION SIGN BELOW - return rune(0x2ac2), true - case "supnE": // SUPERSET OF ABOVE NOT EQUAL TO - return rune(0x2acc), true - case "supne": // SUPERSET OF WITH NOT EQUAL TO - return rune(0x228b), true - case "supplus": // SUPERSET WITH PLUS SIGN BELOW - return rune(0x2ac0), true - case "supset": // SUPERSET OF - return rune(0x2283), true - case "supseteq": // SUPERSET OF OR EQUAL TO - return rune(0x2287), true - case "supseteqq": // SUPERSET OF ABOVE EQUALS SIGN - return rune(0x2ac6), true - case "supsetneq": // SUPERSET OF WITH NOT EQUAL TO - return rune(0x228b), true - case "supsetneqq": // SUPERSET OF ABOVE NOT EQUAL TO - return rune(0x2acc), true - case "supsim": // SUPERSET OF ABOVE TILDE OPERATOR - return rune(0x2ac8), true - case "supsub": // SUPERSET ABOVE SUBSET - return rune(0x2ad4), true - case "supsup": // SUPERSET ABOVE SUPERSET - return rune(0x2ad6), true - case "swArr": // SOUTH WEST DOUBLE ARROW - return rune(0x21d9), true - case "swarhk": // SOUTH WEST ARROW WITH HOOK - return rune(0x2926), true - case "swarr": // SOUTH WEST ARROW - return rune(0x2199), true - case "swarrow": // SOUTH WEST ARROW - return rune(0x2199), true - case "swnwar": // SOUTH WEST ARROW AND NORTH WEST ARROW - return rune(0x292a), true - case "szlig": // LATIN SMALL LETTER SHARP S - return rune(0xdf), true + case "sacute": // LATIN SMALL LETTER S WITH ACUTE + return rune(0x015b), true + case "samalg": // N-ARY COPRODUCT + return rune(0x2210), true + case "sampi": // GREEK LETTER SAMPI + return rune(0x03e0), true + case "sbquo": // SINGLE LOW-9 QUOTATION MARK + return rune(0x201a), true + case "sbsol": // SMALL REVERSE SOLIDUS + return rune(0xfe68), true + case "sc": // SUCCEEDS + return rune(0x227b), true + case "scE": // SUCCEEDS ABOVE EQUALS SIGN + return rune(0x2ab4), true + case "scap": // SUCCEEDS ABOVE ALMOST EQUAL TO + return rune(0x2ab8), true + case "scaron": // LATIN SMALL LETTER S WITH CARON + return rune(0x0161), true + case "sccue": // SUCCEEDS OR EQUAL TO + return rune(0x227d), true + case "sce": // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN + return rune(0x2ab0), true + case "scedil": // LATIN SMALL LETTER S WITH CEDILLA + return rune(0x015f), true + case "scirc": // LATIN SMALL LETTER S WITH CIRCUMFLEX + return rune(0x015d), true + case "scnE": // SUCCEEDS ABOVE NOT EQUAL TO + return rune(0x2ab6), true + case "scnap": // SUCCEEDS ABOVE NOT ALMOST EQUAL TO + return rune(0x2aba), true + case "scnsim": // SUCCEEDS BUT NOT EQUIVALENT TO + return rune(0x22e9), true + case "scpolint": // LINE INTEGRATION WITH SEMICIRCULAR PATH AROUND POLE + return rune(0x2a13), true + case "scsim": // SUCCEEDS OR EQUIVALENT TO + return rune(0x227f), true + case "scy": // CYRILLIC SMALL LETTER ES + return rune(0x0441), true + case "sdot": // DOT OPERATOR + return rune(0x22c5), true + case "sdotb": // SQUARED DOT OPERATOR + return rune(0x22a1), true + case "sdote": // EQUALS SIGN WITH DOT BELOW + return rune(0x2a66), true + case "seArr": // SOUTH EAST DOUBLE ARROW + return rune(0x21d8), true + case "searhk": // SOUTH EAST ARROW WITH HOOK + return rune(0x2925), true + case "searr": // SOUTH EAST ARROW + return rune(0x2198), true + case "searrow": // SOUTH EAST ARROW + return rune(0x2198), true + case "sect": // SECTION SIGN + return rune(0xa7), true + case "semi": // SEMICOLON + return rune(0x3b), true + case "seonearr": // SOUTH EAST ARROW CROSSING NORTH EAST ARROW + return rune(0x292d), true + case "seswar": // SOUTH EAST ARROW AND SOUTH WEST ARROW + return rune(0x2929), true + case "setminus": // SET MINUS + return rune(0x2216), true + case "setmn": // SET MINUS + return rune(0x2216), true + case "sext": // SIX POINTED BLACK STAR + return rune(0x2736), true + case "sfgr": // GREEK SMALL LETTER FINAL SIGMA + return rune(0x03c2), true + case "sfr": // MATHEMATICAL FRAKTUR SMALL S + return rune(0x01d530), true + case "sfrown": // FROWN + return rune(0x2322), true + case "sgr": // GREEK SMALL LETTER SIGMA + return rune(0x03c3), true + case "sharp": // MUSIC SHARP SIGN + return rune(0x266f), true + case "shchcy": // CYRILLIC SMALL LETTER SHCHA + return rune(0x0449), true + case "shcy": // CYRILLIC SMALL LETTER SHA + return rune(0x0448), true + case "shortmid": // DIVIDES + return rune(0x2223), true + case "shortparallel": // PARALLEL TO + return rune(0x2225), true + case "shuffle": // SHUFFLE PRODUCT + return rune(0x29e2), true + case "shy": // SOFT HYPHEN + return rune(0xad), true + case "sigma": // GREEK SMALL LETTER SIGMA + return rune(0x03c3), true + case "sigmaf": // GREEK SMALL LETTER FINAL SIGMA + return rune(0x03c2), true + case "sigmav": // GREEK SMALL LETTER FINAL SIGMA + return rune(0x03c2), true + case "sim": // TILDE OPERATOR + return rune(0x223c), true + case "simdot": // TILDE OPERATOR WITH DOT ABOVE + return rune(0x2a6a), true + case "sime": // ASYMPTOTICALLY EQUAL TO + return rune(0x2243), true + case "simeq": // ASYMPTOTICALLY EQUAL TO + return rune(0x2243), true + case "simg": // SIMILAR OR GREATER-THAN + return rune(0x2a9e), true + case "simgE": // SIMILAR ABOVE GREATER-THAN ABOVE EQUALS SIGN + return rune(0x2aa0), true + case "siml": // SIMILAR OR LESS-THAN + return rune(0x2a9d), true + case "simlE": // SIMILAR ABOVE LESS-THAN ABOVE EQUALS SIGN + return rune(0x2a9f), true + case "simne": // APPROXIMATELY BUT NOT ACTUALLY EQUAL TO + return rune(0x2246), true + case "simplus": // PLUS SIGN WITH TILDE ABOVE + return rune(0x2a24), true + case "simrarr": // TILDE OPERATOR ABOVE RIGHTWARDS ARROW + return rune(0x2972), true + case "slarr": // LEFTWARDS ARROW + return rune(0x2190), true + case "slint": // INTEGRAL AVERAGE WITH SLASH + return rune(0x2a0f), true + case "smallsetminus": // SET MINUS + return rune(0x2216), true + case "smashp": // SMASH PRODUCT + return rune(0x2a33), true + case "smeparsl": // EQUALS SIGN AND SLANTED PARALLEL WITH TILDE ABOVE + return rune(0x29e4), true + case "smid": // DIVIDES + return rune(0x2223), true + case "smile": // SMILE + return rune(0x2323), true + case "smt": // SMALLER THAN + return rune(0x2aaa), true + case "smte": // SMALLER THAN OR EQUAL TO + return rune(0x2aac), true + case "smtes": // SMALLER THAN OR slanted EQUAL + return rune(0x2aac), true + case "softcy": // CYRILLIC SMALL LETTER SOFT SIGN + return rune(0x044c), true + case "sol": // SOLIDUS + return rune(0x2f), true + case "solb": // SQUARED RISING DIAGONAL SLASH + return rune(0x29c4), true + case "solbar": // APL FUNCTIONAL SYMBOL SLASH BAR + return rune(0x233f), true + case "sopf": // MATHEMATICAL DOUBLE-STRUCK SMALL S + return rune(0x01d564), true + case "spades": // BLACK SPADE SUIT + return rune(0x2660), true + case "spadesuit": // BLACK SPADE SUIT + return rune(0x2660), true + case "spar": // PARALLEL TO + return rune(0x2225), true + case "sqcap": // SQUARE CAP + return rune(0x2293), true + case "sqcaps": // SQUARE CAP with serifs + return rune(0x2293), true + case "sqcup": // SQUARE CUP + return rune(0x2294), true + case "sqcups": // SQUARE CUP with serifs + return rune(0x2294), true + case "sqsub": // SQUARE IMAGE OF + return rune(0x228f), true + case "sqsube": // SQUARE IMAGE OF OR EQUAL TO + return rune(0x2291), true + case "sqsubset": // SQUARE IMAGE OF + return rune(0x228f), true + case "sqsubseteq": // SQUARE IMAGE OF OR EQUAL TO + return rune(0x2291), true + case "sqsup": // SQUARE ORIGINAL OF + return rune(0x2290), true + case "sqsupe": // SQUARE ORIGINAL OF OR EQUAL TO + return rune(0x2292), true + case "sqsupset": // SQUARE ORIGINAL OF + return rune(0x2290), true + case "sqsupseteq": // SQUARE ORIGINAL OF OR EQUAL TO + return rune(0x2292), true + case "squ": // WHITE SQUARE + return rune(0x25a1), true + case "square": // WHITE SQUARE + return rune(0x25a1), true + case "squarf": // BLACK SMALL SQUARE + return rune(0x25aa), true + case "squb": // SQUARED SQUARE + return rune(0x29c8), true + case "squerr": // ERROR-BARRED WHITE SQUARE + return rune(0x29ee), true + case "squf": // BLACK SMALL SQUARE + return rune(0x25aa), true + case "squferr": // ERROR-BARRED BLACK SQUARE + return rune(0x29ef), true + case "srarr": // RIGHTWARDS ARROW + return rune(0x2192), true + case "sscr": // MATHEMATICAL SCRIPT SMALL S + return rune(0x01d4c8), true + case "ssetmn": // SET MINUS + return rune(0x2216), true + case "ssmile": // SMILE + return rune(0x2323), true + case "sstarf": // STAR OPERATOR + return rune(0x22c6), true + case "star": // WHITE STAR + return rune(0x2606), true + case "starf": // BLACK STAR + return rune(0x2605), true + case "stigma": // GREEK LETTER STIGMA + return rune(0x03da), true + case "straightepsilon": // GREEK LUNATE EPSILON SYMBOL + return rune(0x03f5), true + case "straightphi": // GREEK PHI SYMBOL + return rune(0x03d5), true + case "strns": // MACRON + return rune(0xaf), true + case "sub": // SUBSET OF + return rune(0x2282), true + case "subE": // SUBSET OF ABOVE EQUALS SIGN + return rune(0x2ac5), true + case "subdot": // SUBSET WITH DOT + return rune(0x2abd), true + case "sube": // SUBSET OF OR EQUAL TO + return rune(0x2286), true + case "subedot": // SUBSET OF OR EQUAL TO WITH DOT ABOVE + return rune(0x2ac3), true + case "submult": // SUBSET WITH MULTIPLICATION SIGN BELOW + return rune(0x2ac1), true + case "subnE": // SUBSET OF ABOVE NOT EQUAL TO + return rune(0x2acb), true + case "subne": // SUBSET OF WITH NOT EQUAL TO + return rune(0x228a), true + case "subplus": // SUBSET WITH PLUS SIGN BELOW + return rune(0x2abf), true + case "subrarr": // SUBSET ABOVE RIGHTWARDS ARROW + return rune(0x2979), true + case "subset": // SUBSET OF + return rune(0x2282), true + case "subseteq": // SUBSET OF OR EQUAL TO + return rune(0x2286), true + case "subseteqq": // SUBSET OF ABOVE EQUALS SIGN + return rune(0x2ac5), true + case "subsetneq": // SUBSET OF WITH NOT EQUAL TO + return rune(0x228a), true + case "subsetneqq": // SUBSET OF ABOVE NOT EQUAL TO + return rune(0x2acb), true + case "subsim": // SUBSET OF ABOVE TILDE OPERATOR + return rune(0x2ac7), true + case "subsub": // SUBSET ABOVE SUBSET + return rune(0x2ad5), true + case "subsup": // SUBSET ABOVE SUPERSET + return rune(0x2ad3), true + case "succ": // SUCCEEDS + return rune(0x227b), true + case "succapprox": // SUCCEEDS ABOVE ALMOST EQUAL TO + return rune(0x2ab8), true + case "succcurlyeq": // SUCCEEDS OR EQUAL TO + return rune(0x227d), true + case "succeq": // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN + return rune(0x2ab0), true + case "succnapprox": // SUCCEEDS ABOVE NOT ALMOST EQUAL TO + return rune(0x2aba), true + case "succneqq": // SUCCEEDS ABOVE NOT EQUAL TO + return rune(0x2ab6), true + case "succnsim": // SUCCEEDS BUT NOT EQUIVALENT TO + return rune(0x22e9), true + case "succsim": // SUCCEEDS OR EQUIVALENT TO + return rune(0x227f), true + case "sum": // N-ARY SUMMATION + return rune(0x2211), true + case "sumint": // SUMMATION WITH INTEGRAL + return rune(0x2a0b), true + case "sung": // EIGHTH NOTE + return rune(0x266a), true + case "sup": // SUPERSET OF + return rune(0x2283), true + case "sup1": // SUPERSCRIPT ONE + return rune(0xb9), true + case "sup2": // SUPERSCRIPT TWO + return rune(0xb2), true + case "sup3": // SUPERSCRIPT THREE + return rune(0xb3), true + case "supE": // SUPERSET OF ABOVE EQUALS SIGN + return rune(0x2ac6), true + case "supdot": // SUPERSET WITH DOT + return rune(0x2abe), true + case "supdsub": // SUPERSET BESIDE AND JOINED BY DASH WITH SUBSET + return rune(0x2ad8), true + case "supe": // SUPERSET OF OR EQUAL TO + return rune(0x2287), true + case "supedot": // SUPERSET OF OR EQUAL TO WITH DOT ABOVE + return rune(0x2ac4), true + case "suphsol": // SUPERSET PRECEDING SOLIDUS + return rune(0x27c9), true + case "suphsub": // SUPERSET BESIDE SUBSET + return rune(0x2ad7), true + case "suplarr": // SUPERSET ABOVE LEFTWARDS ARROW + return rune(0x297b), true + case "supmult": // SUPERSET WITH MULTIPLICATION SIGN BELOW + return rune(0x2ac2), true + case "supnE": // SUPERSET OF ABOVE NOT EQUAL TO + return rune(0x2acc), true + case "supne": // SUPERSET OF WITH NOT EQUAL TO + return rune(0x228b), true + case "supplus": // SUPERSET WITH PLUS SIGN BELOW + return rune(0x2ac0), true + case "supset": // SUPERSET OF + return rune(0x2283), true + case "supseteq": // SUPERSET OF OR EQUAL TO + return rune(0x2287), true + case "supseteqq": // SUPERSET OF ABOVE EQUALS SIGN + return rune(0x2ac6), true + case "supsetneq": // SUPERSET OF WITH NOT EQUAL TO + return rune(0x228b), true + case "supsetneqq": // SUPERSET OF ABOVE NOT EQUAL TO + return rune(0x2acc), true + case "supsim": // SUPERSET OF ABOVE TILDE OPERATOR + return rune(0x2ac8), true + case "supsub": // SUPERSET ABOVE SUBSET + return rune(0x2ad4), true + case "supsup": // SUPERSET ABOVE SUPERSET + return rune(0x2ad6), true + case "swArr": // SOUTH WEST DOUBLE ARROW + return rune(0x21d9), true + case "swarhk": // SOUTH WEST ARROW WITH HOOK + return rune(0x2926), true + case "swarr": // SOUTH WEST ARROW + return rune(0x2199), true + case "swarrow": // SOUTH WEST ARROW + return rune(0x2199), true + case "swnwar": // SOUTH WEST ARROW AND NORTH WEST ARROW + return rune(0x292a), true + case "szlig": // LATIN SMALL LETTER SHARP S + return rune(0xdf), true } case 't': switch name { - case "target": // POSITION INDICATOR - return rune(0x2316), true - case "tau": // GREEK SMALL LETTER TAU - return rune(0x03c4), true - case "tbrk": // TOP SQUARE BRACKET - return rune(0x23b4), true - case "tcaron": // LATIN SMALL LETTER T WITH CARON - return rune(0x0165), true - case "tcedil": // LATIN SMALL LETTER T WITH CEDILLA - return rune(0x0163), true - case "tcy": // CYRILLIC SMALL LETTER TE - return rune(0x0442), true - case "tdot": // COMBINING THREE DOTS ABOVE - return rune(0x20db), true - case "telrec": // TELEPHONE RECORDER - return rune(0x2315), true - case "tfr": // MATHEMATICAL FRAKTUR SMALL T - return rune(0x01d531), true - case "tgr": // GREEK SMALL LETTER TAU - return rune(0x03c4), true - case "there4": // THEREFORE - return rune(0x2234), true - case "therefore": // THEREFORE - return rune(0x2234), true - case "thermod": // THERMODYNAMIC - return rune(0x29e7), true - case "theta": // GREEK SMALL LETTER THETA - return rune(0x03b8), true - case "thetas": // GREEK SMALL LETTER THETA - return rune(0x03b8), true - case "thetasym": // GREEK THETA SYMBOL - return rune(0x03d1), true - case "thetav": // GREEK THETA SYMBOL - return rune(0x03d1), true - case "thgr": // GREEK SMALL LETTER THETA - return rune(0x03b8), true - case "thickapprox": // ALMOST EQUAL TO - return rune(0x2248), true - case "thicksim": // TILDE OPERATOR - return rune(0x223c), true - case "thinsp": // THIN SPACE - return rune(0x2009), true - case "thkap": // ALMOST EQUAL TO - return rune(0x2248), true - case "thksim": // TILDE OPERATOR - return rune(0x223c), true - case "thorn": // LATIN SMALL LETTER THORN - return rune(0xfe), true - case "tilde": // SMALL TILDE - return rune(0x02dc), true - case "timeint": // INTEGRAL WITH TIMES SIGN - return rune(0x2a18), true - case "times": // MULTIPLICATION SIGN - return rune(0xd7), true - case "timesb": // SQUARED TIMES - return rune(0x22a0), true - case "timesbar": // MULTIPLICATION SIGN WITH UNDERBAR - return rune(0x2a31), true - case "timesd": // MULTIPLICATION SIGN WITH DOT ABOVE - return rune(0x2a30), true - case "tint": // TRIPLE INTEGRAL - return rune(0x222d), true - case "toea": // NORTH EAST ARROW AND SOUTH EAST ARROW - return rune(0x2928), true - case "top": // DOWN TACK - return rune(0x22a4), true - case "topbot": // APL FUNCTIONAL SYMBOL I-BEAM - return rune(0x2336), true - case "topcir": // DOWN TACK WITH CIRCLE BELOW - return rune(0x2af1), true - case "topf": // MATHEMATICAL DOUBLE-STRUCK SMALL T - return rune(0x01d565), true - case "topfork": // PITCHFORK WITH TEE TOP - return rune(0x2ada), true - case "tosa": // SOUTH EAST ARROW AND SOUTH WEST ARROW - return rune(0x2929), true - case "tprime": // TRIPLE PRIME - return rune(0x2034), true - case "trade": // TRADE MARK SIGN - return rune(0x2122), true - case "triS": // S IN TRIANGLE - return rune(0x29cc), true - case "triangle": // WHITE UP-POINTING SMALL TRIANGLE - return rune(0x25b5), true - case "triangledown": // WHITE DOWN-POINTING SMALL TRIANGLE - return rune(0x25bf), true - case "triangleleft": // WHITE LEFT-POINTING SMALL TRIANGLE - return rune(0x25c3), true - case "trianglelefteq": // NORMAL SUBGROUP OF OR EQUAL TO - return rune(0x22b4), true - case "triangleq": // DELTA EQUAL TO - return rune(0x225c), true - case "triangleright": // WHITE RIGHT-POINTING SMALL TRIANGLE - return rune(0x25b9), true - case "trianglerighteq": // CONTAINS AS NORMAL SUBGROUP OR EQUAL TO - return rune(0x22b5), true - case "tribar": // TRIANGLE WITH UNDERBAR - return rune(0x29cb), true - case "tridot": // WHITE UP-POINTING TRIANGLE WITH DOT - return rune(0x25ec), true - case "tridoto": // TRIANGLE WITH DOT ABOVE - return rune(0x29ca), true - case "trie": // DELTA EQUAL TO - return rune(0x225c), true - case "triminus": // MINUS SIGN IN TRIANGLE - return rune(0x2a3a), true - case "triplus": // PLUS SIGN IN TRIANGLE - return rune(0x2a39), true - case "trisb": // TRIANGLE WITH SERIFS AT BOTTOM - return rune(0x29cd), true - case "tritime": // MULTIPLICATION SIGN IN TRIANGLE - return rune(0x2a3b), true - case "trpezium": // WHITE TRAPEZIUM - return rune(0x23e2), true - case "tscr": // MATHEMATICAL SCRIPT SMALL T - return rune(0x01d4c9), true - case "tscy": // CYRILLIC SMALL LETTER TSE - return rune(0x0446), true - case "tshcy": // CYRILLIC SMALL LETTER TSHE - return rune(0x045b), true - case "tstrok": // LATIN SMALL LETTER T WITH STROKE - return rune(0x0167), true - case "tverbar": // TRIPLE VERTICAL BAR DELIMITER - return rune(0x2980), true - case "twixt": // BETWEEN - return rune(0x226c), true - case "twoheadleftarrow": // LEFTWARDS TWO HEADED ARROW - return rune(0x219e), true - case "twoheadrightarrow": // RIGHTWARDS TWO HEADED ARROW - return rune(0x21a0), true + case "target": // POSITION INDICATOR + return rune(0x2316), true + case "tau": // GREEK SMALL LETTER TAU + return rune(0x03c4), true + case "tbrk": // TOP SQUARE BRACKET + return rune(0x23b4), true + case "tcaron": // LATIN SMALL LETTER T WITH CARON + return rune(0x0165), true + case "tcedil": // LATIN SMALL LETTER T WITH CEDILLA + return rune(0x0163), true + case "tcy": // CYRILLIC SMALL LETTER TE + return rune(0x0442), true + case "tdot": // COMBINING THREE DOTS ABOVE + return rune(0x20db), true + case "telrec": // TELEPHONE RECORDER + return rune(0x2315), true + case "tfr": // MATHEMATICAL FRAKTUR SMALL T + return rune(0x01d531), true + case "tgr": // GREEK SMALL LETTER TAU + return rune(0x03c4), true + case "there4": // THEREFORE + return rune(0x2234), true + case "therefore": // THEREFORE + return rune(0x2234), true + case "thermod": // THERMODYNAMIC + return rune(0x29e7), true + case "theta": // GREEK SMALL LETTER THETA + return rune(0x03b8), true + case "thetas": // GREEK SMALL LETTER THETA + return rune(0x03b8), true + case "thetasym": // GREEK THETA SYMBOL + return rune(0x03d1), true + case "thetav": // GREEK THETA SYMBOL + return rune(0x03d1), true + case "thgr": // GREEK SMALL LETTER THETA + return rune(0x03b8), true + case "thickapprox": // ALMOST EQUAL TO + return rune(0x2248), true + case "thicksim": // TILDE OPERATOR + return rune(0x223c), true + case "thinsp": // THIN SPACE + return rune(0x2009), true + case "thkap": // ALMOST EQUAL TO + return rune(0x2248), true + case "thksim": // TILDE OPERATOR + return rune(0x223c), true + case "thorn": // LATIN SMALL LETTER THORN + return rune(0xfe), true + case "tilde": // SMALL TILDE + return rune(0x02dc), true + case "timeint": // INTEGRAL WITH TIMES SIGN + return rune(0x2a18), true + case "times": // MULTIPLICATION SIGN + return rune(0xd7), true + case "timesb": // SQUARED TIMES + return rune(0x22a0), true + case "timesbar": // MULTIPLICATION SIGN WITH UNDERBAR + return rune(0x2a31), true + case "timesd": // MULTIPLICATION SIGN WITH DOT ABOVE + return rune(0x2a30), true + case "tint": // TRIPLE INTEGRAL + return rune(0x222d), true + case "toea": // NORTH EAST ARROW AND SOUTH EAST ARROW + return rune(0x2928), true + case "top": // DOWN TACK + return rune(0x22a4), true + case "topbot": // APL FUNCTIONAL SYMBOL I-BEAM + return rune(0x2336), true + case "topcir": // DOWN TACK WITH CIRCLE BELOW + return rune(0x2af1), true + case "topf": // MATHEMATICAL DOUBLE-STRUCK SMALL T + return rune(0x01d565), true + case "topfork": // PITCHFORK WITH TEE TOP + return rune(0x2ada), true + case "tosa": // SOUTH EAST ARROW AND SOUTH WEST ARROW + return rune(0x2929), true + case "tprime": // TRIPLE PRIME + return rune(0x2034), true + case "trade": // TRADE MARK SIGN + return rune(0x2122), true + case "triS": // S IN TRIANGLE + return rune(0x29cc), true + case "triangle": // WHITE UP-POINTING SMALL TRIANGLE + return rune(0x25b5), true + case "triangledown": // WHITE DOWN-POINTING SMALL TRIANGLE + return rune(0x25bf), true + case "triangleleft": // WHITE LEFT-POINTING SMALL TRIANGLE + return rune(0x25c3), true + case "trianglelefteq": // NORMAL SUBGROUP OF OR EQUAL TO + return rune(0x22b4), true + case "triangleq": // DELTA EQUAL TO + return rune(0x225c), true + case "triangleright": // WHITE RIGHT-POINTING SMALL TRIANGLE + return rune(0x25b9), true + case "trianglerighteq": // CONTAINS AS NORMAL SUBGROUP OR EQUAL TO + return rune(0x22b5), true + case "tribar": // TRIANGLE WITH UNDERBAR + return rune(0x29cb), true + case "tridot": // WHITE UP-POINTING TRIANGLE WITH DOT + return rune(0x25ec), true + case "tridoto": // TRIANGLE WITH DOT ABOVE + return rune(0x29ca), true + case "trie": // DELTA EQUAL TO + return rune(0x225c), true + case "triminus": // MINUS SIGN IN TRIANGLE + return rune(0x2a3a), true + case "triplus": // PLUS SIGN IN TRIANGLE + return rune(0x2a39), true + case "trisb": // TRIANGLE WITH SERIFS AT BOTTOM + return rune(0x29cd), true + case "tritime": // MULTIPLICATION SIGN IN TRIANGLE + return rune(0x2a3b), true + case "trpezium": // WHITE TRAPEZIUM + return rune(0x23e2), true + case "tscr": // MATHEMATICAL SCRIPT SMALL T + return rune(0x01d4c9), true + case "tscy": // CYRILLIC SMALL LETTER TSE + return rune(0x0446), true + case "tshcy": // CYRILLIC SMALL LETTER TSHE + return rune(0x045b), true + case "tstrok": // LATIN SMALL LETTER T WITH STROKE + return rune(0x0167), true + case "tverbar": // TRIPLE VERTICAL BAR DELIMITER + return rune(0x2980), true + case "twixt": // BETWEEN + return rune(0x226c), true + case "twoheadleftarrow": // LEFTWARDS TWO HEADED ARROW + return rune(0x219e), true + case "twoheadrightarrow": // RIGHTWARDS TWO HEADED ARROW + return rune(0x21a0), true } case 'u': switch name { - case "uAarr": // UPWARDS TRIPLE ARROW - return rune(0x290a), true - case "uArr": // UPWARDS DOUBLE ARROW - return rune(0x21d1), true - case "uHar": // UPWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT - return rune(0x2963), true - case "uacgr": // GREEK SMALL LETTER UPSILON WITH TONOS - return rune(0x03cd), true - case "uacute": // LATIN SMALL LETTER U WITH ACUTE - return rune(0xfa), true - case "uarr": // UPWARDS ARROW - return rune(0x2191), true - case "uarr2": // UPWARDS PAIRED ARROWS - return rune(0x21c8), true - case "uarrb": // UPWARDS ARROW TO BAR - return rune(0x2912), true - case "uarrln": // UPWARDS ARROW WITH HORIZONTAL STROKE - return rune(0x2909), true - case "ubrcy": // CYRILLIC SMALL LETTER SHORT U - return rune(0x045e), true - case "ubreve": // LATIN SMALL LETTER U WITH BREVE - return rune(0x016d), true - case "ucirc": // LATIN SMALL LETTER U WITH CIRCUMFLEX - return rune(0xfb), true - case "ucy": // CYRILLIC SMALL LETTER U - return rune(0x0443), true - case "udarr": // UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW - return rune(0x21c5), true - case "udblac": // LATIN SMALL LETTER U WITH DOUBLE ACUTE - return rune(0x0171), true - case "udhar": // UPWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT - return rune(0x296e), true - case "udiagr": // GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS - return rune(0x03b0), true - case "udigr": // GREEK SMALL LETTER UPSILON WITH DIALYTIKA - return rune(0x03cb), true - case "udrbrk": // BOTTOM SQUARE BRACKET - return rune(0x23b5), true - case "udrcub": // BOTTOM CURLY BRACKET - return rune(0x23df), true - case "udrpar": // BOTTOM PARENTHESIS - return rune(0x23dd), true - case "ufisht": // UP FISH TAIL - return rune(0x297e), true - case "ufr": // MATHEMATICAL FRAKTUR SMALL U - return rune(0x01d532), true - case "ugr": // GREEK SMALL LETTER UPSILON - return rune(0x03c5), true - case "ugrave": // LATIN SMALL LETTER U WITH GRAVE - return rune(0xf9), true - case "uharl": // UPWARDS HARPOON WITH BARB LEFTWARDS - return rune(0x21bf), true - case "uharr": // UPWARDS HARPOON WITH BARB RIGHTWARDS - return rune(0x21be), true - case "uhblk": // UPPER HALF BLOCK - return rune(0x2580), true - case "ulcorn": // TOP LEFT CORNER - return rune(0x231c), true - case "ulcorner": // TOP LEFT CORNER - return rune(0x231c), true - case "ulcrop": // TOP LEFT CROP - return rune(0x230f), true - case "uldlshar": // UP BARB LEFT DOWN BARB LEFT HARPOON - return rune(0x2951), true - case "ulharb": // UPWARDS HARPOON WITH BARB LEFT TO BAR - return rune(0x2958), true - case "ultri": // UPPER LEFT TRIANGLE - return rune(0x25f8), true - case "umacr": // LATIN SMALL LETTER U WITH MACRON - return rune(0x016b), true - case "uml": // DIAERESIS - return rune(0xa8), true - case "uogon": // LATIN SMALL LETTER U WITH OGONEK - return rune(0x0173), true - case "uopf": // MATHEMATICAL DOUBLE-STRUCK SMALL U - return rune(0x01d566), true - case "uparrow": // UPWARDS ARROW - return rune(0x2191), true - case "updownarrow": // UP DOWN ARROW - return rune(0x2195), true - case "upharpoonleft": // UPWARDS HARPOON WITH BARB LEFTWARDS - return rune(0x21bf), true - case "upharpoonright": // UPWARDS HARPOON WITH BARB RIGHTWARDS - return rune(0x21be), true - case "upint": // INTEGRAL WITH OVERBAR - return rune(0x2a1b), true - case "uplus": // MULTISET UNION - return rune(0x228e), true - case "upsi": // GREEK SMALL LETTER UPSILON - return rune(0x03c5), true - case "upsih": // GREEK UPSILON WITH HOOK SYMBOL - return rune(0x03d2), true - case "upsilon": // GREEK SMALL LETTER UPSILON - return rune(0x03c5), true - case "upuparrows": // UPWARDS PAIRED ARROWS - return rune(0x21c8), true - case "urcorn": // TOP RIGHT CORNER - return rune(0x231d), true - case "urcorner": // TOP RIGHT CORNER - return rune(0x231d), true - case "urcrop": // TOP RIGHT CROP - return rune(0x230e), true - case "urdrshar": // UP BARB RIGHT DOWN BARB RIGHT HARPOON - return rune(0x294f), true - case "urharb": // UPWARDS HARPOON WITH BARB RIGHT TO BAR - return rune(0x2954), true - case "uring": // LATIN SMALL LETTER U WITH RING ABOVE - return rune(0x016f), true - case "urtri": // UPPER RIGHT TRIANGLE - return rune(0x25f9), true - case "urtrif": // BLACK UPPER RIGHT TRIANGLE - return rune(0x25e5), true - case "uscr": // MATHEMATICAL SCRIPT SMALL U - return rune(0x01d4ca), true - case "utdot": // UP RIGHT DIAGONAL ELLIPSIS - return rune(0x22f0), true - case "utilde": // LATIN SMALL LETTER U WITH TILDE - return rune(0x0169), true - case "utri": // WHITE UP-POINTING SMALL TRIANGLE - return rune(0x25b5), true - case "utrif": // BLACK UP-POINTING SMALL TRIANGLE - return rune(0x25b4), true - case "uuarr": // UPWARDS PAIRED ARROWS - return rune(0x21c8), true - case "uuml": // LATIN SMALL LETTER U WITH DIAERESIS - return rune(0xfc), true - case "uwangle": // OBLIQUE ANGLE OPENING DOWN - return rune(0x29a7), true + case "uAarr": // UPWARDS TRIPLE ARROW + return rune(0x290a), true + case "uArr": // UPWARDS DOUBLE ARROW + return rune(0x21d1), true + case "uHar": // UPWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT + return rune(0x2963), true + case "uacgr": // GREEK SMALL LETTER UPSILON WITH TONOS + return rune(0x03cd), true + case "uacute": // LATIN SMALL LETTER U WITH ACUTE + return rune(0xfa), true + case "uarr": // UPWARDS ARROW + return rune(0x2191), true + case "uarr2": // UPWARDS PAIRED ARROWS + return rune(0x21c8), true + case "uarrb": // UPWARDS ARROW TO BAR + return rune(0x2912), true + case "uarrln": // UPWARDS ARROW WITH HORIZONTAL STROKE + return rune(0x2909), true + case "ubrcy": // CYRILLIC SMALL LETTER SHORT U + return rune(0x045e), true + case "ubreve": // LATIN SMALL LETTER U WITH BREVE + return rune(0x016d), true + case "ucirc": // LATIN SMALL LETTER U WITH CIRCUMFLEX + return rune(0xfb), true + case "ucy": // CYRILLIC SMALL LETTER U + return rune(0x0443), true + case "udarr": // UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW + return rune(0x21c5), true + case "udblac": // LATIN SMALL LETTER U WITH DOUBLE ACUTE + return rune(0x0171), true + case "udhar": // UPWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT + return rune(0x296e), true + case "udiagr": // GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS + return rune(0x03b0), true + case "udigr": // GREEK SMALL LETTER UPSILON WITH DIALYTIKA + return rune(0x03cb), true + case "udrbrk": // BOTTOM SQUARE BRACKET + return rune(0x23b5), true + case "udrcub": // BOTTOM CURLY BRACKET + return rune(0x23df), true + case "udrpar": // BOTTOM PARENTHESIS + return rune(0x23dd), true + case "ufisht": // UP FISH TAIL + return rune(0x297e), true + case "ufr": // MATHEMATICAL FRAKTUR SMALL U + return rune(0x01d532), true + case "ugr": // GREEK SMALL LETTER UPSILON + return rune(0x03c5), true + case "ugrave": // LATIN SMALL LETTER U WITH GRAVE + return rune(0xf9), true + case "uharl": // UPWARDS HARPOON WITH BARB LEFTWARDS + return rune(0x21bf), true + case "uharr": // UPWARDS HARPOON WITH BARB RIGHTWARDS + return rune(0x21be), true + case "uhblk": // UPPER HALF BLOCK + return rune(0x2580), true + case "ulcorn": // TOP LEFT CORNER + return rune(0x231c), true + case "ulcorner": // TOP LEFT CORNER + return rune(0x231c), true + case "ulcrop": // TOP LEFT CROP + return rune(0x230f), true + case "uldlshar": // UP BARB LEFT DOWN BARB LEFT HARPOON + return rune(0x2951), true + case "ulharb": // UPWARDS HARPOON WITH BARB LEFT TO BAR + return rune(0x2958), true + case "ultri": // UPPER LEFT TRIANGLE + return rune(0x25f8), true + case "umacr": // LATIN SMALL LETTER U WITH MACRON + return rune(0x016b), true + case "uml": // DIAERESIS + return rune(0xa8), true + case "uogon": // LATIN SMALL LETTER U WITH OGONEK + return rune(0x0173), true + case "uopf": // MATHEMATICAL DOUBLE-STRUCK SMALL U + return rune(0x01d566), true + case "uparrow": // UPWARDS ARROW + return rune(0x2191), true + case "updownarrow": // UP DOWN ARROW + return rune(0x2195), true + case "upharpoonleft": // UPWARDS HARPOON WITH BARB LEFTWARDS + return rune(0x21bf), true + case "upharpoonright": // UPWARDS HARPOON WITH BARB RIGHTWARDS + return rune(0x21be), true + case "upint": // INTEGRAL WITH OVERBAR + return rune(0x2a1b), true + case "uplus": // MULTISET UNION + return rune(0x228e), true + case "upsi": // GREEK SMALL LETTER UPSILON + return rune(0x03c5), true + case "upsih": // GREEK UPSILON WITH HOOK SYMBOL + return rune(0x03d2), true + case "upsilon": // GREEK SMALL LETTER UPSILON + return rune(0x03c5), true + case "upuparrows": // UPWARDS PAIRED ARROWS + return rune(0x21c8), true + case "urcorn": // TOP RIGHT CORNER + return rune(0x231d), true + case "urcorner": // TOP RIGHT CORNER + return rune(0x231d), true + case "urcrop": // TOP RIGHT CROP + return rune(0x230e), true + case "urdrshar": // UP BARB RIGHT DOWN BARB RIGHT HARPOON + return rune(0x294f), true + case "urharb": // UPWARDS HARPOON WITH BARB RIGHT TO BAR + return rune(0x2954), true + case "uring": // LATIN SMALL LETTER U WITH RING ABOVE + return rune(0x016f), true + case "urtri": // UPPER RIGHT TRIANGLE + return rune(0x25f9), true + case "urtrif": // BLACK UPPER RIGHT TRIANGLE + return rune(0x25e5), true + case "uscr": // MATHEMATICAL SCRIPT SMALL U + return rune(0x01d4ca), true + case "utdot": // UP RIGHT DIAGONAL ELLIPSIS + return rune(0x22f0), true + case "utilde": // LATIN SMALL LETTER U WITH TILDE + return rune(0x0169), true + case "utri": // WHITE UP-POINTING SMALL TRIANGLE + return rune(0x25b5), true + case "utrif": // BLACK UP-POINTING SMALL TRIANGLE + return rune(0x25b4), true + case "uuarr": // UPWARDS PAIRED ARROWS + return rune(0x21c8), true + case "uuml": // LATIN SMALL LETTER U WITH DIAERESIS + return rune(0xfc), true + case "uwangle": // OBLIQUE ANGLE OPENING DOWN + return rune(0x29a7), true } case 'v': switch name { - case "vArr": // UP DOWN DOUBLE ARROW - return rune(0x21d5), true - case "vBar": // SHORT UP TACK WITH UNDERBAR - return rune(0x2ae8), true - case "vBarv": // SHORT UP TACK ABOVE SHORT DOWN TACK - return rune(0x2ae9), true - case "vDash": // TRUE - return rune(0x22a8), true - case "vDdash": // VERTICAL BAR TRIPLE RIGHT TURNSTILE - return rune(0x2ae2), true - case "vangrt": // RIGHT ANGLE VARIANT WITH SQUARE - return rune(0x299c), true - case "varepsilon": // GREEK LUNATE EPSILON SYMBOL - return rune(0x03f5), true - case "varkappa": // GREEK KAPPA SYMBOL - return rune(0x03f0), true - case "varnothing": // EMPTY SET - return rune(0x2205), true - case "varphi": // GREEK PHI SYMBOL - return rune(0x03d5), true - case "varpi": // GREEK PI SYMBOL - return rune(0x03d6), true - case "varpropto": // PROPORTIONAL TO - return rune(0x221d), true - case "varr": // UP DOWN ARROW - return rune(0x2195), true - case "varrho": // GREEK RHO SYMBOL - return rune(0x03f1), true - case "varsigma": // GREEK SMALL LETTER FINAL SIGMA - return rune(0x03c2), true - case "varsubsetneq": // SUBSET OF WITH NOT EQUAL TO - variant with stroke through bottom members - return rune(0x228a), true - case "varsubsetneqq": // SUBSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members - return rune(0x2acb), true - case "varsupsetneq": // SUPERSET OF WITH NOT EQUAL TO - variant with stroke through bottom members - return rune(0x228b), true - case "varsupsetneqq": // SUPERSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members - return rune(0x2acc), true - case "vartheta": // GREEK THETA SYMBOL - return rune(0x03d1), true - case "vartriangleleft": // NORMAL SUBGROUP OF - return rune(0x22b2), true - case "vartriangleright": // CONTAINS AS NORMAL SUBGROUP - return rune(0x22b3), true - case "vbrtri": // VERTICAL BAR BESIDE RIGHT TRIANGLE - return rune(0x29d0), true - case "vcy": // CYRILLIC SMALL LETTER VE - return rune(0x0432), true - case "vdash": // RIGHT TACK - return rune(0x22a2), true - case "vee": // LOGICAL OR - return rune(0x2228), true - case "veeBar": // LOGICAL OR WITH DOUBLE UNDERBAR - return rune(0x2a63), true - case "veebar": // XOR - return rune(0x22bb), true - case "veeeq": // EQUIANGULAR TO - return rune(0x225a), true - case "vellip": // VERTICAL ELLIPSIS - return rune(0x22ee), true - case "vellip4": // DOTTED FENCE - return rune(0x2999), true - case "vellipv": // TRIPLE COLON OPERATOR - return rune(0x2af6), true - case "verbar": // VERTICAL LINE - return rune(0x7c), true - case "vert": // VERTICAL LINE - return rune(0x7c), true - case "vert3": // TRIPLE VERTICAL BAR BINARY RELATION - return rune(0x2af4), true - case "vfr": // MATHEMATICAL FRAKTUR SMALL V - return rune(0x01d533), true - case "vldash": // LEFT SQUARE BRACKET LOWER CORNER - return rune(0x23a3), true - case "vltri": // NORMAL SUBGROUP OF - return rune(0x22b2), true - case "vnsub": // SUBSET OF with vertical line - return rune(0x2282), true - case "vnsup": // SUPERSET OF with vertical line - return rune(0x2283), true - case "vopf": // MATHEMATICAL DOUBLE-STRUCK SMALL V - return rune(0x01d567), true - case "vprime": // PRIME - return rune(0x2032), true - case "vprop": // PROPORTIONAL TO - return rune(0x221d), true - case "vrtri": // CONTAINS AS NORMAL SUBGROUP - return rune(0x22b3), true - case "vscr": // MATHEMATICAL SCRIPT SMALL V - return rune(0x01d4cb), true - case "vsubnE": // SUBSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members - return rune(0x2acb), true - case "vsubne": // SUBSET OF WITH NOT EQUAL TO - variant with stroke through bottom members - return rune(0x228a), true - case "vsupnE": // SUPERSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members - return rune(0x2acc), true - case "vsupne": // SUPERSET OF WITH NOT EQUAL TO - variant with stroke through bottom members - return rune(0x228b), true - case "vzigzag": // VERTICAL ZIGZAG LINE - return rune(0x299a), true + case "vArr": // UP DOWN DOUBLE ARROW + return rune(0x21d5), true + case "vBar": // SHORT UP TACK WITH UNDERBAR + return rune(0x2ae8), true + case "vBarv": // SHORT UP TACK ABOVE SHORT DOWN TACK + return rune(0x2ae9), true + case "vDash": // TRUE + return rune(0x22a8), true + case "vDdash": // VERTICAL BAR TRIPLE RIGHT TURNSTILE + return rune(0x2ae2), true + case "vangrt": // RIGHT ANGLE VARIANT WITH SQUARE + return rune(0x299c), true + case "varepsilon": // GREEK LUNATE EPSILON SYMBOL + return rune(0x03f5), true + case "varkappa": // GREEK KAPPA SYMBOL + return rune(0x03f0), true + case "varnothing": // EMPTY SET + return rune(0x2205), true + case "varphi": // GREEK PHI SYMBOL + return rune(0x03d5), true + case "varpi": // GREEK PI SYMBOL + return rune(0x03d6), true + case "varpropto": // PROPORTIONAL TO + return rune(0x221d), true + case "varr": // UP DOWN ARROW + return rune(0x2195), true + case "varrho": // GREEK RHO SYMBOL + return rune(0x03f1), true + case "varsigma": // GREEK SMALL LETTER FINAL SIGMA + return rune(0x03c2), true + case "varsubsetneq": // SUBSET OF WITH NOT EQUAL TO - variant with stroke through bottom members + return rune(0x228a), true + case "varsubsetneqq": // SUBSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members + return rune(0x2acb), true + case "varsupsetneq": // SUPERSET OF WITH NOT EQUAL TO - variant with stroke through bottom members + return rune(0x228b), true + case "varsupsetneqq": // SUPERSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members + return rune(0x2acc), true + case "vartheta": // GREEK THETA SYMBOL + return rune(0x03d1), true + case "vartriangleleft": // NORMAL SUBGROUP OF + return rune(0x22b2), true + case "vartriangleright": // CONTAINS AS NORMAL SUBGROUP + return rune(0x22b3), true + case "vbrtri": // VERTICAL BAR BESIDE RIGHT TRIANGLE + return rune(0x29d0), true + case "vcy": // CYRILLIC SMALL LETTER VE + return rune(0x0432), true + case "vdash": // RIGHT TACK + return rune(0x22a2), true + case "vee": // LOGICAL OR + return rune(0x2228), true + case "veeBar": // LOGICAL OR WITH DOUBLE UNDERBAR + return rune(0x2a63), true + case "veebar": // XOR + return rune(0x22bb), true + case "veeeq": // EQUIANGULAR TO + return rune(0x225a), true + case "vellip": // VERTICAL ELLIPSIS + return rune(0x22ee), true + case "vellip4": // DOTTED FENCE + return rune(0x2999), true + case "vellipv": // TRIPLE COLON OPERATOR + return rune(0x2af6), true + case "verbar": // VERTICAL LINE + return rune(0x7c), true + case "vert": // VERTICAL LINE + return rune(0x7c), true + case "vert3": // TRIPLE VERTICAL BAR BINARY RELATION + return rune(0x2af4), true + case "vfr": // MATHEMATICAL FRAKTUR SMALL V + return rune(0x01d533), true + case "vldash": // LEFT SQUARE BRACKET LOWER CORNER + return rune(0x23a3), true + case "vltri": // NORMAL SUBGROUP OF + return rune(0x22b2), true + case "vnsub": // SUBSET OF with vertical line + return rune(0x2282), true + case "vnsup": // SUPERSET OF with vertical line + return rune(0x2283), true + case "vopf": // MATHEMATICAL DOUBLE-STRUCK SMALL V + return rune(0x01d567), true + case "vprime": // PRIME + return rune(0x2032), true + case "vprop": // PROPORTIONAL TO + return rune(0x221d), true + case "vrtri": // CONTAINS AS NORMAL SUBGROUP + return rune(0x22b3), true + case "vscr": // MATHEMATICAL SCRIPT SMALL V + return rune(0x01d4cb), true + case "vsubnE": // SUBSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members + return rune(0x2acb), true + case "vsubne": // SUBSET OF WITH NOT EQUAL TO - variant with stroke through bottom members + return rune(0x228a), true + case "vsupnE": // SUPERSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members + return rune(0x2acc), true + case "vsupne": // SUPERSET OF WITH NOT EQUAL TO - variant with stroke through bottom members + return rune(0x228b), true + case "vzigzag": // VERTICAL ZIGZAG LINE + return rune(0x299a), true } case 'w': switch name { - case "wcirc": // LATIN SMALL LETTER W WITH CIRCUMFLEX - return rune(0x0175), true - case "wedbar": // LOGICAL AND WITH UNDERBAR - return rune(0x2a5f), true - case "wedge": // LOGICAL AND - return rune(0x2227), true - case "wedgeq": // ESTIMATES - return rune(0x2259), true - case "weierp": // SCRIPT CAPITAL P - return rune(0x2118), true - case "wfr": // MATHEMATICAL FRAKTUR SMALL W - return rune(0x01d534), true - case "wopf": // MATHEMATICAL DOUBLE-STRUCK SMALL W - return rune(0x01d568), true - case "wp": // SCRIPT CAPITAL P - return rune(0x2118), true - case "wr": // WREATH PRODUCT - return rune(0x2240), true - case "wreath": // WREATH PRODUCT - return rune(0x2240), true - case "wscr": // MATHEMATICAL SCRIPT SMALL W - return rune(0x01d4cc), true + case "wcirc": // LATIN SMALL LETTER W WITH CIRCUMFLEX + return rune(0x0175), true + case "wedbar": // LOGICAL AND WITH UNDERBAR + return rune(0x2a5f), true + case "wedge": // LOGICAL AND + return rune(0x2227), true + case "wedgeq": // ESTIMATES + return rune(0x2259), true + case "weierp": // SCRIPT CAPITAL P + return rune(0x2118), true + case "wfr": // MATHEMATICAL FRAKTUR SMALL W + return rune(0x01d534), true + case "wopf": // MATHEMATICAL DOUBLE-STRUCK SMALL W + return rune(0x01d568), true + case "wp": // SCRIPT CAPITAL P + return rune(0x2118), true + case "wr": // WREATH PRODUCT + return rune(0x2240), true + case "wreath": // WREATH PRODUCT + return rune(0x2240), true + case "wscr": // MATHEMATICAL SCRIPT SMALL W + return rune(0x01d4cc), true } case 'x': switch name { - case "xandand": // TWO LOGICAL AND OPERATOR - return rune(0x2a07), true - case "xbsol": // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT - return rune(0x2571), true - case "xcap": // N-ARY INTERSECTION - return rune(0x22c2), true - case "xcirc": // LARGE CIRCLE - return rune(0x25ef), true - case "xcup": // N-ARY UNION - return rune(0x22c3), true - case "xcupdot": // N-ARY UNION OPERATOR WITH DOT - return rune(0x2a03), true - case "xdtri": // WHITE DOWN-POINTING TRIANGLE - return rune(0x25bd), true - case "xfr": // MATHEMATICAL FRAKTUR SMALL X - return rune(0x01d535), true - case "xgr": // GREEK SMALL LETTER XI - return rune(0x03be), true - case "xhArr": // LONG LEFT RIGHT DOUBLE ARROW - return rune(0x27fa), true - case "xharr": // LONG LEFT RIGHT ARROW - return rune(0x27f7), true - case "xi": // GREEK SMALL LETTER XI - return rune(0x03be), true - case "xlArr": // LONG LEFTWARDS DOUBLE ARROW - return rune(0x27f8), true - case "xlarr": // LONG LEFTWARDS ARROW - return rune(0x27f5), true - case "xmap": // LONG RIGHTWARDS ARROW FROM BAR - return rune(0x27fc), true - case "xnis": // CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE - return rune(0x22fb), true - case "xodot": // N-ARY CIRCLED DOT OPERATOR - return rune(0x2a00), true - case "xopf": // MATHEMATICAL DOUBLE-STRUCK SMALL X - return rune(0x01d569), true - case "xoplus": // N-ARY CIRCLED PLUS OPERATOR - return rune(0x2a01), true - case "xoror": // TWO LOGICAL OR OPERATOR - return rune(0x2a08), true - case "xotime": // N-ARY CIRCLED TIMES OPERATOR - return rune(0x2a02), true - case "xrArr": // LONG RIGHTWARDS DOUBLE ARROW - return rune(0x27f9), true - case "xrarr": // LONG RIGHTWARDS ARROW - return rune(0x27f6), true - case "xscr": // MATHEMATICAL SCRIPT SMALL X - return rune(0x01d4cd), true - case "xsol": // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT - return rune(0x2572), true - case "xsqcap": // N-ARY SQUARE INTERSECTION OPERATOR - return rune(0x2a05), true - case "xsqcup": // N-ARY SQUARE UNION OPERATOR - return rune(0x2a06), true - case "xsqu": // WHITE MEDIUM SQUARE - return rune(0x25fb), true - case "xsquf": // BLACK MEDIUM SQUARE - return rune(0x25fc), true - case "xtimes": // N-ARY TIMES OPERATOR - return rune(0x2a09), true - case "xuplus": // N-ARY UNION OPERATOR WITH PLUS - return rune(0x2a04), true - case "xutri": // WHITE UP-POINTING TRIANGLE - return rune(0x25b3), true - case "xvee": // N-ARY LOGICAL OR - return rune(0x22c1), true - case "xwedge": // N-ARY LOGICAL AND - return rune(0x22c0), true + case "xandand": // TWO LOGICAL AND OPERATOR + return rune(0x2a07), true + case "xbsol": // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT + return rune(0x2571), true + case "xcap": // N-ARY INTERSECTION + return rune(0x22c2), true + case "xcirc": // LARGE CIRCLE + return rune(0x25ef), true + case "xcup": // N-ARY UNION + return rune(0x22c3), true + case "xcupdot": // N-ARY UNION OPERATOR WITH DOT + return rune(0x2a03), true + case "xdtri": // WHITE DOWN-POINTING TRIANGLE + return rune(0x25bd), true + case "xfr": // MATHEMATICAL FRAKTUR SMALL X + return rune(0x01d535), true + case "xgr": // GREEK SMALL LETTER XI + return rune(0x03be), true + case "xhArr": // LONG LEFT RIGHT DOUBLE ARROW + return rune(0x27fa), true + case "xharr": // LONG LEFT RIGHT ARROW + return rune(0x27f7), true + case "xi": // GREEK SMALL LETTER XI + return rune(0x03be), true + case "xlArr": // LONG LEFTWARDS DOUBLE ARROW + return rune(0x27f8), true + case "xlarr": // LONG LEFTWARDS ARROW + return rune(0x27f5), true + case "xmap": // LONG RIGHTWARDS ARROW FROM BAR + return rune(0x27fc), true + case "xnis": // CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE + return rune(0x22fb), true + case "xodot": // N-ARY CIRCLED DOT OPERATOR + return rune(0x2a00), true + case "xopf": // MATHEMATICAL DOUBLE-STRUCK SMALL X + return rune(0x01d569), true + case "xoplus": // N-ARY CIRCLED PLUS OPERATOR + return rune(0x2a01), true + case "xoror": // TWO LOGICAL OR OPERATOR + return rune(0x2a08), true + case "xotime": // N-ARY CIRCLED TIMES OPERATOR + return rune(0x2a02), true + case "xrArr": // LONG RIGHTWARDS DOUBLE ARROW + return rune(0x27f9), true + case "xrarr": // LONG RIGHTWARDS ARROW + return rune(0x27f6), true + case "xscr": // MATHEMATICAL SCRIPT SMALL X + return rune(0x01d4cd), true + case "xsol": // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT + return rune(0x2572), true + case "xsqcap": // N-ARY SQUARE INTERSECTION OPERATOR + return rune(0x2a05), true + case "xsqcup": // N-ARY SQUARE UNION OPERATOR + return rune(0x2a06), true + case "xsqu": // WHITE MEDIUM SQUARE + return rune(0x25fb), true + case "xsquf": // BLACK MEDIUM SQUARE + return rune(0x25fc), true + case "xtimes": // N-ARY TIMES OPERATOR + return rune(0x2a09), true + case "xuplus": // N-ARY UNION OPERATOR WITH PLUS + return rune(0x2a04), true + case "xutri": // WHITE UP-POINTING TRIANGLE + return rune(0x25b3), true + case "xvee": // N-ARY LOGICAL OR + return rune(0x22c1), true + case "xwedge": // N-ARY LOGICAL AND + return rune(0x22c0), true } case 'y': switch name { - case "yacute": // LATIN SMALL LETTER Y WITH ACUTE - return rune(0xfd), true - case "yacy": // CYRILLIC SMALL LETTER YA - return rune(0x044f), true - case "ycirc": // LATIN SMALL LETTER Y WITH CIRCUMFLEX - return rune(0x0177), true - case "ycy": // CYRILLIC SMALL LETTER YERU - return rune(0x044b), true - case "yen": // YEN SIGN - return rune(0xa5), true - case "yfr": // MATHEMATICAL FRAKTUR SMALL Y - return rune(0x01d536), true - case "yicy": // CYRILLIC SMALL LETTER YI - return rune(0x0457), true - case "yopf": // MATHEMATICAL DOUBLE-STRUCK SMALL Y - return rune(0x01d56a), true - case "yscr": // MATHEMATICAL SCRIPT SMALL Y - return rune(0x01d4ce), true - case "yucy": // CYRILLIC SMALL LETTER YU - return rune(0x044e), true - case "yuml": // LATIN SMALL LETTER Y WITH DIAERESIS - return rune(0xff), true + case "yacute": // LATIN SMALL LETTER Y WITH ACUTE + return rune(0xfd), true + case "yacy": // CYRILLIC SMALL LETTER YA + return rune(0x044f), true + case "ycirc": // LATIN SMALL LETTER Y WITH CIRCUMFLEX + return rune(0x0177), true + case "ycy": // CYRILLIC SMALL LETTER YERU + return rune(0x044b), true + case "yen": // YEN SIGN + return rune(0xa5), true + case "yfr": // MATHEMATICAL FRAKTUR SMALL Y + return rune(0x01d536), true + case "yicy": // CYRILLIC SMALL LETTER YI + return rune(0x0457), true + case "yopf": // MATHEMATICAL DOUBLE-STRUCK SMALL Y + return rune(0x01d56a), true + case "yscr": // MATHEMATICAL SCRIPT SMALL Y + return rune(0x01d4ce), true + case "yucy": // CYRILLIC SMALL LETTER YU + return rune(0x044e), true + case "yuml": // LATIN SMALL LETTER Y WITH DIAERESIS + return rune(0xff), true } case 'z': switch name { - case "zacute": // LATIN SMALL LETTER Z WITH ACUTE - return rune(0x017a), true - case "zcaron": // LATIN SMALL LETTER Z WITH CARON - return rune(0x017e), true - case "zcy": // CYRILLIC SMALL LETTER ZE - return rune(0x0437), true - case "zdot": // LATIN SMALL LETTER Z WITH DOT ABOVE - return rune(0x017c), true - case "zeetrf": // BLACK-LETTER CAPITAL Z - return rune(0x2128), true - case "zeta": // GREEK SMALL LETTER ZETA - return rune(0x03b6), true - case "zfr": // MATHEMATICAL FRAKTUR SMALL Z - return rune(0x01d537), true - case "zgr": // GREEK SMALL LETTER ZETA - return rune(0x03b6), true - case "zhcy": // CYRILLIC SMALL LETTER ZHE - return rune(0x0436), true - case "zigrarr": // RIGHTWARDS SQUIGGLE ARROW - return rune(0x21dd), true - case "zopf": // MATHEMATICAL DOUBLE-STRUCK SMALL Z - return rune(0x01d56b), true - case "zscr": // MATHEMATICAL SCRIPT SMALL Z - return rune(0x01d4cf), true - case "zwj": // ZERO WIDTH JOINER - return rune(0x200d), true - case "zwnj": // ZERO WIDTH NON-JOINER - return rune(0x200c), true + case "zacute": // LATIN SMALL LETTER Z WITH ACUTE + return rune(0x017a), true + case "zcaron": // LATIN SMALL LETTER Z WITH CARON + return rune(0x017e), true + case "zcy": // CYRILLIC SMALL LETTER ZE + return rune(0x0437), true + case "zdot": // LATIN SMALL LETTER Z WITH DOT ABOVE + return rune(0x017c), true + case "zeetrf": // BLACK-LETTER CAPITAL Z + return rune(0x2128), true + case "zeta": // GREEK SMALL LETTER ZETA + return rune(0x03b6), true + case "zfr": // MATHEMATICAL FRAKTUR SMALL Z + return rune(0x01d537), true + case "zgr": // GREEK SMALL LETTER ZETA + return rune(0x03b6), true + case "zhcy": // CYRILLIC SMALL LETTER ZHE + return rune(0x0436), true + case "zigrarr": // RIGHTWARDS SQUIGGLE ARROW + return rune(0x21dd), true + case "zopf": // MATHEMATICAL DOUBLE-STRUCK SMALL Z + return rune(0x01d56b), true + case "zscr": // MATHEMATICAL SCRIPT SMALL Z + return rune(0x01d4cf), true + case "zwj": // ZERO WIDTH JOINER + return rune(0x200d), true + case "zwnj": // ZERO WIDTH NON-JOINER + return rune(0x200c), true } } return -1, false diff --git a/core/unicode/tools/generate_entity_table.odin b/core/unicode/tools/generate_entity_table.odin index ec8106cbe..16baa1adf 100644 --- a/core/unicode/tools/generate_entity_table.odin +++ b/core/unicode/tools/generate_entity_table.odin @@ -142,7 +142,7 @@ generate_encoding_entity_table :: proc() { /* Generate table. */ - fmt.wprintln(w, "package unicode_entity") + fmt.wprintln(w, "package encoding_unicode_entity") fmt.wprintln(w, "") fmt.wprintln(w, GENERATED) fmt.wprintln(w, "") @@ -195,12 +195,12 @@ named_xml_entity_to_rune :: proc(name: string) -> (decoded: rune, ok: bool) { e := entity_map[v] - fmt.wprintf(w, "\t\t\tcase \"%v\":", e.name) + fmt.wprintf(w, "\t\tcase \"%v\":", e.name) for i := len(e.name); i < max_name_length; i += 1 { fmt.wprintf(w, " ") } fmt.wprintf(w, " // %v\n", e.description) - fmt.wprintf(w, "\t\t\t\treturn %v, true\n", rune_to_string(e.codepoint)) + fmt.wprintf(w, "\t\t\treturn %v, true\n", rune_to_string(e.codepoint)) should_close = true } From 930c92929477ea39d46310bbfbd23c19db4d12ac Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 29 Jun 2024 18:49:57 +0100 Subject: [PATCH 088/129] Indentation fixes --- core/encoding/base32/base32.odin | 232 +++++++++++++++---------------- core/flags/internal_rtti.odin | 209 ++++++++++++++-------------- core/image/common.odin | 82 +++++------ core/image/png/png.odin | 44 +++--- 4 files changed, 280 insertions(+), 287 deletions(-) diff --git a/core/encoding/base32/base32.odin b/core/encoding/base32/base32.odin index 962a3ead4..f3320428d 100644 --- a/core/encoding/base32/base32.odin +++ b/core/encoding/base32/base32.odin @@ -8,141 +8,141 @@ package encoding_base32 // truncate it from the encoded output. ENC_TABLE := [32]byte { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', - 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', - 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', - 'Y', 'Z', '2', '3', '4', '5', '6', '7', + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', + 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', + 'Y', 'Z', '2', '3', '4', '5', '6', '7', } PADDING :: '=' DEC_TABLE := [?]u8 { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 26, 27, 28, 29, 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0, - 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 26, 27, 28, 29, 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0, + 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, } encode :: proc(data: []byte, ENC_TBL := ENC_TABLE, allocator := context.allocator) -> string { - out_length := (len(data) + 4) / 5 * 8 - out := make([]byte, out_length) - _encode(out, data) - return string(out) + out_length := (len(data) + 4) / 5 * 8 + out := make([]byte, out_length) + _encode(out, data) + return string(out) } @private _encode :: proc(out, data: []byte, ENC_TBL := ENC_TABLE, allocator := context.allocator) { - out := out - data := data + out := out + data := data - for len(data) > 0 { - carry: byte - switch len(data) { - case: - out[7] = ENC_TABLE[data[4] & 0x1f] - carry = data[4] >> 5 - fallthrough - case 4: - out[6] = ENC_TABLE[carry | (data[3] << 3) & 0x1f] - out[5] = ENC_TABLE[(data[3] >> 2) & 0x1f] - carry = data[3] >> 7 - fallthrough - case 3: - out[4] = ENC_TABLE[carry | (data[2] << 1) & 0x1f] - carry = (data[2] >> 4) & 0x1f - fallthrough - case 2: - out[3] = ENC_TABLE[carry | (data[1] << 4) & 0x1f] - out[2] = ENC_TABLE[(data[1] >> 1) & 0x1f] - carry = (data[1] >> 6) & 0x1f - fallthrough - case 1: - out[1] = ENC_TABLE[carry | (data[0] << 2) & 0x1f] - out[0] = ENC_TABLE[data[0] >> 3] - } + for len(data) > 0 { + carry: byte + switch len(data) { + case: + out[7] = ENC_TABLE[data[4] & 0x1f] + carry = data[4] >> 5 + fallthrough + case 4: + out[6] = ENC_TABLE[carry | (data[3] << 3) & 0x1f] + out[5] = ENC_TABLE[(data[3] >> 2) & 0x1f] + carry = data[3] >> 7 + fallthrough + case 3: + out[4] = ENC_TABLE[carry | (data[2] << 1) & 0x1f] + carry = (data[2] >> 4) & 0x1f + fallthrough + case 2: + out[3] = ENC_TABLE[carry | (data[1] << 4) & 0x1f] + out[2] = ENC_TABLE[(data[1] >> 1) & 0x1f] + carry = (data[1] >> 6) & 0x1f + fallthrough + case 1: + out[1] = ENC_TABLE[carry | (data[0] << 2) & 0x1f] + out[0] = ENC_TABLE[data[0] >> 3] + } - if len(data) < 5 { - out[7] = byte(PADDING) - if len(data) < 4 { - out[6] = byte(PADDING) - out[5] = byte(PADDING) - if len(data) < 3 { - out[4] = byte(PADDING) - if len(data) < 2 { - out[3] = byte(PADDING) - out[2] = byte(PADDING) - } - } - } - break - } - data = data[5:] - out = out[8:] - } + if len(data) < 5 { + out[7] = byte(PADDING) + if len(data) < 4 { + out[6] = byte(PADDING) + out[5] = byte(PADDING) + if len(data) < 3 { + out[4] = byte(PADDING) + if len(data) < 2 { + out[3] = byte(PADDING) + out[2] = byte(PADDING) + } + } + } + break + } + data = data[5:] + out = out[8:] + } } decode :: proc(data: string, DEC_TBL := DEC_TABLE, allocator := context.allocator) -> []byte #no_bounds_check{ - if len(data) == 0 { - return nil - } + if len(data) == 0 { + return nil + } - outi := 0 - data := data + outi := 0 + data := data - out := make([]byte, len(data) / 8 * 5, allocator) - end := false - for len(data) > 0 && !end { - dbuf : [8]byte - dlen := 8 + out := make([]byte, len(data) / 8 * 5, allocator) + end := false + for len(data) > 0 && !end { + dbuf : [8]byte + dlen := 8 - for j := 0; j < 8; { - if len(data) == 0 { - dlen, end = j, true - break - } - input := data[0] - data = data[1:] - if input == byte(PADDING) && j >= 2 && len(data) < 8 { - assert(!(len(data) + j < 8 - 1), "Corrupted input") - for k := 0; k < 8-1-j; k +=1 { - assert(len(data) < k || data[k] == byte(PADDING), "Corrupted input") - } - dlen, end = j, true - assert(dlen != 1 && dlen != 3 && dlen != 6, "Corrupted input") - break - } - dbuf[j] = DEC_TABLE[input] - assert(dbuf[j] != 0xff, "Corrupted input") - j += 1 - } + for j := 0; j < 8; { + if len(data) == 0 { + dlen, end = j, true + break + } + input := data[0] + data = data[1:] + if input == byte(PADDING) && j >= 2 && len(data) < 8 { + assert(!(len(data) + j < 8 - 1), "Corrupted input") + for k := 0; k < 8-1-j; k +=1 { + assert(len(data) < k || data[k] == byte(PADDING), "Corrupted input") + } + dlen, end = j, true + assert(dlen != 1 && dlen != 3 && dlen != 6, "Corrupted input") + break + } + dbuf[j] = DEC_TABLE[input] + assert(dbuf[j] != 0xff, "Corrupted input") + j += 1 + } - switch dlen { - case 8: - out[outi + 4] = dbuf[6] << 5 | dbuf[7] - fallthrough - case 7: - out[outi + 3] = dbuf[4] << 7 | dbuf[5] << 2 | dbuf[6] >> 3 - fallthrough - case 5: - out[outi + 2] = dbuf[3] << 4 | dbuf[4] >> 1 - fallthrough - case 4: - out[outi + 1] = dbuf[1] << 6 | dbuf[2] << 1 | dbuf[3] >> 4 - fallthrough - case 2: - out[outi + 0] = dbuf[0] << 3 | dbuf[1] >> 2 - } - outi += 5 - } - return out + switch dlen { + case 8: + out[outi + 4] = dbuf[6] << 5 | dbuf[7] + fallthrough + case 7: + out[outi + 3] = dbuf[4] << 7 | dbuf[5] << 2 | dbuf[6] >> 3 + fallthrough + case 5: + out[outi + 2] = dbuf[3] << 4 | dbuf[4] >> 1 + fallthrough + case 4: + out[outi + 1] = dbuf[1] << 6 | dbuf[2] << 1 | dbuf[3] >> 4 + fallthrough + case 2: + out[outi + 0] = dbuf[0] << 3 | dbuf[1] >> 2 + } + outi += 5 + } + return out } diff --git a/core/flags/internal_rtti.odin b/core/flags/internal_rtti.odin index f19f52ba5..b7aecdef3 100644 --- a/core/flags/internal_rtti.odin +++ b/core/flags/internal_rtti.odin @@ -45,45 +45,45 @@ parse_and_set_pointer_by_base_type :: proc(ptr: rawptr, str: string, type_info: if specific_type_info.signed { value := strconv.parse_i128(str) or_return switch type_info.id { - case i8: (cast(^i8) ptr)^ = cast(i8) bounded_int(value, cast(i128)min(i8), cast(i128)max(i8) ) or_return - case i16: (cast(^i16) ptr)^ = cast(i16) bounded_int(value, cast(i128)min(i16), cast(i128)max(i16) ) or_return - case i32: (cast(^i32) ptr)^ = cast(i32) bounded_int(value, cast(i128)min(i32), cast(i128)max(i32) ) or_return - case i64: (cast(^i64) ptr)^ = cast(i64) bounded_int(value, cast(i128)min(i64), cast(i128)max(i64) ) or_return - case i128: (cast(^i128) ptr)^ = value + case i8: (^i8) (ptr)^ = cast(i8) bounded_int(value, cast(i128)min(i8), cast(i128)max(i8) ) or_return + case i16: (^i16) (ptr)^ = cast(i16) bounded_int(value, cast(i128)min(i16), cast(i128)max(i16) ) or_return + case i32: (^i32) (ptr)^ = cast(i32) bounded_int(value, cast(i128)min(i32), cast(i128)max(i32) ) or_return + case i64: (^i64) (ptr)^ = cast(i64) bounded_int(value, cast(i128)min(i64), cast(i128)max(i64) ) or_return + case i128: (^i128) (ptr)^ = value - case int: (cast(^int) ptr)^ = cast(int) bounded_int(value, cast(i128)min(int), cast(i128)max(int) ) or_return + case int: (^int) (ptr)^ = cast(int) bounded_int(value, cast(i128)min(int), cast(i128)max(int) ) or_return - case i16le: (cast(^i16le) ptr)^ = cast(i16le) bounded_int(value, cast(i128)min(i16le), cast(i128)max(i16le) ) or_return - case i32le: (cast(^i32le) ptr)^ = cast(i32le) bounded_int(value, cast(i128)min(i32le), cast(i128)max(i32le) ) or_return - case i64le: (cast(^i64le) ptr)^ = cast(i64le) bounded_int(value, cast(i128)min(i64le), cast(i128)max(i64le) ) or_return - case i128le: (cast(^i128le)ptr)^ = cast(i128le) bounded_int(value, cast(i128)min(i128le), cast(i128)max(i128le)) or_return + case i16le: (^i16le) (ptr)^ = cast(i16le) bounded_int(value, cast(i128)min(i16le), cast(i128)max(i16le) ) or_return + case i32le: (^i32le) (ptr)^ = cast(i32le) bounded_int(value, cast(i128)min(i32le), cast(i128)max(i32le) ) or_return + case i64le: (^i64le) (ptr)^ = cast(i64le) bounded_int(value, cast(i128)min(i64le), cast(i128)max(i64le) ) or_return + case i128le: (^i128le)(ptr)^ = cast(i128le) bounded_int(value, cast(i128)min(i128le), cast(i128)max(i128le)) or_return - case i16be: (cast(^i16be) ptr)^ = cast(i16be) bounded_int(value, cast(i128)min(i16be), cast(i128)max(i16be) ) or_return - case i32be: (cast(^i32be) ptr)^ = cast(i32be) bounded_int(value, cast(i128)min(i32be), cast(i128)max(i32be) ) or_return - case i64be: (cast(^i64be) ptr)^ = cast(i64be) bounded_int(value, cast(i128)min(i64be), cast(i128)max(i64be) ) or_return - case i128be: (cast(^i128be)ptr)^ = cast(i128be) bounded_int(value, cast(i128)min(i128be), cast(i128)max(i128be)) or_return + case i16be: (^i16be) (ptr)^ = cast(i16be) bounded_int(value, cast(i128)min(i16be), cast(i128)max(i16be) ) or_return + case i32be: (^i32be) (ptr)^ = cast(i32be) bounded_int(value, cast(i128)min(i32be), cast(i128)max(i32be) ) or_return + case i64be: (^i64be) (ptr)^ = cast(i64be) bounded_int(value, cast(i128)min(i64be), cast(i128)max(i64be) ) or_return + case i128be: (^i128be)(ptr)^ = cast(i128be) bounded_int(value, cast(i128)min(i128be), cast(i128)max(i128be)) or_return } } else { value := strconv.parse_u128(str) or_return switch type_info.id { - case u8: (cast(^u8) ptr)^ = cast(u8) bounded_uint(value, cast(u128)max(u8) ) or_return - case u16: (cast(^u16) ptr)^ = cast(u16) bounded_uint(value, cast(u128)max(u16) ) or_return - case u32: (cast(^u32) ptr)^ = cast(u32) bounded_uint(value, cast(u128)max(u32) ) or_return - case u64: (cast(^u64) ptr)^ = cast(u64) bounded_uint(value, cast(u128)max(u64) ) or_return - case u128: (cast(^u128) ptr)^ = value + case u8: (^u8) (ptr)^ = cast(u8) bounded_uint(value, cast(u128)max(u8) ) or_return + case u16: (^u16) (ptr)^ = cast(u16) bounded_uint(value, cast(u128)max(u16) ) or_return + case u32: (^u32) (ptr)^ = cast(u32) bounded_uint(value, cast(u128)max(u32) ) or_return + case u64: (^u64) (ptr)^ = cast(u64) bounded_uint(value, cast(u128)max(u64) ) or_return + case u128: (^u128) (ptr)^ = value - case uint: (cast(^uint) ptr)^ = cast(uint) bounded_uint(value, cast(u128)max(uint) ) or_return - case uintptr: (cast(^uintptr)ptr)^ = cast(uintptr) bounded_uint(value, cast(u128)max(uintptr)) or_return + case uint: (^uint) (ptr)^ = cast(uint) bounded_uint(value, cast(u128)max(uint) ) or_return + case uintptr: (^uintptr)(ptr)^ = cast(uintptr) bounded_uint(value, cast(u128)max(uintptr)) or_return - case u16le: (cast(^u16le) ptr)^ = cast(u16le) bounded_uint(value, cast(u128)max(u16le) ) or_return - case u32le: (cast(^u32le) ptr)^ = cast(u32le) bounded_uint(value, cast(u128)max(u32le) ) or_return - case u64le: (cast(^u64le) ptr)^ = cast(u64le) bounded_uint(value, cast(u128)max(u64le) ) or_return - case u128le: (cast(^u128le) ptr)^ = cast(u128le) bounded_uint(value, cast(u128)max(u128le) ) or_return + case u16le: (^u16le) (ptr)^ = cast(u16le) bounded_uint(value, cast(u128)max(u16le) ) or_return + case u32le: (^u32le) (ptr)^ = cast(u32le) bounded_uint(value, cast(u128)max(u32le) ) or_return + case u64le: (^u64le) (ptr)^ = cast(u64le) bounded_uint(value, cast(u128)max(u64le) ) or_return + case u128le: (^u128le) (ptr)^ = cast(u128le) bounded_uint(value, cast(u128)max(u128le) ) or_return - case u16be: (cast(^u16be) ptr)^ = cast(u16be) bounded_uint(value, cast(u128)max(u16be) ) or_return - case u32be: (cast(^u32be) ptr)^ = cast(u32be) bounded_uint(value, cast(u128)max(u32be) ) or_return - case u64be: (cast(^u64be) ptr)^ = cast(u64be) bounded_uint(value, cast(u128)max(u64be) ) or_return - case u128be: (cast(^u128be) ptr)^ = cast(u128be) bounded_uint(value, cast(u128)max(u128be) ) or_return + case u16be: (^u16be) (ptr)^ = cast(u16be) bounded_uint(value, cast(u128)max(u16be) ) or_return + case u32be: (^u32be) (ptr)^ = cast(u32be) bounded_uint(value, cast(u128)max(u32be) ) or_return + case u64be: (^u64be) (ptr)^ = cast(u64be) bounded_uint(value, cast(u128)max(u64be) ) or_return + case u128be: (^u128be) (ptr)^ = cast(u128be) bounded_uint(value, cast(u128)max(u128be) ) or_return } } @@ -92,60 +92,60 @@ parse_and_set_pointer_by_base_type :: proc(ptr: rawptr, str: string, type_info: return false } - (cast(^rune)ptr)^ = utf8.rune_at_pos(str, 0) + (^rune)(ptr)^ = utf8.rune_at_pos(str, 0) case runtime.Type_Info_Float: value := strconv.parse_f64(str) or_return switch type_info.id { - case f16: (cast(^f16) ptr)^ = cast(f16) value - case f32: (cast(^f32) ptr)^ = cast(f32) value - case f64: (cast(^f64) ptr)^ = value + case f16: (^f16) (ptr)^ = cast(f16) value + case f32: (^f32) (ptr)^ = cast(f32) value + case f64: (^f64) (ptr)^ = value - case f16le: (cast(^f16le)ptr)^ = cast(f16le) value - case f32le: (cast(^f32le)ptr)^ = cast(f32le) value - case f64le: (cast(^f64le)ptr)^ = cast(f64le) value + case f16le: (^f16le)(ptr)^ = cast(f16le) value + case f32le: (^f32le)(ptr)^ = cast(f32le) value + case f64le: (^f64le)(ptr)^ = cast(f64le) value - case f16be: (cast(^f16be)ptr)^ = cast(f16be) value - case f32be: (cast(^f32be)ptr)^ = cast(f32be) value - case f64be: (cast(^f64be)ptr)^ = cast(f64be) value + case f16be: (^f16be)(ptr)^ = cast(f16be) value + case f32be: (^f32be)(ptr)^ = cast(f32be) value + case f64be: (^f64be)(ptr)^ = cast(f64be) value } case runtime.Type_Info_Complex: value := strconv.parse_complex128(str) or_return switch type_info.id { - case complex128: (cast(^complex128)ptr)^ = value - case complex64: (cast(^complex64) ptr)^ = cast(complex64)value - case complex32: (cast(^complex32) ptr)^ = cast(complex32)value + case complex32: (^complex32) (ptr)^ = (complex32)(value) + case complex64: (^complex64) (ptr)^ = (complex64)(value) + case complex128: (^complex128)(ptr)^ = value } case runtime.Type_Info_Quaternion: value := strconv.parse_quaternion256(str) or_return switch type_info.id { - case quaternion256: (cast(^quaternion256)ptr)^ = value - case quaternion128: (cast(^quaternion128)ptr)^ = cast(quaternion128)value - case quaternion64: (cast(^quaternion64) ptr)^ = cast(quaternion64)value + case quaternion64: (^quaternion64) (ptr)^ = (quaternion64)(value) + case quaternion128: (^quaternion128)(ptr)^ = (quaternion128)(value) + case quaternion256: (^quaternion256)(ptr)^ = value } case runtime.Type_Info_String: if specific_type_info.is_cstring { - cstr_ptr := cast(^cstring)ptr + cstr_ptr := (^cstring)(ptr) if cstr_ptr != nil { // Prevent memory leaks from us setting this value multiple times. delete(cstr_ptr^) } cstr_ptr^ = strings.clone_to_cstring(str) } else { - (cast(^string)ptr)^ = str + (^string)(ptr)^ = str } case runtime.Type_Info_Boolean: value := strconv.parse_bool(str) or_return switch type_info.id { - case bool: (cast(^bool) ptr)^ = value - case b8: (cast(^b8) ptr)^ = cast(b8) value - case b16: (cast(^b16) ptr)^ = cast(b16) value - case b32: (cast(^b32) ptr)^ = cast(b32) value - case b64: (cast(^b64) ptr)^ = cast(b64) value + case bool: (^bool)(ptr)^ = value + case b8: (^b8) (ptr)^ = b8(value) + case b16: (^b16) (ptr)^ = b16(value) + case b32: (^b32) (ptr)^ = b32(value) + case b64: (^b64) (ptr)^ = b64(value) } case runtime.Type_Info_Bit_Set: @@ -154,9 +154,9 @@ parse_and_set_pointer_by_base_type :: proc(ptr: rawptr, str: string, type_info: value: u128 // NOTE: `upper` is inclusive, i.e: `0..=31` - max_bit_index := cast(u128)(1 + specific_type_info.upper - specific_type_info.lower) - bit_index : u128 = 0 - #no_bounds_check for string_index : uint = 0; string_index < len(str); string_index += 1 { + max_bit_index := u128(1 + specific_type_info.upper - specific_type_info.lower) + bit_index := u128(0) + #no_bounds_check for string_index in 0.. (int, bool) { if args_tag, ok := reflect.struct_tag_lookup(field.tag, TAG_ARGS); ok { if pos_subtag, pos_ok := get_struct_subtag(args_tag, SUBTAG_POS); pos_ok { if value, parse_ok := strconv.parse_u64_of_base(pos_subtag, 10); parse_ok { - return cast(int)value, true + return int(value), true } } } @@ -516,15 +516,8 @@ get_field_by_name :: proc(model: ^$T, name: string) -> (result: reflect.Struct_F // Get a struct field by its `pos` subtag. get_field_by_pos :: proc(model: ^$T, pos: int) -> (result: reflect.Struct_Field, index: int, ok: bool) { for field, i in reflect.struct_fields_zipped(T) { - args_tag, tag_ok := reflect.struct_tag_lookup(field.tag, TAG_ARGS) - if !tag_ok { - continue - } - - pos_subtag, pos_ok := get_struct_subtag(args_tag, SUBTAG_POS) - if !pos_ok { - continue - } + args_tag := reflect.struct_tag_lookup(field.tag, TAG_ARGS) or_continue + pos_subtag := get_struct_subtag(args_tag, SUBTAG_POS) or_continue value, parse_ok := strconv.parse_u64_of_base(pos_subtag, 10) if parse_ok && cast(int)value == pos { diff --git a/core/image/common.odin b/core/image/common.odin index fed2c1470..07152e7db 100644 --- a/core/image/common.odin +++ b/core/image/common.odin @@ -1313,55 +1313,55 @@ expand_grayscale :: proc(img: ^Image, allocator := context.allocator) -> (ok: bo } switch img.depth { - case 8: - switch img.channels { - case 1: // Turn Gray into RGB - out := mem.slice_data_cast([]RGB_Pixel, buf.buf[:]) + case 8: + switch img.channels { + case 1: // Turn Gray into RGB + out := mem.slice_data_cast([]RGB_Pixel, buf.buf[:]) - for p in img.pixels.buf { - out[0] = p // Broadcast gray value into RGB components. - out = out[1:] - } - - case 2: // Turn Gray + Alpha into RGBA - inp := mem.slice_data_cast([]GA_Pixel, img.pixels.buf[:]) - out := mem.slice_data_cast([]RGBA_Pixel, buf.buf[:]) - - for p in inp { - out[0].rgb = p.r // Gray component. - out[0].a = p.g // Alpha component. - } - - case: - unreachable() + for p in img.pixels.buf { + out[0] = p // Broadcast gray value into RGB components. + out = out[1:] } - case 16: - switch img.channels { - case 1: // Turn Gray into RGB - inp := mem.slice_data_cast([]u16, img.pixels.buf[:]) - out := mem.slice_data_cast([]RGB_Pixel_16, buf.buf[:]) + case 2: // Turn Gray + Alpha into RGBA + inp := mem.slice_data_cast([]GA_Pixel, img.pixels.buf[:]) + out := mem.slice_data_cast([]RGBA_Pixel, buf.buf[:]) - for p in inp { - out[0] = p // Broadcast gray value into RGB components. - out = out[1:] - } - - case 2: // Turn Gray + Alpha into RGBA - inp := mem.slice_data_cast([]GA_Pixel_16, img.pixels.buf[:]) - out := mem.slice_data_cast([]RGBA_Pixel_16, buf.buf[:]) - - for p in inp { - out[0].rgb = p.r // Gray component. - out[0].a = p.g // Alpha component. - } - - case: - unreachable() + for p in inp { + out[0].rgb = p.r // Gray component. + out[0].a = p.g // Alpha component. } case: unreachable() + } + + case 16: + switch img.channels { + case 1: // Turn Gray into RGB + inp := mem.slice_data_cast([]u16, img.pixels.buf[:]) + out := mem.slice_data_cast([]RGB_Pixel_16, buf.buf[:]) + + for p in inp { + out[0] = p // Broadcast gray value into RGB components. + out = out[1:] + } + + case 2: // Turn Gray + Alpha into RGBA + inp := mem.slice_data_cast([]GA_Pixel_16, img.pixels.buf[:]) + out := mem.slice_data_cast([]RGBA_Pixel_16, buf.buf[:]) + + for p in inp { + out[0].rgb = p.r // Gray component. + out[0].a = p.g // Alpha component. + } + + case: + unreachable() + } + + case: + unreachable() } diff --git a/core/image/png/png.odin b/core/image/png/png.odin index aa1c5f781..aa42c5f56 100644 --- a/core/image/png/png.odin +++ b/core/image/png/png.odin @@ -535,28 +535,28 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a ct := transmute(u8)info.header.color_type switch ct { - case 3: // Indexed color - if c.header.length != 1 { - return {}, .BKGD_Invalid_Length - } - col := _plte.entries[c.data[0]] - img.background = [3]u16{ - u16(col[0]) << 8 | u16(col[0]), - u16(col[1]) << 8 | u16(col[1]), - u16(col[2]) << 8 | u16(col[2]), - } - case 0, 4: // Grayscale, with and without Alpha - if c.header.length != 2 { - return {}, .BKGD_Invalid_Length - } - col := u16(mem.slice_data_cast([]u16be, c.data[:])[0]) - img.background = [3]u16{col, col, col} - case 2, 6: // Color, with and without Alpha - if c.header.length != 6 { - return {}, .BKGD_Invalid_Length - } - col := mem.slice_data_cast([]u16be, c.data[:]) - img.background = [3]u16{u16(col[0]), u16(col[1]), u16(col[2])} + case 3: // Indexed color + if c.header.length != 1 { + return {}, .BKGD_Invalid_Length + } + col := _plte.entries[c.data[0]] + img.background = [3]u16{ + u16(col[0]) << 8 | u16(col[0]), + u16(col[1]) << 8 | u16(col[1]), + u16(col[2]) << 8 | u16(col[2]), + } + case 0, 4: // Grayscale, with and without Alpha + if c.header.length != 2 { + return {}, .BKGD_Invalid_Length + } + col := u16(mem.slice_data_cast([]u16be, c.data[:])[0]) + img.background = [3]u16{col, col, col} + case 2, 6: // Color, with and without Alpha + if c.header.length != 6 { + return {}, .BKGD_Invalid_Length + } + col := mem.slice_data_cast([]u16be, c.data[:]) + img.background = [3]u16{u16(col[0]), u16(col[1]), u16(col[2])} } case .tRNS: From b0cbda4ee0d3f1a8d20536385df67280210aa551 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 29 Jun 2024 18:51:28 +0100 Subject: [PATCH 089/129] Fix indentation of tests --- tests/core/encoding/hxa/test_core_hxa.odin | 24 +++++++------------ .../path/filepath/test_core_filepath.odin | 6 ++--- 2 files changed, 10 insertions(+), 20 deletions(-) diff --git a/tests/core/encoding/hxa/test_core_hxa.odin b/tests/core/encoding/hxa/test_core_hxa.odin index 31d40c8b3..a8f3e94f6 100644 --- a/tests/core/encoding/hxa/test_core_hxa.odin +++ b/tests/core/encoding/hxa/test_core_hxa.odin @@ -134,14 +134,11 @@ test_write :: proc(t: ^testing.T) { testing.expectf(t, read_err == read_e, fmt.tprintf("read_err %v != %v", read_err, read_e)) defer hxa.file_destroy(file) - testing.expectf(t, file.magic_number == 0x417848, fmt.tprintf("file.magic_number %v != %v", - file.magic_number, 0x417848)) + testing.expectf(t, file.magic_number == 0x417848, fmt.tprintf("file.magic_number %v != %v", file.magic_number, 0x417848)) testing.expectf(t, file.version == 3, fmt.tprintf("file.version %v != %v", file.version, 3)) - testing.expectf(t, file.internal_node_count == 1, fmt.tprintf("file.internal_node_count %v != %v", - file.internal_node_count, 1)) + testing.expectf(t, file.internal_node_count == 1, fmt.tprintf("file.internal_node_count %v != %v", file.internal_node_count, 1)) - testing.expectf(t, len(file.nodes) == len(w_file.nodes), fmt.tprintf("len(file.nodes) %v != %v", - len(file.nodes), len(w_file.nodes))) + testing.expectf(t, len(file.nodes) == len(w_file.nodes), fmt.tprintf("len(file.nodes) %v != %v", len(file.nodes), len(w_file.nodes))) m := &file.nodes[0].meta_data w_m := &w_file.nodes[0].meta_data @@ -150,20 +147,16 @@ test_write :: proc(t: ^testing.T) { m_v, m_v_ok := m[0].value.([]f64le) testing.expectf(t, m_v_ok, fmt.tprintf("m_v_ok %v != %v", m_v_ok, true)) - testing.expectf(t, len(m_v) == len(n1_m1_value), fmt.tprintf("%v != len(m_v) %v", - len(m_v), len(n1_m1_value))) + testing.expectf(t, len(m_v) == len(n1_m1_value), fmt.tprintf("%v != len(m_v) %v", len(m_v), len(n1_m1_value))) for i := 0; i < len(m_v); i += 1 { - testing.expectf(t, m_v[i] == n1_m1_value[i], fmt.tprintf("m_v[%d] %v != %v", - i, m_v[i], n1_m1_value[i])) + testing.expectf(t, m_v[i] == n1_m1_value[i], fmt.tprintf("m_v[%d] %v != %v", i, m_v[i], n1_m1_value[i])) } v, v_ok := file.nodes[0].content.(hxa.Node_Image) testing.expectf(t, v_ok, fmt.tprintf("v_ok %v != %v", v_ok, true)) testing.expectf(t, v.type == n1_content.type, fmt.tprintf("v.type %v != %v", v.type, n1_content.type)) - testing.expectf(t, len(v.resolution) == 3, fmt.tprintf("len(v.resolution) %v != %v", - len(v.resolution), 3)) - testing.expectf(t, len(v.image_stack) == len(n1_content.image_stack), fmt.tprintf("len(v.image_stack) %v != %v", - len(v.image_stack), len(n1_content.image_stack))) + testing.expectf(t, len(v.resolution) == 3, fmt.tprintf("len(v.resolution) %v != %v", len(v.resolution), 3)) + testing.expectf(t, len(v.image_stack) == len(n1_content.image_stack), fmt.tprintf("len(v.image_stack) %v != %v", len(v.image_stack), len(n1_content.image_stack))) for i := 0; i < len(v.image_stack); i += 1 { testing.expectf(t, v.image_stack[i].name == n1_content.image_stack[i].name, fmt.tprintf("v.image_stack[%d].name %v != %v", @@ -182,8 +175,7 @@ test_write :: proc(t: ^testing.T) { testing.expectf(t, l_ok, fmt.tprintf("l_ok %v != %v", l_ok, true)) testing.expectf(t, len(l) == len(n1_t), fmt.tprintf("len(l) %v != %v", len(l), len(n1_t))) for j := 0; j < len(l); j += 1 { - testing.expectf(t, l[j] == n1_t[j], fmt.tprintf("l[%d] %v (%h) != %v (%h)", - j, l[j], l[j], n1_t[j], n1_t[j])) + testing.expectf(t, l[j] == n1_t[j], fmt.tprintf("l[%d] %v (%h) != %v (%h)", j, l[j], l[j], n1_t[j], n1_t[j])) } case []f64le: l, l_ok := v.image_stack[i].data.([]f64le) diff --git a/tests/core/path/filepath/test_core_filepath.odin b/tests/core/path/filepath/test_core_filepath.odin index 94b9329bb..f0137f69b 100644 --- a/tests/core/path/filepath/test_core_filepath.odin +++ b/tests/core/path/filepath/test_core_filepath.odin @@ -35,12 +35,10 @@ test_split_list_windows :: proc(t: ^testing.T) { assert(i == d.i, fmt.tprintf("wrong data index: i %d != d.i %d\n", i, d.i)) r := filepath.split_list(d.v) defer delete_split(r) - testing.expect(t, len(r) == len(d.e), fmt.tprintf("i:%d %s(%s) len(r) %d != len(d.e) %d", - i, #procedure, d.v, len(r), len(d.e))) + testing.expect(t, len(r) == len(d.e), fmt.tprintf("i:%d %s(%s) len(r) %d != len(d.e) %d", i, #procedure, d.v, len(r), len(d.e))) if len(r) == len(d.e) { for _, j in r { - testing.expect(t, r[j] == d.e[j], fmt.tprintf("i:%d %s(%v) -> %v[%d] != %v", - i, #procedure, d.v, r[j], j, d.e[j])) + testing.expect(t, r[j] == d.e[j], fmt.tprintf("i:%d %s(%v) -> %v[%d] != %v", i, #procedure, d.v, r[j], j, d.e[j])) } } } From 96330996a60aec89d2fa94804d9b94613be7c14d Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 29 Jun 2024 18:51:39 +0100 Subject: [PATCH 090/129] Fix indentation --- vendor/fontstash/fontstash.odin | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/vendor/fontstash/fontstash.odin b/vendor/fontstash/fontstash.odin index 70edcd109..9b556a04a 100644 --- a/vendor/fontstash/fontstash.odin +++ b/vendor/fontstash/fontstash.odin @@ -798,10 +798,10 @@ __getVerticalAlign :: proc( case .BOTTOMLEFT: switch av { - case .TOP: res = -font.ascender * f32(pixelSize) / 10 - case .MIDDLE: res = -(font.ascender + font.descender) / 2 * f32(pixelSize) / 10 - case .BASELINE: res = 0 - case .BOTTOM: res = -font.descender * f32(pixelSize) / 10 + case .TOP: res = -font.ascender * f32(pixelSize) / 10 + case .MIDDLE: res = -(font.ascender + font.descender) / 2 * f32(pixelSize) / 10 + case .BASELINE: res = 0 + case .BOTTOM: res = -font.descender * f32(pixelSize) / 10 } } From e8517e2694524a94ee88cf925a4a667fb6575f90 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 29 Jun 2024 18:56:45 +0100 Subject: [PATCH 091/129] `-strict-style`: enforce `case` to be in the same column as `switch` --- src/check_stmt.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index f2e3b0242..edf2fae39 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -1258,6 +1258,20 @@ gb_internal void check_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags error_line("\tSuggestion: Was '#partial switch' wanted?\n"); } } + + if (build_context.strict_style) { + Token stok = ss->token; + for_array(i, bs->stmts) { + Ast *stmt = bs->stmts[i]; + if (stmt->kind != Ast_CaseClause) { + continue; + } + Token ctok = stmt->CaseClause.token; + if (ctok.pos.column > stok.pos.column) { + error(ctok, "With '-strict-style', 'case' statements must share the same column as the 'switch' token"); + } + } + } } From 3f9a58808cd95946043ab38523588aec5d8c68dc Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 29 Jun 2024 19:07:34 +0100 Subject: [PATCH 092/129] More style improvements --- core/container/lru/lru_cache.odin | 3 +-- core/hash/xxhash/xxhash_3.odin | 21 ++++++++-------- core/math/rand/rand.odin | 2 +- core/slice/slice.odin | 3 +-- core/unicode/utf8/grapheme.odin | 27 +++++++------------- vendor/OpenGL/wrappers.odin | 42 +++++++++++-------------------- 6 files changed, 37 insertions(+), 61 deletions(-) diff --git a/core/container/lru/lru_cache.odin b/core/container/lru/lru_cache.odin index 23f01fac3..f8aa55dc2 100644 --- a/core/container/lru/lru_cache.odin +++ b/core/container/lru/lru_cache.odin @@ -70,8 +70,7 @@ set :: proc(c: ^$C/Cache($Key, $Value), key: Key, value: Value) -> runtime.Alloc if c.count == c.capacity { e = c.tail _remove_node(c, e) - } - else { + } else { c.count += 1 e = new(Node(Key, Value), c.node_allocator) or_return } diff --git a/core/hash/xxhash/xxhash_3.odin b/core/hash/xxhash/xxhash_3.odin index 611f4dc9f..be2531b6e 100644 --- a/core/hash/xxhash/xxhash_3.odin +++ b/core/hash/xxhash/xxhash_3.odin @@ -897,19 +897,20 @@ XXH3_hashLong_64b_default :: #force_no_inline proc(input: []u8, seed64: xxh_u64, why (uop cache maybe?), but the difference is large and easily measurable. */ @(optimization_mode="speed") -XXH3_hashLong_64b_withSeed_internal :: #force_no_inline proc(input: []u8, - seed: xxh_u64, - f_acc512: XXH3_accumulate_512_f, - f_scramble: XXH3_scramble_accumulator_f, - f_init_sec: XXH3_init_custom_secret_f) -> (hash: xxh_u64) { +XXH3_hashLong_64b_withSeed_internal :: #force_no_inline proc( + input: []u8, + seed: xxh_u64, + f_acc512: XXH3_accumulate_512_f, + f_scramble: XXH3_scramble_accumulator_f, + f_init_sec: XXH3_init_custom_secret_f, +) -> (hash: xxh_u64) { if seed == 0 { return XXH3_hashLong_64b_internal(input, XXH3_kSecret[:], f_acc512, f_scramble) } - { - secret: [XXH_SECRET_DEFAULT_SIZE]u8 - f_init_sec(secret[:], seed) - return XXH3_hashLong_64b_internal(input, secret[:], f_acc512, f_scramble) - } + + secret: [XXH_SECRET_DEFAULT_SIZE]u8 + f_init_sec(secret[:], seed) + return XXH3_hashLong_64b_internal(input, secret[:], f_acc512, f_scramble) } /* diff --git a/core/math/rand/rand.odin b/core/math/rand/rand.odin index 8e3c0264d..2b7b55096 100644 --- a/core/math/rand/rand.odin +++ b/core/math/rand/rand.odin @@ -655,7 +655,7 @@ choice_enum :: proc($T: typeid) -> T where intrinsics.type_is_enum(T), size_of(T) <= 8, - len(T) == cap(T) /* Only allow contiguous enum types */ + len(T) == cap(T) /* Only allow contiguous enum types */ \ { when intrinsics.type_is_unsigned(intrinsics.type_core_type(T)) && u64(max(T)) > u64(max(i64)) { diff --git a/core/slice/slice.odin b/core/slice/slice.odin index 06f08fda2..56cb25b4c 100644 --- a/core/slice/slice.odin +++ b/core/slice/slice.odin @@ -156,8 +156,7 @@ linear_search_proc :: proc(array: $A/[]$T, f: proc(T) -> bool) -> (index: int, f */ @(require_results) binary_search :: proc(array: $A/[]$T, key: T) -> (index: int, found: bool) - where intrinsics.type_is_ordered(T) #no_bounds_check -{ + where intrinsics.type_is_ordered(T) #no_bounds_check { return binary_search_by(array, key, cmp_proc(T)) } diff --git a/core/unicode/utf8/grapheme.odin b/core/unicode/utf8/grapheme.odin index 911165af9..50d1789ab 100644 --- a/core/unicode/utf8/grapheme.odin +++ b/core/unicode/utf8/grapheme.odin @@ -240,8 +240,7 @@ decode_grapheme_clusters :: proc( // GB8: (LVT | T) × T if is_hangul_syllable_leading(this_rune) || is_hangul_syllable_lv(this_rune) || - is_hangul_syllable_lvt(this_rune) - { + is_hangul_syllable_lvt(this_rune) { if !is_hangul_syllable_leading(last_rune) { grapheme_count += 1 } @@ -251,8 +250,7 @@ decode_grapheme_clusters :: proc( if is_hangul_syllable_vowel(this_rune) { if is_hangul_syllable_leading(last_rune) || is_hangul_syllable_vowel(last_rune) || - is_hangul_syllable_lv(last_rune) - { + is_hangul_syllable_lv(last_rune) { continue } grapheme_count += 1 @@ -263,8 +261,7 @@ decode_grapheme_clusters :: proc( if is_hangul_syllable_trailing(last_rune) || is_hangul_syllable_lvt(last_rune) || is_hangul_syllable_lv(last_rune) || - is_hangul_syllable_vowel(last_rune) - { + is_hangul_syllable_vowel(last_rune) { continue } grapheme_count += 1 @@ -285,8 +282,7 @@ decode_grapheme_clusters :: proc( if current_sequence == .Indic { if is_indic_conjunct_break_extend(this_rune) && ( is_indic_conjunct_break_linker(last_rune) || - is_indic_conjunct_break_consonant(last_rune) ) - { + is_indic_conjunct_break_consonant(last_rune) ) { continue_sequence = true continue } @@ -294,8 +290,7 @@ decode_grapheme_clusters :: proc( if is_indic_conjunct_break_linker(this_rune) && ( is_indic_conjunct_break_linker(last_rune) || is_indic_conjunct_break_extend(last_rune) || - is_indic_conjunct_break_consonant(last_rune) ) - { + is_indic_conjunct_break_consonant(last_rune) ) { continue_sequence = true continue } @@ -306,8 +301,7 @@ decode_grapheme_clusters :: proc( // (Support for GB11.) if current_sequence == .Emoji && ( is_gcb_extend_class(last_rune) || - is_emoji_extended_pictographic(last_rune) ) - { + is_emoji_extended_pictographic(last_rune) ) { continue_sequence = true } @@ -336,8 +330,7 @@ decode_grapheme_clusters :: proc( if is_indic_conjunct_break_consonant(this_rune) { if current_sequence == .Indic { if last_rune == ZERO_WIDTH_JOINER || - is_indic_conjunct_break_linker(last_rune) - { + is_indic_conjunct_break_linker(last_rune) { continue_sequence = true } else { grapheme_count += 1 @@ -353,8 +346,7 @@ decode_grapheme_clusters :: proc( if is_indic_conjunct_break_extend(this_rune) { if current_sequence == .Indic { if is_indic_conjunct_break_consonant(last_rune) || - is_indic_conjunct_break_linker(last_rune) - { + is_indic_conjunct_break_linker(last_rune) { continue_sequence = true } else { grapheme_count += 1 @@ -366,8 +358,7 @@ decode_grapheme_clusters :: proc( if is_indic_conjunct_break_linker(this_rune) { if current_sequence == .Indic { if is_indic_conjunct_break_extend(last_rune) || - is_indic_conjunct_break_linker(last_rune) - { + is_indic_conjunct_break_linker(last_rune) { continue_sequence = true } else { grapheme_count += 1 diff --git a/vendor/OpenGL/wrappers.odin b/vendor/OpenGL/wrappers.odin index a04df6987..4aaec4adc 100644 --- a/vendor/OpenGL/wrappers.odin +++ b/vendor/OpenGL/wrappers.odin @@ -454,20 +454,13 @@ when !GL_DEBUG { BeginQueryIndexed :: proc "c" (target: u32, index: u32, id: u32) { impl_BeginQueryIndexed(target, index, id) } EndQueryIndexed :: proc "c" (target: u32, index: u32) { impl_EndQueryIndexed(target, index) } GetQueryIndexediv :: proc "c" (target: u32, index: u32, pname: u32, params: [^]i32) { impl_GetQueryIndexediv(target, index, pname, params) } - GetTextureHandleARB :: proc "c" (texture: u32) -> u64 - { return impl_GetTextureHandleARB(texture) } - GetTextureSamplerHandleARB :: proc "c" (texture, sampler: u32) -> u64 - { return impl_GetTextureSamplerHandleARB(texture, sampler) } - GetImageHandleARB :: proc "c" (texture: u32, level: i32, layered: bool, layer: i32, format: u32) -> u64 - { return impl_GetImageHandleARB(texture, level, layered, layer, format) } - MakeTextureHandleResidentARB :: proc "c" (handle: u64) - { impl_MakeTextureHandleResidentARB(handle) } - MakeImageHandleResidentARB :: proc "c" (handle: u64, access: u32) - { impl_MakeImageHandleResidentARB(handle, access) } - MakeTextureHandleNonResidentARB:: proc "c" (handle: u64) - { impl_MakeTextureHandleNonResidentARB(handle) } - MakeImageHandleNonResidentARB :: proc "c" (handle: u64) - { impl_MakeImageHandleNonResidentARB(handle) } + GetTextureHandleARB :: proc "c" (texture: u32) -> u64 { return impl_GetTextureHandleARB(texture) } + GetTextureSamplerHandleARB :: proc "c" (texture, sampler: u32) -> u64 { return impl_GetTextureSamplerHandleARB(texture, sampler) } + GetImageHandleARB :: proc "c" (texture: u32, level: i32, layered: bool, layer: i32, format: u32) -> u64 { return impl_GetImageHandleARB(texture, level, layered, layer, format) } + MakeTextureHandleResidentARB :: proc "c" (handle: u64) { impl_MakeTextureHandleResidentARB(handle) } + MakeImageHandleResidentARB :: proc "c" (handle: u64, access: u32) { impl_MakeImageHandleResidentARB(handle, access) } + MakeTextureHandleNonResidentARB:: proc "c" (handle: u64) { impl_MakeTextureHandleNonResidentARB(handle) } + MakeImageHandleNonResidentARB :: proc "c" (handle: u64) { impl_MakeImageHandleNonResidentARB(handle) } // VERSION_4_1 ReleaseShaderCompiler :: proc "c" () { impl_ReleaseShaderCompiler() } @@ -1265,20 +1258,13 @@ when !GL_DEBUG { BeginQueryIndexed :: proc "c" (target: u32, index: u32, id: u32, loc := #caller_location) { impl_BeginQueryIndexed(target, index, id); debug_helper(loc, 0, target, index, id) } EndQueryIndexed :: proc "c" (target: u32, index: u32, loc := #caller_location) { impl_EndQueryIndexed(target, index); debug_helper(loc, 0, target, index) } GetQueryIndexediv :: proc "c" (target: u32, index: u32, pname: u32, params: [^]i32, loc := #caller_location) { impl_GetQueryIndexediv(target, index, pname, params); debug_helper(loc, 0, target, index, pname, params) } - GetTextureHandleARB :: proc "c" (target: u32, loc := #caller_location) -> u64 - { ret := impl_GetTextureHandleARB(target); debug_helper(loc, 0, target); return ret } - GetTextureSamplerHandleARB :: proc "c" (texture, sampler: u32, loc := #caller_location) -> u64 - { ret := impl_GetTextureSamplerHandleARB(texture, sampler); debug_helper(loc, 0, texture, sampler); return ret } - GetImageHandleARB :: proc "c" (texture: u32, level: i32, layered: bool, layer: i32, format: u32, loc := #caller_location) -> u64 - { ret := impl_GetImageHandleARB(texture, level, layered, layer, format); debug_helper(loc, 0, texture, level, layered, layer, format); return ret } - MakeTextureHandleResidentARB :: proc "c" (handle: u64, loc := #caller_location) - { impl_MakeTextureHandleResidentARB(handle); debug_helper(loc, 0, handle) } - MakeImageHandleResidentARB :: proc "c" (handle: u64, access: u32, loc := #caller_location) - { impl_MakeImageHandleResidentARB(handle, access); debug_helper(loc, 0, handle, access) } - MakeTextureHandleNonResidentARB:: proc "c" (handle: u64, loc := #caller_location) - { impl_MakeTextureHandleNonResidentARB(handle); debug_helper(loc, 0, handle) } - MakeImageHandleNonResidentARB :: proc "c" (handle: u64, loc := #caller_location) - { impl_MakeImageHandleNonResidentARB(handle); debug_helper(loc, 0, handle) } + GetTextureHandleARB :: proc "c" (target: u32, loc := #caller_location) -> u64 { ret := impl_GetTextureHandleARB(target); debug_helper(loc, 0, target); return ret } + GetTextureSamplerHandleARB :: proc "c" (texture, sampler: u32, loc := #caller_location) -> u64 { ret := impl_GetTextureSamplerHandleARB(texture, sampler); debug_helper(loc, 0, texture, sampler); return ret } + GetImageHandleARB :: proc "c" (texture: u32, level: i32, layered: bool, layer: i32, format: u32, loc := #caller_location) -> u64 { ret := impl_GetImageHandleARB(texture, level, layered, layer, format); debug_helper(loc, 0, texture, level, layered, layer, format); return ret } + MakeTextureHandleResidentARB :: proc "c" (handle: u64, loc := #caller_location) { impl_MakeTextureHandleResidentARB(handle); debug_helper(loc, 0, handle) } + MakeImageHandleResidentARB :: proc "c" (handle: u64, access: u32, loc := #caller_location) { impl_MakeImageHandleResidentARB(handle, access); debug_helper(loc, 0, handle, access) } + MakeTextureHandleNonResidentARB:: proc "c" (handle: u64, loc := #caller_location) { impl_MakeTextureHandleNonResidentARB(handle); debug_helper(loc, 0, handle) } + MakeImageHandleNonResidentARB :: proc "c" (handle: u64, loc := #caller_location) { impl_MakeImageHandleNonResidentARB(handle); debug_helper(loc, 0, handle) } From 5413a8b744deba571287cc830e017369c46e847b Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 29 Jun 2024 19:11:36 +0100 Subject: [PATCH 093/129] Even more style fixes --- base/runtime/wasm_allocator.odin | 2 +- core/container/bit_array/bit_array.odin | 4 ++-- core/encoding/cbor/coding.odin | 2 +- core/encoding/cbor/marshal.odin | 2 +- core/fmt/fmt.odin | 15 ++++++--------- core/image/bmp/bmp.odin | 2 +- core/image/png/png.odin | 4 ++-- core/image/qoi/qoi.odin | 2 +- core/image/tga/tga.odin | 2 +- core/math/noise/internal.odin | 12 +++++------- core/mem/virtual/virtual_linux.odin | 6 +++--- core/net/interface_darwin.odin | 4 ++-- core/net/socket_darwin.odin | 2 +- core/net/socket_linux.odin | 4 ++-- core/slice/slice.odin | 2 +- core/sys/linux/bits.odin | 20 ++++++++++---------- vendor/ENet/unix.odin | 2 +- 17 files changed, 41 insertions(+), 46 deletions(-) diff --git a/base/runtime/wasm_allocator.odin b/base/runtime/wasm_allocator.odin index 366dc2e44..fb0600ea2 100644 --- a/base/runtime/wasm_allocator.odin +++ b/base/runtime/wasm_allocator.odin @@ -679,7 +679,7 @@ allocate_memory :: proc(a: ^WASM_Allocator, alignment: uint, size: uint, loc := // but we just had a stale bit set to mark a populated bucket. // Reset the bit to update latest status so that we do not // redundantly look at this bucket again. - a.free_region_buckets_used &= ~(BUCKET_BITMASK_T(1) << bucket_index) + a.free_region_buckets_used &~= BUCKET_BITMASK_T(1) << bucket_index bucket_mask ~= 1 } diff --git a/core/container/bit_array/bit_array.odin b/core/container/bit_array/bit_array.odin index a8720715c..398cede50 100644 --- a/core/container/bit_array/bit_array.odin +++ b/core/container/bit_array/bit_array.odin @@ -211,7 +211,7 @@ set :: proc(ba: ^Bit_Array, #any_int index: uint, set_to: bool = true, allocator ba.max_index = max(idx, ba.max_index) if set_to{ ba.bits[leg_index] |= 1 << uint(bit_index) } - else { ba.bits[leg_index] &= ~(1 << uint(bit_index)) } + else { ba.bits[leg_index] &~= 1 << uint(bit_index) } return true } @@ -253,7 +253,7 @@ Inputs: - index: Which bit in the array */ unsafe_unset :: proc(b: ^Bit_Array, bit: int) #no_bounds_check { - b.bits[bit >> INDEX_SHIFT] &= ~(1 << uint(bit & INDEX_MASK)) + b.bits[bit >> INDEX_SHIFT] &~= 1 << uint(bit & INDEX_MASK) } /* A helper function to create a Bit Array with optional bias, in case your smallest index is non-zero (including negative). diff --git a/core/encoding/cbor/coding.odin b/core/encoding/cbor/coding.odin index 07f0637a6..f82dc4b81 100644 --- a/core/encoding/cbor/coding.odin +++ b/core/encoding/cbor/coding.odin @@ -233,7 +233,7 @@ encode_into_encoder :: proc(e: Encoder, v: Value, loc := #caller_location) -> En if .Self_Described_CBOR in e.flags { _encode_u64(e, TAG_SELF_DESCRIBED_CBOR, .Tag) or_return - e.flags &~= { .Self_Described_CBOR } + e.flags -= { .Self_Described_CBOR } } switch v_spec in v { diff --git a/core/encoding/cbor/marshal.odin b/core/encoding/cbor/marshal.odin index 775eafd9c..d64d22d9c 100644 --- a/core/encoding/cbor/marshal.odin +++ b/core/encoding/cbor/marshal.odin @@ -85,7 +85,7 @@ marshal_into_encoder :: proc(e: Encoder, v: any, loc := #caller_location) -> (e if .Self_Described_CBOR in e.flags { err_conv(_encode_u64(e, TAG_SELF_DESCRIBED_CBOR, .Tag)) or_return - e.flags &~= { .Self_Described_CBOR } + e.flags -= { .Self_Described_CBOR } } if v == nil { diff --git a/core/fmt/fmt.odin b/core/fmt/fmt.odin index 424e4e6e8..16d35d94a 100644 --- a/core/fmt/fmt.odin +++ b/core/fmt/fmt.odin @@ -1072,8 +1072,8 @@ _fmt_int :: proc(fi: ^Info, u: u64, base: int, is_signed: bool, bit_size: int, d } flags: strconv.Int_Flags - if fi.hash && !fi.zero && start == 0 { flags |= {.Prefix} } - if fi.plus { flags |= {.Plus} } + if fi.hash && !fi.zero && start == 0 { flags += {.Prefix} } + if fi.plus { flags += {.Plus} } s := strconv.append_bits(buf[start:], u, base, is_signed, bit_size, digits, flags) prev_zero := fi.zero defer fi.zero = prev_zero @@ -1157,8 +1157,8 @@ _fmt_int_128 :: proc(fi: ^Info, u: u128, base: int, is_signed: bool, bit_size: i } flags: strconv.Int_Flags - if fi.hash && !fi.zero && start == 0 { flags |= {.Prefix} } - if fi.plus { flags |= {.Plus} } + if fi.hash && !fi.zero && start == 0 { flags += {.Prefix} } + if fi.plus { flags += {.Plus} } s := strconv.append_bits_128(buf[start:], u, base, is_signed, bit_size, digits, flags) if fi.hash && fi.zero && fi.indent == 0 { @@ -1460,13 +1460,10 @@ fmt_string :: proc(fi: ^Info, s: string, verb: rune) { if !fi.minus { io.write_string(fi.writer, s, &fi.n) } - } - else { + } else { io.write_string(fi.writer, s, &fi.n) } - } - else - { + } else { io.write_string(fi.writer, s, &fi.n) } diff --git a/core/image/bmp/bmp.odin b/core/image/bmp/bmp.odin index 64fc1d5a8..dac1b7ab5 100644 --- a/core/image/bmp/bmp.odin +++ b/core/image/bmp/bmp.odin @@ -131,7 +131,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() if .info in options { - options |= {.return_metadata, .do_not_decompress_image} + options += {.return_metadata, .do_not_decompress_image} options -= {.info} } diff --git a/core/image/png/png.odin b/core/image/png/png.odin index aa42c5f56..177269722 100644 --- a/core/image/png/png.odin +++ b/core/image/png/png.odin @@ -341,7 +341,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a options := options if .info in options { - options |= {.return_metadata, .do_not_decompress_image} + options += {.return_metadata, .do_not_decompress_image} options -= {.info} } @@ -354,7 +354,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a } if .do_not_expand_channels in options { - options |= {.do_not_expand_grayscale, .do_not_expand_indexed} + options += {.do_not_expand_grayscale, .do_not_expand_indexed} } if img == nil { diff --git a/core/image/qoi/qoi.odin b/core/image/qoi/qoi.odin index 15ed449da..a121999ea 100644 --- a/core/image/qoi/qoi.odin +++ b/core/image/qoi/qoi.odin @@ -176,7 +176,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a options := options if .info in options { - options |= {.return_metadata, .do_not_decompress_image} + options += {.return_metadata, .do_not_decompress_image} options -= {.info} } diff --git a/core/image/tga/tga.odin b/core/image/tga/tga.odin index 03ef1a386..46e37a0cf 100644 --- a/core/image/tga/tga.odin +++ b/core/image/tga/tga.odin @@ -100,7 +100,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a } if .info in options { - options |= {.return_metadata, .do_not_decompress_image} + options += {.return_metadata, .do_not_decompress_image} options -= {.info} } diff --git a/core/math/noise/internal.odin b/core/math/noise/internal.odin index 5837f9235..b83c4f1b1 100644 --- a/core/math/noise/internal.odin +++ b/core/math/noise/internal.odin @@ -637,22 +637,20 @@ _internal_noise_4d_unskewed_base :: proc(seed: i64, coord: Vec4) -> (value: f32) // Next point is the closest vertex on the 4-simplex whose base vertex is the aforementioned vertex. score := 1.0 + ssi * (-1.0 / UNSKEW_4D) // Seems slightly faster than 1.0-xsi-ysi-zsi-wsi - if si.x >= si.x && si.x >= si.z && si.x >= si.w && si.x >= score { + switch { + case si.x >= si.x && si.x >= si.z && si.x >= si.w && si.x >= score: svp.x += PRIME_X si.x -= 1 ssi -= UNSKEW_4D - } - else if si.y > si.x && si.y >= si.z && si.y >= si.w && si.y >= score { + case si.y > si.x && si.y >= si.z && si.y >= si.w && si.y >= score: svp.y += PRIME_Y si.y -= 1 ssi -= UNSKEW_4D - } - else if si.z > si.x && si.z > si.y && si.z >= si.w && si.z >= score { + case si.z > si.x && si.z > si.y && si.z >= si.w && si.z >= score: svp.z += PRIME_Z si.z -= 1 ssi -= UNSKEW_4D - } - else if si.w > si.x && si.w > si.y && si.w > si.z && si.w >= score { + case si.w > si.x && si.w > si.y && si.w > si.z && si.w >= score: svp.w += PRIME_W si.w -= 1 ssi -= UNSKEW_4D diff --git a/core/mem/virtual/virtual_linux.odin b/core/mem/virtual/virtual_linux.odin index 816a8bb84..0b4532baa 100644 --- a/core/mem/virtual/virtual_linux.odin +++ b/core/mem/virtual/virtual_linux.odin @@ -36,9 +36,9 @@ _release :: proc "contextless" (data: rawptr, size: uint) { _protect :: proc "contextless" (data: rawptr, size: uint, flags: Protect_Flags) -> bool { pflags: linux.Mem_Protection pflags = {} - if .Read in flags { pflags |= {.READ} } - if .Write in flags { pflags |= {.WRITE} } - if .Execute in flags { pflags |= {.EXEC} } + if .Read in flags { pflags += {.READ} } + if .Write in flags { pflags += {.WRITE} } + if .Execute in flags { pflags += {.EXEC} } errno := linux.mprotect(data, size, pflags) return errno == .NONE } diff --git a/core/net/interface_darwin.odin b/core/net/interface_darwin.odin index 59b0e01c5..68353264c 100644 --- a/core/net/interface_darwin.odin +++ b/core/net/interface_darwin.odin @@ -94,7 +94,7 @@ _enumerate_interfaces :: proc(allocator := context.allocator) -> (interfaces: [] state := Link_State{} if .UP in ifaddr.flags { - state |= {.Up} + state += {.Up} } /*if .DORMANT in ifaddr.flags { @@ -102,7 +102,7 @@ _enumerate_interfaces :: proc(allocator := context.allocator) -> (interfaces: [] }*/ if .LOOPBACK in ifaddr.flags { - state |= {.Loopback} + state += {.Loopback} } iface.link.state = state } diff --git a/core/net/socket_darwin.odin b/core/net/socket_darwin.odin index ba86f1005..3f0e576c1 100644 --- a/core/net/socket_darwin.odin +++ b/core/net/socket_darwin.odin @@ -320,7 +320,7 @@ _set_blocking :: proc(socket: Any_Socket, should_block: bool) -> (err: Network_E } if should_block { - flags &= ~int(os.O_NONBLOCK) + flags &~= int(os.O_NONBLOCK) } else { flags |= int(os.O_NONBLOCK) } diff --git a/core/net/socket_linux.odin b/core/net/socket_linux.odin index dc960a5fb..a5d553234 100644 --- a/core/net/socket_linux.odin +++ b/core/net/socket_linux.odin @@ -377,9 +377,9 @@ _set_blocking :: proc(sock: Any_Socket, should_block: bool) -> (err: Network_Err return Set_Blocking_Error(errno) } if should_block { - flags &= ~{.NONBLOCK} + flags -= {.NONBLOCK} } else { - flags |= {.NONBLOCK} + flags += {.NONBLOCK} } errno = linux.fcntl(os_sock, linux.F_SETFL, flags) if errno != .NONE { diff --git a/core/slice/slice.odin b/core/slice/slice.odin index 56cb25b4c..043e51aa5 100644 --- a/core/slice/slice.odin +++ b/core/slice/slice.odin @@ -711,7 +711,7 @@ enumerated_array :: proc(ptr: ^$T) -> []intrinsics.type_elem_type(T) @(require_results) enum_slice_to_bitset :: proc(enums: []$E, $T: typeid/bit_set[E]) -> (bits: T) where intrinsics.type_is_enum(E), intrinsics.type_bit_set_elem_type(T) == E { for v in enums { - bits |= {v} + bits += {v} } return } diff --git a/core/sys/linux/bits.odin b/core/sys/linux/bits.odin index bd686ed63..1e9e5bbbd 100644 --- a/core/sys/linux/bits.odin +++ b/core/sys/linux/bits.odin @@ -1464,16 +1464,16 @@ Futex_Flags_Bits :: enum { Kind of operation on futex, see FUTEX_WAKE_OP */ Futex_Arg_Op :: enum { - SET = 0, /* uaddr2 = oparg; */ - ADD = 1, /* uaddr2 += oparg; */ - OR = 2, /* uaddr2 |= oparg; */ - ANDN = 3, /* uaddr2 &= ~oparg; */ - XOR = 4, /* uaddr2 ^= oparg; */ - PO2_SET = 0, /* uaddr2 = 1< bool { From 2187f3e7ff076ea6375b1a09e32908a00e479dc8 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 29 Jun 2024 19:14:24 +0100 Subject: [PATCH 094/129] `-strict-style` enforce 1TBS (mostly) --- src/parser.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/parser.cpp b/src/parser.cpp index b1a179573..9b27ae156 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -1486,7 +1486,7 @@ gb_internal bool skip_possible_newline(AstFile *f) { return false; } -gb_internal bool skip_possible_newline_for_literal(AstFile *f) { +gb_internal bool skip_possible_newline_for_literal(AstFile *f, bool seen_where=false) { Token curr = f->curr_token; if (token_is_newline(curr)) { Token next = peek_token(f); @@ -1494,6 +1494,10 @@ gb_internal bool skip_possible_newline_for_literal(AstFile *f) { switch (next.kind) { case Token_OpenBrace: case Token_else: + if (build_context.strict_style && !seen_where) { + syntax_error(next, "With '-strict-style' the attached brace style (1TBS) is enforced"); + } + /*fallthrough*/ case Token_where: advance_token(f); return true; @@ -2517,7 +2521,7 @@ gb_internal Ast *parse_operand(AstFile *f, bool lhs) { return type; } - skip_possible_newline_for_literal(f); + skip_possible_newline_for_literal(f, where_token.kind == Token_where); if (allow_token(f, Token_Uninit)) { if (where_token.kind != Token_Invalid) { @@ -4499,6 +4503,9 @@ gb_internal bool parse_control_statement_semicolon_separator(AstFile *f) { } + + + gb_internal Ast *parse_if_stmt(AstFile *f) { if (f->curr_proc == nullptr) { syntax_error(f->curr_token, "You cannot use an if statement in the file scope"); From 835e8bf87a700c695b30d1efaa224e2207cb61f4 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 29 Jun 2024 19:15:33 +0100 Subject: [PATCH 095/129] Update `-strict-style` --- src/main.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index c1ec77ec4..611890a5c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2352,6 +2352,8 @@ gb_internal void print_show_help(String const arg0, String const &command) { print_usage_line(2, "Errs on unneeded tokens, such as unneeded semicolons."); print_usage_line(2, "Errs on missing trailing commas followed by a newline."); print_usage_line(2, "Errs on deprecated syntax."); + print_usage_line(2, "Errs when 'case' labels are not in the same column as the associated 'switch' token."); + print_usage_line(2, "Errs when the attached-brace style in not adhered to (also known as 1TBS)."); print_usage_line(0, ""); print_usage_line(1, "-ignore-warnings"); From 663661db53719b1a7797a3772f5a227405c5ca98 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 29 Jun 2024 19:16:32 +0100 Subject: [PATCH 096/129] Update `core` to `-strict-style` --- core/container/bit_array/bit_array.odin | 7 +++++-- core/sys/linux/sys.odin | 17 ++++++----------- core/sys/linux/wrappers.odin | 3 +-- core/testing/runner.odin | 11 +++++------ 4 files changed, 17 insertions(+), 21 deletions(-) diff --git a/core/container/bit_array/bit_array.odin b/core/container/bit_array/bit_array.odin index 398cede50..b53bacda7 100644 --- a/core/container/bit_array/bit_array.odin +++ b/core/container/bit_array/bit_array.odin @@ -210,8 +210,11 @@ set :: proc(ba: ^Bit_Array, #any_int index: uint, set_to: bool = true, allocator ba.max_index = max(idx, ba.max_index) - if set_to{ ba.bits[leg_index] |= 1 << uint(bit_index) } - else { ba.bits[leg_index] &~= 1 << uint(bit_index) } + if set_to { + ba.bits[leg_index] |= 1 << uint(bit_index) + } else { + ba.bits[leg_index] &~= 1 << uint(bit_index) + } return true } diff --git a/core/sys/linux/sys.odin b/core/sys/linux/sys.odin index ed40719bf..450af9ca9 100644 --- a/core/sys/linux/sys.odin +++ b/core/sys/linux/sys.odin @@ -2241,8 +2241,7 @@ futex_wake :: proc "contextless" (futex: ^Futex, op: Futex_Wake_Type, flags: Fut Returns the total number of waiters that have been woken up plus the number of waiters requeued. */ futex_cmp_requeue :: proc "contextless" (futex: ^Futex, op: Futex_Cmp_Requeue_Type, flags: Futex_Flags, requeue_threshold: u32, - requeue_max: i32, requeue_futex: ^Futex, val: i32) -> (int, Errno) -{ + requeue_max: i32, requeue_futex: ^Futex, val: i32) -> (int, Errno) { futex_flags := cast(u32) op + transmute(u32) flags ret := syscall(SYS_futex, futex, futex_flags, requeue_threshold, requeue_max, requeue_futex, val) return errno_unwrap(ret, int) @@ -2253,8 +2252,7 @@ futex_cmp_requeue :: proc "contextless" (futex: ^Futex, op: Futex_Cmp_Requeue_Ty Returns the total number of waiters that have been woken up. */ futex_requeue :: proc "contextless" (futex: ^Futex, op: Futex_Requeue_Type, flags: Futex_Flags, requeue_threshold: u32, - requeue_max: i32, requeue_futex: ^Futex) -> (int, Errno) -{ + requeue_max: i32, requeue_futex: ^Futex) -> (int, Errno) { futex_flags := cast(u32) op + transmute(u32) flags ret := syscall(SYS_futex, futex, futex_flags, requeue_threshold, requeue_max, requeue_futex) return errno_unwrap(ret, int) @@ -2265,8 +2263,7 @@ futex_requeue :: proc "contextless" (futex: ^Futex, op: Futex_Requeue_Type, flag purpose is to allow implementing conditional values sync primitive, it seems like. */ futex_wake_op :: proc "contextless" (futex: ^Futex, op: Futex_Wake_Op_Type, flags: Futex_Flags, wakeup: i32, - dst_wakeup, dst: ^Futex, futex_op: u32) -> (int, Errno) -{ + dst_wakeup, dst: ^Futex, futex_op: u32) -> (int, Errno) { futex_flags := cast(u32) op + transmute(u32) flags ret := syscall(SYS_futex, futex, futex_flags, wakeup, dst_wakeup, dst, futex_op) return errno_unwrap(ret, int) @@ -2276,8 +2273,7 @@ futex_wake_op :: proc "contextless" (futex: ^Futex, op: Futex_Wake_Op_Type, flag Same as wait, but mask specifies bits that must be equal for the mutex to wake up. */ futex_wait_bitset :: proc "contextless" (futex: ^Futex, op: Futex_Wait_Bitset_Type, flags: Futex_Flags, val: u32, - timeout: ^Time_Spec, mask: u32) -> (int, Errno) -{ + timeout: ^Time_Spec, mask: u32) -> (int, Errno) { futex_flags := cast(u32) op + transmute(u32) flags ret := syscall(SYS_futex, futex, futex_flags, val, timeout, 0, mask) return errno_unwrap(ret, int) @@ -2286,8 +2282,7 @@ futex_wait_bitset :: proc "contextless" (futex: ^Futex, op: Futex_Wait_Bitset_Ty /* Wake up on bitset. */ -futex_wake_bitset :: proc "contextless" (futex: ^Futex, op: Futex_Wake_Bitset_Type, flags: Futex_Flags, n_wakeup: u32, mask: u32) -> (int, Errno) -{ +futex_wake_bitset :: proc "contextless" (futex: ^Futex, op: Futex_Wake_Bitset_Type, flags: Futex_Flags, n_wakeup: u32, mask: u32) -> (int, Errno) { futex_flags := cast(u32) op + transmute(u32) flags ret := syscall(SYS_futex, futex, futex_flags, n_wakeup, 0, 0, mask) return errno_unwrap(ret, int) @@ -2295,7 +2290,7 @@ futex_wake_bitset :: proc "contextless" (futex: ^Futex, op: Futex_Wake_Bitset_Ty // TODO(flysand): Priority inheritance (PI) futicees -futex :: proc { +futex :: proc{ futex_wait, futex_wake, futex_cmp_requeue, diff --git a/core/sys/linux/wrappers.odin b/core/sys/linux/wrappers.odin index 95c818b9d..998a9244c 100644 --- a/core/sys/linux/wrappers.odin +++ b/core/sys/linux/wrappers.odin @@ -115,7 +115,6 @@ futex_op :: proc "contextless" (arg_op: Futex_Arg_Op, cmp_op: Futex_Cmp_Op, op_a /// Helper function for constructing the config for caches perf_cache_config :: #force_inline proc "contextless" (id: Perf_Hardware_Cache_Id, op: Perf_Hardware_Cache_Op_Id, - res: Perf_Hardware_Cache_Result_Id) -> u64 -{ + res: Perf_Hardware_Cache_Result_Id) -> u64 { return u64(id) | (u64(op) << 8) | (u64(res) << 16) } \ No newline at end of file diff --git a/core/testing/runner.odin b/core/testing/runner.odin index fffbb648c..fa7c2ffd2 100644 --- a/core/testing/runner.odin +++ b/core/testing/runner.odin @@ -51,12 +51,11 @@ get_log_level :: #force_inline proc() -> runtime.Logger_Level { // Always use .Debug in `-debug` mode. return .Debug } else { - when LOG_LEVEL == "debug" { return .Debug } - else when LOG_LEVEL == "info" { return .Info } - else when LOG_LEVEL == "warning" { return .Warning } - else when LOG_LEVEL == "error" { return .Error } - else when LOG_LEVEL == "fatal" { return .Fatal } - else { + when LOG_LEVEL == "debug" { return .Debug } else + when LOG_LEVEL == "info" { return .Info } else + when LOG_LEVEL == "warning" { return .Warning } else + when LOG_LEVEL == "error" { return .Error } else + when LOG_LEVEL == "fatal" { return .Fatal } else { #panic("Unknown `ODIN_TEST_LOG_LEVEL`: \"" + LOG_LEVEL + "\", possible levels are: \"debug\", \"info\", \"warning\", \"error\", or \"fatal\".") } } From 103eccf104ca99d5a60ff0d7a141787d6bda88e0 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 29 Jun 2024 19:23:58 +0100 Subject: [PATCH 097/129] More style improvements --- core/debug/trace/trace_cpp.odin | 2 +- core/net/socket_darwin.odin | 3 +-- core/net/socket_windows.odin | 14 ++++++++------ core/os/os_freebsd.odin | 8 ++++++-- core/os/os_netbsd.odin | 8 ++++++-- core/sys/darwin/CoreFoundation/CFString.odin | 2 +- vendor/ENet/win32.odin | 4 +++- 7 files changed, 26 insertions(+), 15 deletions(-) diff --git a/core/debug/trace/trace_cpp.odin b/core/debug/trace/trace_cpp.odin index 894046c45..dc723184a 100644 --- a/core/debug/trace/trace_cpp.odin +++ b/core/debug/trace/trace_cpp.odin @@ -78,7 +78,7 @@ _Context :: struct { @(private="package") _init :: proc(ctx: ^Context) -> (ok: bool) { - defer if !ok do destroy(ctx) + defer if !ok { destroy(ctx) } ctx.impl.state = backtrace_create_state("odin-debug-trace", 1, nil, ctx) return ctx.impl.state != nil diff --git a/core/net/socket_darwin.odin b/core/net/socket_darwin.odin index 3f0e576c1..fc422b3a9 100644 --- a/core/net/socket_darwin.odin +++ b/core/net/socket_darwin.odin @@ -274,8 +274,7 @@ _set_option :: proc(s: Any_Socket, option: Socket_Option, value: any, loc := #ca .Linger, .Send_Timeout, .Receive_Timeout: - t, ok := value.(time.Duration) - if !ok do panic("set_option() value must be a time.Duration here", loc) + t := value.(time.Duration) or_else panic("set_option() value must be a time.Duration here", loc) micros := i64(time.duration_microseconds(t)) timeval_value.microseconds = int(micros % 1e6) diff --git a/core/net/socket_windows.odin b/core/net/socket_windows.odin index 3b9623749..eef0df583 100644 --- a/core/net/socket_windows.odin +++ b/core/net/socket_windows.odin @@ -263,12 +263,15 @@ _set_option :: proc(s: Any_Socket, option: Socket_Option, value: any, loc := #ca ptr = &bool_value len = size_of(bool_value) case .Linger: - t, ok := value.(time.Duration) - if !ok do panic("set_option() value must be a time.Duration here", loc) + t := value.(time.Duration) or_else panic("set_option() value must be a time.Duration here", loc) num_secs := i64(time.duration_seconds(t)) - if time.Duration(num_secs * 1e9) != t do return .Linger_Only_Supports_Whole_Seconds - if num_secs > i64(max(u16)) do return .Value_Out_Of_Range + if time.Duration(num_secs * 1e9) != t { + return .Linger_Only_Supports_Whole_Seconds + } + if num_secs > i64(max(u16)) { + return .Value_Out_Of_Range + } linger_value.l_onoff = 1 linger_value.l_linger = c.ushort(num_secs) @@ -277,8 +280,7 @@ _set_option :: proc(s: Any_Socket, option: Socket_Option, value: any, loc := #ca case .Receive_Timeout, .Send_Timeout: - t, ok := value.(time.Duration) - if !ok do panic("set_option() value must be a time.Duration here", loc) + t := value.(time.Duration) or_else panic("set_option() value must be a time.Duration here", loc) int_value = i32(time.duration_milliseconds(t)) ptr = &int_value diff --git a/core/os/os_freebsd.odin b/core/os/os_freebsd.odin index 97165b262..36ada0948 100644 --- a/core/os/os_freebsd.odin +++ b/core/os/os_freebsd.odin @@ -705,7 +705,9 @@ set_current_directory :: proc(path: string) -> (err: Errno) { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() cstr := strings.clone_to_cstring(path, context.temp_allocator) res := _unix_chdir(cstr) - if res == -1 do return Errno(get_last_error()) + if res == -1 { + return Errno(get_last_error()) + } return ERROR_NONE } @@ -743,7 +745,9 @@ get_page_size :: proc() -> int { // NOTE(tetra): The page size never changes, so why do anything complicated // if we don't have to. @static page_size := -1 - if page_size != -1 do return page_size + if page_size != -1 { + return page_size + } page_size = int(_unix_getpagesize()) return page_size diff --git a/core/os/os_netbsd.odin b/core/os/os_netbsd.odin index c8f10d1da..2bda8abf7 100644 --- a/core/os/os_netbsd.odin +++ b/core/os/os_netbsd.odin @@ -714,7 +714,9 @@ set_current_directory :: proc(path: string) -> (err: Errno) { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() cstr := strings.clone_to_cstring(path, context.temp_allocator) res := _unix_chdir(cstr) - if res == -1 do return Errno(get_last_error()) + if res == -1 { + return Errno(get_last_error()) + } return ERROR_NONE } @@ -755,7 +757,9 @@ get_page_size :: proc() -> int { // NOTE(tetra): The page size never changes, so why do anything complicated // if we don't have to. @static page_size := -1 - if page_size != -1 do return page_size + if page_size != -1 { + return page_size + } page_size = int(_unix_getpagesize()) return page_size diff --git a/core/sys/darwin/CoreFoundation/CFString.odin b/core/sys/darwin/CoreFoundation/CFString.odin index 4a167c604..6ad3c5bfc 100644 --- a/core/sys/darwin/CoreFoundation/CFString.odin +++ b/core/sys/darwin/CoreFoundation/CFString.odin @@ -192,7 +192,7 @@ StringCopyToOdinString :: proc( max := StringGetMaximumSizeForEncoding(length, StringEncoding(StringBuiltInEncodings.UTF8)) buf, err := make([]byte, max, allocator) - if err != nil do return + if err != nil { return } raw_str := runtime.Raw_String { data = raw_data(buf), diff --git a/vendor/ENet/win32.odin b/vendor/ENet/win32.odin index 1df35ee45..d05cf5d99 100644 --- a/vendor/ENet/win32.odin +++ b/vendor/ENet/win32.odin @@ -39,7 +39,9 @@ foreign WinSock2 { return } } - if s.fd_count >= FD_SETSIZE do return + if s.fd_count >= FD_SETSIZE { + return + } s.fd_array[s.fd_count] = fd s.fd_count += 1 } From 888bf28076eea73b89b3a299523e4371cdf2b6b2 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 29 Jun 2024 19:26:11 +0100 Subject: [PATCH 098/129] `-strict-style` implies `-disallow-do` --- src/main.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 611890a5c..610f214ff 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1276,6 +1276,7 @@ gb_internal bool parse_build_flags(Array args) { break; case BuildFlag_StrictStyle: build_context.strict_style = true; + build_context.disallow_do = true; break; case BuildFlag_Short: build_context.cmd_doc_flags |= CmdDocFlag_Short; @@ -2353,7 +2354,8 @@ gb_internal void print_show_help(String const arg0, String const &command) { print_usage_line(2, "Errs on missing trailing commas followed by a newline."); print_usage_line(2, "Errs on deprecated syntax."); print_usage_line(2, "Errs when 'case' labels are not in the same column as the associated 'switch' token."); - print_usage_line(2, "Errs when the attached-brace style in not adhered to (also known as 1TBS)."); + print_usage_line(2, "Errs when 'case' labels are not in the same column as the associated 'switch' token."); + print_usage_line(2, "Disallows the 'do' keyword in the project (same as '-disallow-do')."); print_usage_line(0, ""); print_usage_line(1, "-ignore-warnings"); From f64d1df90b969c0d13c8b77c9acd153b7243f3a6 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 29 Jun 2024 19:27:26 +0100 Subject: [PATCH 099/129] Add note regarding `-strict-style` --- src/main.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index 610f214ff..9b05fab2f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2350,6 +2350,8 @@ gb_internal void print_show_help(String const arg0, String const &command) { print_usage_line(0, ""); print_usage_line(1, "-strict-style"); + print_usage_line(2, "This enforces parts of same style as the Odin compiler, prefer '-vet-style -vet-semicolon' if you do not want to match it exactly."); + print_usage_line(2, ""); print_usage_line(2, "Errs on unneeded tokens, such as unneeded semicolons."); print_usage_line(2, "Errs on missing trailing commas followed by a newline."); print_usage_line(2, "Errs on deprecated syntax."); From f4abdf716eb2a5e3c9937daa4dd68d92c2f84b4b Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 29 Jun 2024 19:29:20 +0100 Subject: [PATCH 100/129] Move microarch stuff to a separate file --- src/build_settings.cpp | 463 +------------------------------ src/build_settings_microarch.cpp | 462 ++++++++++++++++++++++++++++++ 2 files changed, 463 insertions(+), 462 deletions(-) create mode 100644 src/build_settings_microarch.cpp diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 47a29a461..d79343a8b 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -106,468 +106,7 @@ gb_global String target_arch_names[TargetArch_COUNT] = { str_lit("wasm64p32"), }; -// Generated with the featuregen script in `misc/featuregen` -gb_global String target_microarch_list[TargetArch_COUNT] = { - // TargetArch_Invalid: - str_lit(""), - // TargetArch_amd64: - str_lit("alderlake,amdfam10,athlon,athlon-4,athlon-fx,athlon-mp,athlon-tbird,athlon-xp,athlon64,athlon64-sse3,atom,atom_sse4_2,atom_sse4_2_movbe,barcelona,bdver1,bdver2,bdver3,bdver4,bonnell,broadwell,btver1,btver2,c3,c3-2,cannonlake,cascadelake,cooperlake,core-avx-i,core-avx2,core2,core_2_duo_sse4_1,core_2_duo_ssse3,core_2nd_gen_avx,core_3rd_gen_avx,core_4th_gen_avx,core_4th_gen_avx_tsx,core_5th_gen_avx,core_5th_gen_avx_tsx,core_aes_pclmulqdq,core_i7_sse4_2,corei7,corei7-avx,emeraldrapids,generic,geode,goldmont,goldmont-plus,goldmont_plus,grandridge,graniterapids,graniterapids-d,graniterapids_d,haswell,i386,i486,i586,i686,icelake-client,icelake-server,icelake_client,icelake_server,ivybridge,k6,k6-2,k6-3,k8,k8-sse3,knl,knm,lakemont,meteorlake,mic_avx512,nehalem,nocona,opteron,opteron-sse3,penryn,pentium,pentium-m,pentium-mmx,pentium2,pentium3,pentium3m,pentium4,pentium4m,pentium_4,pentium_4_sse3,pentium_ii,pentium_iii,pentium_iii_no_xmm_regs,pentium_m,pentium_mmx,pentium_pro,pentiumpro,prescott,raptorlake,rocketlake,sandybridge,sapphirerapids,sierraforest,silvermont,skx,skylake,skylake-avx512,skylake_avx512,slm,tigerlake,tremont,westmere,winchip-c6,winchip2,x86-64,x86-64-v2,x86-64-v3,x86-64-v4,yonah,znver1,znver2,znver3,znver4"), - // TargetArch_i386: - str_lit("alderlake,amdfam10,athlon,athlon-4,athlon-fx,athlon-mp,athlon-tbird,athlon-xp,athlon64,athlon64-sse3,atom,atom_sse4_2,atom_sse4_2_movbe,barcelona,bdver1,bdver2,bdver3,bdver4,bonnell,broadwell,btver1,btver2,c3,c3-2,cannonlake,cascadelake,cooperlake,core-avx-i,core-avx2,core2,core_2_duo_sse4_1,core_2_duo_ssse3,core_2nd_gen_avx,core_3rd_gen_avx,core_4th_gen_avx,core_4th_gen_avx_tsx,core_5th_gen_avx,core_5th_gen_avx_tsx,core_aes_pclmulqdq,core_i7_sse4_2,corei7,corei7-avx,emeraldrapids,generic,geode,goldmont,goldmont-plus,goldmont_plus,grandridge,graniterapids,graniterapids-d,graniterapids_d,haswell,i386,i486,i586,i686,icelake-client,icelake-server,icelake_client,icelake_server,ivybridge,k6,k6-2,k6-3,k8,k8-sse3,knl,knm,lakemont,meteorlake,mic_avx512,nehalem,nocona,opteron,opteron-sse3,penryn,pentium,pentium-m,pentium-mmx,pentium2,pentium3,pentium3m,pentium4,pentium4m,pentium_4,pentium_4_sse3,pentium_ii,pentium_iii,pentium_iii_no_xmm_regs,pentium_m,pentium_mmx,pentium_pro,pentiumpro,prescott,raptorlake,rocketlake,sandybridge,sapphirerapids,sierraforest,silvermont,skx,skylake,skylake-avx512,skylake_avx512,slm,tigerlake,tremont,westmere,winchip-c6,winchip2,x86-64,x86-64-v2,x86-64-v3,x86-64-v4,yonah,znver1,znver2,znver3,znver4"), - // TargetArch_arm32: - str_lit("arm1020e,arm1020t,arm1022e,arm10e,arm10tdmi,arm1136j-s,arm1136jf-s,arm1156t2-s,arm1156t2f-s,arm1176jz-s,arm1176jzf-s,arm710t,arm720t,arm7tdmi,arm7tdmi-s,arm8,arm810,arm9,arm920,arm920t,arm922t,arm926ej-s,arm940t,arm946e-s,arm966e-s,arm968e-s,arm9e,arm9tdmi,cortex-a12,cortex-a15,cortex-a17,cortex-a32,cortex-a35,cortex-a5,cortex-a53,cortex-a55,cortex-a57,cortex-a7,cortex-a710,cortex-a72,cortex-a73,cortex-a75,cortex-a76,cortex-a76ae,cortex-a77,cortex-a78,cortex-a78c,cortex-a8,cortex-a9,cortex-m0,cortex-m0plus,cortex-m1,cortex-m23,cortex-m3,cortex-m33,cortex-m35p,cortex-m4,cortex-m55,cortex-m7,cortex-m85,cortex-r4,cortex-r4f,cortex-r5,cortex-r52,cortex-r7,cortex-r8,cortex-x1,cortex-x1c,cyclone,ep9312,exynos-m3,exynos-m4,exynos-m5,generic,iwmmxt,krait,kryo,mpcore,mpcorenovfp,neoverse-n1,neoverse-n2,neoverse-v1,sc000,sc300,strongarm,strongarm110,strongarm1100,strongarm1110,swift,xscale"), - // TargetArch_arm64: - str_lit("a64fx,ampere1,ampere1a,apple-a10,apple-a11,apple-a12,apple-a13,apple-a14,apple-a15,apple-a16,apple-a7,apple-a8,apple-a9,apple-latest,apple-m1,apple-m2,apple-s4,apple-s5,carmel,cortex-a34,cortex-a35,cortex-a510,cortex-a53,cortex-a55,cortex-a57,cortex-a65,cortex-a65ae,cortex-a710,cortex-a715,cortex-a72,cortex-a73,cortex-a75,cortex-a76,cortex-a76ae,cortex-a77,cortex-a78,cortex-a78c,cortex-r82,cortex-x1,cortex-x1c,cortex-x2,cortex-x3,cyclone,exynos-m3,exynos-m4,exynos-m5,falkor,generic,kryo,neoverse-512tvb,neoverse-e1,neoverse-n1,neoverse-n2,neoverse-v1,neoverse-v2,saphira,thunderx,thunderx2t99,thunderx3t110,thunderxt81,thunderxt83,thunderxt88,tsv110"), - // TargetArch_wasm32: - str_lit("bleeding-edge,generic,mvp"), - // TargetArch_wasm64p32: - str_lit("bleeding-edge,generic,mvp"), -}; - -// Generated with the featuregen script in `misc/featuregen` -gb_global String target_features_list[TargetArch_COUNT] = { - // TargetArch_Invalid: - str_lit(""), - // TargetArch_amd64: - str_lit("16bit-mode,32bit-mode,3dnow,3dnowa,64bit,64bit-mode,adx,aes,allow-light-256-bit,amx-bf16,amx-complex,amx-fp16,amx-int8,amx-tile,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512er,avx512f,avx512fp16,avx512ifma,avx512pf,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vp2intersect,avx512vpopcntdq,avxifma,avxneconvert,avxvnni,avxvnniint16,avxvnniint8,bmi,bmi2,branchfusion,cldemote,clflushopt,clwb,clzero,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,ermsb,f16c,false-deps-getmant,false-deps-lzcnt-tzcnt,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-popcnt,false-deps-range,fast-11bytenop,fast-15bytenop,fast-7bytenop,fast-bextr,fast-gather,fast-hops,fast-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fast-vector-shift-masks,faster-shift-than-shuffle,fma,fma4,fsgsbase,fsrm,fxsr,gfni,harden-sls-ijmp,harden-sls-ret,hreset,idivl-to-divb,idivq-to-divl,invpcid,kl,lea-sp,lea-uses-ag,lvi-cfi,lvi-load-hardening,lwp,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,mwaitx,no-bypass-delay,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pad-short-functions,pclmul,pconfig,pku,popcnt,prefer-128-bit,prefer-256-bit,prefer-mask-registers,prefer-movmsk-over-vtest,prefer-no-gather,prefer-no-scatter,prefetchi,prefetchwt1,prfchw,ptwrite,raoint,rdpid,rdpru,rdrnd,rdseed,retpoline,retpoline-external-thunk,retpoline-indirect-branches,retpoline-indirect-calls,rtm,sahf,sbb-dep-breaking,serialize,seses,sgx,sha,sha512,shstk,slow-3ops-lea,slow-incdec,slow-lea,slow-pmaddwd,slow-pmulld,slow-shld,slow-two-mem-ops,slow-unaligned-mem-16,slow-unaligned-mem-32,sm3,sm4,soft-float,sse,sse-unaligned-mem,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,tagged-globals,tbm,tsxldtrk,tuning-fast-imm-vector-shift,uintr,use-glm-div-sqrt-costs,use-slm-arith-costs,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,widekl,x87,xop,xsave,xsavec,xsaveopt,xsaves"), - // TargetArch_i386: - str_lit("16bit-mode,32bit-mode,3dnow,3dnowa,64bit,64bit-mode,adx,aes,allow-light-256-bit,amx-bf16,amx-complex,amx-fp16,amx-int8,amx-tile,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512er,avx512f,avx512fp16,avx512ifma,avx512pf,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vp2intersect,avx512vpopcntdq,avxifma,avxneconvert,avxvnni,avxvnniint16,avxvnniint8,bmi,bmi2,branchfusion,cldemote,clflushopt,clwb,clzero,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,ermsb,f16c,false-deps-getmant,false-deps-lzcnt-tzcnt,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-popcnt,false-deps-range,fast-11bytenop,fast-15bytenop,fast-7bytenop,fast-bextr,fast-gather,fast-hops,fast-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fast-vector-shift-masks,faster-shift-than-shuffle,fma,fma4,fsgsbase,fsrm,fxsr,gfni,harden-sls-ijmp,harden-sls-ret,hreset,idivl-to-divb,idivq-to-divl,invpcid,kl,lea-sp,lea-uses-ag,lvi-cfi,lvi-load-hardening,lwp,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,mwaitx,no-bypass-delay,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pad-short-functions,pclmul,pconfig,pku,popcnt,prefer-128-bit,prefer-256-bit,prefer-mask-registers,prefer-movmsk-over-vtest,prefer-no-gather,prefer-no-scatter,prefetchi,prefetchwt1,prfchw,ptwrite,raoint,rdpid,rdpru,rdrnd,rdseed,retpoline,retpoline-external-thunk,retpoline-indirect-branches,retpoline-indirect-calls,rtm,sahf,sbb-dep-breaking,serialize,seses,sgx,sha,sha512,shstk,slow-3ops-lea,slow-incdec,slow-lea,slow-pmaddwd,slow-pmulld,slow-shld,slow-two-mem-ops,slow-unaligned-mem-16,slow-unaligned-mem-32,sm3,sm4,soft-float,sse,sse-unaligned-mem,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,tagged-globals,tbm,tsxldtrk,tuning-fast-imm-vector-shift,uintr,use-glm-div-sqrt-costs,use-slm-arith-costs,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,widekl,x87,xop,xsave,xsavec,xsaveopt,xsaves"), - // TargetArch_arm32: - str_lit("32bit,8msecext,a12,a15,a17,a32,a35,a5,a53,a55,a57,a7,a72,a73,a75,a76,a77,a78c,a8,a9,aapcs-frame-chain,aapcs-frame-chain-leaf,aclass,acquire-release,aes,armv4,armv4t,armv5t,armv5te,armv5tej,armv6,armv6-m,armv6j,armv6k,armv6kz,armv6s-m,armv6t2,armv7-a,armv7-m,armv7-r,armv7e-m,armv7k,armv7s,armv7ve,armv8-a,armv8-m.base,armv8-m.main,armv8-r,armv8.1-a,armv8.1-m.main,armv8.2-a,armv8.3-a,armv8.4-a,armv8.5-a,armv8.6-a,armv8.7-a,armv8.8-a,armv8.9-a,armv9-a,armv9.1-a,armv9.2-a,armv9.3-a,armv9.4-a,atomics-32,avoid-movs-shop,avoid-partial-cpsr,bf16,big-endian-instructions,cde,cdecp0,cdecp1,cdecp2,cdecp3,cdecp4,cdecp5,cdecp6,cdecp7,cheap-predicable-cpsr,clrbhb,cortex-a710,cortex-a78,cortex-x1,cortex-x1c,crc,crypto,d32,db,dfb,disable-postra-scheduler,dont-widen-vmovs,dotprod,dsp,execute-only,expand-fp-mlx,exynos,fix-cmse-cve-2021-35465,fix-cortex-a57-aes-1742098,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp16fml,fp64,fpao,fpregs,fpregs16,fpregs64,fullfp16,fuse-aes,fuse-literals,harden-sls-blr,harden-sls-nocomdat,harden-sls-retbr,hwdiv,hwdiv-arm,i8mm,iwmmxt,iwmmxt2,krait,kryo,lob,long-calls,loop-align,m3,m7,mclass,mp,muxed-units,mve,mve.fp,mve1beat,mve2beat,mve4beat,nacl-trap,neon,neon-fpmovs,neonfp,neoverse-v1,no-branch-predictor,no-bti-at-return-twice,no-movt,no-neg-immediates,noarm,nonpipelined-vfp,pacbti,perfmon,prefer-ishst,prefer-vmovsr,prof-unpr,r4,r5,r52,r7,ras,rclass,read-tp-tpidrprw,read-tp-tpidruro,read-tp-tpidrurw,reserve-r9,ret-addr-stack,sb,sha2,slow-fp-brcc,slow-load-D-subreg,slow-odd-reg,slow-vdup32,slow-vgetlni32,slowfpvfmx,slowfpvmlx,soft-float,splat-vfp-neon,strict-align,swift,thumb-mode,thumb2,trustzone,use-mipipeliner,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.1m.main,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8.7a,v8.8a,v8.9a,v8m,v8m.main,v9.1a,v9.2a,v9.3a,v9.4a,v9a,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization,vldn-align,vmlx-forwarding,vmlx-hazards,wide-stride-vfp,xscale,zcz"), - // TargetArch_arm64: - str_lit("CONTEXTIDREL2,a35,a510,a53,a55,a57,a64fx,a65,a710,a715,a72,a73,a75,a76,a77,a78,a78c,aes,aggressive-fma,all,alternate-sextload-cvt-f32-pattern,altnzcv,am,ampere1,ampere1a,amvs,apple-a10,apple-a11,apple-a12,apple-a13,apple-a14,apple-a15,apple-a16,apple-a7,apple-a7-sysreg,arith-bcc-fusion,arith-cbz-fusion,ascend-store-address,b16b16,balance-fp-ops,bf16,brbe,bti,call-saved-x10,call-saved-x11,call-saved-x12,call-saved-x13,call-saved-x14,call-saved-x15,call-saved-x18,call-saved-x8,call-saved-x9,carmel,ccdp,ccidx,ccpp,chk,clrbhb,cmp-bcc-fusion,complxnum,cortex-r82,cortex-x1,cortex-x2,cortex-x3,crc,crypto,cssc,custom-cheap-as-move,d128,disable-latency-sched-heuristic,dit,dotprod,ecv,el2vmsa,el3,enable-select-opt,ete,exynos-cheap-as-move,exynosm3,exynosm4,f32mm,f64mm,falkor,fgt,fix-cortex-a53-835769,flagm,fmv,force-32bit-jump-tables,fp-armv8,fp16fml,fptoint,fullfp16,fuse-address,fuse-addsub-2reg-const1,fuse-adrp-add,fuse-aes,fuse-arith-logic,fuse-crypto-eor,fuse-csel,fuse-literals,gcs,harden-sls-blr,harden-sls-nocomdat,harden-sls-retbr,hbc,hcx,i8mm,ite,jsconv,kryo,lor,ls64,lse,lse128,lse2,lsl-fast,mec,mops,mpam,mte,neon,neoverse512tvb,neoversee1,neoversen1,neoversen2,neoversev1,neoversev2,nmi,no-bti-at-return-twice,no-neg-immediates,no-sve-fp-ld1r,no-zcz-fp,nv,outline-atomics,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,prfm-slc-target,rand,ras,rasv2,rcpc,rcpc-immo,rcpc3,rdm,reserve-x1,reserve-x10,reserve-x11,reserve-x12,reserve-x13,reserve-x14,reserve-x15,reserve-x18,reserve-x2,reserve-x20,reserve-x21,reserve-x22,reserve-x23,reserve-x24,reserve-x25,reserve-x26,reserve-x27,reserve-x28,reserve-x3,reserve-x30,reserve-x4,reserve-x5,reserve-x6,reserve-x7,reserve-x9,rme,saphira,sb,sel2,sha2,sha3,slow-misaligned-128store,slow-paired-128,slow-strqro-store,sm4,sme,sme-f16f16,sme-f64f64,sme-i16i64,sme2,sme2p1,spe,spe-eef,specres2,specrestrict,ssbs,strict-align,sve,sve2,sve2-aes,sve2-bitperm,sve2-sha3,sve2-sm4,sve2p1,tagged-globals,the,thunderx,thunderx2t99,thunderx3t110,thunderxt81,thunderxt83,thunderxt88,tlb-rmi,tme,tpidr-el1,tpidr-el2,tpidr-el3,tpidrro-el0,tracev8.4,trbe,tsv110,uaops,use-experimental-zeroing-pseudos,use-postra-scheduler,use-reciprocal-square-root,use-scalar-inc-vl,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8.7a,v8.8a,v8.9a,v8a,v8r,v9.1a,v9.2a,v9.3a,v9.4a,v9a,vh,wfxt,xs,zcm,zcz,zcz-fp-workaround,zcz-gp"), - // TargetArch_wasm32: - str_lit("atomics,bulk-memory,exception-handling,extended-const,multivalue,mutable-globals,nontrapping-fptoint,reference-types,relaxed-simd,sign-ext,simd128,tail-call"), - // TargetArch_wasm64p32: - str_lit("atomics,bulk-memory,exception-handling,extended-const,multivalue,mutable-globals,nontrapping-fptoint,reference-types,relaxed-simd,sign-ext,simd128,tail-call"), -}; - -// Generated with the featuregen script in `misc/featuregen` -gb_global int target_microarch_counts[TargetArch_COUNT] = { - // TargetArch_Invalid: - 0, - // TargetArch_amd64: - 120, - // TargetArch_i386: - 120, - // TargetArch_arm32: - 90, - // TargetArch_arm64: - 63, - // TargetArch_wasm32: - 3, - // TargetArch_wasm64p32: - 3, -}; - -// Generated with the featuregen script in `misc/featuregen` -gb_global MicroarchFeatureList microarch_features_list[] = { - // TargetArch_amd64: - { str_lit("alderlake"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("amdfam10"), str_lit("3dnow,3dnowa,64bit,64bit-mode,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,lzcnt,mmx,nopl,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4a,vzeroupper,x87") }, - { str_lit("athlon"), str_lit("3dnow,3dnowa,64bit-mode,cmov,cx8,mmx,nopl,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("athlon-4"), str_lit("3dnow,3dnowa,64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("athlon-fx"), str_lit("3dnow,3dnowa,64bit,64bit-mode,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("athlon-mp"), str_lit("3dnow,3dnowa,64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("athlon-tbird"), str_lit("3dnow,3dnowa,64bit-mode,cmov,cx8,mmx,nopl,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("athlon-xp"), str_lit("3dnow,3dnowa,64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("athlon64"), str_lit("3dnow,3dnowa,64bit,64bit-mode,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("athlon64-sse3"), str_lit("3dnow,3dnowa,64bit,64bit-mode,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, - { str_lit("atom"), str_lit("64bit,64bit-mode,cmov,cx16,cx8,fxsr,idivl-to-divb,idivq-to-divl,lea-sp,lea-uses-ag,mmx,movbe,no-bypass-delay,nopl,pad-short-functions,sahf,slow-two-mem-ops,slow-unaligned-mem-16,sse,sse2,sse3,ssse3,vzeroupper,x87") }, - { str_lit("atom_sse4_2"), str_lit("64bit,64bit-mode,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-7bytenop,fast-movbe,fxsr,idivq-to-divl,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,rdrnd,sahf,slow-incdec,slow-lea,slow-pmulld,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-slm-arith-costs,vzeroupper,x87") }, - { str_lit("atom_sse4_2_movbe"), str_lit("64bit,64bit-mode,aes,clflushopt,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-7bytenop,fast-movbe,fsgsbase,fxsr,idivq-to-divl,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,sha,slow-incdec,slow-lea,slow-pmulld,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-slm-arith-costs,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("barcelona"), str_lit("3dnow,3dnowa,64bit,64bit-mode,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,lzcnt,mmx,nopl,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4a,vzeroupper,x87") }, - { str_lit("bdver1"), str_lit("64bit,64bit-mode,aes,avx,branchfusion,cmov,crc32,cx16,cx8,fast-11bytenop,fast-scalar-shift-masks,fma4,fxsr,lwp,lzcnt,mmx,nopl,pclmul,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,vzeroupper,x87,xop,xsave") }, - { str_lit("bdver2"), str_lit("64bit,64bit-mode,aes,avx,bmi,branchfusion,cmov,crc32,cx16,cx8,f16c,fast-11bytenop,fast-bextr,fast-movbe,fast-scalar-shift-masks,fma,fma4,fxsr,lwp,lzcnt,mmx,nopl,pclmul,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,tbm,vzeroupper,x87,xop,xsave") }, - { str_lit("bdver3"), str_lit("64bit,64bit-mode,aes,avx,bmi,branchfusion,cmov,crc32,cx16,cx8,f16c,fast-11bytenop,fast-bextr,fast-movbe,fast-scalar-shift-masks,fma,fma4,fsgsbase,fxsr,lwp,lzcnt,mmx,nopl,pclmul,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,tbm,vzeroupper,x87,xop,xsave,xsaveopt") }, - { str_lit("bdver4"), str_lit("64bit,64bit-mode,aes,avx,avx2,bmi,bmi2,branchfusion,cmov,crc32,cx16,cx8,f16c,fast-11bytenop,fast-bextr,fast-movbe,fast-scalar-shift-masks,fma,fma4,fsgsbase,fxsr,lwp,lzcnt,mmx,movbe,mwaitx,nopl,pclmul,popcnt,prfchw,rdrnd,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,tbm,vzeroupper,x87,xop,xsave,xsaveopt") }, - { str_lit("bonnell"), str_lit("64bit,64bit-mode,cmov,cx16,cx8,fxsr,idivl-to-divb,idivq-to-divl,lea-sp,lea-uses-ag,mmx,movbe,no-bypass-delay,nopl,pad-short-functions,sahf,slow-two-mem-ops,slow-unaligned-mem-16,sse,sse2,sse3,ssse3,vzeroupper,x87") }, - { str_lit("broadwell"), str_lit("64bit,64bit-mode,adx,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, - { str_lit("btver1"), str_lit("64bit,64bit-mode,cmov,cx16,cx8,fast-15bytenop,fast-scalar-shift-masks,fast-vector-shift-masks,fxsr,lzcnt,mmx,nopl,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4a,ssse3,vzeroupper,x87") }, - { str_lit("btver2"), str_lit("64bit,64bit-mode,aes,avx,bmi,cmov,crc32,cx16,cx8,f16c,fast-15bytenop,fast-bextr,fast-hops,fast-lzcnt,fast-movbe,fast-scalar-shift-masks,fast-vector-shift-masks,fxsr,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,x87,xsave,xsaveopt") }, - { str_lit("c3"), str_lit("3dnow,64bit-mode,mmx,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("c3-2"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("cannonlake"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vl,bmi,bmi2,clflushopt,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,sha,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("cascadelake"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bw,avx512cd,avx512dq,avx512f,avx512vl,avx512vnni,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,faster-shift-than-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("cooperlake"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bf16,avx512bw,avx512cd,avx512dq,avx512f,avx512vl,avx512vnni,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,faster-shift-than-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("core-avx-i"), str_lit("64bit,64bit-mode,avx,cmov,crc32,cx16,cx8,f16c,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fsgsbase,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, - { str_lit("core-avx2"), str_lit("64bit,64bit-mode,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, - { str_lit("core2"), str_lit("64bit,64bit-mode,cmov,cx16,cx8,fxsr,macrofusion,mmx,nopl,sahf,slow-unaligned-mem-16,sse,sse2,sse3,ssse3,vzeroupper,x87") }, - { str_lit("core_2_duo_sse4_1"), str_lit("64bit,64bit-mode,cmov,cx16,cx8,fxsr,macrofusion,mmx,nopl,sahf,slow-unaligned-mem-16,sse,sse2,sse3,sse4.1,ssse3,vzeroupper,x87") }, - { str_lit("core_2_duo_ssse3"), str_lit("64bit,64bit-mode,cmov,cx16,cx8,fxsr,macrofusion,mmx,nopl,sahf,slow-unaligned-mem-16,sse,sse2,sse3,ssse3,vzeroupper,x87") }, - { str_lit("core_2nd_gen_avx"), str_lit("64bit,64bit-mode,avx,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, - { str_lit("core_3rd_gen_avx"), str_lit("64bit,64bit-mode,avx,cmov,crc32,cx16,cx8,f16c,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fsgsbase,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, - { str_lit("core_4th_gen_avx"), str_lit("64bit,64bit-mode,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, - { str_lit("core_4th_gen_avx_tsx"), str_lit("64bit,64bit-mode,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, - { str_lit("core_5th_gen_avx"), str_lit("64bit,64bit-mode,adx,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, - { str_lit("core_5th_gen_avx_tsx"), str_lit("64bit,64bit-mode,adx,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, - { str_lit("core_aes_pclmulqdq"), str_lit("64bit,64bit-mode,cmov,crc32,cx16,cx8,fxsr,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,sahf,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87") }, - { str_lit("core_i7_sse4_2"), str_lit("64bit,64bit-mode,cmov,crc32,cx16,cx8,fxsr,macrofusion,mmx,no-bypass-delay-mov,nopl,popcnt,sahf,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87") }, - { str_lit("corei7"), str_lit("64bit,64bit-mode,cmov,crc32,cx16,cx8,fxsr,macrofusion,mmx,no-bypass-delay-mov,nopl,popcnt,sahf,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87") }, - { str_lit("corei7-avx"), str_lit("64bit,64bit-mode,avx,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, - { str_lit("emeraldrapids"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,amx-bf16,amx-int8,amx-tile,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512fp16,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,enqcmd,ermsb,evex512,f16c,false-deps-getmant,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-range,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tsxldtrk,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("generic"), str_lit("64bit,64bit-mode,cx8,fast-15bytenop,fast-scalar-fsqrt,idivq-to-divl,macrofusion,slow-3ops-lea,sse,sse2,vzeroupper,x87") }, - { str_lit("geode"), str_lit("3dnow,3dnowa,64bit-mode,cx8,mmx,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("goldmont"), str_lit("64bit,64bit-mode,aes,clflushopt,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-movbe,fsgsbase,fxsr,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,sha,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-glm-div-sqrt-costs,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("goldmont-plus"), str_lit("64bit,64bit-mode,aes,clflushopt,cmov,crc32,cx16,cx8,fast-movbe,fsgsbase,fxsr,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,sha,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-glm-div-sqrt-costs,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("goldmont_plus"), str_lit("64bit,64bit-mode,aes,clflushopt,cmov,crc32,cx16,cx8,fast-movbe,fsgsbase,fxsr,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,sha,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-glm-div-sqrt-costs,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("grandridge"), str_lit("64bit,64bit-mode,adx,aes,avx,avx2,avxifma,avxneconvert,avxvnni,avxvnniint8,bmi,bmi2,cldemote,clflushopt,clwb,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,f16c,fast-movbe,fma,fsgsbase,fxsr,gfni,hreset,invpcid,kl,lzcnt,mmx,movbe,movdir64b,movdiri,no-bypass-delay,nopl,pclmul,pconfig,pku,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,uintr,use-glm-div-sqrt-costs,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("graniterapids"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,amx-bf16,amx-fp16,amx-int8,amx-tile,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512fp16,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,enqcmd,ermsb,evex512,f16c,false-deps-getmant,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-range,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prefetchi,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tsxldtrk,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("graniterapids-d"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,amx-bf16,amx-complex,amx-fp16,amx-int8,amx-tile,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512fp16,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,enqcmd,ermsb,evex512,f16c,false-deps-getmant,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-range,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prefetchi,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tsxldtrk,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("graniterapids_d"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,amx-bf16,amx-complex,amx-fp16,amx-int8,amx-tile,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512fp16,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,enqcmd,ermsb,evex512,f16c,false-deps-getmant,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-range,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prefetchi,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tsxldtrk,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("haswell"), str_lit("64bit,64bit-mode,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, - { str_lit("i386"), str_lit("64bit-mode,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("i486"), str_lit("64bit-mode,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("i586"), str_lit("64bit-mode,cx8,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("i686"), str_lit("64bit-mode,cmov,cx8,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("icelake-client"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,bmi,bmi2,clflushopt,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdpid,rdrnd,rdseed,sahf,sha,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("icelake-server"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prfchw,rdpid,rdrnd,rdseed,sahf,sha,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("icelake_client"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,bmi,bmi2,clflushopt,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdpid,rdrnd,rdseed,sahf,sha,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("icelake_server"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prfchw,rdpid,rdrnd,rdseed,sahf,sha,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("ivybridge"), str_lit("64bit,64bit-mode,avx,cmov,crc32,cx16,cx8,f16c,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fsgsbase,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, - { str_lit("k6"), str_lit("64bit-mode,cx8,mmx,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("k6-2"), str_lit("3dnow,64bit-mode,cx8,mmx,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("k6-3"), str_lit("3dnow,64bit-mode,cx8,mmx,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("k8"), str_lit("3dnow,3dnowa,64bit,64bit-mode,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("k8-sse3"), str_lit("3dnow,3dnowa,64bit,64bit-mode,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, - { str_lit("knl"), str_lit("64bit,64bit-mode,adx,aes,avx,avx2,avx512cd,avx512er,avx512f,avx512pf,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,fast-gather,fast-movbe,fma,fsgsbase,fxsr,idivq-to-divl,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prefer-mask-registers,prefetchwt1,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,slow-incdec,slow-pmaddwd,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,x87,xsave,xsaveopt") }, - { str_lit("knm"), str_lit("64bit,64bit-mode,adx,aes,avx,avx2,avx512cd,avx512er,avx512f,avx512pf,avx512vpopcntdq,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,fast-gather,fast-movbe,fma,fsgsbase,fxsr,idivq-to-divl,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prefer-mask-registers,prefetchwt1,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,slow-incdec,slow-pmaddwd,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,x87,xsave,xsaveopt") }, - { str_lit("lakemont"), str_lit("64bit-mode,cx8,slow-unaligned-mem-16,sse,sse2,vzeroupper") }, - { str_lit("meteorlake"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("mic_avx512"), str_lit("64bit,64bit-mode,adx,aes,avx,avx2,avx512cd,avx512er,avx512f,avx512pf,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,fast-gather,fast-movbe,fma,fsgsbase,fxsr,idivq-to-divl,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prefer-mask-registers,prefetchwt1,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,slow-incdec,slow-pmaddwd,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,x87,xsave,xsaveopt") }, - { str_lit("nehalem"), str_lit("64bit,64bit-mode,cmov,crc32,cx16,cx8,fxsr,macrofusion,mmx,no-bypass-delay-mov,nopl,popcnt,sahf,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87") }, - { str_lit("nocona"), str_lit("64bit,64bit-mode,cmov,cx16,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, - { str_lit("opteron"), str_lit("3dnow,3dnowa,64bit,64bit-mode,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("opteron-sse3"), str_lit("3dnow,3dnowa,64bit,64bit-mode,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, - { str_lit("penryn"), str_lit("64bit,64bit-mode,cmov,cx16,cx8,fxsr,macrofusion,mmx,nopl,sahf,slow-unaligned-mem-16,sse,sse2,sse3,sse4.1,ssse3,vzeroupper,x87") }, - { str_lit("pentium"), str_lit("64bit-mode,cx8,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("pentium-m"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("pentium-mmx"), str_lit("64bit-mode,cx8,mmx,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("pentium2"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("pentium3"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("pentium3m"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("pentium4"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("pentium4m"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("pentium_4"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("pentium_4_sse3"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, - { str_lit("pentium_ii"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("pentium_iii"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("pentium_iii_no_xmm_regs"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("pentium_m"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("pentium_mmx"), str_lit("64bit-mode,cx8,mmx,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("pentium_pro"), str_lit("64bit-mode,cmov,cx8,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("pentiumpro"), str_lit("64bit-mode,cmov,cx8,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("prescott"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, - { str_lit("raptorlake"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("rocketlake"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,bmi,bmi2,clflushopt,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdpid,rdrnd,rdseed,sahf,sha,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("sandybridge"), str_lit("64bit,64bit-mode,avx,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, - { str_lit("sapphirerapids"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,amx-bf16,amx-int8,amx-tile,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512fp16,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,enqcmd,ermsb,evex512,f16c,false-deps-getmant,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-range,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tsxldtrk,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("sierraforest"), str_lit("64bit,64bit-mode,adx,aes,avx,avx2,avxifma,avxneconvert,avxvnni,avxvnniint8,bmi,bmi2,cldemote,clflushopt,clwb,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,f16c,fast-movbe,fma,fsgsbase,fxsr,gfni,hreset,invpcid,kl,lzcnt,mmx,movbe,movdir64b,movdiri,no-bypass-delay,nopl,pclmul,pconfig,pku,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,uintr,use-glm-div-sqrt-costs,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("silvermont"), str_lit("64bit,64bit-mode,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-7bytenop,fast-movbe,fxsr,idivq-to-divl,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,rdrnd,sahf,slow-incdec,slow-lea,slow-pmulld,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-slm-arith-costs,vzeroupper,x87") }, - { str_lit("skx"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bw,avx512cd,avx512dq,avx512f,avx512vl,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,faster-shift-than-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("skylake"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,bmi,bmi2,clflushopt,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("skylake-avx512"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bw,avx512cd,avx512dq,avx512f,avx512vl,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,faster-shift-than-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("skylake_avx512"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bw,avx512cd,avx512dq,avx512f,avx512vl,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,faster-shift-than-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("slm"), str_lit("64bit,64bit-mode,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-7bytenop,fast-movbe,fxsr,idivq-to-divl,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,rdrnd,sahf,slow-incdec,slow-lea,slow-pmulld,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-slm-arith-costs,vzeroupper,x87") }, - { str_lit("tigerlake"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vp2intersect,avx512vpopcntdq,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdpid,rdrnd,rdseed,sahf,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("tremont"), str_lit("64bit,64bit-mode,aes,clflushopt,clwb,cmov,crc32,cx16,cx8,fast-movbe,fsgsbase,fxsr,gfni,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,sha,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-glm-div-sqrt-costs,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("westmere"), str_lit("64bit,64bit-mode,cmov,crc32,cx16,cx8,fxsr,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,sahf,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87") }, - { str_lit("winchip-c6"), str_lit("64bit-mode,mmx,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("winchip2"), str_lit("3dnow,64bit-mode,mmx,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("x86-64"), str_lit("64bit,64bit-mode,cmov,cx8,fxsr,idivq-to-divl,macrofusion,mmx,nopl,slow-3ops-lea,slow-incdec,sse,sse2,vzeroupper,x87") }, - { str_lit("x86-64-v2"), str_lit("64bit,64bit-mode,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fxsr,idivq-to-divl,macrofusion,mmx,nopl,popcnt,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87") }, - { str_lit("x86-64-v3"), str_lit("64bit,64bit-mode,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fxsr,idivq-to-divl,lzcnt,macrofusion,mmx,movbe,nopl,popcnt,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave") }, - { str_lit("x86-64-v4"), str_lit("64bit,64bit-mode,allow-light-256-bit,avx,avx2,avx512bw,avx512cd,avx512dq,avx512f,avx512vl,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fxsr,idivq-to-divl,lzcnt,macrofusion,mmx,movbe,nopl,popcnt,prefer-256-bit,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave") }, - { str_lit("yonah"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, - { str_lit("znver1"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,bmi,bmi2,branchfusion,clflushopt,clzero,cmov,crc32,cx16,cx8,f16c,fast-15bytenop,fast-bextr,fast-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,lzcnt,mmx,movbe,mwaitx,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,sbb-dep-breaking,sha,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("znver2"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,bmi,bmi2,branchfusion,clflushopt,clwb,clzero,cmov,crc32,cx16,cx8,f16c,fast-15bytenop,fast-bextr,fast-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,lzcnt,mmx,movbe,mwaitx,nopl,pclmul,popcnt,prfchw,rdpid,rdpru,rdrnd,rdseed,sahf,sbb-dep-breaking,sha,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,vzeroupper,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("znver3"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,bmi,bmi2,branchfusion,clflushopt,clwb,clzero,cmov,crc32,cx16,cx8,f16c,fast-15bytenop,fast-bextr,fast-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,invpcid,lzcnt,macrofusion,mmx,movbe,mwaitx,nopl,pclmul,pku,popcnt,prfchw,rdpid,rdpru,rdrnd,rdseed,sahf,sbb-dep-breaking,sha,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,vaes,vpclmulqdq,vzeroupper,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("znver4"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,bmi,bmi2,branchfusion,clflushopt,clwb,clzero,cmov,crc32,cx16,cx8,evex512,f16c,fast-15bytenop,fast-bextr,fast-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,invpcid,lzcnt,macrofusion,mmx,movbe,mwaitx,nopl,pclmul,pku,popcnt,prfchw,rdpid,rdpru,rdrnd,rdseed,sahf,sbb-dep-breaking,sha,shstk,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,vaes,vpclmulqdq,vzeroupper,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, - // TargetArch_i386: - { str_lit("alderlake"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("amdfam10"), str_lit("32bit-mode,3dnow,3dnowa,64bit,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,lzcnt,mmx,nopl,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4a,vzeroupper,x87") }, - { str_lit("athlon"), str_lit("32bit-mode,3dnow,3dnowa,cmov,cx8,mmx,nopl,slow-shld,slow-unaligned-mem-16,vzeroupper,x87") }, - { str_lit("athlon-4"), str_lit("32bit-mode,3dnow,3dnowa,cmov,cx8,fxsr,mmx,nopl,slow-shld,slow-unaligned-mem-16,sse,vzeroupper,x87") }, - { str_lit("athlon-fx"), str_lit("32bit-mode,3dnow,3dnowa,64bit,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("athlon-mp"), str_lit("32bit-mode,3dnow,3dnowa,cmov,cx8,fxsr,mmx,nopl,slow-shld,slow-unaligned-mem-16,sse,vzeroupper,x87") }, - { str_lit("athlon-tbird"), str_lit("32bit-mode,3dnow,3dnowa,cmov,cx8,mmx,nopl,slow-shld,slow-unaligned-mem-16,vzeroupper,x87") }, - { str_lit("athlon-xp"), str_lit("32bit-mode,3dnow,3dnowa,cmov,cx8,fxsr,mmx,nopl,slow-shld,slow-unaligned-mem-16,sse,vzeroupper,x87") }, - { str_lit("athlon64"), str_lit("32bit-mode,3dnow,3dnowa,64bit,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("athlon64-sse3"), str_lit("32bit-mode,3dnow,3dnowa,64bit,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, - { str_lit("atom"), str_lit("32bit-mode,64bit,cmov,cx16,cx8,fxsr,idivl-to-divb,idivq-to-divl,lea-sp,lea-uses-ag,mmx,movbe,no-bypass-delay,nopl,pad-short-functions,sahf,slow-two-mem-ops,slow-unaligned-mem-16,sse,sse2,sse3,ssse3,vzeroupper,x87") }, - { str_lit("atom_sse4_2"), str_lit("32bit-mode,64bit,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-7bytenop,fast-movbe,fxsr,idivq-to-divl,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,rdrnd,sahf,slow-incdec,slow-lea,slow-pmulld,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-slm-arith-costs,vzeroupper,x87") }, - { str_lit("atom_sse4_2_movbe"), str_lit("32bit-mode,64bit,aes,clflushopt,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-7bytenop,fast-movbe,fsgsbase,fxsr,idivq-to-divl,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,sha,slow-incdec,slow-lea,slow-pmulld,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-slm-arith-costs,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("barcelona"), str_lit("32bit-mode,3dnow,3dnowa,64bit,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,lzcnt,mmx,nopl,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4a,vzeroupper,x87") }, - { str_lit("bdver1"), str_lit("32bit-mode,64bit,aes,avx,branchfusion,cmov,crc32,cx16,cx8,fast-11bytenop,fast-scalar-shift-masks,fma4,fxsr,lwp,lzcnt,mmx,nopl,pclmul,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,vzeroupper,x87,xop,xsave") }, - { str_lit("bdver2"), str_lit("32bit-mode,64bit,aes,avx,bmi,branchfusion,cmov,crc32,cx16,cx8,f16c,fast-11bytenop,fast-bextr,fast-movbe,fast-scalar-shift-masks,fma,fma4,fxsr,lwp,lzcnt,mmx,nopl,pclmul,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,tbm,vzeroupper,x87,xop,xsave") }, - { str_lit("bdver3"), str_lit("32bit-mode,64bit,aes,avx,bmi,branchfusion,cmov,crc32,cx16,cx8,f16c,fast-11bytenop,fast-bextr,fast-movbe,fast-scalar-shift-masks,fma,fma4,fsgsbase,fxsr,lwp,lzcnt,mmx,nopl,pclmul,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,tbm,vzeroupper,x87,xop,xsave,xsaveopt") }, - { str_lit("bdver4"), str_lit("32bit-mode,64bit,aes,avx,avx2,bmi,bmi2,branchfusion,cmov,crc32,cx16,cx8,f16c,fast-11bytenop,fast-bextr,fast-movbe,fast-scalar-shift-masks,fma,fma4,fsgsbase,fxsr,lwp,lzcnt,mmx,movbe,mwaitx,nopl,pclmul,popcnt,prfchw,rdrnd,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,tbm,vzeroupper,x87,xop,xsave,xsaveopt") }, - { str_lit("bonnell"), str_lit("32bit-mode,64bit,cmov,cx16,cx8,fxsr,idivl-to-divb,idivq-to-divl,lea-sp,lea-uses-ag,mmx,movbe,no-bypass-delay,nopl,pad-short-functions,sahf,slow-two-mem-ops,slow-unaligned-mem-16,sse,sse2,sse3,ssse3,vzeroupper,x87") }, - { str_lit("broadwell"), str_lit("32bit-mode,64bit,adx,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, - { str_lit("btver1"), str_lit("32bit-mode,64bit,cmov,cx16,cx8,fast-15bytenop,fast-scalar-shift-masks,fast-vector-shift-masks,fxsr,lzcnt,mmx,nopl,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4a,ssse3,vzeroupper,x87") }, - { str_lit("btver2"), str_lit("32bit-mode,64bit,aes,avx,bmi,cmov,crc32,cx16,cx8,f16c,fast-15bytenop,fast-bextr,fast-hops,fast-lzcnt,fast-movbe,fast-scalar-shift-masks,fast-vector-shift-masks,fxsr,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,x87,xsave,xsaveopt") }, - { str_lit("c3"), str_lit("32bit-mode,3dnow,mmx,slow-unaligned-mem-16,vzeroupper,x87") }, - { str_lit("c3-2"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,slow-unaligned-mem-16,sse,vzeroupper,x87") }, - { str_lit("cannonlake"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vl,bmi,bmi2,clflushopt,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,sha,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("cascadelake"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bw,avx512cd,avx512dq,avx512f,avx512vl,avx512vnni,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,faster-shift-than-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("cooperlake"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bf16,avx512bw,avx512cd,avx512dq,avx512f,avx512vl,avx512vnni,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,faster-shift-than-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("core-avx-i"), str_lit("32bit-mode,64bit,avx,cmov,crc32,cx16,cx8,f16c,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fsgsbase,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, - { str_lit("core-avx2"), str_lit("32bit-mode,64bit,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, - { str_lit("core2"), str_lit("32bit-mode,64bit,cmov,cx16,cx8,fxsr,macrofusion,mmx,nopl,sahf,slow-unaligned-mem-16,sse,sse2,sse3,ssse3,vzeroupper,x87") }, - { str_lit("core_2_duo_sse4_1"), str_lit("32bit-mode,64bit,cmov,cx16,cx8,fxsr,macrofusion,mmx,nopl,sahf,slow-unaligned-mem-16,sse,sse2,sse3,sse4.1,ssse3,vzeroupper,x87") }, - { str_lit("core_2_duo_ssse3"), str_lit("32bit-mode,64bit,cmov,cx16,cx8,fxsr,macrofusion,mmx,nopl,sahf,slow-unaligned-mem-16,sse,sse2,sse3,ssse3,vzeroupper,x87") }, - { str_lit("core_2nd_gen_avx"), str_lit("32bit-mode,64bit,avx,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, - { str_lit("core_3rd_gen_avx"), str_lit("32bit-mode,64bit,avx,cmov,crc32,cx16,cx8,f16c,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fsgsbase,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, - { str_lit("core_4th_gen_avx"), str_lit("32bit-mode,64bit,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, - { str_lit("core_4th_gen_avx_tsx"), str_lit("32bit-mode,64bit,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, - { str_lit("core_5th_gen_avx"), str_lit("32bit-mode,64bit,adx,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, - { str_lit("core_5th_gen_avx_tsx"), str_lit("32bit-mode,64bit,adx,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, - { str_lit("core_aes_pclmulqdq"), str_lit("32bit-mode,64bit,cmov,crc32,cx16,cx8,fxsr,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,sahf,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87") }, - { str_lit("core_i7_sse4_2"), str_lit("32bit-mode,64bit,cmov,crc32,cx16,cx8,fxsr,macrofusion,mmx,no-bypass-delay-mov,nopl,popcnt,sahf,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87") }, - { str_lit("corei7"), str_lit("32bit-mode,64bit,cmov,crc32,cx16,cx8,fxsr,macrofusion,mmx,no-bypass-delay-mov,nopl,popcnt,sahf,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87") }, - { str_lit("corei7-avx"), str_lit("32bit-mode,64bit,avx,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, - { str_lit("emeraldrapids"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,amx-bf16,amx-int8,amx-tile,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512fp16,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,enqcmd,ermsb,evex512,f16c,false-deps-getmant,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-range,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tsxldtrk,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("generic"), str_lit("32bit-mode,64bit,cx8,fast-15bytenop,fast-scalar-fsqrt,idivq-to-divl,macrofusion,slow-3ops-lea,vzeroupper,x87") }, - { str_lit("geode"), str_lit("32bit-mode,3dnow,3dnowa,cx8,mmx,slow-unaligned-mem-16,vzeroupper,x87") }, - { str_lit("goldmont"), str_lit("32bit-mode,64bit,aes,clflushopt,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-movbe,fsgsbase,fxsr,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,sha,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-glm-div-sqrt-costs,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("goldmont-plus"), str_lit("32bit-mode,64bit,aes,clflushopt,cmov,crc32,cx16,cx8,fast-movbe,fsgsbase,fxsr,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,sha,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-glm-div-sqrt-costs,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("goldmont_plus"), str_lit("32bit-mode,64bit,aes,clflushopt,cmov,crc32,cx16,cx8,fast-movbe,fsgsbase,fxsr,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,sha,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-glm-div-sqrt-costs,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("grandridge"), str_lit("32bit-mode,64bit,adx,aes,avx,avx2,avxifma,avxneconvert,avxvnni,avxvnniint8,bmi,bmi2,cldemote,clflushopt,clwb,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,f16c,fast-movbe,fma,fsgsbase,fxsr,gfni,hreset,invpcid,kl,lzcnt,mmx,movbe,movdir64b,movdiri,no-bypass-delay,nopl,pclmul,pconfig,pku,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,uintr,use-glm-div-sqrt-costs,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("graniterapids"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,amx-bf16,amx-fp16,amx-int8,amx-tile,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512fp16,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,enqcmd,ermsb,evex512,f16c,false-deps-getmant,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-range,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prefetchi,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tsxldtrk,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("graniterapids-d"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,amx-bf16,amx-complex,amx-fp16,amx-int8,amx-tile,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512fp16,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,enqcmd,ermsb,evex512,f16c,false-deps-getmant,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-range,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prefetchi,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tsxldtrk,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("graniterapids_d"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,amx-bf16,amx-complex,amx-fp16,amx-int8,amx-tile,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512fp16,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,enqcmd,ermsb,evex512,f16c,false-deps-getmant,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-range,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prefetchi,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tsxldtrk,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("haswell"), str_lit("32bit-mode,64bit,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, - { str_lit("i386"), str_lit("32bit-mode,slow-unaligned-mem-16,vzeroupper,x87") }, - { str_lit("i486"), str_lit("32bit-mode,slow-unaligned-mem-16,vzeroupper,x87") }, - { str_lit("i586"), str_lit("32bit-mode,cx8,slow-unaligned-mem-16,vzeroupper,x87") }, - { str_lit("i686"), str_lit("32bit-mode,cmov,cx8,slow-unaligned-mem-16,vzeroupper,x87") }, - { str_lit("icelake-client"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,bmi,bmi2,clflushopt,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdpid,rdrnd,rdseed,sahf,sha,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("icelake-server"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prfchw,rdpid,rdrnd,rdseed,sahf,sha,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("icelake_client"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,bmi,bmi2,clflushopt,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdpid,rdrnd,rdseed,sahf,sha,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("icelake_server"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prfchw,rdpid,rdrnd,rdseed,sahf,sha,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("ivybridge"), str_lit("32bit-mode,64bit,avx,cmov,crc32,cx16,cx8,f16c,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fsgsbase,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, - { str_lit("k6"), str_lit("32bit-mode,cx8,mmx,slow-unaligned-mem-16,vzeroupper,x87") }, - { str_lit("k6-2"), str_lit("32bit-mode,3dnow,cx8,mmx,slow-unaligned-mem-16,vzeroupper,x87") }, - { str_lit("k6-3"), str_lit("32bit-mode,3dnow,cx8,mmx,slow-unaligned-mem-16,vzeroupper,x87") }, - { str_lit("k8"), str_lit("32bit-mode,3dnow,3dnowa,64bit,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("k8-sse3"), str_lit("32bit-mode,3dnow,3dnowa,64bit,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, - { str_lit("knl"), str_lit("32bit-mode,64bit,adx,aes,avx,avx2,avx512cd,avx512er,avx512f,avx512pf,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,fast-gather,fast-movbe,fma,fsgsbase,fxsr,idivq-to-divl,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prefer-mask-registers,prefetchwt1,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,slow-incdec,slow-pmaddwd,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,x87,xsave,xsaveopt") }, - { str_lit("knm"), str_lit("32bit-mode,64bit,adx,aes,avx,avx2,avx512cd,avx512er,avx512f,avx512pf,avx512vpopcntdq,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,fast-gather,fast-movbe,fma,fsgsbase,fxsr,idivq-to-divl,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prefer-mask-registers,prefetchwt1,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,slow-incdec,slow-pmaddwd,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,x87,xsave,xsaveopt") }, - { str_lit("lakemont"), str_lit("32bit-mode,cx8,slow-unaligned-mem-16,vzeroupper") }, - { str_lit("meteorlake"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("mic_avx512"), str_lit("32bit-mode,64bit,adx,aes,avx,avx2,avx512cd,avx512er,avx512f,avx512pf,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,fast-gather,fast-movbe,fma,fsgsbase,fxsr,idivq-to-divl,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prefer-mask-registers,prefetchwt1,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,slow-incdec,slow-pmaddwd,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,x87,xsave,xsaveopt") }, - { str_lit("nehalem"), str_lit("32bit-mode,64bit,cmov,crc32,cx16,cx8,fxsr,macrofusion,mmx,no-bypass-delay-mov,nopl,popcnt,sahf,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87") }, - { str_lit("nocona"), str_lit("32bit-mode,64bit,cmov,cx16,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, - { str_lit("opteron"), str_lit("32bit-mode,3dnow,3dnowa,64bit,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("opteron-sse3"), str_lit("32bit-mode,3dnow,3dnowa,64bit,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, - { str_lit("penryn"), str_lit("32bit-mode,64bit,cmov,cx16,cx8,fxsr,macrofusion,mmx,nopl,sahf,slow-unaligned-mem-16,sse,sse2,sse3,sse4.1,ssse3,vzeroupper,x87") }, - { str_lit("pentium"), str_lit("32bit-mode,cx8,slow-unaligned-mem-16,vzeroupper,x87") }, - { str_lit("pentium-m"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("pentium-mmx"), str_lit("32bit-mode,cx8,mmx,slow-unaligned-mem-16,vzeroupper,x87") }, - { str_lit("pentium2"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,vzeroupper,x87") }, - { str_lit("pentium3"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,vzeroupper,x87") }, - { str_lit("pentium3m"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,vzeroupper,x87") }, - { str_lit("pentium4"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("pentium4m"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("pentium_4"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("pentium_4_sse3"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, - { str_lit("pentium_ii"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,vzeroupper,x87") }, - { str_lit("pentium_iii"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,vzeroupper,x87") }, - { str_lit("pentium_iii_no_xmm_regs"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,vzeroupper,x87") }, - { str_lit("pentium_m"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("pentium_mmx"), str_lit("32bit-mode,cx8,mmx,slow-unaligned-mem-16,vzeroupper,x87") }, - { str_lit("pentium_pro"), str_lit("32bit-mode,cmov,cx8,nopl,slow-unaligned-mem-16,vzeroupper,x87") }, - { str_lit("pentiumpro"), str_lit("32bit-mode,cmov,cx8,nopl,slow-unaligned-mem-16,vzeroupper,x87") }, - { str_lit("prescott"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, - { str_lit("raptorlake"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("rocketlake"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,bmi,bmi2,clflushopt,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdpid,rdrnd,rdseed,sahf,sha,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("sandybridge"), str_lit("32bit-mode,64bit,avx,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, - { str_lit("sapphirerapids"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,amx-bf16,amx-int8,amx-tile,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512fp16,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,enqcmd,ermsb,evex512,f16c,false-deps-getmant,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-range,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tsxldtrk,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("sierraforest"), str_lit("32bit-mode,64bit,adx,aes,avx,avx2,avxifma,avxneconvert,avxvnni,avxvnniint8,bmi,bmi2,cldemote,clflushopt,clwb,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,f16c,fast-movbe,fma,fsgsbase,fxsr,gfni,hreset,invpcid,kl,lzcnt,mmx,movbe,movdir64b,movdiri,no-bypass-delay,nopl,pclmul,pconfig,pku,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,uintr,use-glm-div-sqrt-costs,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("silvermont"), str_lit("32bit-mode,64bit,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-7bytenop,fast-movbe,fxsr,idivq-to-divl,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,rdrnd,sahf,slow-incdec,slow-lea,slow-pmulld,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-slm-arith-costs,vzeroupper,x87") }, - { str_lit("skx"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bw,avx512cd,avx512dq,avx512f,avx512vl,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,faster-shift-than-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("skylake"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,bmi,bmi2,clflushopt,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("skylake-avx512"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bw,avx512cd,avx512dq,avx512f,avx512vl,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,faster-shift-than-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("skylake_avx512"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bw,avx512cd,avx512dq,avx512f,avx512vl,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,faster-shift-than-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("slm"), str_lit("32bit-mode,64bit,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-7bytenop,fast-movbe,fxsr,idivq-to-divl,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,rdrnd,sahf,slow-incdec,slow-lea,slow-pmulld,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-slm-arith-costs,vzeroupper,x87") }, - { str_lit("tigerlake"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vp2intersect,avx512vpopcntdq,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdpid,rdrnd,rdseed,sahf,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("tremont"), str_lit("32bit-mode,64bit,aes,clflushopt,clwb,cmov,crc32,cx16,cx8,fast-movbe,fsgsbase,fxsr,gfni,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,sha,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-glm-div-sqrt-costs,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("westmere"), str_lit("32bit-mode,64bit,cmov,crc32,cx16,cx8,fxsr,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,sahf,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87") }, - { str_lit("winchip-c6"), str_lit("32bit-mode,mmx,slow-unaligned-mem-16,vzeroupper,x87") }, - { str_lit("winchip2"), str_lit("32bit-mode,3dnow,mmx,slow-unaligned-mem-16,vzeroupper,x87") }, - { str_lit("x86-64"), str_lit("32bit-mode,64bit,cmov,cx8,fxsr,idivq-to-divl,macrofusion,mmx,nopl,slow-3ops-lea,slow-incdec,sse,sse2,vzeroupper,x87") }, - { str_lit("x86-64-v2"), str_lit("32bit-mode,64bit,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fxsr,idivq-to-divl,macrofusion,mmx,nopl,popcnt,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87") }, - { str_lit("x86-64-v3"), str_lit("32bit-mode,64bit,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fxsr,idivq-to-divl,lzcnt,macrofusion,mmx,movbe,nopl,popcnt,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave") }, - { str_lit("x86-64-v4"), str_lit("32bit-mode,64bit,allow-light-256-bit,avx,avx2,avx512bw,avx512cd,avx512dq,avx512f,avx512vl,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fxsr,idivq-to-divl,lzcnt,macrofusion,mmx,movbe,nopl,popcnt,prefer-256-bit,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave") }, - { str_lit("yonah"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, - { str_lit("znver1"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,bmi,bmi2,branchfusion,clflushopt,clzero,cmov,crc32,cx16,cx8,f16c,fast-15bytenop,fast-bextr,fast-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,lzcnt,mmx,movbe,mwaitx,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,sbb-dep-breaking,sha,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("znver2"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,bmi,bmi2,branchfusion,clflushopt,clwb,clzero,cmov,crc32,cx16,cx8,f16c,fast-15bytenop,fast-bextr,fast-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,lzcnt,mmx,movbe,mwaitx,nopl,pclmul,popcnt,prfchw,rdpid,rdpru,rdrnd,rdseed,sahf,sbb-dep-breaking,sha,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,vzeroupper,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("znver3"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,bmi,bmi2,branchfusion,clflushopt,clwb,clzero,cmov,crc32,cx16,cx8,f16c,fast-15bytenop,fast-bextr,fast-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,invpcid,lzcnt,macrofusion,mmx,movbe,mwaitx,nopl,pclmul,pku,popcnt,prfchw,rdpid,rdpru,rdrnd,rdseed,sahf,sbb-dep-breaking,sha,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,vaes,vpclmulqdq,vzeroupper,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, - { str_lit("znver4"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,bmi,bmi2,branchfusion,clflushopt,clwb,clzero,cmov,crc32,cx16,cx8,evex512,f16c,fast-15bytenop,fast-bextr,fast-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,invpcid,lzcnt,macrofusion,mmx,movbe,mwaitx,nopl,pclmul,pku,popcnt,prfchw,rdpid,rdpru,rdrnd,rdseed,sahf,sbb-dep-breaking,sha,shstk,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,vaes,vpclmulqdq,vzeroupper,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, - // TargetArch_arm32: - { str_lit("arm1020e"), str_lit("armv5te,v4t,v5t,v5te") }, - { str_lit("arm1020t"), str_lit("armv5t,v4t,v5t") }, - { str_lit("arm1022e"), str_lit("armv5te,v4t,v5t,v5te") }, - { str_lit("arm10e"), str_lit("armv5te,v4t,v5t,v5te") }, - { str_lit("arm10tdmi"), str_lit("armv5t,v4t,v5t") }, - { str_lit("arm1136j-s"), str_lit("armv6,dsp,v4t,v5t,v5te,v6") }, - { str_lit("arm1136jf-s"), str_lit("armv6,dsp,fp64,fpregs,fpregs64,slowfpvmlx,v4t,v5t,v5te,v6,vfp2,vfp2sp") }, - { str_lit("arm1156t2-s"), str_lit("armv6t2,dsp,thumb2,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v8m") }, - { str_lit("arm1156t2f-s"), str_lit("armv6t2,dsp,fp64,fpregs,fpregs64,slowfpvmlx,thumb2,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v8m,vfp2,vfp2sp") }, - { str_lit("arm1176jz-s"), str_lit("armv6kz,trustzone,v4t,v5t,v5te,v6,v6k") }, - { str_lit("arm1176jzf-s"), str_lit("armv6kz,fp64,fpregs,fpregs64,slowfpvmlx,trustzone,v4t,v5t,v5te,v6,v6k,vfp2,vfp2sp") }, - { str_lit("arm710t"), str_lit("armv4t,v4t") }, - { str_lit("arm720t"), str_lit("armv4t,v4t") }, - { str_lit("arm7tdmi"), str_lit("armv4t,v4t") }, - { str_lit("arm7tdmi-s"), str_lit("armv4t,v4t") }, - { str_lit("arm8"), str_lit("armv4") }, - { str_lit("arm810"), str_lit("armv4") }, - { str_lit("arm9"), str_lit("armv4t,v4t") }, - { str_lit("arm920"), str_lit("armv4t,v4t") }, - { str_lit("arm920t"), str_lit("armv4t,v4t") }, - { str_lit("arm922t"), str_lit("armv4t,v4t") }, - { str_lit("arm926ej-s"), str_lit("armv5te,v4t,v5t,v5te") }, - { str_lit("arm940t"), str_lit("armv4t,v4t") }, - { str_lit("arm946e-s"), str_lit("armv5te,v4t,v5t,v5te") }, - { str_lit("arm966e-s"), str_lit("armv5te,v4t,v5t,v5te") }, - { str_lit("arm968e-s"), str_lit("armv5te,v4t,v5t,v5te") }, - { str_lit("arm9e"), str_lit("armv5te,v4t,v5t,v5te") }, - { str_lit("arm9tdmi"), str_lit("armv4t,v4t") }, - { str_lit("cortex-a12"), str_lit("a12,aclass,armv7-a,avoid-partial-cpsr,d32,db,dsp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,ret-addr-stack,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization,vmlx-forwarding") }, - { str_lit("cortex-a15"), str_lit("a15,aclass,armv7-a,avoid-partial-cpsr,d32,db,dont-widen-vmovs,dsp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,muxed-units,neon,perfmon,ret-addr-stack,splat-vfp-neon,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization,vldn-align") }, - { str_lit("cortex-a17"), str_lit("a17,aclass,armv7-a,avoid-partial-cpsr,d32,db,dsp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,ret-addr-stack,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization,vmlx-forwarding") }, - { str_lit("cortex-a32"), str_lit("aclass,acquire-release,aes,armv8-a,crc,crypto,d32,db,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, - { str_lit("cortex-a35"), str_lit("a35,aclass,acquire-release,aes,armv8-a,crc,crypto,d32,db,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, - { str_lit("cortex-a5"), str_lit("a5,aclass,armv7-a,d32,db,dsp,fp16,fp64,fpregs,fpregs64,mp,neon,perfmon,ret-addr-stack,slow-fp-brcc,slowfpvfmx,slowfpvmlx,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,vmlx-forwarding") }, - { str_lit("cortex-a53"), str_lit("a53,aclass,acquire-release,aes,armv8-a,crc,crypto,d32,db,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpao,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, - { str_lit("cortex-a55"), str_lit("a55,aclass,acquire-release,aes,armv8.2-a,crc,crypto,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,ras,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, - { str_lit("cortex-a57"), str_lit("a57,aclass,acquire-release,aes,armv8-a,avoid-partial-cpsr,cheap-predicable-cpsr,crc,crypto,d32,db,dsp,fix-cortex-a57-aes-1742098,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpao,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, - { str_lit("cortex-a7"), str_lit("a7,aclass,armv7-a,d32,db,dsp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,ret-addr-stack,slow-fp-brcc,slowfpvfmx,slowfpvmlx,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization,vmlx-forwarding,vmlx-hazards") }, - { str_lit("cortex-a710"), str_lit("aclass,acquire-release,armv9-a,bf16,cortex-a710,crc,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp16fml,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,hwdiv-arm,i8mm,mp,neon,perfmon,ras,sb,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8m,v9a,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, - { str_lit("cortex-a72"), str_lit("a72,aclass,acquire-release,aes,armv8-a,crc,crypto,d32,db,dsp,fix-cortex-a57-aes-1742098,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, - { str_lit("cortex-a73"), str_lit("a73,aclass,acquire-release,aes,armv8-a,crc,crypto,d32,db,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, - { str_lit("cortex-a75"), str_lit("a75,aclass,acquire-release,aes,armv8.2-a,crc,crypto,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,ras,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, - { str_lit("cortex-a76"), str_lit("a76,aclass,acquire-release,aes,armv8.2-a,crc,crypto,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,hwdiv-arm,mp,neon,perfmon,ras,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, - { str_lit("cortex-a76ae"), str_lit("a76,aclass,acquire-release,aes,armv8.2-a,crc,crypto,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,hwdiv-arm,mp,neon,perfmon,ras,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, - { str_lit("cortex-a77"), str_lit("a77,aclass,acquire-release,aes,armv8.2-a,crc,crypto,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,hwdiv-arm,mp,neon,perfmon,ras,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, - { str_lit("cortex-a78"), str_lit("aclass,acquire-release,aes,armv8.2-a,cortex-a78,crc,crypto,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,hwdiv-arm,mp,neon,perfmon,ras,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, - { str_lit("cortex-a78c"), str_lit("a78c,aclass,acquire-release,aes,armv8.2-a,crc,crypto,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,hwdiv-arm,mp,neon,perfmon,ras,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, - { str_lit("cortex-a8"), str_lit("a8,aclass,armv7-a,d32,db,dsp,fp64,fpregs,fpregs64,neon,nonpipelined-vfp,perfmon,ret-addr-stack,slow-fp-brcc,slowfpvfmx,slowfpvmlx,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vmlx-forwarding,vmlx-hazards") }, - { str_lit("cortex-a9"), str_lit("a9,aclass,armv7-a,avoid-partial-cpsr,d32,db,dsp,expand-fp-mlx,fp16,fp64,fpregs,fpregs64,mp,muxed-units,neon,neon-fpmovs,perfmon,prefer-vmovsr,ret-addr-stack,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vldn-align,vmlx-forwarding,vmlx-hazards") }, - { str_lit("cortex-m0"), str_lit("armv6-m,db,mclass,no-branch-predictor,noarm,strict-align,thumb-mode,v4t,v5t,v5te,v6,v6m") }, - { str_lit("cortex-m0plus"), str_lit("armv6-m,db,mclass,no-branch-predictor,noarm,strict-align,thumb-mode,v4t,v5t,v5te,v6,v6m") }, - { str_lit("cortex-m1"), str_lit("armv6-m,db,mclass,no-branch-predictor,noarm,strict-align,thumb-mode,v4t,v5t,v5te,v6,v6m") }, - { str_lit("cortex-m23"), str_lit("8msecext,acquire-release,armv8-m.base,db,hwdiv,mclass,no-branch-predictor,no-movt,noarm,strict-align,thumb-mode,v4t,v5t,v5te,v6,v6m,v7clrex,v8m") }, - { str_lit("cortex-m3"), str_lit("armv7-m,db,hwdiv,loop-align,m3,mclass,no-branch-predictor,noarm,thumb-mode,thumb2,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m") }, - { str_lit("cortex-m33"), str_lit("8msecext,acquire-release,armv8-m.main,db,dsp,fix-cmse-cve-2021-35465,fp-armv8d16sp,fp16,fpregs,hwdiv,loop-align,mclass,no-branch-predictor,noarm,slowfpvfmx,slowfpvmlx,thumb-mode,thumb2,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,v8m.main,vfp2sp,vfp3d16sp,vfp4d16sp") }, - { str_lit("cortex-m35p"), str_lit("8msecext,acquire-release,armv8-m.main,db,dsp,fix-cmse-cve-2021-35465,fp-armv8d16sp,fp16,fpregs,hwdiv,loop-align,mclass,no-branch-predictor,noarm,slowfpvfmx,slowfpvmlx,thumb-mode,thumb2,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,v8m.main,vfp2sp,vfp3d16sp,vfp4d16sp") }, - { str_lit("cortex-m4"), str_lit("armv7e-m,db,dsp,fp16,fpregs,hwdiv,loop-align,mclass,no-branch-predictor,noarm,slowfpvfmx,slowfpvmlx,thumb-mode,thumb2,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2sp,vfp3d16sp,vfp4d16sp") }, - { str_lit("cortex-m55"), str_lit("8msecext,acquire-release,armv8.1-m.main,db,dsp,fix-cmse-cve-2021-35465,fp-armv8d16,fp-armv8d16sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,lob,loop-align,mclass,mve,mve.fp,no-branch-predictor,noarm,ras,slowfpvmlx,thumb-mode,thumb2,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8.1m.main,v8m,v8m.main,vfp2,vfp2sp,vfp3d16,vfp3d16sp,vfp4d16,vfp4d16sp") }, - { str_lit("cortex-m7"), str_lit("armv7e-m,db,dsp,fp-armv8d16,fp-armv8d16sp,fp16,fp64,fpregs,fpregs64,hwdiv,m7,mclass,noarm,thumb-mode,thumb2,use-mipipeliner,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3d16,vfp3d16sp,vfp4d16,vfp4d16sp") }, - { str_lit("cortex-m85"), str_lit("8msecext,acquire-release,armv8.1-m.main,db,dsp,fp-armv8d16,fp-armv8d16sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,lob,mclass,mve,mve.fp,noarm,pacbti,ras,thumb-mode,thumb2,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8.1m.main,v8m,v8m.main,vfp2,vfp2sp,vfp3d16,vfp3d16sp,vfp4d16,vfp4d16sp") }, - { str_lit("cortex-r4"), str_lit("armv7-r,avoid-partial-cpsr,db,dsp,hwdiv,perfmon,r4,rclass,ret-addr-stack,thumb2,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m") }, - { str_lit("cortex-r4f"), str_lit("armv7-r,avoid-partial-cpsr,db,dsp,fp64,fpregs,fpregs64,hwdiv,perfmon,r4,rclass,ret-addr-stack,slow-fp-brcc,slowfpvfmx,slowfpvmlx,thumb2,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3d16,vfp3d16sp") }, - { str_lit("cortex-r5"), str_lit("armv7-r,avoid-partial-cpsr,db,dsp,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,perfmon,r5,rclass,ret-addr-stack,slow-fp-brcc,slowfpvfmx,slowfpvmlx,thumb2,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3d16,vfp3d16sp") }, - { str_lit("cortex-r52"), str_lit("acquire-release,armv8-r,crc,d32,db,dfb,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpao,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,r52,rclass,thumb2,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, - { str_lit("cortex-r7"), str_lit("armv7-r,avoid-partial-cpsr,db,dsp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,perfmon,r7,rclass,ret-addr-stack,slow-fp-brcc,slowfpvfmx,slowfpvmlx,thumb2,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3d16,vfp3d16sp") }, - { str_lit("cortex-r8"), str_lit("armv7-r,avoid-partial-cpsr,db,dsp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,perfmon,rclass,ret-addr-stack,slow-fp-brcc,slowfpvfmx,slowfpvmlx,thumb2,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3d16,vfp3d16sp") }, - { str_lit("cortex-x1"), str_lit("aclass,acquire-release,aes,armv8.2-a,cortex-x1,crc,crypto,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,hwdiv-arm,mp,neon,perfmon,ras,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, - { str_lit("cortex-x1c"), str_lit("aclass,acquire-release,aes,armv8.2-a,cortex-x1c,crc,crypto,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,hwdiv-arm,mp,neon,perfmon,ras,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, - { str_lit("cyclone"), str_lit("aclass,acquire-release,aes,armv8-a,avoid-movs-shop,avoid-partial-cpsr,crc,crypto,d32,db,disable-postra-scheduler,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,neonfp,perfmon,ret-addr-stack,sha2,slowfpvfmx,slowfpvmlx,swift,thumb2,trustzone,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization,zcz") }, - { str_lit("ep9312"), str_lit("armv4t,v4t") }, - { str_lit("exynos-m3"), str_lit("aclass,acquire-release,aes,armv8-a,crc,crypto,d32,db,dont-widen-vmovs,dsp,expand-fp-mlx,exynos,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs64,fuse-aes,fuse-literals,hwdiv,hwdiv-arm,mp,neon,perfmon,prof-unpr,ret-addr-stack,sha2,slow-fp-brcc,slow-vdup32,slow-vgetlni32,slowfpvfmx,slowfpvmlx,splat-vfp-neon,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization,wide-stride-vfp,zcz") }, - { str_lit("exynos-m4"), str_lit("aclass,acquire-release,aes,armv8.2-a,crc,crypto,d32,db,dont-widen-vmovs,dotprod,dsp,expand-fp-mlx,exynos,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,fuse-aes,fuse-literals,hwdiv,hwdiv-arm,mp,neon,perfmon,prof-unpr,ras,ret-addr-stack,sha2,slow-fp-brcc,slow-vdup32,slow-vgetlni32,slowfpvfmx,slowfpvmlx,splat-vfp-neon,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization,wide-stride-vfp,zcz") }, - { str_lit("exynos-m5"), str_lit("aclass,acquire-release,aes,armv8.2-a,crc,crypto,d32,db,dont-widen-vmovs,dotprod,dsp,expand-fp-mlx,exynos,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,fuse-aes,fuse-literals,hwdiv,hwdiv-arm,mp,neon,perfmon,prof-unpr,ras,ret-addr-stack,sha2,slow-fp-brcc,slow-vdup32,slow-vgetlni32,slowfpvfmx,slowfpvmlx,splat-vfp-neon,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization,wide-stride-vfp,zcz") }, - { str_lit("generic"), str_lit("") }, - { str_lit("iwmmxt"), str_lit("armv5te,v4t,v5t,v5te") }, - { str_lit("krait"), str_lit("aclass,armv7-a,avoid-partial-cpsr,d32,db,dsp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,krait,muxed-units,neon,perfmon,ret-addr-stack,thumb2,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,vldn-align,vmlx-forwarding") }, - { str_lit("kryo"), str_lit("aclass,acquire-release,aes,armv8-a,crc,crypto,d32,db,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,kryo,mp,neon,perfmon,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, - { str_lit("mpcore"), str_lit("armv6k,fp64,fpregs,fpregs64,slowfpvmlx,v4t,v5t,v5te,v6,v6k,vfp2,vfp2sp") }, - { str_lit("mpcorenovfp"), str_lit("armv6k,v4t,v5t,v5te,v6,v6k") }, - { str_lit("neoverse-n1"), str_lit("aclass,acquire-release,aes,armv8.2-a,crc,crypto,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,ras,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, - { str_lit("neoverse-n2"), str_lit("aclass,acquire-release,armv9-a,bf16,crc,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,i8mm,mp,neon,perfmon,ras,sb,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8m,v9a,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, - { str_lit("neoverse-v1"), str_lit("aclass,acquire-release,aes,armv8.4-a,bf16,crc,crypto,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,hwdiv-arm,i8mm,mp,neon,perfmon,ras,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8.3a,v8.4a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, - { str_lit("sc000"), str_lit("armv6-m,db,mclass,no-branch-predictor,noarm,strict-align,thumb-mode,v4t,v5t,v5te,v6,v6m") }, - { str_lit("sc300"), str_lit("armv7-m,db,hwdiv,m3,mclass,no-branch-predictor,noarm,thumb-mode,thumb2,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m") }, - { str_lit("strongarm"), str_lit("armv4") }, - { str_lit("strongarm110"), str_lit("armv4") }, - { str_lit("strongarm1100"), str_lit("armv4") }, - { str_lit("strongarm1110"), str_lit("armv4") }, - { str_lit("swift"), str_lit("aclass,armv7-a,avoid-movs-shop,avoid-partial-cpsr,d32,db,disable-postra-scheduler,dsp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,neonfp,perfmon,prefer-ishst,prof-unpr,ret-addr-stack,slow-load-D-subreg,slow-odd-reg,slow-vdup32,slow-vgetlni32,slowfpvfmx,slowfpvmlx,swift,thumb2,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,vmlx-hazards,wide-stride-vfp") }, - { str_lit("xscale"), str_lit("armv5te,v4t,v5t,v5te") }, - // TargetArch_arm64: - { str_lit("a64fx"), str_lit("CONTEXTIDREL2,a64fx,aggressive-fma,arith-bcc-fusion,ccpp,complxnum,crc,el2vmsa,el3,fp-armv8,fullfp16,lor,lse,neon,pan,pan-rwv,perfmon,predictable-select-expensive,ras,rdm,sha2,store-pair-suppress,sve,uaops,use-postra-scheduler,v8.1a,v8.2a,v8a,vh") }, - { str_lit("ampere1"), str_lit("CONTEXTIDREL2,addr-lsl-fast,aes,aggressive-fma,altnzcv,alu-lsl-fast,am,ampere1,amvs,arith-bcc-fusion,bf16,bti,ccdp,ccidx,ccpp,cmp-bcc-fusion,complxnum,crc,dit,dotprod,ecv,el2vmsa,el3,fgt,flagm,fp-armv8,fptoint,fuse-address,fuse-aes,fuse-literals,i8mm,jsconv,ldp-aligned-only,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,predres,rand,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,specrestrict,ssbs,store-pair-suppress,stp-aligned-only,tlb-rmi,tracev8.4,uaops,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8a,vh") }, - { str_lit("ampere1a"), str_lit("CONTEXTIDREL2,addr-lsl-fast,aes,aggressive-fma,altnzcv,alu-lsl-fast,am,ampere1a,amvs,arith-bcc-fusion,bf16,bti,ccdp,ccidx,ccpp,cmp-bcc-fusion,complxnum,crc,dit,dotprod,ecv,el2vmsa,el3,fgt,flagm,fp-armv8,fptoint,fuse-address,fuse-aes,fuse-literals,i8mm,jsconv,ldp-aligned-only,lor,lse,lse2,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predres,rand,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,sm4,specrestrict,ssbs,store-pair-suppress,stp-aligned-only,tlb-rmi,tracev8.4,uaops,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8a,vh") }, - { str_lit("apple-a10"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,apple-a10,arith-bcc-fusion,arith-cbz-fusion,crc,crypto,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fuse-aes,fuse-crypto-eor,lor,neon,pan,perfmon,rdm,sha2,store-pair-suppress,v8a,vh,zcm,zcz,zcz-gp") }, - { str_lit("apple-a11"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,apple-a11,arith-bcc-fusion,arith-cbz-fusion,ccpp,crc,crypto,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fullfp16,fuse-aes,fuse-crypto-eor,lor,lse,neon,pan,pan-rwv,perfmon,ras,rdm,sha2,store-pair-suppress,uaops,v8.1a,v8.2a,v8a,vh,zcm,zcz,zcz-gp") }, - { str_lit("apple-a12"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,apple-a12,arith-bcc-fusion,arith-cbz-fusion,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fullfp16,fuse-aes,fuse-crypto-eor,jsconv,lor,lse,neon,pan,pan-rwv,pauth,perfmon,ras,rcpc,rdm,sha2,store-pair-suppress,uaops,v8.1a,v8.2a,v8.3a,v8a,vh,zcm,zcz,zcz-gp") }, - { str_lit("apple-a13"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,am,apple-a13,arith-bcc-fusion,arith-cbz-fusion,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,dit,dotprod,el2vmsa,el3,flagm,fp-armv8,fp16fml,fullfp16,fuse-aes,fuse-crypto-eor,jsconv,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,ras,rcpc,rcpc-immo,rdm,sel2,sha2,sha3,store-pair-suppress,tlb-rmi,tracev8.4,uaops,v8.1a,v8.2a,v8.3a,v8.4a,v8a,vh,zcm,zcz,zcz-gp") }, - { str_lit("apple-a14"), str_lit("CONTEXTIDREL2,aes,aggressive-fma,alternate-sextload-cvt-f32-pattern,altnzcv,am,apple-a14,arith-bcc-fusion,arith-cbz-fusion,ccdp,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,dit,dotprod,el2vmsa,el3,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-address,fuse-adrp-add,fuse-aes,fuse-arith-logic,fuse-crypto-eor,fuse-csel,fuse-literals,jsconv,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,specrestrict,ssbs,store-pair-suppress,tlb-rmi,tracev8.4,uaops,v8.1a,v8.2a,v8.3a,v8.4a,v8a,vh,zcm,zcz,zcz-gp") }, - { str_lit("apple-a15"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,altnzcv,am,amvs,apple-a15,arith-bcc-fusion,arith-cbz-fusion,bf16,bti,ccdp,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,dit,dotprod,ecv,el2vmsa,el3,fgt,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-address,fuse-aes,fuse-arith-logic,fuse-crypto-eor,fuse-csel,fuse-literals,i8mm,jsconv,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,specrestrict,ssbs,store-pair-suppress,tlb-rmi,tracev8.4,uaops,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8a,vh,zcm,zcz,zcz-gp") }, - { str_lit("apple-a16"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,altnzcv,am,amvs,apple-a16,arith-bcc-fusion,arith-cbz-fusion,bf16,bti,ccdp,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,dit,dotprod,ecv,el2vmsa,el3,fgt,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-address,fuse-aes,fuse-arith-logic,fuse-crypto-eor,fuse-csel,fuse-literals,hcx,i8mm,jsconv,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,specrestrict,ssbs,store-pair-suppress,tlb-rmi,tracev8.4,uaops,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8a,vh,zcm,zcz,zcz-gp") }, - { str_lit("apple-a7"), str_lit("aes,alternate-sextload-cvt-f32-pattern,apple-a7,apple-a7-sysreg,arith-bcc-fusion,arith-cbz-fusion,crypto,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fuse-aes,fuse-crypto-eor,neon,perfmon,sha2,store-pair-suppress,v8a,zcm,zcz,zcz-fp-workaround,zcz-gp") }, - { str_lit("apple-a8"), str_lit("aes,alternate-sextload-cvt-f32-pattern,apple-a7,apple-a7-sysreg,arith-bcc-fusion,arith-cbz-fusion,crypto,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fuse-aes,fuse-crypto-eor,neon,perfmon,sha2,store-pair-suppress,v8a,zcm,zcz,zcz-fp-workaround,zcz-gp") }, - { str_lit("apple-a9"), str_lit("aes,alternate-sextload-cvt-f32-pattern,apple-a7,apple-a7-sysreg,arith-bcc-fusion,arith-cbz-fusion,crypto,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fuse-aes,fuse-crypto-eor,neon,perfmon,sha2,store-pair-suppress,v8a,zcm,zcz,zcz-fp-workaround,zcz-gp") }, - { str_lit("apple-latest"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,altnzcv,am,amvs,apple-a16,arith-bcc-fusion,arith-cbz-fusion,bf16,bti,ccdp,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,dit,dotprod,ecv,el2vmsa,el3,fgt,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-address,fuse-aes,fuse-arith-logic,fuse-crypto-eor,fuse-csel,fuse-literals,hcx,i8mm,jsconv,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,specrestrict,ssbs,store-pair-suppress,tlb-rmi,tracev8.4,uaops,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8a,vh,zcm,zcz,zcz-gp") }, - { str_lit("apple-m1"), str_lit("CONTEXTIDREL2,aes,aggressive-fma,alternate-sextload-cvt-f32-pattern,altnzcv,am,apple-a14,arith-bcc-fusion,arith-cbz-fusion,ccdp,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,dit,dotprod,el2vmsa,el3,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-address,fuse-adrp-add,fuse-aes,fuse-arith-logic,fuse-crypto-eor,fuse-csel,fuse-literals,jsconv,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,specrestrict,ssbs,store-pair-suppress,tlb-rmi,tracev8.4,uaops,v8.1a,v8.2a,v8.3a,v8.4a,v8a,vh,zcm,zcz,zcz-gp") }, - { str_lit("apple-m2"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,altnzcv,am,amvs,apple-a15,arith-bcc-fusion,arith-cbz-fusion,bf16,bti,ccdp,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,dit,dotprod,ecv,el2vmsa,el3,fgt,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-address,fuse-aes,fuse-arith-logic,fuse-crypto-eor,fuse-csel,fuse-literals,i8mm,jsconv,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,specrestrict,ssbs,store-pair-suppress,tlb-rmi,tracev8.4,uaops,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8a,vh,zcm,zcz,zcz-gp") }, - { str_lit("apple-s4"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,apple-a12,arith-bcc-fusion,arith-cbz-fusion,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fullfp16,fuse-aes,fuse-crypto-eor,jsconv,lor,lse,neon,pan,pan-rwv,pauth,perfmon,ras,rcpc,rdm,sha2,store-pair-suppress,uaops,v8.1a,v8.2a,v8.3a,v8a,vh,zcm,zcz,zcz-gp") }, - { str_lit("apple-s5"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,apple-a12,arith-bcc-fusion,arith-cbz-fusion,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fullfp16,fuse-aes,fuse-crypto-eor,jsconv,lor,lse,neon,pan,pan-rwv,pauth,perfmon,ras,rcpc,rdm,sha2,store-pair-suppress,uaops,v8.1a,v8.2a,v8.3a,v8a,vh,zcm,zcz,zcz-gp") }, - { str_lit("carmel"), str_lit("CONTEXTIDREL2,aes,carmel,ccpp,crc,crypto,el2vmsa,el3,fp-armv8,fullfp16,lor,lse,neon,pan,pan-rwv,ras,rdm,sha2,uaops,v8.1a,v8.2a,v8a,vh") }, - { str_lit("cortex-a34"), str_lit("a35,aes,crc,crypto,el2vmsa,el3,fp-armv8,neon,perfmon,sha2,v8a") }, - { str_lit("cortex-a35"), str_lit("a35,aes,crc,crypto,el2vmsa,el3,fp-armv8,neon,perfmon,sha2,v8a") }, - { str_lit("cortex-a510"), str_lit("CONTEXTIDREL2,a510,altnzcv,am,bf16,bti,ccdp,ccidx,ccpp,complxnum,crc,dit,dotprod,el2vmsa,el3,ete,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mec,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,rme,sb,sel2,specrestrict,ssbs,sve,sve2,sve2-bitperm,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,use-scalar-inc-vl,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") }, - { str_lit("cortex-a53"), str_lit("a53,aes,balance-fp-ops,crc,crypto,el2vmsa,el3,fp-armv8,fuse-adrp-add,fuse-aes,neon,perfmon,sha2,use-postra-scheduler,v8a") }, - { str_lit("cortex-a55"), str_lit("CONTEXTIDREL2,a55,aes,ccpp,crc,crypto,dotprod,el2vmsa,el3,fp-armv8,fullfp16,fuse-address,fuse-adrp-add,fuse-aes,lor,lse,neon,pan,pan-rwv,perfmon,ras,rcpc,rdm,sha2,uaops,use-postra-scheduler,v8.1a,v8.2a,v8a,vh") }, - { str_lit("cortex-a57"), str_lit("a57,aes,balance-fp-ops,crc,crypto,el2vmsa,el3,enable-select-opt,fp-armv8,fuse-adrp-add,fuse-aes,fuse-literals,neon,perfmon,predictable-select-expensive,sha2,use-postra-scheduler,v8a") }, - { str_lit("cortex-a65"), str_lit("CONTEXTIDREL2,a65,aes,ccpp,crc,crypto,dotprod,el2vmsa,el3,enable-select-opt,fp-armv8,fullfp16,fuse-address,fuse-adrp-add,fuse-aes,fuse-literals,lor,lse,neon,pan,pan-rwv,perfmon,predictable-select-expensive,ras,rcpc,rdm,sha2,ssbs,uaops,v8.1a,v8.2a,v8a,vh") }, - { str_lit("cortex-a65ae"), str_lit("CONTEXTIDREL2,a65,aes,ccpp,crc,crypto,dotprod,el2vmsa,el3,enable-select-opt,fp-armv8,fullfp16,fuse-address,fuse-adrp-add,fuse-aes,fuse-literals,lor,lse,neon,pan,pan-rwv,perfmon,predictable-select-expensive,ras,rcpc,rdm,sha2,ssbs,uaops,v8.1a,v8.2a,v8a,vh") }, - { str_lit("cortex-a710"), str_lit("CONTEXTIDREL2,a710,addr-lsl-fast,altnzcv,alu-lsl-fast,am,bf16,bti,ccdp,ccidx,ccpp,cmp-bcc-fusion,complxnum,crc,dit,dotprod,el2vmsa,el3,enable-select-opt,ete,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mec,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,ras,rcpc,rcpc-immo,rdm,rme,sb,sel2,specrestrict,ssbs,sve,sve2,sve2-bitperm,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,use-scalar-inc-vl,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") }, - { str_lit("cortex-a715"), str_lit("CONTEXTIDREL2,a715,addr-lsl-fast,altnzcv,alu-lsl-fast,am,bf16,bti,ccdp,ccidx,ccpp,cmp-bcc-fusion,complxnum,crc,dit,dotprod,el2vmsa,el3,enable-select-opt,ete,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mec,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,ras,rcpc,rcpc-immo,rdm,rme,sb,sel2,spe,specrestrict,ssbs,sve,sve2,sve2-bitperm,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,use-scalar-inc-vl,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") }, - { str_lit("cortex-a72"), str_lit("a72,aes,crc,crypto,el2vmsa,el3,enable-select-opt,fp-armv8,fuse-adrp-add,fuse-aes,fuse-literals,neon,perfmon,predictable-select-expensive,sha2,v8a") }, - { str_lit("cortex-a73"), str_lit("a73,aes,crc,crypto,el2vmsa,el3,enable-select-opt,fp-armv8,fuse-adrp-add,fuse-aes,neon,perfmon,predictable-select-expensive,sha2,v8a") }, - { str_lit("cortex-a75"), str_lit("CONTEXTIDREL2,a75,aes,ccpp,crc,crypto,dotprod,el2vmsa,el3,enable-select-opt,fp-armv8,fullfp16,fuse-adrp-add,fuse-aes,lor,lse,neon,pan,pan-rwv,perfmon,predictable-select-expensive,ras,rcpc,rdm,sha2,uaops,v8.1a,v8.2a,v8a,vh") }, - { str_lit("cortex-a76"), str_lit("CONTEXTIDREL2,a76,addr-lsl-fast,aes,alu-lsl-fast,ccpp,crc,crypto,dotprod,el2vmsa,el3,enable-select-opt,fp-armv8,fullfp16,fuse-adrp-add,fuse-aes,lor,lse,neon,pan,pan-rwv,perfmon,predictable-select-expensive,ras,rcpc,rdm,sha2,ssbs,uaops,v8.1a,v8.2a,v8a,vh") }, - { str_lit("cortex-a76ae"), str_lit("CONTEXTIDREL2,a76,addr-lsl-fast,aes,alu-lsl-fast,ccpp,crc,crypto,dotprod,el2vmsa,el3,enable-select-opt,fp-armv8,fullfp16,fuse-adrp-add,fuse-aes,lor,lse,neon,pan,pan-rwv,perfmon,predictable-select-expensive,ras,rcpc,rdm,sha2,ssbs,uaops,v8.1a,v8.2a,v8a,vh") }, - { str_lit("cortex-a77"), str_lit("CONTEXTIDREL2,a77,addr-lsl-fast,aes,alu-lsl-fast,ccpp,cmp-bcc-fusion,crc,crypto,dotprod,el2vmsa,el3,enable-select-opt,fp-armv8,fullfp16,fuse-adrp-add,fuse-aes,lor,lse,neon,pan,pan-rwv,perfmon,predictable-select-expensive,ras,rcpc,rdm,sha2,ssbs,uaops,v8.1a,v8.2a,v8a,vh") }, - { str_lit("cortex-a78"), str_lit("CONTEXTIDREL2,a78,addr-lsl-fast,aes,alu-lsl-fast,ccpp,cmp-bcc-fusion,crc,crypto,dotprod,el2vmsa,el3,enable-select-opt,fp-armv8,fullfp16,fuse-adrp-add,fuse-aes,lor,lse,neon,pan,pan-rwv,perfmon,predictable-select-expensive,ras,rcpc,rdm,sha2,spe,ssbs,uaops,use-postra-scheduler,v8.1a,v8.2a,v8a,vh") }, - { str_lit("cortex-a78c"), str_lit("CONTEXTIDREL2,a78c,addr-lsl-fast,aes,alu-lsl-fast,ccpp,cmp-bcc-fusion,crc,crypto,dotprod,el2vmsa,el3,enable-select-opt,flagm,fp-armv8,fullfp16,fuse-adrp-add,fuse-aes,lor,lse,neon,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,ras,rcpc,rdm,sha2,spe,ssbs,uaops,use-postra-scheduler,v8.1a,v8.2a,v8a,vh") }, - { str_lit("cortex-r82"), str_lit("CONTEXTIDREL2,ccidx,ccpp,complxnum,cortex-r82,crc,dit,dotprod,flagm,fp-armv8,fp16fml,fullfp16,jsconv,lse,neon,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,specrestrict,ssbs,tlb-rmi,tracev8.4,uaops,use-postra-scheduler,v8r") }, - { str_lit("cortex-x1"), str_lit("CONTEXTIDREL2,addr-lsl-fast,aes,alu-lsl-fast,ccpp,cmp-bcc-fusion,cortex-x1,crc,crypto,dotprod,el2vmsa,el3,enable-select-opt,fp-armv8,fullfp16,fuse-adrp-add,fuse-aes,lor,lse,neon,pan,pan-rwv,perfmon,predictable-select-expensive,ras,rcpc,rdm,sha2,spe,ssbs,uaops,use-postra-scheduler,v8.1a,v8.2a,v8a,vh") }, - { str_lit("cortex-x1c"), str_lit("CONTEXTIDREL2,addr-lsl-fast,aes,alu-lsl-fast,ccpp,cmp-bcc-fusion,cortex-x1,crc,crypto,dotprod,el2vmsa,el3,enable-select-opt,flagm,fp-armv8,fullfp16,fuse-adrp-add,fuse-aes,lor,lse,lse2,neon,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,ras,rcpc,rcpc-immo,rdm,sha2,spe,ssbs,uaops,use-postra-scheduler,v8.1a,v8.2a,v8a,vh") }, - { str_lit("cortex-x2"), str_lit("CONTEXTIDREL2,addr-lsl-fast,altnzcv,alu-lsl-fast,am,bf16,bti,ccdp,ccidx,ccpp,cmp-bcc-fusion,complxnum,cortex-x2,crc,dit,dotprod,el2vmsa,el3,enable-select-opt,ete,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mec,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,ras,rcpc,rcpc-immo,rdm,rme,sb,sel2,specrestrict,ssbs,sve,sve2,sve2-bitperm,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,use-scalar-inc-vl,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") }, - { str_lit("cortex-x3"), str_lit("CONTEXTIDREL2,addr-lsl-fast,altnzcv,alu-lsl-fast,am,bf16,bti,ccdp,ccidx,ccpp,complxnum,cortex-x3,crc,dit,dotprod,el2vmsa,el3,enable-select-opt,ete,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mec,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,ras,rcpc,rcpc-immo,rdm,rme,sb,sel2,spe,specrestrict,ssbs,sve,sve2,sve2-bitperm,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,use-scalar-inc-vl,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") }, - { str_lit("cyclone"), str_lit("aes,alternate-sextload-cvt-f32-pattern,apple-a7,apple-a7-sysreg,arith-bcc-fusion,arith-cbz-fusion,crypto,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fuse-aes,fuse-crypto-eor,neon,perfmon,sha2,store-pair-suppress,v8a,zcm,zcz,zcz-fp-workaround,zcz-gp") }, - { str_lit("exynos-m3"), str_lit("addr-lsl-fast,aes,alu-lsl-fast,crc,crypto,el2vmsa,el3,exynos-cheap-as-move,exynosm3,force-32bit-jump-tables,fp-armv8,fuse-address,fuse-adrp-add,fuse-aes,fuse-csel,fuse-literals,neon,perfmon,predictable-select-expensive,sha2,store-pair-suppress,use-postra-scheduler,v8a") }, - { str_lit("exynos-m4"), str_lit("CONTEXTIDREL2,addr-lsl-fast,aes,alu-lsl-fast,arith-bcc-fusion,arith-cbz-fusion,ccpp,crc,crypto,dotprod,el2vmsa,el3,exynos-cheap-as-move,exynosm4,force-32bit-jump-tables,fp-armv8,fullfp16,fuse-address,fuse-adrp-add,fuse-aes,fuse-arith-logic,fuse-csel,fuse-literals,lor,lse,neon,pan,pan-rwv,perfmon,ras,rdm,sha2,store-pair-suppress,uaops,use-postra-scheduler,v8.1a,v8.2a,v8a,vh,zcz,zcz-gp") }, - { str_lit("exynos-m5"), str_lit("CONTEXTIDREL2,addr-lsl-fast,aes,alu-lsl-fast,arith-bcc-fusion,arith-cbz-fusion,ccpp,crc,crypto,dotprod,el2vmsa,el3,exynos-cheap-as-move,exynosm4,force-32bit-jump-tables,fp-armv8,fullfp16,fuse-address,fuse-adrp-add,fuse-aes,fuse-arith-logic,fuse-csel,fuse-literals,lor,lse,neon,pan,pan-rwv,perfmon,ras,rdm,sha2,store-pair-suppress,uaops,use-postra-scheduler,v8.1a,v8.2a,v8a,vh,zcz,zcz-gp") }, - { str_lit("falkor"), str_lit("addr-lsl-fast,aes,alu-lsl-fast,crc,crypto,el2vmsa,el3,falkor,fp-armv8,neon,perfmon,predictable-select-expensive,rdm,sha2,slow-strqro-store,store-pair-suppress,use-postra-scheduler,v8a,zcz,zcz-gp") }, - { str_lit("generic"), str_lit("enable-select-opt,ete,fp-armv8,fuse-adrp-add,fuse-aes,neon,trbe,use-postra-scheduler") }, - { str_lit("kryo"), str_lit("addr-lsl-fast,aes,alu-lsl-fast,crc,crypto,el2vmsa,el3,fp-armv8,kryo,neon,perfmon,predictable-select-expensive,sha2,store-pair-suppress,use-postra-scheduler,v8a,zcz,zcz-gp") }, - { str_lit("neoverse-512tvb"), str_lit("CONTEXTIDREL2,addr-lsl-fast,aes,alu-lsl-fast,am,bf16,ccdp,ccidx,ccpp,complxnum,crc,crypto,dit,dotprod,el2vmsa,el3,enable-select-opt,flagm,fp-armv8,fp16fml,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mpam,neon,neoverse512tvb,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,rand,ras,rcpc,rcpc-immo,rdm,sel2,sha2,spe,ssbs,sve,tlb-rmi,tracev8.4,uaops,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8a,vh") }, - { str_lit("neoverse-e1"), str_lit("CONTEXTIDREL2,aes,ccpp,crc,crypto,dotprod,el2vmsa,el3,fp-armv8,fullfp16,fuse-adrp-add,fuse-aes,lor,lse,neon,neoversee1,pan,pan-rwv,perfmon,ras,rcpc,rdm,sha2,ssbs,uaops,use-postra-scheduler,v8.1a,v8.2a,v8a,vh") }, - { str_lit("neoverse-n1"), str_lit("CONTEXTIDREL2,addr-lsl-fast,aes,alu-lsl-fast,ccpp,crc,crypto,dotprod,el2vmsa,el3,enable-select-opt,fp-armv8,fullfp16,fuse-adrp-add,fuse-aes,lor,lse,neon,neoversen1,pan,pan-rwv,perfmon,predictable-select-expensive,ras,rcpc,rdm,sha2,spe,ssbs,uaops,use-postra-scheduler,v8.1a,v8.2a,v8a,vh") }, - { str_lit("neoverse-n2"), str_lit("CONTEXTIDREL2,addr-lsl-fast,altnzcv,alu-lsl-fast,am,bf16,bti,ccdp,ccidx,ccpp,complxnum,crc,dit,dotprod,el2vmsa,el3,enable-select-opt,ete,flagm,fp-armv8,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mec,mpam,mte,neon,neoversen2,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,ras,rcpc,rcpc-immo,rdm,rme,sb,sel2,specrestrict,ssbs,sve,sve2,sve2-bitperm,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,use-scalar-inc-vl,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") }, - { str_lit("neoverse-v1"), str_lit("CONTEXTIDREL2,addr-lsl-fast,aes,alu-lsl-fast,am,bf16,ccdp,ccidx,ccpp,complxnum,crc,crypto,dit,dotprod,el2vmsa,el3,enable-select-opt,flagm,fp-armv8,fp16fml,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mpam,neon,neoversev1,no-sve-fp-ld1r,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,rand,ras,rcpc,rcpc-immo,rdm,sel2,sha2,spe,ssbs,sve,tlb-rmi,tracev8.4,uaops,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8a,vh") }, - { str_lit("neoverse-v2"), str_lit("CONTEXTIDREL2,addr-lsl-fast,altnzcv,alu-lsl-fast,am,bf16,bti,ccdp,ccidx,ccpp,complxnum,crc,dit,dotprod,el2vmsa,el3,enable-select-opt,ete,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mec,mpam,mte,neon,neoversev2,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,rand,ras,rcpc,rcpc-immo,rdm,rme,sb,sel2,spe,specrestrict,ssbs,sve,sve2,sve2-bitperm,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,use-scalar-inc-vl,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") }, - { str_lit("saphira"), str_lit("CONTEXTIDREL2,addr-lsl-fast,aes,alu-lsl-fast,am,ccidx,ccpp,complxnum,crc,crypto,dit,dotprod,el2vmsa,el3,flagm,fp-armv8,jsconv,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,ras,rcpc,rcpc-immo,rdm,saphira,sel2,sha2,spe,store-pair-suppress,tlb-rmi,tracev8.4,uaops,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8a,vh,zcz,zcz-gp") }, - { str_lit("thunderx"), str_lit("aes,crc,crypto,el2vmsa,el3,fp-armv8,neon,perfmon,predictable-select-expensive,sha2,store-pair-suppress,thunderx,use-postra-scheduler,v8a") }, - { str_lit("thunderx2t99"), str_lit("CONTEXTIDREL2,aes,aggressive-fma,arith-bcc-fusion,crc,crypto,el2vmsa,el3,fp-armv8,lor,lse,neon,pan,predictable-select-expensive,rdm,sha2,store-pair-suppress,thunderx2t99,use-postra-scheduler,v8.1a,v8a,vh") }, - { str_lit("thunderx3t110"), str_lit("CONTEXTIDREL2,aes,aggressive-fma,arith-bcc-fusion,balance-fp-ops,ccidx,ccpp,complxnum,crc,crypto,el2vmsa,el3,fp-armv8,jsconv,lor,lse,neon,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,ras,rcpc,rdm,sha2,store-pair-suppress,strict-align,thunderx3t110,uaops,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8a,vh") }, - { str_lit("thunderxt81"), str_lit("aes,crc,crypto,el2vmsa,el3,fp-armv8,neon,perfmon,predictable-select-expensive,sha2,store-pair-suppress,thunderxt81,use-postra-scheduler,v8a") }, - { str_lit("thunderxt83"), str_lit("aes,crc,crypto,el2vmsa,el3,fp-armv8,neon,perfmon,predictable-select-expensive,sha2,store-pair-suppress,thunderxt83,use-postra-scheduler,v8a") }, - { str_lit("thunderxt88"), str_lit("aes,crc,crypto,el2vmsa,el3,fp-armv8,neon,perfmon,predictable-select-expensive,sha2,store-pair-suppress,thunderxt88,use-postra-scheduler,v8a") }, - { str_lit("tsv110"), str_lit("CONTEXTIDREL2,aes,ccpp,complxnum,crc,crypto,dotprod,el2vmsa,el3,fp-armv8,fp16fml,fullfp16,fuse-aes,jsconv,lor,lse,neon,pan,pan-rwv,perfmon,ras,rdm,sha2,spe,store-pair-suppress,tsv110,uaops,use-postra-scheduler,v8.1a,v8.2a,v8a,vh") }, - // TargetArch_wasm32: - { str_lit("bleeding-edge"), str_lit("atomics,bulk-memory,mutable-globals,nontrapping-fptoint,sign-ext,simd128,tail-call") }, - { str_lit("generic"), str_lit("mutable-globals,sign-ext") }, - { str_lit("mvp"), str_lit("") }, - // TargetArch_wasm64p32: - { str_lit("bleeding-edge"), str_lit("atomics,bulk-memory,mutable-globals,nontrapping-fptoint,sign-ext,simd128,tail-call") }, - { str_lit("generic"), str_lit("mutable-globals,sign-ext") }, - { str_lit("mvp"), str_lit("") }, -}; +#include "build_settings_microarch.cpp" gb_global String target_endian_names[TargetEndian_COUNT] = { str_lit("little"), diff --git a/src/build_settings_microarch.cpp b/src/build_settings_microarch.cpp new file mode 100644 index 000000000..02b507031 --- /dev/null +++ b/src/build_settings_microarch.cpp @@ -0,0 +1,462 @@ +// Generated with the featuregen script in `misc/featuregen` +gb_global String target_microarch_list[TargetArch_COUNT] = { + // TargetArch_Invalid: + str_lit(""), + // TargetArch_amd64: + str_lit("alderlake,amdfam10,athlon,athlon-4,athlon-fx,athlon-mp,athlon-tbird,athlon-xp,athlon64,athlon64-sse3,atom,atom_sse4_2,atom_sse4_2_movbe,barcelona,bdver1,bdver2,bdver3,bdver4,bonnell,broadwell,btver1,btver2,c3,c3-2,cannonlake,cascadelake,cooperlake,core-avx-i,core-avx2,core2,core_2_duo_sse4_1,core_2_duo_ssse3,core_2nd_gen_avx,core_3rd_gen_avx,core_4th_gen_avx,core_4th_gen_avx_tsx,core_5th_gen_avx,core_5th_gen_avx_tsx,core_aes_pclmulqdq,core_i7_sse4_2,corei7,corei7-avx,emeraldrapids,generic,geode,goldmont,goldmont-plus,goldmont_plus,grandridge,graniterapids,graniterapids-d,graniterapids_d,haswell,i386,i486,i586,i686,icelake-client,icelake-server,icelake_client,icelake_server,ivybridge,k6,k6-2,k6-3,k8,k8-sse3,knl,knm,lakemont,meteorlake,mic_avx512,nehalem,nocona,opteron,opteron-sse3,penryn,pentium,pentium-m,pentium-mmx,pentium2,pentium3,pentium3m,pentium4,pentium4m,pentium_4,pentium_4_sse3,pentium_ii,pentium_iii,pentium_iii_no_xmm_regs,pentium_m,pentium_mmx,pentium_pro,pentiumpro,prescott,raptorlake,rocketlake,sandybridge,sapphirerapids,sierraforest,silvermont,skx,skylake,skylake-avx512,skylake_avx512,slm,tigerlake,tremont,westmere,winchip-c6,winchip2,x86-64,x86-64-v2,x86-64-v3,x86-64-v4,yonah,znver1,znver2,znver3,znver4"), + // TargetArch_i386: + str_lit("alderlake,amdfam10,athlon,athlon-4,athlon-fx,athlon-mp,athlon-tbird,athlon-xp,athlon64,athlon64-sse3,atom,atom_sse4_2,atom_sse4_2_movbe,barcelona,bdver1,bdver2,bdver3,bdver4,bonnell,broadwell,btver1,btver2,c3,c3-2,cannonlake,cascadelake,cooperlake,core-avx-i,core-avx2,core2,core_2_duo_sse4_1,core_2_duo_ssse3,core_2nd_gen_avx,core_3rd_gen_avx,core_4th_gen_avx,core_4th_gen_avx_tsx,core_5th_gen_avx,core_5th_gen_avx_tsx,core_aes_pclmulqdq,core_i7_sse4_2,corei7,corei7-avx,emeraldrapids,generic,geode,goldmont,goldmont-plus,goldmont_plus,grandridge,graniterapids,graniterapids-d,graniterapids_d,haswell,i386,i486,i586,i686,icelake-client,icelake-server,icelake_client,icelake_server,ivybridge,k6,k6-2,k6-3,k8,k8-sse3,knl,knm,lakemont,meteorlake,mic_avx512,nehalem,nocona,opteron,opteron-sse3,penryn,pentium,pentium-m,pentium-mmx,pentium2,pentium3,pentium3m,pentium4,pentium4m,pentium_4,pentium_4_sse3,pentium_ii,pentium_iii,pentium_iii_no_xmm_regs,pentium_m,pentium_mmx,pentium_pro,pentiumpro,prescott,raptorlake,rocketlake,sandybridge,sapphirerapids,sierraforest,silvermont,skx,skylake,skylake-avx512,skylake_avx512,slm,tigerlake,tremont,westmere,winchip-c6,winchip2,x86-64,x86-64-v2,x86-64-v3,x86-64-v4,yonah,znver1,znver2,znver3,znver4"), + // TargetArch_arm32: + str_lit("arm1020e,arm1020t,arm1022e,arm10e,arm10tdmi,arm1136j-s,arm1136jf-s,arm1156t2-s,arm1156t2f-s,arm1176jz-s,arm1176jzf-s,arm710t,arm720t,arm7tdmi,arm7tdmi-s,arm8,arm810,arm9,arm920,arm920t,arm922t,arm926ej-s,arm940t,arm946e-s,arm966e-s,arm968e-s,arm9e,arm9tdmi,cortex-a12,cortex-a15,cortex-a17,cortex-a32,cortex-a35,cortex-a5,cortex-a53,cortex-a55,cortex-a57,cortex-a7,cortex-a710,cortex-a72,cortex-a73,cortex-a75,cortex-a76,cortex-a76ae,cortex-a77,cortex-a78,cortex-a78c,cortex-a8,cortex-a9,cortex-m0,cortex-m0plus,cortex-m1,cortex-m23,cortex-m3,cortex-m33,cortex-m35p,cortex-m4,cortex-m55,cortex-m7,cortex-m85,cortex-r4,cortex-r4f,cortex-r5,cortex-r52,cortex-r7,cortex-r8,cortex-x1,cortex-x1c,cyclone,ep9312,exynos-m3,exynos-m4,exynos-m5,generic,iwmmxt,krait,kryo,mpcore,mpcorenovfp,neoverse-n1,neoverse-n2,neoverse-v1,sc000,sc300,strongarm,strongarm110,strongarm1100,strongarm1110,swift,xscale"), + // TargetArch_arm64: + str_lit("a64fx,ampere1,ampere1a,apple-a10,apple-a11,apple-a12,apple-a13,apple-a14,apple-a15,apple-a16,apple-a7,apple-a8,apple-a9,apple-latest,apple-m1,apple-m2,apple-s4,apple-s5,carmel,cortex-a34,cortex-a35,cortex-a510,cortex-a53,cortex-a55,cortex-a57,cortex-a65,cortex-a65ae,cortex-a710,cortex-a715,cortex-a72,cortex-a73,cortex-a75,cortex-a76,cortex-a76ae,cortex-a77,cortex-a78,cortex-a78c,cortex-r82,cortex-x1,cortex-x1c,cortex-x2,cortex-x3,cyclone,exynos-m3,exynos-m4,exynos-m5,falkor,generic,kryo,neoverse-512tvb,neoverse-e1,neoverse-n1,neoverse-n2,neoverse-v1,neoverse-v2,saphira,thunderx,thunderx2t99,thunderx3t110,thunderxt81,thunderxt83,thunderxt88,tsv110"), + // TargetArch_wasm32: + str_lit("bleeding-edge,generic,mvp"), + // TargetArch_wasm64p32: + str_lit("bleeding-edge,generic,mvp"), +}; + +// Generated with the featuregen script in `misc/featuregen` +gb_global String target_features_list[TargetArch_COUNT] = { + // TargetArch_Invalid: + str_lit(""), + // TargetArch_amd64: + str_lit("16bit-mode,32bit-mode,3dnow,3dnowa,64bit,64bit-mode,adx,aes,allow-light-256-bit,amx-bf16,amx-complex,amx-fp16,amx-int8,amx-tile,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512er,avx512f,avx512fp16,avx512ifma,avx512pf,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vp2intersect,avx512vpopcntdq,avxifma,avxneconvert,avxvnni,avxvnniint16,avxvnniint8,bmi,bmi2,branchfusion,cldemote,clflushopt,clwb,clzero,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,ermsb,f16c,false-deps-getmant,false-deps-lzcnt-tzcnt,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-popcnt,false-deps-range,fast-11bytenop,fast-15bytenop,fast-7bytenop,fast-bextr,fast-gather,fast-hops,fast-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fast-vector-shift-masks,faster-shift-than-shuffle,fma,fma4,fsgsbase,fsrm,fxsr,gfni,harden-sls-ijmp,harden-sls-ret,hreset,idivl-to-divb,idivq-to-divl,invpcid,kl,lea-sp,lea-uses-ag,lvi-cfi,lvi-load-hardening,lwp,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,mwaitx,no-bypass-delay,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pad-short-functions,pclmul,pconfig,pku,popcnt,prefer-128-bit,prefer-256-bit,prefer-mask-registers,prefer-movmsk-over-vtest,prefer-no-gather,prefer-no-scatter,prefetchi,prefetchwt1,prfchw,ptwrite,raoint,rdpid,rdpru,rdrnd,rdseed,retpoline,retpoline-external-thunk,retpoline-indirect-branches,retpoline-indirect-calls,rtm,sahf,sbb-dep-breaking,serialize,seses,sgx,sha,sha512,shstk,slow-3ops-lea,slow-incdec,slow-lea,slow-pmaddwd,slow-pmulld,slow-shld,slow-two-mem-ops,slow-unaligned-mem-16,slow-unaligned-mem-32,sm3,sm4,soft-float,sse,sse-unaligned-mem,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,tagged-globals,tbm,tsxldtrk,tuning-fast-imm-vector-shift,uintr,use-glm-div-sqrt-costs,use-slm-arith-costs,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,widekl,x87,xop,xsave,xsavec,xsaveopt,xsaves"), + // TargetArch_i386: + str_lit("16bit-mode,32bit-mode,3dnow,3dnowa,64bit,64bit-mode,adx,aes,allow-light-256-bit,amx-bf16,amx-complex,amx-fp16,amx-int8,amx-tile,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512er,avx512f,avx512fp16,avx512ifma,avx512pf,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vp2intersect,avx512vpopcntdq,avxifma,avxneconvert,avxvnni,avxvnniint16,avxvnniint8,bmi,bmi2,branchfusion,cldemote,clflushopt,clwb,clzero,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,ermsb,f16c,false-deps-getmant,false-deps-lzcnt-tzcnt,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-popcnt,false-deps-range,fast-11bytenop,fast-15bytenop,fast-7bytenop,fast-bextr,fast-gather,fast-hops,fast-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fast-vector-shift-masks,faster-shift-than-shuffle,fma,fma4,fsgsbase,fsrm,fxsr,gfni,harden-sls-ijmp,harden-sls-ret,hreset,idivl-to-divb,idivq-to-divl,invpcid,kl,lea-sp,lea-uses-ag,lvi-cfi,lvi-load-hardening,lwp,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,mwaitx,no-bypass-delay,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pad-short-functions,pclmul,pconfig,pku,popcnt,prefer-128-bit,prefer-256-bit,prefer-mask-registers,prefer-movmsk-over-vtest,prefer-no-gather,prefer-no-scatter,prefetchi,prefetchwt1,prfchw,ptwrite,raoint,rdpid,rdpru,rdrnd,rdseed,retpoline,retpoline-external-thunk,retpoline-indirect-branches,retpoline-indirect-calls,rtm,sahf,sbb-dep-breaking,serialize,seses,sgx,sha,sha512,shstk,slow-3ops-lea,slow-incdec,slow-lea,slow-pmaddwd,slow-pmulld,slow-shld,slow-two-mem-ops,slow-unaligned-mem-16,slow-unaligned-mem-32,sm3,sm4,soft-float,sse,sse-unaligned-mem,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,tagged-globals,tbm,tsxldtrk,tuning-fast-imm-vector-shift,uintr,use-glm-div-sqrt-costs,use-slm-arith-costs,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,widekl,x87,xop,xsave,xsavec,xsaveopt,xsaves"), + // TargetArch_arm32: + str_lit("32bit,8msecext,a12,a15,a17,a32,a35,a5,a53,a55,a57,a7,a72,a73,a75,a76,a77,a78c,a8,a9,aapcs-frame-chain,aapcs-frame-chain-leaf,aclass,acquire-release,aes,armv4,armv4t,armv5t,armv5te,armv5tej,armv6,armv6-m,armv6j,armv6k,armv6kz,armv6s-m,armv6t2,armv7-a,armv7-m,armv7-r,armv7e-m,armv7k,armv7s,armv7ve,armv8-a,armv8-m.base,armv8-m.main,armv8-r,armv8.1-a,armv8.1-m.main,armv8.2-a,armv8.3-a,armv8.4-a,armv8.5-a,armv8.6-a,armv8.7-a,armv8.8-a,armv8.9-a,armv9-a,armv9.1-a,armv9.2-a,armv9.3-a,armv9.4-a,atomics-32,avoid-movs-shop,avoid-partial-cpsr,bf16,big-endian-instructions,cde,cdecp0,cdecp1,cdecp2,cdecp3,cdecp4,cdecp5,cdecp6,cdecp7,cheap-predicable-cpsr,clrbhb,cortex-a710,cortex-a78,cortex-x1,cortex-x1c,crc,crypto,d32,db,dfb,disable-postra-scheduler,dont-widen-vmovs,dotprod,dsp,execute-only,expand-fp-mlx,exynos,fix-cmse-cve-2021-35465,fix-cortex-a57-aes-1742098,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp16fml,fp64,fpao,fpregs,fpregs16,fpregs64,fullfp16,fuse-aes,fuse-literals,harden-sls-blr,harden-sls-nocomdat,harden-sls-retbr,hwdiv,hwdiv-arm,i8mm,iwmmxt,iwmmxt2,krait,kryo,lob,long-calls,loop-align,m3,m7,mclass,mp,muxed-units,mve,mve.fp,mve1beat,mve2beat,mve4beat,nacl-trap,neon,neon-fpmovs,neonfp,neoverse-v1,no-branch-predictor,no-bti-at-return-twice,no-movt,no-neg-immediates,noarm,nonpipelined-vfp,pacbti,perfmon,prefer-ishst,prefer-vmovsr,prof-unpr,r4,r5,r52,r7,ras,rclass,read-tp-tpidrprw,read-tp-tpidruro,read-tp-tpidrurw,reserve-r9,ret-addr-stack,sb,sha2,slow-fp-brcc,slow-load-D-subreg,slow-odd-reg,slow-vdup32,slow-vgetlni32,slowfpvfmx,slowfpvmlx,soft-float,splat-vfp-neon,strict-align,swift,thumb-mode,thumb2,trustzone,use-mipipeliner,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.1m.main,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8.7a,v8.8a,v8.9a,v8m,v8m.main,v9.1a,v9.2a,v9.3a,v9.4a,v9a,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization,vldn-align,vmlx-forwarding,vmlx-hazards,wide-stride-vfp,xscale,zcz"), + // TargetArch_arm64: + str_lit("CONTEXTIDREL2,a35,a510,a53,a55,a57,a64fx,a65,a710,a715,a72,a73,a75,a76,a77,a78,a78c,aes,aggressive-fma,all,alternate-sextload-cvt-f32-pattern,altnzcv,am,ampere1,ampere1a,amvs,apple-a10,apple-a11,apple-a12,apple-a13,apple-a14,apple-a15,apple-a16,apple-a7,apple-a7-sysreg,arith-bcc-fusion,arith-cbz-fusion,ascend-store-address,b16b16,balance-fp-ops,bf16,brbe,bti,call-saved-x10,call-saved-x11,call-saved-x12,call-saved-x13,call-saved-x14,call-saved-x15,call-saved-x18,call-saved-x8,call-saved-x9,carmel,ccdp,ccidx,ccpp,chk,clrbhb,cmp-bcc-fusion,complxnum,cortex-r82,cortex-x1,cortex-x2,cortex-x3,crc,crypto,cssc,custom-cheap-as-move,d128,disable-latency-sched-heuristic,dit,dotprod,ecv,el2vmsa,el3,enable-select-opt,ete,exynos-cheap-as-move,exynosm3,exynosm4,f32mm,f64mm,falkor,fgt,fix-cortex-a53-835769,flagm,fmv,force-32bit-jump-tables,fp-armv8,fp16fml,fptoint,fullfp16,fuse-address,fuse-addsub-2reg-const1,fuse-adrp-add,fuse-aes,fuse-arith-logic,fuse-crypto-eor,fuse-csel,fuse-literals,gcs,harden-sls-blr,harden-sls-nocomdat,harden-sls-retbr,hbc,hcx,i8mm,ite,jsconv,kryo,lor,ls64,lse,lse128,lse2,lsl-fast,mec,mops,mpam,mte,neon,neoverse512tvb,neoversee1,neoversen1,neoversen2,neoversev1,neoversev2,nmi,no-bti-at-return-twice,no-neg-immediates,no-sve-fp-ld1r,no-zcz-fp,nv,outline-atomics,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,prfm-slc-target,rand,ras,rasv2,rcpc,rcpc-immo,rcpc3,rdm,reserve-x1,reserve-x10,reserve-x11,reserve-x12,reserve-x13,reserve-x14,reserve-x15,reserve-x18,reserve-x2,reserve-x20,reserve-x21,reserve-x22,reserve-x23,reserve-x24,reserve-x25,reserve-x26,reserve-x27,reserve-x28,reserve-x3,reserve-x30,reserve-x4,reserve-x5,reserve-x6,reserve-x7,reserve-x9,rme,saphira,sb,sel2,sha2,sha3,slow-misaligned-128store,slow-paired-128,slow-strqro-store,sm4,sme,sme-f16f16,sme-f64f64,sme-i16i64,sme2,sme2p1,spe,spe-eef,specres2,specrestrict,ssbs,strict-align,sve,sve2,sve2-aes,sve2-bitperm,sve2-sha3,sve2-sm4,sve2p1,tagged-globals,the,thunderx,thunderx2t99,thunderx3t110,thunderxt81,thunderxt83,thunderxt88,tlb-rmi,tme,tpidr-el1,tpidr-el2,tpidr-el3,tpidrro-el0,tracev8.4,trbe,tsv110,uaops,use-experimental-zeroing-pseudos,use-postra-scheduler,use-reciprocal-square-root,use-scalar-inc-vl,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8.7a,v8.8a,v8.9a,v8a,v8r,v9.1a,v9.2a,v9.3a,v9.4a,v9a,vh,wfxt,xs,zcm,zcz,zcz-fp-workaround,zcz-gp"), + // TargetArch_wasm32: + str_lit("atomics,bulk-memory,exception-handling,extended-const,multivalue,mutable-globals,nontrapping-fptoint,reference-types,relaxed-simd,sign-ext,simd128,tail-call"), + // TargetArch_wasm64p32: + str_lit("atomics,bulk-memory,exception-handling,extended-const,multivalue,mutable-globals,nontrapping-fptoint,reference-types,relaxed-simd,sign-ext,simd128,tail-call"), +}; + +// Generated with the featuregen script in `misc/featuregen` +gb_global int target_microarch_counts[TargetArch_COUNT] = { + // TargetArch_Invalid: + 0, + // TargetArch_amd64: + 120, + // TargetArch_i386: + 120, + // TargetArch_arm32: + 90, + // TargetArch_arm64: + 63, + // TargetArch_wasm32: + 3, + // TargetArch_wasm64p32: + 3, +}; + +// Generated with the featuregen script in `misc/featuregen` +gb_global MicroarchFeatureList microarch_features_list[] = { + // TargetArch_amd64: + { str_lit("alderlake"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("amdfam10"), str_lit("3dnow,3dnowa,64bit,64bit-mode,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,lzcnt,mmx,nopl,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4a,vzeroupper,x87") }, + { str_lit("athlon"), str_lit("3dnow,3dnowa,64bit-mode,cmov,cx8,mmx,nopl,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("athlon-4"), str_lit("3dnow,3dnowa,64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("athlon-fx"), str_lit("3dnow,3dnowa,64bit,64bit-mode,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("athlon-mp"), str_lit("3dnow,3dnowa,64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("athlon-tbird"), str_lit("3dnow,3dnowa,64bit-mode,cmov,cx8,mmx,nopl,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("athlon-xp"), str_lit("3dnow,3dnowa,64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("athlon64"), str_lit("3dnow,3dnowa,64bit,64bit-mode,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("athlon64-sse3"), str_lit("3dnow,3dnowa,64bit,64bit-mode,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, + { str_lit("atom"), str_lit("64bit,64bit-mode,cmov,cx16,cx8,fxsr,idivl-to-divb,idivq-to-divl,lea-sp,lea-uses-ag,mmx,movbe,no-bypass-delay,nopl,pad-short-functions,sahf,slow-two-mem-ops,slow-unaligned-mem-16,sse,sse2,sse3,ssse3,vzeroupper,x87") }, + { str_lit("atom_sse4_2"), str_lit("64bit,64bit-mode,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-7bytenop,fast-movbe,fxsr,idivq-to-divl,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,rdrnd,sahf,slow-incdec,slow-lea,slow-pmulld,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-slm-arith-costs,vzeroupper,x87") }, + { str_lit("atom_sse4_2_movbe"), str_lit("64bit,64bit-mode,aes,clflushopt,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-7bytenop,fast-movbe,fsgsbase,fxsr,idivq-to-divl,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,sha,slow-incdec,slow-lea,slow-pmulld,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-slm-arith-costs,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("barcelona"), str_lit("3dnow,3dnowa,64bit,64bit-mode,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,lzcnt,mmx,nopl,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4a,vzeroupper,x87") }, + { str_lit("bdver1"), str_lit("64bit,64bit-mode,aes,avx,branchfusion,cmov,crc32,cx16,cx8,fast-11bytenop,fast-scalar-shift-masks,fma4,fxsr,lwp,lzcnt,mmx,nopl,pclmul,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,vzeroupper,x87,xop,xsave") }, + { str_lit("bdver2"), str_lit("64bit,64bit-mode,aes,avx,bmi,branchfusion,cmov,crc32,cx16,cx8,f16c,fast-11bytenop,fast-bextr,fast-movbe,fast-scalar-shift-masks,fma,fma4,fxsr,lwp,lzcnt,mmx,nopl,pclmul,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,tbm,vzeroupper,x87,xop,xsave") }, + { str_lit("bdver3"), str_lit("64bit,64bit-mode,aes,avx,bmi,branchfusion,cmov,crc32,cx16,cx8,f16c,fast-11bytenop,fast-bextr,fast-movbe,fast-scalar-shift-masks,fma,fma4,fsgsbase,fxsr,lwp,lzcnt,mmx,nopl,pclmul,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,tbm,vzeroupper,x87,xop,xsave,xsaveopt") }, + { str_lit("bdver4"), str_lit("64bit,64bit-mode,aes,avx,avx2,bmi,bmi2,branchfusion,cmov,crc32,cx16,cx8,f16c,fast-11bytenop,fast-bextr,fast-movbe,fast-scalar-shift-masks,fma,fma4,fsgsbase,fxsr,lwp,lzcnt,mmx,movbe,mwaitx,nopl,pclmul,popcnt,prfchw,rdrnd,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,tbm,vzeroupper,x87,xop,xsave,xsaveopt") }, + { str_lit("bonnell"), str_lit("64bit,64bit-mode,cmov,cx16,cx8,fxsr,idivl-to-divb,idivq-to-divl,lea-sp,lea-uses-ag,mmx,movbe,no-bypass-delay,nopl,pad-short-functions,sahf,slow-two-mem-ops,slow-unaligned-mem-16,sse,sse2,sse3,ssse3,vzeroupper,x87") }, + { str_lit("broadwell"), str_lit("64bit,64bit-mode,adx,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("btver1"), str_lit("64bit,64bit-mode,cmov,cx16,cx8,fast-15bytenop,fast-scalar-shift-masks,fast-vector-shift-masks,fxsr,lzcnt,mmx,nopl,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4a,ssse3,vzeroupper,x87") }, + { str_lit("btver2"), str_lit("64bit,64bit-mode,aes,avx,bmi,cmov,crc32,cx16,cx8,f16c,fast-15bytenop,fast-bextr,fast-hops,fast-lzcnt,fast-movbe,fast-scalar-shift-masks,fast-vector-shift-masks,fxsr,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,x87,xsave,xsaveopt") }, + { str_lit("c3"), str_lit("3dnow,64bit-mode,mmx,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("c3-2"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("cannonlake"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vl,bmi,bmi2,clflushopt,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,sha,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("cascadelake"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bw,avx512cd,avx512dq,avx512f,avx512vl,avx512vnni,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,faster-shift-than-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("cooperlake"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bf16,avx512bw,avx512cd,avx512dq,avx512f,avx512vl,avx512vnni,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,faster-shift-than-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("core-avx-i"), str_lit("64bit,64bit-mode,avx,cmov,crc32,cx16,cx8,f16c,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fsgsbase,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("core-avx2"), str_lit("64bit,64bit-mode,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("core2"), str_lit("64bit,64bit-mode,cmov,cx16,cx8,fxsr,macrofusion,mmx,nopl,sahf,slow-unaligned-mem-16,sse,sse2,sse3,ssse3,vzeroupper,x87") }, + { str_lit("core_2_duo_sse4_1"), str_lit("64bit,64bit-mode,cmov,cx16,cx8,fxsr,macrofusion,mmx,nopl,sahf,slow-unaligned-mem-16,sse,sse2,sse3,sse4.1,ssse3,vzeroupper,x87") }, + { str_lit("core_2_duo_ssse3"), str_lit("64bit,64bit-mode,cmov,cx16,cx8,fxsr,macrofusion,mmx,nopl,sahf,slow-unaligned-mem-16,sse,sse2,sse3,ssse3,vzeroupper,x87") }, + { str_lit("core_2nd_gen_avx"), str_lit("64bit,64bit-mode,avx,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("core_3rd_gen_avx"), str_lit("64bit,64bit-mode,avx,cmov,crc32,cx16,cx8,f16c,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fsgsbase,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("core_4th_gen_avx"), str_lit("64bit,64bit-mode,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("core_4th_gen_avx_tsx"), str_lit("64bit,64bit-mode,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("core_5th_gen_avx"), str_lit("64bit,64bit-mode,adx,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("core_5th_gen_avx_tsx"), str_lit("64bit,64bit-mode,adx,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("core_aes_pclmulqdq"), str_lit("64bit,64bit-mode,cmov,crc32,cx16,cx8,fxsr,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,sahf,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87") }, + { str_lit("core_i7_sse4_2"), str_lit("64bit,64bit-mode,cmov,crc32,cx16,cx8,fxsr,macrofusion,mmx,no-bypass-delay-mov,nopl,popcnt,sahf,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87") }, + { str_lit("corei7"), str_lit("64bit,64bit-mode,cmov,crc32,cx16,cx8,fxsr,macrofusion,mmx,no-bypass-delay-mov,nopl,popcnt,sahf,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87") }, + { str_lit("corei7-avx"), str_lit("64bit,64bit-mode,avx,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("emeraldrapids"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,amx-bf16,amx-int8,amx-tile,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512fp16,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,enqcmd,ermsb,evex512,f16c,false-deps-getmant,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-range,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tsxldtrk,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("generic"), str_lit("64bit,64bit-mode,cx8,fast-15bytenop,fast-scalar-fsqrt,idivq-to-divl,macrofusion,slow-3ops-lea,sse,sse2,vzeroupper,x87") }, + { str_lit("geode"), str_lit("3dnow,3dnowa,64bit-mode,cx8,mmx,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("goldmont"), str_lit("64bit,64bit-mode,aes,clflushopt,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-movbe,fsgsbase,fxsr,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,sha,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-glm-div-sqrt-costs,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("goldmont-plus"), str_lit("64bit,64bit-mode,aes,clflushopt,cmov,crc32,cx16,cx8,fast-movbe,fsgsbase,fxsr,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,sha,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-glm-div-sqrt-costs,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("goldmont_plus"), str_lit("64bit,64bit-mode,aes,clflushopt,cmov,crc32,cx16,cx8,fast-movbe,fsgsbase,fxsr,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,sha,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-glm-div-sqrt-costs,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("grandridge"), str_lit("64bit,64bit-mode,adx,aes,avx,avx2,avxifma,avxneconvert,avxvnni,avxvnniint8,bmi,bmi2,cldemote,clflushopt,clwb,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,f16c,fast-movbe,fma,fsgsbase,fxsr,gfni,hreset,invpcid,kl,lzcnt,mmx,movbe,movdir64b,movdiri,no-bypass-delay,nopl,pclmul,pconfig,pku,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,uintr,use-glm-div-sqrt-costs,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("graniterapids"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,amx-bf16,amx-fp16,amx-int8,amx-tile,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512fp16,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,enqcmd,ermsb,evex512,f16c,false-deps-getmant,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-range,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prefetchi,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tsxldtrk,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("graniterapids-d"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,amx-bf16,amx-complex,amx-fp16,amx-int8,amx-tile,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512fp16,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,enqcmd,ermsb,evex512,f16c,false-deps-getmant,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-range,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prefetchi,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tsxldtrk,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("graniterapids_d"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,amx-bf16,amx-complex,amx-fp16,amx-int8,amx-tile,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512fp16,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,enqcmd,ermsb,evex512,f16c,false-deps-getmant,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-range,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prefetchi,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tsxldtrk,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("haswell"), str_lit("64bit,64bit-mode,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("i386"), str_lit("64bit-mode,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("i486"), str_lit("64bit-mode,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("i586"), str_lit("64bit-mode,cx8,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("i686"), str_lit("64bit-mode,cmov,cx8,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("icelake-client"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,bmi,bmi2,clflushopt,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdpid,rdrnd,rdseed,sahf,sha,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("icelake-server"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prfchw,rdpid,rdrnd,rdseed,sahf,sha,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("icelake_client"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,bmi,bmi2,clflushopt,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdpid,rdrnd,rdseed,sahf,sha,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("icelake_server"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prfchw,rdpid,rdrnd,rdseed,sahf,sha,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("ivybridge"), str_lit("64bit,64bit-mode,avx,cmov,crc32,cx16,cx8,f16c,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fsgsbase,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("k6"), str_lit("64bit-mode,cx8,mmx,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("k6-2"), str_lit("3dnow,64bit-mode,cx8,mmx,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("k6-3"), str_lit("3dnow,64bit-mode,cx8,mmx,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("k8"), str_lit("3dnow,3dnowa,64bit,64bit-mode,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("k8-sse3"), str_lit("3dnow,3dnowa,64bit,64bit-mode,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, + { str_lit("knl"), str_lit("64bit,64bit-mode,adx,aes,avx,avx2,avx512cd,avx512er,avx512f,avx512pf,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,fast-gather,fast-movbe,fma,fsgsbase,fxsr,idivq-to-divl,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prefer-mask-registers,prefetchwt1,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,slow-incdec,slow-pmaddwd,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,x87,xsave,xsaveopt") }, + { str_lit("knm"), str_lit("64bit,64bit-mode,adx,aes,avx,avx2,avx512cd,avx512er,avx512f,avx512pf,avx512vpopcntdq,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,fast-gather,fast-movbe,fma,fsgsbase,fxsr,idivq-to-divl,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prefer-mask-registers,prefetchwt1,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,slow-incdec,slow-pmaddwd,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,x87,xsave,xsaveopt") }, + { str_lit("lakemont"), str_lit("64bit-mode,cx8,slow-unaligned-mem-16,sse,sse2,vzeroupper") }, + { str_lit("meteorlake"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("mic_avx512"), str_lit("64bit,64bit-mode,adx,aes,avx,avx2,avx512cd,avx512er,avx512f,avx512pf,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,fast-gather,fast-movbe,fma,fsgsbase,fxsr,idivq-to-divl,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prefer-mask-registers,prefetchwt1,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,slow-incdec,slow-pmaddwd,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,x87,xsave,xsaveopt") }, + { str_lit("nehalem"), str_lit("64bit,64bit-mode,cmov,crc32,cx16,cx8,fxsr,macrofusion,mmx,no-bypass-delay-mov,nopl,popcnt,sahf,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87") }, + { str_lit("nocona"), str_lit("64bit,64bit-mode,cmov,cx16,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, + { str_lit("opteron"), str_lit("3dnow,3dnowa,64bit,64bit-mode,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("opteron-sse3"), str_lit("3dnow,3dnowa,64bit,64bit-mode,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, + { str_lit("penryn"), str_lit("64bit,64bit-mode,cmov,cx16,cx8,fxsr,macrofusion,mmx,nopl,sahf,slow-unaligned-mem-16,sse,sse2,sse3,sse4.1,ssse3,vzeroupper,x87") }, + { str_lit("pentium"), str_lit("64bit-mode,cx8,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("pentium-m"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("pentium-mmx"), str_lit("64bit-mode,cx8,mmx,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("pentium2"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("pentium3"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("pentium3m"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("pentium4"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("pentium4m"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("pentium_4"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("pentium_4_sse3"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, + { str_lit("pentium_ii"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("pentium_iii"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("pentium_iii_no_xmm_regs"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("pentium_m"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("pentium_mmx"), str_lit("64bit-mode,cx8,mmx,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("pentium_pro"), str_lit("64bit-mode,cmov,cx8,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("pentiumpro"), str_lit("64bit-mode,cmov,cx8,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("prescott"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, + { str_lit("raptorlake"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("rocketlake"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,bmi,bmi2,clflushopt,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdpid,rdrnd,rdseed,sahf,sha,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("sandybridge"), str_lit("64bit,64bit-mode,avx,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("sapphirerapids"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,amx-bf16,amx-int8,amx-tile,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512fp16,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,enqcmd,ermsb,evex512,f16c,false-deps-getmant,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-range,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tsxldtrk,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("sierraforest"), str_lit("64bit,64bit-mode,adx,aes,avx,avx2,avxifma,avxneconvert,avxvnni,avxvnniint8,bmi,bmi2,cldemote,clflushopt,clwb,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,f16c,fast-movbe,fma,fsgsbase,fxsr,gfni,hreset,invpcid,kl,lzcnt,mmx,movbe,movdir64b,movdiri,no-bypass-delay,nopl,pclmul,pconfig,pku,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,uintr,use-glm-div-sqrt-costs,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("silvermont"), str_lit("64bit,64bit-mode,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-7bytenop,fast-movbe,fxsr,idivq-to-divl,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,rdrnd,sahf,slow-incdec,slow-lea,slow-pmulld,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-slm-arith-costs,vzeroupper,x87") }, + { str_lit("skx"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bw,avx512cd,avx512dq,avx512f,avx512vl,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,faster-shift-than-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("skylake"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,bmi,bmi2,clflushopt,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("skylake-avx512"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bw,avx512cd,avx512dq,avx512f,avx512vl,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,faster-shift-than-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("skylake_avx512"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bw,avx512cd,avx512dq,avx512f,avx512vl,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,faster-shift-than-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("slm"), str_lit("64bit,64bit-mode,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-7bytenop,fast-movbe,fxsr,idivq-to-divl,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,rdrnd,sahf,slow-incdec,slow-lea,slow-pmulld,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-slm-arith-costs,vzeroupper,x87") }, + { str_lit("tigerlake"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vp2intersect,avx512vpopcntdq,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdpid,rdrnd,rdseed,sahf,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("tremont"), str_lit("64bit,64bit-mode,aes,clflushopt,clwb,cmov,crc32,cx16,cx8,fast-movbe,fsgsbase,fxsr,gfni,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,sha,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-glm-div-sqrt-costs,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("westmere"), str_lit("64bit,64bit-mode,cmov,crc32,cx16,cx8,fxsr,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,sahf,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87") }, + { str_lit("winchip-c6"), str_lit("64bit-mode,mmx,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("winchip2"), str_lit("3dnow,64bit-mode,mmx,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("x86-64"), str_lit("64bit,64bit-mode,cmov,cx8,fxsr,idivq-to-divl,macrofusion,mmx,nopl,slow-3ops-lea,slow-incdec,sse,sse2,vzeroupper,x87") }, + { str_lit("x86-64-v2"), str_lit("64bit,64bit-mode,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fxsr,idivq-to-divl,macrofusion,mmx,nopl,popcnt,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87") }, + { str_lit("x86-64-v3"), str_lit("64bit,64bit-mode,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fxsr,idivq-to-divl,lzcnt,macrofusion,mmx,movbe,nopl,popcnt,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave") }, + { str_lit("x86-64-v4"), str_lit("64bit,64bit-mode,allow-light-256-bit,avx,avx2,avx512bw,avx512cd,avx512dq,avx512f,avx512vl,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fxsr,idivq-to-divl,lzcnt,macrofusion,mmx,movbe,nopl,popcnt,prefer-256-bit,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave") }, + { str_lit("yonah"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, + { str_lit("znver1"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,bmi,bmi2,branchfusion,clflushopt,clzero,cmov,crc32,cx16,cx8,f16c,fast-15bytenop,fast-bextr,fast-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,lzcnt,mmx,movbe,mwaitx,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,sbb-dep-breaking,sha,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("znver2"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,bmi,bmi2,branchfusion,clflushopt,clwb,clzero,cmov,crc32,cx16,cx8,f16c,fast-15bytenop,fast-bextr,fast-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,lzcnt,mmx,movbe,mwaitx,nopl,pclmul,popcnt,prfchw,rdpid,rdpru,rdrnd,rdseed,sahf,sbb-dep-breaking,sha,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,vzeroupper,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("znver3"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,bmi,bmi2,branchfusion,clflushopt,clwb,clzero,cmov,crc32,cx16,cx8,f16c,fast-15bytenop,fast-bextr,fast-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,invpcid,lzcnt,macrofusion,mmx,movbe,mwaitx,nopl,pclmul,pku,popcnt,prfchw,rdpid,rdpru,rdrnd,rdseed,sahf,sbb-dep-breaking,sha,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,vaes,vpclmulqdq,vzeroupper,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("znver4"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,bmi,bmi2,branchfusion,clflushopt,clwb,clzero,cmov,crc32,cx16,cx8,evex512,f16c,fast-15bytenop,fast-bextr,fast-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,invpcid,lzcnt,macrofusion,mmx,movbe,mwaitx,nopl,pclmul,pku,popcnt,prfchw,rdpid,rdpru,rdrnd,rdseed,sahf,sbb-dep-breaking,sha,shstk,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,vaes,vpclmulqdq,vzeroupper,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + // TargetArch_i386: + { str_lit("alderlake"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("amdfam10"), str_lit("32bit-mode,3dnow,3dnowa,64bit,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,lzcnt,mmx,nopl,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4a,vzeroupper,x87") }, + { str_lit("athlon"), str_lit("32bit-mode,3dnow,3dnowa,cmov,cx8,mmx,nopl,slow-shld,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("athlon-4"), str_lit("32bit-mode,3dnow,3dnowa,cmov,cx8,fxsr,mmx,nopl,slow-shld,slow-unaligned-mem-16,sse,vzeroupper,x87") }, + { str_lit("athlon-fx"), str_lit("32bit-mode,3dnow,3dnowa,64bit,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("athlon-mp"), str_lit("32bit-mode,3dnow,3dnowa,cmov,cx8,fxsr,mmx,nopl,slow-shld,slow-unaligned-mem-16,sse,vzeroupper,x87") }, + { str_lit("athlon-tbird"), str_lit("32bit-mode,3dnow,3dnowa,cmov,cx8,mmx,nopl,slow-shld,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("athlon-xp"), str_lit("32bit-mode,3dnow,3dnowa,cmov,cx8,fxsr,mmx,nopl,slow-shld,slow-unaligned-mem-16,sse,vzeroupper,x87") }, + { str_lit("athlon64"), str_lit("32bit-mode,3dnow,3dnowa,64bit,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("athlon64-sse3"), str_lit("32bit-mode,3dnow,3dnowa,64bit,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, + { str_lit("atom"), str_lit("32bit-mode,64bit,cmov,cx16,cx8,fxsr,idivl-to-divb,idivq-to-divl,lea-sp,lea-uses-ag,mmx,movbe,no-bypass-delay,nopl,pad-short-functions,sahf,slow-two-mem-ops,slow-unaligned-mem-16,sse,sse2,sse3,ssse3,vzeroupper,x87") }, + { str_lit("atom_sse4_2"), str_lit("32bit-mode,64bit,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-7bytenop,fast-movbe,fxsr,idivq-to-divl,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,rdrnd,sahf,slow-incdec,slow-lea,slow-pmulld,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-slm-arith-costs,vzeroupper,x87") }, + { str_lit("atom_sse4_2_movbe"), str_lit("32bit-mode,64bit,aes,clflushopt,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-7bytenop,fast-movbe,fsgsbase,fxsr,idivq-to-divl,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,sha,slow-incdec,slow-lea,slow-pmulld,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-slm-arith-costs,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("barcelona"), str_lit("32bit-mode,3dnow,3dnowa,64bit,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,lzcnt,mmx,nopl,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4a,vzeroupper,x87") }, + { str_lit("bdver1"), str_lit("32bit-mode,64bit,aes,avx,branchfusion,cmov,crc32,cx16,cx8,fast-11bytenop,fast-scalar-shift-masks,fma4,fxsr,lwp,lzcnt,mmx,nopl,pclmul,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,vzeroupper,x87,xop,xsave") }, + { str_lit("bdver2"), str_lit("32bit-mode,64bit,aes,avx,bmi,branchfusion,cmov,crc32,cx16,cx8,f16c,fast-11bytenop,fast-bextr,fast-movbe,fast-scalar-shift-masks,fma,fma4,fxsr,lwp,lzcnt,mmx,nopl,pclmul,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,tbm,vzeroupper,x87,xop,xsave") }, + { str_lit("bdver3"), str_lit("32bit-mode,64bit,aes,avx,bmi,branchfusion,cmov,crc32,cx16,cx8,f16c,fast-11bytenop,fast-bextr,fast-movbe,fast-scalar-shift-masks,fma,fma4,fsgsbase,fxsr,lwp,lzcnt,mmx,nopl,pclmul,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,tbm,vzeroupper,x87,xop,xsave,xsaveopt") }, + { str_lit("bdver4"), str_lit("32bit-mode,64bit,aes,avx,avx2,bmi,bmi2,branchfusion,cmov,crc32,cx16,cx8,f16c,fast-11bytenop,fast-bextr,fast-movbe,fast-scalar-shift-masks,fma,fma4,fsgsbase,fxsr,lwp,lzcnt,mmx,movbe,mwaitx,nopl,pclmul,popcnt,prfchw,rdrnd,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,tbm,vzeroupper,x87,xop,xsave,xsaveopt") }, + { str_lit("bonnell"), str_lit("32bit-mode,64bit,cmov,cx16,cx8,fxsr,idivl-to-divb,idivq-to-divl,lea-sp,lea-uses-ag,mmx,movbe,no-bypass-delay,nopl,pad-short-functions,sahf,slow-two-mem-ops,slow-unaligned-mem-16,sse,sse2,sse3,ssse3,vzeroupper,x87") }, + { str_lit("broadwell"), str_lit("32bit-mode,64bit,adx,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("btver1"), str_lit("32bit-mode,64bit,cmov,cx16,cx8,fast-15bytenop,fast-scalar-shift-masks,fast-vector-shift-masks,fxsr,lzcnt,mmx,nopl,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4a,ssse3,vzeroupper,x87") }, + { str_lit("btver2"), str_lit("32bit-mode,64bit,aes,avx,bmi,cmov,crc32,cx16,cx8,f16c,fast-15bytenop,fast-bextr,fast-hops,fast-lzcnt,fast-movbe,fast-scalar-shift-masks,fast-vector-shift-masks,fxsr,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,x87,xsave,xsaveopt") }, + { str_lit("c3"), str_lit("32bit-mode,3dnow,mmx,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("c3-2"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,slow-unaligned-mem-16,sse,vzeroupper,x87") }, + { str_lit("cannonlake"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vl,bmi,bmi2,clflushopt,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,sha,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("cascadelake"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bw,avx512cd,avx512dq,avx512f,avx512vl,avx512vnni,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,faster-shift-than-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("cooperlake"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bf16,avx512bw,avx512cd,avx512dq,avx512f,avx512vl,avx512vnni,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,faster-shift-than-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("core-avx-i"), str_lit("32bit-mode,64bit,avx,cmov,crc32,cx16,cx8,f16c,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fsgsbase,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("core-avx2"), str_lit("32bit-mode,64bit,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("core2"), str_lit("32bit-mode,64bit,cmov,cx16,cx8,fxsr,macrofusion,mmx,nopl,sahf,slow-unaligned-mem-16,sse,sse2,sse3,ssse3,vzeroupper,x87") }, + { str_lit("core_2_duo_sse4_1"), str_lit("32bit-mode,64bit,cmov,cx16,cx8,fxsr,macrofusion,mmx,nopl,sahf,slow-unaligned-mem-16,sse,sse2,sse3,sse4.1,ssse3,vzeroupper,x87") }, + { str_lit("core_2_duo_ssse3"), str_lit("32bit-mode,64bit,cmov,cx16,cx8,fxsr,macrofusion,mmx,nopl,sahf,slow-unaligned-mem-16,sse,sse2,sse3,ssse3,vzeroupper,x87") }, + { str_lit("core_2nd_gen_avx"), str_lit("32bit-mode,64bit,avx,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("core_3rd_gen_avx"), str_lit("32bit-mode,64bit,avx,cmov,crc32,cx16,cx8,f16c,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fsgsbase,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("core_4th_gen_avx"), str_lit("32bit-mode,64bit,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("core_4th_gen_avx_tsx"), str_lit("32bit-mode,64bit,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("core_5th_gen_avx"), str_lit("32bit-mode,64bit,adx,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("core_5th_gen_avx_tsx"), str_lit("32bit-mode,64bit,adx,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("core_aes_pclmulqdq"), str_lit("32bit-mode,64bit,cmov,crc32,cx16,cx8,fxsr,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,sahf,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87") }, + { str_lit("core_i7_sse4_2"), str_lit("32bit-mode,64bit,cmov,crc32,cx16,cx8,fxsr,macrofusion,mmx,no-bypass-delay-mov,nopl,popcnt,sahf,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87") }, + { str_lit("corei7"), str_lit("32bit-mode,64bit,cmov,crc32,cx16,cx8,fxsr,macrofusion,mmx,no-bypass-delay-mov,nopl,popcnt,sahf,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87") }, + { str_lit("corei7-avx"), str_lit("32bit-mode,64bit,avx,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("emeraldrapids"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,amx-bf16,amx-int8,amx-tile,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512fp16,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,enqcmd,ermsb,evex512,f16c,false-deps-getmant,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-range,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tsxldtrk,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("generic"), str_lit("32bit-mode,64bit,cx8,fast-15bytenop,fast-scalar-fsqrt,idivq-to-divl,macrofusion,slow-3ops-lea,vzeroupper,x87") }, + { str_lit("geode"), str_lit("32bit-mode,3dnow,3dnowa,cx8,mmx,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("goldmont"), str_lit("32bit-mode,64bit,aes,clflushopt,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-movbe,fsgsbase,fxsr,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,sha,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-glm-div-sqrt-costs,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("goldmont-plus"), str_lit("32bit-mode,64bit,aes,clflushopt,cmov,crc32,cx16,cx8,fast-movbe,fsgsbase,fxsr,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,sha,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-glm-div-sqrt-costs,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("goldmont_plus"), str_lit("32bit-mode,64bit,aes,clflushopt,cmov,crc32,cx16,cx8,fast-movbe,fsgsbase,fxsr,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,sha,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-glm-div-sqrt-costs,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("grandridge"), str_lit("32bit-mode,64bit,adx,aes,avx,avx2,avxifma,avxneconvert,avxvnni,avxvnniint8,bmi,bmi2,cldemote,clflushopt,clwb,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,f16c,fast-movbe,fma,fsgsbase,fxsr,gfni,hreset,invpcid,kl,lzcnt,mmx,movbe,movdir64b,movdiri,no-bypass-delay,nopl,pclmul,pconfig,pku,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,uintr,use-glm-div-sqrt-costs,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("graniterapids"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,amx-bf16,amx-fp16,amx-int8,amx-tile,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512fp16,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,enqcmd,ermsb,evex512,f16c,false-deps-getmant,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-range,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prefetchi,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tsxldtrk,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("graniterapids-d"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,amx-bf16,amx-complex,amx-fp16,amx-int8,amx-tile,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512fp16,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,enqcmd,ermsb,evex512,f16c,false-deps-getmant,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-range,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prefetchi,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tsxldtrk,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("graniterapids_d"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,amx-bf16,amx-complex,amx-fp16,amx-int8,amx-tile,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512fp16,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,enqcmd,ermsb,evex512,f16c,false-deps-getmant,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-range,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prefetchi,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tsxldtrk,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("haswell"), str_lit("32bit-mode,64bit,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("i386"), str_lit("32bit-mode,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("i486"), str_lit("32bit-mode,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("i586"), str_lit("32bit-mode,cx8,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("i686"), str_lit("32bit-mode,cmov,cx8,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("icelake-client"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,bmi,bmi2,clflushopt,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdpid,rdrnd,rdseed,sahf,sha,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("icelake-server"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prfchw,rdpid,rdrnd,rdseed,sahf,sha,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("icelake_client"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,bmi,bmi2,clflushopt,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdpid,rdrnd,rdseed,sahf,sha,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("icelake_server"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prfchw,rdpid,rdrnd,rdseed,sahf,sha,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("ivybridge"), str_lit("32bit-mode,64bit,avx,cmov,crc32,cx16,cx8,f16c,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fsgsbase,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("k6"), str_lit("32bit-mode,cx8,mmx,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("k6-2"), str_lit("32bit-mode,3dnow,cx8,mmx,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("k6-3"), str_lit("32bit-mode,3dnow,cx8,mmx,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("k8"), str_lit("32bit-mode,3dnow,3dnowa,64bit,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("k8-sse3"), str_lit("32bit-mode,3dnow,3dnowa,64bit,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, + { str_lit("knl"), str_lit("32bit-mode,64bit,adx,aes,avx,avx2,avx512cd,avx512er,avx512f,avx512pf,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,fast-gather,fast-movbe,fma,fsgsbase,fxsr,idivq-to-divl,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prefer-mask-registers,prefetchwt1,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,slow-incdec,slow-pmaddwd,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,x87,xsave,xsaveopt") }, + { str_lit("knm"), str_lit("32bit-mode,64bit,adx,aes,avx,avx2,avx512cd,avx512er,avx512f,avx512pf,avx512vpopcntdq,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,fast-gather,fast-movbe,fma,fsgsbase,fxsr,idivq-to-divl,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prefer-mask-registers,prefetchwt1,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,slow-incdec,slow-pmaddwd,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,x87,xsave,xsaveopt") }, + { str_lit("lakemont"), str_lit("32bit-mode,cx8,slow-unaligned-mem-16,vzeroupper") }, + { str_lit("meteorlake"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("mic_avx512"), str_lit("32bit-mode,64bit,adx,aes,avx,avx2,avx512cd,avx512er,avx512f,avx512pf,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,fast-gather,fast-movbe,fma,fsgsbase,fxsr,idivq-to-divl,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prefer-mask-registers,prefetchwt1,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,slow-incdec,slow-pmaddwd,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,x87,xsave,xsaveopt") }, + { str_lit("nehalem"), str_lit("32bit-mode,64bit,cmov,crc32,cx16,cx8,fxsr,macrofusion,mmx,no-bypass-delay-mov,nopl,popcnt,sahf,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87") }, + { str_lit("nocona"), str_lit("32bit-mode,64bit,cmov,cx16,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, + { str_lit("opteron"), str_lit("32bit-mode,3dnow,3dnowa,64bit,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("opteron-sse3"), str_lit("32bit-mode,3dnow,3dnowa,64bit,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, + { str_lit("penryn"), str_lit("32bit-mode,64bit,cmov,cx16,cx8,fxsr,macrofusion,mmx,nopl,sahf,slow-unaligned-mem-16,sse,sse2,sse3,sse4.1,ssse3,vzeroupper,x87") }, + { str_lit("pentium"), str_lit("32bit-mode,cx8,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("pentium-m"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("pentium-mmx"), str_lit("32bit-mode,cx8,mmx,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("pentium2"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("pentium3"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,vzeroupper,x87") }, + { str_lit("pentium3m"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,vzeroupper,x87") }, + { str_lit("pentium4"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("pentium4m"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("pentium_4"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("pentium_4_sse3"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, + { str_lit("pentium_ii"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("pentium_iii"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,vzeroupper,x87") }, + { str_lit("pentium_iii_no_xmm_regs"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,vzeroupper,x87") }, + { str_lit("pentium_m"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("pentium_mmx"), str_lit("32bit-mode,cx8,mmx,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("pentium_pro"), str_lit("32bit-mode,cmov,cx8,nopl,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("pentiumpro"), str_lit("32bit-mode,cmov,cx8,nopl,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("prescott"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, + { str_lit("raptorlake"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("rocketlake"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,bmi,bmi2,clflushopt,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdpid,rdrnd,rdseed,sahf,sha,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("sandybridge"), str_lit("32bit-mode,64bit,avx,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("sapphirerapids"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,amx-bf16,amx-int8,amx-tile,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512fp16,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,enqcmd,ermsb,evex512,f16c,false-deps-getmant,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-range,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tsxldtrk,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("sierraforest"), str_lit("32bit-mode,64bit,adx,aes,avx,avx2,avxifma,avxneconvert,avxvnni,avxvnniint8,bmi,bmi2,cldemote,clflushopt,clwb,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,f16c,fast-movbe,fma,fsgsbase,fxsr,gfni,hreset,invpcid,kl,lzcnt,mmx,movbe,movdir64b,movdiri,no-bypass-delay,nopl,pclmul,pconfig,pku,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,uintr,use-glm-div-sqrt-costs,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("silvermont"), str_lit("32bit-mode,64bit,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-7bytenop,fast-movbe,fxsr,idivq-to-divl,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,rdrnd,sahf,slow-incdec,slow-lea,slow-pmulld,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-slm-arith-costs,vzeroupper,x87") }, + { str_lit("skx"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bw,avx512cd,avx512dq,avx512f,avx512vl,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,faster-shift-than-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("skylake"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,bmi,bmi2,clflushopt,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("skylake-avx512"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bw,avx512cd,avx512dq,avx512f,avx512vl,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,faster-shift-than-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("skylake_avx512"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bw,avx512cd,avx512dq,avx512f,avx512vl,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,faster-shift-than-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("slm"), str_lit("32bit-mode,64bit,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-7bytenop,fast-movbe,fxsr,idivq-to-divl,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,rdrnd,sahf,slow-incdec,slow-lea,slow-pmulld,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-slm-arith-costs,vzeroupper,x87") }, + { str_lit("tigerlake"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vp2intersect,avx512vpopcntdq,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdpid,rdrnd,rdseed,sahf,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("tremont"), str_lit("32bit-mode,64bit,aes,clflushopt,clwb,cmov,crc32,cx16,cx8,fast-movbe,fsgsbase,fxsr,gfni,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,sha,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-glm-div-sqrt-costs,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("westmere"), str_lit("32bit-mode,64bit,cmov,crc32,cx16,cx8,fxsr,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,sahf,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87") }, + { str_lit("winchip-c6"), str_lit("32bit-mode,mmx,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("winchip2"), str_lit("32bit-mode,3dnow,mmx,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("x86-64"), str_lit("32bit-mode,64bit,cmov,cx8,fxsr,idivq-to-divl,macrofusion,mmx,nopl,slow-3ops-lea,slow-incdec,sse,sse2,vzeroupper,x87") }, + { str_lit("x86-64-v2"), str_lit("32bit-mode,64bit,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fxsr,idivq-to-divl,macrofusion,mmx,nopl,popcnt,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87") }, + { str_lit("x86-64-v3"), str_lit("32bit-mode,64bit,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fxsr,idivq-to-divl,lzcnt,macrofusion,mmx,movbe,nopl,popcnt,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave") }, + { str_lit("x86-64-v4"), str_lit("32bit-mode,64bit,allow-light-256-bit,avx,avx2,avx512bw,avx512cd,avx512dq,avx512f,avx512vl,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fxsr,idivq-to-divl,lzcnt,macrofusion,mmx,movbe,nopl,popcnt,prefer-256-bit,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave") }, + { str_lit("yonah"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, + { str_lit("znver1"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,bmi,bmi2,branchfusion,clflushopt,clzero,cmov,crc32,cx16,cx8,f16c,fast-15bytenop,fast-bextr,fast-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,lzcnt,mmx,movbe,mwaitx,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,sbb-dep-breaking,sha,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("znver2"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,bmi,bmi2,branchfusion,clflushopt,clwb,clzero,cmov,crc32,cx16,cx8,f16c,fast-15bytenop,fast-bextr,fast-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,lzcnt,mmx,movbe,mwaitx,nopl,pclmul,popcnt,prfchw,rdpid,rdpru,rdrnd,rdseed,sahf,sbb-dep-breaking,sha,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,vzeroupper,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("znver3"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,bmi,bmi2,branchfusion,clflushopt,clwb,clzero,cmov,crc32,cx16,cx8,f16c,fast-15bytenop,fast-bextr,fast-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,invpcid,lzcnt,macrofusion,mmx,movbe,mwaitx,nopl,pclmul,pku,popcnt,prfchw,rdpid,rdpru,rdrnd,rdseed,sahf,sbb-dep-breaking,sha,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,vaes,vpclmulqdq,vzeroupper,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("znver4"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,bmi,bmi2,branchfusion,clflushopt,clwb,clzero,cmov,crc32,cx16,cx8,evex512,f16c,fast-15bytenop,fast-bextr,fast-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,invpcid,lzcnt,macrofusion,mmx,movbe,mwaitx,nopl,pclmul,pku,popcnt,prfchw,rdpid,rdpru,rdrnd,rdseed,sahf,sbb-dep-breaking,sha,shstk,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,vaes,vpclmulqdq,vzeroupper,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + // TargetArch_arm32: + { str_lit("arm1020e"), str_lit("armv5te,v4t,v5t,v5te") }, + { str_lit("arm1020t"), str_lit("armv5t,v4t,v5t") }, + { str_lit("arm1022e"), str_lit("armv5te,v4t,v5t,v5te") }, + { str_lit("arm10e"), str_lit("armv5te,v4t,v5t,v5te") }, + { str_lit("arm10tdmi"), str_lit("armv5t,v4t,v5t") }, + { str_lit("arm1136j-s"), str_lit("armv6,dsp,v4t,v5t,v5te,v6") }, + { str_lit("arm1136jf-s"), str_lit("armv6,dsp,fp64,fpregs,fpregs64,slowfpvmlx,v4t,v5t,v5te,v6,vfp2,vfp2sp") }, + { str_lit("arm1156t2-s"), str_lit("armv6t2,dsp,thumb2,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v8m") }, + { str_lit("arm1156t2f-s"), str_lit("armv6t2,dsp,fp64,fpregs,fpregs64,slowfpvmlx,thumb2,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v8m,vfp2,vfp2sp") }, + { str_lit("arm1176jz-s"), str_lit("armv6kz,trustzone,v4t,v5t,v5te,v6,v6k") }, + { str_lit("arm1176jzf-s"), str_lit("armv6kz,fp64,fpregs,fpregs64,slowfpvmlx,trustzone,v4t,v5t,v5te,v6,v6k,vfp2,vfp2sp") }, + { str_lit("arm710t"), str_lit("armv4t,v4t") }, + { str_lit("arm720t"), str_lit("armv4t,v4t") }, + { str_lit("arm7tdmi"), str_lit("armv4t,v4t") }, + { str_lit("arm7tdmi-s"), str_lit("armv4t,v4t") }, + { str_lit("arm8"), str_lit("armv4") }, + { str_lit("arm810"), str_lit("armv4") }, + { str_lit("arm9"), str_lit("armv4t,v4t") }, + { str_lit("arm920"), str_lit("armv4t,v4t") }, + { str_lit("arm920t"), str_lit("armv4t,v4t") }, + { str_lit("arm922t"), str_lit("armv4t,v4t") }, + { str_lit("arm926ej-s"), str_lit("armv5te,v4t,v5t,v5te") }, + { str_lit("arm940t"), str_lit("armv4t,v4t") }, + { str_lit("arm946e-s"), str_lit("armv5te,v4t,v5t,v5te") }, + { str_lit("arm966e-s"), str_lit("armv5te,v4t,v5t,v5te") }, + { str_lit("arm968e-s"), str_lit("armv5te,v4t,v5t,v5te") }, + { str_lit("arm9e"), str_lit("armv5te,v4t,v5t,v5te") }, + { str_lit("arm9tdmi"), str_lit("armv4t,v4t") }, + { str_lit("cortex-a12"), str_lit("a12,aclass,armv7-a,avoid-partial-cpsr,d32,db,dsp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,ret-addr-stack,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization,vmlx-forwarding") }, + { str_lit("cortex-a15"), str_lit("a15,aclass,armv7-a,avoid-partial-cpsr,d32,db,dont-widen-vmovs,dsp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,muxed-units,neon,perfmon,ret-addr-stack,splat-vfp-neon,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization,vldn-align") }, + { str_lit("cortex-a17"), str_lit("a17,aclass,armv7-a,avoid-partial-cpsr,d32,db,dsp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,ret-addr-stack,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization,vmlx-forwarding") }, + { str_lit("cortex-a32"), str_lit("aclass,acquire-release,aes,armv8-a,crc,crypto,d32,db,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("cortex-a35"), str_lit("a35,aclass,acquire-release,aes,armv8-a,crc,crypto,d32,db,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("cortex-a5"), str_lit("a5,aclass,armv7-a,d32,db,dsp,fp16,fp64,fpregs,fpregs64,mp,neon,perfmon,ret-addr-stack,slow-fp-brcc,slowfpvfmx,slowfpvmlx,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,vmlx-forwarding") }, + { str_lit("cortex-a53"), str_lit("a53,aclass,acquire-release,aes,armv8-a,crc,crypto,d32,db,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpao,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("cortex-a55"), str_lit("a55,aclass,acquire-release,aes,armv8.2-a,crc,crypto,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,ras,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("cortex-a57"), str_lit("a57,aclass,acquire-release,aes,armv8-a,avoid-partial-cpsr,cheap-predicable-cpsr,crc,crypto,d32,db,dsp,fix-cortex-a57-aes-1742098,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpao,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("cortex-a7"), str_lit("a7,aclass,armv7-a,d32,db,dsp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,ret-addr-stack,slow-fp-brcc,slowfpvfmx,slowfpvmlx,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization,vmlx-forwarding,vmlx-hazards") }, + { str_lit("cortex-a710"), str_lit("aclass,acquire-release,armv9-a,bf16,cortex-a710,crc,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp16fml,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,hwdiv-arm,i8mm,mp,neon,perfmon,ras,sb,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8m,v9a,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("cortex-a72"), str_lit("a72,aclass,acquire-release,aes,armv8-a,crc,crypto,d32,db,dsp,fix-cortex-a57-aes-1742098,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("cortex-a73"), str_lit("a73,aclass,acquire-release,aes,armv8-a,crc,crypto,d32,db,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("cortex-a75"), str_lit("a75,aclass,acquire-release,aes,armv8.2-a,crc,crypto,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,ras,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("cortex-a76"), str_lit("a76,aclass,acquire-release,aes,armv8.2-a,crc,crypto,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,hwdiv-arm,mp,neon,perfmon,ras,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("cortex-a76ae"), str_lit("a76,aclass,acquire-release,aes,armv8.2-a,crc,crypto,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,hwdiv-arm,mp,neon,perfmon,ras,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("cortex-a77"), str_lit("a77,aclass,acquire-release,aes,armv8.2-a,crc,crypto,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,hwdiv-arm,mp,neon,perfmon,ras,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("cortex-a78"), str_lit("aclass,acquire-release,aes,armv8.2-a,cortex-a78,crc,crypto,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,hwdiv-arm,mp,neon,perfmon,ras,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("cortex-a78c"), str_lit("a78c,aclass,acquire-release,aes,armv8.2-a,crc,crypto,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,hwdiv-arm,mp,neon,perfmon,ras,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("cortex-a8"), str_lit("a8,aclass,armv7-a,d32,db,dsp,fp64,fpregs,fpregs64,neon,nonpipelined-vfp,perfmon,ret-addr-stack,slow-fp-brcc,slowfpvfmx,slowfpvmlx,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vmlx-forwarding,vmlx-hazards") }, + { str_lit("cortex-a9"), str_lit("a9,aclass,armv7-a,avoid-partial-cpsr,d32,db,dsp,expand-fp-mlx,fp16,fp64,fpregs,fpregs64,mp,muxed-units,neon,neon-fpmovs,perfmon,prefer-vmovsr,ret-addr-stack,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vldn-align,vmlx-forwarding,vmlx-hazards") }, + { str_lit("cortex-m0"), str_lit("armv6-m,db,mclass,no-branch-predictor,noarm,strict-align,thumb-mode,v4t,v5t,v5te,v6,v6m") }, + { str_lit("cortex-m0plus"), str_lit("armv6-m,db,mclass,no-branch-predictor,noarm,strict-align,thumb-mode,v4t,v5t,v5te,v6,v6m") }, + { str_lit("cortex-m1"), str_lit("armv6-m,db,mclass,no-branch-predictor,noarm,strict-align,thumb-mode,v4t,v5t,v5te,v6,v6m") }, + { str_lit("cortex-m23"), str_lit("8msecext,acquire-release,armv8-m.base,db,hwdiv,mclass,no-branch-predictor,no-movt,noarm,strict-align,thumb-mode,v4t,v5t,v5te,v6,v6m,v7clrex,v8m") }, + { str_lit("cortex-m3"), str_lit("armv7-m,db,hwdiv,loop-align,m3,mclass,no-branch-predictor,noarm,thumb-mode,thumb2,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m") }, + { str_lit("cortex-m33"), str_lit("8msecext,acquire-release,armv8-m.main,db,dsp,fix-cmse-cve-2021-35465,fp-armv8d16sp,fp16,fpregs,hwdiv,loop-align,mclass,no-branch-predictor,noarm,slowfpvfmx,slowfpvmlx,thumb-mode,thumb2,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,v8m.main,vfp2sp,vfp3d16sp,vfp4d16sp") }, + { str_lit("cortex-m35p"), str_lit("8msecext,acquire-release,armv8-m.main,db,dsp,fix-cmse-cve-2021-35465,fp-armv8d16sp,fp16,fpregs,hwdiv,loop-align,mclass,no-branch-predictor,noarm,slowfpvfmx,slowfpvmlx,thumb-mode,thumb2,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,v8m.main,vfp2sp,vfp3d16sp,vfp4d16sp") }, + { str_lit("cortex-m4"), str_lit("armv7e-m,db,dsp,fp16,fpregs,hwdiv,loop-align,mclass,no-branch-predictor,noarm,slowfpvfmx,slowfpvmlx,thumb-mode,thumb2,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2sp,vfp3d16sp,vfp4d16sp") }, + { str_lit("cortex-m55"), str_lit("8msecext,acquire-release,armv8.1-m.main,db,dsp,fix-cmse-cve-2021-35465,fp-armv8d16,fp-armv8d16sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,lob,loop-align,mclass,mve,mve.fp,no-branch-predictor,noarm,ras,slowfpvmlx,thumb-mode,thumb2,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8.1m.main,v8m,v8m.main,vfp2,vfp2sp,vfp3d16,vfp3d16sp,vfp4d16,vfp4d16sp") }, + { str_lit("cortex-m7"), str_lit("armv7e-m,db,dsp,fp-armv8d16,fp-armv8d16sp,fp16,fp64,fpregs,fpregs64,hwdiv,m7,mclass,noarm,thumb-mode,thumb2,use-mipipeliner,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3d16,vfp3d16sp,vfp4d16,vfp4d16sp") }, + { str_lit("cortex-m85"), str_lit("8msecext,acquire-release,armv8.1-m.main,db,dsp,fp-armv8d16,fp-armv8d16sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,lob,mclass,mve,mve.fp,noarm,pacbti,ras,thumb-mode,thumb2,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8.1m.main,v8m,v8m.main,vfp2,vfp2sp,vfp3d16,vfp3d16sp,vfp4d16,vfp4d16sp") }, + { str_lit("cortex-r4"), str_lit("armv7-r,avoid-partial-cpsr,db,dsp,hwdiv,perfmon,r4,rclass,ret-addr-stack,thumb2,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m") }, + { str_lit("cortex-r4f"), str_lit("armv7-r,avoid-partial-cpsr,db,dsp,fp64,fpregs,fpregs64,hwdiv,perfmon,r4,rclass,ret-addr-stack,slow-fp-brcc,slowfpvfmx,slowfpvmlx,thumb2,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3d16,vfp3d16sp") }, + { str_lit("cortex-r5"), str_lit("armv7-r,avoid-partial-cpsr,db,dsp,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,perfmon,r5,rclass,ret-addr-stack,slow-fp-brcc,slowfpvfmx,slowfpvmlx,thumb2,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3d16,vfp3d16sp") }, + { str_lit("cortex-r52"), str_lit("acquire-release,armv8-r,crc,d32,db,dfb,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpao,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,r52,rclass,thumb2,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("cortex-r7"), str_lit("armv7-r,avoid-partial-cpsr,db,dsp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,perfmon,r7,rclass,ret-addr-stack,slow-fp-brcc,slowfpvfmx,slowfpvmlx,thumb2,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3d16,vfp3d16sp") }, + { str_lit("cortex-r8"), str_lit("armv7-r,avoid-partial-cpsr,db,dsp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,perfmon,rclass,ret-addr-stack,slow-fp-brcc,slowfpvfmx,slowfpvmlx,thumb2,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3d16,vfp3d16sp") }, + { str_lit("cortex-x1"), str_lit("aclass,acquire-release,aes,armv8.2-a,cortex-x1,crc,crypto,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,hwdiv-arm,mp,neon,perfmon,ras,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("cortex-x1c"), str_lit("aclass,acquire-release,aes,armv8.2-a,cortex-x1c,crc,crypto,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,hwdiv-arm,mp,neon,perfmon,ras,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("cyclone"), str_lit("aclass,acquire-release,aes,armv8-a,avoid-movs-shop,avoid-partial-cpsr,crc,crypto,d32,db,disable-postra-scheduler,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,neonfp,perfmon,ret-addr-stack,sha2,slowfpvfmx,slowfpvmlx,swift,thumb2,trustzone,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization,zcz") }, + { str_lit("ep9312"), str_lit("armv4t,v4t") }, + { str_lit("exynos-m3"), str_lit("aclass,acquire-release,aes,armv8-a,crc,crypto,d32,db,dont-widen-vmovs,dsp,expand-fp-mlx,exynos,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs64,fuse-aes,fuse-literals,hwdiv,hwdiv-arm,mp,neon,perfmon,prof-unpr,ret-addr-stack,sha2,slow-fp-brcc,slow-vdup32,slow-vgetlni32,slowfpvfmx,slowfpvmlx,splat-vfp-neon,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization,wide-stride-vfp,zcz") }, + { str_lit("exynos-m4"), str_lit("aclass,acquire-release,aes,armv8.2-a,crc,crypto,d32,db,dont-widen-vmovs,dotprod,dsp,expand-fp-mlx,exynos,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,fuse-aes,fuse-literals,hwdiv,hwdiv-arm,mp,neon,perfmon,prof-unpr,ras,ret-addr-stack,sha2,slow-fp-brcc,slow-vdup32,slow-vgetlni32,slowfpvfmx,slowfpvmlx,splat-vfp-neon,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization,wide-stride-vfp,zcz") }, + { str_lit("exynos-m5"), str_lit("aclass,acquire-release,aes,armv8.2-a,crc,crypto,d32,db,dont-widen-vmovs,dotprod,dsp,expand-fp-mlx,exynos,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,fuse-aes,fuse-literals,hwdiv,hwdiv-arm,mp,neon,perfmon,prof-unpr,ras,ret-addr-stack,sha2,slow-fp-brcc,slow-vdup32,slow-vgetlni32,slowfpvfmx,slowfpvmlx,splat-vfp-neon,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization,wide-stride-vfp,zcz") }, + { str_lit("generic"), str_lit("") }, + { str_lit("iwmmxt"), str_lit("armv5te,v4t,v5t,v5te") }, + { str_lit("krait"), str_lit("aclass,armv7-a,avoid-partial-cpsr,d32,db,dsp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,krait,muxed-units,neon,perfmon,ret-addr-stack,thumb2,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,vldn-align,vmlx-forwarding") }, + { str_lit("kryo"), str_lit("aclass,acquire-release,aes,armv8-a,crc,crypto,d32,db,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,kryo,mp,neon,perfmon,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("mpcore"), str_lit("armv6k,fp64,fpregs,fpregs64,slowfpvmlx,v4t,v5t,v5te,v6,v6k,vfp2,vfp2sp") }, + { str_lit("mpcorenovfp"), str_lit("armv6k,v4t,v5t,v5te,v6,v6k") }, + { str_lit("neoverse-n1"), str_lit("aclass,acquire-release,aes,armv8.2-a,crc,crypto,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,ras,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("neoverse-n2"), str_lit("aclass,acquire-release,armv9-a,bf16,crc,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,i8mm,mp,neon,perfmon,ras,sb,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8m,v9a,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("neoverse-v1"), str_lit("aclass,acquire-release,aes,armv8.4-a,bf16,crc,crypto,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,hwdiv-arm,i8mm,mp,neon,perfmon,ras,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8.3a,v8.4a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("sc000"), str_lit("armv6-m,db,mclass,no-branch-predictor,noarm,strict-align,thumb-mode,v4t,v5t,v5te,v6,v6m") }, + { str_lit("sc300"), str_lit("armv7-m,db,hwdiv,m3,mclass,no-branch-predictor,noarm,thumb-mode,thumb2,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m") }, + { str_lit("strongarm"), str_lit("armv4") }, + { str_lit("strongarm110"), str_lit("armv4") }, + { str_lit("strongarm1100"), str_lit("armv4") }, + { str_lit("strongarm1110"), str_lit("armv4") }, + { str_lit("swift"), str_lit("aclass,armv7-a,avoid-movs-shop,avoid-partial-cpsr,d32,db,disable-postra-scheduler,dsp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,neonfp,perfmon,prefer-ishst,prof-unpr,ret-addr-stack,slow-load-D-subreg,slow-odd-reg,slow-vdup32,slow-vgetlni32,slowfpvfmx,slowfpvmlx,swift,thumb2,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,vmlx-hazards,wide-stride-vfp") }, + { str_lit("xscale"), str_lit("armv5te,v4t,v5t,v5te") }, + // TargetArch_arm64: + { str_lit("a64fx"), str_lit("CONTEXTIDREL2,a64fx,aggressive-fma,arith-bcc-fusion,ccpp,complxnum,crc,el2vmsa,el3,fp-armv8,fullfp16,lor,lse,neon,pan,pan-rwv,perfmon,predictable-select-expensive,ras,rdm,sha2,store-pair-suppress,sve,uaops,use-postra-scheduler,v8.1a,v8.2a,v8a,vh") }, + { str_lit("ampere1"), str_lit("CONTEXTIDREL2,addr-lsl-fast,aes,aggressive-fma,altnzcv,alu-lsl-fast,am,ampere1,amvs,arith-bcc-fusion,bf16,bti,ccdp,ccidx,ccpp,cmp-bcc-fusion,complxnum,crc,dit,dotprod,ecv,el2vmsa,el3,fgt,flagm,fp-armv8,fptoint,fuse-address,fuse-aes,fuse-literals,i8mm,jsconv,ldp-aligned-only,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,predres,rand,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,specrestrict,ssbs,store-pair-suppress,stp-aligned-only,tlb-rmi,tracev8.4,uaops,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8a,vh") }, + { str_lit("ampere1a"), str_lit("CONTEXTIDREL2,addr-lsl-fast,aes,aggressive-fma,altnzcv,alu-lsl-fast,am,ampere1a,amvs,arith-bcc-fusion,bf16,bti,ccdp,ccidx,ccpp,cmp-bcc-fusion,complxnum,crc,dit,dotprod,ecv,el2vmsa,el3,fgt,flagm,fp-armv8,fptoint,fuse-address,fuse-aes,fuse-literals,i8mm,jsconv,ldp-aligned-only,lor,lse,lse2,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predres,rand,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,sm4,specrestrict,ssbs,store-pair-suppress,stp-aligned-only,tlb-rmi,tracev8.4,uaops,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8a,vh") }, + { str_lit("apple-a10"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,apple-a10,arith-bcc-fusion,arith-cbz-fusion,crc,crypto,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fuse-aes,fuse-crypto-eor,lor,neon,pan,perfmon,rdm,sha2,store-pair-suppress,v8a,vh,zcm,zcz,zcz-gp") }, + { str_lit("apple-a11"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,apple-a11,arith-bcc-fusion,arith-cbz-fusion,ccpp,crc,crypto,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fullfp16,fuse-aes,fuse-crypto-eor,lor,lse,neon,pan,pan-rwv,perfmon,ras,rdm,sha2,store-pair-suppress,uaops,v8.1a,v8.2a,v8a,vh,zcm,zcz,zcz-gp") }, + { str_lit("apple-a12"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,apple-a12,arith-bcc-fusion,arith-cbz-fusion,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fullfp16,fuse-aes,fuse-crypto-eor,jsconv,lor,lse,neon,pan,pan-rwv,pauth,perfmon,ras,rcpc,rdm,sha2,store-pair-suppress,uaops,v8.1a,v8.2a,v8.3a,v8a,vh,zcm,zcz,zcz-gp") }, + { str_lit("apple-a13"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,am,apple-a13,arith-bcc-fusion,arith-cbz-fusion,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,dit,dotprod,el2vmsa,el3,flagm,fp-armv8,fp16fml,fullfp16,fuse-aes,fuse-crypto-eor,jsconv,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,ras,rcpc,rcpc-immo,rdm,sel2,sha2,sha3,store-pair-suppress,tlb-rmi,tracev8.4,uaops,v8.1a,v8.2a,v8.3a,v8.4a,v8a,vh,zcm,zcz,zcz-gp") }, + { str_lit("apple-a14"), str_lit("CONTEXTIDREL2,aes,aggressive-fma,alternate-sextload-cvt-f32-pattern,altnzcv,am,apple-a14,arith-bcc-fusion,arith-cbz-fusion,ccdp,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,dit,dotprod,el2vmsa,el3,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-address,fuse-adrp-add,fuse-aes,fuse-arith-logic,fuse-crypto-eor,fuse-csel,fuse-literals,jsconv,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,specrestrict,ssbs,store-pair-suppress,tlb-rmi,tracev8.4,uaops,v8.1a,v8.2a,v8.3a,v8.4a,v8a,vh,zcm,zcz,zcz-gp") }, + { str_lit("apple-a15"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,altnzcv,am,amvs,apple-a15,arith-bcc-fusion,arith-cbz-fusion,bf16,bti,ccdp,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,dit,dotprod,ecv,el2vmsa,el3,fgt,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-address,fuse-aes,fuse-arith-logic,fuse-crypto-eor,fuse-csel,fuse-literals,i8mm,jsconv,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,specrestrict,ssbs,store-pair-suppress,tlb-rmi,tracev8.4,uaops,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8a,vh,zcm,zcz,zcz-gp") }, + { str_lit("apple-a16"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,altnzcv,am,amvs,apple-a16,arith-bcc-fusion,arith-cbz-fusion,bf16,bti,ccdp,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,dit,dotprod,ecv,el2vmsa,el3,fgt,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-address,fuse-aes,fuse-arith-logic,fuse-crypto-eor,fuse-csel,fuse-literals,hcx,i8mm,jsconv,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,specrestrict,ssbs,store-pair-suppress,tlb-rmi,tracev8.4,uaops,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8a,vh,zcm,zcz,zcz-gp") }, + { str_lit("apple-a7"), str_lit("aes,alternate-sextload-cvt-f32-pattern,apple-a7,apple-a7-sysreg,arith-bcc-fusion,arith-cbz-fusion,crypto,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fuse-aes,fuse-crypto-eor,neon,perfmon,sha2,store-pair-suppress,v8a,zcm,zcz,zcz-fp-workaround,zcz-gp") }, + { str_lit("apple-a8"), str_lit("aes,alternate-sextload-cvt-f32-pattern,apple-a7,apple-a7-sysreg,arith-bcc-fusion,arith-cbz-fusion,crypto,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fuse-aes,fuse-crypto-eor,neon,perfmon,sha2,store-pair-suppress,v8a,zcm,zcz,zcz-fp-workaround,zcz-gp") }, + { str_lit("apple-a9"), str_lit("aes,alternate-sextload-cvt-f32-pattern,apple-a7,apple-a7-sysreg,arith-bcc-fusion,arith-cbz-fusion,crypto,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fuse-aes,fuse-crypto-eor,neon,perfmon,sha2,store-pair-suppress,v8a,zcm,zcz,zcz-fp-workaround,zcz-gp") }, + { str_lit("apple-latest"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,altnzcv,am,amvs,apple-a16,arith-bcc-fusion,arith-cbz-fusion,bf16,bti,ccdp,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,dit,dotprod,ecv,el2vmsa,el3,fgt,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-address,fuse-aes,fuse-arith-logic,fuse-crypto-eor,fuse-csel,fuse-literals,hcx,i8mm,jsconv,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,specrestrict,ssbs,store-pair-suppress,tlb-rmi,tracev8.4,uaops,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8a,vh,zcm,zcz,zcz-gp") }, + { str_lit("apple-m1"), str_lit("CONTEXTIDREL2,aes,aggressive-fma,alternate-sextload-cvt-f32-pattern,altnzcv,am,apple-a14,arith-bcc-fusion,arith-cbz-fusion,ccdp,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,dit,dotprod,el2vmsa,el3,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-address,fuse-adrp-add,fuse-aes,fuse-arith-logic,fuse-crypto-eor,fuse-csel,fuse-literals,jsconv,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,specrestrict,ssbs,store-pair-suppress,tlb-rmi,tracev8.4,uaops,v8.1a,v8.2a,v8.3a,v8.4a,v8a,vh,zcm,zcz,zcz-gp") }, + { str_lit("apple-m2"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,altnzcv,am,amvs,apple-a15,arith-bcc-fusion,arith-cbz-fusion,bf16,bti,ccdp,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,dit,dotprod,ecv,el2vmsa,el3,fgt,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-address,fuse-aes,fuse-arith-logic,fuse-crypto-eor,fuse-csel,fuse-literals,i8mm,jsconv,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,specrestrict,ssbs,store-pair-suppress,tlb-rmi,tracev8.4,uaops,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8a,vh,zcm,zcz,zcz-gp") }, + { str_lit("apple-s4"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,apple-a12,arith-bcc-fusion,arith-cbz-fusion,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fullfp16,fuse-aes,fuse-crypto-eor,jsconv,lor,lse,neon,pan,pan-rwv,pauth,perfmon,ras,rcpc,rdm,sha2,store-pair-suppress,uaops,v8.1a,v8.2a,v8.3a,v8a,vh,zcm,zcz,zcz-gp") }, + { str_lit("apple-s5"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,apple-a12,arith-bcc-fusion,arith-cbz-fusion,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fullfp16,fuse-aes,fuse-crypto-eor,jsconv,lor,lse,neon,pan,pan-rwv,pauth,perfmon,ras,rcpc,rdm,sha2,store-pair-suppress,uaops,v8.1a,v8.2a,v8.3a,v8a,vh,zcm,zcz,zcz-gp") }, + { str_lit("carmel"), str_lit("CONTEXTIDREL2,aes,carmel,ccpp,crc,crypto,el2vmsa,el3,fp-armv8,fullfp16,lor,lse,neon,pan,pan-rwv,ras,rdm,sha2,uaops,v8.1a,v8.2a,v8a,vh") }, + { str_lit("cortex-a34"), str_lit("a35,aes,crc,crypto,el2vmsa,el3,fp-armv8,neon,perfmon,sha2,v8a") }, + { str_lit("cortex-a35"), str_lit("a35,aes,crc,crypto,el2vmsa,el3,fp-armv8,neon,perfmon,sha2,v8a") }, + { str_lit("cortex-a510"), str_lit("CONTEXTIDREL2,a510,altnzcv,am,bf16,bti,ccdp,ccidx,ccpp,complxnum,crc,dit,dotprod,el2vmsa,el3,ete,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mec,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,rme,sb,sel2,specrestrict,ssbs,sve,sve2,sve2-bitperm,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,use-scalar-inc-vl,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") }, + { str_lit("cortex-a53"), str_lit("a53,aes,balance-fp-ops,crc,crypto,el2vmsa,el3,fp-armv8,fuse-adrp-add,fuse-aes,neon,perfmon,sha2,use-postra-scheduler,v8a") }, + { str_lit("cortex-a55"), str_lit("CONTEXTIDREL2,a55,aes,ccpp,crc,crypto,dotprod,el2vmsa,el3,fp-armv8,fullfp16,fuse-address,fuse-adrp-add,fuse-aes,lor,lse,neon,pan,pan-rwv,perfmon,ras,rcpc,rdm,sha2,uaops,use-postra-scheduler,v8.1a,v8.2a,v8a,vh") }, + { str_lit("cortex-a57"), str_lit("a57,aes,balance-fp-ops,crc,crypto,el2vmsa,el3,enable-select-opt,fp-armv8,fuse-adrp-add,fuse-aes,fuse-literals,neon,perfmon,predictable-select-expensive,sha2,use-postra-scheduler,v8a") }, + { str_lit("cortex-a65"), str_lit("CONTEXTIDREL2,a65,aes,ccpp,crc,crypto,dotprod,el2vmsa,el3,enable-select-opt,fp-armv8,fullfp16,fuse-address,fuse-adrp-add,fuse-aes,fuse-literals,lor,lse,neon,pan,pan-rwv,perfmon,predictable-select-expensive,ras,rcpc,rdm,sha2,ssbs,uaops,v8.1a,v8.2a,v8a,vh") }, + { str_lit("cortex-a65ae"), str_lit("CONTEXTIDREL2,a65,aes,ccpp,crc,crypto,dotprod,el2vmsa,el3,enable-select-opt,fp-armv8,fullfp16,fuse-address,fuse-adrp-add,fuse-aes,fuse-literals,lor,lse,neon,pan,pan-rwv,perfmon,predictable-select-expensive,ras,rcpc,rdm,sha2,ssbs,uaops,v8.1a,v8.2a,v8a,vh") }, + { str_lit("cortex-a710"), str_lit("CONTEXTIDREL2,a710,addr-lsl-fast,altnzcv,alu-lsl-fast,am,bf16,bti,ccdp,ccidx,ccpp,cmp-bcc-fusion,complxnum,crc,dit,dotprod,el2vmsa,el3,enable-select-opt,ete,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mec,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,ras,rcpc,rcpc-immo,rdm,rme,sb,sel2,specrestrict,ssbs,sve,sve2,sve2-bitperm,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,use-scalar-inc-vl,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") }, + { str_lit("cortex-a715"), str_lit("CONTEXTIDREL2,a715,addr-lsl-fast,altnzcv,alu-lsl-fast,am,bf16,bti,ccdp,ccidx,ccpp,cmp-bcc-fusion,complxnum,crc,dit,dotprod,el2vmsa,el3,enable-select-opt,ete,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mec,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,ras,rcpc,rcpc-immo,rdm,rme,sb,sel2,spe,specrestrict,ssbs,sve,sve2,sve2-bitperm,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,use-scalar-inc-vl,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") }, + { str_lit("cortex-a72"), str_lit("a72,aes,crc,crypto,el2vmsa,el3,enable-select-opt,fp-armv8,fuse-adrp-add,fuse-aes,fuse-literals,neon,perfmon,predictable-select-expensive,sha2,v8a") }, + { str_lit("cortex-a73"), str_lit("a73,aes,crc,crypto,el2vmsa,el3,enable-select-opt,fp-armv8,fuse-adrp-add,fuse-aes,neon,perfmon,predictable-select-expensive,sha2,v8a") }, + { str_lit("cortex-a75"), str_lit("CONTEXTIDREL2,a75,aes,ccpp,crc,crypto,dotprod,el2vmsa,el3,enable-select-opt,fp-armv8,fullfp16,fuse-adrp-add,fuse-aes,lor,lse,neon,pan,pan-rwv,perfmon,predictable-select-expensive,ras,rcpc,rdm,sha2,uaops,v8.1a,v8.2a,v8a,vh") }, + { str_lit("cortex-a76"), str_lit("CONTEXTIDREL2,a76,addr-lsl-fast,aes,alu-lsl-fast,ccpp,crc,crypto,dotprod,el2vmsa,el3,enable-select-opt,fp-armv8,fullfp16,fuse-adrp-add,fuse-aes,lor,lse,neon,pan,pan-rwv,perfmon,predictable-select-expensive,ras,rcpc,rdm,sha2,ssbs,uaops,v8.1a,v8.2a,v8a,vh") }, + { str_lit("cortex-a76ae"), str_lit("CONTEXTIDREL2,a76,addr-lsl-fast,aes,alu-lsl-fast,ccpp,crc,crypto,dotprod,el2vmsa,el3,enable-select-opt,fp-armv8,fullfp16,fuse-adrp-add,fuse-aes,lor,lse,neon,pan,pan-rwv,perfmon,predictable-select-expensive,ras,rcpc,rdm,sha2,ssbs,uaops,v8.1a,v8.2a,v8a,vh") }, + { str_lit("cortex-a77"), str_lit("CONTEXTIDREL2,a77,addr-lsl-fast,aes,alu-lsl-fast,ccpp,cmp-bcc-fusion,crc,crypto,dotprod,el2vmsa,el3,enable-select-opt,fp-armv8,fullfp16,fuse-adrp-add,fuse-aes,lor,lse,neon,pan,pan-rwv,perfmon,predictable-select-expensive,ras,rcpc,rdm,sha2,ssbs,uaops,v8.1a,v8.2a,v8a,vh") }, + { str_lit("cortex-a78"), str_lit("CONTEXTIDREL2,a78,addr-lsl-fast,aes,alu-lsl-fast,ccpp,cmp-bcc-fusion,crc,crypto,dotprod,el2vmsa,el3,enable-select-opt,fp-armv8,fullfp16,fuse-adrp-add,fuse-aes,lor,lse,neon,pan,pan-rwv,perfmon,predictable-select-expensive,ras,rcpc,rdm,sha2,spe,ssbs,uaops,use-postra-scheduler,v8.1a,v8.2a,v8a,vh") }, + { str_lit("cortex-a78c"), str_lit("CONTEXTIDREL2,a78c,addr-lsl-fast,aes,alu-lsl-fast,ccpp,cmp-bcc-fusion,crc,crypto,dotprod,el2vmsa,el3,enable-select-opt,flagm,fp-armv8,fullfp16,fuse-adrp-add,fuse-aes,lor,lse,neon,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,ras,rcpc,rdm,sha2,spe,ssbs,uaops,use-postra-scheduler,v8.1a,v8.2a,v8a,vh") }, + { str_lit("cortex-r82"), str_lit("CONTEXTIDREL2,ccidx,ccpp,complxnum,cortex-r82,crc,dit,dotprod,flagm,fp-armv8,fp16fml,fullfp16,jsconv,lse,neon,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,specrestrict,ssbs,tlb-rmi,tracev8.4,uaops,use-postra-scheduler,v8r") }, + { str_lit("cortex-x1"), str_lit("CONTEXTIDREL2,addr-lsl-fast,aes,alu-lsl-fast,ccpp,cmp-bcc-fusion,cortex-x1,crc,crypto,dotprod,el2vmsa,el3,enable-select-opt,fp-armv8,fullfp16,fuse-adrp-add,fuse-aes,lor,lse,neon,pan,pan-rwv,perfmon,predictable-select-expensive,ras,rcpc,rdm,sha2,spe,ssbs,uaops,use-postra-scheduler,v8.1a,v8.2a,v8a,vh") }, + { str_lit("cortex-x1c"), str_lit("CONTEXTIDREL2,addr-lsl-fast,aes,alu-lsl-fast,ccpp,cmp-bcc-fusion,cortex-x1,crc,crypto,dotprod,el2vmsa,el3,enable-select-opt,flagm,fp-armv8,fullfp16,fuse-adrp-add,fuse-aes,lor,lse,lse2,neon,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,ras,rcpc,rcpc-immo,rdm,sha2,spe,ssbs,uaops,use-postra-scheduler,v8.1a,v8.2a,v8a,vh") }, + { str_lit("cortex-x2"), str_lit("CONTEXTIDREL2,addr-lsl-fast,altnzcv,alu-lsl-fast,am,bf16,bti,ccdp,ccidx,ccpp,cmp-bcc-fusion,complxnum,cortex-x2,crc,dit,dotprod,el2vmsa,el3,enable-select-opt,ete,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mec,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,ras,rcpc,rcpc-immo,rdm,rme,sb,sel2,specrestrict,ssbs,sve,sve2,sve2-bitperm,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,use-scalar-inc-vl,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") }, + { str_lit("cortex-x3"), str_lit("CONTEXTIDREL2,addr-lsl-fast,altnzcv,alu-lsl-fast,am,bf16,bti,ccdp,ccidx,ccpp,complxnum,cortex-x3,crc,dit,dotprod,el2vmsa,el3,enable-select-opt,ete,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mec,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,ras,rcpc,rcpc-immo,rdm,rme,sb,sel2,spe,specrestrict,ssbs,sve,sve2,sve2-bitperm,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,use-scalar-inc-vl,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") }, + { str_lit("cyclone"), str_lit("aes,alternate-sextload-cvt-f32-pattern,apple-a7,apple-a7-sysreg,arith-bcc-fusion,arith-cbz-fusion,crypto,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fuse-aes,fuse-crypto-eor,neon,perfmon,sha2,store-pair-suppress,v8a,zcm,zcz,zcz-fp-workaround,zcz-gp") }, + { str_lit("exynos-m3"), str_lit("addr-lsl-fast,aes,alu-lsl-fast,crc,crypto,el2vmsa,el3,exynos-cheap-as-move,exynosm3,force-32bit-jump-tables,fp-armv8,fuse-address,fuse-adrp-add,fuse-aes,fuse-csel,fuse-literals,neon,perfmon,predictable-select-expensive,sha2,store-pair-suppress,use-postra-scheduler,v8a") }, + { str_lit("exynos-m4"), str_lit("CONTEXTIDREL2,addr-lsl-fast,aes,alu-lsl-fast,arith-bcc-fusion,arith-cbz-fusion,ccpp,crc,crypto,dotprod,el2vmsa,el3,exynos-cheap-as-move,exynosm4,force-32bit-jump-tables,fp-armv8,fullfp16,fuse-address,fuse-adrp-add,fuse-aes,fuse-arith-logic,fuse-csel,fuse-literals,lor,lse,neon,pan,pan-rwv,perfmon,ras,rdm,sha2,store-pair-suppress,uaops,use-postra-scheduler,v8.1a,v8.2a,v8a,vh,zcz,zcz-gp") }, + { str_lit("exynos-m5"), str_lit("CONTEXTIDREL2,addr-lsl-fast,aes,alu-lsl-fast,arith-bcc-fusion,arith-cbz-fusion,ccpp,crc,crypto,dotprod,el2vmsa,el3,exynos-cheap-as-move,exynosm4,force-32bit-jump-tables,fp-armv8,fullfp16,fuse-address,fuse-adrp-add,fuse-aes,fuse-arith-logic,fuse-csel,fuse-literals,lor,lse,neon,pan,pan-rwv,perfmon,ras,rdm,sha2,store-pair-suppress,uaops,use-postra-scheduler,v8.1a,v8.2a,v8a,vh,zcz,zcz-gp") }, + { str_lit("falkor"), str_lit("addr-lsl-fast,aes,alu-lsl-fast,crc,crypto,el2vmsa,el3,falkor,fp-armv8,neon,perfmon,predictable-select-expensive,rdm,sha2,slow-strqro-store,store-pair-suppress,use-postra-scheduler,v8a,zcz,zcz-gp") }, + { str_lit("generic"), str_lit("enable-select-opt,ete,fp-armv8,fuse-adrp-add,fuse-aes,neon,trbe,use-postra-scheduler") }, + { str_lit("kryo"), str_lit("addr-lsl-fast,aes,alu-lsl-fast,crc,crypto,el2vmsa,el3,fp-armv8,kryo,neon,perfmon,predictable-select-expensive,sha2,store-pair-suppress,use-postra-scheduler,v8a,zcz,zcz-gp") }, + { str_lit("neoverse-512tvb"), str_lit("CONTEXTIDREL2,addr-lsl-fast,aes,alu-lsl-fast,am,bf16,ccdp,ccidx,ccpp,complxnum,crc,crypto,dit,dotprod,el2vmsa,el3,enable-select-opt,flagm,fp-armv8,fp16fml,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mpam,neon,neoverse512tvb,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,rand,ras,rcpc,rcpc-immo,rdm,sel2,sha2,spe,ssbs,sve,tlb-rmi,tracev8.4,uaops,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8a,vh") }, + { str_lit("neoverse-e1"), str_lit("CONTEXTIDREL2,aes,ccpp,crc,crypto,dotprod,el2vmsa,el3,fp-armv8,fullfp16,fuse-adrp-add,fuse-aes,lor,lse,neon,neoversee1,pan,pan-rwv,perfmon,ras,rcpc,rdm,sha2,ssbs,uaops,use-postra-scheduler,v8.1a,v8.2a,v8a,vh") }, + { str_lit("neoverse-n1"), str_lit("CONTEXTIDREL2,addr-lsl-fast,aes,alu-lsl-fast,ccpp,crc,crypto,dotprod,el2vmsa,el3,enable-select-opt,fp-armv8,fullfp16,fuse-adrp-add,fuse-aes,lor,lse,neon,neoversen1,pan,pan-rwv,perfmon,predictable-select-expensive,ras,rcpc,rdm,sha2,spe,ssbs,uaops,use-postra-scheduler,v8.1a,v8.2a,v8a,vh") }, + { str_lit("neoverse-n2"), str_lit("CONTEXTIDREL2,addr-lsl-fast,altnzcv,alu-lsl-fast,am,bf16,bti,ccdp,ccidx,ccpp,complxnum,crc,dit,dotprod,el2vmsa,el3,enable-select-opt,ete,flagm,fp-armv8,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mec,mpam,mte,neon,neoversen2,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,ras,rcpc,rcpc-immo,rdm,rme,sb,sel2,specrestrict,ssbs,sve,sve2,sve2-bitperm,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,use-scalar-inc-vl,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") }, + { str_lit("neoverse-v1"), str_lit("CONTEXTIDREL2,addr-lsl-fast,aes,alu-lsl-fast,am,bf16,ccdp,ccidx,ccpp,complxnum,crc,crypto,dit,dotprod,el2vmsa,el3,enable-select-opt,flagm,fp-armv8,fp16fml,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mpam,neon,neoversev1,no-sve-fp-ld1r,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,rand,ras,rcpc,rcpc-immo,rdm,sel2,sha2,spe,ssbs,sve,tlb-rmi,tracev8.4,uaops,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8a,vh") }, + { str_lit("neoverse-v2"), str_lit("CONTEXTIDREL2,addr-lsl-fast,altnzcv,alu-lsl-fast,am,bf16,bti,ccdp,ccidx,ccpp,complxnum,crc,dit,dotprod,el2vmsa,el3,enable-select-opt,ete,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mec,mpam,mte,neon,neoversev2,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,rand,ras,rcpc,rcpc-immo,rdm,rme,sb,sel2,spe,specrestrict,ssbs,sve,sve2,sve2-bitperm,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,use-scalar-inc-vl,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") }, + { str_lit("saphira"), str_lit("CONTEXTIDREL2,addr-lsl-fast,aes,alu-lsl-fast,am,ccidx,ccpp,complxnum,crc,crypto,dit,dotprod,el2vmsa,el3,flagm,fp-armv8,jsconv,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,ras,rcpc,rcpc-immo,rdm,saphira,sel2,sha2,spe,store-pair-suppress,tlb-rmi,tracev8.4,uaops,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8a,vh,zcz,zcz-gp") }, + { str_lit("thunderx"), str_lit("aes,crc,crypto,el2vmsa,el3,fp-armv8,neon,perfmon,predictable-select-expensive,sha2,store-pair-suppress,thunderx,use-postra-scheduler,v8a") }, + { str_lit("thunderx2t99"), str_lit("CONTEXTIDREL2,aes,aggressive-fma,arith-bcc-fusion,crc,crypto,el2vmsa,el3,fp-armv8,lor,lse,neon,pan,predictable-select-expensive,rdm,sha2,store-pair-suppress,thunderx2t99,use-postra-scheduler,v8.1a,v8a,vh") }, + { str_lit("thunderx3t110"), str_lit("CONTEXTIDREL2,aes,aggressive-fma,arith-bcc-fusion,balance-fp-ops,ccidx,ccpp,complxnum,crc,crypto,el2vmsa,el3,fp-armv8,jsconv,lor,lse,neon,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,ras,rcpc,rdm,sha2,store-pair-suppress,strict-align,thunderx3t110,uaops,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8a,vh") }, + { str_lit("thunderxt81"), str_lit("aes,crc,crypto,el2vmsa,el3,fp-armv8,neon,perfmon,predictable-select-expensive,sha2,store-pair-suppress,thunderxt81,use-postra-scheduler,v8a") }, + { str_lit("thunderxt83"), str_lit("aes,crc,crypto,el2vmsa,el3,fp-armv8,neon,perfmon,predictable-select-expensive,sha2,store-pair-suppress,thunderxt83,use-postra-scheduler,v8a") }, + { str_lit("thunderxt88"), str_lit("aes,crc,crypto,el2vmsa,el3,fp-armv8,neon,perfmon,predictable-select-expensive,sha2,store-pair-suppress,thunderxt88,use-postra-scheduler,v8a") }, + { str_lit("tsv110"), str_lit("CONTEXTIDREL2,aes,ccpp,complxnum,crc,crypto,dotprod,el2vmsa,el3,fp-armv8,fp16fml,fullfp16,fuse-aes,jsconv,lor,lse,neon,pan,pan-rwv,perfmon,ras,rdm,sha2,spe,store-pair-suppress,tsv110,uaops,use-postra-scheduler,v8.1a,v8.2a,v8a,vh") }, + // TargetArch_wasm32: + { str_lit("bleeding-edge"), str_lit("atomics,bulk-memory,mutable-globals,nontrapping-fptoint,sign-ext,simd128,tail-call") }, + { str_lit("generic"), str_lit("mutable-globals,sign-ext") }, + { str_lit("mvp"), str_lit("") }, + // TargetArch_wasm64p32: + { str_lit("bleeding-edge"), str_lit("atomics,bulk-memory,mutable-globals,nontrapping-fptoint,sign-ext,simd128,tail-call") }, + { str_lit("generic"), str_lit("mutable-globals,sign-ext") }, + { str_lit("mvp"), str_lit("") }, +}; \ No newline at end of file From 90244a0849afe9f17e011dc8c3bae571c9f5bb26 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 29 Jun 2024 19:41:45 +0100 Subject: [PATCH 101/129] Fix accidental deletion in the `-strict-style` help comment --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 9b05fab2f..ea82651f5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2355,7 +2355,7 @@ gb_internal void print_show_help(String const arg0, String const &command) { print_usage_line(2, "Errs on unneeded tokens, such as unneeded semicolons."); print_usage_line(2, "Errs on missing trailing commas followed by a newline."); print_usage_line(2, "Errs on deprecated syntax."); - print_usage_line(2, "Errs when 'case' labels are not in the same column as the associated 'switch' token."); + print_usage_line(2, "Errs when the attached-brace style in not adhered to (also known as 1TBS)."); print_usage_line(2, "Errs when 'case' labels are not in the same column as the associated 'switch' token."); print_usage_line(2, "Disallows the 'do' keyword in the project (same as '-disallow-do')."); print_usage_line(0, ""); From e296d6fb902083fac534bdd4c804e6dbad2fc458 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 29 Jun 2024 19:50:51 +0100 Subject: [PATCH 102/129] Fix loads of indentation issues with mixing spaces and tabs --- base/runtime/random_generator.odin | 4 +- core/compress/common.odin | 6 +- core/container/small_array/small_array.odin | 8 +- .../topological_sort/topological_sort.odin | 2 +- core/crypto/rand_darwin.odin | 4 +- core/encoding/cbor/coding.odin | 30 +- core/encoding/cbor/unmarshal.odin | 14 +- core/encoding/json/marshal.odin | 8 +- core/encoding/xml/debug_print.odin | 10 +- core/fmt/fmt.odin | 16 +- core/image/bmp/bmp.odin | 4 +- core/image/qoi/qoi.odin | 4 +- core/math/big/private.odin | 46 +- core/mem/tlsf/tlsf_internal.odin | 2 +- core/net/interface_darwin.odin | 29 +- core/net/interface_windows.odin | 156 +-- core/odin/parser/parser.odin | 18 +- core/os/os.odin | 4 +- core/os/os_darwin.odin | 2 +- core/os/os_windows.odin | 4 +- core/path/filepath/path.odin | 2 +- core/reflect/types.odin | 4 +- core/strings/intern.odin | 2 +- core/sync/chan/chan.odin | 2 +- core/sync/primitives_atomic.odin | 2 +- core/sys/darwin/xnu_system_call_numbers.odin | 1102 ++++++++--------- core/sys/linux/wrappers.odin | 2 +- core/unicode/letter.odin | 2 +- examples/demo/demo.odin | 2 +- vendor/OpenGL/wrappers.odin | 18 +- vendor/commonmark/cmark.odin | 6 +- vendor/sdl2/sdl2.odin | 4 +- .../vulkan/_gen/create_vulkan_odin_wrapper.py | 2 +- vendor/vulkan/core.odin | 2 +- 34 files changed, 760 insertions(+), 763 deletions(-) diff --git a/base/runtime/random_generator.odin b/base/runtime/random_generator.odin index 94201efac..0c4c92bd2 100644 --- a/base/runtime/random_generator.odin +++ b/base/runtime/random_generator.odin @@ -83,7 +83,7 @@ default_random_generator_proc :: proc(data: rawptr, mode: Random_Generator_Mode, switch mode { case .Read: if r.state == 0 && r.inc == 0 { - init(r, 0) + init(r, 0) } switch len(p) { @@ -108,7 +108,7 @@ default_random_generator_proc :: proc(data: rawptr, mode: Random_Generator_Mode, case .Reset: seed: u64 mem_copy_non_overlapping(&seed, raw_data(p), min(size_of(seed), len(p))) - init(r, seed) + init(r, seed) case .Query_Info: if len(p) != size_of(Random_Generator_Query_Info) { diff --git a/core/compress/common.odin b/core/compress/common.odin index b22172e61..47ba45e88 100644 --- a/core/compress/common.odin +++ b/core/compress/common.odin @@ -34,13 +34,13 @@ COMPRESS_OUTPUT_ALLOCATE_MIN :: int(#config(COMPRESS_OUTPUT_ALLOCATE_MIN, 1 << 2 */ when size_of(uintptr) == 8 { - // For 64-bit platforms, we set the default max buffer size to 4 GiB, - // which is GZIP and PKZIP's max payload size. + // For 64-bit platforms, we set the default max buffer size to 4 GiB, + // which is GZIP and PKZIP's max payload size. COMPRESS_OUTPUT_ALLOCATE_MAX :: int(#config(COMPRESS_OUTPUT_ALLOCATE_MAX, 1 << 32)) } else { // For 32-bit platforms, we set the default max buffer size to 512 MiB. - COMPRESS_OUTPUT_ALLOCATE_MAX :: int(#config(COMPRESS_OUTPUT_ALLOCATE_MAX, 1 << 29)) + COMPRESS_OUTPUT_ALLOCATE_MAX :: int(#config(COMPRESS_OUTPUT_ALLOCATE_MAX, 1 << 29)) } diff --git a/core/container/small_array/small_array.odin b/core/container/small_array/small_array.odin index ecec7b80c..b2068469d 100644 --- a/core/container/small_array/small_array.odin +++ b/core/container/small_array/small_array.odin @@ -119,20 +119,20 @@ consume :: proc "odin" (a: ^$A/Small_Array($N, $T), count: int, loc := #caller_l } ordered_remove :: proc "contextless" (a: ^$A/Small_Array($N, $T), index: int, loc := #caller_location) #no_bounds_check { - runtime.bounds_check_error_loc(loc, index, a.len) - if index+1 < a.len { + runtime.bounds_check_error_loc(loc, index, a.len) + if index+1 < a.len { copy(a.data[index:], a.data[index+1:]) } a.len -= 1 } unordered_remove :: proc "contextless" (a: ^$A/Small_Array($N, $T), index: int, loc := #caller_location) #no_bounds_check { - runtime.bounds_check_error_loc(loc, index, a.len) + runtime.bounds_check_error_loc(loc, index, a.len) n := a.len-1 if index != n { a.data[index] = a.data[n] } - a.len -= 1 + a.len -= 1 } clear :: proc "contextless" (a: ^$A/Small_Array($N, $T)) { diff --git a/core/container/topological_sort/topological_sort.odin b/core/container/topological_sort/topological_sort.odin index 0d34e8d02..10765958e 100644 --- a/core/container/topological_sort/topological_sort.odin +++ b/core/container/topological_sort/topological_sort.odin @@ -61,7 +61,7 @@ add_dependency :: proc(sorter: ^$S/Sorter($K), key, dependency: K) -> bool { } find.dependents[key] = true - find = &sorter.relations[key] + find = &sorter.relations[key] if find == nil { find = map_insert(&sorter.relations, key, make_relations(sorter)) } diff --git a/core/crypto/rand_darwin.odin b/core/crypto/rand_darwin.odin index 56acb5d22..df474bc4c 100644 --- a/core/crypto/rand_darwin.odin +++ b/core/crypto/rand_darwin.odin @@ -11,7 +11,7 @@ HAS_RAND_BYTES :: true _rand_bytes :: proc(dst: []byte) { err := Sec.RandomCopyBytes(count=len(dst), bytes=raw_data(dst)) if err != .Success { - msg := CF.StringCopyToOdinString(Sec.CopyErrorMessageString(err)) - fmt.panicf("crypto/rand_bytes: SecRandomCopyBytes returned non-zero result: %v %s", err, msg) + msg := CF.StringCopyToOdinString(Sec.CopyErrorMessageString(err)) + fmt.panicf("crypto/rand_bytes: SecRandomCopyBytes returned non-zero result: %v %s", err, msg) } } diff --git a/core/encoding/cbor/coding.odin b/core/encoding/cbor/coding.odin index f82dc4b81..bfeb147c4 100644 --- a/core/encoding/cbor/coding.odin +++ b/core/encoding/cbor/coding.odin @@ -423,7 +423,7 @@ _decode_bytes :: proc(d: Decoder, add: Add, type: Major = .Bytes, allocator := c _encode_bytes :: proc(e: Encoder, val: Bytes, major: Major = .Bytes) -> (err: Encode_Error) { assert(len(val) >= 0) _encode_u64(e, u64(len(val)), major) or_return - _, err = io.write_full(e.writer, val[:]) + _, err = io.write_full(e.writer, val[:]) return } @@ -440,7 +440,7 @@ _decode_text :: proc(d: Decoder, add: Add, allocator := context.allocator, loc : } _encode_text :: proc(e: Encoder, val: Text) -> Encode_Error { - return _encode_bytes(e, transmute([]byte)val, .Text) + return _encode_bytes(e, transmute([]byte)val, .Text) } _decode_array_ptr :: proc(d: Decoder, add: Add, allocator := context.allocator, loc := #caller_location) -> (v: ^Array, err: Decode_Error) { @@ -480,10 +480,10 @@ _decode_array :: proc(d: Decoder, add: Add, allocator := context.allocator, loc _encode_array :: proc(e: Encoder, arr: Array) -> Encode_Error { assert(len(arr) >= 0) _encode_u64(e, u64(len(arr)), .Array) - for val in arr { - encode(e, val) or_return - } - return nil + for val in arr { + encode(e, val) or_return + } + return nil } _decode_map_ptr :: proc(d: Decoder, add: Add, allocator := context.allocator, loc := #caller_location) -> (v: ^Map, err: Decode_Error) { @@ -576,7 +576,7 @@ _encode_map :: proc(e: Encoder, m: Map) -> (err: Encode_Error) { encode(e, entry.entry.value) or_return } - return nil + return nil } _decode_tag_ptr :: proc(d: Decoder, add: Add, allocator := context.allocator, loc := #caller_location) -> (v: Value, err: Decode_Error) { @@ -626,7 +626,7 @@ _decode_uint_as_u64 :: proc(r: io.Reader, add: Add) -> (nr: u64, err: Decode_Err _encode_tag :: proc(e: Encoder, val: Tag) -> Encode_Error { _encode_u64(e, val.number, .Tag) or_return - return encode(e, val.value) + return encode(e, val.value) } _decode_simple :: proc(r: io.Reader) -> (v: Simple, err: io.Error) { @@ -739,16 +739,16 @@ _encode_nil :: proc(w: io.Writer) -> io.Error { // Streaming encode_stream_begin :: proc(w: io.Writer, major: Major) -> (err: io.Error) { - assert(major >= Major(.Bytes) && major <= Major(.Map), "illegal stream type") + assert(major >= Major(.Bytes) && major <= Major(.Map), "illegal stream type") - header := (u8(major) << 5) | u8(Add.Length_Unknown) - _, err = io.write_full(w, {header}) + header := (u8(major) << 5) | u8(Add.Length_Unknown) + _, err = io.write_full(w, {header}) return } encode_stream_end :: proc(w: io.Writer) -> io.Error { - header := (u8(Major.Other) << 5) | u8(Add.Break) - _, err := io.write_full(w, {header}) + header := (u8(Major.Other) << 5) | u8(Add.Break) + _, err := io.write_full(w, {header}) return err } @@ -757,8 +757,8 @@ encode_stream_text :: _encode_text encode_stream_array_item :: encode encode_stream_map_entry :: proc(e: Encoder, key: Value, val: Value) -> Encode_Error { - encode(e, key) or_return - return encode(e, val) + encode(e, key) or_return + return encode(e, val) } // For `Bytes` and `Text` strings: Decodes the number of items the header says follows. diff --git a/core/encoding/cbor/unmarshal.odin b/core/encoding/cbor/unmarshal.odin index c31ba1d92..289895e98 100644 --- a/core/encoding/cbor/unmarshal.odin +++ b/core/encoding/cbor/unmarshal.odin @@ -273,13 +273,13 @@ _unmarshal_value :: proc(d: Decoder, v: any, hdr: Header, allocator := context.a // NOTE: Because this is a special type and not to be treated as a general integer, // We only put the value of it in fields that are explicitly of type `Simple`. - switch &dst in v { - case Simple: - dst = decoded - return - case: - return _unsupported(v, hdr, add) - } + switch &dst in v { + case Simple: + dst = decoded + return + case: + return _unsupported(v, hdr, add) + } case .Tag: switch &dst in v { diff --git a/core/encoding/json/marshal.odin b/core/encoding/json/marshal.odin index dfca8b9db..0464c24d1 100644 --- a/core/encoding/json/marshal.odin +++ b/core/encoding/json/marshal.odin @@ -387,17 +387,17 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err: case runtime.Type_Info_Pointer, runtime.Type_Info_Multi_Pointer, runtime.Type_Info_Procedure: - return (^rawptr)(v.data)^ == nil + return (^rawptr)(v.data)^ == nil case runtime.Type_Info_Dynamic_Array: - return (^runtime.Raw_Dynamic_Array)(v.data).len == 0 + return (^runtime.Raw_Dynamic_Array)(v.data).len == 0 case runtime.Type_Info_Slice: - return (^runtime.Raw_Slice)(v.data).len == 0 + return (^runtime.Raw_Slice)(v.data).len == 0 case runtime.Type_Info_Union, runtime.Type_Info_Bit_Set, runtime.Type_Info_Soa_Pointer: return reflect.is_nil(v) case runtime.Type_Info_Map: - return (^runtime.Raw_Map)(v.data).len == 0 + return (^runtime.Raw_Map)(v.data).len == 0 } return false } diff --git a/core/encoding/xml/debug_print.odin b/core/encoding/xml/debug_print.odin index be958baaa..acced262a 100644 --- a/core/encoding/xml/debug_print.odin +++ b/core/encoding/xml/debug_print.odin @@ -33,7 +33,7 @@ print :: proc(writer: io.Writer, doc: ^Document) -> (written: int, err: io.Error written += fmt.wprintf(writer, "[DOCTYPE] %v\n", doc.doctype.ident) if len(doc.doctype.rest) > 0 { - fmt.wprintf(writer, "\t%v\n", doc.doctype.rest) + fmt.wprintf(writer, "\t%v\n", doc.doctype.rest) } } @@ -42,10 +42,10 @@ print :: proc(writer: io.Writer, doc: ^Document) -> (written: int, err: io.Error } if len(doc.elements) > 0 { - fmt.wprintln(writer, " --- ") - print_element(writer, doc, 0) - fmt.wprintln(writer, " --- ") - } + fmt.wprintln(writer, " --- ") + print_element(writer, doc, 0) + fmt.wprintln(writer, " --- ") + } return written, .None } diff --git a/core/fmt/fmt.odin b/core/fmt/fmt.odin index 16d35d94a..bd5f2b155 100644 --- a/core/fmt/fmt.odin +++ b/core/fmt/fmt.odin @@ -92,7 +92,7 @@ _user_formatters: ^map[typeid]User_Formatter // set_user_formatters :: proc(m: ^map[typeid]User_Formatter) { assert(_user_formatters == nil, "set_user_formatters must not be called more than once.") - _user_formatters = m + _user_formatters = m } // Registers a user-defined formatter for a specific typeid // @@ -1229,10 +1229,10 @@ _fmt_memory :: proc(fi: ^Info, u: u64, is_signed: bool, bit_size: int, units: st // Add the unit at the end. copy(buf[len(str):], units[off:off+unit_len]) str = string(buf[:len(str)+unit_len]) - - if !fi.plus { - // Strip sign from "+" but not "+Inf". - if str[0] == '+' && str[1] != 'I' { + + if !fi.plus { + // Strip sign from "+" but not "+Inf". + if str[0] == '+' && str[1] != 'I' { str = str[1:] } } @@ -1765,7 +1765,7 @@ fmt_bit_set :: proc(fi: ^Info, v: any, name: string = "", verb: rune = 'v') { if is_enum { enum_name: string - if ti_named, is_named := info.elem.variant.(runtime.Type_Info_Named); is_named { + if ti_named, is_named := info.elem.variant.(runtime.Type_Info_Named); is_named { enum_name = ti_named.name } for ev, evi in e.values { @@ -2709,7 +2709,7 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { return } if fi.indirection_level < 1 { - fi.indirection_level += 1 + fi.indirection_level += 1 defer fi.indirection_level -= 1 io.write_byte(fi.writer, '&') fmt_value(fi, a, verb) @@ -2778,7 +2778,7 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { runtime.Type_Info_Dynamic_Array, runtime.Type_Info_Map: if fi.indirection_level < 1 { - fi.indirection_level += 1 + fi.indirection_level += 1 defer fi.indirection_level -= 1 io.write_byte(fi.writer, '&', &fi.n) fmt_value(fi, a, verb) diff --git a/core/image/bmp/bmp.odin b/core/image/bmp/bmp.odin index dac1b7ab5..a50ad8996 100644 --- a/core/image/bmp/bmp.odin +++ b/core/image/bmp/bmp.odin @@ -71,7 +71,7 @@ save_to_buffer :: proc(output: ^bytes.Buffer, img: ^Image, options := Options{} written := 0 if resize(&output.buf, int(header.size)) != nil { - return .Unable_To_Allocate_Or_Resize + return .Unable_To_Allocate_Or_Resize } header_bytes := transmute([size_of(image.BMP_Header)]u8)header @@ -735,7 +735,7 @@ destroy :: proc(img: ^Image) { bytes.buffer_destroy(&img.pixels) if v, ok := img.metadata.(^image.BMP_Info); ok { - free(v) + free(v) } free(img) } diff --git a/core/image/qoi/qoi.odin b/core/image/qoi/qoi.odin index a121999ea..989e7ca6e 100644 --- a/core/image/qoi/qoi.odin +++ b/core/image/qoi/qoi.odin @@ -230,7 +230,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a bytes_needed := image.compute_buffer_size(int(header.width), int(header.height), img.channels, 8) if resize(&img.pixels.buf, bytes_needed) != nil { - return img, .Unable_To_Allocate_Or_Resize + return img, .Unable_To_Allocate_Or_Resize } /* @@ -341,7 +341,7 @@ destroy :: proc(img: ^Image) { bytes.buffer_destroy(&img.pixels) if v, ok := img.metadata.(^image.QOI_Info); ok { - free(v) + free(v) } free(img) } diff --git a/core/math/big/private.odin b/core/math/big/private.odin index 2ee6cfafa..220f39871 100644 --- a/core/math/big/private.odin +++ b/core/math/big/private.odin @@ -787,8 +787,8 @@ _private_int_sqr_comba :: proc(dest, src: ^Int, allocator := context.allocator) /* Karatsuba squaring, computes `dest` = `src` * `src` using three half-size squarings. - See comments of `_private_int_mul_karatsuba` for details. - It is essentially the same algorithm but merely tuned to perform recursive squarings. + See comments of `_private_int_mul_karatsuba` for details. + It is essentially the same algorithm but merely tuned to perform recursive squarings. */ _private_int_sqr_karatsuba :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error) { context.allocator = allocator @@ -967,7 +967,7 @@ _private_int_div_3 :: proc(quotient, numerator: ^Int, allocator := context.alloc /* b = 2^_DIGIT_BITS / 3 */ - b := _WORD(1) << _WORD(_DIGIT_BITS) / _WORD(3) + b := _WORD(1) << _WORD(_DIGIT_BITS) / _WORD(3) q := &Int{} internal_grow(q, numerator.used) or_return @@ -1007,8 +1007,8 @@ _private_int_div_3 :: proc(quotient, numerator: ^Int, allocator := context.alloc */ if quotient != nil { err = clamp(q) - internal_swap(q, quotient) - } + internal_swap(q, quotient) + } internal_destroy(q) return remainder, nil } @@ -1555,24 +1555,24 @@ _private_int_gcd_lcm :: proc(res_gcd, res_lcm, a, b: ^Int, allocator := context. /* If neither `a` or `b` was zero, we need to compute `gcd`. - Get copies of `a` and `b` we can modify. - */ + Get copies of `a` and `b` we can modify. + */ u, v := &Int{}, &Int{} defer internal_destroy(u, v) internal_copy(u, a) or_return internal_copy(v, b) or_return - /* - Must be positive for the remainder of the algorithm. - */ + /* + Must be positive for the remainder of the algorithm. + */ u.sign = .Zero_or_Positive; v.sign = .Zero_or_Positive - /* - B1. Find the common power of two for `u` and `v`. - */ - u_lsb, _ := internal_count_lsb(u) - v_lsb, _ := internal_count_lsb(v) - k := min(u_lsb, v_lsb) + /* + B1. Find the common power of two for `u` and `v`. + */ + u_lsb, _ := internal_count_lsb(u) + v_lsb, _ := internal_count_lsb(v) + k := min(u_lsb, v_lsb) if k > 0 { /* @@ -1615,11 +1615,11 @@ _private_int_gcd_lcm :: proc(res_gcd, res_lcm, a, b: ^Int, allocator := context. internal_shr(v, v, b) or_return } - /* - Multiply by 2**k which we divided out at the beginning. - */ - internal_shl(temp_gcd_res, u, k) or_return - temp_gcd_res.sign = .Zero_or_Positive + /* + Multiply by 2**k which we divided out at the beginning. + */ + internal_shl(temp_gcd_res, u, k) or_return + temp_gcd_res.sign = .Zero_or_Positive /* We've computed `gcd`, either the long way, or because one of the inputs was zero. @@ -1786,8 +1786,8 @@ _private_montgomery_reduce_comba :: proc(x, n: ^Int, rho: DIGIT, allocator := co `a = a + mu * m * b**i` This is computed in place and on the fly. The multiplication - by b**i is handled by offseting which columns the results - are added to. + by b**i is handled by offseting which columns the results + are added to. Note the comba method normally doesn't handle carries in the inner loop In this case we fix the carry from the previous diff --git a/core/mem/tlsf/tlsf_internal.odin b/core/mem/tlsf/tlsf_internal.odin index 9b270d338..1c7c326eb 100644 --- a/core/mem/tlsf/tlsf_internal.odin +++ b/core/mem/tlsf/tlsf_internal.odin @@ -214,7 +214,7 @@ block_next :: proc(block: ^Block_Header) -> (next: ^Block_Header) { block_link_next :: proc(block: ^Block_Header) -> (next: ^Block_Header) { next = block_next(block) next.prev_phys_block = block - return + return } block_mark_as_free :: proc(block: ^Block_Header) { diff --git a/core/net/interface_darwin.odin b/core/net/interface_darwin.odin index 68353264c..e2a9a73ca 100644 --- a/core/net/interface_darwin.odin +++ b/core/net/interface_darwin.odin @@ -59,24 +59,21 @@ _enumerate_interfaces :: proc(allocator := context.allocator) -> (interfaces: [] switch int(ifaddr.address.family) { case os.AF_INET, os.AF_INET6: address = _sockaddr_basic_to_endpoint(ifaddr.address).address - case: } } if ifaddr.netmask != nil { switch int(ifaddr.netmask.family) { case os.AF_INET, os.AF_INET6: - netmask = Netmask(_sockaddr_basic_to_endpoint(ifaddr.netmask).address) - case: + netmask = Netmask(_sockaddr_basic_to_endpoint(ifaddr.netmask).address) } } if ifaddr.broadcast_or_dest != nil && .BROADCAST in ifaddr.flags { switch int(ifaddr.broadcast_or_dest.family) { case os.AF_INET, os.AF_INET6: - broadcast := _sockaddr_basic_to_endpoint(ifaddr.broadcast_or_dest).address - append(&iface.multicast, broadcast) - case: + broadcast := _sockaddr_basic_to_endpoint(ifaddr.broadcast_or_dest).address + append(&iface.multicast, broadcast) } } @@ -91,19 +88,19 @@ _enumerate_interfaces :: proc(allocator := context.allocator) -> (interfaces: [] /* TODO: Refine this based on the type of adapter. */ - state := Link_State{} + state := Link_State{} - if .UP in ifaddr.flags { - state += {.Up} - } + if .UP in ifaddr.flags { + state += {.Up} + } - /*if .DORMANT in ifaddr.flags { - state |= {.Dormant} - }*/ + /*if .DORMANT in ifaddr.flags { + state |= {.Dormant} + }*/ - if .LOOPBACK in ifaddr.flags { - state += {.Loopback} - } + if .LOOPBACK in ifaddr.flags { + state += {.Loopback} + } iface.link.state = state } diff --git a/core/net/interface_windows.odin b/core/net/interface_windows.odin index f8bac253a..b9abcff48 100644 --- a/core/net/interface_windows.odin +++ b/core/net/interface_windows.odin @@ -24,42 +24,42 @@ import strings "core:strings" _enumerate_interfaces :: proc(allocator := context.allocator) -> (interfaces: []Network_Interface, err: Network_Error) { context.allocator = allocator - buf: []u8 - defer delete(buf) + buf: []u8 + defer delete(buf) - buf_size: u32 - res: u32 + buf_size: u32 + res: u32 - gaa: for _ in 1..=MAX_INTERFACE_ENUMERATION_TRIES { - res = sys.get_adapters_addresses( - .Unspecified, // Return both IPv4 and IPv6 adapters. + gaa: for _ in 1..=MAX_INTERFACE_ENUMERATION_TRIES { + res = sys.get_adapters_addresses( + .Unspecified, // Return both IPv4 and IPv6 adapters. sys.GAA_Flags{ .Include_Prefix, // (XP SP1+) Return a list of IP address prefixes on this adapter. When this flag is set, IP address prefixes are returned for both IPv6 and IPv4 addresses. .Include_Gateways, // (Vista+) Return the addresses of default gateways. .Include_Tunnel_Binding_Order, // (Vista+) Return the adapter addresses sorted in tunnel binding order. }, - nil, // Reserved - (^sys.IP_Adapter_Addresses)(raw_data(buf)), - &buf_size, - ) + nil, // Reserved + (^sys.IP_Adapter_Addresses)(raw_data(buf)), + &buf_size, + ) - switch res { - case 111: // ERROR_BUFFER_OVERFLOW: - delete(buf) - buf = make([]u8, buf_size) - case 0: - break gaa - case: - return {}, Platform_Error(res) - } - } + switch res { + case 111: // ERROR_BUFFER_OVERFLOW: + delete(buf) + buf = make([]u8, buf_size) + case 0: + break gaa + case: + return {}, Platform_Error(res) + } + } - if res != 0 { - return {}, .Unable_To_Enumerate_Network_Interfaces - } + if res != 0 { + return {}, .Unable_To_Enumerate_Network_Interfaces + } - _interfaces := make([dynamic]Network_Interface, 0, allocator) - for adapter := (^sys.IP_Adapter_Addresses)(raw_data(buf)); adapter != nil; adapter = adapter.Next { + _interfaces := make([dynamic]Network_Interface, 0, allocator) + for adapter := (^sys.IP_Adapter_Addresses)(raw_data(buf)); adapter != nil; adapter = adapter.Next { friendly_name, err1 := sys.wstring_to_utf8(sys.wstring(adapter.FriendlyName), 256, allocator) if err1 != nil { return {}, Platform_Error(err1) } @@ -71,74 +71,74 @@ _enumerate_interfaces :: proc(allocator := context.allocator) -> (interfaces: [] interface := Network_Interface{ adapter_name = strings.clone(string(adapter.AdapterName)), - friendly_name = friendly_name, - description = description, - dns_suffix = dns_suffix, + friendly_name = friendly_name, + description = description, + dns_suffix = dns_suffix, - mtu = adapter.MTU, + mtu = adapter.MTU, - link = { + link = { transmit_speed = adapter.TransmitLinkSpeed, receive_speed = adapter.ReceiveLinkSpeed, - }, - } + }, + } - if adapter.PhysicalAddressLength > 0 && adapter.PhysicalAddressLength <= len(adapter.PhysicalAddress) { - interface.physical_address = physical_address_to_string(adapter.PhysicalAddress[:adapter.PhysicalAddressLength]) - } + if adapter.PhysicalAddressLength > 0 && adapter.PhysicalAddressLength <= len(adapter.PhysicalAddress) { + interface.physical_address = physical_address_to_string(adapter.PhysicalAddress[:adapter.PhysicalAddressLength]) + } - for u_addr := (^sys.IP_ADAPTER_UNICAST_ADDRESS_LH)(adapter.FirstUnicastAddress); u_addr != nil; u_addr = u_addr.Next { - win_addr := parse_socket_address(u_addr.Address) + for u_addr := (^sys.IP_ADAPTER_UNICAST_ADDRESS_LH)(adapter.FirstUnicastAddress); u_addr != nil; u_addr = u_addr.Next { + win_addr := parse_socket_address(u_addr.Address) - lease := Lease{ - address = win_addr.address, - origin = { - prefix = Prefix_Origin(u_addr.PrefixOrigin), - suffix = Suffix_Origin(u_addr.SuffixOrigin), - }, - lifetime = { - valid = u_addr.ValidLifetime, - preferred = u_addr.PreferredLifetime, - lease = u_addr.LeaseLifetime, - }, - address_duplication = Address_Duplication(u_addr.DadState), - } - append(&interface.unicast, lease) - } + lease := Lease{ + address = win_addr.address, + origin = { + prefix = Prefix_Origin(u_addr.PrefixOrigin), + suffix = Suffix_Origin(u_addr.SuffixOrigin), + }, + lifetime = { + valid = u_addr.ValidLifetime, + preferred = u_addr.PreferredLifetime, + lease = u_addr.LeaseLifetime, + }, + address_duplication = Address_Duplication(u_addr.DadState), + } + append(&interface.unicast, lease) + } - for a_addr := (^sys.IP_ADAPTER_ANYCAST_ADDRESS_XP)(adapter.FirstAnycastAddress); a_addr != nil; a_addr = a_addr.Next { - addr := parse_socket_address(a_addr.Address) - append(&interface.anycast, addr.address) - } + for a_addr := (^sys.IP_ADAPTER_ANYCAST_ADDRESS_XP)(adapter.FirstAnycastAddress); a_addr != nil; a_addr = a_addr.Next { + addr := parse_socket_address(a_addr.Address) + append(&interface.anycast, addr.address) + } - for m_addr := (^sys.IP_ADAPTER_MULTICAST_ADDRESS_XP)(adapter.FirstMulticastAddress); m_addr != nil; m_addr = m_addr.Next { - addr := parse_socket_address(m_addr.Address) - append(&interface.multicast, addr.address) - } + for m_addr := (^sys.IP_ADAPTER_MULTICAST_ADDRESS_XP)(adapter.FirstMulticastAddress); m_addr != nil; m_addr = m_addr.Next { + addr := parse_socket_address(m_addr.Address) + append(&interface.multicast, addr.address) + } - for g_addr := (^sys.IP_ADAPTER_GATEWAY_ADDRESS_LH)(adapter.FirstGatewayAddress); g_addr != nil; g_addr = g_addr.Next { - addr := parse_socket_address(g_addr.Address) - append(&interface.gateways, addr.address) - } + for g_addr := (^sys.IP_ADAPTER_GATEWAY_ADDRESS_LH)(adapter.FirstGatewayAddress); g_addr != nil; g_addr = g_addr.Next { + addr := parse_socket_address(g_addr.Address) + append(&interface.gateways, addr.address) + } interface.dhcp_v4 = parse_socket_address(adapter.Dhcpv4Server).address interface.dhcp_v6 = parse_socket_address(adapter.Dhcpv6Server).address - switch adapter.OperStatus { - case .Up: interface.link.state = {.Up} - case .Down: interface.link.state = {.Down} - case .Testing: interface.link.state = {.Testing} - case .Dormant: interface.link.state = {.Dormant} - case .NotPresent: interface.link.state = {.Not_Present} - case .LowerLayerDown: interface.link.state = {.Lower_Layer_Down} - case .Unknown: fallthrough - case: interface.link.state = {} - } + switch adapter.OperStatus { + case .Up: interface.link.state = {.Up} + case .Down: interface.link.state = {.Down} + case .Testing: interface.link.state = {.Testing} + case .Dormant: interface.link.state = {.Dormant} + case .NotPresent: interface.link.state = {.Not_Present} + case .LowerLayerDown: interface.link.state = {.Lower_Layer_Down} + case .Unknown: fallthrough + case: interface.link.state = {} + } - interface.tunnel_type = Tunnel_Type(adapter.TunnelType) + interface.tunnel_type = Tunnel_Type(adapter.TunnelType) - append(&_interfaces, interface) - } + append(&_interfaces, interface) + } return _interfaces[:], {} } diff --git a/core/odin/parser/parser.odin b/core/odin/parser/parser.odin index 715b96d84..dec892f84 100644 --- a/core/odin/parser/parser.odin +++ b/core/odin/parser/parser.odin @@ -308,7 +308,7 @@ consume_comment_group :: proc(p: ^Parser, n: int) -> (comments: ^ast.Comment_Gro end_line = p.curr_tok.pos.line for p.curr_tok.kind == .Comment && p.curr_tok.pos.line <= end_line+n { - comment: tokenizer.Token + comment: tokenizer.Token comment, end_line = consume_comment(p) append(&list, comment) } @@ -1315,8 +1315,8 @@ parse_stmt :: proc(p: ^Parser) -> ^ast.Stmt { // Unary Expressions .Add, .Sub, .Xor, .Not, .And: - s := parse_simple_stmt(p, {Stmt_Allow_Flag.Label}) - expect_semicolon(p, s) + s := parse_simple_stmt(p, {Stmt_Allow_Flag.Label}) + expect_semicolon(p, s) return s @@ -1853,7 +1853,7 @@ parse_ident_list :: proc(p: ^Parser, allow_poly_names: bool) -> []^ast.Expr { } if p.curr_tok.kind != .Comma || p.curr_tok.kind == .EOF { - break + break } advance_token(p) } @@ -2216,10 +2216,10 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr { case .Integer, .Float, .Imag, .Rune, .String: - tok := advance_token(p) - bl := ast.new(ast.Basic_Lit, tok.pos, end_pos(tok)) - bl.tok = tok - return bl + tok := advance_token(p) + bl := ast.new(ast.Basic_Lit, tok.pos, end_pos(tok)) + bl.tok = tok + return bl case .Open_Brace: if !lhs { @@ -3007,7 +3007,7 @@ parse_literal_value :: proc(p: ^Parser, type: ^ast.Expr) -> ^ast.Comp_Lit { } p.expr_level -= 1 - skip_possible_newline(p) + skip_possible_newline(p) close := expect_closing_brace_of_field_list(p) pos := type.pos if type != nil else open.pos diff --git a/core/os/os.odin b/core/os/os.odin index aa460fe01..51652a52b 100644 --- a/core/os/os.odin +++ b/core/os/os.odin @@ -111,7 +111,7 @@ read_entire_file_from_handle :: proc(fd: Handle, allocator := context.allocator, length: i64 err: Errno if length, err = file_size(fd); err != 0 { - return nil, false + return nil, false } if length <= 0 { @@ -120,7 +120,7 @@ read_entire_file_from_handle :: proc(fd: Handle, allocator := context.allocator, data = make([]byte, int(length), allocator, loc) if data == nil { - return nil, false + return nil, false } bytes_read, read_err := read_full(fd, data) diff --git a/core/os/os_darwin.odin b/core/os/os_darwin.odin index 75a1f6a29..bbe335e6e 100644 --- a/core/os/os_darwin.odin +++ b/core/os/os_darwin.odin @@ -896,7 +896,7 @@ access :: proc(path: string, mask: int) -> bool { } flush :: proc(fd: Handle) -> Errno { - return cast(Errno)_unix_fsync(fd) + return cast(Errno)_unix_fsync(fd) } lookup_env :: proc(key: string, allocator := context.allocator) -> (value: string, found: bool) { diff --git a/core/os/os_windows.odin b/core/os/os_windows.odin index b375e7c66..ecfb0b419 100644 --- a/core/os/os_windows.odin +++ b/core/os/os_windows.odin @@ -178,8 +178,8 @@ WINDOWS_11_BUILD_CUTOFF :: 22_000 get_windows_version_w :: proc() -> win32.OSVERSIONINFOEXW { osvi : win32.OSVERSIONINFOEXW osvi.dwOSVersionInfoSize = size_of(win32.OSVERSIONINFOEXW) - win32.RtlGetVersion(&osvi) - return osvi + win32.RtlGetVersion(&osvi) + return osvi } is_windows_xp :: proc() -> bool { diff --git a/core/path/filepath/path.odin b/core/path/filepath/path.odin index 59a0f7f1c..c3dfa2bb1 100644 --- a/core/path/filepath/path.odin +++ b/core/path/filepath/path.odin @@ -432,7 +432,7 @@ rel :: proc(base_path, target_path: string, allocator := context.allocator) -> ( then `"."` is returned. */ dir :: proc(path: string, allocator := context.allocator) -> string { - context.allocator = allocator + context.allocator = allocator vol := volume_name(path) i := len(path) - 1 for i >= len(vol) && !is_separator(path[i]) { diff --git a/core/reflect/types.odin b/core/reflect/types.odin index f242dfd5c..04dd8a52d 100644 --- a/core/reflect/types.odin +++ b/core/reflect/types.odin @@ -114,7 +114,7 @@ are_types_identical :: proc(a, b: ^Type_Info) -> bool { case Type_Info_Struct: y := b.variant.(Type_Info_Struct) or_return - switch { + switch { case len(x.types) != len(y.types), x.is_packed != y.is_packed, x.is_raw_union != y.is_raw_union, @@ -122,7 +122,7 @@ are_types_identical :: proc(a, b: ^Type_Info) -> bool { x.soa_kind != y.soa_kind, x.soa_base_type != y.soa_base_type, x.soa_len != y.soa_len: - return false + return false } for _, i in x.types { xn, yn := x.names[i], y.names[i] diff --git a/core/strings/intern.odin b/core/strings/intern.odin index 88eea3c50..4c270980c 100644 --- a/core/strings/intern.odin +++ b/core/strings/intern.odin @@ -37,7 +37,7 @@ Returns: intern_init :: proc(m: ^Intern, allocator := context.allocator, map_allocator := context.allocator, loc := #caller_location) -> (err: mem.Allocator_Error) { m.allocator = allocator m.entries = make(map[string]^Intern_Entry, 16, map_allocator, loc) or_return - return nil + return nil } /* Frees the map and all its content allocated using the `.allocator`. diff --git a/core/sync/chan/chan.odin b/core/sync/chan/chan.odin index 0c3f4a725..0c98124de 100644 --- a/core/sync/chan/chan.odin +++ b/core/sync/chan/chan.odin @@ -304,7 +304,7 @@ try_recv_raw :: proc "contextless" (c: ^Raw_Chan, msg_out: rawptr) -> bool { if sync.atomic_load(&c.closed) || sync.atomic_load(&c.w_waiting) == 0 { - return false + return false } mem.copy(msg_out, c.unbuffered_data, int(c.msg_size)) diff --git a/core/sync/primitives_atomic.odin b/core/sync/primitives_atomic.odin index 1b7cdfe35..2cf25ac11 100644 --- a/core/sync/primitives_atomic.odin +++ b/core/sync/primitives_atomic.odin @@ -169,7 +169,7 @@ atomic_rw_mutex_shared_unlock :: proc "contextless" (rw: ^Atomic_RW_Mutex) { if (state & Atomic_RW_Mutex_State_Reader_Mask == Atomic_RW_Mutex_State_Reader) && (state & Atomic_RW_Mutex_State_Is_Writing != 0) { - atomic_sema_post(&rw.sema) + atomic_sema_post(&rw.sema) } } diff --git a/core/sys/darwin/xnu_system_call_numbers.odin b/core/sys/darwin/xnu_system_call_numbers.odin index 429d18964..39d902c79 100644 --- a/core/sys/darwin/xnu_system_call_numbers.odin +++ b/core/sys/darwin/xnu_system_call_numbers.odin @@ -1,558 +1,558 @@ package darwin unix_offset_syscall :: proc "contextless" (number: System_Call_Number) -> uintptr { - return uintptr(number) + uintptr(0x2000000) + return uintptr(number) + uintptr(0x2000000) } System_Call_Number :: enum uintptr { - /* 0 syscall */ - exit = 1, - fork = 2, - read = 3, - write = 4, - open = 5, - close = 6, - wait4 = 7, - /* 8 old creat */ - link = 9, - unlink = 10, - /* 11 old execv */ - chdir = 12, - fchdir = 13, - mknod = 14, - chmod = 15, - chown = 16, - /* 17 old break */ - getfsstat = 18, - /* 19 old lseek */ - getpid = 20, - /* 21 old mount */ - /* 22 old umount */ - setuid = 23, - getuid = 24, - geteuid = 25, - ptrace = 26, - recvmsg = 27, - sendmsg = 28, - recvfrom = 29, - accept = 30, - getpeername = 31, - getsockname = 32, - access = 33, - chflags = 34, - fchflags = 35, - sync = 36, - kill = 37, - /* 38 old stat */ - getppid = 39, - /* 40 old lstat */ - dup = 41, - pipe = 42, - getegid = 43, - /* 44 old profil */ - /* 45 old ktrace */ - sigaction = 46, - getgid = 47, - sigprocmask = 48, - getlogin = 49, - setlogin = 50, - acct = 51, - sigpending = 52, - sigaltstack = 53, - ioctl = 54, - reboot = 55, - revoke = 56, - symlink = 57, - readlink = 58, - execve = 59, - umask = 60, - chroot = 61, - /* 62 old fstat */ - /* 63 used internally and reserved */ - /* getpagesize = 64, invalid */ - msync = 65, - vfork = 66, - /* 67 old vread */ - /* 68 old vwrite */ - /* 69 old sbrk */ - /* 70 old sstk */ - /* 71 old mmap */ - /* 72 old vadvise */ - munmap = 73, - mprotect = 74, - madvise = 75, - /* 76 old vhangup */ - /* 77 old vlimit */ - mincore = 78, - getgroups = 79, - setgroups = 80, - getpgrp = 81, - setpgid = 82, - setitimer = 83, - /* 84 old wait */ - swapon = 85, - getitimer = 86, - /* 87 old gethostname */ - /* 88 old sethostname */ - getdtablesize = 89, - dup2 = 90, - /* 91 old getdopt */ - fcntl = 92, - select = 93, - /* 94 old setdopt */ - fsync = 95, - setpriority = 96, - socket = 97, - connect = 98, - /* 99 old accept */ - getpriority = 100, - /* 101 old send */ - /* 102 old recv */ - /* 103 old sigreturn */ - bind = 104, - setsockopt = 105, - listen = 106, - /* 107 old vtimes */ - /* 108 old sigvec */ - /* 109 old sigblock */ - /* 110 old sigsetmask */ - sigsuspend = 111, - /* 112 old sigstack */ - /* 113 old recvmsg */ - /* 114 old sendmsg */ - /* 115 old vtrace */ - gettimeofday = 116, - getrusage = 117, - getsockopt = 118, - /* 119 old resuba */ - readv = 120, - writev = 121, - settimeofday = 122, - fchown = 123, - fchmod = 124, - /* 125 old recvfrom */ - setreuid = 126, - setregid = 127, - rename = 128, - /* 129 old truncate */ - /* 130 old ftruncate */ - flock = 131, - mkfifo = 132, - sendto = 133, - shutdown = 134, - socketpair = 135, - mkdir = 136, - rmdir = 137, - utimes = 138, - futimes = 139, - adjtime = 140, - /* 141 old getpeername */ - gethostuuid = 142, - /* 143 old sethostid */ - /* 144 old getrlimit */ - /* 145 old setrlimit */ - /* 146 old killpg */ - setsid = 147, - /* 148 old setquota */ - /* 149 old qquota */ - /* 150 old getsockname */ - getpgid = 151, - setprivexec = 152, - pread = 153, - pwrite = 154, - nfssvc = 155, - /* 156 old getdirentries */ - statfs = 157, - fstatfs = 158, - unmount = 159, - /* 160 old async_daemon */ - getfh = 161, - /* 162 old getdomainname */ - /* 163 old setdomainname */ - /* 164 */ - quotactl = 165, - /* 166 old exportfs */ - mount = 167, - /* 168 old ustat */ - csops = 169, - csops_audittoken = 170, - /* 171 old wait3 */ - /* 172 old rpause */ - waitid = 173, - /* 174 old getdents */ - /* 175 old gc_control */ - /* 176 old add_profil */ - kdebug_typefilter = 177, - kdebug_trace_string = 178, - kdebug_trace64 = 179, - kdebug_trace = 180, - setgid = 181, - setegid = 182, - seteuid = 183, - sigreturn = 184, - /* 185 old chud */ - thread_selfcounts = 186, - fdatasync = 187, - stat = 188, - fstat = 189, - lstat = 190, - pathconf = 191, - fpathconf = 192, - /* 193 old getfsstat */ - getrlimit = 194, - setrlimit = 195, - getdirentries = 196, - mmap = 197, - /* 198 old __syscall */ - lseek = 199, - truncate = 200, - ftruncate = 201, - sysctl = 202, - mlock = 203, - munlock = 204, - undelete = 205, - /* 206 old ATsocket */ - /* 207 old ATgetmsg */ - /* 208 old ATputmsg */ - /* 209 old ATsndreq */ - /* 210 old ATsndrsp */ - /* 211 old ATgetreq */ - /* 212 old ATgetrsp */ - /* 213 Reserved for AppleTalk */ - /* 214 */ - /* 215 */ - open_dprotected_np = 216, - fsgetpath_ext = 217, - /* 218 old lstatv */ - /* 219 old fstatv */ - getattrlist = 220, - setattrlist = 221, - getdirentriesattr = 222, - exchangedata = 223, - /* 224 old checkuseraccess or fsgetpath */ - searchfs = 225, - delete = 226, - copyfile = 227, - fgetattrlist = 228, - fsetattrlist = 229, - poll = 230, - /* 231 old watchevent */ - /* 232 old waitevent */ - /* 233 old modwatch */ - getxattr = 234, - fgetxattr = 235, - setxattr = 236, - fsetxattr = 237, - removexattr = 238, - fremovexattr = 239, - listxattr = 240, - flistxattr = 241, - fsctl = 242, - initgroups = 243, - posix_spawn = 244, - ffsctl = 245, - /* 246 */ - nfsclnt = 247, - fhopen = 248, - /* 249 */ - minherit = 250, - semsys = 251, - msgsys = 252, - shmsys = 253, - semctl = 254, - semget = 255, - semop = 256, - /* 257 old semconfig */ - msgctl = 258, - msgget = 259, - msgsnd = 260, - msgrcv = 261, - shmat = 262, - shmctl = 263, - shmdt = 264, - shmget = 265, - shm_open = 266, - shm_unlink = 267, - sem_open = 268, - sem_close = 269, - sem_unlink = 270, - sem_wait = 271, - sem_trywait = 272, - sem_post = 273, - sysctlbyname = 274, - /* 275 old sem_init */ - /* 276 old sem_destroy */ - open_extended = 277, - umask_extended = 278, - stat_extended = 279, - lstat_extended = 280, - fstat_extended = 281, - chmod_extended = 282, - fchmod_extended = 283, - access_extended = 284, - settid = 285, - gettid = 286, - setsgroups = 287, - getsgroups = 288, - setwgroups = 289, - getwgroups = 290, - mkfifo_extended = 291, - mkdir_extended = 292, - identitysvc = 293, - shared_region_check_np = 294, - /* 295 old shared_region_map_np */ - vm_pressure_monitor = 296, - psynch_rw_longrdlock = 297, - psynch_rw_yieldwrlock = 298, - psynch_rw_downgrade = 299, - psynch_rw_upgrade = 300, - psynch_mutexwait = 301, - psynch_mutexdrop = 302, - psynch_cvbroad = 303, - psynch_cvsignal = 304, - psynch_cvwait = 305, - psynch_rw_rdlock = 306, - psynch_rw_wrlock = 307, - psynch_rw_unlock = 308, - psynch_rw_unlock2 = 309, - getsid = 310, - settid_with_pid = 311, - psynch_cvclrprepost = 312, - aio_fsync = 313, - aio_return = 314, - aio_suspend = 315, - aio_cancel = 316, - aio_error = 317, - aio_read = 318, - aio_write = 319, - lio_listio = 320, - /* 321 old __pthread_cond_wait */ - iopolicysys = 322, - process_policy = 323, - mlockall = 324, - munlockall = 325, - /* 326 */ - issetugid = 327, - __pthread_kill = 328, - __pthread_sigmask = 329, - __sigwait = 330, - __disable_threadsignal = 331, - __pthread_markcancel = 332, - __pthread_canceled = 333, - __semwait_signal = 334, - /* 335 old utrace */ - proc_info = 336, - sendfile = 337, - stat64 = 338, - fstat64 = 339, - lstat64 = 340, - stat64_extended = 341, - lstat64_extended = 342, - fstat64_extended = 343, - getdirentries64 = 344, - statfs64 = 345, - fstatfs64 = 346, - getfsstat64 = 347, - __pthread_chdir = 348, - __pthread_fchdir = 349, - audit = 350, - auditon = 351, - /* 352 */ - getauid = 353, - setauid = 354, - /* 355 old getaudit */ - /* 356 old setaudit */ - getaudit_addr = 357, - setaudit_addr = 358, - auditctl = 359, - bsdthread_create = 360, - bsdthread_terminate = 361, - kqueue = 362, - kevent = 363, - lchown = 364, - /* 365 old stack_snapshot */ - bsdthread_register = 366, - workq_open = 367, - workq_kernreturn = 368, - kevent64 = 369, - __old_semwait_signal = 370, - __old_semwait_signal_nocancel = 371, - thread_selfid = 372, - ledger = 373, - kevent_qos = 374, - kevent_id = 375, - /* 376 */ - /* 377 */ - /* 378 */ - /* 379 */ - __mac_execve = 380, - __mac_syscall = 381, - __mac_get_file = 382, - __mac_set_file = 383, - __mac_get_link = 384, - __mac_set_link = 385, - __mac_get_proc = 386, - __mac_set_proc = 387, - __mac_get_fd = 388, - __mac_set_fd = 389, - __mac_get_pid = 390, - /* 391 */ - /* 392 */ - /* 393 */ - pselect = 394, - pselect_nocancel = 395, - read_nocancel = 396, - write_nocancel = 397, - open_nocancel = 398, - close_nocancel = 399, - wait4_nocancel = 400, - recvmsg_nocancel = 401, - sendmsg_nocancel = 402, - recvfrom_nocancel = 403, - accept_nocancel = 404, - msync_nocancel = 405, - fcntl_nocancel = 406, - select_nocancel = 407, - fsync_nocancel = 408, - connect_nocancel = 409, - sigsuspend_nocancel = 410, - readv_nocancel = 411, - writev_nocancel = 412, - sendto_nocancel = 413, - pread_nocancel = 414, - pwrite_nocancel = 415, - waitid_nocancel = 416, - poll_nocancel = 417, - msgsnd_nocancel = 418, - msgrcv_nocancel = 419, - sem_wait_nocancel = 420, - aio_suspend_nocancel = 421, - __sigwait_nocancel = 422, - __semwait_signal_nocancel = 423, - __mac_mount = 424, - __mac_get_mount = 425, - __mac_getfsstat = 426, - fsgetpath = 427, - audit_session_self = 428, - audit_session_join = 429, - fileport_makeport = 430, - fileport_makefd = 431, - audit_session_port = 432, - pid_suspend = 433, - pid_resume = 434, - pid_hibernate = 435, - pid_shutdown_sockets = 436, - /* 437 old shared_region_slide_np */ - shared_region_map_and_slide_np = 438, - kas_info = 439, - memorystatus_control = 440, - guarded_open_np = 441, - guarded_close_np = 442, - guarded_kqueue_np = 443, - change_fdguard_np = 444, - usrctl = 445, - proc_rlimit_control = 446, - connectx = 447, - disconnectx = 448, - peeloff = 449, - socket_delegate = 450, - telemetry = 451, - proc_uuid_policy = 452, - memorystatus_get_level = 453, - system_override = 454, - vfs_purge = 455, - sfi_ctl = 456, - sfi_pidctl = 457, - coalition = 458, - coalition_info = 459, - necp_match_policy = 460, - getattrlistbulk = 461, - clonefileat = 462, - openat = 463, - openat_nocancel = 464, - renameat = 465, - faccessat = 466, - fchmodat = 467, - fchownat = 468, - fstatat = 469, - fstatat64 = 470, - linkat = 471, - unlinkat = 472, - readlinkat = 473, - symlinkat = 474, - mkdirat = 475, - getattrlistat = 476, - proc_trace_log = 477, - bsdthread_ctl = 478, - openbyid_np = 479, - recvmsg_x = 480, - sendmsg_x = 481, - thread_selfusage = 482, - csrctl = 483, - guarded_open_dprotected_np = 484, - guarded_write_np = 485, - guarded_pwrite_np = 486, - guarded_writev_np = 487, - renameatx_np = 488, - mremap_encrypted = 489, - netagent_trigger = 490, - stack_snapshot_with_config = 491, - microstackshot = 492, - grab_pgo_data = 493, - persona = 494, - /* 495 */ - mach_eventlink_signal = 496, - mach_eventlink_wait_until = 497, - mach_eventlink_signal_wait_until = 498, - work_interval_ctl = 499, - getentropy = 500, - necp_open = 501, - necp_client_action = 502, - nexus_open = 503, // for those who are intressted http://newosxbook.com/bonus/vol1ch16.html - nexus_register = 504, - nexus_deregister = 505, - nexus_create = 506, - nexus_destroy = 507, - nexus_get_opt = 508, - nexus_set_opt = 509, - channel_open = 510, - channel_get_info = 511, - channel_sync = 512, - channel_get_opt = 513, - channel_set_opt = 514, - ulock_wait = 515, - ulock_wake = 516, - fclonefileat = 517, - fs_snapshot = 518, - register_uexc_handler = 519, - terminate_with_payload = 520, - abort_with_payload = 521, - necp_session_open = 522, - necp_session_action = 523, - setattrlistat = 524, - net_qos_guideline = 525, - fmount = 526, - ntp_adjtime = 527, - ntp_gettime = 528, - os_fault_with_payload = 529, - kqueue_workloop_ctl = 530, - mach_bridge_remote_time = 531, - coalition_ledger = 532, - log_data = 533, - memorystatus_available_memory = 534, - objc_bp_assist_cfg_np = 535, - shared_region_map_and_slide_2_np = 536, - pivot_root = 537, - task_inspect_for_pid = 538, - task_read_for_pid = 539, - preadv = 540, - pwritev = 541, - preadv_nocancel = 542, - pwritev_nocancel = 543, - ulock_wait2 = 544, - proc_info_extended_id = 545, - tracker_action = 546, - debug_syscall_reject = 547, - MAXSYSCALL = 548, - /* invalid = 63, */ + /* 0 syscall */ + exit = 1, + fork = 2, + read = 3, + write = 4, + open = 5, + close = 6, + wait4 = 7, + /* 8 old creat */ + link = 9, + unlink = 10, + /* 11 old execv */ + chdir = 12, + fchdir = 13, + mknod = 14, + chmod = 15, + chown = 16, + /* 17 old break */ + getfsstat = 18, + /* 19 old lseek */ + getpid = 20, + /* 21 old mount */ + /* 22 old umount */ + setuid = 23, + getuid = 24, + geteuid = 25, + ptrace = 26, + recvmsg = 27, + sendmsg = 28, + recvfrom = 29, + accept = 30, + getpeername = 31, + getsockname = 32, + access = 33, + chflags = 34, + fchflags = 35, + sync = 36, + kill = 37, + /* 38 old stat */ + getppid = 39, + /* 40 old lstat */ + dup = 41, + pipe = 42, + getegid = 43, + /* 44 old profil */ + /* 45 old ktrace */ + sigaction = 46, + getgid = 47, + sigprocmask = 48, + getlogin = 49, + setlogin = 50, + acct = 51, + sigpending = 52, + sigaltstack = 53, + ioctl = 54, + reboot = 55, + revoke = 56, + symlink = 57, + readlink = 58, + execve = 59, + umask = 60, + chroot = 61, + /* 62 old fstat */ + /* 63 used internally and reserved */ + /* getpagesize = 64, invalid */ + msync = 65, + vfork = 66, + /* 67 old vread */ + /* 68 old vwrite */ + /* 69 old sbrk */ + /* 70 old sstk */ + /* 71 old mmap */ + /* 72 old vadvise */ + munmap = 73, + mprotect = 74, + madvise = 75, + /* 76 old vhangup */ + /* 77 old vlimit */ + mincore = 78, + getgroups = 79, + setgroups = 80, + getpgrp = 81, + setpgid = 82, + setitimer = 83, + /* 84 old wait */ + swapon = 85, + getitimer = 86, + /* 87 old gethostname */ + /* 88 old sethostname */ + getdtablesize = 89, + dup2 = 90, + /* 91 old getdopt */ + fcntl = 92, + select = 93, + /* 94 old setdopt */ + fsync = 95, + setpriority = 96, + socket = 97, + connect = 98, + /* 99 old accept */ + getpriority = 100, + /* 101 old send */ + /* 102 old recv */ + /* 103 old sigreturn */ + bind = 104, + setsockopt = 105, + listen = 106, + /* 107 old vtimes */ + /* 108 old sigvec */ + /* 109 old sigblock */ + /* 110 old sigsetmask */ + sigsuspend = 111, + /* 112 old sigstack */ + /* 113 old recvmsg */ + /* 114 old sendmsg */ + /* 115 old vtrace */ + gettimeofday = 116, + getrusage = 117, + getsockopt = 118, + /* 119 old resuba */ + readv = 120, + writev = 121, + settimeofday = 122, + fchown = 123, + fchmod = 124, + /* 125 old recvfrom */ + setreuid = 126, + setregid = 127, + rename = 128, + /* 129 old truncate */ + /* 130 old ftruncate */ + flock = 131, + mkfifo = 132, + sendto = 133, + shutdown = 134, + socketpair = 135, + mkdir = 136, + rmdir = 137, + utimes = 138, + futimes = 139, + adjtime = 140, + /* 141 old getpeername */ + gethostuuid = 142, + /* 143 old sethostid */ + /* 144 old getrlimit */ + /* 145 old setrlimit */ + /* 146 old killpg */ + setsid = 147, + /* 148 old setquota */ + /* 149 old qquota */ + /* 150 old getsockname */ + getpgid = 151, + setprivexec = 152, + pread = 153, + pwrite = 154, + nfssvc = 155, + /* 156 old getdirentries */ + statfs = 157, + fstatfs = 158, + unmount = 159, + /* 160 old async_daemon */ + getfh = 161, + /* 162 old getdomainname */ + /* 163 old setdomainname */ + /* 164 */ + quotactl = 165, + /* 166 old exportfs */ + mount = 167, + /* 168 old ustat */ + csops = 169, + csops_audittoken = 170, + /* 171 old wait3 */ + /* 172 old rpause */ + waitid = 173, + /* 174 old getdents */ + /* 175 old gc_control */ + /* 176 old add_profil */ + kdebug_typefilter = 177, + kdebug_trace_string = 178, + kdebug_trace64 = 179, + kdebug_trace = 180, + setgid = 181, + setegid = 182, + seteuid = 183, + sigreturn = 184, + /* 185 old chud */ + thread_selfcounts = 186, + fdatasync = 187, + stat = 188, + fstat = 189, + lstat = 190, + pathconf = 191, + fpathconf = 192, + /* 193 old getfsstat */ + getrlimit = 194, + setrlimit = 195, + getdirentries = 196, + mmap = 197, + /* 198 old __syscall */ + lseek = 199, + truncate = 200, + ftruncate = 201, + sysctl = 202, + mlock = 203, + munlock = 204, + undelete = 205, + /* 206 old ATsocket */ + /* 207 old ATgetmsg */ + /* 208 old ATputmsg */ + /* 209 old ATsndreq */ + /* 210 old ATsndrsp */ + /* 211 old ATgetreq */ + /* 212 old ATgetrsp */ + /* 213 Reserved for AppleTalk */ + /* 214 */ + /* 215 */ + open_dprotected_np = 216, + fsgetpath_ext = 217, + /* 218 old lstatv */ + /* 219 old fstatv */ + getattrlist = 220, + setattrlist = 221, + getdirentriesattr = 222, + exchangedata = 223, + /* 224 old checkuseraccess or fsgetpath */ + searchfs = 225, + delete = 226, + copyfile = 227, + fgetattrlist = 228, + fsetattrlist = 229, + poll = 230, + /* 231 old watchevent */ + /* 232 old waitevent */ + /* 233 old modwatch */ + getxattr = 234, + fgetxattr = 235, + setxattr = 236, + fsetxattr = 237, + removexattr = 238, + fremovexattr = 239, + listxattr = 240, + flistxattr = 241, + fsctl = 242, + initgroups = 243, + posix_spawn = 244, + ffsctl = 245, + /* 246 */ + nfsclnt = 247, + fhopen = 248, + /* 249 */ + minherit = 250, + semsys = 251, + msgsys = 252, + shmsys = 253, + semctl = 254, + semget = 255, + semop = 256, + /* 257 old semconfig */ + msgctl = 258, + msgget = 259, + msgsnd = 260, + msgrcv = 261, + shmat = 262, + shmctl = 263, + shmdt = 264, + shmget = 265, + shm_open = 266, + shm_unlink = 267, + sem_open = 268, + sem_close = 269, + sem_unlink = 270, + sem_wait = 271, + sem_trywait = 272, + sem_post = 273, + sysctlbyname = 274, + /* 275 old sem_init */ + /* 276 old sem_destroy */ + open_extended = 277, + umask_extended = 278, + stat_extended = 279, + lstat_extended = 280, + fstat_extended = 281, + chmod_extended = 282, + fchmod_extended = 283, + access_extended = 284, + settid = 285, + gettid = 286, + setsgroups = 287, + getsgroups = 288, + setwgroups = 289, + getwgroups = 290, + mkfifo_extended = 291, + mkdir_extended = 292, + identitysvc = 293, + shared_region_check_np = 294, + /* 295 old shared_region_map_np */ + vm_pressure_monitor = 296, + psynch_rw_longrdlock = 297, + psynch_rw_yieldwrlock = 298, + psynch_rw_downgrade = 299, + psynch_rw_upgrade = 300, + psynch_mutexwait = 301, + psynch_mutexdrop = 302, + psynch_cvbroad = 303, + psynch_cvsignal = 304, + psynch_cvwait = 305, + psynch_rw_rdlock = 306, + psynch_rw_wrlock = 307, + psynch_rw_unlock = 308, + psynch_rw_unlock2 = 309, + getsid = 310, + settid_with_pid = 311, + psynch_cvclrprepost = 312, + aio_fsync = 313, + aio_return = 314, + aio_suspend = 315, + aio_cancel = 316, + aio_error = 317, + aio_read = 318, + aio_write = 319, + lio_listio = 320, + /* 321 old __pthread_cond_wait */ + iopolicysys = 322, + process_policy = 323, + mlockall = 324, + munlockall = 325, + /* 326 */ + issetugid = 327, + __pthread_kill = 328, + __pthread_sigmask = 329, + __sigwait = 330, + __disable_threadsignal = 331, + __pthread_markcancel = 332, + __pthread_canceled = 333, + __semwait_signal = 334, + /* 335 old utrace */ + proc_info = 336, + sendfile = 337, + stat64 = 338, + fstat64 = 339, + lstat64 = 340, + stat64_extended = 341, + lstat64_extended = 342, + fstat64_extended = 343, + getdirentries64 = 344, + statfs64 = 345, + fstatfs64 = 346, + getfsstat64 = 347, + __pthread_chdir = 348, + __pthread_fchdir = 349, + audit = 350, + auditon = 351, + /* 352 */ + getauid = 353, + setauid = 354, + /* 355 old getaudit */ + /* 356 old setaudit */ + getaudit_addr = 357, + setaudit_addr = 358, + auditctl = 359, + bsdthread_create = 360, + bsdthread_terminate = 361, + kqueue = 362, + kevent = 363, + lchown = 364, + /* 365 old stack_snapshot */ + bsdthread_register = 366, + workq_open = 367, + workq_kernreturn = 368, + kevent64 = 369, + __old_semwait_signal = 370, + __old_semwait_signal_nocancel = 371, + thread_selfid = 372, + ledger = 373, + kevent_qos = 374, + kevent_id = 375, + /* 376 */ + /* 377 */ + /* 378 */ + /* 379 */ + __mac_execve = 380, + __mac_syscall = 381, + __mac_get_file = 382, + __mac_set_file = 383, + __mac_get_link = 384, + __mac_set_link = 385, + __mac_get_proc = 386, + __mac_set_proc = 387, + __mac_get_fd = 388, + __mac_set_fd = 389, + __mac_get_pid = 390, + /* 391 */ + /* 392 */ + /* 393 */ + pselect = 394, + pselect_nocancel = 395, + read_nocancel = 396, + write_nocancel = 397, + open_nocancel = 398, + close_nocancel = 399, + wait4_nocancel = 400, + recvmsg_nocancel = 401, + sendmsg_nocancel = 402, + recvfrom_nocancel = 403, + accept_nocancel = 404, + msync_nocancel = 405, + fcntl_nocancel = 406, + select_nocancel = 407, + fsync_nocancel = 408, + connect_nocancel = 409, + sigsuspend_nocancel = 410, + readv_nocancel = 411, + writev_nocancel = 412, + sendto_nocancel = 413, + pread_nocancel = 414, + pwrite_nocancel = 415, + waitid_nocancel = 416, + poll_nocancel = 417, + msgsnd_nocancel = 418, + msgrcv_nocancel = 419, + sem_wait_nocancel = 420, + aio_suspend_nocancel = 421, + __sigwait_nocancel = 422, + __semwait_signal_nocancel = 423, + __mac_mount = 424, + __mac_get_mount = 425, + __mac_getfsstat = 426, + fsgetpath = 427, + audit_session_self = 428, + audit_session_join = 429, + fileport_makeport = 430, + fileport_makefd = 431, + audit_session_port = 432, + pid_suspend = 433, + pid_resume = 434, + pid_hibernate = 435, + pid_shutdown_sockets = 436, + /* 437 old shared_region_slide_np */ + shared_region_map_and_slide_np = 438, + kas_info = 439, + memorystatus_control = 440, + guarded_open_np = 441, + guarded_close_np = 442, + guarded_kqueue_np = 443, + change_fdguard_np = 444, + usrctl = 445, + proc_rlimit_control = 446, + connectx = 447, + disconnectx = 448, + peeloff = 449, + socket_delegate = 450, + telemetry = 451, + proc_uuid_policy = 452, + memorystatus_get_level = 453, + system_override = 454, + vfs_purge = 455, + sfi_ctl = 456, + sfi_pidctl = 457, + coalition = 458, + coalition_info = 459, + necp_match_policy = 460, + getattrlistbulk = 461, + clonefileat = 462, + openat = 463, + openat_nocancel = 464, + renameat = 465, + faccessat = 466, + fchmodat = 467, + fchownat = 468, + fstatat = 469, + fstatat64 = 470, + linkat = 471, + unlinkat = 472, + readlinkat = 473, + symlinkat = 474, + mkdirat = 475, + getattrlistat = 476, + proc_trace_log = 477, + bsdthread_ctl = 478, + openbyid_np = 479, + recvmsg_x = 480, + sendmsg_x = 481, + thread_selfusage = 482, + csrctl = 483, + guarded_open_dprotected_np = 484, + guarded_write_np = 485, + guarded_pwrite_np = 486, + guarded_writev_np = 487, + renameatx_np = 488, + mremap_encrypted = 489, + netagent_trigger = 490, + stack_snapshot_with_config = 491, + microstackshot = 492, + grab_pgo_data = 493, + persona = 494, + /* 495 */ + mach_eventlink_signal = 496, + mach_eventlink_wait_until = 497, + mach_eventlink_signal_wait_until = 498, + work_interval_ctl = 499, + getentropy = 500, + necp_open = 501, + necp_client_action = 502, + nexus_open = 503, // for those who are intressted http://newosxbook.com/bonus/vol1ch16.html + nexus_register = 504, + nexus_deregister = 505, + nexus_create = 506, + nexus_destroy = 507, + nexus_get_opt = 508, + nexus_set_opt = 509, + channel_open = 510, + channel_get_info = 511, + channel_sync = 512, + channel_get_opt = 513, + channel_set_opt = 514, + ulock_wait = 515, + ulock_wake = 516, + fclonefileat = 517, + fs_snapshot = 518, + register_uexc_handler = 519, + terminate_with_payload = 520, + abort_with_payload = 521, + necp_session_open = 522, + necp_session_action = 523, + setattrlistat = 524, + net_qos_guideline = 525, + fmount = 526, + ntp_adjtime = 527, + ntp_gettime = 528, + os_fault_with_payload = 529, + kqueue_workloop_ctl = 530, + mach_bridge_remote_time = 531, + coalition_ledger = 532, + log_data = 533, + memorystatus_available_memory = 534, + objc_bp_assist_cfg_np = 535, + shared_region_map_and_slide_2_np = 536, + pivot_root = 537, + task_inspect_for_pid = 538, + task_read_for_pid = 539, + preadv = 540, + pwritev = 541, + preadv_nocancel = 542, + pwritev_nocancel = 543, + ulock_wait2 = 544, + proc_info_extended_id = 545, + tracker_action = 546, + debug_syscall_reject = 547, + MAXSYSCALL = 548, + /* invalid = 63, */ } diff --git a/core/sys/linux/wrappers.odin b/core/sys/linux/wrappers.odin index 998a9244c..7a30c3bde 100644 --- a/core/sys/linux/wrappers.odin +++ b/core/sys/linux/wrappers.odin @@ -48,7 +48,7 @@ WCOREDUMP :: #force_inline proc "contextless" (s: u32) -> bool { return 1 << ((cast(uint)(sig) - 1) % (8*size_of(uint))) } @private _sigword :: proc "contextless" (sig: Signal) -> (uint) { - return (cast(uint)sig - 1) / (8*size_of(uint)) + return (cast(uint)sig - 1) / (8*size_of(uint)) } // TODO: sigaddset etc diff --git a/core/unicode/letter.odin b/core/unicode/letter.odin index af345f733..e6d0261c6 100644 --- a/core/unicode/letter.odin +++ b/core/unicode/letter.odin @@ -242,7 +242,7 @@ is_enclosing_mark :: proc(r: rune) -> bool { 0x20DD ..= 0x20E0, 0x20E2 ..= 0x20E4, 0xA670 ..= 0xA672: - return true + return true } return false diff --git a/examples/demo/demo.odin b/examples/demo/demo.odin index 531538697..e27686099 100644 --- a/examples/demo/demo.odin +++ b/examples/demo/demo.odin @@ -2275,7 +2275,7 @@ arbitrary_precision_mathematics :: proc() { } fmt.printf(as) if print_extra_info { - fmt.printf(" (base: %v, bits: %v, digits: %v)", base, cb, a.used) + fmt.printf(" (base: %v, bits: %v, digits: %v)", base, cb, a.used) } if newline { fmt.println() diff --git a/vendor/OpenGL/wrappers.odin b/vendor/OpenGL/wrappers.odin index 4aaec4adc..1eb8fc72f 100644 --- a/vendor/OpenGL/wrappers.odin +++ b/vendor/OpenGL/wrappers.odin @@ -781,17 +781,17 @@ when !GL_DEBUG { { // add input arguments for arg, arg_index in args[num_ret:] { - if arg_index > 0 { fmt.printf(", ") } + if arg_index > 0 { fmt.printf(", ") } - if v, ok := arg.(u32); ok { // TODO: Assumes all u32 are GLenum (they're not, GLbitfield and GLuint are also mapped to u32), fix later by better typing - if err == .INVALID_ENUM { - fmt.printf("INVALID_ENUM=%d", v) + if v, ok := arg.(u32); ok { // TODO: Assumes all u32 are GLenum (they're not, GLbitfield and GLuint are also mapped to u32), fix later by better typing + if err == .INVALID_ENUM { + fmt.printf("INVALID_ENUM=%d", v) + } else { + fmt.printf("GL_%v=%d", GL_Enum(v), v) + } } else { - fmt.printf("GL_%v=%d", GL_Enum(v), v) + fmt.printf("%v", arg) } - } else { - fmt.printf("%v", arg) - } } // add return arguments @@ -810,7 +810,7 @@ when !GL_DEBUG { } // add location - fmt.printf(" in: %s(%d:%d)\n", from_loc.file_path, from_loc.line, from_loc.column) + fmt.printf(" in: %s(%d:%d)\n", from_loc.file_path, from_loc.line, from_loc.column) } } diff --git a/vendor/commonmark/cmark.odin b/vendor/commonmark/cmark.odin index 9ad71da3f..50544b9bd 100644 --- a/vendor/commonmark/cmark.odin +++ b/vendor/commonmark/cmark.odin @@ -494,15 +494,15 @@ free_cstring :: proc "c" (str: cstring) { free_rawptr(rawptr(str)) } free_string :: proc "c" (s: string) { - free_rawptr(raw_data(s)) + free_rawptr(raw_data(s)) } free :: proc{free_rawptr, free_cstring} // Wrap CMark allocator as Odin allocator @(private) cmark_allocator_proc :: proc(allocator_data: rawptr, mode: runtime.Allocator_Mode, - size, alignment: int, - old_memory: rawptr, old_size: int, loc := #caller_location) -> (res: []byte, err: runtime.Allocator_Error) { + size, alignment: int, + old_memory: rawptr, old_size: int, loc := #caller_location) -> (res: []byte, err: runtime.Allocator_Error) { cmark_alloc := cast(^Allocator)allocator_data switch mode { diff --git a/vendor/sdl2/sdl2.odin b/vendor/sdl2/sdl2.odin index 719390adc..73d95e18a 100644 --- a/vendor/sdl2/sdl2.odin +++ b/vendor/sdl2/sdl2.odin @@ -235,8 +235,8 @@ foreign lib { // quit QuitRequested :: #force_inline proc "c" () -> bool { - PumpEvents() - return bool(PeepEvents(nil, 0, .PEEKEVENT, .QUIT, .QUIT) > 0) + PumpEvents() + return bool(PeepEvents(nil, 0, .PEEKEVENT, .QUIT, .QUIT) > 0) } diff --git a/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py b/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py index caebe56a7..a551887ff 100644 --- a/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py +++ b/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py @@ -798,7 +798,7 @@ API_VERSION_1_2 :: (1<<22) | (2<<12) | (0) API_VERSION_1_3 :: (1<<22) | (3<<12) | (0) MAKE_VERSION :: proc(major, minor, patch: u32) -> u32 { - return (major<<22) | (minor<<12) | (patch) +\treturn (major<<22) | (minor<<12) | (patch) } // Base types diff --git a/vendor/vulkan/core.odin b/vendor/vulkan/core.odin index 764156b8d..79b856595 100644 --- a/vendor/vulkan/core.odin +++ b/vendor/vulkan/core.odin @@ -8,7 +8,7 @@ API_VERSION_1_2 :: (1<<22) | (2<<12) | (0) API_VERSION_1_3 :: (1<<22) | (3<<12) | (0) MAKE_VERSION :: proc(major, minor, patch: u32) -> u32 { - return (major<<22) | (minor<<12) | (patch) + return (major<<22) | (minor<<12) | (patch) } // Base types From b1a1da6618ce8ea5ffc8b7fca520895f01d36929 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 29 Jun 2024 19:54:31 +0100 Subject: [PATCH 103/129] Add `-vet-tabs` --- src/build_settings.cpp | 3 +++ src/main.cpp | 7 +++++++ src/parser.cpp | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/src/build_settings.cpp b/src/build_settings.cpp index d79343a8b..c3b4f2506 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -282,6 +282,7 @@ enum VetFlags : u64 { VetFlag_UnusedImports = 1u<<6, VetFlag_Deprecated = 1u<<7, VetFlag_Cast = 1u<<8, + VetFlag_Tabs = 1u<<9, VetFlag_Unused = VetFlag_UnusedVariables|VetFlag_UnusedImports, @@ -311,6 +312,8 @@ u64 get_vet_flag_from_name(String const &name) { return VetFlag_Deprecated; } else if (name == "cast") { return VetFlag_Cast; + } else if (name == "tabs") { + return VetFlag_Tabs; } return VetFlag_NONE; } diff --git a/src/main.cpp b/src/main.cpp index ea82651f5..53e631bb0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -301,6 +301,7 @@ enum BuildFlagKind { BuildFlag_VetStyle, BuildFlag_VetSemicolon, BuildFlag_VetCast, + BuildFlag_VetTabs, BuildFlag_CustomAttribute, BuildFlag_IgnoreUnknownAttributes, @@ -502,6 +503,7 @@ gb_internal bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_VetStyle, str_lit("vet-style"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_VetSemicolon, str_lit("vet-semicolon"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_VetCast, str_lit("vet-cast"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_VetTabs, str_lit("vet-tabs"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_CustomAttribute, str_lit("custom-attribute"), BuildFlagParam_String, Command__does_check, true); add_flag(&build_flags, BuildFlag_IgnoreUnknownAttributes, str_lit("ignore-unknown-attributes"), BuildFlagParam_None, Command__does_check); @@ -1157,6 +1159,7 @@ gb_internal bool parse_build_flags(Array args) { case BuildFlag_VetStyle: build_context.vet_flags |= VetFlag_Style; break; case BuildFlag_VetSemicolon: build_context.vet_flags |= VetFlag_Semicolon; break; case BuildFlag_VetCast: build_context.vet_flags |= VetFlag_Cast; break; + case BuildFlag_VetTabs: build_context.vet_flags |= VetFlag_Tabs; break; case BuildFlag_CustomAttribute: { @@ -2256,6 +2259,10 @@ gb_internal void print_show_help(String const arg0, String const &command) { print_usage_line(1, "-vet-cast"); print_usage_line(2, "Errs on casting a value to its own type or using `transmute` rather than `cast`."); print_usage_line(0, ""); + + print_usage_line(1, "-vet-tabs"); + print_usage_line(2, "Errs when the use of tabs has not been used for indentation."); + print_usage_line(0, ""); } if (check) { diff --git a/src/parser.cpp b/src/parser.cpp index 9b27ae156..51dc03085 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -5286,12 +5286,53 @@ gb_internal Ast *parse_stmt(AstFile *f) { return ast_bad_stmt(f, token, f->curr_token); } + + +gb_internal u64 check_vet_flags(AstFile *file) { + if (file && file->vet_flags_set) { + return file->vet_flags; + } + return build_context.vet_flags; +} + + +gb_internal void parse_enforce_tabs(AstFile *f) { + Token prev = f->prev_token; + Token curr = f->curr_token; + if (prev.pos.line < curr.pos.line) { + u8 *start = f->tokenizer.start+prev.pos.offset; + u8 *end = f->tokenizer.start+curr.pos.offset; + u8 *it = end; + while (it > start) { + if (*it == '\n') { + it++; + break; + } + it--; + } + + isize len = end-it; + for (isize i = 0; i < len; i++) { + if (it[i] == ' ') { + syntax_error(curr, "With '-vet-tabs', tabs must be used for indentation"); + break; + } + } + } +} + gb_internal Array parse_stmt_list(AstFile *f) { auto list = array_make(ast_allocator(f)); while (f->curr_token.kind != Token_case && f->curr_token.kind != Token_CloseBrace && f->curr_token.kind != Token_EOF) { + + // Checks to see if tabs have been used for indentation + if (check_vet_flags(f) & VetFlag_Tabs) { + parse_enforce_tabs(f); + } + Ast *stmt = parse_stmt(f); if (stmt && stmt->kind != Ast_EmptyStmt) { array_add(&list, stmt); From 34fce83d668f1f1754e88c29a8f0e3df71c60057 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 29 Jun 2024 20:04:34 +0100 Subject: [PATCH 104/129] Improve `-strict-style` rules for `if-else` statements --- src/parser.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/parser.cpp b/src/parser.cpp index 51dc03085..583f4a57d 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -1486,7 +1486,7 @@ gb_internal bool skip_possible_newline(AstFile *f) { return false; } -gb_internal bool skip_possible_newline_for_literal(AstFile *f, bool seen_where=false) { +gb_internal bool skip_possible_newline_for_literal(AstFile *f, bool ignore_strict_style=false) { Token curr = f->curr_token; if (token_is_newline(curr)) { Token next = peek_token(f); @@ -1494,7 +1494,7 @@ gb_internal bool skip_possible_newline_for_literal(AstFile *f, bool seen_where=f switch (next.kind) { case Token_OpenBrace: case Token_else: - if (build_context.strict_style && !seen_where) { + if (build_context.strict_style && !ignore_strict_style) { syntax_error(next, "With '-strict-style' the attached brace style (1TBS) is enforced"); } /*fallthrough*/ @@ -4548,7 +4548,11 @@ gb_internal Ast *parse_if_stmt(AstFile *f) { body = parse_block_stmt(f, false); } - skip_possible_newline_for_literal(f); + bool ignore_strict_style = false; + if (token.pos.line == ast_end_token(body).pos.line) { + ignore_strict_style = true; + } + skip_possible_newline_for_literal(f, ignore_strict_style); if (f->curr_token.kind == Token_else) { Token else_token = expect_token(f, Token_else); switch (f->curr_token.kind) { @@ -4600,7 +4604,11 @@ gb_internal Ast *parse_when_stmt(AstFile *f) { body = parse_block_stmt(f, true); } - skip_possible_newline_for_literal(f); + bool ignore_strict_style = false; + if (token.pos.line == ast_end_token(body).pos.line) { + ignore_strict_style = true; + } + skip_possible_newline_for_literal(f, ignore_strict_style); if (f->curr_token.kind == Token_else) { Token else_token = expect_token(f, Token_else); switch (f->curr_token.kind) { From 476d0087c8d47102c23cf6de71eb4014b9a7b6b2 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Sat, 29 Jun 2024 23:14:12 +0200 Subject: [PATCH 105/129] Fix bug in div3 fast path. --- core/math/big/private.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/math/big/private.odin b/core/math/big/private.odin index 220f39871..bb6b9497c 100644 --- a/core/math/big/private.odin +++ b/core/math/big/private.odin @@ -975,7 +975,7 @@ _private_int_div_3 :: proc(quotient, numerator: ^Int, allocator := context.alloc q.sign = numerator.sign w, t: _WORD - #no_bounds_check for ix := numerator.used; ix >= 0; ix -= 1 { + #no_bounds_check for ix := numerator.used - 1; ix >= 0; ix -= 1 { w = (w << _WORD(_DIGIT_BITS)) | _WORD(numerator.digit[ix]) if w >= 3 { /* From 604551eb2d106d64eb9159bc17aa5c57bbca0ca4 Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Sat, 29 Jun 2024 23:09:49 +0200 Subject: [PATCH 106/129] wasi: make the demo run on wasi and run it in CI --- .github/workflows/ci.yml | 8 ++++- base/runtime/entry_wasm.odin | 5 +++ base/runtime/os_specific_wasi.odin | 50 ++++++++++++++++++++++++++++-- base/runtime/wasm_allocator.odin | 2 +- core/encoding/cbor/tags.odin | 1 - core/os/os_wasi.odin | 12 +++++++ core/thread/thread.odin | 6 +++- core/thread/thread_js.odin | 47 ---------------------------- core/thread/thread_other.odin | 47 ++++++++++++++++++++++++++++ core/thread/thread_unix.odin | 2 ++ core/thread/thread_windows.odin | 2 ++ examples/demo/demo.odin | 1 + 12 files changed, 129 insertions(+), 54 deletions(-) delete mode 100644 core/thread/thread_js.odin create mode 100644 core/thread/thread_other.odin diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c9c453331..94f6bef12 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -97,7 +97,7 @@ jobs: - name: Download LLVM (MacOS ARM) if: matrix.os == 'macos-14' run: | - brew install llvm@17 + brew install llvm@17 wasmtime echo "/opt/homebrew/opt/llvm@17/bin" >> $GITHUB_PATH - name: Build Odin @@ -147,6 +147,12 @@ jobs: run: ./odin check examples/all -vet -strict-style -target:openbsd_amd64 if: matrix.os == 'ubuntu-latest' + - name: Run demo on WASI WASM32 + run: | + ./odin build examples/demo -target:wasi_wasm32 -vet -strict-style -out:demo.wasm + wasmtime ./demo.wasm + if: matrix.os == 'macos-14' + build_windows: name: Windows Build, Check, and Test runs-on: windows-2022 diff --git a/base/runtime/entry_wasm.odin b/base/runtime/entry_wasm.odin index a24c6f4b7..99cd8201d 100644 --- a/base/runtime/entry_wasm.odin +++ b/base/runtime/entry_wasm.odin @@ -22,6 +22,11 @@ when !ODIN_TEST && !ODIN_NO_ENTRY_POINT { @(link_name="_start", linkage="strong", require, export) _start :: proc "c" () { context = default_context() + + when ODIN_OS == .WASI { + _wasi_setup_args() + } + #force_no_inline _startup_runtime() intrinsics.__entry_point() } diff --git a/base/runtime/os_specific_wasi.odin b/base/runtime/os_specific_wasi.odin index 0e229ac7e..b85d7adea 100644 --- a/base/runtime/os_specific_wasi.odin +++ b/base/runtime/os_specific_wasi.odin @@ -2,10 +2,54 @@ //+private package runtime -import "core:sys/wasm/wasi" +foreign import wasi "wasi_snapshot_preview1" + +@(default_calling_convention="contextless") +foreign wasi { + fd_write :: proc( + fd: i32, + iovs: [][]byte, + n: ^uint, + ) -> u16 --- + + @(private="file") + args_sizes_get :: proc( + num_of_args: ^uint, + size_of_args: ^uint, + ) -> u16 --- + + @(private="file") + args_get :: proc( + argv: [^]cstring, + argv_buf: [^]byte, + ) -> u16 --- +} _stderr_write :: proc "contextless" (data: []byte) -> (int, _OS_Errno) { - data_iovec := (wasi.ciovec_t)(data) - n, err := wasi.fd_write(1, {data_iovec}) + n: uint + err := fd_write(1, {data}, &n) return int(n), _OS_Errno(err) } + +_wasi_setup_args :: proc() { + num_of_args, size_of_args: uint + if errno := args_sizes_get(&num_of_args, &size_of_args); errno != 0 { + return + } + + err: Allocator_Error + if args__, err = make([]cstring, num_of_args); err != nil { + return + } + + args_buf: []byte + if args_buf, err = make([]byte, size_of_args); err != nil { + delete(args__) + return + } + + if errno := args_get(raw_data(args__), raw_data(args_buf)); errno != 0 { + delete(args__) + delete(args_buf) + } +} diff --git a/base/runtime/wasm_allocator.odin b/base/runtime/wasm_allocator.odin index fb0600ea2..f4b399c47 100644 --- a/base/runtime/wasm_allocator.odin +++ b/base/runtime/wasm_allocator.odin @@ -760,7 +760,7 @@ free :: proc(a: ^WASM_Allocator, ptr: rawptr, loc := #caller_location) { defer unlock(a) size := region.size - assert(region_is_in_use(region), "double free", loc=loc) + assert(region_is_in_use(region), "double free or corrupt region", loc=loc) prev_region_size_field := ([^]uint)(region)[-1] prev_region_size := prev_region_size_field & ~uint(FREE_REGION_FLAG) diff --git a/core/encoding/cbor/tags.odin b/core/encoding/cbor/tags.odin index 3dc79a5dd..17420af46 100644 --- a/core/encoding/cbor/tags.odin +++ b/core/encoding/cbor/tags.odin @@ -95,7 +95,6 @@ tag_register_number :: proc(impl: Tag_Implementation, nr: Tag_Number, id: string } // Controls initialization of default tag implementations. -// JS and WASI default to a panic allocator so we don't want to do it on those. INITIALIZE_DEFAULT_TAGS :: #config(CBOR_INITIALIZE_DEFAULT_TAGS, !ODIN_DEFAULT_TO_PANIC_ALLOCATOR && !ODIN_DEFAULT_TO_NIL_ALLOCATOR) @(private, init, disabled=!INITIALIZE_DEFAULT_TAGS) diff --git a/core/os/os_wasi.odin b/core/os/os_wasi.odin index 9bfd87322..8a1acb194 100644 --- a/core/os/os_wasi.odin +++ b/core/os/os_wasi.odin @@ -6,6 +6,8 @@ import "base:runtime" Handle :: distinct i32 Errno :: distinct i32 +INVALID_HANDLE :: -1 + ERROR_NONE :: Errno(wasi.errno_t.SUCCESS) O_RDONLY :: 0x00000 @@ -26,6 +28,16 @@ stdout: Handle = 1 stderr: Handle = 2 current_dir: Handle = 3 +args := _alloc_command_line_arguments() + +_alloc_command_line_arguments :: proc() -> (args: []string) { + args = make([]string, len(runtime.args__)) + for &arg, i in args { + arg = string(runtime.args__[i]) + } + return +} + write :: proc(fd: Handle, data: []byte) -> (int, Errno) { iovs := wasi.ciovec_t(data) n, err := wasi.fd_write(wasi.fd_t(fd), {iovs}) diff --git a/core/thread/thread.odin b/core/thread/thread.odin index 55f73d106..80e60d6cf 100644 --- a/core/thread/thread.odin +++ b/core/thread/thread.odin @@ -6,6 +6,8 @@ import "base:intrinsics" _ :: intrinsics +IS_SUPPORTED :: _IS_SUPPORTED + Thread_Proc :: #type proc(^Thread) MAX_USER_ARGUMENTS :: 8 @@ -58,7 +60,9 @@ Thread :: struct { creation_allocator: mem.Allocator, } -#assert(size_of(Thread{}.user_index) == size_of(uintptr)) +when IS_SUPPORTED { + #assert(size_of(Thread{}.user_index) == size_of(uintptr)) +} Thread_Priority :: enum { Normal, diff --git a/core/thread/thread_js.odin b/core/thread/thread_js.odin deleted file mode 100644 index 4f5b5b086..000000000 --- a/core/thread/thread_js.odin +++ /dev/null @@ -1,47 +0,0 @@ -//+build js -package thread - -import "base:intrinsics" -import "core:sync" -import "core:mem" - -Thread_Os_Specific :: struct {} - -_thread_priority_map := [Thread_Priority]i32{ - .Normal = 0, - .Low = -2, - .High = +2, -} - -_create :: proc(procedure: Thread_Proc, priority := Thread_Priority.Normal) -> ^Thread { - unimplemented("core:thread procedure not supported on js target") -} - -_start :: proc(t: ^Thread) { - unimplemented("core:thread procedure not supported on js target") -} - -_is_done :: proc(t: ^Thread) -> bool { - unimplemented("core:thread procedure not supported on js target") -} - -_join :: proc(t: ^Thread) { - unimplemented("core:thread procedure not supported on js target") -} - -_join_multiple :: proc(threads: ..^Thread) { - unimplemented("core:thread procedure not supported on js target") -} - -_destroy :: proc(thread: ^Thread) { - unimplemented("core:thread procedure not supported on js target") -} - -_terminate :: proc(using thread : ^Thread, exit_code: int) { - unimplemented("core:thread procedure not supported on js target") -} - -_yield :: proc() { - unimplemented("core:thread procedure not supported on js target") -} - diff --git a/core/thread/thread_other.odin b/core/thread/thread_other.odin new file mode 100644 index 000000000..34bbfda08 --- /dev/null +++ b/core/thread/thread_other.odin @@ -0,0 +1,47 @@ +//+build js, wasi, orca +package thread + +import "base:intrinsics" + +_IS_SUPPORTED :: false + +Thread_Os_Specific :: struct {} + +_thread_priority_map := [Thread_Priority]i32{ + .Normal = 0, + .Low = -2, + .High = +2, +} + +_create :: proc(procedure: Thread_Proc, priority := Thread_Priority.Normal) -> ^Thread { + unimplemented("core:thread procedure not supported on target") +} + +_start :: proc(t: ^Thread) { + unimplemented("core:thread procedure not supported on target") +} + +_is_done :: proc(t: ^Thread) -> bool { + unimplemented("core:thread procedure not supported on target") +} + +_join :: proc(t: ^Thread) { + unimplemented("core:thread procedure not supported on target") +} + +_join_multiple :: proc(threads: ..^Thread) { + unimplemented("core:thread procedure not supported on target") +} + +_destroy :: proc(thread: ^Thread) { + unimplemented("core:thread procedure not supported on target") +} + +_terminate :: proc(using thread : ^Thread, exit_code: int) { + unimplemented("core:thread procedure not supported on target") +} + +_yield :: proc() { + unimplemented("core:thread procedure not supported on target") +} + diff --git a/core/thread/thread_unix.odin b/core/thread/thread_unix.odin index 2218afdd3..363f50862 100644 --- a/core/thread/thread_unix.odin +++ b/core/thread/thread_unix.odin @@ -6,6 +6,8 @@ import "core:sync" import "core:sys/unix" import "core:time" +_IS_SUPPORTED :: true + CAS :: sync.atomic_compare_exchange_strong // NOTE(tetra): Aligned here because of core/unix/pthread_linux.odin/pthread_t. diff --git a/core/thread/thread_windows.odin b/core/thread/thread_windows.odin index 314ef5842..8da75a2d9 100644 --- a/core/thread/thread_windows.odin +++ b/core/thread/thread_windows.odin @@ -6,6 +6,8 @@ import "base:intrinsics" import "core:sync" import win32 "core:sys/windows" +_IS_SUPPORTED :: true + Thread_Os_Specific :: struct { win32_thread: win32.HANDLE, win32_thread_id: win32.DWORD, diff --git a/examples/demo/demo.odin b/examples/demo/demo.odin index e27686099..0ad9f4ab0 100644 --- a/examples/demo/demo.odin +++ b/examples/demo/demo.odin @@ -1140,6 +1140,7 @@ prefix_table := [?]string{ print_mutex := b64(false) +@(disabled=!thread.IS_SUPPORTED) threading_example :: proc() { fmt.println("\n# threading_example") From af3401631ad44487b7fba47330bfffea9ccf797b Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 29 Jun 2024 22:48:43 +0100 Subject: [PATCH 107/129] Remove the `-disallow-do` aspect from `-strict-style` --- src/main.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 53e631bb0..dca2b7fc8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1279,7 +1279,6 @@ gb_internal bool parse_build_flags(Array args) { break; case BuildFlag_StrictStyle: build_context.strict_style = true; - build_context.disallow_do = true; break; case BuildFlag_Short: build_context.cmd_doc_flags |= CmdDocFlag_Short; @@ -2364,7 +2363,6 @@ gb_internal void print_show_help(String const arg0, String const &command) { print_usage_line(2, "Errs on deprecated syntax."); print_usage_line(2, "Errs when the attached-brace style in not adhered to (also known as 1TBS)."); print_usage_line(2, "Errs when 'case' labels are not in the same column as the associated 'switch' token."); - print_usage_line(2, "Disallows the 'do' keyword in the project (same as '-disallow-do')."); print_usage_line(0, ""); print_usage_line(1, "-ignore-warnings"); From 80592f0f5138a6519a77e68cc9e4a7d61865f2cc Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 29 Jun 2024 22:50:23 +0100 Subject: [PATCH 108/129] Add `-disallow-do` in CI --- .github/workflows/ci.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 94f6bef12..ca3d87b12 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,8 +32,8 @@ jobs: gmake -C vendor/stb/src gmake -C vendor/cgltf/src gmake -C vendor/miniaudio/src - ./odin check examples/all -vet -strict-style -target:netbsd_amd64 - ./odin check examples/all -vet -strict-style -target:netbsd_arm64 + ./odin check examples/all -vet -strict-style -disallow-do -target:netbsd_amd64 + ./odin check examples/all -vet -strict-style -disallow-do -target:netbsd_arm64 ./odin test tests/core/normal.odin -file -all-packages -define:ODIN_TEST_FANCY=false ./odin test tests/core/speed.odin -file -all-packages -o:speed -define:ODIN_TEST_FANCY=false ./odin test tests/vendor -all-packages -define:ODIN_TEST_FANCY=false @@ -62,7 +62,7 @@ jobs: gmake -C vendor/stb/src gmake -C vendor/cgltf/src gmake -C vendor/miniaudio/src - ./odin check examples/all -vet -strict-style -target:freebsd_amd64 + ./odin check examples/all -vet -strict-style -disallow-do -target:freebsd_amd64 ./odin test tests/core/normal.odin -file -all-packages -define:ODIN_TEST_FANCY=false ./odin test tests/core/speed.odin -file -all-packages -o:speed -define:ODIN_TEST_FANCY=false ./odin test tests/vendor -all-packages -define:ODIN_TEST_FANCY=false @@ -135,21 +135,21 @@ jobs: ./run.sh - name: Odin check examples/all for Linux i386 - run: ./odin check examples/all -vet -strict-style -target:linux_i386 + run: ./odin check examples/all -vet -strict-style -disallow-do -target:linux_i386 if: matrix.os == 'ubuntu-latest' - name: Odin check examples/all for Linux arm64 - run: ./odin check examples/all -vet -strict-style -target:linux_arm64 + run: ./odin check examples/all -vet -strict-style -disallow-do -target:linux_arm64 if: matrix.os == 'ubuntu-latest' - name: Odin check examples/all for FreeBSD amd64 - run: ./odin check examples/all -vet -strict-style -target:freebsd_amd64 + run: ./odin check examples/all -vet -strict-style -disallow-do -target:freebsd_amd64 if: matrix.os == 'ubuntu-latest' - name: Odin check examples/all for OpenBSD amd64 - run: ./odin check examples/all -vet -strict-style -target:openbsd_amd64 + run: ./odin check examples/all -vet -strict-style -disallow-do -target:openbsd_amd64 if: matrix.os == 'ubuntu-latest' - name: Run demo on WASI WASM32 run: | - ./odin build examples/demo -target:wasi_wasm32 -vet -strict-style -out:demo.wasm + ./odin build examples/demo -target:wasi_wasm32 -vet -strict-style -disallow-do -out:demo.wasm wasmtime ./demo.wasm if: matrix.os == 'macos-14' From 8b305a4c67b0ddab5c1133c6e0efce85c98c46c5 Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Sat, 29 Jun 2024 18:03:32 -0400 Subject: [PATCH 109/129] Add `UCG` library to Odin compiler --- src/ucg/ucg.c | 686 +++++++++++ src/ucg/ucg_tables.h | 2629 ++++++++++++++++++++++++++++++++++++++++++ src/unicode.cpp | 5 + 3 files changed, 3320 insertions(+) create mode 100644 src/ucg/ucg.c create mode 100644 src/ucg/ucg_tables.h diff --git a/src/ucg/ucg.c b/src/ucg/ucg.c new file mode 100644 index 000000000..c3e270e1a --- /dev/null +++ b/src/ucg/ucg.c @@ -0,0 +1,686 @@ +/* + * SPDX-FileCopyrightText: (c) 2024 Feoramund + * SPDX-License-Identifier: BSD-3-Clause + */ + + +// +// NOTE(Feoramund): This is my UCG library, adapted for use within the Odin compiler. +// Most of the comments have been let alone and may not strictly apply anymore. +// +// 1. The UCG allocator interface was replaced by gbAllocator. +// 2. The UCG UTF-8 decoder was replaced with the one already in the compiler. +// 3. Non-essential code was stripped. +// 4. Some types were changed for compatibility. +// + + +/* This is the data that is allocated when an allocator is passed to + * ucg_decode_grapheme_clusters. */ +typedef struct { + i32 byte_index; + i32 rune_index; + i32 width; +} ucg_grapheme; + + +/* #include "ucg.h" */ +#include "ucg_tables.h" + +#define UCG_TABLE_LEN(t) (sizeof(t) / sizeof(int32_t)) + +#define ZERO_WIDTH_SPACE 0x200B +#define ZERO_WIDTH_NON_JOINER 0x200C +#define ZERO_WIDTH_JOINER 0x200D +#define WORD_JOINER 0x2060 + +int ucg_binary_search(int32_t value, const int32_t* table, int length, int stride) { + GB_ASSERT(table != NULL); + GB_ASSERT(length > 0); + GB_ASSERT(stride > 0); + + int n = length; + int t = 0; + for (/**/; n > 1; /**/) { + int m = n / 2; + int p = t + m * stride; + if (value >= table[p]) { + t = p; + n = n - m; + } else { + n = m; + } + } + if (n != 0 && value >= table[t]) { + return t; + } + return -1; +} + +// +// The procedures below are accurate as of Unicode 15.1.0. +// + +bool ucg_is_control(int32_t r) { + if (r <= 0x1F || (0x7F <= r && r <= 0x9F)) { + return true; + } + return false; +} + +// Emoji_Modifier +bool ucg_is_emoji_modifier(int32_t r) { + return 0x1F3FB <= r && r <= 0x1F3FF; +} + +// Regional_Indicator +bool ucg_is_regional_indicator(int32_t r) { + return 0x1F1E6 <= r && r <= 0x1F1FF; +} + +// General_Category=Enclosing_Mark +bool ucg_is_enclosing_mark(int32_t r) { + switch (r) { + case 0x0488: + case 0x0489: + case 0x1ABE: + return true; + } + + if (0x20DD <= r && r <= 0x20E0) { return true; } + if (0x20E2 <= r && r <= 0x20E4) { return true; } + if (0xA670 <= r && r <= 0xA672) { return true; } + + return false; +} + +// Prepended_Concatenation_Mark +bool ucg_is_prepended_concatenation_mark(int32_t r) { + switch (r) { + case 0x006DD: + case 0x0070F: + case 0x008E2: + case 0x110BD: + case 0x110CD: + return true; + } + + if (0x00600 <= r && r <= 0x00605) { return true; } + if (0x00890 <= r && r <= 0x00891) { return true; } + + return false; +} + +// General_Category=Spacing_Mark +bool ucg_is_spacing_mark(int32_t r) { + intptr_t p = ucg_binary_search(r, ucg_spacing_mark_ranges, UCG_TABLE_LEN(ucg_spacing_mark_ranges)/2, 2); + if (p >= 0 && ucg_spacing_mark_ranges[p] <= r && r <= ucg_spacing_mark_ranges[p+1]) { + return true; + } + return false; +} + +// General_Category=Nonspacing_Mark +bool ucg_is_nonspacing_mark(int32_t r) { + intptr_t p = ucg_binary_search(r, ucg_nonspacing_mark_ranges, UCG_TABLE_LEN(ucg_nonspacing_mark_ranges)/2, 2); + if (p >= 0 && ucg_nonspacing_mark_ranges[p] <= r && r <= ucg_nonspacing_mark_ranges[p+1]) { + return true; + } + return false; +} + +// Extended_Pictographic +bool ucg_is_emoji_extended_pictographic(int32_t r) { + intptr_t p = ucg_binary_search(r, ucg_emoji_extended_pictographic_ranges, UCG_TABLE_LEN(ucg_emoji_extended_pictographic_ranges)/2, 2); + if (p >= 0 && ucg_emoji_extended_pictographic_ranges[p] <= r && r <= ucg_emoji_extended_pictographic_ranges[p+1]) { + return true; + } + return false; +} + +// Grapheme_Extend +bool ucg_is_grapheme_extend(int32_t r) { + intptr_t p = ucg_binary_search(r, ucg_grapheme_extend_ranges, UCG_TABLE_LEN(ucg_grapheme_extend_ranges)/2, 2); + if (p >= 0 && ucg_grapheme_extend_ranges[p] <= r && r <= ucg_grapheme_extend_ranges[p+1]) { + return true; + } + return false; +} + + +// Hangul_Syllable_Type=Leading_Jamo +bool ucg_is_hangul_syllable_leading(int32_t r) { + return (0x1100 <= r && r <= 0x115F) || (0xA960 <= r && r <= 0xA97C); +} + +// Hangul_Syllable_Type=Vowel_Jamo +bool ucg_is_hangul_syllable_vowel(int32_t r) { + return (0x1160 <= r && r <= 0x11A7) || (0xD7B0 <= r && r <= 0xD7C6); +} + +// Hangul_Syllable_Type=Trailing_Jamo +bool ucg_is_hangul_syllable_trailing(int32_t r) { + return (0x11A8 <= r && r <= 0x11FF) || (0xD7CB <= r && r <= 0xD7FB); +} + +// Hangul_Syllable_Type=LV_Syllable +bool ucg_is_hangul_syllable_lv(int32_t r) { + intptr_t p = ucg_binary_search(r, ucg_hangul_syllable_lv_singlets, UCG_TABLE_LEN(ucg_hangul_syllable_lv_singlets), 1); + if (p >= 0 && r == ucg_hangul_syllable_lv_singlets[p]) { + return true; + } + return false; +} + +// Hangul_Syllable_Type=LVT_Syllable +bool ucg_is_hangul_syllable_lvt(int32_t r) { + intptr_t p = ucg_binary_search(r, ucg_hangul_syllable_lvt_ranges, UCG_TABLE_LEN(ucg_hangul_syllable_lvt_ranges)/2, 2); + if (p >= 0 && ucg_hangul_syllable_lvt_ranges[p] <= r && r <= ucg_hangul_syllable_lvt_ranges[p+1]) { + return true; + } + return false; +} + + +// Indic_Syllabic_Category=Consonant_Preceding_Repha +bool ucg_is_indic_consonant_preceding_repha(int32_t r) { + switch (r) { + case 0x00D4E: + case 0x11941: + case 0x11D46: + case 0x11F02: + return true; + } + return false; +} + +// Indic_Syllabic_Category=Consonant_Prefixed +bool ucg_is_indic_consonant_prefixed(int32_t r) { + switch (r) { + case 0x1193F: + case 0x11A3A: + return true; + } + + if (0x111C2 <= r && r <= 0x111C3) { return true; } + if (0x11A84 <= r && r <= 0x11A89) { return true; } + + return false; +} + +// Indic_Conjunct_Break=Linker +bool ucg_is_indic_conjunct_break_linker(int32_t r) { + switch (r) { + case 0x094D: + case 0x09CD: + case 0x0ACD: + case 0x0B4D: + case 0x0C4D: + case 0x0D4D: + return true; + } + return false; +} + +// Indic_Conjunct_Break=Consonant +bool ucg_is_indic_conjunct_break_consonant(int32_t r) { + intptr_t p = ucg_binary_search(r, ucg_indic_conjunct_break_consonant_ranges, UCG_TABLE_LEN(ucg_indic_conjunct_break_consonant_ranges)/2, 2); + if (p >= 0 && ucg_indic_conjunct_break_consonant_ranges[p] <= r && r <= ucg_indic_conjunct_break_consonant_ranges[p+1]) { + return true; + } + return false; +} + +// Indic_Conjunct_Break=Extend +bool ucg_is_indic_conjunct_break_extend(int32_t r) { + intptr_t p = ucg_binary_search(r, ucg_indic_conjunct_break_extend_ranges, UCG_TABLE_LEN(ucg_indic_conjunct_break_extend_ranges)/2, 2); + if (p >= 0 && ucg_indic_conjunct_break_extend_ranges[p] <= r && r <= ucg_indic_conjunct_break_extend_ranges[p+1]) { + return true; + } + return false; +} + + +/* +``` +Indic_Syllabic_Category = Consonant_Preceding_Repha, or +Indic_Syllabic_Category = Consonant_Prefixed, or +Prepended_Concatenation_Mark = Yes +``` +*/ +bool ucg_is_gcb_prepend_class(int32_t r) { + return ucg_is_indic_consonant_preceding_repha(r) || ucg_is_indic_consonant_prefixed(r) || ucg_is_prepended_concatenation_mark(r); +} + +/* +``` +Grapheme_Extend = Yes, or +Emoji_Modifier = Yes + +This includes: +General_Category = Nonspacing_Mark +General_Category = Enclosing_Mark +U+200C ZERO WIDTH NON-JOINER + +plus a few General_Category = Spacing_Mark needed for canonical equivalence. +``` +*/ +bool ucg_is_gcb_extend_class(int32_t r) { + return ucg_is_grapheme_extend(r) || ucg_is_emoji_modifier(r); +} + +// Return values: +// +// - 2 if East_Asian_Width=F or W, or +// - 0 if non-printable / zero-width, or +// - 1 in all other cases. +// +int ucg_normalized_east_asian_width(int32_t r) { + if (ucg_is_control(r)) { + return 0; + } else if (r <= 0x10FF) { + // Easy early out for low runes. + return 1; + } + + switch (r) { + // This is a different interpretation of the BOM which occurs in the middle of text. + case 0xFEFF: /* ZERO_WIDTH_NO_BREAK_SPACE */ + case ZERO_WIDTH_SPACE: + case ZERO_WIDTH_NON_JOINER: + case ZERO_WIDTH_JOINER: + case WORD_JOINER: + return 0; + } + + intptr_t p = ucg_binary_search(r, ucg_normalized_east_asian_width_ranges, UCG_TABLE_LEN(ucg_normalized_east_asian_width_ranges)/3, 3); + if (p >= 0 && ucg_normalized_east_asian_width_ranges[p] <= r && r <= ucg_normalized_east_asian_width_ranges[p+1]) { + return (int)ucg_normalized_east_asian_width_ranges[p+2]; + } + return 1; +} + +// +// End of Unicode 15.1.0 block. +// + +enum grapheme_cluster_sequence { + None, + Indic, + Emoji, + Regional, +}; + +typedef struct { + ucg_grapheme* graphemes; + i32 rune_count; + i32 grapheme_count; + i32 width; + + int32_t last_rune; + bool last_rune_breaks_forward; + + i32 last_width; + i32 last_grapheme_count; + + bool bypass_next_rune; + + int regional_indicator_counter; + + enum grapheme_cluster_sequence current_sequence; + bool continue_sequence; +} ucg_decoder_state; + + +void _ucg_decode_grapheme_clusters_deferred_step( + gbAllocator allocator, + ucg_decoder_state* state, + i32 byte_index, + int32_t this_rune +) { + // "Break at the start and end of text, unless the text is empty." + // + // GB1: sot ÷ Any + // GB2: Any ÷ eot + if (state->rune_count == 0 && state->grapheme_count == 0) { + state->grapheme_count += 1; + } + + if (state->grapheme_count > state->last_grapheme_count) { + state->width += ucg_normalized_east_asian_width(this_rune); + + /* if (allocator != NULL) { */ + state->graphemes = (ucg_grapheme*)gb_resize(allocator, + state->graphemes, + sizeof(ucg_grapheme) * (state->grapheme_count), + sizeof(ucg_grapheme) * (1 + state->grapheme_count)); + + ucg_grapheme append = { + byte_index, + state->rune_count, + state->width - state->last_width, + }; + + state->graphemes[state->grapheme_count - 1] = append; + /* } */ + + state->last_grapheme_count = state->grapheme_count; + state->last_width = state->width; + } + + state->last_rune = this_rune; + state->rune_count += 1; + + if (!state->continue_sequence) { + state->current_sequence = None; + state->regional_indicator_counter = 0; + } + state->continue_sequence = false; +} + +int ucg_decode_grapheme_clusters( + gbAllocator allocator, + const uint8_t* str, + int str_len, + + ucg_grapheme** out_graphemes, + i32* out_rune_count, + i32* out_grapheme_count, + i32* out_width +) { + // The following procedure implements text segmentation by breaking on + // Grapheme Cluster Boundaries[1], using the values[2] and rules[3] from + // the Unicode® Standard Annex #29, entitled: + // + // UNICODE TEXT SEGMENTATION + // + // Version: Unicode 15.1.0 + // Date: 2023-08-16 + // Revision: 43 + // + // This procedure is conformant[4] to UAX29-C1-1, otherwise known as the + // extended, non-legacy ruleset. + // + // Please see the references for more information. + // + // + // [1]: https://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries + // [2]: https://www.unicode.org/reports/tr29/#Default_Grapheme_Cluster_Table + // [3]: https://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundary_Rules + // [4]: https://www.unicode.org/reports/tr29/#Conformance + + // Additionally, this procedure takes into account Standard Annex #11, + // in order to estimate how visually wide the string will appear on a + // monospaced display. This can only ever be a rough guess, as this tends + // to be an implementation detail relating to which fonts are being used, + // how codepoints are interpreted and drawn, if codepoint sequences are + // interpreted correctly, and et cetera. + // + // For example, a program may not properly interpret an emoji modifier + // sequence and print the component glyphs instead of one whole glyph. + // + // See here for more information: https://www.unicode.org/reports/tr11/ + // + // NOTE: There is no explicit mention of what to do with zero-width spaces + // as far as grapheme cluster segmentation goes, therefore this + // implementation may count and return graphemes with a `width` of zero. + // + // Treat them as any other space. + + ucg_decoder_state state = {0}; + +#define UCG_DEFERRED_DECODE_STEP() (_ucg_decode_grapheme_clusters_deferred_step(allocator, &state, byte_index, this_rune)) + + for (i32 byte_index = 0, bytes_advanced = 0; byte_index < str_len; byte_index += bytes_advanced) { + int32_t this_rune = GB_RUNE_INVALID; + bytes_advanced = (i32)(utf8_decode(str+byte_index, str_len-byte_index, &this_rune)); + if (this_rune == GB_RUNE_INVALID || bytes_advanced == 0) { + // There was a Unicode parsing error; bail out. + if (out_graphemes != NULL) { *out_graphemes = state.graphemes; } + if (out_rune_count != NULL) { *out_rune_count = state.rune_count; } + if (out_grapheme_count != NULL) { *out_grapheme_count = state.grapheme_count; } + if (out_width != NULL) { *out_width = state.width; } + + // Return an error code. + return -1; + } + + // "Do not break between a CR and LF. Otherwise, break before and after controls." + // + // GB3: CR × LF + // GB4: (Control | CR | LF) ÷ + // GB5: ÷ (Control | CR | LF) + if (this_rune == '\n' && state.last_rune == '\r') { + state.last_rune_breaks_forward = false; + state.bypass_next_rune = false; + UCG_DEFERRED_DECODE_STEP(); continue; + } + + if (ucg_is_control(this_rune)) { + state.grapheme_count += 1; + state.last_rune_breaks_forward = true; + state.bypass_next_rune = true; + UCG_DEFERRED_DECODE_STEP(); continue; + } + + // (This check is for rules that work forwards, instead of backwards.) + if (state.bypass_next_rune) { + if (state.last_rune_breaks_forward) { + state.grapheme_count += 1; + state.last_rune_breaks_forward = false; + } + + state.bypass_next_rune = false; + UCG_DEFERRED_DECODE_STEP(); continue; + } + + // (Optimization 1: Prevent low runes from proceeding further.) + // + // * 0xA9 and 0xAE are in the Extended_Pictographic range, + // which is checked later in GB11. + if (this_rune != 0xA9 && this_rune != 0xAE && this_rune <= 0x2FF) { + state.grapheme_count += 1; + UCG_DEFERRED_DECODE_STEP(); continue; + } + + // (Optimization 2: Check if the rune is in the Hangul space before getting specific.) + if (0x1100 <= this_rune && this_rune <= 0xD7FB) { + // "Do not break Hangul syllable sequences." + // + // GB6: L × (L | V | LV | LVT) + // GB7: (LV | V) × (V | T) + // GB8: (LVT | T) × T + if (ucg_is_hangul_syllable_leading(this_rune) || + ucg_is_hangul_syllable_lv(this_rune) || + ucg_is_hangul_syllable_lvt(this_rune)) + { + if (!ucg_is_hangul_syllable_leading(state.last_rune)) { + state.grapheme_count += 1; + } + UCG_DEFERRED_DECODE_STEP(); continue; + } + + if (ucg_is_hangul_syllable_vowel(this_rune)) { + if (ucg_is_hangul_syllable_leading(state.last_rune) || + ucg_is_hangul_syllable_vowel(state.last_rune) || + ucg_is_hangul_syllable_lv(state.last_rune)) + { + UCG_DEFERRED_DECODE_STEP(); continue; + } + state.grapheme_count += 1; + UCG_DEFERRED_DECODE_STEP(); continue; + } + + if (ucg_is_hangul_syllable_trailing(this_rune)) { + if (ucg_is_hangul_syllable_trailing(state.last_rune) || + ucg_is_hangul_syllable_lvt(state.last_rune) || + ucg_is_hangul_syllable_lv(state.last_rune) || + ucg_is_hangul_syllable_vowel(state.last_rune)) + { + UCG_DEFERRED_DECODE_STEP(); continue; + } + state.grapheme_count += 1; + UCG_DEFERRED_DECODE_STEP(); continue; + } + } + + // "Do not break before extending characters or ZWJ." + // + // GB9: × (Extend | ZWJ) + if (this_rune == ZERO_WIDTH_JOINER) { + state.continue_sequence = true; + UCG_DEFERRED_DECODE_STEP(); continue; + } + + if (ucg_is_gcb_extend_class(this_rune)) { + // (Support for GB9c.) + if (state.current_sequence == Indic) { + if (ucg_is_indic_conjunct_break_extend(this_rune) && ( + ucg_is_indic_conjunct_break_linker(state.last_rune) || + ucg_is_indic_conjunct_break_consonant(state.last_rune) )) + { + state.continue_sequence = true; + UCG_DEFERRED_DECODE_STEP(); continue; + } + + if (ucg_is_indic_conjunct_break_linker(this_rune) && ( + ucg_is_indic_conjunct_break_linker(state.last_rune) || + ucg_is_indic_conjunct_break_extend(state.last_rune) || + ucg_is_indic_conjunct_break_consonant(state.last_rune) )) + { + state.continue_sequence = true; + UCG_DEFERRED_DECODE_STEP(); continue; + } + + UCG_DEFERRED_DECODE_STEP(); continue; + } + + // (Support for GB11.) + if (state.current_sequence == Emoji && ( + ucg_is_gcb_extend_class(state.last_rune) || + ucg_is_emoji_extended_pictographic(state.last_rune) )) + { + state.continue_sequence = true; + } + + UCG_DEFERRED_DECODE_STEP(); continue; + } + + // _The GB9a and GB9b rules only apply to extended grapheme clusters:_ + // "Do not break before SpacingMarks, or after Prepend characters." + // + // GB9a: × SpacingMark + // GB9b: Prepend × + if (ucg_is_spacing_mark(this_rune)) { + UCG_DEFERRED_DECODE_STEP(); continue; + } + + if (ucg_is_gcb_prepend_class(this_rune)) { + state.grapheme_count += 1; + state.bypass_next_rune = true; + UCG_DEFERRED_DECODE_STEP(); continue; + } + + // _The GB9c rule only applies to extended grapheme clusters:_ + // "Do not break within certain combinations with Indic_Conjunct_Break (InCB)=Linker." + // + // GB9c: \p{InCB=Consonant} [ \p{InCB=Extend} \p{InCB=Linker} ]* \p{InCB=Linker} [ \p{InCB=Extend} \p{InCB=Linker} ]* × \p{InCB=Consonant} + if (ucg_is_indic_conjunct_break_consonant(this_rune)) { + if (state.current_sequence == Indic) { + if (state.last_rune == ZERO_WIDTH_JOINER || + ucg_is_indic_conjunct_break_linker(state.last_rune)) + { + state.continue_sequence = true; + } else { + state.grapheme_count += 1; + } + } else { + state.grapheme_count += 1; + state.current_sequence = Indic; + state.continue_sequence = true; + } + UCG_DEFERRED_DECODE_STEP(); continue; + } + + if (ucg_is_indic_conjunct_break_extend(this_rune)) { + if (state.current_sequence == Indic) { + if (ucg_is_indic_conjunct_break_consonant(state.last_rune) || + ucg_is_indic_conjunct_break_linker(state.last_rune)) + { + state.continue_sequence = true; + } else { + state.grapheme_count += 1; + } + } + UCG_DEFERRED_DECODE_STEP(); continue; + } + + if (ucg_is_indic_conjunct_break_linker(this_rune)) { + if (state.current_sequence == Indic) { + if (ucg_is_indic_conjunct_break_extend(state.last_rune) || + ucg_is_indic_conjunct_break_linker(state.last_rune)) + { + state.continue_sequence = true; + } else { + state.grapheme_count += 1; + } + } + UCG_DEFERRED_DECODE_STEP(); continue; + } + + // + // (Curiously, there is no GB10.) + // + + // "Do not break within emoji modifier sequences or emoji zwj sequences." + // + // GB11: \p{Extended_Pictographic} Extend* ZWJ × \p{Extended_Pictographic} + if (ucg_is_emoji_extended_pictographic(this_rune)) { + if (state.current_sequence != Emoji || state.last_rune != ZERO_WIDTH_JOINER) { + state.grapheme_count += 1; + } + state.current_sequence = Emoji; + state.continue_sequence = true; + UCG_DEFERRED_DECODE_STEP(); continue; + } + + // "Do not break within emoji flag sequences. + // That is, do not break between regional indicator (RI) symbols + // if there is an odd number of RI characters before the break point." + // + // GB12: sot (RI RI)* RI × RI + // GB13: [^RI] (RI RI)* RI × RI + if (ucg_is_regional_indicator(this_rune)) { + if ((state.regional_indicator_counter & 1) == 0) { + state.grapheme_count += 1; + } + + state.current_sequence = Regional; + state.continue_sequence = true; + state.regional_indicator_counter += 1; + + UCG_DEFERRED_DECODE_STEP(); continue; + } + + // "Otherwise, break everywhere." + // + // GB999: Any ÷ Any + state.grapheme_count += 1; + UCG_DEFERRED_DECODE_STEP(); + } + +#undef UCG_DEFERRED_DECODE_STEP + + if (out_graphemes != NULL) { *out_graphemes = state.graphemes; } + if (out_rune_count != NULL) { *out_rune_count = state.rune_count; } + if (out_grapheme_count != NULL) { *out_grapheme_count = state.grapheme_count; } + if (out_width != NULL) { *out_width = state.width; } + + return 0; +} + +#undef UCG_TABLE_LEN +#undef ZERO_WIDTH_SPACE +#undef ZERO_WIDTH_NON_JOINER +#undef ZERO_WIDTH_JOINER +#undef WORD_JOINER diff --git a/src/ucg/ucg_tables.h b/src/ucg/ucg_tables.h new file mode 100644 index 000000000..a33f9f898 --- /dev/null +++ b/src/ucg/ucg_tables.h @@ -0,0 +1,2629 @@ +/* + * SPDX-FileCopyrightText: (c) 2024 Feoramund + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef _UCG_TABLES_INCLUDED +#define _UCG_TABLES_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +// +// The tables below are accurate as of Unicode 15.1.0. +// + +static const int32_t ucg_spacing_mark_ranges[] = { + 0x0903, 0x0903, + 0x093B, 0x093B, + 0x093E, 0x0940, + 0x0949, 0x094C, + 0x094E, 0x094F, + 0x0982, 0x0983, + 0x09BE, 0x09C0, + 0x09C7, 0x09C8, + 0x09CB, 0x09CC, + 0x09D7, 0x09D7, + 0x0A03, 0x0A03, + 0x0A3E, 0x0A40, + 0x0A83, 0x0A83, + 0x0ABE, 0x0AC0, + 0x0AC9, 0x0AC9, + 0x0ACB, 0x0ACC, + 0x0B02, 0x0B03, + 0x0B3E, 0x0B3E, + 0x0B40, 0x0B40, + 0x0B47, 0x0B48, + 0x0B4B, 0x0B4C, + 0x0B57, 0x0B57, + 0x0BBE, 0x0BBF, + 0x0BC1, 0x0BC2, + 0x0BC6, 0x0BC8, + 0x0BCA, 0x0BCC, + 0x0BD7, 0x0BD7, + 0x0C01, 0x0C03, + 0x0C41, 0x0C44, + 0x0C82, 0x0C83, + 0x0CBE, 0x0CBE, + 0x0CC0, 0x0CC4, + 0x0CC7, 0x0CC8, + 0x0CCA, 0x0CCB, + 0x0CD5, 0x0CD6, + 0x0CF3, 0x0CF3, + 0x0D02, 0x0D03, + 0x0D3E, 0x0D40, + 0x0D46, 0x0D48, + 0x0D4A, 0x0D4C, + 0x0D57, 0x0D57, + 0x0D82, 0x0D83, + 0x0DCF, 0x0DD1, + 0x0DD8, 0x0DDF, + 0x0DF2, 0x0DF3, + 0x0F3E, 0x0F3F, + 0x0F7F, 0x0F7F, + 0x102B, 0x102C, + 0x1031, 0x1031, + 0x1038, 0x1038, + 0x103B, 0x103C, + 0x1056, 0x1057, + 0x1062, 0x1064, + 0x1067, 0x106D, + 0x1083, 0x1084, + 0x1087, 0x108C, + 0x108F, 0x108F, + 0x109A, 0x109C, + 0x1715, 0x1715, + 0x1734, 0x1734, + 0x17B6, 0x17B6, + 0x17BE, 0x17C5, + 0x17C7, 0x17C8, + 0x1923, 0x1926, + 0x1929, 0x192B, + 0x1930, 0x1931, + 0x1933, 0x1938, + 0x1A19, 0x1A1A, + 0x1A55, 0x1A55, + 0x1A57, 0x1A57, + 0x1A61, 0x1A61, + 0x1A63, 0x1A64, + 0x1A6D, 0x1A72, + 0x1B04, 0x1B04, + 0x1B35, 0x1B35, + 0x1B3B, 0x1B3B, + 0x1B3D, 0x1B41, + 0x1B43, 0x1B44, + 0x1B82, 0x1B82, + 0x1BA1, 0x1BA1, + 0x1BA6, 0x1BA7, + 0x1BAA, 0x1BAA, + 0x1BE7, 0x1BE7, + 0x1BEA, 0x1BEC, + 0x1BEE, 0x1BEE, + 0x1BF2, 0x1BF3, + 0x1C24, 0x1C2B, + 0x1C34, 0x1C35, + 0x1CE1, 0x1CE1, + 0x1CF7, 0x1CF7, + 0x302E, 0x302F, + 0xA823, 0xA824, + 0xA827, 0xA827, + 0xA880, 0xA881, + 0xA8B4, 0xA8C3, + 0xA952, 0xA953, + 0xA983, 0xA983, + 0xA9B4, 0xA9B5, + 0xA9BA, 0xA9BB, + 0xA9BE, 0xA9C0, + 0xAA2F, 0xAA30, + 0xAA33, 0xAA34, + 0xAA4D, 0xAA4D, + 0xAA7B, 0xAA7B, + 0xAA7D, 0xAA7D, + 0xAAEB, 0xAAEB, + 0xAAEE, 0xAAEF, + 0xAAF5, 0xAAF5, + 0xABE3, 0xABE4, + 0xABE6, 0xABE7, + 0xABE9, 0xABEA, + 0xABEC, 0xABEC, + 0x11000, 0x11000, + 0x11002, 0x11002, + 0x11082, 0x11082, + 0x110B0, 0x110B2, + 0x110B7, 0x110B8, + 0x1112C, 0x1112C, + 0x11145, 0x11146, + 0x11182, 0x11182, + 0x111B3, 0x111B5, + 0x111BF, 0x111C0, + 0x111CE, 0x111CE, + 0x1122C, 0x1122E, + 0x11232, 0x11233, + 0x11235, 0x11235, + 0x112E0, 0x112E2, + 0x11302, 0x11303, + 0x1133E, 0x1133F, + 0x11341, 0x11344, + 0x11347, 0x11348, + 0x1134B, 0x1134D, + 0x11357, 0x11357, + 0x11362, 0x11363, + 0x11435, 0x11437, + 0x11440, 0x11441, + 0x11445, 0x11445, + 0x114B0, 0x114B2, + 0x114B9, 0x114B9, + 0x114BB, 0x114BE, + 0x114C1, 0x114C1, + 0x115AF, 0x115B1, + 0x115B8, 0x115BB, + 0x115BE, 0x115BE, + 0x11630, 0x11632, + 0x1163B, 0x1163C, + 0x1163E, 0x1163E, + 0x116AC, 0x116AC, + 0x116AE, 0x116AF, + 0x116B6, 0x116B6, + 0x11720, 0x11721, + 0x11726, 0x11726, + 0x1182C, 0x1182E, + 0x11838, 0x11838, + 0x11930, 0x11935, + 0x11937, 0x11938, + 0x1193D, 0x1193D, + 0x11940, 0x11940, + 0x11942, 0x11942, + 0x119D1, 0x119D3, + 0x119DC, 0x119DF, + 0x119E4, 0x119E4, + 0x11A39, 0x11A39, + 0x11A57, 0x11A58, + 0x11A97, 0x11A97, + 0x11C2F, 0x11C2F, + 0x11C3E, 0x11C3E, + 0x11CA9, 0x11CA9, + 0x11CB1, 0x11CB1, + 0x11CB4, 0x11CB4, + 0x11D8A, 0x11D8E, + 0x11D93, 0x11D94, + 0x11D96, 0x11D96, + 0x11EF5, 0x11EF6, + 0x11F03, 0x11F03, + 0x11F34, 0x11F35, + 0x11F3E, 0x11F3F, + 0x11F41, 0x11F41, + 0x16F51, 0x16F87, + 0x16FF0, 0x16FF1, + 0x1D165, 0x1D166, + 0x1D16D, 0x1D172, +}; + +static const int32_t ucg_nonspacing_mark_ranges[] = { + 0x0300, 0x036F, + 0x0483, 0x0487, + 0x0591, 0x05BD, + 0x05BF, 0x05BF, + 0x05C1, 0x05C2, + 0x05C4, 0x05C5, + 0x05C7, 0x05C7, + 0x0610, 0x061A, + 0x064B, 0x065F, + 0x0670, 0x0670, + 0x06D6, 0x06DC, + 0x06DF, 0x06E4, + 0x06E7, 0x06E8, + 0x06EA, 0x06ED, + 0x0711, 0x0711, + 0x0730, 0x074A, + 0x07A6, 0x07B0, + 0x07EB, 0x07F3, + 0x07FD, 0x07FD, + 0x0816, 0x0819, + 0x081B, 0x0823, + 0x0825, 0x0827, + 0x0829, 0x082D, + 0x0859, 0x085B, + 0x0898, 0x089F, + 0x08CA, 0x08E1, + 0x08E3, 0x0902, + 0x093A, 0x093A, + 0x093C, 0x093C, + 0x0941, 0x0948, + 0x094D, 0x094D, + 0x0951, 0x0957, + 0x0962, 0x0963, + 0x0981, 0x0981, + 0x09BC, 0x09BC, + 0x09C1, 0x09C4, + 0x09CD, 0x09CD, + 0x09E2, 0x09E3, + 0x09FE, 0x09FE, + 0x0A01, 0x0A02, + 0x0A3C, 0x0A3C, + 0x0A41, 0x0A42, + 0x0A47, 0x0A48, + 0x0A4B, 0x0A4D, + 0x0A51, 0x0A51, + 0x0A70, 0x0A71, + 0x0A75, 0x0A75, + 0x0A81, 0x0A82, + 0x0ABC, 0x0ABC, + 0x0AC1, 0x0AC5, + 0x0AC7, 0x0AC8, + 0x0ACD, 0x0ACD, + 0x0AE2, 0x0AE3, + 0x0AFA, 0x0AFF, + 0x0B01, 0x0B01, + 0x0B3C, 0x0B3C, + 0x0B3F, 0x0B3F, + 0x0B41, 0x0B44, + 0x0B4D, 0x0B4D, + 0x0B55, 0x0B56, + 0x0B62, 0x0B63, + 0x0B82, 0x0B82, + 0x0BC0, 0x0BC0, + 0x0BCD, 0x0BCD, + 0x0C00, 0x0C00, + 0x0C04, 0x0C04, + 0x0C3C, 0x0C3C, + 0x0C3E, 0x0C40, + 0x0C46, 0x0C48, + 0x0C4A, 0x0C4D, + 0x0C55, 0x0C56, + 0x0C62, 0x0C63, + 0x0C81, 0x0C81, + 0x0CBC, 0x0CBC, + 0x0CBF, 0x0CBF, + 0x0CC6, 0x0CC6, + 0x0CCC, 0x0CCD, + 0x0CE2, 0x0CE3, + 0x0D00, 0x0D01, + 0x0D3B, 0x0D3C, + 0x0D41, 0x0D44, + 0x0D4D, 0x0D4D, + 0x0D62, 0x0D63, + 0x0D81, 0x0D81, + 0x0DCA, 0x0DCA, + 0x0DD2, 0x0DD4, + 0x0DD6, 0x0DD6, + 0x0E31, 0x0E31, + 0x0E34, 0x0E3A, + 0x0E47, 0x0E4E, + 0x0EB1, 0x0EB1, + 0x0EB4, 0x0EBC, + 0x0EC8, 0x0ECE, + 0x0F18, 0x0F19, + 0x0F35, 0x0F35, + 0x0F37, 0x0F37, + 0x0F39, 0x0F39, + 0x0F71, 0x0F7E, + 0x0F80, 0x0F84, + 0x0F86, 0x0F87, + 0x0F8D, 0x0F97, + 0x0F99, 0x0FBC, + 0x0FC6, 0x0FC6, + 0x102D, 0x1030, + 0x1032, 0x1037, + 0x1039, 0x103A, + 0x103D, 0x103E, + 0x1058, 0x1059, + 0x105E, 0x1060, + 0x1071, 0x1074, + 0x1082, 0x1082, + 0x1085, 0x1086, + 0x108D, 0x108D, + 0x109D, 0x109D, + 0x135D, 0x135F, + 0x1712, 0x1714, + 0x1732, 0x1733, + 0x1752, 0x1753, + 0x1772, 0x1773, + 0x17B4, 0x17B5, + 0x17B7, 0x17BD, + 0x17C6, 0x17C6, + 0x17C9, 0x17D3, + 0x17DD, 0x17DD, + 0x180B, 0x180D, + 0x180F, 0x180F, + 0x1885, 0x1886, + 0x18A9, 0x18A9, + 0x1920, 0x1922, + 0x1927, 0x1928, + 0x1932, 0x1932, + 0x1939, 0x193B, + 0x1A17, 0x1A18, + 0x1A1B, 0x1A1B, + 0x1A56, 0x1A56, + 0x1A58, 0x1A5E, + 0x1A60, 0x1A60, + 0x1A62, 0x1A62, + 0x1A65, 0x1A6C, + 0x1A73, 0x1A7C, + 0x1A7F, 0x1A7F, + 0x1AB0, 0x1ABD, + 0x1ABF, 0x1ACE, + 0x1B00, 0x1B03, + 0x1B34, 0x1B34, + 0x1B36, 0x1B3A, + 0x1B3C, 0x1B3C, + 0x1B42, 0x1B42, + 0x1B6B, 0x1B73, + 0x1B80, 0x1B81, + 0x1BA2, 0x1BA5, + 0x1BA8, 0x1BA9, + 0x1BAB, 0x1BAD, + 0x1BE6, 0x1BE6, + 0x1BE8, 0x1BE9, + 0x1BED, 0x1BED, + 0x1BEF, 0x1BF1, + 0x1C2C, 0x1C33, + 0x1C36, 0x1C37, + 0x1CD0, 0x1CD2, + 0x1CD4, 0x1CE0, + 0x1CE2, 0x1CE8, + 0x1CED, 0x1CED, + 0x1CF4, 0x1CF4, + 0x1CF8, 0x1CF9, + 0x1DC0, 0x1DFF, + 0x20D0, 0x20DC, + 0x20E1, 0x20E1, + 0x20E5, 0x20F0, + 0x2CEF, 0x2CF1, + 0x2D7F, 0x2D7F, + 0x2DE0, 0x2DFF, + 0x302A, 0x302D, + 0x3099, 0x309A, + 0xA66F, 0xA66F, + 0xA674, 0xA67D, + 0xA69E, 0xA69F, + 0xA6F0, 0xA6F1, + 0xA802, 0xA802, + 0xA806, 0xA806, + 0xA80B, 0xA80B, + 0xA825, 0xA826, + 0xA82C, 0xA82C, + 0xA8C4, 0xA8C5, + 0xA8E0, 0xA8F1, + 0xA8FF, 0xA8FF, + 0xA926, 0xA92D, + 0xA947, 0xA951, + 0xA980, 0xA982, + 0xA9B3, 0xA9B3, + 0xA9B6, 0xA9B9, + 0xA9BC, 0xA9BD, + 0xA9E5, 0xA9E5, + 0xAA29, 0xAA2E, + 0xAA31, 0xAA32, + 0xAA35, 0xAA36, + 0xAA43, 0xAA43, + 0xAA4C, 0xAA4C, + 0xAA7C, 0xAA7C, + 0xAAB0, 0xAAB0, + 0xAAB2, 0xAAB4, + 0xAAB7, 0xAAB8, + 0xAABE, 0xAABF, + 0xAAC1, 0xAAC1, + 0xAAEC, 0xAAED, + 0xAAF6, 0xAAF6, + 0xABE5, 0xABE5, + 0xABE8, 0xABE8, + 0xABED, 0xABED, + 0xFB1E, 0xFB1E, + 0xFE00, 0xFE0F, + 0xFE20, 0xFE2F, + 0x101FD, 0x101FD, + 0x102E0, 0x102E0, + 0x10376, 0x1037A, + 0x10A01, 0x10A03, + 0x10A05, 0x10A06, + 0x10A0C, 0x10A0F, + 0x10A38, 0x10A3A, + 0x10A3F, 0x10A3F, + 0x10AE5, 0x10AE6, + 0x10D24, 0x10D27, + 0x10EAB, 0x10EAC, + 0x10EFD, 0x10EFF, + 0x10F46, 0x10F50, + 0x10F82, 0x10F85, + 0x11001, 0x11001, + 0x11038, 0x11046, + 0x11070, 0x11070, + 0x11073, 0x11074, + 0x1107F, 0x11081, + 0x110B3, 0x110B6, + 0x110B9, 0x110BA, + 0x110C2, 0x110C2, + 0x11100, 0x11102, + 0x11127, 0x1112B, + 0x1112D, 0x11134, + 0x11173, 0x11173, + 0x11180, 0x11181, + 0x111B6, 0x111BE, + 0x111C9, 0x111CC, + 0x111CF, 0x111CF, + 0x1122F, 0x11231, + 0x11234, 0x11234, + 0x11236, 0x11237, + 0x1123E, 0x1123E, + 0x11241, 0x11241, + 0x112DF, 0x112DF, + 0x112E3, 0x112EA, + 0x11300, 0x11301, + 0x1133B, 0x1133C, + 0x11340, 0x11340, + 0x11366, 0x1136C, + 0x11370, 0x11374, + 0x11438, 0x1143F, + 0x11442, 0x11444, + 0x11446, 0x11446, + 0x1145E, 0x1145E, + 0x114B3, 0x114B8, + 0x114BA, 0x114BA, + 0x114BF, 0x114C0, + 0x114C2, 0x114C3, + 0x115B2, 0x115B5, + 0x115BC, 0x115BD, + 0x115BF, 0x115C0, + 0x115DC, 0x115DD, + 0x11633, 0x1163A, + 0x1163D, 0x1163D, + 0x1163F, 0x11640, + 0x116AB, 0x116AB, + 0x116AD, 0x116AD, + 0x116B0, 0x116B5, + 0x116B7, 0x116B7, + 0x1171D, 0x1171F, + 0x11722, 0x11725, + 0x11727, 0x1172B, + 0x1182F, 0x11837, + 0x11839, 0x1183A, + 0x1193B, 0x1193C, + 0x1193E, 0x1193E, + 0x11943, 0x11943, + 0x119D4, 0x119D7, + 0x119DA, 0x119DB, + 0x119E0, 0x119E0, + 0x11A01, 0x11A0A, + 0x11A33, 0x11A38, + 0x11A3B, 0x11A3E, + 0x11A47, 0x11A47, + 0x11A51, 0x11A56, + 0x11A59, 0x11A5B, + 0x11A8A, 0x11A96, + 0x11A98, 0x11A99, + 0x11C30, 0x11C36, + 0x11C38, 0x11C3D, + 0x11C3F, 0x11C3F, + 0x11C92, 0x11CA7, + 0x11CAA, 0x11CB0, + 0x11CB2, 0x11CB3, + 0x11CB5, 0x11CB6, + 0x11D31, 0x11D36, + 0x11D3A, 0x11D3A, + 0x11D3C, 0x11D3D, + 0x11D3F, 0x11D45, + 0x11D47, 0x11D47, + 0x11D90, 0x11D91, + 0x11D95, 0x11D95, + 0x11D97, 0x11D97, + 0x11EF3, 0x11EF4, + 0x11F00, 0x11F01, + 0x11F36, 0x11F3A, + 0x11F40, 0x11F40, + 0x11F42, 0x11F42, + 0x13440, 0x13440, + 0x13447, 0x13455, + 0x16AF0, 0x16AF4, + 0x16B30, 0x16B36, + 0x16F4F, 0x16F4F, + 0x16F8F, 0x16F92, + 0x16FE4, 0x16FE4, + 0x1BC9D, 0x1BC9E, + 0x1CF00, 0x1CF2D, + 0x1CF30, 0x1CF46, + 0x1D167, 0x1D169, + 0x1D17B, 0x1D182, + 0x1D185, 0x1D18B, + 0x1D1AA, 0x1D1AD, + 0x1D242, 0x1D244, + 0x1DA00, 0x1DA36, + 0x1DA3B, 0x1DA6C, + 0x1DA75, 0x1DA75, + 0x1DA84, 0x1DA84, + 0x1DA9B, 0x1DA9F, + 0x1DAA1, 0x1DAAF, + 0x1E000, 0x1E006, + 0x1E008, 0x1E018, + 0x1E01B, 0x1E021, + 0x1E023, 0x1E024, + 0x1E026, 0x1E02A, + 0x1E08F, 0x1E08F, + 0x1E130, 0x1E136, + 0x1E2AE, 0x1E2AE, + 0x1E2EC, 0x1E2EF, + 0x1E4EC, 0x1E4EF, + 0x1E8D0, 0x1E8D6, + 0x1E944, 0x1E94A, + 0xE0100, 0xE01EF, +}; + +static const int32_t ucg_emoji_extended_pictographic_ranges[] = { + 0x00A9, 0x00A9, + 0x00AE, 0x00AE, + 0x203C, 0x203C, + 0x2049, 0x2049, + 0x2122, 0x2122, + 0x2139, 0x2139, + 0x2194, 0x2199, + 0x21A9, 0x21AA, + 0x231A, 0x231B, + 0x2328, 0x2328, + 0x2388, 0x2388, + 0x23CF, 0x23CF, + 0x23E9, 0x23EC, + 0x23ED, 0x23EE, + 0x23EF, 0x23EF, + 0x23F0, 0x23F0, + 0x23F1, 0x23F2, + 0x23F3, 0x23F3, + 0x23F8, 0x23FA, + 0x24C2, 0x24C2, + 0x25AA, 0x25AB, + 0x25B6, 0x25B6, + 0x25C0, 0x25C0, + 0x25FB, 0x25FE, + 0x2600, 0x2601, + 0x2602, 0x2603, + 0x2604, 0x2604, + 0x2605, 0x2605, + 0x2607, 0x260D, + 0x260E, 0x260E, + 0x260F, 0x2610, + 0x2611, 0x2611, + 0x2612, 0x2612, + 0x2614, 0x2615, + 0x2616, 0x2617, + 0x2618, 0x2618, + 0x2619, 0x261C, + 0x261D, 0x261D, + 0x261E, 0x261F, + 0x2620, 0x2620, + 0x2621, 0x2621, + 0x2622, 0x2623, + 0x2624, 0x2625, + 0x2626, 0x2626, + 0x2627, 0x2629, + 0x262A, 0x262A, + 0x262B, 0x262D, + 0x262E, 0x262E, + 0x262F, 0x262F, + 0x2630, 0x2637, + 0x2638, 0x2639, + 0x263A, 0x263A, + 0x263B, 0x263F, + 0x2640, 0x2640, + 0x2641, 0x2641, + 0x2642, 0x2642, + 0x2643, 0x2647, + 0x2648, 0x2653, + 0x2654, 0x265E, + 0x265F, 0x265F, + 0x2660, 0x2660, + 0x2661, 0x2662, + 0x2663, 0x2663, + 0x2664, 0x2664, + 0x2665, 0x2666, + 0x2667, 0x2667, + 0x2668, 0x2668, + 0x2669, 0x267A, + 0x267B, 0x267B, + 0x267C, 0x267D, + 0x267E, 0x267E, + 0x267F, 0x267F, + 0x2680, 0x2685, + 0x2690, 0x2691, + 0x2692, 0x2692, + 0x2693, 0x2693, + 0x2694, 0x2694, + 0x2695, 0x2695, + 0x2696, 0x2697, + 0x2698, 0x2698, + 0x2699, 0x2699, + 0x269A, 0x269A, + 0x269B, 0x269C, + 0x269D, 0x269F, + 0x26A0, 0x26A1, + 0x26A2, 0x26A6, + 0x26A7, 0x26A7, + 0x26A8, 0x26A9, + 0x26AA, 0x26AB, + 0x26AC, 0x26AF, + 0x26B0, 0x26B1, + 0x26B2, 0x26BC, + 0x26BD, 0x26BE, + 0x26BF, 0x26C3, + 0x26C4, 0x26C5, + 0x26C6, 0x26C7, + 0x26C8, 0x26C8, + 0x26C9, 0x26CD, + 0x26CE, 0x26CE, + 0x26CF, 0x26CF, + 0x26D0, 0x26D0, + 0x26D1, 0x26D1, + 0x26D2, 0x26D2, + 0x26D3, 0x26D3, + 0x26D4, 0x26D4, + 0x26D5, 0x26E8, + 0x26E9, 0x26E9, + 0x26EA, 0x26EA, + 0x26EB, 0x26EF, + 0x26F0, 0x26F1, + 0x26F2, 0x26F3, + 0x26F4, 0x26F4, + 0x26F5, 0x26F5, + 0x26F6, 0x26F6, + 0x26F7, 0x26F9, + 0x26FA, 0x26FA, + 0x26FB, 0x26FC, + 0x26FD, 0x26FD, + 0x26FE, 0x2701, + 0x2702, 0x2702, + 0x2703, 0x2704, + 0x2705, 0x2705, + 0x2708, 0x270C, + 0x270D, 0x270D, + 0x270E, 0x270E, + 0x270F, 0x270F, + 0x2710, 0x2711, + 0x2712, 0x2712, + 0x2714, 0x2714, + 0x2716, 0x2716, + 0x271D, 0x271D, + 0x2721, 0x2721, + 0x2728, 0x2728, + 0x2733, 0x2734, + 0x2744, 0x2744, + 0x2747, 0x2747, + 0x274C, 0x274C, + 0x274E, 0x274E, + 0x2753, 0x2755, + 0x2757, 0x2757, + 0x2763, 0x2763, + 0x2764, 0x2764, + 0x2765, 0x2767, + 0x2795, 0x2797, + 0x27A1, 0x27A1, + 0x27B0, 0x27B0, + 0x27BF, 0x27BF, + 0x2934, 0x2935, + 0x2B05, 0x2B07, + 0x2B1B, 0x2B1C, + 0x2B50, 0x2B50, + 0x2B55, 0x2B55, + 0x3030, 0x3030, + 0x303D, 0x303D, + 0x3297, 0x3297, + 0x3299, 0x3299, + 0x1F000, 0x1F003, + 0x1F004, 0x1F004, + 0x1F005, 0x1F0CE, + 0x1F0CF, 0x1F0CF, + 0x1F0D0, 0x1F0FF, + 0x1F10D, 0x1F10F, + 0x1F12F, 0x1F12F, + 0x1F16C, 0x1F16F, + 0x1F170, 0x1F171, + 0x1F17E, 0x1F17F, + 0x1F18E, 0x1F18E, + 0x1F191, 0x1F19A, + 0x1F1AD, 0x1F1E5, + 0x1F201, 0x1F202, + 0x1F203, 0x1F20F, + 0x1F21A, 0x1F21A, + 0x1F22F, 0x1F22F, + 0x1F232, 0x1F23A, + 0x1F23C, 0x1F23F, + 0x1F249, 0x1F24F, + 0x1F250, 0x1F251, + 0x1F252, 0x1F2FF, + 0x1F300, 0x1F30C, + 0x1F30D, 0x1F30E, + 0x1F30F, 0x1F30F, + 0x1F310, 0x1F310, + 0x1F311, 0x1F311, + 0x1F312, 0x1F312, + 0x1F313, 0x1F315, + 0x1F316, 0x1F318, + 0x1F319, 0x1F319, + 0x1F31A, 0x1F31A, + 0x1F31B, 0x1F31B, + 0x1F31C, 0x1F31C, + 0x1F31D, 0x1F31E, + 0x1F31F, 0x1F320, + 0x1F321, 0x1F321, + 0x1F322, 0x1F323, + 0x1F324, 0x1F32C, + 0x1F32D, 0x1F32F, + 0x1F330, 0x1F331, + 0x1F332, 0x1F333, + 0x1F334, 0x1F335, + 0x1F336, 0x1F336, + 0x1F337, 0x1F34A, + 0x1F34B, 0x1F34B, + 0x1F34C, 0x1F34F, + 0x1F350, 0x1F350, + 0x1F351, 0x1F37B, + 0x1F37C, 0x1F37C, + 0x1F37D, 0x1F37D, + 0x1F37E, 0x1F37F, + 0x1F380, 0x1F393, + 0x1F394, 0x1F395, + 0x1F396, 0x1F397, + 0x1F398, 0x1F398, + 0x1F399, 0x1F39B, + 0x1F39C, 0x1F39D, + 0x1F39E, 0x1F39F, + 0x1F3A0, 0x1F3C4, + 0x1F3C5, 0x1F3C5, + 0x1F3C6, 0x1F3C6, + 0x1F3C7, 0x1F3C7, + 0x1F3C8, 0x1F3C8, + 0x1F3C9, 0x1F3C9, + 0x1F3CA, 0x1F3CA, + 0x1F3CB, 0x1F3CE, + 0x1F3CF, 0x1F3D3, + 0x1F3D4, 0x1F3DF, + 0x1F3E0, 0x1F3E3, + 0x1F3E4, 0x1F3E4, + 0x1F3E5, 0x1F3F0, + 0x1F3F1, 0x1F3F2, + 0x1F3F3, 0x1F3F3, + 0x1F3F4, 0x1F3F4, + 0x1F3F5, 0x1F3F5, + 0x1F3F6, 0x1F3F6, + 0x1F3F7, 0x1F3F7, + 0x1F3F8, 0x1F3FA, + 0x1F400, 0x1F407, + 0x1F408, 0x1F408, + 0x1F409, 0x1F40B, + 0x1F40C, 0x1F40E, + 0x1F40F, 0x1F410, + 0x1F411, 0x1F412, + 0x1F413, 0x1F413, + 0x1F414, 0x1F414, + 0x1F415, 0x1F415, + 0x1F416, 0x1F416, + 0x1F417, 0x1F429, + 0x1F42A, 0x1F42A, + 0x1F42B, 0x1F43E, + 0x1F43F, 0x1F43F, + 0x1F440, 0x1F440, + 0x1F441, 0x1F441, + 0x1F442, 0x1F464, + 0x1F465, 0x1F465, + 0x1F466, 0x1F46B, + 0x1F46C, 0x1F46D, + 0x1F46E, 0x1F4AC, + 0x1F4AD, 0x1F4AD, + 0x1F4AE, 0x1F4B5, + 0x1F4B6, 0x1F4B7, + 0x1F4B8, 0x1F4EB, + 0x1F4EC, 0x1F4ED, + 0x1F4EE, 0x1F4EE, + 0x1F4EF, 0x1F4EF, + 0x1F4F0, 0x1F4F4, + 0x1F4F5, 0x1F4F5, + 0x1F4F6, 0x1F4F7, + 0x1F4F8, 0x1F4F8, + 0x1F4F9, 0x1F4FC, + 0x1F4FD, 0x1F4FD, + 0x1F4FE, 0x1F4FE, + 0x1F4FF, 0x1F502, + 0x1F503, 0x1F503, + 0x1F504, 0x1F507, + 0x1F508, 0x1F508, + 0x1F509, 0x1F509, + 0x1F50A, 0x1F514, + 0x1F515, 0x1F515, + 0x1F516, 0x1F52B, + 0x1F52C, 0x1F52D, + 0x1F52E, 0x1F53D, + 0x1F546, 0x1F548, + 0x1F549, 0x1F54A, + 0x1F54B, 0x1F54E, + 0x1F54F, 0x1F54F, + 0x1F550, 0x1F55B, + 0x1F55C, 0x1F567, + 0x1F568, 0x1F56E, + 0x1F56F, 0x1F570, + 0x1F571, 0x1F572, + 0x1F573, 0x1F579, + 0x1F57A, 0x1F57A, + 0x1F57B, 0x1F586, + 0x1F587, 0x1F587, + 0x1F588, 0x1F589, + 0x1F58A, 0x1F58D, + 0x1F58E, 0x1F58F, + 0x1F590, 0x1F590, + 0x1F591, 0x1F594, + 0x1F595, 0x1F596, + 0x1F597, 0x1F5A3, + 0x1F5A4, 0x1F5A4, + 0x1F5A5, 0x1F5A5, + 0x1F5A6, 0x1F5A7, + 0x1F5A8, 0x1F5A8, + 0x1F5A9, 0x1F5B0, + 0x1F5B1, 0x1F5B2, + 0x1F5B3, 0x1F5BB, + 0x1F5BC, 0x1F5BC, + 0x1F5BD, 0x1F5C1, + 0x1F5C2, 0x1F5C4, + 0x1F5C5, 0x1F5D0, + 0x1F5D1, 0x1F5D3, + 0x1F5D4, 0x1F5DB, + 0x1F5DC, 0x1F5DE, + 0x1F5DF, 0x1F5E0, + 0x1F5E1, 0x1F5E1, + 0x1F5E2, 0x1F5E2, + 0x1F5E3, 0x1F5E3, + 0x1F5E4, 0x1F5E7, + 0x1F5E8, 0x1F5E8, + 0x1F5E9, 0x1F5EE, + 0x1F5EF, 0x1F5EF, + 0x1F5F0, 0x1F5F2, + 0x1F5F3, 0x1F5F3, + 0x1F5F4, 0x1F5F9, + 0x1F5FA, 0x1F5FA, + 0x1F5FB, 0x1F5FF, + 0x1F600, 0x1F600, + 0x1F601, 0x1F606, + 0x1F607, 0x1F608, + 0x1F609, 0x1F60D, + 0x1F60E, 0x1F60E, + 0x1F60F, 0x1F60F, + 0x1F610, 0x1F610, + 0x1F611, 0x1F611, + 0x1F612, 0x1F614, + 0x1F615, 0x1F615, + 0x1F616, 0x1F616, + 0x1F617, 0x1F617, + 0x1F618, 0x1F618, + 0x1F619, 0x1F619, + 0x1F61A, 0x1F61A, + 0x1F61B, 0x1F61B, + 0x1F61C, 0x1F61E, + 0x1F61F, 0x1F61F, + 0x1F620, 0x1F625, + 0x1F626, 0x1F627, + 0x1F628, 0x1F62B, + 0x1F62C, 0x1F62C, + 0x1F62D, 0x1F62D, + 0x1F62E, 0x1F62F, + 0x1F630, 0x1F633, + 0x1F634, 0x1F634, + 0x1F635, 0x1F635, + 0x1F636, 0x1F636, + 0x1F637, 0x1F640, + 0x1F641, 0x1F644, + 0x1F645, 0x1F64F, + 0x1F680, 0x1F680, + 0x1F681, 0x1F682, + 0x1F683, 0x1F685, + 0x1F686, 0x1F686, + 0x1F687, 0x1F687, + 0x1F688, 0x1F688, + 0x1F689, 0x1F689, + 0x1F68A, 0x1F68B, + 0x1F68C, 0x1F68C, + 0x1F68D, 0x1F68D, + 0x1F68E, 0x1F68E, + 0x1F68F, 0x1F68F, + 0x1F690, 0x1F690, + 0x1F691, 0x1F693, + 0x1F694, 0x1F694, + 0x1F695, 0x1F695, + 0x1F696, 0x1F696, + 0x1F697, 0x1F697, + 0x1F698, 0x1F698, + 0x1F699, 0x1F69A, + 0x1F69B, 0x1F6A1, + 0x1F6A2, 0x1F6A2, + 0x1F6A3, 0x1F6A3, + 0x1F6A4, 0x1F6A5, + 0x1F6A6, 0x1F6A6, + 0x1F6A7, 0x1F6AD, + 0x1F6AE, 0x1F6B1, + 0x1F6B2, 0x1F6B2, + 0x1F6B3, 0x1F6B5, + 0x1F6B6, 0x1F6B6, + 0x1F6B7, 0x1F6B8, + 0x1F6B9, 0x1F6BE, + 0x1F6BF, 0x1F6BF, + 0x1F6C0, 0x1F6C0, + 0x1F6C1, 0x1F6C5, + 0x1F6C6, 0x1F6CA, + 0x1F6CB, 0x1F6CB, + 0x1F6CC, 0x1F6CC, + 0x1F6CD, 0x1F6CF, + 0x1F6D0, 0x1F6D0, + 0x1F6D1, 0x1F6D2, + 0x1F6D3, 0x1F6D4, + 0x1F6D5, 0x1F6D5, + 0x1F6D6, 0x1F6D7, + 0x1F6D8, 0x1F6DB, + 0x1F6DC, 0x1F6DC, + 0x1F6DD, 0x1F6DF, + 0x1F6E0, 0x1F6E5, + 0x1F6E6, 0x1F6E8, + 0x1F6E9, 0x1F6E9, + 0x1F6EA, 0x1F6EA, + 0x1F6EB, 0x1F6EC, + 0x1F6ED, 0x1F6EF, + 0x1F6F0, 0x1F6F0, + 0x1F6F1, 0x1F6F2, + 0x1F6F3, 0x1F6F3, + 0x1F6F4, 0x1F6F6, + 0x1F6F7, 0x1F6F8, + 0x1F6F9, 0x1F6F9, + 0x1F6FA, 0x1F6FA, + 0x1F6FB, 0x1F6FC, + 0x1F6FD, 0x1F6FF, + 0x1F774, 0x1F77F, + 0x1F7D5, 0x1F7DF, + 0x1F7E0, 0x1F7EB, + 0x1F7EC, 0x1F7EF, + 0x1F7F0, 0x1F7F0, + 0x1F7F1, 0x1F7FF, + 0x1F80C, 0x1F80F, + 0x1F848, 0x1F84F, + 0x1F85A, 0x1F85F, + 0x1F888, 0x1F88F, + 0x1F8AE, 0x1F8FF, + 0x1F90C, 0x1F90C, + 0x1F90D, 0x1F90F, + 0x1F910, 0x1F918, + 0x1F919, 0x1F91E, + 0x1F91F, 0x1F91F, + 0x1F920, 0x1F927, + 0x1F928, 0x1F92F, + 0x1F930, 0x1F930, + 0x1F931, 0x1F932, + 0x1F933, 0x1F93A, + 0x1F93C, 0x1F93E, + 0x1F93F, 0x1F93F, + 0x1F940, 0x1F945, + 0x1F947, 0x1F94B, + 0x1F94C, 0x1F94C, + 0x1F94D, 0x1F94F, + 0x1F950, 0x1F95E, + 0x1F95F, 0x1F96B, + 0x1F96C, 0x1F970, + 0x1F971, 0x1F971, + 0x1F972, 0x1F972, + 0x1F973, 0x1F976, + 0x1F977, 0x1F978, + 0x1F979, 0x1F979, + 0x1F97A, 0x1F97A, + 0x1F97B, 0x1F97B, + 0x1F97C, 0x1F97F, + 0x1F980, 0x1F984, + 0x1F985, 0x1F991, + 0x1F992, 0x1F997, + 0x1F998, 0x1F9A2, + 0x1F9A3, 0x1F9A4, + 0x1F9A5, 0x1F9AA, + 0x1F9AB, 0x1F9AD, + 0x1F9AE, 0x1F9AF, + 0x1F9B0, 0x1F9B9, + 0x1F9BA, 0x1F9BF, + 0x1F9C0, 0x1F9C0, + 0x1F9C1, 0x1F9C2, + 0x1F9C3, 0x1F9CA, + 0x1F9CB, 0x1F9CB, + 0x1F9CC, 0x1F9CC, + 0x1F9CD, 0x1F9CF, + 0x1F9D0, 0x1F9E6, + 0x1F9E7, 0x1F9FF, + 0x1FA00, 0x1FA6F, + 0x1FA70, 0x1FA73, + 0x1FA74, 0x1FA74, + 0x1FA75, 0x1FA77, + 0x1FA78, 0x1FA7A, + 0x1FA7B, 0x1FA7C, + 0x1FA7D, 0x1FA7F, + 0x1FA80, 0x1FA82, + 0x1FA83, 0x1FA86, + 0x1FA87, 0x1FA88, + 0x1FA89, 0x1FA8F, + 0x1FA90, 0x1FA95, + 0x1FA96, 0x1FAA8, + 0x1FAA9, 0x1FAAC, + 0x1FAAD, 0x1FAAF, + 0x1FAB0, 0x1FAB6, + 0x1FAB7, 0x1FABA, + 0x1FABB, 0x1FABD, + 0x1FABE, 0x1FABE, + 0x1FABF, 0x1FABF, + 0x1FAC0, 0x1FAC2, + 0x1FAC3, 0x1FAC5, + 0x1FAC6, 0x1FACD, + 0x1FACE, 0x1FACF, + 0x1FAD0, 0x1FAD6, + 0x1FAD7, 0x1FAD9, + 0x1FADA, 0x1FADB, + 0x1FADC, 0x1FADF, + 0x1FAE0, 0x1FAE7, + 0x1FAE8, 0x1FAE8, + 0x1FAE9, 0x1FAEF, + 0x1FAF0, 0x1FAF6, + 0x1FAF7, 0x1FAF8, + 0x1FAF9, 0x1FAFF, + 0x1FC00, 0x1FFFD, +}; + +static const int32_t ucg_grapheme_extend_ranges[] = { + 0x0300, 0x036F, + 0x0483, 0x0487, + 0x0488, 0x0489, + 0x0591, 0x05BD, + 0x05BF, 0x05BF, + 0x05C1, 0x05C2, + 0x05C4, 0x05C5, + 0x05C7, 0x05C7, + 0x0610, 0x061A, + 0x064B, 0x065F, + 0x0670, 0x0670, + 0x06D6, 0x06DC, + 0x06DF, 0x06E4, + 0x06E7, 0x06E8, + 0x06EA, 0x06ED, + 0x0711, 0x0711, + 0x0730, 0x074A, + 0x07A6, 0x07B0, + 0x07EB, 0x07F3, + 0x07FD, 0x07FD, + 0x0816, 0x0819, + 0x081B, 0x0823, + 0x0825, 0x0827, + 0x0829, 0x082D, + 0x0859, 0x085B, + 0x0898, 0x089F, + 0x08CA, 0x08E1, + 0x08E3, 0x0902, + 0x093A, 0x093A, + 0x093C, 0x093C, + 0x0941, 0x0948, + 0x094D, 0x094D, + 0x0951, 0x0957, + 0x0962, 0x0963, + 0x0981, 0x0981, + 0x09BC, 0x09BC, + 0x09BE, 0x09BE, + 0x09C1, 0x09C4, + 0x09CD, 0x09CD, + 0x09D7, 0x09D7, + 0x09E2, 0x09E3, + 0x09FE, 0x09FE, + 0x0A01, 0x0A02, + 0x0A3C, 0x0A3C, + 0x0A41, 0x0A42, + 0x0A47, 0x0A48, + 0x0A4B, 0x0A4D, + 0x0A51, 0x0A51, + 0x0A70, 0x0A71, + 0x0A75, 0x0A75, + 0x0A81, 0x0A82, + 0x0ABC, 0x0ABC, + 0x0AC1, 0x0AC5, + 0x0AC7, 0x0AC8, + 0x0ACD, 0x0ACD, + 0x0AE2, 0x0AE3, + 0x0AFA, 0x0AFF, + 0x0B01, 0x0B01, + 0x0B3C, 0x0B3C, + 0x0B3E, 0x0B3E, + 0x0B3F, 0x0B3F, + 0x0B41, 0x0B44, + 0x0B4D, 0x0B4D, + 0x0B55, 0x0B56, + 0x0B57, 0x0B57, + 0x0B62, 0x0B63, + 0x0B82, 0x0B82, + 0x0BBE, 0x0BBE, + 0x0BC0, 0x0BC0, + 0x0BCD, 0x0BCD, + 0x0BD7, 0x0BD7, + 0x0C00, 0x0C00, + 0x0C04, 0x0C04, + 0x0C3C, 0x0C3C, + 0x0C3E, 0x0C40, + 0x0C46, 0x0C48, + 0x0C4A, 0x0C4D, + 0x0C55, 0x0C56, + 0x0C62, 0x0C63, + 0x0C81, 0x0C81, + 0x0CBC, 0x0CBC, + 0x0CBF, 0x0CBF, + 0x0CC2, 0x0CC2, + 0x0CC6, 0x0CC6, + 0x0CCC, 0x0CCD, + 0x0CD5, 0x0CD6, + 0x0CE2, 0x0CE3, + 0x0D00, 0x0D01, + 0x0D3B, 0x0D3C, + 0x0D3E, 0x0D3E, + 0x0D41, 0x0D44, + 0x0D4D, 0x0D4D, + 0x0D57, 0x0D57, + 0x0D62, 0x0D63, + 0x0D81, 0x0D81, + 0x0DCA, 0x0DCA, + 0x0DCF, 0x0DCF, + 0x0DD2, 0x0DD4, + 0x0DD6, 0x0DD6, + 0x0DDF, 0x0DDF, + 0x0E31, 0x0E31, + 0x0E34, 0x0E3A, + 0x0E47, 0x0E4E, + 0x0EB1, 0x0EB1, + 0x0EB4, 0x0EBC, + 0x0EC8, 0x0ECE, + 0x0F18, 0x0F19, + 0x0F35, 0x0F35, + 0x0F37, 0x0F37, + 0x0F39, 0x0F39, + 0x0F71, 0x0F7E, + 0x0F80, 0x0F84, + 0x0F86, 0x0F87, + 0x0F8D, 0x0F97, + 0x0F99, 0x0FBC, + 0x0FC6, 0x0FC6, + 0x102D, 0x1030, + 0x1032, 0x1037, + 0x1039, 0x103A, + 0x103D, 0x103E, + 0x1058, 0x1059, + 0x105E, 0x1060, + 0x1071, 0x1074, + 0x1082, 0x1082, + 0x1085, 0x1086, + 0x108D, 0x108D, + 0x109D, 0x109D, + 0x135D, 0x135F, + 0x1712, 0x1714, + 0x1732, 0x1733, + 0x1752, 0x1753, + 0x1772, 0x1773, + 0x17B4, 0x17B5, + 0x17B7, 0x17BD, + 0x17C6, 0x17C6, + 0x17C9, 0x17D3, + 0x17DD, 0x17DD, + 0x180B, 0x180D, + 0x180F, 0x180F, + 0x1885, 0x1886, + 0x18A9, 0x18A9, + 0x1920, 0x1922, + 0x1927, 0x1928, + 0x1932, 0x1932, + 0x1939, 0x193B, + 0x1A17, 0x1A18, + 0x1A1B, 0x1A1B, + 0x1A56, 0x1A56, + 0x1A58, 0x1A5E, + 0x1A60, 0x1A60, + 0x1A62, 0x1A62, + 0x1A65, 0x1A6C, + 0x1A73, 0x1A7C, + 0x1A7F, 0x1A7F, + 0x1AB0, 0x1ABD, + 0x1ABE, 0x1ABE, + 0x1ABF, 0x1ACE, + 0x1B00, 0x1B03, + 0x1B34, 0x1B34, + 0x1B35, 0x1B35, + 0x1B36, 0x1B3A, + 0x1B3C, 0x1B3C, + 0x1B42, 0x1B42, + 0x1B6B, 0x1B73, + 0x1B80, 0x1B81, + 0x1BA2, 0x1BA5, + 0x1BA8, 0x1BA9, + 0x1BAB, 0x1BAD, + 0x1BE6, 0x1BE6, + 0x1BE8, 0x1BE9, + 0x1BED, 0x1BED, + 0x1BEF, 0x1BF1, + 0x1C2C, 0x1C33, + 0x1C36, 0x1C37, + 0x1CD0, 0x1CD2, + 0x1CD4, 0x1CE0, + 0x1CE2, 0x1CE8, + 0x1CED, 0x1CED, + 0x1CF4, 0x1CF4, + 0x1CF8, 0x1CF9, + 0x1DC0, 0x1DFF, + 0x200C, 0x200C, + 0x20D0, 0x20DC, + 0x20DD, 0x20E0, + 0x20E1, 0x20E1, + 0x20E2, 0x20E4, + 0x20E5, 0x20F0, + 0x2CEF, 0x2CF1, + 0x2D7F, 0x2D7F, + 0x2DE0, 0x2DFF, + 0x302A, 0x302D, + 0x302E, 0x302F, + 0x3099, 0x309A, + 0xA66F, 0xA66F, + 0xA670, 0xA672, + 0xA674, 0xA67D, + 0xA69E, 0xA69F, + 0xA6F0, 0xA6F1, + 0xA802, 0xA802, + 0xA806, 0xA806, + 0xA80B, 0xA80B, + 0xA825, 0xA826, + 0xA82C, 0xA82C, + 0xA8C4, 0xA8C5, + 0xA8E0, 0xA8F1, + 0xA8FF, 0xA8FF, + 0xA926, 0xA92D, + 0xA947, 0xA951, + 0xA980, 0xA982, + 0xA9B3, 0xA9B3, + 0xA9B6, 0xA9B9, + 0xA9BC, 0xA9BD, + 0xA9E5, 0xA9E5, + 0xAA29, 0xAA2E, + 0xAA31, 0xAA32, + 0xAA35, 0xAA36, + 0xAA43, 0xAA43, + 0xAA4C, 0xAA4C, + 0xAA7C, 0xAA7C, + 0xAAB0, 0xAAB0, + 0xAAB2, 0xAAB4, + 0xAAB7, 0xAAB8, + 0xAABE, 0xAABF, + 0xAAC1, 0xAAC1, + 0xAAEC, 0xAAED, + 0xAAF6, 0xAAF6, + 0xABE5, 0xABE5, + 0xABE8, 0xABE8, + 0xABED, 0xABED, + 0xFB1E, 0xFB1E, + 0xFE00, 0xFE0F, + 0xFE20, 0xFE2F, + 0xFF9E, 0xFF9F, + 0x101FD, 0x101FD, + 0x102E0, 0x102E0, + 0x10376, 0x1037A, + 0x10A01, 0x10A03, + 0x10A05, 0x10A06, + 0x10A0C, 0x10A0F, + 0x10A38, 0x10A3A, + 0x10A3F, 0x10A3F, + 0x10AE5, 0x10AE6, + 0x10D24, 0x10D27, + 0x10EAB, 0x10EAC, + 0x10EFD, 0x10EFF, + 0x10F46, 0x10F50, + 0x10F82, 0x10F85, + 0x11001, 0x11001, + 0x11038, 0x11046, + 0x11070, 0x11070, + 0x11073, 0x11074, + 0x1107F, 0x11081, + 0x110B3, 0x110B6, + 0x110B9, 0x110BA, + 0x110C2, 0x110C2, + 0x11100, 0x11102, + 0x11127, 0x1112B, + 0x1112D, 0x11134, + 0x11173, 0x11173, + 0x11180, 0x11181, + 0x111B6, 0x111BE, + 0x111C9, 0x111CC, + 0x111CF, 0x111CF, + 0x1122F, 0x11231, + 0x11234, 0x11234, + 0x11236, 0x11237, + 0x1123E, 0x1123E, + 0x11241, 0x11241, + 0x112DF, 0x112DF, + 0x112E3, 0x112EA, + 0x11300, 0x11301, + 0x1133B, 0x1133C, + 0x1133E, 0x1133E, + 0x11340, 0x11340, + 0x11357, 0x11357, + 0x11366, 0x1136C, + 0x11370, 0x11374, + 0x11438, 0x1143F, + 0x11442, 0x11444, + 0x11446, 0x11446, + 0x1145E, 0x1145E, + 0x114B0, 0x114B0, + 0x114B3, 0x114B8, + 0x114BA, 0x114BA, + 0x114BD, 0x114BD, + 0x114BF, 0x114C0, + 0x114C2, 0x114C3, + 0x115AF, 0x115AF, + 0x115B2, 0x115B5, + 0x115BC, 0x115BD, + 0x115BF, 0x115C0, + 0x115DC, 0x115DD, + 0x11633, 0x1163A, + 0x1163D, 0x1163D, + 0x1163F, 0x11640, + 0x116AB, 0x116AB, + 0x116AD, 0x116AD, + 0x116B0, 0x116B5, + 0x116B7, 0x116B7, + 0x1171D, 0x1171F, + 0x11722, 0x11725, + 0x11727, 0x1172B, + 0x1182F, 0x11837, + 0x11839, 0x1183A, + 0x11930, 0x11930, + 0x1193B, 0x1193C, + 0x1193E, 0x1193E, + 0x11943, 0x11943, + 0x119D4, 0x119D7, + 0x119DA, 0x119DB, + 0x119E0, 0x119E0, + 0x11A01, 0x11A0A, + 0x11A33, 0x11A38, + 0x11A3B, 0x11A3E, + 0x11A47, 0x11A47, + 0x11A51, 0x11A56, + 0x11A59, 0x11A5B, + 0x11A8A, 0x11A96, + 0x11A98, 0x11A99, + 0x11C30, 0x11C36, + 0x11C38, 0x11C3D, + 0x11C3F, 0x11C3F, + 0x11C92, 0x11CA7, + 0x11CAA, 0x11CB0, + 0x11CB2, 0x11CB3, + 0x11CB5, 0x11CB6, + 0x11D31, 0x11D36, + 0x11D3A, 0x11D3A, + 0x11D3C, 0x11D3D, + 0x11D3F, 0x11D45, + 0x11D47, 0x11D47, + 0x11D90, 0x11D91, + 0x11D95, 0x11D95, + 0x11D97, 0x11D97, + 0x11EF3, 0x11EF4, + 0x11F00, 0x11F01, + 0x11F36, 0x11F3A, + 0x11F40, 0x11F40, + 0x11F42, 0x11F42, + 0x13440, 0x13440, + 0x13447, 0x13455, + 0x16AF0, 0x16AF4, + 0x16B30, 0x16B36, + 0x16F4F, 0x16F4F, + 0x16F8F, 0x16F92, + 0x16FE4, 0x16FE4, + 0x1BC9D, 0x1BC9E, + 0x1CF00, 0x1CF2D, + 0x1CF30, 0x1CF46, + 0x1D165, 0x1D165, + 0x1D167, 0x1D169, + 0x1D16E, 0x1D172, + 0x1D17B, 0x1D182, + 0x1D185, 0x1D18B, + 0x1D1AA, 0x1D1AD, + 0x1D242, 0x1D244, + 0x1DA00, 0x1DA36, + 0x1DA3B, 0x1DA6C, + 0x1DA75, 0x1DA75, + 0x1DA84, 0x1DA84, + 0x1DA9B, 0x1DA9F, + 0x1DAA1, 0x1DAAF, + 0x1E000, 0x1E006, + 0x1E008, 0x1E018, + 0x1E01B, 0x1E021, + 0x1E023, 0x1E024, + 0x1E026, 0x1E02A, + 0x1E08F, 0x1E08F, + 0x1E130, 0x1E136, + 0x1E2AE, 0x1E2AE, + 0x1E2EC, 0x1E2EF, + 0x1E4EC, 0x1E4EF, + 0x1E8D0, 0x1E8D6, + 0x1E944, 0x1E94A, + 0xE0020, 0xE007F, + 0xE0100, 0xE01EF, +}; + +static const int32_t ucg_hangul_syllable_lv_singlets[] = { + 0xAC00, + 0xAC1C, + 0xAC38, + 0xAC54, + 0xAC70, + 0xAC8C, + 0xACA8, + 0xACC4, + 0xACE0, + 0xACFC, + 0xAD18, + 0xAD34, + 0xAD50, + 0xAD6C, + 0xAD88, + 0xADA4, + 0xADC0, + 0xADDC, + 0xADF8, + 0xAE14, + 0xAE30, + 0xAE4C, + 0xAE68, + 0xAE84, + 0xAEA0, + 0xAEBC, + 0xAED8, + 0xAEF4, + 0xAF10, + 0xAF2C, + 0xAF48, + 0xAF64, + 0xAF80, + 0xAF9C, + 0xAFB8, + 0xAFD4, + 0xAFF0, + 0xB00C, + 0xB028, + 0xB044, + 0xB060, + 0xB07C, + 0xB098, + 0xB0B4, + 0xB0D0, + 0xB0EC, + 0xB108, + 0xB124, + 0xB140, + 0xB15C, + 0xB178, + 0xB194, + 0xB1B0, + 0xB1CC, + 0xB1E8, + 0xB204, + 0xB220, + 0xB23C, + 0xB258, + 0xB274, + 0xB290, + 0xB2AC, + 0xB2C8, + 0xB2E4, + 0xB300, + 0xB31C, + 0xB338, + 0xB354, + 0xB370, + 0xB38C, + 0xB3A8, + 0xB3C4, + 0xB3E0, + 0xB3FC, + 0xB418, + 0xB434, + 0xB450, + 0xB46C, + 0xB488, + 0xB4A4, + 0xB4C0, + 0xB4DC, + 0xB4F8, + 0xB514, + 0xB530, + 0xB54C, + 0xB568, + 0xB584, + 0xB5A0, + 0xB5BC, + 0xB5D8, + 0xB5F4, + 0xB610, + 0xB62C, + 0xB648, + 0xB664, + 0xB680, + 0xB69C, + 0xB6B8, + 0xB6D4, + 0xB6F0, + 0xB70C, + 0xB728, + 0xB744, + 0xB760, + 0xB77C, + 0xB798, + 0xB7B4, + 0xB7D0, + 0xB7EC, + 0xB808, + 0xB824, + 0xB840, + 0xB85C, + 0xB878, + 0xB894, + 0xB8B0, + 0xB8CC, + 0xB8E8, + 0xB904, + 0xB920, + 0xB93C, + 0xB958, + 0xB974, + 0xB990, + 0xB9AC, + 0xB9C8, + 0xB9E4, + 0xBA00, + 0xBA1C, + 0xBA38, + 0xBA54, + 0xBA70, + 0xBA8C, + 0xBAA8, + 0xBAC4, + 0xBAE0, + 0xBAFC, + 0xBB18, + 0xBB34, + 0xBB50, + 0xBB6C, + 0xBB88, + 0xBBA4, + 0xBBC0, + 0xBBDC, + 0xBBF8, + 0xBC14, + 0xBC30, + 0xBC4C, + 0xBC68, + 0xBC84, + 0xBCA0, + 0xBCBC, + 0xBCD8, + 0xBCF4, + 0xBD10, + 0xBD2C, + 0xBD48, + 0xBD64, + 0xBD80, + 0xBD9C, + 0xBDB8, + 0xBDD4, + 0xBDF0, + 0xBE0C, + 0xBE28, + 0xBE44, + 0xBE60, + 0xBE7C, + 0xBE98, + 0xBEB4, + 0xBED0, + 0xBEEC, + 0xBF08, + 0xBF24, + 0xBF40, + 0xBF5C, + 0xBF78, + 0xBF94, + 0xBFB0, + 0xBFCC, + 0xBFE8, + 0xC004, + 0xC020, + 0xC03C, + 0xC058, + 0xC074, + 0xC090, + 0xC0AC, + 0xC0C8, + 0xC0E4, + 0xC100, + 0xC11C, + 0xC138, + 0xC154, + 0xC170, + 0xC18C, + 0xC1A8, + 0xC1C4, + 0xC1E0, + 0xC1FC, + 0xC218, + 0xC234, + 0xC250, + 0xC26C, + 0xC288, + 0xC2A4, + 0xC2C0, + 0xC2DC, + 0xC2F8, + 0xC314, + 0xC330, + 0xC34C, + 0xC368, + 0xC384, + 0xC3A0, + 0xC3BC, + 0xC3D8, + 0xC3F4, + 0xC410, + 0xC42C, + 0xC448, + 0xC464, + 0xC480, + 0xC49C, + 0xC4B8, + 0xC4D4, + 0xC4F0, + 0xC50C, + 0xC528, + 0xC544, + 0xC560, + 0xC57C, + 0xC598, + 0xC5B4, + 0xC5D0, + 0xC5EC, + 0xC608, + 0xC624, + 0xC640, + 0xC65C, + 0xC678, + 0xC694, + 0xC6B0, + 0xC6CC, + 0xC6E8, + 0xC704, + 0xC720, + 0xC73C, + 0xC758, + 0xC774, + 0xC790, + 0xC7AC, + 0xC7C8, + 0xC7E4, + 0xC800, + 0xC81C, + 0xC838, + 0xC854, + 0xC870, + 0xC88C, + 0xC8A8, + 0xC8C4, + 0xC8E0, + 0xC8FC, + 0xC918, + 0xC934, + 0xC950, + 0xC96C, + 0xC988, + 0xC9A4, + 0xC9C0, + 0xC9DC, + 0xC9F8, + 0xCA14, + 0xCA30, + 0xCA4C, + 0xCA68, + 0xCA84, + 0xCAA0, + 0xCABC, + 0xCAD8, + 0xCAF4, + 0xCB10, + 0xCB2C, + 0xCB48, + 0xCB64, + 0xCB80, + 0xCB9C, + 0xCBB8, + 0xCBD4, + 0xCBF0, + 0xCC0C, + 0xCC28, + 0xCC44, + 0xCC60, + 0xCC7C, + 0xCC98, + 0xCCB4, + 0xCCD0, + 0xCCEC, + 0xCD08, + 0xCD24, + 0xCD40, + 0xCD5C, + 0xCD78, + 0xCD94, + 0xCDB0, + 0xCDCC, + 0xCDE8, + 0xCE04, + 0xCE20, + 0xCE3C, + 0xCE58, + 0xCE74, + 0xCE90, + 0xCEAC, + 0xCEC8, + 0xCEE4, + 0xCF00, + 0xCF1C, + 0xCF38, + 0xCF54, + 0xCF70, + 0xCF8C, + 0xCFA8, + 0xCFC4, + 0xCFE0, + 0xCFFC, + 0xD018, + 0xD034, + 0xD050, + 0xD06C, + 0xD088, + 0xD0A4, + 0xD0C0, + 0xD0DC, + 0xD0F8, + 0xD114, + 0xD130, + 0xD14C, + 0xD168, + 0xD184, + 0xD1A0, + 0xD1BC, + 0xD1D8, + 0xD1F4, + 0xD210, + 0xD22C, + 0xD248, + 0xD264, + 0xD280, + 0xD29C, + 0xD2B8, + 0xD2D4, + 0xD2F0, + 0xD30C, + 0xD328, + 0xD344, + 0xD360, + 0xD37C, + 0xD398, + 0xD3B4, + 0xD3D0, + 0xD3EC, + 0xD408, + 0xD424, + 0xD440, + 0xD45C, + 0xD478, + 0xD494, + 0xD4B0, + 0xD4CC, + 0xD4E8, + 0xD504, + 0xD520, + 0xD53C, + 0xD558, + 0xD574, + 0xD590, + 0xD5AC, + 0xD5C8, + 0xD5E4, + 0xD600, + 0xD61C, + 0xD638, + 0xD654, + 0xD670, + 0xD68C, + 0xD6A8, + 0xD6C4, + 0xD6E0, + 0xD6FC, + 0xD718, + 0xD734, + 0xD750, + 0xD76C, + 0xD788, +}; + +static const int32_t ucg_hangul_syllable_lvt_ranges[] = { + 0xAC01, 0xAC1B, + 0xAC1D, 0xAC37, + 0xAC39, 0xAC53, + 0xAC55, 0xAC6F, + 0xAC71, 0xAC8B, + 0xAC8D, 0xACA7, + 0xACA9, 0xACC3, + 0xACC5, 0xACDF, + 0xACE1, 0xACFB, + 0xACFD, 0xAD17, + 0xAD19, 0xAD33, + 0xAD35, 0xAD4F, + 0xAD51, 0xAD6B, + 0xAD6D, 0xAD87, + 0xAD89, 0xADA3, + 0xADA5, 0xADBF, + 0xADC1, 0xADDB, + 0xADDD, 0xADF7, + 0xADF9, 0xAE13, + 0xAE15, 0xAE2F, + 0xAE31, 0xAE4B, + 0xAE4D, 0xAE67, + 0xAE69, 0xAE83, + 0xAE85, 0xAE9F, + 0xAEA1, 0xAEBB, + 0xAEBD, 0xAED7, + 0xAED9, 0xAEF3, + 0xAEF5, 0xAF0F, + 0xAF11, 0xAF2B, + 0xAF2D, 0xAF47, + 0xAF49, 0xAF63, + 0xAF65, 0xAF7F, + 0xAF81, 0xAF9B, + 0xAF9D, 0xAFB7, + 0xAFB9, 0xAFD3, + 0xAFD5, 0xAFEF, + 0xAFF1, 0xB00B, + 0xB00D, 0xB027, + 0xB029, 0xB043, + 0xB045, 0xB05F, + 0xB061, 0xB07B, + 0xB07D, 0xB097, + 0xB099, 0xB0B3, + 0xB0B5, 0xB0CF, + 0xB0D1, 0xB0EB, + 0xB0ED, 0xB107, + 0xB109, 0xB123, + 0xB125, 0xB13F, + 0xB141, 0xB15B, + 0xB15D, 0xB177, + 0xB179, 0xB193, + 0xB195, 0xB1AF, + 0xB1B1, 0xB1CB, + 0xB1CD, 0xB1E7, + 0xB1E9, 0xB203, + 0xB205, 0xB21F, + 0xB221, 0xB23B, + 0xB23D, 0xB257, + 0xB259, 0xB273, + 0xB275, 0xB28F, + 0xB291, 0xB2AB, + 0xB2AD, 0xB2C7, + 0xB2C9, 0xB2E3, + 0xB2E5, 0xB2FF, + 0xB301, 0xB31B, + 0xB31D, 0xB337, + 0xB339, 0xB353, + 0xB355, 0xB36F, + 0xB371, 0xB38B, + 0xB38D, 0xB3A7, + 0xB3A9, 0xB3C3, + 0xB3C5, 0xB3DF, + 0xB3E1, 0xB3FB, + 0xB3FD, 0xB417, + 0xB419, 0xB433, + 0xB435, 0xB44F, + 0xB451, 0xB46B, + 0xB46D, 0xB487, + 0xB489, 0xB4A3, + 0xB4A5, 0xB4BF, + 0xB4C1, 0xB4DB, + 0xB4DD, 0xB4F7, + 0xB4F9, 0xB513, + 0xB515, 0xB52F, + 0xB531, 0xB54B, + 0xB54D, 0xB567, + 0xB569, 0xB583, + 0xB585, 0xB59F, + 0xB5A1, 0xB5BB, + 0xB5BD, 0xB5D7, + 0xB5D9, 0xB5F3, + 0xB5F5, 0xB60F, + 0xB611, 0xB62B, + 0xB62D, 0xB647, + 0xB649, 0xB663, + 0xB665, 0xB67F, + 0xB681, 0xB69B, + 0xB69D, 0xB6B7, + 0xB6B9, 0xB6D3, + 0xB6D5, 0xB6EF, + 0xB6F1, 0xB70B, + 0xB70D, 0xB727, + 0xB729, 0xB743, + 0xB745, 0xB75F, + 0xB761, 0xB77B, + 0xB77D, 0xB797, + 0xB799, 0xB7B3, + 0xB7B5, 0xB7CF, + 0xB7D1, 0xB7EB, + 0xB7ED, 0xB807, + 0xB809, 0xB823, + 0xB825, 0xB83F, + 0xB841, 0xB85B, + 0xB85D, 0xB877, + 0xB879, 0xB893, + 0xB895, 0xB8AF, + 0xB8B1, 0xB8CB, + 0xB8CD, 0xB8E7, + 0xB8E9, 0xB903, + 0xB905, 0xB91F, + 0xB921, 0xB93B, + 0xB93D, 0xB957, + 0xB959, 0xB973, + 0xB975, 0xB98F, + 0xB991, 0xB9AB, + 0xB9AD, 0xB9C7, + 0xB9C9, 0xB9E3, + 0xB9E5, 0xB9FF, + 0xBA01, 0xBA1B, + 0xBA1D, 0xBA37, + 0xBA39, 0xBA53, + 0xBA55, 0xBA6F, + 0xBA71, 0xBA8B, + 0xBA8D, 0xBAA7, + 0xBAA9, 0xBAC3, + 0xBAC5, 0xBADF, + 0xBAE1, 0xBAFB, + 0xBAFD, 0xBB17, + 0xBB19, 0xBB33, + 0xBB35, 0xBB4F, + 0xBB51, 0xBB6B, + 0xBB6D, 0xBB87, + 0xBB89, 0xBBA3, + 0xBBA5, 0xBBBF, + 0xBBC1, 0xBBDB, + 0xBBDD, 0xBBF7, + 0xBBF9, 0xBC13, + 0xBC15, 0xBC2F, + 0xBC31, 0xBC4B, + 0xBC4D, 0xBC67, + 0xBC69, 0xBC83, + 0xBC85, 0xBC9F, + 0xBCA1, 0xBCBB, + 0xBCBD, 0xBCD7, + 0xBCD9, 0xBCF3, + 0xBCF5, 0xBD0F, + 0xBD11, 0xBD2B, + 0xBD2D, 0xBD47, + 0xBD49, 0xBD63, + 0xBD65, 0xBD7F, + 0xBD81, 0xBD9B, + 0xBD9D, 0xBDB7, + 0xBDB9, 0xBDD3, + 0xBDD5, 0xBDEF, + 0xBDF1, 0xBE0B, + 0xBE0D, 0xBE27, + 0xBE29, 0xBE43, + 0xBE45, 0xBE5F, + 0xBE61, 0xBE7B, + 0xBE7D, 0xBE97, + 0xBE99, 0xBEB3, + 0xBEB5, 0xBECF, + 0xBED1, 0xBEEB, + 0xBEED, 0xBF07, + 0xBF09, 0xBF23, + 0xBF25, 0xBF3F, + 0xBF41, 0xBF5B, + 0xBF5D, 0xBF77, + 0xBF79, 0xBF93, + 0xBF95, 0xBFAF, + 0xBFB1, 0xBFCB, + 0xBFCD, 0xBFE7, + 0xBFE9, 0xC003, + 0xC005, 0xC01F, + 0xC021, 0xC03B, + 0xC03D, 0xC057, + 0xC059, 0xC073, + 0xC075, 0xC08F, + 0xC091, 0xC0AB, + 0xC0AD, 0xC0C7, + 0xC0C9, 0xC0E3, + 0xC0E5, 0xC0FF, + 0xC101, 0xC11B, + 0xC11D, 0xC137, + 0xC139, 0xC153, + 0xC155, 0xC16F, + 0xC171, 0xC18B, + 0xC18D, 0xC1A7, + 0xC1A9, 0xC1C3, + 0xC1C5, 0xC1DF, + 0xC1E1, 0xC1FB, + 0xC1FD, 0xC217, + 0xC219, 0xC233, + 0xC235, 0xC24F, + 0xC251, 0xC26B, + 0xC26D, 0xC287, + 0xC289, 0xC2A3, + 0xC2A5, 0xC2BF, + 0xC2C1, 0xC2DB, + 0xC2DD, 0xC2F7, + 0xC2F9, 0xC313, + 0xC315, 0xC32F, + 0xC331, 0xC34B, + 0xC34D, 0xC367, + 0xC369, 0xC383, + 0xC385, 0xC39F, + 0xC3A1, 0xC3BB, + 0xC3BD, 0xC3D7, + 0xC3D9, 0xC3F3, + 0xC3F5, 0xC40F, + 0xC411, 0xC42B, + 0xC42D, 0xC447, + 0xC449, 0xC463, + 0xC465, 0xC47F, + 0xC481, 0xC49B, + 0xC49D, 0xC4B7, + 0xC4B9, 0xC4D3, + 0xC4D5, 0xC4EF, + 0xC4F1, 0xC50B, + 0xC50D, 0xC527, + 0xC529, 0xC543, + 0xC545, 0xC55F, + 0xC561, 0xC57B, + 0xC57D, 0xC597, + 0xC599, 0xC5B3, + 0xC5B5, 0xC5CF, + 0xC5D1, 0xC5EB, + 0xC5ED, 0xC607, + 0xC609, 0xC623, + 0xC625, 0xC63F, + 0xC641, 0xC65B, + 0xC65D, 0xC677, + 0xC679, 0xC693, + 0xC695, 0xC6AF, + 0xC6B1, 0xC6CB, + 0xC6CD, 0xC6E7, + 0xC6E9, 0xC703, + 0xC705, 0xC71F, + 0xC721, 0xC73B, + 0xC73D, 0xC757, + 0xC759, 0xC773, + 0xC775, 0xC78F, + 0xC791, 0xC7AB, + 0xC7AD, 0xC7C7, + 0xC7C9, 0xC7E3, + 0xC7E5, 0xC7FF, + 0xC801, 0xC81B, + 0xC81D, 0xC837, + 0xC839, 0xC853, + 0xC855, 0xC86F, + 0xC871, 0xC88B, + 0xC88D, 0xC8A7, + 0xC8A9, 0xC8C3, + 0xC8C5, 0xC8DF, + 0xC8E1, 0xC8FB, + 0xC8FD, 0xC917, + 0xC919, 0xC933, + 0xC935, 0xC94F, + 0xC951, 0xC96B, + 0xC96D, 0xC987, + 0xC989, 0xC9A3, + 0xC9A5, 0xC9BF, + 0xC9C1, 0xC9DB, + 0xC9DD, 0xC9F7, + 0xC9F9, 0xCA13, + 0xCA15, 0xCA2F, + 0xCA31, 0xCA4B, + 0xCA4D, 0xCA67, + 0xCA69, 0xCA83, + 0xCA85, 0xCA9F, + 0xCAA1, 0xCABB, + 0xCABD, 0xCAD7, + 0xCAD9, 0xCAF3, + 0xCAF5, 0xCB0F, + 0xCB11, 0xCB2B, + 0xCB2D, 0xCB47, + 0xCB49, 0xCB63, + 0xCB65, 0xCB7F, + 0xCB81, 0xCB9B, + 0xCB9D, 0xCBB7, + 0xCBB9, 0xCBD3, + 0xCBD5, 0xCBEF, + 0xCBF1, 0xCC0B, + 0xCC0D, 0xCC27, + 0xCC29, 0xCC43, + 0xCC45, 0xCC5F, + 0xCC61, 0xCC7B, + 0xCC7D, 0xCC97, + 0xCC99, 0xCCB3, + 0xCCB5, 0xCCCF, + 0xCCD1, 0xCCEB, + 0xCCED, 0xCD07, + 0xCD09, 0xCD23, + 0xCD25, 0xCD3F, + 0xCD41, 0xCD5B, + 0xCD5D, 0xCD77, + 0xCD79, 0xCD93, + 0xCD95, 0xCDAF, + 0xCDB1, 0xCDCB, + 0xCDCD, 0xCDE7, + 0xCDE9, 0xCE03, + 0xCE05, 0xCE1F, + 0xCE21, 0xCE3B, + 0xCE3D, 0xCE57, + 0xCE59, 0xCE73, + 0xCE75, 0xCE8F, + 0xCE91, 0xCEAB, + 0xCEAD, 0xCEC7, + 0xCEC9, 0xCEE3, + 0xCEE5, 0xCEFF, + 0xCF01, 0xCF1B, + 0xCF1D, 0xCF37, + 0xCF39, 0xCF53, + 0xCF55, 0xCF6F, + 0xCF71, 0xCF8B, + 0xCF8D, 0xCFA7, + 0xCFA9, 0xCFC3, + 0xCFC5, 0xCFDF, + 0xCFE1, 0xCFFB, + 0xCFFD, 0xD017, + 0xD019, 0xD033, + 0xD035, 0xD04F, + 0xD051, 0xD06B, + 0xD06D, 0xD087, + 0xD089, 0xD0A3, + 0xD0A5, 0xD0BF, + 0xD0C1, 0xD0DB, + 0xD0DD, 0xD0F7, + 0xD0F9, 0xD113, + 0xD115, 0xD12F, + 0xD131, 0xD14B, + 0xD14D, 0xD167, + 0xD169, 0xD183, + 0xD185, 0xD19F, + 0xD1A1, 0xD1BB, + 0xD1BD, 0xD1D7, + 0xD1D9, 0xD1F3, + 0xD1F5, 0xD20F, + 0xD211, 0xD22B, + 0xD22D, 0xD247, + 0xD249, 0xD263, + 0xD265, 0xD27F, + 0xD281, 0xD29B, + 0xD29D, 0xD2B7, + 0xD2B9, 0xD2D3, + 0xD2D5, 0xD2EF, + 0xD2F1, 0xD30B, + 0xD30D, 0xD327, + 0xD329, 0xD343, + 0xD345, 0xD35F, + 0xD361, 0xD37B, + 0xD37D, 0xD397, + 0xD399, 0xD3B3, + 0xD3B5, 0xD3CF, + 0xD3D1, 0xD3EB, + 0xD3ED, 0xD407, + 0xD409, 0xD423, + 0xD425, 0xD43F, + 0xD441, 0xD45B, + 0xD45D, 0xD477, + 0xD479, 0xD493, + 0xD495, 0xD4AF, + 0xD4B1, 0xD4CB, + 0xD4CD, 0xD4E7, + 0xD4E9, 0xD503, + 0xD505, 0xD51F, + 0xD521, 0xD53B, + 0xD53D, 0xD557, + 0xD559, 0xD573, + 0xD575, 0xD58F, + 0xD591, 0xD5AB, + 0xD5AD, 0xD5C7, + 0xD5C9, 0xD5E3, + 0xD5E5, 0xD5FF, + 0xD601, 0xD61B, + 0xD61D, 0xD637, + 0xD639, 0xD653, + 0xD655, 0xD66F, + 0xD671, 0xD68B, + 0xD68D, 0xD6A7, + 0xD6A9, 0xD6C3, + 0xD6C5, 0xD6DF, + 0xD6E1, 0xD6FB, + 0xD6FD, 0xD717, + 0xD719, 0xD733, + 0xD735, 0xD74F, + 0xD751, 0xD76B, + 0xD76D, 0xD787, + 0xD789, 0xD7A3, +}; + +static const int32_t ucg_indic_conjunct_break_consonant_ranges[] = { + 0x0915, 0x0939, + 0x0958, 0x095F, + 0x0978, 0x097F, + 0x0995, 0x09A8, + 0x09AA, 0x09B0, + 0x09B2, 0x09B2, + 0x09B6, 0x09B9, + 0x09DC, 0x09DD, + 0x09DF, 0x09DF, + 0x09F0, 0x09F1, + 0x0A95, 0x0AA8, + 0x0AAA, 0x0AB0, + 0x0AB2, 0x0AB3, + 0x0AB5, 0x0AB9, + 0x0AF9, 0x0AF9, + 0x0B15, 0x0B28, + 0x0B2A, 0x0B30, + 0x0B32, 0x0B33, + 0x0B35, 0x0B39, + 0x0B5C, 0x0B5D, + 0x0B5F, 0x0B5F, + 0x0B71, 0x0B71, + 0x0C15, 0x0C28, + 0x0C2A, 0x0C39, + 0x0C58, 0x0C5A, + 0x0D15, 0x0D3A, +}; + +static const int32_t ucg_indic_conjunct_break_extend_ranges[] = { + 0x0300, 0x034E, + 0x0350, 0x036F, + 0x0483, 0x0487, + 0x0591, 0x05BD, + 0x05BF, 0x05BF, + 0x05C1, 0x05C2, + 0x05C4, 0x05C5, + 0x05C7, 0x05C7, + 0x0610, 0x061A, + 0x064B, 0x065F, + 0x0670, 0x0670, + 0x06D6, 0x06DC, + 0x06DF, 0x06E4, + 0x06E7, 0x06E8, + 0x06EA, 0x06ED, + 0x0711, 0x0711, + 0x0730, 0x074A, + 0x07EB, 0x07F3, + 0x07FD, 0x07FD, + 0x0816, 0x0819, + 0x081B, 0x0823, + 0x0825, 0x0827, + 0x0829, 0x082D, + 0x0859, 0x085B, + 0x0898, 0x089F, + 0x08CA, 0x08E1, + 0x08E3, 0x08FF, + 0x093C, 0x093C, + 0x0951, 0x0954, + 0x09BC, 0x09BC, + 0x09FE, 0x09FE, + 0x0A3C, 0x0A3C, + 0x0ABC, 0x0ABC, + 0x0B3C, 0x0B3C, + 0x0C3C, 0x0C3C, + 0x0C55, 0x0C56, + 0x0CBC, 0x0CBC, + 0x0D3B, 0x0D3C, + 0x0E38, 0x0E3A, + 0x0E48, 0x0E4B, + 0x0EB8, 0x0EBA, + 0x0EC8, 0x0ECB, + 0x0F18, 0x0F19, + 0x0F35, 0x0F35, + 0x0F37, 0x0F37, + 0x0F39, 0x0F39, + 0x0F71, 0x0F72, + 0x0F74, 0x0F74, + 0x0F7A, 0x0F7D, + 0x0F80, 0x0F80, + 0x0F82, 0x0F84, + 0x0F86, 0x0F87, + 0x0FC6, 0x0FC6, + 0x1037, 0x1037, + 0x1039, 0x103A, + 0x108D, 0x108D, + 0x135D, 0x135F, + 0x1714, 0x1714, + 0x17D2, 0x17D2, + 0x17DD, 0x17DD, + 0x18A9, 0x18A9, + 0x1939, 0x193B, + 0x1A17, 0x1A18, + 0x1A60, 0x1A60, + 0x1A75, 0x1A7C, + 0x1A7F, 0x1A7F, + 0x1AB0, 0x1ABD, + 0x1ABF, 0x1ACE, + 0x1B34, 0x1B34, + 0x1B6B, 0x1B73, + 0x1BAB, 0x1BAB, + 0x1BE6, 0x1BE6, + 0x1C37, 0x1C37, + 0x1CD0, 0x1CD2, + 0x1CD4, 0x1CE0, + 0x1CE2, 0x1CE8, + 0x1CED, 0x1CED, + 0x1CF4, 0x1CF4, + 0x1CF8, 0x1CF9, + 0x1DC0, 0x1DFF, + 0x200D, 0x200D, + 0x20D0, 0x20DC, + 0x20E1, 0x20E1, + 0x20E5, 0x20F0, + 0x2CEF, 0x2CF1, + 0x2D7F, 0x2D7F, + 0x2DE0, 0x2DFF, + 0x302A, 0x302D, + 0x302E, 0x302F, + 0x3099, 0x309A, + 0xA66F, 0xA66F, + 0xA674, 0xA67D, + 0xA69E, 0xA69F, + 0xA6F0, 0xA6F1, + 0xA82C, 0xA82C, + 0xA8E0, 0xA8F1, + 0xA92B, 0xA92D, + 0xA9B3, 0xA9B3, + 0xAAB0, 0xAAB0, + 0xAAB2, 0xAAB4, + 0xAAB7, 0xAAB8, + 0xAABE, 0xAABF, + 0xAAC1, 0xAAC1, + 0xAAF6, 0xAAF6, + 0xABED, 0xABED, + 0xFB1E, 0xFB1E, + 0xFE20, 0xFE2F, + 0x101FD, 0x101FD, + 0x102E0, 0x102E0, + 0x10376, 0x1037A, + 0x10A0D, 0x10A0D, + 0x10A0F, 0x10A0F, + 0x10A38, 0x10A3A, + 0x10A3F, 0x10A3F, + 0x10AE5, 0x10AE6, + 0x10D24, 0x10D27, + 0x10EAB, 0x10EAC, + 0x10EFD, 0x10EFF, + 0x10F46, 0x10F50, + 0x10F82, 0x10F85, + 0x11070, 0x11070, + 0x1107F, 0x1107F, + 0x110BA, 0x110BA, + 0x11100, 0x11102, + 0x11133, 0x11134, + 0x11173, 0x11173, + 0x111CA, 0x111CA, + 0x11236, 0x11236, + 0x112E9, 0x112EA, + 0x1133B, 0x1133C, + 0x11366, 0x1136C, + 0x11370, 0x11374, + 0x11446, 0x11446, + 0x1145E, 0x1145E, + 0x114C3, 0x114C3, + 0x115C0, 0x115C0, + 0x116B7, 0x116B7, + 0x1172B, 0x1172B, + 0x1183A, 0x1183A, + 0x1193E, 0x1193E, + 0x11943, 0x11943, + 0x11A34, 0x11A34, + 0x11A47, 0x11A47, + 0x11A99, 0x11A99, + 0x11D42, 0x11D42, + 0x11D44, 0x11D45, + 0x11D97, 0x11D97, + 0x11F42, 0x11F42, + 0x16AF0, 0x16AF4, + 0x16B30, 0x16B36, + 0x1BC9E, 0x1BC9E, + 0x1D165, 0x1D165, + 0x1D167, 0x1D169, + 0x1D16E, 0x1D172, + 0x1D17B, 0x1D182, + 0x1D185, 0x1D18B, + 0x1D1AA, 0x1D1AD, + 0x1D242, 0x1D244, + 0x1E000, 0x1E006, + 0x1E008, 0x1E018, + 0x1E01B, 0x1E021, + 0x1E023, 0x1E024, + 0x1E026, 0x1E02A, + 0x1E08F, 0x1E08F, + 0x1E130, 0x1E136, + 0x1E2AE, 0x1E2AE, + 0x1E2EC, 0x1E2EF, + 0x1E4EC, 0x1E4EF, + 0x1E8D0, 0x1E8D6, + 0x1E944, 0x1E94A, +}; + +// Fullwidth (F) and Wide (W) are counted as 2. +// Everything else is 1. +// +// Derived from: https://unicode.org/Public/15.1.0/ucd/EastAsianWidth.txt +static const int32_t ucg_normalized_east_asian_width_ranges[] = { + 0x0000, 0x10FF, 1, + 0x1100, 0x115F, 2, + 0x1160, 0x2319, 1, + 0x231A, 0x231B, 2, + 0x231C, 0x2328, 1, + 0x2329, 0x232A, 2, + 0x232B, 0x23E8, 1, + 0x23E9, 0x23EC, 2, + 0x23ED, 0x23EF, 1, + 0x23F0, 0x23F0, 2, + 0x23F1, 0x23F2, 1, + 0x23F3, 0x23F3, 2, + 0x23F4, 0x25FC, 1, + 0x25FD, 0x25FE, 2, + 0x25FF, 0x2613, 1, + 0x2614, 0x2615, 2, + 0x2616, 0x2647, 1, + 0x2648, 0x2653, 2, + 0x2654, 0x267E, 1, + 0x267F, 0x267F, 2, + 0x2680, 0x2692, 1, + 0x2693, 0x2693, 2, + 0x2694, 0x26A0, 1, + 0x26A1, 0x26A1, 2, + 0x26A2, 0x26A9, 1, + 0x26AA, 0x26AB, 2, + 0x26AC, 0x26BC, 1, + 0x26BD, 0x26BE, 2, + 0x26BF, 0x26C3, 1, + 0x26C4, 0x26C5, 2, + 0x26C6, 0x26CD, 1, + 0x26CE, 0x26CE, 2, + 0x26CF, 0x26D3, 1, + 0x26D4, 0x26D4, 2, + 0x26D5, 0x26E9, 1, + 0x26EA, 0x26EA, 2, + 0x26EB, 0x26F1, 1, + 0x26F2, 0x26F3, 2, + 0x26F4, 0x26F4, 1, + 0x26F5, 0x26F5, 2, + 0x26F6, 0x26F9, 1, + 0x26FA, 0x26FA, 2, + 0x26FB, 0x26FC, 1, + 0x26FD, 0x26FD, 2, + 0x26FE, 0x2704, 1, + 0x2705, 0x2705, 2, + 0x2706, 0x2709, 1, + 0x270A, 0x270B, 2, + 0x270C, 0x2727, 1, + 0x2728, 0x2728, 2, + 0x2729, 0x274B, 1, + 0x274C, 0x274C, 2, + 0x274D, 0x274D, 1, + 0x274E, 0x274E, 2, + 0x274F, 0x2752, 1, + 0x2753, 0x2755, 2, + 0x2756, 0x2756, 1, + 0x2757, 0x2757, 2, + 0x2758, 0x2794, 1, + 0x2795, 0x2797, 2, + 0x2798, 0x27AF, 1, + 0x27B0, 0x27B0, 2, + 0x27B1, 0x27BE, 1, + 0x27BF, 0x27BF, 2, + 0x27C0, 0x2B1A, 1, + 0x2B1B, 0x2B1C, 2, + 0x2B1D, 0x2B4F, 1, + 0x2B50, 0x2B50, 2, + 0x2B51, 0x2B54, 1, + 0x2B55, 0x2B55, 2, + 0x2B56, 0x2E5D, 1, + 0x2E80, 0x303E, 2, + 0x303F, 0x303F, 1, + 0x3041, 0x3247, 2, + 0x3248, 0x324F, 1, + 0x3250, 0x4DBF, 2, + 0x4DC0, 0x4DFF, 1, + 0x4E00, 0xA4C6, 2, + 0xA4D0, 0xA95F, 1, + 0xA960, 0xA97C, 2, + 0xA980, 0xABF9, 1, + 0xAC00, 0xD7A3, 2, + 0xD7B0, 0xF8FF, 1, + 0xF900, 0xFAFF, 2, + 0xFB00, 0xFE0F, 1, + 0xFE10, 0xFE19, 2, + 0xFE20, 0xFE2F, 1, + 0xFE30, 0xFE6B, 2, + 0xFE70, 0xFEFF, 1, + 0xFF01, 0xFF60, 2, + 0xFF61, 0xFFDC, 1, + 0xFFE0, 0xFFE6, 2, + 0xFFE8, 0x16F9F, 1, + 0x16FE0, 0x1B2FB, 2, + 0x1BC00, 0x1F003, 1, + 0x1F004, 0x1F004, 2, + 0x1F005, 0x1F0CE, 1, + 0x1F0CF, 0x1F0CF, 2, + 0x1F0D1, 0x1F18D, 1, + 0x1F18E, 0x1F18E, 2, + 0x1F18F, 0x1F190, 1, + 0x1F191, 0x1F19A, 2, + 0x1F19B, 0x1F1FF, 1, + 0x1F200, 0x1F320, 2, + 0x1F321, 0x1F32C, 1, + 0x1F32D, 0x1F335, 2, + 0x1F336, 0x1F336, 1, + 0x1F337, 0x1F37C, 2, + 0x1F37D, 0x1F37D, 1, + 0x1F37E, 0x1F393, 2, + 0x1F394, 0x1F39F, 1, + 0x1F3A0, 0x1F3CA, 2, + 0x1F3CB, 0x1F3CE, 1, + 0x1F3CF, 0x1F3D3, 2, + 0x1F3D4, 0x1F3DF, 1, + 0x1F3E0, 0x1F3F0, 2, + 0x1F3F1, 0x1F3F3, 1, + 0x1F3F4, 0x1F3F4, 2, + 0x1F3F5, 0x1F3F7, 1, + 0x1F3F8, 0x1F43E, 2, + 0x1F43F, 0x1F43F, 1, + 0x1F440, 0x1F440, 2, + 0x1F441, 0x1F441, 1, + 0x1F442, 0x1F4FC, 2, + 0x1F4FD, 0x1F4FE, 1, + 0x1F4FF, 0x1F53D, 2, + 0x1F53E, 0x1F54A, 1, + 0x1F54B, 0x1F54E, 2, + 0x1F54F, 0x1F54F, 1, + 0x1F550, 0x1F567, 2, + 0x1F568, 0x1F579, 1, + 0x1F57A, 0x1F57A, 2, + 0x1F57B, 0x1F594, 1, + 0x1F595, 0x1F596, 2, + 0x1F597, 0x1F5A3, 1, + 0x1F5A4, 0x1F5A4, 2, + 0x1F5A5, 0x1F5FA, 1, + 0x1F5FB, 0x1F64F, 2, + 0x1F650, 0x1F67F, 1, + 0x1F680, 0x1F6C5, 2, + 0x1F6C6, 0x1F6CB, 1, + 0x1F6CC, 0x1F6CC, 2, + 0x1F6CD, 0x1F6CF, 1, + 0x1F6D0, 0x1F6D2, 2, + 0x1F6D3, 0x1F6D4, 1, + 0x1F6D5, 0x1F6DF, 2, + 0x1F6E0, 0x1F6EA, 1, + 0x1F6EB, 0x1F6EC, 2, + 0x1F6F0, 0x1F6F3, 1, + 0x1F6F4, 0x1F6FC, 2, + 0x1F700, 0x1F7D9, 1, + 0x1F7E0, 0x1F7F0, 2, + 0x1F800, 0x1F90B, 1, + 0x1F90C, 0x1F93A, 2, + 0x1F93B, 0x1F93B, 1, + 0x1F93C, 0x1F945, 2, + 0x1F946, 0x1F946, 1, + 0x1F947, 0x1F9FF, 2, + 0x1FA00, 0x1FA6D, 1, + 0x1FA70, 0x1FAF8, 2, + 0x1FB00, 0x1FBF9, 1, + 0x20000, 0x3FFFD, 2, + 0xE0001, 0x10FFFD, 1, +}; + +// +// End of Unicode 15.1.0 block. +// + +#ifdef __cplusplus +} +#endif + +#endif /* _UCG_TABLES_INCLUDED */ diff --git a/src/unicode.cpp b/src/unicode.cpp index c244a323c..665d5b182 100644 --- a/src/unicode.cpp +++ b/src/unicode.cpp @@ -162,3 +162,8 @@ end: if (codepoint_out) *codepoint_out = codepoint; return width; } + +// NOTE(Feoramund): It's down here because I made UCG use the utf8_decode above to avoid duplicating code. +extern "C" { +#include "ucg/ucg.c" +} From 8ed5cb283b5039693e96d6f47eea6213194d6cbe Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Sat, 29 Jun 2024 18:17:44 -0400 Subject: [PATCH 110/129] Re-implement the error squiggles with visual width --- src/check_stmt.cpp | 18 ++- src/error.cpp | 291 ++++++++++++++++++++------------------------- 2 files changed, 144 insertions(+), 165 deletions(-) diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index c369ba098..f2e3b0242 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -582,20 +582,28 @@ gb_internal Type *check_assignment_variable(CheckerContext *ctx, Operand *lhs, O isize offset = show_error_on_line(e->token.pos, token_pos_end(e->token)); if (offset < 0) { if (is_type_map(e->type)) { - error_line("\t\tSuggestion: Did you mean? 'for key, &%.*s in ...'\n", LIT(e->token.string)); + error_line("\tSuggestion: Did you mean? 'for key, &%.*s in ...'\n", LIT(e->token.string)); } else { - error_line("\t\tSuggestion: Did you mean? 'for &%.*s in ...'\n", LIT(e->token.string)); + error_line("\tSuggestion: Did you mean? 'for &%.*s in ...'\n", LIT(e->token.string)); } } else { - error_line("\t\t'%.*s' is immutable, declare it as '&%.*s' to make it mutable\n", LIT(e->token.string), LIT(e->token.string)); + error_line("\t"); + for (isize i = 0; i < offset-1; i++) { + error_line(" "); + } + error_line("'%.*s' is immutable, declare it as '&%.*s' to make it mutable\n", LIT(e->token.string), LIT(e->token.string)); } } else if (e && e->flags & EntityFlag_SwitchValue) { isize offset = show_error_on_line(e->token.pos, token_pos_end(e->token)); if (offset < 0) { - error_line("\t\tSuggestion: Did you mean? 'switch &%.*s in ...'\n", LIT(e->token.string)); + error_line("\tSuggestion: Did you mean? 'switch &%.*s in ...'\n", LIT(e->token.string)); } else { - error_line("\t\t'%.*s' is immutable, declare it as '&%.*s' to make it mutable\n", LIT(e->token.string), LIT(e->token.string)); + error_line("\t"); + for (isize i = 0; i < offset-1; i++) { + error_line(" "); + } + error_line("'%.*s' is immutable, declare it as '&%.*s' to make it mutable\n", LIT(e->token.string), LIT(e->token.string)); } } } diff --git a/src/error.cpp b/src/error.cpp index 26b4106a0..f95123f15 100644 --- a/src/error.cpp +++ b/src/error.cpp @@ -283,9 +283,6 @@ gb_internal isize show_error_on_line(TokenPos const &pos, TokenPos end) { error_out("\t( empty line )\n"); terminal_reset_colours(); - // Preserve the old return behaviour. Even if we can't guarantee the - // exact visual space offset, there are two places that check this to - // change what sort of suggestion they offer. if (the_line == nullptr) { return -1; } else { @@ -293,244 +290,218 @@ gb_internal isize show_error_on_line(TokenPos const &pos, TokenPos end) { } } - // Specfically use basic ASCII arrows here, in case the terminal - // doesn't support anything fancy. This is meant to be a good fallback. - char const *mark_error_sign = "><"; - char const *open_error_sign = ">>"; - char const *close_error_sign = "<<"; - const TerminalColour marker_colour = TerminalColour_Yellow; - - // ANSI SGR: - // 0 = Reset. - // 58:5:2 = Underline colour, 8-bit, green. (non-standard) - // 4:3 = Wiggly underline. (non-standard) - char const *wiggly_underline_sgr = ""; - char const *disable_underline_sgr = ""; - if (has_ansi_terminal_colours()) { - wiggly_underline_sgr = "\x1b[0;58:5:2;4:3m"; - disable_underline_sgr = "\x1b[24m"; - } - // These two will be used like an Odin slice later. char const *line_text = the_line; i32 line_length_bytes = cast(i32)gb_string_length(the_line); - // NOTE(Feoramund): The numbers below are in Unicode codepoints - // (or runes), not visual glyph width. Calculating the visual width of - // a cluster of Unicode codepoints is vexing, and `utf8proc_charwidth` - // is inadequate. - // - // We're counting codepoints here so we don't slice one down the - // middle during truncation. It will still look strange if we slice - // a cluster down the middle. (i.e. a letter and a combining diacritic) - // - // Luckily, if our assumption about 1 codepoint == 1 glyph is wrong, - // we only suffer a shorter or longer line displayed in total, but all - // of our highlighting and marking will be precise. - // (Unless there's an invalid Unicode codepoint, in which case, no guarantees.) - // - // The line will be longer if a codepoint occupies more than one space - // (CJK in most cases) and shorter if a codepoint is invisible or is - // a type of joiner or combining codepoint. - // - // If we get a complete Unicode glyph counter, it would be as simple as - // replacing `utf8_decode` below to make all of this work perfectly. + ucg_grapheme* graphemes; + i32 line_length_runes = 0; + i32 line_length_graphemes = 0; + i32 line_width = 0; + int ucg_result = ucg_decode_grapheme_clusters( + permanent_allocator(), (const uint8_t*)line_text, line_length_bytes, + &graphemes, &line_length_runes, &line_length_graphemes, &line_width); + + if (ucg_result < 0) { + // There was a UTF-8 parsing error. + // Insert a dummy grapheme so the start of the invalid rune can be pointed at. + graphemes = (ucg_grapheme*)gb_resize(permanent_allocator(), + graphemes, + sizeof(ucg_grapheme) * (line_length_graphemes), + sizeof(ucg_grapheme) * (1 + line_length_graphemes)); + + ucg_grapheme append = { + error_start_index_bytes, + line_length_runes, + 1, + }; + + graphemes[line_length_graphemes] = append; + } + + // The units below are counted in visual, monospace cells. enum { MAX_LINE_LENGTH = 80, MAX_TAB_WIDTH = 8, ELLIPSIS_PADDING = 8, // `... ...` - MAX_MARK_WIDTH = 4, // `><` or `>>` and `<<` MIN_LEFT_VIEW = 8, // A rough estimate of how many characters we'll insert, at most: - MAX_INSERTED_WIDTH = MAX_TAB_WIDTH + ELLIPSIS_PADDING + MAX_MARK_WIDTH, + MAX_INSERTED_WIDTH = MAX_TAB_WIDTH + ELLIPSIS_PADDING, MAX_LINE_LENGTH_PADDED = MAX_LINE_LENGTH - MAX_INSERTED_WIDTH, }; - // For the purposes of truncating long lines, we calculate how many - // runes the line is composed of, first. We'll take note of at which - // rune index the error starts, too. - i32 error_start_index_runes = 0; - - i32 line_length_runes = 0; - for (i32 i = 0; i < line_length_bytes; /**/) { - Rune rune; - - if (i == error_start_index_bytes) { - error_start_index_runes = line_length_runes; - } - - i32 bytes_read = cast(i32)utf8_decode(cast(const u8 *)line_text + i, line_length_bytes - i, &rune); - if (rune == GB_RUNE_INVALID || bytes_read <= 0) { - // Bail out; we won't even try to truncate the line later. - line_length_runes = 0; + i32 error_start_index_graphemes = 0; + for (i32 i = 0; i < line_length_graphemes; i += 1) { + if (graphemes[i].byte_index == error_start_index_bytes) { + error_start_index_graphemes = i; break; } - - line_length_runes += 1; - i += bytes_read; } - if (error_start_index_runes == 0 && error_start_index_bytes != 0 && line_length_runes != 0) { - // The error index in runes was not found, but we did find a valid Unicode string. + if (error_start_index_graphemes == 0 && error_start_index_bytes != 0 && line_length_graphemes != 0) { + // The error index in graphemes was not found, but we did find a valid Unicode string. // // This is an edge case where the error is sitting on a newline or the // end of the line, as that is the only location we could not have checked. - error_start_index_runes = line_length_runes; + error_start_index_graphemes = line_length_graphemes; } error_out("\t"); bool show_right_ellipsis = false; - if (line_length_runes > MAX_LINE_LENGTH_PADDED) { + i32 squiggle_padding = 0; + i32 window_open_bytes = 0; + i32 window_close_bytes = 0; + if (line_width > MAX_LINE_LENGTH_PADDED) { // Now that we know the line is over the length limit, we have to - // compose a runic window in which to display the error. - i32 window_width = MAX_LINE_LENGTH_PADDED; + // compose a visual window in which to display the error. + i32 window_size_left = 0; + i32 window_size_right = 0; + i32 window_open_graphemes = 0; - i32 extend_right = 0; - i32 extend_left = 0; - if (error_start_index_runes + window_width > line_length_runes - 1) { - // Trade space from the right to the left. - extend_right = line_length_runes - error_start_index_runes; - extend_left = window_width - extend_right; - } else if (MIN_LEFT_VIEW - error_start_index_runes > 0) { - // Trade space from the left to the right. - extend_left = error_start_index_runes; - extend_right = window_width - extend_left; - } else { - // Square in the middle somewhere. - extend_left = MIN_LEFT_VIEW; - extend_right = window_width - extend_left; + for (i32 i = error_start_index_graphemes - 1; i > 0; i -= 1) { + window_size_left += graphemes[i].width; + if (window_size_left >= MIN_LEFT_VIEW) { + window_open_graphemes = i; + window_open_bytes = graphemes[i].byte_index; + break; + } } - i32 window_right_runes = gb_min(error_start_index_runes + extend_right, line_length_runes); - i32 window_left_runes = gb_max(0, error_start_index_runes - extend_left); - - i32 window_right_bytes = 0; - i32 window_left_bytes = 0; - - i32 i_runes = 0; - for (i32 i = 0; i < line_length_bytes; /**/) { - if (i_runes == window_left_runes ) { window_left_bytes = i; } - if (i_runes == window_right_runes) { window_right_bytes = i; } - - // No need for error-checking. - // - // We've already validated the string at this point, otherwise - // `line_length_runes` would be 0, and we would not have - // entered this block. - i32 bytes_read = cast(i32)utf8_decode(cast(const u8 *)line_text + i, line_length_bytes - i, nullptr); - - i_runes += 1; - i += bytes_read; + for (i32 i = error_start_index_graphemes; i < line_length_graphemes; i += 1) { + window_size_right += graphemes[i].width; + if (window_size_right >= MAX_LINE_LENGTH_PADDED - MIN_LEFT_VIEW) { + window_close_bytes = graphemes[i].byte_index; + break; + } + } + if (window_close_bytes == 0) { + // The window ends at the end of the line. + window_close_bytes = line_length_bytes; } - if (window_right_bytes == 0) { - // The end of the window is the end of the line. - window_right_bytes = line_length_bytes; + if (window_size_right < MAX_LINE_LENGTH_PADDED - MIN_LEFT_VIEW) { + // Hit the end of the string early on the right side; expand backwards. + for (i32 i = window_open_graphemes - 1; i > 0; i -= 1) { + window_size_left += graphemes[i].width; + if (window_size_left + window_size_right >= MAX_LINE_LENGTH_PADDED) { + window_open_graphemes = i; + window_open_bytes = graphemes[i].byte_index; + break; + } + } } - GB_ASSERT_MSG(window_right_runes >= window_left_runes, "Error line truncation window has wrong rune indices. (left, right: %i, %i)", window_left_runes, window_right_runes); - GB_ASSERT_MSG(window_right_bytes >= window_left_bytes, "Error line truncation window has wrong byte indices. (left, right: %i, %i)", window_left_bytes, window_right_bytes); + GB_ASSERT_MSG(window_close_bytes >= window_open_bytes, "Error line truncation window has wrong byte indices. (open, close: %i, %i)", window_open_bytes, window_close_bytes); - if (window_right_bytes != line_length_bytes) { + if (window_close_bytes != line_length_bytes) { show_right_ellipsis = true; } - // The text will advance; all indices and lengths will become relative. - // We must keep our other iterators in sync. - // NOTE: Uncomment the rune versions if they ever get used beyond this point. - // Close the window, going left. - line_length_bytes = window_right_bytes; + line_length_bytes = window_close_bytes; // Adjust the slice of text. In Odin, this would be: // `line_text = line_text[window_left_bytes:]` - line_text += window_left_bytes; - line_length_bytes -= window_left_bytes; - // line_length_runes -= window_left_runes; + line_text += window_open_bytes; + line_length_bytes -= window_open_bytes; GB_ASSERT_MSG(line_length_bytes >= 0, "Bounds-checking error: line_length_bytes"); - // Part of advancing `line_text`: - error_start_index_bytes -= window_left_bytes; - // error_start_index_runes -= window_left_runes; - GB_ASSERT_MSG(error_start_index_bytes >= 0, "Bounds-checking error: error_start_index_bytes"); - - if (window_left_bytes > 0) { + if (window_open_bytes > 0) { error_out("... "); + squiggle_padding += 4; } + } else { + // No truncation needed. + window_open_bytes = 0; + window_close_bytes = line_length_bytes; + } + + for (i32 i = error_start_index_graphemes; i > 0; i -= 1) { + if (graphemes[i].byte_index == window_open_bytes) { + break; + } + squiggle_padding += graphemes[i].width; } // Start printing code. terminal_set_colours(TerminalStyle_Normal, TerminalColour_White); - error_out("%.*s", error_start_index_bytes, line_text); + error_out("%.*s", line_length_bytes, line_text); - // Odin-like: `line_text = line_text[error_start_index_bytes:]` - line_text += error_start_index_bytes; - line_length_bytes -= error_start_index_bytes; - GB_ASSERT_MSG(line_length_bytes >= 0, "Bounds-checking error: line_length_bytes"); + i32 squiggle_length = 0; + bool trailing_squiggle = false; if (end.file_id == pos.file_id) { // The error has an endpoint. - terminal_set_colours(TerminalStyle_Bold, marker_colour); - error_out(open_error_sign); if (end.line > pos.line) { // Error goes to next line. - error_out(wiggly_underline_sgr); - error_out("%.*s", line_length_bytes, line_text); - - error_out(disable_underline_sgr); - // Always show the ellipsis in this case show_right_ellipsis = true; - } else if (end.line == pos.line && end.column > pos.column) { - // Error terminates before line end. - i32 error_length_bytes = gb_min(end.column - pos.column, line_length_bytes); - - error_out(wiggly_underline_sgr); - error_out("%.*s", error_length_bytes, line_text); - line_text += error_length_bytes; - line_length_bytes -= error_length_bytes; - GB_ASSERT_MSG(line_length_bytes >= 0, "Bounds-checking error: line_length_bytes"); - - error_out(disable_underline_sgr); - - if (!show_right_ellipsis) { - // The line hasn't been truncated; show the end marker. - terminal_set_colours(TerminalStyle_Bold, marker_colour); - error_out(close_error_sign); + for (i32 i = error_start_index_graphemes; i < line_length_graphemes; i += 1) { + squiggle_length += graphemes[i].width; + trailing_squiggle = true; } - terminal_set_colours(TerminalStyle_Normal, TerminalColour_White); - error_out("%.*s", line_length_bytes, line_text); - } + } else if (end.line == pos.line && end.column > pos.column) { + // Error terminates before line end. + i32 adjusted_end_index = graphemes[error_start_index_graphemes].byte_index + end.column - pos.column; + for (i32 i = error_start_index_graphemes; i < line_length_graphemes; i += 1) { + if (graphemes[i].byte_index >= adjusted_end_index) { + break; + } else if (graphemes[i].byte_index >= window_close_bytes) { + trailing_squiggle = true; + break; + } + squiggle_length += graphemes[i].width; + } + } } else { // The error is at one spot; no range known. - terminal_set_colours(TerminalStyle_Bold, marker_colour); - error_out(mark_error_sign); - - terminal_set_colours(TerminalStyle_Normal, TerminalColour_White); - error_out("%.*s", line_length_bytes, line_text); + squiggle_length = 1; } if (show_right_ellipsis) { error_out(" ..."); } + error_out("\n\t"); + + for (i32 i = squiggle_padding; i > 0; i -= 1) { + error_out(" "); + } + + terminal_set_colours(TerminalStyle_Bold, TerminalColour_Green); + + if (squiggle_length > 0) { + error_out("^"); + squiggle_length -= 1; + } + for (/**/; squiggle_length > 1; squiggle_length -= 1) { + error_out("~"); + } + if (squiggle_length > 0) { + if (trailing_squiggle) { + error_out("~ ..."); + } else { + error_out("^"); + } + } + // NOTE(Feoramund): Specifically print a newline, then reset colours, // instead of the other way around. Otherwise the printing mechanism // will collapse the newline for reasons currently beyond my ken. error_out("\n"); terminal_reset_colours(); - return error_start_index_bytes; + return squiggle_padding; } gb_internal void error_out_empty(void) { From 2737ccab3d6d82fc9eb3e8585ea528740928a768 Mon Sep 17 00:00:00 2001 From: flysand7 Date: Sun, 30 Jun 2024 12:35:42 +1100 Subject: [PATCH 111/129] [core/windows]: Bind tlhelp.h functions from kernel32.dll --- core/sys/windows/tlhelp.odin | 101 +++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 core/sys/windows/tlhelp.odin diff --git a/core/sys/windows/tlhelp.odin b/core/sys/windows/tlhelp.odin new file mode 100644 index 000000000..259b3de55 --- /dev/null +++ b/core/sys/windows/tlhelp.odin @@ -0,0 +1,101 @@ +//+build windows +package sys_windows + +foreign import kernel32 "system:Kernel32.lib" + +@(default_calling_convention="system") +foreign kernel32 { + CreateToolhelp32Snapshot :: proc (dwFlags: DWORD, th32ProcessID: DWORD) -> HANDLE --- + Process32FirstW :: proc (hSnapshot: HANDLE, lppe: LPPROCESSENTRY32W) -> BOOL --- + Process32NextW :: proc (hSnapshot: HANDLE, lppe: LPPROCESSENTRY32W) -> BOOL --- + Thread32First :: proc (hSnapshot: HANDLE, lpte: LPTHREADENTRY32) -> BOOL --- + Thread32Next :: proc (hSnapshot: HANDLE, lpte: LPTHREADENTRY32) -> BOOL --- + Module32FirstW :: proc (hSnapshot: HANDLE, lpme: LPMODULEENTRY32W) -> BOOL --- + Module32NextW :: proc (hSnapshot: HANDLE, lpme: LPMODULEENTRY32W) -> BOOL --- + Heap32ListFirst :: proc (hSnapshot: HANDLE, lphl: LPHEAPLIST32) -> BOOL --- + Heap32ListNext :: proc (hSnapshot: HANDLE, lphl: LPHEAPLIST32) -> BOOL --- + Heap32First :: proc (lphe: LPHEAPENTRY32, th32ProcessID: DWORD, th32HeapID: ULONG_PTR) -> BOOL --- + Heap32Next :: proc (lphe: LPHEAPENTRY32) -> BOOL --- + Toolhelp32ReadProcessMemory :: proc ( + th32ProcessID: DWORD, + lpBaseAddress: LPCVOID, + lpBuffer: LPVOID, + cbRead: SIZE_T, + lpNumberOfBytesRead: ^SIZE_T, + ) -> BOOL --- +} + +MAX_MODULE_NAME32 :: 255 + +TH32CS_INHERIT :: 0x80000000 +TH32CS_SNAPHEAPLIST :: 0x00000001 +TH32CS_SNAPPROCESS :: 0x00000001 +TH32CS_SNAPTHREAD :: 0x00000004 +TH32CS_SNAPMODULE :: 0x00000008 +TH32CS_SNAPMODULE32 :: 0x00000010 +TH32CS_SNAPALL :: TH32CS_SNAPHEAPLIST | TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD | TH32CS_SNAPMODULE + +PROCESSENTRY32W :: struct { + dwSize: DWORD, + cntUsage: DWORD, + th32ProcessID: DWORD, + th32DefaultHeapID: ULONG_PTR, + th32ModuleID: DWORD, + cntThreads: DWORD, + th32ParentProcessID: DWORD, + pcPriClassBase: LONG, + dwFlags: DWORD, + szExeFile: [MAX_PATH]WCHAR, +} + +LPPROCESSENTRY32W :: ^PROCESSENTRY32W + +THREADENTRY32 :: struct { + dwSize: DWORD, + cntUsage: DWORD, + th32ThreadID: DWORD, + th32OwnerProcessID: DWORD, + tpBasePri: LONG, + tpDeltaPri: LONG, + dwFlags: DWORD, +} + +LPTHREADENTRY32 :: ^THREADENTRY32 + +MODULEENTRY32W :: struct { + dwSize: DWORD, + th32ModuleID: DWORD, + th32ProcessID: DWORD, + GlblcntUsage: DWORD, + ProccntUsage: DWORD, + modBaseAddr: BYTE, + modBaseSize: DWORD, + hModule: HMODULE, + szModule: [MAX_MODULE_NAME32 + 1]WCHAR, + szExePath: [MAX_PATH]WCHAR, +} + +LPMODULEENTRY32W :: ^MODULEENTRY32W + +HEAPLIST32 :: struct { + dwSize: SIZE_T, + th32ProcessID: DWORD, + th32HeapID: ULONG_PTR, + dwFlags: DWORD, +} + +LPHEAPLIST32 :: ^HEAPLIST32 + +HEAPENTRY32 :: struct { + dwSize: SIZE_T, + hHandle: HANDLE, + dwAddress: ULONG_PTR, + dwBlockSize: SIZE_T, + dwFlags: DWORD, + dwLockCount: DWORD, + dwResvd: DWORD, + th32ProcessID: DWORD, + th32HeapID: ULONG_PTR, +} + +LPHEAPENTRY32 :: ^HEAPENTRY32 From 561b96b20dc87f6483e7820b336e313de954967b Mon Sep 17 00:00:00 2001 From: flysand7 Date: Sun, 30 Jun 2024 13:34:08 +1100 Subject: [PATCH 112/129] [sys/windows]: Fix the value for TH32CS_SNAPPROCESS constant --- core/sys/windows/tlhelp.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/sys/windows/tlhelp.odin b/core/sys/windows/tlhelp.odin index 259b3de55..7e224dd05 100644 --- a/core/sys/windows/tlhelp.odin +++ b/core/sys/windows/tlhelp.odin @@ -29,7 +29,7 @@ MAX_MODULE_NAME32 :: 255 TH32CS_INHERIT :: 0x80000000 TH32CS_SNAPHEAPLIST :: 0x00000001 -TH32CS_SNAPPROCESS :: 0x00000001 +TH32CS_SNAPPROCESS :: 0x00000002 TH32CS_SNAPTHREAD :: 0x00000004 TH32CS_SNAPMODULE :: 0x00000008 TH32CS_SNAPMODULE32 :: 0x00000010 From d1603ebac4ac8def9f8a5e4e1e86ddae861847fe Mon Sep 17 00:00:00 2001 From: h0mtanks Date: Sun, 30 Jun 2024 13:42:55 +0530 Subject: [PATCH 113/129] added missing would_block enum member --- core/net/errors_windows.odin | 1 + 1 file changed, 1 insertion(+) diff --git a/core/net/errors_windows.odin b/core/net/errors_windows.odin index 0538c2b82..c1dfa55dc 100644 --- a/core/net/errors_windows.odin +++ b/core/net/errors_windows.odin @@ -135,6 +135,7 @@ TCP_Send_Error :: enum c.int { No_Buffer_Space_Available = win.WSAENOBUFS, Network_Subsystem_Failure = win.WSAENETDOWN, Host_Unreachable = win.WSAEHOSTUNREACH, + Would_Block = win.WSAEWOULDBLOCK, // TODO: verify possible, as not mentioned in docs Offline = win.WSAENETUNREACH, From 2b615b09f0cacbd7c6e716479a031bf4e3dd366c Mon Sep 17 00:00:00 2001 From: h0mtanks Date: Sun, 30 Jun 2024 13:47:11 +0530 Subject: [PATCH 114/129] fixed whitespace --- core/net/errors_windows.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/net/errors_windows.odin b/core/net/errors_windows.odin index c1dfa55dc..f63f17f4e 100644 --- a/core/net/errors_windows.odin +++ b/core/net/errors_windows.odin @@ -135,7 +135,7 @@ TCP_Send_Error :: enum c.int { No_Buffer_Space_Available = win.WSAENOBUFS, Network_Subsystem_Failure = win.WSAENETDOWN, Host_Unreachable = win.WSAEHOSTUNREACH, - Would_Block = win.WSAEWOULDBLOCK, + Would_Block = win.WSAEWOULDBLOCK, // TODO: verify possible, as not mentioned in docs Offline = win.WSAENETUNREACH, From e0face1ac87d34738751bbdb8c29f32bb89b544d Mon Sep 17 00:00:00 2001 From: Karl Zylinski Date: Sun, 30 Jun 2024 20:36:51 +0200 Subject: [PATCH 115/129] Make types like bit_set[$T] have their upper and lower bits overwritten by upper/lower from the source types when checking if polymorphic type is assignable. This fixes an issue where an i8 was always generated for bit_sets with generic elements, because it couldn't figure out upper/lower when check_bit_set_type was run. Fixes #2860 --- src/check_expr.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 891378b99..b9697a6e8 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -1435,6 +1435,16 @@ gb_internal bool is_polymorphic_type_assignable(CheckerContext *c, Type *poly, T if (!is_polymorphic_type_assignable(c, poly->BitSet.elem, source->BitSet.elem, true, modify_type)) { return false; } + + // For generic types like bit_set[$T] the upper and lower of the poly type will be zeroes since + // it could not figure that stuff out when the poly type was created. + if (poly->BitSet.upper == 0 && modify_type) { + poly->BitSet.upper = source->BitSet.upper; + } + if (poly->BitSet.lower == 0 && modify_type) { + poly->BitSet.lower = source->BitSet.lower; + } + if (poly->BitSet.underlying == nullptr) { if (modify_type) { poly->BitSet.underlying = source->BitSet.underlying; From 1e7dfd0e34916b716e9476dd5a9be82b63669842 Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Sun, 30 Jun 2024 16:23:29 -0400 Subject: [PATCH 116/129] Add more `core:net` tests - UDP send & read - DNS resolution - Nonblocking socket option --- tests/core/net/test_core_net.odin | 99 +++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/tests/core/net/test_core_net.odin b/tests/core/net/test_core_net.odin index f806463e9..d5949fb6c 100644 --- a/tests/core/net/test_core_net.odin +++ b/tests/core/net/test_core_net.odin @@ -18,6 +18,7 @@ import "core:sync" import "core:time" import "core:thread" import "core:fmt" +import "core:log" @test address_parsing_test :: proc(t: ^testing.T) { @@ -216,6 +217,8 @@ IP_Address_Parsing_Test_Vectors :: []IP_Address_Parsing_Test_Vector{ ENDPOINT_TWO_SERVERS := net.Endpoint{net.IP4_Address{127, 0, 0, 1}, 9991} ENDPOINT_CLOSED_PORT := net.Endpoint{net.IP4_Address{127, 0, 0, 1}, 9992} ENDPOINT_SERVER_SENDS := net.Endpoint{net.IP4_Address{127, 0, 0, 1}, 9993} +ENDPOINT_UDP_ECHO := net.Endpoint{net.IP4_Address{127, 0, 0, 1}, 9994} +ENDPOINT_NONBLOCK := net.Endpoint{net.IP4_Address{127, 0, 0, 1}, 9995} @(test) two_servers_binding_same_endpoint :: proc(t: ^testing.T) { @@ -516,6 +519,102 @@ join_url_test :: proc(t: ^testing.T) { } } +@test +test_udp_echo :: proc(t: ^testing.T) { + server, make_server_err := net.make_unbound_udp_socket(.IP4) + if !testing.expect_value(t, make_server_err, nil) { + return + } + defer net.close(server) + + bind_server_err := net.bind(server, ENDPOINT_UDP_ECHO) + if !testing.expect_value(t, bind_server_err, nil) { + return + } + + client, make_client_err := net.make_unbound_udp_socket(.IP4) + if !testing.expect_value(t, make_client_err, nil) { + return + } + defer net.close(client) + + msg := "Hellope world!" + buf: [64]u8 + + bytes_written, send_err := net.send_udp(client, transmute([]u8)msg[:], ENDPOINT_UDP_ECHO) + if !testing.expect_value(t, send_err, nil) { + return + } + if !testing.expect_value(t, bytes_written, len(msg)) { + return + } + + bytes_read, _, read_err := net.recv_udp(server, buf[:]) + if !testing.expect_value(t, read_err, nil) { + return + } + if !testing.expect_value(t, bytes_read, len(msg)) { + return + } + + testing.expect_value(t, msg, transmute(string)buf[:bytes_read]) +} + +@test +test_dns_resolve :: proc(t: ^testing.T) { + // NOTE: This test depends on external factors, so if it fails, an IP + // address may have changed or become unavailable. + + // The net API returns only one address per protocol version, and DNS + // records can store many, so we'll have to check all possibilities. + ep4, ep6, resolve_err := net.resolve("dns.quad9.net") + if !testing.expect_value(t, resolve_err, nil) { + return + } + + ip4, ip4_ok := ep4.address.(net.IP4_Address) + if !testing.expect(t, ip4_ok, "Unable to resolve IP4") { + return + } + + valid_ip4_a := net.IP4_Address{ 9, 9, 9, 9} + valid_ip4_b := net.IP4_Address{149, 112, 112, 112} + if ip4 != valid_ip4_a && ip4 != valid_ip4_b { + log.errorf("DNS resolved to invalid IP4: %v, expected %v or %v", ip4, valid_ip4_a, valid_ip4_b) + } + + ip6, ip6_ok := ep6.address.(net.IP6_Address) + if !testing.expect(t, ip6_ok, "Unable to resolve IP6") { + return + } + + valid_ip6_a := net.IP6_Address{0x2620, 0xfe, 0, 0, 0, 0, 0, 9} + valid_ip6_b := net.IP6_Address{0x2620, 0xfe, 0, 0, 0, 0, 0, 0xfe} + if ip6 != valid_ip6_a && ip6 != valid_ip6_b { + log.errorf("DNS resolved to invalid IP6: %v, expected %v or %v", ip6, valid_ip6_a, valid_ip6_b) + } +} + +@test +test_nonblocking_option :: proc(t: ^testing.T) { + server, listen_err := net.listen_tcp(ENDPOINT_NONBLOCK) + if !testing.expect_value(t, listen_err, nil) { + return + } + defer net.close(server) + + testing.set_fail_timeout(t, 2 * time.Second) + + // If the nonblocking option isn't set correctly in the operating system, + // this should block until the timeout hits. + net.set_blocking(server, false) + + _, _, accept_err := net.accept_tcp(server) + if !testing.expect_value(t, accept_err, net.Accept_Error.Would_Block) { + return + } +} + @(private) address_to_binstr :: proc(address: net.Address) -> (binstr: string) { switch t in address { From 8e64265aed03f7d3b6fec51bbbd8596f2a271c0d Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Sun, 30 Jun 2024 16:27:37 -0400 Subject: [PATCH 117/129] Replace unneeded `transmute` --- tests/core/net/test_core_net.odin | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/core/net/test_core_net.odin b/tests/core/net/test_core_net.odin index d5949fb6c..a8f41082a 100644 --- a/tests/core/net/test_core_net.odin +++ b/tests/core/net/test_core_net.odin @@ -259,7 +259,7 @@ client_sends_server_data :: proc(t: ^testing.T) { } tcp_client :: proc(thread_data: rawptr) { - r := transmute(^Thread_Data)thread_data + r := cast(^Thread_Data)thread_data defer sync.wait_group_done(r.wg) @@ -274,7 +274,7 @@ client_sends_server_data :: proc(t: ^testing.T) { } tcp_server :: proc(thread_data: rawptr) { - r := transmute(^Thread_Data)thread_data + r := cast(^Thread_Data)thread_data defer sync.wait_group_done(r.wg) From e3dde8caf808eba70f8ebdd9317f05aa75c3bb5a Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Mon, 1 Jul 2024 00:50:10 +0200 Subject: [PATCH 118/129] make structs with multiple fields always return indirect in wasm c abi --- src/llvm_abi.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/llvm_abi.cpp b/src/llvm_abi.cpp index 1f7a39447..375f1c86a 100644 --- a/src/llvm_abi.cpp +++ b/src/llvm_abi.cpp @@ -1378,14 +1378,14 @@ namespace lbAbiWasm { } else if (lb_is_type_kind(return_type, LLVMStructTypeKind) || lb_is_type_kind(return_type, LLVMArrayTypeKind)) { if (type_can_be_direct(return_type, ft->calling_convention)) { return lb_arg_type_direct(return_type); - } - - i64 sz = lb_sizeof(return_type); - switch (sz) { - case 1: return lb_arg_type_direct(return_type, LLVMIntTypeInContext(c, 8), nullptr, nullptr); - case 2: return lb_arg_type_direct(return_type, LLVMIntTypeInContext(c, 16), nullptr, nullptr); - case 4: return lb_arg_type_direct(return_type, LLVMIntTypeInContext(c, 32), nullptr, nullptr); - case 8: return lb_arg_type_direct(return_type, LLVMIntTypeInContext(c, 64), nullptr, nullptr); + } else if (ft->calling_convention != ProcCC_CDecl) { + i64 sz = lb_sizeof(return_type); + switch (sz) { + case 1: return lb_arg_type_direct(return_type, LLVMIntTypeInContext(c, 8), nullptr, nullptr); + case 2: return lb_arg_type_direct(return_type, LLVMIntTypeInContext(c, 16), nullptr, nullptr); + case 4: return lb_arg_type_direct(return_type, LLVMIntTypeInContext(c, 32), nullptr, nullptr); + case 8: return lb_arg_type_direct(return_type, LLVMIntTypeInContext(c, 64), nullptr, nullptr); + } } LB_ABI_MODIFY_RETURN_IF_TUPLE_MACRO(); From ef6a73c7efa28f45e3c9329f0734589981c9b6a1 Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Mon, 1 Jul 2024 01:30:44 +0200 Subject: [PATCH 119/129] fix not setting cc before using it in abi computations --- src/llvm_abi.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/llvm_abi.cpp b/src/llvm_abi.cpp index 375f1c86a..b2e485d01 100644 --- a/src/llvm_abi.cpp +++ b/src/llvm_abi.cpp @@ -1239,9 +1239,9 @@ namespace lbAbiWasm { gb_internal LB_ABI_INFO(abi_info) { lbFunctionType *ft = gb_alloc_item(permanent_allocator(), lbFunctionType); ft->ctx = c; + ft->calling_convention = calling_convention; ft->args = compute_arg_types(c, arg_types, arg_count, calling_convention, original_type); ft->ret = compute_return_type(ft, c, return_type, return_is_defined, return_is_tuple); - ft->calling_convention = calling_convention; return ft; } From 4a2b87672c20935821b793d8b484765f1ab6b6ff Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 1 Jul 2024 11:11:06 +0100 Subject: [PATCH 120/129] Unify #soa code for structs and arrays --- base/runtime/core_builtin_soa.odin | 57 ++++++++---------------------- 1 file changed, 15 insertions(+), 42 deletions(-) diff --git a/base/runtime/core_builtin_soa.odin b/base/runtime/core_builtin_soa.odin index 816df13e2..3ef41e32d 100644 --- a/base/runtime/core_builtin_soa.odin +++ b/base/runtime/core_builtin_soa.odin @@ -55,7 +55,7 @@ raw_soa_footer_slice :: proc(array: ^$T/#soa[]$E) -> (footer: ^Raw_SOA_Footer_Sl if array == nil { return nil } - field_count := uintptr(intrinsics.type_struct_field_count(E)) + field_count := uintptr(len(E) when intrinsics.type_is_array(E) else intrinsics.type_struct_field_count(E)) footer = (^Raw_SOA_Footer_Slice)(uintptr(array) + field_count*size_of(rawptr)) return } @@ -64,12 +64,7 @@ raw_soa_footer_dynamic_array :: proc(array: ^$T/#soa[dynamic]$E) -> (footer: ^Ra if array == nil { return nil } - field_count: uintptr - when intrinsics.type_is_array(E) { - field_count = len(E) - } else { - field_count = uintptr(intrinsics.type_struct_field_count(E)) - } + field_count := uintptr(len(E) when intrinsics.type_is_array(E) else intrinsics.type_struct_field_count(E)) footer = (^Raw_SOA_Footer_Dynamic_Array)(uintptr(array) + field_count*size_of(rawptr)) return } @@ -98,7 +93,7 @@ make_soa_aligned :: proc($T: typeid/#soa[]$E, length: int, alignment: int, alloc ti = type_info_base(ti) si := &ti.variant.(Type_Info_Struct) - field_count := uintptr(intrinsics.type_struct_field_count(E)) + field_count := uintptr(len(E) when intrinsics.type_is_array(E) else intrinsics.type_struct_field_count(E)) total_size := 0 for i in 0.. Allocator_Error { - when intrinsics.type_struct_field_count(E) != 0 { + field_count :: len(E) when intrinsics.type_is_array(E) else intrinsics.type_struct_field_count(E) + when field_count != 0 { array := array ptr := (^rawptr)(&array)^ free(ptr, allocator, loc) or_return @@ -399,7 +385,8 @@ delete_soa_slice :: proc(array: $T/#soa[]$E, allocator := context.allocator, loc } delete_soa_dynamic_array :: proc(array: $T/#soa[dynamic]$E, loc := #caller_location) -> Allocator_Error { - when intrinsics.type_struct_field_count(E) != 0 { + field_count :: len(E) when intrinsics.type_is_array(E) else intrinsics.type_struct_field_count(E) + when field_count != 0 { array := array ptr := (^rawptr)(&array)^ footer := raw_soa_footer(&array) @@ -417,7 +404,8 @@ delete_soa :: proc{ clear_soa_dynamic_array :: proc(array: ^$T/#soa[dynamic]$E) { - when intrinsics.type_struct_field_count(E) != 0 { + field_count :: len(E) when intrinsics.type_is_array(E) else intrinsics.type_struct_field_count(E) + when field_count != 0 { footer := raw_soa_footer(array) footer.len = 0 } @@ -439,12 +427,7 @@ into_dynamic_soa :: proc(array: $T/#soa[]$E) -> #soa[dynamic]E { allocator = nil_allocator(), } - field_count: uintptr - when intrinsics.type_is_array(E) { - field_count = len(E) - } else { - field_count = uintptr(intrinsics.type_struct_field_count(E)) - } + field_count := uintptr(len(E) when intrinsics.type_is_array(E) else intrinsics.type_struct_field_count(E)) array := array dynamic_data := ([^]rawptr)(&d)[:field_count] @@ -468,12 +451,7 @@ unordered_remove_soa :: proc(array: ^$T/#soa[dynamic]$E, index: int, loc := #cal ti = type_info_base(ti) si := &ti.variant.(Type_Info_Struct) - field_count: uintptr - when intrinsics.type_is_array(E) { - field_count = len(E) - } else { - field_count = uintptr(intrinsics.type_struct_field_count(E)) - } + field_count := uintptr(len(E) when intrinsics.type_is_array(E) else intrinsics.type_struct_field_count(E)) data := uintptr(array) for i in 0.. Date: Mon, 1 Jul 2024 11:34:50 +0100 Subject: [PATCH 121/129] Add support for `make(#soa[]T)` etc --- base/runtime/core_builtin.odin | 5 +++ src/check_expr.cpp | 79 +++++++++++++++++++++++++++++++++- 2 files changed, 82 insertions(+), 2 deletions(-) diff --git a/base/runtime/core_builtin.odin b/base/runtime/core_builtin.odin index 4601bca9d..a549ca2ae 100644 --- a/base/runtime/core_builtin.odin +++ b/base/runtime/core_builtin.odin @@ -364,6 +364,11 @@ make :: proc{ make_dynamic_array_len_cap, make_map, make_multi_pointer, + + make_soa_slice, + make_soa_dynamic_array, + make_soa_dynamic_array_len, + make_soa_dynamic_array_len_cap, } diff --git a/src/check_expr.cpp b/src/check_expr.cpp index e11014a70..c07a3b248 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -6800,9 +6800,71 @@ gb_internal CallArgumentData check_call_arguments_proc_group(CheckerContext *c, if (procs.count > 0) { error_line("Did you mean to use one of the following:\n"); } + + // Try to reduce the list further for `$T: typeid` like parameters + bool *possibly_ignore = gb_alloc_array(temporary_allocator(), bool, procs.count); + isize possibly_ignore_set = 0; + + if (true) { + // NOTE(bill): This currently only checks for #soa types + for_array(i, procs) { + Entity *proc = procs[i]; + Type *t = base_type(proc->type); + if (t->kind != Type_Proc) continue; + + TypeProc *pt = &t->Proc; + if (pt->param_count == 0) { + continue; + } + + for_array(j, pt->params->Tuple.variables) { + Entity *v = pt->params->Tuple.variables[j]; + if (v->kind != Entity_TypeName) { + continue; + } + + Type *dst_t = base_type(v->type); + while (dst_t->kind == Type_Generic && dst_t->Generic.specialized) { + dst_t = dst_t->Generic.specialized; + } + + if (j >= positional_operands.count) { + continue; + } + Operand const &o = positional_operands[j]; + if (o.mode != Addressing_Type) { + continue; + } + Type *t = base_type(o.type); + if (t->kind == dst_t->kind) { + continue; + } + Type *st = base_type(type_deref(o.type)); + Type *dt = base_type(type_deref(dst_t)); + if (st->kind == dt->kind) { + continue; + } + if (is_type_soa_struct(st)) { + possibly_ignore[i] = true; + possibly_ignore_set += 1; + continue; + } + } + } + } + + if (possibly_ignore_set == procs.count) { + possibly_ignore_set = 0; + } + + isize max_name_length = 0; isize max_type_length = 0; - for (Entity *proc : procs) { + for_array(i, procs) { + if (possibly_ignore_set != 0 && possibly_ignore[i]) { + continue; + } + Entity *proc = procs[i]; Type *t = base_type(proc->type); if (t == t_invalid) continue; String prefix = {}; @@ -6832,7 +6894,11 @@ gb_internal CallArgumentData check_call_arguments_proc_group(CheckerContext *c, } spaces[max_spaces] = 0; - for (Entity *proc : procs) { + for_array(i, procs) { + if (possibly_ignore_set != 0 && possibly_ignore[i]) { + continue; + } + Entity *proc = procs[i]; TokenPos pos = proc->token.pos; Type *t = base_type(proc->type); if (t == t_invalid) continue; @@ -11414,6 +11480,9 @@ gb_internal gbString write_expr_to_string(gbString str, Ast *node, bool shorthan case_end; case_ast_node(pt, PointerType, node); + if (pt->tag) { + str = write_expr_to_string(str, pt->tag, false); + } str = gb_string_append_rune(str, '^'); str = write_expr_to_string(str, pt->type, shorthand); case_end; @@ -11424,6 +11493,9 @@ gb_internal gbString write_expr_to_string(gbString str, Ast *node, bool shorthan case_end; case_ast_node(at, ArrayType, node); + if (at->tag) { + str = write_expr_to_string(str, at->tag, false); + } str = gb_string_append_rune(str, '['); if (at->count != nullptr && at->count->kind == Ast_UnaryExpr && @@ -11437,6 +11509,9 @@ gb_internal gbString write_expr_to_string(gbString str, Ast *node, bool shorthan case_end; case_ast_node(at, DynamicArrayType, node); + if (at->tag) { + str = write_expr_to_string(str, at->tag, false); + } str = gb_string_appendc(str, "[dynamic]"); str = write_expr_to_string(str, at->elem, shorthand); case_end; From 7f6fe918960b7d7e35f5a8c1e9986e35172ccdff Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 1 Jul 2024 11:37:21 +0100 Subject: [PATCH 122/129] Add #soa forms to reserve, clear, and resize --- base/runtime/core_builtin.odin | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/base/runtime/core_builtin.odin b/base/runtime/core_builtin.odin index a549ca2ae..6a9766fd0 100644 --- a/base/runtime/core_builtin.odin +++ b/base/runtime/core_builtin.odin @@ -163,18 +163,32 @@ pop_front_safe :: proc "contextless" (array: ^$T/[dynamic]$E) -> (res: E, ok: bo // `clear` will set the length of a passed dynamic array or map to `0` @builtin -clear :: proc{clear_dynamic_array, clear_map} +clear :: proc{ + clear_dynamic_array, + clear_map, + + clear_soa_dynamic_array, +} // `reserve` will try to reserve memory of a passed dynamic array or map to the requested element count (setting the `cap`). @builtin -reserve :: proc{reserve_dynamic_array, reserve_map} +reserve :: proc{ + reserve_dynamic_array, + reserve_map, + + reserve_soa, +} @builtin non_zero_reserve :: proc{non_zero_reserve_dynamic_array} // `resize` will try to resize memory of a passed dynamic array to the requested element count (setting the `len`, and possibly `cap`). @builtin -resize :: proc{resize_dynamic_array} +resize :: proc{ + resize_dynamic_array, + + resize_soa, +} @builtin non_zero_resize :: proc{non_zero_resize_dynamic_array} @@ -546,7 +560,12 @@ append_string :: proc(array: ^$T/[dynamic]$E/u8, args: ..string, loc := #caller_ } // The append built-in procedure appends elements to the end of a dynamic array -@builtin append :: proc{append_elem, append_elems, append_elem_string} +@builtin append :: proc{ + append_elem, + append_elems, + append_elem_string, +} + @builtin non_zero_append :: proc{non_zero_append_elem, non_zero_append_elems, non_zero_append_elem_string} From 3a4392818448eac5b374384d30d41e0f574b274b Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 1 Jul 2024 11:47:33 +0100 Subject: [PATCH 123/129] Add `#no_broadcast` to `append_soa` --- base/runtime/core_builtin_soa.odin | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/base/runtime/core_builtin_soa.odin b/base/runtime/core_builtin_soa.odin index 3ef41e32d..9b7fa3289 100644 --- a/base/runtime/core_builtin_soa.odin +++ b/base/runtime/core_builtin_soa.odin @@ -264,7 +264,7 @@ reserve_soa :: proc(array: ^$T/#soa[dynamic]$E, capacity: int, loc := #caller_lo } @builtin -append_soa_elem :: proc(array: ^$T/#soa[dynamic]$E, arg: E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { +append_soa_elem :: proc(array: ^$T/#soa[dynamic]$E, #no_broadcast arg: E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { if array == nil { return 0, nil } @@ -312,7 +312,7 @@ append_soa_elem :: proc(array: ^$T/#soa[dynamic]$E, arg: E, loc := #caller_locat } @builtin -append_soa_elems :: proc(array: ^$T/#soa[dynamic]$E, args: ..E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { +append_soa_elems :: proc(array: ^$T/#soa[dynamic]$E, #no_broadcast args: ..E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { if array == nil { return } From 4086a62167a6351a3cef32805abf1a7693bd16f7 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 1 Jul 2024 11:50:35 +0100 Subject: [PATCH 124/129] Fix showing error when not meant to --- src/check_expr.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/check_expr.cpp b/src/check_expr.cpp index c07a3b248..8880452e4 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -6168,7 +6168,9 @@ gb_internal CallArgumentError check_call_arguments_internal(CheckerContext *c, A Type *t = elem; if (is_type_polymorphic(t)) { - error(call, "Ambiguous call to a polymorphic variadic procedure with no variadic input %s", type_to_string(final_proc_type)); + if (show_error) { + error(call, "Ambiguous call to a polymorphic variadic procedure with no variadic input %s", type_to_string(final_proc_type)); + } err = CallArgumentError_AmbiguousPolymorphicVariadic; } From 8ddfcf174d5585f5f0b7c9ca25abeb6af28c107c Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 1 Jul 2024 11:51:28 +0100 Subject: [PATCH 125/129] Add `#soa` support to `append` directly --- base/runtime/core_builtin.odin | 3 +++ 1 file changed, 3 insertions(+) diff --git a/base/runtime/core_builtin.odin b/base/runtime/core_builtin.odin index 6a9766fd0..aceaea937 100644 --- a/base/runtime/core_builtin.odin +++ b/base/runtime/core_builtin.odin @@ -564,6 +564,9 @@ append_string :: proc(array: ^$T/[dynamic]$E/u8, args: ..string, loc := #caller_ append_elem, append_elems, append_elem_string, + + append_soa_elem, + append_soa_elems, } @builtin non_zero_append :: proc{non_zero_append_elem, non_zero_append_elems, non_zero_append_elem_string} From 942f3f52207e32f68a9342ba2693f3b37199937b Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 1 Jul 2024 12:04:29 +0100 Subject: [PATCH 126/129] Add `non_zero_*` variants for `#soa` dynamic array --- base/runtime/core_builtin.odin | 21 ++++++++++++-- base/runtime/core_builtin_soa.odin | 46 ++++++++++++++++++++++++++++-- 2 files changed, 61 insertions(+), 6 deletions(-) diff --git a/base/runtime/core_builtin.odin b/base/runtime/core_builtin.odin index aceaea937..ff87316f2 100644 --- a/base/runtime/core_builtin.odin +++ b/base/runtime/core_builtin.odin @@ -180,7 +180,11 @@ reserve :: proc{ } @builtin -non_zero_reserve :: proc{non_zero_reserve_dynamic_array} +non_zero_reserve :: proc{ + non_zero_reserve_dynamic_array, + + non_zero_reserve_soa, +} // `resize` will try to resize memory of a passed dynamic array to the requested element count (setting the `len`, and possibly `cap`). @builtin @@ -191,7 +195,11 @@ resize :: proc{ } @builtin -non_zero_resize :: proc{non_zero_resize_dynamic_array} +non_zero_resize :: proc{ + non_zero_resize_dynamic_array, + + non_zero_resize_soa, +} // Shrinks the capacity of a dynamic array or map down to the current length, or the given capacity. @builtin @@ -569,7 +577,14 @@ append_string :: proc(array: ^$T/[dynamic]$E/u8, args: ..string, loc := #caller_ append_soa_elems, } -@builtin non_zero_append :: proc{non_zero_append_elem, non_zero_append_elems, non_zero_append_elem_string} +@builtin non_zero_append :: proc{ + non_zero_append_elem, + non_zero_append_elems, + non_zero_append_elem_string, + + non_zero_append_soa_elem, + non_zero_append_soa_elems, +} @builtin diff --git a/base/runtime/core_builtin_soa.odin b/base/runtime/core_builtin_soa.odin index 9b7fa3289..f1b17cbef 100644 --- a/base/runtime/core_builtin_soa.odin +++ b/base/runtime/core_builtin_soa.odin @@ -182,8 +182,28 @@ resize_soa :: proc(array: ^$T/#soa[dynamic]$E, length: int, loc := #caller_locat return nil } +@builtin +non_zero_resize_soa :: proc(array: ^$T/#soa[dynamic]$E, length: int, loc := #caller_location) -> Allocator_Error { + if array == nil { + return nil + } + non_zero_reserve_soa(array, length, loc) or_return + footer := raw_soa_footer(array) + footer.len = length + return nil +} + @builtin reserve_soa :: proc(array: ^$T/#soa[dynamic]$E, capacity: int, loc := #caller_location) -> Allocator_Error { + return _reserve_soa(array, capacity, true, loc) +} + +@builtin +non_zero_reserve_soa :: proc(array: ^$T/#soa[dynamic]$E, capacity: int, loc := #caller_location) -> Allocator_Error { + return _reserve_soa(array, capacity, false, loc) +} + +_reserve_soa :: proc(array: ^$T/#soa[dynamic]$E, capacity: int, zero_memory: bool, loc := #caller_location) -> Allocator_Error { if array == nil { return nil } @@ -228,7 +248,7 @@ reserve_soa :: proc(array: ^$T/#soa[dynamic]$E, capacity: int, loc := #caller_lo old_data := (^rawptr)(array)^ new_bytes := array.allocator.procedure( - array.allocator.data, .Alloc, new_size, max_align, + array.allocator.data, .Alloc if zero_memory else .Alloc_Non_Zeroed, new_size, max_align, nil, old_size, loc, ) or_return new_data := raw_data(new_bytes) @@ -263,8 +283,18 @@ reserve_soa :: proc(array: ^$T/#soa[dynamic]$E, capacity: int, loc := #caller_lo return nil } + @builtin append_soa_elem :: proc(array: ^$T/#soa[dynamic]$E, #no_broadcast arg: E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { + return _append_soa_elem(array, true, arg, loc) +} + +@builtin +non_zero_append_soa_elem :: proc(array: ^$T/#soa[dynamic]$E, #no_broadcast arg: E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { + return _append_soa_elem(array, false, arg, loc) +} + +_append_soa_elem :: proc(array: ^$T/#soa[dynamic]$E, zero_memory: bool, #no_broadcast arg: E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { if array == nil { return 0, nil } @@ -272,7 +302,7 @@ append_soa_elem :: proc(array: ^$T/#soa[dynamic]$E, #no_broadcast arg: E, loc := if cap(array) <= len(array) + 1 { // Same behavior as append_soa_elems but there's only one arg, so we always just add DEFAULT_DYNAMIC_ARRAY_CAPACITY. cap := 2 * cap(array) + DEFAULT_DYNAMIC_ARRAY_CAPACITY - err = reserve_soa(array, cap, loc) // do not 'or_return' here as it could be a partial success + err = _reserve_soa(array, cap, zero_memory, loc) // do not 'or_return' here as it could be a partial success } footer := raw_soa_footer(array) @@ -313,6 +343,16 @@ append_soa_elem :: proc(array: ^$T/#soa[dynamic]$E, #no_broadcast arg: E, loc := @builtin append_soa_elems :: proc(array: ^$T/#soa[dynamic]$E, #no_broadcast args: ..E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { + return _append_soa_elems(array, true, args=args, loc=loc) +} + +@builtin +non_zero_append_soa_elems :: proc(array: ^$T/#soa[dynamic]$E, #no_broadcast args: ..E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { + return _append_soa_elems(array, false, args=args, loc=loc) +} + + +_append_soa_elems :: proc(array: ^$T/#soa[dynamic]$E, zero_memory: bool, #no_broadcast args: ..E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { if array == nil { return } @@ -324,7 +364,7 @@ append_soa_elems :: proc(array: ^$T/#soa[dynamic]$E, #no_broadcast args: ..E, lo if cap(array) <= len(array)+arg_len { cap := 2 * cap(array) + max(DEFAULT_DYNAMIC_ARRAY_CAPACITY, arg_len) - err = reserve_soa(array, cap, loc) // do not 'or_return' here as it could be a partial success + err = _reserve_soa(array, cap, zero_memory, loc) // do not 'or_return' here as it could be a partial success } arg_len = min(cap(array)-len(array), arg_len) From 544959326b467b6587a04d6211ea142de932109c Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 1 Jul 2024 12:13:35 +0100 Subject: [PATCH 127/129] Add `intrinsics.type_struct_has_implicit_padding` #3844 --- base/intrinsics/intrinsics.odin | 3 ++- src/check_builtin.cpp | 25 +++++++++++++++++++++++++ src/checker_builtin_procs.hpp | 4 +++- src/types.cpp | 1 + 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/base/intrinsics/intrinsics.odin b/base/intrinsics/intrinsics.odin index 635c85e6f..8a16ca40e 100644 --- a/base/intrinsics/intrinsics.odin +++ b/base/intrinsics/intrinsics.odin @@ -194,7 +194,8 @@ type_proc_return_count :: proc($T: typeid) -> int where type_is_proc(T) --- type_proc_parameter_type :: proc($T: typeid, index: int) -> typeid where type_is_proc(T) --- type_proc_return_type :: proc($T: typeid, index: int) -> typeid where type_is_proc(T) --- -type_struct_field_count :: proc($T: typeid) -> int where type_is_struct(T) --- +type_struct_field_count :: proc($T: typeid) -> int where type_is_struct(T) --- +type_struct_has_implicit_padding :: proc($T: typeid) -> bool where type_is_struct(T) --- type_polymorphic_record_parameter_count :: proc($T: typeid) -> typeid --- type_polymorphic_record_parameter_value :: proc($T: typeid, index: int) -> $V --- diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index c1422e80e..7a1a8b9ee 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -5839,6 +5839,31 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As operand->mode = Addressing_Constant; operand->type = t_untyped_integer; break; + case BuiltinProc_type_struct_has_implicit_padding: + operand->value = exact_value_bool(false); + if (operand->mode != Addressing_Type) { + error(operand->expr, "Expected a struct type for '%.*s'", LIT(builtin_name)); + } else if (!is_type_struct(operand->type) && !is_type_soa_struct(operand->type)) { + error(operand->expr, "Expected a struct type for '%.*s'", LIT(builtin_name)); + } else { + Type *bt = base_type(operand->type); + if (bt->Struct.is_packed) { + operand->value = exact_value_bool(false); + } else if (bt->Struct.fields.count != 0) { + i64 size = type_size_of(bt); + Type *field_type = nullptr; + i64 last_offset = type_offset_of(bt, bt->Struct.fields.count-1, &field_type); + if (last_offset+type_size_of(field_type) < size) { + operand->value = exact_value_bool(true); + } else { + i64 packed_size = type_size_of_struct_pretend_is_packed(bt); + operand->value = exact_value_bool(packed_size < size); + } + } + } + operand->mode = Addressing_Constant; + operand->type = t_untyped_bool; + break; case BuiltinProc_type_proc_parameter_count: operand->value = exact_value_i64(0); diff --git a/src/checker_builtin_procs.hpp b/src/checker_builtin_procs.hpp index a2b8a5361..a90c52e61 100644 --- a/src/checker_builtin_procs.hpp +++ b/src/checker_builtin_procs.hpp @@ -277,6 +277,7 @@ BuiltinProc__type_simple_boolean_end, BuiltinProc_type_bit_set_underlying_type, BuiltinProc_type_struct_field_count, + BuiltinProc_type_struct_has_implicit_padding, BuiltinProc_type_proc_parameter_count, BuiltinProc_type_proc_return_count, @@ -593,7 +594,8 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = { {STR_LIT("type_bit_set_elem_type"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_bit_set_underlying_type"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("type_struct_field_count"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("type_struct_field_count"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("type_struct_has_implicit_padding"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_proc_parameter_count"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_proc_return_count"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, diff --git a/src/types.cpp b/src/types.cpp index 323c06580..c3a5fb539 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -2366,6 +2366,7 @@ gb_internal bool type_has_nil(Type *t) { return false; } + gb_internal bool elem_type_can_be_constant(Type *t) { t = base_type(t); if (t == t_invalid) { From 42ff7111145e5264ce708edadd69b8c031106c97 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 1 Jul 2024 12:22:18 +0100 Subject: [PATCH 128/129] Fix #3515 --- src/check_expr.cpp | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 8880452e4..b6e5bc222 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -9123,12 +9123,16 @@ gb_internal ExprKind check_compound_literal(CheckerContext *c, Operand *o, Ast * type = nullptr; // [?]Type - if (type_expr->kind == Ast_ArrayType && type_expr->ArrayType.count != nullptr) { + if (type_expr->kind == Ast_ArrayType) { Ast *count = type_expr->ArrayType.count; - if (count->kind == Ast_UnaryExpr && - count->UnaryExpr.op.kind == Token_Question) { - type = alloc_type_array(check_type(c, type_expr->ArrayType.elem), -1); - is_to_be_determined_array_count = true; + if (count != nullptr) { + if (count->kind == Ast_UnaryExpr && + count->UnaryExpr.op.kind == Token_Question) { + type = alloc_type_array(check_type(c, type_expr->ArrayType.elem), -1); + is_to_be_determined_array_count = true; + } + } else { + type = alloc_type_slice(check_type(c, type_expr->ArrayType.elem)); } if (cl->elems.count > 0) { if (type_expr->ArrayType.tag != nullptr) { @@ -9141,8 +9145,7 @@ gb_internal ExprKind check_compound_literal(CheckerContext *c, Operand *o, Ast * } } } - } - if (type_expr->kind == Ast_DynamicArrayType && type_expr->DynamicArrayType.tag != nullptr) { + } else if (type_expr->kind == Ast_DynamicArrayType && type_expr->DynamicArrayType.tag != nullptr) { if (cl->elems.count > 0) { Ast *tag = type_expr->DynamicArrayType.tag; GB_ASSERT(tag->kind == Ast_BasicDirective); @@ -9181,6 +9184,12 @@ gb_internal ExprKind check_compound_literal(CheckerContext *c, Operand *o, Ast * if (cl->elems.count == 0) { break; // NOTE(bill): No need to init } + + if (t->Struct.soa_kind != StructSoa_None) { + error(node, "#soa arrays are not supported for compound literals"); + break; + } + if (t->Struct.is_raw_union) { if (cl->elems.count > 0) { // NOTE: unions cannot be constant From a2b23de0a72ad34f09d11c88fcee4062a54b554e Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 1 Jul 2024 12:24:46 +0100 Subject: [PATCH 129/129] Sanity check for a `nullptr` --- src/check_expr.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/check_expr.cpp b/src/check_expr.cpp index b6e5bc222..2d0b9dfa9 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -6812,7 +6812,9 @@ gb_internal CallArgumentData check_call_arguments_proc_group(CheckerContext *c, for_array(i, procs) { Entity *proc = procs[i]; Type *t = base_type(proc->type); - if (t->kind != Type_Proc) continue; + if (t == nullptr || t->kind != Type_Proc) { + continue; + } TypeProc *pt = &t->Proc; if (pt->param_count == 0) {