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