core: Implement the addex instruction
authorPaul Mackerras <paulus@ozlabs.org>
Thu, 6 Aug 2020 09:15:02 +0000 (19:15 +1000)
committerPaul Mackerras <paulus@ozlabs.org>
Thu, 6 Aug 2020 09:27:00 +0000 (19:27 +1000)
The addex instruction is like adde but uses the XER[OV] bit for the
carry in and out rather than XER[CA].

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

index a58525e9a8c6671021693137c06ac6ebe5400ef3..caff3d80ed798c31af44de3776496f13ffb48954 100644 (file)
@@ -172,6 +172,7 @@ architecture behaviour of decode1 is
         2#1000001010#  =>       (ALU,    OP_ADD,       RA,         RB,          NONE, RT,   '0', '0', '0', '0', ZERO, '1', NONE, '0', '0', '0', '0', '0', '0', RC,   '0', '0'), -- addco
         2#0010001010#  =>       (ALU,    OP_ADD,       RA,         RB,          NONE, RT,   '0', '0', '0', '0', CA,   '1', NONE, '0', '0', '0', '0', '0', '0', RC,   '0', '0'), -- adde
         2#1010001010#  =>       (ALU,    OP_ADD,       RA,         RB,          NONE, RT,   '0', '0', '0', '0', CA,   '1', NONE, '0', '0', '0', '0', '0', '0', RC,   '0', '0'), -- addeo
+        2#0010101010#  =>       (ALU,    OP_ADD,       RA,         RB,          NONE, RT,   '0', '0', '0', '0', OV,   '1', NONE, '0', '0', '0', '0', '0', '0', RC,   '0', '0'), -- addex
         2#0011101010#  =>       (ALU,    OP_ADD,       RA,         CONST_M1,    NONE, RT,   '0', '0', '0', '0', CA,   '1', NONE, '0', '0', '0', '0', '0', '0', RC,   '0', '0'), -- addme
         2#1011101010#  =>       (ALU,    OP_ADD,       RA,         CONST_M1,    NONE, RT,   '0', '0', '0', '0', CA,   '1', NONE, '0', '0', '0', '0', '0', '0', RC,   '0', '0'), -- addmeo
         2#0011001010#  =>       (ALU,    OP_ADD,       RA,         NONE,        NONE, RT,   '0', '0', '0', '0', CA,   '1', NONE, '0', '0', '0', '0', '0', '0', RC,   '0', '0'), -- addze
index e5ae8c192cc348e3c4375741a4f5e8d8ba99f735..7a60eac97fd19ea0b09e9f88fe6743fc3756210c 100644 (file)
@@ -26,7 +26,7 @@ package decode_types is
     type input_reg_c_t is (NONE, RS, RCR);
     type output_reg_a_t is (NONE, RT, RA, SPR);
     type rc_t is (NONE, ONE, RC);
-    type carry_in_t is (ZERO, CA, ONE);
+    type carry_in_t is (ZERO, CA, OV, ONE);
 
     constant SH_OFFSET : integer := 0;
     constant MB_OFFSET : integer := 1;
index a53024fc8e26577f08bc4dc8d448577e6e3b2b16..256cb5e2451cb740f17f7e0cb919748802a8296e 100644 (file)
@@ -164,6 +164,8 @@ architecture behaviour of execute1 is
            return '0';
        when CA =>
            return xerc.ca;
+        when OV =>
+            return xerc.ov;
        when ONE =>
            return '1';
        end case;
@@ -594,7 +596,13 @@ begin
                 carry_64 := result_with_carry(64);
                 if e_in.insn_type = OP_ADD then
                     if e_in.output_carry = '1' then
-                        set_carry(v.e, carry_32, carry_64);
+                        if e_in.input_carry /= OV then
+                            set_carry(v.e, carry_32, carry_64);
+                        else
+                            v.e.xerc.ov := carry_64;
+                            v.e.xerc.ov32 := carry_32;
+                            v.e.write_xerc_enable := '1';
+                        end if;
                     end if;
                     if e_in.oe = '1' then
                         set_ov(v.e,