mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-25 05:01:24 +00:00
[qfcc] Split test_expr per target
While there's a bit of code duplication, it very much cleans things up for the various targets, especially v6 progs. However, spirv is not implemented yet, so that's broken again.
This commit is contained in:
parent
0143a2410c
commit
c88820c31e
10 changed files with 282 additions and 106 deletions
|
@ -52,6 +52,7 @@ typedef struct {
|
||||||
// for both vector and quaternion types
|
// for both vector and quaternion types
|
||||||
const expr_t *(*vector_compare)(int op, const expr_t *e1, const expr_t *e2);
|
const expr_t *(*vector_compare)(int op, const expr_t *e1, const expr_t *e2);
|
||||||
const expr_t *(*shift_op)(int op, const expr_t *e1, const expr_t *e2);
|
const expr_t *(*shift_op)(int op, const expr_t *e1, const expr_t *e2);
|
||||||
|
const expr_t *(*test_expr) (const expr_t *expr);
|
||||||
|
|
||||||
bool (*setup_intrinsic_symtab) (symtab_t *symtab);
|
bool (*setup_intrinsic_symtab) (symtab_t *symtab);
|
||||||
|
|
||||||
|
|
|
@ -111,9 +111,7 @@ get_type (const expr_t *e)
|
||||||
type = e->compound.type;
|
type = e->compound.type;
|
||||||
break;
|
break;
|
||||||
case ex_bool:
|
case ex_bool:
|
||||||
if (options.code.progsversion == PROG_ID_VERSION)
|
return &type_bool;
|
||||||
return &type_float;
|
|
||||||
return &type_int;
|
|
||||||
case ex_nil:
|
case ex_nil:
|
||||||
if (e->nil) {
|
if (e->nil) {
|
||||||
type = e->nil;
|
type = e->nil;
|
||||||
|
|
|
@ -186,9 +186,11 @@ promote_exprs (const expr_t **e1, const expr_t **e2)
|
||||||
//FIXME proper backing type for enum like handle
|
//FIXME proper backing type for enum like handle
|
||||||
t1 = type_default;
|
t1 = type_default;
|
||||||
t2 = type_default;
|
t2 = type_default;
|
||||||
} else if ((is_vector (t1) || is_quaternion (t1)) && is_float (t2)) {
|
} else if ((is_vector (t1) || is_quaternion (t1))
|
||||||
|
&& (is_float (t2) || is_bool (t2))) {
|
||||||
t2 = promote_type (t1, t2);
|
t2 = promote_type (t1, t2);
|
||||||
} else if ((is_vector (t2) || is_quaternion (t2)) && is_float (t1)) {
|
} else if ((is_vector (t2) || is_quaternion (t2))
|
||||||
|
&& (is_float (t1) || is_bool (t2))) {
|
||||||
t1 = promote_type (t2, t1);
|
t1 = promote_type (t2, t1);
|
||||||
} else if (type_promotes (t1, t2)) {
|
} else if (type_promotes (t1, t2)) {
|
||||||
t2 = promote_type (t1, t2);
|
t2 = promote_type (t1, t2);
|
||||||
|
@ -952,7 +954,7 @@ binary_expr (int op, const expr_t *e1, const expr_t *e2)
|
||||||
|
|
||||||
if (expr_type->process) {
|
if (expr_type->process) {
|
||||||
auto e = expr_type->process (op, e1, e2);
|
auto e = expr_type->process (op, e1, e2);
|
||||||
return edag_add_expr (e);
|
return edag_add_expr (fold_constants (e));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto type = t1;
|
auto type = t1;
|
||||||
|
@ -981,10 +983,5 @@ binary_expr (int op, const expr_t *e1, const expr_t *e2)
|
||||||
if (expr_type->associative) {
|
if (expr_type->associative) {
|
||||||
ne->expr.associative = expr_type->associative ();
|
ne->expr.associative = expr_type->associative ();
|
||||||
}
|
}
|
||||||
if (is_compare (op) || is_logic (op)) {
|
|
||||||
if (options.code.progsversion == PROG_ID_VERSION) {
|
|
||||||
ne->expr.type = &type_float;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return edag_add_expr (fold_constants (ne));
|
return edag_add_expr (fold_constants (ne));
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,100 +62,36 @@
|
||||||
#include "tools/qfcc/include/strpool.h"
|
#include "tools/qfcc/include/strpool.h"
|
||||||
#include "tools/qfcc/include/struct.h"
|
#include "tools/qfcc/include/struct.h"
|
||||||
#include "tools/qfcc/include/symtab.h"
|
#include "tools/qfcc/include/symtab.h"
|
||||||
|
#include "tools/qfcc/include/target.h"
|
||||||
#include "tools/qfcc/include/type.h"
|
#include "tools/qfcc/include/type.h"
|
||||||
#include "tools/qfcc/include/value.h"
|
#include "tools/qfcc/include/value.h"
|
||||||
|
|
||||||
const expr_t *
|
const expr_t *
|
||||||
test_expr (const expr_t *e)
|
test_expr (const expr_t *e)
|
||||||
{
|
{
|
||||||
const expr_t *new = 0;
|
if (is_error (e)) {
|
||||||
|
|
||||||
if (e->type == ex_error)
|
|
||||||
return e;
|
return e;
|
||||||
|
}
|
||||||
|
if (e->type == ex_bool) {
|
||||||
|
return e;
|
||||||
|
}
|
||||||
auto type = get_type (e);
|
auto type = get_type (e);
|
||||||
if (e->type == ex_error)
|
if (!type) {
|
||||||
return e;
|
// an error occured while getting the type and was already reported
|
||||||
scoped_src_loc (e);
|
return new_error_expr ();
|
||||||
switch (type->type) {
|
}
|
||||||
case ev_type_count:
|
if (is_void (type)) {
|
||||||
internal_error (e, 0);
|
if (options.traditional) {
|
||||||
case ev_void:
|
if (options.warnings.traditional) {
|
||||||
if (options.traditional) {
|
warning (e, "void has no value");
|
||||||
if (options.warnings.traditional)
|
|
||||||
warning (e, "void has no value");
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
return error (e, "void has no value");
|
|
||||||
case ev_string:
|
|
||||||
if (!options.code.ifstring)
|
|
||||||
return new_alias_expr (type_default, e);
|
|
||||||
new = new_string_expr (0);
|
|
||||||
break;
|
|
||||||
case ev_long:
|
|
||||||
case ev_ulong:
|
|
||||||
if (type->width > 1) {
|
|
||||||
e = new_horizontal_expr ('|', e, &type_long);
|
|
||||||
}
|
|
||||||
e = new_alias_expr (&type_ivec2, e);
|
|
||||||
return new_horizontal_expr ('|', e, &type_int);
|
|
||||||
case ev_ushort:
|
|
||||||
internal_error (e, "ushort not implemented");
|
|
||||||
case ev_uint:
|
|
||||||
case ev_int:
|
|
||||||
case ev_short:
|
|
||||||
if (type->width > 1) {
|
|
||||||
e = new_horizontal_expr ('|', e, &type_int);
|
|
||||||
}
|
|
||||||
if (!is_int(type_default)) {
|
|
||||||
if (is_constant (e)) {
|
|
||||||
return cast_expr (type_default, e);
|
|
||||||
}
|
|
||||||
return new_alias_expr (type_default, e);
|
|
||||||
}
|
}
|
||||||
return e;
|
return e;
|
||||||
case ev_float:
|
}
|
||||||
if (options.code.progsversion < PROG_VERSION
|
return error (e, "void has no value");
|
||||||
&& (options.code.fast_float
|
|
||||||
|| options.code.progsversion == PROG_ID_VERSION)) {
|
|
||||||
if (!is_float(type_default)) {
|
|
||||||
if (is_constant (e)) {
|
|
||||||
return cast_expr (type_default, e);
|
|
||||||
}
|
|
||||||
return new_alias_expr (type_default, e);
|
|
||||||
}
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
new = new_zero_expr (type);
|
|
||||||
new = binary_expr (QC_NE, e, new);
|
|
||||||
return test_expr (new);
|
|
||||||
case ev_double:
|
|
||||||
new = new_zero_expr (type);
|
|
||||||
new = binary_expr (QC_NE, e, new);
|
|
||||||
return test_expr (new);
|
|
||||||
case ev_vector:
|
|
||||||
new = new_zero_expr (&type_vector);
|
|
||||||
break;
|
|
||||||
case ev_entity:
|
|
||||||
return new_alias_expr (type_default, e);
|
|
||||||
case ev_field:
|
|
||||||
return new_alias_expr (type_default, e);
|
|
||||||
case ev_func:
|
|
||||||
return new_alias_expr (type_default, e);
|
|
||||||
case ev_ptr:
|
|
||||||
return new_alias_expr (type_default, e);
|
|
||||||
case ev_quaternion:
|
|
||||||
new = new_zero_expr (&type_quaternion);
|
|
||||||
break;
|
|
||||||
case ev_invalid:
|
|
||||||
if (is_enum (type)) {
|
|
||||||
new = new_nil_expr ();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return test_error (e, get_type (e));
|
|
||||||
}
|
}
|
||||||
new = binary_expr (QC_NE, e, new);
|
e = current_target.test_expr (e);
|
||||||
return new;
|
fold_constants (e);
|
||||||
|
return edag_add_expr (e);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -124,15 +124,8 @@ cast_expr (const type_t *dstType, const expr_t *e)
|
||||||
return conditional_expr (e, enum_one, enum_zero);
|
return conditional_expr (e, enum_one, enum_zero);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (is_integral (dstType) && is_boolean (srcType)) {
|
if (is_boolean (srcType) && srcType->type == dstType->type) {
|
||||||
auto type = dstType;
|
e = new_alias_expr (dstType, e);
|
||||||
if (type_size (dstType) != type_size (srcType)) {
|
|
||||||
type = ev_types[srcType->type];
|
|
||||||
}
|
|
||||||
e = new_alias_expr (type, e);
|
|
||||||
if (type != dstType) {
|
|
||||||
e = cast_expr (dstType, e);
|
|
||||||
}
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
if (is_algebra (dstType) || is_algebra (srcType)) {
|
if (is_algebra (dstType) || is_algebra (srcType)) {
|
||||||
|
|
|
@ -816,6 +816,7 @@ static const expr_t *
|
||||||
proc_select (const expr_t *expr, rua_ctx_t *ctx)
|
proc_select (const expr_t *expr, rua_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
auto test = expr_process (expr->select.test, ctx);
|
auto test = expr_process (expr->select.test, ctx);
|
||||||
|
test = test_expr (test);
|
||||||
edag_flush ();
|
edag_flush ();
|
||||||
auto true_body = expr_process (expr->select.true_body, ctx);
|
auto true_body = expr_process (expr->select.true_body, ctx);
|
||||||
edag_flush ();
|
edag_flush ();
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include "tools/qfcc/include/qfcc.h"
|
#include "tools/qfcc/include/qfcc.h"
|
||||||
#include "tools/qfcc/include/statements.h"
|
#include "tools/qfcc/include/statements.h"
|
||||||
#include "tools/qfcc/include/strpool.h"
|
#include "tools/qfcc/include/strpool.h"
|
||||||
|
#include "tools/qfcc/include/struct.h"
|
||||||
#include "tools/qfcc/include/switch.h"
|
#include "tools/qfcc/include/switch.h"
|
||||||
#include "tools/qfcc/include/symtab.h"
|
#include "tools/qfcc/include/symtab.h"
|
||||||
#include "tools/qfcc/include/target.h"
|
#include "tools/qfcc/include/target.h"
|
||||||
|
@ -406,6 +407,120 @@ ruamoko_shift_op (int op, const expr_t *e1, const expr_t *e2)
|
||||||
return fold_constants (e);
|
return fold_constants (e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const expr_t *
|
||||||
|
ruamoko_test_expr (const expr_t *expr)
|
||||||
|
{
|
||||||
|
scoped_src_loc (expr);
|
||||||
|
auto type = get_type (expr);
|
||||||
|
if (is_bool (type) && is_scalar (type)) {
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
if (is_lbool (type) && is_scalar (type)) {
|
||||||
|
expr = new_alias_expr (&type_ivec2, expr);
|
||||||
|
expr = fold_constants (expr);
|
||||||
|
expr = edag_add_expr (expr);
|
||||||
|
return new_horizontal_expr ('|', expr, &type_int);
|
||||||
|
}
|
||||||
|
if (is_boolean (type)) {
|
||||||
|
// the above is_bool and is_lbool tests ensure a boolean type
|
||||||
|
// is a vector (there are no bool matrices)
|
||||||
|
type = base_type (type);
|
||||||
|
expr = new_horizontal_expr ('|', expr, type);
|
||||||
|
if (type_size (type) > 1) {
|
||||||
|
expr = fold_constants (expr);
|
||||||
|
expr = edag_add_expr (expr);
|
||||||
|
expr = new_alias_expr (&type_ivec2, expr);
|
||||||
|
expr = fold_constants (expr);
|
||||||
|
expr = edag_add_expr (expr);
|
||||||
|
expr = new_horizontal_expr ('|', expr, &type_bool);
|
||||||
|
}
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
if (is_enum (type)) {
|
||||||
|
expr_t *zero, *one;
|
||||||
|
if (!enum_as_bool (type, &zero, &one)) {
|
||||||
|
warning (expr, "enum doesn't convert to bool");
|
||||||
|
}
|
||||||
|
return new_alias_expr (&type_bool, expr);
|
||||||
|
}
|
||||||
|
switch (type->type) {
|
||||||
|
case ev_float:
|
||||||
|
case ev_double:
|
||||||
|
case ev_short:
|
||||||
|
case ev_ushort:
|
||||||
|
{
|
||||||
|
// short and ushort handled with the same code as float/double
|
||||||
|
// because they have no backing type and and thus constants, which
|
||||||
|
// fold_constants will take care of.
|
||||||
|
auto zero = new_zero_expr (type);
|
||||||
|
auto btype = bool_type (type);
|
||||||
|
expr = typed_binary_expr (btype, QC_NE, expr, zero);
|
||||||
|
if (type_width (btype) > 1) {
|
||||||
|
btype = base_type (btype);
|
||||||
|
expr = fold_constants (expr);
|
||||||
|
expr = edag_add_expr (expr);
|
||||||
|
expr = new_horizontal_expr ('|', expr, btype);
|
||||||
|
}
|
||||||
|
if (type_size (btype) > 1) {
|
||||||
|
expr = fold_constants (expr);
|
||||||
|
expr = edag_add_expr (expr);
|
||||||
|
expr = new_alias_expr (&type_ivec2, expr);
|
||||||
|
expr = fold_constants (expr);
|
||||||
|
expr = edag_add_expr (expr);
|
||||||
|
expr = new_horizontal_expr ('|', expr, &type_bool);
|
||||||
|
}
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
case ev_vector:
|
||||||
|
case ev_quaternion:
|
||||||
|
{
|
||||||
|
auto zero = new_zero_expr (type);
|
||||||
|
auto btype = bool_type (type);
|
||||||
|
expr = typed_binary_expr (btype, QC_NE, expr, zero);
|
||||||
|
expr = fold_constants (expr);
|
||||||
|
expr = edag_add_expr (expr);
|
||||||
|
expr = new_horizontal_expr ('|', expr, &type_bool);
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
case ev_string:
|
||||||
|
if (!options.code.ifstring) {
|
||||||
|
return new_alias_expr (&type_bool, expr);
|
||||||
|
}
|
||||||
|
return typed_binary_expr (&type_bool, QC_NE, expr,
|
||||||
|
new_string_expr (0));
|
||||||
|
case ev_int:
|
||||||
|
case ev_uint:
|
||||||
|
if (type_width (type) > 1) {
|
||||||
|
expr = new_horizontal_expr ('|', expr, &type_int);
|
||||||
|
expr = fold_constants (expr);
|
||||||
|
expr = edag_add_expr (expr);
|
||||||
|
}
|
||||||
|
if (is_constant (expr)) {
|
||||||
|
return new_bool_expr (expr_int (expr));
|
||||||
|
}
|
||||||
|
return new_alias_expr (&type_bool, expr);
|
||||||
|
case ev_long:
|
||||||
|
case ev_ulong:
|
||||||
|
if (type_width (type) > 1) {
|
||||||
|
expr = new_horizontal_expr ('|', expr, &type_long);
|
||||||
|
expr = fold_constants (expr);
|
||||||
|
expr = edag_add_expr (expr);
|
||||||
|
}
|
||||||
|
expr = new_alias_expr (&type_ivec2, expr);
|
||||||
|
return new_horizontal_expr ('|', expr, &type_int);
|
||||||
|
case ev_entity:
|
||||||
|
case ev_field:
|
||||||
|
case ev_func:
|
||||||
|
case ev_ptr:
|
||||||
|
return new_alias_expr (&type_bool, expr);
|
||||||
|
case ev_void:
|
||||||
|
case ev_invalid:
|
||||||
|
case ev_type_count:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return error (expr, "cannot convert to bool");
|
||||||
|
}
|
||||||
|
|
||||||
target_t ruamoko_target = {
|
target_t ruamoko_target = {
|
||||||
.value_too_large = ruamoko_value_too_large,
|
.value_too_large = ruamoko_value_too_large,
|
||||||
.build_scope = ruamoko_build_scope,
|
.build_scope = ruamoko_build_scope,
|
||||||
|
@ -418,4 +533,5 @@ target_t ruamoko_target = {
|
||||||
.proc_address = ruamoko_proc_address,
|
.proc_address = ruamoko_proc_address,
|
||||||
.vector_compare = ruamoko_vector_compare,
|
.vector_compare = ruamoko_vector_compare,
|
||||||
.shift_op = ruamoko_shift_op,
|
.shift_op = ruamoko_shift_op,
|
||||||
|
.test_expr = ruamoko_test_expr,
|
||||||
};
|
};
|
||||||
|
|
|
@ -2241,6 +2241,12 @@ spirv_shift_op (int op, const expr_t *e1, const expr_t *e2)
|
||||||
return fold_constants (e);
|
return fold_constants (e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const expr_t *
|
||||||
|
spirv_test_expr (const expr_t *expr)
|
||||||
|
{
|
||||||
|
return error (expr, "not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
target_t spirv_target = {
|
target_t spirv_target = {
|
||||||
.value_too_large = spirv_value_too_large,
|
.value_too_large = spirv_value_too_large,
|
||||||
.build_scope = spirv_build_scope,
|
.build_scope = spirv_build_scope,
|
||||||
|
@ -2251,4 +2257,5 @@ target_t spirv_target = {
|
||||||
.setup_intrinsic_symtab = spirv_setup_intrinsic_symtab,
|
.setup_intrinsic_symtab = spirv_setup_intrinsic_symtab,
|
||||||
.vector_compare = spirv_vector_compare,
|
.vector_compare = spirv_vector_compare,
|
||||||
.shift_op = spirv_shift_op,
|
.shift_op = spirv_shift_op,
|
||||||
|
.test_expr = spirv_test_expr,
|
||||||
};
|
};
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include "tools/qfcc/include/qfcc.h"
|
#include "tools/qfcc/include/qfcc.h"
|
||||||
#include "tools/qfcc/include/statements.h"
|
#include "tools/qfcc/include/statements.h"
|
||||||
#include "tools/qfcc/include/strpool.h"
|
#include "tools/qfcc/include/strpool.h"
|
||||||
|
#include "tools/qfcc/include/struct.h"
|
||||||
#include "tools/qfcc/include/symtab.h"
|
#include "tools/qfcc/include/symtab.h"
|
||||||
#include "tools/qfcc/include/target.h"
|
#include "tools/qfcc/include/target.h"
|
||||||
#include "tools/qfcc/include/type.h"
|
#include "tools/qfcc/include/type.h"
|
||||||
|
@ -254,6 +255,125 @@ v6p_shift_op (int op, const expr_t *e1, const expr_t *e2)
|
||||||
return fold_constants (e);
|
return fold_constants (e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const expr_t *
|
||||||
|
v6_test_expr (const expr_t *expr)
|
||||||
|
{
|
||||||
|
scoped_src_loc (expr);
|
||||||
|
auto type = get_type (expr);
|
||||||
|
if (is_bool (type)) {
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
if (is_enum (type)) {
|
||||||
|
expr_t *zero, *one;
|
||||||
|
if (!enum_as_bool (type, &zero, &one)) {
|
||||||
|
warning (expr, "enum doesn't convert to bool");
|
||||||
|
}
|
||||||
|
return new_alias_expr (&type_bool, expr);
|
||||||
|
}
|
||||||
|
switch (type->type) {
|
||||||
|
case ev_float:
|
||||||
|
{
|
||||||
|
// short and ushort handled with the same code as float/double
|
||||||
|
// because they have no backing type and and thus constants, which
|
||||||
|
// fold_constants will take care of.
|
||||||
|
auto zero = new_zero_expr (type);
|
||||||
|
auto btype = bool_type (type);
|
||||||
|
expr = typed_binary_expr (btype, QC_NE, expr, zero);
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
case ev_vector:
|
||||||
|
case ev_quaternion:
|
||||||
|
{
|
||||||
|
auto zero = new_zero_expr (type);
|
||||||
|
return typed_binary_expr (&type_bool, QC_NE, expr, zero);
|
||||||
|
}
|
||||||
|
case ev_string:
|
||||||
|
if (!options.code.ifstring) {
|
||||||
|
return new_alias_expr (&type_bool, expr);
|
||||||
|
}
|
||||||
|
return typed_binary_expr (&type_bool, QC_NE, expr,
|
||||||
|
new_string_expr (0));
|
||||||
|
case ev_entity:
|
||||||
|
case ev_field:
|
||||||
|
case ev_func:
|
||||||
|
case ev_ptr:
|
||||||
|
return new_alias_expr (&type_bool, expr);
|
||||||
|
case ev_int:
|
||||||
|
case ev_uint:
|
||||||
|
case ev_long:
|
||||||
|
case ev_ulong:
|
||||||
|
case ev_double:
|
||||||
|
case ev_short:
|
||||||
|
case ev_ushort:
|
||||||
|
case ev_void:
|
||||||
|
case ev_invalid:
|
||||||
|
case ev_type_count:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return error (expr, "cannot convert to bool");
|
||||||
|
}
|
||||||
|
|
||||||
|
static const expr_t *
|
||||||
|
v6p_test_expr (const expr_t *expr)
|
||||||
|
{
|
||||||
|
scoped_src_loc (expr);
|
||||||
|
auto type = get_type (expr);
|
||||||
|
if (is_bool (type)) {
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
if (is_enum (type)) {
|
||||||
|
expr_t *zero, *one;
|
||||||
|
if (!enum_as_bool (type, &zero, &one)) {
|
||||||
|
warning (expr, "enum doesn't convert to bool");
|
||||||
|
}
|
||||||
|
return new_alias_expr (&type_bool, expr);
|
||||||
|
}
|
||||||
|
switch (type->type) {
|
||||||
|
case ev_float:
|
||||||
|
case ev_double:
|
||||||
|
case ev_short:
|
||||||
|
case ev_ushort:
|
||||||
|
{
|
||||||
|
// short and ushort handled with the same code as float/double
|
||||||
|
// because they have no backing type and and thus constants, which
|
||||||
|
// fold_constants will take care of.
|
||||||
|
auto zero = new_zero_expr (type);
|
||||||
|
expr = typed_binary_expr (&type_bool, QC_NE, expr, zero);
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
case ev_vector:
|
||||||
|
case ev_quaternion:
|
||||||
|
{
|
||||||
|
auto zero = new_zero_expr (type);
|
||||||
|
return typed_binary_expr (&type_bool, QC_NE, expr, zero);
|
||||||
|
}
|
||||||
|
case ev_string:
|
||||||
|
if (!options.code.ifstring) {
|
||||||
|
return new_alias_expr (&type_bool, expr);
|
||||||
|
}
|
||||||
|
return typed_binary_expr (&type_bool, QC_NE, expr,
|
||||||
|
new_string_expr (0));
|
||||||
|
case ev_int:
|
||||||
|
case ev_uint:
|
||||||
|
if (is_constant (expr)) {
|
||||||
|
return new_bool_expr (expr_int (expr));
|
||||||
|
}
|
||||||
|
return new_alias_expr (&type_bool, expr);
|
||||||
|
case ev_entity:
|
||||||
|
case ev_field:
|
||||||
|
case ev_func:
|
||||||
|
case ev_ptr:
|
||||||
|
return new_alias_expr (&type_bool, expr);
|
||||||
|
case ev_long:
|
||||||
|
case ev_ulong:
|
||||||
|
case ev_void:
|
||||||
|
case ev_invalid:
|
||||||
|
case ev_type_count:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return error (expr, "cannot convert to bool");
|
||||||
|
}
|
||||||
|
|
||||||
target_t v6_target = {
|
target_t v6_target = {
|
||||||
.value_too_large = v6_value_too_large,
|
.value_too_large = v6_value_too_large,
|
||||||
.build_scope = v6p_build_scope,
|
.build_scope = v6p_build_scope,
|
||||||
|
@ -267,6 +387,7 @@ target_t v6_target = {
|
||||||
.proc_address = ruamoko_proc_address,
|
.proc_address = ruamoko_proc_address,
|
||||||
.vector_compare = v6_vector_compare,
|
.vector_compare = v6_vector_compare,
|
||||||
.shift_op = v6_shift_op,
|
.shift_op = v6_shift_op,
|
||||||
|
.test_expr = v6_test_expr,
|
||||||
};
|
};
|
||||||
|
|
||||||
target_t v6p_target = {
|
target_t v6p_target = {
|
||||||
|
@ -282,4 +403,5 @@ target_t v6p_target = {
|
||||||
.proc_address = ruamoko_proc_address,
|
.proc_address = ruamoko_proc_address,
|
||||||
.vector_compare = v6p_vector_compare,
|
.vector_compare = v6p_vector_compare,
|
||||||
.shift_op = v6p_shift_op,
|
.shift_op = v6p_shift_op,
|
||||||
|
.test_expr = v6p_test_expr,
|
||||||
};
|
};
|
||||||
|
|
|
@ -1130,7 +1130,7 @@ print_type_str (dstring_t *str, const type_t *type)
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case ty_bool:
|
case ty_bool:
|
||||||
dasprintf (str, " %s%s", type->type == ev_int ? "bool" : "lbool",
|
dasprintf (str, " %s%s", is_bool (type) ? "bool" : "lbool",
|
||||||
type->width > 1 ? va (0, "{%d}", type->width)
|
type->width > 1 ? va (0, "{%d}", type->width)
|
||||||
: "");
|
: "");
|
||||||
return;
|
return;
|
||||||
|
@ -1505,7 +1505,7 @@ is_bool (const type_t *type)
|
||||||
if (type->meta != ty_bool) {
|
if (type->meta != ty_bool) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return type->type == ev_int;
|
return type->type == ev_int || type->type == ev_float;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -2059,6 +2059,11 @@ chain_basic_types (void)
|
||||||
if (options.code.progsversion == PROG_VERSION) {
|
if (options.code.progsversion == PROG_VERSION) {
|
||||||
type_quaternion.alignment = 4;
|
type_quaternion.alignment = 4;
|
||||||
}
|
}
|
||||||
|
if (options.code.progsversion == PROG_ID_VERSION) {
|
||||||
|
type_bool.type = ev_float;
|
||||||
|
} else {
|
||||||
|
type_bool.type = ev_int;
|
||||||
|
}
|
||||||
|
|
||||||
chain_type (&type_void);
|
chain_type (&type_void);
|
||||||
chain_type (&type_string);
|
chain_type (&type_string);
|
||||||
|
@ -2069,6 +2074,7 @@ chain_basic_types (void)
|
||||||
chain_type (&type_func);
|
chain_type (&type_func);
|
||||||
chain_type (&type_ptr);
|
chain_type (&type_ptr);
|
||||||
chain_type (&type_floatfield);
|
chain_type (&type_floatfield);
|
||||||
|
chain_type (&type_bool);
|
||||||
if (!options.traditional) {
|
if (!options.traditional) {
|
||||||
chain_type (&type_quaternion);
|
chain_type (&type_quaternion);
|
||||||
chain_type (&type_int);
|
chain_type (&type_int);
|
||||||
|
@ -2084,7 +2090,6 @@ chain_basic_types (void)
|
||||||
#include "tools/qfcc/include/vec_types.h"
|
#include "tools/qfcc/include/vec_types.h"
|
||||||
#define MAT_TYPE(name, type, cols, align_as) chain_type (&type_##name);
|
#define MAT_TYPE(name, type, cols, align_as) chain_type (&type_##name);
|
||||||
#include "tools/qfcc/include/mat_types.h"
|
#include "tools/qfcc/include/mat_types.h"
|
||||||
chain_type (&type_bool);
|
|
||||||
chain_type (&type_bvec2);
|
chain_type (&type_bvec2);
|
||||||
chain_type (&type_bvec3);
|
chain_type (&type_bvec3);
|
||||||
chain_type (&type_bvec4);
|
chain_type (&type_bvec4);
|
||||||
|
|
Loading…
Reference in a new issue