Revision b03cce8e tcg/tcg.c
b/tcg/tcg.c | ||
---|---|---|
242 | 242 |
} |
243 | 243 |
|
244 | 244 |
tcg_target_init(s); |
245 |
|
|
246 |
/* init global prologue and epilogue */ |
|
247 |
s->code_buf = code_gen_prologue; |
|
248 |
s->code_ptr = s->code_buf; |
|
249 |
tcg_target_qemu_prologue(s); |
|
250 |
flush_icache_range((unsigned long)s->code_buf, |
|
251 |
(unsigned long)s->code_ptr); |
|
245 | 252 |
} |
246 | 253 |
|
247 | 254 |
void tcg_set_frame(TCGContext *s, int reg, |
... | ... | |
680 | 687 |
nb_oargs = arg >> 16; |
681 | 688 |
nb_iargs = arg & 0xffff; |
682 | 689 |
nb_cargs = def->nb_cargs; |
683 |
} else if (c == INDEX_op_nopn) { |
|
684 |
/* variable number of arguments */ |
|
685 |
nb_cargs = *args; |
|
686 |
nb_oargs = 0; |
|
687 |
nb_iargs = 0; |
|
688 |
} else { |
|
689 |
nb_oargs = def->nb_oargs; |
|
690 |
nb_iargs = def->nb_iargs; |
|
691 |
nb_cargs = def->nb_cargs; |
|
692 |
} |
|
693 | 690 |
|
694 |
k = 0; |
|
695 |
for(i = 0; i < nb_oargs; i++) { |
|
696 |
if (k != 0) |
|
697 |
fprintf(outfile, ","); |
|
698 |
fprintf(outfile, "%s", |
|
699 |
tcg_get_arg_str_idx(s, buf, sizeof(buf), args[k++])); |
|
700 |
} |
|
701 |
for(i = 0; i < nb_iargs; i++) { |
|
702 |
if (k != 0) |
|
703 |
fprintf(outfile, ","); |
|
691 |
/* function name */ |
|
704 | 692 |
/* XXX: dump helper name for call */ |
705 | 693 |
fprintf(outfile, "%s", |
706 |
tcg_get_arg_str_idx(s, buf, sizeof(buf), args[k++])); |
|
707 |
} |
|
708 |
for(i = 0; i < nb_cargs; i++) { |
|
709 |
if (k != 0) |
|
694 |
tcg_get_arg_str_idx(s, buf, sizeof(buf), args[nb_oargs + nb_iargs - 1])); |
|
695 |
/* flags */ |
|
696 |
fprintf(outfile, ",$0x%" TCG_PRIlx, |
|
697 |
args[nb_oargs + nb_iargs]); |
|
698 |
/* nb out args */ |
|
699 |
fprintf(outfile, ",$%d", nb_oargs); |
|
700 |
for(i = 0; i < nb_oargs; i++) { |
|
701 |
fprintf(outfile, ","); |
|
702 |
fprintf(outfile, "%s", |
|
703 |
tcg_get_arg_str_idx(s, buf, sizeof(buf), args[i])); |
|
704 |
} |
|
705 |
for(i = 0; i < (nb_iargs - 1); i++) { |
|
710 | 706 |
fprintf(outfile, ","); |
711 |
arg = args[k++]; |
|
712 |
fprintf(outfile, "$0x%" TCG_PRIlx, arg); |
|
707 |
fprintf(outfile, "%s", |
|
708 |
tcg_get_arg_str_idx(s, buf, sizeof(buf), args[nb_oargs + i])); |
|
709 |
} |
|
710 |
} else { |
|
711 |
if (c == INDEX_op_nopn) { |
|
712 |
/* variable number of arguments */ |
|
713 |
nb_cargs = *args; |
|
714 |
nb_oargs = 0; |
|
715 |
nb_iargs = 0; |
|
716 |
} else { |
|
717 |
nb_oargs = def->nb_oargs; |
|
718 |
nb_iargs = def->nb_iargs; |
|
719 |
nb_cargs = def->nb_cargs; |
|
720 |
} |
|
721 |
|
|
722 |
k = 0; |
|
723 |
for(i = 0; i < nb_oargs; i++) { |
|
724 |
if (k != 0) |
|
725 |
fprintf(outfile, ","); |
|
726 |
fprintf(outfile, "%s", |
|
727 |
tcg_get_arg_str_idx(s, buf, sizeof(buf), args[k++])); |
|
728 |
} |
|
729 |
for(i = 0; i < nb_iargs; i++) { |
|
730 |
if (k != 0) |
|
731 |
fprintf(outfile, ","); |
|
732 |
fprintf(outfile, "%s", |
|
733 |
tcg_get_arg_str_idx(s, buf, sizeof(buf), args[k++])); |
|
734 |
} |
|
735 |
for(i = 0; i < nb_cargs; i++) { |
|
736 |
if (k != 0) |
|
737 |
fprintf(outfile, ","); |
|
738 |
arg = args[k++]; |
|
739 |
fprintf(outfile, "$0x%" TCG_PRIlx, arg); |
|
740 |
} |
|
713 | 741 |
} |
714 | 742 |
fprintf(outfile, "\n"); |
715 | 743 |
args += nb_iargs + nb_oargs + nb_cargs; |
... | ... | |
1027 | 1055 |
/* if end of basic block, update */ |
1028 | 1056 |
if (def->flags & TCG_OPF_BB_END) { |
1029 | 1057 |
tcg_la_bb_end(s, dead_temps); |
1058 |
} else if (def->flags & TCG_OPF_CALL_CLOBBER) { |
|
1059 |
/* globals are live */ |
|
1060 |
memset(dead_temps, 0, s->nb_globals); |
|
1030 | 1061 |
} |
1031 | 1062 |
|
1032 | 1063 |
/* input args are live */ |
... | ... | |
1119 | 1150 |
ts->reg != reg) { |
1120 | 1151 |
printf("Inconsistency for register %s:\n", |
1121 | 1152 |
tcg_target_reg_names[reg]); |
1122 |
printf("reg state:\n"); |
|
1123 |
dump_regs(s); |
|
1124 |
tcg_abort(); |
|
1153 |
goto fail; |
|
1125 | 1154 |
} |
1126 | 1155 |
} |
1127 | 1156 |
} |
... | ... | |
1132 | 1161 |
s->reg_to_temp[ts->reg] != k) { |
1133 | 1162 |
printf("Inconsistency for temp %s:\n", |
1134 | 1163 |
tcg_get_arg_str_idx(s, buf, sizeof(buf), k)); |
1164 |
fail: |
|
1135 | 1165 |
printf("reg state:\n"); |
1136 | 1166 |
dump_regs(s); |
1137 | 1167 |
tcg_abort(); |
1138 | 1168 |
} |
1169 |
if (ts->val_type == TEMP_VAL_CONST && k < s->nb_globals) { |
|
1170 |
printf("constant forbidden in global %s\n", |
|
1171 |
tcg_get_arg_str_idx(s, buf, sizeof(buf), k)); |
|
1172 |
goto fail; |
|
1173 |
} |
|
1139 | 1174 |
} |
1140 | 1175 |
} |
1141 | 1176 |
#endif |
... | ... | |
1376 | 1411 |
} |
1377 | 1412 |
} |
1378 | 1413 |
|
1379 |
/* XXX: permit generic clobber register list ? */ |
|
1380 | 1414 |
if (def->flags & TCG_OPF_CALL_CLOBBER) { |
1415 |
/* XXX: permit generic clobber register list ? */ |
|
1381 | 1416 |
for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) { |
1382 | 1417 |
if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) { |
1383 | 1418 |
tcg_reg_free(s, reg); |
1384 | 1419 |
} |
1385 | 1420 |
} |
1421 |
/* XXX: for load/store we could do that only for the slow path |
|
1422 |
(i.e. when a memory callback is called) */ |
|
1423 |
|
|
1424 |
/* store globals and free associated registers (we assume the insn |
|
1425 |
can modify any global. */ |
|
1426 |
for(i = 0; i < s->nb_globals; i++) { |
|
1427 |
ts = &s->temps[i]; |
|
1428 |
if (!ts->fixed_reg) { |
|
1429 |
if (ts->val_type == TEMP_VAL_REG) { |
|
1430 |
tcg_reg_free(s, ts->reg); |
|
1431 |
} |
|
1432 |
} |
|
1433 |
} |
|
1386 | 1434 |
} |
1387 | 1435 |
|
1388 | 1436 |
/* satisfy the output constraints */ |
... | ... | |
1435 | 1483 |
} |
1436 | 1484 |
} |
1437 | 1485 |
|
1486 |
#ifdef TCG_TARGET_STACK_GROWSUP |
|
1487 |
#define STACK_DIR(x) (-(x)) |
|
1488 |
#else |
|
1489 |
#define STACK_DIR(x) (x) |
|
1490 |
#endif |
|
1491 |
|
|
1438 | 1492 |
static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def, |
1439 | 1493 |
int opc, const TCGArg *args, |
1440 | 1494 |
unsigned int dead_iargs) |
... | ... | |
1443 | 1497 |
TCGArg arg, func_arg; |
1444 | 1498 |
TCGTemp *ts; |
1445 | 1499 |
tcg_target_long stack_offset, call_stack_size, func_addr; |
1446 |
int const_func_arg; |
|
1500 |
int const_func_arg, allocate_args;
|
|
1447 | 1501 |
TCGRegSet allocated_regs; |
1448 | 1502 |
const TCGArgConstraint *arg_ct; |
1449 | 1503 |
|
... | ... | |
1464 | 1518 |
call_stack_size = (nb_params - nb_regs) * sizeof(tcg_target_long); |
1465 | 1519 |
call_stack_size = (call_stack_size + TCG_TARGET_STACK_ALIGN - 1) & |
1466 | 1520 |
~(TCG_TARGET_STACK_ALIGN - 1); |
1467 |
#ifdef TCG_TARGET_STACK_GROWSUP |
|
1468 |
tcg_out_addi(s, TCG_REG_CALL_STACK, call_stack_size); |
|
1469 |
#else |
|
1470 |
tcg_out_addi(s, TCG_REG_CALL_STACK, -call_stack_size); |
|
1471 |
#endif |
|
1472 |
|
|
1521 |
allocate_args = (call_stack_size > TCG_STATIC_CALL_ARGS_SIZE); |
|
1522 |
if (allocate_args) { |
|
1523 |
tcg_out_addi(s, TCG_REG_CALL_STACK, -STACK_DIR(call_stack_size)); |
|
1524 |
} |
|
1525 |
/* XXX: on some architectures it does not start at zero */ |
|
1473 | 1526 |
stack_offset = 0; |
1474 | 1527 |
for(i = nb_regs; i < nb_params; i++) { |
1475 | 1528 |
arg = args[nb_oargs + i]; |
... | ... | |
1491 | 1544 |
} else { |
1492 | 1545 |
tcg_abort(); |
1493 | 1546 |
} |
1494 |
#ifdef TCG_TARGET_STACK_GROWSUP |
|
1495 |
stack_offset -= sizeof(tcg_target_long); |
|
1496 |
#else |
|
1497 |
stack_offset += sizeof(tcg_target_long); |
|
1498 |
#endif |
|
1547 |
/* XXX: not necessarily in the same order */ |
|
1548 |
stack_offset += STACK_DIR(sizeof(tcg_target_long)); |
|
1499 | 1549 |
} |
1500 | 1550 |
|
1501 | 1551 |
/* assign input registers */ |
... | ... | |
1525 | 1575 |
arg_ct = &def->args_ct[0]; |
1526 | 1576 |
ts = &s->temps[func_arg]; |
1527 | 1577 |
func_addr = ts->val; |
1528 |
#ifdef HOST_HPPA |
|
1529 |
func_addr = (tcg_target_long)__canonicalize_funcptr_for_compare((void *)func_addr); |
|
1530 |
#endif |
|
1531 | 1578 |
const_func_arg = 0; |
1532 | 1579 |
if (ts->val_type == TEMP_VAL_MEM) { |
1533 | 1580 |
reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs); |
... | ... | |
1586 | 1633 |
|
1587 | 1634 |
tcg_out_op(s, opc, &func_arg, &const_func_arg); |
1588 | 1635 |
|
1589 |
#ifdef TCG_TARGET_STACK_GROWSUP |
|
1590 |
tcg_out_addi(s, TCG_REG_CALL_STACK, -call_stack_size); |
|
1591 |
#else |
|
1592 |
tcg_out_addi(s, TCG_REG_CALL_STACK, call_stack_size); |
|
1593 |
#endif |
|
1636 |
if (allocate_args) { |
|
1637 |
tcg_out_addi(s, TCG_REG_CALL_STACK, STACK_DIR(call_stack_size)); |
|
1638 |
} |
|
1594 | 1639 |
|
1595 | 1640 |
/* assign output registers and emit moves if needed */ |
1596 | 1641 |
for(i = 0; i < nb_oargs; i++) { |
... | ... | |
1672 | 1717 |
args = gen_opparam_buf; |
1673 | 1718 |
op_index = 0; |
1674 | 1719 |
|
1675 |
#ifdef TCG_TARGET_NEEDS_PROLOGUE |
|
1676 |
tcg_target_prologue(s); |
|
1677 |
#endif |
|
1678 |
|
|
1679 | 1720 |
for(;;) { |
1680 | 1721 |
opc = gen_opc_buf[op_index]; |
1681 | 1722 |
#ifdef CONFIG_PROFILER |
Also available in: Unified diff