static void patch_reloc(uint8_t *code_ptr, int type,
- tcg_target_long value);
+ tcg_target_long value, tcg_target_long addend);
TCGOpDef tcg_op_defs[] = {
#define DEF(s, n, copy_size) { #s, 0, 0, n, n, 0, copy_size },
/* FIXME: This may break relocations on RISC targets that
modify instruction fields in place. The caller may not have
written the initial value. */
- patch_reloc(code_ptr, type, l->u.value + addend);
+ patch_reloc(code_ptr, type, l->u.value, addend);
} else {
/* add a new relocation entry */
r = tcg_malloc(sizeof(TCGRelocation));
tcg_abort();
r = l->u.first_reloc;
while (r != NULL) {
- patch_reloc(r->ptr, r->type, value + r->addend);
+ patch_reloc(r->ptr, r->type, value, r->addend);
r = r->next;
}
l->has_value = 1;
int nb_iargs, nb_oargs, flags, nb_regs, i, reg, nb_params;
TCGArg arg, func_arg;
TCGTemp *ts;
- tcg_target_long stack_offset, call_stack_size;
+ tcg_target_long stack_offset, call_stack_size, func_addr;
int const_func_arg;
TCGRegSet allocated_regs;
const TCGArgConstraint *arg_ct;
call_stack_size = (nb_params - nb_regs) * sizeof(tcg_target_long);
call_stack_size = (call_stack_size + TCG_TARGET_STACK_ALIGN - 1) &
~(TCG_TARGET_STACK_ALIGN - 1);
+#ifdef TCG_TARGET_STACK_GROWSUP
+ tcg_out_addi(s, TCG_REG_CALL_STACK, call_stack_size);
+#else
tcg_out_addi(s, TCG_REG_CALL_STACK, -call_stack_size);
+#endif
stack_offset = 0;
for(i = nb_regs; i < nb_params; i++) {
} else {
tcg_abort();
}
+#ifdef TCG_TARGET_STACK_GROWSUP
+ stack_offset -= sizeof(tcg_target_long);
+#else
stack_offset += sizeof(tcg_target_long);
+#endif
}
/* assign input registers */
func_arg = args[nb_oargs + nb_iargs - 1];
arg_ct = &def->args_ct[0];
ts = &s->temps[func_arg];
+ func_addr = ts->val;
+#ifdef HOST_HPPA
+ func_addr = (tcg_target_long)__canonicalize_funcptr_for_compare((void *)func_addr);
+#endif
const_func_arg = 0;
if (ts->val_type == TEMP_VAL_MEM) {
reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
}
func_arg = reg;
} else if (ts->val_type == TEMP_VAL_CONST) {
- if (tcg_target_const_match(ts->val, arg_ct)) {
+ if (tcg_target_const_match(func_addr, arg_ct)) {
const_func_arg = 1;
- func_arg = ts->val;
+ func_arg = func_addr;
} else {
reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
- tcg_out_movi(s, ts->type, reg, ts->val);
+ tcg_out_movi(s, ts->type, reg, func_addr);
func_arg = reg;
}
} else {
tcg_out_op(s, opc, &func_arg, &const_func_arg);
+#ifdef TCG_TARGET_STACK_GROWSUP
+ tcg_out_addi(s, TCG_REG_CALL_STACK, -call_stack_size);
+#else
tcg_out_addi(s, TCG_REG_CALL_STACK, call_stack_size);
+#endif
/* assign output registers and emit moves if needed */
for(i = 0; i < nb_oargs; i++) {