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.
From-SVN: r225197
+2015-06-30 H.J. Lu <hongjiu.lu@intel.com>
+
+ * configure.ac (ospace_frag): Enable for i?86*-*-elfiamcu
+ target.
+ * configure: Regenerate.
+
2015-06-23 Ludovic Courtès <ludo@gnu.org>
* MAINTAINERS (Write After Approval): Add myself.
:d30v-*)
ospace_frag="config/mt-d30v"
;;
- :m32r-* | :d10v-* | :fr30-*)
+ :m32r-* | :d10v-* | :fr30-* | :i?86*-*-elfiamcu)
ospace_frag="config/mt-ospace"
;;
no:* | :*)
:d30v-*)
ospace_frag="config/mt-d30v"
;;
- :m32r-* | :d10v-* | :fr30-*)
+ :m32r-* | :d10v-* | :fr30-* | :i?86*-*-elfiamcu)
ospace_frag="config/mt-ospace"
;;
no:* | :*)
+2015-06-30 H.J. Lu <hongjiu.lu@intel.com>
+
+ * 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.
+
2015-06-30 Marek Polacek <polacek@redhat.com>
* match.pd (X - (X / Y) * Y): Use convert1 and convert2. Convert
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)
{
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)
{
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"
;;
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__");
+ }
}
\f
|| 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
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);
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;
{
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",
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. */
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
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:
case SImode:
case HImode:
case QImode:
+pass_in_reg:
cum->words += words;
cum->nregs -= words;
cum->regno += words;
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:
case SImode:
case HImode:
case QImode:
+pass_in_reg:
if (words <= cum->nregs)
{
int regno = cum->regno;
}
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;
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
case ix86_align_data_type_cacheline: break;
}
+ if (TARGET_IAMCU)
+ align = iamcu_alignment (type, align);
+
if (opt
&& AGGREGATE_TYPE_P (type)
&& TYPE_SIZE (type)
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:
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
/* 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
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
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
--- /dev/null
+/* 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"
-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}}
@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
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