- 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_sei = fpc_in_cpu_first+1,
in_avr_wdr = fpc_in_cpu_first+2, in_avr_wdr = fpc_in_cpu_first+2,
in_avr_sleep = fpc_in_cpu_first+3, 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, aasmdata,
aasmcpu, aasmcpu,
symdef, symdef,
cgbase, hlcgobj,
pass_2,
cgbase, cgobj, cgutils,
cpubase; cpubase;
function tavrinlinenode.pass_typecheck_cpu : tnode; function tavrinlinenode.pass_typecheck_cpu : tnode;
@ -58,6 +60,16 @@ unit navrinl;
CheckParameters(0); CheckParameters(0);
resultdef:=voidtype; resultdef:=voidtype;
end; end;
in_avr_save:
begin
CheckParameters(0);
resultdef:=u8inttype;
end;
in_avr_restore:
begin
CheckParameters(1);
resultdef:=voidtype;
end;
else else
Result:=inherited pass_typecheck_cpu; Result:=inherited pass_typecheck_cpu;
end; end;
@ -72,11 +84,17 @@ unit navrinl;
in_avr_sleep, in_avr_sleep,
in_avr_sei, in_avr_sei,
in_avr_wdr, in_avr_wdr,
in_avr_cli: in_avr_cli,
in_avr_restore:
begin begin
expectloc:=LOC_VOID; expectloc:=LOC_VOID;
resultdef:=voidtype; resultdef:=voidtype;
end; end;
in_avr_save:
begin
expectloc:=LOC_REGISTER;
resultdef:=u8inttype;
end;
else else
Result:=inherited first_cpu; Result:=inherited first_cpu;
end; end;
@ -96,6 +114,20 @@ unit navrinl;
current_asmdata.CurrAsmList.concat(taicpu.op_none(A_WDR)); current_asmdata.CurrAsmList.concat(taicpu.op_none(A_WDR));
in_avr_cli: in_avr_cli:
current_asmdata.CurrAsmList.concat(taicpu.op_none(A_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 else
inherited pass_generate_code_cpu; inherited pass_generate_code_cpu;
end; end;

View File

@ -2542,7 +2542,7 @@ const
mutexclpo : [] mutexclpo : []
),( ),(
idtok:_INTERNPROC; 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; handler : @pd_internproc;
pocall : pocall_internproc; pocall : pocall_internproc;
pooption : []; pooption : [];

View File

@ -17,6 +17,15 @@
{$asmmode gas} {$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} procedure fpc_cpuinit;{$ifdef SYSTEMINLINE}inline;{$endif}
begin begin
end; end;
@ -84,19 +93,19 @@ function get_frame:pointer;assembler;nostackframe;
{$define FPC_SYSTEM_HAS_GET_CALLER_ADDR} {$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 asm
end; end;
{$define FPC_SYSTEM_HAS_GET_CALLER_FRAME} {$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 asm
end; end;
{$define FPC_SYSTEM_HAS_SPTR} {$define FPC_SYSTEM_HAS_SPTR}
Function Sptr : pointer;assembler; Function Sptr : pointer;assembler;nostackframe;
asm asm
end; end;
@ -106,20 +115,13 @@ function InterLockedDecrement (var Target: longint) : longint;
temp_sreg : byte; temp_sreg : byte;
begin begin
{ block interrupts } { block interrupts }
asm temp_sreg:=avr_save();
in r0,0x3f
std temp_sreg,r0
cli
end;
dec(Target); Result:=Target-1;
Result:=Target; Target:=Result;
{ release interrupts } { release interrupts }
asm avr_restore(temp_sreg);
ldd r0,temp_sreg
out 0x3f,r0
end;
end; end;
@ -128,20 +130,13 @@ function InterLockedIncrement (var Target: longint) : longint;
temp_sreg : byte; temp_sreg : byte;
begin begin
{ block interrupts } { block interrupts }
asm temp_sreg:=avr_save();
in r0,0x3f
std temp_sreg,r0
cli
end;
inc(Target); Result:=Target+1;
Result:=Target; Target:=Result;
{ release interrupts } { release interrupts }
asm avr_restore(temp_sreg);
ldd r0,temp_sreg
out 0x3f,r0
end;
end; end;
@ -150,20 +145,13 @@ function InterLockedExchange (var Target: longint;Source : longint) : longint;
temp_sreg : byte; temp_sreg : byte;
begin begin
{ block interrupts } { block interrupts }
asm temp_sreg:=avr_save();
in r0,0x3f
std temp_sreg,r0
cli
end;
Result:=Target; Result:=Target;
Target:=Source; Target:=Source;
{ release interrupts } { release interrupts }
asm avr_restore(temp_sreg);
ldd r0,temp_sreg
out 0x3f,r0
end;
end; end;
@ -172,21 +160,14 @@ function InterlockedCompareExchange(var Target: longint; NewValue: longint; Comp
temp_sreg : byte; temp_sreg : byte;
begin begin
{ block interrupts } { block interrupts }
asm temp_sreg:=avr_save();
in r0,0x3f
std temp_sreg,r0
cli
end;
Result:=Target; Result:=Target;
if Target=Comperand then if Result=Comperand then
Target:=NewValue; Target:=NewValue;
{ release interrupts } { release interrupts }
asm avr_restore(temp_sreg);
ldd r0,temp_sreg
out 0x3f,r0
end;
end; end;
@ -195,20 +176,13 @@ function InterLockedExchangeAdd (var Target: longint;Source : longint) : longint
temp_sreg : byte; temp_sreg : byte;
begin begin
{ block interrupts } { block interrupts }
asm temp_sreg:=avr_save();
in r0,0x3f
std temp_sreg,r0
cli
end;
Result:=Target; Result:=Target;
inc(Target,Source); Target:=Result+Source;
{ release interrupts } { release interrupts }
asm avr_restore(temp_sreg);
ldd r0,temp_sreg
out 0x3f,r0
end;
end; end;
@ -217,20 +191,13 @@ function InterLockedDecrement (var Target: smallint) : smallint;
temp_sreg : byte; temp_sreg : byte;
begin begin
{ block interrupts } { block interrupts }
asm temp_sreg:=avr_save();
in r0,0x3f
std temp_sreg,r0
cli
end;
dec(Target); Result:=Target-1;
Result:=Target; Target:=Result;
{ release interrupts } { release interrupts }
asm avr_restore(temp_sreg);
ldd r0,temp_sreg
out 0x3f,r0
end;
end; end;
@ -239,20 +206,13 @@ function InterLockedIncrement (var Target: smallint) : smallint;
temp_sreg : byte; temp_sreg : byte;
begin begin
{ block interrupts } { block interrupts }
asm temp_sreg:=avr_save();
in r0,0x3f
std temp_sreg,r0
cli
end;
inc(Target); Result:=Target+1;
Result:=Target; Target:=Result;
{ release interrupts } { release interrupts }
asm avr_restore(temp_sreg);
ldd r0,temp_sreg
out 0x3f,r0
end;
end; end;
@ -261,20 +221,13 @@ function InterLockedExchange (var Target: smallint;Source : smallint) : smallint
temp_sreg : byte; temp_sreg : byte;
begin begin
{ block interrupts } { block interrupts }
asm temp_sreg:=avr_save();
in r0,0x3f
std temp_sreg,r0
cli
end;
Result:=Target; Result:=Target;
Target:=Source; Target:=Source;
{ release interrupts } { release interrupts }
asm avr_restore(temp_sreg);
ldd r0,temp_sreg
out 0x3f,r0
end;
end; end;
@ -283,21 +236,14 @@ function InterlockedCompareExchange(var Target: smallint; NewValue: smallint; Co
temp_sreg : byte; temp_sreg : byte;
begin begin
{ block interrupts } { block interrupts }
asm temp_sreg:=avr_save();
in r0,0x3f
std temp_sreg,r0
cli
end;
Result:=Target; Result:=Target;
if Target=Comperand then if Result=Comperand then
Target:=NewValue; Target:=NewValue;
{ release interrupts } { release interrupts }
asm avr_restore(temp_sreg);
ldd r0,temp_sreg
out 0x3f,r0
end;
end; end;
@ -306,19 +252,12 @@ function InterLockedExchangeAdd (var Target: smallint;Source : smallint) : small
temp_sreg : byte; temp_sreg : byte;
begin begin
{ block interrupts } { block interrupts }
asm temp_sreg:=avr_save();
in r0,0x3f
std temp_sreg,r0
cli
end;
Result:=Target; Result:=Target;
inc(Target,Source); Target:=Result+Source;
{ release interrupts } { release interrupts }
asm avr_restore(temp_sreg);
ldd r0,temp_sreg
out 0x3f,r0
end;
end; end;

View File

@ -17,3 +17,5 @@
in_avr_wdr = fpc_in_cpu_first+2; in_avr_wdr = fpc_in_cpu_first+2;
in_avr_sleep = fpc_in_cpu_first+3; 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

@ -24,6 +24,11 @@ unit intrinsics;
procedure avr_sleep;[INTERNPROC: in_avr_sleep]; procedure avr_sleep;[INTERNPROC: in_avr_sleep];
procedure avr_nop;[INTERNPROC: in_avr_nop]; 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 implementation
end. end.