From ca872faeded461e2547ffea550800e62d3251302 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 3 Jun 2025 19:36:12 +1000 Subject: [PATCH 1/2] core: Consolidate several OP_* values into a single OP_COMPUTE This replaces OP_ADDG6S, OP_BCD, OP_BREV, OP_CMPB, OP_CMPEQB, OP_CMPRB, OP_CROP, OP_EXTS, OP_EXTSWSLI, OP_ISEL, OP_LOGIC, OP_MFCR, OP_PRTY, OP_RLC, OP_RLCL, OP_RLCR, OP_SETB, OP_SHL, OP_SHR, and OP_XOR with a single OP_COMPUTE. The replaced operations are all ones which just compute a result value (for GPR or CR) in execute1, don't have any other side effects, and aren't used in decode2 to determine other signals. The operation to be performed is sufficiently defined by the result and subresult fields in the decode table. With the elimination of OP_SPARE, this reduces the number of insn_type_t values to 44. Signed-off-by: Paul Mackerras --- decode1.vhdl | 118 +++++++++++++++++++------------------- decode2.vhdl | 8 +-- decode_types.vhdl | 21 +++---- execute1.vhdl | 55 ++++++++++-------- logical.vhdl | 29 ++++------ scripts/fmt_log/fmt_log.c | 16 +++--- 6 files changed, 120 insertions(+), 127 deletions(-) diff --git a/decode1.vhdl b/decode1.vhdl index a4beb84..e18350f 100644 --- a/decode1.vhdl +++ b/decode1.vhdl @@ -82,7 +82,7 @@ architecture behaviour of decode1 is INSN_addc => (ALU, NONE, OP_ADD, RA, RB, NONE, NONE, RT, ADD, "000", '0', '0', '0', '0', ZERO, '1', NONE, '0', '0', '0', '0', '0', '0', RCOE, '0', '0', '0', NONE), INSN_adde => (ALU, NONE, OP_ADD, RA, RB, NONE, NONE, RT, ADD, "000", '0', '0', '0', '0', CA, '1', NONE, '0', '0', '0', '0', '0', '0', RCOE, '0', '0', '0', NONE), INSN_addex => (ALU, NONE, OP_ADD, RA, RB, NONE, NONE, RT, ADD, "000", '0', '0', '0', '0', OV, '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), - INSN_addg6s => (ALU, NONE, OP_ADDG6S, RA, RB, NONE, NONE, RT, MSC, "001", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), + INSN_addg6s => (ALU, NONE, OP_COMPUTE, RA, RB, NONE, NONE, RT, MSC, "001", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), INSN_addi => (ALU, NONE, OP_ADD, RA_OR_ZERO, IMM, CONST_SI, NONE, RT, ADD, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), INSN_addic => (ALU, NONE, OP_ADD, RA, IMM, CONST_SI, NONE, RT, ADD, "000", '0', '0', '0', '0', ZERO, '1', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), INSN_addic_dot => (ALU, NONE, OP_ADD, RA, IMM, CONST_SI, NONE, RT, ADD, "000", '0', '0', '0', '0', ZERO, '1', NONE, '0', '0', '0', '0', '0', '0', ONE, '0', '0', '0', NONE), @@ -90,10 +90,10 @@ architecture behaviour of decode1 is INSN_addme => (ALU, NONE, OP_ADD, RA, IMM, CONST_M1, NONE, RT, ADD, "000", '0', '0', '0', '0', CA, '1', NONE, '0', '0', '0', '0', '0', '0', RCOE, '0', '0', '0', NONE), INSN_addpcis => (ALU, NONE, OP_ADD, CIA, IMM, CONST_DXHI4, NONE, RT, ADD, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), INSN_addze => (ALU, NONE, OP_ADD, RA, IMM, NONE, NONE, RT, ADD, "000", '0', '0', '0', '0', CA, '1', NONE, '0', '0', '0', '0', '0', '0', RCOE, '0', '0', '0', NONE), - INSN_and => (ALU, NONE, OP_LOGIC, NONE, RB, NONE, RS, RA, LOG, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), - INSN_andc => (ALU, NONE, OP_LOGIC, NONE, RB, NONE, RS, RA, LOG, "000", '0', '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), - INSN_andi_dot => (ALU, NONE, OP_LOGIC, NONE, IMM, CONST_UI, RS, RA, LOG, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', ONE, '0', '0', '0', NONE), - INSN_andis_dot => (ALU, NONE, OP_LOGIC, NONE, IMM, CONST_UI_HI, RS, RA, LOG, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', ONE, '0', '0', '0', NONE), + INSN_and => (ALU, NONE, OP_COMPUTE, NONE, RB, NONE, RS, RA, LOG, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), + INSN_andc => (ALU, NONE, OP_COMPUTE, NONE, RB, NONE, RS, RA, LOG, "000", '0', '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), + INSN_andi_dot => (ALU, NONE, OP_COMPUTE, NONE, IMM, CONST_UI, RS, RA, LOG, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', ONE, '0', '0', '0', NONE), + INSN_andis_dot => (ALU, NONE, OP_COMPUTE, NONE, IMM, CONST_UI_HI, RS, RA, LOG, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', ONE, '0', '0', '0', NONE), INSN_attn => (ALU, NONE, OP_ATTN, NONE, IMM, NONE, NONE, NONE, ADD, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1', '1', NONE), INSN_brel => (ALU, NONE, OP_B, CIA, IMM, CONST_LI, NONE, NONE, ADD, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '0', '0', NONE), INSN_babs => (ALU, NONE, OP_B, NONE, IMM, CONST_LI, NONE, NONE, ADD, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '0', '0', NONE), @@ -103,31 +103,31 @@ architecture behaviour of decode1 is INSN_bclr => (ALU, NONE, OP_BCREG, NONE, IMM, NONE, NONE, NONE, SPR, "000", '1', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '0', '0', NONE), INSN_bctar => (ALU, NONE, OP_BCREG, NONE, IMM, NONE, NONE, NONE, SPR, "000", '1', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '0', '0', NONE), INSN_bperm => (ALU, NONE, OP_BPERM, NONE, RB, NONE, RS, RA, ADD, "100", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), - INSN_brh => (ALU, NONE, OP_BREV, NONE, IMM, NONE, RS, RA, LOG, "010", '0', '0', '0', '0', ZERO, '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), - INSN_brw => (ALU, NONE, OP_BREV, NONE, IMM, NONE, RS, RA, LOG, "010", '0', '0', '0', '0', ZERO, '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), - INSN_brd => (ALU, NONE, OP_BREV, NONE, IMM, NONE, RS, RA, LOG, "010", '0', '0', '0', '0', ZERO, '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), - INSN_cbcdtd => (ALU, NONE, OP_BCD, NONE, IMM, NONE, RS, RA, LOG, "101", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), - INSN_cdtbcd => (ALU, NONE, OP_BCD, NONE, IMM, NONE, RS, RA, LOG, "101", '0', '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), + INSN_brh => (ALU, NONE, OP_COMPUTE, NONE, IMM, NONE, RS, RA, LOG, "010", '0', '0', '0', '0', ZERO, '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), + INSN_brw => (ALU, NONE, OP_COMPUTE, NONE, IMM, NONE, RS, RA, LOG, "010", '0', '0', '0', '0', ZERO, '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), + INSN_brd => (ALU, NONE, OP_COMPUTE, NONE, IMM, NONE, RS, RA, LOG, "010", '0', '0', '0', '0', ZERO, '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), + INSN_cbcdtd => (ALU, NONE, OP_COMPUTE, NONE, IMM, NONE, RS, RA, LOG, "101", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), + INSN_cdtbcd => (ALU, NONE, OP_COMPUTE, NONE, IMM, NONE, RS, RA, LOG, "110", '0', '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), INSN_cfuged => (ALU, NONE, OP_BSORT, NONE, RB, NONE, RS, RA, ADD, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), INSN_cmp => (ALU, NONE, OP_CMP, RA, RB, NONE, NONE, NONE, ADD, "000", '0', '1', '1', '0', ONE, '0', NONE, '0', '0', '0', '0', '0', '1', NONE, '0', '0', '0', NONE), - INSN_cmpb => (ALU, NONE, OP_CMPB, NONE, RB, NONE, RS, RA, LOG, "100", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), - INSN_cmpeqb => (ALU, NONE, OP_CMPEQB, RA, RB, NONE, NONE, NONE, ADD, "010", '0', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), + INSN_cmpb => (ALU, NONE, OP_COMPUTE, NONE, RB, NONE, RS, RA, LOG, "100", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), + INSN_cmpeqb => (ALU, NONE, OP_COMPUTE, RA, RB, NONE, NONE, NONE, ADD, "010", '0', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), INSN_cmpi => (ALU, NONE, OP_CMP, RA, IMM, CONST_SI, NONE, NONE, ADD, "000", '0', '1', '1', '0', ONE, '0', NONE, '0', '0', '0', '0', '0', '1', NONE, '0', '0', '0', NONE), INSN_cmpl => (ALU, NONE, OP_CMP, RA, RB, NONE, NONE, NONE, ADD, "000", '0', '1', '1', '0', ONE, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), INSN_cmpli => (ALU, NONE, OP_CMP, RA, IMM, CONST_UI, NONE, NONE, ADD, "000", '0', '1', '1', '0', ONE, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), - INSN_cmprb => (ALU, NONE, OP_CMPRB, RA, RB, NONE, NONE, NONE, ADD, "001", '0', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), + INSN_cmprb => (ALU, NONE, OP_COMPUTE, RA, RB, NONE, NONE, NONE, ADD, "001", '0', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), INSN_cntlzd => (ALU, NONE, OP_COUNTB, NONE, IMM, NONE, RS, RA, ADD, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), INSN_cntlzw => (ALU, NONE, OP_COUNTB, NONE, IMM, NONE, RS, RA, ADD, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '0', '0', NONE), INSN_cnttzd => (ALU, NONE, OP_COUNTB, NONE, IMM, NONE, RS, RA, ADD, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), INSN_cnttzw => (ALU, NONE, OP_COUNTB, NONE, IMM, NONE, RS, RA, ADD, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '0', '0', NONE), - INSN_crand => (ALU, NONE, OP_CROP, NONE, IMM, NONE, NONE, NONE, ADD, "011", '1', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), - INSN_crandc => (ALU, NONE, OP_CROP, NONE, IMM, NONE, NONE, NONE, ADD, "011", '1', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), - INSN_creqv => (ALU, NONE, OP_CROP, NONE, IMM, NONE, NONE, NONE, ADD, "011", '1', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), - INSN_crnand => (ALU, NONE, OP_CROP, NONE, IMM, NONE, NONE, NONE, ADD, "011", '1', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), - INSN_crnor => (ALU, NONE, OP_CROP, NONE, IMM, NONE, NONE, NONE, ADD, "011", '1', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), - INSN_cror => (ALU, NONE, OP_CROP, NONE, IMM, NONE, NONE, NONE, ADD, "011", '1', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), - INSN_crorc => (ALU, NONE, OP_CROP, NONE, IMM, NONE, NONE, NONE, ADD, "011", '1', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), - INSN_crxor => (ALU, NONE, OP_CROP, NONE, IMM, NONE, NONE, NONE, ADD, "011", '1', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), + INSN_crand => (ALU, NONE, OP_COMPUTE, NONE, IMM, NONE, NONE, NONE, ADD, "011", '1', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), + INSN_crandc => (ALU, NONE, OP_COMPUTE, NONE, IMM, NONE, NONE, NONE, ADD, "011", '1', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), + INSN_creqv => (ALU, NONE, OP_COMPUTE, NONE, IMM, NONE, NONE, NONE, ADD, "011", '1', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), + INSN_crnand => (ALU, NONE, OP_COMPUTE, NONE, IMM, NONE, NONE, NONE, ADD, "011", '1', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), + INSN_crnor => (ALU, NONE, OP_COMPUTE, NONE, IMM, NONE, NONE, NONE, ADD, "011", '1', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), + INSN_cror => (ALU, NONE, OP_COMPUTE, NONE, IMM, NONE, NONE, NONE, ADD, "011", '1', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), + INSN_crorc => (ALU, NONE, OP_COMPUTE, NONE, IMM, NONE, NONE, NONE, ADD, "011", '1', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), + INSN_crxor => (ALU, NONE, OP_COMPUTE, NONE, IMM, NONE, NONE, NONE, ADD, "011", '1', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), INSN_darn => (ALU, NONE, OP_DARN, NONE, IMM, NONE, NONE, RT, MSC, "011", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), INSN_dcbf => (LDST, NONE, OP_DCBF, RA_OR_ZERO, RB, NONE, NONE, NONE, ADD, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), INSN_dcbst => (ALU, NONE, OP_DCBST, NONE, IMM, NONE, NONE, NONE, ADD, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), @@ -143,11 +143,11 @@ architecture behaviour of decode1 is INSN_divweu => (DVU, NONE, OP_DIVE, RA, RB, NONE, NONE, RT, ADD, "101", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', RCOE, '0', '0', '0', NONE), INSN_divwu => (DVU, NONE, OP_DIV, RA, RB, NONE, NONE, RT, ADD, "101", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', RCOE, '0', '0', '0', NONE), INSN_eieio => (ALU, NONE, OP_NOP, NONE, IMM, NONE, NONE, NONE, ADD, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), - INSN_eqv => (ALU, NONE, OP_XOR, NONE, RB, NONE, RS, RA, LOG, "001", '0', '0', '0', '1', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), - INSN_extsb => (ALU, NONE, OP_EXTS, NONE, IMM, NONE, RS, RA, LOG, "110", '0', '0', '0', '0', ZERO, '0', is1B, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), - INSN_extsh => (ALU, NONE, OP_EXTS, NONE, IMM, NONE, RS, RA, LOG, "110", '0', '0', '0', '0', ZERO, '0', is2B, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), - INSN_extsw => (ALU, NONE, OP_EXTS, NONE, IMM, NONE, RS, RA, LOG, "110", '0', '0', '0', '0', ZERO, '0', is4B, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), - INSN_extswsli => (ALU, NONE, OP_EXTSWSLI, NONE, IMM, CONST_SH, RS, RA, ROT, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), + INSN_eqv => (ALU, NONE, OP_COMPUTE, NONE, RB, NONE, RS, RA, LOG, "001", '0', '0', '0', '1', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), + INSN_extsb => (ALU, NONE, OP_COMPUTE, NONE, IMM, NONE, RS, RA, LOG, "111", '0', '0', '0', '0', ZERO, '0', is1B, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), + INSN_extsh => (ALU, NONE, OP_COMPUTE, NONE, IMM, NONE, RS, RA, LOG, "111", '0', '0', '0', '0', ZERO, '0', is2B, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), + INSN_extsw => (ALU, NONE, OP_COMPUTE, NONE, IMM, NONE, RS, RA, LOG, "111", '0', '0', '0', '0', ZERO, '0', is4B, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), + INSN_extswsli => (ALU, NONE, OP_COMPUTE, NONE, IMM, CONST_SH, RS, RA, ROT, "010", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), INSN_fabs => (FPU, FPU, OP_FP_MOVE, NONE, FRB, NONE, NONE, FRT, ADD, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), INSN_fadd => (FPU, FPU, OP_FP_ARITH, FRA, FRB, NONE, NONE, FRT, ADD, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), INSN_fadds => (FPU, FPU, OP_FP_ARITH, FRA, FRB, NONE, NONE, FRT, ADD, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '0', '0', NONE), @@ -205,7 +205,7 @@ architecture behaviour of decode1 is INSN_hashstp => (LDST, NONE, OP_STORE, RA, RB, NONE, NONE, NONE, ADD, "000", '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, ADD, "000", '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, ADD, "000", '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, MSC, "010", '1', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), + INSN_isel => (ALU, NONE, OP_COMPUTE, RA_OR_ZERO, RB, NONE, NONE, RT, MSC, "010", '1', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), INSN_isync => (ALU, NONE, OP_ISYNC, NONE, IMM, NONE, NONE, NONE, ADD, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), INSN_lbarx => (LDST, NONE, OP_LOAD, RA_OR_ZERO, RB, NONE, NONE, RT, ADD, "000", '0', '0', '0', '0', ZERO, '0', is1B, '0', '0', '0', '1', '0', '0', NONE, '0', '0', '0', NONE), INSN_lbz => (LDST, NONE, OP_LOAD, RA_OR_ZERO, IMM, CONST_SI, NONE, RT, ADD, "000", '0', '0', '0', '0', ZERO, '0', is1B, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), @@ -256,10 +256,10 @@ architecture behaviour of decode1 is INSN_maddhd => (ALU, NONE, OP_MUL_H64, RA, RB, NONE, RCR, RT, ADD, "010", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '1', NONE, '0', '0', '0', NONE), INSN_maddhdu => (ALU, NONE, OP_MUL_H64, RA, RB, NONE, RCR, RT, ADD, "010", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), INSN_maddld => (ALU, NONE, OP_MUL_L64, RA, RB, NONE, RCR, RT, ADD, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '1', NONE, '0', '0', '0', NONE), - INSN_mcrf => (ALU, NONE, OP_CROP, NONE, IMM, NONE, NONE, NONE, ADD, "011", '1', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), + INSN_mcrf => (ALU, NONE, OP_COMPUTE, NONE, IMM, NONE, NONE, NONE, ADD, "100", '1', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), INSN_mcrfs => (FPU, FPU, OP_FP_CMP, NONE, IMM, NONE, NONE, NONE, ADD, "000", '0', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), - INSN_mcrxrx => (ALU, NONE, OP_MCRXRX, NONE, IMM, NONE, NONE, NONE, ADD, "100", '0', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), - INSN_mfcr => (ALU, NONE, OP_MFCR, NONE, IMM, NONE, NONE, RT, MSC, "101", '1', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), + INSN_mcrxrx => (ALU, NONE, OP_MCRXRX, NONE, IMM, NONE, NONE, NONE, ADD, "101", '0', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), + INSN_mfcr => (ALU, NONE, OP_COMPUTE, NONE, IMM, NONE, NONE, RT, MSC, "101", '1', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), INSN_mffs => (FPU, FPU, OP_FP_MISC, NONE, FRB, NONE, NONE, FRT, ADD, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), INSN_mfmsr => (ALU, NONE, OP_MFMSR, NONE, IMM, NONE, NONE, RT, MSC, "100", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1', '1', NONE), INSN_mfspr => (ALU, NONE, OP_MFSPR, NONE, IMM, NONE, RS, RT, SPR, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), @@ -281,14 +281,14 @@ architecture behaviour of decode1 is INSN_mulld => (ALU, NONE, OP_MUL_L64, RA, RB, NONE, NONE, RT, ADD, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '1', RCOE, '0', '0', '0', NONE), INSN_mulli => (ALU, NONE, OP_MUL_L64, RA, IMM, CONST_SI, NONE, RT, ADD, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '1', NONE, '0', '0', '0', NONE), INSN_mullw => (ALU, NONE, OP_MUL_L64, RA, RB, NONE, NONE, RT, ADD, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '1', RCOE, '0', '0', '0', NONE), - INSN_nand => (ALU, NONE, OP_LOGIC, NONE, RB, NONE, RS, RA, LOG, "000", '0', '0', '0', '1', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), + INSN_nand => (ALU, NONE, OP_COMPUTE, NONE, RB, NONE, RS, RA, LOG, "000", '0', '0', '0', '1', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), INSN_neg => (ALU, NONE, OP_ADD, RA, IMM, NONE, NONE, RT, ADD, "000", '0', '0', '1', '0', ONE, '0', NONE, '0', '0', '0', '0', '0', '0', RCOE, '0', '0', '0', NONE), INSN_nop => (ALU, NONE, OP_NOP, NONE, IMM, NONE, NONE, NONE, ADD, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), - INSN_nor => (ALU, NONE, OP_LOGIC, NONE, RB, NONE, RS, RA, LOG, "000", '0', '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '0', '0', NONE), - INSN_or => (ALU, NONE, OP_LOGIC, NONE, RB, NONE, RS, RA, LOG, "000", '0', '0', '1', '1', ZERO, '0', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '0', '0', NONE), - INSN_orc => (ALU, NONE, OP_LOGIC, NONE, RB, NONE, RS, RA, LOG, "000", '0', '0', '0', '1', ZERO, '0', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '0', '0', NONE), - INSN_ori => (ALU, NONE, OP_LOGIC, NONE, IMM, CONST_UI, RS, RA, LOG, "000", '0', '0', '1', '1', ZERO, '0', NONE, '0', '0', '0', '0', '0', '1', NONE, '0', '0', '0', NONE), - INSN_oris => (ALU, NONE, OP_LOGIC, NONE, IMM, CONST_UI_HI, RS, RA, LOG, "000", '0', '0', '1', '1', ZERO, '0', NONE, '0', '0', '0', '0', '0', '1', NONE, '0', '0', '0', NONE), + INSN_nor => (ALU, NONE, OP_COMPUTE, NONE, RB, NONE, RS, RA, LOG, "000", '0', '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '0', '0', NONE), + INSN_or => (ALU, NONE, OP_COMPUTE, NONE, RB, NONE, RS, RA, LOG, "000", '0', '0', '1', '1', ZERO, '0', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '0', '0', NONE), + INSN_orc => (ALU, NONE, OP_COMPUTE, NONE, RB, NONE, RS, RA, LOG, "000", '0', '0', '0', '1', ZERO, '0', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '0', '0', NONE), + INSN_ori => (ALU, NONE, OP_COMPUTE, NONE, IMM, CONST_UI, RS, RA, LOG, "000", '0', '0', '1', '1', ZERO, '0', NONE, '0', '0', '0', '0', '0', '1', NONE, '0', '0', '0', NONE), + INSN_oris => (ALU, NONE, OP_COMPUTE, NONE, IMM, CONST_UI_HI, RS, RA, LOG, "000", '0', '0', '1', '1', ZERO, '0', NONE, '0', '0', '0', '0', '0', '1', NONE, '0', '0', '0', NONE), INSN_paddi => (ALU, NONE, OP_ADD, RA0_OR_CIA, IMM, CONST_PSI, NONE, RT, ADD, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), INSN_pdepd => (ALU, NONE, OP_BSORT, NONE, RB, NONE, RS, RA, ADD, "100", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), INSN_pextd => (ALU, NONE, OP_BSORT, NONE, RB, NONE, RS, RA, ADD, "100", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), @@ -312,31 +312,31 @@ architecture behaviour of decode1 is INSN_popcntb => (ALU, NONE, OP_COUNTB, NONE, IMM, NONE, RS, RA, ADD, "000", '0', '0', '0', '0', ZERO, '0', is1B, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), INSN_popcntd => (ALU, NONE, OP_COUNTB, NONE, IMM, NONE, RS, RA, ADD, "000", '0', '0', '0', '0', ZERO, '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), INSN_popcntw => (ALU, NONE, OP_COUNTB, NONE, IMM, NONE, RS, RA, ADD, "000", '0', '0', '0', '0', ZERO, '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), - INSN_prtyd => (ALU, NONE, OP_PRTY, NONE, IMM, NONE, RS, RA, LOG, "011", '0', '0', '0', '0', ZERO, '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), - INSN_prtyw => (ALU, NONE, OP_PRTY, NONE, IMM, NONE, RS, RA, LOG, "011", '0', '0', '0', '0', ZERO, '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), + INSN_prtyd => (ALU, NONE, OP_COMPUTE, NONE, IMM, NONE, RS, RA, LOG, "011", '0', '0', '0', '0', ZERO, '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), + INSN_prtyw => (ALU, NONE, OP_COMPUTE, NONE, IMM, NONE, RS, RA, LOG, "011", '0', '0', '0', '0', ZERO, '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), INSN_rfid => (ALU, NONE, OP_RFID, NONE, IMM, NONE, NONE, NONE, SPR, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1', '0', NONE), INSN_rfscv => (ALU, NONE, OP_RFID, NONE, IMM, NONE, NONE, NONE, SPR, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1', '0', NONE), - INSN_rldcl => (ALU, NONE, OP_RLCL, NONE, RB, NONE, RS, RA, ROT, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), - INSN_rldcr => (ALU, NONE, OP_RLCR, NONE, RB, NONE, RS, RA, ROT, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), - INSN_rldic => (ALU, NONE, OP_RLC, NONE, IMM, CONST_SH, RS, RA, ROT, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), - INSN_rldicl => (ALU, NONE, OP_RLCL, NONE, IMM, CONST_SH, RS, RA, ROT, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), - INSN_rldicr => (ALU, NONE, OP_RLCR, NONE, IMM, CONST_SH, RS, RA, ROT, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), - INSN_rldimi => (ALU, NONE, OP_RLC, RA, IMM, CONST_SH, RS, RA, ROT, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), - INSN_rlwimi => (ALU, NONE, OP_RLC, RA, IMM, CONST_SH32, RS, RA, ROT, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '0', '0', NONE), - INSN_rlwinm => (ALU, NONE, OP_RLC, NONE, IMM, CONST_SH32, RS, RA, ROT, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '0', '0', NONE), - INSN_rlwnm => (ALU, NONE, OP_RLC, NONE, RB, NONE, RS, RA, ROT, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '0', '0', NONE), + INSN_rldcl => (ALU, NONE, OP_COMPUTE, NONE, RB, NONE, RS, RA, ROT, "100", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), + INSN_rldcr => (ALU, NONE, OP_COMPUTE, NONE, RB, NONE, RS, RA, ROT, "001", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), + INSN_rldic => (ALU, NONE, OP_COMPUTE, NONE, IMM, CONST_SH, RS, RA, ROT, "101", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), + INSN_rldicl => (ALU, NONE, OP_COMPUTE, NONE, IMM, CONST_SH, RS, RA, ROT, "100", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), + INSN_rldicr => (ALU, NONE, OP_COMPUTE, NONE, IMM, CONST_SH, RS, RA, ROT, "001", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), + INSN_rldimi => (ALU, NONE, OP_COMPUTE, RA, IMM, CONST_SH, RS, RA, ROT, "101", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), + INSN_rlwimi => (ALU, NONE, OP_COMPUTE, RA, IMM, CONST_SH32, RS, RA, ROT, "101", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '0', '0', NONE), + INSN_rlwinm => (ALU, NONE, OP_COMPUTE, NONE, IMM, CONST_SH32, RS, RA, ROT, "101", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '0', '0', NONE), + INSN_rlwnm => (ALU, NONE, OP_COMPUTE, NONE, RB, NONE, RS, RA, ROT, "101", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '0', '0', NONE), INSN_rnop => (ALU, NONE, OP_NOP, NONE, IMM, NONE, NONE, NONE, ADD, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), INSN_sc => (ALU, NONE, OP_SC, NONE, IMM, NONE, NONE, NONE, ADD, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), - INSN_setb => (ALU, NONE, OP_SETB, NONE, IMM, NONE, NONE, RT, MSC, "110", '1', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), + INSN_setb => (ALU, NONE, OP_COMPUTE, NONE, IMM, NONE, NONE, RT, MSC, "110", '1', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), INSN_slbia => (LDST, NONE, OP_TLBIE, NONE, IMM, NONE, NONE, NONE, ADD, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1', '0', NONE), - INSN_sld => (ALU, NONE, OP_SHL, NONE, RB, NONE, RS, RA, ROT, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), - INSN_slw => (ALU, NONE, OP_SHL, NONE, RB, NONE, RS, RA, ROT, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '0', '0', NONE), - INSN_srad => (ALU, NONE, OP_SHR, NONE, RB, NONE, RS, RA, ROT, "000", '0', '0', '0', '0', ZERO, '1', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '0', '0', NONE), - INSN_sradi => (ALU, NONE, OP_SHR, NONE, IMM, CONST_SH, RS, RA, ROT, "000", '0', '0', '0', '0', ZERO, '1', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '0', '0', NONE), - INSN_sraw => (ALU, NONE, OP_SHR, NONE, RB, NONE, RS, RA, ROT, "000", '0', '0', '0', '0', ZERO, '1', NONE, '0', '0', '0', '0', '1', '1', RC, '0', '0', '0', NONE), - INSN_srawi => (ALU, NONE, OP_SHR, NONE, IMM, CONST_SH32, RS, RA, ROT, "000", '0', '0', '0', '0', ZERO, '1', NONE, '0', '0', '0', '0', '1', '1', RC, '0', '0', '0', NONE), - INSN_srd => (ALU, NONE, OP_SHR, NONE, RB, NONE, RS, RA, ROT, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), - INSN_srw => (ALU, NONE, OP_SHR, NONE, RB, NONE, RS, RA, ROT, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '0', '0', NONE), + INSN_sld => (ALU, NONE, OP_COMPUTE, NONE, RB, NONE, RS, RA, ROT, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), + INSN_slw => (ALU, NONE, OP_COMPUTE, NONE, RB, NONE, RS, RA, ROT, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '0', '0', NONE), + INSN_srad => (ALU, NONE, OP_COMPUTE, NONE, RB, NONE, RS, RA, ROT, "000", '0', '0', '1', '0', ZERO, '1', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '0', '0', NONE), + INSN_sradi => (ALU, NONE, OP_COMPUTE, NONE, IMM, CONST_SH, RS, RA, ROT, "000", '0', '0', '1', '0', ZERO, '1', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '0', '0', NONE), + INSN_sraw => (ALU, NONE, OP_COMPUTE, NONE, RB, NONE, RS, RA, ROT, "000", '0', '0', '1', '0', ZERO, '1', NONE, '0', '0', '0', '0', '1', '1', RC, '0', '0', '0', NONE), + INSN_srawi => (ALU, NONE, OP_COMPUTE, NONE, IMM, CONST_SH32, RS, RA, ROT, "000", '0', '0', '1', '0', ZERO, '1', NONE, '0', '0', '0', '0', '1', '1', RC, '0', '0', '0', NONE), + INSN_srd => (ALU, NONE, OP_COMPUTE, NONE, RB, NONE, RS, RA, ROT, "000", '0', '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), + INSN_srw => (ALU, NONE, OP_COMPUTE, NONE, RB, NONE, RS, RA, ROT, "000", '0', '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '0', '0', NONE), INSN_stb => (LDST, NONE, OP_STORE, RA_OR_ZERO, IMM, CONST_SI, RS, NONE, ADD, "000", '0', '0', '0', '0', ZERO, '0', is1B, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), INSN_stbcix => (LDST, NONE, OP_STORE, RA_OR_ZERO, RB, NONE, RS, NONE, ADD, "000", '0', '0', '1', '0', ZERO, '0', is1B, '0', '0', '0', '0', '0', '0', NONE, '0', '1', '0', NONE), INSN_stbcx => (LDST, NONE, OP_STORE, RA_OR_ZERO, RB, NONE, RS, NONE, ADD, "000", '0', '0', '0', '0', ZERO, '0', is1B, '0', '0', '0', '1', '0', '0', ONE, '0', '0', '0', NONE), @@ -390,9 +390,9 @@ architecture behaviour of decode1 is INSN_tw => (ALU, NONE, OP_TRAP, RA, RB, NONE, NONE, NONE, ADD, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', NONE, '0', '0', '0', NONE), INSN_twi => (ALU, NONE, OP_TRAP, RA, IMM, CONST_SI, NONE, NONE, ADD, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', NONE, '0', '0', '0', NONE), INSN_wait => (ALU, NONE, OP_WAIT, NONE, IMM, NONE, NONE, NONE, ADD, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '1', NONE), - INSN_xor => (ALU, NONE, OP_XOR, NONE, RB, NONE, RS, RA, LOG, "001", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), - INSN_xori => (ALU, NONE, OP_XOR, NONE, IMM, CONST_UI, RS, RA, LOG, "001", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), - INSN_xoris => (ALU, NONE, OP_XOR, NONE, IMM, CONST_UI_HI, RS, RA, LOG, "001", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), + INSN_xor => (ALU, NONE, OP_COMPUTE, NONE, RB, NONE, RS, RA, LOG, "001", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), + INSN_xori => (ALU, NONE, OP_COMPUTE, NONE, IMM, CONST_UI, RS, RA, LOG, "001", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), + INSN_xoris => (ALU, NONE, OP_COMPUTE, NONE, IMM, CONST_UI_HI, RS, RA, LOG, "001", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), others => (ALU, NONE, OP_ILLEGAL, NONE, IMM, NONE, NONE, NONE, ADD, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE) ); diff --git a/decode2.vhdl b/decode2.vhdl index 033f1f2..0290840 100644 --- a/decode2.vhdl +++ b/decode2.vhdl @@ -629,10 +629,10 @@ begin v.e.misaligned_prefix := d_in.misaligned_prefix; -- rotator control signals - v.e.right_shift := '1' when op = OP_SHR else '0'; - v.e.rot_clear_left := '1' when op = OP_RLC or op = OP_RLCL else '0'; - v.e.rot_clear_right := '1' when op = OP_RLC or op = OP_RLCR else '0'; - v.e.rot_sign_ext := '1' when op = OP_EXTSWSLI else '0'; + v.e.right_shift := d_in.decode.invert_a; + v.e.rot_clear_left := d_in.decode.subresult(2); + v.e.rot_clear_right := d_in.decode.subresult(0); + v.e.rot_sign_ext := d_in.decode.subresult(1); v.e.do_popcnt := '1' when op = OP_COUNTB and d_in.insn(7 downto 6) = "11" else '0'; diff --git a/decode_types.vhdl b/decode_types.vhdl index 2129fe3..598ff52 100644 --- a/decode_types.vhdl +++ b/decode_types.vhdl @@ -4,28 +4,21 @@ use ieee.std_logic_1164.all; package decode_types is type insn_type_t is (OP_ILLEGAL, OP_NOP, OP_ADD, OP_ATTN, OP_B, OP_BC, OP_BCREG, - OP_BCD, OP_BPERM, OP_BREV, - OP_CMP, OP_CMPB, OP_CMPEQB, OP_CMPRB, - OP_COUNTB, OP_CROP, + OP_BPERM, OP_BSORT, OP_CMP, + OP_COMPUTE, + OP_COUNTB, OP_DARN, OP_DCBF, OP_DCBST, OP_DCBZ, - OP_SPARE, OP_ICBI, OP_ICBT, OP_FP_CMP, OP_FP_ARITH, OP_FP_MOVE, OP_FP_MISC, OP_DIV, OP_DIVE, OP_MOD, - OP_EXTS, OP_EXTSWSLI, - OP_ISEL, OP_ISYNC, - OP_LOGIC, + OP_ISYNC, OP_LOAD, OP_STORE, - OP_MCRXRX, OP_MFCR, OP_MFMSR, OP_MFSPR, + OP_MCRXRX, OP_MFMSR, OP_MFSPR, OP_MTCRF, OP_MTMSRD, OP_MTSPR, OP_MUL_L64, OP_MUL_H64, OP_MUL_H32, - OP_BSORT, - OP_PRTY, OP_RFID, - OP_RLC, OP_RLCL, OP_RLCR, OP_SC, OP_SETB, - OP_SHL, OP_SHR, + OP_RFID, + OP_SC, OP_SYNC, OP_TLBIE, OP_TRAP, - OP_XOR, - OP_ADDG6S, OP_WAIT, OP_FETCH_FAILED ); diff --git a/execute1.vhdl b/execute1.vhdl index b302ce3..a018405 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -1120,10 +1120,10 @@ begin when "010" => newcrf := ppc_cmpeqb(a_in, b_in); when "011" => + -- CR logical instructions if is_X(e_in.insn) then newcrf := (others => 'X'); - elsif e_in.insn(1) = '1' then - -- CR logical instructions + else crnum := to_integer(unsigned(bf)); j := (7 - crnum) * 4; newcrf := cr_in(j + 3 downto j); @@ -1142,14 +1142,18 @@ begin newcrf(i) := crresult; end if; end loop; + end if; + when "100" => + -- MCRF + if is_X(e_in.insn) then + newcrf := (others => 'X'); else - -- MCRF bfa := insn_bfa(e_in.insn); scrnum := to_integer(unsigned(bfa)); j := (7 - scrnum) * 4; newcrf := cr_in(j + 3 downto j); end if; - when "100" => + when "101" => -- MCRXRX newcrf := xerc_in.ov & xerc_in.ov32 & xerc_in.ca & xerc_in.ca32; when others => @@ -1190,6 +1194,7 @@ begin variable slow_op : std_ulogic; variable owait : std_ulogic; variable srr1 : std_ulogic_vector(63 downto 0); + variable c32, c64 : std_ulogic; begin v := actions_type_init; v.e.write_data := alu_result; @@ -1247,6 +1252,26 @@ begin v.ciabr_trace := '1'; end if; + if e_in.output_carry = '1' then + case e_in.result_sel is + when ADD => + c32 := carry_32; + c64 := carry_64; + when ROT => + c32 := rotator_carry; + c64 := rotator_carry; + when others => + c32 := '0'; + c64 := '0'; + end case; + if e_in.input_carry /= OV then + set_carry(v.e, c32, c64); + else + v.e.xerc.ov := carry_64; + v.e.xerc.ov32 := carry_32; + end if; + end if; + case_0: case e_in.insn_type is when OP_ILLEGAL => illegal := '1'; @@ -1279,17 +1304,10 @@ begin when OP_NOP | OP_DCBST | OP_ICBT => -- Do nothing when OP_ADD => - if e_in.output_carry = '1' then - if e_in.input_carry /= OV then - set_carry(v.e, carry_32, carry_64); - else - v.e.xerc.ov := carry_64; - v.e.xerc.ov32 := carry_32; - end if; - end if; if e_in.oe = '1' then set_ov(v.e, overflow_64, overflow_32); end if; + when OP_COMPUTE => when OP_CMP => when OP_TRAP => -- trap instructions (tw, twi, td, tdi) @@ -1303,11 +1321,6 @@ begin report "trap"; end if; end if; - when OP_ADDG6S => - when OP_CMPRB => - when OP_CMPEQB => - when OP_LOGIC | OP_XOR | OP_PRTY | OP_CMPB | OP_EXTS | - OP_BREV | OP_BCD => when OP_B => v.take_branch := '1'; @@ -1386,8 +1399,6 @@ begin when OP_COUNTB => v.res2_sel := "01"; slow_op := '1'; - when OP_ISEL => - when OP_CROP => when OP_MCRXRX => when OP_DARN => when OP_MFMSR => @@ -1429,7 +1440,6 @@ begin end if; end if; - when OP_MFCR => when OP_MTCRF => when OP_MTMSRD => v.se.write_msr := '1'; @@ -1503,11 +1513,6 @@ begin illegal := '1'; end if; end if; - when OP_RLC | OP_RLCL | OP_RLCR | OP_SHL | OP_SHR | OP_EXTSWSLI => - if e_in.output_carry = '1' then - set_carry(v.e, rotator_carry, rotator_carry); - end if; - when OP_SETB => when OP_ISYNC => v.e.redirect := '1'; diff --git a/logical.vhdl b/logical.vhdl index e4bc1c5..37321ab 100644 --- a/logical.vhdl +++ b/logical.vhdl @@ -114,7 +114,7 @@ begin end if; case op is - when "000" => -- OP_LOGIC + when "000" => -- and, or, etc. -- for now, abuse the 'is_signed' field to indicate inversion of RS rs_adj := rs; if is_signed = '1' then @@ -124,13 +124,13 @@ begin if invert_out = '1' then tmp := not tmp; end if; - when "001" => -- OP_XOR + when "001" => -- xor, eqv tmp := rs xor rb; if invert_out = '1' then tmp := not tmp; end if; - when "010" => -- OP_BREV + when "010" => -- brev if datalen(3) = '1' then tmp := rs( 7 downto 0) & rs(15 downto 8) & rs(23 downto 16) & rs(31 downto 24) & rs(39 downto 32) & rs(47 downto 40) & rs(55 downto 48) & rs(63 downto 56); @@ -142,22 +142,17 @@ begin rs(23 downto 16) & rs(31 downto 24) & rs( 7 downto 0) & rs(15 downto 8); end if; - when "011" => -- OP_PRTY + when "011" => -- prty* tmp := parity; - when "100" => -- OP_CMPB + when "100" => -- cmpb tmp := ppc_cmpb(rs, rb); - when "101" => -- OP_BCD - -- invert_in is abused to indicate direction of conversion - if invert_in = '0' then - -- cbcdtd - tmp := x"000" & bcd_to_dpd(rs(55 downto 44)) & bcd_to_dpd(rs(43 downto 32)) & - x"000" & bcd_to_dpd(rs(23 downto 12)) & bcd_to_dpd(rs(11 downto 0)); - else - -- cdtbcd - tmp := x"00" & dpd_to_bcd(rs(51 downto 42)) & dpd_to_bcd(rs(41 downto 32)) & - x"00" & dpd_to_bcd(rs(19 downto 10)) & dpd_to_bcd(rs(9 downto 0)); - end if; - when "110" => -- OP_EXTS + when "101" => -- cbcdtd + tmp := x"000" & bcd_to_dpd(rs(55 downto 44)) & bcd_to_dpd(rs(43 downto 32)) & + x"000" & bcd_to_dpd(rs(23 downto 12)) & bcd_to_dpd(rs(11 downto 0)); + when "110" => -- cdtbcd + tmp := x"00" & dpd_to_bcd(rs(51 downto 42)) & dpd_to_bcd(rs(41 downto 32)) & + x"00" & dpd_to_bcd(rs(19 downto 10)) & dpd_to_bcd(rs(9 downto 0)); + when "111" => -- exts* -- note datalen is a 1-hot encoding negative := (datalen(0) and rs(7)) or (datalen(1) and rs(15)) or diff --git a/scripts/fmt_log/fmt_log.c b/scripts/fmt_log/fmt_log.c index aa0573a..5a81c96 100644 --- a/scripts/fmt_log/fmt_log.c +++ b/scripts/fmt_log/fmt_log.c @@ -86,14 +86,14 @@ struct log_entry { const char *units[4] = { "al", "ls", "fp", "3?" }; const char *ops[64] = { - "illegal", "nop ", "add ", "attn ", "b ", "bc ", "bcreg ", "bcd ", - "bperm ", "brev ", "cmp ", "cmpb ", "cmpeqb ", "cmprb ", "countb ", "crop ", - "darn ", "dcbf ", "dcbst ", "xcbt ", "dcbtst ", "dcbz ", "icbi ", "fpcmp ", - "fparith", "fpmove ", "fpmisc ", "div ", "dive ", "mod ", "exts ", "extswsl", - "isel ", "isync ", "logic ", "ld ", "st ", "mcrxrx ", "mfcr ", "mfmsr ", - "mfspr ", "mtcrf ", "mtmsr ", "mtspr ", "mull64 ", "mulh64 ", "mulh32 ", "bsort ", - "prty ", "rfid ", "rlc ", "rlcl ", "rlcr ", "sc ", "setb ", "shl ", - "shr ", "sync ", "tlbie ", "trap ", "xor ", "addg6s ", "wait ", "ffail ", + "illegal", "nop ", "add ", "attn ", "b ", "bc ", "bcreg ", "bperm ", + "bsort ", "cmp ", "compute", "countb ", "darn ", "dcbf ", "dcbst ", "dcbz ", + "icbi ", "icbt ", "fpcmp ", "fparith", "fpmove ", "fpmisc ", "div ", "dive ", + "mod ", "isync ", "ld ", "st ", "mcrxrx ", "mfmsr ", "mfspr ", "mtcrf ", + "mtmsr ", "mtspr ", "mull64 ", "mulh64 ", "mulh32 ", "rfid ", "sc ", "sync ", + "tlbie ", "trap ", "wait ", "ffail ", "?44 ", "?45 ", "?46 ", "?47 ", + "?48 ", "?49 ", "?50 ", "?51 ", "?52 ", "?53 ", "?54 ", "?55 ", + "?56 ", "?57 ", "?58 ", "?59 ", "?60 ", "?61 ", "?62 ", "?63 " }; const char *spr_names[13] = From d2bf3f3580205072de01f8741738b351b10054c7 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Fri, 8 Aug 2025 08:55:48 +1000 Subject: [PATCH 2/2] core: Implement hypervisor doorbell interrupt and msg* instructions This implements the hypervisor doorbell exception and interrupt and the msgsnd, msgclr and msgsync instructions (msgsync is a no-op). The msgsnd instruction can generate a hypervisor doorbell interrupt on any CPU in the system. To achieve this, each core sends its hypervisor doorbell messages to the soc level, which ORs together the bits for each CPU and sends it to that CPU. The privileged doorbell exception/interrupt and the msgsndp/msgclrp instructions are not required since we don't implement SMT. Signed-off-by: Paul Mackerras --- core.vhdl | 7 +++++ decode1.vhdl | 3 +++ decode_types.vhdl | 54 +++++++++++++++++++++------------------ execute1.vhdl | 51 +++++++++++++++++++++++++++++++++--- predecode.vhdl | 3 +++ scripts/fmt_log/fmt_log.c | 6 ++--- soc.vhdl | 22 +++++++++++++++- 7 files changed, 113 insertions(+), 33 deletions(-) diff --git a/core.vhdl b/core.vhdl index d4efcf3..bc59014 100644 --- a/core.vhdl +++ b/core.vhdl @@ -10,6 +10,7 @@ entity core is generic ( SIM : boolean := false; CPU_INDEX : natural := 0; + NCPUS : positive := 1; DISABLE_FLATTEN : boolean := false; EX1_BYPASS : boolean := true; HAS_FPU : boolean := true; @@ -52,6 +53,9 @@ entity core is ext_irq : in std_ulogic; + msg_in : in std_ulogic; + msg_out : out std_ulogic_vector(NCPUS-1 downto 0); + run_out : out std_ulogic; terminated_out : out std_logic ); @@ -370,6 +374,7 @@ begin generic map ( SIM => SIM, CPU_INDEX => CPU_INDEX, + NCPUS => NCPUS, EX1_BYPASS => EX1_BYPASS, HAS_FPU => HAS_FPU, LOG_LENGTH => LOG_LENGTH @@ -398,6 +403,8 @@ begin ls_events => loadstore_events, dc_events => dcache_events, ic_events => icache_events, + msg_out => msg_out, + msg_in => msg_in, run_out => run_out, terminate_out => terminate, dbg_spr_req => dbg_spr_req, diff --git a/decode1.vhdl b/decode1.vhdl index e18350f..afe7610 100644 --- a/decode1.vhdl +++ b/decode1.vhdl @@ -267,6 +267,9 @@ architecture behaviour of decode1 is INSN_modsw => (DVU, NONE, OP_MOD, RA, RB, NONE, NONE, RT, ADD, "101", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '1', NONE, '0', '0', '0', NONE), INSN_modud => (DVU, NONE, OP_MOD, RA, RB, NONE, NONE, RT, ADD, "101", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), INSN_moduw => (DVU, NONE, OP_MOD, RA, RB, NONE, NONE, RT, ADD, "101", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', NONE, '0', '0', '0', NONE), + INSN_msgclr => (ALU, NONE, OP_MSG, NONE, RB, NONE, NONE, NONE, ADD, "011", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1', '0', NONE), + INSN_msgsnd => (ALU, NONE, OP_MSG, NONE, RB, NONE, NONE, NONE, ADD, "001", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1', '0', NONE), + INSN_msgsync => (ALU, NONE, OP_NOP, NONE, IMM, NONE, NONE, NONE, ADD, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1', '0', NONE), INSN_mtcrf => (ALU, NONE, OP_MTCRF, NONE, IMM, NONE, RS, NONE, ADD, "101", '0', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), INSN_mtfsb => (FPU, FPU, OP_FP_MISC, NONE, IMM, NONE, NONE, NONE, ADD, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), INSN_mtfsf => (FPU, FPU, OP_FP_MISC, NONE, FRB, NONE, NONE, NONE, ADD, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE), diff --git a/decode_types.vhdl b/decode_types.vhdl index 598ff52..1503369 100644 --- a/decode_types.vhdl +++ b/decode_types.vhdl @@ -14,6 +14,7 @@ package decode_types is OP_ISYNC, OP_LOAD, OP_STORE, OP_MCRXRX, OP_MFMSR, OP_MFSPR, + OP_MSG, OP_MTCRF, OP_MTMSRD, OP_MTSPR, OP_MUL_L64, OP_MUL_H64, OP_MUL_H32, OP_RFID, @@ -87,10 +88,11 @@ package decode_types is INSN_mfcr, INSN_mfmsr, INSN_mfspr, + INSN_msgsync, INSN_mtcrf, INSN_mtmsr, - INSN_mtmsrd, - INSN_mtspr, -- 60 + INSN_mtmsrd, -- 60 + INSN_mtspr, INSN_mulli, INSN_neg, INSN_nop, @@ -99,8 +101,8 @@ package decode_types is INSN_popcntb, INSN_popcntw, INSN_popcntd, - INSN_prtyw, - INSN_prtyd, -- 70 + INSN_prtyw, -- 70 + INSN_prtyd, INSN_rfid, INSN_rfscv, INSN_rldic, @@ -109,8 +111,8 @@ package decode_types is INSN_rldimi, INSN_rlwimi, INSN_rlwinm, - INSN_rnop, - INSN_sc, -- 80 + INSN_rnop, -- 80 + INSN_sc, INSN_setb, INSN_slbia, INSN_sradi, @@ -119,8 +121,8 @@ package decode_types is INSN_std, INSN_stdu, INSN_sthu, - INSN_stq, - INSN_stwu, -- 90 + INSN_stq, -- 90 + INSN_stwu, INSN_subfic, INSN_subfme, INSN_subfze, @@ -129,10 +131,8 @@ package decode_types is INSN_tlbsync, INSN_twi, INSN_wait, - INSN_xori, - INSN_xoris, -- 100 - -- pad to 102 - INSN_065, + INSN_xori, -- 100 + INSN_xoris, -- Non-prefixed instructions that have a MLS:D prefixed form and -- their corresponding prefixed instructions. @@ -233,6 +233,8 @@ package decode_types is INSN_modsw, INSN_moduw, INSN_modud, -- 190 + INSN_msgclr, + INSN_msgsnd, INSN_mulhw, INSN_mulhwu, INSN_mulhd, @@ -240,9 +242,9 @@ package decode_types is INSN_mullw, INSN_mulld, INSN_nand, - INSN_nor, + INSN_nor, -- 200 INSN_or, - INSN_orc, -- 200 + INSN_orc, INSN_pdepd, INSN_pextd, INSN_rldcl, @@ -250,9 +252,9 @@ package decode_types is INSN_rlwnm, INSN_slw, INSN_sld, - INSN_sraw, + INSN_sraw, -- 210 INSN_srad, - INSN_srw, -- 210 + INSN_srw, INSN_srd, INSN_stbcix, INSN_stbcx, @@ -260,9 +262,9 @@ package decode_types is INSN_stbux, INSN_stdbrx, INSN_stdcix, - INSN_stdcx, + INSN_stdcx, -- 220 INSN_stdx, - INSN_stdux, -- 220 + INSN_stdux, INSN_sthbrx, INSN_sthcix, INSN_sthcx, @@ -270,9 +272,9 @@ package decode_types is INSN_sthux, INSN_stqcx, INSN_stwbrx, - INSN_stwcix, + INSN_stwcix, -- 230 INSN_stwcx, - INSN_stwx, -- 230 + INSN_stwx, INSN_stwux, INSN_subf, INSN_subfc, @@ -280,10 +282,11 @@ package decode_types is INSN_td, INSN_tlbie, INSN_tlbiel, - INSN_tw, + INSN_tw, -- 240 INSN_xor, - -- pad to 240 to simplify comparison logic + -- pad to 248 to simplify comparison logic + INSN_242, INSN_243, INSN_244, INSN_245, INSN_246, INSN_247, -- The following instructions have a third input addressed by RC INSN_maddld, @@ -291,9 +294,7 @@ package decode_types is INSN_maddhdu, -- pad to 256 to simplify comparison logic - INSN_243, - INSN_244, INSN_245, INSN_246, INSN_247, - INSN_248, INSN_249, INSN_250, INSN_251, + INSN_251, INSN_252, INSN_253, INSN_254, INSN_255, -- The following instructions access floating-point registers @@ -693,6 +694,9 @@ package body decode_types is when INSN_moduw => return "011111"; when INSN_modsd => return "011111"; when INSN_modsw => return "011111"; + when INSN_msgclr => return "011111"; + when INSN_msgsnd => return "011111"; + when INSN_msgsync => return "011111"; when INSN_mtcrf => return "011111"; when INSN_mtmsr => return "011111"; when INSN_mtmsrd => return "011111"; diff --git a/execute1.vhdl b/execute1.vhdl index a018405..34fd03a 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -16,6 +16,7 @@ entity execute1 is EX1_BYPASS : boolean := true; HAS_FPU : boolean := true; CPU_INDEX : natural; + NCPUS : positive := 1; -- Non-zero to enable log data collection LOG_LENGTH : natural := 0 ); @@ -48,6 +49,9 @@ entity execute1 is dbg_ctrl_out : out ctrl_t; + msg_in : in std_ulogic; + msg_out : out std_ulogic_vector(NCPUS-1 downto 0); + run_out : out std_ulogic; icache_inval : out std_ulogic; terminate_out : out std_ulogic; @@ -103,8 +107,10 @@ architecture behaviour of execute1 is write_tbl : std_ulogic; write_tbu : std_ulogic; noop_spr_read : std_ulogic; + send_hmsg : std_ulogic_vector(NCPUS-1 downto 0); + clr_hmsg : std_ulogic; end record; - constant side_effect_init : side_effect_type := (others => '0'); + constant side_effect_init : side_effect_type := (send_hmsg => (others => '0'), others => '0'); type actions_type is record e : Execute1ToWritebackType; @@ -287,6 +293,9 @@ architecture behaviour of execute1 is signal tb_next : std_ulogic_vector(63 downto 0); signal tb_carry : std_ulogic; + -- directed hypervisor doorbell state + signal dhd_pending : std_ulogic; + type privilege_level is (USER, SUPER); type op_privilege_array is array(insn_type_t) of privilege_level; constant op_privilege: op_privilege_array := ( @@ -614,6 +623,18 @@ begin dbg_ctrl_out <= ctrl; log_rd_addr <= ex2.log_addr_spr; + -- Doorbells + doorbell_sync : process(clk) + begin + if rising_edge(clk) then + if rst = '1' or ex2.se.clr_hmsg = '1' then + dhd_pending <= '0'; + elsif msg_in = '1' then + dhd_pending <= '1'; + end if; + end if; + end process; + a_in <= e_in.read_data1; b_in <= e_in.read_data2; c_in <= e_in.read_data3; @@ -1440,6 +1461,20 @@ begin end if; end if; + when OP_MSG => + -- msgsnd, msgclr + if b_in(31 downto 27) = 5x"5" then + if e_in.insn(6) = '0' then -- msgsnd + for cpuid in 0 to NCPUS-1 loop + if unsigned(b_in(19 downto 0)) = to_unsigned(cpuid, 20) then + v.se.send_hmsg(cpuid) := '1'; + end if; + end loop; + else -- msgclr + v.se.clr_hmsg := '1'; + end if; + end if; + when OP_MTCRF => when OP_MTMSRD => v.se.write_msr := '1'; @@ -1704,8 +1739,9 @@ begin v.busy := '0'; bypass_valid := actions.bypass_valid; - irq_valid := ex1.msr(MSR_EE) and (pmu_to_x.intr or dec_sign or - (ext_irq_in and not ctrl.lpcr_heic)); + irq_valid := ex1.msr(MSR_EE) and + (pmu_to_x.intr or dec_sign or dhd_pending or + (ext_irq_in and not ctrl.lpcr_heic)); if valid_in = '1' then v.prev_op := e_in.insn_type; @@ -1747,6 +1783,11 @@ begin if pmu_to_x.intr = '1' then v.e.intr_vec := 16#f00#; report "IRQ valid: PMU"; + elsif dhd_pending = '1' then + v.e.intr_vec := 16#e80#; + v.e.hv_intr := '1'; + v.se.clr_hmsg := '1'; + report "Hypervisor doorbell"; elsif dec_sign = '1' then v.e.intr_vec := 16#900#; report "IRQ valid: DEC"; @@ -2175,7 +2216,7 @@ begin -- pending exceptions clear any wait state -- ex1.fp_exception_next is not tested because it is not possible to -- get into wait state with a pending FP exception. - irq_exc := pmu_to_x.intr or dec_sign or ext_irq_in; + irq_exc := pmu_to_x.intr or dec_sign or ext_irq_in or dhd_pending; if ex1.trace_next = '1' or irq_exc = '1' or interrupt_in.intr = '1' then ctrl_tmp.wait_state <= '0'; end if; @@ -2223,6 +2264,8 @@ begin terminate_out <= ex2.se.terminate; icache_inval <= ex2.se.icache_inval; + msg_out <= ex2.se.send_hmsg; + exception_log <= v.e.interrupt; end process; diff --git a/predecode.vhdl b/predecode.vhdl index 852c96c..ece38b1 100644 --- a/predecode.vhdl +++ b/predecode.vhdl @@ -346,6 +346,9 @@ architecture behaviour of predecoder is 2#0_01000_01011# => INSN_moduw, 2#0_11000_01001# => INSN_modsd, 2#0_11000_01011# => INSN_modsw, + 2#0_00111_01110# => INSN_msgclr, + 2#0_00110_01110# => INSN_msgsnd, + 2#0_11011_10110# => INSN_msgsync, 2#0_00100_10000# => INSN_mtcrf, 2#0_00100_10010# => INSN_mtmsr, 2#0_00101_10010# => INSN_mtmsrd, diff --git a/scripts/fmt_log/fmt_log.c b/scripts/fmt_log/fmt_log.c index 5a81c96..d5b4488 100644 --- a/scripts/fmt_log/fmt_log.c +++ b/scripts/fmt_log/fmt_log.c @@ -89,9 +89,9 @@ const char *ops[64] = "illegal", "nop ", "add ", "attn ", "b ", "bc ", "bcreg ", "bperm ", "bsort ", "cmp ", "compute", "countb ", "darn ", "dcbf ", "dcbst ", "dcbz ", "icbi ", "icbt ", "fpcmp ", "fparith", "fpmove ", "fpmisc ", "div ", "dive ", - "mod ", "isync ", "ld ", "st ", "mcrxrx ", "mfmsr ", "mfspr ", "mtcrf ", - "mtmsr ", "mtspr ", "mull64 ", "mulh64 ", "mulh32 ", "rfid ", "sc ", "sync ", - "tlbie ", "trap ", "wait ", "ffail ", "?44 ", "?45 ", "?46 ", "?47 ", + "mod ", "isync ", "ld ", "st ", "mcrxrx ", "mfmsr ", "mfspr ", "msg ", + "mtcrf ", "mtmsr ", "mtspr ", "mull64 ", "mulh64 ", "mulh32 ", "rfid ", "sc ", + "sync ", "tlbie ", "trap ", "wait ", "ffail ", "?45 ", "?46 ", "?47 ", "?48 ", "?49 ", "?50 ", "?51 ", "?52 ", "?53 ", "?54 ", "?55 ", "?56 ", "?57 ", "?58 ", "?59 ", "?60 ", "?61 ", "?62 ", "?63 " }; diff --git a/soc.vhdl b/soc.vhdl index 6652711..3daeb73 100644 --- a/soc.vhdl +++ b/soc.vhdl @@ -273,6 +273,9 @@ architecture behaviour of soc is signal core_run_out : std_ulogic_vector(NCPUS-1 downto 0); + type msg_percpu_array is array(cpu_index_t) of std_ulogic_vector(NCPUS-1 downto 0); + signal msgs : msg_percpu_array; + function wishbone_widen_data(wb : wb_io_master_out) return wishbone_master_out is variable wwb : wishbone_master_out; begin @@ -355,10 +358,14 @@ begin -- Processor cores processors: for i in 0 to NCPUS-1 generate + signal msgin : std_ulogic; + + begin core: entity work.core generic map( SIM => SIM, CPU_INDEX => i, + NCPUS => NCPUS, HAS_FPU => HAS_FPU, HAS_BTC => HAS_BTC, DISABLE_FLATTEN => DISABLE_FLATTEN_CORE, @@ -389,8 +396,21 @@ begin dmi_wr => dmi_wr, dmi_ack => dmi_core_ack(i), dmi_req => dmi_core_req(i), - ext_irq => core_ext_irq(i) + ext_irq => core_ext_irq(i), + msg_out => msgs(i), + msg_in => msgin ); + + process(all) + variable m : std_ulogic; + begin + m := '0'; + for j in 0 to NCPUS-1 loop + m := m or msgs(j)(i); + end loop; + msgin <= m; + end process; + end generate; run_out <= or (core_run_out);