+ 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:
florian 2011-04-10 15:59:06 +00:00
parent 91c824abbc
commit 3ce9ff93f1
9 changed files with 136 additions and 8 deletions

View File

@ -99,7 +99,9 @@ Const
pocall_softfloat, pocall_softfloat,
{ same as stdcall (requires that all const records are passed by { same as stdcall (requires that all const records are passed by
reference, but that's already done for stdcall) } reference, but that's already done for stdcall) }
pocall_mwpascal pocall_mwpascal,
{ used for interrupt handling }
pocall_interrupt
]; ];
cputypestr : array[tcputype] of string[8] = ('', cputypestr : array[tcputype] of string[8] = ('',
@ -147,6 +149,19 @@ Const
'STELLARIS' '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]; vfp_scalar = [fpu_vfpv2,fpu_vfpv3];
{ Supported optimizations, only used for information } { Supported optimizations, only used for information }

View File

@ -1007,7 +1007,8 @@ implementation
'SAFECALL', 'SAFECALL',
'STDCALL', 'STDCALL',
'SOFTFLOAT', 'SOFTFLOAT',
'MWPASCAL' 'MWPASCAL',
'INTERRUPT'
); );
var var
t : tproccalloption; t : tproccalloption;

View File

@ -360,7 +360,9 @@ interface
pocall_softfloat, pocall_softfloat,
{ Metrowerks Pascal. Special case on Mac OS (X): passes all } { Metrowerks Pascal. Special case on Mac OS (X): passes all }
{ constant records by reference. } { constant records by reference. }
pocall_mwpascal pocall_mwpascal,
{ Special interrupt handler for embedded systems }
pocall_interrupt
); );
tproccalloptions = set of tproccalloption; tproccalloptions = set of tproccalloption;
@ -377,7 +379,8 @@ interface
'SafeCall', 'SafeCall',
'StdCall', 'StdCall',
'SoftFloat', 'SoftFloat',
'MWPascal' 'MWPascal',
'Interrupt'
); );
{ Default calling convention } { Default calling convention }

View File

@ -636,7 +636,8 @@ implementation
{ pocall_safecall } 4, { pocall_safecall } 4,
{ pocall_stdcall } 3, { pocall_stdcall } 3,
{ pocall_softfloat } 10, { pocall_softfloat } 10,
{ pocall_mwpascal } 11 { pocall_mwpascal } 11,
{ pocall_interrupt } 12
); );
procedure write_para(parasym:tparavarsym); procedure write_para(parasym:tparavarsym);

View File

@ -1611,9 +1611,22 @@ begin
end; end;
procedure pd_interrupt(pd:tabstractprocdef); procedure pd_interrupt(pd:tabstractprocdef);
var v: Tconstexprint;
begin begin
if pd.parast.symtablelevel>normal_function_level then if pd.parast.symtablelevel>normal_function_level then
Message(parser_e_dont_nest_interrupt); 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; end;
procedure pd_abstract(pd:tabstractprocdef); procedure pd_abstract(pd:tabstractprocdef);

View File

@ -49,10 +49,10 @@ implementation
wpobase, wpobase,
scanner,pbase,pexpr,psystem,psub,pdecsub,ptype scanner,pbase,pexpr,psystem,psub,pdecsub,ptype
,cpuinfo ,cpuinfo
{$ifdef i386} {$if defined(i386) or defined(ARM)}
{ fix me! } { fix me! }
,cpubase ,cpubase
{$endif i386} {$endif defined(i386) or defined(ARM)}
; ;
@ -472,6 +472,89 @@ implementation
end; 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; procedure InsertMemorySizes;
{$IFDEF POWERPC} {$IFDEF POWERPC}
var var
@ -2363,6 +2446,9 @@ implementation
InsertWideInitsTablesTable; InsertWideInitsTablesTable;
InsertMemorySizes; InsertMemorySizes;
if target_info.system in systems_interrupt_table then
InsertInterruptTable;
{ Insert symbol to resource info } { Insert symbol to resource info }
InsertResourceInfo(resources_used); InsertResourceInfo(resources_used);

View File

@ -551,6 +551,8 @@ interface
interfacedef : boolean; interfacedef : boolean;
{ true if the procedure has a forward declaration } { true if the procedure has a forward declaration }
hasforward : boolean; hasforward : boolean;
{ interrupt vector }
interruptvector : longint;
constructor create(level:byte); constructor create(level:byte);
constructor ppuload(ppufile:tcompilerppufile); constructor ppuload(ppufile:tcompilerppufile);
destructor destroy;override; destructor destroy;override;
@ -3331,6 +3333,7 @@ implementation
{$ifdef i386} {$ifdef i386}
fpu_used:=maxfpuregs; fpu_used:=maxfpuregs;
{$endif i386} {$endif i386}
interruptvector:=-1;
end; end;
@ -3369,6 +3372,8 @@ implementation
else else
import_name:=nil; import_name:=nil;
import_nr:=ppufile.getword; import_nr:=ppufile.getword;
if target_info.system in systems_interrupt_table then
interruptvector:=ppufile.getlongint;
if (po_msgint in procoptions) then if (po_msgint in procoptions) then
messageinf.i:=ppufile.getlongint; messageinf.i:=ppufile.getlongint;
if (po_msgstr in procoptions) then if (po_msgstr in procoptions) then
@ -3505,6 +3510,8 @@ implementation
if po_has_importname in procoptions then if po_has_importname in procoptions then
ppufile.putstring(import_name^); ppufile.putstring(import_name^);
ppufile.putword(import_nr); ppufile.putword(import_nr);
if target_info.system in systems_interrupt_table then
ppufile.putlongint(interruptvector);
if (po_msgint in procoptions) then if (po_msgint in procoptions) then
ppufile.putlongint(messageinf.i); ppufile.putlongint(messageinf.i);
if (po_msgstr in procoptions) then if (po_msgstr in procoptions) then

View File

@ -449,6 +449,8 @@ interface
systems_internal_sysinit = [system_i386_linux,system_i386_win32]; systems_internal_sysinit = [system_i386_linux,system_i386_win32];
systems_interrupt_table = [{system_arm_embedded}];
{ all symbian systems } { all symbian systems }
systems_symbian = [system_i386_symbian,system_arm_symbian]; systems_symbian = [system_i386_symbian,system_arm_symbian];

View File

@ -267,7 +267,7 @@ begin
Add('{'); Add('{');
Add(' .text :'); Add(' .text :');
Add(' {'); Add(' {');
Add(' *(.init, .init.*)'); Add(' KEEP(*(.init, .init.*))');
Add(' *(.text, .text.*)'); Add(' *(.text, .text.*)');
Add(' *(.strings)'); Add(' *(.strings)');
Add(' *(.rodata, .rodata.*)'); Add(' *(.rodata, .rodata.*)');