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,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 | int val, rm; | 389 | int val, rm; |
389 | 390 | ||
390 | if (insn & (1 << 22)) { | 391 | if (insn & (1 << 22)) { |
391 | /* immediate */ | 392 | /* immediate */ |
392 | val = (insn & 0xf) | ((insn >> 4) & 0xf0); | 393 | val = (insn & 0xf) | ((insn >> 4) & 0xf0); |
394 | + val += extra; | ||
393 | if (!(insn & (1 << 23))) | 395 | if (!(insn & (1 << 23))) |
394 | val = -val; | 396 | val = -val; |
395 | if (val != 0) | 397 | if (val != 0) |
396 | gen_op_addl_T1_im(val); | 398 | gen_op_addl_T1_im(val); |
397 | } else { | 399 | } else { |
398 | /* register */ | 400 | /* register */ |
401 | + if (extra) | ||
402 | + gen_op_addl_T1_im(extra); | ||
399 | rm = (insn) & 0xf; | 403 | rm = (insn) & 0xf; |
400 | gen_movl_T2_reg(s, rm); | 404 | gen_movl_T2_reg(s, rm); |
401 | if (!(insn & (1 << 23))) | 405 | if (!(insn & (1 << 23))) |
@@ -1530,12 +1534,14 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) | @@ -1530,12 +1534,14 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) | ||
1530 | } | 1534 | } |
1531 | } | 1535 | } |
1532 | } else { | 1536 | } else { |
1537 | + int address_offset; | ||
1533 | /* Misc load/store */ | 1538 | /* Misc load/store */ |
1534 | rn = (insn >> 16) & 0xf; | 1539 | rn = (insn >> 16) & 0xf; |
1535 | rd = (insn >> 12) & 0xf; | 1540 | rd = (insn >> 12) & 0xf; |
1536 | gen_movl_T1_reg(s, rn); | 1541 | gen_movl_T1_reg(s, rn); |
1537 | if (insn & (1 << 24)) | 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 | if (insn & (1 << 20)) { | 1545 | if (insn & (1 << 20)) { |
1540 | /* load */ | 1546 | /* load */ |
1541 | switch(sh) { | 1547 | switch(sh) { |
@@ -1560,8 +1566,6 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) | @@ -1560,8 +1566,6 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) | ||
1560 | gen_op_addl_T1_im(4); | 1566 | gen_op_addl_T1_im(4); |
1561 | gen_movl_T0_reg(s, rd + 1); | 1567 | gen_movl_T0_reg(s, rd + 1); |
1562 | gen_ldst(stl, s); | 1568 | gen_ldst(stl, s); |
1563 | - if ((insn & (1 << 24)) || (insn & (1 << 20))) | ||
1564 | - gen_op_addl_T1_im(-4); | ||
1565 | } else { | 1569 | } else { |
1566 | /* load */ | 1570 | /* load */ |
1567 | gen_ldst(ldl, s); | 1571 | gen_ldst(ldl, s); |
@@ -1569,18 +1573,19 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) | @@ -1569,18 +1573,19 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) | ||
1569 | gen_op_addl_T1_im(4); | 1573 | gen_op_addl_T1_im(4); |
1570 | gen_ldst(ldl, s); | 1574 | gen_ldst(ldl, s); |
1571 | gen_movl_reg_T0(s, rd + 1); | 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 | } else { | 1578 | } else { |
1576 | /* store */ | 1579 | /* store */ |
1577 | gen_movl_T0_reg(s, rd); | 1580 | gen_movl_T0_reg(s, rd); |
1578 | gen_ldst(stw, s); | 1581 | gen_ldst(stw, s); |
1579 | } | 1582 | } |
1580 | if (!(insn & (1 << 24))) { | 1583 | if (!(insn & (1 << 24))) { |
1581 | - gen_add_datah_offset(s, insn); | 1584 | + gen_add_datah_offset(s, insn, address_offset); |
1582 | gen_movl_reg_T1(s, rn); | 1585 | gen_movl_reg_T1(s, rn); |
1583 | } else if (insn & (1 << 21)) { | 1586 | } else if (insn & (1 << 21)) { |
1587 | + if (address_offset) | ||
1588 | + gen_op_addl_T1_im(address_offset); | ||
1584 | gen_movl_reg_T1(s, rn); | 1589 | gen_movl_reg_T1(s, rn); |
1585 | } | 1590 | } |
1586 | } | 1591 | } |