IA MCU psABI support: GCC changes
authorH.J. Lu <hongjiu.lu@intel.com>
Tue, 30 Jun 2015 16:40:19 +0000 (16:40 +0000)
committerH.J. Lu <hjl@gcc.gnu.org>
Tue, 30 Jun 2015 16:40:19 +0000 (09:40 -0700)
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

12 files changed:
ChangeLog
configure
configure.ac
gcc/ChangeLog
gcc/common/config/i386/i386-common.c
gcc/config.gcc
gcc/config/i386/i386-c.c
gcc/config/i386/i386.c
gcc/config/i386/i386.h
gcc/config/i386/i386.opt
gcc/config/i386/iamcu.h [new file with mode: 0644]
gcc/doc/invoke.texi

index 1bc0be284834233a82ab415a0d6282214669309f..5ef6a7ad0c0b1abf5f3b7cef24907bef4abf883e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+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.
index bced9de413e97bdf1e14aae559ba166919abc669..82e45f3bd3995053d85fb0ce6ca54f7075080166 100755 (executable)
--- 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:* | :*)
index 7c06e6ba9fad60ccd511c4809ca777c10a94fe76..dc77a1baeda7e8aa0b89b52158861b780834332b 100644 (file)
@@ -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:* | :*)
index 92953b2f3f220cd8fe9c93dcc25f9f269e737abe..bd460912172bdde6a44cad91cfc74d416ead8143 100644 (file)
@@ -1,3 +1,34 @@
+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
index 0f8c3e1df04c9274640dfefd849f6fad9b9822c6..79b2472dc750973c30a319d1e8c7b9fbfba41b02 100644 (file)
@@ -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)
        {
index 805638d726139a77543fdf89935263238ceab91b..2b3af82be940dae3200681e629b3e4f1ca3b7326 100644 (file)
@@ -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"
        ;;
index d5063457b904de77288a2137709131c5fe566a15..304ce551d201e09bd5f474825568e61588ddd254 100644 (file)
@@ -425,6 +425,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__");
+    }
 }
 
 \f
index 144c1a6fd67f5476cd04597c4c592080dccd6247..7d26e8c2bd00df18fc916619615d605ec85e59e2 100644 (file)
@@ -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;
 
@@ -27334,6 +27390,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
@@ -27368,6 +27452,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)
@@ -27477,6 +27564,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:
 
@@ -43187,6 +43278,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
index e0af36cec34dafd3c3066afe494e2da292cb4f5d..d710b3d2643b8a0b2589806d02b6b2578a687d1c 100644 (file)
@@ -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
index dd46e26de39493c0977a593745a4713f720055f2..042f3c1ab2002756a22f2f2b6a287e78a0f91a59 100644 (file)
@@ -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 (file)
index 0000000..a1c83f4
--- /dev/null
@@ -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"
index 02b1493d9d4e399530a4c456ad6646ce907f1324..0413106deb07e17e96bd63ab3a3d9db2fa28668a 100644 (file)
@@ -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}}
@@ -23289,10 +23289,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
@@ -23311,6 +23313,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