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