2 * Copyright (C) 2012-2022 Free Software Foundation, Inc.
4 * This file is part of GNU lightning.
6 * GNU lightning is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published
8 * by the Free Software Foundation; either version 3, or (at your option)
11 * GNU lightning is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 * License for more details.
17 * Paulo Cesar Pereira de Andrade
31 #include <lightning.h>
35 #if defined(__linux__) && (defined(__i386__) || defined(__x86_64__))
36 # include <fpu_control.h>
39 /* The label_t identifier clashes with a system definitions */
40 #if defined(_AIX) || defined(__sun__) || defined(__osf__)
41 # define label_t l_label_t
45 # define DL_HANDLE RTLD_NEXT
47 static void *DL_HANDLE;
48 #elif defined(__osf__)
49 # define DL_HANDLE NULL
51 # define DL_HANDLE RTLD_DEFAULT
55 # define noreturn __attribute__ ((noreturn))
56 # define printf_format(f, v) __attribute__ ((format (printf, f, v)))
57 # define maybe_unused __attribute__ ((unused))
59 # define noreturn /**/
60 # define printf_format(f, v) /**/
61 # define maybe_unused /**/
64 #define check_data(length) \
66 if (data_offset + length > data_length) \
67 error(".data too small (%ld < %ld)", \
68 data_length, data_offset + length); \
71 #define get_label_by_name(name) ((label_t *)get_hash(labels, name))
73 #define PARSING_NONE 0
74 #define PARSING_DATA 1
75 #define PARSING_CODE 2
76 #define MAX_IDENTIFIER 256
81 typedef struct instr instr_t;
82 typedef union value value_t;
83 typedef struct parser parser_t;
84 typedef struct label label_t;
85 typedef struct patch patch_t;
86 typedef struct symbol symbol_t;
87 typedef struct hash hash_t;
88 typedef struct entry entry_t;
89 typedef int (*function_t)(int argc, char *argv[]);
122 #define compose(a, b) (((a) << 8) | b)
124 expr_inc = compose('+', '+'),
125 expr_dec = compose('-', '-'),
133 expr_lsh = compose('<', '<'),
134 expr_rsh = compose('>', '>'),
139 expr_mulset = compose('*', '='),
140 expr_divset = compose('/', '='),
141 expr_remset = compose('%', '='),
142 expr_addset = compose('+', '='),
143 expr_subset = compose('-', '='),
144 expr_lshset = compose(expr_lsh, '='),
145 expr_rshset = compose(expr_rsh, '='),
146 expr_andset = compose('&', '='),
147 expr_orset = compose('|', '='),
148 expr_xorset = compose('^', '='),
150 expr_le = compose('<', '='),
151 expr_eq = compose('=', '='),
152 expr_ne = compose('!', '='),
154 expr_ge = compose('>', '='),
155 expr_andand = compose('&', '&'),
156 expr_oror = compose('|', '|'),
169 void (*function)(void);
194 /* variable length string buffer */
205 unsigned char buffer[4096];
214 label_kind_code_forward,
251 /* minor support for expressions */
262 static jit_gpr_t get_ireg(void);
263 static jit_fpr_t get_freg(void);
264 static symbol_t *get_symbol(void);
265 static void jmp_forward(void *value, label_t *label);
266 static void mov_forward(void *value, label_t *label);
267 static void call_forward(void *value, label_t *label);
268 static void make_arg(void *value);
269 static jit_pointer_t get_arg(void);
270 static jit_word_t get_imm(void);
271 static void live(void);
272 static void align(void); static void name(void);
273 static void skip(void);
274 static void prolog(void);
275 static void frame(void); static void tramp(void);
276 static void ellipsis(void);
277 static void allocai(void); static void allocar(void);
278 static void arg_c(void); static void arg_s(void);
279 static void arg_i(void);
281 static void arg_l(void);
283 static void arg(void);
284 static void getarg_c(void); static void getarg_uc(void);
285 static void getarg_s(void); static void getarg_us(void);
286 static void getarg_i(void);
288 static void getarg_ui(void); static void getarg_l(void);
290 static void getarg(void);
291 static void putargr_c(void); static void putargi_c(void);
292 static void putargr_uc(void); static void putargi_uc(void);
293 static void putargr_s(void); static void putargi_s(void);
294 static void putargr_us(void); static void putargi_us(void);
295 static void putargr_i(void); static void putargi_i(void);
297 static void putargr_ui(void); static void putargi_ui(void);
298 static void putargr_l(void); static void putargi_l(void);
300 static void putargr(void); static void putargi(void);
301 static void addr(void); static void addi(void);
302 static void addxr(void); static void addxi(void);
303 static void addcr(void); static void addci(void);
304 static void subr(void); static void subi(void);
305 static void subxr(void); static void subxi(void);
306 static void subcr(void); static void subci(void);
307 static void rsbr(void); static void rsbi(void);
308 static void mulr(void); static void muli(void);
309 static void qmulr(void); static void qmuli(void);
310 static void qmulr_u(void); static void qmuli_u(void);
311 static void divr(void); static void divi(void);
312 static void divr_u(void); static void divi_u(void);
313 static void qdivr(void); static void qdivi(void);
314 static void qdivr_u(void); static void qdivi_u(void);
315 static void remr(void); static void remi(void);
316 static void remr_u(void); static void remi_u(void);
317 static void andr(void); static void andi(void);
318 static void orr(void); static void ori(void);
319 static void xorr(void); static void xori(void);
320 static void lshr(void); static void lshi(void);
321 static void rshr(void); static void rshi(void);
322 static void rshr_u(void); static void rshi_u(void);
323 static void negr(void); static void comr(void);
324 static void clor(void); static void clzr(void);
325 static void ctor(void); static void ctzr(void);
326 static void ltr(void); static void lti(void);
327 static void ltr_u(void); static void lti_u(void);
328 static void ler(void); static void lei(void);
329 static void ler_u(void); static void lei_u(void);
330 static void eqr(void); static void eqi(void);
331 static void ger(void); static void gei(void);
332 static void ger_u(void); static void gei_u(void);
333 static void gtr(void); static void gti(void);
334 static void gtr_u(void); static void gti_u(void);
335 static void ner(void); static void nei(void);
336 static void casr(void); static void casi(void);
337 static void movr(void); static void movi(void);
338 static void extr_c(void); static void extr_uc(void);
339 static void extr_s(void); static void extr_us(void);
341 static void extr_i(void); static void extr_ui(void);
343 static void htonr_us(void); static void ntohr_us(void);
344 static void htonr_ui(void); static void ntohr_ui(void);
346 static void htonr_ul(void); static void ntohr_ul(void);
348 static void htonr(void); static void ntohr(void);
349 static void bswapr_us(void); static void bswapr_ui(void);
351 static void bswapr_ul(void);
353 static void bswapr(void);
354 static void movnr(void); static void movzr(void);
355 static void ldr_c(void); static void ldi_c(void);
356 static void ldr_uc(void); static void ldi_uc(void);
357 static void ldr_s(void); static void ldi_s(void);
358 static void ldr_us(void); static void ldi_us(void);
359 static void ldr_i(void); static void ldi_i(void);
361 static void ldr_ui(void); static void ldi_ui(void);
362 static void ldr_l(void); static void ldi_l(void);
364 static void ldr(void); static void ldi(void);
365 static void ldxr_c(void); static void ldxi_c(void);
366 static void ldxr_uc(void); static void ldxi_uc(void);
367 static void ldxr_s(void); static void ldxi_s(void);
368 static void ldxr_us(void); static void ldxi_us(void);
369 static void ldxr_i(void); static void ldxi_i(void);
371 static void ldxr_ui(void); static void ldxi_ui(void);
372 static void ldxr_l(void); static void ldxi_l(void);
374 static void ldxr(void); static void ldxi(void);
375 static void str_c(void); static void sti_c(void);
376 static void str_s(void); static void sti_s(void);
377 static void str_i(void); static void sti_i(void);
379 static void str_l(void); static void sti_l(void);
381 static void str(void); static void sti(void);
382 static void stxr_c(void); static void stxi_c(void);
383 static void stxr_s(void); static void stxi_s(void);
384 static void stxr_i(void); static void stxi_i(void);
386 static void stxr_l(void); static void stxi_l(void);
388 static void stxr(void); static void stxi(void);
389 static void bltr(void); static void blti(void);
390 static void bltr_u(void); static void blti_u(void);
391 static void bler(void); static void blei(void);
392 static void bler_u(void); static void blei_u(void);
393 static void beqr(void); static void beqi(void);
394 static void bger(void); static void bgei(void);
395 static void bger_u(void); static void bgei_u(void);
396 static void bgtr(void); static void bgti(void);
397 static void bgtr_u(void); static void bgti_u(void);
398 static void bner(void); static void bnei(void);
399 static void bmsr(void); static void bmsi(void);
400 static void bmcr(void); static void bmci(void);
401 static void boaddr(void); static void boaddi(void);
402 static void boaddr_u(void); static void boaddi_u(void);
403 static void bxaddr(void); static void bxaddi(void);
404 static void bxaddr_u(void); static void bxaddi_u(void);
405 static void bosubr(void); static void bosubi(void);
406 static void bosubr_u(void); static void bosubi_u(void);
407 static void bxsubr(void); static void bxsubi(void);
408 static void bxsubr_u(void); static void bxsubi_u(void);
409 static void jmpr(void); static void jmpi(void);
410 static void callr(void); static void calli(void);
411 static void prepare(void);
413 static void pushargr_c(void); static void pushargi_c(void);
414 static void pushargr_uc(void); static void pushargi_uc(void);
415 static void pushargr_s(void); static void pushargi_s(void);
416 static void pushargr_us(void); static void pushargi_us(void);
417 static void pushargr_i(void); static void pushargi_i(void);
419 static void pushargr_ui(void); static void pushargi_ui(void);
420 static void pushargr_l(void); static void pushargi_l(void);
422 static void pushargr(void); static void pushargi(void);
424 static void finishr(void); static void finishi(void);
425 static void ret(void);
427 static void retr_c(void); static void reti_c(void);
428 static void retr_uc(void); static void reti_uc(void);
429 static void retr_s(void); static void reti_s(void);
430 static void retr_us(void); static void reti_us(void);
431 static void retr_i(void); static void reti_i(void);
433 static void retr_ui(void); static void reti_ui(void);
434 static void retr_l(void); static void reti_l(void);
436 static void retr(void); static void reti(void);
437 static void retval_c(void); static void retval_uc(void);
438 static void retval_s(void); static void retval_us(void);
439 static void retval_i(void);
441 static void retval_ui(void); static void retval_l(void);
443 static void retval(void);
444 static void epilog(void);
445 static void arg_f(void); static void getarg_f(void);
446 static void putargr_f(void); static void putargi_f(void);
447 static void addr_f(void); static void addi_f(void);
448 static void subr_f(void); static void subi_f(void);
449 static void rsbr_f(void); static void rsbi_f(void);
450 static void mulr_f(void); static void muli_f(void);
451 static void divr_f(void); static void divi_f(void);
452 static void negr_f(void); static void absr_f(void);
453 static void sqrtr_f(void);
454 static void ltr_f(void); static void lti_f(void);
455 static void ler_f(void); static void lei_f(void);
456 static void eqr_f(void); static void eqi_f(void);
457 static void ger_f(void); static void gei_f(void);
458 static void gtr_f(void); static void gti_f(void);
459 static void ner_f(void); static void nei_f(void);
460 static void unltr_f(void); static void unlti_f(void);
461 static void unler_f(void); static void unlei_f(void);
462 static void uneqr_f(void); static void uneqi_f(void);
463 static void unger_f(void); static void ungei_f(void);
464 static void ungtr_f(void); static void ungti_f(void);
465 static void ltgtr_f(void); static void ltgti_f(void);
466 static void ordr_f(void); static void ordi_f(void);
467 static void unordr_f(void); static void unordi_f(void);
468 static void truncr_f_i(void);
470 static void truncr_f_l(void);
472 static void truncr_f(void);
473 static void extr_f(void); static void extr_d_f(void);
474 static void movr_f(void); static void movi_f(void);
475 static void ldr_f(void); static void ldi_f(void);
476 static void ldxr_f(void); static void ldxi_f(void);
477 static void str_f(void); static void sti_f(void);
478 static void stxr_f(void); static void stxi_f(void);
479 static void bltr_f(void); static void blti_f(void);
480 static void bler_f(void); static void blei_f(void);
481 static void beqr_f(void); static void beqi_f(void);
482 static void bger_f(void); static void bgei_f(void);
483 static void bgtr_f(void); static void bgti_f(void);
484 static void bner_f(void); static void bnei_f(void);
485 static void bunltr_f(void); static void bunlti_f(void);
486 static void bunler_f(void); static void bunlei_f(void);
487 static void buneqr_f(void); static void buneqi_f(void);
488 static void bunger_f(void); static void bungei_f(void);
489 static void bungtr_f(void); static void bungti_f(void);
490 static void bltgtr_f(void); static void bltgti_f(void);
491 static void bordr_f(void); static void bordi_f(void);
492 static void bunordr_f(void); static void bunordi_f(void);
493 static void pushargr_f(void); static void pushargi_f(void);
494 static void retr_f(void); static void reti_f(void);
495 static void retval_f(void);
496 static void arg_d(void); static void getarg_d(void);
497 static void putargr_d(void); static void putargi_d(void);
498 static void addr_d(void); static void addi_d(void);
499 static void subr_d(void); static void subi_d(void);
500 static void rsbr_d(void); static void rsbi_d(void);
501 static void mulr_d(void); static void muli_d(void);
502 static void divr_d(void); static void divi_d(void);
503 static void negr_d(void); static void absr_d(void);
504 static void sqrtr_d(void);
505 static void ltr_d(void); static void lti_d(void);
506 static void ler_d(void); static void lei_d(void);
507 static void eqr_d(void); static void eqi_d(void);
508 static void ger_d(void); static void gei_d(void);
509 static void gtr_d(void); static void gti_d(void);
510 static void ner_d(void); static void nei_d(void);
511 static void unltr_d(void); static void unlti_d(void);
512 static void unler_d(void); static void unlei_d(void);
513 static void uneqr_d(void); static void uneqi_d(void);
514 static void unger_d(void); static void ungei_d(void);
515 static void ungtr_d(void); static void ungti_d(void);
516 static void ltgtr_d(void); static void ltgti_d(void);
517 static void ordr_d(void); static void ordi_d(void);
518 static void unordr_d(void); static void unordi_d(void);
519 static void truncr_d_i(void);
521 static void truncr_d_l(void);
523 static void truncr_d(void);
524 static void extr_d(void); static void extr_f_d(void);
525 static void movr_d(void); static void movi_d(void);
526 static void ldr_d(void); static void ldi_d(void);
527 static void ldxr_d(void); static void ldxi_d(void);
528 static void str_d(void); static void sti_d(void);
529 static void stxr_d(void); static void stxi_d(void);
530 static void bltr_d(void); static void blti_d(void);
531 static void bler_d(void); static void blei_d(void);
532 static void beqr_d(void); static void beqi_d(void);
533 static void bger_d(void); static void bgei_d(void);
534 static void bgtr_d(void); static void bgti_d(void);
535 static void bner_d(void); static void bnei_d(void);
536 static void bunltr_d(void); static void bunlti_d(void);
537 static void bunler_d(void); static void bunlei_d(void);
538 static void buneqr_d(void); static void buneqi_d(void);
539 static void bunger_d(void); static void bungei_d(void);
540 static void bungtr_d(void); static void bungti_d(void);
541 static void bltgtr_d(void); static void bltgti_d(void);
542 static void bordr_d(void); static void bordi_d(void);
543 static void bunordr_d(void); static void bunordi_d(void);
544 static void pushargr_d(void); static void pushargi_d(void);
545 static void retr_d(void); static void reti_d(void);
546 static void retval_d(void);
547 static void vastart(void); static void vapush(void);
548 static void vaarg(void); static void vaarg_d(void);
549 static void vaend(void);
551 static void error(const char *format, ...) noreturn printf_format(1, 2);
552 static void warn(const char *format, ...) printf_format(1, 2) maybe_unused;
553 static void message(const char *kind, const char *format, va_list ap);
555 static int getch(void);
556 static int getch_noeof(void);
557 static int ungetch(int ch);
558 static int skipws(void);
559 static int skipnl(void);
560 static int skipct(void);
561 static int skipcp(void);
562 static jit_word_t get_int(skip_t skip);
563 static jit_uword_t get_uint(skip_t skip);
564 static double get_float(skip_t skip);
565 static float make_float(double d);
566 static void *get_pointer(skip_t skip);
567 static label_t *get_label(skip_t skip);
568 static token_t regname(void);
569 static token_t identifier(int ch);
570 static void get_data(type_t type);
571 static void dot(void);
572 static token_t number(int ch);
573 static int escape(int ch);
574 static token_t string(void);
575 static token_t dynamic(void);
576 static token_t character(void);
577 static void expression_prim(void);
578 static void expression_inc(int pre);
579 static void expression_dec(int pre);
580 static void expression_unary(void);
581 static void expression_mul(void);
582 static void expression_add(void);
583 static void expression_shift(void);
584 static void expression_bit(void);
585 static void expression_rel(void);
586 static void expression_cond(void);
587 static token_t expression(void);
588 static token_t primary(skip_t skip);
589 static void parse(void);
590 static int execute(int argc, char *argv[]);
592 static void *xmalloc(size_t size);
593 static void *xrealloc(void *pointer, size_t size);
594 static void *xcalloc(size_t nmemb, size_t size);
596 static label_t *new_label(label_kind_t kind, char *name, void *value);
597 static patch_t *new_patch(patch_kind_t kind, label_t *label, void *value);
598 static int bcmp_symbols(const void *left, const void *right);
599 static int qcmp_symbols(const void *left, const void *right);
600 static symbol_t *new_symbol(char *name);
601 static symbol_t *get_symbol_by_name(char *name);
603 static hash_t *new_hash(void);
604 static int hash_string(char *name);
605 static void put_hash(hash_t *hash, entry_t *entry);
606 static entry_t *get_hash(hash_t *hash, char *name);
607 static void rehash(hash_t *hash);
612 static jit_state_t *_jit;
613 static int flag_verbose;
614 static int flag_data;
615 static int flag_disasm;
616 static char *progname;
617 static parser_t parser;
618 static hash_t *labels;
619 static int label_offset;
620 static patch_t *patches;
621 static symbol_t **symbols;
622 static int symbol_length;
623 static int symbol_offset;
624 static hash_t *instrs;
626 static size_t data_offset, data_length;
627 static instr_t instr_vector[] = {
628 #define entry(value) { NULL, #value, value }
629 #define entry2(name, function) { NULL, name, function }
631 entry(align), entry(name),
634 entry(frame), entry(tramp),
636 entry(allocai), entry(allocar),
637 entry(arg_c), entry(arg_s),
643 entry(getarg_c), entry(getarg_uc),
644 entry(getarg_s), entry(getarg_us),
647 entry(getarg_ui), entry(getarg_l),
651 entry(putargr_c), entry(putargi_c),
652 entry(putargr_uc), entry(putargi_uc),
653 entry(putargr_s), entry(putargi_s),
654 entry(putargr_us), entry(putargi_us),
655 entry(putargr_i), entry(putargi_i),
657 entry(putargr_ui), entry(putargi_ui),
658 entry(putargr_l), entry(putargi_l),
660 entry(putargr), entry(putargi),
661 entry(addr), entry(addi),
662 entry(addxr), entry(addxi),
663 entry(addcr), entry(addci),
664 entry(subr), entry(subi),
665 entry(subxr), entry(subxi),
666 entry(subcr), entry(subci),
667 entry(rsbr), entry(rsbi),
668 entry(mulr), entry(muli),
669 entry(qmulr), entry(qmuli),
670 entry(qmulr_u), entry(qmuli_u),
671 entry(divr), entry(divi),
672 entry(divr_u), entry(divi_u),
673 entry(qdivr), entry(qdivi),
674 entry(qdivr_u), entry(qdivi_u),
675 entry(remr), entry(remi),
676 entry(remr_u), entry(remi_u),
677 entry(andr), entry(andi),
678 entry(orr), entry(ori),
679 entry(xorr), entry(xori),
680 entry(lshr), entry(lshi),
681 entry(rshr), entry(rshi),
682 entry(rshr_u), entry(rshi_u),
683 entry(negr), entry(comr),
684 entry(clor), entry(clzr),
685 entry(ctor), entry(ctzr),
686 entry(ltr), entry(lti),
687 entry(ltr_u), entry(lti_u),
688 entry(ler), entry(lei),
689 entry(ler_u), entry(lei_u),
690 entry(eqr), entry(eqi),
691 entry(ger), entry(gei),
692 entry(ger_u), entry(gei_u),
693 entry(gtr), entry(gti),
694 entry(gtr_u), entry(gti_u),
695 entry(ner), entry(nei),
696 entry(casr), entry(casi),
697 entry(movr), entry(movi),
698 entry(extr_c), entry(extr_uc),
699 entry(extr_s), entry(extr_us),
701 entry(extr_i), entry(extr_ui),
703 entry(htonr_us), entry(ntohr_us),
704 entry(htonr_ui), entry(ntohr_ui),
706 entry(htonr_ul), entry(ntohr_ul),
708 entry(htonr), entry(ntohr),
709 entry(bswapr_us), entry(bswapr_ui),
714 entry(movnr), entry(movzr),
715 entry(ldr_c), entry(ldi_c),
716 entry(ldr_uc), entry(ldi_uc),
717 entry(ldr_s), entry(ldi_s),
718 entry(ldr_us), entry(ldi_us),
719 entry(ldr_i), entry(ldi_i),
721 entry(ldr_ui), entry(ldi_ui),
722 entry(ldr_l), entry(ldi_l),
724 entry(ldr), entry(ldi),
725 entry(ldxr_c), entry(ldxi_c),
726 entry(ldxr_uc), entry(ldxi_uc),
727 entry(ldxr_s), entry(ldxi_s),
728 entry(ldxr_us), entry(ldxi_us),
729 entry(ldxr_i), entry(ldxi_i),
731 entry(ldxr_ui), entry(ldxi_ui),
732 entry(ldxr_l), entry(ldxi_l),
734 entry(ldxr), entry(ldxi),
735 entry(str_c), entry(sti_c),
736 entry(str_s), entry(sti_s),
737 entry(str_i), entry(sti_i),
739 entry(str_l), entry(sti_l),
741 entry(str), entry(sti),
742 entry(stxr_c), entry(stxi_c),
743 entry(stxr_s), entry(stxi_s),
744 entry(stxr_i), entry(stxi_i),
746 entry(stxr_l), entry(stxi_l),
748 entry(stxr), entry(stxi),
749 entry(bltr), entry(blti),
750 entry(bltr_u), entry(blti_u),
751 entry(bler), entry(blei),
752 entry(bler_u), entry(blei_u),
753 entry(beqr), entry(beqi),
754 entry(bger), entry(bgei),
755 entry(bger_u), entry(bgei_u),
756 entry(bgtr), entry(bgti),
757 entry(bgtr_u), entry(bgti_u),
758 entry(bner), entry(bnei),
759 entry(bmsr), entry(bmsi),
760 entry(bmcr), entry(bmci),
761 entry(boaddr), entry(boaddi),
762 entry(boaddr_u), entry(boaddi_u),
763 entry(bxaddr), entry(bxaddi),
764 entry(bxaddr_u), entry(bxaddi_u),
765 entry(bosubr), entry(bosubi),
766 entry(bosubr_u), entry(bosubi_u),
767 entry(bxsubr), entry(bxsubi),
768 entry(bxsubr_u), entry(bxsubi_u),
769 entry(jmpr), entry(jmpi),
770 entry(callr), entry(calli),
772 entry(pushargr_c), entry(pushargi_c),
773 entry(pushargr_uc), entry(pushargi_uc),
774 entry(pushargr_s), entry(pushargi_s),
775 entry(pushargr_us), entry(pushargi_us),
776 entry(pushargr_i), entry(pushargi_i),
778 entry(pushargr_ui), entry(pushargi_ui),
779 entry(pushargr_l), entry(pushargi_l),
781 entry(pushargr), entry(pushargi),
782 entry(finishr), entry(finishi),
784 entry(retr_c), entry(reti_c),
785 entry(retr_uc), entry(reti_uc),
786 entry(retr_s), entry(reti_s),
787 entry(retr_us), entry(reti_us),
788 entry(retr_i), entry(reti_i),
790 entry(retr_ui), entry(reti_ui),
791 entry(retr_l), entry(reti_l),
793 entry(retr), entry(reti),
794 entry(retval_c), entry(retval_uc),
795 entry(retval_s), entry(retval_us),
798 entry(retval_ui), entry(retval_l),
802 entry(arg_f), entry(getarg_f),
803 entry(putargr_f), entry(putargi_f),
804 entry(addr_f), entry(addi_f),
805 entry(subr_f), entry(subi_f),
806 entry(rsbr_f), entry(rsbi_f),
807 entry(mulr_f), entry(muli_f),
808 entry(divr_f), entry(divi_f),
809 entry(negr_f), entry(absr_f),
811 entry(ltr_f), entry(lti_f),
812 entry(ler_f), entry(lei_f),
813 entry(eqr_f), entry(eqi_f),
814 entry(ger_f), entry(gei_f),
815 entry(gtr_f), entry(gti_f),
816 entry(ner_f), entry(nei_f),
817 entry(unltr_f), entry(unlti_f),
818 entry(unler_f), entry(unlei_f),
819 entry(uneqr_f), entry(uneqi_f),
820 entry(unger_f), entry(ungei_f),
821 entry(ungtr_f), entry(ungti_f),
822 entry(ltgtr_f), entry(ltgti_f),
823 entry(ordr_f), entry(ordi_f),
824 entry(unordr_f), entry(unordi_f),
830 entry(extr_f), entry(extr_d_f),
831 entry(movr_f), entry(movi_f),
832 entry(ldr_f), entry(ldi_f),
833 entry(ldxr_f), entry(ldxi_f),
834 entry(str_f), entry(sti_f),
835 entry(stxr_f), entry(stxi_f),
836 entry(bltr_f), entry(blti_f),
837 entry(bler_f), entry(blei_f),
838 entry(beqr_f), entry(beqi_f),
839 entry(bger_f), entry(bgei_f),
840 entry(bgtr_f), entry(bgti_f),
841 entry(bner_f), entry(bnei_f),
842 entry(bunltr_f), entry(bunlti_f),
843 entry(bunler_f), entry(bunlei_f),
844 entry(buneqr_f), entry(buneqi_f),
845 entry(bunger_f), entry(bungei_f),
846 entry(bungtr_f), entry(bungti_f),
847 entry(bltgtr_f), entry(bltgti_f),
848 entry(bordr_f), entry(bordi_f),
849 entry(bunordr_f), entry(bunordi_f),
850 entry(pushargr_f), entry(pushargi_f),
851 entry(retr_f), entry(reti_f),
853 entry(arg_d), entry(getarg_d),
854 entry(putargr_d), entry(putargi_d),
855 entry(addr_d), entry(addi_d),
856 entry(subr_d), entry(subi_d),
857 entry(rsbr_d), entry(rsbi_d),
858 entry(mulr_d), entry(muli_d),
859 entry(divr_d), entry(divi_d),
860 entry(negr_d), entry(absr_d),
862 entry(ltr_d), entry(lti_d),
863 entry(ler_d), entry(lei_d),
864 entry(eqr_d), entry(eqi_d),
865 entry(ger_d), entry(gei_d),
866 entry(gtr_d), entry(gti_d),
867 entry(ner_d), entry(nei_d),
868 entry(unltr_d), entry(unlti_d),
869 entry(unler_d), entry(unlei_d),
870 entry(uneqr_d), entry(uneqi_d),
871 entry(unger_d), entry(ungei_d),
872 entry(ungtr_d), entry(ungti_d),
873 entry(ltgtr_d), entry(ltgti_d),
874 entry(ordr_d), entry(ordi_d),
875 entry(unordr_d), entry(unordi_d),
881 entry(extr_d), entry(extr_f_d),
882 entry(movr_d), entry(movi_d),
883 entry(ldr_d), entry(ldi_d),
884 entry(ldxr_d), entry(ldxi_d),
885 entry(str_d), entry(sti_d),
886 entry(stxr_d), entry(stxi_d),
887 entry(bltr_d), entry(blti_d),
888 entry(bler_d), entry(blei_d),
889 entry(beqr_d), entry(beqi_d),
890 entry(bger_d), entry(bgei_d),
891 entry(bgtr_d), entry(bgti_d),
892 entry(bner_d), entry(bnei_d),
893 entry(bunltr_d), entry(bunlti_d),
894 entry(bunler_d), entry(bunlei_d),
895 entry(buneqr_d), entry(buneqi_d),
896 entry(bunger_d), entry(bungei_d),
897 entry(bungtr_d), entry(bungti_d),
898 entry(bltgtr_d), entry(bltgti_d),
899 entry(bordr_d), entry(bordi_d),
900 entry(bunordr_d), entry(bunordi_d),
901 entry(pushargr_d), entry(pushargi_d),
902 entry(retr_d), entry(reti_d),
904 entry2("va_start", vastart),
905 entry2("va_push", vapush),
906 entry2("va_arg", vaarg),
907 entry2("va_arg_d", vaarg_d),
908 entry2("va_end", vaend),
918 if (primary(skip_ws) != tok_register)
919 error("bad register");
920 if (parser.regtype != type_l)
921 error("bad int register");
923 return ((jit_gpr_t)parser.regval);
929 if (primary(skip_ws) != tok_register)
930 error("bad register");
931 if (parser.regtype != type_d)
932 error("bad float register");
934 return ((jit_fpr_t)parser.regval);
944 error("expecting variable");
945 (void)identifier('$');
946 if (parser.string[1] == '\0')
947 error("expecting variable");
948 if ((symbol = get_symbol_by_name(parser.string)) == NULL)
949 symbol = new_symbol(parser.string);
955 jmp_forward(void *value, label_t *label)
957 (void)new_patch(patch_kind_jmp, label, value);
961 mov_forward(void *value, label_t *label)
963 (void)new_patch(patch_kind_mov, label, value);
967 call_forward(void *value, label_t *label)
969 (void)new_patch(patch_kind_call, label, value);
973 make_arg(void *value)
975 symbol_t *symbol = get_symbol();
977 symbol->type = type_p;
978 symbol->value.p = value;
984 symbol_t *symbol = get_symbol();
986 if (symbol->type != type_p)
987 error("bad argument %s type", symbol->name);
989 return symbol->value.p;
1000 case '+': case '-': case '0' ... '9':
1002 value = get_int(skip_none);
1006 value = parser.value.i;
1009 switch (expression()) {
1012 value = parser.value.i;
1015 error("expecting immediate");
1020 value = (jit_word_t)parser.value.p;
1024 label = get_label(skip_none);
1025 if (label->kind == label_kind_data)
1026 value = (jit_word_t)label->value;
1028 error("expecting immediate");
1034 #define entry(name) \
1040 #define entry_ca(name) \
1044 make_arg(jit_##name()); \
1046 #define entry_ia(name) \
1050 jit_gpr_t r0 = get_ireg(); \
1051 jit_pointer_t ac = get_arg(); \
1052 jit_##name(r0, ac); \
1054 #define entry_im(name) \
1058 jit_word_t im = get_imm(); \
1061 #define entry_ir(name) \
1065 jit_gpr_t r0 = get_ireg(); \
1068 #define entry_ima(name) \
1072 jit_word_t im = get_imm(); \
1073 jit_pointer_t ac = get_arg(); \
1074 jit_##name(im, ac); \
1076 #define entry_ir_ir_ir(name) \
1080 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(), r2 = get_ireg(); \
1081 jit_##name(r0, r1, r2); \
1083 #define entry_ir_ir_im(name) \
1087 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \
1088 jit_word_t im = get_imm(); \
1089 jit_##name(r0, r1, im); \
1091 #define entry_ir_ir_ir_ir(name) \
1095 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(), \
1096 r2 = get_ireg(), r3 = get_ireg(); \
1097 jit_##name(r0, r1, r2, r3); \
1099 #define entry_ir_ir_ir_im(name) \
1103 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(), r2 = get_ireg(); \
1104 jit_word_t im = get_imm(); \
1105 jit_##name(r0, r1, r2, im); \
1107 #define entry_ir_im_ir_ir(name) \
1111 jit_gpr_t r0 = get_ireg(); \
1112 jit_word_t im = get_imm(); \
1113 jit_gpr_t r1 = get_ireg(), r2 = get_ireg(); \
1114 jit_##name(r0, im, r1, r2); \
1117 #define entry_ir_ir(name) \
1121 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \
1122 jit_##name(r0, r1); \
1124 #define entry_ir_im(name) \
1128 jit_gpr_t r0 = get_ireg(); \
1129 jit_word_t im = get_imm(); \
1130 jit_##name(r0, im); \
1132 #define entry_ir_pm(name) \
1136 jit_gpr_t r0 = get_ireg(); \
1137 void *pm = get_pointer(skip_ws); \
1138 jit_##name(r0, pm); \
1140 #define entry_pm_ir(name) \
1144 void *pm = get_pointer(skip_ws); \
1145 jit_gpr_t r0 = get_ireg(); \
1146 jit_##name(pm, r0); \
1148 #define entry_im_ir_ir(name) \
1152 jit_word_t im = get_imm(); \
1153 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \
1154 (void)jit_##name(im, r0, r1); \
1156 #define entry_lb_ir_ir(name) \
1161 label_t *label = get_label(skip_ws); \
1162 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \
1163 if (label->kind == label_kind_code_forward) \
1164 jmp_forward((void *)jit_##name(r0, r1), label); \
1166 jmp = jit_##name(r0, r1); \
1167 jit_patch_at(jmp, (jit_node_t *)label->value); \
1170 #define entry_lb_ir_im(name) \
1175 label_t *label = get_label(skip_ws); \
1176 jit_gpr_t r0 = get_ireg(); \
1177 jit_word_t im = get_imm(); \
1178 if (label->kind == label_kind_code_forward) \
1179 jmp_forward((void *)jit_##name(r0, im), label); \
1181 jmp = jit_##name(r0, im); \
1182 jit_patch_at(jmp, (jit_node_t *)label->value); \
1185 #define entry_lb(name) \
1190 label_t *label = get_label(skip_ws); \
1191 if (label->kind == label_kind_code_forward) \
1192 jmp_forward((void *)jit_##name(), label); \
1194 jmp = jit_##name(); \
1195 jit_patch_at(jmp, (jit_node_t *)label->value); \
1198 #define entry_pm(name) \
1202 void *pm = get_pointer(skip_ws); \
1205 #define entry_fa(name) \
1209 jit_fpr_t r0 = get_freg(); \
1210 jit_pointer_t ac = get_arg(); \
1211 jit_##name(r0, ac); \
1213 #define entry_fma(name) \
1217 jit_float64_t im = get_float(skip_ws); \
1218 jit_pointer_t ac = get_arg(); \
1219 jit_##name(im, ac); \
1221 #define entry_fr_fr_fr(name) \
1225 jit_fpr_t r0 = get_freg(), r1 = get_freg(), r2 = get_freg(); \
1226 jit_##name(r0, r1, r2); \
1228 #define entry_fr_fr_fm(name) \
1232 jit_fpr_t r0 = get_freg(), r1 = get_freg(); \
1233 jit_float64_t im = get_float(skip_ws); \
1234 jit_##name(r0, r1, make_float(im)); \
1236 #define entry_fr_fr_dm(name) \
1240 jit_fpr_t r0 = get_freg(), r1 = get_freg(); \
1241 jit_float64_t im = get_float(skip_ws); \
1242 jit_##name(r0, r1, im); \
1244 #define entry_fr_fr(name) \
1248 jit_fpr_t r0 = get_freg(), r1 = get_freg(); \
1249 jit_##name(r0, r1); \
1251 #define entry_ir_fr_fr(name) \
1255 jit_gpr_t r0 = get_ireg(); \
1256 jit_fpr_t r1 = get_freg(), r2 = get_freg(); \
1257 jit_##name(r0, r1, r2); \
1259 #define entry_ir_fr_fm(name) \
1263 jit_gpr_t r0 = get_ireg(); \
1264 jit_fpr_t r1 = get_freg(); \
1265 jit_float64_t im = get_float(skip_ws); \
1266 jit_##name(r0, r1, make_float(im)); \
1268 #define entry_ir_fr_dm(name) \
1272 jit_gpr_t r0 = get_ireg(); \
1273 jit_fpr_t r1 = get_freg(); \
1274 jit_float64_t im = get_float(skip_ws); \
1275 jit_##name(r0, r1, im); \
1277 #define entry_ir_fr(name) \
1281 jit_gpr_t r0 = get_ireg(); \
1282 jit_fpr_t r1 = get_freg(); \
1283 jit_##name(r0, r1); \
1285 #define entry_fr_ir(name) \
1289 jit_fpr_t r0 = get_freg(); \
1290 jit_gpr_t r1 = get_ireg(); \
1291 jit_##name(r0, r1); \
1293 #define entry_fr_fm(name) \
1297 jit_fpr_t r0 = get_freg(); \
1298 jit_float64_t im = get_float(skip_ws); \
1299 jit_##name(r0, make_float(im)); \
1301 #define entry_fr_dm(name) \
1305 jit_fpr_t r0 = get_freg(); \
1306 jit_float64_t im = get_float(skip_ws); \
1307 jit_##name(r0, im); \
1309 #define entry_fr_pm(name) \
1313 jit_fpr_t r0 = get_freg(); \
1314 void *pm = get_pointer(skip_ws); \
1315 jit_##name(r0, pm); \
1317 #define entry_fr_ir_ir(name) \
1321 jit_fpr_t r0 = get_freg(); \
1322 jit_gpr_t r1 = get_ireg(), r2 = get_ireg(); \
1323 jit_##name(r0, r1, r2); \
1325 #define entry_fr_ir_im(name) \
1329 jit_fpr_t r0 = get_freg(); \
1330 jit_gpr_t r1 = get_ireg(); \
1331 jit_word_t im = get_imm(); \
1332 jit_##name(r0, r1, im); \
1334 #define entry_pm_fr(name) \
1338 void *pm = get_pointer(skip_ws); \
1339 jit_fpr_t r0 = get_freg(); \
1340 jit_##name(pm, r0); \
1342 #define entry_ir_ir_fr(name) \
1346 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \
1347 jit_fpr_t r2 = get_freg(); \
1348 jit_##name(r0, r1, r2); \
1350 #define entry_im_ir_fr(name) \
1354 jit_word_t im = get_imm(); \
1355 jit_gpr_t r0 = get_ireg(); \
1356 jit_fpr_t r1 = get_freg(); \
1357 jit_##name(im, r0, r1); \
1359 #define entry_lb_fr_fr(name) \
1364 label_t *label = get_label(skip_ws); \
1365 jit_fpr_t r0 = get_freg(), r1 = get_freg(); \
1366 if (label->kind == label_kind_code_forward) \
1367 jmp_forward((void *)jit_##name(r0, r1), label); \
1369 jmp = jit_##name(r0, r1); \
1370 jit_patch_at(jmp, (jit_node_t *)label->value); \
1373 #define entry_lb_fr_fm(name) \
1378 label_t *label = get_label(skip_ws); \
1379 jit_fpr_t r0 = get_freg(); \
1380 jit_float64_t im = get_float(skip_ws); \
1381 if (label->kind == label_kind_code_forward) \
1382 jmp_forward((void *)jit_##name(r0, make_float(im)), label); \
1384 jmp = jit_##name(r0, make_float(im)); \
1385 jit_patch_at(jmp, (jit_node_t *)label->value); \
1388 #define entry_lb_fr_dm(name) \
1393 label_t *label = get_label(skip_ws); \
1394 jit_fpr_t r0 = get_freg(); \
1395 jit_float64_t im = get_float(skip_ws); \
1396 if (label->kind == label_kind_code_forward) \
1397 jmp_forward((void *)jit_##name(r0, im), label); \
1399 jmp = jit_##name(r0, im); \
1400 jit_patch_at(jmp, (jit_node_t *)label->value); \
1403 #define entry_fr(name) \
1407 jit_fpr_t r0 = get_freg(); \
1410 #define entry_fm(name) \
1414 jit_float64_t im = get_float(skip_ws); \
1415 jit_##name(make_float(im)); \
1417 #define entry_dm(name) \
1421 jit_float64_t im = get_float(skip_ws); \
1424 #define entry_fn(name) \
1435 value = (void *)(jit_word_t)get_uint(skip_none); \
1438 switch (expression()) { \
1440 value = (void *)parser.value.i; \
1443 value = parser.value.p; \
1446 error("expecting pointer"); \
1451 value = parser.value.p; \
1455 label = get_label(skip_none); \
1456 if (label->kind == label_kind_code_forward) \
1457 call_forward((void *)jit_##name(NULL), label); \
1459 jit_patch_at(jit_##name(NULL), label->value); \
1462 jit_##name(value); \
1467 (void)identifier(ch);
1468 jit_name(parser.string);
1472 if (primary(skip_ws) != tok_register)
1473 error("bad register");
1474 jit_live(parser.regval);
1479 entry_im(frame) entry_im(tramp)
1484 jit_word_t i, im = get_imm();
1485 i = jit_allocai(im);
1486 symbol = get_symbol();
1487 symbol->type = type_l;
1488 symbol->value.i = i;
1490 entry_ir_ir(allocar)
1491 entry_ca(arg_c) entry_ca(arg_s)
1493 #if __WORDSIZE == 64
1497 entry_ia(getarg_c) entry_ia(getarg_uc)
1498 entry_ia(getarg_s) entry_ia(getarg_us)
1500 #if __WORDSIZE == 64
1501 entry_ia(getarg_ui) entry_ia(getarg_l)
1504 entry_ia(putargr_c) entry_ima(putargi_c)
1505 entry_ia(putargr_uc) entry_ima(putargi_uc)
1506 entry_ia(putargr_s) entry_ima(putargi_s)
1507 entry_ia(putargr_us) entry_ima(putargi_us)
1508 entry_ia(putargr_i) entry_ima(putargi_i)
1509 #if __WORDSIZE == 64
1510 entry_ia(putargr_ui) entry_ima(putargi_ui)
1511 entry_ia(putargr_l) entry_ima(putargi_l)
1513 entry_ia(putargr) entry_ima(putargi)
1514 entry_ir_ir_ir(addr) entry_ir_ir_im(addi)
1515 entry_ir_ir_ir(addxr) entry_ir_ir_im(addxi)
1516 entry_ir_ir_ir(addcr) entry_ir_ir_im(addci)
1517 entry_ir_ir_ir(subr) entry_ir_ir_im(subi)
1518 entry_ir_ir_ir(subxr) entry_ir_ir_im(subxi)
1519 entry_ir_ir_ir(subcr) entry_ir_ir_im(subci)
1520 entry_ir_ir_ir(rsbr) entry_ir_ir_im(rsbi)
1521 entry_ir_ir_ir(mulr) entry_ir_ir_im(muli)
1522 entry_ir_ir_ir_ir(qmulr) entry_ir_ir_ir_im(qmuli)
1523 entry_ir_ir_ir_ir(qmulr_u) entry_ir_ir_ir_im(qmuli_u)
1524 entry_ir_ir_ir(divr) entry_ir_ir_im(divi)
1525 entry_ir_ir_ir(divr_u) entry_ir_ir_im(divi_u)
1526 entry_ir_ir_ir_ir(qdivr) entry_ir_ir_ir_im(qdivi)
1527 entry_ir_ir_ir_ir(qdivr_u) entry_ir_ir_ir_im(qdivi_u)
1528 entry_ir_ir_ir(remr) entry_ir_ir_im(remi)
1529 entry_ir_ir_ir(remr_u) entry_ir_ir_im(remi_u)
1530 entry_ir_ir_ir(andr) entry_ir_ir_im(andi)
1531 entry_ir_ir_ir(orr) entry_ir_ir_im(ori)
1532 entry_ir_ir_ir(xorr) entry_ir_ir_im(xori)
1533 entry_ir_ir_ir(lshr) entry_ir_ir_im(lshi)
1534 entry_ir_ir_ir(rshr) entry_ir_ir_im(rshi)
1535 entry_ir_ir_ir(rshr_u) entry_ir_ir_im(rshi_u)
1536 entry_ir_ir(negr) entry_ir_ir(comr)
1537 entry_ir_ir(clor) entry_ir_ir(clzr)
1538 entry_ir_ir(ctor) entry_ir_ir(ctzr)
1539 entry_ir_ir_ir(ltr) entry_ir_ir_im(lti)
1540 entry_ir_ir_ir(ltr_u) entry_ir_ir_im(lti_u)
1541 entry_ir_ir_ir(ler) entry_ir_ir_im(lei)
1542 entry_ir_ir_ir(ler_u) entry_ir_ir_im(lei_u)
1543 entry_ir_ir_ir(eqr) entry_ir_ir_im(eqi)
1544 entry_ir_ir_ir(ger) entry_ir_ir_im(gei)
1545 entry_ir_ir_ir(ger_u) entry_ir_ir_im(gei_u)
1546 entry_ir_ir_ir(gtr) entry_ir_ir_im(gti)
1547 entry_ir_ir_ir(gtr_u) entry_ir_ir_im(gti_u)
1548 entry_ir_ir_ir(ner) entry_ir_ir_im(nei)
1549 entry_ir_ir_ir_ir(casr) entry_ir_im_ir_ir(casi)
1557 jit_gpr_t r0 = get_ireg();
1563 value = (void *)(jit_word_t)get_uint(skip_none);
1567 value = (void *)parser.value.i;
1570 switch (expression()) {
1572 value = (void *)parser.value.i;
1575 value = parser.value.p;
1578 error("expecting pointer");
1583 value = parser.value.p;
1587 label = get_label(skip_none);
1588 if (label->kind == label_kind_code ||
1589 label->kind == label_kind_code_forward) {
1590 mov_forward((void *)jit_movi(r0, 0), label);
1593 value = label->value;
1596 jit_movi(r0, (jit_word_t)value);
1598 entry_ir_ir(extr_c) entry_ir_ir(extr_uc)
1599 entry_ir_ir(extr_s) entry_ir_ir(extr_us)
1600 #if __WORDSIZE == 64
1601 entry_ir_ir(extr_i) entry_ir_ir(extr_ui)
1603 entry_ir_ir(htonr_us) entry_ir_ir(ntohr_us)
1604 entry_ir_ir(htonr_ui) entry_ir_ir(ntohr_ui)
1605 #if __WORDSIZE == 64
1606 entry_ir_ir(htonr_ul) entry_ir_ir(ntohr_ul)
1608 entry_ir_ir(htonr) entry_ir_ir(ntohr)
1609 entry_ir_ir(bswapr_us) entry_ir_ir(bswapr_ui)
1610 #if __WORDSIZE == 64
1611 entry_ir_ir(bswapr_ul)
1614 entry_ir_ir_ir(movnr) entry_ir_ir_ir(movzr)
1615 entry_ir_ir(ldr_c) entry_ir_pm(ldi_c)
1616 entry_ir_ir(ldr_uc) entry_ir_pm(ldi_uc)
1617 entry_ir_ir(ldr_s) entry_ir_pm(ldi_s)
1618 entry_ir_ir(ldr_us) entry_ir_pm(ldi_us)
1619 entry_ir_ir(ldr_i) entry_ir_pm(ldi_i)
1620 #if __WORDSIZE == 64
1621 entry_ir_ir(ldr_ui) entry_ir_pm(ldi_ui)
1622 entry_ir_ir(ldr_l) entry_ir_pm(ldi_l)
1624 entry_ir_ir(ldr) entry_ir_pm(ldi)
1625 entry_ir_ir_ir(ldxr_c) entry_ir_ir_im(ldxi_c)
1626 entry_ir_ir_ir(ldxr_uc) entry_ir_ir_im(ldxi_uc)
1627 entry_ir_ir_ir(ldxr_s) entry_ir_ir_im(ldxi_s)
1628 entry_ir_ir_ir(ldxr_us) entry_ir_ir_im(ldxi_us)
1629 entry_ir_ir_ir(ldxr_i) entry_ir_ir_im(ldxi_i)
1630 #if __WORDSIZE == 64
1631 entry_ir_ir_ir(ldxr_ui) entry_ir_ir_im(ldxi_ui)
1632 entry_ir_ir_ir(ldxr_l) entry_ir_ir_im(ldxi_l)
1634 entry_ir_ir_ir(ldxr) entry_ir_ir_im(ldxi)
1635 entry_ir_ir(str_c) entry_pm_ir(sti_c)
1636 entry_ir_ir(str_s) entry_pm_ir(sti_s)
1637 entry_ir_ir(str_i) entry_pm_ir(sti_i)
1638 #if __WORDSIZE == 64
1639 entry_ir_ir(str_l) entry_pm_ir(sti_l)
1641 entry_ir_ir(str) entry_pm_ir(sti)
1642 entry_ir_ir_ir(stxr_c) entry_im_ir_ir(stxi_c)
1643 entry_ir_ir_ir(stxr_s) entry_im_ir_ir(stxi_s)
1644 entry_ir_ir_ir(stxr_i) entry_im_ir_ir(stxi_i)
1645 #if __WORDSIZE == 64
1646 entry_ir_ir_ir(stxr_l) entry_im_ir_ir(stxi_l)
1648 entry_ir_ir_ir(stxr) entry_im_ir_ir(stxi)
1649 entry_lb_ir_ir(bltr) entry_lb_ir_im(blti)
1650 entry_lb_ir_ir(bltr_u) entry_lb_ir_im(blti_u)
1651 entry_lb_ir_ir(bler) entry_lb_ir_im(blei)
1652 entry_lb_ir_ir(bler_u) entry_lb_ir_im(blei_u)
1653 entry_lb_ir_ir(beqr) entry_lb_ir_im(beqi)
1654 entry_lb_ir_ir(bger) entry_lb_ir_im(bgei)
1655 entry_lb_ir_ir(bger_u) entry_lb_ir_im(bgei_u)
1656 entry_lb_ir_ir(bgtr) entry_lb_ir_im(bgti)
1657 entry_lb_ir_ir(bgtr_u) entry_lb_ir_im(bgti_u)
1658 entry_lb_ir_ir(bner) entry_lb_ir_im(bnei)
1659 entry_lb_ir_ir(bmsr) entry_lb_ir_im(bmsi)
1660 entry_lb_ir_ir(bmcr) entry_lb_ir_im(bmci)
1661 entry_lb_ir_ir(boaddr) entry_lb_ir_im(boaddi)
1662 entry_lb_ir_ir(boaddr_u) entry_lb_ir_im(boaddi_u)
1663 entry_lb_ir_ir(bxaddr) entry_lb_ir_im(bxaddi)
1664 entry_lb_ir_ir(bxaddr_u) entry_lb_ir_im(bxaddi_u)
1665 entry_lb_ir_ir(bosubr) entry_lb_ir_im(bosubi)
1666 entry_lb_ir_ir(bosubr_u) entry_lb_ir_im(bosubi_u)
1667 entry_lb_ir_ir(bxsubr) entry_lb_ir_im(bxsubi)
1668 entry_lb_ir_ir(bxsubr_u) entry_lb_ir_im(bxsubi_u)
1669 entry_ir(jmpr) entry_lb(jmpi)
1670 entry_ir(callr) entry_fn(calli)
1672 entry_ir(pushargr_c) entry_im(pushargi_c)
1673 entry_ir(pushargr_uc) entry_im(pushargi_uc)
1674 entry_ir(pushargr_s) entry_im(pushargi_s)
1675 entry_ir(pushargr_us) entry_im(pushargi_us)
1676 entry_ir(pushargr_i) entry_im(pushargi_i)
1677 #if __WORDSIZE == 64
1678 entry_ir(pushargr_ui) entry_im(pushargi_ui)
1679 entry_ir(pushargr_l) entry_im(pushargi_l)
1681 entry_ir(pushargr) entry_im(pushargi)
1682 entry_ir(finishr) entry_fn(finishi)
1684 entry_ir(retr_c) entry_im(reti_c)
1685 entry_ir(retr_uc) entry_im(reti_uc)
1686 entry_ir(retr_s) entry_im(reti_s)
1687 entry_ir(retr_us) entry_im(reti_us)
1688 entry_ir(retr_i) entry_im(reti_i)
1689 #if __WORDSIZE == 64
1690 entry_ir(retr_ui) entry_im(reti_ui)
1691 entry_ir(retr_l) entry_im(reti_l)
1693 entry_ir(retr) entry_im(reti)
1694 entry_ir(retval_c) entry_ir(retval_uc)
1695 entry_ir(retval_s) entry_ir(retval_us)
1697 #if __WORDSIZE == 64
1698 entry_ir(retval_ui) entry_ir(retval_l)
1702 entry_ca(arg_f) entry_fa(getarg_f)
1703 entry_fa(putargr_f) entry_fma(putargi_f)
1704 entry_fr_fr_fr(addr_f) entry_fr_fr_fm(addi_f)
1705 entry_fr_fr_fr(subr_f) entry_fr_fr_fm(subi_f)
1706 entry_fr_fr_fr(rsbr_f) entry_fr_fr_fm(rsbi_f)
1707 entry_fr_fr_fr(mulr_f) entry_fr_fr_fm(muli_f)
1708 entry_fr_fr_fr(divr_f) entry_fr_fr_fm(divi_f)
1709 entry_fr_fr(negr_f) entry_fr_fr(absr_f)
1710 entry_fr_fr(sqrtr_f)
1711 entry_ir_fr_fr(ltr_f) entry_ir_fr_fm(lti_f)
1712 entry_ir_fr_fr(ler_f) entry_ir_fr_fm(lei_f)
1713 entry_ir_fr_fr(eqr_f) entry_ir_fr_fm(eqi_f)
1714 entry_ir_fr_fr(ger_f) entry_ir_fr_fm(gei_f)
1715 entry_ir_fr_fr(gtr_f) entry_ir_fr_fm(gti_f)
1716 entry_ir_fr_fr(ner_f) entry_ir_fr_fm(nei_f)
1717 entry_ir_fr_fr(unltr_f) entry_ir_fr_fm(unlti_f)
1718 entry_ir_fr_fr(unler_f) entry_ir_fr_fm(unlei_f)
1719 entry_ir_fr_fr(uneqr_f) entry_ir_fr_fm(uneqi_f)
1720 entry_ir_fr_fr(unger_f) entry_ir_fr_fm(ungei_f)
1721 entry_ir_fr_fr(ungtr_f) entry_ir_fr_fm(ungti_f)
1722 entry_ir_fr_fr(ltgtr_f) entry_ir_fr_fm(ltgti_f)
1723 entry_ir_fr_fr(ordr_f) entry_ir_fr_fm(ordi_f)
1724 entry_ir_fr_fr(unordr_f) entry_ir_fr_fm(unordi_f)
1725 entry_ir_fr(truncr_f_i)
1726 #if __WORDSIZE == 64
1727 entry_ir_fr(truncr_f_l)
1729 entry_ir_fr(truncr_f)
1730 entry_fr_ir(extr_f) entry_fr_fr(extr_d_f)
1731 entry_fr_fr(movr_f) entry_fr_fm(movi_f)
1732 entry_fr_ir(ldr_f) entry_fr_pm(ldi_f)
1733 entry_fr_ir_ir(ldxr_f) entry_fr_ir_im(ldxi_f)
1734 entry_ir_fr(str_f) entry_pm_fr(sti_f)
1735 entry_ir_ir_fr(stxr_f) entry_im_ir_fr(stxi_f)
1736 entry_lb_fr_fr(bltr_f) entry_lb_fr_fm(blti_f)
1737 entry_lb_fr_fr(bler_f) entry_lb_fr_fm(blei_f)
1738 entry_lb_fr_fr(beqr_f) entry_lb_fr_fm(beqi_f)
1739 entry_lb_fr_fr(bger_f) entry_lb_fr_fm(bgei_f)
1740 entry_lb_fr_fr(bgtr_f) entry_lb_fr_fm(bgti_f)
1741 entry_lb_fr_fr(bner_f) entry_lb_fr_fm(bnei_f)
1742 entry_lb_fr_fr(bunltr_f) entry_lb_fr_fm(bunlti_f)
1743 entry_lb_fr_fr(bunler_f) entry_lb_fr_fm(bunlei_f)
1744 entry_lb_fr_fr(buneqr_f) entry_lb_fr_fm(buneqi_f)
1745 entry_lb_fr_fr(bunger_f) entry_lb_fr_fm(bungei_f)
1746 entry_lb_fr_fr(bungtr_f) entry_lb_fr_fm(bungti_f)
1747 entry_lb_fr_fr(bltgtr_f) entry_lb_fr_fm(bltgti_f)
1748 entry_lb_fr_fr(bordr_f) entry_lb_fr_fm(bordi_f)
1749 entry_lb_fr_fr(bunordr_f) entry_lb_fr_fm(bunordi_f)
1750 entry_fr(pushargr_f) entry_fm(pushargi_f)
1751 entry_fr(retr_f) entry_fm(reti_f)
1753 entry_ca(arg_d) entry_fa(getarg_d)
1754 entry_fa(putargr_d) entry_fma(putargi_d)
1755 entry_fr_fr_fr(addr_d) entry_fr_fr_dm(addi_d)
1756 entry_fr_fr_fr(subr_d) entry_fr_fr_dm(subi_d)
1757 entry_fr_fr_fr(rsbr_d) entry_fr_fr_dm(rsbi_d)
1758 entry_fr_fr_fr(mulr_d) entry_fr_fr_dm(muli_d)
1759 entry_fr_fr_fr(divr_d) entry_fr_fr_dm(divi_d)
1760 entry_fr_fr(negr_d) entry_fr_fr(absr_d)
1761 entry_fr_fr(sqrtr_d)
1762 entry_ir_fr_fr(ltr_d) entry_ir_fr_dm(lti_d)
1763 entry_ir_fr_fr(ler_d) entry_ir_fr_dm(lei_d)
1764 entry_ir_fr_fr(eqr_d) entry_ir_fr_dm(eqi_d)
1765 entry_ir_fr_fr(ger_d) entry_ir_fr_dm(gei_d)
1766 entry_ir_fr_fr(gtr_d) entry_ir_fr_dm(gti_d)
1767 entry_ir_fr_fr(ner_d) entry_ir_fr_dm(nei_d)
1768 entry_ir_fr_fr(unltr_d) entry_ir_fr_dm(unlti_d)
1769 entry_ir_fr_fr(unler_d) entry_ir_fr_dm(unlei_d)
1770 entry_ir_fr_fr(uneqr_d) entry_ir_fr_dm(uneqi_d)
1771 entry_ir_fr_fr(unger_d) entry_ir_fr_dm(ungei_d)
1772 entry_ir_fr_fr(ungtr_d) entry_ir_fr_dm(ungti_d)
1773 entry_ir_fr_fr(ltgtr_d) entry_ir_fr_dm(ltgti_d)
1774 entry_ir_fr_fr(ordr_d) entry_ir_fr_dm(ordi_d)
1775 entry_ir_fr_fr(unordr_d) entry_ir_fr_dm(unordi_d)
1776 entry_ir_fr(truncr_d_i)
1777 #if __WORDSIZE == 64
1778 entry_ir_fr(truncr_d_l)
1780 entry_ir_fr(truncr_d)
1781 entry_fr_ir(extr_d) entry_fr_fr(extr_f_d)
1782 entry_fr_fr(movr_d) entry_fr_dm(movi_d)
1783 entry_fr_ir(ldr_d) entry_fr_pm(ldi_d)
1784 entry_fr_ir_ir(ldxr_d) entry_fr_ir_im(ldxi_d)
1785 entry_ir_fr(str_d) entry_pm_fr(sti_d)
1786 entry_ir_ir_fr(stxr_d) entry_im_ir_fr(stxi_d)
1787 entry_lb_fr_fr(bltr_d) entry_lb_fr_dm(blti_d)
1788 entry_lb_fr_fr(bler_d) entry_lb_fr_dm(blei_d)
1789 entry_lb_fr_fr(beqr_d) entry_lb_fr_dm(beqi_d)
1790 entry_lb_fr_fr(bger_d) entry_lb_fr_dm(bgei_d)
1791 entry_lb_fr_fr(bgtr_d) entry_lb_fr_dm(bgti_d)
1792 entry_lb_fr_fr(bner_d) entry_lb_fr_dm(bnei_d)
1793 entry_lb_fr_fr(bunltr_d) entry_lb_fr_dm(bunlti_d)
1794 entry_lb_fr_fr(bunler_d) entry_lb_fr_dm(bunlei_d)
1795 entry_lb_fr_fr(buneqr_d) entry_lb_fr_dm(buneqi_d)
1796 entry_lb_fr_fr(bunger_d) entry_lb_fr_dm(bungei_d)
1797 entry_lb_fr_fr(bungtr_d) entry_lb_fr_dm(bungti_d)
1798 entry_lb_fr_fr(bltgtr_d) entry_lb_fr_dm(bltgti_d)
1799 entry_lb_fr_fr(bordr_d) entry_lb_fr_dm(bordi_d)
1800 entry_lb_fr_fr(bunordr_d) entry_lb_fr_dm(bunordi_d)
1801 entry_fr(pushargr_d) entry_dm(pushargi_d)
1802 entry_fr(retr_d) entry_dm(reti_d)
1807 jit_gpr_t r0 = get_ireg();
1813 jit_gpr_t r0 = get_ireg();
1819 jit_gpr_t r0 = get_ireg(), r1 = get_ireg();
1825 jit_fpr_t r0 = get_freg();
1826 jit_gpr_t r1 = get_ireg();
1827 jit_va_arg_d(r0, r1);
1832 jit_gpr_t r0 = get_ireg();
1838 #undef entry_lb_fr_fm
1839 #undef entry_lb_fr_dm
1840 #undef entry_lb_fr_fr
1841 #undef entry_im_ir_fr
1842 #undef entry_ir_ir_fr
1844 #undef entry_fr_ir_ir
1845 #undef entry_fr_ir_im
1851 #undef entry_ir_fr_fm
1852 #undef entry_ir_fr_dm
1853 #undef entry_ir_fr_fr
1855 #undef entry_fr_fr_fm
1856 #undef entry_fr_fr_dm
1857 #undef entry_fr_fr_fr
1862 #undef entry_lb_ir_im
1863 #undef entry_lb_ir_ir
1864 #undef entry_im_ir_ir
1869 #undef entry_ir_ir_im
1870 #undef entry_ir_ir_ir
1879 error(const char *format, ...)
1885 va_start(ap, format);
1886 message("error", format, ap);
1888 length = parser.data.length - parser.data.offset;
1889 string = (char *)(parser.data.buffer + parser.data.offset - 1);
1891 strcpy(string + 74, "...");
1893 parser.data.buffer[parser.data.length - 1] = '\0';
1894 fprintf(stderr, "(%s)\n", string);
1899 warn(const char *format, ...)
1902 va_start(ap, format);
1903 message("warning", format, ap);
1908 message(const char *kind, const char *format, va_list ap)
1910 fprintf(stderr, "%s:%d: %s: ", parser.name,
1911 parser.line - parser.newline, kind);
1912 vfprintf(stderr, format, ap);
1913 fputc('\n', stderr);
1921 if (parser.data.offset < parser.data.length)
1922 ch = parser.data.buffer[parser.data.offset++];
1924 /* keep first offset for ungetch */
1925 if ((parser.data.length = fread(parser.data.buffer + 1, 1,
1926 sizeof(parser.data.buffer) - 1,
1927 parser.fp) + 1) <= 1) {
1929 parser.data.offset = 1;
1932 ch = parser.data.buffer[1];
1933 parser.data.offset = 2;
1936 if ((parser.newline = ch == '\n'))
1948 error("unexpected end of file");
1956 if ((parser.newline = ch == '\n'))
1959 if (parser.data.offset)
1960 parser.data.buffer[--parser.data.offset] = ch;
1963 parser.data.buffer[0] = ch;
1973 for (ch = getch();; ch = getch()) {
1983 case ' ': case '\f': case '\r': case '\t':
1996 for (ch = getch();; ch = getch()) {
2006 case ' ': case '\f': case '\n': case '\r': case '\t':
2008 /* handle as newline */
2025 for (ch = getch(); ch != '\n' && ch != EOF; ch = getch())
2029 for (; ch != '/';) {
2030 while (getch_noeof() != '*')
2032 while ((ch = getch_noeof()) == '*')
2047 for (ch = getch(); ch != '\n' && ch != EOF; ch = getch()) {
2050 if ((number(ch)) == tok_int)
2051 parser.line = parser.value.i - 1;
2055 if (parser.offset >= (int)sizeof(parser.name)) {
2056 strncpy(parser.name, parser.string, sizeof(parser.name));
2057 parser.name[sizeof(parser.name) - 1] = '\0';
2060 strcpy(parser.name, parser.string);
2071 get_int(skip_t skip)
2073 switch (primary(skip)) {
2077 parser.type = type_l;
2078 parser.value.i = (jit_word_t)parser.value.p;
2081 error("expecting integer");
2084 return (parser.value.i);
2088 get_uint(skip_t skip)
2090 switch (primary(skip)) {
2091 case tok_char: case tok_int:
2094 parser.type = type_l;
2095 parser.value.ui = (jit_uword_t)parser.value.p;
2098 error("expecting integer");
2101 return (parser.value.ui);
2105 get_float(skip_t skip)
2107 switch (primary(skip)) {
2110 parser.type = type_d;
2111 parser.value.d = parser.value.i;
2116 error("expecting float");
2119 return (parser.value.d);
2122 /* Workaround gcc not converting unordered values from double to
2123 * float (as done in other architectures) on s390 */
2125 make_float(double d)
2127 /* This is an workaround to a bug in Hercules s390 emulator,
2128 * and at least HP-UX ia64 not have these */
2129 #if defined(HAVE_ISNAN) && defined(HAVE_ISINF)
2130 if (isnan(d)) return ( 0.0f/0.0f);
2132 if (d > 0.0) return ( 1.0f/0.0f);
2133 else return (-1.0f/0.0f);
2140 get_pointer(skip_t skip)
2143 token_t token = primary(skip);
2147 label = get_label_by_name(parser.string);
2149 error("bad identifier %s", parser.string);
2150 switch (label->kind) {
2151 case label_kind_data:
2152 case label_kind_code:
2154 case label_kind_code_forward:
2155 /* as expression arguments */
2156 error("forward references not implemented");
2158 case label_kind_dynamic:
2161 parser.type = type_p;
2162 return (parser.value.p = label->value);
2164 parser.type = type_p;
2165 return (parser.value.p = (void *)parser.value.ui);
2167 return (parser.value.p);
2168 default: error("bad pointer");
2173 get_label(skip_t skip)
2182 case 'a' ... 'z': case 'A' ... 'Z': case '_':
2183 (void)identifier(ch);
2186 error("expecting label/immediate");
2188 if ((label = get_label_by_name(parser.string)) == NULL)
2189 label = new_label(label_kind_code_forward,
2190 parser.string, jit_forward());
2199 int check = 1, ch = getch();
2203 parser.regtype = type_l;
2204 switch (ch = getch()) {
2205 case '0': parser.regval = JIT_R0; break;
2206 case '1': parser.regval = JIT_R1; break;
2207 case '2': parser.regval = JIT_R2; break;
2209 num = get_int(skip_none);
2210 if (num < 0 || num >= JIT_R_NUM) goto fail;
2211 parser.regval = JIT_R(num);
2212 if (getch() != ')') goto fail;
2219 parser.regtype = type_l;
2220 switch (ch = getch()) {
2221 case '0': parser.regval = JIT_V0; break;
2222 case '1': parser.regval = JIT_V1; break;
2223 case '2': parser.regval = JIT_V2; break;
2226 num = get_int(skip_none);
2227 if (num < 0 || num >= JIT_V_NUM) goto fail;
2228 parser.regval = JIT_V(num);
2229 if (getch() != ')') goto fail;
2235 parser.regtype = type_d;
2236 switch (ch = getch()) {
2237 case '0': parser.regval = JIT_F0; break;
2238 case '1': parser.regval = JIT_F1; break;
2239 case '2': parser.regval = JIT_F2; break;
2240 case '3': parser.regval = JIT_F3; break;
2241 case '4': parser.regval = JIT_F4; break;
2242 case '5': parser.regval = JIT_F5; break;
2244 parser.regtype = type_l; /* oops */
2245 parser.regval = JIT_FP; break;
2247 num = get_int(skip_none);
2248 if (num < 0 || num >= JIT_F_NUM) goto fail;
2249 parser.regval = JIT_F(num);
2250 if (getch() != ')') goto fail;
2258 error("bad register");
2262 if ((ch >= 'a' && ch <= 'z') ||
2263 (ch >= 'A' && ch <= 'Z') ||
2264 (ch >= '0' && ch <= '9') ||
2270 return (tok_register);
2276 parser.string[0] = ch;
2277 for (parser.offset = 1;;) {
2278 switch ((ch = getch())) {
2279 case 'a' ... 'z': case 'A' ... 'Z': case '0' ... '9' : case '_':
2280 if (parser.offset + 1 >= MAX_IDENTIFIER) {
2281 parser.string[parser.offset] = '\0';
2282 error("bad identifier %s", parser.string);
2284 parser.string[parser.offset++] = ch;
2287 parser.string[parser.offset] = '\0';
2289 return (tok_symbol);
2295 get_data(type_t type)
2304 switch (token = primary(skip_ws)) {
2305 case tok_char: case tok_int:
2306 check_data(sizeof(signed char));
2307 *(signed char *)(data + data_offset) = parser.value.i;
2308 data_offset += sizeof(char);
2311 check_data(parser.offset);
2312 memcpy(data + data_offset, parser.string,
2314 data_offset += parser.offset;
2317 case tok_semicollon:
2318 if (test == data) error("syntax error");
2320 default: error("bad initializer");
2324 check_data(sizeof(signed short));
2325 *(signed short *)(data + data_offset) = get_int(skip_ws);
2326 data_offset += sizeof(short);
2329 check_data(sizeof(signed int));
2330 *(signed int *)(data + data_offset) = get_int(skip_ws);
2331 data_offset += sizeof(int);
2334 check_data(sizeof(jit_word_t));
2335 *(jit_word_t *)(data + data_offset) = get_int(skip_ws);
2336 data_offset += sizeof(jit_word_t);
2339 check_data(sizeof(float));
2340 *(float *)(data + data_offset) = get_float(skip_ws);
2341 data_offset += sizeof(float);
2344 check_data(sizeof(double));
2345 *(double *)(data + data_offset) = get_float(skip_ws);
2346 data_offset += sizeof(double);
2349 /* FIXME **patch if realloc** */
2350 check_data(sizeof(void*));
2351 *(void **)(data + data_offset) = get_pointer(skip_ws);
2352 data_offset += sizeof(void*);
2358 if (ch == '\n' || ch == ';' || ch == EOF)
2368 size_t offset, length;
2370 switch (ch = getch_noeof()) {
2372 /* use .$(expression) for non side effects expression */
2375 case 'a' ... 'z': case 'A' ... 'Z': case '_':
2376 (void)identifier(ch);
2380 if (skipws() != '$')
2381 error("expecting symbol");
2382 /* allow spaces before an expression */
2386 if (parser.string[1] == '\0') {
2387 switch (parser.string[0]) {
2388 case 'c': get_data(type_c); break;
2389 case 's': get_data(type_s); break;
2390 case 'i': get_data(type_i); break;
2391 case 'l': get_data(type_l); break;
2392 case 'f': get_data(type_f); break;
2393 case 'd': get_data(type_d); break;
2394 case 'p': get_data(type_p); break;
2395 default: error("bad type .%c", parser.string[0]);
2398 else if (strcmp(parser.string, "data") == 0) {
2399 if (parser.parsing != PARSING_NONE)
2400 error(".data must be specified once and be the first section");
2401 parser.parsing = PARSING_DATA;
2402 data_length = get_int(skip_ws);
2403 data = (char *)xcalloc(1, data_length);
2405 else if (strcmp(parser.string, "code") == 0) {
2406 if (parser.parsing != PARSING_NONE &&
2407 parser.parsing != PARSING_DATA)
2408 error(".code must be specified once only");
2409 parser.parsing = PARSING_CODE;
2411 else if (strcmp(parser.string, "align") == 0) {
2412 length = get_int(skip_ws);
2413 if (parser.parsing != PARSING_DATA)
2414 error(".align must be in .data");
2415 if (length > 1 && length <= 4096 && !(length & (length - 1))) {
2416 offset = data_offset;
2417 offset += length - ((offset + length) % length);
2418 check_data(offset - data_offset);
2419 data_offset = offset;
2422 error("bad .align %ld (must be a power of 2, >= 2 && <= 4096)",
2423 (jit_word_t)length);
2425 else if (strcmp(parser.string, "size") == 0) {
2426 length = get_int(skip_ws);
2427 if (parser.parsing != PARSING_DATA)
2428 error(".size must be in .data");
2430 data_offset += length;
2432 else if (strcmp(parser.string, "disasm") == 0)
2435 error("unknown command .%s", parser.string);
2441 char buffer[1024], *endptr;
2442 int integer = 1, offset = 0, neg = 0, e = 0, d = 0, base = 10;
2444 for (;; ch = getch()) {
2451 if (offset && buffer[offset - 1] != 'e') {
2459 if (offset && buffer[offset - 1] != 'e') {
2472 if (offset == 0 && base == 10) {
2478 if (offset == 0 && base == 8) {
2496 if (offset == 0 && base == 8) {
2501 case 'a': case 'c': case 'd': case 'f':
2514 case '_': case 'g' ... 'w': case 'y': case 'z': case 'A' ... 'Z':
2516 buffer[offset++] = '\0';
2517 error("bad constant %s", buffer);
2522 if (offset + 1 >= (int)sizeof(buffer))
2524 buffer[offset++] = ch;
2527 /* check for literal 0 */
2528 if (offset == 0 && base == 8) buffer[offset++] = '0';
2529 buffer[offset] = '\0';
2532 # define STRTOUL strtoull
2534 # define STRTOUL strtoul
2536 parser.value.ui = STRTOUL(buffer, &endptr, base);
2537 parser.type = type_l;
2539 parser.value.i = -parser.value.i;
2542 parser.type = type_d;
2543 parser.value.d = strtod(buffer, &endptr);
2545 parser.value.d = -parser.value.d;
2550 return (integer ? tok_int : tok_float);
2557 case 'a': ch = '\a'; break;
2558 case 'b': ch = '\b'; break;
2559 case 'f': ch = '\f'; break;
2560 case 'n': ch = '\n'; break;
2561 case 'r': ch = '\r'; break;
2562 case 't': ch = '\t'; break;
2563 case 'v': ch = '\v'; break;
2575 for (parser.offset = 0;;) {
2576 switch (ch = getch_noeof()) {
2578 if (esc) goto append;
2583 parser.string[parser.offset++] = '\0';
2584 parser.value.p = parser.string;
2585 parser.type = type_p;
2586 return (tok_string);
2595 if (parser.offset + 1 >= parser.length) {
2596 parser.length += 4096;
2597 parser.string = (char *)xrealloc(parser.string,
2600 parser.string[parser.offset++] = ch;
2611 if ((ch = getch_noeof()) == '\\') {
2615 if (getch_noeof() != '\'')
2616 error("bad single byte char");
2619 parser.type = type_l;
2620 parser.value.i = ch & 0xff;
2631 (void)identifier('@');
2632 if ((label = get_label_by_name(parser.string)) == NULL) {
2633 #if __CYGWIN__ ||_WIN32
2634 /* FIXME kludge to pass varargs test case, otherwise,
2635 * will not print/scan float values */
2636 if (strcmp(parser.string + 1, "sprintf") == 0)
2638 else if (strcmp(parser.string + 1, "sscanf") == 0)
2643 value = dlsym(DL_HANDLE, parser.string + 1);
2644 if ((string = dlerror()))
2645 error("%s", string);
2647 label = new_label(label_kind_dynamic, parser.string, value);
2649 parser.type = type_p;
2650 parser.value.p = label->value;
2652 return (tok_pointer);
2656 expression_prim(void)
2663 if (parser.putback) {
2664 parser.expr = parser.putback;
2665 parser.putback = (expr_t)0;
2668 switch (ch = skipws()) {
2670 if ((ch = getch_noeof()) == '=') parser.expr = expr_ne;
2672 ungetch(ch); parser.expr = expr_not;
2675 case '~': parser.expr = expr_com;
2678 if ((ch = getch_noeof()) == '=') parser.expr = expr_mulset;
2680 ungetch(ch); parser.expr = expr_mul;
2684 if ((ch = getch_noeof()) == '=') parser.expr = expr_divset;
2686 ungetch(ch); parser.expr = expr_div;
2690 if ((ch = getch_noeof()) == '=') parser.expr = expr_remset;
2692 ungetch(ch); parser.expr = expr_rem;
2696 switch (ch = getch_noeof()) {
2697 case '+': parser.expr = expr_inc;
2699 case '=': parser.expr = expr_addset;
2701 default: ungetch(ch); parser.expr = expr_add;
2706 switch (ch = getch_noeof()) {
2707 case '-': parser.expr = expr_dec;
2709 case '=': parser.expr = expr_subset;
2711 default: ungetch(ch); parser.expr = expr_sub;
2716 switch (ch = getch_noeof()) {
2717 case '=': parser.expr = expr_le;
2719 case '<': ch = getch_noeof();
2720 if (ch == '=') parser.expr = expr_lshset;
2722 ungetch(ch); parser.expr = expr_lsh;
2725 default: ungetch(ch); parser.expr = expr_lt;
2730 switch (ch = getch_noeof()) {
2731 case '=': parser.expr = expr_ge;
2733 case '>': ch = getch_noeof();
2734 if (ch == '=') parser.expr = expr_rshset;
2736 ungetch(ch); parser.expr = expr_rsh;
2739 default: ungetch(ch); parser.expr = expr_gt;
2744 switch (ch = getch_noeof()) {
2745 case '=': parser.expr = expr_andset;
2747 case '&': parser.expr = expr_andand;
2749 default: ungetch(ch); parser.expr = expr_and;
2754 switch (ch = getch_noeof()) {
2755 case '=': parser.expr = expr_orset;
2757 case '|': parser.expr = expr_oror;
2759 default: ungetch(ch); parser.expr = expr_or;
2764 if ((ch = getch_noeof()) == '=') parser.expr = expr_xorset;
2766 ungetch(ch); parser.expr = expr_xor;
2770 if ((ch = getch_noeof()) == '=') parser.expr = expr_eq;
2772 ungetch(ch); parser.expr = expr_set;
2775 case '(': parser.expr = expr_lparen;
2777 case ')': parser.expr = expr_rparen;
2781 parser.expr = token == tok_int ? expr_int : expr_float;
2785 parser.expr = expr_pointer;
2789 /* no support for nested expressions */
2790 if (parser.string[0] == '\0')
2791 error("syntax error");
2792 parser.expr = expr_symbol;
2793 if ((symbol = get_symbol_by_name(parser.string)) != NULL) {
2794 parser.type = symbol->type;
2795 parser.value = symbol->value;
2798 /* only create symbol on assignment */
2799 parser.type = type_none;
2801 case 'a' ... 'z': case 'A' ... 'Z': case '_':
2803 if ((label = get_label_by_name(parser.string))) {
2804 if (label->kind == label_kind_code_forward)
2805 error("forward value for %s not supported",
2807 parser.expr = expr_pointer;
2808 parser.type = type_p;
2809 parser.value.p = label->value;
2812 error("invalid identifier %s", parser.string);
2816 parser.expr = expr_int;
2819 /* not smart enough to put it in data and/or relocate it, etc */
2820 error("must declare strings as data");
2822 error("syntax error");
2827 expression_inc(int pre)
2833 if (parser.expr != expr_symbol)
2834 error("syntax error");
2836 if ((symbol = get_symbol_by_name(parser.string)) == NULL) {
2837 if (!parser.short_circuit)
2838 error("undefined symbol %s", symbol->name);
2840 if (!parser.short_circuit) {
2841 parser.type = symbol->type;
2843 parser.value = symbol->value;
2844 switch (symbol->type) {
2849 /* should really be an error */
2850 symbol->value.d += 1.0;
2857 parser.value = symbol->value;
2863 expression_dec(int pre)
2869 if (parser.expr != expr_symbol)
2870 error("syntax error");
2872 if ((symbol = get_symbol_by_name(parser.string)) == NULL) {
2873 if (!parser.short_circuit)
2874 error("undefined symbol %s", symbol->name);
2876 if (!parser.short_circuit) {
2877 parser.type = symbol->type;
2879 parser.value = symbol->value;
2880 switch (symbol->type) {
2885 /* should really be an error */
2886 symbol->value.d -= 1.0;
2893 parser.value = symbol->value;
2899 expression_unary(void)
2905 switch (parser.expr) {
2908 switch (parser.type) {
2913 error("syntax error");
2918 switch (parser.type) {
2920 parser.value.i = -parser.value.i;
2923 parser.value.d = -parser.value.d;
2926 error("syntax error");
2937 switch (parser.type) {
2939 parser.value.i = !parser.value.i;
2942 parser.value.i = parser.value.d != 0;
2945 parser.value.i = parser.value.p != NULL;
2948 error("syntax error");
2950 parser.type = type_l;
2954 if (parser.type != type_l)
2955 error("syntax error");
2956 parser.value.i = ~parser.value.i;
2960 if (parser.expr != expr_rparen)
2961 error("syntax error");
2965 strcpy(buffer, parser.string);
2967 switch (parser.expr) {
2969 if ((symbol = get_symbol_by_name(buffer)) == NULL) {
2970 if (!parser.short_circuit)
2971 symbol = new_symbol(buffer);
2975 if (!parser.short_circuit) {
2977 error("syntax error");
2978 symbol->type = parser.type;
2979 symbol->value = parser.value;
2982 case expr_mulset: parser.putback = expr_mul;
2984 case expr_divset: parser.putback = expr_div;
2986 case expr_remset: parser.putback = expr_rem;
2988 case expr_addset: parser.putback = expr_add;
2990 case expr_subset: parser.putback = expr_sub;
2992 case expr_lshset: parser.putback = expr_lsh;
2994 case expr_rshset: parser.putback = expr_rsh;
2996 case expr_andset: parser.putback = expr_and;
2998 case expr_orset: parser.putback = expr_or;
3000 case expr_xorset: parser.putback = expr_xor;
3002 if ((symbol = get_symbol_by_name(buffer)) == NULL) {
3003 if (!parser.short_circuit)
3004 error("undefined symbol %s", buffer);
3005 parser.type = type_l;
3008 switch (parser.putback) {
3009 case expr_mul: case expr_div: case expr_rem:
3012 case expr_add: case expr_sub:
3015 case expr_lsh: case expr_rsh:
3018 case expr_and: case expr_or: case expr_xor:
3038 /* make next token available */
3046 expression_mul(void)
3052 switch (parser.type) {
3053 case type_l: case type_d: case type_p: break;
3057 switch (parser.expr) {
3059 type = parser.type, value = parser.value;
3061 switch (parser.type) {
3064 value.i *= parser.value.i;
3066 value.d *= parser.value.i;
3069 if (type == type_l) {
3073 value.d *= parser.value.d;
3076 error("invalid operand");
3078 parser.type = type, parser.value = value;
3081 type = parser.type, value = parser.value;
3083 switch (parser.type) {
3085 if (type == type_l) {
3086 if (parser.value.i == 0)
3087 error("divide by zero");
3088 value.i /= parser.value.i;
3091 value.d /= parser.value.i;
3094 if (type == type_l) {
3098 value.d /= parser.value.d;
3101 error("invalid operand");
3103 parser.type = type, parser.value = value;
3106 type = parser.type, value = parser.value;
3108 switch (parser.type) {
3110 if (type == type_l) {
3111 if (parser.value.i == 0)
3112 error("divide by zero");
3113 value.i %= parser.value.i;
3116 error("invalid operand");
3119 error("invalid operand");
3121 parser.type = type, parser.value = value;
3130 expression_add(void)
3136 switch (parser.type) {
3137 case type_l: case type_d: case type_p: break;
3141 switch (parser.expr) {
3143 type = parser.type, value = parser.value;
3145 switch (parser.type) {
3149 value.i += parser.value.i;
3152 value.d += parser.value.i;
3155 value.cp += parser.value.i;
3168 error("invalid operand");
3170 value.d += parser.value.d;
3176 value.cp = value.i + parser.value.cp;
3179 error("invalid operand");
3183 error("invalid operand");
3185 parser.type = type, parser.value = value;
3188 type = parser.type, value = parser.value;
3190 switch (parser.type) {
3194 value.i -= parser.value.i;
3197 value.d -= parser.value.i;
3200 value.cp -= parser.value.i;
3213 error("invalid operand");
3215 value.d -= parser.value.d;
3221 value.i = value.cp - parser.value.cp;
3224 error("invalid operand");
3228 error("invalid operand");
3230 parser.type = type, parser.value = value;
3239 expression_shift(void)
3244 switch (parser.type) {
3245 case type_l: case type_d: case type_p: break;
3249 switch (parser.expr) {
3251 value = parser.value.i;
3252 if (parser.type != type_l)
3253 error("invalid operand");
3255 if (parser.type != type_l)
3256 error("invalid operand");
3257 value <<= parser.value.i;
3258 parser.value.i = value;
3261 value = parser.value.i;
3262 if (parser.type != type_l)
3263 error("invalid operand");
3265 if (parser.type != type_l)
3266 error("invalid operand");
3267 value >>= parser.value.i;
3268 parser.value.i = value;
3277 expression_bit(void)
3282 switch (parser.type) {
3283 case type_l: case type_d: case type_p: break;
3287 switch (parser.expr) {
3289 if (parser.type != type_l)
3290 error("invalid operand");
3293 if (parser.type != type_l)
3294 error("invalid operand");
3295 i &= parser.value.i;
3299 if (parser.type != type_l)
3300 error("invalid operand");
3303 if (parser.type != type_l)
3304 error("invalid operand");
3305 i |= parser.value.i;
3309 if (parser.type != type_l)
3310 error("invalid operand");
3313 if (parser.type != type_l)
3314 error("invalid operand");
3315 i ^= parser.value.i;
3325 expression_rel(void)
3331 switch (parser.type) {
3332 case type_l: case type_d: case type_p: break;
3336 switch (parser.expr) {
3338 type = parser.type, value = parser.value;
3340 switch (parser.type) {
3344 value.i = value.i < parser.value.i;
3347 value.i = value.d < parser.value.i;
3350 value.i = (jit_word_t)value.p < parser.value.i;
3357 value.i = value.i < parser.value.d;
3360 value.i = value.d < parser.value.d;
3363 error("invalid operand");
3369 value.i = value.i < (jit_word_t)parser.value.p;
3372 error("invalid operand");
3374 value.i = (jit_word_t)value.p < (jit_word_t)parser.value.p;
3379 error("invalid operand");
3381 parser.type = type_l, parser.value = value;
3384 type = parser.type, value = parser.value;
3386 switch (parser.type) {
3390 value.i = value.i <= parser.value.i;
3393 value.i = value.d <= parser.value.i;
3396 value.i = (jit_word_t)value.p <= parser.value.i;
3403 value.i = value.i <= parser.value.d;
3406 value.i = value.d <= parser.value.d;
3409 value.i = (jit_word_t)value.p <= parser.value.d;
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;
3477 type = parser.type, value = parser.value;
3479 switch (parser.type) {
3483 value.i = value.i >= parser.value.i;
3486 value.i = value.d >= parser.value.i;
3489 value.i = (jit_word_t)value.p >= parser.value.i;
3496 value.i = value.i >= parser.value.d;
3499 value.i = value.d >= parser.value.d;
3502 error("invalid operand");
3508 value.i = value.i >= (jit_word_t)parser.value.p;
3511 error("invalid operand");
3513 value.i = (jit_word_t)value.p >= (jit_word_t)parser.value.p;
3518 error("invalid operand");
3520 parser.type = type_l, parser.value = value;
3523 type = parser.type, value = parser.value;
3525 switch (parser.type) {
3529 value.i = value.i > parser.value.i;
3532 value.i = value.d > parser.value.i;
3535 value.i = (jit_word_t)value.p > parser.value.i;
3542 value.i = value.i > parser.value.d;
3545 value.i = value.d > parser.value.d;
3548 error("invalid operand");
3554 value.i = value.i > (jit_word_t)parser.value.p;
3557 error("invalid operand");
3559 value.i = (jit_word_t)value.p > (jit_word_t)parser.value.p;
3564 error("invalid operand");
3566 parser.type = type_l, parser.value = value;
3569 type = parser.type, value = parser.value;
3571 switch (parser.type) {
3575 value.i = value.i != parser.value.i;
3578 value.i = value.d != parser.value.i;
3581 value.i = (jit_word_t)value.p != parser.value.i;
3588 value.i = value.i != parser.value.d;
3591 value.i = value.d != parser.value.d;
3594 error("invalid operand");
3600 value.i = value.i != (jit_word_t)parser.value.p;
3603 error("invalid operand");
3605 value.i = value.p != parser.value.p;
3610 error("invalid operand");
3612 parser.type = type_l, parser.value = value;
3621 expression_cond(void)
3628 switch (parser.type) {
3629 case type_l: case type_d: case type_p: break;
3633 switch (parser.expr) {
3635 type = parser.type, value = parser.value;
3638 short_circuit = value.i == 0;
3641 short_circuit = value.d == 0.0;
3644 short_circuit = value.p == NULL;
3647 parser.short_circuit += short_circuit;
3649 parser.short_circuit -= short_circuit;
3650 switch (parser.type) {
3654 value.i = value.i && parser.value.i;
3657 value.i = value.d && parser.value.i;
3660 value.i = value.p && parser.value.i;
3667 value.i = value.i && parser.value.d;
3670 value.i = value.d && parser.value.d;
3673 value.i = value.p && parser.value.d;
3680 value.i = value.i && parser.value.p;
3683 value.i = value.d && parser.value.p;
3686 value.i = value.p && parser.value.p;
3691 error("invalid operand");
3693 parser.type = type_l, parser.value.i = value.i;
3696 type = parser.type, value = parser.value;
3699 short_circuit = value.i != 0;
3702 short_circuit = value.d != 0.0;
3705 short_circuit = value.p != NULL;
3708 parser.short_circuit += short_circuit;
3710 parser.short_circuit -= short_circuit;
3711 switch (parser.type) {
3715 value.i = value.i || parser.value.i;
3718 value.i = value.d || parser.value.i;
3721 value.i = value.p || parser.value.i;
3728 value.i = value.i || parser.value.d;
3731 value.i = value.d || parser.value.d;
3734 value.i = value.p || parser.value.d;
3741 value.i = value.i || parser.value.p;
3744 value.i = value.d || parser.value.p;
3747 value.i = value.p || parser.value.p;
3752 error("invalid operand");
3754 parser.type = type_l, parser.value.i = value.i;
3767 (void)identifier('$');
3768 if (parser.string[1] == '\0') {
3769 if (getch_noeof() != '(')
3770 error("bad symbol or expression");
3771 parser.type = type_none;
3773 if (parser.expr != expr_rparen)
3774 error("bad expression");
3775 switch (parser.type) {
3781 return (tok_pointer);
3783 error("bad expression");
3786 else if ((symbol = get_symbol_by_name(parser.string))) {
3787 switch (parser.type = symbol->type) {
3789 parser.value.i = symbol->value.i;
3792 parser.value.d = symbol->value.d;
3795 parser.value.p = symbol->value.p;
3796 return (tok_pointer);
3800 error("undefined symbol %s", parser.string);
3804 primary(skip_t skip)
3809 case skip_none: ch = getch(); break;
3810 case skip_ws: ch = skipws(); break;
3811 case skip_nl: ch = skipnl(); break;
3817 case 'a' ... 'z': case 'A' ... 'Z': case '_':
3818 return (identifier(ch));
3819 case '0' ... '9': case '+': case '-':
3820 return (number(ch));
3826 return (character());
3830 return (expression());
3834 return (tok_newline);
3836 return (tok_semicollon);
3838 error("syntax error");
3852 switch (token = primary(skip_nl)) {
3856 if ((label = get_label_by_name(parser.string))) {
3857 if (label->kind == label_kind_code_forward) {
3858 label->kind = label_kind_code;
3859 jit_link(label->value);
3860 jit_note(parser.name, parser.line);
3863 error("label %s: redefined", parser.string);
3866 if (parser.parsing == PARSING_DATA) {
3867 value = data + data_offset;
3868 label = new_label(label_kind_data,
3869 parser.string, value);
3871 else if (parser.parsing == PARSING_CODE) {
3872 value = jit_label();
3873 jit_note(parser.name, parser.line);
3874 label = new_label(label_kind_code,
3875 parser.string, value);
3878 error("label not in .code or .data");
3884 (instr_t *)get_hash(instrs, parser.string)) == NULL)
3885 error("unhandled symbol %s", parser.string);
3886 if (parser.parsing != PARSING_CODE)
3887 error(".code must be specified before instructions");
3888 (*instr->function)();
3896 error("syntax error");
3902 execute(int argc, char *argv[])
3906 function_t function;
3907 patch_t *patch, *next;
3909 for (patch = patches; patch; patch = next) {
3911 label = patch->label;
3912 if (label->kind == label_kind_code_forward)
3913 error("undefined label %s", label->name);
3914 switch (patch->kind) {
3915 case patch_kind_jmp:
3916 case patch_kind_mov:
3917 case patch_kind_call:
3918 jit_patch_at(patch->value, label->value);
3927 if (flag_data == 0) {
3929 jit_set_data(NULL, 0, JIT_DISABLE_DATA | JIT_DISABLE_NOTE);
3932 function = jit_emit();
3933 if (flag_verbose > 1 || flag_disasm) {
3935 fprintf(stderr, " - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n");
3937 if (flag_verbose > 0 || flag_disasm) {
3939 fprintf(stderr, " - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n");
3941 if (flag_verbose && argc) {
3942 for (result = 0; result < argc; result++)
3943 printf("argv[%d] = %s\n", result, argv[result]);
3944 fprintf(stderr, " - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n");
3951 result = (*function)(argc, argv);
3952 jit_destroy_state();
3958 xmalloc(size_t size)
3960 void *pointer = malloc(size);
3962 if (pointer == NULL)
3963 error("out of memory");
3969 xrealloc(void *pointer, size_t size)
3971 pointer = realloc(pointer, size);
3973 if (pointer == NULL)
3974 error("out of memory");
3980 xcalloc(size_t nmemb, size_t size)
3982 void *pointer = calloc(nmemb, size);
3984 if (pointer == NULL)
3985 error("out of memory");
3991 new_label(label_kind_t kind, char *name, void *value)
3995 label = (label_t *)xmalloc(sizeof(label_t));
3997 label->name = strdup(name);
3998 label->value = value;
3999 put_hash(labels, (entry_t *)label);
4005 new_patch(patch_kind_t kind, label_t *label, void *value)
4007 patch_t *patch = (patch_t *)xmalloc(sizeof(patch_t));
4009 patch->label = label;
4010 patch->value = value;
4011 patch->next = patches;
4018 bcmp_symbols(const void *left, const void *right)
4020 return (strcmp((char *)left, (*(symbol_t **)right)->name));
4024 qcmp_symbols(const void *left, const void *right)
4026 return (strcmp((*(symbol_t **)left)->name, (*(symbol_t **)right)->name));
4030 new_symbol(char *name)
4034 if ((symbol_offset & 15) == 0) {
4035 if ((symbol_length += 16) == 16)
4036 symbols = (symbol_t **)xmalloc(sizeof(symbol_t *) *
4039 symbols = (symbol_t **)xrealloc(symbols, sizeof(symbol_t *) *
4042 symbol = (symbol_t *)xmalloc(sizeof(symbol_t));
4043 symbol->name = strdup(name);
4044 symbols[symbol_offset++] = symbol;
4045 qsort(symbols, symbol_offset, sizeof(symbol_t *), qcmp_symbols);
4051 get_symbol_by_name(char *name)
4053 symbol_t **symbol_pointer;
4055 if (symbols == NULL)
4057 symbol_pointer = (symbol_t **)bsearch(name, symbols, symbol_offset,
4058 sizeof(symbol_t *), bcmp_symbols);
4060 return (symbol_pointer ? *symbol_pointer : NULL);
4068 hash = (hash_t *)xmalloc(sizeof(hash_t));
4070 hash->entries = (entry_t **)xcalloc(hash->size = 32, sizeof(void *));
4076 hash_string(char *name)
4081 for (key = 0, ptr = name; *ptr; ptr++)
4082 key = (key << (key & 1)) ^ *ptr;
4088 put_hash(hash_t *hash, entry_t *entry)
4090 entry_t *prev, *ptr;
4091 int key = hash_string(entry->name) & (hash->size - 1);
4093 for (prev = ptr = hash->entries[key]; ptr; prev = ptr, ptr = ptr->next) {
4094 if (strcmp(entry->name, ptr->name) == 0)
4095 error("duplicated entry %s", entry->name);
4098 hash->entries[key] = entry;
4103 if (hash->count > hash->size * 0.75)
4108 get_hash(hash_t *hash, char *name)
4111 int key = hash_string(name) & (hash->size - 1);
4113 for (entry = hash->entries[key]; entry; entry = entry->next) {
4114 if (strcmp(entry->name, name) == 0)
4121 rehash(hash_t *hash)
4124 entry_t *entry, *next, **entries;
4126 entries = (entry_t **)xcalloc(size = hash->size * 2, sizeof(void *));
4127 for (i = 0; i < hash->size; i++) {
4128 for (entry = hash->entries[i]; entry; entry = next) {
4130 key = hash_string(entry->name) & (size - 1);
4131 entry->next = entries[key];
4132 entries[key] = entry;
4135 free(hash->entries);
4136 hash->entries = entries;
4143 #if HAVE_GETOPT_LONG_ONLY
4145 Usage: %s [jit assembler options] file [--] [jit program options]\n\
4146 Jit assembler options:\n\
4147 -help Display this information\n\
4148 -v[0-3] Verbose output level\n\
4149 -d Do not use a data buffer\n"
4150 # if defined(__i386__) && __WORDSIZE == 32
4151 " -mx87=1 Force using x87 when sse2 available\n"
4153 # if defined(__i386__) || defined(__x86_64__)
4154 " -msse4_1=0 Do not use sse4_1 instructions when available\n"
4156 # if defined(__arm__)
4157 " -mcpu=<val> Force cpu version (4, 5, 6 or 7)\n\
4158 -mthumb[=0|1] Enable or disable thumb\n\
4159 -mvfp=<val> Set vpf version (0 to disable)\n\
4160 -mneon[=0|1] Enable or disable neon\n"
4165 Usage: %s [jit assembler options] file [--] [jit program options]\n\
4166 Jit assembler options:\n\
4167 -h Display this information\n\
4168 -v Verbose output level\n", progname);
4175 main(int argc, char *argv[])
4177 #if HAVE_GETOPT_LONG_ONLY
4178 static const char *short_options = "dv::";
4179 static struct option long_options[] = {
4180 { "help", 0, 0, 'h' },
4181 { "data", 2, 0, 'd' },
4182 # if defined(__i386__) && __WORDSIZE == 32
4183 { "mx87", 2, 0, '7' },
4185 # if defined(__i386__) || defined(__x86_64__)
4186 { "msse4_1", 2, 0, '4' },
4188 # if defined(__arm__)
4189 { "mcpu", 2, 0, 'c' },
4190 { "mthumb", 2, 0, 't' },
4191 { "mvfp", 2, 0, 'f' },
4192 { "mneon", 2, 0, 'n' },
4197 #endif /* HAVE_GETOPT_LONG_ONLY */
4204 #if defined(__CYGWIN__)
4205 /* Cause a compile warning about redefinition without dllimport
4206 * attribute, *but* cause correct linkage if liblightning.a is
4207 * linked to binutils (that happens to have an internal
4208 * getopt* implementation and an apparently conflicting
4209 * optind global variable) */
4219 DL_HANDLE = dlopen(NULL, RTLD_LAZY);
4223 #if HAVE_GETOPT_LONG_ONLY
4225 if ((opt_short = getopt_long_only(argc, argv, short_options,
4226 long_options, &opt_index)) < 0)
4228 switch (opt_short) {
4235 flag_verbose = strtol(optarg, &endptr, 10);
4236 if (*endptr || flag_verbose < 0)
4245 #if defined(__i386__) && __WORDSIZE == 32
4248 if (strcmp(optarg, "") == 0 || strcmp(optarg, "1") == 0)
4250 else if (strcmp(optarg, "0"))
4257 #if defined(__i386__) || defined(__x86_64__)
4260 if (strcmp(optarg, "0") == 0)
4262 else if (strcmp(optarg, "1"))
4267 #if defined(__arm__)
4270 offset = strtol(optarg, &endptr, 10);
4271 if (*endptr || offset < 0)
4273 if (offset < jit_cpu.version)
4274 jit_cpu.version = offset;
4279 if (strcmp(optarg, "0") == 0)
4281 else if (strcmp(optarg, "1") && strcmp(optarg, "2"))
4286 # if !defined(__ARM_PCS_VFP)
4287 /* Do not allow overrinding hard float abi */
4289 offset = strtol(optarg, &endptr, 10);
4290 if (*endptr || offset < 0)
4292 if (offset < jit_cpu.vfp)
4293 jit_cpu.vfp = offset;
4299 if (strcmp(optarg, "0") == 0)
4301 else if (strcmp(optarg, "1"))
4309 while ((opt_short = getopt(argc, argv, "hvd")) >= 0) {
4310 if (opt_short == 'v')
4312 else if (opt_short == 'd')
4322 if (opt_index < argc && argv[opt_index][0] == '-')
4325 if (opt_index < 0 || opt_index >= argc)
4327 if (strcmp(argv[opt_index], "-") == 0)
4328 strcpy(parser.name, "<stdin>");
4330 if ((endptr = strrchr(argv[opt_index], '/')) == NULL)
4331 endptr = argv[opt_index];
4334 strncpy(parser.name, endptr, sizeof(parser.name));
4335 parser.name[sizeof(parser.name) - 1] = '\0';
4342 opt_short = snprintf(cmdline, sizeof(cmdline), cc " -E -x c %s", argv[opt_index]);
4343 opt_short += snprintf(cmdline + opt_short,
4344 sizeof(cmdline) - opt_short,
4345 " -D__WORDSIZE=%d", __WORDSIZE);
4346 opt_short += snprintf(cmdline + opt_short,
4347 sizeof(cmdline) - opt_short,
4348 " -D__LITTLE_ENDIAN=%d", __LITTLE_ENDIAN);
4349 opt_short += snprintf(cmdline + opt_short,
4350 sizeof(cmdline) - opt_short,
4351 " -D__BIG_ENDIAN=%d", __BIG_ENDIAN);
4352 opt_short += snprintf(cmdline + opt_short,
4353 sizeof(cmdline) - opt_short,
4354 " -D__BYTE_ORDER=%d", __BYTE_ORDER);
4355 #if defined(__i386__)
4356 opt_short += snprintf(cmdline + opt_short,
4357 sizeof(cmdline) - opt_short,
4360 #if defined(__x86_64__)
4361 opt_short += snprintf(cmdline + opt_short,
4362 sizeof(cmdline) - opt_short,
4365 #if defined(__mips__)
4366 opt_short += snprintf(cmdline + opt_short,
4367 sizeof(cmdline) - opt_short,
4369 opt_short += snprintf(cmdline + opt_short,
4370 sizeof(cmdline) - opt_short,
4371 " -D__mips_isa_rev=%d", jit_cpu.release);
4373 #if defined(__arm__)
4374 opt_short += snprintf(cmdline + opt_short,
4375 sizeof(cmdline) - opt_short,
4378 #if defined(__powerpc__)
4379 opt_short += snprintf(cmdline + opt_short,
4380 sizeof(cmdline) - opt_short,
4383 #if defined(__sparc__)
4384 opt_short += snprintf(cmdline + opt_short,
4385 sizeof(cmdline) - opt_short,
4388 #if defined(__ia64__)
4389 opt_short += snprintf(cmdline + opt_short,
4390 sizeof(cmdline) - opt_short,
4393 #if defined(__hppa__)
4394 opt_short += snprintf(cmdline + opt_short,
4395 sizeof(cmdline) - opt_short,
4399 opt_short += snprintf(cmdline + opt_short,
4400 sizeof(cmdline) - opt_short,
4403 #if defined(__sgi__)
4404 opt_short += snprintf(cmdline + opt_short,
4405 sizeof(cmdline) - opt_short,
4408 #if defined(__aarch64__)
4409 opt_short += snprintf(cmdline + opt_short,
4410 sizeof(cmdline) - opt_short,
4411 " -D__aarch64__=1");
4413 #if defined(__s390__) || defined(__s390x__)
4414 opt_short += snprintf(cmdline + opt_short,
4415 sizeof(cmdline) - opt_short,
4418 #if defined(__alpha__)
4419 opt_short += snprintf(cmdline + opt_short,
4420 sizeof(cmdline) - opt_short,
4423 #if defined(__loongarch__)
4424 opt_short += snprintf(cmdline + opt_short,
4425 sizeof(cmdline) - opt_short,
4426 " -D__loongarch__=1");
4428 if ((parser.fp = popen(cmdline, "r")) == NULL)
4429 error("cannot execute %s", cmdline);
4432 parser.string = (char *)xmalloc(parser.length = 4096);
4434 #if defined(__linux__) && (defined(__i386__) || defined(__x86_64__))
4435 /* double precision 0x200
4436 * round nearest 0x000
4437 * invalid operation mask 0x001
4438 * denormalized operand mask 0x002
4439 * zero divide mask 0x004
4440 * precision (inexact) mask 0x020
4443 fpu_control_t fpu_control = 0x027f;
4444 _FPU_SETCW(fpu_control);
4448 _jit = jit_new_state();
4450 instrs = new_hash();
4452 offset < (int)(sizeof(instr_vector) / sizeof(instr_vector[0]));
4454 put_hash(instrs, (entry_t *)(instr_vector + offset));
4456 labels = new_hash();
4462 for (opt_short = 0; opt_index < argc; opt_short++, opt_index++)
4463 argv[opt_short] = argv[opt_index];
4464 argv[opt_short] = NULL;
4466 execute(argc, argv);