-
Notifications
You must be signed in to change notification settings - Fork 73
Description
See:
copilot/copilot-c99/src/Copilot/Compile/C99/Translate.hs
Lines 56 to 106 in 11ab89f
| transop1 :: Op1 a b -> C.Expr -> C.Expr | |
| transop1 op e = case op of | |
| Not -> (C..!) e | |
| Abs _ -> funcall "abs" [e] | |
| Sign _ -> funcall "copysign" [C.LitDouble 1.0, e] | |
| Recip _ -> C.LitDouble 1.0 C../ e | |
| Exp _ -> funcall "exp" [e] | |
| Sqrt _ -> funcall "sqrt" [e] | |
| Log _ -> funcall "log" [e] | |
| Sin _ -> funcall "sin" [e] | |
| Tan _ -> funcall "tan" [e] | |
| Cos _ -> funcall "cos" [e] | |
| Asin _ -> funcall "asin" [e] | |
| Atan _ -> funcall "atan" [e] | |
| Acos _ -> funcall "acos" [e] | |
| Sinh _ -> funcall "sinh" [e] | |
| Tanh _ -> funcall "tanh" [e] | |
| Cosh _ -> funcall "cosh" [e] | |
| Asinh _ -> funcall "asinh" [e] | |
| Atanh _ -> funcall "atanh" [e] | |
| Acosh _ -> funcall "acosh" [e] | |
| BwNot _ -> (C..~) e | |
| Cast _ ty -> C.Cast (transtypename ty) e | |
| GetField (Struct _) _ f -> C.Dot e (accessorname f) | |
| -- | Translates a Copilot binary operator and its arguments into a C99 | |
| -- expression. | |
| transop2 :: Op2 a b c -> C.Expr -> C.Expr -> C.Expr | |
| transop2 op e1 e2 = case op of | |
| And -> e1 C..&& e2 | |
| Or -> e1 C..|| e2 | |
| Add _ -> e1 C..+ e2 | |
| Sub _ -> e1 C..- e2 | |
| Mul _ -> e1 C..* e2 | |
| Mod _ -> e1 C..% e2 | |
| Div _ -> e1 C../ e2 | |
| Fdiv _ -> e1 C../ e2 | |
| Pow _ -> funcall "pow" [e1, e2] | |
| Logb _ -> funcall "log" [e2] C../ funcall "log" [e1] | |
| Eq _ -> e1 C..== e2 | |
| Ne _ -> e1 C..!= e2 | |
| Le _ -> e1 C..<= e2 | |
| Ge _ -> e1 C..>= e2 | |
| Lt _ -> e1 C..< e2 | |
| Gt _ -> e1 C..> e2 | |
| BwAnd _ -> e1 C..& e2 | |
| BwOr _ -> e1 C..| e2 | |
| BwXor _ -> e1 C..^ e2 | |
| BwShiftL _ _ -> e1 C..<< e2 | |
| BwShiftR _ _ -> e1 C..>> e2 | |
| Index _ -> C.Index e1 e2 |
Code generation selects a function to call based only on the operation, without paying attention the type. This is almost certainly not what is desired. For example abs is a function on int, but is applied also to float and double values. This causes the C compiler to (silently (!)) perform numerical coercions to/from int. Instead the generator should select fabs or fabsf. Likewise choosing between copysign or copysignf, cos or cosf, etc.
The abs case for integer values is actually even tricker, as copilot uses the fixed-width intX_t types, but, as far as I know, the standard library does not provide operations for fixed-width types, but instead only provides abs, labs, and llabs for int, long and long long respectively. The Sign operation is also troublesome, as it applies also to integer operations on the copilot side, but has no corresponding C primitive that I know of. These may have to be provided as macros to get correct behavior.