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 movr(void); static void movi(void);
320 static void extr_c(void); static void extr_uc(void);
321 static void extr_s(void); static void extr_us(void);
323 static void extr_i(void); static void extr_ui(void);
325 static void htonr_us(void); static void ntohr_us(void);
326 static void htonr_ui(void); static void ntohr_ui(void);
328 static void htonr_ul(void); static void ntohr_ul(void);
330 static void htonr(void); static void ntohr(void);
331 static void bswapr_us(void); static void bswapr_ui(void);
333 static void bswapr_ul(void);
335 static void bswapr(void);
336 static void movnr(void); static void movzr(void);
337 static void ldr_c(void); static void ldi_c(void);
338 static void ldr_uc(void); static void ldi_uc(void);
339 static void ldr_s(void); static void ldi_s(void);
340 static void ldr_us(void); static void ldi_us(void);
341 static void ldr_i(void); static void ldi_i(void);
343 static void ldr_ui(void); static void ldi_ui(void);
344 static void ldr_l(void); static void ldi_l(void);
346 static void ldr(void); static void ldi(void);
347 static void ldxr_c(void); static void ldxi_c(void);
348 static void ldxr_uc(void); static void ldxi_uc(void);
349 static void ldxr_s(void); static void ldxi_s(void);
350 static void ldxr_us(void); static void ldxi_us(void);
351 static void ldxr_i(void); static void ldxi_i(void);
353 static void ldxr_ui(void); static void ldxi_ui(void);
354 static void ldxr_l(void); static void ldxi_l(void);
356 static void ldxr(void); static void ldxi(void);
357 static void str_c(void); static void sti_c(void);
358 static void str_s(void); static void sti_s(void);
359 static void str_i(void); static void sti_i(void);
361 static void str_l(void); static void sti_l(void);
363 static void str(void); static void sti(void);
364 static void stxr_c(void); static void stxi_c(void);
365 static void stxr_s(void); static void stxi_s(void);
366 static void stxr_i(void); static void stxi_i(void);
368 static void stxr_l(void); static void stxi_l(void);
370 static void stxr(void); static void stxi(void);
371 static void bltr(void); static void blti(void);
372 static void bltr_u(void); static void blti_u(void);
373 static void bler(void); static void blei(void);
374 static void bler_u(void); static void blei_u(void);
375 static void beqr(void); static void beqi(void);
376 static void bger(void); static void bgei(void);
377 static void bger_u(void); static void bgei_u(void);
378 static void bgtr(void); static void bgti(void);
379 static void bgtr_u(void); static void bgti_u(void);
380 static void bner(void); static void bnei(void);
381 static void bmsr(void); static void bmsi(void);
382 static void bmcr(void); static void bmci(void);
383 static void boaddr(void); static void boaddi(void);
384 static void boaddr_u(void); static void boaddi_u(void);
385 static void bxaddr(void); static void bxaddi(void);
386 static void bxaddr_u(void); static void bxaddi_u(void);
387 static void bosubr(void); static void bosubi(void);
388 static void bosubr_u(void); static void bosubi_u(void);
389 static void bxsubr(void); static void bxsubi(void);
390 static void bxsubr_u(void); static void bxsubi_u(void);
391 static void jmpr(void); static void jmpi(void);
392 static void callr(void); static void calli(void);
393 static void prepare(void);
394 static void pushargr(void); static void pushargi(void);
395 static void finishr(void); static void finishi(void);
396 static void ret(void);
397 static void retr(void); static void reti(void);
398 static void retval_c(void); static void retval_uc(void);
399 static void retval_s(void); static void retval_us(void);
400 static void retval_i(void);
402 static void retval_ui(void); static void retval_l(void);
404 static void retval(void);
405 static void epilog(void);
406 static void arg_f(void); static void getarg_f(void);
407 static void putargr_f(void); static void putargi_f(void);
408 static void addr_f(void); static void addi_f(void);
409 static void subr_f(void); static void subi_f(void);
410 static void rsbr_f(void); static void rsbi_f(void);
411 static void mulr_f(void); static void muli_f(void);
412 static void divr_f(void); static void divi_f(void);
413 static void negr_f(void); static void absr_f(void);
414 static void sqrtr_f(void);
415 static void ltr_f(void); static void lti_f(void);
416 static void ler_f(void); static void lei_f(void);
417 static void eqr_f(void); static void eqi_f(void);
418 static void ger_f(void); static void gei_f(void);
419 static void gtr_f(void); static void gti_f(void);
420 static void ner_f(void); static void nei_f(void);
421 static void unltr_f(void); static void unlti_f(void);
422 static void unler_f(void); static void unlei_f(void);
423 static void uneqr_f(void); static void uneqi_f(void);
424 static void unger_f(void); static void ungei_f(void);
425 static void ungtr_f(void); static void ungti_f(void);
426 static void ltgtr_f(void); static void ltgti_f(void);
427 static void ordr_f(void); static void ordi_f(void);
428 static void unordr_f(void); static void unordi_f(void);
429 static void truncr_f_i(void);
431 static void truncr_f_l(void);
433 static void truncr_f(void);
434 static void extr_f(void); static void extr_d_f(void);
435 static void movr_f(void); static void movi_f(void);
436 static void ldr_f(void); static void ldi_f(void);
437 static void ldxr_f(void); static void ldxi_f(void);
438 static void str_f(void); static void sti_f(void);
439 static void stxr_f(void); static void stxi_f(void);
440 static void bltr_f(void); static void blti_f(void);
441 static void bler_f(void); static void blei_f(void);
442 static void beqr_f(void); static void beqi_f(void);
443 static void bger_f(void); static void bgei_f(void);
444 static void bgtr_f(void); static void bgti_f(void);
445 static void bner_f(void); static void bnei_f(void);
446 static void bunltr_f(void); static void bunlti_f(void);
447 static void bunler_f(void); static void bunlei_f(void);
448 static void buneqr_f(void); static void buneqi_f(void);
449 static void bunger_f(void); static void bungei_f(void);
450 static void bungtr_f(void); static void bungti_f(void);
451 static void bltgtr_f(void); static void bltgti_f(void);
452 static void bordr_f(void); static void bordi_f(void);
453 static void bunordr_f(void); static void bunordi_f(void);
454 static void pushargr_f(void); static void pushargi_f(void);
455 static void retr_f(void); static void reti_f(void);
456 static void retval_f(void);
457 static void arg_d(void); static void getarg_d(void);
458 static void putargr_d(void); static void putargi_d(void);
459 static void addr_d(void); static void addi_d(void);
460 static void subr_d(void); static void subi_d(void);
461 static void rsbr_d(void); static void rsbi_d(void);
462 static void mulr_d(void); static void muli_d(void);
463 static void divr_d(void); static void divi_d(void);
464 static void negr_d(void); static void absr_d(void);
465 static void sqrtr_d(void);
466 static void ltr_d(void); static void lti_d(void);
467 static void ler_d(void); static void lei_d(void);
468 static void eqr_d(void); static void eqi_d(void);
469 static void ger_d(void); static void gei_d(void);
470 static void gtr_d(void); static void gti_d(void);
471 static void ner_d(void); static void nei_d(void);
472 static void unltr_d(void); static void unlti_d(void);
473 static void unler_d(void); static void unlei_d(void);
474 static void uneqr_d(void); static void uneqi_d(void);
475 static void unger_d(void); static void ungei_d(void);
476 static void ungtr_d(void); static void ungti_d(void);
477 static void ltgtr_d(void); static void ltgti_d(void);
478 static void ordr_d(void); static void ordi_d(void);
479 static void unordr_d(void); static void unordi_d(void);
480 static void truncr_d_i(void);
482 static void truncr_d_l(void);
484 static void truncr_d(void);
485 static void extr_d(void); static void extr_f_d(void);
486 static void movr_d(void); static void movi_d(void);
487 static void ldr_d(void); static void ldi_d(void);
488 static void ldxr_d(void); static void ldxi_d(void);
489 static void str_d(void); static void sti_d(void);
490 static void stxr_d(void); static void stxi_d(void);
491 static void bltr_d(void); static void blti_d(void);
492 static void bler_d(void); static void blei_d(void);
493 static void beqr_d(void); static void beqi_d(void);
494 static void bger_d(void); static void bgei_d(void);
495 static void bgtr_d(void); static void bgti_d(void);
496 static void bner_d(void); static void bnei_d(void);
497 static void bunltr_d(void); static void bunlti_d(void);
498 static void bunler_d(void); static void bunlei_d(void);
499 static void buneqr_d(void); static void buneqi_d(void);
500 static void bunger_d(void); static void bungei_d(void);
501 static void bungtr_d(void); static void bungti_d(void);
502 static void bltgtr_d(void); static void bltgti_d(void);
503 static void bordr_d(void); static void bordi_d(void);
504 static void bunordr_d(void); static void bunordi_d(void);
505 static void pushargr_d(void); static void pushargi_d(void);
506 static void retr_d(void); static void reti_d(void);
507 static void retval_d(void);
508 static void vastart(void); static void vapush(void);
509 static void vaarg(void); static void vaarg_d(void);
510 static void vaend(void);
512 static void error(const char *format, ...) noreturn printf_format(1, 2);
513 static void warn(const char *format, ...) printf_format(1, 2) maybe_unused;
514 static void message(const char *kind, const char *format, va_list ap);
516 static int getch(void);
517 static int getch_noeof(void);
518 static int ungetch(int ch);
519 static int skipws(void);
520 static int skipnl(void);
521 static int skipct(void);
522 static int skipcp(void);
523 static jit_word_t get_int(skip_t skip);
524 static jit_uword_t get_uint(skip_t skip);
525 static double get_float(skip_t skip);
526 static float make_float(double d);
527 static void *get_pointer(skip_t skip);
528 static label_t *get_label(skip_t skip);
529 static token_t regname(void);
530 static token_t identifier(int ch);
531 static void get_data(type_t type);
532 static void dot(void);
533 static token_t number(int ch);
534 static int escape(int ch);
535 static token_t string(void);
536 static token_t dynamic(void);
537 static token_t character(void);
538 static void expression_prim(void);
539 static void expression_inc(int pre);
540 static void expression_dec(int pre);
541 static void expression_unary(void);
542 static void expression_mul(void);
543 static void expression_add(void);
544 static void expression_shift(void);
545 static void expression_bit(void);
546 static void expression_rel(void);
547 static void expression_cond(void);
548 static token_t expression(void);
549 static token_t primary(skip_t skip);
550 static void parse(void);
551 static int execute(int argc, char *argv[]);
553 static void *xmalloc(size_t size);
554 static void *xrealloc(void *pointer, size_t size);
555 static void *xcalloc(size_t nmemb, size_t size);
557 static label_t *new_label(label_kind_t kind, char *name, void *value);
558 static patch_t *new_patch(patch_kind_t kind, label_t *label, void *value);
559 static int bcmp_symbols(const void *left, const void *right);
560 static int qcmp_symbols(const void *left, const void *right);
561 static symbol_t *new_symbol(char *name);
562 static symbol_t *get_symbol_by_name(char *name);
564 static hash_t *new_hash(void);
565 static int hash_string(char *name);
566 static void put_hash(hash_t *hash, entry_t *entry);
567 static entry_t *get_hash(hash_t *hash, char *name);
568 static void rehash(hash_t *hash);
573 static jit_state_t *_jit;
574 static int flag_verbose;
575 static int flag_data;
576 static int flag_disasm;
577 static char *progname;
578 static parser_t parser;
579 static hash_t *labels;
580 static int label_offset;
581 static patch_t *patches;
582 static symbol_t **symbols;
583 static int symbol_length;
584 static int symbol_offset;
585 static hash_t *instrs;
587 static size_t data_offset, data_length;
588 static instr_t instr_vector[] = {
589 #define entry(value) { NULL, #value, value }
590 #define entry2(name, function) { NULL, name, function }
592 entry(align), entry(name),
594 entry(frame), entry(tramp),
596 entry(allocai), entry(allocar),
598 entry(getarg_c), entry(getarg_uc),
599 entry(getarg_s), entry(getarg_us),
602 entry(getarg_ui), entry(getarg_l),
605 entry(putargr), entry(putargi),
606 entry(addr), entry(addi),
607 entry(addxr), entry(addxi),
608 entry(addcr), entry(addci),
609 entry(subr), entry(subi),
610 entry(subxr), entry(subxi),
611 entry(subcr), entry(subci),
612 entry(rsbr), entry(rsbi),
613 entry(mulr), entry(muli),
614 entry(qmulr), entry(qmuli),
615 entry(qmulr_u), entry(qmuli_u),
616 entry(divr), entry(divi),
617 entry(divr_u), entry(divi_u),
618 entry(qdivr), entry(qdivi),
619 entry(qdivr_u), entry(qdivi_u),
620 entry(remr), entry(remi),
621 entry(remr_u), entry(remi_u),
622 entry(andr), entry(andi),
623 entry(orr), entry(ori),
624 entry(xorr), entry(xori),
625 entry(lshr), entry(lshi),
626 entry(rshr), entry(rshi),
627 entry(rshr_u), entry(rshi_u),
628 entry(negr), entry(comr),
629 entry(ltr), entry(lti),
630 entry(ltr_u), entry(lti_u),
631 entry(ler), entry(lei),
632 entry(ler_u), entry(lei_u),
633 entry(eqr), entry(eqi),
634 entry(ger), entry(gei),
635 entry(ger_u), entry(gei_u),
636 entry(gtr), entry(gti),
637 entry(gtr_u), entry(gti_u),
638 entry(ner), entry(nei),
639 entry(movr), entry(movi),
640 entry(extr_c), entry(extr_uc),
641 entry(extr_s), entry(extr_us),
643 entry(extr_i), entry(extr_ui),
645 entry(htonr_us), entry(ntohr_us),
646 entry(htonr_ui), entry(ntohr_ui),
648 entry(htonr_ul), entry(ntohr_ul),
650 entry(htonr), entry(ntohr),
651 entry(bswapr_us), entry(bswapr_ui),
656 entry(movnr), entry(movzr),
657 entry(ldr_c), entry(ldi_c),
658 entry(ldr_uc), entry(ldi_uc),
659 entry(ldr_s), entry(ldi_s),
660 entry(ldr_us), entry(ldi_us),
661 entry(ldr_i), entry(ldi_i),
663 entry(ldr_ui), entry(ldi_ui),
664 entry(ldr_l), entry(ldi_l),
666 entry(ldr), entry(ldi),
667 entry(ldxr_c), entry(ldxi_c),
668 entry(ldxr_uc), entry(ldxi_uc),
669 entry(ldxr_s), entry(ldxi_s),
670 entry(ldxr_us), entry(ldxi_us),
671 entry(ldxr_i), entry(ldxi_i),
673 entry(ldxr_ui), entry(ldxi_ui),
674 entry(ldxr_l), entry(ldxi_l),
676 entry(ldxr), entry(ldxi),
677 entry(str_c), entry(sti_c),
678 entry(str_s), entry(sti_s),
679 entry(str_i), entry(sti_i),
681 entry(str_l), entry(sti_l),
683 entry(str), entry(sti),
684 entry(stxr_c), entry(stxi_c),
685 entry(stxr_s), entry(stxi_s),
686 entry(stxr_i), entry(stxi_i),
688 entry(stxr_l), entry(stxi_l),
690 entry(stxr), entry(stxi),
691 entry(bltr), entry(blti),
692 entry(bltr_u), entry(blti_u),
693 entry(bler), entry(blei),
694 entry(bler_u), entry(blei_u),
695 entry(beqr), entry(beqi),
696 entry(bger), entry(bgei),
697 entry(bger_u), entry(bgei_u),
698 entry(bgtr), entry(bgti),
699 entry(bgtr_u), entry(bgti_u),
700 entry(bner), entry(bnei),
701 entry(bmsr), entry(bmsi),
702 entry(bmcr), entry(bmci),
703 entry(boaddr), entry(boaddi),
704 entry(boaddr_u), entry(boaddi_u),
705 entry(bxaddr), entry(bxaddi),
706 entry(bxaddr_u), entry(bxaddi_u),
707 entry(bosubr), entry(bosubi),
708 entry(bosubr_u), entry(bosubi_u),
709 entry(bxsubr), entry(bxsubi),
710 entry(bxsubr_u), entry(bxsubi_u),
711 entry(jmpr), entry(jmpi),
712 entry(callr), entry(calli),
714 entry(pushargr), entry(pushargi),
715 entry(finishr), entry(finishi),
717 entry(retr), entry(reti),
718 entry(retval_c), entry(retval_uc),
719 entry(retval_s), entry(retval_us),
722 entry(retval_ui), entry(retval_l),
726 entry(arg_f), entry(getarg_f),
727 entry(putargr_f), entry(putargi_f),
728 entry(addr_f), entry(addi_f),
729 entry(subr_f), entry(subi_f),
730 entry(rsbr_f), entry(rsbi_f),
731 entry(mulr_f), entry(muli_f),
732 entry(divr_f), entry(divi_f),
733 entry(negr_f), entry(absr_f),
735 entry(ltr_f), entry(lti_f),
736 entry(ler_f), entry(lei_f),
737 entry(eqr_f), entry(eqi_f),
738 entry(ger_f), entry(gei_f),
739 entry(gtr_f), entry(gti_f),
740 entry(ner_f), entry(nei_f),
741 entry(unltr_f), entry(unlti_f),
742 entry(unler_f), entry(unlei_f),
743 entry(uneqr_f), entry(uneqi_f),
744 entry(unger_f), entry(ungei_f),
745 entry(ungtr_f), entry(ungti_f),
746 entry(ltgtr_f), entry(ltgti_f),
747 entry(ordr_f), entry(ordi_f),
748 entry(unordr_f), entry(unordi_f),
754 entry(extr_f), entry(extr_d_f),
755 entry(movr_f), entry(movi_f),
756 entry(ldr_f), entry(ldi_f),
757 entry(ldxr_f), entry(ldxi_f),
758 entry(str_f), entry(sti_f),
759 entry(stxr_f), entry(stxi_f),
760 entry(bltr_f), entry(blti_f),
761 entry(bler_f), entry(blei_f),
762 entry(beqr_f), entry(beqi_f),
763 entry(bger_f), entry(bgei_f),
764 entry(bgtr_f), entry(bgti_f),
765 entry(bner_f), entry(bnei_f),
766 entry(bunltr_f), entry(bunlti_f),
767 entry(bunler_f), entry(bunlei_f),
768 entry(buneqr_f), entry(buneqi_f),
769 entry(bunger_f), entry(bungei_f),
770 entry(bungtr_f), entry(bungti_f),
771 entry(bltgtr_f), entry(bltgti_f),
772 entry(bordr_f), entry(bordi_f),
773 entry(bunordr_f), entry(bunordi_f),
774 entry(pushargr_f), entry(pushargi_f),
775 entry(retr_f), entry(reti_f),
777 entry(arg_d), entry(getarg_d),
778 entry(putargr_d), entry(putargi_d),
779 entry(addr_d), entry(addi_d),
780 entry(subr_d), entry(subi_d),
781 entry(rsbr_d), entry(rsbi_d),
782 entry(mulr_d), entry(muli_d),
783 entry(divr_d), entry(divi_d),
784 entry(negr_d), entry(absr_d),
786 entry(ltr_d), entry(lti_d),
787 entry(ler_d), entry(lei_d),
788 entry(eqr_d), entry(eqi_d),
789 entry(ger_d), entry(gei_d),
790 entry(gtr_d), entry(gti_d),
791 entry(ner_d), entry(nei_d),
792 entry(unltr_d), entry(unlti_d),
793 entry(unler_d), entry(unlei_d),
794 entry(uneqr_d), entry(uneqi_d),
795 entry(unger_d), entry(ungei_d),
796 entry(ungtr_d), entry(ungti_d),
797 entry(ltgtr_d), entry(ltgti_d),
798 entry(ordr_d), entry(ordi_d),
799 entry(unordr_d), entry(unordi_d),
805 entry(extr_d), entry(extr_f_d),
806 entry(movr_d), entry(movi_d),
807 entry(ldr_d), entry(ldi_d),
808 entry(ldxr_d), entry(ldxi_d),
809 entry(str_d), entry(sti_d),
810 entry(stxr_d), entry(stxi_d),
811 entry(bltr_d), entry(blti_d),
812 entry(bler_d), entry(blei_d),
813 entry(beqr_d), entry(beqi_d),
814 entry(bger_d), entry(bgei_d),
815 entry(bgtr_d), entry(bgti_d),
816 entry(bner_d), entry(bnei_d),
817 entry(bunltr_d), entry(bunlti_d),
818 entry(bunler_d), entry(bunlei_d),
819 entry(buneqr_d), entry(buneqi_d),
820 entry(bunger_d), entry(bungei_d),
821 entry(bungtr_d), entry(bungti_d),
822 entry(bltgtr_d), entry(bltgti_d),
823 entry(bordr_d), entry(bordi_d),
824 entry(bunordr_d), entry(bunordi_d),
825 entry(pushargr_d), entry(pushargi_d),
826 entry(retr_d), entry(reti_d),
828 entry2("va_start", vastart),
829 entry2("va_push", vapush),
830 entry2("va_arg", vaarg),
831 entry2("va_arg_d", vaarg_d),
832 entry2("va_end", vaend),
842 if (primary(skip_ws) != tok_register)
843 error("bad register");
844 if (parser.regtype != type_l)
845 error("bad int register");
847 return ((jit_gpr_t)parser.regval);
853 if (primary(skip_ws) != tok_register)
854 error("bad register");
855 if (parser.regtype != type_d)
856 error("bad float register");
858 return ((jit_fpr_t)parser.regval);
868 error("expecting variable");
869 (void)identifier('$');
870 if (parser.string[1] == '\0')
871 error("expecting variable");
872 if ((symbol = get_symbol_by_name(parser.string)) == NULL)
873 symbol = new_symbol(parser.string);
879 jmp_forward(void *value, label_t *label)
881 (void)new_patch(patch_kind_jmp, label, value);
885 mov_forward(void *value, label_t *label)
887 (void)new_patch(patch_kind_mov, label, value);
891 call_forward(void *value, label_t *label)
893 (void)new_patch(patch_kind_call, label, value);
897 make_arg(void *value)
899 symbol_t *symbol = get_symbol();
901 symbol->type = type_p;
902 symbol->value.p = value;
908 symbol_t *symbol = get_symbol();
910 if (symbol->type != type_p)
911 error("bad argument %s type", symbol->name);
913 return symbol->value.p;
924 case '+': case '-': case '0' ... '9':
926 value = get_int(skip_none);
930 value = parser.value.i;
933 switch (expression()) {
936 value = parser.value.i;
939 error("expecting immediate");
944 value = (jit_word_t)parser.value.p;
948 label = get_label(skip_none);
949 if (label->kind == label_kind_data)
950 value = (jit_word_t)label->value;
952 error("expecting immediate");
958 #define entry(name) \
964 #define entry_ca(name) \
968 make_arg(jit_##name()); \
970 #define entry_ia(name) \
974 jit_gpr_t r0 = get_ireg(); \
975 jit_pointer_t ac = get_arg(); \
976 jit_##name(r0, ac); \
978 #define entry_im(name) \
982 jit_word_t im = get_imm(); \
985 #define entry_ir(name) \
989 jit_gpr_t r0 = get_ireg(); \
992 #define entry_ima(name) \
996 jit_word_t im = get_imm(); \
997 jit_pointer_t ac = get_arg(); \
998 jit_##name(im, ac); \
1000 #define entry_ir_ir_ir(name) \
1004 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(), r2 = get_ireg(); \
1005 jit_##name(r0, r1, r2); \
1007 #define entry_ir_ir_im(name) \
1011 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \
1012 jit_word_t im = get_imm(); \
1013 jit_##name(r0, r1, im); \
1015 #define entry_ir_ir_ir_ir(name) \
1019 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(), \
1020 r2 = get_ireg(), r3 = get_ireg(); \
1021 jit_##name(r0, r1, r2, r3); \
1023 #define entry_ir_ir_ir_im(name) \
1027 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(), r2 = get_ireg(); \
1028 jit_word_t im = get_imm(); \
1029 jit_##name(r0, r1, r2, im); \
1031 #define entry_ir_ir(name) \
1035 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \
1036 jit_##name(r0, r1); \
1038 #define entry_ir_im(name) \
1042 jit_gpr_t r0 = get_ireg(); \
1043 jit_word_t im = get_imm(); \
1044 jit_##name(r0, im); \
1046 #define entry_ir_pm(name) \
1050 jit_gpr_t r0 = get_ireg(); \
1051 void *pm = get_pointer(skip_ws); \
1052 jit_##name(r0, pm); \
1054 #define entry_pm_ir(name) \
1058 void *pm = get_pointer(skip_ws); \
1059 jit_gpr_t r0 = get_ireg(); \
1060 jit_##name(pm, r0); \
1062 #define entry_im_ir_ir(name) \
1066 jit_word_t im = get_imm(); \
1067 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \
1068 (void)jit_##name(im, r0, r1); \
1070 #define entry_lb_ir_ir(name) \
1075 label_t *label = get_label(skip_ws); \
1076 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \
1077 if (label->kind == label_kind_code_forward) \
1078 jmp_forward((void *)jit_##name(r0, r1), label); \
1080 jmp = jit_##name(r0, r1); \
1081 jit_patch_at(jmp, (jit_node_t *)label->value); \
1084 #define entry_lb_ir_im(name) \
1089 label_t *label = get_label(skip_ws); \
1090 jit_gpr_t r0 = get_ireg(); \
1091 jit_word_t im = get_imm(); \
1092 if (label->kind == label_kind_code_forward) \
1093 jmp_forward((void *)jit_##name(r0, im), label); \
1095 jmp = jit_##name(r0, im); \
1096 jit_patch_at(jmp, (jit_node_t *)label->value); \
1099 #define entry_lb(name) \
1104 label_t *label = get_label(skip_ws); \
1105 if (label->kind == label_kind_code_forward) \
1106 jmp_forward((void *)jit_##name(), label); \
1108 jmp = jit_##name(); \
1109 jit_patch_at(jmp, (jit_node_t *)label->value); \
1112 #define entry_pm(name) \
1116 void *pm = get_pointer(skip_ws); \
1119 #define entry_fa(name) \
1123 jit_fpr_t r0 = get_freg(); \
1124 jit_pointer_t ac = get_arg(); \
1125 jit_##name(r0, ac); \
1127 #define entry_fma(name) \
1131 jit_float64_t im = get_float(skip_ws); \
1132 jit_pointer_t ac = get_arg(); \
1133 jit_##name(im, ac); \
1135 #define entry_fr_fr_fr(name) \
1139 jit_fpr_t r0 = get_freg(), r1 = get_freg(), r2 = get_freg(); \
1140 jit_##name(r0, r1, r2); \
1142 #define entry_fr_fr_fm(name) \
1146 jit_fpr_t r0 = get_freg(), r1 = get_freg(); \
1147 jit_float64_t im = get_float(skip_ws); \
1148 jit_##name(r0, r1, make_float(im)); \
1150 #define entry_fr_fr_dm(name) \
1154 jit_fpr_t r0 = get_freg(), r1 = get_freg(); \
1155 jit_float64_t im = get_float(skip_ws); \
1156 jit_##name(r0, r1, im); \
1158 #define entry_fr_fr(name) \
1162 jit_fpr_t r0 = get_freg(), r1 = get_freg(); \
1163 jit_##name(r0, r1); \
1165 #define entry_ir_fr_fr(name) \
1169 jit_gpr_t r0 = get_ireg(); \
1170 jit_fpr_t r1 = get_freg(), r2 = get_freg(); \
1171 jit_##name(r0, r1, r2); \
1173 #define entry_ir_fr_fm(name) \
1177 jit_gpr_t r0 = get_ireg(); \
1178 jit_fpr_t r1 = get_freg(); \
1179 jit_float64_t im = get_float(skip_ws); \
1180 jit_##name(r0, r1, make_float(im)); \
1182 #define entry_ir_fr_dm(name) \
1186 jit_gpr_t r0 = get_ireg(); \
1187 jit_fpr_t r1 = get_freg(); \
1188 jit_float64_t im = get_float(skip_ws); \
1189 jit_##name(r0, r1, im); \
1191 #define entry_ir_fr(name) \
1195 jit_gpr_t r0 = get_ireg(); \
1196 jit_fpr_t r1 = get_freg(); \
1197 jit_##name(r0, r1); \
1199 #define entry_fr_ir(name) \
1203 jit_fpr_t r0 = get_freg(); \
1204 jit_gpr_t r1 = get_ireg(); \
1205 jit_##name(r0, r1); \
1207 #define entry_fr_fm(name) \
1211 jit_fpr_t r0 = get_freg(); \
1212 jit_float64_t im = get_float(skip_ws); \
1213 jit_##name(r0, make_float(im)); \
1215 #define entry_fr_dm(name) \
1219 jit_fpr_t r0 = get_freg(); \
1220 jit_float64_t im = get_float(skip_ws); \
1221 jit_##name(r0, im); \
1223 #define entry_fr_pm(name) \
1227 jit_fpr_t r0 = get_freg(); \
1228 void *pm = get_pointer(skip_ws); \
1229 jit_##name(r0, pm); \
1231 #define entry_fr_ir_ir(name) \
1235 jit_fpr_t r0 = get_freg(); \
1236 jit_gpr_t r1 = get_ireg(), r2 = get_ireg(); \
1237 jit_##name(r0, r1, r2); \
1239 #define entry_fr_ir_im(name) \
1243 jit_fpr_t r0 = get_freg(); \
1244 jit_gpr_t r1 = get_ireg(); \
1245 jit_word_t im = get_imm(); \
1246 jit_##name(r0, r1, im); \
1248 #define entry_pm_fr(name) \
1252 void *pm = get_pointer(skip_ws); \
1253 jit_fpr_t r0 = get_freg(); \
1254 jit_##name(pm, r0); \
1256 #define entry_ir_ir_fr(name) \
1260 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \
1261 jit_fpr_t r2 = get_freg(); \
1262 jit_##name(r0, r1, r2); \
1264 #define entry_im_ir_fr(name) \
1268 jit_word_t im = get_imm(); \
1269 jit_gpr_t r0 = get_ireg(); \
1270 jit_fpr_t r1 = get_freg(); \
1271 jit_##name(im, r0, r1); \
1273 #define entry_lb_fr_fr(name) \
1278 label_t *label = get_label(skip_ws); \
1279 jit_fpr_t r0 = get_freg(), r1 = get_freg(); \
1280 if (label->kind == label_kind_code_forward) \
1281 jmp_forward((void *)jit_##name(r0, r1), label); \
1283 jmp = jit_##name(r0, r1); \
1284 jit_patch_at(jmp, (jit_node_t *)label->value); \
1287 #define entry_lb_fr_fm(name) \
1292 label_t *label = get_label(skip_ws); \
1293 jit_fpr_t r0 = get_freg(); \
1294 jit_float64_t im = get_float(skip_ws); \
1295 if (label->kind == label_kind_code_forward) \
1296 jmp_forward((void *)jit_##name(r0, make_float(im)), label); \
1298 jmp = jit_##name(r0, make_float(im)); \
1299 jit_patch_at(jmp, (jit_node_t *)label->value); \
1302 #define entry_lb_fr_dm(name) \
1307 label_t *label = get_label(skip_ws); \
1308 jit_fpr_t r0 = get_freg(); \
1309 jit_float64_t im = get_float(skip_ws); \
1310 if (label->kind == label_kind_code_forward) \
1311 jmp_forward((void *)jit_##name(r0, im), label); \
1313 jmp = jit_##name(r0, im); \
1314 jit_patch_at(jmp, (jit_node_t *)label->value); \
1317 #define entry_fr(name) \
1321 jit_fpr_t r0 = get_freg(); \
1324 #define entry_fm(name) \
1328 jit_float64_t im = get_float(skip_ws); \
1329 jit_##name(make_float(im)); \
1331 #define entry_dm(name) \
1335 jit_float64_t im = get_float(skip_ws); \
1338 #define entry_fn(name) \
1349 value = (void *)(jit_word_t)get_uint(skip_none); \
1352 switch (expression()) { \
1354 value = (void *)parser.value.i; \
1357 value = parser.value.p; \
1360 error("expecting pointer"); \
1365 value = parser.value.p; \
1369 label = get_label(skip_none); \
1370 if (label->kind == label_kind_code_forward) \
1371 call_forward((void *)jit_##name(NULL), label); \
1373 jit_patch_at(jit_##name(NULL), label->value); \
1376 jit_##name(value); \
1381 (void)identifier(ch);
1382 jit_name(parser.string);
1386 if (primary(skip_ws) != tok_register)
1387 error("bad register");
1388 jit_live(parser.regval);
1392 entry_im(frame) entry_im(tramp)
1397 jit_word_t i, im = get_imm();
1398 i = jit_allocai(im);
1399 symbol = get_symbol();
1400 symbol->type = type_l;
1401 symbol->value.i = i;
1403 entry_ir_ir(allocar)
1405 entry_ia(getarg_c) entry_ia(getarg_uc)
1406 entry_ia(getarg_s) entry_ia(getarg_us)
1408 #if __WORDSIZE == 64
1409 entry_ia(getarg_ui) entry_ia(getarg_l)
1412 entry_ia(putargr) entry_ima(putargi)
1413 entry_ir_ir_ir(addr) entry_ir_ir_im(addi)
1414 entry_ir_ir_ir(addxr) entry_ir_ir_im(addxi)
1415 entry_ir_ir_ir(addcr) entry_ir_ir_im(addci)
1416 entry_ir_ir_ir(subr) entry_ir_ir_im(subi)
1417 entry_ir_ir_ir(subxr) entry_ir_ir_im(subxi)
1418 entry_ir_ir_ir(subcr) entry_ir_ir_im(subci)
1419 entry_ir_ir_ir(rsbr) entry_ir_ir_im(rsbi)
1420 entry_ir_ir_ir(mulr) entry_ir_ir_im(muli)
1421 entry_ir_ir_ir_ir(qmulr) entry_ir_ir_ir_im(qmuli)
1422 entry_ir_ir_ir_ir(qmulr_u) entry_ir_ir_ir_im(qmuli_u)
1423 entry_ir_ir_ir(divr) entry_ir_ir_im(divi)
1424 entry_ir_ir_ir(divr_u) entry_ir_ir_im(divi_u)
1425 entry_ir_ir_ir_ir(qdivr) entry_ir_ir_ir_im(qdivi)
1426 entry_ir_ir_ir_ir(qdivr_u) entry_ir_ir_ir_im(qdivi_u)
1427 entry_ir_ir_ir(remr) entry_ir_ir_im(remi)
1428 entry_ir_ir_ir(remr_u) entry_ir_ir_im(remi_u)
1429 entry_ir_ir_ir(andr) entry_ir_ir_im(andi)
1430 entry_ir_ir_ir(orr) entry_ir_ir_im(ori)
1431 entry_ir_ir_ir(xorr) entry_ir_ir_im(xori)
1432 entry_ir_ir_ir(lshr) entry_ir_ir_im(lshi)
1433 entry_ir_ir_ir(rshr) entry_ir_ir_im(rshi)
1434 entry_ir_ir_ir(rshr_u) entry_ir_ir_im(rshi_u)
1435 entry_ir_ir(negr) entry_ir_ir(comr)
1436 entry_ir_ir_ir(ltr) entry_ir_ir_im(lti)
1437 entry_ir_ir_ir(ltr_u) entry_ir_ir_im(lti_u)
1438 entry_ir_ir_ir(ler) entry_ir_ir_im(lei)
1439 entry_ir_ir_ir(ler_u) entry_ir_ir_im(lei_u)
1440 entry_ir_ir_ir(eqr) entry_ir_ir_im(eqi)
1441 entry_ir_ir_ir(ger) entry_ir_ir_im(gei)
1442 entry_ir_ir_ir(ger_u) entry_ir_ir_im(gei_u)
1443 entry_ir_ir_ir(gtr) entry_ir_ir_im(gti)
1444 entry_ir_ir_ir(gtr_u) entry_ir_ir_im(gti_u)
1445 entry_ir_ir_ir(ner) entry_ir_ir_im(nei)
1453 jit_gpr_t r0 = get_ireg();
1459 value = (void *)(jit_word_t)get_uint(skip_none);
1463 value = (void *)parser.value.i;
1466 switch (expression()) {
1468 value = (void *)parser.value.i;
1471 value = parser.value.p;
1474 error("expecting pointer");
1479 value = parser.value.p;
1483 label = get_label(skip_none);
1484 if (label->kind == label_kind_code ||
1485 label->kind == label_kind_code_forward) {
1486 mov_forward((void *)jit_movi(r0, 0), label);
1489 value = label->value;
1492 jit_movi(r0, (jit_word_t)value);
1494 entry_ir_ir(extr_c) entry_ir_ir(extr_uc)
1495 entry_ir_ir(extr_s) entry_ir_ir(extr_us)
1496 #if __WORDSIZE == 64
1497 entry_ir_ir(extr_i) entry_ir_ir(extr_ui)
1499 entry_ir_ir(htonr_us) entry_ir_ir(ntohr_us)
1500 entry_ir_ir(htonr_ui) entry_ir_ir(ntohr_ui)
1501 #if __WORDSIZE == 64
1502 entry_ir_ir(htonr_ul) entry_ir_ir(ntohr_ul)
1504 entry_ir_ir(htonr) entry_ir_ir(ntohr)
1505 entry_ir_ir(bswapr_us) entry_ir_ir(bswapr_ui)
1506 #if __WORDSIZE == 64
1507 entry_ir_ir(bswapr_ul)
1510 entry_ir_ir_ir(movnr) entry_ir_ir_ir(movzr)
1511 entry_ir_ir(ldr_c) entry_ir_pm(ldi_c)
1512 entry_ir_ir(ldr_uc) entry_ir_pm(ldi_uc)
1513 entry_ir_ir(ldr_s) entry_ir_pm(ldi_s)
1514 entry_ir_ir(ldr_us) entry_ir_pm(ldi_us)
1515 entry_ir_ir(ldr_i) entry_ir_pm(ldi_i)
1516 #if __WORDSIZE == 64
1517 entry_ir_ir(ldr_ui) entry_ir_pm(ldi_ui)
1518 entry_ir_ir(ldr_l) entry_ir_pm(ldi_l)
1520 entry_ir_ir(ldr) entry_ir_pm(ldi)
1521 entry_ir_ir_ir(ldxr_c) entry_ir_ir_im(ldxi_c)
1522 entry_ir_ir_ir(ldxr_uc) entry_ir_ir_im(ldxi_uc)
1523 entry_ir_ir_ir(ldxr_s) entry_ir_ir_im(ldxi_s)
1524 entry_ir_ir_ir(ldxr_us) entry_ir_ir_im(ldxi_us)
1525 entry_ir_ir_ir(ldxr_i) entry_ir_ir_im(ldxi_i)
1526 #if __WORDSIZE == 64
1527 entry_ir_ir_ir(ldxr_ui) entry_ir_ir_im(ldxi_ui)
1528 entry_ir_ir_ir(ldxr_l) entry_ir_ir_im(ldxi_l)
1530 entry_ir_ir_ir(ldxr) entry_ir_ir_im(ldxi)
1531 entry_ir_ir(str_c) entry_pm_ir(sti_c)
1532 entry_ir_ir(str_s) entry_pm_ir(sti_s)
1533 entry_ir_ir(str_i) entry_pm_ir(sti_i)
1534 #if __WORDSIZE == 64
1535 entry_ir_ir(str_l) entry_pm_ir(sti_l)
1537 entry_ir_ir(str) entry_pm_ir(sti)
1538 entry_ir_ir_ir(stxr_c) entry_im_ir_ir(stxi_c)
1539 entry_ir_ir_ir(stxr_s) entry_im_ir_ir(stxi_s)
1540 entry_ir_ir_ir(stxr_i) entry_im_ir_ir(stxi_i)
1541 #if __WORDSIZE == 64
1542 entry_ir_ir_ir(stxr_l) entry_im_ir_ir(stxi_l)
1544 entry_ir_ir_ir(stxr) entry_im_ir_ir(stxi)
1545 entry_lb_ir_ir(bltr) entry_lb_ir_im(blti)
1546 entry_lb_ir_ir(bltr_u) entry_lb_ir_im(blti_u)
1547 entry_lb_ir_ir(bler) entry_lb_ir_im(blei)
1548 entry_lb_ir_ir(bler_u) entry_lb_ir_im(blei_u)
1549 entry_lb_ir_ir(beqr) entry_lb_ir_im(beqi)
1550 entry_lb_ir_ir(bger) entry_lb_ir_im(bgei)
1551 entry_lb_ir_ir(bger_u) entry_lb_ir_im(bgei_u)
1552 entry_lb_ir_ir(bgtr) entry_lb_ir_im(bgti)
1553 entry_lb_ir_ir(bgtr_u) entry_lb_ir_im(bgti_u)
1554 entry_lb_ir_ir(bner) entry_lb_ir_im(bnei)
1555 entry_lb_ir_ir(bmsr) entry_lb_ir_im(bmsi)
1556 entry_lb_ir_ir(bmcr) entry_lb_ir_im(bmci)
1557 entry_lb_ir_ir(boaddr) entry_lb_ir_im(boaddi)
1558 entry_lb_ir_ir(boaddr_u) entry_lb_ir_im(boaddi_u)
1559 entry_lb_ir_ir(bxaddr) entry_lb_ir_im(bxaddi)
1560 entry_lb_ir_ir(bxaddr_u) entry_lb_ir_im(bxaddi_u)
1561 entry_lb_ir_ir(bosubr) entry_lb_ir_im(bosubi)
1562 entry_lb_ir_ir(bosubr_u) entry_lb_ir_im(bosubi_u)
1563 entry_lb_ir_ir(bxsubr) entry_lb_ir_im(bxsubi)
1564 entry_lb_ir_ir(bxsubr_u) entry_lb_ir_im(bxsubi_u)
1565 entry_ir(jmpr) entry_lb(jmpi)
1566 entry_ir(callr) entry_fn(calli)
1568 entry_ir(pushargr) entry_im(pushargi)
1569 entry_ir(finishr) entry_fn(finishi)
1571 entry_ir(retr) entry_im(reti)
1572 entry_ir(retval_c) entry_ir(retval_uc)
1573 entry_ir(retval_s) entry_ir(retval_us)
1575 #if __WORDSIZE == 64
1576 entry_ir(retval_ui) entry_ir(retval_l)
1580 entry_ca(arg_f) entry_fa(getarg_f)
1581 entry_fa(putargr_f) entry_fma(putargi_f)
1582 entry_fr_fr_fr(addr_f) entry_fr_fr_fm(addi_f)
1583 entry_fr_fr_fr(subr_f) entry_fr_fr_fm(subi_f)
1584 entry_fr_fr_fr(rsbr_f) entry_fr_fr_fm(rsbi_f)
1585 entry_fr_fr_fr(mulr_f) entry_fr_fr_fm(muli_f)
1586 entry_fr_fr_fr(divr_f) entry_fr_fr_fm(divi_f)
1587 entry_fr_fr(negr_f) entry_fr_fr(absr_f)
1588 entry_fr_fr(sqrtr_f)
1589 entry_ir_fr_fr(ltr_f) entry_ir_fr_fm(lti_f)
1590 entry_ir_fr_fr(ler_f) entry_ir_fr_fm(lei_f)
1591 entry_ir_fr_fr(eqr_f) entry_ir_fr_fm(eqi_f)
1592 entry_ir_fr_fr(ger_f) entry_ir_fr_fm(gei_f)
1593 entry_ir_fr_fr(gtr_f) entry_ir_fr_fm(gti_f)
1594 entry_ir_fr_fr(ner_f) entry_ir_fr_fm(nei_f)
1595 entry_ir_fr_fr(unltr_f) entry_ir_fr_fm(unlti_f)
1596 entry_ir_fr_fr(unler_f) entry_ir_fr_fm(unlei_f)
1597 entry_ir_fr_fr(uneqr_f) entry_ir_fr_fm(uneqi_f)
1598 entry_ir_fr_fr(unger_f) entry_ir_fr_fm(ungei_f)
1599 entry_ir_fr_fr(ungtr_f) entry_ir_fr_fm(ungti_f)
1600 entry_ir_fr_fr(ltgtr_f) entry_ir_fr_fm(ltgti_f)
1601 entry_ir_fr_fr(ordr_f) entry_ir_fr_fm(ordi_f)
1602 entry_ir_fr_fr(unordr_f) entry_ir_fr_fm(unordi_f)
1603 entry_ir_fr(truncr_f_i)
1604 #if __WORDSIZE == 64
1605 entry_ir_fr(truncr_f_l)
1607 entry_ir_fr(truncr_f)
1608 entry_fr_ir(extr_f) entry_fr_fr(extr_d_f)
1609 entry_fr_fr(movr_f) entry_fr_fm(movi_f)
1610 entry_fr_ir(ldr_f) entry_fr_pm(ldi_f)
1611 entry_fr_ir_ir(ldxr_f) entry_fr_ir_im(ldxi_f)
1612 entry_ir_fr(str_f) entry_pm_fr(sti_f)
1613 entry_ir_ir_fr(stxr_f) entry_im_ir_fr(stxi_f)
1614 entry_lb_fr_fr(bltr_f) entry_lb_fr_fm(blti_f)
1615 entry_lb_fr_fr(bler_f) entry_lb_fr_fm(blei_f)
1616 entry_lb_fr_fr(beqr_f) entry_lb_fr_fm(beqi_f)
1617 entry_lb_fr_fr(bger_f) entry_lb_fr_fm(bgei_f)
1618 entry_lb_fr_fr(bgtr_f) entry_lb_fr_fm(bgti_f)
1619 entry_lb_fr_fr(bner_f) entry_lb_fr_fm(bnei_f)
1620 entry_lb_fr_fr(bunltr_f) entry_lb_fr_fm(bunlti_f)
1621 entry_lb_fr_fr(bunler_f) entry_lb_fr_fm(bunlei_f)
1622 entry_lb_fr_fr(buneqr_f) entry_lb_fr_fm(buneqi_f)
1623 entry_lb_fr_fr(bunger_f) entry_lb_fr_fm(bungei_f)
1624 entry_lb_fr_fr(bungtr_f) entry_lb_fr_fm(bungti_f)
1625 entry_lb_fr_fr(bltgtr_f) entry_lb_fr_fm(bltgti_f)
1626 entry_lb_fr_fr(bordr_f) entry_lb_fr_fm(bordi_f)
1627 entry_lb_fr_fr(bunordr_f) entry_lb_fr_fm(bunordi_f)
1628 entry_fr(pushargr_f) entry_fm(pushargi_f)
1629 entry_fr(retr_f) entry_fm(reti_f)
1631 entry_ca(arg_d) entry_fa(getarg_d)
1632 entry_fa(putargr_d) entry_fma(putargi_d)
1633 entry_fr_fr_fr(addr_d) entry_fr_fr_dm(addi_d)
1634 entry_fr_fr_fr(subr_d) entry_fr_fr_dm(subi_d)
1635 entry_fr_fr_fr(rsbr_d) entry_fr_fr_dm(rsbi_d)
1636 entry_fr_fr_fr(mulr_d) entry_fr_fr_dm(muli_d)
1637 entry_fr_fr_fr(divr_d) entry_fr_fr_dm(divi_d)
1638 entry_fr_fr(negr_d) entry_fr_fr(absr_d)
1639 entry_fr_fr(sqrtr_d)
1640 entry_ir_fr_fr(ltr_d) entry_ir_fr_dm(lti_d)
1641 entry_ir_fr_fr(ler_d) entry_ir_fr_dm(lei_d)
1642 entry_ir_fr_fr(eqr_d) entry_ir_fr_dm(eqi_d)
1643 entry_ir_fr_fr(ger_d) entry_ir_fr_dm(gei_d)
1644 entry_ir_fr_fr(gtr_d) entry_ir_fr_dm(gti_d)
1645 entry_ir_fr_fr(ner_d) entry_ir_fr_dm(nei_d)
1646 entry_ir_fr_fr(unltr_d) entry_ir_fr_dm(unlti_d)
1647 entry_ir_fr_fr(unler_d) entry_ir_fr_dm(unlei_d)
1648 entry_ir_fr_fr(uneqr_d) entry_ir_fr_dm(uneqi_d)
1649 entry_ir_fr_fr(unger_d) entry_ir_fr_dm(ungei_d)
1650 entry_ir_fr_fr(ungtr_d) entry_ir_fr_dm(ungti_d)
1651 entry_ir_fr_fr(ltgtr_d) entry_ir_fr_dm(ltgti_d)
1652 entry_ir_fr_fr(ordr_d) entry_ir_fr_dm(ordi_d)
1653 entry_ir_fr_fr(unordr_d) entry_ir_fr_dm(unordi_d)
1654 entry_ir_fr(truncr_d_i)
1655 #if __WORDSIZE == 64
1656 entry_ir_fr(truncr_d_l)
1658 entry_ir_fr(truncr_d)
1659 entry_fr_ir(extr_d) entry_fr_fr(extr_f_d)
1660 entry_fr_fr(movr_d) entry_fr_dm(movi_d)
1661 entry_fr_ir(ldr_d) entry_fr_pm(ldi_d)
1662 entry_fr_ir_ir(ldxr_d) entry_fr_ir_im(ldxi_d)
1663 entry_ir_fr(str_d) entry_pm_fr(sti_d)
1664 entry_ir_ir_fr(stxr_d) entry_im_ir_fr(stxi_d)
1665 entry_lb_fr_fr(bltr_d) entry_lb_fr_dm(blti_d)
1666 entry_lb_fr_fr(bler_d) entry_lb_fr_dm(blei_d)
1667 entry_lb_fr_fr(beqr_d) entry_lb_fr_dm(beqi_d)
1668 entry_lb_fr_fr(bger_d) entry_lb_fr_dm(bgei_d)
1669 entry_lb_fr_fr(bgtr_d) entry_lb_fr_dm(bgti_d)
1670 entry_lb_fr_fr(bner_d) entry_lb_fr_dm(bnei_d)
1671 entry_lb_fr_fr(bunltr_d) entry_lb_fr_dm(bunlti_d)
1672 entry_lb_fr_fr(bunler_d) entry_lb_fr_dm(bunlei_d)
1673 entry_lb_fr_fr(buneqr_d) entry_lb_fr_dm(buneqi_d)
1674 entry_lb_fr_fr(bunger_d) entry_lb_fr_dm(bungei_d)
1675 entry_lb_fr_fr(bungtr_d) entry_lb_fr_dm(bungti_d)
1676 entry_lb_fr_fr(bltgtr_d) entry_lb_fr_dm(bltgti_d)
1677 entry_lb_fr_fr(bordr_d) entry_lb_fr_dm(bordi_d)
1678 entry_lb_fr_fr(bunordr_d) entry_lb_fr_dm(bunordi_d)
1679 entry_fr(pushargr_d) entry_dm(pushargi_d)
1680 entry_fr(retr_d) entry_dm(reti_d)
1685 jit_gpr_t r0 = get_ireg();
1691 jit_gpr_t r0 = get_ireg();
1697 jit_gpr_t r0 = get_ireg(), r1 = get_ireg();
1703 jit_fpr_t r0 = get_freg();
1704 jit_gpr_t r1 = get_ireg();
1705 jit_va_arg_d(r0, r1);
1710 jit_gpr_t r0 = get_ireg();
1716 #undef entry_lb_fr_fm
1717 #undef entry_lb_fr_dm
1718 #undef entry_lb_fr_fr
1719 #undef entry_im_ir_fr
1720 #undef entry_ir_ir_fr
1722 #undef entry_fr_ir_ir
1723 #undef entry_fr_ir_im
1729 #undef entry_ir_fr_fm
1730 #undef entry_ir_fr_dm
1731 #undef entry_ir_fr_fr
1733 #undef entry_fr_fr_fm
1734 #undef entry_fr_fr_dm
1735 #undef entry_fr_fr_fr
1740 #undef entry_lb_ir_im
1741 #undef entry_lb_ir_ir
1742 #undef entry_im_ir_ir
1747 #undef entry_ir_ir_im
1748 #undef entry_ir_ir_ir
1757 error(const char *format, ...)
1763 va_start(ap, format);
1764 message("error", format, ap);
1766 length = parser.data.length - parser.data.offset;
1767 string = (char *)(parser.data.buffer + parser.data.offset - 1);
1769 strcpy(string + 74, "...");
1771 parser.data.buffer[parser.data.length - 1] = '\0';
1772 fprintf(stderr, "(%s)\n", string);
1777 warn(const char *format, ...)
1780 va_start(ap, format);
1781 message("warning", format, ap);
1786 message(const char *kind, const char *format, va_list ap)
1788 fprintf(stderr, "%s:%d: %s: ", parser.name,
1789 parser.line - parser.newline, kind);
1790 vfprintf(stderr, format, ap);
1791 fputc('\n', stderr);
1799 if (parser.data.offset < parser.data.length)
1800 ch = parser.data.buffer[parser.data.offset++];
1802 /* keep first offset for ungetch */
1803 if ((parser.data.length = fread(parser.data.buffer + 1, 1,
1804 sizeof(parser.data.buffer) - 1,
1805 parser.fp) + 1) <= 1) {
1807 parser.data.offset = 1;
1810 ch = parser.data.buffer[1];
1811 parser.data.offset = 2;
1814 if ((parser.newline = ch == '\n'))
1826 error("unexpected end of file");
1834 if ((parser.newline = ch == '\n'))
1837 if (parser.data.offset)
1838 parser.data.buffer[--parser.data.offset] = ch;
1841 parser.data.buffer[0] = ch;
1851 for (ch = getch();; ch = getch()) {
1861 case ' ': case '\f': case '\r': case '\t':
1874 for (ch = getch();; ch = getch()) {
1884 case ' ': case '\f': case '\n': case '\r': case '\t':
1886 /* handle as newline */
1903 for (ch = getch(); ch != '\n' && ch != EOF; ch = getch())
1907 for (; ch != '/';) {
1908 while (getch_noeof() != '*')
1910 while ((ch = getch_noeof()) == '*')
1925 for (ch = getch(); ch != '\n' && ch != EOF; ch = getch()) {
1928 if ((number(ch)) == tok_int)
1929 parser.line = parser.value.i - 1;
1933 if (parser.offset >= (int)sizeof(parser.name)) {
1934 strncpy(parser.name, parser.string, sizeof(parser.name));
1935 parser.name[sizeof(parser.name) - 1] = '\0';
1938 strcpy(parser.name, parser.string);
1949 get_int(skip_t skip)
1951 switch (primary(skip)) {
1955 parser.type = type_l;
1956 parser.value.i = (jit_word_t)parser.value.p;
1959 error("expecting integer");
1962 return (parser.value.i);
1966 get_uint(skip_t skip)
1968 switch (primary(skip)) {
1969 case tok_char: case tok_int:
1972 parser.type = type_l;
1973 parser.value.ui = (jit_uword_t)parser.value.p;
1976 error("expecting integer");
1979 return (parser.value.ui);
1983 get_float(skip_t skip)
1985 switch (primary(skip)) {
1988 parser.type = type_d;
1989 parser.value.d = parser.value.i;
1994 error("expecting float");
1997 return (parser.value.d);
2000 /* Workaround gcc not converting unordered values from double to
2001 * float (as done in other architectures) on s390 */
2003 make_float(double d)
2005 /* This is an workaround to a bug in Hercules s390 emulator,
2006 * and at least HP-UX ia64 not have these */
2007 #if defined(HAVE_ISNAN) && defined(HAVE_ISINF)
2008 if (isnan(d)) return ( 0.0f/0.0f);
2010 if (d > 0.0) return ( 1.0f/0.0f);
2011 else return (-1.0f/0.0f);
2018 get_pointer(skip_t skip)
2021 token_t token = primary(skip);
2025 label = get_label_by_name(parser.string);
2027 error("bad identifier %s", parser.string);
2028 switch (label->kind) {
2029 case label_kind_data:
2030 case label_kind_code:
2032 case label_kind_code_forward:
2033 /* as expression arguments */
2034 error("forward references not implemented");
2036 case label_kind_dynamic:
2039 parser.type = type_p;
2040 return (parser.value.p = label->value);
2042 parser.type = type_p;
2043 return (parser.value.p = (void *)parser.value.ui);
2045 return (parser.value.p);
2046 default: error("bad pointer");
2051 get_label(skip_t skip)
2060 case 'a' ... 'z': case 'A' ... 'Z': case '_':
2061 (void)identifier(ch);
2064 error("expecting label/immediate");
2066 if ((label = get_label_by_name(parser.string)) == NULL)
2067 label = new_label(label_kind_code_forward,
2068 parser.string, jit_forward());
2077 int check = 1, ch = getch();
2081 parser.regtype = type_l;
2082 switch (ch = getch()) {
2083 case '0': parser.regval = JIT_R0; break;
2084 case '1': parser.regval = JIT_R1; break;
2085 case '2': parser.regval = JIT_R2; break;
2087 num = get_int(skip_none);
2088 if (num < 0 || num >= JIT_R_NUM) goto fail;
2089 parser.regval = JIT_R(num);
2090 if (getch() != ')') goto fail;
2097 parser.regtype = type_l;
2098 switch (ch = getch()) {
2099 case '0': parser.regval = JIT_V0; break;
2100 case '1': parser.regval = JIT_V1; break;
2101 case '2': parser.regval = JIT_V2; break;
2104 num = get_int(skip_none);
2105 if (num < 0 || num >= JIT_V_NUM) goto fail;
2106 parser.regval = JIT_V(num);
2107 if (getch() != ')') goto fail;
2113 parser.regtype = type_d;
2114 switch (ch = getch()) {
2115 case '0': parser.regval = JIT_F0; break;
2116 case '1': parser.regval = JIT_F1; break;
2117 case '2': parser.regval = JIT_F2; break;
2118 case '3': parser.regval = JIT_F3; break;
2119 case '4': parser.regval = JIT_F4; break;
2120 case '5': parser.regval = JIT_F5; break;
2122 parser.regtype = type_l; /* oops */
2123 parser.regval = JIT_FP; break;
2125 num = get_int(skip_none);
2126 if (num < 0 || num >= JIT_F_NUM) goto fail;
2127 parser.regval = JIT_F(num);
2128 if (getch() != ')') goto fail;
2136 error("bad register");
2140 if ((ch >= 'a' && ch <= 'z') ||
2141 (ch >= 'A' && ch <= 'Z') ||
2142 (ch >= '0' && ch <= '9') ||
2148 return (tok_register);
2154 parser.string[0] = ch;
2155 for (parser.offset = 1;;) {
2156 switch ((ch = getch())) {
2157 case 'a' ... 'z': case 'A' ... 'Z': case '0' ... '9' : case '_':
2158 if (parser.offset + 1 >= MAX_IDENTIFIER) {
2159 parser.string[parser.offset] = '\0';
2160 error("bad identifier %s", parser.string);
2162 parser.string[parser.offset++] = ch;
2165 parser.string[parser.offset] = '\0';
2167 return (tok_symbol);
2173 get_data(type_t type)
2182 switch (token = primary(skip_ws)) {
2183 case tok_char: case tok_int:
2184 check_data(sizeof(signed char));
2185 *(signed char *)(data + data_offset) = parser.value.i;
2186 data_offset += sizeof(char);
2189 check_data(parser.offset);
2190 memcpy(data + data_offset, parser.string,
2192 data_offset += parser.offset;
2195 case tok_semicollon:
2196 if (test == data) error("syntax error");
2198 default: error("bad initializer");
2202 check_data(sizeof(signed short));
2203 *(signed short *)(data + data_offset) = get_int(skip_ws);
2204 data_offset += sizeof(short);
2207 check_data(sizeof(signed int));
2208 *(signed int *)(data + data_offset) = get_int(skip_ws);
2209 data_offset += sizeof(int);
2212 check_data(sizeof(jit_word_t));
2213 *(jit_word_t *)(data + data_offset) = get_int(skip_ws);
2214 data_offset += sizeof(jit_word_t);
2217 check_data(sizeof(float));
2218 *(float *)(data + data_offset) = get_float(skip_ws);
2219 data_offset += sizeof(float);
2222 check_data(sizeof(double));
2223 *(double *)(data + data_offset) = get_float(skip_ws);
2224 data_offset += sizeof(double);
2227 /* FIXME **patch if realloc** */
2228 check_data(sizeof(void*));
2229 *(void **)(data + data_offset) = get_pointer(skip_ws);
2230 data_offset += sizeof(void*);
2236 if (ch == '\n' || ch == ';' || ch == EOF)
2246 size_t offset, length;
2248 switch (ch = getch_noeof()) {
2250 /* use .$(expression) for non side effects expression */
2253 case 'a' ... 'z': case 'A' ... 'Z': case '_':
2254 (void)identifier(ch);
2258 if (skipws() != '$')
2259 error("expecting symbol");
2260 /* allow spaces before an expression */
2264 if (parser.string[1] == '\0') {
2265 switch (parser.string[0]) {
2266 case 'c': get_data(type_c); break;
2267 case 's': get_data(type_s); break;
2268 case 'i': get_data(type_i); break;
2269 case 'l': get_data(type_l); break;
2270 case 'f': get_data(type_f); break;
2271 case 'd': get_data(type_d); break;
2272 case 'p': get_data(type_p); break;
2273 default: error("bad type .%c", parser.string[0]);
2276 else if (strcmp(parser.string, "data") == 0) {
2277 if (parser.parsing != PARSING_NONE)
2278 error(".data must be specified once and be the first section");
2279 parser.parsing = PARSING_DATA;
2280 data_length = get_int(skip_ws);
2281 data = (char *)xcalloc(1, data_length);
2283 else if (strcmp(parser.string, "code") == 0) {
2284 if (parser.parsing != PARSING_NONE &&
2285 parser.parsing != PARSING_DATA)
2286 error(".code must be specified once only");
2287 parser.parsing = PARSING_CODE;
2289 else if (strcmp(parser.string, "align") == 0) {
2290 length = get_int(skip_ws);
2291 if (parser.parsing != PARSING_DATA)
2292 error(".align must be in .data");
2293 if (length > 1 && length <= 4096 && !(length & (length - 1))) {
2294 offset = data_offset;
2295 offset += length - ((offset + length) % length);
2296 check_data(offset - data_offset);
2297 data_offset = offset;
2300 error("bad .align %ld (must be a power of 2, >= 2 && <= 4096)",
2301 (jit_word_t)length);
2303 else if (strcmp(parser.string, "size") == 0) {
2304 length = get_int(skip_ws);
2305 if (parser.parsing != PARSING_DATA)
2306 error(".size must be in .data");
2308 data_offset += length;
2310 else if (strcmp(parser.string, "disasm") == 0)
2313 error("unknown command .%s", parser.string);
2319 char buffer[1024], *endptr;
2320 int integer = 1, offset = 0, neg = 0, e = 0, d = 0, base = 10;
2322 for (;; ch = getch()) {
2329 if (offset && buffer[offset - 1] != 'e') {
2337 if (offset && buffer[offset - 1] != 'e') {
2350 if (offset == 0 && base == 10) {
2356 if (offset == 0 && base == 8) {
2374 if (offset == 0 && base == 8) {
2379 case 'a': case 'c': case 'd': case 'f':
2392 case '_': case 'g' ... 'w': case 'y': case 'z': case 'A' ... 'Z':
2394 buffer[offset++] = '\0';
2395 error("bad constant %s", buffer);
2400 if (offset + 1 >= (int)sizeof(buffer))
2402 buffer[offset++] = ch;
2405 /* check for literal 0 */
2406 if (offset == 0 && base == 8) buffer[offset++] = '0';
2407 buffer[offset] = '\0';
2410 # define STRTOUL strtoull
2412 # define STRTOUL strtoul
2414 parser.value.ui = STRTOUL(buffer, &endptr, base);
2415 parser.type = type_l;
2417 parser.value.i = -parser.value.i;
2420 parser.type = type_d;
2421 parser.value.d = strtod(buffer, &endptr);
2423 parser.value.d = -parser.value.d;
2428 return (integer ? tok_int : tok_float);
2435 case 'a': ch = '\a'; break;
2436 case 'b': ch = '\b'; break;
2437 case 'f': ch = '\f'; break;
2438 case 'n': ch = '\n'; break;
2439 case 'r': ch = '\r'; break;
2440 case 't': ch = '\t'; break;
2441 case 'v': ch = '\v'; break;
2453 for (parser.offset = 0;;) {
2454 switch (ch = getch_noeof()) {
2456 if (esc) goto append;
2461 parser.string[parser.offset++] = '\0';
2462 parser.value.p = parser.string;
2463 parser.type = type_p;
2464 return (tok_string);
2473 if (parser.offset + 1 >= parser.length) {
2474 parser.length += 4096;
2475 parser.string = (char *)xrealloc(parser.string,
2478 parser.string[parser.offset++] = ch;
2489 if ((ch = getch_noeof()) == '\\') {
2493 if (getch_noeof() != '\'')
2494 error("bad single byte char");
2497 parser.type = type_l;
2498 parser.value.i = ch & 0xff;
2509 (void)identifier('@');
2510 if ((label = get_label_by_name(parser.string)) == NULL) {
2511 #if __CYGWIN__ ||_WIN32
2512 /* FIXME kludge to pass varargs test case, otherwise,
2513 * will not print/scan float values */
2514 if (strcmp(parser.string + 1, "sprintf") == 0)
2516 else if (strcmp(parser.string + 1, "sscanf") == 0)
2521 value = dlsym(DL_HANDLE, parser.string + 1);
2522 if ((string = dlerror()))
2523 error("%s", string);
2525 label = new_label(label_kind_dynamic, parser.string, value);
2527 parser.type = type_p;
2528 parser.value.p = label->value;
2530 return (tok_pointer);
2534 expression_prim(void)
2541 if (parser.putback) {
2542 parser.expr = parser.putback;
2543 parser.putback = (expr_t)0;
2546 switch (ch = skipws()) {
2548 if ((ch = getch_noeof()) == '=') parser.expr = expr_ne;
2550 ungetch(ch); parser.expr = expr_not;
2553 case '~': parser.expr = expr_com;
2556 if ((ch = getch_noeof()) == '=') parser.expr = expr_mulset;
2558 ungetch(ch); parser.expr = expr_mul;
2562 if ((ch = getch_noeof()) == '=') parser.expr = expr_divset;
2564 ungetch(ch); parser.expr = expr_div;
2568 if ((ch = getch_noeof()) == '=') parser.expr = expr_remset;
2570 ungetch(ch); parser.expr = expr_rem;
2574 switch (ch = getch_noeof()) {
2575 case '+': parser.expr = expr_inc;
2577 case '=': parser.expr = expr_addset;
2579 default: ungetch(ch); parser.expr = expr_add;
2584 switch (ch = getch_noeof()) {
2585 case '-': parser.expr = expr_dec;
2587 case '=': parser.expr = expr_subset;
2589 default: ungetch(ch); parser.expr = expr_sub;
2594 switch (ch = getch_noeof()) {
2595 case '=': parser.expr = expr_le;
2597 case '<': ch = getch_noeof();
2598 if (ch == '=') parser.expr = expr_lshset;
2600 ungetch(ch); parser.expr = expr_lsh;
2603 default: ungetch(ch); parser.expr = expr_lt;
2608 switch (ch = getch_noeof()) {
2609 case '=': parser.expr = expr_ge;
2611 case '>': ch = getch_noeof();
2612 if (ch == '=') parser.expr = expr_rshset;
2614 ungetch(ch); parser.expr = expr_rsh;
2617 default: ungetch(ch); parser.expr = expr_gt;
2622 switch (ch = getch_noeof()) {
2623 case '=': parser.expr = expr_andset;
2625 case '&': parser.expr = expr_andand;
2627 default: ungetch(ch); parser.expr = expr_and;
2632 switch (ch = getch_noeof()) {
2633 case '=': parser.expr = expr_orset;
2635 case '|': parser.expr = expr_oror;
2637 default: ungetch(ch); parser.expr = expr_or;
2642 if ((ch = getch_noeof()) == '=') parser.expr = expr_xorset;
2644 ungetch(ch); parser.expr = expr_xor;
2648 if ((ch = getch_noeof()) == '=') parser.expr = expr_eq;
2650 ungetch(ch); parser.expr = expr_set;
2653 case '(': parser.expr = expr_lparen;
2655 case ')': parser.expr = expr_rparen;
2659 parser.expr = token == tok_int ? expr_int : expr_float;
2663 parser.expr = expr_pointer;
2667 /* no support for nested expressions */
2668 if (parser.string[0] == '\0')
2669 error("syntax error");
2670 parser.expr = expr_symbol;
2671 if ((symbol = get_symbol_by_name(parser.string)) != NULL) {
2672 parser.type = symbol->type;
2673 parser.value = symbol->value;
2676 /* only create symbol on assignment */
2677 parser.type = type_none;
2679 case 'a' ... 'z': case 'A' ... 'Z': case '_':
2681 if ((label = get_label_by_name(parser.string))) {
2682 if (label->kind == label_kind_code_forward)
2683 error("forward value for %s not supported",
2685 parser.expr = expr_pointer;
2686 parser.type = type_p;
2687 parser.value.p = label->value;
2690 error("invalid identifier %s", parser.string);
2694 parser.expr = expr_int;
2697 /* not smart enough to put it in data and/or relocate it, etc */
2698 error("must declare strings as data");
2700 error("syntax error");
2705 expression_inc(int pre)
2711 if (parser.expr != expr_symbol)
2712 error("syntax error");
2714 if ((symbol = get_symbol_by_name(parser.string)) == NULL) {
2715 if (!parser.short_circuit)
2716 error("undefined symbol %s", symbol->name);
2718 if (!parser.short_circuit) {
2719 parser.type = symbol->type;
2721 parser.value = symbol->value;
2722 switch (symbol->type) {
2727 /* should really be an error */
2728 symbol->value.d += 1.0;
2735 parser.value = symbol->value;
2741 expression_dec(int pre)
2747 if (parser.expr != expr_symbol)
2748 error("syntax error");
2750 if ((symbol = get_symbol_by_name(parser.string)) == NULL) {
2751 if (!parser.short_circuit)
2752 error("undefined symbol %s", symbol->name);
2754 if (!parser.short_circuit) {
2755 parser.type = symbol->type;
2757 parser.value = symbol->value;
2758 switch (symbol->type) {
2763 /* should really be an error */
2764 symbol->value.d -= 1.0;
2771 parser.value = symbol->value;
2777 expression_unary(void)
2783 switch (parser.expr) {
2786 switch (parser.type) {
2791 error("syntax error");
2796 switch (parser.type) {
2798 parser.value.i = -parser.value.i;
2801 parser.value.d = -parser.value.d;
2804 error("syntax error");
2815 switch (parser.type) {
2817 parser.value.i = !parser.value.i;
2820 parser.value.i = parser.value.d != 0;
2823 parser.value.i = parser.value.p != NULL;
2826 error("syntax error");
2828 parser.type = type_l;
2832 if (parser.type != type_l)
2833 error("syntax error");
2834 parser.value.i = ~parser.value.i;
2838 if (parser.expr != expr_rparen)
2839 error("syntax error");
2843 strcpy(buffer, parser.string);
2845 switch (parser.expr) {
2847 if ((symbol = get_symbol_by_name(buffer)) == NULL) {
2848 if (!parser.short_circuit)
2849 symbol = new_symbol(buffer);
2853 if (!parser.short_circuit) {
2855 error("syntax error");
2856 symbol->type = parser.type;
2857 symbol->value = parser.value;
2860 case expr_mulset: parser.putback = expr_mul;
2862 case expr_divset: parser.putback = expr_div;
2864 case expr_remset: parser.putback = expr_rem;
2866 case expr_addset: parser.putback = expr_add;
2868 case expr_subset: parser.putback = expr_sub;
2870 case expr_lshset: parser.putback = expr_lsh;
2872 case expr_rshset: parser.putback = expr_rsh;
2874 case expr_andset: parser.putback = expr_and;
2876 case expr_orset: parser.putback = expr_or;
2878 case expr_xorset: parser.putback = expr_xor;
2880 if ((symbol = get_symbol_by_name(buffer)) == NULL) {
2881 if (!parser.short_circuit)
2882 error("undefined symbol %s", buffer);
2883 parser.type = type_l;
2886 switch (parser.putback) {
2887 case expr_mul: case expr_div: case expr_rem:
2890 case expr_add: case expr_sub:
2893 case expr_lsh: case expr_rsh:
2896 case expr_and: case expr_or: case expr_xor:
2916 /* make next token available */
2924 expression_mul(void)
2930 switch (parser.type) {
2931 case type_l: case type_d: case type_p: break;
2935 switch (parser.expr) {
2937 type = parser.type, value = parser.value;
2939 switch (parser.type) {
2942 value.i *= parser.value.i;
2944 value.d *= parser.value.i;
2947 if (type == type_l) {
2951 value.d *= parser.value.d;
2954 error("invalid operand");
2956 parser.type = type, parser.value = value;
2959 type = parser.type, value = parser.value;
2961 switch (parser.type) {
2963 if (type == type_l) {
2964 if (parser.value.i == 0)
2965 error("divide by zero");
2966 value.i /= parser.value.i;
2969 value.d /= parser.value.i;
2972 if (type == type_l) {
2976 value.d /= parser.value.d;
2979 error("invalid operand");
2981 parser.type = type, parser.value = value;
2984 type = parser.type, value = parser.value;
2986 switch (parser.type) {
2988 if (type == type_l) {
2989 if (parser.value.i == 0)
2990 error("divide by zero");
2991 value.i %= parser.value.i;
2994 error("invalid operand");
2997 error("invalid operand");
2999 parser.type = type, parser.value = value;
3008 expression_add(void)
3014 switch (parser.type) {
3015 case type_l: case type_d: case type_p: break;
3019 switch (parser.expr) {
3021 type = parser.type, value = parser.value;
3023 switch (parser.type) {
3027 value.i += parser.value.i;
3030 value.d += parser.value.i;
3033 value.cp += parser.value.i;
3046 error("invalid operand");
3048 value.d += parser.value.d;
3054 value.cp = value.i + parser.value.cp;
3057 error("invalid operand");
3061 error("invalid operand");
3063 parser.type = type, parser.value = value;
3066 type = parser.type, value = parser.value;
3068 switch (parser.type) {
3072 value.i -= parser.value.i;
3075 value.d -= parser.value.i;
3078 value.cp -= parser.value.i;
3091 error("invalid operand");
3093 value.d -= parser.value.d;
3099 value.i = value.cp - parser.value.cp;
3102 error("invalid operand");
3106 error("invalid operand");
3108 parser.type = type, parser.value = value;
3117 expression_shift(void)
3122 switch (parser.type) {
3123 case type_l: case type_d: case type_p: break;
3127 switch (parser.expr) {
3129 value = parser.value.i;
3130 if (parser.type != type_l)
3131 error("invalid operand");
3133 if (parser.type != type_l)
3134 error("invalid operand");
3135 value <<= parser.value.i;
3136 parser.value.i = value;
3139 value = parser.value.i;
3140 if (parser.type != type_l)
3141 error("invalid operand");
3143 if (parser.type != type_l)
3144 error("invalid operand");
3145 value >>= parser.value.i;
3146 parser.value.i = value;
3155 expression_bit(void)
3160 switch (parser.type) {
3161 case type_l: case type_d: case type_p: break;
3165 switch (parser.expr) {
3167 if (parser.type != type_l)
3168 error("invalid operand");
3171 if (parser.type != type_l)
3172 error("invalid operand");
3173 i &= parser.value.i;
3177 if (parser.type != type_l)
3178 error("invalid operand");
3181 if (parser.type != type_l)
3182 error("invalid operand");
3183 i |= parser.value.i;
3187 if (parser.type != type_l)
3188 error("invalid operand");
3191 if (parser.type != type_l)
3192 error("invalid operand");
3193 i ^= parser.value.i;
3203 expression_rel(void)
3209 switch (parser.type) {
3210 case type_l: case type_d: case type_p: break;
3214 switch (parser.expr) {
3216 type = parser.type, value = parser.value;
3218 switch (parser.type) {
3222 value.i = value.i < parser.value.i;
3225 value.i = value.d < parser.value.i;
3228 value.i = (jit_word_t)value.p < parser.value.i;
3235 value.i = value.i < parser.value.d;
3238 value.i = value.d < parser.value.d;
3241 error("invalid operand");
3247 value.i = value.i < (jit_word_t)parser.value.p;
3250 error("invalid operand");
3252 value.i = (jit_word_t)value.p < (jit_word_t)parser.value.p;
3257 error("invalid operand");
3259 parser.type = type_l, parser.value = value;
3262 type = parser.type, value = parser.value;
3264 switch (parser.type) {
3268 value.i = value.i <= parser.value.i;
3271 value.i = value.d <= parser.value.i;
3274 value.i = (jit_word_t)value.p <= parser.value.i;
3281 value.i = value.i <= parser.value.d;
3284 value.i = value.d <= parser.value.d;
3287 value.i = (jit_word_t)value.p <= parser.value.d;
3294 value.i = value.i <= (jit_word_t)parser.value.p;
3297 error("invalid operand");
3299 value.i = (jit_word_t)value.p <= (jit_word_t)parser.value.p;
3304 error("invalid operand");
3306 parser.type = type_l, parser.value = value;
3309 type = parser.type, value = parser.value;
3311 switch (parser.type) {
3315 value.i = value.i == parser.value.i;
3318 value.i = value.d == parser.value.i;
3321 value.i = (jit_word_t)value.p == parser.value.i;
3328 value.i = value.i == parser.value.d;
3331 value.i = value.d == parser.value.d;
3334 error("invalid operand");
3340 value.i = value.i == (jit_word_t)parser.value.p;
3343 error("invalid operand");
3345 value.i = value.p == parser.value.p;
3350 error("invalid operand");
3352 parser.type = type_l, parser.value = value;
3355 type = parser.type, value = parser.value;
3357 switch (parser.type) {
3361 value.i = value.i >= parser.value.i;
3364 value.i = value.d >= parser.value.i;
3367 value.i = (jit_word_t)value.p >= parser.value.i;
3374 value.i = value.i >= parser.value.d;
3377 value.i = value.d >= parser.value.d;
3380 error("invalid operand");
3386 value.i = value.i >= (jit_word_t)parser.value.p;
3389 error("invalid operand");
3391 value.i = (jit_word_t)value.p >= (jit_word_t)parser.value.p;
3396 error("invalid operand");
3398 parser.type = type_l, parser.value = value;
3401 type = parser.type, value = parser.value;
3403 switch (parser.type) {
3407 value.i = value.i > parser.value.i;
3410 value.i = value.d > parser.value.i;
3413 value.i = (jit_word_t)value.p > parser.value.i;
3420 value.i = value.i > parser.value.d;
3423 value.i = value.d > parser.value.d;
3426 error("invalid operand");
3432 value.i = value.i > (jit_word_t)parser.value.p;
3435 error("invalid operand");
3437 value.i = (jit_word_t)value.p > (jit_word_t)parser.value.p;
3442 error("invalid operand");
3444 parser.type = type_l, parser.value = value;
3447 type = parser.type, value = parser.value;
3449 switch (parser.type) {
3453 value.i = value.i != parser.value.i;
3456 value.i = value.d != parser.value.i;
3459 value.i = (jit_word_t)value.p != parser.value.i;
3466 value.i = value.i != parser.value.d;
3469 value.i = value.d != parser.value.d;
3472 error("invalid operand");
3478 value.i = value.i != (jit_word_t)parser.value.p;
3481 error("invalid operand");
3483 value.i = value.p != parser.value.p;
3488 error("invalid operand");
3490 parser.type = type_l, parser.value = value;
3499 expression_cond(void)
3506 switch (parser.type) {
3507 case type_l: case type_d: case type_p: break;
3511 switch (parser.expr) {
3513 type = parser.type, value = parser.value;
3516 short_circuit = value.i == 0;
3519 short_circuit = value.d == 0.0;
3522 short_circuit = value.p == NULL;
3525 parser.short_circuit += short_circuit;
3527 parser.short_circuit -= short_circuit;
3528 switch (parser.type) {
3532 value.i = value.i && parser.value.i;
3535 value.i = value.d && parser.value.i;
3538 value.i = value.p && parser.value.i;
3545 value.i = value.i && parser.value.d;
3548 value.i = value.d && parser.value.d;
3551 value.i = value.p && parser.value.d;
3558 value.i = value.i && parser.value.p;
3561 value.i = value.d && parser.value.p;
3564 value.i = value.p && parser.value.p;
3569 error("invalid operand");
3571 parser.type = type_l, parser.value.i = value.i;
3574 type = parser.type, value = parser.value;
3577 short_circuit = value.i != 0;
3580 short_circuit = value.d != 0.0;
3583 short_circuit = value.p != NULL;
3586 parser.short_circuit += short_circuit;
3588 parser.short_circuit -= short_circuit;
3589 switch (parser.type) {
3593 value.i = value.i || parser.value.i;
3596 value.i = value.d || parser.value.i;
3599 value.i = value.p || parser.value.i;
3606 value.i = value.i || parser.value.d;
3609 value.i = value.d || parser.value.d;
3612 value.i = value.p || parser.value.d;
3619 value.i = value.i || parser.value.p;
3622 value.i = value.d || parser.value.p;
3625 value.i = value.p || parser.value.p;
3630 error("invalid operand");
3632 parser.type = type_l, parser.value.i = value.i;
3645 (void)identifier('$');
3646 if (parser.string[1] == '\0') {
3647 if (getch_noeof() != '(')
3648 error("bad symbol or expression");
3649 parser.type = type_none;
3651 if (parser.expr != expr_rparen)
3652 error("bad expression");
3653 switch (parser.type) {
3659 return (tok_pointer);
3661 error("bad expression");
3664 else if ((symbol = get_symbol_by_name(parser.string))) {
3665 switch (parser.type = symbol->type) {
3667 parser.value.i = symbol->value.i;
3670 parser.value.d = symbol->value.d;
3673 parser.value.p = symbol->value.p;
3674 return (tok_pointer);
3678 error("undefined symbol %s", parser.string);
3682 primary(skip_t skip)
3687 case skip_none: ch = getch(); break;
3688 case skip_ws: ch = skipws(); break;
3689 case skip_nl: ch = skipnl(); break;
3695 case 'a' ... 'z': case 'A' ... 'Z': case '_':
3696 return (identifier(ch));
3697 case '0' ... '9': case '+': case '-':
3698 return (number(ch));
3704 return (character());
3708 return (expression());
3712 return (tok_newline);
3714 return (tok_semicollon);
3716 error("syntax error");
3730 switch (token = primary(skip_nl)) {
3734 if ((label = get_label_by_name(parser.string))) {
3735 if (label->kind == label_kind_code_forward) {
3736 label->kind = label_kind_code;
3737 jit_link(label->value);
3738 jit_note(parser.name, parser.line);
3741 error("label %s: redefined", parser.string);
3744 if (parser.parsing == PARSING_DATA) {
3745 value = data + data_offset;
3746 label = new_label(label_kind_data,
3747 parser.string, value);
3749 else if (parser.parsing == PARSING_CODE) {
3750 value = jit_label();
3751 jit_note(parser.name, parser.line);
3752 label = new_label(label_kind_code,
3753 parser.string, value);
3756 error("label not in .code or .data");
3762 (instr_t *)get_hash(instrs, parser.string)) == NULL)
3763 error("unhandled symbol %s", parser.string);
3764 if (parser.parsing != PARSING_CODE)
3765 error(".code must be specified before instructions");
3766 (*instr->function)();
3774 error("syntax error");
3780 execute(int argc, char *argv[])
3784 function_t function;
3785 patch_t *patch, *next;
3787 for (patch = patches; patch; patch = next) {
3789 label = patch->label;
3790 if (label->kind == label_kind_code_forward)
3791 error("undefined label %s", label->name);
3792 switch (patch->kind) {
3793 case patch_kind_jmp:
3794 case patch_kind_mov:
3795 case patch_kind_call:
3796 jit_patch_at(patch->value, label->value);
3805 if (flag_data == 0) {
3807 jit_set_data(NULL, 0, JIT_DISABLE_DATA | JIT_DISABLE_NOTE);
3810 function = jit_emit();
3811 if (flag_verbose > 1 || flag_disasm) {
3813 fprintf(stderr, " - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n");
3815 if (flag_verbose > 0 || flag_disasm) {
3817 fprintf(stderr, " - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n");
3824 result = (*function)(argc, argv);
3825 jit_destroy_state();
3831 xmalloc(size_t size)
3833 void *pointer = malloc(size);
3835 if (pointer == NULL)
3836 error("out of memory");
3842 xrealloc(void *pointer, size_t size)
3844 pointer = realloc(pointer, size);
3846 if (pointer == NULL)
3847 error("out of memory");
3853 xcalloc(size_t nmemb, size_t size)
3855 void *pointer = calloc(nmemb, size);
3857 if (pointer == NULL)
3858 error("out of memory");
3864 new_label(label_kind_t kind, char *name, void *value)
3868 label = (label_t *)xmalloc(sizeof(label_t));
3870 label->name = strdup(name);
3871 label->value = value;
3872 put_hash(labels, (entry_t *)label);
3878 new_patch(patch_kind_t kind, label_t *label, void *value)
3880 patch_t *patch = (patch_t *)xmalloc(sizeof(patch_t));
3882 patch->label = label;
3883 patch->value = value;
3884 patch->next = patches;
3891 bcmp_symbols(const void *left, const void *right)
3893 return (strcmp((char *)left, (*(symbol_t **)right)->name));
3897 qcmp_symbols(const void *left, const void *right)
3899 return (strcmp((*(symbol_t **)left)->name, (*(symbol_t **)right)->name));
3903 new_symbol(char *name)
3907 if ((symbol_offset & 15) == 0) {
3908 if ((symbol_length += 16) == 16)
3909 symbols = (symbol_t **)xmalloc(sizeof(symbol_t *) *
3912 symbols = (symbol_t **)xrealloc(symbols, sizeof(symbol_t *) *
3915 symbol = (symbol_t *)xmalloc(sizeof(symbol_t));
3916 symbol->name = strdup(name);
3917 symbols[symbol_offset++] = symbol;
3918 qsort(symbols, symbol_offset, sizeof(symbol_t *), qcmp_symbols);
3924 get_symbol_by_name(char *name)
3926 symbol_t **symbol_pointer;
3928 if (symbols == NULL)
3930 symbol_pointer = (symbol_t **)bsearch(name, symbols, symbol_offset,
3931 sizeof(symbol_t *), bcmp_symbols);
3933 return (symbol_pointer ? *symbol_pointer : NULL);
3941 hash = (hash_t *)xmalloc(sizeof(hash_t));
3943 hash->entries = (entry_t **)xcalloc(hash->size = 32, sizeof(void *));
3949 hash_string(char *name)
3954 for (key = 0, ptr = name; *ptr; ptr++)
3955 key = (key << (key & 1)) ^ *ptr;
3961 put_hash(hash_t *hash, entry_t *entry)
3963 entry_t *prev, *ptr;
3964 int key = hash_string(entry->name) & (hash->size - 1);
3966 for (prev = ptr = hash->entries[key]; ptr; prev = ptr, ptr = ptr->next) {
3967 if (strcmp(entry->name, ptr->name) == 0)
3968 error("duplicated entry %s", entry->name);
3971 hash->entries[key] = entry;
3976 if (hash->count > hash->size * 0.75)
3981 get_hash(hash_t *hash, char *name)
3984 int key = hash_string(name) & (hash->size - 1);
3986 for (entry = hash->entries[key]; entry; entry = entry->next) {
3987 if (strcmp(entry->name, name) == 0)
3994 rehash(hash_t *hash)
3997 entry_t *entry, *next, **entries;
3999 entries = (entry_t **)xcalloc(size = hash->size * 2, sizeof(void *));
4000 for (i = 0; i < hash->size; i++) {
4001 for (entry = hash->entries[i]; entry; entry = next) {
4003 key = hash_string(entry->name) & (size - 1);
4004 entry->next = entries[key];
4005 entries[key] = entry;
4008 free(hash->entries);
4009 hash->entries = entries;
4016 #if HAVE_GETOPT_LONG_ONLY
4018 Usage: %s [jit assembler options] file [jit program options]\n\
4019 Jit assembler options:\n\
4020 -help Display this information\n\
4021 -v[0-3] Verbose output level\n\
4022 -d Do not use a data buffer\n\
4023 -D<macro>[=<val>] Preprocessor options\n"
4024 # if defined(__i386__) && __WORDSIZE == 32
4025 " -mx87=1 Force using x87 when sse2 available\n"
4027 # if defined(__i386__) || defined(__x86_64__)
4028 " -msse4_1=0 Do not use sse4_1 instructions when available\n"
4030 # if defined(__arm__)
4031 " -mcpu=<val> Force cpu version (4, 5, 6 or 7)\n\
4032 -mthumb[=0|1] Enable or disable thumb\n\
4033 -mvfp=<val> Set vpf version (0 to disable)\n\
4034 -mneon[=0|1] Enable or disable neon\n"
4039 Usage: %s [jit assembler options] file [jit program options]\n\
4040 Jit assembler options:\n\
4041 -h Display this information\n\
4042 -v Verbose output level\n\
4043 -D<macro>[=<val>] Preprocessor options\n", progname);
4050 main(int argc, char *argv[])
4052 #if HAVE_GETOPT_LONG_ONLY
4053 static const char *short_options = "dv::";
4054 static struct option long_options[] = {
4055 { "help", 0, 0, 'h' },
4056 { "data", 2, 0, 'd' },
4057 # if defined(__i386__) && __WORDSIZE == 32
4058 { "mx87", 2, 0, '7' },
4060 # if defined(__i386__) || defined(__x86_64__)
4061 { "msse4_1", 2, 0, '4' },
4063 # if defined(__arm__)
4064 { "mcpu", 2, 0, 'c' },
4065 { "mthumb", 2, 0, 't' },
4066 { "mvfp", 2, 0, 'f' },
4067 { "mneon", 2, 0, 'n' },
4072 #endif /* HAVE_GETOPT_LONG_ONLY */
4079 #if defined(__CYGWIN__)
4080 /* Cause a compile warning about redefinition without dllimport
4081 * attribute, *but* cause correct linkage if liblightning.a is
4082 * linked to binutils (that happens to have an internal
4083 * getopt* implementation and an apparently conflicting
4084 * optind global variable) */
4094 DL_HANDLE = dlopen(NULL, RTLD_LAZY);
4098 #if HAVE_GETOPT_LONG_ONLY
4100 if ((opt_short = getopt_long_only(argc, argv, short_options,
4101 long_options, &opt_index)) < 0)
4103 switch (opt_short) {
4110 flag_verbose = strtol(optarg, &endptr, 10);
4111 if (*endptr || flag_verbose < 0)
4120 #if defined(__i386__) && __WORDSIZE == 32
4123 if (strcmp(optarg, "") == 0 || strcmp(optarg, "1") == 0)
4125 else if (strcmp(optarg, "0"))
4132 #if defined(__i386__) || defined(__x86_64__)
4135 if (strcmp(optarg, "0") == 0)
4137 else if (strcmp(optarg, "1"))
4142 #if defined(__arm__)
4145 offset = strtol(optarg, &endptr, 10);
4146 if (*endptr || offset < 0)
4148 if (offset < jit_cpu.version)
4149 jit_cpu.version = offset;
4154 if (strcmp(optarg, "0") == 0)
4156 else if (strcmp(optarg, "1") && strcmp(optarg, "2"))
4161 # if !defined(__ARM_PCS_VFP)
4162 /* Do not allow overrinding hard float abi */
4164 offset = strtol(optarg, &endptr, 10);
4165 if (*endptr || offset < 0)
4167 if (offset < jit_cpu.vfp)
4168 jit_cpu.vfp = offset;
4174 if (strcmp(optarg, "0") == 0)
4176 else if (strcmp(optarg, "1"))
4184 while ((opt_short = getopt(argc, argv, "hvd")) >= 0) {
4185 if (opt_short == 'v')
4187 else if (opt_short == 'd')
4197 if (opt_index < argc && argv[opt_index][0] == '-')
4200 if (opt_index < 0 || opt_index >= argc)
4202 if (strcmp(argv[opt_index], "-") == 0)
4203 strcpy(parser.name, "<stdin>");
4205 if ((endptr = strrchr(argv[opt_index], '/')) == NULL)
4206 endptr = argv[opt_index];
4209 strncpy(parser.name, endptr, sizeof(parser.name));
4210 parser.name[sizeof(parser.name) - 1] = '\0';
4217 opt_short = snprintf(cmdline, sizeof(cmdline), cc " -E -x c %s", argv[opt_index]);
4218 for (++opt_index; opt_index < argc; opt_index++) {
4219 if (argv[opt_index][0] == '-')
4220 opt_short += snprintf(cmdline + opt_short,
4221 sizeof(cmdline) - opt_short,
4222 " %s", argv[opt_index]);
4228 opt_short += snprintf(cmdline + opt_short,
4229 sizeof(cmdline) - opt_short,
4230 " -D__WORDSIZE=%d", __WORDSIZE);
4231 opt_short += snprintf(cmdline + opt_short,
4232 sizeof(cmdline) - opt_short,
4233 " -D__LITTLE_ENDIAN=%d", __LITTLE_ENDIAN);
4234 opt_short += snprintf(cmdline + opt_short,
4235 sizeof(cmdline) - opt_short,
4236 " -D__BIG_ENDIAN=%d", __BIG_ENDIAN);
4237 opt_short += snprintf(cmdline + opt_short,
4238 sizeof(cmdline) - opt_short,
4239 " -D__BYTE_ORDER=%d", __BYTE_ORDER);
4240 #if defined(__i386__)
4241 opt_short += snprintf(cmdline + opt_short,
4242 sizeof(cmdline) - opt_short,
4245 #if defined(__x86_64__)
4246 opt_short += snprintf(cmdline + opt_short,
4247 sizeof(cmdline) - opt_short,
4250 #if defined(__mips__)
4251 opt_short += snprintf(cmdline + opt_short,
4252 sizeof(cmdline) - opt_short,
4255 #if defined(__arm__)
4256 opt_short += snprintf(cmdline + opt_short,
4257 sizeof(cmdline) - opt_short,
4260 #if defined(__powerpc__)
4261 opt_short += snprintf(cmdline + opt_short,
4262 sizeof(cmdline) - opt_short,
4265 #if defined(__sparc__)
4266 opt_short += snprintf(cmdline + opt_short,
4267 sizeof(cmdline) - opt_short,
4270 #if defined(__ia64__)
4271 opt_short += snprintf(cmdline + opt_short,
4272 sizeof(cmdline) - opt_short,
4275 #if defined(__hppa__)
4276 opt_short += snprintf(cmdline + opt_short,
4277 sizeof(cmdline) - opt_short,
4281 opt_short += snprintf(cmdline + opt_short,
4282 sizeof(cmdline) - opt_short,
4285 #if defined(__sgi__)
4286 opt_short += snprintf(cmdline + opt_short,
4287 sizeof(cmdline) - opt_short,
4290 #if defined(__aarch64__)
4291 opt_short += snprintf(cmdline + opt_short,
4292 sizeof(cmdline) - opt_short,
4293 " -D__aarch64__=1");
4295 #if defined(__s390__) || defined(__s390x__)
4296 opt_short += snprintf(cmdline + opt_short,
4297 sizeof(cmdline) - opt_short,
4300 #if defined(__alpha__)
4301 opt_short += snprintf(cmdline + opt_short,
4302 sizeof(cmdline) - opt_short,
4305 if ((parser.fp = popen(cmdline, "r")) == NULL)
4306 error("cannot execute %s", cmdline);
4309 parser.string = (char *)xmalloc(parser.length = 4096);
4311 #if defined(__linux__) && (defined(__i386__) || defined(__x86_64__))
4312 /* double precision 0x200
4313 * round nearest 0x000
4314 * invalid operation mask 0x001
4315 * denormalized operand mask 0x002
4316 * zero divide mask 0x004
4317 * precision (inexact) mask 0x020
4320 fpu_control_t fpu_control = 0x027f;
4321 _FPU_SETCW(fpu_control);
4325 _jit = jit_new_state();
4327 instrs = new_hash();
4329 offset < (int)(sizeof(instr_vector) / sizeof(instr_vector[0]));
4331 put_hash(instrs, (entry_t *)(instr_vector + offset));
4333 labels = new_hash();
4339 for (opt_short = 0; opt_index < argc; opt_short++, opt_index++)
4340 argv[opt_short] = argv[opt_index];
4341 argv[opt_short] = NULL;
4343 execute(argc, argv);