decode: Index minor op table with insn bits for opcode 30
authorPaul Mackerras <paulus@ozlabs.org>
Sun, 29 Sep 2019 06:41:52 +0000 (16:41 +1000)
committerPaul Mackerras <paulus@ozlabs.org>
Tue, 1 Oct 2019 05:27:06 +0000 (15:27 +1000)
This comprises the 64-bit rotate and mask instructions.  In order to
reduce the table index to 3 bits, we combine rldcl and rdlcr into a
single op (OP_RLDCX), and choose the right mask at execute time based
on bit 1 of the instruction word.

Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
decode1.vhdl
decode_types.vhdl
execute1.vhdl

index ee5e6eb389422d2013776d36e5b5c18ecdfc9acf..9b4f2d9e125901afdbcc52b302ba0258db6a0a8f 100644 (file)
@@ -26,6 +26,7 @@ architecture behaviour of decode1 is
         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 op_19_subop_array_t is array(0 to 7) of decode_rom_t;
+        type op_30_subop_array_t is array(0 to 7) of decode_rom_t;
         type minor_rom_array_2_t is array(0 to 3) of decode_rom_t;
 
        type decode_rom_array_t is array(ppc_insn_t) of decode_rom_t;
@@ -112,17 +113,16 @@ architecture behaviour of decode1 is
                others   => illegal_inst
         );
 
-       constant decode_op_30_array : decode_rom_array_t := (
-               --                       unit     internal     in1         in2          in3   out   const const const CR   CR   cry  cry  ldst  BR   sgn  upd  rsrv mul  mul  rc    lk   sgl
-               --                                      op                                          1     2     3     in   out  in   out  len        ext             32  sgn             pipe
-               PPC_ILLEGAL    =>       (ALU,    OP_ILLEGAL,   NONE,       NONE,        NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC,   '0', '1'),
-               PPC_RLDCL      =>       (ALU,    OP_RLDCL,     RS,         RB,          NONE, RA,   NONE, MB,   NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC,   '0', '1'),
-               PPC_RLDCR      =>       (ALU,    OP_RLDCR,     RS,         RB,          NONE, RA,   NONE, MB,   NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC,   '0', '1'),
-               PPC_RLDIC      =>       (ALU,    OP_RLDIC,     RS,         NONE,        NONE, RA,   SH,   MB,   NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC,   '0', '1'),
-               PPC_RLDICL     =>       (ALU,    OP_RLDICL,    RS,         NONE,        NONE, RA,   SH,   MB,   NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC,   '0', '1'),
-               PPC_RLDICR     =>       (ALU,    OP_RLDICR,    RS,         NONE,        NONE, RA,   SH,   ME,   NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC,   '0', '1'),
-               PPC_RLDIMI     =>       (ALU,    OP_RLDIMI,    RA,         RS,          NONE, RA,   SH,   MB,   NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC,   '0', '1'),
-               others   => decode_rom_init
+       constant decode_op_30_array : op_30_subop_array_t := (
+               --                unit     internal     in1         in2          in3   out   const const const CR   CR   cry  cry  ldst  BR   sgn  upd  rsrv mul  mul  rc    lk   sgl
+               --                               op                                          1     2     3     in   out  in   out  len        ext             32  sgn             pipe
+               2#010#   =>       (ALU,    OP_RLDIC,     RS,         NONE,        NONE, RA,   SH,   MB,   NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC,   '0', '1'),
+               2#000#   =>       (ALU,    OP_RLDICL,    RS,         NONE,        NONE, RA,   SH,   MB,   NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC,   '0', '1'),
+               2#001#   =>       (ALU,    OP_RLDICR,    RS,         NONE,        NONE, RA,   SH,   ME,   NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC,   '0', '1'),
+               2#011#   =>       (ALU,    OP_RLDIMI,    RA,         RS,          NONE, RA,   SH,   MB,   NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC,   '0', '1'),
+                -- rldcl, rldcr
+               2#100#   =>       (ALU,    OP_RLDCX,     RS,         RB,          NONE, RA,   NONE, MB,   NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC,   '0', '1'),
+               others   => illegal_inst
         );
 
        -- Note: reformat with column -t -o ' '
@@ -280,6 +280,7 @@ begin
                variable ppc_insn: ppc_insn_t;
                 variable majorop : major_opcode_t;
                 variable op_19_bits: std_ulogic_vector(2 downto 0);
+                variable op_30_bits: std_ulogic_vector(2 downto 0);
        begin
                v := r;
 
@@ -645,29 +646,7 @@ begin
                         end if;
 
                 elsif majorop = "011110" then
-                        if    std_match(f_in.insn, "---------------------------1000-") then
-                               report "PPC_rldcl";
-                               ppc_insn := PPC_RLDCL;
-                       elsif std_match(f_in.insn, "---------------------------1001-") then
-                               report "PPC_rldcr";
-                               ppc_insn := PPC_RLDCR;
-                       elsif std_match(f_in.insn, "---------------------------010--") then
-                               report "PPC_rldic";
-                               ppc_insn := PPC_RLDIC;
-                       elsif std_match(f_in.insn, "---------------------------000--") then
-                               report "PPC_rldicl";
-                               ppc_insn := PPC_RLDICL;
-                       elsif std_match(f_in.insn, "---------------------------001--") then
-                               report "PPC_rldicr";
-                               ppc_insn := PPC_RLDICR;
-                       elsif std_match(f_in.insn, "---------------------------011--") then
-                               report "PPC_rldimi";
-                               ppc_insn := PPC_RLDIMI;
-                       else
-                               report "PPC_illegal";
-                               ppc_insn := PPC_ILLEGAL;
-                       end if;
-                       v.decode := decode_op_30_array(ppc_insn);
+                        v.decode := decode_op_30_array(to_integer(unsigned(f_in.insn(4 downto 2))));
 
                 elsif majorop = "111010" then
                         v.decode := decode_op_58_array(to_integer(unsigned(f_in.insn(1 downto 0))));
index aab59cfcd3c9d7621229a1e1838638e56e5702b2..542126525caf37b68c33b9435b90079f42cc9514 100644 (file)
@@ -51,7 +51,7 @@ package decode_types is
                OP_MTCRF, OP_MTOCRF, OP_MTSPR, OP_MUL_L64,
                OP_MUL_H64, OP_MUL_H32, OP_NAND, OP_NEG, OP_NOR, OP_OR,
                OP_ORC, OP_POPCNTB, OP_POPCNTD, OP_POPCNTW, OP_PRTYD,
-               OP_PRTYW, OP_RLDCL, OP_RLDCR, OP_RLDIC, OP_RLDICL, OP_RLDICR,
+               OP_PRTYW, OP_RLDCX, OP_RLDIC, OP_RLDICL, OP_RLDICR,
                OP_RLDIMI, OP_RLWIMI, OP_RLWINM, OP_RLWNM, OP_SETB, OP_SLD,
                OP_SLW, OP_SRAD, OP_SRADI, OP_SRAW, OP_SRAWI, OP_SRD, OP_SRW,
                OP_SUBF, OP_SUBFE, OP_SUBFME, OP_SYNC, OP_TD, OP_TDI, OP_TW,
index efbba149888eb0f36ef726fec6b2d6e6ed9f808c..7b0801055a2713e60ed53c154a5effe615844e44 100644 (file)
@@ -274,11 +274,12 @@ begin
                                when OP_PRTYW =>
                                        result := ppc_prtyw(e_in.read_data1);
                                        result_en := 1;
-                               when OP_RLDCL =>
-                                       result := ppc_rldcl(e_in.read_data1, e_in.read_data2, e_in.const2(5 downto 0));
-                                       result_en := 1;
-                               when OP_RLDCR =>
-                                       result := ppc_rldcr(e_in.read_data1, e_in.read_data2, e_in.const2(5 downto 0));
+                               when OP_RLDCX =>
+                                        if e_in.insn(1) = '0' then
+                                                result := ppc_rldcl(e_in.read_data1, e_in.read_data2, e_in.const2(5 downto 0));
+                                        else
+                                                result := ppc_rldcr(e_in.read_data1, e_in.read_data2, e_in.const2(5 downto 0));
+                                        end if;
                                        result_en := 1;
                                when OP_RLDICL =>
                                        result := ppc_rldicl(e_in.read_data1, e_in.const1(5 downto 0), e_in.const2(5 downto 0));