Re: Using GS for TLS on x86-64 for target RDOS
I made the suggested changes, and enclose a new patch. Change log: * gcc/config/i386/i386.c: Use DEFAULT_TLS_SEG_REG to access TLS * gcc/config/i386/i386.h: Define default segment register for TLS * gcc/config/i386/rdos.h: Added TLS configuration for RDOS It's been tested with target RDOS, but not with target Linux. Uros, could you commit the patch if it is acceptable? Regards, Leif Ekblad - Original Message - From: "Uros Bizjak" To: "Leif Ekblad" Cc: "Michael Matz" ; Sent: Tuesday, May 14, 2013 8:19 PM Subject: Re: Using GS for TLS on x86-64 for target RDOS On Tue, May 14, 2013 at 6:45 PM, Leif Ekblad wrote: I've made a patch along these lines (enclosed). Change log: * gcc/config/i386/i386.c: Use DEFAULT_TLS_SEG_REG to access TLS * gcc/config/i386/i386.h: Define default segment register for TLS * gcc/config/i386/rdos.h: Added TLS configuration for RDOS *** gcc-4.9-20130512/gcc/config/i386/i386.h2013-04-29 13:00:10.0 +0200 --- gcc-work/gcc/config/i386/i386.h2013-05-14 13:36:19.041020400 +0200 + /* The default TLS segment register used by target. */ + #define DEFAULT_TLS_SEG_REG TARGET_64BIT ? SEG_FS : SEG_GS Precedence is a bit tricky with "?" ternary operand. Please put the expression in braces... *** gcc-4.9-20130512/gcc/config/i386/i386.c2013-05-06 16:53:03.0 +0200 --- gcc-work/gcc/config/i386/i386.c2013-05-14 13:37:14.338020400 +0200 ! || addr.seg != (DEFAULT_TLS_SEG_REG) ... and remove them there. *** gcc-4.9-20130512/gcc/config/i386/rdos.h2013-01-28 21:42:55.0 +0100 --- gcc-work/gcc/config/i386/rdos.h2013-05-14 13:36:17.940020400 +0200 + #undef TARGET_TLS_DIRECT_SEG_REFS + #define TARGET_TLS_DIRECT_SEG_REFS 1 TARGET_TLS_DIRECT_SEG_REFS_DEFAULT ! #define TARGET_OS_CPP_BUILTINS()\ ! do\ ! { \ ! builtin_define ("__RDOS__"); \ ! builtin_assert ("system=rdos"); \ ! } \ This looks like unwanted change to me. The patch is OK for mainline with above changes, if tested on x86_64-linux-gnu. Thanks, Uros. gcc.diff Description: Binary data
Re: Using GS for TLS on x86-64 for target RDOS
I've made a patch along these lines (enclosed). Change log: * gcc/config/i386/i386.c: Use DEFAULT_TLS_SEG_REG to access TLS * gcc/config/i386/i386.h: Define default segment register for TLS * gcc/config/i386/rdos.h: Added TLS configuration for RDOS Regards, Leif Ekblad - Original Message - From: "Uros Bizjak" To: "Michael Matz" Cc: ; "Leif Ekblad" Sent: Tuesday, May 14, 2013 11:35 AM Subject: Re: Using GS for TLS on x86-64 for target RDOS On Tue, May 14, 2013 at 11:13 AM, Michael Matz wrote: On Tue, 14 May 2013, Uros Bizjak wrote: I'd propose to introduce: a) #define DEFAULT_TLS_SEG_REG in i386.h to SEG_GS b) #undef and #define DEFAULT_TLS_SEG_REG in x86-64.h to SEG_FS This would break -m32. Uh, yes. So instead of a) and b), there should be: #define DEFAULT_TLS_SEG_REG TARGET_64BIT ? SEG_FS : SEG_GS in i386.h. Uros. gcc-tls.diff Description: Binary data
Using GS for TLS on x86-64 for target RDOS
I would need a way to use GS segment register instead of FS for x86-64 for target RDOS since RDOS cannot use FS for TLS. It seems like the code related to this is concentrated to two different places: The gcc/config/i386/i386.c: 11677:seg = TARGET_64BIT ? SEG_FS : SEG_GS; 13526: if (ix86_decompose_address (x, &addr) == 0 || addr.seg != (TARGET_64BIT ? SEG_FS : SEG_GS) || addr.disp == NULL_RTX || GET_CODE (addr.disp) != CONST) Especially the second reference would become hard-to-read if more conditionals are added to it. Perhaps the code could be changed to something like this: #ifdef TARGET_RDOS #define GET_TLS_SEG_REG SEG_GS #else #define GET_TLS_SEG_REG TARGET_64BIT ? SEG_FS : SEG_GS #endif Then the above could be patched to: 11677:seg = GET_TLS_SEG_REG; 13526: if (ix86_decompose_address (x, &addr) == 0 || addr.seg != (GET_TLS_SEG_REG) || addr.disp == NULL_RTX || GET_CODE (addr.disp) != CONST) Thoughts? Regards, Leif Ekblad
Re: [PATCH] Adding target rdos to GCC
That looks good. Thanks, Uros. Leif - Original Message - From: "Uros Bizjak" To: "Leif Ekblad" Cc: "Richard Biener" ; ; "H.J. Lu" ; "Jakub Jelinek" Sent: Monday, January 28, 2013 9:45 PM Subject: Re: [PATCH] Adding target rdos to GCC On Mon, Jan 28, 2013 at 9:14 PM, Leif Ekblad wrote: That is intentional. The gthr-rdos.h file is part of libgcc. My intention was to first patch gcc, then update the patches for newlib, and finally libgcc. The gthr-rdos.h file would reference include-files part of newlib, so this is kind of circular. I also cannot define the thread model for RDOS unless I define this file. I see a couple of possible solutions: 1. Keep as is. You cannot build libgcc at the current stage anyway, and the bootstrap must be built without threading 2. Add an empty gthr-rdos.h file until libgcc is done 3. Remove the threading-model for now, and add it with libgcc instead. I propose option 3. Is it enough to remove gthr.m4 change from the patch in this case? Yes, for all practical purposes. There is a reference to thread-file in config.gcc, when threading is enabled, which doesn't work for bootstrapping the compiler anyway. Thanks for pointing it, I have also removed this reference. Attached is the patch that has been committed to SVN. I have added missing licence headers to new files and clean whitespace a bit. 2013-01-28 Leif Ekblad * config.gcc (i[34567]86-*-rdos*, x86_64-*-rdos*): New targets. * config/i386/i386.h (TARGET_RDOS): New macro. (DEFAULT_LARGE_SECTION_THRESHOLD): New macro. * config/i386/i386.c (ix86_option_override_internal): For 64bit TARGET_RDOS, set ix86_cmodel to CM_MEDIUM_PIC and flag_pic to 1. * config/i386/i386.opt (mlarge-data-threshold): Initialize to DEFAULT_LARGE_SECTION_THRESHOLD. * config/i386/i386.md (R14_REG, R15_REG): New constants. * config/i386/rdos.h: New file. * config/i386/rdos64.h: New file. Thanks, Uros.
Re: [PATCH] Adding target rdos to GCC
- Original Message - From: "Uros Bizjak" To: "Leif Ekblad" Cc: "Richard Biener" ; ; "H.J. Lu" ; "Jakub Jelinek" Sent: Monday, January 28, 2013 9:03 PM Subject: Re: [PATCH] Adding target rdos to GCC On Mon, Jan 28, 2013 at 8:57 PM, Leif Ekblad wrote: That is intentional. The gthr-rdos.h file is part of libgcc. My intention was to first patch gcc, then update the patches for newlib, and finally libgcc. The gthr-rdos.h file would reference include-files part of newlib, so this is kind of circular. I also cannot define the thread model for RDOS unless I define this file. I see a couple of possible solutions: 1. Keep as is. You cannot build libgcc at the current stage anyway, and the bootstrap must be built without threading 2. Add an empty gthr-rdos.h file until libgcc is done 3. Remove the threading-model for now, and add it with libgcc instead. I propose option 3. Is it enough to remove gthr.m4 change from the patch in this case? Uros. Yes, for all practical purposes. There is a reference to thread-file in config.gcc, when threading is enabled, which doesn't work for bootstrapping the compiler anyway. Regards, Leif Ekblad
Re: [PATCH] Adding target rdos to GCC
Uros, That is intentional. The gthr-rdos.h file is part of libgcc. My intention was to first patch gcc, then update the patches for newlib, and finally libgcc. The gthr-rdos.h file would reference include-files part of newlib, so this is kind of circular. I also cannot define the thread model for RDOS unless I define this file. I see a couple of possible solutions: 1. Keep as is. You cannot build libgcc at the current stage anyway, and the bootstrap must be built without threading 2. Add an empty gthr-rdos.h file until libgcc is done 3. Remove the threading-model for now, and add it with libgcc instead. Regards, Leif Ekblad - Original Message - From: "Uros Bizjak" To: "Leif Ekblad" Cc: "Richard Biener" ; ; "H.J. Lu" ; "Jakub Jelinek" Sent: Monday, January 28, 2013 8:23 AM Subject: Re: [PATCH] Adding target rdos to GCC On Mon, Jan 28, 2013 at 7:50 AM, Leif Ekblad wrote: If the patch is ok, could some maintainer add it to trunk? There is no gthr-rdos.h file in your patch: *** gcc-4.8-20121230/config/gthr.m4 2012-10-15 15:10:30.0 +0200 --- gcc-work/config/gthr.m4 2013-01-07 10:14:04.620667900 +0100 *** *** 21,26 --- 21,27 tpf) thread_header=config/s390/gthr-tpf.h ;; vxworks) thread_header=config/gthr-vxworks.h ;; win32) thread_header=config/i386/gthr-win32.h ;; + rdos) thread_header=config/i386/gthr-rdos.h ;; This file should be part of libgcc, so it needs its own ChangeLog. Uros.
Re: [PATCH] Adding target rdos to GCC
If the patch is ok, could some maintainer add it to trunk? Regards, Leif Ekblad - Original Message - From: "Richard Biener" To: "Uros Bizjak" Cc: "Leif Ekblad" ; ; "H.J. Lu" ; "Jakub Jelinek" Sent: Wednesday, January 09, 2013 9:37 AM Subject: Re: [PATCH] Adding target rdos to GCC On Wed, 9 Jan 2013, Uros Bizjak wrote: On Tue, Jan 8, 2013 at 9:32 PM, Leif Ekblad wrote: > After some new suggestions from Uros, I've made a new diff. > > > Change log: > * config/gthr.m4: Added rdos thread header. > * gcc/config/i386/i386.c: Provided a way to define a default setting > for > medium memory model and PIC using TARGET_RDOS define. > * gcc/config/i386/i386.h: Defined TARGET_RDOS macro. Defined default > value > for large-data-threshold. > * gcc/config/i386/i386.md: Added r14 and r15 register names. > * gcc/config/i386/i386.opt: Changed initial value for > large-data-threshold > to DEFAULT_LARGE_SECTION_THRESHOLD. > * gcc/config/i386/rdos.h: Common definitions for target rdos > * gcc/config/i386/rdos64.h: Specific definitions for 64-bit rdos > target. > * gcc/config.gcc: Added rdos targets Please use present tense in ChangeLog (see many other entries). > Tested on target rdos and rdos32. This is OK for mainline, but the patch needs explicit approval from Release Managers at this stage. Ok with me. Richard.
Re: [PATCH] Adding target rdos to GCC
After some new suggestions from Uros, I've made a new diff. Change log: * config/gthr.m4: Added rdos thread header. * gcc/config/i386/i386.c: Provided a way to define a default setting for medium memory model and PIC using TARGET_RDOS define. * gcc/config/i386/i386.h: Defined TARGET_RDOS macro. Defined default value for large-data-threshold. * gcc/config/i386/i386.md: Added r14 and r15 register names. * gcc/config/i386/i386.opt: Changed initial value for large-data-threshold to DEFAULT_LARGE_SECTION_THRESHOLD. * gcc/config/i386/rdos.h: Common definitions for target rdos * gcc/config/i386/rdos64.h: Specific definitions for 64-bit rdos target. * gcc/config.gcc: Added rdos targets Tested on target rdos and rdos32. Leif Ekblad - Original Message - From: "Leif Ekblad" To: "Uros Bizjak" ; Cc: "H.J. Lu" Sent: Monday, January 07, 2013 11:13 PM Subject: Re: [PATCH] Adding target rdos to GCC Hello Uros, I tried to use your suggestion and use DEFAULT_SECTION_THRESHOLD in i386.opt, however this doesn't work for me. It seems the default is always 65536 regardless of what I define in rdos.h. Therefore, I kept the design as it was before. Changing name to TARGET_RDOS seems reasonable, and this has been changed. The location of the defines are also changed to the positions you proposed. I added another include-file (rdos32.h) for the 32-bit target. Currently, the 32-bit target is supported with OpenWatcom. While I want to make sure the header-files compile for both 32- and 64-bits, 32-bit support is not my primary target right now. I just need a GCC that can build the 32-bit version. New change log: * config/gthr.m4: Added rdos thread header. * gcc/config/i386/i386.c: Provided a way to define a default setting for medium memory model and PIC using TARGET_RDOS define. Provided a way to define a default value for large-data-threshold. * gcc/config/i386/i386.h: Defined TARGET_RDOS macro. Defined default value for large-data-threshold. * gcc/config/i386/i386.md: Added r14 and r15 register names. * gcc/config/i386/i386.opt: Changed initial value for large-data-threshold to 0 to allow detection of modification. * gcc/config/i386/rdos.h: Added new file for 64-bit rdos target. * gcc/config/i386/rdos32.h: Added new file for 32-bit rdos target. * gcc/config.gcc: Added rdos targets Leif Ekblad - Original Message ----- From: "Uros Bizjak" To: Cc: "Leif Ekblad" ; "H.J. Lu" Sent: Sunday, January 06, 2013 9:32 PM Subject: Re: [PATCH] Adding target rdos to GCC Hello! Updated patches with the suggestions below, except that the initial value is 0 (which is not meaningful). I also added a setting in rdos target file to use r15 for PIC instead of rbx. *** gcc-4.8-20121230/gcc/config/i386/i386.c Thu Dec 27 02:58:06 2012 --- gcc-work/gcc/config/i386/i386.c Sun Jan 6 14:10:34 2013 + if (ix86_section_threshold == 0) + ix86_section_threshold = DEFAULT_SECTION_THRESHOLD; Please see attached patch on how to initialize an option. *** gcc-4.8-20121230/gcc/config/i386/i386.h Wed Dec 19 17:04:12 2012 --- gcc-work/gcc/config/i386/i386.h Sun Jan 6 13:24:26 2013 + #define TARGET_MEDIUM_PIC 0 You should just use TARGET_RDOS here (also, please see attached patch). + /* Default threshold for putting data in large sections with x86-64 +medium memory model */ + #define DEFAULT_SECTION_THRESHOLD 65536 Do not put this define in the middle of i386.h section that deals with alignment... *** gcc-4.8-20121230/gcc/config/i386/rdos.h Thu Jan 1 01:00:00 1970 --- gcc-work/gcc/config/i386/rdos.h Sun Jan 6 13:20:12 2013 + #undef REAL_PIC_OFFSET_TABLE_REGNUM + #define REAL_PIC_OFFSET_TABLE_REGNUM R15_REG Is this header also used for 32bit target? You should not use REX registers for 32bit targets. + #undef TARGET_MEDIUM_PIC + #define TARGET_MEDIUM_PIC 1 TARGET_RDOS + #define DEFAULT_SECTION_THRESHOLD0x10 No hex numbers here. Also, you will need to #undef this first to override the default in i386.h. *** gcc-4.8-20121230/gcc/config.gcc Thu Nov 22 00:33:40 2012 --- gcc-work/gcc/config.gcc Fri Jan 4 21:08:46 2013 + i[34567]86-*-rdos*) + tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h newlib-stdint.h" + ;; You forgot to include i386/rdos.h here (other headers too?). It is needed at least for TARGET_EXECUTABLE_SUFFIX define. Uros. gcc-base.diff Description: Binary data
Re: [PATCH] Adding target rdos to GCC
Hello Uros, I tried to use your suggestion and use DEFAULT_SECTION_THRESHOLD in i386.opt, however this doesn't work for me. It seems the default is always 65536 regardless of what I define in rdos.h. Therefore, I kept the design as it was before. Changing name to TARGET_RDOS seems reasonable, and this has been changed. The location of the defines are also changed to the positions you proposed. I added another include-file (rdos32.h) for the 32-bit target. Currently, the 32-bit target is supported with OpenWatcom. While I want to make sure the header-files compile for both 32- and 64-bits, 32-bit support is not my primary target right now. I just need a GCC that can build the 32-bit version. New change log: * config/gthr.m4: Added rdos thread header. * gcc/config/i386/i386.c: Provided a way to define a default setting for medium memory model and PIC using TARGET_RDOS define. Provided a way to define a default value for large-data-threshold. * gcc/config/i386/i386.h: Defined TARGET_RDOS macro. Defined default value for large-data-threshold. * gcc/config/i386/i386.md: Added r14 and r15 register names. * gcc/config/i386/i386.opt: Changed initial value for large-data-threshold to 0 to allow detection of modification. * gcc/config/i386/rdos.h: Added new file for 64-bit rdos target. * gcc/config/i386/rdos32.h: Added new file for 32-bit rdos target. * gcc/config.gcc: Added rdos targets Leif Ekblad - Original Message - From: "Uros Bizjak" To: Cc: "Leif Ekblad" ; "H.J. Lu" Sent: Sunday, January 06, 2013 9:32 PM Subject: Re: [PATCH] Adding target rdos to GCC Hello! Updated patches with the suggestions below, except that the initial value is 0 (which is not meaningful). I also added a setting in rdos target file to use r15 for PIC instead of rbx. *** gcc-4.8-20121230/gcc/config/i386/i386.c Thu Dec 27 02:58:06 2012 --- gcc-work/gcc/config/i386/i386.c Sun Jan 6 14:10:34 2013 + if (ix86_section_threshold == 0) + ix86_section_threshold = DEFAULT_SECTION_THRESHOLD; Please see attached patch on how to initialize an option. *** gcc-4.8-20121230/gcc/config/i386/i386.h Wed Dec 19 17:04:12 2012 --- gcc-work/gcc/config/i386/i386.h Sun Jan 6 13:24:26 2013 + #define TARGET_MEDIUM_PIC 0 You should just use TARGET_RDOS here (also, please see attached patch). + /* Default threshold for putting data in large sections with x86-64 +medium memory model */ + #define DEFAULT_SECTION_THRESHOLD 65536 Do not put this define in the middle of i386.h section that deals with alignment... *** gcc-4.8-20121230/gcc/config/i386/rdos.h Thu Jan 1 01:00:00 1970 --- gcc-work/gcc/config/i386/rdos.h Sun Jan 6 13:20:12 2013 + #undef REAL_PIC_OFFSET_TABLE_REGNUM + #define REAL_PIC_OFFSET_TABLE_REGNUM R15_REG Is this header also used for 32bit target? You should not use REX registers for 32bit targets. + #undef TARGET_MEDIUM_PIC + #define TARGET_MEDIUM_PIC 1 TARGET_RDOS + #define DEFAULT_SECTION_THRESHOLD0x10 No hex numbers here. Also, you will need to #undef this first to override the default in i386.h. *** gcc-4.8-20121230/gcc/config.gcc Thu Nov 22 00:33:40 2012 --- gcc-work/gcc/config.gcc Fri Jan 4 21:08:46 2013 + i[34567]86-*-rdos*) + tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h newlib-stdint.h" + ;; You forgot to include i386/rdos.h here (other headers too?). It is needed at least for TARGET_EXECUTABLE_SUFFIX define. Uros. gcc-base.diff Description: Binary data
Re: [PATCH] Adding target rdos to GCC
Updated patches with the suggestions below, except that the initial value is 0 (which is not meaningful). I also added a setting in rdos target file to use r15 for PIC instead of rbx. New change log: * config/gthr.m4: Added rdos thread header. * gcc/config/i386/i386.c: Provided a way to define a default setting for medium memory model and PIC. Provided a way to define a default value for large-data-threshold. * gcc/config/i386/i386.h: Defined default value for medium memory model & PIC. Defined default value for large-data-threshold. * gcc/config/i386/i386.md: Added r14 and r15 register names. * gcc/config/i386/i386.opt: Changed initial value for large-data-threshold to 0 to allow detection of modification. * gcc/config/i386/rdos.h: Added new file for rdos target definition. * gcc/config.gcc: Added rdos target Tested for target rdos and rdos32. Regards, Leif Ekblad - Original Message - From: "H.J. Lu" To: "Leif Ekblad" Cc: "GCC Patches" Sent: Friday, January 04, 2013 11:32 PM Subject: Re: [PATCH] Adding target rdos to GCC On Fri, Jan 4, 2013 at 2:22 PM, Leif Ekblad wrote: Change log: * config/gthr.m4: Added rdos thread header. * gcc/config/i386/i386.c: Provided a way to define a default setting for medium memory model and PIC. Provided a way to define a default value for large-data-threshold. * gcc/config/i386/i386.h: Defined default value for medium memory model & PIC. * gcc/config/i386/rdos.h: Added new file for rdos target definition. * gcc/config.gcc: Added rdos target The change to gthr.m4 requires rebuilding the configure scripts. Tested with target rdos and rdos32. Is this ok for trunk? Regards, Leif Ekblad + #ifdef TARGET_SECTION_THRESHOLD + ix86_section_threshold = TARGET_SECTION_THRESHOLD; + #endif You should 1. Add DEFAULT_SECTION_THRESHOLD and set it to 65536. 2. Change the init value of ix86_section_threshold to -1. 3. Set ix86_section_threshold to DEFAULT_SECTION_THRESHOLD if it is -1. -- H.J. gcc.diff Description: Binary data
Re: [RFC PATCH, i386]: Use %r15 for REAL_PIC_OFFSET_TABLE_REGNUM on x86_64
OK. I know I can do that, but I would need to do it for every syscall since every syscall can potentially clobber rbx. Also, it is very strange that it is only one of the inlines the compiler complains about. I have another inline (which uses rbx as input), but that doesn't generate any error: #define RdosUserGateEbxEdiEcxParRetEax(nr, rbx, rdi, rcx, res) do { \ register int _id asm("r14") = nr; \ register typeof(rbx) _rbx asm("rbx") = (rbx); \ register typeof(rdi) _rdi asm("rdi") = (rdi); \ register typeof(rcx) _rcx asm("r8") = (rcx); \ register int _size asm("r12") = (rcx); \ asm volatile ( \ "syscall\n\t" \ "jnc 1f\n\t" \ "xorq %%rax,%%rax\n\t" \ "1: \n\t" \ : "=a" (res) : "r" (_id), "r" (_rbx), "r" (_rdi), "r" (_rcx), "r" (_size) : "rdx", "rsi" \ ); \ } while(0); inline int RdosWriteFile(int Handle, void *Buf, int Size) { int res; RdosUserGateEbxEdiEcxParRetEax(usergate_read_file, Handle, Buf, Size, res); return res; } Why is not this inline causing the problem? Might that be because it will not use rbx, but instead another register? OTOH, the code seems to work and rbx is not assigned to PIC at the point of the call, but to the defined parameter. Regards, Leif Ekblad - Original Message - From: "Jakub Jelinek" To: "Leif Ekblad" Cc: "Uros Bizjak" ; "Richard Henderson" ; "Andi Kleen" ; "Mike Frysinger" ; ; ; "H.J. Lu" Sent: Friday, January 04, 2013 10:42 PM Subject: Re: [RFC PATCH, i386]: Use %r15 for REAL_PIC_OFFSET_TABLE_REGNUM on x86_64 On Fri, Jan 04, 2013 at 10:39:05PM +0100, Leif Ekblad wrote: I just tried the patch, but it seems to produce some problems for me. The other patch which used a 64-bit specific register (r15) instead of rbx was easier to adapt to. The problem for me is that syscalls might clobber higher-half of all 32-bit registers, and that I cannot use the stack to preserve rbx in the call because of the red-zone. Of course you can use the stack, just subtract the red zone size (plus whatever you need) from %rsp first, then save to stack, do syscall, then restore from stack and finally increment %rsp back. Jakub
[PATCH] Adding target rdos to GCC
Change log: * config/gthr.m4: Added rdos thread header. * gcc/config/i386/i386.c: Provided a way to define a default setting for medium memory model and PIC. Provided a way to define a default value for large-data-threshold. * gcc/config/i386/i386.h: Defined default value for medium memory model & PIC. * gcc/config/i386/rdos.h: Added new file for rdos target definition. * gcc/config.gcc: Added rdos target The change to gthr.m4 requires rebuilding the configure scripts. Tested with target rdos and rdos32. Is this ok for trunk? Regards, Leif Ekblad gcc.diff Description: Binary data
Re: [RFC PATCH, i386]: Use %r15 for REAL_PIC_OFFSET_TABLE_REGNUM on x86_64
I just tried the patch, but it seems to produce some problems for me. The other patch which used a 64-bit specific register (r15) instead of rbx was easier to adapt to. The problem for me is that syscalls might clobber higher-half of all 32-bit registers, and that I cannot use the stack to preserve rbx in the call because of the red-zone. Problem code: #define RdosUserGateEdiEcxPar0RetEbx(nr, rdi, rcx, size, res) do { \ register int _id asm("r14") = nr; \ register typeof(rdi) _rdi asm("rdi") = (rdi); \ register typeof(rcx) _rcx asm("r8") = (rcx); \ register int _size asm("r12") = (size); \ asm volatile ( \ "syscall\n\t" \ "jc 1f\n\t" \ "movzx %%bx,%%rax\n\t" \ "jmp 2f\n\t" \ "1: \n\t" \ "xorq %%rax,%%rax\n\t" \ "2: \n\t" \ : "=a" (res) : "r" (_id), "r" (_rdi), "r" (_rcx), "r" (_size) : "rbx", "rdx", "rsi" \ ); \ } while(0); inline volatile int RdosCreateFile(const char *FileName, int Attrib) { int res; int size = strlen(FileName) + 1; RdosUserGateEdiEcxPar0RetEbx(usergate_create_file, FileName, Attrib, size, res); return res; } Error log: $ rdos-gcc test.c -o test.exe In file included from /usr/local/rdos/include/rdos.h:719:0, from test.c:1: /usr/local/rdos/include/rdosgcc.h: In function 'main': /usr/local/rdos/include/rdosgcc.h:236:5: error: PIC register clobbered by 'rbx' in 'asm' RdosUserGateEdiEcxPar0RetEbx(usergate_open_file, FileName, Access, size, res); ^ I would prefer to change PIC register to r15 instead, or alternatively make this an target-option. Regards, Leif Ekblad - Original Message - From: "Uros Bizjak" To: "Richard Henderson" Cc: "Andi Kleen" ; "Mike Frysinger" ; ; "Leif Ekblad" ; "Jakub Jelinek" ; ; "H.J. Lu" Sent: Sunday, December 30, 2012 8:08 PM Subject: Re: [RFC PATCH, i386]: Use %r15 for REAL_PIC_OFFSET_TABLE_REGNUM on x86_64 On Fri, Dec 28, 2012 at 9:27 PM, Richard Henderson wrote: On 12/27/2012 12:08 AM, Uros Bizjak wrote: The alternative approach is changing cpuid definition in cpuid.h (as in attached patch) to preserve %rbx, but we can't detect various code model settings there. Since the change depends on the definition of __PIC__, we unnecessary preserve %rbx also for -mcmodel=small. Certainly we can. We also control the preprocessor defines. All that's needed is that we create one for the code model. Something like attached? I have also included all suggestions (earlyclobber and operand prefix on temporary register). 2012-12-30 Uros Bizjak PR target/55712 * config/i386/i386-c.c (ix86_target_macros_internal): Depending on selected code model, define __code_mode_small__, __code_model_medium__, __code_model_large__, __code_model_32__ or __code_model_kernel__. * config/i386/cpuid.h (__cpuid, __cpuid_count) [__i386__]: Prefix xchg temporary register with %k. Declare temporary register as early clobbered. [__x86_64__]: For medium and large code models, preserve %rbx register. Tested on x86_64-pc-linux-gnu {,-m32}. Uros.
Re: [RFC PATCH, i386]: Use %r15 for REAL_PIC_OFFSET_TABLE_REGNUM on x86_64
In the case of cpuid, the code is hardly performance sensitive, and probably runs only at startup. An alternative solution for the broken code here is to move the result from rbx to another register, and to save/restore rbx. Currently, this is the only place in libgcc and newlib affected by this problem. Leif Ekblad - Original Message - From: "Andi Kleen" To: "Uros Bizjak" Cc: ; "Richard Henderson" ; "Jakub Jelinek" ; ; "H.J. Lu" Sent: Monday, December 24, 2012 10:32 PM Subject: Re: [RFC PATCH, i386]: Use %r15 for REAL_PIC_OFFSET_TABLE_REGNUM on x86_64 Uros Bizjak writes: Hello! Currently, we use %rbx as REAL_PIC_OFFSET_TABLE_REGNUM on x86_64. Since this register gets marked as fixed reg in ix86_conditional_register_usage, we get into troubles with insns that use %rbx (cmpxchg, cpuid). According to x86_64 psABI, we are free to use any register, so attached patch changes %rbx with %r15 (also following the example in the psABI). This patch has no implications on small code model (that doesn't use REAL_PIC_OFFSET_TABLE_REGNUM anyway), but on medium and large code model fixes usage of cpuid.h (please see PR 55712 [1]) and avoids a pair of xchgs around cmpxchg or cpuid instructions. So everyone who worked around this and use r15 now broke. It would be probably better to just teach the register allocator to spill those registers as needed, to handle some asm() statement. Not sure how hard that would be. -Andi -- a...@linux.intel.com -- Speaking for myself only
Re: x86-64 medium memory model
The small memory model will not do since I want to put data at other distinct addresses above 4G. I also want to place the heap at yet another address interval. This way it becomes easy to separate out code, data and heap references, and making sure that pointers are valid. The primary reason for not using below 2G or the last 2G, is because such numbers are formed naturally when doing 32-bit arithmetics, and thus could be executed by chance from corrupt data. If I understand it correctly, the PIE option is very similar to the PIC option, and will not make it possible to use any address for both code and data. Additionally, when I tried the small memory model with a start address of text above 4G, the linker complains about 32-bit fixups overflowing. Leif Ekblad - Original Message - From: "H.J. Lu" To: "Leif Ekblad" Cc: "GCC Patches" ; "GCC Mailing List" Sent: Wednesday, December 12, 2012 9:59 PM Subject: Re: x86-64 medium memory model On Wed, Dec 12, 2012 at 12:56 PM, Leif Ekblad wrote: I'm working on OS-adaptations for an OS that would use x86-64 applications that are located above 4G, but not in the upper area. Binutils provide a function to be able to set the start of text to above 4G, but there are problems with GCC when using this memory model. Have you tried PIE with small model? You can place your binaries above 4G with better performance. -- H.J.
x86-64 medium memory model
I'm working on OS-adaptations for an OS that would use x86-64 applications that are located above 4G, but not in the upper area. Binutils provide a function to be able to set the start of text to above 4G, but there are problems with GCC when using this memory model. The first issue has to do with creating a cross-compiler that defaults to medium memory model using PIC. While there are switches to achieve this on command line (-mcmodel=medium -fpic), this is inconvinient since everything ported must be changed to add these switches, including libgcc and newlib. The cross-compiler instead should default to this memory model. One possibility to achieve this is to add a new .h-file in the gcc/config/i386 directory. However, further inspection of the source indicates there is no macro that can be redefined to achieve this. One possibility is to add such a macro in gcc/config/i386.h, and implement it in gcc/config/i386.c. Here is a simple patch to do this: diff -u -r -N gcc-4.8-20121202/gcc/config/i386/i386.h gcc-work/gcc/config/i386/i386.h --- gcc-4.8-20121202/gcc/config/i386/i386.h 2012-11-23 17:02:10.0 +0100 +++ gcc-work/gcc/config/i386/i386.h 2012-12-08 12:17:40.0 +0100 @@ -86,6 +86,8 @@ #define TARGET_LP64 TARGET_ABI_64 #define TARGET_X32 TARGET_ABI_X32 +#define TARGET_MEDIUM_PIC 0 + /* SSE4.1 defines round instructions */ #define OPTION_MASK_ISA_ROUND OPTION_MASK_ISA_SSE4_1 #define TARGET_ISA_ROUND ((ix86_isa_flags & OPTION_MASK_ISA_ROUND) != 0) diff -u -r -N gcc-4.8-20121202/gcc/config/i386/i386.c gcc-work/gcc/config/i386/i386.c --- gcc-4.8-20121202/gcc/config/i386/i386.c 2012-12-02 00:43:52.0 +0100 +++ gcc-work/gcc/config/i386/i386.c 2012-12-11 21:43:48.0 +0100 @@ -3235,6 +3235,8 @@ DLL, and is essentially just as efficient as direct addressing. */ if (TARGET_64BIT && DEFAULT_ABI == MS_ABI) ix86_cmodel = CM_SMALL_PIC, flag_pic = 1; + else if (TARGET_64BIT && TARGET_MEDIUM_PIC) +ix86_cmodel = CM_MEDIUM_PIC, flag_pic = 1; else if (TARGET_64BIT) ix86_cmodel = flag_pic ? CM_SMALL_PIC : CM_SMALL; else It can be used like this: +#undef TARGET_MEDIUM_PIC +#define TARGET_MEDIUM_PIC 1 Next, with this issue fixed, there is still another problem in libgcc when using a cross-compiler compiled with this memory model: ../../gcc-work/libgcc/. -I../../../gcc-work/libgcc/../gcc -I../../../gcc-work/libgcc/../include -DHAVE_CC_TLS -o cpuinfo.o -MT cpuinfo.o -MD -MP -MF cpuinfo.dep -c ../../../gcc-work/libgcc/config/i386/cpuinfo.c -fvisibility=hidden -DHIDE_EXPORTS In file included from ../../../gcc-work/libgcc/config/i386/cpuinfo.c:21:0: ../../../gcc-work/libgcc/config/i386/cpuinfo.c: In function 'get_available_features': ../../../gcc-work/libgcc/config/i386/cpuinfo.c:236:7: error: inconsistent operand constraints in an 'asm' __cpuid_count (7, 0, eax, ebx, ecx, edx); ^ ../../../gcc-work/libgcc/static-object.mk:17: recipe for target `cpuinfo.o' failed make[1]: *** [cpuinfo.o] Error 1 make[1]: Lämnar katalogen "/usr/src/build-gcc-noheader/rdos/libgcc" Makefile:10619: recipe for target `all-target-libgcc' failed make: *** [all-target-libgcc] Error 2 My guess is that __cpuid_count uses 32-bit addressing when it should be using 64-bit addressing. I have no patch for this as I don't understand what is going on here well enough, but __cpuid_count is defined in gcc/config/i386/cpuid.h. In order to be able to continue to test the medium memory model I'd need patches to be applied to fix these issues. Regards, Leif Ekblad RDOS Development