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>
34 #if defined(__linux__) && (defined(__i386__) || defined(__x86_64__))
35 # include <fpu_control.h>
38 /* The label_t identifier clashes with a system definitions */
39 #if defined(_AIX) || defined(__sun__) || defined(__osf__)
40 # define label_t l_label_t
44 # define DL_HANDLE RTLD_NEXT
46 static void *DL_HANDLE;
47 #elif defined(__osf__)
48 # define DL_HANDLE NULL
50 # define DL_HANDLE RTLD_DEFAULT
54 # define noreturn __attribute__ ((noreturn))
55 # define printf_format(f, v) __attribute__ ((format (printf, f, v)))
56 # define maybe_unused __attribute__ ((unused))
58 # define noreturn /**/
59 # define printf_format(f, v) /**/
60 # define maybe_unused /**/
63 #define check_data(length) \
65 if (data_offset + length > data_length) \
66 error(".data too small (%ld < %ld)", \
67 data_length, data_offset + length); \
70 #define get_label_by_name(name) ((label_t *)get_hash(labels, name))
72 #define PARSING_NONE 0
73 #define PARSING_DATA 1
74 #define PARSING_CODE 2
75 #define MAX_IDENTIFIER 256
80 typedef struct instr instr_t;
81 typedef union value value_t;
82 typedef struct parser parser_t;
83 typedef struct label label_t;
84 typedef struct patch patch_t;
85 typedef struct symbol symbol_t;
86 typedef struct hash hash_t;
87 typedef struct entry entry_t;
88 typedef int (*function_t)(int argc, char *argv[]);
121 #define compose(a, b) (((a) << 8) | b)
123 expr_inc = compose('+', '+'),
124 expr_dec = compose('-', '-'),
132 expr_lsh = compose('<', '<'),
133 expr_rsh = compose('>', '>'),
138 expr_mulset = compose('*', '='),
139 expr_divset = compose('/', '='),
140 expr_remset = compose('%', '='),
141 expr_addset = compose('+', '='),
142 expr_subset = compose('-', '='),
143 expr_lshset = compose(expr_lsh, '='),
144 expr_rshset = compose(expr_rsh, '='),
145 expr_andset = compose('&', '='),
146 expr_orset = compose('|', '='),
147 expr_xorset = compose('^', '='),
149 expr_le = compose('<', '='),
150 expr_eq = compose('=', '='),
151 expr_ne = compose('!', '='),
153 expr_ge = compose('>', '='),
154 expr_andand = compose('&', '&'),
155 expr_oror = compose('|', '|'),
168 void (*function)(void);
193 /* variable length string buffer */
204 unsigned char buffer[4096];
213 label_kind_code_forward,
250 /* minor support for expressions */
261 static jit_gpr_t get_ireg(void);
262 static jit_fpr_t get_freg(void);
263 static symbol_t *get_symbol(void);
264 static void jmp_forward(void *value, label_t *label);
265 static void mov_forward(void *value, label_t *label);
266 static void call_forward(void *value, label_t *label);
267 static void make_arg(void *value);
268 static jit_pointer_t get_arg(void);
269 static jit_word_t get_imm(void);
270 static void live(void);
271 static void align(void); static void name(void);
272 static void prolog(void);
273 static void frame(void); static void tramp(void);
274 static void ellipsis(void);
275 static void allocai(void); static void allocar(void);
276 static void arg(void);
277 static void getarg_c(void); static void getarg_uc(void);
278 static void getarg_s(void); static void getarg_us(void);
279 static void getarg_i(void);
281 static void getarg_ui(void); static void getarg_l(void);
283 static void getarg(void);
284 static void putargr(void); static void putargi(void);
285 static void addr(void); static void addi(void);
286 static void addxr(void); static void addxi(void);
287 static void addcr(void); static void addci(void);
288 static void subr(void); static void subi(void);
289 static void subxr(void); static void subxi(void);
290 static void subcr(void); static void subci(void);
291 static void rsbr(void); static void rsbi(void);
292 static void mulr(void); static void muli(void);
293 static void qmulr(void); static void qmuli(void);
294 static void qmulr_u(void); static void qmuli_u(void);
295 static void divr(void); static void divi(void);
296 static void divr_u(void); static void divi_u(void);
297 static void qdivr(void); static void qdivi(void);
298 static void qdivr_u(void); static void qdivi_u(void);
299 static void remr(void); static void remi(void);
300 static void remr_u(void); static void remi_u(void);
301 static void andr(void); static void andi(void);
302 static void orr(void); static void ori(void);
303 static void xorr(void); static void xori(void);
304 static void lshr(void); static void lshi(void);
305 static void rshr(void); static void rshi(void);
306 static void rshr_u(void); static void rshi_u(void);
307 static void negr(void); static void comr(void);
308 static void ltr(void); static void lti(void);
309 static void ltr_u(void); static void lti_u(void);
310 static void ler(void); static void lei(void);
311 static void ler_u(void); static void lei_u(void);
312 static void eqr(void); static void eqi(void);
313 static void ger(void); static void gei(void);
314 static void ger_u(void); static void gei_u(void);
315 static void gtr(void); static void gti(void);
316 static void gtr_u(void); static void gti_u(void);
317 static void ner(void); static void nei(void);
318 static void movr(void); static void movi(void);
319 static void extr_c(void); static void extr_uc(void);
320 static void extr_s(void); static void extr_us(void);
322 static void extr_i(void); static void extr_ui(void);
324 static void htonr_us(void); static void ntohr_us(void);
325 static void htonr_ui(void); static void ntohr_ui(void);
327 static void htonr_ul(void); static void ntohr_ul(void);
329 static void htonr(void); static void ntohr(void);
330 static void ldr_c(void); static void ldi_c(void);
331 static void ldr_uc(void); static void ldi_uc(void);
332 static void ldr_s(void); static void ldi_s(void);
333 static void ldr_us(void); static void ldi_us(void);
334 static void ldr_i(void); static void ldi_i(void);
336 static void ldr_ui(void); static void ldi_ui(void);
337 static void ldr_l(void); static void ldi_l(void);
339 static void ldr(void); static void ldi(void);
340 static void ldxr_c(void); static void ldxi_c(void);
341 static void ldxr_uc(void); static void ldxi_uc(void);
342 static void ldxr_s(void); static void ldxi_s(void);
343 static void ldxr_us(void); static void ldxi_us(void);
344 static void ldxr_i(void); static void ldxi_i(void);
346 static void ldxr_ui(void); static void ldxi_ui(void);
347 static void ldxr_l(void); static void ldxi_l(void);
349 static void ldxr(void); static void ldxi(void);
350 static void str_c(void); static void sti_c(void);
351 static void str_s(void); static void sti_s(void);
352 static void str_i(void); static void sti_i(void);
354 static void str_l(void); static void sti_l(void);
356 static void str(void); static void sti(void);
357 static void stxr_c(void); static void stxi_c(void);
358 static void stxr_s(void); static void stxi_s(void);
359 static void stxr_i(void); static void stxi_i(void);
361 static void stxr_l(void); static void stxi_l(void);
363 static void stxr(void); static void stxi(void);
364 static void bltr(void); static void blti(void);
365 static void bltr_u(void); static void blti_u(void);
366 static void bler(void); static void blei(void);
367 static void bler_u(void); static void blei_u(void);
368 static void beqr(void); static void beqi(void);
369 static void bger(void); static void bgei(void);
370 static void bger_u(void); static void bgei_u(void);
371 static void bgtr(void); static void bgti(void);
372 static void bgtr_u(void); static void bgti_u(void);
373 static void bner(void); static void bnei(void);
374 static void bmsr(void); static void bmsi(void);
375 static void bmcr(void); static void bmci(void);
376 static void boaddr(void); static void boaddi(void);
377 static void boaddr_u(void); static void boaddi_u(void);
378 static void bxaddr(void); static void bxaddi(void);
379 static void bxaddr_u(void); static void bxaddi_u(void);
380 static void bosubr(void); static void bosubi(void);
381 static void bosubr_u(void); static void bosubi_u(void);
382 static void bxsubr(void); static void bxsubi(void);
383 static void bxsubr_u(void); static void bxsubi_u(void);
384 static void jmpr(void); static void jmpi(void);
385 static void callr(void); static void calli(void);
386 static void prepare(void);
387 static void pushargr(void); static void pushargi(void);
388 static void finishr(void); static void finishi(void);
389 static void ret(void);
390 static void retr(void); static void reti(void);
391 static void retval_c(void); static void retval_uc(void);
392 static void retval_s(void); static void retval_us(void);
393 static void retval_i(void);
395 static void retval_ui(void); static void retval_l(void);
397 static void retval(void);
398 static void epilog(void);
399 static void arg_f(void); static void getarg_f(void);
400 static void putargr_f(void); static void putargi_f(void);
401 static void addr_f(void); static void addi_f(void);
402 static void subr_f(void); static void subi_f(void);
403 static void rsbr_f(void); static void rsbi_f(void);
404 static void mulr_f(void); static void muli_f(void);
405 static void divr_f(void); static void divi_f(void);
406 static void negr_f(void); static void absr_f(void);
407 static void sqrtr_f(void);
408 static void ltr_f(void); static void lti_f(void);
409 static void ler_f(void); static void lei_f(void);
410 static void eqr_f(void); static void eqi_f(void);
411 static void ger_f(void); static void gei_f(void);
412 static void gtr_f(void); static void gti_f(void);
413 static void ner_f(void); static void nei_f(void);
414 static void unltr_f(void); static void unlti_f(void);
415 static void unler_f(void); static void unlei_f(void);
416 static void uneqr_f(void); static void uneqi_f(void);
417 static void unger_f(void); static void ungei_f(void);
418 static void ungtr_f(void); static void ungti_f(void);
419 static void ltgtr_f(void); static void ltgti_f(void);
420 static void ordr_f(void); static void ordi_f(void);
421 static void unordr_f(void); static void unordi_f(void);
422 static void truncr_f_i(void);
424 static void truncr_f_l(void);
426 static void truncr_f(void);
427 static void extr_f(void); static void extr_d_f(void);
428 static void movr_f(void); static void movi_f(void);
429 static void ldr_f(void); static void ldi_f(void);
430 static void ldxr_f(void); static void ldxi_f(void);
431 static void str_f(void); static void sti_f(void);
432 static void stxr_f(void); static void stxi_f(void);
433 static void bltr_f(void); static void blti_f(void);
434 static void bler_f(void); static void blei_f(void);
435 static void beqr_f(void); static void beqi_f(void);
436 static void bger_f(void); static void bgei_f(void);
437 static void bgtr_f(void); static void bgti_f(void);
438 static void bner_f(void); static void bnei_f(void);
439 static void bunltr_f(void); static void bunlti_f(void);
440 static void bunler_f(void); static void bunlei_f(void);
441 static void buneqr_f(void); static void buneqi_f(void);
442 static void bunger_f(void); static void bungei_f(void);
443 static void bungtr_f(void); static void bungti_f(void);
444 static void bltgtr_f(void); static void bltgti_f(void);
445 static void bordr_f(void); static void bordi_f(void);
446 static void bunordr_f(void); static void bunordi_f(void);
447 static void pushargr_f(void); static void pushargi_f(void);
448 static void retr_f(void); static void reti_f(void);
449 static void retval_f(void);
450 static void arg_d(void); static void getarg_d(void);
451 static void putargr_d(void); static void putargi_d(void);
452 static void addr_d(void); static void addi_d(void);
453 static void subr_d(void); static void subi_d(void);
454 static void rsbr_d(void); static void rsbi_d(void);
455 static void mulr_d(void); static void muli_d(void);
456 static void divr_d(void); static void divi_d(void);
457 static void negr_d(void); static void absr_d(void);
458 static void sqrtr_d(void);
459 static void ltr_d(void); static void lti_d(void);
460 static void ler_d(void); static void lei_d(void);
461 static void eqr_d(void); static void eqi_d(void);
462 static void ger_d(void); static void gei_d(void);
463 static void gtr_d(void); static void gti_d(void);
464 static void ner_d(void); static void nei_d(void);
465 static void unltr_d(void); static void unlti_d(void);
466 static void unler_d(void); static void unlei_d(void);
467 static void uneqr_d(void); static void uneqi_d(void);
468 static void unger_d(void); static void ungei_d(void);
469 static void ungtr_d(void); static void ungti_d(void);
470 static void ltgtr_d(void); static void ltgti_d(void);
471 static void ordr_d(void); static void ordi_d(void);
472 static void unordr_d(void); static void unordi_d(void);
473 static void truncr_d_i(void);
475 static void truncr_d_l(void);
477 static void truncr_d(void);
478 static void extr_d(void); static void extr_f_d(void);
479 static void movr_d(void); static void movi_d(void);
480 static void ldr_d(void); static void ldi_d(void);
481 static void ldxr_d(void); static void ldxi_d(void);
482 static void str_d(void); static void sti_d(void);
483 static void stxr_d(void); static void stxi_d(void);
484 static void bltr_d(void); static void blti_d(void);
485 static void bler_d(void); static void blei_d(void);
486 static void beqr_d(void); static void beqi_d(void);
487 static void bger_d(void); static void bgei_d(void);
488 static void bgtr_d(void); static void bgti_d(void);
489 static void bner_d(void); static void bnei_d(void);
490 static void bunltr_d(void); static void bunlti_d(void);
491 static void bunler_d(void); static void bunlei_d(void);
492 static void buneqr_d(void); static void buneqi_d(void);
493 static void bunger_d(void); static void bungei_d(void);
494 static void bungtr_d(void); static void bungti_d(void);
495 static void bltgtr_d(void); static void bltgti_d(void);
496 static void bordr_d(void); static void bordi_d(void);
497 static void bunordr_d(void); static void bunordi_d(void);
498 static void pushargr_d(void); static void pushargi_d(void);
499 static void retr_d(void); static void reti_d(void);
500 static void retval_d(void);
501 static void vastart(void); static void vapush(void);
502 static void vaarg(void); static void vaarg_d(void);
503 static void vaend(void);
505 static void error(const char *format, ...) noreturn printf_format(1, 2);
506 static void warn(const char *format, ...) printf_format(1, 2) maybe_unused;
507 static void message(const char *kind, const char *format, va_list ap);
509 static int getch(void);
510 static int getch_noeof(void);
511 static int ungetch(int ch);
512 static int skipws(void);
513 static int skipnl(void);
514 static int skipct(void);
515 static int skipcp(void);
516 static jit_word_t get_int(skip_t skip);
517 static jit_uword_t get_uint(skip_t skip);
518 static double get_float(skip_t skip);
519 static float make_float(double d);
520 static void *get_pointer(skip_t skip);
521 static label_t *get_label(skip_t skip);
522 static token_t regname(void);
523 static token_t identifier(int ch);
524 static void get_data(type_t type);
525 static void dot(void);
526 static token_t number(int ch);
527 static int escape(int ch);
528 static token_t string(void);
529 static token_t dynamic(void);
530 static token_t character(void);
531 static void expression_prim(void);
532 static void expression_inc(int pre);
533 static void expression_dec(int pre);
534 static void expression_unary(void);
535 static void expression_mul(void);
536 static void expression_add(void);
537 static void expression_shift(void);
538 static void expression_bit(void);
539 static void expression_rel(void);
540 static void expression_cond(void);
541 static token_t expression(void);
542 static token_t primary(skip_t skip);
543 static void parse(void);
544 static int execute(int argc, char *argv[]);
546 static void *xmalloc(size_t size);
547 static void *xrealloc(void *pointer, size_t size);
548 static void *xcalloc(size_t nmemb, size_t size);
550 static label_t *new_label(label_kind_t kind, char *name, void *value);
551 static patch_t *new_patch(patch_kind_t kind, label_t *label, void *value);
552 static int bcmp_symbols(const void *left, const void *right);
553 static int qcmp_symbols(const void *left, const void *right);
554 static symbol_t *new_symbol(char *name);
555 static symbol_t *get_symbol_by_name(char *name);
557 static hash_t *new_hash(void);
558 static int hash_string(char *name);
559 static void put_hash(hash_t *hash, entry_t *entry);
560 static entry_t *get_hash(hash_t *hash, char *name);
561 static void rehash(hash_t *hash);
566 static jit_state_t *_jit;
567 static int flag_verbose;
568 static int flag_data;
569 static int flag_disasm;
570 static char *progname;
571 static parser_t parser;
572 static hash_t *labels;
573 static int label_offset;
574 static patch_t *patches;
575 static symbol_t **symbols;
576 static int symbol_length;
577 static int symbol_offset;
578 static hash_t *instrs;
580 static size_t data_offset, data_length;
581 static instr_t instr_vector[] = {
582 #define entry(value) { NULL, #value, value }
583 #define entry2(name, function) { NULL, name, function }
585 entry(align), entry(name),
587 entry(frame), entry(tramp),
589 entry(allocai), entry(allocar),
591 entry(getarg_c), entry(getarg_uc),
592 entry(getarg_s), entry(getarg_us),
595 entry(getarg_ui), entry(getarg_l),
598 entry(putargr), entry(putargi),
599 entry(addr), entry(addi),
600 entry(addxr), entry(addxi),
601 entry(addcr), entry(addci),
602 entry(subr), entry(subi),
603 entry(subxr), entry(subxi),
604 entry(subcr), entry(subci),
605 entry(rsbr), entry(rsbi),
606 entry(mulr), entry(muli),
607 entry(qmulr), entry(qmuli),
608 entry(qmulr_u), entry(qmuli_u),
609 entry(divr), entry(divi),
610 entry(divr_u), entry(divi_u),
611 entry(qdivr), entry(qdivi),
612 entry(qdivr_u), entry(qdivi_u),
613 entry(remr), entry(remi),
614 entry(remr_u), entry(remi_u),
615 entry(andr), entry(andi),
616 entry(orr), entry(ori),
617 entry(xorr), entry(xori),
618 entry(lshr), entry(lshi),
619 entry(rshr), entry(rshi),
620 entry(rshr_u), entry(rshi_u),
621 entry(negr), entry(comr),
622 entry(ltr), entry(lti),
623 entry(ltr_u), entry(lti_u),
624 entry(ler), entry(lei),
625 entry(ler_u), entry(lei_u),
626 entry(eqr), entry(eqi),
627 entry(ger), entry(gei),
628 entry(ger_u), entry(gei_u),
629 entry(gtr), entry(gti),
630 entry(gtr_u), entry(gti_u),
631 entry(ner), entry(nei),
632 entry(movr), entry(movi),
633 entry(extr_c), entry(extr_uc),
634 entry(extr_s), entry(extr_us),
636 entry(extr_i), entry(extr_ui),
638 entry(htonr_us), entry(ntohr_us),
639 entry(htonr_ui), entry(ntohr_ui),
641 entry(htonr_ul), entry(ntohr_ul),
643 entry(htonr), entry(ntohr),
644 entry(ldr_c), entry(ldi_c),
645 entry(ldr_uc), entry(ldi_uc),
646 entry(ldr_s), entry(ldi_s),
647 entry(ldr_us), entry(ldi_us),
648 entry(ldr_i), entry(ldi_i),
650 entry(ldr_ui), entry(ldi_ui),
651 entry(ldr_l), entry(ldi_l),
653 entry(ldr), entry(ldi),
654 entry(ldxr_c), entry(ldxi_c),
655 entry(ldxr_uc), entry(ldxi_uc),
656 entry(ldxr_s), entry(ldxi_s),
657 entry(ldxr_us), entry(ldxi_us),
658 entry(ldxr_i), entry(ldxi_i),
660 entry(ldxr_ui), entry(ldxi_ui),
661 entry(ldxr_l), entry(ldxi_l),
663 entry(ldxr), entry(ldxi),
664 entry(str_c), entry(sti_c),
665 entry(str_s), entry(sti_s),
666 entry(str_i), entry(sti_i),
668 entry(str_l), entry(sti_l),
670 entry(str), entry(sti),
671 entry(stxr_c), entry(stxi_c),
672 entry(stxr_s), entry(stxi_s),
673 entry(stxr_i), entry(stxi_i),
675 entry(stxr_l), entry(stxi_l),
677 entry(stxr), entry(stxi),
678 entry(bltr), entry(blti),
679 entry(bltr_u), entry(blti_u),
680 entry(bler), entry(blei),
681 entry(bler_u), entry(blei_u),
682 entry(beqr), entry(beqi),
683 entry(bger), entry(bgei),
684 entry(bger_u), entry(bgei_u),
685 entry(bgtr), entry(bgti),
686 entry(bgtr_u), entry(bgti_u),
687 entry(bner), entry(bnei),
688 entry(bmsr), entry(bmsi),
689 entry(bmcr), entry(bmci),
690 entry(boaddr), entry(boaddi),
691 entry(boaddr_u), entry(boaddi_u),
692 entry(bxaddr), entry(bxaddi),
693 entry(bxaddr_u), entry(bxaddi_u),
694 entry(bosubr), entry(bosubi),
695 entry(bosubr_u), entry(bosubi_u),
696 entry(bxsubr), entry(bxsubi),
697 entry(bxsubr_u), entry(bxsubi_u),
698 entry(jmpr), entry(jmpi),
699 entry(callr), entry(calli),
701 entry(pushargr), entry(pushargi),
702 entry(finishr), entry(finishi),
704 entry(retr), entry(reti),
705 entry(retval_c), entry(retval_uc),
706 entry(retval_s), entry(retval_us),
709 entry(retval_ui), entry(retval_l),
713 entry(arg_f), entry(getarg_f),
714 entry(putargr_f), entry(putargi_f),
715 entry(addr_f), entry(addi_f),
716 entry(subr_f), entry(subi_f),
717 entry(rsbr_f), entry(rsbi_f),
718 entry(mulr_f), entry(muli_f),
719 entry(divr_f), entry(divi_f),
720 entry(negr_f), entry(absr_f),
722 entry(ltr_f), entry(lti_f),
723 entry(ler_f), entry(lei_f),
724 entry(eqr_f), entry(eqi_f),
725 entry(ger_f), entry(gei_f),
726 entry(gtr_f), entry(gti_f),
727 entry(ner_f), entry(nei_f),
728 entry(unltr_f), entry(unlti_f),
729 entry(unler_f), entry(unlei_f),
730 entry(uneqr_f), entry(uneqi_f),
731 entry(unger_f), entry(ungei_f),
732 entry(ungtr_f), entry(ungti_f),
733 entry(ltgtr_f), entry(ltgti_f),
734 entry(ordr_f), entry(ordi_f),
735 entry(unordr_f), entry(unordi_f),
741 entry(extr_f), entry(extr_d_f),
742 entry(movr_f), entry(movi_f),
743 entry(ldr_f), entry(ldi_f),
744 entry(ldxr_f), entry(ldxi_f),
745 entry(str_f), entry(sti_f),
746 entry(stxr_f), entry(stxi_f),
747 entry(bltr_f), entry(blti_f),
748 entry(bler_f), entry(blei_f),
749 entry(beqr_f), entry(beqi_f),
750 entry(bger_f), entry(bgei_f),
751 entry(bgtr_f), entry(bgti_f),
752 entry(bner_f), entry(bnei_f),
753 entry(bunltr_f), entry(bunlti_f),
754 entry(bunler_f), entry(bunlei_f),
755 entry(buneqr_f), entry(buneqi_f),
756 entry(bunger_f), entry(bungei_f),
757 entry(bungtr_f), entry(bungti_f),
758 entry(bltgtr_f), entry(bltgti_f),
759 entry(bordr_f), entry(bordi_f),
760 entry(bunordr_f), entry(bunordi_f),
761 entry(pushargr_f), entry(pushargi_f),
762 entry(retr_f), entry(reti_f),
764 entry(arg_d), entry(getarg_d),
765 entry(putargr_d), entry(putargi_d),
766 entry(addr_d), entry(addi_d),
767 entry(subr_d), entry(subi_d),
768 entry(rsbr_d), entry(rsbi_d),
769 entry(mulr_d), entry(muli_d),
770 entry(divr_d), entry(divi_d),
771 entry(negr_d), entry(absr_d),
773 entry(ltr_d), entry(lti_d),
774 entry(ler_d), entry(lei_d),
775 entry(eqr_d), entry(eqi_d),
776 entry(ger_d), entry(gei_d),
777 entry(gtr_d), entry(gti_d),
778 entry(ner_d), entry(nei_d),
779 entry(unltr_d), entry(unlti_d),
780 entry(unler_d), entry(unlei_d),
781 entry(uneqr_d), entry(uneqi_d),
782 entry(unger_d), entry(ungei_d),
783 entry(ungtr_d), entry(ungti_d),
784 entry(ltgtr_d), entry(ltgti_d),
785 entry(ordr_d), entry(ordi_d),
786 entry(unordr_d), entry(unordi_d),
792 entry(extr_d), entry(extr_f_d),
793 entry(movr_d), entry(movi_d),
794 entry(ldr_d), entry(ldi_d),
795 entry(ldxr_d), entry(ldxi_d),
796 entry(str_d), entry(sti_d),
797 entry(stxr_d), entry(stxi_d),
798 entry(bltr_d), entry(blti_d),
799 entry(bler_d), entry(blei_d),
800 entry(beqr_d), entry(beqi_d),
801 entry(bger_d), entry(bgei_d),
802 entry(bgtr_d), entry(bgti_d),
803 entry(bner_d), entry(bnei_d),
804 entry(bunltr_d), entry(bunlti_d),
805 entry(bunler_d), entry(bunlei_d),
806 entry(buneqr_d), entry(buneqi_d),
807 entry(bunger_d), entry(bungei_d),
808 entry(bungtr_d), entry(bungti_d),
809 entry(bltgtr_d), entry(bltgti_d),
810 entry(bordr_d), entry(bordi_d),
811 entry(bunordr_d), entry(bunordi_d),
812 entry(pushargr_d), entry(pushargi_d),
813 entry(retr_d), entry(reti_d),
815 entry2("va_start", vastart),
816 entry2("va_push", vapush),
817 entry2("va_arg", vaarg),
818 entry2("va_arg_d", vaarg_d),
819 entry2("va_end", vaend),
829 if (primary(skip_ws) != tok_register)
830 error("bad register");
831 if (parser.regtype != type_l)
832 error("bad int register");
834 return ((jit_gpr_t)parser.regval);
840 if (primary(skip_ws) != tok_register)
841 error("bad register");
842 if (parser.regtype != type_d)
843 error("bad float register");
845 return ((jit_fpr_t)parser.regval);
855 error("expecting variable");
856 (void)identifier('$');
857 if (parser.string[1] == '\0')
858 error("expecting variable");
859 if ((symbol = get_symbol_by_name(parser.string)) == NULL)
860 symbol = new_symbol(parser.string);
866 jmp_forward(void *value, label_t *label)
868 (void)new_patch(patch_kind_jmp, label, value);
872 mov_forward(void *value, label_t *label)
874 (void)new_patch(patch_kind_mov, label, value);
878 call_forward(void *value, label_t *label)
880 (void)new_patch(patch_kind_call, label, value);
884 make_arg(void *value)
886 symbol_t *symbol = get_symbol();
888 symbol->type = type_p;
889 symbol->value.p = value;
895 symbol_t *symbol = get_symbol();
897 if (symbol->type != type_p)
898 error("bad argument %s type", symbol->name);
900 return symbol->value.p;
911 case '+': case '-': case '0' ... '9':
913 value = get_int(skip_none);
917 value = parser.value.i;
920 switch (expression()) {
923 value = parser.value.i;
926 error("expecting immediate");
931 value = (jit_word_t)parser.value.p;
935 label = get_label(skip_none);
936 if (label->kind == label_kind_data)
937 value = (jit_word_t)label->value;
939 error("expecting immediate");
945 #define entry(name) \
951 #define entry_ca(name) \
955 make_arg(jit_##name()); \
957 #define entry_ia(name) \
961 jit_gpr_t r0 = get_ireg(); \
962 jit_pointer_t ac = get_arg(); \
963 jit_##name(r0, ac); \
965 #define entry_im(name) \
969 jit_word_t im = get_imm(); \
972 #define entry_ir(name) \
976 jit_gpr_t r0 = get_ireg(); \
979 #define entry_ima(name) \
983 jit_word_t im = get_imm(); \
984 jit_pointer_t ac = get_arg(); \
985 jit_##name(im, ac); \
987 #define entry_ir_ir_ir(name) \
991 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(), r2 = get_ireg(); \
992 jit_##name(r0, r1, r2); \
994 #define entry_ir_ir_im(name) \
998 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \
999 jit_word_t im = get_imm(); \
1000 jit_##name(r0, r1, im); \
1002 #define entry_ir_ir_ir_ir(name) \
1006 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(), \
1007 r2 = get_ireg(), r3 = get_ireg(); \
1008 jit_##name(r0, r1, r2, r3); \
1010 #define entry_ir_ir_ir_im(name) \
1014 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(), r2 = get_ireg(); \
1015 jit_word_t im = get_imm(); \
1016 jit_##name(r0, r1, r2, im); \
1018 #define entry_ir_ir(name) \
1022 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \
1023 jit_##name(r0, r1); \
1025 #define entry_ir_im(name) \
1029 jit_gpr_t r0 = get_ireg(); \
1030 jit_word_t im = get_imm(); \
1031 jit_##name(r0, im); \
1033 #define entry_ir_pm(name) \
1037 jit_gpr_t r0 = get_ireg(); \
1038 void *pm = get_pointer(skip_ws); \
1039 jit_##name(r0, pm); \
1041 #define entry_pm_ir(name) \
1045 void *pm = get_pointer(skip_ws); \
1046 jit_gpr_t r0 = get_ireg(); \
1047 jit_##name(pm, r0); \
1049 #define entry_im_ir_ir(name) \
1053 jit_word_t im = get_imm(); \
1054 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \
1055 (void)jit_##name(im, r0, r1); \
1057 #define entry_lb_ir_ir(name) \
1062 label_t *label = get_label(skip_ws); \
1063 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \
1064 if (label->kind == label_kind_code_forward) \
1065 jmp_forward((void *)jit_##name(r0, r1), label); \
1067 jmp = jit_##name(r0, r1); \
1068 jit_patch_at(jmp, (jit_node_t *)label->value); \
1071 #define entry_lb_ir_im(name) \
1076 label_t *label = get_label(skip_ws); \
1077 jit_gpr_t r0 = get_ireg(); \
1078 jit_word_t im = get_imm(); \
1079 if (label->kind == label_kind_code_forward) \
1080 jmp_forward((void *)jit_##name(r0, im), label); \
1082 jmp = jit_##name(r0, im); \
1083 jit_patch_at(jmp, (jit_node_t *)label->value); \
1086 #define entry_lb(name) \
1091 label_t *label = get_label(skip_ws); \
1092 if (label->kind == label_kind_code_forward) \
1093 jmp_forward((void *)jit_##name(), label); \
1095 jmp = jit_##name(); \
1096 jit_patch_at(jmp, (jit_node_t *)label->value); \
1099 #define entry_pm(name) \
1103 void *pm = get_pointer(skip_ws); \
1106 #define entry_fa(name) \
1110 jit_fpr_t r0 = get_freg(); \
1111 jit_pointer_t ac = get_arg(); \
1112 jit_##name(r0, ac); \
1114 #define entry_fma(name) \
1118 jit_float64_t im = get_float(skip_ws); \
1119 jit_pointer_t ac = get_arg(); \
1120 jit_##name(im, ac); \
1122 #define entry_fr_fr_fr(name) \
1126 jit_fpr_t r0 = get_freg(), r1 = get_freg(), r2 = get_freg(); \
1127 jit_##name(r0, r1, r2); \
1129 #define entry_fr_fr_fm(name) \
1133 jit_fpr_t r0 = get_freg(), r1 = get_freg(); \
1134 jit_float64_t im = get_float(skip_ws); \
1135 jit_##name(r0, r1, make_float(im)); \
1137 #define entry_fr_fr_dm(name) \
1141 jit_fpr_t r0 = get_freg(), r1 = get_freg(); \
1142 jit_float64_t im = get_float(skip_ws); \
1143 jit_##name(r0, r1, im); \
1145 #define entry_fr_fr(name) \
1149 jit_fpr_t r0 = get_freg(), r1 = get_freg(); \
1150 jit_##name(r0, r1); \
1152 #define entry_ir_fr_fr(name) \
1156 jit_gpr_t r0 = get_ireg(); \
1157 jit_fpr_t r1 = get_freg(), r2 = get_freg(); \
1158 jit_##name(r0, r1, r2); \
1160 #define entry_ir_fr_fm(name) \
1164 jit_gpr_t r0 = get_ireg(); \
1165 jit_fpr_t r1 = get_freg(); \
1166 jit_float64_t im = get_float(skip_ws); \
1167 jit_##name(r0, r1, make_float(im)); \
1169 #define entry_ir_fr_dm(name) \
1173 jit_gpr_t r0 = get_ireg(); \
1174 jit_fpr_t r1 = get_freg(); \
1175 jit_float64_t im = get_float(skip_ws); \
1176 jit_##name(r0, r1, im); \
1178 #define entry_ir_fr(name) \
1182 jit_gpr_t r0 = get_ireg(); \
1183 jit_fpr_t r1 = get_freg(); \
1184 jit_##name(r0, r1); \
1186 #define entry_fr_ir(name) \
1190 jit_fpr_t r0 = get_freg(); \
1191 jit_gpr_t r1 = get_ireg(); \
1192 jit_##name(r0, r1); \
1194 #define entry_fr_fm(name) \
1198 jit_fpr_t r0 = get_freg(); \
1199 jit_float64_t im = get_float(skip_ws); \
1200 jit_##name(r0, make_float(im)); \
1202 #define entry_fr_dm(name) \
1206 jit_fpr_t r0 = get_freg(); \
1207 jit_float64_t im = get_float(skip_ws); \
1208 jit_##name(r0, im); \
1210 #define entry_fr_pm(name) \
1214 jit_fpr_t r0 = get_freg(); \
1215 void *pm = get_pointer(skip_ws); \
1216 jit_##name(r0, pm); \
1218 #define entry_fr_ir_ir(name) \
1222 jit_fpr_t r0 = get_freg(); \
1223 jit_gpr_t r1 = get_ireg(), r2 = get_ireg(); \
1224 jit_##name(r0, r1, r2); \
1226 #define entry_fr_ir_im(name) \
1230 jit_fpr_t r0 = get_freg(); \
1231 jit_gpr_t r1 = get_ireg(); \
1232 jit_word_t im = get_imm(); \
1233 jit_##name(r0, r1, im); \
1235 #define entry_pm_fr(name) \
1239 void *pm = get_pointer(skip_ws); \
1240 jit_fpr_t r0 = get_freg(); \
1241 jit_##name(pm, r0); \
1243 #define entry_ir_ir_fr(name) \
1247 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \
1248 jit_fpr_t r2 = get_freg(); \
1249 jit_##name(r0, r1, r2); \
1251 #define entry_im_ir_fr(name) \
1255 jit_word_t im = get_imm(); \
1256 jit_gpr_t r0 = get_ireg(); \
1257 jit_fpr_t r1 = get_freg(); \
1258 jit_##name(im, r0, r1); \
1260 #define entry_lb_fr_fr(name) \
1265 label_t *label = get_label(skip_ws); \
1266 jit_fpr_t r0 = get_freg(), r1 = get_freg(); \
1267 if (label->kind == label_kind_code_forward) \
1268 jmp_forward((void *)jit_##name(r0, r1), label); \
1270 jmp = jit_##name(r0, r1); \
1271 jit_patch_at(jmp, (jit_node_t *)label->value); \
1274 #define entry_lb_fr_fm(name) \
1279 label_t *label = get_label(skip_ws); \
1280 jit_fpr_t r0 = get_freg(); \
1281 jit_float64_t im = get_float(skip_ws); \
1282 if (label->kind == label_kind_code_forward) \
1283 jmp_forward((void *)jit_##name(r0, make_float(im)), label); \
1285 jmp = jit_##name(r0, make_float(im)); \
1286 jit_patch_at(jmp, (jit_node_t *)label->value); \
1289 #define entry_lb_fr_dm(name) \
1294 label_t *label = get_label(skip_ws); \
1295 jit_fpr_t r0 = get_freg(); \
1296 jit_float64_t im = get_float(skip_ws); \
1297 if (label->kind == label_kind_code_forward) \
1298 jmp_forward((void *)jit_##name(r0, im), label); \
1300 jmp = jit_##name(r0, im); \
1301 jit_patch_at(jmp, (jit_node_t *)label->value); \
1304 #define entry_fr(name) \
1308 jit_fpr_t r0 = get_freg(); \
1311 #define entry_fm(name) \
1315 jit_float64_t im = get_float(skip_ws); \
1316 jit_##name(make_float(im)); \
1318 #define entry_dm(name) \
1322 jit_float64_t im = get_float(skip_ws); \
1325 #define entry_fn(name) \
1336 value = (void *)(jit_word_t)get_uint(skip_none); \
1339 switch (expression()) { \
1341 value = (void *)parser.value.i; \
1344 value = parser.value.p; \
1347 error("expecting pointer"); \
1352 value = parser.value.p; \
1356 label = get_label(skip_none); \
1357 if (label->kind == label_kind_code_forward) \
1358 call_forward((void *)jit_##name(NULL), label); \
1360 jit_patch_at(jit_##name(NULL), label->value); \
1363 jit_##name(value); \
1368 (void)identifier(ch);
1369 jit_name(parser.string);
1373 if (primary(skip_ws) != tok_register)
1374 error("bad register");
1375 jit_live(parser.regval);
1379 entry_im(frame) entry_im(tramp)
1384 jit_word_t i, im = get_imm();
1385 i = jit_allocai(im);
1386 symbol = get_symbol();
1387 symbol->type = type_l;
1388 symbol->value.i = i;
1390 entry_ir_ir(allocar)
1392 entry_ia(getarg_c) entry_ia(getarg_uc)
1393 entry_ia(getarg_s) entry_ia(getarg_us)
1395 #if __WORDSIZE == 64
1396 entry_ia(getarg_ui) entry_ia(getarg_l)
1399 entry_ia(putargr) entry_ima(putargi)
1400 entry_ir_ir_ir(addr) entry_ir_ir_im(addi)
1401 entry_ir_ir_ir(addxr) entry_ir_ir_im(addxi)
1402 entry_ir_ir_ir(addcr) entry_ir_ir_im(addci)
1403 entry_ir_ir_ir(subr) entry_ir_ir_im(subi)
1404 entry_ir_ir_ir(subxr) entry_ir_ir_im(subxi)
1405 entry_ir_ir_ir(subcr) entry_ir_ir_im(subci)
1406 entry_ir_ir_ir(rsbr) entry_ir_ir_im(rsbi)
1407 entry_ir_ir_ir(mulr) entry_ir_ir_im(muli)
1408 entry_ir_ir_ir_ir(qmulr) entry_ir_ir_ir_im(qmuli)
1409 entry_ir_ir_ir_ir(qmulr_u) entry_ir_ir_ir_im(qmuli_u)
1410 entry_ir_ir_ir(divr) entry_ir_ir_im(divi)
1411 entry_ir_ir_ir(divr_u) entry_ir_ir_im(divi_u)
1412 entry_ir_ir_ir_ir(qdivr) entry_ir_ir_ir_im(qdivi)
1413 entry_ir_ir_ir_ir(qdivr_u) entry_ir_ir_ir_im(qdivi_u)
1414 entry_ir_ir_ir(remr) entry_ir_ir_im(remi)
1415 entry_ir_ir_ir(remr_u) entry_ir_ir_im(remi_u)
1416 entry_ir_ir_ir(andr) entry_ir_ir_im(andi)
1417 entry_ir_ir_ir(orr) entry_ir_ir_im(ori)
1418 entry_ir_ir_ir(xorr) entry_ir_ir_im(xori)
1419 entry_ir_ir_ir(lshr) entry_ir_ir_im(lshi)
1420 entry_ir_ir_ir(rshr) entry_ir_ir_im(rshi)
1421 entry_ir_ir_ir(rshr_u) entry_ir_ir_im(rshi_u)
1422 entry_ir_ir(negr) entry_ir_ir(comr)
1423 entry_ir_ir_ir(ltr) entry_ir_ir_im(lti)
1424 entry_ir_ir_ir(ltr_u) entry_ir_ir_im(lti_u)
1425 entry_ir_ir_ir(ler) entry_ir_ir_im(lei)
1426 entry_ir_ir_ir(ler_u) entry_ir_ir_im(lei_u)
1427 entry_ir_ir_ir(eqr) entry_ir_ir_im(eqi)
1428 entry_ir_ir_ir(ger) entry_ir_ir_im(gei)
1429 entry_ir_ir_ir(ger_u) entry_ir_ir_im(gei_u)
1430 entry_ir_ir_ir(gtr) entry_ir_ir_im(gti)
1431 entry_ir_ir_ir(gtr_u) entry_ir_ir_im(gti_u)
1432 entry_ir_ir_ir(ner) entry_ir_ir_im(nei)
1440 jit_gpr_t r0 = get_ireg();
1446 value = (void *)(jit_word_t)get_uint(skip_none);
1450 value = (void *)parser.value.i;
1453 switch (expression()) {
1455 value = (void *)parser.value.i;
1458 value = parser.value.p;
1461 error("expecting pointer");
1466 value = parser.value.p;
1470 label = get_label(skip_none);
1471 if (label->kind == label_kind_code ||
1472 label->kind == label_kind_code_forward) {
1473 mov_forward((void *)jit_movi(r0, 0), label);
1476 value = label->value;
1479 jit_movi(r0, (jit_word_t)value);
1481 entry_ir_ir(extr_c) entry_ir_ir(extr_uc)
1482 entry_ir_ir(extr_s) entry_ir_ir(extr_us)
1483 #if __WORDSIZE == 64
1484 entry_ir_ir(extr_i) entry_ir_ir(extr_ui)
1486 entry_ir_ir(htonr_us) entry_ir_ir(ntohr_us)
1487 entry_ir_ir(htonr_ui) entry_ir_ir(ntohr_ui)
1488 #if __WORDSIZE == 64
1489 entry_ir_ir(htonr_ul) entry_ir_ir(ntohr_ul)
1491 entry_ir_ir(htonr) entry_ir_ir(ntohr)
1492 entry_ir_ir(ldr_c) entry_ir_pm(ldi_c)
1493 entry_ir_ir(ldr_uc) entry_ir_pm(ldi_uc)
1494 entry_ir_ir(ldr_s) entry_ir_pm(ldi_s)
1495 entry_ir_ir(ldr_us) entry_ir_pm(ldi_us)
1496 entry_ir_ir(ldr_i) entry_ir_pm(ldi_i)
1497 #if __WORDSIZE == 64
1498 entry_ir_ir(ldr_ui) entry_ir_pm(ldi_ui)
1499 entry_ir_ir(ldr_l) entry_ir_pm(ldi_l)
1501 entry_ir_ir(ldr) entry_ir_pm(ldi)
1502 entry_ir_ir_ir(ldxr_c) entry_ir_ir_im(ldxi_c)
1503 entry_ir_ir_ir(ldxr_uc) entry_ir_ir_im(ldxi_uc)
1504 entry_ir_ir_ir(ldxr_s) entry_ir_ir_im(ldxi_s)
1505 entry_ir_ir_ir(ldxr_us) entry_ir_ir_im(ldxi_us)
1506 entry_ir_ir_ir(ldxr_i) entry_ir_ir_im(ldxi_i)
1507 #if __WORDSIZE == 64
1508 entry_ir_ir_ir(ldxr_ui) entry_ir_ir_im(ldxi_ui)
1509 entry_ir_ir_ir(ldxr_l) entry_ir_ir_im(ldxi_l)
1511 entry_ir_ir_ir(ldxr) entry_ir_ir_im(ldxi)
1512 entry_ir_ir(str_c) entry_pm_ir(sti_c)
1513 entry_ir_ir(str_s) entry_pm_ir(sti_s)
1514 entry_ir_ir(str_i) entry_pm_ir(sti_i)
1515 #if __WORDSIZE == 64
1516 entry_ir_ir(str_l) entry_pm_ir(sti_l)
1518 entry_ir_ir(str) entry_pm_ir(sti)
1519 entry_ir_ir_ir(stxr_c) entry_im_ir_ir(stxi_c)
1520 entry_ir_ir_ir(stxr_s) entry_im_ir_ir(stxi_s)
1521 entry_ir_ir_ir(stxr_i) entry_im_ir_ir(stxi_i)
1522 #if __WORDSIZE == 64
1523 entry_ir_ir_ir(stxr_l) entry_im_ir_ir(stxi_l)
1525 entry_ir_ir_ir(stxr) entry_im_ir_ir(stxi)
1526 entry_lb_ir_ir(bltr) entry_lb_ir_im(blti)
1527 entry_lb_ir_ir(bltr_u) entry_lb_ir_im(blti_u)
1528 entry_lb_ir_ir(bler) entry_lb_ir_im(blei)
1529 entry_lb_ir_ir(bler_u) entry_lb_ir_im(blei_u)
1530 entry_lb_ir_ir(beqr) entry_lb_ir_im(beqi)
1531 entry_lb_ir_ir(bger) entry_lb_ir_im(bgei)
1532 entry_lb_ir_ir(bger_u) entry_lb_ir_im(bgei_u)
1533 entry_lb_ir_ir(bgtr) entry_lb_ir_im(bgti)
1534 entry_lb_ir_ir(bgtr_u) entry_lb_ir_im(bgti_u)
1535 entry_lb_ir_ir(bner) entry_lb_ir_im(bnei)
1536 entry_lb_ir_ir(bmsr) entry_lb_ir_im(bmsi)
1537 entry_lb_ir_ir(bmcr) entry_lb_ir_im(bmci)
1538 entry_lb_ir_ir(boaddr) entry_lb_ir_im(boaddi)
1539 entry_lb_ir_ir(boaddr_u) entry_lb_ir_im(boaddi_u)
1540 entry_lb_ir_ir(bxaddr) entry_lb_ir_im(bxaddi)
1541 entry_lb_ir_ir(bxaddr_u) entry_lb_ir_im(bxaddi_u)
1542 entry_lb_ir_ir(bosubr) entry_lb_ir_im(bosubi)
1543 entry_lb_ir_ir(bosubr_u) entry_lb_ir_im(bosubi_u)
1544 entry_lb_ir_ir(bxsubr) entry_lb_ir_im(bxsubi)
1545 entry_lb_ir_ir(bxsubr_u) entry_lb_ir_im(bxsubi_u)
1546 entry_ir(jmpr) entry_lb(jmpi)
1547 entry_ir(callr) entry_fn(calli)
1549 entry_ir(pushargr) entry_im(pushargi)
1550 entry_ir(finishr) entry_fn(finishi)
1552 entry_ir(retr) entry_im(reti)
1553 entry_ir(retval_c) entry_ir(retval_uc)
1554 entry_ir(retval_s) entry_ir(retval_us)
1556 #if __WORDSIZE == 64
1557 entry_ir(retval_ui) entry_ir(retval_l)
1561 entry_ca(arg_f) entry_fa(getarg_f)
1562 entry_fa(putargr_f) entry_fma(putargi_f)
1563 entry_fr_fr_fr(addr_f) entry_fr_fr_fm(addi_f)
1564 entry_fr_fr_fr(subr_f) entry_fr_fr_fm(subi_f)
1565 entry_fr_fr_fr(rsbr_f) entry_fr_fr_fm(rsbi_f)
1566 entry_fr_fr_fr(mulr_f) entry_fr_fr_fm(muli_f)
1567 entry_fr_fr_fr(divr_f) entry_fr_fr_fm(divi_f)
1568 entry_fr_fr(negr_f) entry_fr_fr(absr_f)
1569 entry_fr_fr(sqrtr_f)
1570 entry_ir_fr_fr(ltr_f) entry_ir_fr_fm(lti_f)
1571 entry_ir_fr_fr(ler_f) entry_ir_fr_fm(lei_f)
1572 entry_ir_fr_fr(eqr_f) entry_ir_fr_fm(eqi_f)
1573 entry_ir_fr_fr(ger_f) entry_ir_fr_fm(gei_f)
1574 entry_ir_fr_fr(gtr_f) entry_ir_fr_fm(gti_f)
1575 entry_ir_fr_fr(ner_f) entry_ir_fr_fm(nei_f)
1576 entry_ir_fr_fr(unltr_f) entry_ir_fr_fm(unlti_f)
1577 entry_ir_fr_fr(unler_f) entry_ir_fr_fm(unlei_f)
1578 entry_ir_fr_fr(uneqr_f) entry_ir_fr_fm(uneqi_f)
1579 entry_ir_fr_fr(unger_f) entry_ir_fr_fm(ungei_f)
1580 entry_ir_fr_fr(ungtr_f) entry_ir_fr_fm(ungti_f)
1581 entry_ir_fr_fr(ltgtr_f) entry_ir_fr_fm(ltgti_f)
1582 entry_ir_fr_fr(ordr_f) entry_ir_fr_fm(ordi_f)
1583 entry_ir_fr_fr(unordr_f) entry_ir_fr_fm(unordi_f)
1584 entry_ir_fr(truncr_f_i)
1585 #if __WORDSIZE == 64
1586 entry_ir_fr(truncr_f_l)
1588 entry_ir_fr(truncr_f)
1589 entry_fr_ir(extr_f) entry_fr_fr(extr_d_f)
1590 entry_fr_fr(movr_f) entry_fr_fm(movi_f)
1591 entry_fr_ir(ldr_f) entry_fr_pm(ldi_f)
1592 entry_fr_ir_ir(ldxr_f) entry_fr_ir_im(ldxi_f)
1593 entry_ir_fr(str_f) entry_pm_fr(sti_f)
1594 entry_ir_ir_fr(stxr_f) entry_im_ir_fr(stxi_f)
1595 entry_lb_fr_fr(bltr_f) entry_lb_fr_fm(blti_f)
1596 entry_lb_fr_fr(bler_f) entry_lb_fr_fm(blei_f)
1597 entry_lb_fr_fr(beqr_f) entry_lb_fr_fm(beqi_f)
1598 entry_lb_fr_fr(bger_f) entry_lb_fr_fm(bgei_f)
1599 entry_lb_fr_fr(bgtr_f) entry_lb_fr_fm(bgti_f)
1600 entry_lb_fr_fr(bner_f) entry_lb_fr_fm(bnei_f)
1601 entry_lb_fr_fr(bunltr_f) entry_lb_fr_fm(bunlti_f)
1602 entry_lb_fr_fr(bunler_f) entry_lb_fr_fm(bunlei_f)
1603 entry_lb_fr_fr(buneqr_f) entry_lb_fr_fm(buneqi_f)
1604 entry_lb_fr_fr(bunger_f) entry_lb_fr_fm(bungei_f)
1605 entry_lb_fr_fr(bungtr_f) entry_lb_fr_fm(bungti_f)
1606 entry_lb_fr_fr(bltgtr_f) entry_lb_fr_fm(bltgti_f)
1607 entry_lb_fr_fr(bordr_f) entry_lb_fr_fm(bordi_f)
1608 entry_lb_fr_fr(bunordr_f) entry_lb_fr_fm(bunordi_f)
1609 entry_fr(pushargr_f) entry_fm(pushargi_f)
1610 entry_fr(retr_f) entry_fm(reti_f)
1612 entry_ca(arg_d) entry_fa(getarg_d)
1613 entry_fa(putargr_d) entry_fma(putargi_d)
1614 entry_fr_fr_fr(addr_d) entry_fr_fr_dm(addi_d)
1615 entry_fr_fr_fr(subr_d) entry_fr_fr_dm(subi_d)
1616 entry_fr_fr_fr(rsbr_d) entry_fr_fr_dm(rsbi_d)
1617 entry_fr_fr_fr(mulr_d) entry_fr_fr_dm(muli_d)
1618 entry_fr_fr_fr(divr_d) entry_fr_fr_dm(divi_d)
1619 entry_fr_fr(negr_d) entry_fr_fr(absr_d)
1620 entry_fr_fr(sqrtr_d)
1621 entry_ir_fr_fr(ltr_d) entry_ir_fr_dm(lti_d)
1622 entry_ir_fr_fr(ler_d) entry_ir_fr_dm(lei_d)
1623 entry_ir_fr_fr(eqr_d) entry_ir_fr_dm(eqi_d)
1624 entry_ir_fr_fr(ger_d) entry_ir_fr_dm(gei_d)
1625 entry_ir_fr_fr(gtr_d) entry_ir_fr_dm(gti_d)
1626 entry_ir_fr_fr(ner_d) entry_ir_fr_dm(nei_d)
1627 entry_ir_fr_fr(unltr_d) entry_ir_fr_dm(unlti_d)
1628 entry_ir_fr_fr(unler_d) entry_ir_fr_dm(unlei_d)
1629 entry_ir_fr_fr(uneqr_d) entry_ir_fr_dm(uneqi_d)
1630 entry_ir_fr_fr(unger_d) entry_ir_fr_dm(ungei_d)
1631 entry_ir_fr_fr(ungtr_d) entry_ir_fr_dm(ungti_d)
1632 entry_ir_fr_fr(ltgtr_d) entry_ir_fr_dm(ltgti_d)
1633 entry_ir_fr_fr(ordr_d) entry_ir_fr_dm(ordi_d)
1634 entry_ir_fr_fr(unordr_d) entry_ir_fr_dm(unordi_d)
1635 entry_ir_fr(truncr_d_i)
1636 #if __WORDSIZE == 64
1637 entry_ir_fr(truncr_d_l)
1639 entry_ir_fr(truncr_d)
1640 entry_fr_ir(extr_d) entry_fr_fr(extr_f_d)
1641 entry_fr_fr(movr_d) entry_fr_dm(movi_d)
1642 entry_fr_ir(ldr_d) entry_fr_pm(ldi_d)
1643 entry_fr_ir_ir(ldxr_d) entry_fr_ir_im(ldxi_d)
1644 entry_ir_fr(str_d) entry_pm_fr(sti_d)
1645 entry_ir_ir_fr(stxr_d) entry_im_ir_fr(stxi_d)
1646 entry_lb_fr_fr(bltr_d) entry_lb_fr_dm(blti_d)
1647 entry_lb_fr_fr(bler_d) entry_lb_fr_dm(blei_d)
1648 entry_lb_fr_fr(beqr_d) entry_lb_fr_dm(beqi_d)
1649 entry_lb_fr_fr(bger_d) entry_lb_fr_dm(bgei_d)
1650 entry_lb_fr_fr(bgtr_d) entry_lb_fr_dm(bgti_d)
1651 entry_lb_fr_fr(bner_d) entry_lb_fr_dm(bnei_d)
1652 entry_lb_fr_fr(bunltr_d) entry_lb_fr_dm(bunlti_d)
1653 entry_lb_fr_fr(bunler_d) entry_lb_fr_dm(bunlei_d)
1654 entry_lb_fr_fr(buneqr_d) entry_lb_fr_dm(buneqi_d)
1655 entry_lb_fr_fr(bunger_d) entry_lb_fr_dm(bungei_d)
1656 entry_lb_fr_fr(bungtr_d) entry_lb_fr_dm(bungti_d)
1657 entry_lb_fr_fr(bltgtr_d) entry_lb_fr_dm(bltgti_d)
1658 entry_lb_fr_fr(bordr_d) entry_lb_fr_dm(bordi_d)
1659 entry_lb_fr_fr(bunordr_d) entry_lb_fr_dm(bunordi_d)
1660 entry_fr(pushargr_d) entry_dm(pushargi_d)
1661 entry_fr(retr_d) entry_dm(reti_d)
1666 jit_gpr_t r0 = get_ireg();
1672 jit_gpr_t r0 = get_ireg();
1678 jit_gpr_t r0 = get_ireg(), r1 = get_ireg();
1684 jit_fpr_t r0 = get_freg();
1685 jit_gpr_t r1 = get_ireg();
1686 jit_va_arg_d(r0, r1);
1691 jit_gpr_t r0 = get_ireg();
1697 #undef entry_lb_fr_fm
1698 #undef entry_lb_fr_dm
1699 #undef entry_lb_fr_fr
1700 #undef entry_im_ir_fr
1701 #undef entry_ir_ir_fr
1703 #undef entry_fr_ir_ir
1704 #undef entry_fr_ir_im
1710 #undef entry_ir_fr_fm
1711 #undef entry_ir_fr_dm
1712 #undef entry_ir_fr_fr
1714 #undef entry_fr_fr_fm
1715 #undef entry_fr_fr_dm
1716 #undef entry_fr_fr_fr
1721 #undef entry_lb_ir_im
1722 #undef entry_lb_ir_ir
1723 #undef entry_im_ir_ir
1728 #undef entry_ir_ir_im
1729 #undef entry_ir_ir_ir
1738 error(const char *format, ...)
1744 va_start(ap, format);
1745 message("error", format, ap);
1747 length = parser.data.length - parser.data.offset;
1748 string = (char *)(parser.data.buffer + parser.data.offset - 1);
1750 strcpy(string + 74, "...");
1752 parser.data.buffer[parser.data.length - 1] = '\0';
1753 fprintf(stderr, "(%s)\n", string);
1758 warn(const char *format, ...)
1761 va_start(ap, format);
1762 message("warning", format, ap);
1767 message(const char *kind, const char *format, va_list ap)
1769 fprintf(stderr, "%s:%d: %s: ", parser.name,
1770 parser.line - parser.newline, kind);
1771 vfprintf(stderr, format, ap);
1772 fputc('\n', stderr);
1780 if (parser.data.offset < parser.data.length)
1781 ch = parser.data.buffer[parser.data.offset++];
1783 /* keep first offset for ungetch */
1784 if ((parser.data.length = fread(parser.data.buffer + 1, 1,
1785 sizeof(parser.data.buffer) - 1,
1786 parser.fp) + 1) <= 1) {
1788 parser.data.offset = 1;
1791 ch = parser.data.buffer[1];
1792 parser.data.offset = 2;
1795 if ((parser.newline = ch == '\n'))
1807 error("unexpected end of file");
1815 if ((parser.newline = ch == '\n'))
1818 if (parser.data.offset)
1819 parser.data.buffer[--parser.data.offset] = ch;
1822 parser.data.buffer[0] = ch;
1832 for (ch = getch();; ch = getch()) {
1842 case ' ': case '\f': case '\r': case '\t':
1855 for (ch = getch();; ch = getch()) {
1865 case ' ': case '\f': case '\n': case '\r': case '\t':
1867 /* handle as newline */
1884 for (ch = getch(); ch != '\n' && ch != EOF; ch = getch())
1888 for (; ch != '/';) {
1889 while (getch_noeof() != '*')
1891 while ((ch = getch_noeof()) == '*')
1906 for (ch = getch(); ch != '\n' && ch != EOF; ch = getch()) {
1909 if ((number(ch)) == tok_int)
1910 parser.line = parser.value.i - 1;
1914 if (parser.offset >= (int)sizeof(parser.name)) {
1915 strncpy(parser.name, parser.string, sizeof(parser.name));
1916 parser.name[sizeof(parser.name) - 1] = '\0';
1919 strcpy(parser.name, parser.string);
1930 get_int(skip_t skip)
1932 switch (primary(skip)) {
1936 parser.type = type_l;
1937 parser.value.i = (jit_word_t)parser.value.p;
1940 error("expecting integer");
1943 return (parser.value.i);
1947 get_uint(skip_t skip)
1949 switch (primary(skip)) {
1950 case tok_char: case tok_int:
1953 parser.type = type_l;
1954 parser.value.ui = (jit_uword_t)parser.value.p;
1957 error("expecting integer");
1960 return (parser.value.ui);
1964 get_float(skip_t skip)
1966 switch (primary(skip)) {
1969 parser.type = type_d;
1970 parser.value.d = parser.value.i;
1975 error("expecting float");
1978 return (parser.value.d);
1981 /* Workaround gcc not converting unordered values from double to
1982 * float (as done in other architectures) on s390 */
1984 make_float(double d)
1986 /* This is an workaround to a bug in Hercules s390 emulator,
1987 * and at least HP-UX ia64 not have these */
1988 #if defined(HAVE_ISNAN) && defined(HAVE_ISINF)
1989 if (isnan(d)) return ( 0.0f/0.0f);
1991 if (d > 0.0) return ( 1.0f/0.0f);
1992 else return (-1.0f/0.0f);
1999 get_pointer(skip_t skip)
2002 token_t token = primary(skip);
2006 label = get_label_by_name(parser.string);
2008 error("bad identifier %s", parser.string);
2009 switch (label->kind) {
2010 case label_kind_data:
2011 case label_kind_code:
2013 case label_kind_code_forward:
2014 /* as expression arguments */
2015 error("forward references not implemented");
2017 case label_kind_dynamic:
2020 parser.type = type_p;
2021 return (parser.value.p = label->value);
2023 parser.type = type_p;
2024 return (parser.value.p = (void *)parser.value.ui);
2026 return (parser.value.p);
2027 default: error("bad pointer");
2032 get_label(skip_t skip)
2041 case 'a' ... 'z': case 'A' ... 'Z': case '_':
2042 (void)identifier(ch);
2045 error("expecting label/immediate");
2047 if ((label = get_label_by_name(parser.string)) == NULL)
2048 label = new_label(label_kind_code_forward,
2049 parser.string, jit_forward());
2058 int check = 1, ch = getch();
2062 parser.regtype = type_l;
2063 switch (ch = getch()) {
2064 case '0': parser.regval = JIT_R0; break;
2065 case '1': parser.regval = JIT_R1; break;
2066 case '2': parser.regval = JIT_R2; break;
2068 num = get_int(skip_none);
2069 if (num < 0 || num >= JIT_R_NUM) goto fail;
2070 parser.regval = JIT_R(num);
2071 if (getch() != ')') goto fail;
2078 parser.regtype = type_l;
2079 switch (ch = getch()) {
2080 case '0': parser.regval = JIT_V0; break;
2081 case '1': parser.regval = JIT_V1; break;
2082 case '2': parser.regval = JIT_V2; break;
2085 num = get_int(skip_none);
2086 if (num < 0 || num >= JIT_V_NUM) goto fail;
2087 parser.regval = JIT_V(num);
2088 if (getch() != ')') goto fail;
2094 parser.regtype = type_d;
2095 switch (ch = getch()) {
2096 case '0': parser.regval = JIT_F0; break;
2097 case '1': parser.regval = JIT_F1; break;
2098 case '2': parser.regval = JIT_F2; break;
2099 case '3': parser.regval = JIT_F3; break;
2100 case '4': parser.regval = JIT_F4; break;
2101 case '5': parser.regval = JIT_F5; break;
2103 parser.regtype = type_l; /* oops */
2104 parser.regval = JIT_FP; break;
2106 num = get_int(skip_none);
2107 if (num < 0 || num >= JIT_F_NUM) goto fail;
2108 parser.regval = JIT_F(num);
2109 if (getch() != ')') goto fail;
2117 error("bad register");
2121 if ((ch >= 'a' && ch <= 'z') ||
2122 (ch >= 'A' && ch <= 'Z') ||
2123 (ch >= '0' && ch <= '9') ||
2129 return (tok_register);
2135 parser.string[0] = ch;
2136 for (parser.offset = 1;;) {
2137 switch ((ch = getch())) {
2138 case 'a' ... 'z': case 'A' ... 'Z': case '0' ... '9' : case '_':
2139 if (parser.offset + 1 >= MAX_IDENTIFIER) {
2140 parser.string[parser.offset] = '\0';
2141 error("bad identifier %s", parser.string);
2143 parser.string[parser.offset++] = ch;
2146 parser.string[parser.offset] = '\0';
2148 return (tok_symbol);
2154 get_data(type_t type)
2163 switch (token = primary(skip_ws)) {
2164 case tok_char: case tok_int:
2165 check_data(sizeof(signed char));
2166 *(signed char *)(data + data_offset) = parser.value.i;
2167 data_offset += sizeof(char);
2170 check_data(parser.offset);
2171 memcpy(data + data_offset, parser.string,
2173 data_offset += parser.offset;
2176 case tok_semicollon:
2177 if (test == data) error("syntax error");
2179 default: error("bad initializer");
2183 check_data(sizeof(signed short));
2184 *(signed short *)(data + data_offset) = get_int(skip_ws);
2185 data_offset += sizeof(short);
2188 check_data(sizeof(signed int));
2189 *(signed int *)(data + data_offset) = get_int(skip_ws);
2190 data_offset += sizeof(int);
2193 check_data(sizeof(jit_word_t));
2194 *(jit_word_t *)(data + data_offset) = get_int(skip_ws);
2195 data_offset += sizeof(jit_word_t);
2198 check_data(sizeof(float));
2199 *(float *)(data + data_offset) = get_float(skip_ws);
2200 data_offset += sizeof(float);
2203 check_data(sizeof(double));
2204 *(double *)(data + data_offset) = get_float(skip_ws);
2205 data_offset += sizeof(double);
2208 /* FIXME **patch if realloc** */
2209 check_data(sizeof(void*));
2210 *(void **)(data + data_offset) = get_pointer(skip_ws);
2211 data_offset += sizeof(void*);
2217 if (ch == '\n' || ch == ';' || ch == EOF)
2227 size_t offset, length;
2229 switch (ch = getch_noeof()) {
2231 /* use .$(expression) for non side effects expression */
2234 case 'a' ... 'z': case 'A' ... 'Z': case '_':
2235 (void)identifier(ch);
2239 if (skipws() != '$')
2240 error("expecting symbol");
2241 /* allow spaces before an expression */
2245 if (parser.string[1] == '\0') {
2246 switch (parser.string[0]) {
2247 case 'c': get_data(type_c); break;
2248 case 's': get_data(type_s); break;
2249 case 'i': get_data(type_i); break;
2250 case 'l': get_data(type_l); break;
2251 case 'f': get_data(type_f); break;
2252 case 'd': get_data(type_d); break;
2253 case 'p': get_data(type_p); break;
2254 default: error("bad type .%c", parser.string[0]);
2257 else if (strcmp(parser.string, "data") == 0) {
2258 if (parser.parsing != PARSING_NONE)
2259 error(".data must be specified once and be the first section");
2260 parser.parsing = PARSING_DATA;
2261 data_length = get_int(skip_ws);
2262 data = (char *)xcalloc(1, data_length);
2264 else if (strcmp(parser.string, "code") == 0) {
2265 if (parser.parsing != PARSING_NONE &&
2266 parser.parsing != PARSING_DATA)
2267 error(".code must be specified once only");
2268 parser.parsing = PARSING_CODE;
2270 else if (strcmp(parser.string, "align") == 0) {
2271 length = get_int(skip_ws);
2272 if (parser.parsing != PARSING_DATA)
2273 error(".align must be in .data");
2274 if (length > 1 && length <= 4096 && !(length & (length - 1))) {
2275 offset = data_offset;
2276 offset += length - ((offset + length) % length);
2277 check_data(offset - data_offset);
2278 data_offset = offset;
2281 error("bad .align %ld (must be a power of 2, >= 2 && <= 4096)",
2282 (jit_word_t)length);
2284 else if (strcmp(parser.string, "size") == 0) {
2285 length = get_int(skip_ws);
2286 if (parser.parsing != PARSING_DATA)
2287 error(".size must be in .data");
2289 data_offset += length;
2291 else if (strcmp(parser.string, "disasm") == 0)
2294 error("unknown command .%s", parser.string);
2300 char buffer[1024], *endptr;
2301 int integer = 1, offset = 0, neg = 0, e = 0, d = 0, base = 10;
2303 for (;; ch = getch()) {
2310 if (offset && buffer[offset - 1] != 'e') {
2318 if (offset && buffer[offset - 1] != 'e') {
2331 if (offset == 0 && base == 10) {
2337 if (offset == 0 && base == 8) {
2355 if (offset == 0 && base == 8) {
2360 case 'a': case 'c': case 'd': case 'f':
2373 case '_': case 'g' ... 'w': case 'y': case 'z': case 'A' ... 'Z':
2375 buffer[offset++] = '\0';
2376 error("bad constant %s", buffer);
2381 if (offset + 1 >= (int)sizeof(buffer))
2383 buffer[offset++] = ch;
2386 /* check for literal 0 */
2387 if (offset == 0 && base == 8) buffer[offset++] = '0';
2388 buffer[offset] = '\0';
2391 # define STRTOUL strtoull
2393 # define STRTOUL strtoul
2395 parser.value.ui = STRTOUL(buffer, &endptr, base);
2396 parser.type = type_l;
2398 parser.value.i = -parser.value.i;
2401 parser.type = type_d;
2402 parser.value.d = strtod(buffer, &endptr);
2404 parser.value.d = -parser.value.d;
2409 return (integer ? tok_int : tok_float);
2416 case 'a': ch = '\a'; break;
2417 case 'b': ch = '\b'; break;
2418 case 'f': ch = '\f'; break;
2419 case 'n': ch = '\n'; break;
2420 case 'r': ch = '\r'; break;
2421 case 't': ch = '\t'; break;
2422 case 'v': ch = '\v'; break;
2434 for (parser.offset = 0;;) {
2435 switch (ch = getch_noeof()) {
2437 if (esc) goto append;
2442 parser.string[parser.offset++] = '\0';
2443 parser.value.p = parser.string;
2444 parser.type = type_p;
2445 return (tok_string);
2454 if (parser.offset + 1 >= parser.length) {
2455 parser.length += 4096;
2456 parser.string = (char *)xrealloc(parser.string,
2459 parser.string[parser.offset++] = ch;
2470 if ((ch = getch_noeof()) == '\\') {
2474 if (getch_noeof() != '\'')
2475 error("bad single byte char");
2478 parser.type = type_l;
2479 parser.value.i = ch & 0xff;
2490 (void)identifier('@');
2491 if ((label = get_label_by_name(parser.string)) == NULL) {
2492 #if __CYGWIN__ ||_WIN32
2493 /* FIXME kludge to pass varargs test case, otherwise,
2494 * will not print/scan float values */
2495 if (strcmp(parser.string + 1, "sprintf") == 0)
2497 else if (strcmp(parser.string + 1, "sscanf") == 0)
2502 value = dlsym(DL_HANDLE, parser.string + 1);
2503 if ((string = dlerror()))
2504 error("%s", string);
2506 label = new_label(label_kind_dynamic, parser.string, value);
2508 parser.type = type_p;
2509 parser.value.p = label->value;
2511 return (tok_pointer);
2515 expression_prim(void)
2522 if (parser.putback) {
2523 parser.expr = parser.putback;
2524 parser.putback = (expr_t)0;
2527 switch (ch = skipws()) {
2529 if ((ch = getch_noeof()) == '=') parser.expr = expr_ne;
2531 ungetch(ch); parser.expr = expr_not;
2534 case '~': parser.expr = expr_com;
2537 if ((ch = getch_noeof()) == '=') parser.expr = expr_mulset;
2539 ungetch(ch); parser.expr = expr_mul;
2543 if ((ch = getch_noeof()) == '=') parser.expr = expr_divset;
2545 ungetch(ch); parser.expr = expr_div;
2549 if ((ch = getch_noeof()) == '=') parser.expr = expr_remset;
2551 ungetch(ch); parser.expr = expr_rem;
2555 switch (ch = getch_noeof()) {
2556 case '+': parser.expr = expr_inc;
2558 case '=': parser.expr = expr_addset;
2560 default: ungetch(ch); parser.expr = expr_add;
2565 switch (ch = getch_noeof()) {
2566 case '-': parser.expr = expr_dec;
2568 case '=': parser.expr = expr_subset;
2570 default: ungetch(ch); parser.expr = expr_sub;
2575 switch (ch = getch_noeof()) {
2576 case '=': parser.expr = expr_le;
2578 case '<': ch = getch_noeof();
2579 if (ch == '=') parser.expr = expr_lshset;
2581 ungetch(ch); parser.expr = expr_lsh;
2584 default: ungetch(ch); parser.expr = expr_lt;
2589 switch (ch = getch_noeof()) {
2590 case '=': parser.expr = expr_ge;
2592 case '>': ch = getch_noeof();
2593 if (ch == '=') parser.expr = expr_rshset;
2595 ungetch(ch); parser.expr = expr_rsh;
2598 default: ungetch(ch); parser.expr = expr_gt;
2603 switch (ch = getch_noeof()) {
2604 case '=': parser.expr = expr_andset;
2606 case '&': parser.expr = expr_andand;
2608 default: ungetch(ch); parser.expr = expr_and;
2613 switch (ch = getch_noeof()) {
2614 case '=': parser.expr = expr_orset;
2616 case '|': parser.expr = expr_oror;
2618 default: ungetch(ch); parser.expr = expr_or;
2623 if ((ch = getch_noeof()) == '=') parser.expr = expr_xorset;
2625 ungetch(ch); parser.expr = expr_xor;
2629 if ((ch = getch_noeof()) == '=') parser.expr = expr_eq;
2631 ungetch(ch); parser.expr = expr_set;
2634 case '(': parser.expr = expr_lparen;
2636 case ')': parser.expr = expr_rparen;
2640 parser.expr = token == tok_int ? expr_int : expr_float;
2644 parser.expr = expr_pointer;
2648 /* no support for nested expressions */
2649 if (parser.string[0] == '\0')
2650 error("syntax error");
2651 parser.expr = expr_symbol;
2652 if ((symbol = get_symbol_by_name(parser.string)) != NULL) {
2653 parser.type = symbol->type;
2654 parser.value = symbol->value;
2657 /* only create symbol on assignment */
2658 parser.type = type_none;
2660 case 'a' ... 'z': case 'A' ... 'Z': case '_':
2662 if ((label = get_label_by_name(parser.string))) {
2663 if (label->kind == label_kind_code_forward)
2664 error("forward value for %s not supported",
2666 parser.expr = expr_pointer;
2667 parser.type = type_p;
2668 parser.value.p = label->value;
2671 error("invalid identifier %s", parser.string);
2675 parser.expr = expr_int;
2678 /* not smart enough to put it in data and/or relocate it, etc */
2679 error("must declare strings as data");
2681 error("syntax error");
2686 expression_inc(int pre)
2692 if (parser.expr != expr_symbol)
2693 error("syntax error");
2695 if ((symbol = get_symbol_by_name(parser.string)) == NULL) {
2696 if (!parser.short_circuit)
2697 error("undefined symbol %s", symbol->name);
2699 if (!parser.short_circuit) {
2700 parser.type = symbol->type;
2702 parser.value = symbol->value;
2703 switch (symbol->type) {
2708 /* should really be an error */
2709 symbol->value.d += 1.0;
2716 parser.value = symbol->value;
2722 expression_dec(int pre)
2728 if (parser.expr != expr_symbol)
2729 error("syntax error");
2731 if ((symbol = get_symbol_by_name(parser.string)) == NULL) {
2732 if (!parser.short_circuit)
2733 error("undefined symbol %s", symbol->name);
2735 if (!parser.short_circuit) {
2736 parser.type = symbol->type;
2738 parser.value = symbol->value;
2739 switch (symbol->type) {
2744 /* should really be an error */
2745 symbol->value.d -= 1.0;
2752 parser.value = symbol->value;
2758 expression_unary(void)
2764 switch (parser.expr) {
2767 switch (parser.type) {
2772 error("syntax error");
2777 switch (parser.type) {
2779 parser.value.i = -parser.value.i;
2782 parser.value.d = -parser.value.d;
2785 error("syntax error");
2796 switch (parser.type) {
2798 parser.value.i = !parser.value.i;
2801 parser.value.i = parser.value.d != 0;
2804 parser.value.i = parser.value.p != NULL;
2807 error("syntax error");
2809 parser.type = type_l;
2813 if (parser.type != type_l)
2814 error("syntax error");
2815 parser.value.i = ~parser.value.i;
2819 if (parser.expr != expr_rparen)
2820 error("syntax error");
2824 strcpy(buffer, parser.string);
2826 switch (parser.expr) {
2828 if ((symbol = get_symbol_by_name(buffer)) == NULL) {
2829 if (!parser.short_circuit)
2830 symbol = new_symbol(buffer);
2834 if (!parser.short_circuit) {
2836 error("syntax error");
2837 symbol->type = parser.type;
2838 symbol->value = parser.value;
2841 case expr_mulset: parser.putback = expr_mul;
2843 case expr_divset: parser.putback = expr_div;
2845 case expr_remset: parser.putback = expr_rem;
2847 case expr_addset: parser.putback = expr_add;
2849 case expr_subset: parser.putback = expr_sub;
2851 case expr_lshset: parser.putback = expr_lsh;
2853 case expr_rshset: parser.putback = expr_rsh;
2855 case expr_andset: parser.putback = expr_and;
2857 case expr_orset: parser.putback = expr_or;
2859 case expr_xorset: parser.putback = expr_xor;
2861 if ((symbol = get_symbol_by_name(buffer)) == NULL) {
2862 if (!parser.short_circuit)
2863 error("undefined symbol %s", buffer);
2864 parser.type = type_l;
2867 switch (parser.putback) {
2868 case expr_mul: case expr_div: case expr_rem:
2871 case expr_add: case expr_sub:
2874 case expr_lsh: case expr_rsh:
2877 case expr_and: case expr_or: case expr_xor:
2897 /* make next token available */
2905 expression_mul(void)
2911 switch (parser.type) {
2912 case type_l: case type_d: case type_p: break;
2916 switch (parser.expr) {
2918 type = parser.type, value = parser.value;
2920 switch (parser.type) {
2923 value.i *= parser.value.i;
2925 value.d *= parser.value.i;
2928 if (type == type_l) {
2932 value.d *= parser.value.d;
2935 error("invalid operand");
2937 parser.type = type, parser.value = value;
2940 type = parser.type, value = parser.value;
2942 switch (parser.type) {
2944 if (type == type_l) {
2945 if (parser.value.i == 0)
2946 error("divide by zero");
2947 value.i /= parser.value.i;
2950 value.d /= parser.value.i;
2953 if (type == type_l) {
2957 value.d /= parser.value.d;
2960 error("invalid operand");
2962 parser.type = type, parser.value = value;
2965 type = parser.type, value = parser.value;
2967 switch (parser.type) {
2969 if (type == type_l) {
2970 if (parser.value.i == 0)
2971 error("divide by zero");
2972 value.i %= parser.value.i;
2975 error("invalid operand");
2978 error("invalid operand");
2980 parser.type = type, parser.value = value;
2989 expression_add(void)
2995 switch (parser.type) {
2996 case type_l: case type_d: case type_p: break;
3000 switch (parser.expr) {
3002 type = parser.type, value = parser.value;
3004 switch (parser.type) {
3008 value.i += parser.value.i;
3011 value.d += parser.value.i;
3014 value.cp += parser.value.i;
3027 error("invalid operand");
3029 value.d += parser.value.d;
3035 value.cp = value.i + parser.value.cp;
3038 error("invalid operand");
3042 error("invalid operand");
3044 parser.type = type, parser.value = value;
3047 type = parser.type, value = parser.value;
3049 switch (parser.type) {
3053 value.i -= parser.value.i;
3056 value.d -= parser.value.i;
3059 value.cp -= parser.value.i;
3072 error("invalid operand");
3074 value.d -= parser.value.d;
3080 value.i = value.cp - parser.value.cp;
3083 error("invalid operand");
3087 error("invalid operand");
3089 parser.type = type, parser.value = value;
3098 expression_shift(void)
3103 switch (parser.type) {
3104 case type_l: case type_d: case type_p: break;
3108 switch (parser.expr) {
3110 value = parser.value.i;
3111 if (parser.type != type_l)
3112 error("invalid operand");
3114 if (parser.type != type_l)
3115 error("invalid operand");
3116 value <<= parser.value.i;
3117 parser.value.i = value;
3120 value = parser.value.i;
3121 if (parser.type != type_l)
3122 error("invalid operand");
3124 if (parser.type != type_l)
3125 error("invalid operand");
3126 value >>= parser.value.i;
3127 parser.value.i = value;
3136 expression_bit(void)
3141 switch (parser.type) {
3142 case type_l: case type_d: case type_p: break;
3146 switch (parser.expr) {
3148 if (parser.type != type_l)
3149 error("invalid operand");
3152 if (parser.type != type_l)
3153 error("invalid operand");
3154 i &= parser.value.i;
3158 if (parser.type != type_l)
3159 error("invalid operand");
3162 if (parser.type != type_l)
3163 error("invalid operand");
3164 i |= parser.value.i;
3168 if (parser.type != type_l)
3169 error("invalid operand");
3172 if (parser.type != type_l)
3173 error("invalid operand");
3174 i ^= parser.value.i;
3184 expression_rel(void)
3190 switch (parser.type) {
3191 case type_l: case type_d: case type_p: break;
3195 switch (parser.expr) {
3197 type = parser.type, value = parser.value;
3199 switch (parser.type) {
3203 value.i = value.i < parser.value.i;
3206 value.i = value.d < parser.value.i;
3209 value.i = (jit_word_t)value.p < parser.value.i;
3216 value.i = value.i < parser.value.d;
3219 value.i = value.d < parser.value.d;
3222 error("invalid operand");
3228 value.i = value.i < (jit_word_t)parser.value.p;
3231 error("invalid operand");
3233 value.i = (jit_word_t)value.p < (jit_word_t)parser.value.p;
3238 error("invalid operand");
3240 parser.type = type_l, parser.value = value;
3243 type = parser.type, value = parser.value;
3245 switch (parser.type) {
3249 value.i = value.i <= parser.value.i;
3252 value.i = value.d <= parser.value.i;
3255 value.i = (jit_word_t)value.p <= parser.value.i;
3262 value.i = value.i <= parser.value.d;
3265 value.i = value.d <= parser.value.d;
3268 value.i = (jit_word_t)value.p <= parser.value.d;
3275 value.i = value.i <= (jit_word_t)parser.value.p;
3278 error("invalid operand");
3280 value.i = (jit_word_t)value.p <= (jit_word_t)parser.value.p;
3285 error("invalid operand");
3287 parser.type = type_l, parser.value = value;
3290 type = parser.type, value = parser.value;
3292 switch (parser.type) {
3296 value.i = value.i == parser.value.i;
3299 value.i = value.d == parser.value.i;
3302 value.i = (jit_word_t)value.p == parser.value.i;
3309 value.i = value.i == parser.value.d;
3312 value.i = value.d == parser.value.d;
3315 error("invalid operand");
3321 value.i = value.i == (jit_word_t)parser.value.p;
3324 error("invalid operand");
3326 value.i = value.p == parser.value.p;
3331 error("invalid operand");
3333 parser.type = type_l, parser.value = value;
3336 type = parser.type, value = parser.value;
3338 switch (parser.type) {
3342 value.i = value.i >= parser.value.i;
3345 value.i = value.d >= parser.value.i;
3348 value.i = (jit_word_t)value.p >= parser.value.i;
3355 value.i = value.i >= parser.value.d;
3358 value.i = value.d >= parser.value.d;
3361 error("invalid operand");
3367 value.i = value.i >= (jit_word_t)parser.value.p;
3370 error("invalid operand");
3372 value.i = (jit_word_t)value.p >= (jit_word_t)parser.value.p;
3377 error("invalid operand");
3379 parser.type = type_l, parser.value = value;
3382 type = parser.type, value = parser.value;
3384 switch (parser.type) {
3388 value.i = value.i > parser.value.i;
3391 value.i = value.d > parser.value.i;
3394 value.i = (jit_word_t)value.p > parser.value.i;
3401 value.i = value.i > parser.value.d;
3404 value.i = value.d > parser.value.d;
3407 error("invalid operand");
3413 value.i = value.i > (jit_word_t)parser.value.p;
3416 error("invalid operand");
3418 value.i = (jit_word_t)value.p > (jit_word_t)parser.value.p;
3423 error("invalid operand");
3425 parser.type = type_l, parser.value = value;
3428 type = parser.type, value = parser.value;
3430 switch (parser.type) {
3434 value.i = value.i != parser.value.i;
3437 value.i = value.d != parser.value.i;
3440 value.i = (jit_word_t)value.p != parser.value.i;
3447 value.i = value.i != parser.value.d;
3450 value.i = value.d != parser.value.d;
3453 error("invalid operand");
3459 value.i = value.i != (jit_word_t)parser.value.p;
3462 error("invalid operand");
3464 value.i = value.p != parser.value.p;
3469 error("invalid operand");
3471 parser.type = type_l, parser.value = value;
3480 expression_cond(void)
3487 switch (parser.type) {
3488 case type_l: case type_d: case type_p: break;
3492 switch (parser.expr) {
3494 type = parser.type, value = parser.value;
3497 short_circuit = value.i == 0;
3500 short_circuit = value.d == 0.0;
3503 short_circuit = value.p == NULL;
3506 parser.short_circuit += short_circuit;
3508 parser.short_circuit -= short_circuit;
3509 switch (parser.type) {
3513 value.i = value.i && parser.value.i;
3516 value.i = value.d && parser.value.i;
3519 value.i = value.p && parser.value.i;
3526 value.i = value.i && parser.value.d;
3529 value.i = value.d && parser.value.d;
3532 value.i = value.p && parser.value.d;
3539 value.i = value.i && parser.value.p;
3542 value.i = value.d && parser.value.p;
3545 value.i = value.p && parser.value.p;
3550 error("invalid operand");
3552 parser.type = type_l, parser.value.i = value.i;
3555 type = parser.type, value = parser.value;
3558 short_circuit = value.i != 0;
3561 short_circuit = value.d != 0.0;
3564 short_circuit = value.p != NULL;
3567 parser.short_circuit += short_circuit;
3569 parser.short_circuit -= short_circuit;
3570 switch (parser.type) {
3574 value.i = value.i || parser.value.i;
3577 value.i = value.d || parser.value.i;
3580 value.i = value.p || parser.value.i;
3587 value.i = value.i || parser.value.d;
3590 value.i = value.d || parser.value.d;
3593 value.i = value.p || parser.value.d;
3600 value.i = value.i || parser.value.p;
3603 value.i = value.d || parser.value.p;
3606 value.i = value.p || parser.value.p;
3611 error("invalid operand");
3613 parser.type = type_l, parser.value.i = value.i;
3626 (void)identifier('$');
3627 if (parser.string[1] == '\0') {
3628 if (getch_noeof() != '(')
3629 error("bad symbol or expression");
3630 parser.type = type_none;
3632 if (parser.expr != expr_rparen)
3633 error("bad expression");
3634 switch (parser.type) {
3640 return (tok_pointer);
3642 error("bad expression");
3645 else if ((symbol = get_symbol_by_name(parser.string))) {
3646 switch (parser.type = symbol->type) {
3648 parser.value.i = symbol->value.i;
3651 parser.value.d = symbol->value.d;
3654 parser.value.p = symbol->value.p;
3655 return (tok_pointer);
3659 error("undefined symbol %s", parser.string);
3663 primary(skip_t skip)
3668 case skip_none: ch = getch(); break;
3669 case skip_ws: ch = skipws(); break;
3670 case skip_nl: ch = skipnl(); break;
3676 case 'a' ... 'z': case 'A' ... 'Z': case '_':
3677 return (identifier(ch));
3678 case '0' ... '9': case '+': case '-':
3679 return (number(ch));
3685 return (character());
3689 return (expression());
3693 return (tok_newline);
3695 return (tok_semicollon);
3697 error("syntax error");
3711 switch (token = primary(skip_nl)) {
3715 if ((label = get_label_by_name(parser.string))) {
3716 if (label->kind == label_kind_code_forward) {
3717 label->kind = label_kind_code;
3718 jit_link(label->value);
3719 jit_note(parser.name, parser.line);
3722 error("label %s: redefined", parser.string);
3725 if (parser.parsing == PARSING_DATA) {
3726 value = data + data_offset;
3727 label = new_label(label_kind_data,
3728 parser.string, value);
3730 else if (parser.parsing == PARSING_CODE) {
3731 value = jit_label();
3732 jit_note(parser.name, parser.line);
3733 label = new_label(label_kind_code,
3734 parser.string, value);
3737 error("label not in .code or .data");
3743 (instr_t *)get_hash(instrs, parser.string)) == NULL)
3744 error("unhandled symbol %s", parser.string);
3745 if (parser.parsing != PARSING_CODE)
3746 error(".code must be specified before instructions");
3747 (*instr->function)();
3755 error("syntax error");
3761 execute(int argc, char *argv[])
3765 function_t function;
3766 patch_t *patch, *next;
3768 for (patch = patches; patch; patch = next) {
3770 label = patch->label;
3771 if (label->kind == label_kind_code_forward)
3772 error("undefined label %s", label->name);
3773 switch (patch->kind) {
3774 case patch_kind_jmp:
3775 case patch_kind_mov:
3776 case patch_kind_call:
3777 jit_patch_at(patch->value, label->value);
3786 if (flag_data == 0) {
3788 jit_set_data(NULL, 0, JIT_DISABLE_DATA | JIT_DISABLE_NOTE);
3791 function = jit_emit();
3792 if (flag_verbose > 1 || flag_disasm) {
3794 fprintf(stdout, " - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n");
3796 if (flag_verbose > 0 || flag_disasm) {
3798 fprintf(stdout, " - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n");
3805 result = (*function)(argc, argv);
3806 jit_destroy_state();
3812 xmalloc(size_t size)
3814 void *pointer = malloc(size);
3816 if (pointer == NULL)
3817 error("out of memory");
3823 xrealloc(void *pointer, size_t size)
3825 pointer = realloc(pointer, size);
3827 if (pointer == NULL)
3828 error("out of memory");
3834 xcalloc(size_t nmemb, size_t size)
3836 void *pointer = calloc(nmemb, size);
3838 if (pointer == NULL)
3839 error("out of memory");
3845 new_label(label_kind_t kind, char *name, void *value)
3849 label = (label_t *)xmalloc(sizeof(label_t));
3851 label->name = strdup(name);
3852 label->value = value;
3853 put_hash(labels, (entry_t *)label);
3859 new_patch(patch_kind_t kind, label_t *label, void *value)
3861 patch_t *patch = (patch_t *)xmalloc(sizeof(patch_t));
3863 patch->label = label;
3864 patch->value = value;
3865 patch->next = patches;
3872 bcmp_symbols(const void *left, const void *right)
3874 return (strcmp((char *)left, (*(symbol_t **)right)->name));
3878 qcmp_symbols(const void *left, const void *right)
3880 return (strcmp((*(symbol_t **)left)->name, (*(symbol_t **)right)->name));
3884 new_symbol(char *name)
3888 if ((symbol_offset & 15) == 0) {
3889 if ((symbol_length += 16) == 16)
3890 symbols = (symbol_t **)xmalloc(sizeof(symbol_t *) *
3893 symbols = (symbol_t **)xrealloc(symbols, sizeof(symbol_t *) *
3896 symbol = (symbol_t *)xmalloc(sizeof(symbol_t));
3897 symbol->name = strdup(name);
3898 symbols[symbol_offset++] = symbol;
3899 qsort(symbols, symbol_offset, sizeof(symbol_t *), qcmp_symbols);
3905 get_symbol_by_name(char *name)
3907 symbol_t **symbol_pointer;
3909 if (symbols == NULL)
3911 symbol_pointer = (symbol_t **)bsearch(name, symbols, symbol_offset,
3912 sizeof(symbol_t *), bcmp_symbols);
3914 return (symbol_pointer ? *symbol_pointer : NULL);
3922 hash = (hash_t *)xmalloc(sizeof(hash_t));
3924 hash->entries = (entry_t **)xcalloc(hash->size = 32, sizeof(void *));
3930 hash_string(char *name)
3935 for (key = 0, ptr = name; *ptr; ptr++)
3936 key = (key << (key & 1)) ^ *ptr;
3942 put_hash(hash_t *hash, entry_t *entry)
3944 entry_t *prev, *ptr;
3945 int key = hash_string(entry->name) & (hash->size - 1);
3947 for (prev = ptr = hash->entries[key]; ptr; prev = ptr, ptr = ptr->next) {
3948 if (strcmp(entry->name, ptr->name) == 0)
3949 error("duplicated entry %s", entry->name);
3952 hash->entries[key] = entry;
3957 if (hash->count > hash->size * 0.75)
3962 get_hash(hash_t *hash, char *name)
3965 int key = hash_string(name) & (hash->size - 1);
3967 for (entry = hash->entries[key]; entry; entry = entry->next) {
3968 if (strcmp(entry->name, name) == 0)
3975 rehash(hash_t *hash)
3978 entry_t *entry, *next, **entries;
3980 entries = (entry_t **)xcalloc(size = hash->size * 2, sizeof(void *));
3981 for (i = 0; i < hash->size; i++) {
3982 for (entry = hash->entries[i]; entry; entry = next) {
3984 key = hash_string(entry->name) & (size - 1);
3985 entry->next = entries[key];
3986 entries[key] = entry;
3989 free(hash->entries);
3990 hash->entries = entries;
3997 #if HAVE_GETOPT_LONG_ONLY
3999 Usage: %s [jit assembler options] file [jit program options]\n\
4000 Jit assembler options:\n\
4001 -help Display this information\n\
4002 -v[0-3] Verbose output level\n\
4003 -d Do not use a data buffer\n\
4004 -D<macro>[=<val>] Preprocessor options\n"
4005 # if defined(__i386__) && __WORDSIZE == 32
4006 " -mx87=1 Force using x87 when sse2 available\n"
4008 # if defined(__i386__) || defined(__x86_64__)
4009 " -msse4_1=0 Do not use sse4_1 instructions when available\n"
4011 # if defined(__arm__)
4012 " -mcpu=<val> Force cpu version (4, 5, 6 or 7)\n\
4013 -mthumb[=0|1] Enable or disable thumb\n\
4014 -mvfp=<val> Set vpf version (0 to disable)\n\
4015 -mneon[=0|1] Enable or disable neon\n"
4020 Usage: %s [jit assembler options] file [jit program options]\n\
4021 Jit assembler options:\n\
4022 -h Display this information\n\
4023 -v Verbose output level\n\
4024 -D<macro>[=<val>] Preprocessor options\n", progname);
4031 main(int argc, char *argv[])
4033 #if HAVE_GETOPT_LONG_ONLY
4034 static const char *short_options = "dv::";
4035 static struct option long_options[] = {
4036 { "help", 0, 0, 'h' },
4037 { "data", 2, 0, 'd' },
4038 # if defined(__i386__) && __WORDSIZE == 32
4039 { "mx87", 2, 0, '7' },
4041 # if defined(__i386__) || defined(__x86_64__)
4042 { "msse4_1", 2, 0, '4' },
4044 # if defined(__arm__)
4045 { "mcpu", 2, 0, 'c' },
4046 { "mthumb", 2, 0, 't' },
4047 { "mvfp", 2, 0, 'f' },
4048 { "mneon", 2, 0, 'n' },
4053 #endif /* HAVE_GETOPT_LONG_ONLY */
4060 #if defined(__CYGWIN__)
4061 /* Cause a compile warning about redefinition without dllimport
4062 * attribute, *but* cause correct linkage if liblightning.a is
4063 * linked to binutils (that happens to have an internal
4064 * getopt* implementation and an apparently conflicting
4065 * optind global variable) */
4075 DL_HANDLE = dlopen(NULL, RTLD_LAZY);
4079 #if HAVE_GETOPT_LONG_ONLY
4081 if ((opt_short = getopt_long_only(argc, argv, short_options,
4082 long_options, &opt_index)) < 0)
4084 switch (opt_short) {
4091 flag_verbose = strtol(optarg, &endptr, 10);
4092 if (*endptr || flag_verbose < 0)
4101 #if defined(__i386__) && __WORDSIZE == 32
4104 if (strcmp(optarg, "") == 0 || strcmp(optarg, "1") == 0)
4106 else if (strcmp(optarg, "0"))
4113 #if defined(__i386__) || defined(__x86_64__)
4116 if (strcmp(optarg, "0") == 0)
4118 else if (strcmp(optarg, "1"))
4123 #if defined(__arm__)
4126 offset = strtol(optarg, &endptr, 10);
4127 if (*endptr || offset < 0)
4129 if (offset < jit_cpu.version)
4130 jit_cpu.version = offset;
4135 if (strcmp(optarg, "0") == 0)
4137 else if (strcmp(optarg, "1") && strcmp(optarg, "2"))
4142 # if !defined(__ARM_PCS_VFP)
4143 /* Do not allow overrinding hard float abi */
4145 offset = strtol(optarg, &endptr, 10);
4146 if (*endptr || offset < 0)
4148 if (offset < jit_cpu.vfp)
4149 jit_cpu.vfp = offset;
4155 if (strcmp(optarg, "0") == 0)
4157 else if (strcmp(optarg, "1"))
4165 while ((opt_short = getopt(argc, argv, "hvd")) >= 0) {
4166 if (opt_short == 'v')
4168 else if (opt_short == 'd')
4178 if (opt_index < argc && argv[opt_index][0] == '-')
4181 if (opt_index < 0 || opt_index >= argc)
4183 if (strcmp(argv[opt_index], "-") == 0)
4184 strcpy(parser.name, "<stdin>");
4186 if ((endptr = strrchr(argv[opt_index], '/')) == NULL)
4187 endptr = argv[opt_index];
4190 strncpy(parser.name, endptr, sizeof(parser.name));
4191 parser.name[sizeof(parser.name) - 1] = '\0';
4198 opt_short = snprintf(cmdline, sizeof(cmdline), cc " -E -x c %s", argv[opt_index]);
4199 for (++opt_index; opt_index < argc; opt_index++) {
4200 if (argv[opt_index][0] == '-')
4201 opt_short += snprintf(cmdline + opt_short,
4202 sizeof(cmdline) - opt_short,
4203 " %s", argv[opt_index]);
4209 opt_short += snprintf(cmdline + opt_short,
4210 sizeof(cmdline) - opt_short,
4211 " -D__WORDSIZE=%d", __WORDSIZE);
4212 opt_short += snprintf(cmdline + opt_short,
4213 sizeof(cmdline) - opt_short,
4214 " -D__LITTLE_ENDIAN=%d", __LITTLE_ENDIAN);
4215 opt_short += snprintf(cmdline + opt_short,
4216 sizeof(cmdline) - opt_short,
4217 " -D__BIG_ENDIAN=%d", __BIG_ENDIAN);
4218 opt_short += snprintf(cmdline + opt_short,
4219 sizeof(cmdline) - opt_short,
4220 " -D__BYTE_ORDER=%d", __BYTE_ORDER);
4221 #if defined(__i386__)
4222 opt_short += snprintf(cmdline + opt_short,
4223 sizeof(cmdline) - opt_short,
4226 #if defined(__x86_64__)
4227 opt_short += snprintf(cmdline + opt_short,
4228 sizeof(cmdline) - opt_short,
4231 #if defined(__mips__)
4232 opt_short += snprintf(cmdline + opt_short,
4233 sizeof(cmdline) - opt_short,
4236 #if defined(__arm__)
4237 opt_short += snprintf(cmdline + opt_short,
4238 sizeof(cmdline) - opt_short,
4241 #if defined(__powerpc__)
4242 opt_short += snprintf(cmdline + opt_short,
4243 sizeof(cmdline) - opt_short,
4246 #if defined(__sparc__)
4247 opt_short += snprintf(cmdline + opt_short,
4248 sizeof(cmdline) - opt_short,
4251 #if defined(__ia64__)
4252 opt_short += snprintf(cmdline + opt_short,
4253 sizeof(cmdline) - opt_short,
4256 #if defined(__hppa__)
4257 opt_short += snprintf(cmdline + opt_short,
4258 sizeof(cmdline) - opt_short,
4262 opt_short += snprintf(cmdline + opt_short,
4263 sizeof(cmdline) - opt_short,
4266 #if defined(__sgi__)
4267 opt_short += snprintf(cmdline + opt_short,
4268 sizeof(cmdline) - opt_short,
4271 #if defined(__aarch64__)
4272 opt_short += snprintf(cmdline + opt_short,
4273 sizeof(cmdline) - opt_short,
4274 " -D__aarch64__=1");
4276 #if defined(__s390__) || defined(__s390x__)
4277 opt_short += snprintf(cmdline + opt_short,
4278 sizeof(cmdline) - opt_short,
4281 #if defined(__alpha__)
4282 opt_short += snprintf(cmdline + opt_short,
4283 sizeof(cmdline) - opt_short,
4286 if ((parser.fp = popen(cmdline, "r")) == NULL)
4287 error("cannot execute %s", cmdline);
4290 parser.string = (char *)xmalloc(parser.length = 4096);
4292 #if defined(__linux__) && (defined(__i386__) || defined(__x86_64__))
4293 /* double precision 0x200
4294 * round nearest 0x000
4295 * invalid operation mask 0x001
4296 * denormalized operand mask 0x002
4297 * zero divide mask 0x004
4298 * precision (inexact) mask 0x020
4301 fpu_control_t fpu_control = 0x027f;
4302 _FPU_SETCW(fpu_control);
4306 _jit = jit_new_state();
4308 instrs = new_hash();
4310 offset < (int)(sizeof(instr_vector) / sizeof(instr_vector[0]));
4312 put_hash(instrs, (entry_t *)(instr_vector + offset));
4314 labels = new_hash();
4320 for (opt_short = 0; opt_index < argc; opt_short++, opt_index++)
4321 argv[opt_short] = argv[opt_index];
4322 argv[opt_short] = NULL;
4324 execute(argc, argv);