浏览代码

--- Merging r30164 into '.':
U compiler/powerpc/cgcpu.pas
U compiler/powerpc/cpubase.pas
U compiler/powerpc64/cgcpu.pas
U compiler/ncgutil.pas
U compiler/ppcgen/hlcgppc.pas
A tests/webtbs/tw27634.pp
--- Merging r30169 into '.':
U compiler/pdecobj.pas
A tests/test/tobjc43.pp
--- Merging r30177 into '.':
U compiler/pexpr.pas
A tests/test/tmacfunret2.pp
--- Merging r30178 into '.':
U compiler/options.pas
--- Merging r30204 into '.':
U compiler/i8086/cpupara.pas
--- Merging r30208 into '.':
U compiler/powerpc64/cpubase.pas
U compiler/powerpc64/itcpugas.pas
--- Merging r30209 into '.':
U rtl/linux/si_intf.inc
--- Merging r30219 into '.':
U compiler/powerpc64/cpupara.pas

# revisions: 30164,30169,30177,30178,30204,30208,30209,30219

git-svn-id: branches/fixes_3_0@30252 -

Jonas Maebe 10 年之前
父节点
当前提交
654cda7387

+ 0 - 9
compiler/i8086/cpupara.pas

@@ -286,15 +286,6 @@ unit cpupara;
           usedef:=p.returndef
           usedef:=p.returndef
         else
         else
           usedef:=forcetempdef;
           usedef:=forcetempdef;
-        { on darwin/i386, if a record has only one field and that field is a
-          single or double, it has to be returned like a single/double }
-        if (target_info.system in [system_i386_darwin,system_i386_iphonesim]) and
-           ((usedef.typ=recorddef) or
-            is_object(usedef)) and
-           tabstractrecordsymtable(tabstractrecorddef(usedef).symtable).has_single_field(sym) and
-           (sym.vardef.typ=floatdef) and
-           (tfloatdef(sym.vardef).floattype in [s32real,s64real]) then
-          usedef:=sym.vardef;
 
 
         handled:=set_common_funcretloc_info(p,usedef,retcgsize,result);
         handled:=set_common_funcretloc_info(p,usedef,retcgsize,result);
         { normally forcetempdef is passed straight through to
         { normally forcetempdef is passed straight through to

+ 0 - 12
compiler/ncgutil.pas

@@ -1294,18 +1294,6 @@ implementation
           the initialization and body is parsed because the refcounts are
           the initialization and body is parsed because the refcounts are
           incremented using the local copies }
           incremented using the local copies }
         current_procinfo.procdef.parast.SymList.ForEachCall(@copyvalueparas,list);
         current_procinfo.procdef.parast.SymList.ForEachCall(@copyvalueparas,list);
-{$ifdef powerpc}
-        { unget the register that contains the stack pointer before the procedure entry, }
-        { which is used to access the parameters in their original callee-side location  }
-        if (tppcprocinfo(current_procinfo).needs_frame_pointer) then
-          cg.a_reg_dealloc(list,NR_R12);
-{$endif powerpc}
-{$ifdef powerpc64}
-        { unget the register that contains the stack pointer before the procedure entry, }
-        { which is used to access the parameters in their original callee-side location  }
-        if (tppcprocinfo(current_procinfo).needs_frame_pointer) then
-          cg.a_reg_dealloc(list, NR_OLD_STACK_POINTER_REG);
-{$endif powerpc64}
         if not(po_assembler in current_procinfo.procdef.procoptions) then
         if not(po_assembler in current_procinfo.procdef.procoptions) then
           begin
           begin
             { initialize refcounted paras, and trash others. Needed here
             { initialize refcounted paras, and trash others. Needed here

+ 16 - 6
compiler/options.pas

@@ -804,6 +804,7 @@ function toption.ParseMacVersionMin(out minstr, emptystr: string; const compvarn
     temp,
     temp,
     compvarvalue: string[15];
     compvarvalue: string[15];
     i: longint;
     i: longint;
+    osx_minor_two_digits: boolean;
   begin
   begin
     minstr:=value;
     minstr:=value;
     emptystr:='';
     emptystr:='';
@@ -827,11 +828,16 @@ function toption.ParseMacVersionMin(out minstr, emptystr: string; const compvarn
     temp:=subval(i+1,2,i);
     temp:=subval(i+1,2,i);
     if temp='' then
     if temp='' then
       exit(false);
       exit(false);
-    { on Mac OS X, the minor version number is limited to 1 digit }
+    { on Mac OS X, the minor version number was originally limited to 1 digit;
+      with 10.10 the format changed and two digits were also supported; on iOS,
+      the minor version number always takes up two digits }
+    osx_minor_two_digits:=false;
     if not ios then
     if not ios then
       begin
       begin
-        if length(temp)<>1 then
-          exit(false);
+        { if the minor version number is two digits on OS X (the case since
+          OS X 10.10), we also have to add two digits for the patch level}
+        if length(temp)=2 then
+          osx_minor_two_digits:=true;
       end
       end
     { the minor version number always takes up two digits on iOS }
     { the minor version number always takes up two digits on iOS }
     else if length(temp)=1 then
     else if length(temp)=1 then
@@ -848,9 +854,12 @@ function toption.ParseMacVersionMin(out minstr, emptystr: string; const compvarn
         { there's only room for a single digit patch level in the version macro
         { there's only room for a single digit patch level in the version macro
           for Mac OS X. gcc sets it to zero if there are more digits, but that
           for Mac OS X. gcc sets it to zero if there are more digits, but that
           seems worse than clamping to 9 (don't declare as invalid like with
           seems worse than clamping to 9 (don't declare as invalid like with
-          minor version number, because there is a precedent like 10.4.11)
+          minor version number, because there is a precedent like 10.4.11).
+
+          As of OS X 10.10 there are two digits for the patch level
         }
         }
-        if not ios then
+        if not ios and
+           not osx_minor_two_digits then
           begin
           begin
             if length(temp)<>1 then
             if length(temp)<>1 then
               temp:='9';
               temp:='9';
@@ -866,7 +875,8 @@ function toption.ParseMacVersionMin(out minstr, emptystr: string; const compvarn
         if i<=length(value) then
         if i<=length(value) then
           exit(false);
           exit(false);
       end
       end
-    else if not ios then
+    else if not ios and
+       not osx_minor_two_digits then
       compvarvalue:=compvarvalue+'0'
       compvarvalue:=compvarvalue+'0'
     else
     else
       compvarvalue:=compvarvalue+'00';
       compvarvalue:=compvarvalue+'00';

+ 3 - 3
compiler/pdecobj.pas

@@ -679,9 +679,6 @@ implementation
               Message1(sym_e_formal_class_not_resolved,childof.objrealname^);
               Message1(sym_e_formal_class_not_resolved,childof.objrealname^);
           end;
           end;
 
 
-        { remove forward flag, is resolved }
-        exclude(current_structdef.objectoptions,oo_is_forward);
-
         if hasparentdefined then
         if hasparentdefined then
           begin
           begin
             if current_objectdef.objecttype in [odt_class,odt_objcclass,odt_objcprotocol,odt_javaclass,odt_interfacejava] then
             if current_objectdef.objecttype in [odt_class,odt_objcclass,odt_objcprotocol,odt_javaclass,odt_interfacejava] then
@@ -695,6 +692,9 @@ implementation
               end;
               end;
             consume(_RKLAMMER);
             consume(_RKLAMMER);
           end;
           end;
+
+        { remove forward flag, is resolved }
+        exclude(current_structdef.objectoptions,oo_is_forward);
       end;
       end;
 
 
     procedure parse_extended_type(helpertype:thelpertype);
     procedure parse_extended_type(helpertype:thelpertype);

+ 14 - 3
compiler/pexpr.pas

@@ -2938,10 +2938,21 @@ implementation
              _RETURN :
              _RETURN :
                 begin
                 begin
                   consume(_RETURN);
                   consume(_RETURN);
+                  p1:=nil;
                   if not(token in [_SEMICOLON,_ELSE,_END]) then
                   if not(token in [_SEMICOLON,_ELSE,_END]) then
-                    p1 := cexitnode.create(comp_expr(true,false))
-                  else
-                    p1 := cexitnode.create(nil);
+                    begin
+                      p1:=comp_expr(true,false);
+                      if not assigned(current_procinfo) or
+                         (current_procinfo.procdef.proctypeoption in [potype_constructor,potype_destructor]) or
+                         is_void(current_procinfo.procdef.returndef) then
+                        begin
+                          Message(parser_e_void_function);
+                          { recovery }
+                          p1.free;
+                          p1:=nil;
+                        end;
+                    end;
+                  p1 := cexitnode.create(p1);
                 end;
                 end;
              _INHERITED :
              _INHERITED :
                begin
                begin

+ 2 - 5
compiler/powerpc/cgcpu.pas

@@ -830,11 +830,8 @@ const
             usesgpr := firstregint <> 32;
             usesgpr := firstregint <> 32;
             usesfpr := firstregfpu <> 32;
             usesfpr := firstregfpu <> 32;
 
 
-             if (tppcprocinfo(current_procinfo).needs_frame_pointer) then
-              begin
-                a_reg_alloc(list,NR_R12);
-                list.concat(taicpu.op_reg_reg(A_MR,NR_R12,NR_STACK_POINTER_REG));
-              end;
+             if tppcprocinfo(current_procinfo).needs_frame_pointer then
+               list.concat(taicpu.op_reg_reg(A_MR,NR_OLD_STACK_POINTER_REG,NR_STACK_POINTER_REG));
           end;
           end;
 
 
         if usesfpr then
         if usesfpr then

+ 4 - 0
compiler/powerpc/cpubase.pas

@@ -291,6 +291,10 @@ uses
       {# Stack pointer register }
       {# Stack pointer register }
       NR_STACK_POINTER_REG = NR_R1;
       NR_STACK_POINTER_REG = NR_R1;
       RS_STACK_POINTER_REG = RS_R1;
       RS_STACK_POINTER_REG = RS_R1;
+      { old stack pointer register used during copying variables from the caller
+        stack frame
+      }
+      NR_OLD_STACK_POINTER_REG = NR_R12;
       {# Frame pointer register }
       {# Frame pointer register }
       NR_FRAME_POINTER_REG = NR_STACK_POINTER_REG;
       NR_FRAME_POINTER_REG = NR_STACK_POINTER_REG;
       RS_FRAME_POINTER_REG = RS_STACK_POINTER_REG;
       RS_FRAME_POINTER_REG = RS_STACK_POINTER_REG;

+ 1 - 3
compiler/powerpc64/cgcpu.pas

@@ -1193,10 +1193,8 @@ begin
   save_standard_registers;
   save_standard_registers;
 
 
   { save old stack frame pointer }
   { save old stack frame pointer }
-  if (tppcprocinfo(current_procinfo).needs_frame_pointer) then begin
-    a_reg_alloc(list, NR_OLD_STACK_POINTER_REG);
+  if (tppcprocinfo(current_procinfo).needs_frame_pointer) then
     list.concat(taicpu.op_reg_reg(A_MR, NR_OLD_STACK_POINTER_REG, NR_STACK_POINTER_REG));
     list.concat(taicpu.op_reg_reg(A_MR, NR_OLD_STACK_POINTER_REG, NR_STACK_POINTER_REG));
-  end;
 
 
   { create stack frame }
   { create stack frame }
   if (not nostackframe) and (localsize > 0) and
   if (not nostackframe) and (localsize > 0) and

+ 1 - 1
compiler/powerpc64/cpubase.pas

@@ -93,7 +93,7 @@ type
     A_CMPD, A_CMPDI, A_CMPLD, A_CMPLDI,
     A_CMPD, A_CMPDI, A_CMPLD, A_CMPLDI,
     A_SRDI, A_SRADI,
     A_SRDI, A_SRADI,
     A_SLDI,
     A_SLDI,
-    A_RLDCL, A_RLDICL,
+    A_RLDCL, A_RLDCL_, A_RLDICL, A_RLDICL_, A_RLDCR, A_RLDCR_, A_RLDICR, A_RLDICR_,
     A_DIVDU, A_DIVDU_, A_DIVD, A_DIVD_, A_MULLD, A_MULLD_, A_MULHD, A_MULHD_, A_SRAD, A_SLD, A_SRD,
     A_DIVDU, A_DIVDU_, A_DIVD, A_DIVD_, A_MULLD, A_MULLD_, A_MULHD, A_MULHD_, A_SRAD, A_SLD, A_SRD,
     A_DIVDUO_, A_DIVDO_,
     A_DIVDUO_, A_DIVDO_,
     A_LWA, A_LWAX, A_LWAUX,
     A_LWA, A_LWAX, A_LWAUX,

+ 2 - 1
compiler/powerpc64/cpupara.pas

@@ -177,7 +177,8 @@ begin
     procvardef,
     procvardef,
     recorddef:
     recorddef:
       result :=
       result :=
-        ((varspez = vs_const) and
+        (varspez = vs_const) and
+        (
          (
          (
           (not (calloption in [pocall_cdecl, pocall_cppdecl]) and
           (not (calloption in [pocall_cdecl, pocall_cppdecl]) and
           (def.size > 8))
           (def.size > 8))

+ 1 - 1
compiler/powerpc64/itcpugas.pas

@@ -83,7 +83,7 @@ const
     'cmpd', 'cmpdi', 'cmpld', 'cmpldi',
     'cmpd', 'cmpdi', 'cmpld', 'cmpldi',
     'srdi', 'sradi',
     'srdi', 'sradi',
     'sldi',
     'sldi',
-    'rldcl', 'rldicl',
+    'rldcl', 'rldcl_', 'rldicl', 'rldicl_', 'rldcr', 'rldcr_', 'rldicr', 'rldicr_',
     'divdu', 'divdu.', 'divd', 'divd.', 'mulld', 'mulld.', 'mulhd', 'mulhd.', 'srad', 'sld', 'srd',
     'divdu', 'divdu.', 'divd', 'divd.', 'mulld', 'mulld.', 'mulhd', 'mulhd.', 'srad', 'sld', 'srd',
     'divduo.', 'divdo.',
     'divduo.', 'divdo.',
     'lwa', 'lwax', 'lwaux',
     'lwa', 'lwax', 'lwaux',

+ 17 - 0
compiler/ppcgen/hlcgppc.pas

@@ -36,12 +36,15 @@ type
   thlcgppcgen = class(thlcg2ll)
   thlcgppcgen = class(thlcg2ll)
    protected
    protected
     procedure a_load_subsetref_regs_noindex(list: TAsmList; subsetsize: tdef; loadbitsize: byte; const sref: tsubsetreference; valuereg, extra_value_reg: tregister); override;
     procedure a_load_subsetref_regs_noindex(list: TAsmList; subsetsize: tdef; loadbitsize: byte; const sref: tsubsetreference; valuereg, extra_value_reg: tregister); override;
+   public
+    procedure gen_load_para_value(list: TAsmList); override;
   end;
   end;
 
 
 implementation
 implementation
 
 
   uses
   uses
     cpubase,globtype,
     cpubase,globtype,
+    procinfo,cpupi,
     symdef,defutil;
     symdef,defutil;
 
 
 { thlcgppc }
 { thlcgppc }
@@ -80,5 +83,19 @@ implementation
       a_load_subsetreg_subsetreg(list,subsetsize,subsetsize,fromsreg,tosreg);
       a_load_subsetreg_subsetreg(list,subsetsize,subsetsize,fromsreg,tosreg);
     end;
     end;
 
 
+
+  procedure thlcgppcgen.gen_load_para_value(list: TAsmList);
+    begin
+      { get the register that contains the stack pointer before the procedure
+        entry, which is used to access the parameters in their original
+        callee-side location }
+      if (tppcprocinfo(current_procinfo).needs_frame_pointer) then
+        getcpuregister(list,NR_OLD_STACK_POINTER_REG);
+      inherited;
+      { free it again }
+      if (tppcprocinfo(current_procinfo).needs_frame_pointer) then
+        ungetcpuregister(list,NR_OLD_STACK_POINTER_REG);
+    end;
+
 end.
 end.