[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [4528] more generic call codegen
From: |
Fabrice Bellard |
Subject: |
[Qemu-devel] [4528] more generic call codegen |
Date: |
Thu, 22 May 2008 14:59:57 +0000 |
Revision: 4528
http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=4528
Author: bellard
Date: 2008-05-22 14:59:57 +0000 (Thu, 22 May 2008)
Log Message:
-----------
more generic call codegen
Modified Paths:
--------------
trunk/tcg/i386/tcg-target.h
trunk/tcg/tcg.c
trunk/tcg/tcg.h
trunk/tcg/x86_64/tcg-target.h
Modified: trunk/tcg/i386/tcg-target.h
===================================================================
--- trunk/tcg/i386/tcg-target.h 2008-05-22 14:39:25 UTC (rev 4527)
+++ trunk/tcg/i386/tcg-target.h 2008-05-22 14:59:57 UTC (rev 4528)
@@ -42,6 +42,7 @@
/* used for function call generation */
#define TCG_REG_CALL_STACK TCG_REG_ESP
#define TCG_TARGET_STACK_ALIGN 16
+#define TCG_TARGET_CALL_STACK_OFFSET 0
/* Note: must be synced with dyngen-exec.h */
#define TCG_AREG0 TCG_REG_EBP
Modified: trunk/tcg/tcg.c
===================================================================
--- trunk/tcg/tcg.c 2008-05-22 14:39:25 UTC (rev 4527)
+++ trunk/tcg/tcg.c 2008-05-22 14:59:57 UTC (rev 4528)
@@ -560,7 +560,9 @@
#if TCG_TARGET_REG_BITS < 64
-/* Note: we convert the 64 bit args to 32 bit */
+/* Note: we convert the 64 bit args to 32 bit and do some alignment
+ and endian swap. Maybe it would be better to do the alignment
+ and endian swap in tcg_reg_alloc_call(). */
void tcg_gen_call(TCGContext *s, TCGv func, unsigned int flags,
unsigned int nb_rets, const TCGv *rets,
unsigned int nb_params, const TCGv *args1)
@@ -572,12 +574,17 @@
ret = rets[0];
if (tcg_get_base_type(s, ret) == TCG_TYPE_I64) {
nb_rets = 2;
+#ifdef TCG_TARGET_WORDS_BIGENDIAN
+ rets_2[0] = TCGV_HIGH(ret);
+ rets_2[1] = ret;
+#else
rets_2[0] = ret;
rets_2[1] = TCGV_HIGH(ret);
+#endif
rets = rets_2;
}
}
- args2 = alloca((nb_params * 2) * sizeof(TCGv));
+ args2 = alloca((nb_params * 3) * sizeof(TCGv));
j = 0;
call_type = (flags & TCG_CALL_TYPE_MASK);
for(i = 0; i < nb_params; i++) {
@@ -593,6 +600,12 @@
args2[j++] = arg;
args2[j++] = TCGV_HIGH(arg);
#else
+#ifdef TCG_TARGET_CALL_ALIGN_ARGS
+ /* some targets want aligned 64 bit args */
+ if (j & 1) {
+ args2[j++] = TCG_CALL_DUMMY_ARG;
+ }
+#endif
#ifdef TCG_TARGET_WORDS_BIGENDIAN
args2[j++] = TCGV_HIGH(arg);
args2[j++] = arg;
@@ -744,8 +757,12 @@
}
for(i = 0; i < (nb_iargs - 1); i++) {
fprintf(outfile, ",");
- fprintf(outfile, "%s",
- tcg_get_arg_str_idx(s, buf, sizeof(buf), args[nb_oargs
+ i]));
+ if (args[nb_oargs + i] == TCG_CALL_DUMMY_ARG) {
+ fprintf(outfile, "<dummy>");
+ } else {
+ fprintf(outfile, "%s",
+ tcg_get_arg_str_idx(s, buf, sizeof(buf),
args[nb_oargs + i]));
+ }
}
} else {
if (c == INDEX_op_nopn) {
@@ -983,10 +1000,12 @@
dead_iargs = 0;
for(i = 0; i < nb_iargs; i++) {
arg = args[i + nb_oargs];
- if (dead_temps[arg]) {
- dead_iargs |= (1 << i);
+ if (arg != TCG_CALL_DUMMY_ARG) {
+ if (dead_temps[arg]) {
+ dead_iargs |= (1 << i);
+ }
+ dead_temps[arg] = 0;
}
- dead_temps[arg] = 0;
}
s->op_dead_iargs[op_index] = dead_iargs;
}
@@ -1586,52 +1605,60 @@
if (allocate_args) {
tcg_out_addi(s, TCG_REG_CALL_STACK, -STACK_DIR(call_stack_size));
}
- /* XXX: on some architectures it does not start at zero */
- stack_offset = 0;
+
+ stack_offset = TCG_TARGET_CALL_STACK_OFFSET;
for(i = nb_regs; i < nb_params; i++) {
arg = args[nb_oargs + i];
- ts = &s->temps[arg];
- if (ts->val_type == TEMP_VAL_REG) {
- tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, stack_offset);
- } else if (ts->val_type == TEMP_VAL_MEM) {
- reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
- s->reserved_regs);
- /* XXX: not correct if reading values from the stack */
- tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
- tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
- } else if (ts->val_type == TEMP_VAL_CONST) {
- reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
- s->reserved_regs);
- /* XXX: sign extend may be needed on some targets */
- tcg_out_movi(s, ts->type, reg, ts->val);
- tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
- } else {
- tcg_abort();
+#ifdef TCG_TARGET_STACK_GROWSUP
+ stack_offset -= sizeof(tcg_target_long);
+#endif
+ if (arg != TCG_CALL_DUMMY_ARG) {
+ ts = &s->temps[arg];
+ if (ts->val_type == TEMP_VAL_REG) {
+ tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK,
stack_offset);
+ } else if (ts->val_type == TEMP_VAL_MEM) {
+ reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
+ s->reserved_regs);
+ /* XXX: not correct if reading values from the stack */
+ tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
+ tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
+ } else if (ts->val_type == TEMP_VAL_CONST) {
+ reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
+ s->reserved_regs);
+ /* XXX: sign extend may be needed on some targets */
+ tcg_out_movi(s, ts->type, reg, ts->val);
+ tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
+ } else {
+ tcg_abort();
+ }
}
- /* XXX: not necessarily in the same order */
- stack_offset += STACK_DIR(sizeof(tcg_target_long));
+#ifndef TCG_TARGET_STACK_GROWSUP
+ stack_offset += sizeof(tcg_target_long);
+#endif
}
/* assign input registers */
tcg_regset_set(allocated_regs, s->reserved_regs);
for(i = 0; i < nb_regs; i++) {
arg = args[nb_oargs + i];
- ts = &s->temps[arg];
- reg = tcg_target_call_iarg_regs[i];
- tcg_reg_free(s, reg);
- if (ts->val_type == TEMP_VAL_REG) {
- if (ts->reg != reg) {
- tcg_out_mov(s, reg, ts->reg);
+ if (arg != TCG_CALL_DUMMY_ARG) {
+ ts = &s->temps[arg];
+ reg = tcg_target_call_iarg_regs[i];
+ tcg_reg_free(s, reg);
+ if (ts->val_type == TEMP_VAL_REG) {
+ if (ts->reg != reg) {
+ tcg_out_mov(s, reg, ts->reg);
+ }
+ } else if (ts->val_type == TEMP_VAL_MEM) {
+ tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
+ } else if (ts->val_type == TEMP_VAL_CONST) {
+ /* XXX: sign extend ? */
+ tcg_out_movi(s, ts->type, reg, ts->val);
+ } else {
+ tcg_abort();
}
- } else if (ts->val_type == TEMP_VAL_MEM) {
- tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
- } else if (ts->val_type == TEMP_VAL_CONST) {
- /* XXX: sign extend ? */
- tcg_out_movi(s, ts->type, reg, ts->val);
- } else {
- tcg_abort();
+ tcg_regset_set_reg(allocated_regs, reg);
}
- tcg_regset_set_reg(allocated_regs, reg);
}
/* assign function address */
Modified: trunk/tcg/tcg.h
===================================================================
--- trunk/tcg/tcg.h 2008-05-22 14:39:25 UTC (rev 4527)
+++ trunk/tcg/tcg.h 2008-05-22 14:59:57 UTC (rev 4528)
@@ -153,6 +153,10 @@
safely suppressed if the return value is not used. */
#define TCG_CALL_PURE 0x0010
+/* used to align parameters */
+#define TCG_CALL_DUMMY_TCGV MAKE_TCGV(-1)
+#define TCG_CALL_DUMMY_ARG ((TCGArg)(-1))
+
typedef enum {
TCG_COND_EQ,
TCG_COND_NE,
Modified: trunk/tcg/x86_64/tcg-target.h
===================================================================
--- trunk/tcg/x86_64/tcg-target.h 2008-05-22 14:39:25 UTC (rev 4527)
+++ trunk/tcg/x86_64/tcg-target.h 2008-05-22 14:59:57 UTC (rev 4528)
@@ -53,6 +53,7 @@
/* used for function call generation */
#define TCG_REG_CALL_STACK TCG_REG_RSP
#define TCG_TARGET_STACK_ALIGN 16
+#define TCG_TARGET_CALL_STACK_OFFSET 0
/* optional instructions */
#define TCG_TARGET_HAS_bswap_i32
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Qemu-devel] [4528] more generic call codegen,
Fabrice Bellard <=