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 movnr(void); static void movzr(void);
331 static void ldr_c(void); static void ldi_c(void);
332 static void ldr_uc(void); static void ldi_uc(void);
333 static void ldr_s(void); static void ldi_s(void);
334 static void ldr_us(void); static void ldi_us(void);
335 static void ldr_i(void); static void ldi_i(void);
337 static void ldr_ui(void); static void ldi_ui(void);
338 static void ldr_l(void); static void ldi_l(void);
340 static void ldr(void); static void ldi(void);
341 static void ldxr_c(void); static void ldxi_c(void);
342 static void ldxr_uc(void); static void ldxi_uc(void);
343 static void ldxr_s(void); static void ldxi_s(void);
344 static void ldxr_us(void); static void ldxi_us(void);
345 static void ldxr_i(void); static void ldxi_i(void);
347 static void ldxr_ui(void); static void ldxi_ui(void);
348 static void ldxr_l(void); static void ldxi_l(void);
350 static void ldxr(void); static void ldxi(void);
351 static void str_c(void); static void sti_c(void);
352 static void str_s(void); static void sti_s(void);
353 static void str_i(void); static void sti_i(void);
355 static void str_l(void); static void sti_l(void);
357 static void str(void); static void sti(void);
358 static void stxr_c(void); static void stxi_c(void);
359 static void stxr_s(void); static void stxi_s(void);
360 static void stxr_i(void); static void stxi_i(void);
362 static void stxr_l(void); static void stxi_l(void);
364 static void stxr(void); static void stxi(void);
365 static void bltr(void); static void blti(void);
366 static void bltr_u(void); static void blti_u(void);
367 static void bler(void); static void blei(void);
368 static void bler_u(void); static void blei_u(void);
369 static void beqr(void); static void beqi(void);
370 static void bger(void); static void bgei(void);
371 static void bger_u(void); static void bgei_u(void);
372 static void bgtr(void); static void bgti(void);
373 static void bgtr_u(void); static void bgti_u(void);
374 static void bner(void); static void bnei(void);
375 static void bmsr(void); static void bmsi(void);
376 static void bmcr(void); static void bmci(void);
377 static void boaddr(void); static void boaddi(void);
378 static void boaddr_u(void); static void boaddi_u(void);
379 static void bxaddr(void); static void bxaddi(void);
380 static void bxaddr_u(void); static void bxaddi_u(void);
381 static void bosubr(void); static void bosubi(void);
382 static void bosubr_u(void); static void bosubi_u(void);
383 static void bxsubr(void); static void bxsubi(void);
384 static void bxsubr_u(void); static void bxsubi_u(void);
385 static void jmpr(void); static void jmpi(void);
386 static void callr(void); static void calli(void);
387 static void prepare(void);
388 static void pushargr(void); static void pushargi(void);
389 static void finishr(void); static void finishi(void);
390 static void ret(void);
391 static void retr(void); static void reti(void);
392 static void retval_c(void); static void retval_uc(void);
393 static void retval_s(void); static void retval_us(void);
394 static void retval_i(void);
396 static void retval_ui(void); static void retval_l(void);
398 static void retval(void);
399 static void epilog(void);
400 static void arg_f(void); static void getarg_f(void);
401 static void putargr_f(void); static void putargi_f(void);
402 static void addr_f(void); static void addi_f(void);
403 static void subr_f(void); static void subi_f(void);
404 static void rsbr_f(void); static void rsbi_f(void);
405 static void mulr_f(void); static void muli_f(void);
406 static void divr_f(void); static void divi_f(void);
407 static void negr_f(void); static void absr_f(void);
408 static void sqrtr_f(void);
409 static void ltr_f(void); static void lti_f(void);
410 static void ler_f(void); static void lei_f(void);
411 static void eqr_f(void); static void eqi_f(void);
412 static void ger_f(void); static void gei_f(void);
413 static void gtr_f(void); static void gti_f(void);
414 static void ner_f(void); static void nei_f(void);
415 static void unltr_f(void); static void unlti_f(void);
416 static void unler_f(void); static void unlei_f(void);
417 static void uneqr_f(void); static void uneqi_f(void);
418 static void unger_f(void); static void ungei_f(void);
419 static void ungtr_f(void); static void ungti_f(void);
420 static void ltgtr_f(void); static void ltgti_f(void);
421 static void ordr_f(void); static void ordi_f(void);
422 static void unordr_f(void); static void unordi_f(void);
423 static void truncr_f_i(void);
425 static void truncr_f_l(void);
427 static void truncr_f(void);
428 static void extr_f(void); static void extr_d_f(void);
429 static void movr_f(void); static void movi_f(void);
430 static void ldr_f(void); static void ldi_f(void);
431 static void ldxr_f(void); static void ldxi_f(void);
432 static void str_f(void); static void sti_f(void);
433 static void stxr_f(void); static void stxi_f(void);
434 static void bltr_f(void); static void blti_f(void);
435 static void bler_f(void); static void blei_f(void);
436 static void beqr_f(void); static void beqi_f(void);
437 static void bger_f(void); static void bgei_f(void);
438 static void bgtr_f(void); static void bgti_f(void);
439 static void bner_f(void); static void bnei_f(void);
440 static void bunltr_f(void); static void bunlti_f(void);
441 static void bunler_f(void); static void bunlei_f(void);
442 static void buneqr_f(void); static void buneqi_f(void);
443 static void bunger_f(void); static void bungei_f(void);
444 static void bungtr_f(void); static void bungti_f(void);
445 static void bltgtr_f(void); static void bltgti_f(void);
446 static void bordr_f(void); static void bordi_f(void);
447 static void bunordr_f(void); static void bunordi_f(void);
448 static void pushargr_f(void); static void pushargi_f(void);
449 static void retr_f(void); static void reti_f(void);
450 static void retval_f(void);
451 static void arg_d(void); static void getarg_d(void);
452 static void putargr_d(void); static void putargi_d(void);
453 static void addr_d(void); static void addi_d(void);
454 static void subr_d(void); static void subi_d(void);
455 static void rsbr_d(void); static void rsbi_d(void);
456 static void mulr_d(void); static void muli_d(void);
457 static void divr_d(void); static void divi_d(void);
458 static void negr_d(void); static void absr_d(void);
459 static void sqrtr_d(void);
460 static void ltr_d(void); static void lti_d(void);
461 static void ler_d(void); static void lei_d(void);
462 static void eqr_d(void); static void eqi_d(void);
463 static void ger_d(void); static void gei_d(void);
464 static void gtr_d(void); static void gti_d(void);
465 static void ner_d(void); static void nei_d(void);
466 static void unltr_d(void); static void unlti_d(void);
467 static void unler_d(void); static void unlei_d(void);
468 static void uneqr_d(void); static void uneqi_d(void);
469 static void unger_d(void); static void ungei_d(void);
470 static void ungtr_d(void); static void ungti_d(void);
471 static void ltgtr_d(void); static void ltgti_d(void);
472 static void ordr_d(void); static void ordi_d(void);
473 static void unordr_d(void); static void unordi_d(void);
474 static void truncr_d_i(void);
476 static void truncr_d_l(void);
478 static void truncr_d(void);
479 static void extr_d(void); static void extr_f_d(void);
480 static void movr_d(void); static void movi_d(void);
481 static void ldr_d(void); static void ldi_d(void);
482 static void ldxr_d(void); static void ldxi_d(void);
483 static void str_d(void); static void sti_d(void);
484 static void stxr_d(void); static void stxi_d(void);
485 static void bltr_d(void); static void blti_d(void);
486 static void bler_d(void); static void blei_d(void);
487 static void beqr_d(void); static void beqi_d(void);
488 static void bger_d(void); static void bgei_d(void);
489 static void bgtr_d(void); static void bgti_d(void);
490 static void bner_d(void); static void bnei_d(void);
491 static void bunltr_d(void); static void bunlti_d(void);
492 static void bunler_d(void); static void bunlei_d(void);
493 static void buneqr_d(void); static void buneqi_d(void);
494 static void bunger_d(void); static void bungei_d(void);
495 static void bungtr_d(void); static void bungti_d(void);
496 static void bltgtr_d(void); static void bltgti_d(void);
497 static void bordr_d(void); static void bordi_d(void);
498 static void bunordr_d(void); static void bunordi_d(void);
499 static void pushargr_d(void); static void pushargi_d(void);
500 static void retr_d(void); static void reti_d(void);
501 static void retval_d(void);
502 static void vastart(void); static void vapush(void);
503 static void vaarg(void); static void vaarg_d(void);
504 static void vaend(void);
506 static void error(const char *format, ...) noreturn printf_format(1, 2);
507 static void warn(const char *format, ...) printf_format(1, 2) maybe_unused;
508 static void message(const char *kind, const char *format, va_list ap);
510 static int getch(void);
511 static int getch_noeof(void);
512 static int ungetch(int ch);
513 static int skipws(void);
514 static int skipnl(void);
515 static int skipct(void);
516 static int skipcp(void);
517 static jit_word_t get_int(skip_t skip);
518 static jit_uword_t get_uint(skip_t skip);
519 static double get_float(skip_t skip);
520 static float make_float(double d);
521 static void *get_pointer(skip_t skip);
522 static label_t *get_label(skip_t skip);
523 static token_t regname(void);
524 static token_t identifier(int ch);
525 static void get_data(type_t type);
526 static void dot(void);
527 static token_t number(int ch);
528 static int escape(int ch);
529 static token_t string(void);
530 static token_t dynamic(void);
531 static token_t character(void);
532 static void expression_prim(void);
533 static void expression_inc(int pre);
534 static void expression_dec(int pre);
535 static void expression_unary(void);
536 static void expression_mul(void);
537 static void expression_add(void);
538 static void expression_shift(void);
539 static void expression_bit(void);
540 static void expression_rel(void);
541 static void expression_cond(void);
542 static token_t expression(void);
543 static token_t primary(skip_t skip);
544 static void parse(void);
545 static int execute(int argc, char *argv[]);
547 static void *xmalloc(size_t size);
548 static void *xrealloc(void *pointer, size_t size);
549 static void *xcalloc(size_t nmemb, size_t size);
551 static label_t *new_label(label_kind_t kind, char *name, void *value);
552 static patch_t *new_patch(patch_kind_t kind, label_t *label, void *value);
553 static int bcmp_symbols(const void *left, const void *right);
554 static int qcmp_symbols(const void *left, const void *right);
555 static symbol_t *new_symbol(char *name);
556 static symbol_t *get_symbol_by_name(char *name);
558 static hash_t *new_hash(void);
559 static int hash_string(char *name);
560 static void put_hash(hash_t *hash, entry_t *entry);
561 static entry_t *get_hash(hash_t *hash, char *name);
562 static void rehash(hash_t *hash);
567 static jit_state_t *_jit;
568 static int flag_verbose;
569 static int flag_data;
570 static int flag_disasm;
571 static char *progname;
572 static parser_t parser;
573 static hash_t *labels;
574 static int label_offset;
575 static patch_t *patches;
576 static symbol_t **symbols;
577 static int symbol_length;
578 static int symbol_offset;
579 static hash_t *instrs;
581 static size_t data_offset, data_length;
582 static instr_t instr_vector[] = {
583 #define entry(value) { NULL, #value, value }
584 #define entry2(name, function) { NULL, name, function }
586 entry(align), entry(name),
588 entry(frame), entry(tramp),
590 entry(allocai), entry(allocar),
592 entry(getarg_c), entry(getarg_uc),
593 entry(getarg_s), entry(getarg_us),
596 entry(getarg_ui), entry(getarg_l),
599 entry(putargr), entry(putargi),
600 entry(addr), entry(addi),
601 entry(addxr), entry(addxi),
602 entry(addcr), entry(addci),
603 entry(subr), entry(subi),
604 entry(subxr), entry(subxi),
605 entry(subcr), entry(subci),
606 entry(rsbr), entry(rsbi),
607 entry(mulr), entry(muli),
608 entry(qmulr), entry(qmuli),
609 entry(qmulr_u), entry(qmuli_u),
610 entry(divr), entry(divi),
611 entry(divr_u), entry(divi_u),
612 entry(qdivr), entry(qdivi),
613 entry(qdivr_u), entry(qdivi_u),
614 entry(remr), entry(remi),
615 entry(remr_u), entry(remi_u),
616 entry(andr), entry(andi),
617 entry(orr), entry(ori),
618 entry(xorr), entry(xori),
619 entry(lshr), entry(lshi),
620 entry(rshr), entry(rshi),
621 entry(rshr_u), entry(rshi_u),
622 entry(negr), entry(comr),
623 entry(ltr), entry(lti),
624 entry(ltr_u), entry(lti_u),
625 entry(ler), entry(lei),
626 entry(ler_u), entry(lei_u),
627 entry(eqr), entry(eqi),
628 entry(ger), entry(gei),
629 entry(ger_u), entry(gei_u),
630 entry(gtr), entry(gti),
631 entry(gtr_u), entry(gti_u),
632 entry(ner), entry(nei),
633 entry(movr), entry(movi),
634 entry(extr_c), entry(extr_uc),
635 entry(extr_s), entry(extr_us),
637 entry(extr_i), entry(extr_ui),
639 entry(htonr_us), entry(ntohr_us),
640 entry(htonr_ui), entry(ntohr_ui),
642 entry(htonr_ul), entry(ntohr_ul),
644 entry(htonr), entry(ntohr),
645 entry(movnr), entry(movzr),
646 entry(ldr_c), entry(ldi_c),
647 entry(ldr_uc), entry(ldi_uc),
648 entry(ldr_s), entry(ldi_s),
649 entry(ldr_us), entry(ldi_us),
650 entry(ldr_i), entry(ldi_i),
652 entry(ldr_ui), entry(ldi_ui),
653 entry(ldr_l), entry(ldi_l),
655 entry(ldr), entry(ldi),
656 entry(ldxr_c), entry(ldxi_c),
657 entry(ldxr_uc), entry(ldxi_uc),
658 entry(ldxr_s), entry(ldxi_s),
659 entry(ldxr_us), entry(ldxi_us),
660 entry(ldxr_i), entry(ldxi_i),
662 entry(ldxr_ui), entry(ldxi_ui),
663 entry(ldxr_l), entry(ldxi_l),
665 entry(ldxr), entry(ldxi),
666 entry(str_c), entry(sti_c),
667 entry(str_s), entry(sti_s),
668 entry(str_i), entry(sti_i),
670 entry(str_l), entry(sti_l),
672 entry(str), entry(sti),
673 entry(stxr_c), entry(stxi_c),
674 entry(stxr_s), entry(stxi_s),
675 entry(stxr_i), entry(stxi_i),
677 entry(stxr_l), entry(stxi_l),
679 entry(stxr), entry(stxi),
680 entry(bltr), entry(blti),
681 entry(bltr_u), entry(blti_u),
682 entry(bler), entry(blei),
683 entry(bler_u), entry(blei_u),
684 entry(beqr), entry(beqi),
685 entry(bger), entry(bgei),
686 entry(bger_u), entry(bgei_u),
687 entry(bgtr), entry(bgti),
688 entry(bgtr_u), entry(bgti_u),
689 entry(bner), entry(bnei),
690 entry(bmsr), entry(bmsi),
691 entry(bmcr), entry(bmci),
692 entry(boaddr), entry(boaddi),
693 entry(boaddr_u), entry(boaddi_u),
694 entry(bxaddr), entry(bxaddi),
695 entry(bxaddr_u), entry(bxaddi_u),
696 entry(bosubr), entry(bosubi),
697 entry(bosubr_u), entry(bosubi_u),
698 entry(bxsubr), entry(bxsubi),
699 entry(bxsubr_u), entry(bxsubi_u),
700 entry(jmpr), entry(jmpi),
701 entry(callr), entry(calli),
703 entry(pushargr), entry(pushargi),
704 entry(finishr), entry(finishi),
706 entry(retr), entry(reti),
707 entry(retval_c), entry(retval_uc),
708 entry(retval_s), entry(retval_us),
711 entry(retval_ui), entry(retval_l),
715 entry(arg_f), entry(getarg_f),
716 entry(putargr_f), entry(putargi_f),
717 entry(addr_f), entry(addi_f),
718 entry(subr_f), entry(subi_f),
719 entry(rsbr_f), entry(rsbi_f),
720 entry(mulr_f), entry(muli_f),
721 entry(divr_f), entry(divi_f),
722 entry(negr_f), entry(absr_f),
724 entry(ltr_f), entry(lti_f),
725 entry(ler_f), entry(lei_f),
726 entry(eqr_f), entry(eqi_f),
727 entry(ger_f), entry(gei_f),
728 entry(gtr_f), entry(gti_f),
729 entry(ner_f), entry(nei_f),
730 entry(unltr_f), entry(unlti_f),
731 entry(unler_f), entry(unlei_f),
732 entry(uneqr_f), entry(uneqi_f),
733 entry(unger_f), entry(ungei_f),
734 entry(ungtr_f), entry(ungti_f),
735 entry(ltgtr_f), entry(ltgti_f),
736 entry(ordr_f), entry(ordi_f),
737 entry(unordr_f), entry(unordi_f),
743 entry(extr_f), entry(extr_d_f),
744 entry(movr_f), entry(movi_f),
745 entry(ldr_f), entry(ldi_f),
746 entry(ldxr_f), entry(ldxi_f),
747 entry(str_f), entry(sti_f),
748 entry(stxr_f), entry(stxi_f),
749 entry(bltr_f), entry(blti_f),
750 entry(bler_f), entry(blei_f),
751 entry(beqr_f), entry(beqi_f),
752 entry(bger_f), entry(bgei_f),
753 entry(bgtr_f), entry(bgti_f),
754 entry(bner_f), entry(bnei_f),
755 entry(bunltr_f), entry(bunlti_f),
756 entry(bunler_f), entry(bunlei_f),
757 entry(buneqr_f), entry(buneqi_f),
758 entry(bunger_f), entry(bungei_f),
759 entry(bungtr_f), entry(bungti_f),
760 entry(bltgtr_f), entry(bltgti_f),
761 entry(bordr_f), entry(bordi_f),
762 entry(bunordr_f), entry(bunordi_f),
763 entry(pushargr_f), entry(pushargi_f),
764 entry(retr_f), entry(reti_f),
766 entry(arg_d), entry(getarg_d),
767 entry(putargr_d), entry(putargi_d),
768 entry(addr_d), entry(addi_d),
769 entry(subr_d), entry(subi_d),
770 entry(rsbr_d), entry(rsbi_d),
771 entry(mulr_d), entry(muli_d),
772 entry(divr_d), entry(divi_d),
773 entry(negr_d), entry(absr_d),
775 entry(ltr_d), entry(lti_d),
776 entry(ler_d), entry(lei_d),
777 entry(eqr_d), entry(eqi_d),
778 entry(ger_d), entry(gei_d),
779 entry(gtr_d), entry(gti_d),
780 entry(ner_d), entry(nei_d),
781 entry(unltr_d), entry(unlti_d),
782 entry(unler_d), entry(unlei_d),
783 entry(uneqr_d), entry(uneqi_d),
784 entry(unger_d), entry(ungei_d),
785 entry(ungtr_d), entry(ungti_d),
786 entry(ltgtr_d), entry(ltgti_d),
787 entry(ordr_d), entry(ordi_d),
788 entry(unordr_d), entry(unordi_d),
794 entry(extr_d), entry(extr_f_d),
795 entry(movr_d), entry(movi_d),
796 entry(ldr_d), entry(ldi_d),
797 entry(ldxr_d), entry(ldxi_d),
798 entry(str_d), entry(sti_d),
799 entry(stxr_d), entry(stxi_d),
800 entry(bltr_d), entry(blti_d),
801 entry(bler_d), entry(blei_d),
802 entry(beqr_d), entry(beqi_d),
803 entry(bger_d), entry(bgei_d),
804 entry(bgtr_d), entry(bgti_d),
805 entry(bner_d), entry(bnei_d),
806 entry(bunltr_d), entry(bunlti_d),
807 entry(bunler_d), entry(bunlei_d),
808 entry(buneqr_d), entry(buneqi_d),
809 entry(bunger_d), entry(bungei_d),
810 entry(bungtr_d), entry(bungti_d),
811 entry(bltgtr_d), entry(bltgti_d),
812 entry(bordr_d), entry(bordi_d),
813 entry(bunordr_d), entry(bunordi_d),
814 entry(pushargr_d), entry(pushargi_d),
815 entry(retr_d), entry(reti_d),
817 entry2("va_start", vastart),
818 entry2("va_push", vapush),
819 entry2("va_arg", vaarg),
820 entry2("va_arg_d", vaarg_d),
821 entry2("va_end", vaend),
831 if (primary(skip_ws) != tok_register)
832 error("bad register");
833 if (parser.regtype != type_l)
834 error("bad int register");
836 return ((jit_gpr_t)parser.regval);
842 if (primary(skip_ws) != tok_register)
843 error("bad register");
844 if (parser.regtype != type_d)
845 error("bad float register");
847 return ((jit_fpr_t)parser.regval);
857 error("expecting variable");
858 (void)identifier('$');
859 if (parser.string[1] == '\0')
860 error("expecting variable");
861 if ((symbol = get_symbol_by_name(parser.string)) == NULL)
862 symbol = new_symbol(parser.string);
868 jmp_forward(void *value, label_t *label)
870 (void)new_patch(patch_kind_jmp, label, value);
874 mov_forward(void *value, label_t *label)
876 (void)new_patch(patch_kind_mov, label, value);
880 call_forward(void *value, label_t *label)
882 (void)new_patch(patch_kind_call, label, value);
886 make_arg(void *value)
888 symbol_t *symbol = get_symbol();
890 symbol->type = type_p;
891 symbol->value.p = value;
897 symbol_t *symbol = get_symbol();
899 if (symbol->type != type_p)
900 error("bad argument %s type", symbol->name);
902 return symbol->value.p;
913 case '+': case '-': case '0' ... '9':
915 value = get_int(skip_none);
919 value = parser.value.i;
922 switch (expression()) {
925 value = parser.value.i;
928 error("expecting immediate");
933 value = (jit_word_t)parser.value.p;
937 label = get_label(skip_none);
938 if (label->kind == label_kind_data)
939 value = (jit_word_t)label->value;
941 error("expecting immediate");
947 #define entry(name) \
953 #define entry_ca(name) \
957 make_arg(jit_##name()); \
959 #define entry_ia(name) \
963 jit_gpr_t r0 = get_ireg(); \
964 jit_pointer_t ac = get_arg(); \
965 jit_##name(r0, ac); \
967 #define entry_im(name) \
971 jit_word_t im = get_imm(); \
974 #define entry_ir(name) \
978 jit_gpr_t r0 = get_ireg(); \
981 #define entry_ima(name) \
985 jit_word_t im = get_imm(); \
986 jit_pointer_t ac = get_arg(); \
987 jit_##name(im, ac); \
989 #define entry_ir_ir_ir(name) \
993 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(), r2 = get_ireg(); \
994 jit_##name(r0, r1, r2); \
996 #define entry_ir_ir_im(name) \
1000 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \
1001 jit_word_t im = get_imm(); \
1002 jit_##name(r0, r1, im); \
1004 #define entry_ir_ir_ir_ir(name) \
1008 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(), \
1009 r2 = get_ireg(), r3 = get_ireg(); \
1010 jit_##name(r0, r1, r2, r3); \
1012 #define entry_ir_ir_ir_im(name) \
1016 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(), r2 = get_ireg(); \
1017 jit_word_t im = get_imm(); \
1018 jit_##name(r0, r1, r2, im); \
1020 #define entry_ir_ir(name) \
1024 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \
1025 jit_##name(r0, r1); \
1027 #define entry_ir_im(name) \
1031 jit_gpr_t r0 = get_ireg(); \
1032 jit_word_t im = get_imm(); \
1033 jit_##name(r0, im); \
1035 #define entry_ir_pm(name) \
1039 jit_gpr_t r0 = get_ireg(); \
1040 void *pm = get_pointer(skip_ws); \
1041 jit_##name(r0, pm); \
1043 #define entry_pm_ir(name) \
1047 void *pm = get_pointer(skip_ws); \
1048 jit_gpr_t r0 = get_ireg(); \
1049 jit_##name(pm, r0); \
1051 #define entry_im_ir_ir(name) \
1055 jit_word_t im = get_imm(); \
1056 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \
1057 (void)jit_##name(im, r0, r1); \
1059 #define entry_lb_ir_ir(name) \
1064 label_t *label = get_label(skip_ws); \
1065 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \
1066 if (label->kind == label_kind_code_forward) \
1067 jmp_forward((void *)jit_##name(r0, r1), label); \
1069 jmp = jit_##name(r0, r1); \
1070 jit_patch_at(jmp, (jit_node_t *)label->value); \
1073 #define entry_lb_ir_im(name) \
1078 label_t *label = get_label(skip_ws); \
1079 jit_gpr_t r0 = get_ireg(); \
1080 jit_word_t im = get_imm(); \
1081 if (label->kind == label_kind_code_forward) \
1082 jmp_forward((void *)jit_##name(r0, im), label); \
1084 jmp = jit_##name(r0, im); \
1085 jit_patch_at(jmp, (jit_node_t *)label->value); \
1088 #define entry_lb(name) \
1093 label_t *label = get_label(skip_ws); \
1094 if (label->kind == label_kind_code_forward) \
1095 jmp_forward((void *)jit_##name(), label); \
1097 jmp = jit_##name(); \
1098 jit_patch_at(jmp, (jit_node_t *)label->value); \
1101 #define entry_pm(name) \
1105 void *pm = get_pointer(skip_ws); \
1108 #define entry_fa(name) \
1112 jit_fpr_t r0 = get_freg(); \
1113 jit_pointer_t ac = get_arg(); \
1114 jit_##name(r0, ac); \
1116 #define entry_fma(name) \
1120 jit_float64_t im = get_float(skip_ws); \
1121 jit_pointer_t ac = get_arg(); \
1122 jit_##name(im, ac); \
1124 #define entry_fr_fr_fr(name) \
1128 jit_fpr_t r0 = get_freg(), r1 = get_freg(), r2 = get_freg(); \
1129 jit_##name(r0, r1, r2); \
1131 #define entry_fr_fr_fm(name) \
1135 jit_fpr_t r0 = get_freg(), r1 = get_freg(); \
1136 jit_float64_t im = get_float(skip_ws); \
1137 jit_##name(r0, r1, make_float(im)); \
1139 #define entry_fr_fr_dm(name) \
1143 jit_fpr_t r0 = get_freg(), r1 = get_freg(); \
1144 jit_float64_t im = get_float(skip_ws); \
1145 jit_##name(r0, r1, im); \
1147 #define entry_fr_fr(name) \
1151 jit_fpr_t r0 = get_freg(), r1 = get_freg(); \
1152 jit_##name(r0, r1); \
1154 #define entry_ir_fr_fr(name) \
1158 jit_gpr_t r0 = get_ireg(); \
1159 jit_fpr_t r1 = get_freg(), r2 = get_freg(); \
1160 jit_##name(r0, r1, r2); \
1162 #define entry_ir_fr_fm(name) \
1166 jit_gpr_t r0 = get_ireg(); \
1167 jit_fpr_t r1 = get_freg(); \
1168 jit_float64_t im = get_float(skip_ws); \
1169 jit_##name(r0, r1, make_float(im)); \
1171 #define entry_ir_fr_dm(name) \
1175 jit_gpr_t r0 = get_ireg(); \
1176 jit_fpr_t r1 = get_freg(); \
1177 jit_float64_t im = get_float(skip_ws); \
1178 jit_##name(r0, r1, im); \
1180 #define entry_ir_fr(name) \
1184 jit_gpr_t r0 = get_ireg(); \
1185 jit_fpr_t r1 = get_freg(); \
1186 jit_##name(r0, r1); \
1188 #define entry_fr_ir(name) \
1192 jit_fpr_t r0 = get_freg(); \
1193 jit_gpr_t r1 = get_ireg(); \
1194 jit_##name(r0, r1); \
1196 #define entry_fr_fm(name) \
1200 jit_fpr_t r0 = get_freg(); \
1201 jit_float64_t im = get_float(skip_ws); \
1202 jit_##name(r0, make_float(im)); \
1204 #define entry_fr_dm(name) \
1208 jit_fpr_t r0 = get_freg(); \
1209 jit_float64_t im = get_float(skip_ws); \
1210 jit_##name(r0, im); \
1212 #define entry_fr_pm(name) \
1216 jit_fpr_t r0 = get_freg(); \
1217 void *pm = get_pointer(skip_ws); \
1218 jit_##name(r0, pm); \
1220 #define entry_fr_ir_ir(name) \
1224 jit_fpr_t r0 = get_freg(); \
1225 jit_gpr_t r1 = get_ireg(), r2 = get_ireg(); \
1226 jit_##name(r0, r1, r2); \
1228 #define entry_fr_ir_im(name) \
1232 jit_fpr_t r0 = get_freg(); \
1233 jit_gpr_t r1 = get_ireg(); \
1234 jit_word_t im = get_imm(); \
1235 jit_##name(r0, r1, im); \
1237 #define entry_pm_fr(name) \
1241 void *pm = get_pointer(skip_ws); \
1242 jit_fpr_t r0 = get_freg(); \
1243 jit_##name(pm, r0); \
1245 #define entry_ir_ir_fr(name) \
1249 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \
1250 jit_fpr_t r2 = get_freg(); \
1251 jit_##name(r0, r1, r2); \
1253 #define entry_im_ir_fr(name) \
1257 jit_word_t im = get_imm(); \
1258 jit_gpr_t r0 = get_ireg(); \
1259 jit_fpr_t r1 = get_freg(); \
1260 jit_##name(im, r0, r1); \
1262 #define entry_lb_fr_fr(name) \
1267 label_t *label = get_label(skip_ws); \
1268 jit_fpr_t r0 = get_freg(), r1 = get_freg(); \
1269 if (label->kind == label_kind_code_forward) \
1270 jmp_forward((void *)jit_##name(r0, r1), label); \
1272 jmp = jit_##name(r0, r1); \
1273 jit_patch_at(jmp, (jit_node_t *)label->value); \
1276 #define entry_lb_fr_fm(name) \
1281 label_t *label = get_label(skip_ws); \
1282 jit_fpr_t r0 = get_freg(); \
1283 jit_float64_t im = get_float(skip_ws); \
1284 if (label->kind == label_kind_code_forward) \
1285 jmp_forward((void *)jit_##name(r0, make_float(im)), label); \
1287 jmp = jit_##name(r0, make_float(im)); \
1288 jit_patch_at(jmp, (jit_node_t *)label->value); \
1291 #define entry_lb_fr_dm(name) \
1296 label_t *label = get_label(skip_ws); \
1297 jit_fpr_t r0 = get_freg(); \
1298 jit_float64_t im = get_float(skip_ws); \
1299 if (label->kind == label_kind_code_forward) \
1300 jmp_forward((void *)jit_##name(r0, im), label); \
1302 jmp = jit_##name(r0, im); \
1303 jit_patch_at(jmp, (jit_node_t *)label->value); \
1306 #define entry_fr(name) \
1310 jit_fpr_t r0 = get_freg(); \
1313 #define entry_fm(name) \
1317 jit_float64_t im = get_float(skip_ws); \
1318 jit_##name(make_float(im)); \
1320 #define entry_dm(name) \
1324 jit_float64_t im = get_float(skip_ws); \
1327 #define entry_fn(name) \
1338 value = (void *)(jit_word_t)get_uint(skip_none); \
1341 switch (expression()) { \
1343 value = (void *)parser.value.i; \
1346 value = parser.value.p; \
1349 error("expecting pointer"); \
1354 value = parser.value.p; \
1358 label = get_label(skip_none); \
1359 if (label->kind == label_kind_code_forward) \
1360 call_forward((void *)jit_##name(NULL), label); \
1362 jit_patch_at(jit_##name(NULL), label->value); \
1365 jit_##name(value); \
1370 (void)identifier(ch);
1371 jit_name(parser.string);
1375 if (primary(skip_ws) != tok_register)
1376 error("bad register");
1377 jit_live(parser.regval);
1381 entry_im(frame) entry_im(tramp)
1386 jit_word_t i, im = get_imm();
1387 i = jit_allocai(im);
1388 symbol = get_symbol();
1389 symbol->type = type_l;
1390 symbol->value.i = i;
1392 entry_ir_ir(allocar)
1394 entry_ia(getarg_c) entry_ia(getarg_uc)
1395 entry_ia(getarg_s) entry_ia(getarg_us)
1397 #if __WORDSIZE == 64
1398 entry_ia(getarg_ui) entry_ia(getarg_l)
1401 entry_ia(putargr) entry_ima(putargi)
1402 entry_ir_ir_ir(addr) entry_ir_ir_im(addi)
1403 entry_ir_ir_ir(addxr) entry_ir_ir_im(addxi)
1404 entry_ir_ir_ir(addcr) entry_ir_ir_im(addci)
1405 entry_ir_ir_ir(subr) entry_ir_ir_im(subi)
1406 entry_ir_ir_ir(subxr) entry_ir_ir_im(subxi)
1407 entry_ir_ir_ir(subcr) entry_ir_ir_im(subci)
1408 entry_ir_ir_ir(rsbr) entry_ir_ir_im(rsbi)
1409 entry_ir_ir_ir(mulr) entry_ir_ir_im(muli)
1410 entry_ir_ir_ir_ir(qmulr) entry_ir_ir_ir_im(qmuli)
1411 entry_ir_ir_ir_ir(qmulr_u) entry_ir_ir_ir_im(qmuli_u)
1412 entry_ir_ir_ir(divr) entry_ir_ir_im(divi)
1413 entry_ir_ir_ir(divr_u) entry_ir_ir_im(divi_u)
1414 entry_ir_ir_ir_ir(qdivr) entry_ir_ir_ir_im(qdivi)
1415 entry_ir_ir_ir_ir(qdivr_u) entry_ir_ir_ir_im(qdivi_u)
1416 entry_ir_ir_ir(remr) entry_ir_ir_im(remi)
1417 entry_ir_ir_ir(remr_u) entry_ir_ir_im(remi_u)
1418 entry_ir_ir_ir(andr) entry_ir_ir_im(andi)
1419 entry_ir_ir_ir(orr) entry_ir_ir_im(ori)
1420 entry_ir_ir_ir(xorr) entry_ir_ir_im(xori)
1421 entry_ir_ir_ir(lshr) entry_ir_ir_im(lshi)
1422 entry_ir_ir_ir(rshr) entry_ir_ir_im(rshi)
1423 entry_ir_ir_ir(rshr_u) entry_ir_ir_im(rshi_u)
1424 entry_ir_ir(negr) entry_ir_ir(comr)
1425 entry_ir_ir_ir(ltr) entry_ir_ir_im(lti)
1426 entry_ir_ir_ir(ltr_u) entry_ir_ir_im(lti_u)
1427 entry_ir_ir_ir(ler) entry_ir_ir_im(lei)
1428 entry_ir_ir_ir(ler_u) entry_ir_ir_im(lei_u)
1429 entry_ir_ir_ir(eqr) entry_ir_ir_im(eqi)
1430 entry_ir_ir_ir(ger) entry_ir_ir_im(gei)
1431 entry_ir_ir_ir(ger_u) entry_ir_ir_im(gei_u)
1432 entry_ir_ir_ir(gtr) entry_ir_ir_im(gti)
1433 entry_ir_ir_ir(gtr_u) entry_ir_ir_im(gti_u)
1434 entry_ir_ir_ir(ner) entry_ir_ir_im(nei)
1442 jit_gpr_t r0 = get_ireg();
1448 value = (void *)(jit_word_t)get_uint(skip_none);
1452 value = (void *)parser.value.i;
1455 switch (expression()) {
1457 value = (void *)parser.value.i;
1460 value = parser.value.p;
1463 error("expecting pointer");
1468 value = parser.value.p;
1472 label = get_label(skip_none);
1473 if (label->kind == label_kind_code ||
1474 label->kind == label_kind_code_forward) {
1475 mov_forward((void *)jit_movi(r0, 0), label);
1478 value = label->value;
1481 jit_movi(r0, (jit_word_t)value);
1483 entry_ir_ir(extr_c) entry_ir_ir(extr_uc)
1484 entry_ir_ir(extr_s) entry_ir_ir(extr_us)
1485 #if __WORDSIZE == 64
1486 entry_ir_ir(extr_i) entry_ir_ir(extr_ui)
1488 entry_ir_ir(htonr_us) entry_ir_ir(ntohr_us)
1489 entry_ir_ir(htonr_ui) entry_ir_ir(ntohr_ui)
1490 #if __WORDSIZE == 64
1491 entry_ir_ir(htonr_ul) entry_ir_ir(ntohr_ul)
1493 entry_ir_ir(htonr) entry_ir_ir(ntohr)
1494 entry_ir_ir_ir(movnr) entry_ir_ir_ir(movzr)
1495 entry_ir_ir(ldr_c) entry_ir_pm(ldi_c)
1496 entry_ir_ir(ldr_uc) entry_ir_pm(ldi_uc)
1497 entry_ir_ir(ldr_s) entry_ir_pm(ldi_s)
1498 entry_ir_ir(ldr_us) entry_ir_pm(ldi_us)
1499 entry_ir_ir(ldr_i) entry_ir_pm(ldi_i)
1500 #if __WORDSIZE == 64
1501 entry_ir_ir(ldr_ui) entry_ir_pm(ldi_ui)
1502 entry_ir_ir(ldr_l) entry_ir_pm(ldi_l)
1504 entry_ir_ir(ldr) entry_ir_pm(ldi)
1505 entry_ir_ir_ir(ldxr_c) entry_ir_ir_im(ldxi_c)
1506 entry_ir_ir_ir(ldxr_uc) entry_ir_ir_im(ldxi_uc)
1507 entry_ir_ir_ir(ldxr_s) entry_ir_ir_im(ldxi_s)
1508 entry_ir_ir_ir(ldxr_us) entry_ir_ir_im(ldxi_us)
1509 entry_ir_ir_ir(ldxr_i) entry_ir_ir_im(ldxi_i)
1510 #if __WORDSIZE == 64
1511 entry_ir_ir_ir(ldxr_ui) entry_ir_ir_im(ldxi_ui)
1512 entry_ir_ir_ir(ldxr_l) entry_ir_ir_im(ldxi_l)
1514 entry_ir_ir_ir(ldxr) entry_ir_ir_im(ldxi)
1515 entry_ir_ir(str_c) entry_pm_ir(sti_c)
1516 entry_ir_ir(str_s) entry_pm_ir(sti_s)
1517 entry_ir_ir(str_i) entry_pm_ir(sti_i)
1518 #if __WORDSIZE == 64
1519 entry_ir_ir(str_l) entry_pm_ir(sti_l)
1521 entry_ir_ir(str) entry_pm_ir(sti)
1522 entry_ir_ir_ir(stxr_c) entry_im_ir_ir(stxi_c)
1523 entry_ir_ir_ir(stxr_s) entry_im_ir_ir(stxi_s)
1524 entry_ir_ir_ir(stxr_i) entry_im_ir_ir(stxi_i)
1525 #if __WORDSIZE == 64
1526 entry_ir_ir_ir(stxr_l) entry_im_ir_ir(stxi_l)
1528 entry_ir_ir_ir(stxr) entry_im_ir_ir(stxi)
1529 entry_lb_ir_ir(bltr) entry_lb_ir_im(blti)
1530 entry_lb_ir_ir(bltr_u) entry_lb_ir_im(blti_u)
1531 entry_lb_ir_ir(bler) entry_lb_ir_im(blei)
1532 entry_lb_ir_ir(bler_u) entry_lb_ir_im(blei_u)
1533 entry_lb_ir_ir(beqr) entry_lb_ir_im(beqi)
1534 entry_lb_ir_ir(bger) entry_lb_ir_im(bgei)
1535 entry_lb_ir_ir(bger_u) entry_lb_ir_im(bgei_u)
1536 entry_lb_ir_ir(bgtr) entry_lb_ir_im(bgti)
1537 entry_lb_ir_ir(bgtr_u) entry_lb_ir_im(bgti_u)
1538 entry_lb_ir_ir(bner) entry_lb_ir_im(bnei)
1539 entry_lb_ir_ir(bmsr) entry_lb_ir_im(bmsi)
1540 entry_lb_ir_ir(bmcr) entry_lb_ir_im(bmci)
1541 entry_lb_ir_ir(boaddr) entry_lb_ir_im(boaddi)
1542 entry_lb_ir_ir(boaddr_u) entry_lb_ir_im(boaddi_u)
1543 entry_lb_ir_ir(bxaddr) entry_lb_ir_im(bxaddi)
1544 entry_lb_ir_ir(bxaddr_u) entry_lb_ir_im(bxaddi_u)
1545 entry_lb_ir_ir(bosubr) entry_lb_ir_im(bosubi)
1546 entry_lb_ir_ir(bosubr_u) entry_lb_ir_im(bosubi_u)
1547 entry_lb_ir_ir(bxsubr) entry_lb_ir_im(bxsubi)
1548 entry_lb_ir_ir(bxsubr_u) entry_lb_ir_im(bxsubi_u)
1549 entry_ir(jmpr) entry_lb(jmpi)
1550 entry_ir(callr) entry_fn(calli)
1552 entry_ir(pushargr) entry_im(pushargi)
1553 entry_ir(finishr) entry_fn(finishi)
1555 entry_ir(retr) entry_im(reti)
1556 entry_ir(retval_c) entry_ir(retval_uc)
1557 entry_ir(retval_s) entry_ir(retval_us)
1559 #if __WORDSIZE == 64
1560 entry_ir(retval_ui) entry_ir(retval_l)
1564 entry_ca(arg_f) entry_fa(getarg_f)
1565 entry_fa(putargr_f) entry_fma(putargi_f)
1566 entry_fr_fr_fr(addr_f) entry_fr_fr_fm(addi_f)
1567 entry_fr_fr_fr(subr_f) entry_fr_fr_fm(subi_f)
1568 entry_fr_fr_fr(rsbr_f) entry_fr_fr_fm(rsbi_f)
1569 entry_fr_fr_fr(mulr_f) entry_fr_fr_fm(muli_f)
1570 entry_fr_fr_fr(divr_f) entry_fr_fr_fm(divi_f)
1571 entry_fr_fr(negr_f) entry_fr_fr(absr_f)
1572 entry_fr_fr(sqrtr_f)
1573 entry_ir_fr_fr(ltr_f) entry_ir_fr_fm(lti_f)
1574 entry_ir_fr_fr(ler_f) entry_ir_fr_fm(lei_f)
1575 entry_ir_fr_fr(eqr_f) entry_ir_fr_fm(eqi_f)
1576 entry_ir_fr_fr(ger_f) entry_ir_fr_fm(gei_f)
1577 entry_ir_fr_fr(gtr_f) entry_ir_fr_fm(gti_f)
1578 entry_ir_fr_fr(ner_f) entry_ir_fr_fm(nei_f)
1579 entry_ir_fr_fr(unltr_f) entry_ir_fr_fm(unlti_f)
1580 entry_ir_fr_fr(unler_f) entry_ir_fr_fm(unlei_f)
1581 entry_ir_fr_fr(uneqr_f) entry_ir_fr_fm(uneqi_f)
1582 entry_ir_fr_fr(unger_f) entry_ir_fr_fm(ungei_f)
1583 entry_ir_fr_fr(ungtr_f) entry_ir_fr_fm(ungti_f)
1584 entry_ir_fr_fr(ltgtr_f) entry_ir_fr_fm(ltgti_f)
1585 entry_ir_fr_fr(ordr_f) entry_ir_fr_fm(ordi_f)
1586 entry_ir_fr_fr(unordr_f) entry_ir_fr_fm(unordi_f)
1587 entry_ir_fr(truncr_f_i)
1588 #if __WORDSIZE == 64
1589 entry_ir_fr(truncr_f_l)
1591 entry_ir_fr(truncr_f)
1592 entry_fr_ir(extr_f) entry_fr_fr(extr_d_f)
1593 entry_fr_fr(movr_f) entry_fr_fm(movi_f)
1594 entry_fr_ir(ldr_f) entry_fr_pm(ldi_f)
1595 entry_fr_ir_ir(ldxr_f) entry_fr_ir_im(ldxi_f)
1596 entry_ir_fr(str_f) entry_pm_fr(sti_f)
1597 entry_ir_ir_fr(stxr_f) entry_im_ir_fr(stxi_f)
1598 entry_lb_fr_fr(bltr_f) entry_lb_fr_fm(blti_f)
1599 entry_lb_fr_fr(bler_f) entry_lb_fr_fm(blei_f)
1600 entry_lb_fr_fr(beqr_f) entry_lb_fr_fm(beqi_f)
1601 entry_lb_fr_fr(bger_f) entry_lb_fr_fm(bgei_f)
1602 entry_lb_fr_fr(bgtr_f) entry_lb_fr_fm(bgti_f)
1603 entry_lb_fr_fr(bner_f) entry_lb_fr_fm(bnei_f)
1604 entry_lb_fr_fr(bunltr_f) entry_lb_fr_fm(bunlti_f)
1605 entry_lb_fr_fr(bunler_f) entry_lb_fr_fm(bunlei_f)
1606 entry_lb_fr_fr(buneqr_f) entry_lb_fr_fm(buneqi_f)
1607 entry_lb_fr_fr(bunger_f) entry_lb_fr_fm(bungei_f)
1608 entry_lb_fr_fr(bungtr_f) entry_lb_fr_fm(bungti_f)
1609 entry_lb_fr_fr(bltgtr_f) entry_lb_fr_fm(bltgti_f)
1610 entry_lb_fr_fr(bordr_f) entry_lb_fr_fm(bordi_f)
1611 entry_lb_fr_fr(bunordr_f) entry_lb_fr_fm(bunordi_f)
1612 entry_fr(pushargr_f) entry_fm(pushargi_f)
1613 entry_fr(retr_f) entry_fm(reti_f)
1615 entry_ca(arg_d) entry_fa(getarg_d)
1616 entry_fa(putargr_d) entry_fma(putargi_d)
1617 entry_fr_fr_fr(addr_d) entry_fr_fr_dm(addi_d)
1618 entry_fr_fr_fr(subr_d) entry_fr_fr_dm(subi_d)
1619 entry_fr_fr_fr(rsbr_d) entry_fr_fr_dm(rsbi_d)
1620 entry_fr_fr_fr(mulr_d) entry_fr_fr_dm(muli_d)
1621 entry_fr_fr_fr(divr_d) entry_fr_fr_dm(divi_d)
1622 entry_fr_fr(negr_d) entry_fr_fr(absr_d)
1623 entry_fr_fr(sqrtr_d)
1624 entry_ir_fr_fr(ltr_d) entry_ir_fr_dm(lti_d)
1625 entry_ir_fr_fr(ler_d) entry_ir_fr_dm(lei_d)
1626 entry_ir_fr_fr(eqr_d) entry_ir_fr_dm(eqi_d)
1627 entry_ir_fr_fr(ger_d) entry_ir_fr_dm(gei_d)
1628 entry_ir_fr_fr(gtr_d) entry_ir_fr_dm(gti_d)
1629 entry_ir_fr_fr(ner_d) entry_ir_fr_dm(nei_d)
1630 entry_ir_fr_fr(unltr_d) entry_ir_fr_dm(unlti_d)
1631 entry_ir_fr_fr(unler_d) entry_ir_fr_dm(unlei_d)
1632 entry_ir_fr_fr(uneqr_d) entry_ir_fr_dm(uneqi_d)
1633 entry_ir_fr_fr(unger_d) entry_ir_fr_dm(ungei_d)
1634 entry_ir_fr_fr(ungtr_d) entry_ir_fr_dm(ungti_d)
1635 entry_ir_fr_fr(ltgtr_d) entry_ir_fr_dm(ltgti_d)
1636 entry_ir_fr_fr(ordr_d) entry_ir_fr_dm(ordi_d)
1637 entry_ir_fr_fr(unordr_d) entry_ir_fr_dm(unordi_d)
1638 entry_ir_fr(truncr_d_i)
1639 #if __WORDSIZE == 64
1640 entry_ir_fr(truncr_d_l)
1642 entry_ir_fr(truncr_d)
1643 entry_fr_ir(extr_d) entry_fr_fr(extr_f_d)
1644 entry_fr_fr(movr_d) entry_fr_dm(movi_d)
1645 entry_fr_ir(ldr_d) entry_fr_pm(ldi_d)
1646 entry_fr_ir_ir(ldxr_d) entry_fr_ir_im(ldxi_d)
1647 entry_ir_fr(str_d) entry_pm_fr(sti_d)
1648 entry_ir_ir_fr(stxr_d) entry_im_ir_fr(stxi_d)
1649 entry_lb_fr_fr(bltr_d) entry_lb_fr_dm(blti_d)
1650 entry_lb_fr_fr(bler_d) entry_lb_fr_dm(blei_d)
1651 entry_lb_fr_fr(beqr_d) entry_lb_fr_dm(beqi_d)
1652 entry_lb_fr_fr(bger_d) entry_lb_fr_dm(bgei_d)
1653 entry_lb_fr_fr(bgtr_d) entry_lb_fr_dm(bgti_d)
1654 entry_lb_fr_fr(bner_d) entry_lb_fr_dm(bnei_d)
1655 entry_lb_fr_fr(bunltr_d) entry_lb_fr_dm(bunlti_d)
1656 entry_lb_fr_fr(bunler_d) entry_lb_fr_dm(bunlei_d)
1657 entry_lb_fr_fr(buneqr_d) entry_lb_fr_dm(buneqi_d)
1658 entry_lb_fr_fr(bunger_d) entry_lb_fr_dm(bungei_d)
1659 entry_lb_fr_fr(bungtr_d) entry_lb_fr_dm(bungti_d)
1660 entry_lb_fr_fr(bltgtr_d) entry_lb_fr_dm(bltgti_d)
1661 entry_lb_fr_fr(bordr_d) entry_lb_fr_dm(bordi_d)
1662 entry_lb_fr_fr(bunordr_d) entry_lb_fr_dm(bunordi_d)
1663 entry_fr(pushargr_d) entry_dm(pushargi_d)
1664 entry_fr(retr_d) entry_dm(reti_d)
1669 jit_gpr_t r0 = get_ireg();
1675 jit_gpr_t r0 = get_ireg();
1681 jit_gpr_t r0 = get_ireg(), r1 = get_ireg();
1687 jit_fpr_t r0 = get_freg();
1688 jit_gpr_t r1 = get_ireg();
1689 jit_va_arg_d(r0, r1);
1694 jit_gpr_t r0 = get_ireg();
1700 #undef entry_lb_fr_fm
1701 #undef entry_lb_fr_dm
1702 #undef entry_lb_fr_fr
1703 #undef entry_im_ir_fr
1704 #undef entry_ir_ir_fr
1706 #undef entry_fr_ir_ir
1707 #undef entry_fr_ir_im
1713 #undef entry_ir_fr_fm
1714 #undef entry_ir_fr_dm
1715 #undef entry_ir_fr_fr
1717 #undef entry_fr_fr_fm
1718 #undef entry_fr_fr_dm
1719 #undef entry_fr_fr_fr
1724 #undef entry_lb_ir_im
1725 #undef entry_lb_ir_ir
1726 #undef entry_im_ir_ir
1731 #undef entry_ir_ir_im
1732 #undef entry_ir_ir_ir
1741 error(const char *format, ...)
1747 va_start(ap, format);
1748 message("error", format, ap);
1750 length = parser.data.length - parser.data.offset;
1751 string = (char *)(parser.data.buffer + parser.data.offset - 1);
1753 strcpy(string + 74, "...");
1755 parser.data.buffer[parser.data.length - 1] = '\0';
1756 fprintf(stderr, "(%s)\n", string);
1761 warn(const char *format, ...)
1764 va_start(ap, format);
1765 message("warning", format, ap);
1770 message(const char *kind, const char *format, va_list ap)
1772 fprintf(stderr, "%s:%d: %s: ", parser.name,
1773 parser.line - parser.newline, kind);
1774 vfprintf(stderr, format, ap);
1775 fputc('\n', stderr);
1783 if (parser.data.offset < parser.data.length)
1784 ch = parser.data.buffer[parser.data.offset++];
1786 /* keep first offset for ungetch */
1787 if ((parser.data.length = fread(parser.data.buffer + 1, 1,
1788 sizeof(parser.data.buffer) - 1,
1789 parser.fp) + 1) <= 1) {
1791 parser.data.offset = 1;
1794 ch = parser.data.buffer[1];
1795 parser.data.offset = 2;
1798 if ((parser.newline = ch == '\n'))
1810 error("unexpected end of file");
1818 if ((parser.newline = ch == '\n'))
1821 if (parser.data.offset)
1822 parser.data.buffer[--parser.data.offset] = ch;
1825 parser.data.buffer[0] = ch;
1835 for (ch = getch();; ch = getch()) {
1845 case ' ': case '\f': case '\r': case '\t':
1858 for (ch = getch();; ch = getch()) {
1868 case ' ': case '\f': case '\n': case '\r': case '\t':
1870 /* handle as newline */
1887 for (ch = getch(); ch != '\n' && ch != EOF; ch = getch())
1891 for (; ch != '/';) {
1892 while (getch_noeof() != '*')
1894 while ((ch = getch_noeof()) == '*')
1909 for (ch = getch(); ch != '\n' && ch != EOF; ch = getch()) {
1912 if ((number(ch)) == tok_int)
1913 parser.line = parser.value.i - 1;
1917 if (parser.offset >= (int)sizeof(parser.name)) {
1918 strncpy(parser.name, parser.string, sizeof(parser.name));
1919 parser.name[sizeof(parser.name) - 1] = '\0';
1922 strcpy(parser.name, parser.string);
1933 get_int(skip_t skip)
1935 switch (primary(skip)) {
1939 parser.type = type_l;
1940 parser.value.i = (jit_word_t)parser.value.p;
1943 error("expecting integer");
1946 return (parser.value.i);
1950 get_uint(skip_t skip)
1952 switch (primary(skip)) {
1953 case tok_char: case tok_int:
1956 parser.type = type_l;
1957 parser.value.ui = (jit_uword_t)parser.value.p;
1960 error("expecting integer");
1963 return (parser.value.ui);
1967 get_float(skip_t skip)
1969 switch (primary(skip)) {
1972 parser.type = type_d;
1973 parser.value.d = parser.value.i;
1978 error("expecting float");
1981 return (parser.value.d);
1984 /* Workaround gcc not converting unordered values from double to
1985 * float (as done in other architectures) on s390 */
1987 make_float(double d)
1989 /* This is an workaround to a bug in Hercules s390 emulator,
1990 * and at least HP-UX ia64 not have these */
1991 #if defined(HAVE_ISNAN) && defined(HAVE_ISINF)
1992 if (isnan(d)) return ( 0.0f/0.0f);
1994 if (d > 0.0) return ( 1.0f/0.0f);
1995 else return (-1.0f/0.0f);
2002 get_pointer(skip_t skip)
2005 token_t token = primary(skip);
2009 label = get_label_by_name(parser.string);
2011 error("bad identifier %s", parser.string);
2012 switch (label->kind) {
2013 case label_kind_data:
2014 case label_kind_code:
2016 case label_kind_code_forward:
2017 /* as expression arguments */
2018 error("forward references not implemented");
2020 case label_kind_dynamic:
2023 parser.type = type_p;
2024 return (parser.value.p = label->value);
2026 parser.type = type_p;
2027 return (parser.value.p = (void *)parser.value.ui);
2029 return (parser.value.p);
2030 default: error("bad pointer");
2035 get_label(skip_t skip)
2044 case 'a' ... 'z': case 'A' ... 'Z': case '_':
2045 (void)identifier(ch);
2048 error("expecting label/immediate");
2050 if ((label = get_label_by_name(parser.string)) == NULL)
2051 label = new_label(label_kind_code_forward,
2052 parser.string, jit_forward());
2061 int check = 1, ch = getch();
2065 parser.regtype = type_l;
2066 switch (ch = getch()) {
2067 case '0': parser.regval = JIT_R0; break;
2068 case '1': parser.regval = JIT_R1; break;
2069 case '2': parser.regval = JIT_R2; break;
2071 num = get_int(skip_none);
2072 if (num < 0 || num >= JIT_R_NUM) goto fail;
2073 parser.regval = JIT_R(num);
2074 if (getch() != ')') goto fail;
2081 parser.regtype = type_l;
2082 switch (ch = getch()) {
2083 case '0': parser.regval = JIT_V0; break;
2084 case '1': parser.regval = JIT_V1; break;
2085 case '2': parser.regval = JIT_V2; break;
2088 num = get_int(skip_none);
2089 if (num < 0 || num >= JIT_V_NUM) goto fail;
2090 parser.regval = JIT_V(num);
2091 if (getch() != ')') goto fail;
2097 parser.regtype = type_d;
2098 switch (ch = getch()) {
2099 case '0': parser.regval = JIT_F0; break;
2100 case '1': parser.regval = JIT_F1; break;
2101 case '2': parser.regval = JIT_F2; break;
2102 case '3': parser.regval = JIT_F3; break;
2103 case '4': parser.regval = JIT_F4; break;
2104 case '5': parser.regval = JIT_F5; break;
2106 parser.regtype = type_l; /* oops */
2107 parser.regval = JIT_FP; break;
2109 num = get_int(skip_none);
2110 if (num < 0 || num >= JIT_F_NUM) goto fail;
2111 parser.regval = JIT_F(num);
2112 if (getch() != ')') goto fail;
2120 error("bad register");
2124 if ((ch >= 'a' && ch <= 'z') ||
2125 (ch >= 'A' && ch <= 'Z') ||
2126 (ch >= '0' && ch <= '9') ||
2132 return (tok_register);
2138 parser.string[0] = ch;
2139 for (parser.offset = 1;;) {
2140 switch ((ch = getch())) {
2141 case 'a' ... 'z': case 'A' ... 'Z': case '0' ... '9' : case '_':
2142 if (parser.offset + 1 >= MAX_IDENTIFIER) {
2143 parser.string[parser.offset] = '\0';
2144 error("bad identifier %s", parser.string);
2146 parser.string[parser.offset++] = ch;
2149 parser.string[parser.offset] = '\0';
2151 return (tok_symbol);
2157 get_data(type_t type)
2166 switch (token = primary(skip_ws)) {
2167 case tok_char: case tok_int:
2168 check_data(sizeof(signed char));
2169 *(signed char *)(data + data_offset) = parser.value.i;
2170 data_offset += sizeof(char);
2173 check_data(parser.offset);
2174 memcpy(data + data_offset, parser.string,
2176 data_offset += parser.offset;
2179 case tok_semicollon:
2180 if (test == data) error("syntax error");
2182 default: error("bad initializer");
2186 check_data(sizeof(signed short));
2187 *(signed short *)(data + data_offset) = get_int(skip_ws);
2188 data_offset += sizeof(short);
2191 check_data(sizeof(signed int));
2192 *(signed int *)(data + data_offset) = get_int(skip_ws);
2193 data_offset += sizeof(int);
2196 check_data(sizeof(jit_word_t));
2197 *(jit_word_t *)(data + data_offset) = get_int(skip_ws);
2198 data_offset += sizeof(jit_word_t);
2201 check_data(sizeof(float));
2202 *(float *)(data + data_offset) = get_float(skip_ws);
2203 data_offset += sizeof(float);
2206 check_data(sizeof(double));
2207 *(double *)(data + data_offset) = get_float(skip_ws);
2208 data_offset += sizeof(double);
2211 /* FIXME **patch if realloc** */
2212 check_data(sizeof(void*));
2213 *(void **)(data + data_offset) = get_pointer(skip_ws);
2214 data_offset += sizeof(void*);
2220 if (ch == '\n' || ch == ';' || ch == EOF)
2230 size_t offset, length;
2232 switch (ch = getch_noeof()) {
2234 /* use .$(expression) for non side effects expression */
2237 case 'a' ... 'z': case 'A' ... 'Z': case '_':
2238 (void)identifier(ch);
2242 if (skipws() != '$')
2243 error("expecting symbol");
2244 /* allow spaces before an expression */
2248 if (parser.string[1] == '\0') {
2249 switch (parser.string[0]) {
2250 case 'c': get_data(type_c); break;
2251 case 's': get_data(type_s); break;
2252 case 'i': get_data(type_i); break;
2253 case 'l': get_data(type_l); break;
2254 case 'f': get_data(type_f); break;
2255 case 'd': get_data(type_d); break;
2256 case 'p': get_data(type_p); break;
2257 default: error("bad type .%c", parser.string[0]);
2260 else if (strcmp(parser.string, "data") == 0) {
2261 if (parser.parsing != PARSING_NONE)
2262 error(".data must be specified once and be the first section");
2263 parser.parsing = PARSING_DATA;
2264 data_length = get_int(skip_ws);
2265 data = (char *)xcalloc(1, data_length);
2267 else if (strcmp(parser.string, "code") == 0) {
2268 if (parser.parsing != PARSING_NONE &&
2269 parser.parsing != PARSING_DATA)
2270 error(".code must be specified once only");
2271 parser.parsing = PARSING_CODE;
2273 else if (strcmp(parser.string, "align") == 0) {
2274 length = get_int(skip_ws);
2275 if (parser.parsing != PARSING_DATA)
2276 error(".align must be in .data");
2277 if (length > 1 && length <= 4096 && !(length & (length - 1))) {
2278 offset = data_offset;
2279 offset += length - ((offset + length) % length);
2280 check_data(offset - data_offset);
2281 data_offset = offset;
2284 error("bad .align %ld (must be a power of 2, >= 2 && <= 4096)",
2285 (jit_word_t)length);
2287 else if (strcmp(parser.string, "size") == 0) {
2288 length = get_int(skip_ws);
2289 if (parser.parsing != PARSING_DATA)
2290 error(".size must be in .data");
2292 data_offset += length;
2294 else if (strcmp(parser.string, "disasm") == 0)
2297 error("unknown command .%s", parser.string);
2303 char buffer[1024], *endptr;
2304 int integer = 1, offset = 0, neg = 0, e = 0, d = 0, base = 10;
2306 for (;; ch = getch()) {
2313 if (offset && buffer[offset - 1] != 'e') {
2321 if (offset && buffer[offset - 1] != 'e') {
2334 if (offset == 0 && base == 10) {
2340 if (offset == 0 && base == 8) {
2358 if (offset == 0 && base == 8) {
2363 case 'a': case 'c': case 'd': case 'f':
2376 case '_': case 'g' ... 'w': case 'y': case 'z': case 'A' ... 'Z':
2378 buffer[offset++] = '\0';
2379 error("bad constant %s", buffer);
2384 if (offset + 1 >= (int)sizeof(buffer))
2386 buffer[offset++] = ch;
2389 /* check for literal 0 */
2390 if (offset == 0 && base == 8) buffer[offset++] = '0';
2391 buffer[offset] = '\0';
2394 # define STRTOUL strtoull
2396 # define STRTOUL strtoul
2398 parser.value.ui = STRTOUL(buffer, &endptr, base);
2399 parser.type = type_l;
2401 parser.value.i = -parser.value.i;
2404 parser.type = type_d;
2405 parser.value.d = strtod(buffer, &endptr);
2407 parser.value.d = -parser.value.d;
2412 return (integer ? tok_int : tok_float);
2419 case 'a': ch = '\a'; break;
2420 case 'b': ch = '\b'; break;
2421 case 'f': ch = '\f'; break;
2422 case 'n': ch = '\n'; break;
2423 case 'r': ch = '\r'; break;
2424 case 't': ch = '\t'; break;
2425 case 'v': ch = '\v'; break;
2437 for (parser.offset = 0;;) {
2438 switch (ch = getch_noeof()) {
2440 if (esc) goto append;
2445 parser.string[parser.offset++] = '\0';
2446 parser.value.p = parser.string;
2447 parser.type = type_p;
2448 return (tok_string);
2457 if (parser.offset + 1 >= parser.length) {
2458 parser.length += 4096;
2459 parser.string = (char *)xrealloc(parser.string,
2462 parser.string[parser.offset++] = ch;
2473 if ((ch = getch_noeof()) == '\\') {
2477 if (getch_noeof() != '\'')
2478 error("bad single byte char");
2481 parser.type = type_l;
2482 parser.value.i = ch & 0xff;
2493 (void)identifier('@');
2494 if ((label = get_label_by_name(parser.string)) == NULL) {
2495 #if __CYGWIN__ ||_WIN32
2496 /* FIXME kludge to pass varargs test case, otherwise,
2497 * will not print/scan float values */
2498 if (strcmp(parser.string + 1, "sprintf") == 0)
2500 else if (strcmp(parser.string + 1, "sscanf") == 0)
2505 value = dlsym(DL_HANDLE, parser.string + 1);
2506 if ((string = dlerror()))
2507 error("%s", string);
2509 label = new_label(label_kind_dynamic, parser.string, value);
2511 parser.type = type_p;
2512 parser.value.p = label->value;
2514 return (tok_pointer);
2518 expression_prim(void)
2525 if (parser.putback) {
2526 parser.expr = parser.putback;
2527 parser.putback = (expr_t)0;
2530 switch (ch = skipws()) {
2532 if ((ch = getch_noeof()) == '=') parser.expr = expr_ne;
2534 ungetch(ch); parser.expr = expr_not;
2537 case '~': parser.expr = expr_com;
2540 if ((ch = getch_noeof()) == '=') parser.expr = expr_mulset;
2542 ungetch(ch); parser.expr = expr_mul;
2546 if ((ch = getch_noeof()) == '=') parser.expr = expr_divset;
2548 ungetch(ch); parser.expr = expr_div;
2552 if ((ch = getch_noeof()) == '=') parser.expr = expr_remset;
2554 ungetch(ch); parser.expr = expr_rem;
2558 switch (ch = getch_noeof()) {
2559 case '+': parser.expr = expr_inc;
2561 case '=': parser.expr = expr_addset;
2563 default: ungetch(ch); parser.expr = expr_add;
2568 switch (ch = getch_noeof()) {
2569 case '-': parser.expr = expr_dec;
2571 case '=': parser.expr = expr_subset;
2573 default: ungetch(ch); parser.expr = expr_sub;
2578 switch (ch = getch_noeof()) {
2579 case '=': parser.expr = expr_le;
2581 case '<': ch = getch_noeof();
2582 if (ch == '=') parser.expr = expr_lshset;
2584 ungetch(ch); parser.expr = expr_lsh;
2587 default: ungetch(ch); parser.expr = expr_lt;
2592 switch (ch = getch_noeof()) {
2593 case '=': parser.expr = expr_ge;
2595 case '>': ch = getch_noeof();
2596 if (ch == '=') parser.expr = expr_rshset;
2598 ungetch(ch); parser.expr = expr_rsh;
2601 default: ungetch(ch); parser.expr = expr_gt;
2606 switch (ch = getch_noeof()) {
2607 case '=': parser.expr = expr_andset;
2609 case '&': parser.expr = expr_andand;
2611 default: ungetch(ch); parser.expr = expr_and;
2616 switch (ch = getch_noeof()) {
2617 case '=': parser.expr = expr_orset;
2619 case '|': parser.expr = expr_oror;
2621 default: ungetch(ch); parser.expr = expr_or;
2626 if ((ch = getch_noeof()) == '=') parser.expr = expr_xorset;
2628 ungetch(ch); parser.expr = expr_xor;
2632 if ((ch = getch_noeof()) == '=') parser.expr = expr_eq;
2634 ungetch(ch); parser.expr = expr_set;
2637 case '(': parser.expr = expr_lparen;
2639 case ')': parser.expr = expr_rparen;
2643 parser.expr = token == tok_int ? expr_int : expr_float;
2647 parser.expr = expr_pointer;
2651 /* no support for nested expressions */
2652 if (parser.string[0] == '\0')
2653 error("syntax error");
2654 parser.expr = expr_symbol;
2655 if ((symbol = get_symbol_by_name(parser.string)) != NULL) {
2656 parser.type = symbol->type;
2657 parser.value = symbol->value;
2660 /* only create symbol on assignment */
2661 parser.type = type_none;
2663 case 'a' ... 'z': case 'A' ... 'Z': case '_':
2665 if ((label = get_label_by_name(parser.string))) {
2666 if (label->kind == label_kind_code_forward)
2667 error("forward value for %s not supported",
2669 parser.expr = expr_pointer;
2670 parser.type = type_p;
2671 parser.value.p = label->value;
2674 error("invalid identifier %s", parser.string);
2678 parser.expr = expr_int;
2681 /* not smart enough to put it in data and/or relocate it, etc */
2682 error("must declare strings as data");
2684 error("syntax error");
2689 expression_inc(int pre)
2695 if (parser.expr != expr_symbol)
2696 error("syntax error");
2698 if ((symbol = get_symbol_by_name(parser.string)) == NULL) {
2699 if (!parser.short_circuit)
2700 error("undefined symbol %s", symbol->name);
2702 if (!parser.short_circuit) {
2703 parser.type = symbol->type;
2705 parser.value = symbol->value;
2706 switch (symbol->type) {
2711 /* should really be an error */
2712 symbol->value.d += 1.0;
2719 parser.value = symbol->value;
2725 expression_dec(int pre)
2731 if (parser.expr != expr_symbol)
2732 error("syntax error");
2734 if ((symbol = get_symbol_by_name(parser.string)) == NULL) {
2735 if (!parser.short_circuit)
2736 error("undefined symbol %s", symbol->name);
2738 if (!parser.short_circuit) {
2739 parser.type = symbol->type;
2741 parser.value = symbol->value;
2742 switch (symbol->type) {
2747 /* should really be an error */
2748 symbol->value.d -= 1.0;
2755 parser.value = symbol->value;
2761 expression_unary(void)
2767 switch (parser.expr) {
2770 switch (parser.type) {
2775 error("syntax error");
2780 switch (parser.type) {
2782 parser.value.i = -parser.value.i;
2785 parser.value.d = -parser.value.d;
2788 error("syntax error");
2799 switch (parser.type) {
2801 parser.value.i = !parser.value.i;
2804 parser.value.i = parser.value.d != 0;
2807 parser.value.i = parser.value.p != NULL;
2810 error("syntax error");
2812 parser.type = type_l;
2816 if (parser.type != type_l)
2817 error("syntax error");
2818 parser.value.i = ~parser.value.i;
2822 if (parser.expr != expr_rparen)
2823 error("syntax error");
2827 strcpy(buffer, parser.string);
2829 switch (parser.expr) {
2831 if ((symbol = get_symbol_by_name(buffer)) == NULL) {
2832 if (!parser.short_circuit)
2833 symbol = new_symbol(buffer);
2837 if (!parser.short_circuit) {
2839 error("syntax error");
2840 symbol->type = parser.type;
2841 symbol->value = parser.value;
2844 case expr_mulset: parser.putback = expr_mul;
2846 case expr_divset: parser.putback = expr_div;
2848 case expr_remset: parser.putback = expr_rem;
2850 case expr_addset: parser.putback = expr_add;
2852 case expr_subset: parser.putback = expr_sub;
2854 case expr_lshset: parser.putback = expr_lsh;
2856 case expr_rshset: parser.putback = expr_rsh;
2858 case expr_andset: parser.putback = expr_and;
2860 case expr_orset: parser.putback = expr_or;
2862 case expr_xorset: parser.putback = expr_xor;
2864 if ((symbol = get_symbol_by_name(buffer)) == NULL) {
2865 if (!parser.short_circuit)
2866 error("undefined symbol %s", buffer);
2867 parser.type = type_l;
2870 switch (parser.putback) {
2871 case expr_mul: case expr_div: case expr_rem:
2874 case expr_add: case expr_sub:
2877 case expr_lsh: case expr_rsh:
2880 case expr_and: case expr_or: case expr_xor:
2900 /* make next token available */
2908 expression_mul(void)
2914 switch (parser.type) {
2915 case type_l: case type_d: case type_p: break;
2919 switch (parser.expr) {
2921 type = parser.type, value = parser.value;
2923 switch (parser.type) {
2926 value.i *= parser.value.i;
2928 value.d *= parser.value.i;
2931 if (type == type_l) {
2935 value.d *= parser.value.d;
2938 error("invalid operand");
2940 parser.type = type, parser.value = value;
2943 type = parser.type, value = parser.value;
2945 switch (parser.type) {
2947 if (type == type_l) {
2948 if (parser.value.i == 0)
2949 error("divide by zero");
2950 value.i /= parser.value.i;
2953 value.d /= parser.value.i;
2956 if (type == type_l) {
2960 value.d /= parser.value.d;
2963 error("invalid operand");
2965 parser.type = type, parser.value = value;
2968 type = parser.type, value = parser.value;
2970 switch (parser.type) {
2972 if (type == type_l) {
2973 if (parser.value.i == 0)
2974 error("divide by zero");
2975 value.i %= parser.value.i;
2978 error("invalid operand");
2981 error("invalid operand");
2983 parser.type = type, parser.value = value;
2992 expression_add(void)
2998 switch (parser.type) {
2999 case type_l: case type_d: case type_p: break;
3003 switch (parser.expr) {
3005 type = parser.type, value = parser.value;
3007 switch (parser.type) {
3011 value.i += parser.value.i;
3014 value.d += parser.value.i;
3017 value.cp += parser.value.i;
3030 error("invalid operand");
3032 value.d += parser.value.d;
3038 value.cp = value.i + parser.value.cp;
3041 error("invalid operand");
3045 error("invalid operand");
3047 parser.type = type, parser.value = value;
3050 type = parser.type, value = parser.value;
3052 switch (parser.type) {
3056 value.i -= parser.value.i;
3059 value.d -= parser.value.i;
3062 value.cp -= parser.value.i;
3075 error("invalid operand");
3077 value.d -= parser.value.d;
3083 value.i = value.cp - parser.value.cp;
3086 error("invalid operand");
3090 error("invalid operand");
3092 parser.type = type, parser.value = value;
3101 expression_shift(void)
3106 switch (parser.type) {
3107 case type_l: case type_d: case type_p: break;
3111 switch (parser.expr) {
3113 value = parser.value.i;
3114 if (parser.type != type_l)
3115 error("invalid operand");
3117 if (parser.type != type_l)
3118 error("invalid operand");
3119 value <<= parser.value.i;
3120 parser.value.i = value;
3123 value = parser.value.i;
3124 if (parser.type != type_l)
3125 error("invalid operand");
3127 if (parser.type != type_l)
3128 error("invalid operand");
3129 value >>= parser.value.i;
3130 parser.value.i = value;
3139 expression_bit(void)
3144 switch (parser.type) {
3145 case type_l: case type_d: case type_p: break;
3149 switch (parser.expr) {
3151 if (parser.type != type_l)
3152 error("invalid operand");
3155 if (parser.type != type_l)
3156 error("invalid operand");
3157 i &= parser.value.i;
3161 if (parser.type != type_l)
3162 error("invalid operand");
3165 if (parser.type != type_l)
3166 error("invalid operand");
3167 i |= parser.value.i;
3171 if (parser.type != type_l)
3172 error("invalid operand");
3175 if (parser.type != type_l)
3176 error("invalid operand");
3177 i ^= parser.value.i;
3187 expression_rel(void)
3193 switch (parser.type) {
3194 case type_l: case type_d: case type_p: break;
3198 switch (parser.expr) {
3200 type = parser.type, value = parser.value;
3202 switch (parser.type) {
3206 value.i = value.i < parser.value.i;
3209 value.i = value.d < parser.value.i;
3212 value.i = (jit_word_t)value.p < parser.value.i;
3219 value.i = value.i < parser.value.d;
3222 value.i = value.d < parser.value.d;
3225 error("invalid operand");
3231 value.i = value.i < (jit_word_t)parser.value.p;
3234 error("invalid operand");
3236 value.i = (jit_word_t)value.p < (jit_word_t)parser.value.p;
3241 error("invalid operand");
3243 parser.type = type_l, parser.value = value;
3246 type = parser.type, value = parser.value;
3248 switch (parser.type) {
3252 value.i = value.i <= parser.value.i;
3255 value.i = value.d <= parser.value.i;
3258 value.i = (jit_word_t)value.p <= parser.value.i;
3265 value.i = value.i <= parser.value.d;
3268 value.i = value.d <= parser.value.d;
3271 value.i = (jit_word_t)value.p <= parser.value.d;
3278 value.i = value.i <= (jit_word_t)parser.value.p;
3281 error("invalid operand");
3283 value.i = (jit_word_t)value.p <= (jit_word_t)parser.value.p;
3288 error("invalid operand");
3290 parser.type = type_l, parser.value = value;
3293 type = parser.type, value = parser.value;
3295 switch (parser.type) {
3299 value.i = value.i == parser.value.i;
3302 value.i = value.d == parser.value.i;
3305 value.i = (jit_word_t)value.p == parser.value.i;
3312 value.i = value.i == parser.value.d;
3315 value.i = value.d == parser.value.d;
3318 error("invalid operand");
3324 value.i = value.i == (jit_word_t)parser.value.p;
3327 error("invalid operand");
3329 value.i = value.p == parser.value.p;
3334 error("invalid operand");
3336 parser.type = type_l, parser.value = value;
3339 type = parser.type, value = parser.value;
3341 switch (parser.type) {
3345 value.i = value.i >= parser.value.i;
3348 value.i = value.d >= parser.value.i;
3351 value.i = (jit_word_t)value.p >= parser.value.i;
3358 value.i = value.i >= parser.value.d;
3361 value.i = value.d >= parser.value.d;
3364 error("invalid operand");
3370 value.i = value.i >= (jit_word_t)parser.value.p;
3373 error("invalid operand");
3375 value.i = (jit_word_t)value.p >= (jit_word_t)parser.value.p;
3380 error("invalid operand");
3382 parser.type = type_l, parser.value = value;
3385 type = parser.type, value = parser.value;
3387 switch (parser.type) {
3391 value.i = value.i > parser.value.i;
3394 value.i = value.d > parser.value.i;
3397 value.i = (jit_word_t)value.p > parser.value.i;
3404 value.i = value.i > parser.value.d;
3407 value.i = value.d > parser.value.d;
3410 error("invalid operand");
3416 value.i = value.i > (jit_word_t)parser.value.p;
3419 error("invalid operand");
3421 value.i = (jit_word_t)value.p > (jit_word_t)parser.value.p;
3426 error("invalid operand");
3428 parser.type = type_l, parser.value = value;
3431 type = parser.type, value = parser.value;
3433 switch (parser.type) {
3437 value.i = value.i != parser.value.i;
3440 value.i = value.d != parser.value.i;
3443 value.i = (jit_word_t)value.p != parser.value.i;
3450 value.i = value.i != parser.value.d;
3453 value.i = value.d != parser.value.d;
3456 error("invalid operand");
3462 value.i = value.i != (jit_word_t)parser.value.p;
3465 error("invalid operand");
3467 value.i = value.p != parser.value.p;
3472 error("invalid operand");
3474 parser.type = type_l, parser.value = value;
3483 expression_cond(void)
3490 switch (parser.type) {
3491 case type_l: case type_d: case type_p: break;
3495 switch (parser.expr) {
3497 type = parser.type, value = parser.value;
3500 short_circuit = value.i == 0;
3503 short_circuit = value.d == 0.0;
3506 short_circuit = value.p == NULL;
3509 parser.short_circuit += short_circuit;
3511 parser.short_circuit -= short_circuit;
3512 switch (parser.type) {
3516 value.i = value.i && parser.value.i;
3519 value.i = value.d && parser.value.i;
3522 value.i = value.p && parser.value.i;
3529 value.i = value.i && parser.value.d;
3532 value.i = value.d && parser.value.d;
3535 value.i = value.p && parser.value.d;
3542 value.i = value.i && parser.value.p;
3545 value.i = value.d && parser.value.p;
3548 value.i = value.p && parser.value.p;
3553 error("invalid operand");
3555 parser.type = type_l, parser.value.i = value.i;
3558 type = parser.type, value = parser.value;
3561 short_circuit = value.i != 0;
3564 short_circuit = value.d != 0.0;
3567 short_circuit = value.p != NULL;
3570 parser.short_circuit += short_circuit;
3572 parser.short_circuit -= short_circuit;
3573 switch (parser.type) {
3577 value.i = value.i || parser.value.i;
3580 value.i = value.d || parser.value.i;
3583 value.i = value.p || parser.value.i;
3590 value.i = value.i || parser.value.d;
3593 value.i = value.d || parser.value.d;
3596 value.i = value.p || parser.value.d;
3603 value.i = value.i || parser.value.p;
3606 value.i = value.d || parser.value.p;
3609 value.i = value.p || parser.value.p;
3614 error("invalid operand");
3616 parser.type = type_l, parser.value.i = value.i;
3629 (void)identifier('$');
3630 if (parser.string[1] == '\0') {
3631 if (getch_noeof() != '(')
3632 error("bad symbol or expression");
3633 parser.type = type_none;
3635 if (parser.expr != expr_rparen)
3636 error("bad expression");
3637 switch (parser.type) {
3643 return (tok_pointer);
3645 error("bad expression");
3648 else if ((symbol = get_symbol_by_name(parser.string))) {
3649 switch (parser.type = symbol->type) {
3651 parser.value.i = symbol->value.i;
3654 parser.value.d = symbol->value.d;
3657 parser.value.p = symbol->value.p;
3658 return (tok_pointer);
3662 error("undefined symbol %s", parser.string);
3666 primary(skip_t skip)
3671 case skip_none: ch = getch(); break;
3672 case skip_ws: ch = skipws(); break;
3673 case skip_nl: ch = skipnl(); break;
3679 case 'a' ... 'z': case 'A' ... 'Z': case '_':
3680 return (identifier(ch));
3681 case '0' ... '9': case '+': case '-':
3682 return (number(ch));
3688 return (character());
3692 return (expression());
3696 return (tok_newline);
3698 return (tok_semicollon);
3700 error("syntax error");
3714 switch (token = primary(skip_nl)) {
3718 if ((label = get_label_by_name(parser.string))) {
3719 if (label->kind == label_kind_code_forward) {
3720 label->kind = label_kind_code;
3721 jit_link(label->value);
3722 jit_note(parser.name, parser.line);
3725 error("label %s: redefined", parser.string);
3728 if (parser.parsing == PARSING_DATA) {
3729 value = data + data_offset;
3730 label = new_label(label_kind_data,
3731 parser.string, value);
3733 else if (parser.parsing == PARSING_CODE) {
3734 value = jit_label();
3735 jit_note(parser.name, parser.line);
3736 label = new_label(label_kind_code,
3737 parser.string, value);
3740 error("label not in .code or .data");
3746 (instr_t *)get_hash(instrs, parser.string)) == NULL)
3747 error("unhandled symbol %s", parser.string);
3748 if (parser.parsing != PARSING_CODE)
3749 error(".code must be specified before instructions");
3750 (*instr->function)();
3758 error("syntax error");
3764 execute(int argc, char *argv[])
3768 function_t function;
3769 patch_t *patch, *next;
3771 for (patch = patches; patch; patch = next) {
3773 label = patch->label;
3774 if (label->kind == label_kind_code_forward)
3775 error("undefined label %s", label->name);
3776 switch (patch->kind) {
3777 case patch_kind_jmp:
3778 case patch_kind_mov:
3779 case patch_kind_call:
3780 jit_patch_at(patch->value, label->value);
3789 if (flag_data == 0) {
3791 jit_set_data(NULL, 0, JIT_DISABLE_DATA | JIT_DISABLE_NOTE);
3794 function = jit_emit();
3795 if (flag_verbose > 1 || flag_disasm) {
3797 fprintf(stderr, " - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n");
3799 if (flag_verbose > 0 || flag_disasm) {
3801 fprintf(stderr, " - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n");
3808 result = (*function)(argc, argv);
3809 jit_destroy_state();
3815 xmalloc(size_t size)
3817 void *pointer = malloc(size);
3819 if (pointer == NULL)
3820 error("out of memory");
3826 xrealloc(void *pointer, size_t size)
3828 pointer = realloc(pointer, size);
3830 if (pointer == NULL)
3831 error("out of memory");
3837 xcalloc(size_t nmemb, size_t size)
3839 void *pointer = calloc(nmemb, size);
3841 if (pointer == NULL)
3842 error("out of memory");
3848 new_label(label_kind_t kind, char *name, void *value)
3852 label = (label_t *)xmalloc(sizeof(label_t));
3854 label->name = strdup(name);
3855 label->value = value;
3856 put_hash(labels, (entry_t *)label);
3862 new_patch(patch_kind_t kind, label_t *label, void *value)
3864 patch_t *patch = (patch_t *)xmalloc(sizeof(patch_t));
3866 patch->label = label;
3867 patch->value = value;
3868 patch->next = patches;
3875 bcmp_symbols(const void *left, const void *right)
3877 return (strcmp((char *)left, (*(symbol_t **)right)->name));
3881 qcmp_symbols(const void *left, const void *right)
3883 return (strcmp((*(symbol_t **)left)->name, (*(symbol_t **)right)->name));
3887 new_symbol(char *name)
3891 if ((symbol_offset & 15) == 0) {
3892 if ((symbol_length += 16) == 16)
3893 symbols = (symbol_t **)xmalloc(sizeof(symbol_t *) *
3896 symbols = (symbol_t **)xrealloc(symbols, sizeof(symbol_t *) *
3899 symbol = (symbol_t *)xmalloc(sizeof(symbol_t));
3900 symbol->name = strdup(name);
3901 symbols[symbol_offset++] = symbol;
3902 qsort(symbols, symbol_offset, sizeof(symbol_t *), qcmp_symbols);
3908 get_symbol_by_name(char *name)
3910 symbol_t **symbol_pointer;
3912 if (symbols == NULL)
3914 symbol_pointer = (symbol_t **)bsearch(name, symbols, symbol_offset,
3915 sizeof(symbol_t *), bcmp_symbols);
3917 return (symbol_pointer ? *symbol_pointer : NULL);
3925 hash = (hash_t *)xmalloc(sizeof(hash_t));
3927 hash->entries = (entry_t **)xcalloc(hash->size = 32, sizeof(void *));
3933 hash_string(char *name)
3938 for (key = 0, ptr = name; *ptr; ptr++)
3939 key = (key << (key & 1)) ^ *ptr;
3945 put_hash(hash_t *hash, entry_t *entry)
3947 entry_t *prev, *ptr;
3948 int key = hash_string(entry->name) & (hash->size - 1);
3950 for (prev = ptr = hash->entries[key]; ptr; prev = ptr, ptr = ptr->next) {
3951 if (strcmp(entry->name, ptr->name) == 0)
3952 error("duplicated entry %s", entry->name);
3955 hash->entries[key] = entry;
3960 if (hash->count > hash->size * 0.75)
3965 get_hash(hash_t *hash, char *name)
3968 int key = hash_string(name) & (hash->size - 1);
3970 for (entry = hash->entries[key]; entry; entry = entry->next) {
3971 if (strcmp(entry->name, name) == 0)
3978 rehash(hash_t *hash)
3981 entry_t *entry, *next, **entries;
3983 entries = (entry_t **)xcalloc(size = hash->size * 2, sizeof(void *));
3984 for (i = 0; i < hash->size; i++) {
3985 for (entry = hash->entries[i]; entry; entry = next) {
3987 key = hash_string(entry->name) & (size - 1);
3988 entry->next = entries[key];
3989 entries[key] = entry;
3992 free(hash->entries);
3993 hash->entries = entries;
4000 #if HAVE_GETOPT_LONG_ONLY
4002 Usage: %s [jit assembler options] file [jit program options]\n\
4003 Jit assembler options:\n\
4004 -help Display this information\n\
4005 -v[0-3] Verbose output level\n\
4006 -d Do not use a data buffer\n\
4007 -D<macro>[=<val>] Preprocessor options\n"
4008 # if defined(__i386__) && __WORDSIZE == 32
4009 " -mx87=1 Force using x87 when sse2 available\n"
4011 # if defined(__i386__) || defined(__x86_64__)
4012 " -msse4_1=0 Do not use sse4_1 instructions when available\n"
4014 # if defined(__arm__)
4015 " -mcpu=<val> Force cpu version (4, 5, 6 or 7)\n\
4016 -mthumb[=0|1] Enable or disable thumb\n\
4017 -mvfp=<val> Set vpf version (0 to disable)\n\
4018 -mneon[=0|1] Enable or disable neon\n"
4023 Usage: %s [jit assembler options] file [jit program options]\n\
4024 Jit assembler options:\n\
4025 -h Display this information\n\
4026 -v Verbose output level\n\
4027 -D<macro>[=<val>] Preprocessor options\n", progname);
4034 main(int argc, char *argv[])
4036 #if HAVE_GETOPT_LONG_ONLY
4037 static const char *short_options = "dv::";
4038 static struct option long_options[] = {
4039 { "help", 0, 0, 'h' },
4040 { "data", 2, 0, 'd' },
4041 # if defined(__i386__) && __WORDSIZE == 32
4042 { "mx87", 2, 0, '7' },
4044 # if defined(__i386__) || defined(__x86_64__)
4045 { "msse4_1", 2, 0, '4' },
4047 # if defined(__arm__)
4048 { "mcpu", 2, 0, 'c' },
4049 { "mthumb", 2, 0, 't' },
4050 { "mvfp", 2, 0, 'f' },
4051 { "mneon", 2, 0, 'n' },
4056 #endif /* HAVE_GETOPT_LONG_ONLY */
4063 #if defined(__CYGWIN__)
4064 /* Cause a compile warning about redefinition without dllimport
4065 * attribute, *but* cause correct linkage if liblightning.a is
4066 * linked to binutils (that happens to have an internal
4067 * getopt* implementation and an apparently conflicting
4068 * optind global variable) */
4078 DL_HANDLE = dlopen(NULL, RTLD_LAZY);
4082 #if HAVE_GETOPT_LONG_ONLY
4084 if ((opt_short = getopt_long_only(argc, argv, short_options,
4085 long_options, &opt_index)) < 0)
4087 switch (opt_short) {
4094 flag_verbose = strtol(optarg, &endptr, 10);
4095 if (*endptr || flag_verbose < 0)
4104 #if defined(__i386__) && __WORDSIZE == 32
4107 if (strcmp(optarg, "") == 0 || strcmp(optarg, "1") == 0)
4109 else if (strcmp(optarg, "0"))
4116 #if defined(__i386__) || defined(__x86_64__)
4119 if (strcmp(optarg, "0") == 0)
4121 else if (strcmp(optarg, "1"))
4126 #if defined(__arm__)
4129 offset = strtol(optarg, &endptr, 10);
4130 if (*endptr || offset < 0)
4132 if (offset < jit_cpu.version)
4133 jit_cpu.version = offset;
4138 if (strcmp(optarg, "0") == 0)
4140 else if (strcmp(optarg, "1") && strcmp(optarg, "2"))
4145 # if !defined(__ARM_PCS_VFP)
4146 /* Do not allow overrinding hard float abi */
4148 offset = strtol(optarg, &endptr, 10);
4149 if (*endptr || offset < 0)
4151 if (offset < jit_cpu.vfp)
4152 jit_cpu.vfp = offset;
4158 if (strcmp(optarg, "0") == 0)
4160 else if (strcmp(optarg, "1"))
4168 while ((opt_short = getopt(argc, argv, "hvd")) >= 0) {
4169 if (opt_short == 'v')
4171 else if (opt_short == 'd')
4181 if (opt_index < argc && argv[opt_index][0] == '-')
4184 if (opt_index < 0 || opt_index >= argc)
4186 if (strcmp(argv[opt_index], "-") == 0)
4187 strcpy(parser.name, "<stdin>");
4189 if ((endptr = strrchr(argv[opt_index], '/')) == NULL)
4190 endptr = argv[opt_index];
4193 strncpy(parser.name, endptr, sizeof(parser.name));
4194 parser.name[sizeof(parser.name) - 1] = '\0';
4201 opt_short = snprintf(cmdline, sizeof(cmdline), cc " -E -x c %s", argv[opt_index]);
4202 for (++opt_index; opt_index < argc; opt_index++) {
4203 if (argv[opt_index][0] == '-')
4204 opt_short += snprintf(cmdline + opt_short,
4205 sizeof(cmdline) - opt_short,
4206 " %s", argv[opt_index]);
4212 opt_short += snprintf(cmdline + opt_short,
4213 sizeof(cmdline) - opt_short,
4214 " -D__WORDSIZE=%d", __WORDSIZE);
4215 opt_short += snprintf(cmdline + opt_short,
4216 sizeof(cmdline) - opt_short,
4217 " -D__LITTLE_ENDIAN=%d", __LITTLE_ENDIAN);
4218 opt_short += snprintf(cmdline + opt_short,
4219 sizeof(cmdline) - opt_short,
4220 " -D__BIG_ENDIAN=%d", __BIG_ENDIAN);
4221 opt_short += snprintf(cmdline + opt_short,
4222 sizeof(cmdline) - opt_short,
4223 " -D__BYTE_ORDER=%d", __BYTE_ORDER);
4224 #if defined(__i386__)
4225 opt_short += snprintf(cmdline + opt_short,
4226 sizeof(cmdline) - opt_short,
4229 #if defined(__x86_64__)
4230 opt_short += snprintf(cmdline + opt_short,
4231 sizeof(cmdline) - opt_short,
4234 #if defined(__mips__)
4235 opt_short += snprintf(cmdline + opt_short,
4236 sizeof(cmdline) - opt_short,
4239 #if defined(__arm__)
4240 opt_short += snprintf(cmdline + opt_short,
4241 sizeof(cmdline) - opt_short,
4244 #if defined(__powerpc__)
4245 opt_short += snprintf(cmdline + opt_short,
4246 sizeof(cmdline) - opt_short,
4249 #if defined(__sparc__)
4250 opt_short += snprintf(cmdline + opt_short,
4251 sizeof(cmdline) - opt_short,
4254 #if defined(__ia64__)
4255 opt_short += snprintf(cmdline + opt_short,
4256 sizeof(cmdline) - opt_short,
4259 #if defined(__hppa__)
4260 opt_short += snprintf(cmdline + opt_short,
4261 sizeof(cmdline) - opt_short,
4265 opt_short += snprintf(cmdline + opt_short,
4266 sizeof(cmdline) - opt_short,
4269 #if defined(__sgi__)
4270 opt_short += snprintf(cmdline + opt_short,
4271 sizeof(cmdline) - opt_short,
4274 #if defined(__aarch64__)
4275 opt_short += snprintf(cmdline + opt_short,
4276 sizeof(cmdline) - opt_short,
4277 " -D__aarch64__=1");
4279 #if defined(__s390__) || defined(__s390x__)
4280 opt_short += snprintf(cmdline + opt_short,
4281 sizeof(cmdline) - opt_short,
4284 #if defined(__alpha__)
4285 opt_short += snprintf(cmdline + opt_short,
4286 sizeof(cmdline) - opt_short,
4289 if ((parser.fp = popen(cmdline, "r")) == NULL)
4290 error("cannot execute %s", cmdline);
4293 parser.string = (char *)xmalloc(parser.length = 4096);
4295 #if defined(__linux__) && (defined(__i386__) || defined(__x86_64__))
4296 /* double precision 0x200
4297 * round nearest 0x000
4298 * invalid operation mask 0x001
4299 * denormalized operand mask 0x002
4300 * zero divide mask 0x004
4301 * precision (inexact) mask 0x020
4304 fpu_control_t fpu_control = 0x027f;
4305 _FPU_SETCW(fpu_control);
4309 _jit = jit_new_state();
4311 instrs = new_hash();
4313 offset < (int)(sizeof(instr_vector) / sizeof(instr_vector[0]));
4315 put_hash(instrs, (entry_t *)(instr_vector + offset));
4317 labels = new_hash();
4323 for (opt_short = 0; opt_index < argc; opt_short++, opt_index++)
4324 argv[opt_short] = argv[opt_index];
4325 argv[opt_short] = NULL;
4327 execute(argc, argv);