Bladeren bron

- Adds intrinsics to save/restore SREG when disabling interrupts.
- Adds nostackframe to stack frame investigation stubs.

git-svn-id: trunk@41898 -

Jeppe Johansen 6 jaren geleden
bovenliggende
commit
12879adc2f
6 gewijzigde bestanden met toevoegingen van 89 en 109 verwijderingen
  1. 3 1
      compiler/avr/ccpuinnr.inc
  2. 34 2
      compiler/avr/navrinl.pas
  3. 1 1
      compiler/pdecsub.pas
  4. 44 105
      rtl/avr/avr.inc
  5. 2 0
      rtl/avr/cpuinnr.inc
  6. 5 0
      rtl/avr/intrinsics.pp

+ 3 - 1
compiler/avr/ccpuinnr.inc

@@ -16,4 +16,6 @@
   in_avr_sei = fpc_in_cpu_first+1,
   in_avr_wdr = fpc_in_cpu_first+2,
   in_avr_sleep = fpc_in_cpu_first+3,
-  in_avr_nop = fpc_in_cpu_first+4
+  in_avr_nop = fpc_in_cpu_first+4,
+  in_avr_save = fpc_in_cpu_first+5,
+  in_avr_restore = fpc_in_cpu_first+6

+ 34 - 2
compiler/avr/navrinl.pas

@@ -42,7 +42,9 @@ unit navrinl;
       aasmdata,
       aasmcpu,
       symdef,
-      cgbase,
+      hlcgobj,
+      pass_2,
+      cgbase, cgobj, cgutils,
       cpubase;
 
     function tavrinlinenode.pass_typecheck_cpu : tnode;
@@ -58,6 +60,16 @@ unit navrinl;
               CheckParameters(0);
               resultdef:=voidtype;
             end;
+          in_avr_save:
+            begin
+              CheckParameters(0);
+              resultdef:=u8inttype;
+            end;
+          in_avr_restore:
+            begin
+              CheckParameters(1);
+              resultdef:=voidtype;
+            end;
           else
             Result:=inherited pass_typecheck_cpu;
         end;
@@ -72,11 +84,17 @@ unit navrinl;
           in_avr_sleep,
           in_avr_sei,
           in_avr_wdr,
-          in_avr_cli:
+          in_avr_cli,
+          in_avr_restore:
             begin
               expectloc:=LOC_VOID;
               resultdef:=voidtype;
             end;
+          in_avr_save:
+            begin
+              expectloc:=LOC_REGISTER;
+              resultdef:=u8inttype;
+            end;
           else
             Result:=inherited first_cpu;
         end;
@@ -96,6 +114,20 @@ unit navrinl;
             current_asmdata.CurrAsmList.concat(taicpu.op_none(A_WDR));
           in_avr_cli:
             current_asmdata.CurrAsmList.concat(taicpu.op_none(A_CLI));
+          in_avr_save:
+            begin
+              location_reset(location,LOC_CREGISTER,OS_8);
+              location.register:=cg.getintregister(current_asmdata.CurrAsmList,OS_8);
+
+              current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_IN, location.register, NIO_SREG));
+              current_asmdata.CurrAsmList.concat(taicpu.op_none(A_CLI));
+            end;
+          in_avr_restore:
+            begin
+              secondpass(left);
+              hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false);
+              current_asmdata.CurrAsmList.concat(taicpu.op_const_reg(A_OUT, NIO_SREG, left.location.register));
+            end;
           else
             inherited pass_generate_code_cpu;
         end;

+ 1 - 1
compiler/pdecsub.pas

@@ -2542,7 +2542,7 @@ const
       mutexclpo     : []
     ),(
       idtok:_INTERNPROC;
-      pd_flags : [pd_interface,pd_notobject,pd_notobjintf,pd_notrecord,pd_nothelper];
+      pd_flags : [pd_interface,pd_implemen,pd_notobject,pd_notobjintf,pd_notrecord,pd_nothelper];
       handler  : @pd_internproc;
       pocall   : pocall_internproc;
       pooption : [];

+ 44 - 105
rtl/avr/avr.inc

@@ -17,6 +17,15 @@
 
 {$asmmode gas}
 
+const
+{$i cpuinnr.inc}
+
+{ Reads SREG and then disables interrupts, returns contents of SREG }
+function avr_save: byte;[INTERNPROC: in_avr_save];
+{ Restores SREG }
+procedure avr_restore(old_sreg: byte); [INTERNPROC: in_avr_restore];
+
+
 procedure fpc_cpuinit;{$ifdef SYSTEMINLINE}inline;{$endif}
   begin
   end;
@@ -84,19 +93,19 @@ function get_frame:pointer;assembler;nostackframe;
 
 
 {$define FPC_SYSTEM_HAS_GET_CALLER_ADDR}
-function get_caller_addr(framebp:pointer;addr:pointer=nil):pointer;assembler;
+function get_caller_addr(framebp:pointer;addr:pointer=nil):pointer;assembler;nostackframe;
   asm
   end;
 
 
 {$define FPC_SYSTEM_HAS_GET_CALLER_FRAME}
-function get_caller_frame(framebp:pointer;addr:pointer=nil):pointer;assembler;
+function get_caller_frame(framebp:pointer;addr:pointer=nil):pointer;assembler;nostackframe;
   asm
   end;
 
 
 {$define FPC_SYSTEM_HAS_SPTR}
-Function Sptr : pointer;assembler;
+Function Sptr : pointer;assembler;nostackframe;
   asm
   end;
 
@@ -106,20 +115,13 @@ function InterLockedDecrement (var Target: longint) : longint;
     temp_sreg : byte;
   begin
     { block interrupts }
-    asm
-      in r0,0x3f
-      std temp_sreg,r0
-      cli
-    end;
+    temp_sreg:=avr_save();
 
-    dec(Target);
-    Result:=Target;
+    Result:=Target-1;
+    Target:=Result;
 
     { release interrupts }
-    asm
-      ldd r0,temp_sreg
-      out 0x3f,r0
-    end;
+    avr_restore(temp_sreg);
   end;
 
 
@@ -128,20 +130,13 @@ function InterLockedIncrement (var Target: longint) : longint;
     temp_sreg : byte;
   begin
     { block interrupts }
-    asm
-      in r0,0x3f
-      std temp_sreg,r0
-      cli
-    end;
+    temp_sreg:=avr_save();
 
-    inc(Target);
-    Result:=Target;
+    Result:=Target+1;
+    Target:=Result;
 
     { release interrupts }
-    asm
-      ldd r0,temp_sreg
-      out 0x3f,r0
-    end;
+    avr_restore(temp_sreg);
   end;
 
 
@@ -150,20 +145,13 @@ function InterLockedExchange (var Target: longint;Source : longint) : longint;
     temp_sreg : byte;
   begin
     { block interrupts }
-    asm
-      in r0,0x3f
-      std temp_sreg,r0
-      cli
-    end;
+    temp_sreg:=avr_save();
 
     Result:=Target;
     Target:=Source;
 
     { release interrupts }
-    asm
-      ldd r0,temp_sreg
-      out 0x3f,r0
-    end;
+    avr_restore(temp_sreg);
   end;
 
 
@@ -172,21 +160,14 @@ function InterlockedCompareExchange(var Target: longint; NewValue: longint; Comp
     temp_sreg : byte;
   begin
     { block interrupts }
-    asm
-      in r0,0x3f
-      std temp_sreg,r0
-      cli
-    end;
+    temp_sreg:=avr_save();
 
     Result:=Target;
-    if Target=Comperand then
+    if Result=Comperand then
       Target:=NewValue;
 
     { release interrupts }
-    asm
-      ldd r0,temp_sreg
-      out 0x3f,r0
-    end;
+    avr_restore(temp_sreg);
   end;
 
 
@@ -195,20 +176,13 @@ function InterLockedExchangeAdd (var Target: longint;Source : longint) : longint
     temp_sreg : byte;
   begin
     { block interrupts }
-    asm
-      in r0,0x3f
-      std temp_sreg,r0
-      cli
-    end;
+    temp_sreg:=avr_save();
 
     Result:=Target;
-    inc(Target,Source);
+    Target:=Result+Source;
 
     { release interrupts }
-    asm
-      ldd r0,temp_sreg
-      out 0x3f,r0
-    end;
+    avr_restore(temp_sreg);
   end;
 
 
@@ -217,20 +191,13 @@ function InterLockedDecrement (var Target: smallint) : smallint;
     temp_sreg : byte;
   begin
     { block interrupts }
-    asm
-      in r0,0x3f
-      std temp_sreg,r0
-      cli
-    end;
+    temp_sreg:=avr_save();
 
-    dec(Target);
-    Result:=Target;
+    Result:=Target-1;
+    Target:=Result;
 
     { release interrupts }
-    asm
-      ldd r0,temp_sreg
-      out 0x3f,r0
-    end;
+    avr_restore(temp_sreg);
   end;
 
 
@@ -239,20 +206,13 @@ function InterLockedIncrement (var Target: smallint) : smallint;
     temp_sreg : byte;
   begin
     { block interrupts }
-    asm
-      in r0,0x3f
-      std temp_sreg,r0
-      cli
-    end;
+    temp_sreg:=avr_save();
 
-    inc(Target);
-    Result:=Target;
+    Result:=Target+1;
+    Target:=Result;
 
     { release interrupts }
-    asm
-      ldd r0,temp_sreg
-      out 0x3f,r0
-    end;
+    avr_restore(temp_sreg);
   end;
 
 
@@ -261,20 +221,13 @@ function InterLockedExchange (var Target: smallint;Source : smallint) : smallint
     temp_sreg : byte;
   begin
     { block interrupts }
-    asm
-      in r0,0x3f
-      std temp_sreg,r0
-      cli
-    end;
+    temp_sreg:=avr_save();
 
     Result:=Target;
     Target:=Source;
 
     { release interrupts }
-    asm
-      ldd r0,temp_sreg
-      out 0x3f,r0
-    end;
+    avr_restore(temp_sreg);
   end;
 
 
@@ -283,21 +236,14 @@ function InterlockedCompareExchange(var Target: smallint; NewValue: smallint; Co
     temp_sreg : byte;
   begin
     { block interrupts }
-    asm
-      in r0,0x3f
-      std temp_sreg,r0
-      cli
-    end;
+    temp_sreg:=avr_save();
 
     Result:=Target;
-    if Target=Comperand then
+    if Result=Comperand then
       Target:=NewValue;
 
     { release interrupts }
-    asm
-      ldd r0,temp_sreg
-      out 0x3f,r0
-    end;
+    avr_restore(temp_sreg);
   end;
 
 
@@ -306,19 +252,12 @@ function InterLockedExchangeAdd (var Target: smallint;Source : smallint) : small
     temp_sreg : byte;
   begin
     { block interrupts }
-    asm
-      in r0,0x3f
-      std temp_sreg,r0
-      cli
-    end;
+    temp_sreg:=avr_save();
 
     Result:=Target;
-    inc(Target,Source);
+    Target:=Result+Source;
 
     { release interrupts }
-    asm
-      ldd r0,temp_sreg
-      out 0x3f,r0
-    end;
+    avr_restore(temp_sreg);
   end;
 

+ 2 - 0
rtl/avr/cpuinnr.inc

@@ -17,3 +17,5 @@
   in_avr_wdr = fpc_in_cpu_first+2;
   in_avr_sleep = fpc_in_cpu_first+3;
   in_avr_nop = fpc_in_cpu_first+4;
+  in_avr_save = fpc_in_cpu_first+5;
+  in_avr_restore = fpc_in_cpu_first+6;

+ 5 - 0
rtl/avr/intrinsics.pp

@@ -24,6 +24,11 @@ unit intrinsics;
     procedure avr_sleep;[INTERNPROC: in_avr_sleep];
     procedure avr_nop;[INTERNPROC: in_avr_nop];
 
+    { Reads SREG and then disables interrupts, returns contents of SREG }
+    function avr_save: byte;[INTERNPROC: in_avr_save];
+    { Restores SREG }
+    procedure avr_restore(old_sreg: byte); [INTERNPROC: in_avr_restore];
+
   implementation
 
 end.