Browse Source

* 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 24 years ago
parent
commit
b10e754536

+ 16 - 2
compiler/assemble.pas

@@ -1116,7 +1116,12 @@ Implementation
 {$endif GDB}
 {$endif GDB}
            case hp.typ of
            case hp.typ of
              ait_align :
              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 :
              ait_section :
                begin
                begin
                  objectdata.defaultsection(Tai_section(hp).sec);
                  objectdata.defaultsection(Tai_section(hp).sec);
@@ -1515,7 +1520,16 @@ Implementation
 end.
 end.
 {
 {
   $Log$
   $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)
     * -Ur switch (merged)
     * masm fixes (merged)
     * masm fixes (merged)
     * quoted filenames for go32v2 and win32
     * quoted filenames for go32v2 and win32

+ 87 - 28
compiler/cutils.pas

@@ -38,12 +38,15 @@ interface
     function min(a,b : longint) : longint;
     function min(a,b : longint) : longint;
     function max(a,b : longint) : longint;
     function max(a,b : longint) : longint;
     function align(i,a: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 Replace(var s:string;s1:string;const s2:string);
     procedure ReplaceCase(var s:string;const s1,s2:string);
     procedure ReplaceCase(var s:string;const s1,s2:string);
     function upper(const s : string) : string;
     function upper(const s : string) : string;
     function lower(const s : string) : string;
     function lower(const s : string) : string;
+    function trimbspace(const s:string):string;
     function trimspace(const s:string):string;
     function trimspace(const s:string):string;
+    function GetToken(var s:string;endchar:char):string;
     procedure uppervar(var s : string);
     procedure uppervar(var s : string);
     function hexstr(val : cardinal;cnt : byte) : string;
     function hexstr(val : cardinal;cnt : byte) : string;
     function tostru(i:cardinal) : string;
     function tostru(i:cardinal) : string;
@@ -132,31 +135,6 @@ uses
            max:=a;
            max:=a;
       end;
       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;
     function align(i,a:longint):longint;
     {
     {
@@ -167,7 +145,43 @@ uses
         if a<=1 then
         if a<=1 then
          align:=i
          align:=i
         else
         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;
       end;
 
 
 
 
@@ -295,6 +309,22 @@ uses
       end;
       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;
    function trimspace(const s:string):string;
    {
    {
      return s with all leading and ending spaces and tabs removed
      return s with all leading and ending spaces and tabs removed
@@ -312,6 +342,25 @@ uses
      end;
      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;
    function tostr(i : longint) : string;
    {
    {
      return string of value i
      return string of value i
@@ -323,6 +372,7 @@ uses
         tostr:=hs;
         tostr:=hs;
      end;
      end;
 
 
+
    function int64tostr(i : int64) : string;
    function int64tostr(i : int64) : string;
    {
    {
      return string of value i
      return string of value i
@@ -658,7 +708,16 @@ initialization
 end.
 end.
 {
 {
   $Log$
   $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)
     * -Ur switch (merged)
     * masm fixes (merged)
     * masm fixes (merged)
     * quoted filenames for go32v2 and win32
     * quoted filenames for go32v2 and win32

+ 63 - 7
compiler/globals.pas

@@ -165,7 +165,7 @@ interface
         Initsetalloc,                            {0=fixed, 1 =var}
         Initsetalloc,                            {0=fixed, 1 =var}
        {$ENDIF}
        {$ENDIF}
        initpackenum       : longint;
        initpackenum       : longint;
-       initpackrecords    : tpackrecords;
+       initalignment      : talignmentinfo;
        initoptprocessor,
        initoptprocessor,
        initspecificoptprocessor : tprocessors;
        initspecificoptprocessor : tprocessors;
        initasmmode        : tasmmode;
        initasmmode        : tasmmode;
@@ -183,7 +183,7 @@ interface
        {$ENDIF}
        {$ENDIF}
        aktpackenum        : longint;
        aktpackenum        : longint;
        aktmaxfpuregisters : longint;
        aktmaxfpuregisters : longint;
-       aktpackrecords     : tpackrecords;
+       aktalignment       : talignmentinfo;
        aktoptprocessor,
        aktoptprocessor,
        aktspecificoptprocessor : tprocessors;
        aktspecificoptprocessor : tprocessors;
        aktasmmode         : tasmmode;
        aktasmmode         : tasmmode;
@@ -202,8 +202,7 @@ interface
        EntryMemUsed : longint;
        EntryMemUsed : longint;
 {$endif FPC}
 {$endif FPC}
      { parameter switches }
      { parameter switches }
-       debugstop,
-       only_one_pass : boolean;
+       debugstop : boolean;
 {$EndIf EXTDEBUG}
 {$EndIf EXTDEBUG}
        { windows / OS/2 application type }
        { windows / OS/2 application type }
        apptype : tapptype;
        apptype : tapptype;
@@ -276,6 +275,8 @@ interface
     function  string2guid(const s: string; var GUID: TGUID): boolean;
     function  string2guid(const s: string; var GUID: TGUID): boolean;
     function  guid2string(const GUID: TGUID): string;
     function  guid2string(const GUID: TGUID): string;
 
 
+    function UpdateAlignmentStr(s:string;var a:talignmentinfo):boolean;
+
 
 
 implementation
 implementation
 
 
@@ -1060,6 +1061,7 @@ implementation
         SetCompileMode:=b;
         SetCompileMode:=b;
       end;
       end;
 
 
+
     { '('D1:'00000000-'D2:'0000-'D3:'0000-'D4:'0000-000000000000)' }
     { '('D1:'00000000-'D2:'0000-'D3:'0000-'D4:'0000-000000000000)' }
     function string2guid(const s: string; var GUID: TGUID): boolean;
     function string2guid(const s: string; var GUID: TGUID): boolean;
         function ishexstr(const hs: string): boolean;
         function ishexstr(const hs: string): boolean;
@@ -1138,6 +1140,52 @@ implementation
       end;
       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
                                     Init
@@ -1235,6 +1283,7 @@ implementation
         initmoduleswitches:=[cs_extsyntax,cs_browser];
         initmoduleswitches:=[cs_extsyntax,cs_browser];
         initglobalswitches:=[cs_check_unit_name,cs_link_static];
         initglobalswitches:=[cs_check_unit_name,cs_link_static];
         initoutputformat:=as_none;
         initoutputformat:=as_none;
+        fillchar(initalignment,sizeof(talignmentinfo),0);
 {$ifdef i386}
 {$ifdef i386}
         initoptprocessor:=Class386;
         initoptprocessor:=Class386;
         initspecificoptprocessor:=Class386;
         initspecificoptprocessor:=Class386;
@@ -1242,7 +1291,6 @@ implementation
         {$IFDEF testvarsets}
         {$IFDEF testvarsets}
         initsetalloc:=0;
         initsetalloc:=0;
         {$ENDIF}
         {$ENDIF}
-        initpackrecords:=packrecord_2;
         initasmmode:=asmmode_i386_att;
         initasmmode:=asmmode_i386_att;
 {$else not i386}
 {$else not i386}
   {$ifdef m68k}
   {$ifdef m68k}
@@ -1252,7 +1300,6 @@ implementation
         {$IFDEF testvarsets}
         {$IFDEF testvarsets}
          initsetalloc:=0;
          initsetalloc:=0;
         {$ENDIF}
         {$ENDIF}
-        initpackrecords:=packrecord_2;
         initoutputformat:=as_m68k_as;
         initoutputformat:=as_m68k_as;
         initasmmode:=asmmode_m68k_mot;
         initasmmode:=asmmode_m68k_mot;
   {$endif m68k}
   {$endif m68k}
@@ -1284,7 +1331,16 @@ begin
 end.
 end.
 {
 {
   $Log$
   $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)
     * -Ur switch (merged)
     * masm fixes (merged)
     * masm fixes (merged)
     * quoted filenames for go32v2 and win32
     * quoted filenames for go32v2 and win32

+ 12 - 15
compiler/globtype.pas

@@ -109,7 +109,7 @@ interface
          cs_load_gpc_unit,
          cs_load_gpc_unit,
          { optimizer }
          { optimizer }
          cs_regalloc,cs_uncertainopts,cs_littlesize,cs_optimize,
          cs_regalloc,cs_uncertainopts,cs_littlesize,cs_optimize,
-         cs_fastoptimize, cs_slowoptimize,cs_align,
+         cs_fastoptimize, cs_slowoptimize,
          { browser }
          { browser }
          cs_browser_log,
          cs_browser_log,
          { debugger }
          { debugger }
@@ -119,7 +119,7 @@ interface
          cs_asm_regalloc,cs_asm_tempalloc,
          cs_asm_regalloc,cs_asm_tempalloc,
          { linking }
          { linking }
          cs_link_extern,cs_link_static,cs_link_smart,cs_link_shared,cs_link_deffile,
          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;
        tglobalswitches = set of tglobalswitch;
 
 
@@ -164,18 +164,6 @@ interface
          bt_general,bt_type,bt_const,bt_except
          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
     type
        stringid = string[maxidlen];
        stringid = string[maxidlen];
 
 
@@ -220,7 +208,16 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $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
     + hint directive parsing support
 
 
   Revision 1.11  2001/01/20 18:32:52  hajny
   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
         case t.loc of
           LOC_REGISTER,
           LOC_REGISTER,
          LOC_CREGISTER : begin
          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)))
                              exprasmList.concat(Taicpu.Op_reg(A_PUSH,S_L,makereg32(t.register)))
                            else
                            else
                              exprasmList.concat(Taicpu.Op_reg(A_PUSH,S_W,makereg16(t.register)));
                              exprasmList.concat(Taicpu.Op_reg(A_PUSH,S_W,makereg16(t.register)));
@@ -746,7 +746,7 @@ implementation
                          end;
                          end;
                LOC_MEM,
                LOC_MEM,
          LOC_REFERENCE : begin
          LOC_REFERENCE : begin
-                           if target_info.stackalignment=4 then
+                           if aktalignment.paraalign=4 then
                             opsize:=S_L
                             opsize:=S_L
                            else
                            else
                             opsize:=S_W;
                             opsize:=S_W;
@@ -822,7 +822,7 @@ implementation
         if t.is_immediate then
         if t.is_immediate then
           begin
           begin
             if (size=4) or
             if (size=4) or
-               (target_info.stackalignment=4) then
+               (aktalignment.paraalign=4) then
               exprasmList.concat(Taicpu.Op_const(A_PUSH,S_L,t.offset))
               exprasmList.concat(Taicpu.Op_const(A_PUSH,S_L,t.offset))
             else
             else
               exprasmList.concat(Taicpu.Op_const(A_PUSH,S_W,t.offset));
               exprasmList.concat(Taicpu.Op_const(A_PUSH,S_W,t.offset));
@@ -838,7 +838,7 @@ implementation
               end;
               end;
               exprasmList.concat(Taicpu.Op_ref_reg(A_MOVZX,s,
               exprasmList.concat(Taicpu.Op_ref_reg(A_MOVZX,s,
                 newreference(t),R_EDI));
                 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))
                 exprasmList.concat(Taicpu.Op_reg(A_PUSH,S_L,R_EDI))
               else
               else
                 exprasmList.concat(Taicpu.Op_reg(A_PUSH,S_W,R_DI));
                 exprasmList.concat(Taicpu.Op_reg(A_PUSH,S_W,R_DI));
@@ -2404,12 +2404,11 @@ implementation
           end;
           end;
 {$endif GDB}
 {$endif GDB}
 
 
-       { Align, gprof uses 16 byte granularity }
+         { Align, gprof uses 16 byte granularity }
          if (cs_profile in aktmoduleswitches) then
          if (cs_profile in aktmoduleswitches) then
           exprasmList.insert(Tai_align.Create_op(16,$90))
           exprasmList.insert(Tai_align.Create_op(16,$90))
          else
          else
-          if not(cs_littlesize in aktglobalswitches) then
-           exprasmList.insert(Tai_align.Create(16));
+          exprasmList.insert(Tai_align.Create(aktalignment.procalign));
        end;
        end;
        if inlined then
        if inlined then
          load_regvars(exprasmlist,nil);
          load_regvars(exprasmlist,nil);
@@ -2997,7 +2996,16 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $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
     + some widestring stuff added
 
 
   Revision 1.23  2001/04/21 13:33:16  peter
   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
            While (j <= Length(Opt)) Do
              Begin
              Begin
                case opt[j] of
                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];
                  'G' : initglobalswitches:=initglobalswitches-[cs_littlesize];
                  'G' : initglobalswitches:=initglobalswitches-[cs_littlesize];
                  'r' :
                  'r' :
@@ -121,7 +129,16 @@ initialization
 end.
 end.
 {
 {
   $Log$
   $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
     * simplify_ppu is now the default, a recompile of the compiler now
       only compiles pp.pas
       only compiles pp.pas
 
 

+ 13 - 4
compiler/i386/n386cal.pas

@@ -94,7 +94,7 @@ implementation
       begin
       begin
          { set default para_alignment to target_info.stackalignment }
          { set default para_alignment to target_info.stackalignment }
          if para_alignment=0 then
          if para_alignment=0 then
-          para_alignment:=target_info.stackalignment;
+          para_alignment:=aktalignment.paraalign;
 
 
          { push from left to right if specified }
          { push from left to right if specified }
          if push_from_left_to_right and assigned(right) then
          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
          if ([pocall_cdecl,pocall_cppdecl,pocall_stdcall]*procdefinition.proccalloptions)<>[] then
           para_alignment:=4
           para_alignment:=4
          else
          else
-          para_alignment:=target_info.stackalignment;
+          para_alignment:=aktalignment.paraalign;
 
 
          if not assigned(procdefinition) then
          if not assigned(procdefinition) then
           exit;
           exit;
@@ -485,7 +485,7 @@ implementation
                   para_alignment,para_offset);
                   para_alignment,para_offset);
            end;
            end;
          if inlined then
          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
          if ret_in_param(resulttype.def) then
            begin
            begin
               { This must not be counted for C code
               { This must not be counted for C code
@@ -1576,7 +1576,16 @@ begin
 end.
 end.
 {
 {
   $Log$
   $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
     * better const to var checking
 
 
   Revision 1.24  2001/05/19 21:22:53  peter
   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
          if nodetype=whilen then
            emitjmp(C_None,lcont);
            emitjmp(C_None,lcont);
 
 
-
          { align loop target }
          { 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);
          emitlab(lloop);
 
 
          aktcontinuelabel:=lcont;
          aktcontinuelabel:=lcont;
@@ -355,14 +347,7 @@ implementation
            emitjmp(hcond,aktbreaklabel);
            emitjmp(hcond,aktbreaklabel);
 
 
          { align loop target }
          { 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);
          emitlab(l3);
 
 
          { help register must not be in instruction block }
          { help register must not be in instruction block }
@@ -1355,7 +1340,16 @@ begin
 end.
 end.
 {
 {
   $Log$
   $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
     * fixed crash in labelnode
     * easier detection of goto and label in try blocks
     * 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 }
       { copy the element on the stack, slightly complicated }
         if p.nodetype=ordconstn then
         if p.nodetype=ordconstn then
          begin
          begin
-           if target_info.stackalignment=4 then
+           if aktalignment.paraalign=4 then
              exprasmList.concat(Taicpu.Op_const(A_PUSH,S_L,tordconstnode(p).value))
              exprasmList.concat(Taicpu.Op_const(A_PUSH,S_L,tordconstnode(p).value))
            else
            else
              exprasmList.concat(Taicpu.Op_const(A_PUSH,S_W,tordconstnode(p).value));
              exprasmList.concat(Taicpu.Op_const(A_PUSH,S_W,tordconstnode(p).value));
@@ -320,7 +320,7 @@ implementation
                        hr32:=reg8toreg32(hr);
                        hr32:=reg8toreg32(hr);
                      end;
                      end;
                  end;
                  end;
-                 if target_info.stackalignment=4 then
+                 if aktalignment.paraalign=4 then
                    exprasmList.concat(Taicpu.Op_reg(A_PUSH,S_L,hr32))
                    exprasmList.concat(Taicpu.Op_reg(A_PUSH,S_L,hr32))
                  else
                  else
                    exprasmList.concat(Taicpu.Op_reg(A_PUSH,S_W,hr16));
                    exprasmList.concat(Taicpu.Op_reg(A_PUSH,S_W,hr16));
@@ -1472,7 +1472,16 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $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
     * registration of targets and assemblers
 
 
   Revision 1.15  2001/04/13 01:22:19  peter
   Revision 1.15  2001/04/13 01:22:19  peter

+ 12 - 3
compiler/ncal.pas

@@ -1586,9 +1586,9 @@ implementation
          inlineprocsym:=tcallnode(callp).symtableprocentry;
          inlineprocsym:=tcallnode(callp).symtableprocentry;
          retoffset:=-target_info.size_of_pointer; { less dangerous as zero (PM) }
          retoffset:=-target_info.size_of_pointer; { less dangerous as zero (PM) }
          para_offset:=0;
          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
          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 }
          { copy args }
          if assigned(code) then
          if assigned(code) then
            inlinetree:=code.getcopy
            inlinetree:=code.getcopy
@@ -1655,7 +1655,16 @@ begin
 end.
 end.
 {
 {
   $Log$
   $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
     * procvar support for varargs
 
 
   Revision 1.34  2001/06/04 11:48:02  peter
   Revision 1.34  2001/06/04 11:48:02  peter

+ 157 - 110
compiler/options.pas

@@ -27,7 +27,7 @@ unit options;
 interface
 interface
 
 
 uses
 uses
-  globtype,globals,verbose;
+  globtype,globals,verbose,systems;
 
 
 type
 type
   TOption=class
   TOption=class
@@ -40,6 +40,7 @@ type
     ParaUnitPath,
     ParaUnitPath,
     ParaObjectPath,
     ParaObjectPath,
     ParaLibraryPath : TSearchPathList;
     ParaLibraryPath : TSearchPathList;
+    ParaAlignment   : TAlignmentInfo;
     Constructor Create;
     Constructor Create;
     Destructor Destroy;override;
     Destructor Destroy;override;
     procedure WriteLogo;
     procedure WriteLogo;
@@ -72,7 +73,7 @@ uses
 {$else Delphi}
 {$else Delphi}
   dos,
   dos,
 {$endif Delphi}
 {$endif Delphi}
-  version,systems,
+  version,
   cutils,messages
   cutils,messages
 {$ifdef BrowserLog}
 {$ifdef BrowserLog}
   ,browlog
   ,browlog
@@ -356,10 +357,10 @@ begin
                       initglobalswitches:=initglobalswitches+[cs_asm_leave];
                       initglobalswitches:=initglobalswitches+[cs_asm_leave];
                       for j:=1 to length(more) do
                       for j:=1 to length(more) do
                        case more[j] of
                        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];
                                 [cs_asm_leave, cs_asm_source,cs_asm_regalloc, cs_asm_tempalloc];
                        else
                        else
                          IllegalPara(opt);
                          IllegalPara(opt);
@@ -372,30 +373,35 @@ begin
                        IllegalPara(opt);
                        IllegalPara(opt);
                     end;
                     end;
               'b' : begin
               'b' : begin
+                      if UnsetBool(More,0) then
+                       begin
+                         exclude(initmoduleswitches,cs_browser);
+                         exclude(initmoduleswitches,cs_local_browser);
 {$ifdef BrowserLog}
 {$ifdef BrowserLog}
-                      initglobalswitches:=initglobalswitches+[cs_browser_log];
+                         exclude(initglobalswitches,cs_browser_log);
 {$endif}
 {$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}
 {$ifdef BrowserLog}
-                            initglobalswitches:=initglobalswitches-[cs_browser_log];
+                         include(initglobalswitches,cs_browser_log);
 {$endif}
 {$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}
 {$ifdef BrowserLog}
                           browserlog.elements_to_list.insert(more);
                           browserlog.elements_to_list.insert(more);
 {$else}
 {$else}
                           IllegalPara(opt);
                           IllegalPara(opt);
 {$endif}
 {$endif}
                     end;
                     end;
-              'B' : if UnSetBool(more,0) then
-                      do_build:=false
-                    else
-                      do_build:=true;
+              'B' : do_build:=not UnSetBool(more,0);
               'C' : begin
               'C' : begin
                       j := 1;
                       j := 1;
                       while j <= length(more) Do
                       while j <= length(more) Do
@@ -409,49 +415,53 @@ begin
                                   IllegalPara(opt);
                                   IllegalPara(opt);
                                  break;
                                  break;
                                end;
                                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' :
                             'o' :
                               If UnsetBool(More, j) then
                               If UnsetBool(More, j) then
-                                  initlocalswitches:=initlocalswitches-[cs_check_overflow]
+                                exclude(initlocalswitches,cs_check_overflow)
                               Else
                               Else
-                                initlocalswitches:=initlocalswitches+[cs_check_overflow];
+                                include(initlocalswitches,cs_check_overflow);
                             'r' :
                             'r' :
                               If UnsetBool(More, j) then
                               If UnsetBool(More, j) then
-                                 initlocalswitches:=initlocalswitches-[cs_check_range]
+                                exclude(initlocalswitches,cs_check_range)
                               Else
                               Else
-                                initlocalswitches:=initlocalswitches+[cs_check_range];
+                                include(initlocalswitches,cs_check_range);
                             'R' :
                             'R' :
                               If UnsetBool(More, j) then
                               If UnsetBool(More, j) then
-                                initlocalswitches:=initlocalswitches-[cs_check_object_ext]
+                                exclude(initlocalswitches,cs_check_object_ext)
                               Else
                               Else
-                                initlocalswitches:=initlocalswitches+[cs_check_object_ext];
+                                include(initlocalswitches,cs_check_object_ext);
                             's' :
                             's' :
-                               begin
+                              begin
                                  val(copy(more,j+1,length(more)-j),stacksize,code);
                                  val(copy(more,j+1,length(more)-j),stacksize,code);
                                  if (code<>0) or (stacksize>=67107840) or (stacksize<1024) then
                                  if (code<>0) or (stacksize>=67107840) or (stacksize<1024) then
                                   IllegalPara(opt);
                                   IllegalPara(opt);
                                  break;
                                  break;
-                               end;
+                              end;
                             't' :
                             't' :
                                If UnsetBool(More, j) then
                                If UnsetBool(More, j) then
-                                 initlocalswitches:=initlocalswitches-[cs_check_stack]
+                                 exclude(initlocalswitches,cs_check_stack)
                                Else
                                Else
-                                 initlocalswitches:=initlocalswitches+[cs_check_stack];
+                                 include(initlocalswitches,cs_check_stack);
                             'D' :
                             'D' :
                                If UnsetBool(More, j) then
                                If UnsetBool(More, j) then
-                                   initmoduleswitches:=initmoduleswitches-[cs_create_dynamic]
+                                 exclude(initmoduleswitches,cs_create_dynamic)
                                Else
                                Else
-                                 initmoduleswitches:=initmoduleswitches+[cs_create_dynamic];
+                                 include(initmoduleswitches,cs_create_dynamic);
                             'X' :
                             'X' :
                                If UnsetBool(More, j) then
                                If UnsetBool(More, j) then
-                                 initmoduleswitches:=initmoduleswitches-[cs_create_smart]
+                                 exclude(initmoduleswitches,cs_create_smart)
                                Else
                                Else
-                                 initmoduleswitches:=initmoduleswitches+[cs_create_smart];
+                                 include(initmoduleswitches,cs_create_smart);
                             else
                             else
                                IllegalPara(opt);
                                IllegalPara(opt);
                           end;
                           end;
@@ -460,7 +470,7 @@ begin
                     end;
                     end;
               'd' : def_symbol(more);
               'd' : def_symbol(more);
               'D' : begin
               'D' : begin
-                      initglobalswitches:=initglobalswitches+[cs_link_deffile];
+                      include(initglobalswitches,cs_link_deffile);
                       for j:=1 to length(more) do
                       for j:=1 to length(more) do
                        case more[j] of
                        case more[j] of
                         'd' : begin
                         'd' : begin
@@ -495,8 +505,7 @@ begin
                               end;
                               end;
                         'w' : usewindowapi:=true;
                         'w' : usewindowapi:=true;
                         '-' : begin
                         '-' : begin
-                                initglobalswitches:=initglobalswitches-
-                                  [cs_link_deffile];
+                                exclude(initglobalswitches,cs_link_deffile);
                                 usewindowapi:=false;
                                 usewindowapi:=false;
                               end;
                               end;
                        else
                        else
@@ -505,10 +514,10 @@ begin
                     end;
                     end;
               'e' : exepath:=FixPath(More,true);
               'e' : exepath:=FixPath(More,true);
               { Just used by RHIDE }
               { 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
                     else
-                      initglobalswitches:=initglobalswitches-[cs_link_extern];
+                      include(initglobalswitches,cs_link_extern);
               'F' : begin
               'F' : begin
                       c:=more[1];
                       c:=more[1];
                       Delete(more,1,1);
                       Delete(more,1,1);
@@ -547,26 +556,41 @@ begin
               'g' : begin
               'g' : begin
                       if UnsetBool(More, 0) then
                       if UnsetBool(More, 0) then
                         begin
                         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
                         end
                       else
                       else
                        begin
                        begin
 {$ifdef GDB}
 {$ifdef GDB}
-                         initmoduleswitches:=initmoduleswitches+[cs_debuginfo];
+                         include(initmoduleswitches,cs_debuginfo);
                          if not RelocSectionSetExplicitly then
                          if not RelocSectionSetExplicitly then
                            RelocSection:=false;
                            RelocSection:=false;
                          for j:=1 to length(more) do
                          for j:=1 to length(more) do
                           case more[j] of
                           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
                           else
                             IllegalPara(opt);
                             IllegalPara(opt);
                           end;
                           end;
@@ -592,14 +616,8 @@ begin
                      ParaLinkOptions:=ParaLinkOptions+' '+More
                      ParaLinkOptions:=ParaLinkOptions+' '+More
                     else
                     else
                      IllegalPara(opt);
                      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
               'n' : if More='' then
                      begin
                      begin
                        read_configfile:=false;
                        read_configfile:=false;
@@ -618,15 +636,18 @@ begin
                           undef_symbol('FPC_PROFILE');
                           undef_symbol('FPC_PROFILE');
                         end
                         end
                       else
                       else
+                        if Length(More)=0 then
+                          IllegalPara(opt)
+                        else
                         case more[1] of
                         case more[1] of
-                         'g' : if (length(opt)=3) and UnsetBool(more, 1) then
+                         'g' : if UnsetBool(more, 1) then
                                 begin
                                 begin
-                                  initmoduleswitches:=initmoduleswitches-[cs_profile];
+                                  exclude(initmoduleswitches,cs_profile);
                                   undef_symbol('FPC_PROFILE');
                                   undef_symbol('FPC_PROFILE');
                                 end
                                 end
                                else
                                else
                                 begin
                                 begin
-                                  initmoduleswitches:=initmoduleswitches+[cs_profile];
+                                  include(initmoduleswitches,cs_profile);
                                   def_symbol('FPC_PROFILE');
                                   def_symbol('FPC_PROFILE');
                                end;
                                end;
                         else
                         else
@@ -635,9 +656,9 @@ begin
                     end;
                     end;
 {$ifdef Unix}
 {$ifdef Unix}
               'P' : if UnsetBool(More, 0) then
               'P' : if UnsetBool(More, 0) then
-                      initglobalswitches:=initglobalswitches-[cs_asm_pipe]
+                      exclude(initglobalswitches,cs_asm_pipe)
                     else
                     else
-                      initglobalswitches:=initglobalswitches+[cs_asm_pipe];
+                      include(initglobalswitches,cs_asm_pipe);
 {$endif Unix}
 {$endif Unix}
               's' : if UnsetBool(More, 0) then
               's' : if UnsetBool(More, 0) then
                       initglobalswitches:=initglobalswitches-[cs_asm_extern,cs_link_extern]
                       initglobalswitches:=initglobalswitches-[cs_asm_extern,cs_link_extern]
@@ -657,30 +678,27 @@ begin
                         for j:=1 to length(more) do
                         for j:=1 to length(more) do
                          case more[j] of
                          case more[j] of
                           '2' : SetCompileMode('OBJFPC',true);
                           '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);
                           'd' : SetCompileMode('DELPHI',true);
                           'e' : begin
                           'e' : begin
                                   SetErrorFlags(copy(more,j+1,length(more)));
                                   SetErrorFlags(copy(more,j+1,length(more)));
                                   break;
                                   break;
                                 end;
                                 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);
                           'o' : SetCompileMode('TP',true);
                           'p' : SetCompileMode('GPC',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
                           '-' : 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;
                                 end;
                          else
                          else
                           IllegalPara(opt);
                           IllegalPara(opt);
@@ -719,18 +737,16 @@ begin
                                 break;
                                 break;
                               end;
                               end;
 {$endif UNITALIASES}
 {$endif UNITALIASES}
-                        'n' : initglobalswitches:=initglobalswitches-[cs_check_unit_name];
+                        'n' : exclude(initglobalswitches,cs_check_unit_name);
                         'p' : begin
                         'p' : begin
                                 Message2(option_obsolete_switch_use_new,'-Up','-Fu');
                                 Message2(option_obsolete_switch_use_new,'-Up','-Fu');
                                 break;
                                 break;
                               end;
                               end;
                         'r' : do_release:=true;
                         'r' : do_release:=true;
-                        's' : initmoduleswitches:=initmoduleswitches+[cs_compilesystem];
+                        's' : include(initmoduleswitches,cs_compilesystem);
                         '-' : begin
                         '-' : begin
-                                initmoduleswitches:=initmoduleswitches
-                                  - [cs_compilesystem];
-                                initglobalswitches:=initglobalswitches
-                                  + [cs_check_unit_name];
+                                exclude(initmoduleswitches,cs_compilesystem);
+                                exclude(initglobalswitches,cs_check_unit_name);
                               end;
                               end;
                        else
                        else
                          IllegalPara(opt);
                          IllegalPara(opt);
@@ -744,8 +760,7 @@ begin
                       begin
                       begin
                        inc(j);
                        inc(j);
                        case More[j] of
                        case More[j] of
-                        'B': {bind_win32_dll:=true}
-                             begin
+                        'B': begin
                                {  -WB200000 means set trefered base address
                                {  -WB200000 means set trefered base address
                                  to $200000, but does not change relocsection boolean
                                  to $200000, but does not change relocsection boolean
                                  this way we can create both relocatble and
                                  this way we can create both relocatble and
@@ -762,12 +777,18 @@ begin
                                  end;
                                  end;
                                break;
                                break;
                              end;
                              end;
-                        'C': apptype:=app_cui;
+                        'C': if UnsetBool(More, j) then
+                               apptype:=app_gui
+                              else
+                               apptype:=app_cui;
                         'D': ForceDeffileForExport:=not UnsetBool(More, j);
                         'D': ForceDeffileForExport:=not UnsetBool(More, j);
                         'F': apptype:=app_fs;
                         'F': apptype:=app_fs;
-                        'G': apptype:=app_gui;
+                        'G': if UnsetBool(More, j) then
+                               apptype:=app_cui
+                              else
+                               apptype:=app_gui;
                         'N': begin
                         'N': begin
-                               RelocSection:=false;
+                               RelocSection:=UnsetBool(More,j);
                                RelocSectionSetExplicitly:=true;
                                RelocSectionSetExplicitly:=true;
                              end;
                              end;
                         'R': begin
                         'R': begin
@@ -783,35 +804,38 @@ begin
               'X' : begin
               'X' : begin
                       for j:=1 to length(More) do
                       for j:=1 to length(More) do
                        case More[j] of
                        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
                         'D' : begin
                                 def_symbol('FPC_LINK_DYNAMIC');
                                 def_symbol('FPC_LINK_DYNAMIC');
                                 undef_symbol('FPC_LINK_SMART');
                                 undef_symbol('FPC_LINK_SMART');
                                 undef_symbol('FPC_LINK_STATIC');
                                 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;
                                 LinkTypeSetExplicitly:=true;
                               end;
                               end;
                         'S' : begin
                         'S' : begin
                                 def_symbol('FPC_LINK_STATIC');
                                 def_symbol('FPC_LINK_STATIC');
                                 undef_symbol('FPC_LINK_SMART');
                                 undef_symbol('FPC_LINK_SMART');
                                 undef_symbol('FPC_LINK_DYNAMIC');
                                 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;
                                 LinkTypeSetExplicitly:=true;
                               end;
                               end;
                         'X' : begin
                         'X' : begin
                                 def_symbol('FPC_LINK_SMART');
                                 def_symbol('FPC_LINK_SMART');
                                 undef_symbol('FPC_LINK_STATIC');
                                 undef_symbol('FPC_LINK_STATIC');
                                 undef_symbol('FPC_LINK_DYNAMIC');
                                 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;
                                 LinkTypeSetExplicitly:=true;
                               end;
                               end;
                         '-' : begin
                         '-' : 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;
                                 set_default_link_type;
                               end;
                               end;
                        else
                        else
@@ -1208,6 +1232,7 @@ begin
   ParaObjectPath:=TSearchPathList.Create;
   ParaObjectPath:=TSearchPathList.Create;
   ParaUnitPath:=TSearchPathList.Create;
   ParaUnitPath:=TSearchPathList.Create;
   ParaLibraryPath:=TSearchPathList.Create;
   ParaLibraryPath:=TSearchPathList.Create;
+  FillChar(ParaAlignment,sizeof(ParaAlignment),0);
 end;
 end;
 
 
 
 
@@ -1504,11 +1529,24 @@ begin
 { turn off stripping if compiling with debuginfo or profile }
 { turn off stripping if compiling with debuginfo or profile }
   if (cs_debuginfo in initmoduleswitches) or
   if (cs_debuginfo in initmoduleswitches) or
      (cs_profile in initmoduleswitches) then
      (cs_profile in initmoduleswitches) then
-    initglobalswitches:=initglobalswitches-[cs_link_strip];
+    exclude(initglobalswitches,cs_link_strip);
 
 
   if not LinkTypeSetExplicitly then
   if not LinkTypeSetExplicitly then
    set_default_link_type;
    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 }
 { Set defines depending on the target }
   if (target_info.target in [target_i386_GO32V1,target_i386_GO32V2]) then
   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 }
    def_symbol('DPMI'); { MSDOS is not defined in BP when target is DPMI }
@@ -1526,7 +1564,16 @@ finalization
 end.
 end.
 {
 {
   $Log$
   $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
     * patch from Pavel Ozerski to support +/- better
 
 
   Revision 1.45  2001/06/19 14:55:45  jonas
   Revision 1.45  2001/06/19 14:55:45  jonas

+ 14 - 5
compiler/parser.pas

@@ -267,7 +267,7 @@ implementation
          oldaktmoduleswitches : tmoduleswitches;
          oldaktmoduleswitches : tmoduleswitches;
          oldaktfilepos      : tfileposinfo;
          oldaktfilepos      : tfileposinfo;
          oldaktpackenum,oldaktmaxfpuregisters : longint;
          oldaktpackenum,oldaktmaxfpuregisters : longint;
-         oldaktpackrecords  : tpackrecords;
+         oldaktalignment  : talignmentinfo;
          oldaktoutputformat : tasm;
          oldaktoutputformat : tasm;
          oldaktspecificoptprocessor,
          oldaktspecificoptprocessor,
          oldaktoptprocessor : tprocessors;
          oldaktoptprocessor : tprocessors;
@@ -339,7 +339,7 @@ implementation
           end;
           end;
          oldaktlocalswitches:=aktlocalswitches;
          oldaktlocalswitches:=aktlocalswitches;
          oldaktmoduleswitches:=aktmoduleswitches;
          oldaktmoduleswitches:=aktmoduleswitches;
-         oldaktpackrecords:=aktpackrecords;
+         oldaktalignment:=aktalignment;
          oldaktpackenum:=aktpackenum;
          oldaktpackenum:=aktpackenum;
          oldaktmaxfpuregisters:=aktmaxfpuregisters;
          oldaktmaxfpuregisters:=aktmaxfpuregisters;
          oldaktoutputformat:=aktoutputformat;
          oldaktoutputformat:=aktoutputformat;
@@ -403,7 +403,7 @@ implementation
          {$IFDEF Testvarsets}
          {$IFDEF Testvarsets}
          aktsetalloc:=initsetalloc;
          aktsetalloc:=initsetalloc;
          {$ENDIF}
          {$ENDIF}
-         aktpackrecords:=initpackrecords;
+         aktalignment:=initalignment;
          aktpackenum:=initpackenum;
          aktpackenum:=initpackenum;
          aktoutputformat:=initoutputformat;
          aktoutputformat:=initoutputformat;
          aktoptprocessor:=initoptprocessor;
          aktoptprocessor:=initoptprocessor;
@@ -536,7 +536,7 @@ implementation
               move(oldoverloaded_operators,overloaded_operators,sizeof(toverloaded_operators));
               move(oldoverloaded_operators,overloaded_operators,sizeof(toverloaded_operators));
               aktlocalswitches:=oldaktlocalswitches;
               aktlocalswitches:=oldaktlocalswitches;
               aktmoduleswitches:=oldaktmoduleswitches;
               aktmoduleswitches:=oldaktmoduleswitches;
-              aktpackrecords:=oldaktpackrecords;
+              aktalignment:=oldaktalignment;
               aktpackenum:=oldaktpackenum;
               aktpackenum:=oldaktpackenum;
               aktmaxfpuregisters:=oldaktmaxfpuregisters;
               aktmaxfpuregisters:=oldaktmaxfpuregisters;
               aktoutputformat:=oldaktoutputformat;
               aktoutputformat:=oldaktoutputformat;
@@ -617,7 +617,16 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $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
     * support uses <unit> in <file> construction
 
 
   Revision 1.18  2001/05/06 14:49:17  peter
   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 }
        { Adjust positions of args for cdecl or stdcall }
          if (aktprocsym.definition.deftype=procdef) and
          if (aktprocsym.definition.deftype=procdef) and
             (([pocall_cdecl,pocall_cppdecl,pocall_stdcall]*aktprocsym.definition.proccalloptions)<>[]) then
             (([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 }
       { Call the handler }
         if pointer({$ifndef FPCPROCVAR}@{$endif}proc_direcdata[p].handler)<>nil then
         if pointer({$ifndef FPCPROCVAR}@{$endif}proc_direcdata[p].handler)<>nil then
@@ -1888,7 +1888,16 @@ const
 end.
 end.
 {
 {
   $Log$
   $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
     * fixed crash with procvar directive parsing. Be carefull as the procvar
       directive parsing uses aktprocsym.definition that is a tprocdef, but
       directive parsing uses aktprocsym.definition that is a tprocdef, but
       for procvar the type is tprocvardef. So some fields are not available
       for procvar the type is tprocvardef. So some fields are not available

+ 32 - 3
compiler/pdecvar.pas

@@ -116,7 +116,8 @@ implementation
          tconstsym : ttypedconstsym;
          tconstsym : ttypedconstsym;
          { maxsize contains the max. size of a variant }
          { maxsize contains the max. size of a variant }
          { startvarrec contains the start of the variant part of a record }
          { 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;
          pt : tnode;
          srsym : tsym;
          srsym : tsym;
          srsymtable : tsymtable;
          srsymtable : tsymtable;
@@ -514,7 +515,26 @@ implementation
               symtablestack:=symtablestack.next;
               symtablestack:=symtablestack.next;
               { we do NOT call symtablestack.insert
               { we do NOT call symtablestack.insert
                on purpose PM }
                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;
               symtablestack.datasize:=offset+unionsymtable.datasize;
               if maxalignment>symtablestack.dataalignment then
               if maxalignment>symtablestack.dataalignment then
                 symtablestack.dataalignment:=maxalignment;
                 symtablestack.dataalignment:=maxalignment;
@@ -530,7 +550,16 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $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
     + hint directive parsing support
 
 
   Revision 1.16  2001/04/18 22:01:57  peter
   Revision 1.16  2001/04/18 22:01:57  peter

+ 14 - 5
compiler/ptype.pas

@@ -232,7 +232,7 @@ implementation
         ap : tarraydef;
         ap : tarraydef;
         s : stringid;
         s : stringid;
         l,v : TConstExprInt;
         l,v : TConstExprInt;
-        oldaktpackrecords : tpackrecords;
+        oldaktpackrecords : longint;
         hs : string;
         hs : string;
         defpos,storepos : tfileposinfo;
         defpos,storepos : tfileposinfo;
 
 
@@ -545,13 +545,13 @@ implementation
                   array_dec
                   array_dec
                 else
                 else
                   begin
                   begin
-                    oldaktpackrecords:=aktpackrecords;
-                    aktpackrecords:=packrecord_1;
+                    oldaktpackrecords:=aktalignment.recordalignmax;
+                    aktalignment.recordalignmax:=1;
                     if token in [_CLASS,_OBJECT] then
                     if token in [_CLASS,_OBJECT] then
                       tt.setdef(object_dec(name,nil))
                       tt.setdef(object_dec(name,nil))
                     else
                     else
                       tt.setdef(record_dec);
                       tt.setdef(record_dec);
-                    aktpackrecords:=oldaktpackrecords;
+                    aktalignment.recordalignmax:=oldaktpackrecords;
                   end;
                   end;
               end;
               end;
             _CLASS,
             _CLASS,
@@ -599,7 +599,16 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $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
     * fix for enum with assignment
 
 
   Revision 1.25  2001/06/04 11:51:59  peter
   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 }
            { Support also the ON and OFF as switch }
            hs:=current_scanner.readid;
            hs:=current_scanner.readid;
            if (hs='ON') then
            if (hs='ON') then
-            aktpackrecords:=packrecord_4
+            aktalignment.recordalignmax:=4
            else
            else
             if (hs='OFF') then
             if (hs='OFF') then
-             aktpackrecords:=packrecord_1
+             aktalignment.recordalignmax:=1
            else
            else
             Message(scan_w_only_pack_records);
             Message(scan_w_only_pack_records);
          end
          end
         else
         else
          begin
          begin
            case current_scanner.readval of
            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
            else
             Message(scan_w_only_pack_records);
             Message(scan_w_only_pack_records);
            end;
            end;
@@ -546,23 +546,24 @@ implementation
         if not(c in ['0'..'9']) then
         if not(c in ['0'..'9']) then
          begin
          begin
            hs:=current_scanner.readid;
            hs:=current_scanner.readid;
+           { C has the special recordalignmax of -1 }
            if (hs='C') then
            if (hs='C') then
-            aktpackrecords:=packrecord_C
+            aktalignment.recordalignmax:=-1
            else
            else
             if (hs='NORMAL') or (hs='DEFAULT') then
             if (hs='NORMAL') or (hs='DEFAULT') then
-             aktpackrecords:=packrecord_2
+             aktalignment.recordalignmax:=2
            else
            else
             Message(scan_w_only_pack_records);
             Message(scan_w_only_pack_records);
          end
          end
         else
         else
          begin
          begin
            case current_scanner.readval of
            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
            else
             Message(scan_w_only_pack_records);
             Message(scan_w_only_pack_records);
            end;
            end;
@@ -870,7 +871,16 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $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
     * Align directive supports also values to be Kylix compatible. It's
       strange because the help of kylix still shows only On and Off as
       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
       possible values, so still support those. On means 4 bytes and Off

+ 23 - 4
compiler/symdef.pas

@@ -2866,8 +2866,13 @@ implementation
          inherited create;
          inherited create;
          deftype:=recorddef;
          deftype:=recorddef;
          symtable:=p;
          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;
       end;
 
 
 
 
@@ -4067,7 +4072,12 @@ Const local_symtable_index : longint = $8001;
         vmt_offset:=0;
         vmt_offset:=0;
         symtable.datasize:=0;
         symtable.datasize:=0;
         symtable.defowner:=self;
         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;
         lastvtableindex:=0;
         set_parent(c);
         set_parent(c);
         objname:=stringdup(n);
         objname:=stringdup(n);
@@ -5514,7 +5524,16 @@ Const local_symtable_index : longint = $8001;
 end.
 end.
 {
 {
   $Log$
   $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
     * v10 merges
 
 
   Revision 1.34  2001/06/04 18:05:39  peter
   Revision 1.34  2001/06/04 18:05:39  peter

+ 56 - 131
compiler/symsym.pas

@@ -1392,29 +1392,10 @@ implementation
       end;
       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;
     procedure tvarsym.insert_in_data;
       var
       var
          varalign,
          varalign,
-         l,ali,modulo : longint;
+         l,modulo : longint;
          storefilepos : tfileposinfo;
          storefilepos : tfileposinfo;
       begin
       begin
         if (vo_is_external in varoptions) then
         if (vo_is_external in varoptions) then
@@ -1442,7 +1423,7 @@ implementation
              storefilepos:=aktfilepos;
              storefilepos:=aktfilepos;
              aktfilepos:=akttokenpos;
              aktfilepos:=akttokenpos;
              if (vo_is_thread_var in varoptions) then
              if (vo_is_thread_var in varoptions) then
-               l:=4
+               l:=target_info.size_of_pointer
              else
              else
                l:=getvaluesize;
                l:=getvaluesize;
              case owner.symtabletype of
              case owner.symtabletype of
@@ -1452,48 +1433,28 @@ implementation
                localsymtable :
                localsymtable :
                  begin
                  begin
                    varstate:=vs_declared;
                    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;
                  end;
                staticsymtable :
                staticsymtable :
                  begin
                  begin
                    { enable unitialized warning for local symbols }
                    { enable unitialized warning for local symbols }
                    varstate:=vs_declared;
                    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
                    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}
 {$ifdef GDB}
                    if cs_debuginfo in aktmoduleswitches then
                    if cs_debuginfo in aktmoduleswitches then
                       concatstabto(bsssegment);
                       concatstabto(bsssegment);
 {$endif GDB}
 {$endif GDB}
-
                    if (cs_create_smart in aktmoduleswitches) or
                    if (cs_create_smart in aktmoduleswitches) or
                       DLLSource or
                       DLLSource or
                       (vo_is_exported in varoptions) or
                       (vo_is_exported in varoptions) or
@@ -1501,29 +1462,26 @@ implementation
                      bssSegment.concat(Tai_datablock.Create_global(mangledname,l))
                      bssSegment.concat(Tai_datablock.Create_global(mangledname,l))
                    else
                    else
                      bssSegment.concat(Tai_datablock.Create(mangledname,l));
                      bssSegment.concat(Tai_datablock.Create(mangledname,l));
-                   { increase datasize }
-                   inc(owner.datasize,l);
                    { this symbol can't be loaded to a register }
                    { this symbol can't be loaded to a register }
                    exclude(varoptions,vo_regable);
                    exclude(varoptions,vo_regable);
                    exclude(varoptions,vo_fpuregable);
                    exclude(varoptions,vo_fpuregable);
                  end;
                  end;
                globalsymtable :
                globalsymtable :
                  begin
                  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
                    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}
 {$ifdef GDB}
                    if cs_debuginfo in aktmoduleswitches then
                    if cs_debuginfo in aktmoduleswitches then
                      concatstabto(bsssegment);
                      concatstabto(bsssegment);
 {$endif GDB}
 {$endif GDB}
                    bssSegment.concat(Tai_datablock.Create_global(mangledname,l));
                    bssSegment.concat(Tai_datablock.Create_global(mangledname,l));
-                   inc(owner.datasize,l);
                    { this symbol can't be loaded to a register }
                    { this symbol can't be loaded to a register }
                    exclude(varoptions,vo_regable);
                    exclude(varoptions,vo_regable);
                    exclude(varoptions,vo_fpuregable);
                    exclude(varoptions,vo_fpuregable);
@@ -1535,7 +1493,7 @@ implementation
                    exclude(varoptions,vo_regable);
                    exclude(varoptions,vo_regable);
                    exclude(varoptions,vo_fpuregable);
                    exclude(varoptions,vo_fpuregable);
                  { get the alignment size }
                  { get the alignment size }
-                   if (aktpackrecords=packrecord_C) then
+                   if (aktalignment.recordalignmax=-1) then
                     begin
                     begin
                       varalign:=vartype.def.alignment;
                       varalign:=vartype.def.alignment;
                       if (varalign>4) and ((varalign mod 4)<>0) and
                       if (varalign>4) and ((varalign mod 4)<>0) and
@@ -1545,7 +1503,7 @@ implementation
                         end;
                         end;
                       if varalign=0 then
                       if varalign=0 then
                         varalign:=l;
                         varalign:=l;
-                      if (owner.dataalignment<target_info.maxCrecordalignment) then
+                      if (owner.dataalignment<aktalignment.maxCrecordalign) then
                        begin
                        begin
                          if (varalign>16) and (owner.dataalignment<32) then
                          if (varalign>16) and (owner.dataalignment<32) then
                           owner.dataalignment:=32
                           owner.dataalignment:=32
@@ -1561,67 +1519,28 @@ implementation
                          else if (varalign>1) and (owner.dataalignment<2) then
                          else if (varalign>1) and (owner.dataalignment<2) then
                           owner.dataalignment:=2;
                           owner.dataalignment:=2;
                        end;
                        end;
-                      if owner.dataalignment>target_info.maxCrecordalignment then
-                        owner.dataalignment:=target_info.maxCrecordalignment;
+                      owner.dataalignment:=max(owner.dataalignment,aktalignment.maxCrecordalign);
                     end
                     end
                    else
                    else
                     varalign:=vartype.def.alignment;
                     varalign:=vartype.def.alignment;
                    if varalign=0 then
                    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;
                  end;
                parasymtable :
                parasymtable :
                  begin
                  begin
                    { here we need the size of a push instead of the
                    { here we need the size of a push instead of the
                      size of the data }
                      size of the data }
                    l:=getpushsize;
                    l:=getpushsize;
+                   varalign:=size_2_align(l);
                    varstate:=vs_assigned;
                    varstate:=vs_assigned;
+                   { we need the new datasize already aligned so we can't
+                     use the align_address here }
                    address:=owner.datasize;
                    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
                  end
                else
                else
                  begin
                  begin
@@ -1803,7 +1722,7 @@ implementation
     procedure ttypedconstsym.insert_in_data;
     procedure ttypedconstsym.insert_in_data;
       var
       var
         curconstsegment : taasmoutput;
         curconstsegment : taasmoutput;
-        l,ali,modulo : longint;
+        address,l,varalign : longint;
         storefilepos : tfileposinfo;
         storefilepos : tfileposinfo;
       begin
       begin
         storefilepos:=aktfilepos;
         storefilepos:=aktfilepos;
@@ -1812,22 +1731,19 @@ implementation
           curconstsegment:=consts
           curconstsegment:=consts
         else
         else
           curconstsegment:=datasegment;
           curconstsegment:=datasegment;
-        if (cs_create_smart in aktmoduleswitches) then
-          curconstSegment.concat(Tai_cut.Create);
         l:=getsize;
         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}
 {$ifdef GDB}
-              if cs_debuginfo in aktmoduleswitches then
-                concatstabto(curconstsegment);
+        if cs_debuginfo in aktmoduleswitches then
+          concatstabto(curconstsegment);
 {$endif GDB}
 {$endif GDB}
         if (owner.symtabletype=globalsymtable) then
         if (owner.symtabletype=globalsymtable) then
           begin
           begin
@@ -2329,7 +2245,16 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $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
     * some more support for widechars commited especially
       regarding type casting and constants
       regarding type casting and constants
 
 

+ 33 - 25
compiler/symtable.pas

@@ -81,8 +81,6 @@ interface
           procedure check_forwards;
           procedure check_forwards;
           procedure checklabels;
           procedure checklabels;
           function  needs_init_final : boolean;
           function  needs_init_final : boolean;
-          { change alignment for args  only parasymtable }
-          procedure set_alignment(_alignment : longint);
 {$ifdef CHAINPROCSYMS}
 {$ifdef CHAINPROCSYMS}
           procedure chainprocsyms;
           procedure chainprocsyms;
 {$endif CHAINPROCSYMS}
 {$endif CHAINPROCSYMS}
@@ -132,6 +130,8 @@ interface
        public
        public
           constructor create;
           constructor create;
           procedure insert(sym : tsymentry);override;
           procedure insert(sym : tsymentry);override;
+          { change alignment for args  only parasymtable }
+          procedure set_alignment(_alignment : longint);
        end;
        end;
 
 
        tabstractunitsymtable = class(tstoredsymtable)
        tabstractunitsymtable = class(tstoredsymtable)
@@ -929,27 +929,6 @@ implementation
       end;
       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;
     procedure tstoredsymtable.allunitsused;
       begin
       begin
          foreach({$ifdef FPCPROCVAR}@{$endif}unitsymbolused);
          foreach({$ifdef FPCPROCVAR}@{$endif}unitsymbolused);
@@ -1301,7 +1280,7 @@ implementation
       begin
       begin
         inherited create('');
         inherited create('');
         symtabletype:=parasymtable;
         symtabletype:=parasymtable;
-        dataalignment:=4;
+        dataalignment:=aktalignment.paraalign;
       end;
       end;
 
 
 
 
@@ -1340,6 +1319,26 @@ implementation
       end;
       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
                          TAbstractUnitSymtable
 ****************************************************************************}
 ****************************************************************************}
@@ -2037,7 +2036,16 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $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
     + varargs directive
 
 
   Revision 1.36  2001/06/03 21:57:38  peter
   Revision 1.36  2001/06/03 21:57:38  peter

+ 68 - 4
compiler/systems.pas

@@ -97,6 +97,23 @@ interface
 *****************************************************************************}
 *****************************************************************************}
 
 
      type
      type
+       palignmentinfo = ^talignmentinfo;
+       talignmentinfo = packed record
+         procalign,
+         loopalign,
+         jumpalign,
+         constalignmin,
+         constalignmax,
+         varalignmin,
+         varalignmax,
+         localalignmin,
+         localalignmax,
+         paraalign,
+         recordalignmin,
+         recordalignmax,
+         maxCrecordalign : longint;
+       end;
+
        pasminfo = ^tasminfo;
        pasminfo = ^tasminfo;
        tasminfo = packed record
        tasminfo = packed record
           id          : tasm;
           id          : tasm;
@@ -164,9 +181,8 @@ interface
           linkextern   : tld;  { external linker, used by -s }
           linkextern   : tld;  { external linker, used by -s }
           ar           : tar;
           ar           : tar;
           res          : tres;
           res          : tres;
-          endian          : tendian;
-          stackalignment  : word;
-          maxCrecordalignment : word;
+          endian       : tendian;
+          alignment    : talignmentinfo;
           size_of_pointer : byte;
           size_of_pointer : byte;
           size_of_longint : byte;
           size_of_longint : byte;
           heapsize,
           heapsize,
@@ -211,6 +227,8 @@ interface
     function set_target_asm_by_string(const s : string) : boolean;
     function set_target_asm_by_string(const s : string) : boolean;
     function set_asmmode_by_string(const s:string;var t:tasmmode):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 RegisterTarget(const r:ttargetinfo);
     procedure RegisterAsmMode(const r:tasmmodeinfo);
     procedure RegisterAsmMode(const r:tasmmodeinfo);
     procedure RegisterRes(const r:tresinfo);
     procedure RegisterRes(const r:tresinfo);
@@ -335,6 +353,43 @@ begin
 end;
 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
                               Target registration
 ****************************************************************************}
 ****************************************************************************}
@@ -575,7 +630,16 @@ finalization
 end.
 end.
 {
 {
   $Log$
   $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
    * Fixed ifdef linux bug
 
 
   Revision 1.19  2001/06/03 20:21:08  peter
   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;
             ar           : ar_gnu_ar;
             res          : res_none;
             res          : res_none;
             endian       : endian_little;
             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_pointer : 4;
             size_of_longint : 4;
             size_of_longint : 4;
             heapsize     : 256*1024;
             heapsize     : 256*1024;
@@ -496,7 +510,16 @@ initialization
 end.
 end.
 {
 {
   $Log$
   $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
     * added override and virtual for constructors
 
 
   Revision 1.2  2001/06/03 15:15:31  peter
   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;
             ar           : ar_gnu_ar;
             res          : res_none;
             res          : res_none;
             endian       : endian_little;
             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_pointer : 4;
             size_of_longint : 4;
             size_of_longint : 4;
             heapsize    : 256*1024;
             heapsize    : 256*1024;
@@ -505,7 +519,16 @@ initialization
 end.
 end.
 {
 {
   $Log$
   $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
     * added override and virtual for constructors
 
 
   Revision 1.6  2001/06/03 15:15:31  peter
   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;
             ar           : ar_gnu_ar;
             res          : res_none;
             res          : res_none;
             endian       : endian_little;
             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_pointer : 4;
             size_of_longint : 4;
             size_of_longint : 4;
             heapsize     : 2048*1024;
             heapsize     : 2048*1024;
@@ -245,7 +259,16 @@ initialization
 end.
 end.
 {
 {
   $Log$
   $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
     * added override and virtual for constructors
 
 
   Revision 1.5  2001/06/03 15:15:31  peter
   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
 begin
   with Info do
   with Info do
    begin
    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;
 end;
 end;
 
 
@@ -153,10 +150,12 @@ begin
   WriteResponseFile:=True;
   WriteResponseFile:=True;
 end;
 end;
 
 
+
 Function TLinkerGo32v2.WriteScript(isdll:boolean) : Boolean;
 Function TLinkerGo32v2.WriteScript(isdll:boolean) : Boolean;
 Var
 Var
   scriptres  : TLinkRes;
   scriptres  : TLinkRes;
   i        : longint;
   i        : longint;
+  HPath    : TStringListItem;
   s        : string;
   s        : string;
   linklibc : boolean;
   linklibc : boolean;
 begin
 begin
@@ -167,21 +166,19 @@ begin
   ScriptRes.Add('OUTPUT_FORMAT("coff-go32-exe")');
   ScriptRes.Add('OUTPUT_FORMAT("coff-go32-exe")');
   ScriptRes.Add('ENTRY(start)');
   ScriptRes.Add('ENTRY(start)');
 
 
-{$ifdef dummy}
   { Write path to search libraries }
   { Write path to search libraries }
-  HPath:=current_module.locallibrarysearchpath.First;
+  HPath:=TStringListItem(current_module.locallibrarysearchpath.First);
   while assigned(HPath) do
   while assigned(HPath) do
    begin
    begin
-     ScriptRes.Add('SEARCH_PATH("'+GetShortName(HPath^.Data^)+'")');
-     HPath:=HPath^.Next;
+     LinkRes.Add('SEARCH_PATH("'+GetShortName(HPath.Str)+'")');
+     HPath:=TStringListItem(HPath.Next);
    end;
    end;
-  HPath:=LibrarySearchPath.First;
+  HPath:=TStringListItem(LibrarySearchPath.First);
   while assigned(HPath) do
   while assigned(HPath) do
    begin
    begin
-     ScriptRes.Add('SEARCH_PATH("'+GetShortName(HPath^.Data^)+'")');
-     HPath:=HPath^.Next;
+     LinkRes.Add('SEARCH_PATH("'+GetShortName(HPath.Str)+'")');
+     HPath:=TStringListItem(HPath.Next);
    end;
    end;
-{$endif dummy}
 
 
   ScriptRes.Add('SECTIONS');
   ScriptRes.Add('SECTIONS');
   ScriptRes.Add('{');
   ScriptRes.Add('{');
@@ -289,11 +286,8 @@ begin
   if (cs_link_strip in aktglobalswitches) then
   if (cs_link_strip in aktglobalswitches) then
    StripStr:='-s';
    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 }
 { Call linker }
   SplitBinCmd(Info.ExeCmd[1],binstr,cmdstr);
   SplitBinCmd(Info.ExeCmd[1],binstr,cmdstr);
@@ -454,8 +448,22 @@ end;
             ar           : ar_gnu_ar;
             ar           : ar_gnu_ar;
             res          : res_none;
             res          : res_none;
             endian       : endian_little;
             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_pointer : 4;
             size_of_longint : 4;
             size_of_longint : 4;
             heapsize     : 2048*1024;
             heapsize     : 2048*1024;
@@ -473,7 +481,16 @@ initialization
 end.
 end.
 {
 {
   $Log$
   $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
     * added override and virtual for constructors
 
 
   Revision 1.6  2001/06/18 20:36:26  peter
   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;
             ar           : ar_gnu_ar;
             res          : res_none;
             res          : res_none;
             endian       : endian_little;
             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_pointer : 4;
             size_of_longint : 4;
             size_of_longint : 4;
             heapsize     : 256*1024;
             heapsize     : 256*1024;
@@ -697,7 +711,16 @@ initialization
 end.
 end.
 {
 {
   $Log$
   $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
     * added override and virtual for constructors
 
 
   Revision 1.8  2001/06/04 11:51:06  peter
   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;
             ar           : ar_gnu_ar;
             res          : res_none;
             res          : res_none;
             endian       : endian_little;
             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_pointer : 4;
             size_of_longint : 4;
             size_of_longint : 4;
             heapsize     : 256*1024;
             heapsize     : 256*1024;
@@ -511,7 +525,16 @@ initialization
 end.
 end.
 {
 {
   $Log$
   $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
     * added override and virtual for constructors
 
 
   Revision 1.6  2001/06/03 15:15:32  peter
   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;
             ar           : ar_gnu_ar;
             res          : res_emxbind;
             res          : res_emxbind;
             endian       : endian_little;
             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_pointer : 4;
             size_of_longint : 4;
             size_of_longint : 4;
             heapsize     : 256*1024;
             heapsize     : 256*1024;
@@ -569,7 +583,16 @@ initialization
 end.
 end.
 {
 {
   $Log$
   $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
     * added override and virtual for constructors
 
 
   Revision 1.6  2001/06/03 15:15:32  peter
   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;
             ar           : ar_gnu_ar;
             res          : res_none;
             res          : res_none;
             endian       : endian_little;
             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_pointer : 4;
             size_of_longint : 4;
             size_of_longint : 4;
             heapsize     : 256*1024;
             heapsize     : 256*1024;
@@ -534,7 +548,16 @@ initialization
 end.
 end.
 {
 {
   $Log$
   $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
     * added override and virtual for constructors
 
 
   Revision 1.6  2001/06/03 15:15:32  peter
   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;
             ar           : ar_gnu_arw;
             res          : res_gnu_windres;
             res          : res_gnu_windres;
             endian       : endian_little;
             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_pointer : 4;
             size_of_longint : 4;
             size_of_longint : 4;
             heapsize     : 256*1024;
             heapsize     : 256*1024;
@@ -1456,7 +1470,16 @@ initialization
 end.
 end.
 {
 {
   $Log$
   $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
     * added override and virtual for constructors
 
 
   Revision 1.12  2001/06/18 20:36:26  peter
   Revision 1.12  2001/06/18 20:36:26  peter

+ 11 - 2
compiler/temp_gen.pas

@@ -300,7 +300,7 @@ const
       begin
       begin
         { align to 4 bytes at least
         { align to 4 bytes at least
           otherwise all those subl $2,%esp are meaningless PM }
           otherwise all those subl $2,%esp are meaningless PM }
-        _align:=target_info.stackalignment;
+        _align:=target_info.alignment.localalignmin;
         if _align<4 then
         if _align<4 then
           _align:=4;
           _align:=4;
         gettempsize:=Align(-lasttemp,_align);
         gettempsize:=Align(-lasttemp,_align);
@@ -614,7 +614,16 @@ begin
 end.
 end.
 {
 {
   $Log$
   $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
     * allocate at least 4 bytes, also for 0 byte temps. Give a warning
       with extdebug
       with extdebug