mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-25 13:11:00 +00:00
[qfcc] Implement cast and ?: expressions for spir-v
Unfortunately, there are some bugs with the result of comparisons (getting int instead of bool in the spir-v).
This commit is contained in:
parent
81cc736683
commit
7ad6aff928
4 changed files with 102 additions and 5 deletions
|
@ -348,6 +348,25 @@ print_type_expr (dstring_t *dstr, const expr_t *e, int level, int id,
|
||||||
str, e->loc.line);
|
str, e->loc.line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_cond (dstring_t *dstr, const expr_t *e, int level, int id,
|
||||||
|
const expr_t *next)
|
||||||
|
{
|
||||||
|
int indent = level * 2 + 2;
|
||||||
|
|
||||||
|
_print_expr (dstr, e->cond.test, level, id, next);
|
||||||
|
_print_expr (dstr, e->cond.true_expr, level, id, next);
|
||||||
|
_print_expr (dstr, e->cond.false_expr, level, id, next);
|
||||||
|
dasprintf (dstr, "%*se_%p -> \"e_%p\" [label=\"?\"];\n", indent, "", e,
|
||||||
|
e->cond.test);
|
||||||
|
dasprintf (dstr, "%*se_%p -> \"e_%p\" [label=\"t\"];\n", indent, "", e,
|
||||||
|
e->cond.true_expr);
|
||||||
|
dasprintf (dstr, "%*se_%p -> \"e_%p\" [label=\"f\"];\n", indent, "", e,
|
||||||
|
e->cond.false_expr);
|
||||||
|
dasprintf (dstr, "%*se_%p [label=\"%s\\n%d\"];\n", indent, "", e,
|
||||||
|
"?:", e->loc.line);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_field (dstring_t *dstr, const expr_t *e, int level, int id,
|
print_field (dstring_t *dstr, const expr_t *e, int level, int id,
|
||||||
const expr_t *next)
|
const expr_t *next)
|
||||||
|
@ -814,7 +833,7 @@ _print_expr (dstring_t *dstr, const expr_t *e, int level, int id,
|
||||||
[ex_list] = print_list,
|
[ex_list] = print_list,
|
||||||
[ex_type] = print_type_expr,
|
[ex_type] = print_type_expr,
|
||||||
[ex_incop] = nullptr,
|
[ex_incop] = nullptr,
|
||||||
[ex_cond] = nullptr,
|
[ex_cond] = print_cond,
|
||||||
[ex_field] = print_field,
|
[ex_field] = print_field,
|
||||||
[ex_array] = nullptr,
|
[ex_array] = nullptr,
|
||||||
[ex_decl] = nullptr,
|
[ex_decl] = nullptr,
|
||||||
|
|
|
@ -308,6 +308,15 @@ proc_return (const expr_t *expr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const expr_t *
|
||||||
|
proc_cond (const expr_t *expr)
|
||||||
|
{
|
||||||
|
auto test = expr_process (expr->cond.test);
|
||||||
|
auto true_expr = expr_process (expr->cond.true_expr);
|
||||||
|
auto false_expr = expr_process (expr->cond.false_expr);
|
||||||
|
return new_cond_expr (test, true_expr, false_expr);
|
||||||
|
}
|
||||||
|
|
||||||
static const expr_t *
|
static const expr_t *
|
||||||
proc_decl (const expr_t *expr)
|
proc_decl (const expr_t *expr)
|
||||||
{
|
{
|
||||||
|
@ -352,10 +361,9 @@ const expr_t *
|
||||||
expr_process (const expr_t *expr)
|
expr_process (const expr_t *expr)
|
||||||
{
|
{
|
||||||
static process_f funcs[ex_count] = {
|
static process_f funcs[ex_count] = {
|
||||||
|
[ex_block] = proc_block,
|
||||||
[ex_expr] = proc_expr,
|
[ex_expr] = proc_expr,
|
||||||
[ex_uexpr] = proc_uexpr,
|
[ex_uexpr] = proc_uexpr,
|
||||||
[ex_field] = proc_field,
|
|
||||||
[ex_block] = proc_block,
|
|
||||||
[ex_symbol] = proc_symbol,
|
[ex_symbol] = proc_symbol,
|
||||||
[ex_vector] = proc_vector,
|
[ex_vector] = proc_vector,
|
||||||
[ex_value] = proc_value,
|
[ex_value] = proc_value,
|
||||||
|
@ -363,6 +371,8 @@ expr_process (const expr_t *expr)
|
||||||
[ex_assign] = proc_assign,
|
[ex_assign] = proc_assign,
|
||||||
[ex_branch] = proc_branch,
|
[ex_branch] = proc_branch,
|
||||||
[ex_return] = proc_return,
|
[ex_return] = proc_return,
|
||||||
|
[ex_cond] = proc_cond,
|
||||||
|
[ex_field] = proc_field,
|
||||||
[ex_decl] = proc_decl,
|
[ex_decl] = proc_decl,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -595,7 +595,7 @@ conditional_expression
|
||||||
: logical_or_expression
|
: logical_or_expression
|
||||||
| logical_or_expression '?' expression ':' assignment_expression
|
| logical_or_expression '?' expression ':' assignment_expression
|
||||||
{
|
{
|
||||||
$$ = conditional_expr ($1, $3, $5);
|
$$ = new_cond_expr ($1, $3, $5);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -657,7 +657,7 @@ static spvop_t spv_ops[] = {
|
||||||
|
|
||||||
{"eq", SpvOpIEqual, SPV_INT, SPV_INT },
|
{"eq", SpvOpIEqual, SPV_INT, SPV_INT },
|
||||||
{"eq", SpvOpFOrdEqual, SPV_FLOAT, SPV_FLOAT },
|
{"eq", SpvOpFOrdEqual, SPV_FLOAT, SPV_FLOAT },
|
||||||
{"eq", SpvOpFOrdNotEqual, SPV_FLOAT, SPV_FLOAT },
|
{"ne", SpvOpFOrdNotEqual, SPV_FLOAT, SPV_FLOAT },
|
||||||
{"ne", SpvOpINotEqual, SPV_INT, SPV_INT },
|
{"ne", SpvOpINotEqual, SPV_INT, SPV_INT },
|
||||||
{"le", SpvOpULessThanEqual, SPV_UINT, SPV_UINT },
|
{"le", SpvOpULessThanEqual, SPV_UINT, SPV_UINT },
|
||||||
{"le", SpvOpSLessThanEqual, SPV_SINT, SPV_SINT },
|
{"le", SpvOpSLessThanEqual, SPV_SINT, SPV_SINT },
|
||||||
|
@ -732,9 +732,57 @@ spirv_find_op (const char *op_name, etype_t type1, etype_t type2)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned
|
||||||
|
spirv_cast (const expr_t *e, spirvctx_t *ctx)
|
||||||
|
{
|
||||||
|
auto src_type = get_type (e->expr.e1);
|
||||||
|
auto dst_type = e->expr.type;
|
||||||
|
SpvOp op = 0;
|
||||||
|
if (is_real (src_type)) {
|
||||||
|
if (is_unsigned (dst_type)) {
|
||||||
|
op = SpvOpConvertFToU;
|
||||||
|
} else if (is_signed (dst_type)) {
|
||||||
|
op = SpvOpConvertFToS;
|
||||||
|
} else if (is_real (dst_type)) {
|
||||||
|
op = SpvOpFConvert;
|
||||||
|
}
|
||||||
|
} else if (is_real (dst_type)) {
|
||||||
|
if (is_unsigned (src_type)) {
|
||||||
|
op = SpvOpConvertUToF;
|
||||||
|
} else if (is_signed (src_type)) {
|
||||||
|
op = SpvOpConvertSToF;
|
||||||
|
}
|
||||||
|
} else if (is_unsigned (dst_type)) {
|
||||||
|
if (type_size (base_type (dst_type))
|
||||||
|
!= type_size (base_type (src_type))) {
|
||||||
|
op = SpvOpUConvert;
|
||||||
|
}
|
||||||
|
} else if (is_signed (dst_type)) {
|
||||||
|
if (type_size (base_type (dst_type))
|
||||||
|
!= type_size (base_type (src_type))) {
|
||||||
|
op = SpvOpSConvert;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!op) {
|
||||||
|
internal_error (e, "unexpected type combination");
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned cid = spirv_emit_expr (e->expr.e1, ctx);
|
||||||
|
unsigned tid = type_id (dst_type, ctx);
|
||||||
|
unsigned id = spirv_id (ctx);
|
||||||
|
auto insn = spirv_new_insn (op, 4, ctx->code_space);
|
||||||
|
INSN (insn, 1) = tid;
|
||||||
|
INSN (insn, 2) = id;
|
||||||
|
INSN (insn, 3) = cid;
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
static unsigned
|
static unsigned
|
||||||
spirv_uexpr (const expr_t *e, spirvctx_t *ctx)
|
spirv_uexpr (const expr_t *e, spirvctx_t *ctx)
|
||||||
{
|
{
|
||||||
|
if (e->expr.op == 'C') {
|
||||||
|
return spirv_cast (e, ctx);
|
||||||
|
}
|
||||||
auto op_name = convert_op (e->expr.op);
|
auto op_name = convert_op (e->expr.op);
|
||||||
if (!op_name) {
|
if (!op_name) {
|
||||||
if (e->expr.op > 32 && e->expr.op < 127) {
|
if (e->expr.op > 32 && e->expr.op < 127) {
|
||||||
|
@ -1074,6 +1122,25 @@ spirv_extend (const expr_t *e, spirvctx_t *ctx)
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned
|
||||||
|
spirv_cond (const expr_t *e, spirvctx_t *ctx)
|
||||||
|
{
|
||||||
|
unsigned test_id = spirv_emit_expr (e->cond.test, ctx);
|
||||||
|
unsigned true_id = spirv_emit_expr (e->cond.true_expr, ctx);
|
||||||
|
unsigned false_id = spirv_emit_expr (e->cond.false_expr, ctx);
|
||||||
|
|
||||||
|
auto type = get_type (e);
|
||||||
|
unsigned tid = type_id (type, ctx);
|
||||||
|
unsigned id = spirv_id (ctx);
|
||||||
|
auto insn = spirv_new_insn (SpvOpSelect, 6, ctx->code_space);
|
||||||
|
INSN (insn, 1) = tid;
|
||||||
|
INSN (insn, 2) = id;
|
||||||
|
INSN (insn, 3) = test_id;
|
||||||
|
INSN (insn, 4) = true_id;
|
||||||
|
INSN (insn, 5) = false_id;
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
static unsigned
|
static unsigned
|
||||||
spirv_field (const expr_t *e, spirvctx_t *ctx)
|
spirv_field (const expr_t *e, spirvctx_t *ctx)
|
||||||
{
|
{
|
||||||
|
@ -1145,6 +1212,7 @@ spirv_emit_expr (const expr_t *e, spirvctx_t *ctx)
|
||||||
[ex_branch] = spirv_branch,
|
[ex_branch] = spirv_branch,
|
||||||
[ex_return] = spirv_return,
|
[ex_return] = spirv_return,
|
||||||
[ex_extend] = spirv_extend,
|
[ex_extend] = spirv_extend,
|
||||||
|
[ex_cond] = spirv_cond,
|
||||||
[ex_field] = spirv_field,
|
[ex_field] = spirv_field,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue