diff --git a/decode1.vhdl b/decode1.vhdl index 823667c..d00372b 100644 --- a/decode1.vhdl +++ b/decode1.vhdl @@ -199,10 +199,10 @@ architecture behaviour of decode1 is INSN_fsubs => (FPU, FPU, OP_FP_ARITH, FRA, FRB, NONE, NONE, FRT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '0', '0', NONE), INSN_ftdiv => (FPU, FPU, OP_FP_CMP, FRA, FRB, NONE, NONE, NONE, '0', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), INSN_ftsqrt => (FPU, FPU, OP_FP_CMP, NONE, FRB, NONE, NONE, NONE, '0', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), - INSN_hashchk => (LDST, NONE, OP_LOAD, RA, IMM, CONST_DSX, RBC, NONE, '0', '0', '0', '0', ZERO, '0', is8B, '0', '0', '0', '0', '0', '1', NONE, '0', '0', '0', NONE), - INSN_hashchkp => (LDST, NONE, OP_LOAD, RA, IMM, CONST_DSX, RBC, NONE, '0', '0', '0', '0', ZERO, '0', is8B, '0', '0', '0', '0', '0', '1', NONE, '0', '1', '0', NONE), - INSN_hashst => (LDST, NONE, OP_STORE, RA, IMM, CONST_DSX, RBC, NONE, '0', '0', '0', '0', ZERO, '0', is8B, '0', '0', '0', '0', '0', '1', NONE, '0', '0', '0', NONE), - INSN_hashstp => (LDST, NONE, OP_STORE, RA, IMM, CONST_DSX, RBC, NONE, '0', '0', '0', '0', ZERO, '0', is8B, '0', '0', '0', '0', '0', '1', NONE, '0', '1', '0', NONE), + INSN_hashchk => (LDST, NONE, OP_LOAD, RA, RB, NONE, NONE, NONE, '0', '0', '0', '0', ZERO, '0', is8B, '0', '0', '0', '0', '0', '1', NONE, '0', '0', '0', NONE), + INSN_hashchkp => (LDST, NONE, OP_LOAD, RA, RB, NONE, NONE, NONE, '0', '0', '0', '0', ZERO, '0', is8B, '0', '0', '0', '0', '0', '1', NONE, '0', '1', '0', NONE), + INSN_hashst => (LDST, NONE, OP_STORE, RA, RB, NONE, NONE, NONE, '0', '0', '0', '0', ZERO, '0', is8B, '0', '0', '0', '0', '0', '1', NONE, '0', '0', '0', NONE), + INSN_hashstp => (LDST, NONE, OP_STORE, RA, RB, NONE, NONE, NONE, '0', '0', '0', '0', ZERO, '0', is8B, '0', '0', '0', '0', '0', '1', NONE, '0', '1', '0', NONE), INSN_icbi => (ALU, NONE, OP_ICBI, NONE, IMM, NONE, NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '1', NONE), INSN_icbt => (ALU, NONE, OP_ICBT, NONE, IMM, NONE, NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), INSN_isel => (ALU, NONE, OP_ISEL, RA_OR_ZERO, RB, NONE, NONE, RT, '1', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), @@ -726,12 +726,6 @@ begin if (icode = INSN_stq or icode = INSN_stqcx) and f_in.big_endian = '0' then vr.reg_3_addr(0) := '1'; end if; - -- See if this is an instruction where we need to use the RS/RC - -- read port to read the RB operand, because we want to get an - -- immediate operand to execute1 via read_data2. - if (icode = INSN_hashst or icode = INSN_hashchk or icode = INSN_hashstp or icode = INSN_hashchkp) then - vr.reg_3_addr := '0' & insn_rb(f_in.insn); - end if; vr.read_1_enable := f_in.valid; vr.read_2_enable := f_in.valid and maybe_rb; vr.read_3_enable := f_in.valid; diff --git a/decode2.vhdl b/decode2.vhdl index e99432b..212d78d 100644 --- a/decode2.vhdl +++ b/decode2.vhdl @@ -140,8 +140,6 @@ architecture behaviour of decode2 is ret := x"00000000000000" & "00" & insn_in(1) & insn_in(15 downto 11); when CONST_SH32 => ret := x"00000000000000" & "000" & insn_in(15 downto 11); - when CONST_DSX => - ret := 55x"7FFFFFFFFFFFFF" & insn_in(0) & insn_in(25 downto 21) & "000"; when others => ret := (others => '0'); end case; @@ -188,8 +186,6 @@ architecture behaviour of decode2 is else return ('0', (others => '0')); end if; - when RBC => - return ('1', gpr_to_gspr(insn_rb(insn_in))); when NONE => return ('0', (others => '0')); end case; diff --git a/decode_types.vhdl b/decode_types.vhdl index be0ae76..338a675 100644 --- a/decode_types.vhdl +++ b/decode_types.vhdl @@ -420,9 +420,8 @@ package decode_types is type input_reg_a_t is (NONE, RA, RA_OR_ZERO, RA0_OR_CIA, CIA, FRA); type input_reg_b_t is (IMM, RB, FRB); type const_sel_t is (NONE, CONST_UI, CONST_SI, CONST_SI_HI, CONST_UI_HI, CONST_LI, CONST_BD, - CONST_DXHI4, CONST_DS, CONST_DQ, CONST_M1, CONST_SH, CONST_SH32, CONST_PSI, - CONST_DSX); - type input_reg_c_t is (NONE, RS, RCR, RBC, FRC, FRS); + CONST_DXHI4, CONST_DS, CONST_DQ, CONST_M1, CONST_SH, CONST_SH32, CONST_PSI); + type input_reg_c_t is (NONE, RS, RCR, FRC, FRS); type output_reg_a_t is (NONE, RT, RA, FRT); type rc_t is (NONE, ONE, RC, RCOE); type carry_in_t is (ZERO, CA, OV, ONE); diff --git a/loadstore1.vhdl b/loadstore1.vhdl index 5d05bbb..c32781b 100644 --- a/loadstore1.vhdl +++ b/loadstore1.vhdl @@ -108,6 +108,7 @@ architecture behave of loadstore1 is two_dwords : std_ulogic; incomplete : std_ulogic; ea_valid : std_ulogic; + hash_addr : std_ulogic_vector(63 downto 0); end record; constant request_init : request_t := (addr => (others => '0'), byte_sel => x"00", second_bytes => x"00", @@ -116,6 +117,7 @@ architecture behave of loadstore1 is elt_length => x"0", brev_mask => "000", xerc => xerc_init, sprsel => "0000", ric => "00", + hash_addr => 64x"0", others => '0'); type reg_stage1_t is record @@ -529,7 +531,7 @@ begin -- start a new hash process hv.z0 := 31x"7D12B0E6"; -- 0xFA2561CD >> 1 ra := l_in.addr1; - rb := l_in.data; + rb := l_in.addr2; key := l_in.hashkey; for lane in 0 to 3 loop j := lane * 16; @@ -566,6 +568,7 @@ begin variable misaligned : std_ulogic; variable addr_mask : std_ulogic_vector(2 downto 0); variable hash_nop : std_ulogic; + variable disp : std_ulogic_vector(63 downto 0); begin v := request_init; sprn := l_in.insn(15 downto 11) & l_in.insn(20 downto 16); @@ -598,6 +601,9 @@ begin v.sprsel := "100" & sprn(8); end if; + disp := l_in.addr2; + if l_in.hash = '1' then + end if; lsu_sum := std_ulogic_vector(unsigned(l_in.addr1) + unsigned(l_in.addr2)); if HAS_FPU and l_in.is_32bit = '1' then @@ -615,8 +621,13 @@ begin addr := std_ulogic_vector(unsigned(r1.addr0(63 downto 3)) + not l_in.update) & r1.addr0(2 downto 0); end if; + -- Hash instructions have a short immediate displacement field, + -- interpreted as a negative multiple of 8 + disp := 55x"7FFFFFFFFFFFFF" & l_in.insn(0) & l_in.insn(25 downto 21) & "000"; + v.hash_addr := std_ulogic_vector(unsigned(l_in.addr1) + unsigned(disp)); if l_in.mode_32bit = '1' then addr(63 downto 32) := (others => '0'); + v.hash_addr(63 downto 32) := (others => '0'); end if; v.addr := addr; v.ea_valid := l_in.valid; @@ -812,6 +823,9 @@ begin -- need to initiate and then wait for the hash computation hash_start <= not r1.busy; v.busy := not hash_r.done; + if r1.busy = '1' then + v.req.addr := r1.req.hash_addr; + end if; if hash_r.done = '0' then issue := '0'; else