public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* 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

* Re: Segment register support for the i386
  1999-12-24  8:42 Segment register support for the i386 Mark Kettenis
@ 1999-12-24 11:41 ` Linus Torvalds
  1999-12-28 14:10   ` Jeffrey A Law
  1999-12-31 23:54   ` Linus Torvalds
  1999-12-31 23:54 ` Mark Kettenis
  1 sibling, 2 replies; 30+ messages in thread
From: Linus Torvalds @ 1999-12-24 11:41 UTC (permalink / raw)
  To: submit-linux-egcs

In article < 199912241641.RAA05275@delius.kettenis.local >,
Mark Kettenis  <kettenis@wins.uva.nl> wrote:
>
>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.

You might want to try talking to Steve Chamberlain: I know he tried to
do something similar and he may have suggestions (the suggestion may be
"forget it - it's too hairy", but it doesn't hurt to ask). 

I know there were horrible problems with disambiguating pointer
dereferences that looked the same: CSE needs to be _very_ careful.  If
you go ahead with this, would suggest adding a case like this to your
test-suite:

	int test_it(char *ptr)
	{
		char * gs_ptr __attribute("gsseg");

		gs_ptr = ptr;
		return *ptr == *gs_ptr;
	}

If done right, you should see (a) a warning for different types at the
gs_ptr assignment and (b) the compiler must NOT optimize away the
equality test, because while the pointers "look" the same to some degree
from a CSE standpoint, they obviously dereference potentially very
different values. 

I think pointer attributes could be very useful (alignment attributes,
calling convention attributes for function pointers etc), but there are
nasty issues with type checking etc.

		Linus

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

* Re: Segment register support for the i386
  1999-12-24 11:41 ` Linus Torvalds
@ 1999-12-28 14:10   ` Jeffrey A Law
  1999-12-28 14:47     ` Linus Torvalds
                       ` (2 more replies)
  1999-12-31 23:54   ` Linus Torvalds
  1 sibling, 3 replies; 30+ messages in thread
From: Jeffrey A Law @ 1999-12-28 14:10 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: gcc

  In message < 840i8n$1pp$1@penguin.transmeta.com >you write:
  > I know there were horrible problems with disambiguating pointer
  > dereferences that looked the same: CSE needs to be _very_ careful.  If
  > you go ahead with this, would suggest adding a case like this to your
  > test-suite:
Yes CSE and other passes would all have to know about this kind of
stuff.  Though I don't think it would be that nasty since a seg + offset
pointer would have a different mode than just an offset pointer.

The tougher problem is the general infrastructure to have pointers of
differing sizes, supporting partial mode arithmetic, and ABI issues with
segment/space registers.

Various people looked at supporting segments/spaces in the distant past
(early 90s) but I don't have snapshots of their code anymore.

jeff

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

* Re: Segment register support for the i386
  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 23:54     ` Jeffrey A Law
  2 siblings, 1 reply; 30+ messages in thread
From: Linus Torvalds @ 1999-12-28 14:47 UTC (permalink / raw)
  To: submit-linux-egcs

In article < 576.946299306@upchuck >, Jeffrey A Law  <law@cygnus.com> wrote:
>
>Yes CSE and other passes would all have to know about this kind of
>stuff.  Though I don't think it would be that nasty since a seg + offset
>pointer would have a different mode than just an offset pointer.
>
>The tougher problem is the general infrastructure to have pointers of
>differing sizes, supporting partial mode arithmetic, and ABI issues with
>segment/space registers.

I think that the original suggestion was NOT to support 48-bit pointers
on x86 (which is basically damn hard to do efficiently, because you end
up with a new class or register reload issues to get efficient segment
register usage), but to simply support standard 32-bit pointers that
just are in a different "address space". 

This is not a x86-only issue per se: it's more akin to the difference
between "data" and "code" address spaces - both may be 32-bit pointers,
but that doesn't mean that they have anything else in common.

The "data" vs "code" thing is much easier, because obviously in C you
can't ever dereference a code pointer for data (you can cast it to a
data pointer type, but then you lose the "codeness" of it if the
architecture has two separate address spaces).  So you never have any
issues with CSE etc on dereferencing the stuff. 

I think Java has this issue: you have "stack" vs "data" pointers, but
then Java as a language doesn't actually let you play games with them,
so again that rats-nest is avoided too. 

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"

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.. 

		Linus

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

* Re: Segment register support for the i386
  1999-12-28 14:10   ` Jeffrey A Law
  1999-12-28 14:47     ` Linus Torvalds
@ 1999-12-30 12:41     ` Richard Henderson
  1999-12-31  4:06       ` Denis Chertykov
  1999-12-31 23:54       ` Richard Henderson
  1999-12-31 23:54     ` Jeffrey A Law
  2 siblings, 2 replies; 30+ messages in thread
From: Richard Henderson @ 1999-12-30 12:41 UTC (permalink / raw)
  To: Jeffrey A Law; +Cc: Linus Torvalds, gcc

On Mon, Dec 27, 1999 at 05:55:06AM -0700, Jeffrey A Law wrote:
> Yes CSE and other passes would all have to know about this kind of
> stuff.  Though I don't think it would be that nasty since a seg + offset
> pointer would have a different mode than just an offset pointer.
> 
> The tougher problem is the general infrastructure to have pointers of
> differing sizes, supporting partial mode arithmetic, and ABI issues with
> segment/space registers.

As pointed out in other mail, Mark wasn't looking for 48-bit pointers,
rather different address spaces.  Conceptually, this is actually much
more like the `__X' and `__Y' address spaces from DSP-land, and I have
proposed in the past treating them similarly.

I believe my original thought was to do this with extra modes, so that
you'd have P_Xmode and P_Ymode (P_GSmode and P_FSmode in the x86 case)
to disambiguate the different address spaces.

In any case, that sort of infrastructure is something we'll eventually
need if we want to support DSPs properly, since in that case X and Y
memory accesses are important to scheduling.



r~

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

* Re: Segment register support for the i386
  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         ` Denis Chertykov
  1999-12-31 23:54       ` Richard Henderson
  1 sibling, 2 replies; 30+ messages in thread
From: Denis Chertykov @ 1999-12-31  4:06 UTC (permalink / raw)
  To: Richard Henderson; +Cc: gcc

Richard Henderson <rth@cygnus.com> writes:

> On Mon, Dec 27, 1999 at 05:55:06AM -0700, Jeffrey A Law wrote:
> > Yes CSE and other passes would all have to know about this kind of
> > stuff.  Though I don't think it would be that nasty since a seg + offset
> > pointer would have a different mode than just an offset pointer.
> > 
> > The tougher problem is the general infrastructure to have pointers of
> > differing sizes, supporting partial mode arithmetic, and ABI issues with
> > segment/space registers.
> 
> As pointed out in other mail, Mark wasn't looking for 48-bit pointers,
> rather different address spaces.  Conceptually, this is actually much
> more like the `__X' and `__Y' address spaces from DSP-land, and I have
> proposed in the past treating them similarly.
> 
> I believe my original thought was to do this with extra modes, so that
> you'd have P_Xmode and P_Ymode (P_GSmode and P_FSmode in the x86 case)
> to disambiguate the different address spaces.

It's a good solution for harvard architectures too.
(DSP's and micro controllers)
Something like PCODEmode and PDATAmode.

Denis.

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

* Re: Segment register support for the i386
  1999-12-31  4:06       ` Denis Chertykov
@ 1999-12-31 10:49         ` Joern Rennecke
  1999-12-31 23:54           ` Joern Rennecke
                             ` (2 more replies)
  1999-12-31 23:54         ` Denis Chertykov
  1 sibling, 3 replies; 30+ messages in thread
From: Joern Rennecke @ 1999-12-31 10:49 UTC (permalink / raw)
  To: Denis Chertykov; +Cc: Richard Henderson, gcc

> > I believe my original thought was to do this with extra modes, so that
> > you'd have P_Xmode and P_Ymode (P_GSmode and P_FSmode in the x86 case)
> > to disambiguate the different address spaces.
> 
> It's a good solution for harvard architectures too.
> (DSP's and micro controllers)
> Something like PCODEmode and PDATAmode.

We have some precedent for target-specific modes with EXTRA_CC_MODES
and SELECT_CC_MODE.  However, Pmode is used quite a lot, not only in
the rtl generation stage, but also in some optimizers.  So we'd need
a macro to detect if a mode belongs to the Pmode 'family', and teach
the optimizers how to use it.

How about POINTER_SIZE / POINTERS_EXTEND_UNSIGNED ?  Do we want to
keep them applying to all pointer modes?

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

* Re: Segment register support for the i386
  1999-12-28 14:10   ` Jeffrey A Law
  1999-12-28 14:47     ` Linus Torvalds
  1999-12-30 12:41     ` Richard Henderson
@ 1999-12-31 23:54     ` Jeffrey A Law
  2 siblings, 0 replies; 30+ messages in thread
From: Jeffrey A Law @ 1999-12-31 23:54 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: gcc

  In message < 840i8n$1pp$1@penguin.transmeta.com >you write:
  > I know there were horrible problems with disambiguating pointer
  > dereferences that looked the same: CSE needs to be _very_ careful.  If
  > you go ahead with this, would suggest adding a case like this to your
  > test-suite:
Yes CSE and other passes would all have to know about this kind of
stuff.  Though I don't think it would be that nasty since a seg + offset
pointer would have a different mode than just an offset pointer.

The tougher problem is the general infrastructure to have pointers of
differing sizes, supporting partial mode arithmetic, and ABI issues with
segment/space registers.

Various people looked at supporting segments/spaces in the distant past
(early 90s) but I don't have snapshots of their code anymore.

jeff

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

* Re: Segment register support for the i386
  1999-12-30 12:41     ` Richard Henderson
  1999-12-31  4:06       ` Denis Chertykov
@ 1999-12-31 23:54       ` Richard Henderson
  1 sibling, 0 replies; 30+ messages in thread
From: Richard Henderson @ 1999-12-31 23:54 UTC (permalink / raw)
  To: Jeffrey A Law; +Cc: Linus Torvalds, gcc

On Mon, Dec 27, 1999 at 05:55:06AM -0700, Jeffrey A Law wrote:
> Yes CSE and other passes would all have to know about this kind of
> stuff.  Though I don't think it would be that nasty since a seg + offset
> pointer would have a different mode than just an offset pointer.
> 
> The tougher problem is the general infrastructure to have pointers of
> differing sizes, supporting partial mode arithmetic, and ABI issues with
> segment/space registers.

As pointed out in other mail, Mark wasn't looking for 48-bit pointers,
rather different address spaces.  Conceptually, this is actually much
more like the `__X' and `__Y' address spaces from DSP-land, and I have
proposed in the past treating them similarly.

I believe my original thought was to do this with extra modes, so that
you'd have P_Xmode and P_Ymode (P_GSmode and P_FSmode in the x86 case)
to disambiguate the different address spaces.

In any case, that sort of infrastructure is something we'll eventually
need if we want to support DSPs properly, since in that case X and Y
memory accesses are important to scheduling.



r~

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

* Re: Segment register support for the i386
  1999-12-28 14:47     ` Linus Torvalds
@ 1999-12-31 23:54       ` Linus Torvalds
  0 siblings, 0 replies; 30+ messages in thread
From: Linus Torvalds @ 1999-12-31 23:54 UTC (permalink / raw)
  To: submit-linux-egcs

In article < 576.946299306@upchuck >, Jeffrey A Law  <law@cygnus.com> wrote:
>
>Yes CSE and other passes would all have to know about this kind of
>stuff.  Though I don't think it would be that nasty since a seg + offset
>pointer would have a different mode than just an offset pointer.
>
>The tougher problem is the general infrastructure to have pointers of
>differing sizes, supporting partial mode arithmetic, and ABI issues with
>segment/space registers.

I think that the original suggestion was NOT to support 48-bit pointers
on x86 (which is basically damn hard to do efficiently, because you end
up with a new class or register reload issues to get efficient segment
register usage), but to simply support standard 32-bit pointers that
just are in a different "address space". 

This is not a x86-only issue per se: it's more akin to the difference
between "data" and "code" address spaces - both may be 32-bit pointers,
but that doesn't mean that they have anything else in common.

The "data" vs "code" thing is much easier, because obviously in C you
can't ever dereference a code pointer for data (you can cast it to a
data pointer type, but then you lose the "codeness" of it if the
architecture has two separate address spaces).  So you never have any
issues with CSE etc on dereferencing the stuff. 

I think Java has this issue: you have "stack" vs "data" pointers, but
then Java as a language doesn't actually let you play games with them,
so again that rats-nest is avoided too. 

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"

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.. 

		Linus

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

* Re: Segment register support for the i386
  1999-12-31  4:06       ` Denis Chertykov
  1999-12-31 10:49         ` Joern Rennecke
@ 1999-12-31 23:54         ` Denis Chertykov
  1 sibling, 0 replies; 30+ messages in thread
From: Denis Chertykov @ 1999-12-31 23:54 UTC (permalink / raw)
  To: Richard Henderson; +Cc: gcc

Richard Henderson <rth@cygnus.com> writes:

> On Mon, Dec 27, 1999 at 05:55:06AM -0700, Jeffrey A Law wrote:
> > Yes CSE and other passes would all have to know about this kind of
> > stuff.  Though I don't think it would be that nasty since a seg + offset
> > pointer would have a different mode than just an offset pointer.
> > 
> > The tougher problem is the general infrastructure to have pointers of
> > differing sizes, supporting partial mode arithmetic, and ABI issues with
> > segment/space registers.
> 
> As pointed out in other mail, Mark wasn't looking for 48-bit pointers,
> rather different address spaces.  Conceptually, this is actually much
> more like the `__X' and `__Y' address spaces from DSP-land, and I have
> proposed in the past treating them similarly.
> 
> I believe my original thought was to do this with extra modes, so that
> you'd have P_Xmode and P_Ymode (P_GSmode and P_FSmode in the x86 case)
> to disambiguate the different address spaces.

It's a good solution for harvard architectures too.
(DSP's and micro controllers)
Something like PCODEmode and PDATAmode.

Denis.

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

* Re: Segment register support for the i386
  1999-12-31 10:49         ` Joern Rennecke
@ 1999-12-31 23:54           ` Joern Rennecke
       [not found]           ` <v04220801b492c4a4768c@[192.168.1.254]>
  2000-01-04  2:05           ` Nick Ing-Simmons
  2 siblings, 0 replies; 30+ messages in thread
From: Joern Rennecke @ 1999-12-31 23:54 UTC (permalink / raw)
  To: Denis Chertykov; +Cc: Richard Henderson, gcc

> > I believe my original thought was to do this with extra modes, so that
> > you'd have P_Xmode and P_Ymode (P_GSmode and P_FSmode in the x86 case)
> > to disambiguate the different address spaces.
> 
> It's a good solution for harvard architectures too.
> (DSP's and micro controllers)
> Something like PCODEmode and PDATAmode.

We have some precedent for target-specific modes with EXTRA_CC_MODES
and SELECT_CC_MODE.  However, Pmode is used quite a lot, not only in
the rtl generation stage, but also in some optimizers.  So we'd need
a macro to detect if a mode belongs to the Pmode 'family', and teach
the optimizers how to use it.

How about POINTER_SIZE / POINTERS_EXTEND_UNSIGNED ?  Do we want to
keep them applying to all pointer modes?

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

* Re: Segment register support for the i386
  1999-12-24 11:41 ` Linus Torvalds
  1999-12-28 14:10   ` Jeffrey A Law
@ 1999-12-31 23:54   ` Linus Torvalds
  1 sibling, 0 replies; 30+ messages in thread
From: Linus Torvalds @ 1999-12-31 23:54 UTC (permalink / raw)
  To: submit-linux-egcs

In article < 199912241641.RAA05275@delius.kettenis.local >,
Mark Kettenis  <kettenis@wins.uva.nl> wrote:
>
>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.

You might want to try talking to Steve Chamberlain: I know he tried to
do something similar and he may have suggestions (the suggestion may be
"forget it - it's too hairy", but it doesn't hurt to ask). 

I know there were horrible problems with disambiguating pointer
dereferences that looked the same: CSE needs to be _very_ careful.  If
you go ahead with this, would suggest adding a case like this to your
test-suite:

	int test_it(char *ptr)
	{
		char * gs_ptr __attribute("gsseg");

		gs_ptr = ptr;
		return *ptr == *gs_ptr;
	}

If done right, you should see (a) a warning for different types at the
gs_ptr assignment and (b) the compiler must NOT optimize away the
equality test, because while the pointers "look" the same to some degree
from a CSE standpoint, they obviously dereference potentially very
different values. 

I think pointer attributes could be very useful (alignment attributes,
calling convention attributes for function pointers etc), but there are
nasty issues with type checking etc.

		Linus

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

* Segment register support for the i386
  1999-12-24  8:42 Segment register support for the i386 Mark Kettenis
  1999-12-24 11:41 ` Linus Torvalds
@ 1999-12-31 23:54 ` Mark Kettenis
  1 sibling, 0 replies; 30+ messages in thread
From: Mark Kettenis @ 1999-12-31 23:54 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

* Re: Segment register support for the i386
       [not found]           ` <v04220801b492c4a4768c@[192.168.1.254]>
@ 2000-01-01  1:26             ` Denis Chertykov
  2000-01-01  5:52               ` Alan Lehotsky
  0 siblings, 1 reply; 30+ messages in thread
From: Denis Chertykov @ 2000-01-01  1:26 UTC (permalink / raw)
  To: Alan Lehotsky; +Cc: Joern Rennecke, Denis Chertykov, Richard Henderson, gcc

Alan Lehotsky <lehotsky@tiac.net> writes:

> >>  Something like PCODEmode and PDATAmode.
> 
> 	Yes.  That would help.  I've had to work around problems
> 	in the machine-independent parts of GCC for my ADI SHARC
> 	port dealing with the distinction between code and data
> 	addressing.

As I know ADSP 2181 also uses hacks inside machine-independent parts
of GCC. (Is this your work ?)
Why you use `pm' and `dm' modifiers instead of __attribute__ ((..))
which is standard in GCC. Also you can access PM data with macros.
It's not so readable as `pm' modifier but it's standard.

> >We have some precedent for target-specific modes with EXTRA_CC_MODES
> >and SELECT_CC_MODE.  However, Pmode is used quite a lot, not only in
> >the rtl generation stage, but also in some optimizers.  So we'd need
> >a macro to detect if a mode belongs to the Pmode 'family', and teach
> >the optimizers how to use it.
> >
> >How about POINTER_SIZE / POINTERS_EXTEND_UNSIGNED ?  Do we want to
> >keep them applying to all pointer modes?
> 
> 	As an architectural data-point, the SHARC has two different
> 	size pointers - a 32 bit one (DM) and a 24 bit one (PM).
> 	The address spaces on this machine overlap somewhat.

SHARC always have only 32bits registers (40bits in floating point mode).
Or I'm wrong ?

IMHO change value of POINTER_SIZE according with PXXXmode are very
difficult.
IMHO if we want to make this work (I want) we must split this work to
more simple stages.
Any suggestions ?

Denis.

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

* Re: Segment register support for the i386
  2000-01-01  1:26             ` Denis Chertykov
@ 2000-01-01  5:52               ` Alan Lehotsky
  0 siblings, 0 replies; 30+ messages in thread
From: Alan Lehotsky @ 2000-01-01  5:52 UTC (permalink / raw)
  To: Denis Chertykov; +Cc: Joern Rennecke, Denis Chertykov, Richard Henderson, gcc

At 12:22 +0300 1/1/00, Denis Chertykov wrote:
>Alan Lehotsky <lehotsky@tiac.net> writes:
>
>>  >>  Something like PCODEmode and PDATAmode.
>>
>>	Yes.  That would help.  I've had to work around problems
>>	in the machine-independent parts of GCC for my ADI SHARC
>>	port dealing with the distinction between code and data
>>	addressing.
>
>As I know ADSP 2181 also uses hacks inside machine-independent parts
>of GCC. (Is this your work ?)


	No, I'm innocent of that crime :-)

	I am supporting the SHARC compiler for Mercury Computer Systems,
	the original hacks were done by Analog Devices when they first
	did the port for the 21020 DSP chip.

>Why you use `pm' and `dm' modifiers instead of __attribute__ ((..))
>which is standard in GCC. Also you can access PM data with macros.
>It's not so readable as `pm' modifier but it's standard.

	I actually think the port predates __attribute__.  I've modified
	Mercury's code to use __attribute__ (but left in the old PM
	and DM modifiers for backwards compatibility.

	But even with that, it was necessary to make front-end modifications
	to deal with two address spaces.  There are just a lot of places
	that assume that Pmode covers all the bases.

>  >
>>	As an architectural data-point, the SHARC has two different
>>	size pointers - a 32 bit one (DM) and a 24 bit one (PM).
>>	The address spaces on this machine overlap somewhat.
>
>SHARC always have only 32bits registers (40bits in floating point mode).
>Or I'm wrong ?


	The PM registers are all 24 bits.  They can only physically
	address 16M words of memory.  [When you assign from a PM register,
	it sign-extends into 32 bits....]

	My crime was adding a THIRD kind of pointer - namely a 30 bit
	word address with two bits to indicate "byte-in-word" so that
	the 'char' and 'short' type could be supported as 8 and 16
	bit datums.  This also rippled thru the front end in order that
	the code optimization wouldn't suffer.

>
>IMHO change value of POINTER_SIZE according with PXXXmode are very
>difficult.
>IMHO if we want to make this work (I want) we must split this work to
>more simple stages.
>Any suggestions ?

	Mercury is still using 2.8.1 as a code-base.  [It took me the
	two years (part time) to convert from a 2.3.3 based port to
	the 2.8.1]  If I ever convince them to move to 2.95 and beyond,
	I'd like to discuss how we could support multiple address
	spaces in a more portable fashion.  And I'd want to contribute
	work to help.   But right now, I'm not actively enhancing the
	SHARC compiler - just fixing bugs.

-- Al
------------------------------------------------------------------------

		    Quality Software Management
		http://www.tiac.net/users/lehotsky
			lehotsky@tiac.net
			(978)287-0435 Voice
			(978)808-6836 Cellular
			(978)287-0436 Fax/Data

	Software Process Improvement and Management Consulting
	     Language Design and Compiler Implementation

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

* Re: Segment register support for the i386
  1999-12-31 10:49         ` Joern Rennecke
  1999-12-31 23:54           ` Joern Rennecke
       [not found]           ` <v04220801b492c4a4768c@[192.168.1.254]>
@ 2000-01-04  2:05           ` Nick Ing-Simmons
  2000-01-04  4:47             ` Denis Chertykov
  2 siblings, 1 reply; 30+ messages in thread
From: Nick Ing-Simmons @ 2000-01-04  2:05 UTC (permalink / raw)
  To: amylaar; +Cc: gcc, Richard Henderson, Denis Chertykov

Joern Rennecke <amylaar@cygnus.co.uk> writes:
>> > I believe my original thought was to do this with extra modes, so that
>> > you'd have P_Xmode and P_Ymode (P_GSmode and P_FSmode in the x86 case)
>> > to disambiguate the different address spaces.
>> 
>> It's a good solution for harvard architectures too.
>> (DSP's and micro controllers)
>> Something like PCODEmode and PDATAmode.
>
>We have some precedent for target-specific modes with EXTRA_CC_MODES
>and SELECT_CC_MODE.  However, Pmode is used quite a lot, not only in
>the rtl generation stage, but also in some optimizers.  So we'd need
>a macro to detect if a mode belongs to the Pmode 'family', and teach
>the optimizers how to use it.

The other problem (from trying to use GCC on DSPs) will be 
REG_OK_FOR_BASE & co. Reload has a fixation that there is 
one true "base register class" which was/is a severe handicap 
to handling X/Y space.

-- 
Nick Ing-Simmons <nik@tiuk.ti.com>
Via, but not speaking for: Texas Instruments Ltd.

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

* Re: Segment register support for the i386
  2000-01-04  2:05           ` Nick Ing-Simmons
@ 2000-01-04  4:47             ` Denis Chertykov
  2000-01-05  9:29               ` Sergey Larin
  0 siblings, 1 reply; 30+ messages in thread
From: Denis Chertykov @ 2000-01-04  4:47 UTC (permalink / raw)
  To: Nick Ing-Simmons; +Cc: amylaar, gcc, Richard Henderson, Denis Chertykov

Nick Ing-Simmons <nik@tiuk.ti.com> writes:

> Joern Rennecke <amylaar@cygnus.co.uk> writes:
> >> > I believe my original thought was to do this with extra modes, so that
> >> > you'd have P_Xmode and P_Ymode (P_GSmode and P_FSmode in the x86 case)
> >> > to disambiguate the different address spaces.
> >> 
> >> It's a good solution for harvard architectures too.
> >> (DSP's and micro controllers)
> >> Something like PCODEmode and PDATAmode.
> >
> >We have some precedent for target-specific modes with EXTRA_CC_MODES
> >and SELECT_CC_MODE.  However, Pmode is used quite a lot, not only in
> >the rtl generation stage, but also in some optimizers.  So we'd need
> >a macro to detect if a mode belongs to the Pmode 'family', and teach
> >the optimizers how to use it.

We must select a right Pmode from the Pmode 'family' for stack and
frame addressing. 
Also special macro needed.

> The other problem (from trying to use GCC on DSPs) will be 
> REG_OK_FOR_BASE & co. Reload has a fixation that there is 
> one true "base register class" which was/is a severe handicap 
> to handling X/Y space.

I'm agree with you. I'm also have a problems with one true "base
register class" in reload.

LEGITIMIZE_RELOAD_ADDRESS can help you,
but LEGITIMIZE_RELOAD_ADDRESS don't called in any case.
May be we can correct `find_reloads_address' to using
LEGITIMIZE_RELOAD_ADDRESS in any case.

This is a fragment from the progects file from the old PROGECTS
section.

   Simpler porting.
   
   Right now, describing the target machine's instructions is done
   cleanly, but describing its addressing mode is done with several
   ad-hoc macro definitions. Porting would be much easier if there were
   an RTL description for addressing modes like that for instructions.
   Tools analogous to genflags and genrecog would generate macros from
   this description.
   
   There would be one pattern in the address-description file for each
   kind of addressing, and this pattern would have:
     * the RTL expression for the address
     * C code to verify its validity (since that may depend on the exact
       data).
     * C code to print the address in assembly language.
     * C code to convert the address into a valid one, if it is not
       valid. (This would replace LEGITIMIZE_ADDRESS).
     * Register constraints for all indeterminates that appear in the RTL
       expression.

Is any ideas about implementation exists ?
Is we talk about new methods of address describing ?

Denis.

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

* Re: Segment register support for the i386
  2000-01-04  4:47             ` Denis Chertykov
@ 2000-01-05  9:29               ` Sergey Larin
  2000-01-06 11:15                 ` Denis Chertykov
  0 siblings, 1 reply; 30+ messages in thread
From: Sergey Larin @ 2000-01-05  9:29 UTC (permalink / raw)
  To: gcc; +Cc: Denis Chertykov

Denis Chertykov <denisc@overta.ru> writes:

> This is a fragment from the progects file from the old PROGECTS
> section.
> 
>    Simpler porting.
>    
>    Right now, describing the target machine's instructions is done
>    cleanly, but describing its addressing mode is done with several
>    ad-hoc macro definitions. Porting would be much easier if there were
>    an RTL description for addressing modes like that for instructions.
>    Tools analogous to genflags and genrecog would generate macros from
>    this description.
>    
>    There would be one pattern in the address-description file for each
>    kind of addressing, and this pattern would have:
>      * the RTL expression for the address
>      * C code to verify its validity (since that may depend on the exact
>        data).
>      * C code to print the address in assembly language.
>      * C code to convert the address into a valid one, if it is not
>        valid. (This would replace LEGITIMIZE_ADDRESS).
>      * Register constraints for all indeterminates that appear in the RTL
>        expression.
> 
> Is any ideas about implementation exists ?

Easiest way to begin to resolve this problem is to using code of SHARC
GCC port with replacing qualifers pm & dm to __attribute__ construction
and generalize this code for using in other ports.

> Is we talk about new methods of address describing ?

Porting would be much more easier if all that we need is *.h file and
instructions description file (*.id) that contains
all kinds of machine instructions description of particular target
look like RTL expressions.

For example instruction of hypothetical processor
"mov r0, [r1 + r2 + const]" may be desribed as:

     (define-instruction
        (set (reg:SI (match-operand 0 "general_register"))
             (mem:SI (plus:SI (match-operand 1 "general_register")
                              (plus:SI (match-operand 2 "general_register")
                                       (match-operand 3 "const_6_bit")))))
        "mov %0, [%1 + %2 + %3]"
        (<setup some attrs>))

     ...

(this example not pretended to be complete: may be need addition contructions)

Then with tools analogous to genflags and genrecog generate *.md file that
contains define-insn, define-expand, define-peephole etc with addition of
defines that describes addressing modes. Addressing modes may be extracted
from MEM, PC and ADDERSSOF expressions, then macros (or code replaced this
macros) like LIGITIMIZE_* would be generated automatically.

> 
> Denis.

Sergey.

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

* Re: Segment register support for the i386
  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:52                   ` Jeffrey A Law
  0 siblings, 2 replies; 30+ messages in thread
From: Denis Chertykov @ 2000-01-06 11:15 UTC (permalink / raw)
  To: Sergey Larin; +Cc: gcc, Denis Chertykov

Sergey Larin <larin@overta.ru> writes:


[...]

> Porting would be much more easier if all that we need is *.h file and
> instructions description file (*.id) that contains
> all kinds of machine instructions description of particular target
> look like RTL expressions.

Really I think only about something like this:

(define-address "VOID" ; for any mode
  (match_operand:HI 0 "immediate_operand" "")
  "/* remain C condition */"
  "%0"
  [(set_attr "cost" "4")])


(define-address "QI,HI,SI,SF"
  (match_operand:HI 0 "register_operand" "e")
  ""
  "*{
  switch (REGNO (operands[0]))
    {
    case REG_X: return \"X\";
    case REG_Y: return \"Y\";
    case REG_Z: return \"Z\";
    default:
      fatal (\"Incorrect register as address\");
    }
  }"
  [(set_attr "cost" "2")])

(define-address "QI,HI,SI,SF"
  (post_inc:HI (match_operand:HI 0 "register_operand" "e"))
  ""
  "*{
  switch (REGNO (operands[0]))
    {
    case REG_X: return \"X+\";
    case REG_Y: return \"Y+\";
    case REG_Z: return \"Z+\";
    default:
      fatal ("Incorrect register as address");
    }
  }"
  [(set_attr "cost" "2")
   (set_attr "mode_dependent" "1")])

(define-address "QI,HI,SI,SF"
  (plus:HI (match_operand:HI 0 "register_operand" "b")
	   (match_operand:HI 1 "const_int_operand" "I"))
  "INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 63"
  "*{
  if (REGNO (operands[0]) == REG_Y)
    return \"Y+%1\";
  else if (REGNO (operands[0] == REG_Z))
    return \"Z+%1\";
  else
    fatal (\"Incorrect register as address\");
  }"
  [(set_attr "cost" "2")])

This is a full (except pre_dec) description of the AVR addressing modes.

Where: `b' - base pointer regs;
       `e' - any reg which can be a pointer.
       `I' - numbers lower than 64 and more or equal than 0.

From this descriptions I can generate:
 - GO_IF_LEGITIMATE_ADDRESS;
 - LEGITIMIZE_RELOAD_ADDRESS;
 - ADDRESS_COST;
 - HAVE_POST_INCREMENT, HAVE_POST_DECREMENT,
   HAVE_PRE_INCREMENT, HAVE_PRE_DECREMENT;
 - BASE_REG_CLASS;
 - INDEX_REG_CLASS;
 - REGNO_MODE_OK_FOR_BASE_P;
 - REGNO_OK_FOR_INDEX_P;
 - REG_OK_FOR_BASE_P;
 - REG_OK_FOR_INDEX_P;

Any suggestions ?

Denis.

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

* Re: Segment register support for the i386
  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
  1 sibling, 1 reply; 30+ messages in thread
From: Joern Rennecke @ 2000-01-06 11:25 UTC (permalink / raw)
  To: Denis Chertykov; +Cc: Sergey Larin, gcc

> >From this descriptions I can generate:
...
>  - LEGITIMIZE_RELOAD_ADDRESS;

I don't see that you can generate LEGITIMIZE_RELOAD_ADDRESS.
You not only need to know the available offset ranges, but also
how constants can be loaded and their cost.

And you also neet to know when it is most useful to use an index
register.

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

* Re: Segment register support for the i386
  2000-01-06 11:25                   ` Joern Rennecke
@ 2000-01-06 11:51                     ` Denis Chertykov
  0 siblings, 0 replies; 30+ messages in thread
From: Denis Chertykov @ 2000-01-06 11:51 UTC (permalink / raw)
  To: Joern Rennecke; +Cc: Denis Chertykov, Sergey Larin, gcc

Joern Rennecke <amylaar@cygnus.co.uk> writes:

> > >From this descriptions I can generate:
> ...
> >  - LEGITIMIZE_RELOAD_ADDRESS;
> 
> I don't see that you can generate LEGITIMIZE_RELOAD_ADDRESS.

I must write:
 - part of LEGITIMIZE_RELOAD_ADDRESS;

I think about LEGITIMIZE_RELOAD_ADDRESS only for correct
BASE_REG_CLASS in reload pass.
Not all registers from BASE_REG_CLASS can be used as reg+offset.
but LEGITIMIZE_RELOAD_ADDRESS don't called in any case.
Also I must correct `find_reloads_address' to using
LEGITIMIZE_RELOAD_ADDRESS in any case, independent from `memrefloc'.

I must write:
 - part of LEGITIMIZE_RELOAD_ADDRESS;

> You not only need to know the available offset ranges, but also
> how constants can be loaded and their cost.
> 
> And you also neet to know when it is most useful to use an index
> register.

Yes. Yes.
LEGITIMIZE_RELOAD_ADDRESS always must exists.

Any suggestions ?

Denis.
PS: Are anybody really interesten in results of this work ?


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

* Re: Segment register support for the i386
  2000-01-06 11:15                 ` Denis Chertykov
  2000-01-06 11:25                   ` Joern Rennecke
@ 2000-01-06 11:52                   ` Jeffrey A Law
  2000-01-07  2:35                     ` Denis Chertykov
  1 sibling, 1 reply; 30+ messages in thread
From: Jeffrey A Law @ 2000-01-06 11:52 UTC (permalink / raw)
  To: Denis Chertykov; +Cc: Sergey Larin, gcc

  In message < 4scrrp55.fsf@localhost.localdomain >you write:
  > Sergey Larin <larin@overta.ru> writes:
  > 
  > 
  > [...]
  > 
  > > Porting would be much more easier if all that we need is *.h file and
  > > instructions description file (*.id) that contains
  > > all kinds of machine instructions description of particular target
  > > look like RTL expressions.
  > 
  > Really I think only about something like this:
  > 
  > (define-address "VOID" ; for any mode
  >   (match_operand:HI 0 "immediate_operand" "")
  >   "/* remain C condition */"
  >   "%0"
  >   [(set_attr "cost" "4")])
You should search the 1997 archives -- I believe Michael Hayes started a
discussion about how to describe addressing modes in the md file.

jeff

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

* Re: Segment register support for the i386
  2000-01-06 11:52                   ` Jeffrey A Law
@ 2000-01-07  2:35                     ` Denis Chertykov
  0 siblings, 0 replies; 30+ messages in thread
From: Denis Chertykov @ 2000-01-07  2:35 UTC (permalink / raw)
  To: law; +Cc: Denis Chertykov, Sergey Larin, gcc

Jeffrey A Law <law@cygnus.com> writes:


[...]

> You should search the 1997 archives -- I believe Michael Hayes started a
> discussion about how to describe addressing modes in the md file.

Thanks.
I have founded the thread about describing addressing modes in
1998-Feb.
Subject: Autoincrement addressing modes

Denis.

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

* Re: Segment register support for the i386
  1999-12-30 11:24 ` Linus Torvalds
@ 1999-12-31 23:54   ` Linus Torvalds
  0 siblings, 0 replies; 30+ messages in thread
From: Linus Torvalds @ 1999-12-31 23:54 UTC (permalink / raw)
  To: submit-linux-egcs

In article < 199912301755.SAA01528@delius.kettenis.local >,
Mark Kettenis  <kettenis@wins.uva.nl> wrote:
>
>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.

Hmm..  Using the segment registers as "real" pointers in C kind of makes
sense, but at the same time it does sound confusing.  You cannot do a
lot of the operations that you are supposed to do with a pointer, and
that lack of true "pointerness" makes it suspect.  What would happen
when somebody converts the pointer to an integer?

>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.

How about another approach entirely: think of segments not as pointers
(which they really aren't, not in the C sense), but as _objects_.  Which
they really were meant to be, after all.  Never mind the fact that it
never really worked out very well. 

Now, if done right, you could do this with a C++ approach, methinks. 
I'm not a big fan of C++ myself, but you could think of it as a minor
extension to C rather than having to go full hog.  So what you could
have is something like the "%fs segment object", and then you overload
the assignment and dereference operations, so that you have

	fs_object *thread_ptr;

	y = thread_ptr->tid;

where the dereference gets transformed by the C++ upper layers into

	__asm__("movl %%fs:%0,%1": :"m" (tid), "r" (y));

Ugh..

I'm probably explaining this badly.  What I _mean_ to say is really that
you can try to get the behaviour you want (the _appearance_ of a "thread
structure pointer dereference") without ever going down into the actual
code-generation layer, but instead converting it at a higher level into
the asm code you really want. 

That would require no changes at the architecture-specific time, and
might be useful for other things.  I guess you can't do it as-is (does
C++ even allow overloading of the assignment and dereference
operators?), but that might be an approach that is more generic and more
acceptable to maintainers (because this approach could be used for other
tricks too - hiding nasty syntax behind a C++ layer). 

But maybe the above is just even worse than playing with the code generator.

		Linus

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

* Re: Segment register support for the i386
  1999-12-30 13:07 ` Martin v. Loewis
@ 1999-12-31 23:54   ` Martin v. Loewis
  0 siblings, 0 replies; 30+ messages in thread
From: Martin v. Loewis @ 1999-12-31 23:54 UTC (permalink / raw)
  To: kettenis; +Cc: gcc

> 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.  

They would not be pointer attributes. Instead, they would be type
attributes:

struct TLS{
  fill_in something;
  and something_else;
}__attribute__((segment("gs")));

struct TLS *tls;

then you do

  tls->something++;

and it knows to use a segment prefix on each reference.

Alternatively, they could be qualifiers, like const, volatile,
restrict - although this sounds like a major new extension.

> 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.

No, that would not be nice. What if I do:

  int i;
  __thread_self = &i;

That does not *at all* do what it looks like it would do (if it does
anything at all).

> 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.

I would be such a person :(

Regards,
Martin

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

* Re: Segment register support for the i386
  1999-12-30  9:55 Mark Kettenis
  1999-12-30 11:24 ` Linus Torvalds
  1999-12-30 13:07 ` Martin v. Loewis
@ 1999-12-31 23:54 ` Mark Kettenis
  2 siblings, 0 replies; 30+ messages in thread
From: Mark Kettenis @ 1999-12-31 23:54 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

* Re: Segment register support for the i386
  1999-12-30  9:55 Mark Kettenis
  1999-12-30 11:24 ` 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
  2 siblings, 1 reply; 30+ messages in thread
From: Martin v. Loewis @ 1999-12-30 13:07 UTC (permalink / raw)
  To: kettenis; +Cc: gcc

> 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.  

They would not be pointer attributes. Instead, they would be type
attributes:

struct TLS{
  fill_in something;
  and something_else;
}__attribute__((segment("gs")));

struct TLS *tls;

then you do

  tls->something++;

and it knows to use a segment prefix on each reference.

Alternatively, they could be qualifiers, like const, volatile,
restrict - although this sounds like a major new extension.

> 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.

No, that would not be nice. What if I do:

  int i;
  __thread_self = &i;

That does not *at all* do what it looks like it would do (if it does
anything at all).

> 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.

I would be such a person :(

Regards,
Martin

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

* Re: Segment register support for the i386
  1999-12-30  9:55 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 ` Mark Kettenis
  2 siblings, 1 reply; 30+ messages in thread
From: Linus Torvalds @ 1999-12-30 11:24 UTC (permalink / raw)
  To: submit-linux-egcs

In article < 199912301755.SAA01528@delius.kettenis.local >,
Mark Kettenis  <kettenis@wins.uva.nl> wrote:
>
>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.

Hmm..  Using the segment registers as "real" pointers in C kind of makes
sense, but at the same time it does sound confusing.  You cannot do a
lot of the operations that you are supposed to do with a pointer, and
that lack of true "pointerness" makes it suspect.  What would happen
when somebody converts the pointer to an integer?

>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.

How about another approach entirely: think of segments not as pointers
(which they really aren't, not in the C sense), but as _objects_.  Which
they really were meant to be, after all.  Never mind the fact that it
never really worked out very well. 

Now, if done right, you could do this with a C++ approach, methinks. 
I'm not a big fan of C++ myself, but you could think of it as a minor
extension to C rather than having to go full hog.  So what you could
have is something like the "%fs segment object", and then you overload
the assignment and dereference operations, so that you have

	fs_object *thread_ptr;

	y = thread_ptr->tid;

where the dereference gets transformed by the C++ upper layers into

	__asm__("movl %%fs:%0,%1": :"m" (tid), "r" (y));

Ugh..

I'm probably explaining this badly.  What I _mean_ to say is really that
you can try to get the behaviour you want (the _appearance_ of a "thread
structure pointer dereference") without ever going down into the actual
code-generation layer, but instead converting it at a higher level into
the asm code you really want. 

That would require no changes at the architecture-specific time, and
might be useful for other things.  I guess you can't do it as-is (does
C++ even allow overloading of the assignment and dereference
operators?), but that might be an approach that is more generic and more
acceptable to maintainers (because this approach could be used for other
tricks too - hiding nasty syntax behind a C++ layer). 

But maybe the above is just even worse than playing with the code generator.

		Linus

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

* 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

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-24  8:42 Segment register support for the i386 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
1999-12-30  9:55 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

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).