2015-01-16 01:27:17 +00:00
|
|
|
#ifndef GMQCC_FOLD_HDR
|
|
|
|
#define GMQCC_FOLD_HDR
|
|
|
|
#include "lexer.h"
|
|
|
|
#include "gmqcc.h"
|
|
|
|
|
|
|
|
struct ir_builder;
|
|
|
|
struct ir_value;
|
|
|
|
|
|
|
|
struct ast_function;
|
|
|
|
struct ast_ifthen;
|
|
|
|
struct ast_ternary;
|
|
|
|
struct ast_expression;
|
|
|
|
struct ast_value;
|
|
|
|
|
|
|
|
struct parser_t;
|
|
|
|
|
|
|
|
struct fold {
|
|
|
|
fold();
|
|
|
|
fold(parser_t *parser);
|
|
|
|
~fold();
|
|
|
|
|
2021-03-28 00:32:24 +00:00
|
|
|
// Bitmask describing which branches of a conditional to take after folding.
|
|
|
|
// Zero indicates all the branches can be removed.
|
|
|
|
// ON_TRUE means ON_FALSE can be removed.
|
|
|
|
// ON_FALSE means ON_TRUE can be removed.
|
|
|
|
// ON_TRUE | ON_FALSE means nothing can be removed.
|
|
|
|
enum {
|
|
|
|
ON_TRUE = 1 << 0,
|
|
|
|
ON_FALSE = 1 << 1,
|
|
|
|
};
|
|
|
|
|
2015-01-16 01:27:17 +00:00
|
|
|
bool generate(ir_builder *ir);
|
|
|
|
ast_expression *op(const oper_info *info, ast_expression **opexprs);
|
2018-11-14 13:43:22 +00:00
|
|
|
ast_expression *intrinsic(const char *intrinsic, size_t n_args, ast_expression **args);
|
2015-01-16 01:27:17 +00:00
|
|
|
|
2021-03-28 00:32:24 +00:00
|
|
|
static uint32_t cond_ternary(ast_value *condval, ast_ternary *branch);
|
|
|
|
static uint32_t cond_ifthen(ast_value *condval, ast_ifthen *branch);
|
2015-01-16 01:27:17 +00:00
|
|
|
|
|
|
|
static ast_expression *superfluous(ast_expression *left, ast_expression *right, int op);
|
|
|
|
static ast_expression *binary(lex_ctx_t ctx, int op, ast_expression *left, ast_expression *right);
|
|
|
|
|
|
|
|
ast_expression *constgen_float(qcfloat_t value, bool inexact);
|
|
|
|
ast_expression *constgen_vector(vec3_t value);
|
|
|
|
ast_expression *constgen_string(const char *str, bool translate);
|
2015-01-30 17:59:48 +00:00
|
|
|
ast_expression *constgen_string(const std::string &str, bool translate);
|
2015-01-16 01:27:17 +00:00
|
|
|
|
|
|
|
ast_value *imm_float(size_t index) const { return m_imm_float[index]; }
|
|
|
|
ast_value *imm_vector(size_t index) const { return m_imm_vector[index]; }
|
|
|
|
|
|
|
|
protected:
|
|
|
|
static qcfloat_t immvalue_float(ast_value *value);
|
|
|
|
static vec3_t immvalue_vector(ast_value *value);
|
|
|
|
static const char *immvalue_string(ast_value *value);
|
|
|
|
|
|
|
|
lex_ctx_t ctx();
|
|
|
|
|
|
|
|
bool immediate_true(ast_value *v);
|
|
|
|
|
|
|
|
bool check_except_float_impl(void (*callback)(void), ast_value *a, ast_value *b);
|
|
|
|
bool check_inexact_float(ast_value *a, ast_value *b);
|
|
|
|
|
|
|
|
ast_expression *op_mul_vec(vec3_t vec, ast_value *sel, const char *set);
|
|
|
|
ast_expression *op_neg(ast_value *a);
|
|
|
|
ast_expression *op_not(ast_value *a);
|
|
|
|
ast_expression *op_add(ast_value *a, ast_value *b);
|
|
|
|
ast_expression *op_sub(ast_value *a, ast_value *b);
|
|
|
|
ast_expression *op_mul(ast_value *a, ast_value *b);
|
|
|
|
ast_expression *op_div(ast_value *a, ast_value *b);
|
|
|
|
ast_expression *op_mod(ast_value *a, ast_value *b);
|
|
|
|
ast_expression *op_bor(ast_value *a, ast_value *b);
|
|
|
|
ast_expression *op_band(ast_value *a, ast_value *b);
|
|
|
|
ast_expression *op_xor(ast_value *a, ast_value *b);
|
|
|
|
ast_expression *op_lshift(ast_value *a, ast_value *b);
|
|
|
|
ast_expression *op_rshift(ast_value *a, ast_value *b);
|
|
|
|
ast_expression *op_andor(ast_value *a, ast_value *b, float expr);
|
|
|
|
ast_expression *op_tern(ast_value *a, ast_value *b, ast_value *c);
|
|
|
|
ast_expression *op_exp(ast_value *a, ast_value *b);
|
|
|
|
ast_expression *op_lteqgt(ast_value *a, ast_value *b);
|
|
|
|
ast_expression *op_ltgt(ast_value *a, ast_value *b, bool lt);
|
|
|
|
ast_expression *op_cmp(ast_value *a, ast_value *b, bool ne);
|
|
|
|
ast_expression *op_bnot(ast_value *a);
|
|
|
|
ast_expression *op_cross(ast_value *a, ast_value *b);
|
|
|
|
ast_expression *op_length(ast_value *a);
|
|
|
|
|
|
|
|
ast_expression *intrinsic_isfinite(ast_value *a);
|
|
|
|
ast_expression *intrinsic_isinf(ast_value *a);
|
|
|
|
ast_expression *intrinsic_isnan(ast_value *a);
|
|
|
|
ast_expression *intrinsic_isnormal(ast_value *a);
|
|
|
|
ast_expression *intrinsic_signbit(ast_value *a);
|
|
|
|
ast_expression *intrinsic_acosh(ast_value *a);
|
|
|
|
ast_expression *intrinsic_asinh(ast_value *a);
|
|
|
|
ast_expression *intrinsic_atanh(ast_value *a);
|
|
|
|
ast_expression *intrinsic_exp(ast_value *a);
|
|
|
|
ast_expression *intrinsic_exp2(ast_value *a);
|
|
|
|
ast_expression *intrinsic_expm1(ast_value *a);
|
|
|
|
ast_expression *intrinsic_pow(ast_value *lhs, ast_value *rhs);
|
2018-11-14 13:43:22 +00:00
|
|
|
ast_expression *intrinsic_mod(ast_value *lhs, ast_value *rhs);
|
2015-01-16 01:27:17 +00:00
|
|
|
ast_expression *intrinsic_fabs(ast_value *a);
|
|
|
|
|
2018-11-14 13:43:22 +00:00
|
|
|
ast_expression* intrinsic_nan(void);
|
|
|
|
ast_expression* intrinsic_epsilon(void);
|
|
|
|
ast_expression* intrinsic_inf(void);
|
|
|
|
|
2015-01-16 01:27:17 +00:00
|
|
|
static qcfloat_t immvalue_float(ir_value *value);
|
|
|
|
static vec3_t immvalue_vector(ir_value *value);
|
|
|
|
|
2021-03-28 00:32:24 +00:00
|
|
|
static uint32_t cond(ast_value *condval, ast_ifthen *branch);
|
2015-01-16 01:27:17 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
friend struct intrin;
|
|
|
|
|
|
|
|
std::vector<ast_value*> m_imm_float;
|
|
|
|
std::vector<ast_value*> m_imm_vector;
|
|
|
|
std::vector<ast_value*> m_imm_string;
|
|
|
|
hash_table_t *m_imm_string_untranslate; /* map<string, ast_value*> */
|
|
|
|
hash_table_t *m_imm_string_dotranslate; /* map<string, ast_value*> */
|
|
|
|
parser_t *m_parser;
|
|
|
|
bool m_initialized;
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|