diff --git a/libs/gamecode/engine/pr_exec.c b/libs/gamecode/engine/pr_exec.c index 77820ca28..5f269dfd6 100644 --- a/libs/gamecode/engine/pr_exec.c +++ b/libs/gamecode/engine/pr_exec.c @@ -327,9 +327,11 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum) OPC.integer_var = OPA.integer_var << OPB.integer_var; break; case OP_SHR_I: - case OP_SHR_U: OPC.integer_var = OPA.integer_var >> OPB.integer_var; break; + case OP_SHR_U: + OPC.uinteger_var = OPA.uinteger_var >> OPB.uinteger_var; + break; case OP_GE_F: OPC.float_var = OPA.float_var >= OPB.float_var; break; diff --git a/libs/gamecode/engine/pr_opcode.c b/libs/gamecode/engine/pr_opcode.c index a16ca6587..0e25fe977 100644 --- a/libs/gamecode/engine/pr_opcode.c +++ b/libs/gamecode/engine/pr_opcode.c @@ -694,11 +694,11 @@ opcode_t pr_opcodes[] = { "%Ga, %Gb", }, - {"&&", "and", OP_AND, false, + {"&&", "and.f", OP_AND, false, ev_float, ev_float, ev_integer, PROG_ID_VERSION, }, - {"||", "or", OP_OR, false, + {"||", "or.f", OP_OR, false, ev_float, ev_float, ev_integer, PROG_ID_VERSION, }, @@ -766,6 +766,35 @@ opcode_t pr_opcodes[] = { PROG_VERSION, }, + {"+", "add.u", OP_ADD_U, false, + ev_uinteger, ev_uinteger, ev_uinteger, + PROG_VERSION, + }, + {"-", "sub.u", OP_SUB_U, false, + ev_uinteger, ev_uinteger, ev_uinteger, + PROG_VERSION, + }, + {"*", "mul.u", OP_MUL_U, false, + ev_uinteger, ev_uinteger, ev_uinteger, + PROG_VERSION, + }, + {"/", "div.u", OP_DIV_U, false, + ev_uinteger, ev_uinteger, ev_uinteger, + PROG_VERSION, + }, + {"%", "mod_u", OP_MOD_U, false, + ev_uinteger, ev_uinteger, ev_uinteger, + PROG_VERSION, + }, + {"&", "bitand.u", OP_BITAND_U, false, + ev_uinteger, ev_uinteger, ev_uinteger, + PROG_VERSION, + }, + {"|", "bitor.u", OP_BITOR_U, false, + ev_uinteger, ev_uinteger, ev_uinteger, + PROG_VERSION, + }, + {"%", "mod.f", OP_MOD_F, false, ev_float, ev_float, ev_float, PROG_VERSION, @@ -809,6 +838,27 @@ opcode_t pr_opcodes[] = { PROG_VERSION, }, + {"&&", "and.u", OP_AND_U, false, + ev_uinteger, ev_uinteger, ev_integer, + PROG_VERSION, + }, + {"||", "or.u", OP_OR_U, false, + ev_uinteger, ev_uinteger, ev_integer, + PROG_VERSION, + }, + {"!", "not.u", OP_NOT_U, false, + ev_uinteger, ev_void, ev_integer, + PROG_VERSION, + }, + {"==", "eq.u", OP_EQ_U, false, + ev_uinteger, ev_uinteger, ev_integer, + PROG_VERSION, + }, + {"!=", "ne.u", OP_NE_U, false, + ev_uinteger, ev_uinteger, ev_integer, + PROG_VERSION, + }, + {">=", "ge.u", OP_GE_U, false, ev_uinteger, ev_uinteger, ev_integer, PROG_VERSION, @@ -842,6 +892,14 @@ opcode_t pr_opcodes[] = { ev_integer, ev_void, ev_integer, PROG_VERSION, }, + {"^", "bitxor.u", OP_BITXOR_U, false, + ev_uinteger, ev_uinteger, ev_uinteger, + PROG_VERSION, + }, + {"~", "bitnot.u", OP_BITNOT_U, false, + ev_uinteger, ev_void, ev_uinteger, + PROG_VERSION, + }, {">=", "ge.p", OP_GE_P, false, ev_pointer, ev_pointer, ev_integer, diff --git a/ruamoko/include/Object.h b/ruamoko/include/Object.h index 5fe9e11ac..4bf2eab6b 100644 --- a/ruamoko/include/Object.h +++ b/ruamoko/include/Object.h @@ -101,7 +101,7 @@ typedef enum { @interface Object { Class isa; - integer retainCount; + unsigned retainCount; } + (id) alloc; diff --git a/ruamoko/lib/AutoreleasePool.r b/ruamoko/lib/AutoreleasePool.r index c5c2e51f4..33cff0bc3 100644 --- a/ruamoko/lib/AutoreleasePool.r +++ b/ruamoko/lib/AutoreleasePool.r @@ -45,11 +45,11 @@ - (void) dealloc { - local integer i; + local unsigned i; local id tmp; for (i = 0; i < count; i++) - [array[i] release]; + [array[(integer)i] release]; //FIXME no unsigned addressing obj_free (array); diff --git a/ruamoko/lib/Object.r b/ruamoko/lib/Object.r index c32d2b02e..4ac6e6459 100644 --- a/ruamoko/lib/Object.r +++ b/ruamoko/lib/Object.r @@ -294,7 +294,7 @@ BOOL (id object) object_is_meta_class = #0; } -- (integer) retainCount +- (unsigned) retainCount { return retainCount; } diff --git a/tools/qfcc/include/expr.h b/tools/qfcc/include/expr.h index b009d2849..0ec156f60 100644 --- a/tools/qfcc/include/expr.h +++ b/tools/qfcc/include/expr.h @@ -169,6 +169,9 @@ expr_t *append_expr (expr_t *block, expr_t *e); void print_expr (expr_t *e); void convert_int (expr_t *e); +void convert_uint (expr_t *e); +void convert_uint_int (expr_t *e); +void convert_int_uint (expr_t *e); expr_t *test_expr (expr_t *e, int test); expr_t *binary_expr (int op, expr_t *e1, expr_t *e2); diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index 3b59cab69..a4330dc06 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -1369,6 +1369,27 @@ convert_int (expr_t *e) e->e.float_val = e->e.integer_val; } +void +convert_uint (expr_t *e) +{ + e->type = ex_float; + e->e.float_val = e->e.uinteger_val; +} + +void +convert_uint_int (expr_t *e) +{ + e->type = ex_integer; + e->e.integer_val = e->e.uinteger_val; +} + +void +convert_int_uint (expr_t *e) +{ + e->type = ex_uinteger; + e->e.uinteger_val = e->e.integer_val; +} + static void convert_nil (expr_t *e, type_t *t) { @@ -1439,18 +1460,46 @@ binary_expr (int op, expr_t *e1, expr_t *e2) } } - if (e1->type == ex_integer - && (t2 == &type_float + if (e1->type == ex_integer) { + if (t2 == &type_float || t2 == &type_vector - || t2 == &type_quaternion)) { - convert_int (e1); - t1 = &type_float; - } else if (e2->type == ex_integer - && (t1 == &type_float - || t1 == &type_vector - || t1 == &type_quaternion)) { - convert_int (e2); - t2 = &type_float; + || t2 == &type_quaternion) { + convert_int (e1); + t1 = &type_float; + } else if (t2 == &type_uinteger) { + convert_int_uint (e1); + t1 = &type_uinteger; + } + } else if (e1->type == ex_uinteger) { + if (t2 == &type_float + || t2 == &type_vector + || t2 == &type_quaternion) { + convert_uint (e1); + t1 = &type_float; + } else if (t2 == &type_integer) { + convert_uint_int (e1); + t1 = &type_integer; + } + } else if (e2->type == ex_integer) { + if (t1 == &type_float + || t1 == &type_vector + || t1 == &type_quaternion) { + convert_int (e2); + t2 = &type_float; + } else if (t1 == &type_uinteger) { + convert_int_uint (e2); + t2 = &type_uinteger; + } + } else if (e2->type == ex_uinteger) { + if (t1 == &type_float + || t1 == &type_vector + || t1 == &type_quaternion) { + convert_uint (e2); + t2 = &type_float; + } else if (t1 == &type_integer) { + convert_uint_int (e2); + t2 = &type_integer; + } } if (e1->type >= ex_string && e2->type >= ex_string) @@ -2191,12 +2240,26 @@ assign_expr (expr_t *e1, expr_t *e2) error (e1, "internal error"); abort (); } - if (e2->type == ex_integer - && (t1 == &type_float + if (e2->type == ex_integer) { + if (t1 == &type_float || t1 == &type_vector - || t1 == &type_quaternion)) { - convert_int (e2); - t2 = &type_float; + || t1 == &type_quaternion) { + convert_int (e2); + t2 = &type_float; + } else if (t1 == &type_uinteger) { + convert_int_uint (e2); + t2 = &type_uinteger; + } + } else if (e2->type == ex_uinteger) { + if (t1 == &type_float + || t1 == &type_vector + || t1 == &type_quaternion) { + convert_uint (e2); + t2 = &type_float; + } else if (t1 == &type_integer) { + convert_uint_int (e2); + t2 = &type_integer; + } } if (t1->type != ev_void && e2->type == ex_nil) { @@ -2290,10 +2353,14 @@ cast_expr (type_t *type, expr_t *e) e_type = get_type (e); + if (type == e_type) + return e; + if (!(type->type == ev_pointer && e_type->type == ev_pointer) && !(type->type == ev_func && e_type->type == ev_func) && !(((type == &type_integer || type == &type_uinteger) - && e_type == &type_float) + && (e_type == &type_float || e_type == &type_integer + || e_type == &type_uinteger)) || (type == &type_float && (e_type == &type_integer || e_type == &type_uinteger)))) { c = error (e, "can not cast from %s to %s", @@ -2366,6 +2433,15 @@ init_elements (def_t *def, expr_t *eles) if (e->type == ex_integer && elements[i].type->type == ev_float) convert_int (e); + else if (e->type == ex_integer + && elements[i].type->type == ev_uinteger) + convert_int_uint (e); + else if (e->type == ex_uinteger + && elements[i].type->type == ev_float) + convert_uint (e); + else if (e->type == ex_uinteger + && elements[i].type->type == ev_integer) + convert_uint_int (e); if (get_type (e) != elements[i].type) { error (e, "type mismatch in initializer"); continue; diff --git a/tools/qfcc/source/qc-parse.y b/tools/qfcc/source/qc-parse.y index 3dc78475c..51dc0cadb 100644 --- a/tools/qfcc/source/qc-parse.y +++ b/tools/qfcc/source/qc-parse.y @@ -472,6 +472,8 @@ opt_state_expr { if ($2->type == ex_integer) convert_int ($2); + else if ($2->type == ex_uinteger) + convert_uint ($2); if ($2->type != ex_float) error ($2, "invalid type for frame number"); if ($5->type->type != ev_func)