From 7913654e38d3a03e6a90885ca9ae40b4f1788c36 Mon Sep 17 00:00:00 2001 From: Aiden Isik Date: Mon, 10 Mar 2025 12:52:51 +0000 Subject: [PATCH 1/3] Start fixing the stack frame layout --- gcc/config.gcc | 2 +- gcc/config/rs6000/rs6000-c.cc | 2 ++ gcc/config/rs6000/rs6000-logue.cc | 24 ++++++++++++++++++++++++ gcc/config/rs6000/rs6000-opts.h | 3 ++- gcc/config/rs6000/sysv4.h | 2 ++ gcc/config/rs6000/xenon.h | 28 ++++++++++++++++++++++++++++ 6 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 gcc/config/rs6000/xenon.h 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) From 7d034126c7aa262989e9563af6ac4848732c3d91 Mon Sep 17 00:00:00 2001 From: Aiden Isik Date: Sat, 12 Apr 2025 22:51:38 +0100 Subject: [PATCH 2/3] Fix size of stack frame, get close to basic aspects being correct --- gcc/config.gcc | 2 +- gcc/config/rs6000/rs6000-logue.cc | 39 +++++++++++------------- gcc/config/rs6000/xenon.h | 49 +++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 23 deletions(-) create mode 100644 gcc/config/rs6000/xenon.h 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-logue.cc b/gcc/config/rs6000/rs6000-logue.cc index edc0d6c8f52..bbb38e601be 100644 --- a/gcc/config/rs6000/rs6000-logue.cc +++ b/gcc/config/rs6000/rs6000-logue.cc @@ -767,7 +767,7 @@ rs6000_stack_info (void) RS6000_ALIGN (crtl->outgoing_args_size + info->fixed_size, STACK_BOUNDARY / BITS_PER_UNIT) - info->fixed_size; else - info->parm_size = RS6000_ALIGN (crtl->outgoing_args_size, + info->parm_size = RS6000_ALIGN (crtl->outgoing_args_size, TARGET_ALTIVEC ? 16 : 8); if (FRAME_GROWS_DOWNWARD) info->vars_size @@ -826,34 +826,29 @@ rs6000_stack_info (void) info->lr_save_offset = 2*reg_size; break; - case ABI_V4: - info->fp_save_offset = -info->fp_size; - info->gp_save_offset = info->fp_save_offset - info->gp_size; - info->cr_save_offset = info->gp_save_offset - info->cr_size; + case ABI_V4: /* Just replacing the SV4 ABI with the Xenon one... It's hacky, but I was having trouble defining a special ABI_XENON */ + info->cr_save_p = 0; /* We don't seem to save condition registers on 360 */ + info->gp_save_offset = -0x18 - 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; - if (TARGET_ALTIVEC_ABI) - { - info->vrsave_save_offset = info->cr_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); - /* 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_save_offset = info->vrsave_save_offset - info->altivec_padding_size - info->altivec_size; - /* Adjust for AltiVec case. */ - info->ehrd_offset = info->altivec_save_offset; - } - else - info->ehrd_offset = info->cr_save_offset; + /* Adjust for AltiVec case. */ + info->ehrd_offset = info->altivec_save_offset; - info->ehrd_offset -= ehrd_size; - info->lr_save_offset = reg_size; + info->ehrd_offset -= ehrd_size; + info->lr_save_offset = -0x8; + break; } - save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8; + save_align = ((TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) && DEFAULT_ABI != ABI_V4) ? 16 : 8; info->save_size = RS6000_ALIGN (info->fp_size + info->gp_size + info->altivec_size @@ -947,7 +942,7 @@ debug_stack_info (rs6000_stack_t *info) case ABI_AIX: abi_string = "AIX"; break; case ABI_ELFv2: abi_string = "ELFv2"; break; case ABI_DARWIN: abi_string = "Darwin"; break; - case ABI_V4: abi_string = "V.4"; break; + case ABI_V4: abi_string = "Xenon"; break; } fprintf (stderr, "\tABI = %5s\n", abi_string); diff --git a/gcc/config/rs6000/xenon.h b/gcc/config/rs6000/xenon.h new file mode 100644 index 00000000000..5fe48741cef --- /dev/null +++ b/gcc/config/rs6000/xenon.h @@ -0,0 +1,49 @@ +/* Redefinitions for FreeChainXenon + Copyright (C) 2025 Aiden Isik + + 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. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +#undef TARGET_DEBUG_STACK +#define TARGET_DEBUG_STACK 1 + +/* Force the pointer size to 32 bits (even though we run in 64-bit mode) */ +//#undef POINTER_SIZE +//#define POINTER_SIZE 32 + +/* 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.to_constant (), 16) - crtl->outgoing_args_size.to_constant ()) + 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) From c51b4a828b0f53d073bfb05cb427e33299e0a099 Mon Sep 17 00:00:00 2001 From: Aiden Isik Date: Sat, 12 Apr 2025 23:24:17 +0100 Subject: [PATCH 3/3] Fix offset for saving registers --- gcc/config/rs6000/rs6000-logue.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/config/rs6000/rs6000-logue.cc b/gcc/config/rs6000/rs6000-logue.cc index bbb38e601be..acfbd846585 100644 --- a/gcc/config/rs6000/rs6000-logue.cc +++ b/gcc/config/rs6000/rs6000-logue.cc @@ -828,7 +828,7 @@ rs6000_stack_info (void) case ABI_V4: /* Just replacing the SV4 ABI with the Xenon one... It's hacky, but I was having trouble defining a special ABI_XENON */ info->cr_save_p = 0; /* We don't seem to save condition registers on 360 */ - info->gp_save_offset = -0x18 - info->gp_size; + 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;