core: Implement the setb instruction
[microwatt.git] / ppc_fx_insns.vhdl
1 library ieee;
2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
4
5 library work;
6 use work.helpers.all;
7
8 package ppc_fx_insns is
9 function ppc_addi (ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector;
10 function ppc_addis (ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector;
11 function ppc_add (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
12 function ppc_subf (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
13 function ppc_neg (ra: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
14
15 function ppc_addic (ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector;
16 function ppc_adde (ra, rb: std_ulogic_vector(63 downto 0); carry: std_ulogic) return std_ulogic_vector;
17 function ppc_subfic (ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector;
18 function ppc_subfc (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
19 function ppc_subfe (ra, rb: std_ulogic_vector(63 downto 0); carry: std_ulogic) return std_ulogic_vector;
20 function ppc_addze (ra: std_ulogic_vector(63 downto 0); carry: std_ulogic) return std_ulogic_vector;
21
22 function ppc_andi (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector;
23 function ppc_andis (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector;
24 function ppc_ori (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector;
25 function ppc_oris (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector;
26 function ppc_xori (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector;
27 function ppc_xoris (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector;
28 function ppc_and (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
29 function ppc_xor (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
30 function ppc_nand (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
31 function ppc_or (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
32 function ppc_nor (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
33 function ppc_andc (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
34 function ppc_eqv (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
35 function ppc_orc (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
36
37 function ppc_extsb (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
38 function ppc_extsh (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
39 function ppc_extsw (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
40
41 function ppc_cntlzw (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
42 function ppc_cnttzw (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
43 function ppc_cntlzd (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
44 function ppc_cnttzd (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
45
46 function ppc_popcntb (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
47 function ppc_popcntw (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
48 function ppc_popcntd (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
49
50 function ppc_prtyd (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
51 function ppc_prtyw (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
52
53 function ppc_rlwinm (rs: std_ulogic_vector(63 downto 0); sh, mb, me: std_ulogic_vector(4 downto 0)) return std_ulogic_vector;
54 function ppc_rlwnm (rs, rb: std_ulogic_vector(63 downto 0); mb, me: std_ulogic_vector(4 downto 0)) return std_ulogic_vector;
55 function ppc_rlwimi (ra, rs: std_ulogic_vector(63 downto 0); sh, mb, me: std_ulogic_vector(4 downto 0)) return std_ulogic_vector;
56 function ppc_rldicl (rs: std_ulogic_vector(63 downto 0); sh, mb: std_ulogic_vector(5 downto 0)) return std_ulogic_vector;
57 function ppc_rldicr (rs: std_ulogic_vector(63 downto 0); sh, me: std_ulogic_vector(5 downto 0)) return std_ulogic_vector;
58 function ppc_rldic (rs: std_ulogic_vector(63 downto 0); sh, mb: std_ulogic_vector(5 downto 0)) return std_ulogic_vector;
59 function ppc_rldcl (rs, rb: std_ulogic_vector(63 downto 0); mb: std_ulogic_vector(5 downto 0)) return std_ulogic_vector;
60 function ppc_rldcr (rs, rb: std_ulogic_vector(63 downto 0); me: std_ulogic_vector(5 downto 0)) return std_ulogic_vector;
61 function ppc_rldimi (ra, rs: std_ulogic_vector(63 downto 0); sh, mb: std_ulogic_vector(5 downto 0)) return std_ulogic_vector;
62
63 function ppc_slw (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
64 function ppc_srw (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
65 function ppc_srawi (rs : std_ulogic_vector(63 downto 0); sh: std_ulogic_vector(5 downto 0)) return std_ulogic_vector;
66 function ppc_sraw (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
67 function ppc_sld (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
68 function ppc_srd (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
69 function ppc_sradi (rs: std_ulogic_vector(63 downto 0); sh: std_ulogic_vector(5 downto 0)) return std_ulogic_vector;
70 function ppc_srad (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
71
72 function ppc_mulld (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
73 function ppc_mulhd (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
74 function ppc_mulhdu (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
75 function ppc_mulli (ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector;
76 function ppc_mullw (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
77 function ppc_mulhw (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
78 function ppc_mulhwu (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
79
80 function ppc_cmpi (l: std_ulogic; ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0);
81 so: std_ulogic) return std_ulogic_vector;
82 function ppc_cmp (l: std_ulogic; ra, rb: std_ulogic_vector(63 downto 0);
83 so: std_ulogic) return std_ulogic_vector;
84 function ppc_cmpli (l: std_ulogic; ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0);
85 so: std_ulogic) return std_ulogic_vector;
86 function ppc_cmpl (l: std_ulogic; ra, rb: std_ulogic_vector(63 downto 0);
87 so: std_ulogic) return std_ulogic_vector;
88
89 function ppc_cmpb (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
90
91 function ppc_divw (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
92 function ppc_divdu (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
93 function ppc_divd (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
94 function ppc_divwu (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
95
96 function ppc_bc_taken(bo, bi: std_ulogic_vector(4 downto 0); cr: std_ulogic_vector(31 downto 0); ctr: std_ulogic_vector(63 downto 0)) return std_ulogic;
97 end package ppc_fx_insns;
98
99 package body ppc_fx_insns is
100 function ppc_addi (ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is
101 begin
102 return std_ulogic_vector(signed(ra) + signed(si));
103 end;
104
105 function ppc_addic (ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is
106 begin
107 return std_logic_vector(resize(unsigned(ra), 65) + unsigned(resize(signed(si), 64)));
108 end;
109
110 function ppc_adde (ra, rb: std_ulogic_vector(63 downto 0); carry: std_ulogic) return std_ulogic_vector is
111 begin
112 return std_logic_vector(resize(unsigned(ra), 65) + resize(unsigned(rb), 65) + carry);
113 end;
114
115 function ppc_subfic (ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is
116 begin
117 return std_logic_vector(unsigned(resize(signed(si), 64)) + resize(unsigned(not(ra)), 65) + 1);
118 end;
119
120 function ppc_subfc (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
121 begin
122 return std_logic_vector(resize(unsigned(rb), 65) + resize(unsigned(not(ra)), 65) + 1);
123 end;
124
125 function ppc_subfe (ra, rb: std_ulogic_vector(63 downto 0); carry: std_ulogic) return std_ulogic_vector is
126 begin
127 return std_logic_vector(resize(unsigned(rb), 65) + resize(unsigned(not(ra)), 65) + carry);
128 end;
129
130 function ppc_addze (ra: std_ulogic_vector(63 downto 0); carry: std_ulogic) return std_ulogic_vector is
131 begin
132 return std_logic_vector(resize(unsigned(ra), 65) + carry);
133 end;
134
135 function ppc_addis (ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is
136 begin
137 return std_ulogic_vector(signed(ra) + shift_left(resize(signed(si), 32), 16));
138 end;
139
140 function ppc_add (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
141 begin
142 return std_ulogic_vector(signed(ra) + signed(rb));
143 end;
144
145 function ppc_subf (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
146 begin
147 return std_ulogic_vector(signed(rb) - signed(ra));
148 end;
149
150 function ppc_neg (ra: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
151 begin
152 return std_ulogic_vector(-signed(ra));
153 end;
154
155 function ppc_andi (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is
156 begin
157 return rs and std_ulogic_vector(resize(unsigned(ui), 64));
158 end;
159
160 function ppc_andis (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is
161 begin
162 return rs and std_ulogic_vector(shift_left(resize(unsigned(ui), 64), 16));
163 end;
164
165 function ppc_ori (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is
166 begin
167 return rs or std_ulogic_vector(resize(unsigned(ui), 64));
168 end;
169
170 function ppc_oris (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is
171 begin
172 return rs or std_ulogic_vector(shift_left(resize(unsigned(ui), 64), 16));
173 end;
174
175 function ppc_xori (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is
176 begin
177 return rs xor std_ulogic_vector(resize(unsigned(ui), 64));
178 end;
179
180 function ppc_xoris (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is
181 begin
182 return rs xor std_ulogic_vector(shift_left(resize(unsigned(ui), 64), 16));
183 end;
184
185 function ppc_and (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
186 begin
187 return rs and rb;
188 end;
189
190 function ppc_xor (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
191 begin
192 return rs xor rb;
193 end;
194
195 function ppc_nand (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
196 begin
197 return rs nand rb;
198 end;
199
200 function ppc_or (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
201 begin
202 return rs or rb;
203 end;
204
205 function ppc_nor (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
206 begin
207 return rs nor rb;
208 end;
209
210 function ppc_andc (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
211 begin
212 return rs and not(rb);
213 end;
214
215 function ppc_eqv (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
216 begin
217 return not(rs xor rb);
218 end;
219
220 function ppc_orc (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
221 begin
222 return rs or not(rb);
223 end;
224
225 function ppc_extsb (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
226 begin
227 return std_ulogic_vector(resize(signed(rs(7 downto 0)), rs'length));
228 end;
229
230 function ppc_extsh (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
231 begin
232 return std_ulogic_vector(resize(signed(rs(15 downto 0)), rs'length));
233 end;
234
235 function ppc_extsw (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
236 begin
237 return std_ulogic_vector(resize(signed(rs(31 downto 0)), rs'length));
238 end;
239
240 function ppc_cntlzw (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
241 begin
242 return std_ulogic_vector(to_unsigned(fls_32(rs(31 downto 0)), rs'length));
243 end;
244
245 function ppc_cnttzw (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
246 begin
247 return std_ulogic_vector(to_unsigned(ffs_32(rs(31 downto 0)), rs'length));
248 end;
249
250 function ppc_cntlzd (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
251 begin
252 return std_ulogic_vector(to_unsigned(fls_64(rs), rs'length));
253 end;
254
255 function ppc_cnttzd (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
256 begin
257 return std_ulogic_vector(to_unsigned(ffs_64(rs), rs'length));
258 end;
259
260 function ppc_popcntb (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
261 variable ret: std_ulogic_vector (rs'range);
262 variable hi: integer;
263 variable lo: integer;
264 begin
265 ret := (others => '0');
266
267 for i in 1 to 8 loop
268 hi := (8*i)-1;
269 lo := 8*(i-1);
270 ret(hi downto lo) := popcnt8(rs(hi downto lo));
271 end loop;
272
273 return ret;
274 end;
275
276 function ppc_popcntw (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
277 variable ret: std_ulogic_vector (rs'range);
278 variable hi: integer;
279 variable lo: integer;
280 begin
281 ret := (others => '0');
282
283 for i in 1 to 2 loop
284 hi := (32*i)-1;
285 lo := 32*(i-1);
286 ret(hi downto lo) := popcnt32(rs(hi downto lo));
287 end loop;
288
289 return ret;
290 end;
291
292 function ppc_popcntd (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
293 begin
294 return popcnt64(rs);
295 end;
296
297 function ppc_prtyd (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
298 variable tmp : std_ulogic;
299 variable ret : std_ulogic_vector(63 downto 0);
300 begin
301 ret := (others => '0');
302
303 tmp := '0';
304 for i in 0 to 7 loop
305 tmp := tmp xor rs(i*8);
306 end loop;
307
308 ret(0) := tmp;
309 return ret;
310 end;
311
312 function ppc_prtyw (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
313 variable tmp : std_ulogic;
314 variable ret : std_ulogic_vector(63 downto 0);
315 begin
316 ret := (others => '0');
317
318 tmp := '0';
319 for i in 0 to 3 loop
320 tmp := tmp xor rs(i*8);
321 end loop;
322 ret(0) := tmp;
323
324 tmp := '0';
325 for i in 4 to 7 loop
326 tmp := tmp xor rs(i*8);
327 end loop;
328 ret(32) := tmp;
329
330 return ret;
331 end;
332
333 function ppc_rlwinm (rs: std_ulogic_vector(63 downto 0); sh, mb, me: std_ulogic_vector(4 downto 0)) return std_ulogic_vector is
334 variable hi, lo : integer;
335 variable tmp1, tmp2 : std_ulogic_vector(63 downto 0);
336 begin
337 hi := 31 - to_integer(unsigned(mb));
338 lo := 31 - to_integer(unsigned(me));
339 tmp1 := rs(31 downto 0) & rs(31 downto 0);
340 tmp1 := std_ulogic_vector(rotate_left(unsigned(tmp1), to_integer(unsigned(sh))));
341 tmp2 := (others => '0');
342 if hi < lo then
343 -- Mask wraps around
344 for i in 0 to 63 loop
345 if i <= hi or i >= lo then
346 tmp2(i) := tmp1(i);
347 end if;
348 end loop;
349 else
350 for i in 0 to 63 loop
351 if i >= lo and i <= hi then
352 tmp2(i) := tmp1(i);
353 end if;
354 end loop;
355 end if;
356 return tmp2;
357 end;
358
359 function ppc_rlwnm (rs, rb: std_ulogic_vector(63 downto 0); mb, me: std_ulogic_vector(4 downto 0)) return std_ulogic_vector is
360 variable hi, lo : integer;
361 variable tmp1, tmp2 : std_ulogic_vector(63 downto 0);
362 variable n : integer;
363 begin
364 hi := 31 - to_integer(unsigned(mb));
365 lo := 31 - to_integer(unsigned(me));
366 n := to_integer(unsigned(rb(4 downto 0)));
367 tmp1 := rs(31 downto 0) & rs(31 downto 0);
368 tmp1 := std_ulogic_vector(rotate_left(unsigned(tmp1), n));
369 tmp2 := (others => '0');
370 if hi < lo then
371 -- Mask wraps around
372 for i in 0 to 63 loop
373 if i <= hi or i >= lo then
374 tmp2(i) := tmp1(i);
375 end if;
376 end loop;
377 else
378 for i in 0 to 63 loop
379 if i >= lo and i <= hi then
380 tmp2(i) := tmp1(i);
381 end if;
382 end loop;
383 end if;
384 return tmp2;
385 end;
386
387 function ppc_rlwimi (ra, rs: std_ulogic_vector(63 downto 0); sh, mb, me: std_ulogic_vector(4 downto 0)) return std_ulogic_vector is
388 variable hi, lo : integer;
389 variable tmp1, tmp2 : std_ulogic_vector(63 downto 0);
390 begin
391 hi := 31 - to_integer(unsigned(mb));
392 lo := 31 - to_integer(unsigned(me));
393 tmp1 := rs(31 downto 0) & rs(31 downto 0);
394 tmp1 := std_ulogic_vector(rotate_left(unsigned(tmp1), to_integer(unsigned(sh))));
395 tmp2 := ra;
396 if hi < lo then
397 -- Mask wraps around
398 for i in 0 to 63 loop
399 if i <= hi or i >= lo then
400 tmp2(i) := tmp1(i);
401 end if;
402 end loop;
403 else
404 for i in 0 to 63 loop
405 if i >= lo and i <= hi then
406 tmp2(i) := tmp1(i);
407 end if;
408 end loop;
409 end if;
410 return tmp2;
411 end;
412
413 function ppc_rldicl (rs: std_ulogic_vector(63 downto 0); sh, mb: std_ulogic_vector(5 downto 0)) return std_ulogic_vector is
414 variable hi : integer;
415 variable tmp1, tmp2 : std_ulogic_vector(63 downto 0);
416 begin
417 hi := 63-to_integer(unsigned(mb));
418 tmp1 := std_ulogic_vector(rotate_left(unsigned(rs), to_integer(unsigned(sh))));
419 tmp2 := (others => '0');
420 for i in 0 to 63 loop
421 if i <= hi then
422 tmp2(i) := tmp1(i);
423 end if;
424 end loop;
425 return tmp2;
426 end;
427
428 function ppc_rldicr (rs: std_ulogic_vector(63 downto 0); sh, me: std_ulogic_vector(5 downto 0)) return std_ulogic_vector is
429 variable lo : integer;
430 variable tmp1, tmp2 : std_ulogic_vector(63 downto 0);
431 begin
432 lo := 63-to_integer(unsigned(me));
433 tmp1 := std_ulogic_vector(rotate_left(unsigned(rs), to_integer(unsigned(sh))));
434 tmp2 := (others => '0');
435 for i in 0 to 63 loop
436 if i >= lo then
437 tmp2(i) := tmp1(i);
438 end if;
439 end loop;
440 return tmp2;
441 end;
442
443 function ppc_rldic (rs: std_ulogic_vector(63 downto 0); sh, mb: std_ulogic_vector(5 downto 0)) return std_ulogic_vector is
444 variable hi, lo : integer;
445 variable tmp1, tmp2 : std_ulogic_vector(63 downto 0);
446 begin
447 hi := 63-to_integer(unsigned(mb));
448 lo := to_integer(unsigned(sh));
449 tmp1 := std_ulogic_vector(rotate_left(unsigned(rs), to_integer(unsigned(sh))));
450 tmp2 := (others => '0');
451 if hi < lo then
452 -- Mask wraps around
453 for i in 0 to 63 loop
454 if i <= hi or i >= lo then
455 tmp2(i) := tmp1(i);
456 end if;
457 end loop;
458 else
459 for i in 0 to 63 loop
460 if i >= lo and i <= hi then
461 tmp2(i) := tmp1(i);
462 end if;
463 end loop;
464 end if;
465 return tmp2;
466 end;
467
468 function ppc_rldcl (rs, rb: std_ulogic_vector(63 downto 0); mb: std_ulogic_vector(5 downto 0)) return std_ulogic_vector is
469 variable hi : integer;
470 variable tmp1, tmp2 : std_ulogic_vector(63 downto 0);
471 begin
472 hi := 63-to_integer(unsigned(mb));
473 tmp1 := std_ulogic_vector(rotate_left(unsigned(rs), to_integer(unsigned(rb(5 downto 0)))));
474 tmp2 := (others => '0');
475 for i in 0 to 63 loop
476 if i <= hi then
477 tmp2(i) := tmp1(i);
478 end if;
479 end loop;
480 return tmp2;
481 end;
482
483 function ppc_rldcr (rs, rb: std_ulogic_vector(63 downto 0); me: std_ulogic_vector(5 downto 0)) return std_ulogic_vector is
484 variable lo : integer;
485 variable tmp1, tmp2 : std_ulogic_vector(63 downto 0);
486 begin
487 lo := 63-to_integer(unsigned(me));
488 tmp1 := std_ulogic_vector(rotate_left(unsigned(rs), to_integer(unsigned(rb(5 downto 0)))));
489 tmp2 := (others => '0');
490 for i in 0 to 63 loop
491 if i >= lo then
492 tmp2(i) := tmp1(i);
493 end if;
494 end loop;
495 return tmp2;
496 end;
497
498 function ppc_rldimi (ra, rs: std_ulogic_vector(63 downto 0); sh, mb: std_ulogic_vector(5 downto 0)) return std_ulogic_vector is
499 variable hi, lo : integer;
500 variable tmp1, tmp2 : std_ulogic_vector(rs'range);
501 begin
502 hi := 63-to_integer(unsigned(mb));
503 lo := to_integer(unsigned(sh));
504 tmp1 := std_ulogic_vector(rotate_left(unsigned(rs), lo));
505 tmp2 := ra;
506 if hi < lo then
507 -- Mask wraps around
508 for i in 0 to 63 loop
509 if i <= hi or i >= lo then
510 tmp2(i) := tmp1(i);
511 end if;
512 end loop;
513 else
514 for i in 0 to 63 loop
515 if i >= lo and i <= hi then
516 tmp2(i) := tmp1(i);
517 end if;
518 end loop;
519 end if;
520 return tmp2;
521 end;
522
523 function ppc_slw (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
524 variable n : integer;
525 variable tmp : unsigned(31 downto 0);
526 begin
527 n := to_integer(unsigned(rb(5 downto 0)));
528 tmp := shift_left(unsigned(rs(31 downto 0)), n);
529
530 return (63 downto 32 => '0') & std_ulogic_vector(tmp);
531 end;
532
533 function ppc_srw (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
534 variable n : integer;
535 variable tmp : unsigned(31 downto 0);
536 begin
537 n := to_integer(unsigned(rb(5 downto 0)));
538 tmp := shift_right(unsigned(rs(31 downto 0)), n);
539
540 return (63 downto 32 => '0') & std_ulogic_vector(tmp);
541 end;
542
543 function ppc_srawi (rs : std_ulogic_vector(63 downto 0); sh: std_ulogic_vector(5 downto 0)) return std_ulogic_vector is
544 variable n : integer;
545 variable tmp : signed(31 downto 0);
546 variable mask : std_ulogic_vector(63 downto 0);
547 variable carry: std_ulogic;
548 begin
549 n := to_integer(unsigned(sh));
550 tmp := shift_right(signed(rs(31 downto 0)), n);
551 -- what about n = 0?
552 mask := (others => '0');
553 for i in 0 to 63 loop
554 if i < n then
555 mask(i) := '1';
556 end if;
557 end loop;
558 carry := '0' when (rs and mask) = (63 downto 0 => '0') else rs(31);
559
560 return carry & std_ulogic_vector(resize(tmp, rs'length));
561 end;
562
563 function ppc_sraw (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
564 variable n : natural;
565 variable tmp : signed(31 downto 0);
566 variable mask : std_ulogic_vector(63 downto 0);
567 variable carry: std_ulogic;
568 begin
569 n := to_integer(unsigned(rb(5 downto 0)));
570 tmp := shift_right(signed(rs(31 downto 0)), n);
571 -- what about n = 0?
572 mask := (others => '0');
573 for i in 0 to 63 loop
574 if i < n then
575 mask(i) := '1';
576 end if;
577 end loop;
578 carry := or (rs and mask) and rs(31);
579 return carry & std_ulogic_vector(resize(tmp, rs'length));
580 end;
581
582 function ppc_sld (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
583 variable n : integer;
584 begin
585 n := to_integer(unsigned(rb(6 downto 0)));
586 return std_ulogic_vector(shift_left(unsigned(rs), n));
587 end;
588
589 function ppc_srd (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
590 variable n : integer;
591 begin
592 n := to_integer(unsigned(rb(6 downto 0)));
593 return std_ulogic_vector(shift_right(unsigned(rs), n));
594 end;
595
596 function ppc_sradi (rs: std_ulogic_vector(63 downto 0); sh: std_ulogic_vector(5 downto 0)) return std_ulogic_vector is
597 variable n : integer;
598 variable carry: std_ulogic;
599 variable mask : std_ulogic_vector(63 downto 0);
600 begin
601 n := to_integer(unsigned(sh));
602 -- what about n = 0?
603 mask := (others => '0');
604 for i in 0 to 63 loop
605 if i < n then
606 mask(i) := '1';
607 end if;
608 end loop;
609 carry := '0' when (rs and mask) = (63 downto 0 => '0') else rs(63);
610
611 return carry & std_ulogic_vector(shift_right(signed(rs), n));
612 end;
613
614 function ppc_srad (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
615 variable n : integer;
616 variable carry: std_ulogic;
617 variable mask : std_ulogic_vector(63 downto 0);
618 begin
619 n := to_integer(unsigned(rb(6 downto 0)));
620 -- what about n = 0?
621 mask := (others => '0');
622 for i in 0 to 63 loop
623 if i < n then
624 mask(i) := '1';
625 end if;
626 end loop;
627 carry := '0' when (rs and mask) = (63 downto 0 => '0') else rs(63);
628
629 return carry & std_ulogic_vector(shift_right(signed(rs), n));
630 end;
631
632 -- Not sure how to better communicate the top 64 bits of the result is unused
633 function ppc_mulld (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
634 variable tmp: signed(127 downto 0);
635 begin
636 tmp := signed(ra) * signed(rb);
637 return std_ulogic_vector(tmp(63 downto 0));
638 end;
639
640 -- Not sure how to better communicate the top 64 bits of the result is unused
641 function ppc_mulhd (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
642 variable tmp: signed(127 downto 0);
643 begin
644 tmp := signed(ra) * signed(rb);
645 return std_ulogic_vector(tmp(127 downto 64));
646 end;
647
648 -- Not sure how to better communicate the top 64 bits of the result is unused
649 function ppc_mulhdu (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
650 variable tmp: unsigned(127 downto 0);
651 begin
652 tmp := unsigned(ra) * unsigned(rb);
653 return std_ulogic_vector(tmp(127 downto 64));
654 end;
655
656 -- Not sure how to better communicate the top 16 bits of the result is unused
657 function ppc_mulli (ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is
658 variable tmp: signed(79 downto 0);
659 begin
660 tmp := signed(ra) * signed(si);
661 return std_ulogic_vector(tmp(63 downto 0));
662 end;
663
664 function ppc_mullw (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
665 begin
666 return std_ulogic_vector(signed(ra(31 downto 0)) * signed(rb(31 downto 0)));
667 end;
668
669 function ppc_mulhw (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
670 variable tmp: signed(63 downto 0);
671 begin
672 tmp := signed(ra(31 downto 0)) * signed(rb(31 downto 0));
673 return std_ulogic_vector(tmp(63 downto 32)) & std_ulogic_vector(tmp(63 downto 32));
674 end;
675
676 function ppc_mulhwu (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
677 variable tmp: unsigned(63 downto 0);
678 begin
679 tmp := unsigned(ra(31 downto 0)) * unsigned(rb(31 downto 0));
680 return std_ulogic_vector(tmp(63 downto 32)) & std_ulogic_vector(tmp(63 downto 32));
681 end;
682
683 function ppc_cmpi (l: std_ulogic; ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0);
684 so: std_ulogic) return std_ulogic_vector is
685 variable tmp: signed(ra'range);
686 begin
687 tmp := signed(ra);
688 if l = '0' then
689 tmp := resize(signed(ra(31 downto 0)), tmp'length);
690 end if;
691
692 return ppc_signed_compare(tmp, resize(signed(si), tmp'length), so);
693 end;
694
695 function ppc_cmp (l: std_ulogic; ra, rb: std_ulogic_vector(63 downto 0);
696 so: std_ulogic) return std_ulogic_vector is
697 variable tmpa, tmpb: signed(ra'range);
698 begin
699 tmpa := signed(ra);
700 tmpb := signed(rb);
701 if l = '0' then
702 tmpa := resize(signed(ra(31 downto 0)), ra'length);
703 tmpb := resize(signed(rb(31 downto 0)), ra'length);
704 end if;
705
706 return ppc_signed_compare(tmpa, tmpb, so);
707 end;
708
709 function ppc_cmpli (l: std_ulogic; ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0);
710 so: std_ulogic) return std_ulogic_vector is
711 variable tmp: unsigned(ra'range);
712 begin
713 tmp := unsigned(ra);
714 if l = '0' then
715 tmp := resize(unsigned(ra(31 downto 0)), tmp'length);
716 end if;
717
718 return ppc_unsigned_compare(tmp, resize(unsigned(si), tmp'length), so);
719 end;
720
721 function ppc_cmpl (l: std_ulogic; ra, rb: std_ulogic_vector(63 downto 0);
722 so: std_ulogic) return std_ulogic_vector is
723 variable tmpa, tmpb: unsigned(ra'range);
724 begin
725 tmpa := unsigned(ra);
726 tmpb := unsigned(rb);
727 if l = '0' then
728 tmpa := resize(unsigned(ra(31 downto 0)), ra'length);
729 tmpb := resize(unsigned(rb(31 downto 0)), ra'length);
730 end if;
731
732 return ppc_unsigned_compare(tmpa, tmpb, so);
733 end;
734
735 function ppc_cmpb (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
736 variable ret: std_ulogic_vector (rs'range);
737 variable hi: integer;
738 variable lo: integer;
739 begin
740 for i in 1 to 8 loop
741 hi := (8*i)-1;
742 lo := 8*(i-1);
743 ret(hi downto lo) := cmp_one_byte(rs(hi downto lo), rb(hi downto lo));
744 end loop;
745
746 return ret;
747 end;
748
749 -- Not synthesizable
750 function ppc_divw (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
751 variable tmp: signed(31 downto 0);
752 begin
753 tmp := signed(ra(31 downto 0)) / signed(rb(31 downto 0));
754
755 return (63 downto 32 => '0') & std_ulogic_vector(tmp);
756 end;
757
758 function ppc_divdu (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
759 variable tmp: unsigned(63 downto 0) := (others => '0');
760 begin
761 if unsigned(rb) /= 0 then
762 tmp := unsigned(ra) / unsigned(rb);
763 end if;
764
765 return std_ulogic_vector(tmp);
766 end;
767
768 function ppc_divd (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
769 variable tmp: signed(63 downto 0) := (others => '0');
770 begin
771 if signed(rb) /= 0 then
772 tmp := signed(ra) / signed(rb);
773 end if;
774
775 return std_ulogic_vector(tmp);
776 end;
777
778 function ppc_divwu (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
779 variable tmp: unsigned(31 downto 0) := (others => '0');
780 begin
781 if unsigned(rb(31 downto 0)) /= 0 then
782 tmp := unsigned(ra(31 downto 0)) / unsigned(rb(31 downto 0));
783 end if;
784
785 return std_ulogic_vector(resize(tmp, ra'length));
786 end;
787
788 function ppc_bc_taken(bo, bi: std_ulogic_vector(4 downto 0); cr: std_ulogic_vector(31 downto 0); ctr: std_ulogic_vector(63 downto 0)) return std_ulogic is
789 variable crfield: integer;
790 variable crbit_match: std_ulogic;
791 variable ctr_not_zero: std_ulogic;
792 variable ctr_ok: std_ulogic;
793 variable cond_ok: std_ulogic;
794 begin
795 crfield := to_integer(unsigned(bi));
796 -- BE bit numbering
797 crbit_match := '1' when cr(31-crfield) = bo(4-1) else '0';
798 -- We check this before it is decremented
799 ctr_not_zero := '1' when ctr /= x"0000000000000001" else '0';
800 ctr_ok := bo(4-2) or (ctr_not_zero xor bo(4-3));
801 cond_ok := bo(4-0) or crbit_match;
802 return ctr_ok and cond_ok;
803 end;
804
805 end package body ppc_fx_insns;