Commit 191f9a93f48ba8859bbbc8d5ac9b401568c2c6f4
1 parent
d1e42c5c
ARM postincrememnt addressing fix.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1970 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
12 additions
and
7 deletions
target-arm/translate.c
... | ... | @@ -383,19 +383,23 @@ static inline void gen_add_data_offset(DisasContext *s, unsigned int insn) |
383 | 383 | } |
384 | 384 | } |
385 | 385 | |
386 | -static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn) | |
386 | +static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn, | |
387 | + int extra) | |
387 | 388 | { |
388 | 389 | int val, rm; |
389 | 390 | |
390 | 391 | if (insn & (1 << 22)) { |
391 | 392 | /* immediate */ |
392 | 393 | val = (insn & 0xf) | ((insn >> 4) & 0xf0); |
394 | + val += extra; | |
393 | 395 | if (!(insn & (1 << 23))) |
394 | 396 | val = -val; |
395 | 397 | if (val != 0) |
396 | 398 | gen_op_addl_T1_im(val); |
397 | 399 | } else { |
398 | 400 | /* register */ |
401 | + if (extra) | |
402 | + gen_op_addl_T1_im(extra); | |
399 | 403 | rm = (insn) & 0xf; |
400 | 404 | gen_movl_T2_reg(s, rm); |
401 | 405 | if (!(insn & (1 << 23))) |
... | ... | @@ -1530,12 +1534,14 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) |
1530 | 1534 | } |
1531 | 1535 | } |
1532 | 1536 | } else { |
1537 | + int address_offset; | |
1533 | 1538 | /* Misc load/store */ |
1534 | 1539 | rn = (insn >> 16) & 0xf; |
1535 | 1540 | rd = (insn >> 12) & 0xf; |
1536 | 1541 | gen_movl_T1_reg(s, rn); |
1537 | 1542 | if (insn & (1 << 24)) |
1538 | - gen_add_datah_offset(s, insn); | |
1543 | + gen_add_datah_offset(s, insn, 0); | |
1544 | + address_offset = 0; | |
1539 | 1545 | if (insn & (1 << 20)) { |
1540 | 1546 | /* load */ |
1541 | 1547 | switch(sh) { |
... | ... | @@ -1560,8 +1566,6 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) |
1560 | 1566 | gen_op_addl_T1_im(4); |
1561 | 1567 | gen_movl_T0_reg(s, rd + 1); |
1562 | 1568 | gen_ldst(stl, s); |
1563 | - if ((insn & (1 << 24)) || (insn & (1 << 20))) | |
1564 | - gen_op_addl_T1_im(-4); | |
1565 | 1569 | } else { |
1566 | 1570 | /* load */ |
1567 | 1571 | gen_ldst(ldl, s); |
... | ... | @@ -1569,18 +1573,19 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) |
1569 | 1573 | gen_op_addl_T1_im(4); |
1570 | 1574 | gen_ldst(ldl, s); |
1571 | 1575 | gen_movl_reg_T0(s, rd + 1); |
1572 | - if ((insn & (1 << 24)) || (insn & (1 << 20))) | |
1573 | - gen_op_addl_T1_im(-4); | |
1574 | 1576 | } |
1577 | + address_offset = -4; | |
1575 | 1578 | } else { |
1576 | 1579 | /* store */ |
1577 | 1580 | gen_movl_T0_reg(s, rd); |
1578 | 1581 | gen_ldst(stw, s); |
1579 | 1582 | } |
1580 | 1583 | if (!(insn & (1 << 24))) { |
1581 | - gen_add_datah_offset(s, insn); | |
1584 | + gen_add_datah_offset(s, insn, address_offset); | |
1582 | 1585 | gen_movl_reg_T1(s, rn); |
1583 | 1586 | } else if (insn & (1 << 21)) { |
1587 | + if (address_offset) | |
1588 | + gen_op_addl_T1_im(address_offset); | |
1584 | 1589 | gen_movl_reg_T1(s, rn); |
1585 | 1590 | } |
1586 | 1591 | } | ... | ... |