mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-19 21:19:31 +02:00
+ patch by Jeppe Johansen to support automatic interrupt table generation by using the interrupt directive with an offset. Not activated yet because it requires to change also the startup code of the different mcus.
git-svn-id: trunk@17279 -
This commit is contained in:
parent
91c824abbc
commit
3ce9ff93f1
@ -99,7 +99,9 @@ Const
|
||||
pocall_softfloat,
|
||||
{ same as stdcall (requires that all const records are passed by
|
||||
reference, but that's already done for stdcall) }
|
||||
pocall_mwpascal
|
||||
pocall_mwpascal,
|
||||
{ used for interrupt handling }
|
||||
pocall_interrupt
|
||||
];
|
||||
|
||||
cputypestr : array[tcputype] of string[8] = ('',
|
||||
@ -147,6 +149,19 @@ Const
|
||||
'STELLARIS'
|
||||
);
|
||||
|
||||
interruptvectors : array[tcontrollertype] of longint =
|
||||
(0,
|
||||
8,
|
||||
8,
|
||||
8,
|
||||
8,
|
||||
8,
|
||||
8,
|
||||
8,
|
||||
12+59, { XL-density }
|
||||
12 { No model specified }
|
||||
);
|
||||
|
||||
vfp_scalar = [fpu_vfpv2,fpu_vfpv3];
|
||||
|
||||
{ Supported optimizations, only used for information }
|
||||
|
@ -1007,7 +1007,8 @@ implementation
|
||||
'SAFECALL',
|
||||
'STDCALL',
|
||||
'SOFTFLOAT',
|
||||
'MWPASCAL'
|
||||
'MWPASCAL',
|
||||
'INTERRUPT'
|
||||
);
|
||||
var
|
||||
t : tproccalloption;
|
||||
|
@ -360,7 +360,9 @@ interface
|
||||
pocall_softfloat,
|
||||
{ Metrowerks Pascal. Special case on Mac OS (X): passes all }
|
||||
{ constant records by reference. }
|
||||
pocall_mwpascal
|
||||
pocall_mwpascal,
|
||||
{ Special interrupt handler for embedded systems }
|
||||
pocall_interrupt
|
||||
);
|
||||
tproccalloptions = set of tproccalloption;
|
||||
|
||||
@ -377,7 +379,8 @@ interface
|
||||
'SafeCall',
|
||||
'StdCall',
|
||||
'SoftFloat',
|
||||
'MWPascal'
|
||||
'MWPascal',
|
||||
'Interrupt'
|
||||
);
|
||||
|
||||
{ Default calling convention }
|
||||
|
@ -636,7 +636,8 @@ implementation
|
||||
{ pocall_safecall } 4,
|
||||
{ pocall_stdcall } 3,
|
||||
{ pocall_softfloat } 10,
|
||||
{ pocall_mwpascal } 11
|
||||
{ pocall_mwpascal } 11,
|
||||
{ pocall_interrupt } 12
|
||||
);
|
||||
|
||||
procedure write_para(parasym:tparavarsym);
|
||||
|
@ -1611,9 +1611,22 @@ begin
|
||||
end;
|
||||
|
||||
procedure pd_interrupt(pd:tabstractprocdef);
|
||||
|
||||
var v: Tconstexprint;
|
||||
|
||||
begin
|
||||
if pd.parast.symtablelevel>normal_function_level then
|
||||
Message(parser_e_dont_nest_interrupt);
|
||||
|
||||
if target_info.system in systems_interrupt_table then
|
||||
begin
|
||||
if token<>_SEMICOLON then
|
||||
begin
|
||||
pd.proccalloption:=pocall_interrupt;
|
||||
v:=get_intconst;
|
||||
Tprocdef(pd).interruptvector:=v.uvalue;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure pd_abstract(pd:tabstractprocdef);
|
||||
|
@ -49,10 +49,10 @@ implementation
|
||||
wpobase,
|
||||
scanner,pbase,pexpr,psystem,psub,pdecsub,ptype
|
||||
,cpuinfo
|
||||
{$ifdef i386}
|
||||
{$if defined(i386) or defined(ARM)}
|
||||
{ fix me! }
|
||||
,cpubase
|
||||
{$endif i386}
|
||||
{$endif defined(i386) or defined(ARM)}
|
||||
;
|
||||
|
||||
|
||||
@ -472,6 +472,89 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
procedure InsertInterruptTable;
|
||||
|
||||
procedure WriteVector(const name: string);
|
||||
var
|
||||
ai: taicpu;
|
||||
begin
|
||||
{$IFDEF arm}
|
||||
if current_settings.cputype in [cpu_armv7m, cpu_cortexm3] then
|
||||
current_asmdata.asmlists[al_globals].concat(tai_const.Createname(name,0))
|
||||
else
|
||||
begin
|
||||
ai:=taicpu.op_sym(A_B,current_asmdata.RefAsmSymbol(name));
|
||||
ai.is_jmp:=true;
|
||||
current_asmdata.asmlists[al_globals].concat(ai);
|
||||
end;
|
||||
{$ENDIF arm}
|
||||
end;
|
||||
|
||||
function GetInterruptTableLength: longint;
|
||||
begin
|
||||
{$if defined(ARM)}
|
||||
result:=interruptvectors[current_settings.controllertype];
|
||||
{$else}
|
||||
result:=0;
|
||||
{$endif}
|
||||
end;
|
||||
|
||||
var
|
||||
hp: tused_unit;
|
||||
sym: tsym;
|
||||
i, i2: longint;
|
||||
interruptTable: array of tprocdef;
|
||||
pd: tprocdef;
|
||||
begin
|
||||
SetLength(interruptTable, GetInterruptTableLength);
|
||||
FillChar(interruptTable[0], length(interruptTable)*sizeof(pointer), 0);
|
||||
|
||||
hp:=tused_unit(usedunits.first);
|
||||
while assigned(hp) do
|
||||
begin
|
||||
for i := 0 to hp.u.symlist.Count-1 do
|
||||
begin
|
||||
sym:=tsym(hp.u.symlist[i]);
|
||||
if not assigned(sym) then
|
||||
continue;
|
||||
if sym.typ = procsym then
|
||||
begin
|
||||
for i2 := 0 to tprocsym(sym).ProcdefList.Count-1 do
|
||||
begin
|
||||
pd:=tprocdef(tprocsym(sym).ProcdefList[i2]);
|
||||
if pd.interruptvector >= 0 then
|
||||
begin
|
||||
if pd.interruptvector > high(interruptTable) then
|
||||
Internalerror(2011030602);
|
||||
if interruptTable[pd.interruptvector] <> nil then
|
||||
internalerror(2011030601);
|
||||
|
||||
interruptTable[pd.interruptvector]:=pd;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
hp:=tused_unit(hp.next);
|
||||
end;
|
||||
|
||||
new_section(current_asmdata.asmlists[al_globals],sec_init,'VECTORS',sizeof(pint));
|
||||
current_asmdata.asmlists[al_globals].concat(Tai_symbol.Createname_global('VECTORS',AT_DATA,0));
|
||||
{$IFDEF arm}
|
||||
if current_settings.cputype in [cpu_armv7m, cpu_cortexm3] then
|
||||
current_asmdata.asmlists[al_globals].concat(tai_const.Createname('_stack_top',0)); { ARMv7-M processors have the initial stack value at address 0 }
|
||||
{$ENDIF arm}
|
||||
|
||||
for i:=0 to high(interruptTable) do
|
||||
begin
|
||||
if interruptTable[i]<>nil then
|
||||
writeVector(interruptTable[i].mangledname)
|
||||
else
|
||||
writeVector('DefaultHandler'); { Default handler name }
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure InsertMemorySizes;
|
||||
{$IFDEF POWERPC}
|
||||
var
|
||||
@ -2363,6 +2446,9 @@ implementation
|
||||
InsertWideInitsTablesTable;
|
||||
InsertMemorySizes;
|
||||
|
||||
if target_info.system in systems_interrupt_table then
|
||||
InsertInterruptTable;
|
||||
|
||||
{ Insert symbol to resource info }
|
||||
InsertResourceInfo(resources_used);
|
||||
|
||||
|
@ -551,6 +551,8 @@ interface
|
||||
interfacedef : boolean;
|
||||
{ true if the procedure has a forward declaration }
|
||||
hasforward : boolean;
|
||||
{ interrupt vector }
|
||||
interruptvector : longint;
|
||||
constructor create(level:byte);
|
||||
constructor ppuload(ppufile:tcompilerppufile);
|
||||
destructor destroy;override;
|
||||
@ -3331,6 +3333,7 @@ implementation
|
||||
{$ifdef i386}
|
||||
fpu_used:=maxfpuregs;
|
||||
{$endif i386}
|
||||
interruptvector:=-1;
|
||||
end;
|
||||
|
||||
|
||||
@ -3369,6 +3372,8 @@ implementation
|
||||
else
|
||||
import_name:=nil;
|
||||
import_nr:=ppufile.getword;
|
||||
if target_info.system in systems_interrupt_table then
|
||||
interruptvector:=ppufile.getlongint;
|
||||
if (po_msgint in procoptions) then
|
||||
messageinf.i:=ppufile.getlongint;
|
||||
if (po_msgstr in procoptions) then
|
||||
@ -3505,6 +3510,8 @@ implementation
|
||||
if po_has_importname in procoptions then
|
||||
ppufile.putstring(import_name^);
|
||||
ppufile.putword(import_nr);
|
||||
if target_info.system in systems_interrupt_table then
|
||||
ppufile.putlongint(interruptvector);
|
||||
if (po_msgint in procoptions) then
|
||||
ppufile.putlongint(messageinf.i);
|
||||
if (po_msgstr in procoptions) then
|
||||
|
@ -449,6 +449,8 @@ interface
|
||||
|
||||
systems_internal_sysinit = [system_i386_linux,system_i386_win32];
|
||||
|
||||
systems_interrupt_table = [{system_arm_embedded}];
|
||||
|
||||
{ all symbian systems }
|
||||
systems_symbian = [system_i386_symbian,system_arm_symbian];
|
||||
|
||||
|
@ -267,7 +267,7 @@ begin
|
||||
Add('{');
|
||||
Add(' .text :');
|
||||
Add(' {');
|
||||
Add(' *(.init, .init.*)');
|
||||
Add(' KEEP(*(.init, .init.*))');
|
||||
Add(' *(.text, .text.*)');
|
||||
Add(' *(.strings)');
|
||||
Add(' *(.rodata, .rodata.*)');
|
||||
|
Loading…
Reference in New Issue
Block a user