aboutsummaryrefslogtreecommitdiffstats
path: root/src/synth/netlists-folds.adb
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2019-11-05 19:09:16 +0100
committerTristan Gingold <tgingold@free.fr>2019-11-05 19:09:16 +0100
commitac6ce0e78b3a89e7fa83d0b0c80bfcd7ec0ef49b (patch)
tree9b3e004a428fd0820c4f1cab80693dc2a6ecf4cd /src/synth/netlists-folds.adb
parent50534920b4f1e9846c6d46dce9ae650d790a9f8e (diff)
downloadghdl-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.adb47
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;