diff -uNr a/ffa/libffa/fz_qshft.adb b/ffa/libffa/fz_qshft.adb --- a/ffa/libffa/fz_qshft.adb 4998cc0716b4cbd3d0e8eab6b254de811c9d25601e4ae86c17215e5d66096e9d5768c2cfa2312a1ae9fc460a943a9536f88ed72adc69b46bd9fcbd15f3d6e0fb +++ b/ffa/libffa/fz_qshft.adb e63a519fef85368cecdbb7f7dd03cc9d83f93f3e2d420fc94b964023255140508f2ccc77e8c76056f98f3be5741794403cd90b8fa88251a0f90a4dbeb79b5e1d @@ -38,30 +38,31 @@ S : Positive; -- Current shiftness level B : Word; -- Quantity of shift (bitwalked over) CB : Word; -- Quantity of carry counter-shift (bitwalked over) - St : Word; -- Temporary word shift candidate - Ct : Word; -- Temporary carry counter-shift candidate begin for i in reverse N'Range loop + -- Need to set it here as N and ShiftedN can be the same array Ni := N(i); + + -- Write down carry from previous iteration ShiftedN(i) := C; + + -- For each shift level (of the subword shiftvalue width) : C := W_Mux(Ni, 0, nC); S := 1; - B := Nw; + B := Word(Count); CB := Word(Bitness) - B; -- For each shift level (of the subword shiftvalue width) : for j in 1 .. BitnessLog2 loop -- Shift and mux the current word - St := Shift_Right(Ni, S); - Ni := W_Mux(Ni, St, B and 1); + Ni := Shift_Right_Gated(Ni, S, B and 1); + B := Shift_Right(B, 1); -- Shift and mux the current carry - Ct := Shift_Left(C, S); - C := W_Mux(C, Ct, CB and 1); + C := Shift_Left_Gated(C, S, CB and 1); + CB := Shift_Right(CB, 1); -- Go to the next shiftness level S := S * 2; - B := Shift_Right(B, 1); - CB := Shift_Right(CB, 1); end loop; - -- Slide in the carry from the previous shift + -- Slide in the leftovers of the current Word N(i) ShiftedN(i) := ShiftedN(i) or Ni; end loop; end FZ_Quiet_ShiftRight_SubW_Soft; @@ -78,30 +79,31 @@ S : Positive; -- Current shiftness level B : Word; -- Quantity of shift (bitwalked over) CB : Word; -- Quantity of carry counter-shift (bitwalked over) - St : Word; -- Temporary word shift candidate - Ct : Word; -- Temporary carry counter-shift candidate begin for i in N'Range loop + -- Need to set Ni here as N and ShiftedN can be the same array Ni := N(i); + + -- Write down carry from previous iteration ShiftedN(i) := C; + + -- For each shift level (of the subword shiftvalue width) : C := W_Mux(Ni, 0, nC); S := 1; - B := Nw; + B := Word(Count); CB := Word(Bitness) - B; - -- For each shift level (of the subword shiftvalue width) : for j in 1 .. BitnessLog2 loop -- Shift and mux the current word - St := Shift_Left(Ni, S); - Ni := W_Mux(Ni, St, B and 1); + -- If have to shift at current position, do the shift + Ni := Shift_Left_Gated(Ni, S, B and 1); + B := Shift_Right(B, 1); -- Shift and mux the current carry - Ct := Shift_Right(C, S); - C := W_Mux(C, Ct, CB and 1); + C := Shift_Right_Gated(C, S, CB and 1); + CB := Shift_Right(CB, 1); -- Go to the next shiftness level S := S * 2; - B := Shift_Right(B, 1); - CB := Shift_Right(CB, 1); end loop; - -- Slide in the carry from the previous shift + -- Slide in the leftovers of the current Word N(i) ShiftedN(i) := ShiftedN(i) or Ni; end loop; end FZ_Quiet_ShiftLeft_SubW_Soft; diff -uNr a/ffa/libffa/w_shifts.adb b/ffa/libffa/w_shifts.adb --- a/ffa/libffa/w_shifts.adb false +++ b/ffa/libffa/w_shifts.adb 063b9474f42c9d625be7af9f0871ea6578fab80fe8d88eb81053ffb5b1d3f484ad79bea87d5cd501bc36cc104f541a3270695db11b6efcfa5446454114f1058b @@ -0,0 +1,19 @@ +package body W_Shifts is + function Shift_Left_Gated (W: Word; + Amount: Positive; + Gate: WBool) + return Word is + Temp: Word := Shift_Left(W, Amount); + begin + return W_Mux(W, Temp, Gate); + end Shift_Left_Gated; + + function Shift_Right_Gated (W: Word; + Amount: Positive; + Gate: WBool) + return Word is + Temp: Word := Shift_Right(W, Amount); + begin + return W_Mux(W, Temp, Gate); + end Shift_Right_Gated; +end W_Shifts; diff -uNr a/ffa/libffa/w_shifts.ads b/ffa/libffa/w_shifts.ads --- a/ffa/libffa/w_shifts.ads 0053916c4c078241c2644c24a963cedbb3a4a5eeb7f3060893fd6e1519cb3afe8467f23c3b7be9892d243502d827c0c5ca7d438c629cff580b2399b86966445d +++ b/ffa/libffa/w_shifts.ads 9632e8b333ecff70ce11f8236b309b3985ccc526194c57a81a6ee99eda05459cd2e8b70011eb20099ce71b80ab5e6ed2bc940c5d4268382b3494e07ccdf781dc @@ -18,7 +18,7 @@ ------------------------------------------------------------------------------ with Words; use Words; - +with Word_Ops; use Word_Ops; -- For some peculiar reason, the Ada standards group made -- the fundamental Shift and Rotate bitwise ops into ~optional~ components! @@ -58,5 +58,18 @@ return Word; pragma Import(Intrinsic, Rotate_Right); pragma Inline_Always(Rotate_Right); - + + function Shift_Left_Gated + (W: Word; + Amount: Positive; + Gate: WBool) + return Word; + pragma Inline_Always(Shift_Left_Gated); + + function Shift_Right_Gated + (W: Word; + Amount: Positive; + Gate: WBool) + return Word; + pragma Inline_Always(Shift_Right_Gated); end W_Shifts;