Skip to content

Commit e4e1a03

Browse files
authored
Merge pull request #437 from paulusmack/compliance
Implement fixed-point hash instructions
2 parents e9b57ca + 8f537c1 commit e4e1a03

14 files changed

+1329
-415
lines changed

common.vhdl

+6-2
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ package common is
6969
constant SPR_DAWR1 : spr_num_t := 181;
7070
constant SPR_DAWRX0 : spr_num_t := 188;
7171
constant SPR_DAWRX1 : spr_num_t := 189;
72+
constant SPR_HASHKEYR : spr_num_t := 468;
73+
constant SPR_HASHPKEYR : spr_num_t := 469;
7274

7375
-- PMU registers
7476
constant SPR_UPMC1 : spr_num_t := 771;
@@ -433,6 +435,7 @@ package common is
433435
ramspr_32bit : std_ulogic;
434436
dbg_spr_access : std_ulogic;
435437
dec_ctr : std_ulogic;
438+
privileged : std_ulogic;
436439
prefixed : std_ulogic;
437440
prefix : std_ulogic_vector(25 downto 0);
438441
illegal_suffix : std_ulogic;
@@ -465,7 +468,7 @@ package common is
465468
ramspr_32bit => '0',
466469
dbg_spr_access => '0',
467470
dec_ctr => '0',
468-
prefixed => '0', prefix => (others => '0'), illegal_suffix => '0',
471+
privileged => '0', prefixed => '0', prefix => (others => '0'), illegal_suffix => '0',
469472
misaligned_prefix => '0', illegal_form => '0', uses_tar => '0', uses_dscr => '0',
470473
right_shift => '0', rot_clear_left => '0', rot_clear_right => '0', rot_sign_ext => '0',
471474
do_popcnt => '0',
@@ -585,6 +588,7 @@ package common is
585588
byte_reverse : std_ulogic;
586589
sign_extend : std_ulogic; -- do we need to sign extend?
587590
update : std_ulogic; -- is this an update instruction?
591+
hash : std_ulogic;
588592
xerc : xer_common_t;
589593
reserve : std_ulogic; -- set for larx/stcx.
590594
rc : std_ulogic; -- set for stcx.
@@ -600,7 +604,7 @@ package common is
600604
end record;
601605
constant Execute1ToLoadstore1Init : Execute1ToLoadstore1Type :=
602606
(valid => '0', op => OP_ILLEGAL, ci => '0', byte_reverse => '0',
603-
sign_extend => '0', update => '0', xerc => xerc_init,
607+
sign_extend => '0', update => '0', hash => '0', xerc => xerc_init,
604608
reserve => '0', rc => '0', virt_mode => '0', priv_mode => '0',
605609
insn => (others => '0'),
606610
instr_tag => instr_tag_init,

decode1.vhdl

+328-318
Large diffs are not rendered by default.

decode2.vhdl

+12-2
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ architecture behaviour of decode2 is
138138
ret := ('0', (others => '0'), x"00000000000000" & "00" & insn_in(1) & insn_in(15 downto 11));
139139
when CONST_SH32 =>
140140
ret := ('0', (others => '0'), x"00000000000000" & "000" & insn_in(15 downto 11));
141+
when DSX =>
142+
ret := ('0', (others => '0'), 55x"7FFFFFFFFFFFFF" & insn_in(0) & insn_in(25 downto 21) & "000");
141143
when NONE =>
142144
ret := ('0', (others => '0'), (others => '0'));
143145
end case;
@@ -165,6 +167,8 @@ architecture behaviour of decode2 is
165167
else
166168
return ('0', (others => '0'), (others => '0'));
167169
end if;
170+
when RBC =>
171+
return ('1', gpr_to_gspr(insn_rb(insn_in)), (others => '0'));
168172
when NONE =>
169173
return ('0', (others => '0'), (others => '0'));
170174
end case;
@@ -495,7 +499,8 @@ begin
495499
when SPR_XER =>
496500
v.input_ov := '1';
497501
when SPR_DAR | SPR_DSISR | SPR_PID | SPR_PTCR |
498-
SPR_DAWR0 | SPR_DAWR1 | SPR_DAWRX0 | SPR_DAWRX1 =>
502+
SPR_DAWR0 | SPR_DAWR1 | SPR_DAWRX0 | SPR_DAWRX1 |
503+
SPR_HASHKEYR | SPR_HASHPKEYR =>
499504
unit := LDST;
500505
when SPR_TAR =>
501506
v.e.uses_tar := '1';
@@ -518,7 +523,8 @@ begin
518523
v.e.output_xer := '1';
519524
v.output_ov := '1';
520525
when SPR_DAR | SPR_DSISR | SPR_PID | SPR_PTCR |
521-
SPR_DAWR0 | SPR_DAWR1 | SPR_DAWRX0 | SPR_DAWRX1 =>
526+
SPR_DAWR0 | SPR_DAWR1 | SPR_DAWRX0 | SPR_DAWRX1 |
527+
SPR_HASHKEYR | SPR_HASHPKEYR =>
522528
unit := LDST;
523529
if d_in.valid = '1' then
524530
v.sgl_pipe := '1';
@@ -668,6 +674,10 @@ begin
668674
v.e.result_sel := "001"; -- logical_result
669675
end if;
670676
end if;
677+
v.e.privileged := d_in.decode.privileged;
678+
if (op = OP_MFSPR or op = OP_MTSPR) and d_in.insn(20) = '1' then
679+
v.e.privileged := '1';
680+
end if;
671681
v.e.prefixed := d_in.prefixed;
672682
v.e.prefix := d_in.prefix;
673683
v.e.illegal_suffix := d_in.illegal_suffix;

decode_types.vhdl

+30-20
Original file line numberDiff line numberDiff line change
@@ -205,89 +205,92 @@ package decode_types is
205205
INSN_divwe,
206206
INSN_divweu,
207207
INSN_eqv,
208-
INSN_icbi,
208+
INSN_hashchk,
209+
INSN_hashchkp,
210+
INSN_hashst,
211+
INSN_hashstp,
212+
INSN_icbi, -- 160
209213
INSN_icbt,
210214
INSN_isel,
211215
INSN_lbarx,
212-
INSN_lbzcix, -- 160
216+
INSN_lbzcix,
213217
INSN_lbzux,
214218
INSN_lbzx,
215219
INSN_ldarx,
216220
INSN_ldbrx,
217221
INSN_ldcix,
218-
INSN_ldx,
222+
INSN_ldx, -- 170
219223
INSN_ldux,
220224
INSN_lharx,
221225
INSN_lhax,
222-
INSN_lhaux, -- 170
226+
INSN_lhaux,
223227
INSN_lhbrx,
224228
INSN_lhzcix,
225229
INSN_lhzx,
226230
INSN_lhzux,
227231
INSN_lqarx,
228-
INSN_lwarx,
232+
INSN_lwarx, -- 180
229233
INSN_lwax,
230234
INSN_lwaux,
231235
INSN_lwbrx,
232-
INSN_lwzcix, -- 180
236+
INSN_lwzcix,
233237
INSN_lwzx,
234238
INSN_lwzux,
235239
INSN_modsd,
236240
INSN_modsw,
237241
INSN_moduw,
238-
INSN_modud,
242+
INSN_modud, -- 190
239243
INSN_mulhw,
240244
INSN_mulhwu,
241245
INSN_mulhd,
242-
INSN_mulhdu, -- 190
246+
INSN_mulhdu,
243247
INSN_mullw,
244248
INSN_mulld,
245249
INSN_nand,
246250
INSN_nor,
247251
INSN_or,
248-
INSN_orc,
252+
INSN_orc, -- 200
249253
INSN_pdepd,
250254
INSN_pextd,
251255
INSN_rldcl,
252-
INSN_rldcr, -- 200
256+
INSN_rldcr,
253257
INSN_rlwnm,
254258
INSN_slw,
255259
INSN_sld,
256260
INSN_sraw,
257261
INSN_srad,
258-
INSN_srw,
262+
INSN_srw, -- 210
259263
INSN_srd,
260264
INSN_stbcix,
261265
INSN_stbcx,
262-
INSN_stbx, -- 210
266+
INSN_stbx,
263267
INSN_stbux,
264268
INSN_stdbrx,
265269
INSN_stdcix,
266270
INSN_stdcx,
267271
INSN_stdx,
268-
INSN_stdux,
272+
INSN_stdux, -- 220
269273
INSN_sthbrx,
270274
INSN_sthcix,
271275
INSN_sthcx,
272-
INSN_sthx, -- 220
276+
INSN_sthx,
273277
INSN_sthux,
274278
INSN_stqcx,
275279
INSN_stwbrx,
276280
INSN_stwcix,
277281
INSN_stwcx,
278-
INSN_stwx,
282+
INSN_stwx, -- 230
279283
INSN_stwux,
280284
INSN_subf,
281285
INSN_subfc,
282-
INSN_subfe, -- 230
286+
INSN_subfe,
283287
INSN_td,
284288
INSN_tlbie,
285289
INSN_tlbiel,
286290
INSN_tw,
287291
INSN_xor,
288292

289293
-- pad to 240 to simplify comparison logic
290-
INSN_236, INSN_237, INSN_238, INSN_239,
291294

292295
-- The following instructions have a third input addressed by RC
293296
INSN_maddld,
@@ -416,8 +419,9 @@ package decode_types is
416419

417420
type input_reg_a_t is (NONE, RA, RA_OR_ZERO, RA0_OR_CIA, CIA, FRA);
418421
type input_reg_b_t is (NONE, RB, CONST_UI, CONST_SI, CONST_SI_HI, CONST_UI_HI, CONST_LI, CONST_BD,
419-
CONST_DXHI4, CONST_DS, CONST_DQ, CONST_M1, CONST_SH, CONST_SH32, CONST_PSI, FRB);
420-
type input_reg_c_t is (NONE, RS, RCR, FRC, FRS);
422+
CONST_DXHI4, CONST_DS, CONST_DQ, CONST_M1, CONST_SH, CONST_SH32, CONST_PSI,
423+
DSX, FRB);
424+
type input_reg_c_t is (NONE, RS, RCR, RBC, FRC, FRS);
421425
type output_reg_a_t is (NONE, RT, RA, FRT);
422426
type rc_t is (NONE, ONE, RC, RCOE);
423427
type carry_in_t is (ZERO, CA, OV, ONE);
@@ -480,6 +484,7 @@ package decode_types is
480484
rc : rc_t;
481485
lr : std_ulogic;
482486

487+
privileged : std_ulogic;
483488
sgl_pipe : std_ulogic;
484489
repeat : repeat_t;
485490
end record;
@@ -490,7 +495,8 @@ package decode_types is
490495
invert_a => '0', invert_out => '0', input_carry => ZERO, output_carry => '0',
491496
length => NONE, byte_reverse => '0', sign_extend => '0',
492497
update => '0', reserve => '0', is_32bit => '0',
493-
is_signed => '0', rc => NONE, lr => '0', sgl_pipe => '0', repeat => NONE);
498+
is_signed => '0', rc => NONE, lr => '0',
499+
privileged => '0', sgl_pipe => '0', repeat => NONE);
494500

495501
-- This function maps from insn_code values to primary opcode.
496502
-- With this, we don't have to store the primary opcode of each instruction
@@ -634,6 +640,10 @@ package body decode_types is
634640
when INSN_divwu => return "011111";
635641
when INSN_divd => return "011111";
636642
when INSN_divw => return "011111";
643+
when INSN_hashchk => return "011111";
644+
when INSN_hashchkp => return "011111";
645+
when INSN_hashst => return "011111";
646+
when INSN_hashstp => return "011111";
637647
when INSN_eieio => return "011111";
638648
when INSN_eqv => return "011111";
639649
when INSN_extsb => return "011111";

execute1.vhdl

+4-14
Original file line numberDiff line numberDiff line change
@@ -290,18 +290,6 @@ architecture behaviour of execute1 is
290290
others => USER
291291
);
292292

293-
function instr_is_privileged(op: insn_type_t; insn: std_ulogic_vector(31 downto 0))
294-
return boolean is
295-
begin
296-
if op_privilege(op) = SUPER then
297-
return true;
298-
elsif op = OP_MFSPR or op = OP_MTSPR then
299-
return insn(20) = '1';
300-
else
301-
return false;
302-
end if;
303-
end;
304-
305293
procedure set_carry(e: inout Execute1ToWritebackType;
306294
carry32 : in std_ulogic;
307295
carry : in std_ulogic) is
@@ -1162,8 +1150,8 @@ begin
11621150

11631151
if e_in.illegal_suffix = '1' or e_in.illegal_form = '1' then
11641152
illegal := '1';
1165-
elsif ex1.msr(MSR_PR) = '1' and instr_is_privileged(e_in.insn_type, e_in.insn) then
1166-
privileged := '1';
1153+
elsif ex1.msr(MSR_PR) = '1' then
1154+
privileged := e_in.privileged;
11671155
end if;
11681156

11691157
v.do_trace := ex1.msr(MSR_SE);
@@ -1844,6 +1832,8 @@ begin
18441832
lv.byte_reverse := e_in.byte_reverse xnor ex1.msr(MSR_LE);
18451833
lv.sign_extend := e_in.sign_extend;
18461834
lv.update := e_in.update;
1835+
-- abuse e_in.is_signed to indicate hash store/check instructions
1836+
lv.hash := e_in.is_signed;
18471837
lv.xerc := xerc_in;
18481838
lv.reserve := e_in.reserve;
18491839
lv.rc := e_in.rc;

0 commit comments

Comments
 (0)