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 hmulr(void); static void hmuli(void);
310 static void hmulr_u(void); static void hmuli_u(void);
311 static void qmulr(void); static void qmuli(void);
312 static void qmulr_u(void); static void qmuli_u(void);
313 static void divr(void); static void divi(void);
314 static void divr_u(void); static void divi_u(void);
315 static void qdivr(void); static void qdivi(void);
316 static void qdivr_u(void); static void qdivi_u(void);
317 static void remr(void); static void remi(void);
318 static void remr_u(void); static void remi_u(void);
319 static void andr(void); static void andi(void);
320 static void orr(void); static void ori(void);
321 static void xorr(void); static void xori(void);
322 static void lshr(void); static void lshi(void);
323 static void qlshr(void); static void qlshi(void);
324 static void qlshr_u(void); static void qlshi_u(void);
325 static void rshr(void); static void rshi(void);
326 static void qrshr(void); static void qrshi(void);
327 static void rshr_u(void); static void rshi_u(void);
328 static void qrshr_u(void); static void qrshi_u(void);
329 static void lrotr(void); static void lroti(void);
330 static void rrotr(void); static void rroti(void);
331 static void negr(void); static void negi(void);
332 static void comr(void); static void comi(void);
333 static void clor(void); static void clzr(void);
334 static void cloi(void); static void clzi(void);
335 static void ctor(void); static void ctzr(void);
336 static void ctoi(void); static void ctzi(void);
337 static void rbitr(void); static void rbiti(void);
338 static void popcntr(void); static void popcnti(void);
339 static void ltr(void); static void lti(void);
340 static void ltr_u(void); static void lti_u(void);
341 static void ler(void); static void lei(void);
342 static void ler_u(void); static void lei_u(void);
343 static void eqr(void); static void eqi(void);
344 static void ger(void); static void gei(void);
345 static void ger_u(void); static void gei_u(void);
346 static void gtr(void); static void gti(void);
347 static void gtr_u(void); static void gti_u(void);
348 static void ner(void); static void nei(void);
349 static void casr(void); static void casi(void);
350 static void movr(void); static void movi(void);
351 static void extr(void); static void exti(void);
352 static void extr_u(void); static void exti_u(void);
353 static void depr(void); static void depi(void);
354 static void extr_c(void); static void exti_c(void);
355 static void extr_uc(void); static void exti_uc(void);
356 static void extr_s(void); static void exti_s(void);
357 static void extr_us(void); static void exti_us(void);
359 static void extr_i(void); static void exti_i(void);
360 static void extr_ui(void); static void exti_ui(void);
362 static void htonr_us(void); static void htoni_us(void);
363 static void ntohr_us(void); static void ntohi_us(void);
364 static void htonr_ui(void); static void htoni_ui(void);
365 static void ntohr_ui(void); static void ntohi_ui(void);
367 static void htonr_ul(void); static void htoni_ul(void);
368 static void ntohr_ul(void); static void ntohi_ul(void);
370 static void htonr(void); static void htoni(void);
371 static void ntohr(void); static void ntohi(void);
372 static void bswapr_us(void); static void bswapi_us(void);
373 static void bswapr_ui(void); static void bswapi_ui(void);
375 static void bswapr_ul(void); static void bswapi_ul(void);
377 static void bswapr(void); static void bswapi(void);
378 static void movnr(void); static void movzr(void);
379 static void ldr_c(void); static void ldi_c(void);
380 static void ldr_uc(void); static void ldi_uc(void);
381 static void ldr_s(void); static void ldi_s(void);
382 static void ldr_us(void); static void ldi_us(void);
383 static void ldr_i(void); static void ldi_i(void);
385 static void ldr_ui(void); static void ldi_ui(void);
386 static void ldr_l(void); static void ldi_l(void);
388 static void ldr(void); static void ldi(void);
389 static void ldxr_c(void); static void ldxi_c(void);
390 static void ldxr_uc(void); static void ldxi_uc(void);
391 static void ldxr_s(void); static void ldxi_s(void);
392 static void ldxr_us(void); static void ldxi_us(void);
393 static void ldxr_i(void); static void ldxi_i(void);
395 static void ldxr_ui(void); static void ldxi_ui(void);
396 static void ldxr_l(void); static void ldxi_l(void);
398 static void ldxr(void); static void ldxi(void);
399 static void unldr(void); static void unldi(void);
400 static void unldr_u(void); static void unldi_u(void);
401 static void str_c(void); static void sti_c(void);
402 static void str_s(void); static void sti_s(void);
403 static void str_i(void); static void sti_i(void);
405 static void str_l(void); static void sti_l(void);
407 static void str(void); static void sti(void);
408 static void stxr_c(void); static void stxi_c(void);
409 static void stxr_s(void); static void stxi_s(void);
410 static void stxr_i(void); static void stxi_i(void);
412 static void stxr_l(void); static void stxi_l(void);
414 static void stxr(void); static void stxi(void);
415 static void unstr(void); static void unsti(void);
416 static void bltr(void); static void blti(void);
417 static void bltr_u(void); static void blti_u(void);
418 static void bler(void); static void blei(void);
419 static void bler_u(void); static void blei_u(void);
420 static void beqr(void); static void beqi(void);
421 static void bger(void); static void bgei(void);
422 static void bger_u(void); static void bgei_u(void);
423 static void bgtr(void); static void bgti(void);
424 static void bgtr_u(void); static void bgti_u(void);
425 static void bner(void); static void bnei(void);
426 static void bmsr(void); static void bmsi(void);
427 static void bmcr(void); static void bmci(void);
428 static void boaddr(void); static void boaddi(void);
429 static void boaddr_u(void); static void boaddi_u(void);
430 static void bxaddr(void); static void bxaddi(void);
431 static void bxaddr_u(void); static void bxaddi_u(void);
432 static void bosubr(void); static void bosubi(void);
433 static void bosubr_u(void); static void bosubi_u(void);
434 static void bxsubr(void); static void bxsubi(void);
435 static void bxsubr_u(void); static void bxsubi_u(void);
436 static void jmpr(void); static void jmpi(void);
437 static void callr(void); static void calli(void);
438 static void prepare(void);
439 static void pushargr_c(void); static void pushargi_c(void);
440 static void pushargr_uc(void); static void pushargi_uc(void);
441 static void pushargr_s(void); static void pushargi_s(void);
442 static void pushargr_us(void); static void pushargi_us(void);
443 static void pushargr_i(void); static void pushargi_i(void);
445 static void pushargr_ui(void); static void pushargi_ui(void);
446 static void pushargr_l(void); static void pushargi_l(void);
448 static void pushargr(void); static void pushargi(void);
449 static void finishr(void); static void finishi(void);
450 static void ret(void);
451 static void retr_c(void); static void reti_c(void);
452 static void retr_uc(void); static void reti_uc(void);
453 static void retr_s(void); static void reti_s(void);
454 static void retr_us(void); static void reti_us(void);
455 static void retr_i(void); static void reti_i(void);
457 static void retr_ui(void); static void reti_ui(void);
458 static void retr_l(void); static void reti_l(void);
460 static void retr(void); static void reti(void);
461 static void retval_c(void); static void retval_uc(void);
462 static void retval_s(void); static void retval_us(void);
463 static void retval_i(void);
465 static void retval_ui(void); static void retval_l(void);
467 static void retval(void);
468 static void epilog(void);
469 static void arg_f(void); static void getarg_f(void);
470 static void putargr_f(void); static void putargi_f(void);
471 static void addr_f(void); static void addi_f(void);
472 static void subr_f(void); static void subi_f(void);
473 static void rsbr_f(void); static void rsbi_f(void);
474 static void mulr_f(void); static void muli_f(void);
475 static void divr_f(void); static void divi_f(void);
476 static void negr_f(void); static void negi_f(void);
477 static void absr_f(void); static void absi_f(void);
478 static void sqrtr_f(void); static void sqrti_f(void);
479 static void fmar_f(void); static void fmai_f(void);
480 static void fmsr_f(void); static void fmsi_f(void);
481 static void fnmar_f(void); static void fnmai_f(void);
482 static void fnmsr_f(void); static void fnmsi_f(void);
483 static void ltr_f(void); static void lti_f(void);
484 static void ler_f(void); static void lei_f(void);
485 static void eqr_f(void); static void eqi_f(void);
486 static void ger_f(void); static void gei_f(void);
487 static void gtr_f(void); static void gti_f(void);
488 static void ner_f(void); static void nei_f(void);
489 static void unltr_f(void); static void unlti_f(void);
490 static void unler_f(void); static void unlei_f(void);
491 static void uneqr_f(void); static void uneqi_f(void);
492 static void unger_f(void); static void ungei_f(void);
493 static void ungtr_f(void); static void ungti_f(void);
494 static void ltgtr_f(void); static void ltgti_f(void);
495 static void ordr_f(void); static void ordi_f(void);
496 static void unordr_f(void); static void unordi_f(void);
497 static void truncr_f_i(void);
499 static void truncr_f_l(void);
501 static void truncr_f(void);
502 static void extr_f(void); static void extr_d_f(void);
503 static void movr_f(void); static void movi_f(void);
504 static void movr_w_f(void); static void movr_f_w(void);
505 static void movi_f_w(void); static void movi_w_f(void);
506 static void ldr_f(void); static void ldi_f(void);
507 static void ldxr_f(void); static void ldxi_f(void);
508 static void unldr_x(void); static void unldi_x(void);
509 static void str_f(void); static void sti_f(void);
510 static void stxr_f(void); static void stxi_f(void);
511 static void unstr_x(void); static void unsti_x(void);
512 static void bltr_f(void); static void blti_f(void);
513 static void bler_f(void); static void blei_f(void);
514 static void beqr_f(void); static void beqi_f(void);
515 static void bger_f(void); static void bgei_f(void);
516 static void bgtr_f(void); static void bgti_f(void);
517 static void bner_f(void); static void bnei_f(void);
518 static void bunltr_f(void); static void bunlti_f(void);
519 static void bunler_f(void); static void bunlei_f(void);
520 static void buneqr_f(void); static void buneqi_f(void);
521 static void bunger_f(void); static void bungei_f(void);
522 static void bungtr_f(void); static void bungti_f(void);
523 static void bltgtr_f(void); static void bltgti_f(void);
524 static void bordr_f(void); static void bordi_f(void);
525 static void bunordr_f(void); static void bunordi_f(void);
526 static void pushargr_f(void); static void pushargi_f(void);
527 static void retr_f(void); static void reti_f(void);
528 static void retval_f(void);
529 static void arg_d(void); static void getarg_d(void);
530 static void putargr_d(void); static void putargi_d(void);
531 static void addr_d(void); static void addi_d(void);
532 static void subr_d(void); static void subi_d(void);
533 static void rsbr_d(void); static void rsbi_d(void);
534 static void mulr_d(void); static void muli_d(void);
535 static void divr_d(void); static void divi_d(void);
536 static void negr_d(void); static void negi_d(void);
537 static void absr_d(void); static void absi_d(void);
538 static void sqrtr_d(void); static void sqrti_d(void);
539 static void fmar_d(void); static void fmai_d(void);
540 static void fmsr_d(void); static void fmsi_d(void);
541 static void fnmar_d(void); static void fnmai_d(void);
542 static void fnmsr_d(void); static void fnmsi_d(void);
543 static void ltr_d(void); static void lti_d(void);
544 static void ler_d(void); static void lei_d(void);
545 static void eqr_d(void); static void eqi_d(void);
546 static void ger_d(void); static void gei_d(void);
547 static void gtr_d(void); static void gti_d(void);
548 static void ner_d(void); static void nei_d(void);
549 static void unltr_d(void); static void unlti_d(void);
550 static void unler_d(void); static void unlei_d(void);
551 static void uneqr_d(void); static void uneqi_d(void);
552 static void unger_d(void); static void ungei_d(void);
553 static void ungtr_d(void); static void ungti_d(void);
554 static void ltgtr_d(void); static void ltgti_d(void);
555 static void ordr_d(void); static void ordi_d(void);
556 static void unordr_d(void); static void unordi_d(void);
557 static void truncr_d_i(void);
559 static void truncr_d_l(void);
561 static void truncr_d(void);
562 static void extr_d(void); static void extr_f_d(void);
563 static void movr_d(void); static void movi_d(void);
565 static void movr_ww_d(void); static void movr_d_ww(void);
566 static void movi_d_ww(void); static void movi_ww_d(void);
568 static void movr_w_d(void); static void movr_d_w(void);
569 static void movi_d_w(void); static void movi_w_d(void);
571 static void ldr_d(void); static void ldi_d(void);
572 static void ldxr_d(void); static void ldxi_d(void);
573 static void str_d(void); static void sti_d(void);
574 static void stxr_d(void); static void stxi_d(void);
575 static void bltr_d(void); static void blti_d(void);
576 static void bler_d(void); static void blei_d(void);
577 static void beqr_d(void); static void beqi_d(void);
578 static void bger_d(void); static void bgei_d(void);
579 static void bgtr_d(void); static void bgti_d(void);
580 static void bner_d(void); static void bnei_d(void);
581 static void bunltr_d(void); static void bunlti_d(void);
582 static void bunler_d(void); static void bunlei_d(void);
583 static void buneqr_d(void); static void buneqi_d(void);
584 static void bunger_d(void); static void bungei_d(void);
585 static void bungtr_d(void); static void bungti_d(void);
586 static void bltgtr_d(void); static void bltgti_d(void);
587 static void bordr_d(void); static void bordi_d(void);
588 static void bunordr_d(void); static void bunordi_d(void);
589 static void pushargr_d(void); static void pushargi_d(void);
590 static void retr_d(void); static void reti_d(void);
591 static void retval_d(void);
592 static void vastart(void); static void vapush(void);
593 static void vaarg(void); static void vaarg_d(void);
594 static void vaend(void);
596 static void error(const char *format, ...) noreturn printf_format(1, 2);
597 static void warn(const char *format, ...) printf_format(1, 2) maybe_unused;
598 static void message(const char *kind, const char *format, va_list ap);
600 static int getch(void);
601 static int getch_noeof(void);
602 static int ungetch(int ch);
603 static int skipws(void);
604 static int skipnl(void);
605 static int skipct(void);
606 static int skipcp(void);
607 static jit_word_t get_int(skip_t skip);
608 static jit_uword_t get_uint(skip_t skip);
609 static double get_float(skip_t skip);
610 static float make_float(double d);
611 static void *get_pointer(skip_t skip);
612 static label_t *get_label(skip_t skip);
613 static token_t regname(void);
614 static token_t identifier(int ch);
615 static void get_data(type_t type);
616 static void dot(void);
617 static token_t number(int ch);
618 static int escape(int ch);
619 static token_t string(void);
620 static token_t dynamic(void);
621 static token_t character(void);
622 static void expression_prim(void);
623 static void expression_inc(int pre);
624 static void expression_dec(int pre);
625 static void expression_unary(void);
626 static void expression_mul(void);
627 static void expression_add(void);
628 static void expression_shift(void);
629 static void expression_bit(void);
630 static void expression_rel(void);
631 static void expression_cond(void);
632 static token_t expression(void);
633 static token_t primary(skip_t skip);
634 static void parse(void);
635 static int execute(int argc, char *argv[]);
637 static void *xmalloc(size_t size);
638 static void *xrealloc(void *pointer, size_t size);
639 static void *xcalloc(size_t nmemb, size_t size);
641 static label_t *new_label(label_kind_t kind, char *name, void *value);
642 static patch_t *new_patch(patch_kind_t kind, label_t *label, void *value);
643 static int bcmp_symbols(const void *left, const void *right);
644 static int qcmp_symbols(const void *left, const void *right);
645 static symbol_t *new_symbol(char *name);
646 static symbol_t *get_symbol_by_name(char *name);
648 static hash_t *new_hash(void);
649 static int hash_string(char *name);
650 static void put_hash(hash_t *hash, entry_t *entry);
651 static entry_t *get_hash(hash_t *hash, char *name);
652 static void rehash(hash_t *hash);
657 static jit_state_t *_jit;
658 static int flag_verbose;
659 static int flag_data;
660 static int flag_disasm;
661 static char *progname;
662 static parser_t parser;
663 static hash_t *labels;
664 static int label_offset;
665 static patch_t *patches;
666 static symbol_t **symbols;
667 static int symbol_length;
668 static int symbol_offset;
669 static hash_t *instrs;
671 static size_t data_offset, data_length;
672 static instr_t instr_vector[] = {
673 #define entry(value) { NULL, #value, value }
674 #define entry2(name, function) { NULL, name, function }
676 entry(align), entry(name),
679 entry(frame), entry(tramp),
681 entry(allocai), entry(allocar),
682 entry(arg_c), entry(arg_s),
688 entry(getarg_c), entry(getarg_uc),
689 entry(getarg_s), entry(getarg_us),
692 entry(getarg_ui), entry(getarg_l),
695 entry(putargr_c), entry(putargi_c),
696 entry(putargr_uc), entry(putargi_uc),
697 entry(putargr_s), entry(putargi_s),
698 entry(putargr_us), entry(putargi_us),
699 entry(putargr_i), entry(putargi_i),
701 entry(putargr_ui), entry(putargi_ui),
702 entry(putargr_l), entry(putargi_l),
704 entry(putargr), entry(putargi),
705 entry(addr), entry(addi),
706 entry(addxr), entry(addxi),
707 entry(addcr), entry(addci),
708 entry(subr), entry(subi),
709 entry(subxr), entry(subxi),
710 entry(subcr), entry(subci),
711 entry(rsbr), entry(rsbi),
712 entry(mulr), entry(muli),
713 entry(hmulr), entry(hmuli),
714 entry(hmulr_u), entry(hmuli_u),
715 entry(qmulr), entry(qmuli),
716 entry(qmulr_u), entry(qmuli_u),
717 entry(divr), entry(divi),
718 entry(divr_u), entry(divi_u),
719 entry(qdivr), entry(qdivi),
720 entry(qdivr_u), entry(qdivi_u),
721 entry(remr), entry(remi),
722 entry(remr_u), entry(remi_u),
723 entry(andr), entry(andi),
724 entry(orr), entry(ori),
725 entry(xorr), entry(xori),
726 entry(lshr), entry(lshi),
727 entry(qlshr), entry(qlshi),
728 entry(qlshr_u), entry(qlshi_u),
729 entry(rshr), entry(rshi),
730 entry(qrshr), entry(qrshi),
731 entry(rshr_u), entry(rshi_u),
732 entry(qrshr_u), entry(qrshi_u),
733 entry(lrotr), entry(lroti),
734 entry(rrotr), entry(rroti),
735 entry(negr), entry(negi),
736 entry(comr), entry(comi),
737 entry(clor), entry(cloi),
738 entry(clzr), entry(clzi),
739 entry(ctor), entry(ctoi),
740 entry(ctzr), entry(ctzi),
741 entry(rbitr), entry(rbiti),
742 entry(popcntr), entry(popcnti),
743 entry(ltr), entry(lti),
744 entry(ltr_u), entry(lti_u),
745 entry(ler), entry(lei),
746 entry(ler_u), entry(lei_u),
747 entry(eqr), entry(eqi),
748 entry(ger), entry(gei),
749 entry(ger_u), entry(gei_u),
750 entry(gtr), entry(gti),
751 entry(gtr_u), entry(gti_u),
752 entry(ner), entry(nei),
753 entry(casr), entry(casi),
754 entry(movr), entry(movi),
755 entry(extr), entry(exti),
756 entry(extr_u), entry(exti_u),
757 entry(depr), entry(depi),
758 entry(extr_c), entry(exti_c),
759 entry(extr_uc), entry(exti_uc),
760 entry(extr_s), entry(exti_s),
761 entry(extr_us), entry(exti_us),
763 entry(extr_i), entry(exti_i),
764 entry(extr_ui), entry(exti_ui),
766 entry(htonr_us), entry(htoni_us),
767 entry(ntohr_us), entry(ntohi_us),
768 entry(htonr_ui), entry(htoni_ui),
769 entry(ntohr_ui), entry(ntohi_ui),
771 entry(htonr_ul), entry(htoni_ul),
772 entry(ntohr_ul), entry(ntohi_ul),
774 entry(htonr), entry(htoni),
775 entry(ntohr), entry(ntohi),
776 entry(bswapr_us), entry(bswapi_us),
777 entry(bswapr_ui), entry(bswapi_ui),
779 entry(bswapr_ul), entry(bswapi_ul),
781 entry(bswapr), entry(bswapi),
782 entry(movnr), entry(movzr),
783 entry(ldr_c), entry(ldi_c),
784 entry(ldr_uc), entry(ldi_uc),
785 entry(ldr_s), entry(ldi_s),
786 entry(ldr_us), entry(ldi_us),
787 entry(ldr_i), entry(ldi_i),
789 entry(ldr_ui), entry(ldi_ui),
790 entry(ldr_l), entry(ldi_l),
792 entry(ldr), entry(ldi),
793 entry(ldxr_c), entry(ldxi_c),
794 entry(ldxr_uc), entry(ldxi_uc),
795 entry(ldxr_s), entry(ldxi_s),
796 entry(ldxr_us), entry(ldxi_us),
797 entry(ldxr_i), entry(ldxi_i),
799 entry(ldxr_ui), entry(ldxi_ui),
800 entry(ldxr_l), entry(ldxi_l),
802 entry(ldxr), entry(ldxi),
803 entry(unldr), entry(unldi),
804 entry(unldr_u), entry(unldi_u),
805 entry(str_c), entry(sti_c),
806 entry(str_s), entry(sti_s),
807 entry(str_i), entry(sti_i),
809 entry(str_l), entry(sti_l),
811 entry(str), entry(sti),
812 entry(stxr_c), entry(stxi_c),
813 entry(stxr_s), entry(stxi_s),
814 entry(stxr_i), entry(stxi_i),
816 entry(stxr_l), entry(stxi_l),
818 entry(stxr), entry(stxi),
819 entry(unstr), entry(unsti),
820 entry(bltr), entry(blti),
821 entry(bltr_u), entry(blti_u),
822 entry(bler), entry(blei),
823 entry(bler_u), entry(blei_u),
824 entry(beqr), entry(beqi),
825 entry(bger), entry(bgei),
826 entry(bger_u), entry(bgei_u),
827 entry(bgtr), entry(bgti),
828 entry(bgtr_u), entry(bgti_u),
829 entry(bner), entry(bnei),
830 entry(bmsr), entry(bmsi),
831 entry(bmcr), entry(bmci),
832 entry(boaddr), entry(boaddi),
833 entry(boaddr_u), entry(boaddi_u),
834 entry(bxaddr), entry(bxaddi),
835 entry(bxaddr_u), entry(bxaddi_u),
836 entry(bosubr), entry(bosubi),
837 entry(bosubr_u), entry(bosubi_u),
838 entry(bxsubr), entry(bxsubi),
839 entry(bxsubr_u), entry(bxsubi_u),
840 entry(jmpr), entry(jmpi),
841 entry(callr), entry(calli),
843 entry(pushargr_c), entry(pushargi_c),
844 entry(pushargr_uc), entry(pushargi_uc),
845 entry(pushargr_s), entry(pushargi_s),
846 entry(pushargr_us), entry(pushargi_us),
847 entry(pushargr_i), entry(pushargi_i),
849 entry(pushargr_ui), entry(pushargi_ui),
850 entry(pushargr_l), entry(pushargi_l),
852 entry(pushargr), entry(pushargi),
853 entry(finishr), entry(finishi),
855 entry(retr_c), entry(reti_c),
856 entry(retr_uc), entry(reti_uc),
857 entry(retr_s), entry(reti_s),
858 entry(retr_us), entry(reti_us),
859 entry(retr_i), entry(reti_i),
861 entry(retr_ui), entry(reti_ui),
862 entry(retr_l), entry(reti_l),
864 entry(retr), entry(reti),
865 entry(retval_c), entry(retval_uc),
866 entry(retval_s), entry(retval_us),
869 entry(retval_ui), entry(retval_l),
873 entry(arg_f), entry(getarg_f),
874 entry(putargr_f), entry(putargi_f),
875 entry(addr_f), entry(addi_f),
876 entry(subr_f), entry(subi_f),
877 entry(rsbr_f), entry(rsbi_f),
878 entry(mulr_f), entry(muli_f),
879 entry(divr_f), entry(divi_f),
880 entry(negr_f), entry(negi_f),
881 entry(absr_f), entry(absi_f),
882 entry(sqrtr_f), entry(sqrti_f),
883 entry(fmar_f), entry(fmai_f),
884 entry(fmsr_f), entry(fmsi_f),
885 entry(fnmar_f), entry(fnmai_f),
886 entry(fnmsr_f), entry(fnmsi_f),
887 entry(ltr_f), entry(lti_f),
888 entry(ler_f), entry(lei_f),
889 entry(eqr_f), entry(eqi_f),
890 entry(ger_f), entry(gei_f),
891 entry(gtr_f), entry(gti_f),
892 entry(ner_f), entry(nei_f),
893 entry(unltr_f), entry(unlti_f),
894 entry(unler_f), entry(unlei_f),
895 entry(uneqr_f), entry(uneqi_f),
896 entry(unger_f), entry(ungei_f),
897 entry(ungtr_f), entry(ungti_f),
898 entry(ltgtr_f), entry(ltgti_f),
899 entry(ordr_f), entry(ordi_f),
900 entry(unordr_f), entry(unordi_f),
906 entry(extr_f), entry(extr_d_f),
907 entry(movr_f), entry(movi_f),
908 entry(movr_w_f), entry(movr_f_w),
909 entry(movi_f_w), entry(movi_w_f),
910 entry(ldr_f), entry(ldi_f),
911 entry(ldxr_f), entry(ldxi_f),
912 entry(unldr_x), entry(unldi_x),
913 entry(str_f), entry(sti_f),
914 entry(stxr_f), entry(stxi_f),
915 entry(unstr_x), entry(unsti_x),
916 entry(bltr_f), entry(blti_f),
917 entry(bler_f), entry(blei_f),
918 entry(beqr_f), entry(beqi_f),
919 entry(bger_f), entry(bgei_f),
920 entry(bgtr_f), entry(bgti_f),
921 entry(bner_f), entry(bnei_f),
922 entry(bunltr_f), entry(bunlti_f),
923 entry(bunler_f), entry(bunlei_f),
924 entry(buneqr_f), entry(buneqi_f),
925 entry(bunger_f), entry(bungei_f),
926 entry(bungtr_f), entry(bungti_f),
927 entry(bltgtr_f), entry(bltgti_f),
928 entry(bordr_f), entry(bordi_f),
929 entry(bunordr_f), entry(bunordi_f),
930 entry(pushargr_f), entry(pushargi_f),
931 entry(retr_f), entry(reti_f),
933 entry(arg_d), entry(getarg_d),
934 entry(putargr_d), entry(putargi_d),
935 entry(addr_d), entry(addi_d),
936 entry(subr_d), entry(subi_d),
937 entry(rsbr_d), entry(rsbi_d),
938 entry(mulr_d), entry(muli_d),
939 entry(divr_d), entry(divi_d),
940 entry(negr_d), entry(negi_d),
941 entry(absr_d), entry(absi_d),
942 entry(sqrtr_d), entry(sqrti_d),
943 entry(fmar_d), entry(fmai_d),
944 entry(fmsr_d), entry(fmsi_d),
945 entry(fnmar_d), entry(fnmai_d),
946 entry(fnmsr_d), entry(fnmsi_d),
947 entry(ltr_d), entry(lti_d),
948 entry(ler_d), entry(lei_d),
949 entry(eqr_d), entry(eqi_d),
950 entry(ger_d), entry(gei_d),
951 entry(gtr_d), entry(gti_d),
952 entry(ner_d), entry(nei_d),
953 entry(unltr_d), entry(unlti_d),
954 entry(unler_d), entry(unlei_d),
955 entry(uneqr_d), entry(uneqi_d),
956 entry(unger_d), entry(ungei_d),
957 entry(ungtr_d), entry(ungti_d),
958 entry(ltgtr_d), entry(ltgti_d),
959 entry(ordr_d), entry(ordi_d),
960 entry(unordr_d), entry(unordi_d),
966 entry(extr_d), entry(extr_f_d),
967 entry(movr_d), entry(movi_d),
969 entry(movr_ww_d), entry(movr_d_ww),
970 entry(movi_d_ww), entry(movi_ww_d),
972 entry(movr_w_d), entry(movr_d_w),
973 entry(movi_d_w), entry(movi_w_d),
975 entry(ldr_d), entry(ldi_d),
976 entry(ldxr_d), entry(ldxi_d),
977 entry(str_d), entry(sti_d),
978 entry(stxr_d), entry(stxi_d),
979 entry(bltr_d), entry(blti_d),
980 entry(bler_d), entry(blei_d),
981 entry(beqr_d), entry(beqi_d),
982 entry(bger_d), entry(bgei_d),
983 entry(bgtr_d), entry(bgti_d),
984 entry(bner_d), entry(bnei_d),
985 entry(bunltr_d), entry(bunlti_d),
986 entry(bunler_d), entry(bunlei_d),
987 entry(buneqr_d), entry(buneqi_d),
988 entry(bunger_d), entry(bungei_d),
989 entry(bungtr_d), entry(bungti_d),
990 entry(bltgtr_d), entry(bltgti_d),
991 entry(bordr_d), entry(bordi_d),
992 entry(bunordr_d), entry(bunordi_d),
993 entry(pushargr_d), entry(pushargi_d),
994 entry(retr_d), entry(reti_d),
996 entry2("va_start", vastart),
997 entry2("va_push", vapush),
998 entry2("va_arg", vaarg),
999 entry2("va_arg_d", vaarg_d),
1000 entry2("va_end", vaend),
1010 if (primary(skip_ws) != tok_register)
1011 error("bad register");
1012 if (parser.regtype != type_l)
1013 error("bad int register");
1015 return ((jit_gpr_t)parser.regval);
1021 if (primary(skip_ws) != tok_register)
1022 error("bad register");
1023 if (parser.regtype != type_d)
1024 error("bad float register");
1026 return ((jit_fpr_t)parser.regval);
1036 error("expecting variable");
1037 (void)identifier('$');
1038 if (parser.string[1] == '\0')
1039 error("expecting variable");
1040 if ((symbol = get_symbol_by_name(parser.string)) == NULL)
1041 symbol = new_symbol(parser.string);
1047 jmp_forward(void *value, label_t *label)
1049 (void)new_patch(patch_kind_jmp, label, value);
1053 mov_forward(void *value, label_t *label)
1055 (void)new_patch(patch_kind_mov, label, value);
1059 call_forward(void *value, label_t *label)
1061 (void)new_patch(patch_kind_call, label, value);
1065 make_arg(void *value)
1067 symbol_t *symbol = get_symbol();
1069 symbol->type = type_p;
1070 symbol->value.p = value;
1073 static jit_pointer_t
1076 symbol_t *symbol = get_symbol();
1078 if (symbol->type != type_p)
1079 error("bad argument %s type", symbol->name);
1081 return symbol->value.p;
1092 case '+': case '-': case '0' ... '9':
1094 value = get_int(skip_none);
1098 value = parser.value.i;
1101 switch (expression()) {
1104 value = parser.value.i;
1107 error("expecting immediate");
1112 value = (jit_word_t)parser.value.p;
1116 label = get_label(skip_none);
1117 if (label->kind == label_kind_data)
1118 value = (jit_word_t)label->value;
1120 error("expecting immediate");
1126 #define entry(name) \
1132 #define entry_ca(name) \
1136 make_arg(jit_##name()); \
1138 #define entry_ia(name) \
1142 jit_gpr_t r0 = get_ireg(); \
1143 jit_pointer_t ac = get_arg(); \
1144 jit_##name(r0, ac); \
1146 #define entry_im(name) \
1150 jit_word_t im = get_imm(); \
1153 #define entry_ir(name) \
1157 jit_gpr_t r0 = get_ireg(); \
1160 #define entry_ima(name) \
1164 jit_word_t im = get_imm(); \
1165 jit_pointer_t ac = get_arg(); \
1166 jit_##name(im, ac); \
1168 #define entry_ir_ir_ir(name) \
1172 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(), r2 = get_ireg(); \
1173 jit_##name(r0, r1, r2); \
1175 #define entry_ir_ir_im(name) \
1179 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \
1180 jit_word_t im = get_imm(); \
1181 jit_##name(r0, r1, im); \
1183 #define entry_ir_im_im(name) \
1187 jit_gpr_t r0 = get_ireg(); \
1188 jit_word_t i0 = get_imm(), i1 = get_imm(); \
1189 jit_##name(r0, i0, i1); \
1191 #define entry_ir_fr_im(name) \
1195 jit_gpr_t r0 = get_ireg(); \
1196 jit_fpr_t r1 = get_freg(); \
1197 jit_word_t im = get_imm(); \
1198 jit_##name(r0, r1, im); \
1200 #define entry_im_fr_im(name) \
1204 jit_word_t i0 = get_imm(); \
1205 jit_fpr_t r0 = get_freg(); \
1206 jit_word_t i1 = get_imm(); \
1207 jit_##name(i0, r0, i1); \
1209 #define entry_im_ir_im(name) \
1213 jit_word_t i0 = get_imm(); \
1214 jit_gpr_t r0 = get_ireg(); \
1215 jit_word_t i1 = get_imm(); \
1216 jit_##name(i0, r0, i1); \
1218 #define entry_ir_ir_ir_ir(name) \
1222 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(), \
1223 r2 = get_ireg(), r3 = get_ireg(); \
1224 jit_##name(r0, r1, r2, r3); \
1226 #define entry_ir_ir_ir_im(name) \
1230 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(), r2 = get_ireg(); \
1231 jit_word_t im = get_imm(); \
1232 jit_##name(r0, r1, r2, im); \
1234 #define entry_ir_im_ir_ir(name) \
1238 jit_gpr_t r0 = get_ireg(); \
1239 jit_word_t im = get_imm(); \
1240 jit_gpr_t r1 = get_ireg(), r2 = get_ireg(); \
1241 jit_##name(r0, im, r1, r2); \
1243 #define entry_ir_ir_im_im(name) \
1246 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \
1247 jit_word_t i0 = get_imm(), i1 = get_imm(); \
1248 jit_##name(r0, r1, i0, i1); \
1250 #define entry_ir_im_im_im(name) \
1253 jit_gpr_t r0 = get_ireg(); \
1254 jit_word_t i0 = get_imm(), i1 = get_imm(), i2 = get_imm(); \
1255 jit_##name(r0, i0, i1, i2); \
1257 #define entry_ir_ir(name) \
1261 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \
1262 jit_##name(r0, r1); \
1264 #define entry_ir_im(name) \
1268 jit_gpr_t r0 = get_ireg(); \
1269 jit_word_t im = get_imm(); \
1270 jit_##name(r0, im); \
1272 #define entry_ir_pm(name) \
1276 jit_gpr_t r0 = get_ireg(); \
1277 void *pm = get_pointer(skip_ws); \
1278 jit_##name(r0, pm); \
1280 #define entry_pm_ir(name) \
1284 void *pm = get_pointer(skip_ws); \
1285 jit_gpr_t r0 = get_ireg(); \
1286 jit_##name(pm, r0); \
1288 #define entry_im_ir_ir(name) \
1292 jit_word_t im = get_imm(); \
1293 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \
1294 (void)jit_##name(im, r0, r1); \
1296 #define entry_lb_ir_ir(name) \
1301 label_t *label = get_label(skip_ws); \
1302 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \
1303 if (label->kind == label_kind_code_forward) \
1304 jmp_forward((void *)jit_##name(r0, r1), label); \
1306 jmp = jit_##name(r0, r1); \
1307 jit_patch_at(jmp, (jit_node_t *)label->value); \
1310 #define entry_lb_ir_im(name) \
1315 label_t *label = get_label(skip_ws); \
1316 jit_gpr_t r0 = get_ireg(); \
1317 jit_word_t im = get_imm(); \
1318 if (label->kind == label_kind_code_forward) \
1319 jmp_forward((void *)jit_##name(r0, im), label); \
1321 jmp = jit_##name(r0, im); \
1322 jit_patch_at(jmp, (jit_node_t *)label->value); \
1325 #define entry_lb(name) \
1330 label_t *label = get_label(skip_ws); \
1331 if (label->kind == label_kind_code_forward) \
1332 jmp_forward((void *)jit_##name(), label); \
1334 jmp = jit_##name(); \
1335 jit_patch_at(jmp, (jit_node_t *)label->value); \
1338 #define entry_pm(name) \
1342 void *pm = get_pointer(skip_ws); \
1345 #define entry_fa(name) \
1349 jit_fpr_t r0 = get_freg(); \
1350 jit_pointer_t ac = get_arg(); \
1351 jit_##name(r0, ac); \
1353 #define entry_fma(name) \
1357 jit_float64_t im = get_float(skip_ws); \
1358 jit_pointer_t ac = get_arg(); \
1359 jit_##name(im, ac); \
1361 #define entry_fr_fr_fr(name) \
1365 jit_fpr_t r0 = get_freg(), r1 = get_freg(), r2 = get_freg(); \
1366 jit_##name(r0, r1, r2); \
1368 #define entry_fr_fr_fr_fr(name) \
1372 jit_fpr_t r0 = get_freg(), r1 = get_freg(), \
1373 r2 = get_freg(), r3 = get_freg(); \
1374 jit_##name(r0, r1, r2, r3); \
1376 #define entry_fr_fr_fm(name) \
1380 jit_fpr_t r0 = get_freg(), r1 = get_freg(); \
1381 jit_float64_t im = get_float(skip_ws); \
1382 jit_##name(r0, r1, make_float(im)); \
1384 #define entry_fr_fr_fr_fm(name) \
1388 jit_fpr_t r0 = get_freg(), r1 = get_freg(), \
1390 jit_float64_t im = get_float(skip_ws); \
1391 jit_##name(r0, r1, r2, make_float(im)); \
1393 #define entry_fr_fr_dm(name) \
1397 jit_fpr_t r0 = get_freg(), r1 = get_freg(); \
1398 jit_float64_t im = get_float(skip_ws); \
1399 jit_##name(r0, r1, im); \
1401 #define entry_fr_fr_fr_dm(name) \
1405 jit_fpr_t r0 = get_freg(), r1 = get_freg(), \
1407 jit_float64_t im = get_float(skip_ws); \
1408 jit_##name(r0, r1, r2, im); \
1410 #define entry_fr_fr(name) \
1414 jit_fpr_t r0 = get_freg(), r1 = get_freg(); \
1415 jit_##name(r0, r1); \
1417 #define entry_ir_fr_fr(name) \
1421 jit_gpr_t r0 = get_ireg(); \
1422 jit_fpr_t r1 = get_freg(), r2 = get_freg(); \
1423 jit_##name(r0, r1, r2); \
1425 #define entry_ir_fr_fm(name) \
1429 jit_gpr_t r0 = get_ireg(); \
1430 jit_fpr_t r1 = get_freg(); \
1431 jit_float64_t im = get_float(skip_ws); \
1432 jit_##name(r0, r1, make_float(im)); \
1434 #define entry_ir_fr_dm(name) \
1438 jit_gpr_t r0 = get_ireg(); \
1439 jit_fpr_t r1 = get_freg(); \
1440 jit_float64_t im = get_float(skip_ws); \
1441 jit_##name(r0, r1, im); \
1443 #define entry_ir_fr(name) \
1447 jit_gpr_t r0 = get_ireg(); \
1448 jit_fpr_t r1 = get_freg(); \
1449 jit_##name(r0, r1); \
1451 #define entry_fr_ir(name) \
1455 jit_fpr_t r0 = get_freg(); \
1456 jit_gpr_t r1 = get_ireg(); \
1457 jit_##name(r0, r1); \
1459 #define entry_fr_im(name) \
1463 jit_fpr_t r0 = get_freg(); \
1464 jit_word_t i0 = get_imm(); \
1465 jit_##name(r0, i0); \
1467 #define entry_ir_fm(name) \
1471 jit_gpr_t r0 = get_ireg(); \
1472 jit_float64_t im = get_float(skip_ws); \
1473 jit_##name(r0, make_float(im)); \
1475 #define entry_ir_dm(name) \
1479 jit_gpr_t r0 = get_ireg(); \
1480 jit_float64_t im = get_float(skip_ws); \
1481 jit_##name(r0,im); \
1483 #define entry_ir_ir_dm(name) \
1487 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \
1488 jit_float64_t im = get_float(skip_ws); \
1489 jit_##name(r0, r1, im); \
1491 #define entry_fr_fm(name) \
1495 jit_fpr_t r0 = get_freg(); \
1496 jit_float64_t im = get_float(skip_ws); \
1497 jit_##name(r0, make_float(im)); \
1499 #define entry_fr_dm(name) \
1503 jit_fpr_t r0 = get_freg(); \
1504 jit_float64_t im = get_float(skip_ws); \
1505 jit_##name(r0, im); \
1507 #define entry_fr_pm(name) \
1511 jit_fpr_t r0 = get_freg(); \
1512 void *pm = get_pointer(skip_ws); \
1513 jit_##name(r0, pm); \
1515 #define entry_fr_ir_ir(name) \
1519 jit_fpr_t r0 = get_freg(); \
1520 jit_gpr_t r1 = get_ireg(), r2 = get_ireg(); \
1521 jit_##name(r0, r1, r2); \
1523 #define entry_fr_ir_im(name) \
1527 jit_fpr_t r0 = get_freg(); \
1528 jit_gpr_t r1 = get_ireg(); \
1529 jit_word_t im = get_imm(); \
1530 jit_##name(r0, r1, im); \
1532 #define entry_fr_im_im(name) \
1536 jit_fpr_t r0 = get_freg(); \
1537 jit_word_t i0 = get_imm(); \
1538 jit_word_t i1 = get_imm(); \
1539 jit_##name(r0, i0, i1); \
1541 #define entry_pm_fr(name) \
1545 void *pm = get_pointer(skip_ws); \
1546 jit_fpr_t r0 = get_freg(); \
1547 jit_##name(pm, r0); \
1549 #define entry_ir_ir_fr(name) \
1553 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \
1554 jit_fpr_t r2 = get_freg(); \
1555 jit_##name(r0, r1, r2); \
1557 #define entry_im_ir_fr(name) \
1561 jit_word_t im = get_imm(); \
1562 jit_gpr_t r0 = get_ireg(); \
1563 jit_fpr_t r1 = get_freg(); \
1564 jit_##name(im, r0, r1); \
1566 #define entry_lb_fr_fr(name) \
1571 label_t *label = get_label(skip_ws); \
1572 jit_fpr_t r0 = get_freg(), r1 = get_freg(); \
1573 if (label->kind == label_kind_code_forward) \
1574 jmp_forward((void *)jit_##name(r0, r1), label); \
1576 jmp = jit_##name(r0, r1); \
1577 jit_patch_at(jmp, (jit_node_t *)label->value); \
1580 #define entry_lb_fr_fm(name) \
1585 label_t *label = get_label(skip_ws); \
1586 jit_fpr_t r0 = get_freg(); \
1587 jit_float64_t im = get_float(skip_ws); \
1588 if (label->kind == label_kind_code_forward) \
1589 jmp_forward((void *)jit_##name(r0, make_float(im)), label); \
1591 jmp = jit_##name(r0, make_float(im)); \
1592 jit_patch_at(jmp, (jit_node_t *)label->value); \
1595 #define entry_lb_fr_dm(name) \
1600 label_t *label = get_label(skip_ws); \
1601 jit_fpr_t r0 = get_freg(); \
1602 jit_float64_t im = get_float(skip_ws); \
1603 if (label->kind == label_kind_code_forward) \
1604 jmp_forward((void *)jit_##name(r0, im), label); \
1606 jmp = jit_##name(r0, im); \
1607 jit_patch_at(jmp, (jit_node_t *)label->value); \
1610 #define entry_fr(name) \
1614 jit_fpr_t r0 = get_freg(); \
1617 #define entry_fm(name) \
1621 jit_float64_t im = get_float(skip_ws); \
1622 jit_##name(make_float(im)); \
1624 #define entry_dm(name) \
1628 jit_float64_t im = get_float(skip_ws); \
1631 #define entry_fn(name) \
1642 value = (void *)(jit_word_t)get_uint(skip_none); \
1645 switch (expression()) { \
1647 value = (void *)parser.value.i; \
1650 value = parser.value.p; \
1653 error("expecting pointer"); \
1658 value = parser.value.p; \
1662 label = get_label(skip_none); \
1663 if (label->kind == label_kind_code_forward) \
1664 call_forward((void *)jit_##name(NULL), label); \
1666 jit_patch_at(jit_##name(NULL), label->value); \
1669 jit_##name(value); \
1674 (void)identifier(ch);
1675 jit_name(parser.string);
1679 if (primary(skip_ws) != tok_register)
1680 error("bad register");
1681 jit_live(parser.regval);
1686 entry_im(frame) entry_im(tramp)
1691 jit_word_t i, im = get_imm();
1692 i = jit_allocai(im);
1693 symbol = get_symbol();
1694 symbol->type = type_l;
1695 symbol->value.i = i;
1697 entry_ir_ir(allocar)
1698 entry_ca(arg_c) entry_ca(arg_s)
1700 #if __WORDSIZE == 64
1704 entry_ia(getarg_c) entry_ia(getarg_uc)
1705 entry_ia(getarg_s) entry_ia(getarg_us)
1707 #if __WORDSIZE == 64
1708 entry_ia(getarg_ui) entry_ia(getarg_l)
1711 entry_ia(putargr_c) entry_ima(putargi_c)
1712 entry_ia(putargr_uc) entry_ima(putargi_uc)
1713 entry_ia(putargr_s) entry_ima(putargi_s)
1714 entry_ia(putargr_us) entry_ima(putargi_us)
1715 entry_ia(putargr_i) entry_ima(putargi_i)
1716 #if __WORDSIZE == 64
1717 entry_ia(putargr_ui) entry_ima(putargi_ui)
1718 entry_ia(putargr_l) entry_ima(putargi_l)
1720 entry_ia(putargr) entry_ima(putargi)
1721 entry_ir_ir_ir(addr) entry_ir_ir_im(addi)
1722 entry_ir_ir_ir(addxr) entry_ir_ir_im(addxi)
1723 entry_ir_ir_ir(addcr) entry_ir_ir_im(addci)
1724 entry_ir_ir_ir(subr) entry_ir_ir_im(subi)
1725 entry_ir_ir_ir(subxr) entry_ir_ir_im(subxi)
1726 entry_ir_ir_ir(subcr) entry_ir_ir_im(subci)
1727 entry_ir_ir_ir(rsbr) entry_ir_ir_im(rsbi)
1728 entry_ir_ir_ir(mulr) entry_ir_ir_im(muli)
1729 entry_ir_ir_ir(hmulr) entry_ir_ir_im(hmuli)
1730 entry_ir_ir_ir(hmulr_u) entry_ir_ir_im(hmuli_u)
1731 entry_ir_ir_ir_ir(qmulr) entry_ir_ir_ir_im(qmuli)
1732 entry_ir_ir_ir_ir(qmulr_u) entry_ir_ir_ir_im(qmuli_u)
1733 entry_ir_ir_ir(divr) entry_ir_ir_im(divi)
1734 entry_ir_ir_ir(divr_u) entry_ir_ir_im(divi_u)
1735 entry_ir_ir_ir_ir(qdivr) entry_ir_ir_ir_im(qdivi)
1736 entry_ir_ir_ir_ir(qdivr_u) entry_ir_ir_ir_im(qdivi_u)
1737 entry_ir_ir_ir(remr) entry_ir_ir_im(remi)
1738 entry_ir_ir_ir(remr_u) entry_ir_ir_im(remi_u)
1739 entry_ir_ir_ir(andr) entry_ir_ir_im(andi)
1740 entry_ir_ir_ir(orr) entry_ir_ir_im(ori)
1741 entry_ir_ir_ir(xorr) entry_ir_ir_im(xori)
1742 entry_ir_ir_ir(lshr) entry_ir_ir_im(lshi)
1743 entry_ir_ir_ir_ir(qlshr) entry_ir_ir_ir_im(qlshi)
1744 entry_ir_ir_ir_ir(qlshr_u) entry_ir_ir_ir_im(qlshi_u)
1745 entry_ir_ir_ir(rshr) entry_ir_ir_im(rshi)
1746 entry_ir_ir_ir_ir(qrshr) entry_ir_ir_ir_im(qrshi)
1747 entry_ir_ir_ir(rshr_u) entry_ir_ir_im(rshi_u)
1748 entry_ir_ir_ir_ir(qrshr_u) entry_ir_ir_ir_im(qrshi_u)
1749 entry_ir_ir_ir(lrotr) entry_ir_ir_im(lroti)
1750 entry_ir_ir_ir(rrotr) entry_ir_ir_im(rroti)
1751 entry_ir_ir(negr) entry_ir_im(negi)
1752 entry_ir_ir(comr) entry_ir_im(comi)
1753 entry_ir_ir(clor) entry_ir_im(cloi)
1754 entry_ir_ir(clzr) entry_ir_im(clzi)
1755 entry_ir_ir(ctor) entry_ir_im(ctoi)
1756 entry_ir_ir(ctzr) entry_ir_im(ctzi)
1757 entry_ir_ir(rbitr) entry_ir_im(rbiti)
1758 entry_ir_ir(popcntr) entry_ir_im(popcnti)
1759 entry_ir_ir_ir(ltr) entry_ir_ir_im(lti)
1760 entry_ir_ir_ir(ltr_u) entry_ir_ir_im(lti_u)
1761 entry_ir_ir_ir(ler) entry_ir_ir_im(lei)
1762 entry_ir_ir_ir(ler_u) entry_ir_ir_im(lei_u)
1763 entry_ir_ir_ir(eqr) entry_ir_ir_im(eqi)
1764 entry_ir_ir_ir(ger) entry_ir_ir_im(gei)
1765 entry_ir_ir_ir(ger_u) entry_ir_ir_im(gei_u)
1766 entry_ir_ir_ir(gtr) entry_ir_ir_im(gti)
1767 entry_ir_ir_ir(gtr_u) entry_ir_ir_im(gti_u)
1768 entry_ir_ir_ir(ner) entry_ir_ir_im(nei)
1769 entry_ir_ir_ir_ir(casr) entry_ir_im_ir_ir(casi)
1777 jit_gpr_t r0 = get_ireg();
1783 value = (void *)(jit_word_t)get_uint(skip_none);
1787 value = (void *)parser.value.i;
1790 switch (expression()) {
1792 value = (void *)parser.value.i;
1795 value = parser.value.p;
1798 error("expecting pointer");
1803 value = parser.value.p;
1807 label = get_label(skip_none);
1808 if (label->kind == label_kind_code ||
1809 label->kind == label_kind_code_forward) {
1810 mov_forward((void *)jit_movi(r0, 0), label);
1813 value = label->value;
1816 jit_movi(r0, (jit_word_t)value);
1819 entry_ir_ir_im_im(extr) entry_ir_im_im_im(exti)
1820 entry_ir_ir_im_im(extr_u) entry_ir_im_im_im(exti_u)
1821 entry_ir_ir_im_im(depr) entry_ir_im_im_im(depi)
1822 entry_ir_ir(extr_c) entry_ir_im(exti_c)
1823 entry_ir_ir(extr_uc) entry_ir_im(exti_uc)
1824 entry_ir_ir(extr_s) entry_ir_im(exti_s)
1825 entry_ir_ir(extr_us) entry_ir_im(exti_us)
1826 #if __WORDSIZE == 64
1827 entry_ir_ir(extr_i) entry_ir_im(exti_i)
1828 entry_ir_ir(extr_ui) entry_ir_im(exti_ui)
1830 entry_ir_ir(htonr_us) entry_ir_im(htoni_us)
1831 entry_ir_ir(ntohr_us) entry_ir_im(ntohi_us)
1832 entry_ir_ir(htonr_ui) entry_ir_im(htoni_ui)
1833 entry_ir_ir(ntohr_ui) entry_ir_im(ntohi_ui)
1834 #if __WORDSIZE == 64
1835 entry_ir_ir(htonr_ul) entry_ir_im(htoni_ul)
1836 entry_ir_ir(ntohr_ul) entry_ir_im(ntohi_ul)
1838 entry_ir_ir(htonr) entry_ir_im(htoni)
1839 entry_ir_ir(ntohr) entry_ir_im(ntohi)
1840 entry_ir_ir(bswapr_us) entry_ir_im(bswapi_us)
1841 entry_ir_ir(bswapr_ui) entry_ir_im(bswapi_ui)
1842 #if __WORDSIZE == 64
1843 entry_ir_ir(bswapr_ul) entry_ir_im(bswapi_ul)
1845 entry_ir_ir(bswapr) entry_ir_im(bswapi)
1846 entry_ir_ir_ir(movnr) entry_ir_ir_ir(movzr)
1847 entry_ir_ir(ldr_c) entry_ir_pm(ldi_c)
1848 entry_ir_ir(ldr_uc) entry_ir_pm(ldi_uc)
1849 entry_ir_ir(ldr_s) entry_ir_pm(ldi_s)
1850 entry_ir_ir(ldr_us) entry_ir_pm(ldi_us)
1851 entry_ir_ir(ldr_i) entry_ir_pm(ldi_i)
1852 #if __WORDSIZE == 64
1853 entry_ir_ir(ldr_ui) entry_ir_pm(ldi_ui)
1854 entry_ir_ir(ldr_l) entry_ir_pm(ldi_l)
1856 entry_ir_ir(ldr) entry_ir_pm(ldi)
1857 entry_ir_ir_ir(ldxr_c) entry_ir_ir_im(ldxi_c)
1858 entry_ir_ir_ir(ldxr_uc) entry_ir_ir_im(ldxi_uc)
1859 entry_ir_ir_ir(ldxr_s) entry_ir_ir_im(ldxi_s)
1860 entry_ir_ir_ir(ldxr_us) entry_ir_ir_im(ldxi_us)
1861 entry_ir_ir_ir(ldxr_i) entry_ir_ir_im(ldxi_i)
1862 #if __WORDSIZE == 64
1863 entry_ir_ir_ir(ldxr_ui) entry_ir_ir_im(ldxi_ui)
1864 entry_ir_ir_ir(ldxr_l) entry_ir_ir_im(ldxi_l)
1866 entry_ir_ir_ir(ldxr) entry_ir_ir_im(ldxi)
1867 entry_ir_ir_im(unldr) entry_ir_im_im(unldi)
1868 entry_ir_ir_im(unldr_u) entry_ir_im_im(unldi_u)
1869 entry_ir_ir(str_c) entry_pm_ir(sti_c)
1870 entry_ir_ir(str_s) entry_pm_ir(sti_s)
1871 entry_ir_ir(str_i) entry_pm_ir(sti_i)
1872 #if __WORDSIZE == 64
1873 entry_ir_ir(str_l) entry_pm_ir(sti_l)
1875 entry_ir_ir(str) entry_pm_ir(sti)
1876 entry_ir_ir_ir(stxr_c) entry_im_ir_ir(stxi_c)
1877 entry_ir_ir_ir(stxr_s) entry_im_ir_ir(stxi_s)
1878 entry_ir_ir_ir(stxr_i) entry_im_ir_ir(stxi_i)
1879 #if __WORDSIZE == 64
1880 entry_ir_ir_ir(stxr_l) entry_im_ir_ir(stxi_l)
1882 entry_ir_ir_ir(stxr) entry_im_ir_ir(stxi)
1883 entry_ir_ir_im(unstr) entry_im_ir_im(unsti)
1884 entry_lb_ir_ir(bltr) entry_lb_ir_im(blti)
1885 entry_lb_ir_ir(bltr_u) entry_lb_ir_im(blti_u)
1886 entry_lb_ir_ir(bler) entry_lb_ir_im(blei)
1887 entry_lb_ir_ir(bler_u) entry_lb_ir_im(blei_u)
1888 entry_lb_ir_ir(beqr) entry_lb_ir_im(beqi)
1889 entry_lb_ir_ir(bger) entry_lb_ir_im(bgei)
1890 entry_lb_ir_ir(bger_u) entry_lb_ir_im(bgei_u)
1891 entry_lb_ir_ir(bgtr) entry_lb_ir_im(bgti)
1892 entry_lb_ir_ir(bgtr_u) entry_lb_ir_im(bgti_u)
1893 entry_lb_ir_ir(bner) entry_lb_ir_im(bnei)
1894 entry_lb_ir_ir(bmsr) entry_lb_ir_im(bmsi)
1895 entry_lb_ir_ir(bmcr) entry_lb_ir_im(bmci)
1896 entry_lb_ir_ir(boaddr) entry_lb_ir_im(boaddi)
1897 entry_lb_ir_ir(boaddr_u) entry_lb_ir_im(boaddi_u)
1898 entry_lb_ir_ir(bxaddr) entry_lb_ir_im(bxaddi)
1899 entry_lb_ir_ir(bxaddr_u) entry_lb_ir_im(bxaddi_u)
1900 entry_lb_ir_ir(bosubr) entry_lb_ir_im(bosubi)
1901 entry_lb_ir_ir(bosubr_u) entry_lb_ir_im(bosubi_u)
1902 entry_lb_ir_ir(bxsubr) entry_lb_ir_im(bxsubi)
1903 entry_lb_ir_ir(bxsubr_u) entry_lb_ir_im(bxsubi_u)
1904 entry_ir(jmpr) entry_lb(jmpi)
1905 entry_ir(callr) entry_fn(calli)
1907 entry_ir(pushargr_c) entry_im(pushargi_c)
1908 entry_ir(pushargr_uc) entry_im(pushargi_uc)
1909 entry_ir(pushargr_s) entry_im(pushargi_s)
1910 entry_ir(pushargr_us) entry_im(pushargi_us)
1911 entry_ir(pushargr_i) entry_im(pushargi_i)
1912 #if __WORDSIZE == 64
1913 entry_ir(pushargr_ui) entry_im(pushargi_ui)
1914 entry_ir(pushargr_l) entry_im(pushargi_l)
1916 entry_ir(pushargr) entry_im(pushargi)
1917 entry_ir(finishr) entry_fn(finishi)
1919 entry_ir(retr_c) entry_im(reti_c)
1920 entry_ir(retr_uc) entry_im(reti_uc)
1921 entry_ir(retr_s) entry_im(reti_s)
1922 entry_ir(retr_us) entry_im(reti_us)
1923 entry_ir(retr_i) entry_im(reti_i)
1924 #if __WORDSIZE == 64
1925 entry_ir(retr_ui) entry_im(reti_ui)
1926 entry_ir(retr_l) entry_im(reti_l)
1928 entry_ir(retr) entry_im(reti)
1929 entry_ir(retval_c) entry_ir(retval_uc)
1930 entry_ir(retval_s) entry_ir(retval_us)
1932 #if __WORDSIZE == 64
1933 entry_ir(retval_ui) entry_ir(retval_l)
1937 entry_ca(arg_f) entry_fa(getarg_f)
1938 entry_fa(putargr_f) entry_fma(putargi_f)
1939 entry_fr_fr_fr(addr_f) entry_fr_fr_fm(addi_f)
1940 entry_fr_fr_fr(subr_f) entry_fr_fr_fm(subi_f)
1941 entry_fr_fr_fr(rsbr_f) entry_fr_fr_fm(rsbi_f)
1942 entry_fr_fr_fr(mulr_f) entry_fr_fr_fm(muli_f)
1943 entry_fr_fr_fr(divr_f) entry_fr_fr_fm(divi_f)
1944 entry_fr_fr(negr_f) entry_fr_fm(negi_f)
1945 entry_fr_fr(absr_f) entry_fr_fm(absi_f)
1946 entry_fr_fr(sqrtr_f) entry_fr_fm(sqrti_f)
1947 entry_fr_fr_fr_fr(fmar_f) entry_fr_fr_fr_fm(fmai_f)
1948 entry_fr_fr_fr_fr(fmsr_f) entry_fr_fr_fr_fm(fmsi_f)
1949 entry_fr_fr_fr_fr(fnmar_f) entry_fr_fr_fr_fm(fnmai_f)
1950 entry_fr_fr_fr_fr(fnmsr_f) entry_fr_fr_fr_fm(fnmsi_f)
1951 entry_ir_fr_fr(ltr_f) entry_ir_fr_fm(lti_f)
1952 entry_ir_fr_fr(ler_f) entry_ir_fr_fm(lei_f)
1953 entry_ir_fr_fr(eqr_f) entry_ir_fr_fm(eqi_f)
1954 entry_ir_fr_fr(ger_f) entry_ir_fr_fm(gei_f)
1955 entry_ir_fr_fr(gtr_f) entry_ir_fr_fm(gti_f)
1956 entry_ir_fr_fr(ner_f) entry_ir_fr_fm(nei_f)
1957 entry_ir_fr_fr(unltr_f) entry_ir_fr_fm(unlti_f)
1958 entry_ir_fr_fr(unler_f) entry_ir_fr_fm(unlei_f)
1959 entry_ir_fr_fr(uneqr_f) entry_ir_fr_fm(uneqi_f)
1960 entry_ir_fr_fr(unger_f) entry_ir_fr_fm(ungei_f)
1961 entry_ir_fr_fr(ungtr_f) entry_ir_fr_fm(ungti_f)
1962 entry_ir_fr_fr(ltgtr_f) entry_ir_fr_fm(ltgti_f)
1963 entry_ir_fr_fr(ordr_f) entry_ir_fr_fm(ordi_f)
1964 entry_ir_fr_fr(unordr_f) entry_ir_fr_fm(unordi_f)
1965 entry_ir_fr(truncr_f_i)
1966 #if __WORDSIZE == 64
1967 entry_ir_fr(truncr_f_l)
1969 entry_ir_fr(truncr_f)
1970 entry_fr_ir(extr_f) entry_fr_fr(extr_d_f)
1971 entry_fr_fr(movr_f) entry_fr_fm(movi_f)
1972 entry_fr_ir(movr_w_f) entry_ir_fr(movr_f_w)
1973 entry_ir_fm(movi_f_w) entry_fr_im(movi_w_f)
1974 entry_fr_ir(ldr_f) entry_fr_pm(ldi_f)
1975 entry_fr_ir_ir(ldxr_f) entry_fr_ir_im(ldxi_f)
1976 entry_fr_ir_im(unldr_x) entry_fr_im_im(unldi_x)
1977 entry_ir_fr(str_f) entry_pm_fr(sti_f)
1978 entry_ir_ir_fr(stxr_f) entry_im_ir_fr(stxi_f)
1979 entry_ir_fr_im(unstr_x) entry_im_fr_im(unsti_x)
1980 entry_lb_fr_fr(bltr_f) entry_lb_fr_fm(blti_f)
1981 entry_lb_fr_fr(bler_f) entry_lb_fr_fm(blei_f)
1982 entry_lb_fr_fr(beqr_f) entry_lb_fr_fm(beqi_f)
1983 entry_lb_fr_fr(bger_f) entry_lb_fr_fm(bgei_f)
1984 entry_lb_fr_fr(bgtr_f) entry_lb_fr_fm(bgti_f)
1985 entry_lb_fr_fr(bner_f) entry_lb_fr_fm(bnei_f)
1986 entry_lb_fr_fr(bunltr_f) entry_lb_fr_fm(bunlti_f)
1987 entry_lb_fr_fr(bunler_f) entry_lb_fr_fm(bunlei_f)
1988 entry_lb_fr_fr(buneqr_f) entry_lb_fr_fm(buneqi_f)
1989 entry_lb_fr_fr(bunger_f) entry_lb_fr_fm(bungei_f)
1990 entry_lb_fr_fr(bungtr_f) entry_lb_fr_fm(bungti_f)
1991 entry_lb_fr_fr(bltgtr_f) entry_lb_fr_fm(bltgti_f)
1992 entry_lb_fr_fr(bordr_f) entry_lb_fr_fm(bordi_f)
1993 entry_lb_fr_fr(bunordr_f) entry_lb_fr_fm(bunordi_f)
1994 entry_fr(pushargr_f) entry_fm(pushargi_f)
1995 entry_fr(retr_f) entry_fm(reti_f)
1997 entry_ca(arg_d) entry_fa(getarg_d)
1998 entry_fa(putargr_d) entry_fma(putargi_d)
1999 entry_fr_fr_fr(addr_d) entry_fr_fr_dm(addi_d)
2000 entry_fr_fr_fr(subr_d) entry_fr_fr_dm(subi_d)
2001 entry_fr_fr_fr(rsbr_d) entry_fr_fr_dm(rsbi_d)
2002 entry_fr_fr_fr(mulr_d) entry_fr_fr_dm(muli_d)
2003 entry_fr_fr_fr(divr_d) entry_fr_fr_dm(divi_d)
2004 entry_fr_fr(negr_d) entry_fr_fm(negi_d)
2005 entry_fr_fr(absr_d) entry_fr_fm(absi_d)
2006 entry_fr_fr(sqrtr_d) entry_fr_fm(sqrti_d)
2007 entry_fr_fr_fr_fr(fmar_d) entry_fr_fr_fr_dm(fmai_d)
2008 entry_fr_fr_fr_fr(fmsr_d) entry_fr_fr_fr_dm(fmsi_d)
2009 entry_fr_fr_fr_fr(fnmar_d) entry_fr_fr_fr_dm(fnmai_d)
2010 entry_fr_fr_fr_fr(fnmsr_d) entry_fr_fr_fr_dm(fnmsi_d)
2011 entry_ir_fr_fr(ltr_d) entry_ir_fr_dm(lti_d)
2012 entry_ir_fr_fr(ler_d) entry_ir_fr_dm(lei_d)
2013 entry_ir_fr_fr(eqr_d) entry_ir_fr_dm(eqi_d)
2014 entry_ir_fr_fr(ger_d) entry_ir_fr_dm(gei_d)
2015 entry_ir_fr_fr(gtr_d) entry_ir_fr_dm(gti_d)
2016 entry_ir_fr_fr(ner_d) entry_ir_fr_dm(nei_d)
2017 entry_ir_fr_fr(unltr_d) entry_ir_fr_dm(unlti_d)
2018 entry_ir_fr_fr(unler_d) entry_ir_fr_dm(unlei_d)
2019 entry_ir_fr_fr(uneqr_d) entry_ir_fr_dm(uneqi_d)
2020 entry_ir_fr_fr(unger_d) entry_ir_fr_dm(ungei_d)
2021 entry_ir_fr_fr(ungtr_d) entry_ir_fr_dm(ungti_d)
2022 entry_ir_fr_fr(ltgtr_d) entry_ir_fr_dm(ltgti_d)
2023 entry_ir_fr_fr(ordr_d) entry_ir_fr_dm(ordi_d)
2024 entry_ir_fr_fr(unordr_d) entry_ir_fr_dm(unordi_d)
2025 entry_ir_fr(truncr_d_i)
2026 #if __WORDSIZE == 64
2027 entry_ir_fr(truncr_d_l)
2029 entry_ir_fr(truncr_d)
2030 entry_fr_ir(extr_d) entry_fr_fr(extr_f_d)
2031 entry_fr_fr(movr_d) entry_fr_dm(movi_d)
2032 #if __WORDSIZE == 32
2033 entry_fr_ir_ir(movr_ww_d) entry_ir_ir_fr(movr_d_ww)
2034 entry_ir_ir_dm(movi_d_ww) entry_fr_im_im(movi_ww_d)
2036 entry_fr_ir(movr_w_d) entry_ir_fr(movr_d_w)
2037 entry_ir_dm(movi_d_w) entry_fr_im(movi_w_d)
2039 entry_fr_ir(ldr_d) entry_fr_pm(ldi_d)
2040 entry_fr_ir_ir(ldxr_d) entry_fr_ir_im(ldxi_d)
2041 entry_ir_fr(str_d) entry_pm_fr(sti_d)
2042 entry_ir_ir_fr(stxr_d) entry_im_ir_fr(stxi_d)
2043 entry_lb_fr_fr(bltr_d) entry_lb_fr_dm(blti_d)
2044 entry_lb_fr_fr(bler_d) entry_lb_fr_dm(blei_d)
2045 entry_lb_fr_fr(beqr_d) entry_lb_fr_dm(beqi_d)
2046 entry_lb_fr_fr(bger_d) entry_lb_fr_dm(bgei_d)
2047 entry_lb_fr_fr(bgtr_d) entry_lb_fr_dm(bgti_d)
2048 entry_lb_fr_fr(bner_d) entry_lb_fr_dm(bnei_d)
2049 entry_lb_fr_fr(bunltr_d) entry_lb_fr_dm(bunlti_d)
2050 entry_lb_fr_fr(bunler_d) entry_lb_fr_dm(bunlei_d)
2051 entry_lb_fr_fr(buneqr_d) entry_lb_fr_dm(buneqi_d)
2052 entry_lb_fr_fr(bunger_d) entry_lb_fr_dm(bungei_d)
2053 entry_lb_fr_fr(bungtr_d) entry_lb_fr_dm(bungti_d)
2054 entry_lb_fr_fr(bltgtr_d) entry_lb_fr_dm(bltgti_d)
2055 entry_lb_fr_fr(bordr_d) entry_lb_fr_dm(bordi_d)
2056 entry_lb_fr_fr(bunordr_d) entry_lb_fr_dm(bunordi_d)
2057 entry_fr(pushargr_d) entry_dm(pushargi_d)
2058 entry_fr(retr_d) entry_dm(reti_d)
2063 jit_gpr_t r0 = get_ireg();
2069 jit_gpr_t r0 = get_ireg();
2075 jit_gpr_t r0 = get_ireg(), r1 = get_ireg();
2081 jit_fpr_t r0 = get_freg();
2082 jit_gpr_t r1 = get_ireg();
2083 jit_va_arg_d(r0, r1);
2088 jit_gpr_t r0 = get_ireg();
2094 #undef entry_lb_fr_fm
2095 #undef entry_lb_fr_dm
2096 #undef entry_lb_fr_fr
2097 #undef entry_im_ir_fr
2098 #undef entry_ir_ir_fr
2100 #undef entry_fr_ir_ir
2101 #undef entry_fr_ir_im
2107 #undef entry_ir_fr_fm
2108 #undef entry_ir_fr_dm
2109 #undef entry_ir_fr_fr
2111 #undef entry_fr_fr_fm
2112 #undef entry_fr_fr_dm
2113 #undef entry_fr_fr_fr
2118 #undef entry_lb_ir_im
2119 #undef entry_lb_ir_ir
2120 #undef entry_im_ir_ir
2125 #undef entry_ir_ir_im
2126 #undef entry_ir_ir_ir
2127 #undef entry_ir_ir_im_im
2128 #undef entry_ir_im_im_im
2137 error(const char *format, ...)
2143 va_start(ap, format);
2144 message("error", format, ap);
2146 length = parser.data.length - parser.data.offset;
2147 string = (char *)(parser.data.buffer + parser.data.offset - 1);
2149 strcpy(string + 74, "...");
2151 parser.data.buffer[parser.data.length - 1] = '\0';
2152 fprintf(stderr, "(%s)\n", string);
2157 warn(const char *format, ...)
2160 va_start(ap, format);
2161 message("warning", format, ap);
2166 message(const char *kind, const char *format, va_list ap)
2168 fprintf(stderr, "%s:%d: %s: ", parser.name,
2169 parser.line - parser.newline, kind);
2170 vfprintf(stderr, format, ap);
2171 fputc('\n', stderr);
2179 if (parser.data.offset < parser.data.length)
2180 ch = parser.data.buffer[parser.data.offset++];
2182 /* keep first offset for ungetch */
2183 if ((parser.data.length = fread(parser.data.buffer + 1, 1,
2184 sizeof(parser.data.buffer) - 1,
2185 parser.fp) + 1) <= 1) {
2187 parser.data.offset = 1;
2190 ch = parser.data.buffer[1];
2191 parser.data.offset = 2;
2194 if ((parser.newline = ch == '\n'))
2206 error("unexpected end of file");
2214 if ((parser.newline = ch == '\n'))
2217 if (parser.data.offset)
2218 parser.data.buffer[--parser.data.offset] = ch;
2221 parser.data.buffer[0] = ch;
2231 for (ch = getch();; ch = getch()) {
2241 case ' ': case '\f': case '\r': case '\t':
2254 for (ch = getch();; ch = getch()) {
2264 case ' ': case '\f': case '\n': case '\r': case '\t':
2266 /* handle as newline */
2283 for (ch = getch(); ch != '\n' && ch != EOF; ch = getch())
2287 for (; ch != '/';) {
2288 while (getch_noeof() != '*')
2290 while ((ch = getch_noeof()) == '*')
2305 for (ch = getch(); ch != '\n' && ch != EOF; ch = getch()) {
2308 if ((number(ch)) == tok_int)
2309 parser.line = parser.value.i - 1;
2313 if (parser.offset >= (int)sizeof(parser.name)) {
2314 strncpy(parser.name, parser.string, sizeof(parser.name));
2315 parser.name[sizeof(parser.name) - 1] = '\0';
2318 strcpy(parser.name, parser.string);
2329 get_int(skip_t skip)
2331 switch (primary(skip)) {
2335 parser.type = type_l;
2336 parser.value.i = (jit_word_t)parser.value.p;
2339 error("expecting integer");
2342 return (parser.value.i);
2346 get_uint(skip_t skip)
2348 switch (primary(skip)) {
2349 case tok_char: case tok_int:
2352 parser.type = type_l;
2353 parser.value.ui = (jit_uword_t)parser.value.p;
2356 error("expecting integer");
2359 return (parser.value.ui);
2363 get_float(skip_t skip)
2365 switch (primary(skip)) {
2368 parser.type = type_d;
2369 parser.value.d = parser.value.i;
2374 error("expecting float");
2377 return (parser.value.d);
2380 /* Workaround gcc not converting unordered values from double to
2381 * float (as done in other architectures) on s390 */
2383 make_float(double d)
2385 /* This is an workaround to a bug in Hercules s390 emulator,
2386 * and at least HP-UX ia64 not have these */
2387 #if defined(HAVE_ISNAN) && defined(HAVE_ISINF)
2388 if (isnan(d)) return ( 0.0f/0.0f);
2390 if (d > 0.0) return ( 1.0f/0.0f);
2391 else return (-1.0f/0.0f);
2398 get_pointer(skip_t skip)
2401 token_t token = primary(skip);
2405 label = get_label_by_name(parser.string);
2407 error("bad identifier %s", parser.string);
2408 switch (label->kind) {
2409 case label_kind_data:
2410 case label_kind_code:
2412 case label_kind_code_forward:
2413 /* as expression arguments */
2414 error("forward references not implemented");
2416 case label_kind_dynamic:
2419 parser.type = type_p;
2420 return (parser.value.p = label->value);
2422 parser.type = type_p;
2423 return (parser.value.p = (void *)parser.value.ui);
2425 return (parser.value.p);
2426 default: error("bad pointer");
2431 get_label(skip_t skip)
2440 case 'a' ... 'z': case 'A' ... 'Z': case '_':
2441 (void)identifier(ch);
2444 error("expecting label/immediate");
2446 if ((label = get_label_by_name(parser.string)) == NULL)
2447 label = new_label(label_kind_code_forward,
2448 parser.string, jit_forward());
2457 int check = 1, ch = getch();
2461 parser.regtype = type_l;
2462 switch (ch = getch()) {
2463 case '0': parser.regval = JIT_R0; break;
2464 case '1': parser.regval = JIT_R1; break;
2465 case '2': parser.regval = JIT_R2; break;
2467 num = get_int(skip_none);
2468 if (num < 0 || num >= JIT_R_NUM) goto fail;
2469 parser.regval = JIT_R(num);
2470 if (getch() != ')') goto fail;
2477 parser.regtype = type_l;
2478 switch (ch = getch()) {
2479 case '0': parser.regval = JIT_V0; break;
2480 case '1': parser.regval = JIT_V1; break;
2481 case '2': parser.regval = JIT_V2; break;
2484 num = get_int(skip_none);
2485 if (num < 0 || num >= JIT_V_NUM) goto fail;
2486 parser.regval = JIT_V(num);
2487 if (getch() != ')') goto fail;
2493 parser.regtype = type_d;
2494 switch (ch = getch()) {
2495 case '0': parser.regval = JIT_F0; break;
2496 case '1': parser.regval = JIT_F1; break;
2497 case '2': parser.regval = JIT_F2; break;
2498 case '3': parser.regval = JIT_F3; break;
2499 case '4': parser.regval = JIT_F4; break;
2500 case '5': parser.regval = JIT_F5; break;
2502 parser.regtype = type_l; /* oops */
2503 parser.regval = JIT_FP; break;
2505 num = get_int(skip_none);
2506 if (num < 0 || num >= JIT_F_NUM) goto fail;
2507 parser.regval = JIT_F(num);
2508 if (getch() != ')') goto fail;
2516 error("bad register");
2520 if ((ch >= 'a' && ch <= 'z') ||
2521 (ch >= 'A' && ch <= 'Z') ||
2522 (ch >= '0' && ch <= '9') ||
2528 return (tok_register);
2534 parser.string[0] = ch;
2535 for (parser.offset = 1;;) {
2536 switch ((ch = getch())) {
2537 case 'a' ... 'z': case 'A' ... 'Z': case '0' ... '9' : case '_':
2538 if (parser.offset + 1 >= MAX_IDENTIFIER) {
2539 parser.string[parser.offset] = '\0';
2540 error("bad identifier %s", parser.string);
2542 parser.string[parser.offset++] = ch;
2545 parser.string[parser.offset] = '\0';
2547 return (tok_symbol);
2553 get_data(type_t type)
2562 switch (token = primary(skip_ws)) {
2563 case tok_char: case tok_int:
2564 check_data(sizeof(signed char));
2565 *(signed char *)(data + data_offset) = parser.value.i;
2566 data_offset += sizeof(char);
2569 check_data(parser.offset);
2570 memcpy(data + data_offset, parser.string,
2572 data_offset += parser.offset;
2575 case tok_semicollon:
2576 if (test == data) error("syntax error");
2578 default: error("bad initializer");
2582 check_data(sizeof(signed short));
2583 *(signed short *)(data + data_offset) = get_int(skip_ws);
2584 data_offset += sizeof(short);
2587 check_data(sizeof(signed int));
2588 *(signed int *)(data + data_offset) = get_int(skip_ws);
2589 data_offset += sizeof(int);
2592 check_data(sizeof(jit_word_t));
2593 *(jit_word_t *)(data + data_offset) = get_int(skip_ws);
2594 data_offset += sizeof(jit_word_t);
2597 check_data(sizeof(float));
2598 *(float *)(data + data_offset) = get_float(skip_ws);
2599 data_offset += sizeof(float);
2602 check_data(sizeof(double));
2603 *(double *)(data + data_offset) = get_float(skip_ws);
2604 data_offset += sizeof(double);
2607 /* FIXME **patch if realloc** */
2608 check_data(sizeof(void*));
2609 *(void **)(data + data_offset) = get_pointer(skip_ws);
2610 data_offset += sizeof(void*);
2616 if (ch == '\n' || ch == ';' || ch == EOF)
2626 size_t offset, length;
2628 switch (ch = getch_noeof()) {
2630 /* use .$(expression) for non side effects expression */
2633 case 'a' ... 'z': case 'A' ... 'Z': case '_':
2634 (void)identifier(ch);
2638 if (skipws() != '$')
2639 error("expecting symbol");
2640 /* allow spaces before an expression */
2644 if (parser.string[1] == '\0') {
2645 switch (parser.string[0]) {
2646 case 'c': get_data(type_c); break;
2647 case 's': get_data(type_s); break;
2648 case 'i': get_data(type_i); break;
2649 case 'l': get_data(type_l); break;
2650 case 'f': get_data(type_f); break;
2651 case 'd': get_data(type_d); break;
2652 case 'p': get_data(type_p); break;
2653 default: error("bad type .%c", parser.string[0]);
2656 else if (strcmp(parser.string, "data") == 0) {
2657 if (parser.parsing != PARSING_NONE)
2658 error(".data must be specified once and be the first section");
2659 parser.parsing = PARSING_DATA;
2660 data_length = get_int(skip_ws);
2661 data = (char *)xcalloc(1, data_length);
2663 else if (strcmp(parser.string, "code") == 0) {
2664 if (parser.parsing != PARSING_NONE &&
2665 parser.parsing != PARSING_DATA)
2666 error(".code must be specified once only");
2667 parser.parsing = PARSING_CODE;
2669 else if (strcmp(parser.string, "align") == 0) {
2670 length = get_int(skip_ws);
2671 if (parser.parsing != PARSING_DATA)
2672 error(".align must be in .data");
2673 if (length > 1 && length <= 4096 && !(length & (length - 1))) {
2674 offset = data_offset;
2675 offset += length - ((offset + length) % length);
2676 check_data(offset - data_offset);
2677 data_offset = offset;
2680 error("bad .align %ld (must be a power of 2, >= 2 && <= 4096)",
2681 (jit_word_t)length);
2683 else if (strcmp(parser.string, "size") == 0) {
2684 length = get_int(skip_ws);
2685 if (parser.parsing != PARSING_DATA)
2686 error(".size must be in .data");
2688 data_offset += length;
2690 else if (strcmp(parser.string, "disasm") == 0)
2693 error("unknown command .%s", parser.string);
2697 /* Workaround bug in a few patterns in MSYS64 library;
2698 * below is liberty implementation slightly modified. */
2700 liberty_strtoul(const char *nptr, char **endptr, register int base)
2702 register const char *s = nptr;
2703 register jit_uword_t acc;
2705 register jit_uword_t cutoff;
2706 register int neg = 0, any, cutlim;
2709 * See strtol for comments as to the logic used.
2713 } while (c == ' ' || c == '\t');
2717 } else if (c == '+')
2719 if ((base == 0 || base == 16) &&
2720 c == '0' && (*s == 'x' || *s == 'X')) {
2726 base = c == '0' ? 8 : 10;
2727 cutoff = (jit_uword_t)~0LL / (jit_uword_t)base;
2728 cutlim = (jit_uword_t)~0LL % (jit_uword_t)base;
2729 for (acc = 0, any = 0;; c = *s++) {
2730 if (c >= '0' && c <= '9')
2732 else if ((c >= 'a' && c <= 'z') ||
2733 (c >= 'A' && c <= 'Z'))
2734 c -= (c >= 'A' && c <= 'Z') ? 'A' - 10 : 'a' - 10;
2739 if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
2753 *endptr = (char *) (any ? s - 1 : nptr);
2761 char buffer[1024], *endptr;
2762 int integer = 1, offset = 0, neg = 0, e = 0, d = 0, base = 10;
2764 for (;; ch = getch()) {
2771 if (offset && buffer[offset - 1] != 'e') {
2779 if (offset && buffer[offset - 1] != 'e') {
2792 if (offset == 0 && base == 10) {
2798 if (offset == 0 && base == 8) {
2816 if (offset == 0 && base == 8) {
2821 case 'a': case 'c': case 'd': case 'f':
2834 case '_': case 'g' ... 'w': case 'y': case 'z': case 'A' ... 'Z':
2836 buffer[offset++] = '\0';
2837 error("bad constant %s", buffer);
2842 if (offset + 1 >= (int)sizeof(buffer))
2844 buffer[offset++] = ch;
2847 /* check for literal 0 */
2848 if (offset == 0 && base == 8) buffer[offset++] = '0';
2849 buffer[offset] = '\0';
2852 # define STRTOUL liberty_strtoul
2854 # define STRTOUL strtoul
2856 parser.value.ui = STRTOUL(buffer, &endptr, base);
2857 parser.type = type_l;
2859 parser.value.i = -parser.value.i;
2862 parser.type = type_d;
2863 parser.value.d = strtod(buffer, &endptr);
2865 parser.value.d = -parser.value.d;
2870 return (integer ? tok_int : tok_float);
2877 case 'a': ch = '\a'; break;
2878 case 'b': ch = '\b'; break;
2879 case 'f': ch = '\f'; break;
2880 case 'n': ch = '\n'; break;
2881 case 'r': ch = '\r'; break;
2882 case 't': ch = '\t'; break;
2883 case 'v': ch = '\v'; break;
2895 for (parser.offset = 0;;) {
2896 switch (ch = getch_noeof()) {
2898 if (esc) goto append;
2903 parser.string[parser.offset++] = '\0';
2904 parser.value.p = parser.string;
2905 parser.type = type_p;
2906 return (tok_string);
2915 if (parser.offset + 1 >= parser.length) {
2916 parser.length += 4096;
2917 parser.string = (char *)xrealloc(parser.string,
2920 parser.string[parser.offset++] = ch;
2931 if ((ch = getch_noeof()) == '\\') {
2935 if (getch_noeof() != '\'')
2936 error("bad single byte char");
2939 parser.type = type_l;
2940 parser.value.i = ch & 0xff;
2951 (void)identifier('@');
2952 if ((label = get_label_by_name(parser.string)) == NULL) {
2953 #if __CYGWIN__ ||_WIN32
2954 /* FIXME kludge to pass varargs test case, otherwise,
2955 * will not print/scan float values */
2956 if (strcmp(parser.string + 1, "sprintf") == 0)
2958 else if (strcmp(parser.string + 1, "sscanf") == 0)
2963 value = dlsym(DL_HANDLE, parser.string + 1);
2964 if ((string = dlerror()))
2965 error("%s", string);
2967 label = new_label(label_kind_dynamic, parser.string, value);
2969 parser.type = type_p;
2970 parser.value.p = label->value;
2972 return (tok_pointer);
2976 expression_prim(void)
2983 if (parser.putback) {
2984 parser.expr = parser.putback;
2985 parser.putback = (expr_t)0;
2988 switch (ch = skipws()) {
2990 if ((ch = getch_noeof()) == '=') parser.expr = expr_ne;
2992 ungetch(ch); parser.expr = expr_not;
2995 case '~': parser.expr = expr_com;
2998 if ((ch = getch_noeof()) == '=') parser.expr = expr_mulset;
3000 ungetch(ch); parser.expr = expr_mul;
3004 if ((ch = getch_noeof()) == '=') parser.expr = expr_divset;
3006 ungetch(ch); parser.expr = expr_div;
3010 if ((ch = getch_noeof()) == '=') parser.expr = expr_remset;
3012 ungetch(ch); parser.expr = expr_rem;
3016 switch (ch = getch_noeof()) {
3017 case '+': parser.expr = expr_inc;
3019 case '=': parser.expr = expr_addset;
3021 default: ungetch(ch); parser.expr = expr_add;
3026 switch (ch = getch_noeof()) {
3027 case '-': parser.expr = expr_dec;
3029 case '=': parser.expr = expr_subset;
3031 default: ungetch(ch); parser.expr = expr_sub;
3036 switch (ch = getch_noeof()) {
3037 case '=': parser.expr = expr_le;
3039 case '<': ch = getch_noeof();
3040 if (ch == '=') parser.expr = expr_lshset;
3042 ungetch(ch); parser.expr = expr_lsh;
3045 default: ungetch(ch); parser.expr = expr_lt;
3050 switch (ch = getch_noeof()) {
3051 case '=': parser.expr = expr_ge;
3053 case '>': ch = getch_noeof();
3054 if (ch == '=') parser.expr = expr_rshset;
3056 ungetch(ch); parser.expr = expr_rsh;
3059 default: ungetch(ch); parser.expr = expr_gt;
3064 switch (ch = getch_noeof()) {
3065 case '=': parser.expr = expr_andset;
3067 case '&': parser.expr = expr_andand;
3069 default: ungetch(ch); parser.expr = expr_and;
3074 switch (ch = getch_noeof()) {
3075 case '=': parser.expr = expr_orset;
3077 case '|': parser.expr = expr_oror;
3079 default: ungetch(ch); parser.expr = expr_or;
3084 if ((ch = getch_noeof()) == '=') parser.expr = expr_xorset;
3086 ungetch(ch); parser.expr = expr_xor;
3090 if ((ch = getch_noeof()) == '=') parser.expr = expr_eq;
3092 ungetch(ch); parser.expr = expr_set;
3095 case '(': parser.expr = expr_lparen;
3097 case ')': parser.expr = expr_rparen;
3101 parser.expr = token == tok_int ? expr_int : expr_float;
3105 parser.expr = expr_pointer;
3109 /* no support for nested expressions */
3110 if (parser.string[0] == '\0')
3111 error("syntax error");
3112 parser.expr = expr_symbol;
3113 if ((symbol = get_symbol_by_name(parser.string)) != NULL) {
3114 parser.type = symbol->type;
3115 parser.value = symbol->value;
3118 /* only create symbol on assignment */
3119 parser.type = type_none;
3121 case 'a' ... 'z': case 'A' ... 'Z': case '_':
3123 if ((label = get_label_by_name(parser.string))) {
3124 if (label->kind == label_kind_code_forward)
3125 error("forward value for %s not supported",
3127 parser.expr = expr_pointer;
3128 parser.type = type_p;
3129 parser.value.p = label->value;
3132 error("invalid identifier %s", parser.string);
3136 parser.expr = expr_int;
3139 /* not smart enough to put it in data and/or relocate it, etc */
3140 error("must declare strings as data");
3142 error("syntax error");
3147 expression_inc(int pre)
3153 if (parser.expr != expr_symbol)
3154 error("syntax error");
3156 if ((symbol = get_symbol_by_name(parser.string)) == NULL) {
3157 if (!parser.short_circuit)
3158 error("undefined symbol %s", symbol->name);
3160 if (!parser.short_circuit) {
3161 parser.type = symbol->type;
3163 parser.value = symbol->value;
3164 switch (symbol->type) {
3169 /* should really be an error */
3170 symbol->value.d += 1.0;
3177 parser.value = symbol->value;
3183 expression_dec(int pre)
3189 if (parser.expr != expr_symbol)
3190 error("syntax error");
3192 if ((symbol = get_symbol_by_name(parser.string)) == NULL) {
3193 if (!parser.short_circuit)
3194 error("undefined symbol %s", symbol->name);
3196 if (!parser.short_circuit) {
3197 parser.type = symbol->type;
3199 parser.value = symbol->value;
3200 switch (symbol->type) {
3205 /* should really be an error */
3206 symbol->value.d -= 1.0;
3213 parser.value = symbol->value;
3219 expression_unary(void)
3225 switch (parser.expr) {
3228 switch (parser.type) {
3233 error("syntax error");
3238 switch (parser.type) {
3240 parser.value.i = -parser.value.i;
3243 parser.value.d = -parser.value.d;
3246 error("syntax error");
3257 switch (parser.type) {
3259 parser.value.i = !parser.value.i;
3262 parser.value.i = parser.value.d != 0;
3265 parser.value.i = parser.value.p != NULL;
3268 error("syntax error");
3270 parser.type = type_l;
3274 if (parser.type != type_l)
3275 error("syntax error");
3276 parser.value.i = ~parser.value.i;
3280 if (parser.expr != expr_rparen)
3281 error("syntax error");
3285 strcpy(buffer, parser.string);
3287 switch (parser.expr) {
3289 if ((symbol = get_symbol_by_name(buffer)) == NULL) {
3290 if (!parser.short_circuit)
3291 symbol = new_symbol(buffer);
3295 if (!parser.short_circuit) {
3297 error("syntax error");
3298 symbol->type = parser.type;
3299 symbol->value = parser.value;
3302 case expr_mulset: parser.putback = expr_mul;
3304 case expr_divset: parser.putback = expr_div;
3306 case expr_remset: parser.putback = expr_rem;
3308 case expr_addset: parser.putback = expr_add;
3310 case expr_subset: parser.putback = expr_sub;
3312 case expr_lshset: parser.putback = expr_lsh;
3314 case expr_rshset: parser.putback = expr_rsh;
3316 case expr_andset: parser.putback = expr_and;
3318 case expr_orset: parser.putback = expr_or;
3320 case expr_xorset: parser.putback = expr_xor;
3322 if ((symbol = get_symbol_by_name(buffer)) == NULL) {
3323 if (!parser.short_circuit)
3324 error("undefined symbol %s", buffer);
3325 parser.type = type_l;
3328 switch (parser.putback) {
3329 case expr_mul: case expr_div: case expr_rem:
3332 case expr_add: case expr_sub:
3335 case expr_lsh: case expr_rsh:
3338 case expr_and: case expr_or: case expr_xor:
3358 /* make next token available */
3366 expression_mul(void)
3372 switch (parser.type) {
3373 case type_l: case type_d: case type_p: break;
3377 switch (parser.expr) {
3379 type = parser.type, value = parser.value;
3381 switch (parser.type) {
3384 value.i *= parser.value.i;
3386 value.d *= parser.value.i;
3389 if (type == type_l) {
3393 value.d *= parser.value.d;
3396 error("invalid operand");
3398 parser.type = type, parser.value = value;
3401 type = parser.type, value = parser.value;
3403 switch (parser.type) {
3405 if (type == type_l) {
3406 if (parser.value.i == 0)
3407 error("divide by zero");
3408 value.i /= parser.value.i;
3411 value.d /= parser.value.i;
3414 if (type == type_l) {
3418 value.d /= parser.value.d;
3421 error("invalid operand");
3423 parser.type = type, parser.value = value;
3426 type = parser.type, value = parser.value;
3428 switch (parser.type) {
3430 if (type == type_l) {
3431 if (parser.value.i == 0)
3432 error("divide by zero");
3433 value.i %= parser.value.i;
3436 error("invalid operand");
3439 error("invalid operand");
3441 parser.type = type, parser.value = value;
3450 expression_add(void)
3456 switch (parser.type) {
3457 case type_l: case type_d: case type_p: break;
3461 switch (parser.expr) {
3463 type = parser.type, value = parser.value;
3465 switch (parser.type) {
3469 value.i += parser.value.i;
3472 value.d += parser.value.i;
3475 value.cp += parser.value.i;
3488 error("invalid operand");
3490 value.d += parser.value.d;
3496 value.cp = value.i + parser.value.cp;
3499 error("invalid operand");
3503 error("invalid operand");
3505 parser.type = type, parser.value = value;
3508 type = parser.type, value = parser.value;
3510 switch (parser.type) {
3514 value.i -= parser.value.i;
3517 value.d -= parser.value.i;
3520 value.cp -= parser.value.i;
3533 error("invalid operand");
3535 value.d -= parser.value.d;
3541 value.i = value.cp - parser.value.cp;
3544 error("invalid operand");
3548 error("invalid operand");
3550 parser.type = type, parser.value = value;
3559 expression_shift(void)
3564 switch (parser.type) {
3565 case type_l: case type_d: case type_p: break;
3569 switch (parser.expr) {
3571 value = parser.value.i;
3572 if (parser.type != type_l)
3573 error("invalid operand");
3575 if (parser.type != type_l)
3576 error("invalid operand");
3577 value <<= parser.value.i;
3578 parser.value.i = value;
3581 value = parser.value.i;
3582 if (parser.type != type_l)
3583 error("invalid operand");
3585 if (parser.type != type_l)
3586 error("invalid operand");
3587 value >>= parser.value.i;
3588 parser.value.i = value;
3597 expression_bit(void)
3602 switch (parser.type) {
3603 case type_l: case type_d: case type_p: break;
3607 switch (parser.expr) {
3609 if (parser.type != type_l)
3610 error("invalid operand");
3613 if (parser.type != type_l)
3614 error("invalid operand");
3615 i &= parser.value.i;
3619 if (parser.type != type_l)
3620 error("invalid operand");
3623 if (parser.type != type_l)
3624 error("invalid operand");
3625 i |= parser.value.i;
3629 if (parser.type != type_l)
3630 error("invalid operand");
3633 if (parser.type != type_l)
3634 error("invalid operand");
3635 i ^= parser.value.i;
3645 expression_rel(void)
3651 switch (parser.type) {
3652 case type_l: case type_d: case type_p: break;
3656 switch (parser.expr) {
3658 type = parser.type, value = parser.value;
3660 switch (parser.type) {
3664 value.i = value.i < parser.value.i;
3667 value.i = value.d < parser.value.i;
3670 value.i = (jit_word_t)value.p < parser.value.i;
3677 value.i = value.i < parser.value.d;
3680 value.i = value.d < parser.value.d;
3683 error("invalid operand");
3689 value.i = value.i < (jit_word_t)parser.value.p;
3692 error("invalid operand");
3694 value.i = (jit_word_t)value.p < (jit_word_t)parser.value.p;
3699 error("invalid operand");
3701 parser.type = type_l, parser.value = value;
3704 type = parser.type, value = parser.value;
3706 switch (parser.type) {
3710 value.i = value.i <= parser.value.i;
3713 value.i = value.d <= parser.value.i;
3716 value.i = (jit_word_t)value.p <= parser.value.i;
3723 value.i = value.i <= parser.value.d;
3726 value.i = value.d <= parser.value.d;
3729 value.i = (jit_word_t)value.p <= parser.value.d;
3736 value.i = value.i <= (jit_word_t)parser.value.p;
3739 error("invalid operand");
3741 value.i = (jit_word_t)value.p <= (jit_word_t)parser.value.p;
3746 error("invalid operand");
3748 parser.type = type_l, parser.value = value;
3751 type = parser.type, value = parser.value;
3753 switch (parser.type) {
3757 value.i = value.i == parser.value.i;
3760 value.i = value.d == parser.value.i;
3763 value.i = (jit_word_t)value.p == parser.value.i;
3770 value.i = value.i == parser.value.d;
3773 value.i = value.d == parser.value.d;
3776 error("invalid operand");
3782 value.i = value.i == (jit_word_t)parser.value.p;
3785 error("invalid operand");
3787 value.i = value.p == parser.value.p;
3792 error("invalid operand");
3794 parser.type = type_l, parser.value = value;
3797 type = parser.type, value = parser.value;
3799 switch (parser.type) {
3803 value.i = value.i >= parser.value.i;
3806 value.i = value.d >= parser.value.i;
3809 value.i = (jit_word_t)value.p >= parser.value.i;
3816 value.i = value.i >= parser.value.d;
3819 value.i = value.d >= parser.value.d;
3822 error("invalid operand");
3828 value.i = value.i >= (jit_word_t)parser.value.p;
3831 error("invalid operand");
3833 value.i = (jit_word_t)value.p >= (jit_word_t)parser.value.p;
3838 error("invalid operand");
3840 parser.type = type_l, parser.value = value;
3843 type = parser.type, value = parser.value;
3845 switch (parser.type) {
3849 value.i = value.i > parser.value.i;
3852 value.i = value.d > parser.value.i;
3855 value.i = (jit_word_t)value.p > parser.value.i;
3862 value.i = value.i > parser.value.d;
3865 value.i = value.d > parser.value.d;
3868 error("invalid operand");
3874 value.i = value.i > (jit_word_t)parser.value.p;
3877 error("invalid operand");
3879 value.i = (jit_word_t)value.p > (jit_word_t)parser.value.p;
3884 error("invalid operand");
3886 parser.type = type_l, parser.value = value;
3889 type = parser.type, value = parser.value;
3891 switch (parser.type) {
3895 value.i = value.i != parser.value.i;
3898 value.i = value.d != parser.value.i;
3901 value.i = (jit_word_t)value.p != parser.value.i;
3908 value.i = value.i != parser.value.d;
3911 value.i = value.d != parser.value.d;
3914 error("invalid operand");
3920 value.i = value.i != (jit_word_t)parser.value.p;
3923 error("invalid operand");
3925 value.i = value.p != parser.value.p;
3930 error("invalid operand");
3932 parser.type = type_l, parser.value = value;
3941 expression_cond(void)
3948 switch (parser.type) {
3949 case type_l: case type_d: case type_p: break;
3953 switch (parser.expr) {
3955 type = parser.type, value = parser.value;
3958 short_circuit = value.i == 0;
3961 short_circuit = value.d == 0.0;
3964 short_circuit = value.p == NULL;
3967 parser.short_circuit += short_circuit;
3969 parser.short_circuit -= short_circuit;
3970 switch (parser.type) {
3974 value.i = value.i && parser.value.i;
3977 value.i = value.d && parser.value.i;
3980 value.i = value.p && parser.value.i;
3987 value.i = value.i && parser.value.d;
3990 value.i = value.d && parser.value.d;
3993 value.i = value.p && parser.value.d;
4000 value.i = value.i && parser.value.p;
4003 value.i = value.d && parser.value.p;
4006 value.i = value.p && parser.value.p;
4011 error("invalid operand");
4013 parser.type = type_l, parser.value.i = value.i;
4016 type = parser.type, value = parser.value;
4019 short_circuit = value.i != 0;
4022 short_circuit = value.d != 0.0;
4025 short_circuit = value.p != NULL;
4028 parser.short_circuit += short_circuit;
4030 parser.short_circuit -= short_circuit;
4031 switch (parser.type) {
4035 value.i = value.i || parser.value.i;
4038 value.i = value.d || parser.value.i;
4041 value.i = value.p || parser.value.i;
4048 value.i = value.i || parser.value.d;
4051 value.i = value.d || parser.value.d;
4054 value.i = value.p || parser.value.d;
4061 value.i = value.i || parser.value.p;
4064 value.i = value.d || parser.value.p;
4067 value.i = value.p || parser.value.p;
4072 error("invalid operand");
4074 parser.type = type_l, parser.value.i = value.i;
4087 (void)identifier('$');
4088 if (parser.string[1] == '\0') {
4089 if (getch_noeof() != '(')
4090 error("bad symbol or expression");
4091 parser.type = type_none;
4093 if (parser.expr != expr_rparen)
4094 error("bad expression");
4095 switch (parser.type) {
4101 return (tok_pointer);
4103 error("bad expression");
4106 else if ((symbol = get_symbol_by_name(parser.string))) {
4107 switch (parser.type = symbol->type) {
4109 parser.value.i = symbol->value.i;
4112 parser.value.d = symbol->value.d;
4115 parser.value.p = symbol->value.p;
4116 return (tok_pointer);
4120 error("undefined symbol %s", parser.string);
4124 primary(skip_t skip)
4129 case skip_none: ch = getch(); break;
4130 case skip_ws: ch = skipws(); break;
4131 case skip_nl: ch = skipnl(); break;
4137 case 'a' ... 'z': case 'A' ... 'Z': case '_':
4138 return (identifier(ch));
4139 case '0' ... '9': case '+': case '-':
4140 return (number(ch));
4146 return (character());
4150 return (expression());
4154 return (tok_newline);
4156 return (tok_semicollon);
4158 error("syntax error");
4172 switch (token = primary(skip_nl)) {
4176 if ((label = get_label_by_name(parser.string))) {
4177 if (label->kind == label_kind_code_forward) {
4178 label->kind = label_kind_code;
4179 jit_link(label->value);
4180 jit_note(parser.name, parser.line);
4183 error("label %s: redefined", parser.string);
4186 if (parser.parsing == PARSING_DATA) {
4187 value = data + data_offset;
4188 label = new_label(label_kind_data,
4189 parser.string, value);
4191 else if (parser.parsing == PARSING_CODE) {
4192 value = jit_label();
4193 jit_note(parser.name, parser.line);
4194 label = new_label(label_kind_code,
4195 parser.string, value);
4198 error("label not in .code or .data");
4204 (instr_t *)get_hash(instrs, parser.string)) == NULL)
4205 error("unhandled symbol %s", parser.string);
4206 if (parser.parsing != PARSING_CODE)
4207 error(".code must be specified before instructions");
4208 (*instr->function)();
4216 error("syntax error");
4222 execute(int argc, char *argv[])
4226 function_t function;
4227 patch_t *patch, *next;
4229 for (patch = patches; patch; patch = next) {
4231 label = patch->label;
4232 if (label->kind == label_kind_code_forward)
4233 error("undefined label %s", label->name);
4234 switch (patch->kind) {
4235 case patch_kind_jmp:
4236 case patch_kind_mov:
4237 case patch_kind_call:
4238 jit_patch_at(patch->value, label->value);
4247 if (flag_data == 0) {
4249 jit_set_data(NULL, 0, JIT_DISABLE_DATA | JIT_DISABLE_NOTE);
4252 function = jit_emit();
4253 if (flag_verbose > 1 || flag_disasm) {
4255 fprintf(stderr, " - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n");
4257 if (flag_verbose > 0 || flag_disasm) {
4259 fprintf(stderr, " - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n");
4261 if (flag_verbose && argc) {
4262 for (result = 0; result < argc; result++)
4263 printf("argv[%d] = %s\n", result, argv[result]);
4264 fprintf(stderr, " - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n");
4271 result = (*function)(argc, argv);
4272 jit_destroy_state();
4278 xmalloc(size_t size)
4280 void *pointer = malloc(size);
4282 if (pointer == NULL)
4283 error("out of memory");
4289 xrealloc(void *pointer, size_t size)
4291 pointer = realloc(pointer, size);
4293 if (pointer == NULL)
4294 error("out of memory");
4300 xcalloc(size_t nmemb, size_t size)
4302 void *pointer = calloc(nmemb, size);
4304 if (pointer == NULL)
4305 error("out of memory");
4311 new_label(label_kind_t kind, char *name, void *value)
4315 label = (label_t *)xmalloc(sizeof(label_t));
4317 label->name = strdup(name);
4318 label->value = value;
4319 put_hash(labels, (entry_t *)label);
4325 new_patch(patch_kind_t kind, label_t *label, void *value)
4327 patch_t *patch = (patch_t *)xmalloc(sizeof(patch_t));
4329 patch->label = label;
4330 patch->value = value;
4331 patch->next = patches;
4338 bcmp_symbols(const void *left, const void *right)
4340 return (strcmp((char *)left, (*(symbol_t **)right)->name));
4344 qcmp_symbols(const void *left, const void *right)
4346 return (strcmp((*(symbol_t **)left)->name, (*(symbol_t **)right)->name));
4350 new_symbol(char *name)
4354 if ((symbol_offset & 15) == 0) {
4355 if ((symbol_length += 16) == 16)
4356 symbols = (symbol_t **)xmalloc(sizeof(symbol_t *) *
4359 symbols = (symbol_t **)xrealloc(symbols, sizeof(symbol_t *) *
4362 symbol = (symbol_t *)xmalloc(sizeof(symbol_t));
4363 symbol->name = strdup(name);
4364 symbols[symbol_offset++] = symbol;
4365 qsort(symbols, symbol_offset, sizeof(symbol_t *), qcmp_symbols);
4371 get_symbol_by_name(char *name)
4373 symbol_t **symbol_pointer;
4375 if (symbols == NULL)
4377 symbol_pointer = (symbol_t **)bsearch(name, symbols, symbol_offset,
4378 sizeof(symbol_t *), bcmp_symbols);
4380 return (symbol_pointer ? *symbol_pointer : NULL);
4388 hash = (hash_t *)xmalloc(sizeof(hash_t));
4390 hash->entries = (entry_t **)xcalloc(hash->size = 32, sizeof(void *));
4396 hash_string(char *name)
4401 for (key = 0, ptr = name; *ptr; ptr++)
4402 key = (key << (key & 1)) ^ *ptr;
4408 put_hash(hash_t *hash, entry_t *entry)
4410 entry_t *prev, *ptr;
4411 int key = hash_string(entry->name) & (hash->size - 1);
4413 for (prev = ptr = hash->entries[key]; ptr; prev = ptr, ptr = ptr->next) {
4414 if (strcmp(entry->name, ptr->name) == 0)
4415 error("duplicated entry %s", entry->name);
4418 hash->entries[key] = entry;
4423 if (hash->count > hash->size * 0.75)
4428 get_hash(hash_t *hash, char *name)
4431 int key = hash_string(name) & (hash->size - 1);
4433 for (entry = hash->entries[key]; entry; entry = entry->next) {
4434 if (strcmp(entry->name, name) == 0)
4441 rehash(hash_t *hash)
4444 entry_t *entry, *next, **entries;
4446 entries = (entry_t **)xcalloc(size = hash->size * 2, sizeof(void *));
4447 for (i = 0; i < hash->size; i++) {
4448 for (entry = hash->entries[i]; entry; entry = next) {
4450 key = hash_string(entry->name) & (size - 1);
4451 entry->next = entries[key];
4452 entries[key] = entry;
4455 free(hash->entries);
4456 hash->entries = entries;
4463 #if HAVE_GETOPT_LONG_ONLY
4465 Usage: %s [jit assembler options] file [--] [jit program options]\n\
4466 Jit assembler options:\n\
4467 -help Display this information\n\
4468 -v[0-3] Verbose output level\n\
4469 -d Do not use a data buffer\n"
4470 # if defined(__i386__) && __WORDSIZE == 32
4471 " -mx87=1 Force using x87 when sse2 available\n"
4473 # if defined(__i386__) || defined(__x86_64__)
4474 " -msse4_1=0 Do not use sse4_1 instructions when available\n"
4476 # if defined(__arm__)
4477 " -mcpu=<val> Force cpu version (4, 5, 6 or 7)\n\
4478 -mthumb[=0|1] Enable or disable thumb\n\
4479 -mvfp=<val> Set vpf version (0 to disable)\n\
4480 -mneon[=0|1] Enable or disable neon\n"
4485 Usage: %s [jit assembler options] file [--] [jit program options]\n\
4486 Jit assembler options:\n\
4487 -h Display this information\n\
4488 -v Verbose output level\n", progname);
4495 main(int argc, char *argv[])
4497 #if HAVE_GETOPT_LONG_ONLY
4498 static const char *short_options = "dv::";
4499 static struct option long_options[] = {
4500 { "help", 0, 0, 'h' },
4501 { "data", 2, 0, 'd' },
4502 # if defined(__i386__) && __WORDSIZE == 32
4503 { "mx87", 2, 0, '7' },
4505 # if defined(__i386__) || defined(__x86_64__)
4506 { "msse4_1", 2, 0, '4' },
4508 # if defined(__arm__)
4509 { "mcpu", 2, 0, 'c' },
4510 { "mthumb", 2, 0, 't' },
4511 { "mvfp", 2, 0, 'f' },
4512 { "mneon", 2, 0, 'n' },
4517 #endif /* HAVE_GETOPT_LONG_ONLY */
4524 #if defined(__CYGWIN__)
4525 /* Cause a compile warning about redefinition without dllimport
4526 * attribute, *but* cause correct linkage if liblightning.a is
4527 * linked to binutils (that happens to have an internal
4528 * getopt* implementation and an apparently conflicting
4529 * optind global variable) */
4539 DL_HANDLE = dlopen(NULL, RTLD_LAZY);
4543 #if HAVE_GETOPT_LONG_ONLY
4545 if ((opt_short = getopt_long_only(argc, argv, short_options,
4546 long_options, &opt_index)) < 0)
4548 switch (opt_short) {
4555 flag_verbose = strtol(optarg, &endptr, 10);
4556 if (*endptr || flag_verbose < 0)
4565 #if defined(__i386__) && __WORDSIZE == 32
4568 if (strcmp(optarg, "") == 0 || strcmp(optarg, "1") == 0)
4570 else if (strcmp(optarg, "0"))
4577 #if defined(__i386__) || defined(__x86_64__)
4580 if (strcmp(optarg, "0") == 0)
4582 else if (strcmp(optarg, "1"))
4587 #if defined(__arm__)
4590 offset = strtol(optarg, &endptr, 10);
4591 if (*endptr || offset < 0)
4593 if (offset < jit_cpu.version)
4594 jit_cpu.version = offset;
4599 if (strcmp(optarg, "0") == 0)
4601 else if (strcmp(optarg, "1") && strcmp(optarg, "2"))
4606 # if !defined(__ARM_PCS_VFP)
4607 /* Do not allow overrinding hard float abi */
4609 offset = strtol(optarg, &endptr, 10);
4610 if (*endptr || offset < 0)
4612 if (offset < jit_cpu.vfp)
4613 jit_cpu.vfp = offset;
4619 if (strcmp(optarg, "0") == 0)
4621 else if (strcmp(optarg, "1"))
4629 while ((opt_short = getopt(argc, argv, "hvd")) >= 0) {
4630 if (opt_short == 'v')
4632 else if (opt_short == 'd')
4642 if (opt_index < argc && argv[opt_index][0] == '-')
4645 if (opt_index < 0 || opt_index >= argc)
4647 if (strcmp(argv[opt_index], "-") == 0)
4648 strcpy(parser.name, "<stdin>");
4650 if ((endptr = strrchr(argv[opt_index], '/')) == NULL)
4651 endptr = argv[opt_index];
4654 strncpy(parser.name, endptr, sizeof(parser.name));
4655 parser.name[sizeof(parser.name) - 1] = '\0';
4662 opt_short = snprintf(cmdline, sizeof(cmdline), cc " -E -x c %s", argv[opt_index]);
4663 opt_short += snprintf(cmdline + opt_short,
4664 sizeof(cmdline) - opt_short,
4665 " -D__WORDSIZE=%d", __WORDSIZE);
4666 opt_short += snprintf(cmdline + opt_short,
4667 sizeof(cmdline) - opt_short,
4668 " -D__LITTLE_ENDIAN=%d", __LITTLE_ENDIAN);
4669 opt_short += snprintf(cmdline + opt_short,
4670 sizeof(cmdline) - opt_short,
4671 " -D__BIG_ENDIAN=%d", __BIG_ENDIAN);
4672 opt_short += snprintf(cmdline + opt_short,
4673 sizeof(cmdline) - opt_short,
4674 " -D__BYTE_ORDER=%d", __BYTE_ORDER);
4675 #if defined(__i386__)
4676 opt_short += snprintf(cmdline + opt_short,
4677 sizeof(cmdline) - opt_short,
4680 #if defined(__x86_64__)
4681 opt_short += snprintf(cmdline + opt_short,
4682 sizeof(cmdline) - opt_short,
4685 #if defined(__mips__)
4686 opt_short += snprintf(cmdline + opt_short,
4687 sizeof(cmdline) - opt_short,
4689 opt_short += snprintf(cmdline + opt_short,
4690 sizeof(cmdline) - opt_short,
4691 " -D__mips_isa_rev=%d", jit_cpu.release);
4693 #if defined(__arm__)
4694 opt_short += snprintf(cmdline + opt_short,
4695 sizeof(cmdline) - opt_short,
4698 #if defined(__powerpc__)
4699 opt_short += snprintf(cmdline + opt_short,
4700 sizeof(cmdline) - opt_short,
4703 #if defined(__sparc__)
4704 opt_short += snprintf(cmdline + opt_short,
4705 sizeof(cmdline) - opt_short,
4708 #if defined(__ia64__)
4709 opt_short += snprintf(cmdline + opt_short,
4710 sizeof(cmdline) - opt_short,
4713 #if defined(__hppa__)
4714 opt_short += snprintf(cmdline + opt_short,
4715 sizeof(cmdline) - opt_short,
4719 opt_short += snprintf(cmdline + opt_short,
4720 sizeof(cmdline) - opt_short,
4723 #if defined(__sgi__)
4724 opt_short += snprintf(cmdline + opt_short,
4725 sizeof(cmdline) - opt_short,
4728 #if defined(__aarch64__)
4729 opt_short += snprintf(cmdline + opt_short,
4730 sizeof(cmdline) - opt_short,
4731 " -D__aarch64__=1");
4733 #if defined(__s390__) || defined(__s390x__)
4734 opt_short += snprintf(cmdline + opt_short,
4735 sizeof(cmdline) - opt_short,
4738 #if defined(__alpha__)
4739 opt_short += snprintf(cmdline + opt_short,
4740 sizeof(cmdline) - opt_short,
4743 #if defined(__loongarch__)
4744 opt_short += snprintf(cmdline + opt_short,
4745 sizeof(cmdline) - opt_short,
4746 " -D__loongarch__=1");
4748 if ((parser.fp = popen(cmdline, "r")) == NULL)
4749 error("cannot execute %s", cmdline);
4752 parser.string = (char *)xmalloc(parser.length = 4096);
4754 #if defined(__linux__) && (defined(__i386__) || defined(__x86_64__))
4755 /* double precision 0x200
4756 * round nearest 0x000
4757 * invalid operation mask 0x001
4758 * denormalized operand mask 0x002
4759 * zero divide mask 0x004
4760 * precision (inexact) mask 0x020
4763 fpu_control_t fpu_control = 0x027f;
4764 _FPU_SETCW(fpu_control);
4768 _jit = jit_new_state();
4770 instrs = new_hash();
4772 offset < (int)(sizeof(instr_vector) / sizeof(instr_vector[0]));
4774 put_hash(instrs, (entry_t *)(instr_vector + offset));
4776 labels = new_hash();
4782 for (opt_short = 0; opt_index < argc; opt_short++, opt_index++)
4783 argv[opt_short] = argv[opt_index];
4784 argv[opt_short] = NULL;
4786 execute(argc, argv);