arch-x86: implement POPCNT instruction.
[gem5.git] / src / arch / x86 / isa / insts / general_purpose / compare_and_test / bit_scan.py
1 # Copyright (c) 2007-2008 The Hewlett-Packard Development Company
2 # All rights reserved.
3 #
4 # The license below extends only to copyright in the software and shall
5 # not be construed as granting a license to any other intellectual
6 # property including but not limited to intellectual property relating
7 # to a hardware implementation of the functionality of the software
8 # licensed hereunder. You may use the software subject to the license
9 # terms below provided that you ensure that this notice is replicated
10 # unmodified and in its entirety in all distributions of the software,
11 # modified or unmodified, in source code or in binary form.
12 #
13 # Copyright (c) 2008 The Regents of The University of Michigan
14 # All rights reserved.
15 #
16 # Redistribution and use in source and binary forms, with or without
17 # modification, are permitted provided that the following conditions are
18 # met: redistributions of source code must retain the above copyright
19 # notice, this list of conditions and the following disclaimer;
20 # redistributions in binary form must reproduce the above copyright
21 # notice, this list of conditions and the following disclaimer in the
22 # documentation and/or other materials provided with the distribution;
23 # neither the name of the copyright holders nor the names of its
24 # contributors may be used to endorse or promote products derived from
25 # this software without specific prior written permission.
26 #
27 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38
39 microcode = '''
40 def macroop BSR_R_R {
41 # Determine if the input was zero, and also move it to a temp reg.
42 mov t1, t1, t0, dataSize=8
43 and t1, regm, regm, flags=(ZF,)
44 br label("end"), flags=(CZF,)
45
46 # Zero out the result register
47 movi reg, reg, 0x0
48
49 # Bit 6
50 srli t3, t1, 32, dataSize=8, flags=(EZF,)
51 ori t4, reg, 0x20
52 mov reg, reg, t4, flags=(nCEZF,)
53 mov t1, t1, t3, flags=(nCEZF,)
54
55 # Bit 5
56 srli t3, t1, 16, dataSize=8, flags=(EZF,)
57 ori t4, reg, 0x10
58 mov reg, reg, t4, flags=(nCEZF,)
59 mov t1, t1, t3, flags=(nCEZF,)
60
61 # Bit 4
62 srli t3, t1, 8, dataSize=8, flags=(EZF,)
63 ori t4, reg, 0x8
64 mov reg, reg, t4, flags=(nCEZF,)
65 mov t1, t1, t3, flags=(nCEZF,)
66
67 # Bit 3
68 srli t3, t1, 4, dataSize=8, flags=(EZF,)
69 ori t4, reg, 0x4
70 mov reg, reg, t4, flags=(nCEZF,)
71 mov t1, t1, t3, flags=(nCEZF,)
72
73 # Bit 2
74 srli t3, t1, 2, dataSize=8, flags=(EZF,)
75 ori t4, reg, 0x2
76 mov reg, reg, t4, flags=(nCEZF,)
77 mov t1, t1, t3, flags=(nCEZF,)
78
79 # Bit 1
80 srli t3, t1, 1, dataSize=8, flags=(EZF,)
81 ori t4, reg, 0x1
82 mov reg, reg, t4, flags=(nCEZF,)
83
84 end:
85 fault "NoFault"
86 };
87
88 def macroop BSR_R_M {
89
90 mov t1, t1, t0, dataSize=8
91 ld t1, seg, sib, disp
92
93 # Determine if the input was zero, and also move it to a temp reg.
94 and t1, t1, t1, flags=(ZF,)
95 br label("end"), flags=(CZF,)
96
97 # Zero out the result register
98 movi reg, reg, 0x0
99
100 # Bit 6
101 srli t3, t1, 32, dataSize=8, flags=(EZF,)
102 ori t4, reg, 0x20
103 mov reg, reg, t4, flags=(nCEZF,)
104 mov t1, t1, t3, flags=(nCEZF,)
105
106 # Bit 5
107 srli t3, t1, 16, dataSize=8, flags=(EZF,)
108 ori t4, reg, 0x10
109 mov reg, reg, t4, flags=(nCEZF,)
110 mov t1, t1, t3, flags=(nCEZF,)
111
112 # Bit 4
113 srli t3, t1, 8, dataSize=8, flags=(EZF,)
114 ori t4, reg, 0x8
115 mov reg, reg, t4, flags=(nCEZF,)
116 mov t1, t1, t3, flags=(nCEZF,)
117
118 # Bit 3
119 srli t3, t1, 4, dataSize=8, flags=(EZF,)
120 ori t4, reg, 0x4
121 mov reg, reg, t4, flags=(nCEZF,)
122 mov t1, t1, t3, flags=(nCEZF,)
123
124 # Bit 2
125 srli t3, t1, 2, dataSize=8, flags=(EZF,)
126 ori t4, reg, 0x2
127 mov reg, reg, t4, flags=(nCEZF,)
128 mov t1, t1, t3, flags=(nCEZF,)
129
130 # Bit 1
131 srli t3, t1, 1, dataSize=8, flags=(EZF,)
132 ori t4, reg, 0x1
133 mov reg, reg, t4, flags=(nCEZF,)
134
135 end:
136 fault "NoFault"
137 };
138
139 def macroop BSR_R_P {
140
141 rdip t7
142 mov t1, t1, t0, dataSize=8
143 ld t1, seg, riprel, disp
144
145 # Determine if the input was zero, and also move it to a temp reg.
146 and t1, t1, t1, flags=(ZF,)
147 br label("end"), flags=(CZF,)
148
149 # Zero out the result register
150 movi reg, reg, 0x0
151
152 # Bit 6
153 srli t3, t1, 32, dataSize=8, flags=(EZF,)
154 ori t4, reg, 0x20
155 mov reg, reg, t4, flags=(nCEZF,)
156 mov t1, t1, t3, flags=(nCEZF,)
157
158 # Bit 5
159 srli t3, t1, 16, dataSize=8, flags=(EZF,)
160 ori t4, reg, 0x10
161 mov reg, reg, t4, flags=(nCEZF,)
162 mov t1, t1, t3, flags=(nCEZF,)
163
164 # Bit 4
165 srli t3, t1, 8, dataSize=8, flags=(EZF,)
166 ori t4, reg, 0x8
167 mov reg, reg, t4, flags=(nCEZF,)
168 mov t1, t1, t3, flags=(nCEZF,)
169
170 # Bit 3
171 srli t3, t1, 4, dataSize=8, flags=(EZF,)
172 ori t4, reg, 0x4
173 mov reg, reg, t4, flags=(nCEZF,)
174 mov t1, t1, t3, flags=(nCEZF,)
175
176 # Bit 2
177 srli t3, t1, 2, dataSize=8, flags=(EZF,)
178 ori t4, reg, 0x2
179 mov reg, reg, t4, flags=(nCEZF,)
180 mov t1, t1, t3, flags=(nCEZF,)
181
182 # Bit 1
183 srli t3, t1, 1, dataSize=8, flags=(EZF,)
184 ori t4, reg, 0x1
185 mov reg, reg, t4, flags=(nCEZF,)
186
187 end:
188 fault "NoFault"
189 };
190
191 def macroop BSF_R_R {
192 # Determine if the input was zero, and also move it to a temp reg.
193 mov t1, t1, t0, dataSize=8
194 and t1, regm, regm, flags=(ZF,)
195 br label("end"), flags=(CZF,)
196
197 # Zero out the result register
198 movi reg, reg, 0
199
200 subi t2, t1, 1
201 xor t1, t2, t1
202
203
204 # Bit 6
205 srli t3, t1, 32, dataSize=8, flags=(EZF,)
206 ori t4, reg, 32
207 mov reg, reg, t4, flags=(nCEZF,)
208 mov t1, t1, t3, flags=(nCEZF,)
209
210 # Bit 5
211 srli t3, t1, 16, dataSize=8, flags=(EZF,)
212 ori t4, reg, 16
213 mov reg, reg, t4, flags=(nCEZF,)
214 mov t1, t1, t3, flags=(nCEZF,)
215
216 # Bit 4
217 srli t3, t1, 8, dataSize=8, flags=(EZF,)
218 ori t4, reg, 8
219 mov reg, reg, t4, flags=(nCEZF,)
220 mov t1, t1, t3, flags=(nCEZF,)
221
222 # Bit 3
223 srli t3, t1, 4, dataSize=8, flags=(EZF,)
224 ori t4, reg, 4
225 mov reg, reg, t4, flags=(nCEZF,)
226 mov t1, t1, t3, flags=(nCEZF,)
227
228 # Bit 2
229 srli t3, t1, 2, dataSize=8, flags=(EZF,)
230 ori t4, reg, 2
231 mov reg, reg, t4, flags=(nCEZF,)
232 mov t1, t1, t3, flags=(nCEZF,)
233
234 # Bit 1
235 srli t3, t1, 1, dataSize=8, flags=(EZF,)
236 ori t4, reg, 1
237 mov reg, reg, t4, flags=(nCEZF,)
238
239 end:
240 fault "NoFault"
241 };
242
243 def macroop BSF_R_M {
244
245 mov t1, t1, t0, dataSize=8
246 ld t1, seg, sib, disp
247
248 # Determine if the input was zero, and also move it to a temp reg.
249 and t1, t1, t1, flags=(ZF,)
250 br label("end"), flags=(CZF,)
251
252 # Zero out the result register
253 mov reg, reg, t0
254
255 subi t2, t1, 1
256 xor t1, t2, t1
257
258 # Bit 6
259 srli t3, t1, 32, dataSize=8, flags=(EZF,)
260 ori t4, reg, 32
261 mov reg, reg, t4, flags=(nCEZF,)
262 mov t1, t1, t3, flags=(nCEZF,)
263
264 # Bit 5
265 srli t3, t1, 16, dataSize=8, flags=(EZF,)
266 ori t4, reg, 16
267 mov reg, reg, t4, flags=(nCEZF,)
268 mov t1, t1, t3, flags=(nCEZF,)
269
270 # Bit 4
271 srli t3, t1, 8, dataSize=8, flags=(EZF,)
272 ori t4, reg, 8
273 mov reg, reg, t4, flags=(nCEZF,)
274 mov t1, t1, t3, flags=(nCEZF,)
275
276 # Bit 3
277 srli t3, t1, 4, dataSize=8, flags=(EZF,)
278 ori t4, reg, 4
279 mov reg, reg, t4, flags=(nCEZF,)
280 mov t1, t1, t3, flags=(nCEZF,)
281
282 # Bit 2
283 srli t3, t1, 2, dataSize=8, flags=(EZF,)
284 ori t4, reg, 2
285 mov reg, reg, t4, flags=(nCEZF,)
286 mov t1, t1, t3, flags=(nCEZF,)
287
288 # Bit 1
289 srli t3, t1, 1, dataSize=8, flags=(EZF,)
290 ori t4, reg, 1
291 mov reg, reg, t4, flags=(nCEZF,)
292 mov t1, t1, t3, flags=(nCEZF,)
293
294 end:
295 fault "NoFault"
296 };
297
298 def macroop BSF_R_P {
299
300 rdip t7
301 mov t1, t1, t0, dataSize=8
302 ld t1, seg, riprel, disp
303
304 # Determine if the input was zero, and also move it to a temp reg.
305 and t1, t1, t1, flags=(ZF,)
306 br label("end"), flags=(CZF,)
307
308 # Zero out the result register
309 mov reg, reg, t0
310
311 subi t2, t1, 1
312 xor t1, t2, t1
313
314 # Bit 6
315 srli t3, t1, 32, dataSize=8, flags=(EZF,)
316 ori t4, reg, 32
317 mov reg, reg, t4, flags=(nCEZF,)
318 mov t1, t1, t3, flags=(nCEZF,)
319
320 # Bit 5
321 srli t3, t1, 16, dataSize=8, flags=(EZF,)
322 ori t4, reg, 16
323 mov reg, reg, t4, flags=(nCEZF,)
324 mov t1, t1, t3, flags=(nCEZF,)
325
326 # Bit 4
327 srli t3, t1, 8, dataSize=8, flags=(EZF,)
328 ori t4, reg, 8
329 mov reg, reg, t4, flags=(nCEZF,)
330 mov t1, t1, t3, flags=(nCEZF,)
331
332 # Bit 3
333 srli t3, t1, 4, dataSize=8, flags=(EZF,)
334 ori t4, reg, 4
335 mov reg, reg, t4, flags=(nCEZF,)
336 mov t1, t1, t3, flags=(nCEZF,)
337
338 # Bit 2
339 srli t3, t1, 2, dataSize=8, flags=(EZF,)
340 ori t4, reg, 2
341 mov reg, reg, t4, flags=(nCEZF,)
342 mov t1, t1, t3, flags=(nCEZF,)
343
344 # Bit 1
345 srli t3, t1, 1, dataSize=8, flags=(EZF,)
346 ori t4, reg, 1
347 mov reg, reg, t4, flags=(nCEZF,)
348 mov t1, t1, t3, flags=(nCEZF,)
349
350 end:
351 fault "NoFault"
352 };
353
354 def macroop POPCNT_R_R {
355 popcnt reg, regm, reg, dataSize=8
356 };
357
358 def macroop POPCNT_R_M {
359 ld t1, seg, sib, disp
360 popcnt reg, t1, reg, dataSize=8
361 };
362
363 def macroop POPCNT_R_P {
364 rdip t7
365 ld t1, seg, riprel, disp
366 popcnt reg, t1, reg, dataSize=8
367 };
368 '''