spr: Cleanup decoding of SPR numbers
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>
Thu, 31 Oct 2019 00:42:10 +0000 (11:42 +1100)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Thu, 14 Nov 2019 04:09:37 +0000 (15:09 +1100)
Use a function to obtain the integer number and use constants
with the architected numbers. Replace std_match with a case
statement.

This also has the side effect of returning 0 instead of some
random previous result on mfspr of an unknown SPR.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
common.vhdl
execute1.vhdl

index 3e9da69e0e0bcdb509b97e7fd01c13b634813994..44198b0d5659f467d68485caaa289ab54898592c 100644 (file)
@@ -1,10 +1,21 @@
 library ieee;
 use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
 
 library work;
 use work.decode_types.all;
 
 package common is
+
+    -- SPR numbers
+    subtype spr_num_t is integer range 0 to 1023;
+
+    function decode_spr_num(insn: std_ulogic_vector(31 downto 0)) return spr_num_t;
+
+    constant SPR_LR    : spr_num_t := 8;
+    constant SPR_CTR   : spr_num_t := 9;
+    constant SPR_TB    : spr_num_t := 268;
+
     type ctrl_t is record
        lr: std_ulogic_vector(63 downto 0);
        ctr: std_ulogic_vector(63 downto 0);
@@ -216,4 +227,8 @@ package common is
 end common;
 
 package body common is
+    function decode_spr_num(insn: std_ulogic_vector(31 downto 0)) return spr_num_t is
+    begin
+       return to_integer(unsigned(insn(15 downto 11) & insn(20 downto 16)));
+    end;
 end common;
index 6632783d8d268ace58f95d53b0999fcd6bece0f0..862c631748a1e7062b594d30f648573327f28f11 100644 (file)
@@ -269,16 +269,17 @@ begin
                    v.e.write_cr_data(hi downto lo) := newcrf;
                end loop;
            when OP_MFSPR =>
-               if std_match(e_in.insn(20 downto 11), "0100100000") then
+               case decode_spr_num(e_in.insn) is
+               when SPR_CTR =>
                    result := ctrl.ctr;
-                   result_en := '1';
-               elsif std_match(e_in.insn(20 downto 11), "0100000000") then
+               when SPR_LR =>
                    result := ctrl.lr;
-                   result_en := '1';
-               elsif std_match(e_in.insn(20 downto 11), "0110001000") then
+               when SPR_TB =>
                    result := ctrl.tb;
-                   result_en := '1';
-               end if;
+               when others =>
+                   result := (others => '0');
+               end case;
+               result_en := '1';
            when OP_MFCR =>
                if e_in.insn(20) = '0' then
                    -- mfcr
@@ -308,11 +309,13 @@ begin
                end if;
                v.e.write_cr_data := e_in.read_data3(31 downto 0);
            when OP_MTSPR =>
-               if std_match(e_in.insn(20 downto 11), "0100100000") then
+               case decode_spr_num(e_in.insn) is
+               when SPR_CTR =>
                    ctrl_tmp.ctr <= e_in.read_data3;
-               elsif std_match(e_in.insn(20 downto 11), "0100000000") then
+               when SPR_LR =>
                    ctrl_tmp.lr <= e_in.read_data3;
-               end if;
+               when others =>
+               end case;
            when OP_POPCNTB =>
                result := ppc_popcntb(e_in.read_data3);
                result_en := '1';