diff options
author | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2019-11-05 00:09:04 +0100 |
---|---|---|
committer | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2019-11-05 00:09:04 +0100 |
commit | fdc1539d3c42e114c90805cde8cfabd132cc7944 (patch) | |
tree | 278ed0b3ae9de7c327252529021e39990aad3dd2 | |
parent | 41a1e45b6e9141a1a914f0ffbd5eb18436516159 (diff) | |
parent | fba1931d2c2779b0b84e4837c51187d9d2fe0226 (diff) | |
download | sparse-fdc1539d3c42e114c90805cde8cfabd132cc7944.tar.gz |
Merge branch 'option-arch'
* add new option, --arch=ARCH, allowing to specify the target arch.
-rwxr-xr-x | cgcc | 67 | ||||
-rw-r--r-- | lib.c | 72 | ||||
-rw-r--r-- | machine.h | 22 | ||||
-rw-r--r-- | sparse.1 | 8 | ||||
-rw-r--r-- | target.c | 22 | ||||
-rw-r--r-- | validation/arch/arm.c | 27 | ||||
-rw-r--r-- | validation/arch/arm64.c | 23 | ||||
-rw-r--r-- | validation/arch/mips32.c | 29 | ||||
-rw-r--r-- | validation/arch/riscv64.c | 27 |
9 files changed, 232 insertions, 65 deletions
@@ -148,30 +148,6 @@ sub quote_arg { # ----------------------------------------------------------------------------- -sub integer_types { - my ($char,@dummy) = @_; - - my %pow2m1 = - (8 => '127', - 16 => '32767', - 32 => '2147483647', - 64 => '9223372036854775807', - 128 => '170141183460469231731687303715884105727', - ); - my @types = (['SCHAR',''], ['SHRT',''], ['INT',''], ['LONG','L'], ['LONG_LONG','LL'], ['LONG_LONG_LONG','LLL']); - - my $result = " -D__CHAR_BIT__=$char"; - while (@types && @_) { - my $bits = shift @_; - my ($name,$suffix) = @{ shift @types }; - die "$0: weird number of bits." unless exists $pow2m1{$bits}; - $result .= " -D__${name}_MAX__=" . $pow2m1{$bits} . $suffix; - } - return $result; -} - -# ----------------------------------------------------------------------------- - sub float_types { my ($has_inf,$has_qnan,$dec_dig,@bitsizes) = @_; my $result = " -D__FLT_RADIX__=2"; @@ -241,14 +217,6 @@ sub float_types { # ----------------------------------------------------------------------------- -sub define_size_t { - my ($text) = @_; - # We have to undef in order to override check's internal definition. - return ' -U__SIZE_TYPE__ ' . "e_arg ("-D__SIZE_TYPE__=$text"); -} - -# ----------------------------------------------------------------------------- - sub add_specs { my ($spec) = @_; if ($spec eq 'sunos') { @@ -294,29 +262,26 @@ sub add_specs { " -D'__declspec(x)=__attribute__((x))'"; } elsif ($spec eq 'i386') { return ( + ' --arch=i386' . &float_types (1, 1, 21, [24,8], [53,11], [64,15])); } elsif ($spec eq 'sparc') { return ( - &integer_types (8, 16, 32, $m64 ? 64 : 32, 64) . - &float_types (1, 1, 33, [24,8], [53,11], [113,15]) . - &define_size_t ($m64 ? "long unsigned int" : "unsigned int") . - ' -D__SIZEOF_POINTER__=' . ($m64 ? '8' : '4')); + ' --arch=sparc' . + &float_types (1, 1, 33, [24,8], [53,11], [113,15])); } elsif ($spec eq 'sparc64') { return ( - &integer_types (8, 16, 32, 64, 64, 128) . - &float_types (1, 1, 33, [24,8], [53,11], [113,15]) . - &define_size_t ("long unsigned int") . - ' -D__SIZEOF_POINTER__=8'); + ' --arch=sparc64' . + &float_types (1, 1, 33, [24,8], [53,11], [113,15])); } elsif ($spec eq 'x86_64') { - return &float_types (1, 1, 33, [24,8], [53,11], [113,15]); + return (' --arch=x86_64' . + &float_types (1, 1, 33, [24,8], [53,11], [113,15])); } elsif ($spec eq 'ppc') { return (' -D_BIG_ENDIAN -D_STRING_ARCH_unaligned=1' . - &integer_types (8, 16, 32, $m64 ? 64 : 32, 64) . - &float_types (1, 1, 21, [24,8], [53,11], [113,15]) . - &define_size_t ($m64 ? "long unsigned int" : "unsigned int") . - ' -D__SIZEOF_POINTER__=' . ($m64 ? '8' : '4')); + ' --arch=ppc' . + &float_types (1, 1, 21, [24,8], [53,11], [113,15])); } elsif ($spec eq 'ppc64') { - return (' -D_STRING_ARCH_unaligned=1 -m64' . + return (' -D_STRING_ARCH_unaligned=1 ' . + ' --arch=ppc64' . &float_types (1, 1, 21, [24,8], [53,11], [113,15])); } elsif ($spec eq 'ppc64+be') { return &add_specs ('ppc64') . ' -mbig-endian -D_CALL_ELF=1'; @@ -324,17 +289,15 @@ sub add_specs { return &add_specs ('ppc64') . ' -mlittle-endian -D_CALL_ELF=2'; } elsif ($spec eq 's390x') { return (' -D_BIG_ENDIAN' . - &integer_types (8, 16, 32, $m64 ? 64 : 32, 64) . - &float_types (1, 1, 36, [24,8], [53,11], [113,15]) . - &define_size_t ("long unsigned int") . - ' -D__SIZEOF_POINTER__=' . ($m64 ? '8' : '4')); + ' --arch=s390x' . + &float_types (1, 1, 36, [24,8], [53,11], [113,15])); } elsif ($spec eq 'arm') { - return (' -m32' . + return (' --arch=arm' . &float_types (1, 1, 36, [24,8], [53,11], [53, 11])); } elsif ($spec eq 'arm+hf') { return &add_specs ('arm') . ' -D__ARM_PCS_VFP=1'; } elsif ($spec eq 'aarch64') { - return (' -m64' . + return (' --arch=aarch64' . &float_types (1, 1, 36, [24,8], [53,11], [113,15])); } elsif ($spec eq 'host_os_specs') { my $os = `uname -s`; @@ -459,6 +459,8 @@ static char **handle_switch_m(char *arg, char **next) arch_m64 = ARCH_LP64; } else if (!strcmp(arg, "m32") || !strcmp(arg, "m16")) { arch_m64 = ARCH_LP32; + } else if (!strcmp(arg, "m31")) { + arch_m64 = ARCH_LP32; } else if (!strcmp(arg, "mx32")) { arch_m64 = ARCH_X32; } else if (!strcmp(arg, "msize-llp64")) { @@ -1094,6 +1096,73 @@ static char **handle_switch_x(char *arg, char **next) } +static char **handle_arch(char *arg, char **next) +{ + static const struct arch { + const char *name; + char mach; + char bits; + bool big_endian:1; + } archs[] = { + { "aarch64", MACH_ARM64, 64, 0 }, + { "arm64", MACH_ARM64, 64, 0 }, + { "arm", MACH_ARM, 32, 0 }, + { "i386", MACH_I386, 32, 0 }, + { "m68k", MACH_M68K, 32, 0 }, + { "mips", MACH_MIPS32, 0, 1 }, + { "powerpc", MACH_PPC32, 0, 1 }, + { "ppc", MACH_PPC32, 0, 1 }, + { "riscv", MACH_RISCV32, 0, 0 }, + { "s390x", MACH_S390X, 64, 1 }, + { "s390", MACH_S390, 32, 1 }, + { "sparc", MACH_SPARC32, 0, 1 }, + { "x86_64", MACH_X86_64, 64, 0 }, + { "x86-64", MACH_X86_64, 64, 0 }, + { NULL }, + }; + const struct arch *p; + + if (*arg++ != '=') + die("missing argument for --arch option"); + + for (p = &archs[0]; p->name; p++) { + size_t len = strlen(p->name); + if (strncmp(p->name, arg, len) == 0) { + const char *suf = arg + len; + int bits = p->bits; + + arch_mach = p->mach; + if (bits == 0) { + if (!strcmp(suf, "")) { + bits = 32; + } else if (!strcmp(suf, "32")) { + bits = 32; + } else if (!strcmp(suf, "64")) { + bits = 64; + arch_mach += 1; + } else { + die("invalid architecture: %s", arg); + } + } else { + if (strcmp(suf, "")) + die("invalid architecture: %s", arg); + } + + // adjust the arch size (but keep x32 & llp64) + if (bits == 32) + arch_m64 = ARCH_LP32; + else if (bits == 64 && arch_m64 == ARCH_LP32) + arch_m64 = ARCH_LP64; + if (p->big_endian) + arch_big_endian = 1; + + break; + } + } + + return next; +} + static char **handle_version(char *arg, char **next) { printf("%s\n", SPARSE_VERSION); @@ -1126,6 +1195,7 @@ struct switches { static char **handle_long_options(char *arg, char **next) { static struct switches cmd[] = { + { "arch", handle_arch, 1 }, { "param", handle_param, 1 }, { "version", handle_version }, { NULL, NULL } @@ -1428,6 +1498,7 @@ static void predefined_macros(void) predefine("__mips64", 1, "64"); /* fall-through */ case MACH_MIPS32: + predefine("__mips__", 1, "1"); predefine("__mips", 1, "%d", ptr_ctype.bit_size); predefine("_MIPS_SZINT", 1, "%d", int_ctype.bit_size); predefine("_MIPS_SZLONG", 1, "%d", long_ctype.bit_size); @@ -1454,6 +1525,7 @@ static void predefined_macros(void) case MACH_S390X: predefine("__zarch__", 1, "1"); predefine("__s390x__", 1, "1"); + case MACH_S390: predefine("__s390__", 1, "1"); break; case MACH_SPARC64: @@ -25,20 +25,14 @@ enum { 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_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_S390, MACH_S390X, MACH_M68K, - MACH_S390X, MACH_UNKNOWN }; @@ -70,6 +64,8 @@ enum machine { #define MACH_NATIVE MACH_M68K #elif defined(__s390x__) || defined(__zarch__) #define MACH_NATIVE MACH_S390X +#elif defined(__s390__) +#define MACH_NATIVE MACH_S390 #else #define MACH_NATIVE MACH_UNKNOWN #endif @@ -423,6 +423,14 @@ Sparse does not issue these warnings by default. . .SH MISC OPTIONS .TP +.B \-\-arch=\fIARCH\fR +Specify the target architecture. +For architectures having both a 32-bit and a 64-bit variant (mips, powerpc, +riscv & sparc) the architecture name can be suffixed with \fI32\fR or \fI64\fR. + +The default architecture & size is the one of the machine used to build Sparse. +. +.TP .B \-gcc-base-dir \fIdir\fR Look for compiler-provided system headers in \fIdir\fR/include/ and \fIdir\fR/include-fixed/. . @@ -58,6 +58,27 @@ int enum_alignment = 4; void init_target(void) { switch (arch_mach) { + case MACH_I386: + case MACH_MIPS32: + case MACH_PPC32: + case MACH_RISCV32: + case MACH_SPARC32: + case MACH_S390: + if (arch_m64 == ARCH_LP64) + arch_mach++; + break; + case MACH_X86_64: + case MACH_MIPS64: + case MACH_PPC64: + case MACH_RISCV64: + case MACH_SPARC64: + case MACH_S390X: + if (arch_m64 == ARCH_LP32) + arch_mach--; + break; + } + + switch (arch_mach) { case MACH_X86_64: if (arch_m64 == ARCH_LP64) break; @@ -97,6 +118,7 @@ void init_target(void) switch (arch_mach) { case MACH_ARM: case MACH_MIPS32: + case MACH_S390: case MACH_S390X: case MACH_SPARC32: bits_in_longdouble = 64; diff --git a/validation/arch/arm.c b/validation/arch/arm.c new file mode 100644 index 00000000..4eb804de --- /dev/null +++ b/validation/arch/arm.c @@ -0,0 +1,27 @@ +__arm__ +__aarch64__ +__i386__ +__x86_64__ +__LP64__ +__BYTE_ORDER__ +__SIZEOF_INT__ +__SIZEOF_LONG__ +__SIZE_TYPE__ + +/* + * check-name: arch/arm + * check-command: sparse --arch=arm -E $file + * + * check-output-start + +1 +__aarch64__ +__i386__ +__x86_64__ +__LP64__ +1234 +4 +4 +unsigned int + * check-output-end + */ diff --git a/validation/arch/arm64.c b/validation/arch/arm64.c new file mode 100644 index 00000000..12f839cc --- /dev/null +++ b/validation/arch/arm64.c @@ -0,0 +1,23 @@ +__aarch64__ +__x86_64__ +__LP64__ +__BYTE_ORDER__ +__SIZEOF_INT__ +__SIZEOF_LONG__ +__SIZE_TYPE__ + +/* + * check-name: arch/arm64 + * check-command: sparse --arch=arm64 -E $file + * + * check-output-start + +1 +__x86_64__ +1 +1234 +4 +8 +unsigned long + * check-output-end + */ diff --git a/validation/arch/mips32.c b/validation/arch/mips32.c new file mode 100644 index 00000000..339218b6 --- /dev/null +++ b/validation/arch/mips32.c @@ -0,0 +1,29 @@ +__mips__ +__mips +__mips64__ +__i386__ +__x86_64__ +__LP64__ +__BYTE_ORDER__ +__SIZEOF_INT__ +__SIZEOF_LONG__ +__SIZE_TYPE__ + +/* + * check-name: arch/mips32 + * check-command: sparse --arch=mips32 -E $file + * + * check-output-start + +1 +32 +__mips64__ +__i386__ +__x86_64__ +__LP64__ +4321 +4 +4 +unsigned int + * check-output-end + */ diff --git a/validation/arch/riscv64.c b/validation/arch/riscv64.c new file mode 100644 index 00000000..9da7a7de --- /dev/null +++ b/validation/arch/riscv64.c @@ -0,0 +1,27 @@ +__riscv +__riscv_xlen +__i386__ +__x86_64__ +__LP64__ +__BYTE_ORDER__ +__SIZEOF_INT__ +__SIZEOF_LONG__ +__SIZE_TYPE__ + +/* + * check-name: arch/riscv64 + * check-command: sparse --arch=riscv64 -E $file + * + * check-output-start + +1 +64 +__i386__ +__x86_64__ +1 +1234 +4 +8 +unsigned long + * check-output-end + */ |