- Adds intrinsics to save/restore SREG when disabling interrupts.

- Adds nostackframe to stack frame investigation stubs.

git-svn-id: trunk@41898 -
This commit is contained in:
Jeppe Johansen 2019-04-18 18:26:51 +00:00
parent 1bb2173939
commit 12879adc2f
6 changed files with 89 additions and 109 deletions

View File

@ -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

View File

@ -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;

View File

@ -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 : [];

View File

@ -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;

View File

@ -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;

View File

@ -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.