560 |
560 |
|
561 |
561 |
|
562 |
562 |
#if TCG_TARGET_REG_BITS < 64
|
563 |
|
/* Note: we convert the 64 bit args to 32 bit */
|
|
563 |
/* Note: we convert the 64 bit args to 32 bit and do some alignment
|
|
564 |
and endian swap. Maybe it would be better to do the alignment
|
|
565 |
and endian swap in tcg_reg_alloc_call(). */
|
564 |
566 |
void tcg_gen_call(TCGContext *s, TCGv func, unsigned int flags,
|
565 |
567 |
unsigned int nb_rets, const TCGv *rets,
|
566 |
568 |
unsigned int nb_params, const TCGv *args1)
|
... | ... | |
572 |
574 |
ret = rets[0];
|
573 |
575 |
if (tcg_get_base_type(s, ret) == TCG_TYPE_I64) {
|
574 |
576 |
nb_rets = 2;
|
|
577 |
#ifdef TCG_TARGET_WORDS_BIGENDIAN
|
|
578 |
rets_2[0] = TCGV_HIGH(ret);
|
|
579 |
rets_2[1] = ret;
|
|
580 |
#else
|
575 |
581 |
rets_2[0] = ret;
|
576 |
582 |
rets_2[1] = TCGV_HIGH(ret);
|
|
583 |
#endif
|
577 |
584 |
rets = rets_2;
|
578 |
585 |
}
|
579 |
586 |
}
|
580 |
|
args2 = alloca((nb_params * 2) * sizeof(TCGv));
|
|
587 |
args2 = alloca((nb_params * 3) * sizeof(TCGv));
|
581 |
588 |
j = 0;
|
582 |
589 |
call_type = (flags & TCG_CALL_TYPE_MASK);
|
583 |
590 |
for(i = 0; i < nb_params; i++) {
|
... | ... | |
593 |
600 |
args2[j++] = arg;
|
594 |
601 |
args2[j++] = TCGV_HIGH(arg);
|
595 |
602 |
#else
|
|
603 |
#ifdef TCG_TARGET_CALL_ALIGN_ARGS
|
|
604 |
/* some targets want aligned 64 bit args */
|
|
605 |
if (j & 1) {
|
|
606 |
args2[j++] = TCG_CALL_DUMMY_ARG;
|
|
607 |
}
|
|
608 |
#endif
|
596 |
609 |
#ifdef TCG_TARGET_WORDS_BIGENDIAN
|
597 |
610 |
args2[j++] = TCGV_HIGH(arg);
|
598 |
611 |
args2[j++] = arg;
|
... | ... | |
744 |
757 |
}
|
745 |
758 |
for(i = 0; i < (nb_iargs - 1); i++) {
|
746 |
759 |
fprintf(outfile, ",");
|
747 |
|
fprintf(outfile, "%s",
|
748 |
|
tcg_get_arg_str_idx(s, buf, sizeof(buf), args[nb_oargs + i]));
|
|
760 |
if (args[nb_oargs + i] == TCG_CALL_DUMMY_ARG) {
|
|
761 |
fprintf(outfile, "<dummy>");
|
|
762 |
} else {
|
|
763 |
fprintf(outfile, "%s",
|
|
764 |
tcg_get_arg_str_idx(s, buf, sizeof(buf), args[nb_oargs + i]));
|
|
765 |
}
|
749 |
766 |
}
|
750 |
767 |
} else {
|
751 |
768 |
if (c == INDEX_op_nopn) {
|
... | ... | |
983 |
1000 |
dead_iargs = 0;
|
984 |
1001 |
for(i = 0; i < nb_iargs; i++) {
|
985 |
1002 |
arg = args[i + nb_oargs];
|
986 |
|
if (dead_temps[arg]) {
|
987 |
|
dead_iargs |= (1 << i);
|
|
1003 |
if (arg != TCG_CALL_DUMMY_ARG) {
|
|
1004 |
if (dead_temps[arg]) {
|
|
1005 |
dead_iargs |= (1 << i);
|
|
1006 |
}
|
|
1007 |
dead_temps[arg] = 0;
|
988 |
1008 |
}
|
989 |
|
dead_temps[arg] = 0;
|
990 |
1009 |
}
|
991 |
1010 |
s->op_dead_iargs[op_index] = dead_iargs;
|
992 |
1011 |
}
|
... | ... | |
1586 |
1605 |
if (allocate_args) {
|
1587 |
1606 |
tcg_out_addi(s, TCG_REG_CALL_STACK, -STACK_DIR(call_stack_size));
|
1588 |
1607 |
}
|
1589 |
|
/* XXX: on some architectures it does not start at zero */
|
1590 |
|
stack_offset = 0;
|
|
1608 |
|
|
1609 |
stack_offset = TCG_TARGET_CALL_STACK_OFFSET;
|
1591 |
1610 |
for(i = nb_regs; i < nb_params; i++) {
|
1592 |
1611 |
arg = args[nb_oargs + i];
|
1593 |
|
ts = &s->temps[arg];
|
1594 |
|
if (ts->val_type == TEMP_VAL_REG) {
|
1595 |
|
tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, stack_offset);
|
1596 |
|
} else if (ts->val_type == TEMP_VAL_MEM) {
|
1597 |
|
reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
|
1598 |
|
s->reserved_regs);
|
1599 |
|
/* XXX: not correct if reading values from the stack */
|
1600 |
|
tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
|
1601 |
|
tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
|
1602 |
|
} else if (ts->val_type == TEMP_VAL_CONST) {
|
1603 |
|
reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
|
1604 |
|
s->reserved_regs);
|
1605 |
|
/* XXX: sign extend may be needed on some targets */
|
1606 |
|
tcg_out_movi(s, ts->type, reg, ts->val);
|
1607 |
|
tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
|
1608 |
|
} else {
|
1609 |
|
tcg_abort();
|
|
1612 |
#ifdef TCG_TARGET_STACK_GROWSUP
|
|
1613 |
stack_offset -= sizeof(tcg_target_long);
|
|
1614 |
#endif
|
|
1615 |
if (arg != TCG_CALL_DUMMY_ARG) {
|
|
1616 |
ts = &s->temps[arg];
|
|
1617 |
if (ts->val_type == TEMP_VAL_REG) {
|
|
1618 |
tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, stack_offset);
|
|
1619 |
} else if (ts->val_type == TEMP_VAL_MEM) {
|
|
1620 |
reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
|
|
1621 |
s->reserved_regs);
|
|
1622 |
/* XXX: not correct if reading values from the stack */
|
|
1623 |
tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
|
|
1624 |
tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
|
|
1625 |
} else if (ts->val_type == TEMP_VAL_CONST) {
|
|
1626 |
reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
|
|
1627 |
s->reserved_regs);
|
|
1628 |
/* XXX: sign extend may be needed on some targets */
|
|
1629 |
tcg_out_movi(s, ts->type, reg, ts->val);
|
|
1630 |
tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
|
|
1631 |
} else {
|
|
1632 |
tcg_abort();
|
|
1633 |
}
|
1610 |
1634 |
}
|
1611 |
|
/* XXX: not necessarily in the same order */
|
1612 |
|
stack_offset += STACK_DIR(sizeof(tcg_target_long));
|
|
1635 |
#ifndef TCG_TARGET_STACK_GROWSUP
|
|
1636 |
stack_offset += sizeof(tcg_target_long);
|
|
1637 |
#endif
|
1613 |
1638 |
}
|
1614 |
1639 |
|
1615 |
1640 |
/* assign input registers */
|
1616 |
1641 |
tcg_regset_set(allocated_regs, s->reserved_regs);
|
1617 |
1642 |
for(i = 0; i < nb_regs; i++) {
|
1618 |
1643 |
arg = args[nb_oargs + i];
|
1619 |
|
ts = &s->temps[arg];
|
1620 |
|
reg = tcg_target_call_iarg_regs[i];
|
1621 |
|
tcg_reg_free(s, reg);
|
1622 |
|
if (ts->val_type == TEMP_VAL_REG) {
|
1623 |
|
if (ts->reg != reg) {
|
1624 |
|
tcg_out_mov(s, reg, ts->reg);
|
|
1644 |
if (arg != TCG_CALL_DUMMY_ARG) {
|
|
1645 |
ts = &s->temps[arg];
|
|
1646 |
reg = tcg_target_call_iarg_regs[i];
|
|
1647 |
tcg_reg_free(s, reg);
|
|
1648 |
if (ts->val_type == TEMP_VAL_REG) {
|
|
1649 |
if (ts->reg != reg) {
|
|
1650 |
tcg_out_mov(s, reg, ts->reg);
|
|
1651 |
}
|
|
1652 |
} else if (ts->val_type == TEMP_VAL_MEM) {
|
|
1653 |
tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
|
|
1654 |
} else if (ts->val_type == TEMP_VAL_CONST) {
|
|
1655 |
/* XXX: sign extend ? */
|
|
1656 |
tcg_out_movi(s, ts->type, reg, ts->val);
|
|
1657 |
} else {
|
|
1658 |
tcg_abort();
|
1625 |
1659 |
}
|
1626 |
|
} else if (ts->val_type == TEMP_VAL_MEM) {
|
1627 |
|
tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
|
1628 |
|
} else if (ts->val_type == TEMP_VAL_CONST) {
|
1629 |
|
/* XXX: sign extend ? */
|
1630 |
|
tcg_out_movi(s, ts->type, reg, ts->val);
|
1631 |
|
} else {
|
1632 |
|
tcg_abort();
|
|
1660 |
tcg_regset_set_reg(allocated_regs, reg);
|
1633 |
1661 |
}
|
1634 |
|
tcg_regset_set_reg(allocated_regs, reg);
|
1635 |
1662 |
}
|
1636 |
1663 |
|
1637 |
1664 |
/* assign function address */
|