qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] Bug in s390 instruction emulation


From: Paolo Bonzini
Subject: Re: [Qemu-devel] Bug in s390 instruction emulation
Date: Sun, 14 Dec 2014 22:45:14 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.3.0


On 13/12/2014 23:10, Torbjörn Granlund wrote:
> I wrote:
> 
>   The s390 instruction emulation makes GMP fail most of its tests.
>   I have isolated one of the problems:
>   
>   How to reproduce:
>   
>   gcc m.c x.s
>   ./a.out
>   
>   Correct output on actual hardware:
>   ffffffff
>   
>   Incorrect output using QEMU 2.2.0 rc4:
>   0
>   
>   File m.c:
>   #include <stdio.h>
>   int foo();
>   int main() { printf("%x\n", foo()); return 0; }
>   
>   File x.s:
>       .text
>       .align  8
>       .globl  foo
>       .type   foo,@function
>   foo:        lghi    %r2, 0
>       lghi    %r3, 1
>       slgr    %r2, %r3
>       slbgr   %r3, %r3
>       slbgr   %r2, %r2
>       br      %r14
>   
> Turns out that all failures except 3 are due to subb borrow handling
> code which (almost) never works when there is borrow-in.  A minimal fix
> is quite simple:
> 
> *** /home/tege/qemu/qemu-2.2.0/target-s390x/.~/cc_helper.c.~1~        Tue Dec 
>  9 15:45:44 2014
> --- /home/tege/qemu/qemu-2.2.0/target-s390x/cc_helper.c       Sat Dec 13 
> 22:47:11 2014
> ***************
> *** 182,184 ****
>       /* We had borrow-in if normal subtraction isn't equal.  */
> !     int borrow_in = ar - (a1 - a2);
>       int borrow_out;
> --- 182,184 ----
>       /* We had borrow-in if normal subtraction isn't equal.  */
> !     int borrow_in = (a1 - a2) - ar;
>       int borrow_out;
> 
> There is at least one more instruction emulation error which I have not
> yet isolated [two test failures].  And then EX is not implemented for
> logical operations [one test failure].
> 
> This latter problem is adequately reported by qemu:
> qemu: fatal: EXECUTE on instruction prefix 0xd400 not implemented
> qemu: fatal: EXECUTE on instruction prefix 0xd600 not implemented

Something like this?

diff --git a/target-s390x/mem_helper.c b/target-s390x/mem_helper.c
index 5a55de8..4de3fc2 100644
--- a/target-s390x/mem_helper.c
+++ b/target-s390x/mem_helper.c
@@ -490,10 +490,18 @@ uint32_t HELPER(ex)(CPUS390XState *env, uint32_t cc, 
uint64_t v1,
             helper_mvc(env, l, get_address(env, 0, b1, d1),
                        get_address(env, 0, b2, d2));
             break;
+        case 0x400:
+            cc = helper_nc(env, l, get_address(env, 0, b1, d1),
+                            get_address(env, 0, b2, d2));
+            break;
         case 0x500:
             cc = helper_clc(env, l, get_address(env, 0, b1, d1),
                             get_address(env, 0, b2, d2));
             break;
+        case 0x600:
+            cc = helper_oc(env, l, get_address(env, 0, b1, d1),
+                            get_address(env, 0, b2, d2));
+            break;
         case 0x700:
             cc = helper_xc(env, l, get_address(env, 0, b1, d1),
                            get_address(env, 0, b2, d2));

Paolo



reply via email to

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