This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [i386, PATCH, 1/3] IA MCU psABI support: GCC changes.
- From: Uros Bizjak <ubizjak at gmail dot com>
- To: Kirill Yukhin <kirill dot yukhin at gmail dot com>
- Cc: "Joseph S. Myers" <joseph at codesourcery dot com>, "H.J. Lu" <hjl dot tools at gmail dot com>, GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 26 Jun 2015 12:38:25 +0200
- Subject: Re: [i386, PATCH, 1/3] IA MCU psABI support: GCC changes.
- Authentication-results: sourceware.org; auth=none
- References: <20150622124020 dot GB53692 at msticlxl57 dot ims dot intel dot com> <20150622143621 dot GA2798 at msticlxl57 dot ims dot intel dot com>
On Mon, Jun 22, 2015 at 4:36 PM, Kirill Yukhin <kirill.yukhin@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