www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Inconsistency in CPU version symbols

reply Johannes Pfau <nospam example.com> writes:
I started implementing all the CPU based version symbols shown on
http://dlang.org/version.html for GDC
(https://gist.github.com/4647493), but I found some things to be
strange:

Floating point:
* Why do we have PPC_SoftFP but MIPS_SoftFloat? I'd say we should use
  *_SoftFloat everywhere for consistency. (Except for arm where
  SoftFP has a different meaning)
* Do we need the arch specific SoftFloat/HardFloat if a target only has
  those two? Why PPC_SoftFP and PPC_HardFP, doesn't
  version(PPC){version(D_SoftFloat) else version(D_HardFloat)} work?
* Even for ARM, which has a third mode, we could get rid of
  ARM_Soft and ARM_HardFP, keeping only ARM_SoftFP. Then you can do
  this:

version(ARM)
{
    version(D_SoftFloat)
    {//ARM_SoftFloat
    }
    else version(D_HardFloat)
    {
        version(ARM_SoftFP){}//ARM_SoftFP, special case of D_HardFloat
        else {}//ARM_HardFP
    }
    else
    {//NoFloat
    }
}

* Why do we have MIPS_NoFloat? This can be replaced by
  version(D_SoftFloat) else version(D_HardFloat) else()
  (looks a little ugly, but a convenience version can be defined in user
  code)

* Why do we have MIPS32? No other architecture has a 32 version?


Questions:
* D_LP64 docs say it means 64bit pointers. GDC currently checks for
  "INT_SIZE == 32 && LONG_INT_SIZE == 64 && POINTER_SIZE == 64" which
  matches the C definition of LP64. This would not match ILP64/SILP64
  for example, so what is D_LP64 supposed to mean?	

* ARM64 always has a FPU. I guess it should not set any of the
  ARM_*Float versions?

* Are D_X32 and X86_64 exclusive or does a X32 system define both?

* What about an ARM_Thumb2 version?

* Does Cygwin also define Windows, Win32, Win64? Posix?

Minor doc problems:
ARM: the docs should say AArch32 not AArch32:A32, that's my fault, I'll
file a pull request.
ARM64: AArch64 instead of AArch64:A64
Jan 27 2013
next sibling parent Jacob Carlborg <doob me.com> writes:
On 2013-01-27 10:42, Johannes Pfau wrote:

 Questions:
 * D_LP64 docs say it means 64bit pointers. GDC currently checks for
    "INT_SIZE == 32 && LONG_INT_SIZE == 64 && POINTER_SIZE == 64" which
    matches the C definition of LP64. This would not match ILP64/SILP64
    for example, so what is D_LP64 supposed to mean?	

Looking at the source code, by default LP64 is set if sizeof(size_t) == 8. The the -m32/64 flags can override this. On Windows that name is kind of misleading. On Windows the correct data models seems to be LLP64. http://en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models -- /Jacob Carlborg
Jan 27 2013
prev sibling parent reply =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= <alex lycus.org> writes:
On 27-01-2013 10:42, Johannes Pfau wrote:
 I started implementing all the CPU based version symbols shown on
 http://dlang.org/version.html for GDC
 (https://gist.github.com/4647493), but I found some things to be
 strange:

 Floating point:
 * Why do we have PPC_SoftFP but MIPS_SoftFloat? I'd say we should use
    *_SoftFloat everywhere for consistency. (Except for arm where
    SoftFP has a different meaning)

Yes. Please send a pull request.
 * Do we need the arch specific SoftFloat/HardFloat if a target only has
    those two? Why PPC_SoftFP and PPC_HardFP, doesn't
    version(PPC){version(D_SoftFloat) else version(D_HardFloat)} work?

The intention was that the arch-specific ones should be used to make ABI and architecture-specific decisions while the D_* ones should be used as a general flag indicating whether an FPU exists at all.
 * Even for ARM, which has a third mode, we could get rid of
    ARM_Soft and ARM_HardFP, keeping only ARM_SoftFP. Then you can do
    this:

 version(ARM)
 {
      version(D_SoftFloat)
      {//ARM_SoftFloat
      }
      else version(D_HardFloat)
      {
          version(ARM_SoftFP){}//ARM_SoftFP, special case of D_HardFloat
          else {}//ARM_HardFP
      }
      else
      {//NoFloat
      }
 }

I think that makes it more confusing.
 * Why do we have MIPS_NoFloat? This can be replaced by
    version(D_SoftFloat) else version(D_HardFloat) else()
    (looks a little ugly, but a convenience version can be defined in user
    code)

I am guessing MIPS_NoFloat is for targets where not even soft float exists. But we don't actually support such targets, so this should probably be removed. Martin, thoughts on this?
 * Why do we have MIPS32? No other architecture has a 32 version?

We discussed that here: https://github.com/D-Programming-Language/d-programming-language.org/pull/207#discussion_r2358525
 Questions:
 * D_LP64 docs say it means 64bit pointers. GDC currently checks for
    "INT_SIZE == 32 && LONG_INT_SIZE == 64 && POINTER_SIZE == 64" which
    matches the C definition of LP64. This would not match ILP64/SILP64
    for example, so what is D_LP64 supposed to mean?	

D is specifically designed to not care about targets where word size != pointer size. That is, size_t.sizeof must == (void*).sizeof. It can probably work on such targets, though, so long as D_LP64 is only set when both of those are 64. Why the check for INT_SIZE? Isn't it always 16 or 32 in GCC (never 64)?
 * ARM64 always has a FPU. I guess it should not set any of the
    ARM_*Float versions?

I think for convenience and least surprise, we should still set ARM_HardFP.
 * Are D_X32 and X86_64 exclusive or does a X32 system define both?

D_X32 is a data model (like D_LP64) so it can be defined alongside X86_64.
 * What about an ARM_Thumb2 version?

Are Thumb1 systems still relevant today? I'm not too familiar with Thumb, so forgive my ignorance here. If we still do need to care about Thumb1, then OK.
 * Does Cygwin also define Windows, Win32, Win64? Posix?

I don't think anyone has ported a D compiler to Cygwin, so who knows... I'd certainly expect it to define the first 3, but not sure about the last one... Probably not, though, as a lot of D code assumes Windows and Posix are mutually exclusive.
 Minor doc problems:
 ARM: the docs should say AArch32 not AArch32:A32, that's my fault, I'll
 file a pull request.
 ARM64: AArch64 instead of AArch64:A64

OK. -- Alex Rønne Petersen alex alexrp.com / alex lycus.org http://lycus.org
Jan 27 2013
next sibling parent reply Iain Buclaw <ibuclaw ubuntu.com> writes:
On 27 Jan 2013 15:26, "Alex R=F8nne Petersen" <alex lycus.org> wrote:
 On 27-01-2013 10:42, Johannes Pfau wrote:
 I started implementing all the CPU based version symbols shown on
 http://dlang.org/version.html for GDC
 (https://gist.github.com/4647493), but I found some things to be
 strange:

 Floating point:
 * Why do we have PPC_SoftFP but MIPS_SoftFloat? I'd say we should use
    *_SoftFloat everywhere for consistency. (Except for arm where
    SoftFP has a different meaning)

Yes. Please send a pull request.
 * Do we need the arch specific SoftFloat/HardFloat if a target only has
    those two? Why PPC_SoftFP and PPC_HardFP, doesn't
    version(PPC){version(D_SoftFloat) else version(D_HardFloat)} work?

The intention was that the arch-specific ones should be used to make ABI

and architecture-specific decisions while the D_* ones should be used as a general flag indicating whether an FPU exists at all.
 * Even for ARM, which has a third mode, we could get rid of
    ARM_Soft and ARM_HardFP, keeping only ARM_SoftFP. Then you can do
    this:

 version(ARM)
 {
      version(D_SoftFloat)
      {//ARM_SoftFloat
      }
      else version(D_HardFloat)
      {
          version(ARM_SoftFP){}//ARM_SoftFP, special case of D_HardFloat
          else {}//ARM_HardFP
      }
      else
      {//NoFloat
      }
 }

I think that makes it more confusing.
 * Why do we have MIPS_NoFloat? This can be replaced by
    version(D_SoftFloat) else version(D_HardFloat) else()
    (looks a little ugly, but a convenience version can be defined in use=


r
    code)

I am guessing MIPS_NoFloat is for targets where not even soft float

exists. But we don't actually support such targets, so this should probably be removed.
 Martin, thoughts on this?


 * Why do we have MIPS32? No other architecture has a 32 version?

We discussed that here:

https://github.com/D-Programming-Language/d-programming-language.org/pull/2= 07#discussion_r2358525
 Questions:
 * D_LP64 docs say it means 64bit pointers. GDC currently checks for
    "INT_SIZE =3D=3D 32 && LONG_INT_SIZE =3D=3D 64 && POINTER_SIZE =3D=3D=


64" which
    matches the C definition of LP64. This would not match ILP64/SILP64
    for example, so what is D_LP64 supposed to mean?

D is specifically designed to not care about targets where word size !=3D

pointer size. That is, size_t.sizeof must =3D=3D (void*).sizeof. It can probably work on such targets, though, so long as D_LP64 is only set when both of those are 64.

I see this as being a bug.
 Why the check for INT_SIZE? Isn't it always 16 or 32 in GCC (never 64)?

There are __ILP64__ targets out there... For D, its only useful for C compatibilty, eg: version(D_ILP64) alias long c_int;
 * ARM64 always has a FPU. I guess it should not set any of the
    ARM_*Float versions?

I think for convenience and least surprise, we should still set

ARM_HardFP.
 * Are D_X32 and X86_64 exclusive or does a X32 system define both?

D_X32 is a data model (like D_LP64) so it can be defined alongside X86_64=

.
 * What about an ARM_Thumb2 version?

Are Thumb1 systems still relevant today? I'm not too familiar with Thumb,

so forgive my ignorance here. If we still do need to care about Thumb1, then OK.

I seem to recall thumb being mostly 16bit systems.
 * Does Cygwin also define Windows, Win32, Win64? Posix?

I don't think anyone has ported a D compiler to Cygwin, so who knows... I'd certainly expect it to define the first 3, but not sure about the

last one... Probably not, though, as a lot of D code assumes Windows and Posix are mutually exclusive.

It should define Posix and Windows. I wouldn't have thought Win32/Win64 to be required/is out of scope for the cygwin platform. Regards Iain
Jan 27 2013
parent reply Johannes Pfau <nospam example.com> writes:
Am Sun, 27 Jan 2013 16:14:19 +0000
schrieb Iain Buclaw <ibuclaw ubuntu.com>:

 Are Thumb1 systems still relevant today? I'm not too familiar with
 Thumb,

so forgive my ignorance here. If we still do need to care about Thumb1, then OK.

I seem to recall thumb being mostly 16bit systems.

Really? AFAIK ARM has always been 32bit or more. Thumb only limits instruction size to 16bit, the registers are still 32bit.
Jan 27 2013
parent Iain Buclaw <ibuclaw ubuntu.com> writes:
On 27 January 2013 17:17, Johannes Pfau <nospam example.com> wrote:

 Am Sun, 27 Jan 2013 16:14:19 +0000
 schrieb Iain Buclaw <ibuclaw ubuntu.com>:

 Are Thumb1 systems still relevant today? I'm not too familiar with
 Thumb,

so forgive my ignorance here. If we still do need to care about Thumb1, then OK.

I seem to recall thumb being mostly 16bit systems.

Really? AFAIK ARM has always been 32bit or more. Thumb only limits instruction size to 16bit, the registers are still 32bit.

Learn something new every day. :) -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0';
Jan 27 2013
prev sibling parent Johannes Pfau <nospam example.com> writes:
Am Sun, 27 Jan 2013 16:20:58 +0100
schrieb Alex R=C3=B8nne Petersen <alex lycus.org>:

=20
 * Do we need the arch specific SoftFloat/HardFloat if a target only
 has those two? Why PPC_SoftFP and PPC_HardFP, doesn't
    version(PPC){version(D_SoftFloat) else version(D_HardFloat)}
 work?

=20 The intention was that the arch-specific ones should be used to make ABI and architecture-specific decisions while the D_* ones should be used as a general flag indicating whether an FPU exists at all.

OK I can live with that reasoning.
=20
 * Why do we have MIPS_NoFloat? This can be replaced by
    version(D_SoftFloat) else version(D_HardFloat) else()
    (looks a little ugly, but a convenience version can be defined
 in user code)

=20 I am guessing MIPS_NoFloat is for targets where not even soft float=20 exists. But we don't actually support such targets, so this should=20 probably be removed. =20 Martin, thoughts on this?

I don't think it's important whether we support NoFloat targets. But either way NoFloat is generic, so it should either be D_NoFloat or no NoFloat at all, I don't see a reason for architecture specific NoFloat. Also NoFloat isn't necessary at all, as you can do: version(D_SoftFloat) else version(D_HardFloat) else //NoFloat
=20
 * Why do we have MIPS32? No other architecture has a 32 version?

=20 We discussed that here:=20 https://github.com/D-Programming-Language/d-programming-language.org/pull=

/207#discussion_r2358525 I can understand that reasoning, but we should either have it for all architectures or for none. Having 32bit versions only for MIPS is inconsistent.
 Questions:
 * D_LP64 docs say it means 64bit pointers. GDC currently checks for
    "INT_SIZE =3D=3D 32 && LONG_INT_SIZE =3D=3D 64 && POINTER_SIZE =3D=


=3D 64"
 which matches the C definition of LP64. This would not match
 ILP64/SILP64 for example, so what is D_LP64 supposed to
 mean?=09

=20 D is specifically designed to not care about targets where word size !=3D pointer size. That is, size_t.sizeof must =3D=3D (void*).sizeof.

Pointers and size_t can have equal sizes even on non LP64 systems, see this table: http://en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models
 It can probably work on such targets, though, so long as D_LP64 is
 only set when both of those are 64.
=20
 Why the check for INT_SIZE? Isn't it always 16 or 32 in GCC (never
 64)?

No, there are data models with INT_SIZE=3D64 and LP64 usually doesn't include those. See the wikipedia table. But these data models are only important when interfacing with C, so I'd say make D_LP64 mean pointers are 64 bit (longpointer, 64bit). For c_long, c_ulong, c_int, c_uint just add built in types gcc.builtins.__builtin_clong and make c_long an alias.
=20
 * ARM64 always has a FPU. I guess it should not set any of the
    ARM_*Float versions?

=20 I think for convenience and least surprise, we should still set ARM_HardFP. =20

I have no strong opinion here, but I'd prefer 'clear' behavior.
=20
 * What about an ARM_Thumb2 version?

=20 Are Thumb1 systems still relevant today? I'm not too familiar with=20 Thumb, so forgive my ignorance here. If we still do need to care about Thumb1, then OK.

We basically need it to detect non-thumb. As ARM is also set for thumb code you have to do this: version(ARM) { version(Thumb1) version(Thumb2) else //No Thumb } We could also make Thumb mean 'any' thumb.
Jan 27 2013