qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] fixed one bug, found another :) (was: another tcg bug? tes


From: Juergen Lock
Subject: [Qemu-devel] fixed one bug, found another :) (was: another tcg bug? test r, r case in tcg_out_brcond2())
Date: Sat, 5 Jul 2008 23:29:46 +0200
User-agent: Mutt/1.5.17 (2007-11-01)

On Fri, Jul 04, 2008 at 09:32:04PM +0200, Juergen Lock wrote:
> Hi!
>[...]
>  Unfortunately that patch doesnt seem to be enough i.e. /usr still fails
> to mount.  Have I missed another case of this problem?  The following
>       if (bp->bio_offset > pp->mediasize)
> line that might also cause the mount failure gets translated like the
> follwoing, can anyone see a bug there?
> 
> IN: 
> 0xffffffff8044b2d5:  cmp    0x48(%rdi),%r8
> 0xffffffff8044b2d9:  jle    0xffffffff8044b33a
> 
> OUT: [size=227]
> 0x29487ec0:  mov    0x38(%ebp),%eax
> 0x29487ec3:  mov    0x3c(%ebp),%edx
> 0x29487ec6:  add    $0x48,%eax
> 0x29487ec9:  adc    $0x0,%edx
> 0x29487ecc:  mov    %eax,%ecx
> 0x29487ece:  mov    %edx,%ebx
> 0x29487ed0:  mov    %ecx,%edx
> 0x29487ed2:  mov    %ecx,%eax
> 0x29487ed4:  shr    $0x7,%edx
> 0x29487ed7:  and    $0xfffff007,%eax
> 0x29487edd:  and    $0x1fe0,%edx
> 0x29487ee3:  lea    0x460(%edx,%ebp,1),%edx
> 0x29487eea:  cmp    (%edx),%eax
> 0x29487eec:  mov    %ecx,%eax
> 0x29487eee:  jne    0x29487ef5
> 0x29487ef0:  cmp    0x4(%edx),%ebx
> 0x29487ef3:  je     0x29487f00
> 0x29487ef5:  mov    %ebx,%edx
> 0x29487ef7:  xor    %ecx,%ecx
> 0x29487ef9:  call   0x8157a18
> 0x29487efe:  jmp    0x29487f0a
> 0x29487f00:  add    0x18(%edx),%eax
> 0x29487f03:  mov    %eax,%edx
> 0x29487f05:  mov    (%edx),%eax
> 0x29487f07:  mov    0x4(%edx),%edx
> 0x29487f0a:  mov    0x40(%ebp),%ecx
> 0x29487f0d:  mov    0x44(%ebp),%ebx
> 0x29487f10:  mov    %eax,%esi
> 0x29487f12:  mov    %edx,%edi
> 0x29487f14:  sub    %eax,%ecx
> 0x29487f16:  sbb    %edx,%ebx
> 0x29487f18:  mov    %ecx,%eax
> 0x29487f1a:  mov    %ebx,%edx
> 0x29487f1c:  add    %esi,%eax
> 0x29487f1e:  adc    %edi,%edx
> 0x29487f20:  mov    %ecx,0x98(%ebp)
> 0x29487f26:  mov    $0x11,%ecx
> 0x29487f2b:  mov    %ecx,0xa0(%ebp)
> 0x29487f31:  mov    %esi,0x90(%ebp)
> 0x29487f37:  mov    %edi,0x94(%ebp)
> 0x29487f3d:  mov    %ebx,0x9c(%ebp)
> 0x29487f43:  cmp    %edi,%edx
> 0x29487f45:  jl     0x29487f7e
> 0x29487f4b:  jne    0x29487f59
> 0x29487f51:  cmp    %esi,%eax
> 0x29487f53:  jle    0x29487f7e
               ^^^ wrong!
> 0x29487f59:  jmp    0x29487f5e
> 0x29487f5e:  mov    $0x8044b2db,%eax
> 0x29487f63:  mov    %eax,0x80(%ebp)
> 0x29487f69:  mov    $0xffffffff,%eax
> 0x29487f6e:  mov    %eax,0x84(%ebp)
> 0x29487f74:  mov    $0x112f1328,%eax
> 0x29487f79:  jmp    0x83bd948
> 0x29487f7e:  jmp    0x29487f83
> 0x29487f83:  mov    $0x8044b33a,%eax
> 0x29487f88:  mov    %eax,0x80(%ebp)
> 0x29487f8e:  mov    $0xffffffff,%eax
> 0x29487f93:  mov    %eax,0x84(%ebp)
> 0x29487f99:  mov    $0x112f1329,%eax
> 0x29487f9e:  jmp    0x83bd948

OK so I was confused, the real problem was the use of signed conditions for
the lower half, they need to be unsigned...  But some of the `test r,r'
special handling in my original patch is still useful as an optimization,
so here is the updated patch that now at least lets the mentioned guest mount
its /usr and finish booting:

Index: qemu/tcg/i386/tcg-target.c
@@ -359,25 +359,36 @@
         break;
     case TCG_COND_LT:
         tcg_out_brcond(s, TCG_COND_LT, args[1], args[3], const_args[3], 
args[5]);
+        if (const_args[2] && !args[2])
+            /* test r,r - carry can never be set */
+            break;
         tcg_out_jxx(s, JCC_JNE, label_next);
-        tcg_out_brcond(s, TCG_COND_LT, args[0], args[2], const_args[2], 
args[5]);
+        tcg_out_brcond(s, TCG_COND_LTU, args[0], args[2], const_args[2], 
args[5]);
         break;
     case TCG_COND_LE:
         tcg_out_brcond(s, TCG_COND_LT, args[1], args[3], const_args[3], 
args[5]);
         tcg_out_jxx(s, JCC_JNE, label_next);
-        tcg_out_brcond(s, TCG_COND_LE, args[0], args[2], const_args[2], 
args[5]);
+        tcg_out_brcond(s, TCG_COND_LEU, args[0], args[2], const_args[2], 
args[5]);
         break;
     case TCG_COND_GT:
         tcg_out_brcond(s, TCG_COND_GT, args[1], args[3], const_args[3], 
args[5]);
         tcg_out_jxx(s, JCC_JNE, label_next);
-        tcg_out_brcond(s, TCG_COND_GT, args[0], args[2], const_args[2], 
args[5]);
+        tcg_out_brcond(s, TCG_COND_GTU, args[0], args[2], const_args[2], 
args[5]);
         break;
     case TCG_COND_GE:
+        if (const_args[2] && !args[2]) {
+            /* test r,r - carry can never be set */
+            tcg_out_brcond(s, TCG_COND_GE, args[1], args[3], const_args[3], 
args[5]);
+            break;
+        }
         tcg_out_brcond(s, TCG_COND_GT, args[1], args[3], const_args[3], 
args[5]);
         tcg_out_jxx(s, JCC_JNE, label_next);
-        tcg_out_brcond(s, TCG_COND_GE, args[0], args[2], const_args[2], 
args[5]);
+        tcg_out_brcond(s, TCG_COND_GEU, args[0], args[2], const_args[2], 
args[5]);
         break;
     case TCG_COND_LTU:
+        if (const_args[2] && !args[2])
+            /* test r,r - carry can never be set */
+            break;
         tcg_out_brcond(s, TCG_COND_LTU, args[1], args[3], const_args[3], 
args[5]);
         tcg_out_jxx(s, JCC_JNE, label_next);
         tcg_out_brcond(s, TCG_COND_LTU, args[0], args[2], const_args[2], 
args[5]);
@@ -393,6 +404,11 @@
         tcg_out_brcond(s, TCG_COND_GTU, args[0], args[2], const_args[2], 
args[5]);
         break;
     case TCG_COND_GEU:
+        if (const_args[2] && !args[2]) {
+            /* test r,r - carry can never be set */
+            tcg_out_jxx(s, JCC_JMP, args[5]);
+            break;
+        }
         tcg_out_brcond(s, TCG_COND_GTU, args[1], args[3], const_args[3], 
args[5]);
         tcg_out_jxx(s, JCC_JNE, label_next);
         tcg_out_brcond(s, TCG_COND_GEU, args[0], args[2], const_args[2], 
args[5]);

 (if you don't want the optimizations for sake of code clarity just remove
the `if (const_args[2] && !args[2])' clauses.)

 Ok while writing this I was waiting for a Linux/amd64 guest to boot, which
still failed, and the reason seems to be that either floats or conversion
of floats to integers are also broken for amd64 guests on i386 hosts,
as can be seen by:

(gdb) p 1.
$1 = -nan(0x8000000000000)

 The quickest way to reproduce this is probably a FreeBSD/amd64 livefs iso:
        
ftp://ftp.freebsd.org/pub/FreeBSD/ISO-IMAGES-amd64/7.0/7.0-RELEASE-amd64-livefs.iso
start as:
        qemu-system-x86_64 -cdrom 7.0-RELEASE-amd64-livefs.iso
select fixit -> cdrom in the menu after the keymap configuration, then
you can invoke gdb.

 Thanx,
        Juergen




reply via email to

[Prev in Thread] Current Thread [Next in Thread]