Revision f54b3f92 tcg/tcg.c
b/tcg/tcg.c | ||
---|---|---|
53 | 53 |
|
54 | 54 |
|
55 | 55 |
static void patch_reloc(uint8_t *code_ptr, int type, |
56 |
tcg_target_long value); |
|
56 |
tcg_target_long value, tcg_target_long addend);
|
|
57 | 57 |
|
58 | 58 |
TCGOpDef tcg_op_defs[] = { |
59 | 59 |
#define DEF(s, n, copy_size) { #s, 0, 0, n, n, 0, copy_size }, |
... | ... | |
100 | 100 |
/* FIXME: This may break relocations on RISC targets that |
101 | 101 |
modify instruction fields in place. The caller may not have |
102 | 102 |
written the initial value. */ |
103 |
patch_reloc(code_ptr, type, l->u.value + addend);
|
|
103 |
patch_reloc(code_ptr, type, l->u.value, addend);
|
|
104 | 104 |
} else { |
105 | 105 |
/* add a new relocation entry */ |
106 | 106 |
r = tcg_malloc(sizeof(TCGRelocation)); |
... | ... | |
123 | 123 |
tcg_abort(); |
124 | 124 |
r = l->u.first_reloc; |
125 | 125 |
while (r != NULL) { |
126 |
patch_reloc(r->ptr, r->type, value + r->addend);
|
|
126 |
patch_reloc(r->ptr, r->type, value, r->addend);
|
|
127 | 127 |
r = r->next; |
128 | 128 |
} |
129 | 129 |
l->has_value = 1; |
... | ... | |
1442 | 1442 |
int nb_iargs, nb_oargs, flags, nb_regs, i, reg, nb_params; |
1443 | 1443 |
TCGArg arg, func_arg; |
1444 | 1444 |
TCGTemp *ts; |
1445 |
tcg_target_long stack_offset, call_stack_size; |
|
1445 |
tcg_target_long stack_offset, call_stack_size, func_addr;
|
|
1446 | 1446 |
int const_func_arg; |
1447 | 1447 |
TCGRegSet allocated_regs; |
1448 | 1448 |
const TCGArgConstraint *arg_ct; |
... | ... | |
1464 | 1464 |
call_stack_size = (nb_params - nb_regs) * sizeof(tcg_target_long); |
1465 | 1465 |
call_stack_size = (call_stack_size + TCG_TARGET_STACK_ALIGN - 1) & |
1466 | 1466 |
~(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 |
|
1467 | 1470 |
tcg_out_addi(s, TCG_REG_CALL_STACK, -call_stack_size); |
1471 |
#endif |
|
1468 | 1472 |
|
1469 | 1473 |
stack_offset = 0; |
1470 | 1474 |
for(i = nb_regs; i < nb_params; i++) { |
... | ... | |
1487 | 1491 |
} else { |
1488 | 1492 |
tcg_abort(); |
1489 | 1493 |
} |
1494 |
#ifdef TCG_TARGET_STACK_GROWSUP |
|
1495 |
stack_offset -= sizeof(tcg_target_long); |
|
1496 |
#else |
|
1490 | 1497 |
stack_offset += sizeof(tcg_target_long); |
1498 |
#endif |
|
1491 | 1499 |
} |
1492 | 1500 |
|
1493 | 1501 |
/* assign input registers */ |
... | ... | |
1516 | 1524 |
func_arg = args[nb_oargs + nb_iargs - 1]; |
1517 | 1525 |
arg_ct = &def->args_ct[0]; |
1518 | 1526 |
ts = &s->temps[func_arg]; |
1527 |
func_addr = ts->val; |
|
1528 |
#ifdef HOST_HPPA |
|
1529 |
func_addr = (tcg_target_long)__canonicalize_funcptr_for_compare((void *)func_addr); |
|
1530 |
#endif |
|
1519 | 1531 |
const_func_arg = 0; |
1520 | 1532 |
if (ts->val_type == TEMP_VAL_MEM) { |
1521 | 1533 |
reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs); |
... | ... | |
1529 | 1541 |
} |
1530 | 1542 |
func_arg = reg; |
1531 | 1543 |
} else if (ts->val_type == TEMP_VAL_CONST) { |
1532 |
if (tcg_target_const_match(ts->val, arg_ct)) {
|
|
1544 |
if (tcg_target_const_match(func_addr, arg_ct)) {
|
|
1533 | 1545 |
const_func_arg = 1; |
1534 |
func_arg = ts->val;
|
|
1546 |
func_arg = func_addr;
|
|
1535 | 1547 |
} else { |
1536 | 1548 |
reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs); |
1537 |
tcg_out_movi(s, ts->type, reg, ts->val);
|
|
1549 |
tcg_out_movi(s, ts->type, reg, func_addr);
|
|
1538 | 1550 |
func_arg = reg; |
1539 | 1551 |
} |
1540 | 1552 |
} else { |
... | ... | |
1574 | 1586 |
|
1575 | 1587 |
tcg_out_op(s, opc, &func_arg, &const_func_arg); |
1576 | 1588 |
|
1589 |
#ifdef TCG_TARGET_STACK_GROWSUP |
|
1590 |
tcg_out_addi(s, TCG_REG_CALL_STACK, -call_stack_size); |
|
1591 |
#else |
|
1577 | 1592 |
tcg_out_addi(s, TCG_REG_CALL_STACK, call_stack_size); |
1593 |
#endif |
|
1578 | 1594 |
|
1579 | 1595 |
/* assign output registers and emit moves if needed */ |
1580 | 1596 |
for(i = 0; i < nb_oargs; i++) { |
Also available in: Unified diff