diff options
author | hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-06-30 16:40:19 +0000 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2016-04-16 07:47:13 -0700 |
commit | 8d0fae23d563776f4f07e578b5bba1b56ac70f67 (patch) | |
tree | 3e72c99e0f51ee8808ec198e4fc8690d04634602 | |
parent | 44fa4819ad03d73d85229b2370fd2b5b4df2ebe8 (diff) | |
download | gcc-8d0fae23d563776f4f07e578b5bba1b56ac70f67.tar.gz |
IA MCU psABI support: GCC changes
This patch introduces basic IA MCU psABI support into GCC.
* configure.ac (ospace_frag): Enable for i?86*-*-elfiamcu
target.
* configure: Regenerate.
gcc/
* config.gcc: Support i[34567]86-*-elfiamcu target.
* config/i386/iamcu.h: New.
* config/i386/i386.opt: Add -miamcu.
* doc/invoke.texi: Document -miamcu.
* common/config/i386/i386-common.c (ix86_handle_option): Turn
off x87/MMX/SSE/AVX codegen for -miamcu.
* config/i386/i386-c.c (ix86_target_macros_internal): Define
__iamcu/__iamcu__ for -miamcu.
* config/i386/i386.h (PREFERRED_STACK_BOUNDARY_DEFAULT): Set
to MIN_STACK_BOUNDARY if TARGET_IAMCU is true.
(BIGGEST_ALIGNMENT): Set to 32 if TARGET_IAMCU is true.
* config/i386/i386.c (ix86_option_override_internal): Ignore and
warn -mregparm for Intel MCU. Turn on -mregparm=3 for Intel
MCU by default. Default long double to 64-bit for Intel MCU.
Turn on -freg-struct-return for Intel MCU. Issue an error when
-miamcu is used in 64-bit or x32 mode or if x87, MMX, SSE or
AVX is turned on.
(function_arg_advance_32): Pass value whose size is no larger
than 8 bytes in registers for Intel MCU.
(function_arg_32): Likewise.
(ix86_return_in_memory): Return value whose size is no larger
than 8 bytes in registers for Intel MCU.
(iamcu_alignment): New function.
(ix86_data_alignment): Call iamcu_alignment if TARGET_IAMCU is
true.
(ix86_local_alignment): Don't increase alignment for Intel MCU.
(x86_field_alignment): Return iamcu_alignment if TARGET_IAMCU is
true.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@225197 138bc75d-0d04-0410-961f-82ee72b054a4
-rwxr-xr-x | configure | 2 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | gcc/common/config/i386/i386-common.c | 16 | ||||
-rw-r--r-- | gcc/config.gcc | 3 | ||||
-rw-r--r-- | gcc/config/i386/i386-c.c | 5 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 105 | ||||
-rw-r--r-- | gcc/config/i386/i386.h | 5 | ||||
-rw-r--r-- | gcc/config/i386/i386.opt | 4 | ||||
-rw-r--r-- | gcc/config/i386/iamcu.h | 42 | ||||
-rw-r--r-- | gcc/doc/invoke.texi | 7 |
10 files changed, 179 insertions, 12 deletions
diff --git a/configure b/configure index a3f66bac77e..6ed6267daf2 100755 --- a/configure +++ b/configure @@ -6905,7 +6905,7 @@ case "${enable_target_optspace}:${target}" in :d30v-*) ospace_frag="config/mt-d30v" ;; - :m32r-* | :d10v-* | :fr30-*) + :m32r-* | :d10v-* | :fr30-* | :i?86*-*-elfiamcu) ospace_frag="config/mt-ospace" ;; no:* | :*) diff --git a/configure.ac b/configure.ac index 987dfab411d..aba2a964e93 100644 --- a/configure.ac +++ b/configure.ac @@ -2551,7 +2551,7 @@ case "${enable_target_optspace}:${target}" in :d30v-*) ospace_frag="config/mt-d30v" ;; - :m32r-* | :d10v-* | :fr30-*) + :m32r-* | :d10v-* | :fr30-* | :i?86*-*-elfiamcu) ospace_frag="config/mt-ospace" ;; no:* | :*) diff --git a/gcc/common/config/i386/i386-common.c b/gcc/common/config/i386/i386-common.c index 0f8c3e1df04..79b2472dc75 100644 --- a/gcc/common/config/i386/i386-common.c +++ b/gcc/common/config/i386/i386-common.c @@ -223,7 +223,7 @@ along with GCC; see the file COPYING3. If not see bool ix86_handle_option (struct gcc_options *opts, - struct gcc_options *opts_set ATTRIBUTE_UNUSED, + struct gcc_options *opts_set, const struct cl_decoded_option *decoded, location_t loc) { @@ -232,6 +232,20 @@ ix86_handle_option (struct gcc_options *opts, switch (code) { + case OPT_miamcu: + if (value) + { + /* Turn off x87/MMX/SSE/AVX codegen for -miamcu. */ + opts->x_target_flags &= ~MASK_80387; + opts_set->x_target_flags |= MASK_80387; + opts->x_ix86_isa_flags &= ~(OPTION_MASK_ISA_MMX_UNSET + | OPTION_MASK_ISA_SSE_UNSET); + opts->x_ix86_isa_flags_explicit |= (OPTION_MASK_ISA_MMX_UNSET + | OPTION_MASK_ISA_SSE_UNSET); + + } + return true; + case OPT_mmmx: if (value) { diff --git a/gcc/config.gcc b/gcc/config.gcc index c835734128b..3db57177a89 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -1371,6 +1371,9 @@ x86_64-*-darwin*) tmake_file="${tmake_file} ${cpu_type}/t-darwin64 t-slibgcc" tm_file="${tm_file} ${cpu_type}/darwin64.h" ;; +i[34567]86-*-elfiamcu) + tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h newlib-stdint.h i386/iamcu.h" + ;; i[34567]86-*-elf*) tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h newlib-stdint.h i386/i386elf.h" ;; diff --git a/gcc/config/i386/i386-c.c b/gcc/config/i386/i386-c.c index f3f90df06eb..7d10e83a667 100644 --- a/gcc/config/i386/i386-c.c +++ b/gcc/config/i386/i386-c.c @@ -434,6 +434,11 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag, def_or_undef (parse_in, "__CLWB__"); if (isa_flag & OPTION_MASK_ISA_MWAITX) def_or_undef (parse_in, "__MWAITX__"); + if (TARGET_IAMCU) + { + def_or_undef (parse_in, "__iamcu"); + def_or_undef (parse_in, "__iamcu__"); + } } diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 5088592b49e..49e06c7d4a6 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -3420,6 +3420,10 @@ ix86_option_override_internal (bool main_args_p, || TARGET_16BIT_P (opts->x_ix86_isa_flags)) opts->x_ix86_isa_flags &= ~OPTION_MASK_ABI_X32; #endif + if (TARGET_64BIT_P (opts->x_ix86_isa_flags) + && TARGET_IAMCU_P (opts->x_target_flags)) + sorry ("Intel MCU psABI isn%'t supported in %s mode", + TARGET_X32_P (opts->x_ix86_isa_flags) ? "x32" : "64-bit"); } #endif @@ -3804,6 +3808,20 @@ ix86_option_override_internal (bool main_args_p, if (TARGET_X32 && (ix86_isa_flags & OPTION_MASK_ISA_MPX)) error ("Intel MPX does not support x32"); + if (TARGET_IAMCU_P (opts->x_target_flags)) + { + /* Verify that x87/MMX/SSE/AVX is off for -miamcu. */ + if (TARGET_80387_P (opts->x_target_flags)) + sorry ("X87 FPU isn%'t supported in Intel MCU psABI"); + else if ((opts->x_ix86_isa_flags & (OPTION_MASK_ISA_MMX + | OPTION_MASK_ISA_SSE + | OPTION_MASK_ISA_AVX))) + sorry ("%s isn%'t supported in Intel MCU psABI", + TARGET_MMX_P (opts->x_ix86_isa_flags) + ? "MMX" + : TARGET_SSE_P (opts->x_ix86_isa_flags) ? "SSE" : "AVX"); + } + if (!strcmp (opts->x_ix86_arch_string, "generic")) error ("generic CPU can be used only for %stune=%s %s", prefix, suffix, sw); @@ -3891,7 +3909,16 @@ ix86_option_override_internal (bool main_args_p, if (opts->x_flag_asynchronous_unwind_tables == 2) opts->x_flag_asynchronous_unwind_tables = !USE_IX86_FRAME_POINTER; if (opts->x_flag_pcc_struct_return == 2) - opts->x_flag_pcc_struct_return = DEFAULT_PCC_STRUCT_RETURN; + { + /* Intel MCU psABI specifies that -freg-struct-return should + be on. Instead of setting DEFAULT_PCC_STRUCT_RETURN to 1, + we check -miamcu so that -freg-struct-return is always + turned on if -miamcu is used. */ + if (TARGET_IAMCU_P (opts->x_target_flags)) + opts->x_flag_pcc_struct_return = 0; + else + opts->x_flag_pcc_struct_return = DEFAULT_PCC_STRUCT_RETURN; + } } ix86_tune_cost = processor_target_table[ix86_tune].cost; @@ -3910,6 +3937,8 @@ ix86_option_override_internal (bool main_args_p, { if (TARGET_64BIT_P (opts->x_ix86_isa_flags)) warning (0, "-mregparm is ignored in 64-bit mode"); + else if (TARGET_IAMCU_P (opts->x_target_flags)) + warning (0, "-mregparm is ignored for Intel MCU psABI"); if (opts->x_ix86_regparm > REGPARM_MAX) { error ("-mregparm=%d is not between 0 and %d", @@ -3917,7 +3946,8 @@ ix86_option_override_internal (bool main_args_p, opts->x_ix86_regparm = 0; } } - if (TARGET_64BIT_P (opts->x_ix86_isa_flags)) + if (TARGET_IAMCU_P (opts->x_target_flags) + || TARGET_64BIT_P (opts->x_ix86_isa_flags)) opts->x_ix86_regparm = REGPARM_MAX; /* Default align_* from the processor table. */ @@ -4344,8 +4374,9 @@ ix86_option_override_internal (bool main_args_p, opts->x_recip_mask &= ~(RECIP_MASK_ALL & ~opts->x_recip_mask_explicit); /* Default long double to 64-bit for 32-bit Bionic and to __float128 - for 64-bit Bionic. */ - if (TARGET_HAS_BIONIC + for 64-bit Bionic. Also default long double to 64-bit for Intel + MCU psABI. */ + if ((TARGET_HAS_BIONIC || TARGET_IAMCU) && !(opts_set->x_target_flags & (MASK_LONG_DOUBLE_64 | MASK_LONG_DOUBLE_128))) opts->x_target_flags |= (TARGET_64BIT @@ -7463,6 +7494,15 @@ function_arg_advance_32 (CUMULATIVE_ARGS *cum, machine_mode mode, int res = 0; bool error_p = NULL; + if (TARGET_IAMCU) + { + /* Intel MCU psABI passes scalars and aggregates no larger than 8 + bytes in registers. */ + if (bytes <= 8) + goto pass_in_reg; + return res; + } + switch (mode) { default: @@ -7477,6 +7517,7 @@ function_arg_advance_32 (CUMULATIVE_ARGS *cum, machine_mode mode, case SImode: case HImode: case QImode: +pass_in_reg: cum->words += words; cum->nregs -= words; cum->regno += words; @@ -7705,6 +7746,15 @@ function_arg_32 (CUMULATIVE_ARGS *cum, machine_mode mode, if (mode == VOIDmode) return constm1_rtx; + if (TARGET_IAMCU) + { + /* Intel MCU psABI passes scalars and aggregates no larger than 8 + bytes in registers. */ + if (bytes <= 8) + goto pass_in_reg; + return NULL_RTX; + } + switch (mode) { default: @@ -7718,6 +7768,7 @@ function_arg_32 (CUMULATIVE_ARGS *cum, machine_mode mode, case SImode: case HImode: case QImode: +pass_in_reg: if (words <= cum->nregs) { int regno = cum->regno; @@ -8558,11 +8609,16 @@ ix86_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED) } else { + size = int_size_in_bytes (type); + + /* Intel MCU psABI returns scalars and aggregates no larger than 8 + bytes in registers. */ + if (TARGET_IAMCU) + return size > 8; + if (mode == BLKmode) return true; - size = int_size_in_bytes (type); - if (MS_AGGREGATE_RETURN && AGGREGATE_TYPE_P (type) && size <= 8) return false; @@ -27505,6 +27561,34 @@ ix86_constant_alignment (tree exp, int align) return align; } +/* Compute the alignment for a variable for Intel MCU psABI. TYPE is + the data type, and ALIGN is the alignment that the object would + ordinarily have. */ + +static int +iamcu_alignment (tree type, int align) +{ + enum machine_mode mode; + + if (align < 32 || TYPE_USER_ALIGN (type)) + return align; + + /* Intel MCU psABI specifies scalar types > 4 bytes aligned to 4 + bytes. */ + mode = TYPE_MODE (strip_array_types (type)); + switch (GET_MODE_CLASS (mode)) + { + case MODE_INT: + case MODE_COMPLEX_INT: + case MODE_COMPLEX_FLOAT: + case MODE_FLOAT: + case MODE_DECIMAL_FLOAT: + return 32; + default: + return align; + } +} + /* Compute the alignment for a static variable. TYPE is the data type, and ALIGN is the alignment that the object would ordinarily have. The value of this function is used @@ -27539,6 +27623,9 @@ ix86_data_alignment (tree type, int align, bool opt) case ix86_align_data_type_cacheline: break; } + if (TARGET_IAMCU) + align = iamcu_alignment (type, align); + if (opt && AGGREGATE_TYPE_P (type) && TYPE_SIZE (type) @@ -27648,6 +27735,10 @@ ix86_local_alignment (tree exp, machine_mode mode, return align; } + /* Don't increase alignment for Intel MCU psABI. */ + if (TARGET_IAMCU) + return align; + /* x86-64 ABI requires arrays greater than 16 bytes to be aligned to 16byte boundary. Exact wording is: @@ -43372,6 +43463,8 @@ x86_field_alignment (tree field, int computed) if (TARGET_64BIT || TARGET_ALIGN_DOUBLE) return computed; + if (TARGET_IAMCU) + return iamcu_alignment (type, computed); mode = TYPE_MODE (strip_array_types (type)); if (mode == DFmode || mode == DCmode || GET_MODE_CLASS (mode) == MODE_INT diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index d5a52631081..1d32b11f76e 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -756,7 +756,8 @@ extern const char *host_detect_local_cpu (int argc, const char **argv); /* It should be MIN_STACK_BOUNDARY. But we set it to 128 bits for both 32bit and 64bit, to support codes that need 128 bit stack alignment for SSE instructions, but can't realign the stack. */ -#define PREFERRED_STACK_BOUNDARY_DEFAULT 128 +#define PREFERRED_STACK_BOUNDARY_DEFAULT \ + (TARGET_IAMCU ? MIN_STACK_BOUNDARY : 128) /* 1 if -mstackrealign should be turned on by default. It will generate an alternate prologue and epilogue that realigns the @@ -803,7 +804,7 @@ extern const char *host_detect_local_cpu (int argc, const char **argv); TARGET_ABSOLUTE_BIGGEST_ALIGNMENT. */ #define BIGGEST_ALIGNMENT \ - (TARGET_AVX512F ? 512 : (TARGET_AVX ? 256 : 128)) + (TARGET_AVX512F ? 512 : (TARGET_AVX ? 256 : (TARGET_IAMCU ? 32 : 128))) /* Maximum stack alignment. */ #define MAX_STACK_ALIGNMENT MAX_OFILE_ALIGNMENT diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt index dd46e26de39..042f3c1ab20 100644 --- a/gcc/config/i386/i386.opt +++ b/gcc/config/i386/i386.opt @@ -514,6 +514,10 @@ Clear all tune features mdump-tune-features Target RejectNegative Var(ix86_dump_tunes) Init(0) +miamcu +Target Report Mask(IAMCU) +Generate code that conforms to Intel MCU psABI + mabi= Target RejectNegative Joined Var(ix86_abi) Enum(calling_abi) Init(SYSV_ABI) Generate code that conforms to the given ABI diff --git a/gcc/config/i386/iamcu.h b/gcc/config/i386/iamcu.h new file mode 100644 index 00000000000..a1c83f4dc13 --- /dev/null +++ b/gcc/config/i386/iamcu.h @@ -0,0 +1,42 @@ +/* Definitions of target machine for Intel MCU psABI. + Copyright (C) 2015 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC 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 3, or (at your option) +any later version. + +GCC 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. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +/* Intel MCU has no 80387. Default to Intel MCU psABI. */ +#undef TARGET_SUBTARGET_DEFAULT +#define TARGET_SUBTARGET_DEFAULT MASK_IAMCU + +#undef ASM_SPEC +#define ASM_SPEC "--32 -march=iamcu" + +#undef LINK_SPEC +#define LINK_SPEC "-m elf_iamcu" + +#undef ENDFILE_SPEC +#define ENDFILE_SPEC "" + +#undef STARTFILE_SPEC +#define STARTFILE_SPEC "crt0.o%s" + +#undef LIB_SPEC +#define LIB_SPEC "--start-group -lc -lgloss --end-group" diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 7c1ddaf3ce5..5d9f16eb588 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -1087,7 +1087,7 @@ See RS/6000 and PowerPC Options. -mpc32 -mpc64 -mpc80 -mstackrealign @gol -momit-leaf-frame-pointer -mno-red-zone -mno-tls-direct-seg-refs @gol -mcmodel=@var{code-model} -mabi=@var{name} -maddress-mode=@var{mode} @gol --m32 -m64 -mx32 -m16 -mlarge-data-threshold=@var{num} @gol +-m32 -m64 -mx32 -m16 -miamcu -mlarge-data-threshold=@var{num} @gol -msse2avx -mfentry -mrecord-mcount -mnop-mcount -m8bit-idiv @gol -mavx256-split-unaligned-load -mavx256-split-unaligned-store @gol -malign-data=@var{type} -mstack-protector-guard=@var{guard}} @@ -23023,10 +23023,12 @@ on x86-64 processors in 64-bit environments. @itemx -m64 @itemx -mx32 @itemx -m16 +@itemx -miamcu @opindex m32 @opindex m64 @opindex mx32 @opindex m16 +@opindex miamcu Generate code for a 16-bit, 32-bit or 64-bit environment. The @option{-m32} option sets @code{int}, @code{long}, and pointer types to 32 bits, and @@ -23045,6 +23047,9 @@ The @option{-m16} option is the same as @option{-m32}, except for that it outputs the @code{.code16gcc} assembly directive at the beginning of the assembly output so that the binary can run in 16-bit mode. +The @option{-miamcu} option generates code which conforms to Intel MCU +psABI. It requires the @option{-m32} option to be turned on. + @item -mno-red-zone @opindex mno-red-zone Do not use a so-called ``red zone'' for x86-64 code. The red zone is mandated |