浏览代码

+ AVR: initial support for the avrtiny architecture

git-svn-id: trunk@43987 -
florian 5 年之前
父节点
当前提交
2d9cdab264
共有 3 个文件被更改,包括 64 次插入27 次删除
  1. 50 20
      compiler/avr/cgcpu.pas
  2. 8 3
      compiler/avr/cpupara.pas
  3. 6 4
      compiler/avr/rgcpu.pas

+ 50 - 20
compiler/avr/cgcpu.pas

@@ -148,10 +148,14 @@ unit cgcpu;
     procedure tcgavr.init_register_allocators;
     procedure tcgavr.init_register_allocators;
       begin
       begin
         inherited init_register_allocators;
         inherited init_register_allocators;
-        rg[R_INTREGISTER]:=trgintcpu.create(R_INTREGISTER,R_SUBWHOLE,
-            [RS_R18,RS_R19,RS_R20,RS_R21,RS_R22,RS_R23,RS_R24,RS_R25,
-             RS_R2,RS_R3,RS_R4,RS_R5,RS_R6,RS_R7,RS_R8,RS_R9,
-             RS_R10,RS_R11,RS_R12,RS_R13,RS_R14,RS_R15,RS_R16,RS_R17],first_int_imreg,[]);
+        if CPUAVR_16_REGS in cpu_capabilities[current_settings.cputype] then
+          rg[R_INTREGISTER]:=trgintcpu.create(R_INTREGISTER,R_SUBWHOLE,
+              [RS_R18,RS_R19,RS_R20,RS_R21,RS_R22,RS_R23,RS_R24,RS_R25],first_int_imreg,[])
+        else
+          rg[R_INTREGISTER]:=trgintcpu.create(R_INTREGISTER,R_SUBWHOLE,
+              [RS_R18,RS_R19,RS_R20,RS_R21,RS_R22,RS_R23,RS_R24,RS_R25,
+               RS_R2,RS_R3,RS_R4,RS_R5,RS_R6,RS_R7,RS_R8,RS_R9,
+               RS_R10,RS_R11,RS_R12,RS_R13,RS_R14,RS_R15,RS_R16,RS_R17],first_int_imreg,[]);
       end;
       end;
 
 
 
 
@@ -1218,7 +1222,8 @@ unit cgcpu;
              if not((href.addressmode=AM_UNCHANGED) and
              if not((href.addressmode=AM_UNCHANGED) and
                     (href.symbol=nil) and
                     (href.symbol=nil) and
                      (href.Index=NR_NO) and
                      (href.Index=NR_NO) and
-                     (href.Offset in [0..64-tcgsize2size[fromsize]])) then
+                     (href.Offset in [0..64-tcgsize2size[fromsize]])) or
+                (CPUAVR_16_REGS in cpu_capabilities[current_settings.cputype]) then
                begin
                begin
                  href:=normalize_ref(list,href,NR_R30);
                  href:=normalize_ref(list,href,NR_R30);
                  getcpuregister(list,NR_R30);
                  getcpuregister(list,NR_R30);
@@ -1435,7 +1440,8 @@ unit cgcpu;
              if not((href.addressmode=AM_UNCHANGED) and
              if not((href.addressmode=AM_UNCHANGED) and
                     (href.symbol=nil) and
                     (href.symbol=nil) and
                      (href.Index=NR_NO) and
                      (href.Index=NR_NO) and
-                     (href.Offset in [0..64-tcgsize2size[fromsize]])) then
+                     (href.Offset in [0..64-tcgsize2size[fromsize]])) or
+                (CPUAVR_16_REGS in cpu_capabilities[current_settings.cputype]) then
                begin
                begin
                  href:=normalize_ref(list,href,NR_R30);
                  href:=normalize_ref(list,href,NR_R30);
                  getcpuregister(list,NR_R30);
                  getcpuregister(list,NR_R30);
@@ -2442,9 +2448,11 @@ unit cgcpu;
             reference_reset(srcref,source.alignment,source.volatility);
             reference_reset(srcref,source.alignment,source.volatility);
             reference_reset(dstref,dest.alignment,source.volatility);
             reference_reset(dstref,dest.alignment,source.volatility);
             srcref.base:=NR_R30;
             srcref.base:=NR_R30;
-            srcref.addressmode:=AM_POSTINCREMENT;
+            if not(CPUAVR_16_REGS in cpu_capabilities[current_settings.cputype]) then
+              srcref.addressmode:=AM_POSTINCREMENT;
             dstref.base:=NR_R26;
             dstref.base:=NR_R26;
-            dstref.addressmode:=AM_POSTINCREMENT;
+            if not(CPUAVR_16_REGS in cpu_capabilities[current_settings.cputype]) then
+              dstref.addressmode:=AM_POSTINCREMENT;
 
 
             copysize:=OS_8;
             copysize:=OS_8;
             if len<256 then
             if len<256 then
@@ -2490,6 +2498,14 @@ unit cgcpu;
             cg.getcpuregister(list,GetDefaultTmpReg);
             cg.getcpuregister(list,GetDefaultTmpReg);
             list.concat(taicpu.op_reg_ref(GetLoad(srcref),GetDefaultTmpReg,srcref));
             list.concat(taicpu.op_reg_ref(GetLoad(srcref),GetDefaultTmpReg,srcref));
             list.concat(taicpu.op_ref_reg(GetStore(dstref),dstref,GetDefaultTmpReg));
             list.concat(taicpu.op_ref_reg(GetStore(dstref),dstref,GetDefaultTmpReg));
+
+            if CPUAVR_16_REGS in cpu_capabilities[current_settings.cputype] then
+              begin
+                list.concat(taicpu.op_reg_const(A_SUBI,NR_R30,$ff));
+                list.concat(taicpu.op_reg_const(A_SBCI,NR_R31,$ff));
+                list.concat(taicpu.op_reg_const(A_SUBI,NR_R26,$ff));
+                list.concat(taicpu.op_reg_const(A_SBCI,NR_R27,$ff));
+              end;
             cg.ungetcpuregister(list,GetDefaultTmpReg);
             cg.ungetcpuregister(list,GetDefaultTmpReg);
             if tcgsize2size[countregsize] = 1 then
             if tcgsize2size[countregsize] = 1 then
               list.concat(taicpu.op_reg(A_DEC,countreg))
               list.concat(taicpu.op_reg(A_DEC,countreg))
@@ -2511,17 +2527,20 @@ unit cgcpu;
           begin
           begin
             SrcQuickRef:=false;
             SrcQuickRef:=false;
             DestQuickRef:=false;
             DestQuickRef:=false;
-            if not((source.addressmode=AM_UNCHANGED) and
-                   (source.symbol=nil) and
-                   ((source.base=NR_R28) or
-                    (source.base=NR_R30)) and
-                    (source.Index=NR_NO) and
-                    (source.Offset in [0..64-len])) and
-              not((source.Base=NR_NO) and (source.Index=NR_NO)) then
+            if (CPUAVR_16_REGS in cpu_capabilities[current_settings.cputype]) or
+              (
+                 not((source.addressmode=AM_UNCHANGED) and
+                     (source.symbol=nil) and
+                     ((source.base=NR_R28) or
+                      (source.base=NR_R30)) and
+                      (source.Index=NR_NO) and
+                      (source.Offset in [0..64-len])) and
+                not((source.Base=NR_NO) and (source.Index=NR_NO))
+              ) then
               begin
               begin
                 cg.getcpuregister(list,NR_R30);
                 cg.getcpuregister(list,NR_R30);
                 cg.getcpuregister(list,NR_R31);
                 cg.getcpuregister(list,NR_R31);
-                srcref:=normalize_ref(list,source,NR_R30)
+                srcref:=normalize_ref(list,source,NR_R30);
               end
               end
             else
             else
               begin
               begin
@@ -2529,13 +2548,16 @@ unit cgcpu;
                 srcref:=source;
                 srcref:=source;
               end;
               end;
 
 
-            if not((dest.addressmode=AM_UNCHANGED) and
+            if (CPUAVR_16_REGS in cpu_capabilities[current_settings.cputype]) or
+              (
+                 not((dest.addressmode=AM_UNCHANGED) and
                    (dest.symbol=nil) and
                    (dest.symbol=nil) and
                    ((dest.base=NR_R28) or
                    ((dest.base=NR_R28) or
                     (dest.base=NR_R30)) and
                     (dest.base=NR_R30)) and
                     (dest.Index=NR_No) and
                     (dest.Index=NR_No) and
                     (dest.Offset in [0..64-len])) and
                     (dest.Offset in [0..64-len])) and
-              not((dest.Base=NR_NO) and (dest.Index=NR_NO)) then
+                not((dest.Base=NR_NO) and (dest.Index=NR_NO))
+              ) then
               begin
               begin
                 if not(SrcQuickRef) then
                 if not(SrcQuickRef) then
                   begin
                   begin
@@ -2633,12 +2655,12 @@ unit cgcpu;
             else
             else
               for i:=1 to len do
               for i:=1 to len do
                 begin
                 begin
-                  if not(SrcQuickRef) and (i<len) then
+                  if not(SrcQuickRef) and (i<len) and not(CPUAVR_16_REGS in cpu_capabilities[current_settings.cputype]) then
                     srcref.addressmode:=AM_POSTINCREMENT
                     srcref.addressmode:=AM_POSTINCREMENT
                   else
                   else
                     srcref.addressmode:=AM_UNCHANGED;
                     srcref.addressmode:=AM_UNCHANGED;
 
 
-                  if not(DestQuickRef) and (i<len) then
+                  if not(DestQuickRef) and (i<len) and not(CPUAVR_16_REGS in cpu_capabilities[current_settings.cputype]) then
                     dstref.addressmode:=AM_POSTINCREMENT
                     dstref.addressmode:=AM_POSTINCREMENT
                   else
                   else
                     dstref.addressmode:=AM_UNCHANGED;
                     dstref.addressmode:=AM_UNCHANGED;
@@ -2648,6 +2670,14 @@ unit cgcpu;
                   list.concat(taicpu.op_ref_reg(GetStore(dstref),dstref,GetDefaultTmpReg));
                   list.concat(taicpu.op_ref_reg(GetStore(dstref),dstref,GetDefaultTmpReg));
                   cg.ungetcpuregister(list,GetDefaultTmpReg);
                   cg.ungetcpuregister(list,GetDefaultTmpReg);
 
 
+                  if (CPUAVR_16_REGS in cpu_capabilities[current_settings.cputype]) and (i<len) then
+                    begin
+                      list.concat(taicpu.op_reg_const(A_SUBI,srcref.base,$ff));
+                      list.concat(taicpu.op_reg_const(A_SBCI,TRegister(ord(srcref.base)+1),$ff));
+                      list.concat(taicpu.op_reg_const(A_SUBI,dstref.base,$ff));
+                      list.concat(taicpu.op_reg_const(A_SBCI,TRegister(ord(dstref.base)+1),$ff));
+                    end;
+
                   if SrcQuickRef then
                   if SrcQuickRef then
                     inc(srcref.offset);
                     inc(srcref.offset);
                   if DestQuickRef then
                   if DestQuickRef then

+ 8 - 3
compiler/avr/cpupara.pas

@@ -57,7 +57,10 @@ unit cpupara;
 
 
     function tcpuparamanager.get_volatile_registers_int(calloption : tproccalloption):tcpuregisterset;
     function tcpuparamanager.get_volatile_registers_int(calloption : tproccalloption):tcpuregisterset;
       begin
       begin
-        result:=VOLATILE_INTREGISTERS;
+        if CPUAVR_16_REGS in cpu_capabilities[current_settings.cputype] then
+          result:=VOLATILE_INTREGISTERS-[RS_R18,RS_R19]
+        else
+          result:=VOLATILE_INTREGISTERS;
       end;
       end;
 
 
 
 
@@ -204,7 +207,8 @@ unit cpupara;
         begin
         begin
           { In case of po_delphi_nested_cc, the parent frame pointer
           { In case of po_delphi_nested_cc, the parent frame pointer
             is always passed on the stack. }
             is always passed on the stack. }
-           if (nextintreg>RS_R9) and
+           if (((nextintreg>RS_R9) and not(CPUAVR_16_REGS in cpu_capabilities[current_settings.cputype])) or
+               (nextintreg>RS_R21)) and
               (not(vo_is_parentfp in hp.varoptions) or
               (not(vo_is_parentfp in hp.varoptions) or
                not(po_delphi_nested_cc in p.procoptions)) then
                not(po_delphi_nested_cc in p.procoptions)) then
              begin
              begin
@@ -303,7 +307,8 @@ unit cpupara;
                    by adding paralen mod 2, make the size even
                    by adding paralen mod 2, make the size even
                  }
                  }
                  nextintreg:=curintreg-(paralen+(paralen mod 2))+1;
                  nextintreg:=curintreg-(paralen+(paralen mod 2))+1;
-                 if nextintreg>=RS_R8 then
+                 if ((nextintreg>=RS_R8) and not(CPUAVR_16_REGS in cpu_capabilities[current_settings.cputype])) or
+                   (nextintreg>=RS_R20) then
                    curintreg:=nextintreg-1
                    curintreg:=nextintreg-1
                  else
                  else
                    begin
                    begin

+ 6 - 4
compiler/avr/rgcpu.pas

@@ -49,8 +49,10 @@ unit rgcpu;
 
 
     uses
     uses
       verbose, cutils,
       verbose, cutils,
+      globals,
       cgobj,
       cgobj,
-      procinfo;
+      procinfo,
+      cpuinfo;
 
 
 
 
     procedure trgcpu.add_constraints(reg:tregister);
     procedure trgcpu.add_constraints(reg:tregister);
@@ -95,7 +97,7 @@ unit rgcpu;
         helplist : TAsmList;
         helplist : TAsmList;
         hreg     : tregister;
         hreg     : tregister;
       begin
       begin
-        if abs(spilltemp.offset)>63 then
+        if (abs(spilltemp.offset)>63) or (CPUAVR_16_REGS in cpu_capabilities[current_settings.cputype]) then
           begin
           begin
             helplist:=TAsmList.create;
             helplist:=TAsmList.create;
 
 
@@ -121,7 +123,7 @@ unit rgcpu;
         helplist : TAsmList;
         helplist : TAsmList;
         hreg     : tregister;
         hreg     : tregister;
       begin
       begin
-        if abs(spilltemp.offset)>63 then
+        if (abs(spilltemp.offset)>63) or (CPUAVR_16_REGS in cpu_capabilities[current_settings.cputype]) then
           begin
           begin
             helplist:=TAsmList.create;
             helplist:=TAsmList.create;
 
 
@@ -187,7 +189,7 @@ unit rgcpu;
         b : byte;
         b : byte;
       begin
       begin
         result:=false;
         result:=false;
-        if not(spilltemp.offset in [0..63]) then
+        if not(spilltemp.offset in [0..63]) or (CPUAVR_16_REGS in cpu_capabilities[current_settings.cputype]) then
           exit;
           exit;
 
 
         { Replace 'mov  dst,orgreg' with 'ldd  dst,spilltemp'
         { Replace 'mov  dst,orgreg' with 'ldd  dst,spilltemp'