FPU: Implement fmrgew and fmrgow and add tests for them
authorPaul Mackerras <paulus@ozlabs.org>
Wed, 22 Jul 2020 10:51:31 +0000 (20:51 +1000)
committerPaul Mackerras <paulus@ozlabs.org>
Thu, 3 Sep 2020 07:44:59 +0000 (17:44 +1000)
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
decode1.vhdl
fpu.vhdl
tests/fpu/fpu.c
tests/test_fpu.bin
tests/test_fpu.console_out

index a42899dc9be4848c6ff57fe05750ac40e3876076..34170dda8452bafc224c9d5684b0ffe63ba55c07 100644 (file)
@@ -434,6 +434,8 @@ architecture behaviour of decode1 is
         2#011000001#  => (FPU,   OP_FPOP,       NONE, NONE, NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC,   '0', '0'), --  1/6=mtfsb1
         2#011000010#  => (FPU,   OP_FPOP,       NONE, NONE, NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC,   '0', '0'), --  2/6=mtfsb0
         2#011000100#  => (FPU,   OP_FPOP,       NONE, NONE, NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC,   '0', '0'), --  4/6=mtfsfi
+        2#011011010#  => (FPU,   OP_FPOP_I,     FRA,  FRB,  NONE, FRT,  '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- 26/6=fmrgow
+        2#011011110#  => (FPU,   OP_FPOP_I,     FRA,  FRB,  NONE, FRT,  '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- 30/6=fmrgew
         2#011110010#  => (FPU,   OP_FPOP_I,     NONE, FRB,  NONE, FRT,  '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC,   '0', '0'), -- 18/7=mffs family
         2#011110110#  => (FPU,   OP_FPOP_I,     NONE, FRB,  NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC,   '0', '0'), -- 22/7=mtfsf
         2#100000000#  => (FPU,   OP_FPOP,       FRA,  FRB,  NONE, FRT,  '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC,   '0', '0'), --  0/8=fcpsgn
index 371fdc5bd82bcd86c95f8a53db280a9b8be3d511..e97461c9ae9402961993dd867aab356d170d93bc 100644 (file)
--- a/fpu.vhdl
+++ b/fpu.vhdl
@@ -37,7 +37,7 @@ architecture behaviour of fpu is
 
     type state_t is (IDLE,
                      DO_MCRFS, DO_MTFSB, DO_MTFSFI, DO_MFFS, DO_MTFSF,
-                     DO_FMR,
+                     DO_FMR, DO_FMRG,
                      DO_FCFID, DO_FCTI,
                      DO_FRSP, DO_FRI,
                      FRI_1,
@@ -450,10 +450,14 @@ begin
                         when "00000" =>
                             v.state := DO_MCRFS;
                         when "00110" =>
-                            if e_in.insn(8) = '0' then
-                                v.state := DO_MTFSB;
+                            if e_in.insn(10) = '0' then
+                                if e_in.insn(8) = '0' then
+                                    v.state := DO_MTFSB;
+                                else
+                                    v.state := DO_MTFSFI;
+                                end if;
                             else
-                                v.state := DO_MTFSFI;
+                                v.state := DO_FMRG;
                             end if;
                         when "00111" =>
                             if e_in.insn(8) = '0' then
@@ -524,6 +528,15 @@ begin
                 v.instr_done := '1';
                 v.state := IDLE;
 
+            when DO_FMRG =>
+                -- fmrgew, fmrgow
+                opsel_r <= RES_MISC;
+                misc_sel <= "01" & r.insn(8) & '0';
+                v.int_result := '1';
+                v.writing_back := '1';
+                v.instr_done := '1';
+                v.state := IDLE;
+
             when DO_MFFS =>
                 v.int_result := '1';
                 v.writing_back := '1';
@@ -1009,6 +1022,12 @@ begin
                     when "0011" =>
                         -- mantissa of max representable SP number
                         misc := x"007fffff80000000";
+                    when "0100" =>
+                        -- fmrgow result
+                        misc := r.a.mantissa(31 downto 0) & r.b.mantissa(31 downto 0);
+                    when "0110" =>
+                        -- fmrgew result
+                        misc := r.a.mantissa(63 downto 32) & r.b.mantissa(63 downto 32);
                     when "1000" =>
                         -- max positive result for fctiw[z]
                         misc := x"000000007fffffff";
index d24fe14a1313208888ecc942345eb87e6971f397..e7a13347cb96c15c93fa466ae68851528e1a164a 100644 (file)
@@ -823,6 +823,26 @@ int fpu_test_11(void)
        return trapit(0, test11);
 }
 
+int test12(long arg)
+{
+       unsigned long vals[2];
+       unsigned long results[2];
+
+       vals[0] = 0xf0f0f0f05a5a5a5aul;
+       vals[1] = 0x0123456789abcdeful;
+       asm("lfd 5,0(%0); lfd 6,8(%0); fmrgew 7,5,6; fmrgow 8,5,6; stfd 7,0(%1); stfd 8,8(%1)"
+           : : "b" (vals), "b" (results) : "memory");
+       if (results[0] != 0xf0f0f0f001234567ul || results[1] != 0x5a5a5a5a89abcdeful)
+               return 1;
+       return 0;
+}
+
+int fpu_test_12(void)
+{
+       enable_fp();
+       return trapit(0, test12);
+}
+
 int fail = 0;
 
 void do_test(int num, int (*test)(void))
@@ -859,6 +879,7 @@ int main(void)
        do_test(9, fpu_test_9);
        do_test(10, fpu_test_10);
        do_test(11, fpu_test_11);
+       do_test(12, fpu_test_12);
 
        return fail;
 }
index d2320cd960e8c39417367d3b8d7fc730494c9eca..668ff65367cbf02294b638e77fd93f9173db9532 100755 (executable)
Binary files a/tests/test_fpu.bin and b/tests/test_fpu.bin differ
index 3a5a6018fcdec0d219049254190f6a559d53239c..d926abc9e5e039696b235a8a412a1aab941f30c2 100644 (file)
@@ -9,3 +9,4 @@ test 08:PASS
 test 09:PASS\r
 test 10:PASS\r
 test 11:PASS\r
+test 12:PASS\r