Change requested in launchpad bug #1288352
[packages/centos6/qemu.git] / 0056-tcg-hppa-Fix-brcond2-and-setcond2.patch
1 From 3616400bc0065f7114172ad7801d9d88332ef981 Mon Sep 17 00:00:00 2001
2 From: Richard Henderson <rth@twiddle.net>
3 Date: Tue, 18 Sep 2012 19:59:47 -0700
4 Subject: [PATCH] tcg-hppa: Fix brcond2 and setcond2
5
6 Neither of these functions were performing double-word
7 compares properly.
8
9 Signed-off-by: Richard Henderson <rth@twiddle.net>
10 Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
11 Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
12 ---
13  tcg/hppa/tcg-target.c | 51 ++++++++++++++++++++++++++++++++++++++++++---------
14  1 file changed, 42 insertions(+), 9 deletions(-)
15
16 diff --git a/tcg/hppa/tcg-target.c b/tcg/hppa/tcg-target.c
17 index 8b81b70..a76569d 100644
18 --- a/tcg/hppa/tcg-target.c
19 +++ b/tcg/hppa/tcg-target.c
20 @@ -820,19 +820,34 @@ static void tcg_out_comclr(TCGContext *s, int cond, TCGArg ret,
21      tcg_out32(s, op);
22  }
23  
24 +static TCGCond const tcg_high_cond[] = {
25 +    [TCG_COND_EQ] = TCG_COND_EQ,
26 +    [TCG_COND_NE] = TCG_COND_NE,
27 +    [TCG_COND_LT] = TCG_COND_LT,
28 +    [TCG_COND_LE] = TCG_COND_LT,
29 +    [TCG_COND_GT] = TCG_COND_GT,
30 +    [TCG_COND_GE] = TCG_COND_GT,
31 +    [TCG_COND_LTU] = TCG_COND_LTU,
32 +    [TCG_COND_LEU] = TCG_COND_LTU,
33 +    [TCG_COND_GTU] = TCG_COND_GTU,
34 +    [TCG_COND_GEU] = TCG_COND_GTU
35 +};
36 +
37  static void tcg_out_brcond2(TCGContext *s, int cond, TCGArg al, TCGArg ah,
38                              TCGArg bl, int blconst, TCGArg bh, int bhconst,
39                              int label_index)
40  {
41      switch (cond) {
42      case TCG_COND_EQ:
43 +        tcg_out_comclr(s, TCG_COND_NE, TCG_REG_R0, al, bl, blconst);
44 +        tcg_out_brcond(s, TCG_COND_EQ, ah, bh, bhconst, label_index);
45 +        break;
46      case TCG_COND_NE:
47 -        tcg_out_comclr(s, tcg_invert_cond(cond), TCG_REG_R0, al, bl, blconst);
48 -        tcg_out_brcond(s, cond, ah, bh, bhconst, label_index);
49 +        tcg_out_brcond(s, TCG_COND_NE, al, bl, bhconst, label_index);
50 +        tcg_out_brcond(s, TCG_COND_NE, ah, bh, bhconst, label_index);
51          break;
52 -
53      default:
54 -        tcg_out_brcond(s, cond, ah, bh, bhconst, label_index);
55 +        tcg_out_brcond(s, tcg_high_cond[cond], ah, bh, bhconst, label_index);
56          tcg_out_comclr(s, TCG_COND_NE, TCG_REG_R0, ah, bh, bhconst);
57          tcg_out_brcond(s, tcg_unsigned_cond(cond),
58                         al, bl, blconst, label_index);
59 @@ -853,9 +868,8 @@ static void tcg_out_setcond2(TCGContext *s, int cond, TCGArg ret,
60  {
61      int scratch = TCG_REG_R20;
62  
63 -    if (ret != al && ret != ah
64 -        && (blconst || ret != bl)
65 -        && (bhconst || ret != bh)) {
66 +    /* Note that the low parts are fully consumed before scratch is set.  */
67 +    if (ret != ah && (bhconst || ret != bh)) {
68          scratch = ret;
69      }
70  
71 @@ -867,13 +881,32 @@ static void tcg_out_setcond2(TCGContext *s, int cond, TCGArg ret,
72          tcg_out_movi(s, TCG_TYPE_I32, scratch, cond == TCG_COND_NE);
73          break;
74  
75 -    default:
76 +    case TCG_COND_GE:
77 +    case TCG_COND_GEU:
78 +    case TCG_COND_LT:
79 +    case TCG_COND_LTU:
80 +        /* Optimize compares with low part zero.  */
81 +        if (bl == 0) {
82 +            tcg_out_setcond(s, cond, ret, ah, bh, bhconst);
83 +            return;
84 +        }
85 +        /* FALLTHRU */
86 +
87 +    case TCG_COND_LE:
88 +    case TCG_COND_LEU:
89 +    case TCG_COND_GT:
90 +    case TCG_COND_GTU:
91 +        /* <= : ah < bh | (ah == bh && al <= bl) */
92          tcg_out_setcond(s, tcg_unsigned_cond(cond), scratch, al, bl, blconst);
93          tcg_out_comclr(s, TCG_COND_EQ, TCG_REG_R0, ah, bh, bhconst);
94          tcg_out_movi(s, TCG_TYPE_I32, scratch, 0);
95 -        tcg_out_comclr(s, cond, TCG_REG_R0, ah, bh, bhconst);
96 +        tcg_out_comclr(s, tcg_invert_cond(tcg_high_cond[cond]),
97 +                       TCG_REG_R0, ah, bh, bhconst);
98          tcg_out_movi(s, TCG_TYPE_I32, scratch, 1);
99          break;
100 +
101 +    default:
102 +        tcg_abort();
103      }
104  
105      tcg_out_mov(s, TCG_TYPE_I32, ret, scratch);
106 -- 
107 1.7.12.1
108