]> Git Repo - qemu.git/blob - target-tilegx/helper.c
target-tilegx: Use TILEGX_EXCP_OPCODE_UNKNOWN and TILEGX_EXCP_OPCODE_UNIMPLEMENTED...
[qemu.git] / target-tilegx / helper.c
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 "cpu.h"
22 #include "qemu-common.h"
23 #include "exec/helper-proto.h"
24 #include <zlib.h> /* For crc32 */
25
26 void helper_exception(CPUTLGState *env, uint32_t excp)
27 {
28     CPUState *cs = CPU(tilegx_env_get_cpu(env));
29
30     cs->exception_index = excp;
31     cpu_loop_exit(cs);
32 }
33
34 uint64_t helper_cntlz(uint64_t arg)
35 {
36     return clz64(arg);
37 }
38
39 uint64_t helper_cnttz(uint64_t arg)
40 {
41     return ctz64(arg);
42 }
43
44 uint64_t helper_pcnt(uint64_t arg)
45 {
46     return ctpop64(arg);
47 }
48
49 uint64_t helper_revbits(uint64_t arg)
50 {
51     return revbit64(arg);
52 }
53
54 /*
55  * Functional Description
56  *     uint64_t a = rf[SrcA];
57  *     uint64_t b = rf[SrcB];
58  *     uint64_t d = rf[Dest];
59  *     uint64_t output = 0;
60  *     unsigned int counter;
61  *     for (counter = 0; counter < (WORD_SIZE / BYTE_SIZE); counter++)
62  *     {
63  *         int sel = getByte (b, counter) & 0xf;
64  *         uint8_t byte = (sel < 8) ? getByte (d, sel) : getByte (a, (sel - 8));
65  *         output = setByte (output, counter, byte);
66  *     }
67  *     rf[Dest] = output;
68  */
69 uint64_t helper_shufflebytes(uint64_t dest, uint64_t srca, uint64_t srcb)
70 {
71     uint64_t vdst = 0;
72     int count;
73
74     for (count = 0; count < 64; count += 8) {
75         uint64_t sel = srcb >> count;
76         uint64_t src = (sel & 8) ? srca : dest;
77         vdst |= extract64(src, (sel & 7) * 8, 8) << count;
78     }
79
80     return vdst;
81 }
82
83 uint64_t helper_crc32_8(uint64_t accum, uint64_t input)
84 {
85     uint8_t buf = input;
86
87     /* zlib crc32 converts the accumulator and output to one's complement.  */
88     return crc32(accum ^ 0xffffffff, &buf, 1) ^ 0xffffffff;
89 }
90
91 uint64_t helper_crc32_32(uint64_t accum, uint64_t input)
92 {
93     uint8_t buf[4];
94
95     stl_le_p(buf, input);
96
97     /* zlib crc32 converts the accumulator and output to one's complement.  */
98     return crc32(accum ^ 0xffffffff, buf, 4) ^ 0xffffffff;
99 }
100
101 uint64_t helper_cmula(uint64_t srcd, uint64_t srca, uint64_t srcb)
102 {
103     uint32_t reala = (int16_t)srca;
104     uint32_t imaga = (int16_t)(srca >> 16);
105     uint32_t realb = (int16_t)srcb;
106     uint32_t imagb = (int16_t)(srcb >> 16);
107     uint32_t reald = srcd;
108     uint32_t imagd = srcd >> 32;
109     uint32_t realr = reala * realb - imaga * imagb + reald;
110     uint32_t imagr = reala * imagb + imaga * realb + imagd;
111
112     return deposit64(realr, 32, 32, imagr);
113 }
114
115 uint64_t helper_cmulaf(uint64_t srcd, uint64_t srca, uint64_t srcb)
116 {
117     uint32_t reala = (int16_t)srca;
118     uint32_t imaga = (int16_t)(srca >> 16);
119     uint32_t realb = (int16_t)srcb;
120     uint32_t imagb = (int16_t)(srcb >> 16);
121     uint32_t reald = (int16_t)srcd;
122     uint32_t imagd = (int16_t)(srcd >> 16);
123     int32_t realr = reala * realb - imaga * imagb;
124     int32_t imagr = reala * imagb + imaga * realb;
125
126     return deposit32((realr >> 15) + reald, 16, 16, (imagr >> 15) + imagd);
127 }
128
129 uint64_t helper_cmul2(uint64_t srca, uint64_t srcb, int shift, int round)
130 {
131     uint32_t reala = (int16_t)srca;
132     uint32_t imaga = (int16_t)(srca >> 16);
133     uint32_t realb = (int16_t)srcb;
134     uint32_t imagb = (int16_t)(srcb >> 16);
135     int32_t realr = reala * realb - imaga * imagb + round;
136     int32_t imagr = reala * imagb + imaga * realb + round;
137
138     return deposit32(realr >> shift, 16, 16, imagr >> shift);
139 }
This page took 0.031303 seconds and 4 git commands to generate.