2 * Copyright (C) 2012-2019 Free Software Foundation, Inc.
4 * This file is part of GNU lightning.
6 * GNU lightning is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published
8 * by the Free Software Foundation; either version 3, or (at your option)
11 * GNU lightning is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 * License for more details.
17 * Paulo Cesar Pereira de Andrade
31 #include <lightning.h>
35 #if defined(__linux__) && (defined(__i386__) || defined(__x86_64__))
36 # include <fpu_control.h>
39 /* The label_t identifier clashes with a system definitions */
40 #if defined(_AIX) || defined(__sun__) || defined(__osf__)
41 # define label_t l_label_t
45 # define DL_HANDLE RTLD_NEXT
47 static void *DL_HANDLE;
48 #elif defined(__osf__)
49 # define DL_HANDLE NULL
51 # define DL_HANDLE RTLD_DEFAULT
55 # define noreturn __attribute__ ((noreturn))
56 # define printf_format(f, v) __attribute__ ((format (printf, f, v)))
57 # define maybe_unused __attribute__ ((unused))
59 # define noreturn /**/
60 # define printf_format(f, v) /**/
61 # define maybe_unused /**/
64 #define check_data(length) \
66 if (data_offset + length > data_length) \
67 error(".data too small (%ld < %ld)", \
68 data_length, data_offset + length); \
71 #define get_label_by_name(name) ((label_t *)get_hash(labels, name))
73 #define PARSING_NONE 0
74 #define PARSING_DATA 1
75 #define PARSING_CODE 2
76 #define MAX_IDENTIFIER 256
81 typedef struct instr instr_t;
82 typedef union value value_t;
83 typedef struct parser parser_t;
84 typedef struct label label_t;
85 typedef struct patch patch_t;
86 typedef struct symbol symbol_t;
87 typedef struct hash hash_t;
88 typedef struct entry entry_t;
89 typedef int (*function_t)(int argc, char *argv[]);
122 #define compose(a, b) (((a) << 8) | b)
124 expr_inc = compose('+', '+'),
125 expr_dec = compose('-', '-'),
133 expr_lsh = compose('<', '<'),
134 expr_rsh = compose('>', '>'),
139 expr_mulset = compose('*', '='),
140 expr_divset = compose('/', '='),
141 expr_remset = compose('%', '='),
142 expr_addset = compose('+', '='),
143 expr_subset = compose('-', '='),
144 expr_lshset = compose(expr_lsh, '='),
145 expr_rshset = compose(expr_rsh, '='),
146 expr_andset = compose('&', '='),
147 expr_orset = compose('|', '='),
148 expr_xorset = compose('^', '='),
150 expr_le = compose('<', '='),
151 expr_eq = compose('=', '='),
152 expr_ne = compose('!', '='),
154 expr_ge = compose('>', '='),
155 expr_andand = compose('&', '&'),
156 expr_oror = compose('|', '|'),
169 void (*function)(void);
194 /* variable length string buffer */
205 unsigned char buffer[4096];
214 label_kind_code_forward,
251 /* minor support for expressions */
262 static jit_gpr_t get_ireg(void);
263 static jit_fpr_t get_freg(void);
264 static symbol_t *get_symbol(void);
265 static void jmp_forward(void *value, label_t *label);
266 static void mov_forward(void *value, label_t *label);
267 static void call_forward(void *value, label_t *label);
268 static void make_arg(void *value);
269 static jit_pointer_t get_arg(void);
270 static jit_word_t get_imm(void);
271 static void live(void);
272 static void align(void); static void name(void);
273 static void prolog(void);
274 static void frame(void); static void tramp(void);
275 static void ellipsis(void);
276 static void allocai(void); static void allocar(void);
277 static void arg(void);
278 static void getarg_c(void); static void getarg_uc(void);
279 static void getarg_s(void); static void getarg_us(void);
280 static void getarg_i(void);
282 static void getarg_ui(void); static void getarg_l(void);
284 static void getarg(void);
285 static void putargr(void); static void putargi(void);
286 static void addr(void); static void addi(void);
287 static void addxr(void); static void addxi(void);
288 static void addcr(void); static void addci(void);
289 static void subr(void); static void subi(void);
290 static void subxr(void); static void subxi(void);
291 static void subcr(void); static void subci(void);
292 static void rsbr(void); static void rsbi(void);
293 static void mulr(void); static void muli(void);
294 static void qmulr(void); static void qmuli(void);
295 static void qmulr_u(void); static void qmuli_u(void);
296 static void divr(void); static void divi(void);
297 static void divr_u(void); static void divi_u(void);
298 static void qdivr(void); static void qdivi(void);
299 static void qdivr_u(void); static void qdivi_u(void);
300 static void remr(void); static void remi(void);
301 static void remr_u(void); static void remi_u(void);
302 static void andr(void); static void andi(void);
303 static void orr(void); static void ori(void);
304 static void xorr(void); static void xori(void);
305 static void lshr(void); static void lshi(void);
306 static void rshr(void); static void rshi(void);
307 static void rshr_u(void); static void rshi_u(void);
308 static void negr(void); static void comr(void);
309 static void ltr(void); static void lti(void);
310 static void ltr_u(void); static void lti_u(void);
311 static void ler(void); static void lei(void);
312 static void ler_u(void); static void lei_u(void);
313 static void eqr(void); static void eqi(void);
314 static void ger(void); static void gei(void);
315 static void ger_u(void); static void gei_u(void);
316 static void gtr(void); static void gti(void);
317 static void gtr_u(void); static void gti_u(void);
318 static void ner(void); static void nei(void);
319 static void casr(void); static void casi(void);
320 static void movr(void); static void movi(void);
321 static void extr_c(void); static void extr_uc(void);
322 static void extr_s(void); static void extr_us(void);
324 static void extr_i(void); static void extr_ui(void);
326 static void htonr_us(void); static void ntohr_us(void);
327 static void htonr_ui(void); static void ntohr_ui(void);
329 static void htonr_ul(void); static void ntohr_ul(void);
331 static void htonr(void); static void ntohr(void);
332 static void bswapr_us(void); static void bswapr_ui(void);
334 static void bswapr_ul(void);
336 static void bswapr(void);
337 static void movnr(void); static void movzr(void);
338 static void ldr_c(void); static void ldi_c(void);
339 static void ldr_uc(void); static void ldi_uc(void);
340 static void ldr_s(void); static void ldi_s(void);
341 static void ldr_us(void); static void ldi_us(void);
342 static void ldr_i(void); static void ldi_i(void);
344 static void ldr_ui(void); static void ldi_ui(void);
345 static void ldr_l(void); static void ldi_l(void);
347 static void ldr(void); static void ldi(void);
348 static void ldxr_c(void); static void ldxi_c(void);
349 static void ldxr_uc(void); static void ldxi_uc(void);
350 static void ldxr_s(void); static void ldxi_s(void);
351 static void ldxr_us(void); static void ldxi_us(void);
352 static void ldxr_i(void); static void ldxi_i(void);
354 static void ldxr_ui(void); static void ldxi_ui(void);
355 static void ldxr_l(void); static void ldxi_l(void);
357 static void ldxr(void); static void ldxi(void);
358 static void str_c(void); static void sti_c(void);
359 static void str_s(void); static void sti_s(void);
360 static void str_i(void); static void sti_i(void);
362 static void str_l(void); static void sti_l(void);
364 static void str(void); static void sti(void);
365 static void stxr_c(void); static void stxi_c(void);
366 static void stxr_s(void); static void stxi_s(void);
367 static void stxr_i(void); static void stxi_i(void);
369 static void stxr_l(void); static void stxi_l(void);
371 static void stxr(void); static void stxi(void);
372 static void bltr(void); static void blti(void);
373 static void bltr_u(void); static void blti_u(void);
374 static void bler(void); static void blei(void);
375 static void bler_u(void); static void blei_u(void);
376 static void beqr(void); static void beqi(void);
377 static void bger(void); static void bgei(void);
378 static void bger_u(void); static void bgei_u(void);
379 static void bgtr(void); static void bgti(void);
380 static void bgtr_u(void); static void bgti_u(void);
381 static void bner(void); static void bnei(void);
382 static void bmsr(void); static void bmsi(void);
383 static void bmcr(void); static void bmci(void);
384 static void boaddr(void); static void boaddi(void);
385 static void boaddr_u(void); static void boaddi_u(void);
386 static void bxaddr(void); static void bxaddi(void);
387 static void bxaddr_u(void); static void bxaddi_u(void);
388 static void bosubr(void); static void bosubi(void);
389 static void bosubr_u(void); static void bosubi_u(void);
390 static void bxsubr(void); static void bxsubi(void);
391 static void bxsubr_u(void); static void bxsubi_u(void);
392 static void jmpr(void); static void jmpi(void);
393 static void callr(void); static void calli(void);
394 static void prepare(void);
395 static void pushargr(void); static void pushargi(void);
396 static void finishr(void); static void finishi(void);
397 static void ret(void);
398 static void retr(void); static void reti(void);
399 static void retval_c(void); static void retval_uc(void);
400 static void retval_s(void); static void retval_us(void);
401 static void retval_i(void);
403 static void retval_ui(void); static void retval_l(void);
405 static void retval(void);
406 static void epilog(void);
407 static void arg_f(void); static void getarg_f(void);
408 static void putargr_f(void); static void putargi_f(void);
409 static void addr_f(void); static void addi_f(void);
410 static void subr_f(void); static void subi_f(void);
411 static void rsbr_f(void); static void rsbi_f(void);
412 static void mulr_f(void); static void muli_f(void);
413 static void divr_f(void); static void divi_f(void);
414 static void negr_f(void); static void absr_f(void);
415 static void sqrtr_f(void);
416 static void ltr_f(void); static void lti_f(void);
417 static void ler_f(void); static void lei_f(void);
418 static void eqr_f(void); static void eqi_f(void);
419 static void ger_f(void); static void gei_f(void);
420 static void gtr_f(void); static void gti_f(void);
421 static void ner_f(void); static void nei_f(void);
422 static void unltr_f(void); static void unlti_f(void);
423 static void unler_f(void); static void unlei_f(void);
424 static void uneqr_f(void); static void uneqi_f(void);
425 static void unger_f(void); static void ungei_f(void);
426 static void ungtr_f(void); static void ungti_f(void);
427 static void ltgtr_f(void); static void ltgti_f(void);
428 static void ordr_f(void); static void ordi_f(void);
429 static void unordr_f(void); static void unordi_f(void);
430 static void truncr_f_i(void);
432 static void truncr_f_l(void);
434 static void truncr_f(void);
435 static void extr_f(void); static void extr_d_f(void);
436 static void movr_f(void); static void movi_f(void);
437 static void ldr_f(void); static void ldi_f(void);
438 static void ldxr_f(void); static void ldxi_f(void);
439 static void str_f(void); static void sti_f(void);
440 static void stxr_f(void); static void stxi_f(void);
441 static void bltr_f(void); static void blti_f(void);
442 static void bler_f(void); static void blei_f(void);
443 static void beqr_f(void); static void beqi_f(void);
444 static void bger_f(void); static void bgei_f(void);
445 static void bgtr_f(void); static void bgti_f(void);
446 static void bner_f(void); static void bnei_f(void);
447 static void bunltr_f(void); static void bunlti_f(void);
448 static void bunler_f(void); static void bunlei_f(void);
449 static void buneqr_f(void); static void buneqi_f(void);
450 static void bunger_f(void); static void bungei_f(void);
451 static void bungtr_f(void); static void bungti_f(void);
452 static void bltgtr_f(void); static void bltgti_f(void);
453 static void bordr_f(void); static void bordi_f(void);
454 static void bunordr_f(void); static void bunordi_f(void);
455 static void pushargr_f(void); static void pushargi_f(void);
456 static void retr_f(void); static void reti_f(void);
457 static void retval_f(void);
458 static void arg_d(void); static void getarg_d(void);
459 static void putargr_d(void); static void putargi_d(void);
460 static void addr_d(void); static void addi_d(void);
461 static void subr_d(void); static void subi_d(void);
462 static void rsbr_d(void); static void rsbi_d(void);
463 static void mulr_d(void); static void muli_d(void);
464 static void divr_d(void); static void divi_d(void);
465 static void negr_d(void); static void absr_d(void);
466 static void sqrtr_d(void);
467 static void ltr_d(void); static void lti_d(void);
468 static void ler_d(void); static void lei_d(void);
469 static void eqr_d(void); static void eqi_d(void);
470 static void ger_d(void); static void gei_d(void);
471 static void gtr_d(void); static void gti_d(void);
472 static void ner_d(void); static void nei_d(void);
473 static void unltr_d(void); static void unlti_d(void);
474 static void unler_d(void); static void unlei_d(void);
475 static void uneqr_d(void); static void uneqi_d(void);
476 static void unger_d(void); static void ungei_d(void);
477 static void ungtr_d(void); static void ungti_d(void);
478 static void ltgtr_d(void); static void ltgti_d(void);
479 static void ordr_d(void); static void ordi_d(void);
480 static void unordr_d(void); static void unordi_d(void);
481 static void truncr_d_i(void);
483 static void truncr_d_l(void);
485 static void truncr_d(void);
486 static void extr_d(void); static void extr_f_d(void);
487 static void movr_d(void); static void movi_d(void);
488 static void ldr_d(void); static void ldi_d(void);
489 static void ldxr_d(void); static void ldxi_d(void);
490 static void str_d(void); static void sti_d(void);
491 static void stxr_d(void); static void stxi_d(void);
492 static void bltr_d(void); static void blti_d(void);
493 static void bler_d(void); static void blei_d(void);
494 static void beqr_d(void); static void beqi_d(void);
495 static void bger_d(void); static void bgei_d(void);
496 static void bgtr_d(void); static void bgti_d(void);
497 static void bner_d(void); static void bnei_d(void);
498 static void bunltr_d(void); static void bunlti_d(void);
499 static void bunler_d(void); static void bunlei_d(void);
500 static void buneqr_d(void); static void buneqi_d(void);
501 static void bunger_d(void); static void bungei_d(void);
502 static void bungtr_d(void); static void bungti_d(void);
503 static void bltgtr_d(void); static void bltgti_d(void);
504 static void bordr_d(void); static void bordi_d(void);
505 static void bunordr_d(void); static void bunordi_d(void);
506 static void pushargr_d(void); static void pushargi_d(void);
507 static void retr_d(void); static void reti_d(void);
508 static void retval_d(void);
509 static void vastart(void); static void vapush(void);
510 static void vaarg(void); static void vaarg_d(void);
511 static void vaend(void);
513 static void error(const char *format, ...) noreturn printf_format(1, 2);
514 static void warn(const char *format, ...) printf_format(1, 2) maybe_unused;
515 static void message(const char *kind, const char *format, va_list ap);
517 static int getch(void);
518 static int getch_noeof(void);
519 static int ungetch(int ch);
520 static int skipws(void);
521 static int skipnl(void);
522 static int skipct(void);
523 static int skipcp(void);
524 static jit_word_t get_int(skip_t skip);
525 static jit_uword_t get_uint(skip_t skip);
526 static double get_float(skip_t skip);
527 static float make_float(double d);
528 static void *get_pointer(skip_t skip);
529 static label_t *get_label(skip_t skip);
530 static token_t regname(void);
531 static token_t identifier(int ch);
532 static void get_data(type_t type);
533 static void dot(void);
534 static token_t number(int ch);
535 static int escape(int ch);
536 static token_t string(void);
537 static token_t dynamic(void);
538 static token_t character(void);
539 static void expression_prim(void);
540 static void expression_inc(int pre);
541 static void expression_dec(int pre);
542 static void expression_unary(void);
543 static void expression_mul(void);
544 static void expression_add(void);
545 static void expression_shift(void);
546 static void expression_bit(void);
547 static void expression_rel(void);
548 static void expression_cond(void);
549 static token_t expression(void);
550 static token_t primary(skip_t skip);
551 static void parse(void);
552 static int execute(int argc, char *argv[]);
554 static void *xmalloc(size_t size);
555 static void *xrealloc(void *pointer, size_t size);
556 static void *xcalloc(size_t nmemb, size_t size);
558 static label_t *new_label(label_kind_t kind, char *name, void *value);
559 static patch_t *new_patch(patch_kind_t kind, label_t *label, void *value);
560 static int bcmp_symbols(const void *left, const void *right);
561 static int qcmp_symbols(const void *left, const void *right);
562 static symbol_t *new_symbol(char *name);
563 static symbol_t *get_symbol_by_name(char *name);
565 static hash_t *new_hash(void);
566 static int hash_string(char *name);
567 static void put_hash(hash_t *hash, entry_t *entry);
568 static entry_t *get_hash(hash_t *hash, char *name);
569 static void rehash(hash_t *hash);
574 static jit_state_t *_jit;
575 static int flag_verbose;
576 static int flag_data;
577 static int flag_disasm;
578 static char *progname;
579 static parser_t parser;
580 static hash_t *labels;
581 static int label_offset;
582 static patch_t *patches;
583 static symbol_t **symbols;
584 static int symbol_length;
585 static int symbol_offset;
586 static hash_t *instrs;
588 static size_t data_offset, data_length;
589 static instr_t instr_vector[] = {
590 #define entry(value) { NULL, #value, value }
591 #define entry2(name, function) { NULL, name, function }
593 entry(align), entry(name),
595 entry(frame), entry(tramp),
597 entry(allocai), entry(allocar),
599 entry(getarg_c), entry(getarg_uc),
600 entry(getarg_s), entry(getarg_us),
603 entry(getarg_ui), entry(getarg_l),
606 entry(putargr), entry(putargi),
607 entry(addr), entry(addi),
608 entry(addxr), entry(addxi),
609 entry(addcr), entry(addci),
610 entry(subr), entry(subi),
611 entry(subxr), entry(subxi),
612 entry(subcr), entry(subci),
613 entry(rsbr), entry(rsbi),
614 entry(mulr), entry(muli),
615 entry(qmulr), entry(qmuli),
616 entry(qmulr_u), entry(qmuli_u),
617 entry(divr), entry(divi),
618 entry(divr_u), entry(divi_u),
619 entry(qdivr), entry(qdivi),
620 entry(qdivr_u), entry(qdivi_u),
621 entry(remr), entry(remi),
622 entry(remr_u), entry(remi_u),
623 entry(andr), entry(andi),
624 entry(orr), entry(ori),
625 entry(xorr), entry(xori),
626 entry(lshr), entry(lshi),
627 entry(rshr), entry(rshi),
628 entry(rshr_u), entry(rshi_u),
629 entry(negr), entry(comr),
630 entry(ltr), entry(lti),
631 entry(ltr_u), entry(lti_u),
632 entry(ler), entry(lei),
633 entry(ler_u), entry(lei_u),
634 entry(eqr), entry(eqi),
635 entry(ger), entry(gei),
636 entry(ger_u), entry(gei_u),
637 entry(gtr), entry(gti),
638 entry(gtr_u), entry(gti_u),
639 entry(ner), entry(nei),
640 entry(casr), entry(casi),
641 entry(movr), entry(movi),
642 entry(extr_c), entry(extr_uc),
643 entry(extr_s), entry(extr_us),
645 entry(extr_i), entry(extr_ui),
647 entry(htonr_us), entry(ntohr_us),
648 entry(htonr_ui), entry(ntohr_ui),
650 entry(htonr_ul), entry(ntohr_ul),
652 entry(htonr), entry(ntohr),
653 entry(bswapr_us), entry(bswapr_ui),
658 entry(movnr), entry(movzr),
659 entry(ldr_c), entry(ldi_c),
660 entry(ldr_uc), entry(ldi_uc),
661 entry(ldr_s), entry(ldi_s),
662 entry(ldr_us), entry(ldi_us),
663 entry(ldr_i), entry(ldi_i),
665 entry(ldr_ui), entry(ldi_ui),
666 entry(ldr_l), entry(ldi_l),
668 entry(ldr), entry(ldi),
669 entry(ldxr_c), entry(ldxi_c),
670 entry(ldxr_uc), entry(ldxi_uc),
671 entry(ldxr_s), entry(ldxi_s),
672 entry(ldxr_us), entry(ldxi_us),
673 entry(ldxr_i), entry(ldxi_i),
675 entry(ldxr_ui), entry(ldxi_ui),
676 entry(ldxr_l), entry(ldxi_l),
678 entry(ldxr), entry(ldxi),
679 entry(str_c), entry(sti_c),
680 entry(str_s), entry(sti_s),
681 entry(str_i), entry(sti_i),
683 entry(str_l), entry(sti_l),
685 entry(str), entry(sti),
686 entry(stxr_c), entry(stxi_c),
687 entry(stxr_s), entry(stxi_s),
688 entry(stxr_i), entry(stxi_i),
690 entry(stxr_l), entry(stxi_l),
692 entry(stxr), entry(stxi),
693 entry(bltr), entry(blti),
694 entry(bltr_u), entry(blti_u),
695 entry(bler), entry(blei),
696 entry(bler_u), entry(blei_u),
697 entry(beqr), entry(beqi),
698 entry(bger), entry(bgei),
699 entry(bger_u), entry(bgei_u),
700 entry(bgtr), entry(bgti),
701 entry(bgtr_u), entry(bgti_u),
702 entry(bner), entry(bnei),
703 entry(bmsr), entry(bmsi),
704 entry(bmcr), entry(bmci),
705 entry(boaddr), entry(boaddi),
706 entry(boaddr_u), entry(boaddi_u),
707 entry(bxaddr), entry(bxaddi),
708 entry(bxaddr_u), entry(bxaddi_u),
709 entry(bosubr), entry(bosubi),
710 entry(bosubr_u), entry(bosubi_u),
711 entry(bxsubr), entry(bxsubi),
712 entry(bxsubr_u), entry(bxsubi_u),
713 entry(jmpr), entry(jmpi),
714 entry(callr), entry(calli),
716 entry(pushargr), entry(pushargi),
717 entry(finishr), entry(finishi),
719 entry(retr), entry(reti),
720 entry(retval_c), entry(retval_uc),
721 entry(retval_s), entry(retval_us),
724 entry(retval_ui), entry(retval_l),
728 entry(arg_f), entry(getarg_f),
729 entry(putargr_f), entry(putargi_f),
730 entry(addr_f), entry(addi_f),
731 entry(subr_f), entry(subi_f),
732 entry(rsbr_f), entry(rsbi_f),
733 entry(mulr_f), entry(muli_f),
734 entry(divr_f), entry(divi_f),
735 entry(negr_f), entry(absr_f),
737 entry(ltr_f), entry(lti_f),
738 entry(ler_f), entry(lei_f),
739 entry(eqr_f), entry(eqi_f),
740 entry(ger_f), entry(gei_f),
741 entry(gtr_f), entry(gti_f),
742 entry(ner_f), entry(nei_f),
743 entry(unltr_f), entry(unlti_f),
744 entry(unler_f), entry(unlei_f),
745 entry(uneqr_f), entry(uneqi_f),
746 entry(unger_f), entry(ungei_f),
747 entry(ungtr_f), entry(ungti_f),
748 entry(ltgtr_f), entry(ltgti_f),
749 entry(ordr_f), entry(ordi_f),
750 entry(unordr_f), entry(unordi_f),
756 entry(extr_f), entry(extr_d_f),
757 entry(movr_f), entry(movi_f),
758 entry(ldr_f), entry(ldi_f),
759 entry(ldxr_f), entry(ldxi_f),
760 entry(str_f), entry(sti_f),
761 entry(stxr_f), entry(stxi_f),
762 entry(bltr_f), entry(blti_f),
763 entry(bler_f), entry(blei_f),
764 entry(beqr_f), entry(beqi_f),
765 entry(bger_f), entry(bgei_f),
766 entry(bgtr_f), entry(bgti_f),
767 entry(bner_f), entry(bnei_f),
768 entry(bunltr_f), entry(bunlti_f),
769 entry(bunler_f), entry(bunlei_f),
770 entry(buneqr_f), entry(buneqi_f),
771 entry(bunger_f), entry(bungei_f),
772 entry(bungtr_f), entry(bungti_f),
773 entry(bltgtr_f), entry(bltgti_f),
774 entry(bordr_f), entry(bordi_f),
775 entry(bunordr_f), entry(bunordi_f),
776 entry(pushargr_f), entry(pushargi_f),
777 entry(retr_f), entry(reti_f),
779 entry(arg_d), entry(getarg_d),
780 entry(putargr_d), entry(putargi_d),
781 entry(addr_d), entry(addi_d),
782 entry(subr_d), entry(subi_d),
783 entry(rsbr_d), entry(rsbi_d),
784 entry(mulr_d), entry(muli_d),
785 entry(divr_d), entry(divi_d),
786 entry(negr_d), entry(absr_d),
788 entry(ltr_d), entry(lti_d),
789 entry(ler_d), entry(lei_d),
790 entry(eqr_d), entry(eqi_d),
791 entry(ger_d), entry(gei_d),
792 entry(gtr_d), entry(gti_d),
793 entry(ner_d), entry(nei_d),
794 entry(unltr_d), entry(unlti_d),
795 entry(unler_d), entry(unlei_d),
796 entry(uneqr_d), entry(uneqi_d),
797 entry(unger_d), entry(ungei_d),
798 entry(ungtr_d), entry(ungti_d),
799 entry(ltgtr_d), entry(ltgti_d),
800 entry(ordr_d), entry(ordi_d),
801 entry(unordr_d), entry(unordi_d),
807 entry(extr_d), entry(extr_f_d),
808 entry(movr_d), entry(movi_d),
809 entry(ldr_d), entry(ldi_d),
810 entry(ldxr_d), entry(ldxi_d),
811 entry(str_d), entry(sti_d),
812 entry(stxr_d), entry(stxi_d),
813 entry(bltr_d), entry(blti_d),
814 entry(bler_d), entry(blei_d),
815 entry(beqr_d), entry(beqi_d),
816 entry(bger_d), entry(bgei_d),
817 entry(bgtr_d), entry(bgti_d),
818 entry(bner_d), entry(bnei_d),
819 entry(bunltr_d), entry(bunlti_d),
820 entry(bunler_d), entry(bunlei_d),
821 entry(buneqr_d), entry(buneqi_d),
822 entry(bunger_d), entry(bungei_d),
823 entry(bungtr_d), entry(bungti_d),
824 entry(bltgtr_d), entry(bltgti_d),
825 entry(bordr_d), entry(bordi_d),
826 entry(bunordr_d), entry(bunordi_d),
827 entry(pushargr_d), entry(pushargi_d),
828 entry(retr_d), entry(reti_d),
830 entry2("va_start", vastart),
831 entry2("va_push", vapush),
832 entry2("va_arg", vaarg),
833 entry2("va_arg_d", vaarg_d),
834 entry2("va_end", vaend),
844 if (primary(skip_ws) != tok_register)
845 error("bad register");
846 if (parser.regtype != type_l)
847 error("bad int register");
849 return ((jit_gpr_t)parser.regval);
855 if (primary(skip_ws) != tok_register)
856 error("bad register");
857 if (parser.regtype != type_d)
858 error("bad float register");
860 return ((jit_fpr_t)parser.regval);
870 error("expecting variable");
871 (void)identifier('$');
872 if (parser.string[1] == '\0')
873 error("expecting variable");
874 if ((symbol = get_symbol_by_name(parser.string)) == NULL)
875 symbol = new_symbol(parser.string);
881 jmp_forward(void *value, label_t *label)
883 (void)new_patch(patch_kind_jmp, label, value);
887 mov_forward(void *value, label_t *label)
889 (void)new_patch(patch_kind_mov, label, value);
893 call_forward(void *value, label_t *label)
895 (void)new_patch(patch_kind_call, label, value);
899 make_arg(void *value)
901 symbol_t *symbol = get_symbol();
903 symbol->type = type_p;
904 symbol->value.p = value;
910 symbol_t *symbol = get_symbol();
912 if (symbol->type != type_p)
913 error("bad argument %s type", symbol->name);
915 return symbol->value.p;
926 case '+': case '-': case '0' ... '9':
928 value = get_int(skip_none);
932 value = parser.value.i;
935 switch (expression()) {
938 value = parser.value.i;
941 error("expecting immediate");
946 value = (jit_word_t)parser.value.p;
950 label = get_label(skip_none);
951 if (label->kind == label_kind_data)
952 value = (jit_word_t)label->value;
954 error("expecting immediate");
960 #define entry(name) \
966 #define entry_ca(name) \
970 make_arg(jit_##name()); \
972 #define entry_ia(name) \
976 jit_gpr_t r0 = get_ireg(); \
977 jit_pointer_t ac = get_arg(); \
978 jit_##name(r0, ac); \
980 #define entry_im(name) \
984 jit_word_t im = get_imm(); \
987 #define entry_ir(name) \
991 jit_gpr_t r0 = get_ireg(); \
994 #define entry_ima(name) \
998 jit_word_t im = get_imm(); \
999 jit_pointer_t ac = get_arg(); \
1000 jit_##name(im, ac); \
1002 #define entry_ir_ir_ir(name) \
1006 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(), r2 = get_ireg(); \
1007 jit_##name(r0, r1, r2); \
1009 #define entry_ir_ir_im(name) \
1013 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \
1014 jit_word_t im = get_imm(); \
1015 jit_##name(r0, r1, im); \
1017 #define entry_ir_ir_ir_ir(name) \
1021 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(), \
1022 r2 = get_ireg(), r3 = get_ireg(); \
1023 jit_##name(r0, r1, r2, r3); \
1025 #define entry_ir_ir_ir_im(name) \
1029 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(), r2 = get_ireg(); \
1030 jit_word_t im = get_imm(); \
1031 jit_##name(r0, r1, r2, im); \
1033 #define entry_ir_im_ir_ir(name) \
1037 jit_gpr_t r0 = get_ireg(); \
1038 jit_word_t im = get_imm(); \
1039 jit_gpr_t r1 = get_ireg(), r2 = get_ireg(); \
1040 jit_##name(r0, im, r1, r2); \
1043 #define entry_ir_ir(name) \
1047 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \
1048 jit_##name(r0, r1); \
1050 #define entry_ir_im(name) \
1054 jit_gpr_t r0 = get_ireg(); \
1055 jit_word_t im = get_imm(); \
1056 jit_##name(r0, im); \
1058 #define entry_ir_pm(name) \
1062 jit_gpr_t r0 = get_ireg(); \
1063 void *pm = get_pointer(skip_ws); \
1064 jit_##name(r0, pm); \
1066 #define entry_pm_ir(name) \
1070 void *pm = get_pointer(skip_ws); \
1071 jit_gpr_t r0 = get_ireg(); \
1072 jit_##name(pm, r0); \
1074 #define entry_im_ir_ir(name) \
1078 jit_word_t im = get_imm(); \
1079 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \
1080 (void)jit_##name(im, r0, r1); \
1082 #define entry_lb_ir_ir(name) \
1087 label_t *label = get_label(skip_ws); \
1088 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \
1089 if (label->kind == label_kind_code_forward) \
1090 jmp_forward((void *)jit_##name(r0, r1), label); \
1092 jmp = jit_##name(r0, r1); \
1093 jit_patch_at(jmp, (jit_node_t *)label->value); \
1096 #define entry_lb_ir_im(name) \
1101 label_t *label = get_label(skip_ws); \
1102 jit_gpr_t r0 = get_ireg(); \
1103 jit_word_t im = get_imm(); \
1104 if (label->kind == label_kind_code_forward) \
1105 jmp_forward((void *)jit_##name(r0, im), label); \
1107 jmp = jit_##name(r0, im); \
1108 jit_patch_at(jmp, (jit_node_t *)label->value); \
1111 #define entry_lb(name) \
1116 label_t *label = get_label(skip_ws); \
1117 if (label->kind == label_kind_code_forward) \
1118 jmp_forward((void *)jit_##name(), label); \
1120 jmp = jit_##name(); \
1121 jit_patch_at(jmp, (jit_node_t *)label->value); \
1124 #define entry_pm(name) \
1128 void *pm = get_pointer(skip_ws); \
1131 #define entry_fa(name) \
1135 jit_fpr_t r0 = get_freg(); \
1136 jit_pointer_t ac = get_arg(); \
1137 jit_##name(r0, ac); \
1139 #define entry_fma(name) \
1143 jit_float64_t im = get_float(skip_ws); \
1144 jit_pointer_t ac = get_arg(); \
1145 jit_##name(im, ac); \
1147 #define entry_fr_fr_fr(name) \
1151 jit_fpr_t r0 = get_freg(), r1 = get_freg(), r2 = get_freg(); \
1152 jit_##name(r0, r1, r2); \
1154 #define entry_fr_fr_fm(name) \
1158 jit_fpr_t r0 = get_freg(), r1 = get_freg(); \
1159 jit_float64_t im = get_float(skip_ws); \
1160 jit_##name(r0, r1, make_float(im)); \
1162 #define entry_fr_fr_dm(name) \
1166 jit_fpr_t r0 = get_freg(), r1 = get_freg(); \
1167 jit_float64_t im = get_float(skip_ws); \
1168 jit_##name(r0, r1, im); \
1170 #define entry_fr_fr(name) \
1174 jit_fpr_t r0 = get_freg(), r1 = get_freg(); \
1175 jit_##name(r0, r1); \
1177 #define entry_ir_fr_fr(name) \
1181 jit_gpr_t r0 = get_ireg(); \
1182 jit_fpr_t r1 = get_freg(), r2 = get_freg(); \
1183 jit_##name(r0, r1, r2); \
1185 #define entry_ir_fr_fm(name) \
1189 jit_gpr_t r0 = get_ireg(); \
1190 jit_fpr_t r1 = get_freg(); \
1191 jit_float64_t im = get_float(skip_ws); \
1192 jit_##name(r0, r1, make_float(im)); \
1194 #define entry_ir_fr_dm(name) \
1198 jit_gpr_t r0 = get_ireg(); \
1199 jit_fpr_t r1 = get_freg(); \
1200 jit_float64_t im = get_float(skip_ws); \
1201 jit_##name(r0, r1, im); \
1203 #define entry_ir_fr(name) \
1207 jit_gpr_t r0 = get_ireg(); \
1208 jit_fpr_t r1 = get_freg(); \
1209 jit_##name(r0, r1); \
1211 #define entry_fr_ir(name) \
1215 jit_fpr_t r0 = get_freg(); \
1216 jit_gpr_t r1 = get_ireg(); \
1217 jit_##name(r0, r1); \
1219 #define entry_fr_fm(name) \
1223 jit_fpr_t r0 = get_freg(); \
1224 jit_float64_t im = get_float(skip_ws); \
1225 jit_##name(r0, make_float(im)); \
1227 #define entry_fr_dm(name) \
1231 jit_fpr_t r0 = get_freg(); \
1232 jit_float64_t im = get_float(skip_ws); \
1233 jit_##name(r0, im); \
1235 #define entry_fr_pm(name) \
1239 jit_fpr_t r0 = get_freg(); \
1240 void *pm = get_pointer(skip_ws); \
1241 jit_##name(r0, pm); \
1243 #define entry_fr_ir_ir(name) \
1247 jit_fpr_t r0 = get_freg(); \
1248 jit_gpr_t r1 = get_ireg(), r2 = get_ireg(); \
1249 jit_##name(r0, r1, r2); \
1251 #define entry_fr_ir_im(name) \
1255 jit_fpr_t r0 = get_freg(); \
1256 jit_gpr_t r1 = get_ireg(); \
1257 jit_word_t im = get_imm(); \
1258 jit_##name(r0, r1, im); \
1260 #define entry_pm_fr(name) \
1264 void *pm = get_pointer(skip_ws); \
1265 jit_fpr_t r0 = get_freg(); \
1266 jit_##name(pm, r0); \
1268 #define entry_ir_ir_fr(name) \
1272 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \
1273 jit_fpr_t r2 = get_freg(); \
1274 jit_##name(r0, r1, r2); \
1276 #define entry_im_ir_fr(name) \
1280 jit_word_t im = get_imm(); \
1281 jit_gpr_t r0 = get_ireg(); \
1282 jit_fpr_t r1 = get_freg(); \
1283 jit_##name(im, r0, r1); \
1285 #define entry_lb_fr_fr(name) \
1290 label_t *label = get_label(skip_ws); \
1291 jit_fpr_t r0 = get_freg(), r1 = get_freg(); \
1292 if (label->kind == label_kind_code_forward) \
1293 jmp_forward((void *)jit_##name(r0, r1), label); \
1295 jmp = jit_##name(r0, r1); \
1296 jit_patch_at(jmp, (jit_node_t *)label->value); \
1299 #define entry_lb_fr_fm(name) \
1304 label_t *label = get_label(skip_ws); \
1305 jit_fpr_t r0 = get_freg(); \
1306 jit_float64_t im = get_float(skip_ws); \
1307 if (label->kind == label_kind_code_forward) \
1308 jmp_forward((void *)jit_##name(r0, make_float(im)), label); \
1310 jmp = jit_##name(r0, make_float(im)); \
1311 jit_patch_at(jmp, (jit_node_t *)label->value); \
1314 #define entry_lb_fr_dm(name) \
1319 label_t *label = get_label(skip_ws); \
1320 jit_fpr_t r0 = get_freg(); \
1321 jit_float64_t im = get_float(skip_ws); \
1322 if (label->kind == label_kind_code_forward) \
1323 jmp_forward((void *)jit_##name(r0, im), label); \
1325 jmp = jit_##name(r0, im); \
1326 jit_patch_at(jmp, (jit_node_t *)label->value); \
1329 #define entry_fr(name) \
1333 jit_fpr_t r0 = get_freg(); \
1336 #define entry_fm(name) \
1340 jit_float64_t im = get_float(skip_ws); \
1341 jit_##name(make_float(im)); \
1343 #define entry_dm(name) \
1347 jit_float64_t im = get_float(skip_ws); \
1350 #define entry_fn(name) \
1361 value = (void *)(jit_word_t)get_uint(skip_none); \
1364 switch (expression()) { \
1366 value = (void *)parser.value.i; \
1369 value = parser.value.p; \
1372 error("expecting pointer"); \
1377 value = parser.value.p; \
1381 label = get_label(skip_none); \
1382 if (label->kind == label_kind_code_forward) \
1383 call_forward((void *)jit_##name(NULL), label); \
1385 jit_patch_at(jit_##name(NULL), label->value); \
1388 jit_##name(value); \
1393 (void)identifier(ch);
1394 jit_name(parser.string);
1398 if (primary(skip_ws) != tok_register)
1399 error("bad register");
1400 jit_live(parser.regval);
1404 entry_im(frame) entry_im(tramp)
1409 jit_word_t i, im = get_imm();
1410 i = jit_allocai(im);
1411 symbol = get_symbol();
1412 symbol->type = type_l;
1413 symbol->value.i = i;
1415 entry_ir_ir(allocar)
1417 entry_ia(getarg_c) entry_ia(getarg_uc)
1418 entry_ia(getarg_s) entry_ia(getarg_us)
1420 #if __WORDSIZE == 64
1421 entry_ia(getarg_ui) entry_ia(getarg_l)
1424 entry_ia(putargr) entry_ima(putargi)
1425 entry_ir_ir_ir(addr) entry_ir_ir_im(addi)
1426 entry_ir_ir_ir(addxr) entry_ir_ir_im(addxi)
1427 entry_ir_ir_ir(addcr) entry_ir_ir_im(addci)
1428 entry_ir_ir_ir(subr) entry_ir_ir_im(subi)
1429 entry_ir_ir_ir(subxr) entry_ir_ir_im(subxi)
1430 entry_ir_ir_ir(subcr) entry_ir_ir_im(subci)
1431 entry_ir_ir_ir(rsbr) entry_ir_ir_im(rsbi)
1432 entry_ir_ir_ir(mulr) entry_ir_ir_im(muli)
1433 entry_ir_ir_ir_ir(qmulr) entry_ir_ir_ir_im(qmuli)
1434 entry_ir_ir_ir_ir(qmulr_u) entry_ir_ir_ir_im(qmuli_u)
1435 entry_ir_ir_ir(divr) entry_ir_ir_im(divi)
1436 entry_ir_ir_ir(divr_u) entry_ir_ir_im(divi_u)
1437 entry_ir_ir_ir_ir(qdivr) entry_ir_ir_ir_im(qdivi)
1438 entry_ir_ir_ir_ir(qdivr_u) entry_ir_ir_ir_im(qdivi_u)
1439 entry_ir_ir_ir(remr) entry_ir_ir_im(remi)
1440 entry_ir_ir_ir(remr_u) entry_ir_ir_im(remi_u)
1441 entry_ir_ir_ir(andr) entry_ir_ir_im(andi)
1442 entry_ir_ir_ir(orr) entry_ir_ir_im(ori)
1443 entry_ir_ir_ir(xorr) entry_ir_ir_im(xori)
1444 entry_ir_ir_ir(lshr) entry_ir_ir_im(lshi)
1445 entry_ir_ir_ir(rshr) entry_ir_ir_im(rshi)
1446 entry_ir_ir_ir(rshr_u) entry_ir_ir_im(rshi_u)
1447 entry_ir_ir(negr) entry_ir_ir(comr)
1448 entry_ir_ir_ir(ltr) entry_ir_ir_im(lti)
1449 entry_ir_ir_ir(ltr_u) entry_ir_ir_im(lti_u)
1450 entry_ir_ir_ir(ler) entry_ir_ir_im(lei)
1451 entry_ir_ir_ir(ler_u) entry_ir_ir_im(lei_u)
1452 entry_ir_ir_ir(eqr) entry_ir_ir_im(eqi)
1453 entry_ir_ir_ir(ger) entry_ir_ir_im(gei)
1454 entry_ir_ir_ir(ger_u) entry_ir_ir_im(gei_u)
1455 entry_ir_ir_ir(gtr) entry_ir_ir_im(gti)
1456 entry_ir_ir_ir(gtr_u) entry_ir_ir_im(gti_u)
1457 entry_ir_ir_ir(ner) entry_ir_ir_im(nei)
1458 entry_ir_ir_ir_ir(casr) entry_ir_im_ir_ir(casi)
1466 jit_gpr_t r0 = get_ireg();
1472 value = (void *)(jit_word_t)get_uint(skip_none);
1476 value = (void *)parser.value.i;
1479 switch (expression()) {
1481 value = (void *)parser.value.i;
1484 value = parser.value.p;
1487 error("expecting pointer");
1492 value = parser.value.p;
1496 label = get_label(skip_none);
1497 if (label->kind == label_kind_code ||
1498 label->kind == label_kind_code_forward) {
1499 mov_forward((void *)jit_movi(r0, 0), label);
1502 value = label->value;
1505 jit_movi(r0, (jit_word_t)value);
1507 entry_ir_ir(extr_c) entry_ir_ir(extr_uc)
1508 entry_ir_ir(extr_s) entry_ir_ir(extr_us)
1509 #if __WORDSIZE == 64
1510 entry_ir_ir(extr_i) entry_ir_ir(extr_ui)
1512 entry_ir_ir(htonr_us) entry_ir_ir(ntohr_us)
1513 entry_ir_ir(htonr_ui) entry_ir_ir(ntohr_ui)
1514 #if __WORDSIZE == 64
1515 entry_ir_ir(htonr_ul) entry_ir_ir(ntohr_ul)
1517 entry_ir_ir(htonr) entry_ir_ir(ntohr)
1518 entry_ir_ir(bswapr_us) entry_ir_ir(bswapr_ui)
1519 #if __WORDSIZE == 64
1520 entry_ir_ir(bswapr_ul)
1523 entry_ir_ir_ir(movnr) entry_ir_ir_ir(movzr)
1524 entry_ir_ir(ldr_c) entry_ir_pm(ldi_c)
1525 entry_ir_ir(ldr_uc) entry_ir_pm(ldi_uc)
1526 entry_ir_ir(ldr_s) entry_ir_pm(ldi_s)
1527 entry_ir_ir(ldr_us) entry_ir_pm(ldi_us)
1528 entry_ir_ir(ldr_i) entry_ir_pm(ldi_i)
1529 #if __WORDSIZE == 64
1530 entry_ir_ir(ldr_ui) entry_ir_pm(ldi_ui)
1531 entry_ir_ir(ldr_l) entry_ir_pm(ldi_l)
1533 entry_ir_ir(ldr) entry_ir_pm(ldi)
1534 entry_ir_ir_ir(ldxr_c) entry_ir_ir_im(ldxi_c)
1535 entry_ir_ir_ir(ldxr_uc) entry_ir_ir_im(ldxi_uc)
1536 entry_ir_ir_ir(ldxr_s) entry_ir_ir_im(ldxi_s)
1537 entry_ir_ir_ir(ldxr_us) entry_ir_ir_im(ldxi_us)
1538 entry_ir_ir_ir(ldxr_i) entry_ir_ir_im(ldxi_i)
1539 #if __WORDSIZE == 64
1540 entry_ir_ir_ir(ldxr_ui) entry_ir_ir_im(ldxi_ui)
1541 entry_ir_ir_ir(ldxr_l) entry_ir_ir_im(ldxi_l)
1543 entry_ir_ir_ir(ldxr) entry_ir_ir_im(ldxi)
1544 entry_ir_ir(str_c) entry_pm_ir(sti_c)
1545 entry_ir_ir(str_s) entry_pm_ir(sti_s)
1546 entry_ir_ir(str_i) entry_pm_ir(sti_i)
1547 #if __WORDSIZE == 64
1548 entry_ir_ir(str_l) entry_pm_ir(sti_l)
1550 entry_ir_ir(str) entry_pm_ir(sti)
1551 entry_ir_ir_ir(stxr_c) entry_im_ir_ir(stxi_c)
1552 entry_ir_ir_ir(stxr_s) entry_im_ir_ir(stxi_s)
1553 entry_ir_ir_ir(stxr_i) entry_im_ir_ir(stxi_i)
1554 #if __WORDSIZE == 64
1555 entry_ir_ir_ir(stxr_l) entry_im_ir_ir(stxi_l)
1557 entry_ir_ir_ir(stxr) entry_im_ir_ir(stxi)
1558 entry_lb_ir_ir(bltr) entry_lb_ir_im(blti)
1559 entry_lb_ir_ir(bltr_u) entry_lb_ir_im(blti_u)
1560 entry_lb_ir_ir(bler) entry_lb_ir_im(blei)
1561 entry_lb_ir_ir(bler_u) entry_lb_ir_im(blei_u)
1562 entry_lb_ir_ir(beqr) entry_lb_ir_im(beqi)
1563 entry_lb_ir_ir(bger) entry_lb_ir_im(bgei)
1564 entry_lb_ir_ir(bger_u) entry_lb_ir_im(bgei_u)
1565 entry_lb_ir_ir(bgtr) entry_lb_ir_im(bgti)
1566 entry_lb_ir_ir(bgtr_u) entry_lb_ir_im(bgti_u)
1567 entry_lb_ir_ir(bner) entry_lb_ir_im(bnei)
1568 entry_lb_ir_ir(bmsr) entry_lb_ir_im(bmsi)
1569 entry_lb_ir_ir(bmcr) entry_lb_ir_im(bmci)
1570 entry_lb_ir_ir(boaddr) entry_lb_ir_im(boaddi)
1571 entry_lb_ir_ir(boaddr_u) entry_lb_ir_im(boaddi_u)
1572 entry_lb_ir_ir(bxaddr) entry_lb_ir_im(bxaddi)
1573 entry_lb_ir_ir(bxaddr_u) entry_lb_ir_im(bxaddi_u)
1574 entry_lb_ir_ir(bosubr) entry_lb_ir_im(bosubi)
1575 entry_lb_ir_ir(bosubr_u) entry_lb_ir_im(bosubi_u)
1576 entry_lb_ir_ir(bxsubr) entry_lb_ir_im(bxsubi)
1577 entry_lb_ir_ir(bxsubr_u) entry_lb_ir_im(bxsubi_u)
1578 entry_ir(jmpr) entry_lb(jmpi)
1579 entry_ir(callr) entry_fn(calli)
1581 entry_ir(pushargr) entry_im(pushargi)
1582 entry_ir(finishr) entry_fn(finishi)
1584 entry_ir(retr) entry_im(reti)
1585 entry_ir(retval_c) entry_ir(retval_uc)
1586 entry_ir(retval_s) entry_ir(retval_us)
1588 #if __WORDSIZE == 64
1589 entry_ir(retval_ui) entry_ir(retval_l)
1593 entry_ca(arg_f) entry_fa(getarg_f)
1594 entry_fa(putargr_f) entry_fma(putargi_f)
1595 entry_fr_fr_fr(addr_f) entry_fr_fr_fm(addi_f)
1596 entry_fr_fr_fr(subr_f) entry_fr_fr_fm(subi_f)
1597 entry_fr_fr_fr(rsbr_f) entry_fr_fr_fm(rsbi_f)
1598 entry_fr_fr_fr(mulr_f) entry_fr_fr_fm(muli_f)
1599 entry_fr_fr_fr(divr_f) entry_fr_fr_fm(divi_f)
1600 entry_fr_fr(negr_f) entry_fr_fr(absr_f)
1601 entry_fr_fr(sqrtr_f)
1602 entry_ir_fr_fr(ltr_f) entry_ir_fr_fm(lti_f)
1603 entry_ir_fr_fr(ler_f) entry_ir_fr_fm(lei_f)
1604 entry_ir_fr_fr(eqr_f) entry_ir_fr_fm(eqi_f)
1605 entry_ir_fr_fr(ger_f) entry_ir_fr_fm(gei_f)
1606 entry_ir_fr_fr(gtr_f) entry_ir_fr_fm(gti_f)
1607 entry_ir_fr_fr(ner_f) entry_ir_fr_fm(nei_f)
1608 entry_ir_fr_fr(unltr_f) entry_ir_fr_fm(unlti_f)
1609 entry_ir_fr_fr(unler_f) entry_ir_fr_fm(unlei_f)
1610 entry_ir_fr_fr(uneqr_f) entry_ir_fr_fm(uneqi_f)
1611 entry_ir_fr_fr(unger_f) entry_ir_fr_fm(ungei_f)
1612 entry_ir_fr_fr(ungtr_f) entry_ir_fr_fm(ungti_f)
1613 entry_ir_fr_fr(ltgtr_f) entry_ir_fr_fm(ltgti_f)
1614 entry_ir_fr_fr(ordr_f) entry_ir_fr_fm(ordi_f)
1615 entry_ir_fr_fr(unordr_f) entry_ir_fr_fm(unordi_f)
1616 entry_ir_fr(truncr_f_i)
1617 #if __WORDSIZE == 64
1618 entry_ir_fr(truncr_f_l)
1620 entry_ir_fr(truncr_f)
1621 entry_fr_ir(extr_f) entry_fr_fr(extr_d_f)
1622 entry_fr_fr(movr_f) entry_fr_fm(movi_f)
1623 entry_fr_ir(ldr_f) entry_fr_pm(ldi_f)
1624 entry_fr_ir_ir(ldxr_f) entry_fr_ir_im(ldxi_f)
1625 entry_ir_fr(str_f) entry_pm_fr(sti_f)
1626 entry_ir_ir_fr(stxr_f) entry_im_ir_fr(stxi_f)
1627 entry_lb_fr_fr(bltr_f) entry_lb_fr_fm(blti_f)
1628 entry_lb_fr_fr(bler_f) entry_lb_fr_fm(blei_f)
1629 entry_lb_fr_fr(beqr_f) entry_lb_fr_fm(beqi_f)
1630 entry_lb_fr_fr(bger_f) entry_lb_fr_fm(bgei_f)
1631 entry_lb_fr_fr(bgtr_f) entry_lb_fr_fm(bgti_f)
1632 entry_lb_fr_fr(bner_f) entry_lb_fr_fm(bnei_f)
1633 entry_lb_fr_fr(bunltr_f) entry_lb_fr_fm(bunlti_f)
1634 entry_lb_fr_fr(bunler_f) entry_lb_fr_fm(bunlei_f)
1635 entry_lb_fr_fr(buneqr_f) entry_lb_fr_fm(buneqi_f)
1636 entry_lb_fr_fr(bunger_f) entry_lb_fr_fm(bungei_f)
1637 entry_lb_fr_fr(bungtr_f) entry_lb_fr_fm(bungti_f)
1638 entry_lb_fr_fr(bltgtr_f) entry_lb_fr_fm(bltgti_f)
1639 entry_lb_fr_fr(bordr_f) entry_lb_fr_fm(bordi_f)
1640 entry_lb_fr_fr(bunordr_f) entry_lb_fr_fm(bunordi_f)
1641 entry_fr(pushargr_f) entry_fm(pushargi_f)
1642 entry_fr(retr_f) entry_fm(reti_f)
1644 entry_ca(arg_d) entry_fa(getarg_d)
1645 entry_fa(putargr_d) entry_fma(putargi_d)
1646 entry_fr_fr_fr(addr_d) entry_fr_fr_dm(addi_d)
1647 entry_fr_fr_fr(subr_d) entry_fr_fr_dm(subi_d)
1648 entry_fr_fr_fr(rsbr_d) entry_fr_fr_dm(rsbi_d)
1649 entry_fr_fr_fr(mulr_d) entry_fr_fr_dm(muli_d)
1650 entry_fr_fr_fr(divr_d) entry_fr_fr_dm(divi_d)
1651 entry_fr_fr(negr_d) entry_fr_fr(absr_d)
1652 entry_fr_fr(sqrtr_d)
1653 entry_ir_fr_fr(ltr_d) entry_ir_fr_dm(lti_d)
1654 entry_ir_fr_fr(ler_d) entry_ir_fr_dm(lei_d)
1655 entry_ir_fr_fr(eqr_d) entry_ir_fr_dm(eqi_d)
1656 entry_ir_fr_fr(ger_d) entry_ir_fr_dm(gei_d)
1657 entry_ir_fr_fr(gtr_d) entry_ir_fr_dm(gti_d)
1658 entry_ir_fr_fr(ner_d) entry_ir_fr_dm(nei_d)
1659 entry_ir_fr_fr(unltr_d) entry_ir_fr_dm(unlti_d)
1660 entry_ir_fr_fr(unler_d) entry_ir_fr_dm(unlei_d)
1661 entry_ir_fr_fr(uneqr_d) entry_ir_fr_dm(uneqi_d)
1662 entry_ir_fr_fr(unger_d) entry_ir_fr_dm(ungei_d)
1663 entry_ir_fr_fr(ungtr_d) entry_ir_fr_dm(ungti_d)
1664 entry_ir_fr_fr(ltgtr_d) entry_ir_fr_dm(ltgti_d)
1665 entry_ir_fr_fr(ordr_d) entry_ir_fr_dm(ordi_d)
1666 entry_ir_fr_fr(unordr_d) entry_ir_fr_dm(unordi_d)
1667 entry_ir_fr(truncr_d_i)
1668 #if __WORDSIZE == 64
1669 entry_ir_fr(truncr_d_l)
1671 entry_ir_fr(truncr_d)
1672 entry_fr_ir(extr_d) entry_fr_fr(extr_f_d)
1673 entry_fr_fr(movr_d) entry_fr_dm(movi_d)
1674 entry_fr_ir(ldr_d) entry_fr_pm(ldi_d)
1675 entry_fr_ir_ir(ldxr_d) entry_fr_ir_im(ldxi_d)
1676 entry_ir_fr(str_d) entry_pm_fr(sti_d)
1677 entry_ir_ir_fr(stxr_d) entry_im_ir_fr(stxi_d)
1678 entry_lb_fr_fr(bltr_d) entry_lb_fr_dm(blti_d)
1679 entry_lb_fr_fr(bler_d) entry_lb_fr_dm(blei_d)
1680 entry_lb_fr_fr(beqr_d) entry_lb_fr_dm(beqi_d)
1681 entry_lb_fr_fr(bger_d) entry_lb_fr_dm(bgei_d)
1682 entry_lb_fr_fr(bgtr_d) entry_lb_fr_dm(bgti_d)
1683 entry_lb_fr_fr(bner_d) entry_lb_fr_dm(bnei_d)
1684 entry_lb_fr_fr(bunltr_d) entry_lb_fr_dm(bunlti_d)
1685 entry_lb_fr_fr(bunler_d) entry_lb_fr_dm(bunlei_d)
1686 entry_lb_fr_fr(buneqr_d) entry_lb_fr_dm(buneqi_d)
1687 entry_lb_fr_fr(bunger_d) entry_lb_fr_dm(bungei_d)
1688 entry_lb_fr_fr(bungtr_d) entry_lb_fr_dm(bungti_d)
1689 entry_lb_fr_fr(bltgtr_d) entry_lb_fr_dm(bltgti_d)
1690 entry_lb_fr_fr(bordr_d) entry_lb_fr_dm(bordi_d)
1691 entry_lb_fr_fr(bunordr_d) entry_lb_fr_dm(bunordi_d)
1692 entry_fr(pushargr_d) entry_dm(pushargi_d)
1693 entry_fr(retr_d) entry_dm(reti_d)
1698 jit_gpr_t r0 = get_ireg();
1704 jit_gpr_t r0 = get_ireg();
1710 jit_gpr_t r0 = get_ireg(), r1 = get_ireg();
1716 jit_fpr_t r0 = get_freg();
1717 jit_gpr_t r1 = get_ireg();
1718 jit_va_arg_d(r0, r1);
1723 jit_gpr_t r0 = get_ireg();
1729 #undef entry_lb_fr_fm
1730 #undef entry_lb_fr_dm
1731 #undef entry_lb_fr_fr
1732 #undef entry_im_ir_fr
1733 #undef entry_ir_ir_fr
1735 #undef entry_fr_ir_ir
1736 #undef entry_fr_ir_im
1742 #undef entry_ir_fr_fm
1743 #undef entry_ir_fr_dm
1744 #undef entry_ir_fr_fr
1746 #undef entry_fr_fr_fm
1747 #undef entry_fr_fr_dm
1748 #undef entry_fr_fr_fr
1753 #undef entry_lb_ir_im
1754 #undef entry_lb_ir_ir
1755 #undef entry_im_ir_ir
1760 #undef entry_ir_ir_im
1761 #undef entry_ir_ir_ir
1770 error(const char *format, ...)
1776 va_start(ap, format);
1777 message("error", format, ap);
1779 length = parser.data.length - parser.data.offset;
1780 string = (char *)(parser.data.buffer + parser.data.offset - 1);
1782 strcpy(string + 74, "...");
1784 parser.data.buffer[parser.data.length - 1] = '\0';
1785 fprintf(stderr, "(%s)\n", string);
1790 warn(const char *format, ...)
1793 va_start(ap, format);
1794 message("warning", format, ap);
1799 message(const char *kind, const char *format, va_list ap)
1801 fprintf(stderr, "%s:%d: %s: ", parser.name,
1802 parser.line - parser.newline, kind);
1803 vfprintf(stderr, format, ap);
1804 fputc('\n', stderr);
1812 if (parser.data.offset < parser.data.length)
1813 ch = parser.data.buffer[parser.data.offset++];
1815 /* keep first offset for ungetch */
1816 if ((parser.data.length = fread(parser.data.buffer + 1, 1,
1817 sizeof(parser.data.buffer) - 1,
1818 parser.fp) + 1) <= 1) {
1820 parser.data.offset = 1;
1823 ch = parser.data.buffer[1];
1824 parser.data.offset = 2;
1827 if ((parser.newline = ch == '\n'))
1839 error("unexpected end of file");
1847 if ((parser.newline = ch == '\n'))
1850 if (parser.data.offset)
1851 parser.data.buffer[--parser.data.offset] = ch;
1854 parser.data.buffer[0] = ch;
1864 for (ch = getch();; ch = getch()) {
1874 case ' ': case '\f': case '\r': case '\t':
1887 for (ch = getch();; ch = getch()) {
1897 case ' ': case '\f': case '\n': case '\r': case '\t':
1899 /* handle as newline */
1916 for (ch = getch(); ch != '\n' && ch != EOF; ch = getch())
1920 for (; ch != '/';) {
1921 while (getch_noeof() != '*')
1923 while ((ch = getch_noeof()) == '*')
1938 for (ch = getch(); ch != '\n' && ch != EOF; ch = getch()) {
1941 if ((number(ch)) == tok_int)
1942 parser.line = parser.value.i - 1;
1946 if (parser.offset >= (int)sizeof(parser.name)) {
1947 strncpy(parser.name, parser.string, sizeof(parser.name));
1948 parser.name[sizeof(parser.name) - 1] = '\0';
1951 strcpy(parser.name, parser.string);
1962 get_int(skip_t skip)
1964 switch (primary(skip)) {
1968 parser.type = type_l;
1969 parser.value.i = (jit_word_t)parser.value.p;
1972 error("expecting integer");
1975 return (parser.value.i);
1979 get_uint(skip_t skip)
1981 switch (primary(skip)) {
1982 case tok_char: case tok_int:
1985 parser.type = type_l;
1986 parser.value.ui = (jit_uword_t)parser.value.p;
1989 error("expecting integer");
1992 return (parser.value.ui);
1996 get_float(skip_t skip)
1998 switch (primary(skip)) {
2001 parser.type = type_d;
2002 parser.value.d = parser.value.i;
2007 error("expecting float");
2010 return (parser.value.d);
2013 /* Workaround gcc not converting unordered values from double to
2014 * float (as done in other architectures) on s390 */
2016 make_float(double d)
2018 /* This is an workaround to a bug in Hercules s390 emulator,
2019 * and at least HP-UX ia64 not have these */
2020 #if defined(HAVE_ISNAN) && defined(HAVE_ISINF)
2021 if (isnan(d)) return ( 0.0f/0.0f);
2023 if (d > 0.0) return ( 1.0f/0.0f);
2024 else return (-1.0f/0.0f);
2031 get_pointer(skip_t skip)
2034 token_t token = primary(skip);
2038 label = get_label_by_name(parser.string);
2040 error("bad identifier %s", parser.string);
2041 switch (label->kind) {
2042 case label_kind_data:
2043 case label_kind_code:
2045 case label_kind_code_forward:
2046 /* as expression arguments */
2047 error("forward references not implemented");
2049 case label_kind_dynamic:
2052 parser.type = type_p;
2053 return (parser.value.p = label->value);
2055 parser.type = type_p;
2056 return (parser.value.p = (void *)parser.value.ui);
2058 return (parser.value.p);
2059 default: error("bad pointer");
2064 get_label(skip_t skip)
2073 case 'a' ... 'z': case 'A' ... 'Z': case '_':
2074 (void)identifier(ch);
2077 error("expecting label/immediate");
2079 if ((label = get_label_by_name(parser.string)) == NULL)
2080 label = new_label(label_kind_code_forward,
2081 parser.string, jit_forward());
2090 int check = 1, ch = getch();
2094 parser.regtype = type_l;
2095 switch (ch = getch()) {
2096 case '0': parser.regval = JIT_R0; break;
2097 case '1': parser.regval = JIT_R1; break;
2098 case '2': parser.regval = JIT_R2; break;
2100 num = get_int(skip_none);
2101 if (num < 0 || num >= JIT_R_NUM) goto fail;
2102 parser.regval = JIT_R(num);
2103 if (getch() != ')') goto fail;
2110 parser.regtype = type_l;
2111 switch (ch = getch()) {
2112 case '0': parser.regval = JIT_V0; break;
2113 case '1': parser.regval = JIT_V1; break;
2114 case '2': parser.regval = JIT_V2; break;
2117 num = get_int(skip_none);
2118 if (num < 0 || num >= JIT_V_NUM) goto fail;
2119 parser.regval = JIT_V(num);
2120 if (getch() != ')') goto fail;
2126 parser.regtype = type_d;
2127 switch (ch = getch()) {
2128 case '0': parser.regval = JIT_F0; break;
2129 case '1': parser.regval = JIT_F1; break;
2130 case '2': parser.regval = JIT_F2; break;
2131 case '3': parser.regval = JIT_F3; break;
2132 case '4': parser.regval = JIT_F4; break;
2133 case '5': parser.regval = JIT_F5; break;
2135 parser.regtype = type_l; /* oops */
2136 parser.regval = JIT_FP; break;
2138 num = get_int(skip_none);
2139 if (num < 0 || num >= JIT_F_NUM) goto fail;
2140 parser.regval = JIT_F(num);
2141 if (getch() != ')') goto fail;
2149 error("bad register");
2153 if ((ch >= 'a' && ch <= 'z') ||
2154 (ch >= 'A' && ch <= 'Z') ||
2155 (ch >= '0' && ch <= '9') ||
2161 return (tok_register);
2167 parser.string[0] = ch;
2168 for (parser.offset = 1;;) {
2169 switch ((ch = getch())) {
2170 case 'a' ... 'z': case 'A' ... 'Z': case '0' ... '9' : case '_':
2171 if (parser.offset + 1 >= MAX_IDENTIFIER) {
2172 parser.string[parser.offset] = '\0';
2173 error("bad identifier %s", parser.string);
2175 parser.string[parser.offset++] = ch;
2178 parser.string[parser.offset] = '\0';
2180 return (tok_symbol);
2186 get_data(type_t type)
2195 switch (token = primary(skip_ws)) {
2196 case tok_char: case tok_int:
2197 check_data(sizeof(signed char));
2198 *(signed char *)(data + data_offset) = parser.value.i;
2199 data_offset += sizeof(char);
2202 check_data(parser.offset);
2203 memcpy(data + data_offset, parser.string,
2205 data_offset += parser.offset;
2208 case tok_semicollon:
2209 if (test == data) error("syntax error");
2211 default: error("bad initializer");
2215 check_data(sizeof(signed short));
2216 *(signed short *)(data + data_offset) = get_int(skip_ws);
2217 data_offset += sizeof(short);
2220 check_data(sizeof(signed int));
2221 *(signed int *)(data + data_offset) = get_int(skip_ws);
2222 data_offset += sizeof(int);
2225 check_data(sizeof(jit_word_t));
2226 *(jit_word_t *)(data + data_offset) = get_int(skip_ws);
2227 data_offset += sizeof(jit_word_t);
2230 check_data(sizeof(float));
2231 *(float *)(data + data_offset) = get_float(skip_ws);
2232 data_offset += sizeof(float);
2235 check_data(sizeof(double));
2236 *(double *)(data + data_offset) = get_float(skip_ws);
2237 data_offset += sizeof(double);
2240 /* FIXME **patch if realloc** */
2241 check_data(sizeof(void*));
2242 *(void **)(data + data_offset) = get_pointer(skip_ws);
2243 data_offset += sizeof(void*);
2249 if (ch == '\n' || ch == ';' || ch == EOF)
2259 size_t offset, length;
2261 switch (ch = getch_noeof()) {
2263 /* use .$(expression) for non side effects expression */
2266 case 'a' ... 'z': case 'A' ... 'Z': case '_':
2267 (void)identifier(ch);
2271 if (skipws() != '$')
2272 error("expecting symbol");
2273 /* allow spaces before an expression */
2277 if (parser.string[1] == '\0') {
2278 switch (parser.string[0]) {
2279 case 'c': get_data(type_c); break;
2280 case 's': get_data(type_s); break;
2281 case 'i': get_data(type_i); break;
2282 case 'l': get_data(type_l); break;
2283 case 'f': get_data(type_f); break;
2284 case 'd': get_data(type_d); break;
2285 case 'p': get_data(type_p); break;
2286 default: error("bad type .%c", parser.string[0]);
2289 else if (strcmp(parser.string, "data") == 0) {
2290 if (parser.parsing != PARSING_NONE)
2291 error(".data must be specified once and be the first section");
2292 parser.parsing = PARSING_DATA;
2293 data_length = get_int(skip_ws);
2294 data = (char *)xcalloc(1, data_length);
2296 else if (strcmp(parser.string, "code") == 0) {
2297 if (parser.parsing != PARSING_NONE &&
2298 parser.parsing != PARSING_DATA)
2299 error(".code must be specified once only");
2300 parser.parsing = PARSING_CODE;
2302 else if (strcmp(parser.string, "align") == 0) {
2303 length = get_int(skip_ws);
2304 if (parser.parsing != PARSING_DATA)
2305 error(".align must be in .data");
2306 if (length > 1 && length <= 4096 && !(length & (length - 1))) {
2307 offset = data_offset;
2308 offset += length - ((offset + length) % length);
2309 check_data(offset - data_offset);
2310 data_offset = offset;
2313 error("bad .align %ld (must be a power of 2, >= 2 && <= 4096)",
2314 (jit_word_t)length);
2316 else if (strcmp(parser.string, "size") == 0) {
2317 length = get_int(skip_ws);
2318 if (parser.parsing != PARSING_DATA)
2319 error(".size must be in .data");
2321 data_offset += length;
2323 else if (strcmp(parser.string, "disasm") == 0)
2326 error("unknown command .%s", parser.string);
2332 char buffer[1024], *endptr;
2333 int integer = 1, offset = 0, neg = 0, e = 0, d = 0, base = 10;
2335 for (;; ch = getch()) {
2342 if (offset && buffer[offset - 1] != 'e') {
2350 if (offset && buffer[offset - 1] != 'e') {
2363 if (offset == 0 && base == 10) {
2369 if (offset == 0 && base == 8) {
2387 if (offset == 0 && base == 8) {
2392 case 'a': case 'c': case 'd': case 'f':
2405 case '_': case 'g' ... 'w': case 'y': case 'z': case 'A' ... 'Z':
2407 buffer[offset++] = '\0';
2408 error("bad constant %s", buffer);
2413 if (offset + 1 >= (int)sizeof(buffer))
2415 buffer[offset++] = ch;
2418 /* check for literal 0 */
2419 if (offset == 0 && base == 8) buffer[offset++] = '0';
2420 buffer[offset] = '\0';
2423 # define STRTOUL strtoull
2425 # define STRTOUL strtoul
2427 parser.value.ui = STRTOUL(buffer, &endptr, base);
2428 parser.type = type_l;
2430 parser.value.i = -parser.value.i;
2433 parser.type = type_d;
2434 parser.value.d = strtod(buffer, &endptr);
2436 parser.value.d = -parser.value.d;
2441 return (integer ? tok_int : tok_float);
2448 case 'a': ch = '\a'; break;
2449 case 'b': ch = '\b'; break;
2450 case 'f': ch = '\f'; break;
2451 case 'n': ch = '\n'; break;
2452 case 'r': ch = '\r'; break;
2453 case 't': ch = '\t'; break;
2454 case 'v': ch = '\v'; break;
2466 for (parser.offset = 0;;) {
2467 switch (ch = getch_noeof()) {
2469 if (esc) goto append;
2474 parser.string[parser.offset++] = '\0';
2475 parser.value.p = parser.string;
2476 parser.type = type_p;
2477 return (tok_string);
2486 if (parser.offset + 1 >= parser.length) {
2487 parser.length += 4096;
2488 parser.string = (char *)xrealloc(parser.string,
2491 parser.string[parser.offset++] = ch;
2502 if ((ch = getch_noeof()) == '\\') {
2506 if (getch_noeof() != '\'')
2507 error("bad single byte char");
2510 parser.type = type_l;
2511 parser.value.i = ch & 0xff;
2522 (void)identifier('@');
2523 if ((label = get_label_by_name(parser.string)) == NULL) {
2524 #if __CYGWIN__ ||_WIN32
2525 /* FIXME kludge to pass varargs test case, otherwise,
2526 * will not print/scan float values */
2527 if (strcmp(parser.string + 1, "sprintf") == 0)
2529 else if (strcmp(parser.string + 1, "sscanf") == 0)
2534 value = dlsym(DL_HANDLE, parser.string + 1);
2535 if ((string = dlerror()))
2536 error("%s", string);
2538 label = new_label(label_kind_dynamic, parser.string, value);
2540 parser.type = type_p;
2541 parser.value.p = label->value;
2543 return (tok_pointer);
2547 expression_prim(void)
2554 if (parser.putback) {
2555 parser.expr = parser.putback;
2556 parser.putback = (expr_t)0;
2559 switch (ch = skipws()) {
2561 if ((ch = getch_noeof()) == '=') parser.expr = expr_ne;
2563 ungetch(ch); parser.expr = expr_not;
2566 case '~': parser.expr = expr_com;
2569 if ((ch = getch_noeof()) == '=') parser.expr = expr_mulset;
2571 ungetch(ch); parser.expr = expr_mul;
2575 if ((ch = getch_noeof()) == '=') parser.expr = expr_divset;
2577 ungetch(ch); parser.expr = expr_div;
2581 if ((ch = getch_noeof()) == '=') parser.expr = expr_remset;
2583 ungetch(ch); parser.expr = expr_rem;
2587 switch (ch = getch_noeof()) {
2588 case '+': parser.expr = expr_inc;
2590 case '=': parser.expr = expr_addset;
2592 default: ungetch(ch); parser.expr = expr_add;
2597 switch (ch = getch_noeof()) {
2598 case '-': parser.expr = expr_dec;
2600 case '=': parser.expr = expr_subset;
2602 default: ungetch(ch); parser.expr = expr_sub;
2607 switch (ch = getch_noeof()) {
2608 case '=': parser.expr = expr_le;
2610 case '<': ch = getch_noeof();
2611 if (ch == '=') parser.expr = expr_lshset;
2613 ungetch(ch); parser.expr = expr_lsh;
2616 default: ungetch(ch); parser.expr = expr_lt;
2621 switch (ch = getch_noeof()) {
2622 case '=': parser.expr = expr_ge;
2624 case '>': ch = getch_noeof();
2625 if (ch == '=') parser.expr = expr_rshset;
2627 ungetch(ch); parser.expr = expr_rsh;
2630 default: ungetch(ch); parser.expr = expr_gt;
2635 switch (ch = getch_noeof()) {
2636 case '=': parser.expr = expr_andset;
2638 case '&': parser.expr = expr_andand;
2640 default: ungetch(ch); parser.expr = expr_and;
2645 switch (ch = getch_noeof()) {
2646 case '=': parser.expr = expr_orset;
2648 case '|': parser.expr = expr_oror;
2650 default: ungetch(ch); parser.expr = expr_or;
2655 if ((ch = getch_noeof()) == '=') parser.expr = expr_xorset;
2657 ungetch(ch); parser.expr = expr_xor;
2661 if ((ch = getch_noeof()) == '=') parser.expr = expr_eq;
2663 ungetch(ch); parser.expr = expr_set;
2666 case '(': parser.expr = expr_lparen;
2668 case ')': parser.expr = expr_rparen;
2672 parser.expr = token == tok_int ? expr_int : expr_float;
2676 parser.expr = expr_pointer;
2680 /* no support for nested expressions */
2681 if (parser.string[0] == '\0')
2682 error("syntax error");
2683 parser.expr = expr_symbol;
2684 if ((symbol = get_symbol_by_name(parser.string)) != NULL) {
2685 parser.type = symbol->type;
2686 parser.value = symbol->value;
2689 /* only create symbol on assignment */
2690 parser.type = type_none;
2692 case 'a' ... 'z': case 'A' ... 'Z': case '_':
2694 if ((label = get_label_by_name(parser.string))) {
2695 if (label->kind == label_kind_code_forward)
2696 error("forward value for %s not supported",
2698 parser.expr = expr_pointer;
2699 parser.type = type_p;
2700 parser.value.p = label->value;
2703 error("invalid identifier %s", parser.string);
2707 parser.expr = expr_int;
2710 /* not smart enough to put it in data and/or relocate it, etc */
2711 error("must declare strings as data");
2713 error("syntax error");
2718 expression_inc(int pre)
2724 if (parser.expr != expr_symbol)
2725 error("syntax error");
2727 if ((symbol = get_symbol_by_name(parser.string)) == NULL) {
2728 if (!parser.short_circuit)
2729 error("undefined symbol %s", symbol->name);
2731 if (!parser.short_circuit) {
2732 parser.type = symbol->type;
2734 parser.value = symbol->value;
2735 switch (symbol->type) {
2740 /* should really be an error */
2741 symbol->value.d += 1.0;
2748 parser.value = symbol->value;
2754 expression_dec(int pre)
2760 if (parser.expr != expr_symbol)
2761 error("syntax error");
2763 if ((symbol = get_symbol_by_name(parser.string)) == NULL) {
2764 if (!parser.short_circuit)
2765 error("undefined symbol %s", symbol->name);
2767 if (!parser.short_circuit) {
2768 parser.type = symbol->type;
2770 parser.value = symbol->value;
2771 switch (symbol->type) {
2776 /* should really be an error */
2777 symbol->value.d -= 1.0;
2784 parser.value = symbol->value;
2790 expression_unary(void)
2796 switch (parser.expr) {
2799 switch (parser.type) {
2804 error("syntax error");
2809 switch (parser.type) {
2811 parser.value.i = -parser.value.i;
2814 parser.value.d = -parser.value.d;
2817 error("syntax error");
2828 switch (parser.type) {
2830 parser.value.i = !parser.value.i;
2833 parser.value.i = parser.value.d != 0;
2836 parser.value.i = parser.value.p != NULL;
2839 error("syntax error");
2841 parser.type = type_l;
2845 if (parser.type != type_l)
2846 error("syntax error");
2847 parser.value.i = ~parser.value.i;
2851 if (parser.expr != expr_rparen)
2852 error("syntax error");
2856 strcpy(buffer, parser.string);
2858 switch (parser.expr) {
2860 if ((symbol = get_symbol_by_name(buffer)) == NULL) {
2861 if (!parser.short_circuit)
2862 symbol = new_symbol(buffer);
2866 if (!parser.short_circuit) {
2868 error("syntax error");
2869 symbol->type = parser.type;
2870 symbol->value = parser.value;
2873 case expr_mulset: parser.putback = expr_mul;
2875 case expr_divset: parser.putback = expr_div;
2877 case expr_remset: parser.putback = expr_rem;
2879 case expr_addset: parser.putback = expr_add;
2881 case expr_subset: parser.putback = expr_sub;
2883 case expr_lshset: parser.putback = expr_lsh;
2885 case expr_rshset: parser.putback = expr_rsh;
2887 case expr_andset: parser.putback = expr_and;
2889 case expr_orset: parser.putback = expr_or;
2891 case expr_xorset: parser.putback = expr_xor;
2893 if ((symbol = get_symbol_by_name(buffer)) == NULL) {
2894 if (!parser.short_circuit)
2895 error("undefined symbol %s", buffer);
2896 parser.type = type_l;
2899 switch (parser.putback) {
2900 case expr_mul: case expr_div: case expr_rem:
2903 case expr_add: case expr_sub:
2906 case expr_lsh: case expr_rsh:
2909 case expr_and: case expr_or: case expr_xor:
2929 /* make next token available */
2937 expression_mul(void)
2943 switch (parser.type) {
2944 case type_l: case type_d: case type_p: break;
2948 switch (parser.expr) {
2950 type = parser.type, value = parser.value;
2952 switch (parser.type) {
2955 value.i *= parser.value.i;
2957 value.d *= parser.value.i;
2960 if (type == type_l) {
2964 value.d *= parser.value.d;
2967 error("invalid operand");
2969 parser.type = type, parser.value = value;
2972 type = parser.type, value = parser.value;
2974 switch (parser.type) {
2976 if (type == type_l) {
2977 if (parser.value.i == 0)
2978 error("divide by zero");
2979 value.i /= parser.value.i;
2982 value.d /= parser.value.i;
2985 if (type == type_l) {
2989 value.d /= parser.value.d;
2992 error("invalid operand");
2994 parser.type = type, parser.value = value;
2997 type = parser.type, value = parser.value;
2999 switch (parser.type) {
3001 if (type == type_l) {
3002 if (parser.value.i == 0)
3003 error("divide by zero");
3004 value.i %= parser.value.i;
3007 error("invalid operand");
3010 error("invalid operand");
3012 parser.type = type, parser.value = value;
3021 expression_add(void)
3027 switch (parser.type) {
3028 case type_l: case type_d: case type_p: break;
3032 switch (parser.expr) {
3034 type = parser.type, value = parser.value;
3036 switch (parser.type) {
3040 value.i += parser.value.i;
3043 value.d += parser.value.i;
3046 value.cp += parser.value.i;
3059 error("invalid operand");
3061 value.d += parser.value.d;
3067 value.cp = value.i + parser.value.cp;
3070 error("invalid operand");
3074 error("invalid operand");
3076 parser.type = type, parser.value = value;
3079 type = parser.type, value = parser.value;
3081 switch (parser.type) {
3085 value.i -= parser.value.i;
3088 value.d -= parser.value.i;
3091 value.cp -= parser.value.i;
3104 error("invalid operand");
3106 value.d -= parser.value.d;
3112 value.i = value.cp - parser.value.cp;
3115 error("invalid operand");
3119 error("invalid operand");
3121 parser.type = type, parser.value = value;
3130 expression_shift(void)
3135 switch (parser.type) {
3136 case type_l: case type_d: case type_p: break;
3140 switch (parser.expr) {
3142 value = parser.value.i;
3143 if (parser.type != type_l)
3144 error("invalid operand");
3146 if (parser.type != type_l)
3147 error("invalid operand");
3148 value <<= parser.value.i;
3149 parser.value.i = value;
3152 value = parser.value.i;
3153 if (parser.type != type_l)
3154 error("invalid operand");
3156 if (parser.type != type_l)
3157 error("invalid operand");
3158 value >>= parser.value.i;
3159 parser.value.i = value;
3168 expression_bit(void)
3173 switch (parser.type) {
3174 case type_l: case type_d: case type_p: break;
3178 switch (parser.expr) {
3180 if (parser.type != type_l)
3181 error("invalid operand");
3184 if (parser.type != type_l)
3185 error("invalid operand");
3186 i &= parser.value.i;
3190 if (parser.type != type_l)
3191 error("invalid operand");
3194 if (parser.type != type_l)
3195 error("invalid operand");
3196 i |= parser.value.i;
3200 if (parser.type != type_l)
3201 error("invalid operand");
3204 if (parser.type != type_l)
3205 error("invalid operand");
3206 i ^= parser.value.i;
3216 expression_rel(void)
3222 switch (parser.type) {
3223 case type_l: case type_d: case type_p: break;
3227 switch (parser.expr) {
3229 type = parser.type, value = parser.value;
3231 switch (parser.type) {
3235 value.i = value.i < parser.value.i;
3238 value.i = value.d < parser.value.i;
3241 value.i = (jit_word_t)value.p < parser.value.i;
3248 value.i = value.i < parser.value.d;
3251 value.i = value.d < parser.value.d;
3254 error("invalid operand");
3260 value.i = value.i < (jit_word_t)parser.value.p;
3263 error("invalid operand");
3265 value.i = (jit_word_t)value.p < (jit_word_t)parser.value.p;
3270 error("invalid operand");
3272 parser.type = type_l, parser.value = value;
3275 type = parser.type, value = parser.value;
3277 switch (parser.type) {
3281 value.i = value.i <= parser.value.i;
3284 value.i = value.d <= parser.value.i;
3287 value.i = (jit_word_t)value.p <= parser.value.i;
3294 value.i = value.i <= parser.value.d;
3297 value.i = value.d <= parser.value.d;
3300 value.i = (jit_word_t)value.p <= parser.value.d;
3307 value.i = value.i <= (jit_word_t)parser.value.p;
3310 error("invalid operand");
3312 value.i = (jit_word_t)value.p <= (jit_word_t)parser.value.p;
3317 error("invalid operand");
3319 parser.type = type_l, parser.value = value;
3322 type = parser.type, value = parser.value;
3324 switch (parser.type) {
3328 value.i = value.i == parser.value.i;
3331 value.i = value.d == parser.value.i;
3334 value.i = (jit_word_t)value.p == parser.value.i;
3341 value.i = value.i == parser.value.d;
3344 value.i = value.d == parser.value.d;
3347 error("invalid operand");
3353 value.i = value.i == (jit_word_t)parser.value.p;
3356 error("invalid operand");
3358 value.i = value.p == parser.value.p;
3363 error("invalid operand");
3365 parser.type = type_l, parser.value = value;
3368 type = parser.type, value = parser.value;
3370 switch (parser.type) {
3374 value.i = value.i >= parser.value.i;
3377 value.i = value.d >= parser.value.i;
3380 value.i = (jit_word_t)value.p >= parser.value.i;
3387 value.i = value.i >= parser.value.d;
3390 value.i = value.d >= parser.value.d;
3393 error("invalid operand");
3399 value.i = value.i >= (jit_word_t)parser.value.p;
3402 error("invalid operand");
3404 value.i = (jit_word_t)value.p >= (jit_word_t)parser.value.p;
3409 error("invalid operand");
3411 parser.type = type_l, parser.value = value;
3414 type = parser.type, value = parser.value;
3416 switch (parser.type) {
3420 value.i = value.i > parser.value.i;
3423 value.i = value.d > parser.value.i;
3426 value.i = (jit_word_t)value.p > parser.value.i;
3433 value.i = value.i > parser.value.d;
3436 value.i = value.d > parser.value.d;
3439 error("invalid operand");
3445 value.i = value.i > (jit_word_t)parser.value.p;
3448 error("invalid operand");
3450 value.i = (jit_word_t)value.p > (jit_word_t)parser.value.p;
3455 error("invalid operand");
3457 parser.type = type_l, parser.value = value;
3460 type = parser.type, value = parser.value;
3462 switch (parser.type) {
3466 value.i = value.i != parser.value.i;
3469 value.i = value.d != parser.value.i;
3472 value.i = (jit_word_t)value.p != parser.value.i;
3479 value.i = value.i != parser.value.d;
3482 value.i = value.d != parser.value.d;
3485 error("invalid operand");
3491 value.i = value.i != (jit_word_t)parser.value.p;
3494 error("invalid operand");
3496 value.i = value.p != parser.value.p;
3501 error("invalid operand");
3503 parser.type = type_l, parser.value = value;
3512 expression_cond(void)
3519 switch (parser.type) {
3520 case type_l: case type_d: case type_p: break;
3524 switch (parser.expr) {
3526 type = parser.type, value = parser.value;
3529 short_circuit = value.i == 0;
3532 short_circuit = value.d == 0.0;
3535 short_circuit = value.p == NULL;
3538 parser.short_circuit += short_circuit;
3540 parser.short_circuit -= short_circuit;
3541 switch (parser.type) {
3545 value.i = value.i && parser.value.i;
3548 value.i = value.d && parser.value.i;
3551 value.i = value.p && parser.value.i;
3558 value.i = value.i && parser.value.d;
3561 value.i = value.d && parser.value.d;
3564 value.i = value.p && parser.value.d;
3571 value.i = value.i && parser.value.p;
3574 value.i = value.d && parser.value.p;
3577 value.i = value.p && parser.value.p;
3582 error("invalid operand");
3584 parser.type = type_l, parser.value.i = value.i;
3587 type = parser.type, value = parser.value;
3590 short_circuit = value.i != 0;
3593 short_circuit = value.d != 0.0;
3596 short_circuit = value.p != NULL;
3599 parser.short_circuit += short_circuit;
3601 parser.short_circuit -= short_circuit;
3602 switch (parser.type) {
3606 value.i = value.i || parser.value.i;
3609 value.i = value.d || parser.value.i;
3612 value.i = value.p || parser.value.i;
3619 value.i = value.i || parser.value.d;
3622 value.i = value.d || parser.value.d;
3625 value.i = value.p || parser.value.d;
3632 value.i = value.i || parser.value.p;
3635 value.i = value.d || parser.value.p;
3638 value.i = value.p || parser.value.p;
3643 error("invalid operand");
3645 parser.type = type_l, parser.value.i = value.i;
3658 (void)identifier('$');
3659 if (parser.string[1] == '\0') {
3660 if (getch_noeof() != '(')
3661 error("bad symbol or expression");
3662 parser.type = type_none;
3664 if (parser.expr != expr_rparen)
3665 error("bad expression");
3666 switch (parser.type) {
3672 return (tok_pointer);
3674 error("bad expression");
3677 else if ((symbol = get_symbol_by_name(parser.string))) {
3678 switch (parser.type = symbol->type) {
3680 parser.value.i = symbol->value.i;
3683 parser.value.d = symbol->value.d;
3686 parser.value.p = symbol->value.p;
3687 return (tok_pointer);
3691 error("undefined symbol %s", parser.string);
3695 primary(skip_t skip)
3700 case skip_none: ch = getch(); break;
3701 case skip_ws: ch = skipws(); break;
3702 case skip_nl: ch = skipnl(); break;
3708 case 'a' ... 'z': case 'A' ... 'Z': case '_':
3709 return (identifier(ch));
3710 case '0' ... '9': case '+': case '-':
3711 return (number(ch));
3717 return (character());
3721 return (expression());
3725 return (tok_newline);
3727 return (tok_semicollon);
3729 error("syntax error");
3743 switch (token = primary(skip_nl)) {
3747 if ((label = get_label_by_name(parser.string))) {
3748 if (label->kind == label_kind_code_forward) {
3749 label->kind = label_kind_code;
3750 jit_link(label->value);
3751 jit_note(parser.name, parser.line);
3754 error("label %s: redefined", parser.string);
3757 if (parser.parsing == PARSING_DATA) {
3758 value = data + data_offset;
3759 label = new_label(label_kind_data,
3760 parser.string, value);
3762 else if (parser.parsing == PARSING_CODE) {
3763 value = jit_label();
3764 jit_note(parser.name, parser.line);
3765 label = new_label(label_kind_code,
3766 parser.string, value);
3769 error("label not in .code or .data");
3775 (instr_t *)get_hash(instrs, parser.string)) == NULL)
3776 error("unhandled symbol %s", parser.string);
3777 if (parser.parsing != PARSING_CODE)
3778 error(".code must be specified before instructions");
3779 (*instr->function)();
3787 error("syntax error");
3793 execute(int argc, char *argv[])
3797 function_t function;
3798 patch_t *patch, *next;
3800 for (patch = patches; patch; patch = next) {
3802 label = patch->label;
3803 if (label->kind == label_kind_code_forward)
3804 error("undefined label %s", label->name);
3805 switch (patch->kind) {
3806 case patch_kind_jmp:
3807 case patch_kind_mov:
3808 case patch_kind_call:
3809 jit_patch_at(patch->value, label->value);
3818 if (flag_data == 0) {
3820 jit_set_data(NULL, 0, JIT_DISABLE_DATA | JIT_DISABLE_NOTE);
3823 function = jit_emit();
3824 if (flag_verbose > 1 || flag_disasm) {
3826 fprintf(stderr, " - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n");
3828 if (flag_verbose > 0 || flag_disasm) {
3830 fprintf(stderr, " - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n");
3837 result = (*function)(argc, argv);
3838 jit_destroy_state();
3844 xmalloc(size_t size)
3846 void *pointer = malloc(size);
3848 if (pointer == NULL)
3849 error("out of memory");
3855 xrealloc(void *pointer, size_t size)
3857 pointer = realloc(pointer, size);
3859 if (pointer == NULL)
3860 error("out of memory");
3866 xcalloc(size_t nmemb, size_t size)
3868 void *pointer = calloc(nmemb, size);
3870 if (pointer == NULL)
3871 error("out of memory");
3877 new_label(label_kind_t kind, char *name, void *value)
3881 label = (label_t *)xmalloc(sizeof(label_t));
3883 label->name = strdup(name);
3884 label->value = value;
3885 put_hash(labels, (entry_t *)label);
3891 new_patch(patch_kind_t kind, label_t *label, void *value)
3893 patch_t *patch = (patch_t *)xmalloc(sizeof(patch_t));
3895 patch->label = label;
3896 patch->value = value;
3897 patch->next = patches;
3904 bcmp_symbols(const void *left, const void *right)
3906 return (strcmp((char *)left, (*(symbol_t **)right)->name));
3910 qcmp_symbols(const void *left, const void *right)
3912 return (strcmp((*(symbol_t **)left)->name, (*(symbol_t **)right)->name));
3916 new_symbol(char *name)
3920 if ((symbol_offset & 15) == 0) {
3921 if ((symbol_length += 16) == 16)
3922 symbols = (symbol_t **)xmalloc(sizeof(symbol_t *) *
3925 symbols = (symbol_t **)xrealloc(symbols, sizeof(symbol_t *) *
3928 symbol = (symbol_t *)xmalloc(sizeof(symbol_t));
3929 symbol->name = strdup(name);
3930 symbols[symbol_offset++] = symbol;
3931 qsort(symbols, symbol_offset, sizeof(symbol_t *), qcmp_symbols);
3937 get_symbol_by_name(char *name)
3939 symbol_t **symbol_pointer;
3941 if (symbols == NULL)
3943 symbol_pointer = (symbol_t **)bsearch(name, symbols, symbol_offset,
3944 sizeof(symbol_t *), bcmp_symbols);
3946 return (symbol_pointer ? *symbol_pointer : NULL);
3954 hash = (hash_t *)xmalloc(sizeof(hash_t));
3956 hash->entries = (entry_t **)xcalloc(hash->size = 32, sizeof(void *));
3962 hash_string(char *name)
3967 for (key = 0, ptr = name; *ptr; ptr++)
3968 key = (key << (key & 1)) ^ *ptr;
3974 put_hash(hash_t *hash, entry_t *entry)
3976 entry_t *prev, *ptr;
3977 int key = hash_string(entry->name) & (hash->size - 1);
3979 for (prev = ptr = hash->entries[key]; ptr; prev = ptr, ptr = ptr->next) {
3980 if (strcmp(entry->name, ptr->name) == 0)
3981 error("duplicated entry %s", entry->name);
3984 hash->entries[key] = entry;
3989 if (hash->count > hash->size * 0.75)
3994 get_hash(hash_t *hash, char *name)
3997 int key = hash_string(name) & (hash->size - 1);
3999 for (entry = hash->entries[key]; entry; entry = entry->next) {
4000 if (strcmp(entry->name, name) == 0)
4007 rehash(hash_t *hash)
4010 entry_t *entry, *next, **entries;
4012 entries = (entry_t **)xcalloc(size = hash->size * 2, sizeof(void *));
4013 for (i = 0; i < hash->size; i++) {
4014 for (entry = hash->entries[i]; entry; entry = next) {
4016 key = hash_string(entry->name) & (size - 1);
4017 entry->next = entries[key];
4018 entries[key] = entry;
4021 free(hash->entries);
4022 hash->entries = entries;
4029 #if HAVE_GETOPT_LONG_ONLY
4031 Usage: %s [jit assembler options] file [jit program options]\n\
4032 Jit assembler options:\n\
4033 -help Display this information\n\
4034 -v[0-3] Verbose output level\n\
4035 -d Do not use a data buffer\n\
4036 -D<macro>[=<val>] Preprocessor options\n"
4037 # if defined(__i386__) && __WORDSIZE == 32
4038 " -mx87=1 Force using x87 when sse2 available\n"
4040 # if defined(__i386__) || defined(__x86_64__)
4041 " -msse4_1=0 Do not use sse4_1 instructions when available\n"
4043 # if defined(__arm__)
4044 " -mcpu=<val> Force cpu version (4, 5, 6 or 7)\n\
4045 -mthumb[=0|1] Enable or disable thumb\n\
4046 -mvfp=<val> Set vpf version (0 to disable)\n\
4047 -mneon[=0|1] Enable or disable neon\n"
4052 Usage: %s [jit assembler options] file [jit program options]\n\
4053 Jit assembler options:\n\
4054 -h Display this information\n\
4055 -v Verbose output level\n\
4056 -D<macro>[=<val>] Preprocessor options\n", progname);
4063 main(int argc, char *argv[])
4065 #if HAVE_GETOPT_LONG_ONLY
4066 static const char *short_options = "dv::";
4067 static struct option long_options[] = {
4068 { "help", 0, 0, 'h' },
4069 { "data", 2, 0, 'd' },
4070 # if defined(__i386__) && __WORDSIZE == 32
4071 { "mx87", 2, 0, '7' },
4073 # if defined(__i386__) || defined(__x86_64__)
4074 { "msse4_1", 2, 0, '4' },
4076 # if defined(__arm__)
4077 { "mcpu", 2, 0, 'c' },
4078 { "mthumb", 2, 0, 't' },
4079 { "mvfp", 2, 0, 'f' },
4080 { "mneon", 2, 0, 'n' },
4085 #endif /* HAVE_GETOPT_LONG_ONLY */
4092 #if defined(__CYGWIN__)
4093 /* Cause a compile warning about redefinition without dllimport
4094 * attribute, *but* cause correct linkage if liblightning.a is
4095 * linked to binutils (that happens to have an internal
4096 * getopt* implementation and an apparently conflicting
4097 * optind global variable) */
4107 DL_HANDLE = dlopen(NULL, RTLD_LAZY);
4111 #if HAVE_GETOPT_LONG_ONLY
4113 if ((opt_short = getopt_long_only(argc, argv, short_options,
4114 long_options, &opt_index)) < 0)
4116 switch (opt_short) {
4123 flag_verbose = strtol(optarg, &endptr, 10);
4124 if (*endptr || flag_verbose < 0)
4133 #if defined(__i386__) && __WORDSIZE == 32
4136 if (strcmp(optarg, "") == 0 || strcmp(optarg, "1") == 0)
4138 else if (strcmp(optarg, "0"))
4145 #if defined(__i386__) || defined(__x86_64__)
4148 if (strcmp(optarg, "0") == 0)
4150 else if (strcmp(optarg, "1"))
4155 #if defined(__arm__)
4158 offset = strtol(optarg, &endptr, 10);
4159 if (*endptr || offset < 0)
4161 if (offset < jit_cpu.version)
4162 jit_cpu.version = offset;
4167 if (strcmp(optarg, "0") == 0)
4169 else if (strcmp(optarg, "1") && strcmp(optarg, "2"))
4174 # if !defined(__ARM_PCS_VFP)
4175 /* Do not allow overrinding hard float abi */
4177 offset = strtol(optarg, &endptr, 10);
4178 if (*endptr || offset < 0)
4180 if (offset < jit_cpu.vfp)
4181 jit_cpu.vfp = offset;
4187 if (strcmp(optarg, "0") == 0)
4189 else if (strcmp(optarg, "1"))
4197 while ((opt_short = getopt(argc, argv, "hvd")) >= 0) {
4198 if (opt_short == 'v')
4200 else if (opt_short == 'd')
4210 if (opt_index < argc && argv[opt_index][0] == '-')
4213 if (opt_index < 0 || opt_index >= argc)
4215 if (strcmp(argv[opt_index], "-") == 0)
4216 strcpy(parser.name, "<stdin>");
4218 if ((endptr = strrchr(argv[opt_index], '/')) == NULL)
4219 endptr = argv[opt_index];
4222 strncpy(parser.name, endptr, sizeof(parser.name));
4223 parser.name[sizeof(parser.name) - 1] = '\0';
4230 opt_short = snprintf(cmdline, sizeof(cmdline), cc " -E -x c %s", argv[opt_index]);
4231 for (++opt_index; opt_index < argc; opt_index++) {
4232 if (argv[opt_index][0] == '-')
4233 opt_short += snprintf(cmdline + opt_short,
4234 sizeof(cmdline) - opt_short,
4235 " %s", argv[opt_index]);
4241 opt_short += snprintf(cmdline + opt_short,
4242 sizeof(cmdline) - opt_short,
4243 " -D__WORDSIZE=%d", __WORDSIZE);
4244 opt_short += snprintf(cmdline + opt_short,
4245 sizeof(cmdline) - opt_short,
4246 " -D__LITTLE_ENDIAN=%d", __LITTLE_ENDIAN);
4247 opt_short += snprintf(cmdline + opt_short,
4248 sizeof(cmdline) - opt_short,
4249 " -D__BIG_ENDIAN=%d", __BIG_ENDIAN);
4250 opt_short += snprintf(cmdline + opt_short,
4251 sizeof(cmdline) - opt_short,
4252 " -D__BYTE_ORDER=%d", __BYTE_ORDER);
4253 #if defined(__i386__)
4254 opt_short += snprintf(cmdline + opt_short,
4255 sizeof(cmdline) - opt_short,
4258 #if defined(__x86_64__)
4259 opt_short += snprintf(cmdline + opt_short,
4260 sizeof(cmdline) - opt_short,
4263 #if defined(__mips__)
4264 opt_short += snprintf(cmdline + opt_short,
4265 sizeof(cmdline) - opt_short,
4268 #if defined(__arm__)
4269 opt_short += snprintf(cmdline + opt_short,
4270 sizeof(cmdline) - opt_short,
4273 #if defined(__powerpc__)
4274 opt_short += snprintf(cmdline + opt_short,
4275 sizeof(cmdline) - opt_short,
4278 #if defined(__sparc__)
4279 opt_short += snprintf(cmdline + opt_short,
4280 sizeof(cmdline) - opt_short,
4283 #if defined(__ia64__)
4284 opt_short += snprintf(cmdline + opt_short,
4285 sizeof(cmdline) - opt_short,
4288 #if defined(__hppa__)
4289 opt_short += snprintf(cmdline + opt_short,
4290 sizeof(cmdline) - opt_short,
4294 opt_short += snprintf(cmdline + opt_short,
4295 sizeof(cmdline) - opt_short,
4298 #if defined(__sgi__)
4299 opt_short += snprintf(cmdline + opt_short,
4300 sizeof(cmdline) - opt_short,
4303 #if defined(__aarch64__)
4304 opt_short += snprintf(cmdline + opt_short,
4305 sizeof(cmdline) - opt_short,
4306 " -D__aarch64__=1");
4308 #if defined(__s390__) || defined(__s390x__)
4309 opt_short += snprintf(cmdline + opt_short,
4310 sizeof(cmdline) - opt_short,
4313 #if defined(__alpha__)
4314 opt_short += snprintf(cmdline + opt_short,
4315 sizeof(cmdline) - opt_short,
4318 if ((parser.fp = popen(cmdline, "r")) == NULL)
4319 error("cannot execute %s", cmdline);
4322 parser.string = (char *)xmalloc(parser.length = 4096);
4324 #if defined(__linux__) && (defined(__i386__) || defined(__x86_64__))
4325 /* double precision 0x200
4326 * round nearest 0x000
4327 * invalid operation mask 0x001
4328 * denormalized operand mask 0x002
4329 * zero divide mask 0x004
4330 * precision (inexact) mask 0x020
4333 fpu_control_t fpu_control = 0x027f;
4334 _FPU_SETCW(fpu_control);
4338 _jit = jit_new_state();
4340 instrs = new_hash();
4342 offset < (int)(sizeof(instr_vector) / sizeof(instr_vector[0]));
4344 put_hash(instrs, (entry_t *)(instr_vector + offset));
4346 labels = new_hash();
4352 for (opt_short = 0; opt_index < argc; opt_short++, opt_index++)
4353 argv[opt_short] = argv[opt_index];
4354 argv[opt_short] = NULL;
4356 execute(argc, argv);