Merge branch 'wip-new_instruction_set'

While there is still plenty of improvement to go (mostly in qfcc to take
advantage of the new features, but there's room for optimization in the
VM), the Ruamoko ISA seems to be working quite well.
This commit is contained in:
Bill Currie 2022-02-06 21:26:15 +09:00
commit 748661eb77
275 changed files with 23775 additions and 8077 deletions

1
.gitignore vendored
View file

@ -40,6 +40,7 @@ core
/ltmain.sh
/missing
/mkinstalldirs
/py-compile
/quakeforge-config
/quakeforge.lsm
/test-driver

View file

@ -42,6 +42,7 @@ noinst_LTLIBRARIES =
noinst_LIBRARIES =
noinst_PROGRAMS =
noinst_HEADERS =
noinst_PYTHON =
plugin_LTLIBRARIES =
RANLIB=touch
@ -110,6 +111,11 @@ qcautodep = $(join $(addsuffix $(DEPDIR)/,$(dir $(basename $(1)))),$(addsuffix .
r_depfiles_remade=
pas_depfiles_remade=
V_PY = $(V_PY_@AM_V@)
V_PY_ = $(V_PY_@AM_DEFAULT_V@)
V_PY_0 = @echo " PY " $@;
V_PY_1 =
V_GLSLANG = $(V_GLSLANG_@AM_V@)
V_GLSLANG_ = $(V_GLSLANG_@AM_DEFAULT_V@)
V_GLSLANG_0 = @echo " GLSLANG " $@;

View file

@ -316,9 +316,11 @@ if test "$ENABLE_tools_qfcc" = "yes" -a "$ENABLE_tools_pak" = "yes"; then
QF_NEED(top, [ruamoko])
qfac_qfcc_include_qf="\$(qfcc_include_qf)"
qfac_qfcc_include_qf_input="\$(qfcc_include_qf_input)"
qfac_qfcc_include_qf_progs="\$(qfcc_include_qf_progs)"
fi
QF_SUBST(qfac_qfcc_include_qf)
QF_SUBST(qfac_qfcc_include_qf_input)
QF_SUBST(qfac_qfcc_include_qf_progs)
if test x"${top_need_libs}" = xyes; then
qfac_include_qf="\$(include_qf)"

View file

@ -92,7 +92,6 @@ AC_ARG_ENABLE(simd,
case "$enable_simd" in
no)
QF_CC_OPTION(-Wno-psabi)
simd=no
;;
sse|sse2|avx|avx2)
@ -108,6 +107,13 @@ case "$enable_simd" in
done
;;
esac
case "$simd" in
avx*)
;;
*)
QF_CC_OPTION(-Wno-psabi)
;;
esac
AC_MSG_CHECKING(for optimization)
if test "x$optimize" = xyes -a "x$leave_cflags_alone" != "xyes"; then

View file

@ -8,6 +8,7 @@ AC_PROG_CPP
AC_PROG_LN_S
AC_PROG_RANLIB
AM_PROG_AS
AM_PATH_PYTHON([3])
PKG_PROG_PKG_CONFIG

View file

@ -5,7 +5,7 @@ call_progs_main (progs_t *pr, int argc, const char **argv)
{
int i;
dfunction_t *dfunc;
func_t progs_main = 0;
pr_func_t progs_main = 0;
string_t *pr_argv;
if ((dfunc = PR_FindFunction (pr, "main"))) {

View file

@ -43,10 +43,6 @@ include_qf = \
include/QF/plist.h \
include/QF/plugin.h \
include/QF/pqueue.h \
include/QF/pr_comp.h \
include/QF/pr_debug.h \
include/QF/pr_obj.h \
include/QF/pr_type.h \
include/QF/progs.h \
include/QF/pvsfile.h \
include/QF/qargs.h \
@ -119,6 +115,7 @@ include_qf_input = \
include/QF/input/imt.h
include_qf_math = \
include/QF/math/bitop.h \
include/QF/math/dual.h \
include/QF/math/half.h \
include/QF/math/matrix3.h \
@ -135,6 +132,13 @@ include_qf_plugin = \
include/QF/plugin/snd_render.h \
include/QF/plugin/vid_render.h
include_qf_progs = \
include/QF/progs/pr_comp.h \
include/QF/progs/pr_debug.h \
include/QF/progs/pr_obj.h \
include/QF/progs/pr_type.h \
include/QF/progs/pr_type_names.h
include_qf_scene = \
include/QF/scene/entity.h \
include/QF/scene/hierarchy.h \
@ -145,8 +149,12 @@ include_qf_scene = \
include_qf_simd = \
include/QF/simd/mat4f.h \
include/QF/simd/types.h \
include/QF/simd/vec2d.h \
include/QF/simd/vec2f.h \
include/QF/simd/vec2i.h \
include/QF/simd/vec4d.h \
include/QF/simd/vec4f.h
include/QF/simd/vec4f.h \
include/QF/simd/vec4i.h
include_qf_ui = \
include/QF/ui/inputline.h \
@ -191,6 +199,7 @@ include_qf_vulkan = \
# headers shared with ruamoko
qfcc_include_qf = include/QF/input.h
qfcc_include_qf_progs = include/QF/progs/pr_type_names.h
qfcc_include_qf_input = \
include/QF/input/binding.h \
include/QF/input/imt.h
@ -218,8 +227,10 @@ qf_vulkan_include_HEADERS = @qfac_include_qf_vulkan@
ruamoko_qf_includedir = $(ruamoko_includedir)/QF
ruamoko_qf_input_includedir = $(ruamoko_includedir)/QF/input
ruamoko_qf_progs_includedir = $(ruamoko_includedir)/QF/progs
ruamoko_qf_include_HEADERS = @qfac_qfcc_include_qf@
ruamoko_qf_input_include_HEADERS = @qfac_qfcc_include_qf_input@
ruamoko_qf_progs_include_HEADERS = @qfac_qfcc_include_qf_progs@
EXTRA_HEADERS += \
$(include_qf) \
@ -228,6 +239,7 @@ EXTRA_HEADERS += \
$(include_qf_input) \
$(include_qf_math) \
$(include_qf_plugin) \
$(include_qf_progs) \
$(include_qf_scene) \
$(include_qf_simd) \
$(include_qf_ui) \

73
include/QF/math/bitop.h Normal file
View file

@ -0,0 +1,73 @@
/*
bitop.h
bit-op functions
Copyright (C) 2022 Bill Currie <bill@taniwha.org>
Author: Bill Currie <bill@taniwha.org>
Date: 2022/1/23
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifndef __QF_math_bitop_h
#define __QF_math_bitop_h
/** \defgroup mathlib_bitop Bit-op functions
\ingroup utils
*/
///@{
#include "QF/qtypes.h"
#define BITOP_RUP1__(x) ( (x) | ( (x) >> 1))
#define BITOP_RUP2__(x) (BITOP_RUP1__(x) | (BITOP_RUP1__(x) >> 2))
#define BITOP_RUP4__(x) (BITOP_RUP2__(x) | (BITOP_RUP2__(x) >> 4))
#define BITOP_RUP8__(x) (BITOP_RUP4__(x) | (BITOP_RUP4__(x) >> 8))
#define BITOP_RUP16__(x) (BITOP_RUP8__(x) | (BITOP_RUP8__(x) >> 16))
/** Round x up to the next power of two.
Rounds x up to the next power of two leaving exact powers of two
untouched.
\param x The value to round
\return The next higher power of two or x if it already is a power
of two.
*/
#define BITOP_RUP(x) (BITOP_RUP16__((uint32_t)(x) - 1) + 1)
#define BITOP_LOG2__(x) (((((x) & 0xffff0000) != 0) << 4) \
|((((x) & 0xff00ff00) != 0) << 3) \
|((((x) & 0xf0f0f0f0) != 0) << 2) \
|((((x) & 0xcccccccc) != 0) << 1) \
|((((x) & 0xaaaaaaaa) != 0) << 0))
/** Log base 2 rounded up.
Finds the base 2 logarithm of x rounded up (ceil(log2(x))).
\param x The value for which to find the base 2 logarithm.
\return Log base 2 of x, rounded up (2 -> 1, 3 -> 2, 4 -> 2)
*/
#define BITOP_LOG2(x) BITOP_LOG2__(BITOP_RUP(x))
///@}
#endif // __QF_math_bitop_h

View file

@ -115,10 +115,17 @@ extern const vec_t *const quat_origin;
(c)[2] = (a)[2] / (b)[2]; \
(c)[3] = (a)[3] / (b)[3]; \
} while (0)
#define QuatCompCompare(x, op, y) \
#define QuatCompCompare(m, a, op, b, c) \
do { \
(c)[0] = m((a)[0] op (b)[0]); \
(c)[1] = m((a)[1] op (b)[1]); \
(c)[2] = m((a)[2] op (b)[2]); \
(c)[3] = m((a)[3] op (b)[3]); \
} while (0)
#define QuatCompCompareAll(x, op, y) \
(((x)[0] op (y)[0]) && ((x)[1] op (y)[1]) \
&& ((x)[2] op (y)[2]) && ((x)[3] op (y)[3]))
#define QuatCompare(x, y) QuatCompCompare (x, ==, y)
#define QuatCompare(x, y) QuatCompCompareAll (x, ==, y)
#define QuatCompMin(a, b, c) \
do { \
(c)[0] = min ((a)[0], (b)[0]); \

View file

@ -37,25 +37,27 @@
extern const vec_t *const vec3_origin;
#define VectorCompUop(b, op, a) \
do { \
(b)[0] = op ((a)[0]); \
(b)[1] = op ((a)[1]); \
(b)[2] = op ((a)[2]); \
} while (0)
#define VectorCompOp(c, a, op, b) \
do { \
(c)[0] = (a)[0] op (b)[0]; \
(c)[1] = (a)[1] op (b)[1]; \
(c)[2] = (a)[2] op (b)[2]; \
} while (0)
#define VectorCompAdd(c,a,b) VectorCompOp (c, a, +, b)
#define VectorCompSub(c,a,b) VectorCompOp (c, a, -, b)
#define VectorCompMult(c,a,b) VectorCompOp (c, a, *, b)
#define VectorCompDiv(c,a,b) VectorCompOp (c, a, /, b)
#define DotProduct(a,b) ((a)[0] * (b)[0] + (a)[1] * (b)[1] + (a)[2] * (b)[2])
#define VectorSubtract(a,b,c) \
do { \
(c)[0] = (a)[0] - (b)[0]; \
(c)[1] = (a)[1] - (b)[1]; \
(c)[2] = (a)[2] - (b)[2]; \
} while (0)
#define VectorNegate(a,b) \
do { \
(b)[0] = -(a)[0]; \
(b)[1] = -(a)[1]; \
(b)[2] = -(a)[2]; \
} while (0)
#define VectorAdd(a,b,c) \
do { \
(c)[0] = (a)[0] + (b)[0]; \
(c)[1] = (a)[1] + (b)[1]; \
(c)[2] = (a)[2] + (b)[2]; \
} while (0)
#define VectorSubtract(a,b,c) VectorCompSub (c, a, b)
#define VectorNegate(a,b) VectorCompUop (b, -, a)
#define VectorAdd(a,b,c) VectorCompAdd (c, a, b)
#define VectorCopy(a,b) \
do { \
(b)[0] = (a)[0]; \
@ -119,21 +121,15 @@ extern const vec_t *const vec3_origin;
(c)[1] = (b)[1] - (b)[0] * (a)[0]; \
(c)[0] = (b)[0]; \
} while (0)
#define VectorCompMult(a,b,c) \
#define VectorCompCompare(c, m, a, op, b) \
do { \
(c)[0] = (a)[0] * (b)[0]; \
(c)[1] = (a)[1] * (b)[1]; \
(c)[2] = (a)[2] * (b)[2]; \
(c)[0] = m((a)[0] op (b)[0]); \
(c)[1] = m((a)[1] op (b)[1]); \
(c)[2] = m((a)[2] op (b)[2]); \
} while (0)
#define VectorCompDiv(a,b,c) \
do { \
(c)[0] = (a)[0] / (b)[0]; \
(c)[1] = (a)[1] / (b)[1]; \
(c)[2] = (a)[2] / (b)[2]; \
} while (0)
#define VectorCompCompare(x, op, y) \
#define VectorCompCompareAll(x, op, y) \
(((x)[0] op (y)[0]) && ((x)[1] op (y)[1]) && ((x)[2] op (y)[2]))
#define VectorCompare(x, y) VectorCompCompare (x, ==, y)
#define VectorCompare(x, y) VectorCompCompareAll (x, ==, y)
#define VectorCompMin(a, b, c) \
do { \
(c)[0] = min ((a)[0], (b)[0]); \

View file

@ -1,521 +0,0 @@
/* Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
See file, 'COPYING', for details.
*/
// this file is shared by QuakeForge and qfcc
#ifndef __QF_pr_comp_h
#define __QF_pr_comp_h
#include "QF/qtypes.h"
typedef int16_t pr_short_t;
typedef uint16_t pr_ushort_t;
typedef int32_t pr_int_t;
typedef uint32_t pr_uint_t;
typedef pr_uint_t func_t;
typedef pr_int_t string_t;
typedef pr_uint_t pointer_t;
typedef enum {
ev_void,
ev_string,
ev_float,
ev_vector,
ev_entity,
ev_field,
ev_func,
ev_pointer, // end of v6 types
ev_quat,
ev_integer,
ev_uinteger,
ev_short, // value is embedded in the opcode
ev_double,
ev_invalid, // invalid type. used for instruction checking
ev_type_count // not a type, gives number of types
} etype_t;
extern const pr_ushort_t pr_type_size[ev_type_count];
extern const char * const pr_type_name[ev_type_count];
#define OFS_NULL 0
#define OFS_RETURN 1
#define OFS_PARM0 4 // leave 3 ofs for each parm to hold vectors
#define OFS_PARM1 7
#define OFS_PARM2 10
#define OFS_PARM3 13
#define OFS_PARM4 16
#define OFS_PARM5 19
#define OFS_PARM6 22
#define OFS_PARM7 25
#define RESERVED_OFS 28
typedef enum {
OP_DONE,
OP_MUL_F,
OP_MUL_V,
OP_MUL_FV,
OP_MUL_VF,
OP_DIV_F,
OP_ADD_F,
OP_ADD_V,
OP_SUB_F,
OP_SUB_V,
OP_EQ_F,
OP_EQ_V,
OP_EQ_S,
OP_EQ_E,
OP_EQ_FN,
OP_NE_F,
OP_NE_V,
OP_NE_S,
OP_NE_E,
OP_NE_FN,
OP_LE_F,
OP_GE_F,
OP_LT_F,
OP_GT_F,
OP_LOAD_F,
OP_LOAD_V,
OP_LOAD_S,
OP_LOAD_ENT,
OP_LOAD_FLD,
OP_LOAD_FN,
OP_ADDRESS,
OP_STORE_F,
OP_STORE_V,
OP_STORE_S,
OP_STORE_ENT,
OP_STORE_FLD,
OP_STORE_FN,
OP_STOREP_F,
OP_STOREP_V,
OP_STOREP_S,
OP_STOREP_ENT,
OP_STOREP_FLD,
OP_STOREP_FN,
OP_RETURN,
OP_NOT_F,
OP_NOT_V,
OP_NOT_S,
OP_NOT_ENT,
OP_NOT_FN,
OP_IF,
OP_IFNOT,
OP_CALL0,
OP_CALL1,
OP_CALL2,
OP_CALL3,
OP_CALL4,
OP_CALL5,
OP_CALL6,
OP_CALL7,
OP_CALL8,
OP_STATE,
OP_GOTO,
OP_AND,
OP_OR,
OP_BITAND,
OP_BITOR, // end of v6 opcodes
OP_ADD_S,
OP_LE_S,
OP_GE_S,
OP_LT_S,
OP_GT_S,
OP_ADD_I,
OP_SUB_I,
OP_MUL_I,
OP_DIV_I,
OP_BITAND_I,
OP_BITOR_I,
OP_GE_I,
OP_LE_I,
OP_GT_I,
OP_LT_I,
OP_AND_I,
OP_OR_I,
OP_NOT_I,
OP_EQ_I,
OP_NE_I,
OP_STORE_I,
OP_STOREP_I,
OP_LOAD_I,
OP_CONV_IF,
OP_CONV_FI,
OP_BITXOR_F,
OP_BITXOR_I,
OP_BITNOT_F,
OP_BITNOT_I,
OP_SHL_F,
OP_SHR_F,
OP_SHL_I,
OP_SHR_I,
OP_REM_F,
OP_REM_I,
OP_LOADB_F,
OP_LOADB_V,
OP_LOADB_S,
OP_LOADB_ENT,
OP_LOADB_FLD,
OP_LOADB_FN,
OP_LOADB_I,
OP_LOADB_P,
OP_STOREB_F,
OP_STOREB_V,
OP_STOREB_S,
OP_STOREB_ENT,
OP_STOREB_FLD,
OP_STOREB_FN,
OP_STOREB_I,
OP_STOREB_P,
OP_ADDRESS_VOID,
OP_ADDRESS_F,
OP_ADDRESS_V,
OP_ADDRESS_S,
OP_ADDRESS_ENT,
OP_ADDRESS_FLD,
OP_ADDRESS_FN,
OP_ADDRESS_I,
OP_ADDRESS_P,
OP_LEA,
OP_IFBE,
OP_IFB,
OP_IFAE,
OP_IFA,
OP_JUMP,
OP_JUMPB,
OP_LT_U,
OP_GT_U,
OP_LE_U,
OP_GE_U,
OP_LOADBI_F,
OP_LOADBI_V,
OP_LOADBI_S,
OP_LOADBI_ENT,
OP_LOADBI_FLD,
OP_LOADBI_FN,
OP_LOADBI_I,
OP_LOADBI_P,
OP_STOREBI_F,
OP_STOREBI_V,
OP_STOREBI_S,
OP_STOREBI_ENT,
OP_STOREBI_FLD,
OP_STOREBI_FN,
OP_STOREBI_I,
OP_STOREBI_P,
OP_LEAI,
OP_LOAD_P,
OP_STORE_P,
OP_STOREP_P,
OP_NOT_P,
OP_EQ_P,
OP_NE_P,
OP_LE_P,
OP_GE_P,
OP_LT_P,
OP_GT_P,
OP_MOVEI,
OP_MOVEP,
OP_MOVEPI,
OP_SHR_U,
OP_STATE_F,
OP_ADD_Q,
OP_SUB_Q,
OP_MUL_Q,
OP_MUL_QF,
OP_MUL_FQ,
OP_MUL_QV,
OP_CONJ_Q,
OP_NOT_Q,
OP_EQ_Q,
OP_NE_Q,
OP_STORE_Q,
OP_STOREB_Q,
OP_STOREBI_Q,
OP_STOREP_Q,
OP_LOAD_Q,
OP_LOADB_Q,
OP_LOADBI_Q,
OP_ADDRESS_Q,
OP_RCALL0,
OP_RCALL1,
OP_RCALL2,
OP_RCALL3,
OP_RCALL4,
OP_RCALL5,
OP_RCALL6,
OP_RCALL7,
OP_RCALL8,
OP_RETURN_V,
OP_PUSH_S,
OP_PUSH_F,
OP_PUSH_V,
OP_PUSH_ENT,
OP_PUSH_FLD,
OP_PUSH_FN,
OP_PUSH_P,
OP_PUSH_Q,
OP_PUSH_I,
OP_PUSH_D,
OP_PUSHB_S,
OP_PUSHB_F,
OP_PUSHB_V,
OP_PUSHB_ENT,
OP_PUSHB_FLD,
OP_PUSHB_FN,
OP_PUSHB_P,
OP_PUSHB_Q,
OP_PUSHB_I,
OP_PUSHB_D,
OP_PUSHBI_S,
OP_PUSHBI_F,
OP_PUSHBI_V,
OP_PUSHBI_ENT,
OP_PUSHBI_FLD,
OP_PUSHBI_FN,
OP_PUSHBI_P,
OP_PUSHBI_Q,
OP_PUSHBI_I,
OP_PUSHBI_D,
OP_POP_S,
OP_POP_F,
OP_POP_V,
OP_POP_ENT,
OP_POP_FLD,
OP_POP_FN,
OP_POP_P,
OP_POP_Q,
OP_POP_I,
OP_POP_D,
OP_POPB_S,
OP_POPB_F,
OP_POPB_V,
OP_POPB_ENT,
OP_POPB_FLD,
OP_POPB_FN,
OP_POPB_P,
OP_POPB_Q,
OP_POPB_I,
OP_POPB_D,
OP_POPBI_S,
OP_POPBI_F,
OP_POPBI_V,
OP_POPBI_ENT,
OP_POPBI_FLD,
OP_POPBI_FN,
OP_POPBI_P,
OP_POPBI_Q,
OP_POPBI_I,
OP_POPBI_D,
OP_ADD_D,
OP_SUB_D,
OP_MUL_D,
OP_MUL_QD,
OP_MUL_DQ,
OP_MUL_VD,
OP_MUL_DV,
OP_DIV_D,
OP_REM_D,
OP_GE_D,
OP_LE_D,
OP_GT_D,
OP_LT_D,
OP_NOT_D,
OP_EQ_D,
OP_NE_D,
OP_CONV_FD,
OP_CONV_DF,
OP_CONV_ID,
OP_CONV_DI,
OP_STORE_D,
OP_STOREB_D,
OP_STOREBI_D,
OP_STOREP_D,
OP_LOAD_D,
OP_LOADB_D,
OP_LOADBI_D,
OP_ADDRESS_D,
OP_MOD_I,
OP_MOD_F,
OP_MOD_D,
OP_MEMSETI,
OP_MEMSETP,
OP_MEMSETPI,
} pr_opcode_e;
#define OP_BREAK 0x8000
typedef struct opcode_s {
const char *name;
const char *opname;
pr_opcode_e opcode;
qboolean right_associative;
etype_t type_a, type_b, type_c;
unsigned int min_version;
const char *fmt;
} opcode_t;
extern const opcode_t pr_opcodes[];
opcode_t *PR_Opcode (pr_short_t opcode);
void PR_Opcode_Init (void); // idempotent
typedef struct dstatement_s {
pr_opcode_e op:16;
pr_ushort_t a,b,c;
} GCC_STRUCT dstatement_t;
typedef struct ddef_s {
pr_ushort_t type; // if DEF_SAVEGLOBAL bit is set
// the variable needs to be saved in savegames
pr_ushort_t ofs;
string_t s_name;
} ddef_t;
typedef struct xdef_s {
pointer_t type; ///< pointer to type definition
pointer_t ofs; ///< 32-bit version of ddef_t.ofs
} xdef_t;
typedef struct pr_xdefs_s {
pointer_t xdefs;
pr_int_t num_xdefs;
} pr_xdefs_t;
typedef struct pr_def_s {
pr_ushort_t type;
pr_ushort_t size; ///< may not be correct
pointer_t ofs;
string_t name;
pointer_t type_encoding;
} pr_def_t;
typedef struct dparmsize_s {
uint8_t size:5;
uint8_t alignment:3;
} dparmsize_t;
#define DEF_SAVEGLOBAL (1<<15)
#define MAX_PARMS 8
typedef struct dfunction_s {
pr_int_t first_statement; // negative numbers are builtins
pr_uint_t parm_start;
pr_uint_t locals; // total ints of parms + locals
pr_uint_t profile; // runtime
string_t s_name;
string_t s_file; // source file defined in
pr_int_t numparms;
dparmsize_t parm_size[MAX_PARMS];
} dfunction_t;
typedef union pr_type_u {
float float_var;
string_t string_var;
func_t func_var;
pr_int_t entity_var;
float vector_var; // really [3], but this structure must be 32 bits
float quat_var; // really [4], but this structure must be 32 bits
pr_int_t integer_var;
pointer_t pointer_var;
pr_uint_t uinteger_var;
} pr_type_t;
typedef struct pr_va_list_s {
pr_int_t count;
pointer_t list; // pr_type_t
} pr_va_list_t;
#define PROG_VERSION_ENCODE(a,b,c) \
( (((0x##a) & 0x0ff) << 24) \
|(((0x##b) & 0xfff) << 12) \
|(((0x##c) & 0xfff) << 0) )
#define PROG_ID_VERSION 6
#define PROG_VERSION PROG_VERSION_ENCODE(0,fff,00a)
typedef struct dprograms_s {
pr_uint_t version;
pr_uint_t crc; // check of header file
pr_uint_t ofs_statements;
pr_uint_t numstatements; // statement 0 is an error
pr_uint_t ofs_globaldefs;
pr_uint_t numglobaldefs;
pr_uint_t ofs_fielddefs;
pr_uint_t numfielddefs;
pr_uint_t ofs_functions;
pr_uint_t numfunctions; // function 0 is an empty
pr_uint_t ofs_strings;
pr_uint_t numstrings; // first string is a null string
pr_uint_t ofs_globals;
pr_uint_t numglobals;
pr_uint_t entityfields;
} dprograms_t;
#endif//__QF_pr_comp_h

View file

@ -33,8 +33,9 @@
\image latex vm-mem.eps "VM memory map"
*/
#include "QF/pr_comp.h"
#include "QF/pr_debug.h"
#include "QF/math/bitop.h"
#include "QF/progs/pr_comp.h"
#include "QF/progs/pr_debug.h"
struct QFile_s;
@ -81,15 +82,13 @@ void PR_RunError (progs_t *pr, const char *error, ...) __attribute__((format(PRI
\warning Failure to use this macro before assigning to the P_* macros can
cause corruption of the VM data due to "register" based calling. Can be
safely ignored for parameterless functions, or forwarding parameters
though a builtin.
though a builtin. However, it is ok (and encouraged) to call
PR_SetupParams instead, as this macro calls PR_SetupParams with
PR_MAX_PARAMS and 1 for the alignment.
\hideinitializer
*/
#define PR_RESET_PARAMS(pr) \
do { \
(pr)->pr_params[0] = (pr)->pr_real_params[0]; \
(pr)->pr_params[1] = (pr)->pr_real_params[1]; \
} while (0)
#define PR_RESET_PARAMS(pr) PR_SetupParams (pr, PR_MAX_PARAMS, 1)
/** \name Detouring Function Calls
@ -154,6 +153,38 @@ void PR_RestoreParams (progs_t *pr, pr_stashed_params_t *params);
*/
void PR_PushFrame (progs_t *pr);
/** Reserve space on the data stack and set up the param pointers.
For v6p progs, this only sets up the param pointers as v6p progs do not
have a data stack.
For Ruamoko progs, space for at least \a num_params (each being 4 words)
is created on the stack, with a minimum alignment of min_alignment words,
or 4, whichever is larger.
\param pr pointer to ::progs_t VM struct
\param num_params Number of parameter slots needed for the function call.
Each slot is 4 words. dvec4 and lvec4 parameters require
8 words and must be 8-word aligned. dvec3 and lvec3
also require 8 words due to the minimum 4 word alignment,
but have no alignment requirements themselves. Be sure to
take this into account in size calculations.
\param min_alignment Minimum number of words to which the stack will be
aligned. Must be a power of two. Note that when passing
dvec4 or lvec4 parameters, they have a hardware-enforced
requirement of 8 word alignment. This means that for
something like (int, lvec4), there will be an unused
parameter slot between the int and the lvec4.
Ignored for v6p progs.
\return Pointer to the base of the created parameter area. For
v6p progs, this is just .param_0, but for Ruamoko progs
this will be the current top of the the data stack after
adjustment for the parameter space.
\note Attempting to pass more than PR_MAX_PARAMS parameters to v6p progs
is a hard error.
*/
pr_type_t *PR_SetupParams (progs_t *pr, int num_params, int min_alignment);
/** Pop an execution frame from the VM stack. Restores execution state. Also
frees any temporary strings allocated in this frame (via
PR_FreeTempStrings()).
@ -166,8 +197,9 @@ void PR_PopFrame (progs_t *pr);
return to the caller. Nested calls are fully supported.
\param pr pointer to ::progs_t VM struct
\param fnum number of the function to call
\note Calls PR_CallFunction()
*/
void PR_ExecuteProgram (progs_t *pr, func_t fnum);
void PR_ExecuteProgram (progs_t *pr, pr_func_t fnum);
/** Setup to call a function. If \p fnum is a builtin rather than a progs
function, then the function is called immediately. When called from a
@ -175,10 +207,15 @@ void PR_ExecuteProgram (progs_t *pr, func_t fnum);
execute upon return of control to PR_ExecuteProgram().
\param pr pointer to ::progs_t VM struct
\param fnum number of the function to call
\param return_ptr pointer to location in which return values will be
written
\return true if \p fnum was a progs function, false if \p fnum was
a builtin
\note Called by PR_ExecuteProgram, so the only time this should be called
is in a builtin function that calls a progs function and returns
immediately (eg, to implement `return progsfunc();`).
*/
int PR_CallFunction (progs_t *pr, func_t fnum);
int PR_CallFunction (progs_t *pr, pr_func_t fnum, pr_type_t *return_ptr);
///@}
@ -195,7 +232,7 @@ typedef int pr_load_func_t (progs_t *pr);
/** Initialize a ::progs_t VM struct from an already open file.
\param pr pointer to ::progs_t VM struct
\param file handle of file to read progs data from
\param file handle of file from which to read progs data
\param size bytes of \p file to read
\note \e All runtime strings (permanent or temporary) are allocated from
@ -262,8 +299,9 @@ int PR_RunPostLoadFuncs (progs_t *pr);
\todo should this be elsewhere?
*/
int PR_Check_Opcodes (progs_t *pr);
int PR_Check_v6p_Opcodes (progs_t *pr);
void PR_BoundsCheckSize (progs_t *pr, pointer_t addr, unsigned size);
void PR_BoundsCheckSize (progs_t *pr, pr_ptr_t addr, unsigned size);
void PR_BoundsCheck (progs_t *pr, int addr, etype_t type);
///@}
@ -276,8 +314,8 @@ void PR_BoundsCheck (progs_t *pr, int addr, etype_t type);
struct edict_s {
qboolean free;
progs_t *pr; ///< progs owning this edict
int entnum; ///< number of this entity
int edict; ///< offset of this entity in pr_edict_area
pr_uint_t entnum; ///< number of this entity
pr_uint_t edict; ///< offset of this entity in pr_edict_area
float freetime; ///< sv.time when the object was freed
void *edata; ///< external per-edict data
};
@ -286,10 +324,10 @@ struct edict_s {
void ED_ClearEdict (progs_t *pr, edict_t *e, int val);
edict_t *ED_Alloc (progs_t *pr);
void ED_Free (progs_t *pr, edict_t *ed);
edict_t *ED_EdictNum(progs_t *pr, pr_int_t n) __attribute__((pure));
pr_int_t ED_NumForEdict(progs_t *pr, edict_t *e) __attribute__((pure));
edict_t *ED_EdictNum(progs_t *pr, pr_uint_t n) __attribute__((pure));
pr_uint_t ED_NumForEdict(progs_t *pr, edict_t *e) __attribute__((pure));
void ED_Count (progs_t *pr);
qboolean PR_EdictValid (progs_t *pr, pr_int_t e) __attribute__((pure));
qboolean PR_EdictValid (progs_t *pr, pr_uint_t e) __attribute__((pure));
// pr_debug.c
void ED_Print (progs_t *pr, edict_t *ed, const char *fieldname);
@ -314,10 +352,10 @@ void ED_EntityParseFunction (progs_t *pr);
#define PR_edicts(p) (*(p)->pr_edicts)
#define NEXT_EDICT(p,e) ((e) + 1)
#define EDICT_TO_PROG(p,e) ((e)->entnum * (p)->pr_edict_size)
#define NEXT_EDICT(p,e) ((e) ? (e) + 1 : 0)
#define EDICT_TO_PROG(p,e) ((e) ? (e)->entnum * (p)->pr_edict_size : 0)
#define PROG_TO_EDICT(p,e) (&PR_edicts(p)[(e) / (p)->pr_edict_size])
#define NUM_FOR_BAD_EDICT(p,e) ((e)->entnum)
#define NUM_FOR_BAD_EDICT(p,e) ((e) ? (e)->entnum : 0)
#ifndef PR_PARANOID_PROGS
# define EDICT_NUM(p,n) (PR_edicts (p) + (n))
# define NUM_FOR_EDICT(p,e) NUM_FOR_BAD_EDICT ((p), (e))
@ -334,10 +372,10 @@ void ED_EntityParseFunction (progs_t *pr);
*/
///@{
pr_def_t *PR_SearchDefs (pr_def_t *defs, unsigned num_defs, pointer_t offset)
pr_def_t *PR_SearchDefs (pr_def_t *defs, unsigned num_defs, pr_ptr_t offset)
__attribute__((pure));
pr_def_t *PR_FieldAtOfs (progs_t *pr, pointer_t ofs) __attribute__((pure));
pr_def_t *PR_GlobalAtOfs (progs_t *pr, pointer_t ofs) __attribute__((pure));
pr_def_t *PR_FieldAtOfs (progs_t *pr, pr_ptr_t ofs) __attribute__((pure));
pr_def_t *PR_GlobalAtOfs (progs_t *pr, pr_ptr_t ofs) __attribute__((pure));
pr_def_t *PR_FindField (progs_t *pr, const char *name);
pr_def_t *PR_FindGlobal (progs_t *pr, const char *name);
@ -414,29 +452,29 @@ void PR_Undefined (progs_t *pr, const char *type, const char *name) __attribute_
*/
#define G_DOUBLE(p,o) (*(double *) ((p)->pr_globals + o))
/** Access an integer global. Can be assigned to.
/** Access an int global. Can be assigned to.
\par QC type:
\c integer
\c int
\param p pointer to ::progs_t VM struct
\param o offset into global data space
\return int lvalue
\hideinitializer
*/
#define G_INT(p,o) G_var (p, o, integer)
#define G_INT(p,o) G_var (p, o, int)
/** Access an unsigned integer global. Can be assigned to.
/** Access an unsigned int global. Can be assigned to.
\par QC type:
\c uinteger
\c uint
\param p pointer to ::progs_t VM struct
\param o offset into global data space
\return unsigned int lvalue
\hideinitializer
*/
#define G_UINT(p,o) G_var (p, o, uinteger)
#define G_UINT(p,o) G_var (p, o, uint)
/** Access a vector global. Can be assigned to.
@ -468,7 +506,7 @@ void PR_Undefined (progs_t *pr, const char *type, const char *name) __attribute_
\c string
\param p pointer to ::progs_t VM struct
\param o offset into global data space
\return string_t lvalue
\return pr_string_t lvalue
\hideinitializer
*/
@ -480,7 +518,7 @@ void PR_Undefined (progs_t *pr, const char *type, const char *name) __attribute_
\c void()
\param p pointer to ::progs_t VM struct
\param o offset into global data space
\return func_t lvalue
\return pr_func_t lvalue
\hideinitializer
*/
@ -492,7 +530,7 @@ void PR_Undefined (progs_t *pr, const char *type, const char *name) __attribute_
\c void *
\param p pointer to ::progs_t VM struct
\param o offset into global data space
\return pointer_t lvalue
\return pr_ptr_t lvalue
\hideinitializer
*/
@ -630,29 +668,29 @@ void PR_Undefined (progs_t *pr, const char *type, const char *name) __attribute_
*/
#define P_DOUBLE(p,n) P_PACKED(p, double, n)
/** Access an integer parameter. Can be assigned to.
/** Access an int parameter. Can be assigned to.
\par QC type:
\c integer
\c int
\param p pointer to ::progs_t VM struct
\param n parameter number (0-7)
\return int lvalue
\hideinitializer
*/
#define P_INT(p,n) P_var (p, n, integer)
#define P_INT(p,n) P_var (p, n, int)
/** Access an unsigned integer parameter. Can be assigned to.
/** Access an unsigned int parameter. Can be assigned to.
\par QC type:
\c uinteger
\c uint
\param p pointer to ::progs_t VM struct
\param n parameter number (0-7)
\return unsigned int lvalue
\hideinitializer
*/
#define P_UINT(p,n) P_var (p, n, uinteger)
#define P_UINT(p,n) P_var (p, n, uint)
/** Access a vector parameter. Can be used any way a vec3_t variable can.
@ -684,7 +722,7 @@ void PR_Undefined (progs_t *pr, const char *type, const char *name) __attribute_
\c string
\param p pointer to ::progs_t VM struct
\param n parameter number (0-7)
\return string_t lvalue
\return pr_string_t lvalue
\hideinitializer
*/
@ -696,7 +734,7 @@ void PR_Undefined (progs_t *pr, const char *type, const char *name) __attribute_
\c void()
\param p pointer to ::progs_t VM struct
\param n parameter number (0-7)
\return func_t lvalue
\return pr_func_t lvalue
\hideinitializer
*/
@ -708,7 +746,7 @@ void PR_Undefined (progs_t *pr, const char *type, const char *name) __attribute_
\c void *
\param p pointer to ::progs_t VM struct
\param n parameter number (0-7)
\return pointer_t lvalue
\return pr_ptr_t lvalue
\hideinitializer
*/
@ -848,24 +886,24 @@ void PR_Undefined (progs_t *pr, const char *type, const char *name) __attribute_
/** Access the VM function return value as a \c ::pr_int_t (AKA int32_t)
\par QC type:
\c integer
\c int
\param p pointer to ::progs_t VM struct
\return ::pr_int_t lvalue
\hideinitializer
*/
#define R_INT(p) R_var (p, integer)
#define R_INT(p) R_var (p, int)
/** Access the VM function return value as a \c ::pr_uint_t (AKA uint32_t)
\par QC type:
\c uinteger
\c uint
\param p pointer to ::progs_t VM struct
\return ::pr_int_t lvalue
\hideinitializer
*/
#define R_UINT(p) R_var (p, uinteger)
#define R_UINT(p) R_var (p, uint)
/** Access the VM function return value as a \c ::vec3_t vector.
@ -889,34 +927,34 @@ void PR_Undefined (progs_t *pr, const char *type, const char *name) __attribute_
*/
#define R_QUAT(p) (&R_var (p, quat))
/** Access the VM function return value as a ::string_t (a VM string reference).
/** Access the VM function return value as a ::pr_string_t (a VM string reference).
\par QC type:
\c string
\param p pointer to ::progs_t VM struct
\return ::string_t lvalue
\return ::pr_string_t lvalue
\hideinitializer
*/
#define R_STRING(p) R_var (p, string)
/** Access the VM function return value as a ::func_t (a VM function reference)
/** Access the VM function return value as a ::pr_func_t (a VM function reference)
\par QC type:
\c void()
\param p pointer to ::progs_t VM struct
\return ::func_t lvalue
\return ::pr_func_t lvalue
\hideinitializer
*/
#define R_FUNCTION(p) R_var (p, func)
/** Access the VM function return value as a ::pointer_t (a VM "pointer")
/** Access the VM function return value as a ::pr_ptr_t (a VM "pointer")
\par QC type:
\c void *
\param p pointer to ::progs_t VM struct
\return ::pointer_t lvalue
\return ::pr_ptr_t lvalue
\hideinitializer
*/
@ -978,7 +1016,7 @@ void PR_Undefined (progs_t *pr, const char *type, const char *name) __attribute_
\hideinitializer
*/
#define RETURN_QUAT(p,q) VectorCopy (q, R_QUAT (p))
#define RETURN_QUAT(p,q) QuatCopy (q, R_QUAT (p))
///@}
/** \defgroup prda_entity_fields Entity Fields
@ -1034,29 +1072,29 @@ void PR_Undefined (progs_t *pr, const char *type, const char *name) __attribute_
*/
#define E_DOUBLE(e,o) (*(double *) ((e)->v + o))
/** Access an integer entity field. Can be assigned to.
/** Access an int entity field. Can be assigned to.
\par QC type:
\c integer
\c int
\param e pointer to the entity
\param o field offset into entity data space
\return int lvalue
\hideinitializer
*/
#define E_INT(e,o) E_var (e, o, integer)
#define E_INT(e,o) E_var (e, o, int)
/** Access an unsigned integer entity field. Can be assigned to.
/** Access an unsigned int entity field. Can be assigned to.
\par QC type:
\c uinteger
\c uint
\param e pointer to the entity
\param o field offset into entity data space
\return unsigned int lvalue
\hideinitializer
*/
#define E_UINT(e,o) E_var (e, o, uinteger)
#define E_UINT(e,o) E_var (e, o, uint)
/** Access a vector entity field. Can be used any way a vec3_t variable can.
@ -1089,7 +1127,7 @@ void PR_Undefined (progs_t *pr, const char *type, const char *name) __attribute_
\c string
\param e pointer to the entity
\param o field offset into entity data space
\return string_t lvalue
\return pr_string_t lvalue
\hideinitializer
*/
@ -1101,7 +1139,7 @@ void PR_Undefined (progs_t *pr, const char *type, const char *name) __attribute_
\c void()
\param e pointer to the entity
\param o field offset into entity data space
\return func_t lvalue
\return pr_func_t lvalue
\hideinitializer
*/
@ -1113,7 +1151,7 @@ void PR_Undefined (progs_t *pr, const char *type, const char *name) __attribute_
\c void *
\param e pointer to the entity
\param o field offset into entity data space
\return pointer_t lvalue
\return pr_ptr_t lvalue
\hideinitializer
*/
@ -1186,21 +1224,56 @@ typedef struct {
/// The number of the builtin for \#N in QC. -1 for automatic allocation.
/// 0 or >= ::PR_AUTOBUILTIN is invalid.
pr_int_t binum;
/// The number of parameters the builtin takes. Negative numbers mean
/// varargs with ~num_params (-num_params - 1) being the number of real
/// parameters.
pr_int_t num_params;
/// Parameter size specificiation.
///
/// Up to 8 parameters are supported for automatic parameter setup because
/// that's all that v6p progs can pass. Builtins taking more than 8
/// parameters are already Ruamoko-only and thus know how to deal with the
/// parameters being on the data stack.
///
/// The encoding is the same as for progs functions, with 3:5 for
/// alignment:size (size 0 means 32 words).
dparmsize_t params[PR_MAX_PARAMS];
/// Data passed to builtin functions. Set by PR_RegisterBuiltins
void *data;
} builtin_t;
#define PR_PARAM(type) { \
.size = PR_SIZEOF(type) & 0x1f, \
.alignment = BITOP_LOG2(PR_ALIGNOF(type)), \
}
/** Duplicate the dfunction_t descriptor with the addition of a pointer to the
builtin function. Avoids a level of indirection when calling a builtin
function.
*/
typedef struct {
pr_int_t first_statement;
pr_int_t parm_start;
pr_int_t locals;
pr_uint_t profile;
pr_int_t numparms;
dparmsize_t parm_size[MAX_PARMS];
dfunction_t *descriptor;
builtin_proc func;
pr_int_t numparams;
pr_ulong_t profile;
union {
struct {
dparmsize_t param_size[PR_MAX_PARAMS];
dfunction_t *descriptor;
pr_uint_t params_start;
pr_uint_t locals;
};
struct {
// although Ruamoko progs support more than PR_MAX_PARAMS
// arguments, only the first PR_MAX_PARAMS parameter pointers
// are initialized. This keeps builtins meant for both ISAs
// simple as they either will never accept more tha PR_MAX_PARAMS
// arugments, or they'll be modified to do the right thing.
pr_ushort_t param_offsets[PR_MAX_PARAMS];
builtin_proc func;
void *data; ///< extra data passed to the builtin
};
};
} bfunction_t;
/** Register a set of builtin functions with the VM. Different VMs within the
@ -1208,8 +1281,10 @@ typedef struct {
for the same VM, but redefining a builtin is an error.
\param pr pointer to ::progs_t VM struct
\param builtins array of builtin_t builtins
\param data pointer to builtin-specific data. Usually the resources
struct registered with PR_Resources_Register
*/
void PR_RegisterBuiltins (progs_t *pr, builtin_t *builtins);
void PR_RegisterBuiltins (progs_t *pr, builtin_t *builtins, void *data);
/** Lookup a builtin function referred by name.
\param pr pointer to ::progs_t VM struct
@ -1280,28 +1355,28 @@ int PR_LoadStrings (progs_t *pr);
\param num string index to be validated
\return true if the index is valid, false otherwise
*/
qboolean PR_StringValid (progs_t *pr, string_t num) __attribute__((pure));
qboolean PR_StringValid (progs_t *pr, pr_string_t num) __attribute__((pure));
/** Check if a string is valid and mutable.
\param pr pointer to ::progs_t VM struct
\param num string index to be checked
\return true if the string is valid and mutable, false otherwise
*/
qboolean PR_StringMutable (progs_t *pr, string_t num) __attribute__((pure));
qboolean PR_StringMutable (progs_t *pr, pr_string_t num) __attribute__((pure));
/** Convert a string index to a C string.
\param pr pointer to ::progs_t VM struct
\param num string index to be converted
\return C pointer to the string.
*/
const char *PR_GetString(progs_t *pr, string_t num) __attribute__((pure));
const char *PR_GetString(progs_t *pr, pr_string_t num) __attribute__((pure));
/** Retrieve the dstring_t associated with a mutable string.
\param pr pointer to ::progs_t VM struct
\param num string index of the mutable string
\return the dstring implementing the mutable string
*/
struct dstring_s *PR_GetMutableString(progs_t *pr, string_t num) __attribute__((pure));
struct dstring_s *PR_GetMutableString(progs_t *pr, pr_string_t num) __attribute__((pure));
/** Make a permanent progs string from the given C string. Will not create a
duplicate permanent string (temporary and mutable strings are not checked).
@ -1309,7 +1384,7 @@ struct dstring_s *PR_GetMutableString(progs_t *pr, string_t num) __attribute__((
\param s C string to be made into a permanent progs string
\return string index of the progs string
*/
string_t PR_SetString(progs_t *pr, const char *s);
pr_string_t PR_SetString(progs_t *pr, const char *s);
/** Get the progs string if it exists.
Only static strings are searched.
@ -1318,7 +1393,7 @@ string_t PR_SetString(progs_t *pr, const char *s);
\return string index of the progs string if it exists, otherwise
0 (ambiguous with "").
*/
string_t PR_FindString(progs_t *pr, const char *s);
pr_string_t PR_FindString(progs_t *pr, const char *s);
/** Make a temporary progs string that will survive across function returns.
Will not duplicate a permanent string. If a new progs string is created,
@ -1328,7 +1403,7 @@ string_t PR_FindString(progs_t *pr, const char *s);
\param s C string to be returned to the progs code
\return string index of the progs string
*/
string_t PR_SetReturnString(progs_t *pr, const char *s);
pr_string_t PR_SetReturnString(progs_t *pr, const char *s);
/** Make a temporary progs string that will be freed when the current progs
stack frame is exited. Will not duplicate a permantent string.
@ -1336,7 +1411,7 @@ string_t PR_SetReturnString(progs_t *pr, const char *s);
\param s C string
\return string index of the progs string
*/
string_t PR_SetTempString(progs_t *pr, const char *s);
pr_string_t PR_SetTempString(progs_t *pr, const char *s);
/** Make a temporary memory block that will be freed when the current progs
stack frame is exited. The contents may be anything and a new block is
@ -1348,7 +1423,7 @@ string_t PR_SetTempString(progs_t *pr, const char *s);
\param size size of block in bytes
\return string index of the block
*/
string_t PR_AllocTempBlock (progs_t *pr, size_t size);
pr_string_t PR_AllocTempBlock (progs_t *pr, size_t size);
/** Push a temporary string to the callee stack frame
@ -1359,7 +1434,7 @@ string_t PR_AllocTempBlock (progs_t *pr, size_t size);
\param pr pointer to ::progs_t VM struct
\param num string index of the temp string
*/
void PR_PushTempString (progs_t *pr, string_t num);
void PR_PushTempString (progs_t *pr, pr_string_t num);
/** Make a temporary progs string that is the concatenation of two C strings.
\param pr pointer to ::progs_t VM struct
@ -1368,19 +1443,19 @@ void PR_PushTempString (progs_t *pr, string_t num);
\return string index of the progs string that represents the
concatenation of strings a and b
*/
string_t PR_CatStrings (progs_t *pr, const char *a, const char *b);
pr_string_t PR_CatStrings (progs_t *pr, const char *a, const char *b);
/** Convert a mutable string to a temporary string.
\param pr pointer to ::progs_t VM struct
\param str string index of the mutable string to be converted
*/
void PR_MakeTempString(progs_t *pr, string_t str);
void PR_MakeTempString(progs_t *pr, pr_string_t str);
/** Create a new mutable string.
\param pr pointer to ::progs_t VM struct
\return string index of the newly created mutable string
*/
string_t PR_NewMutableString (progs_t *pr);
pr_string_t PR_NewMutableString (progs_t *pr);
/** Make a dynamic progs string from the given C string. Will not create a
duplicate permanent string (temporary, dynamic and mutable strings are
@ -1389,7 +1464,7 @@ string_t PR_NewMutableString (progs_t *pr);
\param s C string to be made into a permanent progs string
\return string index of the progs string
*/
string_t PR_SetDynamicString (progs_t *pr, const char *s);
pr_string_t PR_SetDynamicString (progs_t *pr, const char *s);
/** Convert an ephemeral string to a dynamic string.
@ -1401,13 +1476,13 @@ string_t PR_SetDynamicString (progs_t *pr, const char *s);
\param str The string to be "held" (made non-ephemeral). Safe to call
on any valid string, but affects only ephemeral strings.
*/
void PR_HoldString (progs_t *pr, string_t str);
void PR_HoldString (progs_t *pr, pr_string_t str);
/** Destroy a mutable, dynamic or temporary string.
\param pr pointer to ::progs_t VM struct
\param str string index of the string to be destroyed
*/
void PR_FreeString (progs_t *pr, string_t str);
void PR_FreeString (progs_t *pr, pr_string_t str);
/** Free all the temporary strings allocated in the current stack frame.
\param pr pointer to ::progs_t VM struct
@ -1450,14 +1525,14 @@ void PR_FreeTempStrings (progs_t *pr);
<ul>
<li>\c '@' \c id Not yet implemented. Silently ignored.
<li>\c 'e' \c entity Prints the edict number of the given entity ("%i")
<li>\c 'i' \c integer Print a integer value. ("%i")
<li>\c 'i' \c int Print a int value. ("%i")
<li>\c 'f' \c float Print a float value. ("%f")
<li>\c 'g' \c float Print a float value. ("%f")
<li>\c 'p' \c void * Print a pointer value. ("%#x")
<li>\c 's' \c string Print a string value. ("%s")
<li>\c 'v' \c vector Print a vector value. ("'%g %g %g'")
<li>\c 'q' \c quaternion Print a quaternion value. ("'%g %g %g %g'")
<li>\c 'x' \c uinteger Print an unsigned integer value. ("%x")
<li>\c 'x' \c uint Print an unsigned int value. ("%x")
</ul>
</ul>
@ -1501,7 +1576,6 @@ void PR_Resources_Clear (progs_t *pr);
\param name The name of the resource. Used for retrieving the
resource.
\param data The resource data.
callback.
\param clear Callback for performing any necessary cleanup. Called
by PR_Resources_Clear(). The parameters are the current
VM (\p pr) and \p data.
@ -1526,7 +1600,7 @@ void *PR_Resources_Find (progs_t *pr, const char *name);
/** \name Resource Map support
These macros can be used to create functions for mapping C resources
to QuakeC integer handles.
to QuakeC int handles.
Valid handles are always negative.
@ -1720,25 +1794,13 @@ typedef void (*type_view_func) (struct qfot_type_s *type, pr_type_t *value,
the entire contents of the data.
*/
typedef struct type_view_s {
type_view_func void_view;
type_view_func string_view;
type_view_func float_view;
type_view_func vector_view;
type_view_func entity_view;
type_view_func field_view;
type_view_func func_view;
type_view_func pointer_view;
type_view_func quat_view;
type_view_func integer_view;
type_view_func uinteger_view;
type_view_func short_view;
type_view_func double_view;
type_view_func struct_view;
type_view_func union_view;
type_view_func enum_view;
type_view_func array_view;
type_view_func class_view;
#define EV_TYPE(type) type_view_func type##_view;
#include "QF/progs/pr_type_names.h"
} type_view_t;
void PR_Debug_Init (progs_t *pr);
@ -1761,7 +1823,7 @@ pr_uint_t PR_FindSourceLineAddr (progs_t *pr, const char *file, pr_uint_t line)
const char *PR_Get_Source_File (progs_t *pr, pr_lineno_t *lineno) __attribute__((pure));
const char *PR_Get_Source_Line (progs_t *pr, pr_uint_t addr);
pr_def_t *PR_Get_Param_Def (progs_t *pr, dfunction_t *func, unsigned parm) __attribute__((pure));
pr_def_t *PR_Get_Local_Def (progs_t *pr, pointer_t *offs) __attribute__((pure));
pr_def_t *PR_Get_Local_Def (progs_t *pr, pr_ptr_t *offs) __attribute__((pure));
void PR_PrintStatement (progs_t *pr, dstatement_t *s, int contents);
void PR_DumpState (progs_t *pr);
void PR_StackTrace (progs_t *pr);
@ -1781,7 +1843,7 @@ extern struct cvar_s *pr_faultchecks;
*/
///@{
char *PF_VarString (progs_t *pr, int first);
char *PF_VarString (progs_t *pr, int first, int count);
void PR_Cmds_Init (progs_t *pr);
extern const char *pr_gametype;
@ -1790,16 +1852,21 @@ extern const char *pr_gametype;
//============================================================================
#define MAX_STACK_DEPTH 64
#define LOCALSTACK_SIZE 4096
#define PR_MAX_STACK_DEPTH 64
#define PR_LOCAL_STACK_SIZE 4096
#define PR_RS_SLOTS 16
#define PR_BASE_IND(o, b) (((o) & OP_##b##_BASE) >> OP_##b##_SHIFT)
#define PR_BASE(p, s, b) (p->pr_bases[PR_BASE_IND(s->op, b)])
typedef struct strref_s strref_t;
typedef struct {
pr_int_t staddr; ///< Return statement.
pr_uivec4_t bases; ///< base registers on entry to function
pr_uint_t staddr; ///< Return statement.
pr_uint_t stack_ptr; ///< data stack on entry to function
bfunction_t *func; ///< Calling function.
strref_t *tstr; ///< Linked list of temporary strings.
pr_type_t *return_ptr; ///< Saved return address
} prstack_t;
struct progs_s {
@ -1843,6 +1910,12 @@ struct progs_s {
struct hashtab_s *field_hash;
///@}
/// \name type encodings
///@{
struct hashtab_s *type_hash;
pr_ptr_t type_encodings;
///@}
/// \name load hooks
///@{
int num_load_funcs;
@ -1875,33 +1948,37 @@ struct progs_s {
pr_def_t *pr_fielddefs;
dstatement_t *pr_statements;
pr_type_t *pr_globals;
unsigned globals_size;
pr_uint_t globals_size;
pr_uint_t null_size; ///< size of block considered null page
pr_uivec4_t pr_bases; ///< base registers (index in opcode)
///@}
/// \name parameter block
///@{
pr_type_t *pr_return;
pr_type_t *pr_params[MAX_PARMS];
pr_type_t *pr_real_params[MAX_PARMS];
pr_type_t *pr_params[PR_MAX_PARAMS];
pr_type_t *pr_real_params[PR_MAX_PARAMS];
int pr_param_size; ///< covers both params and return
int pr_param_alignment; ///< covers both params and return
pr_type_t *pr_return_buffer; ///< for discarded return values
///< or returning values to C
///@}
/// \name edicts
/// \todo FIXME should this be outside the VM?
///@{
edict_t **pr_edicts;
int max_edicts; ///< set by user
int *num_edicts;
int *reserved_edicts; ///< alloc will start at reserved_edicts+1
pr_uint_t max_edicts; ///< set by user
pr_uint_t *num_edicts;
pr_uint_t *reserved_edicts; ///< alloc will start at reserved_edicts+1
void (*unlink) (edict_t *ent);
void (*flush) (void);
int (*prune_edict) (progs_t *pr, edict_t *ent);
void (*free_edict) (progs_t *pr, edict_t *ent);
pr_type_t *pr_edict_area;
int pr_edict_size; ///< # of pr_type_t slots
int pr_edict_area_size; ///< for bounds checking, starts at 0
func_t edict_parse;
pr_uint_t pr_edict_area_size; ///< for bounds checking, starts at 0
pr_func_t edict_parse;
///@}
/// \name execution state
@ -1913,7 +1990,7 @@ struct progs_s {
bfunction_t *pr_xfunction;
int pr_xstatement;
prstack_t pr_stack[MAX_STACK_DEPTH];
prstack_t pr_stack[PR_MAX_STACK_DEPTH];
int pr_depth;
/// \name progs visible stack
@ -1925,11 +2002,11 @@ struct progs_s {
/// stack.
///@{
pr_type_t *stack;
pointer_t stack_bottom;
pr_ptr_t stack_bottom;
int stack_size; ///< set by user
///@}
int localstack[LOCALSTACK_SIZE];
int localstack[PR_LOCAL_STACK_SIZE];
int localstack_used;
///@}
@ -1957,9 +2034,10 @@ struct progs_s {
/// \name globals and fields needed by the VM
///@{
struct {
float *time; ///< required for OP_STATE
pr_int_t *self; ///< required for OP_STATE
pointer_t *stack; ///< required for OP_(PUSH|POP)*
double *dtime; ///< required for OP_STATE d
float *ftime; ///< required for OP_STATE f
pr_uint_t *self; ///< required for OP_STATE
pr_ptr_t *stack; ///< required for OP_(PUSH|POP)*
} globals;
struct {
pr_int_t nextthink; ///< required for OP_STATE
@ -1980,7 +2058,7 @@ struct progs_s {
\return C pointer represented by the parameter. 0 offset -> NULL
*/
static inline pr_type_t *
PR_GetPointer (const progs_t *pr, pointer_t o)
PR_GetPointer (const progs_t *pr, pr_ptr_t o)
{
return o ? pr->pr_globals + o : 0;
}
@ -1990,7 +2068,7 @@ PR_GetPointer (const progs_t *pr, pointer_t o)
\param p C pointer to be converted.
\return Progs offset/pointer represented by \c p. NULL -> 0 offset
*/
static inline pointer_t
static inline pr_ptr_t
PR_SetPointer (const progs_t *pr, const void *p)
{
return p ? (const pr_type_t *) p - pr->pr_globals : 0;

587
include/QF/progs/pr_comp.h Normal file
View file

@ -0,0 +1,587 @@
/* Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
See file, 'COPYING', for details.
*/
// this file is shared by QuakeForge and qfcc
#ifndef __QF_pr_comp_h
#define __QF_pr_comp_h
#include "QF/qtypes.h"
typedef int32_t pr_string_t __attribute__((aligned(4)));
typedef float pr_float_t __attribute__((aligned(4)));
typedef float pr_vector_t[3] __attribute__((aligned(4)));
typedef uint32_t pr_entity_t __attribute__((aligned(4)));
typedef uint32_t pr_field_t __attribute__((aligned(4)));
typedef uint32_t pr_func_t __attribute__((aligned(4)));
typedef uint32_t pr_ptr_t __attribute__((aligned(4)));
typedef float pr_quaternion_t[4] __attribute__((aligned(4)));
typedef int32_t pr_int_t __attribute__((aligned(4)));
typedef uint32_t pr_uint_t __attribute__((aligned(4)));
typedef int16_t pr_short_t __attribute__((aligned(2)));
typedef double pr_double_t __attribute__((aligned(8)));
typedef int64_t pr_long_t __attribute__((aligned(8)));
typedef uint64_t pr_ulong_t __attribute__((aligned(8)));
typedef uint16_t pr_ushort_t __attribute__((aligned(2)));;
#define PR_VEC_TYPE(t,n,s) \
typedef t n __attribute__ ((vector_size (s*sizeof (t))))
PR_VEC_TYPE (pr_int_t, pr_ivec2_t, 2);
typedef pr_int_t pr_ivec3_t[3];
PR_VEC_TYPE (pr_int_t, pr_ivec4_t, 4);
PR_VEC_TYPE (pr_uint_t, pr_uivec2_t, 2);
typedef pr_uint_t pr_uivec3_t[3];
PR_VEC_TYPE (pr_uint_t, pr_uivec4_t, 4);
PR_VEC_TYPE (float, pr_vec2_t, 2);
typedef pr_float_t pr_vec3_t[3];
PR_VEC_TYPE (float, pr_vec4_t, 4);
PR_VEC_TYPE (pr_long_t, pr_lvec2_t, 2);
typedef pr_long_t pr_lvec3_t[3];
PR_VEC_TYPE (pr_long_t, pr_lvec4_t, 4);
PR_VEC_TYPE (pr_ulong_t, pr_ulvec2_t, 2);
typedef pr_ulong_t pr_ulvec3_t[3];
PR_VEC_TYPE (pr_ulong_t, pr_ulvec4_t, 4);
PR_VEC_TYPE (double, pr_dvec2_t, 2);
typedef pr_double_t pr_dvec3_t[3];
PR_VEC_TYPE (double, pr_dvec4_t, 4);
#define EV_TYPE(type) ev_##type,
typedef enum {
#include "QF/progs/pr_type_names.h"
ev_invalid, // invalid type. used for instruction checking
ev_type_count // not a type, gives number of types
} etype_t;
#define PR_SIZEOF(type) (sizeof (pr_##type##_t) / (sizeof (pr_int_t)))
#define PR_ALIGNOF(type) (__alignof__ (pr_##type##_t) / __alignof__ (pr_int_t))
extern const pr_ushort_t pr_type_size[ev_type_count];
extern const pr_ushort_t pr_type_alignment[ev_type_count];
extern const char * const pr_type_name[ev_type_count];
#define OFS_NULL 0
#define OFS_RETURN 1
#define OFS_PARM0 4 // leave 3 ofs for each parm to hold vectors
#define OFS_PARM1 7
#define OFS_PARM2 10
#define OFS_PARM3 13
#define OFS_PARM4 16
#define OFS_PARM5 19
#define OFS_PARM6 22
#define OFS_PARM7 25
#define RESERVED_OFS 28
typedef enum {
OP_DONE_v6p,
OP_MUL_F_v6p,
OP_MUL_V_v6p,
OP_MUL_FV_v6p,
OP_MUL_VF_v6p,
OP_DIV_F_v6p,
OP_ADD_F_v6p,
OP_ADD_V_v6p,
OP_SUB_F_v6p,
OP_SUB_V_v6p,
OP_EQ_F_v6p,
OP_EQ_V_v6p,
OP_EQ_S_v6p,
OP_EQ_E_v6p,
OP_EQ_FN_v6p,
OP_NE_F_v6p,
OP_NE_V_v6p,
OP_NE_S_v6p,
OP_NE_E_v6p,
OP_NE_FN_v6p,
OP_LE_F_v6p,
OP_GE_F_v6p,
OP_LT_F_v6p,
OP_GT_F_v6p,
OP_LOAD_F_v6p,
OP_LOAD_V_v6p,
OP_LOAD_S_v6p,
OP_LOAD_ENT_v6p,
OP_LOAD_FLD_v6p,
OP_LOAD_FN_v6p,
OP_ADDRESS_v6p,
OP_STORE_F_v6p,
OP_STORE_V_v6p,
OP_STORE_S_v6p,
OP_STORE_ENT_v6p,
OP_STORE_FLD_v6p,
OP_STORE_FN_v6p,
OP_STOREP_F_v6p,
OP_STOREP_V_v6p,
OP_STOREP_S_v6p,
OP_STOREP_ENT_v6p,
OP_STOREP_FLD_v6p,
OP_STOREP_FN_v6p,
OP_RETURN_v6p,
OP_NOT_F_v6p,
OP_NOT_V_v6p,
OP_NOT_S_v6p,
OP_NOT_ENT_v6p,
OP_NOT_FN_v6p,
OP_IF_v6p,
OP_IFNOT_v6p,
OP_CALL0_v6p,
OP_CALL1_v6p,
OP_CALL2_v6p,
OP_CALL3_v6p,
OP_CALL4_v6p,
OP_CALL5_v6p,
OP_CALL6_v6p,
OP_CALL7_v6p,
OP_CALL8_v6p,
OP_STATE_v6p,
OP_GOTO_v6p,
OP_AND_v6p,
OP_OR_v6p,
OP_BITAND_v6p,
OP_BITOR_v6p, // end of v6 opcodes
OP_ADD_S_v6p,
OP_LE_S_v6p,
OP_GE_S_v6p,
OP_LT_S_v6p,
OP_GT_S_v6p,
OP_ADD_I_v6p,
OP_SUB_I_v6p,
OP_MUL_I_v6p,
OP_DIV_I_v6p,
OP_BITAND_I_v6p,
OP_BITOR_I_v6p,
OP_GE_I_v6p,
OP_LE_I_v6p,
OP_GT_I_v6p,
OP_LT_I_v6p,
OP_AND_I_v6p,
OP_OR_I_v6p,
OP_NOT_I_v6p,
OP_EQ_I_v6p,
OP_NE_I_v6p,
OP_STORE_I_v6p,
OP_STOREP_I_v6p,
OP_LOAD_I_v6p,
OP_CONV_IF_v6p,
OP_CONV_FI_v6p,
OP_BITXOR_F_v6p,
OP_BITXOR_I_v6p,
OP_BITNOT_F_v6p,
OP_BITNOT_I_v6p,
OP_SHL_F_v6p,
OP_SHR_F_v6p,
OP_SHL_I_v6p,
OP_SHR_I_v6p,
OP_REM_F_v6p,
OP_REM_I_v6p,
OP_LOADB_F_v6p,
OP_LOADB_V_v6p,
OP_LOADB_S_v6p,
OP_LOADB_ENT_v6p,
OP_LOADB_FLD_v6p,
OP_LOADB_FN_v6p,
OP_LOADB_I_v6p,
OP_LOADB_P_v6p,
OP_STOREB_F_v6p,
OP_STOREB_V_v6p,
OP_STOREB_S_v6p,
OP_STOREB_ENT_v6p,
OP_STOREB_FLD_v6p,
OP_STOREB_FN_v6p,
OP_STOREB_I_v6p,
OP_STOREB_P_v6p,
OP_ADDRESS_VOID_v6p,
OP_ADDRESS_F_v6p,
OP_ADDRESS_V_v6p,
OP_ADDRESS_S_v6p,
OP_ADDRESS_ENT_v6p,
OP_ADDRESS_FLD_v6p,
OP_ADDRESS_FN_v6p,
OP_ADDRESS_I_v6p,
OP_ADDRESS_P_v6p,
OP_LEA_v6p,
OP_IFBE_v6p,
OP_IFB_v6p,
OP_IFAE_v6p,
OP_IFA_v6p,
OP_JUMP_v6p,
OP_JUMPB_v6p,
OP_LT_U_v6p,
OP_GT_U_v6p,
OP_LE_U_v6p,
OP_GE_U_v6p,
OP_LOADBI_F_v6p,
OP_LOADBI_V_v6p,
OP_LOADBI_S_v6p,
OP_LOADBI_ENT_v6p,
OP_LOADBI_FLD_v6p,
OP_LOADBI_FN_v6p,
OP_LOADBI_I_v6p,
OP_LOADBI_P_v6p,
OP_STOREBI_F_v6p,
OP_STOREBI_V_v6p,
OP_STOREBI_S_v6p,
OP_STOREBI_ENT_v6p,
OP_STOREBI_FLD_v6p,
OP_STOREBI_FN_v6p,
OP_STOREBI_I_v6p,
OP_STOREBI_P_v6p,
OP_LEAI_v6p,
OP_LOAD_P_v6p,
OP_STORE_P_v6p,
OP_STOREP_P_v6p,
OP_NOT_P_v6p,
OP_EQ_P_v6p,
OP_NE_P_v6p,
OP_LE_P_v6p,
OP_GE_P_v6p,
OP_LT_P_v6p,
OP_GT_P_v6p,
OP_MOVEI_v6p,
OP_MOVEP_v6p,
OP_MOVEPI_v6p,
OP_SHR_U_v6p,
OP_STATE_F_v6p,
OP_ADD_Q_v6p,
OP_SUB_Q_v6p,
OP_MUL_Q_v6p,
OP_MUL_QF_v6p,
OP_MUL_FQ_v6p,
OP_MUL_QV_v6p,
OP_CONJ_Q_v6p,
OP_NOT_Q_v6p,
OP_EQ_Q_v6p,
OP_NE_Q_v6p,
OP_STORE_Q_v6p,
OP_STOREB_Q_v6p,
OP_STOREBI_Q_v6p,
OP_STOREP_Q_v6p,
OP_LOAD_Q_v6p,
OP_LOADB_Q_v6p,
OP_LOADBI_Q_v6p,
OP_ADDRESS_Q_v6p,
OP_RCALL0_v6p,
OP_RCALL1_v6p,
OP_RCALL2_v6p,
OP_RCALL3_v6p,
OP_RCALL4_v6p,
OP_RCALL5_v6p,
OP_RCALL6_v6p,
OP_RCALL7_v6p,
OP_RCALL8_v6p,
OP_RETURN_V_v6p,
OP_PUSH_S_v6p,
OP_PUSH_F_v6p,
OP_PUSH_V_v6p,
OP_PUSH_ENT_v6p,
OP_PUSH_FLD_v6p,
OP_PUSH_FN_v6p,
OP_PUSH_P_v6p,
OP_PUSH_Q_v6p,
OP_PUSH_I_v6p,
OP_PUSH_D_v6p,
OP_PUSHB_S_v6p,
OP_PUSHB_F_v6p,
OP_PUSHB_V_v6p,
OP_PUSHB_ENT_v6p,
OP_PUSHB_FLD_v6p,
OP_PUSHB_FN_v6p,
OP_PUSHB_P_v6p,
OP_PUSHB_Q_v6p,
OP_PUSHB_I_v6p,
OP_PUSHB_D_v6p,
OP_PUSHBI_S_v6p,
OP_PUSHBI_F_v6p,
OP_PUSHBI_V_v6p,
OP_PUSHBI_ENT_v6p,
OP_PUSHBI_FLD_v6p,
OP_PUSHBI_FN_v6p,
OP_PUSHBI_P_v6p,
OP_PUSHBI_Q_v6p,
OP_PUSHBI_I_v6p,
OP_PUSHBI_D_v6p,
OP_POP_S_v6p,
OP_POP_F_v6p,
OP_POP_V_v6p,
OP_POP_ENT_v6p,
OP_POP_FLD_v6p,
OP_POP_FN_v6p,
OP_POP_P_v6p,
OP_POP_Q_v6p,
OP_POP_I_v6p,
OP_POP_D_v6p,
OP_POPB_S_v6p,
OP_POPB_F_v6p,
OP_POPB_V_v6p,
OP_POPB_ENT_v6p,
OP_POPB_FLD_v6p,
OP_POPB_FN_v6p,
OP_POPB_P_v6p,
OP_POPB_Q_v6p,
OP_POPB_I_v6p,
OP_POPB_D_v6p,
OP_POPBI_S_v6p,
OP_POPBI_F_v6p,
OP_POPBI_V_v6p,
OP_POPBI_ENT_v6p,
OP_POPBI_FLD_v6p,
OP_POPBI_FN_v6p,
OP_POPBI_P_v6p,
OP_POPBI_Q_v6p,
OP_POPBI_I_v6p,
OP_POPBI_D_v6p,
OP_ADD_D_v6p,
OP_SUB_D_v6p,
OP_MUL_D_v6p,
OP_MUL_QD_v6p,
OP_MUL_DQ_v6p,
OP_MUL_VD_v6p,
OP_MUL_DV_v6p,
OP_DIV_D_v6p,
OP_REM_D_v6p,
OP_GE_D_v6p,
OP_LE_D_v6p,
OP_GT_D_v6p,
OP_LT_D_v6p,
OP_NOT_D_v6p,
OP_EQ_D_v6p,
OP_NE_D_v6p,
OP_CONV_FD_v6p,
OP_CONV_DF_v6p,
OP_CONV_ID_v6p,
OP_CONV_DI_v6p,
OP_STORE_D_v6p,
OP_STOREB_D_v6p,
OP_STOREBI_D_v6p,
OP_STOREP_D_v6p,
OP_LOAD_D_v6p,
OP_LOADB_D_v6p,
OP_LOADBI_D_v6p,
OP_ADDRESS_D_v6p,
OP_MOD_I_v6p,
OP_MOD_F_v6p,
OP_MOD_D_v6p,
OP_MEMSETI_v6p,
OP_MEMSETP_v6p,
OP_MEMSETPI_v6p,
} pr_opcode_v6p_e;
#define OP_BREAK 0x8000
typedef enum {
#include "QF/progs/pr_opcode.hinc"
} pr_opcode_e;
// Used for both branch and comparison, with jump and call being ignored for
// comparison. For branches, the test is against zero, while for comparison,
// it's a cmp b (where cmp takes the place of "branch" in the enum names).
typedef enum {
pr_branch_eq,
pr_branch_lt,
pr_branch_gt,
pr_branch_jump,
pr_branch_ne,
pr_branch_ge,
pr_branch_le,
pr_branch_call,
} pr_branch_e;
#define OP_A_SHIFT (9)
#define OP_B_SHIFT (11)
#define OP_C_SHIFT (13)
#define OP_A_BASE (3 << OP_A_SHIFT)
#define OP_B_BASE (3 << OP_B_SHIFT)
#define OP_C_BASE (3 << OP_C_SHIFT)
#define OP_MASK (~(OP_BREAK|OP_A_BASE|OP_B_BASE|OP_C_BASE))
typedef enum {
OP_with_zero,
OP_with_base,
OP_with_stack,
OP_with_entity,
} pr_with_e;
typedef struct v6p_opcode_s {
const char *name;
const char *opname;
etype_t type_a, type_b, type_c;
unsigned int min_version;
const char *fmt;
} v6p_opcode_t;
extern const v6p_opcode_t pr_v6p_opcodes[];
const v6p_opcode_t *PR_v6p_Opcode (pr_ushort_t opcode) __attribute__((const));
typedef struct opcode_s {
const char *opname;
const char *mnemonic;
int widths[3]; ///< component count for each argument (1-4)
etype_t types[3]; ///< component type for each argument
const char *fmt;
} opcode_t;
extern const opcode_t pr_opcodes[512];
const opcode_t *PR_Opcode (pr_ushort_t opcode) __attribute__((const));
typedef struct dstatement_s {
pr_opcode_e op:16; // will be pr_opcode_v6p_e for older progs
pr_ushort_t a,b,c;
} GCC_STRUCT dstatement_t;
typedef struct ddef_s {
pr_ushort_t type; // if DEF_SAVEGLOBAL bit is set
// the variable needs to be saved in savegames
pr_ushort_t ofs;
pr_string_t name;
} ddef_t;
typedef struct xdef_s {
pr_ptr_t type; ///< pointer to type definition
pr_ptr_t ofs; ///< 32-bit version of ddef_t.ofs
} xdef_t;
typedef struct pr_xdefs_s {
pr_ptr_t xdefs;
pr_int_t num_xdefs;
} pr_xdefs_t;
typedef struct pr_def_s {
pr_ushort_t type;
pr_ushort_t size; ///< may not be correct
pr_ptr_t ofs;
pr_string_t name;
pr_ptr_t type_encoding;
} pr_def_t;
typedef struct dparmsize_s {
uint8_t size:5;
uint8_t alignment:3;
} dparmsize_t;
#define DEF_SAVEGLOBAL (1<<15)
#define PR_MAX_PARAMS 8
#define PR_MAX_RETURN 32 // maximum size of return value
typedef struct dfunction_s {
pr_int_t first_statement; // negative numbers are builtins
pr_uint_t params_start; // beginning of locals data space
pr_uint_t locals; // total ints of params + locals
pr_uint_t profile; // runtime
pr_string_t name; // source function name
pr_string_t file; // source file defined in
pr_int_t numparams; // -ve is varargs (1s comp of real count)
dparmsize_t param_size[PR_MAX_PARAMS];
} dfunction_t;
typedef union pr_type_u {
float float_var;
pr_string_t string_var;
pr_func_t func_var;
pr_uint_t entity_var;
float vector_var; // really [3], but this structure must be 32 bits
float quat_var; // really [4], but this structure must be 32 bits
pr_int_t int_var;
pr_ptr_t pointer_var;
pr_uint_t uint_var;
} pr_type_t;
typedef pr_type_t pr_void_t; // so size of void is 1
typedef struct pr_va_list_s {
pr_int_t count;
pr_ptr_t list; // pr_type_t
} pr_va_list_t;
#define PROG_VERSION_ENCODE(a,b,c) \
( (((0x##a) & 0x0ff) << 24) \
|(((0x##b) & 0xfff) << 12) \
|(((0x##c) & 0xfff) << 0) )
#define PROG_ID_VERSION 6
#define PROG_V6P_VERSION PROG_VERSION_ENCODE(0,fff,00a)
#define PROG_VERSION PROG_VERSION_ENCODE(0,fff,010)
typedef struct pr_chunk_s {
pr_uint_t offset;
pr_uint_t count;
} pr_chunk_t;
typedef struct dprograms_s {
pr_uint_t version;
pr_uint_t crc; // checksum of header file
pr_chunk_t statements; // statement 0 is an error
pr_chunk_t globaldefs;
pr_chunk_t fielddefs;
pr_chunk_t functions; // function 0 is an empty
pr_chunk_t strings; // first string is a null string, count is bytes
pr_chunk_t globals;
pr_uint_t entityfields;
} dprograms_t;
#endif//__QF_pr_comp_h

View file

@ -32,7 +32,7 @@
#define __QF_pr_debug_h
#ifndef __QFCC__
#include "QF/pr_comp.h"
#include "QF/progs/pr_comp.h"
typedef struct pr_compunit_s {
pr_uint_t unit_name;
@ -75,6 +75,8 @@ typedef struct pr_debug_header_s {
pr_uint_t debug_data;
pr_uint_t debug_data_size;
} pr_debug_header_t;
extern const char *prdebug_names[];
#endif
typedef enum prdebug_e {

View file

@ -31,7 +31,7 @@
#ifndef __QF_pr_obj_h
#define __QF_pr_obj_h
#include "QF/pr_comp.h"
#include "QF/progs/pr_comp.h"
#define PR_BITS_PER_INT (sizeof (pr_int_t) * 8)
@ -74,62 +74,62 @@
#define PR_CLS_GETNUMBER(cls) (__CLS_INFO (cls) >> (PR_BITS_PER_INT / 2))
#define PR_CLS_SETNUMBER(cls, num) \
(__PR_CLS_INFO (cls) = __PR_CLS_INFO (cls) & (~0U >> (PR_BITS_PER_INT / 2)) \
| (num) << (PR_BITS_PER_INT / 2))
| (num) << (PR_BITS_PER_INT / 2))
typedef struct pr_sel_s {
pointer_t sel_id;
string_t sel_types;
pr_ptr_t sel_id;
pr_string_t sel_types;
} pr_sel_t;
typedef struct pr_id_s {
pointer_t class_pointer; // pr_class_t
pr_ptr_t class_pointer; // pr_class_t
} pr_id_t;
typedef struct pr_class_s {
pointer_t class_pointer; // pr_class_t
pointer_t super_class; // pr_class_t
string_t name;
pr_ptr_t class_pointer; // pr_class_t
pr_ptr_t super_class; // pr_class_t
pr_string_t name;
pr_int_t version;
pr_uint_t info;
pr_int_t instance_size;
pointer_t ivars; // pr_ivar_list_t
pointer_t methods; // pr_method_list_t
pointer_t dtable; // resource index
pointer_t subclass_list; // pr_class_t
pointer_t sibling_class; // pr_class_t
pointer_t protocols; // pr_protocol_list_t
pointer_t gc_object_type;
pr_ptr_t ivars; // pr_ivar_list_t
pr_ptr_t methods; // pr_method_list_t
pr_ptr_t dtable; // resource index
pr_ptr_t subclass_list; // pr_class_t
pr_ptr_t sibling_class; // pr_class_t
pr_ptr_t protocols; // pr_protocol_list_t
pr_ptr_t gc_object_type;
} pr_class_t;
typedef struct pr_protocol_s {
pointer_t class_pointer; // pr_class_t
string_t protocol_name;
pointer_t protocol_list; // pr_protocol_list_t
pointer_t instance_methods; // pr_method_description_list_t
pointer_t class_methods; // pr_method_description_list_t
pr_ptr_t class_pointer; // pr_class_t
pr_string_t protocol_name;
pr_ptr_t protocol_list; // pr_protocol_list_t
pr_ptr_t instance_methods; // pr_method_description_list_t
pr_ptr_t class_methods; // pr_method_description_list_t
} pr_protocol_t;
typedef struct pr_category_s {
string_t category_name;
string_t class_name;
pointer_t instance_methods; // pr_method_list_t
pointer_t class_methods; // pr_method_list_t
pointer_t protocols; // pr_protocol_list_t
pr_string_t category_name;
pr_string_t class_name;
pr_ptr_t instance_methods; // pr_method_list_t
pr_ptr_t class_methods; // pr_method_list_t
pr_ptr_t protocols; // pr_protocol_list_t
} pr_category_t;
typedef struct pr_protocol_list_s {
pointer_t next;
pr_ptr_t next;
pr_int_t count;
pointer_t list[1]; // pr_protocol_t
pr_ptr_t list[1]; // pr_protocol_t
} pr_protocol_list_t;
typedef struct pr_method_list_s {
pointer_t method_next;
pr_ptr_t method_next;
pr_int_t method_count;
struct pr_method_s {
pointer_t method_name; // pr_sel_t
string_t method_types;
func_t method_imp; // typedef id (id, SEL, ...) IMP
pr_ptr_t method_name; // pr_sel_t
pr_string_t method_types;
pr_func_t method_imp; // typedef id (id, SEL, ...) IMP
} method_list[1];
} pr_method_list_t;
typedef struct pr_method_s pr_method_t;
@ -137,8 +137,8 @@ typedef struct pr_method_s pr_method_t;
typedef struct pr_method_description_list_s {
pr_int_t count;
struct pr_method_description_s {
pointer_t name; // pr_sel_t
string_t types;
pr_ptr_t name; // pr_sel_t
pr_string_t types;
} list[1];
} pr_method_description_list_t;
typedef struct pr_method_description_s pr_method_description_t;
@ -146,8 +146,8 @@ typedef struct pr_method_description_s pr_method_description_t;
typedef struct pr_ivar_list_s {
pr_int_t ivar_count;
struct pr_ivar_s {
string_t ivar_name;
string_t ivar_type;
pr_string_t ivar_name;
pr_string_t ivar_type;
pr_int_t ivar_offset;
} ivar_list[1];
} pr_ivar_list_t;
@ -157,16 +157,16 @@ typedef struct pr_static_instances_s {
// one per staticly instanced class per module (eg, 3 instances of Object
// will produce one of these structs with 3 pointers to those instances in
// instances[]
string_t class_name;
pointer_t instances[1]; // null terminated array of pr_id_t
pr_string_t class_name;
pr_ptr_t instances[1]; // null terminated array of pr_id_t
} pr_static_instances_t;
typedef struct pr_symtab_s {
pr_int_t sel_ref_cnt;
pointer_t refs; // pr_sel_t
pr_ptr_t refs; // pr_sel_t
pr_int_t cls_def_cnt;
pr_int_t cat_def_cnt;
pointer_t defs[1]; // variable array of cls_def_cnt class
pr_ptr_t defs[1]; // variable array of cls_def_cnt class
// pointers then cat_def_cnt category
// pointers followed by a null terminated
// array of pr_static_instances (not yet
@ -176,13 +176,13 @@ typedef struct pr_symtab_s {
typedef struct pr_module_s {
pr_int_t version;
pr_int_t size;
string_t name;
pointer_t symtab; // pr_symtab_t
pr_string_t name;
pr_ptr_t symtab; // pr_symtab_t
} pr_module_t;
typedef struct pr_super_s {
pointer_t self;
pointer_t class;
pr_ptr_t self;
pr_ptr_t class;
} pr_super_t;
#endif//__QF_pr_obj_h

View file

@ -34,11 +34,11 @@
/** \defgroup qfcc_qfo_type Object file type encoding
\ingroup progs
All \c pointer_t \c type fields are pointers within the type qfo_space.
All \c pr_ptr_t \c type fields are pointers within the type qfo_space.
*/
///@{
#include "QF/pr_comp.h"
#include "QF/progs/pr_comp.h"
typedef enum {
ty_basic, ///< VM type (float, int, pointer, field, etc)
@ -52,43 +52,49 @@ typedef enum {
typedef struct qfot_alias_s {
etype_t type; ///< type at end of alias chain
pointer_t aux_type; ///< referenced type: stripped of aliases
pointer_t full_type; ///< includes full alias info
string_t name; ///< alias name, may be null
pr_ptr_t aux_type; ///< referenced type: stripped of aliases
pr_ptr_t full_type; ///< includes full alias info
pr_string_t name; ///< alias name, may be null
} qfot_alias_t;
typedef struct qfot_fldptr_s {
etype_t type; ///< ev_field or ev_pointer
pointer_t aux_type; ///< referenced type
etype_t type; ///< ev_field or ev_ptr
pr_ptr_t aux_type; ///< referenced type
} qfot_fldptr_t;
typedef struct qfot_basic_s {
etype_t type; ///< integral and fp scalar types
pr_int_t width; ///< components in vector (1 for vector or
///< quaternion)
} qfot_basic_t;
typedef struct qfot_func_s {
etype_t type; ///< always ev_func
pointer_t return_type; ///< return type of the function
pr_ptr_t return_type; ///< return type of the function
pr_int_t num_params; ///< ones compliment count of the
///< parameters. -ve values indicate the
///< number of real parameters before the
///< ellipsis
pointer_t param_types[1]; ///< variable length list of parameter
pr_ptr_t param_types[1]; ///< variable length list of parameter
///< types
} qfot_func_t;
typedef struct qfot_var_s {
pointer_t type; ///< type of field or self reference for
pr_ptr_t type; ///< type of field or self reference for
///< enum
string_t name; ///< name of field/enumerator
pr_string_t name; ///< name of field/enumerator
pr_int_t offset; ///< value for enum, 0 for union
} qfot_var_t;
typedef struct qfot_struct_s {
string_t tag; ///< struct/union/enum tag
pr_string_t tag; ///< struct/union/enum tag
pr_int_t num_fields; ///< number of fields/enumerators
qfot_var_t fields[1]; ///< variable length list of
///< fields/enumerators
} qfot_struct_t;
typedef struct qfot_array_s {
pointer_t type; ///< element type
pr_ptr_t type; ///< element type
pr_int_t base; ///< start index of array
pr_int_t size; ///< number of elements in array
} qfot_array_t;
@ -103,20 +109,21 @@ typedef struct qfot_array_s {
typedef struct qfot_type_s {
ty_meta_e meta; ///< meta type
pr_uint_t size; ///< total word size of this encoding
string_t encoding; ///< Objective-QC encoding
pr_string_t encoding; ///< Objective-QC encoding
union {
etype_t type; ///< ty_basic: etype_t
qfot_fldptr_t fldptr; ///< ty_basic, ev_pointer/ev_field
qfot_basic_t basic; ///< ty_basic: int/float/double/long etc
qfot_fldptr_t fldptr; ///< ty_basic, ev_ptr/ev_field
qfot_func_t func; ///< ty_basic, ev_func
qfot_struct_t strct; ///< ty_struct/ty_union/ty_enum
qfot_array_t array; ///< ty_array
string_t class; ///< ty_class
pr_string_t class; ///< ty_class
qfot_alias_t alias; ///< ty_alias
};
} qfot_type_t;
typedef struct qfot_type_encodings_s {
pointer_t types;
pr_ptr_t types;
pr_uint_t size;
} qfot_type_encodings_t;

View file

@ -0,0 +1,50 @@
/*
pr_type_names.h
Progs type names
Copyright (C) 1996-1997 Id Software, Inc.
Copyright (C) 2022 Bill Currie <bill@taniwha.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifndef EV_TYPE
#define EV_TYPE(event)
#endif
EV_TYPE(void)
EV_TYPE(string)
EV_TYPE(float)
EV_TYPE(vector)
EV_TYPE(entity)
EV_TYPE(field)
EV_TYPE(func)
EV_TYPE(ptr) // end of v6 types
EV_TYPE(quaternion)
EV_TYPE(int)
EV_TYPE(uint)
EV_TYPE(short) // value is embedded in the opcode
EV_TYPE(double)
EV_TYPE(long)
EV_TYPE(ulong)
EV_TYPE(ushort) // value is embedded in the opcode
#undef EV_TYPE

View file

@ -31,15 +31,15 @@
#ifndef __QF_ruamoko_h
#define __QF_ruamoko_h
#include "QF/pr_obj.h"
#include "QF/progs/pr_obj.h"
struct progs_s;
struct cbuf_s;
void RUA_Init (struct progs_s *pr, int secure);
void RUA_Cbuf_SetCbuf (struct progs_s *pr, struct cbuf_s *cbuf);
func_t RUA_Obj_msg_lookup (struct progs_s *pr, pointer_t _self,
pointer_t __cmd);
pr_func_t RUA_Obj_msg_lookup (struct progs_s *pr, pr_ptr_t _self,
pr_ptr_t __cmd);
void RUA_Game_Init (struct progs_s *pr, int secure);

View file

@ -29,8 +29,10 @@
#define __QF_simd_types_h
#include <stdint.h>
#include <inttypes.h>
#define VEC_TYPE(t,n) typedef t n __attribute__ ((vector_size (4*sizeof (t))))
#define VEC_TYPE(t,n,s) \
typedef t n __attribute__ ((vector_size (s*sizeof (t))))
/** Three element vector type for interfacing with compact data.
*
@ -39,7 +41,9 @@
*/
typedef double vec3d_t[3];
#ifdef __AVX2__
VEC_TYPE (double, vec2d_t, 2);
VEC_TYPE (int64_t, vec2l_t, 2);
/** Four element vector type for horizontal (AOS) vector data.
*
* This is used for both vectors (3D and 4D) and quaternions. 3D vectors
@ -49,12 +53,11 @@ typedef double vec3d_t[3];
* a single component from four vectors, or a single row/column (depending on
* context) of an Nx4 or 4xN matrix.
*/
VEC_TYPE (double, vec4d_t);
VEC_TYPE (double, vec4d_t, 4);
/** Used mostly for __builtin_shuffle.
*/
VEC_TYPE (int64_t, vec4l_t);
#endif
VEC_TYPE (int64_t, vec4l_t, 4);
/** Three element vector type for interfacing with compact data.
*
@ -63,6 +66,9 @@ VEC_TYPE (int64_t, vec4l_t);
*/
typedef float vec3f_t[3];
VEC_TYPE (float, vec2f_t, 2);
VEC_TYPE (int, vec2i_t, 2);
/** Four element vector type for horizontal (AOS) vector data.
*
* This is used for both vectors (3D and 4D) and quaternions. 3D vectors
@ -72,20 +78,21 @@ typedef float vec3f_t[3];
* a single component from four vectors, or a single row/column (depending on
* context) of an Nx4 or 4xN matrix.
*/
VEC_TYPE (float, vec4f_t);
VEC_TYPE (float, vec4f_t, 4);
/** Used mostly for __builtin_shuffle.
*/
VEC_TYPE (int, vec4i_t);
VEC_TYPE (int, vec4i_t, 4);
#define VEC2D_FMT "[%.17g, %.17g]"
#define VEC2L_FMT "[%"PRIi64", %"PRIi64"]"
#define VEC4D_FMT "[%.17g, %.17g, %.17g, %.17g]"
#if __WORDSIZE == 64
#define VEC4L_FMT "[%ld, %ld, %ld, %ld]"
#else
#define VEC4L_FMT "[%lld, %lld, %lld, %lld]"
#endif
#define VEC4L_FMT "[%"PRIi64", %"PRIi64", %"PRIi64", %"PRIi64"]"
#define VEC2F_FMT "[%.9g, %.9g]"
#define VEC2I_FMT "[%d, %d]"
#define VEC4F_FMT "[%.9g, %.9g, %.9g, %.9g]"
#define VEC4I_FMT "[%d, %d, %d, %d]"
#define VEC2_EXP(v) (v)[0], (v)[1]
#define VEC4_EXP(v) (v)[0], (v)[1], (v)[2], (v)[3]
#define MAT4_ROW(m, r) (m)[0][r], (m)[1][r], (m)[2][r], (m)[3][r]

141
include/QF/simd/vec2d.h Normal file
View file

@ -0,0 +1,141 @@
/*
QF/simd/vec2d.h
Vector functions for vec2d_t (ie, double precision)
Copyright (C) 2020 Bill Currie <bill@taniwha.org>
Copyright (C) 2022 Bill Currie <bill@taniwha.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifndef __QF_simd_vec2d_h
#define __QF_simd_vec2d_h
#include <immintrin.h>
#include "QF/simd/types.h"
GNU89INLINE inline vec2d_t vsqrt2d (vec2d_t v) __attribute__((const));
GNU89INLINE inline vec2d_t vceil2d (vec2d_t v) __attribute__((const));
GNU89INLINE inline vec2d_t vfloor2d (vec2d_t v) __attribute__((const));
GNU89INLINE inline vec2d_t vtrunc2d (vec2d_t v) __attribute__((const));
/** 2D vector dot product.
*/
GNU89INLINE inline vec2d_t dot2d (vec2d_t a, vec2d_t b) __attribute__((const));
GNU89INLINE inline vec2d_t cmuld (vec2d_t a, vec2d_t b) __attribute__((const));
#ifndef IMPLEMENT_VEC2D_Funcs
GNU89INLINE inline
#else
VISIBLE
#endif
vec2d_t
vsqrt2d (vec2d_t v)
{
return _mm_sqrt_pd (v);
}
#ifndef IMPLEMENT_VEC2D_Funcs
GNU89INLINE inline
#else
VISIBLE
#endif
vec2d_t
vceil2d (vec2d_t v)
{
#ifndef __SSE4_1__
return (vec2d_t) {
ceil (v[0]),
ceil (v[1]),
};
#else
return _mm_ceil_pd (v);
#endif
}
#ifndef IMPLEMENT_VEC2D_Funcs
GNU89INLINE inline
#else
VISIBLE
#endif
vec2d_t
vfloor2d (vec2d_t v)
{
#ifndef __SSE4_1__
return (vec2d_t) {
floor (v[0]),
floor (v[1]),
};
#else
return _mm_floor_pd (v);
#endif
}
#ifndef IMPLEMENT_VEC2D_Funcs
GNU89INLINE inline
#else
VISIBLE
#endif
vec2d_t
vtrunc2d (vec2d_t v)
{
#ifndef __SSE4_1__
return (vec2d_t) {
trunc (v[0]),
trunc (v[1]),
};
#else
return _mm_round_pd (v, _MM_FROUND_TRUNC);
#endif
}
#ifndef IMPLEMENT_VEC2D_Funcs
GNU89INLINE inline
#else
VISIBLE
#endif
vec2d_t
dot2d (vec2d_t a, vec2d_t b)
{
vec2d_t c = a * b;
// gcc-11 does a good job with hadd
c = (vec2d_t) { c[0] + c[1], c[0] + c[1] };
return c;
}
#ifndef IMPLEMENT_VEC2F_Funcs
GNU89INLINE inline
#else
VISIBLE
#endif
vec2d_t
cmuld (vec2d_t a, vec2d_t b)
{
vec2d_t c1 = a * b[0];
vec2d_t c2 = a * b[1];
#ifndef __SSE3__
return (vec2d_t) { c1[0] - c2[1], c1[1] + c2[0] };
#else
return _mm_addsub_pd (c1, (vec2d_t) { c2[1], c2[0] });
#endif
}
#endif//__QF_simd_vec2d_h

182
include/QF/simd/vec2f.h Normal file
View file

@ -0,0 +1,182 @@
/*
QF/simd/vec2f.h
Vector functions for vec2f_t (ie, float precision)
Copyright (C) 2020 Bill Currie <bill@taniwha.org>
Copyright (C) 2022 Bill Currie <bill@taniwha.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifndef __QF_simd_vec2f_h
#define __QF_simd_vec2f_h
#include <immintrin.h>
#include <math.h>
#include "QF/simd/types.h"
GNU89INLINE inline vec2f_t vabs2f (vec2f_t v) __attribute__((const));
GNU89INLINE inline vec2f_t vsqrt2f (vec2f_t v) __attribute__((const));
GNU89INLINE inline vec2f_t vceil2f (vec2f_t v) __attribute__((const));
GNU89INLINE inline vec2f_t vfloor2f (vec2f_t v) __attribute__((const));
GNU89INLINE inline vec2f_t vtrunc2f (vec2f_t v) __attribute__((const));
/** 2D vector dot product.
*/
GNU89INLINE inline vec2f_t dot2f (vec2f_t a, vec2f_t b) __attribute__((const));
GNU89INLINE inline vec2f_t cmulf (vec2f_t a, vec2f_t b) __attribute__((const));
GNU89INLINE inline vec2f_t normal2f (vec2f_t v) __attribute__((pure));
GNU89INLINE inline vec2f_t magnitude2f (vec2f_t v) __attribute__((pure));
#ifndef IMPLEMENT_VEC2F_Funcs
GNU89INLINE inline
#else
VISIBLE
#endif
vec2f_t
vabs2f (vec2f_t v)
{
const uint32_t nan = ~0u >> 1;
const vec2i_t abs = { nan, nan };
return (vec2f_t) ((vec2i_t) v & abs);
}
#ifndef IMPLEMENT_VEC2F_Funcs
GNU89INLINE inline
#else
VISIBLE
#endif
vec2f_t
vsqrt2f (vec2f_t v)
{
vec4f_t t = { v[0], v[1], 0, 0 };
t = _mm_sqrt_ps (t);
return (vec2f_t) { t[0], t[1] };
}
#ifndef IMPLEMENT_VEC2F_Funcs
GNU89INLINE inline
#else
VISIBLE
#endif
vec2f_t
vceil2f (vec2f_t v)
{
#ifndef __SSE4_1__
return (vec2f_t) {
ceilf (v[0]),
ceilf (v[1]),
};
#else
vec4f_t t = { v[0], v[1], 0, 0 };
t = _mm_ceil_ps (t);
return (vec2f_t) { t[0], t[1] };
#endif
}
#ifndef IMPLEMENT_VEC2F_Funcs
GNU89INLINE inline
#else
VISIBLE
#endif
vec2f_t
vfloor2f (vec2f_t v)
{
#ifndef __SSE4_1__
return (vec2f_t) {
floorf (v[0]),
floorf (v[1]),
};
#else
vec4f_t t = { v[0], v[1], 0, 0 };
t = _mm_floor_ps (t);
return (vec2f_t) { t[0], t[1] };
#endif
}
#ifndef IMPLEMENT_VEC2F_Funcs
GNU89INLINE inline
#else
VISIBLE
#endif
vec2f_t
vtrunc2f (vec2f_t v)
{
#ifndef __SSE4_1__
return (vec2f_t) {
truncf (v[0]),
truncf (v[1]),
};
#else
vec4f_t t = { v[0], v[1], 0, 0 };
t = _mm_round_ps (t, _MM_FROUND_TRUNC);
return (vec2f_t) { t[0], t[1] };
#endif
}
#ifndef IMPLEMENT_VEC2F_Funcs
GNU89INLINE inline
#else
VISIBLE
#endif
vec2f_t
dot2f (vec2f_t a, vec2f_t b)
{
vec2f_t c = a * b;
return (vec2f_t) { c[0] + c[1], c[0] + c[1] };
}
#ifndef IMPLEMENT_VEC2F_Funcs
GNU89INLINE inline
#else
VISIBLE
#endif
vec2f_t
cmulf (vec2f_t a, vec2f_t b)
{
vec2f_t c1 = a * b[0];
vec2f_t c2 = a * b[1];
return (vec2f_t) { c1[0] - c2[1], c1[1] + c2[0] };
}
#ifndef IMPLEMENT_VEC2F_Funcs
GNU89INLINE inline
#else
VISIBLE
#endif
vec2f_t
normal2f (vec2f_t v)
{
return v / vsqrt2f (dot2f (v, v));
}
#ifndef IMPLEMENT_VEC2F_Funcs
GNU89INLINE inline
#else
VISIBLE
#endif
vec2f_t
magnitude2f (vec2f_t v)
{
return vsqrt2f (dot2f (v, v));
}
#endif//__QF_simd_vec2f_h

102
include/QF/simd/vec2i.h Normal file
View file

@ -0,0 +1,102 @@
/*
QF/simd/vec2i.h
Vector functions for vec2i_t (ie, int)
Copyright (C) 2022 Bill Currie <bill@taniwha.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifndef __QF_simd_vec2i_h
#define __QF_simd_vec2i_h
#include <immintrin.h>
#include <math.h>
#include "QF/simd/types.h"
GNU89INLINE inline vec2i_t vabs2i (vec2i_t v) __attribute__((const));
GNU89INLINE inline int any2i (vec2i_t v) __attribute__((const));
GNU89INLINE inline int all2i (vec2i_t v) __attribute__((const));
GNU89INLINE inline int none2i (vec2i_t v) __attribute__((const));
#ifndef IMPLEMENT_VEC2I_Funcs
GNU89INLINE inline
#else
VISIBLE
#endif
vec2i_t
vabs2i (vec2i_t v)
{
const uint32_t nan = ~0u >> 1;
const vec2i_t abs = { nan, nan };
return (vec2i_t) ((vec2i_t) v & abs);
}
#ifndef IMPLEMENT_VEC2I_Funcs
GNU89INLINE inline
#else
VISIBLE
#endif
int
any2i (vec2i_t v)
{
vec2i_t t = _m_pcmpeqd (v, (vec2i_t) {0, 0});
#ifndef __SSSE3__
return (t[0] + t[1]) > -2;
#else
return _mm_hadd_pi32 (t, t)[0] > -2;
#endif
}
#ifndef IMPLEMENT_VEC2I_Funcs
GNU89INLINE inline
#else
VISIBLE
#endif
int
all2i (vec2i_t v)
{
vec2i_t t = _m_pcmpeqd (v, (vec2i_t) {0, 0});
#ifndef __SSSE3__
return (t[0] + t[1]) == 0;
#else
return _mm_hadd_pi32 (t, t)[0] == 0;
#endif
}
#ifndef IMPLEMENT_VEC2I_Funcs
GNU89INLINE inline
#else
VISIBLE
#endif
int
none2i (vec2i_t v)
{
vec2i_t t = _m_pcmpeqd (v, (vec2i_t) {0, 0});
#ifndef __SSSE3__
return (t[0] + t[1]) == -2;
#else
return _mm_hadd_pi32 (t, t)[0] == -2;
#endif
}
#endif//__QF_simd_vec2i_h

View file

@ -28,15 +28,15 @@
#ifndef __QF_simd_vec4d_h
#define __QF_simd_vec4d_h
#ifdef __AVX2__
#include <immintrin.h>
#include "QF/simd/types.h"
#include "QF/simd/vec2d.h"
GNU89INLINE inline vec4d_t vsqrtd (vec4d_t v) __attribute__((const));
GNU89INLINE inline vec4d_t vceild (vec4d_t v) __attribute__((const));
GNU89INLINE inline vec4d_t vfloord (vec4d_t v) __attribute__((const));
GNU89INLINE inline vec4d_t vtruncd (vec4d_t v) __attribute__((const));
GNU89INLINE inline vec4d_t vsqrt4d (vec4d_t v) __attribute__((const));
GNU89INLINE inline vec4d_t vceil4d (vec4d_t v) __attribute__((const));
GNU89INLINE inline vec4d_t vfloor4d (vec4d_t v) __attribute__((const));
GNU89INLINE inline vec4d_t vtrunc4d (vec4d_t v) __attribute__((const));
/** 3D vector cross product.
*
* The w (4th) component can be any value on input, and is guaranteed to be 0
@ -96,6 +96,9 @@ GNU89INLINE inline vec4d_t qrotd (vec4d_t a, vec4d_t b) __attribute__((const));
GNU89INLINE inline vec4d_t qconjd (vec4d_t q) __attribute__((const));
GNU89INLINE inline vec4d_t loadvec3d (const double v3[]) __attribute__((pure));
GNU89INLINE inline void storevec3d (double v3[3], vec4d_t v4);
GNU89INLINE inline vec4l_t loadvec3l (const int64_t *v3) __attribute__((pure));
GNU89INLINE inline vec4l_t loadvec3l1 (const int64_t *v3) __attribute__((pure));
GNU89INLINE inline void storevec3l (int64_t *v3, vec4l_t v4);
#ifndef IMPLEMENT_VEC4D_Funcs
GNU89INLINE inline
@ -103,9 +106,17 @@ GNU89INLINE inline
VISIBLE
#endif
vec4d_t
vsqrtd (vec4d_t v)
vsqrt4d (vec4d_t v)
{
#ifndef __AVX__
vec2d_t xy = { v[0], v[1] };
vec2d_t zw = { v[2], v[3] };
xy = vsqrt2d (xy);
zw = vsqrt2d (zw);
return (vec4d_t) { xy[0], xy[1], zw[0], zw[1] };
#else
return _mm256_sqrt_pd (v);
#endif
}
#ifndef IMPLEMENT_VEC4D_Funcs
@ -114,9 +125,17 @@ GNU89INLINE inline
VISIBLE
#endif
vec4d_t
vceild (vec4d_t v)
vceil4d (vec4d_t v)
{
#ifndef __AVX__
vec2d_t xy = { v[0], v[1] };
vec2d_t zw = { v[2], v[3] };
xy = vceil2d (xy);
zw = vceil2d (zw);
return (vec4d_t) { xy[0], xy[1], zw[0], zw[1] };
#else
return _mm256_ceil_pd (v);
#endif
}
#ifndef IMPLEMENT_VEC4D_Funcs
@ -125,9 +144,17 @@ GNU89INLINE inline
VISIBLE
#endif
vec4d_t
vfloord (vec4d_t v)
vfloor4d (vec4d_t v)
{
#ifndef __AVX__
vec2d_t xy = { v[0], v[1] };
vec2d_t zw = { v[2], v[3] };
xy = vfloor2d (xy);
zw = vfloor2d (zw);
return (vec4d_t) { xy[0], xy[1], zw[0], zw[1] };
#else
return _mm256_floor_pd (v);
#endif
}
#ifndef IMPLEMENT_VEC4D_Funcs
@ -136,9 +163,17 @@ GNU89INLINE inline
VISIBLE
#endif
vec4d_t
vtruncd (vec4d_t v)
vtrunc4d (vec4d_t v)
{
#ifndef __AVX__
vec2d_t xy = { v[0], v[1] };
vec2d_t zw = { v[2], v[3] };
xy = vtrunc2d (xy);
zw = vtrunc2d (zw);
return (vec4d_t) { xy[0], xy[1], zw[0], zw[1] };
#else
return _mm256_round_pd (v, _MM_FROUND_TRUNC);
#endif
}
#ifndef IMPLEMENT_VEC4D_Funcs
@ -165,7 +200,11 @@ vec4d_t
dotd (vec4d_t a, vec4d_t b)
{
vec4d_t c = a * b;
#ifndef __AVX__
c = (vec4d_t) { c[0] + c[1], c[0] + c[1], c[2] + c[3], c[2] + c[3] };
#else
c = _mm256_hadd_pd (c, c);
#endif
static const vec4l_t A = {2, 3, 0, 1};
c += __builtin_shuffle(c, A);
return c;
@ -184,8 +223,7 @@ qmuld (vec4d_t a, vec4d_t b)
vec4d_t c = crossd (a, b) + a * b[3] + a[3] * b;
vec4d_t d = dotd (a, b);
// zero out the vector component of dot product so only the scalar remains
d = _mm256_permute2f128_pd (d, d, 0x18);
d = _mm256_permute4x64_pd (d, 0xc0);
d = (vec4d_t) { 0, 0, 0, d[3] };
return c - d;
}
@ -201,8 +239,12 @@ qvmuld (vec4d_t q, vec4d_t v)
double s = q[3];
// zero the scalar of the quaternion. Results in an extra operation, but
// avoids adding precision issues.
#ifndef __AVX__
q = (vec4d_t) { q[0], q[1], q[2], 0 };
#else
vec4d_t z = {};
q = _mm256_blend_pd (q, z, 0x08);
#endif
vec4d_t c = crossd (q, v);
vec4d_t qv = dotd (q, v); // q.w is 0 so v.w is irrelevant
vec4d_t qq = dotd (q, q);
@ -223,8 +265,12 @@ vqmuld (vec4d_t v, vec4d_t q)
double s = q[3];
// zero the scalar of the quaternion. Results in an extra operation, but
// avoids adding precision issues.
#ifndef __AVX__
q = (vec4d_t) { q[0], q[1], q[2], 0 };
#else
vec4d_t z = {};
q = _mm256_blend_pd (q, z, 0x08);
#endif
vec4d_t c = crossd (q, v);
vec4d_t qv = dotd (q, v); // q.w is 0 so v.w is irrelevant
vec4d_t qq = dotd (q, q);
@ -241,11 +287,11 @@ VISIBLE
vec4d_t
qrotd (vec4d_t a, vec4d_t b)
{
vec4d_t ma = vsqrtd (dotd (a, a));
vec4d_t mb = vsqrtd (dotd (b, b));
vec4d_t ma = vsqrt4d (dotd (a, a));
vec4d_t mb = vsqrt4d (dotd (b, b));
vec4d_t den = 2 * ma * mb;
vec4d_t t = mb * a + ma * b;
vec4d_t mba_mab = vsqrtd (dotd (t, t));
vec4d_t mba_mab = vsqrt4d (dotd (t, t));
vec4d_t q = crossd (a, b) / mba_mab;
q[3] = (mba_mab / den)[0];
return q;
@ -261,7 +307,7 @@ qconjd (vec4d_t q)
{
const uint64_t sign = UINT64_C(1) << 63;
const vec4l_t neg = { sign, sign, sign, 0 };
return _mm256_xor_pd (q, (__m256d) neg);
return (vec4d_t) ((vec4l_t) q ^ neg);
}
#ifndef IMPLEMENT_VEC4D_Funcs
@ -293,6 +339,41 @@ storevec3d (double v3[3], vec4d_t v4)
v3[2] = v4[2];
}
#ifndef IMPLEMENT_VEC4F_Funcs
GNU89INLINE inline
#else
VISIBLE
#endif
vec4l_t
loadvec3l (const int64_t *v3)
{
vec4l_t v4 = { v3[0], v3[1], v3[2], 0 };
return v4;
}
#ifndef IMPLEMENT_VEC4F_Funcs
GNU89INLINE inline
#else
VISIBLE
#endif
vec4l_t
loadvec3l1 (const int64_t *v3)
{
vec4l_t v4 = { v3[0], v3[1], v3[2], 1 };
return v4;
}
#ifndef IMPLEMENT_VEC4F_Funcs
GNU89INLINE inline
#else
VISIBLE
#endif
void
storevec3l (int64_t *v3, vec4l_t v4)
{
v3[0] = v4[0];
v3[1] = v4[1];
v3[2] = v4[2];
}
#endif//__QF_simd_vec4d_h

View file

@ -33,11 +33,11 @@
#include "QF/simd/types.h"
GNU89INLINE inline vec4f_t vabsf (vec4f_t v) __attribute__((const));
GNU89INLINE inline vec4f_t vsqrtf (vec4f_t v) __attribute__((const));
GNU89INLINE inline vec4f_t vceilf (vec4f_t v) __attribute__((const));
GNU89INLINE inline vec4f_t vfloorf (vec4f_t v) __attribute__((const));
GNU89INLINE inline vec4f_t vtruncf (vec4f_t v) __attribute__((const));
GNU89INLINE inline vec4f_t vabs4f (vec4f_t v) __attribute__((const));
GNU89INLINE inline vec4f_t vsqrt4f (vec4f_t v) __attribute__((const));
GNU89INLINE inline vec4f_t vceil4f (vec4f_t v) __attribute__((const));
GNU89INLINE inline vec4f_t vfloor4f (vec4f_t v) __attribute__((const));
GNU89INLINE inline vec4f_t vtrunc4f (vec4f_t v) __attribute__((const));
/** 3D vector cross product.
*
* The w (4th) component can be any value on input, and is guaranteed to be 0
@ -106,7 +106,7 @@ GNU89INLINE inline
VISIBLE
#endif
vec4f_t
vabsf (vec4f_t v)
vabs4f (vec4f_t v)
{
const uint32_t nan = ~0u >> 1;
const vec4i_t abs = { nan, nan, nan, nan };
@ -119,7 +119,7 @@ GNU89INLINE inline
VISIBLE
#endif
vec4f_t
vsqrtf (vec4f_t v)
vsqrt4f (vec4f_t v)
{
#ifndef __SSE__
vec4f_t r = { sqrtf (v[0]), sqrtf (v[1]), sqrtf (v[2]), sqrtf (v[3]) };
@ -135,7 +135,7 @@ GNU89INLINE inline
VISIBLE
#endif
vec4f_t
vceilf (vec4f_t v)
vceil4f (vec4f_t v)
{
#ifndef __SSE4_1__
return (vec4f_t) {
@ -155,7 +155,7 @@ GNU89INLINE inline
VISIBLE
#endif
vec4f_t
vfloorf (vec4f_t v)
vfloor4f (vec4f_t v)
{
#ifndef __SSE4_1__
return (vec4f_t) {
@ -175,7 +175,7 @@ GNU89INLINE inline
VISIBLE
#endif
vec4f_t
vtruncf (vec4f_t v)
vtrunc4f (vec4f_t v)
{
#ifndef __SSE4_1__
return (vec4f_t) {
@ -296,11 +296,11 @@ VISIBLE
vec4f_t
qrotf (vec4f_t a, vec4f_t b)
{
vec4f_t ma = vsqrtf (dotf (a, a));
vec4f_t mb = vsqrtf (dotf (b, b));
vec4f_t ma = vsqrt4f (dotf (a, a));
vec4f_t mb = vsqrt4f (dotf (b, b));
vec4f_t den = 2 * ma * mb;
vec4f_t t = mb * a + ma * b;
vec4f_t mba_mab = vsqrtf (dotf (t, t));
vec4f_t mba_mab = vsqrt4f (dotf (t, t));
vec4f_t q = crossf (a, b) / mba_mab;
q[3] = (mba_mab / den)[0];
return q;
@ -388,7 +388,7 @@ VISIBLE
vec4f_t
normalf (vec4f_t v)
{
return v / vsqrtf (dotf (v, v));
return v / vsqrt4f (dotf (v, v));
}
#ifndef IMPLEMENT_VEC4F_Funcs
@ -399,7 +399,7 @@ VISIBLE
vec4f_t
magnitudef (vec4f_t v)
{
return vsqrtf (dotf (v, v));
return vsqrt4f (dotf (v, v));
}
#ifndef IMPLEMENT_VEC4F_Funcs
@ -411,7 +411,7 @@ vec4f_t
magnitude3f (vec4f_t v)
{
v[3] = 0;
return vsqrtf (dotf (v, v));
return vsqrt4f (dotf (v, v));
}
vec4f_t __attribute__((pure))

142
include/QF/simd/vec4i.h Normal file
View file

@ -0,0 +1,142 @@
/*
QF/simd/vec4i.h
Vector functions for vec4i_t (ie, int)
Copyright (C) 2022 Bill Currie <bill@taniwha.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifndef __QF_simd_vec4i_h
#define __QF_simd_vec4i_h
#include <immintrin.h>
#include <math.h>
#include "QF/simd/types.h"
GNU89INLINE inline vec4i_t vabs4i (vec4i_t v) __attribute__((const));
GNU89INLINE inline int any4i (vec4i_t v) __attribute__((const));
GNU89INLINE inline int all4i (vec4i_t v) __attribute__((const));
GNU89INLINE inline int none4i (vec4i_t v) __attribute__((const));
GNU89INLINE inline vec4i_t loadvec3i (const int *v3) __attribute__((pure));
GNU89INLINE inline vec4i_t loadvec3i1 (const int *v3) __attribute__((pure));
GNU89INLINE inline void storevec3i (int *v3, vec4i_t v4);
#ifndef IMPLEMENT_VEC4F_Funcs
GNU89INLINE inline
#else
VISIBLE
#endif
vec4i_t
vabs4i (vec4i_t v)
{
const uint32_t nan = ~0u >> 1;
const vec4i_t abs = { nan, nan, nan, nan };
return (vec4i_t) ((vec4i_t) v & abs);
}
#ifndef IMPLEMENT_VEC2I_Funcs
GNU89INLINE inline
#else
VISIBLE
#endif
int
any4i (vec4i_t v)
{
#ifndef __SSE4_1__
vec4i_t t = (v != (vec4i_t) {});
return (t[0] + t[1] + t[2] + t[3]) != 0;
#else
return !__builtin_ia32_ptestz128 ((__v2di)v, (__v2di)v);
#endif
}
#ifndef IMPLEMENT_VEC2I_Funcs
GNU89INLINE inline
#else
VISIBLE
#endif
int
all4i (vec4i_t v)
{
vec4i_t t = (v == (vec4i_t) {});
#ifndef __SSE4_1__
return (t[0] + t[1] + t[2] + t[3]) == 0;
#else
return __builtin_ia32_ptestz128 ((__v2di)t, (__v2di)t);
#endif
}
#ifndef IMPLEMENT_VEC2I_Funcs
GNU89INLINE inline
#else
VISIBLE
#endif
int
none4i (vec4i_t v)
{
#ifndef __SSE4_1__
vec4i_t t = (v != (vec4i_t) {});
return (t[0] + t[1] + t[2] + t[3]) == 0;
#else
return __builtin_ia32_ptestz128 ((__v2di)v, (__v2di)v);
#endif
}
#ifndef IMPLEMENT_VEC4F_Funcs
GNU89INLINE inline
#else
VISIBLE
#endif
vec4i_t
loadvec3i (const int *v3)
{
vec4i_t v4 = { v3[0], v3[1], v3[2], 0 };
return v4;
}
#ifndef IMPLEMENT_VEC4F_Funcs
GNU89INLINE inline
#else
VISIBLE
#endif
vec4i_t
loadvec3i1 (const int *v3)
{
vec4i_t v4 = { v3[0], v3[1], v3[2], 1 };
return v4;
}
#ifndef IMPLEMENT_VEC4F_Funcs
GNU89INLINE inline
#else
VISIBLE
#endif
void
storevec3i (int *v3, vec4i_t v4)
{
v3[0] = v4[0];
v3[1] = v4[1];
v3[2] = v4[2];
}
#endif//__QF_simd_vec4i_h

View file

@ -64,12 +64,10 @@ extern struct msg_s *net_message;
extern struct cvar_s *qport;
int Net_Log_Init (const char **sound_precache);
int Net_Log_Init (const char **sound_precache, int server);
void Net_LogPrintf (const char *fmt, ...) __attribute__ ((format (PRINTF, 1, 2)));
void Log_Incoming_Packet (const byte *p, int len, int has_sequence,
int is_server);
void Log_Outgoing_Packet (const byte *p, int len, int has_sequence,
int is_server);
void Log_Incoming_Packet (const byte *p, int len, int has_sequence);
void Log_Outgoing_Packet (const byte *p, int len, int has_sequence);
void Net_LogStop (void *data);
void Analyze_Client_Packet (const byte * data, int len, int has_sequence);
void Analyze_Server_Packet (const byte * data, int len, int has_sequence);

View file

@ -268,7 +268,7 @@ void NET_AddCachedHost (const char *name, const char *map, const char *cname,
extern double net_time;
extern struct msg_s *net_message;
extern int net_activeconnections;
extern unsigned net_activeconnections;
/** Initialize the networking sub-system.
*/

View file

@ -33,6 +33,9 @@
#include "QF/quakeio.h"
struct progs_s;
struct dstring_s;
void RUA_Cbuf_Init (struct progs_s *pr, int secure);
void RUA_Cmd_Init (struct progs_s *pr, int secure);
void RUA_Cvar_Init (struct progs_s *pr, int secure);
@ -49,6 +52,10 @@ void RUA_String_Init (struct progs_s *pr, int secure);
void RUA_QFile_Init (struct progs_s *pr, int secure);
void RUA_QFS_Init (struct progs_s *pr, int secure);
// the variable args are assumed to come immediately after fmt_arg
void RUA_Sprintf (struct progs_s *pr, struct dstring_s *dstr, const char *func,
int fmt_arg);
int QFile_AllocHandle (struct progs_s *pr, QFile *file);
QFile *QFile_GetFile (struct progs_s *pr, int handle);
struct plitem_s *Plist_GetItem (struct progs_s *pr, int handle);

View file

@ -47,13 +47,15 @@ bi_S_LocalSound (progs_t *pr)
S_LocalSound (sound);
}
#define bi(x,np,params...) {#x, bi_##x, -1, np, {params}}
#define p(type) PR_PARAM(type)
static builtin_t builtins[] = {
{"S_LocalSound", bi_S_LocalSound, -1},
bi(S_LocalSound, 1, p(string)),
{0}
};
VISIBLE void
S_Progs_Init (progs_t *pr)
{
PR_RegisterBuiltins (pr, builtins);
PR_RegisterBuiltins (pr, builtins, 0);
}

View file

@ -49,8 +49,8 @@ typedef struct il_data_s {
struct il_data_s **prev;
inputline_t *line;
progs_t *pr;
func_t enter; // enter key callback
pointer_t data[2]; // allow two data params for the callback
pr_func_t enter; // enter key callback
pr_ptr_t data[2]; // allow two data params for the callback
int method; // true if method rather than function
} il_data_t;
@ -302,21 +302,23 @@ bi_InputLine_Draw (progs_t *pr)
line->line->draw (line->line);
}
#define bi(x,np,params...) {#x, bi_##x, -1, np, {params}}
#define p(type) PR_PARAM(type)
static builtin_t builtins[] = {
{"InputLine_Create", bi_InputLine_Create, -1},
{"InputLine_SetPos", bi_InputLine_SetPos, -1},
{"InputLine_SetCursor", bi_InputLine_SetCursor, -1},
bi(InputLine_Create, 3, p(int), p(int), p(int)),
bi(InputLine_SetPos, 3, p(ptr), p(int), p(int)),
bi(InputLine_SetCursor, 2, p(ptr), p(int)),
{"InputLine_SetEnter|^{tag _inputline_t=}(v*^v)^v",
bi_InputLine_SetEnter, -1},
bi_InputLine_SetEnter, -1, 3, {p(ptr), p(func), p(ptr)}},
{"InputLine_SetEnter|^{tag _inputline_t=}(@@:.)@:",
bi_InputLine_SetEnter, -1},
{"InputLine_SetWidth", bi_InputLine_SetWidth, -1},
{"InputLine_SetText", bi_InputLine_SetText, -1},
{"InputLine_GetText", bi_InputLine_GetText, -1},
{"InputLine_Destroy", bi_InputLine_Destroy, -1},
{"InputLine_Clear", bi_InputLine_Clear, -1},
{"InputLine_Process", bi_InputLine_Process, -1},
{"InputLine_Draw", bi_InputLine_Draw, -1},
bi_InputLine_SetEnter, -1, 4, {p(ptr), p(func), p(ptr), p(ptr)}},
bi(InputLine_SetWidth, 2, p(ptr), p(int)),
bi(InputLine_SetText, 2, p(ptr), p(string)),
bi(InputLine_GetText, 1, p(ptr)),
bi(InputLine_Destroy, 1, p(ptr)),
bi(InputLine_Clear, 2, p(ptr), p(int)),
bi(InputLine_Process, 2, p(ptr), p(int)),
bi(InputLine_Draw, 1, p(ptr)),
{0}
};
@ -326,7 +328,7 @@ InputLine_Progs_Init (progs_t *pr)
il_resources_t *res = calloc (1, sizeof (il_resources_t));
PR_Resources_Register (pr, "InputLine", res, bi_il_clear);
PR_RegisterBuiltins (pr, builtins);
PR_RegisterBuiltins (pr, builtins, res);
}
VISIBLE void

View file

@ -67,12 +67,12 @@ typedef struct menu_item_s {
int max_items;
int cur_item;
int x, y;
func_t func;
func_t cursor;
func_t keyevent;
func_t draw;
func_t enter_hook;
func_t leave_hook;
pr_func_t func;
pr_func_t cursor;
pr_func_t keyevent;
pr_func_t draw;
pr_func_t enter_hook;
pr_func_t leave_hook;
unsigned fadescreen:1;
unsigned allkeys:1;
const char *text;
@ -85,16 +85,16 @@ static progs_t menu_pr_state;
static menu_item_t *menu;
//static keydest_t menu_keydest;
static hashtab_t *menu_hash;
static func_t menu_init;
static func_t menu_quit;
static func_t menu_draw_hud;
static func_t menu_pre;
static func_t menu_post;
static pr_func_t menu_init;
static pr_func_t menu_quit;
static pr_func_t menu_draw_hud;
static pr_func_t menu_pre;
static pr_func_t menu_post;
static const char *top_menu;
typedef struct menu_func_s {
const char *name;
func_t *func;
pr_func_t *func;
} menu_func_t;
static menu_func_t menu_functions[] = {
@ -129,12 +129,12 @@ menu_resolve_globals (progs_t *pr)
sym = menu_functions[i].name;
if (!(f = PR_FindFunction (pr, sym)))
goto error;
*menu_functions[i].func = (func_t) (f - menu_pr_state.pr_functions);
*menu_functions[i].func = (pr_func_t) (f - menu_pr_state.pr_functions);
}
if (!(def = PR_FindGlobal (pr, sym = "time")))
goto error;
menu_pr_state.globals.time = &G_FLOAT (pr, def->ofs);
menu_pr_state.globals.ftime = &G_FLOAT (pr, def->ofs);//FIXME double time
return 1;
error:
Sys_Printf ("%s: undefined symbol %s\n", pr->progs_name, sym);
@ -315,7 +315,7 @@ bi_Menu_Item (progs_t *pr)
int x = P_INT (pr, 0);
int y = P_INT (pr, 1);
const char *text = P_GSTRING (pr, 2);
func_t func = P_FUNCTION (pr, 3);
pr_func_t func = P_FUNCTION (pr, 3);
int allkeys = P_INT (pr, 4);
menu_item_t *mi = calloc (sizeof (menu_item_t), 1);
@ -331,7 +331,7 @@ bi_Menu_Item (progs_t *pr)
static void
bi_Menu_Cursor (progs_t *pr)
{
func_t func = P_FUNCTION (pr, 0);
pr_func_t func = P_FUNCTION (pr, 0);
menu->cursor = func;
}
@ -339,7 +339,7 @@ bi_Menu_Cursor (progs_t *pr)
static void
bi_Menu_KeyEvent (progs_t *pr)
{
func_t func = P_FUNCTION (pr, 0);
pr_func_t func = P_FUNCTION (pr, 0);
menu->keyevent = func;
}
@ -385,7 +385,7 @@ bi_Menu_SelectMenu (progs_t *pr)
static void
bi_Menu_SetQuit (progs_t *pr)
{
func_t func = P_FUNCTION (pr, 0);
pr_func_t func = P_FUNCTION (pr, 0);
menu_quit = func;
}
@ -513,29 +513,33 @@ menu_load_file (progs_t *pr, const char *path, off_t *size)
return data;
}
#define bi(x,np,params...) {#x, bi_##x, -1, np, {params}}
#define p(type) PR_PARAM(type)
static builtin_t builtins[] = {
{"Menu_Begin", bi_Menu_Begin, -1},
{"Menu_FadeScreen", bi_Menu_FadeScreen, -1},
{"Menu_Draw", bi_Menu_Draw, -1},
{"Menu_EnterHook", bi_Menu_EnterHook, -1},
{"Menu_LeaveHook", bi_Menu_LeaveHook, -1},
{"Menu_Pic", bi_Menu_Pic, -1},
{"Menu_SubPic", bi_Menu_SubPic, -1},
{"Menu_CenterPic", bi_Menu_CenterPic, -1},
{"Menu_CenterSubPic", bi_Menu_CenterSubPic, -1},
{"Menu_Item", bi_Menu_Item, -1},
{"Menu_Cursor", bi_Menu_Cursor, -1},
{"Menu_KeyEvent", bi_Menu_KeyEvent, -1},
{"Menu_End", bi_Menu_End, -1},
{"Menu_TopMenu", bi_Menu_TopMenu, -1},
{"Menu_SelectMenu", bi_Menu_SelectMenu, -1},
{"Menu_SetQuit", bi_Menu_SetQuit, -1},
{"Menu_Quit", bi_Menu_Quit, -1},
{"Menu_GetIndex", bi_Menu_GetIndex, -1},
{"Menu_Next", bi_Menu_Next, -1},
{"Menu_Prev", bi_Menu_Prev, -1},
{"Menu_Enter", bi_Menu_Enter, -1},
{"Menu_Leave", bi_Menu_Leave, -1},
bi(Menu_Begin, 3, p(int), p(int), p(string)),
bi(Menu_FadeScreen, 1, p(int)),
bi(Menu_Draw, 2, p(int), p(int)),
bi(Menu_EnterHook, 1, p(func)),
bi(Menu_LeaveHook, 1, p(func)),
bi(Menu_Pic, 3, p(int), p(int), p(string)),
bi(Menu_SubPic, 7, p(int), p(int), p(string),
p(int), p(int), p(int), p(int)),
bi(Menu_CenterPic, 3, p(int), p(int), p(string)),
bi(Menu_CenterSubPic, 7, p(int), p(int), p(string),
p(int), p(int), p(int), p(int)),
bi(Menu_Item, 5, p(int), p(int), p(string), p(func), p(int)),
bi(Menu_Cursor, 1, p(func)),
bi(Menu_KeyEvent, 1, p(func)),
bi(Menu_End, 0),
bi(Menu_TopMenu, 1, p(string)),
bi(Menu_SelectMenu, 1, p(string)),
bi(Menu_SetQuit, 1, p(func)),
bi(Menu_Quit, 0),
bi(Menu_GetIndex, 0),
bi(Menu_Next, 0),
bi(Menu_Prev, 0),
bi(Menu_Enter, 0),
bi(Menu_Leave, 0),
{0},
};
@ -590,12 +594,13 @@ Menu_Init (void)
menu_pr_state.max_edicts = 0;
menu_pr_state.zone_size = 1024 * 1024;
menu_pr_state.stack_size = 64 * 1024;
PR_Init (&menu_pr_state);
menu_hash = Hash_NewTable (61, menu_get_key, menu_free, 0, 0);
PR_RegisterBuiltins (&menu_pr_state, builtins);
PR_RegisterBuiltins (&menu_pr_state, builtins, 0);
RUA_Init (&menu_pr_state, 3);
@ -672,18 +677,20 @@ Menu_Draw (view_t *view)
if (menu->fadescreen)
r_funcs->Draw_FadeScreen ();
*menu_pr_state.globals.time = *con_data.realtime;
*menu_pr_state.globals.ftime = *con_data.realtime;//FIXME double time
if (menu->draw) {
int ret;
run_menu_pre ();
PR_PushFrame (&menu_pr_state);
PR_RESET_PARAMS (&menu_pr_state);
P_INT (&menu_pr_state, 0) = x;
P_INT (&menu_pr_state, 1) = y;
menu_pr_state.pr_argc = 2;
PR_ExecuteProgram (&menu_pr_state, menu->draw);
ret = R_INT (&menu_pr_state);
PR_PopFrame (&menu_pr_state);
run_menu_post ();
if (!ret)
return;
@ -713,11 +720,13 @@ Menu_Draw (view_t *view)
item = menu->items[menu->cur_item];
if (menu->cursor) {
run_menu_pre ();
PR_PushFrame (&menu_pr_state);
PR_RESET_PARAMS (&menu_pr_state);
P_INT (&menu_pr_state, 0) = x + item->x;
P_INT (&menu_pr_state, 1) = y + item->y;
menu_pr_state.pr_argc = 2;
PR_ExecuteProgram (&menu_pr_state, menu->cursor);
PR_PopFrame (&menu_pr_state);
run_menu_post ();
} else {
r_funcs->Draw_Character (x + item->x, y + item->y,
@ -729,7 +738,7 @@ void
Menu_Draw_Hud (view_t *view)
{
run_menu_pre ();
*menu_pr_state.globals.time = *con_data.realtime;
*menu_pr_state.globals.ftime = *con_data.realtime;//FIXME double time
PR_ExecuteProgram (&menu_pr_state, menu_draw_hud);
run_menu_post ();
@ -746,6 +755,7 @@ menu_key_event (const IE_event_t *ie_event)
return 0;
if (menu->keyevent) {
run_menu_pre ();
PR_PushFrame (&menu_pr_state);
PR_RESET_PARAMS (&menu_pr_state);
P_INT (&menu_pr_state, 0) = key.code;
P_INT (&menu_pr_state, 1) = key.unicode;
@ -753,6 +763,7 @@ menu_key_event (const IE_event_t *ie_event)
menu_pr_state.pr_argc = 3;
PR_ExecuteProgram (&menu_pr_state, menu->keyevent);
ret = R_INT (&menu_pr_state);
PR_PopFrame (&menu_pr_state);
run_menu_post ();
if (ret)
return 1;
@ -767,8 +778,8 @@ menu_key_event (const IE_event_t *ie_event)
P_INT (&menu_pr_state, 1) = key.code;
menu_pr_state.pr_argc = 2;
PR_ExecuteProgram (&menu_pr_state, item->func);
PR_PopFrame (&menu_pr_state);
ret = R_INT (&menu_pr_state);
PR_PopFrame (&menu_pr_state);
run_menu_post ();
if (ret)
return 1;

View file

@ -1,3 +1,5 @@
include libs/gamecode/test/Makemodule.am
gc_deps=libs/util/libQFutil.la
noinst_LTLIBRARIES += libs/gamecode/libQFgamecode.la
@ -11,9 +13,49 @@ libs_gamecode_libQFgamecode_la_SOURCES= \
libs/gamecode/pr_debug.c \
libs/gamecode/pr_exec.c \
libs/gamecode/pr_load.c \
libs/gamecode/pr_parse.c \
libs/gamecode/pr_opcode.c \
libs/gamecode/pr_parse.c \
libs/gamecode/pr_resolve.c \
libs/gamecode/pr_resource.c \
libs/gamecode/pr_strings.c \
libs/gamecode/pr_v6p_opcode.c \
libs/gamecode/pr_zone.c
noinst_PYTHON += $(opcodes_py)
opcodes_py = $(srcdir)/libs/gamecode/opcodes.py
pr_opcode_cinc = $(top_builddir)/libs/gamecode/pr_opcode.cinc
pr_opcode_hinc = $(top_builddir)/include/QF/progs/pr_opcode.hinc
pr_opcode_src = \
${pr_opcode_cinc} \
${pr_opcode_hinc}
libs/gamecode/pr_opcode.lo: libs/gamecode/pr_opcode.c ${pr_opcode_src}
convert_py = $(srcdir)/libs/gamecode/convert.py
pr_convert_cinc = $(top_builddir)/libs/gamecode/pr_convert.cinc
hops_py = $(srcdir)/libs/gamecode/hops.py
pr_hops_cinc = $(top_builddir)/libs/gamecode/pr_hops.cinc
BUILT_SOURCES += \
$(pr_opcode_cinc) \
$(pr_opcode_hinc) \
$(pr_convert_cinc) \
$(pr_hops_cinc)
$(pr_opcode_cinc): $(opcodes_py)
$(V_PY)$(PYTHON) $(opcodes_py) table > $(pr_opcode_cinc).t && \
$(am__mv) $(pr_opcode_cinc).t $(pr_opcode_cinc)
$(pr_opcode_hinc): $(opcodes_py)
$(V_PY) mkdir -p `dirname $(pr_opcode_hinc)` &&\
$(PYTHON) $(opcodes_py) enum > $(pr_opcode_hinc).t && \
$(am__mv) $(pr_opcode_hinc).t $(pr_opcode_hinc)
$(pr_convert_cinc): $(convert_py)
$(V_PY)$(PYTHON) $(convert_py) table > $(pr_convert_cinc).t && \
$(am__mv) $(pr_convert_cinc).t $(pr_convert_cinc)
$(pr_hops_cinc): $(hops_py)
$(V_PY)$(PYTHON) $(hops_py) table > $(pr_hops_cinc).t && \
$(am__mv) $(pr_hops_cinc).t $(pr_hops_cinc)

132
libs/gamecode/convert.py Normal file
View file

@ -0,0 +1,132 @@
print("""// types are encoded as ubf where:
// u = 0: signed, u = 1: unsigned
// b = 0: 32-bit, b = 1: 64-bit
// f = 0: int, f = 1: float/double
// unsigned float/double is interpreted as bool
// width is ww where:
// ww = 00: 1 component
// ww = 01: 2 components
// ww = 10: 3 components
// ww = 11: 4 components
// full conversion code is wwsssddd where:
// ww = width
// sss = src type
// ddd = dst type
// case values are in octal
""")
types = [
"int",
"float",
"long",
"double",
"uint",
"int", # 32-bit bool
"ulong",
"long", # 64-bit bool
]
#does not include size (2 or 4, 3 is special)
vec_types = [
"ivec",
"vec",
"lvec",
"dvec",
"uivec",
"ivec", # 32-bit bool
"ulvec",
"lvec", # 64-bit bool
]
convert_matrix = [
#i f l d ui b ul B
[0, 1, 1, 1, 0, 3, 1, 3], # i
[1, 0, 1, 1, 1, 3, 1, 3], # f
[1, 1, 0, 1, 1, 3, 0, 3], # l
[1, 1, 1, 0, 1, 3, 1, 3], # d
[0, 1, 1, 1, 0, 3, 1, 3], # ui
[2, 2, 2, 2, 2, 0, 2, 3], # 32-bit bool
[1, 1, 0, 1, 1, 3, 0, 3], # ul
[2, 2, 2, 2, 2, 3, 2, 0], # 64-bit bool
]
def case_str(width, src_type, dst_type):
case = (width << 6) | (src_type << 3) | (dst_type)
return f"case {case:04o}:"
#FIXME look into using gcc's __builtin_convertvector
def cast_str(width, src_type, dst_type):
if width & 1:
return f"(pr_{vec_types[dst_type]}{width+1}_t)"
else:
return f"(pr_{types[dst_type]}_t)"
def src_str(width, src_type, dst_type):
if width & 1:
return f"OPA({vec_types[src_type]}{width+1})"
else:
return f"OPA({types[src_type]})"
def dst_str(width, src_type, dst_type):
if width & 1:
return f"OPC({vec_types[dst_type]}{width+1})"
else:
return f"OPC({types[dst_type]})"
def zero_str(width, src_type):
ones = "{%s}" % (", ".join(["0"] * (width + 1)))
return f"{cast_str(width, src_type, src_type)} {ones}"
def one_str(width, src_type):
ones = "{%s}" % (", ".join(["1"] * (width + 1)))
return f"{cast_str(width, src_type, src_type)} {ones}"
def expand_str(width, src, pref=""):
src = [f"{pref}{src}[{i}]" for i in range(width + 1)]
return "{%s}" % (", ".join(src));
for width in range(4):
for src_type in range(8):
for dst_type in range(8):
case = case_str(width, src_type, dst_type)
cast = cast_str(width, src_type, dst_type)
src = src_str(width, src_type, dst_type)
dst = dst_str(width, src_type, dst_type)
mode = convert_matrix[src_type][dst_type]
if mode == 0:
if dst_type & 2 != src_type & 2:
continue
if dst_type & 2:
src = src_str(width, 2, 2)
dst = dst_str(width, 2, 2)
else:
src = src_str(width, 0, 0)
dst = dst_str(width, 0, 0)
if width == 2:
print(f"{case} VectorCopy(&{src},&{dst}); break;")
else:
print(f"{case} {dst} = {src}; break;")
elif mode == 1:
if width == 0:
print(f"{case} {dst} = {cast} {src}; break;")
elif width == 2:
print(f"{case} VectorCompUop(&{dst},{cast},&{src}); break;")
else:
expand = expand_str(width, src)
print(f"{case} {dst} = {cast} {expand}; break;")
elif mode == 2:
one = one_str(width, src_type)
if width == 0:
print(f"{case} {dst} = !!{src}; break;")
elif width == 2:
print(f"{case} VectorCompUop(&{dst},!!,&{src}); break;")
else:
expand = expand_str(width, src, "!!")
print(f"{case} {dst} = {cast} {expand}; break;")
elif mode == 3:
zero = zero_str(width, src_type)
if width == 0:
print(f"{case} {dst} = -!!{src}; break;")
elif width == 2:
print(f"{case} VectorCompUop(&{dst},-!!,&{src}); break;")
else:
expand = expand_str(width, src, "-!!")
print(f"{case} {dst} = {cast} {expand}; break;")

55
libs/gamecode/hops.py Normal file
View file

@ -0,0 +1,55 @@
print("""// encoding is tssooo
// t = 0: 32-bit, t = 1: 64-bit
// ss = 00: reserved
// ss = 01: 2 components
// ss = 10: 3 components
// ss = 11: 4 components
// ooo = 000: and
// ooo = 001: or
// ooo = 010: xor
// ooo = 011: add.i
// ooo = 100: nand
// ooo = 101: nor
// ooo = 110: xnor
// ooo = 111: add.f
""")
#for vec3
types = [
["int", "int", "int", "int", "int", "int", "int", "float"],
["long", "long", "long", "long", "long", "long", "long", "double"]
]
#does not include size (2 or 4, 3 is special)
vec_types = [
["ivec", "ivec", "ivec", "ivec", "ivec", "ivec", "ivec", "vec"],
["lvec", "lvec", "lvec", "lvec", "lvec", "lvec", "lvec", "dvec"]
]
operators = ["&", "|", "^", "+"]
def case_str(type, width, op):
case = (type << 5) | (width << 3) | (op)
return f"case {case:03o}:"
def src_str(type, width, op):
if width & 1:
return f"OPA({vec_types[type][op]}{width+1})"
else:
return f"OPA({types[type][op]})"
def dst_str(type, width, op):
return f"OPC({types[type][op]})"
def hop_str(type, width, op):
return f"{'~' if op & 4 and op != 7 else ''}OP_hop{width+1}"
for type in range(2):
for width in range(1, 4): # 0 is reserved
for opcode in range(8):
case = case_str(type, width, opcode)
src = src_str(type, width, opcode)
dst = dst_str(type, width, opcode)
hop = hop_str(type, width, opcode)
op = operators[opcode & 3]
if width == 2:
print(f"{case} {dst} = {hop} (&{src}, {op}); break;")
else:
print(f"{case} {dst} = {hop} ({src}, {op}); break;")

707
libs/gamecode/opcodes.py Normal file
View file

@ -0,0 +1,707 @@
bitmap_txt = """
0 0000 mmss load
0 0001 mmss store
0 0010 mmss push
0 0011 mmss pop
0 1ccc ttss compare
0 0000 00nn
0 0000 0000 noop
0 0000 0001 adjstk
0 0000 0010 constant
0 1011 otss udivops
0 1111 s0mm load64
0 1111 s1mm store64
0 1111 n000
1 0ooo ttss mathops
1 011r tuss shiftops
1 0110 o1oo string
1 1ccc t0ss compare2
1 1t00 ooss bitops
1 1001 01mm jump
1 1001 11mm call (return specified st->c)
1 1001 1100 return (size in st->c)
1 1010 t1ss scale
1 1010 t100 swizzle
1 1011 tooo vecops
1 1101 01oo move
1 1101 11oo memset
1 1101 c111 statef
1 1110 c1cc branch
1 1110 c111 stated
1 1111 00mm lea
1 1111 01td vecops2
1 1111 10oo fbitops
1 1111 1100 convert (conversion mode in st->b)
1 1111 1101 with (mode in st->a, value in st->b, reg in st->c)
1 1111 1110
1 1111 1111 hops
"""
import copy
address_mode = "ABCD"
address_types = [
"ev_void, ev_invalid",
"ev_entity, ev_field",
"ev_ptr, ev_short",
"ev_ptr, ev_int",
]
address_widths = [
[ "1, 0", "1, 1", "1, 0", "1, 1", ],
[ "2, 0", "1, 1", "1, 0", "1, 1", ],
[ "3, 0", "1, 1", "1, 0", "1, 1", ],
[ "4, 0", "1, 1", "1, 0", "1, 1", ],
[ "-1, 0", "1, 1", "1, 0", "1, 1", ],
]
#store, pop and lea
store_fmt = [
"%ga",
"%Ga.%Gb(%Ea)",
"*(%Ga + %sb)",
"*(%Ga + %Gb)",
]
# load and push
load_fmt = [
"*%Ga, %gc",
"%Ga.%Gb(%Ea)",
"*(%Ga + %sb)",
"*(%Ga + %Gb)",
]
branch_fmt = [
"branch %sa (%Oa)",
"*%Ga",
"%Ga[%sb]",
"%Ga[%Gb]",
]
compare_ccc = [ "eq", "lt", "gt", None, "ne", "ge", "le", None]
type_tt = ['I', 'F', 'L', 'D']
etype_tt = ["ev_int", "ev_float", "ev_long", "ev_double"]
unsigned_t = ["ev_uint", "ev_ulong"]
float_t = ["ev_float", "ev_double"]
adjstk_formats = {
"opcode": "OP_ADJSTK",
"mnemonic": "adjstk",
"opname": "adjstk",
"format": "%sa, %sb",
"widths": "0, 0, 0",
"types": "ev_short, ev_short, ev_invalid",
}
bitops_formats = {
"opcode": "OP_{op_bit[oo].upper()}_{bit_type[t]}_{ss+1}",
"mnemonic": "{op_bit[oo]}",
"opname": "{op_bit[oo]}",
"format": "{bit_fmt[oo]}",
"widths": "{ss+1}, { oo < 3 and ss+1 or 0}, {ss+1}",
"types": "{bit_types[t]}, {oo < 3 and bit_types[t] or 'ev_invalid'}, {bit_types[t]}",
"args": {
"op_bit": ["bitand", "bitor", "bitxor", "bitnot"],
"bit_type": ["I", "L"],
"bit_types": ["ev_int", "ev_long"],
"bit_fmt": [
"%Ga, %Gb, %gc",
"%Ga, %Gb, %gc",
"%Ga, %Gb, %gc",
"%Ga, %gc",
],
},
}
branch_formats = {
"opcode": "OP_{op_cond[c*4+cc].upper()}",
"mnemonic": "{op_cond[c*4+cc]}",
"opname": "{op_cond[c*4+cc]}",
"format": "{cond_fmt[c*4+cc]}{branch_fmt[0]}",
"widths": "0, 0, 1",
"types": "ev_short, ev_invalid, ev_int",
"args": {
"op_mode": "ABCD",
"op_cond": ["ifz", "ifb", "ifa", None,
"ifnz", "ifae", "ifbe", None],
"branch_fmt": branch_fmt,
"cond_fmt": ["%Gc ", "%Gc ", "%Gc ", "", "%Gc ", "%Gc ", "%Gc ", ""],
},
}
call_formats = {
"opcode": "OP_CALL_{op_mode[mm]}",
"mnemonic": "call",
"opname": "call",
"format": "{call_fmt[mm]}",
"widths": "{call_widths[mm]}, -1",
"types": "{call_types[mm]}, ev_void",
"args": {
"op_mode": ".BCD",
"call_fmt": [
None, # return handled seprately
"%Ga, %gc",
"%Ga[%sb], %gc",
"%Ga[%Gb], %gc",
],
"call_types": [
None,
"ev_void, ev_invalid",
"ev_ptr, ev_short",
"ev_ptr, ev_int",
],
"call_widths": [ None, "1, 0", "1, 0", "1, 1" ]
},
}
compare_formats = {
"opcode": "OP_{op_cmp[ccc].upper()}_{cmp_type[tt]}_{ss+1}",
"mnemonic": "{op_cmp[ccc]}.{cmp_type[tt]}",
"opname": "{op_cmp[ccc]}",
"widths": "{ss+1}, {ss+1}, {ss+1}",
"types": "{cmp_types[tt]}, {cmp_types[tt]}, ev_int",
"args": {
"op_cmp": compare_ccc,
"cmp_type": type_tt,
"cmp_types": etype_tt,
},
}
compare2_formats = {
"opcode": "OP_{op_cmp[ccc].upper()}_{cmp_type[t]}_{ss+1}",
"mnemonic": "{op_cmp[ccc]}.{cmp_type[t]}",
"opname": "{op_cmp[ccc]}",
"widths": "{ss+1}, {ss+1}, {ss+1}",
"types": "{cmp_types[t]}, {cmp_types[t]}, ev_int",
"args": {
"op_cmp": compare_ccc,
"cmp_type": ['u', 'U'],
"cmp_types": unsigned_t,
},
}
constant_formats = {
"opcode": "OP_LDCONST",
"mnemonic": "ldconst",
"opname": "ldconst",
"format": "%sa, %sb, %gc",
"widths": "0, 0, -1",
"types": "ev_short, ev_short, ev_void",
}
convert_formats = {
"opcode": "OP_CONV",
"mnemonic": "conv",
"opname": "conv",
"format": "%Ga %Cb %gc",
"widths": "-1, 0, -1",
"types": "ev_void, ev_short, ev_void",
}
fbitops_formats = {
"opcode": "OP_{op_fbit[oo].upper()}_F",
"mnemonic": "{op_fbit[oo]}.f",
"opname": "{op_fbit[oo]}",
"format": "{fbit_fmt[oo]}",
"widths": "1, 1, 1",
"types": "{fbit_types[0]}, {fbit_types[oo==3]}, {fbit_types[0]}",
"args": {
"op_fbit": ["bitand", "bitor", "bitxor", "bitnot"],
"fbit_types": ["ev_float", "ev_invalid"],
"fbit_fmt": [
"%Ga, %Gb, %gc",
"%Ga, %Gb, %gc",
"%Ga, %Gb, %gc",
"%Ga, %gc",
],
},
}
hops_formats = {
"opcode": "OP_HOPS",
"mnemonic": "hops",
"opname": "hops",
"format": "%Ga %Hb %gc",
"widths": "-1, 0, 1",
"types": "ev_void, ev_short, ev_void",
}
jump_formats = {
"opcode": "OP_JUMP_{op_mode[mm]}",
"mnemonic": "jump",
"opname": "jump",
"format": "{jump_fmt[mm]}",
"widths": "{jump_widths[mm]}, 0",
"types": "{jump_types[mm]}",
"args": {
"op_mode": "ABCD",
"jump_fmt": branch_fmt,
"jump_types": [
"ev_short, ev_invalid, ev_invalid",
"ev_void, ev_int, ev_invalid",
"ev_ptr, ev_short, ev_invalid",
"ev_ptr, ev_int, ev_invalid",
],
"jump_widths": [ "0, 0", "1, 1", "1, 0", "1, 1" ]
},
}
load64_formats = {
"opcode": "OP_LOAD64_{op_mode[mm]}_{s+3}",
"mnemonic": "load64",
"opname": "load64",
"format": "{load_fmt[mm]}, %gc",
"widths": "{load_widths[s+2][mm]}, {s+3}",
"types": "{load_types[mm]}, ev_void",
"args": {
"op_mode": address_mode,
"load_fmt": load_fmt,
"load_types": address_types,
"load_widths": address_widths,
},
}
lea_formats = {
"opcode": "OP_LEA_{op_mode[mm]}",
"mnemonic": "lea",
"opname": "lea",
"format": "{lea_fmt[mm]}, %gc",
"widths": "{lea_widths[mm]}, 1",
"types": "{lea_types[mm]}, ev_ptr",
"args": {
"op_mode": address_mode,
"lea_fmt": store_fmt,
"lea_types": address_types,
"lea_widths": address_widths[4],
},
}
load_formats = {
"opcode": "OP_LOAD_{op_mode[mm]}_{ss+1}",
"mnemonic": "load",
"opname": "load",
"format": "{load_fmt[mm]}, %gc",
"widths": "{load_widths[ss][mm]}, {ss+1}",
"types": "{load_types[mm]}, ev_void",
"args": {
"op_mode": address_mode,
"load_fmt": load_fmt,
"load_types": address_types,
"load_widths": address_widths,
},
}
mathops_formats = {
"opcode": "OP_{op_math[ooo].upper()}_{math_type[tt]}_{ss+1}",
"mnemonic": "{op_math[ooo]}.{math_type[tt]}",
"opname": "{op_math[ooo]}",
"widths": "{ss+1}, {ss+1}, {ss+1}",
"types": "{math_types[tt]}, {math_types[tt]}, {math_types[tt]}",
"args": {
"op_math": ["mul", "div", "rem", "mod", "add", "sub", None, None],
"math_type": type_tt,
"math_types": etype_tt,
},
}
memset_formats = {
"opcode": "OP_MEMSET_{op_memset[oo].upper()}",
"mnemonic": "memset.{op_memset[oo]}",
"opname": "memset{suff_memset[oo]}",
"format": "{memset_fmt[oo]}",
"widths": "{memset_widths[oo]}",
"types": "{memset_types[oo]}",
"args": {
"op_memset": ["i", "p", "pi", None],
"suff_memset": ["", "p", "p", None],
"memset_fmt": ["%Ga, %sb, %gc", "%Ga, %Gb, %Gc", "%Ga, %sb, %Gc", None],
"memset_widths": [
"1, 0, -1",
"1, 1, 1",
"1, 0, 1",
None,
],
"memset_types": [
"ev_int, ev_short, ev_void",
"ev_int, ev_int, ev_ptr",
"ev_int, ev_short, ev_ptr",
],
},
}
move_formats = {
"opcode": "OP_MOVE_{op_move[oo].upper()}",
"mnemonic": "move.{op_move[oo]}",
"opname": "move{suff_move[oo]}",
"format": "{move_fmt[oo]}",
"widths": "{move_widths[oo]}",
"types": "{move_types[oo]}",
"args": {
"op_move": ["i", "p", "pi", None],
"suff_move": ["", "p", "p", None],
"move_fmt": ["%Ga, %sb, %gc", "%Ga, %Gb, %Gc", "%Ga, %sb, %Gc", None],
"move_widths": [
"-1, 0, -1",
"1, 1, 1",
"1, 0, 1",
None,
],
"move_types": [
"ev_void, ev_short, ev_void",
"ev_ptr, ev_int, ev_ptr",
"ev_ptr, ev_short, ev_ptr",
],
},
}
noop_formats = {
"opcode": "OP_NOP",
"mnemonic": "nop",
"opname": "nop",
"format": "there were plums...",
"widths": "0, 0, 0",
"types": "ev_invalid, ev_invalid, ev_invalid",
}
push_formats = {
"opcode": "OP_PUSH_{op_mode[mm]}_{ss+1}",
"mnemonic": "push",
"opname": "push",
"format": "{push_fmt[mm]}",
"widths": "{ss+1}, 0, 0",
"types": "{push_types[mm]}, ev_invalid",
"args": {
"op_mode": address_mode,
"push_fmt": load_fmt,
"push_types": address_types,
},
}
pop_formats = {
"opcode": "OP_POP_{op_mode[mm]}_{ss+1}",
"mnemonic": "pop",
"opname": "pop",
"format": "{pop_fmt[mm]}",
"widths": "{ss+1}, 0, 0",
"types": "{pop_types[mm]}, ev_invalid",
"args": {
"op_mode": address_mode,
"pop_fmt": store_fmt,
"pop_types": address_types,
},
}
scale_formats = {
"opcode": "OP_SCALE_{scale_type[t]}_{ss+1}",
"mnemonic": "scale.{scale_type[t]}",
"opname": "scale",
"widths": "{ss+1}, 1, {ss+1}",
"types": "{scale_types[t]}, {scale_types[t]}, {scale_types[t]}",
"args": {
"scale_type": ['F', 'D'],
"scale_types": float_t,
},
}
shiftops_formats = {
"opcode": "OP_{mn_shift[u*2+r].upper()}_{shift_type[u*2+t]}_{ss+1}",
"mnemonic": "{mn_shift[u*2+r]}.{shift_type[u*2+t]}",
"opname": "{op_shift[u*2+r]}",
"widths": "{ss+1}, {ss+1}, {ss+1}",
"types": "{shift_types[t][u]}, {shift_types[t][0]}, {shift_types[t][u]}",
"args": {
"mn_shift": ["shl", "asr", "shl", "shr"],
"op_shift": ["shl", "shr", "shl", "shr"],
"shift_type": ['I', 'L', 'u', 'U'],
"shift_types": [
["ev_int", "ev_uint"],
["ev_long", "ev_ulong"],
],
},
}
statef_formats = {
"opcode": "OP_STATE_{state[c]}",
"mnemonic": "state.{state[c]}",
"opname": "state",
"format": "{state_fmt[c]}",
"widths": "1, 1, {c}",
"types": "ev_float, ev_func, {state_types[c]}",
"args": {
"state": ["ft", "ftt"],
"state_fmt": ["%Ga, %Gb", "%Ga, %Gb, %Gc"],
"state_types": ["ev_invalid", "ev_float"],
},
}
stated_formats = {
"opcode": "OP_STATE_{state[c]}",
"mnemonic": "state.{state[c]}",
"opname": "state",
"format": "{state_fmt[c]}",
"widths": "1, 1, {c}",
"types": "ev_int, ev_func, {state_types[c]}",
"args": {
"state": ["dt", "dtt"],
"state_fmt": ["%Ga, %Gb", "%Ga, %Gb, %Gc"],
"state_types": ["ev_invalid", "ev_double"],
},
}
store_formats = {
"opcode": "OP_STORE_{op_mode[mm]}_{ss+1}",
"mnemonic": "{store_op[mm]}",
"opname": "{store_op[mm]}",
"format": "%Gc, {store_fmt[mm]}",
"widths": "{store_widths[ss][mm]}, {ss+1}",
"types": "{store_types[mm]}, ev_void",
"args": {
"op_mode": address_mode,
"store_fmt": store_fmt,
"store_op": ["assign", "store", "store", "store"],
"store_types": address_types,
"store_widths": address_widths,
},
}
store64_formats = {
"opcode": "OP_STORE64_{op_mode[mm]}_{s+3}",
"mnemonic": "{store_op[mm]}64",
"opname": "{store_op[mm]}64",
"format": "%Gc, {store_fmt[mm]}",
"widths": "{store_widths[s+2][mm]}, {s+3}",
"types": "{store_types[mm]}, ev_void",
"args": {
"op_mode": address_mode,
"store_fmt": store_fmt,
"store_op": ["assign", "store", "store", "store"],
"store_types": address_types,
"store_widths": address_widths,
},
}
string_formats = {
"opcode": "OP_{op_str[o*4+oo].upper()}_S",
"mnemonic": "{op_str[o*4+oo]}.s",
"opname": "{op_str[o*4+oo]}",
"format": "{str_fmt[o*4+oo]}",
"widths": "1, {(o*4+oo)<7 and 1 or 0}, 1",
"types": "{str_types[o*4+oo]}",
"args": {
"op_str": ["eq", "lt", "gt", "add", "cmp", "ge", "le", "not"],
"str_fmt": [
"%Ga, %Gb, %gc",
"%Ga, %Gb, %gc",
"%Ga, %Gb, %gc",
"%Ga, %Gb, %gc",
"%Ga, %Gb, %gc",
"%Ga, %Gb, %gc",
"%Ga, %Gb, %gc",
"%Ga, %gc",
],
"str_types": [
"ev_string, ev_string, ev_int",
"ev_string, ev_string, ev_int",
"ev_string, ev_string, ev_int",
"ev_string, ev_string, ev_string",
"ev_string, ev_string, ev_int",
"ev_string, ev_string, ev_int",
"ev_string, ev_string, ev_int",
"ev_string, ev_invalid, ev_int",
],
},
}
swizzle_formats = {
"opcode": "OP_SWIZZLE_{swiz_type[t]}",
"mnemonic": "swizzle.{swiz_type[t]}",
"opname": "swizzle",
"format": "%Ga %sb %gc",
"widths": "4, 0, 4",
"types": "{swizzle_types[t]}",
"args": {
"swiz_type": ['F', 'D'],
"swizzle_types": float_t,
},
}
return_formats = {
"opcode": "OP_RETURN",
"mnemonic": "return",
"opname": "return",
"widths": "-1, -1, 0", # width specified by st->c
"format": "%Mc5",
"types": "ev_void, ev_void, ev_void",
}
udivops_formats = {
"opcode": "OP_{op_udiv[o].upper()}_{udiv_type[t]}_{ss+1}",
"mnemonic": "{op_udiv[o]}.{udiv_type[t]}",
"opname": "{op_udiv[o]}",
"widths": "{ss+1}, {ss+1}, {ss+1}",
"types": "{udiv_types[t]}, {udiv_types[t]}, {udiv_types[t]}",
"args": {
"op_udiv": ["div", "rem"],
"udiv_type": ['u', 'U'],
"udiv_types": ["ev_uint", "ev_ulong"],
},
}
vecops_formats = {
"opcode": "OP_{op_vop[ooo].upper()}_{vop_type[t]}",
"mnemonic": "{op_vop[ooo]}.{vop_type[t]}",
"opname": "{op_vop[ooo]}",
"widths": "{vec_widths[ooo]}",
"types": "{vec_types[t]}, {vec_types[t]}, {vec_types[t]}",
"args": {
"op_vop": ["cross", "cdot", "vdot", "qdot",
"cmul", "qvmul", "vqmul", "qmul"],
"vop_type": ['F', 'D'],
"vec_widths": [
"3, 3, 3",
"2, 2, 2",
"3, 3, 3",
"4, 4, 4",
"2, 2, 2",
"4, 3, 3",
"3, 4, 3",
"4, 4, 4",
],
"vec_types": float_t,
},
}
vecops2_formats = {
"opcode": "OP_{op_vop[d].upper()}_{vop_type[t]}",
"mnemonic": "{op_vop[d]}.{vop_type[t]}",
"opname": "{op_vop[d]}",
"widths": "4, 4, 4",
"types": "{vec_types[t]}, {vec_types[t]}, {vec_types[t]}",
"args": {
"op_vop": ["qv4mul", "v4qmul"],
"vop_type": ['F', 'D'],
"vec_types": float_t,
},
}
with_formats = {
"opcode": "OP_WITH",
"mnemonic": "with",
"opname": "with",
"format": "%sa, %sb, %sc",
"widths": "0, -1, 0",
"types": "ev_short, ev_void, ev_short",
}
group_map = {
"adjstk": adjstk_formats,
"bitops": bitops_formats,
"branch": branch_formats,
"call": call_formats,
"compare": compare_formats,
"compare2": compare2_formats,
"constant": constant_formats,
"convert": convert_formats,
"fbitops": fbitops_formats,
"hops": hops_formats,
"jump": jump_formats,
"lea": lea_formats,
"load": load_formats,
"load64": load64_formats,
"mathops": mathops_formats,
"memset": memset_formats,
"move": move_formats,
"noop": noop_formats,
"push": push_formats,
"pop": pop_formats,
"scale": scale_formats,
"shiftops": shiftops_formats,
"statef": statef_formats,
"stated": stated_formats,
"store": store_formats,
"store64": store64_formats,
"string": string_formats,
"swizzle": swizzle_formats,
"return": return_formats,
"udivops": udivops_formats,
"vecops": vecops_formats,
"vecops2": vecops2_formats,
"with": with_formats,
}
def parse_bits(bit_string):
bits = [""]
isbit = bit_string[0] in ['0', '1']
lastbit = bit_string[0]
while bit_string:
bit = bit_string[0]
bit_string = bit_string[1:]
if isbit and bit in ['0', '1']:
bits[-1] = bits[-1] + bit
elif lastbit == bit:
bits[-1] = bits[-1] + bit
else:
bits.append(bit)
lastbit = bit
isbit = bit in ['0', '1']
return bits
opcodes = [None] * 512
def expand_opcodes(bits, group, num=0):
if not bits:
opcodes[num] = group
return
block = bits[0]
bits = bits[1:]
num <<= len(block)
if block[0] in ['0', '1']:
num |= int(block, 2)
expand_opcodes(bits, group, num)
else:
for n in range(1<<len(block)):
if group is not None:
expand_opcodes(bits, group + f",{block}={n}", num | n)
else:
expand_opcodes(bits, group, num | n)
def process_opcode(opcode, group):
data = group.split(',')
params = {}
for d in data[1:]:
p = d.split('=')
params[p[0]] = int(p[1])
gm = group_map[data[0]]
if "args" in gm:
params.update(gm["args"])
inst = {}
opcodes[opcode] = inst
#print(f"{opcode:03x}", group)
inst["op"] = eval(f'''f"{gm['opcode']}"''', params)
mn = eval(f'''f"{gm['mnemonic']}"''', params)
inst["mn"] = f'"{mn}"'
on = eval(f'''f"{gm['opname']}"''', params)
inst["on"] = f'"{on}"'
fmt = "%Ga, %Gb, %gc"
if "format" in gm:
if gm["format"] is not None:
fmt = eval(f'''f"{gm['format']}"''', params)
else:
fmt = None
if fmt is None:
fmt = "0"
else:
fmt = f'"{fmt}"'
inst["fmt"] = fmt
inst["wd"] = "{%s}" % eval(f'''f"{gm['widths']}"''', params)
inst["ty"] = "{%s}" % eval(f'''f"{gm['types']}"''', params)
import sys
if len (sys.argv) < 2 or sys.argv[1] not in ["enum", "table"]:
sys.stderr.write ("specify output type: enum or table\n")
sys.exit(1)
lines = bitmap_txt.split('\n')
for l in lines:
l = l.strip()
if not l or l[0] == '#':
continue
c = l.split(' ')
bits = "".join(c[0:3])
group = c[3:] and c[3] or None
descr = ' '.join(c[4:])
#print(bits, group, descr)
#print(parse_bits(bits))
expand_opcodes(parse_bits(bits), group)
for i, group in enumerate(opcodes):
if group is not None:
process_opcode (i, group)
if sys.argv[1] == "enum":
N = 4
W = 15
for i in range(len(opcodes)//N):
row = opcodes[i * N:i * N + N]
#row = map(lambda op: (op and op["op"] or f"OP_spare_{i}"), row)
row = [(op and op["op"] or f"OP_spare_{i*N+x}")
for x, op in enumerate(row)]
row = map(lambda op: f"%-{W}.{W}s" % (op + ','), row)
if sys.argv[2:3] == ["debug"]:
print("%03x" % (i << 3), " ".join(row))
else:
print(" ".join(row))
elif sys.argv[1] == "table":
for i, group in enumerate(opcodes):
if group is not None:
print(eval('f"[{op}] = {{\\n'
'\\t.opname = {on},\\n'
'\\t.mnemonic = {mn},\\n'
'\\t.widths = {wd},\\n'
'\\t.types = {ty},\\n'
'\\t.fmt = {fmt},\\n'
'}},"', group))

View file

@ -95,14 +95,14 @@ bi_no_function (progs_t *pr)
// descriptor with a bad builtin number
dstatement_t *st = pr->pr_statements + pr->pr_xstatement;
dfunction_t *desc = pr->pr_functions + G_FUNCTION (pr, st->a);
const char *bi_name = PR_GetString (pr, desc->s_name);
const char *bi_name = PR_GetString (pr, desc->name);
int ind = -desc->first_statement;
PR_RunError (pr, "Bad builtin called: %s = #%d", bi_name, ind);
}
VISIBLE void
PR_RegisterBuiltins (progs_t *pr, builtin_t *builtins)
PR_RegisterBuiltins (progs_t *pr, builtin_t *builtins, void *data)
{
builtin_t *bi;
int count;
@ -135,21 +135,25 @@ PR_RegisterBuiltins (progs_t *pr, builtin_t *builtins)
builtins = bi;
while (builtins->name) {
if (builtins->binum == 0 || builtins->binum >= PR_AUTOBUILTIN)
if (builtins->binum == 0 || builtins->binum >= PR_AUTOBUILTIN) {
PR_Error (pr, "bad builtin number: %s = #%d", builtins->name,
builtins->binum);
}
if (builtins->binum < 0)
if (builtins->binum < 0) {
builtins->binum = builtin_next (pr);
}
if ((bi = Hash_Find (pr->builtin_hash, builtins->name))
|| (bi = Hash_FindElement (pr->builtin_num_hash, builtins)))
|| (bi = Hash_FindElement (pr->builtin_num_hash, builtins))) {
PR_Error (pr, "builtin %s = #%d already defined (%s = #%d)",
builtins->name, builtins->binum,
bi->name, bi->binum);
}
Hash_Add (pr->builtin_hash, builtins);
Hash_AddElement (pr->builtin_num_hash, builtins);
builtins->data = data;
builtins++;
}
@ -184,24 +188,24 @@ PR_RelocateBuiltins (progs_t *pr)
if (pr->function_table)
free (pr->function_table);
pr->function_table = calloc (pr->progs->numfunctions,
pr->function_table = calloc (pr->progs->functions.count,
sizeof (bfunction_t));
for (i = 1; i < pr->progs->numfunctions; i++) {
for (i = 1; i < pr->progs->functions.count; i++) {
desc = pr->pr_functions + i;
func = pr->function_table + i;
func->first_statement = desc->first_statement;
func->parm_start = desc->parm_start;
func->params_start = desc->params_start;
func->locals = desc->locals;
func->numparms = desc->numparms;
memcpy (func->parm_size, desc->parm_size, sizeof (func->parm_size));
func->numparams = desc->numparams;
memcpy (func->param_size, desc->param_size, sizeof (func->param_size));
func->descriptor = desc;
if (desc->first_statement > 0)
continue;
bi_name = PR_GetString (pr, desc->s_name);
bi_name = PR_GetString (pr, desc->name);
if (!desc->first_statement) {
bi = PR_FindBuiltin (pr, bi_name);
@ -225,12 +229,15 @@ PR_RelocateBuiltins (progs_t *pr)
bi_name, -desc->first_statement);
proc = bi_no_function;
}
if (!desc->s_name && bi) {
desc->s_name = PR_SetString (pr, bi->name);
if (!desc->name && bi) {
desc->name = PR_SetString (pr, bi->name);
Hash_Add (pr->function_hash, &pr->pr_functions[i]);
}
func->first_statement = desc->first_statement;
func->func = proc;
if (bi) {
func->data = bi->data;
}
}
if (bad) {
Sys_Printf ("PR_RelocateBuiltins: %s: progs may not work due to "

View file

@ -42,21 +42,25 @@
#include <ctype.h>
#include <sys/types.h>
#include <stdlib.h>
#include <inttypes.h>
#include "QF/fbsearch.h"
#include "QF/cvar.h"
#include "QF/dstring.h"
#include "QF/hash.h"
#include "QF/mathlib.h"
#include "QF/pr_debug.h"
#include "QF/pr_type.h"
#include "QF/progs.h"
#include "QF/qendian.h"
#include "QF/quakefs.h"
#include "QF/script.h"
#include "QF/sys.h"
#include "QF/va.h"
#include "QF/zone.h"
#include "QF/progs/pr_debug.h"
#include "QF/progs/pr_type.h"
#include "QF/simd/types.h"
#include "compat.h"
typedef struct {
@ -89,11 +93,12 @@ typedef struct prdeb_resources_s {
dstring_t *dva;
dstring_t *line;
dstring_t *dstr;
va_ctx_t *va;
const char *debugfile;
pr_debug_header_t *debug;
pr_auxfunction_t *auxfunctions;
pr_auxfunction_t **auxfunction_map;
func_t *sorted_functions;
pr_func_t *sorted_functions;
pr_lineno_t *linenos;
pr_def_t *local_defs;
pr_def_t *type_encodings_def;
@ -117,32 +122,6 @@ cvar_t *pr_source_path;
static char *source_path_string;
static char **source_paths;
static void pr_debug_void_view (qfot_type_t *type, pr_type_t *value,
void *_data);
static void pr_debug_string_view (qfot_type_t *type, pr_type_t *value,
void *_data);
static void pr_debug_float_view (qfot_type_t *type, pr_type_t *value,
void *_data);
static void pr_debug_vector_view (qfot_type_t *type, pr_type_t *value,
void *_data);
static void pr_debug_entity_view (qfot_type_t *type, pr_type_t *value,
void *_data);
static void pr_debug_field_view (qfot_type_t *type, pr_type_t *value,
void *_data);
static void pr_debug_func_view (qfot_type_t *type, pr_type_t *value,
void *_data);
static void pr_debug_pointer_view (qfot_type_t *type, pr_type_t *value,
void *_data);
static void pr_debug_quat_view (qfot_type_t *type, pr_type_t *value,
void *_data);
static void pr_debug_integer_view (qfot_type_t *type, pr_type_t *value,
void *_data);
static void pr_debug_uinteger_view (qfot_type_t *type, pr_type_t *value,
void *_data);
static void pr_debug_short_view (qfot_type_t *type, pr_type_t *value,
void *_data);
static void pr_debug_double_view (qfot_type_t *type, pr_type_t *value,
void *_data);
static void pr_debug_struct_view (qfot_type_t *type, pr_type_t *value,
void *_data);
static void pr_debug_union_view (qfot_type_t *type, pr_type_t *value,
@ -153,26 +132,20 @@ static void pr_debug_array_view (qfot_type_t *type, pr_type_t *value,
void *_data);
static void pr_debug_class_view (qfot_type_t *type, pr_type_t *value,
void *_data);
#define EV_TYPE(t) \
static void pr_debug_##t##_view (qfot_type_t *type, pr_type_t *value, \
void *_data);
#include "QF/progs/pr_type_names.h"
static type_view_t raw_type_view = {
pr_debug_void_view,
pr_debug_string_view,
pr_debug_float_view,
pr_debug_vector_view,
pr_debug_entity_view,
pr_debug_field_view,
pr_debug_func_view,
pr_debug_pointer_view,
pr_debug_quat_view,
pr_debug_integer_view,
pr_debug_uinteger_view,
pr_debug_short_view,
pr_debug_double_view,
pr_debug_struct_view,
pr_debug_union_view,
pr_debug_enum_view,
pr_debug_array_view,
pr_debug_class_view,
#define EV_TYPE(t) \
pr_debug_##t##_view,
#include "QF/progs/pr_type_names.h"
};
static const char *
@ -261,7 +234,7 @@ pr_debug_type_size (const progs_t *pr, const qfot_type_t *type)
}
return size;
case ty_enum:
return pr_type_size[ev_integer];
return pr_type_size[ev_int];
case ty_array:
aux_type = &G_STRUCT (pr, qfot_type_t, type->array.type);
size = pr_debug_type_size (pr, aux_type);
@ -348,7 +321,7 @@ parse_expression (progs_t *pr, const char *expr, int conditional)
goto error;
if (!Script_GetToken (es, 1))
goto error;
pr->wp_val.integer_var = strtol (es->token->str, &e, 0);
pr->wp_val.int_var = strtol (es->token->str, &e, 0);
if (e == es->token->str)
goto error;
if (*e == '.' || *e == 'e' || *e == 'E')
@ -396,7 +369,7 @@ pr_debug_clear (progs_t *pr, void *data)
pr->watch = 0;
pr->wp_conditional = 0;
pr->wp_val.integer_var = 0;
pr->wp_val.int_var = 0;
for (int i = 0; i < ev_type_count; i++ ) {
res->type_encodings[i] = &res->void_type;
@ -494,10 +467,10 @@ func_compare_sort (const void *_fa, const void *_fb, void *_res)
{
prdeb_resources_t *res = _res;
progs_t *pr = res->pr;
func_t fa = *(const func_t *)_fa;
func_t fb = *(const func_t *)_fb;
const char *fa_file = PR_GetString (pr, pr->pr_functions[fa].s_file);
const char *fb_file = PR_GetString (pr, pr->pr_functions[fb].s_file);
pr_func_t fa = *(const pr_func_t *)_fa;
pr_func_t fb = *(const pr_func_t *)_fb;
const char *fa_file = PR_GetString (pr, pr->pr_functions[fa].file);
const char *fb_file = PR_GetString (pr, pr->pr_functions[fb].file);
int cmp = strcmp (fa_file, fb_file);
if (cmp) {
return cmp;
@ -515,8 +488,8 @@ func_compare_search (const void *_key, const void *_f, void *_res)
prdeb_resources_t *res = _res;
progs_t *pr = res->pr;
const func_key_t *key = _key;
func_t f = *(const func_t *)_f;
const char *f_file = PR_GetString (pr, pr->pr_functions[f].s_file);
pr_func_t f = *(const pr_func_t *)_f;
const char *f_file = PR_GetString (pr, pr->pr_functions[f].file);
int cmp = strcmp (key->file, f_file);
if (cmp) {
return cmp;
@ -538,18 +511,18 @@ PR_DebugSetSym (progs_t *pr, pr_debug_header_t *debug)
res->debug_data = (pr_type_t*)((char*)debug + debug->debug_data);
size_t size;
size = pr->progs->numfunctions * sizeof (pr_auxfunction_t *);
size = pr->progs->functions.count * sizeof (pr_auxfunction_t *);
res->auxfunction_map = pr->allocate_progs_mem (pr, size);
size = pr->progs->numfunctions * sizeof (func_t);
size = pr->progs->functions.count * sizeof (pr_func_t);
res->sorted_functions = pr->allocate_progs_mem (pr, size);
for (pr_uint_t i = 0; i < pr->progs->numfunctions; i++) {
for (pr_uint_t i = 0; i < pr->progs->functions.count; i++) {
res->auxfunction_map[i] = 0;
res->sorted_functions[i] = i;
}
qfot_type_encodings_t *encodings = 0;
pointer_t type_encodings = 0;
pr_ptr_t type_encodings = 0;
res->type_encodings_def = PR_FindGlobal (pr, ".type_encodings");
if (res->type_encodings_def) {
encodings = &G_STRUCT (pr, qfot_type_encodings_t,
@ -564,8 +537,8 @@ PR_DebugSetSym (progs_t *pr, pr_debug_header_t *debug)
res->auxfunction_map[res->auxfunctions[i].function] =
&res->auxfunctions[i];
}
qsort_r (res->sorted_functions, pr->progs->numfunctions, sizeof (func_t),
func_compare_sort, res);
qsort_r (res->sorted_functions, pr->progs->functions.count,
sizeof (pr_func_t), func_compare_sort, res);
for (pr_uint_t i = 0; i < debug->num_locals; i++) {
if (type_encodings) {
@ -573,7 +546,7 @@ PR_DebugSetSym (progs_t *pr, pr_debug_header_t *debug)
}
}
string_t compunit_str = PR_FindString (pr, ".compile_unit");
pr_string_t compunit_str = PR_FindString (pr, ".compile_unit");
for (pr_uint_t i = 0; i < debug->num_debug_defs; i++) {
pr_def_t *def = &res->debug_defs[i];
if (type_encodings) {
@ -587,7 +560,7 @@ PR_DebugSetSym (progs_t *pr, pr_debug_header_t *debug)
if (encodings) {
qfot_type_t *type;
for (pointer_t type_ptr = 4; type_ptr < encodings->size;
for (pr_ptr_t type_ptr = 4; type_ptr < encodings->size;
type_ptr += type->size) {
type = &G_STRUCT (pr, qfot_type_t, type_encodings + type_ptr);
if (type->meta == ty_basic
@ -722,7 +695,7 @@ VISIBLE pr_auxfunction_t *
PR_Debug_MappedAuxFunction (progs_t *pr, pr_uint_t func)
{
prdeb_resources_t *res = pr->pr_debug_resources;
if (!res->debug || func >= pr->progs->numfunctions) {
if (!res->debug || func >= pr->progs->functions.count) {
return 0;
}
return res->auxfunction_map[func];
@ -829,15 +802,15 @@ PR_FindSourceLineAddr (progs_t *pr, const char *file, pr_uint_t line)
{
prdeb_resources_t *res = pr->pr_debug_resources;
func_key_t key = { file, line };
func_t *f = fbsearch_r (&key, res->sorted_functions,
pr->progs->numfunctions, sizeof (func_t),
pr_func_t *f = fbsearch_r (&key, res->sorted_functions,
pr->progs->functions.count, sizeof (pr_func_t),
func_compare_search, res);
if (!f) {
return 0;
}
dfunction_t *func = &pr->pr_functions[*f];
if (func->first_statement <= 0
|| strcmp (file, PR_GetString (pr, func->s_file)) != 0) {
|| strcmp (file, PR_GetString (pr, func->file)) != 0) {
return 0;
}
pr_auxfunction_t *aux = res->auxfunction_map[*f];
@ -867,9 +840,9 @@ PR_Get_Source_File (progs_t *pr, pr_lineno_t *lineno)
pr_auxfunction_t *f;
f = PR_Get_Lineno_Func (pr, lineno);
if (f->function >= (unsigned) pr->progs->numfunctions)
if (f->function >= (unsigned) pr->progs->functions.count)
return 0;
return PR_GetString(pr, pr->pr_functions[f->function].s_file);
return PR_GetString(pr, pr->pr_functions[f->function].file);
}
const char *
@ -903,7 +876,7 @@ PR_Get_Source_Line (progs_t *pr, pr_uint_t addr)
}
pr_def_t *
PR_Get_Param_Def (progs_t *pr, dfunction_t *func, unsigned parm)
PR_Get_Param_Def (progs_t *pr, dfunction_t *func, unsigned param)
{
prdeb_resources_t *res = pr->pr_debug_resources;
pr_uint_t i;
@ -917,12 +890,12 @@ PR_Get_Param_Def (progs_t *pr, dfunction_t *func, unsigned parm)
if (!func)
return 0;
num_params = func->numparms;
num_params = func->numparams;
if (num_params < 0) {
num_params = ~num_params; // one's compliment
param_offs = 1; // skip over @args def
}
if (parm >= (unsigned) num_params)
if (param >= (unsigned) num_params)
return 0;
aux_func = res->auxfunction_map[func - pr->pr_functions];
@ -931,7 +904,7 @@ PR_Get_Param_Def (progs_t *pr, dfunction_t *func, unsigned parm)
for (i = 0; i < aux_func->num_locals; i++) {
ddef = &res->local_defs[aux_func->local_defs + param_offs + i];
if (!parm--)
if (!param--)
break;
}
return ddef;
@ -960,12 +933,12 @@ get_type (prdeb_resources_t *res, int typeptr)
}
pr_def_t *
PR_Get_Local_Def (progs_t *pr, pointer_t *offset)
PR_Get_Local_Def (progs_t *pr, pr_ptr_t *offset)
{
prdeb_resources_t *res = pr->pr_debug_resources;
dfunction_t *func;
pr_auxfunction_t *aux_func;
pointer_t offs = *offset;
pr_ptr_t offs = *offset;
pr_def_t *def;
if (!pr->pr_xfunction)
@ -976,7 +949,19 @@ PR_Get_Local_Def (progs_t *pr, pointer_t *offset)
aux_func = res->auxfunction_map[func - pr->pr_functions];
if (!aux_func)
return 0;
offs -= func->parm_start;
pr_ptr_t locals_start;
if (pr->progs->version == PROG_VERSION) {
if (pr->pr_depth) {
prstack_t *frame = pr->pr_stack + pr->pr_depth - 1;
locals_start = frame->stack_ptr - func->params_start;
} else {
locals_start = 0; //FIXME ? when disassembling in qfprogs
}
} else {
locals_start = func->params_start;
}
offs -= locals_start;
if (offs >= func->locals)
return 0;
if ((def = PR_SearchDefs (res->local_defs + aux_func->local_defs,
@ -1015,51 +1000,18 @@ PR_DumpState (progs_t *pr)
#define ISDENORM(x) ((x) && !((x) & 0x7f800000))
static const char *
static void
value_string (pr_debug_data_t *data, qfot_type_t *type, pr_type_t *value)
{
switch (type->meta) {
case ty_basic:
switch (type->type) {
case ev_void:
raw_type_view.void_view (type, value, data);
break;
case ev_string:
raw_type_view.string_view (type, value, data);
break;
case ev_float:
raw_type_view.float_view (type, value, data);
break;
case ev_vector:
raw_type_view.vector_view (type, value, data);
break;
case ev_entity:
raw_type_view.entity_view (type, value, data);
break;
case ev_field:
raw_type_view.field_view (type, value, data);
break;
case ev_func:
raw_type_view.func_view (type, value, data);
break;
case ev_pointer:
raw_type_view.pointer_view (type, value, data);
break;
case ev_quat:
raw_type_view.quat_view (type, value, data);
break;
case ev_integer:
raw_type_view.integer_view (type, value, data);
break;
case ev_uinteger:
raw_type_view.uinteger_view (type, value, data);
break;
case ev_short:
raw_type_view.short_view (type, value, data);
break;
case ev_double:
raw_type_view.double_view (type, value, data);
#define EV_TYPE(t) \
case ev_##t: \
raw_type_view.t##_view (type, value, data); \
break;
#include "QF/progs/pr_type_names.h"
case ev_invalid:
case ev_type_count:
dstring_appendstr (data->dstr, "<?""?>");
@ -1082,23 +1034,23 @@ value_string (pr_debug_data_t *data, qfot_type_t *type, pr_type_t *value)
break;
case ty_alias://XXX
type = &G_STRUCT (data->pr, qfot_type_t, type->alias.aux_type);
return value_string (data, type, value);
value_string (data, type, value);
break;
}
return data->dstr->str;
}
static pr_def_t *
pr_debug_find_def (progs_t *pr, pointer_t *ofs)
pr_debug_find_def (progs_t *pr, pr_ptr_t *ofs)
{
prdeb_resources_t *res = pr->pr_debug_resources;
pr_def_t *def = 0;
if (*ofs >= pr->progs->numglobals) {
return 0;
}
if (pr_debug->int_val && res->debug) {
def = PR_Get_Local_Def (pr, ofs);
}
if (*ofs >= pr->progs->globals.count) {
return 0;
}
if (!def) {
def = PR_GlobalAtOfs (pr, *ofs);
if (def) {
@ -1109,7 +1061,7 @@ pr_debug_find_def (progs_t *pr, pointer_t *ofs)
}
static const char *
global_string (pr_debug_data_t *data, pointer_t offset, qfot_type_t *type,
global_string (pr_debug_data_t *data, pr_ptr_t offset, qfot_type_t *type,
int contents)
{
progs_t *pr = data->pr;
@ -1118,7 +1070,7 @@ global_string (pr_debug_data_t *data, pointer_t offset, qfot_type_t *type,
pr_def_t *def = NULL;
qfot_type_t dummy_type = { };
const char *name = 0;
pointer_t offs = offset;
pr_ptr_t offs = offset;
dstring_clearstr (dstr);
@ -1184,7 +1136,7 @@ pr_debug_string_view (qfot_type_t *type, pr_type_t *value, void *_data)
{
__auto_type data = (pr_debug_data_t *) _data;
dstring_t *dstr = data->dstr;
string_t string = value->string_var;
pr_string_t string = value->string_var;
if (PR_StringValid (data->pr, string)) {
const char *str = PR_GetString (data->pr, string);
@ -1228,9 +1180,9 @@ pr_debug_float_view (qfot_type_t *type, pr_type_t *value, void *_data)
dstring_t *dstr = data->dstr;
if (data->pr->progs->version == PROG_ID_VERSION
&& ISDENORM (value->integer_var)
&& value->uinteger_var != 0x80000000) {
dasprintf (dstr, "<%08x>", value->integer_var);
&& ISDENORM (value->int_var)
&& value->uint_var != 0x80000000) {
dasprintf (dstr, "<%08x>", value->int_var);
} else {
dasprintf (dstr, "%.9g", value->float_var);
}
@ -1252,7 +1204,7 @@ pr_debug_entity_view (qfot_type_t *type, pr_type_t *value, void *_data)
progs_t *pr = data->pr;
dstring_t *dstr = data->dstr;
if (pr->pr_edicts && value->entity_var >= 0
if (pr->pr_edicts
&& value->entity_var < pr->max_edicts
&& !(value->entity_var % pr->pr_edict_size)) {
edict_t *edict = PROG_TO_EDICT (pr, value->entity_var);
@ -1270,12 +1222,12 @@ pr_debug_field_view (qfot_type_t *type, pr_type_t *value, void *_data)
__auto_type data = (pr_debug_data_t *) _data;
progs_t *pr = data->pr;
dstring_t *dstr = data->dstr;
pr_def_t *def = PR_FieldAtOfs (pr, value->integer_var);
pr_def_t *def = PR_FieldAtOfs (pr, value->int_var);
if (def) {
dasprintf (dstr, ".%s", PR_GetString (pr, def->name));
} else {
dasprintf (dstr, ".<$%04x>", value->integer_var);
dasprintf (dstr, ".<$%04x>", value->int_var);
}
}
@ -1286,24 +1238,24 @@ pr_debug_func_view (qfot_type_t *type, pr_type_t *value, void *_data)
progs_t *pr = data->pr;
dstring_t *dstr = data->dstr;
if (value->func_var >= pr->progs->numfunctions) {
if (value->func_var >= pr->progs->functions.count) {
dasprintf (dstr, "INVALID:%d", value->func_var);
} else if (!value->func_var) {
dstring_appendstr (dstr, "NULL");
} else {
dfunction_t *f = pr->pr_functions + value->func_var;
dasprintf (dstr, "%s()", PR_GetString (pr, f->s_name));
dasprintf (dstr, "%s()", PR_GetString (pr, f->name));
}
}
static void
pr_debug_pointer_view (qfot_type_t *type, pr_type_t *value, void *_data)
pr_debug_ptr_view (qfot_type_t *type, pr_type_t *value, void *_data)
{
__auto_type data = (pr_debug_data_t *) _data;
progs_t *pr = data->pr;
dstring_t *dstr = data->dstr;
pointer_t offset = value->integer_var;
pointer_t offs = offset;
pr_ptr_t offset = value->int_var;
pr_ptr_t offs = offset;
pr_def_t *def = 0;
def = pr_debug_find_def (pr, &offs);
@ -1319,7 +1271,7 @@ pr_debug_pointer_view (qfot_type_t *type, pr_type_t *value, void *_data)
}
static void
pr_debug_quat_view (qfot_type_t *type, pr_type_t *value, void *_data)
pr_debug_quaternion_view (qfot_type_t *type, pr_type_t *value, void *_data)
{
__auto_type data = (pr_debug_data_t *) _data;
dstring_t *dstr = data->dstr;
@ -1328,21 +1280,21 @@ pr_debug_quat_view (qfot_type_t *type, pr_type_t *value, void *_data)
}
static void
pr_debug_integer_view (qfot_type_t *type, pr_type_t *value, void *_data)
pr_debug_int_view (qfot_type_t *type, pr_type_t *value, void *_data)
{
__auto_type data = (pr_debug_data_t *) _data;
dstring_t *dstr = data->dstr;
dasprintf (dstr, "%d", value->integer_var);
dasprintf (dstr, "%d", value->int_var);
}
static void
pr_debug_uinteger_view (qfot_type_t *type, pr_type_t *value, void *_data)
pr_debug_uint_view (qfot_type_t *type, pr_type_t *value, void *_data)
{
__auto_type data = (pr_debug_data_t *) _data;
dstring_t *dstr = data->dstr;
dasprintf (dstr, "$%08x", value->uinteger_var);
dasprintf (dstr, "$%08x", value->uint_var);
}
static void
@ -1351,7 +1303,7 @@ pr_debug_short_view (qfot_type_t *type, pr_type_t *value, void *_data)
__auto_type data = (pr_debug_data_t *) _data;
dstring_t *dstr = data->dstr;
dasprintf (dstr, "%04x", (short)value->integer_var);
dasprintf (dstr, "%04x", (short)value->int_var);
}
static void
@ -1363,6 +1315,33 @@ pr_debug_double_view (qfot_type_t *type, pr_type_t *value, void *_data)
dasprintf (dstr, "%.17g", *(double *)value);
}
static void
pr_debug_long_view (qfot_type_t *type, pr_type_t *value, void *_data)
{
__auto_type data = (pr_debug_data_t *) _data;
dstring_t *dstr = data->dstr;
dasprintf (dstr, "%" PRIi64, *(int64_t *)value);
}
static void
pr_debug_ulong_view (qfot_type_t *type, pr_type_t *value, void *_data)
{
__auto_type data = (pr_debug_data_t *) _data;
dstring_t *dstr = data->dstr;
dasprintf (dstr, "%" PRIu64, *(uint64_t *)value);
}
static void
pr_debug_ushort_view (qfot_type_t *type, pr_type_t *value, void *_data)
{
__auto_type data = (pr_debug_data_t *) _data;
dstring_t *dstr = data->dstr;
dasprintf (dstr, "%04x", (pr_ushort_t)value->int_var);
}
static void
pr_dump_struct (qfot_type_t *type, pr_type_t *value, void *_data,
const char *struct_type)
@ -1436,7 +1415,7 @@ PR_Debug_Watch (progs_t *pr, const char *expr)
(int) (intptr_t) (pr->watch - pr->pr_globals));
if (pr->wp_conditional)
Sys_Printf (" if new val == %d\n",
pr->wp_val.integer_var);
pr->wp_val.int_var);
} else { Sys_Printf (" none active\n");
}
return;
@ -1449,7 +1428,7 @@ PR_Debug_Watch (progs_t *pr, const char *expr)
if (pr->watch) {
Sys_Printf ("watchpoint set to [%d]\n", PR_SetPointer (pr, pr->watch));
if (pr->wp_conditional)
Sys_Printf (" if new val == %d\n", pr->wp_val.integer_var);
Sys_Printf (" if new val == %d\n", pr->wp_val.int_var);
} else {
Sys_Printf ("watchpoint cleared\n");
}
@ -1475,6 +1454,18 @@ PR_Debug_Print (progs_t *pr, const char *expr)
}
}
static const char *
print_raw_op (progs_t *pr, pr_ushort_t op, pr_ushort_t base_ind,
etype_t op_type, int op_width)
{
prdeb_resources_t *res = pr->pr_debug_resources;
const char *width = va (res->va, "%d", op_width);
return va (res->va, "%d:%04x<%08x>%s:%-8s",
base_ind, op, op + pr->pr_bases[base_ind],
op_width > 0 ? width : op_width < 0 ? "X" : "?",
pr_type_name[op_type]);
}
VISIBLE void
PR_PrintStatement (progs_t *pr, dstatement_t *s, int contents)
{
@ -1482,11 +1473,13 @@ PR_PrintStatement (progs_t *pr, dstatement_t *s, int contents)
int addr = s - pr->pr_statements;
int dump_code = contents & 2;
const char *fmt;
opcode_t *op;
const char *mnemonic;
dfunction_t *call_func = 0;
pr_def_t *parm_def = 0;
pr_def_t *param_def = 0;
pr_auxfunction_t *aux_func = 0;
pr_debug_data_t data;
etype_t op_type[3];
int op_width[3];
dstring_clearstr (res->line);
@ -1508,24 +1501,54 @@ PR_PrintStatement (progs_t *pr, dstatement_t *s, int contents)
return;
}
op = PR_Opcode (s->op);
if (!op) {
Sys_Printf ("%sUnknown instruction %d\n", res->line->str, s->op);
return;
if (pr->progs->version < PROG_VERSION) {
const v6p_opcode_t *op = PR_v6p_Opcode (s->op);
if (!op) {
Sys_Printf ("%sUnknown instruction %d\n", res->line->str, s->op);
return;
}
VectorSet (op->type_a, op->type_b, op->type_c, op_type);
VectorSet (1, 1, 1, op_width);
fmt = op->fmt;
mnemonic = op->opname;
} else {
const opcode_t *op = PR_Opcode (s->op);
if (!op) {
Sys_Printf ("%sUnknown instruction %d\n", res->line->str, s->op);
return;
}
VectorCopy (op->widths, op_width);
VectorCopy (op->types, op_type);
fmt = op->fmt;
mnemonic = op->mnemonic;
}
if (!(fmt = op->fmt))
if (!fmt) {
fmt = "%Ga, %Gb, %gc";
}
dasprintf (res->line, "%04x ", addr);
if (pr_debug->int_val > 2)
dasprintf (res->line, "%02x %04x(%8s) %04x(%8s) %04x(%8s)\t",
s->op,
s->a, pr_type_name[op->type_a],
s->b, pr_type_name[op->type_b],
s->c, pr_type_name[op->type_c]);
if (pr_debug->int_val > 2) {
if (pr->progs->version < PROG_VERSION) {
dasprintf (res->line,
"%03x %04x(%8s) %04x(%8s) %04x(%8s)\t",
s->op,
s->a, pr_type_name[op_type[0]],
s->b, pr_type_name[op_type[1]],
s->c, pr_type_name[op_type[2]]);
} else {
dasprintf (res->line, "%04x %s %s %s\t",
s->op,
print_raw_op (pr, s->a, PR_BASE_IND (s->op, A),
op_type[0], op_width[0]),
print_raw_op (pr, s->b, PR_BASE_IND (s->op, B),
op_type[0], op_width[0]),
print_raw_op (pr, s->c, PR_BASE_IND (s->op, C),
op_type[0], op_width[0]));
}
}
dasprintf (res->line, "%s ", op->opname);
dasprintf (res->line, "%s ", mnemonic);
while (*fmt) {
if (*fmt == '%') {
@ -1535,38 +1558,57 @@ PR_PrintStatement (progs_t *pr, dstatement_t *s, int contents)
} else {
const char *str;
char mode = fmt[1], opchar = fmt[2];
unsigned parm_ind = 0;
pr_int_t opval;
unsigned param_ind = 0;
pr_uint_t shift = 0;
pr_uint_t opreg;
pr_uint_t opval;
qfot_type_t *optype = &res->void_type;
func_t func;
pr_func_t func;
if (mode == 'P') {
opchar = fmt[3];
parm_ind = fmt[2] - '0';
param_ind = fmt[2] - '0';
fmt++; // P has one extra item
if (parm_ind >= MAX_PARMS)
if (param_ind >= PR_MAX_PARAMS)
goto err;
}
if (mode == 'M' || mode == 'm') {
if (!isxdigit (fmt[3])) {
goto err;
}
shift = fmt[3];
shift = (shift & 0xf)
+ (((shift & 0x40) >> 3) | ((shift & 0x40) >> 5));
fmt++; // M/m have one extra item
}
switch (opchar) {
case 'a':
opreg = PR_BASE_IND (s->op, A);
opval = s->a;
optype = res->type_encodings[op->type_a];
optype = res->type_encodings[op_type[0]];
break;
case 'b':
opreg = PR_BASE_IND (s->op, B);
opval = s->b;
optype = res->type_encodings[op->type_b];
optype = res->type_encodings[op_type[1]];
break;
case 'c':
opreg = PR_BASE_IND (s->op, C);
opval = s->c;
optype = res->type_encodings[op->type_c];
optype = res->type_encodings[op_type[2]];
break;
case 'o':
opreg = 0;
opval = s->op;
break;
case 'x':
if (mode == 'P') {
opval = pr->pr_real_params[parm_ind]
opval = pr->pr_real_params[param_ind]
- pr->pr_globals;
break;
}
goto err;
default:
goto err;
}
@ -1584,28 +1626,31 @@ PR_PrintStatement (progs_t *pr, dstatement_t *s, int contents)
str = global_string (&data, opval, optype,
contents & 1);
func = G_FUNCTION (pr, opval);
if (func < pr->progs->numfunctions) {
if (func < pr->progs->functions.count) {
call_func = pr->pr_functions + func;
}
break;
case 'P':
parm_def = PR_Get_Param_Def (pr, call_func, parm_ind);
param_def = PR_Get_Param_Def (pr, call_func, param_ind);
optype = &res->void_type;
if (parm_def) {
optype = get_type (res, parm_def->type_encoding);
if (param_def) {
optype = get_type (res, param_def->type_encoding);
}
str = global_string (&data, opval, optype,
contents & 1);
break;
case 'V':
opval += pr->pr_bases[opreg];
str = global_string (&data, opval, ev_void,
contents & 1);
break;
case 'G':
opval += pr->pr_bases[opreg];
str = global_string (&data, opval, optype,
contents & 1);
break;
case 'g':
opval += pr->pr_bases[opreg];
str = global_string (&data, opval, optype, 0);
break;
case 's':
@ -1615,16 +1660,19 @@ PR_PrintStatement (progs_t *pr, dstatement_t *s, int contents)
str = dsprintf (res->dva, "%04x",
addr + (short) opval);
break;
case 'C':
str = dsprintf (res->dva, "%03o", opval);
break;
case 'E':
{
edict_t *ed = 0;
opval = pr->pr_globals[s->a].entity_var;
parm_ind = pr->pr_globals[s->b].uinteger_var;
if (parm_ind < pr->progs->entityfields
param_ind = pr->pr_globals[s->b].uint_var;
if (param_ind < pr->progs->entityfields
&& opval > 0
&& opval < pr->pr_edict_area_size) {
ed = PROG_TO_EDICT (pr, opval);
opval = &E_fld(ed, parm_ind) - pr->pr_globals;
opval = &E_fld(ed, param_ind) - pr->pr_globals;
}
if (!ed) {
str = "bad entity.field";
@ -1636,6 +1684,34 @@ PR_PrintStatement (progs_t *pr, dstatement_t *s, int contents)
s->a, s->b, str);
}
break;
case 'M':
case 'm':
{
pr_ptr_t ptr = 0;
pr_int_t offs = 0;
switch ((opval >> shift) & 3) {
case 0:
ptr = s->a + PR_BASE (pr, s, A);
break;
case 1:
break;
case 2:
ptr = s->a + PR_BASE (pr, s, A);
ptr = G_POINTER (pr, ptr);
offs = (short) s->b;
break;
case 3:
ptr = s->a + PR_BASE (pr, s, A);
ptr = G_POINTER (pr, ptr);
offs = s->b + PR_BASE (pr, s, B);
offs = G_INT (pr, offs);
break;
}
ptr += offs;
str = global_string (&data, ptr, optype,
mode == 'M');
}
break;
default:
goto err;
}
@ -1668,25 +1744,25 @@ dump_frame (progs_t *pr, prstack_t *frame)
pr_lineno_t *lineno = PR_Find_Lineno (pr, frame->staddr);
pr_auxfunction_t *func = PR_Get_Lineno_Func (pr, lineno);
pr_uint_t line = PR_Get_Lineno_Line (pr, lineno);
pr_int_t addr = PR_Get_Lineno_Addr (pr, lineno);
pr_uint_t addr = PR_Get_Lineno_Addr (pr, lineno);
line += func->source_line;
if (addr == frame->staddr) {
Sys_Printf ("%12s:%u : %s: %x\n",
PR_GetString (pr, f->s_file),
PR_GetString (pr, f->file),
line,
PR_GetString (pr, f->s_name),
PR_GetString (pr, f->name),
frame->staddr);
} else {
Sys_Printf ("%12s:%u+%d : %s: %x\n",
PR_GetString (pr, f->s_file),
PR_GetString (pr, f->file),
line, frame->staddr - addr,
PR_GetString (pr, f->s_name),
PR_GetString (pr, f->name),
frame->staddr);
}
} else {
Sys_Printf ("%12s : %s: %x\n", PR_GetString (pr, f->s_file),
PR_GetString (pr, f->s_name), frame->staddr);
Sys_Printf ("%12s : %s: %x\n", PR_GetString (pr, f->file),
PR_GetString (pr, f->name), frame->staddr);
}
}
@ -1711,15 +1787,21 @@ PR_StackTrace (progs_t *pr)
VISIBLE void
PR_Profile (progs_t * pr)
{
pr_uint_t max, num, i;
pr_ulong_t max, num, i;
pr_ulong_t total;
dfunction_t *f;
bfunction_t *best, *bf;
num = 0;
total = 0;
for (i = 0; i < pr->progs->functions.count; i++) {
bf = &pr->function_table[i];
total += bf->profile;
}
do {
max = 0;
best = NULL;
for (i = 0; i < pr->progs->numfunctions; i++) {
for (i = 0; i < pr->progs->functions.count; i++) {
bf = &pr->function_table[i];
if (bf->profile > max) {
max = bf->profile;
@ -1729,13 +1811,15 @@ PR_Profile (progs_t * pr)
if (best) {
if (num < 10) {
f = pr->pr_functions + (best - pr->function_table);
Sys_Printf ("%7i %s\n", best->profile,
PR_GetString (pr, f->s_name));
Sys_Printf ("%7"PRIu64" %s%s\n", best->profile,
PR_GetString (pr, f->name),
f->first_statement < 0 ? " (builtin)" : "");
}
num++;
best->profile = 0;
}
} while (best);
Sys_Printf ("total: %7"PRIu64"\n", total);
}
static void
@ -1791,7 +1875,7 @@ ED_Print (progs_t *pr, edict_t *ed, const char *fieldname)
}
return;
}
for (i = 0; i < pr->progs->numfielddefs; i++) {
for (i = 0; i < pr->progs->fielddefs.count; i++) {
d = &pr->pr_fielddefs[i];
if (!d->name) // null field def (probably 1st)
continue;
@ -1824,6 +1908,7 @@ PR_Debug_Init (progs_t *pr)
res->dva = dstring_newstr ();
res->line = dstring_newstr ();
res->dstr = dstring_newstr ();
res->va = va_create_context (8);
res->void_type.meta = ty_basic;
res->void_type.size = 4;

View file

@ -68,7 +68,7 @@ ED_ClearEdict (progs_t *pr, edict_t *e, int val)
VISIBLE edict_t *
ED_Alloc (progs_t *pr)
{
pr_int_t i;
pr_uint_t i;
edict_t *e;
int start = pr->reserved_edicts ? *pr->reserved_edicts : 0;
@ -79,9 +79,9 @@ ED_Alloc (progs_t *pr)
e = EDICT_NUM (pr, i);
// the first couple seconds of server time can involve a lot of
// freeing and allocating, so relax the replacement policy
if (e->free && (!pr->globals.time
if (e->free && (!pr->globals.ftime//FIXME double time
|| e->freetime < 2
|| *pr->globals.time - e->freetime > 0.5)) {
|| *pr->globals.ftime - e->freetime > 0.5)) {
ED_ClearEdict (pr, e, 0);
return e;
}
@ -123,8 +123,8 @@ ED_Free (progs_t *pr, edict_t *ed)
ED_ClearEdict (pr, ed, 0);
}
ed->free = true;
if (pr->globals.time)
ed->freetime = *pr->globals.time;
if (pr->globals.ftime)//FIXME double time
ed->freetime = *pr->globals.ftime;
}
//===========================================================================
@ -149,7 +149,7 @@ ED_PrintNum (progs_t *pr, pr_int_t ent, const char *fieldname)
VISIBLE void
ED_PrintEdicts (progs_t *pr, const char *fieldval)
{
pr_int_t i;
pr_uint_t i;
int count;
pr_def_t *def;
@ -183,7 +183,6 @@ ED_PrintEdicts (progs_t *pr, const char *fieldval)
VISIBLE void
ED_Count (progs_t *pr)
{
pr_int_t i;
int active, models, solid, step, zombie;
pr_def_t *solid_def;
pr_def_t *model_def;
@ -196,10 +195,10 @@ ED_Count (progs_t *pr)
solid_def = PR_FindField (pr, "solid");
model_def = PR_FindField (pr, "model");
active = models = solid = step = zombie = 0;
for (i = 0; i < *pr->num_edicts; i++) {
for (pr_uint_t i = 0; i < *pr->num_edicts; i++) {
ent = EDICT_NUM (pr, i);
if (ent->free) {
if (pr->globals.time && *pr->globals.time - ent->freetime <= 0.5)
if (pr->globals.ftime && *pr->globals.ftime - ent->freetime <= 0.5)//FIXME double time
zombie++;
continue;
}
@ -218,22 +217,22 @@ ED_Count (progs_t *pr)
}
edict_t *
ED_EdictNum (progs_t *pr, pr_int_t n)
ED_EdictNum (progs_t *pr, pr_uint_t n)
{
if (n < 0 || n >= *pr->num_edicts)
if (n >= *pr->num_edicts)
PR_RunError (pr, "EDICT_NUM: bad number %d", n);
return PR_edicts(pr) + n;
}
pr_int_t
pr_uint_t
ED_NumForEdict (progs_t *pr, edict_t *e)
{
pr_int_t b;
pr_uint_t b;
b = NUM_FOR_BAD_EDICT (pr, e);
if (b && (b < 0 || b >= *pr->num_edicts))
if (b && b >= *pr->num_edicts)
PR_RunError (pr, "NUM_FOR_EDICT: bad pointer %d %p %p", b, e,
pr->pr_edicts);
@ -241,12 +240,12 @@ ED_NumForEdict (progs_t *pr, edict_t *e)
}
qboolean
PR_EdictValid (progs_t *pr, pr_int_t e)
PR_EdictValid (progs_t *pr, pr_uint_t e)
{
if (!pr->num_edicts) {
return false;
}
if (e < 0 || e >= pr->pr_edict_area_size)
if (e >= pr->pr_edict_area_size)
return false;
if (e % pr->pr_edict_size)
return false;

File diff suppressed because it is too large Load diff

View file

@ -46,6 +46,8 @@
#include "QF/sys.h"
#include "QF/zone.h"
#include "QF/progs/pr_type.h"
#include "compat.h"
VISIBLE cvar_t *pr_boundscheck;
@ -58,7 +60,7 @@ function_get_key (const void *f, void *_pr)
{
progs_t *pr = (progs_t*)_pr;
dfunction_t *func = (dfunction_t*)f;
return PR_GetString (pr, func->s_name);
return PR_GetString (pr, func->name);
}
static const char *
@ -69,6 +71,14 @@ var_get_key (const void *d, void *_pr)
return PR_GetString (pr, def->name);
}
static const char *
type_get_key (const void *t, void *_pr)
{
progs_t *pr = (progs_t *) _pr;
__auto_type type = (qfot_type_t *) t;
return PR_GetString (pr, type->encoding);
}
static void
file_error (progs_t *pr, const char *path)
{
@ -95,13 +105,10 @@ free_progs_mem (progs_t *pr, void *mem)
}
static int
align_size (int size)
align_size (int size, int align)
{
// round off to next highest whole word address (esp for Alpha)
// this ensures that pointers in the engine data area are always
// properly aligned
size += sizeof (void*) - 1;
size &= ~(sizeof (void*) - 1);
size += align - 1;
size &= ~(align - 1);
return size;
}
@ -114,9 +121,10 @@ PR_LoadProgsFile (progs_t *pr, QFile *file, int size)
dprograms_t progs;
byte *base;
byte *heap;
pr_def_t *xdefs_def = 0;
ddef_t *global_ddefs;
ddef_t *field_ddefs;
// absolute minimum alignment is 4 bytes
int alignment = sizeof (void *);
if (!pr->file_error)
pr->file_error = file_error;
@ -145,6 +153,7 @@ PR_LoadProgsFile (progs_t *pr, QFile *file, int size)
((int *) &progs)[i] = LittleLong (((int *) &progs)[i]);
if (progs.version != PROG_VERSION
&& progs.version != PROG_V6P_VERSION
&& progs.version != PROG_ID_VERSION) {
if (progs.version < 0x00fff000) {
PR_Error (pr, "%s has unrecognised version number (%u)",
@ -162,31 +171,36 @@ PR_LoadProgsFile (progs_t *pr, QFile *file, int size)
PROG_VERSION & 0xfff);
}
}
if (progs.version == PROG_VERSION) {
// ensure SIMD types can be aligned (qfcc will align them within
// the progs memory map, so the engine needs to ensure the progs memory
// is aligned)
alignment = __alignof__(pr_lvec4_t);
}
// Some compilers (eg, FTE) put extra data between the header and the
// strings section. What's worse, they de-align the data.
offset_tweak = progs.ofs_strings % sizeof (pr_int_t);
offset_tweak = progs.strings.offset % sizeof (pr_int_t);
offset_tweak = (sizeof (pr_int_t) - offset_tweak) % sizeof (pr_int_t);
// size of progs themselves
pr->progs_size = size + offset_tweak;
Sys_MaskPrintf (SYS_dev, "Programs occupy %iK.\n", size / 1024);
pr->progs_size = align_size (pr->progs_size);
pr->zone_size = align_size (pr->zone_size);
pr->stack_size = align_size (pr->stack_size);
pr->progs_size = align_size (pr->progs_size, alignment);
pr->zone_size = align_size (pr->zone_size, alignment);
pr->stack_size = align_size (pr->stack_size, alignment);
// size of edict asked for by progs, but at least 1
pr->pr_edict_size = max (1, progs.entityfields);
// round off to next highest multiple of 4 words
// this ensures that progs that try to align vectors and quaternions
// get what they want
pr->pr_edict_size += (4 - 1);
pr->pr_edict_size &= ~(4 - 1);
// edict size is in words
pr->pr_edict_size = align_size (pr->pr_edict_size, alignment / 4);
pr->pr_edict_area_size = pr->max_edicts * pr->pr_edict_size;
mem_size = pr->pr_edict_area_size * sizeof (pr_type_t);
mem_size += pr->progs_size + pr->zone_size + pr->stack_size;
// space for return buffer
mem_size += PR_MAX_RETURN * sizeof (pr_type_t);
// +1 for a nul terminator
pr->progs = pr->allocate_progs_mem (pr, mem_size + 1);
@ -213,18 +227,22 @@ PR_LoadProgsFile (progs_t *pr, QFile *file, int size)
pr->zone = (memzone_t *) heap;
}
pr->pr_functions = (dfunction_t *) (base + pr->progs->ofs_functions);
pr->pr_strings = (char *) base + pr->progs->ofs_strings;
pr->pr_functions = (dfunction_t *) (base + pr->progs->functions.offset);
pr->pr_strings = (char *) base + pr->progs->strings.offset;
pr->pr_stringsize = (heap - base) + pr->zone_size;
global_ddefs = (ddef_t *) (base + pr->progs->ofs_globaldefs);
field_ddefs = (ddef_t *) (base + pr->progs->ofs_fielddefs);
pr->pr_statements = (dstatement_t *) (base + pr->progs->ofs_statements);
global_ddefs = (ddef_t *) (base + pr->progs->globaldefs.offset);
field_ddefs = (ddef_t *) (base + pr->progs->fielddefs.offset);
pr->pr_statements = (dstatement_t *) (base + pr->progs->statements.offset);
pr->pr_globals = (pr_type_t *) (base + pr->progs->ofs_globals);
pr->pr_globals = (pr_type_t *) (base + pr->progs->globals.offset);
pr->stack = (pr_type_t *) ((byte *) pr->zone + pr->zone_size);
pr->stack_bottom = pr->stack - pr->pr_globals;
pr->globals_size = (pr_type_t *) ((byte *) pr->stack + pr->stack_size)
- pr->pr_globals;
if (pr->globals.stack && pr->stack_bottom) {
*pr->globals.stack = pr->globals_size;
}
pr->pr_return_buffer = pr->pr_globals + pr->globals_size;
if (pr->zone) {
PR_Zone_Init (pr);
@ -233,89 +251,105 @@ PR_LoadProgsFile (progs_t *pr, QFile *file, int size)
Hash_FlushTable (pr->function_hash);
Hash_FlushTable (pr->global_hash);
Hash_FlushTable (pr->field_hash);
Hash_FlushTable (pr->type_hash);
// byte swap the lumps
for (i = 0; i < pr->progs->numstatements; i++) {
for (i = 0; i < pr->progs->statements.count; i++) {
pr->pr_statements[i].op = LittleShort (pr->pr_statements[i].op);
pr->pr_statements[i].a = LittleShort (pr->pr_statements[i].a);
pr->pr_statements[i].b = LittleShort (pr->pr_statements[i].b);
pr->pr_statements[i].c = LittleShort (pr->pr_statements[i].c);
}
for (i = 0; i < pr->progs->numfunctions; i++) {
for (i = 0; i < pr->progs->functions.count; i++) {
pr->pr_functions[i].first_statement =
LittleLong (pr->pr_functions[i].first_statement);
pr->pr_functions[i].parm_start =
LittleLong (pr->pr_functions[i].parm_start);
pr->pr_functions[i].s_name = LittleLong (pr->pr_functions[i].s_name);
pr->pr_functions[i].s_file = LittleLong (pr->pr_functions[i].s_file);
pr->pr_functions[i].numparms =
LittleLong (pr->pr_functions[i].numparms);
pr->pr_functions[i].params_start =
LittleLong (pr->pr_functions[i].params_start);
pr->pr_functions[i].name = LittleLong (pr->pr_functions[i].name);
pr->pr_functions[i].file = LittleLong (pr->pr_functions[i].file);
pr->pr_functions[i].numparams =
LittleLong (pr->pr_functions[i].numparams);
pr->pr_functions[i].locals = LittleLong (pr->pr_functions[i].locals);
if (pr->pr_functions[i].s_name)
if (pr->pr_functions[i].name)
Hash_Add (pr->function_hash, &pr->pr_functions[i]);
}
if (pr->pr_globaldefs) {
free (pr->pr_globaldefs);
}
pr->pr_globaldefs = calloc (pr->progs->numglobaldefs, sizeof (pr_def_t));
pr->pr_globaldefs = calloc (pr->progs->globaldefs.count, sizeof (pr_def_t));
for (i = 0; i < pr->progs->numglobaldefs; i++) {
for (i = 0; i < pr->progs->globaldefs.count; i++) {
pr_ushort_t safe_type = global_ddefs[i].type & ~DEF_SAVEGLOBAL;
global_ddefs[i].type = LittleShort (global_ddefs[i].type);
global_ddefs[i].ofs = LittleShort (global_ddefs[i].ofs);
global_ddefs[i].s_name = LittleLong (global_ddefs[i].s_name);
global_ddefs[i].name = LittleLong (global_ddefs[i].name);
pr->pr_globaldefs[i].type = global_ddefs[i].type;
pr->pr_globaldefs[i].size = pr_type_size[safe_type];
pr->pr_globaldefs[i].ofs = global_ddefs[i].ofs;
pr->pr_globaldefs[i].name = global_ddefs[i].s_name;
pr->pr_globaldefs[i].name = global_ddefs[i].name;
Hash_Add (pr->global_hash, &pr->pr_globaldefs[i]);
}
if (pr->pr_fielddefs) {
free (pr->pr_fielddefs);
}
pr->pr_fielddefs = calloc (pr->progs->numfielddefs, sizeof (pr_def_t));
for (i = 0; i < pr->progs->numfielddefs; i++) {
pr->pr_fielddefs = calloc (pr->progs->fielddefs.count, sizeof (pr_def_t));
for (i = 0; i < pr->progs->fielddefs.count; i++) {
field_ddefs[i].type = LittleShort (field_ddefs[i].type);
if (field_ddefs[i].type & DEF_SAVEGLOBAL)
PR_Error (pr, "PR_LoadProgs: DEF_SAVEGLOBAL on field def %zd", i);
field_ddefs[i].ofs = LittleShort (field_ddefs[i].ofs);
field_ddefs[i].s_name = LittleLong (field_ddefs[i].s_name);
field_ddefs[i].name = LittleLong (field_ddefs[i].name);
pr->pr_fielddefs[i].type = field_ddefs[i].type;
pr->pr_fielddefs[i].ofs = field_ddefs[i].ofs;
pr->pr_fielddefs[i].name = field_ddefs[i].s_name;
pr->pr_fielddefs[i].name = field_ddefs[i].name;
Hash_Add (pr->field_hash, &pr->pr_fielddefs[i]);
}
for (i = 0; i < pr->progs->numglobals; i++)
for (i = 0; i < pr->progs->globals.count; i++)
((int *) pr->pr_globals)[i] = LittleLong (((int *) pr->pr_globals)[i]);
xdefs_def = PR_FindGlobal (pr, ".xdefs");
pr_def_t *types_def = PR_FindGlobal (pr, ".type_encodings");
if (types_def) {
__auto_type encodings = &G_STRUCT (pr, qfot_type_encodings_t,
types_def->ofs);
pr->type_encodings = encodings->types;
qfot_type_t *type;
for (pr_ptr_t type_ptr = 4; type_ptr < encodings->size;
type_ptr += type->size) {
type = &G_STRUCT (pr, qfot_type_t, pr->type_encodings + type_ptr);
Hash_Add (pr->type_hash, type);
}
} else {
pr->type_encodings = 0;
}
pr_def_t *xdefs_def = PR_FindGlobal (pr, ".xdefs");
if (xdefs_def) {
pr_xdefs_t *xdefs = &G_STRUCT (pr, pr_xdefs_t, xdefs_def->ofs);
xdef_t *xdef = &G_STRUCT (pr, xdef_t, xdefs->xdefs);
pr_def_t *def;
for (def = pr->pr_globaldefs, i = 0; i < pr->progs->numglobaldefs;
for (def = pr->pr_globaldefs, i = 0; i < pr->progs->globaldefs.count;
i++, xdef++, def++) {
def->ofs = xdef->ofs;
def->type_encoding = xdef->type;
}
for (def = pr->pr_fielddefs, i = 0; i < pr->progs->numfielddefs;
for (def = pr->pr_fielddefs, i = 0; i < pr->progs->fielddefs.count;
i++, xdef++, def++) {
def->ofs = xdef->ofs;
def->type_encoding = xdef->type;
}
} else {
pr_def_t *def;
for (def = pr->pr_globaldefs, i = 0; i < pr->progs->numglobaldefs;
for (def = pr->pr_globaldefs, i = 0; i < pr->progs->globaldefs.count;
i++, def++) {
def->size = pr_type_size[def->type & ~DEF_SAVEGLOBAL];
}
for (def = pr->pr_fielddefs, i = 0; i < pr->progs->numfielddefs;
for (def = pr->pr_fielddefs, i = 0; i < pr->progs->fielddefs.count;
i++, def++) {
def->size = pr_type_size[def->type & ~DEF_SAVEGLOBAL];
}
@ -363,9 +397,9 @@ pr_run_ctors (progs_t *pr)
pr_uint_t fnum;
dfunction_t *func;
for (fnum = 0; fnum < pr->progs->numfunctions; fnum++) {
for (fnum = 0; fnum < pr->progs->functions.count; fnum++) {
func = pr->pr_functions + fnum;
if (strequal (PR_GetString (pr, func->s_name), ".ctor"))
if (strequal (PR_GetString (pr, func->name), ".ctor"))
PR_ExecuteProgram (pr, fnum);
}
return 1;
@ -478,7 +512,6 @@ PR_Init_Cvars (void)
VISIBLE void
PR_Init (progs_t *pr)
{
PR_Opcode_Init (); // idempotent
PR_Resources_Init (pr);
PR_Strings_Init (pr);
PR_Debug_Init (pr);
@ -488,6 +521,8 @@ PR_Init (progs_t *pr)
pr->hashlink_freelist);
pr->field_hash = Hash_NewTable (1021, var_get_key, 0, pr,
pr->hashlink_freelist);
pr->type_hash = Hash_NewTable (1021, type_get_key, 0, pr,
pr->hashlink_freelist);
}
VISIBLE void

File diff suppressed because it is too large Load diff

View file

@ -76,10 +76,10 @@ PR_UglyValueString (progs_t *pr, etype_t type, pr_type_t *val, dstring_t *line)
break;
case ev_func:
f = pr->pr_functions + val->func_var;
dsprintf (line, "%s", PR_GetString (pr, f->s_name));
dsprintf (line, "%s", PR_GetString (pr, f->name));
break;
case ev_field:
def = PR_FieldAtOfs (pr, val->integer_var);
def = PR_FieldAtOfs (pr, val->int_var);
dsprintf (line, "%s", PR_GetString (pr, def->name));
break;
case ev_void:
@ -88,13 +88,13 @@ PR_UglyValueString (progs_t *pr, etype_t type, pr_type_t *val, dstring_t *line)
case ev_float:
dsprintf (line, "%.9g", val->float_var);
break;
case ev_integer:
dsprintf (line, "%d", val->integer_var);
case ev_int:
dsprintf (line, "%d", val->int_var);
break;
case ev_vector:
dsprintf (line, "%.9g %.9g %.9g", VectorExpand (&val->vector_var));
break;
case ev_quat:
case ev_quaternion:
dsprintf (line, "%.9g %.9g %.9g %.9g", QuatExpand (&val->quat_var));
break;
default:
@ -118,7 +118,7 @@ ED_EntityDict (progs_t *pr, edict_t *ed)
pr_type_t *v;
if (!ed->free) {
for (i = 0; i < pr->progs->numfielddefs; i++) {
for (i = 0; i < pr->progs->fielddefs.count; i++) {
pr_def_t *d = &pr->pr_fielddefs[i];
name = PR_GetString (pr, d->name);
@ -132,7 +132,7 @@ ED_EntityDict (progs_t *pr, edict_t *ed)
// if the value is still all 0, skip the field
type = d->type & ~DEF_SAVEGLOBAL;
for (j = 0; j < pr_type_size[type]; j++)
if (v[j].integer_var)
if (v[j].int_var)
break;
if (j == pr_type_size[type])
continue;
@ -162,7 +162,7 @@ ED_GlobalsDict (progs_t *pr)
pr_def_t *def;
int type;
for (i = 0; i < pr->progs->numglobaldefs; i++) {
for (i = 0; i < pr->progs->globaldefs.count; i++) {
def = &pr->pr_globaldefs[i];
type = def->type;
if (!(def->type & DEF_SAVEGLOBAL))
@ -257,7 +257,7 @@ ED_ParseEpair (progs_t *pr, pr_type_t *base, pr_def_t *key, const char *s)
Sys_Printf ("Can't find field %s\n", s);
return false;
}
d->integer_var = G_INT (pr, def->ofs);
d->int_var = G_INT (pr, def->ofs);
break;
case ev_func:

View file

@ -44,7 +44,7 @@
static const char param_str[] = ".param_0";
pr_def_t *
PR_SearchDefs (pr_def_t *defs, unsigned num_defs, pointer_t offset)
PR_SearchDefs (pr_def_t *defs, unsigned num_defs, pr_ptr_t offset)
{
// fuzzy bsearh
unsigned left = 0;
@ -69,15 +69,15 @@ PR_SearchDefs (pr_def_t *defs, unsigned num_defs, pointer_t offset)
}
pr_def_t *
PR_GlobalAtOfs (progs_t * pr, pointer_t ofs)
PR_GlobalAtOfs (progs_t * pr, pr_ptr_t ofs)
{
return PR_SearchDefs (pr->pr_globaldefs, pr->progs->numglobaldefs, ofs);
return PR_SearchDefs (pr->pr_globaldefs, pr->progs->globaldefs.count, ofs);
}
VISIBLE pr_def_t *
PR_FieldAtOfs (progs_t * pr, pointer_t ofs)
PR_FieldAtOfs (progs_t * pr, pr_ptr_t ofs)
{
return PR_SearchDefs (pr->pr_fielddefs, pr->progs->numfielddefs, ofs);
return PR_SearchDefs (pr->pr_fielddefs, pr->progs->fielddefs.count, ofs);
}
VISIBLE pr_def_t *
@ -129,7 +129,7 @@ PR_ResolveGlobals (progs_t *pr)
if (!(def = PR_FindGlobal (pr, sym = ".return")))
goto error;
pr->pr_return = &pr->pr_globals[def->ofs];
for (i = 0; i < MAX_PARMS; i++) {
for (i = 0; i < PR_MAX_PARAMS; i++) {
param_n[sizeof (param_str) - 2] = i + '0';
if (!(def = PR_FindGlobal (pr, sym = param_n)))
goto error;
@ -142,15 +142,16 @@ PR_ResolveGlobals (progs_t *pr)
goto error;
pr->pr_param_alignment = G_INT (pr, def->ofs);
}
pr->null_size = pr->pr_return - pr->pr_globals;
memcpy (pr->pr_real_params, pr->pr_params, sizeof (pr->pr_params));
if (!pr->globals.time) {
if (!pr->globals.ftime) {//FIXME double time
if ((def = PR_FindGlobal (pr, "time")))
pr->globals.time = &G_FLOAT (pr, def->ofs);
pr->globals.ftime = &G_FLOAT (pr, def->ofs);
}
if (!pr->globals.self) {
if ((def = PR_FindGlobal (pr, ".self"))
|| (def = PR_FindGlobal (pr, "self")))
pr->globals.self = &G_INT (pr, def->ofs);
pr->globals.self = &G_UINT (pr, def->ofs);
}
if (!pr->globals.stack) {
if ((def = PR_FindGlobal (pr, ".stack"))

View file

@ -164,7 +164,7 @@ free_string_ref (prstr_resources_t *res, strref_t *sr)
res->free_string_refs = sr;
}
static __attribute__((pure)) string_t
static __attribute__((pure)) pr_string_t
string_index (prstr_resources_t *res, strref_t *sr)
{
long o = (long) (sr - res->static_strings);
@ -234,7 +234,7 @@ PR_LoadStrings (progs_t *pr)
{
prstr_resources_t *res = PR_Resources_Find (pr, "Strings");
char *end = pr->pr_strings + pr->progs->numstrings;
char *end = pr->pr_strings + pr->progs->strings.count;
char *str = pr->pr_strings;
int count = 0;
@ -242,13 +242,16 @@ PR_LoadStrings (progs_t *pr)
while (str < end) {
count++;
if (*str == '@' && pr->progs->version == PROG_VERSION) {
if (*str == '@' && pr->progs->version == PROG_V6P_VERSION) {
if (!strcmp (str, "@float_promoted@")) {
pr->float_promoted = 1;
}
}
str += strlen (str) + 1;
}
if (pr->progs->version == PROG_VERSION) {
pr->float_promoted = 1;
}
res->ds_mem.alloc = pr_strings_alloc;
res->ds_mem.free = pr_strings_free;
@ -306,7 +309,7 @@ requeue_strref (prstr_resources_t *res, strref_t *sr)
}
static inline strref_t *
get_strref (prstr_resources_t *res, string_t num)
get_strref (prstr_resources_t *res, pr_string_t num)
{
if (num < 0) {
strref_t *ref;
@ -325,7 +328,7 @@ get_strref (prstr_resources_t *res, string_t num)
}
static inline __attribute__((pure)) const char *
get_string (progs_t *pr, string_t num)
get_string (progs_t *pr, pr_string_t num)
{
__auto_type res = pr->pr_string_resources;
if (num < 0) {
@ -353,7 +356,7 @@ get_string (progs_t *pr, string_t num)
}
VISIBLE qboolean
PR_StringValid (progs_t *pr, string_t num)
PR_StringValid (progs_t *pr, pr_string_t num)
{
if (num >= 0) {
return num < pr->pr_stringsize;
@ -362,7 +365,7 @@ PR_StringValid (progs_t *pr, string_t num)
}
VISIBLE qboolean
PR_StringMutable (progs_t *pr, string_t num)
PR_StringMutable (progs_t *pr, pr_string_t num)
{
strref_t *sr;
if (num >= 0) {
@ -373,7 +376,7 @@ PR_StringMutable (progs_t *pr, string_t num)
}
VISIBLE const char *
PR_GetString (progs_t *pr, string_t num)
PR_GetString (progs_t *pr, pr_string_t num)
{
const char *str;
@ -384,7 +387,7 @@ PR_GetString (progs_t *pr, string_t num)
}
VISIBLE dstring_t *
PR_GetMutableString (progs_t *pr, string_t num)
PR_GetMutableString (progs_t *pr, pr_string_t num)
{
strref_t *ref = get_strref (pr->pr_string_resources, num);
if (ref) {
@ -421,7 +424,7 @@ pr_strdup (progs_t *pr, const char *s)
return new;
}
VISIBLE string_t
VISIBLE pr_string_t
PR_SetString (progs_t *pr, const char *s)
{
prstr_resources_t *res = pr->pr_string_resources;
@ -440,7 +443,7 @@ PR_SetString (progs_t *pr, const char *s)
return string_index (res, sr);
}
VISIBLE string_t
VISIBLE pr_string_t
PR_FindString (progs_t *pr, const char *s)
{
prstr_resources_t *res = pr->pr_string_resources;
@ -456,7 +459,7 @@ PR_FindString (progs_t *pr, const char *s)
return 0;
}
VISIBLE string_t
VISIBLE pr_string_t
PR_SetReturnString (progs_t *pr, const char *s)
{
prstr_resources_t *res = pr->pr_string_resources;
@ -496,7 +499,7 @@ PR_SetReturnString (progs_t *pr, const char *s)
return string_index (res, sr);
}
static inline string_t
static inline pr_string_t
pr_settempstring (progs_t *pr, prstr_resources_t *res, char *s)
{
strref_t *sr;
@ -509,7 +512,7 @@ pr_settempstring (progs_t *pr, prstr_resources_t *res, char *s)
return string_index (res, sr);
}
VISIBLE string_t
VISIBLE pr_string_t
PR_CatStrings (progs_t *pr, const char *a, const char *b)
{
size_t lena;
@ -525,7 +528,7 @@ PR_CatStrings (progs_t *pr, const char *a, const char *b)
return pr_settempstring (pr, pr->pr_string_resources, c);
}
VISIBLE string_t
VISIBLE pr_string_t
PR_SetTempString (progs_t *pr, const char *s)
{
prstr_resources_t *res = pr->pr_string_resources;
@ -541,7 +544,7 @@ PR_SetTempString (progs_t *pr, const char *s)
return pr_settempstring (pr, res, pr_strdup (pr, s));
}
VISIBLE string_t
VISIBLE pr_string_t
PR_AllocTempBlock (progs_t *pr, size_t size)
{
prstr_resources_t *res = pr->pr_string_resources;
@ -549,7 +552,7 @@ PR_AllocTempBlock (progs_t *pr, size_t size)
}
VISIBLE void
PR_PushTempString (progs_t *pr, string_t num)
PR_PushTempString (progs_t *pr, pr_string_t num)
{
prstr_resources_t *res = pr->pr_string_resources;
strref_t *ref = get_strref (res, num);
@ -569,7 +572,7 @@ PR_PushTempString (progs_t *pr, string_t num)
PR_Error (pr, "attempt to push stale temp string");
}
VISIBLE string_t
VISIBLE pr_string_t
PR_SetDynamicString (progs_t *pr, const char *s)
{
prstr_resources_t *res = pr->pr_string_resources;
@ -589,7 +592,7 @@ PR_SetDynamicString (progs_t *pr, const char *s)
}
VISIBLE void
PR_MakeTempString (progs_t *pr, string_t str)
PR_MakeTempString (progs_t *pr, pr_string_t str)
{
prstr_resources_t *res = pr->pr_string_resources;
strref_t *sr = get_strref (res, str);
@ -610,7 +613,7 @@ PR_MakeTempString (progs_t *pr, string_t str)
pr->pr_xtstr = sr;
}
VISIBLE string_t
VISIBLE pr_string_t
PR_NewMutableString (progs_t *pr)
{
prstr_resources_t *res = pr->pr_string_resources;
@ -621,7 +624,7 @@ PR_NewMutableString (progs_t *pr)
}
VISIBLE void
PR_HoldString (progs_t *pr, string_t str)
PR_HoldString (progs_t *pr, pr_string_t str)
{
prstr_resources_t *res = pr->pr_string_resources;
strref_t *sr = get_strref (res, str);
@ -651,7 +654,7 @@ PR_HoldString (progs_t *pr, string_t str)
}
VISIBLE void
PR_FreeString (progs_t *pr, string_t str)
PR_FreeString (progs_t *pr, pr_string_t str)
{
prstr_resources_t *res = pr->pr_string_resources;
strref_t *sr = get_strref (res, str);

File diff suppressed because it is too large Load diff

183
libs/gamecode/swizzle.py Normal file
View file

@ -0,0 +1,183 @@
def iter(func):
for i in range(4):
for j in range(4):
for k in range(4):
for l in range(4):
func(i, j, k, l)
def iter16(func):
for i in range(16):
func(i)
import sys
coord=['x', 'y', 'z', 'w']
def label(i, j, k, l):
return f"swizzle_{coord[l]}{coord[k]}{coord[j]}{coord[i]}"
def print_ref(i, j, k, l):
print(f"\t\t&&{label(i, j, k, l)},")
def print_op(i, j, k, l):
print(f"\t{label(i, j, k, l)}: vec = swizzle (vec, (pr_ivec4_t) {{ {l}, {k}, {j}, {i} }}); goto negate;")
def print_data(i, j, k, l):
print(f"\t{{ {l+1:2}, {k+1:2}, {j+1:2}, {i+1:2} }},")
def print_swizzle_f(i, j, k, l):
swiz = i * 64 + j * 16 + k * 4 + l
addr = (swiz + 1) * 4
print(f"\t{{ OP(0, 0, 0, OP_SWIZZLE_F), 0, 0x{swiz:04x}, {addr} }},")
def print_neg_f(i):
swiz = i * 0x100 + 0xe4
addr = (i + 1) * 4
print(f"\t{{ OP(0, 0, 0, OP_SWIZZLE_F), 0, 0x{swiz:04x}, {addr} }},")
def print_zero_f(i):
swiz = i * 0x1000 + 0xe4
addr = (i + 1) * 4
print(f"\t{{ OP(0, 0, 0, OP_SWIZZLE_F), 0, 0x{swiz:04x}, {addr} }},")
def print_swizzle_d(i, j, k, l):
swiz = i * 64 + j * 16 + k * 4 + l
addr = (swiz + 1) * 8
print(f"\t{{ OP(0, 0, 0, OP_SWIZZLE_D), 0, 0x{swiz:04x}, {addr} }},")
def print_neg_d(i):
swiz = i * 0x100 + 0xe4
addr = (i + 1) * 8
print(f"\t{{ OP(0, 0, 0, OP_SWIZZLE_D), 0, 0x{swiz:04x}, {addr} }},")
def print_zero_d(i):
swiz = i * 0x1000 + 0xe4
addr = (i + 1) * 8
print(f"\t{{ OP(0, 0, 0, OP_SWIZZLE_D), 0, 0x{swiz:04x}, {addr} }},")
def print_eights(i, j, k, l):
print(f"\t{{ {8:2}, {8:2}, {8:2}, {8:2} }},")
def print_nines(i):
print(f"\t{{ {9:2}, {9:2}, {9:2}, {9:2} }},")
def print_neg(n):
x = [1, 2, 3, 4]
for i in range(4):
if n & (1<< i):
x[i] = -x[i]
print(f"\t{{ {x[0]:2}, {x[1]:2}, {x[2]:2}, {x[3]:2} }},")
def print_zero(z):
x = [1, 2, 3, 4]
for i in range(4):
if z & (1<< i):
x[i] = 0
print(f"\t{{ {x[0]:2}, {x[1]:2}, {x[2]:2}, {x[3]:2} }},")
types = ["f", "d"]
tests = ["swizzle", "neg", "zero"]
if sys.argv[1] == "case":
iter(print_op)
print("\tstatic void *swizzle_table[256] = {")
iter(print_ref)
print("\t};")
elif sys.argv[1] == "test":
print('#include "head.c"')
print()
print("static pr_vec4_t swizzle_f_init[] = {")
print_data(3, 2, 1, 0)
iter(print_eights)
print("};")
print("static pr_vec4_t swizzle_f_expect[] = {")
print_data(3, 2, 1, 0)
iter(print_data)
print("};")
print()
print("static dstatement_t swizzle_f_statements[] = {")
iter(print_swizzle_f)
print("};")
print()
print("static pr_vec4_t neg_f_init[] = {")
print_neg(0)
iter16(print_nines)
print("};")
print()
print("static pr_vec4_t neg_f_expect[] = {")
print_neg(0)
iter16(print_neg)
print("};")
print()
print("static dstatement_t neg_f_statements[] = {")
iter16(print_neg_f)
print("};")
print()
print("static pr_vec4_t zero_f_init[] = {")
print_zero(0)
iter16(print_nines)
print("};")
print()
print("static pr_vec4_t zero_f_expect[] = {")
print_zero(0)
iter16(print_zero)
print("};")
print()
print("static dstatement_t zero_f_statements[] = {")
iter16(print_zero_f)
print("};")
print()
print("static pr_dvec4_t swizzle_d_init[] = {")
print_data(3, 2, 1, 0)
iter(print_eights)
print("};")
print("static pr_dvec4_t swizzle_d_expect[] = {")
print_data(3, 2, 1, 0)
iter(print_data)
print("};")
print()
print("static dstatement_t swizzle_d_statements[] = {")
iter(print_swizzle_d)
print("};")
print()
print("static pr_dvec4_t neg_d_init[] = {")
print_neg(0)
iter16(print_nines)
print("};")
print()
print("static pr_dvec4_t neg_d_expect[] = {")
print_neg(0)
iter16(print_neg)
print("};")
print()
print("static dstatement_t neg_d_statements[] = {")
iter16(print_neg_d)
print("};")
print()
print("static pr_dvec4_t zero_d_init[] = {")
print_zero(0)
iter16(print_nines)
print("};")
print()
print("static pr_dvec4_t zero_d_expect[] = {")
print_zero(0)
iter16(print_zero)
print("};")
print()
print("static dstatement_t zero_d_statements[] = {")
iter16(print_zero_d)
print("};")
print()
print("test_t tests[] = {")
for t in types:
for o in tests:
print("\t{")
print(f'\t\t.desc = "{o} {t}",')
print(f"\t\t.num_globals = num_globals({o}_{t}_init,{o}_{t}_expect),")
print(f"\t\t.num_statements = num_statements({o}_{t}_statements),")
print(f"\t\t.statements = {o}_{t}_statements,")
print(f"\t\t.init_globals = (pr_int_t *) {o}_{t}_init,")
print(f"\t\t.expect_globals = (pr_int_t *) {o}_{t}_expect,")
print("\t},")
print("};")
print()
print('#include "main.c"')

View file

@ -0,0 +1,196 @@
libs_gamecode_tests = \
libs/gamecode/test/test-branch \
libs/gamecode/test/test-bitops \
libs/gamecode/test/test-callret \
libs/gamecode/test/test-conv0 \
libs/gamecode/test/test-conv1 \
libs/gamecode/test/test-conv2 \
libs/gamecode/test/test-conv3 \
libs/gamecode/test/test-conv4 \
libs/gamecode/test/test-conv5 \
libs/gamecode/test/test-conv6 \
libs/gamecode/test/test-conv7 \
libs/gamecode/test/test-double \
libs/gamecode/test/test-float \
libs/gamecode/test/test-hops \
libs/gamecode/test/test-int \
libs/gamecode/test/test-jump \
libs/gamecode/test/test-lea \
libs/gamecode/test/test-load \
libs/gamecode/test/test-load64 \
libs/gamecode/test/test-long \
libs/gamecode/test/test-mem \
libs/gamecode/test/test-scale \
libs/gamecode/test/test-stack \
libs/gamecode/test/test-state \
libs/gamecode/test/test-store \
libs/gamecode/test/test-store64 \
libs/gamecode/test/test-string \
libs/gamecode/test/test-swizzle \
libs/gamecode/test/test-unsigned \
libs/gamecode/test/test-vector \
libs/gamecode/test/test-with
TESTS += $(libs_gamecode_tests)
check_PROGRAMS += $(libs_gamecode_tests)
EXTRA_DIST += head.c main.c
test_gamecode_libs= \
libs/gamecode/libQFgamecode.la \
libs/util/libQFutil.la
libs_gamecode_test_test_branch_SOURCES= \
libs/gamecode/test/test-branch.c
libs_gamecode_test_test_branch_LDADD= $(test_gamecode_libs)
libs_gamecode_test_test_branch_DEPENDENCIES=$(test_gamecode_libs)
libs_gamecode_test_test_bitops_SOURCES= \
libs/gamecode/test/test-bitops.c
libs_gamecode_test_test_bitops_LDADD= $(test_gamecode_libs)
libs_gamecode_test_test_bitops_DEPENDENCIES=$(test_gamecode_libs)
libs_gamecode_test_test_callret_SOURCES= \
libs/gamecode/test/test-callret.c
libs_gamecode_test_test_callret_LDADD= $(test_gamecode_libs)
libs_gamecode_test_test_callret_DEPENDENCIES=$(test_gamecode_libs)
libs_gamecode_test_test_conv0_SOURCES= \
libs/gamecode/test/test-conv0.c
libs_gamecode_test_test_conv0_LDADD= $(test_gamecode_libs)
libs_gamecode_test_test_conv0_DEPENDENCIES= $(test_gamecode_libs)
libs_gamecode_test_test_conv1_SOURCES= \
libs/gamecode/test/test-conv1.c
libs_gamecode_test_test_conv1_LDADD= $(test_gamecode_libs)
libs_gamecode_test_test_conv1_DEPENDENCIES= $(test_gamecode_libs)
libs_gamecode_test_test_conv2_SOURCES= \
libs/gamecode/test/test-conv2.c
libs_gamecode_test_test_conv2_LDADD= $(test_gamecode_libs)
libs_gamecode_test_test_conv2_DEPENDENCIES= $(test_gamecode_libs)
libs_gamecode_test_test_conv3_SOURCES= \
libs/gamecode/test/test-conv3.c
libs_gamecode_test_test_conv3_LDADD= $(test_gamecode_libs)
libs_gamecode_test_test_conv3_DEPENDENCIES= $(test_gamecode_libs)
libs_gamecode_test_test_conv4_SOURCES= \
libs/gamecode/test/test-conv4.c
libs_gamecode_test_test_conv4_LDADD= $(test_gamecode_libs)
libs_gamecode_test_test_conv4_DEPENDENCIES= $(test_gamecode_libs)
libs_gamecode_test_test_conv5_SOURCES= \
libs/gamecode/test/test-conv5.c
libs_gamecode_test_test_conv5_LDADD= $(test_gamecode_libs)
libs_gamecode_test_test_conv5_DEPENDENCIES= $(test_gamecode_libs)
libs_gamecode_test_test_conv6_SOURCES= \
libs/gamecode/test/test-conv6.c
libs_gamecode_test_test_conv6_LDADD= $(test_gamecode_libs)
libs_gamecode_test_test_conv6_DEPENDENCIES= $(test_gamecode_libs)
libs_gamecode_test_test_conv7_SOURCES= \
libs/gamecode/test/test-conv7.c
libs_gamecode_test_test_conv7_LDADD= $(test_gamecode_libs)
libs_gamecode_test_test_conv7_DEPENDENCIES= $(test_gamecode_libs)
libs_gamecode_test_test_double_SOURCES= \
libs/gamecode/test/test-double.c
libs_gamecode_test_test_double_LDADD= $(test_gamecode_libs)
libs_gamecode_test_test_double_DEPENDENCIES=$(test_gamecode_libs)
libs_gamecode_test_test_float_SOURCES= \
libs/gamecode/test/test-float.c
libs_gamecode_test_test_float_LDADD= $(test_gamecode_libs)
libs_gamecode_test_test_float_DEPENDENCIES= $(test_gamecode_libs)
libs_gamecode_test_test_hops_SOURCES= \
libs/gamecode/test/test-hops.c
libs_gamecode_test_test_hops_LDADD= $(test_gamecode_libs)
libs_gamecode_test_test_hops_DEPENDENCIES= $(test_gamecode_libs)
libs_gamecode_test_test_int_SOURCES= \
libs/gamecode/test/test-int.c
libs_gamecode_test_test_int_LDADD= $(test_gamecode_libs)
libs_gamecode_test_test_int_DEPENDENCIES= $(test_gamecode_libs)
libs_gamecode_test_test_jump_SOURCES= \
libs/gamecode/test/test-jump.c
libs_gamecode_test_test_jump_LDADD= $(test_gamecode_libs)
libs_gamecode_test_test_jump_DEPENDENCIES= $(test_gamecode_libs)
libs_gamecode_test_test_lea_SOURCES= \
libs/gamecode/test/test-lea.c
libs_gamecode_test_test_lea_LDADD= $(test_gamecode_libs)
libs_gamecode_test_test_lea_DEPENDENCIES= $(test_gamecode_libs)
libs_gamecode_test_test_load_SOURCES= \
libs/gamecode/test/test-load.c
libs_gamecode_test_test_load_LDADD= $(test_gamecode_libs)
libs_gamecode_test_test_load_DEPENDENCIES= $(test_gamecode_libs)
libs_gamecode_test_test_load64_SOURCES= \
libs/gamecode/test/test-load64.c
libs_gamecode_test_test_load64_LDADD= $(test_gamecode_libs)
libs_gamecode_test_test_load64_DEPENDENCIES=$(test_gamecode_libs)
libs_gamecode_test_test_long_SOURCES= \
libs/gamecode/test/test-long.c
libs_gamecode_test_test_long_LDADD= $(test_gamecode_libs)
libs_gamecode_test_test_long_DEPENDENCIES= $(test_gamecode_libs)
libs_gamecode_test_test_mem_SOURCES= \
libs/gamecode/test/test-mem.c
libs_gamecode_test_test_mem_LDADD= $(test_gamecode_libs)
libs_gamecode_test_test_mem_DEPENDENCIES= $(test_gamecode_libs)
libs_gamecode_test_test_scale_SOURCES= \
libs/gamecode/test/test-scale.c
libs_gamecode_test_test_scale_LDADD= $(test_gamecode_libs)
libs_gamecode_test_test_scale_DEPENDENCIES= $(test_gamecode_libs)
libs_gamecode_test_test_stack_SOURCES= \
libs/gamecode/test/test-stack.c
libs_gamecode_test_test_stack_LDADD= $(test_gamecode_libs)
libs_gamecode_test_test_stack_DEPENDENCIES= $(test_gamecode_libs)
libs_gamecode_test_test_state_SOURCES= \
libs/gamecode/test/test-state.c
libs_gamecode_test_test_state_LDADD= $(test_gamecode_libs)
libs_gamecode_test_test_store_SOURCES= \
libs/gamecode/test/test-store.c
libs_gamecode_test_test_store_LDADD= $(test_gamecode_libs)
libs_gamecode_test_test_store_DEPENDENCIES= $(test_gamecode_libs)
libs_gamecode_test_test_store64_SOURCES= \
libs/gamecode/test/test-store64.c
libs_gamecode_test_test_store64_LDADD= $(test_gamecode_libs)
libs_gamecode_test_test_store64_DEPENDENCIES= $(test_gamecode_libs)
libs_gamecode_test_test_string_SOURCES= \
libs/gamecode/test/test-string.c
libs_gamecode_test_test_string_LDADD= $(test_gamecode_libs)
libs_gamecode_test_test_string_DEPENDENCIES= $(test_gamecode_libs)
libs_gamecode_test_test_swizzle_SOURCES= \
libs/gamecode/test/test-swizzle.c
libs_gamecode_test_test_swizzle_LDADD= $(test_gamecode_libs)
libs_gamecode_test_test_swizzle_DEPENDENCIES= $(test_gamecode_libs)
libs_gamecode_test_test_unsigned_SOURCES= \
libs/gamecode/test/test-unsigned.c
libs_gamecode_test_test_unsigned_LDADD= $(test_gamecode_libs)
libs_gamecode_test_test_unsigned_DEPENDENCIES= $(test_gamecode_libs)
libs_gamecode_test_test_vector_SOURCES= \
libs/gamecode/test/test-vector.c
libs_gamecode_test_test_vector_LDADD= $(test_gamecode_libs)
libs_gamecode_test_test_vector_DEPENDENCIES= $(test_gamecode_libs)
libs_gamecode_test_test_with_SOURCES= \
libs/gamecode/test/test-with.c
libs_gamecode_test_test_with_LDADD= $(test_gamecode_libs)
libs_gamecode_test_test_with_DEPENDENCIES= $(test_gamecode_libs)

54
libs/gamecode/test/head.c Normal file
View file

@ -0,0 +1,54 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "QF/progs.h"
static int verbose = 0;
// both calculates the number of globals in the test, and ensures that both
// init and expect are the same size (will product a "void value not ignored"
// error if the sizes differ)
#define num_globals(init, expect) \
__builtin_choose_expr ( \
sizeof (init) == sizeof (expect), \
(sizeof (init) / sizeof (init[0])) \
* (sizeof (init[0]) / sizeof (pr_type_t)), \
(void) 0\
)
// calculate the numver of statements in the test
#define num_statements(statements) \
(sizeof (statements) / sizeof (statements[0]))
#define num_functions(functions) \
(sizeof (functions) / sizeof (functions[0]))
#define BASE(b, base) (((base) & 3) << OP_##b##_SHIFT)
#define OP(a, b, c, op) ((op) | BASE(A, a) | BASE(B, b) | BASE(C, c))
typedef struct {
const char *desc;
pr_ptr_t edict_area;
pr_uint_t stack_size;
pr_uint_t extra_globals;
pr_uint_t num_globals;
pr_uint_t num_statements;
dstatement_t *statements;
pr_int_t *init_globals;
pr_int_t *expect_globals;
const char *strings;
pr_uint_t string_size;
// pointers/globals for state
double *double_time;
pr_uint_t dtime;
float *float_time;
pr_uint_t ftime;
pr_uint_t self;
// fields for state
pr_uint_t think;
pr_uint_t nextthink;
pr_uint_t frame;
bfunction_t *functions;
pr_uint_t num_functions;
} test_t;

244
libs/gamecode/test/main.c Normal file
View file

@ -0,0 +1,244 @@
#include <setjmp.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "QF/va.h"
#define num_tests (sizeof (tests) / sizeof (tests[0]))
static int test_enabled[num_tests] = { 0 };
#include "getopt.h"
#include "QF/cmd.h"
#include "QF/cvar.h"
static bfunction_t test_functions[] = {
{}, // null function
{ .first_statement = 0 }
};
static dprograms_t test_progs = {
.version = PROG_VERSION,
};
static progs_t test_pr;
static jmp_buf jump_buffer;
static void
test_debug_handler (prdebug_t event, void *param, void *data)
{
progs_t *pr = data;
switch (event) {
case prd_breakpoint:
if (verbose > 0) {
printf ("debug: %s\n", prdebug_names[event]);
}
longjmp (jump_buffer, 1);
case prd_subenter:
if (verbose > 0) {
printf ("debug: subenter %d\n", *(pr_func_t *) param);
}
case prd_subexit:
break;
case prd_trace:
dstatement_t *st = test_pr.pr_statements + test_pr.pr_xstatement;
if (verbose > 1) {
printf ("---\n");
printf ("debug: trace %05x %04x %04x %04x %04x%s\n",
test_pr.pr_xstatement, st->op, st->a, st->b, st->c,
pr->globals.stack ? va (0, " %05x", *pr->globals.stack)
: "");
printf (" %04x %04x %04x\n",
st->a + PR_BASE (pr, st, A),
st->b + PR_BASE (pr, st, B),
st->c + PR_BASE (pr, st, C));
}
if (verbose > 0) {
PR_PrintStatement (&test_pr, st, 0);
}
if (pr->globals.stack) {
if (*pr->globals.stack & 3) {
printf ("stack not aligned: %d\n", *pr->globals.stack);
longjmp (jump_buffer, 3);
}
}
break;
case prd_runerror:
printf ("debug: %s: %s\n", prdebug_names[event], (char *)param);
longjmp (jump_buffer, 3);
case prd_watchpoint:
case prd_begin:
case prd_terminate:
case prd_error:
case prd_none:
printf ("debug: unexpected:%s %p\n", prdebug_names[event], param);
longjmp (jump_buffer, 2);
}
}
static void
setup_test (test_t *test)
{
memset (&test_pr, 0, sizeof (test_pr));
PR_Init (&test_pr);
PR_Debug_Init (&test_pr);
test_pr.progs = &test_progs;
test_pr.debug_handler = test_debug_handler;
test_pr.debug_data = &test_pr;
test_pr.pr_trace = 1;
test_pr.pr_trace_depth = -1;
if (test->num_functions && test->functions) {
test_pr.function_table = calloc ((test->num_functions + 2),
sizeof (bfunction_t));
memcpy (test_pr.function_table, test_functions,
2 * sizeof (bfunction_t));
memcpy (test_pr.function_table + 2, test->functions,
test->num_functions * sizeof (bfunction_t));
} else {
test_pr.function_table = test_functions;
}
pr_uint_t num_globals = test->num_globals;
num_globals += test->extra_globals + test->stack_size;
test_pr.globals_size = num_globals;
test_pr.pr_globals = Sys_Alloc (num_globals * sizeof (pr_type_t));
memcpy (test_pr.pr_globals, test->init_globals,
test->num_globals * sizeof (pr_type_t));
memset (test_pr.pr_globals + test->num_globals, 0,
test->extra_globals * sizeof (pr_type_t));
if (test->stack_size) {
pr_ptr_t stack = num_globals - test->stack_size;
test_pr.stack_bottom = stack + 4;
test_pr.globals.stack = (pr_ptr_t *) (test_pr.pr_globals + stack);
*test_pr.globals.stack = num_globals;
}
if (test->edict_area) {
test_pr.pr_edict_area = test_pr.pr_globals + test->edict_area;
}
if (test->double_time || test->float_time) {
test_pr.fields.nextthink = test->nextthink;
test_pr.fields.frame = test->frame;
test_pr.fields.think = test->think;
test_pr.globals.self = (pr_uint_t *) &test_pr.pr_globals[test->self];
if (test->double_time) {
test_pr.globals.dtime = (double *)&test_pr.pr_globals[test->dtime];
*test_pr.globals.dtime = *test->double_time;
}
if (test->float_time) {
test_pr.globals.ftime = (float *) &test_pr.pr_globals[test->ftime];
*test_pr.globals.ftime = *test->float_time;
}
}
test_progs.statements.count = test->num_statements + 1;
test_pr.pr_statements
= malloc ((test->num_statements + 1) * sizeof (dstatement_t));
memcpy (test_pr.pr_statements, test->statements,
(test->num_statements + 1) * sizeof (dstatement_t));
test_pr.pr_statements[test->num_statements] =
(dstatement_t) { OP_BREAK, 0, 0, 0 };
test_pr.pr_strings = (char *) test->strings;
test_pr.pr_stringsize = test->string_size;
}
static int
check_result (test_t *test)
{
int ret = 0;
if (memcmp (test_pr.pr_globals, test->expect_globals,
test->num_globals * sizeof (pr_int_t)) == 0) {
ret = 1;
printf ("test #%zd: %s: OK\n", test - tests, test->desc);
} else {
printf ("test #%zd: %s: words differ\n", test - tests, test->desc);
}
return ret;
}
static int
run_test (test_t *test)
{
int jump_ret;
int ret = 0;
setup_test (test);
if (!(jump_ret = setjmp (jump_buffer))) {
PR_ExecuteProgram (&test_pr, 1);
printf ("returned from progs\n");
}
if (jump_ret == 1) {
ret = check_result (test);
} else {
printf ("test #%zd: %s: critical failure\n", test - tests, test->desc);
}
pr_uint_t num_globals = test->num_globals;
num_globals += test->extra_globals + test->stack_size;
if (test->num_functions && test->functions) {
free (test_pr.function_table);
}
Sys_Free (test_pr.pr_globals, num_globals * sizeof (pr_type_t));
free (test_pr.pr_statements);
return ret;
}
int
main (int argc, char **argv)
{
int c;
size_t i, test;
int pass = 1;
Cmd_Init_Hash ();
Cvar_Init_Hash ();
Cmd_Init ();
Cvar_Init ();
PR_Init_Cvars ();
pr_boundscheck->int_val = 1;
while ((c = getopt (argc, argv, "qvt:")) != EOF) {
switch (c) {
case 'q':
verbose--;
break;
case 'v':
verbose++;
break;
case 't':
test = atoi (optarg);
if (test < num_tests) {
test_enabled[test] = 1;
} else {
fprintf (stderr, "Bad test number (0 - %zd)\n", num_tests);
return 1;
}
break;
default:
fprintf (stderr, "-q (quiet) -v (verbose) and/or -t TEST "
"(test number)\n");
return 1;
}
}
for (i = 0; i < num_tests; i++)
if (test_enabled[i])
break;
if (i == num_tests) {
for (i = 0; i < num_tests; i++)
test_enabled[i] = 1;
}
for (i = 0; i < num_tests; i++) {
if (!test_enabled[i])
continue;
pass &= run_test (&tests[i]);
}
return !pass;
}

View file

@ -0,0 +1,260 @@
#include "head.c"
#include "QF/mathlib.h"
static pr_ivec4_t int_bitop_init[] = {
{ 5, -5, 5, -5},
{ 5, 5, -5, -5},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
};
static pr_ivec4_t int_bitop_expect[] = {
{ 5, -5, 5, -5},
{ 5, 5, -5, -5},
{ 5, 1, 1, -5},
{ 5, -1, -1, -5},
{ 0, -2, -2, 0},
{ -6, 4, -6, 4},
};
static dstatement_t int_bitop_1_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 4, 0, 24 }, // init index
//loop:
{ OP(0, 0, 0, OP_LEA_C), 24, -1, 24 }, // dec index
{ OP(0, 0, 0, OP_IFAE), 2, 0, 24 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 24, 1 },
{ OP(1, 1, 1, OP_BITAND_I_1), 0, 4, 8},
{ OP(1, 1, 1, OP_BITOR_I_1), 0, 4, 12},
{ OP(1, 1, 1, OP_BITXOR_I_1), 0, 4, 16},
{ OP(1, 1, 1, OP_BITNOT_I_1), 0, 4, 20},
{ OP(0, 0, 0, OP_JUMP_A), -8, 0, 0 },
};
static dstatement_t int_bitop_2_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 4, 0, 24 }, // index
//loop:
{ OP(0, 0, 0, OP_LEA_C), 24, -2, 24 }, // dec index
{ OP(0, 0, 0, OP_IFAE), 2, 0, 24 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 24, 1 },
{ OP(1, 1, 1, OP_BITAND_I_2), 0, 4, 8},
{ OP(1, 1, 1, OP_BITOR_I_2), 0, 4, 12},
{ OP(1, 1, 1, OP_BITXOR_I_2), 0, 4, 16},
{ OP(1, 1, 1, OP_BITNOT_I_2), 0, 4, 20},
{ OP(0, 0, 0, OP_JUMP_A), -8, 0, 0 },
};
static dstatement_t int_bitop_3a_statements[] = {
{ OP(1, 1, 1, OP_BITAND_I_3), 0, 4, 8},
{ OP(1, 1, 1, OP_BITAND_I_1), 3, 7, 11},
{ OP(1, 1, 1, OP_BITOR_I_3), 0, 4, 12},
{ OP(1, 1, 1, OP_BITOR_I_1), 3, 7, 15},
{ OP(1, 1, 1, OP_BITXOR_I_3), 0, 4, 16},
{ OP(1, 1, 1, OP_BITXOR_I_1), 3, 7, 19},
{ OP(1, 1, 1, OP_BITNOT_I_3), 0, 4, 20},
{ OP(1, 1, 1, OP_BITNOT_I_1), 3, 7, 23},
};
static dstatement_t int_bitop_3b_statements[] = {
{ OP(1, 1, 1, OP_BITAND_I_1), 0, 4, 8},
{ OP(1, 1, 1, OP_BITAND_I_3), 1, 5, 9},
{ OP(1, 1, 1, OP_BITOR_I_1), 0, 4, 12},
{ OP(1, 1, 1, OP_BITOR_I_3), 1, 5, 13},
{ OP(1, 1, 1, OP_BITXOR_I_1), 0, 4, 16},
{ OP(1, 1, 1, OP_BITXOR_I_3), 1, 5, 17},
{ OP(1, 1, 1, OP_BITNOT_I_1), 0, 4, 20},
{ OP(1, 1, 1, OP_BITNOT_I_3), 1, 5, 21},
};
static dstatement_t int_bitop_4_statements[] = {
{ OP(1, 1, 1, OP_BITAND_I_4), 0, 4, 8},
{ OP(1, 1, 1, OP_BITOR_I_4), 0, 4, 12},
{ OP(1, 1, 1, OP_BITXOR_I_4), 0, 4, 16},
{ OP(1, 1, 1, OP_BITNOT_I_4), 0, 4, 20},
};
static pr_lvec4_t long_bitop_init[] = {
{ 5, -5, 5, -5},
{ 5, 5, -5, -5},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
};
static pr_lvec4_t long_bitop_expect[] = {
{ 5, -5, 5, -5},
{ 5, 5, -5, -5},
{ 5, 1, 1, -5},
{ 5, -1, -1, -5},
{ 0, -2, -2, 0},
{ -6, 4, -6, 4},
};
static dstatement_t long_bitop_1_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 8, 0, 48 }, // init index
//loop:
{ OP(0, 0, 0, OP_LEA_C), 48, -2, 48 }, // dec index
{ OP(0, 0, 0, OP_IFAE), 2, 0, 48 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 48, 1 },
{ OP(1, 1, 1, OP_BITAND_L_1), 0, 8, 16},
{ OP(1, 1, 1, OP_BITOR_L_1), 0, 8, 24},
{ OP(1, 1, 1, OP_BITXOR_L_1), 0, 8, 32},
{ OP(1, 1, 1, OP_BITNOT_L_1), 0, 8, 40},
{ OP(0, 0, 0, OP_JUMP_A), -8, 0, 0 },
};
static dstatement_t long_bitop_2_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 8, 0, 48 }, // init index
//loop:
{ OP(0, 0, 0, OP_LEA_C), 48, -4, 48 }, // dec index
{ OP(0, 0, 0, OP_IFAE), 2, 0, 48 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 48, 1 },
{ OP(1, 1, 1, OP_BITAND_L_2), 0, 8, 16},
{ OP(1, 1, 1, OP_BITOR_L_2), 0, 8, 24},
{ OP(1, 1, 1, OP_BITXOR_L_2), 0, 8, 32},
{ OP(1, 1, 1, OP_BITNOT_L_2), 0, 8, 40},
{ OP(0, 0, 0, OP_JUMP_A), -8, 0, 0 },
};
static dstatement_t long_bitop_3a_statements[] = {
{ OP(1, 1, 1, OP_BITAND_L_3), 0, 8, 16},
{ OP(1, 1, 1, OP_BITAND_L_1), 6, 14, 22},
{ OP(1, 1, 1, OP_BITOR_L_3), 0, 8, 24},
{ OP(1, 1, 1, OP_BITOR_L_1), 6, 14, 30},
{ OP(1, 1, 1, OP_BITXOR_L_3), 0, 8, 32},
{ OP(1, 1, 1, OP_BITXOR_L_1), 6, 14, 38},
{ OP(1, 1, 1, OP_BITNOT_L_3), 0, 8, 40},
{ OP(1, 1, 1, OP_BITNOT_L_1), 6, 14, 46},
};
static dstatement_t long_bitop_3b_statements[] = {
{ OP(1, 1, 1, OP_BITAND_L_1), 0, 8, 16},
{ OP(1, 1, 1, OP_BITAND_L_3), 2, 10, 18},
{ OP(1, 1, 1, OP_BITOR_L_1), 0, 8, 24},
{ OP(1, 1, 1, OP_BITOR_L_3), 2, 10, 26},
{ OP(1, 1, 1, OP_BITXOR_L_1), 0, 8, 32},
{ OP(1, 1, 1, OP_BITXOR_L_3), 2, 10, 34},
{ OP(1, 1, 1, OP_BITNOT_L_1), 0, 8, 40},
{ OP(1, 1, 1, OP_BITNOT_L_3), 2, 10, 42},
};
static dstatement_t long_bitop_4_statements[] = {
{ OP(1, 1, 1, OP_BITAND_L_4), 0, 8, 16},
{ OP(1, 1, 1, OP_BITOR_L_4), 0, 8, 24},
{ OP(1, 1, 1, OP_BITXOR_L_4), 0, 8, 32},
{ OP(1, 1, 1, OP_BITNOT_L_4), 0, 8, 40},
};
test_t tests[] = {
{
.desc = "int bitop 1",
.extra_globals = 4 * 1,
.num_globals = num_globals(int_bitop_init,int_bitop_expect),
.num_statements = num_statements (int_bitop_1_statements),
.statements = int_bitop_1_statements,
.init_globals = (pr_int_t *) int_bitop_init,
.expect_globals = (pr_int_t *) int_bitop_expect,
},
{
.desc = "int bitop 2",
.extra_globals = 4 * 1,
.num_globals = num_globals(int_bitop_init,int_bitop_expect),
.num_statements = num_statements (int_bitop_2_statements),
.statements = int_bitop_2_statements,
.init_globals = (pr_int_t *) int_bitop_init,
.expect_globals = (pr_int_t *) int_bitop_expect,
},
{
.desc = "int bitop 3a",
.extra_globals = 4 * 1,
.num_globals = num_globals(int_bitop_init,int_bitop_expect),
.num_statements = num_statements (int_bitop_3a_statements),
.statements = int_bitop_3a_statements,
.init_globals = (pr_int_t *) int_bitop_init,
.expect_globals = (pr_int_t *) int_bitop_expect,
},
{
.desc = "int bitop 3b",
.extra_globals = 4 * 1,
.num_globals = num_globals(int_bitop_init,int_bitop_expect),
.num_statements = num_statements (int_bitop_3b_statements),
.statements = int_bitop_3b_statements,
.init_globals = (pr_int_t *) int_bitop_init,
.expect_globals = (pr_int_t *) int_bitop_expect,
},
{
.desc = "int bitop 4",
.extra_globals = 4 * 1,
.num_globals = num_globals(int_bitop_init,int_bitop_expect),
.num_statements = num_statements (int_bitop_4_statements),
.statements = int_bitop_4_statements,
.init_globals = (pr_int_t *) int_bitop_init,
.expect_globals = (pr_int_t *) int_bitop_expect,
},
{
.desc = "long bitop 1",
.extra_globals = 4 * 1,
.num_globals = num_globals(long_bitop_init,long_bitop_expect),
.num_statements = num_statements (long_bitop_1_statements),
.statements = long_bitop_1_statements,
.init_globals = (pr_int_t *) long_bitop_init,
.expect_globals = (pr_int_t *) long_bitop_expect,
},
{
.desc = "long bitop 2",
.extra_globals = 4 * 1,
.num_globals = num_globals(long_bitop_init,long_bitop_expect),
.num_statements = num_statements (long_bitop_2_statements),
.statements = long_bitop_2_statements,
.init_globals = (pr_int_t *) long_bitop_init,
.expect_globals = (pr_int_t *) long_bitop_expect,
},
{
.desc = "long bitop 3a",
.extra_globals = 4 * 1,
.num_globals = num_globals(long_bitop_init,long_bitop_expect),
.num_statements = num_statements (long_bitop_3a_statements),
.statements = long_bitop_3a_statements,
.init_globals = (pr_int_t *) long_bitop_init,
.expect_globals = (pr_int_t *) long_bitop_expect,
},
{
.desc = "long bitop 3b",
.extra_globals = 4 * 1,
.num_globals = num_globals(long_bitop_init,long_bitop_expect),
.num_statements = num_statements (long_bitop_3b_statements),
.statements = long_bitop_3b_statements,
.init_globals = (pr_int_t *) long_bitop_init,
.expect_globals = (pr_int_t *) long_bitop_expect,
},
{
.desc = "long bitop 4",
.extra_globals = 4 * 1,
.num_globals = num_globals(long_bitop_init,long_bitop_expect),
.num_statements = num_statements (long_bitop_4_statements),
.statements = long_bitop_4_statements,
.init_globals = (pr_int_t *) long_bitop_init,
.expect_globals = (pr_int_t *) long_bitop_expect,
},
};
#include "main.c"

View file

@ -0,0 +1,193 @@
#include "head.c"
#define DB 0xdeadbeef
static pr_int_t test_globals_init[] = {
-1, 1, 0, DB, DB,
};
static pr_int_t test_globals_expect[] = {
-1, 1, 0, DB, 1,
};
static dstatement_t ifz_taken_statements[] = {
{ OP_IFZ, 4, 0, 2 },
{ OP_LEA_A, 1, 0, 3 },
{ OP_LEA_A, 1, 0, 4 },
{ OP_BREAK },
{ OP_IFZ, -2, 0, 2 },
};
static dstatement_t ifb_taken_statements[] = {
{ OP_IFB, 4, 0, 0 },
{ OP_LEA_A, 1, 0, 3 },
{ OP_LEA_A, 1, 0, 4 },
{ OP_BREAK },
{ OP_IFB, -2, 0, 0 },
};
static dstatement_t ifa_taken_statements[] = {
{ OP_IFA, 4, 0, 1 },
{ OP_LEA_A, 1, 0, 3 },
{ OP_LEA_A, 1, 0, 4 },
{ OP_BREAK },
{ OP_IFA, -2, 0, 1 },
};
static dstatement_t ifnz_taken_statements[] = {
{ OP_IFNZ, 4, 0, 0 },
{ OP_LEA_A, 1, 0, 3 },
{ OP_LEA_A, 1, 0, 4 },
{ OP_BREAK },
{ OP_IFNZ, -2, 0, 1 },
};
static dstatement_t ifae_taken_statements[] = {
{ OP_IFAE, 4, 0, 1 },
{ OP_LEA_A, 1, 0, 3 },
{ OP_LEA_A, 1, 0, 4 },
{ OP_BREAK },
{ OP_IFAE, -2, 0, 2 },
};
static dstatement_t ifbe_taken_statements[] = {
{ OP_IFBE, 4, 0, 0 },
{ OP_LEA_A, 1, 0, 3 },
{ OP_LEA_A, 1, 0, 4 },
{ OP_BREAK },
{ OP_IFBE, -2, 0, 2 },
};
static dstatement_t ifz_not_taken_statements[] = {
{ OP_IFZ, 3, 0, 0 },
{ OP_IFZ, 2, 0, 1 },
{ OP_LEA_A, 1, 0, 4 },
};
static dstatement_t ifb_not_taken_statements[] = {
{ OP_IFB, 3, 0, 2 },
{ OP_IFB, 2, 0, 1 },
{ OP_LEA_A, 1, 0, 4 },
};
static dstatement_t ifa_not_taken_statements[] = {
{ OP_IFA, 3, 0, 2 },
{ OP_IFA, 2, 0, 0 },
{ OP_LEA_A, 1, 0, 4 },
};
static dstatement_t ifnz_not_taken_statements[] = {
{ OP_IFNZ, 3, 0, 2 },
{ OP_LEA_A, 1, 0, 4 },
};
static dstatement_t ifae_not_taken_statements[] = {
{ OP_IFAE, 2, 0, 0 },
{ OP_LEA_A, 1, 0, 4 },
};
static dstatement_t ifbe_not_taken_statements[] = {
{ OP_IFBE, 2, 0, 1 },
{ OP_LEA_A, 1, 0, 4 },
};
test_t tests[] = {
{
.desc = "ifz taken",
.num_globals = num_globals (test_globals_init, test_globals_expect),
.num_statements = num_statements (ifz_taken_statements),
.statements = ifz_taken_statements,
.init_globals = test_globals_init,
.expect_globals = test_globals_expect,
},
{
.desc = "ifb taken",
.num_globals = num_globals (test_globals_init, test_globals_expect),
.num_statements = num_statements (ifb_taken_statements),
.statements = ifb_taken_statements,
.init_globals = test_globals_init,
.expect_globals = test_globals_expect,
},
{
.desc = "ifa taken",
.num_globals = num_globals (test_globals_init, test_globals_expect),
.num_statements = num_statements (ifa_taken_statements),
.statements = ifa_taken_statements,
.init_globals = test_globals_init,
.expect_globals = test_globals_expect,
},
{
.desc = "ifnz taken",
.num_globals = num_globals (test_globals_init, test_globals_expect),
.num_statements = num_statements (ifnz_taken_statements),
.statements = ifnz_taken_statements,
.init_globals = test_globals_init,
.expect_globals = test_globals_expect,
},
{
.desc = "ifae taken",
.num_globals = num_globals (test_globals_init, test_globals_expect),
.num_statements = num_statements (ifae_taken_statements),
.statements = ifae_taken_statements,
.init_globals = test_globals_init,
.expect_globals = test_globals_expect,
},
{
.desc = "ifbe taken",
.num_globals = num_globals (test_globals_init, test_globals_expect),
.num_statements = num_statements (ifbe_taken_statements),
.statements = ifbe_taken_statements,
.init_globals = test_globals_init,
.expect_globals = test_globals_expect,
},
{
.desc = "ifz not taken",
.num_globals = num_globals (test_globals_init, test_globals_expect),
.num_statements = num_statements (ifz_not_taken_statements),
.statements = ifz_not_taken_statements,
.init_globals = test_globals_init,
.expect_globals = test_globals_expect,
},
{
.desc = "ifb not taken",
.num_globals = num_globals (test_globals_init, test_globals_expect),
.num_statements = num_statements (ifb_not_taken_statements),
.statements = ifb_not_taken_statements,
.init_globals = test_globals_init,
.expect_globals = test_globals_expect,
},
{
.desc = "ifa not taken",
.num_globals = num_globals (test_globals_init, test_globals_expect),
.num_statements = num_statements (ifa_not_taken_statements),
.statements = ifa_not_taken_statements,
.init_globals = test_globals_init,
.expect_globals = test_globals_expect,
},
{
.desc = "ifnz not taken",
.num_globals = num_globals (test_globals_init, test_globals_expect),
.num_statements = num_statements (ifnz_not_taken_statements),
.statements = ifnz_not_taken_statements,
.init_globals = test_globals_init,
.expect_globals = test_globals_expect,
},
{
.desc = "ifae not taken",
.num_globals = num_globals (test_globals_init, test_globals_expect),
.num_statements = num_statements (ifae_not_taken_statements),
.statements = ifae_not_taken_statements,
.init_globals = test_globals_init,
.expect_globals = test_globals_expect,
},
{
.desc = "ifbe not taken",
.num_globals = num_globals (test_globals_init, test_globals_expect),
.num_statements = num_statements (ifbe_not_taken_statements),
.statements = ifbe_not_taken_statements,
.init_globals = test_globals_init,
.expect_globals = test_globals_expect,
},
};
#include "main.c"

View file

@ -0,0 +1,208 @@
#include "head.c"
#include "QF/mathlib.h"
#define sq(x) ((float)(x)*(float)(x))
#define pi_6 0x3f060a92 // pi/6
#define r3_2 0x3f5db3d7 // sqrt(3)/2
#define f1_2 0x3f000000 // 1/2
#define f1 0x3f800000 // 1
#define f2 0x40000000 // 2
#define shx 0x3f0c4020 // sinh(pi/6)
#define chx 0x3f91f354 // cosh(pi/6)
#define DB 0xdeadbeef
#define STK (32 * 4) // stack ptr just after globals
static pr_ivec4_t callret_init[32] = {
{ 0, pi_6, 2, 0},
{ f1, f2, 0, 0},
// result
{ DB, DB, DB, DB },
// pre-call with
{ DB, DB, DB, DB },
// post-call with
{ DB, DB, DB, DB },
{ DB, DB, DB, DB },
};
static pr_ivec4_t callret_expect[32] = {
// constants
{ 0, pi_6, 2, 0 },
{ f1, f2, 0, 0 },
// result
{ r3_2, f1_2, chx, shx },
// pre-call with: should be all 0 on progs init
{ 0, 0, 0, 0 },
// post-call with; should be restored to pre-call values (in this case,
// progs init)
{ 0, 0, 0, 0 },
{ DB, DB, DB, DB },
};
static dstatement_t callret_statements[] = {
{ OP_WITH, 8, 0, 0 }, // pushregs
{ OP_POP_A_4, 12, 0, 0 },
{ OP_STORE_A_1, 7, 0, STK }, // save stack pointer for check
{ OP_PUSH_A_1, 1, 0, 0 },
{ OP_CALL_B, 2, 0, 8 },
{ OP_LEA_C, STK, 4, STK }, // discard param
{ OP_SUB_I_1, 7, STK, 7 }, // check stack restored
{ OP_WITH, 8, 0, 0 }, // pushregs
{ OP_POP_A_4, 16, 0, 0 },
{ OP_BREAK },
// cos_sin_cosh_sinh:
// calculate cos(x), sin(x), cosh(x) and sinh(x) simultaneously
[32]=
{ OP_WITH, 2, 0, 1 }, // put params into reg 1
{ OP_LEA_C, STK, -24, STK }, // reserve 24 words on the stack
{ OP_WITH, 2, 0, 2 }, // put locals into reg 2
#define x 0 // in parameters float
#define xn 0 // in locals vec4
#define x2 4 // in locals vec4
#define ac 8 // in locals vec4
#define fa 12 // in locals vec4
#define fi 16 // in locals vec4
#define c 20 // in locals int
{ OP(2, 0, 1, OP_STORE_A_1), xn+1,0, x }, // init xn to [1, x, 0, 0]
{ OP(2, 0, 0, OP_STORE_A_1), xn, 0, 4 },
{ OP(2, 0, 2, OP_SWIZZLE_F), xn, 0x0044, xn }, // xn -> [1, x, 1, x]
{ OP(1, 1, 2, OP_MUL_F_1), x, x, x2 }, // x2 -> [x*x, ?, ?, ?]
{ OP(2, 0, 2, OP_SWIZZLE_F), x2, 0x0300, x2},//x2 -> [-x*x, -x*x, x*x, x*x]
{ OP(2, 0, 0, OP_STORE_A_1), fa, 0, 4 }, // init factorial
{ OP(2, 0, 0, OP_STORE_A_1), fa+1,0, 5 },
{ OP(2, 0, 2, OP_SWIZZLE_F), fa, 0x0044, fa }, // fa -> [1, 2, 1, 2]
{ OP(2, 0, 2, OP_SWIZZLE_F), fa, 0x0000, fi }, // init fi -> [1, 1, 1, 1]
{ OP(2, 2, 2, OP_SUB_F_4), ac, ac, ac }, // init acc (output) to 0
{ OP(0, 0, 2, OP_LEA_A), 25, 0, c }, // init count
// loop:
{ OP(2, 2, 2, OP_ADD_F_4), ac, xn, ac }, // acc += xn
{ OP(2, 2, 2, OP_MUL_F_4), xn, x2, xn }, // xn *= x2
{ OP(2, 2, 2, OP_DIV_F_4), xn, fa, xn }, // xn /= f
{ OP(2, 2, 2, OP_ADD_F_4), fa, fi, fa }, // f += inc
{ OP(2, 2, 2, OP_DIV_F_4), xn, fa, xn }, // xn /= f
{ OP(2, 2, 2, OP_ADD_F_4), fa, fi, fa }, // f += inc
{ OP(2, 0, 2, OP_LEA_C), c, -1, c }, // dec count
{ OP(0, 0, 2, OP_IFA), -7, 0, c }, // count > 0
{ OP(2, 0, 0, OP_RETURN), ac, 0, 3 }, // size is (c&31)+1
#undef x
#undef xn
#undef x2
#undef ac
#undef fa
#undef fi
#undef c
};
static pr_ivec4_t call32_init[32] = {
{ 0, 2, 0, 0 },
{ DB, DB, DB, DB },
{ DB, DB, DB, DB },
{ DB, DB, DB, DB },
{ DB, DB, DB, DB },
{ DB, DB, DB, DB },
{ DB, DB, DB, DB },
{ DB, DB, DB, DB },
{ DB, DB, DB, DB },
};
static pr_ivec4_t call32_expect[32] = {
{ 0, 2, 0, 0 },
{ 0, 1, 2, 3 },
{ 4, 5, 6, 7 },
{ 8, 9, 10, 11 },
{ 12, 13, 14, 15 },
{ 16, 17, 18, 19 },
{ 20, 21, 22, 23 },
{ 24, 25, 26, 27 },
{ 28, 29, 30, 31 },
};
static dstatement_t call32_statements[] = {
{ OP_CALL_B, 1, 0, 4 },
{ OP_BREAK },
[32]=
{ OP_LEA_C, STK, -36, STK }, // reserve 36 words on the stack
{ OP_WITH, 2, 0, 2 }, // put locals into reg 2
{ OP(0, 0, 2, OP_LEA_A), 32, 0, 32 }, // init index
{ OP(2, 0, 2, OP_LEA_A), 0, 0, 33 }, // init base to array
//loop:
{ OP(0, 0, 2, OP_IFBE), 4, 0, 32 }, // if index-- > 0
{ OP(2, 0, 2, OP_LEA_C), 32, -1, 32 },
{ OP(2, 2, 2, OP_STORE_D_1), 33, 32, 32 }, // array[index] = index
{ OP(0, 0, 0, OP_JUMP_A), -3, 0, 0 },
{ OP(2, 0, 0, OP_RETURN), 0, 0, 0x1f }, // only bits 0-5 are size
};
static pr_ivec4_t callchain_init[32] = {
{ 0, 2, 3, 4 },
{ DB, DB, DB, DB },
};
static pr_ivec4_t callchain_expect[32] = {
{ 0, 2, 3, 4 },
{ 42, DB, DB, DB },
};
static dstatement_t callchain_statements[] = {
{ OP_CALL_B, 1, 0, 4 },
{ OP_BREAK },
[32]=
{ OP_LEA_C, STK, -4, STK }, // reserve 4 words on the stack
{ OP_WITH, 2, 0, 2 }, // put locals into reg 2
{ OP(0, 0, 2, OP_CALL_B), 2, 0, 0 },
{ OP(0, 0, 2, OP_CALL_B), 3, 0, 1 },
{ OP(2, 0, 0, OP_RETURN), 0, 0, 0 },
[64]=
{ OP_LEA_C, STK, -4, STK }, // reserve 4 words on the stack
{ OP_WITH, 2, 0, 2 }, // put locals into reg 2
{ OP(0, 0, 2, OP_LEA_A), 42, 0, 0 }, // init value
{ OP(2, 0, 0, OP_RETURN), 0, 0, 0 }, // return value
[96]=
{ OP_RETURN, 0, 0, -1 } // void return
};
static bfunction_t callret_functions[] = {
{ .first_statement = 32 },
{ .first_statement = 64 },
{ .first_statement = 96 },
};
test_t tests[] = {
{
.desc = "callret",
.num_globals = num_globals(callret_init,callret_expect),
.num_statements = num_statements (callret_statements),
.statements = callret_statements,
.init_globals = (pr_int_t *) callret_init,
.expect_globals = (pr_int_t *) callret_expect,
.functions = callret_functions,
.num_functions = num_functions(callret_functions),
.stack_size = 128,
},
{
.desc = "call32",
.num_globals = num_globals(call32_init,call32_expect),
.num_statements = num_statements (call32_statements),
.statements = call32_statements,
.init_globals = (pr_int_t *) call32_init,
.expect_globals = (pr_int_t *) call32_expect,
.functions = callret_functions,
.num_functions = num_functions(callret_functions),
.stack_size = 128,
},
{
.desc = "callchain",
.num_globals = num_globals(callchain_init,callchain_expect),
.num_statements = num_statements (callchain_statements),
.statements = callchain_statements,
.init_globals = (pr_int_t *) callchain_init,
.expect_globals = (pr_int_t *) callchain_expect,
.functions = callret_functions,
.num_functions = num_functions(callret_functions),
.stack_size = 128,
},
};
#include "main.c"

View file

@ -0,0 +1,190 @@
#include "head.c"
#include "QF/mathlib.h"
static pr_ivec4_t int_conv_init[] = {
{ 5, -5, 0x80000000, 0x7fffffff}, //int
{ 0x3fc00000, 0xbfc00000, 0x7149f2ca, 0xf149f2ca}, //float 1e30, -1e30
{ 99, 0x80000000, 0x80000000, 99}, //long
{ 256, 0, 0x7fffffff, 0}, //long
{ 0x39a08cea, 0x46293e59, 0x39a08cea, 0xc6293e59}, //double 1e30, -1e30
{ 0, 0x3ff80000, 0, 0xbff80000}, //double 1.5, -1.5
{ 5, -5, 0x80000000, 0x7fffffff}, //uint
{ ~0, 1, 0x80000000, 0}, //bool32
{ 99, 0x80000000, 0x80000000, 99}, //ulong
{ 256, 0, 0x7fffffff, 0}, //ulong
{ ~0, ~0, ~0, 0}, //bool64
{ 0, ~0, 0, 0}, //bool64
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
};
static pr_ivec4_t int_conv_expect[] = {
{ 5, -5, 0x80000000, 0x7fffffff}, //int
{ 0x3fc00000, 0xbfc00000, 0x7149f2ca, 0xf149f2ca}, //float
{ 99, 0x80000000, 0x80000000, 99}, //long
{ 256, 0, 0x7fffffff, 0}, //long
{ 0x39a08cea, 0x46293e59, 0x39a08cea, 0xc6293e59}, //double 1e30, -1e30
{ 0, 0x3ff80000, 0, 0xbff80000}, //double 1.5, -1.5
{ 5, -5, 0x80000000, 0x7fffffff}, //uint
{ ~0, 1, 0x80000000, 0}, //bool32
{ 99, 0x80000000, 0x80000000, 99}, //ulong
{ 256, 0, 0x7fffffff, 0}, //ulong
{ ~0, ~0, ~0, 0}, //bool64
{ 0, ~0, 0, 0}, //bool64
{ 5, -5, 0x80000000, 0x7fffffff}, // int
{ 1, -1, 0x80000000, 0x80000000}, // float undef?
{ 99, 0x80000000, 256, 0x7fffffff}, // long
{ 0x80000000, 0x80000000, 1, -1}, // double undef?
{ 5, -5, 0x80000000, 0x7fffffff}, // uint
{ 1, 1, 1, 0}, // bool32
{ 99, 0x80000000, 256, 0x7fffffff}, // ulong
{ 1, 1, 1, 0}, // bool64
};
static dstatement_t int_conv_1_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 4, 0, 80 }, // init index
{ OP(0, 0, 0, OP_LEA_A), 8, 0, 81 }, // init index for 64-bits
//loop:
{ OP(0, 0, 0, OP_LEA_C), 80, -1, 80 }, // dec index
{ OP(0, 0, 0, OP_LEA_C), 81, -2, 81 }, // dec index for 64-bits
{ OP(0, 0, 0, OP_IFAE), 2, 0, 80 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 80, 1 },
{ OP(0, 0, 0, OP_WITH), 4, 81, 2 },
{ OP(1, 1, 1, OP_CONV), 0, 0000, 48 },
{ OP(1, 1, 1, OP_CONV), 4, 0010, 52 },
{ OP(2, 1, 1, OP_CONV), 8, 0020, 56 },
{ OP(2, 1, 1, OP_CONV), 16, 0030, 60 },
{ OP(1, 1, 1, OP_CONV), 24, 0040, 64 },
{ OP(1, 1, 1, OP_CONV), 28, 0050, 68 },
{ OP(2, 1, 1, OP_CONV), 32, 0060, 72 },
{ OP(2, 1, 1, OP_CONV), 40, 0070, 76 },
{ OP(1, 1, 1, OP_JUMP_A), -14, 0, 0 },
};
static dstatement_t int_conv_2_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 4, 0, 80 }, // index
{ OP(0, 0, 0, OP_LEA_A), 8, 0, 81 }, // init index for 64-bits
//loop:
{ OP(0, 0, 0, OP_LEA_C), 80, -2, 80 }, // dec index
{ OP(0, 0, 0, OP_LEA_C), 81, -4, 81 }, // dec index for 64-bits
{ OP(0, 0, 0, OP_IFAE), 2, 0, 80 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 80, 1 },
{ OP(0, 0, 0, OP_WITH), 4, 81, 2 },
{ OP(1, 1, 1, OP_CONV), 0, 0100, 48 },
{ OP(1, 1, 1, OP_CONV), 4, 0110, 52 },
{ OP(2, 1, 1, OP_CONV), 8, 0120, 56 },
{ OP(2, 1, 1, OP_CONV), 16, 0130, 60 },
{ OP(1, 1, 1, OP_CONV), 24, 0140, 64 },
{ OP(1, 1, 1, OP_CONV), 28, 0150, 68 },
{ OP(2, 1, 1, OP_CONV), 32, 0160, 72 },
{ OP(2, 1, 1, OP_CONV), 40, 0170, 76 },
{ OP(1, 1, 1, OP_JUMP_A), -14, 0, 0 },
};
static dstatement_t int_conv_3a_statements[] = {
{ OP(1, 1, 1, OP_CONV), 0, 0200, 48 },
{ OP(1, 1, 1, OP_CONV), 3, 0200, 51 },
{ OP(1, 1, 1, OP_CONV), 4, 0210, 52 },
{ OP(1, 1, 1, OP_CONV), 7, 0010, 55 },
{ OP(2, 1, 1, OP_CONV), 8, 0220, 56 },
{ OP(2, 1, 1, OP_CONV), 14, 0020, 59 },
{ OP(2, 1, 1, OP_CONV), 16, 0230, 60 },
{ OP(2, 1, 1, OP_CONV), 22, 0030, 63 },
{ OP(1, 1, 1, OP_CONV), 24, 0240, 64 },
{ OP(1, 1, 1, OP_CONV), 27, 0240, 67 },
{ OP(1, 1, 1, OP_CONV), 28, 0250, 68 },
{ OP(1, 1, 1, OP_CONV), 31, 0050, 71 },
{ OP(2, 1, 1, OP_CONV), 32, 0260, 72 },
{ OP(2, 1, 1, OP_CONV), 38, 0060, 75 },
{ OP(2, 1, 1, OP_CONV), 40, 0270, 76 },
{ OP(2, 1, 1, OP_CONV), 46, 0070, 79 },
};
static dstatement_t int_conv_3b_statements[] = {
{ OP(1, 1, 1, OP_CONV), 0, 0200, 48 },
{ OP(1, 1, 1, OP_CONV), 1, 0200, 49 },
{ OP(1, 1, 1, OP_CONV), 4, 0010, 52 },
{ OP(1, 1, 1, OP_CONV), 5, 0210, 53 },
{ OP(2, 1, 1, OP_CONV), 8, 0020, 56 },
{ OP(2, 1, 1, OP_CONV), 10, 0220, 57 },
{ OP(2, 1, 1, OP_CONV), 16, 0030, 60 },
{ OP(2, 1, 1, OP_CONV), 18, 0230, 61 },
{ OP(1, 1, 1, OP_CONV), 24, 0240, 64 },
{ OP(1, 1, 1, OP_CONV), 25, 0240, 65 },
{ OP(1, 1, 1, OP_CONV), 28, 0050, 68 },
{ OP(1, 1, 1, OP_CONV), 29, 0250, 69 },
{ OP(2, 1, 1, OP_CONV), 32, 0060, 72 },
{ OP(2, 1, 1, OP_CONV), 34, 0260, 73 },
{ OP(2, 1, 1, OP_CONV), 40, 0070, 76 },
{ OP(2, 1, 1, OP_CONV), 42, 0270, 77 },
};
static dstatement_t int_conv_4_statements[] = {
{ OP(1, 1, 1, OP_CONV), 0, 0300, 48 },
{ OP(1, 1, 1, OP_CONV), 4, 0310, 52 },
{ OP(2, 1, 1, OP_CONV), 8, 0320, 56 },
{ OP(2, 1, 1, OP_CONV), 16, 0330, 60 },
{ OP(1, 1, 1, OP_CONV), 28, 0350, 68 },
{ OP(2, 1, 1, OP_CONV), 32, 0360, 72 },
{ OP(2, 1, 1, OP_CONV), 40, 0370, 76 },
{ OP(1, 1, 1, OP_CONV), 24, 0340, 64 },
};
test_t tests[] = {
{
.desc = "int conv 1",
.extra_globals = 4 * 1,
.num_globals = num_globals(int_conv_init,int_conv_expect),
.num_statements = num_statements (int_conv_1_statements),
.statements = int_conv_1_statements,
.init_globals = (pr_int_t *) int_conv_init,
.expect_globals = (pr_int_t *) int_conv_expect,
},
{
.desc = "int conv 2",
.extra_globals = 4 * 1,
.num_globals = num_globals(int_conv_init,int_conv_expect),
.num_statements = num_statements (int_conv_2_statements),
.statements = int_conv_2_statements,
.init_globals = (pr_int_t *) int_conv_init,
.expect_globals = (pr_int_t *) int_conv_expect,
},
{
.desc = "int conv 3a",
.extra_globals = 4 * 1,
.num_globals = num_globals(int_conv_init,int_conv_expect),
.num_statements = num_statements (int_conv_3a_statements),
.statements = int_conv_3a_statements,
.init_globals = (pr_int_t *) int_conv_init,
.expect_globals = (pr_int_t *) int_conv_expect,
},
{
.desc = "int conv 3b",
.extra_globals = 4 * 1,
.num_globals = num_globals(int_conv_init,int_conv_expect),
.num_statements = num_statements (int_conv_3b_statements),
.statements = int_conv_3b_statements,
.init_globals = (pr_int_t *) int_conv_init,
.expect_globals = (pr_int_t *) int_conv_expect,
},
{
.desc = "int conv 4",
.extra_globals = 4 * 1,
.num_globals = num_globals(int_conv_init,int_conv_expect),
.num_statements = num_statements (int_conv_4_statements),
.statements = int_conv_4_statements,
.init_globals = (pr_int_t *) int_conv_init,
.expect_globals = (pr_int_t *) int_conv_expect,
},
};
#include "main.c"

View file

@ -0,0 +1,190 @@
#include "head.c"
#include "QF/mathlib.h"
static pr_ivec4_t float_conv_init[] = {
{ 5, -5, 0x80000000, 0x7fffffff}, //int
{ 0x3fc00000, 0xbfc00000, 0x7149f2ca, 0xf149f2ca}, //float 1e30, -1e30
{ 99, 0x80000000, 0x80000000, 99}, //long
{ 256, 0, 0x7fffffff, 0}, //long
{ 0x39a08cea, 0x46293e59, 0x39a08cea, 0xc6293e59}, //double 1e30, -1e30
{ 0, 0x3ff80000, 0, 0xbff80000}, //double 1.5, -1.5
{ 5, -5, 0x80000000, 0x7fffffff}, //uint
{ ~0, 1, 0x80000000, 0}, //bool32
{ 99, 0x80000000, 0x80000000, 99}, //ulong
{ 256, 0, 0x7fffffff, 0}, //ulong
{ ~0, ~0, ~0, 0}, //bool64
{ 0, ~0, 0, 0}, //bool64
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
};
static pr_ivec4_t float_conv_expect[] = {
{ 5, -5, 0x80000000, 0x7fffffff}, //int
{ 0x3fc00000, 0xbfc00000, 0x7149f2ca, 0xf149f2ca}, //float
{ 99, 0x80000000, 0x80000000, 99}, //long
{ 256, 0, 0x7fffffff, 0}, //long
{ 0x39a08cea, 0x46293e59, 0x39a08cea, 0xc6293e59}, //double 1e30, -1e30
{ 0, 0x3ff80000, 0, 0xbff80000}, //double 1.5, -1.5
{ 5, -5, 0x80000000, 0x7fffffff}, //uint
{ ~0, 1, 0x80000000, 0}, //bool32
{ 99, 0x80000000, 0x80000000, 99}, //ulong
{ 256, 0, 0x7fffffff, 0}, //ulong
{ ~0, ~0, ~0, 0}, //bool64
{ 0, ~0, 0, 0}, //bool64
{ 0x40a00000, 0xc0a00000, 0xcf000000, 0x4f000000}, // int
{ 0x3fc00000, 0xbfc00000, 0x7149f2ca, 0xf149f2ca}, // float
{ 0xdf000000, 0x52c70000, 0x43800000, 0x4f000000}, // long
{ 0x7149f2ca, 0xf149f2ca, 0x3fc00000, 0xbfc00000}, // double
{ 0x40a00000, 0x4f800000, 0x4f000000, 0x4f000000}, // uint
{ 0x3f800000, 0x3f800000, 0x3f800000, 0}, // bool32
{ 0x5f000000, 0x52c70000, 0x43800000, 0x4f000000}, // ulong
{ 0x3f800000, 0x3f800000, 0x3f800000, 0}, // bool64
};
static dstatement_t float_conv_1_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 4, 0, 80 }, // init index
{ OP(0, 0, 0, OP_LEA_A), 8, 0, 81 }, // init index for 64-bits
//loop:
{ OP(0, 0, 0, OP_LEA_C), 80, -1, 80 }, // dec index
{ OP(0, 0, 0, OP_LEA_C), 81, -2, 81 }, // dec index for 64-bits
{ OP(0, 0, 0, OP_IFAE), 2, 0, 80 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 80, 1 },
{ OP(0, 0, 0, OP_WITH), 4, 81, 2 },
{ OP(1, 1, 1, OP_CONV), 0, 0001, 48 },
{ OP(1, 1, 1, OP_CONV), 4, 0011, 52 },
{ OP(2, 1, 1, OP_CONV), 8, 0021, 56 },
{ OP(2, 1, 1, OP_CONV), 16, 0031, 60 },
{ OP(1, 1, 1, OP_CONV), 24, 0041, 64 },
{ OP(1, 1, 1, OP_CONV), 28, 0051, 68 },
{ OP(2, 1, 1, OP_CONV), 32, 0061, 72 },
{ OP(2, 1, 1, OP_CONV), 40, 0071, 76 },
{ OP(1, 1, 1, OP_JUMP_A), -14, 0, 0 },
};
static dstatement_t float_conv_2_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 4, 0, 80 }, // index
{ OP(0, 0, 0, OP_LEA_A), 8, 0, 81 }, // init index for 64-bits
//loop:
{ OP(0, 0, 0, OP_LEA_C), 80, -2, 80 }, // dec index
{ OP(0, 0, 0, OP_LEA_C), 81, -4, 81 }, // dec index for 64-bits
{ OP(0, 0, 0, OP_IFAE), 2, 0, 80 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 80, 1 },
{ OP(0, 0, 0, OP_WITH), 4, 81, 2 },
{ OP(1, 1, 1, OP_CONV), 0, 0101, 48 },
{ OP(1, 1, 1, OP_CONV), 4, 0111, 52 },
{ OP(2, 1, 1, OP_CONV), 8, 0121, 56 },
{ OP(2, 1, 1, OP_CONV), 16, 0131, 60 },
{ OP(1, 1, 1, OP_CONV), 24, 0141, 64 },
{ OP(1, 1, 1, OP_CONV), 28, 0151, 68 },
{ OP(2, 1, 1, OP_CONV), 32, 0161, 72 },
{ OP(2, 1, 1, OP_CONV), 40, 0171, 76 },
{ OP(1, 1, 1, OP_JUMP_A), -14, 0, 0 },
};
static dstatement_t float_conv_3a_statements[] = {
{ OP(1, 1, 1, OP_CONV), 0, 0201, 48 },
{ OP(1, 1, 1, OP_CONV), 3, 0001, 51 },
{ OP(1, 1, 1, OP_CONV), 4, 0211, 52 },
{ OP(1, 1, 1, OP_CONV), 7, 0011, 55 },
{ OP(2, 1, 1, OP_CONV), 8, 0221, 56 },
{ OP(2, 1, 1, OP_CONV), 14, 0021, 59 },
{ OP(2, 1, 1, OP_CONV), 16, 0231, 60 },
{ OP(2, 1, 1, OP_CONV), 22, 0031, 63 },
{ OP(1, 1, 1, OP_CONV), 24, 0241, 64 },
{ OP(1, 1, 1, OP_CONV), 27, 0041, 67 },
{ OP(1, 1, 1, OP_CONV), 28, 0251, 68 },
{ OP(1, 1, 1, OP_CONV), 31, 0051, 71 },
{ OP(2, 1, 1, OP_CONV), 32, 0261, 72 },
{ OP(2, 1, 1, OP_CONV), 38, 0061, 75 },
{ OP(2, 1, 1, OP_CONV), 40, 0271, 76 },
{ OP(2, 1, 1, OP_CONV), 46, 0071, 79 },
};
static dstatement_t float_conv_3b_statements[] = {
{ OP(1, 1, 1, OP_CONV), 0, 0001, 48 },
{ OP(1, 1, 1, OP_CONV), 1, 0201, 49 },
{ OP(1, 1, 1, OP_CONV), 4, 0011, 52 },
{ OP(1, 1, 1, OP_CONV), 5, 0211, 53 },
{ OP(2, 1, 1, OP_CONV), 8, 0021, 56 },
{ OP(2, 1, 1, OP_CONV), 10, 0221, 57 },
{ OP(2, 1, 1, OP_CONV), 16, 0031, 60 },
{ OP(2, 1, 1, OP_CONV), 18, 0231, 61 },
{ OP(1, 1, 1, OP_CONV), 24, 0241, 64 },
{ OP(1, 1, 1, OP_CONV), 27, 0041, 67 },
{ OP(1, 1, 1, OP_CONV), 28, 0051, 68 },
{ OP(1, 1, 1, OP_CONV), 29, 0251, 69 },
{ OP(2, 1, 1, OP_CONV), 32, 0061, 72 },
{ OP(2, 1, 1, OP_CONV), 34, 0261, 73 },
{ OP(2, 1, 1, OP_CONV), 40, 0071, 76 },
{ OP(2, 1, 1, OP_CONV), 42, 0271, 77 },
};
static dstatement_t float_conv_4_statements[] = {
{ OP(1, 1, 1, OP_CONV), 0, 0301, 48 },
{ OP(1, 1, 1, OP_CONV), 4, 0311, 52 },
{ OP(2, 1, 1, OP_CONV), 8, 0321, 56 },
{ OP(2, 1, 1, OP_CONV), 16, 0331, 60 },
{ OP(1, 1, 1, OP_CONV), 24, 0341, 64 },
{ OP(1, 1, 1, OP_CONV), 28, 0351, 68 },
{ OP(2, 1, 1, OP_CONV), 32, 0361, 72 },
{ OP(2, 1, 1, OP_CONV), 40, 0371, 76 },
};
test_t tests[] = {
{
.desc = "float conv 1",
.extra_globals = 4 * 1,
.num_globals = num_globals(float_conv_init,float_conv_expect),
.num_statements = num_statements (float_conv_1_statements),
.statements = float_conv_1_statements,
.init_globals = (pr_int_t *) float_conv_init,
.expect_globals = (pr_int_t *) float_conv_expect,
},
{
.desc = "float conv 2",
.extra_globals = 4 * 1,
.num_globals = num_globals(float_conv_init,float_conv_expect),
.num_statements = num_statements (float_conv_2_statements),
.statements = float_conv_2_statements,
.init_globals = (pr_int_t *) float_conv_init,
.expect_globals = (pr_int_t *) float_conv_expect,
},
{
.desc = "float conv 3a",
.extra_globals = 4 * 1,
.num_globals = num_globals(float_conv_init,float_conv_expect),
.num_statements = num_statements (float_conv_3a_statements),
.statements = float_conv_3a_statements,
.init_globals = (pr_int_t *) float_conv_init,
.expect_globals = (pr_int_t *) float_conv_expect,
},
{
.desc = "float conv 3b",
.extra_globals = 4 * 1,
.num_globals = num_globals(float_conv_init,float_conv_expect),
.num_statements = num_statements (float_conv_3b_statements),
.statements = float_conv_3b_statements,
.init_globals = (pr_int_t *) float_conv_init,
.expect_globals = (pr_int_t *) float_conv_expect,
},
{
.desc = "float conv 4",
.extra_globals = 4 * 1,
.num_globals = num_globals(float_conv_init,float_conv_expect),
.num_statements = num_statements (float_conv_4_statements),
.statements = float_conv_4_statements,
.init_globals = (pr_int_t *) float_conv_init,
.expect_globals = (pr_int_t *) float_conv_expect,
},
};
#include "main.c"

View file

@ -0,0 +1,206 @@
#include "head.c"
#include "QF/mathlib.h"
static pr_ivec4_t long_conv_init[] = {
{ 5, -5, 0x80000000, 0x7fffffff}, //int
{ 0x3fc00000, 0xbfc00000, 0x7149f2ca, 0xf149f2ca}, //float 1e30, -1e30
{ 99, 0x80000000, 0x80000000, 99}, //long
{ 256, 0, 0x7fffffff, 0}, //long
{ 0x39a08cea, 0x46293e59, 0x39a08cea, 0xc6293e59}, //double 1e30, -1e30
{ 0, 0x3ff80000, 0, 0xbff80000}, //double 1.5, -1.5
{ 5, -5, 0x80000000, 0x7fffffff}, //uint
{ ~0, 1, 0x80000000, 0}, //bool32
{ 99, 0x80000000, 0x80000000, 99}, //ulong
{ 256, 0, 0x7fffffff, 0}, //ulong
{ ~0, ~0, ~0, 0}, //bool64
{ 0, ~0, 0, 0}, //bool64
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
};
static pr_ivec4_t long_conv_expect[] = {
{ 5, -5, 0x80000000, 0x7fffffff}, //int
{ 0x3fc00000, 0xbfc00000, 0x7149f2ca, 0xf149f2ca}, //float
{ 99, 0x80000000, 0x80000000, 99}, //long
{ 256, 0, 0x7fffffff, 0}, //long
{ 0x39a08cea, 0x46293e59, 0x39a08cea, 0xc6293e59}, //double 1e30, -1e30
{ 0, 0x3ff80000, 0, 0xbff80000}, //double 1.5, -1.5
{ 5, -5, 0x80000000, 0x7fffffff}, //uint
{ ~0, 1, 0x80000000, 0}, //bool32
{ 99, 0x80000000, 0x80000000, 99}, //ulong
{ 256, 0, 0x7fffffff, 0}, //ulong
{ ~0, ~0, ~0, 0}, //bool64
{ 0, ~0, 0, 0}, //bool64
{ 5, 0, -5, 0xffffffff}, // int
{ 0x80000000, 0xffffffff, 0x7fffffff, 0},
{ 1, 0, -1, -1}, // float
{ 0, 0x80000000, 0, 0x80000000}, // undef?
{ 99, 0x80000000, 0x80000000, 99}, // long
{ 256, 0, 0x7fffffff, 0},
{ 0, 0x80000000, 0, 0x80000000}, // double undef?
{ 1, 0, -1, -1},
{ 5, 0, -5, 0}, // uint
{ 0x80000000, 0, 0x7fffffff, 0},
{ 1, 0, 1, 0}, // bool32
{ 1, 0, 0, 0},
{ 99, 0x80000000, 0x80000000, 99}, // ulong
{ 256, 0, 0x7fffffff, 0},
{ 1, 0, 1, 0}, // bool64
{ 1, 0, 0, 0},
};
static dstatement_t long_conv_1_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 4, 0, 112 }, // init index
{ OP(0, 0, 0, OP_LEA_A), 8, 0, 113 }, // init index for 64-bits
//loop:
{ OP(0, 0, 0, OP_LEA_C), 112, -1, 112 }, // dec index
{ OP(0, 0, 0, OP_LEA_C), 113, -2, 113 }, // dec index for 64-bits
{ OP(0, 0, 0, OP_IFAE), 2, 0, 112 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 112, 1 },
{ OP(0, 0, 0, OP_WITH), 4, 113, 2 },
{ OP(1, 1, 2, OP_CONV), 0, 0002, 48 },
{ OP(1, 1, 2, OP_CONV), 4, 0012, 56 },
{ OP(2, 1, 2, OP_CONV), 8, 0022, 64 },
{ OP(2, 1, 2, OP_CONV), 16, 0032, 72 },
{ OP(1, 1, 2, OP_CONV), 24, 0042, 80 },
{ OP(1, 1, 2, OP_CONV), 28, 0052, 88 },
{ OP(2, 1, 2, OP_CONV), 32, 0062, 96 },
{ OP(2, 1, 2, OP_CONV), 40, 0072, 104 },
{ OP(0, 0, 0, OP_JUMP_A), -14, 0, 0 },
};
static dstatement_t long_conv_2_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 4, 0, 112 }, // index
{ OP(0, 0, 0, OP_LEA_A), 8, 0, 113 }, // init index for 64-bits
//loop:
{ OP(0, 0, 0, OP_LEA_C), 112, -2, 112 }, // dec index
{ OP(0, 0, 0, OP_LEA_C), 113, -4, 113 }, // dec index for 64-bits
{ OP(0, 0, 0, OP_IFAE), 2, 0, 112 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 112, 1 },
{ OP(0, 0, 0, OP_WITH), 4, 113, 2 },
{ OP(1, 1, 2, OP_CONV), 0, 0102, 48 },
{ OP(1, 1, 2, OP_CONV), 4, 0112, 56 },
{ OP(2, 1, 2, OP_CONV), 8, 0122, 64 },
{ OP(2, 1, 2, OP_CONV), 16, 0132, 72 },
{ OP(1, 1, 2, OP_CONV), 24, 0142, 80 },
{ OP(1, 1, 2, OP_CONV), 28, 0152, 88 },
{ OP(2, 1, 2, OP_CONV), 32, 0162, 96 },
{ OP(2, 1, 2, OP_CONV), 40, 0172, 104 },
{ OP(0, 0, 0, OP_JUMP_A), -14, 0, 0 },
};
static dstatement_t long_conv_3a_statements[] = {
{ OP(1, 1, 2, OP_CONV), 0, 0202, 48 },
{ OP(1, 1, 2, OP_CONV), 3, 0002, 54 },
{ OP(1, 1, 2, OP_CONV), 4, 0212, 56 },
{ OP(1, 1, 2, OP_CONV), 7, 0012, 62 },
{ OP(2, 1, 2, OP_CONV), 8, 0222, 64 },
{ OP(2, 1, 2, OP_CONV), 14, 0022, 70 },
{ OP(2, 1, 2, OP_CONV), 16, 0232, 72 },
{ OP(2, 1, 2, OP_CONV), 22, 0032, 78 },
{ OP(1, 1, 2, OP_CONV), 24, 0242, 80 },
{ OP(1, 1, 2, OP_CONV), 27, 0042, 86 },
{ OP(1, 1, 2, OP_CONV), 28, 0252, 88 },
{ OP(1, 1, 2, OP_CONV), 31, 0052, 94 },
{ OP(2, 1, 2, OP_CONV), 32, 0262, 96 },
{ OP(2, 1, 2, OP_CONV), 38, 0062, 102 },
{ OP(2, 1, 2, OP_CONV), 40, 0272, 104 },
{ OP(2, 1, 2, OP_CONV), 46, 0072, 110 },
};
static dstatement_t long_conv_3b_statements[] = {
{ OP(1, 1, 2, OP_CONV), 0, 0002, 48 },
{ OP(1, 1, 2, OP_CONV), 1, 0202, 50 },
{ OP(1, 1, 2, OP_CONV), 4, 0012, 56 },
{ OP(1, 1, 2, OP_CONV), 5, 0212, 58 },
{ OP(2, 1, 2, OP_CONV), 8, 0022, 64 },
{ OP(2, 1, 2, OP_CONV), 10, 0222, 66 },
{ OP(2, 1, 2, OP_CONV), 16, 0032, 72 },
{ OP(2, 1, 2, OP_CONV), 18, 0232, 74 },
{ OP(1, 1, 2, OP_CONV), 24, 0042, 80 },
{ OP(1, 1, 2, OP_CONV), 25, 0242, 82 },
{ OP(1, 1, 2, OP_CONV), 28, 0052, 88 },
{ OP(1, 1, 2, OP_CONV), 29, 0252, 90 },
{ OP(2, 1, 2, OP_CONV), 32, 0062, 96 },
{ OP(2, 1, 2, OP_CONV), 34, 0262, 98 },
{ OP(2, 1, 2, OP_CONV), 40, 0072, 104 },
{ OP(2, 1, 2, OP_CONV), 42, 0272, 106 },
};
static dstatement_t long_conv_4_statements[] = {
{ OP(1, 1, 2, OP_CONV), 0, 0302, 48 },
{ OP(1, 1, 2, OP_CONV), 4, 0312, 56 },
{ OP(2, 1, 2, OP_CONV), 8, 0322, 64 },
{ OP(2, 1, 2, OP_CONV), 16, 0332, 72 },
{ OP(1, 1, 2, OP_CONV), 24, 0342, 80 },
{ OP(1, 1, 2, OP_CONV), 28, 0352, 88 },
{ OP(2, 1, 2, OP_CONV), 32, 0362, 96 },
{ OP(2, 1, 2, OP_CONV), 40, 0372, 104 },
};
test_t tests[] = {
{
.desc = "long conv 1",
.extra_globals = 4 * 1,
.num_globals = num_globals(long_conv_init,long_conv_expect),
.num_statements = num_statements (long_conv_1_statements),
.statements = long_conv_1_statements,
.init_globals = (pr_int_t *) long_conv_init,
.expect_globals = (pr_int_t *) long_conv_expect,
},
{
.desc = "long conv 2",
.extra_globals = 4 * 1,
.num_globals = num_globals(long_conv_init,long_conv_expect),
.num_statements = num_statements (long_conv_2_statements),
.statements = long_conv_2_statements,
.init_globals = (pr_int_t *) long_conv_init,
.expect_globals = (pr_int_t *) long_conv_expect,
},
{
.desc = "long conv 3a",
.extra_globals = 4 * 1,
.num_globals = num_globals(long_conv_init,long_conv_expect),
.num_statements = num_statements (long_conv_3a_statements),
.statements = long_conv_3a_statements,
.init_globals = (pr_int_t *) long_conv_init,
.expect_globals = (pr_int_t *) long_conv_expect,
},
{
.desc = "long conv 3b",
.extra_globals = 4 * 1,
.num_globals = num_globals(long_conv_init,long_conv_expect),
.num_statements = num_statements (long_conv_3b_statements),
.statements = long_conv_3b_statements,
.init_globals = (pr_int_t *) long_conv_init,
.expect_globals = (pr_int_t *) long_conv_expect,
},
{
.desc = "long conv 4",
.extra_globals = 4 * 1,
.num_globals = num_globals(long_conv_init,long_conv_expect),
.num_statements = num_statements (long_conv_4_statements),
.statements = long_conv_4_statements,
.init_globals = (pr_int_t *) long_conv_init,
.expect_globals = (pr_int_t *) long_conv_expect,
},
};
#include "main.c"

View file

@ -0,0 +1,206 @@
#include "head.c"
#include "QF/mathlib.h"
static pr_ivec4_t double_conv_init[] = {
{ 5, -5, 0x80000000, 0x7fffffff}, //int
{ 0x3fc00000, 0xbfc00000, 0x7149f2ca, 0xf149f2ca}, //float 1e30, -1e30
{ 99, 0x80000000, 0x80000000, 99}, //long
{ 256, 0, 0x7fffffff, 0}, //long
{ 0x39a08cea, 0x46293e59, 0x39a08cea, 0xc6293e59}, //double 1e30, -1e30
{ 0, 0x3ff80000, 0, 0xbff80000}, //double 1.5, -1.5
{ 5, -5, 0x80000000, 0x7fffffff}, //uint
{ ~0, 1, 0x80000000, 0}, //bool32
{ 99, 0x80000000, 0x80000000, 99}, //ulong
{ 256, 0, 0x7fffffff, 0}, //ulong
{ ~0, ~0, ~0, 0}, //bool64
{ 0, ~0, 0, 0}, //bool64
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
};
static pr_ivec4_t double_conv_expect[] = {
{ 5, -5, 0x80000000, 0x7fffffff}, //int
{ 0x3fc00000, 0xbfc00000, 0x7149f2ca, 0xf149f2ca}, //float
{ 99, 0x80000000, 0x80000000, 99}, //long
{ 256, 0, 0x7fffffff, 0}, //long
{ 0x39a08cea, 0x46293e59, 0x39a08cea, 0xc6293e59}, //double 1e30, -1e30
{ 0, 0x3ff80000, 0, 0xbff80000}, //double 1.5, -1.5
{ 5, -5, 0x80000000, 0x7fffffff}, //uint
{ ~0, 1, 0x80000000, 0}, //bool32
{ 99, 0x80000000, 0x80000000, 99}, //ulong
{ 256, 0, 0x7fffffff, 0}, //ulong
{ ~0, ~0, ~0, 0}, //bool64
{ 0, ~0, 0, 0}, //bool64
{ 0x00000000, 0x40140000, 0x00000000, 0xc0140000}, // int
{ 0x00000000, 0xc1e00000, 0xffc00000, 0x41dfffff},
{ 0x00000000, 0x3ff80000, 0x00000000, 0xbff80000}, // float
{ 0x40000000, 0x46293e59, 0x40000000, 0xc6293e59},
{ 0x00000000, 0xc3e00000, 0x00000000, 0x4258e000}, // long
{ 0x00000000, 0x40700000, 0xffc00000, 0x41dfffff},
{ 0x39a08cea, 0x46293e59, 0x39a08cea, 0xc6293e59}, // double
{ 0, 0x3ff80000, 0, 0xbff80000},
{ 0x00000000, 0x40140000, 0xff600000, 0x41efffff}, // uint
{ 0x00000000, 0x41e00000, 0xffc00000, 0x41dfffff},
{ 0x00000000, 0x3ff00000, 0x00000000, 0x3ff00000}, // bool32
{ 0x00000000, 0x3ff00000, 0x00000000, 0x00000000},
{ 0x00000000, 0x43e00000, 0x00000000, 0x4258e000}, // long
{ 0x00000000, 0x40700000, 0xffc00000, 0x41dfffff},
{ 0x00000000, 0x3ff00000, 0x00000000, 0x3ff00000}, // bool64
{ 0x00000000, 0x3ff00000, 0x00000000, 0x00000000},
};
static dstatement_t double_conv_1_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 4, 0, 112 }, // init index
{ OP(0, 0, 0, OP_LEA_A), 8, 0, 113 }, // init index for 64-bits
//loop:
{ OP(0, 0, 0, OP_LEA_C), 112, -1, 112 }, // dec index
{ OP(0, 0, 0, OP_LEA_C), 113, -2, 113 }, // dec index for 64-bits
{ OP(0, 0, 0, OP_IFAE), 2, 0, 112 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 112, 1 },
{ OP(0, 0, 0, OP_WITH), 4, 113, 2 },
{ OP(1, 1, 2, OP_CONV), 0, 0003, 48 },
{ OP(1, 1, 2, OP_CONV), 4, 0013, 56 },
{ OP(2, 1, 2, OP_CONV), 8, 0023, 64 },
{ OP(2, 1, 2, OP_CONV), 16, 0033, 72 },
{ OP(1, 1, 2, OP_CONV), 24, 0043, 80 },
{ OP(1, 1, 2, OP_CONV), 28, 0053, 88 },
{ OP(2, 1, 2, OP_CONV), 32, 0063, 96 },
{ OP(2, 1, 2, OP_CONV), 40, 0073, 104 },
{ OP(0, 0, 0, OP_JUMP_A), -14, 0, 0 },
};
static dstatement_t double_conv_2_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 4, 0, 112 }, // index
{ OP(0, 0, 0, OP_LEA_A), 8, 0, 113 }, // init index for 64-bits
//loop:
{ OP(0, 0, 0, OP_LEA_C), 112, -2, 112 }, // dec index
{ OP(0, 0, 0, OP_LEA_C), 113, -4, 113 }, // dec index for 64-bits
{ OP(0, 0, 0, OP_IFAE), 2, 0, 112 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 112, 1 },
{ OP(0, 0, 0, OP_WITH), 4, 113, 2 },
{ OP(1, 1, 2, OP_CONV), 0, 0103, 48 },
{ OP(1, 1, 2, OP_CONV), 4, 0113, 56 },
{ OP(2, 1, 2, OP_CONV), 8, 0123, 64 },
{ OP(2, 1, 2, OP_CONV), 16, 0133, 72 },
{ OP(1, 1, 2, OP_CONV), 24, 0143, 80 },
{ OP(1, 1, 2, OP_CONV), 28, 0153, 88 },
{ OP(2, 1, 2, OP_CONV), 32, 0163, 96 },
{ OP(2, 1, 2, OP_CONV), 40, 0173, 104 },
{ OP(0, 0, 0, OP_JUMP_A), -14, 0, 0 },
};
static dstatement_t double_conv_3a_statements[] = {
{ OP(1, 1, 2, OP_CONV), 0, 0203, 48 },
{ OP(1, 1, 2, OP_CONV), 3, 0003, 54 },
{ OP(1, 1, 2, OP_CONV), 4, 0213, 56 },
{ OP(1, 1, 2, OP_CONV), 7, 0013, 62 },
{ OP(2, 1, 2, OP_CONV), 8, 0223, 64 },
{ OP(2, 1, 2, OP_CONV), 14, 0023, 70 },
{ OP(2, 1, 2, OP_CONV), 16, 0233, 72 },
{ OP(2, 1, 2, OP_CONV), 22, 0033, 78 },
{ OP(1, 1, 2, OP_CONV), 24, 0243, 80 },
{ OP(1, 1, 2, OP_CONV), 27, 0043, 86 },
{ OP(1, 1, 2, OP_CONV), 28, 0253, 88 },
{ OP(1, 1, 2, OP_CONV), 31, 0053, 94 },
{ OP(2, 1, 2, OP_CONV), 32, 0263, 96 },
{ OP(2, 1, 2, OP_CONV), 38, 0063, 102 },
{ OP(2, 1, 2, OP_CONV), 40, 0273, 104 },
{ OP(2, 1, 2, OP_CONV), 46, 0073, 110 },
};
static dstatement_t double_conv_3b_statements[] = {
{ OP(1, 1, 2, OP_CONV), 0, 0003, 48 },
{ OP(1, 1, 2, OP_CONV), 1, 0203, 50 },
{ OP(1, 1, 2, OP_CONV), 4, 0013, 56 },
{ OP(1, 1, 2, OP_CONV), 5, 0213, 58 },
{ OP(2, 1, 2, OP_CONV), 8, 0023, 64 },
{ OP(2, 1, 2, OP_CONV), 10, 0223, 66 },
{ OP(2, 1, 2, OP_CONV), 16, 0033, 72 },
{ OP(2, 1, 2, OP_CONV), 18, 0233, 74 },
{ OP(1, 1, 2, OP_CONV), 24, 0043, 80 },
{ OP(1, 1, 2, OP_CONV), 25, 0243, 82 },
{ OP(1, 1, 2, OP_CONV), 28, 0053, 88 },
{ OP(1, 1, 2, OP_CONV), 29, 0253, 90 },
{ OP(2, 1, 2, OP_CONV), 32, 0063, 96 },
{ OP(2, 1, 2, OP_CONV), 34, 0263, 98 },
{ OP(2, 1, 2, OP_CONV), 40, 0073, 104 },
{ OP(2, 1, 2, OP_CONV), 42, 0273, 106 },
};
static dstatement_t double_conv_4_statements[] = {
{ OP(1, 1, 2, OP_CONV), 0, 0303, 48 },
{ OP(1, 1, 2, OP_CONV), 4, 0313, 56 },
{ OP(2, 1, 2, OP_CONV), 8, 0323, 64 },
{ OP(2, 1, 2, OP_CONV), 16, 0333, 72 },
{ OP(1, 1, 2, OP_CONV), 24, 0343, 80 },
{ OP(1, 1, 2, OP_CONV), 28, 0353, 88 },
{ OP(2, 1, 2, OP_CONV), 32, 0363, 96 },
{ OP(2, 1, 2, OP_CONV), 40, 0373, 104 },
};
test_t tests[] = {
{
.desc = "double conv 1",
.extra_globals = 4 * 1,
.num_globals = num_globals(double_conv_init,double_conv_expect),
.num_statements = num_statements (double_conv_1_statements),
.statements = double_conv_1_statements,
.init_globals = (pr_int_t *) double_conv_init,
.expect_globals = (pr_int_t *) double_conv_expect,
},
{
.desc = "double conv 2",
.extra_globals = 4 * 1,
.num_globals = num_globals(double_conv_init,double_conv_expect),
.num_statements = num_statements (double_conv_2_statements),
.statements = double_conv_2_statements,
.init_globals = (pr_int_t *) double_conv_init,
.expect_globals = (pr_int_t *) double_conv_expect,
},
{
.desc = "double conv 3a",
.extra_globals = 4 * 1,
.num_globals = num_globals(double_conv_init,double_conv_expect),
.num_statements = num_statements (double_conv_3a_statements),
.statements = double_conv_3a_statements,
.init_globals = (pr_int_t *) double_conv_init,
.expect_globals = (pr_int_t *) double_conv_expect,
},
{
.desc = "double conv 3b",
.extra_globals = 4 * 1,
.num_globals = num_globals(double_conv_init,double_conv_expect),
.num_statements = num_statements (double_conv_3b_statements),
.statements = double_conv_3b_statements,
.init_globals = (pr_int_t *) double_conv_init,
.expect_globals = (pr_int_t *) double_conv_expect,
},
{
.desc = "double conv 4",
.extra_globals = 4 * 1,
.num_globals = num_globals(double_conv_init,double_conv_expect),
.num_statements = num_statements (double_conv_4_statements),
.statements = double_conv_4_statements,
.init_globals = (pr_int_t *) double_conv_init,
.expect_globals = (pr_int_t *) double_conv_expect,
},
};
#include "main.c"

View file

@ -0,0 +1,190 @@
#include "head.c"
#include "QF/mathlib.h"
static pr_ivec4_t uint_conv_init[] = {
{ 5, -5, 0x80000000, 0x7fffffff}, //int
{ 0x3fc00000, 0xbfc00000, 0x7149f2ca, 0xf149f2ca}, //float 1e30, -1e30
{ 99, 0x80000000, 0x80000000, 99}, //long
{ 256, 0, 0x7fffffff, 0}, //long
{ 0x39a08cea, 0x46293e59, 0x39a08cea, 0xc6293e59}, //double 1e30, -1e30
{ 0, 0x3ff80000, 0, 0xbff80000}, //double 1.5, -1.5
{ 5, -5, 0x80000000, 0x7fffffff}, //uint
{ ~0, 1, 0x80000000, 0}, //bool32
{ 99, 0x80000000, 0x80000000, 99}, //ulong
{ 256, 0, 0x7fffffff, 0}, //ulong
{ ~0, ~0, ~0, 0}, //bool64
{ 0, ~0, 0, 0}, //bool64
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
};
static pr_ivec4_t uint_conv_expect[] = {
{ 5, -5, 0x80000000, 0x7fffffff}, //int
{ 0x3fc00000, 0xbfc00000, 0x7149f2ca, 0xf149f2ca}, //float
{ 99, 0x80000000, 0x80000000, 99}, //long
{ 256, 0, 0x7fffffff, 0}, //long
{ 0x39a08cea, 0x46293e59, 0x39a08cea, 0xc6293e59}, //double 1e30, -1e30
{ 0, 0x3ff80000, 0, 0xbff80000}, //double 1.5, -1.5
{ 5, -5, 0x80000000, 0x7fffffff}, //uint
{ ~0, 1, 0x80000000, 0}, //bool32
{ 99, 0x80000000, 0x80000000, 99}, //ulong
{ 256, 0, 0x7fffffff, 0}, //ulong
{ ~0, ~0, ~0, 0}, //bool64
{ 0, ~0, 0, 0}, //bool64
{ 5, -5, 0x80000000, 0x7fffffff}, // int
{ 1, 0xffffffff, 0, 0}, // float undef?
{ 99, 0x80000000, 256, 0x7fffffff}, // long
{ 0, 0, 1, 0xffffffff}, // double undef?
{ 5, -5, 0x80000000, 0x7fffffff}, // uint
{ 1, 1, 1, 0}, // bool32
{ 99, 0x80000000, 256, 0x7fffffff}, // ulong
{ 1, 1, 1, 0}, // bool64
};
static dstatement_t uint_conv_1_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 4, 0, 80 }, // init index
{ OP(0, 0, 0, OP_LEA_A), 8, 0, 81 }, // init index for 64-bits
//loop:
{ OP(0, 0, 0, OP_LEA_C), 80, -1, 80 }, // dec index
{ OP(0, 0, 0, OP_LEA_C), 81, -2, 81 }, // dec index for 64-bits
{ OP(0, 0, 0, OP_IFAE), 2, 0, 80 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 80, 1 },
{ OP(0, 0, 0, OP_WITH), 4, 81, 2 },
{ OP(1, 1, 1, OP_CONV), 0, 0004, 48 },
{ OP(1, 1, 1, OP_CONV), 4, 0014, 52 },
{ OP(2, 1, 1, OP_CONV), 8, 0024, 56 },
{ OP(2, 1, 1, OP_CONV), 16, 0034, 60 },
{ OP(1, 1, 1, OP_CONV), 24, 0044, 64 },
{ OP(1, 1, 1, OP_CONV), 28, 0054, 68 },
{ OP(2, 1, 1, OP_CONV), 32, 0064, 72 },
{ OP(2, 1, 1, OP_CONV), 40, 0074, 76 },
{ OP(1, 1, 1, OP_JUMP_A), -14, 0, 0 },
};
static dstatement_t uint_conv_2_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 4, 0, 80 }, // index
{ OP(0, 0, 0, OP_LEA_A), 8, 0, 81 }, // init index for 64-bits
//loop:
{ OP(0, 0, 0, OP_LEA_C), 80, -2, 80 }, // dec index
{ OP(0, 0, 0, OP_LEA_C), 81, -4, 81 }, // dec index for 64-bits
{ OP(0, 0, 0, OP_IFAE), 2, 0, 80 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 80, 1 },
{ OP(0, 0, 0, OP_WITH), 4, 81, 2 },
{ OP(1, 1, 1, OP_CONV), 0, 0104, 48 },
{ OP(1, 1, 1, OP_CONV), 4, 0114, 52 },
{ OP(2, 1, 1, OP_CONV), 8, 0124, 56 },
{ OP(2, 1, 1, OP_CONV), 16, 0134, 60 },
{ OP(1, 1, 1, OP_CONV), 24, 0144, 64 },
{ OP(1, 1, 1, OP_CONV), 28, 0154, 68 },
{ OP(2, 1, 1, OP_CONV), 32, 0164, 72 },
{ OP(2, 1, 1, OP_CONV), 40, 0174, 76 },
{ OP(1, 1, 1, OP_JUMP_A), -14, 0, 0 },
};
static dstatement_t uint_conv_3a_statements[] = {
{ OP(1, 1, 1, OP_CONV), 0, 0204, 48 },
{ OP(1, 1, 1, OP_CONV), 3, 0004, 51 },
{ OP(1, 1, 1, OP_CONV), 4, 0214, 52 },
{ OP(1, 1, 1, OP_CONV), 7, 0014, 55 },
{ OP(2, 1, 1, OP_CONV), 8, 0224, 56 },
{ OP(2, 1, 1, OP_CONV), 14, 0024, 59 },
{ OP(2, 1, 1, OP_CONV), 16, 0234, 60 },
{ OP(2, 1, 1, OP_CONV), 22, 0034, 63 },
{ OP(1, 1, 1, OP_CONV), 24, 0244, 64 },
{ OP(1, 1, 1, OP_CONV), 27, 0044, 67 },
{ OP(1, 1, 1, OP_CONV), 28, 0254, 68 },
{ OP(1, 1, 1, OP_CONV), 31, 0054, 71 },
{ OP(2, 1, 1, OP_CONV), 32, 0264, 72 },
{ OP(2, 1, 1, OP_CONV), 38, 0064, 75 },
{ OP(2, 1, 1, OP_CONV), 40, 0274, 76 },
{ OP(2, 1, 1, OP_CONV), 46, 0074, 79 },
};
static dstatement_t uint_conv_3b_statements[] = {
{ OP(1, 1, 1, OP_CONV), 0, 0004, 48 },
{ OP(1, 1, 1, OP_CONV), 1, 0204, 49 },
{ OP(1, 1, 1, OP_CONV), 4, 0014, 52 },
{ OP(1, 1, 1, OP_CONV), 5, 0214, 53 },
{ OP(2, 1, 1, OP_CONV), 8, 0024, 56 },
{ OP(2, 1, 1, OP_CONV), 10, 0224, 57 },
{ OP(2, 1, 1, OP_CONV), 16, 0034, 60 },
{ OP(2, 1, 1, OP_CONV), 18, 0234, 61 },
{ OP(1, 1, 1, OP_CONV), 24, 0044, 64 },
{ OP(1, 1, 1, OP_CONV), 25, 0244, 65 },
{ OP(1, 1, 1, OP_CONV), 28, 0054, 68 },
{ OP(1, 1, 1, OP_CONV), 29, 0254, 69 },
{ OP(2, 1, 1, OP_CONV), 32, 0064, 72 },
{ OP(2, 1, 1, OP_CONV), 34, 0264, 73 },
{ OP(2, 1, 1, OP_CONV), 40, 0074, 76 },
{ OP(2, 1, 1, OP_CONV), 42, 0274, 77 },
};
static dstatement_t uint_conv_4_statements[] = {
{ OP(1, 1, 1, OP_CONV), 0, 0304, 48 },
{ OP(1, 1, 1, OP_CONV), 4, 0314, 52 },
{ OP(2, 1, 1, OP_CONV), 8, 0324, 56 },
{ OP(2, 1, 1, OP_CONV), 16, 0334, 60 },
{ OP(1, 1, 1, OP_CONV), 24, 0344, 64 },
{ OP(1, 1, 1, OP_CONV), 28, 0354, 68 },
{ OP(2, 1, 1, OP_CONV), 32, 0364, 72 },
{ OP(2, 1, 1, OP_CONV), 40, 0374, 76 },
};
test_t tests[] = {
{
.desc = "uint conv 1",
.extra_globals = 4 * 1,
.num_globals = num_globals(uint_conv_init,uint_conv_expect),
.num_statements = num_statements (uint_conv_1_statements),
.statements = uint_conv_1_statements,
.init_globals = (pr_int_t *) uint_conv_init,
.expect_globals = (pr_int_t *) uint_conv_expect,
},
{
.desc = "uint conv 2",
.extra_globals = 4 * 1,
.num_globals = num_globals(uint_conv_init,uint_conv_expect),
.num_statements = num_statements (uint_conv_2_statements),
.statements = uint_conv_2_statements,
.init_globals = (pr_int_t *) uint_conv_init,
.expect_globals = (pr_int_t *) uint_conv_expect,
},
{
.desc = "uint conv 3a",
.extra_globals = 4 * 1,
.num_globals = num_globals(uint_conv_init,uint_conv_expect),
.num_statements = num_statements (uint_conv_3a_statements),
.statements = uint_conv_3a_statements,
.init_globals = (pr_int_t *) uint_conv_init,
.expect_globals = (pr_int_t *) uint_conv_expect,
},
{
.desc = "uint conv 3b",
.extra_globals = 4 * 1,
.num_globals = num_globals(uint_conv_init,uint_conv_expect),
.num_statements = num_statements (uint_conv_3b_statements),
.statements = uint_conv_3b_statements,
.init_globals = (pr_int_t *) uint_conv_init,
.expect_globals = (pr_int_t *) uint_conv_expect,
},
{
.desc = "uint conv 4",
.extra_globals = 4 * 1,
.num_globals = num_globals(uint_conv_init,uint_conv_expect),
.num_statements = num_statements (uint_conv_4_statements),
.statements = uint_conv_4_statements,
.init_globals = (pr_int_t *) uint_conv_init,
.expect_globals = (pr_int_t *) uint_conv_expect,
},
};
#include "main.c"

View file

@ -0,0 +1,190 @@
#include "head.c"
#include "QF/mathlib.h"
static pr_ivec4_t bool32_conv_init[] = {
{ 5, -5, 0x80000000, 0x7fffffff}, //int
{ 0x3fc00000, 0xbfc00000, 0x7149f2ca, 0xf149f2ca}, //float 1e30, -1e30
{ 99, 0x80000000, 0x80000000, 99}, //long
{ 256, 0, 0x7fffffff, 0}, //long
{ 0x39a08cea, 0x46293e59, 0x39a08cea, 0xc6293e59}, //double 1e30, -1e30
{ 0, 0x3ff80000, 0, 0xbff80000}, //double 1.5, -1.5
{ 5, -5, 0x80000000, 0x7fffffff}, //uint
{ ~0, 1, 0x80000000, 0}, //bool32
{ 99, 0x80000000, 0x80000000, 99}, //ulong
{ 256, 0, 0x7fffffff, 0}, //ulong
{ ~0, ~0, ~0, 0}, //bool64
{ 0, ~0, 0, 0}, //bool64
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
};
static pr_ivec4_t bool32_conv_expect[] = {
{ 5, -5, 0x80000000, 0x7fffffff}, //int
{ 0x3fc00000, 0xbfc00000, 0x7149f2ca, 0xf149f2ca}, //float
{ 99, 0x80000000, 0x80000000, 99}, //long
{ 256, 0, 0x7fffffff, 0}, //long
{ 0x39a08cea, 0x46293e59, 0x39a08cea, 0xc6293e59}, //double 1e30, -1e30
{ 0, 0x3ff80000, 0, 0xbff80000}, //double 1.5, -1.5
{ 5, -5, 0x80000000, 0x7fffffff}, //uint
{ ~0, 1, 0x80000000, 0}, //bool32
{ 99, 0x80000000, 0x80000000, 99}, //ulong
{ 256, 0, 0x7fffffff, 0}, //ulong
{ ~0, ~0, ~0, 0}, //bool64
{ 0, ~0, 0, 0}, //bool64
{ -1, -1, -1, -1}, // int
{ -1, -1, -1, -1}, // float
{ -1, -1, -1, -1}, // long
{ -1, -1, -1, -1}, // double
{ -1, -1, -1, -1}, // uint
{ ~0, 1, 0x80000000, 0}, // bool32
{ -1, -1, -1, -1}, // ulong
{ -1, -1, -1, 0}, // bool64
};
static dstatement_t bool32_conv_1_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 4, 0, 80 }, // init index
{ OP(0, 0, 0, OP_LEA_A), 8, 0, 81 }, // init index for 64-bits
//loop:
{ OP(0, 0, 0, OP_LEA_C), 80, -1, 80 }, // dec index
{ OP(0, 0, 0, OP_LEA_C), 81, -2, 81 }, // dec index for 64-bits
{ OP(0, 0, 0, OP_IFAE), 2, 0, 80 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 80, 1 },
{ OP(0, 0, 0, OP_WITH), 4, 81, 2 },
{ OP(1, 1, 1, OP_CONV), 0, 0005, 48 },
{ OP(1, 1, 1, OP_CONV), 4, 0015, 52 },
{ OP(2, 1, 1, OP_CONV), 8, 0025, 56 },
{ OP(2, 1, 1, OP_CONV), 16, 0035, 60 },
{ OP(1, 1, 1, OP_CONV), 24, 0045, 64 },
{ OP(1, 1, 1, OP_CONV), 28, 0055, 68 },
{ OP(2, 1, 1, OP_CONV), 32, 0065, 72 },
{ OP(2, 1, 1, OP_CONV), 40, 0075, 76 },
{ OP(1, 1, 1, OP_JUMP_A), -14, 0, 0 },
};
static dstatement_t bool32_conv_2_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 4, 0, 80 }, // index
{ OP(0, 0, 0, OP_LEA_A), 8, 0, 81 }, // init index for 64-bits
//loop:
{ OP(0, 0, 0, OP_LEA_C), 80, -2, 80 }, // dec index
{ OP(0, 0, 0, OP_LEA_C), 81, -4, 81 }, // dec index for 64-bits
{ OP(0, 0, 0, OP_IFAE), 2, 0, 80 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 80, 1 },
{ OP(0, 0, 0, OP_WITH), 4, 81, 2 },
{ OP(1, 1, 1, OP_CONV), 0, 0105, 48 },
{ OP(1, 1, 1, OP_CONV), 4, 0115, 52 },
{ OP(2, 1, 1, OP_CONV), 8, 0125, 56 },
{ OP(2, 1, 1, OP_CONV), 16, 0135, 60 },
{ OP(1, 1, 1, OP_CONV), 24, 0145, 64 },
{ OP(1, 1, 1, OP_CONV), 28, 0155, 68 },
{ OP(2, 1, 1, OP_CONV), 32, 0165, 72 },
{ OP(2, 1, 1, OP_CONV), 40, 0175, 76 },
{ OP(1, 1, 1, OP_JUMP_A), -14, 0, 0 },
};
static dstatement_t bool32_conv_3a_statements[] = {
{ OP(1, 1, 1, OP_CONV), 0, 0205, 48 },
{ OP(1, 1, 1, OP_CONV), 3, 0005, 51 },
{ OP(1, 1, 1, OP_CONV), 4, 0215, 52 },
{ OP(1, 1, 1, OP_CONV), 7, 0015, 55 },
{ OP(2, 1, 1, OP_CONV), 8, 0225, 56 },
{ OP(2, 1, 1, OP_CONV), 14, 0025, 59 },
{ OP(2, 1, 1, OP_CONV), 16, 0235, 60 },
{ OP(2, 1, 1, OP_CONV), 22, 0035, 63 },
{ OP(1, 1, 1, OP_CONV), 24, 0245, 64 },
{ OP(1, 1, 1, OP_CONV), 27, 0045, 67 },
{ OP(1, 1, 1, OP_CONV), 28, 0255, 68 },
{ OP(1, 1, 1, OP_CONV), 31, 0055, 71 },
{ OP(2, 1, 1, OP_CONV), 32, 0265, 72 },
{ OP(2, 1, 1, OP_CONV), 38, 0065, 75 },
{ OP(2, 1, 1, OP_CONV), 40, 0275, 76 },
{ OP(2, 1, 1, OP_CONV), 46, 0075, 79 },
};
static dstatement_t bool32_conv_3b_statements[] = {
{ OP(1, 1, 1, OP_CONV), 0, 0005, 48 },
{ OP(1, 1, 1, OP_CONV), 1, 0205, 49 },
{ OP(1, 1, 1, OP_CONV), 4, 0015, 52 },
{ OP(1, 1, 1, OP_CONV), 5, 0215, 53 },
{ OP(2, 1, 1, OP_CONV), 8, 0025, 56 },
{ OP(2, 1, 1, OP_CONV), 10, 0225, 57 },
{ OP(2, 1, 1, OP_CONV), 16, 0035, 60 },
{ OP(2, 1, 1, OP_CONV), 18, 0235, 61 },
{ OP(1, 1, 1, OP_CONV), 24, 0045, 64 },
{ OP(1, 1, 1, OP_CONV), 25, 0245, 65 },
{ OP(1, 1, 1, OP_CONV), 28, 0055, 68 },
{ OP(1, 1, 1, OP_CONV), 29, 0255, 69 },
{ OP(2, 1, 1, OP_CONV), 32, 0065, 72 },
{ OP(2, 1, 1, OP_CONV), 34, 0265, 73 },
{ OP(2, 1, 1, OP_CONV), 40, 0075, 76 },
{ OP(2, 1, 1, OP_CONV), 42, 0275, 77 },
};
static dstatement_t bool32_conv_4_statements[] = {
{ OP(1, 1, 1, OP_CONV), 0, 0305, 48 },
{ OP(1, 1, 1, OP_CONV), 4, 0315, 52 },
{ OP(2, 1, 1, OP_CONV), 8, 0325, 56 },
{ OP(2, 1, 1, OP_CONV), 16, 0335, 60 },
{ OP(1, 1, 1, OP_CONV), 24, 0345, 64 },
{ OP(1, 1, 1, OP_CONV), 28, 0355, 68 },
{ OP(2, 1, 1, OP_CONV), 32, 0365, 72 },
{ OP(2, 1, 1, OP_CONV), 40, 0375, 76 },
};
test_t tests[] = {
{
.desc = "bool32 conv 1",
.extra_globals = 4 * 1,
.num_globals = num_globals(bool32_conv_init,bool32_conv_expect),
.num_statements = num_statements (bool32_conv_1_statements),
.statements = bool32_conv_1_statements,
.init_globals = (pr_int_t *) bool32_conv_init,
.expect_globals = (pr_int_t *) bool32_conv_expect,
},
{
.desc = "bool32 conv 2",
.extra_globals = 4 * 1,
.num_globals = num_globals(bool32_conv_init,bool32_conv_expect),
.num_statements = num_statements (bool32_conv_2_statements),
.statements = bool32_conv_2_statements,
.init_globals = (pr_int_t *) bool32_conv_init,
.expect_globals = (pr_int_t *) bool32_conv_expect,
},
{
.desc = "bool32 conv 3a",
.extra_globals = 4 * 1,
.num_globals = num_globals(bool32_conv_init,bool32_conv_expect),
.num_statements = num_statements (bool32_conv_3a_statements),
.statements = bool32_conv_3a_statements,
.init_globals = (pr_int_t *) bool32_conv_init,
.expect_globals = (pr_int_t *) bool32_conv_expect,
},
{
.desc = "bool32 conv 3b",
.extra_globals = 4 * 1,
.num_globals = num_globals(bool32_conv_init,bool32_conv_expect),
.num_statements = num_statements (bool32_conv_3b_statements),
.statements = bool32_conv_3b_statements,
.init_globals = (pr_int_t *) bool32_conv_init,
.expect_globals = (pr_int_t *) bool32_conv_expect,
},
{
.desc = "bool32 conv 4",
.extra_globals = 4 * 1,
.num_globals = num_globals(bool32_conv_init,bool32_conv_expect),
.num_statements = num_statements (bool32_conv_4_statements),
.statements = bool32_conv_4_statements,
.init_globals = (pr_int_t *) bool32_conv_init,
.expect_globals = (pr_int_t *) bool32_conv_expect,
},
};
#include "main.c"

View file

@ -0,0 +1,206 @@
#include "head.c"
#include "QF/mathlib.h"
static pr_ivec4_t ulong_conv_init[] = {
{ 5, -5, 0x80000000, 0x7fffffff}, //int
{ 0x3fc00000, 0xbfc00000, 0x7149f2ca, 0xf149f2ca}, //float 1e30, -1e30
{ 99, 0x80000000, 0x80000000, 99}, //long
{ 256, 0, 0x7fffffff, 0}, //long
{ 0x39a08cea, 0x46293e59, 0x39a08cea, 0xc6293e59}, //double 1e30, -1e30
{ 0, 0x3ff80000, 0, 0xbff80000}, //double 1.5, -1.5
{ 5, -5, 0x80000000, 0x7fffffff}, //uint
{ ~0, 1, 0x80000000, 0}, //bool32
{ 99, 0x80000000, 0x80000000, 99}, //ulong
{ 256, 0, 0x7fffffff, 0}, //ulong
{ ~0, ~0, ~0, 0}, //bool64
{ 0, ~0, 0, 0}, //bool64
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
};
static pr_ivec4_t ulong_conv_expect[] = {
{ 5, -5, 0x80000000, 0x7fffffff}, //int
{ 0x3fc00000, 0xbfc00000, 0x7149f2ca, 0xf149f2ca}, //float
{ 99, 0x80000000, 0x80000000, 99}, //long
{ 256, 0, 0x7fffffff, 0}, //long
{ 0x39a08cea, 0x46293e59, 0x39a08cea, 0xc6293e59}, //double 1e30, -1e30
{ 0, 0x3ff80000, 0, 0xbff80000}, //double 1.5, -1.5
{ 5, -5, 0x80000000, 0x7fffffff}, //uint
{ ~0, 1, 0x80000000, 0}, //bool32
{ 99, 0x80000000, 0x80000000, 99}, //ulong
{ 256, 0, 0x7fffffff, 0}, //ulong
{ ~0, ~0, ~0, 0}, //bool64
{ 0, ~0, 0, 0}, //bool64
{ 5, 0, -5, 0xffffffff}, // int
{ 0x80000000, 0xffffffff, 0x7fffffff, 0},
{ 1, 0, -1, -1}, // float
{ 0, 0, 0, 0x80000000}, // undef?
{ 99, 0x80000000, 0x80000000, 99}, // long
{ 256, 0, 0x7fffffff, 0},
{ 0, 0, 0, 0x80000000}, // double undef?
{ 1, 0, -1, -1},
{ 5, 0, -5, 0}, // uint
{ 0x80000000, 0, 0x7fffffff, 0},
{ 1, 0, 1, 0}, // bool32
{ 1, 0, 0, 0},
{ 99, 0x80000000, 0x80000000, 99}, // ulong
{ 256, 0, 0x7fffffff, 0},
{ 1, 0, 1, 0}, // bool64
{ 1, 0, 0, 0},
};
static dstatement_t ulong_conv_1_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 4, 0, 112 }, // init index
{ OP(0, 0, 0, OP_LEA_A), 8, 0, 113 }, // init index for 64-bits
//loop:
{ OP(0, 0, 0, OP_LEA_C), 112, -1, 112 }, // dec index
{ OP(0, 0, 0, OP_LEA_C), 113, -2, 113 }, // dec index for 64-bits
{ OP(0, 0, 0, OP_IFAE), 2, 0, 112 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 112, 1 },
{ OP(0, 0, 0, OP_WITH), 4, 113, 2 },
{ OP(1, 1, 2, OP_CONV), 0, 0006, 48 },
{ OP(1, 1, 2, OP_CONV), 4, 0016, 56 },
{ OP(2, 1, 2, OP_CONV), 8, 0026, 64 },
{ OP(2, 1, 2, OP_CONV), 16, 0036, 72 },
{ OP(1, 1, 2, OP_CONV), 24, 0046, 80 },
{ OP(1, 1, 2, OP_CONV), 28, 0056, 88 },
{ OP(2, 1, 2, OP_CONV), 32, 0066, 96 },
{ OP(2, 1, 2, OP_CONV), 40, 0076, 104 },
{ OP(0, 0, 0, OP_JUMP_A), -14, 0, 0 },
};
static dstatement_t ulong_conv_2_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 4, 0, 112 }, // index
{ OP(0, 0, 0, OP_LEA_A), 8, 0, 113 }, // init index for 64-bits
//loop:
{ OP(0, 0, 0, OP_LEA_C), 112, -2, 112 }, // dec index
{ OP(0, 0, 0, OP_LEA_C), 113, -4, 113 }, // dec index for 64-bits
{ OP(0, 0, 0, OP_IFAE), 2, 0, 112 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 112, 1 },
{ OP(0, 0, 0, OP_WITH), 4, 113, 2 },
{ OP(1, 1, 2, OP_CONV), 0, 0106, 48 },
{ OP(1, 1, 2, OP_CONV), 4, 0116, 56 },
{ OP(2, 1, 2, OP_CONV), 8, 0126, 64 },
{ OP(2, 1, 2, OP_CONV), 16, 0136, 72 },
{ OP(1, 1, 2, OP_CONV), 24, 0146, 80 },
{ OP(1, 1, 2, OP_CONV), 28, 0156, 88 },
{ OP(2, 1, 2, OP_CONV), 32, 0166, 96 },
{ OP(2, 1, 2, OP_CONV), 40, 0176, 104 },
{ OP(0, 0, 0, OP_JUMP_A), -14, 0, 0 },
};
static dstatement_t ulong_conv_3a_statements[] = {
{ OP(1, 1, 2, OP_CONV), 0, 0206, 48 },
{ OP(1, 1, 2, OP_CONV), 3, 0006, 54 },
{ OP(1, 1, 2, OP_CONV), 4, 0216, 56 },
{ OP(1, 1, 2, OP_CONV), 7, 0016, 62 },
{ OP(2, 1, 2, OP_CONV), 8, 0226, 64 },
{ OP(2, 1, 2, OP_CONV), 14, 0026, 70 },
{ OP(2, 1, 2, OP_CONV), 16, 0236, 72 },
{ OP(2, 1, 2, OP_CONV), 22, 0036, 78 },
{ OP(1, 1, 2, OP_CONV), 24, 0246, 80 },
{ OP(1, 1, 2, OP_CONV), 27, 0046, 86 },
{ OP(1, 1, 2, OP_CONV), 28, 0256, 88 },
{ OP(1, 1, 2, OP_CONV), 31, 0056, 94 },
{ OP(2, 1, 2, OP_CONV), 32, 0266, 96 },
{ OP(2, 1, 2, OP_CONV), 38, 0066, 102 },
{ OP(2, 1, 2, OP_CONV), 40, 0276, 104 },
{ OP(2, 1, 2, OP_CONV), 46, 0076, 110 },
};
static dstatement_t ulong_conv_3b_statements[] = {
{ OP(1, 1, 2, OP_CONV), 0, 0006, 48 },
{ OP(1, 1, 2, OP_CONV), 1, 0206, 50 },
{ OP(1, 1, 2, OP_CONV), 4, 0016, 56 },
{ OP(1, 1, 2, OP_CONV), 5, 0216, 58 },
{ OP(2, 1, 2, OP_CONV), 8, 0026, 64 },
{ OP(2, 1, 2, OP_CONV), 10, 0226, 66 },
{ OP(2, 1, 2, OP_CONV), 16, 0036, 72 },
{ OP(2, 1, 2, OP_CONV), 18, 0236, 74 },
{ OP(1, 1, 2, OP_CONV), 24, 0046, 80 },
{ OP(1, 1, 2, OP_CONV), 25, 0246, 82 },
{ OP(1, 1, 2, OP_CONV), 28, 0056, 88 },
{ OP(1, 1, 2, OP_CONV), 29, 0256, 90 },
{ OP(2, 1, 2, OP_CONV), 32, 0066, 96 },
{ OP(2, 1, 2, OP_CONV), 34, 0266, 98 },
{ OP(2, 1, 2, OP_CONV), 40, 0076, 104 },
{ OP(2, 1, 2, OP_CONV), 42, 0276, 106 },
};
static dstatement_t ulong_conv_4_statements[] = {
{ OP(1, 1, 2, OP_CONV), 0, 0306, 48 },
{ OP(1, 1, 2, OP_CONV), 4, 0316, 56 },
{ OP(2, 1, 2, OP_CONV), 8, 0326, 64 },
{ OP(2, 1, 2, OP_CONV), 16, 0336, 72 },
{ OP(1, 1, 2, OP_CONV), 24, 0346, 80 },
{ OP(1, 1, 2, OP_CONV), 28, 0356, 88 },
{ OP(2, 1, 2, OP_CONV), 32, 0366, 96 },
{ OP(2, 1, 2, OP_CONV), 40, 0376, 104 },
};
test_t tests[] = {
{
.desc = "ulong conv 1",
.extra_globals = 4 * 1,
.num_globals = num_globals(ulong_conv_init,ulong_conv_expect),
.num_statements = num_statements (ulong_conv_1_statements),
.statements = ulong_conv_1_statements,
.init_globals = (pr_int_t *) ulong_conv_init,
.expect_globals = (pr_int_t *) ulong_conv_expect,
},
{
.desc = "ulong conv 2",
.extra_globals = 4 * 1,
.num_globals = num_globals(ulong_conv_init,ulong_conv_expect),
.num_statements = num_statements (ulong_conv_2_statements),
.statements = ulong_conv_2_statements,
.init_globals = (pr_int_t *) ulong_conv_init,
.expect_globals = (pr_int_t *) ulong_conv_expect,
},
{
.desc = "ulong conv 3a",
.extra_globals = 4 * 1,
.num_globals = num_globals(ulong_conv_init,ulong_conv_expect),
.num_statements = num_statements (ulong_conv_3a_statements),
.statements = ulong_conv_3a_statements,
.init_globals = (pr_int_t *) ulong_conv_init,
.expect_globals = (pr_int_t *) ulong_conv_expect,
},
{
.desc = "ulong conv 3b",
.extra_globals = 4 * 1,
.num_globals = num_globals(ulong_conv_init,ulong_conv_expect),
.num_statements = num_statements (ulong_conv_3b_statements),
.statements = ulong_conv_3b_statements,
.init_globals = (pr_int_t *) ulong_conv_init,
.expect_globals = (pr_int_t *) ulong_conv_expect,
},
{
.desc = "ulong conv 4",
.extra_globals = 4 * 1,
.num_globals = num_globals(ulong_conv_init,ulong_conv_expect),
.num_statements = num_statements (ulong_conv_4_statements),
.statements = ulong_conv_4_statements,
.init_globals = (pr_int_t *) ulong_conv_init,
.expect_globals = (pr_int_t *) ulong_conv_expect,
},
};
#include "main.c"

View file

@ -0,0 +1,206 @@
#include "head.c"
#include "QF/mathlib.h"
static pr_ivec4_t bool64_conv_init[] = {
{ 5, -5, 0x80000000, 0x7fffffff}, //int
{ 0x3fc00000, 0xbfc00000, 0x7149f2ca, 0xf149f2ca}, //float 1e30, -1e30
{ 99, 0x80000000, 0x80000000, 99}, //long
{ 256, 0, 0x7fffffff, 0}, //long
{ 0x39a08cea, 0x46293e59, 0x39a08cea, 0xc6293e59}, //double 1e30, -1e30
{ 0, 0x3ff80000, 0, 0xbff80000}, //double 1.5, -1.5
{ 5, -5, 0x80000000, 0x7fffffff}, //uint
{ ~0, 1, 0x80000000, 0}, //bool32
{ 99, 0x80000000, 0x80000000, 99}, //ulong
{ 256, 0, 0x7fffffff, 0}, //ulong
{ ~0, ~0, ~0, 0}, //bool64
{ 0, ~0, 0, 0}, //bool64
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
};
static pr_ivec4_t bool64_conv_expect[] = {
{ 5, -5, 0x80000000, 0x7fffffff}, //int
{ 0x3fc00000, 0xbfc00000, 0x7149f2ca, 0xf149f2ca}, //float
{ 99, 0x80000000, 0x80000000, 99}, //long
{ 256, 0, 0x7fffffff, 0}, //long
{ 0x39a08cea, 0x46293e59, 0x39a08cea, 0xc6293e59}, //double 1e30, -1e30
{ 0, 0x3ff80000, 0, 0xbff80000}, //double 1.5, -1.5
{ 5, -5, 0x80000000, 0x7fffffff}, //uint
{ ~0, 1, 0x80000000, 0}, //bool32
{ 99, 0x80000000, 0x80000000, 99}, //ulong
{ 256, 0, 0x7fffffff, 0}, //ulong
{ ~0, ~0, ~0, 0}, //bool64
{ 0, ~0, 0, 0}, //bool64
{ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}, // int
{ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff},
{ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}, // float
{ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff},
{ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}, // long
{ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff},
{ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}, // double
{ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff},
{ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}, // uint
{ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff},
{ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}, // bool32
{ 0xffffffff, 0xffffffff, 0, 0},
{ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}, // ulong
{ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff},
{ ~0, ~0, ~0, 0}, // bool64
{ 0, ~0, 0, 0},
};
static dstatement_t bool64_conv_1_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 4, 0, 112 }, // init index
{ OP(0, 0, 0, OP_LEA_A), 8, 0, 113 }, // init index for 64-bits
//loop:
{ OP(0, 0, 0, OP_LEA_C), 112, -1, 112 }, // dec index
{ OP(0, 0, 0, OP_LEA_C), 113, -2, 113 }, // dec index for 64-bits
{ OP(0, 0, 0, OP_IFAE), 2, 0, 112 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 112, 1 },
{ OP(0, 0, 0, OP_WITH), 4, 113, 2 },
{ OP(1, 1, 2, OP_CONV), 0, 0007, 48 },
{ OP(1, 1, 2, OP_CONV), 4, 0017, 56 },
{ OP(2, 1, 2, OP_CONV), 8, 0027, 64 },
{ OP(2, 1, 2, OP_CONV), 16, 0037, 72 },
{ OP(1, 1, 2, OP_CONV), 24, 0047, 80 },
{ OP(1, 1, 2, OP_CONV), 28, 0057, 88 },
{ OP(2, 1, 2, OP_CONV), 32, 0067, 96 },
{ OP(2, 1, 2, OP_CONV), 40, 0077, 104 },
{ OP(0, 0, 0, OP_JUMP_A), -14, 0, 0 },
};
static dstatement_t bool64_conv_2_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 4, 0, 112 }, // index
{ OP(0, 0, 0, OP_LEA_A), 8, 0, 113 }, // init index for 64-bits
//loop:
{ OP(0, 0, 0, OP_LEA_C), 112, -2, 112 }, // dec index
{ OP(0, 0, 0, OP_LEA_C), 113, -4, 113 }, // dec index for 64-bits
{ OP(0, 0, 0, OP_IFAE), 2, 0, 112 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 112, 1 },
{ OP(0, 0, 0, OP_WITH), 4, 113, 2 },
{ OP(1, 1, 2, OP_CONV), 0, 0107, 48 },
{ OP(1, 1, 2, OP_CONV), 4, 0117, 56 },
{ OP(2, 1, 2, OP_CONV), 8, 0127, 64 },
{ OP(2, 1, 2, OP_CONV), 16, 0137, 72 },
{ OP(1, 1, 2, OP_CONV), 24, 0147, 80 },
{ OP(1, 1, 2, OP_CONV), 28, 0157, 88 },
{ OP(2, 1, 2, OP_CONV), 32, 0167, 96 },
{ OP(2, 1, 2, OP_CONV), 40, 0177, 104 },
{ OP(0, 0, 0, OP_JUMP_A), -14, 0, 0 },
};
static dstatement_t bool64_conv_3a_statements[] = {
{ OP(1, 1, 2, OP_CONV), 0, 0207, 48 },
{ OP(1, 1, 2, OP_CONV), 3, 0007, 54 },
{ OP(1, 1, 2, OP_CONV), 4, 0217, 56 },
{ OP(1, 1, 2, OP_CONV), 7, 0017, 62 },
{ OP(2, 1, 2, OP_CONV), 8, 0227, 64 },
{ OP(2, 1, 2, OP_CONV), 14, 0027, 70 },
{ OP(2, 1, 2, OP_CONV), 16, 0237, 72 },
{ OP(2, 1, 2, OP_CONV), 22, 0037, 78 },
{ OP(1, 1, 2, OP_CONV), 24, 0247, 80 },
{ OP(1, 1, 2, OP_CONV), 27, 0047, 86 },
{ OP(1, 1, 2, OP_CONV), 28, 0257, 88 },
{ OP(1, 1, 2, OP_CONV), 31, 0057, 94 },
{ OP(2, 1, 2, OP_CONV), 32, 0267, 96 },
{ OP(2, 1, 2, OP_CONV), 38, 0067, 102 },
{ OP(2, 1, 2, OP_CONV), 40, 0277, 104 },
{ OP(2, 1, 2, OP_CONV), 46, 0077, 110 },
};
static dstatement_t bool64_conv_3b_statements[] = {
{ OP(1, 1, 2, OP_CONV), 0, 0007, 48 },
{ OP(1, 1, 2, OP_CONV), 1, 0207, 50 },
{ OP(1, 1, 2, OP_CONV), 4, 0017, 56 },
{ OP(1, 1, 2, OP_CONV), 5, 0217, 58 },
{ OP(2, 1, 2, OP_CONV), 8, 0027, 64 },
{ OP(2, 1, 2, OP_CONV), 10, 0227, 66 },
{ OP(2, 1, 2, OP_CONV), 16, 0037, 72 },
{ OP(2, 1, 2, OP_CONV), 18, 0237, 74 },
{ OP(1, 1, 2, OP_CONV), 24, 0047, 80 },
{ OP(1, 1, 2, OP_CONV), 25, 0247, 82 },
{ OP(1, 1, 2, OP_CONV), 28, 0057, 88 },
{ OP(1, 1, 2, OP_CONV), 29, 0257, 90 },
{ OP(2, 1, 2, OP_CONV), 32, 0067, 96 },
{ OP(2, 1, 2, OP_CONV), 34, 0267, 98 },
{ OP(2, 1, 2, OP_CONV), 40, 0077, 104 },
{ OP(2, 1, 2, OP_CONV), 42, 0277, 106 },
};
static dstatement_t bool64_conv_4_statements[] = {
{ OP(1, 1, 2, OP_CONV), 0, 0307, 48 },
{ OP(1, 1, 2, OP_CONV), 4, 0317, 56 },
{ OP(2, 1, 2, OP_CONV), 8, 0327, 64 },
{ OP(2, 1, 2, OP_CONV), 16, 0337, 72 },
{ OP(1, 1, 2, OP_CONV), 24, 0347, 80 },
{ OP(1, 1, 2, OP_CONV), 28, 0357, 88 },
{ OP(2, 1, 2, OP_CONV), 32, 0367, 96 },
{ OP(2, 1, 2, OP_CONV), 40, 0377, 104 },
};
test_t tests[] = {
{
.desc = "bool64 conv 1",
.extra_globals = 4 * 1,
.num_globals = num_globals(bool64_conv_init,bool64_conv_expect),
.num_statements = num_statements (bool64_conv_1_statements),
.statements = bool64_conv_1_statements,
.init_globals = (pr_int_t *) bool64_conv_init,
.expect_globals = (pr_int_t *) bool64_conv_expect,
},
{
.desc = "bool64 conv 2",
.extra_globals = 4 * 1,
.num_globals = num_globals(bool64_conv_init,bool64_conv_expect),
.num_statements = num_statements (bool64_conv_2_statements),
.statements = bool64_conv_2_statements,
.init_globals = (pr_int_t *) bool64_conv_init,
.expect_globals = (pr_int_t *) bool64_conv_expect,
},
{
.desc = "bool64 conv 3a",
.extra_globals = 4 * 1,
.num_globals = num_globals(bool64_conv_init,bool64_conv_expect),
.num_statements = num_statements (bool64_conv_3a_statements),
.statements = bool64_conv_3a_statements,
.init_globals = (pr_int_t *) bool64_conv_init,
.expect_globals = (pr_int_t *) bool64_conv_expect,
},
{
.desc = "bool64 conv 3b",
.extra_globals = 4 * 1,
.num_globals = num_globals(bool64_conv_init,bool64_conv_expect),
.num_statements = num_statements (bool64_conv_3b_statements),
.statements = bool64_conv_3b_statements,
.init_globals = (pr_int_t *) bool64_conv_init,
.expect_globals = (pr_int_t *) bool64_conv_expect,
},
{
.desc = "bool64 conv 4",
.extra_globals = 4 * 1,
.num_globals = num_globals(bool64_conv_init,bool64_conv_expect),
.num_statements = num_statements (bool64_conv_4_statements),
.statements = bool64_conv_4_statements,
.init_globals = (pr_int_t *) bool64_conv_init,
.expect_globals = (pr_int_t *) bool64_conv_expect,
},
};
#include "main.c"

View file

@ -0,0 +1,333 @@
#include "head.c"
#include "QF/mathlib.h"
#define sq(x) ((x)*(x))
static pr_dvec4_t double_binop_init[] = {
{ 5, -5, 5, -5},
{ 3, 3, -3, -3},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
};
static pr_dvec4_t double_binop_expect[] = {
{ 5, -5, 5, -5},
{ 3, 3, -3, -3},
{ 15, -15, -15, 15},
{ 5.0/3, -5.0/3, -5.0/3, 5.0/3},
{ 2, -2, 2, -2},
{ 2, 1, -1, -2},
{ 8, -2, 2, -8},
{ 2, -8, 8, -2},
};
static dstatement_t double_binop_1_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 8, 0, 64 }, // init index
//loop:
{ OP(0, 0, 0, OP_LEA_C), 64, -2, 64 }, // dec index
{ OP(0, 0, 0, OP_IFAE), 2, 0, 64 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 64, 1 },
{ OP(1, 1, 1, OP_MUL_D_1), 0, 8, 16 },
{ OP(1, 1, 1, OP_DIV_D_1), 0, 8, 24 },
{ OP(1, 1, 1, OP_REM_D_1), 0, 8, 32 },
{ OP(1, 1, 1, OP_MOD_D_1), 0, 8, 40 },
{ OP(1, 1, 1, OP_ADD_D_1), 0, 8, 48 },
{ OP(1, 1, 1, OP_SUB_D_1), 0, 8, 56 },
{ OP(1, 1, 1, OP_JUMP_A), -10, 0, 0 },
};
static dstatement_t double_binop_2_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 8, 0, 64 }, // init index
//loop:
{ OP(0, 0, 0, OP_LEA_C), 64, -4, 64 }, // dec index
{ OP(0, 0, 0, OP_IFAE), 2, 0, 64 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 64, 1 },
{ OP(1, 1, 1, OP_MUL_D_2), 0, 8, 16 },
{ OP(1, 1, 1, OP_DIV_D_2), 0, 8, 24 },
{ OP(1, 1, 1, OP_REM_D_2), 0, 8, 32 },
{ OP(1, 1, 1, OP_MOD_D_2), 0, 8, 40 },
{ OP(1, 1, 1, OP_ADD_D_2), 0, 8, 48 },
{ OP(1, 1, 1, OP_SUB_D_2), 0, 8, 56 },
{ OP(1, 1, 1, OP_JUMP_A), -10, 0, 0 },
};
static dstatement_t double_binop_3a_statements[] = {
{ OP(1, 1, 1, OP_MUL_D_3), 0, 8, 16 },
{ OP(1, 1, 1, OP_MUL_D_1), 6, 14, 22 },
{ OP(1, 1, 1, OP_DIV_D_3), 0, 8, 24 },
{ OP(1, 1, 1, OP_DIV_D_1), 6, 14, 30 },
{ OP(1, 1, 1, OP_REM_D_3), 0, 8, 32 },
{ OP(1, 1, 1, OP_REM_D_1), 6, 14, 38 },
{ OP(1, 1, 1, OP_MOD_D_3), 0, 8, 40 },
{ OP(1, 1, 1, OP_MOD_D_1), 6, 14, 46 },
{ OP(1, 1, 1, OP_ADD_D_3), 0, 8, 48 },
{ OP(1, 1, 1, OP_ADD_D_1), 6, 14, 54 },
{ OP(1, 1, 1, OP_SUB_D_3), 0, 8, 56 },
{ OP(1, 1, 1, OP_SUB_D_1), 6, 14, 62 },
};
static dstatement_t double_binop_3b_statements[] = {
{ OP(1, 1, 1, OP_MUL_D_1), 0, 8, 16 },
{ OP(1, 1, 1, OP_MUL_D_3), 2, 10, 18 },
{ OP(1, 1, 1, OP_DIV_D_1), 0, 8, 24 },
{ OP(1, 1, 1, OP_DIV_D_3), 2, 10, 26 },
{ OP(1, 1, 1, OP_REM_D_1), 0, 8, 32 },
{ OP(1, 1, 1, OP_REM_D_3), 2, 10, 34 },
{ OP(1, 1, 1, OP_MOD_D_1), 0, 8, 40 },
{ OP(1, 1, 1, OP_MOD_D_3), 2, 10, 42 },
{ OP(1, 1, 1, OP_ADD_D_1), 0, 8, 48 },
{ OP(1, 1, 1, OP_ADD_D_3), 2, 10, 50 },
{ OP(1, 1, 1, OP_SUB_D_1), 0, 8, 56 },
{ OP(1, 1, 1, OP_SUB_D_3), 2, 10, 58 },
};
static dstatement_t double_binop_4_statements[] = {
{ OP(1, 1, 1, OP_MUL_D_4), 0, 8, 16 },
{ OP(1, 1, 1, OP_DIV_D_4), 0, 8, 24 },
{ OP(1, 1, 1, OP_REM_D_4), 0, 8, 32 },
{ OP(1, 1, 1, OP_MOD_D_4), 0, 8, 40 },
{ OP(1, 1, 1, OP_ADD_D_4), 0, 8, 48 },
{ OP(1, 1, 1, OP_SUB_D_4), 0, 8, 56 },
};
static pr_dvec4_t double_cossin_init[] = {
{ 1, 2, 3, 4 }, // 0: output
{ M_PI/6, 0, 0, 0 }, // 4: x
{ 1, 2, 0, 0 }, // 8: f
{ 1, 1, 0, 25 }, // 12: f inc and f0 max
{ 0, 0, 0, 0 }, // 16: x2 -> [xx, xx]
// { } // 20: xn
};
static pr_dvec4_t double_cossin_expect[] = {
{ 0.8660254037844386, 0.49999999999999994, 0, 0 }, // 0: output
{ M_PI/6, 0, 0, 0 }, // 4: x
{ 25, 26, 0, 0 }, // 8: f
{ 1, 1, 0, 25 }, // 12: f inc and f0 max
{ -sq(M_PI/6), -sq(M_PI/6), 0, 0 }, // 16: x2 -> [xx, xx]
};
static dstatement_t double_cossin_statements[] = {
{ OP(0, 0, 0, OP_STORE_A_2), 42, 0, 8 }, // init xn -> [?, x]
{ OP(0, 0, 0, OP_STORE_A_2), 40, 0, 16 }, // init xn -> [1, x]
{ OP(0, 0, 0, OP_SWIZZLE_D), 8,0xc000, 32 }, // init x2 -> [x, x, 0, 0]
{ OP(0, 0, 0, OP_MUL_D_2), 32, 32, 32 }, // x2 -> [x*x, x*x, 0, 0]
{ OP(0, 0, 0, OP_SWIZZLE_D), 32,0xc3e4, 32 }, // init x2 -> -x2
{ OP(0, 0, 0, OP_SUB_D_4), 0, 0, 0 }, // init acc (output) to 0
// loop:
{ OP(0, 0, 0, OP_ADD_D_2), 0, 40, 0 }, // acc += xn
{ OP(0, 0, 0, OP_MUL_D_2), 40, 32, 40 }, // xn *= x2
{ OP(0, 0, 0, OP_DIV_D_2), 40, 16, 40 }, // xn /= f
{ OP(0, 0, 0, OP_ADD_D_2), 16, 24, 16 }, // f += inc
{ OP(0, 0, 0, OP_DIV_D_2), 40, 16, 40 }, // xn /= f
{ OP(0, 0, 0, OP_ADD_D_2), 16, 24, 16 }, // f += inc
{ OP(0, 0, 0, OP_LT_D_1), 16, 30, 46 }, // f0 < fmax
{ OP(0, 0, 0, OP_IFNZ), -7, 0, 46 }, // f0 < fmax
};
static pr_dvec4_t double_cmpop_init[] = {
{ 5, -5, 5, -5},
{ 5, 5, -5, -5},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
};
// 5.0 as 64-bit int
#define F 0x4014000000000000l
#define mF 0xc014000000000000l
static pr_lvec4_t double_cmpop_expect[] = {
{ F, mF, F, mF},
{ F, F, mF, mF},
{ -1, 0, 0, -1},
{ 0, -1, 0, 0},
{ 0, 0, -1, 0},
{ 0, -1, -1, 0},
{ -1, 0, -1, -1},
{ -1, -1, 0, -1},
};
static dstatement_t double_cmpop_1_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 8, 0, 64 }, // init index
//loop:
{ OP(0, 0, 0, OP_LEA_C), 64, -2, 64 }, // dec index
{ OP(0, 0, 0, OP_IFAE), 2, 0, 64 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 64, 1 },
{ OP(1, 1, 1, OP_EQ_D_1), 0, 8, 16 },
{ OP(1, 1, 1, OP_LT_D_1), 0, 8, 24 },
{ OP(1, 1, 1, OP_GT_D_1), 0, 8, 32 },
{ OP(1, 1, 1, OP_NE_D_1), 0, 8, 40 },
{ OP(1, 1, 1, OP_GE_D_1), 0, 8, 48 },
{ OP(1, 1, 1, OP_LE_D_1), 0, 8, 56 },
{ OP(1, 1, 1, OP_JUMP_A), -10, 0, 0 },
};
static dstatement_t double_cmpop_2_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 8, 0, 64 }, // init index
//loop:
{ OP(0, 0, 0, OP_LEA_C), 64, -4, 64 }, // dec index
{ OP(0, 0, 0, OP_IFAE), 2, 0, 64 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 64, 1 },
{ OP(1, 1, 1, OP_EQ_D_2), 0, 8, 16 },
{ OP(1, 1, 1, OP_LT_D_2), 0, 8, 24 },
{ OP(1, 1, 1, OP_GT_D_2), 0, 8, 32 },
{ OP(1, 1, 1, OP_NE_D_2), 0, 8, 40 },
{ OP(1, 1, 1, OP_GE_D_2), 0, 8, 48 },
{ OP(1, 1, 1, OP_LE_D_2), 0, 8, 56 },
{ OP(1, 1, 1, OP_JUMP_A), -10, 0, 0 },
};
static dstatement_t double_cmpop_3a_statements[] = {
{ OP(1, 1, 1, OP_EQ_D_3), 0, 8, 16 },
{ OP(1, 1, 1, OP_EQ_D_1), 6, 14, 22 },
{ OP(1, 1, 1, OP_LT_D_3), 0, 8, 24 },
{ OP(1, 1, 1, OP_LT_D_1), 6, 14, 30 },
{ OP(1, 1, 1, OP_GT_D_3), 0, 8, 32 },
{ OP(1, 1, 1, OP_GT_D_1), 6, 14, 38 },
{ OP(1, 1, 1, OP_NE_D_3), 0, 8, 40 },
{ OP(1, 1, 1, OP_NE_D_1), 6, 14, 46 },
{ OP(1, 1, 1, OP_GE_D_3), 0, 8, 48 },
{ OP(1, 1, 1, OP_GE_D_1), 6, 14, 54 },
{ OP(1, 1, 1, OP_LE_D_3), 0, 8, 56 },
{ OP(1, 1, 1, OP_LE_D_1), 6, 14, 62 },
};
static dstatement_t double_cmpop_3b_statements[] = {
{ OP(1, 1, 1, OP_EQ_D_1), 0, 8, 16 },
{ OP(1, 1, 1, OP_EQ_D_3), 2, 10, 18 },
{ OP(1, 1, 1, OP_LT_D_1), 0, 8, 24 },
{ OP(1, 1, 1, OP_LT_D_3), 2, 10, 26 },
{ OP(1, 1, 1, OP_GT_D_1), 0, 8, 32 },
{ OP(1, 1, 1, OP_GT_D_3), 2, 10, 34 },
{ OP(1, 1, 1, OP_NE_D_1), 0, 8, 40 },
{ OP(1, 1, 1, OP_NE_D_3), 2, 10, 42 },
{ OP(1, 1, 1, OP_GE_D_1), 0, 8, 48 },
{ OP(1, 1, 1, OP_GE_D_3), 2, 10, 50 },
{ OP(1, 1, 1, OP_LE_D_1), 0, 8, 56 },
{ OP(1, 1, 1, OP_LE_D_3), 2, 10, 58 },
};
static dstatement_t double_cmpop_4_statements[] = {
{ OP(1, 1, 1, OP_EQ_D_4), 0, 8, 16 },
{ OP(1, 1, 1, OP_LT_D_4), 0, 8, 24 },
{ OP(1, 1, 1, OP_GT_D_4), 0, 8, 32 },
{ OP(1, 1, 1, OP_NE_D_4), 0, 8, 40 },
{ OP(1, 1, 1, OP_GE_D_4), 0, 8, 48 },
{ OP(1, 1, 1, OP_LE_D_4), 0, 8, 56 },
};
test_t tests[] = {
{
.desc = "double binop 1",
.extra_globals = 8 * 1,
.num_globals = num_globals(double_binop_init,double_binop_expect),
.num_statements = num_statements (double_binop_1_statements),
.statements = double_binop_1_statements,
.init_globals = (pr_int_t *) double_binop_init,
.expect_globals = (pr_int_t *) double_binop_expect,
},
{
.desc = "double binop 2",
.extra_globals = 8 * 1,
.num_globals = num_globals(double_binop_init,double_binop_expect),
.num_statements = num_statements (double_binop_2_statements),
.statements = double_binop_2_statements,
.init_globals = (pr_int_t *) double_binop_init,
.expect_globals = (pr_int_t *) double_binop_expect,
},
{
.desc = "double binop 3a",
.extra_globals = 8 * 1,
.num_globals = num_globals(double_binop_init,double_binop_expect),
.num_statements = num_statements (double_binop_3a_statements),
.statements = double_binop_3a_statements,
.init_globals = (pr_int_t *) double_binop_init,
.expect_globals = (pr_int_t *) double_binop_expect,
},
{
.desc = "double binop 3b",
.extra_globals = 8 * 1,
.num_globals = num_globals(double_binop_init,double_binop_expect),
.num_statements = num_statements (double_binop_3b_statements),
.statements = double_binop_3b_statements,
.init_globals = (pr_int_t *) double_binop_init,
.expect_globals = (pr_int_t *) double_binop_expect,
},
{
.desc = "double binop 4",
.extra_globals = 8 * 1,
.num_globals = num_globals(double_binop_init,double_binop_expect),
.num_statements = num_statements (double_binop_4_statements),
.statements = double_binop_4_statements,
.init_globals = (pr_int_t *) double_binop_init,
.expect_globals = (pr_int_t *) double_binop_expect,
},
{
.desc = "double cos sin",
.extra_globals = 8 * 1,
.num_globals = num_globals(double_cossin_init,double_cossin_expect),
.num_statements = num_statements (double_cossin_statements),
.statements = double_cossin_statements,
.init_globals = (pr_int_t *) double_cossin_init,
.expect_globals = (pr_int_t *) double_cossin_expect,
},
{
.desc = "double cmpop 1",
.extra_globals = 4 * 1,
.num_globals = num_globals(double_cmpop_init,double_cmpop_expect),
.num_statements = num_statements (double_cmpop_1_statements),
.statements = double_cmpop_1_statements,
.init_globals = (pr_int_t *) double_cmpop_init,
.expect_globals = (pr_int_t *) double_cmpop_expect,
},
{
.desc = "double cmpop 2",
.extra_globals = 4 * 1,
.num_globals = num_globals(double_cmpop_init,double_cmpop_expect),
.num_statements = num_statements (double_cmpop_2_statements),
.statements = double_cmpop_2_statements,
.init_globals = (pr_int_t *) double_cmpop_init,
.expect_globals = (pr_int_t *) double_cmpop_expect,
},
{
.desc = "double cmpop 3a",
.extra_globals = 4 * 1,
.num_globals = num_globals(double_cmpop_init,double_cmpop_expect),
.num_statements = num_statements (double_cmpop_3a_statements),
.statements = double_cmpop_3a_statements,
.init_globals = (pr_int_t *) double_cmpop_init,
.expect_globals = (pr_int_t *) double_cmpop_expect,
},
{
.desc = "double cmpop 3b",
.extra_globals = 4 * 1,
.num_globals = num_globals(double_cmpop_init,double_cmpop_expect),
.num_statements = num_statements (double_cmpop_3b_statements),
.statements = double_cmpop_3b_statements,
.init_globals = (pr_int_t *) double_cmpop_init,
.expect_globals = (pr_int_t *) double_cmpop_expect,
},
{
.desc = "double cmpop 4",
.extra_globals = 4 * 1,
.num_globals = num_globals(double_cmpop_init,double_cmpop_expect),
.num_statements = num_statements (double_cmpop_4_statements),
.statements = double_cmpop_4_statements,
.init_globals = (pr_int_t *) double_cmpop_init,
.expect_globals = (pr_int_t *) double_cmpop_expect,
},
};
#include "main.c"

View file

@ -0,0 +1,333 @@
#include "head.c"
#include "QF/mathlib.h"
#define sq(x) ((float)(x)*(float)(x))
static pr_vec4_t float_binop_init[] = {
{ 5, -5, 5, -5},
{ 3, 3, -3, -3},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
};
static pr_vec4_t float_binop_expect[] = {
{ 5, -5, 5, -5},
{ 3, 3, -3, -3},
{ 15, -15, -15, 15},
{ 1.666666627, -1.666666627, -1.666666627, 1.666666627},
{ 2, -2, 2, -2},
{ 2, 1, -1, -2},
{ 8, -2, 2, -8},
{ 2, -8, 8, -2},
};
static dstatement_t float_binop_1_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 4, 0, 32 }, // init index
//loop:
{ OP(0, 0, 0, OP_LEA_C), 32, -1, 32 }, // dec index
{ OP(0, 0, 0, OP_IFAE), 2, 0, 32 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 32, 1 },
{ OP(1, 1, 1, OP_MUL_F_1), 0, 4, 8 },
{ OP(1, 1, 1, OP_DIV_F_1), 0, 4, 12 },
{ OP(1, 1, 1, OP_REM_F_1), 0, 4, 16 },
{ OP(1, 1, 1, OP_MOD_F_1), 0, 4, 20 },
{ OP(1, 1, 1, OP_ADD_F_1), 0, 4, 24 },
{ OP(1, 1, 1, OP_SUB_F_1), 0, 4, 28 },
{ OP(1, 1, 1, OP_JUMP_A), -10, 0, 0 },
};
static dstatement_t float_binop_2_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 4, 0, 32 }, // index
//loop:
{ OP(0, 0, 0, OP_LEA_C), 32, -2, 32 }, // dec index
{ OP(0, 0, 0, OP_IFAE), 2, 0, 32 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 32, 1 },
{ OP(1, 1, 1, OP_MUL_F_2), 0, 4, 8 },
{ OP(1, 1, 1, OP_DIV_F_2), 0, 4, 12 },
{ OP(1, 1, 1, OP_REM_F_2), 0, 4, 16 },
{ OP(1, 1, 1, OP_MOD_F_2), 0, 4, 20 },
{ OP(1, 1, 1, OP_ADD_F_2), 0, 4, 24 },
{ OP(1, 1, 1, OP_SUB_F_2), 0, 4, 28 },
{ OP(1, 1, 1, OP_JUMP_A), -10, 0, 0 },
};
static dstatement_t float_binop_3a_statements[] = {
{ OP(1, 1, 1, OP_MUL_F_3), 0, 4, 8 },
{ OP(1, 1, 1, OP_MUL_F_1), 3, 7, 11 },
{ OP(1, 1, 1, OP_DIV_F_3), 0, 4, 12 },
{ OP(1, 1, 1, OP_DIV_F_1), 3, 7, 15 },
{ OP(1, 1, 1, OP_REM_F_3), 0, 4, 16 },
{ OP(1, 1, 1, OP_REM_F_1), 3, 7, 19 },
{ OP(1, 1, 1, OP_MOD_F_3), 0, 4, 20 },
{ OP(1, 1, 1, OP_MOD_F_1), 3, 7, 23 },
{ OP(1, 1, 1, OP_ADD_F_3), 0, 4, 24 },
{ OP(1, 1, 1, OP_ADD_F_1), 3, 7, 27 },
{ OP(1, 1, 1, OP_SUB_F_3), 0, 4, 28 },
{ OP(1, 1, 1, OP_SUB_F_1), 3, 7, 31 },
};
static dstatement_t float_binop_3b_statements[] = {
{ OP(1, 1, 1, OP_MUL_F_1), 0, 4, 8 },
{ OP(1, 1, 1, OP_MUL_F_3), 1, 5, 9 },
{ OP(1, 1, 1, OP_DIV_F_1), 0, 4, 12 },
{ OP(1, 1, 1, OP_DIV_F_3), 1, 5, 13 },
{ OP(1, 1, 1, OP_REM_F_1), 0, 4, 16 },
{ OP(1, 1, 1, OP_REM_F_3), 1, 5, 17 },
{ OP(1, 1, 1, OP_MOD_F_1), 0, 4, 20 },
{ OP(1, 1, 1, OP_MOD_F_3), 1, 5, 21 },
{ OP(1, 1, 1, OP_ADD_F_1), 0, 4, 24 },
{ OP(1, 1, 1, OP_ADD_F_3), 1, 5, 25 },
{ OP(1, 1, 1, OP_SUB_F_1), 0, 4, 28 },
{ OP(1, 1, 1, OP_SUB_F_3), 1, 5, 29 },
};
static dstatement_t float_binop_4_statements[] = {
{ OP(1, 1, 1, OP_MUL_F_4), 0, 4, 8 },
{ OP(1, 1, 1, OP_DIV_F_4), 0, 4, 12 },
{ OP(1, 1, 1, OP_REM_F_4), 0, 4, 16 },
{ OP(1, 1, 1, OP_MOD_F_4), 0, 4, 20 },
{ OP(1, 1, 1, OP_ADD_F_4), 0, 4, 24 },
{ OP(1, 1, 1, OP_SUB_F_4), 0, 4, 28 },
};
static pr_vec4_t float_cossin_init[] = {
{ 1, 2, 3, 4 }, // 0: output
{ M_PI/6, 0, 0, 0 }, // 4: x
{ 1, 2, 0, 0 }, // 8: f
{ 1, 1, 0, 25 }, // 12: f inc and f0 max
{ 0, 0, 0, 0 }, // 16: x2 -> [xx, xx]
// { } // 20: xn
};
static pr_vec4_t float_cossin_expect[] = {
{ 0.866025388, 0.5, 0, 0 }, // 0: output
{ M_PI/6, 0, 0, 0 }, // 4: x
{ 25, 26, 0, 0 }, // 8: f
{ 1, 1, 0, 25 }, // 12: f inc and f0 max
{ -sq(M_PI/6), -sq(M_PI/6), 0, 0 }, // 16: x2 -> [xx, xx]
};
static dstatement_t float_cossin_statements[] = {
{ OP(0, 0, 0, OP_STORE_A_1), 21, 0, 4 }, // init xn -> [?, x]
{ OP(0, 0, 0, OP_STORE_A_1), 20, 0, 8 }, // init xn -> [1, x]
{ OP(0, 0, 0, OP_SWIZZLE_F), 4, 0xc000, 16 },// init x2 -> [x, x, 0, 0]
{ OP(0, 0, 0, OP_MUL_F_2), 16, 16, 16 }, // x2 -> [x*x, x*x, 0, 0]
{ OP(0, 0, 0, OP_SWIZZLE_F), 16, 0xc3e4, 16 },// init x2 -> -x2
{ OP(0, 0, 0, OP_SUB_F_4), 0, 0, 0 }, // init acc (output) to 0
// loop:
{ OP(0, 0, 0, OP_ADD_F_2), 0, 20, 0 }, // acc += xn
{ OP(0, 0, 0, OP_MUL_F_2), 20, 16, 20 }, // xn *= x2
{ OP(0, 0, 0, OP_DIV_F_2), 20, 8, 20 }, // xn /= f
{ OP(0, 0, 0, OP_ADD_F_2), 8, 12, 8 }, // f += inc
{ OP(0, 0, 0, OP_DIV_F_2), 20, 8, 20 }, // xn /= f
{ OP(0, 0, 0, OP_ADD_F_2), 8, 12, 8 }, // f += inc
{ OP(0, 0, 0, OP_LT_F_1), 8, 15, 23 }, // f0 < fmax
{ OP(0, 0, 0, OP_IFNZ), -7, 0, 23 }, // f0 < fmax
};
static pr_vec4_t float_cmpop_init[] = {
{ 5, -5, 5, -5},
{ 5, 5, -5, -5},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
};
// 5.0 as 32-bit int
#define F 0x40a00000
#define mF 0xc0a00000
static pr_ivec4_t float_cmpop_expect[] = {
{ F, mF, F, mF},
{ F, F, mF, mF},
{ -1, 0, 0, -1},
{ 0, -1, 0, 0},
{ 0, 0, -1, 0},
{ 0, -1, -1, 0},
{ -1, 0, -1, -1},
{ -1, -1, 0, -1},
};
static dstatement_t float_cmpop_1_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 4, 0, 32 }, // init index
//loop:
{ OP(0, 0, 0, OP_LEA_C), 32, -1, 32 }, // dec index
{ OP(0, 0, 0, OP_IFAE), 2, 0, 32 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 32, 1 },
{ OP(1, 1, 1, OP_EQ_F_1), 0, 4, 8 },
{ OP(1, 1, 1, OP_LT_F_1), 0, 4, 12 },
{ OP(1, 1, 1, OP_GT_F_1), 0, 4, 16 },
{ OP(1, 1, 1, OP_NE_F_1), 0, 4, 20 },
{ OP(1, 1, 1, OP_GE_F_1), 0, 4, 24 },
{ OP(1, 1, 1, OP_LE_F_1), 0, 4, 28 },
{ OP(1, 1, 1, OP_JUMP_A), -10, 0, 0 },
};
static dstatement_t float_cmpop_2_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 4, 0, 32 }, // index
//loop:
{ OP(0, 0, 0, OP_LEA_C), 32, -2, 32 }, // dec index
{ OP(0, 0, 0, OP_IFAE), 2, 0, 32 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 32, 1 },
{ OP(1, 1, 1, OP_EQ_F_2), 0, 4, 8 },
{ OP(1, 1, 1, OP_LT_F_2), 0, 4, 12 },
{ OP(1, 1, 1, OP_GT_F_2), 0, 4, 16 },
{ OP(1, 1, 1, OP_NE_F_2), 0, 4, 20 },
{ OP(1, 1, 1, OP_GE_F_2), 0, 4, 24 },
{ OP(1, 1, 1, OP_LE_F_2), 0, 4, 28 },
{ OP(1, 1, 1, OP_JUMP_A), -10, 0, 0 },
};
static dstatement_t float_cmpop_3a_statements[] = {
{ OP(1, 1, 1, OP_EQ_F_3), 0, 4, 8 },
{ OP(1, 1, 1, OP_EQ_F_1), 3, 7, 11 },
{ OP(1, 1, 1, OP_LT_F_3), 0, 4, 12 },
{ OP(1, 1, 1, OP_LT_F_1), 3, 7, 15 },
{ OP(1, 1, 1, OP_GT_F_3), 0, 4, 16 },
{ OP(1, 1, 1, OP_GT_F_1), 3, 7, 19 },
{ OP(1, 1, 1, OP_NE_F_3), 0, 4, 20 },
{ OP(1, 1, 1, OP_NE_F_1), 3, 7, 23 },
{ OP(1, 1, 1, OP_GE_F_3), 0, 4, 24 },
{ OP(1, 1, 1, OP_GE_F_1), 3, 7, 27 },
{ OP(1, 1, 1, OP_LE_F_3), 0, 4, 28 },
{ OP(1, 1, 1, OP_LE_F_1), 3, 7, 31 },
};
static dstatement_t float_cmpop_3b_statements[] = {
{ OP(1, 1, 1, OP_EQ_F_1), 0, 4, 8 },
{ OP(1, 1, 1, OP_EQ_F_3), 1, 5, 9 },
{ OP(1, 1, 1, OP_LT_F_1), 0, 4, 12 },
{ OP(1, 1, 1, OP_LT_F_3), 1, 5, 13 },
{ OP(1, 1, 1, OP_GT_F_1), 0, 4, 16 },
{ OP(1, 1, 1, OP_GT_F_3), 1, 5, 17 },
{ OP(1, 1, 1, OP_NE_F_1), 0, 4, 20 },
{ OP(1, 1, 1, OP_NE_F_3), 1, 5, 21 },
{ OP(1, 1, 1, OP_GE_F_1), 0, 4, 24 },
{ OP(1, 1, 1, OP_GE_F_3), 1, 5, 25 },
{ OP(1, 1, 1, OP_LE_F_1), 0, 4, 28 },
{ OP(1, 1, 1, OP_LE_F_3), 1, 5, 29 },
};
static dstatement_t float_cmpop_4_statements[] = {
{ OP(1, 1, 1, OP_EQ_F_4), 0, 4, 8 },
{ OP(1, 1, 1, OP_LT_F_4), 0, 4, 12 },
{ OP(1, 1, 1, OP_GT_F_4), 0, 4, 16 },
{ OP(1, 1, 1, OP_NE_F_4), 0, 4, 20 },
{ OP(1, 1, 1, OP_GE_F_4), 0, 4, 24 },
{ OP(1, 1, 1, OP_LE_F_4), 0, 4, 28 },
};
test_t tests[] = {
{
.desc = "float binop 1",
.extra_globals = 4 * 1,
.num_globals = num_globals(float_binop_init,float_binop_expect),
.num_statements = num_statements (float_binop_1_statements),
.statements = float_binop_1_statements,
.init_globals = (pr_int_t *) float_binop_init,
.expect_globals = (pr_int_t *) float_binop_expect,
},
{
.desc = "float binop 2",
.extra_globals = 4 * 1,
.num_globals = num_globals(float_binop_init,float_binop_expect),
.num_statements = num_statements (float_binop_2_statements),
.statements = float_binop_2_statements,
.init_globals = (pr_int_t *) float_binop_init,
.expect_globals = (pr_int_t *) float_binop_expect,
},
{
.desc = "float binop 3a",
.extra_globals = 4 * 1,
.num_globals = num_globals(float_binop_init,float_binop_expect),
.num_statements = num_statements (float_binop_3a_statements),
.statements = float_binop_3a_statements,
.init_globals = (pr_int_t *) float_binop_init,
.expect_globals = (pr_int_t *) float_binop_expect,
},
{
.desc = "float binop 3b",
.extra_globals = 4 * 1,
.num_globals = num_globals(float_binop_init,float_binop_expect),
.num_statements = num_statements (float_binop_3b_statements),
.statements = float_binop_3b_statements,
.init_globals = (pr_int_t *) float_binop_init,
.expect_globals = (pr_int_t *) float_binop_expect,
},
{
.desc = "float binop 4",
.extra_globals = 4 * 1,
.num_globals = num_globals(float_binop_init,float_binop_expect),
.num_statements = num_statements (float_binop_4_statements),
.statements = float_binop_4_statements,
.init_globals = (pr_int_t *) float_binop_init,
.expect_globals = (pr_int_t *) float_binop_expect,
},
{
.desc = "float cos sin",
.extra_globals = 4 * 1,
.num_globals = num_globals (float_cossin_init, float_cossin_expect),
.num_statements = num_statements (float_cossin_statements),
.statements = float_cossin_statements,
.init_globals = (pr_int_t *) float_cossin_init,
.expect_globals = (pr_int_t *) float_cossin_expect,
},
{
.desc = "float cmpop 1",
.extra_globals = 4 * 1,
.num_globals = num_globals(float_cmpop_init,float_cmpop_expect),
.num_statements = num_statements (float_cmpop_1_statements),
.statements = float_cmpop_1_statements,
.init_globals = (pr_int_t *) float_cmpop_init,
.expect_globals = (pr_int_t *) float_cmpop_expect,
},
{
.desc = "float cmpop 2",
.extra_globals = 4 * 1,
.num_globals = num_globals(float_cmpop_init,float_cmpop_expect),
.num_statements = num_statements (float_cmpop_2_statements),
.statements = float_cmpop_2_statements,
.init_globals = (pr_int_t *) float_cmpop_init,
.expect_globals = (pr_int_t *) float_cmpop_expect,
},
{
.desc = "float cmpop 3a",
.extra_globals = 4 * 1,
.num_globals = num_globals(float_cmpop_init,float_cmpop_expect),
.num_statements = num_statements (float_cmpop_3a_statements),
.statements = float_cmpop_3a_statements,
.init_globals = (pr_int_t *) float_cmpop_init,
.expect_globals = (pr_int_t *) float_cmpop_expect,
},
{
.desc = "float cmpop 3b",
.extra_globals = 4 * 1,
.num_globals = num_globals(float_cmpop_init,float_cmpop_expect),
.num_statements = num_statements (float_cmpop_3b_statements),
.statements = float_cmpop_3b_statements,
.init_globals = (pr_int_t *) float_cmpop_init,
.expect_globals = (pr_int_t *) float_cmpop_expect,
},
{
.desc = "float cmpop 4",
.extra_globals = 4 * 1,
.num_globals = num_globals(float_cmpop_init,float_cmpop_expect),
.num_statements = num_statements (float_cmpop_4_statements),
.statements = float_cmpop_4_statements,
.init_globals = (pr_int_t *) float_cmpop_init,
.expect_globals = (pr_int_t *) float_cmpop_expect,
},
};
#include "main.c"

View file

@ -0,0 +1,166 @@
#include "head.c"
#include "QF/mathlib.h"
static pr_uivec4_t uint_hop_init[7] = {
{ 0x0000ff00, 0x0000f0f0, 0x0000cccc, 0x0000aaaa },
};
static pr_uivec4_t uint_hop_expect[] = {
{ 0x0000ff00, 0x0000f0f0, 0x0000cccc, 0x0000aaaa },
{ 0x00008888, 0x0000eeee, 0x00006666, 0x00017776 },
{ 0xffff7777, 0xffff1111, 0xffff9999, 0 },
{ 0x00008080, 0x0000fefe, 0x00009696, 0x00026866 },
{ 0xffff7f7f, 0xffff0101, 0xffff6969, 0 },
{ 0x00008000, 0x0000fffe, 0x00006996, 0x00036766 },
{ 0xffff7fff, 0xffff0001, 0xffff9669, 0 },
};
static dstatement_t uint_hop_statements[] = {
{ OP(0, 0, 0, OP_WITH), 0, 4, 1 },
{ OP(0, 0, 0, OP_WITH), 0, 12, 2 },
{ OP(0, 0, 0, OP_WITH), 0, 20, 3 },
{ OP(0, 0, 1, OP_HOPS), 2, 010, 0 },
{ OP(0, 0, 1, OP_HOPS), 2, 011, 1 },
{ OP(0, 0, 1, OP_HOPS), 2, 012, 2 },
{ OP(0, 0, 1, OP_HOPS), 2, 013, 3 },
{ OP(0, 0, 1, OP_HOPS), 2, 014, 4 },
{ OP(0, 0, 1, OP_HOPS), 2, 015, 5 },
{ OP(0, 0, 1, OP_HOPS), 2, 016, 6 },
{ OP(0, 0, 2, OP_HOPS), 1, 020, 0 },
{ OP(0, 0, 2, OP_HOPS), 1, 021, 1 },
{ OP(0, 0, 2, OP_HOPS), 1, 022, 2 },
{ OP(0, 0, 2, OP_HOPS), 1, 023, 3 },
{ OP(0, 0, 2, OP_HOPS), 1, 024, 4 },
{ OP(0, 0, 2, OP_HOPS), 1, 025, 5 },
{ OP(0, 0, 2, OP_HOPS), 1, 026, 6 },
{ OP(0, 0, 3, OP_HOPS), 0, 030, 0 },
{ OP(0, 0, 3, OP_HOPS), 0, 031, 1 },
{ OP(0, 0, 3, OP_HOPS), 0, 032, 2 },
{ OP(0, 0, 3, OP_HOPS), 0, 033, 3 },
{ OP(0, 0, 3, OP_HOPS), 0, 034, 4 },
{ OP(0, 0, 3, OP_HOPS), 0, 035, 5 },
{ OP(0, 0, 3, OP_HOPS), 0, 036, 6 },
};
static pr_ulvec4_t ulong_hop_init[7] = {
{ UINT64_C(0x00ff00000000), UINT64_C(0x0f0f00000000),
UINT64_C(0x333300000000), UINT64_C(0x555500000000) },
};
static pr_ulvec4_t ulong_hop_expect[] = {
{ UINT64_C(0x000000ff00000000), UINT64_C(0x00000f0f00000000),
UINT64_C(0x0000333300000000), UINT64_C(0x0000555500000000) },
{ UINT64_C(0x0000111100000000), UINT64_C(0x0000777700000000),
UINT64_C(0x0000666600000000), UINT64_C(0x0000888800000000) },
{ UINT64_C(0xffffeeeeffffffff), UINT64_C(0xffff8888ffffffff),
UINT64_C(0xffff9999ffffffff), 0 },
{ UINT64_C(0x0000010100000000), UINT64_C(0x00007f7f00000000),
UINT64_C(0x0000696900000000), UINT64_C(0x0000979700000000) },
{ UINT64_C(0xfffffefeffffffff), UINT64_C(0xffff8080ffffffff),
UINT64_C(0xffff9696ffffffff), 0 },
{ UINT64_C(0x0000000100000000), UINT64_C(0x00007fff00000000),
UINT64_C(0x0000699600000000), UINT64_C(0x0000989600000000) },
{ UINT64_C(0xfffffffeffffffff), UINT64_C(0xffff8000ffffffff),
UINT64_C(0xffff9669ffffffff), 0 },
};
static dstatement_t ulong_hop_statements[] = {
{ OP(0, 0, 0, OP_WITH), 0, 8, 1 },
{ OP(0, 0, 0, OP_WITH), 0, 24, 2 },
{ OP(0, 0, 0, OP_WITH), 0, 40, 3 },
{ OP(0, 0, 1, OP_HOPS), 4, 050, 0 },
{ OP(0, 0, 1, OP_HOPS), 4, 051, 2 },
{ OP(0, 0, 1, OP_HOPS), 4, 052, 4 },
{ OP(0, 0, 1, OP_HOPS), 4, 053, 6 },
{ OP(0, 0, 1, OP_HOPS), 4, 054, 8 },
{ OP(0, 0, 1, OP_HOPS), 4, 055, 10 },
{ OP(0, 0, 1, OP_HOPS), 4, 056, 12 },
{ OP(0, 0, 2, OP_HOPS), 2, 060, 0 },
{ OP(0, 0, 2, OP_HOPS), 2, 061, 2 },
{ OP(0, 0, 2, OP_HOPS), 2, 062, 4 },
{ OP(0, 0, 2, OP_HOPS), 2, 063, 6 },
{ OP(0, 0, 2, OP_HOPS), 2, 064, 8 },
{ OP(0, 0, 2, OP_HOPS), 2, 065, 10 },
{ OP(0, 0, 2, OP_HOPS), 2, 066, 12 },
{ OP(0, 0, 3, OP_HOPS), 0, 070, 0 },
{ OP(0, 0, 3, OP_HOPS), 0, 071, 2 },
{ OP(0, 0, 3, OP_HOPS), 0, 072, 4 },
{ OP(0, 0, 3, OP_HOPS), 0, 073, 6 },
{ OP(0, 0, 3, OP_HOPS), 0, 074, 8 },
{ OP(0, 0, 3, OP_HOPS), 0, 075, 10 },
{ OP(0, 0, 3, OP_HOPS), 0, 076, 12 },
};
static pr_vec4_t float_hop_init[2] = {
{ 1, 2, 3, 4 },
};
static pr_vec4_t float_hop_expect[] = {
{ 1, 2, 3, 4 },
{ 3, 6, 10, 0 },
};
static dstatement_t float_hop_statements[] = {
{ OP(0, 0, 0, OP_HOPS), 0, 017, 4 },
{ OP(0, 0, 0, OP_HOPS), 0, 027, 5 },
{ OP(0, 0, 0, OP_HOPS), 0, 037, 6 },
};
static pr_dvec4_t double_hop_init[2] = {
{ 1, 2, 3, 4 },
};
static pr_dvec4_t double_hop_expect[] = {
{ 1, 2, 3, 4 },
{ 3, 6, 10, 0 },
};
static dstatement_t double_hop_statements[] = {
{ OP(0, 0, 0, OP_HOPS), 0, 057, 8 },
{ OP(0, 0, 0, OP_HOPS), 0, 067, 10 },
{ OP(0, 0, 0, OP_HOPS), 0, 077, 12 },
};
test_t tests[] = {
{
.desc = "uint hops",
.num_globals = num_globals(uint_hop_init,uint_hop_expect),
.num_statements = num_statements (uint_hop_statements),
.statements = uint_hop_statements,
.init_globals = (pr_int_t *) uint_hop_init,
.expect_globals = (pr_int_t *) uint_hop_expect,
},
{
.desc = "ulong hops",
.num_globals = num_globals(ulong_hop_init,ulong_hop_expect),
.num_statements = num_statements (ulong_hop_statements),
.statements = ulong_hop_statements,
.init_globals = (pr_int_t *) ulong_hop_init,
.expect_globals = (pr_int_t *) ulong_hop_expect,
},
{
.desc = "float hops",
.num_globals = num_globals(float_hop_init,float_hop_expect),
.num_statements = num_statements (float_hop_statements),
.statements = float_hop_statements,
.init_globals = (pr_int_t *) float_hop_init,
.expect_globals = (pr_int_t *) float_hop_expect,
},
{
.desc = "double hops",
.num_globals = num_globals(double_hop_init,double_hop_expect),
.num_statements = num_statements (double_hop_statements),
.statements = double_hop_statements,
.init_globals = (pr_int_t *) double_hop_init,
.expect_globals = (pr_int_t *) double_hop_expect,
},
};
#include "main.c"

View file

@ -0,0 +1,284 @@
#include "head.c"
#include "QF/mathlib.h"
static pr_ivec4_t int_binop_init[] = {
{ 5, -5, 5, -5},
{ 3, 3, -3, -3},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
};
static pr_ivec4_t int_binop_expect[] = {
{ 5, -5, 5, -5},
{ 3, 3, -3, -3},
{ 15, -15, -15, 15},
{ 1, -1, -1, 1},
{ 2, -2, 2, -2},
{ 2, 1, -1, -2},
{ 8, -2, 2, -8},
{ 2, -8, 8, -2},
};
static dstatement_t int_binop_1_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 4, 0, 32 }, // init index
//loop:
{ OP(0, 0, 0, OP_LEA_C), 32, -1, 32 }, // dec index
{ OP(0, 0, 0, OP_IFAE), 2, 0, 32 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 32, 1 },
{ OP(1, 1, 1, OP_MUL_I_1), 0, 4, 8 },
{ OP(1, 1, 1, OP_DIV_I_1), 0, 4, 12 },
{ OP(1, 1, 1, OP_REM_I_1), 0, 4, 16 },
{ OP(1, 1, 1, OP_MOD_I_1), 0, 4, 20 },
{ OP(1, 1, 1, OP_ADD_I_1), 0, 4, 24 },
{ OP(1, 1, 1, OP_SUB_I_1), 0, 4, 28 },
{ OP(1, 1, 1, OP_JUMP_A), -10, 0, 0 },
};
static dstatement_t int_binop_2_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 4, 0, 32 }, // index
//loop:
{ OP(0, 0, 0, OP_LEA_C), 32, -2, 32 }, // dec index
{ OP(0, 0, 0, OP_IFAE), 2, 0, 32 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 32, 1 },
{ OP(1, 1, 1, OP_MUL_I_2), 0, 4, 8 },
{ OP(1, 1, 1, OP_DIV_I_2), 0, 4, 12 },
{ OP(1, 1, 1, OP_REM_I_2), 0, 4, 16 },
{ OP(1, 1, 1, OP_MOD_I_2), 0, 4, 20 },
{ OP(1, 1, 1, OP_ADD_I_2), 0, 4, 24 },
{ OP(1, 1, 1, OP_SUB_I_2), 0, 4, 28 },
{ OP(1, 1, 1, OP_JUMP_A), -10, 0, 0 },
};
static dstatement_t int_binop_3a_statements[] = {
{ OP(1, 1, 1, OP_MUL_I_3), 0, 4, 8 },
{ OP(1, 1, 1, OP_MUL_I_1), 3, 7, 11 },
{ OP(1, 1, 1, OP_DIV_I_3), 0, 4, 12 },
{ OP(1, 1, 1, OP_DIV_I_1), 3, 7, 15 },
{ OP(1, 1, 1, OP_REM_I_3), 0, 4, 16 },
{ OP(1, 1, 1, OP_REM_I_1), 3, 7, 19 },
{ OP(1, 1, 1, OP_MOD_I_3), 0, 4, 20 },
{ OP(1, 1, 1, OP_MOD_I_1), 3, 7, 23 },
{ OP(1, 1, 1, OP_ADD_I_3), 0, 4, 24 },
{ OP(1, 1, 1, OP_ADD_I_1), 3, 7, 27 },
{ OP(1, 1, 1, OP_SUB_I_3), 0, 4, 28 },
{ OP(1, 1, 1, OP_SUB_I_1), 3, 7, 31 },
};
static dstatement_t int_binop_3b_statements[] = {
{ OP(1, 1, 1, OP_MUL_I_1), 0, 4, 8 },
{ OP(1, 1, 1, OP_MUL_I_3), 1, 5, 9 },
{ OP(1, 1, 1, OP_DIV_I_1), 0, 4, 12 },
{ OP(1, 1, 1, OP_DIV_I_3), 1, 5, 13 },
{ OP(1, 1, 1, OP_REM_I_1), 0, 4, 16 },
{ OP(1, 1, 1, OP_REM_I_3), 1, 5, 17 },
{ OP(1, 1, 1, OP_MOD_I_1), 0, 4, 20 },
{ OP(1, 1, 1, OP_MOD_I_3), 1, 5, 21 },
{ OP(1, 1, 1, OP_ADD_I_1), 0, 4, 24 },
{ OP(1, 1, 1, OP_ADD_I_3), 1, 5, 25 },
{ OP(1, 1, 1, OP_SUB_I_1), 0, 4, 28 },
{ OP(1, 1, 1, OP_SUB_I_3), 1, 5, 29 },
};
static dstatement_t int_binop_4_statements[] = {
{ OP(1, 1, 1, OP_MUL_I_4), 0, 4, 8 },
{ OP(1, 1, 1, OP_DIV_I_4), 0, 4, 12 },
{ OP(1, 1, 1, OP_REM_I_4), 0, 4, 16 },
{ OP(1, 1, 1, OP_MOD_I_4), 0, 4, 20 },
{ OP(1, 1, 1, OP_ADD_I_4), 0, 4, 24 },
{ OP(1, 1, 1, OP_SUB_I_4), 0, 4, 28 },
};
static pr_ivec4_t int_cmpop_init[] = {
{ 5, -5, 5, -5},
{ 5, 5, -5, -5},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
};
static pr_ivec4_t int_cmpop_expect[] = {
{ 5, -5, 5, -5},
{ 5, 5, -5, -5},
{ -1, 0, 0, -1},
{ 0, -1, 0, 0},
{ 0, 0, -1, 0},
{ 0, -1, -1, 0},
{ -1, 0, -1, -1},
{ -1, -1, 0, -1},
};
static dstatement_t int_cmpop_1_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 4, 0, 32 }, // init index
//loop:
{ OP(0, 0, 0, OP_LEA_C), 32, -1, 32 }, // dec index
{ OP(0, 0, 0, OP_IFAE), 2, 0, 32 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 32, 1 },
{ OP(1, 1, 1, OP_EQ_I_1), 0, 4, 8 },
{ OP(1, 1, 1, OP_LT_I_1), 0, 4, 12 },
{ OP(1, 1, 1, OP_GT_I_1), 0, 4, 16 },
{ OP(1, 1, 1, OP_NE_I_1), 0, 4, 20 },
{ OP(1, 1, 1, OP_GE_I_1), 0, 4, 24 },
{ OP(1, 1, 1, OP_LE_I_1), 0, 4, 28 },
{ OP(1, 1, 1, OP_JUMP_A), -10, 0, 0 },
};
static dstatement_t int_cmpop_2_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 4, 0, 32 }, // index
//loop:
{ OP(0, 0, 0, OP_LEA_C), 32, -2, 32 }, // dec index
{ OP(0, 0, 0, OP_IFAE), 2, 0, 32 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 32, 1 },
{ OP(1, 1, 1, OP_EQ_I_2), 0, 4, 8 },
{ OP(1, 1, 1, OP_LT_I_2), 0, 4, 12 },
{ OP(1, 1, 1, OP_GT_I_2), 0, 4, 16 },
{ OP(1, 1, 1, OP_NE_I_2), 0, 4, 20 },
{ OP(1, 1, 1, OP_GE_I_2), 0, 4, 24 },
{ OP(1, 1, 1, OP_LE_I_2), 0, 4, 28 },
{ OP(1, 1, 1, OP_JUMP_A), -10, 0, 0 },
};
static dstatement_t int_cmpop_3a_statements[] = {
{ OP(1, 1, 1, OP_EQ_I_3), 0, 4, 8 },
{ OP(1, 1, 1, OP_EQ_I_1), 3, 7, 11 },
{ OP(1, 1, 1, OP_LT_I_3), 0, 4, 12 },
{ OP(1, 1, 1, OP_LT_I_1), 3, 7, 15 },
{ OP(1, 1, 1, OP_GT_I_3), 0, 4, 16 },
{ OP(1, 1, 1, OP_GT_I_1), 3, 7, 19 },
{ OP(1, 1, 1, OP_NE_I_3), 0, 4, 20 },
{ OP(1, 1, 1, OP_NE_I_1), 3, 7, 23 },
{ OP(1, 1, 1, OP_GE_I_3), 0, 4, 24 },
{ OP(1, 1, 1, OP_GE_I_1), 3, 7, 27 },
{ OP(1, 1, 1, OP_LE_I_3), 0, 4, 28 },
{ OP(1, 1, 1, OP_LE_I_1), 3, 7, 31 },
};
static dstatement_t int_cmpop_3b_statements[] = {
{ OP(1, 1, 1, OP_EQ_I_1), 0, 4, 8 },
{ OP(1, 1, 1, OP_EQ_I_3), 1, 5, 9 },
{ OP(1, 1, 1, OP_LT_I_1), 0, 4, 12 },
{ OP(1, 1, 1, OP_LT_I_3), 1, 5, 13 },
{ OP(1, 1, 1, OP_GT_I_1), 0, 4, 16 },
{ OP(1, 1, 1, OP_GT_I_3), 1, 5, 17 },
{ OP(1, 1, 1, OP_NE_I_1), 0, 4, 20 },
{ OP(1, 1, 1, OP_NE_I_3), 1, 5, 21 },
{ OP(1, 1, 1, OP_GE_I_1), 0, 4, 24 },
{ OP(1, 1, 1, OP_GE_I_3), 1, 5, 25 },
{ OP(1, 1, 1, OP_LE_I_1), 0, 4, 28 },
{ OP(1, 1, 1, OP_LE_I_3), 1, 5, 29 },
};
static dstatement_t int_cmpop_4_statements[] = {
{ OP(1, 1, 1, OP_EQ_I_4), 0, 4, 8 },
{ OP(1, 1, 1, OP_LT_I_4), 0, 4, 12 },
{ OP(1, 1, 1, OP_GT_I_4), 0, 4, 16 },
{ OP(1, 1, 1, OP_NE_I_4), 0, 4, 20 },
{ OP(1, 1, 1, OP_GE_I_4), 0, 4, 24 },
{ OP(1, 1, 1, OP_LE_I_4), 0, 4, 28 },
};
test_t tests[] = {
{
.desc = "int binop 1",
.extra_globals = 4 * 1,
.num_globals = num_globals(int_binop_init,int_binop_expect),
.num_statements = num_statements (int_binop_1_statements),
.statements = int_binop_1_statements,
.init_globals = (pr_int_t *) int_binop_init,
.expect_globals = (pr_int_t *) int_binop_expect,
},
{
.desc = "int binop 2",
.extra_globals = 4 * 1,
.num_globals = num_globals(int_binop_init,int_binop_expect),
.num_statements = num_statements (int_binop_2_statements),
.statements = int_binop_2_statements,
.init_globals = (pr_int_t *) int_binop_init,
.expect_globals = (pr_int_t *) int_binop_expect,
},
{
.desc = "int binop 3a",
.extra_globals = 4 * 1,
.num_globals = num_globals(int_binop_init,int_binop_expect),
.num_statements = num_statements (int_binop_3a_statements),
.statements = int_binop_3a_statements,
.init_globals = (pr_int_t *) int_binop_init,
.expect_globals = (pr_int_t *) int_binop_expect,
},
{
.desc = "int binop 3b",
.extra_globals = 4 * 1,
.num_globals = num_globals(int_binop_init,int_binop_expect),
.num_statements = num_statements (int_binop_3b_statements),
.statements = int_binop_3b_statements,
.init_globals = (pr_int_t *) int_binop_init,
.expect_globals = (pr_int_t *) int_binop_expect,
},
{
.desc = "int binop 4",
.extra_globals = 4 * 1,
.num_globals = num_globals(int_binop_init,int_binop_expect),
.num_statements = num_statements (int_binop_4_statements),
.statements = int_binop_4_statements,
.init_globals = (pr_int_t *) int_binop_init,
.expect_globals = (pr_int_t *) int_binop_expect,
},
{
.desc = "int cmpop 1",
.extra_globals = 4 * 1,
.num_globals = num_globals(int_cmpop_init,int_cmpop_expect),
.num_statements = num_statements (int_cmpop_1_statements),
.statements = int_cmpop_1_statements,
.init_globals = (pr_int_t *) int_cmpop_init,
.expect_globals = (pr_int_t *) int_cmpop_expect,
},
{
.desc = "int cmpop 2",
.extra_globals = 4 * 1,
.num_globals = num_globals(int_cmpop_init,int_cmpop_expect),
.num_statements = num_statements (int_cmpop_2_statements),
.statements = int_cmpop_2_statements,
.init_globals = (pr_int_t *) int_cmpop_init,
.expect_globals = (pr_int_t *) int_cmpop_expect,
},
{
.desc = "int cmpop 3a",
.extra_globals = 4 * 1,
.num_globals = num_globals(int_cmpop_init,int_cmpop_expect),
.num_statements = num_statements (int_cmpop_3a_statements),
.statements = int_cmpop_3a_statements,
.init_globals = (pr_int_t *) int_cmpop_init,
.expect_globals = (pr_int_t *) int_cmpop_expect,
},
{
.desc = "int cmpop 3b",
.extra_globals = 4 * 1,
.num_globals = num_globals(int_cmpop_init,int_cmpop_expect),
.num_statements = num_statements (int_cmpop_3b_statements),
.statements = int_cmpop_3b_statements,
.init_globals = (pr_int_t *) int_cmpop_init,
.expect_globals = (pr_int_t *) int_cmpop_expect,
},
{
.desc = "int cmpop 4",
.extra_globals = 4 * 1,
.num_globals = num_globals(int_cmpop_init,int_cmpop_expect),
.num_statements = num_statements (int_cmpop_4_statements),
.statements = int_cmpop_4_statements,
.init_globals = (pr_int_t *) int_cmpop_init,
.expect_globals = (pr_int_t *) int_cmpop_expect,
},
};
#include "main.c"

View file

@ -0,0 +1,77 @@
#include "head.c"
#define DB 0xdeadbeef
static pr_int_t test_globals_init[] = {
DB, 1, 2, 3, DB,
};
static pr_int_t test_globals_expect[] = {
DB, 1, 2, 3, 1,
};
static dstatement_t jump_A_statements[] = {
{ OP(0, 0, 0, OP_JUMP_A), 4, 0, 0 },
{ OP(0, 0, 0, OP_LEA_A), 1, 0, 0 },
{ OP(0, 0, 0, OP_LEA_A), 1, 0, 4 },
{ OP(0, 0, 0, OP_JUMP_A), 2, 0, 0 },
{ OP(0, 0, 0, OP_JUMP_A), -2, 0, 0 },
};
static dstatement_t jump_B_statements[] = {
{ OP(0, 0, 0, OP_JUMP_B), 1, 2, 0 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_LEA_A), 1, 0, 0 },
{ OP(0, 0, 0, OP_LEA_A), 1, 0, 4 },
};
static dstatement_t jump_C_statements[] = {
{ OP(0, 0, 0, OP_JUMP_C), 1, 2, 0 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_LEA_A), 1, 0, 0 },
{ OP(0, 0, 0, OP_LEA_A), 1, 0, 4 },
};
static dstatement_t jump_D_statements[] = {
{ OP(0, 0, 0, OP_JUMP_D), 1, 2, 0 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_LEA_A), 1, 0, 0 },
{ OP(0, 0, 0, OP_LEA_A), 1, 0, 4 },
};
test_t tests[] = {
{
.desc = "jump A",
.num_globals = num_globals (test_globals_init, test_globals_expect),
.num_statements = num_statements (jump_A_statements),
.statements = jump_A_statements,
.init_globals = test_globals_init,
.expect_globals = test_globals_expect,
},
{
.desc = "jump B",
.num_globals = num_globals (test_globals_init, test_globals_expect),
.num_statements = num_statements (jump_B_statements),
.statements = jump_B_statements,
.init_globals = test_globals_init,
.expect_globals = test_globals_expect,
},
{
.desc = "jump C",
.num_globals = num_globals (test_globals_init, test_globals_expect),
.num_statements = num_statements (jump_C_statements),
.statements = jump_C_statements,
.init_globals = test_globals_init,
.expect_globals = test_globals_expect,
},
{
.desc = "jump D",
.num_globals = num_globals (test_globals_init, test_globals_expect),
.num_statements = num_statements (jump_D_statements),
.statements = jump_D_statements,
.init_globals = test_globals_init,
.expect_globals = test_globals_expect,
},
};
#include "main.c"

View file

@ -0,0 +1,40 @@
#include "head.c"
static pr_int_t lea_globals_init[] = {
// pointers
24, 26, 28, 29,
32, -4, -2, 0,
1, 4, 0xdeadbeef, 0xfeedf00d,
0, 0, 0, 0,
};
static pr_int_t lea_globals_expect[] = {
// pointers
24, 26, 28, 29,
32, -4, -2, 0,
1, 4, 0xdeadbeef, 0xfeedf00d,
7, 34, 26, 88,
};
static dstatement_t lea_statements[] = {
{OP(0, 0, 0, OP_LEA_A), 7, 9, 12},
{OP(0, 0, 0, OP_LEA_C), 2, 6, 13},
{OP(0, 0, 0, OP_LEA_D), 2, 6, 14},
{OP(0, 0, 0, OP_LEA_B), 4, 2, 15},
};
test_t tests[] = {
{
.desc = "lea",
.num_globals = num_globals (lea_globals_init, lea_globals_expect),
.num_statements = num_statements (lea_statements),
.statements = lea_statements,
.init_globals = lea_globals_init,
.expect_globals = lea_globals_expect,
.edict_area = 28,
},
};
#include "main.c"

View file

@ -0,0 +1,87 @@
#include "head.c"
static pr_int_t test_globals_init[] = {
// pointers
24, 26, 28, 29,
32, -4, -2, 0,
1, 4, 0xdeadbeef, 0xfeedf00d,
// destination data
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
// source data
11, 12, 9, 10,
8, 5, 6, 7,
1, 2, 3, 4,
};
static pr_int_t test_globals_expect[] = {
// pointers
24, 26, 28, 29,
32, -4, -2, 0,
1, 4, 0xdeadbeef, 0xfeedf00d,
// destination data
1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12,
// source data
11, 12, 9, 10,
8, 5, 6, 7,
1, 2, 3, 4,
};
static dstatement_t load_B_statements[] = {
{OP(0, 0, 0, OP_LOAD_B_4), 7, 9, 12},
{OP(0, 0, 0, OP_LOAD_B_3), 7, 8, 16},
{OP(0, 0, 0, OP_LOAD_B_1), 7, 7, 19},
{OP(0, 0, 0, OP_LOAD_B_2), 7, 6, 20},
{OP(0, 0, 0, OP_LOAD_B_2), 7, 5, 22},
};
static dstatement_t load_C_statements[] = {
{OP(0, 0, 0, OP_LOAD_C_4), 2, 4, 12},
{OP(0, 0, 0, OP_LOAD_C_3), 2, 1, 16},
{OP(0, 0, 0, OP_LOAD_C_1), 2, 0, 19},
{OP(0, 0, 0, OP_LOAD_C_2), 2, -2, 20},
{OP(0, 0, 0, OP_LOAD_C_2), 2, -4, 22},
};
static dstatement_t load_D_statements[] = {
{OP(0, 0, 0, OP_LOAD_D_4), 2, 9, 12},
{OP(0, 0, 0, OP_LOAD_D_3), 2, 8, 16},
{OP(0, 0, 0, OP_LOAD_D_1), 2, 7, 19},
{OP(0, 0, 0, OP_LOAD_D_2), 2, 6, 20},
{OP(0, 0, 0, OP_LOAD_D_2), 2, 5, 22},
};
test_t tests[] = {
{
.desc = "load B",
.num_globals = num_globals (test_globals_init, test_globals_expect),
.num_statements = num_statements (load_B_statements),
.statements = load_B_statements,
.init_globals = test_globals_init,
.expect_globals = test_globals_expect,
// FIXME negative field offsets are not official but work because all
// offset calculations are done in 32-bit and thus wrap anyway
.edict_area = 28,
},
{
.desc = "load C",
.num_globals = num_globals (test_globals_init, test_globals_expect),
.num_statements = num_statements (load_C_statements),
.statements = load_C_statements,
.init_globals = test_globals_init,
.expect_globals = test_globals_expect,
},
{
.desc = "load D",
.num_globals = num_globals (test_globals_init, test_globals_expect),
.num_statements = num_statements (load_D_statements),
.statements = load_D_statements,
.init_globals = test_globals_init,
.expect_globals = test_globals_expect,
},
};
#include "main.c"

View file

@ -0,0 +1,89 @@
#include "head.c"
static pr_int_t test_globals_init[] = {
// pointers
24, 26, 48, 29,
32, -8, -4, 0,
2, 8, 0xdeadbeef, 0xfeedf00d,
0xdeadbeef, 0xfeedf00d, 0xdeadbeef, 0xfeedf00d,
// destination data
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
// source data
21, 22, 23, 24, 17, 18, 19, 20,
15, 16, 9, 10, 11, 12, 13, 14,
1, 2, 3, 4, 5, 6, 7, 8,
};
static pr_int_t test_globals_expect[] = {
// pointers
24, 26, 48, 29,
32, -8, -4, 0,
2, 8, 0xdeadbeef, 0xfeedf00d,
0xdeadbeef, 0xfeedf00d, 0xdeadbeef, 0xfeedf00d,
// destination data
/*16*/ 1, 2, 3, 4, 5, 6, 7, 8,
/*24*/ 9, 10, 11, 12, 13, 14, 15, 16,
/*32*/ 17, 18, 19, 20, 21, 22, 23, 24,
// source data
/*40*/ 21, 22, 23, 24, 17, 18, 19, 20,
/*48*/ 15, 16, 9, 10, 11, 12, 13, 14,
/*56*/ 1, 2, 3, 4, 5, 6, 7, 8,
};
static dstatement_t load64_B_statements[] = {
{OP(0, 0, 0, OP_LOAD64_B_4), 7, 9, 16},
{OP(0, 0, 0, OP_LOAD64_B_3), 7, 8, 24},
{OP(0, 0, 0, OP_LOAD_B_2), 7, 7, 30},
{OP(0, 0, 0, OP_LOAD_B_4), 7, 6, 32},
{OP(0, 0, 0, OP_LOAD_B_4), 7, 5, 36},
};
static dstatement_t load64_C_statements[] = {
{OP(0, 0, 0, OP_LOAD64_C_4), 2, 8, 16},
{OP(0, 0, 0, OP_LOAD64_C_3), 2, 2, 24},
{OP(0, 0, 0, OP_LOAD_C_2), 2, 0, 30},
{OP(0, 0, 0, OP_LOAD_C_4), 2, -4, 32},
{OP(0, 0, 0, OP_LOAD_C_4), 2, -8, 36},
};
static dstatement_t load64_D_statements[] = {
{OP(0, 0, 0, OP_LOAD64_D_4), 2, 9, 16},
{OP(0, 0, 0, OP_LOAD64_D_3), 2, 8, 24},
{OP(0, 0, 0, OP_LOAD_D_2), 2, 7, 30},
{OP(0, 0, 0, OP_LOAD_D_4), 2, 6, 32},
{OP(0, 0, 0, OP_LOAD_D_4), 2, 5, 36},
};
test_t tests[] = {
{
.desc = "load64 B",
.num_globals = num_globals (test_globals_init, test_globals_expect),
.num_statements = num_statements (load64_B_statements),
.statements = load64_B_statements,
.init_globals = test_globals_init,
.expect_globals = test_globals_expect,
// FIXME negative field offsets are not official but work because all
// offset calculations are done in 32-bit and thus wrap anyway
.edict_area = 48,
},
{
.desc = "load64 C",
.num_globals = num_globals (test_globals_init, test_globals_expect),
.num_statements = num_statements (load64_C_statements),
.statements = load64_C_statements,
.init_globals = test_globals_init,
.expect_globals = test_globals_expect,
},
{
.desc = "load64 D",
.num_globals = num_globals (test_globals_init, test_globals_expect),
.num_statements = num_statements (load64_D_statements),
.statements = load64_D_statements,
.init_globals = test_globals_init,
.expect_globals = test_globals_expect,
},
};
#include "main.c"

View file

@ -0,0 +1,286 @@
#include "head.c"
#include "QF/mathlib.h"
#define sq(x) ((x)*(x))
static pr_lvec4_t long_binop_init[] = {
{ 5, -5, 5, -5},
{ 3, 3, -3, -3},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
};
static pr_lvec4_t long_binop_expect[] = {
{ 5, -5, 5, -5},
{ 3, 3, -3, -3},
{ 15, -15, -15, 15},
{ 5.0/3, -5.0/3, -5.0/3, 5.0/3},
{ 2, -2, 2, -2},
{ 2, 1, -1, -2},
{ 8, -2, 2, -8},
{ 2, -8, 8, -2},
};
static dstatement_t long_binop_1_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 8, 0, 64 }, // init index
//loop:
{ OP(0, 0, 0, OP_LEA_C), 64, -2, 64 }, // dec index
{ OP(0, 0, 0, OP_IFAE), 2, 0, 64 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 64, 1 },
{ OP(1, 1, 1, OP_MUL_L_1), 0, 8, 16 },
{ OP(1, 1, 1, OP_DIV_L_1), 0, 8, 24 },
{ OP(1, 1, 1, OP_REM_L_1), 0, 8, 32 },
{ OP(1, 1, 1, OP_MOD_L_1), 0, 8, 40 },
{ OP(1, 1, 1, OP_ADD_L_1), 0, 8, 48 },
{ OP(1, 1, 1, OP_SUB_L_1), 0, 8, 56 },
{ OP(1, 1, 1, OP_JUMP_A), -10, 0, 0 },
};
static dstatement_t long_binop_2_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 8, 0, 64 }, // init index
//loop:
{ OP(0, 0, 0, OP_LEA_C), 64, -4, 64 }, // dec index
{ OP(0, 0, 0, OP_IFAE), 2, 0, 64 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 64, 1 },
{ OP(1, 1, 1, OP_MUL_L_2), 0, 8, 16 },
{ OP(1, 1, 1, OP_DIV_L_2), 0, 8, 24 },
{ OP(1, 1, 1, OP_REM_L_2), 0, 8, 32 },
{ OP(1, 1, 1, OP_MOD_L_2), 0, 8, 40 },
{ OP(1, 1, 1, OP_ADD_L_2), 0, 8, 48 },
{ OP(1, 1, 1, OP_SUB_L_2), 0, 8, 56 },
{ OP(1, 1, 1, OP_JUMP_A), -10, 0, 0 },
};
static dstatement_t long_binop_3a_statements[] = {
{ OP(1, 1, 1, OP_MUL_L_3), 0, 8, 16 },
{ OP(1, 1, 1, OP_MUL_L_1), 6, 14, 22 },
{ OP(1, 1, 1, OP_DIV_L_3), 0, 8, 24 },
{ OP(1, 1, 1, OP_DIV_L_1), 6, 14, 30 },
{ OP(1, 1, 1, OP_REM_L_3), 0, 8, 32 },
{ OP(1, 1, 1, OP_REM_L_1), 6, 14, 38 },
{ OP(1, 1, 1, OP_MOD_L_3), 0, 8, 40 },
{ OP(1, 1, 1, OP_MOD_L_1), 6, 14, 46 },
{ OP(1, 1, 1, OP_ADD_L_3), 0, 8, 48 },
{ OP(1, 1, 1, OP_ADD_L_1), 6, 14, 54 },
{ OP(1, 1, 1, OP_SUB_L_3), 0, 8, 56 },
{ OP(1, 1, 1, OP_SUB_L_1), 6, 14, 62 },
};
static dstatement_t long_binop_3b_statements[] = {
{ OP(1, 1, 1, OP_MUL_L_1), 0, 8, 16 },
{ OP(1, 1, 1, OP_MUL_L_3), 2, 10, 18 },
{ OP(1, 1, 1, OP_DIV_L_1), 0, 8, 24 },
{ OP(1, 1, 1, OP_DIV_L_3), 2, 10, 26 },
{ OP(1, 1, 1, OP_REM_L_1), 0, 8, 32 },
{ OP(1, 1, 1, OP_REM_L_3), 2, 10, 34 },
{ OP(1, 1, 1, OP_MOD_L_1), 0, 8, 40 },
{ OP(1, 1, 1, OP_MOD_L_3), 2, 10, 42 },
{ OP(1, 1, 1, OP_ADD_L_1), 0, 8, 48 },
{ OP(1, 1, 1, OP_ADD_L_3), 2, 10, 50 },
{ OP(1, 1, 1, OP_SUB_L_1), 0, 8, 56 },
{ OP(1, 1, 1, OP_SUB_L_3), 2, 10, 58 },
};
static dstatement_t long_binop_4_statements[] = {
{ OP(1, 1, 1, OP_MUL_L_4), 0, 8, 16 },
{ OP(1, 1, 1, OP_DIV_L_4), 0, 8, 24 },
{ OP(1, 1, 1, OP_REM_L_4), 0, 8, 32 },
{ OP(1, 1, 1, OP_MOD_L_4), 0, 8, 40 },
{ OP(1, 1, 1, OP_ADD_L_4), 0, 8, 48 },
{ OP(1, 1, 1, OP_SUB_L_4), 0, 8, 56 },
};
static pr_lvec4_t long_cmpop_init[] = {
{ 5, -5, 5, -5},
{ 5, 5, -5, -5},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
};
static pr_lvec4_t long_cmpop_expect[] = {
{ 5, -5, 5, -5},
{ 5, 5, -5, -5},
{ -1, 0, 0, -1},
{ 0, -1, 0, 0},
{ 0, 0, -1, 0},
{ 0, -1, -1, 0},
{ -1, 0, -1, -1},
{ -1, -1, 0, -1},
};
static dstatement_t long_cmpop_1_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 8, 0, 64 }, // init index
//loop:
{ OP(0, 0, 0, OP_LEA_C), 64, -2, 64 }, // dec index
{ OP(0, 0, 0, OP_IFAE), 2, 0, 64 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 64, 1 },
{ OP(1, 1, 1, OP_EQ_L_1), 0, 8, 16 },
{ OP(1, 1, 1, OP_LT_L_1), 0, 8, 24 },
{ OP(1, 1, 1, OP_GT_L_1), 0, 8, 32 },
{ OP(1, 1, 1, OP_NE_L_1), 0, 8, 40 },
{ OP(1, 1, 1, OP_GE_L_1), 0, 8, 48 },
{ OP(1, 1, 1, OP_LE_L_1), 0, 8, 56 },
{ OP(1, 1, 1, OP_JUMP_A), -10, 0, 0 },
};
static dstatement_t long_cmpop_2_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 8, 0, 64 }, // init index
//loop:
{ OP(0, 0, 0, OP_LEA_C), 64, -4, 64 }, // dec index
{ OP(0, 0, 0, OP_IFAE), 2, 0, 64 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 64, 1 },
{ OP(1, 1, 1, OP_EQ_L_2), 0, 8, 16 },
{ OP(1, 1, 1, OP_LT_L_2), 0, 8, 24 },
{ OP(1, 1, 1, OP_GT_L_2), 0, 8, 32 },
{ OP(1, 1, 1, OP_NE_L_2), 0, 8, 40 },
{ OP(1, 1, 1, OP_GE_L_2), 0, 8, 48 },
{ OP(1, 1, 1, OP_LE_L_2), 0, 8, 56 },
{ OP(1, 1, 1, OP_JUMP_A), -10, 0, 0 },
};
static dstatement_t long_cmpop_3a_statements[] = {
{ OP(1, 1, 1, OP_EQ_L_3), 0, 8, 16 },
{ OP(1, 1, 1, OP_EQ_L_1), 6, 14, 22 },
{ OP(1, 1, 1, OP_LT_L_3), 0, 8, 24 },
{ OP(1, 1, 1, OP_LT_L_1), 6, 14, 30 },
{ OP(1, 1, 1, OP_GT_L_3), 0, 8, 32 },
{ OP(1, 1, 1, OP_GT_L_1), 6, 14, 38 },
{ OP(1, 1, 1, OP_NE_L_3), 0, 8, 40 },
{ OP(1, 1, 1, OP_NE_L_1), 6, 14, 46 },
{ OP(1, 1, 1, OP_GE_L_3), 0, 8, 48 },
{ OP(1, 1, 1, OP_GE_L_1), 6, 14, 54 },
{ OP(1, 1, 1, OP_LE_L_3), 0, 8, 56 },
{ OP(1, 1, 1, OP_LE_L_1), 6, 14, 62 },
};
static dstatement_t long_cmpop_3b_statements[] = {
{ OP(1, 1, 1, OP_EQ_L_1), 0, 8, 16 },
{ OP(1, 1, 1, OP_EQ_L_3), 2, 10, 18 },
{ OP(1, 1, 1, OP_LT_L_1), 0, 8, 24 },
{ OP(1, 1, 1, OP_LT_L_3), 2, 10, 26 },
{ OP(1, 1, 1, OP_GT_L_1), 0, 8, 32 },
{ OP(1, 1, 1, OP_GT_L_3), 2, 10, 34 },
{ OP(1, 1, 1, OP_NE_L_1), 0, 8, 40 },
{ OP(1, 1, 1, OP_NE_L_3), 2, 10, 42 },
{ OP(1, 1, 1, OP_GE_L_1), 0, 8, 48 },
{ OP(1, 1, 1, OP_GE_L_3), 2, 10, 50 },
{ OP(1, 1, 1, OP_LE_L_1), 0, 8, 56 },
{ OP(1, 1, 1, OP_LE_L_3), 2, 10, 58 },
};
static dstatement_t long_cmpop_4_statements[] = {
{ OP(1, 1, 1, OP_EQ_L_4), 0, 8, 16 },
{ OP(1, 1, 1, OP_LT_L_4), 0, 8, 24 },
{ OP(1, 1, 1, OP_GT_L_4), 0, 8, 32 },
{ OP(1, 1, 1, OP_NE_L_4), 0, 8, 40 },
{ OP(1, 1, 1, OP_GE_L_4), 0, 8, 48 },
{ OP(1, 1, 1, OP_LE_L_4), 0, 8, 56 },
};
test_t tests[] = {
{
.desc = "long binop 1",
.extra_globals = 8 * 1,
.num_globals = num_globals(long_binop_init,long_binop_expect),
.num_statements = num_statements (long_binop_1_statements),
.statements = long_binop_1_statements,
.init_globals = (pr_int_t *) long_binop_init,
.expect_globals = (pr_int_t *) long_binop_expect,
},
{
.desc = "long binop 2",
.extra_globals = 8 * 1,
.num_globals = num_globals(long_binop_init,long_binop_expect),
.num_statements = num_statements (long_binop_2_statements),
.statements = long_binop_2_statements,
.init_globals = (pr_int_t *) long_binop_init,
.expect_globals = (pr_int_t *) long_binop_expect,
},
{
.desc = "long binop 3a",
.extra_globals = 8 * 1,
.num_globals = num_globals(long_binop_init,long_binop_expect),
.num_statements = num_statements (long_binop_3a_statements),
.statements = long_binop_3a_statements,
.init_globals = (pr_int_t *) long_binop_init,
.expect_globals = (pr_int_t *) long_binop_expect,
},
{
.desc = "long binop 3b",
.extra_globals = 8 * 1,
.num_globals = num_globals(long_binop_init,long_binop_expect),
.num_statements = num_statements (long_binop_3b_statements),
.statements = long_binop_3b_statements,
.init_globals = (pr_int_t *) long_binop_init,
.expect_globals = (pr_int_t *) long_binop_expect,
},
{
.desc = "long binop 4",
.extra_globals = 8 * 1,
.num_globals = num_globals(long_binop_init,long_binop_expect),
.num_statements = num_statements (long_binop_4_statements),
.statements = long_binop_4_statements,
.init_globals = (pr_int_t *) long_binop_init,
.expect_globals = (pr_int_t *) long_binop_expect,
},
{
.desc = "long cmpop 1",
.extra_globals = 4 * 1,
.num_globals = num_globals(long_cmpop_init,long_cmpop_expect),
.num_statements = num_statements (long_cmpop_1_statements),
.statements = long_cmpop_1_statements,
.init_globals = (pr_int_t *) long_cmpop_init,
.expect_globals = (pr_int_t *) long_cmpop_expect,
},
{
.desc = "long cmpop 2",
.extra_globals = 4 * 1,
.num_globals = num_globals(long_cmpop_init,long_cmpop_expect),
.num_statements = num_statements (long_cmpop_2_statements),
.statements = long_cmpop_2_statements,
.init_globals = (pr_int_t *) long_cmpop_init,
.expect_globals = (pr_int_t *) long_cmpop_expect,
},
{
.desc = "long cmpop 3a",
.extra_globals = 4 * 1,
.num_globals = num_globals(long_cmpop_init,long_cmpop_expect),
.num_statements = num_statements (long_cmpop_3a_statements),
.statements = long_cmpop_3a_statements,
.init_globals = (pr_int_t *) long_cmpop_init,
.expect_globals = (pr_int_t *) long_cmpop_expect,
},
{
.desc = "long cmpop 3b",
.extra_globals = 4 * 1,
.num_globals = num_globals(long_cmpop_init,long_cmpop_expect),
.num_statements = num_statements (long_cmpop_3b_statements),
.statements = long_cmpop_3b_statements,
.init_globals = (pr_int_t *) long_cmpop_init,
.expect_globals = (pr_int_t *) long_cmpop_expect,
},
{
.desc = "long cmpop 4",
.extra_globals = 4 * 1,
.num_globals = num_globals(long_cmpop_init,long_cmpop_expect),
.num_statements = num_statements (long_cmpop_4_statements),
.statements = long_cmpop_4_statements,
.init_globals = (pr_int_t *) long_cmpop_init,
.expect_globals = (pr_int_t *) long_cmpop_expect,
},
};
#include "main.c"

View file

@ -0,0 +1,51 @@
#include "head.c"
#define DB 0xdeadbeef
static pr_int_t mem_globals_init[] = {
0, 8, 68, 9, 80, 112, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8,
0, 0, 68, 6, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16
DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB,
DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB,
DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB,
DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB,
DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB,
DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB,
};
static pr_int_t mem_globals_expect[] = {
0, 8, 68, 9, 80, 112, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, // 0
0, 0, 68, 6, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16
DB, 0, 0, 0, 0, 0, DB, DB, 9, 9, DB, DB, DB, DB, DB, DB, // 32
1, 2, 3, 4, 5, 6, 7, 8, DB, DB, DB, DB, 5, 6, 7, 8, // 48
DB, DB, DB, DB, 1, 2, 1, 2, 3, 4, 5, 6, DB, DB, DB, DB, // 64
68, 68, 68, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, // 80
DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, // 96
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, DB, // 112
};
static dstatement_t mem_statements[] = {
{OP(0, 0, 0, OP_MEMSET_I), 0, 5, 33},
{OP(0, 0, 0, OP_MEMSET_I), 3, 2, 40},
{OP(0, 0, 0, OP_MOVE_I), 8, 8, 48},
{OP(0, 0, 0, OP_MOVE_I), 12, 4, 60},
{OP(0, 0, 0, OP_MOVE_PI), 1, 8, 2},
{OP(0, 0, 0, OP_MEMSET_P), 2, 10, 4},
{OP(0, 0, 0, OP_MEMSET_PI), 1, 15, 5},
{OP(0, 0, 0, OP_MOVE_P), 18, 19, 20},
};
test_t tests[] = {
{
.desc = "mem",
.num_globals = num_globals (mem_globals_init, mem_globals_expect),
.num_statements = num_statements (mem_statements),
.statements = mem_statements,
.init_globals = mem_globals_init,
.expect_globals = mem_globals_expect,
},
};
#include "main.c"

View file

@ -0,0 +1,68 @@
#include "head.c"
#include "QF/mathlib.h"
static pr_vec4_t float_scale_init[] = {
{ 5, 0, 0, 0},
{ 3, 4, 13, 85},
{ 0, 0, -1, -2},
{ 0, 0, 0, -3},
{ 0, 0, 0, 0},
};
static pr_vec4_t float_scale_expect[] = {
{ 5, 0, 0, 0},
{ 3, 4, 13, 85},
{ 15, 20, -1, -2},
{ 15, 20, 65, -3},
{ 15, 20, 65, 425},
};
static dstatement_t float_scale_statements[] = {
{ OP(1, 1, 1, OP_SCALE_F_2), 4, 0, 8 },
{ OP(1, 1, 1, OP_SCALE_F_3), 4, 0, 12 },
{ OP(1, 1, 1, OP_SCALE_F_4), 4, 0, 16 },
};
static pr_dvec4_t double_scale_init[] = {
{ 5, 0, 0, 0},
{ 3, 4, 13, 85},
{ 0, 0, -1, -2},
{ 0, 0, 0, -3},
{ 0, 0, 0, 0},
};
static pr_dvec4_t double_scale_expect[] = {
{ 5, 0, 0, 0},
{ 3, 4, 13, 85},
{ 15, 20, -1, -2},
{ 15, 20, 65, -3},
{ 15, 20, 65, 425},
};
static dstatement_t double_scale_statements[] = {
{ OP(1, 1, 1, OP_SCALE_D_2), 8, 0, 16 },
{ OP(1, 1, 1, OP_SCALE_D_3), 8, 0, 24 },
{ OP(1, 1, 1, OP_SCALE_D_4), 8, 0, 32 },
};
test_t tests[] = {
{
.desc = "float scale",
.num_globals = num_globals(float_scale_init,float_scale_expect),
.num_statements = num_statements (float_scale_statements),
.statements = float_scale_statements,
.init_globals = (pr_int_t *) float_scale_init,
.expect_globals = (pr_int_t *) float_scale_expect,
},
{
.desc = "double scale",
.num_globals = num_globals(double_scale_init,double_scale_expect),
.num_statements = num_statements (double_scale_statements),
.statements = double_scale_statements,
.init_globals = (pr_int_t *) double_scale_init,
.expect_globals = (pr_int_t *) double_scale_expect,
},
};
#include "main.c"

View file

@ -0,0 +1,233 @@
#include "head.c"
static pr_int_t test_globals_init1[] = {
// pointers
24, 26, 28, 29,
32, -4, -2, 0,
1, 4, 0xdeadbeef, 0xfeedf00d,
// source data
1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12,
// destination data
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
};
static pr_int_t test_globals_expect1[] = {
// pointers
24, 26, 28, 29,
32, -4, -2, 0,
1, 4, 0xdeadbeef, 0xfeedf00d,
// source data
1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12,
// destination data
11, 12, 9, 10,
8, 5, 6, 7,
1, 2, 3, 4,
};
static pr_int_t test_globals_init2[] = {
// pointers
24, 26, 28, 29,
32, -4, -2, 0,
1, 4, 0xdeadbeef, 0xfeedf00d,
// destination data
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
// source data
11, 12, 9, 10,
8, 5, 6, 7,
1, 2, 3, 4,
};
static pr_int_t test_globals_expect2[] = {
// pointers
24, 26, 28, 29,
32, -4, -2, 0,
1, 4, 0xdeadbeef, 0xfeedf00d,
// destination data
1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12,
// source data
11, 12, 9, 10,
8, 5, 6, 7,
1, 2, 3, 4,
};
static dstatement_t stack_AA_statements[] = {
{OP(0, 0, 0, OP_PUSH_A_4), 12, 0, 0},
{OP(0, 0, 0, OP_PUSH_A_3), 16, 0, 0},
{OP(0, 0, 0, OP_PUSH_A_1), 19, 0, 0},
{OP(0, 0, 0, OP_PUSH_A_2), 20, 0, 0},
{OP(0, 0, 0, OP_PUSH_A_2), 22, 0, 0},
{OP(0, 0, 0, OP_POP_A_2), 24, 0, 0},
{OP(0, 0, 0, OP_POP_A_2), 26, 0, 0},
{OP(0, 0, 0, OP_POP_A_1), 28, 0, 0},
{OP(0, 0, 0, OP_POP_A_3), 29, 0, 0},
{OP(0, 0, 0, OP_POP_A_4), 32, 0, 0},
};
static dstatement_t stack_AB_statements[] = {
{OP(0, 0, 0, OP_PUSH_A_4), 12, 0, 0},
{OP(0, 0, 0, OP_PUSH_A_3), 16, 0, 0},
{OP(0, 0, 0, OP_PUSH_A_1), 19, 0, 0},
{OP(0, 0, 0, OP_PUSH_A_2), 20, 0, 0},
{OP(0, 0, 0, OP_PUSH_A_2), 22, 0, 0},
{OP(0, 0, 0, OP_POP_B_2), 7, 5, 0},
{OP(0, 0, 0, OP_POP_B_2), 7, 6, 0},
{OP(0, 0, 0, OP_POP_B_1), 7, 7, 0},
{OP(0, 0, 0, OP_POP_B_3), 7, 8, 0},
{OP(0, 0, 0, OP_POP_B_4), 7, 9, 0},
};
static dstatement_t stack_AC_statements[] = {
{OP(0, 0, 0, OP_PUSH_A_4), 12, 0, 0},
{OP(0, 0, 0, OP_PUSH_A_3), 16, 0, 0},
{OP(0, 0, 0, OP_PUSH_A_1), 19, 0, 0},
{OP(0, 0, 0, OP_PUSH_A_2), 20, 0, 0},
{OP(0, 0, 0, OP_PUSH_A_2), 22, 0, 0},
{OP(0, 0, 0, OP_POP_C_2), 2, -4, 0},
{OP(0, 0, 0, OP_POP_C_2), 2, -2, 0},
{OP(0, 0, 0, OP_POP_C_1), 2, 0, 0},
{OP(0, 0, 0, OP_POP_C_3), 2, 1, 0},
{OP(0, 0, 0, OP_POP_C_4), 2, 4, 0},
};
static dstatement_t stack_AD_statements[] = {
{OP(0, 0, 0, OP_PUSH_A_4), 12, 0, 0},
{OP(0, 0, 0, OP_PUSH_A_3), 16, 0, 0},
{OP(0, 0, 0, OP_PUSH_A_1), 19, 0, 0},
{OP(0, 0, 0, OP_PUSH_A_2), 20, 0, 0},
{OP(0, 0, 0, OP_PUSH_A_2), 22, 0, 0},
{OP(0, 0, 0, OP_POP_D_2), 2, 5, 0},
{OP(0, 0, 0, OP_POP_D_2), 2, 6, 0},
{OP(0, 0, 0, OP_POP_D_1), 2, 7, 0},
{OP(0, 0, 0, OP_POP_D_3), 2, 8, 0},
{OP(0, 0, 0, OP_POP_D_4), 2, 9, 0},
};
static dstatement_t stack_BA_statements[] = {
{OP(0, 0, 0, OP_PUSH_B_2), 7, 5, 0},
{OP(0, 0, 0, OP_PUSH_B_2), 7, 6, 0},
{OP(0, 0, 0, OP_PUSH_B_1), 7, 7, 0},
{OP(0, 0, 0, OP_PUSH_B_3), 7, 8, 0},
{OP(0, 0, 0, OP_PUSH_B_4), 7, 9, 0},
{OP(0, 0, 0, OP_POP_A_4), 12, 0, 0},
{OP(0, 0, 0, OP_POP_A_3), 16, 0, 0},
{OP(0, 0, 0, OP_POP_A_1), 19, 0, 0},
{OP(0, 0, 0, OP_POP_A_2), 20, 0, 0},
{OP(0, 0, 0, OP_POP_A_2), 22, 0, 0},
};
static dstatement_t stack_CA_statements[] = {
{OP(0, 0, 0, OP_PUSH_C_2), 2, -4, 0},
{OP(0, 0, 0, OP_PUSH_C_2), 2, -2, 0},
{OP(0, 0, 0, OP_PUSH_C_1), 2, 0, 0},
{OP(0, 0, 0, OP_PUSH_C_3), 2, 1, 0},
{OP(0, 0, 0, OP_PUSH_C_4), 2, 4, 0},
{OP(0, 0, 0, OP_POP_A_4), 12, 0, 0},
{OP(0, 0, 0, OP_POP_A_3), 16, 0, 0},
{OP(0, 0, 0, OP_POP_A_1), 19, 0, 0},
{OP(0, 0, 0, OP_POP_A_2), 20, 0, 0},
{OP(0, 0, 0, OP_POP_A_2), 22, 0, 0},
};
static dstatement_t stack_DA_statements[] = {
{OP(0, 0, 0, OP_PUSH_D_2), 2, 5, 0},
{OP(0, 0, 0, OP_PUSH_D_2), 2, 6, 0},
{OP(0, 0, 0, OP_PUSH_D_1), 2, 7, 0},
{OP(0, 0, 0, OP_PUSH_D_3), 2, 8, 0},
{OP(0, 0, 0, OP_PUSH_D_4), 2, 9, 0},
{OP(0, 0, 0, OP_POP_A_4), 12, 0, 0},
{OP(0, 0, 0, OP_POP_A_3), 16, 0, 0},
{OP(0, 0, 0, OP_POP_A_1), 19, 0, 0},
{OP(0, 0, 0, OP_POP_A_2), 20, 0, 0},
{OP(0, 0, 0, OP_POP_A_2), 22, 0, 0},
};
test_t tests[] = {
{
.desc = "stack push A pop A",
.stack_size = 32,
.num_globals = num_globals (test_globals_init1, test_globals_expect1),
.num_statements = num_statements (stack_AA_statements),
.statements = stack_AA_statements,
.init_globals = test_globals_init1,
.expect_globals = test_globals_expect1,
},
{
.desc = "stack push A pop B",
.stack_size = 32,
.num_globals = num_globals (test_globals_init1, test_globals_expect1),
.num_statements = num_statements (stack_AB_statements),
.statements = stack_AB_statements,
.init_globals = test_globals_init1,
.expect_globals = test_globals_expect1,
// FIXME negative field offsets are not official but work because all
// offset calculations are done in 32-bit and thus wrap anyway
.edict_area = 28,
},
{
.desc = "stack push A pop C",
.stack_size = 32,
.num_globals = num_globals (test_globals_init1, test_globals_expect1),
.num_statements = num_statements (stack_AC_statements),
.statements = stack_AC_statements,
.init_globals = test_globals_init1,
.expect_globals = test_globals_expect1,
},
{
.desc = "stack push A pop D",
.stack_size = 32,
.num_globals = num_globals (test_globals_init1, test_globals_expect1),
.num_statements = num_statements (stack_AD_statements),
.statements = stack_AD_statements,
.init_globals = test_globals_init1,
.expect_globals = test_globals_expect1,
},
{
.desc = "stack push B pop A",
.stack_size = 32,
.num_globals = num_globals (test_globals_init2, test_globals_expect2),
.num_statements = num_statements (stack_BA_statements),
.statements = stack_BA_statements,
.init_globals = test_globals_init2,
.expect_globals = test_globals_expect2,
// FIXME negative field offsets are not official but work because all
// offset calculations are done in 32-bit and thus wrap anyway
.edict_area = 28,
},
{
.desc = "stack push C pop A",
.stack_size = 32,
.num_globals = num_globals (test_globals_init2, test_globals_expect2),
.num_statements = num_statements (stack_CA_statements),
.statements = stack_CA_statements,
.init_globals = test_globals_init2,
.expect_globals = test_globals_expect2,
},
{
.desc = "stack push D pop A",
.stack_size = 32,
.num_globals = num_globals (test_globals_init2, test_globals_expect2),
.num_statements = num_statements (stack_DA_statements),
.statements = stack_DA_statements,
.init_globals = test_globals_init2,
.expect_globals = test_globals_expect2,
},
};
#include "main.c"

View file

@ -0,0 +1,99 @@
#include "head.c"
#include "QF/mathlib.h"
#define DB 0xdeadbeef
static float float_time = 1;
static pr_ivec4_t float_state_init[] = {
{ 0, 0, DB, DB },
{ 10, 11, 20, 21 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
};
#define f1 0x3f800000
#define f11 0x3f8ccccd
#define f2 0x40000000
static pr_ivec4_t float_state_expect[] = {
{ 0, 8, f1, DB },
{ 10, 11, 20, 21 },
{ 0, 0, 0, 0 },
{ 10, 20, f11, 0 },
{ 11, 21, f2, 0 },
};
static dstatement_t float_state_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 4, 0, 1 },
{ OP(0, 0, 0, OP_STATE_ft), 4, 6, 0 },
{ OP(0, 0, 0, OP_LEA_A), 8, 0, 1 },
{ OP(0, 0, 0, OP_STATE_ftt), 5, 7, 2 },
};
static double double_time = 1;
static pr_ivec4_t double_state_init[] = {
{ 0, 0, DB, DB },
{ 10, 11, 20, 21 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
};
#define d1l 0x00000000
#define d1h 0x3ff00000
#define d11l 0x9999999a
#define d11h 0x3ff19999
#define d2l 0x00000000
#define d2h 0x40000000
static pr_ivec4_t double_state_expect[] = {
{ 0, 8, d1l, d1h },
{ 10, 11, 20, 21 },
{ 0, 0, 0, 0 },
{ 10, 20, d11l, d11h },
{ 11, 21, d2l, d2h },
};
static dstatement_t double_state_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 4, 0, 1 },
{ OP(0, 0, 0, OP_STATE_dt), 4, 6, 0 },
{ OP(0, 0, 0, OP_LEA_A), 8, 0, 1 },
{ OP(0, 0, 0, OP_STATE_dtt), 5, 7, 2 },
};
test_t tests[] = {
{
.desc = "float state",
.num_globals = num_globals(float_state_init,float_state_expect),
.num_statements = num_statements (float_state_statements),
.statements = float_state_statements,
.init_globals = (pr_int_t *) float_state_init,
.expect_globals = (pr_int_t *) float_state_expect,
.self = 1,
.ftime = 2,
.float_time = &float_time,
.edict_area = 8,
.frame = 0,
.think = 1,
.nextthink = 2,
},
{
.desc = "double state",
.num_globals = num_globals(double_state_init,double_state_expect),
.num_statements = num_statements (double_state_statements),
.statements = double_state_statements,
.init_globals = (pr_int_t *) double_state_init,
.expect_globals = (pr_int_t *) double_state_expect,
.self = 1,
.dtime = 2,
.double_time = &double_time,
.edict_area = 8,
.frame = 0,
.think = 1,
.nextthink = 2,
},
};
#include "main.c"

View file

@ -0,0 +1,103 @@
#include "head.c"
static pr_int_t test_globals_init[] = {
// pointers
24, 26, 28, 29,
32, -4, -2, 0,
1, 4, 0xdeadbeef, 0xfeedf00d,
// source data
1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12,
// destination data
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
};
static pr_int_t test_globals_expect[] = {
// pointers
24, 26, 28, 29,
32, -4, -2, 0,
1, 4, 0xdeadbeef, 0xfeedf00d,
// source data
1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12,
// destination data
11, 12, 9, 10,
8, 5, 6, 7,
1, 2, 3, 4,
};
static dstatement_t store_A_statements[] = {
{OP(0, 0, 0, OP_STORE_A_4), 32, 0, 12},
{OP(0, 0, 0, OP_STORE_A_3), 29, 0, 16},
{OP(0, 0, 0, OP_STORE_A_1), 28, 0, 19},
{OP(0, 0, 0, OP_STORE_A_2), 26, 0, 20},
{OP(0, 0, 0, OP_STORE_A_2), 24, 0, 22},
};
static dstatement_t store_B_statements[] = {
{OP(0, 0, 0, OP_STORE_B_4), 7, 9, 12},
{OP(0, 0, 0, OP_STORE_B_3), 7, 8, 16},
{OP(0, 0, 0, OP_STORE_B_1), 7, 7, 19},
{OP(0, 0, 0, OP_STORE_B_2), 7, 6, 20},
{OP(0, 0, 0, OP_STORE_B_2), 7, 5, 22},
};
static dstatement_t store_C_statements[] = {
{OP(0, 0, 0, OP_STORE_C_4), 2, 4, 12},
{OP(0, 0, 0, OP_STORE_C_3), 2, 1, 16},
{OP(0, 0, 0, OP_STORE_C_1), 2, 0, 19},
{OP(0, 0, 0, OP_STORE_C_2), 2, -2, 20},
{OP(0, 0, 0, OP_STORE_C_2), 2, -4, 22},
};
static dstatement_t store_D_statements[] = {
{OP(0, 0, 0, OP_STORE_D_4), 2, 9, 12},
{OP(0, 0, 0, OP_STORE_D_3), 2, 8, 16},
{OP(0, 0, 0, OP_STORE_D_1), 2, 7, 19},
{OP(0, 0, 0, OP_STORE_D_2), 2, 6, 20},
{OP(0, 0, 0, OP_STORE_D_2), 2, 5, 22},
};
test_t tests[] = {
{
.desc = "store A",
.num_globals = num_globals (test_globals_init, test_globals_expect),
.num_statements = num_statements (store_A_statements),
.statements = store_A_statements,
.init_globals = test_globals_init,
.expect_globals = test_globals_expect,
},
{
.desc = "store B",
.num_globals = num_globals (test_globals_init, test_globals_expect),
.num_statements = num_statements (store_B_statements),
.statements = store_B_statements,
.init_globals = test_globals_init,
.expect_globals = test_globals_expect,
// FIXME negative field offsets are not official but work because all
// offset calculations are done in 32-bit and thus wrap anyway
.edict_area = 28,
},
{
.desc = "store C",
.num_globals = num_globals (test_globals_init, test_globals_expect),
.num_statements = num_statements (store_C_statements),
.statements = store_C_statements,
.init_globals = test_globals_init,
.expect_globals = test_globals_expect,
},
{
.desc = "store D",
.num_globals = num_globals (test_globals_init, test_globals_expect),
.num_statements = num_statements (store_D_statements),
.statements = store_D_statements,
.init_globals = test_globals_init,
.expect_globals = test_globals_expect,
},
};
#include "main.c"

View file

@ -0,0 +1,105 @@
#include "head.c"
static pr_int_t test_globals_init[] = {
// pointers
24, 26, 48, 29,
32, -8, -4, 0,
2, 8, 0xdeadbeef, 0xfeedf00d,
0xdeadbeef, 0xfeedf00d, 0xdeadbeef, 0xfeedf00d,
// source data
/*16*/ 1, 2, 3, 4, 5, 6, 7, 8,
/*24*/ 9, 10, 11, 12, 13, 14, 15, 16,
/*32*/ 17, 18, 19, 20, 21, 22, 23, 24,
// destination data
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
};
static pr_int_t test_globals_expect[] = {
// pointers
24, 26, 48, 29,
32, -8, -4, 0,
2, 8, 0xdeadbeef, 0xfeedf00d,
0xdeadbeef, 0xfeedf00d, 0xdeadbeef, 0xfeedf00d,
// source data
/*16*/ 1, 2, 3, 4, 5, 6, 7, 8,
/*24*/ 9, 10, 11, 12, 13, 14, 15, 16,
/*32*/ 17, 18, 19, 20, 21, 22, 23, 24,
// destination data
/*40*/ 21, 22, 23, 24, 17, 18, 19, 20,
/*48*/ 15, 16, 9, 10, 11, 12, 13, 14,
/*56*/ 1, 2, 3, 4, 5, 6, 7, 8,
};
static dstatement_t store64_A_statements[] = {
{OP(0, 0, 0, OP_STORE64_A_4), 56, 0, 16},
{OP(0, 0, 0, OP_STORE64_A_3), 50, 0, 24},
{OP(0, 0, 0, OP_STORE_A_2), 48, 0, 30},
{OP(0, 0, 0, OP_STORE_A_4), 44, 0, 32},
{OP(0, 0, 0, OP_STORE_A_4), 40, 0, 36},
};
static dstatement_t store64_B_statements[] = {
{OP(0, 0, 0, OP_STORE64_B_4), 7, 9, 16},
{OP(0, 0, 0, OP_STORE64_B_3), 7, 8, 24},
{OP(0, 0, 0, OP_STORE_B_2), 7, 7, 30},
{OP(0, 0, 0, OP_STORE_B_4), 7, 6, 32},
{OP(0, 0, 0, OP_STORE_B_4), 7, 5, 36},
};
static dstatement_t store64_C_statements[] = {
{OP(0, 0, 0, OP_STORE64_C_4), 2, 8, 16},
{OP(0, 0, 0, OP_STORE64_C_3), 2, 2, 24},
{OP(0, 0, 0, OP_STORE_C_2), 2, 0, 30},
{OP(0, 0, 0, OP_STORE_C_4), 2, -4, 32},
{OP(0, 0, 0, OP_STORE_C_4), 2, -8, 36},
};
static dstatement_t store64_D_statements[] = {
{OP(0, 0, 0, OP_STORE64_D_4), 2, 9, 16},
{OP(0, 0, 0, OP_STORE64_D_3), 2, 8, 24},
{OP(0, 0, 0, OP_STORE_D_2), 2, 7, 30},
{OP(0, 0, 0, OP_STORE_D_4), 2, 6, 32},
{OP(0, 0, 0, OP_STORE_D_4), 2, 5, 36},
};
test_t tests[] = {
{
.desc = "store64 A",
.num_globals = num_globals (test_globals_init, test_globals_expect),
.num_statements = num_statements (store64_A_statements),
.statements = store64_A_statements,
.init_globals = test_globals_init,
.expect_globals = test_globals_expect,
},
{
.desc = "store64 B",
.num_globals = num_globals (test_globals_init, test_globals_expect),
.num_statements = num_statements (store64_B_statements),
.statements = store64_B_statements,
.init_globals = test_globals_init,
.expect_globals = test_globals_expect,
// FIXME negative field offsets are not official but work because all
// offset calculations are done in 32-bit and thus wrap anyway
.edict_area = 48,
},
{
.desc = "store64 C",
.num_globals = num_globals (test_globals_init, test_globals_expect),
.num_statements = num_statements (store64_C_statements),
.statements = store64_C_statements,
.init_globals = test_globals_init,
.expect_globals = test_globals_expect,
},
{
.desc = "store64 D",
.num_globals = num_globals (test_globals_init, test_globals_expect),
.num_statements = num_statements (store64_D_statements),
.statements = store64_D_statements,
.init_globals = test_globals_init,
.expect_globals = test_globals_expect,
},
};
#include "main.c"

View file

@ -0,0 +1,84 @@
#include "head.c"
const char test_strings[] =
"\0"
"abc\0"
"def\0"
"abc\0";
static pr_int_t string_globals_init[] = {
0, 1, 5, 9, // string pointers
0, 0, 0, 0,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
};
static pr_int_t string_globals_expect[] = {
0, 1, 5, 9, // string pointers
0, 0, 8, 0,
// "\0" "abc" "def" "abc"
-1, 0, 0, 0, 0, -1, 0, -1, 0, 0, -1, 0, 0, -1, 0, -1, // eq
0, -1, -1, -1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, -1, 0, // lt
0, 0, 0, 0, -1, 0, 0, 0, -1, -1, 0, -1, -1, 0, 0, 0, // gt
0,-97,-100,-97, 97, 0, -3, 0, 100, 3, 0, 3, 97, 0, -3, 0, // cmp
-1, 0, 0, 0, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, 0, -1, // ge
-1, -1, -1, -1, 0, -1, -1, -1, 0, 0, -1, 0, 0, -1, -1, -1, // le
-1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // not
};
static dstatement_t string_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 24, 0, 6 }, // init k
// for (i = 4; i-- > 0; ) {
{ OP(0, 0, 0, OP_LEA_A), 4, 0, 4 },
{ OP(0, 0, 0, OP_IFA), 2, 0, 4 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_LEA_C), 4, -1, 4 }, // dec i
{ OP(0, 0, 0, OP_WITH), 4, 4, 1 }, // load i
// for (j = 4; j-- > 0; ) {
{ OP(0, 0, 0, OP_LEA_A), 4, 0, 5 }, // init j
{ OP(0, 0, 0, OP_IFA), 2, 0, 5 },
{ OP(0, 0, 0, OP_JUMP_A), -6, 0, 0 },
{ OP(0, 0, 0, OP_LEA_C), 5, -1, 5 }, // dec j
{ OP(0, 0, 0, OP_WITH), 4, 5, 2 }, // load j
{ OP(0, 0, 0, OP_LEA_C), 6, -1, 6 }, // dec k
{ OP(0, 0, 0, OP_WITH), 4, 6, 3 }, // load k
// i j k
{ OP(1, 2, 3, OP_EQ_S), 0, 0, 0 },
{ OP(1, 2, 3, OP_LT_S), 0, 0, 16 },
{ OP(1, 2, 3, OP_GT_S), 0, 0, 32 },
{ OP(1, 2, 3, OP_CMP_S), 0, 0, 48 },
{ OP(1, 2, 3, OP_GE_S), 0, 0, 64 },
{ OP(1, 2, 3, OP_LE_S), 0, 0, 80 },
{ OP(1, 2, 3, OP_NOT_S), 0, 0, 96 },
// }
{ OP(0, 0, 0, OP_JUMP_A), -13, 0, 0 },
// }
};
test_t tests[] = {
{
.desc = "string",
.num_globals = num_globals (string_globals_init, string_globals_expect),
.num_statements = num_statements (string_statements),
.statements = string_statements,
.init_globals = string_globals_init,
.expect_globals = string_globals_expect,
.strings = test_strings,
.string_size = sizeof (test_strings),
},
};
#include "main.c"

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,776 @@
#include "head.c"
#include "QF/mathlib.h"
static pr_uivec4_t uint_divop_init[] = {
{ 5, -5, 5, -5},
{ 3, 3, -3, -3},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
};
static pr_uivec4_t uint_divop_expect[] = {
{ 5, -5, 5, -5},
{ 3, 3, -3, -3},
{ 1, 0x55555553, 0, 0},
{ 2, 2, 5, -5},
};
static dstatement_t uint_divop_1_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 4, 0, 32 }, // init index
//loop:
{ OP(0, 0, 0, OP_LEA_C), 32, -1, 32 }, // dec index
{ OP(0, 0, 0, OP_IFAE), 2, 0, 32 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 32, 1 },
{ OP(1, 1, 1, OP_DIV_u_1), 0, 4, 8 },
{ OP(1, 1, 1, OP_REM_u_1), 0, 4, 12 },
{ OP(1, 1, 1, OP_JUMP_A), -6, 0, 0 },
};
static dstatement_t uint_divop_2_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 4, 0, 32 }, // index
//loop:
{ OP(0, 0, 0, OP_LEA_C), 32, -2, 32 }, // dec index
{ OP(0, 0, 0, OP_IFAE), 2, 0, 32 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 32, 1 },
{ OP(1, 1, 1, OP_DIV_u_2), 0, 4, 8 },
{ OP(1, 1, 1, OP_REM_u_2), 0, 4, 12 },
{ OP(1, 1, 1, OP_JUMP_A), -6, 0, 0 },
};
static dstatement_t uint_divop_3a_statements[] = {
{ OP(1, 1, 1, OP_DIV_u_3), 0, 4, 8 },
{ OP(1, 1, 1, OP_DIV_u_1), 3, 7, 11 },
{ OP(1, 1, 1, OP_REM_u_3), 0, 4, 12 },
{ OP(1, 1, 1, OP_REM_u_1), 3, 7, 15 },
};
static dstatement_t uint_divop_3b_statements[] = {
{ OP(1, 1, 1, OP_DIV_u_1), 0, 4, 8 },
{ OP(1, 1, 1, OP_DIV_u_3), 1, 5, 9 },
{ OP(1, 1, 1, OP_REM_u_1), 0, 4, 12 },
{ OP(1, 1, 1, OP_REM_u_3), 1, 5, 13 },
};
static dstatement_t uint_divop_4_statements[] = {
{ OP(1, 1, 1, OP_DIV_u_4), 0, 4, 8 },
{ OP(1, 1, 1, OP_REM_u_4), 0, 4, 12 },
};
static pr_uivec4_t uint_cmpop_init[] = {
{ 5, -5, 5, -5},
{ 5, 5, -5, -5},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
};
static pr_uivec4_t uint_cmpop_expect[] = {
{ 5, -5, 5, -5},
{ 5, 5, -5, -5},
{ 0, 0, 0, 0}, // no unsigned EQ (redundant)
{ 0, 0, -1, 0},
{ 0, -1, 0, 0},
{ 0, 0, 0, 0}, // no unsigned NE (redundant)
{ -1, -1, 0, -1},
{ -1, 0, -1, -1},
};
static dstatement_t uint_cmpop_1_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 4, 0, 32 }, // init index
//loop:
{ OP(0, 0, 0, OP_LEA_C), 32, -1, 32 }, // dec index
{ OP(0, 0, 0, OP_IFAE), 2, 0, 32 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 32, 1 },
// no unsigned EQ (redundant)
{ OP(1, 1, 1, OP_LT_u_1), 0, 4, 12 },
{ OP(1, 1, 1, OP_GT_u_1), 0, 4, 16 },
// no unsigned NE (redundant)
{ OP(1, 1, 1, OP_GE_u_1), 0, 4, 24 },
{ OP(1, 1, 1, OP_LE_u_1), 0, 4, 28 },
{ OP(1, 1, 1, OP_JUMP_A), -8, 0, 0 },
};
static dstatement_t uint_cmpop_2_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 4, 0, 32 }, // index
//loop:
{ OP(0, 0, 0, OP_LEA_C), 32, -2, 32 }, // dec index
{ OP(0, 0, 0, OP_IFAE), 2, 0, 32 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 32, 1 },
// no unsigned EQ (redundant)
{ OP(1, 1, 1, OP_LT_u_2), 0, 4, 12 },
{ OP(1, 1, 1, OP_GT_u_2), 0, 4, 16 },
// no unsigned NE (redundant)
{ OP(1, 1, 1, OP_GE_u_2), 0, 4, 24 },
{ OP(1, 1, 1, OP_LE_u_2), 0, 4, 28 },
{ OP(1, 1, 1, OP_JUMP_A), -8, 0, 0 },
};
static dstatement_t uint_cmpop_3a_statements[] = {
// no unsigned EQ (redundant)
// no unsigned EQ (redundant)
{ OP(1, 1, 1, OP_LT_u_3), 0, 4, 12 },
{ OP(1, 1, 1, OP_LT_u_1), 3, 7, 15 },
{ OP(1, 1, 1, OP_GT_u_3), 0, 4, 16 },
{ OP(1, 1, 1, OP_GT_u_1), 3, 7, 19 },
// no unsigned NE (redundant)
// no unsigned NE (redundant)
{ OP(1, 1, 1, OP_GE_u_3), 0, 4, 24 },
{ OP(1, 1, 1, OP_GE_u_1), 3, 7, 27 },
{ OP(1, 1, 1, OP_LE_u_3), 0, 4, 28 },
{ OP(1, 1, 1, OP_LE_u_1), 3, 7, 31 },
};
static dstatement_t uint_cmpop_3b_statements[] = {
// no unsigned EQ (redundant)
// no unsigned EQ (redundant)
{ OP(1, 1, 1, OP_LT_u_1), 0, 4, 12 },
{ OP(1, 1, 1, OP_LT_u_3), 1, 5, 13 },
{ OP(1, 1, 1, OP_GT_u_1), 0, 4, 16 },
{ OP(1, 1, 1, OP_GT_u_3), 1, 5, 17 },
// no unsigned NE (redundant)
// no unsigned NE (redundant)
{ OP(1, 1, 1, OP_GE_u_1), 0, 4, 24 },
{ OP(1, 1, 1, OP_GE_u_3), 1, 5, 25 },
{ OP(1, 1, 1, OP_LE_u_1), 0, 4, 28 },
{ OP(1, 1, 1, OP_LE_u_3), 1, 5, 29 },
};
static dstatement_t uint_cmpop_4_statements[] = {
// no unsigned EQ (redundant)
{ OP(1, 1, 1, OP_LT_u_4), 0, 4, 12 },
{ OP(1, 1, 1, OP_GT_u_4), 0, 4, 16 },
// no unsigned NE (redundant)
{ OP(1, 1, 1, OP_GE_u_4), 0, 4, 24 },
{ OP(1, 1, 1, OP_LE_u_4), 0, 4, 28 },
};
static pr_ulvec4_t ulong_divop_init[] = {
{ 5, -5, 5, -5},
{ 3, 3, -3, -3},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
};
static pr_ulvec4_t ulong_divop_expect[] = {
{ 5, -5, 5, -5},
{ 3, 3, -3, -3},
{ 1, UINT64_C(0x5555555555555553), 0, 0},
{ 2, 2, 5, -5},
};
static dstatement_t ulong_divop_1_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 8, 0, 64 }, // init index
//loop:
{ OP(0, 0, 0, OP_LEA_C), 64, -2, 64 }, // dec index
{ OP(0, 0, 0, OP_IFAE), 2, 0, 64 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 64, 1 },
{ OP(1, 1, 1, OP_DIV_U_1), 0, 8, 16 },
{ OP(1, 1, 1, OP_REM_U_1), 0, 8, 24 },
{ OP(1, 1, 1, OP_JUMP_A), -6, 0, 0 },
};
static dstatement_t ulong_divop_2_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 8, 0, 64 }, // init index
//loop:
{ OP(0, 0, 0, OP_LEA_C), 64, -4, 64 }, // dec index
{ OP(0, 0, 0, OP_IFAE), 2, 0, 64 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 64, 1 },
{ OP(1, 1, 1, OP_DIV_U_2), 0, 8, 16 },
{ OP(1, 1, 1, OP_REM_U_2), 0, 8, 24 },
{ OP(1, 1, 1, OP_JUMP_A), -6, 0, 0 },
};
static dstatement_t ulong_divop_3a_statements[] = {
{ OP(1, 1, 1, OP_DIV_U_3), 0, 8, 16 },
{ OP(1, 1, 1, OP_DIV_U_1), 6, 14, 22 },
{ OP(1, 1, 1, OP_REM_U_3), 0, 8, 24 },
{ OP(1, 1, 1, OP_REM_U_1), 6, 14, 30 },
};
static dstatement_t ulong_divop_3b_statements[] = {
{ OP(1, 1, 1, OP_DIV_U_1), 0, 8, 16 },
{ OP(1, 1, 1, OP_DIV_U_3), 2, 10, 18 },
{ OP(1, 1, 1, OP_REM_U_1), 0, 8, 24 },
{ OP(1, 1, 1, OP_REM_U_3), 2, 10, 26 },
};
static dstatement_t ulong_divop_4_statements[] = {
{ OP(1, 1, 1, OP_DIV_U_4), 0, 8, 16 },
{ OP(1, 1, 1, OP_REM_U_4), 0, 8, 24 },
};
static pr_ulvec4_t ulong_cmpop_init[] = {
{ 5, -5, 5, -5},
{ 5, 5, -5, -5},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
};
static pr_ulvec4_t ulong_cmpop_expect[] = {
{ 5, -5, 5, -5},
{ 5, 5, -5, -5},
{ 0, 0, 0, 0}, // no unsigned EQ (redundant)
{ 0, 0, -1, 0},
{ 0, -1, 0, 0},
{ 0, 0, 0, 0}, // no unsigned NE (redundant)
{ -1, -1, 0, -1},
{ -1, 0, -1, -1},
};
static dstatement_t ulong_cmpop_1_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 8, 0, 64 }, // init index
//loop:
{ OP(0, 0, 0, OP_LEA_C), 64, -2, 64 }, // dec index
{ OP(0, 0, 0, OP_IFAE), 2, 0, 64 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 64, 1 },
// no unsigned EQ (redundant)
{ OP(1, 1, 1, OP_LT_U_1), 0, 8, 24 },
{ OP(1, 1, 1, OP_GT_U_1), 0, 8, 32 },
// no unsigned NE (redundant)
{ OP(1, 1, 1, OP_GE_U_1), 0, 8, 48 },
{ OP(1, 1, 1, OP_LE_U_1), 0, 8, 56 },
{ OP(1, 1, 1, OP_JUMP_A), -8, 0, 0 },
};
static dstatement_t ulong_cmpop_2_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 8, 0, 64 }, // init index
//loop:
{ OP(0, 0, 0, OP_LEA_C), 64, -4, 64 }, // dec index
{ OP(0, 0, 0, OP_IFAE), 2, 0, 64 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 64, 1 },
// no unsigned EQ (redundant)
{ OP(1, 1, 1, OP_LT_U_2), 0, 8, 24 },
{ OP(1, 1, 1, OP_GT_U_2), 0, 8, 32 },
// no unsigned NE (redundant)
{ OP(1, 1, 1, OP_GE_U_2), 0, 8, 48 },
{ OP(1, 1, 1, OP_LE_U_2), 0, 8, 56 },
{ OP(1, 1, 1, OP_JUMP_A), -8, 0, 0 },
};
static dstatement_t ulong_cmpop_3a_statements[] = {
// no unsigned EQ (redundant)
// no unsigned EQ (redundant)
{ OP(1, 1, 1, OP_LT_U_3), 0, 8, 24 },
{ OP(1, 1, 1, OP_LT_U_1), 6, 14, 30 },
{ OP(1, 1, 1, OP_GT_U_3), 0, 8, 32 },
{ OP(1, 1, 1, OP_GT_U_1), 6, 14, 38 },
// no unsigned NE (redundant)
// no unsigned NE (redundant)
{ OP(1, 1, 1, OP_GE_U_3), 0, 8, 48 },
{ OP(1, 1, 1, OP_GE_U_1), 6, 14, 54 },
{ OP(1, 1, 1, OP_LE_U_3), 0, 8, 56 },
{ OP(1, 1, 1, OP_LE_U_1), 6, 14, 62 },
};
static dstatement_t ulong_cmpop_3b_statements[] = {
// no unsigned EQ (redundant)
// no unsigned EQ (redundant)
{ OP(1, 1, 1, OP_LT_U_1), 0, 8, 24 },
{ OP(1, 1, 1, OP_LT_U_3), 2, 10, 26 },
{ OP(1, 1, 1, OP_GT_U_1), 0, 8, 32 },
{ OP(1, 1, 1, OP_GT_U_3), 2, 10, 34 },
// no unsigned NE (redundant)
// no unsigned NE (redundant)
{ OP(1, 1, 1, OP_GE_U_1), 0, 8, 48 },
{ OP(1, 1, 1, OP_GE_U_3), 2, 10, 50 },
{ OP(1, 1, 1, OP_LE_U_1), 0, 8, 56 },
{ OP(1, 1, 1, OP_LE_U_3), 2, 10, 58 },
};
static dstatement_t ulong_cmpop_4_statements[] = {
// no unsigned EQ (redundant)
{ OP(1, 1, 1, OP_LT_U_4), 0, 8, 24 },
{ OP(1, 1, 1, OP_GT_U_4), 0, 8, 32 },
// no unsigned NE (redundant)
{ OP(1, 1, 1, OP_GE_U_4), 0, 8, 48 },
{ OP(1, 1, 1, OP_LE_U_4), 0, 8, 56 },
};
static pr_uivec4_t uint_shiftop_init[] = {
{ 0x12345678, 0x9abcdef0, 0x80000001, 0xaaaa5555 },
{ 12, 16, 9, 1 },
{ 20, 16, 23, 31 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
};
static pr_uivec4_t uint_shiftop_expect[] = {
{ 0x12345678, 0x9abcdef0, 0x80000001, 0xaaaa5555 },
{ 12, 16, 9, 1 },//a
{ 20, 16, 23, 31 },//b
{ 0x45678000, 0xdef00000, 0x00000200, 0x5554aaaa },//shl a
{ 0x67800000, 0xdef00000, 0x00800000, 0x80000000 },//shl b
{ 0x00012345, 0x00009abc, 0x00400000, 0x55552aaa },//shr a
{ 0x00000123, 0x00009abc, 0x00000100, 0x00000001 },//shr b
{ 0x00012345, 0xffff9abc, 0xffc00000, 0xd5552aaa },//asr a
{ 0x00000123, 0xffff9abc, 0xffffff00, 0xffffffff },//asr b
};
static dstatement_t uint_shiftop_1_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 4, 0, 36 }, // init index
//loop:
{ OP(0, 0, 0, OP_LEA_C), 36, -1, 36 }, // dec index
{ OP(0, 0, 0, OP_IFAE), 2, 0, 36 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 36, 1 },
{ OP(1, 1, 1, OP_SHL_I_1), 0, 4, 12 },
{ OP(1, 1, 1, OP_SHL_I_1), 0, 8, 16 },
{ OP(1, 1, 1, OP_SHR_u_1), 0, 4, 20 },
{ OP(1, 1, 1, OP_SHR_u_1), 0, 8, 24 },
{ OP(1, 1, 1, OP_ASR_I_1), 0, 4, 28 },
{ OP(1, 1, 1, OP_ASR_I_1), 0, 8, 32 },
{ OP(1, 1, 1, OP_JUMP_A), -10, 0, 0 },
};
static dstatement_t uint_shiftop_2_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 4, 0, 36 }, // index
//loop:
{ OP(0, 0, 0, OP_LEA_C), 36, -2, 36 }, // dec index
{ OP(0, 0, 0, OP_IFAE), 2, 0, 36 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 36, 1 },
{ OP(1, 1, 1, OP_SHL_I_2), 0, 4, 12 },
{ OP(1, 1, 1, OP_SHL_I_2), 0, 8, 16 },
{ OP(1, 1, 1, OP_SHR_u_2), 0, 4, 20 },
{ OP(1, 1, 1, OP_SHR_u_2), 0, 8, 24 },
{ OP(1, 1, 1, OP_ASR_I_2), 0, 4, 28 },
{ OP(1, 1, 1, OP_ASR_I_2), 0, 8, 32 },
{ OP(1, 1, 1, OP_JUMP_A), -10, 0, 0 },
};
static dstatement_t uint_shiftop_3a_statements[] = {
{ OP(1, 1, 1, OP_SHL_I_3), 0, 4, 12 },
{ OP(1, 1, 1, OP_SHL_I_1), 3, 7, 15 },
{ OP(1, 1, 1, OP_SHL_I_3), 0, 8, 16 },
{ OP(1, 1, 1, OP_SHL_I_1), 3, 11, 19 },
{ OP(1, 1, 1, OP_SHR_u_3), 0, 4, 20 },
{ OP(1, 1, 1, OP_SHR_u_1), 3, 7, 23 },
{ OP(1, 1, 1, OP_SHR_u_3), 0, 8, 24 },
{ OP(1, 1, 1, OP_SHR_u_1), 3, 11, 27 },
{ OP(1, 1, 1, OP_ASR_I_3), 0, 4, 28 },
{ OP(1, 1, 1, OP_ASR_I_1), 3, 7, 31 },
{ OP(1, 1, 1, OP_ASR_I_3), 0, 8, 32 },
{ OP(1, 1, 1, OP_ASR_I_1), 3, 11, 35 },
};
static dstatement_t uint_shiftop_3b_statements[] = {
{ OP(1, 1, 1, OP_SHL_I_1), 0, 4, 12 },
{ OP(1, 1, 1, OP_SHL_I_3), 1, 5, 13 },
{ OP(1, 1, 1, OP_SHL_I_1), 0, 8, 16 },
{ OP(1, 1, 1, OP_SHL_I_3), 1, 9, 17 },
{ OP(1, 1, 1, OP_SHR_u_1), 0, 4, 20 },
{ OP(1, 1, 1, OP_SHR_u_3), 1, 5, 21 },
{ OP(1, 1, 1, OP_SHR_u_1), 0, 8, 24 },
{ OP(1, 1, 1, OP_SHR_u_3), 1, 9, 25 },
{ OP(1, 1, 1, OP_ASR_I_1), 0, 4, 28 },
{ OP(1, 1, 1, OP_ASR_I_3), 1, 5, 29 },
{ OP(1, 1, 1, OP_ASR_I_1), 0, 8, 32 },
{ OP(1, 1, 1, OP_ASR_I_3), 1, 9, 33 },
};
static dstatement_t uint_shiftop_4_statements[] = {
{ OP(1, 1, 1, OP_SHL_I_4), 0, 4, 12 },
{ OP(1, 1, 1, OP_SHL_I_4), 0, 8, 16 },
{ OP(1, 1, 1, OP_SHR_u_4), 0, 4, 20 },
{ OP(1, 1, 1, OP_SHR_u_4), 0, 8, 24 },
{ OP(1, 1, 1, OP_ASR_I_4), 0, 4, 28 },
{ OP(1, 1, 1, OP_ASR_I_4), 0, 8, 32 },
};
static pr_ulvec4_t ulong_shiftop_init[] = {
{ UINT64_C(0x123456789abcdef0), UINT64_C(0x9abcdef012345678),
UINT64_C(0x8000000180000001), UINT64_C(0xaaaa5555aaaa5555) },
{ 12, 16, 9, 1 },
{ 52, 48, 55, 63 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
};
static pr_ulvec4_t ulong_shiftop_expect[] = {
{ UINT64_C(0x123456789abcdef0), UINT64_C(0x9abcdef012345678),
UINT64_C(0x8000000180000001), UINT64_C(0xaaaa5555aaaa5555) },
{ 12, 16, 9, 1 },//a
{ 52, 48, 55, 63 },//b
{ UINT64_C(0x456789abcdef0000), UINT64_C(0xdef0123456780000),
UINT64_C(0x0000030000000200), UINT64_C(0x5554aaab5554aaaa) },//shl a
{ UINT64_C(0xef00000000000000), UINT64_C(0x5678000000000000),
UINT64_C(0x0080000000000000), UINT64_C(0x8000000000000000) },//shl b
{ UINT64_C(0x000123456789abcd), UINT64_C(0x00009abcdef01234),
UINT64_C(0x0040000000c00000), UINT64_C(0x55552aaad5552aaa) },//shr a
{ UINT64_C(0x0000000000000123), UINT64_C(0x0000000000009abc),
UINT64_C(0x0000000000000100), UINT64_C(0x0000000000000001) },//shr b
{ UINT64_C(0x000123456789abcd), UINT64_C(0xffff9abcdef01234),
UINT64_C(0xffc0000000c00000), UINT64_C(0xd5552aaad5552aaa) },//asr a
{ UINT64_C(0x0000000000000123), UINT64_C(0xffffffffffff9abc),
UINT64_C(0xffffffffffffff00), UINT64_C(0xffffffffffffffff) },//asr b
};
static dstatement_t ulong_shiftop_1_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 8, 0, 72 }, // init index
//loop:
{ OP(0, 0, 0, OP_LEA_C), 72, -2, 72 }, // dec index
{ OP(0, 0, 0, OP_IFAE), 2, 0, 72 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 72, 1 },
{ OP(1, 1, 1, OP_SHL_L_1), 0, 8, 24 },
{ OP(1, 1, 1, OP_SHL_L_1), 0, 16, 32 },
{ OP(1, 1, 1, OP_SHR_U_1), 0, 8, 40 },
{ OP(1, 1, 1, OP_SHR_U_1), 0, 16, 48 },
{ OP(1, 1, 1, OP_ASR_L_1), 0, 8, 56 },
{ OP(1, 1, 1, OP_ASR_L_1), 0, 16, 64 },
{ OP(1, 1, 1, OP_JUMP_A), -10, 0, 0 },
};
static dstatement_t ulong_shiftop_2_statements[] = {
{ OP(0, 0, 0, OP_LEA_A), 8, 0, 72 }, // index
//loop:
{ OP(0, 0, 0, OP_LEA_C), 72, -4, 72 }, // dec index
{ OP(0, 0, 0, OP_IFAE), 2, 0, 72 },
{ OP(0, 0, 0, OP_BREAK), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 4, 72, 1 },
{ OP(1, 1, 1, OP_SHL_L_2), 0, 8, 24 },
{ OP(1, 1, 1, OP_SHL_L_2), 0, 16, 32 },
{ OP(1, 1, 1, OP_SHR_U_2), 0, 8, 40 },
{ OP(1, 1, 1, OP_SHR_U_2), 0, 16, 48 },
{ OP(1, 1, 1, OP_ASR_L_2), 0, 8, 56 },
{ OP(1, 1, 1, OP_ASR_L_2), 0, 16, 64 },
{ OP(1, 1, 1, OP_JUMP_A), -10, 0, 0 },
};
static dstatement_t ulong_shiftop_3a_statements[] = {
{ OP(1, 1, 1, OP_SHL_L_3), 0, 8, 24 },
{ OP(1, 1, 1, OP_SHL_L_1), 6, 14, 30 },
{ OP(1, 1, 1, OP_SHL_L_3), 0, 16, 32 },
{ OP(1, 1, 1, OP_SHL_L_1), 6, 22, 38 },
{ OP(1, 1, 1, OP_SHR_U_3), 0, 8, 40 },
{ OP(1, 1, 1, OP_SHR_U_1), 6, 14, 46 },
{ OP(1, 1, 1, OP_SHR_U_3), 0, 16, 48 },
{ OP(1, 1, 1, OP_SHR_U_1), 6, 22, 54 },
{ OP(1, 1, 1, OP_ASR_L_3), 0, 8, 56 },
{ OP(1, 1, 1, OP_ASR_L_1), 6, 14, 62 },
{ OP(1, 1, 1, OP_ASR_L_3), 0, 16, 64 },
{ OP(1, 1, 1, OP_ASR_L_1), 6, 22, 70 },
};
static dstatement_t ulong_shiftop_3b_statements[] = {
{ OP(1, 1, 1, OP_SHL_L_1), 0, 8, 24 },
{ OP(1, 1, 1, OP_SHL_L_3), 2, 10, 26 },
{ OP(1, 1, 1, OP_SHL_L_1), 0, 16, 32 },
{ OP(1, 1, 1, OP_SHL_L_3), 2, 18, 34 },
{ OP(1, 1, 1, OP_SHR_U_1), 0, 8, 40 },
{ OP(1, 1, 1, OP_SHR_U_3), 2, 10, 42 },
{ OP(1, 1, 1, OP_SHR_U_1), 0, 16, 48 },
{ OP(1, 1, 1, OP_SHR_U_3), 2, 18, 50 },
{ OP(1, 1, 1, OP_ASR_L_1), 0, 8, 56 },
{ OP(1, 1, 1, OP_ASR_L_3), 2, 10, 58 },
{ OP(1, 1, 1, OP_ASR_L_1), 0, 16, 64 },
{ OP(1, 1, 1, OP_ASR_L_3), 2, 18, 66 },
};
static dstatement_t ulong_shiftop_4_statements[] = {
{ OP(1, 1, 1, OP_SHL_L_4), 0, 8, 24 },
{ OP(1, 1, 1, OP_SHL_L_4), 0, 16, 32 },
{ OP(1, 1, 1, OP_SHR_U_4), 0, 8, 40 },
{ OP(1, 1, 1, OP_SHR_U_4), 0, 16, 48 },
{ OP(1, 1, 1, OP_ASR_L_4), 0, 8, 56 },
{ OP(1, 1, 1, OP_ASR_L_4), 0, 16, 64 },
};
test_t tests[] = {
{
.desc = "uint divop 1",
.extra_globals = 4 * 1,
.num_globals = num_globals(uint_divop_init,uint_divop_expect),
.num_statements = num_statements (uint_divop_1_statements),
.statements = uint_divop_1_statements,
.init_globals = (pr_int_t *) uint_divop_init,
.expect_globals = (pr_int_t *) uint_divop_expect,
},
{
.desc = "uint divop 2",
.extra_globals = 4 * 1,
.num_globals = num_globals(uint_divop_init,uint_divop_expect),
.num_statements = num_statements (uint_divop_2_statements),
.statements = uint_divop_2_statements,
.init_globals = (pr_int_t *) uint_divop_init,
.expect_globals = (pr_int_t *) uint_divop_expect,
},
{
.desc = "uint divop 3a",
.extra_globals = 4 * 1,
.num_globals = num_globals(uint_divop_init,uint_divop_expect),
.num_statements = num_statements (uint_divop_3a_statements),
.statements = uint_divop_3a_statements,
.init_globals = (pr_int_t *) uint_divop_init,
.expect_globals = (pr_int_t *) uint_divop_expect,
},
{
.desc = "uint divop 3b",
.extra_globals = 4 * 1,
.num_globals = num_globals(uint_divop_init,uint_divop_expect),
.num_statements = num_statements (uint_divop_3b_statements),
.statements = uint_divop_3b_statements,
.init_globals = (pr_int_t *) uint_divop_init,
.expect_globals = (pr_int_t *) uint_divop_expect,
},
{
.desc = "uint divop 4",
.extra_globals = 4 * 1,
.num_globals = num_globals(uint_divop_init,uint_divop_expect),
.num_statements = num_statements (uint_divop_4_statements),
.statements = uint_divop_4_statements,
.init_globals = (pr_int_t *) uint_divop_init,
.expect_globals = (pr_int_t *) uint_divop_expect,
},
{
.desc = "uint cmpop 1",
.extra_globals = 4 * 1,
.num_globals = num_globals(uint_cmpop_init,uint_cmpop_expect),
.num_statements = num_statements (uint_cmpop_1_statements),
.statements = uint_cmpop_1_statements,
.init_globals = (pr_int_t *) uint_cmpop_init,
.expect_globals = (pr_int_t *) uint_cmpop_expect,
},
{
.desc = "uint cmpop 2",
.extra_globals = 4 * 1,
.num_globals = num_globals(uint_cmpop_init,uint_cmpop_expect),
.num_statements = num_statements (uint_cmpop_2_statements),
.statements = uint_cmpop_2_statements,
.init_globals = (pr_int_t *) uint_cmpop_init,
.expect_globals = (pr_int_t *) uint_cmpop_expect,
},
{
.desc = "uint cmpop 3a",
.extra_globals = 4 * 1,
.num_globals = num_globals(uint_cmpop_init,uint_cmpop_expect),
.num_statements = num_statements (uint_cmpop_3a_statements),
.statements = uint_cmpop_3a_statements,
.init_globals = (pr_int_t *) uint_cmpop_init,
.expect_globals = (pr_int_t *) uint_cmpop_expect,
},
{
.desc = "uint cmpop 3b",
.extra_globals = 4 * 1,
.num_globals = num_globals(uint_cmpop_init,uint_cmpop_expect),
.num_statements = num_statements (uint_cmpop_3b_statements),
.statements = uint_cmpop_3b_statements,
.init_globals = (pr_int_t *) uint_cmpop_init,
.expect_globals = (pr_int_t *) uint_cmpop_expect,
},
{
.desc = "uint cmpop 4",
.extra_globals = 4 * 1,
.num_globals = num_globals(uint_cmpop_init,uint_cmpop_expect),
.num_statements = num_statements (uint_cmpop_4_statements),
.statements = uint_cmpop_4_statements,
.init_globals = (pr_int_t *) uint_cmpop_init,
.expect_globals = (pr_int_t *) uint_cmpop_expect,
},
{
.desc = "ulong divop 1",
.extra_globals = 4 * 1,
.num_globals = num_globals(ulong_divop_init,ulong_divop_expect),
.num_statements = num_statements (ulong_divop_1_statements),
.statements = ulong_divop_1_statements,
.init_globals = (pr_int_t *) ulong_divop_init,
.expect_globals = (pr_int_t *) ulong_divop_expect,
},
{
.desc = "ulong divop 2",
.extra_globals = 4 * 1,
.num_globals = num_globals(ulong_divop_init,ulong_divop_expect),
.num_statements = num_statements (ulong_divop_2_statements),
.statements = ulong_divop_2_statements,
.init_globals = (pr_int_t *) ulong_divop_init,
.expect_globals = (pr_int_t *) ulong_divop_expect,
},
{
.desc = "ulong divop 3a",
.extra_globals = 4 * 1,
.num_globals = num_globals(ulong_divop_init,ulong_divop_expect),
.num_statements = num_statements (ulong_divop_3a_statements),
.statements = ulong_divop_3a_statements,
.init_globals = (pr_int_t *) ulong_divop_init,
.expect_globals = (pr_int_t *) ulong_divop_expect,
},
{
.desc = "ulong divop 3b",
.extra_globals = 4 * 1,
.num_globals = num_globals(ulong_divop_init,ulong_divop_expect),
.num_statements = num_statements (ulong_divop_3b_statements),
.statements = ulong_divop_3b_statements,
.init_globals = (pr_int_t *) ulong_divop_init,
.expect_globals = (pr_int_t *) ulong_divop_expect,
},
{
.desc = "ulong divop 4",
.extra_globals = 4 * 1,
.num_globals = num_globals(ulong_divop_init,ulong_divop_expect),
.num_statements = num_statements (ulong_divop_4_statements),
.statements = ulong_divop_4_statements,
.init_globals = (pr_int_t *) ulong_divop_init,
.expect_globals = (pr_int_t *) ulong_divop_expect,
},
{
.desc = "ulong cmpop 1",
.extra_globals = 4 * 1,
.num_globals = num_globals(ulong_cmpop_init,ulong_cmpop_expect),
.num_statements = num_statements (ulong_cmpop_1_statements),
.statements = ulong_cmpop_1_statements,
.init_globals = (pr_int_t *) ulong_cmpop_init,
.expect_globals = (pr_int_t *) ulong_cmpop_expect,
},
{
.desc = "ulong cmpop 2",
.extra_globals = 4 * 1,
.num_globals = num_globals(ulong_cmpop_init,ulong_cmpop_expect),
.num_statements = num_statements (ulong_cmpop_2_statements),
.statements = ulong_cmpop_2_statements,
.init_globals = (pr_int_t *) ulong_cmpop_init,
.expect_globals = (pr_int_t *) ulong_cmpop_expect,
},
{
.desc = "ulong cmpop 3a",
.extra_globals = 4 * 1,
.num_globals = num_globals(ulong_cmpop_init,ulong_cmpop_expect),
.num_statements = num_statements (ulong_cmpop_3a_statements),
.statements = ulong_cmpop_3a_statements,
.init_globals = (pr_int_t *) ulong_cmpop_init,
.expect_globals = (pr_int_t *) ulong_cmpop_expect,
},
{
.desc = "ulong cmpop 3b",
.extra_globals = 4 * 1,
.num_globals = num_globals(ulong_cmpop_init,ulong_cmpop_expect),
.num_statements = num_statements (ulong_cmpop_3b_statements),
.statements = ulong_cmpop_3b_statements,
.init_globals = (pr_int_t *) ulong_cmpop_init,
.expect_globals = (pr_int_t *) ulong_cmpop_expect,
},
{
.desc = "ulong cmpop 4",
.extra_globals = 4 * 1,
.num_globals = num_globals(ulong_cmpop_init,ulong_cmpop_expect),
.num_statements = num_statements (ulong_cmpop_4_statements),
.statements = ulong_cmpop_4_statements,
.init_globals = (pr_int_t *) ulong_cmpop_init,
.expect_globals = (pr_int_t *) ulong_cmpop_expect,
},
{
.desc = "uint shiftop 1",
.extra_globals = 4 * 1,
.num_globals = num_globals(uint_shiftop_init,uint_shiftop_expect),
.num_statements = num_statements (uint_shiftop_1_statements),
.statements = uint_shiftop_1_statements,
.init_globals = (pr_int_t *) uint_shiftop_init,
.expect_globals = (pr_int_t *) uint_shiftop_expect,
},
{
.desc = "uint shiftop 2",
.extra_globals = 4 * 1,
.num_globals = num_globals(uint_shiftop_init,uint_shiftop_expect),
.num_statements = num_statements (uint_shiftop_2_statements),
.statements = uint_shiftop_2_statements,
.init_globals = (pr_int_t *) uint_shiftop_init,
.expect_globals = (pr_int_t *) uint_shiftop_expect,
},
{
.desc = "uint shiftop 3a",
.extra_globals = 4 * 1,
.num_globals = num_globals(uint_shiftop_init,uint_shiftop_expect),
.num_statements = num_statements (uint_shiftop_3a_statements),
.statements = uint_shiftop_3a_statements,
.init_globals = (pr_int_t *) uint_shiftop_init,
.expect_globals = (pr_int_t *) uint_shiftop_expect,
},
{
.desc = "uint shiftop 3b",
.extra_globals = 4 * 1,
.num_globals = num_globals(uint_shiftop_init,uint_shiftop_expect),
.num_statements = num_statements (uint_shiftop_3b_statements),
.statements = uint_shiftop_3b_statements,
.init_globals = (pr_int_t *) uint_shiftop_init,
.expect_globals = (pr_int_t *) uint_shiftop_expect,
},
{
.desc = "uint shiftop 4",
.extra_globals = 4 * 1,
.num_globals = num_globals(uint_shiftop_init,uint_shiftop_expect),
.num_statements = num_statements (uint_shiftop_4_statements),
.statements = uint_shiftop_4_statements,
.init_globals = (pr_int_t *) uint_shiftop_init,
.expect_globals = (pr_int_t *) uint_shiftop_expect,
},
{
.desc = "ulong shiftop 1",
.extra_globals = 4 * 1,
.num_globals = num_globals(ulong_shiftop_init,ulong_shiftop_expect),
.num_statements = num_statements (ulong_shiftop_1_statements),
.statements = ulong_shiftop_1_statements,
.init_globals = (pr_int_t *) ulong_shiftop_init,
.expect_globals = (pr_int_t *) ulong_shiftop_expect,
},
{
.desc = "ulong shiftop 2",
.extra_globals = 4 * 1,
.num_globals = num_globals(ulong_shiftop_init,ulong_shiftop_expect),
.num_statements = num_statements (ulong_shiftop_2_statements),
.statements = ulong_shiftop_2_statements,
.init_globals = (pr_int_t *) ulong_shiftop_init,
.expect_globals = (pr_int_t *) ulong_shiftop_expect,
},
{
.desc = "ulong shiftop 3a",
.extra_globals = 4 * 1,
.num_globals = num_globals(ulong_shiftop_init,ulong_shiftop_expect),
.num_statements = num_statements (ulong_shiftop_3a_statements),
.statements = ulong_shiftop_3a_statements,
.init_globals = (pr_int_t *) ulong_shiftop_init,
.expect_globals = (pr_int_t *) ulong_shiftop_expect,
},
{
.desc = "ulong shiftop 3b",
.extra_globals = 4 * 1,
.num_globals = num_globals(ulong_shiftop_init,ulong_shiftop_expect),
.num_statements = num_statements (ulong_shiftop_3b_statements),
.statements = ulong_shiftop_3b_statements,
.init_globals = (pr_int_t *) ulong_shiftop_init,
.expect_globals = (pr_int_t *) ulong_shiftop_expect,
},
{
.desc = "ulong shiftop 4",
.extra_globals = 4 * 1,
.num_globals = num_globals(ulong_shiftop_init,ulong_shiftop_expect),
.num_statements = num_statements (ulong_shiftop_4_statements),
.statements = ulong_shiftop_4_statements,
.init_globals = (pr_int_t *) ulong_shiftop_init,
.expect_globals = (pr_int_t *) ulong_shiftop_expect,
},
};
#include "main.c"

View file

@ -0,0 +1,170 @@
#include "head.c"
static pr_vec4_t float_globals_init[] = {
{3, 4, 5, 12},
{0, 0, 0, 0},
{1, 2, 3, 8},
{4, 5, 6, 8},
{0, 0, 0, 7},
{0, 0, 0, 7},
{1, 2, 3, 4},
{5, 6, 7, 8},
{2, 3, 4, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 7},
{0, 0, 0, 7},
{0, 0, 0, 7},
{0, 0, 0, 7},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
};
static pr_vec4_t float_globals_expect[] = {
{3, 4, 5, 12},
{63, 63, -33, 56},
{1, 2, 3, 8},
{4, 5, 6, 8},
{32, 32, 32, 7},
{-3, 6, -3, 7},
{1, 2, 3, 4},
{5, 6, 7, 8},
{2, 3, 4, 0},
{70, 70, 70, 70},
{24, 48, 48, -6},
{36, 102, 120, 7},
{52, 70, 136, 7},
{36, 102, 120, 0},
{52, 70, 136, 0},
{-1, -2, -3, 4},
{-1, -2, -3, 4},
{36, 102, 120, 0},
{52, 70, 136, 0},
};
static dstatement_t float_vector_statements[] = {
{ OP(0, 0, 0, OP_CDOT_F), 0, 2, 4 },
{ OP(0, 0, 0, OP_CMUL_F), 0, 2, 6 },
{ OP(0, 0, 0, OP_VDOT_F), 8, 12, 16 },
{ OP(0, 0, 0, OP_CROSS_F), 8, 12, 20 },
{ OP(0, 0, 0, OP_QDOT_F), 24, 28, 36 },
{ OP(0, 0, 0, OP_QMUL_F), 24, 28, 40 },
{ OP(0, 0, 0, OP_QVMUL_F), 24, 32, 44 },
{ OP(0, 0, 0, OP_VQMUL_F), 32, 24, 48 },
{ OP(0, 0, 0, OP_QMUL_F), 24, 32, 52 },
{ OP(0, 0, 0, OP_SWIZZLE_F), 24, 0x07e4, 60 },
{ OP(0, 0, 0, OP_QMUL_F), 52, 60, 52 },
{ OP(0, 0, 0, OP_SWIZZLE_F), 24, 0x07e4, 64 },
{ OP(0, 0, 0, OP_QMUL_F), 64, 32, 56 },
{ OP(0, 0, 0, OP_QMUL_F), 56, 24, 56 },
{ OP(0, 0, 0, OP_QV4MUL_F), 24, 32, 68 },
{ OP(0, 0, 0, OP_V4QMUL_F), 32, 24, 72 },
};
static pr_dvec4_t double_globals_init[] = {
{3, 4, 5, 12},
{0, 0, 0, 0},
{1, 2, 3, 8},
{4, 5, 6, 8},
{0, 0, 0, 7},
{0, 0, 0, 7},
{1, 2, 3, 4},
{5, 6, 7, 8},
{2, 3, 4, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 7},
{0, 0, 0, 7},
{0, 0, 0, 7},
{0, 0, 0, 7},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
};
static pr_dvec4_t double_globals_expect[] = {
{3, 4, 5, 12},
{63, 63, -33, 56},
{1, 2, 3, 8},
{4, 5, 6, 8},
{32, 32, 32, 7},
{-3, 6, -3, 7},
{1, 2, 3, 4},
{5, 6, 7, 8},
{2, 3, 4, 0},
{70, 70, 70, 70},
{24, 48, 48, -6},
{36, 102, 120, 7},
{52, 70, 136, 7},
{36, 102, 120, 0},
{52, 70, 136, 0},
{-1, -2, -3, 4},
{-1, -2, -3, 4},
{36, 102, 120, 0},
{52, 70, 136, 0},
};
static dstatement_t double_vector_statements[] = {
{ OP(0, 0, 0, OP_CDOT_D), 0, 4, 8 },
{ OP(0, 0, 0, OP_CMUL_D), 0, 4, 12 },
{ OP(0, 0, 0, OP_VDOT_D), 16, 24, 32 },
{ OP(0, 0, 0, OP_CROSS_D), 16, 24, 40 },
{ OP(0, 0, 0, OP_QDOT_D), 48, 56, 72 },
{ OP(0, 0, 0, OP_QMUL_D), 48, 56, 80 },
{ OP(0, 0, 0, OP_QVMUL_D), 48, 64, 88 },
{ OP(0, 0, 0, OP_VQMUL_D), 64, 48, 96 },
{ OP(0, 0, 0, OP_QMUL_D), 48, 64, 104 },
{ OP(0, 0, 0, OP_SWIZZLE_D), 48, 0x07e4, 120 },
{ OP(0, 0, 0, OP_QMUL_D), 104, 120, 104 },
{ OP(0, 0, 0, OP_SWIZZLE_D), 48, 0x07e4, 128 },
{ OP(0, 0, 0, OP_QMUL_D), 128, 64, 112 },
{ OP(0, 0, 0, OP_QMUL_D), 112, 48, 112 },
{ OP(0, 0, 0, OP_QV4MUL_D), 48, 64, 136 },
{ OP(0, 0, 0, OP_V4QMUL_D), 64, 48, 144 },
};
test_t tests[] = {
{
.desc = "float vector",
.num_globals = num_globals(float_globals_init, float_globals_expect),
.num_statements = num_statements (float_vector_statements),
.statements = float_vector_statements,
.init_globals = (pr_int_t *) float_globals_init,
.expect_globals = (pr_int_t *) float_globals_expect,
},
{
.desc = "double vector",
.num_globals = num_globals(double_globals_init,double_globals_expect),
.num_statements = num_statements (double_vector_statements),
.statements = double_vector_statements,
.init_globals = (pr_int_t *) double_globals_init,
.expect_globals = (pr_int_t *) double_globals_expect,
},
};
#include "main.c"

View file

@ -0,0 +1,307 @@
#include "head.c"
#include "QF/mathlib.h"
#define DB 0xdeadbeef
static pr_ivec4_t pushregs_init[] = {
{ DB, DB, DB, DB},
};
static pr_ivec4_t pushregs_expect[] = {
{ 0, 0, 0, 0}, // initial base regs should all be 0
};
static dstatement_t pushregs_statements[] = {
{ OP(0, 0, 0, OP_WITH), 8, 0, 0 }, // pushregs
{ OP(0, 0, 0, OP_POP_A_4), 0, 0, 0 },
};
static pr_ivec4_t popregs_init[] = {
{ 4, 5, 6, 7},
{ DB, DB, DB, DB},
};
static pr_ivec4_t popregs_expect[] = {
{ 4, 5, 6, 7},
{ 7, 6, 5, 4},
};
static dstatement_t popregs_statements[] = {
{ OP(0, 0, 0, OP_PUSH_A_4), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 9, 0, 0 }, // popregs
{ OP(3, 0, 0, OP_LEA_A), 0, 0, 0 },
{ OP(2, 0, 1, OP_LEA_A), 0, 0, 0 },
{ OP(1, 0, 2, OP_LEA_A), 0, 0, 0 },
{ OP(0, 0, 3, OP_LEA_A), 0, 0, 0 },
};
static pr_ivec4_t with_0_init[] = {
{ 4, 5, 6, 7},
{ DB, DB, DB, DB},
{ DB, DB, DB, DB},
{ DB, DB, DB, DB},
};
static pr_ivec4_t with_0_expect[] = {
{ 4, 5, 6, 7},
{ 0, 1, 6, 7},
{ 4, 5, 0, 1},
{ 0, 0, 0, 0},
};
static dstatement_t with_0_statements[] = {
{ OP(0, 0, 0, OP_PUSH_A_4), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 9, 0, 0 }, // popregs
{ OP(0, 0, 0, OP_WITH), 0, 0, 0 }, // set reg 0 to 0
{ OP(0, 0, 0, OP_WITH), 0, 1, 1 }, // set reg 1 to 1
{ OP(0, 0, 0, OP_WITH), 8, 0, 0 }, // pushregs
{ OP(0, 0, 0, OP_POP_A_4), 4, 0, 0 },
{ OP(0, 0, 0, OP_PUSH_A_4), 0, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 9, 0, 0 }, // popregs
{ OP(0, 0, 0, OP_WITH), 0, 0, 2 }, // set reg 2 to 0
{ OP(0, 0, 0, OP_WITH), 0, 1, 3 }, // set reg 3 to 1
{ OP(0, 0, 0, OP_WITH), 8, 0, 0 }, // pushregs
{ OP(2, 0, 0, OP_POP_A_4), 8, 0, 0 },
{ OP(0, 0, 0, OP_WITH), 10, 0, 0 }, // reset
{ OP(0, 0, 0, OP_WITH), 8, 0, 0 }, // pushregs
{ OP(2, 0, 0, OP_POP_A_4), 12, 0, 0 },
};
static pr_ivec4_t with_1_init[] = {
{ 4, 5, 6, 7},
{ DB, DB, DB, DB},
};
static pr_ivec4_t with_1_expect[] = {
{ 4, 5, 6, 7},
{ 0, 4, 6, 2},
};
static dstatement_t with_1_statements[] = {
{ OP(0, 0, 0, OP_WITH), 0, 4, 1 },
{ OP(0, 1, 0, OP_WITH), 1, 2, 2 },
{ OP(0, 1, 0, OP_WITH), 1, -2, 3 },
{ OP(0, 0, 0, OP_WITH), 8, 0, 0 }, // pushregs
{ OP(0, 0, 0, OP_POP_A_4), 4, 0, 0 },
};
static pr_ivec4_t with_2_init[] = {
{ 4, 5, 6, 7},
{ DB, DB, DB, DB},
{ DB, DB, DB, DB},
{ DB, DB, DB, DB},
};
static pr_ivec4_t with_2_expect[] = {
{ 4, 5, 6, 7},
{ 0, 44, 48, 40},
{ DB, DB, DB, DB},
{ DB, DB, DB, DB},
};
static dstatement_t with_2_statements[] = {
{ OP(0, 0, 0, OP_PUSH_A_4), 0, 0, 0 }, // so something is on the stack
{ OP(0, 0, 0, OP_WITH), 2, 0, 1 },
{ OP(0, 1, 0, OP_WITH), 2, 4, 2 },
{ OP(0, 1, 0, OP_WITH), 2, -4, 3 },
{ OP(0, 0, 0, OP_WITH), 8, 0, 0 }, // pushregs
{ OP(0, 0, 0, OP_POP_A_4), 4, 0, 0 },
};
static pr_ivec4_t with_3_init[] = {
{ 4, 5, 6, 7},
{ DB, DB, DB, DB},
};
static pr_ivec4_t with_3_expect[] = {
{ 4, 5, 6, 7},
{ 0, 64, 68, 65596}, // edict-area relative is only +ve
};
static dstatement_t with_3_statements[] = {
{ OP(0, 0, 0, OP_WITH), 3, 0, 1 },
{ OP(0, 1, 0, OP_WITH), 3, 4, 2 },
{ OP(0, 1, 0, OP_WITH), 3, -4, 3 },
{ OP(0, 0, 0, OP_WITH), 8, 0, 0 }, // pushregs
{ OP(0, 0, 0, OP_POP_A_4), 4, 0, 0 },
};
static pr_ivec4_t with_4_init[] = {
{ 4, 5, 6, 7},
{ DB, DB, DB, DB},
};
static pr_ivec4_t with_4_expect[] = {
{ 4, 5, 6, 7},
{ 0, 4, 5, 6},
};
static dstatement_t with_4_statements[] = {
{ OP(0, 0, 0, OP_WITH), 4, 0, 1 },
{ OP(0, 1, 0, OP_WITH), 4, 1, 2 },
{ OP(0, 1, 0, OP_WITH), 4, 2, 3 },
{ OP(0, 0, 0, OP_WITH), 8, 0, 0 }, // pushregs
{ OP(0, 0, 0, OP_POP_A_4), 4, 0, 0 },
};
static pr_ivec4_t with_5_init[] = {
{ 4, 5, 6, 7},
{ DB, DB, DB, DB},
};
static pr_ivec4_t with_5_expect[] = {
{ 4, 5, 6, 7},
{ 0, 2, 6, 7},
};
static dstatement_t with_5_statements[] = {
{ OP(0, 0, 0, OP_WITH), 0, 2, 1 },
{ OP(0, 1, 0, OP_WITH), 5, 0, 2 },
{ OP(0, 1, 0, OP_WITH), 5, 1, 3 },
{ OP(0, 0, 0, OP_WITH), 8, 0, 0 }, // pushregs
{ OP(0, 0, 0, OP_POP_A_4), 4, 0, 0 },
};
static pr_ivec4_t with_6_init[] = {
{ 4, 5, 6, -4},
{ DB, DB, DB, DB},
{ DB, DB, DB, DB},
{ DB, DB, DB, DB},
};
static pr_ivec4_t with_6_expect[] = {
{ 4, 5, 6, -4},
{ 0, 44, 48, 40},
{ DB, DB, DB, DB},
{ DB, DB, DB, DB},
};
static dstatement_t with_6_statements[] = {
{ OP(0, 0, 0, OP_PUSH_A_4), 0, 0, 0 }, // so something is on the stack
{ OP(0, 0, 0, OP_WITH), 2, 0, 1 },
{ OP(0, 1, 0, OP_WITH), 6, 0, 2 },
{ OP(0, 1, 0, OP_WITH), 6, 3, 3 },
{ OP(0, 0, 0, OP_WITH), 8, 0, 0 }, // pushregs
{ OP(0, 0, 0, OP_POP_A_4), 4, 0, 0 },
};
static pr_ivec4_t with_7_init[] = {
{ 4, 5, 6, -4},
{ DB, DB, DB, DB},
};
static pr_ivec4_t with_7_expect[] = {
{ 4, 5, 6, -4},
{ 0, 2, 70, 60}, // edict-area relative is only +ve, but 32-bit wrap
};
static dstatement_t with_7_statements[] = {
{ OP(0, 0, 0, OP_WITH), 0, 2, 1 },
{ OP(0, 1, 0, OP_WITH), 7, 0, 2 },
{ OP(0, 1, 0, OP_WITH), 7, 1, 3 },
{ OP(0, 0, 0, OP_WITH), 8, 0, 0 }, // pushregs
{ OP(0, 0, 0, OP_POP_A_4), 4, 0, 0 },
};
test_t tests[] = {
{
.desc = "pushregs",
.num_globals = num_globals(pushregs_init,pushregs_expect),
.num_statements = num_statements (pushregs_statements),
.statements = pushregs_statements,
.init_globals = (pr_int_t *) pushregs_init,
.expect_globals = (pr_int_t *) pushregs_expect,
.stack_size = 32,
},
{
.desc = "popregs",
.num_globals = num_globals(popregs_init,popregs_expect),
.num_statements = num_statements (popregs_statements),
.statements = popregs_statements,
.init_globals = (pr_int_t *) popregs_init,
.expect_globals = (pr_int_t *) popregs_expect,
.stack_size = 32,
},
{
.desc = "with 0",
.num_globals = num_globals(with_0_init,with_0_expect),
.num_statements = num_statements (with_0_statements),
.statements = with_0_statements,
.init_globals = (pr_int_t *) with_0_init,
.expect_globals = (pr_int_t *) with_0_expect,
.stack_size = 32,
},
{
.desc = "with 1",
.num_globals = num_globals(with_1_init,with_1_expect),
.num_statements = num_statements (with_1_statements),
.statements = with_1_statements,
.init_globals = (pr_int_t *) with_1_init,
.expect_globals = (pr_int_t *) with_1_expect,
.stack_size = 32,
.edict_area = 64,
},
{
.desc = "with 2",
.num_globals = num_globals(with_2_init,with_2_expect),
.num_statements = num_statements (with_2_statements),
.statements = with_2_statements,
.init_globals = (pr_int_t *) with_2_init,
.expect_globals = (pr_int_t *) with_2_expect,
.stack_size = 32,
.edict_area = 64,
},
{
.desc = "with 3",
.num_globals = num_globals(with_3_init,with_3_expect),
.num_statements = num_statements (with_3_statements),
.statements = with_3_statements,
.init_globals = (pr_int_t *) with_3_init,
.expect_globals = (pr_int_t *) with_3_expect,
.stack_size = 32,
.edict_area = 64,
},
{
.desc = "with 4",
.num_globals = num_globals(with_4_init,with_4_expect),
.num_statements = num_statements (with_4_statements),
.statements = with_4_statements,
.init_globals = (pr_int_t *) with_4_init,
.expect_globals = (pr_int_t *) with_4_expect,
.stack_size = 32,
.edict_area = 64,
},
{
.desc = "with 5",
.num_globals = num_globals(with_5_init,with_5_expect),
.num_statements = num_statements (with_5_statements),
.statements = with_5_statements,
.init_globals = (pr_int_t *) with_5_init,
.expect_globals = (pr_int_t *) with_5_expect,
.stack_size = 32,
.edict_area = 64,
},
{
.desc = "with 6",
.num_globals = num_globals(with_6_init,with_6_expect),
.num_statements = num_statements (with_6_statements),
.statements = with_6_statements,
.init_globals = (pr_int_t *) with_6_init,
.expect_globals = (pr_int_t *) with_6_expect,
.stack_size = 32,
.edict_area = 64,
},
{
.desc = "with 7",
.num_globals = num_globals(with_7_init,with_7_expect),
.num_statements = num_statements (with_7_statements),
.statements = with_7_statements,
.init_globals = (pr_int_t *) with_7_init,
.expect_globals = (pr_int_t *) with_7_expect,
.stack_size = 32,
.edict_area = 64,
},
};
#include "main.c"

View file

@ -48,8 +48,8 @@
typedef struct bi_gib_builtin_s {
struct bi_gib_builtin_s *next;
gib_builtin_t *builtin;
progs_t *pr;
func_t func;
progs_t *pr;
pr_func_t func;
} bi_gib_builtin_t;
typedef struct bi_gib_resources_s {
@ -86,7 +86,7 @@ bi_gib_builtin_f (void)
pr_list = PR_Zone_Malloc (builtin->pr, GIB_Argc() * sizeof (pr_type_t));
for (i = 0; i < GIB_Argc(); i++)
pr_list[i].integer_var = PR_SetTempString (builtin->pr, GIB_Argv(i));
pr_list[i].int_var = PR_SetTempString (builtin->pr, GIB_Argv(i));
PR_RESET_PARAMS (builtin->pr);
P_INT (builtin->pr, 0) = GIB_Argc();
@ -117,7 +117,7 @@ bi_GIB_Builtin_Add (progs_t *pr)
bi_gib_resources_t *res = PR_Resources_Find (pr, "GIB");
bi_gib_builtin_t *builtin;
const char *name = P_GSTRING (pr, 0);
func_t func = P_FUNCTION (pr, 1);
pr_func_t func = P_FUNCTION (pr, 1);
if (GIB_Builtin_Exists (name)) {
R_INT (pr) = 0;
@ -175,12 +175,15 @@ bi_GIB_Handle_Get (progs_t *pr)
// R_INT (pr) = 0;
}
#define bi(x,np,params...) {#x, bi_##x, -1, np, {params}}
#define p(type) PR_PARAM(type)
#define P(a, s) { .size = (s), .alignment = BITOP_LOG2 (a), }
static builtin_t builtins[] = {
{"GIB_Builtin_Add", bi_GIB_Builtin_Add, -1},
{"GIB_Return", bi_GIB_Return, -1},
{"GIB_Handle_New", bi_GIB_Handle_New, -1},
{"GIB_Handle_Free", bi_GIB_Handle_Free, -1},
{"GIB_Handle_Get", bi_GIB_Handle_Get, -1},
bi(GIB_Builtin_Add, 2, p(string), p(func)),
bi(GIB_Return, 1, p(string)),
bi(GIB_Handle_New, 0),//FIXME
bi(GIB_Handle_Free, 0),//FIXME
bi(GIB_Handle_Get, 0),//FIXME
{0}
};
@ -190,11 +193,10 @@ GIB_Progs_Init (progs_t *pr)
bi_gib_resources_t *res = malloc (sizeof (bi_gib_resources_t));
res->builtins = 0;
PR_Resources_Register (pr, "GIB", res, bi_gib_builtin_clear);
bi_gib_builtins = Hash_NewTable (1021, bi_gib_builtin_get_key,
bi_gib_builtin_free, 0,
pr->hashlink_freelist);
PR_RegisterBuiltins (pr, builtins);
PR_Resources_Register (pr, "GIB", res, bi_gib_builtin_clear);
PR_RegisterBuiltins (pr, builtins, res);
}

View file

@ -120,7 +120,7 @@ init_box (const trace_t *trace, clipbox_t *box, const vec3_t vel)
//FIXME rotated box
for (i = 0; i < 3; i++)
u[i] = (vel[i] >= 0 ? 1 : -1);
VectorCompMult (u, trace->extents, p);
VectorCompMult (p, u, trace->extents);
for (i = 0; i < 3; i++) {
box->portals[i].planenum = i;
box->portals[i].next[0] = 0;
@ -153,17 +153,17 @@ init_box (const trace_t *trace, clipbox_t *box, const vec3_t vel)
box->edges[i].points[j][a]
= s[k] * u[i] * box->edges[i].points[j - 1][b];
}
VectorCompMult (box->points[i].points[j - 1], trace->extents,
box->points[i].points[j - 1]);
VectorCompMult (box->edges[i].points[j - 1], trace->extents,
box->edges[i].points[j - 1]);
VectorCompMult (box->points[i].points[j - 1],
box->points[i].points[j - 1], trace->extents);
VectorCompMult (box->edges[i].points[j - 1],
box->edges[i].points[j - 1], trace->extents);
VectorScale (box->edges[i].points[j - 1], 2,
box->edges[i].points[j - 1]);
}
VectorCompMult (box->points[i].points[3], trace->extents,
box->points[i].points[3]);
VectorCompMult (box->edges[i].points[3], trace->extents,
box->edges[i].points[3]);
VectorCompMult (box->points[i].points[3],
box->points[i].points[3], trace->extents);
VectorCompMult (box->edges[i].points[3],
box->edges[i].points[3], trace->extents);
VectorScale (box->edges[i].points[3], 2,
box->edges[i].points[3]);
}
@ -566,8 +566,8 @@ portal_intersect (trace_t *trace, clipport_t *portal, plane_t *plane,
vec3_t p1, p2, imp, dist;
vec_t t1, t2, frac;
VectorCompMult (trace->extents, verts[i][0], p1);
VectorCompMult (trace->extents, verts[i][1], p2);
VectorCompMult (p1, trace->extents, verts[i][0]);
VectorCompMult (p2, trace->extents, verts[i][1]);
t1 = PlaneDiff (p1, plane) + o_n;
t2 = PlaneDiff (p2, plane) + o_n;
// if both ends of the box edge are on the same side (or touching) the

View file

@ -78,7 +78,7 @@ PollProcedure slistPollProcedure = { NULL, 0.0, Slist_Poll };
static sizebuf_t _net_message_message;
static qmsg_t _net_message = { 0, 0, &_net_message_message };
qmsg_t *net_message = &_net_message;
int net_activeconnections = 0;
unsigned net_activeconnections = 0;
int messagesSent = 0;
int messagesReceived = 0;
@ -197,7 +197,7 @@ NET_Listen_f (void)
static void
MaxPlayers_f (void)
{
int n;
unsigned n;
if (Cmd_Argc () != 2) {
Sys_Printf ("\"maxplayers\" is \"%u\"\n", svs.maxclients);
@ -710,7 +710,7 @@ int
NET_SendToAll (sizebuf_t *data, double blocktime)
{
double start;
int i;
unsigned i;
int count = 0;
qboolean state1[MAX_SCOREBOARD]; /* can we send */
qboolean state2[MAX_SCOREBOARD]; /* did we send */

View file

@ -652,7 +652,7 @@ _Datagram_CheckNewConnections (void)
if (command == CCREQ_PLAYER_INFO) {
int playerNumber;
int activeNumber;
int clientNumber;
unsigned clientNumber;
client_t *client;
playerNumber = MSG_ReadByte (net_message);

View file

@ -54,17 +54,18 @@ VISIBLE const char *pr_gametype = "";
/* BUILT-IN FUNCTIONS */
VISIBLE char *
PF_VarString (progs_t *pr, int first)
PF_VarString (progs_t *pr, int first, int argc)
{
char *out, *dst;
const char *src;
int len, i;
pr_type_t **argv = pr->pr_params;
for (len = 0, i = first; i < pr->pr_argc; i++)
len += strlen (P_GSTRING (pr, i));
for (len = 0, i = first; i < argc; i++)
len += strlen (PR_GetString (pr, argv[i]->string_var));
dst = out = Hunk_TempAlloc (0, len + 1);
for (i = first; i < pr->pr_argc; i++) {
src = P_GSTRING (pr, i);
for (i = first; i < argc; i++) {
src = PR_GetString (pr, argv[i]->string_var);
while (*src)
*dst++ = *src++;
}
@ -249,11 +250,11 @@ PF_fabs (progs_t *pr)
entity (entity start, .(...) fld, ... match) find
*/
static void
PF_Find (progs_t *pr)
PF_find (progs_t *pr)
{
const char *s = 0, *t; // ev_string
int i; // ev_vector
int e, f;
pr_uint_t e, f;
etype_t type;
pr_def_t *field_def;
edict_t *ed;
@ -295,7 +296,7 @@ PF_Find (progs_t *pr)
continue;
RETURN_EDICT (pr, ed);
return;
case ev_integer:
case ev_int:
case ev_entity:
if (P_INT (pr, 2) != E_INT (ed, f))
continue;
@ -352,7 +353,7 @@ PF_eprint (progs_t *pr)
static void
PF_dprint (progs_t *pr)
{
Sys_Printf ("%s", PF_VarString (pr, 0));
Sys_Printf ("%s", PF_VarString (pr, 0, 1));
}
/*
@ -394,7 +395,7 @@ PF_ceil (progs_t *pr)
static void
PF_nextent (progs_t *pr)
{
int i;
pr_uint_t i;
edict_t *ent;
i = P_EDICTNUM (pr, 0);
@ -420,7 +421,7 @@ PF_nextent (progs_t *pr)
#endif
/*
integer (float f) ftoi
int (float f) ftoi
*/
static void
PF_ftoi (progs_t *pr)
@ -453,7 +454,7 @@ PF_ftos (progs_t *pr)
}
/*
float (integer i) itof
float (int i) itof
*/
static void
PF_itof (progs_t *pr)
@ -462,7 +463,7 @@ PF_itof (progs_t *pr)
}
/*
string (integer i) itos
string (int i) itos
*/
static void
PF_itos (progs_t *pr)
@ -484,7 +485,7 @@ PF_stof (progs_t *pr)
}
/*
integer (string s) stoi
int (string s) stoi
*/
static void
PF_stoi (progs_t *pr)
@ -557,7 +558,7 @@ PF_charcount (progs_t *pr)
string () gametype
*/
static void
PR_gametype (progs_t *pr)
PF_gametype (progs_t *pr)
{
RETURN_STRING (pr, pr_gametype);
}
@ -585,46 +586,48 @@ PF_PR_FindFunction (progs_t *pr)
#define QF (PR_RANGE_QF << PR_RANGE_SHIFT) |
#define bi(x,n,np,params...) {#x, PF_##x, n, np, {params}}
#define p(type) PR_PARAM(type)
static builtin_t builtins[] = {
{"break", PF_break, 6},
{"random", PF_random, 7},
{"normalize", PF_normalize, 9},
{"vlen", PF_vlen, 12},
{"vectoyaw", PF_vectoyaw, 13},
{"find", PF_Find, 18},
{"dprint", PF_dprint, 25},
{"ftos", PF_ftos, 26},
{"vtos", PF_vtos, 27},
{"coredump", PF_coredump, 28},
{"traceon", PF_traceon, 29},
{"traceoff", PF_traceoff, 30},
{"eprint", PF_eprint, 31},
{"rint", PF_rint, 36},
{"floor", PF_floor, 37},
{"ceil", PF_ceil, 38},
{"fabs", PF_fabs, 43},
{"cvar", PF_cvar, 45},
{"nextent", PF_nextent, 47},
{"vectoangles", PF_vectoangles, 51},
{"cvar_set", PF_cvar_set, 72},
{"stof", PF_stof, 81},
bi(break, 6, 0),
bi(random, 7, 0),
bi(normalize, 9, 1, p(vector)),
bi(vlen, 12, 1, p(vector)),
bi(vectoyaw, 13, 1, p(vector)),
bi(find, 18, -3, p(entity), p(field)),
bi(dprint, 25, -1),
bi(ftos, 26, 1, p(float)),
bi(vtos, 27, 1, p(vector)),
bi(coredump, 28, 0),
bi(traceon, 29, 0),
bi(traceoff, 30, 0),
bi(eprint, 31, 1, p(entity)),
bi(rint, 36, 1, p(float)),
bi(floor, 37, 1, p(float)),
bi(ceil, 38, 1, p(float)),
bi(fabs, 43, 1, p(float)),
bi(cvar, 45, 1, p(string)),
bi(nextent, 47, 1, p(entity)),
bi(vectoangles, 51, 1, p(vector)),
bi(cvar_set, 72, 2, p(string), p(string)),
bi(stof, 81, 1, p(string)),
{"charcount", PF_charcount, QF 101},
{"ftoi", PF_ftoi, QF 110},
{"itof", PF_itof, QF 111},
{"itos", PF_itos, QF 112},
{"stoi", PF_stoi, QF 113},
{"stov", PF_stov, QF 114},
{"gametype", PR_gametype, QF 115},
bi(charcount, QF 101, 2, p(string), p(string)),
bi(ftoi, QF 110, 1, p(float)),
bi(itof, QF 111, 1, p(int)),
bi(itos, QF 112, 1, p(int)),
bi(stoi, QF 113, 1, p(string)),
bi(stov, QF 114, 1, p(string)),
bi(gametype, QF 115, 0),
{"PR_SetField", PF_PR_SetField, -1},
{"PR_FindFunction", PF_PR_FindFunction, -1},
bi(PR_SetField, -1, 3, p(entity), p(string), p(string)),
bi(PR_FindFunction, -1, 1, p(string)),
{0}
};
VISIBLE void
PR_Cmds_Init (progs_t *pr)
{
PR_RegisterBuiltins (pr, builtins);
PR_RegisterBuiltins (pr, builtins, 0);
}

View file

@ -93,11 +93,14 @@ bi_cbuf_clear (progs_t *pr, void *data)
{
}
#define bi(x,np,params...) {#x, bi_##x, -1, np, {params}}
#define p(type) PR_PARAM(type)
#define P(a, s) { .size = (s), .alignment = BITOP_LOG2 (a), }
static builtin_t builtins[] = {
{"Cbuf_AddText", bi_Cbuf_AddText, -1},
{"Cbuf_InsertText", bi_Cbuf_InsertText, -1},
{"Cbuf_Execute", bi_Cbuf_Execute, -1},
{"Cbuf_Execute_Sets", bi_Cbuf_Execute_Sets, -1},
bi(Cbuf_AddText, 1, p(string)),
bi(Cbuf_InsertText, 1, p(string)),
bi(Cbuf_Execute, 0),
bi(Cbuf_Execute_Sets, 0),
{0}
};
@ -106,7 +109,7 @@ RUA_Cbuf_Init (progs_t *pr, int secure)
{
cbuf_resources_t *res = calloc (sizeof (cbuf_resources_t), 1);
PR_Resources_Register (pr, "Cbuf", res, bi_cbuf_clear);
PR_RegisterBuiltins (pr, builtins);
PR_RegisterBuiltins (pr, builtins, res);
}
VISIBLE void

View file

@ -50,7 +50,7 @@ typedef struct bi_cmd_s {
struct bi_cmd_s *next;
char *name;
progs_t *pr;
func_t func;
pr_func_t func;
} bi_cmd_t;
typedef struct {
@ -90,7 +90,7 @@ bi_Cmd_AddCommand (progs_t *pr)
cmd_resources_t *res = PR_Resources_Find (pr, "Cmd");
bi_cmd_t *cmd = malloc (sizeof (bi_cmd_t));
char *name = strdup (P_GSTRING (pr, 0));
func_t func = P_FUNCTION (pr, 1);
pr_func_t func = P_FUNCTION (pr, 1);
if (!cmd || !name || !Cmd_AddCommand (name, bi_cmd_f, "CSQC command")) {
if (name)
@ -145,11 +145,13 @@ bi_Cmd_Args (progs_t *pr)
//Cmd_ExecuteString
//Cmd_ForwardToServer
#define bi(x,np,params...) {#x, bi_##x, -1, np, {params}}
#define p(type) PR_PARAM(type)
static builtin_t builtins[] = {
{"Cmd_AddCommand", bi_Cmd_AddCommand, -1},
{"Cmd_Argc", bi_Cmd_Argc, -1},
{"Cmd_Argv", bi_Cmd_Argv, -1},
{"Cmd_Args", bi_Cmd_Args, -1},
bi(Cmd_AddCommand, 2, p(string), p(func)),
bi(Cmd_Argc, 0),
bi(Cmd_Argv, 1, p(int)),
bi(Cmd_Args, 1, p(int)),
{0}
};
@ -159,11 +161,11 @@ RUA_Cmd_Init (progs_t *pr, int secure)
cmd_resources_t *res = calloc (1, sizeof (cmd_resources_t));
res->cmds = 0;
PR_Resources_Register (pr, "Cmd", res, bi_cmd_clear);
if (!bi_cmds)
bi_cmds = Hash_NewTable (1021, bi_cmd_get_key, bi_cmd_free, 0,
pr->hashlink_freelist);
PR_RegisterBuiltins (pr, builtins);
PR_Resources_Register (pr, "Cmd", res, bi_cmd_clear);
PR_RegisterBuiltins (pr, builtins, res);
}

View file

@ -232,18 +232,21 @@ bi_Cvar_Toggle (progs_t *pr)
Cvar_Set (var, var->int_val ? "0" : "1");
}
#define bi(x,np,params...) {#x, bi_##x, -1, np, {params}}
#define p(type) PR_PARAM(type)
#define P(a, s) { .size = (s), .alignment = BITOP_LOG2 (a), }
static builtin_t builtins[] = {
{"Cvar_MakeAlias", bi_Cvar_MakeAlias, -1},
{"Cvar_RemoveAlias", bi_Cvar_RemoveAlias, -1},
{"Cvar_SetFloat", bi_Cvar_SetFloat, -1},
{"Cvar_SetInteger", bi_Cvar_SetInteger, -1},
{"Cvar_SetVector", bi_Cvar_SetVector, -1},
{"Cvar_SetString", bi_Cvar_SetString, -1},
{"Cvar_GetFloat", bi_Cvar_GetFloat, -1},
{"Cvar_GetInteger", bi_Cvar_GetInteger, -1},
{"Cvar_GetVector", bi_Cvar_GetVector, -1},
{"Cvar_GetString", bi_Cvar_GetString, -1},
{"Cvar_Toggle", bi_Cvar_Toggle, -1},
bi(Cvar_MakeAlias, 2, p(string), p(string)),
bi(Cvar_RemoveAlias, 1, p(string)),
bi(Cvar_SetFloat, 2, p(string), p(float)),
bi(Cvar_SetInteger, 2, p(string), p(int)),
bi(Cvar_SetVector, 2, p(string), p(vector)),
bi(Cvar_SetString, 2, p(string), p(string)),
bi(Cvar_GetFloat, 1, p(string)),
bi(Cvar_GetInteger, 1, p(string)),
bi(Cvar_GetVector, 1, p(string)),
bi(Cvar_GetString, 1, p(string)),
bi(Cvar_Toggle, 1, p(string)),
{0}
};
@ -254,6 +257,5 @@ RUA_Cvar_Init (progs_t *pr, int secure)
res->aliases = 0;
PR_Resources_Register (pr, "Cvar", res, bi_cvar_clear);
PR_RegisterBuiltins (pr, builtins);
PR_RegisterBuiltins (pr, builtins, res);
}

View file

@ -49,11 +49,11 @@ typedef struct bi_hashtab_s {
struct bi_hashtab_s **prev;
progs_t *pr;
hashtab_t *tab;
func_t gk;
func_t gh;
func_t cmp;
func_t f;
pointer_t ud;
pr_func_t gk;
pr_func_t gh;
pr_func_t cmp;
pr_func_t f;
pr_ptr_t ud;
} bi_hashtab_t;
typedef struct {
@ -95,48 +95,59 @@ static const char *
bi_get_key (const void *key, void *_ht)
{
bi_hashtab_t *ht = (bi_hashtab_t *)_ht;
PR_PushFrame (ht->pr);
PR_RESET_PARAMS (ht->pr);
P_INT (ht->pr, 0) = (intptr_t) (key);
P_INT (ht->pr, 1) = ht->ud;
ht->pr->pr_argc = 2;
PR_ExecuteProgram (ht->pr, ht->gk);
return PR_GetString (ht->pr, R_STRING (ht->pr));
pr_string_t string = R_STRING (ht->pr);
PR_PopFrame (ht->pr);
return PR_GetString (ht->pr, string);
}
static uintptr_t
bi_get_hash (const void *key, void *_ht)
{
bi_hashtab_t *ht = (bi_hashtab_t *)_ht;
PR_PushFrame (ht->pr);
PR_RESET_PARAMS (ht->pr);
P_INT (ht->pr, 0) = (intptr_t) (key);
P_INT (ht->pr, 1) = ht->ud;
ht->pr->pr_argc = 2;
PR_ExecuteProgram (ht->pr, ht->gh);
return R_INT (ht->pr);
int hash = R_INT (ht->pr);
PR_PopFrame (ht->pr);
return hash;
}
static int
bi_compare (const void *key1, const void *key2, void *_ht)
{
bi_hashtab_t *ht = (bi_hashtab_t *)_ht;
PR_PushFrame (ht->pr);
PR_RESET_PARAMS (ht->pr);
P_INT (ht->pr, 0) = (intptr_t) (key1);
P_INT (ht->pr, 1) = (intptr_t) (key2);
P_INT (ht->pr, 2) = ht->ud;
ht->pr->pr_argc = 3;
PR_ExecuteProgram (ht->pr, ht->cmp);
return R_INT (ht->pr);
int cmp = R_INT (ht->pr);
PR_PopFrame (ht->pr);
return cmp;
}
static void
bi_free (void *key, void *_ht)
{
bi_hashtab_t *ht = (bi_hashtab_t *)_ht;
PR_PushFrame (ht->pr);
PR_RESET_PARAMS (ht->pr);
P_INT (ht->pr, 0) = (intptr_t) (key);
P_INT (ht->pr, 1) = ht->ud;
ht->pr->pr_argc = 2;
PR_ExecuteProgram (ht->pr, ht->f);
PR_PopFrame (ht->pr);
}
static void
@ -259,7 +270,7 @@ bi_Hash_FindList (progs_t *pr)
pr_list = PR_Zone_Malloc (pr, count * sizeof (pr_type_t));
// the hash tables stores progs pointers...
for (count = 0, l = list; *l; l++)
pr_list[count++].integer_var = (intptr_t) *l;
pr_list[count++].int_var = (intptr_t) *l;
free (list);
RETURN_POINTER (pr, pr_list);
}
@ -278,7 +289,7 @@ bi_Hash_FindElementList (progs_t *pr)
pr_list = PR_Zone_Malloc (pr, count * sizeof (pr_type_t));
// the hash tables stores progs pointers...
for (count = 0, l = list; *l; l++)
pr_list[count++].integer_var = (intptr_t) *l;
pr_list[count++].int_var = (intptr_t) *l;
free (list);
RETURN_POINTER (pr, pr_list);
}
@ -334,7 +345,7 @@ bi_Hash_GetList (progs_t *pr)
pr_list = PR_Zone_Malloc (pr, count * sizeof (pr_type_t));
// the hash tables stores progs pointers...
for (count = 0, l = list; *l; l++)
pr_list[count++].integer_var = (intptr_t) *l;
pr_list[count++].int_var = (intptr_t) *l;
free (list);
RETURN_POINTER (pr, pr_list);
}
@ -359,24 +370,26 @@ bi_hash_clear (progs_t *pr, void *data)
table_reset (res);
}
#define bi(x,np,params...) {#x, bi_##x, -1, np, {params}}
#define p(type) PR_PARAM(type)
static builtin_t builtins[] = {
{"Hash_NewTable", bi_Hash_NewTable, -1},
{"Hash_SetHashCompare", bi_Hash_SetHashCompare, -1},
{"Hash_DelTable", bi_Hash_DelTable, -1},
{"Hash_FlushTable", bi_Hash_FlushTable, -1},
{"Hash_Add", bi_Hash_Add, -1},
{"Hash_AddElement", bi_Hash_AddElement, -1},
{"Hash_Find", bi_Hash_Find, -1},
{"Hash_FindElement", bi_Hash_FindElement, -1},
{"Hash_FindList", bi_Hash_FindList, -1},
{"Hash_FindElementList", bi_Hash_FindElementList, -1},
{"Hash_Del", bi_Hash_Del, -1},
{"Hash_DelElement", bi_Hash_DelElement, -1},
{"Hash_Free", bi_Hash_Free, -1},
{"Hash_String", bi_Hash_String, -1},
{"Hash_Buffer", bi_Hash_Buffer, -1},
{"Hash_GetList", bi_Hash_GetList, -1},
{"Hash_Stats", bi_Hash_Stats, -1},
bi(Hash_NewTable, 4, p(int), p(func), p(func), p(ptr)),
bi(Hash_SetHashCompare, 3, p(ptr), p(func), p(func)),
bi(Hash_DelTable, 1, p(ptr)),
bi(Hash_FlushTable, 1, p(ptr)),
bi(Hash_Add, 2, p(ptr), p(ptr)),
bi(Hash_AddElement, 2, p(ptr), p(ptr)),
bi(Hash_Find, 2, p(ptr), p(string)),
bi(Hash_FindElement, 2, p(ptr), p(ptr)),
bi(Hash_FindList, 2, p(ptr), p(string)),
bi(Hash_FindElementList, 2, p(ptr), p(ptr)),
bi(Hash_Del, 2, p(ptr), p(string)),
bi(Hash_DelElement, 2, p(ptr), p(ptr)),
bi(Hash_Free, 2, p(ptr), p(ptr)),
bi(Hash_String, 1, p(string)),
bi(Hash_Buffer, 2, p(ptr), p(int)),
bi(Hash_GetList, 1, p(ptr)),
bi(Hash_Stats, 1, p(ptr)),
{0}
};
@ -387,5 +400,5 @@ RUA_Hash_Init (progs_t *pr, int secure)
res->tabs = 0;
PR_Resources_Register (pr, "Hash", res, bi_hash_clear);
PR_RegisterBuiltins (pr, builtins);
PR_RegisterBuiltins (pr, builtins, res);
}

View file

@ -46,8 +46,8 @@
typedef struct rua_in_cookie_s {
size_t users;
progs_t *pr;
func_t func;
pointer_t data;
pr_func_t func;
pr_ptr_t data;
} rua_in_cookie_t;
typedef struct input_resources_s {
@ -193,7 +193,7 @@ bi_IN_GetButtonInfo (progs_t *pr)
}
static rua_in_cookie_t *
make_cookie (progs_t *pr, func_t func, pointer_t data)
make_cookie (progs_t *pr, pr_func_t func, pr_ptr_t data)
{
input_resources_t *res = PR_Resources_Find (pr, "input");
rua_in_cookie_t search = {
@ -212,7 +212,7 @@ make_cookie (progs_t *pr, func_t func, pointer_t data)
}
static rua_in_cookie_t *
find_cookie (progs_t *pr, func_t func, pointer_t data)
find_cookie (progs_t *pr, pr_func_t func, pr_ptr_t data)
{
input_resources_t *res = PR_Resources_Find (pr, "input");
rua_in_cookie_t search = {
@ -236,8 +236,8 @@ static void
rua_add_axis_listener (progs_t *pr, axis_listener_t listener)
{
in_axis_t *axis = &P_STRUCT (pr, in_axis_t, 0);
func_t func = P_FUNCTION (pr, 1);
func_t data = P_POINTER (pr, 2);
pr_func_t func = P_FUNCTION (pr, 1);
pr_func_t data = P_POINTER (pr, 2);
rua_in_cookie_t *cookie = make_cookie (pr, func, data);
IN_AxisAddListener (axis, listener, cookie);
}
@ -246,8 +246,8 @@ static void
rua_remove_axis_listener (progs_t *pr, axis_listener_t listener)
{
in_axis_t *axis = &P_STRUCT (pr, in_axis_t, 0);
func_t func = P_FUNCTION (pr, 1);
func_t data = P_POINTER (pr, 2);
pr_func_t func = P_FUNCTION (pr, 1);
pr_func_t data = P_POINTER (pr, 2);
rua_in_cookie_t *cookie = find_cookie (pr, func, data);
if (cookie) {
IN_AxisRemoveListener (axis, listener, cookie);
@ -259,8 +259,8 @@ static void
rua_add_button_listener (progs_t *pr, button_listener_t listener)
{
in_button_t *button = &P_STRUCT (pr, in_button_t, 0);
func_t func = P_FUNCTION (pr, 1);
func_t data = P_POINTER (pr, 2);
pr_func_t func = P_FUNCTION (pr, 1);
pr_func_t data = P_POINTER (pr, 2);
rua_in_cookie_t *cookie = make_cookie (pr, func, data);
IN_ButtonAddListener (button, listener, cookie);
}
@ -269,8 +269,8 @@ static void
rua_remove_button_listener (progs_t *pr, button_listener_t listener)
{
in_button_t *button = &P_STRUCT (pr, in_button_t, 0);
func_t func = P_FUNCTION (pr, 1);
func_t data = P_POINTER (pr, 2);
pr_func_t func = P_FUNCTION (pr, 1);
pr_func_t data = P_POINTER (pr, 2);
rua_in_cookie_t *cookie = find_cookie (pr, func, data);
if (cookie) {
IN_ButtonRemoveListener (button, listener, cookie);
@ -283,6 +283,7 @@ rua_listener_func (rua_in_cookie_t *cookie, const void *input)
{
progs_t *pr = cookie->pr;
PR_PushFrame (pr);
PR_RESET_PARAMS (pr);
P_POINTER (pr, 0) = cookie->data;
P_POINTER (pr, 1) = PR_SetPointer (pr, input);//FIXME check input
pr->pr_argc = 2;
@ -407,56 +408,58 @@ secured (progs_t *pr)
PR_RunError (pr, "Secured function called");
}
#define bi(x) {#x, secured, -1}
#define p(type) PR_PARAM(type)
#define P(a, s) { .size = (s), .alignment = BITOP_LOG2 (a), }
#define bi(x,np,params...) {#x, secured, -1, np, {params}}
static builtin_t secure_builtins[] = {
bi(IN_CreateButton),
bi(IN_CreateAxis),
bi(IN_LoadConfig),
bi(IN_CreateButton, 2, p(string), p(string)),
bi(IN_CreateAxis, 2, p(string), p(string)),
bi(IN_LoadConfig, 1, p(ptr)),
{0}
};
#undef bi
#define bi(x) {#x, bi_##x, -1}
#define bi(x,np,params...) {#x, bi_##x, -1, np, {params}}
static builtin_t insecure_builtins[] = {
bi(IN_CreateButton),
bi(IN_CreateAxis),
bi(IN_LoadConfig),
bi(IN_CreateButton, 2, p(string), p(string)),
bi(IN_CreateAxis, 2, p(string), p(string)),
bi(IN_LoadConfig, 1, p(ptr)),
{0}
};
static builtin_t builtins[] = {
bi(IN_FindDeviceId),
bi(IN_GetDeviceName),
bi(IN_GetDeviceId),
bi(IN_AxisInfo),
bi(IN_ButtonInfo),
bi(IN_GetAxisName),
bi(IN_GetButtonName),
bi(IN_GetAxisNumber),
bi(IN_GetButtonNumber),
bi(IN_ProcessEvents),
bi(IN_ClearStates),
bi(IN_GetAxisInfo),
bi(IN_GetButtonInfo),
bi(IN_FindDeviceId, 1, p(string)),
bi(IN_GetDeviceName, 1, p(int)),
bi(IN_GetDeviceId, 1, p(int)),
bi(IN_AxisInfo, 0), //FIXME
bi(IN_ButtonInfo, 0), //FIXME
bi(IN_GetAxisName, 2, p(int), p(int)),
bi(IN_GetButtonName, 2, p(int), p(int)),
bi(IN_GetAxisNumber, 2, p(int), p(string)),
bi(IN_GetButtonNumber, 2, p(int), p(string)),
bi(IN_ProcessEvents, 0),
bi(IN_ClearStates, 0),
bi(IN_GetAxisInfo, 3, p(int), p(int), p(ptr)),
bi(IN_GetButtonInfo, 3, p(int), p(int), p(ptr)),
{"IN_ButtonAddListener|^{tag in_button_s=}^(v^v^{tag in_button_s=})^v",
rua_IN_ButtonAddListener_func, -1},
rua_IN_ButtonAddListener_func, -1, 3, {p(ptr), p(func), p(ptr)}},
{"IN_ButtonRemoveListener|^{tag in_button_s=}^(v^v^{tag in_button_s=})^v",
rua_IN_ButtonRemoveListener_func, -1},
rua_IN_ButtonRemoveListener_func, -1, 3, {p(ptr), p(func), p(ptr)}},
{"IN_AxisAddListener|^{tag in_axis_s=}^(v^v^{tag in_axis_s=})^v",
rua_IN_AxisAddListener_func, -1},
rua_IN_AxisAddListener_func, -1, 3, {p(ptr), p(func), p(ptr)}},
{"IN_AxisRemoveListener|^{tag in_axis_s=}^(v^v^{tag in_axis_s=})^v",
rua_IN_AxisRemoveListener_func, -1},
rua_IN_AxisRemoveListener_func, -1, 3, {p(ptr), p(func), p(ptr)}},
{"IN_ButtonAddListener|^{tag in_button_s=}(@@:.)@",
rua_IN_ButtonAddListener_method, -1},
rua_IN_ButtonAddListener_method, -1, 3, {p(ptr), p(func), p(ptr)}},
{"IN_ButtonRemoveListener|^{tag in_button_s=}(@@:.)@",
rua_IN_ButtonRemoveListener_method, -1},
rua_IN_ButtonRemoveListener_method, -1, 3, {p(ptr), p(func), p(ptr)}},
{"IN_AxisAddListener|^{tag in_axis_s=}(@@:.)@",
rua_IN_AxisAddListener_method, -1},
rua_IN_AxisAddListener_method, -1, 3, {p(ptr), p(func), p(ptr)}},
{"IN_AxisRemoveListener|^{tag in_axis_s=}(@@:.)@",
rua_IN_AxisRemoveListener_method, -1},
rua_IN_AxisRemoveListener_method, -1, 3, {p(ptr), p(func), p(ptr)}},
bi(IMT_CreateContext),
bi(IMT_GetContext),
bi(IMT_SetContext),
bi(IMT_CreateContext, 1, p(string)),
bi(IMT_GetContext, 0),
bi(IMT_SetContext, 1, p(int)),
{0}
};
@ -495,17 +498,17 @@ void
RUA_Input_Init (progs_t *pr, int secure)
{
input_resources_t *res = calloc (sizeof (input_resources_t), 1);
PR_Resources_Register (pr, "input", res, bi_input_clear);
res->cookie_super = new_memsuper ();
res->cookies = Hash_NewTable (251, 0, rua_in_free_cookie, res,
&res->hash_links);
Hash_SetHashCompare (res->cookies, rua_in_hash_cookie, rua_in_cmp_cookies);
PR_Resources_Register (pr, "input", res, bi_input_clear);
if (secure & 2) {
PR_RegisterBuiltins (pr, secure_builtins);
PR_RegisterBuiltins (pr, secure_builtins, res);
} else {
PR_RegisterBuiltins (pr, insecure_builtins);
PR_RegisterBuiltins (pr, insecure_builtins, res);
}
PR_RegisterBuiltins (pr, builtins);
PR_RegisterBuiltins (pr, builtins, res);
}

View file

@ -165,18 +165,21 @@ bi_Key_StringToKeynum (progs_t *pr)
R_INT (pr) = Key_StringToKeynum (keyname);
}
#define bi(x,np,params...) {#x, bi_##x, -1, np, {params}}
#define p(type) PR_PARAM(type)
#define P(a, s) { .size = (s), .alignment = BITOP_LOG2 (a), }
static builtin_t builtins[] = {
{"Key_keydown", bi_Key_keydown, -1},
{"Key_SetBinding", bi_Key_SetBinding, -1},
{"Key_LookupBinding", bi_Key_LookupBinding, -1},
{"Key_CountBinding", bi_Key_CountBinding, -1},
{"Key_KeynumToString", bi_Key_KeynumToString, -1},
{"Key_StringToKeynum", bi_Key_StringToKeynum, -1},
bi(Key_keydown, 1, p(int)),
bi(Key_SetBinding, 3, p(string), p(int), p(string)),
bi(Key_LookupBinding, 3, p(string), p(int), p(string)),
bi(Key_CountBinding, 2, p(string), p(string)),
bi(Key_KeynumToString, 1, p(int)),
bi(Key_StringToKeynum, 1, p(string)),
{0}
};
void
RUA_Key_Init (progs_t *pr)
{
PR_RegisterBuiltins (pr, builtins);
PR_RegisterBuiltins (pr, builtins, 0);
}

View file

@ -321,57 +321,59 @@ bi_atanh (progs_t *pr)
R_DOUBLE (pr) = log ((1 + y) / (1 - y)) / 2;
}
#define bi(x,np,params...) {#x, bi_##x, -1, np, {params}}
#define p(type) PR_PARAM(type)
static builtin_t builtins[] = {
{"sin|f", bi_sinf, -1},
{"cos|f", bi_cosf, -1},
{"tan|f", bi_tanf, -1},
{"asin|f", bi_asinf, -1},
{"acos|f", bi_acosf, -1},
{"atan|f", bi_atanf, -1},
{"atan2|ff",bi_atan2f, -1},
{"exp|f", bi_expf, -1},
{"log|f", bi_logf, -1},
{"log2|f", bi_log2f, -1},
{"log10|f", bi_log10f, -1},
{"pow|ff", bi_powf, -1},
{"sqrt|f", bi_sqrtf, -1},
{"cbrt|f", bi_cbrtf, -1},
{"hypot|ff",bi_hypotf, -1},
{"sinh|f", bi_sinhf, -1},
{"cosh|f", bi_coshf, -1},
{"tanh|f", bi_tanhf, -1},
{"asinh|f", bi_asinhf, -1},
{"acosh|f", bi_acoshf, -1},
{"atanh|f", bi_atanhf, -1},
{"floor|d", bi_floor, -1}, // float version in pr_cmds
{"ceil|d", bi_ceil, -1}, // float version in pr_cmds
{"fabs|d", bi_fabs, -1}, // float version in pr_cmds
{"sin|d", bi_sin, -1},
{"cos|d", bi_cos, -1},
{"tan|d", bi_tan, -1},
{"asin|d", bi_asin, -1},
{"acos|d", bi_acos, -1},
{"atan|d", bi_atan, -1},
{"atan2|dd",bi_atan2, -1},
{"exp|d", bi_exp, -1},
{"log|d", bi_log, -1},
{"log2|d", bi_log2, -1},
{"log10|d", bi_log10, -1},
{"pow|dd", bi_pow, -1},
{"sqrt|d", bi_sqrt, -1},
{"cbrt|d", bi_cbrt, -1},
{"hypot|dd",bi_hypot, -1},
{"sinh|d", bi_sinh, -1},
{"cosh|d", bi_cosh, -1},
{"tanh|d", bi_tanh, -1},
{"asinh|d", bi_asinh, -1},
{"acosh|d", bi_acosh, -1},
{"atanh|d", bi_atanh, -1},
{"sin|f", bi_sinf, -1, 1, {p(float)}},
{"cos|f", bi_cosf, -1, 1, {p(float)}},
{"tan|f", bi_tanf, -1, 1, {p(float)}},
{"asin|f", bi_asinf, -1, 1, {p(float)}},
{"acos|f", bi_acosf, -1, 1, {p(float)}},
{"atan|f", bi_atanf, -1, 1, {p(float)}},
{"atan2|ff",bi_atan2f, -1, 2, {p(float), p(float)}},
{"exp|f", bi_expf, -1, 1, {p(float)}},
{"log|f", bi_logf, -1, 1, {p(float)}},
{"log2|f", bi_log2f, -1, 1, {p(float)}},
{"log10|f", bi_log10f, -1, 1, {p(float)}},
{"pow|ff", bi_powf, -1, 2, {p(float), p(float)}},
{"sqrt|f", bi_sqrtf, -1, 1, {p(float)}},
{"cbrt|f", bi_cbrtf, -1, 1, {p(float)}},
{"hypot|ff",bi_hypotf, -1, 2, {p(float), p(float)}},
{"sinh|f", bi_sinhf, -1, 1, {p(float)}},
{"cosh|f", bi_coshf, -1, 1, {p(float)}},
{"tanh|f", bi_tanhf, -1, 1, {p(float)}},
{"asinh|f", bi_asinhf, -1, 1, {p(float)}},
{"acosh|f", bi_acoshf, -1, 1, {p(float)}},
{"atanh|f", bi_atanhf, -1, 1, {p(float)}},
{"floor|d", bi_floor, -1, 1, {p(double)}}, // float version in pr_cmds
{"ceil|d", bi_ceil, -1, 1, {p(double)}}, // float version in pr_cmds
{"fabs|d", bi_fabs, -1, 1, {p(double)}}, // float version in pr_cmds
{"sin|d", bi_sin, -1, 1, {p(double)}},
{"cos|d", bi_cos, -1, 1, {p(double)}},
{"tan|d", bi_tan, -1, 1, {p(double)}},
{"asin|d", bi_asin, -1, 1, {p(double)}},
{"acos|d", bi_acos, -1, 1, {p(double)}},
{"atan|d", bi_atan, -1, 1, {p(double)}},
{"atan2|dd",bi_atan2, -1, 2, {p(double), p(double)}},
{"exp|d", bi_exp, -1, 1, {p(double)}},
{"log|d", bi_log, -1, 1, {p(double)}},
{"log2|d", bi_log2, -1, 1, {p(double)}},
{"log10|d", bi_log10, -1, 1, {p(double)}},
{"pow|dd", bi_pow, -1, 2, {p(double), p(double)}},
{"sqrt|d", bi_sqrt, -1, 1, {p(double)}},
{"cbrt|d", bi_cbrt, -1, 1, {p(double)}},
{"hypot|dd",bi_hypot, -1, 2, {p(double), p(double)}},
{"sinh|d", bi_sinh, -1, 1, {p(double)}},
{"cosh|d", bi_cosh, -1, 1, {p(double)}},
{"tanh|d", bi_tanh, -1, 1, {p(double)}},
{"asinh|d", bi_asinh, -1, 1, {p(double)}},
{"acosh|d", bi_acosh, -1, 1, {p(double)}},
{"atanh|d", bi_atanh, -1, 1, {p(double)}},
{0}
};
void
RUA_Math_Init (progs_t *pr, int secure)
{
PR_RegisterBuiltins (pr, builtins);
PR_RegisterBuiltins (pr, builtins, 0);
}

View file

@ -145,14 +145,15 @@ bi_mtwist_clear (progs_t *pr, void *data)
state_reset (res);
}
#define bi(x) {#x, bi_##x, -1}
#define bi(x,np,params...) {#x, bi_##x, -1, np, {params}}
#define p(type) PR_PARAM(type)
static builtin_t builtins[] = {
bi(mtwist_new),
bi(mtwist_delete),
bi(mtwist_seed),
bi(mtwist_rand),
bi(mtwist_rand_0_1),
bi(mtwist_rand_m1_1),
bi(mtwist_new, 1, p(int)),
bi(mtwist_delete, 1, p(ptr)),
bi(mtwist_seed, 2, p(ptr), p(int)),
bi(mtwist_rand, 1, p(ptr)),
bi(mtwist_rand_0_1, 1, p(ptr)),
bi(mtwist_rand_m1_1, 1, p(ptr)),
{0}
};
@ -162,5 +163,5 @@ RUA_Mersenne_Init (progs_t *pr, int secure)
mtwist_resources_t *res = calloc (1, sizeof (mtwist_resources_t));
PR_Resources_Register (pr, "Mersenne Twister", res, bi_mtwist_clear);
PR_RegisterBuiltins (pr, builtins);
PR_RegisterBuiltins (pr, builtins, res);
}

View file

@ -396,46 +396,49 @@ bi_MsgBuf_ReadUTF8 (progs_t *pr)
R_INT (pr) = MSG_ReadUTF8 (&mb->msg);
}
#define bi(x,np,params...) {#x, bi_##x, -1, np, {params}}
#define p(type) PR_PARAM(type)
#define P(a, s) { .size = (s), .alignment = BITOP_LOG2 (a), }
static builtin_t builtins[] = {
{"MsgBuf_New", bi_MsgBuf_New, -1},
{"MsgBuf_Delete", bi_MsgBuf_Delete, -1},
{"MsgBuf_FromFile", bi_MsgBuf_FromFile, -1},
{"MsgBuf_MaxSize", bi_MsgBuf_MaxSize, -1},
{"MsgBuf_CurSize", bi_MsgBuf_CurSize, -1},
{"MsgBuf_ReadCount", bi_MsgBuf_ReadCount, -1},
{"MsgBuf_DataPtr", bi_MsgBuf_DataPtr, -1},
bi(MsgBuf_New, 1, p(int)),
bi(MsgBuf_Delete, 1, p(ptr)),
bi(MsgBuf_FromFile, 2, p(ptr), p(ptr)),
bi(MsgBuf_MaxSize, 1, p(ptr)),
bi(MsgBuf_CurSize, 1, p(ptr)),
bi(MsgBuf_ReadCount, 1, p(ptr)),
bi(MsgBuf_DataPtr, 1, p(ptr)),
{"MsgBuf_Clear", bi_MsgBuf_Clear, -1},
{"MsgBuf_WriteByte", bi_MsgBuf_WriteByte, -1},
{"MsgBuf_WriteShort", bi_MsgBuf_WriteShort, -1},
{"MsgBuf_WriteLong", bi_MsgBuf_WriteLong, -1},
{"MsgBuf_WriteFloat", bi_MsgBuf_WriteFloat, -1},
{"MsgBuf_WriteString", bi_MsgBuf_WriteString, -1},
// {"MsgBuf_WriteBytes", bi_MsgBuf_WriteBytes, -1},
{"MsgBuf_WriteCoord", bi_MsgBuf_WriteCoord, -1},
{"MsgBuf_WriteCoordV", bi_MsgBuf_WriteCoordV, -1},
{"MsgBuf_WriteCoordAngleV", bi_MsgBuf_WriteCoordAngleV, -1},
{"MsgBuf_WriteAngle", bi_MsgBuf_WriteAngle, -1},
{"MsgBuf_WriteAngleV", bi_MsgBuf_WriteAngleV, -1},
{"MsgBuf_WriteAngle16", bi_MsgBuf_WriteAngle16, -1},
{"MsgBuf_WriteAngle16V", bi_MsgBuf_WriteAngle16V, -1},
{"MsgBuf_WriteUTF8", bi_MsgBuf_WriteUTF8, -1},
bi(MsgBuf_Clear, 1, p(ptr)),
bi(MsgBuf_WriteByte, 2, p(ptr), p(int)),
bi(MsgBuf_WriteShort, 2, p(ptr), p(int)),
bi(MsgBuf_WriteLong, 2, p(ptr), p(int)),
bi(MsgBuf_WriteFloat, 2, p(ptr), p(float)),
bi(MsgBuf_WriteString, 2, p(ptr), p(string)),
// bi(MsgBuf_WriteBytes, _, _),
bi(MsgBuf_WriteCoord, 2, p(ptr), p(float)),
bi(MsgBuf_WriteCoordV, 2, p(ptr), p(vector)),
bi(MsgBuf_WriteCoordAngleV, 2, p(ptr), p(vector)),
bi(MsgBuf_WriteAngle, 2, p(ptr), p(float)),
bi(MsgBuf_WriteAngleV, 2, p(ptr), p(vector)),
bi(MsgBuf_WriteAngle16, 2, p(ptr), p(float)),
bi(MsgBuf_WriteAngle16V, 2, p(ptr), p(vector)),
bi(MsgBuf_WriteUTF8, 2, p(ptr), p(int)),
{"MsgBuf_BeginReading", bi_MsgBuf_BeginReading, -1},
{"MsgBuf_ReadByte", bi_MsgBuf_ReadByte, -1},
{"MsgBuf_ReadShort", bi_MsgBuf_ReadShort, -1},
{"MsgBuf_ReadLong", bi_MsgBuf_ReadLong, -1},
{"MsgBuf_ReadFloat", bi_MsgBuf_ReadFloat, -1},
{"MsgBuf_ReadString", bi_MsgBuf_ReadString, -1},
// {"MsgBuf_ReadBytes", bi_MsgBuf_ReadBytes, -1},
{"MsgBuf_ReadCoord", bi_MsgBuf_ReadCoord, -1},
{"MsgBuf_ReadCoordV", bi_MsgBuf_ReadCoordV, -1},
{"MsgBuf_ReadCoordAngleV", bi_MsgBuf_ReadCoordAngleV, -1},
{"MsgBuf_ReadAngle", bi_MsgBuf_ReadAngle, -1},
{"MsgBuf_ReadAngleV", bi_MsgBuf_ReadAngleV, -1},
{"MsgBuf_ReadAngle16", bi_MsgBuf_ReadAngle16, -1},
{"MsgBuf_ReadAngle16V", bi_MsgBuf_ReadAngle16V, -1},
{"MsgBuf_ReadUTF8", bi_MsgBuf_ReadUTF8, -1},
bi(MsgBuf_BeginReading, 1, p(ptr)),
bi(MsgBuf_ReadByte, 1, p(ptr)),
bi(MsgBuf_ReadShort, 1, p(ptr)),
bi(MsgBuf_ReadLong, 1, p(ptr)),
bi(MsgBuf_ReadFloat, 1, p(ptr)),
bi(MsgBuf_ReadString, 1, p(ptr)),
// bi(MsgBuf_ReadBytes, _, _),
bi(MsgBuf_ReadCoord, 1, p(ptr)),
bi(MsgBuf_ReadCoordV, 1, p(ptr)),
bi(MsgBuf_ReadCoordAngleV, 2, p(ptr), p(ptr)),
bi(MsgBuf_ReadAngle, 1, p(ptr)),
bi(MsgBuf_ReadAngleV, 1, p(ptr)),
bi(MsgBuf_ReadAngle16, 1, p(ptr)),
bi(MsgBuf_ReadAngle16V, 1, p(ptr)),
bi(MsgBuf_ReadUTF8, 1, p(ptr)),
{0}
};
@ -445,5 +448,5 @@ RUA_MsgBuf_Init (progs_t *pr, int secure)
msgbuf_resources_t *res = calloc (sizeof (msgbuf_resources_t), 1);
PR_Resources_Register (pr, "MsgBuf", res, bi_msgbuf_clear);
PR_RegisterBuiltins (pr, builtins);
PR_RegisterBuiltins (pr, builtins, res);
}

View file

@ -48,16 +48,49 @@
#include "QF/dstring.h"
#include "QF/hash.h"
#include "QF/mathlib.h"
#include "QF/pr_obj.h"
#include "QF/progs.h"
#include "QF/ruamoko.h"
#include "QF/sys.h"
#include "QF/progs/pr_obj.h"
#include "QF/progs/pr_type.h"
#include "compat.h"
#include "rua_internal.h"
#define always_inline inline __attribute__((__always_inline__))
/* Macros to help with setting up to call a function, and cleaning up
* afterwards. The problem is that PR_CallFunction saves the CURRENT stack
* pointer, which has been adjusted by PR_SetupParams in order to push
* the function arguments.
*
* RUA_CALL_BEGIN and RUA_CALL_END must be used in pairs and this is enforced
* by the unbalanced {}s in the macros.
*/
#define RUA_CALL_BEGIN(pr, argc) \
{ \
pr_ptr_t saved_stack = 0; \
int call_depth = (pr)->pr_depth; \
if ((pr)->globals.stack) { \
saved_stack = *(pr)->globals.stack; \
} \
PR_SetupParams (pr, argc, 1); \
(pr)->pr_argc = argc;
#define RUA_CALL_END(pr, imp) \
if (PR_CallFunction ((pr), (imp), (pr)->pr_return)) { \
/* the call is to a progs function so a frame was pushed, */ \
/* ensure the stack pointer is restored on return */ \
/* if there's no stack, then the following is effectively a */ \
/* noop */ \
(pr)->pr_stack[call_depth].stack_ptr = saved_stack; \
} else if ((pr)->globals.stack) { \
/* the call was to a builtin, restore the stack */ \
*(pr)->globals.stack = saved_stack; \
} \
}
typedef struct obj_list_s {
struct obj_list_s *next;
void *data;
@ -67,7 +100,7 @@ typedef struct dtable_s {
struct dtable_s *next;
struct dtable_s **prev;
size_t size;
func_t *imp;
pr_func_t *imp;
} dtable_t;
typedef struct probj_resources_s {
@ -75,10 +108,11 @@ typedef struct probj_resources_s {
unsigned selector_index;
unsigned selector_index_max;
obj_list **selector_sels;
string_t *selector_names;
pr_string_t *selector_names;
pr_int_t *selector_argc;
PR_RESMAP (dtable_t) dtables;
dtable_t *dtable_list;
func_t obj_forward;
pr_func_t obj_forward;
pr_sel_t *forward_selector;
dstring_t *msg;
hashtab_t *selector_hash;
@ -422,7 +456,7 @@ object_is_instance (probj_t *probj, pr_id_t *object)
return 0;
}
static string_t
static pr_string_t
object_get_class_name (probj_t *probj, pr_id_t *object)
{
progs_t *pr = probj->pr;
@ -445,7 +479,7 @@ object_get_class_name (probj_t *probj, pr_id_t *object)
//====================================================================
static void
finish_class (probj_t *probj, pr_class_t *class, pointer_t object_ptr)
finish_class (probj_t *probj, pr_class_t *class, pr_ptr_t object_ptr)
{
progs_t *pr = probj->pr;
pr_class_t *meta = &G_STRUCT (pr, pr_class_t, class->class_pointer);
@ -462,7 +496,7 @@ finish_class (probj_t *probj, pr_class_t *class, pointer_t object_ptr)
meta->super_class = val->class_pointer;
class->super_class = PR_SetPointer (pr, val);
} else {
pointer_t *ml = &meta->methods;
pr_ptr_t *ml = &meta->methods;
while (*ml)
ml = &G_STRUCT (pr, pr_method_list_t, *ml).method_next;
*ml = class->methods;
@ -484,10 +518,13 @@ add_sel_name (probj_t *probj, const char *name)
probj->selector_sels = realloc (probj->selector_sels,
size * sizeof (obj_list *));
probj->selector_names = realloc (probj->selector_names,
size * sizeof (string_t));
size * sizeof (pr_string_t));
probj->selector_argc = realloc (probj->selector_argc,
size * sizeof (pr_int_t));
for (i = probj->selector_index_max; i < size; i++) {
probj->selector_sels[i] = 0;
probj->selector_names[i] = 0;
probj->selector_argc[i] = 0;
}
probj->selector_index_max = size;
}
@ -541,6 +578,15 @@ sel_register_typed_name (probj_t *probj, const char *name, const char *types,
l->next = probj->selector_sels[index];
probj->selector_sels[index] = l;
if (sel->sel_types && pr->type_encodings) {
const char *enc = PR_GetString (pr, sel->sel_types);
__auto_type type = (qfot_type_t *) Hash_Find (pr->type_hash, enc);
if (type->meta != ty_basic || type->type != ev_func) {
PR_RunError (pr, "selector type encoing is not a function");
}
probj->selector_argc[index] = type->func.num_params;
}
if (is_new)
Hash_Add (probj->selector_hash, (void *) index);
done:
@ -804,7 +850,7 @@ obj_find_message (probj_t *probj, pr_class_t *class, pr_sel_t *selector)
pr_sel_t *sel;
int i;
int dev = developer->int_val;
string_t *names;
pr_string_t *names;
if (dev & SYS_rua_msg) {
names = probj->selector_names;
@ -935,7 +981,7 @@ obj_install_dispatch_table_for_class (probj_t *probj, pr_class_t *class)
dtable = dtable_new (probj);
class->dtable = dtable_index (probj, dtable);
dtable->size = probj->selector_index + 1;
dtable->imp = calloc (dtable->size, sizeof (func_t));
dtable->imp = calloc (dtable->size, sizeof (pr_func_t));
if (super) {
dtable_t *super_dtable = get_dtable (probj, __FUNCTION__,
super->dtable);
@ -956,10 +1002,10 @@ obj_check_dtable_installed (probj_t *probj, pr_class_t *class)
return get_dtable (probj, __FUNCTION__, class->dtable);
}
static func_t
static pr_func_t
get_imp (probj_t *probj, pr_class_t *class, pr_sel_t *sel)
{
func_t imp = 0;
pr_func_t imp = 0;
if (class->dtable) {
dtable_t *dtable = get_dtable (probj, __FUNCTION__, class->dtable);
@ -984,7 +1030,7 @@ obj_reponds_to (probj_t *probj, pr_id_t *obj, pr_sel_t *sel)
progs_t *pr = probj->pr;
pr_class_t *class;
dtable_t *dtable;
func_t imp = 0;
pr_func_t imp = 0;
class = &G_STRUCT (pr, pr_class_t, obj->class_pointer);
dtable = obj_check_dtable_installed (probj, class);
@ -995,7 +1041,7 @@ obj_reponds_to (probj_t *probj, pr_id_t *obj, pr_sel_t *sel)
return imp != 0;
}
static func_t
static pr_func_t
obj_msg_lookup (probj_t *probj, pr_id_t *receiver, pr_sel_t *op)
{
progs_t *pr = probj->pr;
@ -1014,7 +1060,7 @@ obj_msg_lookup (probj_t *probj, pr_id_t *receiver, pr_sel_t *op)
return get_imp (probj, class, op);
}
static func_t
static pr_func_t
obj_msg_lookup_super (probj_t *probj, pr_super_t *super, pr_sel_t *op)
{
progs_t *pr = probj->pr;
@ -1040,7 +1086,7 @@ obj_verror (probj_t *probj, pr_id_t *object, int code, const char *fmt, int coun
}
static void
dump_ivars (probj_t *probj, pointer_t _ivars)
dump_ivars (probj_t *probj, pr_ptr_t _ivars)
{
progs_t *pr = probj->pr;
pr_ivar_list_t *ivars;
@ -1062,8 +1108,8 @@ obj_init_statics (probj_t *probj)
{
progs_t *pr = probj->pr;
obj_list **cell = &probj->uninitialized_statics;
pointer_t *ptr;
pointer_t *inst;
pr_ptr_t *ptr;
pr_ptr_t *inst;
Sys_MaskPrintf (SYS_rua_obj, "Initializing statics\n");
while (*cell) {
@ -1109,7 +1155,7 @@ rua___obj_exec_class (progs_t *pr)
pr_module_t *module = &P_STRUCT (pr, pr_module_t, 0);
pr_symtab_t *symtab;
pr_sel_t *sel;
pointer_t *ptr;
pr_ptr_t *ptr;
int i;
obj_list **cell;
@ -1215,7 +1261,7 @@ rua___obj_exec_class (progs_t *pr)
if (*ptr) {
Sys_MaskPrintf (SYS_rua_obj, "Static instances lists: %x\n", *ptr);
probj->uninitialized_statics
= list_cons (&G_STRUCT (pr, pointer_t, *ptr),
= list_cons (&G_STRUCT (pr, pr_ptr_t, *ptr),
probj->uninitialized_statics);
}
if (probj->uninitialized_statics) {
@ -1259,7 +1305,7 @@ rua___obj_forward (progs_t *pr)
pr_sel_t *fwd_sel = probj->forward_selector;
pr_sel_t *err_sel;
pr_class_t *class =&G_STRUCT (pr, pr_class_t, obj->class_pointer);
func_t imp;
pr_func_t imp;
if (!fwd_sel) {
//FIXME sel_register_typed_name is really not the way to go about
@ -1270,39 +1316,53 @@ rua___obj_forward (progs_t *pr)
if (obj_reponds_to (probj, obj, fwd_sel)) {
imp = get_imp (probj, class, fwd_sel);
// forward:(SEL) sel :(@va_list) args
// args is full param list
//FIXME oh for a stack
size_t parm_size = pr->pr_param_size * sizeof(pr_type_t);
size_t size = pr->pr_argc * parm_size;
string_t args_block = PR_AllocTempBlock (pr, size);
// args is full param list as a va_list
pr_string_t args_block = 0;
int argc;
pr_type_t *argv;
if (pr->globals.stack) {
argv = pr->pr_params[0];
argc = probj->selector_argc[sel->sel_id];
if (argc < 0) {
// -ve values indicate varargs functions and is the ones
// complement of the number of real parameters before the
// ellipsis. However, Ruamoko ISA progs pass va_list through
// ... so in the end, a -ve value indicates the total number
// of arguments (including va_list) passed to the function.
argc = -argc;
}
} else {
size_t parm_size = pr->pr_param_size * sizeof(pr_type_t);
size_t size = pr->pr_argc * parm_size;
args_block = PR_AllocTempBlock (pr, size);
int argc = pr->pr_argc;
__auto_type argv = (pr_type_t *) PR_GetString (pr, args_block);
// can't memcpy all params because 0 and 1 could be anywhere
memcpy (argv + 0, &P_INT (pr, 0), 4 * sizeof (pr_type_t));
memcpy (argv + 4, &P_INT (pr, 1), 4 * sizeof (pr_type_t));
memcpy (argv + 8, &P_INT (pr, 2), (argc - 2) * parm_size);
argc = pr->pr_argc;
argv = (pr_type_t *) PR_GetString (pr, args_block);
// can't memcpy all params because 0 and 1 could be anywhere
memcpy (argv + 0, &P_INT (pr, 0), 4 * sizeof (pr_type_t));
memcpy (argv + 4, &P_INT (pr, 1), 4 * sizeof (pr_type_t));
memcpy (argv + 8, &P_INT (pr, 2), (argc - 2) * parm_size);
}
PR_RESET_PARAMS (pr);
RUA_CALL_BEGIN (pr, 4);
P_POINTER (pr, 0) = PR_SetPointer (pr, obj);
P_POINTER (pr, 1) = PR_SetPointer (pr, fwd_sel);
P_POINTER (pr, 2) = PR_SetPointer (pr, sel);
P_PACKED (pr, pr_va_list_t, 3).count = argc;
P_PACKED (pr, pr_va_list_t, 3).list = PR_SetPointer (pr, argv);
PR_PushTempString (pr, args_block);
PR_CallFunction (pr, imp);
if (args_block) {
PR_PushTempString (pr, args_block);
}
RUA_CALL_END (pr, imp);
return;
}
//FIXME ditto
err_sel = sel_register_typed_name (probj, "doesNotRecognize:", "", 0);
if (obj_reponds_to (probj, obj, err_sel)) {
imp = get_imp (probj, class, err_sel);
PR_RESET_PARAMS (pr);
RUA_CALL_BEGIN (pr, 3)
P_POINTER (pr, 0) = PR_SetPointer (pr, obj);
P_POINTER (pr, 1) = PR_SetPointer (pr, err_sel);
P_POINTER (pr, 2) = PR_SetPointer (pr, sel);
pr->pr_argc = 3;
PR_CallFunction (pr, imp);
RUA_CALL_END (pr, get_imp (probj, class, err_sel))
return;
}
@ -1311,16 +1371,13 @@ rua___obj_forward (progs_t *pr)
PR_GetString (pr, class->name),
PR_GetString (pr, probj->selector_names[sel->sel_id]));
//FIXME ditto
err_sel = sel_register_typed_name (probj, "error:", "", 0);
if (obj_reponds_to (probj, obj, err_sel)) {
imp = get_imp (probj, class, err_sel);
PR_RESET_PARAMS (pr);
RUA_CALL_BEGIN (pr, 3)
P_POINTER (pr, 0) = PR_SetPointer (pr, obj);
P_POINTER (pr, 1) = PR_SetPointer (pr, err_sel);
P_POINTER (pr, 2) = PR_SetTempString (pr, probj->msg->str);
pr->pr_argc = 3;
PR_CallFunction (pr, imp);
RUA_CALL_END (pr, get_imp (probj, class, err_sel))
return;
}
@ -1371,7 +1428,7 @@ static void
rua_obj_set_error_handler (progs_t *pr)
{
//probj_t *probj = pr->pr_objective_resources;
//func_t func = P_INT (pr, 0);
//pr_func_t func = P_INT (pr, 0);
//arglist
//XXX
PR_RunError (pr, "%s, not implemented", __FUNCTION__);
@ -1401,17 +1458,17 @@ static void
rua_obj_msg_sendv (progs_t *pr)
{
probj_t *probj = pr->pr_objective_resources;
pointer_t obj = P_POINTER (pr, 0);
pr_ptr_t obj = P_POINTER (pr, 0);
pr_id_t *receiver = &P_STRUCT (pr, pr_id_t, 0);
pointer_t sel = P_POINTER (pr, 1);
pr_ptr_t sel = P_POINTER (pr, 1);
pr_sel_t *op = &P_STRUCT (pr, pr_sel_t, 1);
func_t imp = obj_msg_lookup (probj, receiver, op);
pr_func_t imp = obj_msg_lookup (probj, receiver, op);
__auto_type args = &P_PACKED (pr, pr_va_list_t, 2);
int count = args->count;
pr_type_t *params = G_GPOINTER (pr, args->list);
if (count < 2 || count > MAX_PARMS) {
if (count < 2 || count > PR_MAX_PARAMS) {
PR_RunError (pr, "bad args count in obj_msg_sendv: %d", count);
}
if (pr_boundscheck->int_val) {
@ -1424,40 +1481,40 @@ rua_obj_msg_sendv (progs_t *pr)
PR_GetString (pr, probj->selector_names[op->sel_id]));
}
pr->pr_argc = count;
RUA_CALL_BEGIN (pr, count)
// skip over the first two parameters because receiver and op will
// replace them
count -= 2;
params += 2 * pr->pr_param_size;
PR_RESET_PARAMS (pr);
P_POINTER (pr, 0) = obj;
P_POINTER (pr, 1) = sel;
if (count) {
memcpy (&P_INT (pr, 2), params,
count * sizeof (pr_type_t) * pr->pr_param_size);
}
PR_CallFunction (pr, imp);
RUA_CALL_END (pr, imp)
}
static void
rua_obj_increment_retaincount (progs_t *pr)
{
pr_type_t *obj = &P_STRUCT (pr, pr_type_t, 0);
R_INT (pr) = ++(*--obj).integer_var;
R_INT (pr) = ++(*--obj).int_var;
}
static void
rua_obj_decrement_retaincount (progs_t *pr)
{
pr_type_t *obj = &P_STRUCT (pr, pr_type_t, 0);
R_INT (pr) = --(*--obj).integer_var;
R_INT (pr) = --(*--obj).int_var;
}
static void
rua_obj_get_retaincount (progs_t *pr)
{
pr_type_t *obj = &P_STRUCT (pr, pr_type_t, 0);
R_INT (pr) = (*--obj).integer_var;
R_INT (pr) = (*--obj).int_var;
}
static void
@ -1529,12 +1586,15 @@ rua_obj_msgSend (progs_t *pr)
probj_t *probj = pr->pr_objective_resources;
pr_id_t *self = &P_STRUCT (pr, pr_id_t, 0);
pr_sel_t *_cmd = &P_STRUCT (pr, pr_sel_t, 1);
func_t imp;
pr_func_t imp;
if (!self) {
R_INT (pr) = P_INT (pr, 0);
return;
}
if (P_UINT (pr, 0) >= pr->globals_size) {
PR_RunError (pr, "invalid self: %x", P_UINT (pr, 0));
}
if (!_cmd)
PR_RunError (pr, "null selector");
imp = obj_msg_lookup (probj, self, _cmd);
@ -1543,7 +1603,7 @@ rua_obj_msgSend (progs_t *pr)
PR_GetString (pr, object_get_class_name (probj, self)),
PR_GetString (pr, probj->selector_names[_cmd->sel_id]));
PR_CallFunction (pr, imp);
PR_CallFunction (pr, imp, pr->pr_return);
}
static void
@ -1552,7 +1612,7 @@ rua_obj_msgSend_super (progs_t *pr)
probj_t *probj = pr->pr_objective_resources;
pr_super_t *super = &P_STRUCT (pr, pr_super_t, 0);
pr_sel_t *_cmd = &P_STRUCT (pr, pr_sel_t, 1);
func_t imp;
pr_func_t imp;
imp = obj_msg_lookup_super (probj, super, _cmd);
if (!imp) {
@ -1561,9 +1621,11 @@ rua_obj_msgSend_super (progs_t *pr)
PR_GetString (pr, object_get_class_name (probj, self)),
PR_GetString (pr, probj->selector_names[_cmd->sel_id]));
}
pr->pr_params[0] = pr->pr_real_params[0];
if (pr->progs->version < PROG_VERSION) {
pr->pr_params[0] = pr->pr_real_params[0];
}
P_POINTER (pr, 0) = super->self;
PR_CallFunction (pr, imp);
PR_CallFunction (pr, imp, pr->pr_return);
}
static void
@ -1678,12 +1740,12 @@ rua_class_pose_as (progs_t *pr)
{
pr_class_t *impostor = &P_STRUCT (pr, pr_class_t, 0);
pr_class_t *superclass = &P_STRUCT (pr, pr_class_t, 1);
pointer_t *subclass;
pr_ptr_t *subclass;
subclass = &superclass->subclass_list;
while (*subclass) {
pr_class_t *sub = &P_STRUCT (pr, pr_class_t, *subclass);
pointer_t nextSub = sub->sibling_class;
pr_ptr_t nextSub = sub->sibling_class;
if (sub != impostor) {
sub->sibling_class = impostor->subclass_list;
sub->super_class = P_POINTER (pr, 0); // impostor
@ -2077,73 +2139,76 @@ rua_PR_FindGlobal (progs_t *pr)
//====================================================================
#define bi(x,np,params...) {#x, rua_##x, -1, np, {params}}
#define p(type) PR_PARAM(type)
#define P(a, s) { .size = (s), .alignment = BITOP_LOG2 (a), }
static builtin_t obj_methods [] = {
{"__obj_exec_class", rua___obj_exec_class, -1},
{"__obj_forward", rua___obj_forward, -1},
{"__obj_responds_to", rua___obj_responds_to, -1},
bi(__obj_exec_class, 1, p(ptr)),
bi(__obj_forward, -3, p(ptr), p(ptr)),
bi(__obj_responds_to, 2, p(ptr), p(ptr)),
{"obj_error", rua_obj_error, -1},
{"obj_verror", rua_obj_verror, -1},
{"obj_set_error_handler", rua_obj_set_error_handler, -1},
{"obj_msg_lookup", rua_obj_msg_lookup, -1},
{"obj_msg_lookup_super", rua_obj_msg_lookup_super, -1},
{"obj_msg_sendv", rua_obj_msg_sendv, -1},
{"obj_increment_retaincount", rua_obj_increment_retaincount, -1},
{"obj_decrement_retaincount", rua_obj_decrement_retaincount, -1},
{"obj_get_retaincount", rua_obj_get_retaincount, -1},
{"obj_malloc", rua_obj_malloc, -1},
{"obj_atomic_malloc", rua_obj_atomic_malloc, -1},
{"obj_valloc", rua_obj_valloc, -1},
{"obj_realloc", rua_obj_realloc, -1},
{"obj_calloc", rua_obj_calloc, -1},
{"obj_free", rua_obj_free, -1},
{"obj_get_uninstalled_dtable", rua_obj_get_uninstalled_dtable, -1},
{"obj_msgSend", rua_obj_msgSend, -1},
{"obj_msgSend_super", rua_obj_msgSend_super, -1},
bi(obj_error, -4, p(ptr), p(int), p(string)),
bi(obj_verror, 4, p(ptr), p(int), p(string), P(1, 2)),
bi(obj_set_error_handler, 1, p(func)),
bi(obj_msg_lookup, 2, p(ptr), p(ptr)),
bi(obj_msg_lookup_super, 2, p(ptr), p(ptr)),
bi(obj_msg_sendv, 3, p(ptr), p(ptr), P(1, 2)),
bi(obj_increment_retaincount, 1, p(ptr)),
bi(obj_decrement_retaincount, 1, p(ptr)),
bi(obj_get_retaincount, 1, p(ptr)),
bi(obj_malloc, 1, p(int)),
bi(obj_atomic_malloc, 1, p(int)),
bi(obj_valloc, 1, p(int)),
bi(obj_realloc, 2, p(ptr), p(int)),
bi(obj_calloc, 2, p(int), p(int)),
bi(obj_free, 1, p(ptr)),
bi(obj_get_uninstalled_dtable, 0),
bi(obj_msgSend, 2, p(ptr), p(ptr)),//magic
bi(obj_msgSend_super, 2, p(ptr), p(ptr)),//magic
{"obj_get_class", rua_obj_get_class, -1},
{"obj_lookup_class", rua_obj_lookup_class, -1},
{"obj_next_class", rua_obj_next_class, -1},
bi(obj_get_class, 1, p(string)),
bi(obj_lookup_class, 1, p(string)),
bi(obj_next_class, 1, p(ptr)),
{"sel_get_name", rua_sel_get_name, -1},
{"sel_get_type", rua_sel_get_type, -1},
{"sel_get_uid", rua_sel_get_uid, -1},
{"sel_register_name", rua_sel_register_name, -1},
{"sel_is_mapped", rua_sel_is_mapped, -1},
bi(sel_get_name, 1, p(ptr)),
bi(sel_get_type, 1, p(ptr)),
bi(sel_get_uid, 1, p(string)),
bi(sel_register_name, 1, p(string)),
bi(sel_is_mapped, 1, p(ptr)),
{"class_get_class_method", rua_class_get_class_method, -1},
{"class_get_instance_method", rua_class_get_instance_method, -1},
{"class_pose_as", rua_class_pose_as, -1},
{"class_create_instance", rua_class_create_instance, -1},
{"class_get_class_name", rua_class_get_class_name, -1},
{"class_get_instance_size", rua_class_get_instance_size, -1},
{"class_get_meta_class", rua_class_get_meta_class, -1},
{"class_get_super_class", rua_class_get_super_class, -1},
{"class_get_version", rua_class_get_version, -1},
{"class_is_class", rua_class_is_class, -1},
{"class_is_meta_class", rua_class_is_meta_class, -1},
{"class_set_version", rua_class_set_version, -1},
{"class_get_gc_object_type", rua_class_get_gc_object_type, -1},
{"class_ivar_set_gcinvisible", rua_class_ivar_set_gcinvisible, -1},
bi(class_get_class_method, 2, p(ptr), p(ptr)),
bi(class_get_instance_method, 2, p(ptr), p(ptr)),
bi(class_pose_as, 2, p(ptr), p(ptr)),
bi(class_create_instance, 1, p(ptr)),
bi(class_get_class_name, 1, p(ptr)),
bi(class_get_instance_size, 1, p(ptr)),
bi(class_get_meta_class, 1, p(ptr)),
bi(class_get_super_class, 1, p(ptr)),
bi(class_get_version, 1, p(ptr)),
bi(class_is_class, 1, p(ptr)),
bi(class_is_meta_class, 1, p(ptr)),
bi(class_set_version, 2, p(ptr), p(int)),
bi(class_get_gc_object_type, 1, p(ptr)),
bi(class_ivar_set_gcinvisible, 3, p(ptr), p(string), p(int)),
{"method_get_imp", rua_method_get_imp, -1},
{"get_imp", rua_get_imp, -1},
bi(method_get_imp, 1, p(ptr)),
bi(get_imp, 1, p(ptr), p(ptr)),
{"object_copy", rua_object_copy, -1},
{"object_dispose", rua_object_dispose, -1},
{"object_get_class", rua_object_get_class, -1},
{"object_get_class_name", rua_object_get_class_name, -1},
{"object_get_meta_class", rua_object_get_meta_class, -1},
{"object_get_super_class", rua_object_get_super_class, -1},
{"object_is_class", rua_object_is_class, -1},
{"object_is_instance", rua_object_is_instance, -1},
{"object_is_meta_class", rua_object_is_meta_class, -1},
bi(object_copy, 1, p(ptr)),
bi(object_dispose, 1, p(ptr)),
bi(object_get_class, 1, p(ptr)),
bi(object_get_class_name, 1, p(ptr)),
bi(object_get_meta_class, 1, p(ptr)),
bi(object_get_super_class, 1, p(ptr)),
bi(object_is_class, 1, p(ptr)),
bi(object_is_instance, 1, p(ptr)),
bi(object_is_meta_class, 1, p(ptr)),
{"_i_Object__hash", rua__i_Object__hash, -1},
{"_i_Object_error_error_", rua__i_Object_error_error_, -1},
{"_c_Object__conformsToProtocol_", rua__c_Object__conformsToProtocol_, -1},
bi(_i_Object__hash, 2, p(ptr), p(ptr)),
bi(_i_Object_error_error_, -4, p(ptr), p(ptr), p(string)),
bi(_c_Object__conformsToProtocol_, 3, p(ptr), p(ptr), p(ptr)),
{"PR_FindGlobal", rua_PR_FindGlobal, -1},//FIXME
bi(PR_FindGlobal, 1, p(string)),//FIXME
{0}
};
@ -2156,7 +2221,7 @@ rua_init_finish (progs_t *pr)
class_list = (pr_class_t **) Hash_GetList (probj->classes);
if (*class_list) {
pr_class_t *object_class;
pointer_t object_ptr;
pr_ptr_t object_ptr;
object_class = Hash_Find (probj->classes, "Object");
if (object_class && !object_class->super_class)
@ -2241,19 +2306,18 @@ RUA_Obj_Init (progs_t *pr, int secure)
load_methods_compare);
PR_Resources_Register (pr, "RUA_ObjectiveQuakeC", probj, rua_obj_cleanup);
PR_RegisterBuiltins (pr, obj_methods);
PR_RegisterBuiltins (pr, obj_methods, probj);
PR_AddLoadFunc (pr, rua_obj_init_runtime);
}
func_t
RUA_Obj_msg_lookup (progs_t *pr, pointer_t _self, pointer_t __cmd)
pr_func_t
RUA_Obj_msg_lookup (progs_t *pr, pr_ptr_t _self, pr_ptr_t __cmd)
{
probj_t *probj = pr->pr_objective_resources;
pr_id_t *self = &G_STRUCT (pr, pr_id_t, _self);
pr_sel_t *_cmd = &G_STRUCT (pr, pr_sel_t, __cmd);
func_t imp;
pr_func_t imp;
if (!self)
return 0;

View file

@ -444,28 +444,30 @@ plist_compare (const void *k1, const void *k2, void *unused)
return pl1->plitem == pl2->plitem;
}
#define bi(x,np,params...) {#x, bi_##x, -1, np, {params}}
#define p(type) PR_PARAM(type)
static builtin_t builtins[] = {
{"PL_GetFromFile", bi_PL_GetFromFile, -1},
{"PL_GetPropertyList", bi_PL_GetPropertyList, -1},
{"PL_WritePropertyList", bi_PL_WritePropertyList, -1},
{"PL_Type", bi_PL_Type, -1},
{"PL_Line", bi_PL_Line, -1},
{"PL_String", bi_PL_String, -1},
{"PL_ObjectForKey", bi_PL_ObjectForKey, -1},
{"PL_RemoveObjectForKey", bi_PL_RemoveObjectForKey, -1},
{"PL_ObjectAtIndex", bi_PL_ObjectAtIndex, -1},
{"PL_D_AllKeys", bi_PL_D_AllKeys, -1},
{"PL_D_NumKeys", bi_PL_D_NumKeys, -1},
{"PL_D_AddObject", bi_PL_D_AddObject, -1},
{"PL_A_AddObject", bi_PL_A_AddObject, -1},
{"PL_A_NumObjects", bi_PL_A_NumObjects, -1},
{"PL_A_InsertObjectAtIndex", bi_PL_A_InsertObjectAtIndex, -1},
{"PL_RemoveObjectAtIndex", bi_PL_RemoveObjectAtIndex, -1},
{"PL_NewDictionary", bi_PL_NewDictionary, -1},
{"PL_NewArray", bi_PL_NewArray, -1},
{"PL_NewData", bi_PL_NewData, -1},
{"PL_NewString", bi_PL_NewString, -1},
{"PL_Free", bi_PL_Free, -1},
bi(PL_GetFromFile, 1, p(ptr)),
bi(PL_GetPropertyList, 1, p(string)),
bi(PL_WritePropertyList, 1, p(ptr)),
bi(PL_Type, 1, p(ptr)),
bi(PL_Line, 1, p(ptr)),
bi(PL_String, 1, p(ptr)),
bi(PL_ObjectForKey, 2, p(ptr), p(string)),
bi(PL_RemoveObjectForKey, 2, p(ptr), p(string)),
bi(PL_ObjectAtIndex, 2, p(ptr), p(int)),
bi(PL_D_AllKeys, 1, p(ptr)),
bi(PL_D_NumKeys, 1, p(ptr)),
bi(PL_D_AddObject, 3, p(ptr), p(string), p(ptr)),
bi(PL_A_AddObject, 2, p(ptr), p(ptr)),
bi(PL_A_NumObjects, 1, p(ptr)),
bi(PL_A_InsertObjectAtIndex, 3, p(ptr), p(ptr), p(int)),
bi(PL_RemoveObjectAtIndex, 2, p(ptr), p(int)),
bi(PL_NewDictionary, 0),
bi(PL_NewArray, 0),
bi(PL_NewData, 2, p(ptr), p(int)),
bi(PL_NewString, 1, p(string)),
bi(PL_Free, 1, p(ptr)),
{0}
};
@ -477,5 +479,5 @@ RUA_Plist_Init (progs_t *pr, int secure)
Hash_SetHashCompare (res->plist_tab, plist_get_hash, plist_compare);
PR_Resources_Register (pr, "plist", res, bi_plist_clear);
PR_RegisterBuiltins (pr, builtins);
PR_RegisterBuiltins (pr, builtins, res);
}

View file

@ -213,7 +213,7 @@ bi_Qreadstring (progs_t *pr)
int handle = P_INT (pr, 0);
int len = P_INT (pr, 1);
qfile_t *h = get_handle (pr, __FUNCTION__, handle);
string_t str = PR_NewMutableString (pr);
pr_string_t str = PR_NewMutableString (pr);
dstring_t *dstr = PR_GetMutableString (pr, str);
dstr->size = len + 1;
@ -346,35 +346,40 @@ bi_Qfilesize (progs_t *pr)
R_INT (pr) = Qfilesize (h->file);
}
#define bi(x,np,params...) {#x, secured, -1, np, {params}}
#define p(type) PR_PARAM(type)
#define P(a, s) { .size = (s), .alignment = BITOP_LOG2 (a), }
static builtin_t secure_builtins[] = {
{"Qrename", secured, -1},
{"Qremove", secured, -1},
{"Qopen", secured, -1},
bi(Qrename, 2, p(string), p(string)),
bi(Qremove, 1, p(string)),
bi(Qopen, 2, p(string), p(string)),
{0}
};
#undef bi
#define bi(x,np,params...) {#x, bi_##x, -1, np, {params}}
static builtin_t insecure_builtins[] = {
{"Qrename", bi_Qrename, -1},
{"Qremove", bi_Qremove, -1},
{"Qopen", bi_Qopen, -1},
bi(Qrename, 2, p(string), p(string)),
bi(Qremove, 1, p(string)),
bi(Qopen, 2, p(string), p(string)),
{0}
};
static builtin_t builtins[] = {
{"Qclose", bi_Qclose, -1},
{"Qgetline", bi_Qgetline, -1},
{"Qreadstring", bi_Qreadstring, -1},
{"Qread", bi_Qread, -1},
{"Qwrite", bi_Qwrite, -1},
{"Qputs", bi_Qputs, -1},
// {"Qgets", bi_Qgets, -1},
{"Qgetc", bi_Qgetc, -1},
{"Qputc", bi_Qputc, -1},
{"Qseek", bi_Qseek, -1},
{"Qtell", bi_Qtell, -1},
{"Qflush", bi_Qflush, -1},
{"Qeof", bi_Qeof, -1},
{"Qfilesize", bi_Qfilesize, -1},
bi(Qclose, 1, p(ptr)),
bi(Qgetline, 1, p(ptr)),
bi(Qreadstring, 2, p(ptr), p(int)),
bi(Qread, 3, p(ptr), p(ptr), p(int)),
bi(Qwrite, 3, p(ptr), p(ptr), p(int)),
bi(Qputs, 2, p(ptr), p(string)),
// bi(Qgets, _, _),
bi(Qgetc, 1, p(ptr)),
bi(Qputc, 2, p(ptr), p(int)),
bi(Qseek, 3, p(ptr), p(int), p(int)),
bi(Qtell, 1, p(ptr)),
bi(Qflush, 1, p(ptr)),
bi(Qeof, 1, p(ptr)),
bi(Qfilesize, 1, p(ptr)),
{0}
};
@ -385,9 +390,9 @@ RUA_QFile_Init (progs_t *pr, int secure)
PR_Resources_Register (pr, "QFile", res, bi_qfile_clear);
if (secure) {
PR_RegisterBuiltins (pr, secure_builtins);
PR_RegisterBuiltins (pr, secure_builtins, res);
} else {
PR_RegisterBuiltins (pr, insecure_builtins);
PR_RegisterBuiltins (pr, insecure_builtins, res);
}
PR_RegisterBuiltins (pr, builtins);
PR_RegisterBuiltins (pr, builtins, res);
}

View file

@ -45,7 +45,7 @@
typedef struct {
int count;
pointer_t list;
pr_ptr_t list;
} qfslist_t;
static void
@ -155,7 +155,7 @@ bi_QFS_Filelist (progs_t *pr)
{
filelist_t *filelist = QFS_FilelistNew ();
qfslist_t *list;
string_t *strings;
pr_string_t *strings;
int i;
QFS_FilelistFill (filelist, P_GSTRING (pr, 0), P_GSTRING (pr, 1),
@ -163,7 +163,7 @@ bi_QFS_Filelist (progs_t *pr)
list = PR_Zone_Malloc (pr, sizeof (list) + filelist->count * 4);
list->count = filelist->count;
strings = (string_t *) (list + 1);
strings = (pr_string_t *) (list + 1);
list->list = PR_SetPointer (pr, strings);
for (i = 0; i < filelist->count; i++)
strings[i] = PR_SetDynamicString (pr, filelist->list[i]);
@ -174,7 +174,7 @@ static void
bi_QFS_FilelistFree (progs_t *pr)
{
qfslist_t *list = &P_STRUCT (pr, qfslist_t, 0);
string_t *strings = &G_STRUCT (pr, string_t, list->list);
pr_string_t *strings = &G_STRUCT (pr, pr_string_t, list->list);
int i;
for (i = 0; i < list->count; i++)
@ -188,21 +188,23 @@ bi_QFS_GetDirectory (progs_t *pr)
RETURN_STRING (pr, qfs_gamedir->dir.def);
}
#define bi(x,np,params...) {#x, bi_##x, -1, np, {params}}
#define p(type) PR_PARAM(type)
static builtin_t builtins[] = {
{"QFS_Open", bi_QFS_Open, -1},
{"QFS_WOpen", bi_QFS_WOpen, -1},
{"QFS_Rename", bi_QFS_Rename, -1},
{"QFS_LoadFile", bi_QFS_LoadFile, -1},
{"QFS_OpenFile", bi_QFS_OpenFile, -1},
{"QFS_WriteFile", bi_QFS_WriteFile, -1},
{"QFS_Filelist", bi_QFS_Filelist, -1},
{"QFS_FilelistFree", bi_QFS_FilelistFree, -1},
{"QFS_GetDirectory", bi_QFS_GetDirectory, -1},
bi(QFS_Open, 2, p(string), p(string)),
bi(QFS_WOpen, 2, p(string), p(int)),
bi(QFS_Rename, 2, p(string), p(string)),
bi(QFS_LoadFile, 1, p(string)),
bi(QFS_OpenFile, 1, p(string)),
bi(QFS_WriteFile, 3, p(string), p(ptr), p(int)),
bi(QFS_Filelist, 3, p(string), p(string), p(int)),
bi(QFS_FilelistFree, 1, p(ptr)),
bi(QFS_GetDirectory, 0),
{0}
};
void
RUA_QFS_Init (progs_t *pr, int secure)
{
PR_RegisterBuiltins (pr, builtins);
PR_RegisterBuiltins (pr, builtins, 0);
}

View file

@ -56,7 +56,7 @@ bi_va_copy (progs_t *pr)
__auto_type src_list = &G_STRUCT (pr, pr_type_t, src_args->list);
size_t parm_size = pr->pr_param_size * sizeof(pr_type_t);
size_t size = src_args->count * parm_size;
string_t dst_list_block = 0;
pr_string_t dst_list_block = 0;
pr_type_t *dst_list = 0;
if (size) {
@ -69,13 +69,16 @@ bi_va_copy (progs_t *pr)
R_PACKED (pr, pr_va_list_t).list = PR_SetPointer (pr, dst_list);
}
#define bi(x,np,params...) {#x, bi_##x, -1, np, {params}}
#define p(type) PR_PARAM(type)
#define P(a, s) { .size = (s), .alignment = BITOP_LOG2 (a), }
static builtin_t builtins[] = {
{"va_copy", bi_va_copy, -1},
bi(va_copy, 1, P(1, 2)),
{0}
};
void
RUA_Runtime_Init (progs_t *pr, int secure)
{
PR_RegisterBuiltins (pr, builtins);
PR_RegisterBuiltins (pr, builtins, 0);
}

View file

@ -46,7 +46,7 @@
typedef struct {
script_t script;
string_t dstr;
pr_string_t dstr;
progs_t *pr;
} rua_script_t;
@ -187,15 +187,17 @@ bi_Script_NoQuoteLines (progs_t *pr)
script->script.no_quote_lines = P_INT (pr, 1);
}
#define bi(x,np,params...) {#x, bi_##x, -1, np, {params}}
#define p(type) PR_PARAM(type)
static builtin_t builtins[] = {
{"Script_New", bi_Script_New, -1},
{"Script_Delete", bi_Script_Delete, -1},
{"Script_Start", bi_Script_Start, -1},
{"Script_TokenAvailable", bi_Script_TokenAvailable, -1},
{"Script_GetToken", bi_Script_GetToken, -1},
{"Script_UngetToken", bi_Script_UngetToken, -1},
{"Script_Error", bi_Script_Error, -1},
{"Script_NoQuoteLines", bi_Script_NoQuoteLines, -1},
bi(Script_New, 0),
bi(Script_Delete, 1, p(ptr)),
bi(Script_Start, 3, p(ptr), p(string), p(string)),
bi(Script_TokenAvailable, 2, p(ptr), p(int)),
bi(Script_GetToken, 2, p(ptr), p(int)),
bi(Script_UngetToken, 1, p(ptr)),
bi(Script_Error, 1, p(ptr)),
bi(Script_NoQuoteLines, 1, p(ptr)),
{0}
};
@ -205,6 +207,5 @@ RUA_Script_Init (progs_t *pr, int secure)
script_resources_t *res = calloc (1, sizeof (script_resources_t));
PR_Resources_Register (pr, "Script", res, bi_script_clear);
PR_RegisterBuiltins (pr, builtins);
PR_RegisterBuiltins (pr, builtins, res);
}

Some files were not shown because too many files have changed in this diff Show more