summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--char.c4
-rw-r--r--lib.c166
-rw-r--r--lib.h1
-rw-r--r--machine.h83
-rw-r--r--show-parse.c73
-rw-r--r--symbol.h2
-rw-r--r--target.c87
-rw-r--r--target.h10
-rw-r--r--validation/preprocessor/predef-char-bit.c16
-rw-r--r--validation/preprocessor/predef-llp64.c9
-rw-r--r--validation/preprocessor/predef-lp32.c9
-rw-r--r--validation/preprocessor/predef-lp64.c9
-rw-r--r--validation/preprocessor/predef-max.c18
-rw-r--r--validation/preprocessor/predef-sizeof.c25
-rw-r--r--validation/preprocessor/predef-unsigned.c9
-rw-r--r--validation/preprocessor/predef.c57
16 files changed, 415 insertions, 163 deletions
diff --git a/char.c b/char.c
index c52521bc..f26b2a80 100644
--- a/char.c
+++ b/char.c
@@ -84,7 +84,7 @@ void get_char_constant(struct token *token, unsigned long long *val)
end = p + type - TOKEN_WIDE_CHAR;
}
p = parse_escape(p, &v, end,
- type < TOKEN_WIDE_CHAR ? bits_in_char : bits_in_wchar, token->pos);
+ type < TOKEN_WIDE_CHAR ? bits_in_char : wchar_ctype->bit_size, token->pos);
if (p != end)
warning(token->pos,
"multi-character character constant");
@@ -113,7 +113,7 @@ struct token *get_string_constant(struct token *token, struct expression *expr)
done = next;
}
}
- bits = is_wide ? bits_in_wchar : bits_in_char;
+ bits = is_wide ? wchar_ctype->bit_size: bits_in_char;
while (token != done) {
unsigned v;
const char *p = token->string->data;
diff --git a/lib.c b/lib.c
index b981bf64..9f8213df 100644
--- a/lib.c
+++ b/lib.c
@@ -45,7 +45,9 @@
#include "scope.h"
#include "linearize.h"
#include "target.h"
+#include "machine.h"
#include "version.h"
+#include "bits.h"
int verbose, optimize_level, optimize_size, preprocessing;
int die_if_error = 0;
@@ -307,7 +309,7 @@ unsigned long fdump_ir;
int fmem_report = 0;
unsigned long long fmemcpy_max_count = 100000;
unsigned long fpasses = ~0UL;
-int funsigned_char = 0;
+int funsigned_char = UNSIGNED_CHAR;
int preprocess_only;
@@ -319,30 +321,10 @@ static enum { STANDARD_C89,
STANDARD_GNU89,
STANDARD_GNU99, } standard = STANDARD_GNU89;
-enum {
- ARCH_LP32,
- ARCH_X32,
- ARCH_LP64,
- ARCH_LLP64,
-};
-
-#ifdef __LP64__
-#define ARCH_M64_DEFAULT ARCH_LP64
-#elif defined(__x86_64__) || defined(__x86_64)
-#define ARCH_M64_DEFAULT ARCH_X32
-#else
-#define ARCH_M64_DEFAULT ARCH_LP32
-#endif
-
int arch_m64 = ARCH_M64_DEFAULT;
int arch_msize_long = 0;
-
-#ifdef __BIG_ENDIAN__
-#define ARCH_BIG_ENDIAN 1
-#else
-#define ARCH_BIG_ENDIAN 0
-#endif
int arch_big_endian = ARCH_BIG_ENDIAN;
+int arch_mach = MACH_NATIVE;
#define CMDLINE_INCLUDE 20
@@ -496,15 +478,23 @@ static void handle_arch_m64_finalize(void)
max_int_alignment = 8;
predefine("__ILP32__", 1, "1");
predefine("_ILP32", 1, "1");
+ int64_ctype = &llong_ctype;
+ uint64_ctype = &ullong_ctype;
goto case_x86_64;
case ARCH_LP32:
/* default values */
+ int64_ctype = &llong_ctype;
+ uint64_ctype = &ullong_ctype;
+ intmax_ctype = &llong_ctype;
+ uintmax_ctype = &ullong_ctype;
return;
case ARCH_LP64:
bits_in_long = 64;
max_int_alignment = 8;
size_t_ctype = &ulong_ctype;
ssize_t_ctype = &long_ctype;
+ intmax_ctype = &long_ctype;
+ uintmax_ctype = &ulong_ctype;
predefine("__LP64__", 1, "1");
predefine("_LP64", 1, "1");
goto case_64bit_common;
@@ -513,6 +503,8 @@ static void handle_arch_m64_finalize(void)
max_int_alignment = 8;
size_t_ctype = &ullong_ctype;
ssize_t_ctype = &llong_ctype;
+ int64_ctype = &llong_ctype;
+ uint64_ctype = &ullong_ctype;
predefine("__LLP64__", 1, "1");
goto case_64bit_common;
case_64bit_common:
@@ -1181,11 +1173,20 @@ static char **handle_switch(char *arg, char **next)
return next;
}
-static void predefined_sizeof(const char *name, unsigned bits)
+#define PTYPE_SIZEOF (1U << 0)
+#define PTYPE_T (1U << 1)
+#define PTYPE_MAX (1U << 2)
+#define PTYPE_MIN (1U << 3)
+#define PTYPE_WIDTH (1U << 4)
+#define PTYPE_TYPE (1U << 5)
+#define PTYPE_ALL (PTYPE_MAX|PTYPE_SIZEOF|PTYPE_WIDTH)
+#define PTYPE_ALL_T (PTYPE_MAX|PTYPE_SIZEOF|PTYPE_WIDTH|PTYPE_T)
+
+static void predefined_sizeof(const char *name, const char *suffix, unsigned bits)
{
char buf[32];
- snprintf(buf, sizeof(buf), "__SIZEOF_%s__", name);
+ snprintf(buf, sizeof(buf), "__SIZEOF_%s%s__", name, suffix);
predefine(buf, 1, "%d", bits/8);
}
@@ -1197,20 +1198,52 @@ static void predefined_width(const char *name, unsigned bits)
predefine(buf, 1, "%d", bits);
}
-static void predefined_max(const char *name, const char *suffix, unsigned bits)
+static void predefined_max(const char *name, struct symbol *type)
{
- unsigned long long max = (1ULL << (bits - 1 )) - 1;
+ const char *suffix = builtin_type_suffix(type);
+ unsigned bits = type->bit_size - is_signed_type(type);
+ unsigned long long max = bits_mask(bits);
char buf[32];
snprintf(buf, sizeof(buf), "__%s_MAX__", name);
predefine(buf, 1, "%#llx%s", max, suffix);
}
-static void predefined_type_size(const char *name, const char *suffix, unsigned bits)
+static void predefined_min(const char *name, struct symbol *type)
{
- predefined_max(name, suffix, bits);
- predefined_sizeof(name, bits);
- predefined_width(name, bits);
+ const char *suffix = builtin_type_suffix(type);
+ char buf[32];
+
+ snprintf(buf, sizeof(buf), "__%s_MIN__", name);
+
+ if (is_signed_type(type))
+ predefine(buf, 1, "(-__%s_MAX__ - 1)", name);
+ else
+ predefine(buf, 1, "0%s", suffix);
+}
+
+static void predefined_type(const char *name, struct symbol *type)
+{
+ const char *typename = builtin_typename(type);
+ add_pre_buffer("#weak_define __%s_TYPE__ %s\n", name, typename);
+}
+
+static void predefined_ctype(const char *name, struct symbol *type, int flags)
+{
+ unsigned bits = type->bit_size;
+
+ if (flags & PTYPE_SIZEOF) {
+ const char *suffix = (flags & PTYPE_T) ? "_T" : "";
+ predefined_sizeof(name, suffix, bits);
+ }
+ if (flags & PTYPE_MAX)
+ predefined_max(name, type);
+ if (flags & PTYPE_MIN)
+ predefined_min(name, type);
+ if (flags & PTYPE_TYPE)
+ predefined_type(name, type);
+ if (flags & PTYPE_WIDTH)
+ predefined_width(name, bits);
}
static void predefined_macros(void)
@@ -1254,31 +1287,44 @@ static void predefined_macros(void)
break;
}
- predefined_sizeof("SHORT", bits_in_short);
- predefined_max("SHRT", "", bits_in_short);
- predefined_width("SHRT", bits_in_short);
- predefined_max("SCHAR", "", bits_in_char);
- predefined_width("SCHAR", bits_in_char);
- predefined_sizeof("WCHAR_T",bits_in_wchar);
- predefined_max("WCHAR", "", bits_in_wchar);
- predefined_width("WCHAR", bits_in_wchar);
predefine("__CHAR_BIT__", 1, "%d", bits_in_char);
-
- predefined_type_size("INT", "", bits_in_int);
- predefined_type_size("LONG", "L", bits_in_long);
- predefined_type_size("LONG_LONG", "LL", bits_in_longlong);
-
- predefined_sizeof("INT128", 128);
-
- predefined_sizeof("SIZE_T", bits_in_pointer);
- predefined_width( "SIZE", bits_in_pointer);
- predefined_sizeof("PTRDIFF_T", bits_in_pointer);
- predefined_width( "PTRDIFF", bits_in_pointer);
- predefined_sizeof("POINTER", bits_in_pointer);
-
- predefined_sizeof("FLOAT", bits_in_float);
- predefined_sizeof("DOUBLE", bits_in_double);
- predefined_sizeof("LONG_DOUBLE", bits_in_longdouble);
+ if (funsigned_char)
+ predefine("__CHAR_UNSIGNED__", 1, "1");
+
+ predefined_ctype("SHORT", &short_ctype, PTYPE_SIZEOF);
+ predefined_ctype("SHRT", &short_ctype, PTYPE_MAX|PTYPE_WIDTH);
+ predefined_ctype("SCHAR", &schar_ctype, PTYPE_MAX|PTYPE_WIDTH);
+ predefined_ctype("WCHAR", wchar_ctype, PTYPE_ALL_T|PTYPE_MIN|PTYPE_TYPE);
+ predefined_ctype("WINT", wint_ctype, PTYPE_ALL_T|PTYPE_MIN|PTYPE_TYPE);
+ predefined_ctype("CHAR16", &ushort_ctype, PTYPE_TYPE);
+ predefined_ctype("CHAR32", &uint_ctype, PTYPE_TYPE);
+
+ predefined_ctype("INT", &int_ctype, PTYPE_ALL);
+ predefined_ctype("LONG", &long_ctype, PTYPE_ALL);
+ predefined_ctype("LONG_LONG", &llong_ctype, PTYPE_ALL);
+
+ predefined_ctype("INT8", &schar_ctype, PTYPE_MAX|PTYPE_TYPE);
+ predefined_ctype("UINT8", &uchar_ctype, PTYPE_MAX|PTYPE_TYPE);
+ predefined_ctype("INT16", &short_ctype, PTYPE_MAX|PTYPE_TYPE);
+ predefined_ctype("UINT16", &ushort_ctype, PTYPE_MAX|PTYPE_TYPE);
+ predefined_ctype("INT32", int32_ctype, PTYPE_MAX|PTYPE_TYPE);
+ predefined_ctype("UINT32", uint32_ctype, PTYPE_MAX|PTYPE_TYPE);
+ predefined_ctype("INT64", int64_ctype, PTYPE_MAX|PTYPE_TYPE);
+ predefined_ctype("UINT64", uint64_ctype, PTYPE_MAX|PTYPE_TYPE);
+
+ predefined_sizeof("INT128", "", 128);
+
+ predefined_ctype("INTMAX", intmax_ctype, PTYPE_MAX|PTYPE_TYPE|PTYPE_WIDTH);
+ predefined_ctype("UINTMAX", uintmax_ctype, PTYPE_MAX|PTYPE_TYPE);
+ predefined_ctype("INTPTR", ssize_t_ctype, PTYPE_MAX|PTYPE_TYPE|PTYPE_WIDTH);
+ predefined_ctype("UINTPTR", size_t_ctype, PTYPE_MAX|PTYPE_TYPE);
+ predefined_ctype("PTRDIFF", ssize_t_ctype, PTYPE_ALL_T|PTYPE_TYPE);
+ predefined_ctype("SIZE", size_t_ctype, PTYPE_ALL_T|PTYPE_TYPE);
+ predefined_ctype("POINTER", &ptr_ctype, PTYPE_SIZEOF);
+
+ predefined_sizeof("FLOAT", "", bits_in_float);
+ predefined_sizeof("DOUBLE", "", bits_in_double);
+ predefined_sizeof("LONG_DOUBLE", "", bits_in_longdouble);
predefine("__ORDER_LITTLE_ENDIAN__", 1, "1234");
predefine("__ORDER_BIG_ENDIAN__", 1, "4321");
@@ -1306,17 +1352,6 @@ static void create_builtin_stream(void)
// Temporary hack
add_pre_buffer("#define _Pragma(x)\n");
- // gcc defines __SIZE_TYPE__ to be size_t. For linux/i86 and
- // solaris/sparc that is really "unsigned int" and for linux/x86_64
- // it is "long unsigned int". In either case we can probably
- // get away with this. We need the #weak_define as cgcc will define
- // the right __SIZE_TYPE__.
- if (size_t_ctype == &ulong_ctype)
- add_pre_buffer("#weak_define __SIZE_TYPE__ long unsigned int\n");
- else
- add_pre_buffer("#weak_define __SIZE_TYPE__ unsigned int\n");
-
-
/* add the multiarch include directories, if any */
if (multiarch_dir && *multiarch_dir) {
add_pre_buffer("#add_system \"/usr/include/%s\"\n", multiarch_dir);
@@ -1465,6 +1500,7 @@ struct symbol_list *sparse_initialize(int argc, char **argv, struct string_list
list = NULL;
if (filelist) {
// Initialize type system
+ init_target();
init_ctype();
predefined_macros();
diff --git a/lib.h b/lib.h
index 74315076..f2f5f839 100644
--- a/lib.h
+++ b/lib.h
@@ -201,6 +201,7 @@ extern int funsigned_char;
extern int arch_m64;
extern int arch_msize_long;
extern int arch_big_endian;
+extern int arch_mach;
extern void dump_macro_definitions(void);
extern struct symbol_list *sparse_initialize(int argc, char **argv, struct string_list **files);
diff --git a/machine.h b/machine.h
new file mode 100644
index 00000000..09c1f513
--- /dev/null
+++ b/machine.h
@@ -0,0 +1,83 @@
+#ifndef MACHINE_H
+#define MACHINE_H
+
+#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
+#define ARCH_BIG_ENDIAN 1
+#else
+#define ARCH_BIG_ENDIAN 0
+#endif
+
+
+enum {
+ ARCH_LP32,
+ ARCH_X32,
+ ARCH_LP64,
+ ARCH_LLP64,
+};
+
+#ifdef __LP64__
+#define ARCH_M64_DEFAULT ARCH_LP64
+#elif defined(__x86_64__) || defined(__x86_64)
+#define ARCH_M64_DEFAULT ARCH_X32
+#else
+#define ARCH_M64_DEFAULT ARCH_LP32
+#endif
+
+
+enum machine {
+ MACH_ARM,
+ MACH_ARM64,
+ MACH_I386,
+ MACH_X86_64,
+ MACH_MIPS32,
+ MACH_MIPS64,
+ MACH_PPC32,
+ MACH_PPC64,
+ MACH_RISCV32,
+ MACH_RISCV64,
+ MACH_SPARC32,
+ MACH_SPARC64,
+ MACH_M68K,
+ MACH_S390X,
+ MACH_UNKNOWN
+};
+
+#if defined(__aarch64__)
+#define MACH_NATIVE MACH_ARM64
+#elif defined(__arm__)
+#define MACH_NATIVE MACH_ARM
+#elif defined(__x86_64__) || defined(__x86_64)
+#define MACH_NATIVE MACH_X86_64
+#elif defined(__i386__) || defined(__i386)
+#define MACH_NATIVE MACH_I386
+#elif defined(__mips64__) || (defined(__mips) && __mips == 64)
+#define MACH_NATIVE MACH_MIPS64
+#elif defined(__mips__) || defined(__mips)
+#define MACH_NATIVE MACH_MIPS32
+#elif defined(__powerpc64__) || defined(__ppc64__)
+#define MACH_NATIVE MACH_PPC64
+#elif defined(__powerpc__) || defined(__powerpc) || defined(__ppc__)
+#define MACH_NATIVE MACH_PPC32
+#elif defined(__riscv) && (__riscv_xlen == 64)
+#define MACH_NATIVE MACH_RISCV64
+#elif defined(__riscv) && (__riscv_xlen == 32)
+#define MACH_NATIVE MACH_RISCV32
+#elif defined(__sparc_v9__)
+#define MACH_NATIVE MACH_SPARC64
+#elif defined(__sparc__) || defined(__sparc)
+#define MACH_NATIVE MACH_SPARC32
+#elif defined(__m68k__)
+#define MACH_NATIVE MACH_68K
+#elif defined(__s390x__) || defined(__zarch__)
+#define MACH_NATIVE MACH_S390X
+#else
+#define MACH_NATIVE MACH_UNKNOWN
+#endif
+
+#if defined(__CHAR_UNSIGNED__)
+#define UNSIGNED_CHAR 1
+#else
+#define UNSIGNED_CHAR 0
+#endif
+
+#endif
diff --git a/show-parse.c b/show-parse.c
index b892c189..5325f019 100644
--- a/show-parse.c
+++ b/show-parse.c
@@ -226,38 +226,39 @@ static void FORMAT_ATTR(2) append(struct type_name *name, const char *fmt, ...)
static struct ctype_name {
struct symbol *sym;
const char *name;
+ const char *suffix;
} typenames[] = {
- { & char_ctype, "char" },
- { &schar_ctype, "signed char" },
- { &uchar_ctype, "unsigned char" },
- { & short_ctype, "short" },
- { &sshort_ctype, "signed short" },
- { &ushort_ctype, "unsigned short" },
- { & int_ctype, "int" },
- { &sint_ctype, "signed int" },
- { &uint_ctype, "unsigned int" },
- { &slong_ctype, "signed long" },
- { & long_ctype, "long" },
- { &ulong_ctype, "unsigned long" },
- { & llong_ctype, "long long" },
- { &sllong_ctype, "signed long long" },
- { &ullong_ctype, "unsigned long long" },
- { & lllong_ctype, "long long long" },
- { &slllong_ctype, "signed long long long" },
- { &ulllong_ctype, "unsigned long long long" },
-
- { &void_ctype, "void" },
- { &bool_ctype, "bool" },
- { &string_ctype, "string" },
-
- { &float_ctype, "float" },
- { &double_ctype, "double" },
- { &ldouble_ctype,"long double" },
- { &incomplete_ctype, "incomplete type" },
- { &int_type, "abstract int" },
- { &fp_type, "abstract fp" },
- { &label_ctype, "label type" },
- { &bad_ctype, "bad type" },
+ { & char_ctype, "char", "" },
+ { &schar_ctype, "signed char", "" },
+ { &uchar_ctype, "unsigned char", "" },
+ { & short_ctype, "short", "" },
+ { &sshort_ctype, "signed short", "" },
+ { &ushort_ctype, "unsigned short", "" },
+ { & int_ctype, "int", "" },
+ { &sint_ctype, "signed int", "" },
+ { &uint_ctype, "unsigned int", "U" },
+ { & long_ctype, "long", "L" },
+ { &slong_ctype, "signed long", "L" },
+ { &ulong_ctype, "unsigned long", "UL" },
+ { & llong_ctype, "long long", "LL" },
+ { &sllong_ctype, "signed long long", "LL" },
+ { &ullong_ctype, "unsigned long long", "ULL" },
+ { & lllong_ctype, "long long long", "LLL" },
+ { &slllong_ctype, "signed long long long", "LLL" },
+ { &ulllong_ctype, "unsigned long long long", "ULLL" },
+
+ { &void_ctype, "void", "" },
+ { &bool_ctype, "bool", "" },
+ { &string_ctype, "string", "" },
+
+ { &float_ctype, "float", "F" },
+ { &double_ctype, "double", "" },
+ { &ldouble_ctype,"long double", "L" },
+ { &incomplete_ctype, "incomplete type", "" },
+ { &int_type, "abstract int", "" },
+ { &fp_type, "abstract fp", "" },
+ { &label_ctype, "label type", "" },
+ { &bad_ctype, "bad type", "" },
};
const char *builtin_typename(struct symbol *sym)
@@ -270,6 +271,16 @@ const char *builtin_typename(struct symbol *sym)
return NULL;
}
+const char *builtin_type_suffix(struct symbol *sym)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(typenames); i++)
+ if (typenames[i].sym == sym)
+ return typenames[i].suffix;
+ return NULL;
+}
+
const char *builtin_ctypename(struct ctype *ctype)
{
int i;
diff --git a/symbol.h b/symbol.h
index d4c4d120..51e1c867 100644
--- a/symbol.h
+++ b/symbol.h
@@ -305,6 +305,7 @@ extern void init_symbols(void);
extern void init_builtins(int stream);
extern void declare_builtins(void);
extern void init_ctype(void);
+extern void init_target(void);
extern struct symbol *alloc_symbol(struct position, int type);
extern void show_type(struct symbol *);
extern const char *modifier_string(unsigned long mod);
@@ -320,6 +321,7 @@ extern struct symbol *examine_pointer_target(struct symbol *);
extern const char *show_as(struct ident *as);
extern const char *show_typename(struct symbol *sym);
extern const char *builtin_typename(struct symbol *sym);
+extern const char *builtin_type_suffix(struct symbol *sym);
extern const char *builtin_ctypename(struct ctype *ctype);
extern const char* get_type_name(enum type type);
diff --git a/target.c b/target.c
index 86a9e2e6..788ef3fa 100644
--- a/target.c
+++ b/target.c
@@ -2,9 +2,18 @@
#include "symbol.h"
#include "target.h"
+#include "machine.h"
struct symbol *size_t_ctype = &uint_ctype;
struct symbol *ssize_t_ctype = &int_ctype;
+struct symbol *intmax_ctype = &llong_ctype;
+struct symbol *uintmax_ctype = &ullong_ctype;
+struct symbol *int64_ctype = &long_ctype;
+struct symbol *uint64_ctype = &ulong_ctype;
+struct symbol *int32_ctype = &int_ctype;
+struct symbol *uint32_ctype = &uint_ctype;
+struct symbol *wchar_ctype = &int_ctype;
+struct symbol *wint_ctype = &uint_ctype;
/*
* For "__attribute__((aligned))"
@@ -22,8 +31,6 @@ int bits_in_long = 32;
int bits_in_longlong = 64;
int bits_in_longlonglong = 128;
-int bits_in_wchar = 32;
-
int max_int_alignment = 4;
/*
@@ -31,9 +38,9 @@ int max_int_alignment = 4;
*/
int bits_in_float = 32;
int bits_in_double = 64;
-int bits_in_longdouble = 80;
+int bits_in_longdouble = 128;
-int max_fp_alignment = 8;
+int max_fp_alignment = 16;
/*
* Pointer data type
@@ -46,3 +53,75 @@ int pointer_alignment = 4;
*/
int bits_in_enum = 32;
int enum_alignment = 4;
+
+
+void init_target(void)
+{
+ switch (arch_mach) {
+ case MACH_X86_64:
+ if (arch_m64 == ARCH_LP64)
+ break;
+ /* fall through */
+ case MACH_I386:
+ case MACH_M68K:
+ case MACH_SPARC32:
+ case MACH_PPC32:
+ wchar_ctype = &long_ctype;
+ break;
+ case MACH_ARM:
+ case MACH_ARM64:
+ wchar_ctype = &uint_ctype;
+ break;
+ default:
+ break;
+ }
+
+ switch (arch_mach) {
+ case MACH_MIPS64:
+ if (arch_m64 == ARCH_LP64)
+ break;
+ /* fall through */
+ case MACH_M68K:
+ case MACH_SPARC32:
+ case MACH_PPC32:
+ case MACH_MIPS32:
+ case MACH_RISCV32:
+ int32_ctype = &long_ctype;
+ uint32_ctype = &ulong_ctype;
+ break;
+ default:
+ break;
+ }
+
+ switch (arch_mach) {
+ case MACH_ARM:
+ case MACH_MIPS32:
+ case MACH_S390X:
+ case MACH_SPARC32:
+ bits_in_longdouble = 64;
+ max_fp_alignment = 8;
+ break;
+ case MACH_X86_64:
+ if (arch_m64 == ARCH_LP64 || arch_m64 == ARCH_X32)
+ break;
+ /* fall through */
+ case MACH_I386:
+ case MACH_M68K:
+ bits_in_longdouble = 96;
+ max_fp_alignment = 4;
+ break;
+ default:
+ break;
+ }
+
+#if defined(__CYGWIN__)
+ wchar_ctype = &ushort_ctype;
+#endif
+#if defined(__FreeBSD__) || defined(__APPLE__)
+ wint_ctype = &int_ctype;
+#endif
+#if defined(__APPLE__)
+ int64_ctype = &llong_ctype;
+ uint64_ctype = &ullong_ctype;
+#endif
+}
diff --git a/target.h b/target.h
index 8326fa21..8bbe494f 100644
--- a/target.h
+++ b/target.h
@@ -3,6 +3,14 @@
extern struct symbol *size_t_ctype;
extern struct symbol *ssize_t_ctype;
+extern struct symbol *intmax_ctype;
+extern struct symbol *uintmax_ctype;
+extern struct symbol *int64_ctype;
+extern struct symbol *uint64_ctype;
+extern struct symbol *int32_ctype;
+extern struct symbol *uint32_ctype;
+extern struct symbol *wchar_ctype;
+extern struct symbol *wint_ctype;
/*
* For "__attribute__((aligned))"
@@ -20,8 +28,6 @@ extern int bits_in_long;
extern int bits_in_longlong;
extern int bits_in_longlonglong;
-extern int bits_in_wchar;
-
extern int max_int_alignment;
/*
diff --git a/validation/preprocessor/predef-char-bit.c b/validation/preprocessor/predef-char-bit.c
deleted file mode 100644
index fed0166e..00000000
--- a/validation/preprocessor/predef-char-bit.c
+++ /dev/null
@@ -1,16 +0,0 @@
-#define TEST_BIT(X, T) if (__ ## X ## _BIT__ != 8 * sizeof(T)) return 1
-
-int test(void)
-{
- TEST_BIT(CHAR, char);
-
- return 0;
-}
-
-/*
- * check-name: predefined __<type>_BIT__
- * check-command: test-linearize -Wno-decl $file
- * check-output-ignore
- *
- * check-output-contains: ret\\..*\\$0
- */
diff --git a/validation/preprocessor/predef-llp64.c b/validation/preprocessor/predef-llp64.c
new file mode 100644
index 00000000..0a758690
--- /dev/null
+++ b/validation/preprocessor/predef-llp64.c
@@ -0,0 +1,9 @@
+#include "predef.c"
+
+/*
+ * check-name: predefined macros for LLP64
+ * check-command: test-linearize -Wno-decl -msize-llp64 $file
+ * check-output-ignore
+ *
+ * check-output-contains: ret\\..*\\$0
+ */
diff --git a/validation/preprocessor/predef-lp32.c b/validation/preprocessor/predef-lp32.c
new file mode 100644
index 00000000..8fa2846c
--- /dev/null
+++ b/validation/preprocessor/predef-lp32.c
@@ -0,0 +1,9 @@
+#include "predef.c"
+
+/*
+ * check-name: predefined macros for LP32
+ * check-command: test-linearize -Wno-decl -m32 $file
+ * check-output-ignore
+ *
+ * check-output-contains: ret\\..*\\$0
+ */
diff --git a/validation/preprocessor/predef-lp64.c b/validation/preprocessor/predef-lp64.c
new file mode 100644
index 00000000..0173ca40
--- /dev/null
+++ b/validation/preprocessor/predef-lp64.c
@@ -0,0 +1,9 @@
+#include "predef.c"
+
+/*
+ * check-name: predefined macros for LP64
+ * check-command: test-linearize -Wno-decl -m64 $file
+ * check-output-ignore
+ *
+ * check-output-contains: ret\\..*\\$0
+ */
diff --git a/validation/preprocessor/predef-max.c b/validation/preprocessor/predef-max.c
deleted file mode 100644
index ad4b7eaf..00000000
--- a/validation/preprocessor/predef-max.c
+++ /dev/null
@@ -1,18 +0,0 @@
-#define TEST_MAX(X, Z) if (X != ((~ Z) >> 1)) return 1
-
-int test_max(void)
-{
- TEST_MAX(__INT_MAX__, 0U);
- TEST_MAX(__LONG_MAX__, 0UL);
- TEST_MAX(__LONG_LONG_MAX__, 0ULL);
-
- return 0;
-}
-
-/*
- * check-name: predefined __<type>_MAX__
- * check-command: test-linearize -Wno-decl $file
- * check-output-ignore
- *
- * check-output-contains: ret\\..*\\$0
- */
diff --git a/validation/preprocessor/predef-sizeof.c b/validation/preprocessor/predef-sizeof.c
deleted file mode 100644
index 12be2dd1..00000000
--- a/validation/preprocessor/predef-sizeof.c
+++ /dev/null
@@ -1,25 +0,0 @@
-#define TEST(X, T) if (__SIZEOF_ ## X ## __ != sizeof(T)) return 1
-
-int test_sizeof(void)
-{
- TEST(SHORT, short);
- TEST(INT, int);
- TEST(LONG, long);
- TEST(LONG_LONG, long long);
- TEST(INT128, __int128);
- TEST(SIZE_T, __SIZE_TYPE__);
- TEST(POINTER, void*);
- TEST(FLOAT, float);
- TEST(DOUBLE, double);
- TEST(LONG_DOUBLE, long double);
-
- return 0;
-}
-
-/*
- * check-name: predefined __SIZEOF_<type>__
- * check-command: test-linearize -Wno-decl $file
- * check-output-ignore
- *
- * check-output-contains: ret\\..*\\$0
- */
diff --git a/validation/preprocessor/predef-unsigned.c b/validation/preprocessor/predef-unsigned.c
new file mode 100644
index 00000000..0ae4d165
--- /dev/null
+++ b/validation/preprocessor/predef-unsigned.c
@@ -0,0 +1,9 @@
+#include "predef.c"
+
+/*
+ * check-name: predefined macros for -funsigned-char
+ * check-command: test-linearize -Wno-decl -funsigned-char $file
+ * check-output-ignore
+ *
+ * check-output-contains: ret\\..*\\$0
+ */
diff --git a/validation/preprocessor/predef.c b/validation/preprocessor/predef.c
new file mode 100644
index 00000000..5678aced
--- /dev/null
+++ b/validation/preprocessor/predef.c
@@ -0,0 +1,57 @@
+#define BITS(T) (sizeof(T) * 8)
+#define SIGN_BIT(T) (1ULL << (BITS(T) - 1))
+#define SMASK(T) (SIGN_BIT(T) - 1)
+#define UMASK(T) (SIGN_BIT(T) | SMASK(T))
+
+int test(void);
+int test(void)
+{
+#define TEST_BIT(X, T) if (__ ## X ## _BIT__ != BITS(T)) return 1
+ TEST_BIT(CHAR, char);
+
+#define TEST_MAX(X, M) if (__ ## X ## _MAX__ != M) return 1
+#define TEST_SMAX(X, T) TEST_MAX(X, SMASK(T))
+#define TEST_UMAX(X, T) TEST_MAX(X, UMASK(T))
+ TEST_SMAX(SCHAR, signed char);
+ TEST_SMAX(SHRT, short);
+ TEST_SMAX(INT, int);
+ TEST_SMAX(LONG, long);
+ TEST_SMAX(LONG_LONG, long long);
+ TEST_MAX( INT8, 0x7f);
+ TEST_MAX(UINT8, 0xffU);
+ TEST_MAX( INT16, 0x7fff);
+ TEST_MAX(UINT16, 0xffffU);
+ TEST_MAX( INT32, 0x7fffffff);
+ TEST_MAX(UINT32, 0xffffffffU);
+ TEST_MAX( INT64, 0x7fffffffffffffffLL);
+ TEST_MAX(UINT64, 0xffffffffffffffffULL);
+ TEST_SMAX(INTMAX, __INTMAX_TYPE__);
+ TEST_UMAX(UINTMAX, __UINTMAX_TYPE__);
+ TEST_SMAX(INTPTR, __INTPTR_TYPE__);
+ TEST_UMAX(UINTPTR, __UINTPTR_TYPE__);
+ TEST_SMAX(PTRDIFF, __PTRDIFF_TYPE__);
+ TEST_UMAX(SIZE, __SIZE_TYPE__);
+
+#define TEST_SIZEOF(X, T) if (__SIZEOF_ ## X ## __ != sizeof(T)) return 1
+ TEST_SIZEOF(SHORT, short);
+ TEST_SIZEOF(INT, int);
+ TEST_SIZEOF(LONG, long);
+ TEST_SIZEOF(LONG_LONG, long long);
+ TEST_SIZEOF(INT128, __int128);
+ TEST_SIZEOF(PTRDIFF_T, __PTRDIFF_TYPE__);
+ TEST_SIZEOF(SIZE_T, __SIZE_TYPE__);
+ TEST_SIZEOF(POINTER, void*);
+ TEST_SIZEOF(FLOAT, float);
+ TEST_SIZEOF(DOUBLE, double);
+ TEST_SIZEOF(LONG_DOUBLE, long double);
+
+ return 0;
+}
+
+/*
+ * check-name: predefined macros: __SIZEOF_<type>__, ...
+ * check-command: test-linearize -Wno-decl $file
+ * check-output-ignore
+ *
+ * check-output-contains: ret\\..*\\$0
+ */