mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-05-10 17:50:54 +00:00
[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:
parent
e61be2f80f
commit
d11f7be6bf
8 changed files with 75 additions and 102 deletions
|
@ -182,6 +182,7 @@ type_t *base_type (const type_t *vec_type) __attribute__((pure));
|
||||||
null if no such match can be made.
|
null if no such match can be made.
|
||||||
*/
|
*/
|
||||||
type_t *int_type (const type_t *base) __attribute__((pure));
|
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.
|
/** Return a floating point type of same size as the provided type.
|
||||||
|
|
||||||
|
|
|
@ -92,9 +92,12 @@ get_op_string (int op)
|
||||||
case SHR: return ">>";
|
case SHR: return ">>";
|
||||||
case '.': return ".";
|
case '.': return ".";
|
||||||
case 'C': return "<cast>";
|
case 'C': return "<cast>";
|
||||||
|
case HADAMARD: return "@hadamard";
|
||||||
case CROSS: return "@cross";
|
case CROSS: return "@cross";
|
||||||
case DOT: return "@dot";
|
case DOT: return "@dot";
|
||||||
case HADAMARD: return "@hadamard";
|
case WEDGE: return "@wedge";
|
||||||
|
case REGRESSIVE:return "@regressive";
|
||||||
|
case GEOMETRIC:return "@geometric";
|
||||||
case SCALE: return "@scale";
|
case SCALE: return "@scale";
|
||||||
default:
|
default:
|
||||||
return "unknown";
|
return "unknown";
|
||||||
|
|
|
@ -179,74 +179,6 @@ use_tempop (operand_t *op, expr_t *expr)
|
||||||
bug (expr, "temp users went negative: %s", operand_string (op));
|
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
|
static void
|
||||||
emit_statement (statement_t *statement)
|
emit_statement (statement_t *statement)
|
||||||
{
|
{
|
||||||
|
@ -279,17 +211,11 @@ emit_statement (statement_t *statement)
|
||||||
use_tempop (op_c, statement->expr);
|
use_tempop (op_c, statement->expr);
|
||||||
|
|
||||||
if (strcmp (opcode, "swizzle") == 0) {
|
if (strcmp (opcode, "swizzle") == 0) {
|
||||||
op_c->type = float_type (op_c->type);
|
op_c = alias_operand (uint_type (op_c->type), op_c, statement->expr);
|
||||||
op_a->type = float_type (op_a->type);
|
op_a = alias_operand (uint_type (op_a->type), op_a, statement->expr);
|
||||||
if (!op_c->type || !op_a->type) {
|
if (!op_c->type || !op_a->type) {
|
||||||
internal_error (statement->expr, "invalid types in swizzle");
|
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);
|
inst = opcode_find (opcode, op_a, op_b, op_c);
|
||||||
|
|
|
@ -648,7 +648,6 @@ new_swizzle_expr (expr_t *src, const char *swizzle)
|
||||||
return src;
|
return src;
|
||||||
}
|
}
|
||||||
int src_width = type_width (src_type);
|
int src_width = type_width (src_type);
|
||||||
// swizzle always generates a *vec4
|
|
||||||
ex_swizzle_t swiz = {};
|
ex_swizzle_t swiz = {};
|
||||||
|
|
||||||
#define m(x) (1 << ((x) - 'a'))
|
#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.zero |= (0xf << comp_count) & 0xf;
|
||||||
swiz.src = new_alias_expr (vector_type (base_type (src_type), src_width), src);
|
swiz.src = src;
|
||||||
swiz.type = vector_type (base_type (src_type), 4);
|
swiz.type = src_type;
|
||||||
|
|
||||||
expr_t *expr = new_expr ();
|
expr_t *expr = new_expr ();
|
||||||
expr->type = ex_swizzle;
|
expr->type = ex_swizzle;
|
||||||
|
|
|
@ -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))) {
|
if (!is_scalar (get_type (b)) || !is_real (get_type (b))) {
|
||||||
internal_error (b, "not a real scalar type");
|
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");
|
internal_error (b, "not a real scalar type");
|
||||||
}
|
}
|
||||||
int op = is_scalar (get_type (a)) ? '*' : SCALE;
|
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;
|
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);
|
typedef void (*pga_func) (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg);
|
||||||
static void
|
static void
|
||||||
scale_component (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
|
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 stype = alg->type;
|
||||||
auto dot_type = algebra_mvec_type (alg, 0x20);
|
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);
|
auto sa = offset_cast (stype, a, 0);
|
||||||
c[5] = scale_expr (dot_type, vb, sa);
|
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)
|
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 stype = alg->type;
|
||||||
|
auto wtype = vector_type (stype, 2);
|
||||||
auto vtype = vector_type (stype, 3);
|
auto vtype = vector_type (stype, 3);
|
||||||
auto dot_type = algebra_mvec_type (alg, 0x04);
|
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 sa = offset_cast (stype, a, 2);
|
||||||
auto tmp = offset_cast (stype, cross_expr (vtype, b, a), 2);
|
auto vb = offset_cast (wtype, b, 0);
|
||||||
tmp = new_extend_expr (tmp, dot_type, 0, true);
|
auto cv = new_swizzle_expr (vb, "y-x");
|
||||||
c[2] = sum_expr (dot_type, '+', scale_expr (dot_type, vb, sa), tmp);
|
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
|
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)
|
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 stype = alg->type;
|
||||||
auto vtype = vector_type (stype, 3);
|
auto wtype = vector_type (stype, 2);
|
||||||
auto dot_type = algebra_mvec_type (alg, 0x04);
|
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 sb = offset_cast (stype, b, 2);
|
||||||
auto tmp = offset_cast (stype, cross_expr (vtype, b, a), 2);
|
auto cv = new_swizzle_expr (a, "-yx");
|
||||||
tmp = new_extend_expr (tmp, dot_type, 0, true);
|
auto cs = wedge_expr (stype, vb, va);
|
||||||
c[2] = sum_expr (dot_type, '+', tmp, scale_expr (dot_type, va, sb));
|
cs = new_extend_expr (cs, dot_type, 0, true);
|
||||||
|
c[2] = sum_expr (dot_type, '+', cs, scale_expr (dot_type, cv, sb));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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)
|
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 stype = alg->type;
|
||||||
|
auto vtype = vector_type (stype, 3);
|
||||||
|
auto ctype = vector_type (stype, 2);
|
||||||
auto geom_type = algebra_mvec_type (alg, 0x01);
|
auto geom_type = algebra_mvec_type (alg, 0x01);
|
||||||
auto sa = offset_cast (stype, a, 2);
|
auto sa = offset_cast (stype, a, 2);
|
||||||
auto sb = offset_cast (stype, b, 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));
|
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)
|
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 stype = alg->type;
|
||||||
|
auto wtype = vector_type (stype, 2);
|
||||||
auto vtype = vector_type (stype, 3);
|
auto vtype = vector_type (stype, 3);
|
||||||
auto geom_type = algebra_mvec_type (alg, 0x04);
|
auto geom_type = algebra_mvec_type (alg, 0x04);
|
||||||
|
auto va = offset_cast (wtype, a, 0);
|
||||||
auto sa = offset_cast (stype, a, 2);
|
auto sa = offset_cast (stype, a, 2);
|
||||||
auto vb = offset_cast (vtype, new_swizzle_expr (b, "y-x0"), 0);
|
auto vb = offset_cast (wtype, b, 0);
|
||||||
auto tmp = offset_cast (stype, cross_expr (vtype, b, a), 2);
|
auto cv = new_swizzle_expr (vb, "y-x");
|
||||||
tmp = new_extend_expr (tmp, geom_type, 0, true);
|
auto cs = wedge_expr (stype, vb, va);
|
||||||
c[2] = sum_expr (geom_type, '+', tmp, scale_expr (geom_type, vb, sa));
|
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);
|
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)
|
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 stype = alg->type;
|
||||||
|
auto wtype = vector_type (stype, 2);
|
||||||
auto vtype = vector_type (stype, 3);
|
auto vtype = vector_type (stype, 3);
|
||||||
auto geom_type = algebra_mvec_type (alg, 0x04);
|
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 sb = offset_cast (stype, b, 2);
|
||||||
auto tmp = offset_cast (stype, cross_expr (vtype, b, a), 2);
|
auto cv = new_swizzle_expr (va, "-yx");
|
||||||
tmp = new_extend_expr (tmp, geom_type, 0, true);
|
auto cs = wedge_expr (stype, vb, va);
|
||||||
c[2] = sum_expr (geom_type, '+', tmp, scale_expr (geom_type, va, sb));
|
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);
|
c[3] = dot_expr (algebra_mvec_type (alg, 0x08), a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -527,7 +527,7 @@ opcode_print_statement (pr_uint_t addr, dstatement_t *st)
|
||||||
} else {
|
} else {
|
||||||
mnemonic = pr_opcodes[st_op].mnemonic;
|
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,
|
addr, st_op & 0x1ff, mnemonic,
|
||||||
(st->op & OP_A_BASE) >> OP_A_SHIFT, st->a,
|
(st->op & OP_A_BASE) >> OP_A_SHIFT, st->a,
|
||||||
(st->op & OP_B_BASE) >> OP_B_SHIFT, st->b,
|
(st->op & OP_B_BASE) >> OP_B_SHIFT, st->b,
|
||||||
|
|
|
@ -538,6 +538,7 @@ convert_op (int op)
|
||||||
case SHR: return "shr";
|
case SHR: return "shr";
|
||||||
case '.': return "load";
|
case '.': return "load";
|
||||||
case CROSS: return "cross";
|
case CROSS: return "cross";
|
||||||
|
case WEDGE: return "wedge";
|
||||||
case DOT: return "dot";
|
case DOT: return "dot";
|
||||||
case HADAMARD: return "mul";
|
case HADAMARD: return "mul";
|
||||||
case SCALE: return "scale";
|
case SCALE: return "scale";
|
||||||
|
|
|
@ -707,6 +707,22 @@ int_type (const type_t *base)
|
||||||
return vector_type (base, width);
|
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 *
|
type_t *
|
||||||
float_type (const type_t *base)
|
float_type (const type_t *base)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue