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);