diff options
author | Tristan Gingold <tgingold@free.fr> | 2019-11-05 19:09:16 +0100 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2019-11-05 19:09:16 +0100 |
commit | ac6ce0e78b3a89e7fa83d0b0c80bfcd7ec0ef49b (patch) | |
tree | 9b3e004a428fd0820c4f1cab80693dc2a6ecf4cd /src/synth/netlists-folds.adb | |
parent | 50534920b4f1e9846c6d46dce9ae650d790a9f8e (diff) | |
download | ghdl-ac6ce0e78b3a89e7fa83d0b0c80bfcd7ec0ef49b.tar.gz ghdl-ac6ce0e78b3a89e7fa83d0b0c80bfcd7ec0ef49b.tar.bz2 ghdl-ac6ce0e78b3a89e7fa83d0b0c80bfcd7ec0ef49b.zip |
synth: do more constant propagation (on build2
Diffstat (limited to 'src/synth/netlists-folds.adb')
-rw-r--r-- | src/synth/netlists-folds.adb | 47 |
1 files changed, 39 insertions, 8 deletions
diff --git a/src/synth/netlists-folds.adb b/src/synth/netlists-folds.adb index fd35ed8ed..9028c15ea 100644 --- a/src/synth/netlists-folds.adb +++ b/src/synth/netlists-folds.adb @@ -21,6 +21,7 @@ with Types_Utils; use Types_Utils; with Netlists.Gates; use Netlists.Gates; +with Netlists.Utils; use Netlists.Utils; with Netlists.Locations; package body Netlists.Folds is @@ -136,11 +137,29 @@ package body Netlists.Folds is if Wn = W then return I; else - if Wn > W then - Res := Build_Trunc (Ctxt, Id_Utrunc, I, W); + if W <= 64 and then Is_Const_Net (I) then + declare + V : Uns64; + begin + V := Get_Net_Uns64 (I); + if Wn < W then + -- Extend. + pragma Assert (Shift_Right (V, Natural (Wn)) = 0); + null; + else + -- Truncate + V := Shift_Left (V, Natural (64 - Wn)); + V := Shift_Right (V, Natural (64 - Wn)); + end if; + Res := Build2_Const_Uns (Ctxt, V, W); + end; else - pragma Assert (Wn < W); - Res := Build_Extend (Ctxt, Id_Uextend, I, W); + if Wn > W then + Res := Build_Trunc (Ctxt, Id_Utrunc, I, W); + else + pragma Assert (Wn < W); + Res := Build_Extend (Ctxt, Id_Uextend, I, W); + end if; end if; Locations.Set_Location (Res, Loc); return Res; @@ -159,11 +178,23 @@ package body Netlists.Folds is if Wn = W then return I; else - if Wn > W then - Res := Build_Trunc (Ctxt, Id_Strunc, I, W); + if W <= 64 and then Is_Const_Net (I) then + declare + V : Uns64; + Sh : constant Natural := Natural (Width'Min (Wn, W)); + begin + V := Get_Net_Uns64 (I); + V := Shift_Left (V, 64 - Sh); + V := Shift_Right_Arithmetic (V, 64 - Sh); + Res := Build2_Const_Int (Ctxt, To_Int64 (V), W); + end; else - pragma Assert (Wn < W); - Res := Build_Extend (Ctxt, Id_Sextend, I, W); + if Wn > W then + Res := Build_Trunc (Ctxt, Id_Strunc, I, W); + else + pragma Assert (Wn < W); + Res := Build_Extend (Ctxt, Id_Sextend, I, W); + end if; end if; Locations.Set_Location (Res, Loc); return Res; |