public
Last active

  • Download Gist
minmax.c
C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
-- minmax.h
float max_ss(float a, float b);
float min_ss(float a, float b);
 
double max_sd(double a, double b);
double min_sd(double a, double b);
 
float clamp_ss(float x, float mn, float mx);
double clamp_sd(double x, double mn, double mx);
 
-- minmax.c
#include "minmax.h"
#include <xmmintrin.h>
#include <emmintrin.h>
 
inline float max_ss(float a, float b) {
_mm_store_ss(&a, _mm_max_ss(_mm_set_ss(a), _mm_set_ss(b)));
return a;
}
 
inline float min_ss(float a, float b) {
_mm_store_ss(&a, _mm_min_ss(_mm_set_ss(a), _mm_set_ss(b)));
return a;
}
 
inline double max_sd(double a, double b) {
_mm_store_sd(&a, _mm_max_sd(_mm_set_sd(a), _mm_set_sd(b)));
return a;
}
 
inline double min_sd(double a, double b) {
_mm_store_sd(&a, _mm_min_sd(_mm_set_sd(a), _mm_set_sd(b)));
return a;
}
 
inline float clamp_ss(float x, float mn, float mx) {
_mm_store_ss(&x, _mm_min_ss(_mm_max_ss(_mm_set_ss(x),
_mm_set_ss(mn)), _mm_set_ss(mx)));
return x;
}
 
inline double clamp_sd(double x, double mn, double mx) {
_mm_store_sd(&x, _mm_min_sd(_mm_max_sd(_mm_set_sd(x),
_mm_set_sd(mn)), _mm_set_sd(mx)));
return x;
}
 
-- MinMax.hs
{-# LANGUAGE ForeignFunctionInterface, CPP #-}
 
module MinMax (
max_ss, min_ss,
max_sd, min_sd,
clamp_ss, clamp_sd
) where
 
import Foreign
import Foreign.C.Types
 
#define FFI_MM(name,cname,ty) \
foreign import ccall unsafe "minmax.c name" cname :: ty -> ty -> ty ;\
name :: RealFloat a => a -> a -> a ;\
name a b = realToFrac $ cname (realToFrac a) (realToFrac b) ;\
{-# INLINE cname #-} ;\
{-# INLINE name #-}
 
FFI_MM(max_ss,c_max_ss,CFloat)
FFI_MM(min_ss,c_min_ss,CFloat)
FFI_MM(max_sd,c_max_sd,CDouble)
FFI_MM(min_sd,c_min_sd,CDouble)
 
 
#define FFI_CLAMP(name,cname,ty) \
foreign import ccall unsafe "minmax.c name" cname :: ty -> ty -> ty -> ty ;\
name :: RealFloat a => a -> a -> a -> a ;\
name mn mx x = realToFrac $ \
cname (realToFrac x) (realToFrac mn) (realToFrac mx) ;\
{-# INLINE cname #-} ;\
{-# INLINE name #-}
 
FFI_CLAMP(clamp_ss,c_clamp_ss,CFloat)
FFI_CLAMP(clamp_sd,c_clamp_sd,CFloat)

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.