Ver Fonte

* alignmentinfo record added
* -Oa argument supports more alignment settings that can be specified
per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
required alignment and the maximum usefull alignment. The final
alignment will be choosen per variable size dependent on these
settings

peter há 24 anos atrás
pai
commit
b10e754536

+ 16 - 2
compiler/assemble.pas

@@ -1116,7 +1116,12 @@ Implementation
 {$endif GDB}
            case hp.typ of
              ait_align :
-               objectdata.writebytes(Tai_align(hp).getfillbuf^,Tai_align(hp).fillsize);
+               begin
+                 if objectdata.currsec=sec_bss then
+                   objectdata.alloc(Tai_align(hp).fillsize)
+                 else
+                   objectdata.writebytes(Tai_align(hp).getfillbuf^,Tai_align(hp).fillsize);
+               end;
              ait_section :
                begin
                  objectdata.defaultsection(Tai_section(hp).sec);
@@ -1515,7 +1520,16 @@ Implementation
 end.
 {
   $Log$
-  Revision 1.21  2001-06-18 20:36:23  peter
+  Revision 1.22  2001-07-01 20:16:15  peter
+    * alignmentinfo record added
+    * -Oa argument supports more alignment settings that can be specified
+      per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
+      RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
+      required alignment and the maximum usefull alignment. The final
+      alignment will be choosen per variable size dependent on these
+      settings
+
+  Revision 1.21  2001/06/18 20:36:23  peter
     * -Ur switch (merged)
     * masm fixes (merged)
     * quoted filenames for go32v2 and win32

+ 87 - 28
compiler/cutils.pas

@@ -38,12 +38,15 @@ interface
     function min(a,b : longint) : longint;
     function max(a,b : longint) : longint;
     function align(i,a:longint):longint;
-    function align_from_size(datasize:longint;length:longint):longint;
+    function used_align(varalign,minalign,maxalign:longint):longint;
+    function size_2_align(len : longint) : longint;
     procedure Replace(var s:string;s1:string;const s2:string);
     procedure ReplaceCase(var s:string;const s1,s2:string);
     function upper(const s : string) : string;
     function lower(const s : string) : string;
+    function trimbspace(const s:string):string;
     function trimspace(const s:string):string;
+    function GetToken(var s:string;endchar:char):string;
     procedure uppervar(var s : string);
     function hexstr(val : cardinal;cnt : byte) : string;
     function tostru(i:cardinal) : string;
@@ -132,31 +135,6 @@ uses
            max:=a;
       end;
 
-    function align_from_size(datasize:longint;length:longint):longint;
-
-    {Increases the datasize with the required alignment; i.e. on pentium
-     words should be aligned word; and dwords should be aligned dword.
-     So for a word (len=2), datasize is increased to the nearest multiple
-     of 2, and for len=4, datasize is increased to the nearest multiple of
-     4.}
-
-    var data_align:word;
-
-    begin
-        {$IFDEF I386}
-        if length>2 then
-            data_align:=4
-        else if length>1 then
-            data_align:=2
-        else
-            data_align:=1;
-        {$ENDIF}
-        {$IFDEF M68K}
-        data_align:=2;
-        {$ENDIF}
-        align_from_size:=(datasize+data_align-1) and not(data_align-1);
-    end;
-
 
     function align(i,a:longint):longint;
     {
@@ -167,7 +145,43 @@ uses
         if a<=1 then
          align:=i
         else
-         align:=(i+a-1) and not(a-1);
+         align:=((i+a-1) div a) * a;
+      end;
+
+
+    function size_2_align(len : longint) : longint;
+      begin
+         if len>16 then
+           size_2_align:=32
+         else if len>8 then
+           size_2_align:=16
+         else if len>4 then
+           size_2_align:=8
+         else if len>2 then
+           size_2_align:=4
+         else if len>1 then
+           size_2_align:=2
+         else
+           size_2_align:=1;
+      end;
+
+
+    function used_align(varalign,minalign,maxalign:longint):longint;
+      begin
+        { varalign  : minimum alignment required for the variable
+          minalign  : Minimum alignment of this structure, 0 = undefined
+          maxalign  : Maximum alignment of this structure, 0 = undefined }
+        if (minalign>0) and
+           (varalign<minalign) then
+         used_align:=minalign
+        else
+         begin
+           if (maxalign>0) and
+              (varalign>maxalign) then
+            used_align:=maxalign
+           else
+            used_align:=varalign;
+         end;
       end;
 
 
@@ -295,6 +309,22 @@ uses
       end;
 
 
+   function trimbspace(const s:string):string;
+   {
+     return s with all leading spaces and tabs removed
+   }
+     var
+       i,j : longint;
+     begin
+       j:=1;
+       i:=length(s);
+       while (j<i) and (s[j] in [#9,' ']) do
+        inc(j);
+       trimbspace:=Copy(s,j,i-j+1);
+     end;
+
+
+
    function trimspace(const s:string):string;
    {
      return s with all leading and ending spaces and tabs removed
@@ -312,6 +342,25 @@ uses
      end;
 
 
+    function GetToken(var s:string;endchar:char):string;
+      var
+        i : longint;
+      begin
+        s:=TrimSpace(s);
+        i:=pos(EndChar,s);
+        if i=0 then
+         begin
+           GetToken:=s;
+           s:='';
+         end
+        else
+         begin
+           GetToken:=Copy(s,1,i-1);
+           Delete(s,1,i);
+         end;
+      end;
+
+
    function tostr(i : longint) : string;
    {
      return string of value i
@@ -323,6 +372,7 @@ uses
         tostr:=hs;
      end;
 
+
    function int64tostr(i : int64) : string;
    {
      return string of value i
@@ -658,7 +708,16 @@ initialization
 end.
 {
   $Log$
-  Revision 1.7  2001-06-18 20:36:23  peter
+  Revision 1.8  2001-07-01 20:16:15  peter
+    * alignmentinfo record added
+    * -Oa argument supports more alignment settings that can be specified
+      per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
+      RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
+      required alignment and the maximum usefull alignment. The final
+      alignment will be choosen per variable size dependent on these
+      settings
+
+  Revision 1.7  2001/06/18 20:36:23  peter
     * -Ur switch (merged)
     * masm fixes (merged)
     * quoted filenames for go32v2 and win32

+ 63 - 7
compiler/globals.pas

@@ -165,7 +165,7 @@ interface
         Initsetalloc,                            {0=fixed, 1 =var}
        {$ENDIF}
        initpackenum       : longint;
-       initpackrecords    : tpackrecords;
+       initalignment      : talignmentinfo;
        initoptprocessor,
        initspecificoptprocessor : tprocessors;
        initasmmode        : tasmmode;
@@ -183,7 +183,7 @@ interface
        {$ENDIF}
        aktpackenum        : longint;
        aktmaxfpuregisters : longint;
-       aktpackrecords     : tpackrecords;
+       aktalignment       : talignmentinfo;
        aktoptprocessor,
        aktspecificoptprocessor : tprocessors;
        aktasmmode         : tasmmode;
@@ -202,8 +202,7 @@ interface
        EntryMemUsed : longint;
 {$endif FPC}
      { parameter switches }
-       debugstop,
-       only_one_pass : boolean;
+       debugstop : boolean;
 {$EndIf EXTDEBUG}
        { windows / OS/2 application type }
        apptype : tapptype;
@@ -276,6 +275,8 @@ interface
     function  string2guid(const s: string; var GUID: TGUID): boolean;
     function  guid2string(const GUID: TGUID): string;
 
+    function UpdateAlignmentStr(s:string;var a:talignmentinfo):boolean;
+
 
 implementation
 
@@ -1060,6 +1061,7 @@ implementation
         SetCompileMode:=b;
       end;
 
+
     { '('D1:'00000000-'D2:'0000-'D3:'0000-'D4:'0000-000000000000)' }
     function string2guid(const s: string; var GUID: TGUID): boolean;
         function ishexstr(const hs: string): boolean;
@@ -1138,6 +1140,52 @@ implementation
       end;
 
 
+    function UpdateAlignmentStr(s:string;var a:talignmentinfo):boolean;
+      var
+        tok  : string;
+        vstr : string;
+        l    : longint;
+        code : integer;
+        b    : talignmentinfo;
+      begin
+        UpdateAlignmentStr:=true;
+        uppervar(s);
+        fillchar(b,sizeof(b),0);
+        repeat
+          tok:=GetToken(s,'=');
+          if tok='' then
+           break;
+          vstr:=GetToken(s,',');
+          val(vstr,l,code);
+          if tok='PROC' then
+           b.procalign:=l
+          else if tok='JUMP' then
+           b.jumpalign:=l
+          else if tok='LOOP' then
+           b.loopalign:=l
+          else if tok='CONSTMIN' then
+           b.constalignmin:=l
+          else if tok='CONSTMAX' then
+           b.constalignmax:=l
+          else if tok='VARMIN' then
+           b.varalignmin:=l
+          else if tok='VARMAX' then
+           b.varalignmax:=l
+          else if tok='LOCALMIN' then
+           b.localalignmin:=l
+          else if tok='LOCALMAX' then
+           b.localalignmax:=l
+          else if tok='RECORDMIN' then
+           b.recordalignmin:=l
+          else if tok='RECORDMAX' then
+           b.recordalignmax:=l
+          else if tok='PARAALIGN' then
+           b.paraalign:=l
+          else { Error }
+           UpdateAlignmentStr:=false;
+        until false;
+        UpdateAlignment(a,b);
+      end;
 
 {****************************************************************************
                                     Init
@@ -1235,6 +1283,7 @@ implementation
         initmoduleswitches:=[cs_extsyntax,cs_browser];
         initglobalswitches:=[cs_check_unit_name,cs_link_static];
         initoutputformat:=as_none;
+        fillchar(initalignment,sizeof(talignmentinfo),0);
 {$ifdef i386}
         initoptprocessor:=Class386;
         initspecificoptprocessor:=Class386;
@@ -1242,7 +1291,6 @@ implementation
         {$IFDEF testvarsets}
         initsetalloc:=0;
         {$ENDIF}
-        initpackrecords:=packrecord_2;
         initasmmode:=asmmode_i386_att;
 {$else not i386}
   {$ifdef m68k}
@@ -1252,7 +1300,6 @@ implementation
         {$IFDEF testvarsets}
          initsetalloc:=0;
         {$ENDIF}
-        initpackrecords:=packrecord_2;
         initoutputformat:=as_m68k_as;
         initasmmode:=asmmode_m68k_mot;
   {$endif m68k}
@@ -1284,7 +1331,16 @@ begin
 end.
 {
   $Log$
-  Revision 1.38  2001-06-18 20:36:24  peter
+  Revision 1.39  2001-07-01 20:16:15  peter
+    * alignmentinfo record added
+    * -Oa argument supports more alignment settings that can be specified
+      per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
+      RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
+      required alignment and the maximum usefull alignment. The final
+      alignment will be choosen per variable size dependent on these
+      settings
+
+  Revision 1.38  2001/06/18 20:36:24  peter
     * -Ur switch (merged)
     * masm fixes (merged)
     * quoted filenames for go32v2 and win32

+ 12 - 15
compiler/globtype.pas

@@ -109,7 +109,7 @@ interface
          cs_load_gpc_unit,
          { optimizer }
          cs_regalloc,cs_uncertainopts,cs_littlesize,cs_optimize,
-         cs_fastoptimize, cs_slowoptimize,cs_align,
+         cs_fastoptimize, cs_slowoptimize,
          { browser }
          cs_browser_log,
          { debugger }
@@ -119,7 +119,7 @@ interface
          cs_asm_regalloc,cs_asm_tempalloc,
          { linking }
          cs_link_extern,cs_link_static,cs_link_smart,cs_link_shared,cs_link_deffile,
-         cs_link_strip,cs_link_toc,cs_link_staticflag
+         cs_link_strip,cs_link_staticflag
        );
        tglobalswitches = set of tglobalswitch;
 
@@ -164,18 +164,6 @@ interface
          bt_general,bt_type,bt_const,bt_except
        );
 
-       { packrecords types }
-       tpackrecords = (packrecord_none,
-         packrecord_1,packrecord_2,packrecord_4,
-         packrecord_8,packrecord_16,packrecord_32,
-         packrecord_C
-       );
-
-    const
-       packrecordalignment : array[tpackrecords] of byte=(0,
-         1,2,4,8,16,32,1
-       );
-
     type
        stringid = string[maxidlen];
 
@@ -220,7 +208,16 @@ implementation
 end.
 {
   $Log$
-  Revision 1.12  2001-06-03 21:57:35  peter
+  Revision 1.13  2001-07-01 20:16:15  peter
+    * alignmentinfo record added
+    * -Oa argument supports more alignment settings that can be specified
+      per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
+      RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
+      required alignment and the maximum usefull alignment. The final
+      alignment will be choosen per variable size dependent on these
+      settings
+
+  Revision 1.12  2001/06/03 21:57:35  peter
     + hint directive parsing support
 
   Revision 1.11  2001/01/20 18:32:52  hajny

+ 16 - 8
compiler/i386/cgai386.pas

@@ -738,7 +738,7 @@ implementation
         case t.loc of
           LOC_REGISTER,
          LOC_CREGISTER : begin
-                           if target_info.stackalignment=4 then
+                           if aktalignment.paraalign=4 then
                              exprasmList.concat(Taicpu.Op_reg(A_PUSH,S_L,makereg32(t.register)))
                            else
                              exprasmList.concat(Taicpu.Op_reg(A_PUSH,S_W,makereg16(t.register)));
@@ -746,7 +746,7 @@ implementation
                          end;
                LOC_MEM,
          LOC_REFERENCE : begin
-                           if target_info.stackalignment=4 then
+                           if aktalignment.paraalign=4 then
                             opsize:=S_L
                            else
                             opsize:=S_W;
@@ -822,7 +822,7 @@ implementation
         if t.is_immediate then
           begin
             if (size=4) or
-               (target_info.stackalignment=4) then
+               (aktalignment.paraalign=4) then
               exprasmList.concat(Taicpu.Op_const(A_PUSH,S_L,t.offset))
             else
               exprasmList.concat(Taicpu.Op_const(A_PUSH,S_W,t.offset));
@@ -838,7 +838,7 @@ implementation
               end;
               exprasmList.concat(Taicpu.Op_ref_reg(A_MOVZX,s,
                 newreference(t),R_EDI));
-              if target_info.stackalignment=4 then
+              if aktalignment.paraalign=4 then
                 exprasmList.concat(Taicpu.Op_reg(A_PUSH,S_L,R_EDI))
               else
                 exprasmList.concat(Taicpu.Op_reg(A_PUSH,S_W,R_DI));
@@ -2404,12 +2404,11 @@ implementation
           end;
 {$endif GDB}
 
-       { Align, gprof uses 16 byte granularity }
+         { Align, gprof uses 16 byte granularity }
          if (cs_profile in aktmoduleswitches) then
           exprasmList.insert(Tai_align.Create_op(16,$90))
          else
-          if not(cs_littlesize in aktglobalswitches) then
-           exprasmList.insert(Tai_align.Create(16));
+          exprasmList.insert(Tai_align.Create(aktalignment.procalign));
        end;
        if inlined then
          load_regvars(exprasmlist,nil);
@@ -2997,7 +2996,16 @@ implementation
 end.
 {
   $Log$
-  Revision 1.24  2001-05-27 14:30:55  florian
+  Revision 1.25  2001-07-01 20:16:18  peter
+    * alignmentinfo record added
+    * -Oa argument supports more alignment settings that can be specified
+      per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
+      RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
+      required alignment and the maximum usefull alignment. The final
+      alignment will be choosen per variable size dependent on these
+      settings
+
+  Revision 1.24  2001/05/27 14:30:55  florian
     + some widestring stuff added
 
   Revision 1.23  2001/04/21 13:33:16  peter

+ 21 - 4
compiler/i386/cpuswtch.pas

@@ -51,9 +51,17 @@ begin
            While (j <= Length(Opt)) Do
              Begin
                case opt[j] of
-                 '-' : initglobalswitches:=initglobalswitches-[cs_optimize,cs_fastoptimize,cs_slowoptimize,cs_littlesize,
-                           cs_regalloc,cs_uncertainopts,cs_align];
-                 'a' : initglobalswitches:=initglobalswitches+[cs_align];
+                 '-' :
+                   begin
+                     initglobalswitches:=initglobalswitches-[cs_optimize,cs_fastoptimize,cs_slowoptimize,cs_littlesize,
+                       cs_regalloc,cs_uncertainopts];
+                     FillChar(ParaAlignment,sizeof(ParaAlignment),0);
+                   end;
+                 'a' :
+                   begin
+                     UpdateAlignmentStr(Copy(Opt,j+1,255),ParaAlignment);
+                     j:=length(Opt);
+                   end;
                  'g' : initglobalswitches:=initglobalswitches+[cs_littlesize];
                  'G' : initglobalswitches:=initglobalswitches-[cs_littlesize];
                  'r' :
@@ -121,7 +129,16 @@ initialization
 end.
 {
   $Log$
-  Revision 1.3  2001-05-12 12:11:31  peter
+  Revision 1.4  2001-07-01 20:16:20  peter
+    * alignmentinfo record added
+    * -Oa argument supports more alignment settings that can be specified
+      per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
+      RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
+      required alignment and the maximum usefull alignment. The final
+      alignment will be choosen per variable size dependent on these
+      settings
+
+  Revision 1.3  2001/05/12 12:11:31  peter
     * simplify_ppu is now the default, a recompile of the compiler now
       only compiles pp.pas
 

+ 13 - 4
compiler/i386/n386cal.pas

@@ -94,7 +94,7 @@ implementation
       begin
          { set default para_alignment to target_info.stackalignment }
          if para_alignment=0 then
-          para_alignment:=target_info.stackalignment;
+          para_alignment:=aktalignment.paraalign;
 
          { push from left to right if specified }
          if push_from_left_to_right and assigned(right) then
@@ -311,7 +311,7 @@ implementation
          if ([pocall_cdecl,pocall_cppdecl,pocall_stdcall]*procdefinition.proccalloptions)<>[] then
           para_alignment:=4
          else
-          para_alignment:=target_info.stackalignment;
+          para_alignment:=aktalignment.paraalign;
 
          if not assigned(procdefinition) then
           exit;
@@ -485,7 +485,7 @@ implementation
                   para_alignment,para_offset);
            end;
          if inlined then
-           inlinecode.retoffset:=gettempofsizepersistant(Align(resulttype.def.size,target_info.stackalignment));
+           inlinecode.retoffset:=gettempofsizepersistant(Align(resulttype.def.size,aktalignment.paraalign));
          if ret_in_param(resulttype.def) then
            begin
               { This must not be counted for C code
@@ -1576,7 +1576,16 @@ begin
 end.
 {
   $Log$
-  Revision 1.25  2001-06-04 11:48:02  peter
+  Revision 1.26  2001-07-01 20:16:20  peter
+    * alignmentinfo record added
+    * -Oa argument supports more alignment settings that can be specified
+      per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
+      RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
+      required alignment and the maximum usefull alignment. The final
+      alignment will be choosen per variable size dependent on these
+      settings
+
+  Revision 1.25  2001/06/04 11:48:02  peter
     * better const to var checking
 
   Revision 1.24  2001/05/19 21:22:53  peter

+ 12 - 18
compiler/i386/n386flw.pas

@@ -119,16 +119,8 @@ implementation
          if nodetype=whilen then
            emitjmp(C_None,lcont);
 
-
          { align loop target }
-         if not(cs_littlesize in aktglobalswitches) then
-           begin
-              if (cs_align in aktglobalswitches) then
-                exprasmList.concat(Tai_align.Create_op(16,$90))
-              else
-                exprasmList.concat(Tai_align.Create_op(4,$90))
-           end;
-
+         exprasmList.concat(Tai_align.Create(aktalignment.loopalign));
          emitlab(lloop);
 
          aktcontinuelabel:=lcont;
@@ -355,14 +347,7 @@ implementation
            emitjmp(hcond,aktbreaklabel);
 
          { align loop target }
-         if not(cs_littlesize in aktglobalswitches) then
-           begin
-              if (cs_align in aktglobalswitches) then
-                exprasmList.concat(Tai_align.Create_op(16,$90))
-              else
-                exprasmList.concat(Tai_align.Create_op(4,$90))
-           end;
-
+         exprasmList.concat(Tai_align.Create(aktalignment.loopalign));
          emitlab(l3);
 
          { help register must not be in instruction block }
@@ -1355,7 +1340,16 @@ begin
 end.
 {
   $Log$
-  Revision 1.12  2001-04-15 09:48:31  peter
+  Revision 1.13  2001-07-01 20:16:20  peter
+    * alignmentinfo record added
+    * -Oa argument supports more alignment settings that can be specified
+      per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
+      RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
+      required alignment and the maximum usefull alignment. The final
+      alignment will be choosen per variable size dependent on these
+      settings
+
+  Revision 1.12  2001/04/15 09:48:31  peter
     * fixed crash in labelnode
     * easier detection of goto and label in try blocks
 

+ 12 - 3
compiler/i386/n386util.pas

@@ -291,7 +291,7 @@ implementation
       { copy the element on the stack, slightly complicated }
         if p.nodetype=ordconstn then
          begin
-           if target_info.stackalignment=4 then
+           if aktalignment.paraalign=4 then
              exprasmList.concat(Taicpu.Op_const(A_PUSH,S_L,tordconstnode(p).value))
            else
              exprasmList.concat(Taicpu.Op_const(A_PUSH,S_W,tordconstnode(p).value));
@@ -320,7 +320,7 @@ implementation
                        hr32:=reg8toreg32(hr);
                      end;
                  end;
-                 if target_info.stackalignment=4 then
+                 if aktalignment.paraalign=4 then
                    exprasmList.concat(Taicpu.Op_reg(A_PUSH,S_L,hr32))
                  else
                    exprasmList.concat(Taicpu.Op_reg(A_PUSH,S_W,hr16));
@@ -1472,7 +1472,16 @@ implementation
 end.
 {
   $Log$
-  Revision 1.16  2001-04-18 22:02:03  peter
+  Revision 1.17  2001-07-01 20:16:20  peter
+    * alignmentinfo record added
+    * -Oa argument supports more alignment settings that can be specified
+      per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
+      RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
+      required alignment and the maximum usefull alignment. The final
+      alignment will be choosen per variable size dependent on these
+      settings
+
+  Revision 1.16  2001/04/18 22:02:03  peter
     * registration of targets and assemblers
 
   Revision 1.15  2001/04/13 01:22:19  peter

+ 12 - 3
compiler/ncal.pas

@@ -1586,9 +1586,9 @@ implementation
          inlineprocsym:=tcallnode(callp).symtableprocentry;
          retoffset:=-target_info.size_of_pointer; { less dangerous as zero (PM) }
          para_offset:=0;
-         para_size:=inlineprocsym.definition.para_size(target_info.stackalignment);
+         para_size:=inlineprocsym.definition.para_size(target_info.alignment.paraalign);
          if ret_in_param(inlineprocsym.definition.rettype.def) then
-           para_size:=para_size+target_info.size_of_pointer;
+           inc(para_size,target_info.size_of_pointer);
          { copy args }
          if assigned(code) then
            inlinetree:=code.getcopy
@@ -1655,7 +1655,16 @@ begin
 end.
 {
   $Log$
-  Revision 1.35  2001-06-04 18:08:19  peter
+  Revision 1.36  2001-07-01 20:16:15  peter
+    * alignmentinfo record added
+    * -Oa argument supports more alignment settings that can be specified
+      per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
+      RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
+      required alignment and the maximum usefull alignment. The final
+      alignment will be choosen per variable size dependent on these
+      settings
+
+  Revision 1.35  2001/06/04 18:08:19  peter
     * procvar support for varargs
 
   Revision 1.34  2001/06/04 11:48:02  peter

+ 157 - 110
compiler/options.pas

@@ -27,7 +27,7 @@ unit options;
 interface
 
 uses
-  globtype,globals,verbose;
+  globtype,globals,verbose,systems;
 
 type
   TOption=class
@@ -40,6 +40,7 @@ type
     ParaUnitPath,
     ParaObjectPath,
     ParaLibraryPath : TSearchPathList;
+    ParaAlignment   : TAlignmentInfo;
     Constructor Create;
     Destructor Destroy;override;
     procedure WriteLogo;
@@ -72,7 +73,7 @@ uses
 {$else Delphi}
   dos,
 {$endif Delphi}
-  version,systems,
+  version,
   cutils,messages
 {$ifdef BrowserLog}
   ,browlog
@@ -356,10 +357,10 @@ begin
                       initglobalswitches:=initglobalswitches+[cs_asm_leave];
                       for j:=1 to length(more) do
                        case more[j] of
-                        'l' : initglobalswitches:=initglobalswitches+[cs_asm_source];
-                        'r' : initglobalswitches:=initglobalswitches+[cs_asm_regalloc];
-                        't' : initglobalswitches:=initglobalswitches+[cs_asm_tempalloc];
-                        '-' : initglobalswitches:=initglobalswitches-
+                        'l' : include(initglobalswitches,cs_asm_source);
+                        'r' : include(initglobalswitches,cs_asm_regalloc);
+                        't' : include(initglobalswitches,cs_asm_tempalloc);
+                        '-' : initglobalswitches:=initglobalswitches -
                                 [cs_asm_leave, cs_asm_source,cs_asm_regalloc, cs_asm_tempalloc];
                        else
                          IllegalPara(opt);
@@ -372,30 +373,35 @@ begin
                        IllegalPara(opt);
                     end;
               'b' : begin
+                      if UnsetBool(More,0) then
+                       begin
+                         exclude(initmoduleswitches,cs_browser);
+                         exclude(initmoduleswitches,cs_local_browser);
 {$ifdef BrowserLog}
-                      initglobalswitches:=initglobalswitches+[cs_browser_log];
+                         exclude(initglobalswitches,cs_browser_log);
 {$endif}
-                      if More<>'' then
-                        if More='l' then
-                          initmoduleswitches:=initmoduleswitches+[cs_local_browser]
-                        else if More='-' then
-                          begin
-                            initmoduleswitches:=initmoduleswitches-[cs_browser,cs_local_browser];
+                       end
+                      else
+                       begin
+                         include(initmoduleswitches,cs_browser);
 {$ifdef BrowserLog}
-                            initglobalswitches:=initglobalswitches-[cs_browser_log];
+                         include(initglobalswitches,cs_browser_log);
 {$endif}
-                          end
-                        else if More<>'+' then
+                       end;
+                      if More<>'' then
+                        if (More='l') or (More='l+') then
+                          include(initmoduleswitches,cs_local_browser)
+                        else
+                         if More='l-' then
+                          exclude(initmoduleswitches,cs_local_browser)
+                        else
 {$ifdef BrowserLog}
                           browserlog.elements_to_list.insert(more);
 {$else}
                           IllegalPara(opt);
 {$endif}
                     end;
-              'B' : if UnSetBool(more,0) then
-                      do_build:=false
-                    else
-                      do_build:=true;
+              'B' : do_build:=not UnSetBool(more,0);
               'C' : begin
                       j := 1;
                       while j <= length(more) Do
@@ -409,49 +415,53 @@ begin
                                   IllegalPara(opt);
                                  break;
                                end;
-                            'i' : If UnsetBool(More, j) then
-                                    initlocalswitches:=initlocalswitches-[cs_check_io]
-                                  else initlocalswitches:=initlocalswitches+[cs_check_io];
-                            'n' : If UnsetBool(More, j) then
-                                    initglobalswitches:=initglobalswitches-[cs_link_extern]
-                                  Else initglobalswitches:=initglobalswitches+[cs_link_extern];
+                            'i' :
+                              If UnsetBool(More, j) then
+                                exclude(initlocalswitches,cs_check_io)
+                              else
+                                include(initlocalswitches,cs_check_io);
+                            'n' :
+                              If UnsetBool(More, j) then
+                                exclude(initglobalswitches,cs_link_extern)
+                              Else
+                                include(initglobalswitches,cs_link_extern);
                             'o' :
                               If UnsetBool(More, j) then
-                                  initlocalswitches:=initlocalswitches-[cs_check_overflow]
+                                exclude(initlocalswitches,cs_check_overflow)
                               Else
-                                initlocalswitches:=initlocalswitches+[cs_check_overflow];
+                                include(initlocalswitches,cs_check_overflow);
                             'r' :
                               If UnsetBool(More, j) then
-                                 initlocalswitches:=initlocalswitches-[cs_check_range]
+                                exclude(initlocalswitches,cs_check_range)
                               Else
-                                initlocalswitches:=initlocalswitches+[cs_check_range];
+                                include(initlocalswitches,cs_check_range);
                             'R' :
                               If UnsetBool(More, j) then
-                                initlocalswitches:=initlocalswitches-[cs_check_object_ext]
+                                exclude(initlocalswitches,cs_check_object_ext)
                               Else
-                                initlocalswitches:=initlocalswitches+[cs_check_object_ext];
+                                include(initlocalswitches,cs_check_object_ext);
                             's' :
-                               begin
+                              begin
                                  val(copy(more,j+1,length(more)-j),stacksize,code);
                                  if (code<>0) or (stacksize>=67107840) or (stacksize<1024) then
                                   IllegalPara(opt);
                                  break;
-                               end;
+                              end;
                             't' :
                                If UnsetBool(More, j) then
-                                 initlocalswitches:=initlocalswitches-[cs_check_stack]
+                                 exclude(initlocalswitches,cs_check_stack)
                                Else
-                                 initlocalswitches:=initlocalswitches+[cs_check_stack];
+                                 include(initlocalswitches,cs_check_stack);
                             'D' :
                                If UnsetBool(More, j) then
-                                   initmoduleswitches:=initmoduleswitches-[cs_create_dynamic]
+                                 exclude(initmoduleswitches,cs_create_dynamic)
                                Else
-                                 initmoduleswitches:=initmoduleswitches+[cs_create_dynamic];
+                                 include(initmoduleswitches,cs_create_dynamic);
                             'X' :
                                If UnsetBool(More, j) then
-                                 initmoduleswitches:=initmoduleswitches-[cs_create_smart]
+                                 exclude(initmoduleswitches,cs_create_smart)
                                Else
-                                 initmoduleswitches:=initmoduleswitches+[cs_create_smart];
+                                 include(initmoduleswitches,cs_create_smart);
                             else
                                IllegalPara(opt);
                           end;
@@ -460,7 +470,7 @@ begin
                     end;
               'd' : def_symbol(more);
               'D' : begin
-                      initglobalswitches:=initglobalswitches+[cs_link_deffile];
+                      include(initglobalswitches,cs_link_deffile);
                       for j:=1 to length(more) do
                        case more[j] of
                         'd' : begin
@@ -495,8 +505,7 @@ begin
                               end;
                         'w' : usewindowapi:=true;
                         '-' : begin
-                                initglobalswitches:=initglobalswitches-
-                                  [cs_link_deffile];
+                                exclude(initglobalswitches,cs_link_deffile);
                                 usewindowapi:=false;
                               end;
                        else
@@ -505,10 +514,10 @@ begin
                     end;
               'e' : exepath:=FixPath(More,true);
               { Just used by RHIDE }
-              'E' : if (length(more)=0) or (UnsetBool(More, 0)) then
-                      initglobalswitches:=initglobalswitches+[cs_link_extern]
+              'E' : if UnsetBool(More, 0) then
+                      exclude(initglobalswitches,cs_link_extern)
                     else
-                      initglobalswitches:=initglobalswitches-[cs_link_extern];
+                      include(initglobalswitches,cs_link_extern);
               'F' : begin
                       c:=more[1];
                       Delete(more,1,1);
@@ -547,26 +556,41 @@ begin
               'g' : begin
                       if UnsetBool(More, 0) then
                         begin
-                          initmoduleswitches:=initmoduleswitches-[cs_debuginfo];
-                          if (length(More)>1) and (More[2]='l') then
-                            initglobalswitches:=initglobalswitches+[cs_gdb_lineinfo];
+                          exclude(initmoduleswitches,cs_debuginfo);
+                          exclude(initglobalswitches,cs_gdb_dbx);
+                          exclude(initglobalswitches,cs_gdb_gsym);
+                          exclude(initglobalswitches,cs_gdb_heaptrc);
+                          exclude(initglobalswitches,cs_gdb_lineinfo);
+                          exclude(initglobalswitches,cs_checkpointer);
                         end
                       else
                        begin
 {$ifdef GDB}
-                         initmoduleswitches:=initmoduleswitches+[cs_debuginfo];
+                         include(initmoduleswitches,cs_debuginfo);
                          if not RelocSectionSetExplicitly then
                            RelocSection:=false;
                          for j:=1 to length(more) do
                           case more[j] of
-                           'd' : initglobalswitches:=initglobalswitches+[cs_gdb_dbx];
-                           'g' : initglobalswitches:=initglobalswitches+[cs_gdb_gsym];
-                           'h' : initglobalswitches:=initglobalswitches+[cs_gdb_heaptrc];
-                           'l' : initglobalswitches:=initglobalswitches+[cs_gdb_lineinfo];
-                           'c' : initglobalswitches:=initglobalswitches+[cs_checkpointer];
-{$ifdef EXTDEBUG}
-                           'p' : only_one_pass:=true;
-{$endif EXTDEBUG}
+                           'd' : if UnsetBool(More, j) then
+                                   exclude(initglobalswitches,cs_gdb_dbx)
+                                 else
+                                   include(initglobalswitches,cs_gdb_dbx);
+                           'g' : if UnsetBool(More, j) then
+                                   exclude(initglobalswitches,cs_gdb_gsym)
+                                 else
+                                   include(initglobalswitches,cs_gdb_gsym);
+                           'h' : if UnsetBool(More, j) then
+                                   exclude(initglobalswitches,cs_gdb_heaptrc)
+                                 else
+                                   include(initglobalswitches,cs_gdb_heaptrc);
+                           'l' : if UnsetBool(More, j) then
+                                   exclude(initglobalswitches,cs_gdb_lineinfo)
+                                 else
+                                   include(initglobalswitches,cs_gdb_lineinfo);
+                           'c' : if UnsetBool(More, j) then
+                                   exclude(initglobalswitches,cs_checkpointer)
+                                 else
+                                   include(initglobalswitches,cs_checkpointer);
                           else
                             IllegalPara(opt);
                           end;
@@ -592,14 +616,8 @@ begin
                      ParaLinkOptions:=ParaLinkOptions+' '+More
                     else
                      IllegalPara(opt);
-              'l' : if UnSetBool(more,0) then
-                      DoWriteLogo:=false
-                    else
-                      DoWriteLogo:=true;
-              'm' : if UnSetBool(more,0) then
-                      parapreprocess:=false
-                    else
-                      parapreprocess:=true;
+              'l' : DoWriteLogo:=not UnSetBool(more,0);
+              'm' : parapreprocess:=not UnSetBool(more,0);
               'n' : if More='' then
                      begin
                        read_configfile:=false;
@@ -618,15 +636,18 @@ begin
                           undef_symbol('FPC_PROFILE');
                         end
                       else
+                        if Length(More)=0 then
+                          IllegalPara(opt)
+                        else
                         case more[1] of
-                         'g' : if (length(opt)=3) and UnsetBool(more, 1) then
+                         'g' : if UnsetBool(more, 1) then
                                 begin
-                                  initmoduleswitches:=initmoduleswitches-[cs_profile];
+                                  exclude(initmoduleswitches,cs_profile);
                                   undef_symbol('FPC_PROFILE');
                                 end
                                else
                                 begin
-                                  initmoduleswitches:=initmoduleswitches+[cs_profile];
+                                  include(initmoduleswitches,cs_profile);
                                   def_symbol('FPC_PROFILE');
                                end;
                         else
@@ -635,9 +656,9 @@ begin
                     end;
 {$ifdef Unix}
               'P' : if UnsetBool(More, 0) then
-                      initglobalswitches:=initglobalswitches-[cs_asm_pipe]
+                      exclude(initglobalswitches,cs_asm_pipe)
                     else
-                      initglobalswitches:=initglobalswitches+[cs_asm_pipe];
+                      include(initglobalswitches,cs_asm_pipe);
 {$endif Unix}
               's' : if UnsetBool(More, 0) then
                       initglobalswitches:=initglobalswitches-[cs_asm_extern,cs_link_extern]
@@ -657,30 +678,27 @@ begin
                         for j:=1 to length(more) do
                          case more[j] of
                           '2' : SetCompileMode('OBJFPC',true);
-                          'a' : initlocalswitches:=InitLocalswitches+[cs_do_assertion];
-                          'c' : initmoduleswitches:=initmoduleswitches+[cs_support_c_operators];
+                          'a' : include(initlocalswitches,cs_do_assertion);
+                          'c' : include(initmoduleswitches,cs_support_c_operators);
                           'd' : SetCompileMode('DELPHI',true);
                           'e' : begin
                                   SetErrorFlags(copy(more,j+1,length(more)));
                                   break;
                                 end;
-                          'g' : initmoduleswitches:=initmoduleswitches+[cs_support_goto];
-                          'h' : initlocalswitches:=initlocalswitches+[cs_ansistrings];
-                          'i' : initmoduleswitches:=initmoduleswitches+[cs_support_inline];
-                          'm' : initmoduleswitches:=initmoduleswitches+[cs_support_macro];
+                          'g' : include(initmoduleswitches,cs_support_goto);
+                          'h' : include(initlocalswitches,cs_ansistrings);
+                          'i' : include(initmoduleswitches,cs_support_inline);
+                          'm' : include(initmoduleswitches,cs_support_macro);
                           'o' : SetCompileMode('TP',true);
                           'p' : SetCompileMode('GPC',true);
-                          's' : initglobalswitches:=initglobalswitches+[cs_constructor_name];
-                          't' : initmoduleswitches:=initmoduleswitches+[cs_static_keyword];
+                          's' : include(initglobalswitches,cs_constructor_name);
+                          't' : include(initmoduleswitches,cs_static_keyword);
                           '-' : begin
-                                  initglobalswitches:=initglobalswitches -
-                                    [cs_constructor_name];
-                                  initlocalswitches:=InitLocalswitches -
-                                    [cs_do_assertion, cs_ansistrings];
-                                  initmoduleswitches:=initmoduleswitches -
-                                    [cs_support_c_operators, cs_support_goto,
-                                     cs_support_inline, cs_support_macro,
-                                     cs_static_keyword];
+                                  exclude(initglobalswitches,cs_constructor_name);
+                                  initlocalswitches:=InitLocalswitches - [cs_do_assertion, cs_ansistrings];
+                                  initmoduleswitches:=initmoduleswitches - [cs_support_c_operators, cs_support_goto,
+                                                                            cs_support_inline, cs_support_macro,
+                                                                            cs_static_keyword];
                                 end;
                          else
                           IllegalPara(opt);
@@ -719,18 +737,16 @@ begin
                                 break;
                               end;
 {$endif UNITALIASES}
-                        'n' : initglobalswitches:=initglobalswitches-[cs_check_unit_name];
+                        'n' : exclude(initglobalswitches,cs_check_unit_name);
                         'p' : begin
                                 Message2(option_obsolete_switch_use_new,'-Up','-Fu');
                                 break;
                               end;
                         'r' : do_release:=true;
-                        's' : initmoduleswitches:=initmoduleswitches+[cs_compilesystem];
+                        's' : include(initmoduleswitches,cs_compilesystem);
                         '-' : begin
-                                initmoduleswitches:=initmoduleswitches
-                                  - [cs_compilesystem];
-                                initglobalswitches:=initglobalswitches
-                                  + [cs_check_unit_name];
+                                exclude(initmoduleswitches,cs_compilesystem);
+                                exclude(initglobalswitches,cs_check_unit_name);
                               end;
                        else
                          IllegalPara(opt);
@@ -744,8 +760,7 @@ begin
                       begin
                        inc(j);
                        case More[j] of
-                        'B': {bind_win32_dll:=true}
-                             begin
+                        'B': begin
                                {  -WB200000 means set trefered base address
                                  to $200000, but does not change relocsection boolean
                                  this way we can create both relocatble and
@@ -762,12 +777,18 @@ begin
                                  end;
                                break;
                              end;
-                        'C': apptype:=app_cui;
+                        'C': if UnsetBool(More, j) then
+                               apptype:=app_gui
+                              else
+                               apptype:=app_cui;
                         'D': ForceDeffileForExport:=not UnsetBool(More, j);
                         'F': apptype:=app_fs;
-                        'G': apptype:=app_gui;
+                        'G': if UnsetBool(More, j) then
+                               apptype:=app_cui
+                              else
+                               apptype:=app_gui;
                         'N': begin
-                               RelocSection:=false;
+                               RelocSection:=UnsetBool(More,j);
                                RelocSectionSetExplicitly:=true;
                              end;
                         'R': begin
@@ -783,35 +804,38 @@ begin
               'X' : begin
                       for j:=1 to length(More) do
                        case More[j] of
-                        'c' : initglobalswitches:=initglobalswitches+[cs_link_toc];
-                        's' : initglobalswitches:=initglobalswitches+[cs_link_strip];
-                        't' : initglobalswitches:=initglobalswitches+[cs_link_staticflag];
+                        's' : include(initglobalswitches,cs_link_strip);
+                        't' : include(initglobalswitches,cs_link_staticflag);
                         'D' : begin
                                 def_symbol('FPC_LINK_DYNAMIC');
                                 undef_symbol('FPC_LINK_SMART');
                                 undef_symbol('FPC_LINK_STATIC');
-                                initglobalswitches:=initglobalswitches+[cs_link_shared];
-                                initglobalswitches:=initglobalswitches-[cs_link_static,cs_link_smart];
+                                exclude(initglobalswitches,cs_link_static);
+                                exclude(initglobalswitches,cs_link_smart);
+                                include(initglobalswitches,cs_link_shared);
                                 LinkTypeSetExplicitly:=true;
                               end;
                         'S' : begin
                                 def_symbol('FPC_LINK_STATIC');
                                 undef_symbol('FPC_LINK_SMART');
                                 undef_symbol('FPC_LINK_DYNAMIC');
-                                initglobalswitches:=initglobalswitches+[cs_link_static];
-                                initglobalswitches:=initglobalswitches-[cs_link_shared,cs_link_smart];
+                                include(initglobalswitches,cs_link_static);
+                                exclude(initglobalswitches,cs_link_smart);
+                                exclude(initglobalswitches,cs_link_shared);
                                 LinkTypeSetExplicitly:=true;
                               end;
                         'X' : begin
                                 def_symbol('FPC_LINK_SMART');
                                 undef_symbol('FPC_LINK_STATIC');
                                 undef_symbol('FPC_LINK_DYNAMIC');
-                                initglobalswitches:=initglobalswitches+[cs_link_smart];
-                                initglobalswitches:=initglobalswitches-[cs_link_shared,cs_link_static];
+                                exclude(initglobalswitches,cs_link_static);
+                                include(initglobalswitches,cs_link_smart);
+                                exclude(initglobalswitches,cs_link_shared);
                                 LinkTypeSetExplicitly:=true;
                               end;
                         '-' : begin
-                                initglobalswitches:=initglobalswitches-[cs_link_toc, cs_link_strip, cs_link_staticflag];
+                                exclude(initglobalswitches,cs_link_staticflag);
+                                exclude(initglobalswitches,cs_link_strip);
                                 set_default_link_type;
                               end;
                        else
@@ -1208,6 +1232,7 @@ begin
   ParaObjectPath:=TSearchPathList.Create;
   ParaUnitPath:=TSearchPathList.Create;
   ParaLibraryPath:=TSearchPathList.Create;
+  FillChar(ParaAlignment,sizeof(ParaAlignment),0);
 end;
 
 
@@ -1504,11 +1529,24 @@ begin
 { turn off stripping if compiling with debuginfo or profile }
   if (cs_debuginfo in initmoduleswitches) or
      (cs_profile in initmoduleswitches) then
-    initglobalswitches:=initglobalswitches-[cs_link_strip];
+    exclude(initglobalswitches,cs_link_strip);
 
   if not LinkTypeSetExplicitly then
    set_default_link_type;
 
+  { Default alignment settings,
+    1. load the defaults for the target
+    2. override with generic optimizer setting (little size)
+    3. override with the user specified -Oa }
+  UpdateAlignment(initalignment,target_info.alignment);
+  if (cs_littlesize in aktglobalswitches) then
+   begin
+     initalignment.procalign:=1;
+     initalignment.jumpalign:=1;
+     initalignment.loopalign:=1;
+   end;
+  UpdateAlignment(initalignment,option.paraalignment);
+
 { Set defines depending on the target }
   if (target_info.target in [target_i386_GO32V1,target_i386_GO32V2]) then
    def_symbol('DPMI'); { MSDOS is not defined in BP when target is DPMI }
@@ -1526,7 +1564,16 @@ finalization
 end.
 {
   $Log$
-  Revision 1.46  2001-06-29 19:41:54  peter
+  Revision 1.47  2001-07-01 20:16:16  peter
+    * alignmentinfo record added
+    * -Oa argument supports more alignment settings that can be specified
+      per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
+      RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
+      required alignment and the maximum usefull alignment. The final
+      alignment will be choosen per variable size dependent on these
+      settings
+
+  Revision 1.46  2001/06/29 19:41:54  peter
     * patch from Pavel Ozerski to support +/- better
 
   Revision 1.45  2001/06/19 14:55:45  jonas

+ 14 - 5
compiler/parser.pas

@@ -267,7 +267,7 @@ implementation
          oldaktmoduleswitches : tmoduleswitches;
          oldaktfilepos      : tfileposinfo;
          oldaktpackenum,oldaktmaxfpuregisters : longint;
-         oldaktpackrecords  : tpackrecords;
+         oldaktalignment  : talignmentinfo;
          oldaktoutputformat : tasm;
          oldaktspecificoptprocessor,
          oldaktoptprocessor : tprocessors;
@@ -339,7 +339,7 @@ implementation
           end;
          oldaktlocalswitches:=aktlocalswitches;
          oldaktmoduleswitches:=aktmoduleswitches;
-         oldaktpackrecords:=aktpackrecords;
+         oldaktalignment:=aktalignment;
          oldaktpackenum:=aktpackenum;
          oldaktmaxfpuregisters:=aktmaxfpuregisters;
          oldaktoutputformat:=aktoutputformat;
@@ -403,7 +403,7 @@ implementation
          {$IFDEF Testvarsets}
          aktsetalloc:=initsetalloc;
          {$ENDIF}
-         aktpackrecords:=initpackrecords;
+         aktalignment:=initalignment;
          aktpackenum:=initpackenum;
          aktoutputformat:=initoutputformat;
          aktoptprocessor:=initoptprocessor;
@@ -536,7 +536,7 @@ implementation
               move(oldoverloaded_operators,overloaded_operators,sizeof(toverloaded_operators));
               aktlocalswitches:=oldaktlocalswitches;
               aktmoduleswitches:=oldaktmoduleswitches;
-              aktpackrecords:=oldaktpackrecords;
+              aktalignment:=oldaktalignment;
               aktpackenum:=oldaktpackenum;
               aktmaxfpuregisters:=oldaktmaxfpuregisters;
               aktoutputformat:=oldaktoutputformat;
@@ -617,7 +617,16 @@ implementation
 end.
 {
   $Log$
-  Revision 1.19  2001-05-19 23:05:19  peter
+  Revision 1.20  2001-07-01 20:16:16  peter
+    * alignmentinfo record added
+    * -Oa argument supports more alignment settings that can be specified
+      per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
+      RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
+      required alignment and the maximum usefull alignment. The final
+      alignment will be choosen per variable size dependent on these
+      settings
+
+  Revision 1.19  2001/05/19 23:05:19  peter
     * support uses <unit> in <file> construction
 
   Revision 1.18  2001/05/06 14:49:17  peter

+ 11 - 2
compiler/pdecsub.pas

@@ -1556,7 +1556,7 @@ const
        { Adjust positions of args for cdecl or stdcall }
          if (aktprocsym.definition.deftype=procdef) and
             (([pocall_cdecl,pocall_cppdecl,pocall_stdcall]*aktprocsym.definition.proccalloptions)<>[]) then
-           tstoredsymtable(aktprocsym.definition.parast).set_alignment(target_info.size_of_longint);
+           tparasymtable(aktprocsym.definition.parast).set_alignment(target_info.size_of_longint);
 
       { Call the handler }
         if pointer({$ifndef FPCPROCVAR}@{$endif}proc_direcdata[p].handler)<>nil then
@@ -1888,7 +1888,16 @@ const
 end.
 {
   $Log$
-  Revision 1.27  2001-06-04 18:12:26  peter
+  Revision 1.28  2001-07-01 20:16:16  peter
+    * alignmentinfo record added
+    * -Oa argument supports more alignment settings that can be specified
+      per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
+      RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
+      required alignment and the maximum usefull alignment. The final
+      alignment will be choosen per variable size dependent on these
+      settings
+
+  Revision 1.27  2001/06/04 18:12:26  peter
     * fixed crash with procvar directive parsing. Be carefull as the procvar
       directive parsing uses aktprocsym.definition that is a tprocdef, but
       for procvar the type is tprocvardef. So some fields are not available

+ 32 - 3
compiler/pdecvar.pas

@@ -116,7 +116,8 @@ implementation
          tconstsym : ttypedconstsym;
          { maxsize contains the max. size of a variant }
          { startvarrec contains the start of the variant part of a record }
-         maxsize,maxalignment,startvarrecalign,startvarrecsize : longint;
+         usedalign,
+         maxsize,minalignment,maxalignment,startvarrecalign,startvarrecsize : longint;
          pt : tnode;
          srsym : tsym;
          srsymtable : tsymtable;
@@ -514,7 +515,26 @@ implementation
               symtablestack:=symtablestack.next;
               { we do NOT call symtablestack.insert
                on purpose PM }
-              offset:=align_from_size(symtablestack.datasize,maxalignment);
+              if aktalignment.recordalignmax=-1 then
+               begin
+{$ifdef i386}
+                 if maxalignment>2 then
+                  minalignment:=4
+                 else if maxalignment>1 then
+                  minalignment:=2
+                 else
+                  minalignment:=1;
+{$else}
+{$ifdef m68k}
+                 minalignment:=2;
+{$endif}
+                 minalignment:=1;
+{$endif}
+               end
+              else
+               minalignment:=maxalignment;
+              usedalign:=used_align(maxalignment,minalignment,maxalignment);
+              offset:=align(symtablestack.datasize,usedalign);
               symtablestack.datasize:=offset+unionsymtable.datasize;
               if maxalignment>symtablestack.dataalignment then
                 symtablestack.dataalignment:=maxalignment;
@@ -530,7 +550,16 @@ implementation
 end.
 {
   $Log$
-  Revision 1.17  2001-06-03 21:57:36  peter
+  Revision 1.18  2001-07-01 20:16:16  peter
+    * alignmentinfo record added
+    * -Oa argument supports more alignment settings that can be specified
+      per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
+      RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
+      required alignment and the maximum usefull alignment. The final
+      alignment will be choosen per variable size dependent on these
+      settings
+
+  Revision 1.17  2001/06/03 21:57:36  peter
     + hint directive parsing support
 
   Revision 1.16  2001/04/18 22:01:57  peter

+ 14 - 5
compiler/ptype.pas

@@ -232,7 +232,7 @@ implementation
         ap : tarraydef;
         s : stringid;
         l,v : TConstExprInt;
-        oldaktpackrecords : tpackrecords;
+        oldaktpackrecords : longint;
         hs : string;
         defpos,storepos : tfileposinfo;
 
@@ -545,13 +545,13 @@ implementation
                   array_dec
                 else
                   begin
-                    oldaktpackrecords:=aktpackrecords;
-                    aktpackrecords:=packrecord_1;
+                    oldaktpackrecords:=aktalignment.recordalignmax;
+                    aktalignment.recordalignmax:=1;
                     if token in [_CLASS,_OBJECT] then
                       tt.setdef(object_dec(name,nil))
                     else
                       tt.setdef(record_dec);
-                    aktpackrecords:=oldaktpackrecords;
+                    aktalignment.recordalignmax:=oldaktpackrecords;
                   end;
               end;
             _CLASS,
@@ -599,7 +599,16 @@ implementation
 end.
 {
   $Log$
-  Revision 1.26  2001-06-04 18:06:38  peter
+  Revision 1.27  2001-07-01 20:16:16  peter
+    * alignmentinfo record added
+    * -Oa argument supports more alignment settings that can be specified
+      per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
+      RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
+      required alignment and the maximum usefull alignment. The final
+      alignment will be choosen per variable size dependent on these
+      settings
+
+  Revision 1.26  2001/06/04 18:06:38  peter
     * fix for enum with assignment
 
   Revision 1.25  2001/06/04 11:51:59  peter

+ 27 - 17
compiler/scandir.pas

@@ -119,22 +119,22 @@ implementation
            { Support also the ON and OFF as switch }
            hs:=current_scanner.readid;
            if (hs='ON') then
-            aktpackrecords:=packrecord_4
+            aktalignment.recordalignmax:=4
            else
             if (hs='OFF') then
-             aktpackrecords:=packrecord_1
+             aktalignment.recordalignmax:=1
            else
             Message(scan_w_only_pack_records);
          end
         else
          begin
            case current_scanner.readval of
-             1 : aktpackrecords:=packrecord_1;
-             2 : aktpackrecords:=packrecord_2;
-             4 : aktpackrecords:=packrecord_4;
-             8 : aktpackrecords:=packrecord_8;
-            16 : aktpackrecords:=packrecord_16;
-            32 : aktpackrecords:=packrecord_32;
+             1 : aktalignment.recordalignmax:=1;
+             2 : aktalignment.recordalignmax:=2;
+             4 : aktalignment.recordalignmax:=4;
+             8 : aktalignment.recordalignmax:=8;
+            16 : aktalignment.recordalignmax:=16;
+            32 : aktalignment.recordalignmax:=32;
            else
             Message(scan_w_only_pack_records);
            end;
@@ -546,23 +546,24 @@ implementation
         if not(c in ['0'..'9']) then
          begin
            hs:=current_scanner.readid;
+           { C has the special recordalignmax of -1 }
            if (hs='C') then
-            aktpackrecords:=packrecord_C
+            aktalignment.recordalignmax:=-1
            else
             if (hs='NORMAL') or (hs='DEFAULT') then
-             aktpackrecords:=packrecord_2
+             aktalignment.recordalignmax:=2
            else
             Message(scan_w_only_pack_records);
          end
         else
          begin
            case current_scanner.readval of
-             1 : aktpackrecords:=packrecord_1;
-             2 : aktpackrecords:=packrecord_2;
-             4 : aktpackrecords:=packrecord_4;
-             8 : aktpackrecords:=packrecord_8;
-            16 : aktpackrecords:=packrecord_16;
-            32 : aktpackrecords:=packrecord_32;
+             1 : aktalignment.recordalignmax:=1;
+             2 : aktalignment.recordalignmax:=2;
+             4 : aktalignment.recordalignmax:=4;
+             8 : aktalignment.recordalignmax:=8;
+            16 : aktalignment.recordalignmax:=16;
+            32 : aktalignment.recordalignmax:=32;
            else
             Message(scan_w_only_pack_records);
            end;
@@ -870,7 +871,16 @@ implementation
 end.
 {
   $Log$
-  Revision 1.4  2001-06-03 20:20:27  peter
+  Revision 1.5  2001-07-01 20:16:16  peter
+    * alignmentinfo record added
+    * -Oa argument supports more alignment settings that can be specified
+      per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
+      RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
+      required alignment and the maximum usefull alignment. The final
+      alignment will be choosen per variable size dependent on these
+      settings
+
+  Revision 1.4  2001/06/03 20:20:27  peter
     * Align directive supports also values to be Kylix compatible. It's
       strange because the help of kylix still shows only On and Off as
       possible values, so still support those. On means 4 bytes and Off

+ 23 - 4
compiler/symdef.pas

@@ -2866,8 +2866,13 @@ implementation
          inherited create;
          deftype:=recorddef;
          symtable:=p;
-         symtable.defowner := self;
-         symtable.dataalignment:=packrecordalignment[aktpackrecords];
+         symtable.defowner:=self;
+         { recordalign -1 means C record packing, that starts
+           with an alignment of 1 }
+         if aktalignment.recordalignmax=-1 then
+          symtable.dataalignment:=1
+         else
+          symtable.dataalignment:=aktalignment.recordalignmax;
       end;
 
 
@@ -4067,7 +4072,12 @@ Const local_symtable_index : longint = $8001;
         vmt_offset:=0;
         symtable.datasize:=0;
         symtable.defowner:=self;
-        symtable.dataalignment:=packrecordalignment[aktpackrecords];
+        { recordalign -1 means C record packing, that starts
+          with an alignment of 1 }
+        if aktalignment.recordalignmax=-1 then
+         symtable.dataalignment:=1
+        else
+         symtable.dataalignment:=aktalignment.recordalignmax;
         lastvtableindex:=0;
         set_parent(c);
         objname:=stringdup(n);
@@ -5514,7 +5524,16 @@ Const local_symtable_index : longint = $8001;
 end.
 {
   $Log$
-  Revision 1.35  2001-06-27 21:37:36  peter
+  Revision 1.36  2001-07-01 20:16:16  peter
+    * alignmentinfo record added
+    * -Oa argument supports more alignment settings that can be specified
+      per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
+      RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
+      required alignment and the maximum usefull alignment. The final
+      alignment will be choosen per variable size dependent on these
+      settings
+
+  Revision 1.35  2001/06/27 21:37:36  peter
     * v10 merges
 
   Revision 1.34  2001/06/04 18:05:39  peter

+ 56 - 131
compiler/symsym.pas

@@ -1392,29 +1392,10 @@ implementation
       end;
 
 
-    function  data_align(length : longint) : longint;
-      begin
-         (* this is useless under go32v2 at least
-         because the section are only align to dword
-         if length>8 then
-           data_align:=16
-         else if length>4 then
-           data_align:=8
-         else *)
-         if length>2 then
-           data_align:=4
-         else
-          if length>1 then
-           data_align:=2
-         else
-           data_align:=1;
-      end;
-
-
     procedure tvarsym.insert_in_data;
       var
          varalign,
-         l,ali,modulo : longint;
+         l,modulo : longint;
          storefilepos : tfileposinfo;
       begin
         if (vo_is_external in varoptions) then
@@ -1442,7 +1423,7 @@ implementation
              storefilepos:=aktfilepos;
              aktfilepos:=akttokenpos;
              if (vo_is_thread_var in varoptions) then
-               l:=4
+               l:=target_info.size_of_pointer
              else
                l:=getvaluesize;
              case owner.symtabletype of
@@ -1452,48 +1433,28 @@ implementation
                localsymtable :
                  begin
                    varstate:=vs_declared;
-                   modulo:=owner.datasize and 3;
-{$ifdef m68k}
-                 { word alignment required for motorola }
-                   if (l=1) then
-                    l:=2
-                   else
-{$endif}
-{
-                   if (cs_optimize in aktglobalswitches) and
-                      (aktoptprocessor in [classp5,classp6]) and
-                      (l>=8) and ((owner.datasize and 7)<>0) then
-                     inc(owner.datasize,8-(owner.datasize and 7))
-                   else
-}
-                     begin
-                        if (l>=4) and (modulo<>0) then
-                          inc(l,4-modulo)
-                        else
-                          if (l>=2) and ((modulo and 1)<>0) then
-                            inc(l,2-(modulo and 1));
-                     end;
-                   inc(owner.datasize,l);
-                   address:=owner.datasize;
+                   varalign:=size_2_align(l);
+                   varalign:=used_align(varalign,aktalignment.localalignmin,aktalignment.localalignmax);
+                   address:=align(owner.datasize,varalign)+l;
+                   owner.datasize:=address;
                  end;
                staticsymtable :
                  begin
                    { enable unitialized warning for local symbols }
                    varstate:=vs_declared;
+                   varalign:=size_2_align(l);
+                   varalign:=used_align(varalign,aktalignment.varalignmin,aktalignment.varalignmax);
+                   address:=align(owner.datasize,varalign);
+                   { insert cut for smartlinking or alignment }
                    if (cs_create_smart in aktmoduleswitches) then
-                     bssSegment.concat(Tai_cut.Create);
-                   ali:=data_align(l);
-                   if ali>1 then
-                     begin
-                        modulo:=owner.datasize mod ali;
-                        if modulo>0 then
-                          inc(owner.datasize,ali-modulo);
-                     end;
+                     bssSegment.concat(Tai_cut.Create)
+                   else if (address<>owner.datasize) then
+                     bssSegment.concat(Tai_align.create(varalign));
+                   owner.datasize:=address+l;
 {$ifdef GDB}
                    if cs_debuginfo in aktmoduleswitches then
                       concatstabto(bsssegment);
 {$endif GDB}
-
                    if (cs_create_smart in aktmoduleswitches) or
                       DLLSource or
                       (vo_is_exported in varoptions) or
@@ -1501,29 +1462,26 @@ implementation
                      bssSegment.concat(Tai_datablock.Create_global(mangledname,l))
                    else
                      bssSegment.concat(Tai_datablock.Create(mangledname,l));
-                   { increase datasize }
-                   inc(owner.datasize,l);
                    { this symbol can't be loaded to a register }
                    exclude(varoptions,vo_regable);
                    exclude(varoptions,vo_fpuregable);
                  end;
                globalsymtable :
                  begin
+                   varalign:=size_2_align(l);
+                   varalign:=used_align(varalign,aktalignment.varalignmin,aktalignment.varalignmax);
+                   address:=align(owner.datasize,varalign);
+                   { insert cut for smartlinking or alignment }
                    if (cs_create_smart in aktmoduleswitches) then
-                     bssSegment.concat(Tai_cut.Create);
-                   ali:=data_align(l);
-                   if ali>1 then
-                     begin
-                        modulo:=owner.datasize mod ali;
-                        if modulo>0 then
-                          inc(owner.datasize,ali-modulo);
-                     end;
+                     bssSegment.concat(Tai_cut.Create)
+                   else if (address<>owner.datasize) then
+                     bssSegment.concat(Tai_align.create(varalign));
+                   owner.datasize:=address+l;
 {$ifdef GDB}
                    if cs_debuginfo in aktmoduleswitches then
                      concatstabto(bsssegment);
 {$endif GDB}
                    bssSegment.concat(Tai_datablock.Create_global(mangledname,l));
-                   inc(owner.datasize,l);
                    { this symbol can't be loaded to a register }
                    exclude(varoptions,vo_regable);
                    exclude(varoptions,vo_fpuregable);
@@ -1535,7 +1493,7 @@ implementation
                    exclude(varoptions,vo_regable);
                    exclude(varoptions,vo_fpuregable);
                  { get the alignment size }
-                   if (aktpackrecords=packrecord_C) then
+                   if (aktalignment.recordalignmax=-1) then
                     begin
                       varalign:=vartype.def.alignment;
                       if (varalign>4) and ((varalign mod 4)<>0) and
@@ -1545,7 +1503,7 @@ implementation
                         end;
                       if varalign=0 then
                         varalign:=l;
-                      if (owner.dataalignment<target_info.maxCrecordalignment) then
+                      if (owner.dataalignment<aktalignment.maxCrecordalign) then
                        begin
                          if (varalign>16) and (owner.dataalignment<32) then
                           owner.dataalignment:=32
@@ -1561,67 +1519,28 @@ implementation
                          else if (varalign>1) and (owner.dataalignment<2) then
                           owner.dataalignment:=2;
                        end;
-                      if owner.dataalignment>target_info.maxCrecordalignment then
-                        owner.dataalignment:=target_info.maxCrecordalignment;
+                      owner.dataalignment:=max(owner.dataalignment,aktalignment.maxCrecordalign);
                     end
                    else
                     varalign:=vartype.def.alignment;
                    if varalign=0 then
-                     varalign:=l;
-                 { align record and object fields }
-                   if (varalign=1) or (owner.dataalignment=1) then
-                    begin
-                      address:=owner.datasize;
-                      inc(owner.datasize,l)
-                    end
-                   else if (varalign=2) or (owner.dataalignment=2) then
-                     begin
-                       owner.datasize:=(owner.datasize+1) and (not 1);
-                       address:=owner.datasize;
-                       inc(owner.datasize,l)
-                     end
-                   else if (varalign<=4) or (owner.dataalignment=4) then
-                     begin
-                       owner.datasize:=(owner.datasize+3) and (not 3);
-                       address:=owner.datasize;
-                       inc(owner.datasize,l);
-                     end
-                   else if (varalign<=8) or (owner.dataalignment=8) then
-                     begin
-                       owner.datasize:=(owner.datasize+7) and (not 7);
-                       address:=owner.datasize;
-                       inc(owner.datasize,l);
-                     end
-                         { 12 is needed for C long double support }
-                   else if (varalign<=12) and (owner.dataalignment=12) then
-                     begin
-                       owner.datasize:=((owner.datasize+11) div 12) * 12;
-                       address:=owner.datasize;
-                       inc(owner.datasize,l);
-                     end
-                   else if (varalign<=16) or (owner.dataalignment=16) then
-                     begin
-                       owner.datasize:=(owner.datasize+15) and (not 15);
-                       address:=owner.datasize;
-                       inc(owner.datasize,l);
-                     end
-                   else if (varalign<=32) or (owner.dataalignment=32) then
-                     begin
-                       owner.datasize:=(owner.datasize+31) and (not 31);
-                       address:=owner.datasize;
-                       inc(owner.datasize,l);
-                     end
-                    else
-                     internalerror(1000022);
+                     varalign:=size_2_align(l);
+                   varalign:=used_align(varalign,aktalignment.recordalignmin,owner.dataalignment);
+                   address:=align(owner.datasize,varalign);
+                   owner.datasize:=address+l;
                  end;
                parasymtable :
                  begin
                    { here we need the size of a push instead of the
                      size of the data }
                    l:=getpushsize;
+                   varalign:=size_2_align(l);
                    varstate:=vs_assigned;
+                   { we need the new datasize already aligned so we can't
+                     use the align_address here }
                    address:=owner.datasize;
-                   owner.datasize:=align(owner.datasize+l,target_info.stackalignment);
+                   varalign:=used_align(varalign,owner.dataalignment,owner.dataalignment);
+                   owner.datasize:=align(address+l,varalign);
                  end
                else
                  begin
@@ -1803,7 +1722,7 @@ implementation
     procedure ttypedconstsym.insert_in_data;
       var
         curconstsegment : taasmoutput;
-        l,ali,modulo : longint;
+        address,l,varalign : longint;
         storefilepos : tfileposinfo;
       begin
         storefilepos:=aktfilepos;
@@ -1812,22 +1731,19 @@ implementation
           curconstsegment:=consts
         else
           curconstsegment:=datasegment;
-        if (cs_create_smart in aktmoduleswitches) then
-          curconstSegment.concat(Tai_cut.Create);
         l:=getsize;
-        ali:=data_align(l);
-        if ali>1 then
-          begin
-             curconstSegment.concat(Tai_align.Create(ali));
-             modulo:=owner.datasize mod ali;
-             if modulo>0 then
-               inc(owner.datasize,ali-modulo);
-          end;
-        {  Why was there no owner size update here ??? }
-        inc(owner.datasize,l);
+        varalign:=size_2_align(l);
+        varalign:=used_align(varalign,aktalignment.constalignmin,aktalignment.constalignmax);
+        address:=align(owner.datasize,varalign);
+        { insert cut for smartlinking or alignment }
+        if (cs_create_smart in aktmoduleswitches) then
+          curconstSegment.concat(Tai_cut.Create)
+        else if (address<>owner.datasize) then
+          curconstSegment.concat(Tai_align.create(varalign));
+        owner.datasize:=address+l;
 {$ifdef GDB}
-              if cs_debuginfo in aktmoduleswitches then
-                concatstabto(curconstsegment);
+        if cs_debuginfo in aktmoduleswitches then
+          concatstabto(curconstsegment);
 {$endif GDB}
         if (owner.symtabletype=globalsymtable) then
           begin
@@ -2329,7 +2245,16 @@ implementation
 end.
 {
   $Log$
-  Revision 1.13  2001-05-08 21:06:32  florian
+  Revision 1.14  2001-07-01 20:16:17  peter
+    * alignmentinfo record added
+    * -Oa argument supports more alignment settings that can be specified
+      per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
+      RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
+      required alignment and the maximum usefull alignment. The final
+      alignment will be choosen per variable size dependent on these
+      settings
+
+  Revision 1.13  2001/05/08 21:06:32  florian
     * some more support for widechars commited especially
       regarding type casting and constants
 

+ 33 - 25
compiler/symtable.pas

@@ -81,8 +81,6 @@ interface
           procedure check_forwards;
           procedure checklabels;
           function  needs_init_final : boolean;
-          { change alignment for args  only parasymtable }
-          procedure set_alignment(_alignment : longint);
 {$ifdef CHAINPROCSYMS}
           procedure chainprocsyms;
 {$endif CHAINPROCSYMS}
@@ -132,6 +130,8 @@ interface
        public
           constructor create;
           procedure insert(sym : tsymentry);override;
+          { change alignment for args  only parasymtable }
+          procedure set_alignment(_alignment : longint);
        end;
 
        tabstractunitsymtable = class(tstoredsymtable)
@@ -929,27 +929,6 @@ implementation
       end;
 
 
-    procedure tstoredsymtable.set_alignment(_alignment : longint);
-      var
-         sym : tvarsym;
-         l : longint;
-      begin
-        dataalignment:=_alignment;
-        if (symtabletype<>parasymtable) then
-          internalerror(1111);
-        sym:=tvarsym(symindex.first);
-        datasize:=0;
-        { there can be only varsyms }
-        while assigned(sym) do
-          begin
-             l:=sym.getpushsize;
-             sym.address:=datasize;
-             datasize:=align(datasize+l,dataalignment);
-             sym:=tvarsym(sym.indexnext);
-          end;
-      end;
-
-
     procedure tstoredsymtable.allunitsused;
       begin
          foreach({$ifdef FPCPROCVAR}@{$endif}unitsymbolused);
@@ -1301,7 +1280,7 @@ implementation
       begin
         inherited create('');
         symtabletype:=parasymtable;
-        dataalignment:=4;
+        dataalignment:=aktalignment.paraalign;
       end;
 
 
@@ -1340,6 +1319,26 @@ implementation
       end;
 
 
+    procedure tparasymtable.set_alignment(_alignment : longint);
+      var
+         sym : tvarsym;
+         l : longint;
+      begin
+        dataalignment:=_alignment;
+        sym:=tvarsym(symindex.first);
+        datasize:=0;
+        { there can be only varsyms }
+        while assigned(sym) do
+          begin
+             l:=sym.getpushsize;
+             sym.address:=datasize;
+             datasize:=align(datasize+l,dataalignment);
+             sym:=tvarsym(sym.indexnext);
+          end;
+      end;
+
+
+
 {****************************************************************************
                          TAbstractUnitSymtable
 ****************************************************************************}
@@ -2037,7 +2036,16 @@ implementation
 end.
 {
   $Log$
-  Revision 1.37  2001-06-04 11:53:14  peter
+  Revision 1.38  2001-07-01 20:16:18  peter
+    * alignmentinfo record added
+    * -Oa argument supports more alignment settings that can be specified
+      per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
+      RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
+      required alignment and the maximum usefull alignment. The final
+      alignment will be choosen per variable size dependent on these
+      settings
+
+  Revision 1.37  2001/06/04 11:53:14  peter
     + varargs directive
 
   Revision 1.36  2001/06/03 21:57:38  peter

+ 68 - 4
compiler/systems.pas

@@ -97,6 +97,23 @@ interface
 *****************************************************************************}
 
      type
+       palignmentinfo = ^talignmentinfo;
+       talignmentinfo = packed record
+         procalign,
+         loopalign,
+         jumpalign,
+         constalignmin,
+         constalignmax,
+         varalignmin,
+         varalignmax,
+         localalignmin,
+         localalignmax,
+         paraalign,
+         recordalignmin,
+         recordalignmax,
+         maxCrecordalign : longint;
+       end;
+
        pasminfo = ^tasminfo;
        tasminfo = packed record
           id          : tasm;
@@ -164,9 +181,8 @@ interface
           linkextern   : tld;  { external linker, used by -s }
           ar           : tar;
           res          : tres;
-          endian          : tendian;
-          stackalignment  : word;
-          maxCrecordalignment : word;
+          endian       : tendian;
+          alignment    : talignmentinfo;
           size_of_pointer : byte;
           size_of_longint : byte;
           heapsize,
@@ -211,6 +227,8 @@ interface
     function set_target_asm_by_string(const s : string) : boolean;
     function set_asmmode_by_string(const s:string;var t:tasmmode):boolean;
 
+    procedure UpdateAlignment(var d:talignmentinfo;const s:talignmentinfo);
+
     procedure RegisterTarget(const r:ttargetinfo);
     procedure RegisterAsmMode(const r:tasmmodeinfo);
     procedure RegisterRes(const r:tresinfo);
@@ -335,6 +353,43 @@ begin
 end;
 
 
+procedure UpdateAlignment(var d:talignmentinfo;const s:talignmentinfo);
+begin
+  with d do
+   begin
+     { general update rules:
+       minimum: if higher then update
+       maximum: if lower then update or if undefined then update }
+     if s.procalign>procalign then
+      procalign:=s.procalign;
+     if s.loopalign>loopalign then
+      loopalign:=s.loopalign;
+     if s.jumpalign>jumpalign then
+      jumpalign:=s.jumpalign;
+     if s.constalignmin>constalignmin then
+      constalignmin:=s.constalignmin;
+     if (constalignmax=0) or (s.constalignmax<constalignmax) then
+      constalignmax:=s.constalignmax;
+     if s.varalignmin>varalignmin then
+      varalignmin:=s.varalignmin;
+     if (varalignmax=0) or (s.varalignmax<varalignmax) then
+      varalignmax:=s.varalignmax;
+     if s.localalignmin>localalignmin then
+      localalignmin:=s.localalignmin;
+     if (localalignmax=0) or (s.localalignmax<localalignmax) then
+      localalignmax:=s.localalignmax;
+     if s.paraalign>paraalign then
+      paraalign:=s.paraalign;
+     if s.recordalignmin>recordalignmin then
+      recordalignmin:=s.recordalignmin;
+     if (recordalignmax=0) or (s.recordalignmax<recordalignmax) then
+      recordalignmax:=s.recordalignmax;
+     if (maxCrecordalign=0) or (s.maxCrecordalign<maxCrecordalign) then
+      maxCrecordalign:=s.maxCrecordalign;
+   end;
+end;
+
+
 {****************************************************************************
                               Target registration
 ****************************************************************************}
@@ -575,7 +630,16 @@ finalization
 end.
 {
   $Log$
-  Revision 1.20  2001-06-19 14:43:31  marco
+  Revision 1.21  2001-07-01 20:16:18  peter
+    * alignmentinfo record added
+    * -Oa argument supports more alignment settings that can be specified
+      per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
+      RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
+      required alignment and the maximum usefull alignment. The final
+      alignment will be choosen per variable size dependent on these
+      settings
+
+  Revision 1.20  2001/06/19 14:43:31  marco
    * Fixed ifdef linux bug
 
   Revision 1.19  2001/06/03 20:21:08  peter

+ 26 - 3
compiler/targets/t_beos.pas

@@ -473,8 +473,22 @@ end;
             ar           : ar_gnu_ar;
             res          : res_none;
             endian       : endian_little;
-            stackalignment : 4;
-            maxCrecordalignment : 4;
+            alignment    :
+              (
+                procalign       : 4;
+                loopalign       : 4;
+                jumpalign       : 0;
+                constalignmin   : 0;
+                constalignmax   : 1;
+                varalignmin     : 0;
+                varalignmax     : 1;
+                localalignmin   : 0;
+                localalignmax   : 1;
+                paraalign       : 4;
+                recordalignmin  : 0;
+                recordalignmax  : 2;
+                maxCrecordalign : 4
+              );
             size_of_pointer : 4;
             size_of_longint : 4;
             heapsize     : 256*1024;
@@ -496,7 +510,16 @@ initialization
 end.
 {
   $Log$
-  Revision 1.3  2001-06-28 19:46:25  peter
+  Revision 1.4  2001-07-01 20:16:20  peter
+    * alignmentinfo record added
+    * -Oa argument supports more alignment settings that can be specified
+      per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
+      RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
+      required alignment and the maximum usefull alignment. The final
+      alignment will be choosen per variable size dependent on these
+      settings
+
+  Revision 1.3  2001/06/28 19:46:25  peter
     * added override and virtual for constructors
 
   Revision 1.2  2001/06/03 15:15:31  peter

+ 26 - 3
compiler/targets/t_fbsd.pas

@@ -484,8 +484,22 @@ end;
             ar           : ar_gnu_ar;
             res          : res_none;
             endian       : endian_little;
-            stackalignment : 4;
-            maxCrecordalignment : 4;
+            alignment    :
+              (
+                procalign       : 4;
+                loopalign       : 4;
+                jumpalign       : 0;
+                constalignmin   : 0;
+                constalignmax   : 1;
+                varalignmin     : 0;
+                varalignmax     : 1;
+                localalignmin   : 0;
+                localalignmax   : 1;
+                paraalign       : 4;
+                recordalignmin  : 0;
+                recordalignmax  : 2;
+                maxCrecordalign : 4
+              );
             size_of_pointer : 4;
             size_of_longint : 4;
             heapsize    : 256*1024;
@@ -505,7 +519,16 @@ initialization
 end.
 {
   $Log$
-  Revision 1.7  2001-06-28 19:46:25  peter
+  Revision 1.8  2001-07-01 20:16:20  peter
+    * alignmentinfo record added
+    * -Oa argument supports more alignment settings that can be specified
+      per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
+      RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
+      required alignment and the maximum usefull alignment. The final
+      alignment will be choosen per variable size dependent on these
+      settings
+
+  Revision 1.7  2001/06/28 19:46:25  peter
     * added override and virtual for constructors
 
   Revision 1.6  2001/06/03 15:15:31  peter

+ 26 - 3
compiler/targets/t_go32v1.pas

@@ -226,8 +226,22 @@ end;
             ar           : ar_gnu_ar;
             res          : res_none;
             endian       : endian_little;
-            stackalignment : 2;
-            maxCrecordalignment : 4;
+            alignment    :
+              (
+                procalign       : 4;
+                loopalign       : 0;
+                jumpalign       : 0;
+                constalignmin   : 0;
+                constalignmax   : 1;
+                varalignmin     : 0;
+                varalignmax     : 1;
+                localalignmin   : 0;
+                localalignmax   : 1;
+                paraalign       : 2;
+                recordalignmin  : 0;
+                recordalignmax  : 2;
+                maxCrecordalign : 4
+              );
             size_of_pointer : 4;
             size_of_longint : 4;
             heapsize     : 2048*1024;
@@ -245,7 +259,16 @@ initialization
 end.
 {
   $Log$
-  Revision 1.6  2001-06-28 19:46:25  peter
+  Revision 1.7  2001-07-01 20:16:20  peter
+    * alignmentinfo record added
+    * -Oa argument supports more alignment settings that can be specified
+      per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
+      RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
+      required alignment and the maximum usefull alignment. The final
+      alignment will be choosen per variable size dependent on these
+      settings
+
+  Revision 1.6  2001/06/28 19:46:25  peter
     * added override and virtual for constructors
 
   Revision 1.5  2001/06/03 15:15:31  peter

+ 37 - 20
compiler/targets/t_go32v2.pas

@@ -64,10 +64,7 @@ procedure TLinkerGo32v2.SetDefaultInfo;
 begin
   with Info do
    begin
-      if cs_align in aktglobalswitches then
-        ExeCmd[1]:='ld $SCRIPT $OPT $STRIP -o $EXE'
-      else
-        ExeCmd[1]:='ld -oformat coff-go32-exe $OPT $STRIP -o $EXE @$RES'
+     ExeCmd[1]:='ld $SCRIPT $OPT $STRIP -o $EXE';
    end;
 end;
 
@@ -153,10 +150,12 @@ begin
   WriteResponseFile:=True;
 end;
 
+
 Function TLinkerGo32v2.WriteScript(isdll:boolean) : Boolean;
 Var
   scriptres  : TLinkRes;
   i        : longint;
+  HPath    : TStringListItem;
   s        : string;
   linklibc : boolean;
 begin
@@ -167,21 +166,19 @@ begin
   ScriptRes.Add('OUTPUT_FORMAT("coff-go32-exe")');
   ScriptRes.Add('ENTRY(start)');
 
-{$ifdef dummy}
   { Write path to search libraries }
-  HPath:=current_module.locallibrarysearchpath.First;
+  HPath:=TStringListItem(current_module.locallibrarysearchpath.First);
   while assigned(HPath) do
    begin
-     ScriptRes.Add('SEARCH_PATH("'+GetShortName(HPath^.Data^)+'")');
-     HPath:=HPath^.Next;
+     LinkRes.Add('SEARCH_PATH("'+GetShortName(HPath.Str)+'")');
+     HPath:=TStringListItem(HPath.Next);
    end;
-  HPath:=LibrarySearchPath.First;
+  HPath:=TStringListItem(LibrarySearchPath.First);
   while assigned(HPath) do
    begin
-     ScriptRes.Add('SEARCH_PATH("'+GetShortName(HPath^.Data^)+'")');
-     HPath:=HPath^.Next;
+     LinkRes.Add('SEARCH_PATH("'+GetShortName(HPath.Str)+'")');
+     HPath:=TStringListItem(HPath.Next);
    end;
-{$endif dummy}
 
   ScriptRes.Add('SECTIONS');
   ScriptRes.Add('{');
@@ -289,11 +286,8 @@ begin
   if (cs_link_strip in aktglobalswitches) then
    StripStr:='-s';
 
-  if cs_align in aktglobalswitches then
-    WriteScript(false)
-  else
-    { Write used files and libraries }
-    WriteResponseFile(false);
+  { Write used files and libraries and our own ld script }
+  WriteScript(false);
 
 { Call linker }
   SplitBinCmd(Info.ExeCmd[1],binstr,cmdstr);
@@ -454,8 +448,22 @@ end;
             ar           : ar_gnu_ar;
             res          : res_none;
             endian       : endian_little;
-            stackalignment : 2;
-            maxCrecordalignment : 4;
+            alignment    :
+              (
+                procalign       : 4;
+                loopalign       : 4;
+                jumpalign       : 0;
+                constalignmin   : 0;
+                constalignmax   : 1;
+                varalignmin     : 0;
+                varalignmax     : 1;
+                localalignmin   : 0;
+                localalignmax   : 1;
+                paraalign       : 2;
+                recordalignmin  : 0;
+                recordalignmax  : 2;
+                maxCrecordalign : 4
+              );
             size_of_pointer : 4;
             size_of_longint : 4;
             heapsize     : 2048*1024;
@@ -473,7 +481,16 @@ initialization
 end.
 {
   $Log$
-  Revision 1.7  2001-06-28 19:46:25  peter
+  Revision 1.8  2001-07-01 20:16:20  peter
+    * alignmentinfo record added
+    * -Oa argument supports more alignment settings that can be specified
+      per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
+      RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
+      required alignment and the maximum usefull alignment. The final
+      alignment will be choosen per variable size dependent on these
+      settings
+
+  Revision 1.7  2001/06/28 19:46:25  peter
     * added override and virtual for constructors
 
   Revision 1.6  2001/06/18 20:36:26  peter

+ 26 - 3
compiler/targets/t_linux.pas

@@ -510,8 +510,22 @@ end;
             ar           : ar_gnu_ar;
             res          : res_none;
             endian       : endian_little;
-            stackalignment : 4;
-            maxCrecordalignment : 4;
+            alignment    :
+              (
+                procalign       : 4;
+                loopalign       : 4;
+                jumpalign       : 0;
+                constalignmin   : 0;
+                constalignmax   : 1;
+                varalignmin     : 0;
+                varalignmax     : 1;
+                localalignmin   : 0;
+                localalignmax   : 1;
+                paraalign       : 4;
+                recordalignmin  : 0;
+                recordalignmax  : 2;
+                maxCrecordalign : 4
+              );
             size_of_pointer : 4;
             size_of_longint : 4;
             heapsize     : 256*1024;
@@ -697,7 +711,16 @@ initialization
 end.
 {
   $Log$
-  Revision 1.9  2001-06-28 19:46:25  peter
+  Revision 1.10  2001-07-01 20:16:20  peter
+    * alignmentinfo record added
+    * -Oa argument supports more alignment settings that can be specified
+      per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
+      RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
+      required alignment and the maximum usefull alignment. The final
+      alignment will be choosen per variable size dependent on these
+      settings
+
+  Revision 1.9  2001/06/28 19:46:25  peter
     * added override and virtual for constructors
 
   Revision 1.8  2001/06/04 11:51:06  peter

+ 26 - 3
compiler/targets/t_nwm.pas

@@ -490,8 +490,22 @@ end;
             ar           : ar_gnu_ar;
             res          : res_none;
             endian       : endian_little;
-            stackalignment : 4;
-            maxCrecordalignment : 4;
+            alignment    :
+              (
+                procalign       : 4;
+                loopalign       : 4;
+                jumpalign       : 0;
+                constalignmin   : 0;
+                constalignmax   : 1;
+                varalignmin     : 0;
+                varalignmax     : 1;
+                localalignmin   : 0;
+                localalignmax   : 1;
+                paraalign       : 4;
+                recordalignmin  : 0;
+                recordalignmax  : 2;
+                maxCrecordalign : 4
+              );
             size_of_pointer : 4;
             size_of_longint : 4;
             heapsize     : 256*1024;
@@ -511,7 +525,16 @@ initialization
 end.
 {
   $Log$
-  Revision 1.7  2001-06-28 19:46:25  peter
+  Revision 1.8  2001-07-01 20:16:20  peter
+    * alignmentinfo record added
+    * -Oa argument supports more alignment settings that can be specified
+      per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
+      RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
+      required alignment and the maximum usefull alignment. The final
+      alignment will be choosen per variable size dependent on these
+      settings
+
+  Revision 1.7  2001/06/28 19:46:25  peter
     * added override and virtual for constructors
 
   Revision 1.6  2001/06/03 15:15:32  peter

+ 26 - 3
compiler/targets/t_os2.pas

@@ -548,8 +548,22 @@ end;
             ar           : ar_gnu_ar;
             res          : res_emxbind;
             endian       : endian_little;
-            stackalignment : 4;
-            maxCrecordalignment : 4;
+            alignment    :
+              (
+                procalign       : 4;
+                loopalign       : 4;
+                jumpalign       : 0;
+                constalignmin   : 0;
+                constalignmax   : 1;
+                varalignmin     : 0;
+                varalignmax     : 1;
+                localalignmin   : 0;
+                localalignmax   : 1;
+                paraalign       : 4;
+                recordalignmin  : 0;
+                recordalignmax  : 2;
+                maxCrecordalign : 4
+              );
             size_of_pointer : 4;
             size_of_longint : 4;
             heapsize     : 256*1024;
@@ -569,7 +583,16 @@ initialization
 end.
 {
   $Log$
-  Revision 1.7  2001-06-28 19:46:25  peter
+  Revision 1.8  2001-07-01 20:16:20  peter
+    * alignmentinfo record added
+    * -Oa argument supports more alignment settings that can be specified
+      per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
+      RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
+      required alignment and the maximum usefull alignment. The final
+      alignment will be choosen per variable size dependent on these
+      settings
+
+  Revision 1.7  2001/06/28 19:46:25  peter
     * added override and virtual for constructors
 
   Revision 1.6  2001/06/03 15:15:32  peter

+ 26 - 3
compiler/targets/t_sunos.pas

@@ -513,8 +513,22 @@ end;
             ar           : ar_gnu_ar;
             res          : res_none;
             endian       : endian_little;
-            stackalignment : 4;
-            maxCrecordalignment : 4;
+            alignment    :
+              (
+                procalign       : 4;
+                loopalign       : 4;
+                jumpalign       : 0;
+                constalignmin   : 0;
+                constalignmax   : 1;
+                varalignmin     : 0;
+                varalignmax     : 1;
+                localalignmin   : 0;
+                localalignmax   : 1;
+                paraalign       : 4;
+                recordalignmin  : 0;
+                recordalignmax  : 2;
+                maxCrecordalign : 4
+              );
             size_of_pointer : 4;
             size_of_longint : 4;
             heapsize     : 256*1024;
@@ -534,7 +548,16 @@ initialization
 end.
 {
   $Log$
-  Revision 1.7  2001-06-28 19:46:25  peter
+  Revision 1.8  2001-07-01 20:16:21  peter
+    * alignmentinfo record added
+    * -Oa argument supports more alignment settings that can be specified
+      per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
+      RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
+      required alignment and the maximum usefull alignment. The final
+      alignment will be choosen per variable size dependent on these
+      settings
+
+  Revision 1.7  2001/06/28 19:46:25  peter
     * added override and virtual for constructors
 
   Revision 1.6  2001/06/03 15:15:32  peter

+ 26 - 3
compiler/targets/t_win32.pas

@@ -1432,8 +1432,22 @@ function tDLLScannerWin32.scan(const binname:string):longbool;
             ar           : ar_gnu_arw;
             res          : res_gnu_windres;
             endian       : endian_little;
-            stackalignment : 4;
-            maxCrecordalignment : 16;
+            alignment    :
+              (
+                procalign       : 4;
+                loopalign       : 4;
+                jumpalign       : 0;
+                constalignmin   : 0;
+                constalignmax   : 1;
+                varalignmin     : 0;
+                varalignmax     : 1;
+                localalignmin   : 0;
+                localalignmax   : 1;
+                paraalign       : 4;
+                recordalignmin  : 0;
+                recordalignmax  : 2;
+                maxCrecordalign : 16
+              );
             size_of_pointer : 4;
             size_of_longint : 4;
             heapsize     : 256*1024;
@@ -1456,7 +1470,16 @@ initialization
 end.
 {
   $Log$
-  Revision 1.13  2001-06-28 19:46:25  peter
+  Revision 1.14  2001-07-01 20:16:21  peter
+    * alignmentinfo record added
+    * -Oa argument supports more alignment settings that can be specified
+      per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
+      RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
+      required alignment and the maximum usefull alignment. The final
+      alignment will be choosen per variable size dependent on these
+      settings
+
+  Revision 1.13  2001/06/28 19:46:25  peter
     * added override and virtual for constructors
 
   Revision 1.12  2001/06/18 20:36:26  peter

+ 11 - 2
compiler/temp_gen.pas

@@ -300,7 +300,7 @@ const
       begin
         { align to 4 bytes at least
           otherwise all those subl $2,%esp are meaningless PM }
-        _align:=target_info.stackalignment;
+        _align:=target_info.alignment.localalignmin;
         if _align<4 then
           _align:=4;
         gettempsize:=Align(-lasttemp,_align);
@@ -614,7 +614,16 @@ begin
 end.
 {
   $Log$
-  Revision 1.15  2001-06-02 19:20:10  peter
+  Revision 1.16  2001-07-01 20:16:18  peter
+    * alignmentinfo record added
+    * -Oa argument supports more alignment settings that can be specified
+      per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
+      RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
+      required alignment and the maximum usefull alignment. The final
+      alignment will be choosen per variable size dependent on these
+      settings
+
+  Revision 1.15  2001/06/02 19:20:10  peter
     * allocate at least 4 bytes, also for 0 byte temps. Give a warning
       with extdebug