mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-22 04:21:51 +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.
|
||||
*/
|
||||
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.
|
||||
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue