[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