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