mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-16 20:19:33 +02:00
- 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:
parent
1bb2173939
commit
12879adc2f
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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 : [];
|
||||||
|
149
rtl/avr/avr.inc
149
rtl/avr/avr.inc
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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.
|
||||||
|
Loading…
Reference in New Issue
Block a user