New page '__THISCALL'

Forum for discussion about the documentation project.
Post Reply
fxm
Moderator
Posts: 12083
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

New page '__THISCALL'

Post by fxm »

@Jeff,

There is a typo on the link name of the new page '__THISCALL':
- KeyPgThicsall instead of KeyPgThiscall.

After fixing for the page '__THISCALL':
- its link name (I do not have the rights to do so),
- and also the link to the 'This' page ([[KeyThis|This]] -> [[KeyPgThis|This]]),
- and also the name of the example file (.../thicall.bas -> .../thiscall.bas),
then only one link to this so fixed '__THISCALL' page will need to be corrected in another page:
- in the CatPgProcedures page (value="KeyPgThicsall|Thiscall" -> value="KeyPgThiscall|Thiscall").
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: New page '__THISCALL'

Post by coderJeff »

Thanks, fxm. My errors you listed are corrected now.
fxm
Moderator
Posts: 12083
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: New page '__THISCALL'

Post by fxm »

I did not previously create this page myself because I had no information or even knowledge on the subject, and in addition the '__THISCALL' name syntax rather made me think of an internal feature command.
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: New page '__THISCALL'

Post by coderJeff »

It's sort of internal, and developmental for sure. If the feature is ever finished (for win 32-bit gas), then should not need to explicitly specify it. But just needed something to work with in code while under development, which is why I left on the '__' double underscore prefix. In theory it should seldom if ever appear in user code, so will probably have that name forever.
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: New page '__THISCALL'

Post by coderJeff »

fbc 1.10.0 has new updates to the __THISCALL calling convention.

__THISCALL is a calling convention for x86 targets where the first integral argument is passed in the ECX register instead of on the stack. All other arguments are passed right to left and callee cleans up the stack (like STDCALL).

On win32 x86, mingw+gcc will use __THISCALL as the default calling convention for non-static member procedures in classes passing the hidden 'this' parameter by ECX register instead of pushing to the stack.

As of fbc 1.10.0, default calling convention on win32 x86 inside an extern "c++" block for non-static member procedures is __THISCALL.

__THISCALL can be explicitly specified for normal procedures and static member procedures to override the default calling convention.
Other calling conventions (CDECL/STDCALL/etc) can be explicitly specified to override the default __THISCALL calling convention on non-static member procedures.
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: New page '__THISCALL'

Post by coderJeff »

fxm wrote: Oct 22, 2022 21:05
coderJeff wrote: Oct 22, 2022 19:01 - can now also define procedures in fbc with the __thiscall calling convention (not just declare & call as before - I added the missing code generation to gas backend).
_thiscall must be only used at the member procedure declaration level, or also at the member procedure definition level if it exists ?
- It can be specified at both the declaration and the definition.
- The calling convention of the declaration and definition need to match - could be cdecl/stdcall/pascal/__thiscall
- If inside extern "c++" and also on win32 / x86, and it's a non-static member procedure, and no other calling convention is given, the default is __thiscall

Code: Select all

extern "c++"
	type T extends object
		declare constructor() '' __thiscall is default
	end type

	constructor T()  '' __thiscall is default
	end constructor	
end extern
- If definition is outside the extern "c++" block, then __thiscall is requied on the defintion (if the default for the non-static member procedure was __thiscall

Code: Select all

extern "c++"
	type T extends object
		declare constructor() '' __thiscall is default
	end type

end extern

constructor T __thiscall()
end constructor	
fxm
Moderator
Posts: 12083
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: New page '__THISCALL'

Post by fxm »

Documentation page updated:
- KeyPgThiscall → fxm [updated for fbc 1.10.0]
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: New page '__THISCALL'

Post by coderJeff »

Here are examples (for x86) to show low level cdecl/stdcall/pascall/__thiscall differences:

CDECL - Arguments pushed right to left, caller clean-up

Code: Select all

function Sub2LongCdecl naked CDECL _
  ( byval a as long, byval b as long  ) as long
  asm
    mov eax, dword ptr [esp+4]   '' argument 1 on stack
    sub eax, dword ptr [esp+8]   '' argument 2 on stack
    ret                          '' caller cleans up stack
  end asm                        '' result returned in EAX 
end function

dim as long a = 17, b = 3

'' CDECL - Arguments pushed right to left, caller clean-up
''    push [b]
''    push [a]
''    call Sub2LongCdecl
''    add esp, 8

print Sub2LongCdecl( a, b )
STDCALL - Arguments pushed right to left, callee clean-up

Code: Select all

function Sub2LongStdcall naked STDCALL _
  ( byval a as long, byval b as long  ) as long
  asm
    mov eax, dword ptr [esp+4]   '' argument 1 on stack
    sub eax, dword ptr [esp+8]   '' argument 2 on stack
    ret 8                        '' callee cleans up stack
  end asm                        '' result returned in EAX 
end function

dim as long a = 17, b = 3

'' STDCALL - Arguments pushed right to left, callee clean-up
''    push [b]
''    push [a]
''    call Sub2LongStdCall

print Sub2LongStdCall( a, b )
PASCAL - Arguments pushed left to right, callee clean-up

Code: Select all

function Sub2LongPascal naked PASCAL _
  ( byval a as long, byval b as long  ) as long
  asm
    mov eax, dword ptr [esp+8]   '' argument 1 on stack
    sub eax, dword ptr [esp+4]   '' argument 2 on stack
    ret 8                        '' callee cleans up stack
  end asm                        '' result returned in EAX 
end function

dim as long a = 17, b = 3

'' PASCAL - Arguments pushed left to right, callee clean-up
''    push [a]
''    push [b]
''    call Sub2LongPascal

print Sub2LongPascal( a, b )
THISCALL - Arguments pushed right to left, left-most argument in ECX
WIN32 x86: callee clean-up

Code: Select all

#cmdline "-target win32"

function Sub2LongThiscall naked __THISCALL _
  ( byval a as long, byval b as long  ) as long
  asm
    mov eax, ecx                 '' argument 1 in ECX 
    sub eax, dword ptr [esp+4]   '' argument 2 on stack
    ret 4                        '' callee cleans up stack
  end asm                        '' result returned in EAX 
end function

dim as long a = 17, b = 3

'' THISCALL - Arguments pushed right to left, left-most argument in ECX, callee clean-up
''    push [b]
''    mov ecx, [a]
''    call Sub2LongThiscall

print Sub2LongThiscall( a, b )
Linux x86: caller clean-up

Code: Select all

#cmdline "-target linux"

function Sub2LongThiscall naked __THISCALL _
  ( byval a as long, byval b as long  ) as long
  asm
    mov eax, ecx                 '' argument 1 in ECX 
    sub eax, dword ptr [esp+4]   '' argument 2 on stack
    ret                          '' caller cleans up stack
  end asm                        '' result returned in EAX 
end function

dim as long a = 17, b = 3

'' THISCALL - Arguments pushed right to left, left-most argument in ECX, caller clean-up
''    push [b]
''    mov ecx, [a]
''    call Sub2LongThiscall
''    add esp, 4

print Sub2LongThiscall( a, b )
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: New page '__THISCALL'

Post by coderJeff »

Primary purpose of this feature was to provide ABI compatibility for mingw+gcc. However, gcc allows thiscall calling convention as an extension for normal procedures and other targets / platforms, and the rules may be inconsistent across targets / platforms. I don't know all the rules and I have not researched or tested this feature and all targets.

Potential issues and bugs:
  • Confirmation that __thiscall is completely ignored on 64 bit targets
  • Determine any other 32-bit targets that should ignore or support __thiscall? ARM? freebsd x86? etc...
  • VARARGS - functions taking a variable number of arguments
    • fbc should not allow on win32 x86
    • if not allowed, then automatically fallback to CDECL/STDCALL? or a warning?
    • supported on other x86 targets? then that will need to be added to gas backend
  • handling of non-integral left most argument - what is behaviour / error if argument is not byte/short/long?
  • REDIM and ERASE expect object contructor/destructor to be CDECL, so using arrays is not possible if ctor/dtor is __THISCALL
  • more testing, at least on all the targets that make up the 'offical' release binaries
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: New page '__THISCALL'

Post by coderJeff »

I made a change that feels like should be more user friendly when dealing with calling conventions:
- calling convention of the procedure definition is implied by the declaration
- if there is no declaration, then usual defaults apply.
coderJeff wrote: Oct 23, 2022 0:05 - If definition is outside the extern "c++" block, then __thiscall is required optional on the definition (if the default for the non-static member procedure was __thiscall

Code: Select all

extern "c++"
	type T extends object
		declare constructor() '' __thiscall is default
	end type

end extern

constructor T() '' __thiscall is implied by declaration.
end constructor	
This will be same behaviour for cdecl/pascal/stdcall in declarations making the calling convention on the definition optional.

A simple example (which would previously fail to compile on fbc 1.09 windows):

Code: Select all

declare sub proc cdecl ()	

sub proc () '' cdecl implied by declaration, regardless of current target
end sub
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: New page '__THISCALL'

Post by D.J.Peters »

12 years to late :-) but better as never.
I remenber if I wrote the FreeBASIC Steinberg ASIO interface for 32-bit Windows the magic was putting the this pointer in ECX register instead pushing it on the stack.
viewtopic.php?p=148306#p148306

Joshy
Post Reply