mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-26 13:10:22 +02:00
Remove unneeded bits of lightning
This commit is contained in:
parent
9c1b01fba5
commit
90ebba864a
7 changed files with 0 additions and 1872 deletions
415
jit/disasm.c
415
jit/disasm.c
|
@ -1,415 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2012-2018 Free Software Foundation, Inc.
|
|
||||||
*
|
|
||||||
* This file is part of GNU lightning.
|
|
||||||
*
|
|
||||||
* GNU lightning is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU Lesser General Public License as published
|
|
||||||
* by the Free Software Foundation; either version 3, or (at your option)
|
|
||||||
* any later version.
|
|
||||||
*
|
|
||||||
* GNU lightning 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 Lesser General Public
|
|
||||||
* License for more details.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Paulo Cesar Pereira de Andrade
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "jit.h"
|
|
||||||
#include "jit/jit_private.h"
|
|
||||||
#if DISASSEMBLER
|
|
||||||
# include <dis-asm.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Prototypes
|
|
||||||
*/
|
|
||||||
#if DISASSEMBLER
|
|
||||||
static int
|
|
||||||
disasm_compare_symbols(const void *ap, const void *bp);
|
|
||||||
|
|
||||||
static void
|
|
||||||
disasm_print_address(bfd_vma addr, struct disassemble_info *info);
|
|
||||||
|
|
||||||
#define disassemble(u, v) _disassemble(_jit, u, v)
|
|
||||||
static void
|
|
||||||
_disassemble(jit_state_t *_jit, jit_pointer_t code, jit_int32_t length);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialization
|
|
||||||
*/
|
|
||||||
#if DISASSEMBLER
|
|
||||||
static bfd *disasm_bfd;
|
|
||||||
static disassemble_info disasm_info;
|
|
||||||
static disassembler_ftype disasm_print;
|
|
||||||
static asymbol **disasm_symbols;
|
|
||||||
static asymbol *disasm_synthetic;
|
|
||||||
static long disasm_num_symbols;
|
|
||||||
static long disasm_num_synthetic;
|
|
||||||
static jit_state_t *disasm_jit;
|
|
||||||
#define disasm_stream stdout
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Implementation
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
jit_init_debug(const char *progname)
|
|
||||||
{
|
|
||||||
#if DISASSEMBLER
|
|
||||||
bfd_init();
|
|
||||||
|
|
||||||
if (progname)
|
|
||||||
disasm_bfd = bfd_openr(progname, NULL);
|
|
||||||
if (disasm_bfd == NULL) {
|
|
||||||
#if defined(__linux__)
|
|
||||||
disasm_bfd = bfd_openr("/proc/self/exe", NULL);
|
|
||||||
if (disasm_bfd == NULL)
|
|
||||||
#endif
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
bfd_check_format(disasm_bfd, bfd_object);
|
|
||||||
bfd_check_format(disasm_bfd, bfd_archive);
|
|
||||||
INIT_DISASSEMBLE_INFO(disasm_info, disasm_stream, fprintf);
|
|
||||||
# if defined(__i386__) || defined(__x86_64__)
|
|
||||||
disasm_info.arch = bfd_arch_i386;
|
|
||||||
# if defined(__x86_64__)
|
|
||||||
# if __WORDSIZE == 32
|
|
||||||
disasm_info.mach = bfd_mach_x64_32;
|
|
||||||
# else
|
|
||||||
disasm_info.mach = bfd_mach_x86_64;
|
|
||||||
# endif
|
|
||||||
# else
|
|
||||||
disasm_info.mach = bfd_mach_i386_i386;
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
# if defined(__powerpc__)
|
|
||||||
disasm_info.arch = bfd_arch_powerpc;
|
|
||||||
disasm_info.mach = bfd_mach_ppc64;
|
|
||||||
# if HAVE_DISASSEMBLE_INIT_FOR_TARGET
|
|
||||||
disassemble_init_for_target(&disasm_info);
|
|
||||||
# elif HAVE_DISASSEMBLE_INIT_POWERPC
|
|
||||||
disassemble_init_powerpc(&disasm_info);
|
|
||||||
# endif
|
|
||||||
# if defined(__powerpc64__)
|
|
||||||
disasm_info.disassembler_options = "64";
|
|
||||||
# endif
|
|
||||||
# if HAVE_DISASSEMBLE_INIT_FOR_TARGET
|
|
||||||
disassemble_init_for_target(&disasm_info);
|
|
||||||
# elif HAVE_DISASSEMBLE_INIT_POWERPC
|
|
||||||
disassemble_init_powerpc(&disasm_info);
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
# if defined(__sparc__)
|
|
||||||
disasm_info.endian = disasm_info.display_endian = BFD_ENDIAN_BIG;
|
|
||||||
# endif
|
|
||||||
# if defined(__s390__) || defined(__s390x__)
|
|
||||||
disasm_info.arch = bfd_arch_s390;
|
|
||||||
# if __WORDSIZE == 32
|
|
||||||
disasm_info.mach = bfd_mach_s390_31;
|
|
||||||
# else
|
|
||||||
disasm_info.mach = bfd_mach_s390_64;
|
|
||||||
# endif
|
|
||||||
disasm_info.endian = disasm_info.display_endian = BFD_ENDIAN_BIG;
|
|
||||||
disasm_info.disassembler_options = "zarch";
|
|
||||||
# endif
|
|
||||||
# if defined(__alpha__)
|
|
||||||
disasm_info.arch = bfd_arch_alpha;
|
|
||||||
disasm_info.mach = bfd_mach_alpha_ev6;
|
|
||||||
# endif
|
|
||||||
disasm_info.print_address_func = disasm_print_address;
|
|
||||||
|
|
||||||
# if BINUTILS_2_29
|
|
||||||
disasm_print = disassembler(disasm_info.arch, __BYTE_ORDER == __BIG_ENDIAN,
|
|
||||||
disasm_info.mach, disasm_bfd);
|
|
||||||
# else
|
|
||||||
disasm_print = disassembler(disasm_bfd);
|
|
||||||
# endif
|
|
||||||
assert(disasm_print);
|
|
||||||
|
|
||||||
if (bfd_get_file_flags(disasm_bfd) & HAS_SYMS) {
|
|
||||||
asymbol **in;
|
|
||||||
asymbol **out;
|
|
||||||
asymbol *symbol;
|
|
||||||
long offset;
|
|
||||||
long sym_count;
|
|
||||||
long dyn_count;
|
|
||||||
long sym_storage;
|
|
||||||
long dyn_storage;
|
|
||||||
|
|
||||||
if ((sym_storage = bfd_get_symtab_upper_bound(disasm_bfd)) >= 0) {
|
|
||||||
|
|
||||||
if (bfd_get_file_flags(disasm_bfd) & DYNAMIC) {
|
|
||||||
dyn_storage = bfd_get_dynamic_symtab_upper_bound(disasm_bfd);
|
|
||||||
# if defined(__alpha__)
|
|
||||||
/* XXX */
|
|
||||||
if (dyn_storage < 0)
|
|
||||||
dyn_storage = 0;
|
|
||||||
# else
|
|
||||||
assert(dyn_storage >= 0);
|
|
||||||
# endif
|
|
||||||
}
|
|
||||||
else
|
|
||||||
dyn_storage = 0;
|
|
||||||
|
|
||||||
jit_alloc((jit_pointer_t *)&disasm_symbols,
|
|
||||||
(sym_storage + dyn_storage) * sizeof(asymbol *));
|
|
||||||
sym_count = bfd_canonicalize_symtab(disasm_bfd, disasm_symbols);
|
|
||||||
assert(sym_count >= 0);
|
|
||||||
if (dyn_storage) {
|
|
||||||
dyn_count = bfd_canonicalize_dynamic_symtab(disasm_bfd,
|
|
||||||
disasm_symbols +
|
|
||||||
sym_count);
|
|
||||||
assert(dyn_count >= 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
dyn_count = 0;
|
|
||||||
disasm_num_symbols = sym_count + dyn_count;
|
|
||||||
|
|
||||||
disasm_num_synthetic = bfd_get_synthetic_symtab(disasm_bfd,
|
|
||||||
sym_count,
|
|
||||||
disasm_symbols,
|
|
||||||
dyn_count,
|
|
||||||
disasm_symbols +
|
|
||||||
sym_count,
|
|
||||||
&disasm_synthetic);
|
|
||||||
if (disasm_num_synthetic > 0) {
|
|
||||||
jit_realloc((jit_pointer_t *)&disasm_symbols,
|
|
||||||
(sym_storage + dyn_storage) * sizeof(asymbol *),
|
|
||||||
(sym_storage + dyn_storage + disasm_num_synthetic) *
|
|
||||||
sizeof(asymbol *));
|
|
||||||
for (offset = 0; offset < disasm_num_synthetic; offset++)
|
|
||||||
disasm_symbols[disasm_num_symbols++] =
|
|
||||||
disasm_synthetic + offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* remove symbols not useful for disassemble */
|
|
||||||
in = out = disasm_symbols;
|
|
||||||
for (offset = 0; offset < disasm_num_symbols; offset++) {
|
|
||||||
symbol = *in++;
|
|
||||||
if (symbol->name &&
|
|
||||||
symbol->name[0] != '\0' &&
|
|
||||||
!(symbol->flags & (BSF_DEBUGGING | BSF_SECTION_SYM)) &&
|
|
||||||
!bfd_is_und_section(symbol->section) &&
|
|
||||||
!bfd_is_com_section(symbol->section))
|
|
||||||
*out++ = symbol;
|
|
||||||
}
|
|
||||||
disasm_num_symbols = out - disasm_symbols;
|
|
||||||
qsort(disasm_symbols, disasm_num_symbols,
|
|
||||||
sizeof(asymbol *), disasm_compare_symbols);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
jit_finish_debug(void)
|
|
||||||
{
|
|
||||||
#if DISASSEMBLER
|
|
||||||
if (disasm_synthetic)
|
|
||||||
jit_free((jit_pointer_t *)&disasm_synthetic);
|
|
||||||
if (disasm_symbols)
|
|
||||||
jit_free((jit_pointer_t *)&disasm_symbols);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
_jit_disassemble(jit_state_t *_jit)
|
|
||||||
{
|
|
||||||
#if DISASSEMBLER
|
|
||||||
if (disasm_bfd) {
|
|
||||||
# if defined(__arm__)
|
|
||||||
/* FIXME add mapping for prolog switching to arm and possible jump
|
|
||||||
* before first prolog also in arm mode */
|
|
||||||
disasm_info.disassembler_options = jit_cpu.thumb ? "force-thumb" : "";
|
|
||||||
# endif
|
|
||||||
|
|
||||||
disassemble(_jit->code.ptr, _jit->pc.uc - _jit->code.ptr);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#if DISASSEMBLER
|
|
||||||
/* Based on objdump source */
|
|
||||||
static int
|
|
||||||
disasm_compare_symbols(const void *ap, const void *bp)
|
|
||||||
{
|
|
||||||
const asymbol *a = *(const asymbol **)ap;
|
|
||||||
const asymbol *b = *(const asymbol **)bp;
|
|
||||||
|
|
||||||
if (bfd_asymbol_value(a) > bfd_asymbol_value(b))
|
|
||||||
return (1);
|
|
||||||
if (bfd_asymbol_value(a) < bfd_asymbol_value(b))
|
|
||||||
return (-1);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if __WORDSIZE == 32
|
|
||||||
# define address_buffer_length 16
|
|
||||||
# define address_buffer_format "%llx"
|
|
||||||
#else
|
|
||||||
# define address_buffer_length 32
|
|
||||||
# define address_buffer_format "%lx"
|
|
||||||
#endif
|
|
||||||
static void
|
|
||||||
disasm_print_address(bfd_vma addr, struct disassemble_info *info)
|
|
||||||
{
|
|
||||||
char *name;
|
|
||||||
char *file;
|
|
||||||
int line;
|
|
||||||
char buffer[address_buffer_length];
|
|
||||||
|
|
||||||
sprintf(buffer, address_buffer_format, (long long)addr);
|
|
||||||
(*info->fprintf_func)(info->stream, "0x%s", buffer);
|
|
||||||
|
|
||||||
# define _jit disasm_jit
|
|
||||||
# undef jit_pointer_p
|
|
||||||
# define jit_pointer_p(u) \
|
|
||||||
((u) >= _jit->code.ptr && (u) < _jit->pc.uc)
|
|
||||||
if (jit_pointer_p((jit_uint8_t *)(jit_word_t)addr)) {
|
|
||||||
if (jit_get_note((jit_uint8_t *)(jit_word_t)addr, &name, &file, &line))
|
|
||||||
(*info->fprintf_func)(info->stream, " %s:%s:%d",
|
|
||||||
name ? name : "",
|
|
||||||
file ? file : "",
|
|
||||||
line);
|
|
||||||
}
|
|
||||||
# undef jit_pointer_p
|
|
||||||
# undef _jit
|
|
||||||
else if (disasm_num_symbols) {
|
|
||||||
long low;
|
|
||||||
long high;
|
|
||||||
long offset;
|
|
||||||
asymbol *symbol;
|
|
||||||
|
|
||||||
low = 0;
|
|
||||||
high = disasm_num_symbols;
|
|
||||||
do {
|
|
||||||
offset = (low + high) >> 1;
|
|
||||||
symbol = disasm_symbols[offset];
|
|
||||||
if (bfd_asymbol_value(symbol) > addr)
|
|
||||||
high = offset - 1;
|
|
||||||
else if (bfd_asymbol_value(symbol) < addr)
|
|
||||||
low = offset + 1;
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
} while (low < high);
|
|
||||||
|
|
||||||
if (offset >= 0 && offset < disasm_num_symbols) {
|
|
||||||
if (bfd_asymbol_value(symbol) < addr) {
|
|
||||||
while (++offset < disasm_num_symbols) {
|
|
||||||
symbol = disasm_symbols[offset];
|
|
||||||
if (bfd_asymbol_value(symbol) >= addr)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (bfd_asymbol_value(symbol) > addr) {
|
|
||||||
while (offset--) {
|
|
||||||
if (bfd_asymbol_value(disasm_symbols[offset]) < addr)
|
|
||||||
break;
|
|
||||||
symbol = disasm_symbols[offset];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (bfd_asymbol_value(symbol) == addr)
|
|
||||||
(*info->fprintf_func)(info->stream, " # %s", symbol->name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
_disassemble(jit_state_t *_jit, jit_pointer_t code, jit_int32_t length)
|
|
||||||
{
|
|
||||||
int bytes;
|
|
||||||
char *name, *old_name;
|
|
||||||
char *file, *old_file;
|
|
||||||
int line, old_line;
|
|
||||||
#if __arm__
|
|
||||||
jit_int32_t offset;
|
|
||||||
jit_bool_t data_info;
|
|
||||||
jit_int32_t data_offset;
|
|
||||||
#endif
|
|
||||||
bfd_vma pc = (jit_uword_t)code;
|
|
||||||
bfd_vma end = (jit_uword_t)code + length;
|
|
||||||
char buffer[address_buffer_length];
|
|
||||||
#if DEVEL_DISASSEMBLER
|
|
||||||
jit_node_t *node;
|
|
||||||
jit_uword_t prevw;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if __arm__
|
|
||||||
data_info = _jitc && _jitc->data_info.ptr;
|
|
||||||
data_offset = 0;
|
|
||||||
#endif
|
|
||||||
disasm_info.buffer = code;
|
|
||||||
disasm_info.buffer_vma = (jit_uword_t)code;
|
|
||||||
disasm_info.buffer_length = length;
|
|
||||||
old_file = old_name = NULL;
|
|
||||||
old_line = 0;
|
|
||||||
disasm_jit = _jit;
|
|
||||||
#if DEVEL_DISASSEMBLER
|
|
||||||
node = _jitc->head;
|
|
||||||
prevw = pc;
|
|
||||||
#endif
|
|
||||||
while (pc < end) {
|
|
||||||
#if DEVEL_DISASSEMBLER
|
|
||||||
while (node && (jit_uword_t)(prevw + node->offset) < (jit_uword_t)pc) {
|
|
||||||
prevw += node->offset;
|
|
||||||
node = node->next;
|
|
||||||
}
|
|
||||||
while (node && (jit_uword_t)(prevw + node->offset) == (jit_uword_t)pc) {
|
|
||||||
jit_print_node(node);
|
|
||||||
fputc('\n', stdout);
|
|
||||||
prevw += node->offset;
|
|
||||||
node = node->next;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#if __arm__
|
|
||||||
again:
|
|
||||||
if (data_info) {
|
|
||||||
while (_jitc->data_info.ptr[data_offset].code < pc) {
|
|
||||||
if (++data_offset >= _jitc->data_info.length) {
|
|
||||||
data_info = 0;
|
|
||||||
goto again;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (pc == _jitc->data_info.ptr[data_offset].code) {
|
|
||||||
offset = _jitc->data_info.ptr[data_offset].length;
|
|
||||||
for (; offset >= 4; offset -= 4, pc += 4) {
|
|
||||||
bytes = sprintf(buffer, address_buffer_format, pc);
|
|
||||||
(*disasm_info.fprintf_func)(disasm_stream,
|
|
||||||
"%*c0x%s\t.data\t0x%08x\n",
|
|
||||||
16 - bytes, ' ', buffer,
|
|
||||||
*(jit_uint32_t *)
|
|
||||||
(jit_uint32_t)pc);
|
|
||||||
}
|
|
||||||
/* reset disassemble information instead of attempting
|
|
||||||
* to hack the arm specific backend data structures to
|
|
||||||
* tell it to forward the required number of bytes. */
|
|
||||||
disasm_info.buffer = (jit_pointer_t)(jit_uint32_t)pc;
|
|
||||||
disasm_info.buffer_vma = (jit_uword_t)pc;
|
|
||||||
if ((disasm_info.buffer_length = end - pc) <= 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (jit_get_note((jit_uint8_t *)(jit_word_t)pc, &name, &file, &line) &&
|
|
||||||
(name != old_name || file != old_file || line != old_line)) {
|
|
||||||
(*disasm_info.fprintf_func)(disasm_stream, "# %s:%s:%d\n",
|
|
||||||
name ? name : "",
|
|
||||||
file ? file : "",
|
|
||||||
line);
|
|
||||||
old_name = name;
|
|
||||||
old_file = file;
|
|
||||||
old_line = line;
|
|
||||||
}
|
|
||||||
|
|
||||||
bytes = sprintf(buffer, address_buffer_format, (long long)pc);
|
|
||||||
(*disasm_info.fprintf_func)(disasm_stream, "%*c0x%s\t",
|
|
||||||
16 - bytes, ' ', buffer);
|
|
||||||
pc += (*disasm_print)(pc, &disasm_info);
|
|
||||||
putc('\n', disasm_stream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
124
jit/memory.c
124
jit/memory.c
|
@ -1,124 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2013-2018 Free Software Foundation, Inc.
|
|
||||||
*
|
|
||||||
* This file is part of GNU lightning.
|
|
||||||
*
|
|
||||||
* GNU lightning is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU Lesser General Public License as published
|
|
||||||
* by the Free Software Foundation; either version 3, or (at your option)
|
|
||||||
* any later version.
|
|
||||||
*
|
|
||||||
* GNU lightning 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 Lesser General Public
|
|
||||||
* License for more details.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Paulo Cesar Pereira de Andrade
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/mman.h>
|
|
||||||
|
|
||||||
#include "jit.h"
|
|
||||||
#include "jit/jit_private.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Prototypes
|
|
||||||
*/
|
|
||||||
static void *jit_default_alloc_func(size_t);
|
|
||||||
static void *jit_default_realloc_func(void*, size_t);
|
|
||||||
static void jit_default_free_func(void *);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialization
|
|
||||||
*/
|
|
||||||
static jit_alloc_func_ptr jit_alloc_ptr = jit_default_alloc_func;
|
|
||||||
static jit_realloc_func_ptr jit_realloc_ptr = jit_default_realloc_func;
|
|
||||||
static jit_free_func_ptr jit_free_ptr = jit_default_free_func;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Implementation
|
|
||||||
*/
|
|
||||||
jit_pointer_t
|
|
||||||
jit_memcpy(jit_pointer_t dst, const void * src, jit_word_t size)
|
|
||||||
{
|
|
||||||
if (size)
|
|
||||||
return (memcpy(dst, src, size));
|
|
||||||
return (dst);
|
|
||||||
}
|
|
||||||
|
|
||||||
jit_pointer_t
|
|
||||||
jit_memmove(jit_pointer_t dst, const void *src , jit_word_t size)
|
|
||||||
{
|
|
||||||
if (size)
|
|
||||||
return (memmove(dst, src, size));
|
|
||||||
return (dst);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
jit_set_memory_functions(jit_alloc_func_ptr alloc_ptr,
|
|
||||||
jit_realloc_func_ptr realloc_ptr,
|
|
||||||
jit_free_func_ptr free_ptr)
|
|
||||||
{
|
|
||||||
if (alloc_ptr == NULL)
|
|
||||||
alloc_ptr = jit_default_alloc_func;
|
|
||||||
if (realloc_ptr == NULL)
|
|
||||||
realloc_ptr = jit_default_realloc_func;
|
|
||||||
if (free_ptr == NULL)
|
|
||||||
free_ptr = jit_default_free_func;
|
|
||||||
jit_alloc_ptr = alloc_ptr;
|
|
||||||
jit_realloc_ptr = realloc_ptr;
|
|
||||||
jit_free_ptr = free_ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
jit_get_memory_functions(jit_alloc_func_ptr *alloc_ptr,
|
|
||||||
jit_realloc_func_ptr *realloc_ptr,
|
|
||||||
jit_free_func_ptr *free_ptr)
|
|
||||||
{
|
|
||||||
*alloc_ptr = jit_alloc_ptr;
|
|
||||||
*realloc_ptr = jit_realloc_ptr;
|
|
||||||
*free_ptr = jit_free_ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
jit_alloc(jit_pointer_t *ptr, jit_word_t size)
|
|
||||||
{
|
|
||||||
*ptr = (*jit_alloc_ptr)(size);
|
|
||||||
memset(*ptr, 0, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
jit_realloc(jit_pointer_t *ptr, jit_word_t old_size, jit_word_t new_size)
|
|
||||||
{
|
|
||||||
*ptr = (*jit_realloc_ptr)(*ptr, new_size);
|
|
||||||
if (old_size < new_size)
|
|
||||||
memset((jit_int8_t*)*ptr + old_size, 0, new_size - old_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
jit_free(jit_pointer_t *ptr)
|
|
||||||
{
|
|
||||||
if (*ptr) {
|
|
||||||
(*jit_free_ptr)(*ptr);
|
|
||||||
*ptr = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *
|
|
||||||
jit_default_alloc_func(size_t size)
|
|
||||||
{
|
|
||||||
return (malloc(size));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *
|
|
||||||
jit_default_realloc_func(void *ptr, size_t size)
|
|
||||||
{
|
|
||||||
return (realloc(ptr, size));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
jit_default_free_func(void *ptr)
|
|
||||||
{
|
|
||||||
free(ptr);
|
|
||||||
}
|
|
230
jit/names.c
230
jit/names.c
|
@ -1,230 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2014-2017 Free Software Foundation, Inc.
|
|
||||||
*
|
|
||||||
* This file is part of GNU lightning.
|
|
||||||
*
|
|
||||||
* GNU lightning is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU Lesser General Public License as published
|
|
||||||
* by the Free Software Foundation; either version 3, or (at your option)
|
|
||||||
* any later version.
|
|
||||||
*
|
|
||||||
* GNU lightning 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 Lesser General Public
|
|
||||||
* License for more details.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Paulo Cesar Pereira de Andrade
|
|
||||||
*/
|
|
||||||
|
|
||||||
static char *code_name[] = {
|
|
||||||
"data",
|
|
||||||
"live", "align",
|
|
||||||
"save", "load",
|
|
||||||
"#name", "#note",
|
|
||||||
"label",
|
|
||||||
"prolog",
|
|
||||||
"ellipsis", "va_push",
|
|
||||||
"allocai", "allocar",
|
|
||||||
"arg",
|
|
||||||
"getarg_c", "getarg_uc",
|
|
||||||
"getarg_s", "getarg_us",
|
|
||||||
"getarg_i", "getarg_ui",
|
|
||||||
"getarg_l",
|
|
||||||
"putargr", "putargi",
|
|
||||||
"va_start",
|
|
||||||
"va_arg", "va_arg_d",
|
|
||||||
"va_end",
|
|
||||||
"addr", "addi",
|
|
||||||
"addcr", "addci",
|
|
||||||
"addxr", "addxi",
|
|
||||||
"subr", "subi",
|
|
||||||
"subcr", "subci",
|
|
||||||
"subxr", "subxi",
|
|
||||||
"rsbi",
|
|
||||||
"mulr", "muli",
|
|
||||||
"qmulr", "qmuli",
|
|
||||||
"qmulr_u", "qmuli_u",
|
|
||||||
"divr", "divi",
|
|
||||||
"divr_u", "divi_u",
|
|
||||||
"qdivr", "qdivi",
|
|
||||||
"qdivr_u", "qdivi_u",
|
|
||||||
"remr", "remi",
|
|
||||||
"remr_u", "remi_u",
|
|
||||||
"andr", "andi",
|
|
||||||
"orr", "ori",
|
|
||||||
"xorr", "xori",
|
|
||||||
"lshr", "lshi",
|
|
||||||
"rshr", "rshi",
|
|
||||||
"rshr_u", "rshi_u",
|
|
||||||
"negr", "comr",
|
|
||||||
"ltr", "lti",
|
|
||||||
"ltr_u", "lti_u",
|
|
||||||
"ler", "lei",
|
|
||||||
"ler_u", "lei_u",
|
|
||||||
"eqr", "eqi",
|
|
||||||
"ger", "gei",
|
|
||||||
"ger_u", "gei_u",
|
|
||||||
"gtr", "gti",
|
|
||||||
"gtr_u", "gti_u",
|
|
||||||
"ner", "nei",
|
|
||||||
"movr", "movi",
|
|
||||||
"extr_c", "extr_uc",
|
|
||||||
"extr_s", "extr_us",
|
|
||||||
"extr_i", "extr_ui",
|
|
||||||
"htonr_us",
|
|
||||||
"htonr_ui", "htonr_ul",
|
|
||||||
"ldr_c", "ldi_c",
|
|
||||||
"ldr_uc", "ldi_uc",
|
|
||||||
"ldr_s", "ldi_s",
|
|
||||||
"ldr_us", "ldi_us",
|
|
||||||
"ldr_i", "ldi_i",
|
|
||||||
"ldr_ui", "ldi_ui",
|
|
||||||
"ldr_l", "ldi_l",
|
|
||||||
"ldxr_c", "ldxi_c",
|
|
||||||
"ldxr_uc", "ldxi_uc",
|
|
||||||
"ldxr_s", "ldxi_s",
|
|
||||||
"ldxr_us", "ldxi_us",
|
|
||||||
"ldxr_i", "ldxi_i",
|
|
||||||
"ldxr_ui", "ldxi_ui",
|
|
||||||
"ldxr_l", "ldxi_l",
|
|
||||||
"str_c", "sti_c",
|
|
||||||
"str_s", "sti_s",
|
|
||||||
"str_i", "sti_i",
|
|
||||||
"str_l", "sti_l",
|
|
||||||
"stxr_c", "stxi_c",
|
|
||||||
"stxr_s", "stxi_s",
|
|
||||||
"stxr_i", "stxi_i",
|
|
||||||
"stxr_l", "stxi_l",
|
|
||||||
"bltr", "blti",
|
|
||||||
"bltr_u", "blti_u",
|
|
||||||
"bler", "blei",
|
|
||||||
"bler_u", "blei_u",
|
|
||||||
"beqr", "beqi",
|
|
||||||
"bger", "bgei",
|
|
||||||
"bger_u", "bgei_u",
|
|
||||||
"bgtr", "bgti",
|
|
||||||
"bgtr_u", "bgti_u",
|
|
||||||
"bner", "bnei",
|
|
||||||
"bmsr", "bmsi",
|
|
||||||
"bmcr", "bmci",
|
|
||||||
"boaddr", "boaddi",
|
|
||||||
"boaddr_u", "boaddi_u",
|
|
||||||
"bxaddr", "bxaddi",
|
|
||||||
"bxaddr_u", "bxaddi_u",
|
|
||||||
"bosubr", "bosubi",
|
|
||||||
"bosubr_u", "bosubi_u",
|
|
||||||
"bxsubr", "bxsubi",
|
|
||||||
"bxsubr_u", "bxsubi_u",
|
|
||||||
"jmpr", "jmpi",
|
|
||||||
"callr", "calli",
|
|
||||||
"prepare",
|
|
||||||
"pushargr", "pushargi",
|
|
||||||
"finishr", "finishi",
|
|
||||||
"ret",
|
|
||||||
"retr", "reti",
|
|
||||||
"retval_c", "retval_uc",
|
|
||||||
"retval_s", "retval_us",
|
|
||||||
"retval_i", "retval_ui",
|
|
||||||
"retval_l",
|
|
||||||
"epilog",
|
|
||||||
"arg_f", "getarg_f",
|
|
||||||
"putargr_f", "putargi_f",
|
|
||||||
"addr_f", "addi_f",
|
|
||||||
"subr_f", "subi_f",
|
|
||||||
"rsbi_f",
|
|
||||||
"mulr_f", "muli_f",
|
|
||||||
"divr_f", "divi_f",
|
|
||||||
"negr_f", "absr_f",
|
|
||||||
"sqrtr_f",
|
|
||||||
"ltr_f", "lti_f",
|
|
||||||
"ler_f", "lei_f",
|
|
||||||
"eqr_f", "eqi_f",
|
|
||||||
"ger_f", "gei_f",
|
|
||||||
"gtr_f", "gti_f",
|
|
||||||
"ner_f", "nei_f",
|
|
||||||
"unltr_f", "unlti_f",
|
|
||||||
"unler_f", "unlei_f",
|
|
||||||
"uneqr_f", "uneqi_f",
|
|
||||||
"unger_f", "ungei_f",
|
|
||||||
"ungtr_f", "ungti_f",
|
|
||||||
"ltgtr_f", "ltgti_f",
|
|
||||||
"ordr_f", "ordi_f",
|
|
||||||
"unordr_f", "unordi_f",
|
|
||||||
"truncr_f_i", "truncr_f_l",
|
|
||||||
"extr_f", "extr_d_f",
|
|
||||||
"movr_f", "movi_f",
|
|
||||||
"ldr_f", "ldi_f",
|
|
||||||
"ldxr_f", "ldxi_f",
|
|
||||||
"str_f", "sti_f",
|
|
||||||
"stxr_f", "stxi_f",
|
|
||||||
"bltr_f", "blti_f",
|
|
||||||
"bler_f", "blei_f",
|
|
||||||
"beqr_f", "beqi_f",
|
|
||||||
"bger_f", "bgei_f",
|
|
||||||
"bgtr_f", "bgti_f",
|
|
||||||
"bner_f", "bnei_f",
|
|
||||||
"bunltr_f", "bunlti_f",
|
|
||||||
"bunler_f", "bunlei_f",
|
|
||||||
"buneqr_f", "buneqi_f",
|
|
||||||
"bunger_f", "bungei_f",
|
|
||||||
"bungtr_f", "bungti_f",
|
|
||||||
"bltgtr_f", "bltgti_f",
|
|
||||||
"bordr_f", "bordi_f",
|
|
||||||
"bunordr_f", "bunordi_f",
|
|
||||||
"pushargr_f", "pushargi_f",
|
|
||||||
"retr_f", "reti_f",
|
|
||||||
"retval_f",
|
|
||||||
"arg_d", "getarg_d",
|
|
||||||
"putargr_d", "putargi_d",
|
|
||||||
"addr_d", "addi_d",
|
|
||||||
"subr_d", "subi_d",
|
|
||||||
"rsbi_d",
|
|
||||||
"mulr_d", "muli_d",
|
|
||||||
"divr_d", "divi_d",
|
|
||||||
"negr_d", "absr_d",
|
|
||||||
"sqrtr_d",
|
|
||||||
"ltr_d", "lti_d",
|
|
||||||
"ler_d", "lei_d",
|
|
||||||
"eqr_d", "eqi_d",
|
|
||||||
"ger_d", "gei_d",
|
|
||||||
"gtr_d", "gti_d",
|
|
||||||
"ner_d", "nei_d",
|
|
||||||
"unltr_d", "unlti_d",
|
|
||||||
"unler_d", "unlei_d",
|
|
||||||
"uneqr_d", "uneqi_d",
|
|
||||||
"unger_d", "ungei_d",
|
|
||||||
"ungtr_d", "ungti_d",
|
|
||||||
"ltgtr_d", "ltgti_d",
|
|
||||||
"ordr_d", "ordi_d",
|
|
||||||
"unordr_d", "unordi_d",
|
|
||||||
"truncr_d_i", "truncr_d_l",
|
|
||||||
"extr_d", "extr_f_d",
|
|
||||||
"movr_d", "movi_d",
|
|
||||||
"ldr_d", "ldi_d",
|
|
||||||
"ldxr_d", "ldxi_d",
|
|
||||||
"str_d", "sti_d",
|
|
||||||
"stxr_d", "stxi_d",
|
|
||||||
"bltr_d", "blti_d",
|
|
||||||
"bler_d", "blei_d",
|
|
||||||
"beqr_d", "beqi_d",
|
|
||||||
"bger_d", "bgei_d",
|
|
||||||
"bgtr_d", "bgti_d",
|
|
||||||
"bner_d", "bnei_d",
|
|
||||||
"bunltr_d", "bunlti_d",
|
|
||||||
"bunler_d", "bunlei_d",
|
|
||||||
"buneqr_d", "buneqi_d",
|
|
||||||
"bunger_d", "bungei_d",
|
|
||||||
"bungtr_d", "bungti_d",
|
|
||||||
"bltgtr_d", "bltgti_d",
|
|
||||||
"bordr_d", "bordi_d",
|
|
||||||
"bunordr_d", "bunordi_d",
|
|
||||||
"pushargr_d", "pushargi_d",
|
|
||||||
"retr_d", "reti_d",
|
|
||||||
"retval_d",
|
|
||||||
"movr_w_f", "movr_ww_d",
|
|
||||||
"movr_w_d",
|
|
||||||
"movr_f_w", "movi_f_w",
|
|
||||||
"movr_d_ww", "movi_d_ww",
|
|
||||||
"movr_d_w", "movi_d_w",
|
|
||||||
};
|
|
414
jit/note.c
414
jit/note.c
|
@ -1,414 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2013-2018 Free Software Foundation, Inc.
|
|
||||||
*
|
|
||||||
* This file is part of GNU lightning.
|
|
||||||
*
|
|
||||||
* GNU lightning is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU Lesser General Public License as published
|
|
||||||
* by the Free Software Foundation; either version 3, or (at your option)
|
|
||||||
* any later version.
|
|
||||||
*
|
|
||||||
* GNU lightning 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 Lesser General Public
|
|
||||||
* License for more details.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Paulo Cesar Pereira de Andrade
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "jit.h"
|
|
||||||
#include "jit/jit_private.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Prototypes
|
|
||||||
*/
|
|
||||||
#define new_note(u, v) _new_note(_jit, u, v)
|
|
||||||
static jit_note_t *_new_note(jit_state_t *, jit_uint8_t*, char*);
|
|
||||||
static void new_line(jit_int32_t,jit_note_t*,char*,jit_int32_t,jit_int32_t);
|
|
||||||
#define note_search_index(u) _note_search_index(_jit, u)
|
|
||||||
static jit_int32_t _note_search_index(jit_state_t*, jit_uint8_t*);
|
|
||||||
static jit_int32_t line_insert_index(jit_note_t*,jit_int32_t);
|
|
||||||
static jit_int32_t line_search_index(jit_note_t*,jit_int32_t);
|
|
||||||
static jit_int32_t offset_insert_index(jit_line_t*,jit_int32_t);
|
|
||||||
static jit_int32_t offset_search_index(jit_line_t*,jit_int32_t);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Implementation
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
jit_init_note(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
jit_finish_note(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
jit_node_t *
|
|
||||||
_jit_name(jit_state_t *_jit, const char *name)
|
|
||||||
{
|
|
||||||
jit_node_t *node;
|
|
||||||
|
|
||||||
node = jit_new_node(jit_code_name);
|
|
||||||
if (name)
|
|
||||||
node->v.n = jit_data(name, strlen(name) + 1, 1);
|
|
||||||
else
|
|
||||||
node->v.p = NULL;
|
|
||||||
if (_jitc->note.head == NULL)
|
|
||||||
_jitc->note.head = _jitc->note.tail = node;
|
|
||||||
else {
|
|
||||||
_jitc->note.tail->link = node;
|
|
||||||
_jitc->note.tail = node;
|
|
||||||
}
|
|
||||||
++_jit->note.length;
|
|
||||||
_jitc->note.size += sizeof(jit_note_t);
|
|
||||||
/* remember previous note is invalid due to name change */
|
|
||||||
_jitc->note.note = NULL;
|
|
||||||
return (_jitc->note.name = node);
|
|
||||||
}
|
|
||||||
|
|
||||||
jit_node_t *
|
|
||||||
_jit_note(jit_state_t *_jit, const char *name, int line)
|
|
||||||
{
|
|
||||||
jit_node_t *node;
|
|
||||||
|
|
||||||
node = jit_new_node(jit_code_note);
|
|
||||||
if (name)
|
|
||||||
node->v.n = jit_data(name, strlen(name) + 1, 1);
|
|
||||||
else
|
|
||||||
node->v.p = NULL;
|
|
||||||
node->w.w = line;
|
|
||||||
if (_jitc->note.head == NULL)
|
|
||||||
_jitc->note.head = _jitc->note.tail = node;
|
|
||||||
else {
|
|
||||||
_jitc->note.tail->link = node;
|
|
||||||
_jitc->note.tail = node;
|
|
||||||
}
|
|
||||||
if (_jitc->note.note == NULL ||
|
|
||||||
(name == NULL && _jitc->note.note != NULL) ||
|
|
||||||
(name != NULL && _jitc->note.note == NULL) ||
|
|
||||||
(name != NULL && _jitc->note.note != NULL &&
|
|
||||||
strcmp(name, (char *)_jitc->data.ptr + _jitc->note.note->v.n->u.w)))
|
|
||||||
_jitc->note.size += sizeof(jit_line_t);
|
|
||||||
_jitc->note.size += sizeof(jit_int32_t) * 2;
|
|
||||||
return (_jitc->note.note = node);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
_jit_annotate(jit_state_t *_jit)
|
|
||||||
{
|
|
||||||
jit_node_t *node;
|
|
||||||
jit_note_t *note;
|
|
||||||
jit_line_t *line;
|
|
||||||
jit_word_t length;
|
|
||||||
jit_word_t note_offset;
|
|
||||||
jit_word_t line_offset;
|
|
||||||
|
|
||||||
/* initialize pointers in mmaped data area */
|
|
||||||
_jit->note.ptr = (jit_note_t *)_jitc->note.base;
|
|
||||||
_jit->note.length = 0;
|
|
||||||
|
|
||||||
note = NULL;
|
|
||||||
for (node = _jitc->note.head; node; node = node->link) {
|
|
||||||
if (node->code == jit_code_name)
|
|
||||||
note = new_note(node->u.p, node->v.p ? node->v.n->u.p : NULL);
|
|
||||||
else if (node->v.p) {
|
|
||||||
if (note == NULL)
|
|
||||||
note = new_note(node->u.p, NULL);
|
|
||||||
jit_set_note(note, node->v.n->u.p, node->w.w,
|
|
||||||
(jit_uint8_t *)node->u.p - note->code);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* last note */
|
|
||||||
if (note)
|
|
||||||
note->size = _jit->pc.uc - note->code;
|
|
||||||
|
|
||||||
/* annotations may be very complex with conditions to extend
|
|
||||||
* or ignore redundant notes, as well as add entries to earlier
|
|
||||||
* notes, so, relocate the information to the data buffer,
|
|
||||||
* with likely over allocated reserved space */
|
|
||||||
|
|
||||||
/* relocate jit_line_t objects */
|
|
||||||
for (note_offset = 0; note_offset < _jit->note.length; note_offset++) {
|
|
||||||
note = _jit->note.ptr + note_offset;
|
|
||||||
if ((length = sizeof(jit_line_t) * note->length) == 0)
|
|
||||||
continue;
|
|
||||||
assert(_jitc->note.base + length < _jit->data.ptr + _jit->data.length);
|
|
||||||
jit_memcpy(_jitc->note.base, note->lines, length);
|
|
||||||
jit_free((jit_pointer_t *)¬e->lines);
|
|
||||||
note->lines = (jit_line_t *)_jitc->note.base;
|
|
||||||
_jitc->note.base += length;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* relocate offset and line number information */
|
|
||||||
for (note_offset = 0; note_offset < _jit->note.length; note_offset++) {
|
|
||||||
note = _jit->note.ptr + note_offset;
|
|
||||||
for (line_offset = 0; line_offset < note->length; line_offset++) {
|
|
||||||
line = note->lines + line_offset;
|
|
||||||
length = sizeof(jit_int32_t) * line->length;
|
|
||||||
assert(_jitc->note.base + length <
|
|
||||||
_jit->data.ptr + _jit->data.length);
|
|
||||||
jit_memcpy(_jitc->note.base, line->linenos, length);
|
|
||||||
jit_free((jit_pointer_t *)&line->linenos);
|
|
||||||
line->linenos = (jit_int32_t *)_jitc->note.base;
|
|
||||||
_jitc->note.base += length;
|
|
||||||
assert(_jitc->note.base + length <
|
|
||||||
_jit->data.ptr + _jit->data.length);
|
|
||||||
jit_memcpy(_jitc->note.base, line->offsets, length);
|
|
||||||
jit_free((jit_pointer_t *)&line->offsets);
|
|
||||||
line->offsets = (jit_int32_t *)_jitc->note.base;
|
|
||||||
_jitc->note.base += length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
_jit_set_note(jit_state_t *_jit, jit_note_t *note,
|
|
||||||
char *file, int lineno, jit_int32_t offset)
|
|
||||||
{
|
|
||||||
jit_line_t *line;
|
|
||||||
jit_int32_t index;
|
|
||||||
|
|
||||||
index = line_insert_index(note, offset);
|
|
||||||
if (note->length && index == note->length &&
|
|
||||||
note->lines[index - 1].file == file)
|
|
||||||
--index;
|
|
||||||
if (index >= note->length || note->lines[index].file != file)
|
|
||||||
new_line(index, note, file, lineno, offset);
|
|
||||||
else {
|
|
||||||
line = note->lines + index;
|
|
||||||
index = offset_insert_index(line, offset);
|
|
||||||
if (index < line->length && line->offsets[index] == offset) {
|
|
||||||
/* common case if no code was generated for several source lines */
|
|
||||||
if (line->linenos[index] < lineno)
|
|
||||||
line->linenos[index] = lineno;
|
|
||||||
}
|
|
||||||
else if (index < line->length && line->linenos[index] == lineno) {
|
|
||||||
/* common case of extending entry */
|
|
||||||
if (line->offsets[index] > offset)
|
|
||||||
line->offsets[index] = offset;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* line or offset changed */
|
|
||||||
if ((line->length & 15) == 0) {
|
|
||||||
jit_realloc((jit_pointer_t *)&line->linenos,
|
|
||||||
line->length * sizeof(jit_int32_t),
|
|
||||||
(line->length + 17) * sizeof(jit_int32_t));
|
|
||||||
jit_realloc((jit_pointer_t *)&line->offsets,
|
|
||||||
line->length * sizeof(jit_int32_t),
|
|
||||||
(line->length + 17) * sizeof(jit_int32_t));
|
|
||||||
}
|
|
||||||
if (index < note->length) {
|
|
||||||
jit_memmove(line->linenos + index + 1, line->linenos + index,
|
|
||||||
sizeof(jit_int32_t) * (line->length - index));
|
|
||||||
jit_memmove(line->offsets + index + 1, line->offsets + index,
|
|
||||||
sizeof(jit_int32_t) * (line->length - index));
|
|
||||||
}
|
|
||||||
line->linenos[index] = lineno;
|
|
||||||
line->offsets[index] = offset;
|
|
||||||
++line->length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
jit_bool_t
|
|
||||||
_jit_get_note(jit_state_t *_jit, jit_pointer_t code,
|
|
||||||
char **name, char **file, jit_int32_t *lineno)
|
|
||||||
{
|
|
||||||
jit_note_t *note;
|
|
||||||
jit_line_t *line;
|
|
||||||
jit_int32_t index;
|
|
||||||
jit_int32_t offset;
|
|
||||||
|
|
||||||
if ((index = note_search_index((jit_uint8_t *)code)) >= _jit->note.length)
|
|
||||||
return (0);
|
|
||||||
note = _jit->note.ptr + index;
|
|
||||||
if ((jit_uint8_t *)code < note->code ||
|
|
||||||
(jit_uint8_t *)code >= note->code + note->size)
|
|
||||||
return (0);
|
|
||||||
offset = (jit_uint8_t *)code - note->code;
|
|
||||||
if ((index = line_search_index(note, offset)) >= note->length)
|
|
||||||
return (0);
|
|
||||||
if (index == 0 && offset < note->lines[0].offsets[0])
|
|
||||||
return (0);
|
|
||||||
line = note->lines + index;
|
|
||||||
if ((index = offset_search_index(line, offset)) >= line->length)
|
|
||||||
return (0);
|
|
||||||
|
|
||||||
if (name)
|
|
||||||
*name = note->name;
|
|
||||||
if (file)
|
|
||||||
*file = line->file;
|
|
||||||
if (lineno)
|
|
||||||
*lineno = line->linenos[index];
|
|
||||||
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static jit_note_t *
|
|
||||||
_new_note(jit_state_t *_jit, jit_uint8_t *code, char *name)
|
|
||||||
{
|
|
||||||
jit_note_t *note;
|
|
||||||
jit_note_t *prev;
|
|
||||||
|
|
||||||
if (_jit->note.length) {
|
|
||||||
prev = _jit->note.ptr + _jit->note.length - 1;
|
|
||||||
assert(code >= prev->code);
|
|
||||||
prev->size = code - prev->code;
|
|
||||||
}
|
|
||||||
note = (jit_note_t *)_jitc->note.base;
|
|
||||||
_jitc->note.base += sizeof(jit_note_t);
|
|
||||||
++_jit->note.length;
|
|
||||||
note->code = code;
|
|
||||||
note->name = name;
|
|
||||||
|
|
||||||
return (note);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
new_line(jit_int32_t index, jit_note_t *note,
|
|
||||||
char *file, jit_int32_t lineno, jit_int32_t offset)
|
|
||||||
{
|
|
||||||
jit_line_t *line;
|
|
||||||
|
|
||||||
if (note->lines == NULL)
|
|
||||||
jit_alloc((jit_pointer_t *)¬e->lines, 16 * sizeof(jit_line_t));
|
|
||||||
else if ((note->length & 15) == 15)
|
|
||||||
jit_realloc((jit_pointer_t *)¬e->lines,
|
|
||||||
note->length * sizeof(jit_line_t),
|
|
||||||
(note->length + 17) * sizeof(jit_line_t));
|
|
||||||
|
|
||||||
if (index < note->length)
|
|
||||||
jit_memmove(note->lines + index + 1, note->lines + index,
|
|
||||||
sizeof(jit_line_t) * (note->length - index));
|
|
||||||
line = note->lines + index;
|
|
||||||
++note->length;
|
|
||||||
|
|
||||||
line->file = file;
|
|
||||||
line->length = 1;
|
|
||||||
jit_alloc((jit_pointer_t *)&line->linenos, 16 * sizeof(jit_int32_t));
|
|
||||||
line->linenos[0] = lineno;
|
|
||||||
jit_alloc((jit_pointer_t *)&line->offsets, 16 * sizeof(jit_int32_t));
|
|
||||||
line->offsets[0] = offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
static jit_int32_t
|
|
||||||
_note_search_index(jit_state_t *_jit, jit_uint8_t *code)
|
|
||||||
{
|
|
||||||
jit_int32_t bot;
|
|
||||||
jit_int32_t top;
|
|
||||||
jit_int32_t index;
|
|
||||||
jit_note_t *notes;
|
|
||||||
|
|
||||||
bot = 0;
|
|
||||||
top = _jit->note.length;
|
|
||||||
notes = _jit->note.ptr;
|
|
||||||
for (index = (bot + top) >> 1; bot < top; index = (bot + top) >> 1) {
|
|
||||||
if (code < notes[index].code)
|
|
||||||
top = index;
|
|
||||||
else if (code >= notes[index].code &&
|
|
||||||
code - notes[index].code < notes[index].size)
|
|
||||||
break;
|
|
||||||
else
|
|
||||||
bot = index + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (index);
|
|
||||||
}
|
|
||||||
|
|
||||||
static jit_int32_t
|
|
||||||
line_insert_index(jit_note_t *note, jit_int32_t offset)
|
|
||||||
{
|
|
||||||
jit_int32_t bot;
|
|
||||||
jit_int32_t top;
|
|
||||||
jit_int32_t index;
|
|
||||||
jit_line_t *lines;
|
|
||||||
|
|
||||||
bot = 0;
|
|
||||||
top = note->length;
|
|
||||||
if ((lines = note->lines) == NULL)
|
|
||||||
return (0);
|
|
||||||
for (index = (bot + top) >> 1; bot < top; index = (bot + top) >> 1) {
|
|
||||||
if (offset < *lines[index].offsets)
|
|
||||||
top = index;
|
|
||||||
else
|
|
||||||
bot = index + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ((bot + top) >> 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static jit_int32_t
|
|
||||||
line_search_index(jit_note_t *note, jit_int32_t offset)
|
|
||||||
{
|
|
||||||
jit_int32_t bot;
|
|
||||||
jit_int32_t top;
|
|
||||||
jit_int32_t index;
|
|
||||||
jit_line_t *lines;
|
|
||||||
|
|
||||||
bot = 0;
|
|
||||||
top = note->length;
|
|
||||||
if ((lines = note->lines) == NULL)
|
|
||||||
return (0);
|
|
||||||
for (index = (bot + top) >> 1; bot < top; index = (bot + top) >> 1) {
|
|
||||||
if (offset < *lines[index].offsets)
|
|
||||||
top = index;
|
|
||||||
/* offset should be already verified to be in range */
|
|
||||||
else if (index == note->length - 1 ||
|
|
||||||
(offset >= *lines[index].offsets &&
|
|
||||||
offset < *lines[index + 1].offsets))
|
|
||||||
break;
|
|
||||||
else
|
|
||||||
bot = index + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (index);
|
|
||||||
}
|
|
||||||
|
|
||||||
static jit_int32_t
|
|
||||||
offset_insert_index(jit_line_t *line, jit_int32_t offset)
|
|
||||||
{
|
|
||||||
jit_int32_t bot;
|
|
||||||
jit_int32_t top;
|
|
||||||
jit_int32_t index;
|
|
||||||
jit_int32_t *offsets;
|
|
||||||
|
|
||||||
bot = 0;
|
|
||||||
top = line->length;
|
|
||||||
offsets = line->offsets;
|
|
||||||
for (index = (bot + top) >> 1; bot < top; index = (bot + top) >> 1) {
|
|
||||||
if (offset < offsets[index])
|
|
||||||
top = index;
|
|
||||||
else
|
|
||||||
bot = index + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ((bot + top) >> 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static jit_int32_t
|
|
||||||
offset_search_index(jit_line_t *line, jit_int32_t offset)
|
|
||||||
{
|
|
||||||
jit_int32_t bot;
|
|
||||||
jit_int32_t top;
|
|
||||||
jit_int32_t index;
|
|
||||||
jit_int32_t *offsets;
|
|
||||||
|
|
||||||
bot = 0;
|
|
||||||
top = line->length;
|
|
||||||
offsets = line->offsets;
|
|
||||||
for (index = (bot + top) >> 1; bot < top; index = (bot + top) >> 1) {
|
|
||||||
if (offset < offsets[index])
|
|
||||||
top = index;
|
|
||||||
/* offset should be already verified to be in range */
|
|
||||||
else if (index == line->length - 1 ||
|
|
||||||
(offset >= offsets[index] && offset < offsets[index + 1]))
|
|
||||||
break;
|
|
||||||
else
|
|
||||||
bot = index + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (index);
|
|
||||||
}
|
|
367
jit/print.c
367
jit/print.c
|
@ -1,367 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2012-2018 Free Software Foundation, Inc.
|
|
||||||
*
|
|
||||||
* This file is part of GNU lightning.
|
|
||||||
*
|
|
||||||
* GNU lightning is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU Lesser General Public License as published
|
|
||||||
* by the Free Software Foundation; either version 3, or (at your option)
|
|
||||||
* any later version.
|
|
||||||
*
|
|
||||||
* GNU lightning 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 Lesser General Public
|
|
||||||
* License for more details.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Paulo Cesar Pereira de Andrade
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "jit.h"
|
|
||||||
#include "jit/jit_private.h"
|
|
||||||
|
|
||||||
#define print_chr(value) fputc(value, stdout)
|
|
||||||
#define print_hex(value) fprintf(stdout, "0x%lx", value)
|
|
||||||
#define print_dec(value) fprintf(stdout, "%ld", value)
|
|
||||||
#define print_flt(value) fprintf(stdout, "%g", value)
|
|
||||||
#define print_str(value) fprintf(stdout, "%s", value)
|
|
||||||
#define print_ptr(value) fprintf(stdout, "%p", value)
|
|
||||||
#define print_reg(value) \
|
|
||||||
do { \
|
|
||||||
if ((value) & jit_regno_patch) \
|
|
||||||
print_chr('?'); \
|
|
||||||
print_str(_rvs[jit_regno(value)].name); \
|
|
||||||
} while (0)
|
|
||||||
#define print_arg(value) \
|
|
||||||
do { \
|
|
||||||
print_chr('#'); \
|
|
||||||
if (value) \
|
|
||||||
print_dec((value)->v.w); \
|
|
||||||
else \
|
|
||||||
print_chr('?'); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialization
|
|
||||||
*/
|
|
||||||
#include "names.c"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Implementation
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
_jit_print(jit_state_t *_jit)
|
|
||||||
{
|
|
||||||
jit_node_t *node;
|
|
||||||
|
|
||||||
if ((node = _jitc->head)) {
|
|
||||||
jit_print_node(node);
|
|
||||||
for (node = node->next; node; node = node->next) {
|
|
||||||
print_chr('\n');
|
|
||||||
jit_print_node(node);
|
|
||||||
}
|
|
||||||
print_chr('\n');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
_jit_print_node(jit_state_t *_jit, jit_node_t *node)
|
|
||||||
{
|
|
||||||
jit_block_t *block;
|
|
||||||
jit_int32_t value;
|
|
||||||
jit_int32_t offset;
|
|
||||||
|
|
||||||
if (node->code == jit_code_label ||
|
|
||||||
node->code == jit_code_prolog || node->code == jit_code_epilog) {
|
|
||||||
print_chr('L');
|
|
||||||
print_dec(node->v.w);
|
|
||||||
print_chr(':');
|
|
||||||
block = _jitc->blocks.ptr + node->v.w;
|
|
||||||
for (offset = 0; offset < _jitc->reglen; offset++) {
|
|
||||||
if (jit_regset_tstbit(&block->reglive, offset)) {
|
|
||||||
print_chr(' ');
|
|
||||||
print_reg(offset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (node->code == jit_code_prolog ||
|
|
||||||
node->code == jit_code_epilog) {
|
|
||||||
print_str(" /* ");
|
|
||||||
print_str(code_name[node->code]);
|
|
||||||
print_str(" */");
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
value = jit_classify(node->code) &
|
|
||||||
(jit_cc_a0_int|jit_cc_a0_flt|jit_cc_a0_dbl|jit_cc_a0_jmp|
|
|
||||||
jit_cc_a0_reg|jit_cc_a0_rlh|jit_cc_a0_arg|
|
|
||||||
jit_cc_a1_reg|jit_cc_a1_int|jit_cc_a1_flt|jit_cc_a1_dbl|jit_cc_a1_arg|
|
|
||||||
jit_cc_a2_reg|jit_cc_a2_int|jit_cc_a2_flt|jit_cc_a2_dbl);
|
|
||||||
if (!(node->flag & jit_flag_synth) && ((value & jit_cc_a0_jmp) ||
|
|
||||||
node->code == jit_code_finishr ||
|
|
||||||
node->code == jit_code_finishi))
|
|
||||||
print_str(" ");
|
|
||||||
else
|
|
||||||
print_chr('\t');
|
|
||||||
if (node->flag & jit_flag_synth)
|
|
||||||
print_str(" \\__ ");
|
|
||||||
print_str(code_name[node->code]);
|
|
||||||
switch (node->code) {
|
|
||||||
r:
|
|
||||||
print_chr(' '); print_reg(node->u.w); return;
|
|
||||||
w:
|
|
||||||
print_chr(' '); print_hex(node->u.w); return;
|
|
||||||
f:
|
|
||||||
print_chr(' ');
|
|
||||||
if (node->flag & jit_flag_data)
|
|
||||||
print_flt(*(jit_float32_t *)node->u.n->u.w);
|
|
||||||
else
|
|
||||||
print_flt(node->u.f);
|
|
||||||
return;
|
|
||||||
d:
|
|
||||||
print_chr(' ');
|
|
||||||
if (node->flag & jit_flag_data)
|
|
||||||
print_flt(*(jit_float64_t *)node->u.n->u.w);
|
|
||||||
else
|
|
||||||
print_flt(node->u.d);
|
|
||||||
return;
|
|
||||||
n:
|
|
||||||
print_chr(' ');
|
|
||||||
if (!(node->flag & jit_flag_node))
|
|
||||||
print_ptr(node->u.p);
|
|
||||||
else {
|
|
||||||
print_chr('L');
|
|
||||||
print_dec(node->u.n->v.w);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
a:
|
|
||||||
print_chr(' '); print_arg(node); return;
|
|
||||||
r_r:
|
|
||||||
print_chr(' '); print_reg(node->u.w);
|
|
||||||
print_chr(' '); print_reg(node->v.w); return;
|
|
||||||
r_w:
|
|
||||||
print_chr(' '); print_reg(node->u.w);
|
|
||||||
print_chr(' '); print_hex(node->v.w); return;
|
|
||||||
r_f:
|
|
||||||
print_chr(' '); print_reg(node->u.w);
|
|
||||||
print_chr(' ');
|
|
||||||
if (node->flag & jit_flag_data)
|
|
||||||
print_flt(*(jit_float32_t *)node->v.n->u.w);
|
|
||||||
else
|
|
||||||
print_flt(node->v.f);
|
|
||||||
return;
|
|
||||||
r_d:
|
|
||||||
print_chr(' '); print_reg(node->u.w);
|
|
||||||
print_chr(' ');
|
|
||||||
if (node->flag & jit_flag_data)
|
|
||||||
print_flt(*(jit_float64_t *)node->v.n->u.w);
|
|
||||||
else
|
|
||||||
print_flt(node->v.d);
|
|
||||||
return;
|
|
||||||
r_a:
|
|
||||||
print_chr(' '); print_reg(node->u.w);
|
|
||||||
print_chr(' '); print_arg(node->v.n);
|
|
||||||
return;
|
|
||||||
w_r:
|
|
||||||
print_chr(' '); print_hex(node->u.w);
|
|
||||||
print_chr(' '); print_reg(node->v.w); return;
|
|
||||||
w_w:
|
|
||||||
print_chr(' '); print_hex(node->u.w);
|
|
||||||
print_chr(' '); print_hex(node->v.w); return;
|
|
||||||
w_a:
|
|
||||||
print_chr(' '); print_hex(node->u.w);
|
|
||||||
print_chr(' '); print_arg(node->v.n);
|
|
||||||
return;
|
|
||||||
f_a:
|
|
||||||
print_chr(' ');
|
|
||||||
if (node->flag & jit_flag_data)
|
|
||||||
print_flt(*(jit_float32_t *)node->u.n->u.w);
|
|
||||||
else
|
|
||||||
print_flt(node->u.f);
|
|
||||||
print_chr(' '); print_arg(node->v.n);
|
|
||||||
return;
|
|
||||||
d_a:
|
|
||||||
print_chr(' ');
|
|
||||||
if (node->flag & jit_flag_data)
|
|
||||||
print_flt(*(jit_float64_t *)node->u.n->u.w);
|
|
||||||
else
|
|
||||||
print_flt(node->u.d);
|
|
||||||
print_chr(' '); print_arg(node->v.n);
|
|
||||||
return;
|
|
||||||
r_r_r:
|
|
||||||
print_chr(' '); print_reg(node->u.w);
|
|
||||||
print_chr(' '); print_reg(node->v.w);
|
|
||||||
print_chr(' '); print_reg(node->w.w); return;
|
|
||||||
r_r_w:
|
|
||||||
print_chr(' '); print_reg(node->u.w);
|
|
||||||
print_chr(' '); print_reg(node->v.w);
|
|
||||||
print_chr(' '); print_hex(node->w.w); return;
|
|
||||||
q_r_r:
|
|
||||||
print_str(" ("); print_reg(node->u.q.l);
|
|
||||||
print_chr(' '); print_reg(node->u.q.h);
|
|
||||||
print_str(") "); print_reg(node->v.w);
|
|
||||||
print_chr(' '); print_reg(node->w.w); return;
|
|
||||||
q_r_w:
|
|
||||||
print_str(" ("); print_reg(node->u.q.l);
|
|
||||||
print_chr(' '); print_reg(node->u.q.h);
|
|
||||||
print_str(") "); print_reg(node->v.w);
|
|
||||||
print_chr(' '); print_hex(node->w.w); return;
|
|
||||||
r_r_f:
|
|
||||||
print_chr(' '); print_reg(node->u.w);
|
|
||||||
print_chr(' '); print_reg(node->v.w);
|
|
||||||
print_chr(' ');
|
|
||||||
if (node->flag & jit_flag_data)
|
|
||||||
print_flt(*(jit_float32_t *)node->w.n->u.w);
|
|
||||||
else
|
|
||||||
print_flt(node->w.f);
|
|
||||||
return;
|
|
||||||
r_r_d:
|
|
||||||
print_chr(' '); print_reg(node->u.w);
|
|
||||||
print_chr(' '); print_reg(node->v.w);
|
|
||||||
print_chr(' ');
|
|
||||||
if (node->flag & jit_flag_data)
|
|
||||||
print_flt(*(jit_float64_t *)node->w.n->u.w);
|
|
||||||
else
|
|
||||||
print_flt(node->w.d);
|
|
||||||
return;
|
|
||||||
w_r_r:
|
|
||||||
print_chr(' '); print_hex(node->u.w);
|
|
||||||
print_chr(' '); print_reg(node->v.w);
|
|
||||||
print_chr(' '); print_reg(node->w.w); return;
|
|
||||||
n_r_r:
|
|
||||||
print_chr(' ');
|
|
||||||
if (!(node->flag & jit_flag_node))
|
|
||||||
print_ptr(node->u.p);
|
|
||||||
else {
|
|
||||||
print_chr('L');
|
|
||||||
print_dec(node->u.n->v.w);
|
|
||||||
}
|
|
||||||
print_chr(' '); print_reg(node->v.w);
|
|
||||||
print_chr(' '); print_reg(node->w.w); return;
|
|
||||||
n_r_w:
|
|
||||||
print_chr(' ');
|
|
||||||
if (!(node->flag & jit_flag_node))
|
|
||||||
print_ptr(node->u.p);
|
|
||||||
else {
|
|
||||||
print_chr('L');
|
|
||||||
print_dec(node->u.n->v.w);
|
|
||||||
}
|
|
||||||
print_chr(' '); print_reg(node->v.w);
|
|
||||||
print_chr(' '); print_hex(node->w.w); return;
|
|
||||||
n_r_f:
|
|
||||||
print_chr(' ');
|
|
||||||
if (!(node->flag & jit_flag_node))
|
|
||||||
print_ptr(node->u.p);
|
|
||||||
else{
|
|
||||||
print_chr('L');
|
|
||||||
print_dec(node->u.n->v.w);
|
|
||||||
}
|
|
||||||
print_chr(' '); print_reg(node->v.w);
|
|
||||||
print_chr(' ');
|
|
||||||
if (node->flag & jit_flag_data)
|
|
||||||
print_flt(*(jit_float32_t *)node->w.n->u.w);
|
|
||||||
else
|
|
||||||
print_flt(node->w.f);
|
|
||||||
return;
|
|
||||||
n_r_d:
|
|
||||||
print_chr(' ');
|
|
||||||
if (!(node->flag & jit_flag_node))
|
|
||||||
print_ptr(node->u.p);
|
|
||||||
else {
|
|
||||||
print_chr('L');
|
|
||||||
print_dec(node->u.n->v.w);
|
|
||||||
}
|
|
||||||
print_chr(' '); print_reg(node->v.w);
|
|
||||||
print_chr(' ');
|
|
||||||
if (node->flag & jit_flag_data)
|
|
||||||
print_flt(*(jit_float64_t *)node->w.n->u.w);
|
|
||||||
else
|
|
||||||
print_flt(node->w.d);
|
|
||||||
return;
|
|
||||||
case jit_code_name:
|
|
||||||
print_chr(' ');
|
|
||||||
if (node->v.p && _jitc->emit)
|
|
||||||
print_str(node->v.n->u.p);
|
|
||||||
break;
|
|
||||||
case jit_code_note:
|
|
||||||
print_chr(' ');
|
|
||||||
if (node->v.p && _jitc->emit)
|
|
||||||
print_str(node->v.n->u.p);
|
|
||||||
if (node->v.p && _jitc->emit && node->w.w)
|
|
||||||
print_chr(':');
|
|
||||||
if (node->w.w)
|
|
||||||
print_dec(node->w.w);
|
|
||||||
break;
|
|
||||||
case jit_code_data:
|
|
||||||
case jit_code_label:
|
|
||||||
case jit_code_ellipsis:
|
|
||||||
case jit_code_prolog: case jit_code_epilog:
|
|
||||||
case jit_code_ret: case jit_code_prepare:
|
|
||||||
break;
|
|
||||||
case jit_code_save: case jit_code_load:
|
|
||||||
goto r;
|
|
||||||
default:
|
|
||||||
switch (value) {
|
|
||||||
case jit_cc_a0_reg:
|
|
||||||
case jit_cc_a0_reg|jit_cc_a0_chg:
|
|
||||||
case jit_cc_a0_reg|jit_cc_a0_jmp:
|
|
||||||
goto r;
|
|
||||||
case jit_cc_a0_int:
|
|
||||||
goto w;
|
|
||||||
case jit_cc_a0_flt:
|
|
||||||
goto f;
|
|
||||||
case jit_cc_a0_dbl:
|
|
||||||
goto d;
|
|
||||||
case jit_cc_a0_jmp:
|
|
||||||
goto n;
|
|
||||||
case jit_cc_a0_int|jit_cc_a0_arg:
|
|
||||||
goto a;
|
|
||||||
case jit_cc_a0_reg|jit_cc_a1_reg:
|
|
||||||
goto r_r;
|
|
||||||
case jit_cc_a0_reg|jit_cc_a1_int:
|
|
||||||
goto r_w;
|
|
||||||
case jit_cc_a0_reg|jit_cc_a1_flt:
|
|
||||||
goto r_f;
|
|
||||||
case jit_cc_a0_reg|jit_cc_a1_dbl:
|
|
||||||
goto r_d;
|
|
||||||
case jit_cc_a0_reg|jit_cc_a1_arg:
|
|
||||||
goto r_a;
|
|
||||||
case jit_cc_a0_int|jit_cc_a1_reg:
|
|
||||||
goto w_r;
|
|
||||||
case jit_cc_a0_int|jit_cc_a1_int:
|
|
||||||
goto w_w;
|
|
||||||
case jit_cc_a0_int|jit_cc_a1_arg:
|
|
||||||
goto w_a;
|
|
||||||
case jit_cc_a0_flt|jit_cc_a1_arg:
|
|
||||||
goto f_a;
|
|
||||||
case jit_cc_a0_dbl|jit_cc_a1_arg:
|
|
||||||
goto d_a;
|
|
||||||
case jit_cc_a0_reg|jit_cc_a1_reg|jit_cc_a2_reg:
|
|
||||||
goto r_r_r;
|
|
||||||
case jit_cc_a0_reg|jit_cc_a1_reg|jit_cc_a2_int:
|
|
||||||
goto r_r_w;
|
|
||||||
case jit_cc_a0_reg|jit_cc_a0_rlh|
|
|
||||||
jit_cc_a1_reg|jit_cc_a2_reg:
|
|
||||||
goto q_r_r;
|
|
||||||
case jit_cc_a0_reg|jit_cc_a0_rlh|
|
|
||||||
jit_cc_a1_reg|jit_cc_a2_int:
|
|
||||||
goto q_r_w;
|
|
||||||
case jit_cc_a0_reg|jit_cc_a1_reg|jit_cc_a2_flt:
|
|
||||||
goto r_r_f;
|
|
||||||
case jit_cc_a0_reg|jit_cc_a1_reg|jit_cc_a2_dbl:
|
|
||||||
goto r_r_d;
|
|
||||||
case jit_cc_a0_int|jit_cc_a1_reg|jit_cc_a2_reg:
|
|
||||||
goto w_r_r;
|
|
||||||
case jit_cc_a0_jmp|jit_cc_a1_reg|jit_cc_a2_reg:
|
|
||||||
goto n_r_r;
|
|
||||||
case jit_cc_a0_jmp|jit_cc_a1_reg|jit_cc_a2_int:
|
|
||||||
goto n_r_w;
|
|
||||||
case jit_cc_a0_jmp|jit_cc_a1_reg|jit_cc_a2_flt:
|
|
||||||
goto n_r_f;
|
|
||||||
case jit_cc_a0_jmp|jit_cc_a1_reg|jit_cc_a2_dbl:
|
|
||||||
goto n_r_d;
|
|
||||||
default:
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
192
jit/rewind.c
192
jit/rewind.c
|
@ -1,192 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2015-2018 Free Software Foundation, Inc.
|
|
||||||
*
|
|
||||||
* This file is part of GNU lightning.
|
|
||||||
*
|
|
||||||
* GNU lightning is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU Lesser General Public License as published
|
|
||||||
* by the Free Software Foundation; either version 3, or (at your option)
|
|
||||||
* any later version.
|
|
||||||
*
|
|
||||||
* GNU lightning 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 Lesser General Public
|
|
||||||
* License for more details.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Paulo Cesar Pereira de Andrade
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "jit.h"
|
|
||||||
#include "jit/jit_private.h"
|
|
||||||
|
|
||||||
#if PROTO
|
|
||||||
# define free_synth_list(node) _free_synth_list(_jit,node)
|
|
||||||
static jit_node_t *_free_synth_list(jit_state_t*,jit_node_t*);
|
|
||||||
#define rewind_prolog() _rewind_prolog(_jit)
|
|
||||||
static void _rewind_prolog(jit_state_t*);
|
|
||||||
#define rewind_prepare() _rewind_prepare(_jit)
|
|
||||||
static void _rewind_prepare(jit_state_t*);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if CODE
|
|
||||||
/*
|
|
||||||
* Implementation
|
|
||||||
*/
|
|
||||||
static jit_node_t *
|
|
||||||
_free_synth_list(jit_state_t *_jit, jit_node_t *node)
|
|
||||||
{
|
|
||||||
jit_node_t *next;
|
|
||||||
next = node->next;
|
|
||||||
free_node(node);
|
|
||||||
for (node = next; node && (node->flag & jit_flag_synth); node = next) {
|
|
||||||
next = node->next;
|
|
||||||
free_node(node);
|
|
||||||
}
|
|
||||||
return (next);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
_rewind_prolog(jit_state_t *_jit)
|
|
||||||
{
|
|
||||||
jit_node_t *node;
|
|
||||||
jit_node_t *next;
|
|
||||||
_jitc->function->self.size = stack_framesize;
|
|
||||||
#if __arm__
|
|
||||||
assert(jit_cpu.abi);
|
|
||||||
_jitc->function->self.size += 64;
|
|
||||||
#endif
|
|
||||||
#if __mips__ && NEW_ABI
|
|
||||||
/* Only add extra stack space if there are varargs
|
|
||||||
* arguments in registers. */
|
|
||||||
assert(jit_arg_reg_p(_jitc->function->self.argi));
|
|
||||||
_jitc->function->self.size += 64;
|
|
||||||
#endif
|
|
||||||
_jitc->function->self.argi =
|
|
||||||
_jitc->function->self.argf = _jitc->function->self.argn = 0;
|
|
||||||
_jitc->tail = _jitc->function->prolog;
|
|
||||||
node = _jitc->tail->next;
|
|
||||||
_jitc->tail->next = (jit_node_t *)0;
|
|
||||||
_jitc->tail->link = (jit_node_t *)0;
|
|
||||||
for (; node; node = next) {
|
|
||||||
next = node->next;
|
|
||||||
switch (node->code) {
|
|
||||||
case jit_code_arg:
|
|
||||||
node->next = (jit_node_t *)0;
|
|
||||||
jit_make_arg(node);
|
|
||||||
break;
|
|
||||||
case jit_code_arg_f:
|
|
||||||
node->next = (jit_node_t *)0;
|
|
||||||
jit_make_arg_f(node);
|
|
||||||
break;
|
|
||||||
case jit_code_arg_d:
|
|
||||||
node->next = (jit_node_t *)0;
|
|
||||||
jit_make_arg_d(node);
|
|
||||||
break;
|
|
||||||
case jit_code_getarg_c:
|
|
||||||
jit_getarg_c(node->u.w, node->v.n);
|
|
||||||
next = free_synth_list(node);
|
|
||||||
break;
|
|
||||||
case jit_code_getarg_uc:
|
|
||||||
jit_getarg_uc(node->u.w, node->v.n);
|
|
||||||
next = free_synth_list(node);
|
|
||||||
break;
|
|
||||||
case jit_code_getarg_s:
|
|
||||||
jit_getarg_s(node->u.w, node->v.n);
|
|
||||||
next = free_synth_list(node);
|
|
||||||
break;
|
|
||||||
case jit_code_getarg_us:
|
|
||||||
jit_getarg_us(node->u.w, node->v.n);
|
|
||||||
next = free_synth_list(node);
|
|
||||||
break;
|
|
||||||
case jit_code_getarg_i:
|
|
||||||
jit_getarg_i(node->u.w, node->v.n);
|
|
||||||
next = free_synth_list(node);
|
|
||||||
break;
|
|
||||||
case jit_code_getarg_f:
|
|
||||||
jit_getarg_f(node->u.w, node->v.n);
|
|
||||||
next = free_synth_list(node);
|
|
||||||
break;
|
|
||||||
case jit_code_getarg_d:
|
|
||||||
jit_getarg_d(node->u.w, node->v.n);
|
|
||||||
next = free_synth_list(node);
|
|
||||||
break;
|
|
||||||
case jit_code_putargr:
|
|
||||||
jit_putargr(node->u.w, node->v.n);
|
|
||||||
next = free_synth_list(node);
|
|
||||||
break;
|
|
||||||
case jit_code_putargi:
|
|
||||||
jit_putargi(node->u.w, node->v.n);
|
|
||||||
next = free_synth_list(node);
|
|
||||||
break;
|
|
||||||
case jit_code_putargr_f:
|
|
||||||
jit_putargr_f(node->u.w, node->v.n);
|
|
||||||
next = free_synth_list(node);
|
|
||||||
break;
|
|
||||||
case jit_code_putargi_f:
|
|
||||||
jit_putargi_f(node->u.f, node->v.n);
|
|
||||||
next = free_synth_list(node);
|
|
||||||
break;
|
|
||||||
case jit_code_putargr_d:
|
|
||||||
jit_putargr_d(node->u.w, node->v.n);
|
|
||||||
next = free_synth_list(node);
|
|
||||||
break;
|
|
||||||
case jit_code_putargi_d:
|
|
||||||
jit_putargi_d(node->u.d, node->v.n);
|
|
||||||
next = free_synth_list(node);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
node->next = (jit_node_t *)0;
|
|
||||||
link_node(node);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
_rewind_prepare(jit_state_t *_jit)
|
|
||||||
{
|
|
||||||
jit_node_t *node;
|
|
||||||
jit_node_t *next;
|
|
||||||
_jitc->function->call.argi =
|
|
||||||
_jitc->function->call.argf =
|
|
||||||
_jitc->function->call.size = 0;
|
|
||||||
_jitc->tail = _jitc->prepare;
|
|
||||||
node = _jitc->tail->next;
|
|
||||||
_jitc->tail->next = (jit_node_t *)0;
|
|
||||||
_jitc->tail->link = (jit_node_t *)0;
|
|
||||||
for (; node; node = next) {
|
|
||||||
next = node->next;
|
|
||||||
switch (node->code) {
|
|
||||||
case jit_code_pushargr:
|
|
||||||
jit_pushargr(node->u.w);
|
|
||||||
next = free_synth_list(node);
|
|
||||||
break;
|
|
||||||
case jit_code_pushargi:
|
|
||||||
jit_pushargi(node->u.w);
|
|
||||||
next = free_synth_list(node);
|
|
||||||
break;
|
|
||||||
case jit_code_pushargr_f:
|
|
||||||
jit_pushargr_f(node->u.w);
|
|
||||||
next = free_synth_list(node);
|
|
||||||
break;
|
|
||||||
case jit_code_pushargi_f:
|
|
||||||
jit_pushargi_f(node->u.f);
|
|
||||||
next = free_synth_list(node);
|
|
||||||
break;
|
|
||||||
case jit_code_pushargr_d:
|
|
||||||
jit_pushargr_d(node->u.w);
|
|
||||||
next = free_synth_list(node);
|
|
||||||
break;
|
|
||||||
case jit_code_pushargi_d:
|
|
||||||
jit_pushargi_d(node->u.d);
|
|
||||||
next = free_synth_list(node);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
node->next = (jit_node_t *)0;
|
|
||||||
link_node(node);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
130
jit/size.c
130
jit/size.c
|
@ -1,130 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2013-2018 Free Software Foundation, Inc.
|
|
||||||
*
|
|
||||||
* This file is part of GNU lightning.
|
|
||||||
*
|
|
||||||
* GNU lightning is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU Lesser General Public License as published
|
|
||||||
* by the Free Software Foundation; either version 3, or (at your option)
|
|
||||||
* any later version.
|
|
||||||
*
|
|
||||||
* GNU lightning 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 Lesser General Public
|
|
||||||
* License for more details.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Paulo Cesar Pereira de Andrade
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "jit.h"
|
|
||||||
#include "jit/jit_private.h"
|
|
||||||
#if GET_JIT_SIZE
|
|
||||||
# include <stdio.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialization
|
|
||||||
*/
|
|
||||||
static jit_int16_t _szs[jit_code_last_code] = {
|
|
||||||
#if GET_JIT_SIZE
|
|
||||||
# define JIT_INSTR_MAX 256
|
|
||||||
#else
|
|
||||||
# if defined(__i386__) || defined(__x86_64__)
|
|
||||||
# include "x86-sz.c"
|
|
||||||
# elif defined(__mips__)
|
|
||||||
# include "mips-sz.c"
|
|
||||||
# elif defined(__arm__)
|
|
||||||
# include "arm-sz.c"
|
|
||||||
# elif defined(__ppc__) || defined(__powerpc__)
|
|
||||||
# include "ppc-sz.c"
|
|
||||||
# elif defined(__sparc__)
|
|
||||||
# include "sparc-sz.c"
|
|
||||||
# elif defined(__ia64__)
|
|
||||||
# include "ia64-sz.c"
|
|
||||||
# elif defined(__hppa__)
|
|
||||||
# include "hppa-sz.c"
|
|
||||||
# elif defined(__aarch64__)
|
|
||||||
# include "aarch64-sz.c"
|
|
||||||
# elif defined(__s390__) || defined(__s390x__)
|
|
||||||
# include "s390-sz.c"
|
|
||||||
# elif defined(__alpha__)
|
|
||||||
# include "alpha-sz.c"
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Implementation
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
jit_init_size(void)
|
|
||||||
{
|
|
||||||
#if DEBUG
|
|
||||||
# if !GET_JIT_SIZE
|
|
||||||
jit_word_t offset;
|
|
||||||
|
|
||||||
for (offset = 0; offset < jit_size(_szs); offset++)
|
|
||||||
if (_szs[offset] != 0)
|
|
||||||
return;
|
|
||||||
/* Ensure data was collected */
|
|
||||||
abort();
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#if GET_JIT_SIZE
|
|
||||||
void
|
|
||||||
_jit_size_prepare(jit_state_t *_jit)
|
|
||||||
{
|
|
||||||
_jitc->cptr = _jit->code.ptr;
|
|
||||||
_jitc->size = _jit->pc.w;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
_jit_size_collect(jit_state_t *_jit, jit_node_t *node)
|
|
||||||
{
|
|
||||||
jit_word_t length;
|
|
||||||
|
|
||||||
if (_jitc->cptr == _jit->code.ptr) {
|
|
||||||
length = _jit->pc.w - _jitc->size;
|
|
||||||
if (_szs[node->code] < length)
|
|
||||||
_szs[node->code] = length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
jit_word_t
|
|
||||||
_jit_get_size(jit_state_t *_jit)
|
|
||||||
{
|
|
||||||
jit_word_t size;
|
|
||||||
jit_node_t *node;
|
|
||||||
|
|
||||||
for (size = JIT_INSTR_MAX, node = _jitc->head; node; node = node->next)
|
|
||||||
size += _szs[node->code];
|
|
||||||
|
|
||||||
return ((size + 4095) & -4096);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
jit_word_t
|
|
||||||
jit_get_max_instr(void)
|
|
||||||
{
|
|
||||||
return (JIT_INSTR_MAX >= 144 ? JIT_INSTR_MAX : 144);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
jit_finish_size(void)
|
|
||||||
{
|
|
||||||
#if GET_JIT_SIZE
|
|
||||||
FILE *fp;
|
|
||||||
jit_word_t offset;
|
|
||||||
|
|
||||||
/* Define a single path */
|
|
||||||
fp = fopen(JIT_SIZE_PATH, "a");
|
|
||||||
assert(fp);
|
|
||||||
for (offset = 0; offset < jit_size(_szs); offset++)
|
|
||||||
fprintf(fp, "%d %d\n", offset, _szs[offset]);
|
|
||||||
fclose(fp);
|
|
||||||
#endif
|
|
||||||
}
|
|
Loading…
Add table
Add a link
Reference in a new issue