nasm-parse.c 59 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680
  1. /*
  2. * NASM-compatible parser
  3. *
  4. * Copyright (C) 2001-2007 Peter Johnson, Michael Urman
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
  16. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  18. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
  19. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  20. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  21. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  22. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  23. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  24. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  25. * POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. #include <util.h>
  28. #include <libyasm.h>
  29. #include <math.h>
  30. #include "modules/parsers/nasm/nasm-parser.h"
  31. #include "modules/preprocs/nasm/nasm.h"
  32. typedef enum {
  33. NORM_EXPR,
  34. DIR_EXPR, /* Can't have seg:off or WRT anywhere */
  35. DV_EXPR /* Can't have registers anywhere */
  36. } expr_type;
  37. static yasm_bytecode *parse_line(yasm_parser_nasm *parser_nasm);
  38. static int parse_directive_valparams(yasm_parser_nasm *parser_nasm,
  39. /*@out@*/ yasm_valparamhead *vps);
  40. static yasm_bytecode *parse_times(yasm_parser_nasm *parser_nasm);
  41. static yasm_bytecode *parse_exp(yasm_parser_nasm *parser_nasm);
  42. static yasm_bytecode *parse_instr(yasm_parser_nasm *parser_nasm);
  43. static yasm_insn_operand *parse_operand(yasm_parser_nasm *parser_nasm);
  44. static yasm_insn_operand *parse_memaddr(yasm_parser_nasm *parser_nasm);
  45. static yasm_expr *parse_expr(yasm_parser_nasm *parser_nasm, expr_type type);
  46. static yasm_expr *parse_bexpr(yasm_parser_nasm *parser_nasm, expr_type type);
  47. static yasm_expr *parse_expr0(yasm_parser_nasm *parser_nasm, expr_type type);
  48. static yasm_expr *parse_expr1(yasm_parser_nasm *parser_nasm, expr_type type);
  49. static yasm_expr *parse_expr2(yasm_parser_nasm *parser_nasm, expr_type type);
  50. static yasm_expr *parse_expr3(yasm_parser_nasm *parser_nasm, expr_type type);
  51. static yasm_expr *parse_expr4(yasm_parser_nasm *parser_nasm, expr_type type);
  52. static yasm_expr *parse_expr5(yasm_parser_nasm *parser_nasm, expr_type type);
  53. static yasm_expr *parse_expr6(yasm_parser_nasm *parser_nasm, expr_type type);
  54. static void nasm_parser_directive
  55. (yasm_parser_nasm *parser_nasm, const char *name,
  56. /*@null@*/ yasm_valparamhead *valparams,
  57. /*@null@*/ yasm_valparamhead *objext_valparams);
  58. static void set_nonlocal_label(yasm_parser_nasm *parser_nasm, const char *name);
  59. static void define_label(yasm_parser_nasm *parser_nasm, /*@only@*/ char *name,
  60. unsigned int size);
  61. static void yasm_ea_set_implicit_size_segment(yasm_parser_nasm *parser_nasm,
  62. yasm_effaddr *ea, yasm_expr *e)
  63. {
  64. if (parser_nasm->tasm) {
  65. const char *segment = yasm_expr_segment(e);
  66. ea->data_len = yasm_expr_size(e);
  67. if (segment) {
  68. const char *segreg = tasm_get_segment_register(segment);
  69. if (segreg)
  70. yasm_arch_parse_check_regtmod(p_object->arch, segreg,
  71. strlen(segreg), &ea->segreg);
  72. }
  73. }
  74. }
  75. #define is_eol_tok(tok) ((tok) == 0)
  76. #define is_eol() is_eol_tok(curtok)
  77. #define get_next_token() (curtok = nasm_parser_lex(&curval, parser_nasm))
  78. static void
  79. get_peek_token(yasm_parser_nasm *parser_nasm)
  80. {
  81. char savech = parser_nasm->tokch;
  82. if (parser_nasm->peek_token != NONE)
  83. yasm_internal_error(N_("only can have one token of lookahead"));
  84. parser_nasm->peek_token =
  85. nasm_parser_lex(&parser_nasm->peek_tokval, parser_nasm);
  86. parser_nasm->peek_tokch = parser_nasm->tokch;
  87. parser_nasm->tokch = savech;
  88. }
  89. static void
  90. destroy_curtok_(yasm_parser_nasm *parser_nasm)
  91. {
  92. if (curtok < 256)
  93. ;
  94. else switch ((enum tokentype)curtok) {
  95. case INTNUM:
  96. yasm_intnum_destroy(curval.intn);
  97. break;
  98. case FLTNUM:
  99. yasm_floatnum_destroy(curval.flt);
  100. break;
  101. case DIRECTIVE_NAME:
  102. case FILENAME:
  103. case ID:
  104. case LOCAL_ID:
  105. case SPECIAL_ID:
  106. case NONLOCAL_ID:
  107. yasm_xfree(curval.str_val);
  108. break;
  109. case STRING:
  110. yasm_xfree(curval.str.contents);
  111. break;
  112. case INSN:
  113. yasm_bc_destroy(curval.bc);
  114. break;
  115. default:
  116. break;
  117. }
  118. curtok = NONE; /* sanity */
  119. }
  120. #define destroy_curtok() destroy_curtok_(parser_nasm)
  121. /* Eat all remaining tokens to EOL, discarding all of them. If there's any
  122. * intervening tokens, generates an error (junk at end of line).
  123. */
  124. static void
  125. demand_eol_(yasm_parser_nasm *parser_nasm)
  126. {
  127. if (is_eol())
  128. return;
  129. yasm_error_set(YASM_ERROR_SYNTAX,
  130. N_("junk at end of line, first unrecognized character is `%c'"),
  131. parser_nasm->tokch);
  132. do {
  133. destroy_curtok();
  134. get_next_token();
  135. } while (!is_eol());
  136. }
  137. #define demand_eol() demand_eol_(parser_nasm)
  138. static const char *
  139. describe_token(int token)
  140. {
  141. static char strch[] = "` '";
  142. const char *str;
  143. switch (token) {
  144. case 0: str = "end of line"; break;
  145. case INTNUM: str = "integer"; break;
  146. case FLTNUM: str = "floating point value"; break;
  147. case DIRECTIVE_NAME: str = "directive name"; break;
  148. case FILENAME: str = "filename"; break;
  149. case STRING: str = "string"; break;
  150. case SIZE_OVERRIDE: str = "size override"; break;
  151. case DECLARE_DATA: str = "DB/DW/etc."; break;
  152. case RESERVE_SPACE: str = "RESB/RESW/etc."; break;
  153. case INCBIN: str = "INCBIN"; break;
  154. case EQU: str = "EQU"; break;
  155. case TIMES: str = "TIMES"; break;
  156. case SEG: str = "SEG"; break;
  157. case WRT: str = "WRT"; break;
  158. case NOSPLIT: str = "NOSPLIT"; break;
  159. case STRICT: str = "STRICT"; break;
  160. case INSN: str = "instruction"; break;
  161. case PREFIX: str = "instruction prefix"; break;
  162. case REG: str = "register"; break;
  163. case REGGROUP: str = "register group"; break;
  164. case SEGREG: str = "segment register"; break;
  165. case TARGETMOD: str = "target modifier"; break;
  166. case LEFT_OP: str = "<<"; break;
  167. case RIGHT_OP: str = ">>"; break;
  168. case SIGNDIV: str = "//"; break;
  169. case SIGNMOD: str = "%%"; break;
  170. case START_SECTION_ID: str = "$$"; break;
  171. case ID: str = "identifier"; break;
  172. case LOCAL_ID: str = ".identifier"; break;
  173. case SPECIAL_ID: str = "..identifier"; break;
  174. case NONLOCAL_ID: str = "..@identifier"; break;
  175. case LINE: str = "%line"; break;
  176. default:
  177. strch[1] = token;
  178. str = strch;
  179. break;
  180. }
  181. return str;
  182. }
  183. static int
  184. expect_(yasm_parser_nasm *parser_nasm, int token)
  185. {
  186. if (curtok == token)
  187. return 1;
  188. yasm_error_set(YASM_ERROR_PARSE, "expected %s", describe_token(token));
  189. destroy_curtok();
  190. return 0;
  191. }
  192. #define expect(token) expect_(parser_nasm, token)
  193. void
  194. nasm_parser_parse(yasm_parser_nasm *parser_nasm)
  195. {
  196. unsigned char *line;
  197. while ((line = (unsigned char *)
  198. yasm_preproc_get_line(parser_nasm->preproc)) != NULL) {
  199. yasm_bytecode *bc = NULL, *temp_bc;
  200. parser_nasm->s.bot = line;
  201. parser_nasm->s.tok = line;
  202. parser_nasm->s.ptr = line;
  203. parser_nasm->s.cur = line;
  204. parser_nasm->s.lim = line + strlen((char *)line)+1;
  205. parser_nasm->s.top = parser_nasm->s.lim;
  206. get_next_token();
  207. if (!is_eol()) {
  208. bc = parse_line(parser_nasm);
  209. demand_eol();
  210. }
  211. if (parser_nasm->abspos) {
  212. /* If we're inside an absolute section, just add to the absolute
  213. * position rather than appending bytecodes to a section.
  214. * Only RES* are allowed in an absolute section, so this is easy.
  215. */
  216. if (bc) {
  217. /*@null@*/ const yasm_expr *numitems, *multiple;
  218. unsigned int itemsize;
  219. numitems = yasm_bc_reserve_numitems(bc, &itemsize);
  220. if (numitems) {
  221. yasm_expr *e;
  222. e = yasm_expr_create(YASM_EXPR_MUL,
  223. yasm_expr_expr(yasm_expr_copy(numitems)),
  224. yasm_expr_int(yasm_intnum_create_uint(itemsize)),
  225. cur_line);
  226. multiple = yasm_bc_get_multiple_expr(bc);
  227. if (multiple)
  228. e = yasm_expr_create_tree(e, YASM_EXPR_MUL,
  229. yasm_expr_copy(multiple),
  230. cur_line);
  231. parser_nasm->abspos = yasm_expr_create_tree(
  232. parser_nasm->abspos, YASM_EXPR_ADD, e, cur_line);
  233. } else
  234. yasm_error_set(YASM_ERROR_SYNTAX,
  235. N_("only RES* allowed within absolute section"));
  236. yasm_bc_destroy(bc);
  237. }
  238. temp_bc = NULL;
  239. } else if (bc) {
  240. temp_bc = yasm_section_bcs_append(cursect, bc);
  241. if (temp_bc)
  242. parser_nasm->prev_bc = temp_bc;
  243. } else
  244. temp_bc = NULL;
  245. yasm_errwarn_propagate(parser_nasm->errwarns, cur_line);
  246. if (parser_nasm->save_input)
  247. yasm_linemap_add_source(parser_nasm->linemap, temp_bc,
  248. (char *)line);
  249. yasm_linemap_goto_next(parser_nasm->linemap);
  250. yasm_xfree(line);
  251. }
  252. }
  253. /* All parse_* functions expect to be called with curtok being their first
  254. * token. They should return with curtok being the token *after* their
  255. * information.
  256. */
  257. static yasm_bytecode *
  258. parse_line(yasm_parser_nasm *parser_nasm)
  259. {
  260. yasm_bytecode *bc;
  261. bc = parse_exp(parser_nasm);
  262. if (bc)
  263. return bc;
  264. switch (curtok) {
  265. case LINE: /* LINE INTNUM '+' INTNUM FILENAME */
  266. {
  267. yasm_intnum *line, *incr;
  268. char *filename;
  269. get_next_token();
  270. if (!expect(INTNUM)) return NULL;
  271. line = INTNUM_val;
  272. get_next_token();
  273. if (!expect('+')) return NULL;
  274. get_next_token();
  275. if (!expect(INTNUM)) return NULL;
  276. incr = INTNUM_val;
  277. get_next_token();
  278. if (!expect(FILENAME)) return NULL;
  279. filename = FILENAME_val;
  280. get_next_token();
  281. /* %line indicates the line number of the *next* line, so subtract
  282. * out the increment when setting the line number.
  283. */
  284. yasm_linemap_set(parser_nasm->linemap, filename, 0,
  285. yasm_intnum_get_uint(line) - yasm_intnum_get_uint(incr),
  286. yasm_intnum_get_uint(incr));
  287. yasm_intnum_destroy(line);
  288. yasm_intnum_destroy(incr);
  289. yasm_xfree(filename);
  290. return NULL;
  291. }
  292. case '[': /* [ directive ] */
  293. {
  294. char *dirname;
  295. yasm_valparamhead dir_vps;
  296. int have_vps = 1;
  297. parser_nasm->state = DIRECTIVE;
  298. get_next_token();
  299. if (!expect(DIRECTIVE_NAME))
  300. return NULL;
  301. dirname = DIRECTIVE_NAME_val;
  302. get_next_token();
  303. /* ignore [warning]. TODO: actually implement */
  304. if (yasm__strcasecmp(dirname, "warning") == 0) {
  305. yasm_warn_set(YASM_WARN_GENERAL,
  306. N_("[warning] directive not supported; ignored"));
  307. /* throw away the rest of the directive tokens */
  308. while (!is_eol() && curtok != ']')
  309. {
  310. destroy_curtok();
  311. get_next_token();
  312. }
  313. expect(']');
  314. get_next_token();
  315. return NULL;
  316. }
  317. if (curtok == ']' || curtok == ':')
  318. have_vps = 0;
  319. else if (!parse_directive_valparams(parser_nasm, &dir_vps)) {
  320. yasm_error_set(YASM_ERROR_SYNTAX,
  321. N_("invalid arguments to [%s]"), dirname);
  322. yasm_xfree(dirname);
  323. return NULL;
  324. }
  325. if (curtok == ':') {
  326. yasm_valparamhead ext_vps;
  327. get_next_token();
  328. if (!parse_directive_valparams(parser_nasm, &ext_vps)) {
  329. yasm_error_set(YASM_ERROR_SYNTAX,
  330. N_("invalid arguments to [%s]"), dirname);
  331. yasm_xfree(dirname);
  332. return NULL;
  333. }
  334. nasm_parser_directive(parser_nasm, dirname,
  335. have_vps ? &dir_vps : NULL, &ext_vps);
  336. } else
  337. nasm_parser_directive(parser_nasm, dirname,
  338. have_vps ? &dir_vps : NULL, NULL);
  339. yasm_xfree(dirname);
  340. expect(']');
  341. get_next_token();
  342. return NULL;
  343. }
  344. case TIMES: /* TIMES expr exp */
  345. get_next_token();
  346. return parse_times(parser_nasm);
  347. case ID:
  348. case SPECIAL_ID:
  349. case NONLOCAL_ID:
  350. case LOCAL_ID:
  351. {
  352. char *name = ID_val;
  353. int local = parser_nasm->tasm
  354. ? (curtok == ID || curtok == LOCAL_ID ||
  355. (curtok == SPECIAL_ID && name[0] == '@'))
  356. : (curtok != ID);
  357. unsigned int size = 0;
  358. get_next_token();
  359. if (is_eol()) {
  360. /* label alone on the line */
  361. yasm_warn_set(YASM_WARN_ORPHAN_LABEL,
  362. N_("label alone on a line without a colon might be in error"));
  363. if (!local)
  364. set_nonlocal_label(parser_nasm, name);
  365. define_label(parser_nasm, name, 0);
  366. return NULL;
  367. }
  368. if (curtok == ':')
  369. get_next_token();
  370. if (curtok == EQU || (parser_nasm->tasm && curtok == '=')) {
  371. /* label EQU expr */
  372. yasm_expr *e;
  373. get_next_token();
  374. if (parser_nasm->tasm && curtok == SIZE_OVERRIDE) {
  375. size = SIZE_OVERRIDE_val;
  376. get_next_token();
  377. }
  378. e = parse_expr(parser_nasm, NORM_EXPR);
  379. if (!e) {
  380. yasm_error_set(YASM_ERROR_SYNTAX,
  381. N_("expression expected after %s"), "EQU");
  382. yasm_xfree(name);
  383. return NULL;
  384. }
  385. yasm_symtab_define_equ(p_symtab, name, e, cur_line);
  386. yasm_xfree(name);
  387. return NULL;
  388. }
  389. if (parser_nasm->tasm && curtok == LABEL)
  390. get_next_token();
  391. if (parser_nasm->tasm && curtok == SIZE_OVERRIDE) {
  392. size = SIZE_OVERRIDE_val;
  393. get_next_token();
  394. }
  395. if (!local)
  396. set_nonlocal_label(parser_nasm, name);
  397. if (is_eol()) {
  398. define_label(parser_nasm, name, size);
  399. return NULL;
  400. }
  401. if (curtok == TIMES) {
  402. define_label(parser_nasm, name, size);
  403. get_next_token();
  404. return parse_times(parser_nasm);
  405. }
  406. bc = parse_exp(parser_nasm);
  407. if (!parser_nasm->tasm && !bc)
  408. yasm_error_set(YASM_ERROR_SYNTAX,
  409. N_("instruction expected after label"));
  410. if (parser_nasm->tasm && bc && !size)
  411. size = yasm_bc_elem_size(bc);
  412. define_label(parser_nasm, name, size);
  413. return bc;
  414. }
  415. default:
  416. yasm_error_set(YASM_ERROR_SYNTAX,
  417. N_("label or instruction expected at start of line"));
  418. return NULL;
  419. }
  420. }
  421. static int
  422. parse_directive_valparams(yasm_parser_nasm *parser_nasm,
  423. /*@out@*/ yasm_valparamhead *vps)
  424. {
  425. yasm_vps_initialize(vps);
  426. for (;;) {
  427. yasm_valparam *vp;
  428. yasm_expr *e;
  429. char *id = NULL;
  430. /* Look for value first */
  431. if (curtok == ID) {
  432. get_peek_token(parser_nasm);
  433. if (parser_nasm->peek_token == '=') {
  434. id = ID_val;
  435. get_next_token(); /* id */
  436. get_next_token(); /* '=' */
  437. }
  438. }
  439. /* Look for parameter */
  440. switch (curtok) {
  441. case STRING:
  442. vp = yasm_vp_create_string(id, STRING_val.contents);
  443. get_next_token();
  444. break;
  445. case ID:
  446. /* We need a peek token, but avoid error if we have one
  447. * already; we need to work whether or not we hit the
  448. * "value=" if test above.
  449. *
  450. * We cheat and peek ahead to see if this is just an ID or
  451. * the ID is part of an expression. We assume a + or - means
  452. * that it's part of an expression (e.g. "x+y" is parsed as
  453. * the expression "x+y" and not as "x", "+y").
  454. */
  455. if (parser_nasm->peek_token == NONE)
  456. get_peek_token(parser_nasm);
  457. switch (parser_nasm->peek_token) {
  458. case '|': case '^': case '&': case LEFT_OP: case RIGHT_OP:
  459. case '+': case '-':
  460. case '*': case '/': case '%': case SIGNDIV: case SIGNMOD:
  461. break;
  462. default:
  463. /* Just an id */
  464. vp = yasm_vp_create_id(id, ID_val, '$');
  465. get_next_token();
  466. goto next;
  467. }
  468. /*@fallthrough@*/
  469. default:
  470. e = parse_expr(parser_nasm, DIR_EXPR);
  471. if (!e) {
  472. yasm_vps_delete(vps);
  473. return 0;
  474. }
  475. vp = yasm_vp_create_expr(id, e);
  476. break;
  477. }
  478. next:
  479. yasm_vps_append(vps, vp);
  480. if (curtok == ',')
  481. get_next_token();
  482. if (curtok == ']' || curtok == ':' || is_eol())
  483. return 1;
  484. }
  485. }
  486. static yasm_bytecode *
  487. parse_times(yasm_parser_nasm *parser_nasm)
  488. {
  489. yasm_expr *multiple;
  490. yasm_bytecode *bc;
  491. multiple = parse_bexpr(parser_nasm, DV_EXPR);
  492. if (!multiple) {
  493. yasm_error_set(YASM_ERROR_SYNTAX, N_("expression expected after %s"),
  494. "TIMES");
  495. return NULL;
  496. }
  497. bc = parse_exp(parser_nasm);
  498. if (!bc) {
  499. yasm_error_set(YASM_ERROR_SYNTAX,
  500. N_("instruction expected after TIMES expression"));
  501. yasm_expr_destroy(multiple);
  502. return NULL;
  503. }
  504. yasm_bc_set_multiple(bc, multiple);
  505. return bc;
  506. }
  507. static yasm_bytecode *
  508. parse_exp(yasm_parser_nasm *parser_nasm)
  509. {
  510. yasm_bytecode *bc;
  511. bc = parse_instr(parser_nasm);
  512. if (bc)
  513. return bc;
  514. switch (curtok) {
  515. case DECLARE_DATA:
  516. {
  517. unsigned int size = DECLARE_DATA_val/8;
  518. yasm_datavalhead dvs;
  519. yasm_dataval *dv;
  520. yasm_expr *e, *e2;
  521. get_next_token();
  522. yasm_dvs_initialize(&dvs);
  523. for (;;) {
  524. if (curtok == STRING) {
  525. /* Peek ahead to see if we're in an expr. If we're not,
  526. * then generate a real string dataval.
  527. */
  528. get_peek_token(parser_nasm);
  529. if (parser_nasm->peek_token == ','
  530. || is_eol_tok(parser_nasm->peek_token)) {
  531. dv = yasm_dv_create_string(STRING_val.contents,
  532. STRING_val.len);
  533. get_next_token();
  534. goto dv_done;
  535. }
  536. }
  537. if (curtok == '?') {
  538. yasm_dvs_delete(&dvs);
  539. get_next_token();
  540. if (! is_eol_tok(curtok)) {
  541. yasm_error_set(YASM_ERROR_SYNTAX,
  542. N_("can not handle more than one '?'"));
  543. return NULL;
  544. }
  545. return yasm_bc_create_reserve(
  546. p_expr_new_ident(yasm_expr_int(
  547. yasm_intnum_create_uint(1))),
  548. size, cur_line);
  549. }
  550. if (!(e = parse_bexpr(parser_nasm, DV_EXPR))) {
  551. yasm_error_set(YASM_ERROR_SYNTAX,
  552. N_("expression or string expected"));
  553. yasm_dvs_delete(&dvs);
  554. return NULL;
  555. }
  556. if (curtok == DUP) {
  557. get_next_token();
  558. if (curtok != '(') {
  559. yasm_error_set(YASM_ERROR_SYNTAX,
  560. N_("expected ( after DUP"));
  561. goto error;
  562. }
  563. get_next_token();
  564. if (curtok == '?') {
  565. get_next_token();
  566. if (curtok != ')') {
  567. yasm_error_set(YASM_ERROR_SYNTAX,
  568. N_("expected ) after DUPlicated expression"));
  569. goto error;
  570. }
  571. get_next_token();
  572. if (! is_eol_tok(curtok)) {
  573. yasm_error_set(YASM_ERROR_SYNTAX,
  574. N_("can not handle more than one '?'"));
  575. goto error;
  576. }
  577. yasm_dvs_delete(&dvs);
  578. return yasm_bc_create_reserve(e, size, cur_line);
  579. } else if ((e2 = parse_bexpr(parser_nasm, DV_EXPR))) {
  580. if (curtok != ')') {
  581. yasm_expr_destroy(e2);
  582. yasm_error_set(YASM_ERROR_SYNTAX,
  583. N_("expected ) after DUPlicated expression"));
  584. goto error;
  585. }
  586. get_next_token();
  587. dv = yasm_dv_create_expr(e2);
  588. yasm_dv_set_multiple(dv, e);
  589. } else {
  590. yasm_error_set(YASM_ERROR_SYNTAX,
  591. N_("expression or string expected"));
  592. error:
  593. yasm_expr_destroy(e);
  594. yasm_dvs_delete(&dvs);
  595. return NULL;
  596. }
  597. } else
  598. dv = yasm_dv_create_expr(e);
  599. dv_done:
  600. yasm_dvs_append(&dvs, dv);
  601. if (is_eol())
  602. break;
  603. if (!expect(',')) {
  604. yasm_dvs_delete(&dvs);
  605. return NULL;
  606. }
  607. get_next_token();
  608. if (is_eol()) /* allow trailing , on list */
  609. break;
  610. }
  611. return yasm_bc_create_data(&dvs, size, 0, p_object->arch,
  612. cur_line);
  613. }
  614. case RESERVE_SPACE:
  615. {
  616. unsigned int size = RESERVE_SPACE_val/8;
  617. yasm_expr *e;
  618. get_next_token();
  619. e = parse_bexpr(parser_nasm, DV_EXPR);
  620. if (!e) {
  621. yasm_error_set(YASM_ERROR_SYNTAX,
  622. N_("expression expected after %s"), "RESx");
  623. return NULL;
  624. }
  625. return yasm_bc_create_reserve(e, size, cur_line);
  626. }
  627. case INCBIN:
  628. {
  629. char *filename;
  630. yasm_expr *start = NULL, *maxlen = NULL;
  631. get_next_token();
  632. if (!expect(STRING)) {
  633. yasm_error_set(YASM_ERROR_SYNTAX,
  634. N_("filename string expected after INCBIN"));
  635. return NULL;
  636. }
  637. filename = STRING_val.contents;
  638. get_next_token();
  639. /* optional start expression */
  640. if (curtok == ',')
  641. get_next_token();
  642. if (is_eol())
  643. goto incbin_done;
  644. start = parse_bexpr(parser_nasm, DV_EXPR);
  645. if (!start) {
  646. yasm_error_set(YASM_ERROR_SYNTAX,
  647. N_("expression expected for INCBIN start"));
  648. return NULL;
  649. }
  650. /* optional maxlen expression */
  651. if (curtok == ',')
  652. get_next_token();
  653. if (is_eol())
  654. goto incbin_done;
  655. maxlen = parse_bexpr(parser_nasm, DV_EXPR);
  656. if (!maxlen) {
  657. yasm_error_set(YASM_ERROR_SYNTAX,
  658. N_("expression expected for INCBIN maximum length"));
  659. return NULL;
  660. }
  661. incbin_done:
  662. return yasm_bc_create_incbin(filename, start, maxlen,
  663. parser_nasm->linemap, cur_line);
  664. }
  665. default:
  666. return NULL;
  667. }
  668. }
  669. static yasm_bytecode *
  670. parse_instr(yasm_parser_nasm *parser_nasm)
  671. {
  672. yasm_bytecode *bc;
  673. switch (curtok) {
  674. case INSN:
  675. {
  676. yasm_insn *insn;
  677. bc = INSN_val;
  678. insn = yasm_bc_get_insn(bc);
  679. get_next_token();
  680. if (is_eol())
  681. return bc; /* no operands */
  682. /* parse operands */
  683. for (;;) {
  684. yasm_insn_operand *op = parse_operand(parser_nasm);
  685. if (!op) {
  686. if (insn->num_operands == 0)
  687. yasm_error_set(YASM_ERROR_SYNTAX,
  688. N_("unexpected %s after instruction"),
  689. describe_token(curtok));
  690. else
  691. yasm_error_set(YASM_ERROR_SYNTAX,
  692. N_("expected operand, got %s"),
  693. describe_token(curtok));
  694. yasm_bc_destroy(bc);
  695. return NULL;
  696. }
  697. yasm_insn_ops_append(insn, op);
  698. if (is_eol())
  699. break;
  700. if (!expect(',')) {
  701. yasm_bc_destroy(bc);
  702. return NULL;
  703. }
  704. get_next_token();
  705. }
  706. return bc;
  707. }
  708. case PREFIX:
  709. {
  710. uintptr_t prefix = PREFIX_val;
  711. get_next_token();
  712. bc = parse_instr(parser_nasm);
  713. if (!bc)
  714. bc = yasm_arch_create_empty_insn(p_object->arch, cur_line);
  715. yasm_insn_add_prefix(yasm_bc_get_insn(bc), prefix);
  716. return bc;
  717. }
  718. case SEGREG:
  719. {
  720. uintptr_t segreg = SEGREG_val;
  721. get_next_token();
  722. bc = parse_instr(parser_nasm);
  723. if (!bc)
  724. bc = yasm_arch_create_empty_insn(p_object->arch, cur_line);
  725. yasm_insn_add_seg_prefix(yasm_bc_get_insn(bc), segreg);
  726. return bc;
  727. }
  728. default:
  729. return NULL;
  730. }
  731. }
  732. static yasm_insn_operand *
  733. parse_operand(yasm_parser_nasm *parser_nasm)
  734. {
  735. yasm_insn_operand *op;
  736. switch (curtok) {
  737. case '[':
  738. {
  739. get_next_token();
  740. op = parse_memaddr(parser_nasm);
  741. expect(']');
  742. get_next_token();
  743. if (!op) {
  744. yasm_error_set(YASM_ERROR_SYNTAX,
  745. N_("memory address expected"));
  746. return NULL;
  747. }
  748. if (parser_nasm->tasm && !is_eol() && curtok != ',') {
  749. yasm_expr *e = NULL, *f;
  750. yasm_effaddr *ea;
  751. switch (op->type) {
  752. case YASM_INSN__OPERAND_IMM:
  753. e = op->data.val;
  754. break;
  755. case YASM_INSN__OPERAND_MEMORY:
  756. if (op->data.ea->disp.rel) {
  757. yasm_error_set(YASM_ERROR_SYNTAX,
  758. N_("relative adressing not supported\n"));
  759. return NULL;
  760. }
  761. e = yasm_expr_copy(op->data.ea->disp.abs);
  762. yasm_arch_ea_destroy(p_object->arch, op->data.ea);
  763. break;
  764. case YASM_INSN__OPERAND_REG:
  765. case YASM_INSN__OPERAND_SEGREG:
  766. yasm_error_set(YASM_ERROR_SYNTAX,
  767. N_("register adressing not supported\n"));
  768. return NULL;
  769. }
  770. yasm_xfree(op);
  771. f = parse_bexpr(parser_nasm, NORM_EXPR);
  772. if (!f) {
  773. yasm_expr_destroy(e);
  774. yasm_error_set(YASM_ERROR_SYNTAX,
  775. N_("expected expression after ]"));
  776. return NULL;
  777. }
  778. e = p_expr_new_tree(e, YASM_EXPR_ADD, f);
  779. ea = yasm_arch_ea_create(p_object->arch, e);
  780. yasm_ea_set_implicit_size_segment(parser_nasm, ea, e);
  781. op = yasm_operand_create_mem(ea);
  782. }
  783. return op;
  784. }
  785. case OFFSET:
  786. {
  787. yasm_insn_operand *op2;
  788. get_next_token();
  789. if (parser_nasm->masm && curtok == ID && !yasm__strcasecmp(ID_val, "flat")) {
  790. get_next_token();
  791. if (curtok == ':') {
  792. get_next_token();
  793. }
  794. }
  795. op = parse_operand(parser_nasm);
  796. if (!op) {
  797. yasm_error_set(YASM_ERROR_SYNTAX,
  798. N_("memory address expected"));
  799. return NULL;
  800. }
  801. if (op->type == YASM_INSN__OPERAND_IMM)
  802. return op;
  803. if (op->type != YASM_INSN__OPERAND_MEMORY) {
  804. yasm_error_set(YASM_ERROR_SYNTAX,
  805. N_("OFFSET applied to non-memory operand"));
  806. return NULL;
  807. }
  808. if (op->data.ea->disp.rel) {
  809. yasm_error_set(YASM_ERROR_SYNTAX,
  810. N_("OFFSET applied to non-absolute memory operand"));
  811. return NULL;
  812. }
  813. if (op->data.ea->disp.abs)
  814. op2 = yasm_operand_create_imm(op->data.ea->disp.abs);
  815. else
  816. op2 = yasm_operand_create_imm(p_expr_new_ident(
  817. yasm_expr_int(yasm_intnum_create_uint(0))));
  818. yasm_xfree(op);
  819. return op2;
  820. }
  821. case SEGREG:
  822. {
  823. uintptr_t segreg = SEGREG_val;
  824. get_next_token();
  825. if (parser_nasm->tasm && curtok == ':') {
  826. get_next_token();
  827. op = parse_operand(parser_nasm);
  828. if (!op)
  829. return NULL;
  830. if (op->type == YASM_INSN__OPERAND_IMM) {
  831. yasm_effaddr *ea = yasm_arch_ea_create(p_object->arch,
  832. op->data.val);
  833. yasm_insn_operand *op2;
  834. yasm_ea_set_implicit_size_segment(parser_nasm, ea,
  835. op->data.val);
  836. op2 = yasm_operand_create_mem(ea);
  837. op2->size = op->size;
  838. yasm_xfree(op);
  839. op = op2;
  840. }
  841. if (op->type != YASM_INSN__OPERAND_MEMORY) {
  842. yasm_error_set(YASM_ERROR_SYNTAX,
  843. N_("segment applied to non-memory operand"));
  844. return NULL;
  845. }
  846. yasm_ea_set_segreg(op->data.ea, segreg);
  847. return op;
  848. }
  849. op = yasm_operand_create_segreg(segreg);
  850. return op;
  851. }
  852. case REG:
  853. op = yasm_operand_create_reg(REG_val);
  854. get_next_token();
  855. return op;
  856. case REGGROUP:
  857. {
  858. unsigned long regindex;
  859. uintptr_t reg = REGGROUP_val;
  860. get_next_token(); /* REGGROUP */
  861. if (curtok != '(')
  862. return yasm_operand_create_reg(reg);
  863. get_next_token(); /* '(' */
  864. if (!expect(INTNUM)) {
  865. yasm_error_set(YASM_ERROR_SYNTAX,
  866. N_("integer register index expected"));
  867. return NULL;
  868. }
  869. regindex = yasm_intnum_get_uint(INTNUM_val);
  870. get_next_token(); /* INTNUM */
  871. if (!expect(')')) {
  872. yasm_error_set(YASM_ERROR_SYNTAX,
  873. N_("missing closing parenthesis for register index"));
  874. return NULL;
  875. }
  876. get_next_token(); /* ')' */
  877. reg = yasm_arch_reggroup_get_reg(p_object->arch, reg, regindex);
  878. if (reg == 0) {
  879. yasm_error_set(YASM_ERROR_SYNTAX, N_("bad register index `%u'"),
  880. regindex);
  881. return NULL;
  882. }
  883. return yasm_operand_create_reg(reg);
  884. }
  885. case STRICT:
  886. get_next_token();
  887. op = parse_operand(parser_nasm);
  888. if (op)
  889. op->strict = 1;
  890. return op;
  891. case SIZE_OVERRIDE:
  892. {
  893. unsigned int size = SIZE_OVERRIDE_val;
  894. get_next_token();
  895. if (parser_nasm->masm && curtok == ID && !yasm__strcasecmp(ID_val, "ptr")) {
  896. get_next_token();
  897. }
  898. op = parse_operand(parser_nasm);
  899. if (!op)
  900. return NULL;
  901. if (op->type == YASM_INSN__OPERAND_REG &&
  902. yasm_arch_get_reg_size(p_object->arch, op->data.reg) != size)
  903. yasm_error_set(YASM_ERROR_TYPE,
  904. N_("cannot override register size"));
  905. else {
  906. /* Silently override others unless a warning is turned on.
  907. * This is to allow overrides such as:
  908. * %define arg1 dword [bp+4]
  909. * cmp word arg1, 2
  910. * Which expands to:
  911. * cmp word dword [bp+4], 2
  912. */
  913. if (op->size != 0) {
  914. if (op->size != size)
  915. yasm_warn_set(YASM_WARN_SIZE_OVERRIDE,
  916. N_("overriding operand size from %u-bit to %u-bit"),
  917. op->size, size);
  918. else
  919. yasm_warn_set(YASM_WARN_SIZE_OVERRIDE,
  920. N_("double operand size override"));
  921. }
  922. op->size = size;
  923. }
  924. return op;
  925. }
  926. case TARGETMOD:
  927. {
  928. uintptr_t tmod = TARGETMOD_val;
  929. get_next_token();
  930. op = parse_operand(parser_nasm);
  931. if (op)
  932. op->targetmod = tmod;
  933. return op;
  934. }
  935. case ID:
  936. case LOCAL_ID:
  937. case NONLOCAL_ID:
  938. if (parser_nasm->tasm) {
  939. get_peek_token(parser_nasm);
  940. if (parser_nasm->peek_token == '[') {
  941. yasm_symrec *sym = yasm_symtab_use(p_symtab, ID_val,
  942. cur_line);
  943. yasm_expr *e = p_expr_new_ident(yasm_expr_sym(sym)), *f;
  944. yasm_effaddr *ea;
  945. yasm_xfree(ID_val);
  946. get_next_token();
  947. get_next_token();
  948. f = parse_bexpr(parser_nasm, NORM_EXPR);
  949. if (!f) {
  950. yasm_error_set(YASM_ERROR_SYNTAX,
  951. N_("expected expression after ["));
  952. return NULL;
  953. }
  954. e = p_expr_new_tree(e, YASM_EXPR_ADD, f);
  955. if (!expect(']')) {
  956. yasm_error_set(YASM_ERROR_SYNTAX, N_("missing closing bracket"));
  957. return NULL;
  958. }
  959. get_next_token();
  960. ea = yasm_arch_ea_create(p_object->arch, e);
  961. yasm_ea_set_implicit_size_segment(parser_nasm, ea, e);
  962. op = yasm_operand_create_mem(ea);
  963. return op;
  964. }
  965. }
  966. /* Fallthrough */
  967. default:
  968. {
  969. yasm_expr *e = parse_bexpr(parser_nasm, NORM_EXPR);
  970. if (!e)
  971. return NULL;
  972. if (curtok != ':') {
  973. if (parser_nasm->tasm && yasm_expr_size(e)) {
  974. yasm_effaddr *ea = yasm_arch_ea_create(p_object->arch, e);
  975. yasm_ea_set_implicit_size_segment(parser_nasm, ea, e);
  976. op = yasm_operand_create_mem(ea);
  977. return op;
  978. } else if (curtok == '[') {
  979. yasm_expr *f;
  980. yasm_effaddr *ea;
  981. yasm_insn_operand *op2;
  982. op = parse_operand(parser_nasm);
  983. if (!op)
  984. return NULL;
  985. f = op->data.ea->disp.abs;
  986. e = p_expr_new_tree(e, YASM_EXPR_ADD, f);
  987. ea = yasm_arch_ea_create(p_object->arch, e);
  988. yasm_ea_set_implicit_size_segment(parser_nasm, ea, e);
  989. op2 = yasm_operand_create_mem(ea);
  990. yasm_xfree(op);
  991. return op2;
  992. } else {
  993. return yasm_operand_create_imm(e);
  994. }
  995. } else {
  996. yasm_expr *off;
  997. get_next_token();
  998. off = parse_bexpr(parser_nasm, NORM_EXPR);
  999. if (!off) {
  1000. yasm_expr_destroy(e);
  1001. return NULL;
  1002. }
  1003. op = yasm_operand_create_imm(off);
  1004. op->seg = e;
  1005. return op;
  1006. }
  1007. }
  1008. }
  1009. }
  1010. /* memory addresses */
  1011. static yasm_insn_operand *
  1012. parse_memaddr(yasm_parser_nasm *parser_nasm)
  1013. {
  1014. yasm_insn_operand *op;
  1015. switch (curtok) {
  1016. case SEGREG:
  1017. {
  1018. uintptr_t segreg = SEGREG_val;
  1019. get_next_token();
  1020. if (!expect(':')) {
  1021. yasm_error_set(YASM_ERROR_SYNTAX,
  1022. N_("`:' required after segment register"));
  1023. return NULL;
  1024. }
  1025. get_next_token();
  1026. op = parse_memaddr(parser_nasm);
  1027. if (op)
  1028. yasm_ea_set_segreg(op->data.ea, segreg);
  1029. return op;
  1030. }
  1031. case SIZE_OVERRIDE:
  1032. {
  1033. unsigned int size = SIZE_OVERRIDE_val;
  1034. get_next_token();
  1035. op = parse_memaddr(parser_nasm);
  1036. if (op)
  1037. op->data.ea->disp.size = size;
  1038. return op;
  1039. }
  1040. case NOSPLIT:
  1041. get_next_token();
  1042. op = parse_memaddr(parser_nasm);
  1043. if (op)
  1044. op->data.ea->nosplit = 1;
  1045. return op;
  1046. case REL:
  1047. get_next_token();
  1048. op = parse_memaddr(parser_nasm);
  1049. if (op) {
  1050. op->data.ea->pc_rel = 1;
  1051. op->data.ea->not_pc_rel = 0;
  1052. }
  1053. return op;
  1054. case ABS:
  1055. get_next_token();
  1056. op = parse_memaddr(parser_nasm);
  1057. if (op) {
  1058. op->data.ea->pc_rel = 0;
  1059. op->data.ea->not_pc_rel = 1;
  1060. }
  1061. return op;
  1062. default:
  1063. {
  1064. yasm_expr *e = parse_bexpr(parser_nasm, NORM_EXPR);
  1065. if (!e)
  1066. return NULL;
  1067. if (curtok != ':') {
  1068. yasm_effaddr *ea = yasm_arch_ea_create(p_object->arch, e);
  1069. yasm_ea_set_implicit_size_segment(parser_nasm, ea, e);
  1070. return yasm_operand_create_mem(ea);
  1071. } else {
  1072. yasm_effaddr *ea;
  1073. yasm_expr *off;
  1074. get_next_token();
  1075. off = parse_bexpr(parser_nasm, NORM_EXPR);
  1076. if (!off) {
  1077. yasm_expr_destroy(e);
  1078. return NULL;
  1079. }
  1080. ea = yasm_arch_ea_create(p_object->arch, off);
  1081. yasm_ea_set_implicit_size_segment(parser_nasm, ea, off);
  1082. op = yasm_operand_create_mem(ea);
  1083. op->seg = e;
  1084. return op;
  1085. }
  1086. }
  1087. }
  1088. }
  1089. /* Expression grammar parsed is:
  1090. *
  1091. * expr : bexpr [ : bexpr ]
  1092. * bexpr : expr0 [ WRT expr6 ]
  1093. * expr0 : expr1 [ {|} expr1...]
  1094. * expr1 : expr2 [ {^} expr2...]
  1095. * expr2 : expr3 [ {&} expr3...]
  1096. * expr3 : expr4 [ {<<,>>} expr4...]
  1097. * expr4 : expr5 [ {+,-} expr5...]
  1098. * expr5 : expr6 [ {*,/,%,//,%%} expr6...]
  1099. * expr6 : { ~,+,-,SEG } expr6
  1100. * | (expr)
  1101. * | symbol
  1102. * | $
  1103. * | number
  1104. */
  1105. #define parse_expr_common(leftfunc, tok, rightfunc, op) \
  1106. do { \
  1107. yasm_expr *e, *f; \
  1108. e = leftfunc(parser_nasm, type); \
  1109. if (!e) \
  1110. return NULL; \
  1111. \
  1112. while (curtok == tok) { \
  1113. get_next_token(); \
  1114. f = rightfunc(parser_nasm, type); \
  1115. if (!f) { \
  1116. yasm_error_set(YASM_ERROR_SYNTAX, \
  1117. N_("expected expression after %s"), \
  1118. describe_token(op)); \
  1119. yasm_expr_destroy(e); \
  1120. return NULL; \
  1121. } \
  1122. e = p_expr_new_tree(e, op, f); \
  1123. } \
  1124. return e; \
  1125. } while(0)
  1126. static yasm_expr *
  1127. parse_expr(yasm_parser_nasm *parser_nasm, expr_type type)
  1128. {
  1129. switch (type) {
  1130. case DIR_EXPR:
  1131. /* directive expressions can't handle seg:off or WRT */
  1132. return parse_expr0(parser_nasm, type);
  1133. default:
  1134. parse_expr_common(parse_bexpr, ':', parse_bexpr, YASM_EXPR_SEGOFF);
  1135. }
  1136. /*@notreached@*/
  1137. return NULL;
  1138. }
  1139. static yasm_expr *
  1140. parse_bexpr(yasm_parser_nasm *parser_nasm, expr_type type)
  1141. {
  1142. parse_expr_common(parse_expr0, WRT, parse_expr6, YASM_EXPR_WRT);
  1143. }
  1144. static yasm_expr *
  1145. parse_expr0(yasm_parser_nasm *parser_nasm, expr_type type)
  1146. {
  1147. parse_expr_common(parse_expr1, '|', parse_expr1, YASM_EXPR_OR);
  1148. }
  1149. static yasm_expr *
  1150. parse_expr1(yasm_parser_nasm *parser_nasm, expr_type type)
  1151. {
  1152. parse_expr_common(parse_expr2, '^', parse_expr2, YASM_EXPR_XOR);
  1153. }
  1154. static yasm_expr *
  1155. parse_expr2(yasm_parser_nasm *parser_nasm, expr_type type)
  1156. {
  1157. parse_expr_common(parse_expr3, '&', parse_expr3, YASM_EXPR_AND);
  1158. }
  1159. static yasm_expr *
  1160. parse_expr3(yasm_parser_nasm *parser_nasm, expr_type type)
  1161. {
  1162. yasm_expr *e, *f;
  1163. e = parse_expr4(parser_nasm, type);
  1164. if (!e)
  1165. return NULL;
  1166. while (curtok == LEFT_OP || curtok == RIGHT_OP) {
  1167. int op = curtok;
  1168. get_next_token();
  1169. f = parse_expr4(parser_nasm, type);
  1170. if (!f) {
  1171. yasm_error_set(YASM_ERROR_SYNTAX,
  1172. N_("expected expression after %s"),
  1173. describe_token(op));
  1174. yasm_expr_destroy(e);
  1175. return NULL;
  1176. }
  1177. switch (op) {
  1178. case LEFT_OP: e = p_expr_new_tree(e, YASM_EXPR_SHL, f); break;
  1179. case RIGHT_OP: e = p_expr_new_tree(e, YASM_EXPR_SHR, f); break;
  1180. }
  1181. }
  1182. return e;
  1183. }
  1184. static yasm_expr *
  1185. parse_expr4(yasm_parser_nasm *parser_nasm, expr_type type)
  1186. {
  1187. yasm_expr *e, *f;
  1188. e = parse_expr5(parser_nasm, type);
  1189. if (!e)
  1190. return NULL;
  1191. while (curtok == '+' || curtok == '-') {
  1192. int op = curtok;
  1193. get_next_token();
  1194. f = parse_expr5(parser_nasm, type);
  1195. if (!f) {
  1196. yasm_error_set(YASM_ERROR_SYNTAX,
  1197. N_("expected expression after %s"),
  1198. describe_token(op));
  1199. yasm_expr_destroy(e);
  1200. return NULL;
  1201. }
  1202. switch (op) {
  1203. case '+': e = p_expr_new_tree(e, YASM_EXPR_ADD, f); break;
  1204. case '-': e = p_expr_new_tree(e, YASM_EXPR_SUB, f); break;
  1205. }
  1206. }
  1207. return e;
  1208. }
  1209. static yasm_expr *
  1210. parse_expr5(yasm_parser_nasm *parser_nasm, expr_type type)
  1211. {
  1212. yasm_expr *e, *f;
  1213. e = parse_expr6(parser_nasm, type);
  1214. if (!e)
  1215. return NULL;
  1216. while (curtok == '*' || curtok == '/' || curtok == '%'
  1217. || curtok == SIGNDIV || curtok == SIGNMOD) {
  1218. int op = curtok;
  1219. get_next_token();
  1220. f = parse_expr6(parser_nasm, type);
  1221. if (!f) {
  1222. yasm_error_set(YASM_ERROR_SYNTAX,
  1223. N_("expected expression after %s"),
  1224. describe_token(op));
  1225. yasm_expr_destroy(e);
  1226. return NULL;
  1227. }
  1228. switch (op) {
  1229. case '*': e = p_expr_new_tree(e, YASM_EXPR_MUL, f); break;
  1230. case '/': e = p_expr_new_tree(e, YASM_EXPR_DIV, f); break;
  1231. case '%': e = p_expr_new_tree(e, YASM_EXPR_MOD, f); break;
  1232. case SIGNDIV: e = p_expr_new_tree(e, YASM_EXPR_SIGNDIV, f); break;
  1233. case SIGNMOD: e = p_expr_new_tree(e, YASM_EXPR_SIGNMOD, f); break;
  1234. }
  1235. }
  1236. return e;
  1237. }
  1238. static yasm_expr *
  1239. parse_expr6(yasm_parser_nasm *parser_nasm, expr_type type)
  1240. {
  1241. yasm_expr *e;
  1242. yasm_symrec *sym;
  1243. switch (curtok) {
  1244. case '+':
  1245. get_next_token();
  1246. e = parse_expr6(parser_nasm, type);
  1247. if (!e) {
  1248. yasm_error_set(YASM_ERROR_SYNTAX,
  1249. N_("expected expression after %s"), "`+'");
  1250. }
  1251. return e;
  1252. case '-':
  1253. get_next_token();
  1254. e = parse_expr6(parser_nasm, type);
  1255. if (!e) {
  1256. yasm_error_set(YASM_ERROR_SYNTAX,
  1257. N_("expected expression after %s"), "`-'");
  1258. return NULL;
  1259. }
  1260. return p_expr_new_branch(YASM_EXPR_NEG, e);
  1261. case '~':
  1262. get_next_token();
  1263. e = parse_expr6(parser_nasm, type);
  1264. if (!e) {
  1265. yasm_error_set(YASM_ERROR_SYNTAX,
  1266. N_("expected expression after %s"), "`~'");
  1267. return NULL;
  1268. }
  1269. return p_expr_new_branch(YASM_EXPR_NOT, e);
  1270. case LOW:
  1271. get_next_token();
  1272. e = parse_expr6(parser_nasm, type);
  1273. if (!e) {
  1274. yasm_error_set(YASM_ERROR_SYNTAX,
  1275. N_("expected expression after %s"), "LOW");
  1276. return NULL;
  1277. }
  1278. return p_expr_new_tree(e, YASM_EXPR_AND,
  1279. p_expr_new_ident(yasm_expr_int(yasm_intnum_create_uint(0xff))));
  1280. case HIGH:
  1281. get_next_token();
  1282. e = parse_expr6(parser_nasm, type);
  1283. if (!e) {
  1284. yasm_error_set(YASM_ERROR_SYNTAX,
  1285. N_("expected expression after %s"), "HIGH");
  1286. return NULL;
  1287. }
  1288. return p_expr_new_tree(
  1289. p_expr_new_tree(e, YASM_EXPR_SHR,
  1290. p_expr_new_ident(yasm_expr_int(
  1291. yasm_intnum_create_uint(8)))),
  1292. YASM_EXPR_AND,
  1293. p_expr_new_ident(yasm_expr_int(yasm_intnum_create_uint(0xff))));
  1294. case SEG:
  1295. get_next_token();
  1296. e = parse_expr6(parser_nasm, type);
  1297. if (!e) {
  1298. yasm_error_set(YASM_ERROR_SYNTAX,
  1299. N_("expected expression after %s"), "SEG");
  1300. return NULL;
  1301. }
  1302. return p_expr_new_branch(YASM_EXPR_SEG, e);
  1303. case '(':
  1304. get_next_token();
  1305. e = parse_expr(parser_nasm, type);
  1306. if (!e) {
  1307. yasm_error_set(YASM_ERROR_SYNTAX,
  1308. N_("expected expression after %s"), "`('");
  1309. return NULL;
  1310. }
  1311. if (!expect(')')) {
  1312. yasm_error_set(YASM_ERROR_SYNTAX, N_("missing parenthesis"));
  1313. return NULL;
  1314. }
  1315. get_next_token();
  1316. return e;
  1317. case INTNUM:
  1318. e = p_expr_new_ident(yasm_expr_int(INTNUM_val));
  1319. get_next_token();
  1320. return e;
  1321. case REG:
  1322. if (type == DV_EXPR) {
  1323. yasm_error_set(YASM_ERROR_SYNTAX,
  1324. N_("data values can't have registers"));
  1325. return NULL;
  1326. }
  1327. e = p_expr_new_ident(yasm_expr_reg(REG_val));
  1328. get_next_token();
  1329. return e;
  1330. }
  1331. /* directives allow very little and handle IDs specially */
  1332. if (type == DIR_EXPR) {
  1333. switch (curtok) {
  1334. case ID:
  1335. sym = yasm_symtab_use(p_symtab, ID_val, cur_line);
  1336. e = p_expr_new_ident(yasm_expr_sym(sym));
  1337. yasm_xfree(ID_val);
  1338. break;
  1339. default:
  1340. return NULL;
  1341. }
  1342. } else switch (curtok) {
  1343. case FLTNUM:
  1344. e = p_expr_new_ident(yasm_expr_float(FLTNUM_val));
  1345. break;
  1346. case STRING:
  1347. {
  1348. yasm_intnum *intn;
  1349. if (parser_nasm->tasm)
  1350. intn = yasm_intnum_create_charconst_tasm(STRING_val.contents);
  1351. else
  1352. intn = yasm_intnum_create_charconst_nasm(STRING_val.contents);
  1353. e = p_expr_new_ident(yasm_expr_int(intn));
  1354. yasm_xfree(STRING_val.contents);
  1355. break;
  1356. }
  1357. case SPECIAL_ID:
  1358. sym = yasm_objfmt_get_special_sym(p_object, ID_val+2, "nasm");
  1359. if (sym) {
  1360. e = p_expr_new_ident(yasm_expr_sym(sym));
  1361. yasm_xfree(ID_val);
  1362. break;
  1363. }
  1364. /*@fallthrough@*/
  1365. case ID:
  1366. case LOCAL_ID:
  1367. case NONLOCAL_ID:
  1368. sym = yasm_symtab_use(p_symtab, ID_val, cur_line);
  1369. e = p_expr_new_ident(yasm_expr_sym(sym));
  1370. yasm_xfree(ID_val);
  1371. break;
  1372. case '$':
  1373. /* "$" references the current assembly position */
  1374. if (parser_nasm->abspos)
  1375. e = yasm_expr_copy(parser_nasm->abspos);
  1376. else {
  1377. sym = yasm_symtab_define_curpos(p_symtab, "$",
  1378. parser_nasm->prev_bc, cur_line);
  1379. e = p_expr_new_ident(yasm_expr_sym(sym));
  1380. }
  1381. break;
  1382. case START_SECTION_ID:
  1383. /* "$$" references the start of the current section */
  1384. if (parser_nasm->absstart)
  1385. e = yasm_expr_copy(parser_nasm->absstart);
  1386. else {
  1387. sym = yasm_symtab_define_label(p_symtab, "$$",
  1388. yasm_section_bcs_first(cursect), 0, cur_line);
  1389. e = p_expr_new_ident(yasm_expr_sym(sym));
  1390. }
  1391. break;
  1392. default:
  1393. return NULL;
  1394. }
  1395. get_next_token();
  1396. return e;
  1397. }
  1398. static void
  1399. set_nonlocal_label(yasm_parser_nasm *parser_nasm, const char *name)
  1400. {
  1401. if (!parser_nasm->tasm || tasm_locals) {
  1402. if (parser_nasm->locallabel_base)
  1403. yasm_xfree(parser_nasm->locallabel_base);
  1404. parser_nasm->locallabel_base_len = strlen(name);
  1405. parser_nasm->locallabel_base =
  1406. yasm_xmalloc(parser_nasm->locallabel_base_len+1);
  1407. strcpy(parser_nasm->locallabel_base, name);
  1408. }
  1409. }
  1410. static void
  1411. define_label(yasm_parser_nasm *parser_nasm, char *name, unsigned int size)
  1412. {
  1413. yasm_symrec *symrec;
  1414. if (parser_nasm->abspos)
  1415. symrec = yasm_symtab_define_equ(p_symtab, name,
  1416. yasm_expr_copy(parser_nasm->abspos),
  1417. cur_line);
  1418. else
  1419. symrec = yasm_symtab_define_label(p_symtab, name, parser_nasm->prev_bc,
  1420. 1, cur_line);
  1421. yasm_symrec_set_size(symrec, size);
  1422. yasm_symrec_set_segment(symrec, tasm_segment);
  1423. yasm_xfree(name);
  1424. }
  1425. static void
  1426. dir_align(yasm_object *object, yasm_valparamhead *valparams,
  1427. yasm_valparamhead *objext_valparams, unsigned long line)
  1428. {
  1429. yasm_valparam *vp = yasm_vps_first(valparams);
  1430. yasm_expr *boundval = yasm_vp_expr(vp, object->symtab, line);
  1431. /*@depedent@*/ yasm_intnum *boundintn;
  1432. /* Largest .align in the section specifies section alignment.
  1433. * Note: this doesn't match NASM behavior, but is a lot more
  1434. * intelligent!
  1435. */
  1436. if (boundval && (boundintn = yasm_expr_get_intnum(&boundval, 0))) {
  1437. unsigned long boundint = yasm_intnum_get_uint(boundintn);
  1438. /* Alignments must be a power of two. */
  1439. if (is_exp2(boundint)) {
  1440. if (boundint > yasm_section_get_align(object->cur_section))
  1441. yasm_section_set_align(object->cur_section, boundint, line);
  1442. }
  1443. }
  1444. /* As this directive is called only when nop is used as fill, always
  1445. * use arch (nop) fill.
  1446. */
  1447. yasm_section_bcs_append(object->cur_section,
  1448. yasm_bc_create_align(boundval, NULL, NULL,
  1449. /*yasm_section_is_code(object->cur_section) ?*/
  1450. yasm_arch_get_fill(object->arch)/* : NULL*/,
  1451. line));
  1452. }
  1453. static void
  1454. nasm_parser_directive(yasm_parser_nasm *parser_nasm, const char *name,
  1455. yasm_valparamhead *valparams,
  1456. yasm_valparamhead *objext_valparams)
  1457. {
  1458. unsigned long line = cur_line;
  1459. yasm_valparam *vp;
  1460. if (!yasm_object_directive(p_object, name, "nasm", valparams,
  1461. objext_valparams, line))
  1462. ;
  1463. else if (yasm__strcasecmp(name, "absolute") == 0) {
  1464. if (!valparams) {
  1465. yasm_error_set(YASM_ERROR_SYNTAX,
  1466. N_("directive `%s' requires an argument"),
  1467. "absolute");
  1468. } else {
  1469. vp = yasm_vps_first(valparams);
  1470. if (parser_nasm->absstart)
  1471. yasm_expr_destroy(parser_nasm->absstart);
  1472. if (parser_nasm->abspos)
  1473. yasm_expr_destroy(parser_nasm->abspos);
  1474. parser_nasm->absstart = yasm_vp_expr(vp, p_object->symtab, line);
  1475. parser_nasm->abspos = yasm_expr_copy(parser_nasm->absstart);
  1476. cursect = NULL;
  1477. parser_nasm->prev_bc = NULL;
  1478. }
  1479. } else if (yasm__strcasecmp(name, "align") == 0) {
  1480. /* Really, we shouldn't end up with an align directive in an absolute
  1481. * section (as it's supposed to be only used for nop fill), but handle
  1482. * it gracefully anyway.
  1483. */
  1484. if (parser_nasm->abspos) {
  1485. yasm_expr *boundval, *e;
  1486. vp = yasm_vps_first(valparams);
  1487. boundval = yasm_vp_expr(vp, p_object->symtab, line);
  1488. e = yasm_expr_create_tree(
  1489. yasm_expr_create_tree(yasm_expr_copy(parser_nasm->absstart),
  1490. YASM_EXPR_SUB,
  1491. yasm_expr_copy(parser_nasm->abspos),
  1492. cur_line),
  1493. YASM_EXPR_AND,
  1494. yasm_expr_create(YASM_EXPR_SUB, yasm_expr_expr(boundval),
  1495. yasm_expr_int(yasm_intnum_create_uint(1)),
  1496. cur_line),
  1497. cur_line);
  1498. parser_nasm->abspos = yasm_expr_create_tree(
  1499. parser_nasm->abspos, YASM_EXPR_ADD, e, cur_line);
  1500. } else if (!valparams) {
  1501. yasm_error_set(YASM_ERROR_SYNTAX,
  1502. N_("directive `%s' requires an argument"), "align");
  1503. } else
  1504. dir_align(p_object, valparams, objext_valparams, line);
  1505. } else if (yasm__strcasecmp(name, "default") == 0) {
  1506. if (!valparams)
  1507. ;
  1508. else {
  1509. vp = yasm_vps_first(valparams);
  1510. while (vp) {
  1511. const char *id = yasm_vp_id(vp);
  1512. if (id) {
  1513. if (yasm__strcasecmp(id, "rel") == 0)
  1514. yasm_arch_set_var(p_object->arch, "default_rel", 1);
  1515. else if (yasm__strcasecmp(id, "abs") == 0)
  1516. yasm_arch_set_var(p_object->arch, "default_rel", 0);
  1517. else
  1518. yasm_error_set(YASM_ERROR_SYNTAX,
  1519. N_("unrecognized default `%s'"), id);
  1520. } else
  1521. yasm_error_set(YASM_ERROR_SYNTAX,
  1522. N_("unrecognized default value"));
  1523. vp = yasm_vps_next(vp);
  1524. }
  1525. }
  1526. } else
  1527. yasm_error_set(YASM_ERROR_SYNTAX, N_("unrecognized directive `%s'"),
  1528. name);
  1529. if (parser_nasm->absstart && cursect) {
  1530. /* We switched to a new section. Get out of absolute section mode. */
  1531. yasm_expr_destroy(parser_nasm->absstart);
  1532. parser_nasm->absstart = NULL;
  1533. if (parser_nasm->abspos) {
  1534. yasm_expr_destroy(parser_nasm->abspos);
  1535. parser_nasm->abspos = NULL;
  1536. }
  1537. }
  1538. if (cursect) {
  1539. /* In case cursect changed or a bytecode was added, update prev_bc. */
  1540. parser_nasm->prev_bc = yasm_section_bcs_last(cursect);
  1541. }
  1542. if (valparams)
  1543. yasm_vps_delete(valparams);
  1544. if (objext_valparams)
  1545. yasm_vps_delete(objext_valparams);
  1546. }
  1547. yasm_bytecode *
  1548. gas_intel_syntax_parse_instr(yasm_parser_nasm *parser_nasm, unsigned char *instr)
  1549. {
  1550. yasm_bytecode *bc = NULL;
  1551. char *sinstr = (char *) instr;
  1552. parser_nasm->s.bot = instr;
  1553. parser_nasm->s.tok = instr;
  1554. parser_nasm->s.ptr = instr;
  1555. parser_nasm->s.cur = instr;
  1556. parser_nasm->s.lim = instr + strlen(sinstr) + 1;
  1557. parser_nasm->s.top = parser_nasm->s.lim;
  1558. parser_nasm->peek_token = NONE;
  1559. get_next_token();
  1560. if (!is_eol()) {
  1561. bc = parse_instr(parser_nasm);
  1562. }
  1563. return bc;
  1564. }