cgobj.pas 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740
  1. {
  2. $Id$
  3. Copyright (c) 1993-98 by Florian Klaempfl
  4. This unit implements the basic code generator object
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit cgobj;
  19. interface
  20. uses
  21. cobjects,aasm,symtable,symconst,cpuasm,cpubase;
  22. type
  23. qword = comp;
  24. pcg = ^tcg;
  25. tcg = object
  26. constructor init;
  27. destructor done;virtual;
  28. procedure a_call_name_ext(list : paasmoutput;const s : string;
  29. offset : longint);
  30. {************************************************}
  31. { code generation for subroutine entry/exit code }
  32. { helper routines }
  33. procedure g_initialize_data(list : paasmoutput;p : psym);
  34. procedure g_incr_data(list : paasmoutput;p : psym);
  35. procedure g_finalize_data(list : paasmoutput;p : pnamedindexobject);
  36. procedure g_copyvalueparas(list : paasmoutput;p : pnamedindexobject);
  37. procedure g_entrycode(list : paasmoutput;
  38. const proc_names : tstringcontainer;make_global : boolean;
  39. stackframe : longint;var parasize : longint;
  40. var nostackframe : boolean;inlined : boolean);
  41. procedure g_exitcode(list : paasmoutput;parasize : longint;
  42. nostackframe,inlined : boolean);
  43. { string helper routines }
  44. procedure g_decransiref(const ref : treference);
  45. procedure g_removetemps(list : paasmoutput;p : plinkedlist);
  46. {**********************************}
  47. { these methods must be overriden: }
  48. procedure a_push_reg(list : paasmoutput;r : tregister);virtual;
  49. procedure a_call_name(list : paasmoutput;const s : string;
  50. offset : longint);virtual;
  51. procedure a_load_const8_ref(list : paasmoutput;b : byte;const ref : treference);virtual;
  52. procedure a_load_const16_ref(list : paasmoutput;w : word;const ref : treference);virtual;
  53. procedure a_load_const32_ref(list : paasmoutput;l : longint;const ref : treference);virtual;
  54. procedure a_load_const64_ref(list : paasmoutput;q : qword;const ref : treference);virtual;
  55. procedure a_loadaddress_ref_reg(list : paasmoutput;ref : treference;r : tregister);virtual;
  56. procedure g_stackframe_entry(list : paasmoutput;localsize : longint);virtual;
  57. procedure g_maybe_loadself(list : paasmoutput);virtual;
  58. {********************************************************}
  59. { these methods can be overriden for extra functionality }
  60. { the following methods do nothing: }
  61. procedure g_interrupt_stackframe_entry(list : paasmoutput);virtual;
  62. procedure g_interrupt_stackframe_exit(list : paasmoutput);virtual;
  63. procedure g_profilecode(list : paasmoutput);virtual;
  64. procedure g_stackcheck(list : paasmoutput;stackframesize : longint);virtual;
  65. { passing parameters, per default the parameter is pushed }
  66. { nr gives the number of the parameter (enumerated from }
  67. { left to right), this allows to move the parameter to }
  68. { register, if the cpu supports register calling }
  69. { conventions }
  70. procedure a_param_reg(list : paasmoutput;r : tregister;nr : longint);virtual;
  71. procedure a_param_const8(list : paasmoutput;b : byte;nr : longint);virtual;
  72. procedure a_param_const16(list : paasmoutput;w : word;nr : longint);virtual;
  73. procedure a_param_const32(list : paasmoutput;l : longint;nr : longint);virtual;
  74. procedure a_param_const64(list : paasmoutput;q : qword;nr : longint);virtual;
  75. procedure a_param_ref(list : paasmoutput;r : treference;nr : longint);virtual;
  76. end;
  77. var
  78. cg : pcg; { this is the main code generator class }
  79. implementation
  80. uses
  81. globals,globtype,options,files,gdb,systems,
  82. ppu,cgbase,verbose,types,tgobj,tgcpu
  83. ;
  84. constructor tcg.init;
  85. begin
  86. end;
  87. destructor tcg.done;
  88. begin
  89. end;
  90. {*****************************************************************************
  91. per default, this methods nothing, can overriden
  92. *****************************************************************************}
  93. procedure tcg.g_interrupt_stackframe_entry(list : paasmoutput);
  94. begin
  95. end;
  96. procedure tcg.g_interrupt_stackframe_exit(list : paasmoutput);
  97. begin
  98. end;
  99. procedure tcg.g_profilecode(list : paasmoutput);
  100. begin
  101. end;
  102. procedure tcg.a_param_reg(list : paasmoutput;r : tregister;nr : longint);
  103. begin
  104. a_push_reg(list,r);
  105. end;
  106. procedure tcg.a_param_const8(list : paasmoutput;b : byte;nr : longint);
  107. begin
  108. {!!!!!!!! a_push_const8(list,b); }
  109. end;
  110. procedure tcg.a_param_const16(list : paasmoutput;w : word;nr : longint);
  111. begin
  112. {!!!!!!!! a_push_const16(list,w); }
  113. end;
  114. procedure tcg.a_param_const32(list : paasmoutput;l : longint;nr : longint);
  115. begin
  116. {!!!!!!!! a_push_const32(list,l); }
  117. end;
  118. procedure tcg.a_param_const64(list : paasmoutput;q : qword;nr : longint);
  119. begin
  120. {!!!!!!!! a_push_const64(list,q); }
  121. end;
  122. procedure tcg.a_param_ref(list : paasmoutput;r : treference;nr : longint);
  123. begin
  124. a_loadaddress_ref_reg(list,r,scratchregister);
  125. a_param_reg(list,scratchregister,nr);
  126. end;
  127. procedure tcg.g_stackcheck(list : paasmoutput;stackframesize : longint);
  128. begin
  129. a_param_const32(list,stackframesize,1);
  130. a_call_name_ext(list,'FPC_STACKCHECK',0);
  131. end;
  132. procedure tcg.a_call_name_ext(list : paasmoutput;const s : string;
  133. offset : longint);
  134. begin
  135. a_call_name(list,s,offset);
  136. { concat_external(s,m); }
  137. end;
  138. {*****************************************************************************
  139. String helper routines
  140. *****************************************************************************}
  141. procedure tcg.g_removetemps(list : paasmoutput;p : plinkedlist);
  142. var
  143. hp : ptemptodestroy;
  144. pushedregs : tpushed;
  145. begin
  146. hp:=ptemptodestroy(p^.first);
  147. if not(assigned(hp)) then
  148. exit;
  149. tg.pushusedregisters(pushedregs,$ff);
  150. while assigned(hp) do
  151. begin
  152. if is_ansistring(hp^.typ) then
  153. begin
  154. g_decransiref(hp^.address);
  155. tg.ungetiftemp(hp^.address);
  156. end;
  157. hp:=ptemptodestroy(hp^.next);
  158. end;
  159. tg.popusedregisters(pushedregs);
  160. end;
  161. procedure tcg.g_decransiref(const ref : treference);
  162. begin
  163. {!!!!!!!!!}
  164. { emitpushreferenceaddr(exprasmlist,ref);
  165. emitcall('FPC_ANSISTR_DECR_REF',true); }
  166. end;
  167. {*****************************************************************************
  168. Code generation for subroutine entry- and exit code
  169. *****************************************************************************}
  170. { generates the code for initialisation of local data }
  171. procedure tcg.g_initialize_data(list : paasmoutput;p : psym);
  172. begin
  173. runerror(255);
  174. end;
  175. { generates the code for incrementing the reference count of parameters }
  176. procedure tcg.g_incr_data(list : paasmoutput;p : psym);
  177. var
  178. hr : treference;
  179. begin
  180. if (psym(p)^.typ=varsym) and
  181. not((pvarsym(p)^.definition^.deftype=objectdef) and
  182. pobjectdef(pvarsym(p)^.definition)^.is_class) and
  183. pvarsym(p)^.definition^.needs_inittable and
  184. ((pvarsym(p)^.varspez=vs_value)) then
  185. begin
  186. procinfo.flags:=procinfo.flags or pi_needs_implicit_finally;
  187. reset_reference(hr);
  188. hr.symbol:=pvarsym(p)^.definition^.get_inittable_label;
  189. a_param_ref(list,hr,2);
  190. reset_reference(hr);
  191. hr.base:=procinfo.framepointer;
  192. hr.offset:=pvarsym(p)^.address+procinfo.call_offset;
  193. a_param_ref(list,hr,1);
  194. reset_reference(hr);
  195. a_call_name(list,'FPC_ADDREF',0);
  196. end;
  197. end;
  198. { generates the code for finalisation of local data }
  199. procedure tcg.g_finalize_data(list : paasmoutput;p : pnamedindexobject);
  200. begin
  201. runerror(255);
  202. end;
  203. { generates the code to make local copies of the value parameters }
  204. procedure tcg.g_copyvalueparas(list : paasmoutput;p : pnamedindexobject);
  205. begin
  206. runerror(255);
  207. end;
  208. var
  209. _list : paasmoutput;
  210. { wrappers for the methods, because TP doesn't know procedures }
  211. { of objects }
  212. procedure _copyvalueparas(s : pnamedindexobject);{$ifndef FPC}far;{$endif}
  213. begin
  214. cg^.g_copyvalueparas(_list,s);
  215. end;
  216. procedure _finalize_data(s : pnamedindexobject);{$ifndef FPC}far;{$endif}
  217. begin
  218. cg^.g_finalize_data(_list,s);
  219. end;
  220. procedure _incr_data(s : pnamedindexobject);{$ifndef FPC}far;{$endif}
  221. begin
  222. cg^.g_incr_data(_list,psym(s));
  223. end;
  224. procedure _initialize_data(s : pnamedindexobject);{$ifndef FPC}far;{$endif}
  225. begin
  226. cg^.g_initialize_data(_list,psym(s));
  227. end;
  228. { generates the entry code for a procedure }
  229. procedure tcg.g_entrycode(list : paasmoutput;const proc_names:Tstringcontainer;make_global:boolean;
  230. stackframe:longint;var parasize:longint;var nostackframe:boolean;
  231. inlined : boolean);
  232. var
  233. hs : string;
  234. hp : pused_unit;
  235. initcode : taasmoutput;
  236. {$ifdef GDB}
  237. stab_function_name : Pai_stab_function_name;
  238. {$endif GDB}
  239. hr : treference;
  240. r : tregister;
  241. begin
  242. { Align }
  243. if (not inlined) then
  244. begin
  245. { gprof uses 16 byte granularity !! }
  246. if (cs_profile in aktmoduleswitches) then
  247. list^.insert(new(pai_align,init(16)))
  248. else
  249. if not(cs_littlesize in aktglobalswitches) then
  250. list^.insert(new(pai_align,init(4)));
  251. end;
  252. { save registers on cdecl }
  253. if (po_savestdregs in aktprocsym^.definition^.procoptions) then
  254. begin
  255. for r:=firstreg to lastreg do
  256. begin
  257. if (r in registers_saved_on_cdecl) then
  258. if (r in (tg.availabletempregsint+
  259. tg.availabletempregsfpu+
  260. tg.availabletempregsmm)) then
  261. begin
  262. if not(r in tg.usedinproc) then
  263. a_push_reg(list,r)
  264. end
  265. else
  266. a_push_reg(list,r);
  267. end;
  268. end;
  269. { omit stack frame ? }
  270. if not inlined then
  271. if procinfo.framepointer=stack_pointer then
  272. begin
  273. CGMessage(cg_d_stackframe_omited);
  274. nostackframe:=true;
  275. if (aktprocsym^.definition^.proctypeoption in [potype_unitinit,potype_proginit,potype_unitfinalize]) then
  276. parasize:=0
  277. else
  278. parasize:=aktprocsym^.definition^.parast^.datasize+procinfo.call_offset-pointersize;
  279. end
  280. else
  281. begin
  282. if (aktprocsym^.definition^.proctypeoption in [potype_unitinit,potype_proginit,potype_unitfinalize]) then
  283. parasize:=0
  284. else
  285. parasize:=aktprocsym^.definition^.parast^.datasize+procinfo.call_offset-pointersize*2;
  286. nostackframe:=false;
  287. if (po_interrupt in aktprocsym^.definition^.procoptions) then
  288. g_interrupt_stackframe_entry(list);
  289. g_stackframe_entry(list,stackframe);
  290. if (cs_check_stack in aktlocalswitches) and
  291. (tf_supports_stack_checking in target_info.flags) then
  292. g_stackcheck(@initcode,stackframe);
  293. end;
  294. if cs_profile in aktmoduleswitches then
  295. g_profilecode(@initcode);
  296. if (not inlined) and (aktprocsym^.definition^.proctypeoption in [potype_unitinit]) then
  297. begin
  298. { needs the target a console flags ? }
  299. if tf_needs_isconsole in target_info.flags then
  300. begin
  301. hr.symbol:=newasmsymbol('U_'+target_info.system_unit+'_ISCONSOLE');
  302. if apptype=at_cui then
  303. a_load_const8_ref(list,1,hr)
  304. else
  305. a_load_const8_ref(list,0,hr);
  306. dispose(hr.symbol,done);
  307. end;
  308. hp:=pused_unit(usedunits.first);
  309. while assigned(hp) do
  310. begin
  311. { call the unit init code and make it external }
  312. if (hp^.u^.flags and uf_init)<>0 then
  313. a_call_name_ext(list,
  314. 'INIT$$'+hp^.u^.modulename^,0);
  315. hp:=Pused_unit(hp^.next);
  316. end;
  317. end;
  318. {$ifdef dummy}
  319. { a constructor needs a help procedure }
  320. if (aktprocsym^.definition^.options and poconstructor)<>0 then
  321. begin
  322. if procinfo._class^.isclass then
  323. begin
  324. list^.concat(new(pai386,op_sym(A_CALL,S_NO,newasmsymbol('FPC_NEW_CLASS'))));
  325. list^.concat(new(pai386,op_cond_sym(A_Jcc,C_Z,S_NO,quickexitlabel)));
  326. end
  327. else
  328. begin
  329. {
  330. list^.insert(new(pai_labeled,init(A_JZ,quickexitlabel)));
  331. list^.insert(new(pai386,op_csymbol(A_CALL,S_NO,
  332. newcsymbol('FPC_HELP_CONSTRUCTOR',0))));
  333. list^.insert(new(pai386,op_const_reg(A_MOV,S_L,procinfo._class^.vmt_offset,R_EDI)));
  334. concat_external('FPC_HELP_CONSTRUCTOR',EXT_NEAR);
  335. }
  336. end;
  337. end;
  338. {$endif dummy}
  339. {$ifdef GDB}
  340. if (cs_debuginfo in aktmoduleswitches) then
  341. list^.insert(new(pai_force_line,init));
  342. {$endif GDB}
  343. { initialize return value }
  344. if is_ansistring(procinfo.retdef) or
  345. is_widestring(procinfo.retdef) then
  346. begin
  347. reset_reference(hr);
  348. hr.offset:=procinfo.retoffset;
  349. hr.base:=procinfo.framepointer;
  350. a_load_const32_ref(list,0,hr);
  351. end;
  352. _list:=list;
  353. { generate copies of call by value parameters }
  354. if (po_assembler in aktprocsym^.definition^.procoptions) then
  355. aktprocsym^.definition^.parast^.foreach({$ifdef FPC}@{$endif FPC}_copyvalueparas);
  356. { initialisizes local data }
  357. aktprocsym^.definition^.localst^.foreach({$ifdef FPC}@{$endif FPC}_initialize_data);
  358. { add a reference to all call by value/const parameters }
  359. aktprocsym^.definition^.parast^.foreach({$ifdef FPC}@{$endif FPC}_incr_data);
  360. if (cs_profile in aktmoduleswitches) or
  361. (aktprocsym^.definition^.owner^.symtabletype=globalsymtable) or
  362. (assigned(procinfo._class) and (procinfo._class^.owner^.symtabletype=globalsymtable)) then
  363. make_global:=true;
  364. if not inlined then
  365. begin
  366. hs:=proc_names.get;
  367. {$ifdef GDB}
  368. if (cs_debuginfo in aktmoduleswitches) and target_os.use_function_relative_addresses then
  369. stab_function_name := new(pai_stab_function_name,init(strpnew(hs)));
  370. {$endif GDB}
  371. { insert the names for the procedure }
  372. while hs<>'' do
  373. begin
  374. if make_global then
  375. exprasmlist^.insert(new(pai_symbol,initname_global(hs,0)))
  376. else
  377. exprasmlist^.insert(new(pai_symbol,initname(hs,0)));
  378. {$ifdef GDB}
  379. if (cs_debuginfo in aktmoduleswitches) then
  380. begin
  381. if target_os.use_function_relative_addresses then
  382. list^.insert(new(pai_stab_function_name,init(strpnew(hs))));
  383. end;
  384. {$endif GDB}
  385. hs:=proc_names.get;
  386. end;
  387. end;
  388. {$ifdef GDB}
  389. if (not inlined) and (cs_debuginfo in aktmoduleswitches) then
  390. begin
  391. if target_os.use_function_relative_addresses then
  392. list^.insert(stab_function_name);
  393. if make_global or ((procinfo.flags and pi_is_global) <> 0) then
  394. aktprocsym^.is_global := True;
  395. list^.insert(new(pai_stabs,init(aktprocsym^.stabstring)));
  396. aktprocsym^.isstabwritten:=true;
  397. end;
  398. {$endif GDB}
  399. end;
  400. procedure tcg.g_exitcode(list : paasmoutput;parasize:longint;nostackframe,inlined:boolean);
  401. {$ifdef GDB}
  402. var
  403. mangled_length : longint;
  404. p : pchar;
  405. {$endif GDB}
  406. begin
  407. {$ifdef dummy}
  408. { !!!! insert there automatic destructors }
  409. if aktexitlabel^.is_used then
  410. list^.insert(new(pai_label,init(aktexitlabel)));
  411. { call the destructor help procedure }
  412. if (aktprocsym^.definition^.options and podestructor)<>0 then
  413. begin
  414. if procinfo._class^.isclass then
  415. begin
  416. list^.insert(new(pai386,op_csymbol(A_CALL,S_NO,
  417. newcsymbol('FPC_DISPOSE_CLASS',0))));
  418. concat_external('FPC_DISPOSE_CLASS',EXT_NEAR);
  419. end
  420. else
  421. begin
  422. list^.insert(new(pai386,op_csymbol(A_CALL,S_NO,
  423. newcsymbol('FPC_HELP_DESTRUCTOR',0))));
  424. list^.insert(new(pai386,op_const_reg(A_MOV,S_L,procinfo._class^.vmt_offset,R_EDI)));
  425. concat_external('FPC_HELP_DESTRUCTOR',EXT_NEAR);
  426. end;
  427. end;
  428. _list:=list;
  429. { finalize local data }
  430. aktprocsym^.definition^.localst^.foreach({$ifdef FPC}@{$endif FPC}finalize_data);
  431. { finalize paras data }
  432. if assigned(aktprocsym^.definition^.parast) then
  433. aktprocsym^.definition^.parast^.foreach({$ifdef FPC}@{$endif FPC}finalize_data);
  434. { call __EXIT for main program }
  435. if (not DLLsource) and (not inlined) and ((aktprocsym^.definition^.options and poproginit)<>0) then
  436. begin
  437. list^.concat(new(pai386,op_csymbol(A_CALL,S_NO,newcsymbol('FPC_DO_EXIT',0))));
  438. concat_external('FPC_DO_EXIT',EXT_NEAR);
  439. end;
  440. { handle return value }
  441. if (aktprocsym^.definition^.options and poassembler)=0 then
  442. if (aktprocsym^.definition^.options and poconstructor)=0 then
  443. handle_return_value(list,inlined)
  444. else
  445. begin
  446. { successful constructor deletes the zero flag }
  447. { and returns self in eax }
  448. list^.concat(new(pai_label,init(quickexitlabel)));
  449. { eax must be set to zero if the allocation failed !!! }
  450. list^.concat(new(pai386,op_reg_reg(A_MOV,S_L,R_ESI,R_EAX)));
  451. list^.concat(new(pai386,op_reg_reg(A_OR,S_L,R_EAX,R_EAX)));
  452. end;
  453. { stabs uses the label also ! }
  454. if aktexit2label^.is_used or
  455. ((cs_debuginfo in aktmoduleswitches) and not inlined) then
  456. list^.concat(new(pai_label,init(aktexit2label)));
  457. { gives problems for long mangled names }
  458. {list^.concat(new(pai_symbol,init(aktprocsym^.definition^.mangledname+'_end')));}
  459. { should we restore edi ? }
  460. { for all i386 gcc implementations }
  461. if ((aktprocsym^.definition^.options and pocdecl)<>0) then
  462. begin
  463. list^.insert(new(pai386,op_reg(A_POP,S_L,R_EDI)));
  464. list^.insert(new(pai386,op_reg(A_POP,S_L,R_ESI)));
  465. if (aktprocsym^.definition^.usedregisters and ($80 shr byte(R_EBX)))<>0 then
  466. list^.insert(new(pai386,op_reg(A_POP,S_L,R_EBX)));
  467. { here we could reset R_EBX
  468. but that is risky because it only works
  469. if genexitcode is called after genentrycode
  470. so lets skip this for the moment PM
  471. aktprocsym^.definition^.usedregisters:=
  472. aktprocsym^.definition^.usedregisters or not ($80 shr byte(R_EBX));
  473. }
  474. end;
  475. if not(nostackframe) and not inlined then
  476. list^.concat(new(pai386,op_none(A_LEAVE,S_NO)));
  477. { parameters are limited to 65535 bytes because }
  478. { ret allows only imm16 }
  479. if (parasize>65535) and not(aktprocsym^.definition^.options and poclearstack<>0) then
  480. CGMessage(cg_e_parasize_too_big);
  481. { at last, the return is generated }
  482. if not inlined then
  483. if (aktprocsym^.definition^.options and pointerrupt)<>0 then
  484. generate_interrupt_stackframe_exit
  485. else
  486. begin
  487. {Routines with the poclearstack flag set use only a ret.}
  488. { also routines with parasize=0 }
  489. if (parasize=0) or (aktprocsym^.definition^.options and poclearstack<>0) then
  490. list^.concat(new(pai386,op_none(A_RET,S_NO)))
  491. else
  492. list^.concat(new(pai386,op_const(A_RET,S_NO,parasize)));
  493. end;
  494. {$ifdef GDB}
  495. if (cs_debuginfo in aktmoduleswitches) and not inlined then
  496. begin
  497. aktprocsym^.concatstabto(list);
  498. if assigned(procinfo._class) then
  499. list^.concat(new(pai_stabs,init(strpnew(
  500. '"$t:v'+procinfo._class^.numberstring+'",'+
  501. tostr(N_PSYM)+',0,0,'+tostr(procinfo.esi_offset)))));
  502. if (porddef(aktprocsym^.definition^.retdef) <> voiddef) then
  503. if ret_in_param(aktprocsym^.definition^.retdef) then
  504. list^.concat(new(pai_stabs,init(strpnew(
  505. '"'+aktprocsym^.name+':X*'+aktprocsym^.definition^.retdef^.numberstring+'",'+
  506. tostr(N_PSYM)+',0,0,'+tostr(procinfo.retoffset)))))
  507. else
  508. list^.concat(new(pai_stabs,init(strpnew(
  509. '"'+aktprocsym^.name+':X'+aktprocsym^.definition^.retdef^.numberstring+'",'+
  510. tostr(N_PSYM)+',0,0,'+tostr(procinfo.retoffset)))));
  511. mangled_length:=length(aktprocsym^.definition^.mangledname);
  512. getmem(p,mangled_length+50);
  513. strpcopy(p,'192,0,0,');
  514. strpcopy(strend(p),aktprocsym^.definition^.mangledname);
  515. list^.concat(new(pai_stabn,init(strnew(p))));
  516. {list^.concat(new(pai_stabn,init(strpnew('192,0,0,'
  517. +aktprocsym^.definition^.mangledname))));
  518. p[0]:='2';p[1]:='2';p[2]:='4';
  519. strpcopy(strend(p),'_end');}
  520. freemem(p,mangled_length+50);
  521. list^.concat(new(pai_stabn,init(
  522. strpnew('224,0,0,'+lab2str(aktexit2label)))));
  523. { strpnew('224,0,0,'
  524. +aktprocsym^.definition^.mangledname+'_end'))));}
  525. end;
  526. {$endif GDB}
  527. curlist:=nil;
  528. {$endif dummy}
  529. end;
  530. {*****************************************************************************
  531. some abstract definitions
  532. ****************************************************************************}
  533. procedure tcg.a_push_reg(list : paasmoutput;r : tregister);
  534. begin
  535. abstract;
  536. end;
  537. procedure tcg.a_call_name(list : paasmoutput;const s : string;
  538. offset : longint);
  539. begin
  540. abstract;
  541. end;
  542. procedure tcg.a_load_const8_ref(list : paasmoutput;b : byte;const ref : treference);
  543. begin
  544. abstract;
  545. end;
  546. procedure tcg.a_load_const16_ref(list : paasmoutput;w : word;const ref : treference);
  547. begin
  548. abstract;
  549. end;
  550. procedure tcg.a_load_const32_ref(list : paasmoutput;l : longint;const ref : treference);
  551. begin
  552. abstract;
  553. end;
  554. procedure tcg.a_load_const64_ref(list : paasmoutput;q : qword;const ref : treference);
  555. begin
  556. abstract;
  557. end;
  558. procedure tcg.g_stackframe_entry(list : paasmoutput;localsize : longint);
  559. begin
  560. abstract;
  561. end;
  562. procedure tcg.g_maybe_loadself(list : paasmoutput);
  563. begin
  564. abstract;
  565. end;
  566. procedure tcg.a_loadaddress_ref_reg(list : paasmoutput;ref : treference;r : tregister);
  567. begin
  568. abstract;
  569. end;
  570. end.
  571. {
  572. $Log$
  573. Revision 1.11 1999-08-05 14:58:11 florian
  574. * some fixes for the floating point registers
  575. * more things for the new code generator
  576. Revision 1.10 1999/08/04 00:23:52 florian
  577. * renamed i386asm and i386base to cpuasm and cpubase
  578. Revision 1.9 1999/08/02 23:13:21 florian
  579. * more changes to compile for the Alpha
  580. Revision 1.8 1999/08/02 17:14:07 florian
  581. + changed the temp. generator to an object
  582. Revision 1.7 1999/08/01 23:05:55 florian
  583. * changes to compile with FPC
  584. Revision 1.6 1999/08/01 18:22:33 florian
  585. * made it again compilable
  586. Revision 1.5 1999/01/23 23:29:46 florian
  587. * first running version of the new code generator
  588. * when compiling exceptions under Linux fixed
  589. Revision 1.4 1999/01/13 22:52:36 florian
  590. + YES, finally the new code generator is compilable, but it doesn't run yet :(
  591. Revision 1.3 1998/12/26 15:20:30 florian
  592. + more changes for the new version
  593. Revision 1.2 1998/12/15 22:18:55 florian
  594. * some code added
  595. Revision 1.1 1998/12/15 16:32:58 florian
  596. + first version, derived from old routines
  597. }