public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: Segment register support for the i386
@ 1999-12-30  9:55 Mark Kettenis
  1999-12-30 11:24 ` Linus Torvalds
                   ` (2 more replies)
  0 siblings, 3 replies; 30+ messages in thread
From: Mark Kettenis @ 1999-12-30  9:55 UTC (permalink / raw)
  To: gcc

   From: torvalds@transmeta.com (Linus Torvalds) 
   Date: 28 Dec 1999 14:47:17 -0800 

   So what I think the original poster was after was more of a

   "Ok, I've set up %fs to be a thread-specific pointer, and %gs points to
   the global segment, and now I want gcc to treat this 32-bit pointer as
   a 'fs' pointer and that other 32-bit pointer as a 'gs' pointer, while
   the "normal" cases are all the default ds=ss pointer case"

That's indeed what I'm trying to accomplish (see also below).

   So it wouldn't ever be a case of "seg + offset". It would always be just
   "offset" together with a "address space attribute".

   That sounds easier to me than a full "different pointer lengths" kind of
   thing, modulo the CSE kind of issues.

Well, not exactly.  While the "address space attribute" approach would
be nice to have, it isn't that easy to implement, since there seems to
be no support for pointer attributes in GCC.  Instead I propose to
allow the segment registers to be used as register variables in GCC.

Some not-so-register-starved processors (like the Sparc) reserve a
special register for the "thread pointer".  The current LinuxThreads
code for Linux/Sparc defines a global register variable like:

   register struct thread_descr *__thread_self __asm__("%g6");

and then uses __thread_self to access data in the thread descriptor.

On the i386 we cannot spare an ordinary register for this purpose.
However one can use segmentation instead and use one of the spare
segment registers (%fs and %gs), to point to the thread descriptor.
Right now this is only possible by using inline assembler which makes
the code a bit more painful to write and a lot harder to read. 

It would be nice if I could write:

   register struct thread_descr *__thread_self __asm__("%gs");

such that I could use the same C code as in the Sparc case to access
and manipulate the thread descriptor.  It seems that it isn't that
hard to implement this in GCC.  I managed to get this working by only
changing a few lines of code in the i386 back-end code.

However, there are some problems with this approach.  While the
segment registers are indeed pointer-like because of what Intel calls
their "hidden" contents, their visible part is simply a 16-bit value.
That probably means that while

  register void *p __asm__("%gs");

would refer to the "hidden" part of the %gs register,

  register short s __asm__("%gs");

should refer to the "visible" part.  This could lead to unwanted
ambiguities.  The fact that P refers to the "hidden" contents of the
register also means that it doesn't really have a value.  It is
therefore not possible to write something like:

  void *
  foo (void)
  {
    return p;
  }

Code like that should somehow lead to an appropriate error message,
which only the back-end code can generate.

That's why I'm not sure if this approach is acceptable, and I'd like
to hear what other people think of this proposal before spending too
much time on finishing my current implementation.  I can imagine that
people say that this extension is really an ugly hack that should
never be allowed in GCC.

Mark

^ permalink raw reply	[flat|nested] 30+ messages in thread
* Segment register support for the i386
@ 1999-12-24  8:42 Mark Kettenis
  1999-12-24 11:41 ` Linus Torvalds
  1999-12-31 23:54 ` Mark Kettenis
  0 siblings, 2 replies; 30+ messages in thread
From: Mark Kettenis @ 1999-12-24  8:42 UTC (permalink / raw)
  To: gcc

Hi all,

Over the last few days I have been looking into how I can get some
basic support for segmentation on the i386 into GCC.

A while ago Richard Henderson made a suggestion to have something
like:

   int * __attribute__((seggs)) ptr;

so that %gs is used whenever ptr is dereferenced[1]. However support
for multiple pointer types is completey absent in GCC as indicated by
Jeff Law[2].

An approach that seems to be easier to implement is to allow (global)
register variables bound to segment registers (fs, gs and maybe cs,
ds, es and ss), just like what can be done with other registers.

Consider the following code fragment:

   struct foo
   {
     int x;
     int y;
   };

   register struct foo *bar __asm__ ("gs");

   int
   foobar (int x)
   {
     return x + bar->y;
   }

In this example `bar->y' would refer to the member `y' of a `struct
foo' laid out at the start of the segment loaded into the "%gs"
register.  In principle this accomplishes the same as the `attribute'
approach suggested by Richard.

It seems that there is not a whole lot that needs to be done to
support this in GCC.  Basically, I added support for the "%gs"
register to `gcc/config/i386/i386.h' and extended `struct ix86_adress'
and `ix86_decompose_address()' in `gcc/config/i386/i386.c' with
support for a segment prefix.  The resulting compiler produced the
following assembler code for example above:

	   .file   "test-gs.c"
	   .version        "01.01"
   gcc2_compiled.:
   .text
	   .align 16
   .globl foobar
	   .type    foobar,@function
   foobar:
	   pushl   %ebp
	   movl    %esp, %ebp
	   movl    %gs:4, %eax
	   movl    8(%ebp), %edx
	   movl    %ebp, %esp
	   addl    %edx, %eax
	   popl    %ebp
	   ret
   .Lfe1:
	   .size    foobar,.Lfe1-foobar
	   .ident  "GCC: (GNU) 2.96 19991223 (experimental)"

Although I have a working example, I lot of work needs to be done to
assure that the compiler can handle more complex cases correctly, and
to make sure that the compiler signals invalid use of the segment
registers correctly.  However before doing this work (in which I might
need some assistence from more experienced GCC hackers) I first want
to ask if there is any chance for this feature to be included in GCC.

Mark

[1] http://sourceware.cygnus.com/ml/libc-hacker/1999-08/msg00153.html
[2] http://gcc.gnu.org/ml/gcc/1999-06/msg00706.html

^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2000-01-07  2:35 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-12-30  9:55 Segment register support for the i386 Mark Kettenis
1999-12-30 11:24 ` Linus Torvalds
1999-12-31 23:54   ` Linus Torvalds
1999-12-30 13:07 ` Martin v. Loewis
1999-12-31 23:54   ` Martin v. Loewis
1999-12-31 23:54 ` Mark Kettenis
  -- strict thread matches above, loose matches on Subject: below --
1999-12-24  8:42 Mark Kettenis
1999-12-24 11:41 ` Linus Torvalds
1999-12-28 14:10   ` Jeffrey A Law
1999-12-28 14:47     ` Linus Torvalds
1999-12-31 23:54       ` Linus Torvalds
1999-12-30 12:41     ` Richard Henderson
1999-12-31  4:06       ` Denis Chertykov
1999-12-31 10:49         ` Joern Rennecke
1999-12-31 23:54           ` Joern Rennecke
     [not found]           ` <v04220801b492c4a4768c@[192.168.1.254]>
2000-01-01  1:26             ` Denis Chertykov
2000-01-01  5:52               ` Alan Lehotsky
2000-01-04  2:05           ` Nick Ing-Simmons
2000-01-04  4:47             ` Denis Chertykov
2000-01-05  9:29               ` Sergey Larin
2000-01-06 11:15                 ` Denis Chertykov
2000-01-06 11:25                   ` Joern Rennecke
2000-01-06 11:51                     ` Denis Chertykov
2000-01-06 11:52                   ` Jeffrey A Law
2000-01-07  2:35                     ` Denis Chertykov
1999-12-31 23:54         ` Denis Chertykov
1999-12-31 23:54       ` Richard Henderson
1999-12-31 23:54     ` Jeffrey A Law
1999-12-31 23:54   ` Linus Torvalds
1999-12-31 23:54 ` Mark Kettenis

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).