out68k_as.c 70 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017
  1. /*
  2. * GTools C compiler
  3. * =================
  4. * source file :
  5. * assembled binary output
  6. *
  7. * Copyright 2001-2004 Paul Froissart.
  8. * Credits to Christoph van Wuellen and Matthew Brandt.
  9. * All commercial rights reserved.
  10. *
  11. * This compiler may be redistributed as long there is no
  12. * commercial interest. The compiler must not be redistributed
  13. * without its full sources. This notice must stay intact.
  14. */
  15. #include "define.h"
  16. _FILE(__FILE__)
  17. #include "c.h"
  18. #include "expr.h"
  19. #include "gen.h"
  20. #include "cglbdec.h"
  21. #ifdef PC
  22. void nl(void) {
  23. }
  24. #define nl() while (0)
  25. #endif
  26. #ifdef SECURIZED_ALIGN
  27. #define put_align(__a) while (0)
  28. #else
  29. #define put_align(__a) put_align2()
  30. #endif
  31. #ifdef PC
  32. #define tabs "\t"
  33. #else
  34. #define tabs " "
  35. #endif
  36. #define N_TAB 64
  37. #define N_TAB_LOG 6
  38. typedef struct _ltab {
  39. struct _ltab *nxt;
  40. unsigned int t[N_TAB];
  41. } LTAB;
  42. #define N_REF 8
  43. #define N_REF_LOG 3
  44. typedef struct _ref {
  45. unsigned int r[N_REF];
  46. struct _ref *nxt; // very important to be afterwards : if nxt==NULL, then r[N_REF]==0
  47. } REF;
  48. typedef struct _gtab {
  49. struct _gtab *nxt;
  50. unsigned int t[N_TAB];
  51. REF *r[N_TAB];
  52. } GTAB;
  53. typedef struct _rtype {
  54. REF *r0,*r;
  55. } RTYPE;
  56. typedef struct _func {
  57. RTYPE rt;
  58. unsigned int f;
  59. struct _func *nxt;
  60. } FUNC;
  61. typedef struct _xtab {
  62. struct _xtab *nxt;
  63. RTYPE *t[N_TAB];
  64. } XTAB;
  65. FILE *output CGLOB;
  66. unsigned char *bin CGLOB;
  67. struct slit *strtab CGLOB;
  68. long lc_bss CGLOB;
  69. xstatic int lc_stk CGLOB,uses_lc_stk CGLOB;
  70. xstatic char odd CGLOB; // for put_align
  71. xstatic int extlabel CGLOB;
  72. int glblabel CGLOB;
  73. struct ocode *scope_head CGLOB;
  74. unsigned int pos CGLOB,bin_size CGLOB;
  75. int nostub_mode CGLOB;
  76. #ifdef EXE_OUT
  77. int exestub_mode CGLOB;
  78. #else
  79. #define exestub_mode 0
  80. #endif
  81. LTAB *loc_tab CGLOB;
  82. GTAB *glb_tab CGLOB;
  83. XTAB *ext_tab CGLOB;
  84. LTAB *exp_tab CGLOB; // warning : the content is the exported label (but not the offset)
  85. FUNC *rom_funcs CGLOB;
  86. #ifdef RAM_CALLS
  87. FUNC *ram_funcs CGLOB;
  88. #endif
  89. RTYPE reloc_tab CGLOBL,bss_tab CGLOBL;
  90. HTABLE alsyms CGLOBL;
  91. TABLE libsyms CGLOBL; // (FUNC *)sym->value.i
  92. #ifdef SIZE_STATS
  93. xstatic unsigned int c_compiler_sz CGLOB;
  94. #endif
  95. #ifdef MC680X0
  96. /* variable initialization */
  97. enum e_gt {
  98. nogen, bytegen, wordgen, longgen, floatgen
  99. };
  100. enum e_sg {
  101. noseg, codeseg, dataseg
  102. };
  103. char *outlate();
  104. #ifndef NOFLOAT
  105. #ifdef PC
  106. unsigned long double2ffp();
  107. #else
  108. #define double2ffp(__x) (__x)
  109. #endif
  110. #endif
  111. void wrt2(short x);
  112. void set_label(int lab,unsigned int pos);
  113. unsigned int lab_src(int n);
  114. void put_label(int lab);
  115. void put_align2(void);
  116. enum(e_gt) gentype;
  117. enum(e_sg) curseg;
  118. int outcol;
  119. #define BIN_STEP 128
  120. void out_init() {
  121. // fputs("gtc_compiled:\n", output);
  122. curseg = noseg;
  123. gentype = nogen;
  124. outcol = 0;
  125. lc_stk = 0;
  126. odd = 0;
  127. extlabel = -1;
  128. glblabel = -32768;
  129. scope_head = 0;
  130. pos = 4;
  131. hashinit(&alsyms);
  132. reloc_tab.r = 0;
  133. bss_tab.r = 0;
  134. libsyms.tail = libsyms.head = 0;
  135. rom_funcs = 0;
  136. #ifdef RAM_CALLS
  137. ram_funcs = 0;
  138. #endif
  139. loc_tab = 0;
  140. glb_tab = 0;
  141. ext_tab = 0;
  142. nostub_mode = 0;
  143. #ifdef EXE_OUT
  144. exestub_mode = 0;
  145. #endif
  146. bin = malloc(bin_size = BIN_STEP);
  147. pos = 4;
  148. put_label(label("gtc_compiled"));
  149. #ifdef SIZE_STATS
  150. c_compiler_sz=0;
  151. #endif
  152. }
  153. char *unres_name(int lab) {
  154. SYM *ttail; int crc=N_HASH;;
  155. while (crc--) {
  156. ttail=alsyms.h[crc].tail;
  157. while (ttail) {
  158. if ((short)ttail->value.splab==(short)lab)
  159. return ttail->name;
  160. ttail = ttail->prev;
  161. }
  162. }
  163. return 0;
  164. }
  165. void scan_unresolved() {
  166. GTAB *t=glb_tab; int l=0x8000;
  167. while (t) {
  168. REF **r=t->r; int n;
  169. n=N_TAB;
  170. while (n--) {
  171. if (*r++)
  172. uerrc2("unresolved symbol '%s'",unres_name(l));
  173. l++;
  174. }
  175. t=t->nxt;
  176. }
  177. }
  178. int eval_rt(RTYPE *r) {
  179. int n=1;
  180. REF *p=r->r0,*q=r->r;
  181. while (p!=q)
  182. n+=N_REF,p=p->nxt;
  183. if (p) {
  184. unsigned int *a=p->r;
  185. while (*a++) n++;
  186. }
  187. return n;
  188. }
  189. unsigned int eval_functab(FUNC *f) {
  190. int n=1;
  191. while (f)
  192. n+=1+eval_rt(&f->rt),f=f->nxt;
  193. return n+n;
  194. }
  195. unsigned int eval_libs() {
  196. int n=2;
  197. SYM *sp=libsyms.head;
  198. while (sp)
  199. n+=10+eval_functab((FUNC *)sp->value.i),sp=sp->next;
  200. // return 2;
  201. return n;
  202. }
  203. unsigned int eval_export() {
  204. int i=N_TAB,n=i;
  205. int *a;
  206. if (!exp_tab)
  207. return 0;
  208. a=exp_tab->t;
  209. while (i--)
  210. if (*a++) n=i;
  211. return (1+N_TAB-n)<<1;
  212. }
  213. #ifdef PC
  214. xstatic unsigned char *hdr CGLOB,*hdrp CGLOB;
  215. #else
  216. xstatic unsigned short *hdr CGLOB,*hdrp CGLOB;
  217. #endif
  218. xstatic short hshift CGLOB;
  219. #ifdef PC
  220. void _wri(unsigned short x) {
  221. unsigned char hi=(char)(x>>8),lo=(char)x;
  222. *hdrp++=hi;
  223. *hdrp++=lo;
  224. }
  225. void _ovwri(unsigned int i,unsigned short x) {
  226. unsigned char hi=(char)(x>>8),lo=(char)x;
  227. if (i&1) fatal("ODD OVWRI");
  228. hdr[i+0]=hi;
  229. hdr[i+1]=lo;
  230. }
  231. void _orwri(unsigned int i,unsigned short x) {
  232. unsigned char hi=(char)(x>>8),lo=(char)x;
  233. if (i&1) fatal("ODD ORWRI");
  234. hdr[i+0]|=hi;
  235. hdr[i+1]|=lo;
  236. }
  237. #define wri(x) (_wri((unsigned short)(x)))
  238. #define ovwri(i,x) (_ovwri(i,(unsigned short)(x)))
  239. #define orwri(i,x) (_orwri(i,(unsigned short)(x)))
  240. #else
  241. #define wri(x) (*hdrp++=x)
  242. #define ovwri(i,x) (*(unsigned short *)((char *)hdr+i)=x)
  243. #define orwri(i,x) (*(unsigned short *)((char *)hdr+i)|=x)
  244. #endif
  245. void write_rt(RTYPE *r) {
  246. REF *p=r->r0;
  247. while (p) {
  248. unsigned int x,*a=p->r; int n;
  249. if ((p=p->nxt)) {
  250. n=N_REF; while (n--) wri((*a++)+hshift);
  251. } else
  252. while ((x=*a++)) wri(x+hshift);
  253. }
  254. wri(0);
  255. }
  256. void write_reloc(
  257. #ifdef OBJ_OUT
  258. int directly_to_bin
  259. #else
  260. #define directly_to_bin 0
  261. #endif
  262. ) {
  263. RTYPE *r=&reloc_tab;
  264. REF *p=r->r0;
  265. while (p) {
  266. unsigned int x,*a=p->r; int n;
  267. if ((p=p->nxt)) {
  268. n=N_REF; while (n--) {
  269. x=*a++;
  270. directly_to_bin?wrt2(x+hshift+2):wri(x+hshift);
  271. #ifdef PC
  272. { short a=bin[x+2]<<8;
  273. a+=bin[x+3]+hshift; /* logically, shouldn't overflow... */
  274. bin[x+2]=(unsigned char)(a>>8);
  275. bin[x+3]=(unsigned char)(a);
  276. }
  277. #else
  278. *(long *)(bin+x)+=hshift;
  279. #endif
  280. }
  281. } else
  282. while ((x=*a++)) {
  283. #ifdef PC
  284. { short a=bin[x+2]<<8;
  285. a+=bin[x+3]+hshift; /* logically, shouldn't overflow... */
  286. bin[x+2]=(unsigned char)(a>>8);
  287. bin[x+3]=(unsigned char)(a);
  288. }
  289. #else
  290. *(long *)(bin+x)+=hshift;
  291. #endif
  292. directly_to_bin?wrt2(x+hshift+2):wri(x+hshift);
  293. }
  294. }
  295. directly_to_bin?wrt2(0):wri(0);
  296. }
  297. #undef directly_to_bin
  298. void write_functab(FUNC *f0) {
  299. int n=0; FUNC *f=f0;
  300. while (f)
  301. n++,f=f->nxt;
  302. wri(n-1);
  303. f=f0;
  304. while (f)
  305. wri(f->f),write_rt(&f->rt),f=f->nxt;
  306. }
  307. void write_libs() {
  308. int n=0;
  309. SYM *sp=libsyms.head;
  310. // wri(0); return;
  311. while (sp)
  312. n++,sp=sp->next;
  313. wri(n);
  314. sp=libsyms.head;
  315. while (sp) {
  316. memset(hdrp,0,8);
  317. strcpy((char *)hdrp,sp->name);
  318. hdrp+=8/sizeof(*hdrp);
  319. wri(0);
  320. sp=sp->next;
  321. }
  322. sp=libsyms.head;
  323. while (sp)
  324. write_functab((FUNC *)sp->value.i),sp=sp->next;
  325. }
  326. unsigned int qlab_src(int n);
  327. void write_export(unsigned int l) {
  328. int *a=exp_tab->t,x;
  329. l=(l>>1)-1;
  330. wri((short)l);
  331. while (l--) {
  332. if ((x=*a++))
  333. x=qlab_src(x)+hshift;
  334. wri(x);
  335. }
  336. }
  337. #ifdef EXE_OUT
  338. typedef struct {
  339. short t; // type
  340. unsigned short loc; // location, offset based on relocated output
  341. } EXE_ITEM;
  342. int
  343. #ifdef PC
  344. #ifdef _MSC_VER
  345. __cdecl
  346. #endif
  347. #else
  348. CALLBACK
  349. #endif
  350. exe_compare(const void *a,const void *b) {
  351. return ((EXE_ITEM *)a)->loc-((EXE_ITEM *)b)->loc;
  352. }
  353. void *GTPackDo(void *buf,unsigned int *buflen);
  354. #include "out68k_exe.h"
  355. #endif
  356. readonly char pgm_init[0x1A]={0x61,0,0,0,'6','8','k','P'};
  357. readonly char lib_init[0x1A]={0x4E,0x75,0x4E,0x75,'6','8','k','L'};
  358. readonly char pgm_stub[0xA]={0x2F,0x38,0x00,0x34,0x66,0x02,0x50,(char)0x8F,0x4E,0x75};
  359. void wrt2(short x);
  360. void wrt1(char x);
  361. void out_close() {
  362. #ifdef PC
  363. int calctype_used[]={0,0,0};
  364. char *calc_symbols[]={"USE_TI89","USE_TI92PLUS","USE_V200"};
  365. int calc,specific=1,something;
  366. for (something=0;!something;specific=0)
  367. for (calc=0;calc<3;calc++)
  368. if (!specific || search(calc_symbols[calc],-1,&defsyms))
  369. calctype_used[calc]++,something++;
  370. #endif
  371. if (bin) {
  372. /*
  373. * 0x1A+(2+10*nLibs+2*(nLibs+nLibCalls+nLibFuncs))+(2+2+2*(nRomFuncs+nRomCalls))
  374. * +2+2+(4+nBSS*2)+(2+nExport*2)
  375. * +0xA+(nReloc+1)*2
  376. * =
  377. * 0x1A+(2+10*nLibs+nLibs(eval(Lib)))+(2+eval(rom))
  378. * +2+2+(4+nBSS*2)+(2+nExport*2)
  379. * +0xA+eval_rt(reloc_tab)*2
  380. * =
  381. * 0x1A+(2+eval_libs())+(2+eval(rom))
  382. * +2+2+(4+nBSS*2)+(2+nExport*2)
  383. * +0xA+eval_rt(reloc_tab)*2
  384. */
  385. SYM *mainsym;
  386. unsigned int rom=eval_functab(rom_funcs)-2,lib=eval_export();
  387. #ifdef RAM_CALLS
  388. unsigned int ram=eval_functab(ram_funcs)-2;
  389. #else
  390. #define ram 0
  391. #endif
  392. #ifdef OBJ_OUT
  393. int object=!!search("_GENERIC_ARCHIVE",-1,&defsyms);
  394. if (!object) {
  395. #endif
  396. int nostub=search("_nostub",-1,&alsyms) || search("_nostub",-1,&gsyms)
  397. || search("_nostub",-1,&defsyms) || nostub_mode;
  398. #ifdef EXE_OUT
  399. int exestub=!!search("EXE_OUT",-1,&defsyms);
  400. if (exestub) nostub=0;
  401. #else
  402. #define exestub 0
  403. #endif
  404. debug('+');
  405. if (nostub) {
  406. if (ram || rom) fatal("RAM/ROM_CALL in _nostub");
  407. if (libsyms.head) fatal("Libraries in _nostub");
  408. if (bss_tab.r) fatal("BSS in _nostub");
  409. hshift=0;
  410. #ifdef EXE_OUT
  411. } else if (exestub) {
  412. if (ram) fatal("RAM_CALL in EXE format");
  413. if (libsyms.head) fatal("Libraries in exe format");
  414. #endif
  415. } else {
  416. hdrp=hdr=malloc((hshift=0x1A-4+(eval_libs())+(rom?rom+4:2)
  417. +(ram?ram+4:2)+(eval_rt(&reloc_tab)<<1)+(bss_tab.r?4+(eval_rt(&bss_tab)<<1):0)
  418. +(lib)+(lib?0:0xA))+4);
  419. if (!hdr)
  420. fatal("memory");
  421. memcpy(hdr,lib?lib_init:pgm_init,0x1A);
  422. hdrp+=0x1A/sizeof(*hdrp);
  423. write_libs(); // import table
  424. wri(rom); // ROM table
  425. if (rom) write_functab(rom_funcs);
  426. #ifdef RAM_CALLS
  427. wri(ram); // RAM table
  428. if (ram) write_functab(ram_funcs);
  429. #else
  430. wri(0); // no RAM table
  431. #endif
  432. #ifdef OBJ_OUT
  433. write_reloc(0); // reloc table
  434. #else
  435. write_reloc(); // reloc table
  436. #endif
  437. if (bss_tab.r) {
  438. ovwri(0x14,(char *)hdrp-(char *)hdr); // BSS table
  439. wri(lc_bss>>16),wri(lc_bss);
  440. write_rt(&bss_tab);
  441. }
  442. if (lib) {
  443. ovwri(0x16,(char *)hdrp-(char *)hdr); // export table
  444. write_export(lib);
  445. }
  446. if (!lib) {
  447. ovwri(0x02,(char *)hdrp-(char *)hdr-2); // stub
  448. memcpy(hdrp,pgm_stub,0xA);
  449. hdrp+=0xA/sizeof(*hdrp);
  450. }
  451. #ifdef PC
  452. if (hdrp!=hdr+(hshift+4)/sizeof(*hdrp))
  453. ierr(LINK_MISPL,1);
  454. #endif
  455. /* link with file */
  456. if ((mainsym=search("VERSION",-1,&defsyms))) {
  457. ovwri(0x10,1<<8);
  458. }
  459. }
  460. mainsym=NULL;
  461. if (!lib && ((!nostub && !exestub) || !search("NO_MAIN",-1,&defsyms))) {
  462. if (!(mainsym=search("_main",-1,&alsyms)) && !(mainsym=search("__main",-1,&alsyms)))
  463. fatal("_main not found");
  464. if (!nostub && !exestub) {
  465. ovwri(0x0C,qlab_src(mainsym->value.splab)+hshift);
  466. if (!!search("NO_SCREEN",-1,&defsyms))
  467. orwri(0x10,(1<<2));
  468. }
  469. }
  470. scan_unresolved();
  471. /* finally, write the output to the file */
  472. if (nostub) {
  473. if (!mainsym)
  474. memmove(bin,bin+4,pos-4),pos-=4,hshift=-4;
  475. else {
  476. #ifdef PC
  477. bin[0]=0x60,bin[1]=0x00;
  478. bin[2]=(unsigned char)((qlab_src(mainsym->value.splab)-2)>>8);
  479. bin[3]=(unsigned char)((qlab_src(mainsym->value.splab)-2));
  480. #else
  481. *(short *)bin=0x6000;
  482. *(short *)(bin+2)=qlab_src(mainsym->value.splab)-2;
  483. #endif
  484. hshift=0;
  485. }
  486. put_align2();
  487. wrt2(0);
  488. {
  489. RTYPE *r=&reloc_tab;
  490. REF *p=r->r0;
  491. while (p) {
  492. unsigned int x,*a=p->r; int n;
  493. if ((p=p->nxt)) {
  494. n=N_REF; while (n--) {
  495. #ifdef PC
  496. { short z=bin[(x=*a++)+2+hshift]<<8;
  497. z+=bin[x+3+hshift]+hshift;
  498. wrt2(z);
  499. }
  500. #else
  501. wrt2(*(unsigned short *)(bin+(x=*a++)+2+hshift)+hshift);
  502. #endif
  503. if (*(unsigned short *)(bin+x+hshift)!=0)
  504. uerrc("invalid _nostub relocation");
  505. *(unsigned short *)(bin+x+2+hshift)=0;
  506. wrt2((unsigned short)(x+hshift));
  507. }
  508. } else
  509. while ((x=*a++)) {
  510. #ifdef PC
  511. { short z=bin[x+2+hshift]<<8;
  512. z+=bin[x+3+hshift]+hshift;
  513. wrt2(z);
  514. }
  515. #else
  516. wrt2(*(unsigned short *)(bin+x+2+hshift)+hshift);
  517. #endif
  518. if (*(unsigned short *)(bin+x+hshift)!=0)
  519. uerrc("invalid _nostub relocation");
  520. *(unsigned short *)(bin+x+2+hshift)=0;
  521. wrt2((unsigned short)(x+hshift));
  522. }
  523. }
  524. }
  525. wrt1((char)0xF3);
  526. rel_global();
  527. #ifndef PC
  528. fwrite(bin,1,pos,output);
  529. #endif
  530. #ifdef EXE_OUT
  531. } else if (exestub) {
  532. #ifdef TWIN_COMPILE
  533. if (twinc_necessary) {
  534. rel_global();
  535. goto close_it; // don't lose time compressing...
  536. } else {
  537. #endif
  538. #define EXE_END -1
  539. #define EXE_PROGRELOC 0
  540. #define EXE_BSSRELOC 1
  541. #define EXE_ROMRELOC 2
  542. #define EXE_ROMRELOC_NOJSR (0x100|EXE_ROMRELOC)
  543. EXE_ITEM *exe_data=calloc(6000,sizeof(EXE_ITEM)); /* 12 kb */
  544. EXE_ITEM *exe_ptr=exe_data;
  545. int exe_num;
  546. if (!exe_data)
  547. fatal("Memory");
  548. memmove(bin,bin+4,pos-4),pos-=4;
  549. {
  550. RTYPE *r=&reloc_tab;
  551. REF *p=r->r0;
  552. while (p) {
  553. unsigned int x,*a=p->r; int n;
  554. if ((p=p->nxt)) {
  555. n=N_REF; while (n--) {
  556. exe_ptr->t=EXE_PROGRELOC;
  557. exe_ptr->loc=(*a++)-4;
  558. exe_ptr++;
  559. }
  560. } else
  561. while ((x=*a++)) {
  562. exe_ptr->t=EXE_PROGRELOC;
  563. exe_ptr->loc=x-4;
  564. exe_ptr++;
  565. }
  566. }
  567. }
  568. {
  569. FUNC *f=rom_funcs;
  570. while (f) {
  571. RTYPE *r=&f->rt;
  572. REF *p=r->r0;
  573. while (p) {
  574. unsigned int x,*a=p->r; int n;
  575. if ((p=p->nxt)) {
  576. n=N_REF; while (n--) {
  577. exe_ptr->t=EXE_ROMRELOC;
  578. exe_ptr->loc=(*a++)-4;
  579. if (*(long *)(bin+exe_ptr->loc))
  580. fatal("Invalid ROM_CALL");
  581. bin[exe_ptr->loc+2]=f->f>>8;
  582. bin[exe_ptr->loc+3]=f->f&255;
  583. if (bin[exe_ptr->loc-2]==0x4e
  584. && bin[exe_ptr->loc-1]==0xb9)
  585. exe_ptr->loc-=2;
  586. else bin[exe_ptr->loc+2]|=0x80,exe_ptr->t=EXE_ROMRELOC_NOJSR;
  587. exe_ptr++;
  588. }
  589. } else
  590. while ((x=*a++)) {
  591. exe_ptr->t=EXE_ROMRELOC;
  592. exe_ptr->loc=x-4;
  593. if (*(long *)(bin+exe_ptr->loc))
  594. fatal("Invalid ROM_CALL");
  595. bin[exe_ptr->loc+2]=f->f>>8;
  596. bin[exe_ptr->loc+3]=f->f&255;
  597. if (bin[exe_ptr->loc-2]==0x4e
  598. && bin[exe_ptr->loc-1]==0xb9)
  599. exe_ptr->loc-=2;
  600. else bin[exe_ptr->loc+2]|=0x80,exe_ptr->t=EXE_ROMRELOC_NOJSR;
  601. exe_ptr++;
  602. }
  603. }
  604. f=f->nxt;
  605. }
  606. }
  607. exe_ptr->t=-1; exe_ptr->loc=pos; exe_ptr++;
  608. exe_num=exe_ptr-exe_data;
  609. qsort(exe_data,exe_num,sizeof(EXE_ITEM),exe_compare);
  610. {
  611. long relocated_size;
  612. unsigned short last_pos=0; unsigned char *ptr=bin,*out=bin;
  613. char *reloc_ptr=(char *)exe_data,*last_esc=NULL;
  614. int last_esc_num=0;
  615. int i=exe_num; exe_ptr=exe_data;
  616. while (i--) {
  617. unsigned char *dest_ptr=bin+exe_ptr->loc;
  618. unsigned short delta; short type;
  619. #ifdef PC
  620. #define g16(p) (p+=2,(p[-2]<<8)+p[-1])
  621. #define rd16(p) ((p[0]<<8)+p[1])
  622. #define w16(p,v) (*p++=(v)>>8,*p++=(v)&255,(void)0)
  623. #else
  624. #define g16(p) (*((int *)p)++)
  625. #define rd16(p) (*((int *)p))
  626. #define w16(p,v) (g16(p)=(v))
  627. #endif
  628. while (ptr<dest_ptr) {
  629. /*if (ptr==&bin[0xaca])
  630. bkpt(); // [off_nr$9c] */
  631. w16(out,rd16(ptr));
  632. #ifndef OLD_LOADER_WITHOUT_BRANCHES
  633. if (!ptr[1] && (ptr[0]&0xF0)==0x60) {
  634. //printf(".");
  635. ptr+=2;
  636. goto relative_optimize;
  637. }
  638. #endif
  639. if ((g16(ptr)&63)==0x3A) {
  640. #ifndef OLD_LOADER_WITHOUT_BRANCHES
  641. relative_optimize:
  642. #endif
  643. if (ptr>=dest_ptr) break;
  644. w16(out,rd16(ptr)+((char *)ptr-(char *)bin));
  645. ptr+=2;
  646. }
  647. }
  648. delta=(exe_ptr->loc-last_pos)+2;
  649. last_pos=exe_ptr->loc;
  650. if ((delta&1))
  651. uerrc("invalid relocation offset");
  652. delta>>=1;
  653. switch ((type=exe_ptr->t)) { // we *NEED* to save exe_ptr->t as it will be lost
  654. case EXE_PROGRELOC:
  655. if (g16(ptr))
  656. uerrc("invalid _nostub relocation");
  657. w16(out,rd16(ptr)-4); // parameters to w16 can't have side-fx...
  658. ptr+=2;
  659. last_pos+=4;
  660. break;
  661. case EXE_ROMRELOC:
  662. ptr+=4;
  663. w16(out,rd16(ptr)); // parameters to w16 can't have side-fx...
  664. ptr+=2;
  665. last_pos+=6;
  666. break;
  667. case EXE_ROMRELOC_NOJSR:
  668. ptr+=2;
  669. w16(out,rd16(ptr)); // parameters to w16 can't have side-fx...
  670. ptr+=2;
  671. last_pos+=4;
  672. break;
  673. }
  674. if (delta<128)
  675. *reloc_ptr++=delta&255;
  676. else *reloc_ptr++=128|(delta>>8),*reloc_ptr++=delta&255;
  677. if (!last_esc_num--)
  678. last_esc=reloc_ptr,*reloc_ptr++=0,last_esc_num=3;
  679. if (type IS_INVALID) {
  680. *reloc_ptr++=0;
  681. break;
  682. }
  683. (*last_esc)|=type<<(last_esc_num<<1);
  684. exe_ptr++;
  685. }
  686. rel_global();
  687. exe_num=reloc_ptr-(char*)exe_data;
  688. *reloc_ptr=0; /* (same remark as below...) */
  689. reloc_ptr=realloc(exe_data,exe_num+1); /* we don't know if we will need padding... */
  690. relocated_size=pos;
  691. pos=out-bin;
  692. bin=realloc(bin,pos);
  693. #if 0
  694. {
  695. unsigned int i;
  696. for (i=0; i<pos; i++)
  697. printf("0x%x,\n",(int)bin[i]);
  698. }
  699. #endif
  700. bin=GTPackDo(bin,&pos);
  701. if (((exe_num+pos)&1)) exe_num++;
  702. { unsigned short loader_offset=(8-2)+12+pos+exe_num+(bss_tab.r?6:0)+6;
  703. char header[8];
  704. char exe_hdr[12]={0,1,0,0,0,0,0,0,0,0,0,0};
  705. if (loader_offset<=32767) {
  706. header[0]=0x60,header[1]=0x00;
  707. header[2]=loader_offset>>8,header[3]=loader_offset&255;
  708. *(long *)(header+4)=0;
  709. } else {
  710. #ifdef PC
  711. const unsigned char header32[8]=
  712. #else
  713. memcpy(header,(char[])
  714. #endif
  715. {0x41,0xFA,0x7F,0xF2,0x4E,0xE8,0x80,0x0C}
  716. #ifdef PC
  717. ; memcpy(header,header32, 8);
  718. #else
  719. , 8);
  720. #endif
  721. loader_offset+=(0x800C-2);
  722. header[6]=loader_offset>>8,header[7]=loader_offset&255;
  723. loader_offset-=(0x800C-2); // restore it for future use
  724. }
  725. bin=realloc(bin,8+12+pos+exe_num+(bss_tab.r?exeloadersize_bss:exeloadersize_nobss));
  726. if (!bin)
  727. fatal("Memory");
  728. memmove(bin+8+12,bin,pos);
  729. memcpy(bin,header,8);
  730. exe_hdr[2]=pos>>8,exe_hdr[3]=pos&255;
  731. exe_hdr[5]=(char)((relocated_size>>16)&255),
  732. exe_hdr[6]=(char)((relocated_size>>8)&255),
  733. exe_hdr[7]=(char)(relocated_size&255);
  734. if (bss_tab.r)
  735. fatal("BSS in exes are not implemented");
  736. memcpy(bin+8,exe_hdr,12);
  737. memcpy(bin+8+12+pos,reloc_ptr,exe_num);
  738. free(reloc_ptr);
  739. memcpy(bin+8+12+pos+exe_num,bss_tab.r?exeloader_bss:exeloader_nobss,
  740. bss_tab.r?exeloadersize_bss:exeloadersize_nobss);
  741. #ifdef PC
  742. if (verbose) {
  743. msg2("RAM required during execution : %5u bytes\n",(unsigned int)relocated_size);
  744. msg2("Memory required for EXE program : %5u bytes\n",8+12+pos+exe_num);
  745. msg2("Memory required for EXE loader : %5u bytes\n",bss_tab.r?exeloadersize_bss:exeloadersize_nobss);
  746. }
  747. #endif
  748. pos=8+12+pos+exe_num+(bss_tab.r?exeloadersize_bss:exeloadersize_nobss);
  749. bin[pos-3]=(loader_offset+22+2)>>8,bin[pos-2]=(loader_offset+22+2)&255;
  750. #ifdef PC
  751. if (verbose)
  752. msg2("Total program size : %5u bytes\n",pos);
  753. #endif
  754. }
  755. }
  756. #ifndef PC
  757. fwrite(bin,1,pos,output);
  758. #endif
  759. #ifdef TWIN_COMPILE
  760. }
  761. #endif
  762. #endif
  763. } else {
  764. rel_global();
  765. put_align2();
  766. wrt2(0);
  767. wrt1((char)0xF3);
  768. #ifdef PC
  769. if (!(bin=realloc(bin,bin_size+=hshift)))
  770. fatal("Memory");
  771. memmove(bin+hshift+4,bin+4,pos-4);
  772. memcpy(bin,hdr,hshift+4);
  773. pos+=hshift;
  774. #else
  775. fwrite(hdr,1,hshift+4,output);
  776. fwrite(bin+4,1,pos-4,output);
  777. #endif
  778. free(hdr);
  779. }
  780. #ifdef OBJ_OUT
  781. } else {
  782. unsigned int len;
  783. int j;
  784. if (pos&1)
  785. wrt1(0);
  786. len=pos-4;
  787. /* reloc table */
  788. hshift=-4;
  789. write_reloc(1);
  790. /* export table */
  791. j=N_HASH;
  792. while (j--) {
  793. SYM *sp = gsyms.h[j].head;
  794. while (sp) {
  795. if ((sp->storage_class == sc_external && sp->used) ||
  796. (sp->storage_class == sc_global && sp->value.splab)) {
  797. #ifdef PC
  798. if (!lab_src(sp->value.splab))
  799. fatal("UNDEF LABEL"); // should this happen ?
  800. #endif
  801. wrt2(lab_src(sp->value.splab)-2/*fix offset for object format*/);
  802. }
  803. sp = sp->next;
  804. }
  805. }
  806. wrt2(0);
  807. j=N_HASH;
  808. while (j--) {
  809. SYM *sp = gsyms.h[j].head;
  810. while (sp) {
  811. if ((sp->storage_class == sc_external && sp->used) ||
  812. (sp->storage_class == sc_global && sp->value.i != -1)) {
  813. char *s=sp->name;
  814. do
  815. wrt1(*s);
  816. while (*s++);
  817. }
  818. sp = sp->next;
  819. }
  820. }
  821. if (pos&1)
  822. wrt1(0);
  823. /* import table */
  824. {
  825. GTAB *t=glb_tab;
  826. while (t) {
  827. REF **r=t->r; int m=N_TAB;
  828. while (m--) {
  829. REF *q;
  830. if ((q=*r++)) {
  831. while (q) {
  832. unsigned int p,*a=q->r;
  833. int n=N_REF;
  834. while (n--) {
  835. if (!(p=*a++))
  836. goto ref_done;
  837. if (p&1)
  838. fatal("Negative reloc in object output");
  839. // warning, this is a 16-bit reloc, but we have to store it as a 32-bit one
  840. #define offs_convert(p) (p-2/*since 16->32 bit*/-4/*convert bin[] offsets to final object offsets*/)
  841. if (!offs_convert(p))
  842. fatal("Word reloc at beginning");
  843. wrt2(offs_convert(p));
  844. #undef offs_convert
  845. }
  846. q=q->nxt;
  847. }
  848. ref_done:
  849. wrt2(0);
  850. }
  851. }
  852. t=t->nxt;
  853. }
  854. }
  855. wrt2(0);
  856. {
  857. GTAB *t=glb_tab; int l=0x8000;
  858. while (t) {
  859. REF **r=t->r; int m=N_TAB;
  860. while (m--) {
  861. if (*r++) {
  862. char *s=unres_name(l);
  863. do
  864. wrt1(*s);
  865. while (*s++);
  866. }
  867. l++;
  868. }
  869. t=t->nxt;
  870. }
  871. }
  872. if (pos&1)
  873. wrt1(0);
  874. wrt2(0); // leave space for future BSS extension
  875. hdr=bin; // hack pawa =)
  876. ovwri(0x0,pos-4);
  877. ovwri(0x2,len+2);
  878. #ifndef PC
  879. wrt1(0);
  880. wrt1('E');
  881. wrt1('X');
  882. wrt1('T');
  883. wrt1(0);
  884. wrt1(0xF8);
  885. fwrite(bin,1,pos,output);
  886. #endif
  887. }
  888. #endif
  889. #ifdef PC
  890. {
  891. #ifdef OBJ_OUT
  892. if (!object) {
  893. #endif
  894. char *extensions[]={".89z",".9xz",".v2z"};
  895. for (calc=0;calc<3;calc++) {
  896. if (calctype_used[calc]) {
  897. unsigned int tifilelen;
  898. extern char *calcfolder;
  899. char *tifile=create_ti_file(calc,0x21,calcname,calcfolder,bin,pos,&tifilelen);
  900. char *buffer; FILE *fp;
  901. buffer=alloca(strlen(outputname)+strlen(extensions[calc])+1);
  902. strcpy(buffer,outputname);
  903. strcat(buffer,extensions[calc]);
  904. if (!(fp=fopen(buffer,"wb")))
  905. fatal("Could not open output file.");
  906. fwrite(tifile,1,tifilelen,fp);
  907. free(tifile);
  908. fclose(fp);
  909. }
  910. }
  911. #ifdef OBJ_OUT
  912. } else {
  913. char buffer[100]; FILE *fp;
  914. strcpy(buffer,calcname);
  915. strcat(buffer,".ext");
  916. if (!(fp=fopen(buffer,"wb")))
  917. fatal("Could not open output file.");
  918. fwrite(bin,1,pos,fp);
  919. fclose(fp);
  920. }
  921. #endif
  922. }
  923. #endif
  924. #ifdef TWIN_COMPILE
  925. close_it:
  926. #endif
  927. free(bin);
  928. bin=0;
  929. }
  930. }
  931. void bin_chk(unsigned int pos) {
  932. while (bin_size<pos)
  933. if (!(bin=realloc(bin,bin_size+=BIN_STEP)))
  934. fatal("Memory");
  935. }
  936. void lab_set(int n,unsigned int v) {
  937. int i=(n&0x7FFF)>>N_TAB_LOG;
  938. LTAB *p=local(n)?loc_tab:(LTAB *)glb_tab,*o;
  939. debugf("lab_set(%x,%x)\n",n,v);
  940. global_flag+=n&0x8000;
  941. if (!p) {
  942. if (local(n))
  943. loc_tab=p=(LTAB *)xalloc(sizeof(LTAB),_TAB);
  944. else glb_tab=(GTAB *)(p=(LTAB *)xalloc(sizeof(GTAB),_TAB));
  945. }
  946. while (i--)
  947. if (!(p=(o=p)->nxt))
  948. o->nxt=p=(LTAB *)xalloc(local(n)?sizeof(LTAB):sizeof(GTAB),_TAB);
  949. global_flag&=0x7FFF;
  950. #ifndef PC
  951. n&=N_TAB-1;
  952. p->t[n]=v;
  953. #else
  954. i=n&(N_TAB-1);
  955. p->t[i]=v;
  956. #endif
  957. }
  958. #ifdef PC
  959. /* that's what we use if we want the storage to be persistent, even if we call it from a
  960. * temp_mem location
  961. */
  962. void *xallocnt(int s,int m) {
  963. void *p;
  964. temp_local++;
  965. p=xalloc(s,m);
  966. temp_local--;
  967. return p;
  968. }
  969. /* xallocnt in global mode */
  970. void *xallocntg(int s,int m) {
  971. void *p;
  972. global_flag++;
  973. p=xallocnt(s,m);
  974. global_flag--;
  975. return p;
  976. }
  977. #else
  978. #define xallocnt(s,m) _xallocnt(s)
  979. void *_xallocnt(int s) {
  980. void *p;
  981. temp_local++;
  982. p=xalloc(s,0);
  983. temp_local--;
  984. return p;
  985. }
  986. #define xallocntg(s,m) _xallocnt(s)
  987. void *_xallocntg(int s) {
  988. void *p;
  989. global_flag++;
  990. p=xallocnt(s,0);
  991. global_flag--;
  992. return p;
  993. }
  994. #endif
  995. unsigned int lab_src(int n) {
  996. int i=(n&0x7FFF)>>N_TAB_LOG;
  997. LTAB *p=local(n)?loc_tab:(LTAB *)glb_tab,*o;
  998. debugfq("lab_src(%x)",n);
  999. global_flag+=n&0x8000;
  1000. if (!p) {
  1001. if (local(n))
  1002. loc_tab=p=(LTAB *)xallocnt(sizeof(LTAB),_TAB);
  1003. else glb_tab=(GTAB *)(p=(LTAB *)xallocntg(sizeof(GTAB),_TAB));
  1004. }
  1005. while (i--)
  1006. if (!(p=(o=p)->nxt))
  1007. o->nxt=p=(LTAB *)(local(n)?xallocnt(sizeof(LTAB),_TAB):xallocntg(sizeof(GTAB),_TAB));
  1008. global_flag&=0x7FFF;
  1009. n&=N_TAB-1;
  1010. debugf("=%x\n",p->t[n]);
  1011. return p->t[n];
  1012. }
  1013. RTYPE **xt_find(int n) {
  1014. int i=(n=(int)((short)~n))>>N_TAB_LOG;
  1015. XTAB *p=ext_tab,*o;
  1016. global_flag++;
  1017. if (!p)
  1018. ext_tab=p=(XTAB *)xalloc(sizeof(XTAB),_TAB);
  1019. while (i--)
  1020. if (!(p=(o=p)->nxt))
  1021. o->nxt=p=(XTAB *)xalloc(sizeof(XTAB),_TAB);
  1022. global_flag--;
  1023. n&=N_TAB-1;
  1024. return &p->t[n];
  1025. }
  1026. int *exp_find(int n) {
  1027. int i=n>>N_TAB_LOG;
  1028. LTAB *p=exp_tab,*o;
  1029. global_flag++;
  1030. if (!p)
  1031. exp_tab=p=(LTAB *)xalloc(sizeof(LTAB),_TAB);
  1032. while (i--)
  1033. if (!(p=(o=p)->nxt))
  1034. o->nxt=p=(LTAB *)xalloc(sizeof(LTAB),_TAB);
  1035. global_flag--;
  1036. n&=N_TAB-1;
  1037. return (int *)&p->t[n];
  1038. }
  1039. /*void loc_clear() {
  1040. LTAB *p=loc_tab,*o;
  1041. while (p) {
  1042. memset(p->t,0,sizeof(p->t));
  1043. p=p->nxt;
  1044. }
  1045. }*/
  1046. unsigned int qlab_src(int n) {
  1047. int i=(n&0x7FFF)>>N_TAB_LOG;
  1048. LTAB *p=local(n)?loc_tab:(LTAB *)glb_tab;
  1049. n&=N_TAB-1;
  1050. while (i--) p=p->nxt;
  1051. return p->t[n];
  1052. }
  1053. REF *ref_add(REF *r,unsigned int v) {
  1054. unsigned int *a;
  1055. debugf("ref_add(%lx,%x)\n",r,v);
  1056. a=r->r;
  1057. while (*a++);
  1058. if (a>(unsigned int *)&r->nxt) {
  1059. global_flag++;
  1060. (r=r->nxt=(REF *)xalloc(sizeof(REF),_REF+REF_ADD))->r[0]=v;
  1061. global_flag--;
  1062. } else a[-1]=v;
  1063. return r;
  1064. }
  1065. REF **glb_ref(int n) {
  1066. int i=(n&0x7FFF)>>N_TAB_LOG;
  1067. GTAB *p=glb_tab;
  1068. n&=N_TAB-1;
  1069. while (i--)
  1070. p=p->nxt;
  1071. return &p->r[n];
  1072. }
  1073. void lab_add_ref(int n,unsigned int r) {
  1074. int i=(n&0x7FFF)>>N_TAB_LOG;
  1075. GTAB *p=glb_tab; REF **ro;
  1076. debugf("lab_add_r(%x,%x)\n",n,r);
  1077. #ifndef PC
  1078. // asm("0: jbra 0b");
  1079. #endif
  1080. if (local(n))
  1081. uerrc2("local label not found: '%s'",unres_name(n));
  1082. global_flag++;
  1083. n&=N_TAB-1;
  1084. while (i--)
  1085. p=p->nxt;
  1086. ro=&p->r[n];
  1087. if (!*ro)
  1088. *ro=(REF *)xalloc(sizeof(REF),_REF+LAB_ADD_REF);
  1089. while ((*ro)->nxt)
  1090. ro=&(*ro)->nxt;
  1091. global_flag--;
  1092. ref_add(*ro,r);
  1093. }
  1094. void rt_add_ref(RTYPE *rt,unsigned int r) { // effectively appends reloc to reloc table
  1095. debugf("rt_add_r(%lx,%x)\n",rt,r);
  1096. if (!rt->r) {
  1097. global_flag++;
  1098. rt->r0=rt->r=(REF *)xalloc(sizeof(REF),_REF+RT_ADD_REF);
  1099. global_flag--;
  1100. }
  1101. rt->r=ref_add(rt->r,r);
  1102. }
  1103. FUNC *func_search(FUNC **f0,unsigned int f) {
  1104. while (*f0)
  1105. if ((*f0)->f==f) break;
  1106. else f0=&(*f0)->nxt;
  1107. if (*f0) return *f0;
  1108. global_flag++;
  1109. *f0=(FUNC *)xalloc(sizeof(FUNC),_RT);
  1110. global_flag--;
  1111. (*f0)->f=f;
  1112. return *f0;
  1113. }
  1114. typedef struct gv_ret {
  1115. long i;
  1116. int ir,xr,tr; // Internal/eXternal/Total Relocation count
  1117. } GV;
  1118. int get_value(struct enode *ep,GV *r,unsigned int rp,int m) {
  1119. int lab; unsigned int p;
  1120. r->ir=0; r->xr=0;
  1121. gv_restart:
  1122. switch (ep->nodetype) {
  1123. case en_autocon:
  1124. case en_icon:
  1125. #ifndef NOFLOAT
  1126. #ifndef PC
  1127. case en_fcon:
  1128. #endif
  1129. #endif
  1130. r->i=ep->v.i;
  1131. r->tr=0;
  1132. break;
  1133. #ifndef NOFLOAT
  1134. #ifdef PC
  1135. #ifndef BCDFLT
  1136. case en_fcon:
  1137. r->i=double2ffp(ep->v.f);
  1138. r->tr=0;
  1139. break;
  1140. #endif
  1141. #endif
  1142. #endif
  1143. case en_labcon:
  1144. case en_nacon:
  1145. lab=ep->v.enlab;
  1146. r->tr=1;
  1147. if (global(lab)) {
  1148. r->ir=1;
  1149. if (!(p=lab_src(lab))) {
  1150. if (rp)
  1151. lab_add_ref(lab,(rp+2)+m);
  1152. r->i=0;
  1153. return 1;
  1154. } else
  1155. r->i=p;
  1156. } else {
  1157. if (m) uerrc("negative external reference");
  1158. r->i=0,r->xr=1;
  1159. if (rp) {
  1160. RTYPE *rt=*xt_find(lab);
  1161. if (((long)rt)&0x80000000) { // DIRTY, but no hidden bug possible (cf xalloc)
  1162. r->i=((long)rt)&0x7FFFFFFF; // BSS ref
  1163. rt_add_ref(&bss_tab,rp);
  1164. } else rt_add_ref(rt,rp); // lib/ROM ref
  1165. }
  1166. return 1;
  1167. }
  1168. break;
  1169. case en_add:
  1170. case en_sub:
  1171. {
  1172. GV a,b;
  1173. int res=get_value(ep->v.p[0],&a,rp,m);
  1174. res|=get_value(ep->v.p[1],&b,rp,ep->nodetype==en_sub?1-m:m);
  1175. r->xr=a.xr+b.xr;
  1176. r->tr=a.tr+b.tr;
  1177. if (ep->nodetype==en_sub) {
  1178. if (b.xr)
  1179. uerrc("negative external reference");
  1180. r->i=a.i-b.i,r->ir=a.ir-b.ir;
  1181. } else
  1182. r->i=a.i+b.i,r->ir=a.ir+b.ir;
  1183. return res;
  1184. }
  1185. break;
  1186. case en_uminus:
  1187. m=1-m;
  1188. ep=ep->v.p[0];
  1189. goto gv_restart;
  1190. default:
  1191. uerrc("invalid expression");
  1192. }
  1193. return 0;
  1194. }
  1195. int involved_lab(struct enode *ep) {
  1196. gv_restart:
  1197. switch (ep->nodetype) {
  1198. case en_autocon:
  1199. case en_icon:
  1200. #ifndef NOFLOAT
  1201. #ifdef PC
  1202. case en_fcon:
  1203. #endif
  1204. #endif
  1205. return -1;
  1206. case en_labcon:
  1207. case en_nacon:
  1208. return ep->v.enlab;
  1209. case en_add:
  1210. case en_sub:
  1211. return max(involved_lab(ep->v.p[0]),involved_lab(ep->v.p[1]));
  1212. case en_uminus:
  1213. ep=ep->v.p[0];
  1214. goto gv_restart;
  1215. default:
  1216. uerrc("invalid expression");
  1217. }
  1218. return -1;
  1219. }
  1220. xstatic int rel CGLOB, is_long CGLOB;
  1221. long get_long(struct enode *ep,unsigned int rp) {
  1222. GV v;
  1223. get_value(ep,&v,rp,0);
  1224. if (v.ir) {
  1225. rt_add_ref(&reloc_tab,rp);
  1226. if (v.ir!=1)
  1227. uerr(ERRA_INVALIDREL);
  1228. }
  1229. rel=v.ir+v.xr;
  1230. return v.i;
  1231. }
  1232. short get_pcword(struct enode *ep,unsigned int rp) {
  1233. GV v;
  1234. int no_check=get_value(ep,&v,rp-2,0);
  1235. if (v.ir!=1 || v.xr)
  1236. uerr(ERRA_INVALIDREL);
  1237. if (!no_check) {
  1238. v.i -= rp;
  1239. if (v.i>32767L || v.i<-32768L)
  1240. #ifdef TWIN_COMPILE
  1241. {
  1242. if (!twinc_necessary) uwarn("twin compilation required");
  1243. twinc_necessary=1;
  1244. *twinc_info++=involved_lab(ep);
  1245. *twinc_info++=rp;
  1246. }
  1247. #else
  1248. uerrc("PC-relative mode not allowed here");
  1249. #endif
  1250. // v.i += rp;
  1251. return (short)v.i;
  1252. } else
  1253. return (short)v.i-(short)rp;
  1254. }
  1255. short get_word(struct enode *ep,unsigned int rp,int sign) {
  1256. GV v;
  1257. int no_check=get_value(ep,&v,rp-2,0);
  1258. if (v.ir || v.xr)
  1259. uerr(ERRA_INVALIDREL);
  1260. /* otherwise this would bug with myval&0xFFFF7FFF which is converted to and.w */
  1261. if (!no_check && (v.i>(sign?32767L:65535L) || v.i<(sign?-32768L:-65535L)))
  1262. // if (!no_check && (v.i>(sign?32767L:65535L) || v.i<-32768L))
  1263. uerrc("value can't fit in a word");
  1264. return (short)v.i;
  1265. }
  1266. long get_offs(struct enode *ep,unsigned int rp) {
  1267. GV v; int l=0;
  1268. get_value(ep,&v,0,0);
  1269. if (v.ir || v.xr)
  1270. l=1;
  1271. if (v.i>32767L || v.i<-32768L)
  1272. l=1;
  1273. if ((is_long=l))
  1274. return get_long(ep,rp);
  1275. else return get_word(ep,rp,1);
  1276. }
  1277. unsigned char get_byte(struct enode *ep) {
  1278. GV v;
  1279. get_value(ep,&v,0,0);
  1280. if (v.tr)
  1281. uerr(ERRA_INVALIDREL);
  1282. if ((unsigned long)(((unsigned long)v.i)+128)>255)
  1283. uerrc("value can't fit in a byte");
  1284. return (unsigned char)v.i;
  1285. }
  1286. unsigned short get_quick(struct enode *ep) {
  1287. GV v;
  1288. get_value(ep,&v,0,0);
  1289. if (v.tr)
  1290. uerr(ERRA_INVALIDREL);
  1291. if ((unsigned long)(((unsigned long)v.i)-1)>=8)
  1292. uerrc("value can't fit in a quick constant");
  1293. if (v.i==8)
  1294. v.i=0;
  1295. return (unsigned short)v.i;
  1296. }
  1297. enum {
  1298. oi_move=1,
  1299. oi_moveq=oi_move+8,
  1300. oi_clr=oi_moveq+1,
  1301. oi_lea=oi_clr+1,
  1302. oi_add=oi_lea+1,
  1303. oi_addi=oi_add+4,
  1304. oi_addq=oi_addi+1,
  1305. oi_sub=oi_addq+1,
  1306. oi_subi=oi_sub+4,
  1307. oi_subq=oi_subi+1,
  1308. oi_muls=oi_subq+1,
  1309. oi_mulu=oi_muls+1,
  1310. oi_divs=oi_mulu+1,
  1311. oi_divu=oi_divs+1,
  1312. oi_and=oi_divu+1,
  1313. oi_andi=oi_and+3,
  1314. oi_or=oi_andi+1,
  1315. oi_ori=oi_or+3,
  1316. oi_eor=oi_ori+1,
  1317. oi_eori=oi_eor+2,
  1318. oi_lsl=oi_eori+1,
  1319. oi_lsr=oi_lsl+3,
  1320. oi_jmp=oi_lsr+3,
  1321. oi_jsr=oi_jmp+1,
  1322. oi_movem=oi_jsr+1,
  1323. oi_rts=oi_movem+3,
  1324. oi_bra=oi_rts+1,
  1325. oi_bsr=oi_bra+1,
  1326. oi_beq=oi_bsr+1,
  1327. oi_bne=oi_beq+1,
  1328. oi_bhs=oi_bne+1,
  1329. oi_bge=oi_bhs+1,
  1330. oi_bhi=oi_bge+1,
  1331. oi_bgt=oi_bhi+1,
  1332. oi_bls=oi_bgt+1,
  1333. oi_ble=oi_bls+1,
  1334. oi_blo=oi_ble+1,
  1335. oi_blt=oi_blo+1,
  1336. oi_tst=oi_blt+1,
  1337. oi_ext=oi_tst+1,
  1338. oi_swap=oi_ext+1,
  1339. oi_neg=oi_swap+1,
  1340. oi_not=oi_neg+1,
  1341. oi_cmp=oi_not+1,
  1342. oi_link=oi_cmp+5,
  1343. oi_unlk=oi_link+1,
  1344. oi_label=oi_unlk+1,
  1345. oi_pea=oi_label+0,
  1346. oi_cmpi=oi_pea+1,
  1347. oi_dbra=oi_cmpi+1,
  1348. oi_asr=oi_dbra+1,
  1349. oi_bset=oi_asr+3,
  1350. oi_bclr=oi_bset+4,
  1351. oi_bchg=oi_bclr+4,
  1352. _oi_asm=oi_bchg+4,
  1353. _oi_adj=_oi_asm+0,
  1354. #ifndef ASM
  1355. __oi_end=_oi_adj+0
  1356. #endif
  1357. #ifdef ASM
  1358. /* ASM-only */
  1359. oi_asl=_oi_adj+0,
  1360. oi_rol=oi_asl+3,
  1361. oi_ror=oi_rol+3,
  1362. oi_roxl=oi_ror+3,
  1363. oi_roxr=oi_roxl+3,
  1364. oi_btst=oi_roxr+3,
  1365. oi_exg=oi_btst+4,
  1366. oi_dc=oi_exg+4,
  1367. oi_ds=oi_dc+1,
  1368. oi_dcb=oi_ds+1,
  1369. oi_bvs=oi_dcb+1,
  1370. oi_bvc=oi_bvs+1,
  1371. oi_bpl=oi_bvc+1,
  1372. oi_bmi=oi_bpl+1,
  1373. oi_trap=oi_bmi+1,
  1374. oi_negx=oi_trap+1,
  1375. oi_addx=oi_negx+1,
  1376. oi_subx=oi_addx+2,
  1377. oi_chk=oi_subx+2,
  1378. oi_even=oi_chk+1,
  1379. oi_dbeq=oi_even+1,
  1380. oi_dbne=oi_dbeq+1,
  1381. #ifndef LIGHT_DBXX_AND_SXX
  1382. oi_dbhs=oi_dbne+1,
  1383. oi_dbge=oi_dbhs+1,
  1384. oi_dbhi=oi_dbge+1,
  1385. oi_dbgt=oi_dbhi+1,
  1386. oi_dbls=oi_dbgt+1,
  1387. oi_dble=oi_dbls+1,
  1388. oi_dblo=oi_dble+1,
  1389. oi_dblt=oi_dblo+1,
  1390. oi_dbvs=oi_dblt+1,
  1391. oi_dbvc=oi_dbvs+1,
  1392. oi_dbpl=oi_dbvc+1,
  1393. oi_dbmi=oi_dbpl+1,
  1394. oi_st=oi_dbmi+1,
  1395. oi_sf=oi_st+1,
  1396. oi_seq=oi_sf+1,
  1397. oi_sne=oi_seq+1,
  1398. oi_shs=oi_sne+1,
  1399. oi_sge=oi_shs+1,
  1400. oi_shi=oi_sge+1,
  1401. oi_sgt=oi_shi+1,
  1402. oi_sls=oi_sgt+1,
  1403. oi_sle=oi_sls+1,
  1404. oi_slo=oi_sle+1,
  1405. oi_slt=oi_slo+1,
  1406. oi_svs=oi_slt+1,
  1407. oi_svc=oi_svs+1,
  1408. oi_spl=oi_svc+1,
  1409. oi_smi=oi_spl+1,
  1410. oi_tas=oi_smi+1,
  1411. __oi_end=oi_tas+1
  1412. #else
  1413. __oi_end=oi_dbne+1
  1414. #endif
  1415. #endif
  1416. };
  1417. readonly unsigned char opi[_op_max+2]={
  1418. oi_move, oi_moveq, oi_clr, oi_lea, oi_add, oi_addi, oi_addq, oi_sub, oi_subi, oi_subq,
  1419. oi_muls, oi_mulu, oi_divs, oi_divu, oi_and, oi_andi, oi_or, oi_ori, oi_eor, oi_eori,
  1420. oi_lsl, oi_lsr, oi_jmp, oi_jsr, oi_movem,
  1421. oi_rts, oi_bra, oi_bsr, oi_beq, oi_bne, oi_bhs, oi_bge, oi_bhi,
  1422. oi_bgt, oi_bls, oi_ble, oi_blo, oi_blt, oi_tst, oi_ext, oi_swap, oi_neg, oi_not, oi_cmp,
  1423. oi_link, oi_unlk, oi_label, oi_pea, oi_cmpi, oi_dbra, oi_asr,
  1424. oi_bset, oi_bclr, oi_bchg, _oi_asm, _oi_adj,
  1425. #ifdef ASM
  1426. /* ASM-only */
  1427. oi_asl, oi_rol, oi_ror, oi_roxl, oi_roxr, oi_btst, oi_exg, oi_dc, oi_ds, oi_dcb,
  1428. oi_bvs, oi_bvc, oi_bpl, oi_bmi, oi_trap, oi_negx, oi_addx, oi_subx, oi_chk, oi_even,
  1429. oi_dbeq, oi_dbne,
  1430. #ifndef LIGHT_DBXX_AND_SXX
  1431. oi_dbhs, oi_dbge, oi_dbhi, oi_dbgt, oi_dbls, oi_dble, oi_dblo, oi_dblt,/* unsigned, signed */
  1432. oi_dbvs, oi_dbvc, oi_dbpl, oi_dbmi,
  1433. oi_st, oi_sf, oi_seq, oi_sne,
  1434. oi_shs, oi_sge, oi_shi, oi_sgt, oi_sls, oi_sle, oi_slo, oi_slt, /* unsigned, signed */
  1435. oi_svs, oi_svc, oi_spl, oi_smi, oi_tas,
  1436. #endif
  1437. #endif
  1438. __oi_end
  1439. };
  1440. typedef struct _opcode {
  1441. char impl,nargs,model,lenf;
  1442. unsigned short bo;
  1443. int a1,a2;
  1444. } OPCODE;
  1445. enum {
  1446. M_BASIC, M_BASICSWAPPED, M_BRANCH, M_DC, M_ALIGN
  1447. };
  1448. enum { L_0=1<<0, L_1=1<<1, L_2=1<<2, L_4=1<<4 };
  1449. enum {
  1450. A_DREG=0x1,
  1451. A_AREG=0x2,
  1452. A_MEM0=0x4,
  1453. A_MEM=0x84,
  1454. A_PCR=0x8,
  1455. A_IMM=0x10,
  1456. A_MASK1=0x20,
  1457. A_MASK2=0x40,
  1458. A_ADEC=0x80,
  1459. D_RAW2=0x0100, // |= %00000000 00000000 +WORD
  1460. D_RAW=0x0200, // |= %00000000 00000000 (+DAT)
  1461. D_LOW=0x0400, // |= %00000000 dddddddd
  1462. D_EA2=0x0800, // |= %0000nnnm mm000000 (+DAT)
  1463. D_SZ3=0x3000, // |= %00000000 0S000000 (argument-independent)
  1464. D_SZ2=0x1000, // |= %0000000S 00000000 (argument-independent)
  1465. D_SZ=0x2000, // |= %00000000 ss000000 (argument-independent)
  1466. D_Q=0x4000, // |= %0000qqq0 00000000
  1467. D_EA=0x8000, // |= %00000000 00mmmnnn (+DAT)
  1468. };
  1469. #define A_CCR A_MASK1
  1470. #define A_SR A_MASK2
  1471. #define A_USP A_MASK1
  1472. /* we have to implement A_CCR and A_SR like that to avoid the use
  1473. * of a longword for flags... */
  1474. #define A_SRC A_DREG|A_AREG|A_MEM|A_PCR|A_IMM
  1475. #define A_SRC2 A_DREG|A_MEM|A_PCR|A_IMM
  1476. #define A_DST A_DREG|A_AREG|A_MEM
  1477. #define A_DST2 A_DREG|A_MEM
  1478. // for each enum(e_op) value :
  1479. readonly OPCODE ops[]={
  1480. // op_label
  1481. {0},
  1482. // op_move
  1483. {1,2,M_BASIC,L_2,0x3000,A_SRC|D_EA,A_DST|D_EA2}, // movea is in fact the same instruction
  1484. {1,2,M_BASIC,L_4,0x2000,A_SRC|D_EA,A_DST|D_EA2},
  1485. {1,2,M_BASIC,L_1,0x1000,A_SRC2|D_EA,A_DST2|D_EA2}, // move.b does not accept aregs
  1486. {1,2,M_BASIC,L_2,0x44C0,A_SRC2|D_EA,A_CCR},
  1487. {1,2,M_BASIC,L_2,0x46C0,A_SRC2|D_EA,A_SR},
  1488. {1,2,M_BASIC,L_2,0x40C0,A_SR,A_DST2|D_EA},
  1489. {1,2,M_BASIC,L_4,0x4E60,A_AREG|D_LOW,A_USP},
  1490. {1,2,M_BASIC,L_4,0x4E68,A_USP,A_AREG|D_LOW},
  1491. // op_moveq
  1492. {1,2,M_BASIC,L_0+L_4,0x7000,A_IMM|D_LOW,A_DREG|D_Q},
  1493. // op_clr
  1494. {1,1,M_BASIC,L_1+L_2+L_4,0x4200,A_DST2|D_EA|D_SZ},
  1495. // op_lea
  1496. {1,2,M_BASIC,L_0,0x41C0,A_MEM|A_PCR|D_EA,A_AREG|D_Q},
  1497. // op_add
  1498. {1,2,M_BASIC,L_1+L_2+L_4,0xD000,A_SRC|D_EA|D_SZ,A_DREG|D_Q},
  1499. {1,2,M_BASIC,L_1+L_2+L_4,0xD100,A_DREG|D_Q|D_SZ,A_MEM|D_EA},
  1500. {1,2,M_BASIC, L_2+L_4,0xD0C0,A_SRC|D_EA|D_SZ2,A_AREG|D_Q},
  1501. {1,2,M_BASIC,L_1+L_2+L_4,0x0600,A_IMM|D_RAW|D_SZ,A_DST2|D_EA},
  1502. // op_addi
  1503. {1,2,M_BASIC,L_1+L_2+L_4,0x0600,A_IMM|D_RAW|D_SZ,A_DST2|D_EA},
  1504. // op_addq
  1505. {1,2,M_BASIC,L_1+L_2+L_4,0x5000,A_IMM|D_Q|D_SZ,A_DST|D_EA},
  1506. // op_sub
  1507. {1,2,M_BASIC,L_1+L_2+L_4,0x9000,A_SRC|D_EA|D_SZ,A_DREG|D_Q},
  1508. {1,2,M_BASIC,L_1+L_2+L_4,0x9100,A_DREG|D_Q|D_SZ,A_MEM|D_EA},
  1509. {1,2,M_BASIC, L_2+L_4,0x90C0,A_SRC|D_EA|D_SZ2,A_AREG|D_Q},
  1510. {1,2,M_BASIC,L_1+L_2+L_4,0x0400,A_IMM|D_RAW|D_SZ,A_DST2|D_EA},
  1511. // op_subi
  1512. {1,2,M_BASIC,L_1+L_2+L_4,0x0400,A_IMM|D_RAW|D_SZ,A_DST2|D_EA},
  1513. // op_subq
  1514. {1,2,M_BASIC,L_1+L_2+L_4,0x5100,A_IMM|D_Q|D_SZ,A_DST|D_EA},
  1515. // op_muls
  1516. {1,2,M_BASIC,L_2,0xC1C0,A_SRC2|D_EA,A_DREG|D_Q},
  1517. // op_mulu
  1518. {1,2,M_BASIC,L_2,0xC0C0,A_SRC2|D_EA,A_DREG|D_Q},
  1519. // op_divs
  1520. {1,2,M_BASIC,L_2,0x81C0,A_SRC2|D_EA,A_DREG|D_Q},
  1521. // op_divu
  1522. {1,2,M_BASIC,L_2,0x80C0,A_SRC2|D_EA,A_DREG|D_Q},
  1523. // op_and
  1524. {1,2,M_BASIC,L_1+L_2+L_4,0xC000,A_SRC2|D_EA|D_SZ,A_DREG|D_Q},
  1525. {1,2,M_BASIC,L_1+L_2+L_4,0xC100,A_DREG|D_Q|D_SZ,A_MEM|D_EA},
  1526. {1,2,M_BASIC,L_1+L_2+L_4,0x0200,A_IMM|D_RAW|D_SZ,A_DST2|D_EA},
  1527. // op_andi
  1528. {1,2,M_BASIC,L_1+L_2+L_4,0x0200,A_IMM|D_RAW|D_SZ,A_DST2|D_EA},
  1529. // op_or
  1530. {1,2,M_BASIC,L_1+L_2+L_4,0x8000,A_SRC2|D_EA|D_SZ,A_DREG|D_Q},
  1531. {1,2,M_BASIC,L_1+L_2+L_4,0x8100,A_DREG|D_Q|D_SZ,A_MEM|D_EA},
  1532. {1,2,M_BASIC,L_1+L_2+L_4,0x0000,A_IMM|D_RAW|D_SZ,A_DST2|D_EA},
  1533. // op_ori
  1534. {1,2,M_BASIC,L_1+L_2+L_4,0x0000,A_IMM|D_RAW|D_SZ,A_DST2|D_EA},
  1535. // op_eor
  1536. {1,2,M_BASIC,L_1+L_2+L_4,0xB100,A_DREG|D_Q|D_SZ,A_DST2|D_EA},
  1537. {1,2,M_BASIC,L_1+L_2+L_4,0x0A00,A_IMM|D_RAW|D_SZ,A_DST2|D_EA},
  1538. // op_eori
  1539. {1,2,M_BASIC,L_1+L_2+L_4,0x0A00,A_IMM|D_RAW|D_SZ,A_DST2|D_EA},
  1540. // op_lsl
  1541. {1,2,M_BASIC,L_1+L_2+L_4,0xE108,A_IMM|D_Q|D_SZ,A_DREG|D_EA},
  1542. {1,2,M_BASIC,L_1+L_2+L_4,0xE128,A_DREG|D_Q|D_SZ,A_DREG|D_EA},
  1543. {1,1,M_BASIC,L_2,0xE3C0,A_MEM|D_EA},
  1544. // op_lsr
  1545. {1,2,M_BASIC,L_1+L_2+L_4,0xE008,A_IMM|D_Q|D_SZ,A_DREG|D_EA},
  1546. {1,2,M_BASIC,L_1+L_2+L_4,0xE028,A_DREG|D_Q|D_SZ,A_DREG|D_EA},
  1547. {1,1,M_BASIC,L_2,0xE2C0,A_MEM|D_EA},
  1548. // op_jmp
  1549. {1,1,M_BASIC,L_0,0x4EC0,A_MEM|A_PCR|D_EA},
  1550. // op_jsr
  1551. {1,1,M_BASIC,L_0,0x4E80,A_MEM|A_PCR|D_EA},
  1552. // op_movem - contains a little hack : default size is .l, so we separe L_4 from L_2.
  1553. // Uses M_BASICSWAPPED because when 'uses_link' is set, the link reg needs to be after
  1554. // the reg mask.
  1555. {1,2,M_BASIC,L_4,0x4880,A_MASK1|D_RAW|D_SZ3,A_MEM|D_EA}, /* LBUG : A_MEM&~POST_I */
  1556. {1,2,M_BASIC,L_2,0x4880,A_MASK1|D_RAW|D_SZ3,A_MEM|D_EA}, /* LBUG : A_MEM&~POST_I */
  1557. {1,2,M_BASICSWAPPED,L_2+L_4,0x4C80,A_MASK2|D_RAW,A_MEM0|D_EA|D_SZ3},
  1558. // op_rts
  1559. {1,0,M_BASIC,L_0,0x4E75},
  1560. // op_bra
  1561. {1,1,M_BRANCH,L_0+L_1+L_2,0x6000},
  1562. // op_bsr
  1563. {1,1,M_BRANCH,L_0+L_1+L_2,0x6100},
  1564. // op_beq
  1565. {1,1,M_BRANCH,L_0+L_1+L_2,0x6700},
  1566. // op_bne
  1567. {1,1,M_BRANCH,L_0+L_1+L_2,0x6600},
  1568. // op_bhs
  1569. {1,1,M_BRANCH,L_0+L_1+L_2,0x6400},
  1570. // op_bge
  1571. {1,1,M_BRANCH,L_0+L_1+L_2,0x6C00},
  1572. // op_bhi
  1573. {1,1,M_BRANCH,L_0+L_1+L_2,0x6200},
  1574. // op_bgt
  1575. {1,1,M_BRANCH,L_0+L_1+L_2,0x6E00},
  1576. // op_bls
  1577. {1,1,M_BRANCH,L_0+L_1+L_2,0x6300},
  1578. // op_ble
  1579. {1,1,M_BRANCH,L_0+L_1+L_2,0x6F00},
  1580. // op_blo
  1581. {1,1,M_BRANCH,L_0+L_1+L_2,0x6500},
  1582. // op_blt
  1583. {1,1,M_BRANCH,L_0+L_1+L_2,0x6D00},
  1584. // op_tst
  1585. {1,1,M_BASIC,L_1+L_2+L_4,0x4A00,A_DST2|D_EA|D_SZ},
  1586. // op_ext
  1587. {1,1,M_BASIC,L_2+L_4,0x4880,A_DREG|D_EA|D_SZ3},
  1588. // op_swap
  1589. {1,1,M_BASIC,L_4,0x4840,A_DREG|D_EA},
  1590. // op_neg
  1591. {1,1,M_BASIC,L_1+L_2+L_4,0x4400,A_DST2|D_EA|D_SZ},
  1592. // op_not
  1593. {1,1,M_BASIC,L_1+L_2+L_4,0x4600,A_DST2|D_EA|D_SZ},
  1594. // op_cmp
  1595. {1,2,M_BASIC,L_1+L_2+L_4,0xB000,A_SRC2|D_EA|D_SZ,A_DREG|D_Q},
  1596. {1,2,M_BASIC, L_2+L_4,0xB000,A_AREG|D_EA|D_SZ,A_DREG|D_Q},
  1597. {1,2,M_BASIC, L_2+L_4,0xB0C0,A_SRC|D_EA|D_SZ2,A_AREG|D_Q},
  1598. /* {1,2,M_BASIC, L_2 ,0xB100,A_SRC2|D_EA|D_SZ,A_AREG|D_Q},
  1599. {1,2,M_BASIC, L_4,0xB1C0,A_SRC2|D_EA|D_SZ,A_AREG|D_Q},*/
  1600. {1,2,M_BASIC,L_1+L_2+L_4,0x0C00,A_IMM|D_RAW|D_SZ,A_DST2|D_EA},
  1601. {1,2,M_BASIC,L_1+L_2+L_4,0xB108,A_MEM0|D_LOW|D_SZ,A_MEM0|D_Q}, // hum; other modes than A_AINC will generate an internal error (#8451/8452)
  1602. // op_link
  1603. {1,2,M_BASIC,L_2,0x4E50,A_AREG|D_LOW,A_IMM|D_RAW},
  1604. // op_unlk
  1605. {1,1,M_BASIC,L_2,0x4E58,A_AREG|D_LOW},
  1606. // op_pea
  1607. {1,1,M_BASIC,L_0,0x4840,A_MEM|A_PCR|D_EA},
  1608. // op_cmpi
  1609. {1,2,M_BASIC,L_1+L_2+L_4,0x0C00,A_IMM|D_RAW|D_SZ,A_DST2|D_EA},
  1610. // op_dbra
  1611. {1,2,M_BRANCH,L_2,0x51C8,A_DREG|D_LOW},
  1612. // op_asr
  1613. {1,2,M_BASIC,L_1+L_2+L_4,0xE000,A_IMM|D_Q|D_SZ,A_DREG|D_EA},
  1614. {1,2,M_BASIC,L_1+L_2+L_4,0xE020,A_DREG|D_Q|D_SZ,A_DREG|D_EA},
  1615. {1,1,M_BASIC,L_2,0xE0C0,A_MEM|D_EA},
  1616. // op_bset
  1617. {1,2,M_BASIC,L_0+L_1,0x08C0,A_IMM|D_RAW2,A_MEM|D_EA},
  1618. {1,2,M_BASIC,L_0+L_4,0x08C0,A_IMM|D_RAW2,A_DREG|D_EA},
  1619. {1,2,M_BASIC,L_0+L_1,0x01C0,A_DREG|D_Q,A_MEM|D_EA},
  1620. {1,2,M_BASIC,L_0+L_4,0x01C0,A_DREG|D_Q,A_DREG|D_EA},
  1621. // op_bclr
  1622. {1,2,M_BASIC,L_0+L_1,0x0880,A_IMM|D_RAW2,A_MEM|D_EA},
  1623. {1,2,M_BASIC,L_0+L_4,0x0880,A_IMM|D_RAW2,A_DREG|D_EA},
  1624. {1,2,M_BASIC,L_0+L_1,0x0180,A_DREG|D_Q,A_MEM|D_EA},
  1625. {1,2,M_BASIC,L_0+L_4,0x0180,A_DREG|D_Q,A_DREG|D_EA},
  1626. // op_bchg
  1627. {1,2,M_BASIC,L_0+L_1,0x0840,A_IMM|D_RAW2,A_MEM|D_EA},
  1628. {1,2,M_BASIC,L_0+L_4,0x0840,A_IMM|D_RAW2,A_DREG|D_EA},
  1629. {1,2,M_BASIC,L_0+L_1,0x0140,A_DREG|D_Q,A_MEM|D_EA},
  1630. {1,2,M_BASIC,L_0+L_4,0x0140,A_DREG|D_Q,A_DREG|D_EA},
  1631. #ifdef ASM
  1632. /* ASM-only */
  1633. // op_asl
  1634. {1,2,M_BASIC,L_1+L_2+L_4,0xE100,A_IMM|D_Q|D_SZ,A_DREG|D_EA},
  1635. {1,2,M_BASIC,L_1+L_2+L_4,0xE120,A_DREG|D_Q|D_SZ,A_DREG|D_EA},
  1636. {1,1,M_BASIC,L_2,0xE1C0,A_MEM|D_EA},
  1637. // op_rol
  1638. {1,2,M_BASIC,L_1+L_2+L_4,0xE118,A_IMM|D_Q|D_SZ,A_DREG|D_EA},
  1639. {1,2,M_BASIC,L_1+L_2+L_4,0xE138,A_DREG|D_Q|D_SZ,A_DREG|D_EA},
  1640. {1,1,M_BASIC,L_2,0xE7C0,A_MEM|D_EA},
  1641. // op_ror
  1642. {1,2,M_BASIC,L_1+L_2+L_4,0xE018,A_IMM|D_Q|D_SZ,A_DREG|D_EA},
  1643. {1,2,M_BASIC,L_1+L_2+L_4,0xE038,A_DREG|D_Q|D_SZ,A_DREG|D_EA},
  1644. {1,1,M_BASIC,L_2,0xE6C0,A_MEM|D_EA},
  1645. // op_roxl
  1646. {1,2,M_BASIC,L_1+L_2+L_4,0xE110,A_IMM|D_Q|D_SZ,A_DREG|D_EA},
  1647. {1,2,M_BASIC,L_1+L_2+L_4,0xE130,A_DREG|D_Q|D_SZ,A_DREG|D_EA},
  1648. {1,1,M_BASIC,L_2,0xE5C0,A_MEM|D_EA},
  1649. // op_roxr
  1650. {1,2,M_BASIC,L_1+L_2+L_4,0xE010,A_IMM|D_Q|D_SZ,A_DREG|D_EA},
  1651. {1,2,M_BASIC,L_1+L_2+L_4,0xE030,A_DREG|D_Q|D_SZ,A_DREG|D_EA},
  1652. {1,1,M_BASIC,L_2,0xE4C0,A_MEM|D_EA},
  1653. // op_btst
  1654. {1,2,M_BASIC,L_0+L_1,0x0800,A_IMM|D_RAW2,A_MEM|D_EA},
  1655. {1,2,M_BASIC,L_0+L_4,0x0800,A_IMM|D_RAW2,A_DREG|D_EA},
  1656. {1,2,M_BASIC,L_0+L_1,0x0100,A_DREG|D_Q,A_MEM|D_EA},
  1657. {1,2,M_BASIC,L_0+L_4,0x0100,A_DREG|D_Q,A_DREG|D_EA},
  1658. // op_exg
  1659. {1,2,M_BASIC,L_0+L_4,0xC140,A_DREG|D_LOW,A_DREG|D_Q},
  1660. {1,2,M_BASIC,L_0+L_4,0xC148,A_AREG|D_LOW,A_AREG|D_Q},
  1661. {1,2,M_BASIC,L_0+L_4,0xC188,A_AREG|D_LOW,A_DREG|D_Q},
  1662. {1,2,M_BASIC,L_0+L_4,0xC188,A_DREG|D_Q,A_AREG|D_LOW},
  1663. // op_dc
  1664. {1,1,M_DC,0,-1},
  1665. // op_ds
  1666. {1,1,M_DC,0,0},
  1667. // op_dcb
  1668. {1,2,M_DC,0,1},
  1669. // op_bvs
  1670. {1,1,M_BRANCH,L_0+L_1+L_2,0x6900},
  1671. // op_bvc
  1672. {1,1,M_BRANCH,L_0+L_1+L_2,0x6800},
  1673. // op_bpl
  1674. {1,1,M_BRANCH,L_0+L_1+L_2,0x6A00},
  1675. // op_bmi
  1676. {1,1,M_BRANCH,L_0+L_1+L_2,0x6B00},
  1677. // op_trap
  1678. {1,1,M_BASIC,L_0,0x4E40,A_IMM|D_LOW},
  1679. // op_negx
  1680. {1,1,M_BASIC,L_1+L_2+L_4,0x4000,A_DST2|D_EA|D_SZ},
  1681. // op_addx
  1682. {1,2,M_BASIC,L_1+L_2+L_4,0xD100,A_DREG|D_LOW|D_SZ,A_DREG|D_Q},
  1683. {1,2,M_BASIC,L_1+L_2+L_4,0xD108,A_ADEC|D_LOW|D_SZ,A_ADEC|D_Q},
  1684. // op_subx
  1685. {1,2,M_BASIC,L_1+L_2+L_4,0x9100,A_DREG|D_LOW|D_SZ,A_DREG|D_Q},
  1686. {1,2,M_BASIC,L_1+L_2+L_4,0x9108,A_ADEC|D_LOW|D_SZ,A_ADEC|D_Q},
  1687. // op_chk
  1688. {1,2,M_BASIC,L_2,0x4180,A_SRC2|D_EA,A_DREG|D_Q},
  1689. // op_even
  1690. {1,0,M_ALIGN,L_0,2},
  1691. // op_dbeq
  1692. {1,2,M_BRANCH,L_2,0x57C8,A_DREG|D_LOW},
  1693. // op_dbne
  1694. {1,2,M_BRANCH,L_2,0x56C8,A_DREG|D_LOW},
  1695. #ifndef LIGHT_DBXX_AND_SXX
  1696. // op_dbhs
  1697. {1,2,M_BRANCH,L_2,0x54C8,A_DREG|D_LOW},
  1698. // op_dbge
  1699. {1,2,M_BRANCH,L_2,0x5CC8,A_DREG|D_LOW},
  1700. // op_dbhi
  1701. {1,2,M_BRANCH,L_2,0x52C8,A_DREG|D_LOW},
  1702. // op_dbgt
  1703. {1,2,M_BRANCH,L_2,0x5EC8,A_DREG|D_LOW},
  1704. // op_dbls
  1705. {1,2,M_BRANCH,L_2,0x53C8,A_DREG|D_LOW},
  1706. // op_dble
  1707. {1,2,M_BRANCH,L_2,0x5FC8,A_DREG|D_LOW},
  1708. // op_dblo
  1709. {1,2,M_BRANCH,L_2,0x55C8,A_DREG|D_LOW},
  1710. // op_dblt
  1711. {1,2,M_BRANCH,L_2,0x5DC8,A_DREG|D_LOW},
  1712. // op_dbvs
  1713. {1,2,M_BRANCH,L_2,0x59C8,A_DREG|D_LOW},
  1714. // op_dbvc
  1715. {1,2,M_BRANCH,L_2,0x58C8,A_DREG|D_LOW},
  1716. // op_dbpl
  1717. {1,2,M_BRANCH,L_2,0x5AC8,A_DREG|D_LOW},
  1718. // op_dbmi
  1719. {1,2,M_BRANCH,L_2,0x5BC8,A_DREG|D_LOW},
  1720. // op_st
  1721. {1,1,M_BASIC,L_1,0x50C0,A_DST2|D_EA},
  1722. // op_sf
  1723. {1,1,M_BASIC,L_1,0x51C0,A_DST2|D_EA},
  1724. // op_seq
  1725. {1,1,M_BASIC,L_1,0x57C0,A_DST2|D_EA},
  1726. // op_sne
  1727. {1,1,M_BASIC,L_1,0x56C0,A_DST2|D_EA},
  1728. // op_shs
  1729. {1,1,M_BASIC,L_1,0x54C0,A_DST2|D_EA},
  1730. // op_sge
  1731. {1,1,M_BASIC,L_1,0x5CC0,A_DST2|D_EA},
  1732. // op_shi
  1733. {1,1,M_BASIC,L_1,0x52C0,A_DST2|D_EA},
  1734. // op_sgt
  1735. {1,1,M_BASIC,L_1,0x5EC0,A_DST2|D_EA},
  1736. // op_sls
  1737. {1,1,M_BASIC,L_1,0x53C0,A_DST2|D_EA},
  1738. // op_sle
  1739. {1,1,M_BASIC,L_1,0x5FC0,A_DST2|D_EA},
  1740. // op_slo
  1741. {1,1,M_BASIC,L_1,0x55C0,A_DST2|D_EA},
  1742. // op_slt
  1743. {1,1,M_BASIC,L_1,0x5DC0,A_DST2|D_EA},
  1744. // op_svs
  1745. {1,1,M_BASIC,L_1,0x59C0,A_DST2|D_EA},
  1746. // op_svc
  1747. {1,1,M_BASIC,L_1,0x58C0,A_DST2|D_EA},
  1748. // op_spl
  1749. {1,1,M_BASIC,L_1,0x5AC0,A_DST2|D_EA},
  1750. // op_smi
  1751. {1,1,M_BASIC,L_1,0x5BC0,A_DST2|D_EA},
  1752. // op_tas
  1753. {1,1,M_BASIC,L_1,0x4AC0,A_DST2|D_EA},
  1754. #endif
  1755. #endif
  1756. };
  1757. void wrt4(long x) {
  1758. if (odd) fatal("ALIGN");
  1759. bin_chk(pos+=4);
  1760. #ifdef PC
  1761. bin[pos-4]=(unsigned char)(x>>24);
  1762. bin[pos-3]=(unsigned char)(x>>16);
  1763. bin[pos-2]=(unsigned char)(x>>8);
  1764. bin[pos-1]=(unsigned char)(x);
  1765. #else
  1766. *(long *)(bin+pos-4)=x;
  1767. #endif
  1768. #ifdef PC
  1769. if ((pos^odd)&1)
  1770. fatal("INT/ODD");
  1771. #endif
  1772. }
  1773. void wrt2(short x) {
  1774. if (odd) fatal("ALIGN");
  1775. bin_chk(pos+=2);
  1776. #ifdef PC
  1777. bin[pos-2]=(unsigned char)(x>>8);
  1778. bin[pos-1]=(unsigned char)(x);
  1779. #else
  1780. *(short *)(bin+pos-2)=x;
  1781. #endif
  1782. #ifdef PC
  1783. if ((pos^odd)&1)
  1784. fatal("INT/ODD");
  1785. #endif
  1786. }
  1787. void wrt1(char x) {
  1788. bin_chk(pos+=1);
  1789. #ifdef PC
  1790. bin[pos-1]=(unsigned char)(x);
  1791. #else
  1792. *(char *)(bin+pos-1)=x;
  1793. #endif
  1794. odd=~odd;
  1795. #ifdef PC
  1796. if ((pos^odd)&1)
  1797. fatal("INT/ODD");
  1798. #endif
  1799. }
  1800. void fill(int n) {
  1801. if (odd) wrt1(0);
  1802. bin_chk(pos+=n);
  1803. memset(bin+pos-n,0,n);
  1804. odd = -(n&1);
  1805. }
  1806. void move_pos(long diff) { /* caution : only works in overwrite mode */
  1807. odd^=-(diff&1);
  1808. pos+=diff;
  1809. }
  1810. void rewrite(long size) {
  1811. bin_chk(pos+=size);
  1812. memcpy(bin+(pos-size),bin+(pos-2*size),size);
  1813. odd^=-(size&1);
  1814. #ifdef PC
  1815. if ((pos^odd)&1)
  1816. fatal("INT/ODD");
  1817. #endif
  1818. }
  1819. readonly int sz_table[]={0,0,0,0,0,2,2,2,0,0,2,2,2,2,4,0,0,0};
  1820. readonly struct enode zero={en_icon,0,0,{0},0,0};
  1821. readonly struct amode am_null={am_direct,(struct enode *)&zero,0,0,0,0};
  1822. #define ip_lab (((struct lbls *)ip)->lab)
  1823. void pass1() {
  1824. struct ocode *ip=scope_head;
  1825. OPCODE *op;
  1826. unsigned int vpos=pos;
  1827. while (ip) {
  1828. int opt,sz,n,f;
  1829. struct amode *ap;
  1830. int c=opi[ip->opcode],nm=opi[ip->opcode+1]-c;
  1831. int orig_len=ip->length;
  1832. int argnum_ok=0;
  1833. /* if (ip->opcode==_op_adj) {
  1834. sz=0; opt=0; c=-1;
  1835. goto ok;
  1836. }*/
  1837. err_cur_line=ip->line;
  1838. if (!nm) {
  1839. if (ip->opcode!=op_label)
  1840. fatal("P1: UNIMPL");
  1841. {
  1842. if (!local(ip_lab) && lab_src(ip_lab)) {
  1843. char *name=unres_name(ip_lab);
  1844. while (ip && ip->opcode==op_label) ip=ip->fwd;
  1845. if (ip) err_cur_line=ip->line-1;
  1846. else err_assembly=0;
  1847. uerrc2("label '%s' redefined",name);
  1848. }
  1849. lab_set(ip_lab,vpos);
  1850. ip->opcode=0;
  1851. sz=0;
  1852. goto ok_lab;
  1853. }
  1854. }
  1855. nm--; do {
  1856. opt=0;
  1857. op=(OPCODE *)&ops[c];
  1858. if ((!(n=op->nargs) && ip->oper1) || (n==1 && (!ip->oper1 || ip->oper2))
  1859. || (n==2 && !ip->oper2))
  1860. goto nxt;
  1861. argnum_ok++;
  1862. ip->length=orig_len;
  1863. switch (op->model) {
  1864. case M_BASICSWAPPED: /* caution : assumes that it is the sole M_BASICSWAPPED */
  1865. ap=ip->oper1; /* and that it is placed at the very end... */
  1866. ip->oper1=ip->oper2;
  1867. ip->oper2=ap;
  1868. /* FALLTHROUGH */
  1869. case M_BASIC:
  1870. if (!((f=op->lenf) & (1<<ip->length))) {
  1871. if (!ip->length) {
  1872. if (!(f & (1<<2))) {
  1873. if (!(f & (1<<4)))
  1874. ip->length=1;
  1875. else ip->length=4;
  1876. } else ip->length=2;
  1877. } else goto nxt;
  1878. }
  1879. sz=2;
  1880. ap=ip->oper1;
  1881. f=op->a1;
  1882. while (n--) {
  1883. int m=ap->mode;
  1884. if (!(f&
  1885. (m<am_indx2?
  1886. (m<am_ainc?
  1887. (m==am_dreg?A_DREG
  1888. :(m==am_areg?A_AREG
  1889. :A_MEM0)
  1890. )
  1891. :
  1892. (m==am_indx?
  1893. A_MEM0
  1894. :(ip->length?(m==am_ainc?A_MEM0:A_ADEC):0)
  1895. )
  1896. )
  1897. :
  1898. (m<am_mask1?
  1899. (m==am_immed?A_IMM:A_MEM0)
  1900. : (m<am_pcrel?(m==am_mask2?A_MASK2:A_MASK1)
  1901. :(m==am_pcrel?A_PCR:
  1902. (m<am_sr?A_MEM0:(m==am_sr?A_SR:(m==am_ccr?A_CCR:A_USP)))))
  1903. )
  1904. )
  1905. ))
  1906. goto nxt;
  1907. #ifdef TWIN_COMPILE
  1908. {int tclab,tcoff;
  1909. /*if (twinc_prev)
  1910. bkpt();*/
  1911. #endif
  1912. if (m==am_direct) {
  1913. if ((f&A_PCR) && ((ap->offset->nodetype==en_labcon
  1914. || ap->offset->nodetype==en_nacon) &&
  1915. #ifndef LARGE_MODEL
  1916. global(ap->offset->v.enlab)
  1917. #else
  1918. local(ap->offset->v.enlab)
  1919. #endif
  1920. #ifdef TWIN_COMPILE
  1921. && (!twinc_prev ||
  1922. ((tclab=twinc_prev[0],tcoff=twinc_prev[1],
  1923. twinc_prev+=2,
  1924. tclab!=ap->offset->v.enlab||abs(tcoff-vpos)>=5000)
  1925. && (twinc_prev-=2,1)))
  1926. #endif
  1927. )) {
  1928. /*if (ap->offset->v.enlab==0xFFFF8032)
  1929. bkpt();*/
  1930. m=am_pcrel;
  1931. } else {
  1932. get_offs(ap->offset,0);
  1933. if (is_long)
  1934. m=am_dirl;
  1935. else m=am_dirw;
  1936. }
  1937. ap = *(ap==ip->oper1 ? &ip->oper1 : &ip->oper2) = copy_addr(ap);
  1938. /* this is because the same operand might be either pcrel or
  1939. dirl, depending on the instruction/place of the operand */
  1940. ap->mode=m;
  1941. }
  1942. #ifdef TWIN_COMPILE
  1943. }
  1944. #endif
  1945. if (f&D_RAW2)
  1946. sz+=2;
  1947. else if ((f&D_RAW) && m==am_immed)
  1948. sz+=(ip->length+1)&-2;
  1949. else if (!(f&(D_Q|D_LOW)))
  1950. sz+=(m==am_immed?(ip->length+1)&-2:sz_table[m]);
  1951. ap=ip->oper2;
  1952. f=op->a2;
  1953. }
  1954. break;
  1955. case M_BRANCH:
  1956. if (n==1) { // Bcc
  1957. if (ip->oper1->offset->nodetype!=en_labcon
  1958. && ip->oper1->offset->nodetype!=en_nacon)
  1959. // fatal("BRANCH");
  1960. uerrc("invalid branch");
  1961. n=ip->oper1->offset->v.enlab;
  1962. if (!global(n))
  1963. // fatal("XT BRANCH");
  1964. uerrc("invalid branch");
  1965. if (ip->length==2) opt=0,sz=4;
  1966. else {
  1967. if ((f=lab_src(n))) {
  1968. f-=vpos;
  1969. opt=(f>129 || f<-126); // all branches are backwards so we needn't
  1970. // handle branches to next stmt in this pass
  1971. } else opt=1;
  1972. sz=2+(opt<<1);
  1973. }
  1974. } else { // DBcc
  1975. if ((ip->oper2->offset->nodetype!=en_labcon
  1976. && ip->oper2->offset->nodetype!=en_nacon)
  1977. || (ip->oper1->mode!=am_dreg))
  1978. // fatal("DBRANCH");
  1979. uerrc("invalid branch");
  1980. n=ip->oper2->offset->v.enlab;
  1981. if (!global(n))
  1982. // fatal("XT BRANCH");
  1983. uerrc("invalid branch");
  1984. sz=4;
  1985. }
  1986. break;
  1987. #ifdef ASM
  1988. case M_DC:
  1989. f=ip->length-2;
  1990. if (f<=0) f++; // f=log_2(ip->length)
  1991. if (ip->oper1->mode!=am_direct)
  1992. // fatal("DC");
  1993. uerrc("invalid declaration");
  1994. sz=1;
  1995. if (((short)op->bo)>=0) {
  1996. if (ip->oper1->offset->nodetype!=en_icon)
  1997. uerrc("invalid declaration");
  1998. sz=ip->oper1->offset->v.i;
  1999. if (op->bo && ip->oper2->mode!=am_direct)
  2000. uerrc("invalid declaration");
  2001. }
  2002. sz<<=f;
  2003. if (sz>=128)
  2004. uerrsys("too many elements in 'dc' instruction; use C arrays");
  2005. break;
  2006. case M_ALIGN:
  2007. sz=0;
  2008. if (vpos&1) {
  2009. sz=1;
  2010. c=oi_dc;
  2011. ip->length=1;
  2012. ip->oper1=(struct amode *)&am_null;
  2013. }
  2014. break;
  2015. default:
  2016. fatal("P1");
  2017. sz=0;
  2018. break;
  2019. #endif
  2020. }
  2021. goto ok;
  2022. nxt:
  2023. c++;
  2024. } while (nm--);
  2025. if (!argnum_ok)
  2026. uerrc2("instruction requires %d arguments",n);
  2027. uerrc("invalid address modes");
  2028. return;
  2029. // fatal("P1: INVALID");
  2030. ok:
  2031. #ifdef SIZE_STATS
  2032. if (!ip->opt) /* not from an asm() statement */
  2033. c_compiler_sz+=sz; /* note this is approximative, but close to reality */
  2034. #endif
  2035. ip->opt=opt;
  2036. ip->sz=sz;
  2037. ip->opcode=c;
  2038. ok_lab:
  2039. ip=ip->fwd;
  2040. vpos+=sz;
  2041. }
  2042. }
  2043. void pass2() {
  2044. struct ocode *ip=scope_head;
  2045. unsigned int vpos=pos,opos=vpos,s;
  2046. OPCODE *op;
  2047. while (ip) {
  2048. if (ip->opcode>0) {
  2049. s=ip->sz;
  2050. if (ip->opt) {
  2051. op=(OPCODE *)&ops[ip->opcode];
  2052. switch (op->model) {
  2053. case M_BASIC: case M_BASICSWAPPED:
  2054. break;
  2055. case M_BRANCH: { // this is necessarily a Bcc since ip->opt==1
  2056. int n=ip->oper1->offset->v.enlab;
  2057. long f=qlab_src(n);
  2058. if (!f) break; // global label not found
  2059. if ((unsigned int)f>opos) // we HAVE TO compare with opos (since opos>=vpos)
  2060. f-=opos+2; // <- here, f is afterwards, so relative to old pos
  2061. else f-=vpos+2;
  2062. /* the case of the next stmt branch :
  2063. * PASS 1 : the label is unknown, so opt=1 and ip->sz=4
  2064. * PASS 2 : qlab_src(n)-opos==4, so here, f==2 (rather than f==0) */
  2065. if (f!=2 && f>=-128 && f<=127)
  2066. ip->sz=2;
  2067. else if (f>=-32768 && f<=32767)
  2068. ip->sz=4;
  2069. else err_cur_line=ip->line, uerrc("branch size can't fit in a word");
  2070. } break;
  2071. }
  2072. }
  2073. opos+=s, vpos+=ip->sz;
  2074. } else if (!ip->opcode) {// op_label
  2075. /* if (vpos==0x2642)
  2076. printf("rjo");*/
  2077. lab_set(ip_lab,vpos);
  2078. }
  2079. /* else { // _op_adj
  2080. }*/
  2081. ip=ip->fwd;
  2082. }
  2083. }
  2084. int movem(short x) {
  2085. int n=0;
  2086. while (x) {
  2087. if (x<0) n++;
  2088. x+=x;
  2089. }
  2090. return n;
  2091. }
  2092. void pass3() {
  2093. struct ocode *ip=scope_head;
  2094. #ifdef PC
  2095. unsigned int opos=pos;
  2096. #endif
  2097. OPCODE *op;
  2098. while (ip) {
  2099. int n,f;
  2100. struct amode *ap;
  2101. short code;
  2102. if (ip->opcode>0) {
  2103. err_cur_line=ip->line;
  2104. op=(OPCODE *)&ops[ip->opcode];
  2105. n=op->nargs;
  2106. switch (op->model) {
  2107. case M_BASIC: case M_BASICSWAPPED: {
  2108. int ds=0,ds2=0; int len=ip->length;
  2109. #ifdef PC
  2110. long dc=0xdddddddd,dc2=0xdddddddd;
  2111. #else
  2112. long dc=dc,dc2=dc2;
  2113. #endif
  2114. unsigned int vpos=pos+2;
  2115. code=op->bo;
  2116. ap=ip->oper1;
  2117. f=op->a1;
  2118. #ifndef USE_LINK
  2119. if (n)
  2120. if (ap->preg==STACKPTR-8) {
  2121. if (ap->mode==am_ainc) { // for <op> (a7)+,...
  2122. lc_stk-=len+(len&1);
  2123. } else if (ap->mode==am_adec)
  2124. lc_stk+=len+(len&1); // for clr -(a7)
  2125. }
  2126. #endif
  2127. while (n--) {
  2128. if ((f&D_SZ3)==D_SZ3) {
  2129. if (len==4) code|=0x40;
  2130. } else if (f&D_SZ)
  2131. code|=(len==2?0x40:(len==4?0x80:0x00));
  2132. else if ((f&D_SZ2) && len==4)
  2133. code|=0x100;
  2134. if (f&D_EA)
  2135. switch (ap->mode) {
  2136. case am_areg:
  2137. case am_ind:
  2138. case am_ainc:
  2139. case am_adec:
  2140. code+=ap->mode<<3;
  2141. case am_dreg:
  2142. code+=ap->preg;
  2143. break;
  2144. case am_indx:
  2145. #ifndef USE_LINK
  2146. if (ap->preg==FRAMEPTR-8) {
  2147. if (uses_link)
  2148. ap->preg+=TRUE_FRAMEPTR-FRAMEPTR;
  2149. else {
  2150. ap->preg+=STACKPTR-FRAMEPTR;
  2151. ap->offset->v.i += lc_stk - (ap->offset->v.i>0 ? 4 : 0);
  2152. uses_lc_stk = 1;
  2153. }
  2154. }
  2155. #endif
  2156. code+=0x28+ap->preg;
  2157. ds=1; dc=get_word(ap->offset,vpos,1);
  2158. break;
  2159. case am_pcrel:
  2160. code+=0x3A;
  2161. ds=1; dc=get_pcword(ap->offset,vpos); // rel to vpos, not pos!
  2162. break;
  2163. case am_dirw:
  2164. code+=0x38;
  2165. ds=1; dc=get_word(ap->offset,vpos,1);
  2166. break;
  2167. case am_dirl:
  2168. code+=0x39;
  2169. ds=2; dc=get_long(ap->offset,vpos);
  2170. break;
  2171. case am_immed:
  2172. code+=0x3C;
  2173. ds=(1+len)>>1;
  2174. if (ds==1) dc=get_word(ap->offset,vpos,0);
  2175. else dc=get_long(ap->offset,vpos);
  2176. break;
  2177. case am_indx2:
  2178. code+=0x30+ap->preg;
  2179. ds=1;
  2180. dc=get_byte(ap->offset)+((short)ap->sreg<<12)+
  2181. (ap->slen==4?0x0800:0x0000);
  2182. break;
  2183. case am_indx3:
  2184. code+=0x30+ap->preg;
  2185. ds=1;
  2186. dc=get_byte(ap->offset)+((short)ap->sreg<<12)+
  2187. (ap->slen==4?0x8800:0x8000);
  2188. break;
  2189. #ifdef PC
  2190. default:
  2191. ierr(PASS3,1);
  2192. #endif
  2193. }
  2194. else if (f&D_EA2)
  2195. switch (ap->mode) {
  2196. case am_areg:
  2197. case am_ind:
  2198. case am_ainc:
  2199. case am_adec:
  2200. code+=ap->mode<<6;
  2201. case am_dreg:
  2202. code+=((short)ap->preg)<<9;
  2203. break;
  2204. case am_indx:
  2205. #ifndef USE_LINK
  2206. if (ap->preg==FRAMEPTR-8) {
  2207. if (uses_link)
  2208. ap->preg+=TRUE_FRAMEPTR-FRAMEPTR;
  2209. else {
  2210. ap->preg+=STACKPTR-FRAMEPTR;
  2211. ap->offset->v.i += lc_stk - (ap->offset->v.i>0 ? 4 : 0);
  2212. uses_lc_stk = 1;
  2213. }
  2214. }
  2215. #endif
  2216. code+=(0x28<<3)+((short)ap->preg<<9);
  2217. ds=1; dc=get_word(ap->offset,vpos,1);
  2218. break;
  2219. /* case am_pcrel:
  2220. code+=(0x38<<3)+(0x02<<9);
  2221. ds=1; dc=get_pcword(ap->offset,vpos); // rel to vpos, not pos!
  2222. break;*/
  2223. case am_dirw:
  2224. code+=0x38<<3;
  2225. ds=1; dc=get_word(ap->offset,vpos,1);
  2226. break;
  2227. case am_dirl:
  2228. code+=(0x38<<3)+(0x01<<9);
  2229. ds=2; dc=get_long(ap->offset,vpos);
  2230. break;
  2231. case am_indx2:
  2232. code+=(0x30<<3)+(ap->preg<<9);
  2233. ds=1;
  2234. dc=get_byte(ap->offset)+((short)ap->sreg<<12)+
  2235. (ap->slen==4?0x0800:0x0000);
  2236. break;
  2237. case am_indx3:
  2238. code+=(0x30<<3)+(ap->preg<<9);
  2239. ds=1;
  2240. dc=get_byte(ap->offset)+((short)ap->sreg<<12)+
  2241. (ap->slen==4?0x8800:0x8000);
  2242. break;
  2243. #ifdef PC
  2244. default:
  2245. ierr(PASS3,2);
  2246. #endif
  2247. }
  2248. else if (f&D_Q)
  2249. switch (ap->mode) {
  2250. case am_areg:
  2251. case am_dreg:
  2252. case am_ainc:
  2253. case am_adec:
  2254. code+=((unsigned short)ap->preg)<<9;
  2255. break;
  2256. case am_immed:
  2257. code+=get_quick(ap->offset)<<9;
  2258. break;
  2259. #ifdef PC
  2260. default:
  2261. ierr(PASS3,3);
  2262. #endif
  2263. }
  2264. else if (f&D_LOW)
  2265. switch (ap->mode) {
  2266. case am_areg:
  2267. case am_dreg:
  2268. case am_adec:
  2269. case am_ainc:
  2270. code+=ap->preg;
  2271. break;
  2272. case am_immed:
  2273. code+=get_byte(ap->offset);
  2274. break;
  2275. #ifdef PC
  2276. default:
  2277. ierr(PASS3,4);
  2278. #endif
  2279. }
  2280. else if (f&D_RAW)
  2281. switch (ap->mode) {
  2282. case am_immed:
  2283. if (len==4)
  2284. ds=2,dc=get_long(ap->offset,vpos);
  2285. else
  2286. ds=1,dc=get_word(ap->offset,vpos,0);
  2287. break;
  2288. case am_mask1:
  2289. case am_mask2:
  2290. ds=1; dc=ap->offset->v.i;
  2291. break;
  2292. #ifdef PC
  2293. default:
  2294. ierr(PASS3,5);
  2295. #endif
  2296. }
  2297. else if (f&D_RAW2)
  2298. ds=1,dc=get_word(ap->offset,vpos,0);
  2299. ap=ip->oper2;
  2300. f=op->a2;
  2301. vpos+=ds<<1;
  2302. if (n) {
  2303. ds2=ds,dc2=dc,ds=0;
  2304. #ifndef USE_LINK
  2305. if (ap->preg==STACKPTR-8) {
  2306. if (ap->mode==am_adec) { // for <op> ...,-(a7)
  2307. if (ip->oper1->mode==am_mask1)
  2308. lc_stk+=movem((short)ip->oper1->offset->v.i)<<(len>>1);
  2309. else lc_stk+=len+(len&1);
  2310. }
  2311. else if (ap->mode==am_ainc && ip->oper1->mode==am_mask2)
  2312. lc_stk-=movem((short)ip->oper1->offset->v.i)<<(len>>1);
  2313. }
  2314. #endif
  2315. }
  2316. }
  2317. #ifndef USE_LINK
  2318. if (code==0x4FEF // lea x(a7),a7
  2319. || (code&0xF13F)==0x500F // addq.* #x,a7
  2320. || (code&0xFEFF)==0xDEFC) // add.* #x,a7
  2321. lc_stk-=ip->oper1->offset->v.i;
  2322. else if ((code&0xF13F)==0x510F // subq.* #x,a7
  2323. || (code&0xFEFF)==0x9EFC) // sub.* #x,a7
  2324. lc_stk+=ip->oper1->offset->v.i;
  2325. else if (((code&0xFFC0)==0x4840 && (code&0x0038/*!swap*/))) // pea <ea>
  2326. lc_stk+=4;
  2327. #endif
  2328. wrt2(code);
  2329. if (--ds2>=0) {
  2330. if (!ds2) wrt2((short)dc2);
  2331. else wrt4(dc2);
  2332. }
  2333. if (--ds>=0) {
  2334. if (!ds) wrt2((short)dc);
  2335. else wrt4(dc);
  2336. }
  2337. } break;
  2338. case M_BRANCH: {
  2339. unsigned int vpos=pos+2;
  2340. code=op->bo;
  2341. if (ip->oper2) // DBcc
  2342. n=ip->oper2->offset->v.enlab, code+=ip->oper1->preg;
  2343. else n=ip->oper1->offset->v.enlab; // Bcc
  2344. if ((f=qlab_src(n))) {
  2345. if (ip->sz==2)
  2346. wrt2(code|=(f-vpos)&0xFF);
  2347. else
  2348. wrt2(code),wrt2((short)(f-vpos));
  2349. } else
  2350. wrt2(code),wrt2((short)-(short)vpos),lab_add_ref(n,vpos);
  2351. } break;
  2352. case M_DC: {
  2353. struct enode *ep=ip->oper1->offset;
  2354. n=1;
  2355. if (((short)op->bo)>=0) {
  2356. n=ip->oper1->offset->v.i;
  2357. if (op->bo)
  2358. ep=ip->oper2->offset;
  2359. else ep=(struct enode *)&zero;
  2360. }
  2361. f=ip->length-2;
  2362. while (n--) {
  2363. if (f<0) {
  2364. GV v;
  2365. get_value(ep,&v,0,0);
  2366. if (v.tr)
  2367. uerr(ERRA_INVALIDREL);
  2368. if (v.i>255 || v.i<-128)
  2369. uerrc("result can't fit in a byte");
  2370. wrt1((char)v.i);
  2371. } else if (!f) wrt2(get_word(ep,pos,0));
  2372. else wrt4(get_long(ep,pos));
  2373. }
  2374. } break;
  2375. }
  2376. #ifdef PC
  2377. opos+=ip->sz;
  2378. if (pos!=opos) {
  2379. // printf("%d",oi_ds);
  2380. ierr(PASS3,6);
  2381. }
  2382. #endif
  2383. }
  2384. /* else if (ip->opcode) { // _op_adj
  2385. }*/
  2386. else if (!ip->opcode) { // op_label
  2387. //#ifdef PC
  2388. // if (pos!=qlab_src(ip_lab))
  2389. // ierr(PASS3,7);
  2390. //#endif
  2391. if (pos!=qlab_src(ip_lab))
  2392. uerrc2("label '%s' defined twice",unres_name(ip_lab));
  2393. if (!local(ip_lab)) {
  2394. lab_set(ip_lab,0); // 'unset' it so there will be no error...
  2395. set_label(ip_lab,pos);
  2396. }
  2397. }
  2398. ip=ip->fwd;
  2399. }
  2400. }
  2401. void scope_flush(void) {
  2402. err_assembly=1;
  2403. pass1();
  2404. pass2();
  2405. pass3();
  2406. err_assembly=0;
  2407. if (uses_lc_stk && lc_stk) {
  2408. uwarn("stack displacement of %d: compiler bug?",(int)lc_stk);
  2409. iwarn(WARN_LC_STK,1);
  2410. }
  2411. scope_head = 0;
  2412. loc_tab = 0;
  2413. }
  2414. void scope_init(void) {
  2415. if (scope_head) scope_flush();
  2416. lc_stk = 0;
  2417. uses_lc_stk = 0;
  2418. nextlabel = 1;
  2419. loc_tab = 0;
  2420. }
  2421. void local_clean(void) { /* remove local symbols from alsyms -- to be called just before rel_local */
  2422. HTABLE *tab=&alsyms;
  2423. SYM *ttail,**prv;
  2424. struct htab *root;
  2425. int i;
  2426. if (!tab->hash)
  2427. ierr(TABLE_HASH,2);
  2428. #ifdef PC
  2429. if (tab->hash!=0x2489)
  2430. ierr(TABLE_HASH,1);
  2431. #endif
  2432. i=N_HASH;
  2433. while (i--) {
  2434. prv=&((root=&tab->h[i])->tail);
  2435. while ((ttail=*prv)) {
  2436. if (local(ttail->value.splab)) {
  2437. // *prv = ttail->prev;
  2438. if (ttail->next) ttail->next->prev = ttail->prev;
  2439. if (ttail->prev) ttail->prev->next = ttail->next;
  2440. // ttail->next = prv;
  2441. if (root->tail==ttail) root->tail=ttail->prev;
  2442. if (root->head==ttail) root->head=ttail->next;
  2443. /* if (!root->tail)
  2444. root->head=0;*/
  2445. }
  2446. prv = &(ttail->prev);
  2447. }
  2448. }
  2449. }
  2450. int label(char *s) {
  2451. int lab; SYM *sp;
  2452. /* if (!strcmp(s,"__L_plane") || !strcmp(s,"__D_plane"))
  2453. bkpt();*/
  2454. if (!(sp=search(s,-1,&alsyms))) {
  2455. if (s[0]!='\\')
  2456. global_flag++;
  2457. sp=(SYM *)xalloc((int)sizeof(SYM),_SYM);
  2458. sp->name=strsave(s);
  2459. if (s[0]=='\\')
  2460. lab_src(sp->value.splab=lab=nxtlabel());
  2461. else if (internal(s))
  2462. lab_src(sp->value.splab=lab=nxtglabel());
  2463. else
  2464. sp->value.splab=lab=extlabel--;
  2465. insert(sp,&alsyms);
  2466. if (s[0]!='\\')
  2467. global_flag--;
  2468. } else
  2469. lab=sp->value.splab;
  2470. debugf("label(%s)=%x\n",s,lab);
  2471. #ifdef PC
  2472. /* if (lab==0x806d)
  2473. bkpt();*/
  2474. if (!*s)
  2475. return lab;
  2476. #endif
  2477. return lab;
  2478. }
  2479. void set_label(int lab,unsigned int pos) {
  2480. /*if ((unsigned short)lab==0x8014)
  2481. bkpt();*/
  2482. debugf("set_lab(%x,%x)\n",lab,pos);
  2483. if (lab_src(lab)) uerrc("label redefinition");
  2484. if (global(lab)) {
  2485. lab_set(lab,pos);
  2486. if (!local(lab)) {
  2487. REF **rp,*r;
  2488. unsigned int p,*a; int n;
  2489. r=*(rp=glb_ref(lab));
  2490. while (r) {
  2491. a=r->r;
  2492. n=N_REF;
  2493. while (n--) {
  2494. if (!(p=*a++))
  2495. goto ref_done;
  2496. #ifdef PC
  2497. { int m=p&1; short a,olda;
  2498. p-=m;
  2499. a=(bin[p]<<8)+bin[p+1],olda=a;
  2500. if (m) {
  2501. if ((a-=pos)>0 && olda) fatal("PC RANGE 3");
  2502. } else if ((a+=pos)<0 && olda) fatal("PC RANGE 2");
  2503. bin[p]=(unsigned char)(a>>8);
  2504. bin[p+1]=(unsigned char)(a);
  2505. }
  2506. #else
  2507. if (p&1) {
  2508. short *z=(short *)(bin+(p&-2));
  2509. if (*z && ((*z)-=pos)>0)
  2510. fatal("PC RANGE 3");
  2511. else (*z)-=pos;
  2512. } else if ((*(short *)(bin+p)+=pos)<0 && *(short *)(bin+p)!=pos)
  2513. fatal("PC RANGE 2");
  2514. #endif
  2515. }
  2516. r=r->nxt;
  2517. }
  2518. ref_done:
  2519. *rp=0;
  2520. }
  2521. }
  2522. else debugf(" --local\n");
  2523. }
  2524. void put_label(int lab) {
  2525. /*
  2526. * output a compiler generated label.
  2527. */
  2528. #ifdef NO_OUT
  2529. return;
  2530. #endif
  2531. set_label(lab,pos);
  2532. }
  2533. void g_strlab(char *s) {
  2534. /*
  2535. * generate a named label.
  2536. */
  2537. #ifdef NO_OUT
  2538. return;
  2539. #endif
  2540. put_label(label(s));
  2541. }
  2542. void genbyte(int val) {
  2543. #ifdef NO_OUT
  2544. return;
  2545. #endif
  2546. wrt1((char)val);
  2547. }
  2548. void genword(int val) {
  2549. #ifdef NO_OUT
  2550. return;
  2551. #endif
  2552. put_align2();
  2553. wrt2((short)val);
  2554. }
  2555. typedef struct _pc_bcd_s {
  2556. short exponent;
  2557. unsigned char mantissa[8];
  2558. } _pc_bcd;
  2559. #ifndef NOFLOAT
  2560. void genfloat(double val) {
  2561. #ifndef BCDFLT
  2562. put_align2();
  2563. wrt4(double2ffp(val));
  2564. #else
  2565. BCD bcd;
  2566. double2bcd(val,&bcd);
  2567. wrt2(bcd.exponent);
  2568. #ifdef PC
  2569. {
  2570. int i;
  2571. for (i=0;i<BCDLEN;i++)
  2572. wrt1(bcd.mantissa[i]);
  2573. }
  2574. #else
  2575. wrt4(((long *)bcd.mantissa)[0]);
  2576. wrt4(((long *)bcd.mantissa)[1]);
  2577. #endif
  2578. #endif
  2579. }
  2580. #ifdef DOUBLE
  2581. void gendouble(double val) {
  2582. genfloat(val);
  2583. }
  2584. #endif
  2585. #endif
  2586. void genptr(struct enode *node) {
  2587. #ifdef NO_OUT
  2588. return;
  2589. #endif
  2590. put_align2();
  2591. wrt4(get_long(node,pos));
  2592. }
  2593. #ifdef PC
  2594. extern int forbid_bss;
  2595. #endif
  2596. void genstorage(struct sym *sp, int align) {
  2597. long size = sp->tp->size;
  2598. #ifdef NO_OUT
  2599. return;
  2600. #endif
  2601. #ifdef PC
  2602. #define no_bss (nostub_mode || forbid_bss)
  2603. #else
  2604. #define no_bss nostub_mode
  2605. #endif
  2606. if (align!=1) put_align2();
  2607. size=(size+1)&-2; // round size
  2608. if (sp->value.splab) {
  2609. if (no_bss) { /* that's OK in _nostub mode :) */
  2610. if (lab_src(sp->value.splab))
  2611. return;
  2612. } else
  2613. uerrc2("BSS redeclaration of '%s' : use 'extern' for prototyping",sp->name);
  2614. } else if (no_bss) {
  2615. if (sp->storage_class==sc_static)
  2616. sp->value.splab=nxtglabel();
  2617. else
  2618. sp->value.splab=label(sp->name);
  2619. }
  2620. if (no_bss) {
  2621. put_label(sp->value.splab);
  2622. fill(size);
  2623. } else {
  2624. *(long *)xt_find(sp->value.splab=extlabel--)=lc_bss|0x80000000; // DIRTY, but no hidden
  2625. lc_bss+=size; // bug possible
  2626. } // (cf xalloc)
  2627. #if 0
  2628. remain = size % AL_DEFAULT;
  2629. if (remain != 0)
  2630. size = size + AL_DEFAULT - remain;
  2631. if (sp->storage_class == sc_static) {
  2632. fprintf(output, "L%ld:" tabs "ds.b %ld\n", sp->value.i, size);
  2633. lc_bss += sp->tp->size;
  2634. } else
  2635. fprintf(output, "L%d:" tabs "ds.b %ld\n", label(sp->name),size);
  2636. #endif
  2637. #undef no_bss
  2638. }
  2639. void dumplits() {
  2640. /*
  2641. * dump the string literal pool.
  2642. */
  2643. char *cp;
  2644. int len;
  2645. /*
  2646. * The ACK assembler may produce a .text section of an uneven length.
  2647. * This will eventually bomb the linker when it tries to relocate
  2648. * something in a following (.data) section, which then is misaligned
  2649. * as a whole in memory (perhaps this is just a bug in the linker).
  2650. *
  2651. * To avoid this (it can only happen if the string pool is the last
  2652. * thing dumped to the assembler file) we count the total number of
  2653. * bytes in the string pool and emit a zero filler byte if that
  2654. * number was uneven.
  2655. * This is perhaps an ugly hack, but in virtually all of the cases
  2656. * this filler byte is inserted anyway by the assembler when
  2657. * doing the alignment necessary for the next function body.
  2658. */
  2659. // long count=0;
  2660. while (strtab != 0) {
  2661. cseg();
  2662. nl();
  2663. put_label((unsigned int) strtab->label);
  2664. cp = strtab->str;
  2665. len = strtab->len;
  2666. //count += (len+1);
  2667. while (len--)
  2668. wrt1(*cp++);
  2669. wrt1(0);
  2670. strtab = strtab->next;
  2671. }
  2672. put_align2();
  2673. }
  2674. void put_align2(void) {
  2675. /* align the following data to 2 */
  2676. if (odd) wrt1(0);
  2677. }
  2678. /*put_align(align)
  2679. int align;
  2680. // align the following data
  2681. {
  2682. switch (align) {
  2683. case 1:
  2684. break;
  2685. case 2:
  2686. if (odd) wrt1(0);
  2687. }
  2688. }*/
  2689. #ifdef LISTING
  2690. void put_external(char *s) {
  2691. /* put the definition of an external name in the ouput file */
  2692. }
  2693. void put_global(char *s) {
  2694. /* put the definition of a global name in the output file */
  2695. }
  2696. #endif
  2697. /*cseg()
  2698. {
  2699. if (curseg != codeseg) {
  2700. nl();
  2701. #ifdef PC
  2702. fputs(tabs ".text\n", output);
  2703. #endif
  2704. curseg = codeseg;
  2705. }
  2706. }*/
  2707. /*dseg()
  2708. {
  2709. if (curseg != dataseg) {
  2710. nl();
  2711. #ifdef PC
  2712. fputs(tabs ".data\n", output);
  2713. #endif
  2714. curseg = dataseg;
  2715. }
  2716. }*/
  2717. int radix16(char c) {
  2718. if (isdigit(c))
  2719. return c - '0';
  2720. /* if (c >= 'a' && c <= 'z')
  2721. return c - 'a' + 10;*/
  2722. if (c >= 'A' && c <= 'Z')
  2723. return c - 'A' + 10;
  2724. return -1;
  2725. }
  2726. int hexatoi(char *s) {
  2727. int x=0;
  2728. if (strlen(s)>3) return -1;
  2729. while (*s) {
  2730. int y=radix16(*s++);
  2731. if (y<0) return -1;
  2732. x<<=4; x+=y;
  2733. }
  2734. return x;
  2735. }
  2736. int internal(char *s) {
  2737. int n=0;
  2738. char c,old=0,*p;
  2739. if (*s == '.')
  2740. return 1;
  2741. p=s;
  2742. while ((c=*p++)) {
  2743. if (n==10) {
  2744. if (((
  2745. #ifdef FLINE_RC
  2746. !fline_rc &&
  2747. #endif
  2748. !strncmp(s,"_ROM_CALL_",10)))
  2749. #ifdef RAM_CALLS
  2750. || !strncmp(s,"_RAM_CALL_",10)
  2751. #endif
  2752. ) {
  2753. int f=hexatoi(p-1);
  2754. if (f<0)
  2755. goto cont;
  2756. *xt_find(extlabel)=&(func_search(
  2757. #ifdef RAM_CALLS
  2758. s[2]=='O' ? &rom_funcs : &ram_funcs
  2759. #else
  2760. &rom_funcs
  2761. #endif
  2762. ,f))->rt;
  2763. return 0;
  2764. }
  2765. }
  2766. if (n==export_pfx_len) {
  2767. if (!strncmp(s,export_pfx,n)) {
  2768. int f=hexatoi(p);
  2769. if (f<0)
  2770. goto cont3;
  2771. *exp_find(f)=glblabel;
  2772. return 1;
  2773. }
  2774. }
  2775. if (c=='_' && n && old=='_' && *p=='0') {
  2776. SYM *sp;
  2777. int f=hexatoi(p+1);
  2778. if (f<0)
  2779. goto cont2;
  2780. p[-2]=0;
  2781. if (!(sp=search(s,-1,(HTABLE *)&libsyms))) {
  2782. global_flag++;
  2783. sp=(SYM *)xalloc((int)sizeof(SYM),_SYM);
  2784. sp->name=strsave(s);
  2785. insert(sp,(HTABLE *)&libsyms);
  2786. global_flag--;
  2787. }
  2788. *xt_find(extlabel)=&(func_search((FUNC **)&sp->value.i,f))->rt;
  2789. p[-2]='_';
  2790. return 0;
  2791. }
  2792. cont:
  2793. cont2:
  2794. cont3:
  2795. old=c; n++;
  2796. }
  2797. return 1;
  2798. }
  2799. #ifdef PCH
  2800. unsigned char *_end_of(short *p) { /* works endian-independently */
  2801. while (*p++);
  2802. return (unsigned char *)p;
  2803. }
  2804. unsigned char *_end_of2(short *p) { /* works endian-independently */
  2805. while (*p++ || *p);
  2806. return (unsigned char *)(p+1);
  2807. }
  2808. #define end_of(p) _end_of((short *)(p))
  2809. #define end_of2(p) _end_of2((short *)(p))
  2810. #ifndef isidch
  2811. #ifdef PC
  2812. static int isidch(char c) {
  2813. return (c>='0'&&c<='9') || (c>='A'&&c<='Z') || (c>='a'&&c<='z')
  2814. || c == '_' || c == '$';
  2815. }
  2816. #else
  2817. #define isidch(___c) ({register short __c=(___c); \
  2818. (__c>='0'&&__c<='9') || (__c>='A'&&__c<='Z') || (__c>='a'&&__c<='z') || __c=='_' || __c=='$';})
  2819. #endif
  2820. #endif
  2821. int pchsearch(char *id,int mode);
  2822. #define lscan(x) pchsearch(x,PCHS_ADD)
  2823. #define lexpand(x) (x)
  2824. /*#define lscan (void)lexpand
  2825. void macro_expansion(char *in,char *inbound);
  2826. char lexp_buf[100];
  2827. char *lexpand(char *s) {
  2828. char c,*p=lexp_buf;
  2829. strcpy(p,s);
  2830. macro_expansion(p,&lexp_buf[100]);
  2831. if (*p>='0' && *p<='9')
  2832. return s;
  2833. while ((c=*p++))
  2834. if (!isidch(c)) return s;
  2835. return lexp_buf;
  2836. }*/
  2837. #ifdef PC
  2838. #define g16(p) (p+=2,(p[-2]<<8)+p[-1])
  2839. #define r16(o) ((ext[o]<<8)+ext[o+1])
  2840. #define align(strp) if ((strp-ext)&1) strp++
  2841. #else
  2842. #define g16(p) (*((int *)p)++)
  2843. #define r16(o) (*(int *)(ext+o))
  2844. #define align(strp) if (((short)((long)strp))&1) strp++
  2845. #endif
  2846. void extscan(unsigned char *ext) {
  2847. int codeOff=r16(0);
  2848. unsigned char *offp=ext+codeOff,*strp;
  2849. /* reloc table */
  2850. offp=end_of(offp);
  2851. /* export table */
  2852. strp=end_of(offp);
  2853. while (g16(offp))
  2854. while (*strp++);
  2855. align(strp);
  2856. /* import table */
  2857. offp=strp; strp=end_of2(offp);
  2858. while (*(short *)offp) {
  2859. lscan(strp);
  2860. offp=end_of(offp);
  2861. while (*strp++);
  2862. }
  2863. }
  2864. #undef off // for TI-GCC :D
  2865. #ifdef PC
  2866. #define add_offs(val,offs) do { \
  2867. short a=bin[offs+0]<<8; \
  2868. a+=bin[offs+1]; \
  2869. a+=val; \
  2870. bin[offs+0]=(unsigned char)(a>>8); \
  2871. bin[offs+1]=(unsigned char)(a); \
  2872. } while (0)
  2873. #else
  2874. #define add_offs(val,offs) (*(short *)(bin+offs)+=val)
  2875. #endif
  2876. void extload(unsigned char *ext) {
  2877. int codeOff=r16(0); unsigned int wriOff;
  2878. SYM *sp;
  2879. if (odd) wrt1(0);
  2880. /*#ifdef PC
  2881. if (codeOff>=0x2000)
  2882. printf("gfio");
  2883. #endif*/
  2884. /* In the following case, either the .ext has already been loaded, either
  2885. * there is a conflict, in which case the error will arise at the end
  2886. * (what's more, it allows for overriding of the default functions) */
  2887. sp=search(end_of(end_of(ext+codeOff)),-1,&alsyms);
  2888. if (sp && lab_src(sp->value.splab))
  2889. return;
  2890. wriOff=pos-2; /* since offsets are based on ext::$00, not on ext::$02=code */
  2891. bin_chk(pos+=codeOff-2);
  2892. memcpy(bin+pos-codeOff+2,ext+2,codeOff-2);
  2893. {
  2894. /* reloc table */
  2895. unsigned short off; unsigned char *offp=ext+codeOff;
  2896. while ((off=g16(offp))) {
  2897. rt_add_ref(&reloc_tab,off+wriOff);
  2898. add_offs(wriOff+2,off+wriOff+2);
  2899. }
  2900. {
  2901. /* export table */
  2902. unsigned char *strp=end_of(offp);
  2903. while ((off=g16(offp))) {
  2904. set_label(label(strp),off+wriOff);
  2905. while (*strp++);
  2906. }
  2907. align(strp);
  2908. /* import table */
  2909. offp=strp; strp=end_of2(offp);
  2910. while (*(short *)offp) {
  2911. int n=label(lexpand(strp)); unsigned int p=lab_src(n);
  2912. while ((off=g16(offp))) {
  2913. off+=wriOff;
  2914. if (p) {
  2915. #ifdef PC
  2916. unsigned short a=bin[off+2]<<8;
  2917. a+=bin[off+3];
  2918. a+=p;
  2919. bin[off+2]=(unsigned char)(a>>8);
  2920. bin[off+3]=(unsigned char)(a);
  2921. #else
  2922. *(short *)(bin+off+2)+=p;
  2923. #endif
  2924. /* if (ip->sz==2)
  2925. wrt2(code|=(f-vpos)&0xFF);
  2926. else wrt2(code),wrt2((short)(f-vpos));*/
  2927. } else
  2928. lab_add_ref(n,off+2);
  2929. rt_add_ref(&reloc_tab,off);
  2930. }
  2931. while (*strp++);
  2932. }
  2933. }
  2934. }
  2935. }
  2936. #endif
  2937. #endif /* MC680X0 */
  2938. // vim:ts=4:sw=4