Добавление в архив исходного кода проекта и выбор для проекта лицензии 'Apache License 2.0'.

This commit is contained in:
stepanov_pa 2023-01-26 02:34:00 +03:00
parent 7f5ccca8b1
commit 8add65e1e8
29 changed files with 28418 additions and 0 deletions

202
LICENSE Normal file
View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

5
NOTICE Normal file
View File

@ -0,0 +1,5 @@
Lccrt Project
Copyright 2023 AO "MCST"
This product includes software developed at
AO "MCST" (http://www.mcst.ru/).

View File

@ -0,0 +1,325 @@
/**
* Part of the Lccrt Project, under the Apache License v2.0
* See http://www.apache.org/licenses/LICENSE-2.0.txt for license information.
* SPDX-License-Identifier: Apache-2.0
*
* lccrt_ctx.h - пользовательский интерфейс (динамической) компиляции.
*/
#ifndef LCCRT_CTX_H
#define LCCRT_CTX_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#include <stdlib.h>
#include <string.h>
#include "lccrt.h"
#include "internal/lccrt_ilist.h"
#include "internal/lccrt_hash.h"
#define LCCRT_MAX( a, b) (((a) >= (b)) ? (a) : (b))
#define LCCRT_MIN( a, b) (((a) <= (b)) ? (a) : (b))
#ifndef NDEBUG
/**
* Макрос задающий тип сборки в отладочном режиме.
*/
#define LCCRT_DEBUG
#endif /* !NDEBUG */
/**
* Преобразование значения в строку.
*/
#define LCCRT_TO_STR_OPERATOR( x) #x
#define LCCRT_TO_STR( x) LCCRT_TO_STR_OPERATOR( x)
#define LCCRT_ASM_SFUNC_COMPILE LCCRT_TO_STR( LCCRT_ASM_FUNC_COMPILE)
#define LCCRT_ASM_SFUNC_GETTOOL LCCRT_TO_STR( LCCRT_ASM_FUNC_GETTOOL)
#define LCCRT_IRROBJ_SFUNC_NODE_COMPILE LCCRT_TO_STR( LCCRT_IRROBJ_FUNC_NODE_COMPILE)
#define LCCRT_IRROBJ_SFUNC_NODE_DECOMPILE LCCRT_TO_STR( LCCRT_IRROBJ_FUNC_NODE_DECOMPILE)
#define LCCRT_IRROBJ_SFUNC_RELOC_PATCH LCCRT_TO_STR( LCCRT_IRROBJ_FUNC_RELOC_PATCH)
#define LCCRT_IRROBJ_SFUNC_CODE_EXEC LCCRT_TO_STR( LCCRT_IRROBJ_FUNC_CODE_EXEC)
#define LCCRT_IRROBJ_SFUNC_GETCONF LCCRT_TO_STR( LCCRT_IRROBJ_FUNC_GETCONF)
#define LCCRT_PLUGIN_LIBRARY_NAME_S LCCRT_TO_STR( LCCRT_PLUGIN_LIBRARY_NAME)
#define LCCRT_PLUGIN_LCCRT_VERSION_S LCCRT_TO_STR( LCCRT_PLUGIN_LCCRT_VERSION)
#define LCCRT_PLUGIN_TARGETS_S LCCRT_TO_STR( LCCRT_PLUGIN_TARGETS)
/**
* Проверка двух строк на равенство.
*/
#define lccrt_str_eq( s, p) (strcmp( s, p) == 0)
#define lccrt_str_eqz( p, q) (!(p) || !(q) || lccrt_str_eq( p, q))
#define lccrt_min( a, b) ((a) < (b) ? (a) : (b))
#define lccrt_max( a, b) ((a) > (b) ? (a) : (b))
/**
* Присвоение под условием.
*/
#define lccrt_assign( p, v) ((p) ? ((*(p) = (v)), 0) : 0)
/**
* Исполнить выражение при нулевом значении флаговой переменной с сохранением во
* флаговую переменную результата выполнения выражения.
*/
#define lccrt_test0( flag, expr) ((flag) = ((expr) != 0) || (flag))
#define lccrt_test1( flag, expr) ((flag) = (!(expr) != 0) || (flag))
/**
* Чтение числа из строки с продвижкой указателя (возвращается 1 при возможности чтения
* символов из строки s).
*/
#define lccrt_strtoll( s, se, base, p) \
( \
((s) && (s)[0]) \
? (((p)[0] = strtoll( s, se, base)), 1) \
: 0 \
)
/**
* Интерефейс динамической проверки типов структур.
*/
#ifdef LCCRT_DEBUG
int lccrt_assert_var __attribute__((weak));
#define lccrt_assert( p) \
( \
lccrt_assert_var = ((p) \
? 0 \
: (printf( "ERROR: %s: %s:%d\n", __FUNCTION__, __FILE__, __LINE__), \
abort(), 0)) \
)
//#define lccrt_assert( p) assert( p)
#define lccrt_check_type_name( type) lccrt_check_var__##type
#define lccrt_check_type_declare( type) extern void *lccrt_check_type_name( type)
#define lccrt_check_type_define( type) void *lccrt_check_type_name( type)
#define lccrt_check_type_assert( d, t) \
( \
lccrt_assert( !(d) \
|| (((t *)(d))->type_check.ptr == (void *)&lccrt_check_type_name( t))) \
)
#define lccrt_check_type_init( d, t) \
( \
((t *)(d))->type_check.ptr = (void *)&lccrt_check_type_name( t) \
)
#define lccrt_check_type_done( d, t) \
( \
lccrt_check_type_assert( d, t), ((t *)(d))->type_check.ptr = 0 \
)
#else /* !LCCRT_DEBUG */
#define lccrt_assert( p)
#define lccrt_check_type_assert( d, t)
#define lccrt_check_type_declare( type)
#define lccrt_check_type_define( type)
#define lccrt_check_type_init( d, t)
#define lccrt_check_type_done( d, t)
#endif /* LCCRT_DEBUG */
/**
* Структура для динамического контроля типа структур.
*/
typedef struct
{
#ifdef LCCRT_DEBUG
void *ptr;
#endif /* LCCRT_DEBUG */
} lccrt_check_type_t;
/**
* Типы плагинов.
*/
typedef enum
{
LCCRT_PLUGIN_TYPE_ASM,
LCCRT_PLUGIN_TYPE_IRROBJ,
LCCRT_PLUGIN_TYPE_LAST
} lccrt_plugin_type_t;
/**
* Типы функций в ассемблере.
*/
typedef enum
{
LCCRT_PLUGIN_ASM_FUNC_COMP,
LCCRT_PLUGIN_ASM_FUNC_TOOL,
LCCRT_PLUGIN_ASM_FUNC_LAST
} lccrt_plugin_asm_func_name_t;
/**
* Типы функций в трансляторе из IR-R в объектный код.
*/
typedef enum
{
LCCRT_PLUGIN_IRROBJ_FUNC_NODE_COMPILE,
LCCRT_PLUGIN_IRROBJ_FUNC_NODE_DECOMPILE,
LCCRT_PLUGIN_IRROBJ_FUNC_RELOC_PATCH,
LCCRT_PLUGIN_IRROBJ_FUNC_CODE_EXEC,
LCCRT_PLUGIN_IRROBJ_FUNC_GETCONF,
LCCRT_PLUGIN_IRROBJ_FUNC_LAST
} lccrt_plugin_irrobj_func_name_t;
/**
* Структура внешнего плагина.
*/
typedef struct lccrt_plugin_r
{
lccrt_context_ptr ctx;
lccrt_plugin_type_t type; /* тип плагина */
void *lib; /* плагин */
const char *lib_name; /* название плагина */
const char *lccrt_ver; /* версия lccrt-библиотеки, с которой был собран плагин */
int num_targs; /* количество, поддерживаемых целей */
const char **targs; /* массив целей */
int num_funcs; /* количество методов в плагине */
void **funcs; /* методы плагина */
const char **lccrt_s; /* пути установки нативных (!) библиотек liblccrt_s */
const char **include_s; /* пути установки нативных заголовочных файлов */
lccrt_check_type_t type_check;
} lccrt_plugin_t;
/**
* Штатные пути для поиска компонент.
*/
typedef struct
{
char *home; /* корневая директория */
char *plugin; /* директория поиска плагинов */
char *plugins[LCCRT_PLUGIN_TYPE_LAST]; /* директория поиска плагинов по типу */
} lccrt_context_paths_t;
/**
* Данные по типам отладочных печатей.
*/
typedef struct
{
int8_t is_base; /* информация о переменных окружения, плагинах и т.п. */
int8_t is_ir; /* создание новых операций */
} lccrt_context_verbose_t;
/**
* \defgroup tyCtx lccrt_context_t
* Для работы с библиотекой в начале необходимо создать структуру контекста lccrt_context_t.
* В основном структура данных lccrt_context_t выполняет технические функции,
* в частности, можно одновременно создать несколько контекстов. Далее можно работать с разными контекстами
* независимым образом, причем все последующие данные создаются только в рамках одного из контекстов.
* При удалении контекста также (автоматически) удаляются все данные, созданные в рамках данного контекста.
*
* При создании контекста:
* - задается \ref lccrt_mem_t "менеджер памяти", с помощью которого должна выделяться память под структуры данных
* (при использовании внешних библиотек менеджер памяти не пропагируется), причем по умолчанию используются
* стандартные функции <b><tt> malloc/free </tt></b>
* - задается \ref lccrt_err_t "менеджер вывода сообщений об ошибках", причем по умолчанию используются
* стандартные функции <b><tt> printf/abort </tt></b>
* - происходит загрузка плагинов по штатным путям (см. \ref pgPlg "Загрузка плагинов")
*
*/
/**
* \class lccrt_context_t
* \copydoc tyCtx
*
* \copydoc tyCtxFns
*
* \ref tyCtxFns
*/
typedef struct lccrt_context_r
{
lccrt_mem_t mem; /*!< интерфейс менеджера памяти */
lccrt_err_t err; /*!< интерфейс менеджера ошибок */
lccrt_hash_ptr modules; /* хеш-таблица модулей */
uint64_t module_max; /* счетчик модулей */
int num_plgs[LCCRT_PLUGIN_TYPE_LAST]; /* количество штатных плагинов */
lccrt_plugin_t *plgs[LCCRT_PLUGIN_TYPE_LAST]; /* штатные плагины */
lccrt_context_paths_t paths; /* пути поиска компонент */
lccrt_context_verbose_t verbose; /* флаги отладочных печатетей */
lccrt_check_type_t type_check;
} lccrt_context_t;
/**
* Стандартный менеджер памяти и поток вывода ошибок.
*/
extern lccrt_mem_t lccrt_std_mem;
extern lccrt_err_t lccrt_std_err;
/**
* Перечисление типов структур с динамической проверкой типа.
*/
lccrt_check_type_declare( lccrt_type_t);
lccrt_check_type_declare( lccrt_varinit_t);
lccrt_check_type_declare( lccrt_var_t);
lccrt_check_type_declare( lccrt_oper_t);
lccrt_check_type_declare( lccrt_oper_iterator_t);
lccrt_check_type_declare( lccrt_einfo_block_t);
lccrt_check_type_declare( lccrt_einfo_tydescr_t);
lccrt_check_type_declare( lccrt_einfo_link_t);
lccrt_check_type_declare( lccrt_function_t);
lccrt_check_type_declare( lccrt_function_jit_info_t);
lccrt_check_type_declare( lccrt_module_t);
lccrt_check_type_declare( lccrt_context_t);
lccrt_check_type_declare( lccrt_plugin_t);
lccrt_check_type_declare( lccrt_fs_t);
lccrt_check_type_declare( lccrt_jit_t);
lccrt_check_type_declare( lccrt_irr_code_area_t);
lccrt_check_type_declare( lccrt_irr_jit_region_t);
lccrt_check_type_declare( lccrt_irr_code_t);
lccrt_check_type_declare( lccrt_irr_execute_context_t);
lccrt_check_type_declare( lccrt_irr_reloc_unit_t);
lccrt_check_type_declare( lccrt_irr_reloc_t);
lccrt_check_type_declare( lccrt_irr_node_t);
lccrt_check_type_declare( lccrt_irr_oper_iter_t);
lccrt_check_type_declare( lccrt_irr_oper_t);
lccrt_check_type_declare( lccrt_irr_arg_t);
lccrt_check_type_declare( lccrt_irr_reg_t);
lccrt_check_type_declare( lccrt_irr_edge_t);
extern void *lccrt_ctx_malloc_func( lccrt_ctx_ptr ctx, uint64_t size);
extern void *lccrt_ctx_realloc_func( lccrt_ctx_ptr ctx, void *ptr, uint64_t size);
extern void *lccrt_ctx_free_func( lccrt_ctx_ptr ctx, void *ptr);
extern void *lccrt_ctx_memdup_func( lccrt_ctx_ptr ctx, void *ptr, uint64_t len);
extern void **lccrt_ctx_copy_arr_func( lccrt_ctx_ptr ctx, void **ptr, uint64_t size, uint64_t len);
extern char *lccrt_ctx_copy_str( lccrt_context_ptr ctx, const char *str);
extern char *lccrt_ctx_cat_strs( lccrt_context_ptr ctx, const char *str1, const char *str2);
extern char *lccrt_ctx_catby_strs( lccrt_context_ptr ctx, const char *str1, const char *str2);
#define lccrt_ctx_malloc( ctx, type) (type *)lccrt_ctx_malloc_func( ctx, sizeof( type))
#define lccrt_ctx_mallocn( ctx, type, n) ((type *)lccrt_ctx_malloc_func( ctx, (n) * sizeof( type)))
#define lccrt_ctx_realloc( ctx, ptr, len) lccrt_ctx_realloc_func( ctx, (void *)ptr, len)
#define lccrt_ctx_free( ctx, ptr) lccrt_ctx_free_func( ctx, (void *)ptr)
#define lccrt_ctx_memdup( ctx, ptr, len) lccrt_ctx_memdup_func( ctx, (void *)ptr, len)
#define lccrt_ctx_copy_arr( ctx, ptr, type, n) \
( \
(type *)lccrt_ctx_copy_arr_func( ctx, (void **)(ptr), sizeof( type), n) \
)
#define lccrt_ctx_error( ctx, eid, fmt, ...) \
( \
(ctx)->err.error_func \
? ((ctx)->err.error_func( (ctx)->err.data, eid, "Error:%s:%d: " fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__), 0) \
: 0 \
)
#define lccrt_ctx_warning( ctx, wid, fmt, ...) \
( \
(ctx)->err.warning_func \
? ((ctx)->err.warning_func( (ctx)->err.data, wid, "Warning:%s:%d: " fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__), 0) \
: 0 \
)
extern void *lccrt_ctx_plugin_get_func( lccrt_plg_ptr plg, int func_num);
extern lccrt_fs_ptr lccrt_fs_new_file( lccrt_context_ptr ctx, FILE *file);
extern lccrt_fs_ptr lccrt_fs_open_file( lccrt_context_ptr ctx, const char *name, int is_load);
extern lccrt_fs_ptr lccrt_fs_new_buffer( lccrt_context_ptr ctx, char *buff, uint64_t buff_size);
extern int lccrt_fs_delete( lccrt_fs_ptr f);
extern int lccrt_fs_is_error( lccrt_fs_ptr f);
extern uint64_t lccrt_fs_get_syms_count( lccrt_fs_ptr f);
extern char *lccrt_fs_get_buffer( lccrt_fs_ptr f);
extern int lccrt_fs_get_sym( lccrt_fs_ptr f);
extern int lccrt_fs_printf( lccrt_fs_ptr f, const char *fmt, ...);
extern int lccrt_fs_print_name_str( lccrt_fs_ptr f, const char *name);
#if defined(__cplusplus)
}
#endif
#endif /* LCCRT_CTX_H */

View File

@ -0,0 +1,37 @@
/**
* Part of the Lccrt Project, under the Apache License v2.0
* See http://www.apache.org/licenses/LICENSE-2.0.txt for license information.
* SPDX-License-Identifier: Apache-2.0
*
* lccrt_hash.h - пользовательский интерфейс (динамической) компиляции.
*/
#ifndef LCCRT_HASH_H
#define LCCRT_HASH_H
#if 0
typedef enum
{
LCCRT_HASH_KEY_INTPTR,
LCCRT_HASH_KEY_STRING,
LCCRT_HASH_KEY_LAST
} lccrt_hash_key_type_t;
typedef lccrt_hash_key_type_t lccrt_hkt_t;
typedef struct lccrt_hash_entry_r *lccrt_hash_entry_ptr;
typedef struct lccrt_hash_r *lccrt_hash_ptr;
typedef lccrt_hash_entry_ptr lccrt_he_ptr;
typedef lccrt_hash_ptr lccrt_h_ptr;
extern lccrt_h_ptr lccrt_hash_new( lccrt_ctx_ptr ctx, lccrt_hkt_t type);
extern void lccrt_hash_delete( lccrt_h_ptr ht);
extern lccrt_he_ptr lccrt_hash_push( lccrt_h_ptr ht, uintptr_t key, int *is_new);
extern lccrt_he_ptr lccrt_hash_find( lccrt_h_ptr ht, uintptr_t key);
extern uintptr_t lccrt_hash_remove( lccrt_he_ptr he);
extern uintptr_t lccrt_hash_get( lccrt_he_ptr he);
extern uintptr_t lccrt_hash_set( lccrt_he_ptr he, uintptr_t data);
extern lccrt_he_ptr lccrt_hash_first( lccrt_h_ptr ht);
extern lccrt_he_ptr lccrt_hash_next( lccrt_he_ptr he);
#endif
#endif /* LCCRT_HASH_H */

View File

@ -0,0 +1,110 @@
/**
* Part of the Lccrt Project, under the Apache License v2.0
* See http://www.apache.org/licenses/LICENSE-2.0.txt for license information.
* SPDX-License-Identifier: Apache-2.0
*
* lccrt_ilist.h - пользовательский интерфейс (динамической) компиляции.
*/
#ifndef LCCRT_ILIST_H
#define LCCRT_ILIST_H
/**
* Тип-шаблон для заголовка.
*/
#define lccrt_ilist_head( ptr) lccrt_ilist_head__##ptr
#define lccrt_ilist_head_typedef( ptr) \
typedef struct \
{ \
ptr first; \
ptr last; \
} lccrt_ilist_head( ptr)
/**
* Тип-шаблон для связи элементов.
*/
#define lccrt_ilist_unit( ptr) lccrt_ilist_unit__##ptr
#define lccrt_ilist_unit_typedef( ptr) \
typedef struct \
{ \
ptr prev; \
ptr next; \
} lccrt_ilist_unit( ptr)
/**
* Инициализация.
*/
#define lccrt_ilist_head_init( h) \
( \
(h)->first = 0, \
(h)->last = 0 \
)
/**
* Инициализация.
*/
#define lccrt_ilist_unit_init( h) \
( \
(h)->prev = 0, \
(h)->next = 0 \
)
/**
* Поменять значение ссылки.
*/
#define lccrt_ilist_assign_prev( l, u, v) ((u) ? ((u)->l.prev = (v)) : 0)
#define lccrt_ilist_assign_next( l, u, v) ((u) ? ((u)->l.next = (v)) : 0)
/**
* Связывание двух узлов со внутренним списком.
*/
#define lccrt_ilist_link( l, u, v) \
(\
lccrt_ilist_assign_next( l, u, v), \
lccrt_ilist_assign_prev( l, v, u), \
0 \
)
/**
* Вставка во внутренний список после заданного элемента нового узла.
*/
#define lccrt_ilist_insert( l, u, v) \
( \
lccrt_ilist_link( l, v, ((u) ? (u)->l.next : 0)), \
lccrt_ilist_link( l, u, v), \
(v) \
)
/**
* Вставка во внутренний список после заданного элемента нового узла.
*/
#define lccrt_ilist_head_insert( h, l, v) \
( \
lccrt_ilist_insert( l, (h)->last, v), \
((h)->last = v), \
(((h)->first) ? 0 : ((h)->first = (v))), \
(v) \
)
/**
* Удаление из списка текущего элемента.
*/
#define lccrt_ilist_remove( l, v) \
( \
lccrt_ilist_assign_next( l, (v)->l.prev, 0), \
lccrt_ilist_assign_prev( l, (v)->l.next, 0), \
(v)->l.prev \
)
/**
* Удаление из списка текущего элемента.
*/
#define lccrt_ilist_head_remove( h, l, v) \
( \
lccrt_ilist_remove( l, v), \
(((h)->first == (v)) ? ((h)->first = (v)->l.next) : 0), \
(((h)->last == (v)) ? ((h)->last = (v)->l.prev) : 0), \
(v)->l.prev \
)
#endif /* LCCRT_ILIST_H */

View File

@ -0,0 +1,478 @@
/**
* Part of the Lccrt Project, under the Apache License v2.0
* See http://www.apache.org/licenses/LICENSE-2.0.txt for license information.
* SPDX-License-Identifier: Apache-2.0
*
* lccrt_irv.h - пользовательский интерфейс (динамической) компиляции.
*/
#ifndef LCCRT_IRV_H
#define LCCRT_IRV_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#include "internal/lccrt_ctx.h"
/**
* Получить по битовому размеру целового типа его внутреннее название.
*/
#define lccrt_type_get_int_subtype_name( bs) \
( \
(bs) == 8 \
? LCCRT_INT_SUBTYPE_8 \
: ((bs) == 16 \
? LCCRT_INT_SUBTYPE_16 \
: ((bs) == 32 \
? LCCRT_INT_SUBTYPE_32 \
: ((bs) == 64 \
? LCCRT_INT_SUBTYPE_64 \
: ((bs) == 128 \
? LCCRT_INT_SUBTYPE_128 \
: LCCRT_INT_SUBTYPE_LAST)))) \
)
/**
* Получить по битовому размеру плавающего типа его внутреннее название.
*/
#define lccrt_type_get_float_subtype_name( bs) \
( \
(bs) == 32 \
? LCCRT_FLOAT_SUBTYPE_32 \
: ((bs) == 64 \
? LCCRT_FLOAT_SUBTYPE_64 \
: ((bs) == 80 \
? LCCRT_FLOAT_SUBTYPE_80 \
: ((bs) == 128 \
? LCCRT_FLOAT_SUBTYPE_128 \
: LCCRT_FLOAT_SUBTYPE_LAST))) \
)
/**
* Определение типов для списков.
*/
lccrt_ilist_head_typedef( lccrt_t_ptr);
lccrt_ilist_unit_typedef( lccrt_t_ptr);
lccrt_ilist_head_typedef( lccrt_f_ptr);
lccrt_ilist_unit_typedef( lccrt_f_ptr);
lccrt_ilist_head_typedef( lccrt_v_ptr);
lccrt_ilist_unit_typedef( lccrt_v_ptr);
lccrt_ilist_head_typedef( lccrt_vi_ptr);
lccrt_ilist_unit_typedef( lccrt_vi_ptr);
typedef struct lccrt_einfo_link_r *lccrt_einfo_link_ptr;
typedef struct lccrt_einfo_block_r *lccrt_einfo_block_ptr;
typedef lccrt_einfo_link_ptr lccrt_eil_ptr;
typedef lccrt_einfo_block_ptr lccrt_eib_ptr;
/**
* IR-тип данных.
*/
typedef struct lccrt_type_r
{
//lccrt_context_ptr ctx;
lccrt_module_ptr m;
lccrt_type_ptr parent; /* указуемый тип (для LCCRT_TYPE_PTR)
указуемый тип (для LCCRT_TYPE_NAME)
возвращаемый тип (для LCCRT_TYPE_FUNC)
элементарный тип (для LCCRT_TYPE_ARRAY)
элементарный тип (для LCCRT_TYPE_VLA_ARRAY)
элементарный тип (для LCCRT_TYPE_FIELD) */
lccrt_type_ptr *args; /* массив аргументов (для LCCRT_TYPE_FUNC)
массив элементов (для LCCRT_TYPE_STRUCT) */
uint64_t num_args; /* количество аргументов (для LCCRT_TYPE_FUNC)
количество элементов (для LCCRT_TYPE_ARRAY)
количество элементов (для LCCRT_TYPE_STRUCT) */
lccrt_var_ptr vnum; /* количество элементов (для LCCRT_TYPE_VLA_ARRAY) */
const char *sym_name; /* символьное имя (является ключем в ctx->types) */
const char *usr_name; /* пользовательское имя (является ключем в ctx->type_usr_names), может быть
пустым */
lccrt_ilist_unit( lccrt_t_ptr) types_unit; /* элемент списка типов */
uint64_t bytealign; /* байтовое выравнивание */
uint64_t bytesize; /* байтовый размер */
uint64_t byteshift; /* смещение от начала объемлющего типа (для LCCRT_TYPE_FIELD) */
uint64_t ident_num; /* уникальный номер типа */
lccrt_type_name_t type_name; /* идентификатор типа */
unsigned char bitsubshift; /* дополнительное битовое смещение (для LCCRT_TYPE_FIELD) */
unsigned char bitsubsize; /* количество хранимых бит (для LCCRT_TYPE_FIELD) */
unsigned char is_sign; /* знаковость (для LCCRT_TYPE_INT) */
unsigned char is_union; /* флаг совмещения полей (для LCCRT_TYPE_STRUCT) */
lccrt_check_type_t type_check;
} lccrt_type_t;
/**
* Основные IR-типы данных.
*/
typedef struct lccrt_types_std_r
{
int ptr_bytesize; /* байтовый размер указателей */
lccrt_type_ptr void_type; /* тип void */
lccrt_type_ptr bool_type; /* тип bool */
lccrt_type_ptr int_types[2][LCCRT_INT_SUBTYPE_LAST+1]; /* целые типы */
lccrt_type_ptr float_types[LCCRT_FLOAT_SUBTYPE_LAST+1]; /* плавающие типы */
lccrt_type_ptr ellipsis; /* тип для аргумента функции вида "..." */
lccrt_type_ptr intptr; /* целый тип по размеру эквивалентный указателю */
lccrt_type_ptr ptr_byte; /* указатель на uint8 */
lccrt_type_ptr ptr_char; /* указатель на sint8 */
lccrt_type_ptr ptr_intptr; /* указатель на intptr */
} lccrt_types_std_t;
/**
* Тип einfo-данных.
*/
typedef enum
{
LCCRT_EINFO_NULL = 0,
LCCRT_EINFO_INT64,
LCCRT_EINFO_STRUCT,
LCCRT_EINFO_UNION,
LCCRT_EINFO_ARRAY,
LCCRT_EINFO_RAW,
LCCRT_EINFO_LAST
} lccrt_einfo_type_t;
/**
* Указатель на einfo-данные.
*/
typedef struct
{
uint8_t type; /* тип einfo-данных */
union
{
uint64_t i64; // значение типа LCCRT_EINFO_INT64
lccrt_einfo_block_ptr ref; // указатель для типов LCCRT_EINFO_ARRAY, LCCRT_EINFO_STRUCT,
// LCCRT_EINFO_RAW, LCCRT_EINFO_UNION
} data;
} lccrt_einfo_handle_t;
/**
* Описание типа метаданных.
*/
typedef struct lccrt_einfo_tydescr_r
{
lccrt_einfo_tydescr_ptr next; /* общий список всех структур */
lccrt_einfo_type_t type; /* тип einfo-данных */
int num_flds; /* количество полей */
lccrt_module_ptr m; /* ссылка на модуль */
char *self_name; /* название структуры данных */
char **flds; /* массив с названиями полей */
lccrt_einfo_tydescr_ptr *types; /* массив с типами полей */
lccrt_check_type_t type_check;
} lccrt_einfo_tydescr_t;
/**
* Мета-данные.
*/
typedef struct lccrt_einfo_block_r
{
lccrt_einfo_block_ptr next; /* общий список всех данных */
uint8_t type; /* тип мета-данных */
int32_t num_args; /* количество полей для LCCRT_EINFO_STRUCT,
количество элементов для LCCRT_EINFO_ARRAY,
байтовый размер для LCCRT_EINFO_RAW */
int32_t max_args; /* длина выделения массива элементов для LCCRT_EINFO_ARRAY */
lccrt_einfo_tydescr_ptr tydescr; /* описание типов полей для LCCRT_EINFO_STRUCT, LCCRT_EINFO_UNION,
описание типа элемента для LCCRT_EINFO_ARRAY */
union
{
lccrt_einfo_handle_t *flds; /* значение полей для LCCRT_EINFO_STRUCT, LCCRT_EINFO_UNION */
lccrt_einfo_handle_t *elems; /* значение элементов LCCRT_EINFO_ARRAY */
uint8_t *rdata; /* данные для LCCRT_EINFO_RAW */
} data;
lccrt_check_type_t type_check;
} lccrt_einfo_block_t;
/**
* Элемент списка мета-данных.
*/
typedef struct lccrt_einfo_link_r
{
lccrt_einfo_link_ptr prev; /* ссылка на предыдущий элемент */
lccrt_einfo_link_ptr next; /* ссылка на следующий элемент */
lccrt_einfo_category_t ident; /* дескриптор свойства */
lccrt_einfo_handle_t value; /* значение свойства */
lccrt_check_type_t type_check;
} lccrt_einfo_link_t;
/**
* Размер диапазона кешируемых константных значений.
*/
#define LCCRT_MODULE_CARG_MIN (-32LL)
#define LCCRT_MODULE_CARG_MAX (+31LL)
#define LCCRT_MODULE_CARG_LEN (LCCRT_MODULE_CARG_MAX - LCCRT_MODULE_CARG_MIN + 1)
/**
* Модуль - аналог языковой единицы компиляции.
*/
typedef struct lccrt_module_r
{
lccrt_context_ptr ctx;
const char *name; /* название модуля */
const char *asm_text; /* asm-inline текст модуля */
uint64_t ident_num; /* уникальный идентификатор модуля */
lccrt_types_std_t types_std; /* основные типы данных */
lccrt_h_ptr types; /* хеш-таблица типов */
lccrt_h_ptr type_usr_names; /* хеш-таблица (пользовательскоеИмя -> тип) */
uint64_t type_max; /* счетчик типов */
lccrt_h_ptr gvars; /* соответствие имя->глобальнаяПеременная */
lccrt_h_ptr funcs; /* соответствие имя->функция */
uintptr_t einfo_ident; /* идентификатор для следующего класса метаданных */
lccrt_h_ptr einfo_cats; /* таблица названиеКатегории -> идентификаторКатегории */
lccrt_einfo_tydescr_ptr etydescrs_head; /* список всех блоков описания мета-данных */
lccrt_einfo_block_ptr eblocks_head; /* список всех блоков мета-данных */
lccrt_einfo_tydescr_ptr einfo_tyi64; /* описание типа для i64-einfo */
lccrt_einfo_tydescr_ptr einfo_tyraw; /* описание типа для raw-einfo */
lccrt_h_ptr einfo_tyarrs; /* таблица типЭлемента -> типМассив */
lccrt_h_ptr einfo_tysts; /* таблица тегНазвание -> типСтруктура */
lccrt_einfo_link_ptr einfo; /* собственные мета-данные модуля */
lccrt_ilist_head( lccrt_t_ptr) types_head; /* список всех типов */
lccrt_ilist_head( lccrt_v_ptr) gvars_head; /* список всех глобальных переменных */
lccrt_ilist_head( lccrt_f_ptr) funcs_head; /* список всех функций */
lccrt_ilist_head( lccrt_vi_ptr) varinits_head; /* список всех инициализаторов */
uint64_t funcs_num; /* нумерация функций */
uint64_t gvars_num; /* нумерация глобальных переменных */
uint64_t cargs_name_id; /* нумерация константных имен */
uint64_t global_name_id; /* нумерация глобальных имен */
lccrt_var_ptr carg_vars[2][LCCRT_MODULE_CARG_LEN]; /* переменные константные
аргументы [u32,u64][-32..+31] */
uint8_t is_ptr32; /* компиляция для 32-битной модели памяти */
uint8_t is_jit; /* компиляция в динамическом режиме */
lccrt_check_type_t type_check;
} lccrt_module_t;
/**
* Инициализатор переменной.
*/
typedef struct lccrt_varinit_r
{
lccrt_type_ptr type; /* ir-тип */
union lccrt_varinit_data_r
{
uint64_t ival; /* скалярное значение (для LCCRT_VARINIT_HEX) */
char *sval; /* массив байт (для LCCRT_VARINIT_STR) */
lccrt_varinit_ptr *vals; /* массив значений (для LCCRT_VARINIT_ARR) */
lccrt_var_ptr var; /* адрес переменной (для LCCRT_VARINIT_ADDR_VAR) */
struct lccrt_function_r *func; /* адрес функции (для LCCRT_VARINIT_ADDR_FUNC) */
} data;
lccrt_varinit_inittype_t init_type; /* разновидность инициализатора */
uint64_t num_elems; /* количество элементов (для LCCRT_VARINIT_ARR)
количество элементов (для LCCRT_VARINIT_STR)
смещение в байтах (для LCCRT_VARINIT_ADDR_VAR)
смещение в байтах (для LCCRT_VARINIT_ADDR_FUNC) */
lccrt_ilist_unit( lccrt_vi_ptr) varinits_unit; /* элемент списка инициализаторов */
lccrt_check_type_t type_check;
} lccrt_varinit_t;
/**
* Информация о способе линковке.
*/
typedef struct
{
lccrt_link_bind_t bnd; /* тип старшинства */
lccrt_link_visibility_t vis; /* тип видимости */
lccrt_link_tls_t tls; /* tls-тип */
uint8_t is_cnst; /* флаг неизменности значения ячейки памяти */
uint8_t is_alias; /* флаг алиаса */
} lccrt_asmlink_t;
/**
* Булевые атрибуты переменной (собираем вместе для экономии памяти).
*/
typedef enum
{
LCCRT_VAR_ATTR_USED, /* признак (скрытого) использования */
LCCRT_VAR_ATTR_COMMON, /* признак common-переменной */
LCCRT_VAR_ATTR_RESTRICT,
LCCRT_VAR_ATTR_LAST
} lccrt_var_attr_name_t;
/**
* Количество длинных слов (по 64 бита), которое необходимо для хранения значений
* всех атрибутов.
*/
#define LCCRT_VAR_ATTRS_LENGTH ((LCCRT_VAR_ATTR_LAST + 63) / 64)
/**
* Аналог языковой переменной.
*/
typedef struct lccrt_var_r
{
void *holder; /* полный контекст, модуль или функция (в зависимости от loc) */
const char *name; /* название переменной */
const char *asm_name; /* название в ассемблерном файле (для обычных переменных)
ассемблерный текст (для LCCRT_VAR_LOC_ASM) */
const char *section_name; /* название секции в ассемблерном файле */
const char *comdat; /* значение поля comdat (или 0) */
lccrt_varinit_ptr init_value; /* инициализатор переменной */
lccrt_type_ptr type; /* тип переменной */
lccrt_einfo_link_ptr einfo; /* мета-данные переменной */
lccrt_ilist_unit( lccrt_v_ptr) vars_unit; /* элемент списка переменных */
lccrt_var_loc_t loc; /* тип размещения переменной */
lccrt_asmlink_t link; /* тип связывания переменной */
uint64_t ident_num; /* идентификатор (внутри holder-контекста) */
unsigned align; /* минимальное выравнивание переменной */
int arg_num; /* номер аргумента среди аргументов функции (для LCCRT_VAR_LOC_ARG) */
int num_defs; /* количество использований переменной в качестве результата */
uint64_t attrs[LCCRT_VAR_ATTRS_LENGTH]; /* булевые атрибуты переменной */
lccrt_check_type_t type_check;
} lccrt_var_t;
/**
* Итератор для ссылки на операции.
*/
typedef struct lccrt_oper_iterator_r
{
lccrt_context_ptr ctx;
lccrt_oper_ptr prev;
lccrt_oper_ptr next;
lccrt_oper_ptr last; /* последняя, созданная с помощью итератора, операция */
int is_forward; /* флаг замены prev новой операцией, иначе - замена next */
lccrt_check_type_t type_check;
} lccrt_oper_iterator_t;
#define LCCRT_GET_BYTE( d, k) (((unsigned char *)(d))[k])
#define LCCRT_LINK_BYTE_BND( d) LCCRT_GET_BYTE( d, 0)
#define LCCRT_LINK_BYTE_VIS( d) LCCRT_GET_BYTE( d, 1)
#define LCCRT_LINK_BYTE_TLS( d) LCCRT_GET_BYTE( d, 2)
#define LCCRT_LINK_BYTE_CST( d) LCCRT_GET_BYTE( d, 3)
#define LCCRT_LINK_BYTE_ALS( d) LCCRT_GET_BYTE( d, 4)
/**
* Булевые атрибуты функции (собираем вместе для экономии памяти).
*/
typedef enum
{
LCCRT_FUNC_ATTR_DECLARATION, /* признак заголовочного объявления */
LCCRT_FUNC_ATTR_BUILTIN, /* признак встроенной функции */
LCCRT_FUNC_ATTR_USED, /* признак "used" */
LCCRT_FUNC_ATTR_EXTERN_INLINE, /* признак declare-функции, для которой доступно тело
функции, но только для оптимизаций типа inline */
LCCRT_FUNC_ATTR_DOES_NOT_THROW, /* признак "does not throw" */
LCCRT_FUNC_ATTR_JIT_PROFGEN, /* признак генерации профиля */
LCCRT_FUNC_ATTR_LAST
} lccrt_function_attr_name_t;
/**
* Количество длинных слов (по 64 бита), которое необходимо для хранения значений
* всех атрибутов.
*/
#define LCCRT_FUNC_ATTRS_LENGTH ((LCCRT_FUNC_ATTR_LAST + 63) / 64)
/**
* Функция.
*/
typedef struct lccrt_function_r
{
lccrt_context_ptr ctx;
lccrt_module_ptr module; /* охватывающий модуль */
const char *name; /* имя функции */
const char *asm_name; /* имя функции в ассемблерном файле */
const char *section; /* название секции в ассемблерном файле (или 0) */
const char *comdat; /* значение поля comdat (или 0) */
lccrt_hash_ptr lvars; /* локальные переменные функции */
lccrt_asmlink_t link; /* информация о линковке */
lccrt_type_ptr sig_type; /* сигнатура функции */
lccrt_var_ptr *args; /* аргументы функции */
lccrt_var_ptr *sysargs; /* (специальные) аргументы функции */
lccrt_function_jit_info_ptr jit_info; /* данные для динамической компиляции */
lccrt_einfo_link_ptr einfo; /* мета-данные функции */
uint64_t ident_num; /* уникальный идентификатор функции (внутри модуля) */
uint32_t sysargs_num; /* нумерация (специальных) аргументов функции */
uint32_t lvars_num; /* нумерация локальных переменных */
uint32_t opers_num; /* нумерация операций */
uint32_t local_name_id; /* нумерация локальных имен */
lccrt_ilist_unit( lccrt_f_ptr) funcs_unit; /* элемент списка функций */
lccrt_oper_ptr start; /* стартовая ir-операция */
lccrt_oper_iterator_t cur; /* ir-итератор */
lccrt_ilist_head( lccrt_v_ptr) lvars_head; /* список всех локальных переменных */
lccrt_function_init_type_t init_type; /* тип инициализации для функции */
int init_priority; /* порядок инициализации функции */
uint64_t attrs[LCCRT_FUNC_ATTRS_LENGTH]; /* булевые атрибуты функции */
lccrt_check_type_t type_check;
} lccrt_function_t;
/**
* IR-операция.
*/
typedef struct lccrt_oper_r
{
lccrt_function_ptr func;
uint64_t ident_num; /* идентификатор операции */
lccrt_oper_ptr prev; /* предыдущая операция */
lccrt_oper_ptr next; /* следующая операция */
lccrt_var_ptr res; /* результат операции */
lccrt_arg_t *args; /* аргументы операции */
const char *label; /* метка операции (для LCCRT_OPER_LABEL) */
lccrt_einfo_link_ptr einfo; /* мета-данные операции */
lccrt_oper_name_t name; /* название операции */
int32_t num_args; /* количество аргументов */
int32_t num_sysargs; /* количество (специальных) аргументов */
char is_volatile; /* флаг volatile-обращение */
char is_atomic; /* флаг atomic-обращение */
char is_cleanup; /* флаг cleanup-landingpad'а */
lccrt_check_type_t type_check;
} lccrt_oper_t;
extern lccrt_t_ptr lccrt_type_make_simple( lccrt_m_ptr m, lccrt_type_name_t name, const char *sym_name,
int is_sign, uint64_t bytealign, uint64_t bytesize);
extern void lccrt_type_delete( lccrt_t_ptr type);
extern void lccrt_type_set_parent( lccrt_type_ptr type, lccrt_type_ptr parent);
extern void lccrt_type_set_arg( lccrt_type_ptr type, int arg_num, lccrt_type_ptr arg);
extern lccrt_t_ptr lccrt_type_import( lccrt_m_ptr m, lccrt_t_ptr type, lccrt_h_ptr types);
extern lccrt_link_t lccrt_link_conv( lccrt_asmlink_t link);
extern lccrt_asmlink_t lccrt_link_unpack( lccrt_link_t link);
extern void lccrt_varinit_delete( lccrt_vi_ptr vi);
extern void lccrt_var_copy_attrs( lccrt_v_ptr dst, lccrt_v_ptr src);
extern void lccrt_module_delete_data( lccrt_m_ptr m);
extern char *lccrt_module_name_new_global( lccrt_m_ptr m, const char *name);
extern lccrt_hash_ptr lccrt_module_get_types( lccrt_m_ptr m);
extern lccrt_hash_ptr lccrt_module_get_gvars( lccrt_m_ptr m);
extern lccrt_hash_ptr lccrt_module_get_funcs( lccrt_m_ptr m);
extern uint64_t lccrt_module_get_type_max( lccrt_module_ptr m);
extern uint64_t lccrt_module_get_func_max( lccrt_module_ptr m);
extern void lccrt_function_delete( lccrt_f_ptr f);
extern int lccrt_function_get_attr_jit_profgen( lccrt_f_ptr func);
extern int lccrt_function_set_attr_jit_profgen( lccrt_f_ptr func, int value);
extern char *lccrt_function_name_new_local( lccrt_f_ptr f, const char *name);
extern void lccrt_function_clear( lccrt_function_ptr f);
extern lccrt_f_ptr lccrt_function_copy( lccrt_m_ptr m, lccrt_f_ptr f, const char *name,
const char *asm_name, lccrt_link_t ln, lccrt_h_ptr types);
extern lccrt_o_ptr lccrt_function_call_inline( lccrt_o_ptr call, lccrt_f_ptr call_func);
extern lccrt_var_ptr lccrt_function_var_import( lccrt_f_ptr dst_func, lccrt_f_ptr src_func,
lccrt_v_ptr v, lccrt_h_ptr vars, lccrt_h_ptr types,
int is_same_name);
extern void lccrt_function_init_jit_info( lccrt_f_ptr f, lccrt_f_ptr root,
lccrt_v_ptr func_entry, lccrt_v_ptr profgen_tls);
extern lccrt_einfo_handle_t lccrt_einfo_get_handle( lccrt_einfo_reference_t value);
extern int lccrt_einfo_is_scalar( lccrt_einfo_reference_t einfo);
extern lccrt_eir_t lccrt_einfo_get_block_reference( lccrt_eib_ptr eblock);
extern void lccrt_einfo_block_delete( lccrt_einfo_block_ptr eblock);
extern void lccrt_einfo_tydescr_delete( lccrt_einfo_tydescr_ptr etyde);
extern lccrt_einfo_link_ptr lccrt_einfo_link_new( lccrt_m_ptr m, lccrt_eil_ptr elink,
lccrt_eic_t ecat, lccrt_eir_t value);
extern lccrt_einfo_link_ptr lccrt_einfo_link_push_value( lccrt_m_ptr m, lccrt_eil_ptr elink0,
lccrt_eic_t ecat, lccrt_eir_t value);
extern lccrt_einfo_link_ptr lccrt_einfo_link_delete_chain( lccrt_einfo_link_ptr elink);
extern lccrt_einfo_link_ptr lccrt_einfo_link_find( lccrt_einfo_link_ptr elink, lccrt_eic_t ecat);
extern void lccrt_einfo_link_delete( lccrt_einfo_link_ptr elink);
extern lccrt_einfo_reference_t lccrt_einfo_link_get_value( lccrt_einfo_link_ptr elink);
extern void lccrt_module_einfo_number( lccrt_m_ptr m, lccrt_h_ptr btbl, lccrt_h_ptr ttbl);
extern int lccrt_var_get_num_defs( lccrt_v_ptr v);
extern int lccrt_var_set_num_defs( lccrt_v_ptr v, int num_defs);
extern const char *lccrt_oper_get_name_str( lccrt_oper_ptr op);
extern void lccrt_oper_print_opers( lccrt_o_ptr op1, lccrt_o_ptr op2);
extern int lccrt_oper_get_str_opername( const char *str);
#if defined(__cplusplus)
}
#endif
#endif /* LCCRT_IRV_H */

View File

@ -0,0 +1,22 @@
/**
* Part of the Lccrt Project, under the Apache License v2.0
* See http://www.apache.org/licenses/LICENSE-2.0.txt for license information.
* SPDX-License-Identifier: Apache-2.0
*
* lccrt_real.h - пользовательский интерфейс (динамической) компиляции.
*/
#ifndef LCCRT_REAL_H
#define LCCRT_REAL_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#include "internal/lccrt_irv.h"
#if defined(__cplusplus)
}
#endif
#endif /* LCCRT_REAL_H */

1539
include/lccrt.h Normal file

File diff suppressed because it is too large Load Diff

1284
lib/common/lccrt_ctx.c Normal file

File diff suppressed because it is too large Load Diff

351
lib/common/lccrt_fs.c Normal file
View File

@ -0,0 +1,351 @@
/**
* Part of the Lccrt Project, under the Apache License v2.0
* See http://www.apache.org/licenses/LICENSE-2.0.txt for license information.
* SPDX-License-Identifier: Apache-2.0
*
* lccrt_fs.c - работа с потоками данных.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include "lccrt_real.h"
/**
* Разновидности потоков данных.
*/
typedef enum
{
LCCRT_FS_TYPE_FILE,
LCCRT_FS_TYPE_BUFFER,
LCCRT_FS_TYPE_LAST
} lccrt_fs_type_t;
/**
* Файловый поток данных.
*/
typedef struct lccrt_fs_r
{
lccrt_context_ptr ctx; /* etc */
lccrt_fs_type_t type; /* тип потока данных */
FILE *file;
char *buff;
uint64_t buff_size; /* размер буфера (для LCCRT_FS_TYPE_BUFFER) */
uint64_t syms_count; /* счетчик записанных или прочитанных символов */
int8_t is_self; /* флаг владением потоком данных */
int8_t is_error; /* флаг возникновения ошибки при работе с потоком данных */
lccrt_check_type_t type_check; /* средства динамического контроля типа данных */
} lccrt_fs_t;
lccrt_check_type_define( lccrt_fs_t);
/**
* Открытие потока данных.
*/
static lccrt_fs_ptr
lccrt_fs_new( lccrt_context_ptr ctx)
{
lccrt_fs_ptr r = 0;
r = lccrt_ctx_malloc( ctx, lccrt_fs_t);
memset( r, 0, sizeof( r[0]));
lccrt_check_type_init( r, lccrt_fs_t);
r->ctx = ctx;
r->type = LCCRT_FS_TYPE_LAST;
r->file = 0;
r->buff = 0;
r->buff_size = 0;
r->is_self = 0;
r->is_error = 0;
r->syms_count = 0;
return (r);
} /* lccrt_fs_new */
/**
* Открытие потока данных на основе файла.
*/
lccrt_fs_ptr
lccrt_fs_new_file( lccrt_context_ptr ctx, FILE *file)
{
lccrt_fs_ptr r = 0;
if ( file )
{
r = lccrt_fs_new( ctx);
r->type = LCCRT_FS_TYPE_FILE;
r->file = file;
}
return (r);
} /* lccrt_fs_new_file */
/**
* Открытие потока данных на основе файла.
*/
lccrt_fs_ptr
lccrt_fs_open_file( lccrt_context_ptr ctx, const char *name, int is_load)
{
lccrt_fs_ptr r = 0;
FILE *file = 0;
file = fopen( name, is_load ? "r" : "w");
if ( file )
{
r = lccrt_fs_new_file( ctx, file);
r->is_self = 1;
}
return (r);
} /* lccrt_fs_open_file */
/**
* Открытие потока данных на основе буфера в памяти.
*/
lccrt_fs_ptr
lccrt_fs_new_buffer( lccrt_context_ptr ctx, char *buff, uint64_t buff_size)
{
lccrt_fs_ptr r = 0;
r = lccrt_fs_new( ctx);
r->type = LCCRT_FS_TYPE_BUFFER;
if ( buff )
{
r->buff_size = buff_size;
r->buff = buff;
} else
{
r->is_self = 1;
r->buff_size = buff_size ? buff_size : 4096;
r->buff = lccrt_ctx_mallocn( ctx, char, r->buff_size);
}
return (r);
} /* lccrt_fs_new_buffer */
/**
* Закрытие потока данных.
*/
int
lccrt_fs_delete( lccrt_fs_ptr f)
{
int r = 0;
if ( f )
{
lccrt_check_type_assert( f, lccrt_fs_t);
if ( (f->type == LCCRT_FS_TYPE_FILE) )
{
if ( f->is_self )
{
r = fclose( f->file);
}
} else if ( (f->type == LCCRT_FS_TYPE_BUFFER) )
{
if ( f->is_self )
{
lccrt_ctx_free( f->ctx, f->buff);
}
} else
{
r = -1;
lccrt_assert( 0);
}
lccrt_check_type_done( f, lccrt_fs_t);
lccrt_ctx_free( f->ctx, f);
}
return (r);
} /* lccrt_fs_delete */
/**
* Получить значение поля.
*/
int
lccrt_fs_is_error( lccrt_fs_ptr f)
{
int r = 0;
lccrt_check_type_assert( f, lccrt_fs_t);
r = f->is_error;
return (r);
} /* lccrt_fs_is_error */
/**
* Получить значение поля.
*/
uint64_t
lccrt_fs_get_syms_count( lccrt_fs_ptr f)
{
uint64_t r = 0;
lccrt_check_type_assert( f, lccrt_fs_t);
r = f->syms_count;
return (r);
} /* lccrt_fs_get_syms_count */
/**
* Для потока данных на основе буфера дать ссылку на область данных
* (ссылка доступна только до первого действия с потоком данных).
*/
char *
lccrt_fs_get_buffer( lccrt_fs_ptr f)
{
char *r = f->buff;
lccrt_check_type_assert( f, lccrt_fs_t);
return (r);
} /* lccrt_fs_get_buffer */
/**
* Чтение символа из потока.
*/
int
lccrt_fs_get_sym( lccrt_fs_ptr f)
{
int r = EOF;
lccrt_check_type_assert( f, lccrt_fs_t);
if ( (f->type == LCCRT_FS_TYPE_FILE) )
{
r = fgetc( f->file);
if ( !feof( f->file) )
{
f->syms_count++;
}
} else if ( (f->type == LCCRT_FS_TYPE_BUFFER) )
{
if ( (f->syms_count < f->buff_size) )
{
r = f->buff[f->syms_count];
f->syms_count++;
}
} else
{
lccrt_assert( 0);
}
return (r);
} /* lccrt_fs_get_sym */
/**
* Форматированный вывод в поток данных.
*/
int
lccrt_fs_printf( lccrt_fs_ptr f, const char *fmt, ...)
{
va_list ap;
int r = 0;
lccrt_check_type_assert( f, lccrt_fs_t);
if ( !f->is_error )
{
if ( (f->type == LCCRT_FS_TYPE_FILE) )
{
va_start( ap, fmt);
r = vfprintf( f->file, fmt, ap);
va_end( ap);
} else if ( (f->type == LCCRT_FS_TYPE_BUFFER) )
{
int k = f->buff_size;
int j = f->syms_count;
lccrt_assert( f->syms_count <= f->buff_size);
lccrt_assert( f->buff_size > 0);
if ( !f->is_self )
{
va_start( ap, fmt);
r = vsnprintf( f->buff + j, k - j, fmt, ap);
va_end( ap);
if ( (r == k - j) )
{
int l = 0;
char *b = lccrt_ctx_mallocn( f->ctx, char, r + 1);
/* Проверяем, что размера буфера было достаточно для вывода
всех данных. */
va_start( ap, fmt);
l = vsnprintf( b, r + 1, fmt, ap);
va_end( ap);
lccrt_ctx_free( f->ctx, b);
if ( (r != l) )
{
/* Превышен допустимый размер буфера. */
f->is_error = 1;
}
}
} else
{
int is_work = 1;
while ( is_work )
{
va_start( ap, fmt);
r = vsnprintf( f->buff + j, k - j, fmt, ap);
va_end( ap);
if ( (r < k - j) )
{
/* Текущего размера буфера достаточно. */
is_work = 0;
} else
{
/* Необходимо увеличить размер буфера. */
f->buff_size = 2*f->buff_size;
f->buff = lccrt_ctx_realloc( f->ctx, f->buff, f->buff_size);
k = f->buff_size;
}
}
}
} else
{
lccrt_assert( 0);
r = -1;
}
if ( (r < 0) )
{
f->is_error = 1;
} else
{
f->syms_count += r;
}
}
return (r);
} /* lccrt_fs_printf */
/**
* Вывод на печать строки и символа '\0', после строки.
*/
int
lccrt_fs_print_name_str( lccrt_fs_ptr f, const char *name)
{
int r = 0;
if ( name )
{
int k = 0;
for ( k = 0; name[k]; ++k )
{
if ( (name[k] == 0)
|| (name[k] == '\\') )
{
r += lccrt_fs_printf( f, "\\");
}
r += lccrt_fs_printf( f, "%c", name[k]);
}
r += lccrt_fs_printf( f, "%c", 0);
}
return (r);
} /* lccrt_fs_print_name_str */

557
lib/common/lccrt_hash.c Normal file
View File

@ -0,0 +1,557 @@
/**
* Part of the Lccrt Project, under the Apache License v2.0
* See http://www.apache.org/licenses/LICENSE-2.0.txt for license information.
* SPDX-License-Identifier: Apache-2.0
*
* lccrt_hash.c - работа с хеш-таблицами.
*/
#include "internal/lccrt_ctx.h"
lccrt_check_type_define( lccrt_hash_entry_t);
lccrt_check_type_define( lccrt_hash_t);
/**
* Запись.
*/
typedef struct lccrt_hash_entry_r
{
uintptr_t key; /* значение ключа */
uintptr_t data; /* пользовательские данные */
int64_t bucket_ident; /* номер корзины */
lccrt_hash_ptr table; /* исходная таблица */
lccrt_hash_entry_ptr prev; /* список записей в корзине */
lccrt_hash_entry_ptr next; /* список записей в корзине */
lccrt_check_type_t type_check;
} lccrt_hash_entry_t;
/**
* Таблица.
*/
typedef struct lccrt_hash_r
{
lccrt_ctx_ptr ctx;
lccrt_hash_key_type_t key_type; /* тип ключа, используемый в таблице */
int64_t num_entries; /* общее количество всех записей */
int64_t num_buckets; /* текущее количество корзин */
lccrt_hash_entry_ptr *buckets; /* массив корзин */
int64_t bucket_path_len; /* суммарный путь поиска по спискам */
lccrt_check_type_t type_check;
} lccrt_hash_t;
#define LCCRT_HASH_IS_REDUCE( h) \
( \
((h)->num_entries < (h)->num_buckets/8) \
&& ((h)->num_buckets > 8) \
)
/**
* Создание новой таблицы.
*/
lccrt_h_ptr
lccrt_hash_new( lccrt_ctx_ptr ctx, lccrt_hkt_t type)
{
lccrt_h_ptr r = lccrt_ctx_malloc( ctx, lccrt_hash_t);
memset( r, 0, sizeof( r[0]));
lccrt_check_type_init( r, lccrt_hash_t);
r->ctx = ctx;
r->key_type = type;
lccrt_assert( (0 <= type) && (type < LCCRT_HASH_KEY_LAST));
return (r);
} /* lccrt_hash_new */
/**
* Удаление данных записи.
*/
static void
lccrt_hash_entry_delete_internal( lccrt_hash_entry_ptr he)
{
lccrt_hash_ptr h = he->table;
lccrt_ctx_ptr ctx = h->ctx;
lccrt_check_type_assert( he, lccrt_hash_entry_t);
if ( (h->key_type == LCCRT_HASH_KEY_STRING) )
{
lccrt_ctx_free( ctx, (char *)he->key);
} else
{
lccrt_assert( h->key_type == LCCRT_HASH_KEY_INTPTR);
}
lccrt_check_type_done( he, lccrt_hash_entry_t);
lccrt_ctx_free( ctx, he);
return;
} /* lccrt_hash_entry_delete_internal */
/**
* Удаление таблицы.
*/
void
lccrt_hash_delete( lccrt_hash_ptr h)
{
int64_t i;
lccrt_ctx_ptr ctx = h->ctx;
lccrt_check_type_assert( h, lccrt_hash_t);
for ( i = 0; i < h->num_buckets; ++i )
{
lccrt_hash_entry_ptr he, he_next;
he = h->buckets[i];
while ( he )
{
he_next = he->next;
lccrt_assert( i == he->bucket_ident);
lccrt_hash_entry_delete_internal( he);
he = he_next;
}
}
lccrt_ctx_free( ctx, h->buckets);
lccrt_check_type_done( h, lccrt_hash_t);
lccrt_ctx_free( ctx, h);
return;
} /* lccrt_hash_delete */
/**
* Количество элементов в хеш-таблице.
*/
int64_t
lccrt_hash_length( lccrt_hash_ptr ht)
{
int64_t r = ht->num_entries;
return (r);
} /* lccrt_hash_length */
/**
* Вычисление хеш-значения для ключа.
*/
static uint64_t
lccrt_hash_key_calc( lccrt_hash_key_type_t type, uintptr_t key)
{
uint64_t r = 0;
if ( (type == LCCRT_HASH_KEY_INTPTR) )
{
r = (uint64_t)key * 1103515245ULL;
} else if ( (type == LCCRT_HASH_KEY_STRING) )
{
const char *p = (char *)key;
while ( p[0] )
{
r = ((r << 7) | (r >> (64 - 7))) ^ (uint64_t)p[0];
++p;
}
} else
{
lccrt_assert( 0);
}
return (r);
} /* lccrt_hash_key_calc */
/**
* Вычисление корзины для ключа.
*/
static int64_t
lccrt_hash_key_calc_pos( lccrt_hash_ptr h, uintptr_t key)
{
int64_t r = -1;
lccrt_check_type_assert( h, lccrt_hash_t);
if ( (h->num_buckets > 0) )
{
r = lccrt_hash_key_calc( h->key_type, key) % h->num_buckets;
}
return (r);
} /* lccrt_hash_key_calc_pos */
/**
* Сравнение двух ключей на равенство.
*/
static uintptr_t
lccrt_hash_key_copy( lccrt_ctx_ptr ctx, lccrt_hkt_t type, uintptr_t key)
{
uintptr_t r = 0;
if ( (type == LCCRT_HASH_KEY_STRING) )
{
r = (uintptr_t)lccrt_ctx_copy_str( ctx, (const char *)key);
} else if ( (type == LCCRT_HASH_KEY_INTPTR) )
{
r = key;
} else
{
lccrt_assert( 0);
}
return (r);
} /* lccrt_hash_key_copy */
/**
* Сравнение двух ключей на равенство.
*/
static int
lccrt_hash_keys_equal( lccrt_hkt_t type, uintptr_t key1, uintptr_t key2)
{
int r = 0;
if ( (type == LCCRT_HASH_KEY_STRING) )
{
r = lccrt_str_eq( (const char *)key1, (const char *)key2);
} else if ( (type == LCCRT_HASH_KEY_INTPTR) )
{
r = (key1 == key2);
} else
{
lccrt_assert( 0);
}
return (r);
} /* lccrt_hash_keys_equal */
/**
* Поиск в корзине записи с ключом заданного значения.
*/
static lccrt_hash_entry_ptr
lccrt_hash_bucket_find_key( lccrt_hash_entry_ptr he, uintptr_t key)
{
lccrt_hash_entry_ptr r = 0;
lccrt_check_type_assert( he, lccrt_hash_entry_t);
if ( he )
{
int64_t i = 0;
lccrt_hash_ptr h = he->table;
lccrt_hash_key_type_t type = h->key_type;
lccrt_check_type_assert( h, lccrt_hash_t);
if ( (type == LCCRT_HASH_KEY_INTPTR) )
{
for ( ; he ; he = he->next, i++ )
{
if ( (key == he->key) )
{
r = he;
break;
}
}
} else if ( (type == LCCRT_HASH_KEY_STRING) )
{
for ( ; he ; he = he->next, i++ )
{
if ( lccrt_hash_keys_equal( type, key, he->key) )
{
r = he;
break;
}
}
} else
{
lccrt_assert( 0);
}
h->bucket_path_len += i;
}
return (r);
} /* lccrt_hash_bucket_find_key */
/**
* Создать новую запись и вставить ее в список записей.
*/
static lccrt_hash_entry_ptr
lccrt_hash_entry_new( lccrt_hash_ptr h, uintptr_t key, uintptr_t data,
int64_t bucket_ident, lccrt_he_ptr prev, lccrt_he_ptr next)
{
lccrt_ctx_ptr ctx = h->ctx;
lccrt_hash_key_type_t type = h->key_type;
lccrt_hash_entry_ptr r = lccrt_ctx_malloc( ctx, lccrt_hash_entry_t);
lccrt_check_type_assert( h, lccrt_hash_t);
memset( r, 0, sizeof( r[0]));
lccrt_check_type_init( r, lccrt_hash_entry_t);
r->table = h;
r->bucket_ident = bucket_ident;
r->key = lccrt_hash_key_copy( ctx, type, key);
r->data = data;
r->prev = prev;
r->next = next;
if ( next )
{
next->prev = r;
}
if ( prev )
{
prev->next = r;
}
return (r);
} /* lccrt_hash_entry_new */
/**
* Увеличение/уменьшение количества корзин.
*/
static void
lccrt_hash_rebuild( lccrt_hash_ptr h, int is_increase)
{
lccrt_ctx_ptr ctx = h->ctx;
lccrt_hash_key_type_t type = h->key_type;
lccrt_check_type_assert( h, lccrt_hash_t);
h->bucket_path_len = 0;
if ( (h->num_entries > 0) )
{
int64_t i;
lccrt_hash_entry_ptr *buckets = h->buckets;
int64_t num_buckets = h->num_buckets;
h->num_buckets = is_increase ? 2*num_buckets : num_buckets/2;
lccrt_assert( num_buckets > 0);
h->buckets = lccrt_ctx_mallocn( ctx, lccrt_hash_entry_ptr, h->num_buckets);
memset( h->buckets, 0, h->num_buckets*sizeof( h->buckets[0]));
for ( i = 0; i < num_buckets; ++i )
{
lccrt_hash_entry_ptr e, e_next;
for ( e = buckets[i]; e; e = e_next )
{
int64_t key_pos = lccrt_hash_key_calc_pos( h, e->key);
e_next = e->next;
h->buckets[key_pos] = lccrt_hash_entry_new( h, e->key, e->data, key_pos, 0, h->buckets[key_pos]);
lccrt_hash_entry_delete_internal( e);
}
}
lccrt_ctx_free( ctx, buckets);
}
return;
} /* lccrt_hash_rebuild */
/**
* Добавить в таблицу запись с заданным ключом.
*/
lccrt_hash_entry_ptr
lccrt_hash_push( lccrt_hash_ptr h, uintptr_t key, int *is_new)
{
lccrt_hash_entry_ptr r = 0;
lccrt_ctx_ptr ctx = h->ctx;
lccrt_hash_key_type_t type = h->key_type;
int64_t key_pos = -1;
lccrt_hash_entry_ptr he = 0;
lccrt_check_type_assert( h, lccrt_hash_t);
if ( (h->num_buckets == 0) )
{
lccrt_assert( h->num_entries == 0);
h->num_buckets = 1;
h->buckets = lccrt_ctx_mallocn( ctx, lccrt_hash_entry_ptr, 1);
key_pos = 0;
he = 0;
} else
{
key_pos = lccrt_hash_key_calc_pos( h, key);
he = h->buckets[key_pos];
r = lccrt_hash_bucket_find_key( he, key);
}
if ( r )
{
lccrt_assign( is_new, 0);
} else
{
lccrt_assign( is_new, 1);
r = lccrt_hash_entry_new( h, key, 0, key_pos, 0, he);
h->buckets[key_pos] = r;
h->num_entries++;
}
#if 0
if ( (h->bucket_path_len >= h->num_entries) )
{
//lccrt_hash_rebuild( h);
}
#endif
if ( (h->num_entries > 0)
&& (h->num_entries >= 4*h->num_buckets) )
{
lccrt_hash_rebuild( h, 1);
r = lccrt_hash_find( h, key);
}
return (r);
} /* lccrt_hash_push */
/**
* Поиск записи.
*/
lccrt_hash_entry_ptr
lccrt_hash_find( lccrt_hash_ptr h, uintptr_t key)
{
lccrt_hash_entry_ptr r = 0;
lccrt_check_type_assert( h, lccrt_hash_t);
if ( (h->num_entries > 0)
&& (h->num_entries >= 4*h->num_buckets) )
{
lccrt_assert( 0);
//lccrt_hash_rebuild( h, 1);
}
if ( (h->num_entries > 0) )
{
int64_t key_pos = lccrt_hash_key_calc_pos( h, key);
lccrt_hash_entry_ptr he = h->buckets[key_pos];
r = lccrt_hash_bucket_find_key( he, key);
}
return (r);
} /* lccrt_hash_find */
/**
* Поиск записи.
*/
uintptr_t
lccrt_hash_remove( lccrt_hash_entry_ptr he)
{
lccrt_hash_entry_ptr r = 0;
lccrt_hash_entry_ptr he_prev = he->prev;
lccrt_hash_entry_ptr he_next = he->next;
lccrt_hash_ptr h = he->table;
lccrt_check_type_assert( he, lccrt_hash_entry_t);
lccrt_check_type_assert( h, lccrt_hash_t);
if ( he->next )
{
he_next->prev = he_prev;
}
if ( he_prev )
{
he_prev->next = he_next;
} else
{
h->buckets[he->bucket_ident] = he_next;
}
lccrt_hash_entry_delete_internal( he);
he = 0;
h->num_entries--;
if ( LCCRT_HASH_IS_REDUCE( h) )
{
lccrt_hash_rebuild( h, 0);
}
return (0);
} /* lccrt_hash_remove */
/**
* Получить пользовательские данные.
*/
uintptr_t
lccrt_hash_get_key( lccrt_hash_entry_ptr he)
{
uintptr_t r = he->key;
lccrt_check_type_assert( he, lccrt_hash_entry_t);
return (r);
} /* lccrt_hash_get_key */
/**
* Получить пользовательские данные.
*/
uintptr_t
lccrt_hash_get( lccrt_hash_entry_ptr he)
{
uintptr_t r = he->data;
lccrt_check_type_assert( he, lccrt_hash_entry_t);
return (r);
} /* lccrt_hash_get */
/**
* Получить пользовательские данные.
*/
uintptr_t
lccrt_hash_set( lccrt_hash_entry_ptr he, uintptr_t data)
{
uintptr_t r = lccrt_hash_get( he);
he->data = data;
return (r);
} /* lccrt_hash_set */
/**
* Получить первую запись.
*/
lccrt_hash_entry_ptr
lccrt_hash_first( lccrt_hash_ptr h)
{
int64_t i;
lccrt_hash_entry_ptr r = 0;
lccrt_check_type_assert( h, lccrt_hash_t);
if ( (h->num_entries > 0) )
{
for ( i = 0; i < h->num_buckets; ++i )
{
if ( h->buckets[i] )
{
r = h->buckets[i];
break;
}
}
}
return (r);
} /* lccrt_hash_first */
/**
* Получить следующую запись.
*/
lccrt_hash_entry_ptr
lccrt_hash_next( lccrt_hash_entry_ptr he)
{
lccrt_hash_entry_ptr r = 0;
lccrt_hash_ptr h = he->table;
lccrt_check_type_assert( he, lccrt_hash_entry_t);
lccrt_check_type_assert( h, lccrt_hash_t);
if ( he->next )
{
r = he->next;
} else
{
int64_t i;
for ( i = he->bucket_ident + 1; i < h->num_buckets; ++i )
{
if ( h->buckets[i] )
{
r = h->buckets[i];
break;
}
}
}
return (r);
} /* lccrt_hash_next */

147
lib/irv/lccrt_asmout.c Normal file
View File

@ -0,0 +1,147 @@
/**
* Part of the Lccrt Project, under the Apache License v2.0
* See http://www.apache.org/licenses/LICENSE-2.0.txt for license information.
* SPDX-License-Identifier: Apache-2.0
*
* lccrt_asm.c - реализация печати ассемблера.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include "lccrt_real.h"
#define lccrt_snprintf_max( l, j) ((j < (l)) ? ((l) - j) : 0)
#define lccrt_snprintf( s, l, j, ...) \
(j += snprintf( s + j, lccrt_snprintf_max( l, j), __VA_ARGS__))
/**
* Основная структура данных модуля печати ассемблера.
*/
typedef struct
{
lccrt_fs_ptr fs; /* выходной поток данных */
lccrt_hash_ptr types; /* множество типов, определение которых уже напечатаны */
} lccrt_asm_out_t;
/**
* Печать название идентификатора с экранированием по необходимости.
*/
void
lccrt_asm_print_name( lccrt_asm_out_t *ao, const char *name)
{
int i;
int is_simple = 1;
for ( i = 0; name[i]; ++i )
{
if ( 0 )
{
is_simple = 0;
}
}
if ( is_simple )
{
lccrt_fs_printf( ao->fs, "%s", name);
} else
{
lccrt_fs_printf( ao->fs, "\"");
for ( i = 0; name[i]; ++i )
{
if ( 0 )
{
lccrt_fs_printf( ao->fs, "%c", name[i]);
} else
{
lccrt_fs_printf( ao->fs, "\\%c", name[i]);
}
}
lccrt_fs_printf( ao->fs, "\"");
}
return;
} /* lccrt_asm_print_name */
void
lccrt_asm_print_type_definition( lccrt_asm_out_t *ao, lccrt_type_ptr type)
{
lccrt_hash_entry_ptr e;
lccrt_check_type_assert( type, lccrt_type_t);
e = lccrt_hash_find( ao->types, (uintptr_t)type);
if ( e )
{
} else if ( (type->type_name == LCCRT_TYPE_VOID)
|| (type->type_name == LCCRT_TYPE_BOOL)
|| (type->type_name == LCCRT_TYPE_INT)
|| (type->type_name == LCCRT_TYPE_FLOAT)
|| (type->type_name == LCCRT_TYPE_ELLIPSIS) )
{
} else if ( (type->type_name == LCCRT_TYPE_PTR) )
{
//lccrt_fs_printf( ao->fs, "type ");
//lccrt_asm_print_type_definition( ao, type->parent);
} else if ( (type->type_name == LCCRT_TYPE_FUNC) )
{
} else if ( (type->type_name == LCCRT_TYPE_STRUCT) )
{
} else if ( (type->type_name == LCCRT_TYPE_FIELD) )
{
} else if ( (type->type_name == LCCRT_TYPE_ARRAY) )
{
} else
{
fprintf( stderr, "type: %s\n", type->sym_name);
lccrt_assert( 0);
}
return;
} /* lccrt_asm_print_type */
void
lccrt_asm_print_var( lccrt_asm_out_t *ao, lccrt_var_ptr v, int is_global)
{
lccrt_check_type_assert( v, lccrt_var_t);
lccrt_fs_printf( ao->fs, "var ");
lccrt_asm_print_name( ao, v->name);
return;
} /* lccrt_asm_print_var */
/**
* Печатаем в выходной поток модуль.
*/
void
lccrt_asm_print_module( lccrt_fs_ptr fs, lccrt_module_ptr m)
{
lccrt_hash_entry_ptr e;
lccrt_asm_out_t ao = {0};
ao.fs = fs;
ao.types = lccrt_hash_new( m->ctx, LCCRT_HASH_KEY_INTPTR);
for ( e = lccrt_hash_first( m->types); e; e = lccrt_hash_next( e) )
{
lccrt_asm_print_type_definition( &ao, (lccrt_type_ptr)lccrt_hash_get( e));
}
for ( e = lccrt_hash_first( m->gvars); e; e = lccrt_hash_next( e) )
{
lccrt_asm_print_var( &ao, (lccrt_var_ptr)lccrt_hash_get( e), 1);
}
lccrt_hash_delete( ao.types);
return;
} /* lccrt_asm_print_module */

1241
lib/irv/lccrt_func.c Normal file

File diff suppressed because it is too large Load Diff

4045
lib/irv/lccrt_irreader.c Normal file

File diff suppressed because it is too large Load Diff

1483
lib/irv/lccrt_irwriter.c Normal file

File diff suppressed because it is too large Load Diff

128
lib/irv/lccrt_link.c Normal file
View File

@ -0,0 +1,128 @@
/**
* Part of the Lccrt Project, under the Apache License v2.0
* See http://www.apache.org/licenses/LICENSE-2.0.txt for license information.
* SPDX-License-Identifier: Apache-2.0
*
* lccrt_link.c - реализация пользовательский интерфейс (динамической) компиляции.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include "lccrt_real.h"
/**
* Получить значение.
*/
lccrt_link_t
lccrt_link_get( lccrt_link_bind_t bnd, lccrt_link_visibility_t vis, lccrt_link_tls_t tls,
int is_cnst, int is_alias)
{
lccrt_link_t r = 0;
LCCRT_LINK_BYTE_BND( &r) = bnd;
LCCRT_LINK_BYTE_VIS( &r) = vis;
LCCRT_LINK_BYTE_TLS( &r) = tls;
LCCRT_LINK_BYTE_CST( &r) = is_cnst;
LCCRT_LINK_BYTE_ALS( &r) = is_alias;
return (r);
} /* lccrt_link_get */
/**
* Получить значение.
*/
lccrt_link_t
lccrt_link_conv( lccrt_asmlink_t link)
{
lccrt_link_t r = 0;
r = lccrt_link_get( link.bnd, link.vis, link.tls, link.is_cnst, link.is_alias);
return (r);
} /* lccrt_link_conv */
/**
* Получить значение поля.
*/
lccrt_link_bind_t
lccrt_link_get_bnd( lccrt_link_t link)
{
lccrt_link_bind_t r;
r = LCCRT_LINK_BYTE_BND( &link);
return (r);
} /* lccrt_link_get_bnd */
/**
* Получить значение поля.
*/
lccrt_link_visibility_t
lccrt_link_get_vis( lccrt_link_t link)
{
lccrt_link_visibility_t r;
r = LCCRT_LINK_BYTE_VIS( &link);
return (r);
} /* lccrt_link_get_vis */
/**
* Получить значение поля.
*/
lccrt_link_tls_t
lccrt_link_get_tls( lccrt_link_t link)
{
lccrt_link_tls_t r;
r = LCCRT_LINK_BYTE_TLS( &link);
return (r);
} /* lccrt_link_get_tls */
/**
* Получить значение поля.
*/
int
lccrt_link_is_const( lccrt_link_t link)
{
int r;
r = LCCRT_LINK_BYTE_CST( &link);
return (r);
} /* lccrt_link_is_const */
/**
* Получить значение поля.
*/
int
lccrt_link_is_alias( lccrt_link_t link)
{
int r;
r = LCCRT_LINK_BYTE_ALS( &link);
return (r);
} /* lccrt_link_is_alias */
/**
* Получить значение.
*/
lccrt_asmlink_t
lccrt_link_unpack( lccrt_link_t link)
{
lccrt_asmlink_t r = {0};
r.bnd = LCCRT_LINK_BYTE_BND( &link);
r.vis = LCCRT_LINK_BYTE_VIS( &link);
r.tls = LCCRT_LINK_BYTE_TLS( &link);
r.is_cnst = LCCRT_LINK_BYTE_CST( &link);
r.is_alias = LCCRT_LINK_BYTE_ALS( &link);
return (r);
} /* lccrt_link_unpack */

1091
lib/irv/lccrt_metadata.c Normal file

File diff suppressed because it is too large Load Diff

452
lib/irv/lccrt_module.c Normal file
View File

@ -0,0 +1,452 @@
/**
* Part of the Lccrt Project, under the Apache License v2.0
* See http://www.apache.org/licenses/LICENSE-2.0.txt for license information.
* SPDX-License-Identifier: Apache-2.0
*
* lccrt_module.c - реализация пользовательский интерфейс (динамической) компиляции.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include "lccrt_real.h"
/**
* Инициализация контекста (стандартные типы).
*/
static void
lccrt_module_init_types_std( lccrt_module_ptr m)
{
lccrt_types_std_t *ts = &(m->types_std);
lccrt_check_type_assert( m, lccrt_module_t);
ts->ptr_bytesize = m->is_ptr32 ? 4 : 8;
ts->bool_type = lccrt_type_make_simple( m, LCCRT_TYPE_BOOL, "bool", 0, 1, 1);
//ts->bool_type = lccrt_type_make_simple( m, LCCRT_TYPE_INT, "u8", 0, 1);
ts->void_type = lccrt_type_make_simple( m, LCCRT_TYPE_VOID, "void", 0, 1, 0);
ts->int_types[0][0] = lccrt_type_make_simple( m, LCCRT_TYPE_INT, "u8", 0, 1, 1);
ts->int_types[0][1] = lccrt_type_make_simple( m, LCCRT_TYPE_INT, "u16", 0, 2, 2);
ts->int_types[0][2] = lccrt_type_make_simple( m, LCCRT_TYPE_INT, "u32", 0, 4, 4);
ts->int_types[0][3] = lccrt_type_make_simple( m, LCCRT_TYPE_INT, "u64", 0, 8, 8);
ts->int_types[0][4] = lccrt_type_make_simple( m, LCCRT_TYPE_INT, "u128", 0, 16, 16);
ts->int_types[0][5] = 0;
ts->int_types[1][0] = lccrt_type_make_simple( m, LCCRT_TYPE_INT, "i8", 1, 1, 1);
ts->int_types[1][1] = lccrt_type_make_simple( m, LCCRT_TYPE_INT, "i16", 1, 2, 2);
ts->int_types[1][2] = lccrt_type_make_simple( m, LCCRT_TYPE_INT, "i32", 1, 4, 4);
ts->int_types[1][3] = lccrt_type_make_simple( m, LCCRT_TYPE_INT, "i64", 1, 8, 8);
ts->int_types[1][4] = lccrt_type_make_simple( m, LCCRT_TYPE_INT, "i128", 1, 16, 16);
ts->int_types[1][5] = 0;
ts->float_types[0] = lccrt_type_make_simple( m, LCCRT_TYPE_FLOAT, "f32", 0, 4, 4);
ts->float_types[1] = lccrt_type_make_simple( m, LCCRT_TYPE_FLOAT, "f64", 0, 8, 8);
ts->float_types[2] = lccrt_type_make_simple( m, LCCRT_TYPE_FLOAT, "f80", 0, 16, 10);
ts->float_types[3] = lccrt_type_make_simple( m, LCCRT_TYPE_FLOAT, "f128", 0, 16, 16);
ts->float_types[4] = 0;
ts->ellipsis = lccrt_type_make_simple( m, LCCRT_TYPE_ELLIPSIS, "...", 0, 1, 0);
ts->intptr = ts->int_types[0][m->is_ptr32 ? LCCRT_INT_SUBTYPE_32 : LCCRT_INT_SUBTYPE_64];
ts->ptr_byte = lccrt_type_make_ptr_type( ts->int_types[0][LCCRT_INT_SUBTYPE_8]);
ts->ptr_char = lccrt_type_make_ptr_type( ts->int_types[1][LCCRT_INT_SUBTYPE_8]);
ts->ptr_intptr = lccrt_type_make_ptr_type( ts->intptr);
return;
} /* lccrt_module_init_types_std */
/**
* Создание нового модуля.
*/
lccrt_module_ptr
lccrt_module_new( lccrt_context_ptr ctx, const char *name, int is_m32)
{
lccrt_module_ptr m = lccrt_ctx_malloc( ctx, lccrt_module_t);
lccrt_check_type_assert( ctx, lccrt_context_t);
memset( m, 0, sizeof( m[0]));
lccrt_check_type_init( m, lccrt_module_t);
m->ctx = ctx;
m->name = lccrt_ctx_copy_str( ctx, name);
m->is_ptr32 = is_m32;
m->types = lccrt_hash_new( ctx, LCCRT_HASH_KEY_STRING);
m->type_usr_names = lccrt_hash_new( ctx, LCCRT_HASH_KEY_STRING);
m->type_max = 0;
m->gvars = lccrt_hash_new( ctx, LCCRT_HASH_KEY_STRING);
m->funcs = lccrt_hash_new( ctx, LCCRT_HASH_KEY_STRING);
m->einfo_cats = lccrt_hash_new( ctx, LCCRT_HASH_KEY_STRING);
m->einfo_tyarrs = lccrt_hash_new( ctx, LCCRT_HASH_KEY_INTPTR);
m->einfo_tysts = lccrt_hash_new( ctx, LCCRT_HASH_KEY_STRING);
lccrt_ilist_head_init( &(m->types_head));
lccrt_ilist_head_init( &(m->gvars_head));
lccrt_ilist_head_init( &(m->funcs_head));
lccrt_ilist_head_init( &(m->varinits_head));
ctx->module_max++;
m->ident_num = ctx->module_max;
m->gvars_num = 0;
m->funcs_num = 0;
m->cargs_name_id = 0;
m->global_name_id = 0;
lccrt_hash_push( ctx->modules, (uintptr_t)m, 0);
lccrt_module_init_types_std( m);
return (m);
} /* lccrt_module_new */
/**
* Удаление модуля.
*/
void
lccrt_module_delete_data( lccrt_m_ptr m)
{
lccrt_varinit_ptr vi_unit;
lccrt_einfo_block_ptr eib_unit, eib_next;
lccrt_einfo_tydescr_ptr eitd_unit, eitd_next;
lccrt_hash_entry_ptr e = 0;
lccrt_context_ptr ctx = m->ctx;
lccrt_check_type_assert( m, lccrt_module_t);
lccrt_ctx_free( ctx, m->name);
lccrt_ctx_free( ctx, m->asm_text);
/* Удаляем все ранее созданные типы и сопутствующие структуры данных. */
for ( e = lccrt_hash_first( m->funcs); e; e = lccrt_hash_next( e) )
{
lccrt_function_delete( (lccrt_f_ptr)lccrt_hash_get( e));
}
lccrt_hash_delete( m->funcs);
for ( e = lccrt_hash_first( m->gvars); e; e = lccrt_hash_next( e) )
{
lccrt_var_delete( (lccrt_v_ptr)lccrt_hash_get( e));
}
lccrt_hash_delete( m->gvars);
for ( vi_unit = m->varinits_head.first; vi_unit; vi_unit = m->varinits_head.first )
{
lccrt_varinit_delete( vi_unit);
}
/* Удаляем цепочку привязку к модулю собственных мета-данных. */
m->einfo = lccrt_einfo_link_delete_chain( m->einfo);
/* Удаляем все категории мета-данных. */
lccrt_hash_delete( m->einfo_cats);
/* Удаляем все мета-данные. */
for ( eib_unit = m->eblocks_head; eib_unit; eib_unit = eib_next )
{
eib_next = eib_unit->next;
lccrt_einfo_block_delete( eib_unit);
}
/* Удаляем все описания типов мета-данных. */
for ( eitd_unit = m->etydescrs_head; eitd_unit; eitd_unit = eitd_next )
{
eitd_next = eitd_unit->next;
lccrt_einfo_tydescr_delete( eitd_unit);
}
/* Удаляем таблицы хеширования описания мета-данных. */
lccrt_hash_delete( m->einfo_tyarrs);
lccrt_hash_delete( m->einfo_tysts);
for ( e = lccrt_hash_first( m->types); e; e = lccrt_hash_next( e) )
{
lccrt_type_delete( (lccrt_t_ptr)lccrt_hash_get( e));
}
lccrt_hash_delete( m->types);
lccrt_hash_delete( m->type_usr_names);
lccrt_check_type_done( m, lccrt_module_t);
lccrt_ctx_free( ctx, m);
return;
} /* lccrt_module_delete_data */
/**
* Удаление модуля.
*/
void
lccrt_module_delete( lccrt_module_ptr m)
{
lccrt_context_ptr ctx = m->ctx;
lccrt_hash_entry_ptr he = lccrt_hash_find( ctx->modules, (uintptr_t)m);
lccrt_check_type_assert( m, lccrt_module_t);
lccrt_check_type_assert( ctx, lccrt_context_t);
lccrt_module_delete_data( m);
if ( he )
{
lccrt_hash_remove( he);
}
return;
} /* lccrt_module_delete */
/**
* Прочитать поле.
*/
lccrt_context_ptr
lccrt_module_get_context( lccrt_module_ptr m)
{
lccrt_context_ptr r = m->ctx;
lccrt_check_type_assert( m, lccrt_module_t);
return (r);
} /* lccrt_module_get_context */
/**
* Прочитать поле.
*/
const char *
lccrt_module_get_inline_asm( lccrt_m_ptr m)
{
const char *r = m->asm_text;
lccrt_check_type_assert( m, lccrt_module_t);
return (r);
} /* lccrt_module_get_inline_asm */
/**
* Прочитать поле.
*/
void
lccrt_module_set_inline_asm( lccrt_m_ptr m, const char *asm_text)
{
lccrt_ctx_ptr ctx = m->ctx;
lccrt_check_type_assert( m, lccrt_module_t);
lccrt_ctx_free( ctx, m->asm_text);
m->asm_text = lccrt_ctx_copy_str( ctx, asm_text);
return;
} /* lccrt_module_set_inline_asm */
/**
* Прочитать поле.
*/
uint64_t
lccrt_module_get_type_max( lccrt_module_ptr m)
{
uint64_t r = m->type_max;
lccrt_check_type_assert( m, lccrt_module_t);
return (r);
} /* lccrt_module_get_type_max */
/**
* Прочитать поле.
*/
uint64_t
lccrt_module_get_func_max( lccrt_module_ptr m)
{
uint64_t r = m->funcs_num;
lccrt_check_type_assert( m, lccrt_module_t);
return (r);
} /* lccrt_module_get_func_max */
/**
* Прочитать поле.
*/
const char*
lccrt_module_get_name( lccrt_module_ptr m)
{
const char *r = m->name;
lccrt_check_type_assert( m, lccrt_module_t);
return (r);
} /* lccrt_module_get_name */
/**
* Формирование нового имени для глобальной переменной.
*/
char *
lccrt_module_name_new_global( lccrt_m_ptr module, const char *name)
{
char str[1024];
const char *q = name;
char *result = 0;
lccrt_check_type_assert( module, lccrt_module_t);
if ( !name )
{
snprintf( str, 1024, "__lccrt_g%j", module->global_name_id);
module->global_name_id++;
q = str;
}
result = lccrt_ctx_copy_str( module->ctx, q);
return (result);
} /* lccrt_module_name_new_global */
/**
* Прочитать поле.
*/
int
lccrt_module_is_ptr32( lccrt_module_ptr m)
{
int r = m->is_ptr32;
lccrt_check_type_assert( m, lccrt_module_t);
return (r);
} /* lccrt_module_is_ptr32 */
/**
* Прочитать поле.
*/
lccrt_hash_ptr
lccrt_module_get_types( lccrt_module_ptr m)
{
lccrt_check_type_assert( m, lccrt_module_t);
return (m->types);
} /* lccrt_module_get_types */
/**
* Прочитать поле.
*/
lccrt_hash_ptr
lccrt_module_get_gvars( lccrt_module_ptr m)
{
lccrt_check_type_assert( m, lccrt_module_t);
return (m->gvars);
} /* lccrt_module_get_gvars */
/**
* Прочитать поле.
*/
lccrt_hash_ptr
lccrt_module_get_funcs( lccrt_module_ptr m)
{
lccrt_check_type_assert( m, lccrt_module_t);
return (m->funcs);
} /* lccrt_module_get_funcs */
/**
* Получить первый тип модуля.
*/
lccrt_type_ptr
lccrt_module_get_first_type( lccrt_module_ptr m)
{
lccrt_type_ptr r;
lccrt_check_type_assert( m, lccrt_module_t);
r = m->types_head.first;
lccrt_check_type_assert( r, lccrt_type_t);
return (r);
} /* lccrt_module_get_first_type */
/**
* Получить первую глобальную переменную модуля.
*/
lccrt_var_ptr
lccrt_module_get_first_var( lccrt_module_ptr m)
{
lccrt_var_ptr r;
lccrt_check_type_assert( m, lccrt_module_t);
r = m->gvars_head.first;
lccrt_assert( !r || lccrt_var_is_global( r));
return (r);
} /* lccrt_module_get_first_var */
/**
* Получить первую глобальную переменную модуля.
*/
lccrt_function_ptr
lccrt_module_get_first_func( lccrt_module_ptr m)
{
lccrt_function_ptr r;
lccrt_check_type_assert( m, lccrt_module_t);
r = m->funcs_head.first;
return (r);
} /* lccrt_module_get_first_func */
/**
* Поиск функции по имени.
*/
lccrt_function_ptr
lccrt_module_find_function( lccrt_module_ptr m, const char *name)
{
lccrt_hash_entry_ptr e = lccrt_hash_find( m->funcs, (uintptr_t)name);
lccrt_function_ptr r = e ? (lccrt_f_ptr)lccrt_hash_get( e) : 0;
lccrt_check_type_assert( m, lccrt_module_t);
return (r);
} /* lccrt_module_find_function */
/**
* Добавить в модуль новые мета-данные, либо изменить значение старых.
*/
void
lccrt_module_set_einfo( lccrt_module_ptr m, lccrt_einfo_category_t ecat, lccrt_eir_t value)
{
lccrt_check_type_assert( m, lccrt_module_t);
lccrt_assert( !lccrt_einfo_is_scalar( value));
m->einfo = lccrt_einfo_link_push_value( m, m->einfo, ecat, value);
return;
} /* lccrt_module_set_einfo */
/**
* Получить значение мета-данных с заданным именем или 0, если таких данных нет.
*/
lccrt_einfo_reference_t
lccrt_module_get_einfo( lccrt_module_ptr m, lccrt_einfo_category_t ecat)
{
lccrt_einfo_link_ptr unit = lccrt_einfo_link_find( m->einfo, ecat);
lccrt_einfo_reference_t r = lccrt_einfo_link_get_value( unit);
lccrt_check_type_assert( m, lccrt_module_t);
return (r);
} /* lccrt_module_get_einfo */
/**
* Получить первую глобальную переменную модуля.
*/
void
lccrt_module_rename( lccrt_module_ptr m, const char *new_name)
{
lccrt_check_type_assert( m, lccrt_module_t);
lccrt_assert( 0);
return;
} /* lccrt_module_rename */
/**
* Всем типам, у которых не задано пользовательское имя, назначить пользовательское имя.
*/
void
lccrt_module_init_types_usr_names( lccrt_module_ptr m)
{
lccrt_hash_entry_ptr e;
for ( e = lccrt_hash_first( m->types); e; e = lccrt_hash_next( e) )
{
lccrt_type_ptr t = (lccrt_type_ptr)(uintptr_t)lccrt_hash_get( e);
if ( t->usr_name )
{
}
}
return;
} /* lccrt_module_init_types_usr_names */

2137
lib/irv/lccrt_oper.c Normal file

File diff suppressed because it is too large Load Diff

1405
lib/irv/lccrt_type.c Normal file

File diff suppressed because it is too large Load Diff

1606
lib/irv/lccrt_var.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,15 @@
/**
* Part of the Lccrt Project, under the Apache License v2.0
* See http://www.apache.org/licenses/LICENSE-2.0.txt for license information.
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <ctype.h>
#include "lccrt.h"
extern int lcbe_emit_c( lccrt_module_ptr m, const char *c_name);

File diff suppressed because it is too large Load Diff

2345
tools/lcbe/src/lcbe_emit.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,511 @@
/**
* Part of the Lccrt Project, under the Apache License v2.0
* See http://www.apache.org/licenses/LICENSE-2.0.txt for license information.
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif /* !_GNU_SOURCE */
#include <stdint.h>
#include <stdio.h>
#include <math.h>
#include <assert.h>
#define __LCCRT_UMAX_U32 (0xffffffffULL)
#define __LCCRT_SMIN_S32 ((int32_t)0x80000000LL)
#define __LCCRT_SMAX_S32 ((int32_t)0x7fffffffLL)
#define __LCCRT_UMAX_U64 (0xffffffffffffffffULL)
#define __LCCRT_SMIN_S64 ((int64_t)0x8000000000000000LL)
#define __LCCRT_SMAX_S64 ((int64_t)0x7fffffffffffffffLL)
#define __LCCRT_SMIN_U64 (0x8000000000000000ULL)
#define __LCCRT_SMAX_U64 (0x7fffffffffffffffULL)
#define __LCCRT_MIN( a, b) (((a) <= (b)) ? (a) : (b))
#define __LCCRT_MAX( a, b) (((a) >= (b)) ? (a) : (b))
#define __LCCRT_BITS( x, h, l) ((((x) << (63ULL - (h)))) >> ((63ULL - (h)) + (l)))
#define __LCCRT_PRINT_BITS2( b0, b1) \
( \
printf( "%s:%d\n%s:%d\n", #b0, (int)(b0), #b1, (int)(b1)) \
)
#define __LCCRT_PRINT_BITS3( b0, b1, b2) \
( \
printf( "%s:%d\n%s:%d\n%s:%d\n", #b0, (int)(b0), #b1, (int)(b1), #b2, (int)(b2)) \
)
#define __LCCRT_PRINT_BITS4( b0, b1, b2, b3) \
( \
printf( "%s:%d\n%s:%d\n%s:%d\n:%s:%d\n", #b0, (int)(b0), #b1, (int)(b1), #b2, (int)(b2), #b3, (int)(b3)) \
)
#define __LCCRT_N_ARG1( rbits, abits, r, a) \
uint32_t rbits, uint32_t abits, uint8_t *r, uint8_t *a
#define __LCCRT_N_ARG2( rbits, abits, bbits, r, a, b) \
uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b
#define __LCCRT_N_ARG3( rbits, abits, bbits, cbits, r, a, b, c) \
uint32_t rbits, uint32_t abits, uint32_t bbits, uint32_t cbits, uint8_t *r, uint8_t *a, uint8_t *b, uint8_t *c
#define __LCCRT_VEC_ARGS1( rbits, abits, r, a, rnum, anum, rebits, aebits) \
uint32_t rbits, uint32_t abits, uint8_t *r, uint8_t *a, \
uint32_t rnum, uint32_t anum, uint32_t rebits, uint32_t aebits
#define __LCCRT_VEC_ARGS2( rbits, abits, bbits, r, a, b, rnum, anum, bnum, rebits, aebits, bebits) \
uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b, \
uint32_t rnum, uint32_t anum, uint32_t bnum, uint32_t rebits, uint32_t aebits, uint32_t bebits
#define __LCCRT_VEC_ARGS3( rb, ab, bb, cb, r, a, b, c, rn, an, bn, cn, reb, aeb, beb, ceb) \
uint32_t rb, uint32_t ab, uint32_t bb, uint32_t cb, \
uint8_t *r, uint8_t *a, uint8_t *b, uint8_t *c, \
uint32_t rn, uint32_t an, uint32_t bn, uint32_t cn, \
uint32_t reb, uint32_t aeb, uint32_t beb, uint32_t ceb
typedef float __lccrt_f32_t;
typedef double __lccrt_f64_t;
typedef long double __lccrt_f80_t;
typedef __lccrt_f32_t f32_t;
typedef __lccrt_f64_t f64_t;
#define __define_lccrt_nint_t( N) typedef struct { uint8_t a[((N) + 7)/8]; } __lccrt_nint##N##_t
__define_lccrt_nint_t( 96);
#if __LCC__ <= 123
typedef struct
{
float x;
float y;
} __lccrt_complex_f32;
typedef struct
{
double x;
double y;
} __lccrt_complex_f64;
typedef struct
{
long double x;
long double y;
} __lccrt_complex_f80;
#endif /* __LCC__ <= 123 */
#define __lccrt_vec_typedef( type, N) typedef struct { type a[N]; } __lccrt_vec_##type##_##N
#define __lccrt_vec_si( k, N) __lccrt_vec_int##k##_t_##N
#define __lccrt_vec_ui( k, N) __lccrt_vec_uint##k##_t_##N
#define __lccrt_vec_f( k, N) __lccrt_vec_f##k##_t_##N
__lccrt_vec_typedef( int32_t, 2);
__lccrt_vec_typedef( int32_t, 16);
__lccrt_vec_typedef( int32_t, 32);
__lccrt_vec_typedef( int8_t, 16);
__lccrt_vec_typedef( int16_t, 8);
__lccrt_vec_typedef( int32_t, 4);
__lccrt_vec_typedef( int64_t, 2);
__lccrt_vec_typedef( int8_t, 32);
__lccrt_vec_typedef( int16_t, 16);
__lccrt_vec_typedef( int32_t, 8);
__lccrt_vec_typedef( int64_t, 4);
__lccrt_vec_typedef( uint8_t, 16);
__lccrt_vec_typedef( uint16_t, 8);
__lccrt_vec_typedef( uint32_t, 4);
__lccrt_vec_typedef( uint64_t, 2);
__lccrt_vec_typedef( uint8_t, 32);
__lccrt_vec_typedef( uint16_t, 16);
__lccrt_vec_typedef( uint32_t, 8);
__lccrt_vec_typedef( uint64_t, 4);
__lccrt_vec_typedef( f32_t, 4);
__lccrt_vec_typedef( f64_t, 2);
__lccrt_vec_typedef( f32_t, 8);
__lccrt_vec_typedef( f64_t, 4);
typedef struct
{
uint8_t value;
uint8_t is_overflow;
} __lccrt_overflow_8_t;
typedef struct
{
uint16_t value;
uint8_t is_overflow;
} __lccrt_overflow_16_t;
typedef struct
{
uint32_t value;
uint8_t is_overflow;
} __lccrt_overflow_32_t;
typedef struct
{
uint64_t value;
uint8_t is_overflow;
} __lccrt_overflow_64_t;
typedef struct
{
uint64_t lo;
uint64_t hi;
} __lccrt_uint128_t;
typedef struct
{
__lccrt_uint128_t value;
uint8_t is_overflow;
} __lccrt_overflow_128_t;
typedef struct
{
__lccrt_uint128_t lo;
__lccrt_uint128_t hi;
} __lccrt_uint256_t;
typedef struct
{
__lccrt_uint256_t value;
uint8_t is_overflow;
} __lccrt_overflow_256_t;
extern __lccrt_overflow_8_t __lccrt_uadd_overflow_8( uint64_t a, uint64_t b);
extern __lccrt_overflow_8_t __lccrt_sadd_overflow_8( uint64_t a, uint64_t b);
extern __lccrt_overflow_16_t __lccrt_uadd_overflow_16( uint64_t a, uint64_t b);
extern __lccrt_overflow_16_t __lccrt_sadd_overflow_16( uint64_t a, uint64_t b);
extern __lccrt_overflow_32_t __lccrt_uadd_overflow_32( uint64_t a, uint64_t b);
extern __lccrt_overflow_32_t __lccrt_sadd_overflow_32( uint64_t a, uint64_t b);
extern __lccrt_overflow_64_t __lccrt_uadd_overflow_64( uint64_t a, uint64_t b);
extern __lccrt_overflow_64_t __lccrt_sadd_overflow_64( uint64_t a, uint64_t b);
extern __lccrt_overflow_128_t __lccrt_uadd_overflow_128( __lccrt_uint128_t a, __lccrt_uint128_t b);
extern __lccrt_overflow_128_t __lccrt_sadd_overflow_128( __lccrt_uint128_t a, __lccrt_uint128_t b);
extern __lccrt_overflow_256_t __lccrt_uadd_overflow_256( __lccrt_uint256_t a, __lccrt_uint256_t b);
extern __lccrt_overflow_256_t __lccrt_sadd_overflow_256( __lccrt_uint256_t a, __lccrt_uint256_t b);
extern __lccrt_overflow_8_t __lccrt_usub_overflow_8( uint64_t a, uint64_t b);
extern __lccrt_overflow_8_t __lccrt_ssub_overflow_8( uint64_t a, uint64_t b);
extern __lccrt_overflow_16_t __lccrt_usub_overflow_16( uint64_t a, uint64_t b);
extern __lccrt_overflow_16_t __lccrt_ssub_overflow_16( uint64_t a, uint64_t b);
extern __lccrt_overflow_32_t __lccrt_usub_overflow_32( uint64_t a, uint64_t b);
extern __lccrt_overflow_32_t __lccrt_ssub_overflow_32( uint64_t a, uint64_t b);
extern __lccrt_overflow_64_t __lccrt_usub_overflow_64( uint64_t a, uint64_t b);
extern __lccrt_overflow_64_t __lccrt_ssub_overflow_64( uint64_t a, uint64_t b);
extern __lccrt_overflow_128_t __lccrt_usub_overflow_128( __lccrt_uint128_t a, __lccrt_uint128_t b);
extern __lccrt_overflow_128_t __lccrt_ssub_overflow_128( __lccrt_uint128_t a, __lccrt_uint128_t b);
extern __lccrt_overflow_8_t __lccrt_umul_overflow_8( uint64_t a, uint64_t b);
extern __lccrt_overflow_8_t __lccrt_smul_overflow_8( uint64_t a, uint64_t b);
extern __lccrt_overflow_16_t __lccrt_umul_overflow_16( uint64_t a, uint64_t b);
extern __lccrt_overflow_16_t __lccrt_smul_overflow_16( uint64_t a, uint64_t b);
extern __lccrt_overflow_32_t __lccrt_umul_overflow_32( uint64_t a, uint64_t b);
extern __lccrt_overflow_32_t __lccrt_smul_overflow_32( uint64_t a, uint64_t b);
extern __lccrt_overflow_64_t __lccrt_umul_overflow_64( uint64_t a, uint64_t b);
extern __lccrt_overflow_64_t __lccrt_smul_overflow_64( uint64_t a, uint64_t b);
extern __lccrt_overflow_128_t __lccrt_umul_overflow_128( __lccrt_uint128_t a, __lccrt_uint128_t b);
extern __lccrt_overflow_128_t __lccrt_smul_overflow_128( __lccrt_uint128_t a, __lccrt_uint128_t b);
extern uint8_t __lccrt_uadd_sat_8( uint8_t a, uint8_t b);
extern uint8_t __lccrt_sadd_sat_8( uint8_t a, uint8_t b);
extern uint16_t __lccrt_uadd_sat_16( uint16_t a, uint16_t b);
extern uint16_t __lccrt_sadd_sat_16( uint16_t a, uint16_t b);
extern uint32_t __lccrt_uadd_sat_32( uint32_t a, uint32_t b);
extern uint32_t __lccrt_sadd_sat_32( uint32_t a, uint32_t b);
extern uint64_t __lccrt_uadd_sat_64( uint64_t a, uint64_t b);
extern uint64_t __lccrt_sadd_sat_64( uint64_t a, uint64_t b);
extern __lccrt_uint128_t __lccrt_uadd_sat_128( __lccrt_uint128_t a, __lccrt_uint128_t b);
extern __lccrt_uint128_t __lccrt_sadd_sat_128( __lccrt_uint128_t a, __lccrt_uint128_t b);
extern uint8_t __lccrt_usub_sat_8( uint8_t a, uint8_t b);
extern uint8_t __lccrt_ssub_sat_8( uint8_t a, uint8_t b);
extern uint16_t __lccrt_usub_sat_16( uint16_t a, uint16_t b);
extern uint16_t __lccrt_ssub_sat_16( uint16_t a, uint16_t b);
extern uint32_t __lccrt_usub_sat_32( uint32_t a, uint32_t b);
extern uint32_t __lccrt_ssub_sat_32( uint32_t a, uint32_t b);
extern uint64_t __lccrt_usub_sat_64( uint64_t a, uint64_t b);
extern uint64_t __lccrt_ssub_sat_64( uint64_t a, uint64_t b);
extern __lccrt_uint128_t __lccrt_usub_sat_128( __lccrt_uint128_t a, __lccrt_uint128_t b);
extern __lccrt_uint128_t __lccrt_ssub_sat_128( __lccrt_uint128_t a, __lccrt_uint128_t b);
extern uint8_t __lccrt_umul_sat_8( uint8_t a, uint8_t b);
extern uint8_t __lccrt_smul_sat_8( uint8_t a, uint8_t b);
extern uint16_t __lccrt_umul_sat_16( uint16_t a, uint16_t b);
extern uint16_t __lccrt_smul_sat_16( uint16_t a, uint16_t b);
extern uint32_t __lccrt_umul_sat_32( uint32_t a, uint32_t b);
extern uint32_t __lccrt_smul_sat_32( uint32_t a, uint32_t b);
extern uint64_t __lccrt_umul_sat_64( uint64_t a, uint64_t b);
extern uint64_t __lccrt_smul_sat_64( uint64_t a, uint64_t b);
//extern uint8_t __lccrt_umul_sat_128( uint8_t a, uint8_t b);
//extern uint8_t __lccrt_smul_sat_128( uint8_t a, uint8_t b);
extern uint8_t __lccrt_fshl_i8( uint8_t a, uint8_t b, uint8_t c);
extern uint16_t __lccrt_fshl_i16( uint16_t a, uint16_t b, uint16_t c);
extern uint32_t __lccrt_fshl_i32( uint32_t a, uint32_t b, uint32_t c);
extern uint64_t __lccrt_fshl_i64( uint64_t a, uint64_t b, uint64_t c);
extern uint8_t __lccrt_fshr_8( uint8_t a, uint8_t b, uint8_t c);
extern uint16_t __lccrt_fshr_16( uint16_t a, uint16_t b, uint16_t c);
extern uint32_t __lccrt_fshr_32( uint32_t a, uint32_t b, uint32_t c);
extern uint64_t __lccrt_fshr_64( uint64_t a, uint64_t b, uint64_t c);
extern __lccrt_uint128_t __lccrt_fshl_i128( __lccrt_uint128_t a, __lccrt_uint128_t b, __lccrt_uint128_t c);
extern __lccrt_uint128_t __lccrt_fshr_128( __lccrt_uint128_t a, __lccrt_uint128_t b, __lccrt_uint128_t c);
extern void __lccrt_bitcast_n( uint32_t rbits, uint32_t abits, uint8_t *r, uint8_t *a);
extern void __lccrt_select( uint32_t rbits, uint32_t abits, uint32_t bbits, uint32_t cbits,
uint8_t *r, uint8_t *a, uint8_t *b, uint8_t *c);
extern void __lccrt_abs_n( uint32_t rbits, uint32_t abits, uint8_t *r, uint8_t *a);
extern void __lccrt_zext_n( uint32_t rbits, uint32_t abits, uint8_t *r, uint8_t *a);
extern void __lccrt_sext_n( uint32_t rbits, uint32_t abits, uint8_t *r, uint8_t *a);
extern void __lccrt_trunc_n( uint32_t rbits, uint32_t abits, uint8_t *r, uint8_t *a);
extern void __lccrt_shl_n( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b);
extern void __lccrt_shr_n( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b);
extern void __lccrt_sar_n( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b);
extern void __lccrt_fshl_n( __LCCRT_N_ARG3( rbits, abits, bbits, cbits, r, a, b, c));
extern void __lccrt_and_n( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b);
extern void __lccrt_or_n( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b);
extern void __lccrt_xor_n( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b);
extern void __lccrt_add_n( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b);
extern void __lccrt_sub_n( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b);
extern void __lccrt_mul_n( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b);
extern void __lccrt_udiv_n( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b);
extern void __lccrt_sdiv_n( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b);
extern void __lccrt_umod_n( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b);
extern void __lccrt_smod_n( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b);
extern void __lccrt_fmod_n( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b);
extern void __lccrt_minnum_n( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b);
extern void __lccrt_maxnum_n( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b);
extern void __lccrt_fneg_n( uint32_t rbits, uint32_t abits, uint8_t *r, uint8_t *a);
extern void __lccrt_shuffle_n( uint32_t rbits, uint32_t abits, uint32_t bbits, uint32_t cbits,
uint8_t *r, uint8_t *a, uint8_t *b, uint8_t *c,
uint32_t rn, uint32_t an, uint32_t bn, uint32_t cn);
extern void __lccrt_fptofp_n( uint32_t rbits, uint32_t abits, uint8_t *r, uint8_t *a);
extern void __lccrt_fptosi_n( uint32_t rbits, uint32_t abits, uint8_t *r, uint8_t *a);
extern void __lccrt_fptoui_n( uint32_t rbits, uint32_t abits, uint8_t *r, uint8_t *a);
extern void __lccrt_sitofp_n( uint32_t rbits, uint32_t abits, uint8_t *r, uint8_t *a);
extern void __lccrt_uitofp_n( uint32_t rbits, uint32_t abits, uint8_t *r, uint8_t *a);
extern void __lccrt_uadd_sat_n( __LCCRT_N_ARG2( rbits, abits, bbits, r, a, b));
extern void __lccrt_sadd_sat_n( __LCCRT_N_ARG2( rbits, abits, bbits, r, a, b));
extern void __lccrt_usub_sat_n( __LCCRT_N_ARG2( rbits, abits, bbits, r, a, b));
extern void __lccrt_ssub_sat_n( __LCCRT_N_ARG2( rbits, abits, bbits, r, a, b));
extern void __lccrt_bswap_n( __LCCRT_N_ARG1( rbits, abits, r, a));
extern void __lccrt_bitreverse_n( __LCCRT_N_ARG1( rbits, abits, r, a));
extern void __lccrt_ctpop_n( __LCCRT_N_ARG1( rbits, abits, r, a));
extern void __lccrt_shl_v( __LCCRT_VEC_ARGS2( rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb));
extern void __lccrt_shr_v( __LCCRT_VEC_ARGS2( rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb));
extern void __lccrt_sar_v( __LCCRT_VEC_ARGS2( rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb));
extern void __lccrt_fshl_v( __LCCRT_VEC_ARGS3( rb, ab, bb, cb, r, a, b, c, rn, an, bn, cn, reb, aeb, beb, ceb));
extern void __lccrt_and_v( __LCCRT_VEC_ARGS2( rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb));
extern void __lccrt_or_v( __LCCRT_VEC_ARGS2( rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb));
extern void __lccrt_xor_v( __LCCRT_VEC_ARGS2( rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb));
extern void __lccrt_add_v( __LCCRT_VEC_ARGS2( rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb));
extern void __lccrt_sub_v( __LCCRT_VEC_ARGS2( rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb));
extern void __lccrt_mul_v( __LCCRT_VEC_ARGS2( rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb));
extern void __lccrt_udiv_v( __LCCRT_VEC_ARGS2( rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb));
extern void __lccrt_sdiv_v( __LCCRT_VEC_ARGS2( rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb));
extern void __lccrt_umod_v( __LCCRT_VEC_ARGS2( rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb));
extern void __lccrt_smod_v( __LCCRT_VEC_ARGS2( rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb));
extern void __lccrt_fadd_v( __LCCRT_VEC_ARGS2( rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb));
extern void __lccrt_fsub_v( __LCCRT_VEC_ARGS2( rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb));
extern void __lccrt_fmul_v( __LCCRT_VEC_ARGS2( rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb));
extern void __lccrt_fmuladd_v( __LCCRT_VEC_ARGS3( rb, ab, bb, cb, r, a, b, c, rn, an, bn, cn, reb, aeb, beb, ceb));
extern void __lccrt_fdiv_v( __LCCRT_VEC_ARGS2( rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb));
extern void __lccrt_fmod_v( __LCCRT_VEC_ARGS2( rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb));
extern void __lccrt_minnum_v( __LCCRT_VEC_ARGS2( rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb));
extern void __lccrt_maxnum_v( __LCCRT_VEC_ARGS2( rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb));
extern void __lccrt_abs_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb));
extern void __lccrt_reduce_fmin_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb));
extern void __lccrt_reduce_fmax_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb));
extern void __lccrt_fneg_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb));
extern void __lccrt_ptoi_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb));
extern void __lccrt_itop_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb));
extern void __lccrt_fptofp_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb));
extern void __lccrt_fptosi_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb));
extern void __lccrt_fptoui_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb));
extern void __lccrt_sitofp_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb));
extern void __lccrt_uitofp_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb));
extern void __lccrt_trunc_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb));
extern void __lccrt_uadd_sat_v( __LCCRT_VEC_ARGS2( rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb));
extern void __lccrt_sadd_sat_v( __LCCRT_VEC_ARGS2( rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb));
extern void __lccrt_usub_sat_v( __LCCRT_VEC_ARGS2( rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb));
extern void __lccrt_ssub_sat_v( __LCCRT_VEC_ARGS2( rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb));
extern void __lccrt_fabs_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb));
extern void __lccrt_sqrt_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb));
extern void __lccrt_exp2_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb));
extern void __lccrt_log2_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb));
extern void __lccrt_exp10_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb));
extern void __lccrt_log10_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb));
extern void __lccrt_exp_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb));
extern void __lccrt_log_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb));
extern void __lccrt_cos_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb));
extern void __lccrt_sin_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb));
extern void __lccrt_tan_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb));
extern void __lccrt_acos_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb));
extern void __lccrt_asin_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb));
extern void __lccrt_pow_v( __LCCRT_VEC_ARGS2( rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb));
extern void __lccrt_powi_v( __LCCRT_VEC_ARGS2( rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb));
extern void __lccrt_bswap_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb));
extern void __lccrt_bitreverse_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb));
extern void __lccrt_ctpop_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb));
extern void __lccrt_fma_v( __LCCRT_VEC_ARGS3( rb, ab, bb, cb, r, a, b, c, rn, an, bn, cn, reb, aeb, beb, ceb));
extern void __lccrt_floor_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb));
extern void __lccrt_ceil_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb));
extern void __lccrt_round_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb));
extern void __lccrt_ftrunc_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb));
extern void __lccrt_rint_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb));
extern void __lccrt_cmp_n_eq_i( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b);
extern void __lccrt_cmp_n_ne_i( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b);
extern void __lccrt_cmp_n_lt_i( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b);
extern void __lccrt_cmp_n_lt_u( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b);
extern void __lccrt_cmp_n_le_i( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b);
extern void __lccrt_cmp_n_le_u( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b);
extern void __lccrt_cmp_n_gt_i( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b);
extern void __lccrt_cmp_n_gt_u( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b);
extern void __lccrt_cmp_n_ge_i( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b);
extern void __lccrt_cmp_n_ge_u( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b);
extern void __lccrt_cmp_v_eq_i( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b,
uint32_t rn, uint32_t an, uint32_t bn);
extern void __lccrt_cmp_v_ne_i( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b,
uint32_t rn, uint32_t an, uint32_t bn);
extern void __lccrt_cmp_v_lt_i( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b,
uint32_t rn, uint32_t an, uint32_t bn);
extern void __lccrt_cmp_v_lt_u( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b,
uint32_t rn, uint32_t an, uint32_t bn);
extern void __lccrt_cmp_v_le_i( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b,
uint32_t rn, uint32_t an, uint32_t bn);
extern void __lccrt_cmp_v_le_u( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b,
uint32_t rn, uint32_t an, uint32_t bn);
extern void __lccrt_cmp_v_gt_i( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b,
uint32_t rn, uint32_t an, uint32_t bn);
extern void __lccrt_cmp_v_gt_u( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b,
uint32_t rn, uint32_t an, uint32_t bn);
extern void __lccrt_cmp_v_ge_i( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b,
uint32_t rn, uint32_t an, uint32_t bn);
extern void __lccrt_cmp_v_ge_u( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b,
uint32_t rn, uint32_t an, uint32_t bn);
extern void __lccrt_cmp_fo( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b);
extern void __lccrt_cmp_fu( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b);
extern void __lccrt_cmp_eq_fu( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b);
extern void __lccrt_cmp_ne_fu( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b);
extern void __lccrt_cmp_lt_fu( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b);
extern void __lccrt_cmp_le_fu( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b);
extern void __lccrt_cmp_gt_fu( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b);
extern void __lccrt_cmp_ge_fu( uint32_t rbits, uint32_t abits, uint32_t bbits, uint8_t *r, uint8_t *a, uint8_t *b);
extern uint64_t __lccrt_ctlz_8( uint64_t a);
extern uint64_t __lccrt_ctlz_16( uint64_t a);
extern uint64_t __lccrt_ctlz_32( uint64_t a);
extern uint64_t __lccrt_ctlz_64( uint64_t a);
extern __lccrt_uint128_t __lccrt_ctlz_128( __lccrt_uint128_t a);
extern uint64_t __lccrt_cttz_8( uint64_t a);
extern uint64_t __lccrt_cttz_16( uint64_t a);
extern uint64_t __lccrt_cttz_32( uint64_t a);
extern uint64_t __lccrt_cttz_64( uint64_t a);
extern __lccrt_uint128_t __lccrt_cttz_128( __lccrt_uint128_t a);
extern uint64_t __lccrt_ctpop_i8( uint64_t a);
extern uint64_t __lccrt_ctpop_i16( uint64_t a);
extern uint64_t __lccrt_ctpop_i32( uint64_t a);
extern uint64_t __lccrt_ctpop_i64( uint64_t a);
extern __lccrt_uint128_t __lccrt_ctpop_i128( __lccrt_uint128_t a);
extern uint64_t __lccrt_bitreverse_8( uint64_t a);
extern uint64_t __lccrt_bitreverse_16( uint64_t a);
extern uint64_t __lccrt_bitreverse_32( uint64_t a);
extern uint64_t __lccrt_bitreverse_64( uint64_t a);
extern __lccrt_uint128_t __lccrt_bitreverse_128( __lccrt_uint128_t a);
#if defined( __LCC__) && (__LCC__ <= 123)
extern __lccrt_complex_f32 __mulsc3( __lccrt_f32_t a, __lccrt_f32_t b, __lccrt_f32_t c, __lccrt_f32_t d);
extern __lccrt_complex_f64 __muldc3( __lccrt_f64_t a, __lccrt_f64_t b, __lccrt_f64_t c, __lccrt_f64_t d);
extern __lccrt_complex_f32 __divsc3( __lccrt_f32_t a, __lccrt_f32_t b, __lccrt_f32_t c, __lccrt_f32_t d);
extern __lccrt_complex_f64 __divdc3( __lccrt_f64_t a, __lccrt_f64_t b, __lccrt_f64_t c, __lccrt_f64_t d);
#endif /* __LCC__ <= 123 */
int8_t __atomic_fetch_max_1( int8_t *a, int8_t b);
int16_t __atomic_fetch_max_2( int16_t *a, int16_t b);
int32_t __atomic_fetch_max_4( int32_t *a, int32_t b);
int64_t __atomic_fetch_max_8( int64_t *a, int64_t b);
int8_t __atomic_fetch_min_1( int8_t *a, int8_t b);
int16_t __atomic_fetch_min_2( int16_t *a, int16_t b);
int32_t __atomic_fetch_min_4( int32_t *a, int32_t b);
int64_t __atomic_fetch_min_8( int64_t *a, int64_t b);
uint8_t __atomic_fetch_umax_1( uint8_t *a, uint8_t b);
uint16_t __atomic_fetch_umax_2( uint16_t *a, uint16_t b);
uint32_t __atomic_fetch_umax_4( uint32_t *a, uint32_t b);
uint64_t __atomic_fetch_umax_8( uint64_t *a, uint64_t b);
uint8_t __atomic_fetch_umin_1( uint8_t *a, uint8_t b);
uint16_t __atomic_fetch_umin_2( uint16_t *a, uint16_t b);
uint32_t __atomic_fetch_umin_4( uint32_t *a, uint32_t b);
uint64_t __atomic_fetch_umin_8( uint64_t *a, uint64_t b);
extern __lccrt_vec_si( 8, 16) __lccopt_shuffle_v16i8( __lccrt_vec_si( 8, 16) x, __lccrt_vec_si( 8, 16) y,
__lccrt_vec_si( 32, 16) c);
extern __lccrt_vec_si( 16, 8) __lccopt_shuffle_v8i16( __lccrt_vec_si( 16, 8) x, __lccrt_vec_si( 16, 8) y,
__lccrt_vec_si( 32, 8) c);
extern __lccrt_vec_si( 32, 4) __lccopt_shuffle_v4i32( __lccrt_vec_si( 32, 4) x, __lccrt_vec_si( 32, 4) y,
__lccrt_vec_si( 32, 4) c);
extern __lccrt_vec_si( 64, 2) __lccopt_shuffle_v2i64( __lccrt_vec_si( 64, 2) x, __lccrt_vec_si( 64, 2) y,
__lccrt_vec_si( 32, 2) c);
extern __lccrt_vec_si( 8, 32) __lccopt_shuffle_v32i8( __lccrt_vec_si( 8, 32) x, __lccrt_vec_si( 8, 32) y,
__lccrt_vec_si( 32, 32) c);
extern __lccrt_vec_si( 16, 16) __lccopt_shuffle_v16i16( __lccrt_vec_si( 16, 16) x, __lccrt_vec_si( 16, 16) y,
__lccrt_vec_si( 32, 16) c);
extern __lccrt_vec_si( 32, 8) __lccopt_shuffle_v8i32( __lccrt_vec_si( 32, 8) x, __lccrt_vec_si( 32, 8) y,
__lccrt_vec_si( 32, 8) c);
extern __lccrt_vec_si( 64, 4) __lccopt_shuffle_v4i64( __lccrt_vec_si( 64, 4) x, __lccrt_vec_si( 64, 4) y,
__lccrt_vec_si( 32, 4) c);
extern __lccrt_vec_f( 32, 4) __lccopt_shuffle_v4f32( __lccrt_vec_f( 32, 4) x, __lccrt_vec_f( 32, 4) y,
__lccrt_vec_si( 32, 4) c);
extern __lccrt_vec_f( 64, 2) __lccopt_shuffle_v2f64( __lccrt_vec_f( 64, 2) x, __lccrt_vec_f( 64, 2) y,
__lccrt_vec_si( 32, 2) c);
extern __lccrt_vec_f( 32, 8) __lccopt_shuffle_v8f32( __lccrt_vec_f( 32, 8) x, __lccrt_vec_f( 32, 8) y,
__lccrt_vec_si( 32, 8) c);
extern __lccrt_vec_f( 64, 4) __lccopt_shuffle_v4f64( __lccrt_vec_f( 64, 4) x, __lccrt_vec_f( 64, 4) y,
__lccrt_vec_si( 32, 4) c);
extern __lccrt_uint128_t __lccrt_bswap_128( __lccrt_uint128_t v);
extern int8_t __lccrt_fptosi_sat_i8f32( __lccrt_f32_t);
extern int8_t __lccrt_fptosi_sat_i8f64( __lccrt_f64_t);
extern int8_t __lccrt_fptosi_sat_i8f80( __lccrt_f80_t);
extern int16_t __lccrt_fptosi_sat_i16f32( __lccrt_f32_t);
extern int16_t __lccrt_fptosi_sat_i16f64( __lccrt_f64_t);
extern int16_t __lccrt_fptosi_sat_i16f80( __lccrt_f80_t);
extern int32_t __lccrt_fptosi_sat_i32f32( __lccrt_f32_t);
extern int32_t __lccrt_fptosi_sat_i32f64( __lccrt_f64_t);
extern int32_t __lccrt_fptosi_sat_i32f80( __lccrt_f80_t);
extern int64_t __lccrt_fptosi_sat_i64f32( __lccrt_f32_t);
extern int64_t __lccrt_fptosi_sat_i64f64( __lccrt_f64_t);
extern int64_t __lccrt_fptosi_sat_i64f80( __lccrt_f80_t);
extern __lccrt_uint128_t __lccrt_fptosi_sat_i128f32( __lccrt_f32_t);
extern __lccrt_uint128_t __lccrt_fptosi_sat_i128f64( __lccrt_f64_t);
extern uint8_t __lccrt_fptoui_sat_i8f32( __lccrt_f32_t);
extern uint8_t __lccrt_fptoui_sat_i8f64( __lccrt_f64_t);
extern uint8_t __lccrt_fptoui_sat_i8f80( __lccrt_f80_t);
extern uint16_t __lccrt_fptoui_sat_i16f32( __lccrt_f32_t);
extern uint16_t __lccrt_fptoui_sat_i16f64( __lccrt_f64_t);
extern uint16_t __lccrt_fptoui_sat_i16f80( __lccrt_f80_t);
extern uint32_t __lccrt_fptoui_sat_i32f32( __lccrt_f32_t);
extern uint32_t __lccrt_fptoui_sat_i32f64( __lccrt_f64_t);
extern uint32_t __lccrt_fptoui_sat_i32f80( __lccrt_f80_t);
extern uint64_t __lccrt_fptoui_sat_i64f32( __lccrt_f32_t);
extern uint64_t __lccrt_fptoui_sat_i64f64( __lccrt_f64_t);
extern uint64_t __lccrt_fptoui_sat_i64f80( __lccrt_f80_t);
extern __lccrt_uint128_t __lccrt_fptoui_sat_i128f32( __lccrt_f32_t);
extern __lccrt_uint128_t __lccrt_fptoui_sat_i128f64( __lccrt_f64_t);
extern __lccrt_nint96_t __lccrt_fshl_i96( __lccrt_nint96_t, __lccrt_nint96_t, __lccrt_nint96_t);
extern uint8_t __lccrt_typetest_unsupported_yet( void);

203
tools/lccrt_s/src/lccrt.c Normal file
View File

@ -0,0 +1,203 @@
/**
* Part of the Lccrt Project, under the Apache License v2.0
* See http://www.apache.org/licenses/LICENSE-2.0.txt for license information.
* SPDX-License-Identifier: Apache-2.0
*/
#include "lccrt_s.h"
#include <assert.h>
uint64_t
__lccrt_ctlz_8( uint64_t a)
{
uint64_t r = __builtin_clz( a & 0xff) - 24;
return (r);
} /* __lccrt_ctlz_8 */
uint64_t
__lccrt_ctlz_16( uint64_t a)
{
uint64_t r = __builtin_clz( a & 0xffff) - 16;
return (r);
} /* __lccrt_ctlz_16 */
uint64_t
__lccrt_ctlz_32( uint64_t a)
{
uint64_t r = __builtin_clz( a);
return (r);
} /* __lccrt_ctlz_32 */
uint64_t
__lccrt_ctlz_64( uint64_t a)
{
uint64_t r = __builtin_clzll( a);
return (r);
} /* __lccrt_ctlz_64 */
uint64_t
__lccrt_cttz_8( uint64_t a)
{
uint64_t r = __builtin_ctz( a | (1U << 8U));
return (r);
} /* __lccrt_cttz_8 */
uint64_t
__lccrt_cttz_16( uint64_t a)
{
uint64_t r = __builtin_ctz( a | (1U << 16U));
return (r);
} /* __lccrt_cttz_16 */
uint64_t
__lccrt_cttz_32( uint64_t a)
{
uint64_t r = __builtin_ctz( a);
return (r);
} /* __lccrt_cttz_32 */
uint64_t
__lccrt_cttz_64( uint64_t a)
{
uint64_t r = __builtin_ctzll( a);
return (r);
} /* __lccrt_cttz_64 */
uint64_t
__lccrt_ctpop_i8( uint64_t a)
{
uint64_t r = __builtin_popcount( a & 0xff);
return (r);
} /* __lccrt_ctpop_i8 */
uint64_t
__lccrt_ctpop_i16( uint64_t a)
{
uint64_t r = __builtin_popcount( a & 0xffff);
return (r);
} /* __lccrt_ctpop_i16 */
uint64_t
__lccrt_ctpop_i32( uint64_t a)
{
uint64_t r = __builtin_popcount( a);
return (r);
} /* __lccrt_ctpop_i32 */
uint64_t
__lccrt_ctpop_i64( uint64_t a)
{
uint64_t r = __builtin_popcountll( a);
return (r);
} /* __lccrt_ctpop_i64 */
__lccrt_uint128_t
__lccrt_ctpop_i128( __lccrt_uint128_t a)
{
__lccrt_uint128_t r = {0};
r.lo = __builtin_popcountll( a.hi) + __builtin_popcountll( a.lo);
return (r);
} /* __lccrt_ctpop_i128 */
double __lccrt___lccrt_sqrt_f64( double) asm( "__lccrt_sqrt.f64");
double
__lccrt___lccrt_sqrt_f64( double a)
{
assert( 0);
}
void
__builtin_lccopt_mul_4_x_i8( void)
{
assert( 0);
}
void
__builtin_lccopt_shuffle_4_x_i8( void)
{
assert( 0);
}
#if defined( __LCC__) && (__LCC__ <= 123)
__lccrt_complex_f32
__mulsc3( float a, float b, float c, float d)
{
__lccrt_complex_f32 r = {a*c - b*d, a*d + b*c};
return (r);
} /* __mulsc3 */
#endif /* __LCC__ <= 123 */
#if defined( __LCC__) && (__LCC__ <= 123)
__lccrt_complex_f64
__muldc3( __lccrt_f64_t a, __lccrt_f64_t b, __lccrt_f64_t c, __lccrt_f64_t d)
{
__lccrt_complex_f64 r = {a*c - b*d, a*d + b*c};
return (r);
} /* __muldc3 */
#endif /* __LCC__ <= 123 */
#if defined( __LCC__) && (__LCC__ <= 123)
__lccrt_complex_f32
__divsc3( float a, float b, float c, float d)
{
float v2 = c*c + d*d;
__lccrt_complex_f32 r = {(a*c - b*d)/v2, (a*d + b*c)/v2};
return (r);
} /* __divsc3 */
#endif /* __LCC__ <= 123 */
#if defined( __LCC__) && (__LCC__ <= 123)
__lccrt_complex_f64
__divdc3( __lccrt_f64_t a, __lccrt_f64_t b, __lccrt_f64_t c, __lccrt_f64_t d)
{
__lccrt_f64_t v2 = c*c + d*d;
__lccrt_complex_f64 r = {(a*c - b*d)/v2, (a*d + b*c)/v2};
return (r);
} /* __divdc3 */
#endif /* __LCC__ <= 123 */
extern void __lccrt_lifetime_start( void) asm( "llvm.lifetime.start.p0i8");
extern void __lccrt_lifetime_end( void) asm( "llvm.lifetime.end.p0i8");
extern void *__lccrt_frameaddress( void) asm( "llvm.frameaddress.p0i8");
void __lccrt_lifetime_start( void) {}
void __lccrt_lifetime_end( void) {}
void *__lccrt_frameaddress() { return (0); }
void __lccrt_stacksave( void) { assert( 0); }
void __lccrt_stackrestore( void) { assert( 0); }
int8_t
__atomic_fetch_max_1( int8_t *a, int8_t b)
{
assert( 0);
return (0);
} /* __atomic_fetch_max_1 */
uint8_t
__lccrt_typetest_unsupported_yet( void)
{
assert( 0);
return (0);
} /* __lccrt_typetest_unsupported_yet */

3754
tools/lccrt_s/src/lccrt_n.c Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,103 @@
/**
* Part of the Lccrt Project, under the Apache License v2.0
* See http://www.apache.org/licenses/LICENSE-2.0.txt for license information.
* SPDX-License-Identifier: Apache-2.0
*/
#include "lccrt_s.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define __lccrt_shuffle_get( n, k, x, y) (((k) < (n)) ? (x).a[k] : (y).a[(k) - (n)])
#define __lccopt_vec_shuffle( suffix, arg_type, ind_type, len) \
arg_type \
__lccopt_shuffle_##suffix( arg_type x, arg_type y, ind_type c) \
{ \
int i; \
arg_type r; \
\
for ( i = 0; i < len; ++i ) \
{ \
r.a[i] = __lccrt_shuffle_get( len, c.a[i], x, y); \
} \
\
return (r); \
} /* __builtin_lccopt_shuffle_##suffix */
__lccopt_vec_shuffle( v16i8, __lccrt_vec_si( 8, 16), __lccrt_vec_si( 32, 16), 16)
__lccopt_vec_shuffle( v8i16, __lccrt_vec_si( 16, 8), __lccrt_vec_si( 32, 8), 8)
__lccopt_vec_shuffle( v4i32, __lccrt_vec_si( 32, 4), __lccrt_vec_si( 32, 4), 4)
__lccopt_vec_shuffle( v2i64, __lccrt_vec_si( 64, 2), __lccrt_vec_si( 32, 2), 2)
__lccopt_vec_shuffle( v32i8, __lccrt_vec_si( 8, 32), __lccrt_vec_si( 32, 32), 32)
__lccopt_vec_shuffle( v16i16, __lccrt_vec_si( 16, 16), __lccrt_vec_si( 32, 16), 16)
__lccopt_vec_shuffle( v8i32, __lccrt_vec_si( 32, 8), __lccrt_vec_si( 32, 8), 8)
__lccopt_vec_shuffle( v4i64, __lccrt_vec_si( 64, 4), __lccrt_vec_si( 32, 4), 4)
__lccopt_vec_shuffle( v4f32, __lccrt_vec_f( 32, 4), __lccrt_vec_si( 32, 4), 4)
__lccopt_vec_shuffle( v2f64, __lccrt_vec_f( 64, 2), __lccrt_vec_si( 32, 2), 2)
__lccopt_vec_shuffle( v8f32, __lccrt_vec_f( 32, 8), __lccrt_vec_si( 32, 8), 8)
__lccopt_vec_shuffle( v4f64, __lccrt_vec_f( 64, 4), __lccrt_vec_si( 32, 4), 4)
__lccrt_vec_si( 32, 4)
__lccrt_mul_v4i32( __lccrt_vec_si( 32, 4) a, __lccrt_vec_si( 32, 4) b)
{
int i;
__lccrt_vec_si( 32, 4) r;
for ( i = 0; i < 4; ++i ) r.a[i] = a.a[i] * b.a[i];
return (r);
}
__lccrt_vec_f( 32, 4)
__lccrt_fdiv_v4f32( __lccrt_vec_f( 32, 4) a, __lccrt_vec_f( 32, 4) b)
{
int i;
__lccrt_vec_f( 32, 4) r;
for ( i = 0; i < 4; ++i ) r.a[i] = a.a[i] / b.a[i];
return (r);
}
__lccrt_vec_si( 32, 4)
__lccrt_select_v4i32_t( __lccrt_vec_si( 32, 4) a,
__lccrt_vec_si( 32, 4) b,
__lccrt_vec_si( 32, 4) c)
{
int i;
__lccrt_vec_si( 32, 4) r;
for ( i = 0; i < 4; ++i ) r.a[i] = a.a[i] ? b.a[i] : c.a[i];
return (r);
}
__lccrt_vec_f( 32, 4)
__lccrt_select_v4f32_t( __lccrt_vec_si( 32, 4) a,
__lccrt_vec_f( 32, 4) b,
__lccrt_vec_f( 32, 4) c)
{
int i;
__lccrt_vec_f( 32, 4) r;
for ( i = 0; i < 4; ++i ) r.a[i] = a.a[i] ? b.a[i] : c.a[i];
return (r);
}
__lccrt_vec_f( 32, 4)
__lccrt_sqrt_v4f32( __lccrt_vec_f( 32, 4) a)
{
int i;
__lccrt_vec_f( 32, 4) r;
for ( i = 0; i < 4; ++i ) r.a[i] = __builtin_sqrtf( a.a[i]);
return (r);
}