Skip to content

Commit

Permalink
IA MCU psABI support: GCC changes
Browse files Browse the repository at this point in the history
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
  • Loading branch information
hjl committed Jun 30, 2015
1 parent 754e086 commit 1c26a2e
Show file tree
Hide file tree
Showing 12 changed files with 216 additions and 12 deletions.
6 changes: 6 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
2015-06-30 H.J. Lu <[email protected]>

* configure.ac (ospace_frag): Enable for i?86*-*-elfiamcu
target.
* configure: Regenerate.

2015-06-23 Ludovic Courtès <[email protected]>

* MAINTAINERS (Write After Approval): Add myself.
Expand Down
2 changes: 1 addition & 1 deletion configure
Original file line number Diff line number Diff line change
Expand Up @@ -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:* | :*)
Expand Down
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -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:* | :*)
Expand Down
31 changes: 31 additions & 0 deletions gcc/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,34 @@
2015-06-30 H.J. Lu <[email protected]>

* 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 <[email protected]>

* match.pd (X - (X / Y) * Y): Use convert1 and convert2. Convert
Expand Down
16 changes: 15 additions & 1 deletion gcc/common/config/i386/i386-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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)
{
Expand Down
3 changes: 3 additions & 0 deletions gcc/config.gcc
Original file line number Diff line number Diff line change
Expand Up @@ -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"
;;
Expand Down
5 changes: 5 additions & 0 deletions gcc/config/i386/i386-c.c
Original file line number Diff line number Diff line change
Expand Up @@ -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__");
}
}


Expand Down
105 changes: 99 additions & 6 deletions gcc/config/i386/i386.c
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -3923,14 +3950,17 @@ 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",
opts->x_ix86_regparm, REGPARM_MAX);
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. */
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand All @@ -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;
Expand Down Expand Up @@ -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:
Expand All @@ -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;
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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:

Expand Down Expand Up @@ -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
Expand Down
5 changes: 3 additions & 2 deletions gcc/config/i386/i386.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions gcc/config/i386/i386.opt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading

0 comments on commit 1c26a2e

Please sign in to comment.