library ieee ;
use ieee.std_logic_1164. all ;
use ieee.numeric_std. all ;
library work ;
use work.common. all ;
use work.decode_types. all ;
use work.insn_helpers. all ;
entity decode1 is
generic (
HAS_FPU : boolean : = true ;
-- Non-zero to enable log data collection
LOG_LENGTH : natural : = 0
) ;
port (
clk : in std_ulogic ;
rst : in std_ulogic ;
stall_in : in std_ulogic ;
flush_in : in std_ulogic ;
busy_out : out std_ulogic ;
flush_out : out std_ulogic ;
f_in : in IcacheToDecode1Type ;
f_out : out Decode1ToFetch1Type ;
d_out : out Decode1ToDecode2Type ;
r_out : out Decode1ToRegisterFileType ;
log_out : out std_ulogic_vector ( 12 downto 0 )
) ;
end entity decode1 ;
architecture behaviour of decode1 is
signal r , rin : Decode1ToDecode2Type ;
signal f , fin : Decode1ToFetch1Type ;
constant illegal_inst : decode_rom_t : =
( NONE , NONE , OP_ILLEGAL , NONE , NONE , NONE , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) ;
constant x_inst : decode_rom_t : =
( NONE , NONE , OP_ILLEGAL , NONE , NONE , NONE , NONE , 'X' , 'X' , 'X' , 'X' , ZERO , 'X' , NONE , 'X' , 'X' , 'X' , 'X' , 'X' , 'X' , NONE , 'X' , 'X' , NONE ) ;
-- If we have an FPU, then it is used for integer divisions,
-- otherwise a dedicated divider in the ALU is used.
function divider_unit ( hf : boolean ) return unit_t is
begin
if hf then
return FPU ;
else
return ALU ;
end if ;
end ;
constant DVU : unit_t : = divider_unit ( HAS_FPU ) ;
type reg_internal_t is record
override : std_ulogic ;
override_decode : decode_rom_t ;
override_unit : std_ulogic ;
force_single : std_ulogic ;
end record ;
constant reg_internal_t_init : reg_internal_t : =
( override = > '0' , override_decode = > illegal_inst , override_unit = > '0' , force_single = > '0' ) ;
signal ri , ri_in : reg_internal_t ;
type br_predictor_t is record
br_nia : std_ulogic_vector ( 61 downto 0 ) ;
br_offset : signed ( 23 downto 0 ) ;
predict : std_ulogic ;
end record ;
signal br , br_in : br_predictor_t ;
subtype major_opcode_t is unsigned ( 5 downto 0 ) ;
type major_rom_array_t is array ( 0 to 63 ) of decode_rom_t ;
type minor_valid_array_t is array ( 0 to 1023 ) of std_ulogic ;
type minor_valid_array_2t is array ( 0 to 2047 ) of std_ulogic ;
type op_4_subop_array_t is array ( 0 to 63 ) of decode_rom_t ;
type op_19_subop_array_t is array ( 0 to 7 ) of decode_rom_t ;
type op_30_subop_array_t is array ( 0 to 15 ) of decode_rom_t ;
type op_31_subop_array_t is array ( 0 to 1023 ) of decode_rom_t ;
FPU: Implement floating convert from integer instructions
This implements fcfid, fcfidu, fcfids and fcfidus, which convert
64-bit integer values in an FPR into a floating-point value.
This brings in a lot of the datapath that will be needed in
future, including the shifter, adder, mask generator and
count-leading-zeroes logic, along with the machinery for rounding
to single-precision or double-precision, detecting inexact results,
signalling inexact-result exceptions, and updating result flags
in the FPSCR.
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
5 years ago
type op_59_subop_array_t is array ( 0 to 31 ) of decode_rom_t ;
type minor_rom_array_2_t is array ( 0 to 3 ) of decode_rom_t ;
type op_63_subop_array_0_t is array ( 0 to 511 ) of decode_rom_t ;
type op_63_subop_array_1_t is array ( 0 to 16 ) of decode_rom_t ;
constant major_decode_rom_array : major_rom_array_t : = (
-- unit fac internal in1 in2 in3 out CR CR inv inv cry cry ldst BR sgn upd rsrv 32b sgn rc lk sgl rpt
-- op in out A out in out len ext pipe
12 = > ( ALU , NONE , OP_ADD , RA , CONST_SI , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '1' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- addic
13 = > ( ALU , NONE , OP_ADD , RA , CONST_SI , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '1' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , ONE , '0' , '0' , NONE ) , -- addic.
14 = > ( ALU , NONE , OP_ADD , RA_OR_ZERO , CONST_SI , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- addi
15 = > ( ALU , NONE , OP_ADD , RA_OR_ZERO , CONST_SI_HI , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- addis
28 = > ( ALU , NONE , OP_AND , NONE , CONST_UI , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , ONE , '0' , '0' , NONE ) , -- andi.
29 = > ( ALU , NONE , OP_AND , NONE , CONST_UI_HI , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , ONE , '0' , '0' , NONE ) , -- andis.
0 = > ( ALU , NONE , OP_ATTN , NONE , NONE , NONE , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '1' , NONE ) , -- attn
18 = > ( ALU , NONE , OP_B , NONE , CONST_LI , NONE , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '1' , '0' , NONE ) , -- b
16 = > ( ALU , NONE , OP_BC , NONE , CONST_BD , NONE , NONE , '1' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '1' , '0' , NONE ) , -- bc
11 = > ( ALU , NONE , OP_CMP , RA , CONST_SI , NONE , NONE , '0' , '1' , '1' , '0' , ONE , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '1' , NONE , '0' , '0' , NONE ) , -- cmpi
10 = > ( ALU , NONE , OP_CMP , RA , CONST_UI , NONE , NONE , '0' , '1' , '1' , '0' , ONE , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- cmpli
34 = > ( LDST , NONE , OP_LOAD , RA_OR_ZERO , CONST_SI , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , is1B , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- lbz
35 = > ( LDST , NONE , OP_LOAD , RA_OR_ZERO , CONST_SI , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , is1B , '0' , '0' , '1' , '0' , '0' , '0' , NONE , '0' , '0' , DUPD ) , -- lbzu
50 = > ( LDST , FPU , OP_LOAD , RA_OR_ZERO , CONST_SI , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , is8B , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- lfd
51 = > ( LDST , FPU , OP_LOAD , RA_OR_ZERO , CONST_SI , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , is8B , '0' , '0' , '1' , '0' , '0' , '0' , NONE , '0' , '0' , DUPD ) , -- lfdu
48 = > ( LDST , FPU , OP_LOAD , RA_OR_ZERO , CONST_SI , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , is4B , '0' , '0' , '0' , '0' , '1' , '0' , NONE , '0' , '0' , NONE ) , -- lfs
49 = > ( LDST , FPU , OP_LOAD , RA_OR_ZERO , CONST_SI , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , is4B , '0' , '0' , '1' , '0' , '1' , '0' , NONE , '0' , '0' , DUPD ) , -- lfsu
42 = > ( LDST , NONE , OP_LOAD , RA_OR_ZERO , CONST_SI , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , is2B , '0' , '1' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- lha
43 = > ( LDST , NONE , OP_LOAD , RA_OR_ZERO , CONST_SI , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , is2B , '0' , '1' , '1' , '0' , '0' , '0' , NONE , '0' , '0' , DUPD ) , -- lhau
40 = > ( LDST , NONE , OP_LOAD , RA_OR_ZERO , CONST_SI , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , is2B , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- lhz
41 = > ( LDST , NONE , OP_LOAD , RA_OR_ZERO , CONST_SI , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , is2B , '0' , '0' , '1' , '0' , '0' , '0' , NONE , '0' , '0' , DUPD ) , -- lhzu
32 = > ( LDST , NONE , OP_LOAD , RA_OR_ZERO , CONST_SI , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , is4B , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- lwz
33 = > ( LDST , NONE , OP_LOAD , RA_OR_ZERO , CONST_SI , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , is4B , '0' , '0' , '1' , '0' , '0' , '0' , NONE , '0' , '0' , DUPD ) , -- lwzu
7 = > ( ALU , NONE , OP_MUL_L64 , RA , CONST_SI , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '1' , NONE , '0' , '0' , NONE ) , -- mulli
24 = > ( ALU , NONE , OP_OR , NONE , CONST_UI , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- ori
25 = > ( ALU , NONE , OP_OR , NONE , CONST_UI_HI , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- oris
20 = > ( ALU , NONE , OP_RLC , RA , CONST_SH32 , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '1' , '0' , RC , '0' , '0' , NONE ) , -- rlwimi
21 = > ( ALU , NONE , OP_RLC , NONE , CONST_SH32 , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '1' , '0' , RC , '0' , '0' , NONE ) , -- rlwinm
23 = > ( ALU , NONE , OP_RLC , NONE , RB , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '1' , '0' , RC , '0' , '0' , NONE ) , -- rlwnm
17 = > ( ALU , NONE , OP_SC , NONE , NONE , NONE , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- sc
38 = > ( LDST , NONE , OP_STORE , RA_OR_ZERO , CONST_SI , RS , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , is1B , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- stb
39 = > ( LDST , NONE , OP_STORE , RA_OR_ZERO , CONST_SI , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , is1B , '0' , '0' , '1' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- stbu
54 = > ( LDST , FPU , OP_STORE , RA_OR_ZERO , CONST_SI , FRS , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , is8B , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- stfd
55 = > ( LDST , FPU , OP_STORE , RA_OR_ZERO , CONST_SI , FRS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , is8B , '0' , '0' , '1' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- stfdu
52 = > ( LDST , FPU , OP_STORE , RA_OR_ZERO , CONST_SI , FRS , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , is4B , '0' , '0' , '0' , '0' , '1' , '0' , NONE , '0' , '0' , NONE ) , -- stfs
53 = > ( LDST , FPU , OP_STORE , RA_OR_ZERO , CONST_SI , FRS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , is4B , '0' , '0' , '1' , '0' , '1' , '0' , NONE , '0' , '0' , NONE ) , -- stfsu
44 = > ( LDST , NONE , OP_STORE , RA_OR_ZERO , CONST_SI , RS , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , is2B , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- sth
45 = > ( LDST , NONE , OP_STORE , RA_OR_ZERO , CONST_SI , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , is2B , '0' , '0' , '1' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- sthu
36 = > ( LDST , NONE , OP_STORE , RA_OR_ZERO , CONST_SI , RS , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , is4B , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- stw
37 = > ( LDST , NONE , OP_STORE , RA_OR_ZERO , CONST_SI , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , is4B , '0' , '0' , '1' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- stwu
8 = > ( ALU , NONE , OP_ADD , RA , CONST_SI , NONE , RT , '0' , '0' , '1' , '0' , ONE , '1' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- subfic
2 = > ( ALU , NONE , OP_TRAP , RA , CONST_SI , NONE , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- tdi
3 = > ( ALU , NONE , OP_TRAP , RA , CONST_SI , NONE , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '1' , '0' , NONE , '0' , '0' , NONE ) , -- twi
26 = > ( ALU , NONE , OP_XOR , NONE , CONST_UI , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- xori
27 = > ( ALU , NONE , OP_XOR , NONE , CONST_UI_HI , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- xoris
others = > illegal_inst
) ;
-- indexed by bits 5..0 and 10..6 of instruction word
constant decode_op_4_valid : minor_valid_array_2t : = (
2#11000000000# to 2#11000011111# = > '1' , -- maddhd
2#11000100000# to 2#11000111111# = > '1' , -- maddhdu
2#11001100000# to 2#11001111111# = > '1' , -- maddld
others = > '0'
) ;
-- indexed by bits 5..0 of instruction word
constant decode_op_4_array : op_4_subop_array_t : = (
-- unit fac internal in1 in2 in3 out CR CR inv inv cry cry ldst BR sgn upd rsrv 32b sgn rc lk sgl rpt
-- op in out A out in out len ext pipe
2#110000# = > ( ALU , NONE , OP_MUL_H64 , RA , RB , RCR , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '1' , NONE , '0' , '0' , NONE ) , -- maddhd
2#110001# = > ( ALU , NONE , OP_MUL_H64 , RA , RB , RCR , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- maddhdu
2#110011# = > ( ALU , NONE , OP_MUL_L64 , RA , RB , RCR , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '1' , NONE , '0' , '0' , NONE ) , -- maddld
others = > decode_rom_init
) ;
-- indexed by bits 10..1 of instruction word
constant decode_op_19_valid : minor_valid_array_t : = (
2#0001000000# to 2#0001011111# = > '1' , -- addpcis, 5 upper bits are part of constant
2#1000010000# = > '1' , -- bcctr
2#1000000000# = > '1' , -- bclr
2#1000010001# = > '1' , -- bctar
2#0000101000# = > '1' , -- crand
2#0000100100# = > '1' , -- crandc
2#0000101001# = > '1' , -- creqv
2#0000100111# = > '1' , -- crnand
2#0000100001# = > '1' , -- crnor
2#0000101110# = > '1' , -- cror
2#0000101101# = > '1' , -- crorc
2#0000100110# = > '1' , -- crxor
2#1011000100# = > '1' , -- isync
2#0000000000# = > '1' , -- mcrf
2#1001000000# = > '1' , -- rfid
others = > '0'
) ;
-- indexed by bits 5, 3, 2 of instruction word
constant decode_op_19_array : op_19_subop_array_t : = (
-- unit fac internal in1 in2 in3 out CR CR inv inv cry cry ldst BR sgn upd rsrv 32b sgn rc lk sgl rpt
-- op in out A out in out len ext pipe
-- mcrf; and cr logical ops
2#000# = > ( ALU , NONE , OP_CROP , NONE , NONE , NONE , NONE , '1' , '1' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) ,
-- addpcis
2#001# = > ( ALU , NONE , OP_ADD , CIA , CONST_DXHI4 , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) ,
-- bclr, bcctr, bctar
2#100# = > ( ALU , NONE , OP_BCREG , NONE , NONE , NONE , NONE , '1' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '1' , '0' , NONE ) ,
-- isync
decode1: Reduce number of single-issue instructions
This reduces the set of instructions marked as single-issue to just
attn and mtspr to "slow" SPRs (those that are not stored in the
register file).
The instructions that were previously single-issue are: isync, dcbf,
dcbst, dcbt, dcbtst, eieio, icbi, mfmsr, mtmsr, mtmsrd, mfspr to slow
SPRS, sync, tlbsync and wait. The synchronization instructions are
mostly no-ops anyway due to the in-order nature of the core, and the
cache-management instructions are unimplemented (except for icbi).
The MSR ops don't need to be single-issue due to the in-order core and
the fact that MSR updates are effective on the following instruction.
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
3 years ago
2#111# = > ( ALU , NONE , OP_ISYNC , NONE , NONE , NONE , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) ,
-- rfid
2#101# = > ( ALU , NONE , OP_RFID , NONE , NONE , NONE , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) ,
others = > illegal_inst
) ;
constant decode_op_30_array : op_30_subop_array_t : = (
-- unit fac internal in1 in2 in3 out CR CR inv inv cry cry ldst BR sgn upd rsrv 32b sgn rc lk sgl rpt
-- op in out A out in out len ext pipe
2#0100# = > ( ALU , NONE , OP_RLC , NONE , CONST_SH , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- rldic
2#0101# = > ( ALU , NONE , OP_RLC , NONE , CONST_SH , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- rldic
2#0000# = > ( ALU , NONE , OP_RLCL , NONE , CONST_SH , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- rldicl
2#0001# = > ( ALU , NONE , OP_RLCL , NONE , CONST_SH , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- rldicl
2#0010# = > ( ALU , NONE , OP_RLCR , NONE , CONST_SH , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- rldicr
2#0011# = > ( ALU , NONE , OP_RLCR , NONE , CONST_SH , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- rldicr
2#0110# = > ( ALU , NONE , OP_RLC , RA , CONST_SH , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- rldimi
2#0111# = > ( ALU , NONE , OP_RLC , RA , CONST_SH , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- rldimi
2#1000# = > ( ALU , NONE , OP_RLCL , NONE , RB , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- rldcl
2#1001# = > ( ALU , NONE , OP_RLCR , NONE , RB , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- rldcr
others = > illegal_inst
) ;
-- Note: reformat with column -t -o ' '
constant decode_op_31_array : op_31_subop_array_t : = (
-- unit fac internal in1 in2 in3 out CR CR inv inv cry cry ldst BR sgn upd rsrv 32b sgn rc lk sgl rpt
-- op in out A out in out len ext pipe
2#0100001010# = > ( ALU , NONE , OP_ADD , RA , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- add
2#1100001010# = > ( ALU , NONE , OP_ADD , RA , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- addo
2#0000001010# = > ( ALU , NONE , OP_ADD , RA , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '1' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- addc
2#1000001010# = > ( ALU , NONE , OP_ADD , RA , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '1' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- addco
2#0010001010# = > ( ALU , NONE , OP_ADD , RA , RB , NONE , RT , '0' , '0' , '0' , '0' , CA , '1' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- adde
2#1010001010# = > ( ALU , NONE , OP_ADD , RA , RB , NONE , RT , '0' , '0' , '0' , '0' , CA , '1' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- addeo
2#0010101010# = > ( ALU , NONE , OP_ADD , RA , RB , NONE , RT , '0' , '0' , '0' , '0' , OV , '1' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- addex
2#0001001010# = > ( ALU , NONE , OP_ADDG6S , RA , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- addg6s
2#0011101010# = > ( ALU , NONE , OP_ADD , RA , CONST_M1 , NONE , RT , '0' , '0' , '0' , '0' , CA , '1' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- addme
2#1011101010# = > ( ALU , NONE , OP_ADD , RA , CONST_M1 , NONE , RT , '0' , '0' , '0' , '0' , CA , '1' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- addmeo
2#0011001010# = > ( ALU , NONE , OP_ADD , RA , NONE , NONE , RT , '0' , '0' , '0' , '0' , CA , '1' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- addze
2#1011001010# = > ( ALU , NONE , OP_ADD , RA , NONE , NONE , RT , '0' , '0' , '0' , '0' , CA , '1' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- addzeo
2#0000011100# = > ( ALU , NONE , OP_AND , NONE , RB , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- and
2#0000111100# = > ( ALU , NONE , OP_AND , NONE , RB , RS , RA , '0' , '0' , '1' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- andc
2#0011111100# = > ( ALU , NONE , OP_BPERM , NONE , RB , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- bperm
2#0100111010# = > ( ALU , NONE , OP_BCD , NONE , NONE , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- cbcdtd
2#0100011010# = > ( ALU , NONE , OP_BCD , NONE , NONE , RS , RA , '0' , '0' , '1' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- cdtbcd
2#0000000000# = > ( ALU , NONE , OP_CMP , RA , RB , NONE , NONE , '0' , '1' , '1' , '0' , ONE , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '1' , NONE , '0' , '0' , NONE ) , -- cmp
2#0111111100# = > ( ALU , NONE , OP_CMPB , NONE , RB , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- cmpb
2#0011100000# = > ( ALU , NONE , OP_CMPEQB , RA , RB , NONE , NONE , '0' , '1' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- cmpeqb
2#0000100000# = > ( ALU , NONE , OP_CMP , RA , RB , NONE , NONE , '0' , '1' , '1' , '0' , ONE , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- cmpl
2#0011000000# = > ( ALU , NONE , OP_CMPRB , RA , RB , NONE , NONE , '0' , '1' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- cmprb
2#0000111010# = > ( ALU , NONE , OP_CNTZ , NONE , NONE , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- cntlzd
2#0000011010# = > ( ALU , NONE , OP_CNTZ , NONE , NONE , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '1' , '0' , RC , '0' , '0' , NONE ) , -- cntlzw
2#1000111010# = > ( ALU , NONE , OP_CNTZ , NONE , NONE , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- cnttzd
2#1000011010# = > ( ALU , NONE , OP_CNTZ , NONE , NONE , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '1' , '0' , RC , '0' , '0' , NONE ) , -- cnttzw
2#1011110011# = > ( ALU , NONE , OP_DARN , NONE , NONE , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- darn
decode1: Reduce number of single-issue instructions
This reduces the set of instructions marked as single-issue to just
attn and mtspr to "slow" SPRs (those that are not stored in the
register file).
The instructions that were previously single-issue are: isync, dcbf,
dcbst, dcbt, dcbtst, eieio, icbi, mfmsr, mtmsr, mtmsrd, mfspr to slow
SPRS, sync, tlbsync and wait. The synchronization instructions are
mostly no-ops anyway due to the in-order nature of the core, and the
cache-management instructions are unimplemented (except for icbi).
The MSR ops don't need to be single-issue due to the in-order core and
the fact that MSR updates are effective on the following instruction.
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
3 years ago
2#0001010110# = > ( ALU , NONE , OP_DCBF , NONE , NONE , NONE , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- dcbf
2#0000110110# = > ( ALU , NONE , OP_DCBST , NONE , NONE , NONE , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- dcbst
2#0100010110# = > ( ALU , NONE , OP_DCBT , NONE , NONE , NONE , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- dcbt
2#0011110110# = > ( ALU , NONE , OP_DCBTST , NONE , NONE , NONE , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- dcbtst
2#1111110110# = > ( LDST , NONE , OP_DCBZ , RA_OR_ZERO , RB , NONE , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- dcbz
2#0110001001# = > ( DVU , NONE , OP_DIVE , RA , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- divdeu
2#1110001001# = > ( DVU , NONE , OP_DIVE , RA , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- divdeuo
2#0110001011# = > ( DVU , NONE , OP_DIVE , RA , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '1' , '0' , RC , '0' , '0' , NONE ) , -- divweu
2#1110001011# = > ( DVU , NONE , OP_DIVE , RA , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '1' , '0' , RC , '0' , '0' , NONE ) , -- divweuo
2#0110101001# = > ( DVU , NONE , OP_DIVE , RA , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '1' , RC , '0' , '0' , NONE ) , -- divde
2#1110101001# = > ( DVU , NONE , OP_DIVE , RA , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '1' , RC , '0' , '0' , NONE ) , -- divdeo
2#0110101011# = > ( DVU , NONE , OP_DIVE , RA , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '1' , '1' , RC , '0' , '0' , NONE ) , -- divwe
2#1110101011# = > ( DVU , NONE , OP_DIVE , RA , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '1' , '1' , RC , '0' , '0' , NONE ) , -- divweo
2#0111001001# = > ( DVU , NONE , OP_DIV , RA , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- divdu
2#1111001001# = > ( DVU , NONE , OP_DIV , RA , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- divduo
2#0111001011# = > ( DVU , NONE , OP_DIV , RA , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '1' , '0' , RC , '0' , '0' , NONE ) , -- divwu
2#1111001011# = > ( DVU , NONE , OP_DIV , RA , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '1' , '0' , RC , '0' , '0' , NONE ) , -- divwuo
2#0111101001# = > ( DVU , NONE , OP_DIV , RA , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '1' , RC , '0' , '0' , NONE ) , -- divd
2#1111101001# = > ( DVU , NONE , OP_DIV , RA , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '1' , RC , '0' , '0' , NONE ) , -- divdo
2#0111101011# = > ( DVU , NONE , OP_DIV , RA , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '1' , '1' , RC , '0' , '0' , NONE ) , -- divw
2#1111101011# = > ( DVU , NONE , OP_DIV , RA , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '1' , '1' , RC , '0' , '0' , NONE ) , -- divwo
2#1100110110# = > ( ALU , NONE , OP_NOP , NONE , NONE , NONE , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- dss
2#0101010110# = > ( ALU , NONE , OP_NOP , NONE , NONE , NONE , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- dst
2#0101110110# = > ( ALU , NONE , OP_NOP , NONE , NONE , NONE , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- dstst
decode1: Reduce number of single-issue instructions
This reduces the set of instructions marked as single-issue to just
attn and mtspr to "slow" SPRs (those that are not stored in the
register file).
The instructions that were previously single-issue are: isync, dcbf,
dcbst, dcbt, dcbtst, eieio, icbi, mfmsr, mtmsr, mtmsrd, mfspr to slow
SPRS, sync, tlbsync and wait. The synchronization instructions are
mostly no-ops anyway due to the in-order nature of the core, and the
cache-management instructions are unimplemented (except for icbi).
The MSR ops don't need to be single-issue due to the in-order core and
the fact that MSR updates are effective on the following instruction.
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
3 years ago
2#1101010110# = > ( ALU , NONE , OP_NOP , NONE , NONE , NONE , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- eieio
2#0100011100# = > ( ALU , NONE , OP_XOR , NONE , RB , RS , RA , '0' , '0' , '0' , '1' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- eqv
2#1110111010# = > ( ALU , NONE , OP_EXTS , NONE , NONE , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , is1B , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- extsb
2#1110011010# = > ( ALU , NONE , OP_EXTS , NONE , NONE , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , is2B , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- extsh
2#1111011010# = > ( ALU , NONE , OP_EXTS , NONE , NONE , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , is4B , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- extsw
2#1101111010# = > ( ALU , NONE , OP_EXTSWSLI , NONE , CONST_SH , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- extswsli
2#1101111011# = > ( ALU , NONE , OP_EXTSWSLI , NONE , CONST_SH , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- extswsli
2#1111010110# = > ( ALU , NONE , OP_ICBI , NONE , NONE , NONE , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '1' , NONE ) , -- icbi
2#0000010110# = > ( ALU , NONE , OP_ICBT , NONE , NONE , NONE , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '1' , NONE ) , -- icbt
2#0000001111# = > ( ALU , NONE , OP_ISEL , RA_OR_ZERO , RB , NONE , RT , '1' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- isel
2#0000101111# = > ( ALU , NONE , OP_ISEL , RA_OR_ZERO , RB , NONE , RT , '1' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- isel
2#0001001111# = > ( ALU , NONE , OP_ISEL , RA_OR_ZERO , RB , NONE , RT , '1' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- isel
2#0001101111# = > ( ALU , NONE , OP_ISEL , RA_OR_ZERO , RB , NONE , RT , '1' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- isel
2#0010001111# = > ( ALU , NONE , OP_ISEL , RA_OR_ZERO , RB , NONE , RT , '1' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- isel
2#0010101111# = > ( ALU , NONE , OP_ISEL , RA_OR_ZERO , RB , NONE , RT , '1' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- isel
2#0011001111# = > ( ALU , NONE , OP_ISEL , RA_OR_ZERO , RB , NONE , RT , '1' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- isel
2#0011101111# = > ( ALU , NONE , OP_ISEL , RA_OR_ZERO , RB , NONE , RT , '1' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- isel
2#0100001111# = > ( ALU , NONE , OP_ISEL , RA_OR_ZERO , RB , NONE , RT , '1' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- isel
2#0100101111# = > ( ALU , NONE , OP_ISEL , RA_OR_ZERO , RB , NONE , RT , '1' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- isel
2#0101001111# = > ( ALU , NONE , OP_ISEL , RA_OR_ZERO , RB , NONE , RT , '1' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- isel
2#0101101111# = > ( ALU , NONE , OP_ISEL , RA_OR_ZERO , RB , NONE , RT , '1' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- isel
2#0110001111# = > ( ALU , NONE , OP_ISEL , RA_OR_ZERO , RB , NONE , RT , '1' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- isel
2#0110101111# = > ( ALU , NONE , OP_ISEL , RA_OR_ZERO , RB , NONE , RT , '1' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- isel
2#0111001111# = > ( ALU , NONE , OP_ISEL , RA_OR_ZERO , RB , NONE , RT , '1' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- isel
2#0111101111# = > ( ALU , NONE , OP_ISEL , RA_OR_ZERO , RB , NONE , RT , '1' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- isel
2#1000001111# = > ( ALU , NONE , OP_ISEL , RA_OR_ZERO , RB , NONE , RT , '1' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- isel
2#1000101111# = > ( ALU , NONE , OP_ISEL , RA_OR_ZERO , RB , NONE , RT , '1' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- isel
2#1001001111# = > ( ALU , NONE , OP_ISEL , RA_OR_ZERO , RB , NONE , RT , '1' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- isel
2#1001101111# = > ( ALU , NONE , OP_ISEL , RA_OR_ZERO , RB , NONE , RT , '1' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- isel
2#1010001111# = > ( ALU , NONE , OP_ISEL , RA_OR_ZERO , RB , NONE , RT , '1' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- isel
2#1010101111# = > ( ALU , NONE , OP_ISEL , RA_OR_ZERO , RB , NONE , RT , '1' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- isel
2#1011001111# = > ( ALU , NONE , OP_ISEL , RA_OR_ZERO , RB , NONE , RT , '1' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- isel
2#1011101111# = > ( ALU , NONE , OP_ISEL , RA_OR_ZERO , RB , NONE , RT , '1' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- isel
2#1100001111# = > ( ALU , NONE , OP_ISEL , RA_OR_ZERO , RB , NONE , RT , '1' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- isel
2#1100101111# = > ( ALU , NONE , OP_ISEL , RA_OR_ZERO , RB , NONE , RT , '1' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- isel
2#1101001111# = > ( ALU , NONE , OP_ISEL , RA_OR_ZERO , RB , NONE , RT , '1' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- isel
2#1101101111# = > ( ALU , NONE , OP_ISEL , RA_OR_ZERO , RB , NONE , RT , '1' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- isel
2#1110001111# = > ( ALU , NONE , OP_ISEL , RA_OR_ZERO , RB , NONE , RT , '1' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- isel
2#1110101111# = > ( ALU , NONE , OP_ISEL , RA_OR_ZERO , RB , NONE , RT , '1' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- isel
2#1111001111# = > ( ALU , NONE , OP_ISEL , RA_OR_ZERO , RB , NONE , RT , '1' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- isel
2#1111101111# = > ( ALU , NONE , OP_ISEL , RA_OR_ZERO , RB , NONE , RT , '1' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- isel
2#0000110100# = > ( LDST , NONE , OP_LOAD , RA_OR_ZERO , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , is1B , '0' , '0' , '0' , '1' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- lbarx
2#1101010101# = > ( LDST , NONE , OP_LOAD , RA_OR_ZERO , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , is1B , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- lbzcix
2#0001110111# = > ( LDST , NONE , OP_LOAD , RA_OR_ZERO , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , is1B , '0' , '0' , '1' , '0' , '0' , '0' , NONE , '0' , '0' , DUPD ) , -- lbzux
2#0001010111# = > ( LDST , NONE , OP_LOAD , RA_OR_ZERO , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , is1B , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- lbzx
2#0001010100# = > ( LDST , NONE , OP_LOAD , RA_OR_ZERO , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , is8B , '0' , '0' , '0' , '1' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- ldarx
2#1000010100# = > ( LDST , NONE , OP_LOAD , RA_OR_ZERO , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , is8B , '1' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- ldbrx
2#1101110101# = > ( LDST , NONE , OP_LOAD , RA_OR_ZERO , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , is8B , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- ldcix
2#0000110101# = > ( LDST , NONE , OP_LOAD , RA_OR_ZERO , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , is8B , '0' , '0' , '1' , '0' , '0' , '0' , NONE , '0' , '0' , DUPD ) , -- ldux
2#0000010101# = > ( LDST , NONE , OP_LOAD , RA_OR_ZERO , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , is8B , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- ldx
2#1001010111# = > ( LDST , FPU , OP_LOAD , RA_OR_ZERO , RB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , is8B , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- lfdx
2#1001110111# = > ( LDST , FPU , OP_LOAD , RA_OR_ZERO , RB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , is8B , '0' , '0' , '1' , '0' , '0' , '0' , NONE , '0' , '0' , DUPD ) , -- lfdux
2#1101010111# = > ( LDST , FPU , OP_LOAD , RA_OR_ZERO , RB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , is4B , '0' , '1' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- lfiwax
2#1101110111# = > ( LDST , FPU , OP_LOAD , RA_OR_ZERO , RB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , is4B , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- lfiwzx
2#1000010111# = > ( LDST , FPU , OP_LOAD , RA_OR_ZERO , RB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , is4B , '0' , '0' , '0' , '0' , '1' , '0' , NONE , '0' , '0' , NONE ) , -- lfsx
2#1000110111# = > ( LDST , FPU , OP_LOAD , RA_OR_ZERO , RB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , is4B , '0' , '0' , '1' , '0' , '1' , '0' , NONE , '0' , '0' , DUPD ) , -- lfsux
2#0001110100# = > ( LDST , NONE , OP_LOAD , RA_OR_ZERO , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , is2B , '0' , '0' , '0' , '1' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- lharx
2#0101110111# = > ( LDST , NONE , OP_LOAD , RA_OR_ZERO , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , is2B , '0' , '1' , '1' , '0' , '0' , '0' , NONE , '0' , '0' , DUPD ) , -- lhaux
2#0101010111# = > ( LDST , NONE , OP_LOAD , RA_OR_ZERO , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , is2B , '0' , '1' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- lhax
2#1100010110# = > ( LDST , NONE , OP_LOAD , RA_OR_ZERO , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , is2B , '1' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- lhbrx
2#1100110101# = > ( LDST , NONE , OP_LOAD , RA_OR_ZERO , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , is2B , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- lhzcix
2#0100110111# = > ( LDST , NONE , OP_LOAD , RA_OR_ZERO , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , is2B , '0' , '0' , '1' , '0' , '0' , '0' , NONE , '0' , '0' , DUPD ) , -- lhzux
2#0100010111# = > ( LDST , NONE , OP_LOAD , RA_OR_ZERO , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , is2B , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- lhzx
2#0000010100# = > ( LDST , NONE , OP_LOAD , RA_OR_ZERO , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , is4B , '0' , '0' , '0' , '1' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- lwarx
2#0101110101# = > ( LDST , NONE , OP_LOAD , RA_OR_ZERO , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , is4B , '0' , '1' , '1' , '0' , '0' , '0' , NONE , '0' , '0' , DUPD ) , -- lwaux
2#0101010101# = > ( LDST , NONE , OP_LOAD , RA_OR_ZERO , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , is4B , '0' , '1' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- lwax
2#1000010110# = > ( LDST , NONE , OP_LOAD , RA_OR_ZERO , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , is4B , '1' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- lwbrx
2#1100010101# = > ( LDST , NONE , OP_LOAD , RA_OR_ZERO , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , is4B , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- lwzcix
2#0000110111# = > ( LDST , NONE , OP_LOAD , RA_OR_ZERO , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , is4B , '0' , '0' , '1' , '0' , '0' , '0' , NONE , '0' , '0' , DUPD ) , -- lwzux
2#0000010111# = > ( LDST , NONE , OP_LOAD , RA_OR_ZERO , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , is4B , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- lwzx
2#1001000000# = > ( ALU , NONE , OP_MCRXRX , NONE , NONE , NONE , NONE , '0' , '1' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- mcrxrx
2#0000010011# = > ( ALU , NONE , OP_MFCR , NONE , NONE , NONE , RT , '1' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- mfcr/mfocrf
2#0001010011# = > ( ALU , NONE , OP_MFMSR , NONE , NONE , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '1' , NONE ) , -- mfmsr
2#0101010011# = > ( ALU , NONE , OP_MFSPR , NONE , NONE , RS , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- mfspr
2#0100001001# = > ( DVU , NONE , OP_MOD , RA , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- modud
2#0100001011# = > ( DVU , NONE , OP_MOD , RA , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '1' , '0' , NONE , '0' , '0' , NONE ) , -- moduw
2#1100001001# = > ( DVU , NONE , OP_MOD , RA , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '1' , NONE , '0' , '0' , NONE ) , -- modsd
2#1100001011# = > ( DVU , NONE , OP_MOD , RA , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '1' , '1' , NONE , '0' , '0' , NONE ) , -- modsw
2#0010010000# = > ( ALU , NONE , OP_MTCRF , NONE , NONE , RS , NONE , '0' , '1' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- mtcrf/mtocrf
decode1: Reduce number of single-issue instructions
This reduces the set of instructions marked as single-issue to just
attn and mtspr to "slow" SPRs (those that are not stored in the
register file).
The instructions that were previously single-issue are: isync, dcbf,
dcbst, dcbt, dcbtst, eieio, icbi, mfmsr, mtmsr, mtmsrd, mfspr to slow
SPRS, sync, tlbsync and wait. The synchronization instructions are
mostly no-ops anyway due to the in-order nature of the core, and the
cache-management instructions are unimplemented (except for icbi).
The MSR ops don't need to be single-issue due to the in-order core and
the fact that MSR updates are effective on the following instruction.
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
3 years ago
2#0010010010# = > ( ALU , NONE , OP_MTMSRD , NONE , NONE , RS , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '1' , '0' , NONE , '0' , '0' , NONE ) , -- mtmsr
2#0010110010# = > ( ALU , NONE , OP_MTMSRD , NONE , NONE , RS , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- mtmsrd # ignore top bits and d
2#0111010011# = > ( ALU , NONE , OP_MTSPR , NONE , NONE , RS , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- mtspr
2#0001001001# = > ( ALU , NONE , OP_MUL_H64 , RA , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '1' , RC , '0' , '0' , NONE ) , -- mulhd
2#0000001001# = > ( ALU , NONE , OP_MUL_H64 , RA , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- mulhdu
2#0001001011# = > ( ALU , NONE , OP_MUL_H32 , RA , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '1' , '1' , RC , '0' , '0' , NONE ) , -- mulhw
2#0000001011# = > ( ALU , NONE , OP_MUL_H32 , RA , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '1' , '0' , RC , '0' , '0' , NONE ) , -- mulhwu
-- next 4 have reserved bit set
2#1001001001# = > ( ALU , NONE , OP_MUL_H64 , RA , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '1' , RC , '0' , '0' , NONE ) , -- mulhd
2#1000001001# = > ( ALU , NONE , OP_MUL_H64 , RA , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- mulhdu
2#1001001011# = > ( ALU , NONE , OP_MUL_H32 , RA , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '1' , '1' , RC , '0' , '0' , NONE ) , -- mulhw
2#1000001011# = > ( ALU , NONE , OP_MUL_H32 , RA , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '1' , '0' , RC , '0' , '0' , NONE ) , -- mulhwu
2#0011101001# = > ( ALU , NONE , OP_MUL_L64 , RA , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '1' , RC , '0' , '0' , NONE ) , -- mulld
2#1011101001# = > ( ALU , NONE , OP_MUL_L64 , RA , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '1' , RC , '0' , '0' , NONE ) , -- mulldo
2#0011101011# = > ( ALU , NONE , OP_MUL_L64 , RA , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '1' , '1' , RC , '0' , '0' , NONE ) , -- mullw
2#1011101011# = > ( ALU , NONE , OP_MUL_L64 , RA , RB , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '1' , '1' , RC , '0' , '0' , NONE ) , -- mullwo
2#0111011100# = > ( ALU , NONE , OP_AND , NONE , RB , RS , RA , '0' , '0' , '0' , '1' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- nand
2#0001101000# = > ( ALU , NONE , OP_ADD , RA , NONE , NONE , RT , '0' , '0' , '1' , '0' , ONE , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- neg
2#1001101000# = > ( ALU , NONE , OP_ADD , RA , NONE , NONE , RT , '0' , '0' , '1' , '0' , ONE , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- nego
-- next 8 are reserved no-op instructions
2#1000010010# = > ( ALU , NONE , OP_NOP , NONE , NONE , NONE , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- nop
2#1000110010# = > ( ALU , NONE , OP_NOP , NONE , NONE , NONE , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- nop
2#1001010010# = > ( ALU , NONE , OP_NOP , NONE , NONE , NONE , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- nop
2#1001110010# = > ( ALU , NONE , OP_NOP , NONE , NONE , NONE , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- nop
2#1010010010# = > ( ALU , NONE , OP_NOP , NONE , NONE , NONE , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- nop
2#1010110010# = > ( ALU , NONE , OP_NOP , NONE , NONE , NONE , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- nop
2#1011010010# = > ( ALU , NONE , OP_NOP , NONE , NONE , NONE , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- nop
2#1011110010# = > ( ALU , NONE , OP_NOP , NONE , NONE , NONE , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- nop
2#0001111100# = > ( ALU , NONE , OP_OR , NONE , RB , RS , RA , '0' , '0' , '0' , '1' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- nor
2#0110111100# = > ( ALU , NONE , OP_OR , NONE , RB , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- or
2#0110011100# = > ( ALU , NONE , OP_OR , NONE , RB , RS , RA , '0' , '0' , '1' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- orc
2#0001111010# = > ( ALU , NONE , OP_POPCNT , NONE , NONE , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , is1B , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- popcntb
2#0111111010# = > ( ALU , NONE , OP_POPCNT , NONE , NONE , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , is8B , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- popcntd
2#0101111010# = > ( ALU , NONE , OP_POPCNT , NONE , NONE , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , is4B , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- popcntw
2#0010111010# = > ( ALU , NONE , OP_PRTY , NONE , NONE , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , is8B , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- prtyd
2#0010011010# = > ( ALU , NONE , OP_PRTY , NONE , NONE , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , is4B , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- prtyw
2#0010000000# = > ( ALU , NONE , OP_SETB , NONE , NONE , NONE , RT , '1' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- setb
2#0111110010# = > ( LDST , NONE , OP_TLBIE , NONE , NONE , NONE , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- slbia
2#0000011011# = > ( ALU , NONE , OP_SHL , NONE , RB , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- sld
2#0000011000# = > ( ALU , NONE , OP_SHL , NONE , RB , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '1' , '0' , RC , '0' , '0' , NONE ) , -- slw
2#1100011010# = > ( ALU , NONE , OP_SHR , NONE , RB , RS , RA , '0' , '0' , '0' , '0' , ZERO , '1' , NONE , '0' , '0' , '0' , '0' , '0' , '1' , RC , '0' , '0' , NONE ) , -- srad
2#1100111010# = > ( ALU , NONE , OP_SHR , NONE , CONST_SH , RS , RA , '0' , '0' , '0' , '0' , ZERO , '1' , NONE , '0' , '0' , '0' , '0' , '0' , '1' , RC , '0' , '0' , NONE ) , -- sradi
2#1100111011# = > ( ALU , NONE , OP_SHR , NONE , CONST_SH , RS , RA , '0' , '0' , '0' , '0' , ZERO , '1' , NONE , '0' , '0' , '0' , '0' , '0' , '1' , RC , '0' , '0' , NONE ) , -- sradi
2#1100011000# = > ( ALU , NONE , OP_SHR , NONE , RB , RS , RA , '0' , '0' , '0' , '0' , ZERO , '1' , NONE , '0' , '0' , '0' , '0' , '1' , '1' , RC , '0' , '0' , NONE ) , -- sraw
2#1100111000# = > ( ALU , NONE , OP_SHR , NONE , CONST_SH32 , RS , RA , '0' , '0' , '0' , '0' , ZERO , '1' , NONE , '0' , '0' , '0' , '0' , '1' , '1' , RC , '0' , '0' , NONE ) , -- srawi
2#1000011011# = > ( ALU , NONE , OP_SHR , NONE , RB , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- srd
2#1000011000# = > ( ALU , NONE , OP_SHR , NONE , RB , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '1' , '0' , RC , '0' , '0' , NONE ) , -- srw
2#1111010101# = > ( LDST , NONE , OP_STORE , RA_OR_ZERO , RB , RS , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , is1B , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- stbcix
2#1010110110# = > ( LDST , NONE , OP_STORE , RA_OR_ZERO , RB , RS , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , is1B , '0' , '0' , '0' , '1' , '0' , '0' , ONE , '0' , '0' , NONE ) , -- stbcx
2#0011110111# = > ( LDST , NONE , OP_STORE , RA_OR_ZERO , RB , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , is1B , '0' , '0' , '1' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- stbux
2#0011010111# = > ( LDST , NONE , OP_STORE , RA_OR_ZERO , RB , RS , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , is1B , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- stbx
2#1010010100# = > ( LDST , NONE , OP_STORE , RA_OR_ZERO , RB , RS , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , is8B , '1' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- stdbrx
2#1111110101# = > ( LDST , NONE , OP_STORE , RA_OR_ZERO , RB , RS , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , is8B , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- stdcix
2#0011010110# = > ( LDST , NONE , OP_STORE , RA_OR_ZERO , RB , RS , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , is8B , '0' , '0' , '0' , '1' , '0' , '0' , ONE , '0' , '0' , NONE ) , -- stdcx
2#0010110101# = > ( LDST , NONE , OP_STORE , RA_OR_ZERO , RB , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , is8B , '0' , '0' , '1' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- stdux
2#0010010101# = > ( LDST , NONE , OP_STORE , RA_OR_ZERO , RB , RS , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , is8B , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- stdx
2#1011010111# = > ( LDST , FPU , OP_STORE , RA_OR_ZERO , RB , FRS , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , is8B , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- stfdx
2#1011110111# = > ( LDST , FPU , OP_STORE , RA_OR_ZERO , RB , FRS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , is8B , '0' , '0' , '1' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- stfdux
2#1111010111# = > ( LDST , FPU , OP_STORE , RA_OR_ZERO , RB , FRS , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , is4B , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- stfiwx
2#1010010111# = > ( LDST , FPU , OP_STORE , RA_OR_ZERO , RB , FRS , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , is4B , '0' , '0' , '0' , '0' , '1' , '0' , NONE , '0' , '0' , NONE ) , -- stfsx
2#1010110111# = > ( LDST , FPU , OP_STORE , RA_OR_ZERO , RB , FRS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , is4B , '0' , '0' , '1' , '0' , '1' , '0' , NONE , '0' , '0' , NONE ) , -- stfsux
2#1110010110# = > ( LDST , NONE , OP_STORE , RA_OR_ZERO , RB , RS , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , is2B , '1' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- sthbrx
2#1110110101# = > ( LDST , NONE , OP_STORE , RA_OR_ZERO , RB , RS , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , is2B , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- sthcix
2#1011010110# = > ( LDST , NONE , OP_STORE , RA_OR_ZERO , RB , RS , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , is2B , '0' , '0' , '0' , '1' , '0' , '0' , ONE , '0' , '0' , NONE ) , -- sthcx
2#0110110111# = > ( LDST , NONE , OP_STORE , RA_OR_ZERO , RB , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , is2B , '0' , '0' , '1' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- sthux
2#0110010111# = > ( LDST , NONE , OP_STORE , RA_OR_ZERO , RB , RS , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , is2B , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- sthx
2#1010010110# = > ( LDST , NONE , OP_STORE , RA_OR_ZERO , RB , RS , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , is4B , '1' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- stwbrx
2#1110010101# = > ( LDST , NONE , OP_STORE , RA_OR_ZERO , RB , RS , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , is4B , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- stwcix
2#0010010110# = > ( LDST , NONE , OP_STORE , RA_OR_ZERO , RB , RS , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , is4B , '0' , '0' , '0' , '1' , '0' , '0' , ONE , '0' , '0' , NONE ) , -- stwcx
2#0010110111# = > ( LDST , NONE , OP_STORE , RA_OR_ZERO , RB , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , is4B , '0' , '0' , '1' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- stwux
2#0010010111# = > ( LDST , NONE , OP_STORE , RA_OR_ZERO , RB , RS , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , is4B , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- stwx
2#0000101000# = > ( ALU , NONE , OP_ADD , RA , RB , NONE , RT , '0' , '0' , '1' , '0' , ONE , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- subf
2#1000101000# = > ( ALU , NONE , OP_ADD , RA , RB , NONE , RT , '0' , '0' , '1' , '0' , ONE , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- subfo
2#0000001000# = > ( ALU , NONE , OP_ADD , RA , RB , NONE , RT , '0' , '0' , '1' , '0' , ONE , '1' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- subfc
2#1000001000# = > ( ALU , NONE , OP_ADD , RA , RB , NONE , RT , '0' , '0' , '1' , '0' , ONE , '1' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- subfco
2#0010001000# = > ( ALU , NONE , OP_ADD , RA , RB , NONE , RT , '0' , '0' , '1' , '0' , CA , '1' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- subfe
2#1010001000# = > ( ALU , NONE , OP_ADD , RA , RB , NONE , RT , '0' , '0' , '1' , '0' , CA , '1' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- subfeo
2#0011101000# = > ( ALU , NONE , OP_ADD , RA , CONST_M1 , NONE , RT , '0' , '0' , '1' , '0' , CA , '1' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- subfme
2#1011101000# = > ( ALU , NONE , OP_ADD , RA , CONST_M1 , NONE , RT , '0' , '0' , '1' , '0' , CA , '1' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- subfmeo
2#0011001000# = > ( ALU , NONE , OP_ADD , RA , NONE , NONE , RT , '0' , '0' , '1' , '0' , CA , '1' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- subfze
2#1011001000# = > ( ALU , NONE , OP_ADD , RA , NONE , NONE , RT , '0' , '0' , '1' , '0' , CA , '1' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- subfzeo
decode1: Reduce number of single-issue instructions
This reduces the set of instructions marked as single-issue to just
attn and mtspr to "slow" SPRs (those that are not stored in the
register file).
The instructions that were previously single-issue are: isync, dcbf,
dcbst, dcbt, dcbtst, eieio, icbi, mfmsr, mtmsr, mtmsrd, mfspr to slow
SPRS, sync, tlbsync and wait. The synchronization instructions are
mostly no-ops anyway due to the in-order nature of the core, and the
cache-management instructions are unimplemented (except for icbi).
The MSR ops don't need to be single-issue due to the in-order core and
the fact that MSR updates are effective on the following instruction.
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
3 years ago
2#1001010110# = > ( ALU , NONE , OP_NOP , NONE , NONE , NONE , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- sync
2#0001000100# = > ( ALU , NONE , OP_TRAP , RA , RB , NONE , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- td
2#0000000100# = > ( ALU , NONE , OP_TRAP , RA , RB , NONE , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '1' , '0' , NONE , '0' , '0' , NONE ) , -- tw
2#0100110010# = > ( LDST , NONE , OP_TLBIE , NONE , RB , RS , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- tlbie
2#0100010010# = > ( LDST , NONE , OP_TLBIE , NONE , RB , RS , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- tlbiel
decode1: Reduce number of single-issue instructions
This reduces the set of instructions marked as single-issue to just
attn and mtspr to "slow" SPRs (those that are not stored in the
register file).
The instructions that were previously single-issue are: isync, dcbf,
dcbst, dcbt, dcbtst, eieio, icbi, mfmsr, mtmsr, mtmsrd, mfspr to slow
SPRS, sync, tlbsync and wait. The synchronization instructions are
mostly no-ops anyway due to the in-order nature of the core, and the
cache-management instructions are unimplemented (except for icbi).
The MSR ops don't need to be single-issue due to the in-order core and
the fact that MSR updates are effective on the following instruction.
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
3 years ago
2#1000110110# = > ( ALU , NONE , OP_NOP , NONE , NONE , NONE , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- tlbsync
2#0000011110# = > ( ALU , NONE , OP_NOP , NONE , NONE , NONE , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- wait
2#0100111100# = > ( ALU , NONE , OP_XOR , NONE , RB , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- xor
others = > illegal_inst
) ;
constant decode_op_58_array : minor_rom_array_2_t : = (
-- unit fac internal in1 in2 in3 out CR CR inv inv cry cry ldst BR sgn upd rsrv 32b sgn rc lk sgl rpt
-- op in out A out in out len ext pipe
0 = > ( LDST , NONE , OP_LOAD , RA_OR_ZERO , CONST_DS , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , is8B , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- ld
1 = > ( LDST , NONE , OP_LOAD , RA_OR_ZERO , CONST_DS , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , is8B , '0' , '0' , '1' , '0' , '0' , '0' , NONE , '0' , '0' , DUPD ) , -- ldu
2 = > ( LDST , NONE , OP_LOAD , RA_OR_ZERO , CONST_DS , NONE , RT , '0' , '0' , '0' , '0' , ZERO , '0' , is4B , '0' , '1' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- lwa
others = > decode_rom_init
) ;
FPU: Implement floating convert from integer instructions
This implements fcfid, fcfidu, fcfids and fcfidus, which convert
64-bit integer values in an FPR into a floating-point value.
This brings in a lot of the datapath that will be needed in
future, including the shifter, adder, mask generator and
count-leading-zeroes logic, along with the machinery for rounding
to single-precision or double-precision, detecting inexact results,
signalling inexact-result exceptions, and updating result flags
in the FPSCR.
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
5 years ago
constant decode_op_59_array : op_59_subop_array_t : = (
-- unit fac internal in1 in2 in3 out CR CR inv inv cry cry ldst BR sgn upd rsrv 32b sgn rc lk sgl rpt
-- op in out A out in out len ext pipe
2#01110# = > ( FPU , FPU , OP_FPOP_I , NONE , FRB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '1' , '0' , RC , '0' , '0' , NONE ) , -- fcfid[u]s
2#10010# = > ( FPU , FPU , OP_FPOP , FRA , FRB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '1' , '0' , RC , '0' , '0' , NONE ) , -- fdivs
2#10100# = > ( FPU , FPU , OP_FPOP , FRA , FRB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '1' , '0' , RC , '0' , '0' , NONE ) , -- fsubs
2#10101# = > ( FPU , FPU , OP_FPOP , FRA , FRB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '1' , '0' , RC , '0' , '0' , NONE ) , -- fadds
2#10110# = > ( FPU , FPU , OP_FPOP , NONE , FRB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '1' , '0' , RC , '0' , '0' , NONE ) , -- fsqrts
2#11000# = > ( FPU , FPU , OP_FPOP , NONE , FRB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '1' , '0' , RC , '0' , '0' , NONE ) , -- fres
2#11001# = > ( FPU , FPU , OP_FPOP , FRA , NONE , FRC , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '1' , '0' , RC , '0' , '0' , NONE ) , -- fmuls
2#11010# = > ( FPU , FPU , OP_FPOP , NONE , FRB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '1' , '0' , RC , '0' , '0' , NONE ) , -- frsqrtes
2#11100# = > ( FPU , FPU , OP_FPOP , FRA , FRB , FRC , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '1' , '0' , RC , '0' , '0' , NONE ) , -- fmsubs
2#11101# = > ( FPU , FPU , OP_FPOP , FRA , FRB , FRC , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '1' , '0' , RC , '0' , '0' , NONE ) , -- fmadds
2#11110# = > ( FPU , FPU , OP_FPOP , FRA , FRB , FRC , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '1' , '0' , RC , '0' , '0' , NONE ) , -- fnmsubs
2#11111# = > ( FPU , FPU , OP_FPOP , FRA , FRB , FRC , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '1' , '0' , RC , '0' , '0' , NONE ) , -- fnmadds
FPU: Implement floating convert from integer instructions
This implements fcfid, fcfidu, fcfids and fcfidus, which convert
64-bit integer values in an FPR into a floating-point value.
This brings in a lot of the datapath that will be needed in
future, including the shifter, adder, mask generator and
count-leading-zeroes logic, along with the machinery for rounding
to single-precision or double-precision, detecting inexact results,
signalling inexact-result exceptions, and updating result flags
in the FPSCR.
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
5 years ago
others = > illegal_inst
) ;
constant decode_op_62_array : minor_rom_array_2_t : = (
-- unit fac internal in1 in2 in3 out CR CR inv inv cry cry ldst BR sgn upd rsrv 32b sgn rc lk sgl rpt
-- op in out A out in out len ext pipe
0 = > ( LDST , NONE , OP_STORE , RA_OR_ZERO , CONST_DS , RS , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , is8B , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- std
1 = > ( LDST , NONE , OP_STORE , RA_OR_ZERO , CONST_DS , RS , RA , '0' , '0' , '0' , '0' , ZERO , '0' , is8B , '0' , '0' , '1' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- stdu
others = > decode_rom_init
) ;
-- indexed by bits 4..1 and 10..6 of instruction word
constant decode_op_63l_array : op_63_subop_array_0_t : = (
-- unit fac internal in1 in2 in3 out CR CR inv inv cry cry ldst BR sgn upd rsrv 32b sgn rc lk sgl rpt
-- op in out A out in out len ext pipe
2#000000000# = > ( FPU , FPU , OP_FPOP , FRA , FRB , NONE , NONE , '0' , '1' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- 0/0=fcmpu
2#000000001# = > ( FPU , FPU , OP_FPOP , FRA , FRB , NONE , NONE , '0' , '1' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- 1/0=fcmpo
2#000000010# = > ( FPU , FPU , OP_FPOP , NONE , NONE , NONE , NONE , '0' , '1' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- 2/0=mcrfs
2#000000100# = > ( FPU , FPU , OP_FPOP , FRA , FRB , NONE , NONE , '0' , '1' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- 4/0=ftdiv
2#000000101# = > ( FPU , FPU , OP_FPOP , NONE , FRB , NONE , NONE , '0' , '1' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- 5/0=ftsqrt
2#011000001# = > ( FPU , FPU , OP_FPOP , NONE , NONE , NONE , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- 1/6=mtfsb1
2#011000010# = > ( FPU , FPU , OP_FPOP , NONE , NONE , NONE , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- 2/6=mtfsb0
2#011000100# = > ( FPU , FPU , OP_FPOP , NONE , NONE , NONE , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- 4/6=mtfsfi
2#011011010# = > ( FPU , FPU , OP_FPOP_I , FRA , FRB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- 26/6=fmrgow
2#011011110# = > ( FPU , FPU , OP_FPOP_I , FRA , FRB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) , -- 30/6=fmrgew
2#011110010# = > ( FPU , FPU , OP_FPOP_I , NONE , FRB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- 18/7=mffs family
2#011110110# = > ( FPU , FPU , OP_FPOP_I , NONE , FRB , NONE , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- 22/7=mtfsf
2#100000000# = > ( FPU , FPU , OP_FPOP , FRA , FRB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- 0/8=fcpsgn
2#100000001# = > ( FPU , FPU , OP_FPOP , NONE , FRB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- 1/8=fneg
2#100000010# = > ( FPU , FPU , OP_FPOP , NONE , FRB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- 2/8=fmr
2#100000100# = > ( FPU , FPU , OP_FPOP , NONE , FRB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- 4/8=fnabs
2#100001000# = > ( FPU , FPU , OP_FPOP , NONE , FRB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- 8/8=fabs
2#100001100# = > ( FPU , FPU , OP_FPOP , NONE , FRB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- 12/8=frin
2#100001101# = > ( FPU , FPU , OP_FPOP , NONE , FRB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- 13/8=friz
2#100001110# = > ( FPU , FPU , OP_FPOP , NONE , FRB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- 14/8=frip
2#100001111# = > ( FPU , FPU , OP_FPOP , NONE , FRB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- 15/8=frim
2#110000000# = > ( FPU , FPU , OP_FPOP , NONE , FRB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '1' , '0' , RC , '0' , '0' , NONE ) , -- 0/12=frsp
2#111000000# = > ( FPU , FPU , OP_FPOP , NONE , FRB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- 0/14=fctiw
2#111000100# = > ( FPU , FPU , OP_FPOP , NONE , FRB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- 4/14=fctiwu
2#111011001# = > ( FPU , FPU , OP_FPOP , NONE , FRB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- 25/14=fctid
2#111011010# = > ( FPU , FPU , OP_FPOP_I , NONE , FRB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- 26/14=fcfid
2#111011101# = > ( FPU , FPU , OP_FPOP , NONE , FRB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- 29/14=fctidu
2#111011110# = > ( FPU , FPU , OP_FPOP_I , NONE , FRB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- 30/14=fcfidu
2#111100000# = > ( FPU , FPU , OP_FPOP , NONE , FRB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- 0/15=fctiwz
2#111100100# = > ( FPU , FPU , OP_FPOP , NONE , FRB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- 4/15=fctiwuz
2#111111001# = > ( FPU , FPU , OP_FPOP , NONE , FRB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- 25/15=fctidz
2#111111101# = > ( FPU , FPU , OP_FPOP , NONE , FRB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- 29/15=fctiduz
others = > illegal_inst
) ;
-- indexed by bits 4..1 of instruction word
constant decode_op_63h_array : op_63_subop_array_1_t : = (
-- unit fac internal in1 in2 in3 out CR CR inv inv cry cry ldst BR sgn upd rsrv 32b sgn rc lk sgl rpt
-- op in out A out in out len ext pipe
2#0010# = > ( FPU , FPU , OP_FPOP , FRA , FRB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- fdiv
2#0100# = > ( FPU , FPU , OP_FPOP , FRA , FRB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- fsub
2#0101# = > ( FPU , FPU , OP_FPOP , FRA , FRB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- fadd
2#0110# = > ( FPU , FPU , OP_FPOP , NONE , FRB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- fsqrt
2#0111# = > ( FPU , FPU , OP_FPOP , FRA , FRB , FRC , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- fsel
2#1000# = > ( FPU , FPU , OP_FPOP , NONE , FRB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- fre
2#1001# = > ( FPU , FPU , OP_FPOP , FRA , NONE , FRC , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- fmul
2#1010# = > ( FPU , FPU , OP_FPOP , NONE , FRB , NONE , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- frsqrte
2#1100# = > ( FPU , FPU , OP_FPOP , FRA , FRB , FRC , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- fmsub
2#1101# = > ( FPU , FPU , OP_FPOP , FRA , FRB , FRC , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- fmadd
2#1110# = > ( FPU , FPU , OP_FPOP , FRA , FRB , FRC , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- fnmsub
2#1111# = > ( FPU , FPU , OP_FPOP , FRA , FRB , FRC , FRT , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , RC , '0' , '0' , NONE ) , -- fnmadd
others = > illegal_inst
) ;
-- unit fac internal in1 in2 in3 out CR CR inv inv cry cry ldst BR sgn upd rsrv 32b sgn rc lk sgl rpt
-- op in out A out in out len ext pipe
constant nop_instr : decode_rom_t : = ( ALU , NONE , OP_NOP , NONE , NONE , NONE , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) ;
constant fetch_fail_inst : decode_rom_t : = ( LDST , NONE , OP_FETCH_FAILED , NONE , NONE , NONE , NONE , '0' , '0' , '0' , '0' , ZERO , '0' , NONE , '0' , '0' , '0' , '0' , '0' , '0' , NONE , '0' , '0' , NONE ) ;
function decode_ram_spr ( sprn : spr_num_t ) return ram_spr_info is
variable ret : ram_spr_info ;
begin
ret : = ( index = > ( others = > '0' ) , isodd = > '0' , valid = > '1' ) ;
case sprn is
when SPR_LR = >
ret . index : = RAMSPR_LR ;
when SPR_CTR = >
ret . index : = RAMSPR_CTR ;
ret . isodd : = '1' ;
when SPR_TAR = >
ret . index : = RAMSPR_TAR ;
when SPR_SRR0 = >
ret . index : = RAMSPR_SRR0 ;
when SPR_SRR1 = >
ret . index : = RAMSPR_SRR1 ;
ret . isodd : = '1' ;
when SPR_HSRR0 = >
ret . index : = RAMSPR_HSRR0 ;
when SPR_HSRR1 = >
ret . index : = RAMSPR_HSRR1 ;
ret . isodd : = '1' ;
when SPR_SPRG0 = >
ret . index : = RAMSPR_SPRG0 ;
when SPR_SPRG1 = >
ret . index : = RAMSPR_SPRG1 ;
ret . isodd : = '1' ;
when SPR_SPRG2 = >
ret . index : = RAMSPR_SPRG2 ;
when SPR_SPRG3 | SPR_SPRG3U = >
ret . index : = RAMSPR_SPRG3 ;
ret . isodd : = '1' ;
when SPR_HSPRG0 = >
ret . index : = RAMSPR_HSPRG0 ;
when SPR_HSPRG1 = >
ret . index : = RAMSPR_HSPRG1 ;
ret . isodd : = '1' ;
when others = >
ret . valid : = '0' ;
end case ;
return ret ;
end ;
function map_spr ( sprn : spr_num_t ) return spr_id is
variable i : spr_id ;
begin
i . sel : = "000" ;
i . valid : = '1' ;
i . ispmu : = '0' ;
case sprn is
when SPR_TB = >
i . sel : = SPRSEL_TB ;
when SPR_TBU = >
i . sel : = SPRSEL_TBU ;
when SPR_DEC = >
i . sel : = SPRSEL_DEC ;
when SPR_PVR = >
i . sel : = SPRSEL_PVR ;
when 724 = > -- LOG_ADDR SPR
i . sel : = SPRSEL_LOGA ;
when 725 = > -- LOG_DATA SPR
i . sel : = SPRSEL_LOGD ;
when SPR_UPMC1 | SPR_UPMC2 | SPR_UPMC3 | SPR_UPMC4 | SPR_UPMC5 | SPR_UPMC6 |
SPR_UMMCR0 | SPR_UMMCR1 | SPR_UMMCR2 | SPR_UMMCRA | SPR_USIER | SPR_USIAR | SPR_USDAR |
SPR_PMC1 | SPR_PMC2 | SPR_PMC3 | SPR_PMC4 | SPR_PMC5 | SPR_PMC6 |
SPR_MMCR0 | SPR_MMCR1 | SPR_MMCR2 | SPR_MMCRA | SPR_SIER | SPR_SIAR | SPR_SDAR = >
i . ispmu : = '1' ;
when SPR_CFAR = >
i . sel : = SPRSEL_CFAR ;
when SPR_XER = >
i . sel : = SPRSEL_XER ;
when others = >
i . valid : = '0' ;
end case ;
return i ;
end ;
begin
decode1_0 : process ( clk )
begin
if rising_edge ( clk ) then
if rst = '1' then
r < = Decode1ToDecode2Init ;
ri < = reg_internal_t_init ;
elsif flush_in = '1' then
r . valid < = '0' ;
elsif stall_in = '0' then
r < = rin ;
ri < = ri_in ;
end if ;
if rst = '1' then
br . br_nia < = ( others = > '0' ) ;
br . br_offset < = ( others = > '0' ) ;
br . predict < = '0' ;
else
br < = br_in ;
end if ;
end if ;
end process ;
busy_out < = stall_in ;
decode1_1 : process ( all )
variable v : Decode1ToDecode2Type ;
variable vr : Decode1ToRegisterFileType ;
variable vi : reg_internal_t ;
variable majorop : major_opcode_t ;
variable minor4op : std_ulogic_vector ( 10 downto 0 ) ;
variable op_19_bits : std_ulogic_vector ( 2 downto 0 ) ;
variable sprn : spr_num_t ;
variable br_target : std_ulogic_vector ( 61 downto 0 ) ;
variable br_offset : signed ( 23 downto 0 ) ;
variable bv : br_predictor_t ;
variable fprs , fprabc : std_ulogic ;
variable in3rc : std_ulogic ;
variable may_read_rb : std_ulogic ;
begin
v : = Decode1ToDecode2Init ;
vi : = reg_internal_t_init ;
v . valid : = f_in . valid ;
v . nia : = f_in . nia ;
v . insn : = f_in . insn ;
v . stop_mark : = f_in . stop_mark ;
core: Implement quadword loads and stores
This implements the lq, stq, lqarx and stqcx. instructions.
These instructions all access two consecutive GPRs; for example the
"lq %r6,0(%r3)" instruction will load the doubleword at the address
in R3 into R7 and the doubleword at address R3 + 8 into R6. To cope
with having two GPR sources or destinations, the instruction gets
repeated at the decode2 stage, that is, for each lq/stq/lqarx/stqcx.
coming in from decode1, two instructions get sent out to execute1.
For these instructions, the RS or RT register gets modified on one
of the iterations by setting the LSB of the register number. In LE
mode, the first iteration uses RS|1 or RT|1 and the second iteration
uses RS or RT. In BE mode, this is done the other way around. In
order for decode2 to know what endianness is currently in use, we
pass the big_endian flag down from icache through decode1 to decode2.
This is always in sync with what execute1 is using because only rfid
or an interrupt can change MSR[LE], and those operations all cause
a flush and redirect.
There is now an extra column in the decode tables in decode1 to
indicate whether the instruction needs to be repeated. Decode1 also
enforces the rule that lq with RT = RT and lqarx with RA = RT or
RB = RT are illegal.
Decode2 now passes a 'repeat' flag and a 'second' flag to execute1,
and execute1 passes them on to loadstore1. The 'repeat' flag is set
for both iterations of a repeated instruction, and 'second' is set
on the second iteration. Execute1 does not take asynchronous or
trace interrupts on the second iteration of a repeated instruction.
Loadstore1 uses 'next_addr' for the second iteration of a repeated
load/store so that we access the second doubleword of the memory
operand. Thus loadstore1 accesses the doublewords in increasing
memory order. For 16-byte loads this means that the first iteration
writes GPR RT|1. It is possible that RA = RT|1 (this is a legal
but non-preferred form), meaning that if the memory operand was
misaligned, the first iteration would overwrite RA but then the
second iteration might take a page fault, leading to corrupted state.
To avoid that possibility, 16-byte loads in LE mode take an
alignment interrupt if the operand is not 16-byte aligned. (This
is the case anyway for lqarx, and we enforce it for lq as well.)
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
4 years ago
v . big_endian : = f_in . big_endian ;
fprs : = '0' ;
fprabc : = '0' ;
in3rc : = '0' ;
may_read_rb : = '0' ;
if f_in . valid = '1' then
report "Decode insn " & to_hstring ( f_in . insn ) & " at " & to_hstring ( f_in . nia ) ;
end if ;
br_offset : = ( others = > '0' ) ;
majorop : = unsigned ( f_in . insn ( 31 downto 26 ) ) ;
if is_X ( majorop ) then
v . decode : = x_inst ;
else
v . decode : = major_decode_rom_array ( to_integer ( majorop ) ) ;
end if ;
if is_X ( f_in . insn ) then
v . spr_info : = ( sel = > "XXX" , others = > 'X' ) ;
v . ram_spr : = ( index = > ( others = > 'X' ) , others = > 'X' ) ;
else
sprn : = decode_spr_num ( f_in . insn ) ;
v . spr_info : = map_spr ( sprn ) ;
v . ram_spr : = decode_ram_spr ( sprn ) ;
end if ;
case unsigned ( majorop ) is
when "000100" = > -- 4
-- major opcode 4, mostly VMX/VSX stuff but also some integer ops (madd*)
minor4op : = f_in . insn ( 5 downto 0 ) & f_in . insn ( 10 downto 6 ) ;
vi . override : = not decode_op_4_valid ( to_integer ( unsigned ( minor4op ) ) ) ;
v . decode : = decode_op_4_array ( to_integer ( unsigned ( f_in . insn ( 5 downto 0 ) ) ) ) ;
in3rc : = '1' ;
may_read_rb : = '1' ;
when "010111" = > -- 23
-- rlwnm[.]
may_read_rb : = '1' ;
when "011111" = > -- 31
-- major opcode 31, lots of things
if is_X ( f_in . insn ) then
v . decode : = x_inst ;
else
v . decode : = decode_op_31_array ( to_integer ( unsigned ( f_in . insn ( 10 downto 1 ) ) ) ) ;
end if ;
may_read_rb : = '1' ;
if std_match ( f_in . insn ( 10 downto 1 ) , "01-1010011" ) then
-- mfspr or mtspr
-- Make mtspr to slow SPRs single issue
if v . spr_info . valid = '1' then
decode1: Reduce number of single-issue instructions
This reduces the set of instructions marked as single-issue to just
attn and mtspr to "slow" SPRs (those that are not stored in the
register file).
The instructions that were previously single-issue are: isync, dcbf,
dcbst, dcbt, dcbtst, eieio, icbi, mfmsr, mtmsr, mtmsrd, mfspr to slow
SPRS, sync, tlbsync and wait. The synchronization instructions are
mostly no-ops anyway due to the in-order nature of the core, and the
cache-management instructions are unimplemented (except for icbi).
The MSR ops don't need to be single-issue due to the in-order core and
the fact that MSR updates are effective on the following instruction.
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
3 years ago
vi . force_single : = f_in . insn ( 8 ) ;
end if ;
-- send MMU-related SPRs to loadstore1
case sprn is
when SPR_DAR | SPR_DSISR | SPR_PID | SPR_PTCR = >
vi . override_decode . unit : = LDST ;
vi . override_unit : = '1' ;
-- make mtspr to loadstore SPRs single-issue
if f_in . insn ( 8 ) = '1' then
vi . force_single : = '1' ;
end if ;
when others = >
end case ;
-- FIXME: This is a bit fragile doing this here but sprn depends
-- on f_in.insn
if is_X ( f_in . insn ) then
vi . override_decode . unit : = NONE ;
vi . override_unit : = 'X' ;
vi . force_single : = 'X' ;
end if ;
end if ;
if HAS_FPU and std_match ( f_in . insn ( 10 downto 1 ) , "1----10111" ) then
-- lower half of column 23 has FP loads and stores
fprs : = '1' ;
end if ;
when "010000" = > -- 16
-- Predict backward branches as taken, forward as untaken
v . br_pred : = f_in . insn ( 15 ) ;
br_offset : = resize ( signed ( f_in . insn ( 15 downto 2 ) ) , 24 ) ;
when "010010" = > -- 18
-- Unconditional branches are always taken
v . br_pred : = '1' ;
br_offset : = signed ( f_in . insn ( 25 downto 2 ) ) ;
when "010011" = > -- 19
if is_X ( f_in . insn ) then
vi . override : = 'X' ;
else
vi . override : = not decode_op_19_valid ( to_integer ( unsigned ( f_in . insn ( 5 downto 1 ) & f_in . insn ( 10 downto 6 ) ) ) ) ;
end if ;
op_19_bits : = f_in . insn ( 5 ) & f_in . insn ( 3 ) & f_in . insn ( 2 ) ;
if is_X ( op_19_bits ) then
v . decode : = x_inst ;
else
v . decode : = decode_op_19_array ( to_integer ( unsigned ( op_19_bits ) ) ) ;
end if ;
when "011000" = > -- 24
-- ori, special-case the standard NOP
if std_match ( f_in . insn , "01100000000000000000000000000000" ) then
report "PPC_nop" ;
vi . override : = '1' ;
vi . override_decode : = nop_instr ;
end if ;
when "011110" = > -- 30
if is_X ( f_in . insn ) then
v . decode : = x_inst ;
else
v . decode : = decode_op_30_array ( to_integer ( unsigned ( f_in . insn ( 4 downto 1 ) ) ) ) ;
end if ;
may_read_rb : = f_in . insn ( 4 ) ;
when "110100" | "110101" | "110110" | "110111" = > -- 52, 53, 54, 55
-- stfd[u] and stfs[u]
if HAS_FPU then
fprs : = '1' ;
end if ;
when "111010" = > -- 58
if is_X ( f_in . insn ) then
v . decode : = x_inst ;
else
v . decode : = decode_op_58_array ( to_integer ( unsigned ( f_in . insn ( 1 downto 0 ) ) ) ) ;
end if ;
when "111011" = > -- 59
FPU: Implement floating convert from integer instructions
This implements fcfid, fcfidu, fcfids and fcfidus, which convert
64-bit integer values in an FPR into a floating-point value.
This brings in a lot of the datapath that will be needed in
future, including the shifter, adder, mask generator and
count-leading-zeroes logic, along with the machinery for rounding
to single-precision or double-precision, detecting inexact results,
signalling inexact-result exceptions, and updating result flags
in the FPSCR.
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
5 years ago
if HAS_FPU then
-- floating point operations, mostly single-precision
if is_X ( f_in . insn ) then
v . decode : = x_inst ;
else
v . decode : = decode_op_59_array ( to_integer ( unsigned ( f_in . insn ( 5 downto 1 ) ) ) ) ;
end if ;
FPU: Implement floating convert from integer instructions
This implements fcfid, fcfidu, fcfids and fcfidus, which convert
64-bit integer values in an FPR into a floating-point value.
This brings in a lot of the datapath that will be needed in
future, including the shifter, adder, mask generator and
count-leading-zeroes logic, along with the machinery for rounding
to single-precision or double-precision, detecting inexact results,
signalling inexact-result exceptions, and updating result flags
in the FPSCR.
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
5 years ago
if f_in . insn ( 5 ) = '0' and not std_match ( f_in . insn ( 10 downto 1 ) , "11-1001110" ) then
vi . override : = '1' ;
end if ;
in3rc : = '1' ;
fprabc : = '1' ;
fprs : = '1' ;
may_read_rb : = '1' ;
FPU: Implement floating convert from integer instructions
This implements fcfid, fcfidu, fcfids and fcfidus, which convert
64-bit integer values in an FPR into a floating-point value.
This brings in a lot of the datapath that will be needed in
future, including the shifter, adder, mask generator and
count-leading-zeroes logic, along with the machinery for rounding
to single-precision or double-precision, detecting inexact results,
signalling inexact-result exceptions, and updating result flags
in the FPSCR.
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
5 years ago
end if ;
when "111110" = > -- 62
if is_X ( f_in . insn ) then
v . decode : = x_inst ;
else
v . decode : = decode_op_62_array ( to_integer ( unsigned ( f_in . insn ( 1 downto 0 ) ) ) ) ;
end if ;
when "111111" = > -- 63
if HAS_FPU then
-- floating point operations, general and double-precision
if is_X ( f_in . insn ) then
v . decode : = x_inst ;
elsif f_in . insn ( 5 ) = '0' then
v . decode : = decode_op_63l_array ( to_integer ( unsigned ( f_in . insn ( 4 downto 1 ) & f_in . insn ( 10 downto 6 ) ) ) ) ;
else
v . decode : = decode_op_63h_array ( to_integer ( unsigned ( f_in . insn ( 4 downto 1 ) ) ) ) ;
end if ;
in3rc : = '1' ;
fprabc : = '1' ;
fprs : = '1' ;
may_read_rb : = '1' ;
end if ;
when others = >
end case ;
-- Work out GPR/FPR read addresses
vr . reg_1_addr : = fprabc & insn_ra ( f_in . insn ) ;
vr . reg_2_addr : = fprabc & insn_rb ( f_in . insn ) ;
if in3rc = '1' then
vr . reg_3_addr : = fprabc & insn_rcreg ( f_in . insn ) ;
else
vr . reg_3_addr : = fprs & insn_rs ( f_in . insn ) ;
end if ;
vr . read_1_enable : = f_in . valid and not f_in . fetch_failed ;
vr . read_2_enable : = f_in . valid and not f_in . fetch_failed and may_read_rb ;
vr . read_3_enable : = f_in . valid and not f_in . fetch_failed ;
v . reg_a : = vr . reg_1_addr ;
v . reg_b : = vr . reg_2_addr ;
v . reg_c : = vr . reg_3_addr ;
if f_in . fetch_failed = '1' then
v . valid : = '1' ;
vi . override : = '1' ;
vi . override_decode : = fetch_fail_inst ;
-- Only send down a single OP_FETCH_FAILED
if ri . override = '1' and ri . override_decode . insn_type = OP_FETCH_FAILED then
v . valid : = '0' ;
end if ;
end if ;
-- Branch predictor
-- Note bclr, bcctr and bctar are predicted not taken as we have no
-- count cache or link stack.
bv . br_nia : = f_in . nia ( 63 downto 2 ) ;
if f_in . insn ( 1 ) = '1' then
bv . br_nia : = ( others = > '0' ) ;
end if ;
bv . br_offset : = br_offset ;
fetch1: Implement a simple branch target cache
This implements a cache in fetch1, where each entry stores the address
of a simple branch instruction (b or bc) and the target of the branch.
When fetching sequentially, if the address being fetched matches the
cache entry, then fetching will be redirected to the branch target.
The cache has 1024 entries and is direct-mapped, i.e. indexed by bits
11..2 of the NIA.
The bus from execute1 now carries information about taken and
not-taken simple branches, which fetch1 uses to update the cache.
The cache entry is updated for both taken and not-taken branches, with
the valid bit being set if the branch was taken and cleared if the
branch was not taken.
If fetching is redirected to the branch target then that goes down the
pipe as a predicted-taken branch, and decode1 does not do any static
branch prediction. If fetching is not redirected, then the next
instruction goes down the pipe as normal and decode1 does its static
branch prediction.
In order to make timing, the lookup of the cache is pipelined, so on
each cycle the cache entry for the current NIA + 8 is read. This
means that after a redirect (from decode1 or execute1), only the third
and subsequent sequentially-fetched instructions will be able to be
predicted.
This improves the coremark value on the Arty A7-100 from about 180 to
about 190 (more than 5%).
The BTC is optional. Builds for the Artix 7 35-T part have it off by
default because the extra ~1420 LUTs it takes mean that the design
doesn't fit on the Arty A7-35 board.
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
4 years ago
if f_in . next_predicted = '1' then
v . br_pred : = '1' ;
elsif f_in . next_pred_ntaken = '1' then
v . br_pred : = '0' ;
fetch1: Implement a simple branch target cache
This implements a cache in fetch1, where each entry stores the address
of a simple branch instruction (b or bc) and the target of the branch.
When fetching sequentially, if the address being fetched matches the
cache entry, then fetching will be redirected to the branch target.
The cache has 1024 entries and is direct-mapped, i.e. indexed by bits
11..2 of the NIA.
The bus from execute1 now carries information about taken and
not-taken simple branches, which fetch1 uses to update the cache.
The cache entry is updated for both taken and not-taken branches, with
the valid bit being set if the branch was taken and cleared if the
branch was not taken.
If fetching is redirected to the branch target then that goes down the
pipe as a predicted-taken branch, and decode1 does not do any static
branch prediction. If fetching is not redirected, then the next
instruction goes down the pipe as normal and decode1 does its static
branch prediction.
In order to make timing, the lookup of the cache is pipelined, so on
each cycle the cache entry for the current NIA + 8 is read. This
means that after a redirect (from decode1 or execute1), only the third
and subsequent sequentially-fetched instructions will be able to be
predicted.
This improves the coremark value on the Arty A7-100 from about 180 to
about 190 (more than 5%).
The BTC is optional. Builds for the Artix 7 35-T part have it off by
default because the extra ~1420 LUTs it takes mean that the design
doesn't fit on the Arty A7-35 board.
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
4 years ago
end if ;
bv . predict : = v . br_pred and f_in . valid and not flush_in and not busy_out and not f_in . next_predicted ;
-- after a clock edge...
br_target : = std_ulogic_vector ( signed ( br . br_nia ) + br . br_offset ) ;
-- Update registers
rin < = v ;
ri_in < = vi ;
br_in < = bv ;
-- Update outputs
d_out < = r ;
if ri . override = '1' then
d_out . decode < = ri . override_decode ;
elsif ri . override_unit = '1' then
d_out . decode . unit < = ri . override_decode . unit ;
end if ;
if ri . force_single = '1' then
d_out . decode . sgl_pipe < = '1' ;
end if ;
f_out . redirect < = br . predict ;
f_out . redirect_nia < = br_target & "00" ;
flush_out < = bv . predict or br . predict ;
r_out < = vr ;
end process ;
d1_log : if LOG_LENGTH > 0 generate
signal log_data : std_ulogic_vector ( 12 downto 0 ) ;
begin
dec1_log : process ( clk )
begin
if rising_edge ( clk ) then
log_data < = std_ulogic_vector ( to_unsigned ( insn_type_t 'pos ( r . decode . insn_type ) , 6 ) ) &
r . nia ( 5 downto 2 ) &
std_ulogic_vector ( to_unsigned ( unit_t 'pos ( r . decode . unit ) , 2 ) ) &
r . valid ;
end if ;
end process ;
log_out < = log_data ;
end generate ;
end architecture behaviour ;