diff options
113 files changed, 6682 insertions, 2666 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0fdeab3..dd930d6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,92 @@ +2025-10-23 Andrew Pinski <andrew.pinski@oss.qualcomm.com> + + * match.pd (`(type1)x CMP CST1 ? (type2)x : CST2`): Better handling + of `((signed)x) < 0`. + +2025-10-23 Andrew Pinski <andrew.pinski@oss.qualcomm.com> + + PR tree-optimization/101024 + * tree-ssa-phiopt.cc (match_simplify_replacement): Special + case fp `a CMP b ? a : b` when not creating a min/max. + (strip_bit_not): Remove. + (invert_minmax_code): Remove. + (minmax_replacement): Remove. + (pass_phiopt::execute): Update pass comment. + Don't call minmax_replacement. + +2025-10-23 Andrew Pinski <andrew.pinski@oss.qualcomm.com> + + PR tree-optimization/101024 + * fold-const.cc (minmax_from_comparison): New version that takes widest_int + instead of tree. + (minmax_from_comparison): Call minmax_from_comparison for integer cst case. + * fold-const.h (minmax_from_comparison): New declaration. + * match.pd (`((signed)a </>= 0) ? min/max (a, c) : b`): New pattern. + +2025-10-23 Alfie Richards <alfie.richards@arm.com> + + * config/aarch64/aarch64-c.cc (aarch64_update_cpp_builtins): Add + __HAVE_FUNCTION_MULTI_VERSIONING macro. + +2025-10-23 Alfie Richards <alfie.richards@arm.com> + + * config/aarch64/aarch64.cc (dispatch_function_versions): Remove + unnecessary sorting and data structure. + +2025-10-23 Alfie Richards <alfie.richards@arm.com> + + PR target/122190 + * config/aarch64/aarch64.cc (compare_feature_masks): Fix version rules. + +2025-10-23 Alfie Richards <alfie.richards@arm.com> + + * config/aarch64/aarch64.cc (aarch64_generate_version_dispatcher_body): + Dump function versions and the ordering. + +2025-10-23 zhaozhou <zhaozhou@loongson.cn> + + * match.pd: Add new pattern for round. + +2025-10-23 Richard Biener <rguenther@suse.de> + + * tree-vectorizer.h (_loop_vec_info::slp_unrolling_factor): Remove. + (LOOP_VINFO_SLP_UNROLLING_FACTOR): Likewise. + * tree-vect-loop.cc (_loop_vec_info::_loop_vec_info): Adjust. + (vect_analyze_loop_2): Likewise. + * tree-vect-slp.cc (vect_make_slp_decision): Set + LOOP_VINFO_VECT_FACTOR directly. + +2025-10-23 Richard Biener <rguenther@suse.de> + + * tree-vect-loop.cc (vect_analyze_loop_2): Move vect_optimize_slp + after applying suggested_unroll_factor. + +2025-10-23 Richard Biener <rguenther@suse.de> + + * tree-vect-loop.cc (vect_analyze_loop_2): Deal with NULL + element in SLP_TREE_SCALAR_STMTS. + +2025-10-23 liuhongt <hongtao.liu@intel.com> + + PR target/101639 + * config/i386/sse.md + (VI_AVX): New mode iterator. + (VI_AVX_CMP): Ditto. + (ssebytemode): Add V16HI, V32QI, V16QI. + (reduc_sbool_and_scal_<mode>): New expander. + (reduc_sbool_ior_scal_<mode>): Ditto. + (reduc_sbool_xor_scal_<mode>): Ditto. + (*eq<mode>3_2_negate): New pre_reload splitter. + (*ptest<mode>_ccz): Ditto. + +2025-10-23 liuhongt <hongtao.liu@intel.com> + + PR target/101639 + * config/i386/sse.md + (reduc_sbool_and_scal_<mode>): New expander. + (reduc_sbool_ior_scal_<mode>): Ditto. + (reduc_sbool_xor_scal_<mode>): Ditto. + 2025-10-22 H.J. Lu <hjl.tools@gmail.com> * config/i386/i386-expand.cc (ix86_expand_set_or_cpymem): Use diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index b8ebc41..a234d9f 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20251023 +20251024 diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc index 56fb0be..0cf3f92 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -675,14 +675,15 @@ c_token_starts_typename (c_token *token) } } -/* Return true if the next token from PARSER can start a type name, - false otherwise. LA specifies how to do lookahead in order to +/* Return true if the next token from PARSER, starting from token N, can start + a type name, false otherwise. LA specifies how to do lookahead in order to detect unknown type names. If unsure, pick CLA_PREFER_ID. */ static inline bool -c_parser_next_tokens_start_typename (c_parser *parser, enum c_lookahead_kind la) +c_parser_next_tokens_start_typename (c_parser *parser, enum c_lookahead_kind la, + unsigned int n = 1) { - c_token *token = c_parser_peek_token (parser); + c_token *token = c_parser_peek_nth_token (parser, n); if (c_token_starts_typename (token)) return true; @@ -695,8 +696,8 @@ c_parser_next_tokens_start_typename (c_parser *parser, enum c_lookahead_kind la) && !parser->objc_could_be_foreach_context && (la == cla_prefer_type - || c_parser_peek_2nd_token (parser)->type == CPP_NAME - || c_parser_peek_2nd_token (parser)->type == CPP_MULT) + || c_parser_peek_nth_token (parser, n + 1)->type == CPP_NAME + || c_parser_peek_nth_token (parser, n + 1)->type == CPP_MULT) /* Only unknown identifiers. */ && !lookup_name (token->value)) @@ -892,30 +893,47 @@ c_parser_next_token_starts_declspecs (c_parser *parser) return c_token_starts_declspecs (token); } -/* Return true if the next tokens from PARSER can start declaration - specifiers (not including standard attributes) or a static - assertion, false otherwise. */ +static bool c_parser_check_balanced_raw_token_sequence (c_parser *, + unsigned int *); + +/* Return true if the next tokens from PARSER (starting with token N, 1-based) + can start declaration specifiers (not including standard attributes) or a + static assertion, false otherwise. */ bool -c_parser_next_tokens_start_declaration (c_parser *parser) +c_parser_next_tokens_start_declaration (c_parser *parser, unsigned int n) { - c_token *token = c_parser_peek_token (parser); + c_token *token = c_parser_peek_nth_token (parser, n); /* Same as above. */ if (c_dialect_objc () && token->type == CPP_NAME && token->id_kind == C_ID_CLASSNAME - && c_parser_peek_2nd_token (parser)->type == CPP_DOT) + && c_parser_peek_nth_token (parser, n + 1)->type == CPP_DOT) return false; /* Labels do not start declarations. */ if (token->type == CPP_NAME - && c_parser_peek_2nd_token (parser)->type == CPP_COLON) + && c_parser_peek_nth_token (parser, n + 1)->type == CPP_COLON) return false; + /* A static assertion is only a declaration if followed by a semicolon; + otherwise, it may be an expression in C2Y. */ + if (token->keyword == RID_STATIC_ASSERT + && c_parser_peek_nth_token (parser, n + 1)->type == CPP_OPEN_PAREN) + { + n += 2; + if (!c_parser_check_balanced_raw_token_sequence (parser, &n) + || c_parser_peek_nth_token_raw (parser, n)->type != CPP_CLOSE_PAREN) + /* Invalid static assertion syntax; treat as a declaration and report a + syntax error there. */ + return true; + return c_parser_peek_nth_token_raw (parser, n + 1)->type == CPP_SEMICOLON; + } + if (c_token_starts_declaration (token)) return true; - if (c_parser_next_tokens_start_typename (parser, cla_nonabstract_decl)) + if (c_parser_next_tokens_start_typename (parser, cla_nonabstract_decl, n)) return true; return false; @@ -5855,9 +5873,6 @@ c_parser_balanced_token_sequence (c_parser *parser) } } -static bool c_parser_check_balanced_raw_token_sequence (c_parser *, - unsigned int *); - /* Parse arguments of omp::directive or omp::decl attribute. directive-name ,[opt] clause-list[opt] @@ -7724,7 +7739,7 @@ c_parser_compound_statement_nostart (c_parser *parser) == RID_EXTENSION)) c_parser_consume_token (parser); if (!have_std_attrs - && (c_token_starts_declaration (c_parser_peek_2nd_token (parser)) + && (c_parser_next_tokens_start_declaration (parser, 2) || c_parser_nth_token_starts_std_attributes (parser, 2))) { int ext; @@ -9132,7 +9147,7 @@ c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll, && (c_parser_peek_2nd_token (parser)->keyword == RID_EXTENSION)) c_parser_consume_token (parser); - if (c_token_starts_declaration (c_parser_peek_2nd_token (parser)) + if (c_parser_next_tokens_start_declaration (parser, 2) || c_parser_nth_token_starts_std_attributes (parser, 2)) { int ext; @@ -10513,8 +10528,9 @@ c_parser_cast_expression (c_parser *parser, struct c_expr *after) _Countof ( type-name ) sizeof unary-expression sizeof ( type-name ) + static-assert-declaration-no-semi - (_Countof is new in C2y.) + (_Countof and the use of static assertions in expressions are new in C2y.) unary-operator: one of & * + - ~ ! @@ -10679,6 +10695,15 @@ c_parser_unary_expression (c_parser *parser) case RID_TRANSACTION_RELAXED: return c_parser_transaction_expression (parser, c_parser_peek_token (parser)->keyword); + case RID_STATIC_ASSERT: + c_parser_static_assert_declaration_no_semi (parser); + pedwarn_c23 (op_loc, OPT_Wpedantic, + "ISO C does not support static assertions in " + "expressions before C2Y"); + ret.value = void_node; + set_c_expr_source_range (&ret, op_loc, op_loc); + ret.m_decimal = 0; + return ret; default: return c_parser_postfix_expression (parser); } diff --git a/gcc/c/c-parser.h b/gcc/c/c-parser.h index a84779b..46713d7 100644 --- a/gcc/c/c-parser.h +++ b/gcc/c/c-parser.h @@ -156,7 +156,8 @@ extern void c_parser_skip_until_found (c_parser *parser, enum cpp_ttype type, const char *msgid, location_t = UNKNOWN_LOCATION); extern bool c_parser_next_token_starts_declspecs (c_parser *parser); -bool c_parser_next_tokens_start_declaration (c_parser *parser); +bool c_parser_next_tokens_start_declaration (c_parser *parser, + unsigned int n = 1); bool c_token_starts_typename (c_token *token); /* Abstraction to avoid defining c_parser here which messes up gengtype diff --git a/gcc/cobol/ChangeLog b/gcc/cobol/ChangeLog index 8a0a3db..e1595a0 100644 --- a/gcc/cobol/ChangeLog +++ b/gcc/cobol/ChangeLog @@ -1,3 +1,78 @@ +2025-10-23 Robert Dubner <rdubner@symas.com> + + * genapi.cc (parser_alphabet): Alphabet encoding. + (parser_alphabet_use): Likewise. + (parser_xml_parse): Use correct debugging macro; encoding. + (parser_xml_on_exception): Likewise. + (parser_xml_not_exception): Likewise. + (parser_xml_end): Likewise. + (initialize_the_data): Encoding. + (parser_label_label): Debugging macros. + (parser_label_goto): Likewise. + (parser_file_add): Encoding. + (parser_intrinsic_call_1): Special handling for __gg__char. + (parser_intrinsic_call_2): Formatting. + * parse.y: Response from FUNCTION ORD is flagged "unsigned". + * symbols.cc (cbl_alphabet_t::reencode): Establish + low_char & high_char. + * symbols.h (struct cbl_alphabet_t): Likewise. + +2025-10-23 Robert Dubner <rdubner@symas.com> + James K. Lowden <jklowden@cobolworx.com> + + * Make-lang.in: Incorporate new token_names.h file. + * cdf.y: Modify tokens. + * gcobol.1: Document XML PARSE statement + * genapi.cc (parser_enter_program): Verify that every goto has a + matching label. + (parser_end_program): Likewise. + (parser_alphabet): Refine handling codeset encodings. + (parser_alphabet_use): Likewise. + (label_fetch): Moved from later in the source code. + (parser_xml_parse): New routine for XML PARSE. + (parser_xml_on_exception): Likewise. + (parser_xml_not_exception): Likewise. + (parser_xml_end): Likewise. + (parser_label_label): Verify goto/label matching. + (parser_label_goto): Likewise. + (parser_entry): Minor change to SHOW_PARSE report. + * genapi.h (parser_alphabet): Set parameter to const. + (parser_xml_parse): Declare new function. + (parser_xml_on_exception): Likewise. + (parser_xml_not_exception): Likewise. + (parser_xml_end): Likewise. + (parser_label_addr): Likewise. + * parse.y: label_pair_t structure; locale processing; new token + processing for alphabets and XML PARSE. + * parse_ante.h (name_of): Return field->name when initial is NULL. + (new_tempnumeric): Make signable_e optional. + (ast_save_locale): New function. + (data_division_ready): Warning for "no alphabet". + * scan.l: Repair interpretation of BINARY, COMP, COMP-4, and + COMP-5. + * scan_ante.h (struct bint_t): Likewise. + * scan_post.h (current_tokens_t::tokenset_t::tokenset_t): + Include token_names.h. + * symbols.cc (symbols_alphabet_set): Revert to prior alphabet + determination. + (symbol_table_init): New XML special registers. + (new_temporary): Make signable_e controllable, not fixed. + * symbols.h (__gg__encoding_iconv_valid): New declaration. + (enum cbl_label_type_t): New LblXml label type. + (struct cbl_xml_parse_t): + (struct cbl_label_t): Implement XML PARSE. + (new_temporary): Incorporate boolean for signable_e. + (symbol_elem_of): Change label field type handling. + (cbl_section_of): Likewise. + (cbl_field_of): Likewise. + (cbl_label_of): Likewise. + (cbl_special_name_of): Likewise. + (cbl_alphabet_of): Likewise. + (cbl_file_of): Likewise. + * token_names.h: New file. + * util.cc (gcc_location_set_impl): Improve location_t calculations + when entering and leaving COPYBOOKs. + 2025-10-19 Robert Dubner <rdubner@symas.com> * genapi.cc (move_tree): Formatting. diff --git a/gcc/cobol/Make-lang.in b/gcc/cobol/Make-lang.in index 0e2a773..1f9995f 100644 --- a/gcc/cobol/Make-lang.in +++ b/gcc/cobol/Make-lang.in @@ -225,6 +225,7 @@ cobol/scan.o: cobol/scan.cc \ $(srcdir)/cobol/scan_post.h \ $(srcdir)/cobol/symbols.h \ $(srcdir)/cobol/util.h \ + $(srcdir)/cobol/token_names.h \ $(srcdir)/hwint.h \ $(srcdir)/system.h \ $(srcdir)/../include/ansidecl.h \ @@ -241,6 +242,15 @@ cobol/scan.o: cobol/scan.cc \ cobol/cdf.cc \ cobol/parse.cc +# Update token names if the generator script is installed +# (by a developer) and there's been a change. +$(srcdir)/cobol/token_names.h: cobol/parse.cc + if [ -f $@.gen ]; then \ + $@.gen $(subst .cc,.h,$^) \ + | diff -u $@ - \ + | patch -t --set-time $@ ; \ + fi + # # The src<foo> targets are executed if # ‘--enable-generated-files-in-srcdir’ was specified as a configure diff --git a/gcc/cobol/cdf.y b/gcc/cobol/cdf.y index f01c8f6..f72ed77 100644 --- a/gcc/cobol/cdf.y +++ b/gcc/cobol/cdf.y @@ -244,21 +244,21 @@ apply_cdf_turn( const exception_turn_t& turn ) { %type <boolean> DEFINED %token OTHER 699 PARAMETER_kw 369 "PARAMETER" %token OFF 688 OVERRIDE 370 -%token THRU 952 -%token TRUE_kw 815 "True" +%token THRU 949 +%token TRUE_kw 814 "True" %token CALL_COBOL 393 "CALL" %token CALL_VERBATIM 394 "CALL (as C)" -%token TURN 817 CHECKING 497 LOCATION 650 ON 690 WITH 844 +%token TURN 816 CHECKING 497 LOCATION 650 ON 690 WITH 843 -%left OR 953 -%left AND 954 -%right NOT 955 -%left '<' '>' '=' NE 956 LE 957 GE 958 +%left OR 950 +%left AND 951 +%right NOT 952 +%left '<' '>' '=' NE 953 LE 954 GE 955 %left '-' '+' %left '*' '/' -%right NEG 960 +%right NEG 957 %define api.prefix {ydf} %define api.token.prefix{YDF_} diff --git a/gcc/cobol/gcobol.1 b/gcc/cobol/gcobol.1 index 9ea9bfd..0de86df 100644 --- a/gcc/cobol/gcobol.1 +++ b/gcc/cobol/gcobol.1 @@ -778,6 +778,30 @@ resolution of .Ar filename is deferred until runtime, when the name must appear in the program's environment. +.Ss XML PARSE +.Nm +emulates the IBM +.Sy "XML PARSE" +statement. The following values for +.Sy XML-EVENT +are defined: +.Bl -tag -compact +.It Sy COMMENT +Text of a comment between "<!--" and "-->" +.It Sy CONTENT-CHARACTERS +Some or all of the character content of the element between start and end tags. +.It Sy END-OF-ELEMENT +End-element tag, with name if present in the input. +.It Sy PROCESSING-INSTRUCTION-DATA +Processing instruction (after the target name), excluding "?>". +.It Sy PROCESSING-INSTRUCTION-TARGET +The processing instruction target name appears in +.Sy XML-TEXT +or +.Sy XML-NTEXT . +.It Sy START-OF-ELEMENT +Name of the start element tag or empty element tag. +.El . .Sh ISO \*[lang] Implementation Status .Ss USAGE Data Types @@ -1480,6 +1504,18 @@ error. This feature is meant to help diagnose mysterious copybook errors. .El . +.Ss Variables for Developers +.Bl -tag -compact +.It Ev GCOBOL_SHOW +produces a trace of the internal calls made by the parser to prepare +the GENERIC tree. +.It Ev GCOBOL_TRACE +used at compile time, produces an executable that traces the +execution, mapping it back the same code-creation functions as +.Ev GCOBOL_SHOW , +as well as the values of data items and branch conditions. +.El +. .Sh FILES Executables produced by .Nm diff --git a/gcc/cobol/genapi.cc b/gcc/cobol/genapi.cc index 6fc4770..9d30dde 100644 --- a/gcc/cobol/genapi.cc +++ b/gcc/cobol/genapi.cc @@ -3988,6 +3988,37 @@ parser_enter_program( const char *funcname_, free(funcname); } +static class label_verify_t { + std::set<size_t> lain, dangling; + static inline size_t index_of( const cbl_label_t *label ) { + return symbol_index(symbol_elem_of(label)); + } +public: + void go_to( const cbl_label_t *label ) { + auto p = lain.find(index_of(label)); + if( p == lain.end() ) { + dangling.insert(index_of(label)); + } + } + bool lay( const cbl_label_t *label ) { + auto ok = lain.insert(index_of(label)); + if( ok.second ) { + dangling.erase(index_of(label)); + } + return true; + } + bool vet() const { // be always agreeable, for now. + return dangling.empty(); + } + void dump() const { + fprintf(stderr, "%u nonexistent labels called\n", unsigned(dangling.size()) ); + for( auto sym : dangling ) { + const cbl_label_t *label = cbl_label_of(symbol_at(sym)); + fprintf(stderr, "\t %s\n", label->name); + } + } +} label_verify; + void parser_end_program(const char *prog_name ) { @@ -4014,6 +4045,13 @@ parser_end_program(const char *prog_name ) TRACE1_END } + if( ! label_verify.vet() ) + { + label_verify.dump(); + gcc_unreachable(); + } + + if( gg_trans_unit.function_stack.size() ) { // The body has been created by various parser calls. It's time @@ -5035,7 +5073,7 @@ parser_accept_date_hhmmssff( struct cbl_field_t *target ) */ void -parser_alphabet( cbl_alphabet_t& alphabet ) +parser_alphabet( const cbl_alphabet_t& alphabet ) { Analyze(); SHOW_PARSE @@ -5046,6 +5084,9 @@ parser_alphabet( cbl_alphabet_t& alphabet ) free(psz); switch(alphabet.encoding) { + case iconv_CP1252_e: + psz = xasprintf("CP1252"); + break; case ASCII_e: psz = xasprintf("ASCII"); break; @@ -5074,6 +5115,7 @@ parser_alphabet( cbl_alphabet_t& alphabet ) switch(alphabet.encoding) { + case iconv_CP1252_e: case ASCII_e: case iso646_e: case EBCDIC_e: @@ -5082,6 +5124,7 @@ parser_alphabet( cbl_alphabet_t& alphabet ) case custom_encoding_e: { +#pragma message "Use program-id to disambiguate" size_t alphabet_index = symbol_index(symbol_elem_of(&alphabet)); unsigned char ach[256]; @@ -5097,23 +5140,28 @@ parser_alphabet( cbl_alphabet_t& alphabet ) gg_assign( gg_array_value(table256, ch), build_int_cst_type(UCHAR, (alphabet.alphabet[i])) ); } + + unsigned int low_char = alphabet.low_char; + unsigned int high_char = alphabet.high_char; __gg__alphabet_create(alphabet.encoding, alphabet_index, ach, - alphabet.low_index, - alphabet.high_index); + low_char, + high_char); gg_call(VOID, "__gg__alphabet_create", build_int_cst_type(INT, alphabet.encoding), build_int_cst_type(SIZE_T, alphabet_index), gg_get_address_of(table256), - build_int_cst_type(INT, alphabet.low_index), - build_int_cst_type(INT, alphabet.high_index), - + build_int_cst_type(INT, low_char), + build_int_cst_type(INT, high_char), NULL_TREE ); break; } default: + fprintf(stderr, "%s: Program ID %s:\n", + cobol_filename(), + cbl_label_of(symbol_at(current_program_index()))->name); gcc_unreachable(); } } @@ -5130,6 +5178,9 @@ parser_alphabet_use( cbl_alphabet_t& alphabet ) free(psz); switch(alphabet.encoding) { + case iconv_CP1252_e: + psz = xasprintf("CP1252"); + break; case ASCII_e: psz = xasprintf("ASCII"); break; @@ -5159,6 +5210,7 @@ parser_alphabet_use( cbl_alphabet_t& alphabet ) { default: gcc_unreachable(); + case iconv_CP1252_e: case ASCII_e: case iso646_e: case EBCDIC_e: @@ -5167,7 +5219,8 @@ parser_alphabet_use( cbl_alphabet_t& alphabet ) __gg__high_value_character = DEGENERATE_HIGH_VALUE; gg_call(VOID, "__gg__alphabet_use", - build_int_cst_type(INT, current_encoding(encoding_display_e)), + build_int_cst_type(INT, current_encoding(display_encoding_e)), + build_int_cst_type(INT, current_encoding(national_encoding_e)), build_int_cst_type(INT, alphabet.encoding), null_pointer_node, NULL_TREE); @@ -5183,7 +5236,8 @@ parser_alphabet_use( cbl_alphabet_t& alphabet ) gg_call(VOID, "__gg__alphabet_use", - build_int_cst_type(INT, current_encoding(encoding_display_e)), + build_int_cst_type(INT, current_encoding(display_encoding_e)), + build_int_cst_type(INT, current_encoding(national_encoding_e)), build_int_cst_type(INT, alphabet.encoding), build_int_cst_type(SIZE_T, alphabet_index), NULL_TREE); @@ -6802,6 +6856,160 @@ parser_free( size_t n, cbl_refer_t refers[] ) } } +static +cbl_label_addresses_t * +label_fetch(struct cbl_label_t *label) + { + if( !label->structs.goto_trees ) + { + label->structs.goto_trees + = static_cast<cbl_label_addresses_t *> + (xmalloc(sizeof(struct cbl_label_addresses_t))); + gcc_assert(label->structs.goto_trees); + + gg_create_goto_pair(&label->structs.goto_trees->go_to, + &label->structs.goto_trees->label); + } + return label->structs.goto_trees; + } + +void +parser_xml_parse( cbl_label_t *instance, + cbl_refer_t input, + cbl_field_t *encoding, + cbl_field_t *validating, + bool returns_national, + cbl_label_t *from_proc, + cbl_label_t *to_proc ) + { + SHOW_PARSE + { + SHOW_PARSE_HEADER + SHOW_PARSE_LABEL_OK("", instance) + SHOW_PARSE_REF(" ", input) + SHOW_PARSE_END + } + + TRACE1 + { + TRACE1_HEADER + TRACE1_END + } + + // We know that this routine comes first in the sequence, so we can + // create the goto/label pairs here: + + instance->structs.xml_parse = static_cast<struct cbl_xml_parse_t *> + (xmalloc(sizeof(struct cbl_xml_parse_t))); + gcc_assert(instance->structs.xml_parse); + + gg_create_goto_pair(&instance->structs.xml_parse->over.go_to, + &instance->structs.xml_parse->over.label); + gg_create_goto_pair(&instance->structs.xml_parse->exception.go_to, + &instance->structs.xml_parse->exception.label); + gg_create_goto_pair(&instance->structs.xml_parse->no_exception.go_to, + &instance->structs.xml_parse->no_exception.label); + + // We need to create a COBOL ENTRY point into this function. That entry + // point will be used by __gg__xml_parse to perform from_proc through to_proc + // as part of processing the libxml2 callbacks. + + char ach[64]; + static int instance_counter = 1; + sprintf(ach, + "_%s_xml_callback_%d", + current_function->our_name, + instance_counter++); + + cbl_field_t for_entry = {}; + for_entry.type = FldAlphanumeric; + for_entry.data.capacity = strlen(ach); + for_entry.data.initial = ach; + for_entry.codeset.encoding = iconv_CP1252_e; + + // build an island for the callback: + tree island_goto; + tree island_label; + gg_create_goto_pair(&island_goto, + &island_label); + + gg_append_statement(island_goto); + // This creates the separate _xml_callback function + parser_entry(&for_entry, 0, nullptr); + // When invoked, the callback performs the processing procedures + parser_perform(from_proc, to_proc); + // And then returns back to the caller + gg_return(0); + gg_append_statement(island_label); + + // With the callback in place, we are ready to call the library: + tree pcallback = gg_get_function_address(VOID, ach); + + tree erc = gg_define_int(); + gg_assign(erc, gg_call_expr(INT, + "__gg__xml_parse", + gg_get_address_of(input.field->var_decl_node), + refer_offset(input), + refer_size_source(input), + encoding ? + gg_get_address_of(encoding->var_decl_node) + : null_pointer_node, + validating ? + gg_get_address_of(validating->var_decl_node) + : null_pointer_node, + build_int_cst_type(INT, returns_national), + pcallback, + NULL_TREE)); + IF( erc, ne_op, integer_zero_node ) + { + //gg_printf("__gg__xml_parse() failed with erc %d\n", erc, NULL_TREE); + gg_append_statement(instance->structs.xml_parse->exception.go_to); + } + ELSE + { + //gg_printf("__gg__xml_parse() apparently succeeded\n", NULL_TREE); + gg_append_statement(instance->structs.xml_parse->no_exception.go_to); + } + ENDIF + } + +void +parser_xml_on_exception( cbl_label_t *instance ) + { + SHOW_PARSE + { + SHOW_PARSE_HEADER + SHOW_PARSE_LABEL_OK(" ", instance) + SHOW_PARSE_END + } + gg_append_statement(instance->structs.xml_parse->over.go_to); + gg_append_statement(instance->structs.xml_parse->exception.label); + } + +void +parser_xml_not_exception( cbl_label_t *instance ) +{ + SHOW_PARSE + { + SHOW_PARSE_HEADER + SHOW_PARSE_LABEL_OK(" ", instance) + SHOW_PARSE_END + } + gg_append_statement(instance->structs.xml_parse->over.go_to); + gg_append_statement(instance->structs.xml_parse->no_exception.label); + } + +void parser_xml_end( cbl_label_t *instance ) + { + SHOW_PARSE + { + SHOW_PARSE_HEADER + SHOW_PARSE_LABEL_OK(" ", instance) + SHOW_PARSE_END + } + gg_append_statement(instance->structs.xml_parse->over.label); + } + void parser_arith_error(cbl_label_t *arithmetic_label) { @@ -6933,7 +7141,8 @@ initialize_the_data() // This is one-time initialization of the libgcobol program state stack gg_call(VOID, "__gg__init_program_state", - build_int_cst_type(INT, current_encoding(encoding_display_e)), + build_int_cst_type(INT, current_encoding(display_encoding_e)), + build_int_cst_type(INT, current_encoding(national_encoding_e)), NULL_TREE); __gg__currency_signs = __gg__ct_currency_signs; @@ -7962,23 +8171,6 @@ parser_see_stop_run(struct cbl_refer_t exit_status, gg_exit(returned_value); } -static -cbl_label_addresses_t * -label_fetch(struct cbl_label_t *label) - { - if( !label->structs.goto_trees ) - { - label->structs.goto_trees - = static_cast<cbl_label_addresses_t *> - (xmalloc(sizeof(struct cbl_label_addresses_t))); - gcc_assert(label->structs.goto_trees); - - gg_create_goto_pair(&label->structs.goto_trees->go_to, - &label->structs.goto_trees->label); - } - return label->structs.goto_trees; - } - void parser_label_label(struct cbl_label_t *label) { @@ -8009,6 +8201,18 @@ parser_label_label(struct cbl_label_t *label) } CHECK_LABEL(label); + +#if 1 + // At the present time, label_verify.lay is returning true, so I edited + // out the if( !... ) to quiet cppcheck + label_verify.lay(label); +#else + if( ! label_verify.lay(label) ) + { + yywarn("%s: label %qs already exists", __func__, label->name); + gcc_unreachable(); + } +#endif if(strcmp(label->name, "_end_declaratives") == 0 ) { @@ -8048,6 +8252,10 @@ parser_label_goto(struct cbl_label_t *label) } CHECK_LABEL(label); + + label_verify.go_to(label); + + label_verify.go_to(label); if( strcmp(label->name, "_end_declaratives") == 0 ) { @@ -9682,6 +9890,7 @@ parser_file_add(struct cbl_file_t *file) __func__); } +#pragma message "Use program-id to disambiguate" size_t symbol_table_index = symbol_index(symbol_elem_of(file)); gg_call(VOID, @@ -9708,7 +9917,7 @@ parser_file_add(struct cbl_file_t *file) /* Right now, file->codeset.encoding is not being set properly. Remove this comment and fix the following code when that's repaired. */ // build_int_cst_type(INT, (int)file->codeset.encoding), - build_int_cst_type(INT, current_encoding(encoding_display_e)), + build_int_cst_type(INT, current_encoding(display_encoding_e)), build_int_cst_type(INT, (int)file->codeset.alphabet), NULL_TREE); file->var_decl_node = new_var_decl; @@ -11138,6 +11347,16 @@ parser_intrinsic_call_1( cbl_field_t *tgt, } } } + else if( strcmp(function_name, "__gg__char") == 0 ) + { + gg_call(VOID, + function_name, + gg_get_address_of(tgt->var_decl_node), + gg_get_address_of(ref1.field->var_decl_node), + refer_offset(ref1), + refer_size_source(ref1), + NULL_TREE); + } else { TRACE1 @@ -11192,13 +11411,15 @@ parser_intrinsic_call_2( cbl_field_t *tgt, TRACE1_REFER("parameter 2: ", ref2, "") } store_location_stuff(function_name); + gg_call(VOID, function_name, gg_get_address_of(tgt->var_decl_node), gg_get_address_of(ref1.field->var_decl_node), refer_offset(ref1), refer_size_source(ref1), - ref2.field ? gg_get_address_of(ref2.field->var_decl_node) : null_pointer_node, + ref2.field ? gg_get_address_of(ref2.field->var_decl_node) + : null_pointer_node, refer_offset(ref2), refer_size_source(ref2), NULL_TREE); @@ -13525,7 +13746,8 @@ parser_entry( const cbl_field_t *name, size_t nusing, cbl_ffi_arg_t *args ) SHOW_PARSE { SHOW_PARSE_HEADER - SHOW_PARSE_FIELD( " ENTRY ", name) + SHOW_PARSE_TEXT(" ") + SHOW_PARSE_TEXT(name->data.initial) SHOW_PARSE_END } diff --git a/gcc/cobol/genapi.h b/gcc/cobol/genapi.h index 1aafc65..6582d2e 100644 --- a/gcc/cobol/genapi.h +++ b/gcc/cobol/genapi.h @@ -81,7 +81,7 @@ void parser_accept_date_dow( cbl_field_t *tgt ); void parser_accept_date_hhmmssff( cbl_field_t *tgt ); void -parser_alphabet( cbl_alphabet_t& alphabet ); +parser_alphabet( const cbl_alphabet_t& alphabet ); void parser_alphabet_use( cbl_alphabet_t& alphabet ); @@ -90,6 +90,18 @@ parser_allocate( cbl_refer_t size_or_based, cbl_refer_t returning, bool initiali void parser_free( size_t n, cbl_refer_t refers[] ); +void parser_xml_parse( cbl_label_t *stmt, + cbl_refer_t input, + cbl_field_t *encoding, + cbl_field_t *validating, + bool returns_national, + cbl_label_t *from_proc, + cbl_label_t *to_proc ); + +void parser_xml_on_exception( cbl_label_t *name ); +void parser_xml_not_exception( cbl_label_t *name ); +void parser_xml_end( cbl_label_t *name ); + void parser_add( size_t nC, cbl_num_result_t *C, size_t nA, cbl_refer_t *A, @@ -322,6 +334,9 @@ parser_label_label( struct cbl_label_t *label ); void parser_label_goto( struct cbl_label_t *label ); +callback_t * +parser_label_addr( struct cbl_label_t *label ); + void parser_goto( cbl_refer_t value, size_t narg, cbl_label_t * const labels[] ); diff --git a/gcc/cobol/parse.y b/gcc/cobol/parse.y index c497b8f..9187a59 100644 --- a/gcc/cobol/parse.y +++ b/gcc/cobol/parse.y @@ -55,6 +55,41 @@ const char *alpha, *national; }; + struct label_pair_t { + cbl_label_t *from, *to; + }; + +class locale_tgt_t { + char user_system_default; + std::vector<int> categories; + public: + locale_tgt_t() : user_system_default('\0') {} + locale_tgt_t( int category ) + : user_system_default('\0') + , categories(1, category) + {} + locale_tgt_t operator=( int ch ) { + assert(categories.empty()); + switch(ch) { + case 'S': case 'U': + user_system_default = ch; + return *this; + } + gcc_unreachable(); + } + locale_tgt_t push_back( int token ) { + categories.push_back(token); + return *this; + } + + bool is_default() const { return 0 < user_system_default; } + char default_of() const { + assert(categories.empty()); + return user_system_default; + } + const std::vector<int>& lc_categories() const { return categories; } +}; + class literal_t { size_t isym; public: @@ -65,9 +100,7 @@ bool empty() const { return data == NULL; } size_t isymbol() const { return isym; } - const char * symbol_name() const { - return isym? cbl_field_of(symbol_at(isym))->name : ""; - } + const char * symbol_name() const; literal_t& set( size_t len, char *data, const char prefix[] ) { @@ -76,17 +109,8 @@ return *this; } - literal_t& - set( const cbl_field_t * field ) { - assert(field->has_attr(constant_e)); - assert(is_literal(field)); - - set_prefix( "", 0 ); - set_data( field->data.capacity, - const_cast<char*>(field->data.initial), - field_index(field) ); - return *this; - } + literal_t& set( const cbl_field_t * field ); + literal_t& set_data( size_t len, char *data, size_t isym = 0 ) { this->isym = isym; @@ -99,36 +123,8 @@ } return *this; } - literal_t& - set_prefix( const char *input, size_t len ) { - encoding = current_encoding('A'); - assert(len < sizeof(prefix)); - std::fill(prefix, prefix + sizeof(prefix), '\0'); - std::transform(input, input + len, prefix, toupper); - switch(prefix[0]) { - case '\0': case 'Z': - encoding = current_encoding('A'); - break; - case 'N': - encoding = current_encoding('N'); - if( 'X' == prefix[1] ) { - cbl_unimplemented("NX literals"); - } - break; - case 'G': - cbl_unimplemented("DBCS encoding not supported"); - break; - case 'U': - encoding = UTF8_e; - break; - case 'X': - break; - default: - gcc_unreachable(); - } - assert(encoding <= iconv_YU_e); - return *this; - } + literal_t& set_prefix( const char *input, size_t len ); + bool compatible_prefix( const literal_t& that ) const { if( prefix[0] != that.prefix[0] ) { @@ -456,7 +452,7 @@ CF CH CHANGED CHAR CHAR_NATIONAL "CHAR-NATIONAL" CHARACTER CHARACTERS CHECKING CLASS - COBOL CODE CODESET COLLATING + COBOL CODE CODESET "CODE-SET" COLLATING COLUMN COMBINED_DATETIME "COMBINED-DATETIME" COMMA COMMAND_LINE "COMMAND-LINE" COMMAND_LINE_COUNT "COMMAND-LINE-COUNT" @@ -524,7 +520,7 @@ INTEGER_OF_DAY "INTEGER-OF-DAY" INTEGER_OF_FORMATTED_DATE "INTEGER-OF-FORMATTED-DATE" INTEGER_PART "INTEGER-PART" - INTO INTRINSIC INVOKE IO IO_CONTROL "IO-CONTROL" + INTO INTRINSIC INVOKE IO "I-O" IO_CONTROL "I-O-CONTROL" IS ISNT "IS NOT" KANJI KEY @@ -600,7 +596,7 @@ STATUS STRONG SUBSTITUTE SUM SYMBOL SYMBOLIC SYNCHRONIZED - TALLY TALLYING TAN TERMINATE TEST + TALLYING TAN TERMINATE TEST TEST_DATE_YYYYMMDD "TEST-DATE-YYYYMMDD" TEST_DAY_YYYYDDD "TEST-DAY-YYYYDDD" TEST_FORMATTED_DATETIME "TEST-FORMATTED-DATETIME" @@ -663,6 +659,8 @@ UNDERLINE UNSIGNED_kw UTF_16 "UTF-16" UTF_8 "UTF-8" + XMLGENERATE "XML GENERATE" + XMLPARSE "XML PARSE" ADDRESS END_ACCEPT "END-ACCEPT" @@ -814,6 +812,7 @@ %type <error> on_overflow on_overflows %type <error> arith_err arith_errs %type <error> accept_except accept_excepts call_except call_excepts + %type <compute_body_t> compute_body %type <refer> ffi_name set_operand set_tgt scalar_arg unstring_src @@ -837,6 +836,12 @@ %type <number> mistake globally first_last %type <io_mode> io_mode +%type <label_pair> xmlprocs +%type <error> xmlexcept xmlexcepts +%type <field> xmlencoding xmlvalidating +%type <number> xmlreturning +%type <label> xmlparse_body + %type <labels> labels %type <label> label_1 section_name @@ -868,6 +873,8 @@ %type <opt_init_sects> opt_init_sects %type <opt_init_sect> opt_init_sect %type <number> opt_init_value +%type <number> locale_current loc_category user_default +%type <token_list> loc_categories locale_tgt %type <opt_round> rounded round_between rounded_type rounded_mode %type <opt_arith> opt_arith_type %type <module_type> module_type @@ -944,7 +951,9 @@ struct { cbl_refer_t *input, *delimiter; } delimited_1; struct { cbl_refer_t *from, *len; } refmod_parts; struct refer_collection_t *delimiteds; + struct { cbl_label_t *on_error, *not_error; } error; + label_pair_t label_pair; struct { unsigned int nclause; bool tf; } error_clauses; struct refer_pair_t { cbl_refer_t *first, *second; } refer2; struct { refer_collection_t *inputs; refer_pair_t into; } str_body; @@ -977,6 +986,7 @@ substitution_t substitution; substitutions_t *substitutions; struct { bool is_locale; cbl_refer_t *arg2; } numval_locale_t; + locale_tgt_t *token_list; cbl_options_t::arith_t opt_arith; cbl_round_t opt_round; @@ -1064,8 +1074,7 @@ SEARCH SET SELECT SORT SORT_MERGE STRING_kw STOP SUBTRACT START UNSTRING WRITE WHEN INVALID - XMLGENERATE "XML GENERATE" - XMLPARSE "XML PARSE" + XMLGENERATE XMLPARSE %left ABS ACCESS ACOS ACTUAL ADVANCING AFP_5A AFTER ALL ALLOCATE @@ -1241,7 +1250,7 @@ LITERAL SUBSTITUTE SUM SWITCH SYMBOL SYMBOLIC SYNCHRONIZED SYSIN SYSIPT SYSLST SYSOUT SYSPCH SYSPUNCH - TALLY TALLYING TAN TERMINATE TEST + TALLYING TAN TERMINATE TEST TEST_DATE_YYYYMMDD TEST_DAY_YYYYDDD TEST_FORMATTED_DATETIME @@ -1589,8 +1598,8 @@ function_id: FUNCTION NAME program_as program_attrs[attr] '.' if( !current.new_program(@NAME, LblFunction, $NAME, $program_as.data, $attr.common, $attr.initial) ) { - auto L = symbol_program(current_program_index(), $NAME); - assert(L); + auto e = symbol_function(current_program_index(), $NAME); + auto L = cbl_label_of(e); error_msg(@NAME, "FUNCTION %s already defined on line %d", $NAME, L->line); YYERROR; @@ -2734,9 +2743,18 @@ device_name: SYSIN { $$.token = SYSIN; $$.id = SYSIN_e; } /* ENVIRONMENT_VALUE { $$.token=0; $$.id = ENV_VALUE_e; } */ ; -alphabet_name: STANDARD_ALPHABET { $$ = alphabet_add(@1, ASCII_e); } +alphabet_name: STANDARD_ALPHABET { $$ = alphabet_add(@1, CP1252_e); } | NATIVE { $$ = alphabet_add(@1, EBCDIC_e); } | EBCDIC { $$ = alphabet_add(@1, EBCDIC_e); } + | LOCALE ctx_name + { + auto e = symbol_alphabet(PROGRAM, $ctx_name); + if( !e ) { + error_msg(@ctx_name, "no such ALPHABET %qs", $ctx_name); + YYERROR; + } + $$ = cbl_alphabet_of(e); + } | alphabet_seqs { $1->reencode(); @@ -4208,16 +4226,17 @@ picture_clause: PIC signed nps[fore] nines nps[aft] { cbl_field_t *field = current_field(); field->data.digits = $left + $rdigits; + field->attr |= $signed; if( field->is_binary_integer() ) { field->data.capacity = type_capacity(field->type, field->data.digits); + field->data.rdigits = $rdigits; } else { if( !field_type_update(field, FldNumericDisplay, @$) ) { YYERROR; } ERROR_IF_CAPACITY(@PIC, field); - field->attr |= $signed; field->data.capacity = field->data.digits; field->data.rdigits = $rdigits; } @@ -4487,8 +4506,8 @@ usage_clause1: usage BIT field->clear_attr(signable_e); } else { error_msg(@comp, "numeric USAGE invalid " - "with Alpnanumeric PICTURE"); - dialect_error(@1, "Alpnanumeric COMP-5 or COMP-X", "mf or gnu"); + "with Alphanumeric PICTURE"); + dialect_error(@1, "Alphanumeric COMP-5 or COMP-X", "mf or gnu"); YYERROR; } break; @@ -4568,8 +4587,8 @@ usage_clause1: usage BIT field->clear_attr(signable_e); } else { error_msg(@comp, "numeric USAGE invalid " - "with Alpnanumeric PICTURE"); - dialect_error(@1, "Alpnanumeric COMP-5 or COMP-X", "mf or gnu"); + "with Alphanumeric PICTURE"); + dialect_error(@1, "Alphanumeric COMP-5 or COMP-X", "mf or gnu"); YYERROR; } break; @@ -7341,8 +7360,7 @@ num_value: scalar // might actually be a string | DETAIL OF scalar {$$ = $scalar; } | LENGTH_OF binary_type[size] { location_set(@1); - $$ = new cbl_refer_t( new_tempnumeric() ); - $$->field->clear_attr(signable_e); + $$ = new cbl_refer_t( new_tempnumeric(none_e) ); if( dialect_gcc() ) { dialect_error(@1, "LENGTH OF", "ibm"); } @@ -7350,8 +7368,7 @@ num_value: scalar // might actually be a string } | LENGTH_OF name[val] { location_set(@1); - $$ = new cbl_refer_t( new_tempnumeric() ); - $$->field->clear_attr(signable_e); + $$ = new cbl_refer_t( new_tempnumeric(none_e) ); if( dialect_gcc() ) { dialect_error(@1, "LENGTH OF", "ibm"); } @@ -7359,8 +7376,7 @@ num_value: scalar // might actually be a string } | LENGTH_OF name[val] subscripts[subs] { location_set(@1); - $$ = new cbl_refer_t( new_tempnumeric() ); - $$->field->clear_attr(signable_e); + $$ = new cbl_refer_t( new_tempnumeric(none_e) ); if( dialect_gcc() ) { dialect_error(@1, "LENGTH OF", "ibm"); } @@ -7576,8 +7592,7 @@ signed_literal: num_literal } | LENGTH_OF binary_type[size] { location_set(@1); - $$ = new_tempnumeric(); - $$->clear_attr(signable_e); + $$ = new_tempnumeric(none_e); if( dialect_gcc() ) { dialect_error(@1, "LENGTH OF", "ibm"); } @@ -7585,8 +7600,7 @@ signed_literal: num_literal } | LENGTH_OF name[val] { location_set(@1); - $$ = new_tempnumeric(); - $$->clear_attr(signable_e); + $$ = new_tempnumeric(none_e); if( dialect_gcc() ) { dialect_error(@1, "LENGTH OF", "ibm"); } @@ -7594,8 +7608,7 @@ signed_literal: num_literal } | LENGTH_OF name[val] subscripts[subs] { location_set(@1); - $$ = new_tempnumeric(); - $$->clear_attr(signable_e); + $$ = new_tempnumeric(none_e); if( dialect_gcc() ) { dialect_error(@1, "LENGTH OF", "ibm"); } @@ -8146,8 +8159,7 @@ varg1a: ADDRESS OF scalar { } | LENGTH_OF binary_type[size] { location_set(@1); - $$ = new cbl_refer_t( new_tempnumeric() ); - $$->field->clear_attr(signable_e); + $$ = new cbl_refer_t( new_tempnumeric(none_e) ); if( dialect_gcc() ) { dialect_error(@1, "LENGTH OF", "ibm"); } @@ -8155,8 +8167,7 @@ varg1a: ADDRESS OF scalar { } | LENGTH_OF name[val] { location_set(@1); - $$ = new cbl_refer_t( new_tempnumeric() ); - $$->field->clear_attr(signable_e); + $$ = new cbl_refer_t( new_tempnumeric(none_e) ); if( dialect_gcc() ) { dialect_error(@1, "LENGTH OF", "ibm"); } @@ -8164,8 +8175,7 @@ varg1a: ADDRESS OF scalar { } | LENGTH_OF name[val] subscripts[subs] { location_set(@1); - $$ = new cbl_refer_t( new_tempnumeric() ); - $$->field->clear_attr(signable_e); + $$ = new cbl_refer_t( new_tempnumeric(none_e) ); if( dialect_gcc() ) { dialect_error(@1, "LENGTH OF", "ibm"); } @@ -8881,6 +8891,23 @@ set: SET set_tgts[tgts] TO set_operand[src] new_literal($src, quoted_e); ast_set_pointers($tgts->targets, literal); } + // Format 12 (save-locale): + | SET set_tgts[tgts] TO LOCALE locale_current + { + if( $tgts->targets.size() > 1 ) { + error_msg(@tgts, "only 1 save-locale data-item is valid"); + } + switch($locale_current) { + case LC_ALL_kw: + case DEFAULT: + ast_save_locale($tgts->targets.front().refer, $locale_current); + break; + default: + gcc_unreachable(); + } + cbl_unimplementedw("unimplemented: SET TO LOCALE"); + } + ; | SET set_tgts[tgts] UP BY num_operand[src] { statement_begin(@1, SET); @@ -8939,6 +8966,42 @@ set: SET set_tgts[tgts] TO set_operand[src] set_conditional($yn)); } | SET { statement_begin(@1, SET); } many_switches + + // Format 11 (set-locale): + | SET LOCALE locale_tgt[tgt] TO locale_src + { + if( $tgt->is_default() ) { + // do something $tgt->default_of() + } else { + // do something $tgt->lc_categories() + } + cbl_unimplementedw("unimplemented: SET LOCALE"); + } + ; + +locale_tgt: user_default { $$ = new locale_tgt_t(); *$$ = $1; } + | loc_categories + ; +loc_categories: loc_category { $$ = new locale_tgt_t($1); } + | loc_categories loc_category { + $$ = $1; + $$->push_back($2); + } + ; +loc_category: LC_ALL_kw { $$ = LC_ALL_kw; } + | LC_COLLATE_kw { $$ = LC_COLLATE_kw; } + | LC_CTYPE_kw { $$ = LC_CTYPE_kw; } + | LC_MESSAGES_kw { $$ = LC_MESSAGES_kw; } + | LC_MONETARY_kw { $$ = LC_MONETARY_kw; } + | LC_NUMERIC_kw { $$ = LC_NUMERIC_kw; } + | LC_TIME_kw { $$ = LC_TIME_kw; } + ; +locale_src: scalar + | DEFAULT { assert($1 == 'U' || $1 == 'S'); } + ; + +locale_current: LC_ALL_kw { $$ = LC_ALL_kw; } // locale to be saved by SET Format 12. + | user_default { $$ = DEFAULT; } ; many_switches: set_switches @@ -9273,16 +9336,20 @@ sort_target: label_name release: RELEASE NAME[record] FROM scalar[name] { - statement_begin(@1, RELEASE); - symbol_elem_t *record = symbol_find(@record, $record); - parser_move(cbl_field_of(record), *$name); - parser_release(cbl_field_of(record)); + if( ! mode_syntax_only() ) { + statement_begin(@1, RELEASE); + symbol_elem_t *record = symbol_find(@record, $record); + parser_move(cbl_field_of(record), *$name); + parser_release(cbl_field_of(record)); + } } | RELEASE NAME[record] { - statement_begin(@1, RELEASE); - symbol_elem_t *record = symbol_find(@record, $record); - parser_release(cbl_field_of(record)); + if( ! mode_syntax_only() ) { + statement_begin(@1, RELEASE); + symbol_elem_t *record = symbol_find(@record, $record); + parser_release(cbl_field_of(record)); + } } ; @@ -10705,15 +10772,13 @@ intrinsic: function_udf } | LENGTH '(' tableish[val] ')' { location_set(@1); - $$ = new_tempnumeric("LENGTH"); - $$->clear_attr(signable_e); + $$ = new_tempnumeric("LENGTH", none_e); parser_set_numeric($$, $val->field->size()); if( ! intrinsic_call_1($$, LENGTH, $val, @val)) YYERROR; } | LENGTH '(' varg1a[val] ')' { location_set(@1); - $$ = new_tempnumeric("LENGTH"); - $$->clear_attr(signable_e); + $$ = new_tempnumeric("LENGTH", none_e); parser_set_numeric($$, $val->field->data.capacity); if( ! intrinsic_call_1($$, LENGTH, $val, @val)) YYERROR; } @@ -10738,7 +10803,7 @@ intrinsic: function_udf | ORD '(' alpha_val[r1] ')' { location_set(@1); - $$ = new_tempnumeric("ORD"); + $$ = new_tempnumeric("ORD", none_e); if( ! intrinsic_call_1($$, ORD, $r1, @r1)) YYERROR; } | RANDOM @@ -11436,6 +11501,20 @@ usage: %empty | USAGE IS ; +user_default: DEFAULT + { // cannot be empty + switch( $1 ) { + case 'U': break; + case 'S': + error_msg(@1, "invalid syntax: SYSTEM-DEFAULT"); + break; + default: + error_msg(@1, "invalid syntax: DEFAULT"); + gcc_unreachable(); + } + } + ; + with: %empty | WITH ; @@ -11689,40 +11768,115 @@ xml_generic_numeric: ; xmlparse: xmlparse_impl end_xml { - cbl_unimplemented("XML PARSE"); + auto xml_stmt = xml_statements.top(); + parser_xml_end(xml_stmt); + xml_statements.pop(); + current.declaratives_evaluate(); } | xmlparse_cond end_xml { - cbl_unimplemented("XML PARSE"); + auto xml_stmt = xml_statements.top(); + parser_xml_end(xml_stmt); + xml_statements.pop(); + current.declaratives_evaluate(); } ; -xmlparse_impl: XMLPARSE xmlparse_body +xmlparse_impl: XMLPARSE xmlparse_body[body] + { + parser_xml_on_exception($body); + parser_xml_not_exception($body); + } ; xmlparse_cond: XMLPARSE xmlparse_body[body] xmlexcepts[err] + { + if( ! $err.on_error ) parser_xml_on_exception($body); + if( ! $err.not_error ) parser_xml_not_exception($body); + } ; -xmlparse_body: XMLPARSE name xmlencoding xmlreturning xmlvalidating - PROCESSING PROCEDURE is xmlprocs +xmlparse_body: scalar xmlencoding xmlreturning xmlvalidating + PROCESSING PROCEDURE is xmlprocs[procs] + { + $$ = label_add(@$, LblXml, uniq_label("xml")); + xml_statements.push($$); + statement_begin(@$, XMLPARSE); + parser_xml_parse( $$, + *$scalar, + $xmlencoding, + $xmlvalidating, + $xmlreturning == NATIONAL, + $procs.from, + $procs.to ); + } ; -xmlencoding: %empty %prec NAME - | with ENCODING name [codepage] +xmlencoding: %empty %prec NAME { $$ = nullptr; } + | with ENCODING name [codepage] { $$ = $codepage; } ; -xmlreturning: %empty - | RETURNING NATIONAL +xmlreturning: %empty { $$ = 0; } + | RETURNING NATIONAL { $$ = NATIONAL; } ; -xmlvalidating: %empty - | VALIDATING with name - | VALIDATING with FILE_KW name +xmlvalidating: %empty { $$ = nullptr; } + | VALIDATING with name { $$ = $name; } + | VALIDATING with FILE_KW name { $$ = $name; } ; -xmlprocs: label_1[proc] - | label_1[proc1] THRU label_1[proc2] +xmlprocs: label_1 { + $$ = label_pair_t{$1}; + } + | label_1[from] THRU label_1[to] { + $$ = label_pair_t{$from, $to}; + } ; xmlexcepts: xmlexcept[a] statements %prec XMLPARSE + { + assert( $a.on_error || $a.not_error ); + assert( ! ($a.on_error && $a.not_error) ); + $$ = $a; + } | xmlexcepts[a] xmlexcept[b] statements %prec XMLPARSE - ; + { + if( $a.on_error && $a.not_error ) { + error_msg(@1, "too many ON ERROR clauses"); + YYERROR; + } + // "ON" and "NOT ON" could be reversed, but not duplicated. + if( $a.on_error && $b.on_error ) { + error_msg(@1, "duplicate ON ERROR clauses"); + YYERROR; + } + if( $a.not_error && $b.not_error ) { + error_msg(@1, "duplicate NOT ON ERROR clauses"); + YYERROR; + } + $$ = $a; + if( $$.on_error ) { + assert($b.not_error); + $$.not_error = $b.not_error; + } else { + assert($b.on_error); + $$.on_error = $b.on_error; + } + } + ; xmlexcept: EXCEPTION + { + auto xml_stmt = xml_statements.top(); + // The value of the pointer no longer matters, only NULL or not. + $$.on_error = $$.not_error = nullptr; + switch($1) { + case EXCEPTION: + $$.on_error = xml_stmt; + parser_xml_on_exception(xml_stmt); + break; + case NOT: + $$.not_error = xml_stmt; + parser_xml_not_exception(xml_stmt); + break; + default: + gcc_unreachable(); + } + } ; end_xml: %empty %prec XMLPARSE @@ -11864,12 +12018,6 @@ bool iso_cobol_word( const std::string& name, bool include_context ); * REPOSITORY names. */ -// tokens.h is generated as needed from parse.h with tokens.h.gen -current_tokens_t::tokenset_t::tokenset_t() { -#include "token_names.h" -} - - // Look up the lowercase form of a keyword, excluding some CDF names. int current_tokens_t::tokenset_t::find( const cbl_name_t name, bool include_intrinsics ) { @@ -13391,6 +13539,54 @@ cbl_figconst_field_of( const char *value ) { return token == 0 ? nullptr : constant_of(constant_index(token)); } +const char * +literal_t::symbol_name() const { + return isym? cbl_field_of(symbol_at(isym))->name : ""; +} + +literal_t& +literal_t::set( const cbl_field_t * field ) { + assert(field->has_attr(constant_e)); + assert(is_literal(field)); + + set_prefix( "", 0 ); + set_data( field->data.capacity, + const_cast<char*>(field->data.initial), + field_index(field) ); + return *this; +} + +literal_t& +literal_t::set_prefix( const char *input, size_t len ) { + encoding = current_encoding('A'); + assert(len < sizeof(prefix)); + std::fill(prefix, prefix + sizeof(prefix), '\0'); + std::transform(input, input + len, prefix, toupper); + switch(prefix[0]) { + case '\0': case 'Z': + encoding = current_encoding('A'); + break; + case 'N': + encoding = current_encoding('N'); + if( 'X' == prefix[1] ) { + cbl_unimplemented("NX literals"); + } + break; + case 'G': + cbl_unimplemented("DBCS encoding not supported"); + break; + case 'U': + encoding = UTF8_e; + break; + case 'X': + break; + default: + gcc_unreachable(); + } + assert(encoding <= iconv_YU_e); + return *this; +} + cbl_field_attr_t literal_attr( const char prefix[] ) { @@ -13766,3 +13962,4 @@ eval_subject_t::compare( const cbl_refer_t& object, parser_relop(result, subject, eq_op, object); return result; } + diff --git a/gcc/cobol/parse_ante.h b/gcc/cobol/parse_ante.h index c3e3495..1fbc8f5 100644 --- a/gcc/cobol/parse_ante.h +++ b/gcc/cobol/parse_ante.h @@ -278,6 +278,9 @@ name_of( cbl_field_t *field ) { // associated with returning a static. I don't actually know. -- RJD. static size_t static_length = 0; static char * static_buffer = nullptr; + + if( field->data.initial == nullptr ) return field->name; + if( field->name[0] == '_' ) { // Make a copy of .initial @@ -757,6 +760,8 @@ class eval_subject_t { } }; +static std::stack<cbl_label_t *> xml_statements; + class evaluate_t : private std::stack<eval_subject_t> { public: size_t depth() const { return size(); } @@ -2366,8 +2371,13 @@ char * normalize_picture( char picture[] ); static inline cbl_field_t * -new_tempnumeric(const cbl_name_t name = nullptr) { - return new_temporary(FldNumericBin5, name); +new_tempnumeric(const cbl_name_t name = nullptr, cbl_field_attr_t attr = signable_e ) { + return new_temporary(FldNumericBin5, name, attr == signable_e); +} + +static inline cbl_field_t * +new_tempnumeric(const cbl_field_attr_t attr ) { + return new_temporary(FldNumericBin5, nullptr, attr == signable_e); } static inline cbl_field_t * @@ -3183,6 +3193,16 @@ ast_set_pointers( const list<cbl_num_result_t>& tgts, cbl_refer_t src ) { parser_set_pointers(nptr, ptrs.data(), src); } +static void +ast_save_locale( cbl_refer_t refer, int /* token */ ) { + assert( ! refer.addr_of && ! refer.is_reference() ); + if( ! refer.is_pointer() ) { + error_msg(refer.loc, "%s must be USAGE POINTER", refer.name()); + return; + } + cbl_unimplemented("SET identifier-11 TO LOCALE"); +} + void stringify( refer_collection_t *inputs, const cbl_refer_t& into, const cbl_refer_t& pointer, @@ -3269,7 +3289,11 @@ data_division_ready() { const char *name = current.collating_sequence(); if( ! symbols_alphabet_set(PROGRAM, name) ) { - error_msg(yylloc, "no alphabet '%s' defined", name); + if( name ) { + error_msg(yylloc, "no alphabet '%s' defined", name); + } else { + error_msg(yylloc, "no alphabet defined"); + } return false; } } diff --git a/gcc/cobol/scan.l b/gcc/cobol/scan.l index 53d88cb..07aa76d 100644 --- a/gcc/cobol/scan.l +++ b/gcc/cobol/scan.l @@ -517,7 +517,6 @@ THAN { return THAN; } TEST { return TEST; } TERMINATE { return TERMINATE; } TALLYING { return TALLYING; } -TALLY { return TALLY; } SYSPUNCH { return SYSPUNCH; } SYSOUT { return SYSOUT; } SYSIN { return SYSIN; } @@ -997,12 +996,12 @@ USE({SPC}FOR)? { return USE; } COMP(UTATIONAL)?-X { return ucomputable(FldNumericBin5, 0xFF); } COMP(UTATIONAL)?-6 { return ucomputable(FldPacked, 0); } COMP(UTATIONAL)?-5 { return ucomputable(FldNumericBin5, 0); } - COMP(UTATIONAL)?-4 { return scomputable(FldNumericBinary, 0); } + COMP(UTATIONAL)?-4 { return ucomputable(FldNumericBinary, 0); } COMP(UTATIONAL)?-3 { return PACKED_DECIMAL; } COMP(UTATIONAL)?-2 { return ucomputable(FldFloat, 8); } COMP(UTATIONAL)?-1 { return ucomputable(FldFloat, 4); } COMP(UTATIONAL)? { return ucomputable(FldNumericBinary, 0); } - BINARY { return scomputable(FldNumericBinary, 0); } + BINARY { return ucomputable(FldNumericBinary, 0); } BINARY-CHAR { return bcomputable(FldNumericBin5, 1); } BINARY-SHORT { return bcomputable(FldNumericBin5, 2); } @@ -2262,7 +2261,7 @@ BASIS { yy_push_state(basis); return BASIS; } DE { return DE; } DECIMAL-POINT { return DECIMAL_POINT; } DECLARATIVES { return DECLARATIVES; } - DEFAULT { return DEFAULT; } + DEFAULT { yylval.number = 'D'; return DEFAULT; } DELETE { return DELETE; } DELIMITED { return DELIMITED; } DELIMITER { return DELIMITER; } diff --git a/gcc/cobol/scan_ante.h b/gcc/cobol/scan_ante.h index c00826d..a6ec99b 100644 --- a/gcc/cobol/scan_ante.h +++ b/gcc/cobol/scan_ante.h @@ -575,36 +575,41 @@ keyword_alias_add( const std::string& keyword, const std::string& alias ) { struct bint_t { int token; cbl_field_type_t type; - uint32_t capacity; + uint32_t capacity; // zero means capacity depends on PICTURE bool signable; }; static const std::map <std::string, bint_t > binary_integers { - { "COMP-X", { COMPUTATIONAL, FldNumericBin5, 0xFF, false } }, - { "COMP-6", { COMPUTATIONAL, FldPacked, 0, false } }, - { "COMP-5", { COMPUTATIONAL, FldNumericBin5, 0, false } }, - { "COMP-4", { COMPUTATIONAL, FldNumericBinary, 0, true } }, - { "COMP-2", { COMPUTATIONAL, FldFloat, 8, false } }, - { "COMP-1", { COMPUTATIONAL, FldFloat, 4, false } }, - { "COMP", { COMPUTATIONAL, FldNumericBinary, 0, false } }, - { "COMPUTATIONAL-X", { COMPUTATIONAL, FldNumericBin5, 0xFF, false } }, - { "COMPUTATIONAL-6", { COMPUTATIONAL, FldPacked, 0, false } }, - { "COMPUTATIONAL-5", { COMPUTATIONAL, FldNumericBin5, 0, false } }, - { "COMPUTATIONAL-4", { COMPUTATIONAL, FldNumericBinary, 0, true } }, - { "COMPUTATIONAL-2", { COMPUTATIONAL, FldFloat, 8, false } }, - { "COMPUTATIONAL-1", { COMPUTATIONAL, FldFloat, 4, false } }, - { "COMPUTATIONAL", { COMPUTATIONAL, FldNumericBinary, 0, false } }, - { "BINARY", { BINARY_INTEGER, FldNumericBinary, 0, true } }, - { "BINARY-CHAR", { BINARY_INTEGER, FldNumericBin5, 1, true } }, - { "BINARY-SHORT", { BINARY_INTEGER, FldNumericBin5, 2, true } }, - { "BINARY-LONG", { BINARY_INTEGER, FldNumericBin5, 4, true } }, - { "BINARY-DOUBLE", { BINARY_INTEGER, FldNumericBin5, 8, true } }, - { "BINARY-LONG-LONG", { BINARY_INTEGER, FldNumericBin5, 8, true } }, - { "FLOAT-BINARY-32", { COMPUTATIONAL, FldFloat, 4, false } }, - { "FLOAT-BINARY-64", { COMPUTATIONAL, FldFloat, 8, false } }, + { "BINARY", { COMPUTATIONAL, FldNumericBinary, 0, false } }, + { "COMP", { COMPUTATIONAL, FldNumericBinary, 0, false } }, + { "COMPUTATIONAL", { COMPUTATIONAL, FldNumericBinary, 0, false } }, + { "COMP-4", { COMPUTATIONAL, FldNumericBinary, 0, false } }, + { "COMPUTATIONAL-4", { COMPUTATIONAL, FldNumericBinary, 0, false } }, + + { "BINARY-CHAR", { BINARY_INTEGER, FldNumericBin5, 1, true } }, + { "BINARY-SHORT", { BINARY_INTEGER, FldNumericBin5, 2, true } }, + { "BINARY-LONG", { BINARY_INTEGER, FldNumericBin5, 4, true } }, + { "BINARY-DOUBLE", { BINARY_INTEGER, FldNumericBin5, 8, true } }, + { "BINARY-LONG-LONG", { BINARY_INTEGER, FldNumericBin5, 8, true } }, + + { "COMP-5", { COMPUTATIONAL, FldNumericBin5, 0, false } }, + { "COMPUTATIONAL-5", { COMPUTATIONAL, FldNumericBin5, 0, false } }, + { "COMP-X", { COMPUTATIONAL, FldNumericBin5, 0xFF, false } }, + { "COMPUTATIONAL-X", { COMPUTATIONAL, FldNumericBin5, 0xFF, false } }, + + { "COMP-1", { COMPUTATIONAL, FldFloat, 4, false } }, + { "COMPUTATIONAL-1", { COMPUTATIONAL, FldFloat, 4, false } }, + { "FLOAT-BINARY-32", { COMPUTATIONAL, FldFloat, 4, false } }, + { "FLOAT-SHORT", { COMPUTATIONAL, FldFloat, 4, false } }, + + { "COMP-2", { COMPUTATIONAL, FldFloat, 8, false } }, + { "COMPUTATIONAL-2", { COMPUTATIONAL, FldFloat, 8, false } }, + { "FLOAT-BINARY-64", { COMPUTATIONAL, FldFloat, 8, false } }, + { "FLOAT-LONG", { COMPUTATIONAL, FldFloat, 8, false } }, { "FLOAT-BINARY-128", { COMPUTATIONAL, FldFloat, 16, false } }, - { "FLOAT-EXTENDED", { COMPUTATIONAL, FldFloat, 16, false } }, - { "FLOAT-LONG", { COMPUTATIONAL, FldFloat, 8, false } }, - { "FLOAT-SHORT", { COMPUTATIONAL, FldFloat, 4, false } }, + { "FLOAT-EXTENDED", { COMPUTATIONAL, FldFloat, 16, false } }, + + { "COMP-6", { COMPUTATIONAL, FldPacked, 0, false } }, + { "COMPUTATIONAL-6", { COMPUTATIONAL, FldPacked, 0, false } }, }; static int diff --git a/gcc/cobol/scan_post.h b/gcc/cobol/scan_post.h index 7cf2b98..01c863e 100644 --- a/gcc/cobol/scan_post.h +++ b/gcc/cobol/scan_post.h @@ -401,3 +401,12 @@ yylex(void) { return token; } + +/* + * Token name<->string utilities + */ + +// tokens.h is generated as needed from parse.h with tokens.h.gen +current_tokens_t::tokenset_t::tokenset_t() { +#include "token_names.h" +}; diff --git a/gcc/cobol/symbols.cc b/gcc/cobol/symbols.cc index b6f4a37..2a299ce 100644 --- a/gcc/cobol/symbols.cc +++ b/gcc/cobol/symbols.cc @@ -1634,6 +1634,9 @@ extend_66_capacity( cbl_field_t *alias ) { bool symbols_alphabet_set( size_t program, const char name[]) { + +//////// +// Older version struct alpha { void operator()( symbol_elem_t& elem ) const { if( elem.type == SymAlphabet ) { @@ -1654,6 +1657,38 @@ symbols_alphabet_set( size_t program, const char name[]) { parser_alphabet_use(*cbl_alphabet_of(e)); } return true; +// End older version +//////// + +//// // Define alphabets for codegen. +//// const cbl_alphabet_t *alphabet = nullptr; +//// bool supported = true; +//// +//// std::for_each( symbols_begin(program), symbols_end(), +//// [&alphabet, &supported]( const auto& sym ) { +//// if( sym.type == SymAlphabet ) { +//// alphabet = cbl_alphabet_of(&sym); +//// supported = __gg__encoding_iconv_valid(alphabet->encoding); +//// if( supported ) { +//// parser_alphabet( *alphabet ); +//// } +//// } +//// } ); +//// if( ! supported ) { +//// const char *encoding = __gg__encoding_iconv_name(alphabet->encoding); +//// cbl_unimplemented("alphabet %qs (as %qs)", alphabet->name, encoding); +//// return false; +//// } +//// +//// // Set collation sequence before parser_symbol_add.` +//// if( name ) { +//// symbol_elem_t *e = symbol_alphabet(program, name); +//// if( !e ) { +//// return false; +//// } +//// parser_alphabet_use(*cbl_alphabet_of(e)); +//// } +//// return true; } static std::ostream& @@ -2352,6 +2387,7 @@ symbol_table_init(void) { assert(table.nelem < table.capacity); std::for_each(debug_start+1, p, parent_elem_set(debug_start - table.elems)); + // special registers static cbl_field_t special_registers[] = { { FldNumericDisplay, register_e, {2,2,2,0, NULL}, 0, "_FILE_STATUS" }, { FldNumericBin5, register_e, {2,2,4,0, NULL}, 0, "UPSI-0" }, @@ -2363,7 +2399,6 @@ symbol_table_init(void) { { FldLiteralA, constq|register_e, {0,0,0,0, "/dev/null"}, 0, "_dev_null" }, }; - // special registers assert(table.nelem + COUNT_OF(special_registers) < table.capacity); p = table.elems + table.nelem; @@ -2373,6 +2408,26 @@ symbol_table_init(void) { table.nelem = p - table.elems; assert(table.nelem < table.capacity); + // xml registers + static cbl_field_t xml_registers[] = { + { FldNumericBin5, register_e, {4,4,9,0, "0"}, 1, "XML-CODE" }, + { FldAlphanumeric, register_e, {30,30,0,0, " "}, 1, "XML-EVENT" }, + { FldNumericBin5, register_e, {4,4,9,0, "0"}, 1, "XML-INFORMATION" }, + { FldAlphanumeric, register_e | based_e | any_length_e, {1,1,0,0, nullptr}, 1, "XML-NAMESPACE" }, + { FldAlphanumeric, register_e | based_e | any_length_e, {1,1,0,0, nullptr}, 1, "XML-NNAMESPACE" }, + { FldAlphanumeric, register_e | based_e | any_length_e, {1,1,0,0, nullptr}, 1, "XML-NAMESPACE-PREFIX" }, + { FldAlphanumeric, register_e | based_e | any_length_e, {1,1,0,0, nullptr}, 1, "XML-NNAMESPACE-PREFIX" }, + { FldAlphanumeric, register_e | based_e | any_length_e, {1,1,0,0, nullptr}, 1, "XML-TEXT" }, + { FldAlphanumeric, register_e | based_e | any_length_e, {1,1,0,0, nullptr}, 1, "XML-NTEXT" }, + }, * const eoxml = xml_registers + COUNT_OF(xml_registers); + + assert(table.nelem + COUNT_OF(xml_registers) < table.capacity); + + p = table.elems + table.nelem; + p = std::transform(xml_registers, eoxml, p, elementize); + table.nelem = p - table.elems; + assert(table.nelem < table.capacity); + // Initialize symbol table. symbols = table; @@ -3162,6 +3217,13 @@ cbl_alphabet_t::reencode() { const unsigned char * const pend = alphabet + sizeof(alphabet); std::vector<char> tgt(256, (char)0xFF); + /* Keep copies of low_index and last_index for use in run-time as LOW-VALUE + and HIGH-VALUE, which are kept as globals in the source-code codeset + and converted to the display encoding as necessary. */ + + low_char = low_index; + high_char = last_index; + /* * For now, assume CP1252 source-code encoding because we're not capturing it * anywhere except in cbl_field_t::internalize(). The only known examples of @@ -3533,12 +3595,16 @@ new_alphanumeric( size_t capacity, const cbl_name_t name = nullptr ) { extern os_locale_t os_locale; -const encodings_t cbl_field_t::codeset_t::standard_internal = { iconv_CP1252_e, "CP1252" }; +const encodings_t cbl_field_t::codeset_t::standard_internal = { + true, iconv_CP1252_e, "CP1252" +}; #define standard_internal cbl_field_t::codeset_t::standard_internal cbl_field_t * -new_temporary( enum cbl_field_type_t type, const char *initial ) { - if( ! initial ) { +new_temporary( enum cbl_field_type_t type, const char *initial, bool is_signed ) { + const bool force_unsigned = type == FldNumericBin5 && ! is_signed; + + if( ! initial && ! force_unsigned ) { assert( ! is_literal(type) ); // Literal type must have literal value. return temporaries.acquire(type, initial); } @@ -3549,7 +3615,14 @@ new_temporary( enum cbl_field_type_t type, const char *initial ) { return field; } cbl_field_t *field = new_temporary_impl(type, initial); - temporaries.add(field); + + // don't reuse unsigned numeric + if( force_unsigned ) { + field->clear_attr(signable_e); + } else { + temporaries.add(field); + } + parser_symbol_add(field); return field; diff --git a/gcc/cobol/symbols.h b/gcc/cobol/symbols.h index b24283a..66fb2fd 100644 --- a/gcc/cobol/symbols.h +++ b/gcc/cobol/symbols.h @@ -500,6 +500,7 @@ struct cbl_subtable_t { }; const char * __gg__encoding_iconv_name( cbl_encoding_t encoding ); +bool __gg__encoding_iconv_valid( cbl_encoding_t encoding ); bool is_elementary( enum cbl_field_type_t type ); @@ -507,8 +508,8 @@ bool is_elementary( enum cbl_field_type_t type ); // current_encoding('A') and current_encoding('N') enum { - encoding_display_e = 'A', - encoding_national_e = 'N' + display_encoding_e = 'A', + national_encoding_e = 'N' }; cbl_encoding_t current_encoding( char a_or_n ); @@ -964,6 +965,7 @@ enum cbl_label_type_t { LblString, LblArith, LblCompute, + LblXml, }; struct cbl_proc_addresses_t { @@ -1188,6 +1190,12 @@ struct cbl_compute_error_t { tree compute_error_code; }; +struct cbl_xml_parse_t { + cbl_label_addresses_t over; + cbl_label_addresses_t exception; + cbl_label_addresses_t no_exception; +}; + struct cbl_label_t { enum cbl_label_type_t type; size_t parent; @@ -1221,6 +1229,10 @@ struct cbl_label_t { // for parser_op/parser_assign error tracking struct cbl_compute_error_t *compute_error; + + // for parse_xml processing: + struct cbl_xml_parse_t *xml_parse; + } structs; bool is_function() const { return type == LblFunction; } @@ -1239,6 +1251,7 @@ struct cbl_label_t { case LblString: return "LblString"; case LblArith: return "LblArith"; case LblCompute: return "LblCompute"; + case LblXml: return "LblXml"; } gcc_unreachable(); } @@ -1293,7 +1306,9 @@ struct label_cmp_lessthan { size_t field_index( const cbl_field_t *f ); -cbl_field_t * new_temporary( enum cbl_field_type_t type, const char initial[] = NULL ); +cbl_field_t * new_temporary( enum cbl_field_type_t type, + const char initial[] = NULL, + bool attr = false ); cbl_field_t * new_temporary_like( cbl_field_t skel ); cbl_field_t * new_temporary_clone( const cbl_field_t *orig); cbl_field_t * keep_temporary( cbl_field_type_t type ); @@ -1532,6 +1547,7 @@ struct cbl_alphabet_t { cbl_name_t name; cbl_encoding_t encoding; unsigned char low_index, high_index, last_index, alphabet[256]; + unsigned char low_char, high_char; cbl_alphabet_t() : loc { 1,1, 1,1 } @@ -1539,6 +1555,8 @@ struct cbl_alphabet_t { , low_index(0) , high_index(255) , last_index(0) + , low_char(0) + , high_char(0) { memset(name, '\0', sizeof(name)); memset(alphabet, 0xFF, sizeof(alphabet)); @@ -1550,6 +1568,8 @@ struct cbl_alphabet_t { , low_index(0) , high_index(255) , last_index(0) + , low_char(0) + , high_char(0) { memset(name, '\0', sizeof(name)); memset(alphabet, 0xFF, sizeof(alphabet)); @@ -1562,6 +1582,8 @@ struct cbl_alphabet_t { , encoding(custom_encoding_e) , low_index(low_index), high_index(high_index) , last_index(high_index) + , low_char(low_index) + , high_char(high_index) { assert(strlen(name) < sizeof(this->name)); strcpy(this->name, name); @@ -1953,6 +1975,14 @@ symbol_elem_of( cbl_alphabet_t *alphabet ) { reinterpret_cast<symbol_elem_t *>((char*)alphabet - n); } +static inline const symbol_elem_t * +symbol_elem_of( const cbl_alphabet_t *alphabet ) { + size_t n = offsetof(symbol_elem_t, elem.alphabet); + return + // cppcheck-suppress cstyleCast + reinterpret_cast<const symbol_elem_t *>((const char*)alphabet - n); +} + static inline symbol_elem_t * symbol_elem_of( cbl_file_t *file ) { size_t n = offsetof(struct symbol_elem_t, elem.file); @@ -2027,14 +2057,14 @@ const cbl_field_t * symbol_unresolved_file_key( const cbl_file_t * file, const cbl_name_t key_field_name ); -static inline struct cbl_section_t * -cbl_section_of( struct symbol_elem_t *e ) { +static inline cbl_section_t * +cbl_section_of( symbol_elem_t *e ) { assert(e && e->type == SymDataSection); return &e->elem.section; } -static inline struct cbl_field_t * -cbl_field_of( struct symbol_elem_t *e ) { +static inline cbl_field_t * +cbl_field_of( symbol_elem_t *e ) { assert(e && e->type == SymField); return &e->elem.field; } @@ -2044,8 +2074,8 @@ cbl_field_of( const symbol_elem_t *e ) { return &e->elem.field; } -static inline struct cbl_label_t * -cbl_label_of( struct symbol_elem_t *e ) { +static inline cbl_label_t * +cbl_label_of( symbol_elem_t *e ) { assert(e && e->type == SymLabel); return &e->elem.label; } @@ -2056,20 +2086,26 @@ cbl_label_of( const symbol_elem_t *e ) { return &e->elem.label; } -static inline struct cbl_special_name_t * -cbl_special_name_of( struct symbol_elem_t *e ) { +static inline cbl_special_name_t * +cbl_special_name_of( symbol_elem_t *e ) { assert(e && e->type == SymSpecial); return &e->elem.special; } -static inline struct cbl_alphabet_t * -cbl_alphabet_of( struct symbol_elem_t *e ) { +static inline cbl_alphabet_t * +cbl_alphabet_of( symbol_elem_t *e ) { + assert(e && e->type == SymAlphabet); + return &e->elem.alphabet; +} + +static inline const cbl_alphabet_t * +cbl_alphabet_of( const symbol_elem_t *e ) { assert(e && e->type == SymAlphabet); return &e->elem.alphabet; } -static inline struct cbl_file_t * -cbl_file_of( struct symbol_elem_t *e ) { +static inline cbl_file_t * +cbl_file_of( symbol_elem_t *e ) { assert(e && e->type == SymFile); return &e->elem.file; } diff --git a/gcc/cobol/token_names.h b/gcc/cobol/token_names.h index 77029f7..6d3de71 100644 --- a/gcc/cobol/token_names.h +++ b/gcc/cobol/token_names.h @@ -1,5 +1,5 @@ -// generated by ./token_names.h.gen ../../build/gcc/cobol/parse.h -// Mon Sep 15 22:47:12 EDT 2025 +// generated by /home/jklowden/projects/3rd/gcc/parser/gcc/cobol/token_names.h.gen cobol/parse.h +// Mon Oct 20 14:11:39 EDT 2025 tokens = { { "identification", IDENTIFICATION_DIV }, // 258 { "environment", ENVIRONMENT_DIV }, // 259 @@ -541,171 +541,170 @@ tokens = { { "symbol", SYMBOL }, // 790 { "symbolic", SYMBOLIC }, // 791 { "synchronized", SYNCHRONIZED }, // 792 - { "tally", TALLY }, // 793 - { "tallying", TALLYING }, // 794 - { "tan", TAN }, // 795 - { "terminate", TERMINATE }, // 796 - { "test", TEST }, // 797 - { "test-date-yyyymmdd", TEST_DATE_YYYYMMDD }, // 798 - { "test-day-yyyyddd", TEST_DAY_YYYYDDD }, // 799 - { "test-formatted-datetime", TEST_FORMATTED_DATETIME }, // 800 - { "test-numval", TEST_NUMVAL }, // 801 - { "test-numval-c", TEST_NUMVAL_C }, // 802 - { "test-numval-f", TEST_NUMVAL_F }, // 803 - { "than", THAN }, // 804 - { "time", TIME }, // 805 - { "times", TIMES }, // 806 - { "to", TO }, // 807 - { "top", TOP }, // 808 - { "top-level", TOP_LEVEL }, // 809 - { "tracks", TRACKS }, // 810 - { "track-area", TRACK_AREA }, // 811 - { "trailing", TRAILING }, // 812 - { "transform", TRANSFORM }, // 813 - { "trim", TRIM }, // 814 - { "true", TRUE_kw }, // 815 - { "try", TRY }, // 816 - { "turn", TURN }, // 817 - { "type", TYPE }, // 818 - { "typedef", TYPEDEF }, // 819 - { "ulength", ULENGTH }, // 820 - { "unbounded", UNBOUNDED }, // 821 - { "unit", UNIT }, // 822 - { "units", UNITS }, // 823 - { "unit-record", UNIT_RECORD }, // 824 - { "until", UNTIL }, // 825 - { "up", UP }, // 826 - { "upon", UPON }, // 827 - { "upos", UPOS }, // 828 - { "upper-case", UPPER_CASE }, // 829 - { "usage", USAGE }, // 830 - { "using", USING }, // 831 - { "usubstr", USUBSTR }, // 832 - { "usupplementary", USUPPLEMENTARY }, // 833 - { "utility", UTILITY }, // 834 - { "uuid4", UUID4 }, // 835 - { "uvalid", UVALID }, // 836 - { "uwidth", UWIDTH }, // 837 - { "validating", VALIDATING }, // 838 - { "value", VALUE }, // 839 - { "variance", VARIANCE }, // 840 - { "varying", VARYING }, // 841 - { "volatile", VOLATILE }, // 842 - { "when-compiled", WHEN_COMPILED }, // 843 - { "with", WITH }, // 844 - { "working-storage", WORKING_STORAGE }, // 845 - { "year-to-yyyy", YEAR_TO_YYYY }, // 846 - { "yyyyddd", YYYYDDD }, // 847 - { "yyyymmdd", YYYYMMDD }, // 848 - { "arithmetic", ARITHMETIC }, // 849 - { "attribute", ATTRIBUTE }, // 850 - { "auto", AUTO }, // 851 - { "automatic", AUTOMATIC }, // 852 - { "away-from-zero", AWAY_FROM_ZERO }, // 853 - { "background-color", BACKGROUND_COLOR }, // 854 - { "bell", BELL }, // 855 - { "binary-encoding", BINARY_ENCODING }, // 856 - { "blink", BLINK }, // 857 - { "capacity", CAPACITY }, // 858 - { "center", CENTER }, // 859 - { "classification", CLASSIFICATION }, // 860 - { "cycle", CYCLE }, // 861 - { "decimal-encoding", DECIMAL_ENCODING }, // 862 - { "entry-convention", ENTRY_CONVENTION }, // 863 - { "eol", EOL }, // 864 - { "eos", EOS }, // 865 - { "erase", ERASE }, // 866 - { "expands", EXPANDS }, // 867 - { "float-binary", FLOAT_BINARY }, // 868 - { "float-decimal", FLOAT_DECIMAL }, // 869 - { "foreground-color", FOREGROUND_COLOR }, // 870 - { "forever", FOREVER }, // 871 - { "full", FULL }, // 872 - { "highlight", HIGHLIGHT }, // 873 - { "high-order-left", HIGH_ORDER_LEFT }, // 874 - { "high-order-right", HIGH_ORDER_RIGHT }, // 875 - { "ignoring", IGNORING }, // 876 - { "implements", IMPLEMENTS }, // 877 - { "initialized", INITIALIZED }, // 878 - { "intermediate", INTERMEDIATE }, // 879 - { "lc-all", LC_ALL_kw }, // 880 - { "lc-collate", LC_COLLATE_kw }, // 881 - { "lc-ctype", LC_CTYPE_kw }, // 882 - { "lc-messages", LC_MESSAGES_kw }, // 883 - { "lc-monetary", LC_MONETARY_kw }, // 884 - { "lc-numeric", LC_NUMERIC_kw }, // 885 - { "lc-time", LC_TIME_kw }, // 886 - { "lowlight", LOWLIGHT }, // 887 - { "nearest-away-from-zero", NEAREST_AWAY_FROM_ZERO }, // 888 - { "nearest-even", NEAREST_EVEN }, // 889 - { "nearest-toward-zero", NEAREST_TOWARD_ZERO }, // 890 - { "none", NONE }, // 891 - { "normal", NORMAL }, // 892 - { "numbers", NUMBERS }, // 893 - { "prefixed", PREFIXED }, // 894 - { "previous", PREVIOUS }, // 895 - { "prohibited", PROHIBITED }, // 896 - { "relation", RELATION }, // 897 - { "required", REQUIRED }, // 898 - { "reverse-video", REVERSE_VIDEO }, // 899 - { "rounding", ROUNDING }, // 900 - { "seconds", SECONDS }, // 901 - { "secure", SECURE }, // 902 - { "short", SHORT }, // 903 - { "signed", SIGNED_kw }, // 904 - { "standard-binary", STANDARD_BINARY }, // 905 - { "standard-decimal", STANDARD_DECIMAL }, // 906 - { "statement", STATEMENT }, // 907 - { "step", STEP }, // 908 - { "structure", STRUCTURE }, // 909 - { "toward-greater", TOWARD_GREATER }, // 910 - { "toward-lesser", TOWARD_LESSER }, // 911 - { "truncation", TRUNCATION }, // 912 - { "ucs-4", UCS_4 }, // 913 - { "underline", UNDERLINE }, // 914 - { "unsigned", UNSIGNED_kw }, // 915 - { "utf-16", UTF_16 }, // 916 - { "utf-8", UTF_8 }, // 917 - { "address", ADDRESS }, // 918 - { "end-accept", END_ACCEPT }, // 919 - { "end-add", END_ADD }, // 920 - { "end-call", END_CALL }, // 921 - { "end-compute", END_COMPUTE }, // 922 - { "end-delete", END_DELETE }, // 923 - { "end-display", END_DISPLAY }, // 924 - { "end-divide", END_DIVIDE }, // 925 - { "end-evaluate", END_EVALUATE }, // 926 - { "end-multiply", END_MULTIPLY }, // 927 - { "end-perform", END_PERFORM }, // 928 - { "end-read", END_READ }, // 929 - { "end-return", END_RETURN }, // 930 - { "end-rewrite", END_REWRITE }, // 931 - { "end-search", END_SEARCH }, // 932 - { "end-start", END_START }, // 933 - { "end-string", END_STRING }, // 934 - { "end-subtract", END_SUBTRACT }, // 935 - { "end-unstring", END_UNSTRING }, // 936 - { "end-write", END_WRITE }, // 937 - { "end-xml", END_XML }, // 938 - { "end-if", END_IF }, // 939 - { "xmlgenerate", XMLGENERATE }, // 940 - { "xmlparse", XMLPARSE }, // 942 - { "attributes", ATTRIBUTES }, // 944 - { "element", ELEMENT }, // 945 - { "namespace", NAMESPACE }, // 946 - { "namespace-prefix", NAMESPACE_PREFIX }, // 947 - { "nonnumeric", NONNUMERIC }, // 949 - { "xml-declaration", XML_DECLARATION }, // 950 - { "thru", THRU }, // 952 - { "through", THRU }, // 952 - { "or", OR }, // 953 - { "and", AND }, // 954 - { "not", NOT }, // 955 - { "ne", NE }, // 956 - { "le", LE }, // 957 - { "ge", GE }, // 958 - { "pow", POW }, // 959 - { "neg", NEG }, // 960 + { "tallying", TALLYING }, // 793 + { "tan", TAN }, // 794 + { "terminate", TERMINATE }, // 795 + { "test", TEST }, // 796 + { "test-date-yyyymmdd", TEST_DATE_YYYYMMDD }, // 797 + { "test-day-yyyyddd", TEST_DAY_YYYYDDD }, // 798 + { "test-formatted-datetime", TEST_FORMATTED_DATETIME }, // 799 + { "test-numval", TEST_NUMVAL }, // 800 + { "test-numval-c", TEST_NUMVAL_C }, // 801 + { "test-numval-f", TEST_NUMVAL_F }, // 802 + { "than", THAN }, // 803 + { "time", TIME }, // 804 + { "times", TIMES }, // 805 + { "to", TO }, // 806 + { "top", TOP }, // 807 + { "top-level", TOP_LEVEL }, // 808 + { "tracks", TRACKS }, // 809 + { "track-area", TRACK_AREA }, // 810 + { "trailing", TRAILING }, // 811 + { "transform", TRANSFORM }, // 812 + { "trim", TRIM }, // 813 + { "true", TRUE_kw }, // 814 + { "try", TRY }, // 815 + { "turn", TURN }, // 816 + { "type", TYPE }, // 817 + { "typedef", TYPEDEF }, // 818 + { "ulength", ULENGTH }, // 819 + { "unbounded", UNBOUNDED }, // 820 + { "unit", UNIT }, // 821 + { "units", UNITS }, // 822 + { "unit-record", UNIT_RECORD }, // 823 + { "until", UNTIL }, // 824 + { "up", UP }, // 825 + { "upon", UPON }, // 826 + { "upos", UPOS }, // 827 + { "upper-case", UPPER_CASE }, // 828 + { "usage", USAGE }, // 829 + { "using", USING }, // 830 + { "usubstr", USUBSTR }, // 831 + { "usupplementary", USUPPLEMENTARY }, // 832 + { "utility", UTILITY }, // 833 + { "uuid4", UUID4 }, // 834 + { "uvalid", UVALID }, // 835 + { "uwidth", UWIDTH }, // 836 + { "validating", VALIDATING }, // 837 + { "value", VALUE }, // 838 + { "variance", VARIANCE }, // 839 + { "varying", VARYING }, // 840 + { "volatile", VOLATILE }, // 841 + { "when-compiled", WHEN_COMPILED }, // 842 + { "with", WITH }, // 843 + { "working-storage", WORKING_STORAGE }, // 844 + { "year-to-yyyy", YEAR_TO_YYYY }, // 845 + { "yyyyddd", YYYYDDD }, // 846 + { "yyyymmdd", YYYYMMDD }, // 847 + { "arithmetic", ARITHMETIC }, // 848 + { "attribute", ATTRIBUTE }, // 849 + { "auto", AUTO }, // 850 + { "automatic", AUTOMATIC }, // 851 + { "away-from-zero", AWAY_FROM_ZERO }, // 852 + { "background-color", BACKGROUND_COLOR }, // 853 + { "bell", BELL }, // 854 + { "binary-encoding", BINARY_ENCODING }, // 855 + { "blink", BLINK }, // 856 + { "capacity", CAPACITY }, // 857 + { "center", CENTER }, // 858 + { "classification", CLASSIFICATION }, // 859 + { "cycle", CYCLE }, // 860 + { "decimal-encoding", DECIMAL_ENCODING }, // 861 + { "entry-convention", ENTRY_CONVENTION }, // 862 + { "eol", EOL }, // 863 + { "eos", EOS }, // 864 + { "erase", ERASE }, // 865 + { "expands", EXPANDS }, // 866 + { "float-binary", FLOAT_BINARY }, // 867 + { "float-decimal", FLOAT_DECIMAL }, // 868 + { "foreground-color", FOREGROUND_COLOR }, // 869 + { "forever", FOREVER }, // 870 + { "full", FULL }, // 871 + { "highlight", HIGHLIGHT }, // 872 + { "high-order-left", HIGH_ORDER_LEFT }, // 873 + { "high-order-right", HIGH_ORDER_RIGHT }, // 874 + { "ignoring", IGNORING }, // 875 + { "implements", IMPLEMENTS }, // 876 + { "initialized", INITIALIZED }, // 877 + { "intermediate", INTERMEDIATE }, // 878 + { "lc-all", LC_ALL_kw }, // 879 + { "lc-collate", LC_COLLATE_kw }, // 880 + { "lc-ctype", LC_CTYPE_kw }, // 881 + { "lc-messages", LC_MESSAGES_kw }, // 882 + { "lc-monetary", LC_MONETARY_kw }, // 883 + { "lc-numeric", LC_NUMERIC_kw }, // 884 + { "lc-time", LC_TIME_kw }, // 885 + { "lowlight", LOWLIGHT }, // 886 + { "nearest-away-from-zero", NEAREST_AWAY_FROM_ZERO }, // 887 + { "nearest-even", NEAREST_EVEN }, // 888 + { "nearest-toward-zero", NEAREST_TOWARD_ZERO }, // 889 + { "none", NONE }, // 890 + { "normal", NORMAL }, // 891 + { "numbers", NUMBERS }, // 892 + { "prefixed", PREFIXED }, // 893 + { "previous", PREVIOUS }, // 894 + { "prohibited", PROHIBITED }, // 895 + { "relation", RELATION }, // 896 + { "required", REQUIRED }, // 897 + { "reverse-video", REVERSE_VIDEO }, // 898 + { "rounding", ROUNDING }, // 899 + { "seconds", SECONDS }, // 900 + { "secure", SECURE }, // 901 + { "short", SHORT }, // 902 + { "signed", SIGNED_kw }, // 903 + { "standard-binary", STANDARD_BINARY }, // 904 + { "standard-decimal", STANDARD_DECIMAL }, // 905 + { "statement", STATEMENT }, // 906 + { "step", STEP }, // 907 + { "structure", STRUCTURE }, // 908 + { "toward-greater", TOWARD_GREATER }, // 909 + { "toward-lesser", TOWARD_LESSER }, // 910 + { "truncation", TRUNCATION }, // 911 + { "ucs-4", UCS_4 }, // 912 + { "underline", UNDERLINE }, // 913 + { "unsigned", UNSIGNED_kw }, // 914 + { "utf-16", UTF_16 }, // 915 + { "utf-8", UTF_8 }, // 916 + { "xmlgenerate", XMLGENERATE }, // 917 + { "xmlparse", XMLPARSE }, // 918 + { "address", ADDRESS }, // 919 + { "end-accept", END_ACCEPT }, // 920 + { "end-add", END_ADD }, // 921 + { "end-call", END_CALL }, // 922 + { "end-compute", END_COMPUTE }, // 923 + { "end-delete", END_DELETE }, // 924 + { "end-display", END_DISPLAY }, // 925 + { "end-divide", END_DIVIDE }, // 926 + { "end-evaluate", END_EVALUATE }, // 927 + { "end-multiply", END_MULTIPLY }, // 928 + { "end-perform", END_PERFORM }, // 929 + { "end-read", END_READ }, // 930 + { "end-return", END_RETURN }, // 931 + { "end-rewrite", END_REWRITE }, // 932 + { "end-search", END_SEARCH }, // 933 + { "end-start", END_START }, // 934 + { "end-string", END_STRING }, // 935 + { "end-subtract", END_SUBTRACT }, // 936 + { "end-unstring", END_UNSTRING }, // 937 + { "end-write", END_WRITE }, // 938 + { "end-xml", END_XML }, // 939 + { "end-if", END_IF }, // 940 + { "attributes", ATTRIBUTES }, // 941 + { "element", ELEMENT }, // 942 + { "namespace", NAMESPACE }, // 943 + { "namespace-prefix", NAMESPACE_PREFIX }, // 944 + { "nonnumeric", NONNUMERIC }, // 946 + { "xml-declaration", XML_DECLARATION }, // 947 + { "thru", THRU }, // 949 + { "through", THRU }, // 949 + { "or", OR }, // 950 + { "and", AND }, // 951 + { "not", NOT }, // 952 + { "ne", NE }, // 953 + { "le", LE }, // 954 + { "ge", GE }, // 955 + { "pow", POW }, // 956 + { "neg", NEG }, // 957 }; // cppcheck-suppress useInitializationList @@ -1245,168 +1244,167 @@ token_names = { "SYMBOL", // 532 (790) "SYMBOLIC", // 533 (791) "SYNCHRONIZED", // 534 (792) - "TALLY", // 535 (793) - "TALLYING", // 536 (794) - "TAN", // 537 (795) - "TERMINATE", // 538 (796) - "TEST", // 539 (797) - "TEST-DATE-YYYYMMDD", // 540 (798) - "TEST-DAY-YYYYDDD", // 541 (799) - "TEST-FORMATTED-DATETIME", // 542 (800) - "TEST-NUMVAL", // 543 (801) - "TEST-NUMVAL-C", // 544 (802) - "TEST-NUMVAL-F", // 545 (803) - "THAN", // 546 (804) - "TIME", // 547 (805) - "TIMES", // 548 (806) - "TO", // 549 (807) - "TOP", // 550 (808) - "TOP-LEVEL", // 551 (809) - "TRACKS", // 552 (810) - "TRACK-AREA", // 553 (811) - "TRAILING", // 554 (812) - "TRANSFORM", // 555 (813) - "TRIM", // 556 (814) - "TRUE", // 557 (815) - "TRY", // 558 (816) - "TURN", // 559 (817) - "TYPE", // 560 (818) - "TYPEDEF", // 561 (819) - "ULENGTH", // 562 (820) - "UNBOUNDED", // 563 (821) - "UNIT", // 564 (822) - "UNITS", // 565 (823) - "UNIT-RECORD", // 566 (824) - "UNTIL", // 567 (825) - "UP", // 568 (826) - "UPON", // 569 (827) - "UPOS", // 570 (828) - "UPPER-CASE", // 571 (829) - "USAGE", // 572 (830) - "USING", // 573 (831) - "USUBSTR", // 574 (832) - "USUPPLEMENTARY", // 575 (833) - "UTILITY", // 576 (834) - "UUID4", // 577 (835) - "UVALID", // 578 (836) - "UWIDTH", // 579 (837) - "VALIDATING", // 580 (838) - "VALUE", // 581 (839) - "VARIANCE", // 582 (840) - "VARYING", // 583 (841) - "VOLATILE", // 584 (842) - "WHEN-COMPILED", // 585 (843) - "WITH", // 586 (844) - "WORKING-STORAGE", // 587 (845) - "YEAR-TO-YYYY", // 588 (846) - "YYYYDDD", // 589 (847) - "YYYYMMDD", // 590 (848) - "ARITHMETIC", // 591 (849) - "ATTRIBUTE", // 592 (850) - "AUTO", // 593 (851) - "AUTOMATIC", // 594 (852) - "AWAY-FROM-ZERO", // 595 (853) - "BACKGROUND-COLOR", // 596 (854) - "BELL", // 597 (855) - "BINARY-ENCODING", // 598 (856) - "BLINK", // 599 (857) - "CAPACITY", // 600 (858) - "CENTER", // 601 (859) - "CLASSIFICATION", // 602 (860) - "CYCLE", // 603 (861) - "DECIMAL-ENCODING", // 604 (862) - "ENTRY-CONVENTION", // 605 (863) - "EOL", // 606 (864) - "EOS", // 607 (865) - "ERASE", // 608 (866) - "EXPANDS", // 609 (867) - "FLOAT-BINARY", // 610 (868) - "FLOAT-DECIMAL", // 611 (869) - "FOREGROUND-COLOR", // 612 (870) - "FOREVER", // 613 (871) - "FULL", // 614 (872) - "HIGHLIGHT", // 615 (873) - "HIGH-ORDER-LEFT", // 616 (874) - "HIGH-ORDER-RIGHT", // 617 (875) - "IGNORING", // 618 (876) - "IMPLEMENTS", // 619 (877) - "INITIALIZED", // 620 (878) - "INTERMEDIATE", // 621 (879) - "LC-ALL", // 622 (880) - "LC-COLLATE", // 623 (881) - "LC-CTYPE", // 624 (882) - "LC-MESSAGES", // 625 (883) - "LC-MONETARY", // 626 (884) - "LC-NUMERIC", // 627 (885) - "LC-TIME", // 628 (886) - "LOWLIGHT", // 629 (887) - "NEAREST-AWAY-FROM-ZERO", // 630 (888) - "NEAREST-EVEN", // 631 (889) - "NEAREST-TOWARD-ZERO", // 632 (890) - "NONE", // 633 (891) - "NORMAL", // 634 (892) - "NUMBERS", // 635 (893) - "PREFIXED", // 636 (894) - "PREVIOUS", // 637 (895) - "PROHIBITED", // 638 (896) - "RELATION", // 639 (897) - "REQUIRED", // 640 (898) - "REVERSE-VIDEO", // 641 (899) - "ROUNDING", // 642 (900) - "SECONDS", // 643 (901) - "SECURE", // 644 (902) - "SHORT", // 645 (903) - "SIGNED", // 646 (904) - "STANDARD-BINARY", // 647 (905) - "STANDARD-DECIMAL", // 648 (906) - "STATEMENT", // 649 (907) - "STEP", // 650 (908) - "STRUCTURE", // 651 (909) - "TOWARD-GREATER", // 652 (910) - "TOWARD-LESSER", // 653 (911) - "TRUNCATION", // 654 (912) - "UCS-4", // 655 (913) - "UNDERLINE", // 656 (914) - "UNSIGNED", // 657 (915) - "UTF-16", // 658 (916) - "UTF-8", // 659 (917) - "ADDRESS", // 660 (918) - "END-ACCEPT", // 661 (919) - "END-ADD", // 662 (920) - "END-CALL", // 663 (921) - "END-COMPUTE", // 664 (922) - "END-DELETE", // 665 (923) - "END-DISPLAY", // 666 (924) - "END-DIVIDE", // 667 (925) - "END-EVALUATE", // 668 (926) - "END-MULTIPLY", // 669 (927) - "END-PERFORM", // 670 (928) - "END-READ", // 671 (929) - "END-RETURN", // 672 (930) - "END-REWRITE", // 673 (931) - "END-SEARCH", // 674 (932) - "END-START", // 675 (933) - "END-STRING", // 676 (934) - "END-SUBTRACT", // 677 (935) - "END-UNSTRING", // 678 (936) - "END-WRITE", // 679 (937) - "END-XML", // 680 (938) - "END-IF", // 681 (939) - "XMLGENERATE", // 682 (940) - "XMLPARSE", // 684 (942) - "ATTRIBUTES", // 686 (944) - "ELEMENT", // 687 (945) - "NAMESPACE", // 688 (946) - "NAMESPACE-PREFIX", // 689 (947) - "NONNUMERIC", // 691 (949) - "XML-DECLARATION", // 692 (950) - "THRU", // 694 (952) - "OR", // 695 (953) - "AND", // 696 (954) - "NOT", // 697 (955) - "NE", // 698 (956) - "LE", // 699 (957) - "GE", // 700 (958) - "POW", // 701 (959) - "NEG", // 702 (960) + "TALLYING", // 535 (793) + "TAN", // 536 (794) + "TERMINATE", // 537 (795) + "TEST", // 538 (796) + "TEST-DATE-YYYYMMDD", // 539 (797) + "TEST-DAY-YYYYDDD", // 540 (798) + "TEST-FORMATTED-DATETIME", // 541 (799) + "TEST-NUMVAL", // 542 (800) + "TEST-NUMVAL-C", // 543 (801) + "TEST-NUMVAL-F", // 544 (802) + "THAN", // 545 (803) + "TIME", // 546 (804) + "TIMES", // 547 (805) + "TO", // 548 (806) + "TOP", // 549 (807) + "TOP-LEVEL", // 550 (808) + "TRACKS", // 551 (809) + "TRACK-AREA", // 552 (810) + "TRAILING", // 553 (811) + "TRANSFORM", // 554 (812) + "TRIM", // 555 (813) + "TRUE", // 556 (814) + "TRY", // 557 (815) + "TURN", // 558 (816) + "TYPE", // 559 (817) + "TYPEDEF", // 560 (818) + "ULENGTH", // 561 (819) + "UNBOUNDED", // 562 (820) + "UNIT", // 563 (821) + "UNITS", // 564 (822) + "UNIT-RECORD", // 565 (823) + "UNTIL", // 566 (824) + "UP", // 567 (825) + "UPON", // 568 (826) + "UPOS", // 569 (827) + "UPPER-CASE", // 570 (828) + "USAGE", // 571 (829) + "USING", // 572 (830) + "USUBSTR", // 573 (831) + "USUPPLEMENTARY", // 574 (832) + "UTILITY", // 575 (833) + "UUID4", // 576 (834) + "UVALID", // 577 (835) + "UWIDTH", // 578 (836) + "VALIDATING", // 579 (837) + "VALUE", // 580 (838) + "VARIANCE", // 581 (839) + "VARYING", // 582 (840) + "VOLATILE", // 583 (841) + "WHEN-COMPILED", // 584 (842) + "WITH", // 585 (843) + "WORKING-STORAGE", // 586 (844) + "YEAR-TO-YYYY", // 587 (845) + "YYYYDDD", // 588 (846) + "YYYYMMDD", // 589 (847) + "ARITHMETIC", // 590 (848) + "ATTRIBUTE", // 591 (849) + "AUTO", // 592 (850) + "AUTOMATIC", // 593 (851) + "AWAY-FROM-ZERO", // 594 (852) + "BACKGROUND-COLOR", // 595 (853) + "BELL", // 596 (854) + "BINARY-ENCODING", // 597 (855) + "BLINK", // 598 (856) + "CAPACITY", // 599 (857) + "CENTER", // 600 (858) + "CLASSIFICATION", // 601 (859) + "CYCLE", // 602 (860) + "DECIMAL-ENCODING", // 603 (861) + "ENTRY-CONVENTION", // 604 (862) + "EOL", // 605 (863) + "EOS", // 606 (864) + "ERASE", // 607 (865) + "EXPANDS", // 608 (866) + "FLOAT-BINARY", // 609 (867) + "FLOAT-DECIMAL", // 610 (868) + "FOREGROUND-COLOR", // 611 (869) + "FOREVER", // 612 (870) + "FULL", // 613 (871) + "HIGHLIGHT", // 614 (872) + "HIGH-ORDER-LEFT", // 615 (873) + "HIGH-ORDER-RIGHT", // 616 (874) + "IGNORING", // 617 (875) + "IMPLEMENTS", // 618 (876) + "INITIALIZED", // 619 (877) + "INTERMEDIATE", // 620 (878) + "LC-ALL", // 621 (879) + "LC-COLLATE", // 622 (880) + "LC-CTYPE", // 623 (881) + "LC-MESSAGES", // 624 (882) + "LC-MONETARY", // 625 (883) + "LC-NUMERIC", // 626 (884) + "LC-TIME", // 627 (885) + "LOWLIGHT", // 628 (886) + "NEAREST-AWAY-FROM-ZERO", // 629 (887) + "NEAREST-EVEN", // 630 (888) + "NEAREST-TOWARD-ZERO", // 631 (889) + "NONE", // 632 (890) + "NORMAL", // 633 (891) + "NUMBERS", // 634 (892) + "PREFIXED", // 635 (893) + "PREVIOUS", // 636 (894) + "PROHIBITED", // 637 (895) + "RELATION", // 638 (896) + "REQUIRED", // 639 (897) + "REVERSE-VIDEO", // 640 (898) + "ROUNDING", // 641 (899) + "SECONDS", // 642 (900) + "SECURE", // 643 (901) + "SHORT", // 644 (902) + "SIGNED", // 645 (903) + "STANDARD-BINARY", // 646 (904) + "STANDARD-DECIMAL", // 647 (905) + "STATEMENT", // 648 (906) + "STEP", // 649 (907) + "STRUCTURE", // 650 (908) + "TOWARD-GREATER", // 651 (909) + "TOWARD-LESSER", // 652 (910) + "TRUNCATION", // 653 (911) + "UCS-4", // 654 (912) + "UNDERLINE", // 655 (913) + "UNSIGNED", // 656 (914) + "UTF-16", // 657 (915) + "UTF-8", // 658 (916) + "XMLGENERATE", // 659 (917) + "XMLPARSE", // 660 (918) + "ADDRESS", // 661 (919) + "END-ACCEPT", // 662 (920) + "END-ADD", // 663 (921) + "END-CALL", // 664 (922) + "END-COMPUTE", // 665 (923) + "END-DELETE", // 666 (924) + "END-DISPLAY", // 667 (925) + "END-DIVIDE", // 668 (926) + "END-EVALUATE", // 669 (927) + "END-MULTIPLY", // 670 (928) + "END-PERFORM", // 671 (929) + "END-READ", // 672 (930) + "END-RETURN", // 673 (931) + "END-REWRITE", // 674 (932) + "END-SEARCH", // 675 (933) + "END-START", // 676 (934) + "END-STRING", // 677 (935) + "END-SUBTRACT", // 678 (936) + "END-UNSTRING", // 679 (937) + "END-WRITE", // 680 (938) + "END-XML", // 681 (939) + "END-IF", // 682 (940) + "ATTRIBUTES", // 683 (941) + "ELEMENT", // 684 (942) + "NAMESPACE", // 685 (943) + "NAMESPACE-PREFIX", // 686 (944) + "NONNUMERIC", // 688 (946) + "XML-DECLARATION", // 689 (947) + "THRU", // 691 (949) + "OR", // 692 (950) + "AND", // 693 (951) + "NOT", // 694 (952) + "NE", // 695 (953) + "LE", // 696 (954) + "GE", // 697 (955) + "POW", // 698 (956) + "NEG", // 699 (957) }; diff --git a/gcc/cobol/util.cc b/gcc/cobol/util.cc index d3a4b01..9615987 100644 --- a/gcc/cobol/util.cc +++ b/gcc/cobol/util.cc @@ -2107,28 +2107,35 @@ void current_location_minus_one_clear() first_line_minus_1 = 0; } +/* + * Update global token_location with a location_t expressing a source range + * with start and caret at the first line/column of LOC, and finishing at the + * last line/column of LOC. + */ template <typename LOC> static void gcc_location_set_impl( const LOC& loc ) { // Set the position to the first line & column in the location. static location_t loc_m_1 = 0; - - token_location = linemap_line_start( line_table, loc.first_line, 80 ); - token_location = linemap_position_for_column( line_table, loc.first_column); - - if( loc.first_line > first_line_minus_1 ) - { - // In order for GDB-COBOL to be able to step through COBOL code properly, - // it is sometimes necessary for the code at the beginning of a COBOL - // line to be using the location_t of the previous line. This is true, for - // example, when laying down the infrastructure code between the last - // statement of a paragraph and the code created at the beginning of the - // following paragragh. This code assumes that token_location values of - // interest are monotonic, and stores that prior value. - first_line_minus_1 = loc.first_line; - token_location_minus_1 = loc_m_1; - loc_m_1 = token_location; - } + const location_t + start_line = linemap_line_start( line_table, loc.first_line, 80 ), + token_start = linemap_position_for_column( line_table, loc.first_column), + finish_line = linemap_line_start( line_table, loc.last_line, 80 ), + token_finish = linemap_position_for_column( line_table, loc.last_column); + token_location = make_location (token_start, token_start, token_finish); + + if( loc.first_line > first_line_minus_1 ) { + // In order for GDB-COBOL to be able to step through COBOL code properly, + // it is sometimes necessary for the code at the beginning of a COBOL + // line to be using the location_t of the previous line. This is true, for + // example, when laying down the infrastructure code between the last + // statement of a paragraph and the code created at the beginning of the + // following paragragh. This code assumes that token_location values of + // interest are monotonic, and stores that prior value. + first_line_minus_1 = loc.first_line; + token_location_minus_1 = loc_m_1; + loc_m_1 = token_location; + } location_dump(__func__, __LINE__, "parser", loc); } diff --git a/gcc/config/aarch64/aarch64-c.cc b/gcc/config/aarch64/aarch64-c.cc index a8ff58e..c3957c7 100644 --- a/gcc/config/aarch64/aarch64-c.cc +++ b/gcc/config/aarch64/aarch64-c.cc @@ -296,6 +296,10 @@ aarch64_update_cpp_builtins (cpp_reader *pfile) "__ARM_FEATURE_SME2p1", pfile); aarch64_def_or_undef (TARGET_FAMINMAX, "__ARM_FEATURE_FAMINMAX", pfile); + // Function multi-versioning defines + aarch64_def_or_undef (targetm.has_ifunc_p (), + "__HAVE_FUNCTION_MULTI_VERSIONING", pfile); + /* Not for ACLE, but required to keep "float.h" correct if we switch target between implementations that do or do not support ARMv8.2-A 16-bit floating-point extensions. */ diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index b860641..6f6dea6 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -20607,14 +20607,8 @@ static int compare_feature_masks (aarch64_fmv_feature_mask mask1, aarch64_fmv_feature_mask mask2) { - int pop1 = popcount_hwi (mask1); - int pop2 = popcount_hwi (mask2); - if (pop1 > pop2) - return 1; - if (pop2 > pop1) - return -1; - auto diff_mask = mask1 ^ mask2; + /* If there is no difference. */ if (diff_mask == 0ULL) return 0; int num_features = ARRAY_SIZE (aarch64_fmv_feature_data); @@ -21029,45 +21023,16 @@ dispatch_function_versions (tree dispatch_decl, unsigned int num_versions = fndecls->length (); gcc_assert (num_versions >= 2); - struct function_version_info - { - tree version_decl; - aarch64_fmv_feature_mask feature_mask; - } *function_versions; - - function_versions = (struct function_version_info *) - XNEWVEC (struct function_version_info, (num_versions)); - - unsigned int actual_versions = 0; - - for (tree version_decl : *fndecls) + int i; + tree version_decl; + FOR_EACH_VEC_ELT_REVERSE ((*fndecls), i, version_decl) { - aarch64_fmv_feature_mask feature_mask; - /* Get attribute string, parse it and find the right features. */ - feature_mask = get_feature_mask_for_version (version_decl); - function_versions [actual_versions].version_decl = version_decl; - function_versions [actual_versions].feature_mask = feature_mask; - actual_versions++; + aarch64_fmv_feature_mask feature_mask + = get_feature_mask_for_version (version_decl); + *empty_bb = add_condition_to_bb (dispatch_decl, version_decl, + feature_mask, mask_var, *empty_bb); } - auto compare_feature_version_info = [](const void *p1, const void *p2) { - const function_version_info v1 = *(const function_version_info *)p1; - const function_version_info v2 = *(const function_version_info *)p2; - return - compare_feature_masks (v1.feature_mask, v2.feature_mask); - }; - - /* Sort the versions according to descending order of dispatch priority. */ - qsort (function_versions, actual_versions, - sizeof (struct function_version_info), compare_feature_version_info); - - for (unsigned int i = 0; i < actual_versions; ++i) - *empty_bb = add_condition_to_bb (dispatch_decl, - function_versions[i].version_decl, - function_versions[i].feature_mask, - mask_var, - *empty_bb); - - free (function_versions); return 0; } @@ -21109,6 +21074,9 @@ aarch64_generate_version_dispatcher_body (void *node_p) auto_vec<tree, 2> fn_ver_vec; + if (dump_enabled_p ()) + dump_printf (MSG_NOTE, "Version order for %s:\n", node->dump_asm_name ()); + for (versn_info = node_version_info->next; versn_info; versn_info = versn_info->next) { @@ -21121,6 +21089,9 @@ aarch64_generate_version_dispatcher_body (void *node_p) if (DECL_VINDEX (versn->decl)) sorry ("virtual function multiversioning not supported"); + if (dump_enabled_p ()) + dump_printf (MSG_NOTE, "%s\n", versn->dump_asm_name ()); + fn_ver_vec.safe_push (versn->decl); } diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index b1918c4..5eba992 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -569,6 +569,18 @@ (V16SI "TARGET_AVX512F") (V8SI "TARGET_AVX2") V4SI (V8DI "TARGET_AVX512F") (V4DI "TARGET_AVX2") V2DI]) +(define_mode_iterator VI_AVX + [(V32QI "TARGET_AVX") V16QI + (V16HI "TARGET_AVX") V8HI + (V8SI "TARGET_AVX") V4SI + (V4DI "TARGET_AVX") V2DI]) + +(define_mode_iterator VI_AVX2_CMP + [(V32QI "TARGET_AVX2") V16QI + (V16HI "TARGET_AVX2") V8HI + (V8SI "TARGET_AVX2") V4SI + (V4DI "TARGET_AVX2") V2DI]) + (define_mode_iterator VI_AVX_AVX512F [(V64QI "TARGET_AVX512F") (V32QI "TARGET_AVX") V16QI (V32HI "TARGET_AVX512F") (V16HI "TARGET_AVX") V8HI @@ -896,7 +908,8 @@ (define_mode_attr ssebytemode [(V8DI "V64QI") (V4DI "V32QI") (V2DI "V16QI") (V16SI "V64QI") (V8SI "V32QI") (V4SI "V16QI") - (V8HI "V16QI")]) + (V16HI "V32QI") (V8HI "V16QI") + (V32QI "V32QI") (V16QI "V16QI")]) (define_mode_attr sseintconvert [(V32HI "w") (V16HI "w") (V8HI "w") @@ -4095,6 +4108,88 @@ DONE; }) +(define_expand "reduc_sbool_and_scal_<mode>" + [(match_operand:QI 0 "register_operand") + (match_operand:VI_AVX 1 "register_operand")] + "TARGET_SSE4_1" +{ + rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG); + rtx op2, tmp; + if (TARGET_AVX2 || <MODE_SIZE> != 32) + { + op2 = force_reg (<MODE>mode, CONST0_RTX (<MODE>mode)); + tmp = gen_reg_rtx (<MODE>mode); + rtx op1 = gen_rtx_EQ (<MODE>mode, operands[1], op2); + emit_insn (gen_vec_cmp<mode><mode> (tmp, op1, operands[1], op2)); + } + else + { + op2 = force_reg (<MODE>mode, CONSTM1_RTX (<MODE>mode)); + tmp = gen_reg_rtx (<MODE>mode); + rtx ops[3] = { tmp, operands[1], op2 }; + ix86_expand_vector_logical_operator (XOR, <MODE>mode, ops); + } + + tmp = gen_rtx_UNSPEC (CCZmode, gen_rtvec(2, tmp, tmp), UNSPEC_PTEST); + emit_insn (gen_rtx_SET (flags, tmp)); + rtx ret = gen_rtx_fmt_ee (EQ, VOIDmode, flags, const0_rtx); + PUT_MODE (ret, QImode); + emit_insn (gen_rtx_SET (operands[0], ret)); + DONE; + +}) + +(define_expand "reduc_sbool_ior_scal_<mode>" + [(match_operand:QI 0 "register_operand") + (match_operand:VI_AVX 1 "register_operand")] + "TARGET_SSE4_1" +{ + rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG); + rtx tmp = gen_rtx_UNSPEC (CCZmode, gen_rtvec(2, operands[1], operands[1]), UNSPEC_PTEST); + emit_insn (gen_rtx_SET (flags, tmp)); + rtx ret = gen_rtx_fmt_ee (NE, VOIDmode, flags, const0_rtx); + PUT_MODE (ret, QImode); + emit_insn (gen_rtx_SET (operands[0], ret)); + DONE; +}) + +(define_expand "reduc_sbool_xor_scal_<mode>" + [(match_operand:QI 0 "register_operand") + (match_operand:VI1_AVX2 1 "register_operand")] + "TARGET_SSE2 && TARGET_POPCNT" +{ + rtx popcnt1 = gen_reg_rtx (SImode); + emit_insn (gen_<sse2_avx2>_pmovmskb (popcnt1,operands[1])); + + emit_insn (gen_popcountsi2 (popcnt1, popcnt1)); + emit_insn (gen_andsi3 (popcnt1, popcnt1, GEN_INT (0x1))); + + emit_move_insn (operands[0], gen_lowpart (QImode, popcnt1)); + DONE; +}) + +(define_mode_attr ssefltvecmode + [(V2DI "V2DF") (V4DI "V4DF") (V4SI "V4SF") (V8SI "V8SF")]) + +(define_expand "reduc_sbool_xor_scal_<mode>" + [(match_operand:QI 0 "register_operand") + (match_operand:VI48_AVX 1 "register_operand")] + "TARGET_SSE2 && TARGET_POPCNT" +{ + rtx popcnt1 = gen_reg_rtx (SImode); + rtx tmp = gen_rtx_UNSPEC (SImode, gen_rtvec(1, + gen_lowpart (<ssefltvecmode>mode, + operands[1])), + UNSPEC_MOVMSK); + emit_insn (gen_rtx_SET (popcnt1, tmp)); + + emit_insn (gen_popcountsi2 (popcnt1, popcnt1)); + emit_insn (gen_andsi3 (popcnt1, popcnt1, GEN_INT (0x1))); + + emit_move_insn (operands[0], gen_lowpart (QImode, popcnt1)); + DONE; +}) + (define_insn "<mask_codefor>reducep<mode><mask_name><round_saeonly_name>" [(set (match_operand:VFH_AVX512VL 0 "register_operand" "=v") (unspec:VFH_AVX512VL @@ -18084,6 +18179,24 @@ (set_attr "prefix" "vex") (set_attr "mode" "OI")]) +(define_insn_and_split "*eq<mode>3_2_negate" + [(set (match_operand:VI_AVX2_CMP 0 "register_operand") + (eq:VI_AVX2_CMP + (eq:VI_AVX2_CMP + (eq: VI_AVX2_CMP + (match_operand:VI_AVX2_CMP 1 "nonimmediate_operand") + (match_operand:VI_AVX2_CMP 2 "general_operand")) + (match_operand:VI_AVX2_CMP 3 "const0_operand")) + (match_operand:VI_AVX2_CMP 4 "const0_operand")))] + "TARGET_SSE4_1 && ix86_pre_reload_split ()" + "#" + "&& 1" + [(set (match_dup 0) + (eq:VI_AVX2_CMP (match_dup 1) + (match_dup 5)))] + "operands[5] = force_reg (<MODE>mode, operands[2]);") + + (define_insn_and_split "*avx2_pcmp<mode>3_1" [(set (match_operand:VI_128_256 0 "register_operand") (vec_merge:VI_128_256 @@ -23774,9 +23887,6 @@ (set_attr "btver2_decode" "vector,vector,vector") (set_attr "mode" "<MODE>")]) -(define_mode_attr ssefltvecmode - [(V2DI "V2DF") (V4DI "V4DF") (V4SI "V4SF") (V8SI "V8SF")]) - (define_insn_and_split "*<sse4_1>_blendv<ssefltmodesuffix><avxsizesuffix>_ltint" [(set (match_operand:<ssebytemode> 0 "register_operand" "=Yr,*x,x") (unspec:<ssebytemode> @@ -25591,6 +25701,36 @@ (match_dup 0) (pc)))]) + +;; (unspec:ccz [(eq (eq op0 const0) const0)] unspec_ptest) +;; is equal to (unspec:ccz [op0 op0] unspec_ptest). +(define_insn_and_split "*ptest<mode>_ccz" + [(set (reg:CCZ FLAGS_REG) + (unspec:CCZ + [(eq:VI_AVX + (eq:VI_AVX + (match_operand:VI_AVX 0 "vector_operand") + (match_operand:VI_AVX 1 "const0_operand")) + (match_operand:VI_AVX 2 "const0_operand")) + (eq:VI_AVX + (eq:VI_AVX (match_dup 0) (match_dup 1)) + (match_dup 2))] + UNSPEC_PTEST))] + "TARGET_SSE4_1 + && ix86_pre_reload_split ()" + "#" + "&& 1" + [(set (reg:CCZ FLAGS_REG) + (unspec:CCZ + [(match_dup 3) (match_dup 3)] + UNSPEC_PTEST))] +{ + if (MEM_P (operands[0])) + operands[3] = force_reg (<MODE>mode, operands[0]); + else + operands[3] = operands[0]; +}) + (define_expand "nearbyint<mode>2" [(set (match_operand:VFH 0 "register_operand") (unspec:VFH diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc index e8cfee8..1311c6e 100644 --- a/gcc/fold-const.cc +++ b/gcc/fold-const.cc @@ -151,74 +151,89 @@ static tree fold_view_convert_expr (tree, tree); static tree fold_negate_expr (location_t, tree); /* This is a helper function to detect min/max for some operands of COND_EXPR. + The form is "(exp0 CMP cst1) ? exp0 : cst2". */ +tree_code +minmax_from_comparison (tree_code cmp, tree exp0, + const widest_int cst1, + const widest_int cst2) +{ + if (cst1 == cst2) + { + if (cmp == LE_EXPR || cmp == LT_EXPR) + return MIN_EXPR; + if (cmp == GT_EXPR || cmp == GE_EXPR) + return MAX_EXPR; + } + if (cst1 == cst2 - 1) + { + /* X <= Y - 1 equals to X < Y. */ + if (cmp == LE_EXPR) + return MIN_EXPR; + /* X > Y - 1 equals to X >= Y. */ + if (cmp == GT_EXPR) + return MAX_EXPR; + /* a != MIN_RANGE<a> ? a : MIN_RANGE<a>+1 -> MAX_EXPR<MIN_RANGE<a>+1, a> */ + if (cmp == NE_EXPR && TREE_CODE (exp0) == SSA_NAME) + { + int_range_max r; + get_range_query (cfun)->range_of_expr (r, exp0); + if (r.undefined_p ()) + r.set_varying (TREE_TYPE (exp0)); + + widest_int min = widest_int::from (r.lower_bound (), + TYPE_SIGN (TREE_TYPE (exp0))); + if (min == cst1) + return MAX_EXPR; + } + } + if (cst1 == cst2 + 1) + { + /* X < Y + 1 equals to X <= Y. */ + if (cmp == LT_EXPR) + return MIN_EXPR; + /* X >= Y + 1 equals to X > Y. */ + if (cmp == GE_EXPR) + return MAX_EXPR; + /* a != MAX_RANGE<a> ? a : MAX_RANGE<a>-1 -> MIN_EXPR<MIN_RANGE<a>-1, a> */ + if (cmp == NE_EXPR && TREE_CODE (exp0) == SSA_NAME) + { + int_range_max r; + get_range_query (cfun)->range_of_expr (r, exp0); + if (r.undefined_p ()) + r.set_varying (TREE_TYPE (exp0)); + + widest_int max = widest_int::from (r.upper_bound (), + TYPE_SIGN (TREE_TYPE (exp0))); + if (max == cst1) + return MIN_EXPR; + } + } + return ERROR_MARK; +} + + +/* This is a helper function to detect min/max for some operands of COND_EXPR. The form is "(EXP0 CMP EXP1) ? EXP2 : EXP3". */ tree_code minmax_from_comparison (tree_code cmp, tree exp0, tree exp1, tree exp2, tree exp3) { - enum tree_code code = ERROR_MARK; - if (HONOR_NANS (exp0) || HONOR_SIGNED_ZEROS (exp0)) return ERROR_MARK; if (!operand_equal_p (exp0, exp2)) return ERROR_MARK; - if (TREE_CODE (exp3) == INTEGER_CST && TREE_CODE (exp1) == INTEGER_CST) - { - if (wi::to_widest (exp1) == (wi::to_widest (exp3) - 1)) - { - /* X <= Y - 1 equals to X < Y. */ - if (cmp == LE_EXPR) - code = LT_EXPR; - /* X > Y - 1 equals to X >= Y. */ - if (cmp == GT_EXPR) - code = GE_EXPR; - /* a != MIN_RANGE<a> ? a : MIN_RANGE<a>+1 -> MAX_EXPR<MIN_RANGE<a>+1, a> */ - if (cmp == NE_EXPR && TREE_CODE (exp0) == SSA_NAME) - { - int_range_max r; - get_range_query (cfun)->range_of_expr (r, exp0); - if (r.undefined_p ()) - r.set_varying (TREE_TYPE (exp0)); - - widest_int min = widest_int::from (r.lower_bound (), - TYPE_SIGN (TREE_TYPE (exp0))); - if (min == wi::to_widest (exp1)) - code = MAX_EXPR; - } - } - if (wi::to_widest (exp1) == (wi::to_widest (exp3) + 1)) - { - /* X < Y + 1 equals to X <= Y. */ - if (cmp == LT_EXPR) - code = LE_EXPR; - /* X >= Y + 1 equals to X > Y. */ - if (cmp == GE_EXPR) - code = GT_EXPR; - /* a != MAX_RANGE<a> ? a : MAX_RANGE<a>-1 -> MIN_EXPR<MIN_RANGE<a>-1, a> */ - if (cmp == NE_EXPR && TREE_CODE (exp0) == SSA_NAME) - { - int_range_max r; - get_range_query (cfun)->range_of_expr (r, exp0); - if (r.undefined_p ()) - r.set_varying (TREE_TYPE (exp0)); - - widest_int max = widest_int::from (r.upper_bound (), - TYPE_SIGN (TREE_TYPE (exp0))); - if (max == wi::to_widest (exp1)) - code = MIN_EXPR; - } - } - } - if (code != ERROR_MARK - || operand_equal_p (exp1, exp3)) + if (operand_equal_p (exp1, exp3)) { if (cmp == LT_EXPR || cmp == LE_EXPR) - code = MIN_EXPR; + return MIN_EXPR; if (cmp == GT_EXPR || cmp == GE_EXPR) - code = MAX_EXPR; + return MAX_EXPR; } - return code; + if (TREE_CODE (exp3) == INTEGER_CST + && TREE_CODE (exp1) == INTEGER_CST) + return minmax_from_comparison (cmp, exp0, wi::to_widest (exp1), wi::to_widest (exp3)); + return ERROR_MARK; } /* Return EXPR_LOCATION of T if it is not UNKNOWN_LOCATION. diff --git a/gcc/fold-const.h b/gcc/fold-const.h index e95cf48..00975dc 100644 --- a/gcc/fold-const.h +++ b/gcc/fold-const.h @@ -254,6 +254,9 @@ extern tree fold_build_pointer_plus_hwi_loc (location_t loc, tree ptr, HOST_WIDE #define fold_build_pointer_plus_hwi(p,o) \ fold_build_pointer_plus_hwi_loc (UNKNOWN_LOCATION, p, o) +extern tree_code minmax_from_comparison (tree_code, tree, + const widest_int, + const widest_int); extern tree_code minmax_from_comparison (tree_code, tree, tree, tree, tree); diff --git a/gcc/match.pd b/gcc/match.pd index a4248a5..4c05fe2 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -794,6 +794,27 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (rdiv @0 (negate @1)) (rdiv (negate @0) @1)) +/* convert semantics of round(x) function to floor(x+0.5). */ +/* (x-floor(x)) < (ceil(x)-x) ? floor(x) : ceil(x) --> floor(x+0.5). */ +/* (x-floor(x)) >= (ceil(x)-x) ? ceil(x) : floor(x) --> floor(x+0.5). */ +/* (ceil(x)-x) > (x-floor(x)) ? floor(x) : ceil(x) --> floor(x+0.5). */ +/* (ceil(x)-x) <= (x-floor(x)) ? ceil(x) : floor(x) --> floor(x+0.5). */ +(for op (lt lt lt lt ge ge ge ge) + bt (BUILT_IN_FLOORF BUILT_IN_FLOOR BUILT_IN_FLOORL IFN_FLOOR + BUILT_IN_CEILF BUILT_IN_CEIL BUILT_IN_CEILL IFN_CEIL) + bf (BUILT_IN_CEILF BUILT_IN_CEIL BUILT_IN_CEILL IFN_CEIL + BUILT_IN_FLOORF BUILT_IN_FLOOR BUILT_IN_FLOORL IFN_FLOOR) + floor (BUILT_IN_FLOORF BUILT_IN_FLOOR BUILT_IN_FLOORL IFN_FLOOR + BUILT_IN_FLOORF BUILT_IN_FLOOR BUILT_IN_FLOORL IFN_FLOOR) + ceil (BUILT_IN_CEILF BUILT_IN_CEIL BUILT_IN_CEILL IFN_CEIL + BUILT_IN_CEILF BUILT_IN_CEIL BUILT_IN_CEILL IFN_CEIL) + (simplify + (cond (op:c (minus:s SSA_NAME@0 (floor SSA_NAME@0)) + (minus:s (ceil SSA_NAME@0) SSA_NAME@0)) + (bt SSA_NAME@0) (bf SSA_NAME@0)) + (if (!HONOR_SIGNED_ZEROS (type) && !HONOR_SIGN_DEPENDENT_ROUNDING (type)) + (floor (plus @0 { build_real (type, dconsthalf); }))))) + (if (flag_unsafe_math_optimizations) /* Simplify (C / x op 0.0) to x op 0.0 for C != 0, C != Inf/Nan. Since C / x may underflow to zero, do this only for unsafe math. */ @@ -6571,25 +6592,30 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) tree from_type = TREE_TYPE (@1); tree c1_type = TREE_TYPE (@3), c2_type = TREE_TYPE (@2); enum tree_code code = ERROR_MARK; - enum tree_code ncmp = cmp; - tree c1 = @3; /* `((signed)a) < 0` should be converted back into `a >= (unsigned)SIGNED_TYPE_MIN`. `((signed)a) >= 0` should be converted back into `a < (unsigned)SIGNED_TYPE_MIN`. */ - if (integer_zerop (c1) + if (integer_zerop (@3) + && INTEGRAL_TYPE_P (from_type) && (cmp == GE_EXPR || cmp == LT_EXPR) && TYPE_UNSIGNED (from_type) && !TYPE_UNSIGNED (c1_type) - && TYPE_PRECISION (from_type) == TYPE_PRECISION (c1_type)) + && TYPE_PRECISION (from_type) == TYPE_PRECISION (c1_type) + && int_fits_type_p (@2, from_type) + && (types_match (c2_type, from_type) + || (TYPE_PRECISION (c2_type) > TYPE_PRECISION (from_type) + && (TYPE_UNSIGNED (from_type) + || TYPE_SIGN (c2_type) == TYPE_SIGN (from_type))))) { - ncmp = cmp == GE_EXPR ? LT_EXPR : GE_EXPR; - c1 = fold_convert (from_type, TYPE_MIN_VALUE (c1_type)); - c1_type = from_type; + tree_code ncmp = cmp == GE_EXPR ? LE_EXPR : GT_EXPR; + widest_int c1 = wi::mask<widest_int>(TYPE_PRECISION (type) - 1, 0); + code = minmax_from_comparison (ncmp, @1, c1, wi::to_widest (@2)); } - if (INTEGRAL_TYPE_P (from_type) + if (code == ERROR_MARK + && INTEGRAL_TYPE_P (from_type) && int_fits_type_p (@2, from_type) && (types_match (c1_type, from_type) || (TYPE_PRECISION (c1_type) > TYPE_PRECISION (from_type) @@ -6600,8 +6626,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) && (TYPE_UNSIGNED (from_type) || TYPE_SIGN (c2_type) == TYPE_SIGN (from_type))))) { - if (ncmp != EQ_EXPR) - code = minmax_from_comparison (ncmp, @1, c1, @1, @2); + if (cmp != EQ_EXPR) + code = minmax_from_comparison (cmp, @1, @3, @1, @2); /* Can do A == C1 ? A : C2 -> A == C1 ? C1 : C2? */ else if (int_fits_type_p (@3, from_type)) code = EQ_EXPR; @@ -6911,6 +6937,35 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) && integer_nonzerop (fold_build2 (GE_EXPR, boolean_type_node, @3, @4))) (max @2 @4)))))) +/* Optimize (((signed)a CMP 0) ? max<a,CST2> : CST3 */ +(for cmp (lt ge) + minmax (min max) + (simplify + (cond (cmp:c (nop_convert @0) integer_zerop@1) (minmax@2 @0 INTEGER_CST@3) INTEGER_CST@4) + (if (!TYPE_UNSIGNED (TREE_TYPE (@1)) + && TYPE_UNSIGNED (TREE_TYPE (@0))) + (with + { + tree_code code; + /* ((signed)a) < 0 -> a > SIGNED_MAX */ + /* ((signed)a) >= 0 -> a <= SIGNED_MAX */ + widest_int c1 = wi::mask<widest_int>(TYPE_PRECISION (type) - 1, 0); + tree_code ncmp = cmp == GE_EXPR ? LE_EXPR : GT_EXPR; + code = minmax_from_comparison (ncmp, @0, c1, wi::to_widest (@4)); + } + (if (ncmp == LE_EXPR + && code == MIN_EXPR + && wi::le_p (wi::to_wide (@3), + wi::to_wide (@4), + TYPE_SIGN (type))) + (min @2 @4) + (if (ncmp == GT_EXPR + && code == MAX_EXPR + && wi::ge_p (wi::to_wide (@3), + wi::to_wide (@4), + TYPE_SIGN (type))) + (max @2 @4))))))) + #if GIMPLE /* These patterns should be after min/max detection as simplifications of `(type)(zero_one ==/!= 0)` to `(type)(zero_one)` diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index eb21078..65fa7fa 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,79 @@ +2025-10-23 Robert Dubner <rdubner@symas.com> + + * cobol.dg/group2/Length_overflow__2_.out: Updated test result. + * cobol.dg/group2/Length_overflow_with_offset__1_.out: Likewise. + * cobol.dg/group2/Offset_overflow.out: Likewise. + * cobol.dg/group2/CALL_with_OCCURS_DEPENDING_ON.cob: New test. + * cobol.dg/group2/CALL_with_OCCURS_DEPENDING_ON.out: New test. + * cobol.dg/group2/CHAR_and_ORD_with_COLLATING_sequence_-_ASCII.cob: New test. + * cobol.dg/group2/CHAR_and_ORD_with_COLLATING_sequence_-_ASCII.out: New test. + * cobol.dg/group2/CHAR_and_ORD_with_COLLATING_sequence_-_EBCDIC.cob: New test. + * cobol.dg/group2/CHAR_and_ORD_with_COLLATING_sequence_-_EBCDIC.out: New test. + * cobol.dg/group2/EC-BOUND-REF-MOD_checking_process_termination.cob: New test. + * cobol.dg/group2/EC-BOUND-REF-MOD_checking_process_termination.out: New test. + * cobol.dg/group2/Intrinsics_without_FUNCTION_keyword__3_.cob: New test. + * cobol.dg/group2/Occurs_DEPENDING_ON__source_and_dest.cob: New test. + * cobol.dg/group2/Occurs_DEPENDING_ON__source_and_dest.out: New test. + * cobol.dg/group2/Recursive_subscripts.cob: New test. + * cobol.dg/group2/Recursive_subscripts.out: New test. + * cobol.dg/group2/SEARCH_ALL_with_OCCURS_DEPENDING_ON.cob: New test. + * cobol.dg/group2/SEARCH_ALL_with_OCCURS_DEPENDING_ON.out: New test. + * cobol.dg/group2/Subscript_by_arithmetic_expression.cob: New test. + * cobol.dg/group2/Subscript_out_of_bounds__1_.cob: New test. + * cobol.dg/group2/Subscript_out_of_bounds__1_.out: New test. + * cobol.dg/group2/Subscript_out_of_bounds__2_.cob: New test. + * cobol.dg/group2/Subscript_out_of_bounds__2_.out: New test. + * cobol.dg/group2/Subscripted_refmods.cob: New test. + * cobol.dg/group2/Subscripted_refmods.out: New test. + * cobol.dg/group2/length_of_ODO_Rules_7__8A__and_8B.cob: New test. + * cobol.dg/group2/length_of_ODO_Rules_7__8A__and_8B.out: New test. + * cobol.dg/group2/length_of_ODO_w_-_reference_modification.cob: New test. + +2025-10-23 Andrew Pinski <andrew.pinski@oss.qualcomm.com> + + * gcc.dg/tree-ssa/bool-12.c: Update based on when BIT_AND/BIT_IOR + is created and no longer MIN/MAX. + +2025-10-23 Robert Dubner <rdubner@symas.com> + James K. Lowden <jklowden@cobolworx.com> + + * cobol.dg/typo-1.cob: New test for squiggles and carets. + +2025-10-23 Alfie Richards <alfie.richards@arm.com> + + * gcc.target/aarch64/fmv_priority1.c: New test. + * gcc.target/aarch64/fmv_priority2.c: New test. + * gcc.target/aarch64/fmv_priority.in: Support file. + +2025-10-23 Alfie Richards <alfie.richards@arm.com> + + PR target/122190 + * gcc.target/aarch64/pr122190.c: New test + +2025-10-23 zhaozhou <zhaozhou@loongson.cn> + + * gcc.dg/fold-round-1.c: New test. + +2025-10-23 Christophe Lyon <christophe.lyon@linaro.org> + + PR target/122223 + * gcc.target/arm/mve/intrinsics/pr122223.c: Relax expected code. + +2025-10-23 liuhongt <hongtao.liu@intel.com> + + * gcc.target/i386/pr101639_reduc_mask_vdi.c: New test. + * gcc.target/i386/pr101639_reduc_mask_vqi.c: New test. + * gcc.target/i386/pr101639_reduc_mask_vsi.c: New test. + * gcc.target/i386/pr101639_reduc_mask_ior_vqi.c: New test. + * gcc.target/i386/pr101639_reduc_mask_and_vqi.c: New test. + +2025-10-23 liuhongt <hongtao.liu@intel.com> + + * gcc.target/i386/pr101639_reduc_mask_di.c: New test. + * gcc.target/i386/pr101639_reduc_mask_hi.c: New test. + * gcc.target/i386/pr101639_reduc_mask_qi.c: New test. + * gcc.target/i386/pr101639_reduc_mask_si.c: New test. + 2025-10-22 Paul-Antoine Arras <parras@baylibre.com> PR middle-end/122378 diff --git a/gcc/testsuite/cobol.dg/group2/CALL_with_OCCURS_DEPENDING_ON.cob b/gcc/testsuite/cobol.dg/group2/CALL_with_OCCURS_DEPENDING_ON.cob new file mode 100644 index 0000000..c1b3b5f1b --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/CALL_with_OCCURS_DEPENDING_ON.cob @@ -0,0 +1,37 @@ + *> { dg-do run } + *> { dg-output-file "group2/CALL_with_OCCURS_DEPENDING_ON.out" } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog-main. + + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 parm. + 03 parm-size PIC S999 COMP. + 03 parm-str. + 05 parm-char PIC X OCCURS 0 TO 100 TIMES + DEPENDING ON parm-size. + + PROCEDURE DIVISION. + MOVE 10 TO parm-size + MOVE "Hi, there!" TO parm-str + CALL "prog" USING parm + . + END PROGRAM prog-main. + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + + DATA DIVISION. + LINKAGE SECTION. + 01 parm. + 03 parm-size PIC S999 COMP. + 03 parm-str. + 05 parm-char PIC X OCCURS 0 TO 100 TIMES + DEPENDING ON parm-size. + + PROCEDURE DIVISION USING parm. + DISPLAY FUNCTION TRIM(parm-str) WITH NO ADVANCING + . + END PROGRAM prog. + diff --git a/gcc/testsuite/cobol.dg/group2/CALL_with_OCCURS_DEPENDING_ON.out b/gcc/testsuite/cobol.dg/group2/CALL_with_OCCURS_DEPENDING_ON.out new file mode 100644 index 0000000..bd79118 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/CALL_with_OCCURS_DEPENDING_ON.out @@ -0,0 +1 @@ +Hi, there! diff --git a/gcc/testsuite/cobol.dg/group2/CHAR_and_ORD_with_COLLATING_sequence_-_ASCII.cob b/gcc/testsuite/cobol.dg/group2/CHAR_and_ORD_with_COLLATING_sequence_-_ASCII.cob new file mode 100644 index 0000000..fddd1fb --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/CHAR_and_ORD_with_COLLATING_sequence_-_ASCII.cob @@ -0,0 +1,26 @@ + *> { dg-do run } + *> { dg-output-file "group2/CHAR_and_ORD_with_COLLATING_sequence_-_ASCII.out" } + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + ENVIRONMENT DIVISION. + CONFIGURATION SECTION. + OBJECT-COMPUTER. + GNU-Linux + PROGRAM COLLATING SEQUENCE IS THE-WILD-ONE. + SPECIAL-NAMES. + ALPHABET + THE-WILD-ONE IS "A" THRU "H" "I" ALSO "J", ALSO "K", ALSO + "L" ALSO "M" ALSO "N" "O" THROUGH "Z" "0" THRU "9". + PROCEDURE DIVISION. + DISPLAY LOW-VALUE + DISPLAY HIGH-VALUE + DISPLAY FUNCTION CHAR(1). + DISPLAY FUNCTION CHAR(9). + DISPLAY FUNCTION CHAR(10). + DISPLAY FUNCTION ORD("A") + DISPLAY FUNCTION ORD("I") + DISPLAY FUNCTION ORD("J") + DISPLAY FUNCTION ORD("K") + DISPLAY FUNCTION ORD("O") + GOBACK. + diff --git a/gcc/testsuite/cobol.dg/group2/CHAR_and_ORD_with_COLLATING_sequence_-_ASCII.out b/gcc/testsuite/cobol.dg/group2/CHAR_and_ORD_with_COLLATING_sequence_-_ASCII.out new file mode 100644 index 0000000..655f8ae --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/CHAR_and_ORD_with_COLLATING_sequence_-_ASCII.out @@ -0,0 +1,11 @@ +A +9 +A +I +O +1 +9 +9 +9 +10 + diff --git a/gcc/testsuite/cobol.dg/group2/CHAR_and_ORD_with_COLLATING_sequence_-_EBCDIC.cob b/gcc/testsuite/cobol.dg/group2/CHAR_and_ORD_with_COLLATING_sequence_-_EBCDIC.cob new file mode 100644 index 0000000..f6f6bbc --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/CHAR_and_ORD_with_COLLATING_sequence_-_EBCDIC.cob @@ -0,0 +1,27 @@ + *> { dg-do run } + *> { dg-options "-finternal-ebcdic" } + *> { dg-output-file "group2/CHAR_and_ORD_with_COLLATING_sequence_-_EBCDIC.out" } + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + ENVIRONMENT DIVISION. + CONFIGURATION SECTION. + OBJECT-COMPUTER. + GNU-Linux + PROGRAM COLLATING SEQUENCE IS THE-WILD-ONE. + SPECIAL-NAMES. + ALPHABET + THE-WILD-ONE IS "A" THRU "H" "I" ALSO "J", ALSO "K", ALSO + "L" ALSO "M" ALSO "N" "O" THROUGH "Z" "0" THRU "9". + PROCEDURE DIVISION. + DISPLAY LOW-VALUE + DISPLAY HIGH-VALUE + DISPLAY FUNCTION CHAR(1). + DISPLAY FUNCTION CHAR(9). + DISPLAY FUNCTION CHAR(10). + DISPLAY FUNCTION ORD("A") + DISPLAY FUNCTION ORD("I") + DISPLAY FUNCTION ORD("J") + DISPLAY FUNCTION ORD("K") + DISPLAY FUNCTION ORD("O") + GOBACK. + diff --git a/gcc/testsuite/cobol.dg/group2/CHAR_and_ORD_with_COLLATING_sequence_-_EBCDIC.out b/gcc/testsuite/cobol.dg/group2/CHAR_and_ORD_with_COLLATING_sequence_-_EBCDIC.out new file mode 100644 index 0000000..655f8ae --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/CHAR_and_ORD_with_COLLATING_sequence_-_EBCDIC.out @@ -0,0 +1,11 @@ +A +9 +A +I +O +1 +9 +9 +9 +10 + diff --git a/gcc/testsuite/cobol.dg/group2/EC-BOUND-REF-MOD_checking_process_termination.cob b/gcc/testsuite/cobol.dg/group2/EC-BOUND-REF-MOD_checking_process_termination.cob new file mode 100644 index 0000000..ecb38d2 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/EC-BOUND-REF-MOD_checking_process_termination.cob @@ -0,0 +1,41 @@ + *> { dg-do run } + *> { dg-xfail-run-if "" { *-*-* } } + *> { dg-output-file "group2/EC-BOUND-REF-MOD_checking_process_termination.out" } + identification division. + program-id. caller. + data division. + working-storage section. + 77 str pic x(4) value "abcd". + procedure division. + display "sending str " str + call "prog1" using str. + display "returned str " str + call "prog2" using str. + display "returned str " str + goback. + + identification division. + program-id. prog1. + data division. + linkage section. + 01 str pic x any length. + procedure division using str. + move '4' to str(5:1) + display "We should get here, because there is no checking" + goback. + end program prog1. + + >>turn ec-all checking on + identification division. + program-id. prog2. + data division. + linkage section. + 01 str pic x any length. + procedure division using str. + move '4' to str(5:1) + display "I don't think we should get here?" + goback. + end program prog2. + + end program caller. + diff --git a/gcc/testsuite/cobol.dg/group2/EC-BOUND-REF-MOD_checking_process_termination.out b/gcc/testsuite/cobol.dg/group2/EC-BOUND-REF-MOD_checking_process_termination.out new file mode 100644 index 0000000..5e497b6 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/EC-BOUND-REF-MOD_checking_process_termination.out @@ -0,0 +1,4 @@ +sending str abcd +We should get here, because there is no checking +returned str abcd + diff --git a/gcc/testsuite/cobol.dg/group2/Intrinsics_without_FUNCTION_keyword__3_.cob b/gcc/testsuite/cobol.dg/group2/Intrinsics_without_FUNCTION_keyword__3_.cob new file mode 100644 index 0000000..39a0c5b --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Intrinsics_without_FUNCTION_keyword__3_.cob @@ -0,0 +1,17 @@ + *> { dg-do run } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + ENVIRONMENT DIVISION. + CONFIGURATION SECTION. + REPOSITORY. + FUNCTION PI INTRINSIC + FUNCTION E INTRINSIC. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 Z PIC 99V99. + PROCEDURE DIVISION. + MOVE PI TO Z. + MOVE E TO Z. + STOP RUN. + diff --git a/gcc/testsuite/cobol.dg/group2/Length_overflow__2_.out b/gcc/testsuite/cobol.dg/group2/Length_overflow__2_.out index f2ad6c7..78981922 100644 --- a/gcc/testsuite/cobol.dg/group2/Length_overflow__2_.out +++ b/gcc/testsuite/cobol.dg/group2/Length_overflow__2_.out @@ -1 +1 @@ -c +a diff --git a/gcc/testsuite/cobol.dg/group2/Length_overflow_with_offset__1_.out b/gcc/testsuite/cobol.dg/group2/Length_overflow_with_offset__1_.out index f2ad6c7..78981922 100644 --- a/gcc/testsuite/cobol.dg/group2/Length_overflow_with_offset__1_.out +++ b/gcc/testsuite/cobol.dg/group2/Length_overflow_with_offset__1_.out @@ -1 +1 @@ -c +a diff --git a/gcc/testsuite/cobol.dg/group2/Occurs_DEPENDING_ON__source_and_dest.cob b/gcc/testsuite/cobol.dg/group2/Occurs_DEPENDING_ON__source_and_dest.cob new file mode 100644 index 0000000..33d8c11 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Occurs_DEPENDING_ON__source_and_dest.cob @@ -0,0 +1,48 @@ + *> { dg-do run } + *> { dg-output-file "group2/Occurs_DEPENDING_ON__source_and_dest.out" } + identification division. + program-id. prog. + data division. + working-storage section. + 01 table1d value "1234567890". + 02 table1 pic x occurs 0 to 10 times depending on table1do. + + 01 table2d value "1234567890". + 02 table2 pic x occurs 0 to 10 times depending on table2do. + + 01 table3d. + 02 table3do pic 99. + 02 table3dd. + 03 table3 pic x occurs 0 to 10 times depending on table3do. + + 77 table1do pic 99. + 77 table2do pic 99. + 77 n pic 99. + procedure division. + display "Test1: Demonstrate ODO limits:" + perform varying n from 0 by 1 until n > 10 + move n to table1do + display n space """"table1d"""" + end-perform + + display "Test2: result should be ABC4567890" + move 3 to table2do + move "ABCDEFGHIJ" to table2d + move 10 to table2do + display " result is "table2d + + display "Test3A: result should be 05ABCDE" + move "05ABCDEFGHIJ" to table3d + display " result is "table3d + move 10 to table3do + display "Test3B: result should be 10ABCDEFGHIJ" + display " result is "table3d + + display "Test4: result should be 10lmnopqGHIJ" + move 6 to table3do + move "lmnopqrstu" to table3dd + move 10 to table3do + display " result is "table3d + + goback. + diff --git a/gcc/testsuite/cobol.dg/group2/Occurs_DEPENDING_ON__source_and_dest.out b/gcc/testsuite/cobol.dg/group2/Occurs_DEPENDING_ON__source_and_dest.out new file mode 100644 index 0000000..4c59c65 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Occurs_DEPENDING_ON__source_and_dest.out @@ -0,0 +1,21 @@ +Test1: Demonstrate ODO limits: +00 "" +01 "1" +02 "12" +03 "123" +04 "1234" +05 "12345" +06 "123456" +07 "1234567" +08 "12345678" +09 "123456789" +10 "1234567890" +Test2: result should be ABC4567890 + result is ABC4567890 +Test3A: result should be 05ABCDE + result is 05ABCDE +Test3B: result should be 10ABCDEFGHIJ + result is 10ABCDEFGHIJ +Test4: result should be 10lmnopqGHIJ + result is 10lmnopqGHIJ + diff --git a/gcc/testsuite/cobol.dg/group2/Offset_overflow.out b/gcc/testsuite/cobol.dg/group2/Offset_overflow.out index 7ed6ff8..78981922 100644 --- a/gcc/testsuite/cobol.dg/group2/Offset_overflow.out +++ b/gcc/testsuite/cobol.dg/group2/Offset_overflow.out @@ -1 +1 @@ -5 +a diff --git a/gcc/testsuite/cobol.dg/group2/Recursive_subscripts.cob b/gcc/testsuite/cobol.dg/group2/Recursive_subscripts.cob new file mode 100644 index 0000000..c2efd57 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Recursive_subscripts.cob @@ -0,0 +1,27 @@ + *> { dg-do run } + *> { dg-output-file "group2/Recursive_subscripts.out" } + + identification division. + program-id. pmain. + data division. + working-storage section. + 01 filler. + 02 tabl-values pic x(9) value "234567890". + 02 v redefines tabl-values occurs 9 pic 9. + procedure division. + display v(1) " should be 2" + display v(v(1)) " should be 3" + display v(v(v(1))) " should be 4" + display v(v(v(v(1)))) " should be 5" + display v(v(v(v(v(1))))) " should be 6" + display v(v(v(v(v(v(1)))))) " should be 7" + display v(v(v(v(v(v(v(1))))))) " should be 8" + display v(v(v(v(v(v(v(v(1)))))))) " should be 9" + + display v(v(v(v(v(v(v(v(v(1))))))))) " should be 0" + move 1 to v(v(v(v(v(v(v(v(v(1))))))))) + display v(v(v(v(v(v(v(v(v(1))))))))) " should be 1" + + goback. + end program pmain. + diff --git a/gcc/testsuite/cobol.dg/group2/Recursive_subscripts.out b/gcc/testsuite/cobol.dg/group2/Recursive_subscripts.out new file mode 100644 index 0000000..2fa81d4 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Recursive_subscripts.out @@ -0,0 +1,11 @@ +2 should be 2 +3 should be 3 +4 should be 4 +5 should be 5 +6 should be 6 +7 should be 7 +8 should be 8 +9 should be 9 +0 should be 0 +1 should be 1 + diff --git a/gcc/testsuite/cobol.dg/group2/SEARCH_ALL_with_OCCURS_DEPENDING_ON.cob b/gcc/testsuite/cobol.dg/group2/SEARCH_ALL_with_OCCURS_DEPENDING_ON.cob new file mode 100644 index 0000000..097fa77 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/SEARCH_ALL_with_OCCURS_DEPENDING_ON.cob @@ -0,0 +1,42 @@ + *> { dg-do run } + *> { dg-output-file "group2/SEARCH_ALL_with_OCCURS_DEPENDING_ON.out" } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + * + 77 SCREEN-AKT PIC 9(02) VALUE 0. + 01 SCREEN-TAB. + 03 SCREEN-ENTRY OCCURS 0 TO 20 + DEPENDING ON SCREEN-AKT + ASCENDING KEY SCREEN-NAME + INDEXED BY SCREEN-IDX. + 05 SCREEN-NAME PIC X(02). + + PROCEDURE DIVISION. + + SEARCH ALL SCREEN-ENTRY + AT END + DISPLAY 'END' + WHEN SCREEN-NAME (SCREEN-IDX) = 'AB' + DISPLAY 'FOUND' + END-SEARCH + MOVE 1 TO SCREEN-AKT + MOVE 'AB' TO SCREEN-NAME (1) + SEARCH ALL SCREEN-ENTRY + AT END + DISPLAY 'END' + WHEN SCREEN-NAME (SCREEN-IDX) = 'AB' + DISPLAY 'FOUND' + END-SEARCH + MOVE 2 TO SCREEN-AKT + MOVE 'CD' TO SCREEN-NAME (2) + SEARCH ALL SCREEN-ENTRY + AT END + DISPLAY 'END' + WHEN SCREEN-NAME (SCREEN-IDX) = 'CD' + DISPLAY 'FOUND' + END-SEARCH + EXIT PROGRAM. + diff --git a/gcc/testsuite/cobol.dg/group2/SEARCH_ALL_with_OCCURS_DEPENDING_ON.out b/gcc/testsuite/cobol.dg/group2/SEARCH_ALL_with_OCCURS_DEPENDING_ON.out new file mode 100644 index 0000000..47a32dd --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/SEARCH_ALL_with_OCCURS_DEPENDING_ON.out @@ -0,0 +1,4 @@ +END +FOUND +FOUND + diff --git a/gcc/testsuite/cobol.dg/group2/Subscript_by_arithmetic_expression.cob b/gcc/testsuite/cobol.dg/group2/Subscript_by_arithmetic_expression.cob new file mode 100644 index 0000000..b9851d4 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Subscript_by_arithmetic_expression.cob @@ -0,0 +1,22 @@ + *> { dg-do run } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 G VALUE "1234". + 02 X PIC X OCCURS 4. + 01 Z PIC X. + PROCEDURE DIVISION. + MOVE X((3 + 1) / 2) TO Z. + IF Z NOT = "2" + DISPLAY Z + END-DISPLAY + END-IF. + MOVE X(2 ** 2) TO Z. + IF Z NOT = "4" + DISPLAY Z + END-DISPLAY + END-IF. + STOP RUN. + diff --git a/gcc/testsuite/cobol.dg/group2/Subscript_out_of_bounds__1_.cob b/gcc/testsuite/cobol.dg/group2/Subscript_out_of_bounds__1_.cob new file mode 100644 index 0000000..828f81c --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Subscript_out_of_bounds__1_.cob @@ -0,0 +1,17 @@ + *> { dg-do run } + *> { dg-xfail-run-if "" { *-*-* } } + *> { dg-output-file "group2/Subscript_out_of_bounds__1_.out" } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 G. + 02 X PIC X OCCURS 10. + 01 I PIC 9 VALUE 0. + PROCEDURE DIVISION. + >>TURN EC-ALL CHECKING ON + DISPLAY """" X(I) """" + END-DISPLAY. + STOP RUN. + diff --git a/gcc/testsuite/cobol.dg/group2/Subscript_out_of_bounds__1_.out b/gcc/testsuite/cobol.dg/group2/Subscript_out_of_bounds__1_.out new file mode 100644 index 0000000..f66f772 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Subscript_out_of_bounds__1_.out @@ -0,0 +1,2 @@ +" " + diff --git a/gcc/testsuite/cobol.dg/group2/Subscript_out_of_bounds__2_.cob b/gcc/testsuite/cobol.dg/group2/Subscript_out_of_bounds__2_.cob new file mode 100644 index 0000000..d7ae196 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Subscript_out_of_bounds__2_.cob @@ -0,0 +1,17 @@ + *> { dg-do run } + *> { dg-xfail-run-if "" { *-*-* } } + *> { dg-output-file "group2/Subscript_out_of_bounds__2_.out" } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 G. + 02 X PIC X OCCURS 10. + 01 I PIC 99 VALUE 11. + PROCEDURE DIVISION. + >>TURN EC-ALL CHECKING ON + DISPLAY """" X(I) """" + END-DISPLAY. + STOP RUN. + diff --git a/gcc/testsuite/cobol.dg/group2/Subscript_out_of_bounds__2_.out b/gcc/testsuite/cobol.dg/group2/Subscript_out_of_bounds__2_.out new file mode 100644 index 0000000..f66f772 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Subscript_out_of_bounds__2_.out @@ -0,0 +1,2 @@ +" " + diff --git a/gcc/testsuite/cobol.dg/group2/Subscripted_refmods.cob b/gcc/testsuite/cobol.dg/group2/Subscripted_refmods.cob new file mode 100644 index 0000000..c69a6e7 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Subscripted_refmods.cob @@ -0,0 +1,16 @@ + *> { dg-do run } + *> { dg-output-file "group2/Subscripted_refmods.out" } + + identification division. + program-id. pmain. + data division. + working-storage section. + 01 filler. + 02 tabl-values pic x(9) value "123456789". + 02 v redefines tabl-values occurs 9 pic 9. + procedure division. + display tabl-values( 3:4 ) " should be 3456" + display tabl-values( v(3):v(4) ) " should be 3456" + goback. + end program pmain. + diff --git a/gcc/testsuite/cobol.dg/group2/Subscripted_refmods.out b/gcc/testsuite/cobol.dg/group2/Subscripted_refmods.out new file mode 100644 index 0000000..4c69c3a --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Subscripted_refmods.out @@ -0,0 +1,3 @@ +3456 should be 3456 +3456 should be 3456 + diff --git a/gcc/testsuite/cobol.dg/group2/length_of_ODO_Rules_7__8A__and_8B.cob b/gcc/testsuite/cobol.dg/group2/length_of_ODO_Rules_7__8A__and_8B.cob new file mode 100644 index 0000000..4b9e55d --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/length_of_ODO_Rules_7__8A__and_8B.cob @@ -0,0 +1,76 @@ + *> { dg-do run } + *> { dg-output-file "group2/length_of_ODO_Rules_7__8A__and_8B.out" } + + identification division. + program-id. prog. + procedure division. + call "prog1" + call "prog2" + call "prog3" + goback. + end program prog. + + identification division. + program-id. prog1. + data division. + working-storage section. + 01 depl pic 9. + 01 digtab. + 05 digitgrp. + 10 digits occurs 1 to 9 depending on depl pic x. + procedure division. + display "Demonstrates 13.18.38.4 OCCURS General rules 7)" + display "depl is completely separate" + display "output should be ""12345 """ + move 9 to depl + move space to digtab + move 5 to depl + move "123456789" to digtab + move 9 to depl + display """" digtab """" + goback. + end program prog1. + + identification division. + program-id. prog2. + data division. + working-storage section. + 01 digtab. + 05 depl pic 9. + 05 digitgrp. + 10 digits occurs 1 to 9 depending on depl pic x. + procedure division. + display "Demonstrates 13.18.38.4 OCCURS General rules 8a)" + display "depl is not subordinate to digitgrp" + display "output should be ""12345 """ + move 9 to depl + move space to digtab + move 5 to depl + move "123456789" to digitgrp + move 9 to depl + display """" digitgrp """" + goback. + end program prog2. + + identification division. + program-id. prog3. + data division. + working-storage section. + 01 digtab. + 05 depl pic 9. + 05 digitgrp. + 10 digits occurs 1 to 9 depending on depl pic x. + procedure division. + display "Demonstrates 13.18.38.4 OCCURS General rules 8b)" + display "depl is subordinate to digtab" + display "output should be ""123"" followed by ""123456789""" + move 9 to depl + move space to digtab + move 5 to depl + move "3123456789" to digtab + display """" digitgrp """" + move 9 to depl + display """" digitgrp """" + goback. + end program prog3. + diff --git a/gcc/testsuite/cobol.dg/group2/length_of_ODO_Rules_7__8A__and_8B.out b/gcc/testsuite/cobol.dg/group2/length_of_ODO_Rules_7__8A__and_8B.out new file mode 100644 index 0000000..6c6e906 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/length_of_ODO_Rules_7__8A__and_8B.out @@ -0,0 +1,14 @@ +Demonstrates 13.18.38.4 OCCURS General rules 7) +depl is completely separate +output should be "12345 " +"12345 " +Demonstrates 13.18.38.4 OCCURS General rules 8a) +depl is not subordinate to digitgrp +output should be "12345 " +"12345 " +Demonstrates 13.18.38.4 OCCURS General rules 8b) +depl is subordinate to digtab +output should be "123" followed by "123456789" +"123" +"123456789" + diff --git a/gcc/testsuite/cobol.dg/group2/length_of_ODO_w_-_reference_modification.cob b/gcc/testsuite/cobol.dg/group2/length_of_ODO_w_-_reference_modification.cob new file mode 100644 index 0000000..37afe0b --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/length_of_ODO_w_-_reference_modification.cob @@ -0,0 +1,47 @@ + *> { dg-do run } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 PLINE. + 03 PLINE-LEN PIC S9(4) COMP-5. + 03 PLINE-TEXT. + 04 FILLER PIC X(1) OCCURS 1 TO 80 + DEPENDING ON PLINE-LEN. + procedure division. + a-main section. + MOVE 5 TO PLINE-LEN + MOVE 'the first part in' TO PLINE-TEXT + MOVE 30 TO PLINE-LEN + IF PLINE-TEXT NOT = 'the f' + DISPLAY 'text1 wrong: ' PLINE-TEXT + END-DISPLAY + END-IF + MOVE 'the first part in' TO PLINE-TEXT + MOVE 4 TO PLINE-LEN + MOVE 'second' TO PLINE-TEXT + MOVE 14 TO PLINE-LEN + IF PLINE-TEXT NOT = 'secofirst part' + DISPLAY 'text2 wrong: ' PLINE-TEXT + END-DISPLAY + END-IF + MOVE 80 TO PLINE-LEN + MOVE SPACES TO PLINE-TEXT + MOVE 5 TO PLINE-LEN + MOVE 'the first part in' TO PLINE-TEXT (2:) + MOVE 30 TO PLINE-LEN + IF PLINE-TEXT NOT = ' the ' + DISPLAY 'text3 wrong: ' PLINE-TEXT + END-DISPLAY + END-IF + MOVE 'the first part in' TO PLINE-TEXT (2:) + MOVE 4 TO PLINE-LEN + MOVE 'second' TO PLINE-TEXT (2:) + MOVE 14 TO PLINE-LEN + IF PLINE-TEXT NOT = ' sec first par' + DISPLAY 'text4 wrong: ' PLINE-TEXT + END-DISPLAY + END-IF + STOP RUN. + diff --git a/gcc/testsuite/cobol.dg/typo-1.cob b/gcc/testsuite/cobol.dg/typo-1.cob new file mode 100644 index 0000000..a806863 --- /dev/null +++ b/gcc/testsuite/cobol.dg/typo-1.cob @@ -0,0 +1,15 @@ +*> { dg-options "-fdiagnostics-show-caret" } +*> { dg-do compile } + + identification division. + porgram-id. hello. *> { dg-error "8: syntax error, unexpected NAME, expecting FUNCTION or PROGRAM-ID" } + procedure division. + display "Hello World!". + stop run. + +*<< +{ dg-begin-multiline-output "" } + porgram-id. hello. + ^~~~~~~~~~~ +{ dg-end-multiline-output "" } +*>> diff --git a/gcc/testsuite/gcc.dg/c23-static-assert-5.c b/gcc/testsuite/gcc.dg/c23-static-assert-5.c new file mode 100644 index 0000000..2edc6b7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c23-static-assert-5.c @@ -0,0 +1,69 @@ +/* Test C2y static assertions in expressions: -pedantic warnings for C23. */ +/* { dg-do compile } */ +/* { dg-options "-std=c23 -pedantic" } */ + +/* Old forms of static assertion still valid. */ +static_assert (1); +static_assert (2, "message" ); +struct s { int a; static_assert (3); }; + +void +f () +{ + static_assert (4); + label: + static_assert (5); + for (static_assert (6);;) + ; +} + +/* Test new forms of static assertion. */ +void +g () +{ + (void) 0, static_assert (7), (void) 0; /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + extern typeof (static_assert (8)) f (); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + 1 + ? static_assert (9) /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + : static_assert (10); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + if (1) + static_assert (11); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + else + static_assert (12); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + for (;;) + static_assert (13); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + while (true) + static_assert (14); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + do + static_assert (15); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + while (false); + switch (16) + static_assert (17); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + (void) static_assert (18); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + (static_assert (19)); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ +} + +void +g2 () +{ + (void) 0, static_assert (7, "message"), (void) 0; /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + extern typeof (static_assert (8, "message")) f (); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + 1 + ? static_assert (9, "message") /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + : static_assert (10, "message"); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + if (1) + static_assert (11, "message"); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + else + static_assert (12, "message"); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + for (;;) + static_assert (13, "message"); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + while (true) + static_assert (14, "message"); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + do + static_assert (15, "message"); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + while (false); + switch (16) + static_assert (17, "message"); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + (void) static_assert (18, "message"); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + (static_assert (19, "message")); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ +} diff --git a/gcc/testsuite/gcc.dg/c23-static-assert-6.c b/gcc/testsuite/gcc.dg/c23-static-assert-6.c new file mode 100644 index 0000000..43e0b27 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c23-static-assert-6.c @@ -0,0 +1,70 @@ +/* Test C2y static assertions in expressions: -pedantic-errors errors for + C23. */ +/* { dg-do compile } */ +/* { dg-options "-std=c23 -pedantic-errors" } */ + +/* Old forms of static assertion still valid. */ +static_assert (1); +static_assert (2, "message" ); +struct s { int a; static_assert (3); }; + +void +f () +{ + static_assert (4); + label: + static_assert (5); + for (static_assert (6);;) + ; +} + +/* Test new forms of static assertion. */ +void +g () +{ + (void) 0, static_assert (7), (void) 0; /* { dg-error "ISO C does not support static assertions in expressions before C2Y" } */ + extern typeof (static_assert (8)) f (); /* { dg-error "ISO C does not support static assertions in expressions before C2Y" } */ + 1 + ? static_assert (9) /* { dg-error "ISO C does not support static assertions in expressions before C2Y" } */ + : static_assert (10); /* { dg-error "ISO C does not support static assertions in expressions before C2Y" } */ + if (1) + static_assert (11); /* { dg-error "ISO C does not support static assertions in expressions before C2Y" } */ + else + static_assert (12); /* { dg-error "ISO C does not support static assertions in expressions before C2Y" } */ + for (;;) + static_assert (13); /* { dg-error "ISO C does not support static assertions in expressions before C2Y" } */ + while (true) + static_assert (14); /* { dg-error "ISO C does not support static assertions in expressions before C2Y" } */ + do + static_assert (15); /* { dg-error "ISO C does not support static assertions in expressions before C2Y" } */ + while (false); + switch (16) + static_assert (17); /* { dg-error "ISO C does not support static assertions in expressions before C2Y" } */ + (void) static_assert (18); /* { dg-error "ISO C does not support static assertions in expressions before C2Y" } */ + (static_assert (19)); /* { dg-error "ISO C does not support static assertions in expressions before C2Y" } */ +} + +void +g2 () +{ + (void) 0, static_assert (7, "message"), (void) 0; /* { dg-error "ISO C does not support static assertions in expressions before C2Y" } */ + extern typeof (static_assert (8, "message")) f (); /* { dg-error "ISO C does not support static assertions in expressions before C2Y" } */ + 1 + ? static_assert (9, "message") /* { dg-error "ISO C does not support static assertions in expressions before C2Y" } */ + : static_assert (10, "message"); /* { dg-error "ISO C does not support static assertions in expressions before C2Y" } */ + if (1) + static_assert (11, "message"); /* { dg-error "ISO C does not support static assertions in expressions before C2Y" } */ + else + static_assert (12, "message"); /* { dg-error "ISO C does not support static assertions in expressions before C2Y" } */ + for (;;) + static_assert (13, "message"); /* { dg-error "ISO C does not support static assertions in expressions before C2Y" } */ + while (true) + static_assert (14, "message"); /* { dg-error "ISO C does not support static assertions in expressions before C2Y" } */ + do + static_assert (15, "message"); /* { dg-error "ISO C does not support static assertions in expressions before C2Y" } */ + while (false); + switch (16) + static_assert (17, "message"); /* { dg-error "ISO C does not support static assertions in expressions before C2Y" } */ + (void) static_assert (18, "message"); /* { dg-error "ISO C does not support static assertions in expressions before C2Y" } */ + (static_assert (19, "message")); /* { dg-error "ISO C does not support static assertions in expressions before C2Y" } */ +} diff --git a/gcc/testsuite/gcc.dg/c23-static-assert-7.c b/gcc/testsuite/gcc.dg/c23-static-assert-7.c new file mode 100644 index 0000000..9c35353 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c23-static-assert-7.c @@ -0,0 +1,70 @@ +/* Test C2y static assertions in expressions: -Wc23-c2y-compat warnings for + C23. */ +/* { dg-do compile } */ +/* { dg-options "-std=c23 -Wc23-c2y-compat" } */ + +/* Old forms of static assertion still valid. */ +static_assert (1); +static_assert (2, "message" ); +struct s { int a; static_assert (3); }; + +void +f () +{ + static_assert (4); + label: + static_assert (5); + for (static_assert (6);;) + ; +} + +/* Test new forms of static assertion. */ +void +g () +{ + (void) 0, static_assert (7), (void) 0; /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + extern typeof (static_assert (8)) f (); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + 1 + ? static_assert (9) /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + : static_assert (10); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + if (1) + static_assert (11); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + else + static_assert (12); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + for (;;) + static_assert (13); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + while (true) + static_assert (14); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + do + static_assert (15); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + while (false); + switch (16) + static_assert (17); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + (void) static_assert (18); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + (static_assert (19)); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ +} + +void +g2 () +{ + (void) 0, static_assert (7, "message"), (void) 0; /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + extern typeof (static_assert (8, "message")) f (); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + 1 + ? static_assert (9, "message") /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + : static_assert (10, "message"); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + if (1) + static_assert (11, "message"); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + else + static_assert (12, "message"); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + for (;;) + static_assert (13, "message"); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + while (true) + static_assert (14, "message"); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + do + static_assert (15, "message"); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + while (false); + switch (16) + static_assert (17, "message"); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + (void) static_assert (18, "message"); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + (static_assert (19, "message")); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ +} diff --git a/gcc/testsuite/gcc.dg/c23-static-assert-8.c b/gcc/testsuite/gcc.dg/c23-static-assert-8.c new file mode 100644 index 0000000..118e199 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c23-static-assert-8.c @@ -0,0 +1,66 @@ +/* Test C2y static assertions in expressions: not diagnosed for C23 with + -pedantic-errors -Wno-c23-c2y-compat. */ +/* { dg-do compile } */ +/* { dg-options "-std=c23 -pedantic-errors -Wno-c23-c2y-compat" } */ + +/* Old forms of static assertion still valid. */ +static_assert (1); +static_assert (2, "message" ); +struct s { int a; static_assert (3); }; + +void +f () +{ + static_assert (4); + label: + static_assert (5); + for (static_assert (6);;) + ; +} + +/* Test new forms of static assertion. */ +void +g () +{ + (void) 0, static_assert (7), (void) 0; + extern typeof (static_assert (8)) f (); + 1 ? static_assert (9) : static_assert (10); + if (1) + static_assert (11); + else + static_assert (12); + for (;;) + static_assert (13); + while (true) + static_assert (14); + do + static_assert (15); + while (false); + switch (16) + static_assert (17); + (void) static_assert (18); + (static_assert (19)); +} + +void +g2 () +{ + (void) 0, static_assert (7, "message"), (void) 0; + extern typeof (static_assert (8, "message")) f (); + 1 ? static_assert (9, "message") : static_assert (10, "message"); + if (1) + static_assert (11, "message"); + else + static_assert (12, "message"); + for (;;) + static_assert (13, "message"); + while (true) + static_assert (14, "message"); + do + static_assert (15, "message"); + while (false); + switch (16) + static_assert (17, "message"); + (void) static_assert (18, "message"); + (static_assert (19, "message")); +} diff --git a/gcc/testsuite/gcc.dg/c2y-static-assert-2.c b/gcc/testsuite/gcc.dg/c2y-static-assert-2.c new file mode 100644 index 0000000..81cdd9d --- /dev/null +++ b/gcc/testsuite/gcc.dg/c2y-static-assert-2.c @@ -0,0 +1,65 @@ +/* Test C2y static assertions in expressions. */ +/* { dg-do compile } */ +/* { dg-options "-std=c2y -pedantic-errors" } */ + +/* Old forms of static assertion still valid. */ +static_assert (1); +static_assert (2, "message" ); +struct s { int a; static_assert (3); }; + +void +f () +{ + static_assert (4); + label: + static_assert (5); + for (static_assert (6);;) + ; +} + +/* Test new forms of static assertion. */ +void +g () +{ + (void) 0, static_assert (7), (void) 0; + extern typeof (static_assert (8)) f (); + 1 ? static_assert (9) : static_assert (10); + if (1) + static_assert (11); + else + static_assert (12); + for (;;) + static_assert (13); + while (true) + static_assert (14); + do + static_assert (15); + while (false); + switch (16) + static_assert (17); + (void) static_assert (18); + (static_assert (19)); +} + +void +g2 () +{ + (void) 0, static_assert (7, "message"), (void) 0; + extern typeof (static_assert (8, "message")) f (); + 1 ? static_assert (9, "message") : static_assert (10, "message"); + if (1) + static_assert (11, "message"); + else + static_assert (12, "message"); + for (;;) + static_assert (13, "message"); + while (true) + static_assert (14, "message"); + do + static_assert (15, "message"); + while (false); + switch (16) + static_assert (17, "message"); + (void) static_assert (18, "message"); + (static_assert (19, "message")); +} diff --git a/gcc/testsuite/gcc.dg/c2y-static-assert-3.c b/gcc/testsuite/gcc.dg/c2y-static-assert-3.c new file mode 100644 index 0000000..fcbf6af --- /dev/null +++ b/gcc/testsuite/gcc.dg/c2y-static-assert-3.c @@ -0,0 +1,69 @@ +/* Test C2y static assertions in expressions: -Wc23-c2y-compat warnings. */ +/* { dg-do compile } */ +/* { dg-options "-std=c2y -pedantic-errors -Wc23-c2y-compat" } */ + +/* Old forms of static assertion still valid. */ +static_assert (1); +static_assert (2, "message" ); +struct s { int a; static_assert (3); }; + +void +f () +{ + static_assert (4); + label: + static_assert (5); + for (static_assert (6);;) + ; +} + +/* Test new forms of static assertion. */ +void +g () +{ + (void) 0, static_assert (7), (void) 0; /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + extern typeof (static_assert (8)) f (); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + 1 + ? static_assert (9) /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + : static_assert (10); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + if (1) + static_assert (11); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + else + static_assert (12); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + for (;;) + static_assert (13); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + while (true) + static_assert (14); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + do + static_assert (15); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + while (false); + switch (16) + static_assert (17); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + (void) static_assert (18); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + (static_assert (19)); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ +} + +void +g2 () +{ + (void) 0, static_assert (7, "message"), (void) 0; /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + extern typeof (static_assert (8, "message")) f (); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + 1 + ? static_assert (9, "message") /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + : static_assert (10, "message"); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + if (1) + static_assert (11, "message"); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + else + static_assert (12, "message"); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + for (;;) + static_assert (13, "message"); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + while (true) + static_assert (14, "message"); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + do + static_assert (15, "message"); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + while (false); + switch (16) + static_assert (17, "message"); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + (void) static_assert (18, "message"); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ + (static_assert (19, "message")); /* { dg-warning "ISO C does not support static assertions in expressions before C2Y" } */ +} diff --git a/gcc/testsuite/gcc.dg/c2y-static-assert-4.c b/gcc/testsuite/gcc.dg/c2y-static-assert-4.c new file mode 100644 index 0000000..87eb7c8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c2y-static-assert-4.c @@ -0,0 +1,69 @@ +/* Test C2y static assertions in expressions: failed assertions. */ +/* { dg-do compile } */ +/* { dg-options "-std=c2y -pedantic-errors" } */ + +/* Old forms of static assertion still valid. */ +static_assert (0); /* { dg-error "static assertion failed" } */ +static_assert (0, "message" ); /* { dg-error "static assertion failed" } */ +struct s { int a; static_assert (0); }; /* { dg-error "static assertion failed" } */ + +void +f () +{ + static_assert (0); /* { dg-error "static assertion failed" } */ + label: + static_assert (0); /* { dg-error "static assertion failed" } */ + for (static_assert (0);;) /* { dg-error "static assertion failed" } */ + ; +} + +/* Test new forms of static assertion. */ +void +g () +{ + (void) 0, static_assert (0), (void) 0; /* { dg-error "static assertion failed" } */ + extern typeof (static_assert (0)) f (); /* { dg-error "static assertion failed" } */ + 1 + ? static_assert (0) /* { dg-error "static assertion failed" } */ + : static_assert (0); /* { dg-error "static assertion failed" } */ + if (1) + static_assert (0); /* { dg-error "static assertion failed" } */ + else + static_assert (0); /* { dg-error "static assertion failed" } */ + for (;;) + static_assert (0); /* { dg-error "static assertion failed" } */ + while (true) + static_assert (0); /* { dg-error "static assertion failed" } */ + do + static_assert (0); /* { dg-error "static assertion failed" } */ + while (false); + switch (16) + static_assert (0); /* { dg-error "static assertion failed" } */ + (void) static_assert (0); /* { dg-error "static assertion failed" } */ + (static_assert (0)); /* { dg-error "static assertion failed" } */ +} + +void +g2 () +{ + (void) 0, static_assert (0, "message"), (void) 0; /* { dg-error "static assertion failed" } */ + extern typeof (static_assert (0, "message")) f (); /* { dg-error "static assertion failed" } */ + 1 + ? static_assert (0, "message") /* { dg-error "static assertion failed" } */ + : static_assert (0, "message"); /* { dg-error "static assertion failed" } */ + if (1) + static_assert (0, "message"); /* { dg-error "static assertion failed" } */ + else + static_assert (0, "message"); /* { dg-error "static assertion failed" } */ + for (;;) + static_assert (0, "message"); /* { dg-error "static assertion failed" } */ + while (true) + static_assert (0, "message"); /* { dg-error "static assertion failed" } */ + do + static_assert (0, "message"); /* { dg-error "static assertion failed" } */ + while (false); + switch (16) + static_assert (0, "message"); /* { dg-error "static assertion failed" } */ + (void) static_assert (0, "message"); /* { dg-error "static assertion failed" } */ + (static_assert (0, "message")); /* { dg-error "static assertion failed" } */ +} diff --git a/gcc/testsuite/gcc.dg/fold-round-1.c b/gcc/testsuite/gcc.dg/fold-round-1.c new file mode 100644 index 0000000..0d7f954 --- /dev/null +++ b/gcc/testsuite/gcc.dg/fold-round-1.c @@ -0,0 +1,56 @@ +/* { dg-do compile } */ +/* { dg-options "-Ofast" } */ + +extern void link_error (void); + +#define TEST_ROUND(TYPE, FFLOOR, FCEIL) \ + void round_##FFLOOR##_1 (TYPE x) \ + { \ + TYPE t1 = 0; \ + TYPE t2 = __builtin_##FFLOOR (x + 0.5); \ + if ((x - __builtin_##FFLOOR (x)) < (__builtin_##FCEIL (x) - x)) \ + t1 = __builtin_##FFLOOR (x); \ + else \ + t1 = __builtin_##FCEIL (x); \ + if (t1 != t2) \ + link_error (); \ + } \ + void round_##FFLOOR##_2 (TYPE x) \ + { \ + TYPE t1 = 0; \ + TYPE t2 = __builtin_##FFLOOR (x + 0.5); \ + if ((__builtin_##FCEIL (x) - x) > (x - __builtin_##FFLOOR (x))) \ + t1 = __builtin_##FFLOOR (x); \ + else \ + t1 = __builtin_##FCEIL (x); \ + if (t1 != t2) \ + link_error (); \ + } \ + void round_##FFLOOR##_3 (TYPE x) \ + { \ + TYPE t1 = 0; \ + TYPE t2 = __builtin_##FFLOOR (x + 0.5); \ + if ((__builtin_##FCEIL (x) - x) <= (x - __builtin_##FFLOOR (x))) \ + t1 = __builtin_##FCEIL (x); \ + else \ + t1 = __builtin_##FFLOOR (x); \ + if (t1 != t2) \ + link_error (); \ + } \ + void round_##FFLOOR##_4 (TYPE x) \ + { \ + TYPE t1 = 0; \ + TYPE t2 = __builtin_##FFLOOR (x + 0.5); \ + if ((x - __builtin_##FFLOOR (x)) >= (__builtin_##FCEIL (x) - x)) \ + t1 = __builtin_##FCEIL (x); \ + else \ + t1 = __builtin_##FFLOOR (x); \ + if (t1 != t2) \ + link_error (); \ + } + +TEST_ROUND (float, floorf, ceilf) +TEST_ROUND (double, floor, ceil) +TEST_ROUND (long double, floorl, ceill) + +/* { dg-final { scan-assembler-not "link_error" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/bool-12.c b/gcc/testsuite/gcc.dg/tree-ssa/bool-12.c index e62594e..244e562 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/bool-12.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/bool-12.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O1 -fdump-tree-optimized -fdump-tree-original -fdump-tree-phiopt1 -fdump-tree-forwprop2" } */ +/* { dg-options "-O1 -fdump-tree-optimized -fdump-tree-original -fdump-tree-phiopt2-raw" } */ #define bool _Bool int maxbool(bool ab, bool bb) { @@ -28,15 +28,12 @@ int minbool(bool ab, bool bb) /* { dg-final { scan-tree-dump-times "MIN_EXPR" 0 "original" } } */ /* { dg-final { scan-tree-dump-times "if " 2 "original" } } */ -/* PHI-OPT1 should have converted it into min/max */ -/* { dg-final { scan-tree-dump-times "MAX_EXPR" 1 "phiopt1" } } */ -/* { dg-final { scan-tree-dump-times "MIN_EXPR" 1 "phiopt1" } } */ -/* { dg-final { scan-tree-dump-times "if " 0 "phiopt1" } } */ - -/* Forwprop2 (after ccp) will convert it into &\| */ -/* { dg-final { scan-tree-dump-times "MAX_EXPR" 0 "forwprop2" } } */ -/* { dg-final { scan-tree-dump-times "MIN_EXPR" 0 "forwprop2" } } */ -/* { dg-final { scan-tree-dump-times "if " 0 "forwprop2" } } */ +/* PHI-OPT2 should have converted it into &\| */ +/* { dg-final { scan-tree-dump-not "min_expr, " "phiopt2" } } */ +/* { dg-final { scan-tree-dump-not "max_expr, " "phiopt2" } } */ +/* { dg-final { scan-tree-dump-times "bit_ior_expr, " 1 "phiopt2" } } */ +/* { dg-final { scan-tree-dump-times "bit_and_expr, " 1 "phiopt2" } } */ +/* { dg-final { scan-tree-dump-times "gimple_cond " 0 "phiopt2" } } */ /* By optimize there should be no min/max nor if */ /* { dg-final { scan-tree-dump-times "MAX_EXPR" 0 "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/fmv_priority.in b/gcc/testsuite/gcc.target/aarch64/fmv_priority.in new file mode 100644 index 0000000..93209bc --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/fmv_priority.in @@ -0,0 +1,92 @@ +int fn [[gnu::target_version("default")]] (int) { return 1; } +int fn_default (int) asm("fn.default"); +int fn [[gnu::target_version("rng")]] (int) { return 1; } +int fn_rng(int) asm("fn._Mrng"); +int fn [[gnu::target_version("flagm")]] (int) { return 1; } +int fn_flagm(int) asm("fn._Mflagm"); +int fn [[gnu::target_version("flagm2")]] (int) { return 1; } +int fn_flagm2(int) asm("fn._Mflagm2"); +int fn [[gnu::target_version("lse")]] (int) { return 1; } +int fn_lse(int) asm("fn._Mlse"); +int fn [[gnu::target_version("fp")]] (int) { return 1; } +int fn_fp(int) asm("fn._Mfp"); +int fn [[gnu::target_version("simd")]] (int) { return 1; } +int fn_simd(int) asm("fn._Msimd"); +int fn [[gnu::target_version("dotprod")]] (int) { return 1; } +int fn_dotprod(int) asm("fn._Mdotprod"); +int fn [[gnu::target_version("sm4")]] (int) { return 1; } +int fn_sm4(int) asm("fn._Msm4"); +int fn [[gnu::target_version("rdm")]] (int) { return 1; } +int fn_rdm(int) asm("fn._MrdmaMrdm"); +int fn [[gnu::target_version("crc")]] (int) { return 1; } +int fn_crc(int) asm("fn._Mcrc"); +int fn [[gnu::target_version("sha2")]] (int) { return 1; } +int fn_sha2(int) asm("fn._Msha2"); +int fn [[gnu::target_version("sha3")]] (int) { return 1; } +int fn_sha3(int) asm("fn._Msha3"); +int fn [[gnu::target_version("aes")]] (int) { return 1; } +int fn_aes(int) asm("fn._Maes"); +int fn [[gnu::target_version("fp16")]] (int) { return 1; } +int fn_fp16(int) asm("fn._Mfp16"); +int fn [[gnu::target_version("fp16fml")]] (int) { return 1; } +int fn_fp16fml(int) asm("fn._Mfp16fml"); +/* TODO: These FMV features are not yet supported in GCC. */ +// int fn [[gnu::target_version("dit")]] (int) { return 1; } +// int fn [[gnu::target_version("dpb")]] (int) { return 1; } +// int fn [[gnu::target_version("dpb2")]] (int) { return 1; } +int fn [[gnu::target_version("jscvt")]] (int) { return 1; } +int fn_jscvt(int) asm("fn._Mjscvt"); +int fn [[gnu::target_version("fcma")]] (int) { return 1; } +int fn_fcma(int) asm("fn._Mfcma"); +int fn [[gnu::target_version("rcpc")]] (int) { return 1; } +int fn_rcpc(int) asm("fn._Mrcpc"); +int fn [[gnu::target_version("rcpc2")]] (int) { return 1; } +int fn_rcpc2(int) asm("fn._Mrcpc2"); +int fn [[gnu::target_version("rcpc3")]] (int) { return 1; } +int fn_rcpc3(int) asm("fn._Mrcpc3"); +int fn [[gnu::target_version("frintts")]] (int) { return 1; } +int fn_frintts(int) asm("fn._Mfrintts"); +int fn [[gnu::target_version("i8mm")]] (int) { return 1; } +int fn_i8mm(int) asm("fn._Mi8mm"); +int fn [[gnu::target_version("bf16")]] (int) { return 1; } +int fn_bf16(int) asm("fn._Mbf16"); +int fn [[gnu::target_version("sve")]] (int) { return 1; } +int fn_sve(int) asm("fn._Msve"); +int fn [[gnu::target_version("f32mm")]] (int) { return 1; } +int fn_f32mm(int) asm("fn._Mf32mm"); +int fn [[gnu::target_version("f64mm")]] (int) { return 1; } +int fn_f64mm(int) asm("fn._Mf64mm"); +int fn [[gnu::target_version("sve2")]] (int) { return 1; } +int fn_sve2(int) asm("fn._Msve2"); +int fn [[gnu::target_version("sve2-aes")]] (int) { return 1; } +int fn_sve2_aes(int) asm("fn._Msve2_aes"); +int fn [[gnu::target_version("sve2-bitperm")]] (int) { return 1; } +int fn_sve2_bitperm(int) asm("fn._Msve2_bitperm"); +int fn [[gnu::target_version("sve2-sha3")]] (int) { return 1; } +int fn_sve2_sha3(int) asm("fn._Msve2_sha3"); +int fn [[gnu::target_version("sve2-sm4")]] (int) { return 1; } +int fn_sve2_sm4(int) asm("fn._Msve2_sm4"); +int fn [[gnu::target_version("sve2+sme")]] (int) { return 1; } +int fn_sve2_sme(int) asm("fn._Msve2Msme"); +/* TODO: This FMV features is not yet supported in GCC. */ +// int fn [[gnu::target_version("memtag")]] (int) { return 1; } +int fn [[gnu::target_version("sb")]] (int) { return 1; } +int fn_sb(int) asm("fn._Msb"); +/* TODO: This FMV feature is not yet supported in GCC. */ +// int fn [[gnu::target_version("ssbs")]] (int) { return 1; } +// int fn_ssbs(int) asm("fn._Mssbs"); +/* TODO: This FMV feature is not yet supported in GCC. */ +// int fn [[gnu::target_version("bti")]] (int) { return 1; } +int fn [[gnu::target_version("wfxt")]] (int) { return 1; } +int fn_wfxt(int) asm("fn._Mwfxt"); +int fn [[gnu::target_version("sve2+sme-f64f64")]] (int) { return 1; } +int fn_sve2_sme_f64f64(int) asm("fn._Msve2Msme_f64f64"); +int fn [[gnu::target_version("sve2+sme-i16i64")]] (int) { return 1; } +int fn_sve2_sme_i16i64(int) asm("fn._Msve2Msme_i16i64"); +int fn [[gnu::target_version("sve2+sme2")]] (int) { return 1; } +int fn_sve2_sme2(int) asm("fn._Msve2Msme2"); +int fn [[gnu::target_version("mops")]] (int) { return 1; } +int fn_mops(int) asm("fn._Mmops"); +int fn [[gnu::target_version("cssc")]] (int) { return 1; } +int fn_cssc(int) asm("fn._Mcssc"); + diff --git a/gcc/testsuite/gcc.target/aarch64/fmv_priority1.c b/gcc/testsuite/gcc.target/aarch64/fmv_priority1.c new file mode 100644 index 0000000..942b7a7 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/fmv_priority1.c @@ -0,0 +1,175 @@ +/* { dg-do run { target { aarch64_asm_sme2_ok } } } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O0 -march=armv8-a" } */ + +#include <sys/auxv.h> +#include "../../../common/config/aarch64/cpuinfo.h" + +/* This test has a FMV function set with one version per feature we support. + Each version is turned on incrementally and the generated resolver is + checked to show the correct version is chosen. */ + +/* The resolver does actually take arguments, but ignores them and uses + __aarch64_cpu_features global instead to establish what features are + present. */ +int (*(resolver)(void)) (int) asm("fn.resolver"); + +extern struct { + unsigned long long features; +} aarch64_cpu_features asm("__aarch64_cpu_features"); + +#include "fmv_priority.in" + +#define setCPUFeature(F) aarch64_cpu_features.features |= 1UL << F + +int main () { + aarch64_cpu_features.features = 0; + + /* Initialize the CPU features, so the resolver doesn't try fetch it. */ + setCPUFeature(FEAT_INIT); + + /* Go through features in order and assure the priorities are correct. + By checking the correct versions are resolved. */ + + /* Some are missing as they are defined in the ACLE but are not yet + implemented. */ + if (resolver() != &fn_default) return 1; + + setCPUFeature(FEAT_RNG); + if (resolver() != &fn_rng) return 1; + + setCPUFeature(FEAT_FLAGM); + if (resolver() != &fn_flagm) return 1; + + setCPUFeature(FEAT_FLAGM2); + if (resolver() != &fn_flagm2) return 1; + + setCPUFeature (FEAT_LSE); + if (resolver () != &fn_lse) return 1; + + setCPUFeature (FEAT_FP); + if (resolver () != &fn_fp) return 1; + + setCPUFeature (FEAT_SIMD); + if (resolver () != &fn_simd) return 1; + + setCPUFeature (FEAT_DOTPROD); + if (resolver () != &fn_dotprod) return 1; + + setCPUFeature (FEAT_SM4); + if(resolver() != &fn_sm4) return 1; + + setCPUFeature (FEAT_RDM); + if(resolver() != &fn_rdm) return 1; + + setCPUFeature (FEAT_CRC); + if (resolver () != &fn_crc) return 1; + + setCPUFeature (FEAT_SHA2); + if (resolver () != &fn_sha2) return 1; + + setCPUFeature (FEAT_SHA3); + if (resolver () != &fn_sha3) return 1; + + setCPUFeature(FEAT_PMULL); + if(resolver() != &fn_aes) return 1; + + setCPUFeature (FEAT_FP16); + if (resolver () != &fn_fp16) return 1; + + setCPUFeature (FEAT_FP16FML); + if(resolver() != &fn_fp16fml) return 1; + + setCPUFeature (FEAT_DIT); + // if(resolver() != &fn_dit) return 1; + // + setCPUFeature (FEAT_DPB); + // if(resolver() != &fn_dpb) return 1; + // + setCPUFeature (FEAT_DPB2); + // if(resolver() != &fn_dpb2) return 1; + // + setCPUFeature (FEAT_JSCVT); + if (resolver () != &fn_jscvt) return 1; + + setCPUFeature (FEAT_FCMA); + if (resolver () != &fn_fcma) return 1; + + setCPUFeature (FEAT_RCPC); + if (resolver () != &fn_rcpc) return 1; + + setCPUFeature (FEAT_RCPC2); + if (resolver () != &fn_rcpc2) return 1; + + setCPUFeature (FEAT_RCPC3); + // if(resolver() != &fn_rcpc3) return 1; + // + setCPUFeature (FEAT_FRINTTS); + if (resolver () != &fn_frintts) return 1; + + setCPUFeature (FEAT_I8MM); + if (resolver () != &fn_i8mm) return 1; + + setCPUFeature (FEAT_BF16); + if (resolver () != &fn_bf16) return 1; + + setCPUFeature (FEAT_SVE); + if (resolver () != &fn_sve) return 1; + + setCPUFeature (FEAT_SVE_F32MM); + if(resolver() != &fn_f32mm) return 1; + + setCPUFeature (FEAT_SVE_F64MM); + if(resolver() != &fn_f64mm) return 1; + + setCPUFeature (FEAT_SVE2); + if (resolver () != &fn_sve2) return 1; + + setCPUFeature(FEAT_SVE_PMULL128); + if(resolver() != &fn_sve2_aes) return 1; + + setCPUFeature (FEAT_SVE_BITPERM); + if (resolver () != &fn_sve2_bitperm) return 1; + + setCPUFeature (FEAT_SVE_SHA3); + if (resolver () != &fn_sve2_sha3) return 1; + + setCPUFeature (FEAT_SVE_SM4); + if (resolver () != &fn_sve2_sm4) return 1; + + setCPUFeature (FEAT_SME); + if (resolver () != &fn_sve2_sme) return 1; + + setCPUFeature(FEAT_MEMTAG2); + // if(resolver() != &fn_memtag) return 1; + + setCPUFeature (FEAT_SB); + if (resolver () != &fn_sb) return 1; + + setCPUFeature(FEAT_SSBS2); + // if(resolver() != &fn_ssbs) return 1; + + setCPUFeature(FEAT_BTI); + // if(resolver() != &fn_bti) return 1; + + setCPUFeature (FEAT_WFXT); + if (resolver () != &fn_wfxt) return 1; + + setCPUFeature (FEAT_SME_F64); + if (resolver () != &fn_sve2_sme_f64f64) return 1; + + setCPUFeature (FEAT_SME_I64); + if (resolver () != &fn_sve2_sme_i16i64) return 1; + + setCPUFeature (FEAT_SME2); + if (resolver () != &fn_sve2_sme2) return 1; + + setCPUFeature (FEAT_MOPS); + if (resolver () != &fn_mops) return 1; + + setCPUFeature (FEAT_CSSC); + if (resolver () != &fn_cssc) return 1; + + return 0; +} + diff --git a/gcc/testsuite/gcc.target/aarch64/fmv_priority2.c b/gcc/testsuite/gcc.target/aarch64/fmv_priority2.c new file mode 100644 index 0000000..dbeb15e --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/fmv_priority2.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O0 -march=armv8-a -fdump-ipa-targetclone1-details" } */ + +#include "fmv_priority.in" + +// Checks that the versions are in the correct order +// Each of these lines checks 3 consecutive versions in the list with one overlap +/* { dg-final { scan-ipa-dump-times "Version order for fn/\[0-9\]+:\\nfn\.default/\[0-9\]+\\n" 1 "targetclone1" } } */ +/* { dg-final { scan-ipa-dump-times "fn\.default/\[0-9\]+\\nfn\._Mrng/\[0-9\]+\\nfn\._Mflagm/\[0-9\]+\\n" 1 "targetclone1" } } */ +/* { dg-final { scan-ipa-dump-times "fn\._Mflagm/\[0-9\]+\\nfn\._Mflagm2/\[0-9\]+\\nfn\._Mlse/\[0-9\]+\\n" 1 "targetclone1" } } */ +/* { dg-final { scan-ipa-dump-times "fn\._Mlse/\[0-9\]+\\nfn\._Mfp/\[0-9\]+\\nfn\._Msimd/\[0-9\]+\\n" 1 "targetclone1" } } */ +/* { dg-final { scan-ipa-dump-times "fn\._Msimd/\[0-9\]+\\nfn\._Mdotprod/\[0-9\]+\\nfn\._Msm4/\[0-9\]+\\n" 1 "targetclone1" } } */ +/* { dg-final { scan-ipa-dump-times "fn\._Msm4/\[0-9\]+\\nfn\._MrdmaMrdm/\[0-9\]+\\nfn\._Mcrc/\[0-9\]+\\n" 1 "targetclone1" } } */ +/* { dg-final { scan-ipa-dump-times "fn\._Mcrc/\[0-9\]+\\nfn\._Msha2/\[0-9\]+\\nfn\._Msha3/\[0-9\]+\\n" 1 "targetclone1" } } */ +/* { dg-final { scan-ipa-dump-times "fn\._Msha3/\[0-9\]+\\nfn\._Maes/\[0-9\]+\\nfn\._Mfp16/\[0-9\]+\\n" 1 "targetclone1" } } */ +/* { dg-final { scan-ipa-dump-times "fn\._Mfp16/\[0-9\]+\\nfn\._Mfp16fml/\[0-9\]+\\nfn\._Mjscvt/\[0-9\]+\\n" 1 "targetclone1" } } */ +/* { dg-final { scan-ipa-dump-times "fn\._Mjscvt/\[0-9\]+\\nfn\._Mfcma/\[0-9\]+\\nfn\._Mrcpc/\[0-9\]+\\n" 1 "targetclone1" } } */ +/* { dg-final { scan-ipa-dump-times "fn\._Mrcpc/\[0-9\]+\\nfn\._Mrcpc2/\[0-9\]+\\nfn\._Mrcpc3/\[0-9\]+\\n" 1 "targetclone1" } } */ +/* { dg-final { scan-ipa-dump-times "fn\._Mrcpc3/\[0-9\]+\\nfn\._Mfrintts/\[0-9\]+\\nfn\._Mi8mm/\[0-9\]+\\n" 1 "targetclone1" } } */ +/* { dg-final { scan-ipa-dump-times "fn\._Mi8mm/\[0-9\]+\\nfn\._Mbf16/\[0-9\]+\\nfn\._Msve/\[0-9\]+\\n" 1 "targetclone1" } } */ +/* { dg-final { scan-ipa-dump-times "fn\._Msve/\[0-9\]+\\nfn\._Mf32mm/\[0-9\]+\\nfn\._Mf64mm/\[0-9\]+\\n" 1 "targetclone1" } } */ +/* { dg-final { scan-ipa-dump-times "fn\._Mf64mm/\[0-9\]+\\nfn\._Msve2/\[0-9\]+\\nfn\._Msve2_aes/\[0-9\]+\\n" 1 "targetclone1" } } */ +/* { dg-final { scan-ipa-dump-times "fn\._Msve2_aes/\[0-9\]+\\nfn\._Msve2_bitperm/\[0-9\]+\\nfn\._Msve2_sha3/\[0-9\]+\\n" 1 "targetclone1" } } */ +/* { dg-final { scan-ipa-dump-times "fn\._Msve2_sha3/\[0-9\]+\\nfn\._Msve2_sm4/\[0-9\]+\\nfn\._Msve2Msme/\[0-9\]+\\n" 1 "targetclone1" } } */ +/* { dg-final { scan-ipa-dump-times "fn\._Msve2Msme/\[0-9\]+\\nfn\._Msb/\[0-9\]+\\nfn\._Mwfxt/\[0-9\]+\\n" 1 "targetclone1" } } */ +/* { dg-final { scan-ipa-dump-times "fn\._Mwfxt/\[0-9\]+\\nfn\._Msve2Msme_f64f64/\[0-9\]+\\nfn\._Msve2Msme_i16i64/\[0-9\]+\\n" 1 "targetclone1" } } */ +/* { dg-final { scan-ipa-dump-times "fn\._Msve2Msme_i16i64/\[0-9\]+\\nfn\._Msve2Msme2/\[0-9\]+\\nfn\._Mmops/\[0-9\]+\\n" 1 "targetclone1" } } */ +/* { dg-final { scan-ipa-dump-times "fn\._Mmops/\[0-9\]+\\nfn\._Mcssc/\[0-9\]+\\n" 1 "targetclone1" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/pr122190.c b/gcc/testsuite/gcc.target/aarch64/pr122190.c new file mode 100644 index 0000000..8546e12 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr122190.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O0 -march=armv8-a -fdump-ipa-targetclone1-details" } */ + +int fn (int a) {return 1;} +int fn[[gnu::target_version("sve")]] (int a) {return 2;} +int fn[[gnu::target_version("simd+dotprod")]] (int a) {return 3;} +int fn[[gnu::target_version("sve+fp")]] (int a) {return 2;} + +/* { dg-final { scan-ipa-dump-times "Version order for fn/\[0-9\]+:\\nfn\.default/\[0-9\]+\\nfn\._MsimdMdotprod/\[0-9\]+\\nfn\._Msve/\[0-9\]+\\nfn\._MfpMsve/\[0-9\]+\\n" 1 "targetclone1" } } */ diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr122223.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr122223.c index 59e757a..045815c 100644 --- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr122223.c +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr122223.c @@ -21,5 +21,5 @@ float32x4_t foo() { } #endif -/* { dg-final { scan-assembler-not "vmov.f32\tq0, #0.0" } } */ -/* { dg-final { scan-assembler "vmov.f32\tq0, #1.0" } } */ +/* { dg-final { scan-assembler-not "vmov.f32\tq\[0-9\]+, #0.0" } } */ +/* { dg-final { scan-assembler "vmov.f32\tq\[0-9\]+, #1.0" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr101639_reduc_mask_and_vqi.c b/gcc/testsuite/gcc.target/i386/pr101639_reduc_mask_and_vqi.c new file mode 100644 index 0000000..23fc67e --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr101639_reduc_mask_and_vqi.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-march=x86-64-v3 -O2" } */ +/* { dg-final { scan-assembler-times "vptest" 1 } } */ +/* { dg-final { scan-assembler-times "sete" 1 } } */ +/* { dg-final { scan-assembler-times "vpcmpeq" 1 } } */ + +bool f2(char * p, long n) +{ + bool r = true; + for(long i = 0; i < 32; ++i) + r &= (p[i] != 0); + return r; +} + diff --git a/gcc/testsuite/gcc.target/i386/pr101639_reduc_mask_ior_vqi.c b/gcc/testsuite/gcc.target/i386/pr101639_reduc_mask_ior_vqi.c new file mode 100644 index 0000000..e1deb2f --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr101639_reduc_mask_ior_vqi.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-march=x86-64-v3 -O2" } */ +/* { dg-final { scan-assembler-times "vptest" 1 } } */ +/* { dg-final { scan-assembler-times "setne" 1 } } */ +/* { dg-final { scan-assembler-not "vpcmpeq" } } */ + +bool f2(char * p, long n) +{ + bool r = false; + for(long i = 0; i < 32; ++i) + r |= (p[i] != 0); + return r; +} + diff --git a/gcc/testsuite/gcc.target/i386/pr101639_reduc_mask_vdi.c b/gcc/testsuite/gcc.target/i386/pr101639_reduc_mask_vdi.c new file mode 100644 index 0000000..ee52697 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr101639_reduc_mask_vdi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-march=x86-64-v3 -O2" } */ +/* { dg-final { scan-assembler-times "vptest" 2 } } */ +/* { dg-final { scan-assembler-times "sete" 1 } } */ +/* { dg-final { scan-assembler-times "setne" 1 } } */ +/* { dg-final { scan-assembler-times "popcnt" 1 } } */ +/* { dg-final { scan-assembler-times "vmovmskpd" 1 } } */ + +bool f(long long *p, long n) +{ + bool r = true; + for(long i = 0; i < 4; ++i) + r &= (p[i] != 0); + return r; +} + +bool f2(long long *p, long n) +{ + bool r = false; + for(long i = 0; i < 4; ++i) + r |= (p[i] != 0); + return r; +} + +bool f3(long long *p, long n) +{ + bool r = false; + for(long i = 0; i < 4; ++i) + r ^= (p[i] != 0); + return r; +} diff --git a/gcc/testsuite/gcc.target/i386/pr101639_reduc_mask_vqi.c b/gcc/testsuite/gcc.target/i386/pr101639_reduc_mask_vqi.c new file mode 100644 index 0000000..1707f15 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr101639_reduc_mask_vqi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-march=x86-64-v3 -O2" } */ +/* { dg-final { scan-assembler-times "vptest" 2 } } */ +/* { dg-final { scan-assembler-times "sete" 1 } } */ +/* { dg-final { scan-assembler-times "setne" 1 } } */ +/* { dg-final { scan-assembler-times "popcnt" 1 } } */ +/* { dg-final { scan-assembler-times "vpmovmskb" 1 } } */ + +bool f(char * p, long n) +{ + bool r = true; + for(long i = 0; i < 32; ++i) + r &= (p[i] != 0); + return r; +} + +bool f2(char * p, long n) +{ + bool r = false; + for(long i = 0; i < 32; ++i) + r |= (p[i] != 0); + return r; +} + +bool f3(char * p, long n) +{ + bool r = false; + for(long i = 0; i < 32; ++i) + r ^= (p[i] != 0); + return r; +} diff --git a/gcc/testsuite/gcc.target/i386/pr101639_reduc_mask_vsi.c b/gcc/testsuite/gcc.target/i386/pr101639_reduc_mask_vsi.c new file mode 100644 index 0000000..2d4a39f --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr101639_reduc_mask_vsi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-march=x86-64-v3 -O2" } */ +/* { dg-final { scan-assembler-times "vptest" 2 } } */ +/* { dg-final { scan-assembler-times "sete" 1 } } */ +/* { dg-final { scan-assembler-times "setne" 1 } } */ +/* { dg-final { scan-assembler-times "popcnt" 1 } } */ +/* { dg-final { scan-assembler-times "vmovmskps" 1 } } */ + +bool f(int * p, long n) +{ + bool r = true; + for(long i = 0; i < 8; ++i) + r &= (p[i] != 0); + return r; +} + +bool f2(int * p, long n) +{ + bool r = false; + for(long i = 0; i < 8; ++i) + r |= (p[i] != 0); + return r; +} + +bool f3(int * p, long n) +{ + bool r = false; + for(long i = 0; i < 8; ++i) + r ^= (p[i] != 0); + return r; +} diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc index 031184d..88153d3 100644 --- a/gcc/tree-ssa-phiopt.cc +++ b/gcc/tree-ssa-phiopt.cc @@ -1007,7 +1007,34 @@ match_simplify_replacement (basic_block cond_bb, basic_block middle_bb, } if (!result) - return false; + { + /* If we don't get back a MIN/MAX_EXPR still make sure the expression + stays in a form to be recognized by ISA that map to IEEE x > y ? x : y + semantics (that's not IEEE max semantics). */ + if (!HONOR_NANS (type) && !HONOR_SIGNED_ZEROS (type)) + return false; + if (stmt_to_move || stmt_to_move_alt) + return false; + tree_code cmp = gimple_cond_code (stmt); + if (cmp != LT_EXPR && cmp != LE_EXPR + && cmp != GT_EXPR && cmp != GE_EXPR) + return false; + tree lhs = gimple_cond_lhs (stmt); + tree rhs = gimple_cond_rhs (stmt); + /* `lhs CMP rhs ? lhs : rhs` or `lhs CMP rhs ? rhs : lhs` + are only acceptable case here. */ + if ((!operand_equal_for_phi_arg_p (lhs, arg_false) + || !operand_equal_for_phi_arg_p (rhs, arg_true)) + && (!operand_equal_for_phi_arg_p (rhs, arg_false) + || !operand_equal_for_phi_arg_p (lhs, arg_true))) + return false; + seq = nullptr; + result = gimple_build (&seq, cmp, boolean_type_node, lhs, rhs); + result = gimple_build (&seq, COND_EXPR, type, result, + arg_true, arg_false); + statistics_counter_event (cfun, "Non-IEEE FP MIN/MAX PHI replacement", + 1); + } if (dump_file && (dump_flags & TDF_FOLDING)) fprintf (dump_file, "accepted the phiopt match-simplify.\n"); @@ -1767,622 +1794,6 @@ value_replacement (basic_block cond_bb, basic_block middle_bb, return 0; } -/* If VAR is an SSA_NAME that points to a BIT_NOT_EXPR then return the TREE for - the value being inverted. */ - -static tree -strip_bit_not (tree var) -{ - if (TREE_CODE (var) != SSA_NAME) - return NULL_TREE; - - gimple *assign = SSA_NAME_DEF_STMT (var); - if (gimple_code (assign) != GIMPLE_ASSIGN) - return NULL_TREE; - - if (gimple_assign_rhs_code (assign) != BIT_NOT_EXPR) - return NULL_TREE; - - return gimple_assign_rhs1 (assign); -} - -/* Invert a MIN to a MAX or a MAX to a MIN expression CODE. */ - -enum tree_code -invert_minmax_code (enum tree_code code) -{ - switch (code) { - case MIN_EXPR: - return MAX_EXPR; - case MAX_EXPR: - return MIN_EXPR; - default: - gcc_unreachable (); - } -} - -/* The function minmax_replacement does the main work of doing the minmax - replacement. Return true if the replacement is done. Otherwise return - false. - BB is the basic block where the replacement is going to be done on. ARG0 - is argument 0 from the PHI. Likewise for ARG1. - - If THREEWAY_P then expect the BB to be laid out in diamond shape with each - BB containing only a MIN or MAX expression. */ - -static bool -minmax_replacement (basic_block cond_bb, basic_block middle_bb, basic_block alt_middle_bb, - edge e0, edge e1, gphi *phi, tree arg0, tree arg1, bool threeway_p) -{ - tree result; - edge true_edge, false_edge; - enum tree_code minmax, ass_code; - tree smaller, larger, arg_true, arg_false; - gimple_stmt_iterator gsi, gsi_from; - - tree type = TREE_TYPE (gimple_phi_result (phi)); - - gcond *cond = as_a <gcond *> (*gsi_last_bb (cond_bb)); - enum tree_code cmp = gimple_cond_code (cond); - tree rhs = gimple_cond_rhs (cond); - - /* Turn EQ/NE of extreme values to order comparisons. */ - if ((cmp == NE_EXPR || cmp == EQ_EXPR) - && TREE_CODE (rhs) == INTEGER_CST - && INTEGRAL_TYPE_P (TREE_TYPE (rhs))) - { - if (wi::eq_p (wi::to_wide (rhs), wi::min_value (TREE_TYPE (rhs)))) - { - cmp = (cmp == EQ_EXPR) ? LT_EXPR : GE_EXPR; - rhs = wide_int_to_tree (TREE_TYPE (rhs), - wi::min_value (TREE_TYPE (rhs)) + 1); - } - else if (wi::eq_p (wi::to_wide (rhs), wi::max_value (TREE_TYPE (rhs)))) - { - cmp = (cmp == EQ_EXPR) ? GT_EXPR : LE_EXPR; - rhs = wide_int_to_tree (TREE_TYPE (rhs), - wi::max_value (TREE_TYPE (rhs)) - 1); - } - } - - /* This transformation is only valid for order comparisons. Record which - operand is smaller/larger if the result of the comparison is true. */ - tree alt_smaller = NULL_TREE; - tree alt_larger = NULL_TREE; - if (cmp == LT_EXPR || cmp == LE_EXPR) - { - smaller = gimple_cond_lhs (cond); - larger = rhs; - /* If we have smaller < CST it is equivalent to smaller <= CST-1. - Likewise smaller <= CST is equivalent to smaller < CST+1. */ - if (TREE_CODE (larger) == INTEGER_CST - && INTEGRAL_TYPE_P (TREE_TYPE (larger))) - { - if (cmp == LT_EXPR) - { - wi::overflow_type overflow; - wide_int alt = wi::sub (wi::to_wide (larger), 1, - TYPE_SIGN (TREE_TYPE (larger)), - &overflow); - if (! overflow) - alt_larger = wide_int_to_tree (TREE_TYPE (larger), alt); - } - else - { - wi::overflow_type overflow; - wide_int alt = wi::add (wi::to_wide (larger), 1, - TYPE_SIGN (TREE_TYPE (larger)), - &overflow); - if (! overflow) - alt_larger = wide_int_to_tree (TREE_TYPE (larger), alt); - } - } - } - else if (cmp == GT_EXPR || cmp == GE_EXPR) - { - smaller = rhs; - larger = gimple_cond_lhs (cond); - /* If we have larger > CST it is equivalent to larger >= CST+1. - Likewise larger >= CST is equivalent to larger > CST-1. */ - if (TREE_CODE (smaller) == INTEGER_CST - && INTEGRAL_TYPE_P (TREE_TYPE (smaller))) - { - wi::overflow_type overflow; - if (cmp == GT_EXPR) - { - wide_int alt = wi::add (wi::to_wide (smaller), 1, - TYPE_SIGN (TREE_TYPE (smaller)), - &overflow); - if (! overflow) - alt_smaller = wide_int_to_tree (TREE_TYPE (smaller), alt); - } - else - { - wide_int alt = wi::sub (wi::to_wide (smaller), 1, - TYPE_SIGN (TREE_TYPE (smaller)), - &overflow); - if (! overflow) - alt_smaller = wide_int_to_tree (TREE_TYPE (smaller), alt); - } - } - } - else - return false; - - /* Handle the special case of (signed_type)x < 0 being equivalent - to x > MAX_VAL(signed_type) and (signed_type)x >= 0 equivalent - to x <= MAX_VAL(signed_type). */ - if ((cmp == GE_EXPR || cmp == LT_EXPR) - && INTEGRAL_TYPE_P (type) - && TYPE_UNSIGNED (type) - && integer_zerop (rhs)) - { - tree op = gimple_cond_lhs (cond); - if (TREE_CODE (op) == SSA_NAME - && INTEGRAL_TYPE_P (TREE_TYPE (op)) - && !TYPE_UNSIGNED (TREE_TYPE (op))) - { - gimple *def_stmt = SSA_NAME_DEF_STMT (op); - if (gimple_assign_cast_p (def_stmt)) - { - tree op1 = gimple_assign_rhs1 (def_stmt); - if (INTEGRAL_TYPE_P (TREE_TYPE (op1)) - && TYPE_UNSIGNED (TREE_TYPE (op1)) - && (TYPE_PRECISION (TREE_TYPE (op)) - == TYPE_PRECISION (TREE_TYPE (op1))) - && useless_type_conversion_p (type, TREE_TYPE (op1))) - { - wide_int w1 = wi::max_value (TREE_TYPE (op)); - wide_int w2 = wi::add (w1, 1); - if (cmp == LT_EXPR) - { - larger = op1; - smaller = wide_int_to_tree (TREE_TYPE (op1), w1); - alt_smaller = wide_int_to_tree (TREE_TYPE (op1), w2); - alt_larger = NULL_TREE; - } - else - { - smaller = op1; - larger = wide_int_to_tree (TREE_TYPE (op1), w1); - alt_larger = wide_int_to_tree (TREE_TYPE (op1), w2); - alt_smaller = NULL_TREE; - } - } - } - } - } - - /* We need to know which is the true edge and which is the false - edge so that we know if have abs or negative abs. */ - extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge); - - /* Forward the edges over the middle basic block. */ - if (true_edge->dest == middle_bb) - true_edge = EDGE_SUCC (true_edge->dest, 0); - if (false_edge->dest == middle_bb) - false_edge = EDGE_SUCC (false_edge->dest, 0); - - /* When THREEWAY_P then e1 will point to the edge of the final transition - from middle-bb to end. */ - if (true_edge == e0) - { - if (!threeway_p) - gcc_assert (false_edge == e1); - arg_true = arg0; - arg_false = arg1; - } - else - { - gcc_assert (false_edge == e0); - if (!threeway_p) - gcc_assert (true_edge == e1); - arg_true = arg1; - arg_false = arg0; - } - - if (empty_block_p (middle_bb) - && (!threeway_p - || empty_block_p (alt_middle_bb))) - { - if ((operand_equal_for_phi_arg_p (arg_true, smaller) - || (alt_smaller - && operand_equal_for_phi_arg_p (arg_true, alt_smaller))) - && (operand_equal_for_phi_arg_p (arg_false, larger) - || (alt_larger - && operand_equal_for_phi_arg_p (arg_true, alt_larger)))) - { - /* Case - - if (smaller < larger) - rslt = smaller; - else - rslt = larger; */ - minmax = MIN_EXPR; - } - else if ((operand_equal_for_phi_arg_p (arg_false, smaller) - || (alt_smaller - && operand_equal_for_phi_arg_p (arg_false, alt_smaller))) - && (operand_equal_for_phi_arg_p (arg_true, larger) - || (alt_larger - && operand_equal_for_phi_arg_p (arg_true, alt_larger)))) - minmax = MAX_EXPR; - else - return false; - } - else if (HONOR_NANS (type) || HONOR_SIGNED_ZEROS (type)) - /* The optimization may be unsafe due to NaNs. */ - return false; - else if (middle_bb != alt_middle_bb && threeway_p) - { - /* Recognize the following case: - - if (smaller < larger) - a = MIN (smaller, c); - else - b = MIN (larger, c); - x = PHI <a, b> - - This is equivalent to - - a = MIN (smaller, c); - x = MIN (larger, a); */ - - gimple *assign = last_and_only_stmt (middle_bb); - tree lhs, op0, op1, bound; - tree alt_lhs, alt_op0, alt_op1; - bool invert = false; - - /* When THREEWAY_P then e1 will point to the edge of the final transition - from middle-bb to end. */ - if (true_edge == e0) - gcc_assert (false_edge == EDGE_PRED (e1->src, 0)); - else - gcc_assert (true_edge == EDGE_PRED (e1->src, 0)); - - bool valid_minmax_p = false; - gimple_stmt_iterator it1 - = gsi_start_nondebug_after_labels_bb (middle_bb); - gimple_stmt_iterator it2 - = gsi_start_nondebug_after_labels_bb (alt_middle_bb); - if (gsi_one_nondebug_before_end_p (it1) - && gsi_one_nondebug_before_end_p (it2)) - { - gimple *stmt1 = gsi_stmt (it1); - gimple *stmt2 = gsi_stmt (it2); - if (is_gimple_assign (stmt1) && is_gimple_assign (stmt2)) - { - enum tree_code code1 = gimple_assign_rhs_code (stmt1); - enum tree_code code2 = gimple_assign_rhs_code (stmt2); - valid_minmax_p = (code1 == MIN_EXPR || code1 == MAX_EXPR) - && (code2 == MIN_EXPR || code2 == MAX_EXPR); - } - } - - if (!valid_minmax_p) - return false; - - if (!assign - || gimple_code (assign) != GIMPLE_ASSIGN) - return false; - - /* There cannot be any phi nodes in the middle bb. */ - if (!gimple_seq_empty_p (phi_nodes (middle_bb))) - return false; - - lhs = gimple_assign_lhs (assign); - ass_code = gimple_assign_rhs_code (assign); - if (ass_code != MAX_EXPR && ass_code != MIN_EXPR) - return false; - - op0 = gimple_assign_rhs1 (assign); - op1 = gimple_assign_rhs2 (assign); - - assign = last_and_only_stmt (alt_middle_bb); - if (!assign - || gimple_code (assign) != GIMPLE_ASSIGN) - return false; - - /* There cannot be any phi nodes in the alt middle bb. */ - if (!gimple_seq_empty_p (phi_nodes (alt_middle_bb))) - return false; - - alt_lhs = gimple_assign_lhs (assign); - if (ass_code != gimple_assign_rhs_code (assign)) - return false; - - if (!operand_equal_for_phi_arg_p (lhs, arg_true) - || !operand_equal_for_phi_arg_p (alt_lhs, arg_false)) - return false; - - alt_op0 = gimple_assign_rhs1 (assign); - alt_op1 = gimple_assign_rhs2 (assign); - - if ((operand_equal_for_phi_arg_p (op0, smaller) - || (alt_smaller - && operand_equal_for_phi_arg_p (op0, alt_smaller))) - && (operand_equal_for_phi_arg_p (alt_op0, larger) - || (alt_larger - && operand_equal_for_phi_arg_p (alt_op0, alt_larger)))) - { - /* We got here if the condition is true, i.e., SMALLER < LARGER. */ - if (!operand_equal_for_phi_arg_p (op1, alt_op1)) - return false; - - if ((arg0 = strip_bit_not (op0)) != NULL - && (arg1 = strip_bit_not (alt_op0)) != NULL - && (bound = strip_bit_not (op1)) != NULL) - { - minmax = MAX_EXPR; - ass_code = invert_minmax_code (ass_code); - invert = true; - } - else - { - bound = op1; - minmax = MIN_EXPR; - arg0 = op0; - arg1 = alt_op0; - } - } - else if ((operand_equal_for_phi_arg_p (op0, larger) - || (alt_larger - && operand_equal_for_phi_arg_p (op0, alt_larger))) - && (operand_equal_for_phi_arg_p (alt_op0, smaller) - || (alt_smaller - && operand_equal_for_phi_arg_p (alt_op0, alt_smaller)))) - { - /* We got here if the condition is true, i.e., SMALLER > LARGER. */ - if (!operand_equal_for_phi_arg_p (op1, alt_op1)) - return false; - - if ((arg0 = strip_bit_not (op0)) != NULL - && (arg1 = strip_bit_not (alt_op0)) != NULL - && (bound = strip_bit_not (op1)) != NULL) - { - minmax = MIN_EXPR; - ass_code = invert_minmax_code (ass_code); - invert = true; - } - else - { - bound = op1; - minmax = MAX_EXPR; - arg0 = op0; - arg1 = alt_op0; - } - } - else - return false; - - /* Emit the statement to compute min/max. */ - location_t locus = gimple_location (last_nondebug_stmt (cond_bb)); - gimple_seq stmts = NULL; - tree phi_result = gimple_phi_result (phi); - result = gimple_build (&stmts, locus, minmax, TREE_TYPE (phi_result), - arg0, arg1); - result = gimple_build (&stmts, locus, ass_code, TREE_TYPE (phi_result), - result, bound); - if (invert) - result = gimple_build (&stmts, locus, BIT_NOT_EXPR, TREE_TYPE (phi_result), - result); - - gsi = gsi_last_bb (cond_bb); - gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT); - - replace_phi_edge_with_variable (cond_bb, e1, phi, result); - - return true; - } - else if (!threeway_p - || empty_block_p (alt_middle_bb)) - { - /* Recognize the following case, assuming d <= u: - - if (a <= u) - b = MAX (a, d); - x = PHI <b, u> - - This is equivalent to - - b = MAX (a, d); - x = MIN (b, u); */ - - gimple *assign = last_and_only_stmt (middle_bb); - tree lhs, op0, op1, bound; - - if (!single_pred_p (middle_bb)) - return false; - - if (!assign - || gimple_code (assign) != GIMPLE_ASSIGN) - return false; - - /* There cannot be any phi nodes in the middle bb. */ - if (!gimple_seq_empty_p (phi_nodes (middle_bb))) - return false; - - lhs = gimple_assign_lhs (assign); - ass_code = gimple_assign_rhs_code (assign); - if (ass_code != MAX_EXPR && ass_code != MIN_EXPR) - return false; - op0 = gimple_assign_rhs1 (assign); - op1 = gimple_assign_rhs2 (assign); - - if (true_edge->src == middle_bb) - { - /* We got here if the condition is true, i.e., SMALLER < LARGER. */ - if (!operand_equal_for_phi_arg_p (lhs, arg_true)) - return false; - - if (operand_equal_for_phi_arg_p (arg_false, larger) - || (alt_larger - && operand_equal_for_phi_arg_p (arg_false, alt_larger))) - { - /* Case - - if (smaller < larger) - { - r' = MAX_EXPR (smaller, bound) - } - r = PHI <r', larger> --> to be turned to MIN_EXPR. */ - if (ass_code != MAX_EXPR) - return false; - - minmax = MIN_EXPR; - if (operand_equal_for_phi_arg_p (op0, smaller) - || (alt_smaller - && operand_equal_for_phi_arg_p (op0, alt_smaller))) - bound = op1; - else if (operand_equal_for_phi_arg_p (op1, smaller) - || (alt_smaller - && operand_equal_for_phi_arg_p (op1, alt_smaller))) - bound = op0; - else - return false; - - /* We need BOUND <= LARGER. */ - if (!integer_nonzerop (fold_build2 (LE_EXPR, boolean_type_node, - bound, arg_false))) - return false; - } - else if (operand_equal_for_phi_arg_p (arg_false, smaller) - || (alt_smaller - && operand_equal_for_phi_arg_p (arg_false, alt_smaller))) - { - /* Case - - if (smaller < larger) - { - r' = MIN_EXPR (larger, bound) - } - r = PHI <r', smaller> --> to be turned to MAX_EXPR. */ - if (ass_code != MIN_EXPR) - return false; - - minmax = MAX_EXPR; - if (operand_equal_for_phi_arg_p (op0, larger) - || (alt_larger - && operand_equal_for_phi_arg_p (op0, alt_larger))) - bound = op1; - else if (operand_equal_for_phi_arg_p (op1, larger) - || (alt_larger - && operand_equal_for_phi_arg_p (op1, alt_larger))) - bound = op0; - else - return false; - - /* We need BOUND >= SMALLER. */ - if (!integer_nonzerop (fold_build2 (GE_EXPR, boolean_type_node, - bound, arg_false))) - return false; - } - else - return false; - } - else - { - /* We got here if the condition is false, i.e., SMALLER > LARGER. */ - if (!operand_equal_for_phi_arg_p (lhs, arg_false)) - return false; - - if (operand_equal_for_phi_arg_p (arg_true, larger) - || (alt_larger - && operand_equal_for_phi_arg_p (arg_true, alt_larger))) - { - /* Case - - if (smaller > larger) - { - r' = MIN_EXPR (smaller, bound) - } - r = PHI <r', larger> --> to be turned to MAX_EXPR. */ - if (ass_code != MIN_EXPR) - return false; - - minmax = MAX_EXPR; - if (operand_equal_for_phi_arg_p (op0, smaller) - || (alt_smaller - && operand_equal_for_phi_arg_p (op0, alt_smaller))) - bound = op1; - else if (operand_equal_for_phi_arg_p (op1, smaller) - || (alt_smaller - && operand_equal_for_phi_arg_p (op1, alt_smaller))) - bound = op0; - else - return false; - - /* We need BOUND >= LARGER. */ - if (!integer_nonzerop (fold_build2 (GE_EXPR, boolean_type_node, - bound, arg_true))) - return false; - } - else if (operand_equal_for_phi_arg_p (arg_true, smaller) - || (alt_smaller - && operand_equal_for_phi_arg_p (arg_true, alt_smaller))) - { - /* Case - - if (smaller > larger) - { - r' = MAX_EXPR (larger, bound) - } - r = PHI <r', smaller> --> to be turned to MIN_EXPR. */ - if (ass_code != MAX_EXPR) - return false; - - minmax = MIN_EXPR; - if (operand_equal_for_phi_arg_p (op0, larger)) - bound = op1; - else if (operand_equal_for_phi_arg_p (op1, larger)) - bound = op0; - else - return false; - - /* We need BOUND <= SMALLER. */ - if (!integer_nonzerop (fold_build2 (LE_EXPR, boolean_type_node, - bound, arg_true))) - return false; - } - else - return false; - } - - /* Move the statement from the middle block. */ - gsi = gsi_last_bb (cond_bb); - gsi_from = gsi_last_nondebug_bb (middle_bb); - reset_flow_sensitive_info (SINGLE_SSA_TREE_OPERAND (gsi_stmt (gsi_from), - SSA_OP_DEF)); - gsi_move_before (&gsi_from, &gsi); - } - else - return false; - - /* Emit the statement to compute min/max. */ - gimple_seq stmts = NULL; - tree phi_result = gimple_phi_result (phi); - - /* When we can't use a MIN/MAX_EXPR still make sure the expression - stays in a form to be recognized by ISA that map to IEEE x > y ? x : y - semantics (that's not IEEE max semantics). */ - if (HONOR_NANS (type) || HONOR_SIGNED_ZEROS (type)) - { - result = gimple_build (&stmts, cmp, boolean_type_node, - gimple_cond_lhs (cond), rhs); - result = gimple_build (&stmts, COND_EXPR, TREE_TYPE (phi_result), - result, arg_true, arg_false); - } - else - result = gimple_build (&stmts, minmax, TREE_TYPE (phi_result), arg0, arg1); - - gsi = gsi_last_bb (cond_bb); - gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT); - - replace_phi_edge_with_variable (cond_bb, e1, phi, result); - - return true; -} - /* Attempt to optimize (x <=> y) cmp 0 and similar comparisons. For strong ordering <=> try to match something like: <bb 2> : // cond3_bb (== cond2_bb) @@ -4365,9 +3776,8 @@ execute_over_cond_phis (func_type func) But in this case bb1/bb2 can only be forwarding basic blocks. This fully replaces the old "Conditional Replacement", - "ABS Replacement" transformations as they are now + "ABS Replacement" and "MIN/MAX Replacement" transformations as they are now implmeneted in match.pd. - Some parts of the "MIN/MAX Replacement" are re-implemented in match.pd. Value Replacement ----------------- @@ -4409,26 +3819,6 @@ execute_over_cond_phis (func_type func) t3 = t1 & t2; x = a; - MIN/MAX Replacement - ------------------- - - This transformation, minmax_replacement replaces - - bb0: - if (a <= b) goto bb2; else goto bb1; - bb1: - bb2: - x = PHI <b (bb1), a (bb0), ...>; - - with - - bb0: - x' = MIN_EXPR (a, b) - bb2: - x = PHI <x' (bb0), ...>; - - A similar transformation is done for MAX_EXPR. - This pass also performs a fifth transformation of a slightly different flavor. @@ -4642,9 +4032,6 @@ pass_phiopt::execute (function *) && cond_removal_in_builtin_zero_pattern (bb, bb1, e1, e2, phi, arg0, arg1)) cfgchanged = true; - else if (minmax_replacement (bb, bb1, bb2, e1, e2, phi, arg0, arg1, - diamond_p)) - cfgchanged = true; else if (single_pred_p (bb1) && !diamond_p && spaceship_replacement (bb, bb1, e1, e2, phi, arg0, arg1)) diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc index 9320bf8..a98c06d 100644 --- a/gcc/tree-vect-loop.cc +++ b/gcc/tree-vect-loop.cc @@ -738,7 +738,6 @@ _loop_vec_info::_loop_vec_info (class loop *loop_in, vec_info_shared *shared) nonlinear_iv (false), ivexpr_map (NULL), scan_map (NULL), - slp_unrolling_factor (1), inner_loop_cost_factor (param_vect_inner_loop_cost_factor), vectorizable (false), can_use_partial_vectors_p (param_vect_partial_vector_usage != 0), @@ -2236,16 +2235,15 @@ start_over: if (!ok) return ok; - /* If there are any SLP instances mark them as pure_slp. */ + /* If there are any SLP instances mark them as pure_slp and compute + the overall vectorization factor. */ if (!vect_make_slp_decision (loop_vinfo)) return opt_result::failure_at (vect_location, "no stmts to vectorize.\n"); if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, "Loop contains only SLP stmts\n"); - /* Determine the vectorization factor from the SLP decision. */ - LOOP_VINFO_VECT_FACTOR (loop_vinfo) - = LOOP_VINFO_SLP_UNROLLING_FACTOR (loop_vinfo); + /* Dump the vectorization factor from the SLP decision. */ if (dump_enabled_p ()) { dump_printf_loc (MSG_NOTE, vect_location, "vectorization factor = "); @@ -2253,12 +2251,6 @@ start_over: dump_printf (MSG_NOTE, "\n"); } - /* Optimize the SLP graph with the vectorization factor fixed. */ - vect_optimize_slp (loop_vinfo); - - /* Gather the loads reachable from the SLP graph entries. */ - vect_gather_slp_loads (loop_vinfo); - /* We don't expect to have to roll back to anything other than an empty set of rgroups. */ gcc_assert (LOOP_VINFO_MASKS (loop_vinfo).is_empty ()); @@ -2273,6 +2265,12 @@ start_over: poly_uint64 vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo); gcc_assert (known_ne (vectorization_factor, 0U)); + /* Optimize the SLP graph with the vectorization factor fixed. */ + vect_optimize_slp (loop_vinfo); + + /* Gather the loads reachable from the SLP graph entries. */ + vect_gather_slp_loads (loop_vinfo); + if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo) && dump_enabled_p ()) { dump_printf_loc (MSG_NOTE, vect_location, @@ -2598,7 +2596,7 @@ again: stmt_vec_info vinfo; vinfo = SLP_TREE_SCALAR_STMTS (SLP_INSTANCE_TREE (instance))[0]; - if (! STMT_VINFO_GROUPED_ACCESS (vinfo)) + if (!vinfo || !STMT_VINFO_GROUPED_ACCESS (vinfo)) continue; vinfo = DR_GROUP_FIRST_ELEMENT (vinfo); unsigned int size = DR_GROUP_SIZE (vinfo); diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc index 9698709..3c760b4 100644 --- a/gcc/tree-vect-slp.cc +++ b/gcc/tree-vect-slp.cc @@ -8171,7 +8171,7 @@ vect_make_slp_decision (loop_vec_info loop_vinfo) decided_to_slp++; } - LOOP_VINFO_SLP_UNROLLING_FACTOR (loop_vinfo) = unrolling_factor; + LOOP_VINFO_VECT_FACTOR (loop_vinfo) = unrolling_factor; if (decided_to_slp && dump_enabled_p ()) { diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index 905a291..56b3a5a 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -945,7 +945,8 @@ public: used. */ poly_uint64 versioning_threshold; - /* Unrolling factor */ + /* Unrolling factor. In case of suitable super-word parallelism + it can be that no unrolling is needed, and thus this is 1. */ poly_uint64 vectorization_factor; /* If this loop is an epilogue loop whose main loop can be skipped, @@ -1090,10 +1091,6 @@ public: rhs of the store of the initializer. */ hash_map<tree, tree> *scan_map; - /* The unrolling factor needed to SLP the loop. In case of that pure SLP is - applied to the loop, i.e., no unrolling is needed, this is 1. */ - poly_uint64 slp_unrolling_factor; - /* The factor used to over weight those statements in an inner loop relative to the loop being vectorized. */ unsigned int inner_loop_cost_factor; @@ -1294,7 +1291,6 @@ public: #define LOOP_VINFO_USER_UNROLL(L) (L)->user_unroll #define LOOP_VINFO_GROUPED_STORES(L) (L)->grouped_stores #define LOOP_VINFO_SLP_INSTANCES(L) (L)->slp_instances -#define LOOP_VINFO_SLP_UNROLLING_FACTOR(L) (L)->slp_unrolling_factor #define LOOP_VINFO_REDUCTIONS(L) (L)->reductions #define LOOP_VINFO_PEELING_FOR_GAPS(L) (L)->peeling_for_gaps #define LOOP_VINFO_PEELING_FOR_NITER(L) (L)->peeling_for_niter diff --git a/libgcobol/ChangeLog b/libgcobol/ChangeLog index 80d51e2..1858e80 100644 --- a/libgcobol/ChangeLog +++ b/libgcobol/ChangeLog @@ -1,3 +1,45 @@ +2025-10-23 Robert Dubner <rdubner@symas.com> + + * charmaps.cc: Encoding. + * charmaps.h (class charmap_t): Encoding. + * intrinsic.cc (__gg__char): Report the character at the + collation position. + (__gg__ord): Report the collation position of a character. + * libgcobol.cc (struct program_state): Add encodings; + Remove obsolete defines. + (__gg__current_collation): New function for encoding/collation. + (__gg__pop_program_state): Encoding. + (__gg__init_program_state): Encoding. + (format_for_display_internal): Handle LOW-VALUE and HIGH-VALUE. + (__gg__compare_2): Encoding. + (__gg__alphabet_use): Likewise. + * libgcobol.h (__gg__current_collation): New declaration. + * xmlparse.cc (__gg__xml_parse): Make a parameter const. + +2025-10-23 Robert Dubner <rdubner@symas.com> + James K. Lowden <jklowden@cobolworx.com> + + * Makefile.am: Changes for XML PARSE and POSIX functions. + * Makefile.in: Likewise. + * charmaps.cc: Augment encodings[] table with "supported" boolean. + (__gg__encoding_iconv_name): Modify how encodings are identified. + (encoding_descr): Likewise. + (__gg__encoding_iconv_valid): Likewise. + * common-defs.h (callback_t): Define function pointer. + * constants.cc: Use named cbl_attr_e constants instead of magic + numbers.; New definitions for XML special registers. + * encodings.h (struct encodings_t): Declare "supported" boolean. + * libgcobol.cc (format_for_display_internal): Use std::ptrdiff_t. + (__gg__alphabet_use): Add case for iconv_CP1252_e. + (default_exception_handler): Repair exception handling after a + successful file operation. + * posix/errno.cc: New file. + * posix/localtime.cc: New file. + * posix/stat.cc: New file. + * posix/stat.h: New file. + * posix/tm.h: New file. + * xmlparse.cc: New file to support XML PARSE statement. + 2025-10-19 Robert Dubner <rdubner@symas.com> * charmaps.cc (__gg__set_internal_codeset): Eliminate ascii/ebcdic. diff --git a/libgcobol/Makefile.am b/libgcobol/Makefile.am index 1e3d3432..f42bfce 100644 --- a/libgcobol/Makefile.am +++ b/libgcobol/Makefile.am @@ -19,7 +19,7 @@ # Written de novo for libgcobol. -AUTOMAKE_OPTIONS = 1.8 foreign +AUTOMAKE_OPTIONS = 1.8 foreign subdir-objects ACLOCAL_AMFLAGS = -I .. -I ../config # May be used by various substitution variables. @@ -34,6 +34,7 @@ toolexeclib_DATA = libgcobol.spec ## 2.2.12 Automatic Dependency Tracking ## Automake generates code for automatic dependency tracking by default ## + libgcobol_la_SOURCES = \ charmaps.cc \ constants.cc \ @@ -42,12 +43,20 @@ libgcobol_la_SOURCES = \ intrinsic.cc \ io.cc \ libgcobol.cc \ + posix/errno.cc \ + posix/localtime.cc \ + posix/stat.cc \ stringbin.cc \ - valconv.cc + valconv.cc \ + xmlparse.cc + +libgcobol_la_LIBADD = -lxml2 WARN_CFLAGS = -W -Wall -Wwrite-strings -AM_CPPFLAGS = -I. -I$(srcdir) $(LIBQUADINCLUDE) +AM_CPPFLAGS = -I. -I$(srcdir) -I$(srcdir)/posix $(LIBQUADINCLUDE) +AM_CPPFLAGS += -I /usr/include/libxml2 + AM_CFLAGS = $(XCFLAGS) AM_CXXFLAGS = $(XCFLAGS) AM_CXXFLAGS += $(WARN_CFLAGS) @@ -64,7 +73,7 @@ endif libgcobol_la_LINK = $(CXXLINK) $(libgcobol_la_LDFLAGS) version_arg = -version-info $(LIBGCOBOL_VERSION) libgcobol_la_LDFLAGS = $(LTLDFLAGS) $(LIBQUADLIB) $(LTLIBICONV) \ - $(extra_ldflags_libgcobol) $(LIBS) $(version_arg) + $(extra_ldflags_libgcobol) $(LIBS) -lxml2 $(version_arg) libgcobol_la_DEPENDENCIES = libgcobol.spec $(LIBQUADLIB_DEP) endif BUILD_LIBGCOBOL diff --git a/libgcobol/Makefile.in b/libgcobol/Makefile.in index 61b9e86..880fa1f 100644 --- a/libgcobol/Makefile.in +++ b/libgcobol/Makefile.in @@ -115,6 +115,7 @@ target_triplet = @target@ # Handle embedded rpaths for Darwin. @BUILD_LIBGCOBOL_TRUE@@ENABLE_DARWIN_AT_RPATH_TRUE@am__append_1 = -Wc,-nodefaultrpaths \ @BUILD_LIBGCOBOL_TRUE@@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wl,-rpath,@loader_path +@BUILD_LIBGCOBOL_FALSE@libgcobol_la_DEPENDENCIES = subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/../config/clang-plugin.m4 \ @@ -176,11 +177,13 @@ am__uninstall_files_from_dir = { \ am__installdirs = "$(DESTDIR)$(toolexeclibdir)" \ "$(DESTDIR)$(toolexeclibdir)" LTLIBRARIES = $(toolexeclib_LTLIBRARIES) -libgcobol_la_LIBADD = +am__dirstamp = $(am__leading_dot)dirstamp @BUILD_LIBGCOBOL_TRUE@am_libgcobol_la_OBJECTS = charmaps.lo \ @BUILD_LIBGCOBOL_TRUE@ constants.lo gfileio.lo gmath.lo \ @BUILD_LIBGCOBOL_TRUE@ intrinsic.lo io.lo libgcobol.lo \ -@BUILD_LIBGCOBOL_TRUE@ stringbin.lo valconv.lo +@BUILD_LIBGCOBOL_TRUE@ posix/errno.lo posix/localtime.lo \ +@BUILD_LIBGCOBOL_TRUE@ posix/stat.lo stringbin.lo valconv.lo \ +@BUILD_LIBGCOBOL_TRUE@ xmlparse.lo libgcobol_la_OBJECTS = $(am_libgcobol_la_OBJECTS) @BUILD_LIBGCOBOL_TRUE@am_libgcobol_la_rpath = -rpath $(toolexeclibdir) AM_V_P = $(am__v_P_@AM_V@) @@ -390,7 +393,7 @@ toolexeclibdir = @toolexeclibdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -AUTOMAKE_OPTIONS = 1.8 foreign +AUTOMAKE_OPTIONS = 1.8 foreign subdir-objects ACLOCAL_AMFLAGS = -I .. -I ../config # May be used by various substitution variables. @@ -407,11 +410,18 @@ gcc_version := $(shell @get_gcc_base_ver@ $(top_srcdir)/../gcc/BASE-VER) @BUILD_LIBGCOBOL_TRUE@ intrinsic.cc \ @BUILD_LIBGCOBOL_TRUE@ io.cc \ @BUILD_LIBGCOBOL_TRUE@ libgcobol.cc \ +@BUILD_LIBGCOBOL_TRUE@ posix/errno.cc \ +@BUILD_LIBGCOBOL_TRUE@ posix/localtime.cc \ +@BUILD_LIBGCOBOL_TRUE@ posix/stat.cc \ @BUILD_LIBGCOBOL_TRUE@ stringbin.cc \ -@BUILD_LIBGCOBOL_TRUE@ valconv.cc +@BUILD_LIBGCOBOL_TRUE@ valconv.cc \ +@BUILD_LIBGCOBOL_TRUE@ xmlparse.cc +@BUILD_LIBGCOBOL_TRUE@libgcobol_la_LIBADD = -lxml2 @BUILD_LIBGCOBOL_TRUE@WARN_CFLAGS = -W -Wall -Wwrite-strings -@BUILD_LIBGCOBOL_TRUE@AM_CPPFLAGS = -I. -I$(srcdir) $(LIBQUADINCLUDE) +@BUILD_LIBGCOBOL_TRUE@AM_CPPFLAGS = -I. -I$(srcdir) -I$(srcdir)/posix \ +@BUILD_LIBGCOBOL_TRUE@ $(LIBQUADINCLUDE) -I \ +@BUILD_LIBGCOBOL_TRUE@ /usr/include/libxml2 @BUILD_LIBGCOBOL_TRUE@AM_CFLAGS = $(XCFLAGS) @BUILD_LIBGCOBOL_TRUE@AM_CXXFLAGS = $(XCFLAGS) $(WARN_CFLAGS) \ @BUILD_LIBGCOBOL_TRUE@ -DIN_TARGET_LIBS -fno-strict-aliasing @@ -420,7 +430,7 @@ gcc_version := $(shell @get_gcc_base_ver@ $(top_srcdir)/../gcc/BASE-VER) @BUILD_LIBGCOBOL_TRUE@libgcobol_la_LINK = $(CXXLINK) $(libgcobol_la_LDFLAGS) @BUILD_LIBGCOBOL_TRUE@version_arg = -version-info $(LIBGCOBOL_VERSION) @BUILD_LIBGCOBOL_TRUE@libgcobol_la_LDFLAGS = $(LTLDFLAGS) $(LIBQUADLIB) $(LTLIBICONV) \ -@BUILD_LIBGCOBOL_TRUE@ $(extra_ldflags_libgcobol) $(LIBS) $(version_arg) +@BUILD_LIBGCOBOL_TRUE@ $(extra_ldflags_libgcobol) $(LIBS) -lxml2 $(version_arg) @BUILD_LIBGCOBOL_TRUE@libgcobol_la_DEPENDENCIES = libgcobol.spec $(LIBQUADLIB_DEP) all: config.h @@ -513,12 +523,24 @@ clean-toolexeclibLTLIBRARIES: echo rm -f $${locs}; \ rm -f $${locs}; \ } +posix/$(am__dirstamp): + @$(MKDIR_P) posix + @: > posix/$(am__dirstamp) +posix/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) posix/$(DEPDIR) + @: > posix/$(DEPDIR)/$(am__dirstamp) +posix/errno.lo: posix/$(am__dirstamp) posix/$(DEPDIR)/$(am__dirstamp) +posix/localtime.lo: posix/$(am__dirstamp) \ + posix/$(DEPDIR)/$(am__dirstamp) +posix/stat.lo: posix/$(am__dirstamp) posix/$(DEPDIR)/$(am__dirstamp) libgcobol.la: $(libgcobol_la_OBJECTS) $(libgcobol_la_DEPENDENCIES) $(EXTRA_libgcobol_la_DEPENDENCIES) $(AM_V_GEN)$(libgcobol_la_LINK) $(am_libgcobol_la_rpath) $(libgcobol_la_OBJECTS) $(libgcobol_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) + -rm -f posix/*.$(OBJEXT) + -rm -f posix/*.lo distclean-compile: -rm -f *.tab.c @@ -532,24 +554,31 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcobol.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stringbin.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/valconv.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xmlparse.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@posix/$(DEPDIR)/errno.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@posix/$(DEPDIR)/localtime.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@posix/$(DEPDIR)/stat.Plo@am__quote@ .cc.o: -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cc.lo: -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< @@ -559,6 +588,7 @@ mostlyclean-libtool: clean-libtool: -rm -rf .libs _libs + -rm -rf posix/.libs posix/_libs distclean-libtool: -rm -f libtool config.lt @@ -675,6 +705,8 @@ clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f posix/$(DEPDIR)/$(am__dirstamp) + -rm -f posix/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @@ -686,7 +718,7 @@ clean-am: clean-generic clean-libtool clean-toolexeclibLTLIBRARIES \ distclean: distclean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf ./$(DEPDIR) + -rm -rf ./$(DEPDIR) posix/$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-hdr distclean-libtool distclean-tags @@ -735,7 +767,7 @@ installcheck-am: maintainer-clean: maintainer-clean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache - -rm -rf ./$(DEPDIR) + -rm -rf ./$(DEPDIR) posix/$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic diff --git a/libgcobol/charmaps.cc b/libgcobol/charmaps.cc index 61481a6..349c669 100644 --- a/libgcobol/charmaps.cc +++ b/libgcobol/charmaps.cc @@ -56,11 +56,11 @@ int __gg__quote_character = '"' ; int __gg__low_value_character = 0x00 ; int __gg__high_value_character = 0xFF ; char **__gg__currency_signs ; - int __gg__default_currency_sign; - char *__gg__ct_currency_signs[256]; // Compile-time currency signs +cbl_encoding_t __gg__display_encoding = no_encoding_e; +cbl_encoding_t __gg__national_encoding = no_encoding_e; // First: single-byte-coded (SBC) character sets: @@ -229,1196 +229,1210 @@ __gg__ebcdic_to_cp1252_collation[256] = }; static encodings_t encodings[] = { - { iconv_437_e, "437" }, - { iconv_500_e, "500" }, - { iconv_500V1_e, "500V1" }, - { iconv_850_e, "850" }, - { iconv_851_e, "851" }, - { iconv_852_e, "852" }, - { iconv_855_e, "855" }, - { iconv_856_e, "856" }, - { iconv_857_e, "857" }, - { iconv_858_e, "858" }, - { iconv_860_e, "860" }, - { iconv_861_e, "861" }, - { iconv_862_e, "862" }, - { iconv_863_e, "863" }, - { iconv_864_e, "864" }, - { iconv_865_e, "865" }, - { iconv_866_e, "866" }, - { iconv_866NAV_e, "866NAV" }, - { iconv_869_e, "869" }, - { iconv_874_e, "874" }, - { iconv_904_e, "904" }, - { iconv_1026_e, "1026" }, - { iconv_1046_e, "1046" }, - { iconv_1047_e, "1047" }, - { iconv_8859_1_e, "8859_1" }, - { iconv_8859_2_e, "8859_2" }, - { iconv_8859_3_e, "8859_3" }, - { iconv_8859_4_e, "8859_4" }, - { iconv_8859_5_e, "8859_5" }, - { iconv_8859_6_e, "8859_6" }, - { iconv_8859_7_e, "8859_7" }, - { iconv_8859_8_e, "8859_8" }, - { iconv_8859_9_e, "8859_9" }, - { iconv_10646_1_1993_e, "10646-1:1993" }, - { iconv_10646_1_1993_e, "UCS4/ 10646-1:1993/UCS4/" }, - { iconv_ANSI_X3_4_1968_e, "ANSI_X3.4-1968" }, - { iconv_ANSI_X3_4_1986_e, "ANSI_X3.4-1986" }, - { iconv_ANSI_X3_4_e, "ANSI_X3.4" }, - { iconv_ANSI_X3_110_1983_e, "ANSI_X3.110-1983" }, - { iconv_ANSI_X3_110_e, "ANSI_X3.110" }, - { iconv_ARABIC_e, "ARABIC" }, - { iconv_ARABIC7_e, "ARABIC7" }, - { iconv_ARMSCII_8_e, "ARMSCII-8" }, - { iconv_ARMSCII8_e, "ARMSCII8" }, - { iconv_ASCII_e, "ASCII" }, - { iconv_ASMO_708_e, "ASMO-708" }, - { iconv_ASMO_449_e, "ASMO_449" }, - { iconv_BALTIC_e, "BALTIC" }, - { iconv_BIG_5_e, "BIG-5" }, - { iconv_BIG_FIVE_e, "BIG-FIVE" }, - { iconv_BIG5_HKSCS_e, "BIG5-HKSCS" }, - { iconv_BIG5_e, "BIG5" }, - { iconv_BIG5HKSCS_e, "BIG5HKSCS" }, - { iconv_BIGFIVE_e, "BIGFIVE" }, - { iconv_BRF_e, "BRF" }, - { iconv_BS_4730_e, "BS_4730" }, - { iconv_CA_e, "CA" }, - { iconv_CN_BIG5_e, "CN-BIG5" }, - { iconv_CN_GB_e, "CN-GB" }, - { iconv_CN_e, "CN" }, - { iconv_CP_AR_e, "CP-AR" }, - { iconv_CP_GR_e, "CP-GR" }, - { iconv_CP_HU_e, "CP-HU" }, - { iconv_CP037_e, "CP037" }, - { iconv_CP038_e, "CP038" }, - { iconv_CP273_e, "CP273" }, - { iconv_CP274_e, "CP274" }, - { iconv_CP275_e, "CP275" }, - { iconv_CP278_e, "CP278" }, - { iconv_CP280_e, "CP280" }, - { iconv_CP281_e, "CP281" }, - { iconv_CP282_e, "CP282" }, - { iconv_CP284_e, "CP284" }, - { iconv_CP285_e, "CP285" }, - { iconv_CP290_e, "CP290" }, - { iconv_CP297_e, "CP297" }, - { iconv_CP367_e, "CP367" }, - { iconv_CP420_e, "CP420" }, - { iconv_CP423_e, "CP423" }, - { iconv_CP424_e, "CP424" }, - { iconv_CP437_e, "CP437" }, - { iconv_CP500_e, "CP500" }, - { iconv_CP737_e, "CP737" }, - { iconv_CP770_e, "CP770" }, - { iconv_CP771_e, "CP771" }, - { iconv_CP772_e, "CP772" }, - { iconv_CP773_e, "CP773" }, - { iconv_CP774_e, "CP774" }, - { iconv_CP775_e, "CP775" }, - { iconv_CP803_e, "CP803" }, - { iconv_CP813_e, "CP813" }, - { iconv_CP819_e, "CP819" }, - { iconv_CP850_e, "CP850" }, - { iconv_CP851_e, "CP851" }, - { iconv_CP852_e, "CP852" }, - { iconv_CP855_e, "CP855" }, - { iconv_CP856_e, "CP856" }, - { iconv_CP857_e, "CP857" }, - { iconv_CP858_e, "CP858" }, - { iconv_CP860_e, "CP860" }, - { iconv_CP861_e, "CP861" }, - { iconv_CP862_e, "CP862" }, - { iconv_CP863_e, "CP863" }, - { iconv_CP864_e, "CP864" }, - { iconv_CP865_e, "CP865" }, - { iconv_CP866_e, "CP866" }, - { iconv_CP866NAV_e, "CP866NAV" }, - { iconv_CP868_e, "CP868" }, - { iconv_CP869_e, "CP869" }, - { iconv_CP870_e, "CP870" }, - { iconv_CP871_e, "CP871" }, - { iconv_CP874_e, "CP874" }, - { iconv_CP875_e, "CP875" }, - { iconv_CP880_e, "CP880" }, - { iconv_CP891_e, "CP891" }, - { iconv_CP901_e, "CP901" }, - { iconv_CP902_e, "CP902" }, - { iconv_CP903_e, "CP903" }, - { iconv_CP904_e, "CP904" }, - { iconv_CP905_e, "CP905" }, - { iconv_CP912_e, "CP912" }, - { iconv_CP915_e, "CP915" }, - { iconv_CP916_e, "CP916" }, - { iconv_CP918_e, "CP918" }, - { iconv_CP920_e, "CP920" }, - { iconv_CP921_e, "CP921" }, - { iconv_CP922_e, "CP922" }, - { iconv_CP930_e, "CP930" }, - { iconv_CP932_e, "CP932" }, - { iconv_CP933_e, "CP933" }, - { iconv_CP935_e, "CP935" }, - { iconv_CP936_e, "CP936" }, - { iconv_CP937_e, "CP937" }, - { iconv_CP939_e, "CP939" }, - { iconv_CP949_e, "CP949" }, - { iconv_CP950_e, "CP950" }, - { iconv_CP1004_e, "CP1004" }, - { iconv_CP1008_e, "CP1008" }, - { iconv_CP1025_e, "CP1025" }, - { iconv_CP1026_e, "CP1026" }, - { iconv_CP1046_e, "CP1046" }, - { iconv_CP1047_e, "CP1047" }, - { iconv_CP1070_e, "CP1070" }, - { iconv_CP1079_e, "CP1079" }, - { iconv_CP1081_e, "CP1081" }, - { iconv_CP1084_e, "CP1084" }, - { iconv_CP1089_e, "CP1089" }, - { iconv_CP1097_e, "CP1097" }, - { iconv_CP1112_e, "CP1112" }, - { iconv_CP1122_e, "CP1122" }, - { iconv_CP1123_e, "CP1123" }, - { iconv_CP1124_e, "CP1124" }, - { iconv_CP1125_e, "CP1125" }, - { iconv_CP1129_e, "CP1129" }, - { iconv_CP1130_e, "CP1130" }, - { iconv_CP1132_e, "CP1132" }, - { iconv_CP1133_e, "CP1133" }, - { iconv_CP1137_e, "CP1137" }, - { iconv_CP1140_e, "CP1140" }, - { iconv_CP1141_e, "CP1141" }, - { iconv_CP1142_e, "CP1142" }, - { iconv_CP1143_e, "CP1143" }, - { iconv_CP1144_e, "CP1144" }, - { iconv_CP1145_e, "CP1145" }, - { iconv_CP1146_e, "CP1146" }, - { iconv_CP1147_e, "CP1147" }, - { iconv_CP1148_e, "CP1148" }, - { iconv_CP1149_e, "CP1149" }, - { iconv_CP1153_e, "CP1153" }, - { iconv_CP1154_e, "CP1154" }, - { iconv_CP1155_e, "CP1155" }, - { iconv_CP1156_e, "CP1156" }, - { iconv_CP1157_e, "CP1157" }, - { iconv_CP1158_e, "CP1158" }, - { iconv_CP1160_e, "CP1160" }, - { iconv_CP1161_e, "CP1161" }, - { iconv_CP1162_e, "CP1162" }, - { iconv_CP1163_e, "CP1163" }, - { iconv_CP1164_e, "CP1164" }, - { iconv_CP1166_e, "CP1166" }, - { iconv_CP1167_e, "CP1167" }, - { iconv_CP1250_e, "CP1250" }, - { iconv_CP1251_e, "CP1251" }, - { iconv_CP1252_e, "CP1252" }, - { iconv_CP1253_e, "CP1253" }, - { iconv_CP1254_e, "CP1254" }, - { iconv_CP1255_e, "CP1255" }, - { iconv_CP1256_e, "CP1256" }, - { iconv_CP1257_e, "CP1257" }, - { iconv_CP1258_e, "CP1258" }, - { iconv_CP1282_e, "CP1282" }, - { iconv_CP1361_e, "CP1361" }, - { iconv_CP1364_e, "CP1364" }, - { iconv_CP1371_e, "CP1371" }, - { iconv_CP1388_e, "CP1388" }, - { iconv_CP1390_e, "CP1390" }, - { iconv_CP1399_e, "CP1399" }, - { iconv_CP4517_e, "CP4517" }, - { iconv_CP4899_e, "CP4899" }, - { iconv_CP4909_e, "CP4909" }, - { iconv_CP4971_e, "CP4971" }, - { iconv_CP5347_e, "CP5347" }, - { iconv_CP9030_e, "CP9030" }, - { iconv_CP9066_e, "CP9066" }, - { iconv_CP9448_e, "CP9448" }, - { iconv_CP10007_e, "CP10007" }, - { iconv_CP12712_e, "CP12712" }, - { iconv_CP16804_e, "CP16804" }, - { iconv_CPIBM861_e, "CPIBM861" }, - { iconv_CSA7_1_e, "CSA7-1" }, - { iconv_CSA7_2_e, "CSA7-2" }, - { iconv_CSASCII_e, "CSASCII" }, - { iconv_CSA_T500_1983_e, "CSA_T500-1983" }, - { iconv_CSA_T500_e, "CSA_T500" }, - { iconv_CSA_Z243_4_1985_1_e, "CSA_Z243.4-1985-1" }, - { iconv_CSA_Z243_4_1985_2_e, "CSA_Z243.4-1985-2" }, - { iconv_CSA_Z243_419851_e, "CSA_Z243.419851" }, - { iconv_CSA_Z243_419852_e, "CSA_Z243.419852" }, - { iconv_CSDECMCS_e, "CSDECMCS" }, - { iconv_CSEBCDICATDE_e, "CSEBCDICATDE" }, - { iconv_CSEBCDICATDEA_e, "CSEBCDICATDEA" }, - { iconv_CSEBCDICCAFR_e, "CSEBCDICCAFR" }, - { iconv_CSEBCDICDKNO_e, "CSEBCDICDKNO" }, - { iconv_CSEBCDICDKNOA_e, "CSEBCDICDKNOA" }, - { iconv_CSEBCDICES_e, "CSEBCDICES" }, - { iconv_CSEBCDICESA_e, "CSEBCDICESA" }, - { iconv_CSEBCDICESS_e, "CSEBCDICESS" }, - { iconv_CSEBCDICFISE_e, "CSEBCDICFISE" }, - { iconv_CSEBCDICFISEA_e, "CSEBCDICFISEA" }, - { iconv_CSEBCDICFR_e, "CSEBCDICFR" }, - { iconv_CSEBCDICIT_e, "CSEBCDICIT" }, - { iconv_CSEBCDICPT_e, "CSEBCDICPT" }, - { iconv_CSEBCDICUK_e, "CSEBCDICUK" }, - { iconv_CSEBCDICUS_e, "CSEBCDICUS" }, - { iconv_CSEUCKR_e, "CSEUCKR" }, - { iconv_CSEUCPKDFMTJAPANESE_e, "CSEUCPKDFMTJAPANESE" }, - { iconv_CSGB2312_e, "CSGB2312" }, - { iconv_CSHPROMAN8_e, "CSHPROMAN8" }, - { iconv_CSIBM037_e, "CSIBM037" }, - { iconv_CSIBM038_e, "CSIBM038" }, - { iconv_CSIBM273_e, "CSIBM273" }, - { iconv_CSIBM274_e, "CSIBM274" }, - { iconv_CSIBM275_e, "CSIBM275" }, - { iconv_CSIBM277_e, "CSIBM277" }, - { iconv_CSIBM278_e, "CSIBM278" }, - { iconv_CSIBM280_e, "CSIBM280" }, - { iconv_CSIBM281_e, "CSIBM281" }, - { iconv_CSIBM284_e, "CSIBM284" }, - { iconv_CSIBM285_e, "CSIBM285" }, - { iconv_CSIBM290_e, "CSIBM290" }, - { iconv_CSIBM297_e, "CSIBM297" }, - { iconv_CSIBM420_e, "CSIBM420" }, - { iconv_CSIBM423_e, "CSIBM423" }, - { iconv_CSIBM424_e, "CSIBM424" }, - { iconv_CSIBM500_e, "CSIBM500" }, - { iconv_CSIBM803_e, "CSIBM803" }, - { iconv_CSIBM851_e, "CSIBM851" }, - { iconv_CSIBM855_e, "CSIBM855" }, - { iconv_CSIBM856_e, "CSIBM856" }, - { iconv_CSIBM857_e, "CSIBM857" }, - { iconv_CSIBM860_e, "CSIBM860" }, - { iconv_CSIBM863_e, "CSIBM863" }, - { iconv_CSIBM864_e, "CSIBM864" }, - { iconv_CSIBM865_e, "CSIBM865" }, - { iconv_CSIBM866_e, "CSIBM866" }, - { iconv_CSIBM868_e, "CSIBM868" }, - { iconv_CSIBM869_e, "CSIBM869" }, - { iconv_CSIBM870_e, "CSIBM870" }, - { iconv_CSIBM871_e, "CSIBM871" }, - { iconv_CSIBM880_e, "CSIBM880" }, - { iconv_CSIBM891_e, "CSIBM891" }, - { iconv_CSIBM901_e, "CSIBM901" }, - { iconv_CSIBM902_e, "CSIBM902" }, - { iconv_CSIBM903_e, "CSIBM903" }, - { iconv_CSIBM904_e, "CSIBM904" }, - { iconv_CSIBM905_e, "CSIBM905" }, - { iconv_CSIBM918_e, "CSIBM918" }, - { iconv_CSIBM921_e, "CSIBM921" }, - { iconv_CSIBM922_e, "CSIBM922" }, - { iconv_CSIBM930_e, "CSIBM930" }, - { iconv_CSIBM932_e, "CSIBM932" }, - { iconv_CSIBM933_e, "CSIBM933" }, - { iconv_CSIBM935_e, "CSIBM935" }, - { iconv_CSIBM937_e, "CSIBM937" }, - { iconv_CSIBM939_e, "CSIBM939" }, - { iconv_CSIBM943_e, "CSIBM943" }, - { iconv_CSIBM1008_e, "CSIBM1008" }, - { iconv_CSIBM1025_e, "CSIBM1025" }, - { iconv_CSIBM1026_e, "CSIBM1026" }, - { iconv_CSIBM1097_e, "CSIBM1097" }, - { iconv_CSIBM1112_e, "CSIBM1112" }, - { iconv_CSIBM1122_e, "CSIBM1122" }, - { iconv_CSIBM1123_e, "CSIBM1123" }, - { iconv_CSIBM1124_e, "CSIBM1124" }, - { iconv_CSIBM1129_e, "CSIBM1129" }, - { iconv_CSIBM1130_e, "CSIBM1130" }, - { iconv_CSIBM1132_e, "CSIBM1132" }, - { iconv_CSIBM1133_e, "CSIBM1133" }, - { iconv_CSIBM1137_e, "CSIBM1137" }, - { iconv_CSIBM1140_e, "CSIBM1140" }, - { iconv_CSIBM1141_e, "CSIBM1141" }, - { iconv_CSIBM1142_e, "CSIBM1142" }, - { iconv_CSIBM1143_e, "CSIBM1143" }, - { iconv_CSIBM1144_e, "CSIBM1144" }, - { iconv_CSIBM1145_e, "CSIBM1145" }, - { iconv_CSIBM1146_e, "CSIBM1146" }, - { iconv_CSIBM1147_e, "CSIBM1147" }, - { iconv_CSIBM1148_e, "CSIBM1148" }, - { iconv_CSIBM1149_e, "CSIBM1149" }, - { iconv_CSIBM1153_e, "CSIBM1153" }, - { iconv_CSIBM1154_e, "CSIBM1154" }, - { iconv_CSIBM1155_e, "CSIBM1155" }, - { iconv_CSIBM1156_e, "CSIBM1156" }, - { iconv_CSIBM1157_e, "CSIBM1157" }, - { iconv_CSIBM1158_e, "CSIBM1158" }, - { iconv_CSIBM1160_e, "CSIBM1160" }, - { iconv_CSIBM1161_e, "CSIBM1161" }, - { iconv_CSIBM1163_e, "CSIBM1163" }, - { iconv_CSIBM1164_e, "CSIBM1164" }, - { iconv_CSIBM1166_e, "CSIBM1166" }, - { iconv_CSIBM1167_e, "CSIBM1167" }, - { iconv_CSIBM1364_e, "CSIBM1364" }, - { iconv_CSIBM1371_e, "CSIBM1371" }, - { iconv_CSIBM1388_e, "CSIBM1388" }, - { iconv_CSIBM1390_e, "CSIBM1390" }, - { iconv_CSIBM1399_e, "CSIBM1399" }, - { iconv_CSIBM4517_e, "CSIBM4517" }, - { iconv_CSIBM4899_e, "CSIBM4899" }, - { iconv_CSIBM4909_e, "CSIBM4909" }, - { iconv_CSIBM4971_e, "CSIBM4971" }, - { iconv_CSIBM5347_e, "CSIBM5347" }, - { iconv_CSIBM9030_e, "CSIBM9030" }, - { iconv_CSIBM9066_e, "CSIBM9066" }, - { iconv_CSIBM9448_e, "CSIBM9448" }, - { iconv_CSIBM12712_e, "CSIBM12712" }, - { iconv_CSIBM16804_e, "CSIBM16804" }, - { iconv_CSIBM11621162_e, "CSIBM11621162" }, - { iconv_CSISO4UNITEDKINGDOM_e, "CSISO4UNITEDKINGDOM" }, - { iconv_CSISO10SWEDISH_e, "CSISO10SWEDISH" }, - { iconv_CSISO11SWEDISHFORNAMES_e, "CSISO11SWEDISHFORNAMES" }, - { iconv_CSISO14JISC6220RO_e, "CSISO14JISC6220RO" }, - { iconv_CSISO15ITALIAN_e, "CSISO15ITALIAN" }, - { iconv_CSISO16PORTUGESE_e, "CSISO16PORTUGESE" }, - { iconv_CSISO17SPANISH_e, "CSISO17SPANISH" }, - { iconv_CSISO18GREEK7OLD_e, "CSISO18GREEK7OLD" }, - { iconv_CSISO19LATINGREEK_e, "CSISO19LATINGREEK" }, - { iconv_CSISO21GERMAN_e, "CSISO21GERMAN" }, - { iconv_CSISO25FRENCH_e, "CSISO25FRENCH" }, - { iconv_CSISO27LATINGREEK1_e, "CSISO27LATINGREEK1" }, - { iconv_CSISO49INIS_e, "CSISO49INIS" }, - { iconv_CSISO50INIS8_e, "CSISO50INIS8" }, - { iconv_CSISO51INISCYRILLIC_e, "CSISO51INISCYRILLIC" }, - { iconv_CSISO58GB1988_e, "CSISO58GB1988" }, - { iconv_CSISO60DANISHNORWEGIAN_e, "CSISO60DANISHNORWEGIAN" }, - { iconv_CSISO60NORWEGIAN1_e, "CSISO60NORWEGIAN1" }, - { iconv_CSISO61NORWEGIAN2_e, "CSISO61NORWEGIAN2" }, - { iconv_CSISO69FRENCH_e, "CSISO69FRENCH" }, - { iconv_CSISO84PORTUGUESE2_e, "CSISO84PORTUGUESE2" }, - { iconv_CSISO85SPANISH2_e, "CSISO85SPANISH2" }, - { iconv_CSISO86HUNGARIAN_e, "CSISO86HUNGARIAN" }, - { iconv_CSISO88GREEK7_e, "CSISO88GREEK7" }, - { iconv_CSISO89ASMO449_e, "CSISO89ASMO449" }, - { iconv_CSISO90_e, "CSISO90" }, - { iconv_CSISO92JISC62991984B_e, "CSISO92JISC62991984B" }, - { iconv_CSISO99NAPLPS_e, "CSISO99NAPLPS" }, - { iconv_CSISO103T618BIT_e, "CSISO103T618BIT" }, - { iconv_CSISO111ECMACYRILLIC_e, "CSISO111ECMACYRILLIC" }, - { iconv_CSISO121CANADIAN1_e, "CSISO121CANADIAN1" }, - { iconv_CSISO122CANADIAN2_e, "CSISO122CANADIAN2" }, - { iconv_CSISO139CSN369103_e, "CSISO139CSN369103" }, - { iconv_CSISO141JUSIB1002_e, "CSISO141JUSIB1002" }, - { iconv_CSISO143IECP271_e, "CSISO143IECP271" }, - { iconv_CSISO150_e, "CSISO150" }, - { iconv_CSISO150GREEKCCITT_e, "CSISO150GREEKCCITT" }, - { iconv_CSISO151CUBA_e, "CSISO151CUBA" }, - { iconv_CSISO153GOST1976874_e, "CSISO153GOST1976874" }, - { iconv_CSISO646DANISH_e, "CSISO646DANISH" }, - { iconv_CSISO2022CN_e, "CSISO2022CN" }, - { iconv_CSISO2022JP_e, "CSISO2022JP" }, - { iconv_CSISO2022JP2_e, "CSISO2022JP2" }, - { iconv_CSISO2022KR_e, "CSISO2022KR" }, - { iconv_CSISO2033_e, "CSISO2033" }, - { iconv_CSISO5427CYRILLIC_e, "CSISO5427CYRILLIC" }, - { iconv_CSISO5427CYRILLIC1981_e, "CSISO5427CYRILLIC1981" }, - { iconv_CSISO5428GREEK_e, "CSISO5428GREEK" }, - { iconv_CSISO10367BOX_e, "CSISO10367BOX" }, - { iconv_CSISOLATIN1_e, "CSISOLATIN1" }, - { iconv_CSISOLATIN2_e, "CSISOLATIN2" }, - { iconv_CSISOLATIN3_e, "CSISOLATIN3" }, - { iconv_CSISOLATIN4_e, "CSISOLATIN4" }, - { iconv_CSISOLATIN5_e, "CSISOLATIN5" }, - { iconv_CSISOLATIN6_e, "CSISOLATIN6" }, - { iconv_CSISOLATINARABIC_e, "CSISOLATINARABIC" }, - { iconv_CSISOLATINCYRILLIC_e, "CSISOLATINCYRILLIC" }, - { iconv_CSISOLATINGREEK_e, "CSISOLATINGREEK" }, - { iconv_CSISOLATINHEBREW_e, "CSISOLATINHEBREW" }, - { iconv_CSKOI8R_e, "CSKOI8R" }, - { iconv_CSKSC5636_e, "CSKSC5636" }, - { iconv_CSMACINTOSH_e, "CSMACINTOSH" }, - { iconv_CSNATSDANO_e, "CSNATSDANO" }, - { iconv_CSNATSSEFI_e, "CSNATSSEFI" }, - { iconv_CSN_369103_e, "CSN_369103" }, - { iconv_CSPC8CODEPAGE437_e, "CSPC8CODEPAGE437" }, - { iconv_CSPC775BALTIC_e, "CSPC775BALTIC" }, - { iconv_CSPC850MULTILINGUAL_e, "CSPC850MULTILINGUAL" }, - { iconv_CSPC858MULTILINGUAL_e, "CSPC858MULTILINGUAL" }, - { iconv_CSPC862LATINHEBREW_e, "CSPC862LATINHEBREW" }, - { iconv_CSPCP852_e, "CSPCP852" }, - { iconv_CSSHIFTJIS_e, "CSSHIFTJIS" }, - { iconv_CSUCS4_e, "CSUCS4" }, - { iconv_CSUNICODE_e, "CSUNICODE" }, - { iconv_CSWINDOWS31J_e, "CSWINDOWS31J" }, - { iconv_CUBA_e, "CUBA" }, - { iconv_CWI_2_e, "CWI-2" }, - { iconv_CWI_e, "CWI" }, - { iconv_CYRILLIC_e, "CYRILLIC" }, - { iconv_DE_e, "DE" }, - { iconv_DEC_MCS_e, "DEC-MCS" }, - { iconv_DEC_e, "DEC" }, - { iconv_DECMCS_e, "DECMCS" }, - { iconv_DIN_66003_e, "DIN_66003" }, - { iconv_DK_e, "DK" }, - { iconv_DS2089_e, "DS2089" }, - { iconv_DS_2089_e, "DS_2089" }, - { iconv_E13B_e, "E13B" }, - { iconv_EBCDIC_AT_DE_A_e, "EBCDIC-AT-DE-A" }, - { iconv_EBCDIC_AT_DE_e, "EBCDIC-AT-DE" }, - { iconv_EBCDIC_BE_e, "EBCDIC-BE" }, - { iconv_EBCDIC_BR_e, "EBCDIC-BR" }, - { iconv_EBCDIC_CA_FR_e, "EBCDIC-CA-FR" }, - { iconv_EBCDIC_CP_AR1_e, "EBCDIC-CP-AR1" }, - { iconv_EBCDIC_CP_AR2_e, "EBCDIC-CP-AR2" }, - { iconv_EBCDIC_CP_BE_e, "EBCDIC-CP-BE" }, - { iconv_EBCDIC_CP_CA_e, "EBCDIC-CP-CA" }, - { iconv_EBCDIC_CP_CH_e, "EBCDIC-CP-CH" }, - { iconv_EBCDIC_CP_DK_e, "EBCDIC-CP-DK" }, - { iconv_EBCDIC_CP_ES_e, "EBCDIC-CP-ES" }, - { iconv_EBCDIC_CP_FI_e, "EBCDIC-CP-FI" }, - { iconv_EBCDIC_CP_FR_e, "EBCDIC-CP-FR" }, - { iconv_EBCDIC_CP_GB_e, "EBCDIC-CP-GB" }, - { iconv_EBCDIC_CP_GR_e, "EBCDIC-CP-GR" }, - { iconv_EBCDIC_CP_HE_e, "EBCDIC-CP-HE" }, - { iconv_EBCDIC_CP_IS_e, "EBCDIC-CP-IS" }, - { iconv_EBCDIC_CP_IT_e, "EBCDIC-CP-IT" }, - { iconv_EBCDIC_CP_NL_e, "EBCDIC-CP-NL" }, - { iconv_EBCDIC_CP_NO_e, "EBCDIC-CP-NO" }, - { iconv_EBCDIC_CP_ROECE_e, "EBCDIC-CP-ROECE" }, - { iconv_EBCDIC_CP_SE_e, "EBCDIC-CP-SE" }, - { iconv_EBCDIC_CP_TR_e, "EBCDIC-CP-TR" }, - { iconv_EBCDIC_CP_US_e, "EBCDIC-CP-US" }, - { iconv_EBCDIC_CP_WT_e, "EBCDIC-CP-WT" }, - { iconv_EBCDIC_CP_YU_e, "EBCDIC-CP-YU" }, - { iconv_EBCDIC_CYRILLIC_e, "EBCDIC-CYRILLIC" }, - { iconv_EBCDIC_DK_NO_A_e, "EBCDIC-DK-NO-A" }, - { iconv_EBCDIC_DK_NO_e, "EBCDIC-DK-NO" }, - { iconv_EBCDIC_ES_A_e, "EBCDIC-ES-A" }, - { iconv_EBCDIC_ES_S_e, "EBCDIC-ES-S" }, - { iconv_EBCDIC_ES_e, "EBCDIC-ES" }, - { iconv_EBCDIC_FI_SE_A_e, "EBCDIC-FI-SE-A" }, - { iconv_EBCDIC_FI_SE_e, "EBCDIC-FI-SE" }, - { iconv_EBCDIC_FR_e, "EBCDIC-FR" }, - { iconv_EBCDIC_GREEK_e, "EBCDIC-GREEK" }, - { iconv_EBCDIC_INT_e, "EBCDIC-INT" }, - { iconv_EBCDIC_INT1_e, "EBCDIC-INT1" }, - { iconv_EBCDIC_IS_FRISS_e, "EBCDIC-IS-FRISS" }, - { iconv_EBCDIC_IT_e, "EBCDIC-IT" }, - { iconv_EBCDIC_JP_E_e, "EBCDIC-JP-E" }, - { iconv_EBCDIC_JP_KANA_e, "EBCDIC-JP-KANA" }, - { iconv_EBCDIC_PT_e, "EBCDIC-PT" }, - { iconv_EBCDIC_UK_e, "EBCDIC-UK" }, - { iconv_EBCDIC_US_e, "EBCDIC-US" }, - { iconv_EBCDICATDE_e, "EBCDICATDE" }, - { iconv_EBCDICATDEA_e, "EBCDICATDEA" }, - { iconv_EBCDICCAFR_e, "EBCDICCAFR" }, - { iconv_EBCDICDKNO_e, "EBCDICDKNO" }, - { iconv_EBCDICDKNOA_e, "EBCDICDKNOA" }, - { iconv_EBCDICES_e, "EBCDICES" }, - { iconv_EBCDICESA_e, "EBCDICESA" }, - { iconv_EBCDICESS_e, "EBCDICESS" }, - { iconv_EBCDICFISE_e, "EBCDICFISE" }, - { iconv_EBCDICFISEA_e, "EBCDICFISEA" }, - { iconv_EBCDICFR_e, "EBCDICFR" }, - { iconv_EBCDICISFRISS_e, "EBCDICISFRISS" }, - { iconv_EBCDICIT_e, "EBCDICIT" }, - { iconv_EBCDICPT_e, "EBCDICPT" }, - { iconv_EBCDICUK_e, "EBCDICUK" }, - { iconv_EBCDICUS_e, "EBCDICUS" }, - { iconv_ECMA_114_e, "ECMA-114" }, - { iconv_ECMA_118_e, "ECMA-118" }, - { iconv_ECMA_128_e, "ECMA-128" }, - { iconv_ECMA_CYRILLIC_e, "ECMA-CYRILLIC" }, - { iconv_ECMACYRILLIC_e, "ECMACYRILLIC" }, - { iconv_ELOT_928_e, "ELOT_928" }, - { iconv_ES_e, "ES" }, - { iconv_ES2_e, "ES2" }, - { iconv_EUC_CN_e, "EUC-CN" }, - { iconv_EUC_JISX0213_e, "EUC-JISX0213" }, - { iconv_EUC_JP_MS_e, "EUC-JP-MS" }, - { iconv_EUC_JP_e, "EUC-JP" }, - { iconv_EUC_KR_e, "EUC-KR" }, - { iconv_EUC_TW_e, "EUC-TW" }, - { iconv_EUCCN_e, "EUCCN" }, - { iconv_EUCJP_MS_e, "EUCJP-MS" }, - { iconv_EUCJP_OPEN_e, "EUCJP-OPEN" }, - { iconv_EUCJP_WIN_e, "EUCJP-WIN" }, - { iconv_EUCJP_e, "EUCJP" }, - { iconv_EUCKR_e, "EUCKR" }, - { iconv_EUCTW_e, "EUCTW" }, - { iconv_FI_e, "FI" }, - { iconv_FR_e, "FR" }, - { iconv_GB_e, "GB" }, - { iconv_GB2312_e, "GB2312" }, - { iconv_GB13000_e, "GB13000" }, - { iconv_GB18030_e, "GB18030" }, - { iconv_GBK_e, "GBK" }, - { iconv_GB_1988_80_e, "GB_1988-80" }, - { iconv_GB_198880_e, "GB_198880" }, - { iconv_GEORGIAN_ACADEMY_e, "GEORGIAN-ACADEMY" }, - { iconv_GEORGIAN_PS_e, "GEORGIAN-PS" }, - { iconv_GOST_19768_74_e, "GOST_19768-74" }, - { iconv_GOST_19768_e, "GOST_19768" }, - { iconv_GOST_1976874_e, "GOST_1976874" }, - { iconv_GREEK_CCITT_e, "GREEK-CCITT" }, - { iconv_GREEK_e, "GREEK" }, - { iconv_GREEK7_OLD_e, "GREEK7-OLD" }, - { iconv_GREEK7_e, "GREEK7" }, - { iconv_GREEK7OLD_e, "GREEK7OLD" }, - { iconv_GREEK8_e, "GREEK8" }, - { iconv_GREEKCCITT_e, "GREEKCCITT" }, - { iconv_HEBREW_e, "HEBREW" }, - { iconv_HP_GREEK8_e, "HP-GREEK8" }, - { iconv_HP_ROMAN8_e, "HP-ROMAN8" }, - { iconv_HP_ROMAN9_e, "HP-ROMAN9" }, - { iconv_HP_THAI8_e, "HP-THAI8" }, - { iconv_HP_TURKISH8_e, "HP-TURKISH8" }, - { iconv_HPGREEK8_e, "HPGREEK8" }, - { iconv_HPROMAN8_e, "HPROMAN8" }, - { iconv_HPROMAN9_e, "HPROMAN9" }, - { iconv_HPTHAI8_e, "HPTHAI8" }, - { iconv_HPTURKISH8_e, "HPTURKISH8" }, - { iconv_HU_e, "HU" }, - { iconv_IBM_803_e, "IBM-803" }, - { iconv_IBM_856_e, "IBM-856" }, - { iconv_IBM_901_e, "IBM-901" }, - { iconv_IBM_902_e, "IBM-902" }, - { iconv_IBM_921_e, "IBM-921" }, - { iconv_IBM_922_e, "IBM-922" }, - { iconv_IBM_930_e, "IBM-930" }, - { iconv_IBM_932_e, "IBM-932" }, - { iconv_IBM_933_e, "IBM-933" }, - { iconv_IBM_935_e, "IBM-935" }, - { iconv_IBM_937_e, "IBM-937" }, - { iconv_IBM_939_e, "IBM-939" }, - { iconv_IBM_943_e, "IBM-943" }, - { iconv_IBM_1008_e, "IBM-1008" }, - { iconv_IBM_1025_e, "IBM-1025" }, - { iconv_IBM_1046_e, "IBM-1046" }, - { iconv_IBM_1047_e, "IBM-1047" }, - { iconv_IBM_1097_e, "IBM-1097" }, - { iconv_IBM_1112_e, "IBM-1112" }, - { iconv_IBM_1122_e, "IBM-1122" }, - { iconv_IBM_1123_e, "IBM-1123" }, - { iconv_IBM_1124_e, "IBM-1124" }, - { iconv_IBM_1129_e, "IBM-1129" }, - { iconv_IBM_1130_e, "IBM-1130" }, - { iconv_IBM_1132_e, "IBM-1132" }, - { iconv_IBM_1133_e, "IBM-1133" }, - { iconv_IBM_1137_e, "IBM-1137" }, - { iconv_IBM_1140_e, "IBM-1140" }, - { iconv_IBM_1141_e, "IBM-1141" }, - { iconv_IBM_1142_e, "IBM-1142" }, - { iconv_IBM_1143_e, "IBM-1143" }, - { iconv_IBM_1144_e, "IBM-1144" }, - { iconv_IBM_1145_e, "IBM-1145" }, - { iconv_IBM_1146_e, "IBM-1146" }, - { iconv_IBM_1147_e, "IBM-1147" }, - { iconv_IBM_1148_e, "IBM-1148" }, - { iconv_IBM_1149_e, "IBM-1149" }, - { iconv_IBM_1153_e, "IBM-1153" }, - { iconv_IBM_1154_e, "IBM-1154" }, - { iconv_IBM_1155_e, "IBM-1155" }, - { iconv_IBM_1156_e, "IBM-1156" }, - { iconv_IBM_1157_e, "IBM-1157" }, - { iconv_IBM_1158_e, "IBM-1158" }, - { iconv_IBM_1160_e, "IBM-1160" }, - { iconv_IBM_1161_e, "IBM-1161" }, - { iconv_IBM_1162_e, "IBM-1162" }, - { iconv_IBM_1163_e, "IBM-1163" }, - { iconv_IBM_1164_e, "IBM-1164" }, - { iconv_IBM_1166_e, "IBM-1166" }, - { iconv_IBM_1167_e, "IBM-1167" }, - { iconv_IBM_1364_e, "IBM-1364" }, - { iconv_IBM_1371_e, "IBM-1371" }, - { iconv_IBM_1388_e, "IBM-1388" }, - { iconv_IBM_1390_e, "IBM-1390" }, - { iconv_IBM_1399_e, "IBM-1399" }, - { iconv_IBM_4517_e, "IBM-4517" }, - { iconv_IBM_4899_e, "IBM-4899" }, - { iconv_IBM_4909_e, "IBM-4909" }, - { iconv_IBM_4971_e, "IBM-4971" }, - { iconv_IBM_5347_e, "IBM-5347" }, - { iconv_IBM_9030_e, "IBM-9030" }, - { iconv_IBM_9066_e, "IBM-9066" }, - { iconv_IBM_9448_e, "IBM-9448" }, - { iconv_IBM_12712_e, "IBM-12712" }, - { iconv_IBM_16804_e, "IBM-16804" }, - { iconv_IBM037_e, "IBM037" }, - { iconv_IBM038_e, "IBM038" }, - { iconv_IBM256_e, "IBM256" }, - { iconv_IBM273_e, "IBM273" }, - { iconv_IBM274_e, "IBM274" }, - { iconv_IBM275_e, "IBM275" }, - { iconv_IBM277_e, "IBM277" }, - { iconv_IBM278_e, "IBM278" }, - { iconv_IBM280_e, "IBM280" }, - { iconv_IBM281_e, "IBM281" }, - { iconv_IBM284_e, "IBM284" }, - { iconv_IBM285_e, "IBM285" }, - { iconv_IBM290_e, "IBM290" }, - { iconv_IBM297_e, "IBM297" }, - { iconv_IBM367_e, "IBM367" }, - { iconv_IBM420_e, "IBM420" }, - { iconv_IBM423_e, "IBM423" }, - { iconv_IBM424_e, "IBM424" }, - { iconv_IBM437_e, "IBM437" }, - { iconv_IBM500_e, "IBM500" }, - { iconv_IBM775_e, "IBM775" }, - { iconv_IBM803_e, "IBM803" }, - { iconv_IBM813_e, "IBM813" }, - { iconv_IBM819_e, "IBM819" }, - { iconv_IBM848_e, "IBM848" }, - { iconv_IBM850_e, "IBM850" }, - { iconv_IBM851_e, "IBM851" }, - { iconv_IBM852_e, "IBM852" }, - { iconv_IBM855_e, "IBM855" }, - { iconv_IBM856_e, "IBM856" }, - { iconv_IBM857_e, "IBM857" }, - { iconv_IBM858_e, "IBM858" }, - { iconv_IBM860_e, "IBM860" }, - { iconv_IBM861_e, "IBM861" }, - { iconv_IBM862_e, "IBM862" }, - { iconv_IBM863_e, "IBM863" }, - { iconv_IBM864_e, "IBM864" }, - { iconv_IBM865_e, "IBM865" }, - { iconv_IBM866_e, "IBM866" }, - { iconv_IBM866NAV_e, "IBM866NAV" }, - { iconv_IBM868_e, "IBM868" }, - { iconv_IBM869_e, "IBM869" }, - { iconv_IBM870_e, "IBM870" }, - { iconv_IBM871_e, "IBM871" }, - { iconv_IBM874_e, "IBM874" }, - { iconv_IBM875_e, "IBM875" }, - { iconv_IBM880_e, "IBM880" }, - { iconv_IBM891_e, "IBM891" }, - { iconv_IBM901_e, "IBM901" }, - { iconv_IBM902_e, "IBM902" }, - { iconv_IBM903_e, "IBM903" }, - { iconv_IBM904_e, "IBM904" }, - { iconv_IBM905_e, "IBM905" }, - { iconv_IBM912_e, "IBM912" }, - { iconv_IBM915_e, "IBM915" }, - { iconv_IBM916_e, "IBM916" }, - { iconv_IBM918_e, "IBM918" }, - { iconv_IBM920_e, "IBM920" }, - { iconv_IBM921_e, "IBM921" }, - { iconv_IBM922_e, "IBM922" }, - { iconv_IBM930_e, "IBM930" }, - { iconv_IBM932_e, "IBM932" }, - { iconv_IBM933_e, "IBM933" }, - { iconv_IBM935_e, "IBM935" }, - { iconv_IBM937_e, "IBM937" }, - { iconv_IBM939_e, "IBM939" }, - { iconv_IBM943_e, "IBM943" }, - { iconv_IBM1004_e, "IBM1004" }, - { iconv_IBM1008_e, "IBM1008" }, - { iconv_IBM1025_e, "IBM1025" }, - { iconv_IBM1026_e, "IBM1026" }, - { iconv_IBM1046_e, "IBM1046" }, - { iconv_IBM1047_e, "IBM1047" }, - { iconv_IBM1089_e, "IBM1089" }, - { iconv_IBM1097_e, "IBM1097" }, - { iconv_IBM1112_e, "IBM1112" }, - { iconv_IBM1122_e, "IBM1122" }, - { iconv_IBM1123_e, "IBM1123" }, - { iconv_IBM1124_e, "IBM1124" }, - { iconv_IBM1129_e, "IBM1129" }, - { iconv_IBM1130_e, "IBM1130" }, - { iconv_IBM1132_e, "IBM1132" }, - { iconv_IBM1133_e, "IBM1133" }, - { iconv_IBM1137_e, "IBM1137" }, - { iconv_IBM1140_e, "IBM1140" }, - { iconv_IBM1141_e, "IBM1141" }, - { iconv_IBM1142_e, "IBM1142" }, - { iconv_IBM1143_e, "IBM1143" }, - { iconv_IBM1144_e, "IBM1144" }, - { iconv_IBM1145_e, "IBM1145" }, - { iconv_IBM1146_e, "IBM1146" }, - { iconv_IBM1147_e, "IBM1147" }, - { iconv_IBM1148_e, "IBM1148" }, - { iconv_IBM1149_e, "IBM1149" }, - { iconv_IBM1153_e, "IBM1153" }, - { iconv_IBM1154_e, "IBM1154" }, - { iconv_IBM1155_e, "IBM1155" }, - { iconv_IBM1156_e, "IBM1156" }, - { iconv_IBM1157_e, "IBM1157" }, - { iconv_IBM1158_e, "IBM1158" }, - { iconv_IBM1160_e, "IBM1160" }, - { iconv_IBM1161_e, "IBM1161" }, - { iconv_IBM1162_e, "IBM1162" }, - { iconv_IBM1163_e, "IBM1163" }, - { iconv_IBM1164_e, "IBM1164" }, - { iconv_IBM1166_e, "IBM1166" }, - { iconv_IBM1167_e, "IBM1167" }, - { iconv_IBM1364_e, "IBM1364" }, - { iconv_IBM1371_e, "IBM1371" }, - { iconv_IBM1388_e, "IBM1388" }, - { iconv_IBM1390_e, "IBM1390" }, - { iconv_IBM1399_e, "IBM1399" }, - { iconv_IBM4517_e, "IBM4517" }, - { iconv_IBM4899_e, "IBM4899" }, - { iconv_IBM4909_e, "IBM4909" }, - { iconv_IBM4971_e, "IBM4971" }, - { iconv_IBM5347_e, "IBM5347" }, - { iconv_IBM9030_e, "IBM9030" }, - { iconv_IBM9066_e, "IBM9066" }, - { iconv_IBM9448_e, "IBM9448" }, - { iconv_IBM12712_e, "IBM12712" }, - { iconv_IBM16804_e, "IBM16804" }, - { iconv_IEC_P27_1_e, "IEC_P27-1" }, - { iconv_IEC_P271_e, "IEC_P271" }, - { iconv_INIS_8_e, "INIS-8" }, - { iconv_INIS_CYRILLIC_e, "INIS-CYRILLIC" }, - { iconv_INIS_e, "INIS" }, - { iconv_INIS8_e, "INIS8" }, - { iconv_INISCYRILLIC_e, "INISCYRILLIC" }, - { iconv_ISIRI_3342_e, "ISIRI-3342" }, - { iconv_ISIRI3342_e, "ISIRI3342" }, - { iconv_ISO_2022_CN_EXT_e, "ISO-2022-CN-EXT" }, - { iconv_ISO_2022_CN_e, "ISO-2022-CN" }, - { iconv_ISO_2022_JP_2_e, "ISO-2022-JP-2" }, - { iconv_ISO_2022_JP_3_e, "ISO-2022-JP-3" }, - { iconv_ISO_2022_JP_e, "ISO-2022-JP" }, - { iconv_ISO_2022_KR_e, "ISO-2022-KR" }, - { iconv_ISO_8859_1_e, "ISO-8859-1" }, - { iconv_ISO_8859_2_e, "ISO-8859-2" }, - { iconv_ISO_8859_3_e, "ISO-8859-3" }, - { iconv_ISO_8859_4_e, "ISO-8859-4" }, - { iconv_ISO_8859_5_e, "ISO-8859-5" }, - { iconv_ISO_8859_6_e, "ISO-8859-6" }, - { iconv_ISO_8859_7_e, "ISO-8859-7" }, - { iconv_ISO_8859_8_e, "ISO-8859-8" }, - { iconv_ISO_8859_9_e, "ISO-8859-9" }, - { iconv_ISO_8859_9E_e, "ISO-8859-9E" }, - { iconv_ISO_8859_10_e, "ISO-8859-10" }, - { iconv_ISO_8859_11_e, "ISO-8859-11" }, - { iconv_ISO_8859_13_e, "ISO-8859-13" }, - { iconv_ISO_8859_14_e, "ISO-8859-14" }, - { iconv_ISO_8859_15_e, "ISO-8859-15" }, - { iconv_ISO_8859_16_e, "ISO-8859-16" }, - { iconv_ISO_10646_e, "ISO-10646" }, - { iconv_ISO_10646_e, "UCS2/ ISO-10646/UCS2/" }, - { iconv_ISO_10646_e, "UCS4/ ISO-10646/UCS4/" }, - { iconv_ISO_10646_e, "UTF-8/ ISO-10646/UTF-8/" }, - { iconv_ISO_10646_e, "UTF8/ ISO-10646/UTF8/" }, - { iconv_ISO_CELTIC_e, "ISO-CELTIC" }, - { iconv_ISO_IR_4_e, "ISO-IR-4" }, - { iconv_ISO_IR_6_e, "ISO-IR-6" }, - { iconv_ISO_IR_8_1_e, "ISO-IR-8-1" }, - { iconv_ISO_IR_9_1_e, "ISO-IR-9-1" }, - { iconv_ISO_IR_10_e, "ISO-IR-10" }, - { iconv_ISO_IR_11_e, "ISO-IR-11" }, - { iconv_ISO_IR_14_e, "ISO-IR-14" }, - { iconv_ISO_IR_15_e, "ISO-IR-15" }, - { iconv_ISO_IR_16_e, "ISO-IR-16" }, - { iconv_ISO_IR_17_e, "ISO-IR-17" }, - { iconv_ISO_IR_18_e, "ISO-IR-18" }, - { iconv_ISO_IR_19_e, "ISO-IR-19" }, - { iconv_ISO_IR_21_e, "ISO-IR-21" }, - { iconv_ISO_IR_25_e, "ISO-IR-25" }, - { iconv_ISO_IR_27_e, "ISO-IR-27" }, - { iconv_ISO_IR_37_e, "ISO-IR-37" }, - { iconv_ISO_IR_49_e, "ISO-IR-49" }, - { iconv_ISO_IR_50_e, "ISO-IR-50" }, - { iconv_ISO_IR_51_e, "ISO-IR-51" }, - { iconv_ISO_IR_54_e, "ISO-IR-54" }, - { iconv_ISO_IR_55_e, "ISO-IR-55" }, - { iconv_ISO_IR_57_e, "ISO-IR-57" }, - { iconv_ISO_IR_60_e, "ISO-IR-60" }, - { iconv_ISO_IR_61_e, "ISO-IR-61" }, - { iconv_ISO_IR_69_e, "ISO-IR-69" }, - { iconv_ISO_IR_84_e, "ISO-IR-84" }, - { iconv_ISO_IR_85_e, "ISO-IR-85" }, - { iconv_ISO_IR_86_e, "ISO-IR-86" }, - { iconv_ISO_IR_88_e, "ISO-IR-88" }, - { iconv_ISO_IR_89_e, "ISO-IR-89" }, - { iconv_ISO_IR_90_e, "ISO-IR-90" }, - { iconv_ISO_IR_92_e, "ISO-IR-92" }, - { iconv_ISO_IR_98_e, "ISO-IR-98" }, - { iconv_ISO_IR_99_e, "ISO-IR-99" }, - { iconv_ISO_IR_100_e, "ISO-IR-100" }, - { iconv_ISO_IR_101_e, "ISO-IR-101" }, - { iconv_ISO_IR_103_e, "ISO-IR-103" }, - { iconv_ISO_IR_109_e, "ISO-IR-109" }, - { iconv_ISO_IR_110_e, "ISO-IR-110" }, - { iconv_ISO_IR_111_e, "ISO-IR-111" }, - { iconv_ISO_IR_121_e, "ISO-IR-121" }, - { iconv_ISO_IR_122_e, "ISO-IR-122" }, - { iconv_ISO_IR_126_e, "ISO-IR-126" }, - { iconv_ISO_IR_127_e, "ISO-IR-127" }, - { iconv_ISO_IR_138_e, "ISO-IR-138" }, - { iconv_ISO_IR_139_e, "ISO-IR-139" }, - { iconv_ISO_IR_141_e, "ISO-IR-141" }, - { iconv_ISO_IR_143_e, "ISO-IR-143" }, - { iconv_ISO_IR_144_e, "ISO-IR-144" }, - { iconv_ISO_IR_148_e, "ISO-IR-148" }, - { iconv_ISO_IR_150_e, "ISO-IR-150" }, - { iconv_ISO_IR_151_e, "ISO-IR-151" }, - { iconv_ISO_IR_153_e, "ISO-IR-153" }, - { iconv_ISO_IR_155_e, "ISO-IR-155" }, - { iconv_ISO_IR_156_e, "ISO-IR-156" }, - { iconv_ISO_IR_157_e, "ISO-IR-157" }, - { iconv_ISO_IR_166_e, "ISO-IR-166" }, - { iconv_ISO_IR_179_e, "ISO-IR-179" }, - { iconv_ISO_IR_193_e, "ISO-IR-193" }, - { iconv_ISO_IR_197_e, "ISO-IR-197" }, - { iconv_ISO_IR_199_e, "ISO-IR-199" }, - { iconv_ISO_IR_203_e, "ISO-IR-203" }, - { iconv_ISO_IR_209_e, "ISO-IR-209" }, - { iconv_ISO_IR_226_e, "ISO-IR-226" }, - { iconv_ISO_e, "TR_11548-1/ ISO/TR_11548-1/" }, - { iconv_ISO646_CA_e, "ISO646-CA" }, - { iconv_ISO646_CA2_e, "ISO646-CA2" }, - { iconv_ISO646_CN_e, "ISO646-CN" }, - { iconv_ISO646_CU_e, "ISO646-CU" }, - { iconv_ISO646_DE_e, "ISO646-DE" }, - { iconv_ISO646_DK_e, "ISO646-DK" }, - { iconv_ISO646_ES_e, "ISO646-ES" }, - { iconv_ISO646_ES2_e, "ISO646-ES2" }, - { iconv_ISO646_FI_e, "ISO646-FI" }, - { iconv_ISO646_FR_e, "ISO646-FR" }, - { iconv_ISO646_FR1_e, "ISO646-FR1" }, - { iconv_ISO646_GB_e, "ISO646-GB" }, - { iconv_ISO646_HU_e, "ISO646-HU" }, - { iconv_ISO646_IT_e, "ISO646-IT" }, - { iconv_ISO646_JP_OCR_B_e, "ISO646-JP-OCR-B" }, - { iconv_ISO646_JP_e, "ISO646-JP" }, - { iconv_ISO646_KR_e, "ISO646-KR" }, - { iconv_ISO646_NO_e, "ISO646-NO" }, - { iconv_ISO646_NO2_e, "ISO646-NO2" }, - { iconv_ISO646_PT_e, "ISO646-PT" }, - { iconv_ISO646_PT2_e, "ISO646-PT2" }, - { iconv_ISO646_SE_e, "ISO646-SE" }, - { iconv_ISO646_SE2_e, "ISO646-SE2" }, - { iconv_ISO646_US_e, "ISO646-US" }, - { iconv_ISO646_YU_e, "ISO646-YU" }, - { iconv_ISO2022CN_e, "ISO2022CN" }, - { iconv_ISO2022CNEXT_e, "ISO2022CNEXT" }, - { iconv_ISO2022JP_e, "ISO2022JP" }, - { iconv_ISO2022JP2_e, "ISO2022JP2" }, - { iconv_ISO2022KR_e, "ISO2022KR" }, - { iconv_ISO6937_e, "ISO6937" }, - { iconv_ISO8859_1_e, "ISO8859-1" }, - { iconv_ISO8859_2_e, "ISO8859-2" }, - { iconv_ISO8859_3_e, "ISO8859-3" }, - { iconv_ISO8859_4_e, "ISO8859-4" }, - { iconv_ISO8859_5_e, "ISO8859-5" }, - { iconv_ISO8859_6_e, "ISO8859-6" }, - { iconv_ISO8859_7_e, "ISO8859-7" }, - { iconv_ISO8859_8_e, "ISO8859-8" }, - { iconv_ISO8859_9_e, "ISO8859-9" }, - { iconv_ISO8859_9E_e, "ISO8859-9E" }, - { iconv_ISO8859_10_e, "ISO8859-10" }, - { iconv_ISO8859_11_e, "ISO8859-11" }, - { iconv_ISO8859_13_e, "ISO8859-13" }, - { iconv_ISO8859_14_e, "ISO8859-14" }, - { iconv_ISO8859_15_e, "ISO8859-15" }, - { iconv_ISO8859_16_e, "ISO8859-16" }, - { iconv_ISO11548_1_e, "ISO11548-1" }, - { iconv_ISO88591_e, "ISO88591" }, - { iconv_ISO88592_e, "ISO88592" }, - { iconv_ISO88593_e, "ISO88593" }, - { iconv_ISO88594_e, "ISO88594" }, - { iconv_ISO88595_e, "ISO88595" }, - { iconv_ISO88596_e, "ISO88596" }, - { iconv_ISO88597_e, "ISO88597" }, - { iconv_ISO88598_e, "ISO88598" }, - { iconv_ISO88599_e, "ISO88599" }, - { iconv_ISO88599E_e, "ISO88599E" }, - { iconv_ISO885910_e, "ISO885910" }, - { iconv_ISO885911_e, "ISO885911" }, - { iconv_ISO885913_e, "ISO885913" }, - { iconv_ISO885914_e, "ISO885914" }, - { iconv_ISO885915_e, "ISO885915" }, - { iconv_ISO885916_e, "ISO885916" }, - { iconv_ISO_646_IRV_1991_e, "ISO_646.IRV:1991" }, - { iconv_ISO_2033_1983_e, "ISO_2033-1983" }, - { iconv_ISO_2033_e, "ISO_2033" }, - { iconv_ISO_5427_EXT_e, "ISO_5427-EXT" }, - { iconv_ISO_5427_e, "ISO_5427" }, - { iconv_ISO_5427_1981_e, "ISO_5427:1981" }, - { iconv_ISO_5427EXT_e, "ISO_5427EXT" }, - { iconv_ISO_5428_e, "ISO_5428" }, - { iconv_ISO_5428_1980_e, "ISO_5428:1980" }, - { iconv_ISO_6937_2_e, "ISO_6937-2" }, - { iconv_ISO_6937_2_1983_e, "ISO_6937-2:1983" }, - { iconv_ISO_6937_e, "ISO_6937" }, - { iconv_ISO_6937_1992_e, "ISO_6937:1992" }, - { iconv_ISO_8859_1_e, "ISO_8859-1" }, - { iconv_ISO_8859_1_1987_e, "ISO_8859-1:1987" }, - { iconv_ISO_8859_2_e, "ISO_8859-2" }, - { iconv_ISO_8859_2_1987_e, "ISO_8859-2:1987" }, - { iconv_ISO_8859_3_e, "ISO_8859-3" }, - { iconv_ISO_8859_3_1988_e, "ISO_8859-3:1988" }, - { iconv_ISO_8859_4_e, "ISO_8859-4" }, - { iconv_ISO_8859_4_1988_e, "ISO_8859-4:1988" }, - { iconv_ISO_8859_5_e, "ISO_8859-5" }, - { iconv_ISO_8859_5_1988_e, "ISO_8859-5:1988" }, - { iconv_ISO_8859_6_e, "ISO_8859-6" }, - { iconv_ISO_8859_6_1987_e, "ISO_8859-6:1987" }, - { iconv_ISO_8859_7_e, "ISO_8859-7" }, - { iconv_ISO_8859_7_1987_e, "ISO_8859-7:1987" }, - { iconv_ISO_8859_7_2003_e, "ISO_8859-7:2003" }, - { iconv_ISO_8859_8_e, "ISO_8859-8" }, - { iconv_ISO_8859_8_1988_e, "ISO_8859-8:1988" }, - { iconv_ISO_8859_9_e, "ISO_8859-9" }, - { iconv_ISO_8859_9_1989_e, "ISO_8859-9:1989" }, - { iconv_ISO_8859_9E_e, "ISO_8859-9E" }, - { iconv_ISO_8859_10_e, "ISO_8859-10" }, - { iconv_ISO_8859_10_1992_e, "ISO_8859-10:1992" }, - { iconv_ISO_8859_14_e, "ISO_8859-14" }, - { iconv_ISO_8859_14_1998_e, "ISO_8859-14:1998" }, - { iconv_ISO_8859_15_e, "ISO_8859-15" }, - { iconv_ISO_8859_15_1998_e, "ISO_8859-15:1998" }, - { iconv_ISO_8859_16_e, "ISO_8859-16" }, - { iconv_ISO_8859_16_2001_e, "ISO_8859-16:2001" }, - { iconv_ISO_9036_e, "ISO_9036" }, - { iconv_ISO_10367_BOX_e, "ISO_10367-BOX" }, - { iconv_ISO_10367BOX_e, "ISO_10367BOX" }, - { iconv_ISO_11548_1_e, "ISO_11548-1" }, - { iconv_ISO_69372_e, "ISO_69372" }, - { iconv_IT_e, "IT" }, - { iconv_JIS_C6220_1969_RO_e, "JIS_C6220-1969-RO" }, - { iconv_JIS_C6229_1984_B_e, "JIS_C6229-1984-B" }, - { iconv_JIS_C62201969RO_e, "JIS_C62201969RO" }, - { iconv_JIS_C62291984B_e, "JIS_C62291984B" }, - { iconv_JOHAB_e, "JOHAB" }, - { iconv_JP_OCR_B_e, "JP-OCR-B" }, - { iconv_JP_e, "JP" }, - { iconv_JS_e, "JS" }, - { iconv_JUS_I_B1_002_e, "JUS_I.B1.002" }, - { iconv_KOI_7_e, "KOI-7" }, - { iconv_KOI_8_e, "KOI-8" }, - { iconv_KOI8_R_e, "KOI8-R" }, - { iconv_KOI8_RU_e, "KOI8-RU" }, - { iconv_KOI8_T_e, "KOI8-T" }, - { iconv_KOI8_U_e, "KOI8-U" }, - { iconv_KOI8_e, "KOI8" }, - { iconv_KOI8R_e, "KOI8R" }, - { iconv_KOI8U_e, "KOI8U" }, - { iconv_KSC5636_e, "KSC5636" }, - { iconv_L1_e, "L1" }, - { iconv_L2_e, "L2" }, - { iconv_L3_e, "L3" }, - { iconv_L4_e, "L4" }, - { iconv_L5_e, "L5" }, - { iconv_L6_e, "L6" }, - { iconv_L7_e, "L7" }, - { iconv_L8_e, "L8" }, - { iconv_L10_e, "L10" }, - { iconv_LATIN_9_e, "LATIN-9" }, - { iconv_LATIN_GREEK_1_e, "LATIN-GREEK-1" }, - { iconv_LATIN_GREEK_e, "LATIN-GREEK" }, - { iconv_LATIN1_e, "LATIN1" }, - { iconv_LATIN2_e, "LATIN2" }, - { iconv_LATIN3_e, "LATIN3" }, - { iconv_LATIN4_e, "LATIN4" }, - { iconv_LATIN5_e, "LATIN5" }, - { iconv_LATIN6_e, "LATIN6" }, - { iconv_LATIN7_e, "LATIN7" }, - { iconv_LATIN8_e, "LATIN8" }, - { iconv_LATIN9_e, "LATIN9" }, - { iconv_LATIN10_e, "LATIN10" }, - { iconv_LATINGREEK_e, "LATINGREEK" }, - { iconv_LATINGREEK1_e, "LATINGREEK1" }, - { iconv_MAC_CENTRALEUROPE_e, "MAC-CENTRALEUROPE" }, - { iconv_MAC_CYRILLIC_e, "MAC-CYRILLIC" }, - { iconv_MAC_IS_e, "MAC-IS" }, - { iconv_MAC_SAMI_e, "MAC-SAMI" }, - { iconv_MAC_UK_e, "MAC-UK" }, - { iconv_MAC_e, "MAC" }, - { iconv_MACCYRILLIC_e, "MACCYRILLIC" }, - { iconv_MACINTOSH_e, "MACINTOSH" }, - { iconv_MACIS_e, "MACIS" }, - { iconv_MACUK_e, "MACUK" }, - { iconv_MACUKRAINIAN_e, "MACUKRAINIAN" }, - { iconv_MIK_e, "MIK" }, - { iconv_MS_ANSI_e, "MS-ANSI" }, - { iconv_MS_ARAB_e, "MS-ARAB" }, - { iconv_MS_CYRL_e, "MS-CYRL" }, - { iconv_MS_EE_e, "MS-EE" }, - { iconv_MS_GREEK_e, "MS-GREEK" }, - { iconv_MS_HEBR_e, "MS-HEBR" }, - { iconv_MS_MAC_CYRILLIC_e, "MS-MAC-CYRILLIC" }, - { iconv_MS_TURK_e, "MS-TURK" }, - { iconv_MS932_e, "MS932" }, - { iconv_MS936_e, "MS936" }, - { iconv_MSCP949_e, "MSCP949" }, - { iconv_MSCP1361_e, "MSCP1361" }, - { iconv_MSMACCYRILLIC_e, "MSMACCYRILLIC" }, - { iconv_MSZ_7795_3_e, "MSZ_7795.3" }, - { iconv_MS_KANJI_e, "MS_KANJI" }, - { iconv_NAPLPS_e, "NAPLPS" }, - { iconv_NATS_DANO_e, "NATS-DANO" }, - { iconv_NATS_SEFI_e, "NATS-SEFI" }, - { iconv_NATSDANO_e, "NATSDANO" }, - { iconv_NATSSEFI_e, "NATSSEFI" }, - { iconv_NC_NC0010_e, "NC_NC0010" }, - { iconv_NC_NC00_10_e, "NC_NC00-10" }, - { iconv_NC_NC00_10_81_e, "NC_NC00-10:81" }, - { iconv_NF_Z_62_010_e, "NF_Z_62-010" }, - { iconv_NF_Z_62_010__1973__e, "NF_Z_62-010_(1973)" }, - { iconv_NF_Z_62_010_1973_e, "NF_Z_62-010_1973" }, - { iconv_NF_Z_62010_e, "NF_Z_62010" }, - { iconv_NF_Z_62010_1973_e, "NF_Z_62010_1973" }, - { iconv_NO_e, "NO" }, - { iconv_NO2_e, "NO2" }, - { iconv_NS_4551_1_e, "NS_4551-1" }, - { iconv_NS_4551_2_e, "NS_4551-2" }, - { iconv_NS_45511_e, "NS_45511" }, - { iconv_NS_45512_e, "NS_45512" }, - { iconv_OS2LATIN1_e, "OS2LATIN1" }, - { iconv_OSF00010001_e, "OSF00010001" }, - { iconv_OSF00010002_e, "OSF00010002" }, - { iconv_OSF00010003_e, "OSF00010003" }, - { iconv_OSF00010004_e, "OSF00010004" }, - { iconv_OSF00010005_e, "OSF00010005" }, - { iconv_OSF00010006_e, "OSF00010006" }, - { iconv_OSF00010007_e, "OSF00010007" }, - { iconv_OSF00010008_e, "OSF00010008" }, - { iconv_OSF00010009_e, "OSF00010009" }, - { iconv_OSF0001000A_e, "OSF0001000A" }, - { iconv_OSF00010020_e, "OSF00010020" }, - { iconv_OSF00010100_e, "OSF00010100" }, - { iconv_OSF00010101_e, "OSF00010101" }, - { iconv_OSF00010102_e, "OSF00010102" }, - { iconv_OSF00010104_e, "OSF00010104" }, - { iconv_OSF00010105_e, "OSF00010105" }, - { iconv_OSF00010106_e, "OSF00010106" }, - { iconv_OSF00030010_e, "OSF00030010" }, - { iconv_OSF0004000A_e, "OSF0004000A" }, - { iconv_OSF0005000A_e, "OSF0005000A" }, - { iconv_OSF05010001_e, "OSF05010001" }, - { iconv_OSF100201A4_e, "OSF100201A4" }, - { iconv_OSF100201A8_e, "OSF100201A8" }, - { iconv_OSF100201B5_e, "OSF100201B5" }, - { iconv_OSF100201F4_e, "OSF100201F4" }, - { iconv_OSF100203B5_e, "OSF100203B5" }, - { iconv_OSF1002011C_e, "OSF1002011C" }, - { iconv_OSF1002011D_e, "OSF1002011D" }, - { iconv_OSF1002035D_e, "OSF1002035D" }, - { iconv_OSF1002035E_e, "OSF1002035E" }, - { iconv_OSF1002035F_e, "OSF1002035F" }, - { iconv_OSF1002036B_e, "OSF1002036B" }, - { iconv_OSF1002037B_e, "OSF1002037B" }, - { iconv_OSF10010001_e, "OSF10010001" }, - { iconv_OSF10010004_e, "OSF10010004" }, - { iconv_OSF10010006_e, "OSF10010006" }, - { iconv_OSF10020025_e, "OSF10020025" }, - { iconv_OSF10020111_e, "OSF10020111" }, - { iconv_OSF10020115_e, "OSF10020115" }, - { iconv_OSF10020116_e, "OSF10020116" }, - { iconv_OSF10020118_e, "OSF10020118" }, - { iconv_OSF10020122_e, "OSF10020122" }, - { iconv_OSF10020129_e, "OSF10020129" }, - { iconv_OSF10020352_e, "OSF10020352" }, - { iconv_OSF10020354_e, "OSF10020354" }, - { iconv_OSF10020357_e, "OSF10020357" }, - { iconv_OSF10020359_e, "OSF10020359" }, - { iconv_OSF10020360_e, "OSF10020360" }, - { iconv_OSF10020364_e, "OSF10020364" }, - { iconv_OSF10020365_e, "OSF10020365" }, - { iconv_OSF10020366_e, "OSF10020366" }, - { iconv_OSF10020367_e, "OSF10020367" }, - { iconv_OSF10020370_e, "OSF10020370" }, - { iconv_OSF10020387_e, "OSF10020387" }, - { iconv_OSF10020388_e, "OSF10020388" }, - { iconv_OSF10020396_e, "OSF10020396" }, - { iconv_OSF10020402_e, "OSF10020402" }, - { iconv_OSF10020417_e, "OSF10020417" }, - { iconv_PT_e, "PT" }, - { iconv_PT2_e, "PT2" }, - { iconv_PT154_e, "PT154" }, - { iconv_R8_e, "R8" }, - { iconv_R9_e, "R9" }, - { iconv_RK1048_e, "RK1048" }, - { iconv_ROMAN8_e, "ROMAN8" }, - { iconv_ROMAN9_e, "ROMAN9" }, - { iconv_RUSCII_e, "RUSCII" }, - { iconv_SE_e, "SE" }, - { iconv_SE2_e, "SE2" }, - { iconv_SEN_850200_B_e, "SEN_850200_B" }, - { iconv_SEN_850200_C_e, "SEN_850200_C" }, - { iconv_SHIFT_JIS_e, "SHIFT-JIS" }, - { iconv_SHIFTJISX0213_e, "SHIFTJISX0213" }, - { iconv_SHIFT_JIS_e, "SHIFT_JIS" }, - { iconv_SHIFT_JISX0213_e, "SHIFT_JISX0213" }, - { iconv_SJIS_OPEN_e, "SJIS-OPEN" }, - { iconv_SJIS_WIN_e, "SJIS-WIN" }, - { iconv_SJIS_e, "SJIS" }, - { iconv_SS636127_e, "SS636127" }, - { iconv_STRK1048_2002_e, "STRK1048-2002" }, - { iconv_ST_SEV_358_88_e, "ST_SEV_358-88" }, - { iconv_T_61_8BIT_e, "T.61-8BIT" }, - { iconv_T_61_e, "T.61" }, - { iconv_T_618BIT_e, "T.618BIT" }, - { iconv_TCVN_5712_e, "TCVN-5712" }, - { iconv_TCVN_e, "TCVN" }, - { iconv_TCVN5712_1_e, "TCVN5712-1" }, - { iconv_TCVN5712_1_1993_e, "TCVN5712-1:1993" }, - { iconv_THAI8_e, "THAI8" }, - { iconv_TIS_620_e, "TIS-620" }, - { iconv_TIS620_0_e, "TIS620-0" }, - { iconv_TIS620_2529_1_e, "TIS620.2529-1" }, - { iconv_TIS620_2533_0_e, "TIS620.2533-0" }, - { iconv_TIS620_e, "TIS620" }, - { iconv_TS_5881_e, "TS-5881" }, - { iconv_TSCII_e, "TSCII" }, - { iconv_TURKISH8_e, "TURKISH8" }, - { iconv_UCS_2_e, "UCS-2" }, - { iconv_UCS_2BE_e, "UCS-2BE" }, - { iconv_UCS_2LE_e, "UCS-2LE" }, - { iconv_UCS_4_e, "UCS-4" }, - { iconv_UCS_4BE_e, "UCS-4BE" }, - { iconv_UCS_4LE_e, "UCS-4LE" }, - { iconv_UCS2_e, "UCS2" }, - { iconv_UCS4_e, "UCS4" }, - { iconv_UHC_e, "UHC" }, - { iconv_UJIS_e, "UJIS" }, - { iconv_UK_e, "UK" }, - { iconv_UNICODE_e, "UNICODE" }, - { iconv_UNICODEBIG_e, "UNICODEBIG" }, - { iconv_UNICODELITTLE_e, "UNICODELITTLE" }, - { iconv_US_ASCII_e, "US-ASCII" }, - { iconv_US_e, "US" }, - { iconv_UTF_7_e, "UTF-7" }, - { iconv_UTF_8_e, "UTF-8" }, - { iconv_UTF_16_e, "UTF-16" }, - { iconv_UTF_16BE_e, "UTF-16BE" }, - { iconv_UTF_16LE_e, "UTF-16LE" }, - { iconv_UTF_32_e, "UTF-32" }, - { iconv_UTF_32BE_e, "UTF-32BE" }, - { iconv_UTF_32LE_e, "UTF-32LE" }, - { iconv_UTF7_e, "UTF7" }, - { iconv_UTF8_e, "UTF8" }, - { iconv_UTF16_e, "UTF16" }, - { iconv_UTF16BE_e, "UTF16BE" }, - { iconv_UTF16LE_e, "UTF16LE" }, - { iconv_UTF32_e, "UTF32" }, - { iconv_UTF32BE_e, "UTF32BE" }, - { iconv_UTF32LE_e, "UTF32LE" }, - { iconv_VISCII_e, "VISCII" }, - { iconv_WCHAR_T_e, "WCHAR_T" }, - { iconv_WIN_SAMI_2_e, "WIN-SAMI-2" }, - { iconv_WINBALTRIM_e, "WINBALTRIM" }, - { iconv_WINDOWS_31J_e, "WINDOWS-31J" }, - { iconv_WINDOWS_874_e, "WINDOWS-874" }, - { iconv_WINDOWS_936_e, "WINDOWS-936" }, - { iconv_WINDOWS_1250_e, "WINDOWS-1250" }, - { iconv_WINDOWS_1251_e, "WINDOWS-1251" }, - { iconv_WINDOWS_1252_e, "WINDOWS-1252" }, - { iconv_WINDOWS_1253_e, "WINDOWS-1253" }, - { iconv_WINDOWS_1254_e, "WINDOWS-1254" }, - { iconv_WINDOWS_1255_e, "WINDOWS-1255" }, - { iconv_WINDOWS_1256_e, "WINDOWS-1256" }, - { iconv_WINDOWS_1257_e, "WINDOWS-1257" }, - { iconv_WINDOWS_1258_e, "WINDOWS-1258" }, - { iconv_WINSAMI2_e, "WINSAMI2" }, - { iconv_WS2_e, "WS2" }, - { iconv_YU_e, "YU" }, + { false, iconv_437_e, "437" }, + { false, iconv_500_e, "500" }, + { false, iconv_500V1_e, "500V1" }, + { false, iconv_850_e, "850" }, + { false, iconv_851_e, "851" }, + { false, iconv_852_e, "852" }, + { false, iconv_855_e, "855" }, + { false, iconv_856_e, "856" }, + { false, iconv_857_e, "857" }, + { false, iconv_858_e, "858" }, + { false, iconv_860_e, "860" }, + { false, iconv_861_e, "861" }, + { false, iconv_862_e, "862" }, + { false, iconv_863_e, "863" }, + { false, iconv_864_e, "864" }, + { false, iconv_865_e, "865" }, + { false, iconv_866_e, "866" }, + { false, iconv_866NAV_e, "866NAV" }, + { false, iconv_869_e, "869" }, + { false, iconv_874_e, "874" }, + { false, iconv_904_e, "904" }, + { false, iconv_1026_e, "1026" }, + { false, iconv_1046_e, "1046" }, + { false, iconv_1047_e, "1047" }, + { false, iconv_8859_1_e, "8859_1" }, + { false, iconv_8859_2_e, "8859_2" }, + { false, iconv_8859_3_e, "8859_3" }, + { false, iconv_8859_4_e, "8859_4" }, + { false, iconv_8859_5_e, "8859_5" }, + { false, iconv_8859_6_e, "8859_6" }, + { false, iconv_8859_7_e, "8859_7" }, + { false, iconv_8859_8_e, "8859_8" }, + { false, iconv_8859_9_e, "8859_9" }, + { false, iconv_10646_1_1993_e, "10646-1:1993" }, + { false, iconv_10646_1_1993_e, "UCS4/ 10646-1:1993/UCS4/" }, + { false, iconv_ANSI_X3_4_1968_e, "ANSI_X3.4-1968" }, + { false, iconv_ANSI_X3_4_1986_e, "ANSI_X3.4-1986" }, + { false, iconv_ANSI_X3_4_e, "ANSI_X3.4" }, + { false, iconv_ANSI_X3_110_1983_e, "ANSI_X3.110-1983" }, + { false, iconv_ANSI_X3_110_e, "ANSI_X3.110" }, + { false, iconv_ARABIC_e, "ARABIC" }, + { false, iconv_ARABIC7_e, "ARABIC7" }, + { false, iconv_ARMSCII_8_e, "ARMSCII-8" }, + { false, iconv_ARMSCII8_e, "ARMSCII8" }, + { true, iconv_ASCII_e, "ASCII" }, + { false, iconv_ASMO_708_e, "ASMO-708" }, + { false, iconv_ASMO_449_e, "ASMO_449" }, + { false, iconv_BALTIC_e, "BALTIC" }, + { false, iconv_BIG_5_e, "BIG-5" }, + { false, iconv_BIG_FIVE_e, "BIG-FIVE" }, + { false, iconv_BIG5_HKSCS_e, "BIG5-HKSCS" }, + { false, iconv_BIG5_e, "BIG5" }, + { false, iconv_BIG5HKSCS_e, "BIG5HKSCS" }, + { false, iconv_BIGFIVE_e, "BIGFIVE" }, + { false, iconv_BRF_e, "BRF" }, + { false, iconv_BS_4730_e, "BS_4730" }, + { false, iconv_CA_e, "CA" }, + { false, iconv_CN_BIG5_e, "CN-BIG5" }, + { false, iconv_CN_GB_e, "CN-GB" }, + { false, iconv_CN_e, "CN" }, + { false, iconv_CP_AR_e, "CP-AR" }, + { false, iconv_CP_GR_e, "CP-GR" }, + { false, iconv_CP_HU_e, "CP-HU" }, + { false, iconv_CP037_e, "CP037" }, + { false, iconv_CP038_e, "CP038" }, + { false, iconv_CP273_e, "CP273" }, + { false, iconv_CP274_e, "CP274" }, + { false, iconv_CP275_e, "CP275" }, + { false, iconv_CP278_e, "CP278" }, + { false, iconv_CP280_e, "CP280" }, + { false, iconv_CP281_e, "CP281" }, + { false, iconv_CP282_e, "CP282" }, + { false, iconv_CP284_e, "CP284" }, + { false, iconv_CP285_e, "CP285" }, + { false, iconv_CP290_e, "CP290" }, + { false, iconv_CP297_e, "CP297" }, + { false, iconv_CP367_e, "CP367" }, + { false, iconv_CP420_e, "CP420" }, + { false, iconv_CP423_e, "CP423" }, + { false, iconv_CP424_e, "CP424" }, + { false, iconv_CP437_e, "CP437" }, + { false, iconv_CP500_e, "CP500" }, + { false, iconv_CP737_e, "CP737" }, + { false, iconv_CP770_e, "CP770" }, + { false, iconv_CP771_e, "CP771" }, + { false, iconv_CP772_e, "CP772" }, + { false, iconv_CP773_e, "CP773" }, + { false, iconv_CP774_e, "CP774" }, + { false, iconv_CP775_e, "CP775" }, + { false, iconv_CP803_e, "CP803" }, + { false, iconv_CP813_e, "CP813" }, + { false, iconv_CP819_e, "CP819" }, + { false, iconv_CP850_e, "CP850" }, + { false, iconv_CP851_e, "CP851" }, + { false, iconv_CP852_e, "CP852" }, + { false, iconv_CP855_e, "CP855" }, + { false, iconv_CP856_e, "CP856" }, + { false, iconv_CP857_e, "CP857" }, + { false, iconv_CP858_e, "CP858" }, + { false, iconv_CP860_e, "CP860" }, + { false, iconv_CP861_e, "CP861" }, + { false, iconv_CP862_e, "CP862" }, + { false, iconv_CP863_e, "CP863" }, + { false, iconv_CP864_e, "CP864" }, + { false, iconv_CP865_e, "CP865" }, + { false, iconv_CP866_e, "CP866" }, + { false, iconv_CP866NAV_e, "CP866NAV" }, + { false, iconv_CP868_e, "CP868" }, + { false, iconv_CP869_e, "CP869" }, + { false, iconv_CP870_e, "CP870" }, + { false, iconv_CP871_e, "CP871" }, + { false, iconv_CP874_e, "CP874" }, + { false, iconv_CP875_e, "CP875" }, + { false, iconv_CP880_e, "CP880" }, + { false, iconv_CP891_e, "CP891" }, + { false, iconv_CP901_e, "CP901" }, + { false, iconv_CP902_e, "CP902" }, + { false, iconv_CP903_e, "CP903" }, + { false, iconv_CP904_e, "CP904" }, + { false, iconv_CP905_e, "CP905" }, + { false, iconv_CP912_e, "CP912" }, + { false, iconv_CP915_e, "CP915" }, + { false, iconv_CP916_e, "CP916" }, + { false, iconv_CP918_e, "CP918" }, + { false, iconv_CP920_e, "CP920" }, + { false, iconv_CP921_e, "CP921" }, + { false, iconv_CP922_e, "CP922" }, + { false, iconv_CP930_e, "CP930" }, + { false, iconv_CP932_e, "CP932" }, + { false, iconv_CP933_e, "CP933" }, + { false, iconv_CP935_e, "CP935" }, + { false, iconv_CP936_e, "CP936" }, + { false, iconv_CP937_e, "CP937" }, + { false, iconv_CP939_e, "CP939" }, + { false, iconv_CP949_e, "CP949" }, + { false, iconv_CP950_e, "CP950" }, + { false, iconv_CP1004_e, "CP1004" }, + { false, iconv_CP1008_e, "CP1008" }, + { false, iconv_CP1025_e, "CP1025" }, + { false, iconv_CP1026_e, "CP1026" }, + { false, iconv_CP1046_e, "CP1046" }, + { false, iconv_CP1047_e, "CP1047" }, + { false, iconv_CP1070_e, "CP1070" }, + { false, iconv_CP1079_e, "CP1079" }, + { false, iconv_CP1081_e, "CP1081" }, + { false, iconv_CP1084_e, "CP1084" }, + { false, iconv_CP1089_e, "CP1089" }, + { false, iconv_CP1097_e, "CP1097" }, + { false, iconv_CP1112_e, "CP1112" }, + { false, iconv_CP1122_e, "CP1122" }, + { false, iconv_CP1123_e, "CP1123" }, + { false, iconv_CP1124_e, "CP1124" }, + { false, iconv_CP1125_e, "CP1125" }, + { false, iconv_CP1129_e, "CP1129" }, + { false, iconv_CP1130_e, "CP1130" }, + { false, iconv_CP1132_e, "CP1132" }, + { false, iconv_CP1133_e, "CP1133" }, + { false, iconv_CP1137_e, "CP1137" }, + { true, iconv_CP1140_e, "CP1140" }, + { false, iconv_CP1141_e, "CP1141" }, + { false, iconv_CP1142_e, "CP1142" }, + { false, iconv_CP1143_e, "CP1143" }, + { false, iconv_CP1144_e, "CP1144" }, + { false, iconv_CP1145_e, "CP1145" }, + { false, iconv_CP1146_e, "CP1146" }, + { false, iconv_CP1147_e, "CP1147" }, + { false, iconv_CP1148_e, "CP1148" }, + { false, iconv_CP1149_e, "CP1149" }, + { false, iconv_CP1153_e, "CP1153" }, + { false, iconv_CP1154_e, "CP1154" }, + { false, iconv_CP1155_e, "CP1155" }, + { false, iconv_CP1156_e, "CP1156" }, + { false, iconv_CP1157_e, "CP1157" }, + { false, iconv_CP1158_e, "CP1158" }, + { false, iconv_CP1160_e, "CP1160" }, + { false, iconv_CP1161_e, "CP1161" }, + { false, iconv_CP1162_e, "CP1162" }, + { false, iconv_CP1163_e, "CP1163" }, + { false, iconv_CP1164_e, "CP1164" }, + { false, iconv_CP1166_e, "CP1166" }, + { false, iconv_CP1167_e, "CP1167" }, + { false, iconv_CP1250_e, "CP1250" }, + { false, iconv_CP1251_e, "CP1251" }, + { true, iconv_CP1252_e, "CP1252" }, + { false, iconv_CP1253_e, "CP1253" }, + { false, iconv_CP1254_e, "CP1254" }, + { false, iconv_CP1255_e, "CP1255" }, + { false, iconv_CP1256_e, "CP1256" }, + { false, iconv_CP1257_e, "CP1257" }, + { false, iconv_CP1258_e, "CP1258" }, + { false, iconv_CP1282_e, "CP1282" }, + { false, iconv_CP1361_e, "CP1361" }, + { false, iconv_CP1364_e, "CP1364" }, + { false, iconv_CP1371_e, "CP1371" }, + { false, iconv_CP1388_e, "CP1388" }, + { false, iconv_CP1390_e, "CP1390" }, + { false, iconv_CP1399_e, "CP1399" }, + { false, iconv_CP4517_e, "CP4517" }, + { false, iconv_CP4899_e, "CP4899" }, + { false, iconv_CP4909_e, "CP4909" }, + { false, iconv_CP4971_e, "CP4971" }, + { false, iconv_CP5347_e, "CP5347" }, + { false, iconv_CP9030_e, "CP9030" }, + { false, iconv_CP9066_e, "CP9066" }, + { false, iconv_CP9448_e, "CP9448" }, + { false, iconv_CP10007_e, "CP10007" }, + { false, iconv_CP12712_e, "CP12712" }, + { false, iconv_CP16804_e, "CP16804" }, + { false, iconv_CPIBM861_e, "CPIBM861" }, + { false, iconv_CSA7_1_e, "CSA7-1" }, + { false, iconv_CSA7_2_e, "CSA7-2" }, + { false, iconv_CSASCII_e, "CSASCII" }, + { false, iconv_CSA_T500_1983_e, "CSA_T500-1983" }, + { false, iconv_CSA_T500_e, "CSA_T500" }, + { false, iconv_CSA_Z243_4_1985_1_e, "CSA_Z243.4-1985-1" }, + { false, iconv_CSA_Z243_4_1985_2_e, "CSA_Z243.4-1985-2" }, + { false, iconv_CSA_Z243_419851_e, "CSA_Z243.419851" }, + { false, iconv_CSA_Z243_419852_e, "CSA_Z243.419852" }, + { false, iconv_CSDECMCS_e, "CSDECMCS" }, + { false, iconv_CSEBCDICATDE_e, "CSEBCDICATDE" }, + { false, iconv_CSEBCDICATDEA_e, "CSEBCDICATDEA" }, + { false, iconv_CSEBCDICCAFR_e, "CSEBCDICCAFR" }, + { false, iconv_CSEBCDICDKNO_e, "CSEBCDICDKNO" }, + { false, iconv_CSEBCDICDKNOA_e, "CSEBCDICDKNOA" }, + { false, iconv_CSEBCDICES_e, "CSEBCDICES" }, + { false, iconv_CSEBCDICESA_e, "CSEBCDICESA" }, + { false, iconv_CSEBCDICESS_e, "CSEBCDICESS" }, + { false, iconv_CSEBCDICFISE_e, "CSEBCDICFISE" }, + { false, iconv_CSEBCDICFISEA_e, "CSEBCDICFISEA" }, + { false, iconv_CSEBCDICFR_e, "CSEBCDICFR" }, + { false, iconv_CSEBCDICIT_e, "CSEBCDICIT" }, + { false, iconv_CSEBCDICPT_e, "CSEBCDICPT" }, + { false, iconv_CSEBCDICUK_e, "CSEBCDICUK" }, + { false, iconv_CSEBCDICUS_e, "CSEBCDICUS" }, + { false, iconv_CSEUCKR_e, "CSEUCKR" }, + { false, iconv_CSEUCPKDFMTJAPANESE_e, "CSEUCPKDFMTJAPANESE" }, + { false, iconv_CSGB2312_e, "CSGB2312" }, + { false, iconv_CSHPROMAN8_e, "CSHPROMAN8" }, + { false, iconv_CSIBM037_e, "CSIBM037" }, + { false, iconv_CSIBM038_e, "CSIBM038" }, + { false, iconv_CSIBM273_e, "CSIBM273" }, + { false, iconv_CSIBM274_e, "CSIBM274" }, + { false, iconv_CSIBM275_e, "CSIBM275" }, + { false, iconv_CSIBM277_e, "CSIBM277" }, + { false, iconv_CSIBM278_e, "CSIBM278" }, + { false, iconv_CSIBM280_e, "CSIBM280" }, + { false, iconv_CSIBM281_e, "CSIBM281" }, + { false, iconv_CSIBM284_e, "CSIBM284" }, + { false, iconv_CSIBM285_e, "CSIBM285" }, + { false, iconv_CSIBM290_e, "CSIBM290" }, + { false, iconv_CSIBM297_e, "CSIBM297" }, + { false, iconv_CSIBM420_e, "CSIBM420" }, + { false, iconv_CSIBM423_e, "CSIBM423" }, + { false, iconv_CSIBM424_e, "CSIBM424" }, + { false, iconv_CSIBM500_e, "CSIBM500" }, + { false, iconv_CSIBM803_e, "CSIBM803" }, + { false, iconv_CSIBM851_e, "CSIBM851" }, + { false, iconv_CSIBM855_e, "CSIBM855" }, + { false, iconv_CSIBM856_e, "CSIBM856" }, + { false, iconv_CSIBM857_e, "CSIBM857" }, + { false, iconv_CSIBM860_e, "CSIBM860" }, + { false, iconv_CSIBM863_e, "CSIBM863" }, + { false, iconv_CSIBM864_e, "CSIBM864" }, + { false, iconv_CSIBM865_e, "CSIBM865" }, + { false, iconv_CSIBM866_e, "CSIBM866" }, + { false, iconv_CSIBM868_e, "CSIBM868" }, + { false, iconv_CSIBM869_e, "CSIBM869" }, + { false, iconv_CSIBM870_e, "CSIBM870" }, + { false, iconv_CSIBM871_e, "CSIBM871" }, + { false, iconv_CSIBM880_e, "CSIBM880" }, + { false, iconv_CSIBM891_e, "CSIBM891" }, + { false, iconv_CSIBM901_e, "CSIBM901" }, + { false, iconv_CSIBM902_e, "CSIBM902" }, + { false, iconv_CSIBM903_e, "CSIBM903" }, + { false, iconv_CSIBM904_e, "CSIBM904" }, + { false, iconv_CSIBM905_e, "CSIBM905" }, + { false, iconv_CSIBM918_e, "CSIBM918" }, + { false, iconv_CSIBM921_e, "CSIBM921" }, + { false, iconv_CSIBM922_e, "CSIBM922" }, + { false, iconv_CSIBM930_e, "CSIBM930" }, + { false, iconv_CSIBM932_e, "CSIBM932" }, + { false, iconv_CSIBM933_e, "CSIBM933" }, + { false, iconv_CSIBM935_e, "CSIBM935" }, + { false, iconv_CSIBM937_e, "CSIBM937" }, + { false, iconv_CSIBM939_e, "CSIBM939" }, + { false, iconv_CSIBM943_e, "CSIBM943" }, + { false, iconv_CSIBM1008_e, "CSIBM1008" }, + { false, iconv_CSIBM1025_e, "CSIBM1025" }, + { false, iconv_CSIBM1026_e, "CSIBM1026" }, + { false, iconv_CSIBM1097_e, "CSIBM1097" }, + { false, iconv_CSIBM1112_e, "CSIBM1112" }, + { false, iconv_CSIBM1122_e, "CSIBM1122" }, + { false, iconv_CSIBM1123_e, "CSIBM1123" }, + { false, iconv_CSIBM1124_e, "CSIBM1124" }, + { false, iconv_CSIBM1129_e, "CSIBM1129" }, + { false, iconv_CSIBM1130_e, "CSIBM1130" }, + { false, iconv_CSIBM1132_e, "CSIBM1132" }, + { false, iconv_CSIBM1133_e, "CSIBM1133" }, + { false, iconv_CSIBM1137_e, "CSIBM1137" }, + { false, iconv_CSIBM1140_e, "CSIBM1140" }, + { false, iconv_CSIBM1141_e, "CSIBM1141" }, + { false, iconv_CSIBM1142_e, "CSIBM1142" }, + { false, iconv_CSIBM1143_e, "CSIBM1143" }, + { false, iconv_CSIBM1144_e, "CSIBM1144" }, + { false, iconv_CSIBM1145_e, "CSIBM1145" }, + { false, iconv_CSIBM1146_e, "CSIBM1146" }, + { false, iconv_CSIBM1147_e, "CSIBM1147" }, + { false, iconv_CSIBM1148_e, "CSIBM1148" }, + { false, iconv_CSIBM1149_e, "CSIBM1149" }, + { false, iconv_CSIBM1153_e, "CSIBM1153" }, + { false, iconv_CSIBM1154_e, "CSIBM1154" }, + { false, iconv_CSIBM1155_e, "CSIBM1155" }, + { false, iconv_CSIBM1156_e, "CSIBM1156" }, + { false, iconv_CSIBM1157_e, "CSIBM1157" }, + { false, iconv_CSIBM1158_e, "CSIBM1158" }, + { false, iconv_CSIBM1160_e, "CSIBM1160" }, + { false, iconv_CSIBM1161_e, "CSIBM1161" }, + { false, iconv_CSIBM1163_e, "CSIBM1163" }, + { false, iconv_CSIBM1164_e, "CSIBM1164" }, + { false, iconv_CSIBM1166_e, "CSIBM1166" }, + { false, iconv_CSIBM1167_e, "CSIBM1167" }, + { false, iconv_CSIBM1364_e, "CSIBM1364" }, + { false, iconv_CSIBM1371_e, "CSIBM1371" }, + { false, iconv_CSIBM1388_e, "CSIBM1388" }, + { false, iconv_CSIBM1390_e, "CSIBM1390" }, + { false, iconv_CSIBM1399_e, "CSIBM1399" }, + { false, iconv_CSIBM4517_e, "CSIBM4517" }, + { false, iconv_CSIBM4899_e, "CSIBM4899" }, + { false, iconv_CSIBM4909_e, "CSIBM4909" }, + { false, iconv_CSIBM4971_e, "CSIBM4971" }, + { false, iconv_CSIBM5347_e, "CSIBM5347" }, + { false, iconv_CSIBM9030_e, "CSIBM9030" }, + { false, iconv_CSIBM9066_e, "CSIBM9066" }, + { false, iconv_CSIBM9448_e, "CSIBM9448" }, + { false, iconv_CSIBM12712_e, "CSIBM12712" }, + { false, iconv_CSIBM16804_e, "CSIBM16804" }, + { false, iconv_CSIBM11621162_e, "CSIBM11621162" }, + { false, iconv_CSISO4UNITEDKINGDOM_e, "CSISO4UNITEDKINGDOM" }, + { false, iconv_CSISO10SWEDISH_e, "CSISO10SWEDISH" }, + { false, iconv_CSISO11SWEDISHFORNAMES_e, "CSISO11SWEDISHFORNAMES" }, + { false, iconv_CSISO14JISC6220RO_e, "CSISO14JISC6220RO" }, + { false, iconv_CSISO15ITALIAN_e, "CSISO15ITALIAN" }, + { false, iconv_CSISO16PORTUGESE_e, "CSISO16PORTUGESE" }, + { false, iconv_CSISO17SPANISH_e, "CSISO17SPANISH" }, + { false, iconv_CSISO18GREEK7OLD_e, "CSISO18GREEK7OLD" }, + { false, iconv_CSISO19LATINGREEK_e, "CSISO19LATINGREEK" }, + { false, iconv_CSISO21GERMAN_e, "CSISO21GERMAN" }, + { false, iconv_CSISO25FRENCH_e, "CSISO25FRENCH" }, + { false, iconv_CSISO27LATINGREEK1_e, "CSISO27LATINGREEK1" }, + { false, iconv_CSISO49INIS_e, "CSISO49INIS" }, + { false, iconv_CSISO50INIS8_e, "CSISO50INIS8" }, + { false, iconv_CSISO51INISCYRILLIC_e, "CSISO51INISCYRILLIC" }, + { false, iconv_CSISO58GB1988_e, "CSISO58GB1988" }, + { false, iconv_CSISO60DANISHNORWEGIAN_e, "CSISO60DANISHNORWEGIAN" }, + { false, iconv_CSISO60NORWEGIAN1_e, "CSISO60NORWEGIAN1" }, + { false, iconv_CSISO61NORWEGIAN2_e, "CSISO61NORWEGIAN2" }, + { false, iconv_CSISO69FRENCH_e, "CSISO69FRENCH" }, + { false, iconv_CSISO84PORTUGUESE2_e, "CSISO84PORTUGUESE2" }, + { false, iconv_CSISO85SPANISH2_e, "CSISO85SPANISH2" }, + { false, iconv_CSISO86HUNGARIAN_e, "CSISO86HUNGARIAN" }, + { false, iconv_CSISO88GREEK7_e, "CSISO88GREEK7" }, + { false, iconv_CSISO89ASMO449_e, "CSISO89ASMO449" }, + { false, iconv_CSISO90_e, "CSISO90" }, + { false, iconv_CSISO92JISC62991984B_e, "CSISO92JISC62991984B" }, + { false, iconv_CSISO99NAPLPS_e, "CSISO99NAPLPS" }, + { false, iconv_CSISO103T618BIT_e, "CSISO103T618BIT" }, + { false, iconv_CSISO111ECMACYRILLIC_e, "CSISO111ECMACYRILLIC" }, + { false, iconv_CSISO121CANADIAN1_e, "CSISO121CANADIAN1" }, + { false, iconv_CSISO122CANADIAN2_e, "CSISO122CANADIAN2" }, + { false, iconv_CSISO139CSN369103_e, "CSISO139CSN369103" }, + { false, iconv_CSISO141JUSIB1002_e, "CSISO141JUSIB1002" }, + { false, iconv_CSISO143IECP271_e, "CSISO143IECP271" }, + { false, iconv_CSISO150_e, "CSISO150" }, + { false, iconv_CSISO150GREEKCCITT_e, "CSISO150GREEKCCITT" }, + { false, iconv_CSISO151CUBA_e, "CSISO151CUBA" }, + { false, iconv_CSISO153GOST1976874_e, "CSISO153GOST1976874" }, + { false, iconv_CSISO646DANISH_e, "CSISO646DANISH" }, + { false, iconv_CSISO2022CN_e, "CSISO2022CN" }, + { false, iconv_CSISO2022JP_e, "CSISO2022JP" }, + { false, iconv_CSISO2022JP2_e, "CSISO2022JP2" }, + { false, iconv_CSISO2022KR_e, "CSISO2022KR" }, + { false, iconv_CSISO2033_e, "CSISO2033" }, + { false, iconv_CSISO5427CYRILLIC_e, "CSISO5427CYRILLIC" }, + { false, iconv_CSISO5427CYRILLIC1981_e, "CSISO5427CYRILLIC1981" }, + { false, iconv_CSISO5428GREEK_e, "CSISO5428GREEK" }, + { false, iconv_CSISO10367BOX_e, "CSISO10367BOX" }, + { false, iconv_CSISOLATIN1_e, "CSISOLATIN1" }, + { false, iconv_CSISOLATIN2_e, "CSISOLATIN2" }, + { false, iconv_CSISOLATIN3_e, "CSISOLATIN3" }, + { false, iconv_CSISOLATIN4_e, "CSISOLATIN4" }, + { false, iconv_CSISOLATIN5_e, "CSISOLATIN5" }, + { false, iconv_CSISOLATIN6_e, "CSISOLATIN6" }, + { false, iconv_CSISOLATINARABIC_e, "CSISOLATINARABIC" }, + { false, iconv_CSISOLATINCYRILLIC_e, "CSISOLATINCYRILLIC" }, + { false, iconv_CSISOLATINGREEK_e, "CSISOLATINGREEK" }, + { false, iconv_CSISOLATINHEBREW_e, "CSISOLATINHEBREW" }, + { false, iconv_CSKOI8R_e, "CSKOI8R" }, + { false, iconv_CSKSC5636_e, "CSKSC5636" }, + { false, iconv_CSMACINTOSH_e, "CSMACINTOSH" }, + { false, iconv_CSNATSDANO_e, "CSNATSDANO" }, + { false, iconv_CSNATSSEFI_e, "CSNATSSEFI" }, + { false, iconv_CSN_369103_e, "CSN_369103" }, + { false, iconv_CSPC8CODEPAGE437_e, "CSPC8CODEPAGE437" }, + { false, iconv_CSPC775BALTIC_e, "CSPC775BALTIC" }, + { false, iconv_CSPC850MULTILINGUAL_e, "CSPC850MULTILINGUAL" }, + { false, iconv_CSPC858MULTILINGUAL_e, "CSPC858MULTILINGUAL" }, + { false, iconv_CSPC862LATINHEBREW_e, "CSPC862LATINHEBREW" }, + { false, iconv_CSPCP852_e, "CSPCP852" }, + { false, iconv_CSSHIFTJIS_e, "CSSHIFTJIS" }, + { false, iconv_CSUCS4_e, "CSUCS4" }, + { false, iconv_CSUNICODE_e, "CSUNICODE" }, + { false, iconv_CSWINDOWS31J_e, "CSWINDOWS31J" }, + { false, iconv_CUBA_e, "CUBA" }, + { false, iconv_CWI_2_e, "CWI-2" }, + { false, iconv_CWI_e, "CWI" }, + { false, iconv_CYRILLIC_e, "CYRILLIC" }, + { false, iconv_DE_e, "DE" }, + { false, iconv_DEC_MCS_e, "DEC-MCS" }, + { false, iconv_DEC_e, "DEC" }, + { false, iconv_DECMCS_e, "DECMCS" }, + { false, iconv_DIN_66003_e, "DIN_66003" }, + { false, iconv_DK_e, "DK" }, + { false, iconv_DS2089_e, "DS2089" }, + { false, iconv_DS_2089_e, "DS_2089" }, + { false, iconv_E13B_e, "E13B" }, + { false, iconv_EBCDIC_AT_DE_A_e, "EBCDIC-AT-DE-A" }, + { false, iconv_EBCDIC_AT_DE_e, "EBCDIC-AT-DE" }, + { false, iconv_EBCDIC_BE_e, "EBCDIC-BE" }, + { false, iconv_EBCDIC_BR_e, "EBCDIC-BR" }, + { false, iconv_EBCDIC_CA_FR_e, "EBCDIC-CA-FR" }, + { false, iconv_EBCDIC_CP_AR1_e, "EBCDIC-CP-AR1" }, + { false, iconv_EBCDIC_CP_AR2_e, "EBCDIC-CP-AR2" }, + { false, iconv_EBCDIC_CP_BE_e, "EBCDIC-CP-BE" }, + { false, iconv_EBCDIC_CP_CA_e, "EBCDIC-CP-CA" }, + { false, iconv_EBCDIC_CP_CH_e, "EBCDIC-CP-CH" }, + { false, iconv_EBCDIC_CP_DK_e, "EBCDIC-CP-DK" }, + { false, iconv_EBCDIC_CP_ES_e, "EBCDIC-CP-ES" }, + { false, iconv_EBCDIC_CP_FI_e, "EBCDIC-CP-FI" }, + { false, iconv_EBCDIC_CP_FR_e, "EBCDIC-CP-FR" }, + { false, iconv_EBCDIC_CP_GB_e, "EBCDIC-CP-GB" }, + { false, iconv_EBCDIC_CP_GR_e, "EBCDIC-CP-GR" }, + { false, iconv_EBCDIC_CP_HE_e, "EBCDIC-CP-HE" }, + { false, iconv_EBCDIC_CP_IS_e, "EBCDIC-CP-IS" }, + { false, iconv_EBCDIC_CP_IT_e, "EBCDIC-CP-IT" }, + { false, iconv_EBCDIC_CP_NL_e, "EBCDIC-CP-NL" }, + { false, iconv_EBCDIC_CP_NO_e, "EBCDIC-CP-NO" }, + { false, iconv_EBCDIC_CP_ROECE_e, "EBCDIC-CP-ROECE" }, + { false, iconv_EBCDIC_CP_SE_e, "EBCDIC-CP-SE" }, + { false, iconv_EBCDIC_CP_TR_e, "EBCDIC-CP-TR" }, + { false, iconv_EBCDIC_CP_US_e, "EBCDIC-CP-US" }, + { false, iconv_EBCDIC_CP_WT_e, "EBCDIC-CP-WT" }, + { false, iconv_EBCDIC_CP_YU_e, "EBCDIC-CP-YU" }, + { false, iconv_EBCDIC_CYRILLIC_e, "EBCDIC-CYRILLIC" }, + { false, iconv_EBCDIC_DK_NO_A_e, "EBCDIC-DK-NO-A" }, + { false, iconv_EBCDIC_DK_NO_e, "EBCDIC-DK-NO" }, + { false, iconv_EBCDIC_ES_A_e, "EBCDIC-ES-A" }, + { false, iconv_EBCDIC_ES_S_e, "EBCDIC-ES-S" }, + { false, iconv_EBCDIC_ES_e, "EBCDIC-ES" }, + { false, iconv_EBCDIC_FI_SE_A_e, "EBCDIC-FI-SE-A" }, + { false, iconv_EBCDIC_FI_SE_e, "EBCDIC-FI-SE" }, + { false, iconv_EBCDIC_FR_e, "EBCDIC-FR" }, + { false, iconv_EBCDIC_GREEK_e, "EBCDIC-GREEK" }, + { false, iconv_EBCDIC_INT_e, "EBCDIC-INT" }, + { false, iconv_EBCDIC_INT1_e, "EBCDIC-INT1" }, + { false, iconv_EBCDIC_IS_FRISS_e, "EBCDIC-IS-FRISS" }, + { false, iconv_EBCDIC_IT_e, "EBCDIC-IT" }, + { false, iconv_EBCDIC_JP_E_e, "EBCDIC-JP-E" }, + { false, iconv_EBCDIC_JP_KANA_e, "EBCDIC-JP-KANA" }, + { false, iconv_EBCDIC_PT_e, "EBCDIC-PT" }, + { false, iconv_EBCDIC_UK_e, "EBCDIC-UK" }, + { false, iconv_EBCDIC_US_e, "EBCDIC-US" }, + { false, iconv_EBCDICATDE_e, "EBCDICATDE" }, + { false, iconv_EBCDICATDEA_e, "EBCDICATDEA" }, + { false, iconv_EBCDICCAFR_e, "EBCDICCAFR" }, + { false, iconv_EBCDICDKNO_e, "EBCDICDKNO" }, + { false, iconv_EBCDICDKNOA_e, "EBCDICDKNOA" }, + { false, iconv_EBCDICES_e, "EBCDICES" }, + { false, iconv_EBCDICESA_e, "EBCDICESA" }, + { false, iconv_EBCDICESS_e, "EBCDICESS" }, + { false, iconv_EBCDICFISE_e, "EBCDICFISE" }, + { false, iconv_EBCDICFISEA_e, "EBCDICFISEA" }, + { false, iconv_EBCDICFR_e, "EBCDICFR" }, + { false, iconv_EBCDICISFRISS_e, "EBCDICISFRISS" }, + { false, iconv_EBCDICIT_e, "EBCDICIT" }, + { false, iconv_EBCDICPT_e, "EBCDICPT" }, + { false, iconv_EBCDICUK_e, "EBCDICUK" }, + { false, iconv_EBCDICUS_e, "EBCDICUS" }, + { false, iconv_ECMA_114_e, "ECMA-114" }, + { false, iconv_ECMA_118_e, "ECMA-118" }, + { false, iconv_ECMA_128_e, "ECMA-128" }, + { false, iconv_ECMA_CYRILLIC_e, "ECMA-CYRILLIC" }, + { false, iconv_ECMACYRILLIC_e, "ECMACYRILLIC" }, + { false, iconv_ELOT_928_e, "ELOT_928" }, + { false, iconv_ES_e, "ES" }, + { false, iconv_ES2_e, "ES2" }, + { false, iconv_EUC_CN_e, "EUC-CN" }, + { false, iconv_EUC_JISX0213_e, "EUC-JISX0213" }, + { false, iconv_EUC_JP_MS_e, "EUC-JP-MS" }, + { false, iconv_EUC_JP_e, "EUC-JP" }, + { false, iconv_EUC_KR_e, "EUC-KR" }, + { false, iconv_EUC_TW_e, "EUC-TW" }, + { false, iconv_EUCCN_e, "EUCCN" }, + { false, iconv_EUCJP_MS_e, "EUCJP-MS" }, + { false, iconv_EUCJP_OPEN_e, "EUCJP-OPEN" }, + { false, iconv_EUCJP_WIN_e, "EUCJP-WIN" }, + { false, iconv_EUCJP_e, "EUCJP" }, + { false, iconv_EUCKR_e, "EUCKR" }, + { false, iconv_EUCTW_e, "EUCTW" }, + { false, iconv_FI_e, "FI" }, + { false, iconv_FR_e, "FR" }, + { false, iconv_GB_e, "GB" }, + { false, iconv_GB2312_e, "GB2312" }, + { false, iconv_GB13000_e, "GB13000" }, + { false, iconv_GB18030_e, "GB18030" }, + { false, iconv_GBK_e, "GBK" }, + { false, iconv_GB_1988_80_e, "GB_1988-80" }, + { false, iconv_GB_198880_e, "GB_198880" }, + { false, iconv_GEORGIAN_ACADEMY_e, "GEORGIAN-ACADEMY" }, + { false, iconv_GEORGIAN_PS_e, "GEORGIAN-PS" }, + { false, iconv_GOST_19768_74_e, "GOST_19768-74" }, + { false, iconv_GOST_19768_e, "GOST_19768" }, + { false, iconv_GOST_1976874_e, "GOST_1976874" }, + { false, iconv_GREEK_CCITT_e, "GREEK-CCITT" }, + { false, iconv_GREEK_e, "GREEK" }, + { false, iconv_GREEK7_OLD_e, "GREEK7-OLD" }, + { false, iconv_GREEK7_e, "GREEK7" }, + { false, iconv_GREEK7OLD_e, "GREEK7OLD" }, + { false, iconv_GREEK8_e, "GREEK8" }, + { false, iconv_GREEKCCITT_e, "GREEKCCITT" }, + { false, iconv_HEBREW_e, "HEBREW" }, + { false, iconv_HP_GREEK8_e, "HP-GREEK8" }, + { false, iconv_HP_ROMAN8_e, "HP-ROMAN8" }, + { false, iconv_HP_ROMAN9_e, "HP-ROMAN9" }, + { false, iconv_HP_THAI8_e, "HP-THAI8" }, + { false, iconv_HP_TURKISH8_e, "HP-TURKISH8" }, + { false, iconv_HPGREEK8_e, "HPGREEK8" }, + { false, iconv_HPROMAN8_e, "HPROMAN8" }, + { false, iconv_HPROMAN9_e, "HPROMAN9" }, + { false, iconv_HPTHAI8_e, "HPTHAI8" }, + { false, iconv_HPTURKISH8_e, "HPTURKISH8" }, + { false, iconv_HU_e, "HU" }, + { false, iconv_IBM_803_e, "IBM-803" }, + { false, iconv_IBM_856_e, "IBM-856" }, + { false, iconv_IBM_901_e, "IBM-901" }, + { false, iconv_IBM_902_e, "IBM-902" }, + { false, iconv_IBM_921_e, "IBM-921" }, + { false, iconv_IBM_922_e, "IBM-922" }, + { false, iconv_IBM_930_e, "IBM-930" }, + { false, iconv_IBM_932_e, "IBM-932" }, + { false, iconv_IBM_933_e, "IBM-933" }, + { false, iconv_IBM_935_e, "IBM-935" }, + { false, iconv_IBM_937_e, "IBM-937" }, + { false, iconv_IBM_939_e, "IBM-939" }, + { false, iconv_IBM_943_e, "IBM-943" }, + { false, iconv_IBM_1008_e, "IBM-1008" }, + { false, iconv_IBM_1025_e, "IBM-1025" }, + { false, iconv_IBM_1046_e, "IBM-1046" }, + { false, iconv_IBM_1047_e, "IBM-1047" }, + { false, iconv_IBM_1097_e, "IBM-1097" }, + { false, iconv_IBM_1112_e, "IBM-1112" }, + { false, iconv_IBM_1122_e, "IBM-1122" }, + { false, iconv_IBM_1123_e, "IBM-1123" }, + { false, iconv_IBM_1124_e, "IBM-1124" }, + { false, iconv_IBM_1129_e, "IBM-1129" }, + { false, iconv_IBM_1130_e, "IBM-1130" }, + { false, iconv_IBM_1132_e, "IBM-1132" }, + { false, iconv_IBM_1133_e, "IBM-1133" }, + { false, iconv_IBM_1137_e, "IBM-1137" }, + { false, iconv_IBM_1140_e, "IBM-1140" }, + { false, iconv_IBM_1141_e, "IBM-1141" }, + { false, iconv_IBM_1142_e, "IBM-1142" }, + { false, iconv_IBM_1143_e, "IBM-1143" }, + { false, iconv_IBM_1144_e, "IBM-1144" }, + { false, iconv_IBM_1145_e, "IBM-1145" }, + { false, iconv_IBM_1146_e, "IBM-1146" }, + { false, iconv_IBM_1147_e, "IBM-1147" }, + { false, iconv_IBM_1148_e, "IBM-1148" }, + { false, iconv_IBM_1149_e, "IBM-1149" }, + { false, iconv_IBM_1153_e, "IBM-1153" }, + { false, iconv_IBM_1154_e, "IBM-1154" }, + { false, iconv_IBM_1155_e, "IBM-1155" }, + { false, iconv_IBM_1156_e, "IBM-1156" }, + { false, iconv_IBM_1157_e, "IBM-1157" }, + { false, iconv_IBM_1158_e, "IBM-1158" }, + { false, iconv_IBM_1160_e, "IBM-1160" }, + { false, iconv_IBM_1161_e, "IBM-1161" }, + { false, iconv_IBM_1162_e, "IBM-1162" }, + { false, iconv_IBM_1163_e, "IBM-1163" }, + { false, iconv_IBM_1164_e, "IBM-1164" }, + { false, iconv_IBM_1166_e, "IBM-1166" }, + { false, iconv_IBM_1167_e, "IBM-1167" }, + { false, iconv_IBM_1364_e, "IBM-1364" }, + { false, iconv_IBM_1371_e, "IBM-1371" }, + { false, iconv_IBM_1388_e, "IBM-1388" }, + { false, iconv_IBM_1390_e, "IBM-1390" }, + { false, iconv_IBM_1399_e, "IBM-1399" }, + { false, iconv_IBM_4517_e, "IBM-4517" }, + { false, iconv_IBM_4899_e, "IBM-4899" }, + { false, iconv_IBM_4909_e, "IBM-4909" }, + { false, iconv_IBM_4971_e, "IBM-4971" }, + { false, iconv_IBM_5347_e, "IBM-5347" }, + { false, iconv_IBM_9030_e, "IBM-9030" }, + { false, iconv_IBM_9066_e, "IBM-9066" }, + { false, iconv_IBM_9448_e, "IBM-9448" }, + { false, iconv_IBM_12712_e, "IBM-12712" }, + { false, iconv_IBM_16804_e, "IBM-16804" }, + { false, iconv_IBM037_e, "IBM037" }, + { false, iconv_IBM038_e, "IBM038" }, + { false, iconv_IBM256_e, "IBM256" }, + { false, iconv_IBM273_e, "IBM273" }, + { false, iconv_IBM274_e, "IBM274" }, + { false, iconv_IBM275_e, "IBM275" }, + { false, iconv_IBM277_e, "IBM277" }, + { false, iconv_IBM278_e, "IBM278" }, + { false, iconv_IBM280_e, "IBM280" }, + { false, iconv_IBM281_e, "IBM281" }, + { false, iconv_IBM284_e, "IBM284" }, + { false, iconv_IBM285_e, "IBM285" }, + { false, iconv_IBM290_e, "IBM290" }, + { false, iconv_IBM297_e, "IBM297" }, + { false, iconv_IBM367_e, "IBM367" }, + { false, iconv_IBM420_e, "IBM420" }, + { false, iconv_IBM423_e, "IBM423" }, + { false, iconv_IBM424_e, "IBM424" }, + { false, iconv_IBM437_e, "IBM437" }, + { false, iconv_IBM500_e, "IBM500" }, + { false, iconv_IBM775_e, "IBM775" }, + { false, iconv_IBM803_e, "IBM803" }, + { false, iconv_IBM813_e, "IBM813" }, + { false, iconv_IBM819_e, "IBM819" }, + { false, iconv_IBM848_e, "IBM848" }, + { false, iconv_IBM850_e, "IBM850" }, + { false, iconv_IBM851_e, "IBM851" }, + { false, iconv_IBM852_e, "IBM852" }, + { false, iconv_IBM855_e, "IBM855" }, + { false, iconv_IBM856_e, "IBM856" }, + { false, iconv_IBM857_e, "IBM857" }, + { false, iconv_IBM858_e, "IBM858" }, + { false, iconv_IBM860_e, "IBM860" }, + { false, iconv_IBM861_e, "IBM861" }, + { false, iconv_IBM862_e, "IBM862" }, + { false, iconv_IBM863_e, "IBM863" }, + { false, iconv_IBM864_e, "IBM864" }, + { false, iconv_IBM865_e, "IBM865" }, + { false, iconv_IBM866_e, "IBM866" }, + { false, iconv_IBM866NAV_e, "IBM866NAV" }, + { false, iconv_IBM868_e, "IBM868" }, + { false, iconv_IBM869_e, "IBM869" }, + { false, iconv_IBM870_e, "IBM870" }, + { false, iconv_IBM871_e, "IBM871" }, + { false, iconv_IBM874_e, "IBM874" }, + { false, iconv_IBM875_e, "IBM875" }, + { false, iconv_IBM880_e, "IBM880" }, + { false, iconv_IBM891_e, "IBM891" }, + { false, iconv_IBM901_e, "IBM901" }, + { false, iconv_IBM902_e, "IBM902" }, + { false, iconv_IBM903_e, "IBM903" }, + { false, iconv_IBM904_e, "IBM904" }, + { false, iconv_IBM905_e, "IBM905" }, + { false, iconv_IBM912_e, "IBM912" }, + { false, iconv_IBM915_e, "IBM915" }, + { false, iconv_IBM916_e, "IBM916" }, + { false, iconv_IBM918_e, "IBM918" }, + { false, iconv_IBM920_e, "IBM920" }, + { false, iconv_IBM921_e, "IBM921" }, + { false, iconv_IBM922_e, "IBM922" }, + { false, iconv_IBM930_e, "IBM930" }, + { false, iconv_IBM932_e, "IBM932" }, + { false, iconv_IBM933_e, "IBM933" }, + { false, iconv_IBM935_e, "IBM935" }, + { false, iconv_IBM937_e, "IBM937" }, + { false, iconv_IBM939_e, "IBM939" }, + { false, iconv_IBM943_e, "IBM943" }, + { false, iconv_IBM1004_e, "IBM1004" }, + { false, iconv_IBM1008_e, "IBM1008" }, + { false, iconv_IBM1025_e, "IBM1025" }, + { false, iconv_IBM1026_e, "IBM1026" }, + { false, iconv_IBM1046_e, "IBM1046" }, + { false, iconv_IBM1047_e, "IBM1047" }, + { false, iconv_IBM1089_e, "IBM1089" }, + { false, iconv_IBM1097_e, "IBM1097" }, + { false, iconv_IBM1112_e, "IBM1112" }, + { false, iconv_IBM1122_e, "IBM1122" }, + { false, iconv_IBM1123_e, "IBM1123" }, + { false, iconv_IBM1124_e, "IBM1124" }, + { false, iconv_IBM1129_e, "IBM1129" }, + { false, iconv_IBM1130_e, "IBM1130" }, + { false, iconv_IBM1132_e, "IBM1132" }, + { false, iconv_IBM1133_e, "IBM1133" }, + { false, iconv_IBM1137_e, "IBM1137" }, + { false, iconv_IBM1140_e, "IBM1140" }, + { false, iconv_IBM1141_e, "IBM1141" }, + { false, iconv_IBM1142_e, "IBM1142" }, + { false, iconv_IBM1143_e, "IBM1143" }, + { false, iconv_IBM1144_e, "IBM1144" }, + { false, iconv_IBM1145_e, "IBM1145" }, + { false, iconv_IBM1146_e, "IBM1146" }, + { false, iconv_IBM1147_e, "IBM1147" }, + { false, iconv_IBM1148_e, "IBM1148" }, + { false, iconv_IBM1149_e, "IBM1149" }, + { false, iconv_IBM1153_e, "IBM1153" }, + { false, iconv_IBM1154_e, "IBM1154" }, + { false, iconv_IBM1155_e, "IBM1155" }, + { false, iconv_IBM1156_e, "IBM1156" }, + { false, iconv_IBM1157_e, "IBM1157" }, + { false, iconv_IBM1158_e, "IBM1158" }, + { false, iconv_IBM1160_e, "IBM1160" }, + { false, iconv_IBM1161_e, "IBM1161" }, + { false, iconv_IBM1162_e, "IBM1162" }, + { false, iconv_IBM1163_e, "IBM1163" }, + { false, iconv_IBM1164_e, "IBM1164" }, + { false, iconv_IBM1166_e, "IBM1166" }, + { false, iconv_IBM1167_e, "IBM1167" }, + { false, iconv_IBM1364_e, "IBM1364" }, + { false, iconv_IBM1371_e, "IBM1371" }, + { false, iconv_IBM1388_e, "IBM1388" }, + { false, iconv_IBM1390_e, "IBM1390" }, + { false, iconv_IBM1399_e, "IBM1399" }, + { false, iconv_IBM4517_e, "IBM4517" }, + { false, iconv_IBM4899_e, "IBM4899" }, + { false, iconv_IBM4909_e, "IBM4909" }, + { false, iconv_IBM4971_e, "IBM4971" }, + { false, iconv_IBM5347_e, "IBM5347" }, + { false, iconv_IBM9030_e, "IBM9030" }, + { false, iconv_IBM9066_e, "IBM9066" }, + { false, iconv_IBM9448_e, "IBM9448" }, + { false, iconv_IBM12712_e, "IBM12712" }, + { false, iconv_IBM16804_e, "IBM16804" }, + { false, iconv_IEC_P27_1_e, "IEC_P27-1" }, + { false, iconv_IEC_P271_e, "IEC_P271" }, + { false, iconv_INIS_8_e, "INIS-8" }, + { false, iconv_INIS_CYRILLIC_e, "INIS-CYRILLIC" }, + { false, iconv_INIS_e, "INIS" }, + { false, iconv_INIS8_e, "INIS8" }, + { false, iconv_INISCYRILLIC_e, "INISCYRILLIC" }, + { false, iconv_ISIRI_3342_e, "ISIRI-3342" }, + { false, iconv_ISIRI3342_e, "ISIRI3342" }, + { false, iconv_ISO_2022_CN_EXT_e, "ISO-2022-CN-EXT" }, + { false, iconv_ISO_2022_CN_e, "ISO-2022-CN" }, + { false, iconv_ISO_2022_JP_2_e, "ISO-2022-JP-2" }, + { false, iconv_ISO_2022_JP_3_e, "ISO-2022-JP-3" }, + { false, iconv_ISO_2022_JP_e, "ISO-2022-JP" }, + { false, iconv_ISO_2022_KR_e, "ISO-2022-KR" }, + { false, iconv_ISO_8859_1_e, "ISO-8859-1" }, + { false, iconv_ISO_8859_2_e, "ISO-8859-2" }, + { false, iconv_ISO_8859_3_e, "ISO-8859-3" }, + { false, iconv_ISO_8859_4_e, "ISO-8859-4" }, + { false, iconv_ISO_8859_5_e, "ISO-8859-5" }, + { false, iconv_ISO_8859_6_e, "ISO-8859-6" }, + { false, iconv_ISO_8859_7_e, "ISO-8859-7" }, + { false, iconv_ISO_8859_8_e, "ISO-8859-8" }, + { false, iconv_ISO_8859_9_e, "ISO-8859-9" }, + { false, iconv_ISO_8859_9E_e, "ISO-8859-9E" }, + { false, iconv_ISO_8859_10_e, "ISO-8859-10" }, + { false, iconv_ISO_8859_11_e, "ISO-8859-11" }, + { false, iconv_ISO_8859_13_e, "ISO-8859-13" }, + { false, iconv_ISO_8859_14_e, "ISO-8859-14" }, + { false, iconv_ISO_8859_15_e, "ISO-8859-15" }, + { false, iconv_ISO_8859_16_e, "ISO-8859-16" }, + { true, iconv_ISO_10646_e, "ISO-10646" }, + { true, iconv_ISO_10646_e, "UCS2/ ISO-10646/UCS2/" }, + { true, iconv_ISO_10646_e, "UCS4/ ISO-10646/UCS4/" }, + { true, iconv_ISO_10646_e, "UTF-8/ ISO-10646/UTF-8/" }, + { true, iconv_ISO_10646_e, "UTF8/ ISO-10646/UTF8/" }, + { false, iconv_ISO_CELTIC_e, "ISO-CELTIC" }, + { false, iconv_ISO_IR_4_e, "ISO-IR-4" }, + { false, iconv_ISO_IR_6_e, "ISO-IR-6" }, + { false, iconv_ISO_IR_8_1_e, "ISO-IR-8-1" }, + { false, iconv_ISO_IR_9_1_e, "ISO-IR-9-1" }, + { false, iconv_ISO_IR_10_e, "ISO-IR-10" }, + { false, iconv_ISO_IR_11_e, "ISO-IR-11" }, + { false, iconv_ISO_IR_14_e, "ISO-IR-14" }, + { false, iconv_ISO_IR_15_e, "ISO-IR-15" }, + { false, iconv_ISO_IR_16_e, "ISO-IR-16" }, + { false, iconv_ISO_IR_17_e, "ISO-IR-17" }, + { false, iconv_ISO_IR_18_e, "ISO-IR-18" }, + { false, iconv_ISO_IR_19_e, "ISO-IR-19" }, + { false, iconv_ISO_IR_21_e, "ISO-IR-21" }, + { false, iconv_ISO_IR_25_e, "ISO-IR-25" }, + { false, iconv_ISO_IR_27_e, "ISO-IR-27" }, + { false, iconv_ISO_IR_37_e, "ISO-IR-37" }, + { false, iconv_ISO_IR_49_e, "ISO-IR-49" }, + { false, iconv_ISO_IR_50_e, "ISO-IR-50" }, + { false, iconv_ISO_IR_51_e, "ISO-IR-51" }, + { false, iconv_ISO_IR_54_e, "ISO-IR-54" }, + { false, iconv_ISO_IR_55_e, "ISO-IR-55" }, + { false, iconv_ISO_IR_57_e, "ISO-IR-57" }, + { false, iconv_ISO_IR_60_e, "ISO-IR-60" }, + { false, iconv_ISO_IR_61_e, "ISO-IR-61" }, + { false, iconv_ISO_IR_69_e, "ISO-IR-69" }, + { false, iconv_ISO_IR_84_e, "ISO-IR-84" }, + { false, iconv_ISO_IR_85_e, "ISO-IR-85" }, + { false, iconv_ISO_IR_86_e, "ISO-IR-86" }, + { false, iconv_ISO_IR_88_e, "ISO-IR-88" }, + { false, iconv_ISO_IR_89_e, "ISO-IR-89" }, + { false, iconv_ISO_IR_90_e, "ISO-IR-90" }, + { false, iconv_ISO_IR_92_e, "ISO-IR-92" }, + { false, iconv_ISO_IR_98_e, "ISO-IR-98" }, + { false, iconv_ISO_IR_99_e, "ISO-IR-99" }, + { false, iconv_ISO_IR_100_e, "ISO-IR-100" }, + { false, iconv_ISO_IR_101_e, "ISO-IR-101" }, + { false, iconv_ISO_IR_103_e, "ISO-IR-103" }, + { false, iconv_ISO_IR_109_e, "ISO-IR-109" }, + { false, iconv_ISO_IR_110_e, "ISO-IR-110" }, + { false, iconv_ISO_IR_111_e, "ISO-IR-111" }, + { false, iconv_ISO_IR_121_e, "ISO-IR-121" }, + { false, iconv_ISO_IR_122_e, "ISO-IR-122" }, + { false, iconv_ISO_IR_126_e, "ISO-IR-126" }, + { false, iconv_ISO_IR_127_e, "ISO-IR-127" }, + { false, iconv_ISO_IR_138_e, "ISO-IR-138" }, + { false, iconv_ISO_IR_139_e, "ISO-IR-139" }, + { false, iconv_ISO_IR_141_e, "ISO-IR-141" }, + { false, iconv_ISO_IR_143_e, "ISO-IR-143" }, + { false, iconv_ISO_IR_144_e, "ISO-IR-144" }, + { false, iconv_ISO_IR_148_e, "ISO-IR-148" }, + { false, iconv_ISO_IR_150_e, "ISO-IR-150" }, + { false, iconv_ISO_IR_151_e, "ISO-IR-151" }, + { false, iconv_ISO_IR_153_e, "ISO-IR-153" }, + { false, iconv_ISO_IR_155_e, "ISO-IR-155" }, + { false, iconv_ISO_IR_156_e, "ISO-IR-156" }, + { false, iconv_ISO_IR_157_e, "ISO-IR-157" }, + { false, iconv_ISO_IR_166_e, "ISO-IR-166" }, + { false, iconv_ISO_IR_179_e, "ISO-IR-179" }, + { false, iconv_ISO_IR_193_e, "ISO-IR-193" }, + { false, iconv_ISO_IR_197_e, "ISO-IR-197" }, + { false, iconv_ISO_IR_199_e, "ISO-IR-199" }, + { false, iconv_ISO_IR_203_e, "ISO-IR-203" }, + { false, iconv_ISO_IR_209_e, "ISO-IR-209" }, + { false, iconv_ISO_IR_226_e, "ISO-IR-226" }, + { false, iconv_ISO_e, "TR_11548-1/ ISO/TR_11548-1/" }, + { false, iconv_ISO646_CA_e, "ISO646-CA" }, + { false, iconv_ISO646_CA2_e, "ISO646-CA2" }, + { false, iconv_ISO646_CN_e, "ISO646-CN" }, + { false, iconv_ISO646_CU_e, "ISO646-CU" }, + { false, iconv_ISO646_DE_e, "ISO646-DE" }, + { false, iconv_ISO646_DK_e, "ISO646-DK" }, + { false, iconv_ISO646_ES_e, "ISO646-ES" }, + { false, iconv_ISO646_ES2_e, "ISO646-ES2" }, + { false, iconv_ISO646_FI_e, "ISO646-FI" }, + { false, iconv_ISO646_FR_e, "ISO646-FR" }, + { false, iconv_ISO646_FR1_e, "ISO646-FR1" }, + { false, iconv_ISO646_GB_e, "ISO646-GB" }, + { false, iconv_ISO646_HU_e, "ISO646-HU" }, + { false, iconv_ISO646_IT_e, "ISO646-IT" }, + { false, iconv_ISO646_JP_OCR_B_e, "ISO646-JP-OCR-B" }, + { false, iconv_ISO646_JP_e, "ISO646-JP" }, + { false, iconv_ISO646_KR_e, "ISO646-KR" }, + { false, iconv_ISO646_NO_e, "ISO646-NO" }, + { false, iconv_ISO646_NO2_e, "ISO646-NO2" }, + { false, iconv_ISO646_PT_e, "ISO646-PT" }, + { false, iconv_ISO646_PT2_e, "ISO646-PT2" }, + { false, iconv_ISO646_SE_e, "ISO646-SE" }, + { false, iconv_ISO646_SE2_e, "ISO646-SE2" }, + { false, iconv_ISO646_US_e, "ISO646-US" }, + { false, iconv_ISO646_YU_e, "ISO646-YU" }, + { false, iconv_ISO2022CN_e, "ISO2022CN" }, + { false, iconv_ISO2022CNEXT_e, "ISO2022CNEXT" }, + { false, iconv_ISO2022JP_e, "ISO2022JP" }, + { false, iconv_ISO2022JP2_e, "ISO2022JP2" }, + { false, iconv_ISO2022KR_e, "ISO2022KR" }, + { false, iconv_ISO6937_e, "ISO6937" }, + { false, iconv_ISO8859_1_e, "ISO8859-1" }, + { false, iconv_ISO8859_2_e, "ISO8859-2" }, + { false, iconv_ISO8859_3_e, "ISO8859-3" }, + { false, iconv_ISO8859_4_e, "ISO8859-4" }, + { false, iconv_ISO8859_5_e, "ISO8859-5" }, + { false, iconv_ISO8859_6_e, "ISO8859-6" }, + { false, iconv_ISO8859_7_e, "ISO8859-7" }, + { false, iconv_ISO8859_8_e, "ISO8859-8" }, + { false, iconv_ISO8859_9_e, "ISO8859-9" }, + { false, iconv_ISO8859_9E_e, "ISO8859-9E" }, + { false, iconv_ISO8859_10_e, "ISO8859-10" }, + { false, iconv_ISO8859_11_e, "ISO8859-11" }, + { false, iconv_ISO8859_13_e, "ISO8859-13" }, + { false, iconv_ISO8859_14_e, "ISO8859-14" }, + { false, iconv_ISO8859_15_e, "ISO8859-15" }, + { false, iconv_ISO8859_16_e, "ISO8859-16" }, + { false, iconv_ISO11548_1_e, "ISO11548-1" }, + { false, iconv_ISO88591_e, "ISO88591" }, + { false, iconv_ISO88592_e, "ISO88592" }, + { false, iconv_ISO88593_e, "ISO88593" }, + { false, iconv_ISO88594_e, "ISO88594" }, + { false, iconv_ISO88595_e, "ISO88595" }, + { false, iconv_ISO88596_e, "ISO88596" }, + { false, iconv_ISO88597_e, "ISO88597" }, + { false, iconv_ISO88598_e, "ISO88598" }, + { false, iconv_ISO88599_e, "ISO88599" }, + { false, iconv_ISO88599E_e, "ISO88599E" }, + { false, iconv_ISO885910_e, "ISO885910" }, + { false, iconv_ISO885911_e, "ISO885911" }, + { false, iconv_ISO885913_e, "ISO885913" }, + { false, iconv_ISO885914_e, "ISO885914" }, + { false, iconv_ISO885915_e, "ISO885915" }, + { false, iconv_ISO885916_e, "ISO885916" }, + { false, iconv_ISO_646_IRV_1991_e, "ISO_646.IRV:1991" }, + { false, iconv_ISO_2033_1983_e, "ISO_2033-1983" }, + { false, iconv_ISO_2033_e, "ISO_2033" }, + { false, iconv_ISO_5427_EXT_e, "ISO_5427-EXT" }, + { false, iconv_ISO_5427_e, "ISO_5427" }, + { false, iconv_ISO_5427_1981_e, "ISO_5427:1981" }, + { false, iconv_ISO_5427EXT_e, "ISO_5427EXT" }, + { false, iconv_ISO_5428_e, "ISO_5428" }, + { false, iconv_ISO_5428_1980_e, "ISO_5428:1980" }, + { false, iconv_ISO_6937_2_e, "ISO_6937-2" }, + { false, iconv_ISO_6937_2_1983_e, "ISO_6937-2:1983" }, + { false, iconv_ISO_6937_e, "ISO_6937" }, + { false, iconv_ISO_6937_1992_e, "ISO_6937:1992" }, + { false, iconv_ISO_8859_1_e, "ISO_8859-1" }, + { false, iconv_ISO_8859_1_1987_e, "ISO_8859-1:1987" }, + { false, iconv_ISO_8859_2_e, "ISO_8859-2" }, + { false, iconv_ISO_8859_2_1987_e, "ISO_8859-2:1987" }, + { false, iconv_ISO_8859_3_e, "ISO_8859-3" }, + { false, iconv_ISO_8859_3_1988_e, "ISO_8859-3:1988" }, + { false, iconv_ISO_8859_4_e, "ISO_8859-4" }, + { false, iconv_ISO_8859_4_1988_e, "ISO_8859-4:1988" }, + { false, iconv_ISO_8859_5_e, "ISO_8859-5" }, + { false, iconv_ISO_8859_5_1988_e, "ISO_8859-5:1988" }, + { false, iconv_ISO_8859_6_e, "ISO_8859-6" }, + { false, iconv_ISO_8859_6_1987_e, "ISO_8859-6:1987" }, + { false, iconv_ISO_8859_7_e, "ISO_8859-7" }, + { false, iconv_ISO_8859_7_1987_e, "ISO_8859-7:1987" }, + { false, iconv_ISO_8859_7_2003_e, "ISO_8859-7:2003" }, + { false, iconv_ISO_8859_8_e, "ISO_8859-8" }, + { false, iconv_ISO_8859_8_1988_e, "ISO_8859-8:1988" }, + { false, iconv_ISO_8859_9_e, "ISO_8859-9" }, + { false, iconv_ISO_8859_9_1989_e, "ISO_8859-9:1989" }, + { false, iconv_ISO_8859_9E_e, "ISO_8859-9E" }, + { false, iconv_ISO_8859_10_e, "ISO_8859-10" }, + { false, iconv_ISO_8859_10_1992_e, "ISO_8859-10:1992" }, + { false, iconv_ISO_8859_14_e, "ISO_8859-14" }, + { false, iconv_ISO_8859_14_1998_e, "ISO_8859-14:1998" }, + { false, iconv_ISO_8859_15_e, "ISO_8859-15" }, + { false, iconv_ISO_8859_15_1998_e, "ISO_8859-15:1998" }, + { false, iconv_ISO_8859_16_e, "ISO_8859-16" }, + { false, iconv_ISO_8859_16_2001_e, "ISO_8859-16:2001" }, + { false, iconv_ISO_9036_e, "ISO_9036" }, + { false, iconv_ISO_10367_BOX_e, "ISO_10367-BOX" }, + { false, iconv_ISO_10367BOX_e, "ISO_10367BOX" }, + { false, iconv_ISO_11548_1_e, "ISO_11548-1" }, + { false, iconv_ISO_69372_e, "ISO_69372" }, + { false, iconv_IT_e, "IT" }, + { false, iconv_JIS_C6220_1969_RO_e, "JIS_C6220-1969-RO" }, + { false, iconv_JIS_C6229_1984_B_e, "JIS_C6229-1984-B" }, + { false, iconv_JIS_C62201969RO_e, "JIS_C62201969RO" }, + { false, iconv_JIS_C62291984B_e, "JIS_C62291984B" }, + { false, iconv_JOHAB_e, "JOHAB" }, + { false, iconv_JP_OCR_B_e, "JP-OCR-B" }, + { false, iconv_JP_e, "JP" }, + { false, iconv_JS_e, "JS" }, + { false, iconv_JUS_I_B1_002_e, "JUS_I.B1.002" }, + { false, iconv_KOI_7_e, "KOI-7" }, + { false, iconv_KOI_8_e, "KOI-8" }, + { false, iconv_KOI8_R_e, "KOI8-R" }, + { false, iconv_KOI8_RU_e, "KOI8-RU" }, + { false, iconv_KOI8_T_e, "KOI8-T" }, + { false, iconv_KOI8_U_e, "KOI8-U" }, + { false, iconv_KOI8_e, "KOI8" }, + { false, iconv_KOI8R_e, "KOI8R" }, + { false, iconv_KOI8U_e, "KOI8U" }, + { false, iconv_KSC5636_e, "KSC5636" }, + { false, iconv_L1_e, "L1" }, + { false, iconv_L2_e, "L2" }, + { false, iconv_L3_e, "L3" }, + { false, iconv_L4_e, "L4" }, + { false, iconv_L5_e, "L5" }, + { false, iconv_L6_e, "L6" }, + { false, iconv_L7_e, "L7" }, + { false, iconv_L8_e, "L8" }, + { false, iconv_L10_e, "L10" }, + { false, iconv_LATIN_9_e, "LATIN-9" }, + { false, iconv_LATIN_GREEK_1_e, "LATIN-GREEK-1" }, + { false, iconv_LATIN_GREEK_e, "LATIN-GREEK" }, + { false, iconv_LATIN1_e, "LATIN1" }, + { false, iconv_LATIN2_e, "LATIN2" }, + { false, iconv_LATIN3_e, "LATIN3" }, + { false, iconv_LATIN4_e, "LATIN4" }, + { false, iconv_LATIN5_e, "LATIN5" }, + { false, iconv_LATIN6_e, "LATIN6" }, + { false, iconv_LATIN7_e, "LATIN7" }, + { false, iconv_LATIN8_e, "LATIN8" }, + { false, iconv_LATIN9_e, "LATIN9" }, + { false, iconv_LATIN10_e, "LATIN10" }, + { false, iconv_LATINGREEK_e, "LATINGREEK" }, + { false, iconv_LATINGREEK1_e, "LATINGREEK1" }, + { false, iconv_MAC_CENTRALEUROPE_e, "MAC-CENTRALEUROPE" }, + { false, iconv_MAC_CYRILLIC_e, "MAC-CYRILLIC" }, + { false, iconv_MAC_IS_e, "MAC-IS" }, + { false, iconv_MAC_SAMI_e, "MAC-SAMI" }, + { false, iconv_MAC_UK_e, "MAC-UK" }, + { false, iconv_MAC_e, "MAC" }, + { false, iconv_MACCYRILLIC_e, "MACCYRILLIC" }, + { false, iconv_MACINTOSH_e, "MACINTOSH" }, + { false, iconv_MACIS_e, "MACIS" }, + { false, iconv_MACUK_e, "MACUK" }, + { false, iconv_MACUKRAINIAN_e, "MACUKRAINIAN" }, + { false, iconv_MIK_e, "MIK" }, + { false, iconv_MS_ANSI_e, "MS-ANSI" }, + { false, iconv_MS_ARAB_e, "MS-ARAB" }, + { false, iconv_MS_CYRL_e, "MS-CYRL" }, + { false, iconv_MS_EE_e, "MS-EE" }, + { false, iconv_MS_GREEK_e, "MS-GREEK" }, + { false, iconv_MS_HEBR_e, "MS-HEBR" }, + { false, iconv_MS_MAC_CYRILLIC_e, "MS-MAC-CYRILLIC" }, + { false, iconv_MS_TURK_e, "MS-TURK" }, + { false, iconv_MS932_e, "MS932" }, + { false, iconv_MS936_e, "MS936" }, + { false, iconv_MSCP949_e, "MSCP949" }, + { false, iconv_MSCP1361_e, "MSCP1361" }, + { false, iconv_MSMACCYRILLIC_e, "MSMACCYRILLIC" }, + { false, iconv_MSZ_7795_3_e, "MSZ_7795.3" }, + { false, iconv_MS_KANJI_e, "MS_KANJI" }, + { false, iconv_NAPLPS_e, "NAPLPS" }, + { false, iconv_NATS_DANO_e, "NATS-DANO" }, + { false, iconv_NATS_SEFI_e, "NATS-SEFI" }, + { false, iconv_NATSDANO_e, "NATSDANO" }, + { false, iconv_NATSSEFI_e, "NATSSEFI" }, + { false, iconv_NC_NC0010_e, "NC_NC0010" }, + { false, iconv_NC_NC00_10_e, "NC_NC00-10" }, + { false, iconv_NC_NC00_10_81_e, "NC_NC00-10:81" }, + { false, iconv_NF_Z_62_010_e, "NF_Z_62-010" }, + { false, iconv_NF_Z_62_010__1973__e, "NF_Z_62-010_(1973)" }, + { false, iconv_NF_Z_62_010_1973_e, "NF_Z_62-010_1973" }, + { false, iconv_NF_Z_62010_e, "NF_Z_62010" }, + { false, iconv_NF_Z_62010_1973_e, "NF_Z_62010_1973" }, + { false, iconv_NO_e, "NO" }, + { false, iconv_NO2_e, "NO2" }, + { false, iconv_NS_4551_1_e, "NS_4551-1" }, + { false, iconv_NS_4551_2_e, "NS_4551-2" }, + { false, iconv_NS_45511_e, "NS_45511" }, + { false, iconv_NS_45512_e, "NS_45512" }, + { false, iconv_OS2LATIN1_e, "OS2LATIN1" }, + { false, iconv_OSF00010001_e, "OSF00010001" }, + { false, iconv_OSF00010002_e, "OSF00010002" }, + { false, iconv_OSF00010003_e, "OSF00010003" }, + { false, iconv_OSF00010004_e, "OSF00010004" }, + { false, iconv_OSF00010005_e, "OSF00010005" }, + { false, iconv_OSF00010006_e, "OSF00010006" }, + { false, iconv_OSF00010007_e, "OSF00010007" }, + { false, iconv_OSF00010008_e, "OSF00010008" }, + { false, iconv_OSF00010009_e, "OSF00010009" }, + { false, iconv_OSF0001000A_e, "OSF0001000A" }, + { false, iconv_OSF00010020_e, "OSF00010020" }, + { false, iconv_OSF00010100_e, "OSF00010100" }, + { false, iconv_OSF00010101_e, "OSF00010101" }, + { false, iconv_OSF00010102_e, "OSF00010102" }, + { false, iconv_OSF00010104_e, "OSF00010104" }, + { false, iconv_OSF00010105_e, "OSF00010105" }, + { false, iconv_OSF00010106_e, "OSF00010106" }, + { false, iconv_OSF00030010_e, "OSF00030010" }, + { false, iconv_OSF0004000A_e, "OSF0004000A" }, + { false, iconv_OSF0005000A_e, "OSF0005000A" }, + { false, iconv_OSF05010001_e, "OSF05010001" }, + { false, iconv_OSF100201A4_e, "OSF100201A4" }, + { false, iconv_OSF100201A8_e, "OSF100201A8" }, + { false, iconv_OSF100201B5_e, "OSF100201B5" }, + { false, iconv_OSF100201F4_e, "OSF100201F4" }, + { false, iconv_OSF100203B5_e, "OSF100203B5" }, + { false, iconv_OSF1002011C_e, "OSF1002011C" }, + { false, iconv_OSF1002011D_e, "OSF1002011D" }, + { false, iconv_OSF1002035D_e, "OSF1002035D" }, + { false, iconv_OSF1002035E_e, "OSF1002035E" }, + { false, iconv_OSF1002035F_e, "OSF1002035F" }, + { false, iconv_OSF1002036B_e, "OSF1002036B" }, + { false, iconv_OSF1002037B_e, "OSF1002037B" }, + { false, iconv_OSF10010001_e, "OSF10010001" }, + { false, iconv_OSF10010004_e, "OSF10010004" }, + { false, iconv_OSF10010006_e, "OSF10010006" }, + { false, iconv_OSF10020025_e, "OSF10020025" }, + { false, iconv_OSF10020111_e, "OSF10020111" }, + { false, iconv_OSF10020115_e, "OSF10020115" }, + { false, iconv_OSF10020116_e, "OSF10020116" }, + { false, iconv_OSF10020118_e, "OSF10020118" }, + { false, iconv_OSF10020122_e, "OSF10020122" }, + { false, iconv_OSF10020129_e, "OSF10020129" }, + { false, iconv_OSF10020352_e, "OSF10020352" }, + { false, iconv_OSF10020354_e, "OSF10020354" }, + { false, iconv_OSF10020357_e, "OSF10020357" }, + { false, iconv_OSF10020359_e, "OSF10020359" }, + { false, iconv_OSF10020360_e, "OSF10020360" }, + { false, iconv_OSF10020364_e, "OSF10020364" }, + { false, iconv_OSF10020365_e, "OSF10020365" }, + { false, iconv_OSF10020366_e, "OSF10020366" }, + { false, iconv_OSF10020367_e, "OSF10020367" }, + { false, iconv_OSF10020370_e, "OSF10020370" }, + { false, iconv_OSF10020387_e, "OSF10020387" }, + { false, iconv_OSF10020388_e, "OSF10020388" }, + { false, iconv_OSF10020396_e, "OSF10020396" }, + { false, iconv_OSF10020402_e, "OSF10020402" }, + { false, iconv_OSF10020417_e, "OSF10020417" }, + { false, iconv_PT_e, "PT" }, + { false, iconv_PT2_e, "PT2" }, + { false, iconv_PT154_e, "PT154" }, + { false, iconv_R8_e, "R8" }, + { false, iconv_R9_e, "R9" }, + { false, iconv_RK1048_e, "RK1048" }, + { false, iconv_ROMAN8_e, "ROMAN8" }, + { false, iconv_ROMAN9_e, "ROMAN9" }, + { false, iconv_RUSCII_e, "RUSCII" }, + { false, iconv_SE_e, "SE" }, + { false, iconv_SE2_e, "SE2" }, + { false, iconv_SEN_850200_B_e, "SEN_850200_B" }, + { false, iconv_SEN_850200_C_e, "SEN_850200_C" }, + { false, iconv_SHIFT_JIS_e, "SHIFT-JIS" }, + { false, iconv_SHIFTJISX0213_e, "SHIFTJISX0213" }, + { false, iconv_SHIFT_JIS_e, "SHIFT_JIS" }, + { false, iconv_SHIFT_JISX0213_e, "SHIFT_JISX0213" }, + { false, iconv_SJIS_OPEN_e, "SJIS-OPEN" }, + { false, iconv_SJIS_WIN_e, "SJIS-WIN" }, + { false, iconv_SJIS_e, "SJIS" }, + { false, iconv_SS636127_e, "SS636127" }, + { false, iconv_STRK1048_2002_e, "STRK1048-2002" }, + { false, iconv_ST_SEV_358_88_e, "ST_SEV_358-88" }, + { false, iconv_T_61_8BIT_e, "T.61-8BIT" }, + { false, iconv_T_61_e, "T.61" }, + { false, iconv_T_618BIT_e, "T.618BIT" }, + { false, iconv_TCVN_5712_e, "TCVN-5712" }, + { false, iconv_TCVN_e, "TCVN" }, + { false, iconv_TCVN5712_1_e, "TCVN5712-1" }, + { false, iconv_TCVN5712_1_1993_e, "TCVN5712-1:1993" }, + { false, iconv_THAI8_e, "THAI8" }, + { false, iconv_TIS_620_e, "TIS-620" }, + { false, iconv_TIS620_0_e, "TIS620-0" }, + { false, iconv_TIS620_2529_1_e, "TIS620.2529-1" }, + { false, iconv_TIS620_2533_0_e, "TIS620.2533-0" }, + { false, iconv_TIS620_e, "TIS620" }, + { false, iconv_TS_5881_e, "TS-5881" }, + { false, iconv_TSCII_e, "TSCII" }, + { false, iconv_TURKISH8_e, "TURKISH8" }, + { false, iconv_UCS_2_e, "UCS-2" }, + { false, iconv_UCS_2BE_e, "UCS-2BE" }, + { false, iconv_UCS_2LE_e, "UCS-2LE" }, + { false, iconv_UCS_4_e, "UCS-4" }, + { false, iconv_UCS_4BE_e, "UCS-4BE" }, + { false, iconv_UCS_4LE_e, "UCS-4LE" }, + { false, iconv_UCS2_e, "UCS2" }, + { false, iconv_UCS4_e, "UCS4" }, + { false, iconv_UHC_e, "UHC" }, + { false, iconv_UJIS_e, "UJIS" }, + { false, iconv_UK_e, "UK" }, + { false, iconv_UNICODE_e, "UNICODE" }, + { false, iconv_UNICODEBIG_e, "UNICODEBIG" }, + { false, iconv_UNICODELITTLE_e, "UNICODELITTLE" }, + { false, iconv_US_ASCII_e, "US-ASCII" }, + { false, iconv_US_e, "US" }, + { false, iconv_UTF_7_e, "UTF-7" }, + // Is UTF-8 supported?? "supported" means "recognized by parser_alphabet", + // but UTF-8 is not a valid runtime encoding. + { false, iconv_UTF_8_e, "UTF-8" }, + { false, iconv_UTF_16_e, "UTF-16" }, + { false, iconv_UTF_16BE_e, "UTF-16BE" }, + { false, iconv_UTF_16LE_e, "UTF-16LE" }, + { false, iconv_UTF_32_e, "UTF-32" }, + { false, iconv_UTF_32BE_e, "UTF-32BE" }, + { false, iconv_UTF_32LE_e, "UTF-32LE" }, + { false, iconv_UTF7_e, "UTF7" }, + { false, iconv_UTF8_e, "UTF8" }, + { false, iconv_UTF16_e, "UTF16" }, + { false, iconv_UTF16BE_e, "UTF16BE" }, + { false, iconv_UTF16LE_e, "UTF16LE" }, + { false, iconv_UTF32_e, "UTF32" }, + { false, iconv_UTF32BE_e, "UTF32BE" }, + { false, iconv_UTF32LE_e, "UTF32LE" }, + { false, iconv_VISCII_e, "VISCII" }, + { false, iconv_WCHAR_T_e, "WCHAR_T" }, + { false, iconv_WIN_SAMI_2_e, "WIN-SAMI-2" }, + { false, iconv_WINBALTRIM_e, "WINBALTRIM" }, + { false, iconv_WINDOWS_31J_e, "WINDOWS-31J" }, + { false, iconv_WINDOWS_874_e, "WINDOWS-874" }, + { false, iconv_WINDOWS_936_e, "WINDOWS-936" }, + { false, iconv_WINDOWS_1250_e, "WINDOWS-1250" }, + { false, iconv_WINDOWS_1251_e, "WINDOWS-1251" }, + { false, iconv_WINDOWS_1252_e, "WINDOWS-1252" }, + { false, iconv_WINDOWS_1253_e, "WINDOWS-1253" }, + { false, iconv_WINDOWS_1254_e, "WINDOWS-1254" }, + { false, iconv_WINDOWS_1255_e, "WINDOWS-1255" }, + { false, iconv_WINDOWS_1256_e, "WINDOWS-1256" }, + { false, iconv_WINDOWS_1257_e, "WINDOWS-1257" }, + { false, iconv_WINDOWS_1258_e, "WINDOWS-1258" }, + { false, iconv_WINSAMI2_e, "WINSAMI2" }, + { false, iconv_WS2_e, "WS2" }, + { false, iconv_YU_e, "YU" }, }; -const char * -__gg__encoding_iconv_name( cbl_encoding_t encoding ) { +static const encodings_t * +encoding_descr( cbl_encoding_t encoding ) { static encodings_t *eoencodings = encodings + COUNT_OF(encodings); auto p = std::find_if( encodings, eoencodings, [encoding]( const encodings_t& elem ) { return encoding == elem.type; } ); - return p < eoencodings? p->name : nullptr; + return p < eoencodings? p : nullptr; +} + +const char * +__gg__encoding_iconv_name( cbl_encoding_t encoding ) { + auto p = encoding_descr(encoding); + return p? p->name : nullptr; +} + +bool +__gg__encoding_iconv_valid( cbl_encoding_t encoding ) { + auto p = encoding_descr(encoding); + return p? p->supported : false; } cbl_encoding_t diff --git a/libgcobol/charmaps.h b/libgcobol/charmaps.h index 4abbfd0..f35d033 100644 --- a/libgcobol/charmaps.h +++ b/libgcobol/charmaps.h @@ -110,6 +110,8 @@ extern int __gg__low_value_character ; extern int __gg__high_value_character ; extern char **__gg__currency_signs ; extern int __gg__default_currency_sign; +extern cbl_encoding_t __gg__display_encoding ; +extern cbl_encoding_t __gg__national_encoding ; extern char *__gg__ct_currency_signs[256]; // Compile-time currency signs #define NULLCH ('\0') @@ -307,11 +309,11 @@ class charmap_t } int low_value_character() { - return __gg__low_value_character; + return mapped_character(__gg__low_value_character); } int high_value_character() { - return __gg__high_value_character; + return mapped_character(__gg__high_value_character); } int figconst_character(cbl_figconst_t figconst) diff --git a/libgcobol/common-defs.h b/libgcobol/common-defs.h index 3e6b5ff..5c35dc7 100644 --- a/libgcobol/common-defs.h +++ b/libgcobol/common-defs.h @@ -33,7 +33,11 @@ #include <cassert> #include <cstdio> #include <cstdint> + +#include <algorithm> #include <list> +#include <set> +#include <vector> #include "encodings.h" @@ -125,6 +129,8 @@ */ typedef char cbl_name_t[64]; +typedef void (callback_t)(); + // Note that the field_type enum is duplicated in the source code for the // COBOL-aware GDB, and so any changes here (or there) have to be reflected // there (or here) diff --git a/libgcobol/constants.cc b/libgcobol/constants.cc index 1715db4..75ae497 100644 --- a/libgcobol/constants.cc +++ b/libgcobol/constants.cc @@ -248,7 +248,7 @@ struct cblc_field_t __ggsr__nulls = { .parent = NULL, .occurs_lower = 0 , .occurs_upper = 0 , - .attr = 0x280 , + .attr = quoted_e | constant_e , .type = FldPointer , .level = 0 , .digits = 0 , @@ -428,7 +428,7 @@ struct cblc_field_t __ggsr___dev_null = { }; unsigned char __gg__data_tally[] = {0,0}; -struct cblc_field_t __ggsr__tally = { +struct cblc_field_t __ggsr___tally = { .data = __gg__data_tally , .capacity = 4 , .allocated = 4 , @@ -469,21 +469,200 @@ struct cblc_field_t __ggsr__argi = { .alphabet = 0 , }; -/** +/* + * Special registers used by the XML parser + */ +// XML-CODE PICTURE S9(9) USAGE BINARY VALUE ZERO *> status of XML event +static int __gg__data_xml_code = 0; +struct cblc_field_t __ggsr__xml_code = { + .data = reinterpret_cast<unsigned char*>(&__gg__data_xml_code), + .capacity = 4 , + .allocated = 4 , + .offset = 0 , + .name = "XML-CODE" , + .picture = "" , + .initial = "" , + .parent = NULL, + .occurs_lower = 0 , + .occurs_upper = 0 , + .attr = register_e, + .type = FldNumericBin5 , + .level = 0 , + .digits = 9 , + .rdigits = 0 , + .encoding = iconv_CP1252_e , + .alphabet = 0 , + }; + +// XML-EVENT PICTURE X(30) USAGE DISPLAY VALUE SPACE *> name of XML event +static unsigned char __gg__data_xml_event[30]; +struct cblc_field_t __ggsr__xml_event = { + .data = __gg__data_xml_event, + .capacity = 30 , + .allocated = 30 , + .offset = 0 , + .name = "XML-EVENT" , + .picture = "" , + .initial = NULL, + .parent = NULL, + .occurs_lower = 0 , + .occurs_upper = 0 , + .attr = register_e , + .type = FldAlphanumeric , + .level = 0 , + .digits = 0 , + .rdigits = 0 , + .encoding = iconv_CP1252_e , + .alphabet = 0 , + }; + +// XML-INFORMATION PICTURE S9(9) USAGE BINARY VALUE ZERO +static int __gg__data_xml_information = 0; +struct cblc_field_t __ggsr__xml_information = { + .data = reinterpret_cast<unsigned char*>(&__gg__data_xml_information), + .capacity = 4 , + .allocated = 4 , + .offset = 0 , + .name = "XML-INFORMATION" , + .picture = "" , + .initial = "" , + .parent = NULL, + .occurs_lower = 0 , + .occurs_upper = 0 , + .attr = register_e, + .type = FldNumericBin5 , + .level = 0 , + .digits = 9 , + .rdigits = 0 , + .encoding = iconv_CP1252_e , + .alphabet = 0 , + }; -Special registers used by the XML parser -Special register Implicit definition and usage Content - -XML-EVENT PICTURE X(30) USAGE DISPLAY VALUE SPACE *> name of XML event -XML-CODE PICTURE S9(9) USAGE BINARY VALUE ZERO *> status of XML event -XML-TEXT Variable-length alphanumeric item -XML-NTEXT Variable-length national item +// XML-NAMESPACE Variable-length based alphanumeric item +struct cblc_field_t __ggsr__xml_namespace = { + .data = nullptr , + .capacity = 1 , + .allocated = 1 , + .offset = 0 , + .name = "XML-NAMESPACE" , + .picture = "" , + .initial = "" , + .parent = NULL, + .occurs_lower = 0 , + .occurs_upper = 0 , + .attr = register_e | based_e | any_length_e, + .type = FldAlphanumeric , + .level = 0 , + .digits = 0 , + .rdigits = 0 , + .encoding = iconv_CP1252_e , + .alphabet = 0 , + }; +// XML-NNAMESPACE Variable-length national item +struct cblc_field_t __ggsr__xml_nnamespace = { + .data = nullptr , + .capacity = 1 , + .allocated = 1 , + .offset = 0 , + .name = "XML-NNAMESPACE" , + .picture = "" , + .initial = "" , + .parent = NULL, + .occurs_lower = 0 , + .occurs_upper = 0 , + .attr = register_e | based_e | any_length_e, + .type = FldAlphanumeric , + .level = 0 , + .digits = 0 , + .rdigits = 0 , + .encoding = iconv_CP1252_e , + .alphabet = 0 , + }; +// XML-NAMESPACE-PREFIX Variable-length based alphanumeric item +struct cblc_field_t __ggsr__xml_namespace_prefix = { + .data = nullptr , + .capacity = 1 , + .allocated = 1 , + .offset = 0 , + .name = "XML-NAMESPACE-PREFIX" , + .picture = "" , + .initial = "" , + .parent = NULL, + .occurs_lower = 0 , + .occurs_upper = 0 , + .attr = register_e | based_e | any_length_e, + .type = FldAlphanumeric , + .level = 0 , + .digits = 0 , + .rdigits = 0 , + .encoding = iconv_CP1252_e , + .alphabet = 0 , + }; -**/ +// XML-NNAMESPACE_PREFIX Variable-length national item +struct cblc_field_t __ggsr__xml_nnamespace_prefix = { + .data = nullptr , + .capacity = 1 , + .allocated = 1 , + .offset = 0 , + .name = "XML-NNAMESPACE-PREFIX" , + .picture = "" , + .initial = "" , + .parent = NULL, + .occurs_lower = 0 , + .occurs_upper = 0 , + .attr = register_e | based_e | any_length_e, + .type = FldAlphanumeric , + .level = 0 , + .digits = 0 , + .rdigits = 0 , + .encoding = iconv_CP1252_e , + .alphabet = 0 , + }; +// XML-TEXT Variable-length based alphanumeric item +struct cblc_field_t __ggsr__xml_text = { + .data = nullptr , + .capacity = 1 , + .allocated = 1 , + .offset = 0 , + .name = "XML-TEXT" , + .picture = "" , + .initial = "" , + .parent = NULL, + .occurs_lower = 0 , + .occurs_upper = 0 , + .attr = register_e | based_e | any_length_e , + .type = FldAlphanumeric , + .level = 0 , + .digits = 0 , + .rdigits = 0 , + .encoding = iconv_CP1252_e , + .alphabet = 0 , + }; +// XML-NTEXT Variable-length national item +struct cblc_field_t __ggsr__xml_ntext = { + .data = nullptr , + .capacity = 1 , + .allocated = 1 , + .offset = 0 , + .name = "XML-NTEXT" , + .picture = "" , + .initial = "" , + .parent = NULL, + .occurs_lower = 0 , + .occurs_upper = 0 , + .attr = register_e | based_e | any_length_e, + .type = FldAlphanumeric , + .level = 0 , + .digits = 0 , + .rdigits = 0 , + .encoding = iconv_CP1252_e , + .alphabet = 0 , + }; /* The following defines storage for the global DEBUG-ITEM: diff --git a/libgcobol/encodings.h b/libgcobol/encodings.h index dfa4b67..51cc6c3 100644 --- a/libgcobol/encodings.h +++ b/libgcobol/encodings.h @@ -1202,6 +1202,7 @@ enum cbl_encoding_t { #define iso646_e iconv_ISO_10646_e struct encodings_t { + bool supported; cbl_encoding_t type; const char name[32]; }; diff --git a/libgcobol/intrinsic.cc b/libgcobol/intrinsic.cc index c85b263..49dee6e 100644 --- a/libgcobol/intrinsic.cc +++ b/libgcobol/intrinsic.cc @@ -1146,19 +1146,58 @@ __gg__char( cblc_field_t *dest, // The CHAR function takes an integer, the ordinal position. It // returns a single-character string, which is the character at that - // ordinal position. + // ordinal position in the DISPLAY collation. - // 'A', with the ascii value of 65, is at the ordinal position 66. + // 'A', with the ascii value of 65, is at the ordinal position 66 + // in the default collation. int ordinal = (int)(__gg__binary_value_from_qualified_field(&rdigits, source, source_offset, source_size)); ordinal /= __gg__power_of_ten(rdigits); - int ch = ordinal-1; - charmap_t *charmap = __gg__get_charmap(dest->encoding); - memset(dest->data, charmap->mapped_character(ascii_space), dest->capacity); - dest->data[0] = ch; + ordinal -= 1; + + // We now look for that ordinal position in the collation table: + const unsigned short *collation = __gg__current_collation(); + int ch = -1; + for(int i=0; i<256; i++) + { + if( collation[i] == ordinal ) + { + ch = i; + break; + } + } + if( ch == -1 ) + { + // This means that the given ordinal was not in the range of + // LOW-VALUE through HIGH-VALUE + exception_raise(ec_argument_function_e); + } + + // We need to convert the ch character to the destination encoding. + const char achFrom[2] = {static_cast<char>(ch), '\0'}; + size_t charsout; + const char *converted = __gg__iconverter(__gg__display_encoding, + dest->encoding, + achFrom, + 1, + &charsout ); + // Pick up our character, because mapped_character() might clobber + // the converted contents. + int converted_char = *converted; // cppcheck-suppress variableScope + // Space fill the dest: + charmap_t *charmap_dest = __gg__get_charmap(dest->encoding); + memset(dest->data, + charmap_dest->mapped_character(ascii_space), + dest->capacity); + // Make the first character of the destination equal to our converted + // character: + if( ch > -1 && charsout == 1 ) + { + dest->data[0] = converted_char; + } } extern "C" @@ -3052,9 +3091,12 @@ __gg__ord(cblc_field_t *dest, const char *arg = PTRCAST(char, (input->data + input_offset)); // The ORD function takes a single-character string and returns the - // ordinal position of that character. + // ordinal position of that character within the current collation. + + const unsigned short *collation = __gg__current_collation(); + + size_t retval = (collation[arg[0]&0xFF]) + 1; - size_t retval = (arg[0]&0xFF) + 1; __gg__int128_to_field(dest, retval, NO_RDIGITS, diff --git a/libgcobol/libgcobol.cc b/libgcobol/libgcobol.cc index 3d1161c..89153bb 100644 --- a/libgcobol/libgcobol.cc +++ b/libgcobol/libgcobol.cc @@ -462,6 +462,8 @@ struct program_state int rt_high_value_character; char *rt_currency_signs[256]; const unsigned short *rt_collation; // Points to a table of 256 values; + cbl_encoding_t rt_display_encoding; + cbl_encoding_t rt_national_encoding; char *rt_program_name; program_state() @@ -485,6 +487,8 @@ struct program_state memset(rt_currency_signs, 0, sizeof(rt_currency_signs)); + rt_display_encoding = __gg__display_encoding; + rt_national_encoding = __gg__national_encoding; rt_collation = __gg__one_to_one_values; rt_program_name = NULL; } @@ -496,10 +500,12 @@ struct program_state rt_quote_character = ps.rt_quote_character ; rt_low_value_character = ps.rt_low_value_character ; // Note throughout the code that there is special processing for the - // high-value character. In EBCDIC 0xFF doesn't map to ASCII 0xFF, so - // we are forced to avoid converting EBCDIC 0xFF. + // default high-value character. In EBCDIC 0xFF doesn't map + // to ASCII 0xFF, so we are forced to avoid converting EBCDIC 0xFF. rt_high_value_character = ps.rt_high_value_character ; - rt_collation = ps.rt_collation ; + rt_display_encoding = ps.rt_display_encoding ; + rt_national_encoding = ps.rt_national_encoding ; + rt_collation = ps.rt_collation ; for( int i=0; i<256; i++ ) { @@ -532,14 +538,14 @@ struct program_state static std::vector<program_state> program_states; #define collated(a) (program_states.back().rt_collation[(unsigned int)(a&0xFF)]) #define program_name (program_states.back().rt_program_name) -// #define decimal_point (program_states.back().rt_decimal_point) -// #define decimal_separator (program_states.back().rt_decimal_separator) -// #define quote_character (program_states.back().rt_quote_character) -// #define low_value_character (program_states.back().rt_low_value_character) -// #define high_value_character (program_states.back().rt_high_value_character) -// #define currency_signs(a) (program_states.back().rt_currency_signs[(a)]) #define currency_signs(a) (__gg__currency_signs[(a)]) +const unsigned short * +__gg__current_collation() + { + return program_states.back().rt_collation; + } + #ifdef DEBUG_MALLOC void *malloc(size_t a) { @@ -691,6 +697,8 @@ __gg__pop_program_state() __gg__quote_character = program_states.back().rt_quote_character ; __gg__low_value_character = program_states.back().rt_low_value_character ; __gg__high_value_character = program_states.back().rt_high_value_character ; + __gg__display_encoding = program_states.back().rt_display_encoding ; + __gg__national_encoding = program_states.back().rt_national_encoding ; __gg__currency_signs = program_states.back().rt_currency_signs ; } @@ -732,10 +740,14 @@ __gg__decimal_point_is_comma() extern "C" void -__gg__init_program_state() +__gg__init_program_state(cbl_encoding_t display_encoding, + cbl_encoding_t national_encoding) { // This routine gets called at DATA DIVISION time. + __gg__display_encoding = display_encoding; + __gg__national_encoding = national_encoding; + // We need to make sure that the program_states vector has at least one // entry in it. This happens when we are the very first PROGRAM-ID called // in this module. @@ -2972,18 +2984,32 @@ format_for_display_internal(char **dest, case FldAlphanumeric: case FldNumericEdited: case FldAlphaEdited: + { __gg__realloc_if_necessary(dest, dest_size, actual_length+1); - if( actual_location ) + + cbl_figconst_t figconst = (cbl_figconst_t)(var->attr & FIGCONST_MASK); + if( figconst ) { - memcpy(*dest, actual_location, actual_length); + charmap_t *charmap = __gg__get_charmap(retval); + int figconst_char = charmap->figconst_character(figconst); + memset(*dest, figconst_char, actual_length); + (*dest)[actual_length] = NULLCH; } else { - fprintf(stderr, "attempting to display a NULL pointer in %s\n", var->name); - abort(); + if( actual_location ) + { + memcpy(*dest, actual_location, actual_length); + } + else + { + fprintf(stderr, "attempting to display a NULL pointer in %s\n", var->name); + abort(); + } + (*dest)[actual_length] = NULLCH; } - (*dest)[actual_length] = NULLCH; break; + } case FldNumericDisplay: { @@ -3051,7 +3077,7 @@ format_for_display_internal(char **dest, bool is_negative; int index = 0; // This is the running index into our output destination - ptrdiff_t signoffset; + std::ptrdiff_t signoffset; switch(signtype) { case 0: @@ -4160,6 +4186,7 @@ __gg__compare_2(cblc_field_t *left_side, unsigned int fig_left = 0; unsigned int fig_right = 0; + fig_left = charmap_left->figconst_character(left_figconst); fig_right = charmap_right->figconst_character(right_figconst); @@ -10717,7 +10744,8 @@ __gg__set_pointer(cblc_field_t *target, extern "C" void -__gg__alphabet_use( cbl_encoding_t alphabetic_encoding, +__gg__alphabet_use( cbl_encoding_t display_encoding, + cbl_encoding_t national_encoding, cbl_encoding_t encoding, size_t alphabet_index) { @@ -10725,6 +10753,9 @@ __gg__alphabet_use( cbl_encoding_t alphabetic_encoding, // state needs to be saved -- for example, if we are doing a SORT with an // ALPHABET override -- that's up to the caller + __gg__display_encoding = display_encoding; + __gg__national_encoding = national_encoding; + if( program_states.empty() ) { // When there is no DATA DIVISION, program_states can be empty when @@ -10732,10 +10763,11 @@ __gg__alphabet_use( cbl_encoding_t alphabetic_encoding, initialize_program_state(); } - const charmap_t *charmap_alphabetic = __gg__get_charmap(alphabetic_encoding); + const charmap_t *charmap_alphabetic = __gg__get_charmap(display_encoding); switch( encoding ) { + case iconv_CP1252_e: case ASCII_e: case iso646_e: // This is one of the very common standard situations; where we are using @@ -11589,8 +11621,7 @@ default_exception_handler( ec_type_t ec ) filename = file.filename; switch( last_exception_file_operation ) { case file_op_none: // not an I/O statement - assert(false); - abort(); + break; case file_op_open: case file_op_close: // No OPEN/CLOSE results in a fatal error. disposition = ec_category_none_e; diff --git a/libgcobol/libgcobol.h b/libgcobol/libgcobol.h index 2871f71..b137f36 100644 --- a/libgcobol/libgcobol.h +++ b/libgcobol/libgcobol.h @@ -142,4 +142,6 @@ void __gg__convert_encoding_length(char *pch, cbl_encoding_t from, cbl_encoding_t to ); +const unsigned short *__gg__current_collation(); + #endif diff --git a/libgcobol/posix/errno.cc b/libgcobol/posix/errno.cc new file mode 100644 index 0000000..3849ef8 --- /dev/null +++ b/libgcobol/posix/errno.cc @@ -0,0 +1,7 @@ +#include <errno.h> + +extern "C" +int +posix_errno() { + return errno; +} diff --git a/libgcobol/posix/localtime.cc b/libgcobol/posix/localtime.cc new file mode 100644 index 0000000..5080f96 --- /dev/null +++ b/libgcobol/posix/localtime.cc @@ -0,0 +1,34 @@ +#include <assert.h> +#include <time.h> + +extern "C" { + +#include "tm.h" + +static struct posix_tm posix_tm; + + +struct posix_tm * +posix_localtime(const time_t *timep, size_t size) { + + assert(timep); + assert(sizeof(posix_tm) == size); + + struct tm * tm = localtime(timep); + + if( tm == NULL ) return NULL; + + posix_tm.tm_sec = tm->tm_sec; + posix_tm.tm_min = tm->tm_min; + posix_tm.tm_hour = tm->tm_hour; + posix_tm.tm_mday = tm->tm_mday; + posix_tm.tm_mon = tm->tm_mon; + posix_tm.tm_year = tm->tm_year; + posix_tm.tm_wday = tm->tm_wday; + posix_tm.tm_yday = tm->tm_yday; + posix_tm.tm_isdst = tm->tm_isdst; + + return &posix_tm; +} + +} // extern "C" diff --git a/libgcobol/posix/stat.cc b/libgcobol/posix/stat.cc new file mode 100644 index 0000000..fc34f7b --- /dev/null +++ b/libgcobol/posix/stat.cc @@ -0,0 +1,90 @@ +#include <assert.h> +#include <stddef.h> +#include <stdio.h> +#include <unistd.h> + +#include <sys/types.h> +#include <sys/stat.h> + +extern "C" { + +#include "stat.h" + +int +posix_stat(const char *pathname, struct posix_stat_t *statbuf, size_t size) { + struct stat sb; + int erc = stat(pathname, &sb); + + if( sizeof(struct posix_stat_t) != size ) { + fprintf(stderr, "posix_stat %lu != received size %lu\n", + (unsigned long)sizeof(struct posix_stat_t), + (unsigned long)size); + } + + assert(sizeof(struct posix_stat_t) == size); + assert(statbuf); + + if( erc == 0 ) { + statbuf->st_dev = sb.st_dev; + statbuf->st_ino = sb.st_ino; + statbuf->st_mode = sb.st_mode; + statbuf->st_nlink = sb.st_nlink; + statbuf->st_uid = sb.st_uid; + statbuf->st_gid = sb.st_gid; + statbuf->st_rdev = sb.st_rdev; + statbuf->st_size = sb.st_size; + statbuf->st_blksize = sb.st_blksize; + statbuf->st_blocks = sb.st_blocks; + statbuf->st_atim = sb.st_atim.tv_sec; + statbuf->st_mtim = sb.st_mtim.tv_sec; + statbuf->st_ctim = sb.st_ctim.tv_sec; + } + + if( 0 ) { + printf("%4lu: st_dev: %lu = %lu\n", + (unsigned long)offsetof(struct posix_stat_t, st_dev), + (unsigned long)statbuf->st_dev, (unsigned long)sb.st_dev); + printf("%4lu: st_ino: %lu = %lu\n", + (unsigned long)offsetof(struct posix_stat_t, st_ino), + (unsigned long)statbuf->st_ino, (unsigned long)sb.st_ino); + printf("%4lu: st_mode: %lu = %lu\n", + (unsigned long)offsetof(struct posix_stat_t, st_mode), + (unsigned long)statbuf->st_mode, (unsigned long)sb.st_mode); + printf("%4lu: st_nlink: %lu = %lu\n", + (unsigned long)offsetof(struct posix_stat_t, st_nlink), + (unsigned long)statbuf->st_nlink, (unsigned long)sb.st_nlink); + printf("%4lu: st_uid: %lu = %lu\n", + (unsigned long)offsetof(struct posix_stat_t, st_uid), + (unsigned long)statbuf->st_uid, (unsigned long)sb.st_uid); + printf("%4lu: st_gid: %lu = %lu\n", + (unsigned long)offsetof(struct posix_stat_t, st_gid), + (unsigned long)statbuf->st_gid, (unsigned long)sb.st_gid); + printf("%4lu: st_rdev: %lu = %lu\n", + (unsigned long)offsetof(struct posix_stat_t, st_rdev), + (unsigned long)statbuf->st_rdev, (unsigned long)sb.st_rdev); + printf("%4lu: st_size: %lu = %lu\n", + (unsigned long)offsetof(struct posix_stat_t, st_size), + (unsigned long)statbuf->st_size, (unsigned long)sb.st_size); + printf("%4lu: st_blksize: %lu = %lu\n", + (unsigned long)offsetof(struct posix_stat_t, st_blksize), + (unsigned long)statbuf->st_blksize, (unsigned long)sb.st_blksize); + printf("%4lu: st_blocks: %lu = %lu\n", + (unsigned long)offsetof(struct posix_stat_t, st_blocks), + (unsigned long)statbuf->st_blocks, (unsigned long)sb.st_blocks); + printf("%4lu: st_atim: %lu = %lu\n", + (unsigned long)offsetof(struct posix_stat_t, st_atim), + (unsigned long)statbuf->st_atim, (unsigned long)sb.st_atim.tv_sec); + printf("%4lu: st_mtim: %lu = %lu\n", + (unsigned long)offsetof(struct posix_stat_t, st_mtim), + (unsigned long)statbuf->st_mtim, (unsigned long)sb.st_mtim.tv_sec); + printf("%4lu: st_ctim: %lu = %lu\n", + (unsigned long)offsetof(struct posix_stat_t, st_ctim), + (unsigned long)statbuf->st_ctim, (unsigned long)sb.st_ctim.tv_sec); + } + + return erc; + + +} + +} // extern "C" diff --git a/libgcobol/posix/stat.h b/libgcobol/posix/stat.h new file mode 100644 index 0000000..4def867 --- /dev/null +++ b/libgcobol/posix/stat.h @@ -0,0 +1,15 @@ +struct posix_stat_t { + dev_t st_dev; /* ID of device containing file */ + ino_t st_ino; /* Inode number */ + mode_t st_mode; /* File type and mode */ + nlink_t st_nlink; /* Number of hard links */ + uid_t st_uid; /* User ID of owner */ + gid_t st_gid; /* Group ID of owner */ + dev_t st_rdev; /* Device ID (if special file) */ + off_t st_size; /* Total size, in bytes */ + blksize_t st_blksize; /* Block size for filesystem I/O */ + blkcnt_t st_blocks; /* Number of 512B blocks allocated */ + time_t st_atim; /* Time of last access */ + time_t st_mtim; /* Time of last modification */ + time_t st_ctim; /* Time of last status change */ +}; diff --git a/libgcobol/posix/tm.h b/libgcobol/posix/tm.h new file mode 100644 index 0000000..862f38f --- /dev/null +++ b/libgcobol/posix/tm.h @@ -0,0 +1,11 @@ +struct posix_tm { + int tm_sec; /* Seconds (0-60) */ + int tm_min; /* Minutes (0-59) */ + int tm_hour; /* Hours (0-23) */ + int tm_mday; /* Day of the month (1-31) */ + int tm_mon; /* Month (0-11) */ + int tm_year; /* Year - 1900 */ + int tm_wday; /* Day of the week (0-6, Sunday = 0) */ + int tm_yday; /* Day in the year (0-365, 1 Jan = 0) */ + int tm_isdst; /* Daylight saving time */ +}; diff --git a/libgcobol/xmlparse.cc b/libgcobol/xmlparse.cc new file mode 100644 index 0000000..69849e3 --- /dev/null +++ b/libgcobol/xmlparse.cc @@ -0,0 +1,592 @@ +/* + * Copyright (c) 2021-2025 Symas Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the Symas Corporation 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 + * OWNER 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. + */ + +#include <fcntl.h> +#include <unistd.h> + +#include <cctype> +#include <cerrno> +#include <cmath> +#include <cfenv> +#include <cstdio> +#include <cstdlib> +#include <cstring> +#include <ctime> + +#include <algorithm> +#include <vector> + +#include <libxml/SAX2.h> +#include <libxml/parser.h> + +#include "config.h" +#include "libgcobol-fp.h" +#include "ec.h" +#include "common-defs.h" +#include "io.h" +#include "gcobolio.h" +#include "libgcobol.h" + +#define COUNT_OF(X) (sizeof(X) / sizeof(X[0])) + +void sayso( const char func[], int line, + int len = 0 , const unsigned char data[] = { 0} ) { + if( getenv("XMLPARSE") ) { + switch(len) { + case 0: + fprintf(stderr, "%s:%d Kilroy was here\n", func, line); + break; + case -1: + fprintf(stderr, "%s:%d: '%s'\n", func, line, data); + break; + default: + fprintf(stderr, "%s:%d: '%.*s'\n", func, line, len, data); + break; + } + } +} +#define SAYSO() sayso(__func__, __LINE__) +#define SAYSO_DATAZ(S) sayso(__func__, __LINE__, -1, S) +#define SAYSO_DATA(N, S) sayso(__func__, __LINE__, N, S) + +struct xml_ec_value_t { + int ibm_code; + const char msg[80]; +} xml_ec_values[] = { + // Table 73. XML PARSE exceptions that allow continuation + { 1, "invalid character between elements" }, + { 2, "invalid start before element content" }, + { 3, "duplicate attribute" }, + { 4, "markup character '<' in an attribute value" }, + { 5, "start/end tag mismatch" }, + { 6, "invalid character in element" }, + { 7, "invalid start in element content. " }, + { 8, "CDATA closing character sequence ']]>' not opened" }, + { 10, "comment the character sequence '--' without '>'" }, + { 11, "invalid character in a processing instruction" }, + { 12, "XML declaration was not start of document" }, + { 13, "invalid digit in a hexadecimal character reference" }, + { 14, "invalid digit in a decimal character reference" }, + { 15, "encoding declaration value name must start with [a-zA-Z] character" }, + { 16, "character reference did not refer to a legal XML character" }, + { 17, "invalid character in an entity reference name" }, + { 70, "EBCDIC document, supported EBCDIC page, unsupported declaration" }, + { 71, "EBCDIC document, unsupported EBCDIC page " }, + { 72, "EBCDIC document, unsupported EBCDIC page, unsupported declaration" }, + { 73, "EBCDIC document, unsupported EBCDIC page and declaration " }, + { 80, "ASCII document, supported ASCII page, unsupported declaration" }, + { 81, "ASCII document, unsupported ASCII page " }, + { 82, "ASCII document, unsupported ASCII page, unsupported declaration" }, + { 83, "ASCII document, unsupported ASCII page and declaration " }, + { 84, "ASCII document, invalid UTF-8, external UTF-8, no declaration. " }, + { 85, "ASCII document, invalid UTF-8, external UTF-8, invalid declaration" }, + { 86, "ASCII document, invalid UTF-8, external ASCII" }, + { 87, "ASCII document, invalid UTF-8, external and document UTF-8" }, + { 88, "ASCII document, invalid UTF-8, unsupported ASCII/UTF-8, UTF-8 declaration" }, + { 89, "ASCII document, invalid UTF-8, external UTF-8, ASCII declaration" }, + { 92, "alphanumeric document expected, document is UTF-16. " }, + + // XML PARSE exceptions that allow continuation (continued) + //// 100,001 - 165,535 EBCDIC document encoding does not match code page + //// 200,001 - 265,535 ASCII document encoding does not match code page + + // XML PARSE exceptions that do not allow continuation + { 100, "end of document before start of XML declaration" }, + { 101, "end of document before end of XML declaration" }, + { 102, "end of document before root element" }, + { 103, "end of document before version information in XML declaration" }, + { 104, "end of document before version information value in XML declaration" }, + { 106, "end of document before encoding declaration value in XML declaration" }, + { 108, "end of document before standalone declaration value in XML declaration" }, + { 109, "end of document before attribute name" }, + { 110, "end of document before attribute value" }, + { 111, "end of document before character/entity reference in attribute value" }, + { 112, "end of document before empty element tag" }, + { 113, "end of document before root element name" }, + { 114, "end of document before element name" }, + { 115, "end of document before character data in element content" }, + { 116, "end of document before processing instruction in element content" }, + { 117, "end of document before comment or CDATA section in element content" }, + { 118, "end of document before comment in element content" }, + { 119, "end of document before CDATA section in element content" }, + { 120, "end of document before character/entity reference in element content" }, + { 121, "end of document before after close of root element" }, + { 122, "possible invalid start of a document type" }, + { 123, "duplicate document type" }, + { 124, "root element name must start with [A-Za-z_:]" }, + { 125, "first attribute name must start with [A-Za-z_:]" }, + { 126, "invalid character in or after element name" }, + { 127, "attribute name not followed by '=' " }, + { 128, "invalid attribute value delimiter" }, + { 130, "attribute name must start with [A-Za-z_:]" }, + { 131, "invalid character in or after attribute name" }, + { 132, "empty element tag not terminated with '/>'" }, + { 133, "element end tag name name must start with [A-Za-z_:]" }, + { 134, "element end tag not terminated with '>'" }, + { 135, "element name must start with [A-Za-z_:]" }, + { 136, "invalid start of comment/CDATA in element" }, + { 137, "invalid start of comment" }, + { 138, "processing instruction target name must start with [A-Za-z_:]" }, + { 139, "invalid character in/afterprocessing instruction target name" }, + { 140, "processing instruction not terminated with '?>'" }, + { 141, "invalid character following '&' in a character/entity reference" }, + { 142, "missing version information in XML declaration" }, + { 143, "missing '=' after 'version' in XML declaration " }, + { 144, "missing XML version declaration " }, + { 145, "invalid character in XML version information" }, + { 146, "invalid character following XML version information value " }, + { 147, "invalid attribute in XML declaration" }, + { 148, "missing '=' after 'encoding' in XML declaration" }, + { 149, "missing XML encoding declaration value" }, + { 150, "invalid XML encoding declaration value" }, + { 151, "invalid character afer XML declaration" }, + { 152, "invalid attribute XML declaration" }, + { 153, "missing '=' after standalone XML declaration" }, + { 154, "missing standalone XML declaration value" }, + { 155, "standalone declaration must be 'yes' or 'no'" }, + { 156, "invalid standalone XML declaration value" }, + { 157, "invalid character following XML standalone declaration value" }, + { 158, "unterminated XML declaration " }, + { 159, "start of document type declaration after end of root element" }, + { 160, "start of element after end of root element" }, + { 161, "invalid UTF-8 byte sequence" }, + { 162, "UTF-8 character that has a Unicode code point above x'FFFF'" }, + { 315, "UTF-16 document little-endian unsupported" }, + { 316, "UCS4 document unsupported" }, + { 317, "unrecognized document encoding" }, + { 318, "UTF-8 document unsupported " }, + { 320, "mismatched national document data item to document encoding EBCDIC" }, + { 321, "mismatched national document data item to document encoding ASCII" }, + { 322, "mismatched native alphanumeric document data item to document encoding EBCDIC" }, + { 323, "mismatched host alphanumeric document data item to document encoding ASCII" }, + { 324, "mismatched national document data item to document encoding UTF-8" }, + { 325, "mismatched host alphanumeric document datat to document encoding UTF-8" }, + { 500, "internal error" }, +}, *eoxml_ec_values = xml_ec_values + COUNT_OF(xml_ec_values); + +static const xml_ec_value_t * +xml_ec_value_of( int ibm_code ) { + if( 100000 < ibm_code && ibm_code < 200000 ) { + static xml_ec_value_t not_ebcdic{ 0, "EBCDIC document encoding " + "does not match code page" }; + not_ebcdic.ibm_code = ibm_code; + return ¬_ebcdic; + } + if( 200000 < ibm_code && ibm_code < 300000 ) { + static xml_ec_value_t not_ascii{ 0, "ASCII document encoding " + "does not match code page" }; + not_ascii.ibm_code = ibm_code; + return ¬_ascii; + } + auto p = std::find_if( xml_ec_values, eoxml_ec_values, + [ibm_code]( const auto& value ) { + return ibm_code == value.ibm_code; + } ); + return p < eoxml_ec_values ? &*p : nullptr; +} + +const char * +xml_ec_value_str( int ibm_code ) { + auto p = xml_ec_value_of(ibm_code); + return p? p->msg : nullptr; +} + +#if NEEDED +static bool +xml_fatal( int ibm_code ) { + if( ibm_code < 100 ) return false; + if( ibm_code > 100000 ) return false; + assert(ibm_code < 1000); + return true; +} +#endif + +static callback_t *cobol_callback; + +/* + * Internal handler functions + */ +/////////////// +/* + +ATTRIBUTE-CHARACTER The single character that corresponds with the predefined entity reference in the attribute value +ATTRIBUTE-CHARACTERS The value within quotation marks or apostrophes. This can be a substring of the attribute value if the value includes an entity reference. +ATTRIBUTE-NAME The attribute name; the string to the left of the equal sign +ATTRIBUTE-NATIONAL-CHARACTER Regardless of the type of the XML document specified by identifier-1 in the XML PARSE statement, XML-TEXT is empty with length zero and XML-NTEXT contains the single national character that corresponds with the numeric character reference. + +CONTENT-CHARACTER The single character that corresponds with the predefined entity reference in the element content + +CONTENT-NATIONAL-CHARACTER Regardless of the type of the XML document specified by identifier-1 in the XML PARSE statement, XML-TEXT is empty with length zero and XML-NTEXT contains the single national character that corresponds with the numeric character reference.1 +DOCUMENT-TYPE-DECLARATION The entire document type declaration, including the opening and closing character sequences "<!DOCTYPE" and ">" +ENCODING-DECLARATION The value, between quotes or apostrophes, of the encoding declaration in the XML declaration +END-OF-CDATA-SECTION The string "]]>" +END-OF-DOCUMENT Empty with length zero + +EXCEPTION The part of the document that was successfully scanned, up to and including the point at which the exception was detected.2 Special register XML-CODE contains the unique error code that identifies the exception. + +PROCESSING-INSTRUCTION-TARGET The processing instruction target name, which occurs immediately after the processing instruction opening sequence, "<?" +STANDALONE-DECLARATION The value, between quotation marks or apostrophes ("yes" or "no"), of the stand-alone declaration in the XML declaration +START-OF-CDATA-SECTION The string "<![CDATA[" +START-OF-DOCUMENT The entire document + +UNKNOWN-REFERENCE-IN-CONTENT The entity reference name, not including the "&" and ";" delimiters +UNKNOWN-REFERENCE-IN-ATTRIBUTE The entity reference name, not including the "&" and ";" delimiters +VERSION-INFORMATION The value, between quotation marks or apostrophes, of the version information in the XML declaration + +*/ +/////////////// + +extern cblc_field_t __ggsr__xml_event; +extern cblc_field_t __ggsr__xml_code; +extern cblc_field_t __ggsr__xml_text; +extern cblc_field_t __ggsr__xml_ntext; + +static void +xml_event( const char event_name[], size_t len, char text[] ) { + assert(strlen(event_name) < __ggsr__xml_event.allocated); + + auto pend = __ggsr__xml_event.data + __ggsr__xml_event.allocated; + auto p = std::copy( event_name, event_name + strlen(event_name), + PTRCAST(char, __ggsr__xml_event.data) ); + std::fill(PTRCAST(unsigned char, p), pend, 0x20); + + __ggsr__xml_text.data = reinterpret_cast<unsigned char*>(text); + __ggsr__xml_text.capacity = __ggsr__xml_text.allocated = len; + __ggsr__xml_code.data = 0; + cobol_callback(); +} + +static inline void +xml_event( const char event_name[], char text[] ) { + xml_event(event_name, strlen(text), text); +} + +static inline void +xml_event( const char event_name[], size_t len, const xmlChar * value ) { + char *text = reinterpret_cast<char*>(const_cast<xmlChar*>(value)); + xml_event(event_name, len, text); +} + +static inline void +xml_event( const char event_name[], const xmlChar * value ) { + char *text = reinterpret_cast<char*>(const_cast<xmlChar*>(value)); + xml_event(event_name, strlen(text), text); +} + +static void attributeDecl(void * ctx, + const xmlChar * elem, + const xmlChar * fullname, + int type, + int def, + const xmlChar * defaultValue, + xmlEnumerationPtr tree) +{ + fprintf(stderr, "%s:%d: elem=%s, name=%s, default=%s\n", + __func__, __LINE__, elem, fullname, defaultValue); +} + +static void cdataBlock(void * ctx, + const xmlChar * data, + int len) +{ + SAYSO_DATA(len, data); + xml_event("CONTENT-CHARACTERS", len, data); +} + +static void characters(void * ctx, + const xmlChar * data, + int len) +{ + SAYSO_DATA(len, data); + xml_event("CONTENT-CHARACTERS", len, data); +} + +static void comment(void * ctx, const xmlChar * value) { + SAYSO_DATAZ(value); + xml_event("COMMENT", value); +} + +static void elementDecl(void * ctx, + const xmlChar * name, + int type, + xmlElementContentPtr content) +{ SAYSO_DATAZ(name); } + +static void endDocument(void * ctx) +{ SAYSO(); } + +static void endElementNs(void * ctx, + const xmlChar * localname, + const xmlChar * prefix, + const xmlChar * URI) +{ + SAYSO_DATAZ(localname); + xml_event("END-OF-ELEMENT", localname); +} + +static void endElement(void * ctx, + const xmlChar * name) +{ SAYSO_DATAZ(name); } + +static void entityDecl(void * ctx, + const xmlChar * name, + int type, + const xmlChar * publicId, + const xmlChar * systemId, + xmlChar * content) +{ SAYSO_DATAZ(name); } + +static void error(void * ctx, const char * msg, ...) +{ + va_list ap; + va_start (ap, msg); + fprintf(stderr, "error: "); + vfprintf(stderr, msg, ap); + fprintf(stderr, "\n"); + va_end (ap); +} + +static void externalSubset(void * ctx, + const xmlChar * name, + const xmlChar * ExternalID, + const xmlChar * SystemID) +{ SAYSO_DATAZ(name); } + +static void fatalError(void * ctx, const char * msg, ...) +{ + va_list ap; + va_start (ap, msg); + fprintf(stderr, "fatal: "); + vfprintf(stderr, msg, ap); + fprintf(stderr, "\n"); + va_end (ap); +} + +static xmlEntityPtr getEntity(void * ctx, + const xmlChar * name) +{ SAYSO_DATAZ(name); } + +static xmlEntityPtr getParameterEntity(void * ctx, + const xmlChar * name) +{ SAYSO_DATAZ(name); } + +static int hasExternalSubset(void * ctx) +{ SAYSO(); } + +static int hasInternalSubset(void * ctx) +{ SAYSO(); } + +static void ignorableWhitespace(void * ctx, + const xmlChar * ch, + int len) +{ SAYSO_DATA(len, ch); } + +static void internalSubset(void * ctx, + const xmlChar * name, + const xmlChar * ExternalID, + const xmlChar * SystemID) +{ SAYSO_DATAZ(name); } + +static int isStandalone (void * ctx) +{ SAYSO(); } + + +static void notationDecl(void * ctx, + const xmlChar * name, + const xmlChar * publicId, + const xmlChar * systemId) +{ SAYSO_DATAZ(name); } + +static void processingInstruction(void * ctx, + const xmlChar * target, + const xmlChar * data) +{ + SAYSO_DATAZ(target); + xml_event("PROCESSING-INSTRUCTION-TARGET", target); + SAYSO_DATAZ(data); + xml_event("PROCESSING-INSTRUCTION-DATA", data); +} + +static void reference(void * ctx, + const xmlChar * name) +{ SAYSO_DATAZ(name); } + +static xmlParserInputPtr resolveEntity( void * ctx, + const xmlChar * publicId, + const xmlChar * systemId) +{ SAYSO(); } + +static void setDocumentLocator(void * ctx, + xmlSAXLocatorPtr loc) +{ SAYSO(); } + +/* + * Called after the XML declaration was parsed. + * Use xmlCtxtGetVersion(), xmlCtxtGetDeclaredEncoding() and + * xmlCtxtGetStandalone() to get data from the XML declaration. + */ +static void startDocument(void * ctx) +{ SAYSO(); } + +static void startElementNs(void * ctx, + const xmlChar * localname, + const xmlChar * prefix, + const xmlChar * URI, + int nb_namespaces, + const xmlChar ** namespaces, + int nb_attributes, + int nb_defaulted, + const xmlChar ** attributes) +{ + SAYSO_DATAZ(localname); + xml_event("START-OF-ELEMENT", localname); +} + +static void startElement(void * ctx, + const xmlChar * name, + const xmlChar ** atts) +{ SAYSO_DATAZ(name); } + +static void unparsedEntityDecl(void * ctx, + const xmlChar * name, + const xmlChar * publicId, + const xmlChar * systemId, + const xmlChar * notationName) +{ SAYSO_DATAZ(name); } + +static void warning(void * ctx, const char * msg, ... ) +{ + va_list ap; + va_start (ap, msg); + fprintf(stderr, "warning: "); + vfprintf(stderr, msg, ap); + fprintf(stderr, "\n"); + va_end (ap); +} + +/* + * xmlSAXHandler is a structure of function pointers that the SAX parser calls + * as it encounters XML elements in the input. Each pointer is a callback + * function, locally defined in this file. These we term "handlers". + * + * Each handler sets the XML registers per IBM, and then calls + * cobol_callback(), which is a function pointer supplied by the COBOL program + * to be the processing procedure for XML PARSE. + * + * There is no obvious way to abort parsing at the C level. See: + * http://veillard.com/XML/messages/0540.html + * + * > The simplest to implement this would not be to add a new SAX + * > callback but rather modify the xmlParserCtxtPtr passed to the + * > callbacks. The best seems to be: + * > - set ctxt->instate to XML_PARSER_EOF + * > - hack xmlCurrentChar() to return 0 + * > if (ctxt->instate == XML_PARSER_EOF) + * > Doing both should led to a quick termination of parsing + * > (but endElement(s)/endDocument will certainly be called anyway). + * + * Another hack might be to set the input to all blanks in cobol_callback. + */ + +static xmlSAXHandler handlers; + +static void +initialize_handlers( callback_t *callback ) { + handlers = xmlSAXHandler {}; + handlers.initialized = XML_SAX2_MAGIC; + + cobol_callback = callback; + +#if 0 + //// Should typically not be modified + handlers.attributeDecl = attributeDecl; + handlers.elementDecl = elementDecl; + handlers.entityDecl = entityDecl; + handlers.externalSubset = externalSubset; + handlers.getEntity = getEntity; + handlers.getParameterEntity = getParameterEntity; + handlers.internalSubset = internalSubset; + handlers.notationDecl = notationDecl; + handlers.resolveEntity = resolveEntity; + handlers.unparsedEntityDecl = unparsedEntityDecl; + + //// Not supposed to be changed by applications + handlers.hasExternalSubset = hasExternalSubset; + handlers.hasInternalSubset = hasInternalSubset; + handlers.isStandalone = isStandalone; + + //// SAX 1 only + handlers.startElement = startElement; + handlers.endElement = endElement; + + //// Everything is available on the context, so this is useless in our case + handlers.setDocumentLocator = setDocumentLocator; +#endif + + handlers.cdataBlock = cdataBlock; + handlers.characters = characters; + handlers.comment = comment; + handlers.endDocument = endDocument; + handlers.endElementNs = endElementNs; + handlers.ignorableWhitespace = ignorableWhitespace; + handlers.processingInstruction = processingInstruction; + handlers.reference = reference; + handlers.startDocument = startDocument; + handlers.startElementNs = startElementNs; + handlers.error = error; + handlers.fatalError = fatalError; + handlers.warning = warning; +} + +extern "C" +int +__gg__xml_parse( const cblc_field_t *input_field, + size_t input_offset, + size_t len, + cblc_field_t *encoding, + cblc_field_t *validating, + int returns_national, + void (*callback)(void) ) +{ + initialize_handlers(callback); + + const char *input = PTRCAST(char, input_field->data + input_offset); + + int erc = xmlSAXUserParseMemory(&handlers, nullptr, input, len); + + if( erc ) { + xmlErrorPtr msg = xmlCtxtGetLastError(nullptr); + fprintf(stderr, "XML PARSE: error: line %d: %s (%d: %d.%d.%d)\n", + msg->line, msg->message, erc, msg->domain, msg->level, msg->code); + } + return erc; +} + + diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog index c102808..ab7f752 100644 --- a/libgomp/ChangeLog +++ b/libgomp/ChangeLog @@ -1,3 +1,59 @@ +2025-10-23 Andrew Stubbs <ams@baylibre.com> + + * Makefile.am (libgomp_la_SOURCES): Add simple-allocator.c. + * Makefile.in: Regenerate. + * basic-allocator.c: Mention simple-allocator in the comment. + * config/linux/allocator.c: Include unistd.h. + (pin_ctx): New variable. + (ctxlock): New variable. + (linux_init_pin_ctx): New function. + (linux_memspace_alloc): Use simple-allocator for pinned memory. + (linux_memspace_free): Likewise. + (linux_memspace_realloc): Likewise. + * libgomp.h (gomp_simple_alloc_init_context): New prototype. + (gomp_simple_alloc_register_memory): New prototype. + (gomp_simple_alloc): New prototype. + (gomp_simple_free): New prototype. + (gomp_simple_realloc): New prototype. + * libgomp.texi: Update pinned memory trait documentation. + * testsuite/libgomp.c/alloc-pinned-8.c: New test. + * simple-allocator.c: New file. + +2025-10-23 Andrew Stubbs <ams@baylibre.com> + Thomas Schwinge <thomas@codesourcery.com> + + * config/linux/allocator.c: Include assert.h. + (using_device_for_page_locked): New variable. + (linux_memspace_alloc): Add init0 parameter. Support device pinning. + (linux_memspace_calloc): Set init0 to true. + (linux_memspace_free): Support device pinning. + (linux_memspace_realloc): Support device pinning. + (MEMSPACE_ALLOC): Set init0 to false. + * libgomp-plugin.h + (GOMP_OFFLOAD_page_locked_host_alloc): New prototype. + (GOMP_OFFLOAD_page_locked_host_free): Likewise. + * libgomp.h (gomp_page_locked_host_alloc): Likewise. + (gomp_page_locked_host_free): Likewise. + (struct gomp_device_descr): Add page_locked_host_alloc_func and + page_locked_host_free_func. + * libgomp.texi: Adjust the docs for the pinned trait. + * plugin/plugin-nvptx.c + (GOMP_OFFLOAD_page_locked_host_alloc): New function. + (GOMP_OFFLOAD_page_locked_host_free): Likewise. + * target.c (device_for_page_locked): New variable. + (get_device_for_page_locked): New function. + (gomp_page_locked_host_alloc): Likewise. + (gomp_page_locked_host_free): Likewise. + (gomp_load_plugin_for_device): Add page_locked_host_alloc and + page_locked_host_free. + * testsuite/libgomp.c/alloc-pinned-1.c: Change expectations for NVPTX + devices. + * testsuite/libgomp.c/alloc-pinned-2.c: Likewise. + * testsuite/libgomp.c/alloc-pinned-3.c: Likewise. + * testsuite/libgomp.c/alloc-pinned-4.c: Likewise. + * testsuite/libgomp.c/alloc-pinned-5.c: Likewise. + * testsuite/libgomp.c/alloc-pinned-6.c: Likewise. + 2025-10-20 Josef Melcr <jmelcr02@gmail.com> * testsuite/libgomp.c/ipcp-cb-spec1.c: Moved from diff --git a/libgomp/Makefile.am b/libgomp/Makefile.am index 19479ae..0902164 100644 --- a/libgomp/Makefile.am +++ b/libgomp/Makefile.am @@ -69,8 +69,8 @@ libgomp_la_SOURCES = alloc.c atomic.c barrier.c critical.c env.c error.c \ mutex.c proc.c sem.c bar.c ptrlock.c time.c fortran.c affinity.c \ target.c splay-tree.c libgomp-plugin.c oacc-parallel.c oacc-host.c \ oacc-init.c oacc-mem.c oacc-async.c oacc-plugin.c oacc-cuda.c \ - priority_queue.c affinity-fmt.c teams.c allocator.c oacc-profiling.c \ - oacc-target.c target-indirect.c target-cxa-dso-dtor.c + priority_queue.c affinity-fmt.c teams.c allocator.c simple-allocator.c \ + oacc-profiling.c oacc-target.c target-indirect.c target-cxa-dso-dtor.c include $(top_srcdir)/plugin/Makefrag.am diff --git a/libgomp/Makefile.in b/libgomp/Makefile.in index 8dc2ace..5f8a5f5 100644 --- a/libgomp/Makefile.in +++ b/libgomp/Makefile.in @@ -220,9 +220,9 @@ am_libgomp_la_OBJECTS = alloc.lo atomic.lo barrier.lo critical.lo \ affinity.lo target.lo splay-tree.lo libgomp-plugin.lo \ oacc-parallel.lo oacc-host.lo oacc-init.lo oacc-mem.lo \ oacc-async.lo oacc-plugin.lo oacc-cuda.lo priority_queue.lo \ - affinity-fmt.lo teams.lo allocator.lo oacc-profiling.lo \ - oacc-target.lo target-indirect.lo target-cxa-dso-dtor.lo \ - $(am__objects_1) + affinity-fmt.lo teams.lo allocator.lo simple-allocator.lo \ + oacc-profiling.lo oacc-target.lo target-indirect.lo \ + target-cxa-dso-dtor.lo $(am__objects_1) libgomp_la_OBJECTS = $(am_libgomp_la_OBJECTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) @@ -555,9 +555,9 @@ libgomp_la_SOURCES = alloc.c atomic.c barrier.c critical.c env.c \ fortran.c affinity.c target.c splay-tree.c libgomp-plugin.c \ oacc-parallel.c oacc-host.c oacc-init.c oacc-mem.c \ oacc-async.c oacc-plugin.c oacc-cuda.c priority_queue.c \ - affinity-fmt.c teams.c allocator.c oacc-profiling.c \ - oacc-target.c target-indirect.c target-cxa-dso-dtor.c \ - $(am__append_3) + affinity-fmt.c teams.c allocator.c simple-allocator.c \ + oacc-profiling.c oacc-target.c target-indirect.c \ + target-cxa-dso-dtor.c $(am__append_3) # Nvidia PTX OpenACC plugin. @PLUGIN_NVPTX_TRUE@libgomp_plugin_nvptx_version_info = -version-info $(libtool_VERSION) @@ -783,6 +783,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scope.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sections.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sem.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simple-allocator.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/single.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/splay-tree.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/target-cxa-dso-dtor.Plo@am__quote@ diff --git a/libgomp/basic-allocator.c b/libgomp/basic-allocator.c index 11804bb..9464e09 100644 --- a/libgomp/basic-allocator.c +++ b/libgomp/basic-allocator.c @@ -25,6 +25,11 @@ /* This is a basic "malloc" implementation intended for use with small, low-latency memories. + Compared to the "simple" allocator, this one is designed to keep the + metadata and heap together (no slow memory needed), and prioritize + space-efficiency over algorithm speed (the memory already being + low-latency). + To use this template, define BASIC_ALLOC_PREFIX, and then #include the source file. The other configuration macros are optional. diff --git a/libgomp/config/linux/allocator.c b/libgomp/config/linux/allocator.c index 8dea959..f957bb3 100644 --- a/libgomp/config/linux/allocator.c +++ b/libgomp/config/linux/allocator.c @@ -36,6 +36,11 @@ /* Implement malloc routines that can handle pinned memory on Linux. + Given that pinned memory is typically used to help host <-> device memory + transfers, we attempt to allocate such memory using a device (really: + libgomp plugin), but fall back to mmap plus mlock if no suitable device is + available. + It's possible to use mlock on any heap memory, but using munlock is problematic if there are multiple pinned allocations on the same page. Tracking all that manually would be possible, but adds overhead. This may @@ -48,50 +53,110 @@ #define _GNU_SOURCE #include <sys/mman.h> +#include <unistd.h> #include <string.h> +#include <assert.h> #include "libgomp.h" #ifdef HAVE_INTTYPES_H # include <inttypes.h> /* For PRIu64. */ #endif +static int using_device_for_page_locked + = /* uninitialized */ -1; + + +static gomp_simple_alloc_ctx_p pin_ctx = NULL; +static pthread_once_t ctxlock = PTHREAD_ONCE_INIT; + +static void +linux_init_pin_ctx () +{ + pin_ctx = gomp_simple_alloc_init_context (); +} + static void * -linux_memspace_alloc (omp_memspace_handle_t memspace, size_t size, int pin) +linux_memspace_alloc (omp_memspace_handle_t memspace, size_t size, int pin, + bool init0) { - (void)memspace; + void *addr = NULL; if (pin) { - /* Note that mmap always returns zeroed memory and is therefore also a - suitable implementation of calloc. */ - void *addr = mmap (NULL, size, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - if (addr == MAP_FAILED) - return NULL; - - if (mlock (addr, size)) + int using_device = __atomic_load_n (&using_device_for_page_locked, + MEMMODEL_RELAXED); + if (using_device != 0) + { + using_device = gomp_page_locked_host_alloc (&addr, size); + int using_device_old + = __atomic_exchange_n (&using_device_for_page_locked, + using_device, MEMMODEL_RELAXED); + assert (using_device_old == -1 + /* We shouldn't have concurrently changed our mind. */ + || using_device_old == using_device); + } + if (using_device == 0) { + static int pagesize = 0; + static void *addrhint = NULL; + + if (!pagesize) + pagesize = sysconf(_SC_PAGE_SIZE); + + while (1) + { + addr = gomp_simple_alloc (pin_ctx, size); + if (addr) + break; + + /* Round up to a whole page. */ + size_t misalignment = size % pagesize; + size_t mmap_size = (misalignment > 0 + ? size + pagesize - misalignment + : size); + void *newpage = mmap (addrhint, mmap_size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (newpage == MAP_FAILED) + break; + else + { + if (mlock (newpage, size)) + { #ifdef HAVE_INTTYPES_H - gomp_debug (0, "libgomp: failed to pin %"PRIu64" bytes of" - " memory (ulimit too low?)\n", (uint64_t) size); + gomp_debug (0, "libgomp: failed to pin %"PRIu64" bytes" + " of memory (ulimit too low?)\n", + (uint64_t) size); #else - gomp_debug (0, "libgomp: failed to pin %lu bytes of" - " memory (ulimit too low?)\n", (unsigned long) size); + gomp_debug (0, "libgomp: failed to pin %lu bytes of" + " memory (ulimit too low?)\n", + (unsigned long) size); #endif - munmap (addr, size); - return NULL; - } + munmap (newpage, size); + break; + } - return addr; + addrhint = newpage + mmap_size; + + pthread_once (&ctxlock, linux_init_pin_ctx); + gomp_simple_alloc_register_memory (pin_ctx, newpage, + mmap_size); + } + } + } } else - return malloc (size); + addr = malloc (size); + + if (addr && init0) + memset (addr, 0, size); + + return addr; } static void * linux_memspace_calloc (omp_memspace_handle_t memspace, size_t size, int pin) { if (pin) - return linux_memspace_alloc (memspace, size, pin); + return linux_memspace_alloc (memspace, size, pin, true); else return calloc (1, size); } @@ -100,10 +165,19 @@ static void linux_memspace_free (omp_memspace_handle_t memspace, void *addr, size_t size, int pin) { - (void)memspace; - if (pin) - munmap (addr, size); + { + int using_device + = __atomic_load_n (&using_device_for_page_locked, + MEMMODEL_RELAXED); + if (using_device == 1) + gomp_page_locked_host_free (addr); + else + /* The "simple" allocator does not (currently) munmap locked pages + (meaning that the number of locked pages never decreases), but it + can reuse the freed memory in subsequent gomp_simple_alloc calls. */ + gomp_simple_free (pin_ctx, addr); + } else free (addr); } @@ -114,25 +188,34 @@ linux_memspace_realloc (omp_memspace_handle_t memspace, void *addr, { if (oldpin && pin) { - void *newaddr = mremap (addr, oldsize, size, MREMAP_MAYMOVE); - if (newaddr == MAP_FAILED) - return NULL; - - return newaddr; - } - else if (oldpin || pin) - { - void *newaddr = linux_memspace_alloc (memspace, size, pin); - if (newaddr) + int using_device + = __atomic_load_n (&using_device_for_page_locked, + MEMMODEL_RELAXED); + /* The device plugin API does not support realloc, + but the gomp_simple_alloc allocator does. */ + if (using_device == 0) { - memcpy (newaddr, addr, oldsize < size ? oldsize : size); - linux_memspace_free (memspace, addr, oldsize, oldpin); + /* This can fail if there is insufficient pinned memory free. */ + void *newaddr = gomp_simple_realloc (pin_ctx, addr, size); + if (newaddr) + return newaddr; } - - return newaddr; } + else if (oldpin || pin) + /* Moving from pinned to unpinned memory cannot be done in-place. */ + ; else return realloc (addr, size); + + /* In-place reallocation failed. Fall back to copy. */ + void *newaddr = linux_memspace_alloc (memspace, size, pin, false); + if (newaddr) + { + memcpy (newaddr, addr, oldsize < size ? oldsize : size); + linux_memspace_free (memspace, addr, oldsize, oldpin); + } + + return newaddr; } static int @@ -143,7 +226,7 @@ linux_memspace_validate (omp_memspace_handle_t, unsigned, int) } #define MEMSPACE_ALLOC(MEMSPACE, SIZE, PIN) \ - linux_memspace_alloc (MEMSPACE, SIZE, PIN) + linux_memspace_alloc (MEMSPACE, SIZE, PIN, false) #define MEMSPACE_CALLOC(MEMSPACE, SIZE, PIN) \ linux_memspace_calloc (MEMSPACE, SIZE, PIN) #define MEMSPACE_REALLOC(MEMSPACE, ADDR, OLDSIZE, SIZE, OLDPIN, PIN) \ diff --git a/libgomp/libgomp-plugin.h b/libgomp/libgomp-plugin.h index f3823c0..f2baed9 100644 --- a/libgomp/libgomp-plugin.h +++ b/libgomp/libgomp-plugin.h @@ -171,6 +171,8 @@ extern int GOMP_OFFLOAD_load_image (int, unsigned, const void *, extern bool GOMP_OFFLOAD_unload_image (int, unsigned, const void *); extern void *GOMP_OFFLOAD_alloc (int, size_t); extern bool GOMP_OFFLOAD_free (int, void *); +extern bool GOMP_OFFLOAD_page_locked_host_alloc (void **, size_t); +extern bool GOMP_OFFLOAD_page_locked_host_free (void *); extern bool GOMP_OFFLOAD_dev2host (int, void *, const void *, size_t); extern bool GOMP_OFFLOAD_host2dev (int, void *, const void *, size_t); extern bool GOMP_OFFLOAD_dev2dev (int, void *, const void *, size_t); diff --git a/libgomp/libgomp.h b/libgomp/libgomp.h index a433983..3d406be 100644 --- a/libgomp/libgomp.h +++ b/libgomp/libgomp.h @@ -1135,6 +1135,8 @@ extern int gomp_get_num_devices (void); extern bool gomp_target_task_fn (void *); extern void gomp_target_rev (uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, int, struct goacc_asyncqueue *); +extern bool gomp_page_locked_host_alloc (void **, size_t); +extern void gomp_page_locked_host_free (void *); /* Splay tree definitions. */ typedef struct splay_tree_node_s *splay_tree_node; @@ -1419,6 +1421,8 @@ struct gomp_device_descr __typeof (GOMP_OFFLOAD_unload_image) *unload_image_func; __typeof (GOMP_OFFLOAD_alloc) *alloc_func; __typeof (GOMP_OFFLOAD_free) *free_func; + __typeof (GOMP_OFFLOAD_page_locked_host_alloc) *page_locked_host_alloc_func; + __typeof (GOMP_OFFLOAD_page_locked_host_free) *page_locked_host_free_func; __typeof (GOMP_OFFLOAD_dev2host) *dev2host_func; __typeof (GOMP_OFFLOAD_host2dev) *host2dev_func; __typeof (GOMP_OFFLOAD_dev2dev) *dev2dev_func; @@ -1668,4 +1672,16 @@ gomp_thread_to_pthread_t (struct gomp_thread *thr) } #endif +/* simple-allocator.c */ + +typedef struct gomp_simple_alloc_context *gomp_simple_alloc_ctx_p; + +gomp_simple_alloc_ctx_p gomp_simple_alloc_init_context (); +void gomp_simple_alloc_register_memory (gomp_simple_alloc_ctx_p ctx, + char *base, size_t size); +void *gomp_simple_alloc (gomp_simple_alloc_ctx_p ctx, size_t size); +void gomp_simple_free (gomp_simple_alloc_ctx_p ctx, void *addr); +void *gomp_simple_realloc (gomp_simple_alloc_ctx_p ctx, void *addr, + size_t newsize); + #endif /* LIBGOMP_H */ diff --git a/libgomp/libgomp.texi b/libgomp/libgomp.texi index 62b04af..76a0162 100644 --- a/libgomp/libgomp.texi +++ b/libgomp/libgomp.texi @@ -7013,11 +7013,12 @@ a @code{nearest} allocation. Additional notes regarding the traits: @itemize -@item The @code{pinned} trait is supported on Linux hosts, but is subject to - the OS @code{ulimit}/@code{rlimit} locked memory settings. It currently - uses @code{mmap} and is therefore optimized for few allocations, including - large data. If the conditions for numa or memkind allocations are - fulfilled, those allocators are used instead. +@item The @code{pinned} trait is supported on Linux hosts, but is usually + subject to the OS @code{ulimit}/@code{rlimit} locked memory settings (see + @ref{Offload-Target Specifics} for exceptions). The implementation + uses a custom allocator to try to use as few memory pages as possible. + At present, freed pinned memory is not returned to the OS (although it + may be reused by subsequent pinned allocations). @item The default for the @code{pool_size} trait is no pool and for every (re)allocation the associated library routine is called, which might internally use a memory pool. Currently, the same applies when a @@ -7128,6 +7129,12 @@ The implementation remark: @code{omp_thread_mem_alloc}, all use low-latency memory as first preference, and fall back to main graphics memory when the low-latency pool is exhausted. +@item Pinned memory allocated using @code{omp_alloc} with the + @code{ompx_gnu_pinned_mem_alloc} allocator or the @code{pinned} trait is + obtained via the CUDA API when an NVPTX device is present. This provides + a performance boost for NVPTX offload code and also allows unlimited use + of pinned memory regardless of the OS @code{ulimit}/@code{rlimit} + settings. @item The OpenMP routines @code{omp_target_memcpy_rect} and @code{omp_target_memcpy_rect_async} and the @code{target update} directive for non-contiguous list items use the 3D memory-copy function diff --git a/libgomp/plugin/plugin-nvptx.c b/libgomp/plugin/plugin-nvptx.c index 92c62ee..5ad6668 100644 --- a/libgomp/plugin/plugin-nvptx.c +++ b/libgomp/plugin/plugin-nvptx.c @@ -1886,6 +1886,39 @@ GOMP_OFFLOAD_free (int ord, void *ptr) && nvptx_free (ptr, ptx_devices[ord])); } +bool +GOMP_OFFLOAD_page_locked_host_alloc (void **ptr, size_t size) +{ + if (size == 0) + { + /* Special case to ensure omp_alloc specification compliance. */ + *ptr = NULL; + return true; + } + + CUresult r; + + unsigned int flags = 0; + /* Given 'CU_DEVICE_ATTRIBUTE_UNIFIED_ADDRESSING', we don't need + 'flags |= CU_MEMHOSTALLOC_PORTABLE;' here. */ + r = CUDA_CALL_NOCHECK (cuMemHostAlloc, ptr, size, flags); + if (r == CUDA_ERROR_OUT_OF_MEMORY) + *ptr = NULL; + else if (r != CUDA_SUCCESS) + { + GOMP_PLUGIN_error ("cuMemHostAlloc error: %s", cuda_error (r)); + return false; + } + return true; +} + +bool +GOMP_OFFLOAD_page_locked_host_free (void *ptr) +{ + CUDA_CALL (cuMemFreeHost, ptr); + return true; +} + void GOMP_OFFLOAD_openacc_exec (void (*fn) (void *), size_t mapnum __attribute__((unused)), diff --git a/libgomp/simple-allocator.c b/libgomp/simple-allocator.c new file mode 100644 index 0000000..531bd18 --- /dev/null +++ b/libgomp/simple-allocator.c @@ -0,0 +1,315 @@ +/* Copyright (C) 2025 Free Software Foundation, Inc. + + This file is part of the GNU Offloading and Multi Processing Library + (libgomp). + + Libgomp is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +/* This is a simple "malloc" implementation intended for use with device + Managed Memory and Pinned Memory. It allocates memory from a pool allocated + and configured by the device plugin, or the OS-specific allocator + (for pinned). + + Unlike the "basic" allocator, this implementation keeps the allocated/free + chain in a side-table (splay tree) to ensure that the allocation routine + does not have the side-effect of migrating all the managed memory pages back + into host memory. Keeping the meta-data elsewhere is also useful for pinned + memory, which is typically an extremely limited resource. */ + +#include <string.h> +#include "libgomp.h" + +/* Use a splay tree to track allocations. */ + +typedef struct simple_alloc_splay_tree_node_s *simple_alloc_splay_tree_node; +typedef struct simple_alloc_splay_tree_s *simple_alloc_splay_tree; +typedef struct simple_alloc_splay_tree_key_s *simple_alloc_splay_tree_key; + +struct simple_alloc_splay_tree_key_s { + void *base; + size_t size; +}; + +static inline int +simple_alloc_splay_compare (simple_alloc_splay_tree_key x, + simple_alloc_splay_tree_key y) +{ + return (x->base == y->base ? 0 + : x->base > y->base ? 1 + : -1); +} + +#define splay_tree_prefix simple_alloc +#include "splay-tree.h" + +/* 128-byte granularity means GPU cache-line aligned. */ +#define ALIGN(VAR) (((VAR) + 127) & ~127) + +/* The context data prevents the need for global state. */ +struct gomp_simple_alloc_context { + struct simple_alloc_splay_tree_s allocations; + struct simple_alloc_splay_tree_s free_space; + gomp_mutex_t lock; +}; + +gomp_simple_alloc_ctx_p +gomp_simple_alloc_init_context () +{ + return calloc (1, sizeof (struct gomp_simple_alloc_context)); +} + +/* Coalesce contiguous free space into one entry. This considers the entries + either side of the root node only, so it should be called each time a new + entry in inserted into the root. */ + +static void +simple_alloc_coalesce_free_space (gomp_simple_alloc_ctx_p ctx) +{ + simple_alloc_splay_tree_node prev, next, node = ctx->free_space.root; + + for (prev = node->left; prev && prev->right; prev = prev->right) + ; + for (next = node->right; next && next->left; next = next->left) + ; + + /* Coalesce adjacent free chunks. */ + if (next + && node->key.base + node->key.size == next->key.base) + { + /* Free chunk follows. */ + node->key.size += next->key.size; + simple_alloc_splay_tree_remove (&ctx->free_space, &next->key); + free (next); + } + if (prev + && prev->key.base + prev->key.size == node->key.base) + { + /* Free chunk precedes. */ + prev->key.size += node->key.size; + simple_alloc_splay_tree_remove (&ctx->free_space, &node->key); + free (node); + } +} + +/* Add a new memory region into the free chain. This is how our heap is + initialized and extended (using memory acquired by an external caller). If + the new region is contiguous with an existing region then any free space + will be coalesced. */ + +void +gomp_simple_alloc_register_memory (gomp_simple_alloc_ctx_p ctx, char *base, + size_t size) +{ + if (base == NULL || ctx == NULL) + return; + + gomp_mutex_lock (&ctx->lock); + + simple_alloc_splay_tree_node node; + node = malloc (sizeof (struct simple_alloc_splay_tree_node_s)); + node->key.base = base; + node->key.size = size; + node->left = NULL; + node->right = NULL; + simple_alloc_splay_tree_insert (&ctx->free_space, node); + simple_alloc_coalesce_free_space (ctx); + + gomp_mutex_unlock (&ctx->lock); +} + +/* This splay_tree_foreach callback selects the first free space large enough + to hold the allocation needed. Since the splay_tree walk may start in the + middle the "first" isn't necessarily the "leftmost" entry. */ + +struct simple_alloc_callback_data { + size_t size; + simple_alloc_splay_tree_node found; +}; + +static int +simple_alloc_callback (simple_alloc_splay_tree_key key, void *data) +{ + struct simple_alloc_callback_data *cbd + = (struct simple_alloc_callback_data *)data; + + if (key->size >= cbd->size) + { + cbd->found = (simple_alloc_splay_tree_node)key; + return 1; + } + + return 0; +} + +/* Simple "malloc". Selects and moves and address range from ctx->free_space to + ctx->allocations, while leaving any excess in ctx->free_space. */ + +void * +gomp_simple_alloc (gomp_simple_alloc_ctx_p ctx, size_t size) +{ + if (ctx == NULL) + return NULL; + + /* Memory is allocated in N-byte granularity. */ + size = ALIGN (size); + + gomp_mutex_lock (&ctx->lock); + + if (!ctx->free_space.root) + { + /* No memory registered, or no free space. */ + gomp_mutex_unlock (&ctx->lock); + return NULL; + } + + /* Find a suitable free block. */ + struct simple_alloc_callback_data cbd = {size, NULL}; + simple_alloc_splay_tree_foreach_lazy (&ctx->free_space, + simple_alloc_callback, &cbd); + simple_alloc_splay_tree_node freenode = cbd.found; + + void *result = NULL; + if (freenode) + { + /* Allocation successful. */ + result = freenode->key.base; + simple_alloc_splay_tree_node allocnode = malloc (sizeof (*allocnode)); + allocnode->key.base = result; + allocnode->key.size = size; + allocnode->left = NULL; + allocnode->right = NULL; + simple_alloc_splay_tree_insert (&ctx->allocations, allocnode); + + /* Update the free chain. */ + size_t stillfree_size = freenode->key.size - size; + if (stillfree_size > 0) + { + freenode->key.base = freenode->key.base + size; + freenode->key.size = stillfree_size; + } + else + { + simple_alloc_splay_tree_remove (&ctx->free_space, &freenode->key); + free (freenode); + } + } + + gomp_mutex_unlock (&ctx->lock); + + return result; +} + +/* Simple "free". Moves an address range from ctx->allocations to + ctx->free_space and merges that record with any contiguous free memory. */ + +void +gomp_simple_free (gomp_simple_alloc_ctx_p ctx, void *addr) +{ + if (ctx == NULL) + return; + + gomp_mutex_lock (&ctx->lock); + + /* Convert the memory map to free. */ + struct simple_alloc_splay_tree_key_s key = {addr}; + simple_alloc_splay_tree_key found + = simple_alloc_splay_tree_lookup (&ctx->allocations, &key); + if (!found) + GOMP_PLUGIN_fatal ("invalid free"); + simple_alloc_splay_tree_remove (&ctx->allocations, &key); + simple_alloc_splay_tree_insert (&ctx->free_space, + (simple_alloc_splay_tree_node)found); + simple_alloc_coalesce_free_space (ctx); + + gomp_mutex_unlock (&ctx->lock); +} + +/* Simple "realloc". Works in-place, if possible; reallocates otherwise. */ + +void * +gomp_simple_realloc (gomp_simple_alloc_ctx_p ctx, void *addr, size_t newsize) +{ + if (ctx == NULL) + return NULL; + + newsize = ALIGN (newsize); + + gomp_mutex_lock (&ctx->lock); + + /* Convert the memory map to free. */ + struct simple_alloc_splay_tree_key_s key = {addr}; + simple_alloc_splay_tree_key found + = simple_alloc_splay_tree_lookup (&ctx->allocations, &key); + if (!found) + GOMP_PLUGIN_fatal ("invalid realloc"); + + if (newsize == found->size) + ; /* Nothing to do. */ + else if (newsize < found->size) + { + /* We're reducing the allocation size. */ + simple_alloc_splay_tree_node newfree = malloc (sizeof (*newfree)); + newfree->key.base = found->base + newsize; + newfree->key.size = found->size - newsize; + newfree->left = NULL; + newfree->right = NULL; + simple_alloc_splay_tree_insert (&ctx->free_space, newfree); + simple_alloc_coalesce_free_space (ctx); + } + else + { + /* We're extending the allocation. */ + struct simple_alloc_splay_tree_key_s freekey = {addr + found->size}; + simple_alloc_splay_tree_key foundfree; + foundfree = simple_alloc_splay_tree_lookup (&ctx->free_space, &freekey); + if (foundfree && foundfree->size >= newsize - found->size) + { + /* Allocation can be expanded in place. */ + foundfree->base += found->size; + foundfree->size -= newsize - found->size; + found->size = newsize; + + if (foundfree->size == 0) + simple_alloc_splay_tree_remove (&ctx->free_space, &freekey); + } + else + { + /* Allocation must be relocated. + Release the lock and use alloc/free. */ + gomp_mutex_unlock (&ctx->lock); + + void *newaddr = gomp_simple_alloc (ctx, newsize); + if (!newaddr) + return NULL; + + memcpy (newaddr, addr, found->size); + gomp_simple_free (ctx, addr); + return newaddr; + } + } + + gomp_mutex_unlock (&ctx->lock); + return addr; +} + +/* Include the splay tree code inline, with the prefixes added. */ +#define splay_tree_prefix simple_alloc +#define splay_tree_c +#include "splay-tree.h" diff --git a/libgomp/target.c b/libgomp/target.c index c89c82c..ac5b4b0 100644 --- a/libgomp/target.c +++ b/libgomp/target.c @@ -4697,6 +4697,117 @@ omp_target_free (void *device_ptr, int device_num) gomp_mutex_unlock (&devicep->lock); } +/* Device (really: libgomp plugin) to use for paged-locked memory. We + assume there is either none or exactly one such device for the lifetime of + the process. */ + +static struct gomp_device_descr *device_for_page_locked + = /* uninitialized */ (void *) -1; + +static struct gomp_device_descr * +get_device_for_page_locked (void) +{ + struct gomp_device_descr *device; +#ifdef HAVE_SYNC_BUILTINS + device + = __atomic_load_n (&device_for_page_locked, MEMMODEL_RELAXED); + if (device == (void *) -1) + { + gomp_init_targets_once (); + + device = NULL; + for (int i = 0; i < num_devices; ++i) + { + /* We consider only the first device of potentially several of the + same type as this functionality is not specific to an individual + offloading device, but instead relates to the host-side + implementation of the respective offloading implementation. */ + if (devices[i].target_id != 0) + continue; + + if (!devices[i].page_locked_host_alloc_func) + continue; + + if (device) + gomp_fatal ("Unclear how %s and %s libgomp plugins may" + " simultaneously provide functionality" + " for page-locked memory", + device->name, devices[i].name); + + device = &devices[i]; + gomp_debug (0, "Using device %s for page-locked memory\n", + device->name); + } + + struct gomp_device_descr *device_old + = __atomic_exchange_n (&device_for_page_locked, device, + MEMMODEL_RELAXED); + assert (device_old == (void *) -1 + /* We shouldn't have concurrently found a different or no + device. */ + || device_old == device); + } +#else /* !HAVE_SYNC_BUILTINS */ + (void) &device_for_page_locked; + device = NULL; +#endif /* HAVE_SYNC_BUILTINS */ + + return device; +} + +/* Allocate page-locked host memory. + Returns whether we have a device capable of that. */ + +attribute_hidden bool +gomp_page_locked_host_alloc (void **ptr, size_t size) +{ + struct gomp_device_descr *device = get_device_for_page_locked (); + if (device) + { + gomp_mutex_lock (&device->lock); + if (device->state == GOMP_DEVICE_UNINITIALIZED) + gomp_init_device (device); + else if (device->state == GOMP_DEVICE_FINALIZED) + { + gomp_mutex_unlock (&device->lock); + gomp_fatal ("Device %s used for page-locked memory is finalized", + device->name); + } + gomp_mutex_unlock (&device->lock); + + if (!device->page_locked_host_alloc_func (ptr, size)) + gomp_fatal ("Failed to allocate page-locked host memory" + " via %s libgomp plugin", + device->name); + } + return device != NULL; +} + +/* Free page-locked host memory. + This must only be called if 'gomp_page_locked_host_alloc' returned + 'true'. */ + +attribute_hidden void +gomp_page_locked_host_free (void *ptr) +{ + struct gomp_device_descr *device = get_device_for_page_locked (); + assert (device); + + gomp_mutex_lock (&device->lock); + assert (device->state != GOMP_DEVICE_UNINITIALIZED); + if (device->state == GOMP_DEVICE_FINALIZED) + { + gomp_mutex_unlock (&device->lock); + return; + } + gomp_mutex_unlock (&device->lock); + + if (!device->page_locked_host_free_func (ptr)) + gomp_fatal ("Failed to free page-locked host memory" + " via %s libgomp plugin", + device->name); +} + int omp_target_is_present (const void *ptr, int device_num) { @@ -5818,6 +5929,8 @@ gomp_load_plugin_for_device (struct gomp_device_descr *device, DLSYM (unload_image); DLSYM (alloc); DLSYM (free); + DLSYM_OPT (page_locked_host_alloc, page_locked_host_alloc); + DLSYM_OPT (page_locked_host_free, page_locked_host_free); DLSYM (dev2host); DLSYM (host2dev); DLSYM_OPT (memcpy2d, memcpy2d); diff --git a/libgomp/testsuite/libgomp.c/alloc-pinned-1.c b/libgomp/testsuite/libgomp.c/alloc-pinned-1.c index 672f245..693f903 100644 --- a/libgomp/testsuite/libgomp.c/alloc-pinned-1.c +++ b/libgomp/testsuite/libgomp.c/alloc-pinned-1.c @@ -2,6 +2,8 @@ /* { dg-skip-if "Pinning not implemented on this host" { ! *-*-linux-gnu* } } */ +/* { dg-additional-options -DOFFLOAD_DEVICE_NVPTX { target offload_device_nvptx } } */ + /* Test that pinned memory works. */ #include <stdio.h> @@ -63,10 +65,16 @@ verify0 (char *p, size_t s) int main () { +#ifdef OFFLOAD_DEVICE_NVPTX + /* Go big or go home. + The OS ulimit does not affect memory locked via CUDA for NVPTX devices. */ + const int SIZE = 40 * 1024 * 1024; +#else /* Allocate at least a page each time, allowing space for overhead, but stay within the ulimit. */ const int SIZE = PAGE_SIZE - 128; CHECK_SIZE (SIZE * 5); // This is intended to help diagnose failures +#endif const omp_alloctrait_t traits[] = { { omp_atk_pinned, 1 } @@ -88,21 +96,39 @@ main () abort (); int amount = get_pinned_mem (); +#ifdef OFFLOAD_DEVICE_NVPTX + /* This doesn't show up as process 'VmLck'ed memory. */ + if (amount != 0) + abort (); +#else if (amount == 0) abort (); +#endif p = omp_realloc (p, SIZE * 2, allocator, allocator); int amount2 = get_pinned_mem (); +#ifdef OFFLOAD_DEVICE_NVPTX + /* This doesn't show up as process 'VmLck'ed memory. */ + if (amount2 != 0) + abort (); +#else if (amount2 <= amount) abort (); +#endif /* SIZE*2 ensures that it doesn't slot into the space possibly vacated by realloc. */ p = omp_calloc (1, SIZE * 2, allocator); +#ifdef OFFLOAD_DEVICE_NVPTX + /* This doesn't show up as process 'VmLck'ed memory. */ + if (get_pinned_mem () != 0) + abort (); +#else if (get_pinned_mem () <= amount2) abort (); +#endif verify0 (p, SIZE * 2); diff --git a/libgomp/testsuite/libgomp.c/alloc-pinned-2.c b/libgomp/testsuite/libgomp.c/alloc-pinned-2.c index b6d1d83..e7ac64e 100644 --- a/libgomp/testsuite/libgomp.c/alloc-pinned-2.c +++ b/libgomp/testsuite/libgomp.c/alloc-pinned-2.c @@ -2,6 +2,8 @@ /* { dg-skip-if "Pinning not implemented on this host" { ! *-*-linux-gnu* } } */ +/* { dg-additional-options -DOFFLOAD_DEVICE_NVPTX { target offload_device_nvptx } } */ + /* Test that pinned memory works (pool_size code path). */ #include <stdio.h> @@ -63,10 +65,16 @@ verify0 (char *p, size_t s) int main () { +#ifdef OFFLOAD_DEVICE_NVPTX + /* Go big or go home. + The OS ulimit does not affect memory locked via CUDA for NVPTX devices. */ + const int SIZE = 40 * 1024 * 1024; +#else /* Allocate at least a page each time, allowing space for overhead, but stay within the ulimit. */ const int SIZE = PAGE_SIZE - 128; CHECK_SIZE (SIZE * 5); // This is intended to help diagnose failures +#endif const omp_alloctrait_t traits[] = { { omp_atk_pinned, 1 }, @@ -89,16 +97,28 @@ main () abort (); int amount = get_pinned_mem (); +#ifdef OFFLOAD_DEVICE_NVPTX + /* This doesn't show up as process 'VmLck'ed memory. */ + if (amount != 0) + abort (); +#else if (amount == 0) abort (); +#endif p = omp_realloc (p, SIZE * 2, allocator, allocator); if (!p) abort (); int amount2 = get_pinned_mem (); +#ifdef OFFLOAD_DEVICE_NVPTX + /* This doesn't show up as process 'VmLck'ed memory. */ + if (amount2 != 0) + abort (); +#else if (amount2 <= amount) abort (); +#endif /* SIZE*2 ensures that it doesn't slot into the space possibly vacated by realloc. */ @@ -106,8 +126,14 @@ main () if (!p) abort (); +#ifdef OFFLOAD_DEVICE_NVPTX + /* This doesn't show up as process 'VmLck'ed memory. */ + if (get_pinned_mem () != 0) + abort (); +#else if (get_pinned_mem () <= amount2) abort (); +#endif verify0 (p, SIZE * 2); diff --git a/libgomp/testsuite/libgomp.c/alloc-pinned-3.c b/libgomp/testsuite/libgomp.c/alloc-pinned-3.c index 11dc818..250cb55 100644 --- a/libgomp/testsuite/libgomp.c/alloc-pinned-3.c +++ b/libgomp/testsuite/libgomp.c/alloc-pinned-3.c @@ -1,5 +1,7 @@ /* { dg-do run } */ +/* { dg-additional-options -DOFFLOAD_DEVICE_NVPTX { target offload_device_nvptx } } */ + /* Test that pinned memory fails correctly. */ #include <stdio.h> @@ -75,8 +77,15 @@ verify0 (char *p, size_t s) int main () { +#ifdef OFFLOAD_DEVICE_NVPTX + /* Go big or go home. + The OS ulimit does not affect memory locked via CUDA for NVPTX devices. */ + const int SIZE = 40 * 1024 * 1024; +#else /* This needs to be large enough to cover multiple pages. */ const int SIZE = PAGE_SIZE * 4; +#endif + const int PIN_LIMIT = PAGE_SIZE * 2; /* Pinned memory, no fallback. */ const omp_alloctrait_t traits1[] = { @@ -101,23 +110,34 @@ main () #endif /* Ensure that the limit is smaller than the allocation. */ - set_pin_limit (SIZE / 2); + set_pin_limit (PIN_LIMIT); // Sanity check if (get_pinned_mem () != 0) abort (); - // Should fail void *p1 = omp_alloc (SIZE, allocator1); +#ifdef OFFLOAD_DEVICE_NVPTX + // Doesn't care about 'set_pin_limit'. + if (!p1) + abort (); +#else + // Should fail if (p1) abort (); +#endif - // Should fail void *p2 = omp_calloc (1, SIZE, allocator1); +#ifdef OFFLOAD_DEVICE_NVPTX + // Doesn't care about 'set_pin_limit'. + if (!p2) + abort (); +#else + // Should fail if (p2) abort (); +#endif - // Should fall back void *p3 = omp_alloc (SIZE, allocator2); if (!p3) abort (); @@ -128,16 +148,29 @@ main () abort (); verify0 (p4, SIZE); - // Should fail to realloc void *notpinned = omp_alloc (SIZE, omp_default_mem_alloc); void *p5 = omp_realloc (notpinned, SIZE, allocator1, omp_default_mem_alloc); +#ifdef OFFLOAD_DEVICE_NVPTX + // Doesn't care about 'set_pin_limit'; does reallocate. + if (!notpinned || !p5 || p5 == notpinned) + abort (); +#else + // Should fail to realloc if (!notpinned || p5) abort (); +#endif - // Should fall back to no realloc needed +#ifdef OFFLOAD_DEVICE_NVPTX + void *p6 = omp_realloc (p5, SIZE, allocator2, allocator1); + // Does reallocate. + if (p5 == p6) + abort (); +#else void *p6 = omp_realloc (notpinned, SIZE, allocator2, omp_default_mem_alloc); + // Should fall back to no realloc needed if (p6 != notpinned) abort (); +#endif // No memory should have been pinned int amount = get_pinned_mem (); diff --git a/libgomp/testsuite/libgomp.c/alloc-pinned-4.c b/libgomp/testsuite/libgomp.c/alloc-pinned-4.c index 2ecd01f..b7a9966 100644 --- a/libgomp/testsuite/libgomp.c/alloc-pinned-4.c +++ b/libgomp/testsuite/libgomp.c/alloc-pinned-4.c @@ -1,5 +1,7 @@ /* { dg-do run } */ +/* { dg-additional-options -DOFFLOAD_DEVICE_NVPTX { target offload_device_nvptx } } */ + /* Test that pinned memory fails correctly, pool_size code path. */ #include <stdio.h> @@ -75,8 +77,15 @@ verify0 (char *p, size_t s) int main () { +#ifdef OFFLOAD_DEVICE_NVPTX + /* Go big or go home. + The OS ulimit does not affect memory locked via CUDA for NVPTX devices. */ + const int SIZE = 40 * 1024 * 1024; +#else /* This needs to be large enough to cover multiple pages. */ const int SIZE = PAGE_SIZE * 4; +#endif + const int PIN_LIMIT = PAGE_SIZE * 2; /* Pinned memory, no fallback. */ const omp_alloctrait_t traits1[] = { @@ -103,21 +112,33 @@ main () #endif /* Ensure that the limit is smaller than the allocation. */ - set_pin_limit (SIZE / 2); + set_pin_limit (PIN_LIMIT); // Sanity check if (get_pinned_mem () != 0) abort (); - // Should fail void *p = omp_alloc (SIZE, allocator1); +#ifdef OFFLOAD_DEVICE_NVPTX + // Doesn't care about 'set_pin_limit'. + if (!p) + abort (); +#else + // Should fail if (p) abort (); +#endif - // Should fail p = omp_calloc (1, SIZE, allocator1); +#ifdef OFFLOAD_DEVICE_NVPTX + // Doesn't care about 'set_pin_limit'. + if (!p) + abort (); +#else + // Should fail if (p) abort (); +#endif // Should fall back p = omp_alloc (SIZE, allocator2); @@ -130,16 +151,29 @@ main () abort (); verify0 (p, SIZE); - // Should fail to realloc void *notpinned = omp_alloc (SIZE, omp_default_mem_alloc); p = omp_realloc (notpinned, SIZE, allocator1, omp_default_mem_alloc); +#ifdef OFFLOAD_DEVICE_NVPTX + // Doesn't care about 'set_pin_limit'; does reallocate. + if (!notpinned || !p || p == notpinned) + abort (); +#else + // Should fail to realloc if (!notpinned || p) abort (); +#endif - // Should fall back to no realloc needed +#ifdef OFFLOAD_DEVICE_NVPTX + void *p_ = omp_realloc (p, SIZE, allocator2, allocator1); + // Does reallocate. + if (p_ == p) + abort (); +#else p = omp_realloc (notpinned, SIZE, allocator2, omp_default_mem_alloc); + // Should fall back to no realloc needed if (p != notpinned) abort (); +#endif // No memory should have been pinned int amount = get_pinned_mem (); diff --git a/libgomp/testsuite/libgomp.c/alloc-pinned-5.c b/libgomp/testsuite/libgomp.c/alloc-pinned-5.c index 0ba2feb..cc77764 100644 --- a/libgomp/testsuite/libgomp.c/alloc-pinned-5.c +++ b/libgomp/testsuite/libgomp.c/alloc-pinned-5.c @@ -2,6 +2,8 @@ /* { dg-skip-if "Pinning not implemented on this host" { ! *-*-linux-gnu* } } */ +/* { dg-additional-options -DOFFLOAD_DEVICE_NVPTX { target offload_device_nvptx } } */ + /* Test that ompx_gnu_pinned_mem_alloc works. */ #include <stdio.h> @@ -63,10 +65,16 @@ verify0 (char *p, size_t s) int main () { +#ifdef OFFLOAD_DEVICE_NVPTX + /* Go big or go home. + The OS ulimit does not affect memory locked via CUDA for NVPTX devices. */ + const int SIZE = 40 * 1024 * 1024; +#else /* Allocate at least a page each time, allowing space for overhead, but stay within the ulimit. */ const int SIZE = PAGE_SIZE - 128; CHECK_SIZE (SIZE * 5); +#endif // Sanity check if (get_pinned_mem () != 0) @@ -77,22 +85,40 @@ main () abort (); int amount = get_pinned_mem (); +#ifdef OFFLOAD_DEVICE_NVPTX + /* This doesn't show up as process 'VmLck'ed memory. */ + if (amount != 0) + abort (); +#else if (amount == 0) abort (); +#endif p = omp_realloc (p, SIZE * 2, ompx_gnu_pinned_mem_alloc, ompx_gnu_pinned_mem_alloc); int amount2 = get_pinned_mem (); +#ifdef OFFLOAD_DEVICE_NVPTX + /* This doesn't show up as process 'VmLck'ed memory. */ + if (amount2 != 0) + abort (); +#else if (amount2 <= amount) abort (); +#endif /* SIZE*2 ensures that it doesn't slot into the space possibly vacated by realloc. */ p = omp_calloc (1, SIZE * 2, ompx_gnu_pinned_mem_alloc); +#ifdef OFFLOAD_DEVICE_NVPTX + /* This doesn't show up as process 'VmLck'ed memory. */ + if (get_pinned_mem () != 0) + abort (); +#else if (get_pinned_mem () <= amount2) abort (); +#endif verify0 (p, SIZE * 2); diff --git a/libgomp/testsuite/libgomp.c/alloc-pinned-6.c b/libgomp/testsuite/libgomp.c/alloc-pinned-6.c index 99f1269..6dd5544 100644 --- a/libgomp/testsuite/libgomp.c/alloc-pinned-6.c +++ b/libgomp/testsuite/libgomp.c/alloc-pinned-6.c @@ -1,4 +1,5 @@ /* { dg-do run } */ +/* { dg-additional-options -DOFFLOAD_DEVICE_NVPTX { target offload_device_nvptx } } */ /* Test that ompx_gnu_pinned_mem_alloc fails correctly. */ @@ -66,32 +67,57 @@ set_pin_limit (int size) int main () { +#ifdef OFFLOAD_DEVICE_NVPTX + /* Go big or go home. + The OS ulimit does not affect memory locked via CUDA for NVPTX devices. */ + const int SIZE = 40 * 1024 * 1024; +#else /* Allocate at least a page each time, but stay within the ulimit. */ const int SIZE = PAGE_SIZE * 4; +#endif + const int PIN_LIMIT = PAGE_SIZE*2; /* Ensure that the limit is smaller than the allocation. */ - set_pin_limit (SIZE / 2); + set_pin_limit (PIN_LIMIT); // Sanity check if (get_pinned_mem () != 0) abort (); - // Should fail void *p = omp_alloc (SIZE, ompx_gnu_pinned_mem_alloc); +#ifdef OFFLOAD_DEVICE_NVPTX + // Doesn't care about 'set_pin_limit'. + if (!p) + abort (); +#else + // Should fail if (p) abort (); +#endif - // Should fail p = omp_calloc (1, SIZE, ompx_gnu_pinned_mem_alloc); +#ifdef OFFLOAD_DEVICE_NVPTX + // Doesn't care about 'set_pin_limit'. + if (!p) + abort (); +#else + // Should fail if (p) abort (); +#endif - // Should fail to realloc void *notpinned = omp_alloc (SIZE, omp_default_mem_alloc); p = omp_realloc (notpinned, SIZE, ompx_gnu_pinned_mem_alloc, omp_default_mem_alloc); +#ifdef OFFLOAD_DEVICE_NVPTX + // Doesn't care about 'set_pin_limit'; does reallocate. + if (!notpinned || !p || p == notpinned) + abort (); +#else + // Should fail to realloc if (!notpinned || p) abort (); +#endif // No memory should have been pinned int amount = get_pinned_mem (); diff --git a/libgomp/testsuite/libgomp.c/alloc-pinned-8.c b/libgomp/testsuite/libgomp.c/alloc-pinned-8.c new file mode 100644 index 0000000..0fc737b --- /dev/null +++ b/libgomp/testsuite/libgomp.c/alloc-pinned-8.c @@ -0,0 +1,122 @@ +/* { dg-do run } */ + +/* { dg-skip-if "Pinning not implemented on this host" { ! *-*-linux-gnu* } } */ + +/* { dg-additional-options -DOFFLOAD_DEVICE_NVPTX { target offload_device_nvptx } } */ + +/* Test that pinned memory works for small allocations. */ + +#include <stdio.h> +#include <stdlib.h> + +#ifdef __linux__ +#include <sys/types.h> +#include <unistd.h> + +#include <sys/mman.h> +#include <sys/resource.h> + +#define PAGE_SIZE sysconf(_SC_PAGESIZE) +#define CHECK_SIZE(SIZE) { \ + struct rlimit limit; \ + if (getrlimit (RLIMIT_MEMLOCK, &limit) \ + || limit.rlim_cur <= SIZE) \ + fprintf (stderr, "insufficient lockable memory; please increase ulimit\n"); \ + } + +int +get_pinned_mem () +{ + int pid = getpid (); + char buf[100]; + sprintf (buf, "/proc/%d/status", pid); + + FILE *proc = fopen (buf, "r"); + if (!proc) + abort (); + while (fgets (buf, 100, proc)) + { + int val; + if (sscanf (buf, "VmLck: %d", &val)) + { + fclose (proc); + return val; + } + } + abort (); +} +#else +#error "OS unsupported" +#endif + +static void +verify0 (char *p, size_t s) +{ + for (size_t i = 0; i < s; ++i) + if (p[i] != 0) + abort (); +} + +#include <omp.h> + +int +main () +{ + /* Choose a small size where all our allocations fit on one page. */ + const int SIZE = 10; +#ifndef OFFLOAD_DEVICE_NVPTX + CHECK_SIZE (SIZE*4); +#endif + + const omp_alloctrait_t traits[] = { + { omp_atk_pinned, 1 } + }; + omp_allocator_handle_t allocator = omp_init_allocator (omp_default_mem_space, 1, traits); + + // Sanity check + if (get_pinned_mem () != 0) + abort (); + + void *p = omp_alloc (SIZE, allocator); + if (!p) + abort (); + + int amount = get_pinned_mem (); +#ifdef OFFLOAD_DEVICE_NVPTX + /* This doesn't show up as process 'VmLck'ed memory. */ + if (amount != 0) + abort (); +#else + if (amount == 0) + abort (); +#endif + + p = omp_realloc (p, SIZE * 2, allocator, allocator); + + int amount2 = get_pinned_mem (); +#ifdef OFFLOAD_DEVICE_NVPTX + /* This doesn't show up as process 'VmLck'ed memory. */ + if (amount2 != 0) + abort (); +#else + /* A small allocation should not allocate another page. */ + if (amount2 != amount) + abort (); +#endif + + p = omp_calloc (1, SIZE, allocator); + +#ifdef OFFLOAD_DEVICE_NVPTX + /* This doesn't show up as process 'VmLck'ed memory. */ + if (get_pinned_mem () != 0) + abort (); +#else + /* A small allocation should not allocate another page. */ + if (get_pinned_mem () != amount2) + abort (); +#endif + + verify0 (p, SIZE); + + return 0; +} |
