Library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.std_logic_arith.all;

ENTITY sp IS

PORT( CLOCK: in std_logic;
      Rs1: in std_logic_vector(63 downto 0);
      --Register input Rs1
      Rs2: IN std_logic_vector(63 downto 0);
      --Register input Rs2 OR immediate input
      --for extract and deposit, Rd to Rs2
      Opcode: IN std_logic_vector(5 downto 0);      
      Subop: IN std_logic_vector(12 downto 0);
      --for most instructions, send subop/subwd in bottom 8 bits
      --for shrp, send immediate to bottom 8 bits
      --for extract/deposit, send imm7 to subop(12-6), imm6 to subop(5-0)
      Data: OUT std_logic_vector(63 downto 0));
        
END sp;

ARCHITECTURE opcodes OF sp IS

	--Opcodes

	CONSTANT Type4aOP: std_logic_vector(5 downto 0) := "110010";
	CONSTANT Type4bOP: std_logic_vector(5 downto 0) := "110011";
	CONSTANT slliOP: std_logic_vector(5 downto 0) := "100101";
	CONSTANT sraiOP: std_logic_vector(5 downto 0) := "100110";
	CONSTANT srliOP: std_logic_vector(5 downto 0) := "100111";
	CONSTANT depositOP: std_logic_vector(5 downto 0) := "101000";
	CONSTANT extractOP: std_logic_vector(5 downto 0) := "101001";
	CONSTANT shrpOP: std_logic_vector(5 downto 0) := "101010";
	
	--Subops

	CONSTANT LeftSO: std_logic_vector(5 downto 0) := "000000";
	CONSTANT ARightSO: std_logic_vector(5 downto 0) := "000001";
	CONSTANT LRightSO: std_logic_vector(5 downto 0) := "000010";
	CONSTANT MixLeftSO: std_logic_vector(5 downto 0) := "010000";
	CONSTANT MixRightSO: std_logic_vector(5 downto 0) := "010001";
	CONSTANT PermuteSO: std_logic_vector(5 downto 0) := "100000";

	CONSTANT MuxRevSO: std_logic_vector(5 downto 0) := "001000";
	CONSTANT MuxMixSO: std_logic_vector(5 downto 0) := "001001";
	CONSTANT MuxShufSO: std_logic_vector(5 downto 0) := "001010";
	CONSTANT MuxAltSO: std_logic_vector(5 downto 0) := "001011";
	CONSTANT MuxBrcstSO: std_logic_vector(5 downto 0) := "001110";
	
	--shifter constants
	CONSTANT LEFT: std_logic := '0';
	CONSTANT RIGHT: std_logic := '1';
	CONSTANT zeros: std_logic_vector(7 downto 0) := "00000000";
	CONSTANT ones: std_logic_vector(7 downto 0) := "11111111";
	CONSTANT YES: std_logic := '1';
	CONSTANT NO: std_logic := '0';

	--mux select
	CONSTANT logical: std_logic_vector(1 downto 0) := "00";
	CONSTANT arith1: std_logic_vector(1 downto 0) := "01";
	CONSTANT other: std_logic_vector(1 downto 0) := "10";
	
        --aliases
        --Subop aliases
        alias subword : std_logic_vector(1 downto 0) is Subop(1 downto 0);  -- bottom 2 bits of subop
        alias SO : std_logic_vector(5 downto 0) is Subop(7 downto 2);  -- actual Subop of instruction
        alias imm7 : std_logic_vector(6 downto 0) is Subop(12 downto 6);
        alias imm6 : std_logic_vector(5 downto 0) is Subop(5 downto 0);
        alias imm8 : std_logic_vector(7 downto 0) is Subop(7 downto 0); -- for shrp

        --Rs2 aliases
        alias imm13 : std_logic_vector(12 downto 0) is Rs2(12 downto 0);  
                                        -- for Type 2 insts
        alias imm5 : std_logic_vector(4 downto 0) is Rs2(4 downto 0);  
                                        -- for Type 4b

	alias R2byte7 : std_logic_vector(7 downto 0) is Rs2(63 downto 56);
	alias R2byte6 : std_logic_vector(7 downto 0) is Rs2(55 downto 48);
	alias R2byte5 : std_logic_vector(7 downto 0) is Rs2(47 downto 40);
	alias R2byte4 : std_logic_vector(7 downto 0) is Rs2(39 downto 32);
	alias R2byte3 : std_logic_vector(7 downto 0) is Rs2(31 downto 24);
	alias R2byte2 : std_logic_vector(7 downto 0) is Rs2(23 downto 16);
	alias R2byte1 : std_logic_vector(7 downto 0) is Rs2(15 downto 8);
	alias R2byte0 : std_logic_vector(7 downto 0) is Rs2(7 downto 0);

	--Rs1 aliases
	alias R1byte7 : std_logic_vector(7 downto 0) is Rs1(63 downto 56);
	alias R1byte6 : std_logic_vector(7 downto 0) is Rs1(55 downto 48);
	alias R1byte5 : std_logic_vector(7 downto 0) is Rs1(47 downto 40);
	alias R1byte4 : std_logic_vector(7 downto 0) is Rs1(39 downto 32);
	alias R1byte3 : std_logic_vector(7 downto 0) is Rs1(31 downto 24);
	alias R1byte2 : std_logic_vector(7 downto 0) is Rs1(23 downto 16);
	alias R1byte1 : std_logic_vector(7 downto 0) is Rs1(15 downto 8);
	alias R1byte0 : std_logic_vector(7 downto 0) is Rs1(7 downto 0);


	--control signals
	--amt signals
	SIGNAL byteamt : integer := 0;
	SIGNAL bitamt : integer := 0;

	--original vectors
	SIGNAL orig0 : std_logic_vector(7 downto 0);
	SIGNAL orig1 : std_logic_vector(7 downto 0);
	SIGNAL orig2 : std_logic_vector(7 downto 0);
	SIGNAL orig3 : std_logic_vector(7 downto 0);
	SIGNAL orig4 : std_logic_vector(7 downto 0);
	SIGNAL orig5 : std_logic_vector(7 downto 0);
	SIGNAL orig6 : std_logic_vector(7 downto 0);
	SIGNAL orig7 : std_logic_vector(7 downto 0);

	--'0' means left, '1' means right
	SIGNAL dir : std_logic;

	--'other' signals
	SIGNAL other0 : std_logic_vector(7 downto 0);
	SIGNAL other1 : std_logic_vector(7 downto 0);
	SIGNAL other2 : std_logic_vector(7 downto 0);
	SIGNAL other3 : std_logic_vector(7 downto 0);
	SIGNAL other4 : std_logic_vector(7 downto 0);
	SIGNAL other5 : std_logic_vector(7 downto 0);
	SIGNAL other6 : std_logic_vector(7 downto 0);
	SIGNAL other7 : std_logic_vector(7 downto 0);

	--mux select signals
	SIGNAL mux0 : std_logic_vector(1 downto 0);
	SIGNAL mux1 : std_logic_vector(1 downto 0);
	SIGNAL mux2 : std_logic_vector(1 downto 0);
	SIGNAL mux3 : std_logic_vector(1 downto 0);
	SIGNAL mux4 : std_logic_vector(1 downto 0);
	SIGNAL mux5 : std_logic_vector(1 downto 0);
	SIGNAL mux6 : std_logic_vector(1 downto 0);
	SIGNAL mux7 : std_logic_vector(1 downto 0);

	--mux input signals
	SIGNAL z0 : std_logic_vector(7 downto 0);
	SIGNAL z1 : std_logic_vector(7 downto 0);
	SIGNAL z2 : std_logic_vector(7 downto 0);
	SIGNAL z3 : std_logic_vector(7 downto 0);
	SIGNAL z4 : std_logic_vector(7 downto 0);
	SIGNAL z5 : std_logic_vector(7 downto 0);
	SIGNAL z6 : std_logic_vector(7 downto 0);
	SIGNAL z7 : std_logic_vector(7 downto 0);

	SIGNAL o0 : std_logic_vector(7 downto 0);
	SIGNAL o1 : std_logic_vector(7 downto 0);
	SIGNAL o2 : std_logic_vector(7 downto 0);
	SIGNAL o3 : std_logic_vector(7 downto 0);
	SIGNAL o4 : std_logic_vector(7 downto 0);
	SIGNAL o5 : std_logic_vector(7 downto 0);
	SIGNAL o6 : std_logic_vector(7 downto 0);
	SIGNAL o7 : std_logic_vector(7 downto 0);

	--mux output signals
	SIGNAL muxout0: std_logic_vector(7 downto 0);
	SIGNAL muxout1: std_logic_vector(7 downto 0);
	SIGNAL muxout2: std_logic_vector(7 downto 0);
	SIGNAL muxout3: std_logic_vector(7 downto 0);
	SIGNAL muxout4: std_logic_vector(7 downto 0);
	SIGNAL muxout5: std_logic_vector(7 downto 0);
	SIGNAL muxout6: std_logic_vector(7 downto 0);
	SIGNAL muxout7: std_logic_vector(7 downto 0);

COMPONENT mux

PORT(	sel: IN std_logic_vector(1 downto 0);
	i0: IN std_logic_vector(7 downto 0);
	i1: IN std_logic_vector(7 downto 0);
	i2: IN std_logic_vector(7 downto 0);
	mout: OUT std_logic_vector(7 downto 0));	
END COMPONENT;

COMPONENT bitshift

PORT(	dir: IN std_logic;
	original: IN std_logic_vector(7 downto 0);
	amt: IN integer;
	shiftin: IN std_logic_vector(7 downto 0);
	dout: OUT std_logic_vector(7 downto 0));
END COMPONENT;

BEGIN
    
U1:  mux
PORT MAP(
	mux0,
	z0,
	o0,
	other0,
	muxout0);

U2: mux
PORT MAP(
	mux1,
	z1,
	o1,
	other1,
	muxout1);

U3:  mux
PORT MAP(
	mux2,
	z2,
	o2,
	other2,
	muxout2);

U4: mux
PORT MAP(
	mux3,
	z3,
	o3,
	other3,
	muxout3);

U5:  mux
PORT MAP(
	mux4,
	z4,
	o4,
	other4,
	muxout4);

U6: mux
PORT MAP(
	mux5,
	z5,
	o5,
	other5,
	muxout5);

U7:  mux
PORT MAP(
	mux6,
	z6,
	o6,
	other6,
	muxout6);

U8: mux
PORT MAP(
	mux7,
	z7,
	o7,
	other7,
	muxout7);

U9: bitshift
PORT MAP(
	dir,
	orig0,
	bitamt,
	muxout0,
	Data(7 downto 0));

U10: bitshift
PORT MAP(
	dir,
	orig1,
	bitamt,
	muxout1,
	Data(15 downto 8));

U11: bitshift
PORT MAP(
	dir,
	orig2,
	bitamt,
	muxout2,
	Data(23 downto 16));

U12: bitshift
PORT MAP(
	dir,
	orig3,
	bitamt,
	muxout3,
	Data(31 downto 24));

U13: bitshift
PORT MAP(
	dir,
	orig4,
	bitamt,
	muxout4,
	Data(39 downto 32));

U14: bitshift
PORT MAP(
	dir,
	orig5,
	bitamt,
	muxout5,
	Data(47 downto 40));

U15: bitshift
PORT MAP(
	dir,
	orig6,
	bitamt,
	muxout6,
	Data(55 downto 48));

U16: bitshift
PORT MAP(
	dir,
	orig7,
	bitamt,
	muxout7,
	Data(63 downto 56));

OPERATE: Process(Rs1,Rs2,Opcode,Subop)
	variable byteshift : integer := 0;
	variable bitshift : integer := 0;
	variable index : integer := 0;
	variable temp : std_logic_vector(63 downto 0);
	variable shiftB: std_logic_vector(6 downto 0);

	--type int_array is array (0 to 7) of integer;
	--variable amts : int_array;
BEGIN

z0 <= zeros;
z1 <= zeros;
z2 <= zeros;
z3 <= zeros;
z4 <= zeros;
z5 <= zeros;
z6 <= zeros;
z7 <= zeros;

o0 <= ones;
o1 <= ones;
o2 <= ones;
o3 <= ones;
o4 <= ones;
o5 <= ones;
o6 <= ones;
o7 <= ones;

byteshift := 0;
bitshift := 0;

case Opcode is
--what type of instruction is it?  
when  slliOP =>  
	shiftB := imm13(6 downto 0);

when sraiOP =>
	shiftB := imm13(6 downto 0);

when srliOP => 
	shiftB := imm13(6 downto 0);

when shrpOP =>
	shiftB := imm8(6 downto 0);

when Type4aOP =>
	if SO(5 downto 3) = "000" then
	shiftB := Rs2(6 downto 0);
	else
	shiftB := "0000000";
	end if;

when Type4bOP =>
	if SO(5 downto 3) = "000" then
	shiftB := "00" & imm5;
	else
	shiftB := "0000000";
	end if;

when depositOP =>
	shiftB := "0000000";	

when extractOP =>
	shiftB := "0000000";

when others =>
	null;
end case;

--calculate how much shift
if shiftB(0) = '1' then
	bitshift := 1;
end if;
if shiftB(1) = '1' then
	bitshift := bitshift + 2;
end if;		
if shiftB(2) = '1' then
	bitshift := bitshift + 4;
end if;
if shiftB(3) = '1' then
	byteshift := 1;
end if;
if shiftB(4) = '1' then
	byteshift := byteshift + 2;
end if;
if shiftB(5) = '1' then
	byteshift := byteshift + 4;
end if;
if shiftB(6) = '1' then
	byteshift := byteshift + 8;
end if;  

byteamt <= byteshift;
bitamt <= bitshift;

end PROCESS;    


ORIGINATOR: Process(Rs1,Rs2,Opcode,Subop, byteamt)

	variable or0: std_logic_vector(7 downto 0);
	variable or1: std_logic_vector(7 downto 0);
	variable or2: std_logic_vector(7 downto 0);
	variable or3: std_logic_vector(7 downto 0);
	variable or4: std_logic_vector(7 downto 0);
	variable or5: std_logic_vector(7 downto 0);
	variable or6: std_logic_vector(7 downto 0);
	variable or7: std_logic_vector(7 downto 0);

	variable length : integer;
	variable location: integer;
	variable tempRd: std_logic_vector(63 downto 0);

BEGIN

--default
mux0 <= other;
mux1 <= other;
mux2 <= other;
mux3 <= other;
mux4 <= other;
mux5 <= other;
mux6 <= other;
mux7 <= other;

length := 0;
location := 0;
tempRd := "0000000000000000000000000000000000000000000000000000000000000000";

CASE Opcode IS
when shrpOP =>
	dir <= RIGHT;

	case byteamt is
	when 0 =>
		or0 := R2byte0;
		or1 := R2byte1;
		or2 := R2byte2;
		or3 := R2byte3;
		or4 := R2byte4;
		or5 := R2byte5;
		or6 := R2byte6;
		or7 := R2byte7;
		other7 <= R1byte0;

	when 1 =>
		or0 := R2byte1;
		or1 := R2byte2;
		or2 := R2byte3;
		or3 := R2byte4;
		or4 := R2byte5;
		or5 := R2byte6;
		or6 := R2byte7;
		or7 := R1byte0;
		other7 <= R1byte1;

	when 2 =>
		or0 := R2byte2;
		or1 := R2byte3;
		or2 := R2byte4;
		or3 := R2byte5;
		or4 := R2byte6;
		or5 := R2byte7;
		or6 := R1byte0;
		or7 := R1byte1;
		other7 <= R1byte2;
	
	when 3 =>
		or0 := R2byte3;
		or1 := R2byte4;
		or2 := R2byte5;
		or3 := R2byte6;
		or4 := R2byte7;
		or5 := R1byte0;
		or6 := R1byte1;
		or7 := R1byte2;
		other7 <= R1byte3;
	
	when 4 =>
		or0 := R2byte4;
		or1 := R2byte5;
		or2 := R2byte6;
		or3 := R2byte7;
		or4 := R1byte0;
		or5 := R1byte1;
		or6 := R1byte2;
		or7 := R1byte3;
		other7 <= R1byte4;
	
	when 5 =>
		or0 := R2byte5;
		or1 := R2byte6;
		or2 := R2byte7;
		or3 := R1byte0;
		or4 := R1byte1;
		or5 := R1byte2;
		or6 := R1byte3;
		or7 := R1byte4;
		other7 <= R1byte5;
	
	when 6 =>
		or0 := R2byte6;
		or1 := R2byte7;
		or2 := R1byte0;
		or3 := R1byte1;
		or4 := R1byte2;
		or5 := R1byte3;
		or6 := R1byte4;
		or7 := R1byte5;
		other7 <= R1byte6;
	
	when 7 =>
		or0 := R2byte7;
		or1 := R1byte0;
		or2 := R1byte1;
		or3 := R1byte2;
		or4 := R1byte3;
		or5 := R1byte4;
		or6 := R1byte5;
		or7 := R1byte6;
		other7 <= R1byte7;
	
	when 8 =>
		or0 := R1byte0;
		or1 := R1byte1;
		or2 := R1byte2;
		or3 := R1byte3;
		or4 := R1byte4;
		or5 := R1byte5;
		or6 := R1byte6;
		or7 := R1byte7;
		other7 <= zeros;

	when others =>
		null;
	end case; --for byteamt

	other0 <= or1;
	other1 <= or2;
	other2 <= or3;
	other3 <= or4;
	other4 <= or5;
	other5 <= or6;
	other6 <= or7;
	
when slliOP =>
	dir <= LEFT;

	case byteamt is
	when 0 => 
		or0 := R1byte0;
		or1 := R1byte1;
		or2 := R1byte2;
		or3 := R1byte3;
		or4 := R1byte4;
		or5 := R1byte5;
		or6 := R1byte6;
		or7 := R1byte7;
	
	when 1 =>
		or0 := zeros;
		or1 := R1byte0;
		or2 := R1byte1;
		or3 := R1byte2;
		or4 := R1byte3;
		or5 := R1byte4;
		or6 := R1byte5;
		or7 := R1byte6;
	
	when 2 =>
		or0 := zeros;
		or1 := zeros;
		or2 := R1byte0;
		or3 := R1byte1;
		or4 := R1byte2;
		or5 := R1byte3;
		or6 := R1byte4;
		or7 := R1byte5;
	
	when 3 =>
		or0 := zeros;
		or1 := zeros;
		or2 := zeros;
		or3 := R1byte0;
		or4 := R1byte1;
		or5 := R1byte2;
		or6 := R1byte3;
		or7 := R1byte4;
	
	when 4 =>
		or0 := zeros;
		or1 := zeros;
		or2 := zeros;
		or3 := zeros;
		or4 := R1byte0;
		or5 := R1byte1;
		or6 := R1byte2;
		or7 := R1byte3;
	
	when 5 =>
		or0 := zeros;
		or1 := zeros;
		or2 := zeros;
		or3 := zeros;
		or4 := zeros;
		or5 := R1byte0;
		or6 := R1byte1;
		or7 := R1byte2;
	
	when 6 =>
		or0 := zeros;
		or1 := zeros;
		or2 := zeros;
		or3 := zeros;
		or4 := zeros;
		or5 := zeros;
		or6 := R1byte0;
		or7 := R1byte1;
	
	when 7 =>
		or0 := zeros;
		or1 := zeros;
		or2 := zeros;
		or3 := zeros;
		or4 := zeros;
		or5 := zeros;
		or6 := zeros;
		or7 := R1byte0;
	
	when 8 =>
		or0 := zeros;
		or1 := zeros;
		or2 := zeros;
		or3 := zeros;
		or4 := zeros;
		or5 := zeros;
		or6 := zeros;
		or7 := zeros;
	
	when others =>
		null;
	end case;
	
	other0 <= zeros;
	other1 <= or0;
	other2 <= or1;
	other3 <= or2;
	other4 <= or3;
	other5 <= or4;
	other6 <= or5;
	other7 <= or6;
	
when sraiOP =>
	dir <= RIGHT;

	case byteamt is
	when 0 =>
		or0 := R1byte0;
		or1 := R1byte1;
		or2 := R1byte2;
		or3 := R1byte3;
		or4 := R1byte4;
		or5 := R1byte5;
		or6 := R1byte6;
		or7 := R1byte7;
	
	when 1 => 
		or0 := R1byte1;
		or1 := R1byte2;
		or2 := R1byte3;
		or3 := R1byte4;
		or4 := R1byte5;
		or5 := R1byte6;
		or6 := R1byte7;
		or7 := zeros;
		if Rs1(63) = '1' then
		or7 := ones;
		end if;
	
	when 2 =>
		or0 := R1byte2;
		or1 := R1byte3;
		or2 := R1byte4;
		or3 := R1byte5;
		or4 := R1byte6;
		or5 := R1byte7;
		or6 := zeros;
		or7 := zeros;
		if Rs1(63) = '1' then
		or6 := ones;
		or7 := ones;
		end if;
	
	when 3 =>
		or0 := R1byte3;
		or1 := R1byte4;
		or2 := R1byte5;
		or3 := R1byte6;
		or4 := R1byte7;
		or5 := zeros;
		or6 := zeros;
		or7 := zeros;
		if Rs1(63) = '1' then
		or5 := ones;
		or6 := ones;
		or7 := ones;
		end if;
	
	when 4 =>
		or0 := R1byte4;
		or1 := R1byte5;
		or2 := R1byte6;
		or3 := R1byte7;
		or4 := zeros;
		or5 := zeros;
		or6 := zeros;
		or7 := zeros;
		if Rs1(63) = '1' then
		or4 := ones;
		or5 := ones;
		or6 := ones;
		or7 := ones;
		end if;
	
	when 5 =>
		or0 := R1byte5;
		or1 := R1byte6;
		or2 := R1byte7;
		or3 := zeros;
		or4 := zeros;
		or5 := zeros;
		or6 := zeros;
		or7 := zeros;
		if Rs1(63) = '1' then
		or3 := ones;
		or4 := ones;
		or5 := ones;
		or6 := ones;
		or7 := ones;
		end if;	
	
	when 6 =>
		or0 := R1byte6;
		or1 := R1byte7;
		or2 := zeros;
		or3 := zeros;
		or4 := zeros;
		or5 := zeros;
		or6 := zeros;
		or7 := zeros;
		if Rs1(63) = '1' then
		or2 := ones;
		or3 := ones;
		or4 := ones;
		or5 := ones;
		or6 := ones;
		or7 := ones;
		end if;	
	
	when 7 =>
		or0 := R1byte7;
		or1 := zeros;
		or2 := zeros;
		or3 := zeros;
		or4 := zeros;
		or5 := zeros;
		or6 := zeros;
		or7 := zeros;
		if Rs1(63) = '1' then
		or1 := ones;
		or2 := ones;
		or3 := ones;
		or4 := ones;
		or5 := ones;
		or6 := ones;
		or7 := ones;
		end if;	
	
	when 8 =>
		or0 := zeros;
		or1 := zeros;
		or2 := zeros;
		or3 := zeros;
		or4 := zeros;
		or5 := zeros;
		or6 := zeros;
		or7 := zeros;
		if Rs1(63) = '1' then
		or0 := ones;
		or1 := ones;
		or2 := ones;
		or3 := ones;
		or4 := ones;
		or5 := ones;
		or6 := ones;
		or7 := ones;
		end if;

	when others =>
		null;
	end case;

	other0 <= or1;
	other1 <= or2;
	other2 <= or3;
	other3 <= or4;
	other4 <= or5;
	other5 <= or6;
	other6 <= or7;
	other7 <= zeros;
	if Rs1(63) = '1' then
	other7 <= ones;
	end if;

when srliOP =>
	dir <= RIGHT;

	case byteamt is
	when 0 =>
		or0 := R1byte0;
		or1 := R1byte1;
		or2 := R1byte2;
		or3 := R1byte3;
		or4 := R1byte4;
		or5 := R1byte5;
		or6 := R1byte6;
		or7 := R1byte7;
	
	when 1 => 
		or0 := R1byte1;
		or1 := R1byte2;
		or2 := R1byte3;
		or3 := R1byte4;
		or4 := R1byte5;
		or5 := R1byte6;
		or6 := R1byte7;
		or7 := zeros;
	
	when 2 =>
		or0 := R1byte2;
		or1 := R1byte3;
		or2 := R1byte4;
		or3 := R1byte5;
		or4 := R1byte6;
		or5 := R1byte7;
		or6 := zeros;
		or7 := zeros;
	
	when 3 =>
		or0 := R1byte3;
		or1 := R1byte4;
		or2 := R1byte5;
		or3 := R1byte6;
		or4 := R1byte7;
		or5 := zeros;
		or6 := zeros;
		or7 := zeros;
	
	when 4 =>
		or0 := R1byte4;
		or1 := R1byte5;
		or2 := R1byte6;
		or3 := R1byte7;
		or4 := zeros;
		or5 := zeros;
		or6 := zeros;
		or7 := zeros;
	
	when 5 =>
		or0 := R1byte5;
		or1 := R1byte6;
		or2 := R1byte7;
		or3 := zeros;
		or4 := zeros;
		or5 := zeros;
		or6 := zeros;
		or7 := zeros;
	
	when 6 =>
		or0 := R1byte6;
		or1 := R1byte7;
		or2 := zeros;
		or3 := zeros;
		or4 := zeros;
		or5 := zeros;
		or6 := zeros;
		or7 := zeros;
	
	when 7 =>
		or0 := R1byte7;
		or1 := zeros;
		or2 := zeros;
		or3 := zeros;
		or4 := zeros;
		or5 := zeros;
		or6 := zeros;
		or7 := zeros;
	
	when 8 =>
		or0 := zeros;
		or1 := zeros;
		or2 := zeros;
		or3 := zeros;
		or4 := zeros;
		or5 := zeros;
		or6 := zeros;
		or7 := zeros;
	
	when others =>
		null;
	end case;

	other0 <= or1;
	other1 <= or2;
	other2 <= or3;
	other3 <= or4;
	other4 <= or5;
	other5 <= or6;
	other6 <= or7;
	other7 <= zeros;
	
when Type4aOP =>
if SO(1 downto 0) = "00" then
	dir <= LEFT;
	case byteamt is
	when 0 =>
		or0 := R1byte0;
		or1 := R1byte1;
		or2 := R1byte2;
		or3 := R1byte3;
		or4 := R1byte4;
		or5 := R1byte5;
		or6 := R1byte6;
		or7 := R1byte7;
	
	if SO(5 downto 3) = "010" then --it's a mix left inst
	if subword = "00" then
		or7 := R1byte7;
		or6 := R2byte7;
		or5 := R1byte5;
		or4 := R2byte5;
		or3 := R1byte3;
		or2 := R2byte3;
		or1 := R1byte1;
		or0 := R2byte1;
	elsif subword = "01" then
		or7 := R1byte7;
		or6 := R1byte6;
		or5 := R2byte7;
		or4 := R2byte6;
		or3 := R1byte3;
		or2 := R1byte2;
		or1 := R2byte3;
		or0 := R2byte2;
	elsif subword = "10" then
		or7 := R1byte7;
		or6 := R1byte6;
		or5 := R1byte5;
		or4 := R1byte4;
		or3 := R2byte7;
		or2 := R2byte6;
		or1 := R2byte5;
		or0 := R2byte4;
	else null;
	end if;
	elsif SO(5 downto 3) = "100" then  --it's a perm instruction
	if Rs2(3 downto 0) = "0000" then
		or0 := R1byte0;
		or1 := R1byte1;
	elsif Rs2(3 downto 0) = "0001" then
		or0 := R1byte2;
		or1 := R1byte3;
	elsif Rs2(3 downto 0) = "0010" then
		or0 := R1byte4;
		or1 := R1byte5;
	elsif Rs2(3 downto 0) = "0011" then
		or0 := R1byte6;
		or1 := R1byte7;
	else null;
	end if;

	if Rs2(7 downto 4) = "0000" then
		or2 := R1byte0;
		or3 := R1byte1;
	elsif Rs2(7 downto 4) = "0001" then
		or2 := R1byte2;
		or3 := R1byte3;
	elsif Rs2(7 downto 4) = "0010" then
		or2 := R1byte4;
		or3 := R1byte5;
	elsif Rs2(7 downto 4) = "0011" then
		or2 := R1byte6;
		or3 := R1byte7;
	else null;
	end if;	
	
	if Rs2(11 downto 8) = "0000" then
		or4 := R1byte0;
		or5 := R1byte1;
	elsif Rs2(11 downto 8) = "0001" then
		or4 := R1byte2;
		or5 := R1byte3;
	elsif Rs2(11 downto 8) = "0010" then
		or4 := R1byte4;
		or5 := R1byte5;
	elsif Rs2(11 downto 8) = "0011" then
		or4 := R1byte6;
		or5 := R1byte7;
	else null;
	end if;	

	if Rs2(15 downto 12) = "0000" then
		or6 := R1byte0;
		or7 := R1byte1;
	elsif Rs2(15 downto 12) = "0001" then
		or6 := R1byte2;
		or7 := R1byte3;
	elsif Rs2(15 downto 12) = "0010" then
		or6 := R1byte4;
		or7 := R1byte5;
	elsif Rs2(15 downto 12) = "0011" then
		or6 := R1byte6;
		or7 := R1byte7;
	else null;
	end if;	

	end if;  --end the SO(5 downto 3) if
	when 1 =>
		or0 := zeros;
		or1 := R1byte0;
		or2 := R1byte1;
		or3 := R1byte2;
		or4 := R1byte3;
		or5 := R1byte4;
		or6 := R1byte5;
		or7 := R1byte6;
		
		if subword = "01" then
			or2 := zeros;
			or4 := zeros;
			or6 := zeros;
		elsif subword = "10" then
			or4 := zeros;
		else null;
		end if;

	when 2 =>
		or0 := zeros;
		or1 := zeros;
		or2 := R1byte0;
		or3 := R1byte1;
		or4 := R1byte2;
		or5 := R1byte3;
		or6 := R1byte4;
		or7 := R1byte5;
		
		if subword = "01" then
			or2 := zeros;
			or3 := zeros;
			or4 := zeros;
			or5 := zeros;
			or6 := zeros;
			or7 := zeros;
		elsif subword = "10" then
			or4 := zeros;
			or5 := zeros;
		end if;

	when 3 =>
		or0 := zeros;
		or1 := zeros;
		or2 := zeros;
		or3 := R1byte0;
		or4 := R1byte1;
		or5 := R1byte2;
		or6 := R1byte3;
		or7 := R1byte4;

		if subword = "10" then
			or4 := zeros;
			or5 := zeros;
			or6 := zeros;
		end if;
		
	when 4 =>
		or0 := zeros;
		or1 := zeros;
		or2 := zeros;
		or3 := zeros;
		or4 := R1byte0;
		or5 := R1byte1;
		or6 := R1byte2;
		or7 := R1byte3;

		if subword = "10" then
			or4 := zeros;
			or5 := zeros;
			or6 := zeros;
			or7 := zeros;
		end if;
	when 5 =>
		or0 := zeros;
		or1 := zeros;
		or2 := zeros;
		or3 := zeros;
		or4 := zeros;
		or5 := R1byte0;
		or6 := R1byte1;
		or7 := R1byte2;
	
	when 6 =>
		or0 := zeros;
		or1 := zeros;
		or2 := zeros;
		or3 := zeros;
		or4 := zeros;
		or5 := zeros;
		or6 := R1byte0;
		or7 := R1byte1;
	
	when 7 =>
		or0 := zeros;
		or1 := zeros;
		or2 := zeros;
		or3 := zeros;
		or4 := zeros;
		or5 := zeros;
		or6 := zeros;
		or7 := R1byte0;
	
	when 8 =>
		or0 := zeros;
		or1 := zeros;
		or2 := zeros;
		or3 := zeros;
		or4 := zeros;
		or5 := zeros;
		or6 := zeros;
		or7 := zeros;
	
	when others =>
		null;
	end case;
	
	other0 <= zeros;
	other1 <= or0;
	other2 <= or1;
	other3 <= or2;
	other4 <= or3;
	other5 <= or4;
	other6 <= or5;
	other7 <= or6;	
	
	if subword = "01" then
	mux2 <= logical;
	mux4 <= logical;
	mux6 <= logical;
	elsif subword = "10" then
	mux4 <= logical;
	end if;
			
elsif SO(1 downto 0) = "01" then --dir is right arith
	dir <= RIGHT;
	
	case byteamt is
	when 0 =>
		or0 := R1byte0;
		or1 := R1byte1;
		or2 := R1byte2;
		or3 := R1byte3;
		or4 := R1byte4;
		or5 := R1byte5;
		or6 := R1byte6;
		or7 := R1byte7;

	if SO(5 downto 3) = "010" then --it's a mix right inst
	if subword = "00" then
		or7 := R1byte6;
		or6 := R2byte6;
		or5 := R1byte4;
		or4 := R2byte4;
		or3 := R1byte2;
		or2 := R2byte2;
		or1 := R1byte0;
		or0 := R2byte0;
	elsif subword = "01" then
		or7 := R1byte5;
		or6 := R1byte4;
		or5 := R2byte5;
		or4 := R2byte4;
		or3 := R1byte1;
		or2 := R1byte0;
		or1 := R2byte1;
		or0 := R2byte0;
	elsif subword = "10" then
		or7 := R1byte3;
		or6 := R1byte2;
		or5 := R1byte1;
		or4 := R1byte0;
		or3 := R2byte3;
		or2 := R2byte2;
		or1 := R2byte1;
		or0 := R2byte0;
	end if;
	end if;	
	when 1 => 
		or0 := R1byte1;
		or1 := R1byte2;
		or2 := R1byte3;
		or3 := R1byte4;
		or4 := R1byte5;
		or5 := R1byte6;
		or6 := R1byte7;
		or7 := zeros;
		if Rs1(63) = '1' then
		or7 := ones;
		end if;

		if subword = "01" then
		or1 := zeros;
		or3 := zeros;
		or5 := zeros;
		if  R1byte1(7) = '1' then
		or1 := ones;
		end if;
		if R1byte3(7) = '1' then
		or3 := ones;
		end if;
		if R1byte5(7) = '1' then
		or5 := ones;
		end if;
	
		elsif subword = "10" then
		or3 := zeros;
		if R1byte3(7) = '1' then
		or3 := ones;
		end if;

		end if;

	when 2 =>
		or0 := R1byte2;
		or1 := R1byte3;
		or2 := R1byte4;
		or3 := R1byte5;
		or4 := R1byte6;
		or5 := R1byte7;
		or6 := zeros;
		or7 := zeros;
		if Rs1(63) = '1' then
		or6 := ones;
		or7 := ones;
		end if;

		if subword = "01" then
		or5 := zeros;
		or4 := zeros;
		or3 := zeros;
		or2 := zeros;
		or1 := zeros;
		or0 := zeros;
		if R1byte5(7) = '1' then
		or5 := ones;
		or4 := ones;
		end if;
		if R1byte3(7) = '1' then
		or3 := ones;
		or2 := ones;
		end if;
		if R1byte1(7) = '1' then
		or1 := ones;
		or0 := ones;
		end if;
		elsif subword = "10" then
		or3 := zeros;
		or2 := zeros;
		if R1byte3(7) = '1' then
		or3 := ones;
		or2 := ones;
		end if;
		end if;
		
	when 3 =>
		or0 := R1byte3;
		or1 := R1byte4;
		or2 := R1byte5;
		or3 := R1byte6;
		or4 := R1byte7;
		or5 := zeros;
		or6 := zeros;
		or7 := zeros;
		if Rs1(63) = '1' then
		or5 := ones;
		or6 := ones;
		or7 := ones;
		end if;

		if subword = "10" then
		or3 := zeros;
		or2 := zeros;
		or1 := zeros;
		if R1byte3(7) = '1' then
		or3 := ones;
		or2 := ones;
		or1 := ones;
		end if;
		end if;
	
	when 4 =>
		or0 := R1byte4;
		or1 := R1byte5;
		or2 := R1byte6;
		or3 := R1byte7;
		or4 := zeros;
		or5 := zeros;
		or6 := zeros;
		or7 := zeros;
		if Rs1(63) = '1' then
		or4 := ones;
		or5 := ones;
		or6 := ones;
		or7 := ones;
		end if;
	
		if subword = "10" then
		or3 := zeros;
		or2 := zeros;
		or1 := zeros;
		or0 := zeros;
		if R1byte3(7) = '1' then
		or3 := ones;
		or2 := ones;
		or1 := ones;
		or0 := ones;
		end if;
		end if;

	when 5 =>
		or0 := R1byte5;
		or1 := R1byte6;
		or2 := R1byte7;
		or3 := zeros;
		or4 := zeros;
		or5 := zeros;
		or6 := zeros;
		or7 := zeros;
		if Rs1(63) = '1' then
		or3 := ones;
		or4 := ones;
		or5 := ones;
		or6 := ones;
		or7 := ones;
		end if;	
	
	when 6 =>
		or0 := R1byte6;
		or1 := R1byte7;
		or2 := zeros;
		or3 := zeros;
		or4 := zeros;
		or5 := zeros;
		or6 := zeros;
		or7 := zeros;
		if Rs1(63) = '1' then
		or2 := ones;
		or3 := ones;
		or4 := ones;
		or5 := ones;
		or6 := ones;
		or7 := ones;
		end if;	
	
	when 7 =>
		or0 := R1byte7;
		or1 := zeros;
		or2 := zeros;
		or3 := zeros;
		or4 := zeros;
		or5 := zeros;
		or6 := zeros;
		or7 := zeros;
		if Rs1(63) = '1' then
		or1 := ones;
		or2 := ones;
		or3 := ones;
		or4 := ones;
		or5 := ones;
		or6 := ones;
		or7 := ones;
		end if;	
	
	when 8 =>
		or0 := zeros;
		or1 := zeros;
		or2 := zeros;
		or3 := zeros;
		or4 := zeros;
		or5 := zeros;
		or6 := zeros;
		or7 := zeros;
		if Rs1(63) = '1' then
		or0 := ones;
		or1 := ones;
		or2 := ones;
		or3 := ones;
		or4 := ones;
		or5 := ones;
		or6 := ones;
		or7 := ones;
		end if;

	when others =>
		null;
	end case;

	other0 <= or1;
	other1 <= or2;
	other2 <= or3;
	other3 <= or4;
	other4 <= or5;
	other5 <= or6;
	other6 <= or7;
	other7 <= zeros;
	if Rs1(63) = '1' then
	other7 <= ones;
	end if;

	if subword = "01" then
	mux5 <= logical;
	mux3 <= logical;
	mux1 <= logical;
	if R1byte5(7) = '1' then
	mux5 <= arith1;
	end if;
	if R1byte3(7) = '1' then
	mux3 <= arith1;
	end if;
	if R1byte1(7) = '1' then
	mux1 <= arith1;
	end if;
	elsif subword = "10" then
	mux3 <= logical;
	if R1byte3(7) = '1' then
	mux3 <= arith1;
	end if;
	end if;

elsif SO(1 downto 0) = "10" then
	dir <= RIGHT;
	
	case byteamt is
	when 0 =>
		or0 := R1byte0;
		or1 := R1byte1;
		or2 := R1byte2;
		or3 := R1byte3;
		or4 := R1byte4;
		or5 := R1byte5;
		or6 := R1byte6;
		or7 := R1byte7;
	
	when 1 => 
		or0 := R1byte1;
		or1 := R1byte2;
		or2 := R1byte3;
		or3 := R1byte4;
		or4 := R1byte5;
		or5 := R1byte6;
		or6 := R1byte7;
		or7 := zeros;

		if subword = "01" then
		or1 := zeros;
		or3 := zeros;
		or5 := zeros;
		elsif subword = "10" then
		or3 := zeros;
		end if;

	when 2 =>
		or0 := R1byte2;
		or1 := R1byte3;
		or2 := R1byte4;
		or3 := R1byte5;
		or4 := R1byte6;
		or5 := R1byte7;
		or6 := zeros;
		or7 := zeros;

		if subword = "01" then
		or5 := zeros;
		or4 := zeros;
		or3 := zeros;
		or2 := zeros;
		or1 := zeros;
		or0 := zeros;
		elsif subword = "10" then
		or3 := zeros;
		or2 := zeros;
		end if;
		
	when 3 =>
		or0 := R1byte3;
		or1 := R1byte4;
		or2 := R1byte5;
		or3 := R1byte6;
		or4 := R1byte7;
		or5 := zeros;
		or6 := zeros;
		or7 := zeros;

		if subword = "10" then
		or3 := zeros;
		or2 := zeros;
		or1 := zeros;
		end if;
	
	when 4 =>
		or0 := R1byte4;
		or1 := R1byte5;
		or2 := R1byte6;
		or3 := R1byte7;
		or4 := zeros;
		or5 := zeros;
		or6 := zeros;
		or7 := zeros;
	
		if subword = "10" then
		or3 := zeros;
		or2 := zeros;
		or1 := zeros;
		or0 := zeros;
		end if;

	when 5 =>
		or0 := R1byte5;
		or1 := R1byte6;
		or2 := R1byte7;
		or3 := zeros;
		or4 := zeros;
		or5 := zeros;
		or6 := zeros;
		or7 := zeros;
	
	when 6 =>
		or0 := R1byte6;
		or1 := R1byte7;
		or2 := zeros;
		or3 := zeros;
		or4 := zeros;
		or5 := zeros;
		or6 := zeros;
		or7 := zeros;
	
	when 7 =>
		or0 := R1byte7;
		or1 := zeros;
		or2 := zeros;
		or3 := zeros;
		or4 := zeros;
		or5 := zeros;
		or6 := zeros;
		or7 := zeros;
	
	when 8 =>
		or0 := zeros;
		or1 := zeros;
		or2 := zeros;
		or3 := zeros;
		or4 := zeros;
		or5 := zeros;
		or6 := zeros;
		or7 := zeros;

	when others =>
		null;
	end case;

	other0 <= or1;
	other1 <= or2;
	other2 <= or3;
	other3 <= or4;
	other4 <= or5;
	other5 <= or6;
	other6 <= or7;
	other7 <= zeros;

	if subword = "01" then
	mux5 <= logical;
	mux3 <= logical;
	mux1 <= logical;
	elsif subword = "10" then
	mux3 <= logical;
	end if;	
	
end if;

when Type4bOP =>
if SO(2 downto 0) = "000" then
	dir <= LEFT;
	case byteamt is
	when 0 =>
		or0 := R1byte0;
		or1 := R1byte1;
		or2 := R1byte2;
		or3 := R1byte3;
		or4 := R1byte4;
		or5 := R1byte5;
		or6 := R1byte6;
		or7 := R1byte7;
	
	if SO(5 downto 3) = "001" then --it's a mux.rev
		or0 := R1byte7;
		or1 := R1byte6;
		or2 := R1byte5;
		or3 := R1byte4;
		or4 := R1byte3;
		or5 := R1byte2;
		or6 := R1byte1;
		or7 := R1byte0;
	end if;

	when 1 =>
		or0 := zeros;
		or1 := R1byte0;
		or2 := R1byte1;
		or3 := R1byte2;
		or4 := R1byte3;
		or5 := R1byte4;
		or6 := R1byte5;
		or7 := R1byte6;
		
		if subword = "01" then
			or2 := zeros;
			or4 := zeros;
			or6 := zeros;
		elsif subword = "10" then
			or4 := zeros;
		end if;

	when 2 =>
		or0 := zeros;
		or1 := zeros;
		or2 := R1byte0;
		or3 := R1byte1;
		or4 := R1byte2;
		or5 := R1byte3;
		or6 := R1byte4;
		or7 := R1byte5;
		
		if subword = "01" then
			or2 := zeros;
			or3 := zeros;
			or4 := zeros;
			or5 := zeros;
			or6 := zeros;
			or7 := zeros;
		elsif subword = "10" then
			or4 := zeros;
			or5 := zeros;
		end if;

	when 3 =>
		or0 := zeros;
		or1 := zeros;
		or2 := zeros;
		or3 := R1byte0;
		or4 := R1byte1;
		or5 := R1byte2;
		or6 := R1byte3;
		or7 := R1byte4;

		if subword = "10" then
			or4 := zeros;
			or5 := zeros;
			or6 := zeros;
		end if;
	
	when others =>
		null;
	end case;
	
	other0 <= zeros;
	other1 <= or0;
	other2 <= or1;
	other3 <= or2;
	other4 <= or3;
	other5 <= or4;
	other6 <= or5;
	other7 <= or6;	
	
	if subword = "01" then
	mux2 <= logical;
	mux4 <= logical;
	mux6 <= logical;
	elsif subword = "10" then
	mux4 <= logical;
	end if;
			
elsif SO(2 downto 0) = "001" then --dir is right arith
	dir <= RIGHT;
	
	case byteamt is
	when 0 =>
		or0 := R1byte0;
		or1 := R1byte1;
		or2 := R1byte2;
		or3 := R1byte3;
		or4 := R1byte4;
		or5 := R1byte5;
		or6 := R1byte6;
		or7 := R1byte7;
	
	if SO(5 downto 3) = "001" then --it's a mux.mix
		or0 := R1byte0;
		or1 := R1byte4;
		or2 := R1byte2;
		or3 := R1byte6;
		or4 := R1byte1;
		or5 := R1byte5;
		or6 := R1byte3;
		or7 := R1byte7;
	end if;
	when 1 => 
		or0 := R1byte1;
		or1 := R1byte2;
		or2 := R1byte3;
		or3 := R1byte4;
		or4 := R1byte5;
		or5 := R1byte6;
		or6 := R1byte7;
		or7 := zeros;
		if Rs1(63) = '1' then
		or7 := ones;
		end if;

		if subword = "01" then
		or1 := zeros;
		or3 := zeros;
		or5 := zeros;
		if  R1byte1(7) = '1' then
		or1 := ones;
		end if;
		if R1byte3(7) = '1' then
		or3 := ones;
		end if;
		if R1byte5(7) = '1' then
		or5 := ones;
		end if;
	
		elsif subword = "10" then
		or3 := zeros;
		if R1byte3(7) = '1' then
		or3 := ones;
		end if;

		end if;

	when 2 =>
		or0 := R1byte2;
		or1 := R1byte3;
		or2 := R1byte4;
		or3 := R1byte5;
		or4 := R1byte6;
		or5 := R1byte7;
		or6 := zeros;
		or7 := zeros;
		if Rs1(63) = '1' then
		or6 := ones;
		or7 := ones;
		end if;

		if subword = "01" then
		or5 := zeros;
		or4 := zeros;
		or3 := zeros;
		or2 := zeros;
		or1 := zeros;
		or0 := zeros;
		if R1byte5(7) = '1' then
		or5 := ones;
		or4 := ones;
		end if;
		if R1byte3(7) = '1' then
		or3 := ones;
		or2 := ones;
		end if;
		if R1byte1(7) = '1' then
		or1 := ones;
		or0 := ones;
		end if;
		elsif subword = "10" then
		or3 := zeros;
		or2 := zeros;
		if R1byte3(7) = '1' then
		or3 := ones;
		or2 := ones;
		end if;
		end if;
		
	when 3 =>
		or0 := R1byte3;
		or1 := R1byte4;
		or2 := R1byte5;
		or3 := R1byte6;
		or4 := R1byte7;
		or5 := zeros;
		or6 := zeros;
		or7 := zeros;
		if Rs1(63) = '1' then
		or5 := ones;
		or6 := ones;
		or7 := ones;
		end if;

		if subword = "10" then
		or3 := zeros;
		or2 := zeros;
		or1 := zeros;
		if R1byte3(7) = '1' then
		or3 := ones;
		or2 := ones;
		or1 := ones;
		end if;
		end if;	

	when others =>
		null;
	end case;

	other0 <= or1;
	other1 <= or2;
	other2 <= or3;
	other3 <= or4;
	other4 <= or5;
	other5 <= or6;
	other6 <= or7;
	other7 <= zeros;
	if Rs1(63) = '1' then
	other7 <= ones;
	end if;

	if subword = "01" then
	mux5 <= logical;
	mux3 <= logical;
	mux1 <= logical;
	if R1byte5(7) = '1' then
	mux5 <= arith1;
	end if;
	if R1byte3(7) = '1' then
	mux3 <= arith1;
	end if;
	if R1byte1(7) = '1' then
	mux1 <= arith1;
	end if;
	elsif subword = "10" then
	mux3 <= logical;
	if R1byte3(7) = '1' then
	mux3 <= arith1;
	end if;
	end if;

elsif SO(2 downto 0) = "010" then
	dir <= RIGHT;
	
	case byteamt is
	when 0 =>
		or0 := R1byte0;
		or1 := R1byte1;
		or2 := R1byte2;
		or3 := R1byte3;
		or4 := R1byte4;
		or5 := R1byte5;
		or6 := R1byte6;
		or7 := R1byte7;
	
	if SO(5 downto 3) = "001" then --it's mux.shuf
		or0 := R1byte0;
		or1 := R1byte4;
		or2 := R1byte1;
		or3 := R1byte5;
		or4 := R1byte2;
		or5 := R1byte6;
		or6 := R1byte3;
		or7 := R1byte7;
	end if;
	when 1 => 
		or0 := R1byte1;
		or1 := R1byte2;
		or2 := R1byte3;
		or3 := R1byte4;
		or4 := R1byte5;
		or5 := R1byte6;
		or6 := R1byte7;
		or7 := zeros;

		if subword = "01" then
		or1 := zeros;
		or3 := zeros;
		or5 := zeros;
		elsif subword = "10" then
		or3 := zeros;
		end if;

	when 2 =>
		or0 := R1byte2;
		or1 := R1byte3;
		or2 := R1byte4;
		or3 := R1byte5;
		or4 := R1byte6;
		or5 := R1byte7;
		or6 := zeros;
		or7 := zeros;

		if subword = "01" then
		or5 := zeros;
		or4 := zeros;
		or3 := zeros;
		or2 := zeros;
		or1 := zeros;
		or0 := zeros;
		elsif subword = "10" then
		or3 := zeros;
		or2 := zeros;
		end if;
		
	when 3 =>
		or0 := R1byte3;
		or1 := R1byte4;
		or2 := R1byte5;
		or3 := R1byte6;
		or4 := R1byte7;
		or5 := zeros;
		or6 := zeros;
		or7 := zeros;

		if subword = "10" then
		or3 := zeros;
		or2 := zeros;
		or1 := zeros;
		end if;

	when others =>
		null;
	end case;

	other0 <= or1;
	other1 <= or2;
	other2 <= or3;
	other3 <= or4;
	other4 <= or5;
	other5 <= or6;
	other6 <= or7;
	other7 <= zeros;

	if subword = "01" then
	mux5 <= logical;
	mux3 <= logical;
	mux1 <= logical;
	elsif subword = "10" then
	mux3 <= logical;
	end if;	
	
elsif SO(2 downto 0) = "011" then -- mux.alt
	or0 := R1byte0;
	or1 := R1byte2;
	or2 := R1byte4;
	or3 := R1byte6;
	or4 := R1byte1;
	or5 := R1byte3;
	or6 := R1byte5;
	or7 := R1byte7;

	--these other signals are assigned but don't matter
	other0 <= or1;
	other1 <= or2;
	other2 <= or3;
	other3 <= or4;
	other4 <= or5;
	other5 <= or6;
	other6 <= or7;
	other7 <= zeros;

elsif SO(2 downto 0) = "100" then --mux.brcst
	or0 := R1byte0;	
	or1 := R1byte0;	
	or2 := R1byte0;	
	or3 := R1byte0;	
	or4 := R1byte0;	
	or5 := R1byte0;	
	or6 := R1byte0;	
	or7 := R1byte0;	

	--these other signals are assigned but don't matter
	other0 <= or1;
	other1 <= or2;
	other2 <= or3;
	other3 <= or4;
	other4 <= or5;
	other5 <= or6;
	other6 <= or7;
	other7 <= zeros;
end if;

when depositOP =>
	if imm7(0) = '1' then
	location := 1;
	end if;
	if imm7(1) = '1' then
	location := location + 2;
	end if;
	if imm7(2) = '1' then
	location := location + 4;
	end if;
	if imm7(3) = '1' then
	location := location + 8;
	end if;
	if imm7(4) = '1' then
	location := location + 16;
	end if;
	if imm7(5) = '1' then
	location := location + 32;
	end if;
	if imm7(6) = '1' then
	location := location + 64;
	end if;

	if imm6(0) = '1' then 
	length := 1;
	end if;
	if imm6(1) = '1' then
	length := length + 2;
	end if;
	if imm6(2) = '1' then
	length := length + 4;
	end if;
	if imm6(3) = '1' then
	length := length + 8;
	end if;
	if imm6(4) = '1' then
	length := length + 16;
	end if;
	if imm6(5) = '1' then
	length := length + 32;
	end if;

	tempRd(63 downto (length+location)) := Rs2(63 downto (length+location));
	tempRd((length+location-1) downto location) := Rs1((length-1) downto 0);
	tempRd((location-1) downto 0) := Rs2((location-1) downto 0);
	
	or0 := tempRd(7 downto 0);
	or1 := tempRd(15 downto 8);
	or2 := tempRd(23 downto 16);
	or3 := tempRd(31 downto 24);
	or4 := tempRd(39 downto 32);
	or5 := tempRd(47 downto 40);
	or6 := tempRd(55 downto 48);
	or7 := tempRd(63 downto 56);

	--these other signals are assigned but don't matter
	other0 <= or1;
	other1 <= or2;
	other2 <= or3;
	other3 <= or4;
	other4 <= or5;
	other5 <= or6;
	other6 <= or7;
	other7 <= zeros;

when extractOP =>
	if imm7(0) = '1' then
	location := 1;
	end if;
	if imm7(1) = '1' then
	location := location + 2;
	end if;
	if imm7(2) = '1' then
	location := location + 4;
	end if;
	if imm7(3) = '1' then
	location := location + 8;
	end if;
	if imm7(4) = '1' then
	location := location + 16;
	end if;
	if imm7(5) = '1' then
	location := location + 32;
	end if;
	if imm7(6) = '1' then
	location := location + 64;
	end if;

	if imm6(0) = '1' then 
	length := 1;
	end if;
	if imm6(1) = '1' then
	length := length + 2;
	end if;
	if imm6(2) = '1' then
	length := length + 4;
	end if;
	if imm6(3) = '1' then
	length := length + 8;
	end if;
	if imm6(4) = '1' then
	length := length + 16;
	end if;
	if imm6(5) = '1' then
	length := length + 32;
	end if;

	tempRd((length-1) downto 0) := Rs1((length+location-1) downto location);

	or0 := tempRd(7 downto 0);
	or1 := tempRd(15 downto 8);
	or2 := tempRd(23 downto 16);
	or3 := tempRd(31 downto 24);
	or4 := tempRd(39 downto 32);
	or5 := tempRd(47 downto 40);
	or6 := tempRd(55 downto 48);
	or7 := tempRd(63 downto 56);

	--these other signals are assigned but don't matter
	other0 <= or1;
	other1 <= or2;
	other2 <= or3;
	other3 <= or4;
	other4 <= or5;
	other5 <= or6;
	other6 <= or7;
	other7 <= zeros;	
	
when others =>
	null;
end case;

	
orig0 <= or0;
orig1 <= or1;
orig2 <= or2;
orig3 <= or3;
orig4 <= or4;
orig5 <= or5;
orig6 <= or6;
orig7 <= or7;


end process;

end opcodes;    
