core: Simplify operand presentation for hash instructions

This removes the cases in the decode stages which allowed the C
register address to come from the RB field for the hash instructions
(hashst[p], hashchk[p]), and generated a negative immediate value for
the B operand.  The motivation is to simpify the logic for the C
register address.  Instead the unusual construction of the address for
the hash instructions is handled in the loadstore1_in process, and the
hash computation uses the A and B operands rather than A and C.

Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
pull/445/head
Paul Mackerras 4 months ago
parent dc9d351833
commit e14712e45c

@ -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_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_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_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_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, IMM, CONST_DSX, RBC, NONE, '0', '0', '0', '0', ZERO, '0', is8B, '0', '0', '0', '0', '0', '1', NONE, '0', '1', '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, IMM, CONST_DSX, RBC, NONE, '0', '0', '0', '0', ZERO, '0', is8B, '0', '0', '0', '0', '0', '1', NONE, '0', '0', '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, IMM, CONST_DSX, RBC, NONE, '0', '0', '0', '0', ZERO, '0', is8B, '0', '0', '0', '0', '0', '1', NONE, '0', '1', '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_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_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), 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 if (icode = INSN_stq or icode = INSN_stqcx) and f_in.big_endian = '0' then
vr.reg_3_addr(0) := '1'; vr.reg_3_addr(0) := '1';
end if; 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_1_enable := f_in.valid;
vr.read_2_enable := f_in.valid and maybe_rb; vr.read_2_enable := f_in.valid and maybe_rb;
vr.read_3_enable := f_in.valid; vr.read_3_enable := f_in.valid;

@ -140,8 +140,6 @@ architecture behaviour of decode2 is
ret := x"00000000000000" & "00" & insn_in(1) & insn_in(15 downto 11); ret := x"00000000000000" & "00" & insn_in(1) & insn_in(15 downto 11);
when CONST_SH32 => when CONST_SH32 =>
ret := x"00000000000000" & "000" & insn_in(15 downto 11); 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 => when others =>
ret := (others => '0'); ret := (others => '0');
end case; end case;
@ -188,8 +186,6 @@ architecture behaviour of decode2 is
else else
return ('0', (others => '0')); return ('0', (others => '0'));
end if; end if;
when RBC =>
return ('1', gpr_to_gspr(insn_rb(insn_in)));
when NONE => when NONE =>
return ('0', (others => '0')); return ('0', (others => '0'));
end case; end case;

@ -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_a_t is (NONE, RA, RA_OR_ZERO, RA0_OR_CIA, CIA, FRA);
type input_reg_b_t is (IMM, RB, FRB); 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, 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_DXHI4, CONST_DS, CONST_DQ, CONST_M1, CONST_SH, CONST_SH32, CONST_PSI);
CONST_DSX); type input_reg_c_t is (NONE, RS, RCR, FRC, FRS);
type input_reg_c_t is (NONE, RS, RCR, RBC, FRC, FRS);
type output_reg_a_t is (NONE, RT, RA, FRT); type output_reg_a_t is (NONE, RT, RA, FRT);
type rc_t is (NONE, ONE, RC, RCOE); type rc_t is (NONE, ONE, RC, RCOE);
type carry_in_t is (ZERO, CA, OV, ONE); type carry_in_t is (ZERO, CA, OV, ONE);

@ -108,6 +108,7 @@ architecture behave of loadstore1 is
two_dwords : std_ulogic; two_dwords : std_ulogic;
incomplete : std_ulogic; incomplete : std_ulogic;
ea_valid : std_ulogic; ea_valid : std_ulogic;
hash_addr : std_ulogic_vector(63 downto 0);
end record; end record;
constant request_init : request_t := (addr => (others => '0'), constant request_init : request_t := (addr => (others => '0'),
byte_sel => x"00", second_bytes => x"00", byte_sel => x"00", second_bytes => x"00",
@ -116,6 +117,7 @@ architecture behave of loadstore1 is
elt_length => x"0", brev_mask => "000", elt_length => x"0", brev_mask => "000",
xerc => xerc_init, xerc => xerc_init,
sprsel => "0000", ric => "00", sprsel => "0000", ric => "00",
hash_addr => 64x"0",
others => '0'); others => '0');


type reg_stage1_t is record type reg_stage1_t is record
@ -529,7 +531,7 @@ begin
-- start a new hash process -- start a new hash process
hv.z0 := 31x"7D12B0E6"; -- 0xFA2561CD >> 1 hv.z0 := 31x"7D12B0E6"; -- 0xFA2561CD >> 1
ra := l_in.addr1; ra := l_in.addr1;
rb := l_in.data; rb := l_in.addr2;
key := l_in.hashkey; key := l_in.hashkey;
for lane in 0 to 3 loop for lane in 0 to 3 loop
j := lane * 16; j := lane * 16;
@ -566,6 +568,7 @@ begin
variable misaligned : std_ulogic; variable misaligned : std_ulogic;
variable addr_mask : std_ulogic_vector(2 downto 0); variable addr_mask : std_ulogic_vector(2 downto 0);
variable hash_nop : std_ulogic; variable hash_nop : std_ulogic;
variable disp : std_ulogic_vector(63 downto 0);
begin begin
v := request_init; v := request_init;
sprn := l_in.insn(15 downto 11) & l_in.insn(20 downto 16); sprn := l_in.insn(15 downto 11) & l_in.insn(20 downto 16);
@ -598,6 +601,9 @@ begin
v.sprsel := "100" & sprn(8); v.sprsel := "100" & sprn(8);
end if; 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)); lsu_sum := std_ulogic_vector(unsigned(l_in.addr1) + unsigned(l_in.addr2));


if HAS_FPU and l_in.is_32bit = '1' then 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) & addr := std_ulogic_vector(unsigned(r1.addr0(63 downto 3)) + not l_in.update) &
r1.addr0(2 downto 0); r1.addr0(2 downto 0);
end if; 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 if l_in.mode_32bit = '1' then
addr(63 downto 32) := (others => '0'); addr(63 downto 32) := (others => '0');
v.hash_addr(63 downto 32) := (others => '0');
end if; end if;
v.addr := addr; v.addr := addr;
v.ea_valid := l_in.valid; v.ea_valid := l_in.valid;
@ -812,6 +823,9 @@ begin
-- need to initiate and then wait for the hash computation -- need to initiate and then wait for the hash computation
hash_start <= not r1.busy; hash_start <= not r1.busy;
v.busy := not hash_r.done; 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 if hash_r.done = '0' then
issue := '0'; issue := '0';
else else

Loading…
Cancel
Save