On Mon, Jun 22, 2015 at 4:36 PM, Kirill Yukhin <kirill.yuk...@gmail.com> wrote: > Hello, > This patch introduces basic support into GCC. > > Bootstrapped and regtested. > > / > * 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.
Please avoid lines here. Just go with the sentences one after another, separated with two spaces. > (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. > > Is it OK for trunk? OK. Thanks, Uros. > > -- > Thanks, K > > diff --git a/configure b/configure > index bced9de..82e45f3 100755 > --- a/configure > +++ b/configure > @@ -6914,7 +6914,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 7c06e6b..dc77a1b 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -2560,7 +2560,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 0f8c3e1..79b2472 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 805638d..2b3af82 100644 > --- a/gcc/config.gcc > +++ b/gcc/config.gcc > @@ -1389,6 +1389,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 0228f4b..66f7e37 100644 > --- a/gcc/config/i386/i386-c.c > +++ b/gcc/config/i386/i386-c.c > @@ -426,6 +426,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 24fccfc..26ffa67 100644 > --- a/gcc/config/i386/i386.c > +++ b/gcc/config/i386/i386.c > @@ -3433,6 +3433,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 > > @@ -3817,6 +3821,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); > @@ -3904,7 +3922,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; > @@ -3923,6 +3950,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", > @@ -3930,7 +3959,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. */ > @@ -4334,8 +4364,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 > @@ -7455,6 +7486,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: > @@ -7469,6 +7509,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; > @@ -7702,6 +7743,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: > @@ -7715,6 +7765,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; > @@ -8561,11 +8612,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; > > @@ -27341,6 +27397,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 > @@ -27375,6 +27459,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) > @@ -27484,6 +27571,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: > > @@ -43182,6 +43273,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 e0af36c..d710b3d 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 dd46e26..042f3c1 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 0000000..a1c83f4 > --- /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 b99ab1c..e4f816f 100644 > --- a/gcc/doc/invoke.texi > +++ b/gcc/doc/invoke.texi > @@ -1096,7 +1096,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}} > @@ -23267,10 +23267,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 > @@ -23289,6 +23291,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