Revision 39cf05d3 tcg/tcg.c

b/tcg/tcg.c
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 */

Also available in: Unified diff