Browse Source

* support loading longint in dx:ax when using the 'register' calling convention
on i8086. This is compatible with Borland C++ 3.1's _fastcall. Note that
passing parameters in multiple registers is not yet implemented, so using this
will cause internal errors, but these will be fixed later (and the 'register'
calling convention was never officially supported on i8086).

git-svn-id: trunk@38784 -

nickysn 7 years ago
parent
commit
a73aabcc39
1 changed files with 28 additions and 6 deletions
  1. 28 6
      compiler/i8086/cpupara.pas

+ 28 - 6
compiler/i8086/cpupara.pas

@@ -591,19 +591,41 @@ unit cpupara;
                     hp.paraloc[side].Alignment:=paraalign;
                     hp.paraloc[side].Alignment:=paraalign;
                     hp.paraloc[side].def:=paradef;
                     hp.paraloc[side].def:=paradef;
                     {
                     {
-                      EAX
-                      EDX
-                      ECX
+                      AX
+                      DX
+                      BX
                       Stack
                       Stack
                       Stack
                       Stack
 
 
-                      64bit values,floats,arrays and records are always
-                      on the stack.
+                      32/64bit values,far pointers,floats,arrays and records are
+                      always on the stack. The only exception is that Longints
+                      (but not far pointers) can be passed in DX:AX if these
+                      registers are unallocated.
 
 
                       In case of po_delphi_nested_cc, the parent frame pointer
                       In case of po_delphi_nested_cc, the parent frame pointer
                       is also always passed on the stack.
                       is also always passed on the stack.
                     }
                     }
-                    if (parareg<=high(parasupregs)) and
+                    if (parareg=low(parasupregs)) and
+                       (paralen=4) and
+                       (hp.vardef.typ=orddef) then
+                      begin
+                        if pass=1 then
+                          begin
+                            paraloc:=hp.paraloc[side].add_location;
+                            paraloc^.size:=OS_16;
+                            paraloc^.def:=paradef;
+                            paraloc^.loc:=LOC_REGISTER;
+                            paraloc^.register:=newreg(R_INTREGISTER,parasupregs[parareg],R_SUBW);
+                            inc(parareg);
+                            paraloc:=hp.paraloc[side].add_location;
+                            paraloc^.size:=OS_16;
+                            paraloc^.def:=paradef;
+                            paraloc^.loc:=LOC_REGISTER;
+                            paraloc^.register:=newreg(R_INTREGISTER,parasupregs[parareg],R_SUBW);
+                            inc(parareg);
+                          end;
+                      end
+                    else if (parareg<=high(parasupregs)) and
                        (paralen<=sizeof(aint)) and
                        (paralen<=sizeof(aint)) and
                        (not(hp.vardef.typ in [floatdef,recorddef,arraydef]) or
                        (not(hp.vardef.typ in [floatdef,recorddef,arraydef]) or
                         pushaddr or
                         pushaddr or