aboutsummaryrefslogtreecommitdiffstats
path: root/x86/SelectOp.vp
diff options
context:
space:
mode:
authorXavier Leroy <xavier.leroy@college-de-france.fr>2019-05-17 16:17:51 +0200
committerXavier Leroy <xavier.leroy@college-de-france.fr>2019-06-07 09:08:40 +0200
commitb3bfdc3655479f7f8f1c5e3a7571473a72b421cb (patch)
tree8fdc27ef9b7c186ee3af9c04327a28b7e8424fd1 /x86/SelectOp.vp
parent8e3a73448c5ddfa4be3871d7f4fd80281a7549f4 (diff)
downloadcompcert-b3bfdc3655479f7f8f1c5e3a7571473a72b421cb.tar.gz
compcert-b3bfdc3655479f7f8f1c5e3a7571473a72b421cb.zip
x86 branchless implementation of unsigned int32 -> float conversion
Based on a suggestion by RĂ©mi Hutin. The new implementation produces smaller code (3 FP instructions and 2 integer "and") and has no conditional branch. On average, it is a little slower than the old implementation. Hence both implementations are supported: - with -ffavor-branchless, use the new implementation - by default, use the old, branching implementation
Diffstat (limited to 'x86/SelectOp.vp')
-rw-r--r--x86/SelectOp.vp17
1 files changed, 12 insertions, 5 deletions
diff --git a/x86/SelectOp.vp b/x86/SelectOp.vp
index cf0f37ec..df9c5394 100644
--- a/x86/SelectOp.vp
+++ b/x86/SelectOp.vp
@@ -497,6 +497,8 @@ Nondetfunction floatofint (e: expr) :=
| _ => Eop Ofloatofint (e ::: Enil)
end.
+Parameter favor_branchless: unit -> bool.
+
Definition intuoffloat (e: expr) :=
Elet e
(Elet (Eop (Ofloatconst (Float.of_intu Float.ox8000_0000)) Enil)
@@ -508,11 +510,16 @@ Nondetfunction floatofintu (e: expr) :=
match e with
| Eop (Ointconst n) Enil => Eop (Ofloatconst (Float.of_intu n)) Enil
| _ =>
- let f := Eop (Ofloatconst (Float.of_intu Float.ox8000_0000)) Enil in
- Elet e
- (Econdition (CEcond (Ccompuimm Clt Float.ox8000_0000) (Eletvar O ::: Enil))
- (floatofint (Eletvar O))
- (addf (floatofint (addimm (Int.neg Float.ox8000_0000) (Eletvar O))) f))
+ if favor_branchless tt then
+ Elet e (subf
+ (Eop Ofloatofint (andimm Float.ox7FFF_FFFF (Eletvar O) ::: Enil))
+ (Eop Ofloatofint (andimm Float.ox8000_0000 (Eletvar O) ::: Enil)))
+ else
+ let f := Eop (Ofloatconst (Float.of_intu Float.ox8000_0000)) Enil in
+ Elet e
+ (Econdition (CEcond (Ccompuimm Clt Float.ox8000_0000) (Eletvar O ::: Enil))
+ (floatofint (Eletvar O))
+ (addf (floatofint (addimm (Int.neg Float.ox8000_0000) (Eletvar O))) f))
end.
Definition intofsingle (e: expr) := Eop Ointofsingle (e ::: Enil).