* [Qemu-devel] qemu-arm: wrong execution of post-indexed loads when Rm and Rd are the same register @ 2007-03-15 19:35 Lauro Ramos Venancio 2007-03-15 19:43 ` [Qemu-devel] " Lauro Ramos Venancio 2007-03-15 20:03 ` [Qemu-devel] " Paul Brook 0 siblings, 2 replies; 9+ messages in thread From: Lauro Ramos Venancio @ 2007-03-15 19:35 UTC (permalink / raw) To: qemu-devel Qemu-arm is wrongly executing post-indexed loads when Rm and Rd are the same register. For example: ldr r0, [r1], +r0 Current behavior: r0 <- [r1] r1 <- r1 + r0 Expected behavior: addr <- r1 r1 <- r1 + r0 r0 <- [addr] The attached patch fixes this bug. Patched by me and Rodrigo Vivi. This patch was made based on qemu 0.9. Lauro Venancio ^ permalink raw reply [flat|nested] 9+ messages in thread
* [Qemu-devel] Re: qemu-arm: wrong execution of post-indexed loads when Rm and Rd are the same register 2007-03-15 19:35 [Qemu-devel] qemu-arm: wrong execution of post-indexed loads when Rm and Rd are the same register Lauro Ramos Venancio @ 2007-03-15 19:43 ` Lauro Ramos Venancio 2007-03-15 20:03 ` [Qemu-devel] " Paul Brook 1 sibling, 0 replies; 9+ messages in thread From: Lauro Ramos Venancio @ 2007-03-15 19:43 UTC (permalink / raw) To: qemu-devel [-- Attachment #1: Type: text/plain, Size: 486 bytes --] Now sending the attachment. :) Lauro On Thu, 2007-03-15 at 16:35 -0300, Lauro Ramos Venancio wrote: > Qemu-arm is wrongly executing post-indexed loads when Rm and Rd are > the same register. For example: > > ldr r0, [r1], +r0 > > Current behavior: > r0 <- [r1] > r1 <- r1 + r0 > > Expected behavior: > addr <- r1 > r1 <- r1 + r0 > r0 <- [addr] > > The attached patch fixes this bug. Patched by me and Rodrigo Vivi. > This patch was made based on qemu 0.9. > > > Lauro Venancio [-- Attachment #2: 00_ldr_writeback.patch --] [-- Type: text/x-patch, Size: 3917 bytes --] --- target-arm/op.c.orig 2007-03-09 18:40:02.000000000 -0300 +++ target-arm/op.c 2007-03-09 18:40:27.000000000 -0300 @@ -106,6 +106,11 @@ void OPPROTO op_movl_T0_T1(void) T0 = T1; } +void OPPROTO op_movl_T1_T0(void) +{ + T1 = T0; +} + void OPPROTO op_movl_T1_im(void) { T1 = PARAM1; --- target-arm/translate.c.orig 2007-03-09 18:40:02.000000000 -0300 +++ target-arm/translate.c 2007-03-09 18:40:32.000000000 -0300 @@ -383,23 +383,19 @@ static inline void gen_add_data_offset(D } } -static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn, - int extra) +static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn) { int val, rm; if (insn & (1 << 22)) { /* immediate */ val = (insn & 0xf) | ((insn >> 4) & 0xf0); - val += extra; if (!(insn & (1 << 23))) val = -val; if (val != 0) gen_op_addl_T1_im(val); } else { /* register */ - if (extra) - gen_op_addl_T1_im(extra); rm = (insn) & 0xf; gen_movl_T2_reg(s, rm); if (!(insn & (1 << 23))) @@ -1534,14 +1530,17 @@ static void disas_arm_insn(CPUState * en } } } else { - int address_offset; /* Misc load/store */ rn = (insn >> 16) & 0xf; rd = (insn >> 12) & 0xf; gen_movl_T1_reg(s, rn); - if (insn & (1 << 24)) - gen_add_datah_offset(s, insn, 0); - address_offset = 0; + gen_movl_T0_reg(s, rn); + gen_add_datah_offset(s, insn); + /* writeback */ + if (!(insn & (1 << 24))||(insn & (1 << 21))) + gen_movl_reg_T1(s, rn); + if (!(insn & (1 << 24))) /* pos-indexed */ + gen_op_movl_T1_T0(); if (insn & (1 << 20)) { /* load */ switch(sh) { @@ -1574,20 +1573,11 @@ static void disas_arm_insn(CPUState * en gen_ldst(ldl, s); gen_movl_reg_T0(s, rd + 1); } - address_offset = -4; } else { /* store */ gen_movl_T0_reg(s, rd); gen_ldst(stw, s); } - if (!(insn & (1 << 24))) { - gen_add_datah_offset(s, insn, address_offset); - gen_movl_reg_T1(s, rn); - } else if (insn & (1 << 21)) { - if (address_offset) - gen_op_addl_T1_im(address_offset); - gen_movl_reg_T1(s, rn); - } } break; case 0x4: @@ -1607,9 +1597,14 @@ static void disas_arm_insn(CPUState * en rn = (insn >> 16) & 0xf; rd = (insn >> 12) & 0xf; gen_movl_T1_reg(s, rn); + gen_movl_T0_reg(s, rn); i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000); - if (insn & (1 << 24)) gen_add_data_offset(s, insn); + /* writeback */ + if (!(insn & (1 << 24))||(insn & (1 << 21))) + gen_movl_reg_T1(s, rn); + if (!(insn & (1 << 24))) /* pos-indexed */ + gen_op_movl_T1_T0(); if (insn & (1 << 20)) { /* load */ #if defined(CONFIG_USER_ONLY) @@ -1656,12 +1651,6 @@ static void disas_arm_insn(CPUState * en } #endif } - if (!(insn & (1 << 24))) { - gen_add_data_offset(s, insn); - gen_movl_reg_T1(s, rn); - } else if (insn & (1 << 21)) - gen_movl_reg_T1(s, rn); { - } break; case 0x08: case 0x09: ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] qemu-arm: wrong execution of post-indexed loads when Rm and Rd are the same register 2007-03-15 19:35 [Qemu-devel] qemu-arm: wrong execution of post-indexed loads when Rm and Rd are the same register Lauro Ramos Venancio 2007-03-15 19:43 ` [Qemu-devel] " Lauro Ramos Venancio @ 2007-03-15 20:03 ` Paul Brook 2007-03-15 20:32 ` Rodrigo Vivi 1 sibling, 1 reply; 9+ messages in thread From: Paul Brook @ 2007-03-15 20:03 UTC (permalink / raw) To: qemu-devel; +Cc: Lauro Ramos Venancio On Thursday 15 March 2007 19:35, Lauro Ramos Venancio wrote: > Qemu-arm is wrongly executing post-indexed loads when Rm and Rd are > the same register. For example: > > ldr r0, [r1], +r0 > > Current behavior: > r0 <- [r1] > r1 <- r1 + r0 > > Expected behavior: > addr <- r1 > r1 <- r1 + r0 > r0 <- [addr] This is still wrong. The writeback must happen after the load. Your implementation will give incorrect results if the load faults. Paul ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] qemu-arm: wrong execution of post-indexed loads when Rm and Rd are the same register 2007-03-15 20:03 ` [Qemu-devel] " Paul Brook @ 2007-03-15 20:32 ` Rodrigo Vivi 2007-03-15 21:10 ` Paul Brook 0 siblings, 1 reply; 9+ messages in thread From: Rodrigo Vivi @ 2007-03-15 20:32 UTC (permalink / raw) To: qemu-devel; +Cc: Lauro Ramos Venancio Hi Paul, On 3/15/07, Paul Brook <paul@codesourcery.com> wrote: > On Thursday 15 March 2007 19:35, Lauro Ramos Venancio wrote: > > Qemu-arm is wrongly executing post-indexed loads when Rm and Rd are > > the same register. For example: > > > > ldr r0, [r1], +r0 > > > > Current behavior: > > r0 <- [r1] > > r1 <- r1 + r0 > > > > Expected behavior: > > addr <- r1 > > r1 <- r1 + r0 > > r0 <- [addr] > > This is still wrong. So, is this a known bug? > The writeback must happen after the load. We code like this because - we didn't find this restriction in arm reference manual - the LLVM uses this instruction expecting a result like this - That was the result that we got running these instructions in an OMAP1710 > Your > implementation will give incorrect results if the load faults. Another thing, is that in this manual (at page A2-18) there are 2 rules for data abort: - Base Restored Abort Model and Base Updated Abort Model. So, we can not understand why it will give incorect results if a load faults... > > Paul thanks Rodrigo Vivi vivijim at freenode > > > _______________________________________________ > Qemu-devel mailing list > Qemu-devel@nongnu.org > http://lists.nongnu.org/mailman/listinfo/qemu-devel > ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] qemu-arm: wrong execution of post-indexed loads when Rm and Rd are the same register 2007-03-15 20:32 ` Rodrigo Vivi @ 2007-03-15 21:10 ` Paul Brook 2007-03-15 21:19 ` Rodrigo Vivi 2007-03-15 21:55 ` Laurent Desnogues 0 siblings, 2 replies; 9+ messages in thread From: Paul Brook @ 2007-03-15 21:10 UTC (permalink / raw) To: qemu-devel; +Cc: Rodrigo Vivi, Lauro Ramos Venancio > > This is still wrong. > > So, is this a known bug? Still wrong implies it's a bug, and your patch does not fix it properly. > > The writeback must happen after the load. > > We code like this because > - we didn't find this restriction in arm reference manual It's the Abort model section you mention below. > - the LLVM uses this instruction expecting a result like this The compiler knows nothing about the abort behavior. The difference is only visible if the load faults. > - That was the result that we got running these instructions in an OMAP1710 I suggest you check again. I'm fairly sure the arm926 implements the Base Restored abort model. Paul ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] qemu-arm: wrong execution of post-indexed loads when Rm and Rd are the same register 2007-03-15 21:10 ` Paul Brook @ 2007-03-15 21:19 ` Rodrigo Vivi 2007-03-15 21:55 ` Laurent Desnogues 1 sibling, 0 replies; 9+ messages in thread From: Rodrigo Vivi @ 2007-03-15 21:19 UTC (permalink / raw) To: Paul Brook; +Cc: Lauro Ramos Venancio, qemu-devel On 3/15/07, Paul Brook <paul@codesourcery.com> wrote: > > > This is still wrong. > > > > So, is this a known bug? > > Still wrong implies it's a bug, and your patch does not fix it properly. I know that... I was not clear.. sorry... what I mean is: do you agree that there was a bug in these instructions? > > > > The writeback must happen after the load. > > > > We code like this because > > - we didn't find this restriction in arm reference manual > > It's the Abort model section you mention below. > > > - the LLVM uses this instruction expecting a result like this > > The compiler knows nothing about the abort behavior. The difference is only > visible if the load faults. > > > - That was the result that we got running these instructions in an OMAP1710 > > I suggest you check again. I'm fairly sure the arm926 implements the Base > Restored abort model. Actually we did not test the abort model... So, Base Restored abort model is the model that qemu implements, isn't it? then we will try to use that and recode the patch... thanks for your help > > Paul > vivijim ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] qemu-arm: wrong execution of post-indexed loads when Rm and Rd are the same register 2007-03-15 21:10 ` Paul Brook 2007-03-15 21:19 ` Rodrigo Vivi @ 2007-03-15 21:55 ` Laurent Desnogues 2007-03-15 22:04 ` Paul Brook 1 sibling, 1 reply; 9+ messages in thread From: Laurent Desnogues @ 2007-03-15 21:55 UTC (permalink / raw) To: qemu-devel Paul Brook a écrit : > > I suggest you check again. I'm fairly sure the arm926 implements the Base > Restored abort model. Yes, but arm7 is Based Updated IIRC. What particular implementation does Qemu target? There are so many IMPLEMENTATION DEFINED and UNPREDICTABLE in the architecture (that are indeed used by even Linux kernel) that targeting multiple implementations in the same is almost impossible. Laurent ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] qemu-arm: wrong execution of post-indexed loads when Rm and Rd are the same register 2007-03-15 21:55 ` Laurent Desnogues @ 2007-03-15 22:04 ` Paul Brook 2007-03-16 20:42 ` Lauro Ramos Venancio 0 siblings, 1 reply; 9+ messages in thread From: Paul Brook @ 2007-03-15 22:04 UTC (permalink / raw) To: qemu-devel On Thursday 15 March 2007 21:55, Laurent Desnogues wrote: > Paul Brook a écrit : > > I suggest you check again. I'm fairly sure the arm926 implements the Base > > Restored abort model. > > Yes, but arm7 is Based Updated IIRC. What particular implementation > does Qemu target? Qemu currently emulates arm926 or arm1026. For userspace emulation we have to use the Base Restored model because that's what linux implements, even on Base Updated hardware. In recent revisions of the ARM Architecture (v6+) Base Restored is the only model allowed. Paul ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] qemu-arm: wrong execution of post-indexed loads when Rm and Rd are the same register 2007-03-15 22:04 ` Paul Brook @ 2007-03-16 20:42 ` Lauro Ramos Venancio 0 siblings, 0 replies; 9+ messages in thread From: Lauro Ramos Venancio @ 2007-03-16 20:42 UTC (permalink / raw) To: qemu-devel [-- Attachment #1: Type: text/plain, Size: 88 bytes --] I'm sending a new version of the patch that uses Base Restored data abort model. Lauro [-- Attachment #2: 00_ldr_writeback.patch --] [-- Type: text/x-patch, Size: 2010 bytes --] diff -ru qemu-0.9.0.orig/target-arm/translate.c qemu-0.9.0/target-arm/translate.c --- qemu-0.9.0.orig/target-arm/translate.c 2007-03-16 11:41:28.000000000 -0300 +++ qemu-0.9.0/target-arm/translate.c 2007-03-16 14:59:40.000000000 -0300 @@ -1556,7 +1556,6 @@ gen_ldst(ldsw, s); break; } - gen_movl_reg_T0(s, rd); } else if (sh & 2) { /* doubleword */ if (sh & 1) { @@ -1572,7 +1571,7 @@ gen_movl_reg_T0(s, rd); gen_op_addl_T1_im(4); gen_ldst(ldl, s); - gen_movl_reg_T0(s, rd + 1); + ++rd; } address_offset = -4; } else { @@ -1588,6 +1587,12 @@ gen_op_addl_T1_im(address_offset); gen_movl_reg_T1(s, rn); } + + if ((insn & (1 << 20)) || + ((!(insn & (1 << 20)))&&((sh & 3) == 2))) { + /* load */ + gen_movl_reg_T0(s, rd); + } } break; case 0x4: @@ -1630,10 +1635,6 @@ gen_op_ldl_kernel(); } #endif - if (rd == 15) - gen_bx(s); - else - gen_movl_reg_T0(s, rd); } else { /* store */ gen_movl_T0_reg(s, rd); @@ -1662,6 +1663,13 @@ } else if (insn & (1 << 21)) gen_movl_reg_T1(s, rn); { } + if (insn & (1 << 20)) { + /* load */ + if (rd == 15) + gen_bx(s); + else + gen_movl_reg_T0(s, rd); + } break; case 0x08: case 0x09: Only in qemu-0.9.0/target-arm: translate.c~ ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2007-03-16 20:44 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2007-03-15 19:35 [Qemu-devel] qemu-arm: wrong execution of post-indexed loads when Rm and Rd are the same register Lauro Ramos Venancio 2007-03-15 19:43 ` [Qemu-devel] " Lauro Ramos Venancio 2007-03-15 20:03 ` [Qemu-devel] " Paul Brook 2007-03-15 20:32 ` Rodrigo Vivi 2007-03-15 21:10 ` Paul Brook 2007-03-15 21:19 ` Rodrigo Vivi 2007-03-15 21:55 ` Laurent Desnogues 2007-03-15 22:04 ` Paul Brook 2007-03-16 20:42 ` Lauro Ramos Venancio
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).