Commit 00402c94 by Richard Henderson Committed by Richard Henderson

i386: Add address spaces for fs/gs segments and tls

        * config/i386/i386-c.c (ix86_target_macros): Define __SEG_FS,
        __SEG_GS, __SEG_TLS.
        (ix86_register_pragmas): Register address spaces __seg_fs,
        __seg_gs, __seg_tls.
        * config/i386/i386-protos.h (enum ix86_address_seg): Remove.
        (ADDR_SPACE_SEG_FS, ADDR_SPACE_SEG_GS, ADDR_SPACE_SEG_TLS): New.
        (struct ix86_address): Use addr_space_t instead of ix86_address_seg.
        * config/i386/i386.c (ix86_decompose_address): Likewise.
        (ix86_legitimate_address_p): Likewise.
        (memory_address_length): Likewise.  Check mem address space too.
        (ix86_print_operand): Use ix86_print_operand_address_as.
        (ix86_print_operand_address_as): Rename from
        ix86_print_operand_address, add new addr_space_t parameter.
        Validate that either the parameter or the ix86_address segment
        is default address space.  Handle ADDR_SPACE_SEG_TLS.
        (ix86_print_operand_address): New.
        (ix86_addr_space_subset_p, TARGET_ADDR_SPACE_SUBSET_P): New.
        (ix86_addr_space_convert, TARGET_ADDR_SPACE_CONVERT): New.
        (ix86_addr_space_debug, TARGET_ADDR_SPACE_DEBUG): New.
        (ix86_addr_space_zero_address_valid): New.
        (TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID): New.
        * config/i386/i386.h (DEFAULT_TLS_SEG_REG): Use addr_space_t constants.
        * config/i386/rdos.h (DEFAULT_TLS_SEG_REG): Likewise.
        * config/i386/predicates.md (address_no_seg_operand): Likewise.
        (vsib_address_operand): Likewise.
        (address_mpx_no_base_operand): Likewise.
        (address_mpx_no_index_operand): Likewise.
        * doc/extend.texi (x86 Named Address Spaces): New section.

        * gcc.target/i386/addr-space-1.c: New test.
        * gcc.target/i386/addr-space-2.c: New test.
        * gcc.target/i386/addr-space-3.c: New test.

From-SVN: r230003
parent 16734677
2015-11-09 Richard Henderson <rth@redhat.com>
* config/i386/i386-c.c (ix86_target_macros): Define __SEG_FS,
__SEG_GS, __SEG_TLS.
(ix86_register_pragmas): Register address spaces __seg_fs,
__seg_gs, __seg_tls.
* config/i386/i386-protos.h (enum ix86_address_seg): Remove.
(ADDR_SPACE_SEG_FS, ADDR_SPACE_SEG_GS, ADDR_SPACE_SEG_TLS): New.
(struct ix86_address): Use addr_space_t instead of ix86_address_seg.
* config/i386/i386.c (ix86_decompose_address): Likewise.
(ix86_legitimate_address_p): Likewise.
(memory_address_length): Likewise. Check mem address space too.
(ix86_print_operand): Use ix86_print_operand_address_as.
(ix86_print_operand_address_as): Rename from
ix86_print_operand_address, add new addr_space_t parameter.
Validate that either the parameter or the ix86_address segment
is default address space. Handle ADDR_SPACE_SEG_TLS.
(ix86_print_operand_address): New.
(ix86_addr_space_subset_p, TARGET_ADDR_SPACE_SUBSET_P): New.
(ix86_addr_space_convert, TARGET_ADDR_SPACE_CONVERT): New.
(ix86_addr_space_debug, TARGET_ADDR_SPACE_DEBUG): New.
(ix86_addr_space_zero_address_valid): New.
(TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID): New.
* config/i386/i386.h (DEFAULT_TLS_SEG_REG): Use addr_space_t constants.
* config/i386/rdos.h (DEFAULT_TLS_SEG_REG): Likewise.
* config/i386/predicates.md (address_no_seg_operand): Likewise.
(vsib_address_operand): Likewise.
(address_mpx_no_base_operand): Likewise.
(address_mpx_no_index_operand): Likewise.
* doc/extend.texi (x86 Named Address Spaces): New section.
* config/i386/i386.c (ix86_check_no_addr_space): New.
(decide_alg): Add have_as parameter.
(alg_usable_p): Likewise; disable rep algorithms if set.
......@@ -586,6 +586,10 @@ ix86_target_macros (void)
ix86_tune,
ix86_fpmath,
cpp_define);
cpp_define (parse_in, "__SEG_FS");
cpp_define (parse_in, "__SEG_GS");
cpp_define (parse_in, "__SEG_TLS");
}
......@@ -600,6 +604,10 @@ ix86_register_pragmas (void)
/* Update pragma hook to allow parsing #pragma GCC target. */
targetm.target_option.pragma_parse = ix86_pragma_target_parse;
c_register_addr_space ("__seg_fs", ADDR_SPACE_SEG_FS);
c_register_addr_space ("__seg_gs", ADDR_SPACE_SEG_GS);
c_register_addr_space ("__seg_tls", ADDR_SPACE_SEG_TLS);
#ifdef REGISTER_SUBTARGET_PRAGMAS
REGISTER_SUBTARGET_PRAGMAS ();
#endif
......
......@@ -279,12 +279,11 @@ extern rtx maybe_get_pool_constant (rtx);
extern char internal_label_prefix[16];
extern int internal_label_prefix_len;
enum ix86_address_seg { SEG_DEFAULT, SEG_FS, SEG_GS };
struct ix86_address
{
rtx base, index, disp;
HOST_WIDE_INT scale;
enum ix86_address_seg seg;
addr_space_t seg;
};
extern int ix86_decompose_address (rtx, struct ix86_address *);
......@@ -326,3 +325,7 @@ struct ix86_first_cycle_multipass_data_
# define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DATA_T \
struct ix86_first_cycle_multipass_data_
#endif /* RTX_CODE */
const addr_space_t ADDR_SPACE_SEG_FS = 1;
const addr_space_t ADDR_SPACE_SEG_GS = 2;
const addr_space_t ADDR_SPACE_SEG_TLS = 3;
......@@ -602,7 +602,8 @@ extern tree x86_mfence;
#define DEFAULT_ABI SYSV_ABI
/* The default TLS segment register used by target. */
#define DEFAULT_TLS_SEG_REG (TARGET_64BIT ? SEG_FS : SEG_GS)
#define DEFAULT_TLS_SEG_REG \
(TARGET_64BIT ? ADDR_SPACE_SEG_FS : ADDR_SPACE_SEG_GS)
/* Subtargets may reset this to 1 in order to enable 96-bit long double
with the rounding mode forced to 53 bits. */
......
......@@ -974,7 +974,7 @@
ok = ix86_decompose_address (op, &parts);
gcc_assert (ok);
return parts.seg == SEG_DEFAULT;
return parts.seg == ADDR_SPACE_GENERIC;
})
;; Return true if op if a valid base register, displacement or
......@@ -988,7 +988,7 @@
ok = ix86_decompose_address (op, &parts);
gcc_assert (ok);
if (parts.index || parts.seg != SEG_DEFAULT)
if (parts.index || parts.seg != ADDR_SPACE_GENERIC)
return false;
/* VSIB addressing doesn't support (%rip). */
......@@ -1032,7 +1032,7 @@
if (parts.index && parts.base)
return false;
if (parts.seg != SEG_DEFAULT)
if (parts.seg != ADDR_SPACE_GENERIC)
return false;
/* Do not support (%rip). */
......@@ -1064,7 +1064,7 @@
if (parts.index)
return false;
if (parts.seg != SEG_DEFAULT)
if (parts.seg != ADDR_SPACE_GENERIC)
return false;
/* Do not support (%rip). */
......
......@@ -25,7 +25,7 @@ along with GCC; see the file COPYING3. If not see
#define TARGET_TLS_DIRECT_SEG_REFS_DEFAULT MASK_TLS_DIRECT_SEG_REFS
#undef DEFAULT_TLS_SEG_REG
#define DEFAULT_TLS_SEG_REG SEG_GS
#define DEFAULT_TLS_SEG_REG ADDR_SPACE_SEG_GS
#undef TARGET_RDOS
#define TARGET_RDOS 1
......
......@@ -1261,8 +1261,8 @@ As an extension, GNU C supports named address spaces as
defined in the N1275 draft of ISO/IEC DTR 18037. Support for named
address spaces in GCC will evolve as the draft technical report
changes. Calling conventions for any target might also change. At
present, only the AVR, SPU, M32C, and RL78 targets support address
spaces other than the generic address space.
present, only the AVR, SPU, M32C, RL78, and x86 targets support
address spaces other than the generic address space.
Address space identifiers may be used exactly like any other C type
qualifier (e.g., @code{const} or @code{volatile}). See the N1275
......@@ -1451,6 +1451,49 @@ It may use runtime library
support, or generate special machine instructions to access that address
space.
@subsection x86 Named Address Spaces
@cindex x86 named address spaces
On the x86 target, variables may be declared as being relative
to the @code{%fs} or @code{%gs} segments.
@table @code
@item __seg_fs
@itemx __seg_gs
@cindex @code{__seg_fs} x86 named address space
@cindex @code{__seg_gs} x86 named address space
The object is accessed with the respective segment override prefix.
The respective segment base must be set via some method specific to
the operating system. Rather than require an expensive system call
to retrieve the segment base, these address spaces are not considered
to be subspaces of the generic (flat) address space. This means that
explicit casts are required to convert pointers between these address
spaces and the generic address space. In practice the application
should cast to @code{uintptr_t} and apply the segment base offset
that it installed previously.
The preprocessor symbols @code{__SEG_FS} and @code{__SEG_GS} are
defined when these address spaces are supported.
@item __seg_tls
@cindex @code{__seg_tls} x86 named address space
Some operating systems define either the @code{%fs} or @code{%gs}
segment as the thread-local storage base for each thread. Objects
within this address space are accessed with the appropriate
segment override prefix.
The pointer located at address 0 within the segment contains the
offset of the segment within the generic address space. Thus this
address space is considered a subspace of the generic address space,
and the known segment offset is applied when converting addresses
to and from the generic address space.
The preprocessor symbol @code{__SEG_TLS} is defined when this
address space is supported.
@end table
@node Zero Length
@section Arrays of Length Zero
@cindex arrays of length zero
......
2015-11-09 Richard Henderson <rth@redhat.com>
* gcc.target/i386/addr-space-1.c: New test.
* gcc.target/i386/addr-space-2.c: New test.
* gcc.target/i386/addr-space-3.c: New test.
2015-11-08 Steven g. Kargl <kargl@gcc.gnu.org>
PR fortran/68053
......
/* { dg-do compile */
/* { dg-options "-O2" } */
/* { dg-final { scan-assembler "movl\[ \t\]%gs:\\((%eax|%rax)\\), %eax" } } */
extern __seg_gs int *call_me (void);
int
read_seg_gs (void)
{
return *call_me();
}
/* { dg-do compile } */
/* { dg-options "-O" } */
/* { dg-final { scan-assembler "fs:16" } } */
/* { dg-final { scan-assembler "gs:16" } } */
int test(void)
{
int __seg_fs *f = (int __seg_fs *)16;
int __seg_gs *g = (int __seg_gs *)16;
return *f + *g;
}
/* { dg-do compile } */
/* { dg-options "-O" } */
/* { dg-final { scan-assembler "[fg]s:0" } } */
void test(int *y)
{
int *x = (int __seg_tls *)0;
if (x == y)
asm("");
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment