X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=blobdiff_plain;f=gmqcc.h;h=4c4d129df3aa868f251274962911c81fd4ce1d14;hp=02a8c891f57d5ee4638b66cbdfd8fd1ed7631cb4;hb=3c003bc168fe47f3e7ce08328782f969b59d89a3;hpb=fe344cb5b29516f26105f0fe2aeaf66d4dbb6d34 diff --git a/gmqcc.h b/gmqcc.h index 02a8c89..4c4d129 100644 --- a/gmqcc.h +++ b/gmqcc.h @@ -39,6 +39,7 @@ # pragma warning(disable : 4018 ) /* signed/unsigned mismatch */ # pragma warning(disable : 4996 ) /* This function or variable may be unsafe */ # pragma warning(disable : 4700 ) /* uninitialized local variable used */ +# pragma warning(disable : 4129 ) /* unrecognized character secape sequence */ #endif #define GMQCC_VERSION_MAJOR 0 @@ -116,7 +117,7 @@ * I suspect it also has just __inline of some sort, but our use * of inline is correct (not guessed), WE WANT IT TO BE INLINE */ -#elseif defined(_MSC_VER) +#elif defined(_MSC_VER) # define GMQCC_INLINE __forceinline #else # define GMQCC_INLINE @@ -134,65 +135,112 @@ # define GMQCC_NORETURN #endif +#ifndef _MSC_VER +# include +#else + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; + typedef unsigned __int64 uint64_t; + + typedef __int16 int16_t; + typedef __int32 int32_t; + typedef __int64 int64_t; +#endif + +/* + *windows makes these prefixed because they're C99 + * TODO: utility versions that are type-safe and not + * just plain textual subsitution. + */ +#ifdef _MSC_VER +# define snprintf(X, Y, Z, ...) _snprintf(X, Y, Z, __VA_ARGS__) + /* strtof doesn't exist -> strtod does though :) */ +# define strtof(X, Y) (float)(strtod(X, Y)) +#endif + + /* - * stdint.h and inttypes.h -less subset - * for systems that don't have it, which we must - * assume is all systems. (int8_t not required) + * Very roboust way at determining endianess at compile time: this handles + * almost every possible situation. Otherwise a runtime check has to be + * performed. */ -#if CHAR_MIN == -128 - typedef unsigned char uint8_t; /* same as below */ -#elif SCHAR_MIN == -128 - typedef unsigned char uint8_t; /* same as above */ +#define GMQCC_BYTE_ORDER_LITTLE 1234 +#define GMQCC_BYTE_ORDER_BIG 4321 + +#if defined (__GNUC__) || defined (__GNU_LIBRARY__) +# if defined (__FreeBSD__) || defined (__OpenBSD__) +# include +# elif defined (BSD) && (BSD >= 199103) || defined (__DJGPP__) || defined (__CYGWIN32__) +# include +# elif defined (__APPLE__) +# if defined (__BIG_ENDIAN__) && !defined(BIG_ENDIAN) +# define BIG_ENDIAN +# elif defined (__LITTLE_ENDIAN__) && !defined (LITTLE_ENDIAN) +# define LITTLE_ENDIAN +# endif +# elif !defined (__MINGW32__) +# include +# if !defined (__BEOS__) +# include +# endif +# endif #endif -#if SHRT_MAX == 0x7FFF - typedef short int16_t; - typedef unsigned short uint16_t; -#elif INT_MAX == 0x7FFF - typedef int int16_t; - typedef unsigned int uint16_t; +#if !defined(PLATFORM_BYTE_ORDER) +# if defined (LITTLE_ENDIAN) || defined (BIG_ENDIAN) +# if defined (LITTLE_ENDIAN) && !defined(BIG_ENDIAN) +# define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_LITTLE +# elif !defined (LITTLE_ENDIAN) && defined (BIG_ENDIAN) +# define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_BIG +# elif defined (BYTE_ORDER) && (BYTE_ORDER == LITTLE_ENDIAN) +# define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_LITTLE +# elif defined (BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN) +# define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_BIG +# endif +# elif defined (_LITTLE_ENDIAN) || defined (_BIG_ENDIAN) +# if defined (_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN) +# define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_LITTLE +# elif !defined (_LITTLE_ENDIAN) && defined (_BIG_ENDIAN) +# define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_BIG +# elif defined (_BYTE_ORDER) && (_BYTE_ORDER == _LITTLE_ENDIAN) +# define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_LITTLE +# elif defined (_BYTE_ORDER) && (_BYTE_ORDER == _BIG_ENDIAN) +# define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_BIG +# endif +# elif defined (__LITTLE_ENDIAN__) || defined (__BIG_ENDIAN__) +# if defined (__LITTLE_ENDIAN__) && !defined (__BIG_ENDIAN__) +# define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_LITTLE +# elif !defined (__LITTLE_ENDIAN__) && defined (__BIG_ENDIAN__) +# define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_BIG +# elif defined (__BYTE_ORDER__) && (__BYTE_ORDER__ == __LITTLE_ENDIAN__) +# define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_LITTLE +# elif defined (__BYTE_ORDER__) && (__BYTE_ORDER__ == __BIG_ENDIAN__) +# define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_BIG +# endif +# endif #endif -#if INT_MAX == 0x7FFFFFFF - typedef int int32_t; - typedef unsigned int uint32_t; -#elif LONG_MAX == 0x7FFFFFFF - typedef long int32_t; - typedef unsigned long uint32_t; +#if !defined (PLATFORM_BYTE_ORDER) +# if defined (__aplha__) || defined (__aplha) || defined (i386) || \ + defined (__i386__) || defined (_M_I86) || defined (_M_IX86) || \ + defined (__OS2__) || defined (sun386) || defined (__TURBOC__) || \ + defined (vax) || defined (vms) || defined (VMS) || \ + defined (__VMS) || defined (__x86_64__) || defined (_M_IA64) || \ + defined (_M_X64) || defined (__i386) || defined (__x86_64) +# define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_LITTLE +# elif defined (AMIGA) || defined (applec) || defined (__AS400__) || \ + defined (_CRAY) || defined (__hppa) || defined (__hp9000) || \ + defined (ibm370) || defined (mc68000) || defined (m68k) || \ + defined (__MRC__) || defined (__MVS__) || defined (__MWERKS__) || \ + defined (sparc) || defined (__sparc) || defined (SYMANTEC_C) || \ + defined (__TANDEM) || defined (THINK_C) || defined (__VMCMS__) || \ + defined (__PPC__) || defined (__PPC) || defined (PPC) +# define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_BIG +# else +# define PLATFORM_BYTE_ORDER -1 +# endif #endif -#if defined(__GNUC__) || defined (__CLANG__) - typedef int int64_t __attribute__((__mode__(__DI__))); - typedef unsigned int uint64_t __attribute__((__mode__(__DI__))); -#elif defined(_MSC_VER) - typedef __int64 int64_t; - typedef unsigned __int64 uint64_t; -#else - /* - * Incorrectly size the types so static assertions below will - * fail. There is no valid way to get a 64bit type at this point - * without making assumptions of too many things. - */ - typedef struct { char _fail : 0; } int64_t; - typedef struct { char _fail : 0; } uint64_t; -#endif -#ifdef _LP64 /* long pointer == 64 */ - typedef unsigned long uintptr_t; - typedef long intptr_t; -#else - typedef unsigned int uintptr_t; - typedef int intptr_t; -#endif -/* Ensure type sizes are correct: */ -typedef char uint8_size_is_correct [sizeof(uint8_t) == 1?1:-1]; -typedef char uint16_size_is_correct [sizeof(uint16_t) == 2?1:-1]; -typedef char uint32_size_is_correct [sizeof(uint32_t) == 4?1:-1]; -typedef char uint64_size_is_correct [sizeof(uint64_t) == 8?1:-1]; -typedef char int16_size_if_correct [sizeof(int16_t) == 2?1:-1]; -typedef char int32_size_is_correct [sizeof(int32_t) == 4?1:-1]; -typedef char int64_size_is_correct [sizeof(int64_t) >= 8?1:-1]; -/* intptr_t / uintptr_t correct size check */ -typedef char uintptr_size_is_correct[sizeof(intptr_t) == sizeof(int*)?1:-1]; -typedef char intptr_size_is_correct [sizeof(uintptr_t)== sizeof(int*)?1:-1]; /*===================================================================*/ /*=========================== util.c ================================*/ @@ -215,7 +263,7 @@ char *util_strsws (const char *); char *util_strchp (const char *, const char *); void util_debug (const char *, const char *, ...); int util_getline (char **, size_t *, FILE *); -void util_endianswap (void *, int, int); +void util_endianswap (void *, size_t, unsigned int); size_t util_strtocmd (const char *, char *, size_t); size_t util_strtononcmd (const char *, char *, size_t); @@ -236,7 +284,7 @@ uint32_t util_crc32(uint32_t crc, const char *data, size_t len); /* * TODO: make these safer to use. Currently this only works on * x86 and x86_64, some systems will likely not like this. Such - * as BE systems. + * as BE systems. (and clean this up to use a structure ... ) */ #define FLT2INT(Y) *((int32_t*)&(Y)) #define INT2FLT(Y) *((float *)&(Y)) @@ -263,6 +311,7 @@ void _util_vec_grow(void **a, size_t i, size_t s); #define vec_shrinkto(A,N) (_vec_end(A) = (N)) #define vec_shrinkby(A,N) (_vec_end(A) -= (N)) +/* vec_upload needs to be cleaned up as well to be a function */ #define vec_upload(X,Y,S) \ do { \ size_t E = 0; \ @@ -338,14 +387,12 @@ enum { }; /* const/var qualifiers */ -#define CV_NONE 0 -#define CV_CONST 1 -#define CV_VAR -1 -/* magic number to help parsing */ -#define CV_WRONG 0x8000 +#define CV_NONE 0 +#define CV_CONST 1 +#define CV_VAR -1 +#define CV_WRONG 0x8000 /* magic number to help parsing */ extern const char *type_name [TYPE_COUNT]; -extern size_t type_sizeof [TYPE_COUNT]; extern uint16_t type_store_instr [TYPE_COUNT]; extern uint16_t field_store_instr[TYPE_COUNT]; @@ -546,9 +593,15 @@ enum { */ VINSTR_PHI, VINSTR_JUMP, - VINSTR_COND + VINSTR_COND, + /* A never returning CALL. + * Creating this causes IR blocks to be marked as 'final'. + * No-Return-Call + */ + VINSTR_NRCALL }; +/* TODO: cleanup this mess */ extern prog_section_statement *code_statements; extern int *code_linenums; extern prog_section_def *code_defs; @@ -558,6 +611,7 @@ extern int *code_globals; extern char *code_chars; extern uint16_t code_crc; +/* uhh? */ typedef float qcfloat; typedef int32_t qcint; @@ -573,6 +627,7 @@ qcint code_alloc_field (size_t qcsize); /* this function is used to keep statements and linenumbers together */ void code_push_statement(prog_section_statement *stmt, int linenum); +void code_pop_statement(); /* * A shallow copy of a lex_file to remember where which ast node @@ -623,14 +678,15 @@ int con_out (const char *, ...); extern size_t compile_errors; extern size_t compile_warnings; -void /********/ compile_error (lex_ctx ctx, /*LVL_ERROR*/ const char *msg, ...); -bool GMQCC_WARN compile_warning(lex_ctx ctx, int warntype, const char *fmt, ...); -void /********/ vcompile_error (lex_ctx ctx, /*LVL_ERROR*/ const char *msg, va_list); -bool GMQCC_WARN vcompile_warning(lex_ctx ctx, int warntype, const char *fmt, va_list); +void /********/ compile_error (lex_ctx ctx, /*LVL_ERROR*/ const char *msg, ...); +void /********/ vcompile_error (lex_ctx ctx, /*LVL_ERROR*/ const char *msg, va_list ap); +bool GMQCC_WARN compile_warning (lex_ctx ctx, int warntype, const char *fmt, ...); +bool GMQCC_WARN vcompile_warning(lex_ctx ctx, int warntype, const char *fmt, va_list ap); /*===================================================================*/ /*========================= assembler.c =============================*/ /*===================================================================*/ +/* TODO: remove this ... */ static const struct { const char *m; /* menomic */ const size_t o; /* operands */ @@ -867,14 +923,24 @@ typedef uint32_t longbit; #define LONGBIT(bit) (bit) #endif -/* Used to store the list of flags with names */ +/*===================================================================*/ +/*============================= opts.c ==============================*/ +/*===================================================================*/ typedef struct { const char *name; longbit bit; } opts_flag_def; -/*===================================================================*/ -/* list of -f flags, like -fdarkplaces-string-table-bug */ +bool opts_setflag (const char *, bool); +bool opts_setwarn (const char *, bool); +bool opts_setwerror(const char *, bool); +bool opts_setoptim (const char *, bool); + +void opts_init (const char *, int, size_t); +void opts_set (uint32_t *, size_t, bool); +void opts_setoptimlevel(unsigned int); +void opts_ini_init (const char *); + enum { # define GMQCC_TYPE_FLAGS # define GMQCC_DEFINE_FLAG(X) X, @@ -919,26 +985,25 @@ static const unsigned int opts_opt_oflag[] = { # include "opts.def" 0 }; -extern unsigned int optimization_count[COUNT_OPTIMIZATIONS]; +extern unsigned int opts_optimizationcount[COUNT_OPTIMIZATIONS]; /* other options: */ -enum { +typedef enum { COMPILER_QCC, /* circa QuakeC */ COMPILER_FTEQCC, /* fteqcc QuakeC */ COMPILER_QCCX, /* qccx QuakeC */ COMPILER_GMQCC /* this QuakeC */ -}; +} opts_std_t; typedef struct { uint32_t O; /* -Ox */ const char *output; /* -o file */ bool g; /* -g */ - int standard; /* -std= */ + opts_std_t standard; /* -std= */ bool debug; /* -debug */ bool memchk; /* -memchk */ bool dumpfin; /* -dumpfin */ bool dump; /* -dump */ - bool werror; /* -Werror */ bool forcecrc; /* --force-crc= */ uint16_t forced_crc; /* --force-crc= */ bool pp_only; /* -E */ @@ -946,16 +1011,16 @@ typedef struct { uint32_t flags [1 + (COUNT_FLAGS / 32)]; uint32_t warn [1 + (COUNT_WARNINGS / 32)]; + uint32_t werror [1 + (COUNT_WARNINGS / 32)]; uint32_t optimization[1 + (COUNT_OPTIMIZATIONS / 32)]; -} cmd_options; +} opts_cmd_t; -extern cmd_options opts; +extern opts_cmd_t opts; /*===================================================================*/ #define OPTS_FLAG(i) (!! (opts.flags [(i)/32] & (1<< ((i)%32)))) #define OPTS_WARN(i) (!! (opts.warn [(i)/32] & (1<< ((i)%32)))) +#define OPTS_WERROR(i) (!! (opts.werror [(i)/32] & (1<< ((i)%32)))) #define OPTS_OPTIMIZATION(i) (!! (opts.optimization[(i)/32] & (1<< ((i)%32)))) -void options_set(uint32_t *flags, size_t idx, bool on); - #endif