1 | /* |
2 | * QEMU TILE-Gx helpers |
3 | * |
4 | * Copyright (c) 2015 Chen Gang |
5 | * |
6 | * This library is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU Lesser General Public |
8 | * License as published by the Free Software Foundation; either |
9 | * version 2.1 of the License, or (at your option) any later version. |
10 | * |
11 | * This library is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | * Lesser General Public License for more details. |
15 | * |
16 | * You should have received a copy of the GNU Lesser General Public |
17 | * License along with this library; if not, see |
18 | * <http://www.gnu.org/licenses/lgpl-2.1.html> |
19 | */ |
20 | |
21 | #include "qemu/osdep.h" |
22 | #include "cpu.h" |
23 | #include "exec/helper-proto.h" |
24 | |
25 | |
26 | /* Broadcast a value to all elements of a vector. */ |
27 | #define V1(X) (((X) & 0xff) * 0x0101010101010101ull) |
28 | #define V2(X) (((X) & 0xffff) * 0x0001000100010001ull) |
29 | |
30 | |
31 | uint64_t helper_v1multu(uint64_t a, uint64_t b) |
32 | { |
33 | uint64_t r = 0; |
34 | int i; |
35 | |
36 | for (i = 0; i < 64; i += 8) { |
37 | unsigned ae = extract64(a, i, 8); |
38 | unsigned be = extract64(b, i, 8); |
39 | r = deposit64(r, i, 8, ae * be); |
40 | } |
41 | return r; |
42 | } |
43 | |
44 | uint64_t helper_v2mults(uint64_t a, uint64_t b) |
45 | { |
46 | uint64_t r = 0; |
47 | int i; |
48 | |
49 | /* While the instruction talks about signed inputs, with a |
50 | truncated result the sign of the inputs doesn't matter. */ |
51 | for (i = 0; i < 64; i += 16) { |
52 | unsigned ae = extract64(a, i, 16); |
53 | unsigned be = extract64(b, i, 16); |
54 | r = deposit64(r, i, 16, ae * be); |
55 | } |
56 | return r; |
57 | } |
58 | |
59 | uint64_t helper_v1shl(uint64_t a, uint64_t b) |
60 | { |
61 | uint64_t m; |
62 | |
63 | b &= 7; |
64 | m = V1(0xff >> b); |
65 | return (a & m) << b; |
66 | } |
67 | |
68 | uint64_t helper_v2shl(uint64_t a, uint64_t b) |
69 | { |
70 | uint64_t m; |
71 | |
72 | b &= 15; |
73 | m = V2(0xffff >> b); |
74 | return (a & m) << b; |
75 | } |
76 | |
77 | uint64_t helper_v1shru(uint64_t a, uint64_t b) |
78 | { |
79 | uint64_t m; |
80 | |
81 | b &= 7; |
82 | m = V1(0xff << b); |
83 | return (a & m) >> b; |
84 | } |
85 | |
86 | uint64_t helper_v2shru(uint64_t a, uint64_t b) |
87 | { |
88 | uint64_t m; |
89 | |
90 | b &= 15; |
91 | m = V2(0xffff << b); |
92 | return (a & m) >> b; |
93 | } |
94 | |
95 | uint64_t helper_v1shrs(uint64_t a, uint64_t b) |
96 | { |
97 | uint64_t r = 0; |
98 | int i; |
99 | |
100 | b &= 7; |
101 | for (i = 0; i < 64; i += 8) { |
102 | r = deposit64(r, i, 8, sextract64(a, i + b, 8 - b)); |
103 | } |
104 | return r; |
105 | } |
106 | |
107 | uint64_t helper_v2shrs(uint64_t a, uint64_t b) |
108 | { |
109 | uint64_t r = 0; |
110 | int i; |
111 | |
112 | b &= 15; |
113 | for (i = 0; i < 64; i += 16) { |
114 | r = deposit64(r, i, 16, sextract64(a, i + b, 16 - b)); |
115 | } |
116 | return r; |
117 | } |
118 | |
119 | uint64_t helper_v1int_h(uint64_t a, uint64_t b) |
120 | { |
121 | uint64_t r = 0; |
122 | int i; |
123 | |
124 | for (i = 0; i < 32; i += 8) { |
125 | r = deposit64(r, 2 * i + 8, 8, extract64(a, i + 32, 8)); |
126 | r = deposit64(r, 2 * i, 8, extract64(b, i + 32, 8)); |
127 | } |
128 | return r; |
129 | } |
130 | |
131 | uint64_t helper_v1int_l(uint64_t a, uint64_t b) |
132 | { |
133 | uint64_t r = 0; |
134 | int i; |
135 | |
136 | for (i = 0; i < 32; i += 8) { |
137 | r = deposit64(r, 2 * i + 8, 8, extract64(a, i, 8)); |
138 | r = deposit64(r, 2 * i, 8, extract64(b, i, 8)); |
139 | } |
140 | return r; |
141 | } |
142 | |
143 | uint64_t helper_v2int_h(uint64_t a, uint64_t b) |
144 | { |
145 | uint64_t r = 0; |
146 | int i; |
147 | |
148 | for (i = 0; i < 32; i += 16) { |
149 | r = deposit64(r, 2 * i + 16, 16, extract64(a, i + 32, 16)); |
150 | r = deposit64(r, 2 * i, 16, extract64(b, i + 32, 16)); |
151 | } |
152 | return r; |
153 | } |
154 | |
155 | uint64_t helper_v2int_l(uint64_t a, uint64_t b) |
156 | { |
157 | uint64_t r = 0; |
158 | int i; |
159 | |
160 | for (i = 0; i < 32; i += 16) { |
161 | r = deposit64(r, 2 * i + 16, 16, extract64(a, i, 16)); |
162 | r = deposit64(r, 2 * i, 16, extract64(b, i, 16)); |
163 | } |
164 | return r; |
165 | } |
166 | |