ra386int.pas 60 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Carl Eric Codere and Peter Vreman
  4. Does the parsing process for the intel styled inline assembler.
  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 Ra386int;
  19. {$i fpcdefs.inc}
  20. Interface
  21. uses
  22. node;
  23. function assemble: tnode;
  24. Implementation
  25. uses
  26. { common }
  27. cutils,cclasses,
  28. { global }
  29. globtype,globals,verbose,
  30. systems,
  31. { aasm }
  32. cpuinfo,cpubase,aasmbase,aasmtai,aasmcpu,
  33. { symtable }
  34. symconst,symbase,symtype,symsym,symtable,
  35. { pass 1 }
  36. nbas,
  37. { parser }
  38. scanner,
  39. { register allocator }
  40. rautils,rax86,itx86int,
  41. { codegen }
  42. cgbase,cgobj,procinfo
  43. ;
  44. type
  45. tasmtoken = (
  46. AS_NONE,AS_LABEL,AS_LLABEL,AS_STRING,AS_INTNUM,
  47. AS_COMMA,AS_LBRACKET,AS_RBRACKET,AS_LPAREN,
  48. AS_RPAREN,AS_COLON,AS_DOT,AS_PLUS,AS_MINUS,AS_STAR,
  49. AS_SEPARATOR,AS_ID,AS_REGISTER,AS_OPCODE,AS_SLASH,
  50. {------------------ Assembler directives --------------------}
  51. AS_DB,AS_DW,AS_DD,AS_END,
  52. {------------------ Assembler Operators --------------------}
  53. AS_BYTE,AS_WORD,AS_DWORD,AS_QWORD,AS_TBYTE,AS_NEAR,AS_FAR,
  54. AS_HIGH,AS_LOW,AS_OFFSET,AS_SEG,AS_TYPE,AS_PTR,AS_MOD,AS_SHL,AS_SHR,AS_NOT,
  55. AS_AND,AS_OR,AS_XOR);
  56. tasmkeyword = string[6];
  57. const
  58. { These tokens should be modified accordingly to the modifications }
  59. { in the different enumerations. }
  60. firstdirective = AS_DB;
  61. lastdirective = AS_END;
  62. firstoperator = AS_BYTE;
  63. lastoperator = AS_XOR;
  64. _count_asmdirectives = longint(lastdirective)-longint(firstdirective);
  65. _count_asmoperators = longint(lastoperator)-longint(firstoperator);
  66. _asmdirectives : array[0.._count_asmdirectives] of tasmkeyword =
  67. ('DB','DW','DD','END');
  68. { problems with shl,shr,not,and,or and xor, they are }
  69. { context sensitive. }
  70. _asmoperators : array[0.._count_asmoperators] of tasmkeyword = (
  71. 'BYTE','WORD','DWORD','QWORD','TBYTE','NEAR','FAR','HIGH',
  72. 'LOW','OFFSET','SEG','TYPE','PTR','MOD','SHL','SHR','NOT','AND',
  73. 'OR','XOR');
  74. token2str : array[tasmtoken] of string[10] = (
  75. '','Label','LLabel','String','Integer',
  76. ',','[',']','(',
  77. ')',':','.','+','-','*',
  78. ';','identifier','register','opcode','/',
  79. '','','','END',
  80. '','','','','','','','',
  81. '','','','type','ptr','mod','shl','shr','not',
  82. 'and','or','xor'
  83. );
  84. const
  85. newline = #10;
  86. firsttoken : boolean = TRUE;
  87. var
  88. _asmsorted : boolean;
  89. inexpression : boolean;
  90. curlist : TAAsmoutput;
  91. c : char;
  92. prevasmtoken : tasmtoken;
  93. actasmtoken : tasmtoken;
  94. actasmpattern : string;
  95. actasmregister : tregister;
  96. actopcode : tasmop;
  97. actopsize : topsize;
  98. actcondition : tasmcond;
  99. iasmops : tdictionary;
  100. Procedure SetupTables;
  101. { creates uppercased symbol tables for speed access }
  102. var
  103. i : tasmop;
  104. str2opentry: tstr2opentry;
  105. Begin
  106. { opcodes }
  107. iasmops:=tdictionary.create;
  108. iasmops.delete_doubles:=true;
  109. for i:=firstop to lastop do
  110. begin
  111. str2opentry:=tstr2opentry.createname(upper(std_op2str[i]));
  112. str2opentry.op:=i;
  113. iasmops.insert(str2opentry);
  114. end;
  115. end;
  116. {---------------------------------------------------------------------}
  117. { Routines for the tokenizing }
  118. {---------------------------------------------------------------------}
  119. function is_asmopcode(const s: string):boolean;
  120. var
  121. str2opentry: tstr2opentry;
  122. cond : string[4];
  123. cnd : tasmcond;
  124. j: longint;
  125. Begin
  126. is_asmopcode:=FALSE;
  127. actopcode:=A_None;
  128. actcondition:=C_None;
  129. actopsize:=S_NO;
  130. str2opentry:=tstr2opentry(iasmops.search(s));
  131. if assigned(str2opentry) then
  132. begin
  133. actopcode:=str2opentry.op;
  134. actasmtoken:=AS_OPCODE;
  135. is_asmopcode:=TRUE;
  136. exit;
  137. end;
  138. { not found yet, check condition opcodes }
  139. j:=0;
  140. while (j<CondAsmOps) do
  141. begin
  142. if Copy(s,1,Length(CondAsmOpStr[j]))=CondAsmOpStr[j] then
  143. begin
  144. cond:=Copy(s,Length(CondAsmOpStr[j])+1,255);
  145. if cond<>'' then
  146. begin
  147. for cnd:=low(TasmCond) to high(TasmCond) do
  148. if Cond=Upper(cond2str[cnd]) then
  149. begin
  150. actopcode:=CondASmOp[j];
  151. actcondition:=cnd;
  152. is_asmopcode:=TRUE;
  153. actasmtoken:=AS_OPCODE;
  154. exit
  155. end;
  156. end;
  157. end;
  158. inc(j);
  159. end;
  160. end;
  161. function is_asmoperator(const s: string):boolean;
  162. var
  163. i : longint;
  164. Begin
  165. for i:=0 to _count_asmoperators do
  166. if s=_asmoperators[i] then
  167. begin
  168. actasmtoken:=tasmtoken(longint(firstoperator)+i);
  169. is_asmoperator:=true;
  170. exit;
  171. end;
  172. is_asmoperator:=false;
  173. end;
  174. Function is_asmdirective(const s: string):boolean;
  175. var
  176. i : longint;
  177. Begin
  178. for i:=0 to _count_asmdirectives do
  179. if s=_asmdirectives[i] then
  180. begin
  181. actasmtoken:=tasmtoken(longint(firstdirective)+i);
  182. is_asmdirective:=true;
  183. exit;
  184. end;
  185. is_asmdirective:=false;
  186. end;
  187. function is_register(const s:string):boolean;
  188. begin
  189. is_register:=false;
  190. actasmregister:=masm_regnum_search(lower(s));
  191. if actasmregister<>NR_NO then
  192. begin
  193. is_register:=true;
  194. actasmtoken:=AS_REGISTER;
  195. end;
  196. end;
  197. function is_locallabel(const s:string):boolean;
  198. begin
  199. is_locallabel:=(length(s)>1) and (s[1]='@');
  200. end;
  201. Procedure GetToken;
  202. var
  203. len : longint;
  204. forcelabel : boolean;
  205. srsym : tsym;
  206. srsymtable : tsymtable;
  207. begin
  208. { save old token and reset new token }
  209. prevasmtoken:=actasmtoken;
  210. actasmtoken:=AS_NONE;
  211. { reset }
  212. forcelabel:=FALSE;
  213. actasmpattern:='';
  214. { while space and tab , continue scan... }
  215. while (c in [' ',#9]) do
  216. c:=current_scanner.asmgetchar;
  217. { get token pos }
  218. if not (c in [newline,#13,'{',';']) then
  219. current_scanner.gettokenpos;
  220. { Local Label, Label, Directive, Prefix or Opcode }
  221. if firsttoken and not (c in [newline,#13,'{',';']) then
  222. begin
  223. firsttoken:=FALSE;
  224. len:=0;
  225. while c in ['A'..'Z','a'..'z','0'..'9','_','@'] do
  226. begin
  227. { if there is an at_sign, then this must absolutely be a label }
  228. if c = '@' then
  229. forcelabel:=TRUE;
  230. inc(len);
  231. actasmpattern[len]:=c;
  232. c:=current_scanner.asmgetchar;
  233. end;
  234. actasmpattern[0]:=chr(len);
  235. uppervar(actasmpattern);
  236. { label ? }
  237. if c = ':' then
  238. begin
  239. if actasmpattern[1]='@' then
  240. actasmtoken:=AS_LLABEL
  241. else
  242. actasmtoken:=AS_LABEL;
  243. { let us point to the next character }
  244. c:=current_scanner.asmgetchar;
  245. firsttoken:=true;
  246. exit;
  247. end;
  248. { Are we trying to create an identifier with }
  249. { an at-sign...? }
  250. if forcelabel then
  251. Message(asmr_e_none_label_contain_at);
  252. { opcode ? }
  253. If is_asmopcode(actasmpattern) then
  254. Begin
  255. { check if we are in an expression }
  256. { then continue with asm directives }
  257. if not inexpression then
  258. exit;
  259. end;
  260. if is_asmdirective(actasmpattern) then
  261. exit;
  262. message1(asmr_e_unknown_opcode,actasmpattern);
  263. actasmtoken:=AS_NONE;
  264. exit;
  265. end
  266. else { else firsttoken }
  267. begin
  268. case c of
  269. '@' : { possiblities : - local label reference , such as in jmp @local1 }
  270. { - @Result, @Code or @Data special variables. }
  271. begin
  272. actasmpattern:=c;
  273. c:=current_scanner.asmgetchar;
  274. while c in ['A'..'Z','a'..'z','0'..'9','_','@'] do
  275. begin
  276. actasmpattern:=actasmpattern + c;
  277. c:=current_scanner.asmgetchar;
  278. end;
  279. uppervar(actasmpattern);
  280. actasmtoken:=AS_ID;
  281. exit;
  282. end;
  283. 'A'..'Z','a'..'z','_': { identifier, register, opcode, prefix or directive }
  284. begin
  285. actasmpattern:=c;
  286. c:=current_scanner.asmgetchar;
  287. while c in ['A'..'Z','a'..'z','0'..'9','_'] do
  288. begin
  289. actasmpattern:=actasmpattern + c;
  290. c:=current_scanner.asmgetchar;
  291. end;
  292. uppervar(actasmpattern);
  293. { after prefix we allow also a new opcode }
  294. If is_prefix(actopcode) and is_asmopcode(actasmpattern) then
  295. Begin
  296. { if we are not in a constant }
  297. { expression than this is an }
  298. { opcode. }
  299. if not inexpression then
  300. exit;
  301. end;
  302. { support st(X) for fpu registers }
  303. if (actasmpattern = 'ST') and (c='(') then
  304. Begin
  305. actasmpattern:=actasmpattern+c;
  306. c:=current_scanner.asmgetchar;
  307. if c in ['0'..'7'] then
  308. actasmpattern:=actasmpattern + c
  309. else
  310. Message(asmr_e_invalid_fpu_register);
  311. c:=current_scanner.asmgetchar;
  312. if c <> ')' then
  313. Message(asmr_e_invalid_fpu_register)
  314. else
  315. Begin
  316. actasmpattern:=actasmpattern + c;
  317. c:=current_scanner.asmgetchar;
  318. end;
  319. end;
  320. if is_register(actasmpattern) then
  321. exit;
  322. if is_asmdirective(actasmpattern) then
  323. exit;
  324. if is_asmoperator(actasmpattern) then
  325. exit;
  326. { if next is a '.' and this is a unitsym then we also need to
  327. parse the identifier }
  328. if (c='.') then
  329. begin
  330. searchsym(actasmpattern,srsym,srsymtable);
  331. if assigned(srsym) and
  332. (srsym.typ=unitsym) and
  333. (srsym.owner.unitid=0) then
  334. begin
  335. { Add . to create System.Identifier }
  336. actasmpattern:=actasmpattern+c;
  337. c:=current_scanner.asmgetchar;
  338. { Delphi allows System.@Halt, just ignore the @ }
  339. if c='@' then
  340. c:=current_scanner.asmgetchar;
  341. while c in ['A'..'Z','a'..'z','0'..'9','_','$'] do
  342. begin
  343. actasmpattern:=actasmpattern + upcase(c);
  344. c:=current_scanner.asmgetchar;
  345. end;
  346. end;
  347. end;
  348. actasmtoken:=AS_ID;
  349. exit;
  350. end;
  351. '''' : { string or character }
  352. begin
  353. actasmpattern:='';
  354. current_scanner.in_asm_string:=true;
  355. repeat
  356. if c = '''' then
  357. begin
  358. c:=current_scanner.asmgetchar;
  359. if c=newline then
  360. begin
  361. Message(scan_f_string_exceeds_line);
  362. break;
  363. end;
  364. repeat
  365. if c='''' then
  366. begin
  367. c:=current_scanner.asmgetchar;
  368. if c='''' then
  369. begin
  370. actasmpattern:=actasmpattern+'''';
  371. c:=current_scanner.asmgetchar;
  372. if c=newline then
  373. begin
  374. Message(scan_f_string_exceeds_line);
  375. break;
  376. end;
  377. end
  378. else
  379. break;
  380. end
  381. else
  382. begin
  383. actasmpattern:=actasmpattern+c;
  384. c:=current_scanner.asmgetchar;
  385. if c=newline then
  386. begin
  387. Message(scan_f_string_exceeds_line);
  388. break
  389. end;
  390. end;
  391. until false; { end repeat }
  392. end
  393. else
  394. break; { end if }
  395. until false;
  396. current_scanner.in_asm_string:=false;
  397. actasmtoken:=AS_STRING;
  398. exit;
  399. end;
  400. '"' : { string or character }
  401. begin
  402. current_scanner.in_asm_string:=true;
  403. actasmpattern:='';
  404. repeat
  405. if c = '"' then
  406. begin
  407. c:=current_scanner.asmgetchar;
  408. if c=newline then
  409. begin
  410. Message(scan_f_string_exceeds_line);
  411. break;
  412. end;
  413. repeat
  414. if c='"' then
  415. begin
  416. c:=current_scanner.asmgetchar;
  417. if c='"' then
  418. begin
  419. actasmpattern:=actasmpattern+'"';
  420. c:=current_scanner.asmgetchar;
  421. if c=newline then
  422. begin
  423. Message(scan_f_string_exceeds_line);
  424. break;
  425. end;
  426. end
  427. else
  428. break;
  429. end
  430. else
  431. begin
  432. actasmpattern:=actasmpattern+c;
  433. c:=current_scanner.asmgetchar;
  434. if c=newline then
  435. begin
  436. Message(scan_f_string_exceeds_line);
  437. break
  438. end;
  439. end;
  440. until false; { end repeat }
  441. end
  442. else
  443. break; { end if }
  444. until false;
  445. current_scanner.in_asm_string:=false;
  446. actasmtoken:=AS_STRING;
  447. exit;
  448. end;
  449. '$' :
  450. begin
  451. c:=current_scanner.asmgetchar;
  452. while c in ['0'..'9','A'..'F','a'..'f'] do
  453. begin
  454. actasmpattern:=actasmpattern + c;
  455. c:=current_scanner.asmgetchar;
  456. end;
  457. actasmpattern:=tostr(ValHexaDecimal(actasmpattern));
  458. actasmtoken:=AS_INTNUM;
  459. exit;
  460. end;
  461. ',' :
  462. begin
  463. actasmtoken:=AS_COMMA;
  464. c:=current_scanner.asmgetchar;
  465. exit;
  466. end;
  467. '[' :
  468. begin
  469. actasmtoken:=AS_LBRACKET;
  470. c:=current_scanner.asmgetchar;
  471. exit;
  472. end;
  473. ']' :
  474. begin
  475. actasmtoken:=AS_RBRACKET;
  476. c:=current_scanner.asmgetchar;
  477. exit;
  478. end;
  479. '(' :
  480. begin
  481. actasmtoken:=AS_LPAREN;
  482. c:=current_scanner.asmgetchar;
  483. exit;
  484. end;
  485. ')' :
  486. begin
  487. actasmtoken:=AS_RPAREN;
  488. c:=current_scanner.asmgetchar;
  489. exit;
  490. end;
  491. ':' :
  492. begin
  493. actasmtoken:=AS_COLON;
  494. c:=current_scanner.asmgetchar;
  495. exit;
  496. end;
  497. '.' :
  498. begin
  499. actasmtoken:=AS_DOT;
  500. c:=current_scanner.asmgetchar;
  501. exit;
  502. end;
  503. '+' :
  504. begin
  505. actasmtoken:=AS_PLUS;
  506. c:=current_scanner.asmgetchar;
  507. exit;
  508. end;
  509. '-' :
  510. begin
  511. actasmtoken:=AS_MINUS;
  512. c:=current_scanner.asmgetchar;
  513. exit;
  514. end;
  515. '*' :
  516. begin
  517. actasmtoken:=AS_STAR;
  518. c:=current_scanner.asmgetchar;
  519. exit;
  520. end;
  521. '/' :
  522. begin
  523. actasmtoken:=AS_SLASH;
  524. c:=current_scanner.asmgetchar;
  525. exit;
  526. end;
  527. '0'..'9':
  528. begin
  529. actasmpattern:=c;
  530. c:=current_scanner.asmgetchar;
  531. { Get the possible characters }
  532. while c in ['0'..'9','A'..'F','a'..'f'] do
  533. begin
  534. actasmpattern:=actasmpattern + c;
  535. c:=current_scanner.asmgetchar;
  536. end;
  537. { Get ending character }
  538. uppervar(actasmpattern);
  539. c:=upcase(c);
  540. { possibly a binary number. }
  541. if (actasmpattern[length(actasmpattern)] = 'B') and (c <> 'H') then
  542. Begin
  543. { Delete the last binary specifier }
  544. delete(actasmpattern,length(actasmpattern),1);
  545. actasmpattern:=tostr(ValBinary(actasmpattern));
  546. actasmtoken:=AS_INTNUM;
  547. exit;
  548. end
  549. else
  550. Begin
  551. case c of
  552. 'O' :
  553. Begin
  554. actasmpattern:=tostr(ValOctal(actasmpattern));
  555. actasmtoken:=AS_INTNUM;
  556. c:=current_scanner.asmgetchar;
  557. exit;
  558. end;
  559. 'H' :
  560. Begin
  561. actasmpattern:=tostr(ValHexaDecimal(actasmpattern));
  562. actasmtoken:=AS_INTNUM;
  563. c:=current_scanner.asmgetchar;
  564. exit;
  565. end;
  566. else { must be an integer number }
  567. begin
  568. actasmpattern:=tostr(ValDecimal(actasmpattern));
  569. actasmtoken:=AS_INTNUM;
  570. exit;
  571. end;
  572. end;
  573. end;
  574. end;
  575. ';','{',#13,newline :
  576. begin
  577. c:=current_scanner.asmgetchar;
  578. firsttoken:=TRUE;
  579. actasmtoken:=AS_SEPARATOR;
  580. exit;
  581. end;
  582. else
  583. current_scanner.illegal_char(c);
  584. end;
  585. end;
  586. end;
  587. function consume(t : tasmtoken):boolean;
  588. begin
  589. Consume:=true;
  590. if t<>actasmtoken then
  591. begin
  592. Message2(scan_f_syn_expected,token2str[t],token2str[actasmtoken]);
  593. Consume:=false;
  594. end;
  595. repeat
  596. gettoken;
  597. until actasmtoken<>AS_NONE;
  598. end;
  599. procedure RecoverConsume(allowcomma:boolean);
  600. begin
  601. While not (actasmtoken in [AS_SEPARATOR,AS_END]) do
  602. begin
  603. if allowcomma and (actasmtoken=AS_COMMA) then
  604. break;
  605. Consume(actasmtoken);
  606. end;
  607. end;
  608. {*****************************************************************************
  609. Parsing Helpers
  610. *****************************************************************************}
  611. Procedure BuildRecordOffsetSize(const expr: string;var offset:longint;var size:longint);
  612. { Description: This routine builds up a record offset after a AS_DOT }
  613. { token is encountered. }
  614. { On entry actasmtoken should be equal to AS_DOT }
  615. var
  616. s : string;
  617. Begin
  618. offset:=0;
  619. size:=0;
  620. s:=expr;
  621. while (actasmtoken=AS_DOT) do
  622. begin
  623. Consume(AS_DOT);
  624. if actasmtoken=AS_ID then
  625. s:=s+'.'+actasmpattern;
  626. if not Consume(AS_ID) then
  627. begin
  628. RecoverConsume(true);
  629. break;
  630. end;
  631. end;
  632. if not GetRecordOffsetSize(s,offset,size) then
  633. Message(asmr_e_building_record_offset);
  634. end;
  635. Procedure BuildConstSymbolExpression(needofs,isref:boolean;var value:longint;var asmsym:string);
  636. var
  637. tempstr,expr,hs : string;
  638. parenlevel,l,k : longint;
  639. errorflag : boolean;
  640. prevtok : tasmtoken;
  641. hl : tasmlabel;
  642. sym : tsym;
  643. srsymtable : tsymtable;
  644. Begin
  645. { reset }
  646. value:=0;
  647. asmsym:='';
  648. errorflag:=FALSE;
  649. tempstr:='';
  650. expr:='';
  651. inexpression:=TRUE;
  652. parenlevel:=0;
  653. Repeat
  654. Case actasmtoken of
  655. AS_LPAREN:
  656. Begin
  657. Consume(AS_LPAREN);
  658. expr:=expr + '(';
  659. inc(parenlevel);
  660. end;
  661. AS_RPAREN:
  662. Begin
  663. Consume(AS_RPAREN);
  664. expr:=expr + ')';
  665. dec(parenlevel);
  666. end;
  667. AS_SHL:
  668. Begin
  669. Consume(AS_SHL);
  670. expr:=expr + '<';
  671. end;
  672. AS_SHR:
  673. Begin
  674. Consume(AS_SHR);
  675. expr:=expr + '>';
  676. end;
  677. AS_SLASH:
  678. Begin
  679. Consume(AS_SLASH);
  680. expr:=expr + '/';
  681. end;
  682. AS_MOD:
  683. Begin
  684. Consume(AS_MOD);
  685. expr:=expr + '%';
  686. end;
  687. AS_STAR:
  688. Begin
  689. Consume(AS_STAR);
  690. if isref and (actasmtoken=AS_REGISTER) then
  691. break;
  692. expr:=expr + '*';
  693. end;
  694. AS_PLUS:
  695. Begin
  696. Consume(AS_PLUS);
  697. if isref and (actasmtoken=AS_REGISTER) then
  698. break;
  699. expr:=expr + '+';
  700. end;
  701. AS_LBRACKET:
  702. begin
  703. { Support ugly delphi constructs like: [ECX].1+2[EDX] }
  704. if isref then
  705. break;
  706. end;
  707. AS_MINUS:
  708. Begin
  709. Consume(AS_MINUS);
  710. expr:=expr + '-';
  711. end;
  712. AS_AND:
  713. Begin
  714. Consume(AS_AND);
  715. expr:=expr + '&';
  716. end;
  717. AS_NOT:
  718. Begin
  719. Consume(AS_NOT);
  720. expr:=expr + '~';
  721. end;
  722. AS_XOR:
  723. Begin
  724. Consume(AS_XOR);
  725. expr:=expr + '^';
  726. end;
  727. AS_OR:
  728. Begin
  729. Consume(AS_OR);
  730. expr:=expr + '|';
  731. end;
  732. AS_INTNUM:
  733. Begin
  734. expr:=expr + actasmpattern;
  735. Consume(AS_INTNUM);
  736. end;
  737. AS_OFFSET:
  738. begin
  739. Consume(AS_OFFSET);
  740. if actasmtoken<>AS_ID then
  741. Message(asmr_e_offset_without_identifier);
  742. end;
  743. AS_TYPE:
  744. begin
  745. l:=0;
  746. Consume(AS_TYPE);
  747. if actasmtoken<>AS_ID then
  748. Message(asmr_e_type_without_identifier)
  749. else
  750. begin
  751. tempstr:=actasmpattern;
  752. Consume(AS_ID);
  753. if actasmtoken=AS_DOT then
  754. BuildRecordOffsetSize(tempstr,k,l)
  755. else
  756. begin
  757. searchsym(tempstr,sym,srsymtable);
  758. if assigned(sym) then
  759. begin
  760. case sym.typ of
  761. varsym :
  762. l:=tvarsym(sym).getsize;
  763. typedconstsym :
  764. l:=ttypedconstsym(sym).getsize;
  765. typesym :
  766. l:=ttypesym(sym).restype.def.size;
  767. else
  768. Message(asmr_e_wrong_sym_type);
  769. end;
  770. end
  771. else
  772. Message1(sym_e_unknown_id,tempstr);
  773. end;
  774. end;
  775. str(l, tempstr);
  776. expr:=expr + tempstr;
  777. end;
  778. AS_STRING:
  779. Begin
  780. l:=0;
  781. case Length(actasmpattern) of
  782. 1 :
  783. l:=ord(actasmpattern[1]);
  784. 2 :
  785. l:=ord(actasmpattern[2]) + ord(actasmpattern[1]) shl 8;
  786. 3 :
  787. l:=ord(actasmpattern[3]) +
  788. Ord(actasmpattern[2]) shl 8 + ord(actasmpattern[1]) shl 16;
  789. 4 :
  790. l:=ord(actasmpattern[4]) + ord(actasmpattern[3]) shl 8 +
  791. Ord(actasmpattern[2]) shl 16 + ord(actasmpattern[1]) shl 24;
  792. else
  793. Message1(asmr_e_invalid_string_as_opcode_operand,actasmpattern);
  794. end;
  795. str(l, tempstr);
  796. expr:=expr + tempstr;
  797. Consume(AS_STRING);
  798. end;
  799. AS_ID:
  800. Begin
  801. hs:='';
  802. tempstr:=actasmpattern;
  803. prevtok:=prevasmtoken;
  804. consume(AS_ID);
  805. if SearchIConstant(tempstr,l) then
  806. begin
  807. str(l, tempstr);
  808. expr:=expr + tempstr;
  809. end
  810. else
  811. begin
  812. if is_locallabel(tempstr) then
  813. begin
  814. CreateLocalLabel(tempstr,hl,false);
  815. hs:=hl.name
  816. end
  817. else
  818. if SearchLabel(tempstr,hl,false) then
  819. hs:=hl.name
  820. else
  821. begin
  822. searchsym(tempstr,sym,srsymtable);
  823. if assigned(sym) then
  824. begin
  825. case sym.typ of
  826. varsym :
  827. begin
  828. if sym.owner.symtabletype in [localsymtable,parasymtable] then
  829. Message(asmr_e_no_local_or_para_allowed);
  830. hs:=tvarsym(sym).mangledname;
  831. end;
  832. typedconstsym :
  833. hs:=ttypedconstsym(sym).mangledname;
  834. procsym :
  835. begin
  836. if Tprocsym(sym).procdef_count>1 then
  837. Message(asmr_w_calling_overload_func);
  838. hs:=tprocsym(sym).first_procdef.mangledname;
  839. end;
  840. typesym :
  841. begin
  842. if not(ttypesym(sym).restype.def.deftype in [recorddef,objectdef]) then
  843. Message(asmr_e_wrong_sym_type);
  844. end;
  845. else
  846. Message(asmr_e_wrong_sym_type);
  847. end;
  848. end
  849. else
  850. Message1(sym_e_unknown_id,tempstr);
  851. end;
  852. { symbol found? }
  853. if hs<>'' then
  854. begin
  855. if needofs and (prevtok<>AS_OFFSET) then
  856. Message(asmr_e_need_offset);
  857. if asmsym='' then
  858. asmsym:=hs
  859. else
  860. Message(asmr_e_cant_have_multiple_relocatable_symbols);
  861. if (expr='') or (expr[length(expr)]='+') then
  862. begin
  863. { don't remove the + if there could be a record field }
  864. if actasmtoken<>AS_DOT then
  865. delete(expr,length(expr),1);
  866. end
  867. else
  868. Message(asmr_e_only_add_relocatable_symbol);
  869. end;
  870. if actasmtoken=AS_DOT then
  871. begin
  872. BuildRecordOffsetSize(tempstr,l,k);
  873. str(l, tempstr);
  874. expr:=expr + tempstr;
  875. end
  876. else
  877. begin
  878. if (expr='') or (expr[length(expr)] in ['+','-','/','*']) then
  879. delete(expr,length(expr),1);
  880. end;
  881. end;
  882. { check if there are wrong operator used like / or mod etc. }
  883. if (hs<>'') and not(actasmtoken in [AS_MINUS,AS_PLUS,AS_COMMA,AS_SEPARATOR,AS_END,AS_RBRACKET]) then
  884. Message(asmr_e_only_add_relocatable_symbol);
  885. end;
  886. AS_END,
  887. AS_RBRACKET,
  888. AS_SEPARATOR,
  889. AS_COMMA:
  890. Begin
  891. break;
  892. end;
  893. else
  894. Begin
  895. { write error only once. }
  896. if not errorflag then
  897. Message(asmr_e_invalid_constant_expression);
  898. { consume tokens until we find COMMA or SEPARATOR }
  899. Consume(actasmtoken);
  900. errorflag:=TRUE;
  901. end;
  902. end;
  903. Until false;
  904. { calculate expression }
  905. if not ErrorFlag then
  906. value:=CalculateExpression(expr)
  907. else
  908. value:=0;
  909. { no longer in an expression }
  910. inexpression:=FALSE;
  911. end;
  912. Function BuildConstExpression:longint;
  913. var
  914. l : longint;
  915. hs : string;
  916. begin
  917. BuildConstSymbolExpression(false,false,l,hs);
  918. if hs<>'' then
  919. Message(asmr_e_relocatable_symbol_not_allowed);
  920. BuildConstExpression:=l;
  921. end;
  922. Function BuildRefConstExpression:longint;
  923. var
  924. l : longint;
  925. hs : string;
  926. begin
  927. BuildConstSymbolExpression(false,true,l,hs);
  928. if hs<>'' then
  929. Message(asmr_e_relocatable_symbol_not_allowed);
  930. BuildRefConstExpression:=l;
  931. end;
  932. {****************************************************************************
  933. T386IntelOperand
  934. ****************************************************************************}
  935. type
  936. T386IntelOperand=class(T386Operand)
  937. Procedure BuildOperand;override;
  938. private
  939. Procedure BuildReference;
  940. Procedure BuildConstant;
  941. end;
  942. Procedure T386IntelOperand.BuildReference;
  943. var
  944. k,l,scale : longint;
  945. tempstr,hs : string;
  946. typesize : longint;
  947. code : integer;
  948. hreg,
  949. oldbase : tregister;
  950. GotStar,GotOffset,HadVar,
  951. GotPlus,Negative : boolean;
  952. Begin
  953. Consume(AS_LBRACKET);
  954. InitRef;
  955. GotStar:=false;
  956. GotPlus:=true;
  957. GotOffset:=false;
  958. Negative:=false;
  959. Scale:=0;
  960. repeat
  961. if GotOffset and (actasmtoken<>AS_ID) then
  962. Message(asmr_e_invalid_reference_syntax);
  963. Case actasmtoken of
  964. AS_ID: { Constant reference expression OR variable reference expression }
  965. Begin
  966. if not GotPlus then
  967. Message(asmr_e_invalid_reference_syntax);
  968. if actasmpattern[1] = '@' then
  969. Message(asmr_e_local_label_not_allowed_as_ref);
  970. GotStar:=false;
  971. GotPlus:=false;
  972. if SearchIConstant(actasmpattern,l) or
  973. SearchRecordType(actasmpattern) then
  974. begin
  975. l:=BuildRefConstExpression;
  976. GotPlus:=(prevasmtoken=AS_PLUS);
  977. GotStar:=(prevasmtoken=AS_STAR);
  978. if GotStar then
  979. opr.ref.scalefactor:=l
  980. else
  981. begin
  982. if negative then
  983. Dec(opr.ref.offset,l)
  984. else
  985. Inc(opr.ref.offset,l);
  986. end;
  987. end
  988. else
  989. Begin
  990. if hasvar and not GotOffset then
  991. Message(asmr_e_cant_have_multiple_relocatable_symbols);
  992. HadVar:=hasvar and GotOffset;
  993. if negative then
  994. Message(asmr_e_only_add_relocatable_symbol);
  995. oldbase:=opr.ref.base;
  996. opr.ref.base:=NR_NO;
  997. tempstr:=actasmpattern;
  998. Consume(AS_ID);
  999. { typecasting? }
  1000. if (actasmtoken=AS_LPAREN) and
  1001. SearchType(tempstr,typesize) then
  1002. begin
  1003. hastype:=true;
  1004. Consume(AS_LPAREN);
  1005. BuildOperand;
  1006. Consume(AS_RPAREN);
  1007. if opr.typ in [OPR_REFERENCE,OPR_LOCAL] then
  1008. SetSize(typesize,true);
  1009. end
  1010. else
  1011. if not SetupVar(tempstr,GotOffset) then
  1012. Message1(sym_e_unknown_id,tempstr);
  1013. { record.field ? }
  1014. if actasmtoken=AS_DOT then
  1015. begin
  1016. BuildRecordOffsetSize(tempstr,l,k);
  1017. inc(opr.ref.offset,l);
  1018. end;
  1019. if GotOffset then
  1020. begin
  1021. if hasvar and (opr.ref.base=current_procinfo.framepointer) then
  1022. begin
  1023. opr.ref.base:=NR_NO;
  1024. hasvar:=hadvar;
  1025. end
  1026. else
  1027. begin
  1028. if hasvar and hadvar then
  1029. Message(asmr_e_cant_have_multiple_relocatable_symbols);
  1030. { should we allow ?? }
  1031. end;
  1032. end;
  1033. { is the base register loaded by the var ? }
  1034. if (opr.ref.base<>NR_NO) then
  1035. begin
  1036. { check if we can move the old base to the index register }
  1037. if (opr.ref.index<>NR_NO) then
  1038. Message(asmr_e_wrong_base_index)
  1039. else
  1040. opr.ref.index:=oldbase;
  1041. end
  1042. else
  1043. opr.ref.base:=oldbase;
  1044. { we can't have a Constant here so add the constant value to the
  1045. offset }
  1046. if opr.typ=OPR_CONSTANT then
  1047. begin
  1048. opr.typ:=OPR_REFERENCE;
  1049. inc(opr.ref.offset,opr.val);
  1050. end;
  1051. end;
  1052. GotOffset:=false;
  1053. end;
  1054. AS_PLUS :
  1055. Begin
  1056. Consume(AS_PLUS);
  1057. Negative:=false;
  1058. GotPlus:=true;
  1059. GotStar:=false;
  1060. Scale:=0;
  1061. end;
  1062. AS_MINUS :
  1063. begin
  1064. Consume(AS_MINUS);
  1065. Negative:=true;
  1066. GotPlus:=true;
  1067. GotStar:=false;
  1068. Scale:=0;
  1069. end;
  1070. AS_STAR : { Scaling, with eax*4 order }
  1071. begin
  1072. Consume(AS_STAR);
  1073. hs:='';
  1074. l:=0;
  1075. case actasmtoken of
  1076. AS_LPAREN :
  1077. l:=BuildConstExpression;
  1078. AS_INTNUM:
  1079. Begin
  1080. hs:=actasmpattern;
  1081. Consume(AS_INTNUM);
  1082. end;
  1083. AS_REGISTER :
  1084. begin
  1085. if opr.ref.scalefactor=0 then
  1086. if scale<>0 then
  1087. begin
  1088. opr.ref.scalefactor:=scale;
  1089. scale:=0;
  1090. end
  1091. else
  1092. Message(asmr_e_wrong_scale_factor);
  1093. end;
  1094. else
  1095. Message(asmr_e_invalid_reference_syntax);
  1096. end;
  1097. if actasmtoken<>AS_REGISTER then
  1098. begin
  1099. if hs<>'' then
  1100. val(hs,l,code);
  1101. opr.ref.scalefactor:=l;
  1102. if l>9 then
  1103. Message(asmr_e_wrong_scale_factor);
  1104. end;
  1105. GotPlus:=false;
  1106. GotStar:=false;
  1107. end;
  1108. AS_REGISTER :
  1109. begin
  1110. if not((GotPlus and (not Negative)) or
  1111. GotStar) then
  1112. Message(asmr_e_invalid_reference_syntax);
  1113. hreg:=actasmregister;
  1114. Consume(AS_REGISTER);
  1115. { this register will be the index:
  1116. 1. just read a *
  1117. 2. next token is a *
  1118. 3. base register is already used }
  1119. if (GotStar) or
  1120. (actasmtoken=AS_STAR) or
  1121. (opr.ref.base<>NR_NO) then
  1122. begin
  1123. if (opr.ref.index<>NR_NO) then
  1124. Message(asmr_e_multiple_index);
  1125. opr.ref.index:=hreg;
  1126. if scale<>0 then
  1127. begin
  1128. opr.ref.scalefactor:=scale;
  1129. scale:=0;
  1130. end;
  1131. end
  1132. else
  1133. opr.ref.base:=hreg;
  1134. GotPlus:=false;
  1135. GotStar:=false;
  1136. end;
  1137. AS_OFFSET :
  1138. begin
  1139. Consume(AS_OFFSET);
  1140. GotOffset:=true;
  1141. end;
  1142. AS_TYPE,
  1143. AS_NOT,
  1144. AS_STRING,
  1145. AS_INTNUM,
  1146. AS_LPAREN : { Constant reference expression }
  1147. begin
  1148. if not GotPlus and not GotStar then
  1149. Message(asmr_e_invalid_reference_syntax);
  1150. BuildConstSymbolExpression(true,true,l,tempstr);
  1151. if tempstr<>'' then
  1152. begin
  1153. if GotStar then
  1154. Message(asmr_e_only_add_relocatable_symbol);
  1155. if not assigned(opr.ref.symbol) then
  1156. opr.ref.symbol:=objectlibrary.newasmsymbol(tempstr)
  1157. else
  1158. Message(asmr_e_cant_have_multiple_relocatable_symbols);
  1159. end;
  1160. if GotStar then
  1161. opr.ref.scalefactor:=l
  1162. else if (prevasmtoken = AS_STAR) then
  1163. begin
  1164. if scale<>0 then
  1165. scale:=l*scale
  1166. else
  1167. scale:=l;
  1168. end
  1169. else
  1170. begin
  1171. if negative then
  1172. Dec(opr.ref.offset,l)
  1173. else
  1174. Inc(opr.ref.offset,l);
  1175. end;
  1176. GotPlus:=(prevasmtoken=AS_PLUS) or
  1177. (prevasmtoken=AS_MINUS);
  1178. if GotPlus then
  1179. negative := prevasmtoken = AS_MINUS;
  1180. GotStar:=(prevasmtoken=AS_STAR);
  1181. end;
  1182. AS_RBRACKET :
  1183. begin
  1184. if GotPlus or GotStar then
  1185. Message(asmr_e_invalid_reference_syntax);
  1186. Consume(AS_RBRACKET);
  1187. break;
  1188. end;
  1189. else
  1190. Begin
  1191. Message(asmr_e_invalid_reference_syntax);
  1192. RecoverConsume(true);
  1193. break;
  1194. end;
  1195. end;
  1196. until false;
  1197. end;
  1198. Procedure T386IntelOperand.BuildConstant;
  1199. var
  1200. l : longint;
  1201. tempstr : string;
  1202. begin
  1203. BuildConstSymbolExpression(true,false,l,tempstr);
  1204. if tempstr<>'' then
  1205. begin
  1206. opr.typ:=OPR_SYMBOL;
  1207. opr.symofs:=l;
  1208. opr.symbol:=objectlibrary.newasmsymbol(tempstr);
  1209. end
  1210. else
  1211. begin
  1212. opr.typ:=OPR_CONSTANT;
  1213. opr.val:=l;
  1214. end;
  1215. end;
  1216. Procedure T386IntelOperand.BuildOperand;
  1217. var
  1218. expr : string;
  1219. tempreg : tregister;
  1220. typesize,
  1221. l : longint;
  1222. hl : tasmlabel;
  1223. procedure AddLabelOperand(hl:tasmlabel);
  1224. begin
  1225. if is_calljmp(actopcode) then
  1226. begin
  1227. opr.typ:=OPR_SYMBOL;
  1228. opr.symbol:=hl;
  1229. end
  1230. else
  1231. begin
  1232. InitRef;
  1233. opr.ref.symbol:=hl;
  1234. end;
  1235. end;
  1236. procedure MaybeRecordOffset;
  1237. var
  1238. l,
  1239. toffset,
  1240. tsize : longint;
  1241. begin
  1242. if not(actasmtoken in [AS_DOT,AS_PLUS,AS_MINUS]) then
  1243. exit;
  1244. l:=0;
  1245. if actasmtoken=AS_DOT then
  1246. begin
  1247. { if no type was specified before the [] then we expect the
  1248. first ID to be the type }
  1249. if expr='' then
  1250. begin
  1251. consume(AS_DOT);
  1252. if actasmtoken=AS_ID then
  1253. begin
  1254. expr:=actasmpattern;
  1255. consume(AS_ID);
  1256. { now the next one must the be the dot }
  1257. if actasmtoken<>AS_DOT then
  1258. begin
  1259. { if it is not a dot then we expect a constant
  1260. value as offset }
  1261. if not SearchIConstant(expr,l) then
  1262. Message(asmr_e_building_record_offset);
  1263. expr:='';
  1264. end;
  1265. end
  1266. else
  1267. Message(asmr_e_no_var_type_specified)
  1268. end;
  1269. if expr<>'' then
  1270. begin
  1271. BuildRecordOffsetSize(expr,toffset,tsize);
  1272. inc(l,toffset);
  1273. SetSize(tsize,true);
  1274. end;
  1275. end;
  1276. if actasmtoken in [AS_PLUS,AS_MINUS] then
  1277. inc(l,BuildConstExpression);
  1278. case opr.typ of
  1279. OPR_LOCAL :
  1280. begin
  1281. { don't allow direct access to fields of parameters, becuase that
  1282. will generate buggy code. Allow it only for explicit typecasting
  1283. and when the parameter is in a register (delphi compatible) }
  1284. if (not hastype) and
  1285. (tvarsym(opr.localsym).owner.symtabletype=parasymtable) and
  1286. (current_procinfo.procdef.proccalloption<>pocall_register) then
  1287. Message(asmr_e_cannot_access_field_directly_for_parameters);
  1288. inc(opr.localsymofs,l)
  1289. end;
  1290. OPR_CONSTANT :
  1291. inc(opr.val,l);
  1292. OPR_REFERENCE :
  1293. inc(opr.ref.offset,l);
  1294. else
  1295. internalerror(200309222);
  1296. end;
  1297. end;
  1298. Begin
  1299. repeat
  1300. expr:='';
  1301. if actasmtoken=AS_DOT then
  1302. Consume(AS_DOT);
  1303. case actasmtoken of
  1304. AS_OFFSET,
  1305. AS_TYPE,
  1306. AS_PLUS,
  1307. AS_MINUS,
  1308. AS_NOT,
  1309. AS_LPAREN,
  1310. AS_STRING :
  1311. Begin
  1312. if not (opr.typ in [OPR_NONE,OPR_CONSTANT]) then
  1313. Message(asmr_e_invalid_operand_type);
  1314. BuildConstant;
  1315. end;
  1316. AS_INTNUM :
  1317. begin
  1318. case opr.typ of
  1319. OPR_REFERENCE :
  1320. inc(opr.ref.offset,BuildRefConstExpression);
  1321. OPR_LOCAL :
  1322. inc(opr.localsymofs,BuildRefConstExpression);
  1323. OPR_NONE,
  1324. OPR_CONSTANT :
  1325. BuildConstant;
  1326. else
  1327. Message(asmr_e_invalid_operand_type);
  1328. end;
  1329. end;
  1330. AS_ID : { A constant expression, or a Variable ref. }
  1331. Begin
  1332. { Label or Special symbol reference? }
  1333. if actasmpattern[1] = '@' then
  1334. Begin
  1335. if actasmpattern = '@RESULT' then
  1336. Begin
  1337. InitRef;
  1338. SetupResult;
  1339. Consume(AS_ID);
  1340. end
  1341. else
  1342. if (actasmpattern = '@CODE') or (actasmpattern = '@DATA') then
  1343. begin
  1344. Message(asmr_w_CODE_and_DATA_not_supported);
  1345. Consume(AS_ID);
  1346. end
  1347. else
  1348. { Local Label }
  1349. begin
  1350. CreateLocalLabel(actasmpattern,hl,false);
  1351. Consume(AS_ID);
  1352. AddLabelOperand(hl);
  1353. if not (actasmtoken in [AS_END,AS_SEPARATOR,AS_COMMA]) then
  1354. Message(asmr_e_syntax_error);
  1355. end;
  1356. end
  1357. else
  1358. { support result for delphi modes }
  1359. if (m_objpas in aktmodeswitches) and (actasmpattern='RESULT') then
  1360. begin
  1361. InitRef;
  1362. SetUpResult;
  1363. Consume(AS_ID);
  1364. end
  1365. { probably a variable or normal expression }
  1366. { or a procedure (such as in CALL ID) }
  1367. else
  1368. Begin
  1369. { is it a constant ? }
  1370. if SearchIConstant(actasmpattern,l) then
  1371. Begin
  1372. case opr.typ of
  1373. OPR_REFERENCE :
  1374. inc(opr.ref.offset,BuildRefConstExpression);
  1375. OPR_LOCAL :
  1376. inc(opr.localsymofs,BuildRefConstExpression);
  1377. OPR_NONE,
  1378. OPR_CONSTANT :
  1379. BuildConstant;
  1380. else
  1381. Message(asmr_e_invalid_operand_type);
  1382. end;
  1383. end
  1384. else
  1385. { Check for pascal label }
  1386. if SearchLabel(actasmpattern,hl,false) then
  1387. begin
  1388. Consume(AS_ID);
  1389. AddLabelOperand(hl);
  1390. if not (actasmtoken in [AS_END,AS_SEPARATOR,AS_COMMA]) then
  1391. Message(asmr_e_syntax_error);
  1392. end
  1393. else
  1394. { is it a normal variable ? }
  1395. Begin
  1396. InitRef;
  1397. expr:=actasmpattern;
  1398. Consume(AS_ID);
  1399. { typecasting? }
  1400. if (actasmtoken=AS_LPAREN) and
  1401. SearchType(expr,typesize) then
  1402. begin
  1403. hastype:=true;
  1404. Consume(AS_LPAREN);
  1405. BuildOperand;
  1406. Consume(AS_RPAREN);
  1407. if opr.typ in [OPR_REFERENCE,OPR_LOCAL] then
  1408. SetSize(typesize,true);
  1409. end
  1410. else
  1411. begin
  1412. if SetupVar(expr,false) then
  1413. begin
  1414. MaybeRecordOffset;
  1415. { add a constant expression? }
  1416. if (actasmtoken=AS_PLUS) then
  1417. begin
  1418. l:=BuildConstExpression;
  1419. case opr.typ of
  1420. OPR_CONSTANT :
  1421. inc(opr.val,l);
  1422. OPR_LOCAL :
  1423. inc(opr.localsymofs,l);
  1424. OPR_REFERENCE :
  1425. inc(opr.ref.offset,l);
  1426. else
  1427. internalerror(200309203);
  1428. end;
  1429. end
  1430. end
  1431. else
  1432. Begin
  1433. { not a variable, check special variables.. }
  1434. if expr = 'SELF' then
  1435. SetupSelf
  1436. else
  1437. Message1(sym_e_unknown_id,expr);
  1438. end;
  1439. end;
  1440. end;
  1441. { handle references }
  1442. if actasmtoken=AS_LBRACKET then
  1443. begin
  1444. if opr.typ=OPR_CONSTANT then
  1445. begin
  1446. l:=opr.val;
  1447. opr.typ:=OPR_REFERENCE;
  1448. reference_reset(opr.ref);
  1449. opr.Ref.Offset:=l;
  1450. end;
  1451. BuildReference;
  1452. end;
  1453. end;
  1454. end;
  1455. AS_REGISTER : { Register, a variable reference or a constant reference }
  1456. begin
  1457. { save the type of register used. }
  1458. tempreg:=actasmregister;
  1459. Consume(AS_REGISTER);
  1460. if actasmtoken = AS_COLON then
  1461. Begin
  1462. Consume(AS_COLON);
  1463. InitRef;
  1464. opr.ref.segment:=tempreg;
  1465. BuildReference;
  1466. end
  1467. else
  1468. { Simple register }
  1469. begin
  1470. if not (opr.typ in [OPR_NONE,OPR_REGISTER]) then
  1471. Message(asmr_e_invalid_operand_type);
  1472. opr.typ:=OPR_REGISTER;
  1473. opr.reg:=tempreg;
  1474. SetSize(tcgsize2size[cg.reg_cgsize(opr.reg)],true);
  1475. end;
  1476. end;
  1477. AS_LBRACKET: { a variable reference, register ref. or a constant reference }
  1478. Begin
  1479. InitRef;
  1480. BuildReference;
  1481. end;
  1482. AS_SEG :
  1483. Begin
  1484. Message(asmr_e_seg_not_supported);
  1485. Consume(actasmtoken);
  1486. end;
  1487. AS_SEPARATOR,
  1488. AS_END,
  1489. AS_COMMA:
  1490. break;
  1491. else
  1492. Message(asmr_e_syn_operand);
  1493. end;
  1494. until not(actasmtoken in [AS_DOT,AS_LBRACKET]);
  1495. if not((actasmtoken in [AS_END,AS_SEPARATOR,AS_COMMA]) or
  1496. (hastype and (actasmtoken=AS_RPAREN))) then
  1497. begin
  1498. Message(asmr_e_syntax_error);
  1499. RecoverConsume(true);
  1500. end;
  1501. end;
  1502. {*****************************************************************************
  1503. T386IntelInstruction
  1504. *****************************************************************************}
  1505. type
  1506. T386IntelInstruction=class(T386Instruction)
  1507. procedure InitOperands;override;
  1508. procedure BuildOpcode;override;
  1509. end;
  1510. procedure T386IntelInstruction.InitOperands;
  1511. var
  1512. i : longint;
  1513. begin
  1514. for i:=1 to 3 do
  1515. Operands[i]:=T386IntelOperand.Create;
  1516. end;
  1517. Procedure T386IntelInstruction.BuildOpCode;
  1518. var
  1519. PrefixOp,OverrideOp: tasmop;
  1520. size,
  1521. operandnum : longint;
  1522. Begin
  1523. PrefixOp:=A_None;
  1524. OverrideOp:=A_None;
  1525. { prefix seg opcode / prefix opcode }
  1526. repeat
  1527. if is_prefix(actopcode) then
  1528. begin
  1529. OpOrder:=op_intel;
  1530. PrefixOp:=ActOpcode;
  1531. opcode:=ActOpcode;
  1532. condition:=ActCondition;
  1533. opsize:=ActOpsize;
  1534. ConcatInstruction(curlist);
  1535. Consume(AS_OPCODE);
  1536. end
  1537. else
  1538. if is_override(actopcode) then
  1539. begin
  1540. OpOrder:=op_intel;
  1541. OverrideOp:=ActOpcode;
  1542. opcode:=ActOpcode;
  1543. condition:=ActCondition;
  1544. opsize:=ActOpsize;
  1545. ConcatInstruction(curlist);
  1546. Consume(AS_OPCODE);
  1547. end
  1548. else
  1549. break;
  1550. { allow for newline after prefix or override }
  1551. while actasmtoken=AS_SEPARATOR do
  1552. Consume(AS_SEPARATOR);
  1553. until (actasmtoken<>AS_OPCODE);
  1554. { opcode }
  1555. if (actasmtoken <> AS_OPCODE) then
  1556. Begin
  1557. Message(asmr_e_invalid_or_missing_opcode);
  1558. RecoverConsume(false);
  1559. exit;
  1560. end;
  1561. { Fill the instr object with the current state }
  1562. OpOrder:=op_intel;
  1563. Opcode:=ActOpcode;
  1564. condition:=ActCondition;
  1565. opsize:=ActOpsize;
  1566. { Valid combination of prefix/override and instruction ? }
  1567. if (prefixop<>A_NONE) and (NOT CheckPrefix(PrefixOp,actopcode)) then
  1568. Message1(asmr_e_invalid_prefix_and_opcode,actasmpattern);
  1569. if (overrideop<>A_NONE) and (NOT CheckOverride(OverrideOp,ActOpcode)) then
  1570. Message1(asmr_e_invalid_override_and_opcode,actasmpattern);
  1571. { We are reading operands, so opcode will be an AS_ID }
  1572. operandnum:=1;
  1573. Consume(AS_OPCODE);
  1574. { Zero operand opcode ? }
  1575. if actasmtoken in [AS_SEPARATOR,AS_END] then
  1576. begin
  1577. operandnum:=0;
  1578. exit;
  1579. end;
  1580. { Read Operands }
  1581. repeat
  1582. case actasmtoken of
  1583. { End of asm operands for this opcode }
  1584. AS_END,
  1585. AS_SEPARATOR :
  1586. break;
  1587. { Operand delimiter }
  1588. AS_COMMA :
  1589. Begin
  1590. if operandnum > Max_Operands then
  1591. Message(asmr_e_too_many_operands)
  1592. else
  1593. Inc(operandnum);
  1594. Consume(AS_COMMA);
  1595. end;
  1596. { Typecast, Constant Expression, Type Specifier }
  1597. AS_DWORD,
  1598. AS_BYTE,
  1599. AS_WORD,
  1600. AS_TBYTE,
  1601. AS_QWORD :
  1602. Begin
  1603. { load the size in a temp variable, so it can be set when the
  1604. operand is read }
  1605. size:=0;
  1606. Case actasmtoken of
  1607. AS_DWORD : size:=4;
  1608. AS_WORD : size:=2;
  1609. AS_BYTE : size:=1;
  1610. AS_QWORD : size:=8;
  1611. AS_TBYTE : size:=extended_size;
  1612. end;
  1613. Consume(actasmtoken);
  1614. if actasmtoken=AS_PTR then
  1615. begin
  1616. Consume(AS_PTR);
  1617. Operands[operandnum].InitRef;
  1618. end;
  1619. Operands[operandnum].BuildOperand;
  1620. { now set the size which was specified by the override }
  1621. Operands[operandnum].setsize(size,true);
  1622. end;
  1623. { Type specifier }
  1624. AS_NEAR,
  1625. AS_FAR :
  1626. Begin
  1627. if actasmtoken = AS_NEAR then
  1628. begin
  1629. Message(asmr_w_near_ignored);
  1630. opsize:=S_NEAR;
  1631. end
  1632. else
  1633. begin
  1634. Message(asmr_w_far_ignored);
  1635. opsize:=S_FAR;
  1636. end;
  1637. Consume(actasmtoken);
  1638. if actasmtoken=AS_PTR then
  1639. begin
  1640. Consume(AS_PTR);
  1641. Operands[operandnum].InitRef;
  1642. end;
  1643. Operands[operandnum].BuildOperand;
  1644. end;
  1645. else
  1646. Operands[operandnum].BuildOperand;
  1647. end; { end case }
  1648. until false;
  1649. Ops:=operandnum;
  1650. end;
  1651. Procedure BuildConstant(maxvalue: longint);
  1652. var
  1653. strlength: byte;
  1654. asmsym,
  1655. expr: string;
  1656. value : longint;
  1657. Begin
  1658. strlength:=0; { assume it is a DB }
  1659. Repeat
  1660. Case actasmtoken of
  1661. AS_STRING:
  1662. Begin
  1663. if maxvalue = $ffff then
  1664. strlength:=2
  1665. else
  1666. if maxvalue = longint($ffffffff) then
  1667. strlength:=4;
  1668. { DD and DW cases }
  1669. if strlength <> 0 then
  1670. Begin
  1671. if Not PadZero(actasmpattern,strlength) then
  1672. Message(scan_f_string_exceeds_line);
  1673. end;
  1674. expr:=actasmpattern;
  1675. Consume(AS_STRING);
  1676. Case actasmtoken of
  1677. AS_COMMA:
  1678. Consume(AS_COMMA);
  1679. AS_END,
  1680. AS_SEPARATOR: ;
  1681. else
  1682. Message(asmr_e_invalid_string_expression);
  1683. end;
  1684. ConcatString(curlist,expr);
  1685. end;
  1686. AS_PLUS,
  1687. AS_MINUS,
  1688. AS_LPAREN,
  1689. AS_NOT,
  1690. AS_INTNUM,
  1691. AS_ID :
  1692. Begin
  1693. BuildConstSymbolExpression(false,false,value,asmsym);
  1694. if asmsym<>'' then
  1695. begin
  1696. if maxvalue<>longint($ffffffff) then
  1697. Message1(asmr_w_const32bit_for_address,asmsym);
  1698. ConcatConstSymbol(curlist,asmsym,value)
  1699. end
  1700. else
  1701. ConcatConstant(curlist,value,maxvalue);
  1702. end;
  1703. AS_COMMA:
  1704. Consume(AS_COMMA);
  1705. AS_END,
  1706. AS_SEPARATOR:
  1707. break;
  1708. else
  1709. begin
  1710. Message(asmr_e_syn_constant);
  1711. RecoverConsume(false);
  1712. end
  1713. end;
  1714. Until false;
  1715. end;
  1716. Function Assemble: tnode;
  1717. Var
  1718. hl : tasmlabel;
  1719. instr : T386IntelInstruction;
  1720. Begin
  1721. Message1(asmr_d_start_reading,'intel');
  1722. inexpression:=FALSE;
  1723. firsttoken:=TRUE;
  1724. { sets up all opcode and register tables in uppercase }
  1725. if not _asmsorted then
  1726. Begin
  1727. SetupTables;
  1728. _asmsorted:=TRUE;
  1729. end;
  1730. curlist:=TAAsmoutput.Create;
  1731. { setup label linked list }
  1732. LocalLabelList:=TLocalLabelList.Create;
  1733. { start tokenizer }
  1734. c:=current_scanner.asmgetchar;
  1735. gettoken;
  1736. { main loop }
  1737. repeat
  1738. case actasmtoken of
  1739. AS_LLABEL:
  1740. Begin
  1741. if CreateLocalLabel(actasmpattern,hl,true) then
  1742. ConcatLabel(curlist,hl);
  1743. Consume(AS_LLABEL);
  1744. end;
  1745. AS_LABEL:
  1746. Begin
  1747. if SearchLabel(upper(actasmpattern),hl,true) then
  1748. ConcatLabel(curlist,hl)
  1749. else
  1750. Message1(asmr_e_unknown_label_identifier,actasmpattern);
  1751. Consume(AS_LABEL);
  1752. end;
  1753. AS_DW :
  1754. Begin
  1755. inexpression:=true;
  1756. Consume(AS_DW);
  1757. BuildConstant($ffff);
  1758. inexpression:=false;
  1759. end;
  1760. AS_DB :
  1761. Begin
  1762. inexpression:=true;
  1763. Consume(AS_DB);
  1764. BuildConstant($ff);
  1765. inexpression:=false;
  1766. end;
  1767. AS_DD :
  1768. Begin
  1769. inexpression:=true;
  1770. Consume(AS_DD);
  1771. BuildConstant(longint($ffffffff));
  1772. inexpression:=false;
  1773. end;
  1774. AS_OPCODE :
  1775. Begin
  1776. instr:=T386IntelInstruction.Create;
  1777. instr.BuildOpcode;
  1778. { We need AT&T style operands }
  1779. instr.Swapoperands;
  1780. { Must be done with args in ATT order }
  1781. instr.CheckNonCommutativeOpcodes;
  1782. instr.AddReferenceSizes;
  1783. instr.SetInstructionOpsize;
  1784. instr.CheckOperandSizes;
  1785. instr.ConcatInstruction(curlist);
  1786. instr.Free;
  1787. end;
  1788. AS_SEPARATOR :
  1789. Begin
  1790. Consume(AS_SEPARATOR);
  1791. end;
  1792. AS_END :
  1793. break; { end assembly block }
  1794. else
  1795. Begin
  1796. Message(asmr_e_syntax_error);
  1797. RecoverConsume(false);
  1798. end;
  1799. end; { end case }
  1800. until false;
  1801. { Check LocalLabelList }
  1802. LocalLabelList.CheckEmitted;
  1803. LocalLabelList.Free;
  1804. { Return the list in an asmnode }
  1805. assemble:=casmnode.create(curlist);
  1806. Message1(asmr_d_finish_reading,'intel');
  1807. end;
  1808. {*****************************************************************************
  1809. Initialize
  1810. *****************************************************************************}
  1811. const
  1812. asmmode_i386_intel_info : tasmmodeinfo =
  1813. (
  1814. id : asmmode_i386_intel;
  1815. idtxt : 'INTEL'
  1816. );
  1817. initialization
  1818. RegisterAsmMode(asmmode_i386_intel_info);
  1819. finalization
  1820. if assigned(iasmops) then
  1821. iasmops.Free;
  1822. end.
  1823. {
  1824. $Log$
  1825. Revision 1.58 2003-10-23 17:19:44 peter
  1826. * typecasting fixes
  1827. * reference building more delphi compatible
  1828. Revision 1.57 2003/10/21 18:17:40 peter
  1829. * ignore @ in Unit.@Proc
  1830. Revision 1.56 2003/10/10 17:48:14 peter
  1831. * old trgobj moved to x86/rgcpu and renamed to trgx86fpu
  1832. * tregisteralloctor renamed to trgobj
  1833. * removed rgobj from a lot of units
  1834. * moved location_* and reference_* to cgobj
  1835. * first things for mmx register allocation
  1836. Revision 1.55 2003/10/07 18:21:18 peter
  1837. * fix crash
  1838. * allow parameter subscription for register parameters
  1839. Revision 1.54 2003/10/02 21:17:38 peter
  1840. * fix operand order when a prefix opcode is supplied
  1841. Revision 1.53 2003/10/01 20:34:49 peter
  1842. * procinfo unit contains tprocinfo
  1843. * cginfo renamed to cgbase
  1844. * moved cgmessage to verbose
  1845. * fixed ppc and sparc compiles
  1846. Revision 1.52 2003/09/23 20:37:53 peter
  1847. * fix global var+offset
  1848. Revision 1.51 2003/09/23 17:56:06 peter
  1849. * locals and paras are allocated in the code generation
  1850. * tvarsym.localloc contains the location of para/local when
  1851. generating code for the current procedure
  1852. Revision 1.50 2003/09/03 15:55:01 peter
  1853. * NEWRA branch merged
  1854. Revision 1.49.2.2 2003/08/31 15:46:26 peter
  1855. * more updates for tregister
  1856. Revision 1.49.2.1 2003/08/28 18:35:08 peter
  1857. * tregister changed to cardinal
  1858. Revision 1.49 2003/06/06 14:41:59 peter
  1859. * use setsize for size specifier
  1860. Revision 1.48 2003/05/30 23:57:08 peter
  1861. * more sparc cleanup
  1862. * accumulator removed, splitted in function_return_reg (called) and
  1863. function_result_reg (caller)
  1864. Revision 1.47 2003/04/30 15:45:35 florian
  1865. * merged more x86-64/i386 code
  1866. Revision 1.46 2003/04/27 11:21:35 peter
  1867. * aktprocdef renamed to current_procdef
  1868. * procinfo renamed to current_procinfo
  1869. * procinfo will now be stored in current_module so it can be
  1870. cleaned up properly
  1871. * gen_main_procsym changed to create_main_proc and release_main_proc
  1872. to also generate a tprocinfo structure
  1873. * fixed unit implicit initfinal
  1874. Revision 1.45 2003/04/21 20:05:10 peter
  1875. * removed some ie checks
  1876. Revision 1.44 2003/03/28 19:16:57 peter
  1877. * generic constructor working for i386
  1878. * remove fixed self register
  1879. * esi added as address register for i386
  1880. Revision 1.43 2003/03/18 18:15:53 peter
  1881. * changed reg2opsize to function
  1882. Revision 1.42 2003/03/17 21:32:52 peter
  1883. * allow character constants in reference declaration
  1884. Revision 1.41 2003/02/26 22:57:44 daniel
  1885. * Changed no longer correct fillchar of reference into location_reset
  1886. Revision 1.40 2003/02/19 22:00:16 daniel
  1887. * Code generator converted to new register notation
  1888. - Horribily outdated todo.txt removed
  1889. Revision 1.39 2003/01/08 18:43:57 daniel
  1890. * Tregister changed into a record
  1891. Revision 1.38 2002/12/14 15:02:03 carl
  1892. * maxoperands -> max_operands (for portability in rautils.pas)
  1893. * fix some range-check errors with loadconst
  1894. + add ncgadd unit to m68k
  1895. * some bugfix of a_param_reg with LOC_CREFERENCE
  1896. Revision 1.37 2002/12/01 22:08:34 carl
  1897. * some small cleanup (remove some specific operators which are not supported)
  1898. Revision 1.36 2002/11/15 01:58:59 peter
  1899. * merged changes from 1.0.7 up to 04-11
  1900. - -V option for generating bug report tracing
  1901. - more tracing for option parsing
  1902. - errors for cdecl and high()
  1903. - win32 import stabs
  1904. - win32 records<=8 are returned in eax:edx (turned off by default)
  1905. - heaptrc update
  1906. - more info for temp management in .s file with EXTDEBUG
  1907. Revision 1.35 2002/09/16 19:07:00 peter
  1908. * support [eax].constant as reference
  1909. Revision 1.34 2002/09/03 16:26:28 daniel
  1910. * Make Tprocdef.defs protected
  1911. Revision 1.33 2002/08/17 09:23:47 florian
  1912. * first part of procinfo rewrite
  1913. Revision 1.32 2002/08/13 18:01:52 carl
  1914. * rename swatoperands to swapoperands
  1915. + m68k first compilable version (still needs a lot of testing):
  1916. assembler generator, system information , inline
  1917. assembler reader.
  1918. Revision 1.31 2002/08/11 14:32:31 peter
  1919. * renamed current_library to objectlibrary
  1920. Revision 1.30 2002/08/11 13:24:17 peter
  1921. * saving of asmsymbols in ppu supported
  1922. * asmsymbollist global is removed and moved into a new class
  1923. tasmlibrarydata that will hold the info of a .a file which
  1924. corresponds with a single module. Added librarydata to tmodule
  1925. to keep the library info stored for the module. In the future the
  1926. objectfiles will also be stored to the tasmlibrarydata class
  1927. * all getlabel/newasmsymbol and friends are moved to the new class
  1928. Revision 1.29 2002/07/01 18:46:34 peter
  1929. * internal linker
  1930. * reorganized aasm layer
  1931. Revision 1.28 2002/05/18 13:34:26 peter
  1932. * readded missing revisions
  1933. Revision 1.27 2002/05/16 19:46:52 carl
  1934. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  1935. + try to fix temp allocation (still in ifdef)
  1936. + generic constructor calls
  1937. + start of tassembler / tmodulebase class cleanup
  1938. Revision 1.25 2002/04/20 21:37:07 carl
  1939. + generic FPC_CHECKPOINTER
  1940. + first parameter offset in stack now portable
  1941. * rename some constants
  1942. + move some cpu stuff to other units
  1943. - remove unused constents
  1944. * fix stacksize for some targets
  1945. * fix generic size problems which depend now on EXTEND_SIZE constant
  1946. * removing frame pointer in routines is only available for : i386,m68k and vis targets
  1947. Revision 1.24 2002/04/15 19:44:22 peter
  1948. * fixed stackcheck that would be called recursively when a stack
  1949. error was found
  1950. * generic changeregsize(reg,size) for i386 register resizing
  1951. * removed some more routines from cga unit
  1952. * fixed returnvalue handling
  1953. * fixed default stacksize of linux and go32v2, 8kb was a bit small :-)
  1954. Revision 1.23 2002/04/15 19:12:09 carl
  1955. + target_info.size_of_pointer -> pointer_size
  1956. + some cleanup of unused types/variables
  1957. * move several constants from cpubase to their specific units
  1958. (where they are used)
  1959. + att_Reg2str -> gas_reg2str
  1960. + int_reg2str -> std_reg2str
  1961. Revision 1.22 2002/04/04 19:06:13 peter
  1962. * removed unused units
  1963. * use tlocation.size in cg.a_*loc*() routines
  1964. Revision 1.21 2002/04/02 17:11:39 peter
  1965. * tlocation,treference update
  1966. * LOC_CONSTANT added for better constant handling
  1967. * secondadd splitted in multiple routines
  1968. * location_force_reg added for loading a location to a register
  1969. of a specified size
  1970. * secondassignment parses now first the right and then the left node
  1971. (this is compatible with Kylix). This saves a lot of push/pop especially
  1972. with string operations
  1973. * adapted some routines to use the new cg methods
  1974. Revision 1.20 2002/01/24 18:25:53 peter
  1975. * implicit result variable generation for assembler routines
  1976. * removed m_tp modeswitch, use m_tp7 or not(m_fpc) instead
  1977. }