Skip to content

Add symbols ASSEMBLER, ASMX86, ASMX64 and deprecate CPUASM, PUREPASCAL - #28

Open
Delphier wants to merge 1 commit into
project-jedi:masterfrom
Delphier:assembler
Open

Add symbols ASSEMBLER, ASMX86, ASMX64 and deprecate CPUASM, PUREPASCAL#28
Delphier wants to merge 1 commit into
project-jedi:masterfrom
Delphier:assembler

Conversation

@Delphier

@Delphier Delphier commented May 15, 2026

Copy link
Copy Markdown

This is preparatory work for WinARM64EC support.

Changes:

1. Use ASSEMBLER instead of CPUASM
ASSEMBLER is a predefined Delphi symbol with clearer semantics. By contrast, the "CPU" in CPUASM introduces ambiguity. Since CPUASM has never been used anywhere in JCL, this change has no impact on existing code.

2. Add new symbols ASMX86 and ASMX64
The inline assembly code currently in JCL only targets x86 and x64. With these two new symbols, conditional compilation between assembly and pure Pascal can be written as follows:

{$IF DEFINED(ASMX86)}
// x86 asm code
{$ELSEIF DEFINED(ASMX64)}
// x64 asm code
{$ELSE}
// pure pascal code
{$IFEND}

3. Deprecate PUREPASCAL
With the conditional compilation pattern above, there is no longer any need to define PUREPASCAL.
Additionally, PUREPASCAL is semantically the opposite of ASSEMBLER, and since ASSEMBLER is always active in FPC, {$IFDEF PUREPASCAL} will never match in FPC.
Currently JclLogic.pas and JclMath.pas make use of PUREPASCAL; if this PR is accepted, I will update them accordingly.

@Delphier

Copy link
Copy Markdown
Author

@davidm-ro Hi, does Oxygene have a predefined symbol called ASSEMBLER? I checked your documentation and it doesn't seem to be there, just wanted to confirm.

@obones

obones commented May 15, 2026

Copy link
Copy Markdown
Member

A few comments out the top of my head:

  1. The jedi.inc file is not just used by JCL and JVCL, it's being used by people directly in their own projects
  2. The PUREPASCAL define is the de factor standard for non assembly code, as can be seen in numerous places inside the RTL/VCL from Embarcadero itself. On top of that I personally dislike the inverted logic that IFNDEF introduces
  3. $IF may not be available to all the supported compilers hence the need to keep the cumulative approach:
    {$IFDEF X86ASM}
    {$ENDIF X86ASM}
    {$IFDEF X64ASM}
    {$ENDIF X64ASM}
    {$IFDEF PUREPASCAL}
    {$ENDIF PUREPASCAL}

@Delphier

Delphier commented May 15, 2026

Copy link
Copy Markdown
Author

The PUREPASCAL define is the de facto standard for non-assembly code, as can be seen in numerous places inside the RTL/VCL from Embarcadero itself.

  1. That may have been true when Delphi only supported Win32, but it isn't the case anymore.
  2. We also need to consider FPC/ARM and Oxygene.
  3. In the RTL/VCL, PUREPASCAL is only used internally within units, and it does not equate to IFNDEF ASSEMBLER — which is actually one of my reasons for opposing the use of PUREPASCAL here, since it would be inconsistent with how it is used in the VCL.

$IF may not be available to all the supported compilers

$IF has already been in use in Jedi.inc for a long time.

@Delphier

Delphier commented May 15, 2026

Copy link
Copy Markdown
Author

The jedi.inc file is not just used by JCL and JVCL, it's being used by people directly in their own projects

Maybe it’s time to start JCL v3 — supporting WinARM64EC really does require quite a few changes.

@Delphier Delphier changed the title Add symbols ASSEMBLER, X86ASM, X64ASM and remove CPUASM, PUREPASCAL Add symbols ASSEMBLER, X86ASM, X64ASM and deprecate CPUASM, PUREPASCAL May 17, 2026
@Delphier

Copy link
Copy Markdown
Author

For backward compatibility, and to handle future breaking changes (I'm planning to submit another change similar to #27), I've revised the strategy:

  • Keep the symbols that were to be removed, with their semantics unchanged.
  • But mark them as deprecated, with notes on the alternatives.
  • Move all deprecated symbols to the last section of the file for unified definition.

@boramis

boramis commented May 20, 2026

Copy link
Copy Markdown
Contributor

$IF has already been in use in Jedi.inc for a long time.

$IF was introduced in Delphi 6. All of the uses of it in jedi.inc are protected by either {$IFDEF CONDITIONALEXPRESSIONS} (the official way to check for its support) or {$IFDEF FPC}, so the current header does still work back through Delphi 1.

I avoided using {$IF ...} with my changes for precisely that reason, which I'll freely admit made things more awkward and is essentially the entire reason I introduced the CPUINTEL define. Personally I'd prefer the JCL break compatibility and just use $IF, even if jedi.inc maintains that compatibility for other vendors that rely on it. Delphi 6 was released in 2001; there can't be that many projects that (A) still use Delphi 5 or earlier, and (B) need an up-to-date JCL.

That said, I am willing to defer to @obones and rework my patches if there's an acceptable alternative.

@Delphier

Copy link
Copy Markdown
Author

In the JCL codebase, searching for {$IF reveals that $IF is already in use.

@boramis

boramis commented May 21, 2026

Copy link
Copy Markdown
Contributor

Sure enough, JclWin32.pas has an unprotected {$IF DECLARED} that Andreas added back in 2014. Given the number of units that use that directly or indirectly, and how long it's been in there, I think that's a solid argument that avoiding {$IF } is unnecessary. I'm in favor of your initial proposal.

@obones

obones commented May 21, 2026

Copy link
Copy Markdown
Member

@boramis, @Delphier, you are mixing up the JCL and this JEDI project. You have to understand that this project holds jedi.inc which is NOT used exclusively by the JCL or the JVCL but by lots of other projects and people around the world.
We have no control on those project but have a duty to respect them by not intentionally breaking functionality.

So no, stop mixing up those projects and please DO NOT use $IF in jedi.inc

@boramis

boramis commented May 21, 2026

Copy link
Copy Markdown
Contributor

@obones, it might have been better to discuss this in my jcl WinARM64EC merge request, but we’re not talking about using $IF in jedi.inc. We’re talking about the best way to handle it in the Jcl and what changes would be necessary in jedi.inc to support it. The $IF/$ELSEIF/$ELSE blocks @Delphier mentioned in his first post are how the code would look in the JCL where functions have asm and pure pascal implementations. The specific changes to jedi.inc would be adding the X86ASM/X64ASM defines and deprecation of some existing ones. You can see the changes he’s proposing for jedi.inc specifically in the commit.

@Delphier

Copy link
Copy Markdown
Author

Just to clarify a few points:

  • This PR does not break compatibility with Jedi.inc.
  • This PR never requested the use of $IF in Jedi.inc.
  • PUREPASCAL is considered deprecated and should no longer be used going forward.

As I mentioned from the very beginning, this is preparatory groundwork to support WinARM64EC — there is a clear reason behind the changes to Jedi.ini, and they are not arbitrary.

@Delphier

Copy link
Copy Markdown
Author

We could shift the discussion in a different direction: is there anything wrong with the PUREPASCAL symbol itself? Should it be deprecated? If we have an answer to that question, everything else becomes straightforward.

@obones

obones commented May 22, 2026

Copy link
Copy Markdown
Member

To me PUREPASCAL is a good convention because it offers a future proof fallback should a new CPU target come along. It allows code that works, even if not optimal, instead of simply breaking a library until a fix is found.
So no, it should not be deprecated, it should even be encouraged to be used for the fallback mechanism I described above.

@Delphier

Copy link
Copy Markdown
Author

The assembly support for the three compilers supported by Jedi is as follows:

  • FPC: Assembly syntax is supported on x86/x64/arm
  • Delphi: Supported on x86/x64, ARM assembly is not supported
  • Oxygene: Assembly is not supported at all

Under what circumstances is it still necessary to use {$IFDEF PUREPASCAL}? And if it is used, what are the consequences?

Conversely, if we define X86ASM/X64ASM, platforms and compilers that support assembly optimization execute the assembly code, while all others fall back to pure Pascal. This would offer better compatibility and be more intuitive.

If a contributor can provide ARM assembly, we would simply need to define an ARM64ASM symbol at that point.

@obones

obones commented May 22, 2026

Copy link
Copy Markdown
Member

Once again, you are assuming that the jedi.inc file is only used by the JCL and you are assuming that every assembly usage will be covered.
That is is not the case for both situations, which is why PUREPASCAL is needed and will be for a long time. There MUST be a fallback to be future proof, because no, there is no way that we will magically get immediate support for a new assembly that would be newly supported in the IDEs.

So I'm requiring that PUREPASCAL is not deprecated and even encouraged as a fallback solution. I don't want a $ELSE either because once a new target removes PUREPASCAL because it supports a new assembly variant, I want the compilation to immediately fail which would immediately show where the new assembly is missing. With the removal of PUREPASCAL, you need a $ELSE and so are basically making life much harder to identify the places where a new assembly is needed.

@Delphier

Copy link
Copy Markdown
Author

So I'd like to know, does Jedi.inc plan to support the ARM architecture in the future?

@Delphier

Copy link
Copy Markdown
Author

Jedi's PUREPASCAL is borrowed from VCL. However, VCL's PUREPASCAL is independently defined and used within each unit — you could say that the meaning of PUREPASCAL in each VCL unit is completely different.

It was a mistake from the very beginning.

@Delphier

Copy link
Copy Markdown
Author

Furthermore, regarding the breaking change you mentioned — this PR doesn't break anything; the semantics of PUREPASCAL have not changed. On the contrary, using {IFDEF PUREPASCAL} under a compiler that supports ARM would actually introduce breaking changes.

So it must be deprecated.

@boramis

boramis commented May 22, 2026

Copy link
Copy Markdown
Contributor

Under FPC, if someone were to start adding ARM inline ASM functions, what would be the structure for doing so? Say they wanted ARM versions of the routines in JclLogic.pas for performance but that Pascal versions (whether covered by PUREPASCAL or $ELSE) are sufficient everywhere else?

@boramis

boramis commented May 23, 2026

Copy link
Copy Markdown
Contributor

What about just including “PUREPASCAL” as just an informational comment in an $ELSE block? E.g.,

{$IF DEFINED(X86ASM)}
// x86 asm code
{$ELSEIF DEFINED(X64ASM)}
// x64 asm code
{$ELSE PUREPASCAL}
// pure pascal code
{$IFEND !PUREPASCAL}

As long as it was enforced as a coding standard it would still be easy to find them, even if the actually define is non-functional.

@boramis

boramis commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

@obones Can we please make some progress on this? If I need to completely rework my JCL pull request I’d like it to be when the code is still somewhat fresh in my mind.

@obones

obones commented Jun 29, 2026

Copy link
Copy Markdown
Member

I've seen the comment made by @Delphier on the JCL PR and am wondering what your thoughts are bout his suggestions.
They don't seem to require a change in jedi.inc but I'm not sure this is a valid approach anyway.

@boramis

boramis commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Are you referring to @Delphier's comments on my JCL pull request (linked in my previous comment here)? His suggestion was to split the pull request up and to change jedi.inc with this pull request. I'm not sure what you mean by "don't seem to require a change in jedi.inc?

Yes, we can make it work without changes to jedi.inc, but that would require all ASM blocks in the Jcl units to look like:

{$IF DEFINED(CPUASM) AND DEFINED(CPUX86)}
// 32-bit Intel Assembly
{$ELSEIF DEFINED(CPUASM) AND DEFINED(CPUX64)}
// 64-bit Intel Assembly
{$ELSE}
// Pascal
{$IFEND}

We can certainly do that, but it would be nice to have single symbols for DEFINED(CPUASM) AND DEFINED(CPUxxx), which is what he's trying to introduce here.

That also doesn't incorporate PUREPASCAL in any meaningful way, which I'm fine with. As @Delphier mentioned, the VCL/RTL units that use PUREPASCAL all do so at a local level, and that's how it's used in the Jcl units currently. If we do as above, then we can just replace JclLogic's {.$DEFINE PUREPASCAL} with {.$UNDEF CPUASM} and get the same behavior, which seems reasonable to me. I wouldn't want to have to do {$IF NOT DEFINED(PUREPASCAL) AND DEFINED(CPUASM) AND DEFINED(CPUX86)} before every asm block. As I said though, I would be ok with adding PUREPASCAL as a non-function comment to the {$ELSE} block to at least make them easier to find.

I also still think there's value in the changes I suggested in #27. Delphi defines CPUARM/CPUARM64 for their ARM targets but Free Pascal only defines CPUAARCH64, and Delphi defines CPUARM for DEFINED(ARM32) OR DEFINED(ARM64) but doesn't have an equivalent for Intel CPUs.

To summarize:

jedi.inc:

  1. Add CPUARM and CPUARM64 conditionals on FPC for Delphi compatibility
  2. Add CPUINTEL for DEFINED(CPUX86) OR DEFINED(CPUX64)
  3. Add X86ASM and X64ASM to mean DEFINED(CPUASM) AND DEFINED(CPUX86) and DEFINED(CPUASM) AND DEFINED(CPUX64)

JCL units:
Use {$IF} rather than complicated nesting of {$IFDEF} blocks.

@Delphier also suggested deprecating CPUASM in favor of ASSEMBLER which the compilers already define. I'm happy to go either way on that.

If we can get the changes above in, I'll work on pulling apart my JCL changes into smaller merge requests.

@Delphier

Delphier commented Jul 2, 2026

Copy link
Copy Markdown
Author

To clearly illustrate the necessity of adding the symbols X86ASM, X64ASM and deprecating PUREPASCAL, I have submitted JCL PR project-jedi/jcl#195, which completely removes the PUREPASCAL symbol from JCL, in hopes of accelerating the discussion on this issue.

@ronaldhoek

Copy link
Copy Markdown

Once again, you are assuming that the jedi.inc file is only used by the JCL and you are assuming that every assembly usage will be covered. That is is not the case for both situations, which is why PUREPASCAL is needed and will be for a long time. There MUST be a fallback to be future proof, because no, there is no way that we will magically get immediate support for a new assembly that would be newly supported in the IDEs.

So I'm requiring that PUREPASCAL is not deprecated and even encouraged as a fallback solution. I don't want a $ELSE either because once a new target removes PUREPASCAL because it supports a new assembly variant, I want the compilation to immediately fail which would immediately show where the new assembly is missing. With the removal of PUREPASCAL, you need a $ELSE and so are basically making life much harder to identify the places where a new assembly is needed.

I can see an advantage when looking at suggested modification to jedi.inc so this can be used in projects for Delphi/Pascal IDE's that support the syntax

{$IF DEFINED(X86ASM)}
// x86 asm code
{$ELSEIF DEFINED(X64ASM)}
// x64 asm code
{$ELSE}
// pure pascal code
{$IFEND}

BUT - as @obones is saying: the jedi.inc file is not solely used but JCL/JVCL and therefore backwards compatibility is a requirement!

This means:

  • no {$IF ... } statements
  • the need to at least also define the old defines like PUREPASCAL

@boramis

boramis commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

@ronaldhoek No one is asking to use {$IF DEFINED} in jedi.inc, only in the JCL, which already uses it.

@obones

obones commented Jul 3, 2026

Copy link
Copy Markdown
Member

Ok, fair enough, but should this and #27 both be merged, or only one of the two and if yes, which one?

@Delphier

Delphier commented Jul 3, 2026

Copy link
Copy Markdown
Author

@obones Does this mean you've accepted this patch?

A few open questions remain:

  • For symbol naming, should we use X86ASM/X64ASM or ASMX86/ASMX64? I'm currently leaning slightly toward the latter.
  • Is it necessary to define an X86ASM_OR_X64ASM symbol? It could shorten code like this: {$IF DEFINED(X86ASM) OR DEFINED(X64ASM)}
  • Code formatting: should we use DEFINED() or Defined(), and should and/or in $IF be uppercase or lowercase?

@obones

obones commented Jul 3, 2026

Copy link
Copy Markdown
Member

Well, yes, it seems legit like that.
To answer your questions:

$IF is NOT to be used inside jedi.inc I know for a fact that there are people using it with compilers that do not support this syntax.
For syntax, I'm more inclined to accept ASMX86, ASMX64, ASMARM32...
The OR symbol is something I'm not sure about, as it could open the door to creating all the possible combinations. But if we were to move that way, it would be ASMX86_OR_X64
Code formatting mandates that all of this is uppercased: IFDEF ASMX86 and because this is the "jedi" project, there is no question about DEFINED and the operators (OR / AND)

@Delphier

Delphier commented Jul 3, 2026

Copy link
Copy Markdown
Author

Great, I'll update the patch as soon as possible and do a final code review. I have no other questions.

@boramis

boramis commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Both #27 and #28 should be merged, since #28 doesn't do anything with the ARM symbols. @Delphier, if you're planning on submitting another related patch, might be best to just combine all three into a single pull request?

For ASMX86_OR_X64 the equivalent in my patch was CPUINTEL. I don't care what way we go with that, but IMO the two symbols should match. I picked CPUINTEL to be similar to CPUARM, though I could see CPUX86FAMILY or something similar instead since it's not specific to Intel® CPUs.

I don't think we need to consider XXX_OR_YYY symbols outside specific CPU families. ASMX86_OR_X64 is all x86-compatible instruction sets, and would be similar to ASMARM being ASSEMBLER_AND_CPUARM, but I don't think there's any reason to add other combinations like ASMX86_OR_ARM32 since there won't be significant overlap across CPU types.

@Delphier

Delphier commented Jul 3, 2026

Copy link
Copy Markdown
Author

@boramis

@Delphier Delphier changed the title Add symbols ASSEMBLER, X86ASM, X64ASM and deprecate CPUASM, PUREPASCAL Add symbols ASSEMBLER, ASMX86, ASMX64 and deprecate CPUASM, PUREPASCAL Jul 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants