[qfcc] Use the new 2d wedge and 2-component swizzles

This cleans up the generated geometric algebra a little bit and, more
importantly, fixes #58.
This commit is contained in:
Bill Currie 2023-08-31 20:22:59 +09:00
parent e61be2f80f
commit d11f7be6bf
8 changed files with 75 additions and 102 deletions

View file

@ -182,6 +182,7 @@ type_t *base_type (const type_t *vec_type) __attribute__((pure));
null if no such match can be made.
*/
type_t *int_type (const type_t *base) __attribute__((pure));
type_t *uint_type (const type_t *base) __attribute__((pure));
/** Return a floating point type of same size as the provided type.

View file

@ -92,9 +92,12 @@ get_op_string (int op)
case SHR: return ">>";
case '.': return ".";
case 'C': return "<cast>";
case HADAMARD: return "@hadamard";
case CROSS: return "@cross";
case DOT: return "@dot";
case HADAMARD: return "@hadamard";
case WEDGE: return "@wedge";
case REGRESSIVE:return "@regressive";
case GEOMETRIC:return "@geometric";
case SCALE: return "@scale";
default:
return "unknown";

View file

@ -179,74 +179,6 @@ use_tempop (operand_t *op, expr_t *expr)
bug (expr, "temp users went negative: %s", operand_string (op));
}
static def_t *
cover_def_32 (def_t *def, int *adj)
{
int offset = def->offset;
def_t *cover = def;
if (def->alias) {
offset += def->alias->offset;
}
*adj = offset & 3;
if (offset & 3) {
if (def->alias) {
cover = cover_alias_def (def->alias, def->type,
def->offset - (offset & 3));
} else {
cover = cover_alias_def (def, def->type, -(offset & 3));
}
}
return cover;
}
static def_t *
cover_def_64 (def_t *def, int *adj)
{
int offset = def->offset;
def_t *cover = def;
if (def->alias) {
offset += def->alias->offset;
}
if (offset & 1) {
internal_error (0, "misaligned 64-bit swizzle source");
}
*adj = (offset & 6) >> 1;
if (offset & 6) {
if (def->alias) {
cover = cover_alias_def (def->alias, def->type,
def->offset - (offset & 6));
} else {
cover = cover_alias_def (def, def->type, -(offset & 6));
}
}
return cover;
}
static def_t *
cover_def (def_t *def, int *adj)
{
if (type_size (base_type (def->type)) == 1) {
return cover_def_32 (def, adj);
} else {
return cover_def_64 (def, adj);
}
}
static void
adjust_swizzle (def_t *def, int adj)
{
pr_ushort_t swiz = def->offset;
for (int i = 0; i < 8; i += 2) {
pr_ushort_t mask = 3 << i;
pr_ushort_t ind = swiz & mask;
swiz &= ~mask;
swiz |= (ind + (adj << i)) & mask;
}
def->offset = swiz;
}
static void
emit_statement (statement_t *statement)
{
@ -279,17 +211,11 @@ emit_statement (statement_t *statement)
use_tempop (op_c, statement->expr);
if (strcmp (opcode, "swizzle") == 0) {
op_c->type = float_type (op_c->type);
op_a->type = float_type (op_a->type);
op_c = alias_operand (uint_type (op_c->type), op_c, statement->expr);
op_a = alias_operand (uint_type (op_a->type), op_a, statement->expr);
if (!op_c->type || !op_a->type) {
internal_error (statement->expr, "invalid types in swizzle");
}
if (op_a->width < 4) {
int adj;
def_a = cover_def (def_a, &adj);
adjust_swizzle (def_b, adj);
op_a->width = 4;
}
}
inst = opcode_find (opcode, op_a, op_b, op_c);

View file

@ -648,7 +648,6 @@ new_swizzle_expr (expr_t *src, const char *swizzle)
return src;
}
int src_width = type_width (src_type);
// swizzle always generates a *vec4
ex_swizzle_t swiz = {};
#define m(x) (1 << ((x) - 'a'))
@ -699,8 +698,8 @@ new_swizzle_expr (expr_t *src, const char *swizzle)
}
}
swiz.zero |= (0xf << comp_count) & 0xf;
swiz.src = new_alias_expr (vector_type (base_type (src_type), src_width), src);
swiz.type = vector_type (base_type (src_type), 4);
swiz.src = src;
swiz.type = src_type;
expr_t *expr = new_expr ();
expr->type = ex_swizzle;

View file

@ -301,7 +301,7 @@ scale_expr (type_t *type, expr_t *a, expr_t *b)
if (!is_scalar (get_type (b)) || !is_real (get_type (b))) {
internal_error (b, "not a real scalar type");
}
if (!is_real (get_type (a))) {
if (!is_real (get_type (b))) {
internal_error (b, "not a real scalar type");
}
int op = is_scalar (get_type (a)) ? '*' : SCALE;
@ -327,6 +327,14 @@ cross_expr (type_t *type, expr_t *a, expr_t *b)
return cross;
}
static expr_t *
wedge_expr (type_t *type, expr_t *a, expr_t *b)
{
auto cross = new_binary_expr (WEDGE, a, b);
cross->e.expr.type = type;
return cross;
}
typedef void (*pga_func) (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg);
static void
scale_component (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
@ -463,7 +471,7 @@ pga3_wxyz_dot_x_y_z_w (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
{
auto stype = alg->type;
auto dot_type = algebra_mvec_type (alg, 0x20);
auto vb = offset_cast (dot_type, new_swizzle_expr (b, "-x-y-z0"), 0);
auto vb = new_swizzle_expr (b, "-x-y-z0");
auto sa = offset_cast (stype, a, 0);
c[5] = scale_expr (dot_type, vb, sa);
}
@ -599,13 +607,18 @@ static void
pga2_yw_wx_xy_dot_x_y_w (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
{
auto stype = alg->type;
auto wtype = vector_type (stype, 2);
auto vtype = vector_type (stype, 3);
auto dot_type = algebra_mvec_type (alg, 0x04);
auto vb = offset_cast (dot_type, new_swizzle_expr (b, "y-x0"), 0);
auto va = offset_cast (wtype, a, 0);
auto sa = offset_cast (stype, a, 2);
auto tmp = offset_cast (stype, cross_expr (vtype, b, a), 2);
tmp = new_extend_expr (tmp, dot_type, 0, true);
c[2] = sum_expr (dot_type, '+', scale_expr (dot_type, vb, sa), tmp);
auto vb = offset_cast (wtype, b, 0);
auto cv = new_swizzle_expr (vb, "y-x");
auto cs = wedge_expr (stype, vb, va);
cs = new_extend_expr (cs, dot_type, 0, true);
c[2] = sum_expr (dot_type, '+', cs,
new_extend_expr (scale_expr (wtype, cv, sa), vtype,
0, false));
}
static void
@ -623,13 +636,15 @@ static void
pga2_x_y_w_dot_yw_wx_xy (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
{
auto stype = alg->type;
auto vtype = vector_type (stype, 3);
auto wtype = vector_type (stype, 2);
auto dot_type = algebra_mvec_type (alg, 0x04);
auto va = offset_cast (vtype, new_swizzle_expr (a, "-yx0"), 0);
auto va = offset_cast (wtype, a, 0);
auto vb = offset_cast (wtype, b, 0);
auto sb = offset_cast (stype, b, 2);
auto tmp = offset_cast (stype, cross_expr (vtype, b, a), 2);
tmp = new_extend_expr (tmp, dot_type, 0, true);
c[2] = sum_expr (dot_type, '+', tmp, scale_expr (dot_type, va, sb));
auto cv = new_swizzle_expr (a, "-yx");
auto cs = wedge_expr (stype, vb, va);
cs = new_extend_expr (cs, dot_type, 0, true);
c[2] = sum_expr (dot_type, '+', cs, scale_expr (dot_type, cv, sb));
}
static void
@ -1284,12 +1299,14 @@ static void
pga2_yw_wx_xy_geom_yw_wx_xy (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
{
auto stype = alg->type;
auto vtype = vector_type (stype, 3);
auto ctype = vector_type (stype, 2);
auto geom_type = algebra_mvec_type (alg, 0x01);
auto sa = offset_cast (stype, a, 2);
auto sb = offset_cast (stype, b, 2);
auto cv = cross_expr (geom_type, b, a);
auto cv = new_offset_alias_expr (ctype, cross_expr (vtype, b, a), 0);
c[0] = offset_cast (geom_type, new_swizzle_expr (cv, "xy0"), 0);
c[0] = new_extend_expr (cv, geom_type, 0, false);
c[1] = unary_expr ('-', scale_expr (algebra_mvec_type (alg, 0x02), sa, sb));
}
@ -1297,13 +1314,18 @@ static void
pga2_yw_wx_xy_geom_x_y_w (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
{
auto stype = alg->type;
auto wtype = vector_type (stype, 2);
auto vtype = vector_type (stype, 3);
auto geom_type = algebra_mvec_type (alg, 0x04);
auto va = offset_cast (wtype, a, 0);
auto sa = offset_cast (stype, a, 2);
auto vb = offset_cast (vtype, new_swizzle_expr (b, "y-x0"), 0);
auto tmp = offset_cast (stype, cross_expr (vtype, b, a), 2);
tmp = new_extend_expr (tmp, geom_type, 0, true);
c[2] = sum_expr (geom_type, '+', tmp, scale_expr (geom_type, vb, sa));
auto vb = offset_cast (wtype, b, 0);
auto cv = new_swizzle_expr (vb, "y-x");
auto cs = wedge_expr (stype, vb, va);
cs = new_extend_expr (cs, geom_type, 0, true);
c[2] = sum_expr (geom_type, '+', cs,
new_extend_expr (scale_expr (wtype, cv, sa), vtype,
0, false));
c[3] = dot_expr (algebra_mvec_type (alg, 0x08), a, b);
}
@ -1322,13 +1344,18 @@ static void
pga2_x_y_w_geom_yw_wx_xy (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
{
auto stype = alg->type;
auto wtype = vector_type (stype, 2);
auto vtype = vector_type (stype, 3);
auto geom_type = algebra_mvec_type (alg, 0x04);
auto va = offset_cast (vtype, new_swizzle_expr (a, "-yx0"), 0);
auto va = offset_cast (wtype, a, 0);
auto vb = offset_cast (wtype, b, 0);
auto sb = offset_cast (stype, b, 2);
auto tmp = offset_cast (stype, cross_expr (vtype, b, a), 2);
tmp = new_extend_expr (tmp, geom_type, 0, true);
c[2] = sum_expr (geom_type, '+', tmp, scale_expr (geom_type, va, sb));
auto cv = new_swizzle_expr (va, "-yx");
auto cs = wedge_expr (stype, vb, va);
cs = new_extend_expr (cs, geom_type, 0, true);
c[2] = sum_expr (geom_type, '+', cs,
new_extend_expr (scale_expr (wtype, cv, sb), vtype,
0, false));
c[3] = dot_expr (algebra_mvec_type (alg, 0x08), a, b);
}

View file

@ -527,7 +527,7 @@ opcode_print_statement (pr_uint_t addr, dstatement_t *st)
} else {
mnemonic = pr_opcodes[st_op].mnemonic;
}
printf ("%04x (%03x)%-8s %d:%04x %d:%04x %d:%04x\n",
printf ("%04x (%03x)%-8s %d:%04hx %d:%04hx %d:%04hx\n",
addr, st_op & 0x1ff, mnemonic,
(st->op & OP_A_BASE) >> OP_A_SHIFT, st->a,
(st->op & OP_B_BASE) >> OP_B_SHIFT, st->b,

View file

@ -538,6 +538,7 @@ convert_op (int op)
case SHR: return "shr";
case '.': return "load";
case CROSS: return "cross";
case WEDGE: return "wedge";
case DOT: return "dot";
case HADAMARD: return "mul";
case SCALE: return "scale";

View file

@ -707,6 +707,22 @@ int_type (const type_t *base)
return vector_type (base, width);
}
type_t *
uint_type (const type_t *base)
{
int width = type_width (base);
base = base_type (base);
if (!base) {
return 0;
}
if (type_size (base) == 1) {
base = &type_uint;
} else if (type_size (base) == 2) {
base = &type_ulong;
}
return vector_type (base, width);
}
type_t *
float_type (const type_t *base)
{