ppc_fx_insns.vhdl 30 KB

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