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 unldr_f(void); static void unldi_f(void);
513 static void bltr_f(void); static void blti_f(void);
514 static void bler_f(void); static void blei_f(void);
515 static void beqr_f(void); static void beqi_f(void);
516 static void bger_f(void); static void bgei_f(void);
517 static void bgtr_f(void); static void bgti_f(void);
518 static void bner_f(void); static void bnei_f(void);
519 static void bunltr_f(void); static void bunlti_f(void);
520 static void bunler_f(void); static void bunlei_f(void);
521 static void buneqr_f(void); static void buneqi_f(void);
522 static void bunger_f(void); static void bungei_f(void);
523 static void bungtr_f(void); static void bungti_f(void);
524 static void bltgtr_f(void); static void bltgti_f(void);
525 static void bordr_f(void); static void bordi_f(void);
526 static void bunordr_f(void); static void bunordi_f(void);
527 static void pushargr_f(void); static void pushargi_f(void);
528 static void retr_f(void); static void reti_f(void);
529 static void retval_f(void);
530 static void arg_d(void); static void getarg_d(void);
531 static void putargr_d(void); static void putargi_d(void);
532 static void addr_d(void); static void addi_d(void);
533 static void subr_d(void); static void subi_d(void);
534 static void rsbr_d(void); static void rsbi_d(void);
535 static void mulr_d(void); static void muli_d(void);
536 static void divr_d(void); static void divi_d(void);
537 static void negr_d(void); static void negi_d(void);
538 static void absr_d(void); static void absi_d(void);
539 static void sqrtr_d(void); static void sqrti_d(void);
540 static void fmar_d(void); static void fmai_d(void);
541 static void fmsr_d(void); static void fmsi_d(void);
542 static void fnmar_d(void); static void fnmai_d(void);
543 static void fnmsr_d(void); static void fnmsi_d(void);
544 static void ltr_d(void); static void lti_d(void);
545 static void ler_d(void); static void lei_d(void);
546 static void eqr_d(void); static void eqi_d(void);
547 static void ger_d(void); static void gei_d(void);
548 static void gtr_d(void); static void gti_d(void);
549 static void ner_d(void); static void nei_d(void);
550 static void unltr_d(void); static void unlti_d(void);
551 static void unler_d(void); static void unlei_d(void);
552 static void uneqr_d(void); static void uneqi_d(void);
553 static void unger_d(void); static void ungei_d(void);
554 static void ungtr_d(void); static void ungti_d(void);
555 static void ltgtr_d(void); static void ltgti_d(void);
556 static void ordr_d(void); static void ordi_d(void);
557 static void unordr_d(void); static void unordi_d(void);
558 static void truncr_d_i(void);
560 static void truncr_d_l(void);
562 static void truncr_d(void);
563 static void extr_d(void); static void extr_f_d(void);
564 static void movr_d(void); static void movi_d(void);
566 static void movr_ww_d(void); static void movr_d_ww(void);
567 static void movi_d_ww(void); static void movi_ww_d(void);
569 static void movr_w_d(void); static void movr_d_w(void);
570 static void movi_d_w(void); static void movi_w_d(void);
572 static void ldr_d(void); static void ldi_d(void);
573 static void ldxr_d(void); static void ldxi_d(void);
574 static void str_d(void); static void sti_d(void);
575 static void stxr_d(void); static void stxi_d(void);
576 static void bltr_d(void); static void blti_d(void);
577 static void bler_d(void); static void blei_d(void);
578 static void beqr_d(void); static void beqi_d(void);
579 static void bger_d(void); static void bgei_d(void);
580 static void bgtr_d(void); static void bgti_d(void);
581 static void bner_d(void); static void bnei_d(void);
582 static void bunltr_d(void); static void bunlti_d(void);
583 static void bunler_d(void); static void bunlei_d(void);
584 static void buneqr_d(void); static void buneqi_d(void);
585 static void bunger_d(void); static void bungei_d(void);
586 static void bungtr_d(void); static void bungti_d(void);
587 static void bltgtr_d(void); static void bltgti_d(void);
588 static void bordr_d(void); static void bordi_d(void);
589 static void bunordr_d(void); static void bunordi_d(void);
590 static void pushargr_d(void); static void pushargi_d(void);
591 static void retr_d(void); static void reti_d(void);
592 static void retval_d(void);
593 static void vastart(void); static void vapush(void);
594 static void vaarg(void); static void vaarg_d(void);
595 static void vaend(void);
597 static void error(const char *format, ...) noreturn printf_format(1, 2);
598 static void warn(const char *format, ...) printf_format(1, 2) maybe_unused;
599 static void message(const char *kind, const char *format, va_list ap);
601 static int getch(void);
602 static int getch_noeof(void);
603 static int ungetch(int ch);
604 static int skipws(void);
605 static int skipnl(void);
606 static int skipct(void);
607 static int skipcp(void);
608 static jit_word_t get_int(skip_t skip);
609 static jit_uword_t get_uint(skip_t skip);
610 static double get_float(skip_t skip);
611 static float make_float(double d);
612 static void *get_pointer(skip_t skip);
613 static label_t *get_label(skip_t skip);
614 static token_t regname(void);
615 static token_t identifier(int ch);
616 static void get_data(type_t type);
617 static void dot(void);
618 static token_t number(int ch);
619 static int escape(int ch);
620 static token_t string(void);
621 static token_t dynamic(void);
622 static token_t character(void);
623 static void expression_prim(void);
624 static void expression_inc(int pre);
625 static void expression_dec(int pre);
626 static void expression_unary(void);
627 static void expression_mul(void);
628 static void expression_add(void);
629 static void expression_shift(void);
630 static void expression_bit(void);
631 static void expression_rel(void);
632 static void expression_cond(void);
633 static token_t expression(void);
634 static token_t primary(skip_t skip);
635 static void parse(void);
636 static int execute(int argc, char *argv[]);
638 static void *xmalloc(size_t size);
639 static void *xrealloc(void *pointer, size_t size);
640 static void *xcalloc(size_t nmemb, size_t size);
642 static label_t *new_label(label_kind_t kind, char *name, void *value);
643 static patch_t *new_patch(patch_kind_t kind, label_t *label, void *value);
644 static int bcmp_symbols(const void *left, const void *right);
645 static int qcmp_symbols(const void *left, const void *right);
646 static symbol_t *new_symbol(char *name);
647 static symbol_t *get_symbol_by_name(char *name);
649 static hash_t *new_hash(void);
650 static int hash_string(char *name);
651 static void put_hash(hash_t *hash, entry_t *entry);
652 static entry_t *get_hash(hash_t *hash, char *name);
653 static void rehash(hash_t *hash);
658 static jit_state_t *_jit;
659 static int flag_verbose;
660 static int flag_data;
661 static int flag_disasm;
662 static char *progname;
663 static parser_t parser;
664 static hash_t *labels;
665 static int label_offset;
666 static patch_t *patches;
667 static symbol_t **symbols;
668 static int symbol_length;
669 static int symbol_offset;
670 static hash_t *instrs;
672 static size_t data_offset, data_length;
673 static instr_t instr_vector[] = {
674 #define entry(value) { NULL, #value, value }
675 #define entry2(name, function) { NULL, name, function }
677 entry(align), entry(name),
680 entry(frame), entry(tramp),
682 entry(allocai), entry(allocar),
683 entry(arg_c), entry(arg_s),
689 entry(getarg_c), entry(getarg_uc),
690 entry(getarg_s), entry(getarg_us),
693 entry(getarg_ui), entry(getarg_l),
696 entry(putargr_c), entry(putargi_c),
697 entry(putargr_uc), entry(putargi_uc),
698 entry(putargr_s), entry(putargi_s),
699 entry(putargr_us), entry(putargi_us),
700 entry(putargr_i), entry(putargi_i),
702 entry(putargr_ui), entry(putargi_ui),
703 entry(putargr_l), entry(putargi_l),
705 entry(putargr), entry(putargi),
706 entry(addr), entry(addi),
707 entry(addxr), entry(addxi),
708 entry(addcr), entry(addci),
709 entry(subr), entry(subi),
710 entry(subxr), entry(subxi),
711 entry(subcr), entry(subci),
712 entry(rsbr), entry(rsbi),
713 entry(mulr), entry(muli),
714 entry(hmulr), entry(hmuli),
715 entry(hmulr_u), entry(hmuli_u),
716 entry(qmulr), entry(qmuli),
717 entry(qmulr_u), entry(qmuli_u),
718 entry(divr), entry(divi),
719 entry(divr_u), entry(divi_u),
720 entry(qdivr), entry(qdivi),
721 entry(qdivr_u), entry(qdivi_u),
722 entry(remr), entry(remi),
723 entry(remr_u), entry(remi_u),
724 entry(andr), entry(andi),
725 entry(orr), entry(ori),
726 entry(xorr), entry(xori),
727 entry(lshr), entry(lshi),
728 entry(qlshr), entry(qlshi),
729 entry(qlshr_u), entry(qlshi_u),
730 entry(rshr), entry(rshi),
731 entry(qrshr), entry(qrshi),
732 entry(rshr_u), entry(rshi_u),
733 entry(qrshr_u), entry(qrshi_u),
734 entry(lrotr), entry(lroti),
735 entry(rrotr), entry(rroti),
736 entry(negr), entry(negi),
737 entry(comr), entry(comi),
738 entry(clor), entry(cloi),
739 entry(clzr), entry(clzi),
740 entry(ctor), entry(ctoi),
741 entry(ctzr), entry(ctzi),
742 entry(rbitr), entry(rbiti),
743 entry(popcntr), entry(popcnti),
744 entry(ltr), entry(lti),
745 entry(ltr_u), entry(lti_u),
746 entry(ler), entry(lei),
747 entry(ler_u), entry(lei_u),
748 entry(eqr), entry(eqi),
749 entry(ger), entry(gei),
750 entry(ger_u), entry(gei_u),
751 entry(gtr), entry(gti),
752 entry(gtr_u), entry(gti_u),
753 entry(ner), entry(nei),
754 entry(casr), entry(casi),
755 entry(movr), entry(movi),
756 entry(extr), entry(exti),
757 entry(extr_u), entry(exti_u),
758 entry(depr), entry(depi),
759 entry(extr_c), entry(exti_c),
760 entry(extr_uc), entry(exti_uc),
761 entry(extr_s), entry(exti_s),
762 entry(extr_us), entry(exti_us),
764 entry(extr_i), entry(exti_i),
765 entry(extr_ui), entry(exti_ui),
767 entry(htonr_us), entry(htoni_us),
768 entry(ntohr_us), entry(ntohi_us),
769 entry(htonr_ui), entry(htoni_ui),
770 entry(ntohr_ui), entry(ntohi_ui),
772 entry(htonr_ul), entry(htoni_ul),
773 entry(ntohr_ul), entry(ntohi_ul),
775 entry(htonr), entry(htoni),
776 entry(ntohr), entry(ntohi),
777 entry(bswapr_us), entry(bswapi_us),
778 entry(bswapr_ui), entry(bswapi_ui),
780 entry(bswapr_ul), entry(bswapi_ul),
782 entry(bswapr), entry(bswapi),
783 entry(movnr), entry(movzr),
784 entry(ldr_c), entry(ldi_c),
785 entry(ldr_uc), entry(ldi_uc),
786 entry(ldr_s), entry(ldi_s),
787 entry(ldr_us), entry(ldi_us),
788 entry(ldr_i), entry(ldi_i),
790 entry(ldr_ui), entry(ldi_ui),
791 entry(ldr_l), entry(ldi_l),
793 entry(ldr), entry(ldi),
794 entry(ldxr_c), entry(ldxi_c),
795 entry(ldxr_uc), entry(ldxi_uc),
796 entry(ldxr_s), entry(ldxi_s),
797 entry(ldxr_us), entry(ldxi_us),
798 entry(ldxr_i), entry(ldxi_i),
800 entry(ldxr_ui), entry(ldxi_ui),
801 entry(ldxr_l), entry(ldxi_l),
803 entry(ldxr), entry(ldxi),
804 entry(unldr), entry(unldi),
805 entry(unldr_u), entry(unldi_u),
806 entry(str_c), entry(sti_c),
807 entry(str_s), entry(sti_s),
808 entry(str_i), entry(sti_i),
810 entry(str_l), entry(sti_l),
812 entry(str), entry(sti),
813 entry(stxr_c), entry(stxi_c),
814 entry(stxr_s), entry(stxi_s),
815 entry(stxr_i), entry(stxi_i),
817 entry(stxr_l), entry(stxi_l),
819 entry(stxr), entry(stxi),
820 entry(unstr), entry(unsti),
821 entry(bltr), entry(blti),
822 entry(bltr_u), entry(blti_u),
823 entry(bler), entry(blei),
824 entry(bler_u), entry(blei_u),
825 entry(beqr), entry(beqi),
826 entry(bger), entry(bgei),
827 entry(bger_u), entry(bgei_u),
828 entry(bgtr), entry(bgti),
829 entry(bgtr_u), entry(bgti_u),
830 entry(bner), entry(bnei),
831 entry(bmsr), entry(bmsi),
832 entry(bmcr), entry(bmci),
833 entry(boaddr), entry(boaddi),
834 entry(boaddr_u), entry(boaddi_u),
835 entry(bxaddr), entry(bxaddi),
836 entry(bxaddr_u), entry(bxaddi_u),
837 entry(bosubr), entry(bosubi),
838 entry(bosubr_u), entry(bosubi_u),
839 entry(bxsubr), entry(bxsubi),
840 entry(bxsubr_u), entry(bxsubi_u),
841 entry(jmpr), entry(jmpi),
842 entry(callr), entry(calli),
844 entry(pushargr_c), entry(pushargi_c),
845 entry(pushargr_uc), entry(pushargi_uc),
846 entry(pushargr_s), entry(pushargi_s),
847 entry(pushargr_us), entry(pushargi_us),
848 entry(pushargr_i), entry(pushargi_i),
850 entry(pushargr_ui), entry(pushargi_ui),
851 entry(pushargr_l), entry(pushargi_l),
853 entry(pushargr), entry(pushargi),
854 entry(finishr), entry(finishi),
856 entry(retr_c), entry(reti_c),
857 entry(retr_uc), entry(reti_uc),
858 entry(retr_s), entry(reti_s),
859 entry(retr_us), entry(reti_us),
860 entry(retr_i), entry(reti_i),
862 entry(retr_ui), entry(reti_ui),
863 entry(retr_l), entry(reti_l),
865 entry(retr), entry(reti),
866 entry(retval_c), entry(retval_uc),
867 entry(retval_s), entry(retval_us),
870 entry(retval_ui), entry(retval_l),
874 entry(arg_f), entry(getarg_f),
875 entry(putargr_f), entry(putargi_f),
876 entry(addr_f), entry(addi_f),
877 entry(subr_f), entry(subi_f),
878 entry(rsbr_f), entry(rsbi_f),
879 entry(mulr_f), entry(muli_f),
880 entry(divr_f), entry(divi_f),
881 entry(negr_f), entry(negi_f),
882 entry(absr_f), entry(absi_f),
883 entry(sqrtr_f), entry(sqrti_f),
884 entry(fmar_f), entry(fmai_f),
885 entry(fmsr_f), entry(fmsi_f),
886 entry(fnmar_f), entry(fnmai_f),
887 entry(fnmsr_f), entry(fnmsi_f),
888 entry(ltr_f), entry(lti_f),
889 entry(ler_f), entry(lei_f),
890 entry(eqr_f), entry(eqi_f),
891 entry(ger_f), entry(gei_f),
892 entry(gtr_f), entry(gti_f),
893 entry(ner_f), entry(nei_f),
894 entry(unltr_f), entry(unlti_f),
895 entry(unler_f), entry(unlei_f),
896 entry(uneqr_f), entry(uneqi_f),
897 entry(unger_f), entry(ungei_f),
898 entry(ungtr_f), entry(ungti_f),
899 entry(ltgtr_f), entry(ltgti_f),
900 entry(ordr_f), entry(ordi_f),
901 entry(unordr_f), entry(unordi_f),
907 entry(extr_f), entry(extr_d_f),
908 entry(movr_f), entry(movi_f),
909 entry(movr_w_f), entry(movr_f_w),
910 entry(movi_f_w), entry(movi_w_f),
911 entry(ldr_f), entry(ldi_f),
912 entry(ldxr_f), entry(ldxi_f),
913 entry(unldr_x), entry(unldi_x),
914 entry(str_f), entry(sti_f),
915 entry(stxr_f), entry(stxi_f),
916 entry(unstr_x), entry(unsti_x),
917 entry(bltr_f), entry(blti_f),
918 entry(bler_f), entry(blei_f),
919 entry(beqr_f), entry(beqi_f),
920 entry(bger_f), entry(bgei_f),
921 entry(bgtr_f), entry(bgti_f),
922 entry(bner_f), entry(bnei_f),
923 entry(bunltr_f), entry(bunlti_f),
924 entry(bunler_f), entry(bunlei_f),
925 entry(buneqr_f), entry(buneqi_f),
926 entry(bunger_f), entry(bungei_f),
927 entry(bungtr_f), entry(bungti_f),
928 entry(bltgtr_f), entry(bltgti_f),
929 entry(bordr_f), entry(bordi_f),
930 entry(bunordr_f), entry(bunordi_f),
931 entry(pushargr_f), entry(pushargi_f),
932 entry(retr_f), entry(reti_f),
934 entry(arg_d), entry(getarg_d),
935 entry(putargr_d), entry(putargi_d),
936 entry(addr_d), entry(addi_d),
937 entry(subr_d), entry(subi_d),
938 entry(rsbr_d), entry(rsbi_d),
939 entry(mulr_d), entry(muli_d),
940 entry(divr_d), entry(divi_d),
941 entry(negr_d), entry(negi_d),
942 entry(absr_d), entry(absi_d),
943 entry(sqrtr_d), entry(sqrti_d),
944 entry(fmar_d), entry(fmai_d),
945 entry(fmsr_d), entry(fmsi_d),
946 entry(fnmar_d), entry(fnmai_d),
947 entry(fnmsr_d), entry(fnmsi_d),
948 entry(ltr_d), entry(lti_d),
949 entry(ler_d), entry(lei_d),
950 entry(eqr_d), entry(eqi_d),
951 entry(ger_d), entry(gei_d),
952 entry(gtr_d), entry(gti_d),
953 entry(ner_d), entry(nei_d),
954 entry(unltr_d), entry(unlti_d),
955 entry(unler_d), entry(unlei_d),
956 entry(uneqr_d), entry(uneqi_d),
957 entry(unger_d), entry(ungei_d),
958 entry(ungtr_d), entry(ungti_d),
959 entry(ltgtr_d), entry(ltgti_d),
960 entry(ordr_d), entry(ordi_d),
961 entry(unordr_d), entry(unordi_d),
967 entry(extr_d), entry(extr_f_d),
968 entry(movr_d), entry(movi_d),
970 entry(movr_ww_d), entry(movr_d_ww),
971 entry(movi_d_ww), entry(movi_ww_d),
973 entry(movr_w_d), entry(movr_d_w),
974 entry(movi_d_w), entry(movi_w_d),
976 entry(ldr_d), entry(ldi_d),
977 entry(ldxr_d), entry(ldxi_d),
978 entry(str_d), entry(sti_d),
979 entry(stxr_d), entry(stxi_d),
980 entry(bltr_d), entry(blti_d),
981 entry(bler_d), entry(blei_d),
982 entry(beqr_d), entry(beqi_d),
983 entry(bger_d), entry(bgei_d),
984 entry(bgtr_d), entry(bgti_d),
985 entry(bner_d), entry(bnei_d),
986 entry(bunltr_d), entry(bunlti_d),
987 entry(bunler_d), entry(bunlei_d),
988 entry(buneqr_d), entry(buneqi_d),
989 entry(bunger_d), entry(bungei_d),
990 entry(bungtr_d), entry(bungti_d),
991 entry(bltgtr_d), entry(bltgti_d),
992 entry(bordr_d), entry(bordi_d),
993 entry(bunordr_d), entry(bunordi_d),
994 entry(pushargr_d), entry(pushargi_d),
995 entry(retr_d), entry(reti_d),
997 entry2("va_start", vastart),
998 entry2("va_push", vapush),
999 entry2("va_arg", vaarg),
1000 entry2("va_arg_d", vaarg_d),
1001 entry2("va_end", vaend),
1011 if (primary(skip_ws) != tok_register)
1012 error("bad register");
1013 if (parser.regtype != type_l)
1014 error("bad int register");
1016 return ((jit_gpr_t)parser.regval);
1022 if (primary(skip_ws) != tok_register)
1023 error("bad register");
1024 if (parser.regtype != type_d)
1025 error("bad float register");
1027 return ((jit_fpr_t)parser.regval);
1037 error("expecting variable");
1038 (void)identifier('$');
1039 if (parser.string[1] == '\0')
1040 error("expecting variable");
1041 if ((symbol = get_symbol_by_name(parser.string)) == NULL)
1042 symbol = new_symbol(parser.string);
1048 jmp_forward(void *value, label_t *label)
1050 (void)new_patch(patch_kind_jmp, label, value);
1054 mov_forward(void *value, label_t *label)
1056 (void)new_patch(patch_kind_mov, label, value);
1060 call_forward(void *value, label_t *label)
1062 (void)new_patch(patch_kind_call, label, value);
1066 make_arg(void *value)
1068 symbol_t *symbol = get_symbol();
1070 symbol->type = type_p;
1071 symbol->value.p = value;
1074 static jit_pointer_t
1077 symbol_t *symbol = get_symbol();
1079 if (symbol->type != type_p)
1080 error("bad argument %s type", symbol->name);
1082 return symbol->value.p;
1093 case '+': case '-': case '0' ... '9':
1095 value = get_int(skip_none);
1099 value = parser.value.i;
1102 switch (expression()) {
1105 value = parser.value.i;
1108 error("expecting immediate");
1113 value = (jit_word_t)parser.value.p;
1117 label = get_label(skip_none);
1118 if (label->kind == label_kind_data)
1119 value = (jit_word_t)label->value;
1121 error("expecting immediate");
1127 #define entry(name) \
1133 #define entry_ca(name) \
1137 make_arg(jit_##name()); \
1139 #define entry_ia(name) \
1143 jit_gpr_t r0 = get_ireg(); \
1144 jit_pointer_t ac = get_arg(); \
1145 jit_##name(r0, ac); \
1147 #define entry_im(name) \
1151 jit_word_t im = get_imm(); \
1154 #define entry_ir(name) \
1158 jit_gpr_t r0 = get_ireg(); \
1161 #define entry_ima(name) \
1165 jit_word_t im = get_imm(); \
1166 jit_pointer_t ac = get_arg(); \
1167 jit_##name(im, ac); \
1169 #define entry_ir_ir_ir(name) \
1173 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(), r2 = get_ireg(); \
1174 jit_##name(r0, r1, r2); \
1176 #define entry_ir_ir_im(name) \
1180 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \
1181 jit_word_t im = get_imm(); \
1182 jit_##name(r0, r1, im); \
1184 #define entry_ir_im_im(name) \
1188 jit_gpr_t r0 = get_ireg(); \
1189 jit_word_t i0 = get_imm(), i1 = get_imm(); \
1190 jit_##name(r0, i0, i1); \
1192 #define entry_ir_fr_im(name) \
1196 jit_gpr_t r0 = get_ireg(); \
1197 jit_fpr_t r1 = get_freg(); \
1198 jit_word_t im = get_imm(); \
1199 jit_##name(r0, r1, im); \
1201 #define entry_im_fr_im(name) \
1205 jit_word_t i0 = get_imm(); \
1206 jit_fpr_t r0 = get_freg(); \
1207 jit_word_t i1 = get_imm(); \
1208 jit_##name(i0, r0, i1); \
1210 #define entry_im_ir_im(name) \
1214 jit_word_t i0 = get_imm(); \
1215 jit_gpr_t r0 = get_ireg(); \
1216 jit_word_t i1 = get_imm(); \
1217 jit_##name(i0, r0, i1); \
1219 #define entry_ir_ir_ir_ir(name) \
1223 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(), \
1224 r2 = get_ireg(), r3 = get_ireg(); \
1225 jit_##name(r0, r1, r2, r3); \
1227 #define entry_ir_ir_ir_im(name) \
1231 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(), r2 = get_ireg(); \
1232 jit_word_t im = get_imm(); \
1233 jit_##name(r0, r1, r2, im); \
1235 #define entry_ir_im_ir_ir(name) \
1239 jit_gpr_t r0 = get_ireg(); \
1240 jit_word_t im = get_imm(); \
1241 jit_gpr_t r1 = get_ireg(), r2 = get_ireg(); \
1242 jit_##name(r0, im, r1, r2); \
1244 #define entry_ir_ir_im_im(name) \
1247 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \
1248 jit_word_t i0 = get_imm(), i1 = get_imm(); \
1249 jit_##name(r0, r1, i0, i1); \
1251 #define entry_ir_im_im_im(name) \
1254 jit_gpr_t r0 = get_ireg(); \
1255 jit_word_t i0 = get_imm(), i1 = get_imm(), i2 = get_imm(); \
1256 jit_##name(r0, i0, i1, i2); \
1258 #define entry_ir_ir(name) \
1262 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \
1263 jit_##name(r0, r1); \
1265 #define entry_ir_im(name) \
1269 jit_gpr_t r0 = get_ireg(); \
1270 jit_word_t im = get_imm(); \
1271 jit_##name(r0, im); \
1273 #define entry_ir_pm(name) \
1277 jit_gpr_t r0 = get_ireg(); \
1278 void *pm = get_pointer(skip_ws); \
1279 jit_##name(r0, pm); \
1281 #define entry_pm_ir(name) \
1285 void *pm = get_pointer(skip_ws); \
1286 jit_gpr_t r0 = get_ireg(); \
1287 jit_##name(pm, r0); \
1289 #define entry_im_ir_ir(name) \
1293 jit_word_t im = get_imm(); \
1294 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \
1295 (void)jit_##name(im, r0, r1); \
1297 #define entry_lb_ir_ir(name) \
1302 label_t *label = get_label(skip_ws); \
1303 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \
1304 if (label->kind == label_kind_code_forward) \
1305 jmp_forward((void *)jit_##name(r0, r1), label); \
1307 jmp = jit_##name(r0, r1); \
1308 jit_patch_at(jmp, (jit_node_t *)label->value); \
1311 #define entry_lb_ir_im(name) \
1316 label_t *label = get_label(skip_ws); \
1317 jit_gpr_t r0 = get_ireg(); \
1318 jit_word_t im = get_imm(); \
1319 if (label->kind == label_kind_code_forward) \
1320 jmp_forward((void *)jit_##name(r0, im), label); \
1322 jmp = jit_##name(r0, im); \
1323 jit_patch_at(jmp, (jit_node_t *)label->value); \
1326 #define entry_lb(name) \
1331 label_t *label = get_label(skip_ws); \
1332 if (label->kind == label_kind_code_forward) \
1333 jmp_forward((void *)jit_##name(), label); \
1335 jmp = jit_##name(); \
1336 jit_patch_at(jmp, (jit_node_t *)label->value); \
1339 #define entry_pm(name) \
1343 void *pm = get_pointer(skip_ws); \
1346 #define entry_fa(name) \
1350 jit_fpr_t r0 = get_freg(); \
1351 jit_pointer_t ac = get_arg(); \
1352 jit_##name(r0, ac); \
1354 #define entry_fma(name) \
1358 jit_float64_t im = get_float(skip_ws); \
1359 jit_pointer_t ac = get_arg(); \
1360 jit_##name(im, ac); \
1362 #define entry_fr_fr_fr(name) \
1366 jit_fpr_t r0 = get_freg(), r1 = get_freg(), r2 = get_freg(); \
1367 jit_##name(r0, r1, r2); \
1369 #define entry_fr_fr_fr_fr(name) \
1373 jit_fpr_t r0 = get_freg(), r1 = get_freg(), \
1374 r2 = get_freg(), r3 = get_freg(); \
1375 jit_##name(r0, r1, r2, r3); \
1377 #define entry_fr_fr_fm(name) \
1381 jit_fpr_t r0 = get_freg(), r1 = get_freg(); \
1382 jit_float64_t im = get_float(skip_ws); \
1383 jit_##name(r0, r1, make_float(im)); \
1385 #define entry_fr_fr_fr_fm(name) \
1389 jit_fpr_t r0 = get_freg(), r1 = get_freg(), \
1391 jit_float64_t im = get_float(skip_ws); \
1392 jit_##name(r0, r1, r2, make_float(im)); \
1394 #define entry_fr_fr_dm(name) \
1398 jit_fpr_t r0 = get_freg(), r1 = get_freg(); \
1399 jit_float64_t im = get_float(skip_ws); \
1400 jit_##name(r0, r1, im); \
1402 #define entry_fr_fr_fr_dm(name) \
1406 jit_fpr_t r0 = get_freg(), r1 = get_freg(), \
1408 jit_float64_t im = get_float(skip_ws); \
1409 jit_##name(r0, r1, r2, im); \
1411 #define entry_fr_fr(name) \
1415 jit_fpr_t r0 = get_freg(), r1 = get_freg(); \
1416 jit_##name(r0, r1); \
1418 #define entry_ir_fr_fr(name) \
1422 jit_gpr_t r0 = get_ireg(); \
1423 jit_fpr_t r1 = get_freg(), r2 = get_freg(); \
1424 jit_##name(r0, r1, r2); \
1426 #define entry_ir_fr_fm(name) \
1430 jit_gpr_t r0 = get_ireg(); \
1431 jit_fpr_t r1 = get_freg(); \
1432 jit_float64_t im = get_float(skip_ws); \
1433 jit_##name(r0, r1, make_float(im)); \
1435 #define entry_ir_fr_dm(name) \
1439 jit_gpr_t r0 = get_ireg(); \
1440 jit_fpr_t r1 = get_freg(); \
1441 jit_float64_t im = get_float(skip_ws); \
1442 jit_##name(r0, r1, im); \
1444 #define entry_ir_fr(name) \
1448 jit_gpr_t r0 = get_ireg(); \
1449 jit_fpr_t r1 = get_freg(); \
1450 jit_##name(r0, r1); \
1452 #define entry_fr_ir(name) \
1456 jit_fpr_t r0 = get_freg(); \
1457 jit_gpr_t r1 = get_ireg(); \
1458 jit_##name(r0, r1); \
1460 #define entry_fr_im(name) \
1464 jit_fpr_t r0 = get_freg(); \
1465 jit_word_t i0 = get_imm(); \
1466 jit_##name(r0, i0); \
1468 #define entry_ir_fm(name) \
1472 jit_gpr_t r0 = get_ireg(); \
1473 jit_float64_t im = get_float(skip_ws); \
1474 jit_##name(r0, make_float(im)); \
1476 #define entry_ir_dm(name) \
1480 jit_gpr_t r0 = get_ireg(); \
1481 jit_float64_t im = get_float(skip_ws); \
1482 jit_##name(r0,im); \
1484 #define entry_ir_ir_dm(name) \
1488 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \
1489 jit_float64_t im = get_float(skip_ws); \
1490 jit_##name(r0, r1, im); \
1492 #define entry_fr_fm(name) \
1496 jit_fpr_t r0 = get_freg(); \
1497 jit_float64_t im = get_float(skip_ws); \
1498 jit_##name(r0, make_float(im)); \
1500 #define entry_fr_dm(name) \
1504 jit_fpr_t r0 = get_freg(); \
1505 jit_float64_t im = get_float(skip_ws); \
1506 jit_##name(r0, im); \
1508 #define entry_fr_pm(name) \
1512 jit_fpr_t r0 = get_freg(); \
1513 void *pm = get_pointer(skip_ws); \
1514 jit_##name(r0, pm); \
1516 #define entry_fr_ir_ir(name) \
1520 jit_fpr_t r0 = get_freg(); \
1521 jit_gpr_t r1 = get_ireg(), r2 = get_ireg(); \
1522 jit_##name(r0, r1, r2); \
1524 #define entry_fr_ir_im(name) \
1528 jit_fpr_t r0 = get_freg(); \
1529 jit_gpr_t r1 = get_ireg(); \
1530 jit_word_t im = get_imm(); \
1531 jit_##name(r0, r1, im); \
1533 #define entry_fr_im_im(name) \
1537 jit_fpr_t r0 = get_freg(); \
1538 jit_word_t i0 = get_imm(); \
1539 jit_word_t i1 = get_imm(); \
1540 jit_##name(r0, i0, i1); \
1542 #define entry_pm_fr(name) \
1546 void *pm = get_pointer(skip_ws); \
1547 jit_fpr_t r0 = get_freg(); \
1548 jit_##name(pm, r0); \
1550 #define entry_ir_ir_fr(name) \
1554 jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \
1555 jit_fpr_t r2 = get_freg(); \
1556 jit_##name(r0, r1, r2); \
1558 #define entry_im_ir_fr(name) \
1562 jit_word_t im = get_imm(); \
1563 jit_gpr_t r0 = get_ireg(); \
1564 jit_fpr_t r1 = get_freg(); \
1565 jit_##name(im, r0, r1); \
1567 #define entry_lb_fr_fr(name) \
1572 label_t *label = get_label(skip_ws); \
1573 jit_fpr_t r0 = get_freg(), r1 = get_freg(); \
1574 if (label->kind == label_kind_code_forward) \
1575 jmp_forward((void *)jit_##name(r0, r1), label); \
1577 jmp = jit_##name(r0, r1); \
1578 jit_patch_at(jmp, (jit_node_t *)label->value); \
1581 #define entry_lb_fr_fm(name) \
1586 label_t *label = get_label(skip_ws); \
1587 jit_fpr_t r0 = get_freg(); \
1588 jit_float64_t im = get_float(skip_ws); \
1589 if (label->kind == label_kind_code_forward) \
1590 jmp_forward((void *)jit_##name(r0, make_float(im)), label); \
1592 jmp = jit_##name(r0, make_float(im)); \
1593 jit_patch_at(jmp, (jit_node_t *)label->value); \
1596 #define entry_lb_fr_dm(name) \
1601 label_t *label = get_label(skip_ws); \
1602 jit_fpr_t r0 = get_freg(); \
1603 jit_float64_t im = get_float(skip_ws); \
1604 if (label->kind == label_kind_code_forward) \
1605 jmp_forward((void *)jit_##name(r0, im), label); \
1607 jmp = jit_##name(r0, im); \
1608 jit_patch_at(jmp, (jit_node_t *)label->value); \
1611 #define entry_fr(name) \
1615 jit_fpr_t r0 = get_freg(); \
1618 #define entry_fm(name) \
1622 jit_float64_t im = get_float(skip_ws); \
1623 jit_##name(make_float(im)); \
1625 #define entry_dm(name) \
1629 jit_float64_t im = get_float(skip_ws); \
1632 #define entry_fn(name) \
1643 value = (void *)(jit_word_t)get_uint(skip_none); \
1646 switch (expression()) { \
1648 value = (void *)parser.value.i; \
1651 value = parser.value.p; \
1654 error("expecting pointer"); \
1659 value = parser.value.p; \
1663 label = get_label(skip_none); \
1664 if (label->kind == label_kind_code_forward) \
1665 call_forward((void *)jit_##name(NULL), label); \
1667 jit_patch_at(jit_##name(NULL), label->value); \
1670 jit_##name(value); \
1675 (void)identifier(ch);
1676 jit_name(parser.string);
1680 if (primary(skip_ws) != tok_register)
1681 error("bad register");
1682 jit_live(parser.regval);
1687 entry_im(frame) entry_im(tramp)
1692 jit_word_t i, im = get_imm();
1693 i = jit_allocai(im);
1694 symbol = get_symbol();
1695 symbol->type = type_l;
1696 symbol->value.i = i;
1698 entry_ir_ir(allocar)
1699 entry_ca(arg_c) entry_ca(arg_s)
1701 #if __WORDSIZE == 64
1705 entry_ia(getarg_c) entry_ia(getarg_uc)
1706 entry_ia(getarg_s) entry_ia(getarg_us)
1708 #if __WORDSIZE == 64
1709 entry_ia(getarg_ui) entry_ia(getarg_l)
1712 entry_ia(putargr_c) entry_ima(putargi_c)
1713 entry_ia(putargr_uc) entry_ima(putargi_uc)
1714 entry_ia(putargr_s) entry_ima(putargi_s)
1715 entry_ia(putargr_us) entry_ima(putargi_us)
1716 entry_ia(putargr_i) entry_ima(putargi_i)
1717 #if __WORDSIZE == 64
1718 entry_ia(putargr_ui) entry_ima(putargi_ui)
1719 entry_ia(putargr_l) entry_ima(putargi_l)
1721 entry_ia(putargr) entry_ima(putargi)
1722 entry_ir_ir_ir(addr) entry_ir_ir_im(addi)
1723 entry_ir_ir_ir(addxr) entry_ir_ir_im(addxi)
1724 entry_ir_ir_ir(addcr) entry_ir_ir_im(addci)
1725 entry_ir_ir_ir(subr) entry_ir_ir_im(subi)
1726 entry_ir_ir_ir(subxr) entry_ir_ir_im(subxi)
1727 entry_ir_ir_ir(subcr) entry_ir_ir_im(subci)
1728 entry_ir_ir_ir(rsbr) entry_ir_ir_im(rsbi)
1729 entry_ir_ir_ir(mulr) entry_ir_ir_im(muli)
1730 entry_ir_ir_ir(hmulr) entry_ir_ir_im(hmuli)
1731 entry_ir_ir_ir(hmulr_u) entry_ir_ir_im(hmuli_u)
1732 entry_ir_ir_ir_ir(qmulr) entry_ir_ir_ir_im(qmuli)
1733 entry_ir_ir_ir_ir(qmulr_u) entry_ir_ir_ir_im(qmuli_u)
1734 entry_ir_ir_ir(divr) entry_ir_ir_im(divi)
1735 entry_ir_ir_ir(divr_u) entry_ir_ir_im(divi_u)
1736 entry_ir_ir_ir_ir(qdivr) entry_ir_ir_ir_im(qdivi)
1737 entry_ir_ir_ir_ir(qdivr_u) entry_ir_ir_ir_im(qdivi_u)
1738 entry_ir_ir_ir(remr) entry_ir_ir_im(remi)
1739 entry_ir_ir_ir(remr_u) entry_ir_ir_im(remi_u)
1740 entry_ir_ir_ir(andr) entry_ir_ir_im(andi)
1741 entry_ir_ir_ir(orr) entry_ir_ir_im(ori)
1742 entry_ir_ir_ir(xorr) entry_ir_ir_im(xori)
1743 entry_ir_ir_ir(lshr) entry_ir_ir_im(lshi)
1744 entry_ir_ir_ir_ir(qlshr) entry_ir_ir_ir_im(qlshi)
1745 entry_ir_ir_ir_ir(qlshr_u) entry_ir_ir_ir_im(qlshi_u)
1746 entry_ir_ir_ir(rshr) entry_ir_ir_im(rshi)
1747 entry_ir_ir_ir_ir(qrshr) entry_ir_ir_ir_im(qrshi)
1748 entry_ir_ir_ir(rshr_u) entry_ir_ir_im(rshi_u)
1749 entry_ir_ir_ir_ir(qrshr_u) entry_ir_ir_ir_im(qrshi_u)
1750 entry_ir_ir_ir(lrotr) entry_ir_ir_im(lroti)
1751 entry_ir_ir_ir(rrotr) entry_ir_ir_im(rroti)
1752 entry_ir_ir(negr) entry_ir_im(negi)
1753 entry_ir_ir(comr) entry_ir_im(comi)
1754 entry_ir_ir(clor) entry_ir_im(cloi)
1755 entry_ir_ir(clzr) entry_ir_im(clzi)
1756 entry_ir_ir(ctor) entry_ir_im(ctoi)
1757 entry_ir_ir(ctzr) entry_ir_im(ctzi)
1758 entry_ir_ir(rbitr) entry_ir_im(rbiti)
1759 entry_ir_ir(popcntr) entry_ir_im(popcnti)
1760 entry_ir_ir_ir(ltr) entry_ir_ir_im(lti)
1761 entry_ir_ir_ir(ltr_u) entry_ir_ir_im(lti_u)
1762 entry_ir_ir_ir(ler) entry_ir_ir_im(lei)
1763 entry_ir_ir_ir(ler_u) entry_ir_ir_im(lei_u)
1764 entry_ir_ir_ir(eqr) entry_ir_ir_im(eqi)
1765 entry_ir_ir_ir(ger) entry_ir_ir_im(gei)
1766 entry_ir_ir_ir(ger_u) entry_ir_ir_im(gei_u)
1767 entry_ir_ir_ir(gtr) entry_ir_ir_im(gti)
1768 entry_ir_ir_ir(gtr_u) entry_ir_ir_im(gti_u)
1769 entry_ir_ir_ir(ner) entry_ir_ir_im(nei)
1770 entry_ir_ir_ir_ir(casr) entry_ir_im_ir_ir(casi)
1778 jit_gpr_t r0 = get_ireg();
1784 value = (void *)(jit_word_t)get_uint(skip_none);
1788 value = (void *)parser.value.i;
1791 switch (expression()) {
1793 value = (void *)parser.value.i;
1796 value = parser.value.p;
1799 error("expecting pointer");
1804 value = parser.value.p;
1808 label = get_label(skip_none);
1809 if (label->kind == label_kind_code ||
1810 label->kind == label_kind_code_forward) {
1811 mov_forward((void *)jit_movi(r0, 0), label);
1814 value = label->value;
1817 jit_movi(r0, (jit_word_t)value);
1820 entry_ir_ir_im_im(extr) entry_ir_im_im_im(exti)
1821 entry_ir_ir_im_im(extr_u) entry_ir_im_im_im(exti_u)
1822 entry_ir_ir_im_im(depr) entry_ir_im_im_im(depi)
1823 entry_ir_ir(extr_c) entry_ir_im(exti_c)
1824 entry_ir_ir(extr_uc) entry_ir_im(exti_uc)
1825 entry_ir_ir(extr_s) entry_ir_im(exti_s)
1826 entry_ir_ir(extr_us) entry_ir_im(exti_us)
1827 #if __WORDSIZE == 64
1828 entry_ir_ir(extr_i) entry_ir_im(exti_i)
1829 entry_ir_ir(extr_ui) entry_ir_im(exti_ui)
1831 entry_ir_ir(htonr_us) entry_ir_im(htoni_us)
1832 entry_ir_ir(ntohr_us) entry_ir_im(ntohi_us)
1833 entry_ir_ir(htonr_ui) entry_ir_im(htoni_ui)
1834 entry_ir_ir(ntohr_ui) entry_ir_im(ntohi_ui)
1835 #if __WORDSIZE == 64
1836 entry_ir_ir(htonr_ul) entry_ir_im(htoni_ul)
1837 entry_ir_ir(ntohr_ul) entry_ir_im(ntohi_ul)
1839 entry_ir_ir(htonr) entry_ir_im(htoni)
1840 entry_ir_ir(ntohr) entry_ir_im(ntohi)
1841 entry_ir_ir(bswapr_us) entry_ir_im(bswapi_us)
1842 entry_ir_ir(bswapr_ui) entry_ir_im(bswapi_ui)
1843 #if __WORDSIZE == 64
1844 entry_ir_ir(bswapr_ul) entry_ir_im(bswapi_ul)
1846 entry_ir_ir(bswapr) entry_ir_im(bswapi)
1847 entry_ir_ir_ir(movnr) entry_ir_ir_ir(movzr)
1848 entry_ir_ir(ldr_c) entry_ir_pm(ldi_c)
1849 entry_ir_ir(ldr_uc) entry_ir_pm(ldi_uc)
1850 entry_ir_ir(ldr_s) entry_ir_pm(ldi_s)
1851 entry_ir_ir(ldr_us) entry_ir_pm(ldi_us)
1852 entry_ir_ir(ldr_i) entry_ir_pm(ldi_i)
1853 #if __WORDSIZE == 64
1854 entry_ir_ir(ldr_ui) entry_ir_pm(ldi_ui)
1855 entry_ir_ir(ldr_l) entry_ir_pm(ldi_l)
1857 entry_ir_ir(ldr) entry_ir_pm(ldi)
1858 entry_ir_ir_ir(ldxr_c) entry_ir_ir_im(ldxi_c)
1859 entry_ir_ir_ir(ldxr_uc) entry_ir_ir_im(ldxi_uc)
1860 entry_ir_ir_ir(ldxr_s) entry_ir_ir_im(ldxi_s)
1861 entry_ir_ir_ir(ldxr_us) entry_ir_ir_im(ldxi_us)
1862 entry_ir_ir_ir(ldxr_i) entry_ir_ir_im(ldxi_i)
1863 #if __WORDSIZE == 64
1864 entry_ir_ir_ir(ldxr_ui) entry_ir_ir_im(ldxi_ui)
1865 entry_ir_ir_ir(ldxr_l) entry_ir_ir_im(ldxi_l)
1867 entry_ir_ir_ir(ldxr) entry_ir_ir_im(ldxi)
1868 entry_ir_ir_im(unldr) entry_ir_im_im(unldi)
1869 entry_ir_ir_im(unldr_u) entry_ir_im_im(unldi_u)
1870 entry_ir_ir(str_c) entry_pm_ir(sti_c)
1871 entry_ir_ir(str_s) entry_pm_ir(sti_s)
1872 entry_ir_ir(str_i) entry_pm_ir(sti_i)
1873 #if __WORDSIZE == 64
1874 entry_ir_ir(str_l) entry_pm_ir(sti_l)
1876 entry_ir_ir(str) entry_pm_ir(sti)
1877 entry_ir_ir_ir(stxr_c) entry_im_ir_ir(stxi_c)
1878 entry_ir_ir_ir(stxr_s) entry_im_ir_ir(stxi_s)
1879 entry_ir_ir_ir(stxr_i) entry_im_ir_ir(stxi_i)
1880 #if __WORDSIZE == 64
1881 entry_ir_ir_ir(stxr_l) entry_im_ir_ir(stxi_l)
1883 entry_ir_ir_ir(stxr) entry_im_ir_ir(stxi)
1884 entry_ir_ir_im(unstr) entry_im_ir_im(unsti)
1885 entry_lb_ir_ir(bltr) entry_lb_ir_im(blti)
1886 entry_lb_ir_ir(bltr_u) entry_lb_ir_im(blti_u)
1887 entry_lb_ir_ir(bler) entry_lb_ir_im(blei)
1888 entry_lb_ir_ir(bler_u) entry_lb_ir_im(blei_u)
1889 entry_lb_ir_ir(beqr) entry_lb_ir_im(beqi)
1890 entry_lb_ir_ir(bger) entry_lb_ir_im(bgei)
1891 entry_lb_ir_ir(bger_u) entry_lb_ir_im(bgei_u)
1892 entry_lb_ir_ir(bgtr) entry_lb_ir_im(bgti)
1893 entry_lb_ir_ir(bgtr_u) entry_lb_ir_im(bgti_u)
1894 entry_lb_ir_ir(bner) entry_lb_ir_im(bnei)
1895 entry_lb_ir_ir(bmsr) entry_lb_ir_im(bmsi)
1896 entry_lb_ir_ir(bmcr) entry_lb_ir_im(bmci)
1897 entry_lb_ir_ir(boaddr) entry_lb_ir_im(boaddi)
1898 entry_lb_ir_ir(boaddr_u) entry_lb_ir_im(boaddi_u)
1899 entry_lb_ir_ir(bxaddr) entry_lb_ir_im(bxaddi)
1900 entry_lb_ir_ir(bxaddr_u) entry_lb_ir_im(bxaddi_u)
1901 entry_lb_ir_ir(bosubr) entry_lb_ir_im(bosubi)
1902 entry_lb_ir_ir(bosubr_u) entry_lb_ir_im(bosubi_u)
1903 entry_lb_ir_ir(bxsubr) entry_lb_ir_im(bxsubi)
1904 entry_lb_ir_ir(bxsubr_u) entry_lb_ir_im(bxsubi_u)
1905 entry_ir(jmpr) entry_lb(jmpi)
1906 entry_ir(callr) entry_fn(calli)
1908 entry_ir(pushargr_c) entry_im(pushargi_c)
1909 entry_ir(pushargr_uc) entry_im(pushargi_uc)
1910 entry_ir(pushargr_s) entry_im(pushargi_s)
1911 entry_ir(pushargr_us) entry_im(pushargi_us)
1912 entry_ir(pushargr_i) entry_im(pushargi_i)
1913 #if __WORDSIZE == 64
1914 entry_ir(pushargr_ui) entry_im(pushargi_ui)
1915 entry_ir(pushargr_l) entry_im(pushargi_l)
1917 entry_ir(pushargr) entry_im(pushargi)
1918 entry_ir(finishr) entry_fn(finishi)
1920 entry_ir(retr_c) entry_im(reti_c)
1921 entry_ir(retr_uc) entry_im(reti_uc)
1922 entry_ir(retr_s) entry_im(reti_s)
1923 entry_ir(retr_us) entry_im(reti_us)
1924 entry_ir(retr_i) entry_im(reti_i)
1925 #if __WORDSIZE == 64
1926 entry_ir(retr_ui) entry_im(reti_ui)
1927 entry_ir(retr_l) entry_im(reti_l)
1929 entry_ir(retr) entry_im(reti)
1930 entry_ir(retval_c) entry_ir(retval_uc)
1931 entry_ir(retval_s) entry_ir(retval_us)
1933 #if __WORDSIZE == 64
1934 entry_ir(retval_ui) entry_ir(retval_l)
1938 entry_ca(arg_f) entry_fa(getarg_f)
1939 entry_fa(putargr_f) entry_fma(putargi_f)
1940 entry_fr_fr_fr(addr_f) entry_fr_fr_fm(addi_f)
1941 entry_fr_fr_fr(subr_f) entry_fr_fr_fm(subi_f)
1942 entry_fr_fr_fr(rsbr_f) entry_fr_fr_fm(rsbi_f)
1943 entry_fr_fr_fr(mulr_f) entry_fr_fr_fm(muli_f)
1944 entry_fr_fr_fr(divr_f) entry_fr_fr_fm(divi_f)
1945 entry_fr_fr(negr_f) entry_fr_fm(negi_f)
1946 entry_fr_fr(absr_f) entry_fr_fm(absi_f)
1947 entry_fr_fr(sqrtr_f) entry_fr_fm(sqrti_f)
1948 entry_fr_fr_fr_fr(fmar_f) entry_fr_fr_fr_fm(fmai_f)
1949 entry_fr_fr_fr_fr(fmsr_f) entry_fr_fr_fr_fm(fmsi_f)
1950 entry_fr_fr_fr_fr(fnmar_f) entry_fr_fr_fr_fm(fnmai_f)
1951 entry_fr_fr_fr_fr(fnmsr_f) entry_fr_fr_fr_fm(fnmsi_f)
1952 entry_ir_fr_fr(ltr_f) entry_ir_fr_fm(lti_f)
1953 entry_ir_fr_fr(ler_f) entry_ir_fr_fm(lei_f)
1954 entry_ir_fr_fr(eqr_f) entry_ir_fr_fm(eqi_f)
1955 entry_ir_fr_fr(ger_f) entry_ir_fr_fm(gei_f)
1956 entry_ir_fr_fr(gtr_f) entry_ir_fr_fm(gti_f)
1957 entry_ir_fr_fr(ner_f) entry_ir_fr_fm(nei_f)
1958 entry_ir_fr_fr(unltr_f) entry_ir_fr_fm(unlti_f)
1959 entry_ir_fr_fr(unler_f) entry_ir_fr_fm(unlei_f)
1960 entry_ir_fr_fr(uneqr_f) entry_ir_fr_fm(uneqi_f)
1961 entry_ir_fr_fr(unger_f) entry_ir_fr_fm(ungei_f)
1962 entry_ir_fr_fr(ungtr_f) entry_ir_fr_fm(ungti_f)
1963 entry_ir_fr_fr(ltgtr_f) entry_ir_fr_fm(ltgti_f)
1964 entry_ir_fr_fr(ordr_f) entry_ir_fr_fm(ordi_f)
1965 entry_ir_fr_fr(unordr_f) entry_ir_fr_fm(unordi_f)
1966 entry_ir_fr(truncr_f_i)
1967 #if __WORDSIZE == 64
1968 entry_ir_fr(truncr_f_l)
1970 entry_ir_fr(truncr_f)
1971 entry_fr_ir(extr_f) entry_fr_fr(extr_d_f)
1972 entry_fr_fr(movr_f) entry_fr_fm(movi_f)
1973 entry_fr_ir(movr_w_f) entry_ir_fr(movr_f_w)
1974 entry_ir_fm(movi_f_w) entry_fr_im(movi_w_f)
1975 entry_fr_ir(ldr_f) entry_fr_pm(ldi_f)
1976 entry_fr_ir_ir(ldxr_f) entry_fr_ir_im(ldxi_f)
1977 entry_fr_ir_im(unldr_x) entry_fr_im_im(unldi_x)
1978 entry_ir_fr(str_f) entry_pm_fr(sti_f)
1979 entry_ir_ir_fr(stxr_f) entry_im_ir_fr(stxi_f)
1980 entry_ir_fr_im(unstr_x) entry_im_fr_im(unsti_x)
1981 entry_lb_fr_fr(bltr_f) entry_lb_fr_fm(blti_f)
1982 entry_lb_fr_fr(bler_f) entry_lb_fr_fm(blei_f)
1983 entry_lb_fr_fr(beqr_f) entry_lb_fr_fm(beqi_f)
1984 entry_lb_fr_fr(bger_f) entry_lb_fr_fm(bgei_f)
1985 entry_lb_fr_fr(bgtr_f) entry_lb_fr_fm(bgti_f)
1986 entry_lb_fr_fr(bner_f) entry_lb_fr_fm(bnei_f)
1987 entry_lb_fr_fr(bunltr_f) entry_lb_fr_fm(bunlti_f)
1988 entry_lb_fr_fr(bunler_f) entry_lb_fr_fm(bunlei_f)
1989 entry_lb_fr_fr(buneqr_f) entry_lb_fr_fm(buneqi_f)
1990 entry_lb_fr_fr(bunger_f) entry_lb_fr_fm(bungei_f)
1991 entry_lb_fr_fr(bungtr_f) entry_lb_fr_fm(bungti_f)
1992 entry_lb_fr_fr(bltgtr_f) entry_lb_fr_fm(bltgti_f)
1993 entry_lb_fr_fr(bordr_f) entry_lb_fr_fm(bordi_f)
1994 entry_lb_fr_fr(bunordr_f) entry_lb_fr_fm(bunordi_f)
1995 entry_fr(pushargr_f) entry_fm(pushargi_f)
1996 entry_fr(retr_f) entry_fm(reti_f)
1998 entry_ca(arg_d) entry_fa(getarg_d)
1999 entry_fa(putargr_d) entry_fma(putargi_d)
2000 entry_fr_fr_fr(addr_d) entry_fr_fr_dm(addi_d)
2001 entry_fr_fr_fr(subr_d) entry_fr_fr_dm(subi_d)
2002 entry_fr_fr_fr(rsbr_d) entry_fr_fr_dm(rsbi_d)
2003 entry_fr_fr_fr(mulr_d) entry_fr_fr_dm(muli_d)
2004 entry_fr_fr_fr(divr_d) entry_fr_fr_dm(divi_d)
2005 entry_fr_fr(negr_d) entry_fr_fm(negi_d)
2006 entry_fr_fr(absr_d) entry_fr_fm(absi_d)
2007 entry_fr_fr(sqrtr_d) entry_fr_fm(sqrti_d)
2008 entry_fr_fr_fr_fr(fmar_d) entry_fr_fr_fr_dm(fmai_d)
2009 entry_fr_fr_fr_fr(fmsr_d) entry_fr_fr_fr_dm(fmsi_d)
2010 entry_fr_fr_fr_fr(fnmar_d) entry_fr_fr_fr_dm(fnmai_d)
2011 entry_fr_fr_fr_fr(fnmsr_d) entry_fr_fr_fr_dm(fnmsi_d)
2012 entry_ir_fr_fr(ltr_d) entry_ir_fr_dm(lti_d)
2013 entry_ir_fr_fr(ler_d) entry_ir_fr_dm(lei_d)
2014 entry_ir_fr_fr(eqr_d) entry_ir_fr_dm(eqi_d)
2015 entry_ir_fr_fr(ger_d) entry_ir_fr_dm(gei_d)
2016 entry_ir_fr_fr(gtr_d) entry_ir_fr_dm(gti_d)
2017 entry_ir_fr_fr(ner_d) entry_ir_fr_dm(nei_d)
2018 entry_ir_fr_fr(unltr_d) entry_ir_fr_dm(unlti_d)
2019 entry_ir_fr_fr(unler_d) entry_ir_fr_dm(unlei_d)
2020 entry_ir_fr_fr(uneqr_d) entry_ir_fr_dm(uneqi_d)
2021 entry_ir_fr_fr(unger_d) entry_ir_fr_dm(ungei_d)
2022 entry_ir_fr_fr(ungtr_d) entry_ir_fr_dm(ungti_d)
2023 entry_ir_fr_fr(ltgtr_d) entry_ir_fr_dm(ltgti_d)
2024 entry_ir_fr_fr(ordr_d) entry_ir_fr_dm(ordi_d)
2025 entry_ir_fr_fr(unordr_d) entry_ir_fr_dm(unordi_d)
2026 entry_ir_fr(truncr_d_i)
2027 #if __WORDSIZE == 64
2028 entry_ir_fr(truncr_d_l)
2030 entry_ir_fr(truncr_d)
2031 entry_fr_ir(extr_d) entry_fr_fr(extr_f_d)
2032 entry_fr_fr(movr_d) entry_fr_dm(movi_d)
2033 #if __WORDSIZE == 32
2034 entry_fr_ir_ir(movr_ww_d) entry_ir_ir_fr(movr_d_ww)
2035 entry_ir_ir_dm(movi_d_ww) entry_fr_im_im(movi_ww_d)
2037 entry_fr_ir(movr_w_d) entry_ir_fr(movr_d_w)
2038 entry_ir_dm(movi_d_w) entry_fr_im(movi_w_d)
2040 entry_fr_ir(ldr_d) entry_fr_pm(ldi_d)
2041 entry_fr_ir_ir(ldxr_d) entry_fr_ir_im(ldxi_d)
2042 entry_ir_fr(str_d) entry_pm_fr(sti_d)
2043 entry_ir_ir_fr(stxr_d) entry_im_ir_fr(stxi_d)
2044 entry_lb_fr_fr(bltr_d) entry_lb_fr_dm(blti_d)
2045 entry_lb_fr_fr(bler_d) entry_lb_fr_dm(blei_d)
2046 entry_lb_fr_fr(beqr_d) entry_lb_fr_dm(beqi_d)
2047 entry_lb_fr_fr(bger_d) entry_lb_fr_dm(bgei_d)
2048 entry_lb_fr_fr(bgtr_d) entry_lb_fr_dm(bgti_d)
2049 entry_lb_fr_fr(bner_d) entry_lb_fr_dm(bnei_d)
2050 entry_lb_fr_fr(bunltr_d) entry_lb_fr_dm(bunlti_d)
2051 entry_lb_fr_fr(bunler_d) entry_lb_fr_dm(bunlei_d)
2052 entry_lb_fr_fr(buneqr_d) entry_lb_fr_dm(buneqi_d)
2053 entry_lb_fr_fr(bunger_d) entry_lb_fr_dm(bungei_d)
2054 entry_lb_fr_fr(bungtr_d) entry_lb_fr_dm(bungti_d)
2055 entry_lb_fr_fr(bltgtr_d) entry_lb_fr_dm(bltgti_d)
2056 entry_lb_fr_fr(bordr_d) entry_lb_fr_dm(bordi_d)
2057 entry_lb_fr_fr(bunordr_d) entry_lb_fr_dm(bunordi_d)
2058 entry_fr(pushargr_d) entry_dm(pushargi_d)
2059 entry_fr(retr_d) entry_dm(reti_d)
2064 jit_gpr_t r0 = get_ireg();
2070 jit_gpr_t r0 = get_ireg();
2076 jit_gpr_t r0 = get_ireg(), r1 = get_ireg();
2082 jit_fpr_t r0 = get_freg();
2083 jit_gpr_t r1 = get_ireg();
2084 jit_va_arg_d(r0, r1);
2089 jit_gpr_t r0 = get_ireg();
2095 #undef entry_lb_fr_fm
2096 #undef entry_lb_fr_dm
2097 #undef entry_lb_fr_fr
2098 #undef entry_im_ir_fr
2099 #undef entry_ir_ir_fr
2101 #undef entry_fr_ir_ir
2102 #undef entry_fr_ir_im
2108 #undef entry_ir_fr_fm
2109 #undef entry_ir_fr_dm
2110 #undef entry_ir_fr_fr
2112 #undef entry_fr_fr_fm
2113 #undef entry_fr_fr_dm
2114 #undef entry_fr_fr_fr
2119 #undef entry_lb_ir_im
2120 #undef entry_lb_ir_ir
2121 #undef entry_im_ir_ir
2126 #undef entry_ir_ir_im
2127 #undef entry_ir_ir_ir
2128 #undef entry_ir_ir_im_im
2129 #undef entry_ir_im_im_im
2138 error(const char *format, ...)
2144 va_start(ap, format);
2145 message("error", format, ap);
2147 length = parser.data.length - parser.data.offset;
2148 string = (char *)(parser.data.buffer + parser.data.offset - 1);
2150 strcpy(string + 74, "...");
2152 parser.data.buffer[parser.data.length - 1] = '\0';
2153 fprintf(stderr, "(%s)\n", string);
2158 warn(const char *format, ...)
2161 va_start(ap, format);
2162 message("warning", format, ap);
2167 message(const char *kind, const char *format, va_list ap)
2169 fprintf(stderr, "%s:%d: %s: ", parser.name,
2170 parser.line - parser.newline, kind);
2171 vfprintf(stderr, format, ap);
2172 fputc('\n', stderr);
2180 if (parser.data.offset < parser.data.length)
2181 ch = parser.data.buffer[parser.data.offset++];
2183 /* keep first offset for ungetch */
2184 if ((parser.data.length = fread(parser.data.buffer + 1, 1,
2185 sizeof(parser.data.buffer) - 1,
2186 parser.fp) + 1) <= 1) {
2188 parser.data.offset = 1;
2191 ch = parser.data.buffer[1];
2192 parser.data.offset = 2;
2195 if ((parser.newline = ch == '\n'))
2207 error("unexpected end of file");
2215 if ((parser.newline = ch == '\n'))
2218 if (parser.data.offset)
2219 parser.data.buffer[--parser.data.offset] = ch;
2222 parser.data.buffer[0] = ch;
2232 for (ch = getch();; ch = getch()) {
2242 case ' ': case '\f': case '\r': case '\t':
2255 for (ch = getch();; ch = getch()) {
2265 case ' ': case '\f': case '\n': case '\r': case '\t':
2267 /* handle as newline */
2284 for (ch = getch(); ch != '\n' && ch != EOF; ch = getch())
2288 for (; ch != '/';) {
2289 while (getch_noeof() != '*')
2291 while ((ch = getch_noeof()) == '*')
2306 for (ch = getch(); ch != '\n' && ch != EOF; ch = getch()) {
2309 if ((number(ch)) == tok_int)
2310 parser.line = parser.value.i - 1;
2314 if (parser.offset >= (int)sizeof(parser.name)) {
2315 strncpy(parser.name, parser.string, sizeof(parser.name));
2316 parser.name[sizeof(parser.name) - 1] = '\0';
2319 strcpy(parser.name, parser.string);
2330 get_int(skip_t skip)
2332 switch (primary(skip)) {
2336 parser.type = type_l;
2337 parser.value.i = (jit_word_t)parser.value.p;
2340 error("expecting integer");
2343 return (parser.value.i);
2347 get_uint(skip_t skip)
2349 switch (primary(skip)) {
2350 case tok_char: case tok_int:
2353 parser.type = type_l;
2354 parser.value.ui = (jit_uword_t)parser.value.p;
2357 error("expecting integer");
2360 return (parser.value.ui);
2364 get_float(skip_t skip)
2366 switch (primary(skip)) {
2369 parser.type = type_d;
2370 parser.value.d = parser.value.i;
2375 error("expecting float");
2378 return (parser.value.d);
2381 /* Workaround gcc not converting unordered values from double to
2382 * float (as done in other architectures) on s390 */
2384 make_float(double d)
2386 /* This is an workaround to a bug in Hercules s390 emulator,
2387 * and at least HP-UX ia64 not have these */
2388 #if defined(HAVE_ISNAN) && defined(HAVE_ISINF)
2389 if (isnan(d)) return ( 0.0f/0.0f);
2391 if (d > 0.0) return ( 1.0f/0.0f);
2392 else return (-1.0f/0.0f);
2399 get_pointer(skip_t skip)
2402 token_t token = primary(skip);
2406 label = get_label_by_name(parser.string);
2408 error("bad identifier %s", parser.string);
2409 switch (label->kind) {
2410 case label_kind_data:
2411 case label_kind_code:
2413 case label_kind_code_forward:
2414 /* as expression arguments */
2415 error("forward references not implemented");
2417 case label_kind_dynamic:
2420 parser.type = type_p;
2421 return (parser.value.p = label->value);
2423 parser.type = type_p;
2424 return (parser.value.p = (void *)parser.value.ui);
2426 return (parser.value.p);
2427 default: error("bad pointer");
2432 get_label(skip_t skip)
2441 case 'a' ... 'z': case 'A' ... 'Z': case '_':
2442 (void)identifier(ch);
2445 error("expecting label/immediate");
2447 if ((label = get_label_by_name(parser.string)) == NULL)
2448 label = new_label(label_kind_code_forward,
2449 parser.string, jit_forward());
2458 int check = 1, ch = getch();
2462 parser.regtype = type_l;
2463 switch (ch = getch()) {
2464 case '0': parser.regval = JIT_R0; break;
2465 case '1': parser.regval = JIT_R1; break;
2466 case '2': parser.regval = JIT_R2; break;
2468 num = get_int(skip_none);
2469 if (num < 0 || num >= JIT_R_NUM) goto fail;
2470 parser.regval = JIT_R(num);
2471 if (getch() != ')') goto fail;
2478 parser.regtype = type_l;
2479 switch (ch = getch()) {
2480 case '0': parser.regval = JIT_V0; break;
2481 case '1': parser.regval = JIT_V1; break;
2482 case '2': parser.regval = JIT_V2; break;
2485 num = get_int(skip_none);
2486 if (num < 0 || num >= JIT_V_NUM) goto fail;
2487 parser.regval = JIT_V(num);
2488 if (getch() != ')') goto fail;
2494 parser.regtype = type_d;
2495 switch (ch = getch()) {
2496 case '0': parser.regval = JIT_F0; break;
2497 case '1': parser.regval = JIT_F1; break;
2498 case '2': parser.regval = JIT_F2; break;
2499 case '3': parser.regval = JIT_F3; break;
2500 case '4': parser.regval = JIT_F4; break;
2501 case '5': parser.regval = JIT_F5; break;
2503 parser.regtype = type_l; /* oops */
2504 parser.regval = JIT_FP; break;
2506 num = get_int(skip_none);
2507 if (num < 0 || num >= JIT_F_NUM) goto fail;
2508 parser.regval = JIT_F(num);
2509 if (getch() != ')') goto fail;
2517 error("bad register");
2521 if ((ch >= 'a' && ch <= 'z') ||
2522 (ch >= 'A' && ch <= 'Z') ||
2523 (ch >= '0' && ch <= '9') ||
2529 return (tok_register);
2535 parser.string[0] = ch;
2536 for (parser.offset = 1;;) {
2537 switch ((ch = getch())) {
2538 case 'a' ... 'z': case 'A' ... 'Z': case '0' ... '9' : case '_':
2539 if (parser.offset + 1 >= MAX_IDENTIFIER) {
2540 parser.string[parser.offset] = '\0';
2541 error("bad identifier %s", parser.string);
2543 parser.string[parser.offset++] = ch;
2546 parser.string[parser.offset] = '\0';
2548 return (tok_symbol);
2554 get_data(type_t type)
2563 switch (token = primary(skip_ws)) {
2564 case tok_char: case tok_int:
2565 check_data(sizeof(signed char));
2566 *(signed char *)(data + data_offset) = parser.value.i;
2567 data_offset += sizeof(char);
2570 check_data(parser.offset);
2571 memcpy(data + data_offset, parser.string,
2573 data_offset += parser.offset;
2576 case tok_semicollon:
2577 if (test == data) error("syntax error");
2579 default: error("bad initializer");
2583 check_data(sizeof(signed short));
2584 *(signed short *)(data + data_offset) = get_int(skip_ws);
2585 data_offset += sizeof(short);
2588 check_data(sizeof(signed int));
2589 *(signed int *)(data + data_offset) = get_int(skip_ws);
2590 data_offset += sizeof(int);
2593 check_data(sizeof(jit_word_t));
2594 *(jit_word_t *)(data + data_offset) = get_int(skip_ws);
2595 data_offset += sizeof(jit_word_t);
2598 check_data(sizeof(float));
2599 *(float *)(data + data_offset) = get_float(skip_ws);
2600 data_offset += sizeof(float);
2603 check_data(sizeof(double));
2604 *(double *)(data + data_offset) = get_float(skip_ws);
2605 data_offset += sizeof(double);
2608 /* FIXME **patch if realloc** */
2609 check_data(sizeof(void*));
2610 *(void **)(data + data_offset) = get_pointer(skip_ws);
2611 data_offset += sizeof(void*);
2617 if (ch == '\n' || ch == ';' || ch == EOF)
2627 size_t offset, length;
2629 switch (ch = getch_noeof()) {
2631 /* use .$(expression) for non side effects expression */
2634 case 'a' ... 'z': case 'A' ... 'Z': case '_':
2635 (void)identifier(ch);
2639 if (skipws() != '$')
2640 error("expecting symbol");
2641 /* allow spaces before an expression */
2645 if (parser.string[1] == '\0') {
2646 switch (parser.string[0]) {
2647 case 'c': get_data(type_c); break;
2648 case 's': get_data(type_s); break;
2649 case 'i': get_data(type_i); break;
2650 case 'l': get_data(type_l); break;
2651 case 'f': get_data(type_f); break;
2652 case 'd': get_data(type_d); break;
2653 case 'p': get_data(type_p); break;
2654 default: error("bad type .%c", parser.string[0]);
2657 else if (strcmp(parser.string, "data") == 0) {
2658 if (parser.parsing != PARSING_NONE)
2659 error(".data must be specified once and be the first section");
2660 parser.parsing = PARSING_DATA;
2661 data_length = get_int(skip_ws);
2662 data = (char *)xcalloc(1, data_length);
2664 else if (strcmp(parser.string, "code") == 0) {
2665 if (parser.parsing != PARSING_NONE &&
2666 parser.parsing != PARSING_DATA)
2667 error(".code must be specified once only");
2668 parser.parsing = PARSING_CODE;
2670 else if (strcmp(parser.string, "align") == 0) {
2671 length = get_int(skip_ws);
2672 if (parser.parsing != PARSING_DATA)
2673 error(".align must be in .data");
2674 if (length > 1 && length <= 4096 && !(length & (length - 1))) {
2675 offset = data_offset;
2676 offset += length - ((offset + length) % length);
2677 check_data(offset - data_offset);
2678 data_offset = offset;
2681 error("bad .align %ld (must be a power of 2, >= 2 && <= 4096)",
2682 (jit_word_t)length);
2684 else if (strcmp(parser.string, "size") == 0) {
2685 length = get_int(skip_ws);
2686 if (parser.parsing != PARSING_DATA)
2687 error(".size must be in .data");
2689 data_offset += length;
2691 else if (strcmp(parser.string, "disasm") == 0)
2694 error("unknown command .%s", parser.string);
2698 /* Workaround bug in a few patterns in MSYS64 library;
2699 * below is liberty implementation slightly modified. */
2701 liberty_strtoul(const char *nptr, char **endptr, register int base)
2703 register const char *s = nptr;
2704 register jit_uword_t acc;
2706 register jit_uword_t cutoff;
2707 register int neg = 0, any, cutlim;
2710 * See strtol for comments as to the logic used.
2714 } while (c == ' ' || c == '\t');
2718 } else if (c == '+')
2720 if ((base == 0 || base == 16) &&
2721 c == '0' && (*s == 'x' || *s == 'X')) {
2727 base = c == '0' ? 8 : 10;
2728 cutoff = (jit_uword_t)~0LL / (jit_uword_t)base;
2729 cutlim = (jit_uword_t)~0LL % (jit_uword_t)base;
2730 for (acc = 0, any = 0;; c = *s++) {
2731 if (c >= '0' && c <= '9')
2733 else if ((c >= 'a' && c <= 'z') ||
2734 (c >= 'A' && c <= 'Z'))
2735 c -= (c >= 'A' && c <= 'Z') ? 'A' - 10 : 'a' - 10;
2740 if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
2754 *endptr = (char *) (any ? s - 1 : nptr);
2762 char buffer[1024], *endptr;
2763 int integer = 1, offset = 0, neg = 0, e = 0, d = 0, base = 10;
2765 for (;; ch = getch()) {
2772 if (offset && buffer[offset - 1] != 'e') {
2780 if (offset && buffer[offset - 1] != 'e') {
2793 if (offset == 0 && base == 10) {
2799 if (offset == 0 && base == 8) {
2817 if (offset == 0 && base == 8) {
2822 case 'a': case 'c': case 'd': case 'f':
2835 case '_': case 'g' ... 'w': case 'y': case 'z': case 'A' ... 'Z':
2837 buffer[offset++] = '\0';
2838 error("bad constant %s", buffer);
2843 if (offset + 1 >= (int)sizeof(buffer))
2845 buffer[offset++] = ch;
2848 /* check for literal 0 */
2849 if (offset == 0 && base == 8) buffer[offset++] = '0';
2850 buffer[offset] = '\0';
2853 # define STRTOUL liberty_strtoul
2855 # define STRTOUL strtoul
2857 parser.value.ui = STRTOUL(buffer, &endptr, base);
2858 parser.type = type_l;
2860 parser.value.i = -parser.value.i;
2863 parser.type = type_d;
2864 parser.value.d = strtod(buffer, &endptr);
2866 parser.value.d = -parser.value.d;
2871 return (integer ? tok_int : tok_float);
2878 case 'a': ch = '\a'; break;
2879 case 'b': ch = '\b'; break;
2880 case 'f': ch = '\f'; break;
2881 case 'n': ch = '\n'; break;
2882 case 'r': ch = '\r'; break;
2883 case 't': ch = '\t'; break;
2884 case 'v': ch = '\v'; break;
2896 for (parser.offset = 0;;) {
2897 switch (ch = getch_noeof()) {
2899 if (esc) goto append;
2904 parser.string[parser.offset++] = '\0';
2905 parser.value.p = parser.string;
2906 parser.type = type_p;
2907 return (tok_string);
2916 if (parser.offset + 1 >= parser.length) {
2917 parser.length += 4096;
2918 parser.string = (char *)xrealloc(parser.string,
2921 parser.string[parser.offset++] = ch;
2932 if ((ch = getch_noeof()) == '\\') {
2936 if (getch_noeof() != '\'')
2937 error("bad single byte char");
2940 parser.type = type_l;
2941 parser.value.i = ch & 0xff;
2952 (void)identifier('@');
2953 if ((label = get_label_by_name(parser.string)) == NULL) {
2954 #if __CYGWIN__ ||_WIN32
2955 /* FIXME kludge to pass varargs test case, otherwise,
2956 * will not print/scan float values */
2957 if (strcmp(parser.string + 1, "sprintf") == 0)
2959 else if (strcmp(parser.string + 1, "sscanf") == 0)
2964 value = dlsym(DL_HANDLE, parser.string + 1);
2965 if ((string = dlerror()))
2966 error("%s", string);
2968 label = new_label(label_kind_dynamic, parser.string, value);
2970 parser.type = type_p;
2971 parser.value.p = label->value;
2973 return (tok_pointer);
2977 expression_prim(void)
2984 if (parser.putback) {
2985 parser.expr = parser.putback;
2986 parser.putback = (expr_t)0;
2989 switch (ch = skipws()) {
2991 if ((ch = getch_noeof()) == '=') parser.expr = expr_ne;
2993 ungetch(ch); parser.expr = expr_not;
2996 case '~': parser.expr = expr_com;
2999 if ((ch = getch_noeof()) == '=') parser.expr = expr_mulset;
3001 ungetch(ch); parser.expr = expr_mul;
3005 if ((ch = getch_noeof()) == '=') parser.expr = expr_divset;
3007 ungetch(ch); parser.expr = expr_div;
3011 if ((ch = getch_noeof()) == '=') parser.expr = expr_remset;
3013 ungetch(ch); parser.expr = expr_rem;
3017 switch (ch = getch_noeof()) {
3018 case '+': parser.expr = expr_inc;
3020 case '=': parser.expr = expr_addset;
3022 default: ungetch(ch); parser.expr = expr_add;
3027 switch (ch = getch_noeof()) {
3028 case '-': parser.expr = expr_dec;
3030 case '=': parser.expr = expr_subset;
3032 default: ungetch(ch); parser.expr = expr_sub;
3037 switch (ch = getch_noeof()) {
3038 case '=': parser.expr = expr_le;
3040 case '<': ch = getch_noeof();
3041 if (ch == '=') parser.expr = expr_lshset;
3043 ungetch(ch); parser.expr = expr_lsh;
3046 default: ungetch(ch); parser.expr = expr_lt;
3051 switch (ch = getch_noeof()) {
3052 case '=': parser.expr = expr_ge;
3054 case '>': ch = getch_noeof();
3055 if (ch == '=') parser.expr = expr_rshset;
3057 ungetch(ch); parser.expr = expr_rsh;
3060 default: ungetch(ch); parser.expr = expr_gt;
3065 switch (ch = getch_noeof()) {
3066 case '=': parser.expr = expr_andset;
3068 case '&': parser.expr = expr_andand;
3070 default: ungetch(ch); parser.expr = expr_and;
3075 switch (ch = getch_noeof()) {
3076 case '=': parser.expr = expr_orset;
3078 case '|': parser.expr = expr_oror;
3080 default: ungetch(ch); parser.expr = expr_or;
3085 if ((ch = getch_noeof()) == '=') parser.expr = expr_xorset;
3087 ungetch(ch); parser.expr = expr_xor;
3091 if ((ch = getch_noeof()) == '=') parser.expr = expr_eq;
3093 ungetch(ch); parser.expr = expr_set;
3096 case '(': parser.expr = expr_lparen;
3098 case ')': parser.expr = expr_rparen;
3102 parser.expr = token == tok_int ? expr_int : expr_float;
3106 parser.expr = expr_pointer;
3110 /* no support for nested expressions */
3111 if (parser.string[0] == '\0')
3112 error("syntax error");
3113 parser.expr = expr_symbol;
3114 if ((symbol = get_symbol_by_name(parser.string)) != NULL) {
3115 parser.type = symbol->type;
3116 parser.value = symbol->value;
3119 /* only create symbol on assignment */
3120 parser.type = type_none;
3122 case 'a' ... 'z': case 'A' ... 'Z': case '_':
3124 if ((label = get_label_by_name(parser.string))) {
3125 if (label->kind == label_kind_code_forward)
3126 error("forward value for %s not supported",
3128 parser.expr = expr_pointer;
3129 parser.type = type_p;
3130 parser.value.p = label->value;
3133 error("invalid identifier %s", parser.string);
3137 parser.expr = expr_int;
3140 /* not smart enough to put it in data and/or relocate it, etc */
3141 error("must declare strings as data");
3143 error("syntax error");
3148 expression_inc(int pre)
3154 if (parser.expr != expr_symbol)
3155 error("syntax error");
3157 if ((symbol = get_symbol_by_name(parser.string)) == NULL) {
3158 if (!parser.short_circuit)
3159 error("undefined symbol %s", symbol->name);
3161 if (!parser.short_circuit) {
3162 parser.type = symbol->type;
3164 parser.value = symbol->value;
3165 switch (symbol->type) {
3170 /* should really be an error */
3171 symbol->value.d += 1.0;
3178 parser.value = symbol->value;
3184 expression_dec(int pre)
3190 if (parser.expr != expr_symbol)
3191 error("syntax error");
3193 if ((symbol = get_symbol_by_name(parser.string)) == NULL) {
3194 if (!parser.short_circuit)
3195 error("undefined symbol %s", symbol->name);
3197 if (!parser.short_circuit) {
3198 parser.type = symbol->type;
3200 parser.value = symbol->value;
3201 switch (symbol->type) {
3206 /* should really be an error */
3207 symbol->value.d -= 1.0;
3214 parser.value = symbol->value;
3220 expression_unary(void)
3226 switch (parser.expr) {
3229 switch (parser.type) {
3234 error("syntax error");
3239 switch (parser.type) {
3241 parser.value.i = -parser.value.i;
3244 parser.value.d = -parser.value.d;
3247 error("syntax error");
3258 switch (parser.type) {
3260 parser.value.i = !parser.value.i;
3263 parser.value.i = parser.value.d != 0;
3266 parser.value.i = parser.value.p != NULL;
3269 error("syntax error");
3271 parser.type = type_l;
3275 if (parser.type != type_l)
3276 error("syntax error");
3277 parser.value.i = ~parser.value.i;
3281 if (parser.expr != expr_rparen)
3282 error("syntax error");
3286 strcpy(buffer, parser.string);
3288 switch (parser.expr) {
3290 if ((symbol = get_symbol_by_name(buffer)) == NULL) {
3291 if (!parser.short_circuit)
3292 symbol = new_symbol(buffer);
3296 if (!parser.short_circuit) {
3298 error("syntax error");
3299 symbol->type = parser.type;
3300 symbol->value = parser.value;
3303 case expr_mulset: parser.putback = expr_mul;
3305 case expr_divset: parser.putback = expr_div;
3307 case expr_remset: parser.putback = expr_rem;
3309 case expr_addset: parser.putback = expr_add;
3311 case expr_subset: parser.putback = expr_sub;
3313 case expr_lshset: parser.putback = expr_lsh;
3315 case expr_rshset: parser.putback = expr_rsh;
3317 case expr_andset: parser.putback = expr_and;
3319 case expr_orset: parser.putback = expr_or;
3321 case expr_xorset: parser.putback = expr_xor;
3323 if ((symbol = get_symbol_by_name(buffer)) == NULL) {
3324 if (!parser.short_circuit)
3325 error("undefined symbol %s", buffer);
3326 parser.type = type_l;
3329 switch (parser.putback) {
3330 case expr_mul: case expr_div: case expr_rem:
3333 case expr_add: case expr_sub:
3336 case expr_lsh: case expr_rsh:
3339 case expr_and: case expr_or: case expr_xor:
3359 /* make next token available */
3367 expression_mul(void)
3373 switch (parser.type) {
3374 case type_l: case type_d: case type_p: break;
3378 switch (parser.expr) {
3380 type = parser.type, value = parser.value;
3382 switch (parser.type) {
3385 value.i *= parser.value.i;
3387 value.d *= parser.value.i;
3390 if (type == type_l) {
3394 value.d *= parser.value.d;
3397 error("invalid operand");
3399 parser.type = type, parser.value = value;
3402 type = parser.type, value = parser.value;
3404 switch (parser.type) {
3406 if (type == type_l) {
3407 if (parser.value.i == 0)
3408 error("divide by zero");
3409 value.i /= parser.value.i;
3412 value.d /= parser.value.i;
3415 if (type == type_l) {
3419 value.d /= parser.value.d;
3422 error("invalid operand");
3424 parser.type = type, parser.value = value;
3427 type = parser.type, value = parser.value;
3429 switch (parser.type) {
3431 if (type == type_l) {
3432 if (parser.value.i == 0)
3433 error("divide by zero");
3434 value.i %= parser.value.i;
3437 error("invalid operand");
3440 error("invalid operand");
3442 parser.type = type, parser.value = value;
3451 expression_add(void)
3457 switch (parser.type) {
3458 case type_l: case type_d: case type_p: break;
3462 switch (parser.expr) {
3464 type = parser.type, value = parser.value;
3466 switch (parser.type) {
3470 value.i += parser.value.i;
3473 value.d += parser.value.i;
3476 value.cp += parser.value.i;
3489 error("invalid operand");
3491 value.d += parser.value.d;
3497 value.cp = value.i + parser.value.cp;
3500 error("invalid operand");
3504 error("invalid operand");
3506 parser.type = type, parser.value = value;
3509 type = parser.type, value = parser.value;
3511 switch (parser.type) {
3515 value.i -= parser.value.i;
3518 value.d -= parser.value.i;
3521 value.cp -= parser.value.i;
3534 error("invalid operand");
3536 value.d -= parser.value.d;
3542 value.i = value.cp - parser.value.cp;
3545 error("invalid operand");
3549 error("invalid operand");
3551 parser.type = type, parser.value = value;
3560 expression_shift(void)
3565 switch (parser.type) {
3566 case type_l: case type_d: case type_p: break;
3570 switch (parser.expr) {
3572 value = parser.value.i;
3573 if (parser.type != type_l)
3574 error("invalid operand");
3576 if (parser.type != type_l)
3577 error("invalid operand");
3578 value <<= parser.value.i;
3579 parser.value.i = value;
3582 value = parser.value.i;
3583 if (parser.type != type_l)
3584 error("invalid operand");
3586 if (parser.type != type_l)
3587 error("invalid operand");
3588 value >>= parser.value.i;
3589 parser.value.i = value;
3598 expression_bit(void)
3603 switch (parser.type) {
3604 case type_l: case type_d: case type_p: break;
3608 switch (parser.expr) {
3610 if (parser.type != type_l)
3611 error("invalid operand");
3614 if (parser.type != type_l)
3615 error("invalid operand");
3616 i &= parser.value.i;
3620 if (parser.type != type_l)
3621 error("invalid operand");
3624 if (parser.type != type_l)
3625 error("invalid operand");
3626 i |= parser.value.i;
3630 if (parser.type != type_l)
3631 error("invalid operand");
3634 if (parser.type != type_l)
3635 error("invalid operand");
3636 i ^= parser.value.i;
3646 expression_rel(void)
3652 switch (parser.type) {
3653 case type_l: case type_d: case type_p: break;
3657 switch (parser.expr) {
3659 type = parser.type, value = parser.value;
3661 switch (parser.type) {
3665 value.i = value.i < parser.value.i;
3668 value.i = value.d < parser.value.i;
3671 value.i = (jit_word_t)value.p < parser.value.i;
3678 value.i = value.i < parser.value.d;
3681 value.i = value.d < parser.value.d;
3684 error("invalid operand");
3690 value.i = value.i < (jit_word_t)parser.value.p;
3693 error("invalid operand");
3695 value.i = (jit_word_t)value.p < (jit_word_t)parser.value.p;
3700 error("invalid operand");
3702 parser.type = type_l, parser.value = value;
3705 type = parser.type, value = parser.value;
3707 switch (parser.type) {
3711 value.i = value.i <= parser.value.i;
3714 value.i = value.d <= parser.value.i;
3717 value.i = (jit_word_t)value.p <= parser.value.i;
3724 value.i = value.i <= parser.value.d;
3727 value.i = value.d <= parser.value.d;
3730 value.i = (jit_word_t)value.p <= parser.value.d;
3737 value.i = value.i <= (jit_word_t)parser.value.p;
3740 error("invalid operand");
3742 value.i = (jit_word_t)value.p <= (jit_word_t)parser.value.p;
3747 error("invalid operand");
3749 parser.type = type_l, parser.value = value;
3752 type = parser.type, value = parser.value;
3754 switch (parser.type) {
3758 value.i = value.i == parser.value.i;
3761 value.i = value.d == parser.value.i;
3764 value.i = (jit_word_t)value.p == parser.value.i;
3771 value.i = value.i == parser.value.d;
3774 value.i = value.d == parser.value.d;
3777 error("invalid operand");
3783 value.i = value.i == (jit_word_t)parser.value.p;
3786 error("invalid operand");
3788 value.i = value.p == parser.value.p;
3793 error("invalid operand");
3795 parser.type = type_l, parser.value = value;
3798 type = parser.type, value = parser.value;
3800 switch (parser.type) {
3804 value.i = value.i >= parser.value.i;
3807 value.i = value.d >= parser.value.i;
3810 value.i = (jit_word_t)value.p >= parser.value.i;
3817 value.i = value.i >= parser.value.d;
3820 value.i = value.d >= parser.value.d;
3823 error("invalid operand");
3829 value.i = value.i >= (jit_word_t)parser.value.p;
3832 error("invalid operand");
3834 value.i = (jit_word_t)value.p >= (jit_word_t)parser.value.p;
3839 error("invalid operand");
3841 parser.type = type_l, parser.value = value;
3844 type = parser.type, value = parser.value;
3846 switch (parser.type) {
3850 value.i = value.i > parser.value.i;
3853 value.i = value.d > parser.value.i;
3856 value.i = (jit_word_t)value.p > parser.value.i;
3863 value.i = value.i > parser.value.d;
3866 value.i = value.d > parser.value.d;
3869 error("invalid operand");
3875 value.i = value.i > (jit_word_t)parser.value.p;
3878 error("invalid operand");
3880 value.i = (jit_word_t)value.p > (jit_word_t)parser.value.p;
3885 error("invalid operand");
3887 parser.type = type_l, parser.value = value;
3890 type = parser.type, value = parser.value;
3892 switch (parser.type) {
3896 value.i = value.i != parser.value.i;
3899 value.i = value.d != parser.value.i;
3902 value.i = (jit_word_t)value.p != parser.value.i;
3909 value.i = value.i != parser.value.d;
3912 value.i = value.d != parser.value.d;
3915 error("invalid operand");
3921 value.i = value.i != (jit_word_t)parser.value.p;
3924 error("invalid operand");
3926 value.i = value.p != parser.value.p;
3931 error("invalid operand");
3933 parser.type = type_l, parser.value = value;
3942 expression_cond(void)
3949 switch (parser.type) {
3950 case type_l: case type_d: case type_p: break;
3954 switch (parser.expr) {
3956 type = parser.type, value = parser.value;
3959 short_circuit = value.i == 0;
3962 short_circuit = value.d == 0.0;
3965 short_circuit = value.p == NULL;
3968 parser.short_circuit += short_circuit;
3970 parser.short_circuit -= short_circuit;
3971 switch (parser.type) {
3975 value.i = value.i && parser.value.i;
3978 value.i = value.d && parser.value.i;
3981 value.i = value.p && parser.value.i;
3988 value.i = value.i && parser.value.d;
3991 value.i = value.d && parser.value.d;
3994 value.i = value.p && parser.value.d;
4001 value.i = value.i && parser.value.p;
4004 value.i = value.d && parser.value.p;
4007 value.i = value.p && parser.value.p;
4012 error("invalid operand");
4014 parser.type = type_l, parser.value.i = value.i;
4017 type = parser.type, value = parser.value;
4020 short_circuit = value.i != 0;
4023 short_circuit = value.d != 0.0;
4026 short_circuit = value.p != NULL;
4029 parser.short_circuit += short_circuit;
4031 parser.short_circuit -= short_circuit;
4032 switch (parser.type) {
4036 value.i = value.i || parser.value.i;
4039 value.i = value.d || parser.value.i;
4042 value.i = value.p || parser.value.i;
4049 value.i = value.i || parser.value.d;
4052 value.i = value.d || parser.value.d;
4055 value.i = value.p || parser.value.d;
4062 value.i = value.i || parser.value.p;
4065 value.i = value.d || parser.value.p;
4068 value.i = value.p || parser.value.p;
4073 error("invalid operand");
4075 parser.type = type_l, parser.value.i = value.i;
4088 (void)identifier('$');
4089 if (parser.string[1] == '\0') {
4090 if (getch_noeof() != '(')
4091 error("bad symbol or expression");
4092 parser.type = type_none;
4094 if (parser.expr != expr_rparen)
4095 error("bad expression");
4096 switch (parser.type) {
4102 return (tok_pointer);
4104 error("bad expression");
4107 else if ((symbol = get_symbol_by_name(parser.string))) {
4108 switch (parser.type = symbol->type) {
4110 parser.value.i = symbol->value.i;
4113 parser.value.d = symbol->value.d;
4116 parser.value.p = symbol->value.p;
4117 return (tok_pointer);
4121 error("undefined symbol %s", parser.string);
4125 primary(skip_t skip)
4130 case skip_none: ch = getch(); break;
4131 case skip_ws: ch = skipws(); break;
4132 case skip_nl: ch = skipnl(); break;
4138 case 'a' ... 'z': case 'A' ... 'Z': case '_':
4139 return (identifier(ch));
4140 case '0' ... '9': case '+': case '-':
4141 return (number(ch));
4147 return (character());
4151 return (expression());
4155 return (tok_newline);
4157 return (tok_semicollon);
4159 error("syntax error");
4173 switch (token = primary(skip_nl)) {
4177 if ((label = get_label_by_name(parser.string))) {
4178 if (label->kind == label_kind_code_forward) {
4179 label->kind = label_kind_code;
4180 jit_link(label->value);
4181 jit_note(parser.name, parser.line);
4184 error("label %s: redefined", parser.string);
4187 if (parser.parsing == PARSING_DATA) {
4188 value = data + data_offset;
4189 label = new_label(label_kind_data,
4190 parser.string, value);
4192 else if (parser.parsing == PARSING_CODE) {
4193 value = jit_label();
4194 jit_note(parser.name, parser.line);
4195 label = new_label(label_kind_code,
4196 parser.string, value);
4199 error("label not in .code or .data");
4205 (instr_t *)get_hash(instrs, parser.string)) == NULL)
4206 error("unhandled symbol %s", parser.string);
4207 if (parser.parsing != PARSING_CODE)
4208 error(".code must be specified before instructions");
4209 (*instr->function)();
4217 error("syntax error");
4223 execute(int argc, char *argv[])
4227 function_t function;
4228 patch_t *patch, *next;
4230 for (patch = patches; patch; patch = next) {
4232 label = patch->label;
4233 if (label->kind == label_kind_code_forward)
4234 error("undefined label %s", label->name);
4235 switch (patch->kind) {
4236 case patch_kind_jmp:
4237 case patch_kind_mov:
4238 case patch_kind_call:
4239 jit_patch_at(patch->value, label->value);
4248 if (flag_data == 0) {
4250 jit_set_data(NULL, 0, JIT_DISABLE_DATA | JIT_DISABLE_NOTE);
4253 function = jit_emit();
4254 if (flag_verbose > 1 || flag_disasm) {
4256 fprintf(stderr, " - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n");
4258 if (flag_verbose > 0 || flag_disasm) {
4260 fprintf(stderr, " - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n");
4262 if (flag_verbose && argc) {
4263 for (result = 0; result < argc; result++)
4264 printf("argv[%d] = %s\n", result, argv[result]);
4265 fprintf(stderr, " - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n");
4272 result = (*function)(argc, argv);
4273 jit_destroy_state();
4279 xmalloc(size_t size)
4281 void *pointer = malloc(size);
4283 if (pointer == NULL)
4284 error("out of memory");
4290 xrealloc(void *pointer, size_t size)
4292 pointer = realloc(pointer, size);
4294 if (pointer == NULL)
4295 error("out of memory");
4301 xcalloc(size_t nmemb, size_t size)
4303 void *pointer = calloc(nmemb, size);
4305 if (pointer == NULL)
4306 error("out of memory");
4312 new_label(label_kind_t kind, char *name, void *value)
4316 label = (label_t *)xmalloc(sizeof(label_t));
4318 label->name = strdup(name);
4319 label->value = value;
4320 put_hash(labels, (entry_t *)label);
4326 new_patch(patch_kind_t kind, label_t *label, void *value)
4328 patch_t *patch = (patch_t *)xmalloc(sizeof(patch_t));
4330 patch->label = label;
4331 patch->value = value;
4332 patch->next = patches;
4339 bcmp_symbols(const void *left, const void *right)
4341 return (strcmp((char *)left, (*(symbol_t **)right)->name));
4345 qcmp_symbols(const void *left, const void *right)
4347 return (strcmp((*(symbol_t **)left)->name, (*(symbol_t **)right)->name));
4351 new_symbol(char *name)
4355 if ((symbol_offset & 15) == 0) {
4356 if ((symbol_length += 16) == 16)
4357 symbols = (symbol_t **)xmalloc(sizeof(symbol_t *) *
4360 symbols = (symbol_t **)xrealloc(symbols, sizeof(symbol_t *) *
4363 symbol = (symbol_t *)xmalloc(sizeof(symbol_t));
4364 symbol->name = strdup(name);
4365 symbols[symbol_offset++] = symbol;
4366 qsort(symbols, symbol_offset, sizeof(symbol_t *), qcmp_symbols);
4372 get_symbol_by_name(char *name)
4374 symbol_t **symbol_pointer;
4376 if (symbols == NULL)
4378 symbol_pointer = (symbol_t **)bsearch(name, symbols, symbol_offset,
4379 sizeof(symbol_t *), bcmp_symbols);
4381 return (symbol_pointer ? *symbol_pointer : NULL);
4389 hash = (hash_t *)xmalloc(sizeof(hash_t));
4391 hash->entries = (entry_t **)xcalloc(hash->size = 32, sizeof(void *));
4397 hash_string(char *name)
4402 for (key = 0, ptr = name; *ptr; ptr++)
4403 key = (key << (key & 1)) ^ *ptr;
4409 put_hash(hash_t *hash, entry_t *entry)
4411 entry_t *prev, *ptr;
4412 int key = hash_string(entry->name) & (hash->size - 1);
4414 for (prev = ptr = hash->entries[key]; ptr; prev = ptr, ptr = ptr->next) {
4415 if (strcmp(entry->name, ptr->name) == 0)
4416 error("duplicated entry %s", entry->name);
4419 hash->entries[key] = entry;
4424 if (hash->count > hash->size * 0.75)
4429 get_hash(hash_t *hash, char *name)
4432 int key = hash_string(name) & (hash->size - 1);
4434 for (entry = hash->entries[key]; entry; entry = entry->next) {
4435 if (strcmp(entry->name, name) == 0)
4442 rehash(hash_t *hash)
4445 entry_t *entry, *next, **entries;
4447 entries = (entry_t **)xcalloc(size = hash->size * 2, sizeof(void *));
4448 for (i = 0; i < hash->size; i++) {
4449 for (entry = hash->entries[i]; entry; entry = next) {
4451 key = hash_string(entry->name) & (size - 1);
4452 entry->next = entries[key];
4453 entries[key] = entry;
4456 free(hash->entries);
4457 hash->entries = entries;
4464 #if HAVE_GETOPT_LONG_ONLY
4466 Usage: %s [jit assembler options] file [--] [jit program options]\n\
4467 Jit assembler options:\n\
4468 -help Display this information\n\
4469 -v[0-3] Verbose output level\n\
4470 -d Do not use a data buffer\n"
4471 # if defined(__i386__) && __WORDSIZE == 32
4472 " -mx87=1 Force using x87 when sse2 available\n"
4474 # if defined(__i386__) || defined(__x86_64__)
4475 " -msse4_1=0 Do not use sse4_1 instructions when available\n"
4477 # if defined(__arm__)
4478 " -mcpu=<val> Force cpu version (4, 5, 6 or 7)\n\
4479 -mthumb[=0|1] Enable or disable thumb\n\
4480 -mvfp=<val> Set vpf version (0 to disable)\n\
4481 -mneon[=0|1] Enable or disable neon\n"
4486 Usage: %s [jit assembler options] file [--] [jit program options]\n\
4487 Jit assembler options:\n\
4488 -h Display this information\n\
4489 -v Verbose output level\n", progname);
4496 main(int argc, char *argv[])
4498 #if HAVE_GETOPT_LONG_ONLY
4499 static const char *short_options = "dv::";
4500 static struct option long_options[] = {
4501 { "help", 0, 0, 'h' },
4502 { "data", 2, 0, 'd' },
4503 # if defined(__i386__) && __WORDSIZE == 32
4504 { "mx87", 2, 0, '7' },
4506 # if defined(__i386__) || defined(__x86_64__)
4507 { "msse4_1", 2, 0, '4' },
4509 # if defined(__arm__)
4510 { "mcpu", 2, 0, 'c' },
4511 { "mthumb", 2, 0, 't' },
4512 { "mvfp", 2, 0, 'f' },
4513 { "mneon", 2, 0, 'n' },
4518 #endif /* HAVE_GETOPT_LONG_ONLY */
4525 #if defined(__CYGWIN__)
4526 /* Cause a compile warning about redefinition without dllimport
4527 * attribute, *but* cause correct linkage if liblightning.a is
4528 * linked to binutils (that happens to have an internal
4529 * getopt* implementation and an apparently conflicting
4530 * optind global variable) */
4540 DL_HANDLE = dlopen(NULL, RTLD_LAZY);
4544 #if HAVE_GETOPT_LONG_ONLY
4546 if ((opt_short = getopt_long_only(argc, argv, short_options,
4547 long_options, &opt_index)) < 0)
4549 switch (opt_short) {
4556 flag_verbose = strtol(optarg, &endptr, 10);
4557 if (*endptr || flag_verbose < 0)
4566 #if defined(__i386__) && __WORDSIZE == 32
4569 if (strcmp(optarg, "") == 0 || strcmp(optarg, "1") == 0)
4571 else if (strcmp(optarg, "0"))
4578 #if defined(__i386__) || defined(__x86_64__)
4581 if (strcmp(optarg, "0") == 0)
4583 else if (strcmp(optarg, "1"))
4588 #if defined(__arm__)
4591 offset = strtol(optarg, &endptr, 10);
4592 if (*endptr || offset < 0)
4594 if (offset < jit_cpu.version)
4595 jit_cpu.version = offset;
4600 if (strcmp(optarg, "0") == 0)
4602 else if (strcmp(optarg, "1") && strcmp(optarg, "2"))
4607 # if !defined(__ARM_PCS_VFP)
4608 /* Do not allow overrinding hard float abi */
4610 offset = strtol(optarg, &endptr, 10);
4611 if (*endptr || offset < 0)
4613 if (offset < jit_cpu.vfp)
4614 jit_cpu.vfp = offset;
4620 if (strcmp(optarg, "0") == 0)
4622 else if (strcmp(optarg, "1"))
4630 while ((opt_short = getopt(argc, argv, "hvd")) >= 0) {
4631 if (opt_short == 'v')
4633 else if (opt_short == 'd')
4643 if (opt_index < argc && argv[opt_index][0] == '-')
4646 if (opt_index < 0 || opt_index >= argc)
4648 if (strcmp(argv[opt_index], "-") == 0)
4649 strcpy(parser.name, "<stdin>");
4651 if ((endptr = strrchr(argv[opt_index], '/')) == NULL)
4652 endptr = argv[opt_index];
4655 strncpy(parser.name, endptr, sizeof(parser.name));
4656 parser.name[sizeof(parser.name) - 1] = '\0';
4663 opt_short = snprintf(cmdline, sizeof(cmdline), cc " -E -x c %s", argv[opt_index]);
4664 opt_short += snprintf(cmdline + opt_short,
4665 sizeof(cmdline) - opt_short,
4666 " -D__WORDSIZE=%d", __WORDSIZE);
4667 opt_short += snprintf(cmdline + opt_short,
4668 sizeof(cmdline) - opt_short,
4669 " -D__LITTLE_ENDIAN=%d", __LITTLE_ENDIAN);
4670 opt_short += snprintf(cmdline + opt_short,
4671 sizeof(cmdline) - opt_short,
4672 " -D__BIG_ENDIAN=%d", __BIG_ENDIAN);
4673 opt_short += snprintf(cmdline + opt_short,
4674 sizeof(cmdline) - opt_short,
4675 " -D__BYTE_ORDER=%d", __BYTE_ORDER);
4676 #if defined(__i386__)
4677 opt_short += snprintf(cmdline + opt_short,
4678 sizeof(cmdline) - opt_short,
4681 #if defined(__x86_64__)
4682 opt_short += snprintf(cmdline + opt_short,
4683 sizeof(cmdline) - opt_short,
4686 #if defined(__mips__)
4687 opt_short += snprintf(cmdline + opt_short,
4688 sizeof(cmdline) - opt_short,
4690 opt_short += snprintf(cmdline + opt_short,
4691 sizeof(cmdline) - opt_short,
4692 " -D__mips_isa_rev=%d", jit_cpu.release);
4694 #if defined(__arm__)
4695 opt_short += snprintf(cmdline + opt_short,
4696 sizeof(cmdline) - opt_short,
4699 #if defined(__powerpc__)
4700 opt_short += snprintf(cmdline + opt_short,
4701 sizeof(cmdline) - opt_short,
4704 #if defined(__sparc__)
4705 opt_short += snprintf(cmdline + opt_short,
4706 sizeof(cmdline) - opt_short,
4709 #if defined(__ia64__)
4710 opt_short += snprintf(cmdline + opt_short,
4711 sizeof(cmdline) - opt_short,
4714 #if defined(__hppa__)
4715 opt_short += snprintf(cmdline + opt_short,
4716 sizeof(cmdline) - opt_short,
4720 opt_short += snprintf(cmdline + opt_short,
4721 sizeof(cmdline) - opt_short,
4724 #if defined(__sgi__)
4725 opt_short += snprintf(cmdline + opt_short,
4726 sizeof(cmdline) - opt_short,
4729 #if defined(__aarch64__)
4730 opt_short += snprintf(cmdline + opt_short,
4731 sizeof(cmdline) - opt_short,
4732 " -D__aarch64__=1");
4734 #if defined(__s390__) || defined(__s390x__)
4735 opt_short += snprintf(cmdline + opt_short,
4736 sizeof(cmdline) - opt_short,
4739 #if defined(__alpha__)
4740 opt_short += snprintf(cmdline + opt_short,
4741 sizeof(cmdline) - opt_short,
4744 #if defined(__loongarch__)
4745 opt_short += snprintf(cmdline + opt_short,
4746 sizeof(cmdline) - opt_short,
4747 " -D__loongarch__=1");
4749 if ((parser.fp = popen(cmdline, "r")) == NULL)
4750 error("cannot execute %s", cmdline);
4753 parser.string = (char *)xmalloc(parser.length = 4096);
4755 #if defined(__linux__) && (defined(__i386__) || defined(__x86_64__))
4756 /* double precision 0x200
4757 * round nearest 0x000
4758 * invalid operation mask 0x001
4759 * denormalized operand mask 0x002
4760 * zero divide mask 0x004
4761 * precision (inexact) mask 0x020
4764 fpu_control_t fpu_control = 0x027f;
4765 _FPU_SETCW(fpu_control);
4769 _jit = jit_new_state();
4771 instrs = new_hash();
4773 offset < (int)(sizeof(instr_vector) / sizeof(instr_vector[0]));
4775 put_hash(instrs, (entry_t *)(instr_vector + offset));
4777 labels = new_hash();
4783 for (opt_short = 0; opt_index < argc; opt_short++, opt_index++)
4784 argv[opt_short] = argv[opt_index];
4785 argv[opt_short] = NULL;
4787 execute(argc, argv);