~ubuntu-branches/ubuntu/vivid/qemu/vivid

« back to all changes in this revision

Viewing changes to debian/patches/ubuntu/arm64/0137-target-arm-A64-Add-integer-ops-from-SIMD-3-same-grou.patch

  • Committer: Package Import Robot
  • Author(s): dann frazier
  • Date: 2014-02-11 15:41:53 UTC
  • Revision ID: package-import@ubuntu.com-20140211154153-2d001tf0ium08u81
Tags: 1.7.0+dfsg-3ubuntu2
* Backport changes to enable qemu-user-static support for aarch64
* debian/control: add ppc64el to Architectures
* debian/rules: only install qemu-system-aarch64 on arm64.
  Fixes a FTBFS  when built twice in a row on non-arm64 due to a stale
  debian/qemu-system-aarch64 directory

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
From 63eb4e807f53c966897628cf93a4fa977d649226 Mon Sep 17 00:00:00 2001
 
2
From: Peter Maydell <peter.maydell@linaro.org>
 
3
Date: Fri, 31 Jan 2014 14:47:37 +0000
 
4
Subject: [PATCH 137/158] target-arm: A64: Add integer ops from SIMD 3-same
 
5
 group
 
6
 
 
7
Add some of the integer operations in the SIMD 3-same group:
 
8
specifically, the comparisons, addition and subtraction.
 
9
 
 
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
 
11
Reviewed-by: Richard Henderson <rth@twiddle.net>
 
12
---
 
13
 target-arm/translate-a64.c | 165 ++++++++++++++++++++++++++++++++++++++++++++-
 
14
 1 file changed, 164 insertions(+), 1 deletion(-)
 
15
 
 
16
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
 
17
index aa53ddc..9e7401c 100644
 
18
--- a/target-arm/translate-a64.c
 
19
+++ b/target-arm/translate-a64.c
 
20
@@ -72,6 +72,9 @@ typedef struct AArch64DecodeTable {
 
21
     AArch64DecodeFn *disas_fn;
 
22
 } AArch64DecodeTable;
 
23
 
 
24
+/* Function prototype for gen_ functions for calling Neon helpers */
 
25
+typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32);
 
26
+
 
27
 /* initialize TCG globals.  */
 
28
 void a64_translate_init(void)
 
29
 {
 
30
@@ -787,6 +790,25 @@ static void write_vec_element(DisasContext *s, TCGv_i64 tcg_src, int destidx,
 
31
     }
 
32
 }
 
33
 
 
34
+static void write_vec_element_i32(DisasContext *s, TCGv_i32 tcg_src,
 
35
+                                  int destidx, int element, TCGMemOp memop)
 
36
+{
 
37
+    int vect_off = vec_reg_offset(destidx, element, memop & MO_SIZE);
 
38
+    switch (memop) {
 
39
+    case MO_8:
 
40
+        tcg_gen_st8_i32(tcg_src, cpu_env, vect_off);
 
41
+        break;
 
42
+    case MO_16:
 
43
+        tcg_gen_st16_i32(tcg_src, cpu_env, vect_off);
 
44
+        break;
 
45
+    case MO_32:
 
46
+        tcg_gen_st_i32(tcg_src, cpu_env, vect_off);
 
47
+        break;
 
48
+    default:
 
49
+        g_assert_not_reached();
 
50
+    }
 
51
+}
 
52
+
 
53
 /* Clear the high 64 bits of a 128 bit vector (in general non-quad
 
54
  * vector ops all need to do this).
 
55
  */
 
56
@@ -6012,7 +6034,148 @@ static void disas_simd_3same_float(DisasContext *s, uint32_t insn)
 
57
 /* Integer op subgroup of C3.6.16. */
 
58
 static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
 
59
 {
 
60
-    unsupported_encoding(s, insn);
 
61
+    int is_q = extract32(insn, 30, 1);
 
62
+    int u = extract32(insn, 29, 1);
 
63
+    int size = extract32(insn, 22, 2);
 
64
+    int opcode = extract32(insn, 11, 5);
 
65
+    int rm = extract32(insn, 16, 5);
 
66
+    int rn = extract32(insn, 5, 5);
 
67
+    int rd = extract32(insn, 0, 5);
 
68
+    int pass;
 
69
+
 
70
+    switch (opcode) {
 
71
+    case 0x13: /* MUL, PMUL */
 
72
+        if (u && size != 0) {
 
73
+            unallocated_encoding(s);
 
74
+            return;
 
75
+        }
 
76
+        /* fall through */
 
77
+    case 0x0: /* SHADD, UHADD */
 
78
+    case 0x2: /* SRHADD, URHADD */
 
79
+    case 0x4: /* SHSUB, UHSUB */
 
80
+    case 0xc: /* SMAX, UMAX */
 
81
+    case 0xd: /* SMIN, UMIN */
 
82
+    case 0xe: /* SABD, UABD */
 
83
+    case 0xf: /* SABA, UABA */
 
84
+    case 0x12: /* MLA, MLS */
 
85
+        if (size == 3) {
 
86
+            unallocated_encoding(s);
 
87
+            return;
 
88
+        }
 
89
+        unsupported_encoding(s, insn);
 
90
+        return;
 
91
+    case 0x1: /* SQADD */
 
92
+    case 0x5: /* SQSUB */
 
93
+    case 0x8: /* SSHL, USHL */
 
94
+    case 0x9: /* SQSHL, UQSHL */
 
95
+    case 0xa: /* SRSHL, URSHL */
 
96
+    case 0xb: /* SQRSHL, UQRSHL */
 
97
+        if (size == 3 && !is_q) {
 
98
+            unallocated_encoding(s);
 
99
+            return;
 
100
+        }
 
101
+        unsupported_encoding(s, insn);
 
102
+        return;
 
103
+    case 0x16: /* SQDMULH, SQRDMULH */
 
104
+        if (size == 0 || size == 3) {
 
105
+            unallocated_encoding(s);
 
106
+            return;
 
107
+        }
 
108
+        unsupported_encoding(s, insn);
 
109
+        return;
 
110
+    default:
 
111
+        if (size == 3 && !is_q) {
 
112
+            unallocated_encoding(s);
 
113
+            return;
 
114
+        }
 
115
+        break;
 
116
+    }
 
117
+
 
118
+    if (size == 3) {
 
119
+        for (pass = 0; pass < (is_q ? 2 : 1); pass++) {
 
120
+            TCGv_i64 tcg_op1 = tcg_temp_new_i64();
 
121
+            TCGv_i64 tcg_op2 = tcg_temp_new_i64();
 
122
+            TCGv_i64 tcg_res = tcg_temp_new_i64();
 
123
+
 
124
+            read_vec_element(s, tcg_op1, rn, pass, MO_64);
 
125
+            read_vec_element(s, tcg_op2, rm, pass, MO_64);
 
126
+
 
127
+            handle_3same_64(s, opcode, u, tcg_res, tcg_op1, tcg_op2);
 
128
+
 
129
+            write_vec_element(s, tcg_res, rd, pass, MO_64);
 
130
+
 
131
+            tcg_temp_free_i64(tcg_res);
 
132
+            tcg_temp_free_i64(tcg_op1);
 
133
+            tcg_temp_free_i64(tcg_op2);
 
134
+        }
 
135
+    } else {
 
136
+        for (pass = 0; pass < (is_q ? 4 : 2); pass++) {
 
137
+            TCGv_i32 tcg_op1 = tcg_temp_new_i32();
 
138
+            TCGv_i32 tcg_op2 = tcg_temp_new_i32();
 
139
+            TCGv_i32 tcg_res = tcg_temp_new_i32();
 
140
+            NeonGenTwoOpFn *genfn;
 
141
+
 
142
+            read_vec_element_i32(s, tcg_op1, rn, pass, MO_32);
 
143
+            read_vec_element_i32(s, tcg_op2, rm, pass, MO_32);
 
144
+
 
145
+            switch (opcode) {
 
146
+            case 0x6: /* CMGT, CMHI */
 
147
+            {
 
148
+                static NeonGenTwoOpFn * const fns[3][2] = {
 
149
+                    { gen_helper_neon_cgt_s8, gen_helper_neon_cgt_u8 },
 
150
+                    { gen_helper_neon_cgt_s16, gen_helper_neon_cgt_u16 },
 
151
+                    { gen_helper_neon_cgt_s32, gen_helper_neon_cgt_u32 },
 
152
+                };
 
153
+                genfn = fns[size][u];
 
154
+                break;
 
155
+            }
 
156
+            case 0x7: /* CMGE, CMHS */
 
157
+            {
 
158
+                static NeonGenTwoOpFn * const fns[3][2] = {
 
159
+                    { gen_helper_neon_cge_s8, gen_helper_neon_cge_u8 },
 
160
+                    { gen_helper_neon_cge_s16, gen_helper_neon_cge_u16 },
 
161
+                    { gen_helper_neon_cge_s32, gen_helper_neon_cge_u32 },
 
162
+                };
 
163
+                genfn = fns[size][u];
 
164
+                break;
 
165
+            }
 
166
+            case 0x10: /* ADD, SUB */
 
167
+            {
 
168
+                static NeonGenTwoOpFn * const fns[3][2] = {
 
169
+                    { gen_helper_neon_add_u8, gen_helper_neon_sub_u8 },
 
170
+                    { gen_helper_neon_add_u16, gen_helper_neon_sub_u16 },
 
171
+                    { tcg_gen_add_i32, tcg_gen_sub_i32 },
 
172
+                };
 
173
+                genfn = fns[size][u];
 
174
+                break;
 
175
+            }
 
176
+            case 0x11: /* CMTST, CMEQ */
 
177
+            {
 
178
+                static NeonGenTwoOpFn * const fns[3][2] = {
 
179
+                    { gen_helper_neon_tst_u8, gen_helper_neon_ceq_u8 },
 
180
+                    { gen_helper_neon_tst_u16, gen_helper_neon_ceq_u16 },
 
181
+                    { gen_helper_neon_tst_u32, gen_helper_neon_ceq_u32 },
 
182
+                };
 
183
+                genfn = fns[size][u];
 
184
+                break;
 
185
+            }
 
186
+            default:
 
187
+                g_assert_not_reached();
 
188
+            }
 
189
+
 
190
+            genfn(tcg_res, tcg_op1, tcg_op2);
 
191
+
 
192
+            write_vec_element_i32(s, tcg_res, rd, pass, MO_32);
 
193
+
 
194
+            tcg_temp_free_i32(tcg_res);
 
195
+            tcg_temp_free_i32(tcg_op1);
 
196
+            tcg_temp_free_i32(tcg_op2);
 
197
+        }
 
198
+    }
 
199
+
 
200
+    if (!is_q) {
 
201
+        clear_vec_high(s, rd);
 
202
+    }
 
203
 }
 
204
 
 
205
 /* C3.6.16 AdvSIMD three same
 
206
-- 
 
207
1.9.rc1
 
208