+ 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,
{ 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 }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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