summaryrefslogtreecommitdiff
path: root/compiler/ncgutil.pas
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/ncgutil.pas')
-rw-r--r--compiler/ncgutil.pas144
1 files changed, 140 insertions, 4 deletions
diff --git a/compiler/ncgutil.pas b/compiler/ncgutil.pas
index 7d0ab56073..4751ee691b 100644
--- a/compiler/ncgutil.pas
+++ b/compiler/ncgutil.pas
@@ -161,6 +161,10 @@ interface
procedure gen_pic_helpers(list : TAsmList);
+ procedure gen_fpc_dummy(list : TAsmList);
+
+ procedure InsertInterruptTable;
+
implementation
uses
@@ -1568,6 +1572,8 @@ implementation
procedure init_paras(p:TObject;arg:pointer);
var
href : treference;
+ hsym : tparavarsym;
+ eldef : tdef;
tmpreg : tregister;
list : TAsmList;
needs_inittable,
@@ -1591,7 +1597,18 @@ implementation
paramanager.push_addr_param(tparavarsym(p).varspez,tparavarsym(p).vardef,current_procinfo.procdef.proccalloption)) then
begin
location_get_data_ref(list,tparavarsym(p).initialloc,href,is_open_array(tparavarsym(p).vardef),sizeof(pint));
- cg.g_incrrefcount(list,tparavarsym(p).vardef,href);
+ if is_open_array(tparavarsym(p).vardef) then
+ begin
+ { open arrays do not contain correct element count in their rtti,
+ the actual count must be passed separately. }
+ hsym:=tparavarsym(tsym(p).owner.Find('high'+tsym(p).name));
+ eldef:=tarraydef(tparavarsym(p).vardef).elementdef;
+ if not assigned(hsym) then
+ internalerror(201003031);
+ cg.g_array_rtti_helper(list,eldef,href,hsym.initialloc,'FPC_ADDREF_ARRAY');
+ end
+ else
+ cg.g_incrrefcount(list,tparavarsym(p).vardef,href);
end;
end;
vs_out :
@@ -1616,7 +1633,18 @@ implementation
else
trash_reference(list,href,2);
if needs_inittable then
- cg.g_initialize(list,tparavarsym(p).vardef,href);
+ begin
+ if is_open_array(tparavarsym(p).vardef) then
+ begin
+ hsym:=tparavarsym(tsym(p).owner.Find('high'+tsym(p).name));
+ eldef:=tarraydef(tparavarsym(p).vardef).elementdef;
+ if not assigned(hsym) then
+ internalerror(201103033);
+ cg.g_array_rtti_helper(list,eldef,href,hsym.initialloc,'FPC_INITIALIZE_ARRAY');
+ end
+ else
+ cg.g_initialize(list,tparavarsym(p).vardef,href);
+ end;
end;
end;
else if do_trashing and
@@ -1649,6 +1677,8 @@ implementation
var
list : TAsmList;
href : treference;
+ hsym : tparavarsym;
+ eldef : tdef;
begin
if not(tsym(p).typ=paravarsym) then
exit;
@@ -1659,7 +1689,16 @@ implementation
begin
include(current_procinfo.flags,pi_needs_implicit_finally);
location_get_data_ref(list,tparavarsym(p).localloc,href,is_open_array(tparavarsym(p).vardef),sizeof(pint));
- cg.g_decrrefcount(list,tparavarsym(p).vardef,href);
+ if is_open_array(tparavarsym(p).vardef) then
+ begin
+ hsym:=tparavarsym(tsym(p).owner.Find('high'+tsym(p).name));
+ eldef:=tarraydef(tparavarsym(p).vardef).elementdef;
+ if not assigned(hsym) then
+ internalerror(201003032);
+ cg.g_array_rtti_helper(list,eldef,href,hsym.initialloc,'FPC_DECREF_ARRAY');
+ end
+ else
+ cg.g_decrrefcount(list,tparavarsym(p).vardef,href);
end;
end;
{ open arrays can contain elements requiring init/final code, so the else has been removed here }
@@ -2496,7 +2535,10 @@ implementation
sectype:=sec_bss;
end;
maybe_new_object_file(list);
- new_section(list,sectype,lower(sym.mangledname),varalign);
+ if sym.section<>'' then
+ new_section(list,sec_user,sym.section,varalign)
+ else
+ new_section(list,sectype,lower(sym.mangledname),varalign);
if (sym.owner.symtabletype=globalsymtable) or
create_smartlink or
DLLSource or
@@ -3092,4 +3134,98 @@ implementation
{$endif i386}
end;
+
+ procedure gen_fpc_dummy(list : TAsmList);
+ begin
+{$ifdef i386}
+ { fix me! }
+ list.concat(Taicpu.Op_const_reg(A_MOV,S_L,1,NR_EAX));
+ list.concat(Taicpu.Op_const(A_RET,S_W,12));
+{$endif i386}
+ 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;
+
+
end.