diff options
Diffstat (limited to 'compiler/ncgutil.pas')
-rw-r--r-- | compiler/ncgutil.pas | 144 |
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. |