From e2bfaf8109631880ec25cc23d4ce36f4d05e1485 Mon Sep 17 00:00:00 2001 From: Dale Weiler Date: Sat, 23 Nov 2013 07:37:26 -0500 Subject: [PATCH] Implemented exp2 intrinsic --- fold.c | 5 +++++ intrin.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/fold.c b/fold.c index c75106a..823184f 100644 --- a/fold.c +++ b/fold.c @@ -725,6 +725,10 @@ static GMQCC_INLINE ast_expression *fold_intrin_exp(fold_t *fold, ast_value *val return fold_constgen_float(fold, exp(fold_immvalue_float(value))); } +static GMQCC_INLINE ast_expression *fold_intrin_exp2(fold_t *fold, ast_value *value) { + return fold_constgen_float(fold, pow(2, fold_immvalue_float(value))); +} + static GMQCC_INLINE ast_expression *fold_intrin_isnan(fold_t *fold, ast_value *value) { return fold_constgen_float(fold, isnan(fold_immvalue_float(value)) != 0.0f); } @@ -739,6 +743,7 @@ ast_expression *fold_intrin(fold_t *fold, const char *intrin, ast_expression **a if (!strcmp(intrin, "mod")) ret = fold_intrin_mod (fold, (ast_value*)arg[0], (ast_value*)arg[1]); if (!strcmp(intrin, "pow")) ret = fold_intrin_pow (fold, (ast_value*)arg[0], (ast_value*)arg[1]); if (!strcmp(intrin, "exp")) ret = fold_intrin_exp (fold, (ast_value*)arg[0]); + if (!strcmp(intrin, "exp2")) ret = fold_intrin_exp2 (fold, (ast_value*)arg[0]); if (!strcmp(intrin, "isnan")) ret = fold_intrin_isnan(fold, (ast_value*)arg[0]); if (!strcmp(intrin, "fabs")) ret = fold_intrin_fabs (fold, (ast_value*)arg[0]); diff --git a/intrin.c b/intrin.c index acd3846..0ab2789 100644 --- a/intrin.c +++ b/intrin.c @@ -647,6 +647,37 @@ static ast_expression *intrin_exp(intrin_t *intrin) { return (ast_expression*)value; } +static ast_expression *intrin_exp2(intrin_t *intrin) { + /* + * float exp2(float x) { + * return pow(2, x); + * } + */ + ast_value *value = NULL; + ast_call *callpow = ast_call_new (intrin_ctx(intrin), intrin_func_self(intrin, "pow", "exp2")); + ast_value *arg1 = ast_value_new(intrin_ctx(intrin), "x", TYPE_FLOAT); + ast_block *body = ast_block_new(intrin_ctx(intrin)); + ast_function *func = intrin_value(intrin, &value, "exp2", TYPE_FLOAT); + + vec_push(value->expression.params, arg1); + + vec_push(callpow->params, (ast_expression*)fold_constgen_float(intrin->fold, 2.0f)); + vec_push(callpow->params, (ast_expression*)arg1); + + /* return */ + vec_push(body->exprs, + (ast_expression*)ast_return_new( + intrin_ctx(intrin), + (ast_expression*)callpow + ) + ); + + vec_push(func->blocks, body); + + intrin_reg(intrin, value, func); + return (ast_expression*)value; +} + static ast_expression *intrin_isnan(intrin_t *intrin) { /* * float isnan(float x) { @@ -743,6 +774,7 @@ ast_expression *intrin_debug_typestring(intrin_t *intrin) { static const intrin_func_t intrinsics[] = { {&intrin_exp, "__builtin_exp", "exp", 1}, + {&intrin_exp2, "__builtin_exp2", "exp2", 1}, {&intrin_mod, "__builtin_mod", "mod", 2}, {&intrin_pow, "__builtin_pow", "pow", 2}, {&intrin_isnan, "__builtin_isnan", "isnan", 1}, -- 2.39.2