libgcc, libatomic, libquadmath with MCST patches

This commit is contained in:
Nobody 2022-08-11 23:05:21 +03:00 committed by Alibek Omarov
parent 6184085fc6
commit f3201d7ce6
42 changed files with 2821 additions and 280 deletions

128
builtin.h Normal file
View File

@ -0,0 +1,128 @@
/* Сюда пока в виде макросов
* Файл взял без изменений от такой же версии для gcc-3.4.6, поэтому
* комментарии соответствующие */
/* gnu'шный номер для регистра %sp */
#define __builtin_dwarf_sp_column() 14
/* Инициализация массива char'ов размерами регистров. Нумерация идёт в gnu'той
* терминологии (см. файл mdes_sparc_reg.c, только там количество регистров
* не полное) */
#ifdef __LP64__
#define __builtin_init_dwarf_reg_size_table(buff) \
{ \
int i; \
char *ptr = (char*)(buff); \
for (i = 0; i < 32; i++) \
ptr[i] = 8; \
for (i = 33; i < 102; i++) \
ptr[i] = 4; \
}
#else
#define __builtin_init_dwarf_reg_size_table(buff) \
{ \
int i; \
char *ptr = (char*)(buff); \
for (i = 0; i < 102; i++) \
ptr[i] = 4; \
}
#endif
/* Судя по всему, для sparc'а все регистры принудительно откачиваются в стек,
* потому как вся unwind-info описана в терминах того, что регистры
* от предыдущего окна хранятся в стеке
*
* Старый комментарий:
*
* Точно не заю что
* См. gcc-3.4.6/gcc/except.c процедура expand_builtin_unwind_init
* Далее на sparc'е вызывается gen_flush_register_windows, что соответсвует
* define_insn "flush_register_windows". При этом в процедуре
* expand_builtin_unwind_init взводится флажок current_function_has_nonlocal_label,
* по которому хз что делается, но, вроде бы как для -O0 некритично */
#ifdef __LP64__
#define __builtin_unwind_init() \
asm ("flushw");
#else
#define __builtin_unwind_init() \
asm ("ta 3");
#endif
/* См. bug #82489
*
* Старый комментарий:
*
* См. gcc-3.4.6/gcc/except.c процедура expand_builtin_eh_return_data_regno
* На sparc'е реализации такие:
*
* #define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N) + 24 : INVALID_REGNUM)
* DWARF_FRAME_REGNUM - не нашёл, но, судя по тому, что генерит sparc'овский gcc,
* он ничего не делает
*
* Параметр должен быть строго константный, но здесь нормально это не отсечём
* (чтобы была именно ошибка компиляции). Так что полагаем, что в исходниках
* у нас всё в порядке */
#define __builtin_eh_return_data_regno(val) \
(((val) >= 0 && (val) < 4) ? (val) + 24 : -1)
/* Судя по всему, это вычисление CFA (Call Frame Adress). По сути описания
* в стандарте dwarf2 это есть значение %sp в предыдущем фрэйме (т.е. значение
* %fp в текущем фрэйме)
*
* Старый комментарий:
*
* Непонятно, что это, но на v9, судя по тому, что генерится, это
* результат '%fp + 2047', а на v8 просто '%fp'.
* Соответсвует return virtual_cfa_rtx; а откудо оно берётся - не осилил */
#ifdef __LP64__
#define __builtin_dwarf_cfa() \
({ void *p; \
asm volatile ("add %%fp, 2047, %0" : "=r"(p)); \
p; })
#else
#define __builtin_dwarf_cfa() \
({ void *p; \
asm volatile ("mov %%fp, %0" : "=r"(p)); \
p; })
#endif
/* См. gcc-3.4.6/gcc/except.c процедура expand_builtin_frob_return_addr
* Фактически dst = src - RETURN_ADDR_OFFSET в терминах void*
* Для sparc'а
* #define RETURN_ADDR_OFFSET \
* (8 + 4 * (! TARGET_ARCH64 && current_function_returns_struct))
* Так что для режима 64 можно сделать и в виде макроса */
#ifdef __LP64__
#define __builtin_frob_return_addr(src) \
((void*)(src) - 8)
#else
/* В нашем случае нигде нет использования builtin'а в процедурах, возвращающих
* структуру, а потому реализуем вариант со скалярным результатом и нам пока
* этого достаточно. Полноценный вариант можно сделать только при поддержке
* builtin'а компилятором */
#define __builtin_frob_return_addr(src) \
((void*)(src) - 8)
#endif
/* См. gcc-3.4.6/gcc/except.c процедура expand_builtin_eh_return
* Мало чего понял, а потому сделал то, что делает gcc
* При этом есть подозрение, что использование %g1 и %g2 критично
* (по крайней мере про %g1 где-то что-то встречал) */
#if defined __sparc__
#define __builtin_eh_return(ival,ptr) \
({ \
asm volatile ("mov %0, %%g1\n\t" \
"mov %1, %%g2\n\t" \
"mov %%g2, %%i7\n\t" \
"restore\n\t" \
"retl\n\t" \
" add %%sp, %%g1, %%sp" \
: : "r" ((long)(ival)), "r" ((void*)(ptr)) : "g1", "g2", "i7"); \
});
#elif defined __e2k__
#define __builtin_eh_return(ival,ptr) \
({ \
asm volatile ("nop" : : "r" ((long)(ival)), "r" ((void*)(ptr))); \
});
#endif

97
gcc_objdir/auto-host.h Normal file
View File

@ -0,0 +1,97 @@
/* auto-host.h. Generated from config.in by configure. */
/* config.in. Generated from configure.ac by autoheader. */
/* Define if you want runtime assertions enabled. This is a cheap check. */
#define ENABLE_RUNTIME_CHECKING 1
/* Define 0/1 if your assembler supports CFI directives. */
#define HAVE_GAS_CFI_DIRECTIVE 1
/* Define 0/1 if your assembler supports .cfi_personality. */
#define HAVE_GAS_CFI_PERSONALITY_DIRECTIVE 1
/* Define 0/1 if your assembler supports .cfi_sections. */
#define HAVE_GAS_CFI_SECTIONS_DIRECTIVE 1
/* Define if your assembler and linker support .hidden. */
#define HAVE_GAS_HIDDEN 1
/* Define .init_array/.fini_array sections are available and working. */
#ifndef USED_FOR_TARGET
/* òÁÎØÛÅ × ËÏÍÐÉÌÑÔÏÒÅ ×Ú×ÏÄÉÌÉ ÍÁËÒÏÓ __LCC_INITFINI_ARRAY__ ÔÁÍ,
* ÇÄÅ ÅÓÔØ ÐÏÄÄÅÒÖËÁ .init_array/.fini_array. ÷ ÓÁÍÏÍ ËÏÍÐÉÌÑÔÏÒÅ
* ÎÉÞÅÇÏ ÄÏÐÏÌÎÉÔÅÌØÎÏÇÏ ÎÅ ÄÅÌÁÌÏÓØ, ÐÒÏÓÔÏ ÂÙÌÁ ÐÏÄÄÅÒÖËÁ ÏÐÃÉÉ
* -print-mode=initfini. óÅÊÞÁÓ ÐÏÓÔÆÁËÔÕÍ ×ÓÅ ÁÒÈÉÔÅËÔÕÒÙ, ÇÄÅ
* ÎÅÔ ÔÁËÏÊ ÐÏÄÄÅÒÖËÉ, ÐÏÐÁÌÉ × ËÁÔÅÇÏÒÉÀ ÕÂÏÇÉÈ, É ÄÌÑ ÎÉÈ ×ÍÅÓÔÏ
* libgcc ÉÓÐÏÌØÚÕÅÔÓÑ libgcc.mcst. ô.Å. ×ÎÕÔÒÉ libgcc ÐÏÓÔÆÁËÔÕÍ
* ËÏÍÐÉÌÑÔÏÒ (ÔÏÞÎÅÅ, ÓÉÓÔÅÍÁ ÐÒÏÇÒÁÍÍÉÒÏ×ÁÎÉÑ) ×ÓÅÇÄÁ ÕÍÅÅÔ ÒÁÂÏÔÁÔØ
* Ó ÜÔÉÍÉ ÓÅËÃÉÑÍÉ, ÐÏÜÔÏÍÕ ÚÄÅÓØ ÐÒÉÎÕÄÉÔÅÌØÎÏ ×ËÌÀÞÉÍ. äÌÑ ËÏÎÔÒÏÌÑ
* ÐÏÓÔÁ×ÌÀ ÅÝ£ ÐÒÏ×ÅÒËÕ, ÞÔÏÂÙ ÎÅ ÚÁÂÙÔØ ÐÒÏ ÜÔÏÔ ÍÏÍÅÎÔ, ÅÓÌÉ ×ÄÒÕÇ
* ÚÁÈÏÔÉÍ ÐÅÒÅ×ÅÓÔÉ ÅÝÅ ËÁËÕÀ-ÎÉÂÕÄØ ÕÂÏÇÕÀ ÓÉÓÔÅÍÕ (ÎÁ ÄÁÎÎÙÊ ÍÏÍÅÎÔ
* ÉÚ ÔÁËÏ×ÙÈ ÏÓÔÁÌÓÑ ÌÉÛØ solaris) ÎÁ ÎÏÒÍÁÌØÎÙÅ ÒÅÌØÓÙ. */
# if ! defined __linux__ && ! defined __QNX__
# error "ðÒÉ ÓÂÏÒËÅ ÎÁ ÐÏÄ ÄÒÕÇÉÅ ÏÐÅÒÁÃÉÏÎÎÙÅ ÓÉÓÔÅÍÙ ÎÁÄÏ ÐÒÁ×ÉÌØÎÏ ÎÁÓÔÒÏÉÔØ ÍÁËÒÏÓ HAVE_INITFINI_ARRAY_SUPPORT"
# endif
# if 1 /* defined __LCC_INITFINI_ARRAY__ */
# define HAVE_INITFINI_ARRAY_SUPPORT 1
# else /* ! defined __LCC_INITFINI_ARRAY__ */
/* #undef HAVE_INITFINI_ARRAY_SUPPORT */
# endif /* ! defined __LCC_INITFINI_ARRAY__ */
#endif
/* Define if your linker supports .eh_frame_hdr. */
#define HAVE_LD_EH_FRAME_HDR 1
/* Define if your target C library provides sys/sdt.h */
/* #undef HAVE_SYS_SDT_H */
/* Define if your target C library provides the `dl_iterate_phdr' function. */
/* #undef TARGET_DL_ITERATE_PHDR */
/* Enable extensions on AIX 3, Interix. */
#ifndef _ALL_SOURCE
# define _ALL_SOURCE 1
#endif
/* Enable GNU extensions on systems that have them. */
#ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
#endif
/* Enable threading extensions on Solaris. */
#ifndef _POSIX_PTHREAD_SEMANTICS
# define _POSIX_PTHREAD_SEMANTICS 1
#endif
/* Enable extensions on HP NonStop. */
#ifndef _TANDEM_SOURCE
# define _TANDEM_SOURCE 1
#endif
/* Enable general extensions on Solaris. */
#ifndef __EXTENSIONS__
# define __EXTENSIONS__ 1
#endif
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
# define WORDS_BIGENDIAN 1
# endif
#endif
/* Number of bits in a file offset, on hosts where this is settable. */
#ifndef USED_FOR_TARGET
#define _FILE_OFFSET_BITS 64
#endif
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
/* #undef inline */
#endif

4
gcc_objdir/gcov-iov.h Normal file
View File

@ -0,0 +1,4 @@
/* Generated automatically by the program `build/gcov-iov'
from `7.3.0 (7 3) and (*)'. */
#define GCOV_VERSION ((gcov_unsigned_t)0x3730332a) /* 505* */

3
gcc_objdir/libgcc.mvars Normal file
View File

@ -0,0 +1,3 @@
GCC_CFLAGS = -DIN_GCC -W -Wall -Wwrite-strings -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition -isystem ./include
INHIBIT_LIBC_CFLAGS =
TARGET_SYSTEM_ROOT =

10
gcc_objdir/tconfig.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef GCC_TCONFIG_H
#define GCC_TCONFIG_H
#ifndef USED_FOR_TARGET
# define USED_FOR_TARGET
#endif
#include "auto-host.h"
#ifdef IN_GCC
# include "ansidecl.h"
#endif
#endif /* GCC_TCONFIG_H */

180
gcc_objdir/tm.h Normal file
View File

@ -0,0 +1,180 @@
#ifndef GCC_TM_H
#define GCC_TM_H
/* ************************************************************************** */
/* áÒÈÉÔÅËÔÕÒÎÏ-ÚÁ×ÉÓÉÍÁÑ ÞÁÓÔØ. */
#if defined(__sparc__)
#if defined(__sparcv9) || defined(__arch64__)
#define UNITS_PER_WORD 8
#else /* defined(__sparcv9) || defined(__arch64__) */
#define UNITS_PER_WORD 4
#endif /* defined(__sparcv9) || defined(__arch64__) */
#define MIN_UNITS_PER_WORD UNITS_PER_WORD
/* FIXME òÁÚÏÂÒÁÔØÓÑ, ÚÁÞÅÍ ÏÎÏ ÎÕÖÎÏ, É, ×ÏÚÍÏÖÎÏ, ÏÐÒÅÄÅÌÉÔØ ÄÌÑ e2k. */
#define WIDEST_HARDWARE_FP_SIZE 64
/* éÓÐÏÌØÚÕÅÔÓÑ ÐÒÉ ÏÐÒÅÄÅÌÅÎÉÉ DWARF_FRAME_REGISTERS. */
#define FIRST_PSEUDO_REGISTER 103
/* éÓÐÏÌØÚÕÅÔÓÑ ÐÒÉ ÏÐÒÅÄÅÌÅÎÉÉ __LIBGCC_STACK_GROWS_DOWNWARD__. */
#define STACK_GROWS_DOWNWARD 1
/* éÓÐÏÌØÚÕÅÔÓÑ ÐÒÉ ÏÐÒÅÄÅÌÅÎÉÉ __LIBGCC_EH_RETURN_STACKADJ_RTX__. */
#define EH_RETURN_STACKADJ_RTX /* */
#define TEXT_SECTION_ASM_OP "\t.text"
#define INIT_SECTION_ASM_OP "\t.section \".init\""
#define FINI_SECTION_ASM_OP "\t.section \".fini\""
/* ðÏÄÏÊÄ£Ô É ÒÅÁÌÉÚÁÃÉÑ ÐÏ ÕÍÏÌÞÁÎÉÀ ÉÚ crtstuff.c, ÎÏ ÔÁË ÁÓÓÅÍÂÌÅÒÎÙÊ ÆÁÊÌ
* ÐÏÌÕÞÁÅÔÓÑ ÞÉÝÅ (ÎÅ ÓÔÒÏÑÔÓÑ ÍÕÓÏÒÎÙÅ ÐÒÏÌÏÇÉ É ÜÐÉÌÏÇÉ). */
#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \
asm(SECTION_OP "\n" \
"\tcall " #FUNC "\n" \
"\t nop");
#elif defined(__e2k__)
/* éÓÐÏÌØÚÕÅÔÓÑ × libgcc2.c, libgcc2.h É ÐÒÉ ÏÐÒÅÄÅÌÅÎÉÉ MIN_UNITS_PER_WORD. */
#define UNITS_PER_WORD 8
/* éÓÐÏÌØÚÕÅÔÓÑ × libgcc2.c, libgcc2.h. */
#define MIN_UNITS_PER_WORD UNITS_PER_WORD
/* éÓÐÏÌØÚÕÅÔÓÑ ÐÒÉ ÏÐÒÅÄÅÌÅÎÉÉ DWARF_FRAME_REGISTERS. */
/* FIXME òÁÚÏÂÒÁÔØÓÑ, ÎÕÖÎÏ ÌÉ ÏÎÏ ÄÌÑ e2k. */
#define FIRST_PSEUDO_REGISTER 48
#define TEXT_SECTION_ASM_OP "\t.text"
#define INIT_SECTION_ASM_OP "\t.section \".init\", \"ax\", @progbits"
#define FINI_SECTION_ASM_OP "\t.section \".fini\", \"ax\", @progbits"
/* ÷ÁÖÎÏ, ÞÔÏ wbs = 0x6. åÓÌÉ ÉÚÍÅÎÑÔØ, ÔÏ ÎÕÖÎÏ ÔÁËÖÅ ÉÓÐÒÁ×ÌÑÔØ crti.c
* (ËÏÔÏÒÙÊ ÉÄ£Ô × ÓÏÓÔÁ×Å glibc). á ÜÔÏ ÎÁÒÕÛÉÔ Ä×ÏÉÞÎÕÀ ÓÏ×ÍÅÓÔÉÍÏÓÔØ. */
#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \
asm(SECTION_OP "\n" \
"\t{ nop 4; disp %ctpr1, " #FUNC " }\n" \
"\tcall %ctpr1, wbs = 0x6\n");
#endif /* defined(__sparc__) || defined(__e2k__) */
/* ************************************************************************** */
/* ïÂÝÁÑ ÞÁÓÔØ ÄÌÑ ÐÏÄÄÅÒÖÉ×ÁÅÍÙÈ ÐÌÁÔÆÏÒÍ. */
/* éÓÐÏÌØÚÕÅÔÓÑ × crtstuff.c, libgcc2.c. */
#define OBJECT_FORMAT_ELF
/* éÓÐÏÌØÚÕÅÔÓÑ × crtstuff.c. îÁÛ ËÏÍÐÉÌÑÔÏÒ ÎÅ ÕÍÅÅÔ transactional memory,
* ÐÏÜÔÏÍÕ 0. */
#define USE_TM_CLONE_REGISTRY 0
/* ÷ËÌÀÞÉÔØ × auto-host.h ÐÏÓÌÅ ×ËÌÀÞÅÎÉÑ ÐÏÄÄÅÒÖËÉ .init_array, .fini_array. */
#ifdef HAVE_INITFINI_ARRAY_SUPPORT
/* éÓÐÏÌØÚÕÅÔÓÑ × crtstuff.c. */
#define USE_INITFINI_ARRAY
/* åÓÌÉ ÅÓÔØ ÐÏÄÄÅÒÖËÁ .init_array, .fini_array, ÜÔÉ ÍÁËÒÏÓÙ ÎÕÖÎÏ
* ÒÁÚÏÐÒÅÄÅÌÉÔØ. */
#undef INIT_SECTION_ASM_OP
#undef FINI_SECTION_ASM_OP
/* éÓÐÏÌØÚÕÅÔÓÑ ÐÒÉ ÏÐÒÅÄÅÌÅÎÉÉ __LIBGCC_INIT_ARRAY_SECTION_ASM_OP__. */
#define INIT_ARRAY_SECTION_ASM_OP
/* éÓÐÏÌØÚÕÅÔÓÑ × crtstuff.c */
#define FINI_ARRAY_SECTION_ASM_OP
#endif /* HAVE_INITFINI_ARRAY_SUPPORT */
#define BITS_PER_UNIT 8
/* íÁËÒÏÓ Ó ÔÁËÉÍ ÉÍÅÎÅÍ ÉÓÐÏÌØÚÕÅÔÓÑ × gthr.h, gthr-posix.h. */
#define SUPPORTS_WEAK 1
/* éÓÐÏÌØÚÕÅÔÓÑ × crtstuff.c. */
#define TARGET_ATTRIBUTE_WEAK __attribute__ ((weak))
/* éÓÐÏÌØÚÕÅÔÓÑ ÄÌÑ ÏÐÒÅÄÅÌÅÎÉÑ __LIBGCC_EH_FRAME_SECTION_NAME__. */
#define EH_FRAME_SECTION_NAME ".eh_frame"
/* éÓÐÏÌØÚÕÅÔÓÑ ÄÌÑ ÏÐÒÅÄÅÌÅÎÉÑ __LIBGCC_EH_TABLES_CAN_BE_READ_ONLY__. */
#define EH_TABLES_CAN_BE_READ_ONLY 1
/* éÓÐÏÌØÚÕÅÔÓÑ ÄÌÑ ÏÐÒÅÄÅÌÅÎÉÑ __LIBGCC_DWARF_FRAME_REGISTERS__. */
#define DWARF_FRAME_REGISTERS FIRST_PSEUDO_REGISTER
/* éÓÐÏÌØÚÕÅÔÓÑ × unwind-dw2.c. */
#define DWARF_REG_TO_UNWIND_COLUMN(REGNO) (REGNO)
/* éÓÐÏÌØÚÕÅÔÓÑ ÄÌÑ ÏÐÒÅÄÅÌÅÎÉÑ __LIBGCC_VTABLE_USES_DESCRIPTORS__. */
#define TARGET_VTABLE_USES_DESCRIPTORS 0
/* éÓÐÏÌØÚÕÅÔÓÑ × libgcov.h, libgcov-driver-system.c. */
#define TARGET_POSIX_IO
/* éÓÐÏÌØÚÕÅÔÓÑ × libgcov.h. */
#define LONG_LONG_TYPE_SIZE 64
/* ************************************************************************** */
/* ïÐÒÅÄÅÌÅÎÉÅ ÍÁËÒÏÓÏ×, ËÏÔÏÒÙÅ ÐÏ-ÈÏÒÏÛÅÍÕ ÄÏÌÖÅÎ ÏÐÒÅÄÅÌÑÔØ ËÏÍÐÉÌÑÔÏÒ
* ÐÏ ÏÐÃÉÉ -fbuilding-libgcc. ðÏ ÜÔÏÊ ÏÐÃÉÉ ÍÙ ÏÐÒÅÄÅÌÑÅÍ ÞÁÓÔØ ÉÚ ÎÉÈ;
* ÏÓÔÁÌØÎÙÅ ÕÄÏÂÎÅÅ ÄÅÒÖÁÔØ ÚÄÅÓØ. */
/* éÓÐÏÌØÚÕÅÔÓÑ × crtstuff.c. */
#define __LIBGCC_EH_TABLES_CAN_BE_READ_ONLY__ EH_TABLES_CAN_BE_READ_ONLY
/* éÓÐÏÌØÚÕÅÔÓÑ × crtstuff.c. */
#ifdef EH_FRAME_SECTION_NAME
#define __LIBGCC_EH_FRAME_SECTION_NAME__ EH_FRAME_SECTION_NAME
#endif /* EH_FRAME_SECTION_NAME */
/* éÓÐÏÌØÚÕÅÔÓÑ × crtstuff.c. */
#ifdef CTORS_SECTION_ASM_OP
#define __LIBGCC_CTORS_SECTION_ASM_OP__ CTORS_SECTION_ASM_OP
#endif /* CTORS_SECTION_ASM_OP */
/* éÓÐÏÌØÚÕÅÔÓÑ × crtstuff.c. */
#ifdef DTORS_SECTION_ASM_OP
#define __LIBGCC_DTORS_SECTION_ASM_OP__ DTORS_SECTION_ASM_OP
#endif /* DTORS_SECTION_ASM_OP */
/* éÓÐÏÌØÚÕÅÔÓÑ × crtstuff.c. */
#ifdef TEXT_SECTION_ASM_OP
#define __LIBGCC_TEXT_SECTION_ASM_OP__ TEXT_SECTION_ASM_OP
#endif /* TEXT_SECTION_ASM_OP */
/* éÓÐÏÌØÚÕÅÔÓÑ × crtstuff.c, libgcc2.c. */
#ifdef INIT_SECTION_ASM_OP
#define __LIBGCC_INIT_SECTION_ASM_OP__ INIT_SECTION_ASM_OP
#endif /* INIT_SECTION_ASM_OP */
/* éÓÐÏÌØÚÕÅÔÓÑ × crtstuff.c, libgcc2.c. */
#ifdef INIT_ARRAY_SECTION_ASM_OP
#define __LIBGCC_INIT_ARRAY_SECTION_ASM_OP__
#endif /* INIT_ARRAY_SECTION_ASM_OP */
/* éÓÐÏÌØÚÕÅÔÓÑ × unwind-dw2.c. */
#if STACK_GROWS_DOWNWARD
#define __LIBGCC_STACK_GROWS_DOWNWARD__
#endif /* STACK_GROWS_DOWNWARD */
/* éÓÐÏÌØÚÕÅÔÓÑ × unwind-dw2.c. */
#define __LIBGCC_DWARF_FRAME_REGISTERS__ DWARF_FRAME_REGISTERS
/* éÓÐÏÌØÚÕÅÔÓÑ × unwind-dw2.c */
#ifdef EH_RETURN_STACKADJ_RTX
#define __LIBGCC_EH_RETURN_STACKADJ_RTX__
#endif /* EH_RETURN_STACKADJ_RTX */
/* éÓÐÏÌØÚÕÅÔÓÑ × libgcov-profiler.c. */
#define __LIBGCC_VTABLE_USES_DESCRIPTORS__ TARGET_VTABLE_USES_DESCRIPTORS
#endif /* GCC_TM_H */

View File

@ -23,7 +23,7 @@
## <http://www.gnu.org/licenses/>. ## <http://www.gnu.org/licenses/>.
ACLOCAL_AMFLAGS = -I .. -I ../config ACLOCAL_AMFLAGS = -I .. -I ../config
SUBDIRS = testsuite SUBDIRS =
## May be used by toolexeclibdir. ## May be used by toolexeclibdir.
gcc_version := $(shell @get_gcc_base_ver@ $(top_srcdir)/../gcc/BASE-VER) gcc_version := $(shell @get_gcc_base_ver@ $(top_srcdir)/../gcc/BASE-VER)

View File

@ -60,7 +60,7 @@ target_triplet = @target@
@ARCH_I386_TRUE@@HAVE_IFUNC_TRUE@am__append_2 = $(addsuffix _8_1_.lo,$(SIZEOBJS)) @ARCH_I386_TRUE@@HAVE_IFUNC_TRUE@am__append_2 = $(addsuffix _8_1_.lo,$(SIZEOBJS))
@ARCH_X86_64_TRUE@@HAVE_IFUNC_TRUE@am__append_3 = $(addsuffix _16_1_.lo,$(SIZEOBJS)) @ARCH_X86_64_TRUE@@HAVE_IFUNC_TRUE@am__append_3 = $(addsuffix _16_1_.lo,$(SIZEOBJS))
subdir = . subdir = .
DIST_COMMON = ChangeLog $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/configure $(am__configure_deps) \ $(top_srcdir)/configure $(am__configure_deps) \
$(srcdir)/auto-config.h.in $(srcdir)/../mkinstalldirs \ $(srcdir)/auto-config.h.in $(srcdir)/../mkinstalldirs \
$(srcdir)/../depcomp $(srcdir)/../depcomp
@ -298,7 +298,7 @@ top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@ top_builddir = @top_builddir@
top_srcdir = @top_srcdir@ top_srcdir = @top_srcdir@
ACLOCAL_AMFLAGS = -I .. -I ../config ACLOCAL_AMFLAGS = -I .. -I ../config
SUBDIRS = testsuite SUBDIRS =
gcc_version := $(shell @get_gcc_base_ver@ $(top_srcdir)/../gcc/BASE-VER) gcc_version := $(shell @get_gcc_base_ver@ $(top_srcdir)/../gcc/BASE-VER)
search_path = $(addprefix $(top_srcdir)/config/, $(config_path)) \ search_path = $(addprefix $(top_srcdir)/config/, $(config_path)) \
$(top_srcdir) $(top_builddir) $(top_srcdir) $(top_builddir)

12
libatomic/configure vendored
View File

@ -8239,7 +8239,7 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; }
*nto* | *qnx*) *nto* | *qnx*)
# QNX uses GNU C++, but need to define -shared option too, otherwise # QNX uses GNU C++, but need to define -shared option too, otherwise
# it will coredump. # it will coredump.
lt_prog_compiler_pic='-fPIC -shared' lt_prog_compiler_pic='-fPIC'
;; ;;
sysv4*MP*) sysv4*MP*)
@ -8366,7 +8366,7 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; }
*nto* | *qnx*) *nto* | *qnx*)
# QNX uses GNU C++, but need to define -shared option too, otherwise # QNX uses GNU C++, but need to define -shared option too, otherwise
# it will coredump. # it will coredump.
lt_prog_compiler_pic='-fPIC -shared' lt_prog_compiler_pic='-fPIC'
;; ;;
osf3* | osf4* | osf5*) osf3* | osf4* | osf5*)
@ -12333,6 +12333,7 @@ _ACEOF
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __atomic_load/store for size 2" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __atomic_load/store for size 2" >&5
$as_echo_n "checking for __atomic_load/store for size 2... " >&6; } $as_echo_n "checking for __atomic_load/store for size 2... " >&6; }
if test "${libat_cv_have_at_ldst_2+set}" = set; then : if test "${libat_cv_have_at_ldst_2+set}" = set; then :
@ -12400,6 +12401,7 @@ _ACEOF
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __atomic_load/store for size 4" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __atomic_load/store for size 4" >&5
$as_echo_n "checking for __atomic_load/store for size 4... " >&6; } $as_echo_n "checking for __atomic_load/store for size 4... " >&6; }
if test "${libat_cv_have_at_ldst_4+set}" = set; then : if test "${libat_cv_have_at_ldst_4+set}" = set; then :
@ -12467,6 +12469,7 @@ _ACEOF
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __atomic_load/store for size 8" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __atomic_load/store for size 8" >&5
$as_echo_n "checking for __atomic_load/store for size 8... " >&6; } $as_echo_n "checking for __atomic_load/store for size 8... " >&6; }
if test "${libat_cv_have_at_ldst_8+set}" = set; then : if test "${libat_cv_have_at_ldst_8+set}" = set; then :
@ -12534,6 +12537,7 @@ _ACEOF
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __atomic_load/store for size 16" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __atomic_load/store for size 16" >&5
$as_echo_n "checking for __atomic_load/store for size 16... " >&6; } $as_echo_n "checking for __atomic_load/store for size 16... " >&6; }
if test "${libat_cv_have_at_ldst_16+set}" = set; then : if test "${libat_cv_have_at_ldst_16+set}" = set; then :
@ -12602,6 +12606,7 @@ _ACEOF
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __atomic_test_and_set for size 1" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __atomic_test_and_set for size 1" >&5
$as_echo_n "checking for __atomic_test_and_set for size 1... " >&6; } $as_echo_n "checking for __atomic_test_and_set for size 1... " >&6; }
if test "${libat_cv_have_at_tas_1+set}" = set; then : if test "${libat_cv_have_at_tas_1+set}" = set; then :
@ -15281,7 +15286,7 @@ else
multilib_arg= multilib_arg=
fi fi
ac_config_files="$ac_config_files Makefile testsuite/Makefile" ac_config_files="$ac_config_files Makefile"
cat >confcache <<\_ACEOF cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure # This file is a shell script that caches the results of configure
@ -16329,7 +16334,6 @@ do
"libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
"gstdint.h") CONFIG_COMMANDS="$CONFIG_COMMANDS gstdint.h" ;; "gstdint.h") CONFIG_COMMANDS="$CONFIG_COMMANDS gstdint.h" ;;
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
"testsuite/Makefile") CONFIG_FILES="$CONFIG_FILES testsuite/Makefile" ;;
*) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;; *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
esac esac

View File

@ -263,5 +263,5 @@ else
multilib_arg= multilib_arg=
fi fi
AC_CONFIG_FILES(Makefile testsuite/Makefile) AC_CONFIG_FILES(Makefile)
AC_OUTPUT AC_OUTPUT

View File

@ -73,6 +73,18 @@
} \ } \
} while (0) } while (0)
#if (defined __LCC__) && (defined __ptr128__)
#undef LARGER
#define LARGER(N) \
do { \
/* do nothing (bug #114558) */ \
if (1) break; \
/* avoid warnings */ \
r = 0; a = 0; v = (union max_size_u){ 0 }; \
if (1) goto Lsucc; else goto Lfail; \
} while (0)
#endif /* __LCC__ */
bool bool
@ -90,7 +102,11 @@ libat_compare_exchange (size_t n, void *mptr, void *eptr, void *dptr,
case 2: EXACT(2); goto L4; case 2: EXACT(2); goto L4;
case 4: EXACT(4); goto L8; case 4: EXACT(4); goto L8;
case 8: EXACT(8); goto L16; case 8: EXACT(8); goto L16;
#if defined(__LCC__) && defined(__ptr128__) && (! HAVE_ATOMIC_CAS_16)
case 16: /* do nothing (mcstbug #125743.4) */ break;
#else
case 16: EXACT(16); break; case 16: EXACT(16); break;
#endif
case 3: L4: LARGER(4); /* FALLTHRU */ case 3: L4: LARGER(4); /* FALLTHRU */
case 5 ... 7: L8: LARGER(8); /* FALLTHRU */ case 5 ... 7: L8: LARGER(8); /* FALLTHRU */

View File

@ -76,6 +76,17 @@
} \ } \
} while (0) } while (0)
#if (defined __LCC__) && (defined __ptr128__)
#undef LARGER
#define LARGER(N) \
do { \
/* do nothing (bug #114558) */ \
if (1) break; \
/* avoid warnings */ \
r = 0; a = 0; v = (union max_size_u){ 0 }; goto Lfinish; \
} while (0)
#endif /* __LCC__ */
static void __attribute__((noinline)) static void __attribute__((noinline))
libat_exchange_large_inplace (size_t n, void *mptr, void *vptr) libat_exchange_large_inplace (size_t n, void *mptr, void *vptr)
@ -114,7 +125,11 @@ libat_exchange (size_t n, void *mptr, void *vptr, void *rptr, int smodel)
case 2: EXACT(2); goto L4; case 2: EXACT(2); goto L4;
case 4: EXACT(4); goto L8; case 4: EXACT(4); goto L8;
case 8: EXACT(8); goto L16; case 8: EXACT(8); goto L16;
#if defined(__LCC__) && defined(__ptr128__) && (! HAVE_ATOMIC_EXCHANGE_16)
case 16: /* do nothing (mcstbug #125743.4) */ break;
#else
case 16: EXACT(16); break; case 16: EXACT(16); break;
#endif
case 3: L4: LARGER(4); /* FALLTHRU */ case 3: L4: LARGER(4); /* FALLTHRU */
case 5 ... 7: L8: LARGER(8); /* FALLTHRU */ case 5 ... 7: L8: LARGER(8); /* FALLTHRU */

View File

@ -63,6 +63,17 @@
EXACT_ (N, u.C2(i,N), PTR(N,a), goto Lfinish); \ EXACT_ (N, u.C2(i,N), PTR(N,a), goto Lfinish); \
} while (0) } while (0)
#if (defined __LCC__) && (defined __ptr128__)
#undef LARGER
#define LARGER(N) \
do { \
/* do nothing (bug #114558) */ \
if (1) break; \
/* avoid warnings */ \
r = 0; a = 0; goto Lfinish; \
} while (0)
#endif /* __LCC__ */
void void
libat_load (size_t n, void *mptr, void *rptr, int smodel) libat_load (size_t n, void *mptr, void *rptr, int smodel)
@ -77,7 +88,11 @@ libat_load (size_t n, void *mptr, void *rptr, int smodel)
case 2: EXACT(2); goto L4; case 2: EXACT(2); goto L4;
case 4: EXACT(4); goto L8; case 4: EXACT(4); goto L8;
case 8: EXACT(8); goto L16; case 8: EXACT(8); goto L16;
#if defined(__LCC__) && defined(__ptr128__) && (! HAVE_ATOMIC_LDST_16)
case 16: /* do nothing (mcstbug #125743.4) */ break;
#else
case 16: EXACT(16); break; case 16: EXACT(16); break;
#endif
case 3: L4: LARGER(4); /* FALLTHRU */ case 3: L4: LARGER(4); /* FALLTHRU */
case 5 ... 7: L8: LARGER(8); /* FALLTHRU */ case 5 ... 7: L8: LARGER(8); /* FALLTHRU */

View File

@ -78,6 +78,14 @@
} \ } \
} while (0) } while (0)
#if (defined __LCC__) && (defined __ptr128__)
#undef LARGER
#define LARGER(N) \
do { \
/* do nothing (bug #114558) */ \
} while (0)
#endif /* __LCC__ */
void void
libat_store (size_t n, void *mptr, void *vptr, int smodel) libat_store (size_t n, void *mptr, void *vptr, int smodel)
@ -89,7 +97,11 @@ libat_store (size_t n, void *mptr, void *vptr, int smodel)
case 2: EXACT(2); goto L4; case 2: EXACT(2); goto L4;
case 4: EXACT(4); goto L8; case 4: EXACT(4); goto L8;
case 8: EXACT(8); goto L16; case 8: EXACT(8); goto L16;
#if defined(__LCC__) && defined(__ptr128__) && (! HAVE_ATOMIC_LDST_16)
case 16: /* do nothing (mcstbug #125743.4) */ break;
#else
case 16: EXACT(16); break; case 16: EXACT(16); break;
#endif
case 3: L4: LARGER(4); /* FALLTHRU */ case 3: L4: LARGER(4); /* FALLTHRU */
case 5 ... 7: L8: LARGER(8); /* FALLTHRU */ case 5 ... 7: L8: LARGER(8); /* FALLTHRU */

View File

@ -213,6 +213,15 @@ DECLARE_ALL_SIZED(4);
DECLARE_ALL_SIZED(8); DECLARE_ALL_SIZED(8);
DECLARE_ALL_SIZED(16); DECLARE_ALL_SIZED(16);
#if defined(__LCC__) && !defined(__OPTIMIZE__) /* См. bug #89377, #87484.5. */
#if !HAVE_INT16 /* Чтобы не сломать сборку при включении поддержки __int128. */
#define libat_load_16 ((__typeof__(libat_load_16) *)0)
#define libat_store_16 ((__typeof__(libat_store_16) *)0)
#define libat_exchange_16 ((__typeof__(libat_exchange_16) *)0)
#define libat_compare_exchange_16 ((__typeof__(libat_compare_exchange_16) *)0)
#endif /* !HAVE_INT16 */
#endif /* defined(__LCC__) && !defined(__OPTIMIZE__) */
#undef DECLARE_1 #undef DECLARE_1
#undef DECLARE_ALL_SIZED #undef DECLARE_ALL_SIZED
#undef DECLARE_ALL_SIZED_ #undef DECLARE_ALL_SIZED_

View File

@ -239,8 +239,8 @@ endif
# Options to use when compiling libgcc2.a. # Options to use when compiling libgcc2.a.
# #
LIBGCC2_DEBUG_CFLAGS = -g LIBGCC2_DEBUG_CFLAGS =
LIBGCC2_CFLAGS = -O2 $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) $(HOST_LIBGCC2_CFLAGS) \ LIBGCC2_CFLAGS = $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) $(HOST_LIBGCC2_CFLAGS) \
$(LIBGCC2_DEBUG_CFLAGS) -DIN_LIBGCC2 \ $(LIBGCC2_DEBUG_CFLAGS) -DIN_LIBGCC2 \
-fbuilding-libgcc -fno-stack-protector \ -fbuilding-libgcc -fno-stack-protector \
$(INHIBIT_LIBC_CFLAGS) $(INHIBIT_LIBC_CFLAGS)
@ -290,17 +290,17 @@ INTERNAL_CFLAGS = $(CFLAGS) $(LIBGCC2_CFLAGS) $(HOST_LIBGCC2_CFLAGS) \
$(INCLUDES) @set_have_cc_tls@ @set_use_emutls@ $(INCLUDES) @set_have_cc_tls@ @set_use_emutls@
# Options to use when compiling crtbegin/end. # Options to use when compiling crtbegin/end.
CRTSTUFF_CFLAGS = -O2 $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -g0 \ CRTSTUFF_CFLAGS = $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -g0 \
$(NO_PIE_CFLAGS) -finhibit-size-directive -fno-inline -fno-exceptions \ $(NO_PIE_CFLAGS) -finhibit-size-directive -fno-inline -fno-exceptions \
-fno-zero-initialized-in-bss -fno-toplevel-reorder -fno-tree-vectorize \ -fno-toplevel-reorder \
-fbuilding-libgcc -fno-stack-protector $(FORCE_EXPLICIT_EH_REGISTRY) \ -fbuilding-libgcc -fno-stack-protector $(FORCE_EXPLICIT_EH_REGISTRY) \
$(INHIBIT_LIBC_CFLAGS) $(INHIBIT_LIBC_CFLAGS)
# Extra flags to use when compiling crt{begin,end}.o. # Extra flags to use when compiling crt{begin,end}.o.
CRTSTUFF_T_CFLAGS = CRTSTUFF_T_CFLAGS =
MULTIDIR := $(shell $(CC) $(CFLAGS) -print-multi-directory) MULTIDIR := .
MULTIOSDIR := $(shell $(CC) $(CFLAGS) -print-multi-os-directory) MULTIOSDIR := .
MULTIOSSUBDIR := $(shell if test $(MULTIOSDIR) != .; then echo /$(MULTIOSDIR); fi) MULTIOSSUBDIR := $(shell if test $(MULTIOSDIR) != .; then echo /$(MULTIOSDIR); fi)
inst_libdir = $(libsubdir)$(MULTISUBDIR) inst_libdir = $(libsubdir)$(MULTISUBDIR)
@ -425,9 +425,9 @@ LIB2ADD += enable-execute-stack.c
# While emutls.c has nothing to do with EH, it is in LIB2ADDEH* # While emutls.c has nothing to do with EH, it is in LIB2ADDEH*
# instead of LIB2ADD because that's the way to be sure on some targets # instead of LIB2ADD because that's the way to be sure on some targets
# (e.g. *-*-darwin*) only one copy of it is linked. # (e.g. *-*-darwin*) only one copy of it is linked.
LIB2ADDEH += $(srcdir)/emutls.c # LIB2ADDEH += $(srcdir)/emutls.c
LIB2ADDEHSTATIC += $(srcdir)/emutls.c # LIB2ADDEHSTATIC += $(srcdir)/emutls.c
LIB2ADDEHSHARED += $(srcdir)/emutls.c # LIB2ADDEHSHARED += $(srcdir)/emutls.c
# Library members defined in libgcc2.c. # Library members defined in libgcc2.c.
lib2funcs = _muldi3 _negdi2 _lshrdi3 _ashldi3 _ashrdi3 _cmpdi2 _ucmpdi2 \ lib2funcs = _muldi3 _negdi2 _lshrdi3 _ashldi3 _ashrdi3 _cmpdi2 _ucmpdi2 \

View File

@ -484,6 +484,10 @@ cris-*-elf)
cris-*-linux* | crisv32-*-linux*) cris-*-linux* | crisv32-*-linux*)
tmake_file="$tmake_file cris/t-cris t-softfp-sfdf t-softfp cris/t-linux" tmake_file="$tmake_file cris/t-cris t-softfp-sfdf t-softfp cris/t-linux"
;; ;;
e2k-mcst-linux-gnu)
tmake_file="$tmake_file e2k/t-eh-e2k e2k/t-crtalign t-softfp-tf e2k/t-softfp t-softfp e2k/t-linux"
extra_parts="$extra_parts crtalign.o"
;;
epiphany-*-elf* | epiphany-*-rtems*) epiphany-*-elf* | epiphany-*-rtems*)
tmake_file="$tmake_file epiphany/t-epiphany t-fdpbit epiphany/t-custom-eqsf" tmake_file="$tmake_file epiphany/t-epiphany t-fdpbit epiphany/t-custom-eqsf"
extra_parts="$extra_parts crti.o crtint.o crtrunc.o crtm1reg-r43.o crtm1reg-r63.o crtn.o" extra_parts="$extra_parts crti.o crtint.o crtrunc.o crtm1reg-r43.o crtm1reg-r63.o crtn.o"
@ -1195,7 +1199,7 @@ sparc-*-elf*)
extra_parts="$extra_parts crti.o crtn.o crtfastmath.o" extra_parts="$extra_parts crti.o crtn.o crtfastmath.o"
;; ;;
sparc-*-linux*) # SPARC's running GNU/Linux, libc6 sparc-*-linux*) # SPARC's running GNU/Linux, libc6
tmake_file="${tmake_file} t-crtfm" tmake_file="${tmake_file} t-crtfm sparc/t-crtunaligned"
if test "${host_address}" = 64; then if test "${host_address}" = 64; then
tmake_file="$tmake_file sparc/t-linux64" tmake_file="$tmake_file sparc/t-linux64"
fi fi
@ -1216,7 +1220,7 @@ sparc-*-linux*) # SPARC's running GNU/Linux, libc6
fi fi
;; ;;
esac esac
extra_parts="$extra_parts crtfastmath.o" extra_parts="$extra_parts crtfastmath.o crtunaligned.o"
md_unwind_header=sparc/linux-unwind.h md_unwind_header=sparc/linux-unwind.h
;; ;;
sparc-*-rtems*) sparc-*-rtems*)
@ -1243,8 +1247,8 @@ sparc64-*-freebsd*|ultrasparc-*-freebsd*)
extra_parts="$extra_parts crtfastmath.o" extra_parts="$extra_parts crtfastmath.o"
;; ;;
sparc64-*-linux*) # 64-bit SPARC's running GNU/Linux sparc64-*-linux*) # 64-bit SPARC's running GNU/Linux
extra_parts="$extra_parts crtfastmath.o" extra_parts="$extra_parts crtfastmath.o crtunaligned.o"
tmake_file="${tmake_file} t-crtfm sparc/t-linux" tmake_file="${tmake_file} t-crtfm sparc/t-linux sparc/t-crtunaligned"
if test "${host_address}" = 64; then if test "${host_address}" = 64; then
tmake_file="${tmake_file} sparc/t-linux64" tmake_file="${tmake_file} sparc/t-linux64"
fi fi

View File

@ -0,0 +1,15 @@
#ifndef __e2k__
#error Поддерживается только e2k
#endif
.section ".init", "ax", @progbits
/*
* Установка флага запрета невыровненных обращений
*/
rrs %upsr, %r0
ors %r0, (1<<2), %r0
{
rws %r0, %upsr
nop 4
}

View File

@ -0,0 +1,64 @@
# Copyright (C) 2000-2017 Free Software Foundation, Inc.
#
# This file is part of GCC.
#
# GCC is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GCC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GCC; see the file COPYING3. If not see
# <http://www.gnu.org/licenses/>.
# In order to work around the very problems that force us to now generally
# create a libgcc.so, glibc reexported a number of routines from libgcc.a.
# By now choosing the same version tags for these specific routines, we
# maintain enough binary compatibility to allow future versions of glibc
# to defer implementation of these routines to libgcc.so via DT_AUXILIARY.
%exclude {
__divdi3
__moddi3
__udivdi3
__umoddi3
__register_frame
__register_frame_table
__deregister_frame
__register_frame_info
__deregister_frame_info
__frame_state_for
__register_frame_info_table
}
%inherit GCC_3.0 GLIBC_2.0
GLIBC_2.0 {
# Sampling of DImode arithmetic used by (at least) i386 and m68k.
__divdi3
__moddi3
__udivdi3
__umoddi3
# Exception handling support functions used by most everyone.
__register_frame
__register_frame_table
__deregister_frame
__register_frame_info
__deregister_frame_info
__frame_state_for
__register_frame_info_table
}
# mcstbug #120089
# Used <ecomp>/lib/GNU/gcc-7/libgcc/config/libgcc-glibc.ver
# with additions below
GCC_7.0.0 {
__copysigntf3
__fabstf2
__signbittf2
}

View File

@ -0,0 +1,32 @@
#include "sfp-machine.h"
void __attribute__ ((optimize(0)))
__sfp_handle_exceptions (int _fex)
{
const double max = __DBL_MAX__;
const double min = __DBL_MIN__;
const double zero = 0.0;
const double one = 1.0;
volatile double r;
if (_fex & FP_EX_INVALID)
{
r = zero / zero;
}
if (_fex & FP_EX_DIVZERO)
{
r = one / zero;
}
if (_fex & FP_EX_OVERFLOW)
{
r = max + max;
}
if (_fex & FP_EX_UNDERFLOW)
{
r = min * min;
}
if (_fex & FP_EX_INEXACT)
{
r = max - one;
}
}

View File

@ -0,0 +1,100 @@
#define _FP_W_TYPE_SIZE 64
#define _FP_W_TYPE unsigned long long
#define _FP_WS_TYPE signed long long
#define _FP_I_TYPE long long
typedef int TItype __attribute__ ((mode (TI)));
typedef unsigned int UTItype __attribute__ ((mode (TI)));
#define TI_BITS (__CHAR_BIT__ * (int)sizeof(TItype))
/* The type of the result of a floating point comparison. This must
match `__libgcc_cmp_return__' in GCC for the target. */
typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
#define CMPtype __gcc_CMPtype
#define _FP_MUL_MEAT_Q(R,X,Y) \
_FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
#define _FP_NANFRAC_S _FP_QNANBIT_S
#define _FP_NANFRAC_D _FP_QNANBIT_D
#define _FP_NANFRAC_E _FP_QNANBIT_E, 0
#define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0
#define _FP_KEEPNANFRACP 1
#define _FP_QNANNEGATEDP 0
#define _FP_NANSIGN_S 1
#define _FP_NANSIGN_D 1
#define _FP_NANSIGN_E 1
#define _FP_NANSIGN_Q 1
/* Here is something Intel misdesigned: the specs don't define
the case where we have two NaNs with same mantissas, but
different sign. Different operations pick up different NaNs. */
#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
do { \
if (_FP_FRAC_GT_##wc(X, Y) \
|| (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*'))) \
{ \
R##_s = X##_s; \
_FP_FRAC_COPY_##wc(R,X); \
} \
else \
{ \
R##_s = Y##_s; \
_FP_FRAC_COPY_##wc(R,Y); \
} \
R##_c = FP_CLS_NAN; \
} while (0)
#define _FP_TININESS_AFTER_ROUNDING 1
#define FP_EX_INVALID 0x01
#define FP_EX_DENORM 0x02
#define FP_EX_DIVZERO 0x04
#define FP_EX_OVERFLOW 0x08
#define FP_EX_UNDERFLOW 0x10
#define FP_EX_INEXACT 0x20
#define FP_EX_ALL \
(FP_EX_INVALID | FP_EX_DENORM | FP_EX_DIVZERO | FP_EX_OVERFLOW \
| FP_EX_UNDERFLOW | FP_EX_INEXACT)
void __sfp_handle_exceptions (int);
#define FP_HANDLE_EXCEPTIONS \
do { \
if (__builtin_expect (_fex, 0)) \
__sfp_handle_exceptions (_fex); \
} while (0)
#define FP_TRAPPING_EXCEPTIONS ((~_pfpfr >> 7) & FP_EX_ALL)
#define FP_RND_NEAREST 0x0000
#define FP_RND_ZERO 0x6000
#define FP_RND_PINF 0x4000
#define FP_RND_MINF 0x2000
#define FP_RND_MASK 0x6000
#define _FP_DECL_EX \
unsigned int _pfpfr __attribute__ ((unused)) = FP_RND_NEAREST
#define FP_INIT_ROUNDMODE \
_Pragma ("asm_inline") __asm__ __volatile ("rrs %%pfpfr, %0" : "=r" (_pfpfr))
#define FP_ROUNDMODE (_pfpfr & FP_RND_MASK)
#define __LITTLE_ENDIAN 1234
#define __BIG_ENDIAN 4321
#define __BYTE_ORDER __LITTLE_ENDIAN
/* Define ALIASNAME as a strong alias for NAME. */
#define strong_alias(name, aliasname) _strong_alias(name, aliasname)
#define _strong_alias(name, aliasname) \
extern __typeof (name) aliasname __attribute__ ((alias (#name)));
#pragma diag_suppress 62 /* "shift count is negative" */
#pragma diag_suppress 63 /* "shift count is too large" */

View File

@ -0,0 +1,2 @@
crtalign.o: $(srcdir)/config/e2k/crtalign.S
$(gcc_compile) -c -x assembler-with-cpp $<

View File

@ -0,0 +1,6 @@
LIB2ADDEH = $(srcdir)/config/e2k/unwind-dw2-e2k.c $(srcdir)/unwind-dw2-fde-dip.c \
$(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c
# liblcc.a should be linked into libgcc_s.so for the sake of runtime support of
# `__builtin_cpu_is ()' in the latter.
SHLIB_LC = -llcc -lc

View File

@ -0,0 +1,3 @@
# Override t-slibgcc-elf-ver to export some libgcc symbols with
# the symbol versions that glibc used.
SHLIB_MAPFILES += $(srcdir)/config/e2k/libgcc-glibc.ver

View File

@ -0,0 +1,5 @@
# Provide fallbacks for __builtin_copysignq, __builtin_fabsq
# and __builtin_signbitq.
LIB2ADD += $(srcdir)/config/e2k/tf-signs.c
LIB2ADD += $(srcdir)/config/e2k/sfp-exceptions.c

View File

@ -0,0 +1,71 @@
/* Copyright (C) 2008-2017 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
union _FP_UNION_Q
{
__float128 flt;
struct
{
unsigned long long frac0 : 64;
unsigned long long frac1 : 48;
unsigned exp : 15;
unsigned sign : 1;
} bits __attribute__((packed));
};
__float128 __copysigntf3 (__float128, __float128);
__float128 __fabstf2 (__float128);
int __signbittf2 (__float128);
__float128
__copysigntf3 (__float128 a, __float128 b)
{
union _FP_UNION_Q A, B;
A.flt = a;
B.flt = b;
A.bits.sign = B.bits.sign;
return A.flt;
}
__float128
__fabstf2 (__float128 a)
{
union _FP_UNION_Q A;
A.flt = a;
A.bits.sign = 0;
return A.flt;
}
int
__signbittf2 (__float128 a)
{
union _FP_UNION_Q A;
A.flt = a;
return A.bits.sign;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,8 @@
#include <sys/prctl.h>
static void __attribute__((constructor))
__permit_unaligned_ldd_std (void)
{
/* óÍ. bug #81602 */
prctl (PR_SET_UNALIGN, PR_UNALIGN_NOPRINT, 0, 0, 0);
}

View File

@ -0,0 +1,2 @@
crtunaligned.o: $(srcdir)/config/sparc/crtunaligned.c
$(gcc_compile) -c $<

0
libgcc/configure vendored Normal file → Executable file
View File

View File

@ -62,6 +62,11 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#include "coretypes.h" #include "coretypes.h"
#include "tm.h" #include "tm.h"
#include "libgcc_tm.h" #include "libgcc_tm.h"
#if defined (__e2k__) && defined (__ptr128__)
/* Required because of `_Unwind_Ptr'. */
# include "unwind.h"
#endif /* defined (__e2k__) && defined (__ptr128__) */
#include "unwind-dw2-fde.h" #include "unwind-dw2-fde.h"
#ifndef FORCE_CODE_SECTION_ALIGN #ifndef FORCE_CODE_SECTION_ALIGN
@ -180,7 +185,12 @@ call_ ## FUNC (void) \
extern void __register_frame_info (const void *, struct object *) extern void __register_frame_info (const void *, struct object *)
TARGET_ATTRIBUTE_WEAK; TARGET_ATTRIBUTE_WEAK;
extern void __register_frame_info_bases (const void *, struct object *, extern void __register_frame_info_bases (const void *, struct object *,
void *, void *) # if ! (defined (__e2k__) && defined (__ptr128__))
void *, void *
# else /* defined (__e2k__) && defined (__ptr128__) */
_Unwind_Ptr, _Unwind_Ptr
# endif /* defined (__e2k__) && defined (__ptr128__) */
)
TARGET_ATTRIBUTE_WEAK; TARGET_ATTRIBUTE_WEAK;
extern void *__deregister_frame_info (const void *) extern void *__deregister_frame_info (const void *)
TARGET_ATTRIBUTE_WEAK; TARGET_ATTRIBUTE_WEAK;

View File

@ -169,12 +169,14 @@ GCC_3.0 {
_Unwind_GetGR _Unwind_GetGR
_Unwind_GetIP _Unwind_GetIP
_Unwind_GetLanguageSpecificData _Unwind_GetLanguageSpecificData
_Unwind_GetPCSP
_Unwind_GetRegionStart _Unwind_GetRegionStart
_Unwind_GetTextRelBase _Unwind_GetTextRelBase
_Unwind_GetDataRelBase _Unwind_GetDataRelBase
_Unwind_RaiseException _Unwind_RaiseException
_Unwind_Resume _Unwind_Resume
_Unwind_SetGR _Unwind_SetGR
_Unwind_SetGRPtr
_Unwind_SetIP _Unwind_SetIP
__deregister_frame __deregister_frame
__deregister_frame_info __deregister_frame_info

View File

@ -32,8 +32,10 @@
#include "tconfig.h" #include "tconfig.h"
#include "tsystem.h" #include "tsystem.h"
#if !defined(inhibit_libc) && !defined(__OpenBSD__) #if !defined(inhibit_libc) && !defined(__OpenBSD__) && !defined(__QNX__)
#include <elf.h> /* Get DT_CONFIG. */ #include <elf.h> /* Get DT_CONFIG. */
#elif defined(__QNX__)
#include <sys/elf.h>
#endif #endif
#include "coretypes.h" #include "coretypes.h"
#include "tm.h" #include "tm.h"
@ -87,10 +89,20 @@
#include <link.h> #include <link.h>
#ifndef __RELOC_POINTER #ifndef __RELOC_POINTER
# if ! (defined (__e2k__) && defined (__ptr128__))
# define __RELOC_POINTER(ptr, base) ((ptr) + (base)) # define __RELOC_POINTER(ptr, base) ((ptr) + (base))
# else /* defined (__e2k__) && defined (__ptr128__) */
// # define __RELOC_POINTER(idx, ap) &ap[idx]
# endif /* defined (__e2k__) && defined (__ptr128__) */
#endif #endif
static const fde * _Unwind_Find_registered_FDE (void *pc, struct dwarf_eh_bases *bases); static const fde * _Unwind_Find_registered_FDE (
#if ! (defined (__e2k__) && defined ( __ptr128__))
void *pc,
#else /* defined (__e2k__) && defined (__ptr128__) */
_Unwind_Ptr pc,
#endif /* defined (__e2k__) && defined (__ptr128__) */
struct dwarf_eh_bases *bases);
#define _Unwind_Find_FDE _Unwind_Find_registered_FDE #define _Unwind_Find_FDE _Unwind_Find_registered_FDE
#include "unwind-dw2-fde.c" #include "unwind-dw2-fde.c"
@ -103,8 +115,13 @@ static const fde * _Unwind_Find_registered_FDE (void *pc, struct dwarf_eh_bases
struct unw_eh_callback_data struct unw_eh_callback_data
{ {
_Unwind_Ptr pc; _Unwind_Ptr pc;
#if ! (defined (__e2k__) && defined (__ptr128__))
void *tbase; void *tbase;
void *dbase; void *dbase;
#else /* defined (__e2k__) && defined (__ptr128__) */
_Unwind_Ptr tbase;
_Unwind_Ptr dbase;
#endif /* defined (__e2k__) && defined (__ptr128__) */
void *func; void *func;
const fde *ret; const fde *ret;
int check_cache; int check_cache;
@ -127,9 +144,18 @@ static struct frame_hdr_cache_element
#if defined __FRV_FDPIC__ || defined __BFIN_FDPIC__ #if defined __FRV_FDPIC__ || defined __BFIN_FDPIC__
struct elf32_fdpic_loadaddr load_base; struct elf32_fdpic_loadaddr load_base;
#else #else
#if ! (defined (__e2k__) && defined (__ptr128__))
_Unwind_Ptr load_base; _Unwind_Ptr load_base;
#else /* defined (__e2k__) && defined (__ptr128__) */
_Unwind_Ptr text_base;
const char *gd;
#endif /* defined (__e2k__) && defined (__ptr128__) */
#endif #endif
#if ! (defined (__e2k__) && defined (__ptr128__))
const ElfW(Phdr) *p_eh_frame_hdr; const ElfW(Phdr) *p_eh_frame_hdr;
#else /* defined (__e2k__) && defined (__ptr128__) */
const struct unw_eh_frame_hdr *eh_frame_hdr_contents;
#endif /* defined (__e2k__) && defined (__ptr128__) */
const ElfW(Phdr) *p_dynamic; const ElfW(Phdr) *p_dynamic;
struct frame_hdr_cache_element *link; struct frame_hdr_cache_element *link;
} frame_hdr_cache[FRAME_HDR_CACHE_SIZE]; } frame_hdr_cache[FRAME_HDR_CACHE_SIZE];
@ -161,26 +187,187 @@ base_from_cb_data (unsigned char encoding, struct unw_eh_callback_data *data)
} }
} }
#if defined __e2k__ && defined __ptr128__
static unsigned int
get_range_num (const char *gd,
unsigned int phnum,
const ElfW(Phdr) *phdrs)
{
unsigned int i = 0;
const ElfW(Phdr) *phdr;
for (phdr = &phdrs[0]; phdr < &phdrs[phnum]; phdr++)
{
if (phdr->p_type == PT_LOAD)
{
++i;
/* Use the same criterium as in glibc to distinguish between legacy
and packed PM ELFs. */
if (phdr->p_offset == 0 && !(phdr->p_flags & PF_X))
{
uintptr_t phdr_offset = (uintptr_t) phdrs - (uintptr_t) gd;
if (phdr_offset >= phdr->p_vaddr)
/* Good chances are that this is a legacy PM ELF. */
return 0;
}
}
}
return i;
}
struct range
{
uintptr_t min;
uintptr_t max;
uintptr_t align;
long delta;
int in_cud;
};
static void
fill_ranges (unsigned int phnum,
const ElfW(Phdr) *phdrs,
unsigned int range_num,
struct range *ranges)
{
unsigned int i;
const ElfW(Phdr) *phdr;
for (phdr = phdrs, i = 0;
(phdr < &phdrs[phnum]
/* Just to be on the safe side. */
&& i < range_num);
++phdr)
{
if (phdr->p_type == PT_LOAD)
{
ranges[i].min = phdr->p_vaddr;
ranges[i].max = phdr->p_vaddr + phdr->p_memsz;
ranges[i].align = phdr->p_align;
ranges[i].in_cud = (phdr->p_flags & PF_X) ? 1 : 0;
i++;
}
}
/* Stupidly sort the obtained ranges. I believe that qsort () may be
unavailable in context of ld.so */
for (i = 0; i < range_num - 1; i++)
{
unsigned int j;
for (j = i + 1; j < range_num; j++)
{
if (ranges[j].min < ranges[i].min)
{
struct range tmp = ranges[i];
ranges[i] = ranges[j];
ranges[j] = tmp;
}
}
}
uintptr_t max_page_aligned = 0;
uintptr_t cud_size = 0, gd_size = 0;
for (i = 0; i < range_num; i++)
{
uintptr_t min_page_aligned = ranges[i].min & ~(ranges[i].align - 1);
uintptr_t b, r, pos;
/* MAX_PAGE_ALIGNED corresponds to the preceding segment in this
comparison, of course. */
if (min_page_aligned < max_page_aligned)
{
/* The Kernel should have failed to load this executable
in such a case. */
}
max_page_aligned = (ranges[i].max + 0xfffULL) & ~(0xfffULL);
if (ranges[i].in_cud)
pos = cud_size;
else
pos = gd_size;
pos = (pos + 0xfffULL) & ~0xfffULL;
r = ranges[i].min & (ranges[i].align - 1);
b = (pos + ranges[i].align - (r + 1)) / ranges[i].align;
pos = b * ranges[i].align + r;
ranges[i].delta = pos - ranges[i].min;
pos += ranges[i].max - ranges[i].min;
if (ranges[i].in_cud)
cud_size = pos;
else
gd_size = pos;
}
}
long
get_offset_delta (const char *gd,
unsigned int phnum,
const ElfW(Phdr) *phdrs,
uintptr_t off)
{
unsigned int range_num = get_range_num (gd, phnum, phdrs);
struct range ranges[range_num];
fill_ranges (phnum, phdrs, range_num, ranges);
unsigned int j;
for (j = 0; j < range_num; j++)
{
if (off >= ranges[j].min && off < ranges[j].max)
return ranges[j].delta;
}
return 0;
}
#endif /* defined __e2k__ && defined __ptr128__ */
static int static int
_Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr) _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr)
{ {
struct unw_eh_callback_data *data = (struct unw_eh_callback_data *) ptr; struct unw_eh_callback_data *data = (struct unw_eh_callback_data *) ptr;
const ElfW(Phdr) *phdr, *p_eh_frame_hdr, *p_dynamic; const ElfW(Phdr) *phdr;
# if ! (defined (__e2k__) && defined (__ptr128__))
const ElfW(Phdr) *p_eh_frame_hdr;
#endif /* ! (defined (__e2k__) && defined (__ptr128__)) */
const ElfW(Phdr) *p_dynamic;
long n, match; long n, match;
#if defined __FRV_FDPIC__ || defined __BFIN_FDPIC__ #if defined __FRV_FDPIC__ || defined __BFIN_FDPIC__
struct elf32_fdpic_loadaddr load_base; struct elf32_fdpic_loadaddr load_base;
#else #else
# if ! (defined (__e2k__) && defined (__ptr128__))
_Unwind_Ptr load_base; _Unwind_Ptr load_base;
# else /* defined (__e2k__) && defined (__ptr128__) */
_Unwind_Ptr text_base;
const char *gd;
# endif /* defined (__e2k__) && defined (__ptr128__) */
#endif #endif
const unsigned char *p; const unsigned char *p;
const struct unw_eh_frame_hdr *hdr; const struct unw_eh_frame_hdr *hdr;
#if ! (defined (__e2k__) && defined (__ptr128__))
_Unwind_Ptr eh_frame; _Unwind_Ptr eh_frame;
#else /* defined (__e2k__) && defined (__ptr128__) */
_Unwind_Ptr eh_frame_off;
void *eh_frame;
#endif /* defined (__e2k__) && defined (__ptr128__) */
struct object ob; struct object ob;
_Unwind_Ptr pc_low = 0, pc_high = 0; _Unwind_Ptr pc_low = 0, pc_high = 0;
struct ext_dl_phdr_info struct ext_dl_phdr_info
{ {
ElfW(Addr) dlpi_addr; ElfW(Addr) dlpi_addr;
#if defined (__e2k__) && defined (__ptr128__)
const char *dlpi_gd;
#endif /* defined (__e2k__) && defined (__ptr128__) */
const char *dlpi_name; const char *dlpi_name;
const ElfW(Phdr) *dlpi_phdr; const ElfW(Phdr) *dlpi_phdr;
ElfW(Half) dlpi_phnum; ElfW(Half) dlpi_phnum;
@ -190,8 +377,14 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr)
match = 0; match = 0;
phdr = info->dlpi_phdr; phdr = info->dlpi_phdr;
#if ! (defined (__e2k__) && defined (__ptr128__))
load_base = info->dlpi_addr; load_base = info->dlpi_addr;
p_eh_frame_hdr = NULL; p_eh_frame_hdr = NULL;
#else /* defined (__e2k__) && defined (__ptr128__) */
text_base = info->dlpi_addr;
gd = info->dlpi_gd;
hdr = NULL;
#endif /* defined (__e2k__) && defined (__ptr128__) */
p_dynamic = NULL; p_dynamic = NULL;
struct frame_hdr_cache_element *prev_cache_entry = NULL, struct frame_hdr_cache_element *prev_cache_entry = NULL,
@ -222,8 +415,14 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr)
if (data->pc >= cache_entry->pc_low if (data->pc >= cache_entry->pc_low
&& data->pc < cache_entry->pc_high) && data->pc < cache_entry->pc_high)
{ {
#if ! (defined (__e2k__) && defined (__ptr128__))
load_base = cache_entry->load_base; load_base = cache_entry->load_base;
p_eh_frame_hdr = cache_entry->p_eh_frame_hdr; p_eh_frame_hdr = cache_entry->p_eh_frame_hdr;
#else /* defined (__e2k__) && defined (__ptr128__) */
text_base = cache_entry->text_base;
gd = cache_entry->gd;
hdr = cache_entry->eh_frame_hdr_contents;
#endif /* defined (__e2k__) && defined (__ptr128__) */
p_dynamic = cache_entry->p_dynamic; p_dynamic = cache_entry->p_dynamic;
/* And move the entry we're using to the head. */ /* And move the entry we're using to the head. */
@ -272,10 +471,25 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr)
segment at the same time. */ segment at the same time. */
for (n = info->dlpi_phnum; --n >= 0; phdr++) for (n = info->dlpi_phnum; --n >= 0; phdr++)
{ {
if (phdr->p_type == PT_LOAD) if (phdr->p_type == PT_LOAD
#if defined (__e2k__) && defined (__ptr128__)
/* Ensure that the segment under consideration belongs to the text
segment in PM. Otherwise, the calculation of VADDR below won't
make any sense. */
&& (phdr->p_flags & PF_X)
#endif /* defined (__e2k__) && defined (__ptr128__) */
)
{ {
#if ! (defined (__e2k__) && defined (__ptr128__))
_Unwind_Ptr vaddr = (_Unwind_Ptr) _Unwind_Ptr vaddr = (_Unwind_Ptr)
__RELOC_POINTER (phdr->p_vaddr, load_base); __RELOC_POINTER (phdr->p_vaddr, load_base);
#else /* defined (__e2k__) && defined (__ptr128__) */
_Unwind_Ptr vaddr = (text_base + phdr->p_vaddr
+ get_offset_delta (info->dlpi_gd,
info->dlpi_phnum,
info->dlpi_phdr,
phdr->p_vaddr));
#endif /* defined (__e2k__) && defined (__ptr128__) */
if (data->pc >= vaddr && data->pc < vaddr + phdr->p_memsz) if (data->pc >= vaddr && data->pc < vaddr + phdr->p_memsz)
{ {
match = 1; match = 1;
@ -284,7 +498,22 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr)
} }
} }
else if (phdr->p_type == PT_GNU_EH_FRAME) else if (phdr->p_type == PT_GNU_EH_FRAME)
{
#if ! (defined (__e2k__) && defined (__ptr128__))
p_eh_frame_hdr = phdr; p_eh_frame_hdr = phdr;
#else /* defined (__e2k__) && defined (__ptr128__) */
/* One finds himself here if the matching hash entry does not exist
yet. So, gd should still contain info->dlpi_gd set in the very
beginning of this function. */
gcc_assert (gd == info->dlpi_gd);
hdr = ((const struct unw_eh_frame_hdr *)
&gd[phdr->p_vaddr
+ get_offset_delta (gd,
info->dlpi_phnum,
info->dlpi_phdr,
phdr->p_vaddr)]);
#endif /* defined (__e2k__) && defined (__ptr128__) */
}
#ifdef PT_SUNW_UNWIND #ifdef PT_SUNW_UNWIND
/* Sun ld emits PT_SUNW_UNWIND .eh_frame_hdr sections instead of /* Sun ld emits PT_SUNW_UNWIND .eh_frame_hdr sections instead of
PT_SUNW_EH_FRAME/PT_GNU_EH_FRAME, so accept them as well. */ PT_SUNW_EH_FRAME/PT_GNU_EH_FRAME, so accept them as well. */
@ -310,8 +539,15 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr)
frame_hdr_cache_head = last_cache_entry; frame_hdr_cache_head = last_cache_entry;
} }
#if ! (defined (__e2k__) && defined (__ptr128__))
frame_hdr_cache_head->load_base = load_base; frame_hdr_cache_head->load_base = load_base;
frame_hdr_cache_head->p_eh_frame_hdr = p_eh_frame_hdr; frame_hdr_cache_head->p_eh_frame_hdr = p_eh_frame_hdr;
#else /* defined (__e2k__) && defined (__ptr128__) */
frame_hdr_cache_head->text_base = text_base;
frame_hdr_cache_head->gd = gd;
frame_hdr_cache_head->eh_frame_hdr_contents = hdr;
#endif /* defined (__e2k__) && defined (__ptr128__) */
frame_hdr_cache_head->p_dynamic = p_dynamic; frame_hdr_cache_head->p_dynamic = p_dynamic;
frame_hdr_cache_head->pc_low = pc_low; frame_hdr_cache_head->pc_low = pc_low;
frame_hdr_cache_head->pc_high = pc_high; frame_hdr_cache_head->pc_high = pc_high;
@ -319,12 +555,22 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr)
found: found:
if (!p_eh_frame_hdr) if (
#if ! (defined (__e2k__) && defined (__ptr128__))
!p_eh_frame_hdr
#else /* defined (__e2k__) && defined (__ptr128__) */
!hdr
#endif /* defined (__e2k__) && defined (__ptr128__) */
)
return 0; return 0;
/* Read .eh_frame_hdr header. */ /* Read .eh_frame_hdr header. */
#if ! (defined (__e2k__) && defined (__ptr128__))
hdr = (const struct unw_eh_frame_hdr *) hdr = (const struct unw_eh_frame_hdr *)
__RELOC_POINTER (p_eh_frame_hdr->p_vaddr, load_base); __RELOC_POINTER (p_eh_frame_hdr->p_vaddr, load_base);
#else /* defined (__e2k__) && defined (__ptr128__) */
/* In PM it has already been read or fetched from the cache above. */
#endif /* defined (__e2k__) && defined (__ptr128__) */
if (hdr->version != 1) if (hdr->version != 1)
return 1; return 1;
@ -341,13 +587,13 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr)
if (dyn->d_tag == DT_PLTGOT) if (dyn->d_tag == DT_PLTGOT)
{ {
data->dbase = (void *) dyn->d_un.d_ptr; data->dbase = (void *) dyn->d_un.d_ptr;
#if defined __linux__ # if defined __linux__
/* On IA-32 Linux, _DYNAMIC is writable and GLIBC has /* On IA-32 Linux, _DYNAMIC is writable and GLIBC has
relocated it. */ relocated it. */
#elif defined __sun__ && defined __svr4__ # elif defined __sun__ && defined __svr4__
/* On Solaris 2/x86, we need to do this ourselves. */ /* On Solaris 2/x86, we need to do this ourselves. */
data->dbase += load_base; data->dbase += load_base;
#endif # endif
break; break;
} }
} }
@ -362,7 +608,18 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr)
base_from_cb_data (hdr->eh_frame_ptr_enc, base_from_cb_data (hdr->eh_frame_ptr_enc,
data), data),
(const unsigned char *) (hdr + 1), (const unsigned char *) (hdr + 1),
&eh_frame); #if ! (defined (__e2k__) && defined (__ptr128__))
&eh_frame
#else /* defined (__e2k__) && defined (__ptr128__) */
&eh_frame_off
#endif /* defined (__e2k__) && defined (__ptr128__) */
);
#if defined (__e2k__) && defined (__ptr128__)
eh_frame = (void *) &info->dlpi_gd[eh_frame_off - (_Unwind_Ptr) info->dlpi_gd];
#endif /* defined (__e2k__) && defined (__ptr128__) */
/* We require here specific table encoding to speed things up. /* We require here specific table encoding to speed things up.
Also, DW_EH_PE_datarel here means using PT_GNU_EH_FRAME start Also, DW_EH_PE_datarel here means using PT_GNU_EH_FRAME start
@ -392,6 +649,16 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr)
unsigned int f_enc, f_enc_size; unsigned int f_enc, f_enc_size;
_Unwind_Ptr range; _Unwind_Ptr range;
#if defined (__e2k__) && defined (__ptr128__)
/* This rather strangely named variable is used by them both to
evaluate runtime PCs based on the values encoded in the `table[]'
and the pointer to the resulting FDE. In PM it's used only for the
former goal, whereas FDE is obtained via the offset from the start
of `.eh_frame_hdr' pointed to by `hdr' without this idiotic
intermediate cast to `_Unwind_Ptr'. */
data_base += text_base - (_Unwind_Ptr) gd;
#endif /* defined (__e2k__) && defined (__ptr128__) */
mid = fde_count - 1; mid = fde_count - 1;
if (data->pc < table[0].initial_loc + data_base) if (data->pc < table[0].initial_loc + data_base)
return 1; return 1;
@ -413,8 +680,11 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr)
gcc_assert (lo < hi); gcc_assert (lo < hi);
} }
#if ! (defined (__e2k__) && defined (__ptr128__))
f = (fde *) (table[mid].fde + data_base); f = (fde *) (table[mid].fde + data_base);
#else /* defined (__e2k__) && defined (__ptr128__) */
f = (fde *) &((char *) hdr)[table[mid].fde];
#endif /* defined (__e2k__) && defined (__ptr128__) */
f_enc = get_fde_encoding (f); f_enc = get_fde_encoding (f);
f_enc_size = size_of_encoded_value (f_enc); f_enc_size = size_of_encoded_value (f_enc);
read_encoded_value_with_base (f_enc & 0x0f, 0, read_encoded_value_with_base (f_enc & 0x0f, 0,
@ -429,13 +699,21 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr)
/* We have no sorted search table, so need to go the slow way. /* We have no sorted search table, so need to go the slow way.
As soon as GLIBC will provide API so to notify that a library has been As soon as GLIBC will provide API so to notify that a library has been
removed, we could cache this (and thus use search_object). */ removed, we could cache this (and thus use search_object). */
#if ! (defined (__e2k__) && defined (__ptr128__))
ob.pc_begin = NULL; ob.pc_begin = NULL;
#else /* defined (__e2k__) && defined (__ptr128__) */
ob.pc_begin = 0;
#endif /* defined (__e2k__) && defined (__ptr128__) */
ob.tbase = data->tbase; ob.tbase = data->tbase;
ob.dbase = data->dbase; ob.dbase = data->dbase;
ob.u.single = (fde *) eh_frame; ob.u.single = (fde *) eh_frame;
ob.s.i = 0; ob.s.i = 0;
ob.s.b.mixed_encoding = 1; /* Need to assume worst case. */ ob.s.b.mixed_encoding = 1; /* Need to assume worst case. */
data->ret = linear_search_fdes (&ob, (fde *) eh_frame, (void *) data->pc); data->ret = linear_search_fdes (&ob, (fde *) eh_frame,
#if !(defined (__e2k__) && defined (__ptr128__))
(void *)
#endif /* !(defined (__e2k__) && defined (__ptr128__)) */
data->pc);
if (data->ret != NULL) if (data->ret != NULL)
{ {
_Unwind_Ptr func; _Unwind_Ptr func;
@ -450,7 +728,13 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr)
} }
const fde * const fde *
_Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases) _Unwind_Find_FDE (
#if ! (defined (__e2k__) && defined (__ptr128__))
void *pc,
#else /* defined (__e2k__) && defined (__ptr128__) */
_Unwind_Ptr pc,
#endif /* defined (__e2k__) && defined (__ptr128__) */
struct dwarf_eh_bases *bases)
{ {
struct unw_eh_callback_data data; struct unw_eh_callback_data data;
const fde *ret; const fde *ret;
@ -460,8 +744,13 @@ _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases)
return ret; return ret;
data.pc = (_Unwind_Ptr) pc; data.pc = (_Unwind_Ptr) pc;
#if ! (defined (__e2k__) && defined (__ptr128__))
data.tbase = NULL; data.tbase = NULL;
data.dbase = NULL; data.dbase = NULL;
#else /* defined (__e2k__) && defined (__ptr128__) */
data.tbase = 0;
data.dbase = 0;
#endif /* defined (__e2k__) && defined (__ptr128__) */
data.func = NULL; data.func = NULL;
data.ret = NULL; data.ret = NULL;
data.check_cache = 1; data.check_cache = 1;

View File

@ -83,13 +83,22 @@ static __gthread_mutex_t object_mutex;
void void
__register_frame_info_bases (const void *begin, struct object *ob, __register_frame_info_bases (const void *begin, struct object *ob,
void *tbase, void *dbase) #if ! (defined (__e2k__) && defined (__ptr128__))
void *tbase, void *dbase
#else /* defined (__e2k__) && defined (__ptr128__) */
_Unwind_Ptr tbase, _Unwind_Ptr dbase
#endif /* defined (__e2k__) && defined (__ptr128__) */
)
{ {
/* If .eh_frame is empty, don't register at all. */ /* If .eh_frame is empty, don't register at all. */
if ((const uword *) begin == 0 || *(const uword *) begin == 0) if ((const uword *) begin == 0 || *(const uword *) begin == 0)
return; return;
#if ! (defined (__e2k__) && defined (__ptr128__))
ob->pc_begin = (void *)-1; ob->pc_begin = (void *)-1;
#else /* defined (__e2k__) && defined (__ptr128__) */
ob->pc_begin = (_Unwind_Ptr) -1;
#endif /* defined (__e2k__) && defined (__ptr128__) */
ob->tbase = tbase; ob->tbase = tbase;
ob->dbase = dbase; ob->dbase = dbase;
ob->u.single = begin; ob->u.single = begin;
@ -121,7 +130,31 @@ __register_frame_info_bases (const void *begin, struct object *ob,
void void
__register_frame_info (const void *begin, struct object *ob) __register_frame_info (const void *begin, struct object *ob)
{ {
__register_frame_info_bases (begin, ob, 0, 0); #if defined (__e2k__) && defined (__ptr128__)
_Unwind_Ptr tbase;
_Unwind_Ptr dbase;
tbase = ({
register unsigned long cud;
asm volatile ("rrd %%cud.lo, %0" : "=r" (cud));
(_Unwind_Ptr) (cud & 0xffffffff);
});
dbase = ({
register unsigned long gd;
asm volatile ("rrd %%gd.lo, %0" : "=r" (gd));
(_Unwind_Ptr) (gd & 0xffffffff);
});
#endif /* defined (__e2k__) && defined (__ptr128__) */
__register_frame_info_bases (begin, ob,
#if ! (defined (__e2k__) && defined (__ptr128__))
0, 0
#else /* defined (__e2k__) && defined (__ptr128__) */
tbase, dbase
#endif /* defined (__e2k__) && defined (__ptr128__) */
);
} }
void void
@ -143,9 +176,18 @@ __register_frame (void *begin)
void void
__register_frame_info_table_bases (void *begin, struct object *ob, __register_frame_info_table_bases (void *begin, struct object *ob,
void *tbase, void *dbase) #if ! (defined (__e2k__) && defined (__ptr128__))
void *tbase, void *dbase
#else /* defined (__e2k__) && defined (__ptr128__) */
_Unwind_Ptr tbase, _Unwind_Ptr dbase
#endif /* defined (__e2k__) && defined (__ptr128__) */
)
{ {
#if ! (defined (__e2k__) && defined (__ptr128__))
ob->pc_begin = (void *)-1; ob->pc_begin = (void *)-1;
#else /* defined (__e2k__) && defined (__ptr128__) */
ob->pc_begin = (_Unwind_Ptr) -1;
#endif /* defined (__e2k__) && defined (__ptr128__) */
ob->tbase = tbase; ob->tbase = tbase;
ob->dbase = dbase; ob->dbase = dbase;
ob->u.array = begin; ob->u.array = begin;
@ -272,10 +314,20 @@ base_from_object (unsigned char encoding, struct object *ob)
switch (encoding & 0x70) switch (encoding & 0x70)
{ {
case DW_EH_PE_absptr: case DW_EH_PE_absptr:
#if ! (defined (__e2k__) && defined (__ptr128__))
case DW_EH_PE_pcrel: case DW_EH_PE_pcrel:
#endif /* ! (defined (__e2k__) && defined (__ptr128__)) */
case DW_EH_PE_aligned: case DW_EH_PE_aligned:
return 0; return 0;
#if defined (__e2k__) && defined (__ptr128__)
case DW_EH_PE_pcrel:
/* Take into account that in PM the value calculated by means of the
relative encoding and the current position in `.eh_frame' belong to
different segments. */
return (_Unwind_Ptr) ob->tbase - (_Unwind_Ptr) ob->dbase;
#endif /* defined (__e2k__) && defined (__ptr128__) */
case DW_EH_PE_textrel: case DW_EH_PE_textrel:
return (_Unwind_Ptr) ob->tbase; return (_Unwind_Ptr) ob->tbase;
case DW_EH_PE_datarel: case DW_EH_PE_datarel:
@ -292,7 +344,11 @@ static int
get_cie_encoding (const struct dwarf_cie *cie) get_cie_encoding (const struct dwarf_cie *cie)
{ {
const unsigned char *aug, *p; const unsigned char *aug, *p;
#if ! (defined (__e2k__) && defined (__ptr128__))
_Unwind_Ptr dummy; _Unwind_Ptr dummy;
#else /* defined (__e2k__) && defined (__ptr128__) */
void *dummy;
#endif /* defined (__e2k__) && defined (__ptr128__) */
_uleb128_t utmp; _uleb128_t utmp;
_sleb128_t stmp; _sleb128_t stmp;
@ -329,7 +385,13 @@ get_cie_encoding (const struct dwarf_cie *cie)
/* ??? Avoid dereferencing indirect pointers, since we're /* ??? Avoid dereferencing indirect pointers, since we're
faking the base address. Gotta keep DW_EH_PE_aligned faking the base address. Gotta keep DW_EH_PE_aligned
intact, however. */ intact, however. */
p = read_encoded_value_with_base (*p & 0x7F, 0, p + 1, &dummy); p =
#if ! (defined (__e2k__) && defined (__ptr128__))
read_encoded_value_with_base
#else /* defined (__e2k__) && defined (__ptr128__) */
read_encoded_ptr_with_base
#endif /* defined (__e2k__) && defined (__ptr128__) */
(*p & 0x7F, 0, p + 1, &dummy);
} }
/* LSDA encoding. */ /* LSDA encoding. */
else if (*aug == 'L') else if (*aug == 'L')
@ -671,17 +733,30 @@ classify_object_over_fdes (struct object *ob, const fde *this_fde)
the encoding is smaller than a pointer a true NULL may not the encoding is smaller than a pointer a true NULL may not
be representable. Assume 0 in the representable bits is NULL. */ be representable. Assume 0 in the representable bits is NULL. */
mask = size_of_encoded_value (encoding); mask = size_of_encoded_value (encoding);
/* FIXME: in PM `size_of_encoded_value ()' returns 8, which is probably
unreasonably large and should be fixed. This makes the calculations
below result in an unexpected `mask == 0' somehow taking into account
that `_Unwind_Ptr' is a 32-bit type. Temporarely overcome this issue
this way . . . */
#if ! (defined (__e2k__) && defined (__ptr128__))
if (mask < sizeof (void *)) if (mask < sizeof (void *))
mask = (((_Unwind_Ptr) 1) << (mask << 3)) - 1; mask = (((_Unwind_Ptr) 1) << (mask << 3)) - 1;
else else
#endif /* ! (defined (__e2k__) && defined (__ptr128__)) */
mask = -1; mask = -1;
if ((pc_begin & mask) == 0) if ((pc_begin & mask) == 0)
continue; continue;
count += 1; count += 1;
#if ! (defined (__e2k__) && defined (__ptr128__))
if ((void *) pc_begin < ob->pc_begin) if ((void *) pc_begin < ob->pc_begin)
ob->pc_begin = (void *) pc_begin; ob->pc_begin = (void *) pc_begin;
#else /* defined (__e2k__) && defined (__ptr128__) */
if (pc_begin < ob->pc_begin)
ob->pc_begin = pc_begin;
#endif /* defined (__e2k__) && defined (__ptr128__) */
} }
return count; return count;
@ -733,10 +808,14 @@ add_fdes (struct object *ob, struct fde_accumulator *accu, const fde *this_fde)
In these cases, the function address will be NULL, but if In these cases, the function address will be NULL, but if
the encoding is smaller than a pointer a true NULL may not the encoding is smaller than a pointer a true NULL may not
be representable. Assume 0 in the representable bits is NULL. */ be representable. Assume 0 in the representable bits is NULL. */
mask = size_of_encoded_value (encoding); mask = size_of_encoded_value (encoding);
/* See above. */
#if ! (defined (__e2k__) && defined (__ptr128__))
if (mask < sizeof (void *)) if (mask < sizeof (void *))
mask = (((_Unwind_Ptr) 1) << (mask << 3)) - 1; mask = (((_Unwind_Ptr) 1) << (mask << 3)) - 1;
else else
#endif /* defined (__e2k__) && defined (__ptr128__) */
mask = -1; mask = -1;
if ((pc_begin & mask) == 0) if ((pc_begin & mask) == 0)
@ -823,7 +902,13 @@ init_object (struct object* ob)
array. */ array. */
static const fde * static const fde *
linear_search_fdes (struct object *ob, const fde *this_fde, void *pc) linear_search_fdes (struct object *ob, const fde *this_fde,
#if ! (defined (__e2k__) && defined (__ptr128__))
void *pc
#else /* defined (__e2k__) && defined (__ptr128__) */
_Unwind_Ptr pc
#endif /* defined (__e2k__) && defined (__ptr128__) */
)
{ {
const struct dwarf_cie *last_cie = 0; const struct dwarf_cie *last_cie = 0;
int encoding = ob->s.b.encoding; int encoding = ob->s.b.encoding;
@ -893,7 +978,13 @@ linear_search_fdes (struct object *ob, const fde *this_fde, void *pc)
implementations of increasing complexity. */ implementations of increasing complexity. */
static inline const fde * static inline const fde *
binary_search_unencoded_fdes (struct object *ob, void *pc) binary_search_unencoded_fdes (struct object *ob,
#if ! (defined (__e2k__) && defined (__ptr128__))
void *pc
#else /* defined (__e2k__) && defined (__ptr128__) */
_Unwind_Ptr pc
#endif /* defined (__e2k__) && defined (__ptr128__) */
)
{ {
struct fde_vector *vec = ob->u.sort; struct fde_vector *vec = ob->u.sort;
size_t lo, hi; size_t lo, hi;
@ -902,9 +993,19 @@ binary_search_unencoded_fdes (struct object *ob, void *pc)
{ {
size_t i = (lo + hi) / 2; size_t i = (lo + hi) / 2;
const fde *const f = vec->array[i]; const fde *const f = vec->array[i];
#if ! (defined (__e2k__) && defined (__ptr128__))
void *pc_begin; void *pc_begin;
#else /* defined (__e2k__) && defined (__ptr128__) */
_Unwind_Ptr pc_begin;
#endif /* defined (__e2k__) && defined (__ptr128__) */
uaddr pc_range; uaddr pc_range;
memcpy (&pc_begin, (const void * const *) f->pc_begin, sizeof (void *)); memcpy (&pc_begin,
#if ! (defined (__e2k__) && defined (__ptr128__))
(const void * const *) f->pc_begin, sizeof (void *)
#else /* defined (__e2k__) && defined (__ptr128__) */
(const _Unwind_Ptr *) f->pc_begin, sizeof (_Unwind_Ptr)
#endif /* defined (__e2k__) && defined (__ptr128__) */
);
memcpy (&pc_range, (const uaddr *) f->pc_begin + 1, sizeof (uaddr)); memcpy (&pc_range, (const uaddr *) f->pc_begin + 1, sizeof (uaddr));
if (pc < pc_begin) if (pc < pc_begin)
@ -919,7 +1020,13 @@ binary_search_unencoded_fdes (struct object *ob, void *pc)
} }
static inline const fde * static inline const fde *
binary_search_single_encoding_fdes (struct object *ob, void *pc) binary_search_single_encoding_fdes (struct object *ob,
#if ! (defined (__e2k__) && defined (__ptr128__))
void *pc
#else /* defined (__e2k__) && defined (__ptr128__) */
_Unwind_Ptr pc
#endif /* defined (__e2k__) && defined (__ptr128__) */
)
{ {
struct fde_vector *vec = ob->u.sort; struct fde_vector *vec = ob->u.sort;
int encoding = ob->s.b.encoding; int encoding = ob->s.b.encoding;
@ -949,7 +1056,13 @@ binary_search_single_encoding_fdes (struct object *ob, void *pc)
} }
static inline const fde * static inline const fde *
binary_search_mixed_encoding_fdes (struct object *ob, void *pc) binary_search_mixed_encoding_fdes (struct object *ob,
#if ! (defined (__e2k__) && defined (__ptr128__))
void *pc
#else /* defined (__e2k__) && defined (__ptr128__) */
_Unwind_Ptr pc
#endif /* defined (__e2k__) && defined (__ptr128__) */
)
{ {
struct fde_vector *vec = ob->u.sort; struct fde_vector *vec = ob->u.sort;
size_t lo, hi; size_t lo, hi;
@ -980,7 +1093,13 @@ binary_search_mixed_encoding_fdes (struct object *ob, void *pc)
} }
static const fde * static const fde *
search_object (struct object* ob, void *pc) search_object (struct object* ob,
#if ! (defined (__e2k__) && defined (__ptr128__))
void *pc
#else /* defined (__e2k__) && defined (__ptr128__) */
_Unwind_Ptr pc
#endif /* defined (__e2k__) && defined (__ptr128__) */
)
{ {
/* If the data hasn't been sorted, try to do this now. We may have /* If the data hasn't been sorted, try to do this now. We may have
more memory available than last time we tried. */ more memory available than last time we tried. */
@ -1024,7 +1143,13 @@ search_object (struct object* ob, void *pc)
} }
const fde * const fde *
_Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases) _Unwind_Find_FDE (
#if ! (defined (__e2k__) && defined (__ptr128__))
void *pc,
#else /* defined (__e2k__) && defined (__ptr128__) */
_Unwind_Ptr pc,
#endif /* defined (__e2k__) && defined (__ptr128__) */
struct dwarf_eh_bases *bases)
{ {
struct object *ob; struct object *ob;
const fde *f = NULL; const fde *f = NULL;

View File

@ -39,9 +39,15 @@ struct fde_vector
struct object struct object
{ {
#if ! (defined (__e2k__) && defined (__ptr128__))
void *pc_begin; void *pc_begin;
void *tbase; void *tbase;
void *dbase; void *dbase;
#else /* defined (__e2k__) && defined (__ptr128__) */
_Unwind_Ptr pc_begin;
_Unwind_Ptr tbase;
_Unwind_Ptr dbase;
#endif /* defined (__e2k__) && defined (__ptr128__) */
union { union {
const struct dwarf_fde *single; const struct dwarf_fde *single;
struct dwarf_fde **array; struct dwarf_fde **array;
@ -84,18 +90,33 @@ struct old_object
struct dwarf_eh_bases struct dwarf_eh_bases
{ {
#if ! (defined (__e2k__) && defined (__ptr128__))
void *tbase; void *tbase;
void *dbase; void *dbase;
#else /* defined (__e2k__) && defined (__ptr128__) */
_Unwind_Ptr tbase;
_Unwind_Ptr dbase;
#endif /* defined (__e2k__) && defined (__ptr128__) */
void *func; void *func;
}; };
extern void __register_frame_info_bases (const void *, struct object *, extern void __register_frame_info_bases (const void *, struct object *,
void *, void *); #if ! (defined (__e2k__) && defined (__ptr128__))
void *, void *
#else /* defined (__e2k__) && defined (__ptr128__) */
_Unwind_Ptr, _Unwind_Ptr
#endif /* defined (__e2k__) && defined (__ptr128__) */
);
extern void __register_frame_info (const void *, struct object *); extern void __register_frame_info (const void *, struct object *);
extern void __register_frame (void *); extern void __register_frame (void *);
extern void __register_frame_info_table_bases (void *, struct object *, extern void __register_frame_info_table_bases (void *, struct object *,
void *, void *); #if ! (defined (__e2k__) && defined (__ptr128__))
void *, void *
#else /* defined (__e2k__) && defined (__ptr128__) */
_Unwind_Ptr, _Unwind_Ptr
#endif /* defined (__e2k__) && defined (__ptr128__) */
);
extern void __register_frame_info_table (void *, struct object *); extern void __register_frame_info_table (void *, struct object *);
extern void __register_frame_table (void *); extern void __register_frame_table (void *);
extern void *__deregister_frame_info (const void *); extern void *__deregister_frame_info (const void *);
@ -105,7 +126,11 @@ extern void __deregister_frame (void *);
typedef int sword __attribute__ ((mode (SI))); typedef int sword __attribute__ ((mode (SI)));
typedef unsigned int uword __attribute__ ((mode (SI))); typedef unsigned int uword __attribute__ ((mode (SI)));
typedef unsigned int uaddr __attribute__ ((mode (pointer))); typedef unsigned int uaddr
#if ! (defined (__e2k__) && defined (__ptr128__))
__attribute__ ((mode (pointer)))
#endif /* ! (defined (__e2k__) && defined (__ptr128__)) */
;
typedef int saddr __attribute__ ((mode (pointer))); typedef int saddr __attribute__ ((mode (pointer)));
typedef unsigned char ubyte; typedef unsigned char ubyte;
@ -163,7 +188,13 @@ next_fde (const fde *f)
return (const fde *) ((const char *) f + f->length + sizeof (f->length)); return (const fde *) ((const char *) f + f->length + sizeof (f->length));
} }
extern const fde * _Unwind_Find_FDE (void *, struct dwarf_eh_bases *); extern const fde * _Unwind_Find_FDE (
#if ! (defined (__e2k__) && defined (__ptr128__))
void *,
#else /* defined (__e2k__) && defined (__ptr128__) */
_Unwind_Ptr,
#endif /* defined (__e2k__) && defined (__ptr128__) */
struct dwarf_eh_bases *);
static inline int static inline int
last_fde (struct object *obj __attribute__ ((__unused__)), const fde *f) last_fde (struct object *obj __attribute__ ((__unused__)), const fde *f)

View File

@ -31,6 +31,8 @@ typedef struct
another register, or a location expression. */ another register, or a location expression. */
struct frame_state_reg_info struct frame_state_reg_info
{ {
/* reg[] isn't currently used in any way on E2K. */
#if ! defined __e2k__
struct { struct {
union { union {
_Unwind_Word reg; _Unwind_Word reg;
@ -47,6 +49,7 @@ typedef struct
REG_UNDEFINED REG_UNDEFINED
} how; } how;
} reg[__LIBGCC_DWARF_FRAME_REGISTERS__+1]; } reg[__LIBGCC_DWARF_FRAME_REGISTERS__+1];
#endif /* ! defined __e2k__ */
/* Used to implement DW_CFA_remember_state. */ /* Used to implement DW_CFA_remember_state. */
struct frame_state_reg_info *prev; struct frame_state_reg_info *prev;

View File

@ -49,10 +49,17 @@ typedef unsigned _Unwind_Word __attribute__((__mode__(__unwind_word__)));
typedef signed _Unwind_Sword __attribute__((__mode__(__unwind_word__))); typedef signed _Unwind_Sword __attribute__((__mode__(__unwind_word__)));
#if defined(__ia64__) && defined(__hpux__) #if defined(__ia64__) && defined(__hpux__)
typedef unsigned _Unwind_Ptr __attribute__((__mode__(__word__))); typedef unsigned _Unwind_Ptr __attribute__((__mode__(__word__)));
#else #elif ! (defined (__e2k__) && defined (__ptr128__))
typedef unsigned _Unwind_Ptr __attribute__((__mode__(__pointer__))); typedef unsigned _Unwind_Ptr __attribute__((__mode__(__pointer__)));
#endif #endif
#if ! (defined (__e2k__) && defined (__ptr128__))
typedef unsigned _Unwind_Internal_Ptr __attribute__((__mode__(__pointer__))); typedef unsigned _Unwind_Internal_Ptr __attribute__((__mode__(__pointer__)));
#else /* defined (__e2k__) && defined (__ptr128__) */
/* We may live in 64-bit address space in PM nowadays if ELF64 is used. */
typedef unsigned long _Unwind_Ptr;
typedef unsigned long _Unwind_Internal_Ptr;
#endif /* defined (__e2k__) && defined (__ptr128__) */
/* @@@ The IA-64 ABI uses a 64-bit word to identify the producer and /* @@@ The IA-64 ABI uses a 64-bit word to identify the producer and
consumer of an exception. We'll go along with this for now even on consumer of an exception. We'll go along with this for now even on
@ -95,8 +102,13 @@ struct _Unwind_Exception
#if !defined (__USING_SJLJ_EXCEPTIONS__) && defined (__SEH__) #if !defined (__USING_SJLJ_EXCEPTIONS__) && defined (__SEH__)
_Unwind_Word private_[6]; _Unwind_Word private_[6];
#else #else
# if ! (defined (__e2k__) && defined (__ptr128__))
_Unwind_Word private_1; _Unwind_Word private_1;
_Unwind_Word private_2; _Unwind_Word private_2;
# else /* defined (__e2k__) && defined (__ptr128__) */
void *private_1;
void *private_2;
# endif /* defined (__e2k__) && defined (__ptr128__) */
#endif #endif
/* @@@ The IA-64 ABI says that this structure must be double-word aligned. /* @@@ The IA-64 ABI says that this structure must be double-word aligned.
@ -170,6 +182,12 @@ _Unwind_Backtrace (_Unwind_Trace_Fn, void *);
extern _Unwind_Word _Unwind_GetGR (struct _Unwind_Context *, int); extern _Unwind_Word _Unwind_GetGR (struct _Unwind_Context *, int);
extern void _Unwind_SetGR (struct _Unwind_Context *, int, _Unwind_Word); extern void _Unwind_SetGR (struct _Unwind_Context *, int, _Unwind_Word);
/* This one should be externally visible only in Protected Mode. */
#if defined (__e2k__) && defined (__ptr128__)
extern void _Unwind_SetGRPtr (struct _Unwind_Context *context, int index,
void *p);
#endif /* defined (__e2k__) && defined (__ptr128__) */
extern _Unwind_Ptr _Unwind_GetIP (struct _Unwind_Context *); extern _Unwind_Ptr _Unwind_GetIP (struct _Unwind_Context *);
extern _Unwind_Ptr _Unwind_GetIPInfo (struct _Unwind_Context *, int *); extern _Unwind_Ptr _Unwind_GetIPInfo (struct _Unwind_Context *, int *);
extern void _Unwind_SetIP (struct _Unwind_Context *, _Unwind_Ptr); extern void _Unwind_SetIP (struct _Unwind_Context *, _Unwind_Ptr);
@ -244,7 +262,13 @@ extern _Unwind_Ptr _Unwind_GetTextRelBase (struct _Unwind_Context *);
/* @@@ Given an address, return the entry point of the function that /* @@@ Given an address, return the entry point of the function that
contains it. */ contains it. */
extern void * _Unwind_FindEnclosingFunction (void *pc); extern void * _Unwind_FindEnclosingFunction (
#if ! (defined (__e2k__) && defined (__ptr128__))
void *pc
#else /* defined (__e2k__) && defined (__ptr128__) */
_Unwind_Ptr pc
#endif /* defined (__e2k__) && defined (__ptr128__) */
);
#ifndef __SIZEOF_LONG__ #ifndef __SIZEOF_LONG__
#error "__SIZEOF_LONG__ macro not defined" #error "__SIZEOF_LONG__ macro not defined"
@ -269,6 +293,9 @@ extern void * _Unwind_FindEnclosingFunction (void *pc);
#elif __SIZEOF_LONG_LONG__ >= __SIZEOF_POINTER__ #elif __SIZEOF_LONG_LONG__ >= __SIZEOF_POINTER__
typedef long long _sleb128_t; typedef long long _sleb128_t;
typedef unsigned long long _uleb128_t; typedef unsigned long long _uleb128_t;
#elif defined (__e2k__) && defined (__ptr128__)
typedef long _sleb128_t;
typedef unsigned long _uleb128_t;
#else #else
# error "What type shall we use for _sleb128_t?" # error "What type shall we use for _sleb128_t?"
#endif #endif

View File

@ -71,6 +71,11 @@ size_of_encoded_value (unsigned char encoding) __attribute__ ((unused));
static unsigned int static unsigned int
size_of_encoded_value (unsigned char encoding) size_of_encoded_value (unsigned char encoding)
{ {
#if defined (__e2k__) && defined (__ptr128__)
if (encoding == DW_EH_PE_aligned)
return 16;
#endif /* defined (__e2k__) && defined (__ptr128__) */
if (encoding == DW_EH_PE_omit) if (encoding == DW_EH_PE_omit)
return 0; return 0;
@ -179,11 +184,19 @@ read_sleb128 (const unsigned char *p, _sleb128_t *val)
static const unsigned char * static const unsigned char *
read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base, read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base,
const unsigned char *p, _Unwind_Ptr *val) const unsigned char *p, _Unwind_Ptr *val
#if defined (__e2k__) && defined (__ptr128__)
, void **pval
#endif /* defined (__e2k__) && defined (__ptr128__) */
)
{ {
union unaligned union unaligned
{ {
#if ! (defined (__e2k__) && defined (__ptr128__))
void *ptr; void *ptr;
#else /* (defined (__e2k__) && defined (__ptr128__) */
_Unwind_Ptr ptr;
#endif /* (defined (__e2k__) && defined (__ptr128__) */
unsigned u2 __attribute__ ((mode (HI))); unsigned u2 __attribute__ ((mode (HI)));
unsigned u4 __attribute__ ((mode (SI))); unsigned u4 __attribute__ ((mode (SI)));
unsigned u8 __attribute__ ((mode (DI))); unsigned u8 __attribute__ ((mode (DI)));
@ -199,8 +212,17 @@ read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base,
{ {
_Unwind_Internal_Ptr a = (_Unwind_Internal_Ptr) p; _Unwind_Internal_Ptr a = (_Unwind_Internal_Ptr) p;
a = (a + sizeof (void *) - 1) & - sizeof(void *); a = (a + sizeof (void *) - 1) & - sizeof(void *);
#if ! (defined (__e2k__) && defined (__ptr128__))
result = *(_Unwind_Internal_Ptr *) a; result = *(_Unwind_Internal_Ptr *) a;
p = (const unsigned char *) (_Unwind_Internal_Ptr) (a + sizeof (void *)); p = (const unsigned char *) (_Unwind_Internal_Ptr) (a + sizeof (void *));
#else /* defined (__e2k__) && defined (__ptr128__) */
/* Do without conversion of an integer into a pointer when calculating an
aligned pointer in PM. */
p += a - (_Unwind_Internal_Ptr) p;
result = *(_Unwind_Internal_Ptr *) (void *) p;
*pval = *(void **) (void *) p;
p += sizeof (void *);
#endif /* defined (__e2k__) && defined (__ptr128__) */
} }
else else
{ {
@ -208,7 +230,11 @@ read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base,
{ {
case DW_EH_PE_absptr: case DW_EH_PE_absptr:
result = (_Unwind_Internal_Ptr) u->ptr; result = (_Unwind_Internal_Ptr) u->ptr;
#if ! (defined (__e2k__) && defined (__ptr128__))
p += sizeof (void *); p += sizeof (void *);
#else /* defined (__e2k__) && defined (__ptr128__) */
p += sizeof (_Unwind_Ptr);
#endif /* defined (__e2k__) && defined (__ptr128__) */
break; break;
case DW_EH_PE_uleb128: case DW_EH_PE_uleb128:
@ -261,15 +287,56 @@ read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base,
{ {
result += ((encoding & 0x70) == DW_EH_PE_pcrel result += ((encoding & 0x70) == DW_EH_PE_pcrel
? (_Unwind_Internal_Ptr) u : base); ? (_Unwind_Internal_Ptr) u : base);
#if defined (__e2k__) && defined (__ptr128__)
/* In Protected Mode U belongs to the data segment, while PC,
being evaluated by means of DW_EH_PE_pcrel, to the text one.
BASE takes into account the difference between the bases of
these segments. */
if ((encoding & 0x70) == DW_EH_PE_pcrel)
result += base;
#endif /* defined (__e2k__) && defined (__ptr128__) */
if (encoding & DW_EH_PE_indirect) if (encoding & DW_EH_PE_indirect)
result = *(_Unwind_Internal_Ptr *) result; result = *(_Unwind_Internal_Ptr *) result;
} }
} }
#if defined (__e2k__) && defined (__ptr128__)
/* In PM VAL is of an inappropriate type for returning a pointer, which
is why the user may pass NULL for it. */
if (val)
#endif /* defined (__e2k__) && defined (__ptr128__) */
*val = result; *val = result;
return p; return p;
} }
#if defined (__e2k__) && defined (__ptr128__)
static const unsigned char *
read_encoded_ptr_with_base (unsigned char encoding, _Unwind_Ptr base,
const unsigned char *p, void **pval)
{
return read_encoded_value_with_base (encoding,
base, p, NULL, pval);
}
# ifndef NO_BASE_OF_ENCODED_VALUE
static inline const unsigned char *
read_encoded_ptr (struct _Unwind_Context *context, unsigned char encoding,
const unsigned char *p, void **pval)
{
return read_encoded_ptr_with_base (encoding,
base_of_encoded_value (encoding, context),
p, pval);
}
# endif /* ! defined NO_BASE_OF_ENCODED_VALUE */
# define read_encoded_value_with_base(a, b, c, d) \
read_encoded_value_with_base (a, b, c, d, NULL)
#endif /* defined (__e2k__) && defined (__ptr128__) */
#ifndef NO_BASE_OF_ENCODED_VALUE #ifndef NO_BASE_OF_ENCODED_VALUE
/* Like read_encoded_value_with_base, but get the base from the context /* Like read_encoded_value_with_base, but get the base from the context

View File

@ -83,9 +83,16 @@ _Unwind_RaiseException(struct _Unwind_Exception *exc)
{ {
struct _Unwind_Context this_context, cur_context; struct _Unwind_Context this_context, cur_context;
_Unwind_Reason_Code code; _Unwind_Reason_Code code;
#if defined __e2k__
e2k_mem_crs_t chain_stack[CHAIN_STACK_CACHE_LEN];
#endif /* defined __e2k__ */
/* Set up this_context to describe the current stack frame. */ /* Set up this_context to describe the current stack frame. */
uw_init_context (&this_context); uw_init_context (&this_context
#if defined __e2k__
, chain_stack
#endif /* defined __e2k__ */
);
cur_context = this_context; cur_context = this_context;
/* Phase 1: Search. Unwind the stack, calling the personality routine /* Phase 1: Search. Unwind the stack, calling the personality routine
@ -127,6 +134,13 @@ _Unwind_RaiseException(struct _Unwind_Exception *exc)
exc->private_1 = 0; exc->private_1 = 0;
exc->private_2 = uw_identify_context (&cur_context); exc->private_2 = uw_identify_context (&cur_context);
#if defined __e2k__
/* Now that the chain stack cache is shared between `{THIS,CUR}_CONTEXT' it
may have been changed while updating the latter above. Ensure that it
matches THIS_CONTEXT prior to starting phase 2. */
reinit_chain_stack_cache (&this_context);
#endif /* defined __e2k__ */
cur_context = this_context; cur_context = this_context;
code = _Unwind_RaiseException_Phase2 (exc, &cur_context); code = _Unwind_RaiseException_Phase2 (exc, &cur_context);
if (code != _URC_INSTALL_CONTEXT) if (code != _URC_INSTALL_CONTEXT)
@ -142,8 +156,13 @@ static _Unwind_Reason_Code
_Unwind_ForcedUnwind_Phase2 (struct _Unwind_Exception *exc, _Unwind_ForcedUnwind_Phase2 (struct _Unwind_Exception *exc,
struct _Unwind_Context *context) struct _Unwind_Context *context)
{ {
#if ! (defined (__e2k__) && defined (__ptr128__))
_Unwind_Stop_Fn stop = (_Unwind_Stop_Fn) (_Unwind_Ptr) exc->private_1; _Unwind_Stop_Fn stop = (_Unwind_Stop_Fn) (_Unwind_Ptr) exc->private_1;
void *stop_argument = (void *) (_Unwind_Ptr) exc->private_2; void *stop_argument = (void *) (_Unwind_Ptr) exc->private_2;
#else /* defined (__e2k__) && defined (__ptr128__) */
_Unwind_Stop_Fn stop = (_Unwind_Stop_Fn) exc->private_1;
void *stop_argument = exc->private_2;
#endif /* defined (__e2k__) && defined (__ptr128__) */
_Unwind_Reason_Code code, stop_code; _Unwind_Reason_Code code, stop_code;
while (1) while (1)
@ -197,12 +216,24 @@ _Unwind_ForcedUnwind (struct _Unwind_Exception *exc,
{ {
struct _Unwind_Context this_context, cur_context; struct _Unwind_Context this_context, cur_context;
_Unwind_Reason_Code code; _Unwind_Reason_Code code;
#if defined __e2k__
e2k_mem_crs_t chain_stack[CHAIN_STACK_CACHE_LEN];
#endif /* defined __e2k__ */
uw_init_context (&this_context); uw_init_context (&this_context
#if defined __e2k__
, chain_stack
#endif /* defined __e2k__ */
);
cur_context = this_context; cur_context = this_context;
#if ! (defined (__e2k__) && defined (__ptr128__))
exc->private_1 = (_Unwind_Ptr) stop; exc->private_1 = (_Unwind_Ptr) stop;
exc->private_2 = (_Unwind_Ptr) stop_argument; exc->private_2 = (_Unwind_Ptr) stop_argument;
#else /* defined (__e2k__) && defined (__ptr128__) */
exc->private_1 = (void *) stop;
exc->private_2 = stop_argument;
#endif /* defined (__e2k__) && defined (__ptr128__) */
code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context); code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context);
if (code != _URC_INSTALL_CONTEXT) if (code != _URC_INSTALL_CONTEXT)
@ -220,8 +251,16 @@ _Unwind_Resume (struct _Unwind_Exception *exc)
{ {
struct _Unwind_Context this_context, cur_context; struct _Unwind_Context this_context, cur_context;
_Unwind_Reason_Code code; _Unwind_Reason_Code code;
#if defined __e2k__
e2k_mem_crs_t chain_stack[CHAIN_STACK_CACHE_LEN];
#endif /* defined __e2k__ */
uw_init_context (&this_context);
uw_init_context (&this_context
#if defined __e2k__
, chain_stack
#endif /* defined __e2k__ */
);
cur_context = this_context; cur_context = this_context;
/* Choose between continuing to process _Unwind_RaiseException /* Choose between continuing to process _Unwind_RaiseException
@ -245,13 +284,20 @@ _Unwind_Resume_or_Rethrow (struct _Unwind_Exception *exc)
{ {
struct _Unwind_Context this_context, cur_context; struct _Unwind_Context this_context, cur_context;
_Unwind_Reason_Code code; _Unwind_Reason_Code code;
#if defined __e2k__
e2k_mem_crs_t chain_stack[CHAIN_STACK_CACHE_LEN];
#endif /* defined __e2k__ */
/* Choose between continuing to process _Unwind_RaiseException /* Choose between continuing to process _Unwind_RaiseException
or _Unwind_ForcedUnwind. */ or _Unwind_ForcedUnwind. */
if (exc->private_1 == 0) if (exc->private_1 == 0)
return _Unwind_RaiseException (exc); return _Unwind_RaiseException (exc);
uw_init_context (&this_context); uw_init_context (&this_context
#if defined __e2k__
, chain_stack
#endif /* defined __e2k__ */
);
cur_context = this_context; cur_context = this_context;
code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context); code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context);
@ -279,8 +325,15 @@ _Unwind_Backtrace(_Unwind_Trace_Fn trace, void * trace_argument)
{ {
struct _Unwind_Context context; struct _Unwind_Context context;
_Unwind_Reason_Code code; _Unwind_Reason_Code code;
#if defined __e2k__
e2k_mem_crs_t chain_stack[CHAIN_STACK_CACHE_LEN];
#endif /* defined __e2k__ */
uw_init_context (&context); uw_init_context (&context
#if defined __e2k__
, chain_stack
#endif /* defined __e2k__ */
);
while (1) while (1)
{ {

View File

@ -7669,7 +7669,7 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; }
*nto* | *qnx*) *nto* | *qnx*)
# QNX uses GNU C++, but need to define -shared option too, otherwise # QNX uses GNU C++, but need to define -shared option too, otherwise
# it will coredump. # it will coredump.
lt_prog_compiler_pic='-fPIC -shared' lt_prog_compiler_pic='-fPIC'
;; ;;
sysv4*MP*) sysv4*MP*)
@ -7796,7 +7796,7 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; }
*nto* | *qnx*) *nto* | *qnx*)
# QNX uses GNU C++, but need to define -shared option too, otherwise # QNX uses GNU C++, but need to define -shared option too, otherwise
# it will coredump. # it will coredump.
lt_prog_compiler_pic='-fPIC -shared' lt_prog_compiler_pic='-fPIC'
;; ;;
osf3* | osf4* | osf5*) osf3* | osf4* | osf5*)

View File

@ -122,6 +122,63 @@ static wchar_t *group_number (wchar_t *buf, wchar_t *bufend,
unsigned int intdig_no, const char *grouping, unsigned int intdig_no, const char *grouping,
wchar_t thousands_sep, int ngroups); wchar_t thousands_sep, int ngroups);
struct hack_digit_param
{
/* Sign of the exponent. */
int expsign;
/* The type of output format that will be used: 'e'/'E' or 'f'. */
int type;
/* and the exponent. */
int exponent;
/* The fraction of the floting-point value in question */
MPN_VAR(frac);
/* Scaling factor. */
MPN_VAR(scale);
/* Temporary bignum value. */
MPN_VAR(tmp);
};
static wchar_t
hack_digit (struct hack_digit_param *p)
{
mp_limb_t hi;
if (p->expsign != 0 && p->type == 'f' && p->exponent-- > 0)
hi = 0;
else if (p->scalesize == 0)
{
hi = p->frac[p->fracsize - 1];
p->frac[p->fracsize - 1] = mpn_mul_1 (p->frac, p->frac, p->fracsize - 1, 10);
}
else
{
if (p->fracsize < p->scalesize)
hi = 0;
else
{
hi = mpn_divmod (p->tmp, p->frac, p->fracsize, p->scale, p->scalesize);
p->tmp[p->fracsize - p->scalesize] = hi;
hi = p->tmp[0];
p->fracsize = p->scalesize;
while (p->fracsize != 0 && p->frac[p->fracsize - 1] == 0)
--p->fracsize;
if (p->fracsize == 0)
{
/* We're not prepared for an mpn variable with zero
limbs. */
p->fracsize = 1;
return L_('0') + hi;
}
}
mp_limb_t _cy = mpn_mul_1 (p->frac, p->frac, p->fracsize, 10);
if (_cy != 0)
p->frac[p->fracsize++] = _cy;
}
return L_('0') + hi;
}
int int
__quadmath_printf_fp (struct __quadmath_printf_file *fp, __quadmath_printf_fp (struct __quadmath_printf_file *fp,
@ -150,28 +207,14 @@ __quadmath_printf_fp (struct __quadmath_printf_file *fp,
/* We need to shift the contents of fp_input by this amount of bits. */ /* We need to shift the contents of fp_input by this amount of bits. */
int to_shift = 0; int to_shift = 0;
/* The fraction of the floting-point value in question */ struct hack_digit_param p;
MPN_VAR(frac);
/* and the exponent. */
int exponent;
/* Sign of the exponent. */
int expsign = 0;
/* Sign of float number. */ /* Sign of float number. */
int is_neg = 0; int is_neg = 0;
/* Scaling factor. */
MPN_VAR(scale);
/* Temporary bignum value. */
MPN_VAR(tmp);
/* Digit which is result of last hack_digit() call. */ /* Digit which is result of last hack_digit() call. */
wchar_t last_digit, next_digit; wchar_t last_digit, next_digit;
bool more_bits; bool more_bits;
/* The type of output format that will be used: 'e'/'E' or 'f'. */
int type;
/* Counter for number of written characters. */ /* Counter for number of written characters. */
int done = 0; int done = 0;
@ -186,48 +229,7 @@ __quadmath_printf_fp (struct __quadmath_printf_file *fp,
/* Flag whether wbuffer is malloc'ed or not. */ /* Flag whether wbuffer is malloc'ed or not. */
int buffer_malloced = 0; int buffer_malloced = 0;
auto wchar_t hack_digit (void); p.expsign = 0;
wchar_t hack_digit (void)
{
mp_limb_t hi;
if (expsign != 0 && type == 'f' && exponent-- > 0)
hi = 0;
else if (scalesize == 0)
{
hi = frac[fracsize - 1];
frac[fracsize - 1] = mpn_mul_1 (frac, frac, fracsize - 1, 10);
}
else
{
if (fracsize < scalesize)
hi = 0;
else
{
hi = mpn_divmod (tmp, frac, fracsize, scale, scalesize);
tmp[fracsize - scalesize] = hi;
hi = tmp[0];
fracsize = scalesize;
while (fracsize != 0 && frac[fracsize - 1] == 0)
--fracsize;
if (fracsize == 0)
{
/* We're not prepared for an mpn variable with zero
limbs. */
fracsize = 1;
return L_('0') + hi;
}
}
mp_limb_t _cy = mpn_mul_1 (frac, frac, fracsize, 10);
if (_cy != 0)
frac[fracsize++] = _cy;
}
return L_('0') + hi;
}
/* Figure out the decimal point character. */ /* Figure out the decimal point character. */
#ifdef USE_NL_LANGINFO #ifdef USE_NL_LANGINFO
@ -397,11 +399,11 @@ __quadmath_printf_fp (struct __quadmath_printf_file *fp,
} }
else else
{ {
fracsize = mpn_extract_flt128 (fp_input, p.fracsize = mpn_extract_flt128 (fp_input,
(sizeof (fp_input) / (sizeof (fp_input) /
sizeof (fp_input[0])), sizeof (fp_input[0])),
&exponent, &is_neg, fpnum); &p.exponent, &is_neg, fpnum);
to_shift = 1 + fracsize * BITS_PER_MP_LIMB - FLT128_MANT_DIG; to_shift = 1 + p.fracsize * BITS_PER_MP_LIMB - FLT128_MANT_DIG;
} }
} }
@ -437,20 +439,20 @@ __quadmath_printf_fp (struct __quadmath_printf_file *fp,
efficient to use variables of the fixed maximum size but because this efficient to use variables of the fixed maximum size but because this
would be really big it could lead to memory problems. */ would be really big it could lead to memory problems. */
{ {
mp_size_t bignum_size = ((ABS (exponent) + BITS_PER_MP_LIMB - 1) mp_size_t bignum_size = ((ABS (p.exponent) + BITS_PER_MP_LIMB - 1)
/ BITS_PER_MP_LIMB / BITS_PER_MP_LIMB
+ (FLT128_MANT_DIG / BITS_PER_MP_LIMB > 2 ? 8 : 4)) + (FLT128_MANT_DIG / BITS_PER_MP_LIMB > 2 ? 8 : 4))
* sizeof (mp_limb_t); * sizeof (mp_limb_t);
frac = (mp_limb_t *) alloca (bignum_size); p.frac = (mp_limb_t *) alloca (bignum_size);
tmp = (mp_limb_t *) alloca (bignum_size); p.tmp = (mp_limb_t *) alloca (bignum_size);
scale = (mp_limb_t *) alloca (bignum_size); p.scale = (mp_limb_t *) alloca (bignum_size);
} }
/* We now have to distinguish between numbers with positive and negative /* We now have to distinguish between numbers with positive and negative
exponents because the method used for the one is not applicable/efficient exponents because the method used for the one is not applicable/efficient
for the other. */ for the other. */
scalesize = 0; p.scalesize = 0;
if (exponent > 2) if (p.exponent > 2)
{ {
/* |FP| >= 8.0. */ /* |FP| >= 8.0. */
int scaleexpo = 0; int scaleexpo = 0;
@ -459,22 +461,22 @@ __quadmath_printf_fp (struct __quadmath_printf_file *fp,
const struct mp_power *powers = &_fpioconst_pow10[explog + 1]; const struct mp_power *powers = &_fpioconst_pow10[explog + 1];
int cnt_h, cnt_l, i; int cnt_h, cnt_l, i;
if ((exponent + to_shift) % BITS_PER_MP_LIMB == 0) if ((p.exponent + to_shift) % BITS_PER_MP_LIMB == 0)
{ {
MPN_COPY_DECR (frac + (exponent + to_shift) / BITS_PER_MP_LIMB, MPN_COPY_DECR (p.frac + (p.exponent + to_shift) / BITS_PER_MP_LIMB,
fp_input, fracsize); fp_input, p.fracsize);
fracsize += (exponent + to_shift) / BITS_PER_MP_LIMB; p.fracsize += (p.exponent + to_shift) / BITS_PER_MP_LIMB;
} }
else else
{ {
cy = mpn_lshift (frac + (exponent + to_shift) / BITS_PER_MP_LIMB, cy = mpn_lshift (p.frac + (p.exponent + to_shift) / BITS_PER_MP_LIMB,
fp_input, fracsize, fp_input, p.fracsize,
(exponent + to_shift) % BITS_PER_MP_LIMB); (p.exponent + to_shift) % BITS_PER_MP_LIMB);
fracsize += (exponent + to_shift) / BITS_PER_MP_LIMB; p.fracsize += (p.exponent + to_shift) / BITS_PER_MP_LIMB;
if (cy) if (cy)
frac[fracsize++] = cy; p.frac[p.fracsize++] = cy;
} }
MPN_ZERO (frac, (exponent + to_shift) / BITS_PER_MP_LIMB); MPN_ZERO (p.frac, (p.exponent + to_shift) / BITS_PER_MP_LIMB);
assert (powers > &_fpioconst_pow10[0]); assert (powers > &_fpioconst_pow10[0]);
do do
@ -483,9 +485,9 @@ __quadmath_printf_fp (struct __quadmath_printf_file *fp,
/* The number of the product of two binary numbers with n and m /* The number of the product of two binary numbers with n and m
bits respectively has m+n or m+n-1 bits. */ bits respectively has m+n or m+n-1 bits. */
if (exponent >= scaleexpo + powers->p_expo - 1) if (p.exponent >= scaleexpo + powers->p_expo - 1)
{ {
if (scalesize == 0) if (p.scalesize == 0)
{ {
if (FLT128_MANT_DIG > _FPIO_CONST_OFFSET * BITS_PER_MP_LIMB) if (FLT128_MANT_DIG > _FPIO_CONST_OFFSET * BITS_PER_MP_LIMB)
{ {
@ -494,60 +496,60 @@ __quadmath_printf_fp (struct __quadmath_printf_file *fp,
- _FPIO_CONST_OFFSET) - _FPIO_CONST_OFFSET)
/* 64bit const offset is not enough for /* 64bit const offset is not enough for
IEEE quad long double. */ IEEE quad long double. */
tmpsize = powers->arraysize + _FPIO_CONST_SHIFT; p.tmpsize = powers->arraysize + _FPIO_CONST_SHIFT;
memcpy (tmp + _FPIO_CONST_SHIFT, memcpy (p.tmp + _FPIO_CONST_SHIFT,
&__tens[powers->arrayoff], &__tens[powers->arrayoff],
tmpsize * sizeof (mp_limb_t)); p.tmpsize * sizeof (mp_limb_t));
MPN_ZERO (tmp, _FPIO_CONST_SHIFT); MPN_ZERO (p.tmp, _FPIO_CONST_SHIFT);
/* Adjust exponent, as scaleexpo will be this much /* Adjust exponent, as scaleexpo will be this much
bigger too. */ bigger too. */
exponent += _FPIO_CONST_SHIFT * BITS_PER_MP_LIMB; p.exponent += _FPIO_CONST_SHIFT * BITS_PER_MP_LIMB;
} }
else else
{ {
tmpsize = powers->arraysize; p.tmpsize = powers->arraysize;
memcpy (tmp, &__tens[powers->arrayoff], memcpy (p.tmp, &__tens[powers->arrayoff],
tmpsize * sizeof (mp_limb_t)); p.tmpsize * sizeof (mp_limb_t));
} }
} }
else else
{ {
cy = mpn_mul (tmp, scale, scalesize, cy = mpn_mul (p.tmp, p.scale, p.scalesize,
&__tens[powers->arrayoff &__tens[powers->arrayoff
+ _FPIO_CONST_OFFSET], + _FPIO_CONST_OFFSET],
powers->arraysize - _FPIO_CONST_OFFSET); powers->arraysize - _FPIO_CONST_OFFSET);
tmpsize = scalesize + powers->arraysize - _FPIO_CONST_OFFSET; p.tmpsize = p.scalesize + powers->arraysize - _FPIO_CONST_OFFSET;
if (cy == 0) if (cy == 0)
--tmpsize; --p.tmpsize;
} }
if (MPN_GE (frac, tmp)) if (MPN_GE (p.frac, p.tmp))
{ {
int cnt; int cnt;
MPN_ASSIGN (scale, tmp); MPN_ASSIGN (p.scale, p.tmp);
count_leading_zeros (cnt, scale[scalesize - 1]); count_leading_zeros (cnt, p.scale[p.scalesize - 1]);
scaleexpo = (scalesize - 2) * BITS_PER_MP_LIMB - cnt - 1; scaleexpo = (p.scalesize - 2) * BITS_PER_MP_LIMB - cnt - 1;
exp10 |= 1 << explog; exp10 |= 1 << explog;
} }
} }
--explog; --explog;
} }
while (powers > &_fpioconst_pow10[0]); while (powers > &_fpioconst_pow10[0]);
exponent = exp10; p.exponent = exp10;
/* Optimize number representations. We want to represent the numbers /* Optimize number representations. We want to represent the numbers
with the lowest number of bytes possible without losing any with the lowest number of bytes possible without losing any
bytes. Also the highest bit in the scaling factor has to be set bytes. Also the highest bit in the scaling factor has to be set
(this is a requirement of the MPN division routines). */ (this is a requirement of the MPN division routines). */
if (scalesize > 0) if (p.scalesize > 0)
{ {
/* Determine minimum number of zero bits at the end of /* Determine minimum number of zero bits at the end of
both numbers. */ both numbers. */
for (i = 0; scale[i] == 0 && frac[i] == 0; i++) for (i = 0; p.scale[i] == 0 && p.frac[i] == 0; i++)
; ;
/* Determine number of bits the scaling factor is misplaced. */ /* Determine number of bits the scaling factor is misplaced. */
count_leading_zeros (cnt_h, scale[scalesize - 1]); count_leading_zeros (cnt_h, p.scale[p.scalesize - 1]);
if (cnt_h == 0) if (cnt_h == 0)
{ {
@ -555,27 +557,27 @@ __quadmath_printf_fp (struct __quadmath_printf_file *fp,
we only have to remove the trailing empty limbs. */ we only have to remove the trailing empty limbs. */
if (i > 0) if (i > 0)
{ {
MPN_COPY_INCR (scale, scale + i, scalesize - i); MPN_COPY_INCR (p.scale, p.scale + i, p.scalesize - i);
scalesize -= i; p.scalesize -= i;
MPN_COPY_INCR (frac, frac + i, fracsize - i); MPN_COPY_INCR (p.frac, p.frac + i, p.fracsize - i);
fracsize -= i; p.fracsize -= i;
} }
} }
else else
{ {
if (scale[i] != 0) if (p.scale[i] != 0)
{ {
count_trailing_zeros (cnt_l, scale[i]); count_trailing_zeros (cnt_l, p.scale[i]);
if (frac[i] != 0) if (p.frac[i] != 0)
{ {
int cnt_l2; int cnt_l2;
count_trailing_zeros (cnt_l2, frac[i]); count_trailing_zeros (cnt_l2, p.frac[i]);
if (cnt_l2 < cnt_l) if (cnt_l2 < cnt_l)
cnt_l = cnt_l2; cnt_l = cnt_l2;
} }
} }
else else
count_trailing_zeros (cnt_l, frac[i]); count_trailing_zeros (cnt_l, p.frac[i]);
/* Now shift the numbers to their optimal position. */ /* Now shift the numbers to their optimal position. */
if (i == 0 && BITS_PER_MP_LIMB - cnt_h > cnt_l) if (i == 0 && BITS_PER_MP_LIMB - cnt_h > cnt_l)
@ -583,10 +585,10 @@ __quadmath_printf_fp (struct __quadmath_printf_file *fp,
/* We cannot save any memory. So just roll both numbers /* We cannot save any memory. So just roll both numbers
so that the scaling factor has its highest bit set. */ so that the scaling factor has its highest bit set. */
(void) mpn_lshift (scale, scale, scalesize, cnt_h); (void) mpn_lshift (p.scale, p.scale, p.scalesize, cnt_h);
cy = mpn_lshift (frac, frac, fracsize, cnt_h); cy = mpn_lshift (p.frac, p.frac, p.fracsize, cnt_h);
if (cy != 0) if (cy != 0)
frac[fracsize++] = cy; p.frac[p.fracsize++] = cy;
} }
else if (BITS_PER_MP_LIMB - cnt_h <= cnt_l) else if (BITS_PER_MP_LIMB - cnt_h <= cnt_l)
{ {
@ -594,31 +596,31 @@ __quadmath_printf_fp (struct __quadmath_printf_file *fp,
and by packing the non-zero limbs which gain another and by packing the non-zero limbs which gain another
free one. */ free one. */
(void) mpn_rshift (scale, scale + i, scalesize - i, (void) mpn_rshift (p.scale, p.scale + i, p.scalesize - i,
BITS_PER_MP_LIMB - cnt_h); BITS_PER_MP_LIMB - cnt_h);
scalesize -= i + 1; p.scalesize -= i + 1;
(void) mpn_rshift (frac, frac + i, fracsize - i, (void) mpn_rshift (p.frac, p.frac + i, p.fracsize - i,
BITS_PER_MP_LIMB - cnt_h); BITS_PER_MP_LIMB - cnt_h);
fracsize -= frac[fracsize - i - 1] == 0 ? i + 1 : i; p.fracsize -= p.frac[p.fracsize - i - 1] == 0 ? i + 1 : i;
} }
else else
{ {
/* We can only save the memory of the limbs which are zero. /* We can only save the memory of the limbs which are zero.
The non-zero parts occupy the same number of limbs. */ The non-zero parts occupy the same number of limbs. */
(void) mpn_rshift (scale, scale + (i - 1), (void) mpn_rshift (p.scale, p.scale + (i - 1),
scalesize - (i - 1), p.scalesize - (i - 1),
BITS_PER_MP_LIMB - cnt_h); BITS_PER_MP_LIMB - cnt_h);
scalesize -= i; p.scalesize -= i;
(void) mpn_rshift (frac, frac + (i - 1), (void) mpn_rshift (p.frac, p.frac + (i - 1),
fracsize - (i - 1), p.fracsize - (i - 1),
BITS_PER_MP_LIMB - cnt_h); BITS_PER_MP_LIMB - cnt_h);
fracsize -= frac[fracsize - (i - 1) - 1] == 0 ? i : i - 1; p.fracsize -= p.frac[p.fracsize - (i - 1) - 1] == 0 ? i : i - 1;
} }
} }
} }
} }
else if (exponent < 0) else if (p.exponent < 0)
{ {
/* |FP| < 1.0. */ /* |FP| < 1.0. */
int exp10 = 0; int exp10 = 0;
@ -626,40 +628,40 @@ __quadmath_printf_fp (struct __quadmath_printf_file *fp,
const struct mp_power *powers = &_fpioconst_pow10[explog + 1]; const struct mp_power *powers = &_fpioconst_pow10[explog + 1];
/* Now shift the input value to its right place. */ /* Now shift the input value to its right place. */
cy = mpn_lshift (frac, fp_input, fracsize, to_shift); cy = mpn_lshift (p.frac, fp_input, p.fracsize, to_shift);
frac[fracsize++] = cy; p.frac[p.fracsize++] = cy;
assert (cy == 1 || (frac[fracsize - 2] == 0 && frac[0] == 0)); assert (cy == 1 || (p.frac[p.fracsize - 2] == 0 && p.frac[0] == 0));
expsign = 1; p.expsign = 1;
exponent = -exponent; p.exponent = -p.exponent;
assert (powers != &_fpioconst_pow10[0]); assert (powers != &_fpioconst_pow10[0]);
do do
{ {
--powers; --powers;
if (exponent >= powers->m_expo) if (p.exponent >= powers->m_expo)
{ {
int i, incr, cnt_h, cnt_l; int i, incr, cnt_h, cnt_l;
mp_limb_t topval[2]; mp_limb_t topval[2];
/* The mpn_mul function expects the first argument to be /* The mpn_mul function expects the first argument to be
bigger than the second. */ bigger than the second. */
if (fracsize < powers->arraysize - _FPIO_CONST_OFFSET) if (p.fracsize < powers->arraysize - _FPIO_CONST_OFFSET)
cy = mpn_mul (tmp, &__tens[powers->arrayoff cy = mpn_mul (p.tmp, &__tens[powers->arrayoff
+ _FPIO_CONST_OFFSET], + _FPIO_CONST_OFFSET],
powers->arraysize - _FPIO_CONST_OFFSET, powers->arraysize - _FPIO_CONST_OFFSET,
frac, fracsize); p.frac, p.fracsize);
else else
cy = mpn_mul (tmp, frac, fracsize, cy = mpn_mul (p.tmp, p.frac, p.fracsize,
&__tens[powers->arrayoff + _FPIO_CONST_OFFSET], &__tens[powers->arrayoff + _FPIO_CONST_OFFSET],
powers->arraysize - _FPIO_CONST_OFFSET); powers->arraysize - _FPIO_CONST_OFFSET);
tmpsize = fracsize + powers->arraysize - _FPIO_CONST_OFFSET; p.tmpsize = p.fracsize + powers->arraysize - _FPIO_CONST_OFFSET;
if (cy == 0) if (cy == 0)
--tmpsize; --p.tmpsize;
count_leading_zeros (cnt_h, tmp[tmpsize - 1]); count_leading_zeros (cnt_h, p.tmp[p.tmpsize - 1]);
incr = (tmpsize - fracsize) * BITS_PER_MP_LIMB incr = (p.tmpsize - p.fracsize) * BITS_PER_MP_LIMB
+ BITS_PER_MP_LIMB - 1 - cnt_h; + BITS_PER_MP_LIMB - 1 - cnt_h;
assert (incr <= powers->p_expo); assert (incr <= powers->p_expo);
@ -667,7 +669,7 @@ __quadmath_printf_fp (struct __quadmath_printf_file *fp,
/* If we increased the exponent by exactly 3 we have to test /* If we increased the exponent by exactly 3 we have to test
for overflow. This is done by comparing with 10 shifted for overflow. This is done by comparing with 10 shifted
to the right position. */ to the right position. */
if (incr == exponent + 3) if (incr == p.exponent + 3)
{ {
if (cnt_h <= BITS_PER_MP_LIMB - 4) if (cnt_h <= BITS_PER_MP_LIMB - 4)
{ {
@ -689,32 +691,32 @@ __quadmath_printf_fp (struct __quadmath_printf_file *fp,
against 10.0. If it is greater or equal to 10.0 the against 10.0. If it is greater or equal to 10.0 the
multiplication was not valid. This is because we cannot multiplication was not valid. This is because we cannot
determine the number of bits in the result in advance. */ determine the number of bits in the result in advance. */
if (incr < exponent + 3 if (incr < p.exponent + 3
|| (incr == exponent + 3 && || (incr == p.exponent + 3 &&
(tmp[tmpsize - 1] < topval[1] (p.tmp[p.tmpsize - 1] < topval[1]
|| (tmp[tmpsize - 1] == topval[1] || (p.tmp[p.tmpsize - 1] == topval[1]
&& tmp[tmpsize - 2] < topval[0])))) && p.tmp[p.tmpsize - 2] < topval[0]))))
{ {
/* The factor is right. Adapt binary and decimal /* The factor is right. Adapt binary and decimal
exponents. */ exponents. */
exponent -= incr; p.exponent -= incr;
exp10 |= 1 << explog; exp10 |= 1 << explog;
/* If this factor yields a number greater or equal to /* If this factor yields a number greater or equal to
1.0, we must not shift the non-fractional digits down. */ 1.0, we must not shift the non-fractional digits down. */
if (exponent < 0) if (p.exponent < 0)
cnt_h += -exponent; cnt_h += -p.exponent;
/* Now we optimize the number representation. */ /* Now we optimize the number representation. */
for (i = 0; tmp[i] == 0; ++i); for (i = 0; p.tmp[i] == 0; ++i);
if (cnt_h == BITS_PER_MP_LIMB - 1) if (cnt_h == BITS_PER_MP_LIMB - 1)
{ {
MPN_COPY (frac, tmp + i, tmpsize - i); MPN_COPY (p.frac, p.tmp + i, p.tmpsize - i);
fracsize = tmpsize - i; p.fracsize = p.tmpsize - i;
} }
else else
{ {
count_trailing_zeros (cnt_l, tmp[i]); count_trailing_zeros (cnt_l, p.tmp[i]);
/* Now shift the numbers to their optimal position. */ /* Now shift the numbers to their optimal position. */
if (i == 0 && BITS_PER_MP_LIMB - 1 - cnt_h > cnt_l) if (i == 0 && BITS_PER_MP_LIMB - 1 - cnt_h > cnt_l)
@ -723,15 +725,15 @@ __quadmath_printf_fp (struct __quadmath_printf_file *fp,
number so that the leading digit is in a number so that the leading digit is in a
separate limb. */ separate limb. */
cy = mpn_lshift (frac, tmp, tmpsize, cnt_h + 1); cy = mpn_lshift (p.frac, p.tmp, p.tmpsize, cnt_h + 1);
fracsize = tmpsize + 1; p.fracsize = p.tmpsize + 1;
frac[fracsize - 1] = cy; p.frac[p.fracsize - 1] = cy;
} }
else if (BITS_PER_MP_LIMB - 1 - cnt_h <= cnt_l) else if (BITS_PER_MP_LIMB - 1 - cnt_h <= cnt_l)
{ {
(void) mpn_rshift (frac, tmp + i, tmpsize - i, (void) mpn_rshift (p.frac, p.tmp + i, p.tmpsize - i,
BITS_PER_MP_LIMB - 1 - cnt_h); BITS_PER_MP_LIMB - 1 - cnt_h);
fracsize = tmpsize - i; p.fracsize = p.tmpsize - i;
} }
else else
{ {
@ -739,41 +741,41 @@ __quadmath_printf_fp (struct __quadmath_printf_file *fp,
are zero. The non-zero parts occupy the same are zero. The non-zero parts occupy the same
number of limbs. */ number of limbs. */
(void) mpn_rshift (frac, tmp + (i - 1), (void) mpn_rshift (p.frac, p.tmp + (i - 1),
tmpsize - (i - 1), p.tmpsize - (i - 1),
BITS_PER_MP_LIMB - 1 - cnt_h); BITS_PER_MP_LIMB - 1 - cnt_h);
fracsize = tmpsize - (i - 1); p.fracsize = p.tmpsize - (i - 1);
} }
} }
} }
} }
--explog; --explog;
} }
while (powers != &_fpioconst_pow10[1] && exponent > 0); while (powers != &_fpioconst_pow10[1] && p.exponent > 0);
/* All factors but 10^-1 are tested now. */ /* All factors but 10^-1 are tested now. */
if (exponent > 0) if (p.exponent > 0)
{ {
int cnt_l; int cnt_l;
cy = mpn_mul_1 (tmp, frac, fracsize, 10); cy = mpn_mul_1 (p.tmp, p.frac, p.fracsize, 10);
tmpsize = fracsize; p.tmpsize = p.fracsize;
assert (cy == 0 || tmp[tmpsize - 1] < 20); assert (cy == 0 || p.tmp[p.tmpsize - 1] < 20);
count_trailing_zeros (cnt_l, tmp[0]); count_trailing_zeros (cnt_l, p.tmp[0]);
if (cnt_l < MIN (4, exponent)) if (cnt_l < MIN (4, p.exponent))
{ {
cy = mpn_lshift (frac, tmp, tmpsize, cy = mpn_lshift (p.frac, p.tmp, p.tmpsize,
BITS_PER_MP_LIMB - MIN (4, exponent)); BITS_PER_MP_LIMB - MIN (4, p.exponent));
if (cy != 0) if (cy != 0)
frac[tmpsize++] = cy; p.frac[p.tmpsize++] = cy;
} }
else else
(void) mpn_rshift (frac, tmp, tmpsize, MIN (4, exponent)); (void) mpn_rshift (p.frac, p.tmp, p.tmpsize, MIN (4, p.exponent));
fracsize = tmpsize; p.fracsize = p.tmpsize;
exp10 |= 1; exp10 |= 1;
assert (frac[fracsize - 1] < 10); assert (p.frac[p.fracsize - 1] < 10);
} }
exponent = exp10; p.exponent = exp10;
} }
else else
{ {
@ -781,13 +783,13 @@ __quadmath_printf_fp (struct __quadmath_printf_file *fp,
numbers are in the range of 1.0 <= |fp| < 8.0. We simply numbers are in the range of 1.0 <= |fp| < 8.0. We simply
shift it to the right place and divide it by 1.0 to get the shift it to the right place and divide it by 1.0 to get the
leading digit. (Of course this division is not really made.) */ leading digit. (Of course this division is not really made.) */
assert (0 <= exponent && exponent < 3 && assert (0 <= p.exponent && p.exponent < 3 &&
exponent + to_shift < BITS_PER_MP_LIMB); p.exponent + to_shift < BITS_PER_MP_LIMB);
/* Now shift the input value to its right place. */ /* Now shift the input value to its right place. */
cy = mpn_lshift (frac, fp_input, fracsize, (exponent + to_shift)); cy = mpn_lshift (p.frac, fp_input, p.fracsize, (p.exponent + to_shift));
frac[fracsize++] = cy; p.frac[p.fracsize++] = cy;
exponent = 0; p.exponent = 0;
} }
{ {
@ -805,7 +807,7 @@ __quadmath_printf_fp (struct __quadmath_printf_file *fp,
if (spec == 'e') if (spec == 'e')
{ {
type = info->spec; p.type = info->spec;
intdig_max = 1; intdig_max = 1;
fracdig_min = fracdig_max = info->prec < 0 ? 6 : info->prec; fracdig_min = fracdig_max = info->prec < 0 ? 6 : info->prec;
chars_needed = 1 + 1 + (size_t) fracdig_max + 1 + 1 + 4; chars_needed = 1 + 1 + (size_t) fracdig_max + 1 + 1 + 4;
@ -815,15 +817,15 @@ __quadmath_printf_fp (struct __quadmath_printf_file *fp,
} }
else if (spec == 'f') else if (spec == 'f')
{ {
type = 'f'; p.type = 'f';
fracdig_min = fracdig_max = info->prec < 0 ? 6 : info->prec; fracdig_min = fracdig_max = info->prec < 0 ? 6 : info->prec;
dig_max = __INT_MAX__; /* Unlimited. */ dig_max = __INT_MAX__; /* Unlimited. */
significant = 1; /* Does not matter here. */ significant = 1; /* Does not matter here. */
if (expsign == 0) if (p.expsign == 0)
{ {
intdig_max = exponent + 1; intdig_max = p.exponent + 1;
/* This can be really big! */ /* XXX Maybe malloc if too big? */ /* This can be really big! */ /* XXX Maybe malloc if too big? */
chars_needed = (size_t) exponent + 1 + 1 + (size_t) fracdig_max; chars_needed = (size_t) p.exponent + 1 + 1 + (size_t) fracdig_max;
} }
else else
{ {
@ -834,21 +836,21 @@ __quadmath_printf_fp (struct __quadmath_printf_file *fp,
else else
{ {
dig_max = info->prec < 0 ? 6 : (info->prec == 0 ? 1 : info->prec); dig_max = info->prec < 0 ? 6 : (info->prec == 0 ? 1 : info->prec);
if ((expsign == 0 && exponent >= dig_max) if ((p.expsign == 0 && p.exponent >= dig_max)
|| (expsign != 0 && exponent > 4)) || (p.expsign != 0 && p.exponent > 4))
{ {
if ('g' - 'G' == 'e' - 'E') if ('g' - 'G' == 'e' - 'E')
type = 'E' + (info->spec - 'G'); p.type = 'E' + (info->spec - 'G');
else else
type = isupper (info->spec) ? 'E' : 'e'; p.type = isupper (info->spec) ? 'E' : 'e';
fracdig_max = dig_max - 1; fracdig_max = dig_max - 1;
intdig_max = 1; intdig_max = 1;
chars_needed = 1 + 1 + (size_t) fracdig_max + 1 + 1 + 4; chars_needed = 1 + 1 + (size_t) fracdig_max + 1 + 1 + 4;
} }
else else
{ {
type = 'f'; p.type = 'f';
intdig_max = expsign == 0 ? exponent + 1 : 0; intdig_max = p.expsign == 0 ? p.exponent + 1 : 0;
fracdig_max = dig_max - intdig_max; fracdig_max = dig_max - intdig_max;
/* We need space for the significant digits and perhaps /* We need space for the significant digits and perhaps
for leading zeros when < 1.0. The number of leading for leading zeros when < 1.0. The number of leading
@ -898,18 +900,18 @@ __quadmath_printf_fp (struct __quadmath_printf_file *fp,
wcp = wstartp = wbuffer + 2; /* Let room for rounding. */ wcp = wstartp = wbuffer + 2; /* Let room for rounding. */
/* Do the real work: put digits in allocated buffer. */ /* Do the real work: put digits in allocated buffer. */
if (expsign == 0 || type != 'f') if (p.expsign == 0 || p.type != 'f')
{ {
assert (expsign == 0 || intdig_max == 1); assert (p.expsign == 0 || intdig_max == 1);
while (intdig_no < intdig_max) while (intdig_no < intdig_max)
{ {
++intdig_no; ++intdig_no;
*wcp++ = hack_digit (); *wcp++ = hack_digit (&p);
} }
significant = 1; significant = 1;
if (info->alt if (info->alt
|| fracdig_min > 0 || fracdig_min > 0
|| (fracdig_max > 0 && (fracsize > 1 || frac[0] != 0))) || (fracdig_max > 0 && (p.fracsize > 1 || p.frac[0] != 0)))
*wcp++ = decimalwc; *wcp++ = decimalwc;
} }
else else
@ -917,7 +919,7 @@ __quadmath_printf_fp (struct __quadmath_printf_file *fp,
/* |fp| < 1.0 and the selected type is 'f', so put "0." /* |fp| < 1.0 and the selected type is 'f', so put "0."
in the buffer. */ in the buffer. */
*wcp++ = L_('0'); *wcp++ = L_('0');
--exponent; --p.exponent;
*wcp++ = decimalwc; *wcp++ = decimalwc;
} }
@ -925,10 +927,10 @@ __quadmath_printf_fp (struct __quadmath_printf_file *fp,
int fracdig_no = 0; int fracdig_no = 0;
int added_zeros = 0; int added_zeros = 0;
while (fracdig_no < fracdig_min + added_zeros while (fracdig_no < fracdig_min + added_zeros
|| (fracdig_no < fracdig_max && (fracsize > 1 || frac[0] != 0))) || (fracdig_no < fracdig_max && (p.fracsize > 1 || p.frac[0] != 0)))
{ {
++fracdig_no; ++fracdig_no;
*wcp = hack_digit (); *wcp = hack_digit (&p);
if (*wcp++ != L_('0')) if (*wcp++ != L_('0'))
significant = 1; significant = 1;
else if (significant == 0) else if (significant == 0)
@ -941,19 +943,19 @@ __quadmath_printf_fp (struct __quadmath_printf_file *fp,
/* Do rounding. */ /* Do rounding. */
last_digit = wcp[-1] != decimalwc ? wcp[-1] : wcp[-2]; last_digit = wcp[-1] != decimalwc ? wcp[-1] : wcp[-2];
next_digit =hack_digit (); next_digit =hack_digit (&p);
if (next_digit != L_('0') && next_digit != L_('5')) if (next_digit != L_('0') && next_digit != L_('5'))
more_bits = true; more_bits = true;
else if (fracsize == 1 && frac[0] == 0) else if (p.fracsize == 1 && p.frac[0] == 0)
/* Rest of the number is zero. */ /* Rest of the number is zero. */
more_bits = false; more_bits = false;
else if (scalesize == 0) else if (p.scalesize == 0)
{ {
/* Here we have to see whether all limbs are zero since no /* Here we have to see whether all limbs are zero since no
normalization happened. */ normalization happened. */
size_t lcnt = fracsize; size_t lcnt = p.fracsize;
while (lcnt >= 1 && frac[lcnt - 1] == 0) while (lcnt >= 1 && p.frac[lcnt - 1] == 0)
--lcnt; --lcnt;
more_bits = lcnt > 0; more_bits = lcnt > 0;
} }
@ -982,7 +984,7 @@ __quadmath_printf_fp (struct __quadmath_printf_file *fp,
if (*wtp != decimalwc) if (*wtp != decimalwc)
/* Round up. */ /* Round up. */
(*wtp)++; (*wtp)++;
else if (__builtin_expect (spec == 'g' && type == 'f' && info->alt else if (__builtin_expect (spec == 'g' && p.type == 'f' && info->alt
&& wtp == wstartp + 1 && wtp == wstartp + 1
&& wstartp[0] == L_('0'), && wstartp[0] == L_('0'),
0)) 0))
@ -1007,16 +1009,16 @@ __quadmath_printf_fp (struct __quadmath_printf_file *fp,
else else
/* It is more critical. All digits were 9's. */ /* It is more critical. All digits were 9's. */
{ {
if (type != 'f') if (p.type != 'f')
{ {
*wstartp = '1'; *wstartp = '1';
exponent += expsign == 0 ? 1 : -1; p.exponent += p.expsign == 0 ? 1 : -1;
/* The above exponent adjustment could lead to 1.0e-00, /* The above exponent adjustment could lead to 1.0e-00,
e.g. for 0.999999999. Make sure exponent 0 always e.g. for 0.999999999. Make sure exponent 0 always
uses + sign. */ uses + sign. */
if (exponent == 0) if (p.exponent == 0)
expsign = 0; p.expsign = 0;
} }
else if (intdig_no == dig_max) else if (intdig_no == dig_max)
{ {
@ -1036,9 +1038,9 @@ __quadmath_printf_fp (struct __quadmath_printf_file *fp,
fracdig_no += intdig_no; fracdig_no += intdig_no;
intdig_no = 1; intdig_no = 1;
fracdig_max = intdig_max - intdig_no; fracdig_max = intdig_max - intdig_no;
++exponent; ++p.exponent;
/* Now we must print the exponent. */ /* Now we must print the exponent. */
type = isupper (info->spec) ? 'E' : 'e'; p.type = isupper (info->spec) ? 'E' : 'e';
} }
else else
{ {
@ -1085,9 +1087,9 @@ __quadmath_printf_fp (struct __quadmath_printf_file *fp,
} }
/* Write the exponent if it is needed. */ /* Write the exponent if it is needed. */
if (type != 'f') if (p.type != 'f')
{ {
if (__builtin_expect (expsign != 0 && exponent == 4 && spec == 'g', 0)) if (__builtin_expect (p.expsign != 0 && p.exponent == 4 && spec == 'g', 0))
{ {
/* This is another special case. The exponent of the number is /* This is another special case. The exponent of the number is
really smaller than -4, which requires the 'e'/'E' format. really smaller than -4, which requires the 'e'/'E' format.
@ -1108,26 +1110,26 @@ __quadmath_printf_fp (struct __quadmath_printf_file *fp,
} }
else else
{ {
*wcp++ = (wchar_t) type; *wcp++ = (wchar_t) p.type;
*wcp++ = expsign ? L_('-') : L_('+'); *wcp++ = p.expsign ? L_('-') : L_('+');
/* Find the magnitude of the exponent. */ /* Find the magnitude of the exponent. */
expscale = 10; expscale = 10;
while (expscale <= exponent) while (expscale <= p.exponent)
expscale *= 10; expscale *= 10;
if (exponent < 10) if (p.exponent < 10)
/* Exponent always has at least two digits. */ /* Exponent always has at least two digits. */
*wcp++ = L_('0'); *wcp++ = L_('0');
else else
do do
{ {
expscale /= 10; expscale /= 10;
*wcp++ = L_('0') + (exponent / expscale); *wcp++ = L_('0') + (p.exponent / expscale);
exponent %= expscale; p.exponent %= expscale;
} }
while (expscale > 10); while (expscale > 10);
*wcp++ = L_('0') + exponent; *wcp++ = L_('0') + p.exponent;
} }
} }

8
libtool.m4 vendored
View File

@ -3653,7 +3653,7 @@ m4_if([$1], [CXX], [
*qnx* | *nto*) *qnx* | *nto*)
# QNX uses GNU C++, but need to define -shared option too, otherwise # QNX uses GNU C++, but need to define -shared option too, otherwise
# it will coredump. # it will coredump.
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
;; ;;
*) *)
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
@ -3803,7 +3803,7 @@ m4_if([$1], [CXX], [
*qnx* | *nto*) *qnx* | *nto*)
# QNX uses GNU C++, but need to define -shared option too, otherwise # QNX uses GNU C++, but need to define -shared option too, otherwise
# it will coredump. # it will coredump.
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
;; ;;
osf3* | osf4* | osf5*) osf3* | osf4* | osf5*)
case $cc_basename in case $cc_basename in
@ -3970,7 +3970,7 @@ m4_if([$1], [CXX], [
*nto* | *qnx*) *nto* | *qnx*)
# QNX uses GNU C++, but need to define -shared option too, otherwise # QNX uses GNU C++, but need to define -shared option too, otherwise
# it will coredump. # it will coredump.
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
;; ;;
sysv4*MP*) sysv4*MP*)
@ -4098,7 +4098,7 @@ m4_if([$1], [CXX], [
*nto* | *qnx*) *nto* | *qnx*)
# QNX uses GNU C++, but need to define -shared option too, otherwise # QNX uses GNU C++, but need to define -shared option too, otherwise
# it will coredump. # it will coredump.
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
;; ;;
osf3* | osf4* | osf5*) osf3* | osf4* | osf5*)