Mercurial > hg-old > index.cgi
comparison lwasm/pseudo.c @ 160:b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
author | lost |
---|---|
date | Sat, 31 Jan 2009 06:33:03 +0000 |
parents | f0527dc3804d |
children | 02ada556bcc0 |
comparison
equal
deleted
inserted
replaced
159:71561c12b20b | 160:b061350c17e4 |
---|---|
344 l -> addrset = 2; | 344 l -> addrset = 2; |
345 | 345 |
346 as -> dpval = v & 0xFF; | 346 as -> dpval = v & 0xFF; |
347 } | 347 } |
348 | 348 |
349 // used to get a byte from a string | |
350 // -1 is end of line | |
351 int pseudo_fcc_fetchchar(asmstate_t *as, char **p) | |
352 { | |
353 int c; | |
354 | |
355 // - | |
356 if (!**p) | |
357 return -1; | |
358 | |
359 c = (unsigned char)(**p); | |
360 (*p)++; | |
361 | |
362 if (as -> pragmas & PRAGMA_CESCAPES && c == '\\') | |
363 { | |
364 // decode escapes if needed | |
365 if (!**p) | |
366 return c; | |
367 | |
368 c = **p; | |
369 (*p)++; | |
370 | |
371 switch (c) | |
372 { | |
373 // octal value | |
374 // 1, 2, or 3 digits | |
375 // NOTE: \0 for NUL is included in this... | |
376 case '0': | |
377 case '1': | |
378 case '2': | |
379 case '3': | |
380 case '4': | |
381 case '5': | |
382 case '6': | |
383 case '7': | |
384 c -= '0'; | |
385 if (**p < '0' || **p > '9') | |
386 return c; | |
387 c = c << 3; | |
388 c |= **p - '0'; | |
389 (*p)++; | |
390 if (**p < '0' || **p > '9') | |
391 return c; | |
392 c = c << 3; | |
393 c |= **p - '0'; | |
394 (*p)++; | |
395 return c; | |
396 | |
397 // LF | |
398 case 'n': | |
399 return 10; | |
400 | |
401 // CR | |
402 case 'r': | |
403 return 13; | |
404 | |
405 // TAB | |
406 case 't': | |
407 return 9; | |
408 | |
409 // VT | |
410 case 'v': | |
411 return 11; | |
412 | |
413 // BS | |
414 case 'b': | |
415 return 8; | |
416 | |
417 // FF | |
418 case 'f': | |
419 return 12; | |
420 | |
421 // BEL | |
422 case 'a': | |
423 return 7; | |
424 | |
425 // hex char code (2 chars) | |
426 case 'x': | |
427 { | |
428 int c2; | |
429 if (!**p) | |
430 return 'x'; | |
431 c = toupper(**p); | |
432 (*p)++; | |
433 if (c < '0' || (c > '9' && c < 'A') || c > 'F') | |
434 return 0; | |
435 c -= '0'; | |
436 if (c > 9) | |
437 c -= 7; | |
438 c2 = c << 4; | |
439 if (!**p) | |
440 return 0; | |
441 c = toupper(**p); | |
442 (*p)++; | |
443 if (c < '0' || (c > '9' && c < 'A') || c > 'F') | |
444 return 0; | |
445 c -= '0'; | |
446 if (c > 9) | |
447 c -= 7; | |
448 c2 |= c; | |
449 return c2; | |
450 } | |
451 // everything else stands for itself as a fall back or legit | |
452 default: | |
453 return c; | |
454 } | |
455 } | |
456 return c; | |
457 } | |
458 | |
349 OPFUNC(pseudo_fcc) | 459 OPFUNC(pseudo_fcc) |
350 { | 460 { |
351 int delim = 0; | 461 int delim = 0; |
462 int c; | |
352 | 463 |
353 delim = **p; | 464 delim = **p; |
354 if (!delim) | 465 if (!delim) |
355 { | 466 { |
356 register_error(as, l, 1, "Bad operand"); | 467 register_error(as, l, 1, "Bad operand"); |
357 return; | 468 return; |
358 } | 469 } |
359 *p += 1; | 470 *p += 1; |
360 while (**p && **p != delim) | 471 for (;;) |
361 { | 472 { |
362 lwasm_emit(as, l, **p); | 473 c = pseudo_fcc_fetchchar(as, p); |
363 (*p)++; | 474 if (c == delim || c < 0) |
364 } | 475 break; |
365 if (**p) | 476 |
366 (*p)++; | 477 lwasm_emit(as, l, c); |
478 } | |
367 } | 479 } |
368 | 480 |
369 | 481 |
370 OPFUNC(pseudo_fcs) | 482 OPFUNC(pseudo_fcs) |
371 { | 483 { |
372 int delim = 0; | 484 int delim = 0; |
373 | 485 int c, lc = -1; |
486 | |
374 delim = **p; | 487 delim = **p; |
375 if (!delim) | 488 if (!delim) |
376 { | 489 { |
377 register_error(as, l, 1, "Bad operand"); | 490 register_error(as, l, 1, "Bad operand"); |
378 return; | 491 return; |
379 } | 492 } |
380 *p += 1; | 493 *p += 1; |
381 while (**p && **p != delim) | 494 for (;;) |
382 { | 495 { |
383 if (!*((*p) + 1) || *((*p) + 1) == delim) | 496 c = pseudo_fcc_fetchchar(as, p); |
384 lwasm_emit(as, l, **p | 0x80); | 497 if (c == delim || c < 0) |
385 else | 498 { |
386 lwasm_emit(as, l, **p); | 499 if (lc >= 0) |
387 (*p)++; | 500 lwasm_emit(as, l, lc | 0x80); |
388 } | 501 break; |
389 if (**p) | 502 } |
390 (*p)++; | 503 if (lc >= 0) |
504 lwasm_emit(as, l, lc); | |
505 lc = c; | |
506 } | |
391 } | 507 } |
392 | 508 |
393 OPFUNC(pseudo_fcn) | 509 OPFUNC(pseudo_fcn) |
394 { | 510 { |
395 int delim = 0; | 511 int delim = 0; |
396 | 512 int c; |
513 | |
397 delim = **p; | 514 delim = **p; |
398 if (!delim) | 515 if (!delim) |
399 { | 516 { |
400 register_error(as, l, 1, "Bad operand"); | 517 register_error(as, l, 1, "Bad operand"); |
401 return; | 518 return; |
402 } | 519 } |
403 *p += 1; | 520 *p += 1; |
404 while (**p && **p != delim) | 521 for (;;) |
405 { | 522 { |
406 lwasm_emit(as, l, **p); | 523 c = pseudo_fcc_fetchchar(as, p); |
407 (*p)++; | 524 if (c == delim || c < 0) |
408 } | 525 break; |
409 if (**p) | 526 |
410 (*p)++; | 527 lwasm_emit(as, l, c); |
528 } | |
411 lwasm_emit(as, l, 0); | 529 lwasm_emit(as, l, 0); |
412 } | 530 } |
413 | 531 |
414 // FIXME: handle external, etc., references in a useful manner | |
415 OPFUNC(pseudo_fcb) | 532 OPFUNC(pseudo_fcb) |
416 { | 533 { |
417 int r, v; | 534 int r, v; |
418 | 535 |
419 fcb_again: | 536 fcb_again: |
843 s -> obytes = NULL; | 960 s -> obytes = NULL; |
844 s -> oblen = 0; | 961 s -> oblen = 0; |
845 s -> obsize = 0; | 962 s -> obsize = 0; |
846 s -> rl = NULL; | 963 s -> rl = NULL; |
847 s -> exports = NULL; | 964 s -> exports = NULL; |
965 // if name of section is "bss" or ".bss", assume bss flag | |
966 // which can be overridden with !bss flag | |
967 if (!strcasecmp(sn, "bss") || !strcasecmp(sn, ".bss")) | |
968 s -> flags = SECTION_BSS; | |
848 // parse options; only one "bss" | 969 // parse options; only one "bss" |
849 if (opts && as -> passnum == 1) | 970 if (opts && as -> passnum == 1) |
850 { | 971 { |
851 if (!strcasecmp(opts, "bss")) | 972 if (!strcasecmp(opts, "bss")) |
852 { | 973 { |
853 s -> flags = SECTION_BSS; | 974 s -> flags |= SECTION_BSS; |
975 } | |
976 else if (!strcasecmp(opts, "!bss")) | |
977 { | |
978 s -> flags &= ~SECTION_BSS; | |
854 } | 979 } |
855 else | 980 else |
856 { | 981 { |
857 register_error(as, l, 1, "Unrecognized section option '%s'", opts); | 982 register_error(as, l, 1, "Unrecognized section option '%s'", opts); |
858 lwasm_free(s -> name); | 983 lwasm_free(s -> name); |