Browse Source

* for avr1, do not save registers during an interrupt procedure, as it has no memory to store them

git-svn-id: trunk@44139 -
florian 5 years ago
parent
commit
2135b9b724
5 changed files with 408 additions and 387 deletions
  1. 1 0
      compiler/avr/aasmcpu.pas
  2. 26 17
      compiler/avr/cgcpu.pas
  3. 5 1
      compiler/msg/errore.msg
  4. 3 2
      compiler/msgidx.inc
  5. 373 367
      compiler/msgtxt.inc

+ 1 - 0
compiler/avr/aasmcpu.pas

@@ -409,6 +409,7 @@ implementation
           i: Integer;
           i: Integer;
           hp: tai;
           hp: tai;
         begin
         begin
+          exit;
           taicpu(firstinstruction).opcode:=A_SLEEP;
           taicpu(firstinstruction).opcode:=A_SLEEP;
           for i:=0 to taicpu(firstinstruction).opercnt-1 do
           for i:=0 to taicpu(firstinstruction).opercnt-1 do
             taicpu(firstinstruction).freeop(i);
             taicpu(firstinstruction).freeop(i);

+ 26 - 17
compiler/avr/cgcpu.pas

@@ -2229,15 +2229,20 @@ unit cgcpu;
 
 
             regs:=regs+[getsupreg(GetDefaultTmpReg)];
             regs:=regs+[getsupreg(GetDefaultTmpReg)];
 
 
-            for reg:=RS_R31 downto RS_R0 do
-              if reg in regs then
-                list.concat(taicpu.op_reg(A_PUSH,newreg(R_INTREGISTER,reg,R_SUBWHOLE)));
+            if current_settings.cputype=cpu_avr1 then
+              message1(cg_w_interrupt_does_not_save_registers,current_procinfo.procdef.fullprocname(false))
+            else
+              begin
+                for reg:=RS_R31 downto RS_R0 do
+                  if reg in regs then
+                    list.concat(taicpu.op_reg(A_PUSH,newreg(R_INTREGISTER,reg,R_SUBWHOLE)));
+                { Save SREG }
+                cg.getcpuregister(list,GetDefaultTmpReg);
+                list.concat(taicpu.op_reg_const(A_IN, GetDefaultTmpReg, $3F));
+                list.concat(taicpu.op_reg(A_PUSH, GetDefaultTmpReg));
+                cg.ungetcpuregister(list,GetDefaultTmpReg);
+              end;
 
 
-            { Save SREG }
-            cg.getcpuregister(list,GetDefaultTmpReg);
-            list.concat(taicpu.op_reg_const(A_IN, GetDefaultTmpReg, $3F));
-            list.concat(taicpu.op_reg(A_PUSH, GetDefaultTmpReg));
-            cg.ungetcpuregister(list,GetDefaultTmpReg);
 
 
             list.concat(taicpu.op_reg(A_CLR,GetDefaultZeroReg));
             list.concat(taicpu.op_reg(A_CLR,GetDefaultZeroReg));
 
 
@@ -2315,17 +2320,21 @@ unit cgcpu;
                 { we clear r1 }
                 { we clear r1 }
                 include(regs,getsupreg(GetDefaultZeroReg));
                 include(regs,getsupreg(GetDefaultZeroReg));
 
 
-                { Reload SREG }
-                regs:=regs+[getsupreg(GetDefaultTmpReg)];
+                if current_settings.cputype<>cpu_avr1 then
+                  begin
+                    { Reload SREG }
+                    regs:=regs+[getsupreg(GetDefaultTmpReg)];
 
 
-                cg.getcpuregister(list,GetDefaultTmpReg);
-                list.concat(taicpu.op_reg(A_POP, GetDefaultTmpReg));
-                list.concat(taicpu.op_const_reg(A_OUT, $3F, GetDefaultTmpReg));
-                cg.ungetcpuregister(list,GetDefaultTmpReg);
 
 
-                for reg:=RS_R0 to RS_R31 do
-                  if reg in regs then
-                    list.concat(taicpu.op_reg(A_POP,newreg(R_INTREGISTER,reg,R_SUBWHOLE)));
+                    cg.getcpuregister(list,GetDefaultTmpReg);
+                    list.concat(taicpu.op_reg(A_POP, GetDefaultTmpReg));
+                    list.concat(taicpu.op_const_reg(A_OUT, $3F, GetDefaultTmpReg));
+                    cg.ungetcpuregister(list,GetDefaultTmpReg);
+
+                    for reg:=RS_R0 to RS_R31 do
+                      if reg in regs then
+                        list.concat(taicpu.op_reg(A_POP,newreg(R_INTREGISTER,reg,R_SUBWHOLE)));
+                  end;
               end;
               end;
             list.concat(taicpu.op_none(A_RETI));
             list.concat(taicpu.op_none(A_RETI));
           end
           end

+ 5 - 1
compiler/msg/errore.msg

@@ -2377,7 +2377,7 @@ sym_e_type_must_be_rec_or_object=05098_E_Record or object type expected
 #
 #
 # Codegenerator
 # Codegenerator
 #
 #
-# 06060 is the last used one
+# 06062 is the last used one
 #
 #
 % \section{Code generator messages}
 % \section{Code generator messages}
 % This section lists all messages that can be displayed if the code
 % This section lists all messages that can be displayed if the code
@@ -2541,6 +2541,10 @@ cg_w_cannot_compile_subroutine=06061_W_The current subroutine "$1" cannot be com
 % Some processors have a very limited instruction set so some routines cannot be compiled for them. As it is not always
 % Some processors have a very limited instruction set so some routines cannot be compiled for them. As it is not always
 % clear from the beginning if a subroutine can be compiled for a certain CPU or not, the compiler checks afterwards
 % clear from the beginning if a subroutine can be compiled for a certain CPU or not, the compiler checks afterwards
 % and creates a dummy if it cannot compile the subroutine.
 % and creates a dummy if it cannot compile the subroutine.
+cg_w_interrupt_does_not_save_registers=06062_W_The target CPU does not support preserving the registers in subroutine "$1"
+% Certain processors have no memory (e.~g. avr1 family), so they do not support storing/restoring the used registers
+% in an interrupt routine. The programmer has to ensure that while there is a chance for the interrupt routine being
+% called that no other code depending on registers being preserved is executed.
 %
 %
 % \end{description}
 % \end{description}
 # EndOfTeX
 # EndOfTeX

+ 3 - 2
compiler/msgidx.inc

@@ -705,6 +705,7 @@ const
   cg_e_case_missing_value=06059;
   cg_e_case_missing_value=06059;
   cg_w_case_incomplete=06060;
   cg_w_case_incomplete=06060;
   cg_w_cannot_compile_subroutine=06061;
   cg_w_cannot_compile_subroutine=06061;
+  cg_w_interrupt_does_not_save_registers=06062;
   asmr_d_start_reading=07000;
   asmr_d_start_reading=07000;
   asmr_d_finish_reading=07001;
   asmr_d_finish_reading=07001;
   asmr_e_none_label_contain_at=07002;
   asmr_e_none_label_contain_at=07002;
@@ -1120,9 +1121,9 @@ const
   option_info=11024;
   option_info=11024;
   option_help_pages=11025;
   option_help_pages=11025;
 
 
-  MsgTxtSize = 84469;
+  MsgTxtSize = 84553;
 
 
   MsgIdxMax : array[1..20] of longint=(
   MsgIdxMax : array[1..20] of longint=(
-    28,106,354,127,99,62,143,35,223,68,
+    28,106,354,127,99,63,143,35,223,68,
     62,20,30,1,1,1,1,1,1,1
     62,20,30,1,1,1,1,1,1,1
   );
   );

File diff suppressed because it is too large
+ 373 - 367
compiler/msgtxt.inc


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