Add qemu 2.4.0
[kvmfornfv.git] / qemu / target-alpha / int_helper.c
1 /*
2  *  Helpers for integer and multimedia instructions.
3  *
4  *  Copyright (c) 2007 Jocelyn Mayer
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 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 <http://www.gnu.org/licenses/>.
18  */
19
20 #include "cpu.h"
21 #include "exec/helper-proto.h"
22 #include "qemu/host-utils.h"
23
24
25 uint64_t helper_ctpop(uint64_t arg)
26 {
27     return ctpop64(arg);
28 }
29
30 uint64_t helper_ctlz(uint64_t arg)
31 {
32     return clz64(arg);
33 }
34
35 uint64_t helper_cttz(uint64_t arg)
36 {
37     return ctz64(arg);
38 }
39
40 uint64_t helper_zapnot(uint64_t val, uint64_t mskb)
41 {
42     uint64_t mask;
43
44     mask  = -(mskb & 0x01) & 0x00000000000000ffull;
45     mask |= -(mskb & 0x02) & 0x000000000000ff00ull;
46     mask |= -(mskb & 0x04) & 0x0000000000ff0000ull;
47     mask |= -(mskb & 0x08) & 0x00000000ff000000ull;
48     mask |= -(mskb & 0x10) & 0x000000ff00000000ull;
49     mask |= -(mskb & 0x20) & 0x0000ff0000000000ull;
50     mask |= -(mskb & 0x40) & 0x00ff000000000000ull;
51     mask |= -(mskb & 0x80) & 0xff00000000000000ull;
52
53     return val & mask;
54 }
55
56 uint64_t helper_zap(uint64_t val, uint64_t mask)
57 {
58     return helper_zapnot(val, ~mask);
59 }
60
61 uint64_t helper_cmpbge(uint64_t op1, uint64_t op2)
62 {
63     uint8_t opa, opb, res;
64     int i;
65
66     res = 0;
67     for (i = 0; i < 8; i++) {
68         opa = op1 >> (i * 8);
69         opb = op2 >> (i * 8);
70         if (opa >= opb) {
71             res |= 1 << i;
72         }
73     }
74     return res;
75 }
76
77 uint64_t helper_minub8(uint64_t op1, uint64_t op2)
78 {
79     uint64_t res = 0;
80     uint8_t opa, opb, opr;
81     int i;
82
83     for (i = 0; i < 8; ++i) {
84         opa = op1 >> (i * 8);
85         opb = op2 >> (i * 8);
86         opr = opa < opb ? opa : opb;
87         res |= (uint64_t)opr << (i * 8);
88     }
89     return res;
90 }
91
92 uint64_t helper_minsb8(uint64_t op1, uint64_t op2)
93 {
94     uint64_t res = 0;
95     int8_t opa, opb;
96     uint8_t opr;
97     int i;
98
99     for (i = 0; i < 8; ++i) {
100         opa = op1 >> (i * 8);
101         opb = op2 >> (i * 8);
102         opr = opa < opb ? opa : opb;
103         res |= (uint64_t)opr << (i * 8);
104     }
105     return res;
106 }
107
108 uint64_t helper_minuw4(uint64_t op1, uint64_t op2)
109 {
110     uint64_t res = 0;
111     uint16_t opa, opb, opr;
112     int i;
113
114     for (i = 0; i < 4; ++i) {
115         opa = op1 >> (i * 16);
116         opb = op2 >> (i * 16);
117         opr = opa < opb ? opa : opb;
118         res |= (uint64_t)opr << (i * 16);
119     }
120     return res;
121 }
122
123 uint64_t helper_minsw4(uint64_t op1, uint64_t op2)
124 {
125     uint64_t res = 0;
126     int16_t opa, opb;
127     uint16_t opr;
128     int i;
129
130     for (i = 0; i < 4; ++i) {
131         opa = op1 >> (i * 16);
132         opb = op2 >> (i * 16);
133         opr = opa < opb ? opa : opb;
134         res |= (uint64_t)opr << (i * 16);
135     }
136     return res;
137 }
138
139 uint64_t helper_maxub8(uint64_t op1, uint64_t op2)
140 {
141     uint64_t res = 0;
142     uint8_t opa, opb, opr;
143     int i;
144
145     for (i = 0; i < 8; ++i) {
146         opa = op1 >> (i * 8);
147         opb = op2 >> (i * 8);
148         opr = opa > opb ? opa : opb;
149         res |= (uint64_t)opr << (i * 8);
150     }
151     return res;
152 }
153
154 uint64_t helper_maxsb8(uint64_t op1, uint64_t op2)
155 {
156     uint64_t res = 0;
157     int8_t opa, opb;
158     uint8_t opr;
159     int i;
160
161     for (i = 0; i < 8; ++i) {
162         opa = op1 >> (i * 8);
163         opb = op2 >> (i * 8);
164         opr = opa > opb ? opa : opb;
165         res |= (uint64_t)opr << (i * 8);
166     }
167     return res;
168 }
169
170 uint64_t helper_maxuw4(uint64_t op1, uint64_t op2)
171 {
172     uint64_t res = 0;
173     uint16_t opa, opb, opr;
174     int i;
175
176     for (i = 0; i < 4; ++i) {
177         opa = op1 >> (i * 16);
178         opb = op2 >> (i * 16);
179         opr = opa > opb ? opa : opb;
180         res |= (uint64_t)opr << (i * 16);
181     }
182     return res;
183 }
184
185 uint64_t helper_maxsw4(uint64_t op1, uint64_t op2)
186 {
187     uint64_t res = 0;
188     int16_t opa, opb;
189     uint16_t opr;
190     int i;
191
192     for (i = 0; i < 4; ++i) {
193         opa = op1 >> (i * 16);
194         opb = op2 >> (i * 16);
195         opr = opa > opb ? opa : opb;
196         res |= (uint64_t)opr << (i * 16);
197     }
198     return res;
199 }
200
201 uint64_t helper_perr(uint64_t op1, uint64_t op2)
202 {
203     uint64_t res = 0;
204     uint8_t opa, opb, opr;
205     int i;
206
207     for (i = 0; i < 8; ++i) {
208         opa = op1 >> (i * 8);
209         opb = op2 >> (i * 8);
210         if (opa >= opb) {
211             opr = opa - opb;
212         } else {
213             opr = opb - opa;
214         }
215         res += opr;
216     }
217     return res;
218 }
219
220 uint64_t helper_pklb(uint64_t op1)
221 {
222     return (op1 & 0xff) | ((op1 >> 24) & 0xff00);
223 }
224
225 uint64_t helper_pkwb(uint64_t op1)
226 {
227     return ((op1 & 0xff)
228             | ((op1 >> 8) & 0xff00)
229             | ((op1 >> 16) & 0xff0000)
230             | ((op1 >> 24) & 0xff000000));
231 }
232
233 uint64_t helper_unpkbl(uint64_t op1)
234 {
235     return (op1 & 0xff) | ((op1 & 0xff00) << 24);
236 }
237
238 uint64_t helper_unpkbw(uint64_t op1)
239 {
240     return ((op1 & 0xff)
241             | ((op1 & 0xff00) << 8)
242             | ((op1 & 0xff0000) << 16)
243             | ((op1 & 0xff000000) << 24));
244 }
245
246 void helper_check_overflow(CPUAlphaState *env, uint64_t op1, uint64_t op2)
247 {
248     if (unlikely(op1 != op2)) {
249         arith_excp(env, GETPC(), EXC_M_IOV, 0);
250     }
251 }