|
| 1 | +#lang s-exp "../syntax/platform-language.rkt" |
| 2 | + |
| 3 | +;; C/C++ platform with a full libm |
| 4 | + |
| 5 | +(require math/flonum) |
| 6 | + |
| 7 | +(define 64bit-move-cost 0.125) |
| 8 | +(define 32bit-move-cost 0.125) |
| 9 | +(define boolean-move-cost 0.100) |
| 10 | + |
| 11 | + |
| 12 | +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; BOOLEAN ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 13 | + |
| 14 | +(define-representation <bool> #:cost boolean-move-cost) |
| 15 | + |
| 16 | +(define-operations () <bool> |
| 17 | + [TRUE #:spec (TRUE) #:impl (const true) #:fpcore TRUE #:cost boolean-move-cost] |
| 18 | + [FALSE #:spec (FALSE) #:impl (const false) #:fpcore FALSE #:cost boolean-move-cost]) |
| 19 | + |
| 20 | +(define-operations ([x <bool>] [y <bool>]) <bool> |
| 21 | + [and #:spec (and x y) #:impl (lambda v (andmap values v)) #:cost boolean-move-cost] |
| 22 | + [or #:spec (or x y) #:impl (lambda v (ormap values v)) #:cost boolean-move-cost]) |
| 23 | + |
| 24 | +(define-operation (not [x <bool>]) <bool> |
| 25 | + #:spec (not x) #:impl not #:cost boolean-move-cost) |
| 26 | + |
| 27 | +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; BINARY 32 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 28 | + |
| 29 | +(define-representation <binary32> #:cost 32bit-move-cost) |
| 30 | + |
| 31 | +(define-operation (if.f32 [c <bool>] [t <binary32>] [f <binary32>]) <binary32> |
| 32 | + #:spec (if c t f) #:impl if-impl |
| 33 | + #:cost (if-cost boolean-move-cost)) |
| 34 | + |
| 35 | +(define-operations ([x <binary32>] [y <binary32>]) <bool> |
| 36 | + [==.f32 #:spec (== x y) #:impl = #:cost 32bit-move-cost] |
| 37 | + [!=.f32 #:spec (!= x y) #:impl (negate =) #:cost 32bit-move-cost] |
| 38 | + [<.f32 #:spec (< x y) #:impl < #:cost 32bit-move-cost] |
| 39 | + [>.f32 #:spec (> x y) #:impl > #:cost 32bit-move-cost] |
| 40 | + [<=.f32 #:spec (<= x y) #:impl <= #:cost 32bit-move-cost] |
| 41 | + [>=.f32 #:spec (>= x y) #:impl >= #:cost 32bit-move-cost]) |
| 42 | + |
| 43 | +(define-operations () <binary32> #:fpcore (! :precision binary32 _) |
| 44 | + [PI.f32 #:spec (PI) #:impl (const (flsingle pi)) #:fpcore PI #:cost 32bit-move-cost] |
| 45 | + [E.f32 #:spec (E) #:impl (const (flsingle (exp 1))) #:fpcore E #:cost 32bit-move-cost] |
| 46 | + #;[INFINITY.f32 #:spec (INFINITY) #:impl (const +inf.0) #:fpcore INFINITY #:cost 32bit-move-cost] |
| 47 | + #;[NAN.f32 #:spec (NAN) #:impl (const +nan.0) #:fpcore NAN #:cost 32bit-move-cost]) |
| 48 | + |
| 49 | +(define-operation (neg.f32 [x <binary32>]) <binary32> |
| 50 | + #:spec (neg x) #:impl (compose flsingle -) |
| 51 | + #:fpcore (! :precision binary32 (- x)) #:cost 0.125) |
| 52 | + |
| 53 | +(define-operations ([x <binary32>] [y <binary32>]) <binary32> #:fpcore (! :precision binary32 _) |
| 54 | + [+.f32 #:spec (+ x y) #:impl (compose flsingle +) #:cost 0.200] |
| 55 | + [-.f32 #:spec (- x y) #:impl (compose flsingle -) #:cost 0.200] |
| 56 | + [*.f32 #:spec (* x y) #:impl (compose flsingle *) #:cost 0.250] |
| 57 | + [/.f32 #:spec (/ x y) #:impl (compose flsingle /) #:cost 0.350]) |
| 58 | + |
| 59 | +(define-operations ([x <binary32>]) <binary32> #:fpcore (! :precision binary32 _) |
| 60 | + [fabs.f32 #:spec (fabs x) #:impl (from-libm 'fabsf) #:cost 0.125] |
| 61 | + [sin.f32 #:spec (sin x) #:impl (from-libm 'sinf) #:cost 4.250] |
| 62 | + [cos.f32 #:spec (cos x) #:impl (from-libm 'cosf) #:cost 4.250] |
| 63 | + [tan.f32 #:spec (tan x) #:impl (from-libm 'tanf) #:cost 4.750] |
| 64 | + #;[sinh.f32 #:spec (sinh x) #:impl (from-libm 'sinhf) #:cost 1.750] |
| 65 | + #;[cosh.f32 #:spec (cosh x) #:impl (from-libm 'coshf) #:cost 1.250] |
| 66 | + [acos.f32 #:spec (acos x) #:impl (from-libm 'acosf) #:cost 0.500] |
| 67 | + #;[acosh.f32 #:spec (acosh x) #:impl (from-libm 'acoshf) #:cost 0.850] |
| 68 | + [asin.f32 #:spec (asin x) #:impl (from-libm 'asinf) #:cost 0.500] |
| 69 | + #;[asinh.f32 #:spec (asinh x) #:impl (from-libm 'asinhf) #:cost 1.125] |
| 70 | + [atan.f32 #:spec (atan x) #:impl (from-libm 'atanf) #:cost 1.100] |
| 71 | + #;[atanh.f32 #:spec (atanh x) #:impl (from-libm 'atanhf) #:cost 0.500] |
| 72 | + #;[cbrt.f32 #:spec (cbrt x) #:impl (from-libm 'cbrtf) #:cost 2.000] |
| 73 | + #;[ceil.f32 #:spec (ceil x) #:impl (from-libm 'ceilf) #:cost 0.250] |
| 74 | + #;[erf.f32 #:spec (erf x) #:impl (from-libm 'erff) #:cost 1.125] |
| 75 | + [exp.f32 #:spec (exp x) #:impl (from-libm 'expf) #:cost 1.375] |
| 76 | + #;[exp2.f32 #:spec (exp2 x) #:impl (from-libm 'exp2f) #:cost 1.175] |
| 77 | + #;[floor.f32 #:spec (floor x) #:impl (from-libm 'floorf) #:cost 0.250] |
| 78 | + #;[lgamma.f32 #:spec (lgamma x) #:impl (from-libm 'lgammaf) #:cost 2.250] |
| 79 | + [log.f32 #:spec (log x) #:impl (from-libm 'logf) #:cost 0.750] |
| 80 | + #;[log10.f32 #:spec (log10 x) #:impl (from-libm 'log10f) #:cost 1.175] |
| 81 | + #;[log2.f32 #:spec (log2 x) #:impl (from-libm 'log2f) #:cost 0.875] |
| 82 | + #;[logb.f32 #:spec (logb x) #:impl (from-libm 'logbf) #:cost 0.375] |
| 83 | + #;[rint.f32 #:spec (rint x) #:impl (from-libm 'rintf) #:cost 0.300] |
| 84 | + #;[round.f32 #:spec (round x) #:impl (from-libm 'roundf) #:cost 0.875] |
| 85 | + [sqrt.f32 #:spec (sqrt x) #:impl (from-libm 'sqrtf) #:cost 0.250] |
| 86 | + #;[tanh.f32 #:spec (tanh x) #:impl (from-libm 'tanhf) #:cost 1.000] |
| 87 | + #;[tgamma.f32 #:spec (tgamma x) #:impl (from-libm 'tgammaf) #:cost 2.625] |
| 88 | + #;[trunc.f32 #:spec (trunc x) #:impl (from-libm 'truncf) #:cost 0.275]) |
| 89 | + |
| 90 | +(define-operations ([x <binary32>] [y <binary32>]) <binary32> #:fpcore (! :precision binary32 _) |
| 91 | + [pow.f32 #:spec (pow x y) #:impl (from-libm 'powf) #:cost 2.000] |
| 92 | + #;[atan2.f32 #:spec (atan2 x y) #:impl (from-libm 'atan2f) #:cost 2.000] |
| 93 | + #;[copysign.f32 #:spec (copysign x y) #:impl (from-libm 'copysignf) #:cost 0.200] |
| 94 | + #;[fdim.f32 #:spec (fdim x y) #:impl (from-libm 'fdimf) #:cost 0.750] |
| 95 | + [fmax.f32 #:spec (fmax x y) #:impl (from-libm 'fmaxf) #:cost 0.250] |
| 96 | + [fmin.f32 #:spec (fmin x y) #:impl (from-libm 'fminf) #:cost 0.250] |
| 97 | + #;[fmod.f32 #:spec (fmod x y) #:impl (from-libm 'fmodf) #:cost 1.750] |
| 98 | + #;[remainder.f32 #:spec (remainder x y) #:impl (from-libm 'remainderf) #:cost 1.000]) |
| 99 | + |
| 100 | +#;(define-operations ([x <binary32>]) <binary32> #:fpcore (! :precision binary32 _) |
| 101 | + [erfc.f32 #:spec (- 1 (erf x)) #:impl (from-libm 'erfcf) #:fpcore (erfc x) #:cost 0.900] |
| 102 | + [expm1.f32 #:spec (- (exp x) 1) #:impl (from-libm 'expm1f) #:fpcore (expm1 x) #:cost 0.900] |
| 103 | + [log1p.f32 #:spec (log (+ 1 x)) #:impl (from-libm 'log1pf) #:fpcore (log1p x) #:cost 1.300]) |
| 104 | + |
| 105 | +#;(define-operation (hypot.f32 [x <binary32>] [y <binary32>]) <binary32> |
| 106 | + #:spec (sqrt (+ (* x x) (* y y))) #:impl (from-libm 'hypotf) |
| 107 | + #:fpcore (! :precision binary32 (hypot x y)) #:cost 1.700) |
| 108 | + |
| 109 | +#;(define-operation (fma.f32 [x <binary32>] [y <binary32>] [z <binary32>]) <binary32> |
| 110 | + #:spec (+ (* x y) z) #:impl (from-libm 'fmaf) |
| 111 | + #:fpcore (! :precision binary32 (fma x y z)) #:cost 0.375) |
| 112 | + |
| 113 | +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; BINARY 64 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 114 | + |
| 115 | +(define-representation <binary64> #:cost 64bit-move-cost) |
| 116 | + |
| 117 | +(define-operation (if.f64 [c <bool>] [t <binary64>] [f <binary64>]) <binary64> |
| 118 | + #:spec (if c t f) #:impl if-impl |
| 119 | + #:cost (if-cost boolean-move-cost)) |
| 120 | + |
| 121 | +(define-operations ([x <binary64>] [y <binary64>]) <bool> |
| 122 | + [==.f64 #:spec (== x y) #:impl = #:cost 64bit-move-cost] |
| 123 | + [!=.f64 #:spec (!= x y) #:impl (negate =) #:cost 64bit-move-cost] |
| 124 | + [<.f64 #:spec (< x y) #:impl < #:cost 64bit-move-cost] |
| 125 | + [>.f64 #:spec (> x y) #:impl > #:cost 64bit-move-cost] |
| 126 | + [<=.f64 #:spec (<= x y) #:impl <= #:cost 64bit-move-cost] |
| 127 | + [>=.f64 #:spec (>= x y) #:impl >= #:cost 64bit-move-cost]) |
| 128 | + |
| 129 | +(define-operations () <binary64> #:fpcore (! :precision binary64 _) |
| 130 | + [PI.f64 #:spec (PI) #:impl (const pi) #:fpcore PI #:cost 64bit-move-cost] |
| 131 | + [E.f64 #:spec (E) #:impl (const (exp 1)) #:fpcore E #:cost 64bit-move-cost] |
| 132 | + #;[INFINITY #:spec (INFINITY) #:impl (const +inf.0) #:fpcore INFINITY #:cost 64bit-move-cost] |
| 133 | + #;[NAN.f64 #:spec (NAN) #:impl (const +nan.0) #:fpcore NAN #:cost 64bit-move-cost]) |
| 134 | + |
| 135 | +(define-operation (neg.f64 [x <binary64>]) <binary64> |
| 136 | + #:spec (neg x) #:impl - #:fpcore (! :precision binary64 (- x)) #:cost 0.125) |
| 137 | + |
| 138 | +(define-operations ([x <binary64>] [y <binary64>]) <binary64> #:fpcore (! :precision binary64 _) |
| 139 | + [+.f64 #:spec (+ x y) #:impl + #:cost 0.200] |
| 140 | + [-.f64 #:spec (- x y) #:impl - #:cost 0.200] |
| 141 | + [*.f64 #:spec (* x y) #:impl * #:cost 0.250] |
| 142 | + [/.f64 #:spec (/ x y) #:impl / #:cost 0.350]) |
| 143 | + |
| 144 | +(define-operations ([x <binary64>]) <binary64> #:fpcore (! :precision binary64 _) |
| 145 | + [fabs.f64 #:spec (fabs x) #:impl (from-libm 'fabs) #:cost 0.125] |
| 146 | + [sin.f64 #:spec (sin x) #:impl (from-libm 'sin) #:cost 4.200] |
| 147 | + [cos.f64 #:spec (cos x) #:impl (from-libm 'cos) #:cost 4.200] |
| 148 | + [tan.f64 #:spec (tan x) #:impl (from-libm 'tan) #:cost 4.650] |
| 149 | + #;[sinh.f64 #:spec (sinh x) #:impl (from-libm 'sinh) #:cost 1.750] |
| 150 | + #;[cosh.f64 #:spec (cosh x) #:impl (from-libm 'cosh) #:cost 1.650] |
| 151 | + [acos.f64 #:spec (acos x) #:impl (from-libm 'acos) #:cost 0.500] |
| 152 | + #;[acosh.f64 #:spec (acosh x) #:impl (from-libm 'acosh) #:cost 0.850] |
| 153 | + [asin.f64 #:spec (asin x) #:impl (from-libm 'asin) #:cost 0.500] |
| 154 | + #;[asinh.f64 #:spec (asinh x) #:impl (from-libm 'asinh) #:cost 1.125] |
| 155 | + [atan.f64 #:spec (atan x) #:impl (from-libm 'atan) #:cost 1.100] |
| 156 | + #;[atanh.f64 #:spec (atanh x) #:impl (from-libm 'atanh) #:cost 0.450] |
| 157 | + #;[cbrt.f64 #:spec (cbrt x) #:impl (from-libm 'cbrt) #:cost 2.000] |
| 158 | + #;[ceil.f64 #:spec (ceil x) #:impl (from-libm 'ceil) #:cost 0.250] |
| 159 | + #;[erf.f64 #:spec (erf x) #:impl (from-libm 'erf) #:cost 1.125] |
| 160 | + [exp.f64 #:spec (exp x) #:impl (from-libm 'exp) #:cost 1.375] |
| 161 | + #;[exp2.f64 #:spec (exp2 x) #:impl (from-libm 'exp2) #:cost 1.175] |
| 162 | + #;[floor.f64 #:spec (floor x) #:impl (from-libm 'floor) #:cost 0.300] |
| 163 | + #;[lgamma.f64 #:spec (lgamma x) #:impl (from-libm 'lgamma) #:cost 2.250] |
| 164 | + [log.f64 #:spec (log x) #:impl (from-libm 'log) #:cost 0.750] |
| 165 | + #;[log10.f64 #:spec (log10 x) #:impl (from-libm 'log10) #:cost 1.175] |
| 166 | + #;[log2.f64 #:spec (log2 x) #:impl (from-libm 'log2) #:cost 0.850] |
| 167 | + #;[logb.f64 #:spec (logb x) #:impl (from-libm 'logb) #:cost 0.350] |
| 168 | + #;[rint.f64 #:spec (rint x) #:impl (from-libm 'rint) #:cost 0.300] |
| 169 | + #;[round.f64 #:spec (round x) #:impl (from-libm 'round) #:cost 0.850] |
| 170 | + [sqrt.f64 #:spec (sqrt x) #:impl (from-libm 'sqrt) #:cost 0.250] |
| 171 | + #;[tanh.f64 #:spec (tanh x) #:impl (from-libm 'tanh) #:cost 1.000] |
| 172 | + #;[tgamma.f64 #:spec (tgamma x) #:impl (from-libm 'tgamma) #:cost 2.625] |
| 173 | + #;[trunc.f64 #:spec (trunc x) #:impl (from-libm 'trunc) #:cost 0.250]) |
| 174 | + |
| 175 | +(define-operations ([x <binary64>] [y <binary64>]) <binary64> #:fpcore (! :precision binary64 _) |
| 176 | + [pow.f64 #:spec (pow x y) #:impl (from-libm 'pow) #:cost 2.000] |
| 177 | + #;[atan2.f64 #:spec (atan2 x y) #:impl (from-libm 'atan2) #:cost 2.000] |
| 178 | + #;[copysign.f64 #:spec (copysign x y) #:impl (from-libm 'copysign) #:cost 0.200] |
| 179 | + #;[fdim.f64 #:spec (fdim x y) #:impl (from-libm 'fdim) #:cost 0.750] |
| 180 | + [fmax.f64 #:spec (fmax x y) #:impl (from-libm 'fmax) #:cost 0.250] |
| 181 | + [fmin.f64 #:spec (fmin x y) #:impl (from-libm 'fmin) #:cost 0.250] |
| 182 | + #;[fmod.f64 #:spec (fmod x y) #:impl (from-libm 'fmod) #:cost 1.750] |
| 183 | + #;[remainder.f64 #:spec (remainder x y) #:impl (from-libm 'remainder) #:cost 1.000]) |
| 184 | + |
| 185 | +#;(define-operations ([x <binary64>]) <binary64> #:fpcore (! :precision binary64 _) |
| 186 | + [erfc.f64 #:spec (- 1 (erf x)) #:impl (from-libm 'erfc) #:fpcore (erfc x) #:cost 0.900] |
| 187 | + [expm1.f64 #:spec (- (exp x) 1) #:impl (from-libm 'expm1) #:fpcore (expm1 x) #:cost 0.900] |
| 188 | + [log1p.f64 #:spec (log (+ 1 x)) #:impl (from-libm 'log1p) #:fpcore (log1p x) #:cost 1.300]) |
| 189 | + |
| 190 | +#;(define-operation (hypot.f64 [x <binary64>] [y <binary64>]) <binary64> |
| 191 | + #:spec (sqrt (+ (* x x) (* y y))) #:impl (from-libm 'hypot) |
| 192 | + #:fpcore (! :precision binary64 (hypot x y)) #:cost 1.700) |
| 193 | + |
| 194 | +#;(define-operation (fma.f64 [x <binary64>] [y <binary64>] [z <binary64>]) <binary64> |
| 195 | + #:spec (+ (* x y) z) #:impl (from-libm 'fma) |
| 196 | + #:fpcore (! :precision binary64 (fma x y z)) #:cost 0.375) |
0 commit comments