digitalmars.D - Can we kill the D calling convention already?
- =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= <xtzgzorex gmail.com> Apr 24 2012
- Gor Gyolchanyan <gor.f.gyolchanyan gmail.com> Apr 24 2012
- "Kagamin" <spam here.lot> Apr 24 2012
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= <xtzgzorex gmail.com> Apr 24 2012
- =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= <xtzgzorex gmail.com> Apr 24 2012
- mta`chrono <chrono mta-international.net> Apr 24 2012
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= <xtzgzorex gmail.com> Apr 24 2012
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= <xtzgzorex gmail.com> Apr 25 2012
- Don Clugston <dac nospam.com> Apr 25 2012
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= <xtzgzorex gmail.com> Apr 26 2012
- Iain Buclaw <ibuclaw ubuntu.com> Apr 24 2012
- "Erik Jensen" <eriksjunk rkjnsn.net> Apr 24 2012
- "Paulo Pinto" <pjmlp progtools.org> Apr 24 2012
- Iain Buclaw <ibuclaw ubuntu.com> Apr 24 2012
- "Kagamin" <spam here.lot> Apr 25 2012
- "Paulo Pinto" <pjmlp progtools.org> Apr 25 2012
- "Paulo Pinto" <pjmlp progtools.org> Apr 25 2012
- mta`chrono <chrono mta-international.net> Apr 25 2012
- =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= <xtzgzorex gmail.com> Apr 25 2012
- "CTFE-4-the-win" <CTFE 4the.win> Apr 25 2012
- "David Nadlinger" <see klickverbot.at> Apr 25 2012
- "Jonathan M Davis" <jmdavisProg gmx.com> Apr 25 2012
- "Kagamin" <spam here.lot> Apr 26 2012
Writing portable code is hard enough as it is. Why do we have to have some random, D-specialized calling convention (only on Win32 and only in DMD)? The result of the current state of things is that extern(D) is essentially useless - it has completely different meanings across compilers. You cannot rely on it at all. If memory serves me right, both LDC and GDC just alias it to extern(C), but DMD insists on using this magical D calling convention on Win32. I'm not attacking the D ABI (name mangling) here, but I do think this calling convention needs to either go away, or be optional (i.e. as some extern() argument). We *have* to make extern(D) consistent across compilers, or we'll be no better than the mess that is C and C++; we're advertising a standard inline assembler with support for naked functions, but that support is useless if we don't have a consistent default calling convention. -- - Alex
Apr 24 2012
There are lots of times, when a specialized custom calling convention is necessary. For instance, I need a dynamic typing subsystem, to create abstract state machines, which can be effortlessly adapted to run-time heterogeneous data. I already made a function, that takes arbitrary arguments and tightly packs them in a single chunk of memory, making a run-time defined structures. A new calling convention would normalize the ABI of all functions, making them all take a single pointer to such a structure. This will allow to safely discard the static type info of the functions, allowing them to be stored in and called from statically homogeneous containers (like the ones inside an abstract state machine). Currently, in order to do that, you'd need to define a function in a very weird way and use tons of mixins to inject naked function assembly to do this without the overhead of going through the current static-only type system and calling conventions. A simple option of allowing to define custom calling convention would already lead to library solutions, that make D equally effective static and dynamic typed language simultaneously (which would be beautifully integrated with each other). On Tue, Apr 24, 2012 at 1:10 PM, Iain Buclaw <ibuclaw ubuntu.com> wrote:On 24 April 2012 10:08, Iain Buclaw <ibuclaw ubuntu.com> wrote:On 24 April 2012 09:42, Alex R=C3=B8nne Petersen <xtzgzorex gmail.com> w=
Writing portable code is hard enough as it is. Why do we have to have s=
random, D-specialized calling convention (only on Win32 and only in DMD=
The result of the current state of things is that extern(D) is essentia=
useless - it has completely different meanings across compilers. You ca=
rely on it at all. If memory serves me right, both LDC and GDC just ali=
to extern(C), but DMD insists on using this magical D calling conventio=
Win32.
extern(System) would be a more accurate description of what GDC does, as it uses the default calling convention for the target/platform you are running on, which may not neccessarily be extern(C).
s/ running on / compiling for / -- Iain Buclaw *(p < e ? p++ : p) =3D (c & 0x0f) + '0';
--=20 Bye, Gor Gyolchanyan.
Apr 24 2012
On 24-04-2012 11:41, Gor Gyolchanyan wrote:There are lots of times, when a specialized custom calling convention is necessary. For instance, I need a dynamic typing subsystem, to create abstract state machines, which can be effortlessly adapted to run-time heterogeneous data. I already made a function, that takes arbitrary arguments and tightly packs them in a single chunk of memory, making a run-time defined structures. A new calling convention would normalize the ABI of all functions, making them all take a single pointer to such a structure. This will allow to safely discard the static type info of the functions, allowing them to be stored in and called from statically homogeneous containers (like the ones inside an abstract state machine). Currently, in order to do that, you'd need to define a function in a very weird way and use tons of mixins to inject naked function assembly to do this without the overhead of going through the current static-only type system and calling conventions. A simple option of allowing to define custom calling convention would already lead to library solutions, that make D equally effective static and dynamic typed language simultaneously (which would be beautifully integrated with each other). On Tue, Apr 24, 2012 at 1:10 PM, Iain Buclaw<ibuclaw ubuntu.com> wrote:On 24 April 2012 10:08, Iain Buclaw<ibuclaw ubuntu.com> wrote:On 24 April 2012 09:42, Alex Rønne Petersen<xtzgzorex gmail.com> wrote:Writing portable code is hard enough as it is. Why do we have to have some random, D-specialized calling convention (only on Win32 and only in DMD)? The result of the current state of things is that extern(D) is essentially useless - it has completely different meanings across compilers. You cannot rely on it at all. If memory serves me right, both LDC and GDC just alias it to extern(C), but DMD insists on using this magical D calling convention on Win32.
extern(System) would be a more accurate description of what GDC does, as it uses the default calling convention for the target/platform you are running on, which may not neccessarily be extern(C).
s/ running on / compiling for / -- Iain Buclaw *(p< e ? p++ : p) = (c& 0x0f) + '0';
I'm not sure what that has to do with the state of extern(D), but yes, I agree that custom calling conventions could be useful in some specialized cases. -- - Alex
Apr 24 2012
Speaking about GDC, you can't link to omf files directly - so there shouldn't be any binary incompatibility. If the assembler code is unportable across compilers, it's a developer's mistake or intention.
Apr 24 2012
On 24-04-2012 11:42, Kagamin wrote:Speaking about GDC, you can't link to omf files directly - so there shouldn't be any binary incompatibility. If the assembler code is unportable across compilers, it's a developer's mistake or intention.
The point is just that: Right now I can write assembly that will work on GDC, LDC, and DMD on non-Windows. It will not work for DMD on Windows. Something has to change here. You're missing the point if you think this is a "developer mistake". -- - Alex
Apr 24 2012
On 24-04-2012 16:39, Iain Buclaw wrote:On 24 April 2012 11:29, Alex Rønne Petersen<xtzgzorex gmail.com> wrote:On 24-04-2012 11:42, Kagamin wrote:Speaking about GDC, you can't link to omf files directly - so there shouldn't be any binary incompatibility. If the assembler code is unportable across compilers, it's a developer's mistake or intention.
The point is just that: Right now I can write assembly that will work on GDC, LDC, and DMD on non-Windows. It will not work for DMD on Windows. Something has to change here. You're missing the point if you think this is a "developer mistake".
Is not just Windows, the DMD calling convention on Linux differs from the system calling convention. For example, some of the naked functions in std.math returning floating point values assumes caller clean up. Where as the C calling convention is callee clean up.
It just gets better and better! :) -- - Alex
Apr 24 2012
As D is more than just C or C++ it may take account for providing it's own calling convention. _BUT_ (That's the point, I agree to Alex), it needs to be consistent across _different compilers for the same plattform_. Maybe someone can point out the benefits of having a different calling convention on linux and windows for the same target machine.
Apr 24 2012
On 24-04-2012 19:54, Paulo Pinto wrote:This means that in the end we have the same ABI issues between D compilers, as in other languages I suppose, right? -- Paulo On Tuesday, 24 April 2012 at 14:40:05 UTC, Iain Buclaw wrote:On 24 April 2012 11:29, Alex Rønne Petersen <xtzgzorex gmail.com> wrote:On 24-04-2012 11:42, Kagamin wrote:Speaking about GDC, you can't link to omf files directly - so there shouldn't be any binary incompatibility. If the assembler code is unportable across compilers, it's a developer's mistake or intention.
The point is just that: Right now I can write assembly that will work on GDC, LDC, and DMD on non-Windows. It will not work for DMD on Windows. Something has to change here. You're missing the point if you think this is a "developer mistake".
Is not just Windows, the DMD calling convention on Linux differs from the system calling convention. For example, some of the naked functions in std.math returning floating point values assumes caller clean up. Where as the C calling convention is callee clean up.
Exactly. We can do better, and we really should. -- - Alex
Apr 24 2012
On 25-04-2012 15:06, Kagamin wrote:On Tuesday, 24 April 2012 at 10:29:52 UTC, Alex Rønne Petersen wrote:The point is just that: Right now I can write assembly that will work on GDC, LDC, and DMD on non-Windows. It will not work for DMD on Windows. Something has to change here.
If it doesn't work on Windows, it should be versioned out. What we have: http://dlang.org/version.html#PredefinedVersions - versions for LDC, GDC, DMD and Windows - all what you want.
Yes, I added them. :) You're missing the point. D is providing (or trying to provide) a standard inline assembler, but calling conventions are not standardized enough for it to be useful across compilers. If you're writing inline assembly because you *have* to, you don't just "version it out", you have to write different logic for different compilers, which is a maintenance nightmare. -- - Alex
Apr 25 2012
On 25/04/12 17:05, Paulo Pinto wrote:On Wednesday, 25 April 2012 at 14:32:13 UTC, Alex Rønne Petersen wrote:On 25-04-2012 15:06, Kagamin wrote:On Tuesday, 24 April 2012 at 10:29:52 UTC, Alex Rønne Petersen wrote:The point is just that: Right now I can write assembly that will work on GDC, LDC, and DMD on non-Windows. It will not work for DMD on Windows. Something has to change here.
If it doesn't work on Windows, it should be versioned out. What we have: http://dlang.org/version.html#PredefinedVersions - versions for LDC, GDC, DMD and Windows - all what you want.
Yes, I added them. :) You're missing the point. D is providing (or trying to provide) a standard inline assembler, but calling conventions are not standardized enough for it to be useful across compilers. If you're writing inline assembly because you *have* to, you don't just "version it out", you have to write different logic for different compilers, which is a maintenance nightmare.
This is exactly what C++ gets blamed for, yet most people fail to realize that the situation is common to all languages that generate native code.
No, it's totally the fault of C++. C++ failed to specify it, so everyone did something different. Then you get this very unfortunate mindset where everyone is so used to it, they don't find it unacceptable any more.The only reason it works out for C, is that the C ABI is actually the OS ABI, as such all C compilers tend to have a common ABI.
Not true. The ABI for Win32 is __stdcall, not C. Pascal and Fortran calling conventions were always well standardized, too.It would be nice if I could use D libraries without having to worry which compiler was used to generate them.
Yes. This is mandatory. It'd be fantastic if we had a calling convention that depended ONLY on the CPU, not on the OS. But I don't know if it is feasible. The Windows64 calling convention is standardized, and it's different to the Linux64 one. I don't know if it's even possible to use a different calling convention on Win64, there are interactions with system exception handling.
Apr 25 2012
On 26-04-2012 13:37, Kagamin wrote:On Wednesday, 25 April 2012 at 14:32:13 UTC, Alex Rønne Petersen wrote:You're missing the point. D is providing (or trying to provide) a standard inline assembler, but calling conventions are not standardized enough for it to be useful across compilers. If you're writing inline assembly because you *have* to, you don't just "version it out", you have to write different logic for different compilers, which is a maintenance nightmare.
Don't implement complex logic in assembly, extract it to D or C code.
Look, your argument is just plain invalid. Please reread what I said: "[...] If you're writing inline assembly because you *have* to [...]". Notice the emphasis. And even if we disregarded that, the language boasts a standardized inline assembler, and therefore needs to actually make it sane to use it. As it stands, we're no better than C and C++, yet we claim we are. -- - Alex
Apr 26 2012
On 24 April 2012 11:29, Alex R=F8nne Petersen <xtzgzorex gmail.com> wrote:On 24-04-2012 11:42, Kagamin wrote:Speaking about GDC, you can't link to omf files directly - so there shouldn't be any binary incompatibility. If the assembler code is unportable across compilers, it's a developer's mistake or intention.
The point is just that: Right now I can write assembly that will work on GDC, LDC, and DMD on non-Windows. It will not work for DMD on Windows. Something has to change here. You're missing the point if you think this is a "developer mistake".
Is not just Windows, the DMD calling convention on Linux differs from the system calling convention. For example, some of the naked functions in std.math returning floating point values assumes caller clean up. Where as the C calling convention is callee clean up. --=20 Iain Buclaw *(p < e ? p++ : p) =3D (c & 0x0f) + '0';
Apr 24 2012
On Tuesday, 24 April 2012 at 14:40:05 UTC, Iain Buclaw wrote:On 24 April 2012 11:29, Alex Rønne Petersen <xtzgzorex gmail.com> wrote:On 24-04-2012 11:42, Kagamin wrote:Speaking about GDC, you can't link to omf files directly - so there shouldn't be any binary incompatibility. If the assembler code is unportable across compilers, it's a developer's mistake or intention.
The point is just that: Right now I can write assembly that will work on GDC, LDC, and DMD on non-Windows. It will not work for DMD on Windows. Something has to change here. You're missing the point if you think this is a "developer mistake".
Is not just Windows, the DMD calling convention on Linux differs from the system calling convention. For example, some of the naked functions in std.math returning floating point values assumes caller clean up. Where as the C calling convention is callee clean up.
That is incorrect. The cdecl calling convention is caller clean-up (see http://en.wikipedia.org/wiki/X86_calling_conventions). Otherwise, variable argument functions would not be possible (the called function doesn't know what to clean up).
Apr 24 2012
This means that in the end we have the same ABI issues between D compilers, as in other languages I suppose, right? -- Paulo On Tuesday, 24 April 2012 at 14:40:05 UTC, Iain Buclaw wrote:On 24 April 2012 11:29, Alex Rønne Petersen <xtzgzorex gmail.com> wrote:On 24-04-2012 11:42, Kagamin wrote:Speaking about GDC, you can't link to omf files directly - so there shouldn't be any binary incompatibility. If the assembler code is unportable across compilers, it's a developer's mistake or intention.
The point is just that: Right now I can write assembly that will work on GDC, LDC, and DMD on non-Windows. It will not work for DMD on Windows. Something has to change here. You're missing the point if you think this is a "developer mistake".
Is not just Windows, the DMD calling convention on Linux differs from the system calling convention. For example, some of the naked functions in std.math returning floating point values assumes caller clean up. Where as the C calling convention is callee clean up.
Apr 24 2012
On 24 April 2012 17:05, Erik Jensen <eriksjunk rkjnsn.net> wrote:On Tuesday, 24 April 2012 at 14:40:05 UTC, Iain Buclaw wrote:On 24 April 2012 11:29, Alex R=F8nne Petersen <xtzgzorex gmail.com> wrot=
On 24-04-2012 11:42, Kagamin wrote:Speaking about GDC, you can't link to omf files directly - so there shouldn't be any binary incompatibility. If the assembler code is unportable across compilers, it's a developer=
mistake or intention.
The point is just that: Right now I can write assembly that will work o=
GDC, LDC, and DMD on non-Windows. It will not work for DMD on Windows. Something has to change here. You're missing the point if you think this is a "developer mistake".
Is not just Windows, the DMD calling convention on Linux differs from the system calling convention. =A0For example, some of the naked functions in std.math returning floating point values assumes caller clean up. =A0Where as the C calling convention is callee clean up.
That is incorrect. The cdecl calling convention is caller clean-up (see http://en.wikipedia.org/wiki/X86_calling_conventions). Otherwise, variabl=
argument functions would not be possible (the called function doesn't kno=
what to clean up).
I forget which, but I'm pretty certain the CDecl calling convention does not call 'ret PARAMSIZE;' when returning floats. =3D) --=20 Iain Buclaw *(p < e ? p++ : p) =3D (c & 0x0f) + '0';
Apr 24 2012
On Tuesday, 24 April 2012 at 10:29:52 UTC, Alex Rønne Petersen wrote:The point is just that: Right now I can write assembly that will work on GDC, LDC, and DMD on non-Windows. It will not work for DMD on Windows. Something has to change here.
If it doesn't work on Windows, it should be versioned out. What we have: http://dlang.org/version.html#PredefinedVersions - versions for LDC, GDC, DMD and Windows - all what you want.
Apr 25 2012
On Wednesday, 25 April 2012 at 14:32:13 UTC, Alex Rønne Petersen wrote:On 25-04-2012 15:06, Kagamin wrote:On Tuesday, 24 April 2012 at 10:29:52 UTC, Alex Rønne Petersen wrote:The point is just that: Right now I can write assembly that will work on GDC, LDC, and DMD on non-Windows. It will not work for DMD on Windows. Something has to change here.
If it doesn't work on Windows, it should be versioned out. What we have: http://dlang.org/version.html#PredefinedVersions - versions for LDC, GDC, DMD and Windows - all what you want.
Yes, I added them. :) You're missing the point. D is providing (or trying to provide) a standard inline assembler, but calling conventions are not standardized enough for it to be useful across compilers. If you're writing inline assembly because you *have* to, you don't just "version it out", you have to write different logic for different compilers, which is a maintenance nightmare.
This is exactly what C++ gets blamed for, yet most people fail to realize that the situation is common to all languages that generate native code. The only reason it works out for C, is that the C ABI is actually the OS ABI, as such all C compilers tend to have a common ABI. It would be nice if I could use D libraries without having to worry which compiler was used to generate them.
Apr 25 2012
On Wednesday, 25 April 2012 at 15:20:31 UTC, Don Clugston wrote:On 25/04/12 17:05, Paulo Pinto wrote:On Wednesday, 25 April 2012 at 14:32:13 UTC, Alex Rønne Petersen wrote:On 25-04-2012 15:06, Kagamin wrote:On Tuesday, 24 April 2012 at 10:29:52 UTC, Alex Rønne Petersen wrote:The point is just that: Right now I can write assembly that will work on GDC, LDC, and DMD on non-Windows. It will not work for DMD on Windows. Something has to change here.
If it doesn't work on Windows, it should be versioned out. What we have: http://dlang.org/version.html#PredefinedVersions - versions for LDC, GDC, DMD and Windows - all what you want.
Yes, I added them. :) You're missing the point. D is providing (or trying to provide) a standard inline assembler, but calling conventions are not standardized enough for it to be useful across compilers. If you're writing inline assembly because you *have* to, you don't just "version it out", you have to write different logic for different compilers, which is a maintenance nightmare.
This is exactly what C++ gets blamed for, yet most people fail to realize that the situation is common to all languages that generate native code.
No, it's totally the fault of C++. C++ failed to specify it, so everyone did something different. Then you get this very unfortunate mindset where everyone is so used to it, they don't find it unacceptable any more.
As far as I am aware this is the same in all languages. I am not aware of any ISO or ANSI language standard that specifies ABIs.The only reason it works out for C, is that the C ABI is actually the OS ABI, as such all C compilers tend to have a common ABI.
Not true. The ABI for Win32 is __stdcall, not C. Pascal and Fortran calling conventions were always well standardized, too.
For me this is the same, as all C compilers in Win32 are required to generate __stdcall entry points. Plus since C is nothing more than a glorified assembler, there is not much to speak about an ABI. In a way the operating system can be seen as the C language runtime (I am exaggerating a bit here). Taking your language's example, which two FORTRAN or Pascal compilers, in a given OS, are able to mix object or library files? I am just defending that I should be able to combine a mix of libraries compiled with DMD, LDC and GDC, without having to worry which is which. -- Paulo
Apr 25 2012
Am 24.04.2012 10:42, schrieb Alex Rønne Petersen:Writing portable code is hard enough as it is. Why do we have to have some random, D-specialized calling convention (only on Win32 and only in DMD)? The result of the current state of things is that extern(D) is essentially useless - it has completely different meanings across compilers. You cannot rely on it at all. If memory serves me right, both LDC and GDC just alias it to extern(C), but DMD insists on using this magical D calling convention on Win32. I'm not attacking the D ABI (name mangling) here, but I do think this calling convention needs to either go away, or be optional (i.e. as some extern() argument). We *have* to make extern(D) consistent across compilers, or we'll be no better than the mess that is C and C++; we're advertising a standard inline assembler with support for naked functions, but that support is useless if we don't have a consistent default calling convention.
Introducing a commen calling convention would be one approach. The other would be to templatize D's inline assembler?
Apr 25 2012
On 25-04-2012 19:44, mta`chrono wrote:Am 24.04.2012 10:42, schrieb Alex Rønne Petersen:Writing portable code is hard enough as it is. Why do we have to have some random, D-specialized calling convention (only on Win32 and only in DMD)? The result of the current state of things is that extern(D) is essentially useless - it has completely different meanings across compilers. You cannot rely on it at all. If memory serves me right, both LDC and GDC just alias it to extern(C), but DMD insists on using this magical D calling convention on Win32. I'm not attacking the D ABI (name mangling) here, but I do think this calling convention needs to either go away, or be optional (i.e. as some extern() argument). We *have* to make extern(D) consistent across compilers, or we'll be no better than the mess that is C and C++; we're advertising a standard inline assembler with support for naked functions, but that support is useless if we don't have a consistent default calling convention.
Introducing a commen calling convention would be one approach. The other would be to templatize D's inline assembler?
All the big compiler back ends are not realistically going to implement some random calling convention because we tell them to. -- - Alex
Apr 25 2012
On 25-04-2012 20:41, CTFE-4-the-win wrote:On Wednesday, 25 April 2012 at 17:51:45 UTC, Alex Rønne Petersen wrote:Introducing a commen calling convention would be one approach. The other would be to templatize D's inline assembler?
All the big compiler back ends are not realistically going to implement some random calling convention because we tell them to.
Hmmm... actually, only the symbols marked with 'export' would matter, we could have our own super optimized calling convention internally... no?
export doesn't currently do anything anywhere but on Windows, and it seems like this situation won't change for some time. -- - Alex
Apr 25 2012
On Wednesday, 25 April 2012 at 17:51:45 UTC, Alex Rønne Petersen wrote:Introducing a commen calling convention would be one approach. The other would be to templatize D's inline assembler?
All the big compiler back ends are not realistically going to implement some random calling convention because we tell them to.
Hmmm... actually, only the symbols marked with 'export' would matter, we could have our own super optimized calling convention internally... no?
Apr 25 2012
On Wednesday, 25 April 2012 at 17:44:03 UTC, mta`chrono wrote:The other would be to templatize D's inline assembler?
Templatize D's inline assembler? Do you mean using compiler intrinsics in place of raw inline assembly? David
Apr 25 2012
On 25-04-2012 20:48, David Nadlinger wrote:On Wednesday, 25 April 2012 at 17:44:03 UTC, mta`chrono wrote:The other would be to templatize D's inline assembler?
Templatize D's inline assembler? Do you mean using compiler intrinsics in place of raw inline assembly? David
Or perhaps use template arguments to carry info about the calling convention... I'm not sure what was meant either, but it seems like it would be a hack at best. -- - Alex
Apr 25 2012
On Wednesday, April 25, 2012 21:01:39 Alex Rønne Petersen wrote:export doesn't currently do anything anywhere but on Windows, and it seems like this situation won't change for some time.
And I hope that it never does. I hate export with a passion. - Jonathan M Davis
Apr 25 2012
On Wednesday, 25 April 2012 at 14:32:13 UTC, Alex Rønne Petersen wrote:You're missing the point. D is providing (or trying to provide) a standard inline assembler, but calling conventions are not standardized enough for it to be useful across compilers. If you're writing inline assembly because you *have* to, you don't just "version it out", you have to write different logic for different compilers, which is a maintenance nightmare.
Don't implement complex logic in assembly, extract it to D or C code.
Apr 26 2012









=?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= <xtzgzorex gmail.com> 