PageRenderTime 273ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/syntax/std/syntax.c

https://github.com/ezrec/vasm
C | 1196 lines | 1042 code | 130 blank | 24 comment | 188 complexity | 50a06fc73ae268d3f36be6184189e53b MD5 | raw file
  1. /* syntax.c syntax module for vasm */
  2. /* (c) in 2002-2010 by Volker Barthelmann and Frank Wille */
  3. #include "vasm.h"
  4. /* The syntax module parses the input (read_next_line), handles
  5. assembly-directives (section, data-storage etc.) and parses
  6. mnemonics. Assembly instructions are split up in mnemonic name,
  7. qualifiers and operands. new_inst returns a matching instruction,
  8. if one exists.
  9. Routines for creating sections and adding atoms to sections will
  10. be provided by the main module.
  11. */
  12. char *syntax_copyright="vasm std syntax module 3.6c (c) 2002-2010 Volker Barthelmann";
  13. static hashtable *dirhash;
  14. #if defined(VASM_CPU_C16X) || defined(VASM_CPU_M68K) || defined(VASM_CPU_650X) || defined(VASM_CPU_ARM) || defined(VASM_CPU_Z80)
  15. char commentchar=';';
  16. #else
  17. char commentchar='#';
  18. #endif
  19. char *defsectname = NULL;
  20. char *defsecttype = NULL;
  21. static int nodotneeded=0;
  22. static int alloccommon=0;
  23. static taddr sdlimit=-1; /* max size of common data in .sbss section */
  24. static char *textname=".text",*textattr="acrx";
  25. static char *dataname=".data",*dataattr="adrw";
  26. static char *sdataname=".sdata",*sdataattr="adrw";
  27. static char *sdata2name=".sdata2",*sdata2attr="adr";
  28. static char *rodataname=".rodata",*rodataattr="adr";
  29. static char *bssname=".bss",*bssattr="aurw";
  30. static char *sbssname=".sbss",*sbssattr="aurw";
  31. static char *tocdname=".tocd",*tocdattr="adrw";
  32. static char *stabname=".stab",*stabattr="dr";
  33. static char *stabstrname=".stabstr",*stabstrattr="dr";
  34. #define MAXCONDLEV 63
  35. static char cond[MAXCONDLEV+1];
  36. static int clev,ifnesting;
  37. #define LOCAL (RSRVD_S<<0) /* symbol flag for local binding */
  38. char *skip(char *s)
  39. {
  40. while (isspace((unsigned char )*s))
  41. s++;
  42. return s;
  43. }
  44. /* check for end of line, issue error, if not */
  45. void eol(char *s)
  46. {
  47. s = skip(s);
  48. if (*s!='\0' && *s!=commentchar)
  49. syntax_error(6);
  50. }
  51. char *skip_operand(char *s)
  52. {
  53. int par_cnt=0;
  54. char c;
  55. while(1){
  56. c = *s;
  57. if(START_PARENTH(c)) par_cnt++;
  58. if(END_PARENTH(c)){
  59. if(par_cnt>0)
  60. par_cnt--;
  61. else
  62. syntax_error(3);
  63. }
  64. if(!c||c==commentchar||(c==','&&par_cnt==0))
  65. break;
  66. s++;
  67. }
  68. if(par_cnt!=0)
  69. syntax_error(4);
  70. return s;
  71. }
  72. static void prident(char *p,int len)
  73. {
  74. int olen=len;
  75. while(len--)
  76. putchar(*p++);
  77. printf("(len=%d)",olen);
  78. }
  79. static taddr comma_constexpr(char **s)
  80. {
  81. *s = skip(*s);
  82. if (**s == ',') {
  83. *s = skip(*s + 1);
  84. return parse_constexpr(s);
  85. }
  86. syntax_error(9); /* comma expected */
  87. return 0;
  88. }
  89. static void add_const_datadef(section *s,taddr val,int size,int align)
  90. {
  91. char buf[32];
  92. int len;
  93. operand *op;
  94. if (size <= 32) {
  95. len = sprintf(buf,"%ld",(long)val);
  96. op = new_operand();
  97. if (parse_operand(buf,len,op,DATA_OPERAND(size))) {
  98. atom *a = new_datadef_atom(size,op);
  99. a->align = align;
  100. add_atom(s,a);
  101. }
  102. else
  103. syntax_error(8);
  104. }
  105. else
  106. ierror(0);
  107. }
  108. static void handle_section(char *s)
  109. {
  110. char *name,*attr;
  111. if(!(name=parse_name(&s)))
  112. return;
  113. if(*s==','){
  114. s=skip(s+1);
  115. attr=s;
  116. if(*s!='\"')
  117. syntax_error(7);
  118. else
  119. s++;
  120. attr=s;
  121. while(*s&&*s!='\"')
  122. s++;
  123. attr=cnvstr(attr,s-attr);
  124. s=skip(s+1);
  125. }else{
  126. attr="";
  127. if(!strcmp(name,textname)) attr=textattr;
  128. if(!strcmp(name,dataname)) attr=dataattr;
  129. if(!strcmp(name,sdataname)) attr=sdataattr;
  130. if(!strcmp(name,sdata2name)) attr=sdata2attr;
  131. if(!strcmp(name,rodataname)) attr=rodataattr;
  132. if(!strcmp(name,bssname)) attr=bssattr;
  133. if(!strcmp(name,sbssname)) attr=sbssattr;
  134. if(!strcmp(name,tocdname)) attr=tocdattr;
  135. }
  136. new_section(name,attr,1);
  137. switch_section(name,attr);
  138. eol(s);
  139. }
  140. static void handle_org(char *s)
  141. {
  142. if (*s == current_pc_char) { /* "* = * + <expr>" reserves bytes */
  143. s = skip(s+1);
  144. if (*s == '+') {
  145. add_atom(0,new_space_atom(parse_expr_tmplab(&s),1,0));
  146. }
  147. else {
  148. syntax_error(18); /* syntax error */
  149. return;
  150. }
  151. }
  152. else {
  153. new_org(parse_constexpr(&s));
  154. }
  155. eol(s);
  156. }
  157. static void handle_file(char *s)
  158. {
  159. char *name;
  160. if(*s!='\"'){
  161. syntax_error(7);
  162. return;
  163. }
  164. name=++s;
  165. while(*s&&*s!='\"')
  166. s++;
  167. if(*s!='\"')
  168. syntax_error(7);
  169. name=cnvstr(name,s-name);
  170. setfilename(name);
  171. eol(++s);
  172. }
  173. static int oplen(char *e,char *s)
  174. {
  175. while(s!=e&&isspace((unsigned char)e[-1]))
  176. e--;
  177. return e-s;
  178. }
  179. static void handle_data(char *s,int size,int noalign)
  180. {
  181. for (;;) {
  182. char *opstart = s;
  183. operand *op;
  184. dblock *db = NULL;
  185. if ((size==8 || size==16) && *s=='\"') {
  186. if (db = parse_string(&opstart,*s,size)) {
  187. add_atom(0,new_data_atom(db,1));
  188. s = opstart;
  189. }
  190. }
  191. if (!db) {
  192. op = new_operand();
  193. s = skip_operand(s);
  194. if (parse_operand(opstart,s-opstart,op,DATA_OPERAND(size))) {
  195. atom *a;
  196. a = new_datadef_atom(size,op);
  197. if (noalign)
  198. a->align=1;
  199. add_atom(0,a);
  200. }
  201. else
  202. syntax_error(8); /* invalid data operand */
  203. }
  204. s = skip(s);
  205. if (*s == ',') {
  206. s = skip(s+1);
  207. }
  208. else if (*s==commentchar)
  209. break;
  210. else if (*s) {
  211. syntax_error(9); /* , expected */
  212. return;
  213. }
  214. else
  215. break;
  216. }
  217. eol(s);
  218. }
  219. static void handle_equ(char *s)
  220. {
  221. char *labname;
  222. symbol *label;
  223. if(!(labname=parse_identifier(&s))){
  224. syntax_error(10); /* identifier expected */
  225. return;
  226. }
  227. s=skip(s);
  228. if(*s!=',')
  229. syntax_error(9);
  230. else
  231. s=skip(s+1);
  232. label=new_abs(labname,parse_expr_tmplab(&s));
  233. myfree(labname);
  234. eol(s);
  235. }
  236. static char *get_bind_name(symbol *s)
  237. {
  238. if(s->flags&EXPORT)
  239. return "global";
  240. else if(s->flags&WEAK)
  241. return "weak";
  242. else if(s->flags&LOCAL)
  243. return "local";
  244. return "unknown";
  245. }
  246. static void do_binding(char *s,int bind)
  247. {
  248. symbol *sym;
  249. char *name;
  250. while(1){
  251. if(!(name=parse_identifier(&s))){
  252. syntax_error(10); /* identifier expected */
  253. return;
  254. }
  255. sym=new_import(name);
  256. myfree(name);
  257. if(sym->flags&(EXPORT|WEAK|LOCAL)!=0 &&
  258. sym->flags&(EXPORT|WEAK|LOCAL)!=bind)
  259. syntax_error(20,sym->name,get_bind_name(sym)); /* binding already set */
  260. else
  261. sym->flags|=bind;
  262. s=skip(s);
  263. if(*s!=',')
  264. break;
  265. s=skip(s+1);
  266. }
  267. eol(s);
  268. }
  269. static void handle_global(char *s)
  270. {
  271. do_binding(s,EXPORT);
  272. }
  273. static void handle_weak(char *s)
  274. {
  275. do_binding(s,WEAK);
  276. }
  277. static void handle_local(char *s)
  278. {
  279. do_binding(s,LOCAL);
  280. }
  281. static void do_align(taddr align,expr *fill,taddr max)
  282. /* @@@ 'max' alignment is not really supported at the moment */
  283. {
  284. atom *a = new_space_atom(number_expr(0),1,fill);
  285. a->align = align;
  286. add_atom(0,a);
  287. }
  288. static void alignment(char *s,int mode)
  289. {
  290. int align,max=0;
  291. expr *fill=0;
  292. align = parse_constexpr(&s);
  293. s = skip(s);
  294. if (*s == ',') {
  295. s = skip(s+1);
  296. if (*s != ',')
  297. fill = parse_expr_tmplab(&s);
  298. s = skip(s);
  299. if (*s == ',') {
  300. s = skip(s+1);
  301. max = parse_constexpr(&s);
  302. }
  303. }
  304. if (!mode)
  305. mode = CPU_DEF_ALIGN;
  306. do_align(mode==1?align:(1<<align),fill,max);
  307. eol(s);
  308. }
  309. static void handle_align(char *s)
  310. {
  311. alignment(s,0);
  312. }
  313. static void handle_balign(char *s)
  314. {
  315. alignment(s,1);
  316. }
  317. static void handle_p2align(char *s)
  318. {
  319. alignment(s,2);
  320. }
  321. static void handle_space(char *s)
  322. {
  323. expr *space = parse_expr_tmplab(&s);
  324. expr *fill = 0;
  325. s = skip(s);
  326. if (*s == ',') {
  327. s = skip(s+1);
  328. fill = parse_expr_tmplab(&s);
  329. }
  330. add_atom(0,new_space_atom(space,1,fill));
  331. eol(s);
  332. }
  333. static void handle_size(char *s)
  334. {
  335. char *name;
  336. symbol *sym;
  337. if(!(name=parse_identifier(&s))){
  338. syntax_error(10); /* identifier expected */
  339. return;
  340. }
  341. sym=new_import(name);
  342. myfree(name);
  343. s=skip(s);
  344. if(*s==',')
  345. s=skip(s+1);
  346. else
  347. syntax_error(9);
  348. sym->size=parse_expr_tmplab(&s);
  349. eol(s);
  350. }
  351. static void handle_type(char *s)
  352. {
  353. char *name;
  354. symbol *sym;
  355. if(!(name=parse_identifier(&s))){
  356. syntax_error(10); /* identifier expected */
  357. return;
  358. }
  359. sym=new_import(name);
  360. myfree(name);
  361. s=skip(s);
  362. if(*s==',')
  363. s=skip(s+1);
  364. else
  365. syntax_error(9);
  366. if(!strncmp(s,"@object",7)){
  367. sym->flags|=TYPE_OBJECT;
  368. s=skip(s+7);
  369. }else if(!strncmp(s,"@function",9)){
  370. sym->flags|=TYPE_FUNCTION;
  371. s=skip(s+9);
  372. }else
  373. sym->flags|=parse_constexpr(&s);
  374. eol(s);
  375. }
  376. static void new_bss(char *s,int global)
  377. {
  378. char *name;
  379. symbol *sym;
  380. atom *a;
  381. taddr size;
  382. section *bss;
  383. if(!(name=parse_identifier(&s))){
  384. syntax_error(10); /* identifier expected */
  385. return;
  386. }
  387. size=comma_constexpr(&s);
  388. if(size<=sdlimit){
  389. if(!(bss=find_section(sbssname,sbssattr)))
  390. bss=new_section(sbssname,sbssattr,1);
  391. }
  392. else{
  393. if(!(bss=find_section(bssname,bssattr)))
  394. bss=new_section(bssname,bssattr,1);
  395. }
  396. sym=new_labsym(bss,name);
  397. sym->flags|=TYPE_OBJECT;
  398. if(global) sym->flags|=EXPORT;
  399. sym->size=number_expr(size);
  400. myfree(name);
  401. s=skip(s);
  402. if(*s==','){
  403. s=skip(s+1);
  404. sym->align=parse_constexpr(&s);
  405. }
  406. else
  407. sym->align=(size>=8)?8:4;
  408. a=new_label_atom(sym);
  409. if(sym->align)
  410. a->align=sym->align;
  411. add_atom(bss,a);
  412. a=new_space_atom(number_expr(size),1,0);
  413. if(sym->align)
  414. a->align=sym->align;
  415. add_atom(bss,a);
  416. eol(s);
  417. }
  418. static void handle_comm(char *s)
  419. {
  420. char *name;
  421. symbol *sym;
  422. if (alloccommon){
  423. new_bss(s,1);
  424. return;
  425. }
  426. if(!(name=parse_identifier(&s))){
  427. syntax_error(10); /* identifier expected */
  428. return;
  429. }
  430. sym=new_import(name);
  431. myfree(name);
  432. s=skip(s);
  433. if(*s==',')
  434. s=skip(s+1);
  435. else
  436. syntax_error(9);
  437. if (!(sym->size=parse_expr(&s)))
  438. return;
  439. simplify_expr(sym->size);
  440. if(sym->size->type!=NUM){
  441. syntax_error(12);
  442. return;
  443. }
  444. sym->flags|=COMMON|TYPE_OBJECT;
  445. s=skip(s);
  446. if(*s==','){
  447. s=skip(s+1);
  448. sym->align=parse_constexpr(&s);
  449. }
  450. else
  451. sym->align=(sym->size->c.val>=8)?8:4;
  452. eol(s);
  453. }
  454. static void handle_lcomm(char *s)
  455. {
  456. new_bss(s,0);
  457. }
  458. static taddr new_stabstr(char *name)
  459. {
  460. section *str;
  461. taddr index;
  462. dblock *db;
  463. if (!(str = find_section(stabstrname,stabstrattr)))
  464. ierror(0);
  465. index = str->pc;
  466. db = new_dblock();
  467. db->size = strlen(name) + 1;
  468. db->data = name;
  469. add_atom(str,new_data_atom(db,1));
  470. return index;
  471. }
  472. static void stab_entry(char *name,int type,int othr,int desc,char *s)
  473. {
  474. section *stabs;
  475. if (!(stabs = find_section(stabname,stabattr))) {
  476. section *str;
  477. dblock *db;
  478. stabs = new_section(stabname,stabattr,4);
  479. if (!(str = find_section(stabstrname,stabstrattr))) {
  480. str = new_section(stabstrname,stabstrattr,1);
  481. }
  482. else {
  483. if (str->pc != 0)
  484. ierror(0);
  485. }
  486. /* first byte of .stabstr is 0 */
  487. add_atom(str,new_space_atom(number_expr(1),1,0));
  488. /* compilation unit header has to be patched by output module */
  489. new_stabstr(getfilename());
  490. db = new_dblock();
  491. db->size = 12;
  492. db->data = mymalloc(12);
  493. add_atom(stabs,new_data_atom(db,1));
  494. }
  495. add_const_datadef(stabs,name?new_stabstr(name):0,32,1);
  496. add_const_datadef(stabs,type,8,1);
  497. add_const_datadef(stabs,othr,8,1);
  498. add_const_datadef(stabs,desc,16,1);
  499. if (s) {
  500. operand *op = new_operand();
  501. int len = oplen(skip_operand(s),s);
  502. if (parse_operand(s,len,op,DATA_OPERAND(32))) {
  503. atom *a = new_datadef_atom(32,op);
  504. a->align = 1;
  505. add_atom(stabs,a);
  506. }
  507. else
  508. syntax_error(8);
  509. }
  510. else
  511. add_atom(stabs,new_space_atom(number_expr(4),1,0)); /* no value */
  512. }
  513. static void handle_stabs(char *s)
  514. {
  515. char *name;
  516. int t,o,d;
  517. if (*s++ == '\"') {
  518. name = s;
  519. while (*s && *s!='\"')
  520. s++;
  521. name = cnvstr(name,s-name);
  522. }
  523. else {
  524. syntax_error(7); /* " expected */
  525. return;
  526. }
  527. s++;
  528. t = comma_constexpr(&s);
  529. o = comma_constexpr(&s);
  530. d = comma_constexpr(&s);
  531. s = skip(s);
  532. if (*s == ',') {
  533. s = skip(s+1);
  534. stab_entry(name,t,o,d,s);
  535. s = skip_operand(s);
  536. }
  537. else
  538. syntax_error(9);
  539. eol(s);
  540. }
  541. static void handle_stabn(char *s)
  542. {
  543. int t,o,d;
  544. t = parse_constexpr(&s);
  545. o = comma_constexpr(&s);
  546. d = comma_constexpr(&s);
  547. s = skip(s);
  548. if (*s == ',') {
  549. s = skip(s+1);
  550. stab_entry(NULL,t,o,d,s);
  551. s = skip_operand(s);
  552. }
  553. else
  554. syntax_error(9);
  555. eol(s);
  556. }
  557. static void handle_stabd(char *s)
  558. {
  559. int t,o,d;
  560. t = parse_constexpr(&s);
  561. o = comma_constexpr(&s);
  562. d = comma_constexpr(&s);
  563. stab_entry(NULL,t,o,d,NULL);
  564. eol(s);
  565. }
  566. static void handle_incdir(char *s)
  567. {
  568. char *name;
  569. if (name = parse_name(&s))
  570. new_include_path(name);
  571. eol(s);
  572. }
  573. static void handle_include(char *s)
  574. {
  575. char *name;
  576. if (name = parse_name(&s)) {
  577. eol(s);
  578. include_source(name);
  579. }
  580. }
  581. static void handle_incbin(char *s)
  582. {
  583. char *name;
  584. if (name = parse_name(&s)) {
  585. eol(s);
  586. include_binary_file(name);
  587. }
  588. }
  589. static void handle_rept(char *s)
  590. {
  591. taddr cnt = parse_constexpr(&s);
  592. eol(s);
  593. new_repeat((int)cnt,nodotneeded?"rept":".rept",nodotneeded?"endr":".endr");
  594. }
  595. static void handle_endr(char *s)
  596. {
  597. syntax_error(19); /* unexpected endr without rept */
  598. }
  599. static void handle_macro(char *s)
  600. {
  601. char *name;
  602. if (name = parse_identifier(&s)) {
  603. eol(s);
  604. new_macro(name,nodotneeded ?"endm":".endm");
  605. myfree(name);
  606. }
  607. else
  608. syntax_error(10); /* identifier expected */
  609. }
  610. static void handle_endm(char *s)
  611. {
  612. syntax_error(13); /* unexpected endm without macro */
  613. }
  614. static void ifdef(char *s,int b)
  615. {
  616. char *name;
  617. symbol *sym;
  618. int result;
  619. if (!(name = get_local_label(&s))) {
  620. if (!(name = parse_identifier(&s))) {
  621. syntax_error(10); /* identifier expected */
  622. return;
  623. }
  624. }
  625. if (sym = find_symbol(name))
  626. result = sym->type != IMPORT;
  627. else
  628. result = 0;
  629. myfree(name);
  630. cond[++clev] = result == b;
  631. eol(s);
  632. }
  633. static void handle_ifd(char *s)
  634. {
  635. ifdef(s,1);
  636. }
  637. static void handle_ifnd(char *s)
  638. {
  639. ifdef(s,0);
  640. }
  641. static void ifexp(char *s,int c)
  642. {
  643. taddr val = parse_constexpr(&s);
  644. int b;
  645. switch (c) {
  646. case 0: b = val == 0; break;
  647. case 1: b = val != 0; break;
  648. case 2: b = val > 0; break;
  649. case 3: b = val >= 0; break;
  650. case 4: b = val < 0; break;
  651. case 5: b = val <= 0; break;
  652. default: ierror(0); break;
  653. }
  654. cond[++clev] = b;
  655. eol(s);
  656. }
  657. static void handle_ifeq(char *s)
  658. {
  659. ifexp(s,0);
  660. }
  661. static void handle_ifne(char *s)
  662. {
  663. ifexp(s,1);
  664. }
  665. static void handle_ifgt(char *s)
  666. {
  667. ifexp(s,2);
  668. }
  669. static void handle_ifge(char *s)
  670. {
  671. ifexp(s,3);
  672. }
  673. static void handle_iflt(char *s)
  674. {
  675. ifexp(s,4);
  676. }
  677. static void handle_ifle(char *s)
  678. {
  679. ifexp(s,5);
  680. }
  681. static void handle_else(char *s)
  682. {
  683. eol(s);
  684. if (clev > 0)
  685. cond[clev] = 0;
  686. else
  687. syntax_error(17); /* else without if */
  688. }
  689. static void handle_endif(char *s)
  690. {
  691. eol(s);
  692. if (clev > 0)
  693. clev--;
  694. else
  695. syntax_error(14); /* endif without if */
  696. }
  697. static void handle_bsss(char *s)
  698. {
  699. s = skip(s);
  700. if (*s!=0 && *s!=commentchar) {
  701. new_bss(s,0);
  702. }
  703. else {
  704. handle_section(bssname);
  705. eol(s);
  706. }
  707. }
  708. static void handle_8bit(char *s){ handle_data(s,8,0); }
  709. static void handle_16bit(char *s){ handle_data(s,16,0); }
  710. static void handle_32bit(char *s){ handle_data(s,32,0); }
  711. static void handle_64bit(char *s){ handle_data(s,64,0); }
  712. static void handle_16bit_noalign(char *s){ handle_data(s,16,1); }
  713. static void handle_32bit_noalign(char *s){ handle_data(s,32,1); }
  714. static void handle_64bit_noalign(char *s){ handle_data(s,64,1); }
  715. #if VASM_CPU_OIL
  716. static void handle_string(char *s){ handle_data(s,8,0); }
  717. #else
  718. static void handle_string(char *s)
  719. {
  720. handle_data(s,8,0);
  721. add_atom(0,new_space_atom(number_expr(1),1,0)); /* terminating zero */
  722. }
  723. #endif
  724. static void handle_texts(char *s){ handle_section(textname);eol(s);}
  725. static void handle_datas(char *s){ handle_section(dataname);eol(s);}
  726. static void handle_sdatas(char *s){ handle_section(sdataname);eol(s);}
  727. static void handle_sdata2s(char *s){ handle_section(sdata2name);eol(s);}
  728. static void handle_rodatas(char *s){ handle_section(rodataname);eol(s);}
  729. static void handle_sbsss(char *s){ handle_section(sbssname);eol(s);}
  730. static void handle_tocds(char *s){ handle_section(tocdname);eol(s);}
  731. static void handle_title(char *s)
  732. {
  733. char *t;
  734. s=skip(s);
  735. if(*s!='\"')
  736. syntax_error(7);
  737. else
  738. s++;
  739. t=s;
  740. while(*s&&*s!='\"')
  741. s++;
  742. set_list_title(t,s-t);
  743. if(*s!='\"')
  744. syntax_error(7);
  745. else
  746. s++;
  747. eol(s);
  748. }
  749. static void handle_ident(char *s)
  750. {
  751. char *name;
  752. if(name=parse_name(&s))
  753. setfilename(name);
  754. eol(s);
  755. }
  756. struct {
  757. char *name;
  758. void (*func)(char *);
  759. } directives[]={
  760. "org",handle_org,
  761. "section",handle_section,
  762. "string",handle_string,
  763. "byte",handle_8bit,
  764. "ascii",handle_8bit,
  765. "asciz",handle_string,
  766. "short",handle_16bit,
  767. "half",handle_16bit,
  768. "word",handle_32bit,
  769. "int",handle_32bit,
  770. "long",handle_32bit,
  771. "quad",handle_64bit,
  772. "2byte",handle_16bit_noalign,
  773. "uahalf",handle_16bit_noalign,
  774. "4byte",handle_32bit_noalign,
  775. "uaword",handle_32bit_noalign,
  776. "ualong",handle_32bit_noalign,
  777. "8byte",handle_64bit_noalign,
  778. "uaquad",handle_64bit_noalign,
  779. "text",handle_texts,
  780. "data",handle_datas,
  781. "bss",handle_bsss,
  782. "rodata",handle_rodatas,
  783. "sdata",handle_sdatas,
  784. "sdata2",handle_sdata2s,
  785. "sbss",handle_sbsss,
  786. "tocd",handle_tocds,
  787. "equ",handle_equ,
  788. "set",handle_equ,
  789. "global",handle_global,
  790. "globl",handle_global,
  791. "extern",handle_global,
  792. "weak",handle_weak,
  793. "local",handle_local,
  794. "align",handle_align,
  795. "balign",handle_balign,
  796. "p2align",handle_p2align,
  797. "space",handle_space,
  798. "skip",handle_space,
  799. "comm",handle_comm,
  800. "lcomm",handle_lcomm,
  801. "size",handle_size,
  802. "type",handle_type,
  803. "file",handle_file,
  804. "stabs",handle_stabs,
  805. "stabn",handle_stabn,
  806. "stabd",handle_stabd,
  807. "incdir",handle_incdir,
  808. "include",handle_include,
  809. "incbin",handle_incbin,
  810. "rept",handle_rept,
  811. "endr",handle_endr,
  812. "macro",handle_macro,
  813. "endm",handle_endm,
  814. "ifdef",handle_ifd,
  815. "ifndef",handle_ifnd,
  816. "if",handle_ifne,
  817. "ifeq",handle_ifeq,
  818. "ifne",handle_ifne,
  819. "ifgt",handle_ifgt,
  820. "ifge",handle_ifge,
  821. "iflt",handle_iflt,
  822. "ifle",handle_ifle,
  823. "else",handle_else,
  824. "endif",handle_endif,
  825. "title",handle_title,
  826. "ident",handle_ident,
  827. };
  828. int dir_cnt=sizeof(directives)/sizeof(directives[0]);
  829. /* checks for a valid directive, and return index when found, -1 otherwise */
  830. static int check_directive(char **line)
  831. {
  832. char *s,*name;
  833. hashdata data;
  834. s = skip(*line);
  835. if (!ISIDSTART(*s))
  836. return -1;
  837. name = s++;
  838. while (ISIDCHAR(*s))
  839. s++;
  840. if (*name == '.')
  841. name++;
  842. else if (!nodotneeded)
  843. return -1;
  844. if (!find_namelen(dirhash,name,s-name,&data))
  845. return -1;
  846. *line = s;
  847. return data.idx;
  848. }
  849. /* Handles assembly directives; returns non-zero if the line
  850. was a directive. */
  851. static int handle_directive(char *line)
  852. {
  853. int idx = check_directive(&line);
  854. if (idx >= 0) {
  855. directives[idx].func(skip(line));
  856. return 1;
  857. }
  858. return 0;
  859. }
  860. void parse(void)
  861. {
  862. char *s,*line,*ext[MAX_QUALIFIERS?MAX_QUALIFIERS:1],*op[MAX_OPERANDS];
  863. char *labname,*start;
  864. int inst_len,ext_len[MAX_QUALIFIERS?MAX_QUALIFIERS:1],op_len[MAX_OPERANDS];
  865. int ext_cnt,op_cnt;
  866. instruction *ip;
  867. while (line=read_next_line()){
  868. if (clev >= MAXCONDLEV)
  869. syntax_error(16,clev); /* nesting depth exceeded */
  870. if (!cond[clev]) {
  871. /* skip source until ELSE or ENDIF */
  872. int idx;
  873. s = line;
  874. idx = check_directive(&s);
  875. if (idx >= 0) {
  876. if (!strncmp(directives[idx].name,"if",2)) {
  877. ifnesting++;
  878. }
  879. else if (ifnesting==0 && !strncmp(directives[idx].name,"else",4)) {
  880. cond[clev] = 1;
  881. }
  882. else if (directives[idx].func == handle_endif) {
  883. if (ifnesting == 0) {
  884. if (clev > 0)
  885. clev--;
  886. else
  887. syntax_error(14); /* endif without if */
  888. }
  889. else
  890. ifnesting--;
  891. }
  892. }
  893. continue;
  894. }
  895. s=skip(line);
  896. if(handle_directive(s))
  897. continue;
  898. /* skip spaces */
  899. s=skip(s);
  900. if(!*s||*s==commentchar)
  901. continue;
  902. /* check for label */
  903. start=s;
  904. if(labname=get_local_label(&s)){ /* local label? */
  905. if(*s!=':'){
  906. s=start;
  907. myfree(labname);
  908. labname=NULL;
  909. }
  910. }
  911. else if(ISIDSTART(*s)){ /* or global label? */
  912. s++;
  913. while(ISIDCHAR(*s)) s++;
  914. if(*s!=':')
  915. s=start;
  916. else
  917. labname=cnvstr(start,s-start);
  918. }
  919. if(labname){
  920. /* we have found a valid global or local label */
  921. add_atom(0,new_label_atom(new_labsym(0,labname)));
  922. s=skip(s+1);
  923. myfree(labname);
  924. }
  925. if(!*s||*s==commentchar)
  926. continue;
  927. s=skip(parse_cpu_special(s));
  928. if(*s==0||*s==commentchar)
  929. continue;
  930. if(handle_directive(s))
  931. continue;
  932. /* read mnemonic name */
  933. start=s;
  934. ext_cnt=0;
  935. if(!ISIDSTART(*s)){
  936. syntax_error(10);
  937. continue;
  938. }
  939. #if MAX_QUALIFIERS==0
  940. while(*s&&!isspace((unsigned char)*s))
  941. s++;
  942. inst_len=s-start;
  943. #else
  944. s=parse_instruction(s,&inst_len,ext,ext_len,&ext_cnt);
  945. #endif
  946. s=skip(s);
  947. if(execute_macro(start,inst_len,ext,ext_len,ext_cnt,s,clev))
  948. continue;
  949. /* read operands, terminated by comma (unless in parentheses) */
  950. op_cnt=0;
  951. while(*s&&*s!=commentchar&&op_cnt<MAX_OPERANDS){
  952. op[op_cnt]=s;
  953. s=skip_operand(s);
  954. op_len[op_cnt]=oplen(s,op[op_cnt]);
  955. #if !ALLOW_EMPTY_OPS
  956. if(op_len[op_cnt]<=0)
  957. syntax_error(5);
  958. else
  959. #endif
  960. op_cnt++;
  961. s=skip(s);
  962. if(*s!=','){
  963. break;
  964. }else{
  965. s=skip(s+1);
  966. }
  967. }
  968. s=skip(s);
  969. if(*s!=0&&*s!=commentchar) syntax_error(6);
  970. ip=new_inst(start,inst_len,op_cnt,op,op_len);
  971. #if MAX_QUALIFIERS>0
  972. if(ip){
  973. int i;
  974. for(i=0;i<ext_cnt;i++)
  975. ip->qualifiers[i]=cnvstr(ext[i],ext_len[i]);
  976. for(;i<MAX_QUALIFIERS;i++)
  977. ip->qualifiers[i]=0;
  978. }
  979. #endif
  980. if(ip){
  981. add_atom(0,new_inst_atom(ip));
  982. }else
  983. ;
  984. }
  985. if (clev > 0)
  986. syntax_error(15); /* if without endif */
  987. }
  988. char *const_prefix(char *s,int *base)
  989. {
  990. if(!isdigit((unsigned char)*s)){
  991. *base=0;
  992. return s;
  993. }
  994. if(*s=='0'){
  995. if(s[1]=='x'||s[1]=='X'){
  996. *base=16;
  997. return s+2;
  998. }
  999. if(s[1]=='b'||s[1]=='B'){
  1000. *base=2;
  1001. return s+2;
  1002. }
  1003. *base=8;
  1004. return s;
  1005. }
  1006. *base=10;
  1007. return s;
  1008. }
  1009. char *get_local_label(char **start)
  1010. /* local labels start with a '.' or end with '$': "1234$", ".1" */
  1011. {
  1012. char *s = *start;
  1013. char *name = NULL;
  1014. if (*s == '.') {
  1015. s++;
  1016. while (isdigit((unsigned char)*s) || *s=='_') /* '_' needed for '\@' */
  1017. s++;
  1018. if (s > (*start+1)) {
  1019. name = make_local_label(NULL,0,*start,s-*start);
  1020. *start = skip(s);
  1021. }
  1022. }
  1023. else {
  1024. while (isalnum((unsigned char)*s) || *s=='_') /* '_' needed for '\@' */
  1025. s++;
  1026. if (s!=*start && *s=='$') {
  1027. name = make_local_label(NULL,0,*start,s-*start);
  1028. *start = skip(++s);
  1029. }
  1030. }
  1031. return name;
  1032. }
  1033. int init_syntax()
  1034. {
  1035. size_t i;
  1036. hashdata data;
  1037. dirhash=new_hashtable(0x200); /*FIXME: */
  1038. for(i=0;i<dir_cnt;i++){
  1039. data.idx=i;
  1040. add_hashentry(dirhash,directives[i].name,data);
  1041. }
  1042. #if defined(VASM_CPU_X86)
  1043. current_pc_char = '.';
  1044. #endif
  1045. cond[0] = 1;
  1046. clev = ifnesting = 0;
  1047. return 1;
  1048. }
  1049. int syntax_args(char *p)
  1050. {
  1051. int i;
  1052. if (!strcmp(p,"-nodotneeded")) {
  1053. nodotneeded = 1;
  1054. return 1;
  1055. }
  1056. else if (!strcmp(p,"-ac")) {
  1057. alloccommon = 1;
  1058. return 1;
  1059. }
  1060. else if (!strncmp(p,"-sdlimit=",9)) {
  1061. i = atoi(p+9);
  1062. sdlimit = (i<=0) ? -1 : i;
  1063. return 1;
  1064. }
  1065. return 0;
  1066. }