diff --git a/gcc/config.gcc b/gcc/config.gcc index 0defa13dc69..bae0c640e27 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -1764,7 +1764,7 @@ epiphany-*-elf | epiphany-*-rtems*) extra_headers="epiphany_intrinsics.h" ;; *-fcx-*) - tm_file="${tm_file} elfos.h gnu-user.h freebsd-spec.h newlib-stdint.h rs6000/sysv4.h rs6000/eabi.h rs6000/eabialtivec.h" + tm_file="${tm_file} elfos.h gnu-user.h freebsd-spec.h newlib-stdint.h rs6000/sysv4.h rs6000/eabi.h rs6000/eabialtivec.h rs6000/xenon.h" extra_options="${extra_options} rs6000/sysv4.opt" tmake_file="rs6000/t-fprules rs6000/t-ppcendian rs6000/t-ppccomm" use_gcc_stdint=wrap diff --git a/gcc/config/rs6000/rs6000-c.cc b/gcc/config/rs6000/rs6000-c.cc index 6229c503bd0..c2d2821f856 100644 --- a/gcc/config/rs6000/rs6000-c.cc +++ b/gcc/config/rs6000/rs6000-c.cc @@ -753,6 +753,8 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfile) case ABI_DARWIN: builtin_define ("_CALL_DARWIN"); break; + case ABI_XENON: + builtin_define ("_CALL_SYSV"); /* Should be okay? */ default: break; } diff --git a/gcc/config/rs6000/rs6000-logue.cc b/gcc/config/rs6000/rs6000-logue.cc index edc0d6c8f52..470b03c3035 100644 --- a/gcc/config/rs6000/rs6000-logue.cc +++ b/gcc/config/rs6000/rs6000-logue.cc @@ -851,6 +851,23 @@ rs6000_stack_info (void) info->ehrd_offset -= ehrd_size; info->lr_save_offset = reg_size; + break; + + case ABI_XENON: + info->gp_save_offset = -0xC - info->gp_size; + info->fp_save_offset = info->gp_save_offset - info->fp_size; + info->vrsave_save_offset = info->fp_save_offset - info->vrsave_size; + + /* Align stack so vector save area is on a quadword boundary. */ + if (info->altivec_size != 0) + info->altivec_padding_size = 16 - (-info->vrsave_save_offset % 16); + + info->altivec_save_offset = info->vrsave_save_offset + - info->altivec_padding_size + - info->altivec_size; + + info->lr_save_offset = -0x8; + break; } save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8; @@ -870,12 +887,18 @@ rs6000_stack_info (void) info->total_size = RS6000_ALIGN (non_fixed_size + info->fixed_size, ABI_STACK_BOUNDARY / BITS_PER_UNIT); + if(DEFAULT_ABI == ABI_XENON) + /* 0x10 == unknown area (empty?), 0x40 == slots for callee to store r3->r10, */ + /* 0xC == space before saved regs */ + info->total_size += RS6000_ALIGN(0x10 + 0x40 + 0xC, ABI_STACK_BOUNDARY / BITS_PER_UNIT); + /* Determine if we need to save the link register. */ if (info->calls_p || ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && crtl->profile && !TARGET_PROFILE_KERNEL) || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca) + || DEFAULT_ABI == ABI_XENON #ifdef TARGET_RELOCATABLE || (DEFAULT_ABI == ABI_V4 && (TARGET_RELOCATABLE || flag_pic > 1) @@ -948,6 +971,7 @@ debug_stack_info (rs6000_stack_t *info) case ABI_ELFv2: abi_string = "ELFv2"; break; case ABI_DARWIN: abi_string = "Darwin"; break; case ABI_V4: abi_string = "V.4"; break; + case ABI_XENON: abi_string = "Xenon"; break; } fprintf (stderr, "\tABI = %5s\n", abi_string); diff --git a/gcc/config/rs6000/rs6000-opts.h b/gcc/config/rs6000/rs6000-opts.h index 33fd0efc936..99015983593 100644 --- a/gcc/config/rs6000/rs6000-opts.h +++ b/gcc/config/rs6000/rs6000-opts.h @@ -102,7 +102,8 @@ enum rs6000_abi { ABI_AIX, /* IBM's AIX, or Linux ELFv1 */ ABI_ELFv2, /* Linux ELFv2 ABI */ ABI_V4, /* System V.4/eabi */ - ABI_DARWIN /* Apple's Darwin (OS X kernel) */ + ABI_DARWIN, /* Apple's Darwin (OS X kernel) */ + ABI_XENON /* Xbox 360 OS */ }; /* Small data support types. */ diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h index bcafa9d0cf4..9a6d26c4952 100644 --- a/gcc/config/rs6000/sysv4.h +++ b/gcc/config/rs6000/sysv4.h @@ -103,6 +103,8 @@ do { \ rs6000_current_abi = ABI_V4; \ else if (!strcmp (rs6000_abi_name, "openbsd")) \ rs6000_current_abi = ABI_V4; \ + else if (!strcmp (rs6000_abi_name, "xenon")) \ + rs6000_current_abi = ABI_XENON; \ else if (!strcmp (rs6000_abi_name, "i960-old")) \ { \ rs6000_current_abi = ABI_V4; \ diff --git a/gcc/config/rs6000/xenon.h b/gcc/config/rs6000/xenon.h new file mode 100644 index 00000000000..ef2e5957791 --- /dev/null +++ b/gcc/config/rs6000/xenon.h @@ -0,0 +1,28 @@ +/* Specify Xenon ABI */ +#undef RS6000_ABI_NAME +#define RS6000_ABI_NAME "xenon" + +/* Change the fixed area for the 360's stack frame convention */ +#undef RS6000_SAVE_AREA +#define RS6000_SAVE_AREA \ + (0x10 + (RS6000_ALIGN (crtl->outgoing_args_size, 16) - crtl->outgoing_args_size) + 0x40) + +/* Redefine the starting frame offset, since it relies on the size of the fixed area */ +#undef RS6000_STARTING_FRAME_OFFSET +#define RS6000_STARTING_FRAME_OFFSET \ + (cfun->calls_alloca \ + ? (RS6000_ALIGN (crtl->outgoing_args_size + RS6000_SAVE_AREA, 16)) \ + : (RS6000_ALIGN (crtl->outgoing_args_size, 16) + RS6000_SAVE_AREA)) + +/* Redefine the offset of the first stack argument, since it relies on the size of the fixed area */ +#undef FIRST_PARM_OFFSET +#define FIRST_PARM_OFFSET(FNDECL) RS6000_SAVE_AREA + +/* Redefine stack pointer offset, since it relies on the size of the fixed area */ +#undef STACK_POINTER_OFFSET +#define STACK_POINTER_OFFSET RS6000_SAVE_AREA + +/* Redefine the offset from the stack pointer to items allocated by alloca() and friends */ +#undef STACK_DYNAMIC_OFFSET +#define STACK_DYNAMIC_OFFSET(FUNDECL) \ + RS6000_ALIGN (crtl->outgoing_args_size.to_constant () + STACK_POINTER_OFFSET, 16)