mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-02 21:10:27 +02:00
*include/lightning.h, lib/lightning.c: Add the new jit_live code to explicitly mark a register as live. It is required to avoid assuming functions always return a value in the gpr and fpr return register, and to avoid the need of some very specialized codes that vary too much from backend to backend, to instruct the optimization code the return register is live. * lib/jit_arm.c, lib/jit_mips.c, lib/jit_ppc.c, lib/jit_print.c, lib/jit_x86.c: Update for the new jit_live code. * check/ret.ok, check/ret.tst: New files implementing a simple test case that would previously fail at least in ix86/x86_64. * check/Makefile.am: Update for new "ret" test case.
464 lines
12 KiB
C
464 lines
12 KiB
C
/*
|
|
* Copyright (C) 2012 Free Software Foundation, Inc.
|
|
*
|
|
* This 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 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This software 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.
|
|
*
|
|
* Authors:
|
|
* Paulo Cesar Pereira de Andrade
|
|
*/
|
|
|
|
#include <lightning.h>
|
|
#include <lightning/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)
|
|
|
|
/*
|
|
* Initialization
|
|
*/
|
|
static char *code_name[] = {
|
|
"data",
|
|
"live",
|
|
"save", "load",
|
|
"#name", "#note",
|
|
"label",
|
|
"prolog",
|
|
"arg",
|
|
"addr", "addi",
|
|
"addcr", "addci",
|
|
"addxr", "addxi",
|
|
"subr", "subi",
|
|
"subcr", "subci",
|
|
"subxr", "subxi",
|
|
"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",
|
|
"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",
|
|
"epilog",
|
|
"arg_f",
|
|
"addr_f", "addi_f",
|
|
"subr_f", "subi_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",
|
|
"arg_d",
|
|
"addr_d", "addi_d",
|
|
"subr_d", "subi_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",
|
|
"movr_w_f", "movr_ww_d",
|
|
"movr_f_w", "movi_f_w",
|
|
"movr_d_ww", "movi_d_ww",
|
|
"x86_retval_f", "x86_retval_d",
|
|
};
|
|
|
|
/*
|
|
* Implementation
|
|
*/
|
|
void
|
|
_jit_print(jit_state_t *_jit)
|
|
{
|
|
jit_node_t *node;
|
|
jit_block_t *block;
|
|
jit_bool_t first;
|
|
jit_int32_t value;
|
|
jit_int32_t offset;
|
|
|
|
first = 0;
|
|
for (node = _jit->head; node; node = node->next) {
|
|
if (!first)
|
|
print_chr('\n');
|
|
else
|
|
first = 0;
|
|
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 = _jit->blocks.ptr + node->v.w;
|
|
for (offset = 0; offset < _jit->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(" */");
|
|
}
|
|
continue;
|
|
}
|
|
value = jit_classify(node->code) &
|
|
(jit_cc_a0_int|jit_cc_a0_jmp|jit_cc_a0_reg|jit_cc_a0_rlh|
|
|
jit_cc_a1_reg|jit_cc_a1_int|jit_cc_a1_flt|jit_cc_a1_dbl|
|
|
jit_cc_a2_reg|jit_cc_a2_int|jit_cc_a2_flt|jit_cc_a2_dbl);
|
|
if (value & jit_cc_a0_jmp)
|
|
print_str(" ");
|
|
else
|
|
print_chr('\t');
|
|
print_str(code_name[node->code]);
|
|
switch (node->code) {
|
|
r:
|
|
print_chr(' '); print_reg(node->u.w); continue;
|
|
w:
|
|
print_chr(' '); print_hex(node->u.w); continue;
|
|
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);
|
|
}
|
|
continue;
|
|
r_r:
|
|
print_chr(' '); print_reg(node->u.w);
|
|
print_chr(' '); print_reg(node->v.w); continue;
|
|
r_w:
|
|
print_chr(' '); print_reg(node->u.w);
|
|
print_chr(' '); print_hex(node->v.w); continue;
|
|
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);
|
|
continue;
|
|
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);
|
|
continue;
|
|
w_r:
|
|
print_chr(' '); print_hex(node->u.w);
|
|
print_chr(' '); print_reg(node->v.w); continue;
|
|
r_r_r:
|
|
print_chr(' '); print_reg(node->u.w);
|
|
print_chr(' '); print_reg(node->v.w);
|
|
print_chr(' '); print_reg(node->w.w); continue;
|
|
r_r_w:
|
|
print_chr(' '); print_reg(node->u.w);
|
|
print_chr(' '); print_reg(node->v.w);
|
|
print_chr(' '); print_hex(node->w.w); continue;
|
|
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); continue;
|
|
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); continue;
|
|
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);
|
|
continue;
|
|
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);
|
|
continue;
|
|
w_r_r:
|
|
print_chr(' '); print_hex(node->u.w);
|
|
print_chr(' '); print_reg(node->v.w);
|
|
print_chr(' '); print_reg(node->w.w); continue;
|
|
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); continue;
|
|
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); continue;
|
|
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);
|
|
continue;
|
|
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);
|
|
continue;
|
|
case jit_code_name:
|
|
print_chr(' ');
|
|
if (node->v.p)
|
|
print_str(node->v.n->u.p);
|
|
break;
|
|
case jit_code_note:
|
|
print_chr(' ');
|
|
if (node->v.p)
|
|
print_str(node->v.n->u.p);
|
|
if (node->v.p && 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_prolog: case jit_code_epilog:
|
|
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_jmp:
|
|
goto n;
|
|
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_int|jit_cc_a1_reg:
|
|
goto w_r;
|
|
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;
|
|
}
|
|
}
|
|
print_chr('\n');
|
|
}
|