mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-04-07 01:42:04 +00:00
[qfcc] Add an intrinsic expression type
This will be fore generating specific SPIR-V instructions via function calls, and could be useful for Ruamoko, too.
This commit is contained in:
parent
0dfe81bce8
commit
1893df34a3
7 changed files with 55 additions and 0 deletions
|
@ -373,6 +373,12 @@ typedef struct {
|
|||
bool not;
|
||||
} ex_select_t;
|
||||
|
||||
typedef struct {
|
||||
const expr_t *opcode;
|
||||
const type_t *res_type;
|
||||
ex_list_t operands;
|
||||
} ex_intrinsic_t;
|
||||
|
||||
typedef struct expr_s {
|
||||
expr_t *next;
|
||||
rua_loc_t loc; ///< source location of expression
|
||||
|
@ -421,6 +427,7 @@ typedef struct expr_s {
|
|||
ex_decl_t decl; ///< variable declaration expression
|
||||
ex_loop_t loop; ///< loop construct expression
|
||||
ex_select_t select; ///< selection construct expression
|
||||
ex_intrinsic_t intrinsic; ///< intrinsic intruction expression
|
||||
};
|
||||
} expr_t;
|
||||
|
||||
|
|
|
@ -76,6 +76,7 @@ EX_EXPR(array) ///< array index expression (::ex_array_t)
|
|||
EX_EXPR(decl) ///< delcaration expression (::ex_array_t)
|
||||
EX_EXPR(loop) ///< loop construct expression (::ex_loop_t)
|
||||
EX_EXPR(select) ///< select construct expression (::ex_select_t)
|
||||
EX_EXPR(intrinsic) ///< intrinsic instruction expression (::ex_intrinsic_t)
|
||||
|
||||
#undef EX_EXPR
|
||||
|
||||
|
|
|
@ -399,6 +399,22 @@ print_array (dstring_t *dstr, const expr_t *e, int level, int id,
|
|||
"[]", e->loc.line);
|
||||
}
|
||||
|
||||
static void
|
||||
print_intrinsic (dstring_t *dstr, const expr_t *e, int level, int id,
|
||||
const expr_t *next)
|
||||
{
|
||||
int indent = level * 2 + 2;
|
||||
|
||||
_print_expr (dstr, e->intrinsic.opcode, level, id, next);
|
||||
for (auto l = e->intrinsic.operands.head; l; l = l->next) {
|
||||
_print_expr (dstr, l->expr, level, id, next);
|
||||
}
|
||||
for (auto l = e->intrinsic.operands.head; l; l = l->next) {
|
||||
dasprintf (dstr, "%*se_%p -> \"e_%p\" [label=\"b\"];\n", indent, "", e,
|
||||
l->expr);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_subexpr (dstring_t *dstr, const expr_t *e, int level, int id, const expr_t *next)
|
||||
{
|
||||
|
@ -854,6 +870,9 @@ _print_expr (dstring_t *dstr, const expr_t *e, int level, int id,
|
|||
[ex_field] = print_field,
|
||||
[ex_array] = print_array,
|
||||
[ex_decl] = nullptr,
|
||||
[ex_loop] = nullptr,
|
||||
[ex_select] = nullptr,
|
||||
[ex_intrinsic] = print_intrinsic,
|
||||
};
|
||||
int indent = level * 2 + 2;
|
||||
|
||||
|
|
|
@ -224,6 +224,9 @@ get_type (const expr_t *e)
|
|||
return e->field.type;
|
||||
case ex_array:
|
||||
return e->array.type;
|
||||
case ex_intrinsic:
|
||||
type = e->intrinsic.res_type;
|
||||
break;
|
||||
case ex_count:
|
||||
internal_error (e, "invalid expression");
|
||||
}
|
||||
|
@ -1990,6 +1993,7 @@ has_function_call (const expr_t *e)
|
|||
case ex_decl:
|
||||
case ex_loop:
|
||||
case ex_select:
|
||||
case ex_intrinsic:
|
||||
return false;
|
||||
case ex_multivec:
|
||||
for (auto c = e->multivec.components.head; c; c = c->next) {
|
||||
|
|
|
@ -136,6 +136,7 @@ is_lvalue (const expr_t *expr)
|
|||
case ex_decl:
|
||||
case ex_loop:
|
||||
case ex_select:
|
||||
case ex_intrinsic:
|
||||
break;
|
||||
case ex_cond:
|
||||
return (is_lvalue (expr->cond.true_expr)
|
||||
|
|
|
@ -82,6 +82,7 @@ edag_add_expr (const expr_t *expr)
|
|||
case ex_decl:
|
||||
case ex_loop:
|
||||
case ex_select:
|
||||
case ex_intrinsic:
|
||||
// these are never put in the dag
|
||||
return expr;
|
||||
case ex_list:
|
||||
|
|
|
@ -414,6 +414,27 @@ proc_select (const expr_t *expr)
|
|||
return select;
|
||||
}
|
||||
|
||||
static const expr_t *
|
||||
proc_intrinsic (const expr_t *expr)
|
||||
{
|
||||
int count = list_count (&expr->intrinsic.operands);
|
||||
const expr_t *operands[count + 1];
|
||||
list_scatter (&expr->intrinsic.operands, operands);
|
||||
auto opcode = expr_process (expr->intrinsic.opcode);
|
||||
for (int i = 0; i < count; i++) {
|
||||
operands[i] = expr_process (operands[i]);
|
||||
}
|
||||
scoped_src_loc (expr);
|
||||
auto e = new_expr ();
|
||||
e->type = ex_intrinsic;
|
||||
e->intrinsic = (ex_intrinsic_t) {
|
||||
.opcode = opcode,
|
||||
.res_type = expr->intrinsic.res_type,
|
||||
};
|
||||
list_gather (&e->intrinsic.operands, operands, count);
|
||||
return e;
|
||||
}
|
||||
|
||||
const expr_t *
|
||||
expr_process (const expr_t *expr)
|
||||
{
|
||||
|
@ -438,6 +459,7 @@ expr_process (const expr_t *expr)
|
|||
[ex_decl] = proc_decl,
|
||||
[ex_loop] = proc_loop,
|
||||
[ex_select] = proc_select,
|
||||
[ex_intrinsic] = proc_intrinsic,
|
||||
};
|
||||
|
||||
if (expr->type >= ex_count) {
|
||||
|
|
Loading…
Reference in a new issue