View Issue Details

IDProjectCategoryView StatusLast Update
0015691FPCCompilerpublic2011-08-29 04:10
ReporterRadek Assigned To 
PrioritynormalSeveritymajorReproducibilitysometimes
Status newResolutionopen 
Product Version2.4.0 
Summary0015691: Wrong order of arguments in register calling convention functions
Descriptionvar
  First,
  Second:Boolean;

procedure Test1(A,B,C:Byte); register;
assembler;asm
        XOR AH,AH
        CMP AL,1
        JNE @@1
        CMP DL,2
        JNE @@1
        CMP CL,3
        JNE @@1
        MOV AH,1
@@1: MOV First,AH
end;

// @Result is in eax instead in ecx
function Test2(A,B:Byte):ShortString; register;
assembler;asm
        XOR AH,AH
        CMP AL,1
        JNE @@1
        CMP DL,2
        JNE @@1
        MOV AH,1
@@1: MOV Second,AH
end;

var
  S:ShortString;
begin
  Test1(1,2,3);
  WriteLn('Valid: ',First);
  S:=Test2(1,2);
  WriteLn('Valid: ',Second);
end.
TagsNo tags attached.
Fixed in Revision
FPCOldBugId
FPCTarget
Attached Files

Relationships

related to 0020075 closedFlorian Wrong register values in assembly methods due to implicit exceptions 
has duplicate 0016697 closedJonas Maebe Small records are passed incompatible to Delphi 

Activities

Florian

2010-02-05 21:58

administrator   ~0034254

I just checked with 2.4.0 and get two times true?

Radek

2010-02-05 23:52

reporter   ~0034255

Last edited: 2010-02-06 01:21

Free Pascal Compiler version 2.4.0 [2009/12/16] for i386

When option -TGo32V2

.globl P$PROGRAM_TEST2$BYTE$BYTE$$SHORTSTRING
P$PROGRAM_TEST2$BYTE$BYTE$$SHORTSTRING:
# Temps allocated between ebp+0 and ebp+0
# [28] end;
        pushl %ebp
        movl %esp,%ebp
# Var A located in register dl
# Var B located in register cl
# Var $result located in register eax
# [21] XOR AH,AH
        xorb %ah,%ah
# [22] CMP AL,1
        cmpb $1,%al
# [23] JNE @@1
        jne .Lj8
# [24] CMP DL,2
        cmpb $2,%dl
# [25] JNE @@1
        jne .Lj8
# [26] MOV AH,1
        movb $1,%ah
.Lj8:
# [27] @@1: MOV Second,AH
        movb %ah,U_P$PROGRAM_SECOND
        leave
        ret

Jonas Maebe

2010-02-10 18:25

manager   ~0034366

Is there a detailed description of register calling convention as implemented by Delphi somewhere? The Delphi documentation says nothing about how function results are passed, about the relative order of self/function result, etc.

We already made FPC incompatible with itself once in the past by changing the "register" calling convention to be more Delphi compatible, apparently we may have to do it again, and it would sad if we'd have to do it yet again in the future (because assembler code written for FPC may already depend on the way the parameters are currently passed in FPC).

Sergei Gorelkin

2010-03-12 20:21

developer   ~0035398

I guess that Delphi simply puts the result into a hidden out-parameter, which is passed in ecx (third parameter).

Jonas Maebe

2010-03-12 20:35

manager   ~0035402

> I guess that Delphi simply puts the result into a hidden out-parameter

It certainly does. That's what FPC also does.

> which is passed in ecx (third parameter).

But this is the problem. According to all documentation I've seen, the hidden result parameter is supposed to be first one (and that's what FPC does). And afaik, in most cases it's indeed also the first parameter in Delphi. I don't know when it is the last instead of the first like in this case. And I don't know whether there are more special cases.

Graeme Geldenhuys

2010-03-15 11:20

reporter   ~0035544

Please see the following URL for more information.

http://docwiki.embarcadero.com/RADStudio/en/Program_Control

Luiz Americo

2011-08-28 01:00

developer   ~0051191

I stumbled with a similar problem in a real case (method TBaseVirtualTree.PackArrayAsm : line 13187 of http://lazarus-ccr.svn.sourceforge.net/viewvc/lazarus-ccr/components/virtualtreeview-new/branches/4.8/VirtualTrees.pas?revision=1846&view=markup )

These are my findings:

Under Delphi (tested with the CPU window - confirming comments in code):
Self = EAX
TheArray = EDX
Count = ECX

Under Lazarus/fpc:
Due to bug 20075 the registers are invalid at all but even disabling implicit exceptions the order is different from Delphi (see attachments in bug 20075 - the order is the same as in the real VTV code):

Self = EAX
TheArray = EBP+8
Count = EDX
ECX = ??

Sergei Gorelkin

2011-08-28 10:56

developer   ~0051195

@Luiz: it is probably a separate issue, not related to parameter ordering. Delphi passes dynamic arrays in registers (because it is actually a pointer and fits into register perfectly well), FPC does not.

Luiz Americo

2011-08-29 04:10

developer   ~0051227

@Sergei

Thanks. You are right changing TheArray type from a dynamic array to Integer the order is equal between delphi and fpc:
Self = EAX
TheArray = EDX
Count = ECX

Issue History

Date Modified Username Field Change
2010-02-05 19:50 Radek New Issue
2010-02-05 21:58 Florian Note Added: 0034254
2010-02-05 21:58 Florian Status new => feedback
2010-02-05 23:52 Radek Note Added: 0034255
2010-02-06 00:00 Radek Note Edited: 0034255
2010-02-06 00:37 Radek Note Edited: 0034255
2010-02-06 01:21 Radek Note Edited: 0034255
2010-02-10 18:25 Jonas Maebe Note Added: 0034366
2010-03-12 20:21 Sergei Gorelkin Note Added: 0035398
2010-03-12 20:35 Jonas Maebe Note Added: 0035402
2010-03-15 11:20 Graeme Geldenhuys Note Added: 0035544
2010-06-11 14:15 Jonas Maebe Relationship added has duplicate 0016697
2010-06-11 16:39 Jonas Maebe Status feedback => new
2011-08-28 01:00 Luiz Americo Note Added: 0051191
2011-08-28 10:12 Marco van de Voort Relationship added related to 0020075
2011-08-28 10:56 Sergei Gorelkin Note Added: 0051195
2011-08-29 04:10 Luiz Americo Note Added: 0051227