Sfoglia il codice sorgente

* reintegrate avr branch into trunk, work on avr is less invasive than I thought so it can be continued in trunk

git-svn-id: trunk@17348 -
florian 14 anni fa
parent
commit
7f0d245ac2

+ 2 - 0
.gitattributes

@@ -6812,6 +6812,8 @@ rtl/embedded/arm/at91sam7x256.pp svneol=native#text/plain
 rtl/embedded/arm/lpc21x4.pp svneol=native#text/plain
 rtl/embedded/arm/stellaris.pp svneol=native#text/plain
 rtl/embedded/arm/stm32f103.pp svneol=native#text/plain
+rtl/embedded/avr/atmega128.pp svneol=native#text/plain
+rtl/embedded/avr/start.inc svneol=native#text/plain
 rtl/embedded/check.inc svneol=native#text/plain
 rtl/embedded/empty.cfg svneol=native#text/plain
 rtl/embedded/rtl.cfg svneol=native#text/plain

+ 53 - 6
compiler/aggas.pas

@@ -93,14 +93,16 @@ interface
        end;
 
 
+     function ReplaceForbiddenChars(const s: string): string;
+
+
 implementation
 
     uses
       SysUtils,
       cutils,cfileutl,systems,
       fmodule,finput,verbose,
-      itcpugas,cpubase
-      ;
+      itcpugas,cpubase;
 
     const
       line_length = 70;
@@ -217,6 +219,17 @@ implementation
         #9'.rva'#9,#9'.secrel32'#9,#9'.quad'#9,#9'.long'#9
       );
 
+    function ReplaceForbiddenChars(const s: string): string;
+      var
+      i : longint;
+      begin
+        Result:=s;
+        for i:=1 to Length(Result) do
+          if Result[i]='$' then
+            Result[i]:='s';
+      end;
+
+
 {****************************************************************************}
 {                          GNU Assembler writer                              }
 {****************************************************************************}
@@ -868,6 +881,9 @@ implementation
                                   end
                                else
                                  s:=tai_const(hp).sym.name;
+{$ifdef avr}
+                               s:=ReplaceForbiddenChars(s);
+{$endif avr}
                                if tai_const(hp).value<>0 then
                                  s:=s+tostr_with_plus(tai_const(hp).value);
                              end
@@ -1045,9 +1061,17 @@ implementation
                   if tai_label(hp).labsym.bind in [AB_GLOBAL,AB_PRIVATE_EXTERN] then
                    begin
                      AsmWrite('.globl'#9);
+{$ifdef avr}
+                     AsmWriteLn(ReplaceForbiddenChars(tai_label(hp).labsym.name));
+{$else avr}
                      AsmWriteLn(tai_label(hp).labsym.name);
+{$endif avr}
                    end;
+{$ifdef avr}
+                  AsmWrite(ReplaceForbiddenChars(tai_label(hp).labsym.name));
+{$else avr}
                   AsmWrite(tai_label(hp).labsym.name);
+{$endif avr}
                   AsmWriteLn(':');
                 end;
              end;
@@ -1057,17 +1081,24 @@ implementation
                if (tai_symbol(hp).sym.bind=AB_PRIVATE_EXTERN) then
                  begin
                    AsmWrite(#9'.private_extern ');
+{$ifdef avr}
+                   AsmWriteln(ReplaceForbiddenChars(tai_symbol(hp).sym.name));
+{$else avr}
                    AsmWriteln(tai_symbol(hp).sym.name);
+{$endif avr}
                  end;
                if (target_info.system = system_powerpc64_linux) and
                  (tai_symbol(hp).sym.typ = AT_FUNCTION) and (cs_profile in current_settings.moduleswitches) then
-                 begin
                  AsmWriteLn('.globl _mcount');
-               end;
+
                if tai_symbol(hp).is_global then
                 begin
                   AsmWrite('.globl'#9);
-                  AsmWriteLn(tai_symbol(hp).sym.name);
+{$ifdef avr}
+                  AsmWriteln(ReplaceForbiddenChars(tai_symbol(hp).sym.name));
+{$else avr}
+                  AsmWriteln(tai_symbol(hp).sym.name);
+{$endif avr}
                 end;
                if (target_info.system = system_powerpc64_linux) and
                  (tai_symbol(hp).sym.typ = AT_FUNCTION) then
@@ -1099,10 +1130,17 @@ implementation
                          AsmWriteLn(',' + sepChar + 'function');
                      end;
                  end;
+{$ifdef avr}
+               if not(tai_symbol(hp).has_value) then
+                 AsmWriteLn(ReplaceForbiddenChars(tai_symbol(hp).sym.name + ':'))
+               else
+                 AsmWriteLn(ReplaceForbiddenChars(tai_symbol(hp).sym.name + '=' + tostr(tai_symbol(hp).value)));
+{$else avr}
                if not(tai_symbol(hp).has_value) then
                  AsmWriteLn(tai_symbol(hp).sym.name + ':')
                else
                  AsmWriteLn(tai_symbol(hp).sym.name + '=' + tostr(tai_symbol(hp).value));
+{$endif avr}
              end;
 {$ifdef arm}
            ait_thumb_func:
@@ -1121,11 +1159,19 @@ implementation
                   AsmWrite(#9'.size'#9);
                   if (target_info.system = system_powerpc64_linux) and (tai_symbol_end(hp).sym.typ = AT_FUNCTION) then
                     AsmWrite('.');
+{$ifdef avr}
+                  AsmWrite(ReplaceForbiddenChars(tai_symbol_end(hp).sym.name));
+{$else avr}
                   AsmWrite(tai_symbol_end(hp).sym.name);
+{$endif avr}
                   AsmWrite(', '+s+' - ');
                   if (target_info.system = system_powerpc64_linux) and (tai_symbol_end(hp).sym.typ = AT_FUNCTION) then
                      AsmWrite('.');
+{$ifdef avr}
+                  AsmWriteLn(ReplaceForbiddenChars(tai_symbol_end(hp).sym.name));
+{$else avr}
                   AsmWriteLn(tai_symbol_end(hp).sym.name);
+{$endif avr}
                 end;
              end;
 
@@ -1145,7 +1191,8 @@ implementation
              end;
 
            ait_force_line,
-           ait_function_name : ;
+           ait_function_name :
+             ;
 
            ait_cutobject :
              begin

+ 20 - 8
compiler/avr/aasmcpu.pas

@@ -209,14 +209,14 @@ implementation
 
     function taicpu.spilling_get_operation_type(opnr: longint): topertype;
       begin
-        result := operand_read;
+        result:=operand_read;
         case opcode of
-          A_CP,A_CPC,A_CPI :
+          A_CP,A_CPC,A_CPI,A_PUSH :
             ;
           else
             begin
-              if opnr=ops-1 then
-                result := operand_write;
+              if opnr=0 then
+                result:=operand_write;
             end;
         end;
       end;
@@ -226,9 +226,15 @@ implementation
       begin
         case getregtype(r) of
           R_INTREGISTER :
-            result:=taicpu.op_ref_reg(A_LD,ref,r);
+            if ref.offset<>0 then
+              result:=taicpu.op_reg_ref(A_LDD,r,ref)
+            else
+              result:=taicpu.op_reg_ref(A_LD,r,ref);
           R_ADDRESSREGISTER :
-            result:=taicpu.op_ref_reg(A_LD,ref,r);
+            if ref.offset<>0 then
+              result:=taicpu.op_reg_ref(A_LDD,r,ref)
+            else
+              result:=taicpu.op_reg_ref(A_LD,r,ref);
           else
             internalerror(200401041);
         end;
@@ -239,9 +245,15 @@ implementation
       begin
         case getregtype(r) of
           R_INTREGISTER :
-            result:=taicpu.op_reg_ref(A_ST,r,ref);
+            if ref.offset<>0 then
+              result:=taicpu.op_ref_reg(A_STD,ref,r)
+            else
+              result:=taicpu.op_ref_reg(A_ST,ref,r);
           R_ADDRESSREGISTER :
-            result:=taicpu.op_reg_ref(A_ST,r,ref);
+            if ref.offset<>0 then
+              result:=taicpu.op_ref_reg(A_STD,ref,r)
+            else
+              result:=taicpu.op_ref_reg(A_ST,ref,r);
           else
             internalerror(200401041);
         end;

+ 102 - 57
compiler/avr/agavrgas.pas

@@ -29,13 +29,18 @@ unit agavrgas;
   interface
 
     uses
+       globtype,
        aasmtai,aasmdata,
        aggas,
        cpubase;
 
     type
+
+      { TAVRGNUAssembler }
+
       TAVRGNUAssembler=class(TGNUassembler)
         constructor create(smart: boolean); override;
+       function MakeCmdLine: TCmdStr; override;
       end;
 
      TAVRInstrWriter=class(TCPUInstrWriter)
@@ -51,6 +56,7 @@ unit agavrgas;
        assemble,
        aasmcpu,
        itcpugas,
+       cpuinfo,
        cgbase,cgutils;
 
 {****************************************************************************}
@@ -68,69 +74,102 @@ unit agavrgas;
 {                  Helper routines for Instruction Writer                    }
 {****************************************************************************}
 
-    function getreferencestring(var ref : treference) : string;
-      var
-        s : string;
-      begin
-         with ref do
-          begin
-{$ifdef extdebug}
-            // if base=NR_NO then
-            //   internalerror(200308292);
-
-            // if ((index<>NR_NO) or (shiftmode<>SM_None)) and ((offset<>0) or (symbol<>nil)) then
-            //   internalerror(200308293);
-{$endif extdebug}
-
-            if assigned(symbol) then
-              begin
-                s:=symbol.name;
-                if offset<0 then
-                  s:=s+tostr(offset)
-                else if offset>0 then
-                  s:=s+'+'+tostr(offset);
-              end
-            else
-              begin
-                s:=gas_regname(base);
-              end;
 
-          end;
-        getreferencestring:=s;
-      end;
+    Procedure TAVRInstrWriter.WriteInstruction(hp : tai);
+
+      function getreferencestring(var ref : treference) : string;
+        var
+          s : string;
+        begin
+           with ref do
+            begin
+  {$ifdef extdebug}
+              // if base=NR_NO then
+              //   internalerror(200308292);
+
+              // if ((index<>NR_NO) or (shiftmode<>SM_None)) and ((offset<>0) or (symbol<>nil)) then
+              //   internalerror(200308293);
+  {$endif extdebug}
+              if index<>NR_NO then
+                internalerror(2011021701)
+              else if base<>NR_NO then
+                begin
+                  if addressmode=AM_PREDRECEMENT then
+                    s:='-'
+                  else
+                    s:='';
+                  case base of
+                    NR_R26:
+                      s:=s+'X';
+                    NR_R28:
+                      s:=s+'Y';
+                    NR_R30:
+                      s:=s+'Z';
+                    else
+                      s:=gas_regname(base);
+                  end;
+                  if addressmode=AM_POSTINCREMENT then
+                    s:=s+'+';
+
+                  if offset>0 then
+                    s:=s+'+'+tostr(offset)
+                  else if offset<0 then
+                    s:=s+tostr(offset)
+                end
+              else if assigned(symbol) or (offset<>0) then
+                begin
+                  if assigned(symbol) then
+                    s:=ReplaceForbiddenChars(symbol.name)
+                  else
+                     s:='';
+
+                  if offset<0 then
+                    s:=s+tostr(offset)
+                  else if offset>0 then
+                    s:=s+'+'+tostr(offset);
+                  case refaddr of
+                    addr_hi8:
+                      s:='hi8('+s+')';
+                    addr_lo8:
+                      s:='lo8('+s+')';
+                    else
+                      s:='('+s+')';
+                  end;
+                end;
+            end;
+          getreferencestring:=s;
+        end;
 
 
-    function getopstr(const o:toper) : string;
-      var
-        hs : string;
-        first : boolean;
-        r : tsuperregister;
-      begin
-        case o.typ of
-          top_reg:
-            getopstr:=gas_regname(o.reg);
-          top_const:
-            getopstr:='#'+tostr(longint(o.val));
-          top_ref:
-            if o.ref^.refaddr=addr_full then
-              begin
-                hs:=o.ref^.symbol.name;
-                if o.ref^.offset>0 then
-                 hs:=hs+'+'+tostr(o.ref^.offset)
-                else
-                 if o.ref^.offset<0 then
-                  hs:=hs+tostr(o.ref^.offset);
-                getopstr:=hs;
-              end
+      function getopstr(const o:toper) : string;
+        var
+          hs : string;
+          first : boolean;
+          r : tsuperregister;
+        begin
+          case o.typ of
+            top_reg:
+              getopstr:=gas_regname(o.reg);
+            top_const:
+              getopstr:=tostr(longint(o.val));
+            top_ref:
+              if o.ref^.refaddr=addr_full then
+                begin
+                  hs:=ReplaceForbiddenChars(o.ref^.symbol.name);
+                  if o.ref^.offset>0 then
+                   hs:=hs+'+'+tostr(o.ref^.offset)
+                  else
+                   if o.ref^.offset<0 then
+                    hs:=hs+tostr(o.ref^.offset);
+                  getopstr:=hs;
+                end
+              else
+                getopstr:=getreferencestring(o.ref^);
             else
-              getopstr:=getreferencestring(o.ref^);
-          else
-            internalerror(2002070604);
+              internalerror(2002070604);
+          end;
         end;
-      end;
-
 
-    Procedure TAVRInstrWriter.WriteInstruction(hp : tai);
     var op: TAsmOp;
         s: string;
         i: byte;
@@ -151,6 +190,12 @@ unit agavrgas;
     end;
 
 
+    function TAVRGNUAssembler.MakeCmdLine: TCmdStr;
+      begin
+        result := '-mmcu='+lower(cputypestr[current_settings.cputype])+' '+inherited MakeCmdLine;
+      end;
+
+
     const
        as_arm_gas_info : tasminfo =
           (

+ 37 - 1
compiler/avr/aoptcpu.pas

@@ -40,7 +40,7 @@ Type
 Implementation
 
   uses
-    aasmbase,aasmcpu;
+    aasmbase,aasmcpu,cgbase;
 
   function CanBeCond(p : tai) : boolean;
     begin
@@ -53,8 +53,44 @@ Implementation
       next1: tai;
     begin
       result := false;
+      case p.typ of
+        ait_instruction:
+          begin
+            case taicpu(p).opcode of
+              A_MOV:
+                begin
+                  { fold
+                    mov reg2,reg0
+                    mov reg3,reg1
+                    to
+                    movw reg2,reg0
+                  }
+                  if (taicpu(p).ops=2) and
+                     (taicpu(p).oper[0]^.typ = top_reg) and
+                     (taicpu(p).oper[1]^.typ = top_reg) and
+                     getnextinstruction(p,next1) and
+                     (next1.typ = ait_instruction) and
+                     (taicpu(next1).opcode = A_MOV) and
+                     (taicpu(next1).ops=2) and
+                     (taicpu(next1).oper[0]^.typ = top_reg) and
+                     (taicpu(next1).oper[1]^.typ = top_reg) and
+                     (getsupreg(taicpu(next1).oper[0]^.reg)=getsupreg(taicpu(p).oper[0]^.reg)+1) and
+                     ((getsupreg(taicpu(p).oper[0]^.reg) mod 2)=0) and
+                     ((getsupreg(taicpu(p).oper[1]^.reg) mod 2)=0) and
+                     (getsupreg(taicpu(next1).oper[1]^.reg)=getsupreg(taicpu(p).oper[1]^.reg)+1) then
+                    begin
+                      taicpu(p).opcode:=A_MOVW;
+                      asml.remove(next1);
+                      next1.free;
+                      result := true;
+                    end;
+                end;
+            end;
+          end;
+      end;
     end;
 
+
   procedure TCpuAsmOptimizer.PeepHoleOptPass2;
     begin
     end;

File diff suppressed because it is too large
+ 513 - 130
compiler/avr/cgcpu.pas


+ 25 - 6
compiler/avr/cpubase.pas

@@ -44,7 +44,7 @@ unit cpubase;
 
     type
       TAsmOp=(A_None,
-        A_ADD,A_ADC,A_ADIW,A_SUB,A_SUBI,A_SBC,A_SBCI,A_SBIW,A_AND,A_ANDI,
+        A_ADD,A_ADC,A_ADIW,A_SUB,A_SUBI,A_SBC,A_SBCI,A_SBRC,A_SBRS,A_CLC,A_SEC,A_SBIW,A_AND,A_ANDI,
         A_OR,A_ORI,A_EOR,A_COM,A_NEG,A_SBR,A_CBR,A_INC,A_DEC,A_TST,A_CLR,
         A_SER,A_MUL,A_MULS,A_FMUL,A_FMULS,A_FMULSU,A_RJMP,A_IJMP,
         A_EIJMP,A_JMP,A_RCALL,A_ICALL,R_EICALL,A_CALL,A_RET,A_RETI,A_CPSE,
@@ -121,7 +121,7 @@ unit cpubase;
         {$i ravrdwa.inc}
       );
       { registers which may be destroyed by calls }
-      VOLATILE_INTREGISTERS = [RS_R18..RS_R27,RS_R30..RS_R31];
+      VOLATILE_INTREGISTERS = [RS_R0,RS_R1,RS_R8..RS_R27,RS_R30,RS_R31];
       VOLATILE_FPUREGISTERS = [];
 
     type
@@ -259,8 +259,8 @@ unit cpubase;
       NR_STACK_POINTER_REG = NR_R13;
       RS_STACK_POINTER_REG = RS_R13;
       { Frame pointer register }
-      RS_FRAME_POINTER_REG = RS_R11;
-      NR_FRAME_POINTER_REG = NR_R11;
+      RS_FRAME_POINTER_REG = RS_R28;
+      NR_FRAME_POINTER_REG = NR_R28;
       { Register for addressing absolute data in a position independant way,
         such as in PIC code. The exact meaning is ABI specific. For
         further information look at GCC source : PIC_OFFSET_TABLE_REGNUM
@@ -306,8 +306,10 @@ unit cpubase;
         This value can be deduced from the CALLED_USED_REGISTERS array in the
         GCC source.
       }
-      saved_standard_registers : array[0..6] of tsuperregister =
-        (RS_R4,RS_R5,RS_R6,RS_R7,RS_R8,RS_R9,RS_R10);
+      { on avr, gen_entry/gen_exit code saves/restores registers, so
+        we don't need this array }
+      saved_standard_registers : array[0..0] of tsuperregister =
+        (RS_INVALID);
       { Required parameter alignment when calling a routine declared as
         stdcall and cdecl. The alignment value should be the one defined
         by GCC or the target ABI.
@@ -341,6 +343,11 @@ unit cpubase;
     { returns the next virtual register }
     function GetNextReg(const r : TRegister) : TRegister;
 
+    { returns the last virtual register }
+    function GetLastReg(const r : TRegister) : TRegister;
+
+    function GetOffsetReg(const r : TRegister;ofs : shortint) : TRegister;
+
   implementation
 
     uses
@@ -469,4 +476,16 @@ unit cpubase;
         result:=TRegister(longint(r)+1);
       end;
 
+
+    function GetLastReg(const r: TRegister): TRegister;
+      begin
+        result:=TRegister(longint(r)-1);
+      end;
+
+
+    function GetOffsetReg(const r: TRegister;ofs : shortint): TRegister;
+      begin
+        result:=TRegister(longint(r)+ofs);
+      end;
+
 end.

+ 47 - 2
compiler/avr/cpuinfo.pas

@@ -32,8 +32,30 @@ Type
    { possible supported processors for this target }
    tcputype =
       (cpu_none,
-       cpu_avr
+       cpu_avr1,
+       cpu_avr2,
+       cpu_avr25,
+       cpu_avr3,
+       cpu_avr31,
+       cpu_avr35,
+       cpu_avr4,
+       cpu_avr5,
+       cpu_avr51,
+       cpu_avr6
       );
+
+   tcpuflags =
+      (AVR_HAVE_JMP_CALL,
+       AVR_HAVE_MOVW,
+       AVR_HAVE_LPMX,
+       AVR_HAVE_MUL,
+       AVR_HAVE_RAMPZ,
+       AVR_HAVE_ELPM,
+       AVR_HAVE_ELPMX,
+       AVR_2_BYTE_PC,
+       AVR_3_BYTE_PC
+      );
+
    tfputype =
      (fpu_none,
       fpu_soft,
@@ -72,7 +94,16 @@ Const
    ];
 
    cputypestr : array[tcputype] of string[5] = ('',
-     'AVR'
+     'AVR1',
+     'AVR2',
+     'AVR25',
+     'AVR3',
+     'AVR31',
+     'AVR35',
+     'AVR4',
+     'AVR5',
+     'AVR51',
+     'AVR6'
    );
 
    fputypestr : array[tfputype] of string[6] = (
@@ -112,6 +143,20 @@ Const
      [cs_opt_regvar,cs_opt_stackframe,cs_opt_tailrecursion];
    level3optimizerswitches = genericlevel3optimizerswitches + level2optimizerswitches + [{,cs_opt_loopunroll}];
 
+   cpu_capabilities : array[tcputype] of set of tcpuflags =
+     ( { cpu_none } [],
+       { cpu_avr1 } [],
+       { cpu_avr2 } [],
+       { cpu_avr25 } [],
+       { cpu_avr3 } [],
+       { cpu_avr31 } [],
+       { cpu_avr35 } [],
+       { cpu_avr4 } [],
+       { cpu_avr5 } [],
+       { cpu_avr51 } [],
+       { cpu_avr6 } []
+     );
+
 Implementation
 
 end.

+ 12 - 10
compiler/avr/cpupara.pas

@@ -84,17 +84,17 @@ unit cpupara;
           begin
             size:=OS_INT;
             { the four first parameters are passed into registers }
-            if nr<=4 then
+            if nr<=9 then
               begin
                 loc:=LOC_REGISTER;
-                register:=newreg(R_INTREGISTER,RS_R0+nr-1,R_SUBWHOLE);
+                register:=newreg(R_INTREGISTER,RS_R25-(nr-1)*2,R_SUBWHOLE);
               end
             else
               begin
                 { the other parameters are passed on the stack }
                 loc:=LOC_REFERENCE;
                 reference.index:=NR_STACK_POINTER_REG;
-                reference.offset:=(nr-5)*4;
+                reference.offset:=(nr-10)*2;
               end;
           end;
       end;
@@ -200,13 +200,14 @@ unit cpupara;
 
     procedure tavrparamanager.init_values(var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword);
       begin
-        curintreg:=RS_R0;
+        curintreg:=RS_R25;
         curfloatreg:=RS_INVALID;
         curmmreg:=RS_INVALID;
         cur_stack_offset:=0;
       end;
 
 
+    { TODO : fix tavrparamanager.create_paraloc_info_intern }
     function tavrparamanager.create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras: tparalist;
         var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword):longint;
 
@@ -225,7 +226,7 @@ unit cpupara;
         begin
           { In case of po_delphi_nested_cc, the parent frame pointer
             is always passed on the stack. }
-           if (nextintreg<=RS_R3) and
+           if (nextintreg>RS_R8) and
               (not(vo_is_parentfp in hp.varoptions) or
                not(po_delphi_nested_cc in p.procoptions)) then
              begin
@@ -238,7 +239,7 @@ unit cpupara;
                paraloc^.loc:=LOC_REFERENCE;
                paraloc^.reference.index:=NR_STACK_POINTER_REG;
                paraloc^.reference.offset:=stack_offset;
-               inc(stack_offset,4);
+               dec(stack_offset,2);
             end;
         end;
 
@@ -265,7 +266,7 @@ unit cpupara;
                 paraloc:=hp.paraloc[side].add_location;
                 { hack: the paraloc must be valid, but is not actually used }
                 paraloc^.loc:=LOC_REGISTER;
-                paraloc^.register:=NR_R0;
+                paraloc^.register:=NR_R25;
                 paraloc^.size:=OS_ADDR;
                 break;
               end;
@@ -333,11 +334,11 @@ unit cpupara;
                       begin
                         { this is not abi compliant
                           why? (FK) }
-                        if nextintreg<=RS_R3 then
+                        if nextintreg>=RS_R8 then
                           begin
                             paraloc^.loc:=LOC_REGISTER;
                             paraloc^.register:=newreg(R_INTREGISTER,nextintreg,R_SUBWHOLE);
-                            inc(nextintreg);
+                            dec(nextintreg);
                           end
                         else
                           begin
@@ -374,7 +375,7 @@ unit cpupara;
                      if paraloc^.loc=LOC_REFERENCE then
                        begin
                          paraloc^.reference.index:=NR_FRAME_POINTER_REG;
-                         inc(paraloc^.reference.offset,4);
+                         inc(paraloc^.reference.offset,2);
                        end;
                    end;
                  dec(paralen,tcgsize2size[paraloc^.size]);
@@ -408,6 +409,7 @@ unit cpupara;
       end;
 
 
+    { TODO : fix tavrparamanager.get_funcretloc }
     function  tavrparamanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara;
       var
         retcgsize : tcgsize;

+ 2 - 14
compiler/avr/cpupi.pas

@@ -33,7 +33,6 @@ unit cpupi;
 
     type
        tavrprocinfo = class(tcgprocinfo)
-          floatregstart : aint;
           // procedure handle_body_start;override;
           // procedure after_pass1;override;
           procedure set_first_temp_offset;override;
@@ -54,26 +53,14 @@ unit cpupi;
 
     procedure tavrprocinfo.set_first_temp_offset;
       begin
-        { We allocate enough space to save all registers because we can't determine
-          the necessary space because the used registers aren't known before
-          secondpass is run. Even worse, patching
-          the local offsets after generating the code could cause trouble because
-          "shifter" constants could change to non-"shifter" constants. This
-          is especially a problem when taking the address of a local. For now,
-          this extra memory should hurt less than generating all local contants with offsets
-          >256 as non shifter constants }
         if tg.direction = -1 then
-          tg.setfirsttemp(-12-28)
+          tg.setfirsttemp(0)
         else
           tg.setfirsttemp(maxpushedparasize);
       end;
 
 
     function tavrprocinfo.calc_stackframe_size:longint;
-      var
-         firstfloatreg,lastfloatreg,
-         r : byte;
-         floatsavesize : aword;
       begin
         maxpushedparasize:=align(maxpushedparasize,max(current_settings.alignment.localalignmin,4));
       end;
@@ -82,3 +69,4 @@ unit cpupi;
 begin
    cprocinfo:=tavrprocinfo;
 end.
+

+ 1 - 1
compiler/avr/itcpugas.pas

@@ -35,7 +35,7 @@ interface
       processor manufacturer.
     }
     gas_op2str : op2strtable = ('',
-        'add','adc','adiw','sub','subi','sbc','sbci','sbiw','and','andi',
+        'add','adc','adiw','sub','subi','sbc','sbci','sbrc','sbrs','clc','sec','sbiw','and','andi',
         'or','ori','eor','com','neg','sbr','cbr','inc','dec','tst','clr',
         'ser','mul','muls','fmul','fmuls','fmulsu','rjmp','ijmp',
         'eijmp','jmp','rcall','icall','eicall','call','ret','reti','cpse',

+ 26 - 8
compiler/avr/navradd.pas

@@ -120,25 +120,36 @@ interface
 
 
     procedure tavraddnode.second_cmpsmallset;
+
+      procedure gencmp(tmpreg1,tmpreg2 : tregister);
+        var
+          i : byte;
+        begin
+          current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CP,tmpreg1,tmpreg2));
+          for i:=2 to tcgsize2size[left.location.size] do
+            begin
+              tmpreg1:=GetNextReg(tmpreg1);
+              tmpreg2:=GetNextReg(tmpreg2);
+              current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CPC,tmpreg1,tmpreg2));
+            end;
+        end;
+
       var
         tmpreg : tregister;
       begin
-        {
         pass_left_right;
-
         location_reset(location,LOC_FLAGS,OS_NO);
-
         force_reg_left_right(false,false);
 
         case nodetype of
           equaln:
             begin
-              current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CMP,left.location.register,right.location.register));
+              gencmp(left.location.register,right.location.register);
               location.resflags:=F_EQ;
             end;
           unequaln:
             begin
-              current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CMP,left.location.register,right.location.register));
+              gencmp(left.location.register,right.location.register);
               location.resflags:=F_NE;
             end;
           lten,
@@ -150,14 +161,14 @@ interface
                   (nodetype = gten)) then
                 swapleftright;
               tmpreg:=cg.getintregister(current_asmdata.CurrAsmList,location.size);
-              current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_AND,tmpreg,left.location.register,right.location.register));
-              current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CMP,tmpreg,right.location.register));
+              cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList,OP_AND,location.size,
+                left.location.register,right.location.register,tmpreg);
+              gencmp(tmpreg,right.location.register);
               location.resflags:=F_EQ;
             end;
           else
             internalerror(2004012401);
         end;
-        }
       end;
 
 
@@ -182,6 +193,13 @@ interface
 
         for i:=2 to tcgsize2size[left.location.size] do
           begin
+            tmpreg1:=GetNextReg(tmpreg1);
+            tmpreg2:=GetNextReg(tmpreg2);
+            if i=5 then
+              begin
+                tmpreg1:=left.location.registerhi;
+                tmpreg2:=right.location.registerhi;
+              end;
             current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CPC,tmpreg1,tmpreg2));
           end;
 

+ 1 - 122
compiler/avr/navrcnv.pas

@@ -44,7 +44,7 @@ interface
          { procedure second_cord_to_pointer;override; }
          { procedure second_proc_to_procvar;override; }
          { procedure second_bool_to_int;override; }
-           procedure second_int_to_bool;override;
+         {  procedure second_int_to_bool;override; }
          { procedure second_load_smallset;override;  }
          { procedure second_ansistring_to_pchar;override; }
          { procedure second_pchar_to_string;override; }
@@ -54,127 +54,6 @@ interface
 
 implementation
 
-   uses
-      verbose,globtype,globals,systems,
-      symconst,symdef,aasmbase,aasmtai,aasmdata,
-      defutil,
-      cgbase,cgutils,
-      pass_1,pass_2,procinfo,
-      ncon,ncal,
-      ncgutil,
-      cpubase,aasmcpu,
-      rgobj,tgobj,cgobj,cgcpu;
-
-
-    procedure tarmtypeconvnode.second_int_to_bool;
-      var
-        hregister : tregister;
-        href      : treference;
-        resflags  : tresflags;
-        hlabel,oldTrueLabel,oldFalseLabel : tasmlabel;
-        newsize   : tcgsize;
-      begin
-        {
-        oldTrueLabel:=current_procinfo.CurrTrueLabel;
-        oldFalseLabel:=current_procinfo.CurrFalseLabel;
-        current_asmdata.getjumplabel(current_procinfo.CurrTrueLabel);
-        current_asmdata.getjumplabel(current_procinfo.CurrFalseLabel);
-        secondpass(left);
-        if codegenerror then
-         exit;
-
-        { Explicit typecasts from any ordinal type to a boolean type }
-        { must not change the ordinal value                          }
-        if (nf_explicit in flags) and
-           not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) then
-          begin
-             location_copy(location,left.location);
-             newsize:=def_cgsize(resultdef);
-             { change of size? change sign only if location is LOC_(C)REGISTER? Then we have to sign/zero-extend }
-             if (tcgsize2size[newsize]<>tcgsize2size[left.location.size]) or
-                ((newsize<>left.location.size) and (location.loc in [LOC_REGISTER,LOC_CREGISTER])) then
-               location_force_reg(current_asmdata.CurrAsmList,location,newsize,true)
-             else
-               location.size:=newsize;
-             current_procinfo.CurrTrueLabel:=oldTrueLabel;
-             current_procinfo.CurrFalseLabel:=oldFalseLabel;
-             exit;
-          end;
-
-        { Load left node into flag F_NE/F_E }
-        resflags:=F_NE;
-        case left.location.loc of
-          LOC_CREFERENCE,
-          LOC_REFERENCE :
-            begin
-              if left.location.size in [OS_64,OS_S64] then
-               begin
-                 hregister:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
-                 cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_32,OS_32,left.location.reference,hregister);
-                 href:=left.location.reference;
-                 inc(href.offset,4);
-                 tcgarm(cg).cgsetflags:=true;
-                 cg.a_op_ref_reg(current_asmdata.CurrAsmList,OP_OR,OS_32,href,hregister);
-                 tcgarm(cg).cgsetflags:=false;
-               end
-              else
-               begin
-                 location_force_reg(current_asmdata.CurrAsmList,left.location,left.location.size,true);
-                 tcgarm(cg).cgsetflags:=true;
-                 cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_OR,left.location.size,left.location.register,left.location.register);
-                 tcgarm(cg).cgsetflags:=false;
-               end;
-            end;
-          LOC_FLAGS :
-            begin
-              resflags:=left.location.resflags;
-            end;
-          LOC_REGISTER,LOC_CREGISTER :
-            begin
-              if left.location.size in [OS_64,OS_S64] then
-               begin
-                 hregister:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
-                 cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_32,OS_32,left.location.register64.reglo,hregister);
-                 tcgarm(cg).cgsetflags:=true;
-                 cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_OR,OS_32,left.location.register64.reghi,hregister);
-                 tcgarm(cg).cgsetflags:=false;
-               end
-              else
-               begin
-                 tcgarm(cg).cgsetflags:=true;
-                 cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_OR,left.location.size,left.location.register,left.location.register);
-                 tcgarm(cg).cgsetflags:=false;
-               end;
-            end;
-          LOC_JUMP :
-            begin
-              hregister:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
-              current_asmdata.getjumplabel(hlabel);
-              cg.a_label(current_asmdata.CurrAsmList,current_procinfo.CurrTrueLabel);
-              cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_INT,1,hregister);
-              cg.a_jmp_always(current_asmdata.CurrAsmList,hlabel);
-              cg.a_label(current_asmdata.CurrAsmList,current_procinfo.CurrFalseLabel);
-              cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_INT,0,hregister);
-              cg.a_label(current_asmdata.CurrAsmList,hlabel);
-              tcgarm(cg).cgsetflags:=true;
-              cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_OR,OS_INT,hregister,hregister);
-              tcgarm(cg).cgsetflags:=false;
-            end;
-          else
-            internalerror(200311301);
-        end;
-        { load flags to register }
-        location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
-        location.register:=cg.getintregister(current_asmdata.CurrAsmList,location.size);
-        cg.g_flags2reg(current_asmdata.CurrAsmList,location.size,resflags,location.register);
-        if (is_cbool(resultdef)) then
-          cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_NEG,location.size,location.register,location.register);
-        current_procinfo.CurrTrueLabel:=oldTrueLabel;
-        current_procinfo.CurrFalseLabel:=oldFalseLabel;
-        }
-      end;
-
-
 begin
   ctypeconvnode:=tarmtypeconvnode;
 end.

+ 7 - 12
compiler/avr/raavrgas.pas

@@ -333,13 +333,6 @@ Unit raavrgas;
               BuildReference(oper);
             end;
 
-          AS_HASH: { Constant expression  }
-            Begin
-              Consume(AS_HASH);
-              BuildConstantOperand(oper);
-            end;
-
-          (*
           AS_INTNUM,
           AS_MINUS,
           AS_PLUS:
@@ -348,16 +341,18 @@ Unit raavrgas;
               { This must absolutely be followed by (  }
               oper.InitRef;
               oper.opr.ref.offset:=BuildConstExpression(True,False);
-              if actasmtoken<>AS_LPAREN then
+
+              { absolute memory addresss? }
+              if actopcode in [A_LDS,A_STS] then
+                BuildReference(oper)
+              else
                 begin
                   ofs:=oper.opr.ref.offset;
                   BuildConstantOperand(oper);
                   inc(oper.opr.val,ofs);
-                end
-              else
-                BuildReference(oper);
+                end;
             end;
-          *)
+
           AS_ID: { A constant expression, or a Variable ref.  }
             Begin
               { Local Label ? }

+ 59 - 7
compiler/avr/rgcpu.pas

@@ -87,28 +87,80 @@ unit rgcpu;
       end;
 
 
-
     procedure trgcpu.do_spill_read(list:TAsmList;pos:tai;const spilltemp:treference;tempreg:tregister);
+      var
+        helpins  : tai;
+        tmpref   : treference;
+        helplist : TAsmList;
+        hreg     : tregister;
       begin
-        inherited do_spill_read(list,pos,spilltemp,tempreg);
+        if abs(spilltemp.offset)>63 then
+          begin
+            helplist:=TAsmList.create;
+
+            helplist.concat(taicpu.op_reg_const(A_LDI,NR_R26,lo(word(spilltemp.offset))));
+            helplist.concat(taicpu.op_reg_const(A_LDI,NR_R27,hi(word(spilltemp.offset))));
+            helplist.concat(taicpu.op_reg_reg(A_ADD,NR_R26,spilltemp.base));
+            helplist.concat(taicpu.op_reg_reg(A_ADC,NR_R27,GetNextReg(spilltemp.base)));
+
+            reference_reset_base(tmpref,NR_R26,0,1);
+            helpins:=spilling_create_load(tmpref,tempreg);
+            helplist.concat(helpins);
+            list.insertlistafter(pos,helplist);
+            helplist.free;
+          end
+        else
+          inherited do_spill_read(list,pos,spilltemp,tempreg);
       end;
 
 
     procedure trgcpu.do_spill_written(list:TAsmList;pos:tai;const spilltemp:treference;tempreg:tregister);
+      var
+        tmpref   : treference;
+        helplist : TAsmList;
+        hreg     : tregister;
       begin
-        inherited do_spill_written(list,pos,spilltemp,tempreg);
-      end;
+        if abs(spilltemp.offset)>63 then
+          begin
+            helplist:=TAsmList.create;
+
+            helplist.concat(taicpu.op_reg_const(A_LDI,NR_R26,lo(word(spilltemp.offset))));
+            helplist.concat(taicpu.op_reg_const(A_LDI,NR_R27,hi(word(spilltemp.offset))));
+            helplist.concat(taicpu.op_reg_reg(A_ADD,NR_R26,spilltemp.base));
+            helplist.concat(taicpu.op_reg_reg(A_ADC,NR_R27,GetNextReg(spilltemp.base)));
+
+            reference_reset_base(tmpref,NR_R26,0,1);
+            helplist.concat(spilling_create_store(tempreg,tmpref));
+            list.insertlistafter(pos,helplist);
+            helplist.free;
+          end
+        else
+          inherited do_spill_written(list,pos,spilltemp,tempreg);
+    end;
 
 
     procedure trgintcpu.add_cpu_interferences(p : tai);
       var
-        r : tregister;
+        r : tsuperregister;
       begin
         if p.typ=ait_instruction then
           begin
             case taicpu(p).opcode of
-              A_LD:
-                ;
+              A_CPI,
+              A_ANDI,
+              A_ORI,
+              A_SUBI,
+              A_SBCI,
+              A_LDI:
+                for r:=RS_R0 to RS_R15 do
+                  add_edge(r,GetSupReg(taicpu(p).oper[0]^.reg));
+              A_MULS:
+                begin
+                  for r:=RS_R0 to RS_R15 do
+                    add_edge(r,GetSupReg(taicpu(p).oper[0]^.reg));
+                  for r:=RS_R0 to RS_R15 do
+                    add_edge(r,GetSupReg(taicpu(p).oper[1]^.reg));
+                end;
             end;
           end;
       end;

+ 17 - 10
compiler/cgobj.pas

@@ -346,7 +346,7 @@ unit cgobj;
 
           {  comparison operations }
           procedure a_cmp_const_reg_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;a : aint;reg : tregister;
-            l : tasmlabel);virtual; abstract;
+            l : tasmlabel); virtual;
           procedure a_cmp_const_ref_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;a : aint;const ref : treference;
             l : tasmlabel); virtual;
           procedure a_cmp_const_loc_label(list: TAsmList; size: tcgsize;cmp_op: topcmp; a: aint; const loc: tlocation;
@@ -757,12 +757,12 @@ implementation
     procedure tcg.allocallcpuregisters(list:TAsmList);
       begin
         alloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
-{$ifndef i386}
+{$if not(defined(i386)) and not(defined(avr))}
         alloccpuregisters(list,R_FPUREGISTER,paramanager.get_volatile_registers_fpu(pocall_default));
 {$ifdef cpumm}
         alloccpuregisters(list,R_MMREGISTER,paramanager.get_volatile_registers_mm(pocall_default));
 {$endif cpumm}
-{$endif i386}
+{$endif not(defined(i386)) and not(defined(avr))}
       end;
 
 
@@ -778,12 +778,12 @@ implementation
     procedure tcg.deallocallcpuregisters(list:TAsmList);
       begin
         dealloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
-{$ifndef i386}
+{$if not(defined(i386)) and not(defined(avr))}
         dealloccpuregisters(list,R_FPUREGISTER,paramanager.get_volatile_registers_fpu(pocall_default));
 {$ifdef cpumm}
         dealloccpuregisters(list,R_MMREGISTER,paramanager.get_volatile_registers_mm(pocall_default));
 {$endif cpumm}
-{$endif i386}
+{$endif not(defined(i386)) and not(defined(avr))}
       end;
 
 
@@ -3055,12 +3055,21 @@ implementation
       end;
 
 
-    procedure tcg.a_cmp_const_ref_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;a : aint;const ref : treference;
-     l : tasmlabel);
-
+    procedure tcg.a_cmp_const_reg_label(list: TAsmList; size: tcgsize;
+      cmp_op: topcmp; a: aint; reg: tregister; l: tasmlabel);
       var
         tmpreg: tregister;
+      begin
+        tmpreg:=getintregister(list,size);
+        a_load_const_reg(list,size,a,tmpreg);
+        a_cmp_reg_reg_label(list,size,cmp_op,tmpreg,reg,l);
+      end;
 
+
+    procedure tcg.a_cmp_const_ref_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;a : aint;const ref : treference;
+      l : tasmlabel);
+      var
+        tmpreg: tregister;
       begin
         tmpreg:=getintregister(list,size);
         a_load_ref_reg(list,size,size,ref,tmpreg);
@@ -3070,10 +3079,8 @@ implementation
 
     procedure tcg.a_cmp_const_loc_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;a : aint;const loc : tlocation;
       l : tasmlabel);
-
       var
         tmpreg : tregister;
-
       begin
         case loc.loc of
           LOC_REGISTER,LOC_CREGISTER:

+ 1 - 0
compiler/fpcdefs.inc

@@ -119,6 +119,7 @@
   {$define cpunofpu}
   {$define cpunodefaultint}
   {$define cpuneedsdiv32helper}
+  {$define cpuneedsmulhelper}
 {$endif avr}
 
 {$ifdef mipsel}

+ 2 - 2
compiler/globals.pas

@@ -399,8 +399,8 @@ interface
         fputype : fpu_sse64;
 {$endif x86_64}
 {$ifdef avr}
-        cputype : cpuinfo.cpu_avr;
-        optimizecputype : cpuinfo.cpu_avr;
+        cputype : cpuinfo.cpu_avr5;
+        optimizecputype : cpuinfo.cpu_avr5;
         fputype : fpu_none;
 {$endif avr}
 {$ifdef mips}

+ 30 - 0
compiler/nadd.pas

@@ -2476,6 +2476,7 @@ implementation
          rd,ld   : tdef;
          i       : longint;
          lt,rt   : tnodetype;
+         procname : string[32];
       begin
          result:=nil;
 
@@ -2577,6 +2578,7 @@ implementation
                     expectloc:=LOC_JUMP;
                end
 {$endif cpu64bitaddr}
+{$ifndef cpuneedsmulhelper}
              { is there a cardinal? }
              else if (torddef(ld).ordtype=u32bit) then
                begin
@@ -2585,9 +2587,37 @@ implementation
                   else
                     expectloc:=LOC_FLAGS;
                end
+{$endif cpuneedsmulhelper}
              { generic s32bit conversion }
              else
                begin
+{$ifdef cpuneedsmulhelper}
+                 if (nodetype=muln) and not(torddef(resultdef).ordtype in [u8bit,s8bit]) then
+                   begin
+                     result := nil;
+
+                     case torddef(resultdef).ordtype of
+                       s16bit:
+                         procname := 'fpc_mul_integer';
+                       u16bit:
+                         procname := 'fpc_mul_word';
+                       s32bit:
+                         procname := 'fpc_mul_longint';
+                       u32bit:
+                         procname := 'fpc_mul_dword';
+                       else
+                         internalerror(2011022301);
+                     end;
+                     result := ccallnode.createintern(procname,
+                       ccallparanode.create(cordconstnode.create(0,booltype,false),
+                       ccallparanode.create(right,
+                       ccallparanode.create(left,nil))));
+                     left := nil;
+                     right := nil;
+                     firstpass(result);
+                     exit;
+                   end;
+{$endif cpuneedsmulhelper}
                   if nodetype in [addn,subn,muln,andn,orn,xorn] then
                     expectloc:=LOC_REGISTER
                   else

+ 2 - 2
compiler/ncgadd.pas

@@ -208,8 +208,8 @@ interface
 {$ifndef cpu64bitalu}
             if location.size in [OS_64,OS_S64] then
               begin
-                location.register64.reglo := cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
-                location.register64.reghi := cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
+                location.register64.reglo := cg.getintregister(current_asmdata.CurrAsmList,OS_32);
+                location.register64.reghi := cg.getintregister(current_asmdata.CurrAsmList,OS_32);
               end
             else
 {$endif}

+ 101 - 0
compiler/ncgcnv.pas

@@ -30,6 +30,9 @@ interface
        node,ncnv,defutil,defcmp;
 
     type
+
+       { tcgtypeconvnode }
+
        tcgtypeconvnode = class(ttypeconvnode)
          procedure second_int_to_int;override;
          procedure second_cstring_to_pchar;override;
@@ -49,6 +52,7 @@ interface
          procedure second_char_to_char;override;
          procedure second_nothing;override;
          procedure pass_generate_code;override;
+        procedure second_int_to_bool;override;
        end;
 
        tcgasnode = class(tasnode)
@@ -131,6 +135,103 @@ interface
       end;
 
 
+    procedure tcgtypeconvnode.second_int_to_bool;
+      var
+        hregister : tregister;
+        href      : treference;
+        resflags  : tresflags;
+        hlabel,oldTrueLabel,oldFalseLabel : tasmlabel;
+        newsize   : tcgsize;
+      begin
+        oldTrueLabel:=current_procinfo.CurrTrueLabel;
+        oldFalseLabel:=current_procinfo.CurrFalseLabel;
+        current_asmdata.getjumplabel(current_procinfo.CurrTrueLabel);
+        current_asmdata.getjumplabel(current_procinfo.CurrFalseLabel);
+        secondpass(left);
+        if codegenerror then
+         exit;
+
+        { Explicit typecasts from any ordinal type to a boolean type }
+        { must not change the ordinal value                          }
+        if (nf_explicit in flags) and
+           not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) then
+          begin
+             location_copy(location,left.location);
+             newsize:=def_cgsize(resultdef);
+             { change of size? change sign only if location is LOC_(C)REGISTER? Then we have to sign/zero-extend }
+             if (tcgsize2size[newsize]<>tcgsize2size[left.location.size]) or
+                ((newsize<>left.location.size) and (location.loc in [LOC_REGISTER,LOC_CREGISTER])) then
+               location_force_reg(current_asmdata.CurrAsmList,location,newsize,true)
+             else
+               location.size:=newsize;
+             current_procinfo.CurrTrueLabel:=oldTrueLabel;
+             current_procinfo.CurrFalseLabel:=oldFalseLabel;
+             exit;
+          end;
+
+        { Load left node into flag F_NE/F_E }
+        resflags:=F_NE;
+        case left.location.loc of
+          LOC_CREFERENCE,
+          LOC_REFERENCE :
+            begin
+              if left.location.size in [OS_64,OS_S64] then
+               begin
+                 hregister:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
+                 cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_32,OS_32,left.location.reference,hregister);
+                 href:=left.location.reference;
+                 inc(href.offset,4);
+                 cg.a_op_ref_reg(current_asmdata.CurrAsmList,OP_OR,OS_32,href,hregister);
+               end
+              else
+               begin
+                 location_force_reg(current_asmdata.CurrAsmList,left.location,left.location.size,true);
+                 cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_OR,left.location.size,left.location.register,left.location.register);
+               end;
+            end;
+          LOC_FLAGS :
+            begin
+              resflags:=left.location.resflags;
+            end;
+          LOC_REGISTER,LOC_CREGISTER :
+            begin
+              if left.location.size in [OS_64,OS_S64] then
+               begin
+                 hregister:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
+                 cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_32,OS_32,left.location.register64.reglo,hregister);
+                 cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_OR,OS_32,left.location.register64.reghi,hregister);
+               end
+              else
+               begin
+                 cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_OR,left.location.size,left.location.register,left.location.register);
+               end;
+            end;
+          LOC_JUMP :
+            begin
+              hregister:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
+              current_asmdata.getjumplabel(hlabel);
+              cg.a_label(current_asmdata.CurrAsmList,current_procinfo.CurrTrueLabel);
+              cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_INT,1,hregister);
+              cg.a_jmp_always(current_asmdata.CurrAsmList,hlabel);
+              cg.a_label(current_asmdata.CurrAsmList,current_procinfo.CurrFalseLabel);
+              cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_INT,0,hregister);
+              cg.a_label(current_asmdata.CurrAsmList,hlabel);
+              cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_OR,OS_INT,hregister,hregister);
+            end;
+          else
+            internalerror(200311301);
+        end;
+        { load flags to register }
+        location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
+        location.register:=cg.getintregister(current_asmdata.CurrAsmList,location.size);
+        cg.g_flags2reg(current_asmdata.CurrAsmList,location.size,resflags,location.register);
+        if (is_cbool(resultdef)) then
+          cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_NEG,location.size,location.register,location.register);
+        current_procinfo.CurrTrueLabel:=oldTrueLabel;
+        current_procinfo.CurrFalseLabel:=oldFalseLabel;
+      end;
+
+
     procedure tcgtypeconvnode.second_cstring_to_pchar;
 
       var

+ 5 - 0
compiler/ncgmat.pas

@@ -410,11 +410,16 @@ implementation
            shln: op:=OP_SHL;
            shrn: op:=OP_SHR;
          end;
+{$ifdef cpunodefaultint}
+        opsize:=left.location.size;
+{$else cpunodefaultint}
          { load left operators in a register }
          if is_signed(left.resultdef) then
            opsize:=OS_SINT
          else
            opsize:=OS_INT;
+{$endif cpunodefaultint}
+
          location_force_reg(current_asmdata.CurrAsmList,left.location,opsize,true);
          location_reset(location,LOC_REGISTER,opsize);
          location.register:=cg.getintregister(current_asmdata.CurrAsmList,opsize);

+ 13 - 6
compiler/ncgutil.pas

@@ -493,11 +493,18 @@ implementation
               { load a smaller size to OS_64 }
               if l.loc=LOC_REGISTER then
                begin
+{$ifdef AVR}
+                 { on avr, we cannot change the size of a register
+                   due to the nature how register with size > OS8 are handled
+                 }
+                 hregister:=cg.getintregister(list,OS_32);
+{$else AVR}
                  hregister:=cg.makeregsize(list,l.register64.reglo,OS_32);
+{$endif AVR}
                  cg.a_load_reg_reg(list,l.size,OS_32,l.register64.reglo,hregister);
                end
               else
-               hregister:=cg.getintregister(list,OS_INT);
+               hregister:=cg.getintregister(list,OS_32);
               { load value in low register }
               case l.loc of
 {$ifdef cpuflags}
@@ -518,7 +525,7 @@ implementation
                   cg.a_load_loc_reg(list,OS_INT,l,hregister);
               end;
               { reset hi part, take care of the signed bit of the current value }
-              hregisterhi:=cg.getintregister(list,OS_INT);
+              hregisterhi:=cg.getintregister(list,OS_32);
               if (l.size in [OS_S8,OS_S16,OS_S32]) then
                begin
                  if l.loc=LOC_CONSTANT then
@@ -551,8 +558,8 @@ implementation
                end
               else
                begin
-                 hregister:=cg.getintregister(list,OS_INT);
-                 hregisterhi:=cg.getintregister(list,OS_INT);
+                 hregister:=cg.getintregister(list,OS_32);
+                 hregisterhi:=cg.getintregister(list,OS_32);
                  const_location := false;
                end;
               hreg64.reglo:=hregister;
@@ -622,8 +629,8 @@ implementation
                         l.reference.alignment:=newalignment(l.reference.alignment,TCGSize2Size[l.size]-TCGSize2Size[dst_size]);
                       end;
 {$ifdef x86}
-                  if not (l.loc in [LOC_SUBSETREG,LOC_CSUBSETREG]) then
-                     l.size:=dst_size;
+                    if not (l.loc in [LOC_SUBSETREG,LOC_CSUBSETREG]) then
+                      l.size:=dst_size;
 {$endif x86}
                   end;
                  cg.a_load_loc_reg(list,dst_size,l,hregister);

+ 24 - 1
compiler/nmat.pas

@@ -483,6 +483,7 @@ implementation
     function tshlshrnode.pass_typecheck:tnode;
       var
          t : tnode;
+         nd : tdef;
       begin
          result:=nil;
          typecheckpass(left);
@@ -508,6 +509,14 @@ implementation
               exit;
            end;
 
+{$ifdef cpunodefaultint}
+         { for small cpus we use the smallest common type }
+         if (left.resultdef.typ=orddef) and (right.resultdef.typ=orddef) then
+           nd:=get_common_intdef(torddef(left.resultdef),torddef(right.resultdef),false)
+         else
+           nd:=s32inttype;
+{$endif cpunodefaultint}
+
          { calculations for ordinals < 32 bit have to be done in
            32 bit for backwards compatibility. That way 'shl 33' is
            the same as 'shl 1'. It's ugly but compatible with delphi/tp/gcc }
@@ -516,12 +525,26 @@ implementation
            begin
              { keep singness of orignal type }
              if is_signed(left.resultdef) then
+{$ifdef cpunodefaultint}
+               inserttypeconv(left,nd)
+{$else cpunodefaultint}
                inserttypeconv(left,s32inttype)
+{$endif cpunodefaultint}
              else
-               inserttypeconv(left,u32inttype);
+               begin
+{$ifdef cpunodefaultint}
+                 inserttypeconv(left,nd)
+{$else cpunodefaultint}
+                 inserttypeconv(left,u32inttype);
+{$endif cpunodefaultint}
+               end
            end;
 
+{$ifdef cpunodefaultint}
+         inserttypeconv(right,nd);
+{$else cpunodefaultint}
          inserttypeconv(right,sinttype);
+{$endif cpunodefaultint}
 
          resultdef:=left.resultdef;
       end;

+ 4 - 1
compiler/ppcavr.lpi

@@ -12,7 +12,7 @@
       </Flags>
       <SessionStorage Value="InProjectDir"/>
       <MainUnit Value="0"/>
-      <Title Value="pp"/>
+      <Title Value="ppavr"/>
     </General>
     <BuildModes Count="1">
       <Item1 Name="default" Default="True"/>
@@ -74,6 +74,9 @@
       <ConfigFile>
         <StopAfterErrCount Value="50"/>
       </ConfigFile>
+      <CompilerMessages>
+        <UseMsgFile Value="True"/>
+      </CompilerMessages>
       <CustomOptions Value="-davr"/>
       <CompilerPath Value="$(CompPath)"/>
     </Other>

+ 2 - 4
compiler/pstatmnt.pas

@@ -1297,8 +1297,7 @@ implementation
          include(current_procinfo.flags,pi_is_assembler);
          p:=_asm_statement;
 
-{$ifndef sparc}
-{$ifndef arm}
+{$if not(defined(sparc)) and not(defined(arm)) and not(defined(avr))}
          if (po_assembler in current_procinfo.procdef.procoptions) then
            begin
              { set the framepointer to esp for assembler functions when the
@@ -1323,8 +1322,7 @@ implementation
                  current_procinfo.framepointer:=NR_STACK_POINTER_REG;
                end;
            end;
-{$endif arm}
-{$endif sparc}
+{$endif not(defined(sparc)) and not(defined(arm)) and not(defined(avr))}
 
         { Flag the result as assigned when it is returned in a
           register.

+ 1 - 4
compiler/symtype.pas

@@ -954,11 +954,8 @@ implementation
         {$if sizeof(TConstPtrUInt)=8}
           putint64(int64(v));
         {$else}
-        {$if sizeof(TConstPtrUInt)=4}
           putlongint(longint(v));
-        {$else}
-          internalerror(2002082601);
-        {$endif} {$endif}
+        {$endif}
       end;
 
 

+ 238 - 2
compiler/systems/t_embed.pas

@@ -82,7 +82,7 @@ Var
 begin
   WriteResponseFile:=False;
   linklibc:=(SharedLibFiles.Find('c')<>nil);
-{$if defined(ARM) or defined(i386)}
+{$if defined(ARM) or defined(i386) or defined(AVR)}
   prtobj:='';
 {$else}
   prtobj:='prt0';
@@ -293,6 +293,7 @@ begin
       Add('_end = .;');
     end;
 {$endif ARM}
+
 {$ifdef i386}
   with linkres do
     begin
@@ -327,7 +328,242 @@ begin
       Add('}');
       Add('_end = .;');
     end;
-{$endif I386}
+{$endif i386}
+
+{$ifdef AVR}
+  with linkres do
+    begin
+      { linker script from ld 2.19 }
+      Add('ENTRY(_START)');
+      Add('OUTPUT_FORMAT("elf32-avr","elf32-avr","elf32-avr")');
+      Add('OUTPUT_ARCH(avr:2)');
+      Add('MEMORY');
+      Add('{');
+      Add('  text      (rx)   : ORIGIN = 0, LENGTH = 8K');
+      Add('  data      (rw!x) : ORIGIN = 0x800060, LENGTH = 0xffa0');
+      Add('  eeprom    (rw!x) : ORIGIN = 0x810000, LENGTH = 64K');
+      Add('  fuse      (rw!x) : ORIGIN = 0x820000, LENGTH = 1K');
+      Add('  lock      (rw!x) : ORIGIN = 0x830000, LENGTH = 1K');
+      Add('  signature (rw!x) : ORIGIN = 0x840000, LENGTH = 1K');
+      Add('}');
+      Add('SECTIONS');
+      Add('{');
+      Add('  /* Read-only sections, merged into text segment: */');
+      Add('  .hash          : { *(.hash)		}');
+      Add('  .dynsym        : { *(.dynsym)		}');
+      Add('  .dynstr        : { *(.dynstr)		}');
+      Add('  .gnu.version   : { *(.gnu.version)	}');
+      Add('  .gnu.version_d   : { *(.gnu.version_d)	}');
+      Add('  .gnu.version_r   : { *(.gnu.version_r)	}');
+      Add('  .rel.init      : { *(.rel.init)		}');
+      Add('  .rela.init     : { *(.rela.init)	}');
+      Add('  .rel.text      :');
+      Add('    {');
+      Add('      *(.rel.text)');
+      Add('      *(.rel.text.*)');
+      Add('      *(.rel.gnu.linkonce.t*)');
+      Add('    }');
+      Add('  .rela.text     :');
+      Add('    {');
+      Add('      *(.rela.text)');
+      Add('      *(.rela.text.*)');
+      Add('      *(.rela.gnu.linkonce.t*)');
+      Add('    }');
+      Add('  .rel.fini      : { *(.rel.fini)		}');
+      Add('  .rela.fini     : { *(.rela.fini)	}');
+      Add('  .rel.rodata    :');
+      Add('    {');
+      Add('      *(.rel.rodata)');
+      Add('      *(.rel.rodata.*)');
+      Add('      *(.rel.gnu.linkonce.r*)');
+      Add('    }');
+      Add('  .rela.rodata   :');
+      Add('    {');
+      Add('      *(.rela.rodata)');
+      Add('      *(.rela.rodata.*)');
+      Add('      *(.rela.gnu.linkonce.r*)');
+      Add('    }');
+      Add('  .rel.data      :');
+      Add('    {');
+      Add('      *(.rel.data)');
+      Add('      *(.rel.data.*)');
+      Add('      *(.rel.gnu.linkonce.d*)');
+      Add('    }');
+      Add('  .rela.data     :');
+      Add('    {');
+      Add('      *(.rela.data)');
+      Add('      *(.rela.data.*)');
+      Add('      *(.rela.gnu.linkonce.d*)');
+      Add('    }');
+      Add('  .rel.ctors     : { *(.rel.ctors)	}');
+      Add('  .rela.ctors    : { *(.rela.ctors)	}');
+      Add('  .rel.dtors     : { *(.rel.dtors)	}');
+      Add('  .rela.dtors    : { *(.rela.dtors)	}');
+      Add('  .rel.got       : { *(.rel.got)		}');
+      Add('  .rela.got      : { *(.rela.got)		}');
+      Add('  .rel.bss       : { *(.rel.bss)		}');
+      Add('  .rela.bss      : { *(.rela.bss)		}');
+      Add('  .rel.plt       : { *(.rel.plt)		}');
+      Add('  .rela.plt      : { *(.rela.plt)		}');
+      Add('  /* Internal text space or external memory.  */');
+      Add('  .text   :');
+      Add('  {');
+      Add('    *(.vectors)');
+      Add('    KEEP(*(.vectors))');
+      Add('    /* For data that needs to reside in the lower 64k of progmem.  */');
+      Add('    *(.progmem.gcc*)');
+      Add('    *(.progmem*)');
+      Add('    . = ALIGN(2);');
+      Add('     __trampolines_start = . ;');
+      Add('    /* The jump trampolines for the 16-bit limited relocs will reside here.  */');
+      Add('    *(.trampolines)');
+      Add('    *(.trampolines*)');
+      Add('     __trampolines_end = . ;');
+      Add('    /* For future tablejump instruction arrays for 3 byte pc devices.');
+      Add('       We don''t relax jump/call instructions within these sections.  */');
+      Add('    *(.jumptables)');
+      Add('    *(.jumptables*)');
+      Add('    /* For code that needs to reside in the lower 128k progmem.  */');
+      Add('    *(.lowtext)');
+      Add('    *(.lowtext*)');
+      Add('     __ctors_start = . ;');
+      Add('     *(.ctors)');
+      Add('     __ctors_end = . ;');
+      Add('     __dtors_start = . ;');
+      Add('     *(.dtors)');
+      Add('     __dtors_end = . ;');
+      Add('    KEEP(SORT(*)(.ctors))');
+      Add('    KEEP(SORT(*)(.dtors))');
+      Add('    /* From this point on, we don''t bother about wether the insns are');
+      Add('       below or above the 16 bits boundary.  */');
+      Add('    *(.init0)  /* Start here after reset.  */');
+      Add('    KEEP (*(.init0))');
+      Add('    *(.init1)');
+      Add('    KEEP (*(.init1))');
+      Add('    *(.init2)  /* Clear __zero_reg__, set up stack pointer.  */');
+      Add('    KEEP (*(.init2))');
+      Add('    *(.init3)');
+      Add('    KEEP (*(.init3))');
+      Add('    *(.init4)  /* Initialize data and BSS.  */');
+      Add('    KEEP (*(.init4))');
+      Add('    *(.init5)');
+      Add('    KEEP (*(.init5))');
+      Add('    *(.init6)  /* C++ constructors.  */');
+      Add('    KEEP (*(.init6))');
+      Add('    *(.init7)');
+      Add('    KEEP (*(.init7))');
+      Add('    *(.init8)');
+      Add('    KEEP (*(.init8))');
+      Add('    *(.init9)  /* Call main().  */');
+      Add('    KEEP (*(.init9))');
+      Add('    *(.text)');
+      Add('    . = ALIGN(2);');
+      Add('    *(.text.*)');
+      Add('    . = ALIGN(2);');
+      Add('    *(.fini9)  /* _exit() starts here.  */');
+      Add('    KEEP (*(.fini9))');
+      Add('    *(.fini8)');
+      Add('    KEEP (*(.fini8))');
+      Add('    *(.fini7)');
+      Add('    KEEP (*(.fini7))');
+      Add('    *(.fini6)  /* C++ destructors.  */');
+      Add('    KEEP (*(.fini6))');
+      Add('    *(.fini5)');
+      Add('    KEEP (*(.fini5))');
+      Add('    *(.fini4)');
+      Add('    KEEP (*(.fini4))');
+      Add('    *(.fini3)');
+      Add('    KEEP (*(.fini3))');
+      Add('    *(.fini2)');
+      Add('    KEEP (*(.fini2))');
+      Add('    *(.fini1)');
+      Add('    KEEP (*(.fini1))');
+      Add('    *(.fini0)  /* Infinite loop after program termination.  */');
+      Add('    KEEP (*(.fini0))');
+      Add('     _etext = . ;');
+      Add('  }  > text');
+      Add('  .data	  : AT (ADDR (.text) + SIZEOF (.text))');
+      Add('  {');
+      Add('     PROVIDE (__data_start = .) ;');
+      Add('    *(.data)');
+      Add('    *(.data*)');
+      Add('    *(.rodata)  /* We need to include .rodata here if gcc is used */');
+      Add('    *(.rodata*) /* with -fdata-sections.  */');
+      Add('    *(.gnu.linkonce.d*)');
+      Add('    . = ALIGN(2);');
+      Add('     _edata = . ;');
+      Add('     PROVIDE (__data_end = .) ;');
+      Add('  }  > data');
+      Add('  .bss   : AT (ADDR (.bss))');
+      Add('  {');
+      Add('     PROVIDE (__bss_start = .) ;');
+      Add('    *(.bss)');
+      Add('    *(.bss*)');
+      Add('    *(COMMON)');
+      Add('     PROVIDE (__bss_end = .) ;');
+      Add('  }  > data');
+      Add('   __data_load_start = LOADADDR(.data);');
+      Add('   __data_load_end = __data_load_start + SIZEOF(.data);');
+      Add('  /* Global data not cleared after reset.  */');
+      Add('  .noinit  :');
+      Add('  {');
+      Add('     PROVIDE (__noinit_start = .) ;');
+      Add('    *(.noinit*)');
+      Add('     PROVIDE (__noinit_end = .) ;');
+      Add('     _end = . ;');
+      Add('     PROVIDE (__heap_start = .) ;');
+      Add('  }  > data');
+      Add('  .eeprom  :');
+      Add('  {');
+      Add('    *(.eeprom*)');
+      Add('     __eeprom_end = . ;');
+      Add('  }  > eeprom');
+      Add('  .fuse  :');
+      Add('  {');
+      Add('    KEEP(*(.fuse))');
+      Add('    KEEP(*(.lfuse))');
+      Add('    KEEP(*(.hfuse))');
+      Add('    KEEP(*(.efuse))');
+      Add('  }  > fuse');
+      Add('  .lock  :');
+      Add('  {');
+      Add('    KEEP(*(.lock*))');
+      Add('  }  > lock');
+      Add('  .signature  :');
+      Add('  {');
+      Add('    KEEP(*(.signature*))');
+      Add('  }  > signature');
+      Add('  /* Stabs debugging sections.  */');
+      Add('  .stab 0 : { *(.stab) }');
+      Add('  .stabstr 0 : { *(.stabstr) }');
+      Add('  .stab.excl 0 : { *(.stab.excl) }');
+      Add('  .stab.exclstr 0 : { *(.stab.exclstr) }');
+      Add('  .stab.index 0 : { *(.stab.index) }');
+      Add('  .stab.indexstr 0 : { *(.stab.indexstr) }');
+      Add('  .comment 0 : { *(.comment) }');
+      Add('  /* DWARF debug sections.');
+      Add('     Symbols in the DWARF debugging sections are relative to the beginning');
+      Add('     of the section so we begin them at 0.  */');
+      Add('  /* DWARF 1 */');
+      Add('  .debug          0 : { *(.debug) }');
+      Add('  .line           0 : { *(.line) }');
+      Add('  /* GNU DWARF 1 extensions */');
+      Add('  .debug_srcinfo  0 : { *(.debug_srcinfo) }');
+      Add('  .debug_sfnames  0 : { *(.debug_sfnames) }');
+      Add('  /* DWARF 1.1 and DWARF 2 */');
+      Add('  .debug_aranges  0 : { *(.debug_aranges) }');
+      Add('  .debug_pubnames 0 : { *(.debug_pubnames) }');
+      Add('  /* DWARF 2 */');
+      Add('  .debug_info     0 : { *(.debug_info) *(.gnu.linkonce.wi.*) }');
+      Add('  .debug_abbrev   0 : { *(.debug_abbrev) }');
+      Add('  .debug_line     0 : { *(.debug_line) }');
+      Add('  .debug_frame    0 : { *(.debug_frame) }');
+      Add('  .debug_str      0 : { *(.debug_str) }');
+      Add('  .debug_loc      0 : { *(.debug_loc) }');
+      Add('  .debug_macinfo  0 : { *(.debug_macinfo) }');
+      Add('}');
+    end;
+{$endif AVR}
 
   { Write and Close response }
   linkres.writetodisk;

+ 1 - 1
compiler/tgobj.pas

@@ -161,7 +161,7 @@ implementation
        tempfreelist:=nil;
        templist:=nil;
        { we could create a new child class for this but I don't if it is worth the effort (FK) }
-{$if defined(powerpc) or defined(powerpc64)}
+{$if defined(powerpc) or defined(powerpc64) or defined(avr)}
        direction:=1;
 {$else}
        direction:=-1;

+ 145 - 5
rtl/avr/avr.inc

@@ -18,10 +18,150 @@
 {$asmmode gas}
 
 Procedure SysInitFPU;{$ifdef SYSTEMINLINE}inline;{$endif}
-begin
-end;
+  begin
+  end;
+
 
 procedure fpc_cpuinit;
-begin
-  SysInitFPU;
-end;
+  begin
+    SysInitFPU;
+  end;
+
+
+
+{$IFNDEF INTERNAL_BACKTRACE}
+{$define FPC_SYSTEM_HAS_GET_FRAME}
+function get_frame:pointer;assembler;nostackframe;
+  asm
+  end;
+{$ENDIF not INTERNAL_BACKTRACE}
+
+
+{$define FPC_SYSTEM_HAS_GET_CALLER_ADDR}
+function get_caller_addr(framebp:pointer):pointer;assembler;
+  asm
+  end;
+
+
+{$define FPC_SYSTEM_HAS_GET_CALLER_FRAME}
+function get_caller_frame(framebp:pointer):pointer;assembler;
+  asm
+  end;
+
+
+{$define FPC_SYSTEM_HAS_SPTR}
+Function Sptr : pointer;assembler;
+  asm
+  end;
+
+
+function InterLockedDecrement (var Target: longint) : longint;
+  var
+    sreg : byte;
+  begin
+    { block interrupts }
+    asm
+      in r0,0x3f
+      std sreg,r0
+      cli
+    end;
+
+    dec(Target);
+    Result:=Target;
+
+    { release interrupts }
+    asm
+      ldd r0,sreg
+      out 0x3f,r0
+    end;
+  end;
+
+
+function InterLockedIncrement (var Target: longint) : longint;
+  var
+    sreg : byte;
+  begin
+    { block interrupts }
+    asm
+      in r0,0x3f
+      std sreg,r0
+      cli
+    end;
+
+    inc(Target);
+    Result:=Target;
+
+    { release interrupts }
+    asm
+      ldd r0,sreg
+      out 0x3f,r0
+    end;
+  end;
+
+
+function InterLockedExchange (var Target: longint;Source : longint) : longint;
+  var
+    sreg : byte;
+  begin
+    { block interrupts }
+    asm
+      in r0,0x3f
+      std sreg,r0
+      cli
+    end;
+
+    Result:=Target;
+    Target:=Source;
+
+    { release interrupts }
+    asm
+      ldd r0,sreg
+      out 0x3f,r0
+    end;
+  end;
+
+
+function InterlockedCompareExchange(var Target: longint; NewValue: longint; Comperand: longint): longint;
+  var
+    sreg : byte;
+  begin
+    { block interrupts }
+    asm
+      in r0,0x3f
+      std sreg,r0
+      cli
+    end;
+
+    Result:=Target;
+    if Target=Comperand then
+      Target:=NewValue;
+
+    { release interrupts }
+    asm
+      ldd r0,sreg
+      out 0x3f,r0
+    end;
+  end;
+
+
+function InterLockedExchangeAdd (var Target: longint;Source : longint) : longint;
+  var
+    sreg : byte;
+  begin
+    { block interrupts }
+    asm
+      in r0,0x3f
+      std sreg,r0
+      cli
+    end;
+
+    Result:=Target;
+    inc(Target,Source);
+
+    { release interrupts }
+    asm
+      ldd r0,sreg
+      out 0x3f,r0
+    end;
+  end;
+

+ 87 - 0
rtl/embedded/avr/atmega128.pp

@@ -0,0 +1,87 @@
+{******************************************************************************
+Register definitions and startup code for ATMEL ATmega128
+
+
+******************************************************************************}
+unit atmega128;
+
+{$goto on}
+
+  interface
+
+  implementation
+
+    procedure PASCALMAIN; external name 'PASCALMAIN';
+
+    procedure _FPC_haltproc; assembler; nostackframe; public name '_haltproc';
+      asm
+        cli
+      .Lhalt:
+        xjmp .Lhalt
+      end;
+
+    var
+      _data: record end; external name '_data';
+      _edata: record end; external name '_edata';
+      _etext: record end; external name '_etext';
+      _bss_start: record end; external name '_bss_start';
+      _bss_end: record end; external name '_bss_end';
+      _stack_top: record end; external name '_stack_top';
+
+    procedure _FPC_start; assembler; nostackframe;
+      label
+        _start;
+      asm
+        // code derived from phillips appnote 10254
+        .init
+        .align 16
+        .globl _start
+        b   _start
+        b   .LUndefined_Addr  // Undefined Instruction vector
+        b   .LSWI_Addr        // Software Interrupt vector
+        b   .LPrefetch_Addr   // Prefetch abort vector
+        b   .LAbort_Addr      // Data abort vector
+        nop                   // reserved
+        b   .LIRQ_Addr        // Interrupt Request (IRQ) vector
+        b   .LFIQ_Addr        // Fast interrupt request (FIQ) vector
+
+    .LUndefined_Addr:
+        ldr r0,.L1
+        ldr pc,[r0]
+    .LSWI_Addr:
+        ldr r0,.L2
+        ldr pc,[r0]
+    .LPrefetch_Addr:
+        ldr r0,.L3
+        ldr pc,[r0]
+    .LAbort_Addr:
+        ldr r0,.L4
+        ldr pc,[r0]
+    .LIRQ_Addr:
+        ldr r0,.L5
+        ldr pc,[r0]
+    .LFIQ_Addr:
+        ldr r0,.L5
+        ldr pc,[r0]
+
+    .L1:
+        .long     Undefined_Handler
+    .L2:
+        .long     SWI_Handler
+    .L3:
+        .long     Prefetch_Handler
+    .L4:
+        .long     Abort_Handler
+    .L5:
+        .long     IRQ_Handler
+    .L6:
+        .long     FIQ_Handler
+
+        {
+          all ATMEL MCUs use the same startup code, the details are
+          governed by defines
+        }
+        {$i start.inc}
+      end;
+
+end.

+ 33 - 0
rtl/embedded/avr/start.inc

@@ -0,0 +1,33 @@
+    _start:
+        clr r1
+        // load stack pointer
+        ldi r0,lo8(_stack_top)
+        out 0x3d,r0
+        ldi r0,hi8(_stack_top)
+        out 0x3e,r0
+
+
+
+        // copy initialized data from flash to ram
+        ldr r1,.L_etext
+        ldr r2,.L_data
+        ldr r3,.L_edata
+.Lcopyloop:
+        cmp r2,r3
+        ldrls r0,[r1],#4
+        strls r0,[r2],#4
+        bls .Lcopyloop
+
+        // clear onboard ram
+        ldr r1,.L_bss_start
+        ldr r2,.L_bss_end
+        mov r0,#0
+.Lzeroloop:
+        cmp r1,r2
+        strls r0,[r1],#4
+        bls .Lzeroloop
+
+        xcall PASCALMAIN
+        xcall _FPC_haltproc
+        .text
+

+ 7 - 0
rtl/inc/compproc.inc

@@ -580,6 +580,13 @@ function fpc_div_longint(n,z : longint) : longint; compilerproc;
 function fpc_mod_longint(n,z : longint) : longint; compilerproc;
 {$endif FPC_INCLUDE_SOFTWARE_MOD_DIV}
 
+{$ifdef FPC_INCLUDE_SOFTWARE_MUL}
+function fpc_mul_integer(f1,f2 : integer;checkoverflow : boolean) : integer; compilerproc;
+function fpc_mul_word(f1,f2 : word;checkoverflow : boolean) : word; compilerproc;
+function fpc_mul_longint(f1,f2 : longint;checkoverflow : boolean) : longint; compilerproc;
+function fpc_mul_dword(f1,f2 : dword;checkoverflow : boolean) : dword; compilerproc;
+{$endif FPC_INCLUDE_SOFTWARE_MUL}
+
 { from int64.inc }
 function fpc_div_qword(n,z : qword) : qword; compilerproc;
 function fpc_mod_qword(n,z : qword) : qword; compilerproc;

+ 158 - 0
rtl/inc/generic.inc

@@ -1287,6 +1287,164 @@ end;
                                  Math
 ****************************************************************************}
 
+{****************************************************************************
+                          Software multiplication
+****************************************************************************}
+
+{$ifndef FPC_SYSTEM_HAS_MUL_INTEGER}
+    function fpc_mul_integer(f1,f2 : integer;checkoverflow : boolean) : integer;[public,alias: 'FPC_MUL_INTEGER']; compilerproc;
+      var
+        sign : boolean;
+        q1,q2,q3 : word;
+      begin
+        begin
+           sign:=false;
+           if f1<0 then
+             begin
+                sign:=not(sign);
+                q1:=word(-f1);
+             end
+           else
+             q1:=f1;
+           if f2<0 then
+             begin
+                sign:=not(sign);
+                q2:=word(-f2);
+             end
+           else
+             q2:=f2;
+           { the q1*q2 is coded as call to mulqword }
+           q3:=q1*q2;
+
+           if checkoverflow and (q1 <> 0) and (q2 <>0) and
+           ((q1>q3) or (q2>q3) or
+             { the bit 63 can be only set if we have $8000 }
+             { and sign is true                            }
+             (q3 shr 15<>0) and
+              ((q3<>word(word(1) shl 15)) or not(sign))
+             ) then
+             HandleErrorFrame(215,get_frame);
+
+           if sign then
+             fpc_mul_integer:=-q3
+           else
+             fpc_mul_integer:=q3;
+        end;
+      end;
+{$endif FPC_SYSTEM_HAS_MUL_INTEGER}
+
+
+{$ifndef FPC_SYSTEM_HAS_MUL_WORD}
+    function fpc_mul_word(f1,f2 : word;checkoverflow : boolean) : word;[public,alias: 'FPC_MUL_WORD']; compilerproc;
+      var
+        _f1,bitpos : word;
+        b : byte;
+        f1overflowed : boolean;
+      begin
+        fpc_mul_word:=0;
+        bitpos:=1;
+        f1overflowed:=false;
+
+        for b:=0 to 15 do
+          begin
+            if (f2 and bitpos)<>0 then
+              begin
+                _f1:=fpc_mul_word;
+                fpc_mul_word:=fpc_mul_word+f1;
+
+                { if one of the operands is greater than the result an
+                  overflow occurs                                      }
+                if checkoverflow and (f1overflowed or ((_f1<>0) and (f1<>0) and
+                  ((_f1>fpc_mul_word) or (f1>fpc_mul_word)))) then
+                  HandleErrorFrame(215,get_frame);
+              end;
+            { when bootstrapping, we forget about overflow checking for qword :) }
+            f1overflowed:=f1overflowed or ((f1 and (1 shl 15))<>0);
+            f1:=f1 shl 1;
+            bitpos:=bitpos shl 1;
+          end;
+      end;
+{$endif FPC_SYSTEM_HAS_MUL_WORD}
+
+
+{$ifndef FPC_SYSTEM_HAS_MUL_LONGINT}
+    function fpc_mul_longint(f1,f2 : longint;checkoverflow : boolean) : longint;[public,alias: 'FPC_MUL_LONGINT']; compilerproc;
+      var
+        sign : boolean;
+        q1,q2,q3 : dword;
+      begin
+        begin
+           sign:=false;
+           if f1<0 then
+             begin
+                sign:=not(sign);
+                q1:=dword(-f1);
+             end
+           else
+             q1:=f1;
+           if f2<0 then
+             begin
+                sign:=not(sign);
+                q2:=dword(-f2);
+             end
+           else
+             q2:=f2;
+           { the q1*q2 is coded as call to mulqword }
+           q3:=q1*q2;
+
+           if checkoverflow and (q1 <> 0) and (q2 <>0) and
+           ((q1>q3) or (q2>q3) or
+             { the bit 31 can be only set if we have $8000 0000 }
+             { and sign is true                                 }
+             (q3 shr 15<>0) and
+              ((q3<>dword(dword(1) shl 31)) or not(sign))
+             ) then
+             HandleErrorFrame(215,get_frame);
+
+           if sign then
+             fpc_mul_longint:=-q3
+           else
+             fpc_mul_longint:=q3;
+        end;
+      end;
+{$endif FPC_SYSTEM_HAS_MUL_INTEGER}
+
+
+{$ifndef FPC_SYSTEM_HAS_MUL_DWORD}
+    { multiplies two dwords
+      the longbool for checkoverflow avoids a misaligned stack
+    }
+    function fpc_mul_dword(f1,f2 : dword;checkoverflow : boolean) : dword;[public,alias: 'FPC_MUL_DWORD']; compilerproc;
+      var
+        _f1,bitpos : dword;
+        b : byte;
+        f1overflowed : boolean;
+      begin
+        fpc_mul_dword:=0;
+        bitpos:=1;
+        f1overflowed:=false;
+
+        for b:=0 to 31 do
+          begin
+            if (f2 and bitpos)<>0 then
+              begin
+                _f1:=fpc_mul_dword;
+                fpc_mul_dword:=fpc_mul_dword+f1;
+
+                { if one of the operands is greater than the result an
+                  overflow occurs                                      }
+                if checkoverflow and (f1overflowed or ((_f1<>0) and (f1<>0) and
+                  ((_f1>fpc_mul_dword) or (f1>fpc_mul_dword)))) then
+                  HandleErrorFrame(215,get_frame);
+              end;
+            { when bootstrapping, we forget about overflow checking for qword :) }
+            f1overflowed:=f1overflowed or ((f1 and (1 shl 31))<>0);
+            f1:=f1 shl 1;
+            bitpos:=bitpos shl 1;
+          end;
+      end;
+{$endif FPC_SYSTEM_HAS_MUL_DWORD}
+
 {****************************************************************************
                           Software longint/dword division
 ****************************************************************************}

+ 2 - 2
rtl/inc/sstrings.inc

@@ -374,7 +374,7 @@ end;
 
 {$ifndef CPU64}
 
-procedure fpc_shortstr_qword(v : qword;len : longint;out s : shortstring);[public,alias:'FPC_SHORTSTR_QWORD']; compilerproc;
+procedure fpc_shortstr_qword(v : qword;len : SizeInt;out s : shortstring);[public,alias:'FPC_SHORTSTR_QWORD']; compilerproc;
 begin
   int_str(v,s);
   if length(s)<len then
@@ -382,7 +382,7 @@ begin
 end;
 
 
-procedure fpc_shortstr_int64(v : int64;len : longint;out s : shortstring);[public,alias:'FPC_SHORTSTR_INT64'];  compilerproc;
+procedure fpc_shortstr_int64(v : int64;len : SizeInt;out s : shortstring);[public,alias:'FPC_SHORTSTR_INT64'];  compilerproc;
 begin
   int_str(v,s);
   if length(s)<len then

+ 7 - 0
rtl/inc/system.inc

@@ -60,8 +60,13 @@ Const
   This way we keep TP compatibility, and the TextRec definition is available
   for everyone who needs it.
 }
+{$ifdef FPC_HAS_FEATURE_FILEIO}
 {$i filerec.inc}
+{$endif FPC_HAS_FEATURE_FILEIO}
+
+{$ifdef FPC_HAS_FEATURE_TEXTIO}
 {$i textrec.inc}
+{$endif FPC_HAS_FEATURE_TEXTIO}
 
 {$ifdef FPC_HAS_FEATURE_EXITCODE}
   {$ifdef FPC_OBJFPC_EXTENDED_IF}
@@ -76,8 +81,10 @@ Const
 Procedure HandleError (Errno : Longint); forward;
 Procedure HandleErrorFrame (Errno : longint;frame : Pointer); forward;
 
+{$ifdef FPC_HAS_FEATURE_TEXTIO}
 type
   FileFunc = Procedure(var t : TextRec);
+{$endif FPC_HAS_FEATURE_TEXTIO}
 
 
 const

+ 1 - 0
rtl/inc/systemh.inc

@@ -219,6 +219,7 @@ Type
   {$define DEFAULT_SINGLE}
 
   {$define FPC_INCLUDE_SOFTWARE_MOD_DIV}
+  {$define FPC_INCLUDE_SOFTWARE_MUL}
   {$define FPC_INCLUDE_SOFTWARE_SHIFT_INT64}
 
   {$ifndef FPUNONE}

+ 8 - 0
rtl/objpas/objpas.pp

@@ -32,10 +32,18 @@ unit objpas;
        PString = PAnsiString;
 
        { array types }
+{$ifdef CPU16}
+       IntegerArray  = array[0..$eff] of Integer;
+{$else CPU16}
        IntegerArray  = array[0..$effffff] of Integer;
+{$endif CPU16}
        TIntegerArray = IntegerArray;
        PIntegerArray = ^IntegerArray;
+{$ifdef CPU16}
+       PointerArray  = array [0..16*1024-2] of Pointer;
+{$else CPU16}
        PointerArray  = array [0..512*1024*1024-2] of Pointer;
+{$endif CPU16}
        TPointerArray = PointerArray;
        PPointerArray = ^PointerArray;
        TBoundArray = array of integer;

+ 242 - 240
utils/fpcmkcfg/fpccfg.inc

@@ -1,252 +1,254 @@
 {$ifdef Delphi}
-const DefaultConfig : array[0..25] of string[240]=(
+const DefaultConfig : array[0..26] of string[240]=(
 {$else Delphi}
-const DefaultConfig : array[0..25,1..240] of char=(
+const DefaultConfig : array[0..26,1..240] of char=(
 {$endif Delphi}
-  '#'#010+
-  '# Config file generated by fpcmkcfg on %BUILDDATE% - %BUILDTIME%'#010+
-  '# Example fpc.cfg for Free Pascal Compiler'#010+
-  '#'#010+
-  #010+
-  '# ----------------------'#010+
-  '# Defines (preprocessor)'#010+
-  '# ----------------------'#010+
-  #010+
-  '#'#010+
-  '# nested #IFNDEF, #IFDEF, #ENDIF, #ELSE, #DEFINE,',' #UNDEF are allowed'+
-  #010+
-  '#'#010+
-  '# -d is the same as #DEFINE'#010+
-  '# -u is the same as #UNDEF'#010+
-  '#'#010+
-  #010+
-  '#'#010+
-  '# Some examples (for switches see below, and the -? helppages)'#010+
-  '#'#010+
-  '# Try compiling with the -dRELEASE or -dDEBUG on the commandline'#010+
-  '#'#010+
-  #010+
-  '# For a release compile w','ith optimizes and strip debuginfo'#010+
-  '#IFDEF RELEASE'#010+
-  '  -O2'#010+
-  '  -Xs'#010+
-  '  #WRITE Compiling Release Version'#010+
-  '#ENDIF'#010+
-  #010+
+  '#'#013#010+
+  '# Config file generated by fpcmkcfg on %BUILDDATE% - %BUILDTIME%'#013#010+
+  '# Example fpc.cfg for Free Pascal Compiler'#013#010+
+  '#'#013#010+
+  #013#010+
+  '# ----------------------'#013#010+
+  '# Defines (preprocessor)'#013#010+
+  '# ----------------------'#013#010+
+  #013#010+
+  '#'#013#010+
+  '# nested #IFNDEF, #IFDEF, #ENDIF, #ELSE',', #DEFINE, #UNDEF are allowed'+
+  #013#010+
+  '#'#013#010+
+  '# -d is the same as #DEFINE'#013#010+
+  '# -u is the same as #UNDEF'#013#010+
+  '#'#013#010+
+  #013#010+
+  '#'#013#010+
+  '# Some examples (for switches see below, and the -? helppages)'#013#010+
+  '#'#013#010+
+  '# Try compiling with the -dRELEASE or -dDEBUG on the commandline'#013#010+
+  '#'#013#010+
+  #013#010+
+  '# F','or a release compile with optimizes and strip debuginfo'#013#010+
+  '#IFDEF RELEASE'#013#010+
+  '  -O2'#013#010+
+  '  -Xs'#013#010+
+  '  #WRITE Compiling Release Version'#013#010+
+  '#ENDIF'#013#010+
+  #013#010+
   '# For a debug version compile with debuginfo and all codegeneration ch'+
-  'ecks on'#010+
-  '#IFDEF DEBUG'#010+
-  '  -gl'#010+
-  '  -Crtoi'#010+
-  '  #WRITE Compiling Debug Versi','on'#010+
-  '#ENDIF'#010+
-  #010+
-  '# assembling'#010+
-  '#ifdef darwin'#010+
-  '# use pipes instead of temporary files for assembling'#010+
-  '-ap'#010+
-  '#endif'#010+
-  #010+
-  '# ----------------'#010+
-  '# Parsing switches'#010+
-  '# ----------------'#010+
-  #010+
-  '# Pascal language mode'#010+
-  '#      -Mfpc      free pascal dialect (default)'#010+
-  '#      ','-Mobjfpc   switch some Delphi 2 extensions on'#010+
-  '#      -Mdelphi   tries to be Delphi compatible'#010+
-  '#      -Mtp       tries to be TP/BP 7.0 compatible'#010+
-  '#      -Mgpc      tries to be gpc compatible'#010+
-  '#      -Mmacpas   tries to be compatible to the ma','cintosh pascal dia'+
-  'lects'#010+
-  '#'#010+
-  '# Turn on Object Pascal extensions by default'#010+
-  '#-Mobjfpc'#010+
-  #010+
-  '# Assembler reader mode'#010+
-  '#      -Rdefault  use default assembler'#010+
-  '#      -Ratt      read AT&T style assembler'#010+
-  '#      -Rintel    read Intel style assembler'#010+
-  '#'#010+
-  '# ','All assembler blocks are AT&T styled by default'#010+
-  '#-Ratt'#010+
-  #010+
-  '# Semantic checking'#010+
-  '#      -S2        same as -Mobjfpc'#010+
-  '#      -Sc        supports operators like C (*=,+=,/= and -=)'#010+
-  '#      -Sa        include assertion code.'#010+
-  '#      -Sd        same as',' -Mdelphi'#010+
+  'ecks on'#013#010+
+  '#IFDEF DEBUG'#013#010+
+  '  -gl'#013#010+
+  '  -Crto','i'#013#010+
+  '  #WRITE Compiling Debug Version'#013#010+
+  '#ENDIF'#013#010+
+  #013#010+
+  '# assembling'#013#010+
+  '#ifdef darwin'#013#010+
+  '# use pipes instead of temporary files for assembling'#013#010+
+  '-ap'#013#010+
+  '#endif'#013#010+
+  #013#010+
+  '# ----------------'#013#010+
+  '# Parsing switches'#013#010+
+  '# ----------------'#013#010+
+  #013#010+
+  '# Pascal language mode'#013#010+
+  '#      -','Mfpc      free pascal dialect (default)'#013#010+
+  '#      -Mobjfpc   switch some Delphi 2 extensions on'#013#010+
+  '#      -Mdelphi   tries to be Delphi compatible'#013#010+
+  '#      -Mtp       tries to be TP/BP 7.0 compatible'#013#010+
+  '#      -Mgpc      tries to be gpc compatible',#013#010+
+  '#      -Mmacpas   tries to be compatible to the macintosh pascal diale'+
+  'cts'#013#010+
+  '#'#013#010+
+  '# Turn on Object Pascal extensions by default'#013#010+
+  '#-Mobjfpc'#013#010+
+  #013#010+
+  '# Assembler reader mode'#013#010+
+  '#      -Rdefault  use default assembler'#013#010+
+  '#      -Ratt      read AT&T style ','assembler'#013#010+
+  '#      -Rintel    read Intel style assembler'#013#010+
+  '#'#013#010+
+  '# All assembler blocks are AT&T styled by default'#013#010+
+  '#-Ratt'#013#010+
+  #013#010+
+  '# Semantic checking'#013#010+
+  '#      -S2        same as -Mobjfpc'#013#010+
+  '#      -Sc        supports operators like C (*=,+=,/= and -=)'#013,#010+
+  '#      -Sa        include assertion code.'#013#010+
+  '#      -Sd        same as -Mdelphi'#013#010+
   '#      -Se<x>     error options. <x> is a combination of the following'+
-  ':'#010+
-  '#         <n> : compiler stops after <n> errors (default is 1)'#010+
-  '#         w   : compiler stops also after warnings'#010+
-  '#         n   : compiler stops also after no','tes'#010+
-  '#         h   : compiler stops also after hints'#010+
-  '#      -Sg        allow LABEL and GOTO'#010+
-  '#      -Sh        Use ansistrings'#010+
-  '#      -Si        support C++ styled INLINE'#010+
-  '#      -Sk        load fpcylix unit'#010+
-  '#      -SI<x>     set interface sty','le to <x>'#010+
-  '#         -SIcom    COM compatible interface (default)'#010+
-  '#         -SIcorba  CORBA compatible interface'#010+
-  '#      -Sm        support macros like C (global)'#010+
-  '#      -So        same as -Mtp'#010+
-  '#      -Sp        same as -Mgpc'#010+
-  '#      -Ss      ','  constructor name must be init (destructor must be '+
-  'done)'#010+
+  ':'#013#010+
+  '#         <n> : compiler stops after <n> errors (default is 1)'#013#010+
+  '#         w   : compile','r stops also after warnings'#013#010+
+  '#         n   : compiler stops also after notes'#013#010+
+  '#         h   : compiler stops also after hints'#013#010+
+  '#      -Sg        allow LABEL and GOTO'#013#010+
+  '#      -Sh        Use ansistrings'#013#010+
+  '#      -Si        support C++ styled I','NLINE'#013#010+
+  '#      -Sk        load fpcylix unit'#013#010+
+  '#      -SI<x>     set interface style to <x>'#013#010+
+  '#         -SIcom    COM compatible interface (default)'#013#010+
+  '#         -SIcorba  CORBA compatible interface'#013#010+
+  '#      -Sm        support macros like C (globa','l)'#013#010+
+  '#      -So        same as -Mtp'#013#010+
+  '#      -Sp        same as -Mgpc'#013#010+
+  '#      -Ss        constructor name must be init (destructor must be do'+
+  'ne)'#013#010+
   '#      -Sx        enable exception keywords (default in Delphi/ObjFPC '+
-  'modes)'#010+
-  '#'#010+
-  '# Allow goto, inline, C-operators, C-vars'#010+
-  '-Sgic'#010+
-  #010+
-  '# ---------------'#010+
-  '# Code generation'#010+
-  '# ---------------'#010,
-  #010+
+  'modes)'#013#010+
+  '#'#013#010+
+  '# Allow goto, i','nline, C-operators, C-vars'#013#010+
+  '-Sgic'#013#010+
+  #013#010+
+  '# ---------------'#013#010+
+  '# Code generation'#013#010+
+  '# ---------------'#013#010+
+  #013#010+
   '# Uncomment the next line if you always want static/dynamic units by d'+
-  'efault'#010+
-  '# (can be overruled with -CD, -CS at the commandline)'#010+
-  '#-CS'#010+
-  '#-CD'#010+
-  #010+
-  '# Set the default heapsize to 8Mb'#010+
-  '#-Ch8000000'#010+
-  #010+
-  '# Set default codegeneration checks (iocheck, over','flow, range, stack'+
-  ')'#010+
-  '#-Ci'#010+
-  '#-Co'#010+
-  '#-Cr'#010+
-  '#-Ct'#010+
-  #010+
-  '# Optimizer switches'#010+
-  '# -Os        generate smaller code'#010+
-  '# -Oa=N      set alignment to N'#010+
-  '# -O1        level 1 optimizations (quick optimizations, debuggable)'#010+
-  '# -O2        level 2 optimizations (-O1 + ','optimizations which make d'+
-  'ebugging more difficult)'#010+
+  'efault'#013#010+
+  '# (can be overruled with -CD, -CS at the commandline)'#013#010+
+  '#-CS'#013#010+
+  '#-CD'#013,#010+
+  #013#010+
+  '# Set the default heapsize to 8Mb'#013#010+
+  '#-Ch8000000'#013#010+
+  #013#010+
+  '# Set default codegeneration checks (iocheck, overflow, range, stack)'#013+
+  #010+
+  '#-Ci'#013#010+
+  '#-Co'#013#010+
+  '#-Cr'#013#010+
+  '#-Ct'#013#010+
+  #013#010+
+  '# Optimizer switches'#013#010+
+  '# -Os        generate smaller code'#013#010+
+  '# -Oa=N      set alignment to N'#013,#010+
+  '# -O1        level 1 optimizations (quick optimizations, debuggable)'#013+
+  #010+
+  '# -O2        level 2 optimizations (-O1 + optimizations which make deb'+
+  'ugging more difficult)'#013#010+
   '# -O3        level 3 optimizations (-O2 + optimizations which also may'+
-  ' make the program slower rather than faster)'#010+
+  ' make',' the program slower rather than faster)'#013#010+
   '# -Oo<x>     switch on optimalization x. See fpc -i for possible value'+
-  's'#010+
-  '# ','-OoNO<x>   switch off optimalization x. See fpc -i for possible va'+
-  'lues'#010+
-  '# -Op<x>     set target cpu for optimizing, see fpc -i for possible va'+
-  'lues'#010+
-  #010+
-  '#ifdef darwin'#010+
-  '#ifdef cpui386'#010+
-  '-Cppentiumm'#010+
-  '-Oppentiumm'#010+
-  '#endif'#010+
-  '#endif'#010+
-  #010+
-  '# -----------------------',#010+
-  '# Set Filenames and Paths'#010+
-  '# -----------------------'#010+
-  #010+
-  '# Both slashes and backslashes are allowed in paths'#010+
-  #010+
-  '# path to the messagefile, not necessary anymore but can be used to ov'+
-  'erride'#010+
-  '# the default language'#010+
-  '#-Fr%basepath%/msg/errore.msg'#010+
-  '#-F','r%basepath%/msg/errorn.msg'#010+
-  '#-Fr%basepath%/msg/errores.msg'#010+
-  '#-Fr%basepath%/msg/errord.msg'#010+
-  '#-Fr%basepath%/msg/errorr.msg'#010+
-  #010+
-  '# searchpath for units and other system dependent things'#010+
-  '-Fu%basepath%/units/$fpctarget'#010+
-  '-Fu%basepath%/units/$fpctarget/*'#010,
-  '-Fu%basepath%/units/$fpctarget/rtl'#010+
-  #010+
-  '#IFDEF FPCAPACHE_1_3'#010+
-  '-Fu%basepath%/units/$fpctarget/httpd13/'#010+
-  '#ELSE'#010+
-  '#IFDEF FPCAPACHE_2_0'#010+
-  '-Fu%basepath%/units/$fpctarget/httpd20'#010+
-  '#ELSE'#010+
-  '-Fu%basepath%/units/$fpctarget/httpd22'#010+
-  '#ENDIF'#010+
-  '#ENDIF'#010+
-  #010+
-  '# searchpath for ','fppkg user-specific packages'#010+
-  '-Fu%localbasepath%/units/$FPCTARGET/*'#010+
-  #010+
-  '# path to the gcclib'#010+
-  '%gcclibpath%'#010+
-  #010+
-  '# searchpath for libraries'#010+
-  '#-Fl%basepath%/lib'#010+
-  '#-Fl/lib;/usr/lib'#010+
-  #010+
-  '# searchpath for tools'#010+
-  '-FD%basepath%/bin/$FPCTARGET'#010+
-  #010+
-  '%NEEDCROSSBINUTILSI','FDEF%'#010+
-  #010+
-  '# binutils prefix for cross compiling'#010+
-  '#IFDEF FPC_CROSSCOMPILING'#010+
-  '#IFDEF NEEDCROSSBINUTILS'#010+
-  '  -XP$FPCTARGET-'#010+
-  '#ENDIF'#010+
-  '#ENDIF'#010+
-  #010+
-  #010+
-  '# -------------'#010+
-  '# Linking'#010+
-  '# -------------'#010+
-  #010+
-  '# generate always debugging information for GDB (slows down the comp','i'+
-  'ling'#010+
-  '# process)'#010+
-  '#      -gc        generate checks for pointers'#010+
-  '#      -gd        use dbx'#010+
-  '#      -gg        use gsym'#010+
-  '#      -gh        use heap trace unit (for memory leak debugging)'#010+
-  '#      -gl        use line info unit to show more info fo','r backtrace'+
-  's'#010+
-  '#      -gv        generates programs tracable with valgrind'#010+
-  '#      -gw        generate dwarf debugging info'#010+
-  '#'#010+
-  '# Enable debuginfo and use the line info unit by default'#010+
-  '#-gl'#010+
-  #010+
-  '# always pass an option to the linker'#010+
-  '#-k-s'#010+
-  #010+
-  '# Always ','strip debuginfo from the executable'#010+
-  '-Xs'#010+
-  #010+
-  #010+
-  '# -------------'#010+
-  '# Miscellaneous'#010+
-  '# -------------'#010+
-  #010+
-  '# Write always a nice FPC logo ;)'#010+
-  '-l'#010+
-  #010+
-  '# Verbosity'#010+
-  '#      e : Show errors (default)       d : Show debug info'#010+
-  '#      w : Show warnings               u',' : Show unit info'#010+
-  '#      n : Show notes                  t : Show tried/used files'#010+
-  '#      h : Show hints                  s : Show time stamps'#010+
-  '#      i : Show general info           q : Show message numbers'#010+
-  '#      l : Show linenumbers      ','      c : Show conditionals'#010+
+  's'#013#010+
+  '# -OoNO<x>   switch off optimalization x. See fpc -i for possible valu'+
+  'es'#013#010+
+  '# -Op<x>     set target cpu for optimizing, see fpc ','-i for possible '+
+  'values'#013#010+
+  #013#010+
+  '#ifdef darwin'#013#010+
+  '#ifdef cpui386'#013#010+
+  '-Cppentiumm'#013#010+
+  '-Oppentiumm'#013#010+
+  '#endif'#013#010+
+  '#endif'#013#010+
+  #013#010+
+  '# -----------------------'#013#010+
+  '# Set Filenames and Paths'#013#010+
+  '# -----------------------'#013#010+
+  #013#010+
+  '# Both slashes and backslashes are allowed in paths'#013#010+
+  #013#010+
+  '#',' path to the messagefile, not necessary anymore but can be used to '+
+  'override'#013#010+
+  '# the default language'#013#010+
+  '#-Fr%basepath%/msg/errore.msg'#013#010+
+  '#-Fr%basepath%/msg/errorn.msg'#013#010+
+  '#-Fr%basepath%/msg/errores.msg'#013#010+
+  '#-Fr%basepath%/msg/errord.msg'#013#010+
+  '#-Fr%basepath%','/msg/errorr.msg'#013#010+
+  #013#010+
+  '# searchpath for units and other system dependent things'#013#010+
+  '-Fu%basepath%/units/$fpctarget'#013#010+
+  '-Fu%basepath%/units/$fpctarget/*'#013#010+
+  '-Fu%basepath%/units/$fpctarget/rtl'#013#010+
+  #013#010+
+  '#IFDEF FPCAPACHE_1_3'#013#010+
+  '-Fu%basepath%/units/$fpctarget/httpd1','3/'#013#010+
+  '#ELSE'#013#010+
+  '#IFDEF FPCAPACHE_2_0'#013#010+
+  '-Fu%basepath%/units/$fpctarget/httpd20'#013#010+
+  '#ELSE'#013#010+
+  '-Fu%basepath%/units/$fpctarget/httpd22'#013#010+
+  '#ENDIF'#013#010+
+  '#ENDIF'#013#010+
+  #013#010+
+  '# searchpath for fppkg user-specific packages'#013#010+
+  '-Fu%localbasepath%/units/$FPCTARGET/*'#013#010+
+  #013#010+
+  '# path to the ','gcclib'#013#010+
+  '%gcclibpath%'#013#010+
+  #013#010+
+  '# searchpath for libraries'#013#010+
+  '#-Fl%basepath%/lib'#013#010+
+  '#-Fl/lib;/usr/lib'#013#010+
+  #013#010+
+  '# searchpath for tools'#013#010+
+  '-FD%basepath%/bin/$FPCTARGET'#013#010+
+  #013#010+
+  '%NEEDCROSSBINUTILSIFDEF%'#013#010+
+  #013#010+
+  '# binutils prefix for cross compiling'#013#010+
+  '#IFDEF FPC_CROSSCOMPILIN','G'#013#010+
+  '#IFDEF NEEDCROSSBINUTILS'#013#010+
+  '  -XP$FPCTARGET-'#013#010+
+  '#ENDIF'#013#010+
+  '#ENDIF'#013#010+
+  #013#010+
+  #013#010+
+  '# -------------'#013#010+
+  '# Linking'#013#010+
+  '# -------------'#013#010+
+  #013#010+
+  '# generate always debugging information for GDB (slows down the compil'+
+  'ing'#013#010+
+  '# process)'#013#010+
+  '#      -gc        generate checks for p','ointers'#013#010+
+  '#      -gd        use dbx'#013#010+
+  '#      -gg        use gsym'#013#010+
+  '#      -gh        use heap trace unit (for memory leak debugging)'#013#010+
+  '#      -gl        use line info unit to show more info for backtraces'#013+
+  #010+
+  '#      -gv        generates programs t','racable with valgrind'#013#010+
+  '#      -gw        generate dwarf debugging info'#013#010+
+  '#'#013#010+
+  '# Enable debuginfo and use the line info unit by default'#013#010+
+  '#-gl'#013#010+
+  #013#010+
+  '# always pass an option to the linker'#013#010+
+  '#-k-s'#013#010+
+  #013#010+
+  '# Always strip debuginfo from the executable'#013#010+
+  '-Xs'#013#010,
+  #013#010+
+  #013#010+
+  '# -------------'#013#010+
+  '# Miscellaneous'#013#010+
+  '# -------------'#013#010+
+  #013#010+
+  '# Write always a nice FPC logo ;)'#013#010+
+  '-l'#013#010+
+  #013#010+
+  '# Verbosity'#013#010+
+  '#      e : Show errors (default)       d : Show debug info'#013#010+
+  '#      w : Show warnings               u : Show unit info'#013#010+
+  '#      n :',' Show notes                  t : Show tried/used files'#013+
+  #010+
+  '#      h : Show hints                  s : Show time stamps'#013#010+
+  '#      i : Show general info           q : Show message numbers'#013#010+
+  '#      l : Show linenumbers            c : Show conditiona','ls'#013#010+
   '#      a : Show everything             0 : Show nothing (except errors'+
-  ')'#010+
+  ')'#013#010+
   '#      b : Write file names messages   r : Rhide/GCC compatibility mod'+
-  'e'#010+
-  '#          with full path              x : Executable info (Win32 on','l'+
-  'y)'#010+
-  '#      v : write fpcdebug.txt with     p : Write tree.log with parse t'+
-  'ree'#010+
-  '#          lots of debugging info'#010+
-  '#'#010+
-  '# Display Info, Warnings and Notes'#010+
-  '-viwn'#010+
-  '# If you don'#039't want so much verbosity use'#010+
-  '#-vw'#010
+  'e'#013#010+
+  '#          with full path              x : Executable info (Win32 only'+
+  ')'#013#010+
+  '#      v : write ','fpcdebug.txt with     p : Write tree.log with parse'+
+  ' tree'#013#010+
+  '#          lots of debugging info'#013#010+
+  '#'#013#010+
+  '# Display Info, Warnings and Notes'#013#010+
+  '-viwn'#013#010+
+  '# If you don'#039't want so much verbosity use'#013#010+
+  '#-vw'#013#010
 );

+ 11 - 11
utils/fpcmkcfg/fppkg.inc

@@ -3,15 +3,15 @@ const fppkg : array[0..1] of string[240]=(
 {$else Delphi}
 const fppkg : array[0..1,1..240] of char=(
 {$endif Delphi}
-  '[Defaults]'#010+
-  'ConfigVersion=4'#010+
-  'LocalRepository=%LocalRepository%'#010+
-  'BuildDir={LocalRepository}build/'#010+
-  'ArchivesDir={LocalRepository}archives/'#010+
-  'CompilerConfigDir=%CompilerConfigDir%'#010+
-  'RemoteMirrors=http://www.freepascal.org/repository/mirrors.xml'#010+
-  'Remote','Repository=auto'#010+
-  'CompilerConfig=default'#010+
-  'FPMakeCompilerConfig=default'#010+
-  'Downloader=lnet'#010
+  '[Defaults]'#013#010+
+  'ConfigVersion=4'#013#010+
+  'LocalRepository=%LocalRepository%'#013#010+
+  'BuildDir={LocalRepository}build/'#013#010+
+  'ArchivesDir={LocalRepository}archives/'#013#010+
+  'CompilerConfigDir=%CompilerConfigDir%'#013#010+
+  'RemoteMirrors=http://www.freepascal.org/repository/mirrors.xml'#013,#010+
+  'RemoteRepository=auto'#013#010+
+  'CompilerConfig=default'#013#010+
+  'FPMakeCompilerConfig=default'#013#010+
+  'Downloader=lnet'#013#010
 );

Some files were not shown because too many files changed in this diff