Sfoglia il codice sorgente

* correctly handle X86_64_X87UP_CLASS getting merged with another class and
becoming X86_64_SSE_CLASS/X86_64_INTEGER_CLASS/... This is not defined in
the ABI because there sizeof(extended)=16 and hence the class of the upper
eightbyte of the extended value can never be merged with the class of
another field (except in a union, but then the class of the lower
eightbyte will also be overwritten).

Handle it the same as when the lower eightbyte class of an extended in an
aggregate gets changed into something else: pass everything in memory
(part of mantis #26993)

git-svn-id: trunk@28984 -

Jonas Maebe 10 anni fa
parent
commit
6712954607
3 ha cambiato i file con 65 aggiunte e 0 eliminazioni
  1. 1 0
      .gitattributes
  2. 14 0
      compiler/x86_64/cpupara.pas
  3. 50 0
      tests/webtbs/tw26993a.pp

+ 1 - 0
.gitattributes

@@ -14111,6 +14111,7 @@ tests/webtbs/tw2690.pp svneol=native#text/plain
 tests/webtbs/tw2691.pp svneol=native#text/plain
 tests/webtbs/tw2696.pp svneol=native#text/plain
 tests/webtbs/tw26976.pp svneol=native#text/plain
+tests/webtbs/tw26993a.pp svneol=native#text/plain
 tests/webtbs/tw2702.pp svneol=native#text/plain
 tests/webtbs/tw2703.pp svneol=native#text/plain
 tests/webtbs/tw2704.pp svneol=native#text/plain

+ 14 - 0
compiler/x86_64/cpupara.pas

@@ -407,6 +407,20 @@ unit cpupara;
             if (classes[i].typ=X86_64_X87UP_CLASS) and
                (classes[i-1].typ<>X86_64_X87_CLASS) then
               exit(0);
+
+            (* FPC addition: because we store an extended in 10 bytes, the
+               X86_64_X87UP_CLASS can be replaced with e.g. INTEGER if an
+               extended is followed by e.g. an array [0..5] of byte -> we also
+               have to check whether each X86_64_X87_CLASS is followed by
+               X86_64_X87UP_CLASS -- if not, pass in memory
+
+               This cannot happen in the original ABI, because there
+               sizeof(extended) = 16 and hence nothing can be merged with
+               X86_64_X87UP_CLASS and change it into something else *)
+            if (classes[i].typ=X86_64_X87_CLASS) and
+               ((i=(words-1)) or
+                (classes[i+1].typ<>X86_64_X87UP_CLASS)) then
+              exit(0);
           end;
 
           { FIXME: in case a record contains empty padding space, e.g. a

+ 50 - 0
tests/webtbs/tw26993a.pp

@@ -0,0 +1,50 @@
+program tw26993a;
+
+{$mode delphi}
+
+uses
+  Classes, SysUtils;
+
+type
+
+  { TExtendedTestCase }
+
+  TExtendedTestCase = record
+  private
+    FValue: extended;
+    dummy: array[0..5] of byte;
+  public
+    property Value: extended read FValue write FValue;
+    class operator Add(v1, v2: TExtendedTestCase): TExtendedTestCase;
+    class operator Multiply(v1, v2: TExtendedTestCase): TExtendedTestCase;
+  end;
+
+
+{ TExtendedTestCase }
+
+class operator TExtendedTestCase.Add(v1, v2: TExtendedTestCase): TExtendedTestCase;
+begin
+  Result.Value := v1.Value + v2.Value;
+end;
+
+class operator TExtendedTestCase.Multiply(v1, v2: TExtendedTestCase):
+TExtendedTestCase;
+begin
+  Result.Value := v1.Value * v2.Value;
+end;
+
+var
+  e1,e2,e3: textendedtestcase;
+begin
+  e1.fvalue:=2.0;
+  e2.fvalue:=3.0;
+  e3:=e1+e2;
+  if (e3*e2).fvalue<>15.0 then
+    halt(1);
+
+end.
+
+
+
+
+