summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>2015-06-30 16:40:19 +0000
committerH.J. Lu <hjl.tools@gmail.com>2016-04-16 07:47:13 -0700
commit8d0fae23d563776f4f07e578b5bba1b56ac70f67 (patch)
tree3e72c99e0f51ee8808ec198e4fc8690d04634602
parent44fa4819ad03d73d85229b2370fd2b5b4df2ebe8 (diff)
downloadgcc-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-xconfigure2
-rw-r--r--configure.ac2
-rw-r--r--gcc/common/config/i386/i386-common.c16
-rw-r--r--gcc/config.gcc3
-rw-r--r--gcc/config/i386/i386-c.c5
-rw-r--r--gcc/config/i386/i386.c105
-rw-r--r--gcc/config/i386/i386.h5
-rw-r--r--gcc/config/i386/i386.opt4
-rw-r--r--gcc/config/i386/iamcu.h42
-rw-r--r--gcc/doc/invoke.texi7
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