Добавление в архив исходного кода проекта и выбор для проекта лицензии 'Apache License 2.0'.
This commit is contained in:
parent
7f5ccca8b1
commit
8add65e1e8
|
@ -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.
|
|
@ -0,0 +1,5 @@
|
|||
Lccrt Project
|
||||
Copyright 2023 AO "MCST"
|
||||
|
||||
This product includes software developed at
|
||||
AO "MCST" (http://www.mcst.ru/).
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -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 */
|
File diff suppressed because it is too large
Load Diff
|
@ -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 */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -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
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
|
@ -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 */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
||||
}
|
Loading…
Reference in New Issue