Skip to main content
deleted 2 characters in body
Source Link
Glorfindel
  • 3.2k
  • 6
  • 28
  • 34

Raymond Chen put together a history of calling conventions here. While he doesn't touch on Clarion, he does touch on Fastcall, which while not the same as Clarion does use more of a register-based approach.

He has this to say:

Fastcall (__fastcall)

The Fastcall calling convention passes the first parameter in the DX register and the second in the CX register (I think). Whether this was actually faster depended on your call usage. It was generally faster since parameters passed in registers do not need to be spilled to the stack, then reloaded by the callee. On the other hand, if significant computation occurs between the computation of the first and second parameters, the caller has to spill it anyway. To add insult to injury, the called function often spilled the register into memory because it needed to spare the register for something else, which in the "significant computation between the first two parameters" case means that you get a double-spill. Ouch!

Consequently, __fastcall was typically faster only for short leaf functions, and even then it might not be.

I believe the criticism applied here is still relevant - Clarion is likely faster for certain types of calls, but not others.

That being said, your points about the register usage are quite valid. While you did not want to consider x64 in the scope of your question, the pattern discussed later in that series for Itaniumlater in that series for Itanium might interest you!

Raymond Chen put together a history of calling conventions here. While he doesn't touch on Clarion, he does touch on Fastcall, which while not the same as Clarion does use more of a register-based approach.

He has this to say:

Fastcall (__fastcall)

The Fastcall calling convention passes the first parameter in the DX register and the second in the CX register (I think). Whether this was actually faster depended on your call usage. It was generally faster since parameters passed in registers do not need to be spilled to the stack, then reloaded by the callee. On the other hand, if significant computation occurs between the computation of the first and second parameters, the caller has to spill it anyway. To add insult to injury, the called function often spilled the register into memory because it needed to spare the register for something else, which in the "significant computation between the first two parameters" case means that you get a double-spill. Ouch!

Consequently, __fastcall was typically faster only for short leaf functions, and even then it might not be.

I believe the criticism applied here is still relevant - Clarion is likely faster for certain types of calls, but not others.

That being said, your points about the register usage are quite valid. While you did not want to consider x64 in the scope of your question, the pattern discussed later in that series for Itanium might interest you!

Raymond Chen put together a history of calling conventions here. While he doesn't touch on Clarion, he does touch on Fastcall, which while not the same as Clarion does use more of a register-based approach.

He has this to say:

Fastcall (__fastcall)

The Fastcall calling convention passes the first parameter in the DX register and the second in the CX register (I think). Whether this was actually faster depended on your call usage. It was generally faster since parameters passed in registers do not need to be spilled to the stack, then reloaded by the callee. On the other hand, if significant computation occurs between the computation of the first and second parameters, the caller has to spill it anyway. To add insult to injury, the called function often spilled the register into memory because it needed to spare the register for something else, which in the "significant computation between the first two parameters" case means that you get a double-spill. Ouch!

Consequently, __fastcall was typically faster only for short leaf functions, and even then it might not be.

I believe the criticism applied here is still relevant - Clarion is likely faster for certain types of calls, but not others.

That being said, your points about the register usage are quite valid. While you did not want to consider x64 in the scope of your question, the pattern discussed later in that series for Itanium might interest you!

Raymond Chen put together a history of calling conventionshistory of calling conventions here. While he doesn't touch on Clarion, he does touch on Fastcall, which while not the same as Clarion does use more of a register-based approach.

He has this to say:

Fastcall (__fastcall)

The Fastcall calling convention passes the first parameter in the DX register and the second in the CX register (I think). Whether this was actually faster depended on your call usage. It was generally faster since parameters passed in registers do not need to be spilled to the stack, then reloaded by the callee. On the other hand, if significant computation occurs between the computation of the first and second parameters, the caller has to spill it anyway. To add insult to injury, the called function often spilled the register into memory because it needed to spare the register for something else, which in the "significant computation between the first two parameters" case means that you get a double-spill. Ouch!

Consequently, __fastcall was typically faster only for short leaf functions, and even then it might not be.

I believe the criticism applied here is still relevant - Clarion is likely faster for certain types of calls, but not others.

That being said, your points about the register usage are quite valid. While you did not want to consider x64 in the scope of your question, the pattern discussed later in that series for Itanium might interest you!

Raymond Chen put together a history of calling conventions here. While he doesn't touch on Clarion, he does touch on Fastcall, which while not the same as Clarion does use more of a register-based approach.

He has this to say:

Fastcall (__fastcall)

The Fastcall calling convention passes the first parameter in the DX register and the second in the CX register (I think). Whether this was actually faster depended on your call usage. It was generally faster since parameters passed in registers do not need to be spilled to the stack, then reloaded by the callee. On the other hand, if significant computation occurs between the computation of the first and second parameters, the caller has to spill it anyway. To add insult to injury, the called function often spilled the register into memory because it needed to spare the register for something else, which in the "significant computation between the first two parameters" case means that you get a double-spill. Ouch!

Consequently, __fastcall was typically faster only for short leaf functions, and even then it might not be.

I believe the criticism applied here is still relevant - Clarion is likely faster for certain types of calls, but not others.

That being said, your points about the register usage are quite valid. While you did not want to consider x64 in the scope of your question, the pattern discussed later in that series for Itanium might interest you!

Raymond Chen put together a history of calling conventions here. While he doesn't touch on Clarion, he does touch on Fastcall, which while not the same as Clarion does use more of a register-based approach.

He has this to say:

Fastcall (__fastcall)

The Fastcall calling convention passes the first parameter in the DX register and the second in the CX register (I think). Whether this was actually faster depended on your call usage. It was generally faster since parameters passed in registers do not need to be spilled to the stack, then reloaded by the callee. On the other hand, if significant computation occurs between the computation of the first and second parameters, the caller has to spill it anyway. To add insult to injury, the called function often spilled the register into memory because it needed to spare the register for something else, which in the "significant computation between the first two parameters" case means that you get a double-spill. Ouch!

Consequently, __fastcall was typically faster only for short leaf functions, and even then it might not be.

I believe the criticism applied here is still relevant - Clarion is likely faster for certain types of calls, but not others.

That being said, your points about the register usage are quite valid. While you did not want to consider x64 in the scope of your question, the pattern discussed later in that series for Itanium might interest you!

Source Link
J Trana
  • 1.4k
  • 9
  • 17

Raymond Chen put together a history of calling conventions here. While he doesn't touch on Clarion, he does touch on Fastcall, which while not the same as Clarion does use more of a register-based approach.

He has this to say:

Fastcall (__fastcall)

The Fastcall calling convention passes the first parameter in the DX register and the second in the CX register (I think). Whether this was actually faster depended on your call usage. It was generally faster since parameters passed in registers do not need to be spilled to the stack, then reloaded by the callee. On the other hand, if significant computation occurs between the computation of the first and second parameters, the caller has to spill it anyway. To add insult to injury, the called function often spilled the register into memory because it needed to spare the register for something else, which in the "significant computation between the first two parameters" case means that you get a double-spill. Ouch!

Consequently, __fastcall was typically faster only for short leaf functions, and even then it might not be.

I believe the criticism applied here is still relevant - Clarion is likely faster for certain types of calls, but not others.

That being said, your points about the register usage are quite valid. While you did not want to consider x64 in the scope of your question, the pattern discussed later in that series for Itanium might interest you!