|
|
1.1 root 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 "helper.h"
22: #include "host-utils.h"
23:
24:
25: uint64_t helper_umulh(uint64_t op1, uint64_t op2)
26: {
27: uint64_t tl, th;
28: mulu64(&tl, &th, op1, op2);
29: return th;
30: }
31:
32: uint64_t helper_ctpop(uint64_t arg)
33: {
34: return ctpop64(arg);
35: }
36:
37: uint64_t helper_ctlz(uint64_t arg)
38: {
39: return clz64(arg);
40: }
41:
42: uint64_t helper_cttz(uint64_t arg)
43: {
44: return ctz64(arg);
45: }
46:
47: static inline uint64_t byte_zap(uint64_t op, uint8_t mskb)
48: {
49: uint64_t mask;
50:
51: mask = 0;
52: mask |= ((mskb >> 0) & 1) * 0x00000000000000FFULL;
53: mask |= ((mskb >> 1) & 1) * 0x000000000000FF00ULL;
54: mask |= ((mskb >> 2) & 1) * 0x0000000000FF0000ULL;
55: mask |= ((mskb >> 3) & 1) * 0x00000000FF000000ULL;
56: mask |= ((mskb >> 4) & 1) * 0x000000FF00000000ULL;
57: mask |= ((mskb >> 5) & 1) * 0x0000FF0000000000ULL;
58: mask |= ((mskb >> 6) & 1) * 0x00FF000000000000ULL;
59: mask |= ((mskb >> 7) & 1) * 0xFF00000000000000ULL;
60:
61: return op & ~mask;
62: }
63:
64: uint64_t helper_zap(uint64_t val, uint64_t mask)
65: {
66: return byte_zap(val, mask);
67: }
68:
69: uint64_t helper_zapnot(uint64_t val, uint64_t mask)
70: {
71: return byte_zap(val, ~mask);
72: }
73:
74: uint64_t helper_cmpbge(uint64_t op1, uint64_t op2)
75: {
76: uint8_t opa, opb, res;
77: int i;
78:
79: res = 0;
80: for (i = 0; i < 8; i++) {
81: opa = op1 >> (i * 8);
82: opb = op2 >> (i * 8);
83: if (opa >= opb) {
84: res |= 1 << i;
85: }
86: }
87: return res;
88: }
89:
90: uint64_t helper_minub8(uint64_t op1, uint64_t op2)
91: {
92: uint64_t res = 0;
93: uint8_t opa, opb, opr;
94: int i;
95:
96: for (i = 0; i < 8; ++i) {
97: opa = op1 >> (i * 8);
98: opb = op2 >> (i * 8);
99: opr = opa < opb ? opa : opb;
100: res |= (uint64_t)opr << (i * 8);
101: }
102: return res;
103: }
104:
105: uint64_t helper_minsb8(uint64_t op1, uint64_t op2)
106: {
107: uint64_t res = 0;
108: int8_t opa, opb;
109: uint8_t opr;
110: int i;
111:
112: for (i = 0; i < 8; ++i) {
113: opa = op1 >> (i * 8);
114: opb = op2 >> (i * 8);
115: opr = opa < opb ? opa : opb;
116: res |= (uint64_t)opr << (i * 8);
117: }
118: return res;
119: }
120:
121: uint64_t helper_minuw4(uint64_t op1, uint64_t op2)
122: {
123: uint64_t res = 0;
124: uint16_t opa, opb, opr;
125: int i;
126:
127: for (i = 0; i < 4; ++i) {
128: opa = op1 >> (i * 16);
129: opb = op2 >> (i * 16);
130: opr = opa < opb ? opa : opb;
131: res |= (uint64_t)opr << (i * 16);
132: }
133: return res;
134: }
135:
136: uint64_t helper_minsw4(uint64_t op1, uint64_t op2)
137: {
138: uint64_t res = 0;
139: int16_t opa, opb;
140: uint16_t opr;
141: int i;
142:
143: for (i = 0; i < 4; ++i) {
144: opa = op1 >> (i * 16);
145: opb = op2 >> (i * 16);
146: opr = opa < opb ? opa : opb;
147: res |= (uint64_t)opr << (i * 16);
148: }
149: return res;
150: }
151:
152: uint64_t helper_maxub8(uint64_t op1, uint64_t op2)
153: {
154: uint64_t res = 0;
155: uint8_t opa, opb, opr;
156: int i;
157:
158: for (i = 0; i < 8; ++i) {
159: opa = op1 >> (i * 8);
160: opb = op2 >> (i * 8);
161: opr = opa > opb ? opa : opb;
162: res |= (uint64_t)opr << (i * 8);
163: }
164: return res;
165: }
166:
167: uint64_t helper_maxsb8(uint64_t op1, uint64_t op2)
168: {
169: uint64_t res = 0;
170: int8_t opa, opb;
171: uint8_t opr;
172: int i;
173:
174: for (i = 0; i < 8; ++i) {
175: opa = op1 >> (i * 8);
176: opb = op2 >> (i * 8);
177: opr = opa > opb ? opa : opb;
178: res |= (uint64_t)opr << (i * 8);
179: }
180: return res;
181: }
182:
183: uint64_t helper_maxuw4(uint64_t op1, uint64_t op2)
184: {
185: uint64_t res = 0;
186: uint16_t opa, opb, opr;
187: int i;
188:
189: for (i = 0; i < 4; ++i) {
190: opa = op1 >> (i * 16);
191: opb = op2 >> (i * 16);
192: opr = opa > opb ? opa : opb;
193: res |= (uint64_t)opr << (i * 16);
194: }
195: return res;
196: }
197:
198: uint64_t helper_maxsw4(uint64_t op1, uint64_t op2)
199: {
200: uint64_t res = 0;
201: int16_t opa, opb;
202: uint16_t opr;
203: int i;
204:
205: for (i = 0; i < 4; ++i) {
206: opa = op1 >> (i * 16);
207: opb = op2 >> (i * 16);
208: opr = opa > opb ? opa : opb;
209: res |= (uint64_t)opr << (i * 16);
210: }
211: return res;
212: }
213:
214: uint64_t helper_perr(uint64_t op1, uint64_t op2)
215: {
216: uint64_t res = 0;
217: uint8_t opa, opb, opr;
218: int i;
219:
220: for (i = 0; i < 8; ++i) {
221: opa = op1 >> (i * 8);
222: opb = op2 >> (i * 8);
223: if (opa >= opb) {
224: opr = opa - opb;
225: } else {
226: opr = opb - opa;
227: }
228: res += opr;
229: }
230: return res;
231: }
232:
233: uint64_t helper_pklb(uint64_t op1)
234: {
235: return (op1 & 0xff) | ((op1 >> 24) & 0xff00);
236: }
237:
238: uint64_t helper_pkwb(uint64_t op1)
239: {
240: return ((op1 & 0xff)
241: | ((op1 >> 8) & 0xff00)
242: | ((op1 >> 16) & 0xff0000)
243: | ((op1 >> 24) & 0xff000000));
244: }
245:
246: uint64_t helper_unpkbl(uint64_t op1)
247: {
248: return (op1 & 0xff) | ((op1 & 0xff00) << 24);
249: }
250:
251: uint64_t helper_unpkbw(uint64_t op1)
252: {
253: return ((op1 & 0xff)
254: | ((op1 & 0xff00) << 8)
255: | ((op1 & 0xff0000) << 16)
256: | ((op1 & 0xff000000) << 24));
257: }
258:
259: uint64_t helper_addqv(CPUAlphaState *env, uint64_t op1, uint64_t op2)
260: {
261: uint64_t tmp = op1;
262: op1 += op2;
263: if (unlikely((tmp ^ op2 ^ (-1ULL)) & (tmp ^ op1) & (1ULL << 63))) {
264: arith_excp(env, GETPC(), EXC_M_IOV, 0);
265: }
266: return op1;
267: }
268:
269: uint64_t helper_addlv(CPUAlphaState *env, uint64_t op1, uint64_t op2)
270: {
271: uint64_t tmp = op1;
272: op1 = (uint32_t)(op1 + op2);
273: if (unlikely((tmp ^ op2 ^ (-1UL)) & (tmp ^ op1) & (1UL << 31))) {
274: arith_excp(env, GETPC(), EXC_M_IOV, 0);
275: }
276: return op1;
277: }
278:
279: uint64_t helper_subqv(CPUAlphaState *env, uint64_t op1, uint64_t op2)
280: {
281: uint64_t res;
282: res = op1 - op2;
283: if (unlikely((op1 ^ op2) & (res ^ op1) & (1ULL << 63))) {
284: arith_excp(env, GETPC(), EXC_M_IOV, 0);
285: }
286: return res;
287: }
288:
289: uint64_t helper_sublv(CPUAlphaState *env, uint64_t op1, uint64_t op2)
290: {
291: uint32_t res;
292: res = op1 - op2;
293: if (unlikely((op1 ^ op2) & (res ^ op1) & (1UL << 31))) {
294: arith_excp(env, GETPC(), EXC_M_IOV, 0);
295: }
296: return res;
297: }
298:
299: uint64_t helper_mullv(CPUAlphaState *env, uint64_t op1, uint64_t op2)
300: {
301: int64_t res = (int64_t)op1 * (int64_t)op2;
302:
303: if (unlikely((int32_t)res != res)) {
304: arith_excp(env, GETPC(), EXC_M_IOV, 0);
305: }
306: return (int64_t)((int32_t)res);
307: }
308:
309: uint64_t helper_mulqv(CPUAlphaState *env, uint64_t op1, uint64_t op2)
310: {
311: uint64_t tl, th;
312:
313: muls64(&tl, &th, op1, op2);
314: /* If th != 0 && th != -1, then we had an overflow */
315: if (unlikely((th + 1) > 1)) {
316: arith_excp(env, GETPC(), EXC_M_IOV, 0);
317: }
318: return tl;
319: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.