📄 armshiefter.vhd
字号:
-- 64 63 33 32 31 1 0
-- +---+---+---------------+===+=============+---+
-- | 000 | c | op1-1 |
-- +---+---+---------------+===+=============+ccc+
-- : rrx
shiftin(31 downto 0) := data2;
shiftin(32) := carry;
op2 := (others => '0');
carryoutsrc := shiftin_00;
when ash_sdir_snone =>
op2 := (others => '0');
when others => null;
end case;
when ash_styp_sreg =>
shiftin := (others => '0');
shiftin(32 downto 1) := data1;
case dir is
when ash_sdir_slsl =>
--$(del)
--if Rs[7:0] == 0 then
-- shifter_operand = Rm
-- shifter_carry_out = C Flag
--else if Rs[7:0] < 32 then
-- shifter_operand = Rm Logical_Shift_Left Rs[7:0]
-- shifter_carry_out = Rm[32 - Rs[7:0]]
--else if Rs[7:0] == 32 then
-- shifter_operand = 0
-- shifter_carry_out = Rm[0]
--else /* Rs[7:0] > 32 */
-- shifter_operand = 0
-- shifter_carry_out = 0
--$(/del)
-- 64 63 33 32 31 1 0
-- +---+---+---------------+===+=============+---+
-- | c | op1 | 000 | 0 |
-- +---+---+------------ccc+===+=============+---+
-- c | op1 | << 31 (>>0)
-- c | op1 | << 0 (>>31)
shiftin := (others => '0');
shiftin(64) := carry;
shiftin(63 downto 32) := data1;
op2 := not data2(4 downto 0);
carryoutsrc := shiftin_33;
if not (data2(7 downto 5) = "000") then -- >= 32
shiftin := (others => '0');
if data2(7 downto 0) = "00100000" then -- == 32
carryoutsrc := shiftin_prev;
carryout := data1(0);
end if;
end if;
when ash_sdir_slsr =>
--$(del)
--if Rs[7:0] == 0 then
-- shifter_operand = Rm
-- shifter_carry_out = C Flag
--else if Rs[7:0] < 32 then
-- shifter_operand = Rm Logical_Shift_Right Rs[7:0]
-- shifter_carry_out = Rm[Rs[7:0] - 1]
--else if Rs[7:0] == 32 then
-- shifter_operand = 0
-- shifter_carry_out = Rm[31]
--else /* Rs[7:0] > 32 */
-- shifter_operand = 0
-- shifter_carry_out = 0
--$(/del)
-- 64 63 33 32 31 1 0
-- +---+---+---------------+===+=============+---+
-- | 0 | 0 | 000 | op1 | c |
-- +---+---+---------------+===+=============+ccc+
-- | op1 | >> 0
-- |op1| >> 31
shiftin := (others => '0');
shiftin(0) := carry;
shiftin(32 downto 1) := data1;
op2 := data2(4 downto 0);
carryoutsrc := shiftin_00;
if not (data2(7 downto 5) = "000") then -- >= 32
shiftin := (others => '0');
if data2(7 downto 0) = "00100000" then -- == 32
carryoutsrc := shiftin_prev;
carryout := data1(31);
end if;
end if;
when ash_sdir_sasr =>
--$(del)
--if Rs[7:0] == 0 then
-- shifter_operand = Rm
-- shifter_carry_out = C Flag
--else if Rs[7:0] < 32 then
-- shifter_operand = Rm Arithmetic_Shift_Right Rs[7:0]
-- shifter_carry_out = Rm[Rs[7:0] - 1]
--else /* Rs[7:0] >= 32 */
-- if Rm[31] == 0 then
-- shifter_operand = 0
-- shifter_carry_out = Rm[31]
-- else /* Rm[31] == 1 */
-- shifter_operand = 0xFFFFFFFF
-- shifter_carry_out = Rm[31]
--$(/del)
-- 64 63 33 32 31 1 0
-- +---+---+---------------+===+=============+---+
-- | s | s | sss | op1 | c |
-- +---+---+---------------+===+=============+ccc+
-- s | op1 | >> 1
-- sss |op1| >> 31
-- 000 | 0 >> 0 (s=0)
-- 111 | 1 >> 0 (s=1)
if data1(31) = '1' then
shiftin(64 downto 33) := (others => '1');
else
shiftin(64 downto 33) := (others => '0');
end if;
shiftin(0) := carry;
shiftin(32 downto 1) := data1;
op2 := data2(4 downto 0);
if not (data2(7 downto 5) = "000") then -- >= 32
if data1(31) = '1' then
shiftin(32 downto 0) := (others => '1');
else
shiftin(32 downto 0) := (others => '0');
end if;
end if;
carryoutsrc := shiftin_00;
when ash_sdir_sror =>
--$(del)
--if Rs[7:0] == 0 then
-- shifter_operand = Rm
-- shifter_carry_out = C Flag
--else if Rs[4:0] == 0 then
-- shifter_operand = Rm
-- shifter_carry_out = Rm[31]
--else /* Rs[4:0] > 0 */
-- shifter_operand = Rm Rotate_Right Rs[4:0]
-- shifter_carry_out = Rm[Rs[4:0] - 1]
--$(/del)
-- 64 63 33 32 31 1 0
-- +---+---+---------------+===+=============+---+
-- | op1 | op1 | 0 |
-- +---+---+---------------+ccc+=============+---+
-- | op1 | << 1 (>>1)
-- | op1 | << 31 (>>31)
shiftin := (others => '0');
shiftin(64 downto 33) := data1;
shiftin(32 downto 1) := data1;
op2 := data2(4 downto 0);
carryoutsrc := shiftin_32;
if data2(7 downto 0) = "00000000" then -- == 0
carryoutsrc := shiftin_prev;
carryout := carry;
end if;
when ash_sdir_srrx =>
--$(del)
--shifter_operand = (C Flag Logical_Shift_Left 31) OR (Rm Logical_Shift_Right 1)
--shifter_carry_out = Rm[0]
--$(/del)
-- 64 63 33 32 31 1 0
-- +---+---+---------------+===+=============+---+
-- | 000 | c | op1-1 |
-- +---+---+---------------+===+=============+ccc+
-- : rrx
op2 := (others => '0');
shiftin(31 downto 0) := carry & shiftin(31 downto 1);
when ash_sdir_snone =>
when others => null;
end case;
when ash_styp_none =>
shiftin := (others => '0');
shiftin(32 downto 1) := data2;
when others =>
end case;
-- shifter
if op2 (4) = '1' then
shiftin(48 downto 0) := shiftin(64 downto 16);
end if;
if op2 (3) = '1' then
shiftin(40 downto 0) := shiftin(48 downto 8);
end if;
if op2 (2) = '1' then
shiftin(36 downto 0) := shiftin(40 downto 4);
end if;
if op2 (1) = '1' then
shiftin(34 downto 0) := shiftin(36 downto 2);
end if;
if op2 (0) = '1' then
shiftin(32 downto 0) := shiftin(33 downto 1);
end if;
-- carry out select
case carryoutsrc is
when shiftin_00 => carryout := shiftin(0);
when shiftin_33 => carryout := shiftin(33);
when shiftin_32 => carryout := shiftin(32);
when shiftin_prev =>
when others => null;
end case;
shieftout := shiftin(32 downto 1);
shieftcarryout := carryout;
end;
end armshiefter;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -