diff mbox

Bug in s390 instruction emulation

Message ID 548E04EA.1030804@redhat.com
State New
Headers show

Commit Message

Paolo Bonzini Dec. 14, 2014, 9:45 p.m. UTC
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?


Paolo
diff mbox

Patch

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));