Update lightrec 20220910 (#686)
[pcsx_rearmed.git] / deps / lightning / check / lightning.c
1 /*
2  * Copyright (C) 2012-2019  Free Software Foundation, Inc.
3  *
4  * This file is part of GNU lightning.
5  *
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)
9  * any later version.
10  *
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.
15  *
16  * Authors:
17  *      Paulo Cesar Pereira de Andrade
18  */
19
20 #if HAVE_CONFIG_H
21 # include "config.h"
22 #endif
23
24 #if HAVE_GETOPT_H
25 #  include <getopt.h>
26 #else
27 #  include <unistd.h>
28 #endif
29 #include <stdio.h>
30 #include <stdarg.h>
31 #include <lightning.h>
32 #include <dlfcn.h>
33 #include <math.h>
34
35 #if defined(__linux__) && (defined(__i386__) || defined(__x86_64__))
36 #  include <fpu_control.h>
37 #endif
38
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
42 #endif
43
44 #if defined(__hpux)
45 #  define DL_HANDLE             RTLD_NEXT
46 #elif defined(__sgi)
47 static void                     *DL_HANDLE;
48 #elif defined(__osf__)
49 #  define DL_HANDLE             NULL
50 #else
51 #  define DL_HANDLE             RTLD_DEFAULT
52 #endif
53
54 #if defined(__GNUC__)
55 #  define noreturn              __attribute__ ((noreturn))
56 #  define printf_format(f, v)   __attribute__ ((format (printf, f, v)))
57 #  define maybe_unused          __attribute__ ((unused))
58 #else
59 #  define noreturn              /**/
60 #  define printf_format(f, v)   /**/
61 #  define maybe_unused          /**/
62 #endif
63
64 #define check_data(length)                                              \
65     do {                                                                \
66         if (data_offset + length > data_length)                         \
67             error(".data too small (%ld < %ld)",                        \
68                   data_length, data_offset + length);                   \
69     } while (0)
70
71 #define get_label_by_name(name) ((label_t *)get_hash(labels, name))
72
73 #define PARSING_NONE            0
74 #define PARSING_DATA            1
75 #define PARSING_CODE            2
76 #define MAX_IDENTIFIER          256
77
78 /*
79  * Types
80  */
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[]);
90
91 typedef enum {
92     tok_eof = -1,
93     tok_symbol,
94     tok_char,
95     tok_int,
96     tok_float,
97     tok_pointer,
98     tok_string,
99     tok_register,
100     tok_dot,
101     tok_newline,
102     tok_semicollon,
103 } token_t;
104
105 typedef enum {
106     skip_none,
107     skip_ws,
108     skip_nl,
109 } skip_t;
110
111 typedef enum {
112     type_none,
113     type_c,
114     type_s,
115     type_i,
116     type_l,
117     type_f,
118     type_d,
119     type_p,
120 } type_t;
121
122 #define compose(a, b)           (((a) << 8) | b)
123 typedef enum {
124     expr_inc     = compose('+', '+'),
125     expr_dec     = compose('-', '-'),
126     expr_not     = '!',
127     expr_com     = '~',
128     expr_mul     = '*',
129     expr_div     = '/',
130     expr_rem     = '%',
131     expr_add     = '+',
132     expr_sub     = '-',
133     expr_lsh     = compose('<', '<'),
134     expr_rsh     = compose('>', '>'),
135     expr_and     = '&',
136     expr_or      = '|',
137     expr_xor     = '^',
138     expr_set     = '=',
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('^', '='),
149     expr_lt      = '<',
150     expr_le      = compose('<', '='),
151     expr_eq      = compose('=', '='),
152     expr_ne      = compose('!', '='),
153     expr_gt      = '>',
154     expr_ge      = compose('>', '='),
155     expr_andand  = compose('&', '&'),
156     expr_oror    = compose('|', '|'),
157     expr_lparen  = '(',
158     expr_rparen  = ')',
159     expr_int     = '0',
160     expr_float   = '.',
161     expr_pointer = '@',
162     expr_symbol  = '$',
163 } expr_t;
164 #undef compose
165
166 struct instr {
167     instr_t              *next;
168     const char           *name;
169     void                (*function)(void);
170     int                   flag;
171 };
172
173 union value {
174     jit_word_t           i;
175     jit_uword_t          ui;
176     float                f;
177     double               d;
178     void                *p;
179     char                *cp;
180     label_t             *label;
181     patch_t             *patch;
182 };
183
184 struct parser {
185     FILE                *fp;
186     char                 name[256];
187     int                  line;
188     int                  regval;
189     type_t               regtype;
190     expr_t               expr;
191     type_t               type;
192     value_t              value;
193
194     /* variable length string buffer */
195     char                *string;
196     int                  length;
197     int                  offset;
198
199     int                  newline;
200     expr_t               putback;
201     int                  short_circuit;
202     int                  parsing;
203
204     struct {
205         unsigned char    buffer[4096];
206         int              offset;
207         int              length;
208     } data;
209 };
210
211 typedef enum {
212     label_kind_data,
213     label_kind_code,
214     label_kind_code_forward,
215     label_kind_dynamic,
216 } label_kind_t;
217
218 struct hash {
219     entry_t             **entries;
220     int                   size;
221     int                   count;
222 };
223
224 struct entry {
225     entry_t              *next;
226     char                 *name;
227     void                 *value;
228     int                   flag;
229 };
230
231 struct label {
232     label_t             *next;
233     char                *name;
234     void                *value;
235     label_kind_t         kind;
236 };
237
238 typedef enum {
239     patch_kind_jmp,
240     patch_kind_mov,
241     patch_kind_call,
242 } patch_kind_t;
243
244 struct patch {
245     patch_t             *next;
246     label_t             *label;
247     void                *value;
248     patch_kind_t         kind;
249 };
250
251 /* minor support for expressions */
252 struct symbol {
253     symbol_t            *next;
254     char                *name;
255     value_t              value;
256     type_t               type;
257 };
258
259 /*
260  * Prototypes
261  */
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 prolog(void);
274 static void frame(void);        static void tramp(void);
275 static void ellipsis(void);
276 static void allocai(void);      static void allocar(void);
277 static void arg(void);
278 static void getarg_c(void);     static void getarg_uc(void);
279 static void getarg_s(void);     static void getarg_us(void);
280 static void getarg_i(void);
281 #if __WORDSIZE == 64
282 static void getarg_ui(void);    static void getarg_l(void);
283 #endif
284 static void getarg(void);
285 static void putargr(void);      static void putargi(void);
286 static void addr(void);         static void addi(void);
287 static void addxr(void);        static void addxi(void);
288 static void addcr(void);        static void addci(void);
289 static void subr(void);         static void subi(void);
290 static void subxr(void);        static void subxi(void);
291 static void subcr(void);        static void subci(void);
292 static void rsbr(void);         static void rsbi(void);
293 static void mulr(void);         static void muli(void);
294 static void qmulr(void);        static void qmuli(void);
295 static void qmulr_u(void);      static void qmuli_u(void);
296 static void divr(void);         static void divi(void);
297 static void divr_u(void);       static void divi_u(void);
298 static void qdivr(void);        static void qdivi(void);
299 static void qdivr_u(void);      static void qdivi_u(void);
300 static void remr(void);         static void remi(void);
301 static void remr_u(void);       static void remi_u(void);
302 static void andr(void);         static void andi(void);
303 static void orr(void);          static void ori(void);
304 static void xorr(void);         static void xori(void);
305 static void lshr(void);         static void lshi(void);
306 static void rshr(void);         static void rshi(void);
307 static void rshr_u(void);       static void rshi_u(void);
308 static void negr(void);         static void comr(void);
309 static void ltr(void);          static void lti(void);
310 static void ltr_u(void);        static void lti_u(void);
311 static void ler(void);          static void lei(void);
312 static void ler_u(void);        static void lei_u(void);
313 static void eqr(void);          static void eqi(void);
314 static void ger(void);          static void gei(void);
315 static void ger_u(void);        static void gei_u(void);
316 static void gtr(void);          static void gti(void);
317 static void gtr_u(void);        static void gti_u(void);
318 static void ner(void);          static void nei(void);
319 static void casr(void);         static void casi(void);
320 static void movr(void);         static void movi(void);
321 static void extr_c(void);       static void extr_uc(void);
322 static void extr_s(void);       static void extr_us(void);
323 #if __WORDSIZE == 64
324 static void extr_i(void);       static void extr_ui(void);
325 #endif
326 static void htonr_us(void);     static void ntohr_us(void);
327 static void htonr_ui(void);     static void ntohr_ui(void);
328 #if __WORDSIZE == 64
329 static void htonr_ul(void);     static void ntohr_ul(void);
330 #endif
331 static void htonr(void);        static void ntohr(void);
332 static void bswapr_us(void);    static void bswapr_ui(void);
333 #if __WORDSIZE == 64
334 static void bswapr_ul(void);
335 #endif
336 static void bswapr(void);
337 static void movnr(void);        static void movzr(void);
338 static void ldr_c(void);        static void ldi_c(void);
339 static void ldr_uc(void);       static void ldi_uc(void);
340 static void ldr_s(void);        static void ldi_s(void);
341 static void ldr_us(void);       static void ldi_us(void);
342 static void ldr_i(void);        static void ldi_i(void);
343 #if __WORDSIZE == 64
344 static void ldr_ui(void);       static void ldi_ui(void);
345 static void ldr_l(void);        static void ldi_l(void);
346 #endif
347 static void ldr(void);          static void ldi(void);
348 static void ldxr_c(void);       static void ldxi_c(void);
349 static void ldxr_uc(void);      static void ldxi_uc(void);
350 static void ldxr_s(void);       static void ldxi_s(void);
351 static void ldxr_us(void);      static void ldxi_us(void);
352 static void ldxr_i(void);       static void ldxi_i(void);
353 #if __WORDSIZE == 64
354 static void ldxr_ui(void);      static void ldxi_ui(void);
355 static void ldxr_l(void);       static void ldxi_l(void);
356 #endif
357 static void ldxr(void);         static void ldxi(void);
358 static void str_c(void);        static void sti_c(void);
359 static void str_s(void);        static void sti_s(void);
360 static void str_i(void);        static void sti_i(void);
361 #if __WORDSIZE == 64
362 static void str_l(void);        static void sti_l(void);
363 #endif
364 static void str(void);          static void sti(void);
365 static void stxr_c(void);       static void stxi_c(void);
366 static void stxr_s(void);       static void stxi_s(void);
367 static void stxr_i(void);       static void stxi_i(void);
368 #if __WORDSIZE == 64
369 static void stxr_l(void);       static void stxi_l(void);
370 #endif
371 static void stxr(void);         static void stxi(void);
372 static void bltr(void);         static void blti(void);
373 static void bltr_u(void);       static void blti_u(void);
374 static void bler(void);         static void blei(void);
375 static void bler_u(void);       static void blei_u(void);
376 static void beqr(void);         static void beqi(void);
377 static void bger(void);         static void bgei(void);
378 static void bger_u(void);       static void bgei_u(void);
379 static void bgtr(void);         static void bgti(void);
380 static void bgtr_u(void);       static void bgti_u(void);
381 static void bner(void);         static void bnei(void);
382 static void bmsr(void);         static void bmsi(void);
383 static void bmcr(void);         static void bmci(void);
384 static void boaddr(void);       static void boaddi(void);
385 static void boaddr_u(void);     static void boaddi_u(void);
386 static void bxaddr(void);       static void bxaddi(void);
387 static void bxaddr_u(void);     static void bxaddi_u(void);
388 static void bosubr(void);       static void bosubi(void);
389 static void bosubr_u(void);     static void bosubi_u(void);
390 static void bxsubr(void);       static void bxsubi(void);
391 static void bxsubr_u(void);     static void bxsubi_u(void);
392 static void jmpr(void);         static void jmpi(void);
393 static void callr(void);        static void calli(void);
394 static void prepare(void);
395 static void pushargr(void);     static void pushargi(void);
396 static void finishr(void);      static void finishi(void);
397 static void ret(void);
398 static void retr(void);         static void reti(void);
399 static void retval_c(void);     static void retval_uc(void);
400 static void retval_s(void);     static void retval_us(void);
401 static void retval_i(void);
402 #if __WORDSIZE == 64
403 static void retval_ui(void);    static void retval_l(void);
404 #endif
405 static void retval(void);
406 static void epilog(void);
407 static void arg_f(void);        static void getarg_f(void);
408 static void putargr_f(void);    static void putargi_f(void);
409 static void addr_f(void);       static void addi_f(void);
410 static void subr_f(void);       static void subi_f(void);
411 static void rsbr_f(void);       static void rsbi_f(void);
412 static void mulr_f(void);       static void muli_f(void);
413 static void divr_f(void);       static void divi_f(void);
414 static void negr_f(void);       static void absr_f(void);
415 static void sqrtr_f(void);
416 static void ltr_f(void);        static void lti_f(void);
417 static void ler_f(void);        static void lei_f(void);
418 static void eqr_f(void);        static void eqi_f(void);
419 static void ger_f(void);        static void gei_f(void);
420 static void gtr_f(void);        static void gti_f(void);
421 static void ner_f(void);        static void nei_f(void);
422 static void unltr_f(void);      static void unlti_f(void);
423 static void unler_f(void);      static void unlei_f(void);
424 static void uneqr_f(void);      static void uneqi_f(void);
425 static void unger_f(void);      static void ungei_f(void);
426 static void ungtr_f(void);      static void ungti_f(void);
427 static void ltgtr_f(void);      static void ltgti_f(void);
428 static void ordr_f(void);       static void ordi_f(void);
429 static void unordr_f(void);     static void unordi_f(void);
430 static void truncr_f_i(void);
431 #if __WORDSIZE == 64
432 static void truncr_f_l(void);
433 #endif
434 static void truncr_f(void);
435 static void extr_f(void);       static void extr_d_f(void);
436 static void movr_f(void);       static void movi_f(void);
437 static void ldr_f(void);        static void ldi_f(void);
438 static void ldxr_f(void);       static void ldxi_f(void);
439 static void str_f(void);        static void sti_f(void);
440 static void stxr_f(void);       static void stxi_f(void);
441 static void bltr_f(void);       static void blti_f(void);
442 static void bler_f(void);       static void blei_f(void);
443 static void beqr_f(void);       static void beqi_f(void);
444 static void bger_f(void);       static void bgei_f(void);
445 static void bgtr_f(void);       static void bgti_f(void);
446 static void bner_f(void);       static void bnei_f(void);
447 static void bunltr_f(void);     static void bunlti_f(void);
448 static void bunler_f(void);     static void bunlei_f(void);
449 static void buneqr_f(void);     static void buneqi_f(void);
450 static void bunger_f(void);     static void bungei_f(void);
451 static void bungtr_f(void);     static void bungti_f(void);
452 static void bltgtr_f(void);     static void bltgti_f(void);
453 static void bordr_f(void);      static void bordi_f(void);
454 static void bunordr_f(void);    static void bunordi_f(void);
455 static void pushargr_f(void);   static void pushargi_f(void);
456 static void retr_f(void);       static void reti_f(void);
457 static void retval_f(void);
458 static void arg_d(void);        static void getarg_d(void);
459 static void putargr_d(void);    static void putargi_d(void);
460 static void addr_d(void);       static void addi_d(void);
461 static void subr_d(void);       static void subi_d(void);
462 static void rsbr_d(void);       static void rsbi_d(void);
463 static void mulr_d(void);       static void muli_d(void);
464 static void divr_d(void);       static void divi_d(void);
465 static void negr_d(void);       static void absr_d(void);
466 static void sqrtr_d(void);
467 static void ltr_d(void);        static void lti_d(void);
468 static void ler_d(void);        static void lei_d(void);
469 static void eqr_d(void);        static void eqi_d(void);
470 static void ger_d(void);        static void gei_d(void);
471 static void gtr_d(void);        static void gti_d(void);
472 static void ner_d(void);        static void nei_d(void);
473 static void unltr_d(void);      static void unlti_d(void);
474 static void unler_d(void);      static void unlei_d(void);
475 static void uneqr_d(void);      static void uneqi_d(void);
476 static void unger_d(void);      static void ungei_d(void);
477 static void ungtr_d(void);      static void ungti_d(void);
478 static void ltgtr_d(void);      static void ltgti_d(void);
479 static void ordr_d(void);       static void ordi_d(void);
480 static void unordr_d(void);     static void unordi_d(void);
481 static void truncr_d_i(void);
482 #if __WORDSIZE == 64
483 static void truncr_d_l(void);
484 #endif
485 static void truncr_d(void);
486 static void extr_d(void);       static void extr_f_d(void);
487 static void movr_d(void);       static void movi_d(void);
488 static void ldr_d(void);        static void ldi_d(void);
489 static void ldxr_d(void);       static void ldxi_d(void);
490 static void str_d(void);        static void sti_d(void);
491 static void stxr_d(void);       static void stxi_d(void);
492 static void bltr_d(void);       static void blti_d(void);
493 static void bler_d(void);       static void blei_d(void);
494 static void beqr_d(void);       static void beqi_d(void);
495 static void bger_d(void);       static void bgei_d(void);
496 static void bgtr_d(void);       static void bgti_d(void);
497 static void bner_d(void);       static void bnei_d(void);
498 static void bunltr_d(void);     static void bunlti_d(void);
499 static void bunler_d(void);     static void bunlei_d(void);
500 static void buneqr_d(void);     static void buneqi_d(void);
501 static void bunger_d(void);     static void bungei_d(void);
502 static void bungtr_d(void);     static void bungti_d(void);
503 static void bltgtr_d(void);     static void bltgti_d(void);
504 static void bordr_d(void);      static void bordi_d(void);
505 static void bunordr_d(void);    static void bunordi_d(void);
506 static void pushargr_d(void);   static void pushargi_d(void);
507 static void retr_d(void);       static void reti_d(void);
508 static void retval_d(void);
509 static void vastart(void);      static void vapush(void);
510 static void vaarg(void);        static void vaarg_d(void);
511 static void vaend(void);
512
513 static void error(const char *format, ...) noreturn printf_format(1, 2);
514 static void warn(const char *format, ...) printf_format(1, 2) maybe_unused;
515 static void message(const char *kind, const char *format, va_list ap);
516
517 static int getch(void);
518 static int getch_noeof(void);
519 static int ungetch(int ch);
520 static int skipws(void);
521 static int skipnl(void);
522 static int skipct(void);
523 static int skipcp(void);
524 static jit_word_t get_int(skip_t skip);
525 static jit_uword_t get_uint(skip_t skip);
526 static double get_float(skip_t skip);
527 static float make_float(double d);
528 static void *get_pointer(skip_t skip);
529 static label_t *get_label(skip_t skip);
530 static token_t regname(void);
531 static token_t identifier(int ch);
532 static void get_data(type_t type);
533 static void dot(void);
534 static token_t number(int ch);
535 static int escape(int ch);
536 static token_t string(void);
537 static token_t dynamic(void);
538 static token_t character(void);
539 static void expression_prim(void);
540 static void expression_inc(int pre);
541 static void expression_dec(int pre);
542 static void expression_unary(void);
543 static void expression_mul(void);
544 static void expression_add(void);
545 static void expression_shift(void);
546 static void expression_bit(void);
547 static void expression_rel(void);
548 static void expression_cond(void);
549 static token_t expression(void);
550 static token_t primary(skip_t skip);
551 static void parse(void);
552 static int execute(int argc, char *argv[]);
553
554 static void *xmalloc(size_t size);
555 static void *xrealloc(void *pointer, size_t size);
556 static void *xcalloc(size_t nmemb, size_t size);
557
558 static label_t *new_label(label_kind_t kind, char *name, void *value);
559 static patch_t *new_patch(patch_kind_t kind, label_t *label, void *value);
560 static int bcmp_symbols(const void *left, const void *right);
561 static int qcmp_symbols(const void *left, const void *right);
562 static symbol_t *new_symbol(char *name);
563 static symbol_t *get_symbol_by_name(char *name);
564
565 static hash_t *new_hash(void);
566 static int hash_string(char *name);
567 static void put_hash(hash_t *hash, entry_t *entry);
568 static entry_t *get_hash(hash_t *hash, char *name);
569 static void rehash(hash_t *hash);
570
571 /*
572  * Initialization
573  */
574 static jit_state_t       *_jit;
575 static int                flag_verbose;
576 static int                flag_data;
577 static int                flag_disasm;
578 static char              *progname;
579 static parser_t           parser;
580 static hash_t            *labels;
581 static int                label_offset;
582 static patch_t           *patches;
583 static symbol_t         **symbols;
584 static int                symbol_length;
585 static int                symbol_offset;
586 static hash_t            *instrs;
587 static char              *data;
588 static size_t             data_offset, data_length;
589 static instr_t            instr_vector[] = {
590 #define entry(value)    { NULL, #value, value }
591 #define entry2(name, function)  { NULL, name, function }
592     entry(live),
593     entry(align),       entry(name),
594     entry(prolog),
595     entry(frame),       entry(tramp),
596     entry(ellipsis),
597     entry(allocai),     entry(allocar),
598     entry(arg),
599     entry(getarg_c),    entry(getarg_uc),
600     entry(getarg_s),    entry(getarg_us),
601     entry(getarg_i),
602 #if __WORDSIZE == 64
603     entry(getarg_ui),   entry(getarg_l),
604 #endif
605     entry(getarg),
606     entry(putargr),     entry(putargi),
607     entry(addr),        entry(addi),
608     entry(addxr),       entry(addxi),
609     entry(addcr),       entry(addci),
610     entry(subr),        entry(subi),
611     entry(subxr),       entry(subxi),
612     entry(subcr),       entry(subci),
613     entry(rsbr),        entry(rsbi),
614     entry(mulr),        entry(muli),
615     entry(qmulr),       entry(qmuli),
616     entry(qmulr_u),     entry(qmuli_u),
617     entry(divr),        entry(divi),
618     entry(divr_u),      entry(divi_u),
619     entry(qdivr),       entry(qdivi),
620     entry(qdivr_u),     entry(qdivi_u),
621     entry(remr),        entry(remi),
622     entry(remr_u),      entry(remi_u),
623     entry(andr),        entry(andi),
624     entry(orr),         entry(ori),
625     entry(xorr),        entry(xori),
626     entry(lshr),        entry(lshi),
627     entry(rshr),        entry(rshi),
628     entry(rshr_u),      entry(rshi_u),
629     entry(negr),        entry(comr),
630     entry(ltr),         entry(lti),
631     entry(ltr_u),       entry(lti_u),
632     entry(ler),         entry(lei),
633     entry(ler_u),       entry(lei_u),
634     entry(eqr),         entry(eqi),
635     entry(ger),         entry(gei),
636     entry(ger_u),       entry(gei_u),
637     entry(gtr),         entry(gti),
638     entry(gtr_u),       entry(gti_u),
639     entry(ner),         entry(nei),
640     entry(casr),        entry(casi),
641     entry(movr),        entry(movi),
642     entry(extr_c),      entry(extr_uc),
643     entry(extr_s),      entry(extr_us),
644 #if __WORDSIZE == 64
645     entry(extr_i),      entry(extr_ui),
646 #endif
647     entry(htonr_us),    entry(ntohr_us),
648     entry(htonr_ui),    entry(ntohr_ui),
649 #if __WORDSIZE == 64
650     entry(htonr_ul),    entry(ntohr_ul),
651 #endif
652     entry(htonr),       entry(ntohr),
653     entry(bswapr_us),   entry(bswapr_ui),
654 #if __WORDSIZE == 64
655     entry(bswapr_ul),
656 #endif
657     entry(bswapr),
658     entry(movnr),       entry(movzr),
659     entry(ldr_c),       entry(ldi_c),
660     entry(ldr_uc),      entry(ldi_uc),
661     entry(ldr_s),       entry(ldi_s),
662     entry(ldr_us),      entry(ldi_us),
663     entry(ldr_i),       entry(ldi_i),
664 #if __WORDSIZE == 64
665     entry(ldr_ui),      entry(ldi_ui),
666     entry(ldr_l),       entry(ldi_l),
667 #endif
668     entry(ldr),         entry(ldi),
669     entry(ldxr_c),      entry(ldxi_c),
670     entry(ldxr_uc),     entry(ldxi_uc),
671     entry(ldxr_s),      entry(ldxi_s),
672     entry(ldxr_us),     entry(ldxi_us),
673     entry(ldxr_i),      entry(ldxi_i),
674 #if __WORDSIZE == 64
675     entry(ldxr_ui),     entry(ldxi_ui),
676     entry(ldxr_l),      entry(ldxi_l),
677 #endif
678     entry(ldxr),        entry(ldxi),
679     entry(str_c),       entry(sti_c),
680     entry(str_s),       entry(sti_s),
681     entry(str_i),       entry(sti_i),
682 #if __WORDSIZE == 64
683     entry(str_l),       entry(sti_l),
684 #endif
685     entry(str),         entry(sti),
686     entry(stxr_c),      entry(stxi_c),
687     entry(stxr_s),      entry(stxi_s),
688     entry(stxr_i),      entry(stxi_i),
689 #if __WORDSIZE == 64
690     entry(stxr_l),      entry(stxi_l),
691 #endif
692     entry(stxr),        entry(stxi),
693     entry(bltr),        entry(blti),
694     entry(bltr_u),      entry(blti_u),
695     entry(bler),        entry(blei),
696     entry(bler_u),      entry(blei_u),
697     entry(beqr),        entry(beqi),
698     entry(bger),        entry(bgei),
699     entry(bger_u),      entry(bgei_u),
700     entry(bgtr),        entry(bgti),
701     entry(bgtr_u),      entry(bgti_u),
702     entry(bner),        entry(bnei),
703     entry(bmsr),        entry(bmsi),
704     entry(bmcr),        entry(bmci),
705     entry(boaddr),      entry(boaddi),
706     entry(boaddr_u),    entry(boaddi_u),
707     entry(bxaddr),      entry(bxaddi),
708     entry(bxaddr_u),    entry(bxaddi_u),
709     entry(bosubr),      entry(bosubi),
710     entry(bosubr_u),    entry(bosubi_u),
711     entry(bxsubr),      entry(bxsubi),
712     entry(bxsubr_u),    entry(bxsubi_u),
713     entry(jmpr),        entry(jmpi),
714     entry(callr),       entry(calli),
715     entry(prepare),
716     entry(pushargr),    entry(pushargi),
717     entry(finishr),     entry(finishi),
718     entry(ret),
719     entry(retr),        entry(reti),
720     entry(retval_c),    entry(retval_uc),
721     entry(retval_s),    entry(retval_us),
722     entry(retval_i),
723 #if __WORDSIZE == 64
724     entry(retval_ui),   entry(retval_l),
725 #endif
726     entry(retval),
727     entry(epilog),
728     entry(arg_f),       entry(getarg_f),
729     entry(putargr_f),   entry(putargi_f),
730     entry(addr_f),      entry(addi_f),
731     entry(subr_f),      entry(subi_f),
732     entry(rsbr_f),      entry(rsbi_f),
733     entry(mulr_f),      entry(muli_f),
734     entry(divr_f),      entry(divi_f),
735     entry(negr_f),      entry(absr_f),
736     entry(sqrtr_f),
737     entry(ltr_f),       entry(lti_f),
738     entry(ler_f),       entry(lei_f),
739     entry(eqr_f),       entry(eqi_f),
740     entry(ger_f),       entry(gei_f),
741     entry(gtr_f),       entry(gti_f),
742     entry(ner_f),       entry(nei_f),
743     entry(unltr_f),     entry(unlti_f),
744     entry(unler_f),     entry(unlei_f),
745     entry(uneqr_f),     entry(uneqi_f),
746     entry(unger_f),     entry(ungei_f),
747     entry(ungtr_f),     entry(ungti_f),
748     entry(ltgtr_f),     entry(ltgti_f),
749     entry(ordr_f),      entry(ordi_f),
750     entry(unordr_f),    entry(unordi_f),
751     entry(truncr_f_i),
752 #if __WORDSIZE == 64
753     entry(truncr_f_l),
754 #endif
755     entry(truncr_f),
756     entry(extr_f),      entry(extr_d_f),
757     entry(movr_f),      entry(movi_f),
758     entry(ldr_f),       entry(ldi_f),
759     entry(ldxr_f),      entry(ldxi_f),
760     entry(str_f),       entry(sti_f),
761     entry(stxr_f),      entry(stxi_f),
762     entry(bltr_f),      entry(blti_f),
763     entry(bler_f),      entry(blei_f),
764     entry(beqr_f),      entry(beqi_f),
765     entry(bger_f),      entry(bgei_f),
766     entry(bgtr_f),      entry(bgti_f),
767     entry(bner_f),      entry(bnei_f),
768     entry(bunltr_f),    entry(bunlti_f),
769     entry(bunler_f),    entry(bunlei_f),
770     entry(buneqr_f),    entry(buneqi_f),
771     entry(bunger_f),    entry(bungei_f),
772     entry(bungtr_f),    entry(bungti_f),
773     entry(bltgtr_f),    entry(bltgti_f),
774     entry(bordr_f),     entry(bordi_f),
775     entry(bunordr_f),   entry(bunordi_f),
776     entry(pushargr_f),  entry(pushargi_f),
777     entry(retr_f),      entry(reti_f),
778     entry(retval_f),
779     entry(arg_d),       entry(getarg_d),
780     entry(putargr_d),   entry(putargi_d),
781     entry(addr_d),      entry(addi_d),
782     entry(subr_d),      entry(subi_d),
783     entry(rsbr_d),      entry(rsbi_d),
784     entry(mulr_d),      entry(muli_d),
785     entry(divr_d),      entry(divi_d),
786     entry(negr_d),      entry(absr_d),
787     entry(sqrtr_d),
788     entry(ltr_d),       entry(lti_d),
789     entry(ler_d),       entry(lei_d),
790     entry(eqr_d),       entry(eqi_d),
791     entry(ger_d),       entry(gei_d),
792     entry(gtr_d),       entry(gti_d),
793     entry(ner_d),       entry(nei_d),
794     entry(unltr_d),     entry(unlti_d),
795     entry(unler_d),     entry(unlei_d),
796     entry(uneqr_d),     entry(uneqi_d),
797     entry(unger_d),     entry(ungei_d),
798     entry(ungtr_d),     entry(ungti_d),
799     entry(ltgtr_d),     entry(ltgti_d),
800     entry(ordr_d),      entry(ordi_d),
801     entry(unordr_d),    entry(unordi_d),
802     entry(truncr_d_i),
803 #if __WORDSIZE == 64
804     entry(truncr_d_l),
805 #endif
806     entry(truncr_d),
807     entry(extr_d),      entry(extr_f_d),
808     entry(movr_d),      entry(movi_d),
809     entry(ldr_d),       entry(ldi_d),
810     entry(ldxr_d),      entry(ldxi_d),
811     entry(str_d),       entry(sti_d),
812     entry(stxr_d),      entry(stxi_d),
813     entry(bltr_d),      entry(blti_d),
814     entry(bler_d),      entry(blei_d),
815     entry(beqr_d),      entry(beqi_d),
816     entry(bger_d),      entry(bgei_d),
817     entry(bgtr_d),      entry(bgti_d),
818     entry(bner_d),      entry(bnei_d),
819     entry(bunltr_d),    entry(bunlti_d),
820     entry(bunler_d),    entry(bunlei_d),
821     entry(buneqr_d),    entry(buneqi_d),
822     entry(bunger_d),    entry(bungei_d),
823     entry(bungtr_d),    entry(bungti_d),
824     entry(bltgtr_d),    entry(bltgti_d),
825     entry(bordr_d),     entry(bordi_d),
826     entry(bunordr_d),   entry(bunordi_d),
827     entry(pushargr_d),  entry(pushargi_d),
828     entry(retr_d),      entry(reti_d),
829     entry(retval_d),
830     entry2("va_start", vastart),
831     entry2("va_push", vapush),
832     entry2("va_arg", vaarg),
833     entry2("va_arg_d", vaarg_d),
834     entry2("va_end", vaend),
835 #undef entry
836 };
837
838 /*
839  * Implementation
840  */
841 static jit_gpr_t
842 get_ireg(void)
843 {
844     if (primary(skip_ws) != tok_register)
845         error("bad register");
846     if (parser.regtype != type_l)
847         error("bad int register");
848
849     return ((jit_gpr_t)parser.regval);
850 }
851
852 static jit_fpr_t
853 get_freg(void)
854 {
855     if (primary(skip_ws) != tok_register)
856         error("bad register");
857     if (parser.regtype != type_d)
858         error("bad float register");
859
860     return ((jit_fpr_t)parser.regval);
861 }
862
863 static symbol_t *
864 get_symbol(void)
865 {
866     symbol_t    *symbol;
867     int          ch = skipws();
868
869     if (ch != '$')
870         error("expecting variable");
871     (void)identifier('$');
872     if (parser.string[1] == '\0')
873         error("expecting variable");
874     if ((symbol = get_symbol_by_name(parser.string)) == NULL)
875         symbol = new_symbol(parser.string);
876
877     return (symbol);
878 }
879
880 static void
881 jmp_forward(void *value, label_t *label)
882 {
883     (void)new_patch(patch_kind_jmp, label, value);
884 }
885
886 static void
887 mov_forward(void *value, label_t *label)
888 {
889     (void)new_patch(patch_kind_mov, label, value);
890 }
891
892 static void
893 call_forward(void *value, label_t *label)
894 {
895     (void)new_patch(patch_kind_call, label, value);
896 }
897
898 static void
899 make_arg(void *value)
900 {
901     symbol_t    *symbol = get_symbol();
902
903     symbol->type = type_p;
904     symbol->value.p = value;
905 }
906
907 static jit_pointer_t
908 get_arg(void)
909 {
910     symbol_t    *symbol = get_symbol();
911
912     if (symbol->type != type_p)
913         error("bad argument %s type", symbol->name);
914
915     return symbol->value.p;
916 }
917
918 static jit_word_t
919 get_imm(void)
920 {
921     int          ch;
922     label_t     *label;
923     jit_word_t   value;
924     ch = skipws();
925     switch (ch) {
926         case '+': case '-': case '0' ... '9':
927             ungetch(ch);
928             value = get_int(skip_none);
929             break;
930         case '\'':
931             character();
932             value = parser.value.i;
933             break;
934         case '$':
935             switch (expression()) {
936                 case tok_int:
937                 case tok_pointer:
938                     value = parser.value.i;
939                     break;
940                 default:
941                     error("expecting immediate");
942             }
943             break;
944         case '@':
945             dynamic();
946             value = (jit_word_t)parser.value.p;
947             break;
948         default:
949             ungetch(ch);
950             label = get_label(skip_none);
951             if (label->kind == label_kind_data)
952                 value = (jit_word_t)label->value;
953             else
954                 error("expecting immediate");
955             break;
956     }
957     return (value);
958 }
959
960 #define entry(name)                                                     \
961 static void                                                             \
962 name(void)                                                              \
963 {                                                                       \
964     jit_##name();                                                       \
965 }
966 #define entry_ca(name)                                                  \
967 static void                                                             \
968 name(void)                                                              \
969 {                                                                       \
970     make_arg(jit_##name());                                             \
971 }
972 #define entry_ia(name)                                                  \
973 static void                                                             \
974 name(void)                                                              \
975 {                                                                       \
976     jit_gpr_t           r0 = get_ireg();                                \
977     jit_pointer_t       ac = get_arg();                                 \
978     jit_##name(r0, ac);                                                 \
979 }
980 #define entry_im(name)                                                  \
981 static void                                                             \
982 name(void)                                                              \
983 {                                                                       \
984     jit_word_t   im = get_imm();                                        \
985     jit_##name(im);                                                     \
986 }
987 #define entry_ir(name)                                                  \
988 static void                                                             \
989 name(void)                                                              \
990 {                                                                       \
991     jit_gpr_t    r0 = get_ireg();                                       \
992     jit_##name(r0);                                                     \
993 }
994 #define entry_ima(name)                                                 \
995 static void                                                             \
996 name(void)                                                              \
997 {                                                                       \
998     jit_word_t          im = get_imm();                                 \
999     jit_pointer_t       ac = get_arg();                                 \
1000     jit_##name(im, ac);                                                 \
1001 }
1002 #define entry_ir_ir_ir(name)                                            \
1003 static void                                                             \
1004 name(void)                                                              \
1005 {                                                                       \
1006     jit_gpr_t   r0 = get_ireg(), r1 = get_ireg(), r2 = get_ireg();      \
1007     jit_##name(r0, r1, r2);                                             \
1008 }
1009 #define entry_ir_ir_im(name)                                            \
1010 static void                                                             \
1011 name(void)                                                              \
1012 {                                                                       \
1013     jit_gpr_t   r0 = get_ireg(), r1 = get_ireg();                       \
1014     jit_word_t  im = get_imm();                                         \
1015     jit_##name(r0, r1, im);                                             \
1016 }
1017 #define entry_ir_ir_ir_ir(name)                                         \
1018 static void                                                             \
1019 name(void)                                                              \
1020 {                                                                       \
1021     jit_gpr_t   r0 = get_ireg(), r1 = get_ireg(),                       \
1022                 r2 = get_ireg(), r3 = get_ireg();                       \
1023     jit_##name(r0, r1, r2, r3);                                         \
1024 }
1025 #define entry_ir_ir_ir_im(name)                                         \
1026 static void                                                             \
1027 name(void)                                                              \
1028 {                                                                       \
1029     jit_gpr_t   r0 = get_ireg(), r1 = get_ireg(), r2 = get_ireg();      \
1030     jit_word_t  im = get_imm();                                         \
1031     jit_##name(r0, r1, r2, im);                                         \
1032 }
1033 #define entry_ir_im_ir_ir(name)                                         \
1034 static void                                                             \
1035 name(void)                                                              \
1036 {                                                                       \
1037     jit_gpr_t   r0 = get_ireg();                                        \
1038     jit_word_t  im = get_imm();                                         \
1039     jit_gpr_t r1 = get_ireg(), r2 = get_ireg();                         \
1040     jit_##name(r0, im, r1, r2);                                         \
1041 }
1042
1043 #define entry_ir_ir(name)                                               \
1044 static void                                                             \
1045 name(void)                                                              \
1046 {                                                                       \
1047     jit_gpr_t   r0 = get_ireg(), r1 = get_ireg();                       \
1048     jit_##name(r0, r1);                                                 \
1049 }
1050 #define entry_ir_im(name)                                               \
1051 static void                                                             \
1052 name(void)                                                              \
1053 {                                                                       \
1054     jit_gpr_t   r0 = get_ireg();                                        \
1055     jit_word_t  im = get_imm();                                         \
1056     jit_##name(r0, im);                                                 \
1057 }
1058 #define entry_ir_pm(name)                                               \
1059 static void                                                             \
1060 name(void)                                                              \
1061 {                                                                       \
1062     jit_gpr_t    r0 = get_ireg();                                       \
1063     void        *pm = get_pointer(skip_ws);                             \
1064     jit_##name(r0, pm);                                                 \
1065 }
1066 #define entry_pm_ir(name)                                               \
1067 static void                                                             \
1068 name(void)                                                              \
1069 {                                                                       \
1070     void        *pm = get_pointer(skip_ws);                             \
1071     jit_gpr_t    r0 = get_ireg();                                       \
1072     jit_##name(pm, r0);                                                 \
1073 }
1074 #define entry_im_ir_ir(name)                                            \
1075 static void                                                             \
1076 name(void)                                                              \
1077 {                                                                       \
1078     jit_word_t  im = get_imm();                                         \
1079     jit_gpr_t   r0 = get_ireg(), r1 = get_ireg();                       \
1080     (void)jit_##name(im, r0, r1);                                       \
1081 }
1082 #define entry_lb_ir_ir(name)                                            \
1083 static void                                                             \
1084 name(void)                                                              \
1085 {                                                                       \
1086     jit_node_t  *jmp;                                                   \
1087     label_t     *label = get_label(skip_ws);                            \
1088     jit_gpr_t    r0 = get_ireg(), r1 = get_ireg();                      \
1089     if (label->kind == label_kind_code_forward)                         \
1090         jmp_forward((void *)jit_##name(r0, r1), label);                 \
1091     else {                                                              \
1092         jmp = jit_##name(r0, r1);                                       \
1093         jit_patch_at(jmp, (jit_node_t *)label->value);                  \
1094     }                                                                   \
1095 }
1096 #define entry_lb_ir_im(name)                                            \
1097 static void                                                             \
1098 name(void)                                                              \
1099 {                                                                       \
1100     jit_node_t  *jmp;                                                   \
1101     label_t     *label = get_label(skip_ws);                            \
1102     jit_gpr_t    r0 = get_ireg();                                       \
1103     jit_word_t   im = get_imm();                                        \
1104     if (label->kind == label_kind_code_forward)                         \
1105         jmp_forward((void *)jit_##name(r0, im), label);                 \
1106     else {                                                              \
1107         jmp = jit_##name(r0, im);                                       \
1108         jit_patch_at(jmp, (jit_node_t *)label->value);                  \
1109     }                                                                   \
1110 }
1111 #define entry_lb(name)                                                  \
1112 static void                                                             \
1113 name(void)                                                              \
1114 {                                                                       \
1115     jit_node_t  *jmp;                                                   \
1116     label_t     *label = get_label(skip_ws);                            \
1117     if (label->kind == label_kind_code_forward)                         \
1118         jmp_forward((void *)jit_##name(), label);                       \
1119     else {                                                              \
1120         jmp = jit_##name();                                             \
1121         jit_patch_at(jmp, (jit_node_t *)label->value);                  \
1122     }                                                                   \
1123 }
1124 #define entry_pm(name)                                                  \
1125 static void                                                             \
1126 name(void)                                                              \
1127 {                                                                       \
1128     void        *pm = get_pointer(skip_ws);                             \
1129     jit_##name(pm);                                                     \
1130 }
1131 #define entry_fa(name)                                                  \
1132 static void                                                             \
1133 name(void)                                                              \
1134 {                                                                       \
1135     jit_fpr_t           r0 = get_freg();                                \
1136     jit_pointer_t       ac = get_arg();                                 \
1137     jit_##name(r0, ac);                                                 \
1138 }
1139 #define entry_fma(name)                                                 \
1140 static void                                                             \
1141 name(void)                                                              \
1142 {                                                                       \
1143     jit_float64_t       im = get_float(skip_ws);                        \
1144     jit_pointer_t       ac = get_arg();                                 \
1145     jit_##name(im, ac);                                                 \
1146 }
1147 #define entry_fr_fr_fr(name)                                            \
1148 static void                                                             \
1149 name(void)                                                              \
1150 {                                                                       \
1151     jit_fpr_t   r0 = get_freg(), r1 = get_freg(), r2 = get_freg();      \
1152     jit_##name(r0, r1, r2);                                             \
1153 }
1154 #define entry_fr_fr_fm(name)                                            \
1155 static void                                                             \
1156 name(void)                                                              \
1157 {                                                                       \
1158     jit_fpr_t           r0 = get_freg(), r1 = get_freg();               \
1159     jit_float64_t       im = get_float(skip_ws);                        \
1160     jit_##name(r0, r1, make_float(im));                                 \
1161 }
1162 #define entry_fr_fr_dm(name)                                            \
1163 static void                                                             \
1164 name(void)                                                              \
1165 {                                                                       \
1166     jit_fpr_t           r0 = get_freg(), r1 = get_freg();               \
1167     jit_float64_t       im = get_float(skip_ws);                        \
1168     jit_##name(r0, r1, im);                                             \
1169 }
1170 #define entry_fr_fr(name)                                               \
1171 static void                                                             \
1172 name(void)                                                              \
1173 {                                                                       \
1174     jit_fpr_t   r0 = get_freg(), r1 = get_freg();                       \
1175     jit_##name(r0, r1);                                                 \
1176 }
1177 #define entry_ir_fr_fr(name)                                            \
1178 static void                                                             \
1179 name(void)                                                              \
1180 {                                                                       \
1181     jit_gpr_t   r0 = get_ireg();                                        \
1182     jit_fpr_t   r1 = get_freg(), r2 = get_freg();                       \
1183     jit_##name(r0, r1, r2);                                             \
1184 }
1185 #define entry_ir_fr_fm(name)                                            \
1186 static void                                                             \
1187 name(void)                                                              \
1188 {                                                                       \
1189     jit_gpr_t           r0 = get_ireg();                                \
1190     jit_fpr_t           r1 = get_freg();                                \
1191     jit_float64_t       im = get_float(skip_ws);                        \
1192     jit_##name(r0, r1, make_float(im));                                 \
1193 }
1194 #define entry_ir_fr_dm(name)                                            \
1195 static void                                                             \
1196 name(void)                                                              \
1197 {                                                                       \
1198     jit_gpr_t           r0 = get_ireg();                                \
1199     jit_fpr_t           r1 = get_freg();                                \
1200     jit_float64_t       im = get_float(skip_ws);                        \
1201     jit_##name(r0, r1, im);                                             \
1202 }
1203 #define entry_ir_fr(name)                                               \
1204 static void                                                             \
1205 name(void)                                                              \
1206 {                                                                       \
1207     jit_gpr_t   r0 = get_ireg();                                        \
1208     jit_fpr_t   r1 = get_freg();                                        \
1209     jit_##name(r0, r1);                                                 \
1210 }
1211 #define entry_fr_ir(name)                                               \
1212 static void                                                             \
1213 name(void)                                                              \
1214 {                                                                       \
1215     jit_fpr_t   r0 = get_freg();                                        \
1216     jit_gpr_t   r1 = get_ireg();                                        \
1217     jit_##name(r0, r1);                                                 \
1218 }
1219 #define entry_fr_fm(name)                                               \
1220 static void                                                             \
1221 name(void)                                                              \
1222 {                                                                       \
1223     jit_fpr_t           r0 = get_freg();                                \
1224     jit_float64_t       im = get_float(skip_ws);                        \
1225     jit_##name(r0, make_float(im));                                     \
1226 }
1227 #define entry_fr_dm(name)                                               \
1228 static void                                                             \
1229 name(void)                                                              \
1230 {                                                                       \
1231     jit_fpr_t           r0 = get_freg();                                \
1232     jit_float64_t       im = get_float(skip_ws);                        \
1233     jit_##name(r0, im);                                                 \
1234 }
1235 #define entry_fr_pm(name)                                               \
1236 static void                                                             \
1237 name(void)                                                              \
1238 {                                                                       \
1239     jit_fpr_t    r0 = get_freg();                                       \
1240     void        *pm = get_pointer(skip_ws);                             \
1241     jit_##name(r0, pm);                                                 \
1242 }
1243 #define entry_fr_ir_ir(name)                                            \
1244 static void                                                             \
1245 name(void)                                                              \
1246 {                                                                       \
1247     jit_fpr_t   r0 = get_freg();                                        \
1248     jit_gpr_t   r1 = get_ireg(), r2 = get_ireg();                       \
1249     jit_##name(r0, r1, r2);                                             \
1250 }
1251 #define entry_fr_ir_im(name)                                            \
1252 static void                                                             \
1253 name(void)                                                              \
1254 {                                                                       \
1255     jit_fpr_t   r0 = get_freg();                                        \
1256     jit_gpr_t   r1 = get_ireg();                                        \
1257     jit_word_t  im = get_imm();                                         \
1258     jit_##name(r0, r1, im);                                             \
1259 }
1260 #define entry_pm_fr(name)                                               \
1261 static void                                                             \
1262 name(void)                                                              \
1263 {                                                                       \
1264     void        *pm = get_pointer(skip_ws);                             \
1265     jit_fpr_t    r0 = get_freg();                                       \
1266     jit_##name(pm, r0);                                                 \
1267 }
1268 #define entry_ir_ir_fr(name)                                            \
1269 static void                                                             \
1270 name(void)                                                              \
1271 {                                                                       \
1272     jit_gpr_t   r0 = get_ireg(), r1 = get_ireg();                       \
1273     jit_fpr_t   r2 = get_freg();                                        \
1274     jit_##name(r0, r1, r2);                                             \
1275 }
1276 #define entry_im_ir_fr(name)                                            \
1277 static void                                                             \
1278 name(void)                                                              \
1279 {                                                                       \
1280     jit_word_t  im = get_imm();                                         \
1281     jit_gpr_t   r0 = get_ireg();                                        \
1282     jit_fpr_t   r1 = get_freg();                                        \
1283     jit_##name(im, r0, r1);                                             \
1284 }
1285 #define entry_lb_fr_fr(name)                                            \
1286 static void                                                             \
1287 name(void)                                                              \
1288 {                                                                       \
1289     jit_node_t  *jmp;                                                   \
1290     label_t     *label = get_label(skip_ws);                            \
1291     jit_fpr_t    r0 = get_freg(), r1 = get_freg();                      \
1292     if (label->kind == label_kind_code_forward)                         \
1293         jmp_forward((void *)jit_##name(r0, r1), label);                 \
1294     else {                                                              \
1295         jmp = jit_##name(r0, r1);                                       \
1296         jit_patch_at(jmp, (jit_node_t *)label->value);                  \
1297     }                                                                   \
1298 }
1299 #define entry_lb_fr_fm(name)                                            \
1300 static void                                                             \
1301 name(void)                                                              \
1302 {                                                                       \
1303     jit_node_t          *jmp;                                           \
1304     label_t             *label = get_label(skip_ws);                    \
1305     jit_fpr_t            r0 = get_freg();                               \
1306     jit_float64_t        im = get_float(skip_ws);                       \
1307     if (label->kind == label_kind_code_forward)                         \
1308         jmp_forward((void *)jit_##name(r0, make_float(im)), label);     \
1309     else {                                                              \
1310         jmp = jit_##name(r0, make_float(im));                           \
1311         jit_patch_at(jmp, (jit_node_t *)label->value);                  \
1312     }                                                                   \
1313 }
1314 #define entry_lb_fr_dm(name)                                            \
1315 static void                                                             \
1316 name(void)                                                              \
1317 {                                                                       \
1318     jit_node_t          *jmp;                                           \
1319     label_t             *label = get_label(skip_ws);                    \
1320     jit_fpr_t            r0 = get_freg();                               \
1321     jit_float64_t        im = get_float(skip_ws);                       \
1322     if (label->kind == label_kind_code_forward)                         \
1323         jmp_forward((void *)jit_##name(r0, im), label);                 \
1324     else {                                                              \
1325         jmp = jit_##name(r0, im);                                       \
1326         jit_patch_at(jmp, (jit_node_t *)label->value);                  \
1327     }                                                                   \
1328 }
1329 #define entry_fr(name)                                                  \
1330 static void                                                             \
1331 name(void)                                                              \
1332 {                                                                       \
1333     jit_fpr_t   r0 = get_freg();                                        \
1334     jit_##name(r0);                                                     \
1335 }
1336 #define entry_fm(name)                                                  \
1337 static void                                                             \
1338 name(void)                                                              \
1339 {                                                                       \
1340     jit_float64_t       im = get_float(skip_ws);                        \
1341     jit_##name(make_float(im));                                         \
1342 }
1343 #define entry_dm(name)                                                  \
1344 static void                                                             \
1345 name(void)                                                              \
1346 {                                                                       \
1347     jit_float64_t       im = get_float(skip_ws);                        \
1348     jit_##name(im);                                                     \
1349 }
1350 #define entry_fn(name)                                                  \
1351 static void                                                             \
1352 name(void)                                                              \
1353 {                                                                       \
1354     int          ch;                                                    \
1355     label_t     *label;                                                 \
1356     void        *value;                                                 \
1357     ch = skipws();                                                      \
1358     switch (ch) {                                                       \
1359         case '0' ... '9':                                               \
1360             ungetch(ch);                                                \
1361             value = (void *)(jit_word_t)get_uint(skip_none);            \
1362             break;                                                      \
1363         case '$':                                                       \
1364             switch (expression()) {                                     \
1365                 case tok_int:                                           \
1366                     value = (void *)parser.value.i;                     \
1367                     break;                                              \
1368                 case tok_pointer:                                       \
1369                     value = parser.value.p;                             \
1370                     break;                                              \
1371                 default:                                                \
1372                     error("expecting pointer");                         \
1373             }                                                           \
1374             break;                                                      \
1375         case '@':                                                       \
1376             dynamic();                                                  \
1377             value = parser.value.p;                                     \
1378             break;                                                      \
1379         default:                                                        \
1380             ungetch(ch);                                                \
1381             label = get_label(skip_none);                               \
1382             if (label->kind == label_kind_code_forward)                 \
1383                 call_forward((void *)jit_##name(NULL), label);          \
1384             else                                                        \
1385                 jit_patch_at(jit_##name(NULL), label->value);           \
1386             return;                                                     \
1387     }                                                                   \
1388     jit_##name(value);                                                  \
1389 }
1390 static void
1391 name(void) {
1392     int          ch = skipws();
1393     (void)identifier(ch);
1394     jit_name(parser.string);
1395 }
1396 static void
1397 live(void) {
1398     if (primary(skip_ws) != tok_register)
1399         error("bad register");
1400     jit_live(parser.regval);
1401 }
1402 entry_im(align)
1403 entry(prolog)
1404 entry_im(frame)                 entry_im(tramp)
1405 entry(ellipsis)
1406 void
1407 allocai(void) {
1408     symbol_t    *symbol;
1409     jit_word_t   i, im = get_imm();
1410     i = jit_allocai(im);
1411     symbol = get_symbol();
1412     symbol->type = type_l;
1413     symbol->value.i = i;
1414 }
1415 entry_ir_ir(allocar)
1416 entry_ca(arg)
1417 entry_ia(getarg_c)              entry_ia(getarg_uc)
1418 entry_ia(getarg_s)              entry_ia(getarg_us)
1419 entry_ia(getarg_i)
1420 #if __WORDSIZE == 64
1421 entry_ia(getarg_ui)             entry_ia(getarg_l)
1422 #endif
1423 entry_ia(getarg)
1424 entry_ia(putargr)               entry_ima(putargi)
1425 entry_ir_ir_ir(addr)            entry_ir_ir_im(addi)
1426 entry_ir_ir_ir(addxr)           entry_ir_ir_im(addxi)
1427 entry_ir_ir_ir(addcr)           entry_ir_ir_im(addci)
1428 entry_ir_ir_ir(subr)            entry_ir_ir_im(subi)
1429 entry_ir_ir_ir(subxr)           entry_ir_ir_im(subxi)
1430 entry_ir_ir_ir(subcr)           entry_ir_ir_im(subci)
1431 entry_ir_ir_ir(rsbr)            entry_ir_ir_im(rsbi)
1432 entry_ir_ir_ir(mulr)            entry_ir_ir_im(muli)
1433 entry_ir_ir_ir_ir(qmulr)        entry_ir_ir_ir_im(qmuli)
1434 entry_ir_ir_ir_ir(qmulr_u)      entry_ir_ir_ir_im(qmuli_u)
1435 entry_ir_ir_ir(divr)            entry_ir_ir_im(divi)
1436 entry_ir_ir_ir(divr_u)          entry_ir_ir_im(divi_u)
1437 entry_ir_ir_ir_ir(qdivr)        entry_ir_ir_ir_im(qdivi)
1438 entry_ir_ir_ir_ir(qdivr_u)      entry_ir_ir_ir_im(qdivi_u)
1439 entry_ir_ir_ir(remr)            entry_ir_ir_im(remi)
1440 entry_ir_ir_ir(remr_u)          entry_ir_ir_im(remi_u)
1441 entry_ir_ir_ir(andr)            entry_ir_ir_im(andi)
1442 entry_ir_ir_ir(orr)             entry_ir_ir_im(ori)
1443 entry_ir_ir_ir(xorr)            entry_ir_ir_im(xori)
1444 entry_ir_ir_ir(lshr)            entry_ir_ir_im(lshi)
1445 entry_ir_ir_ir(rshr)            entry_ir_ir_im(rshi)
1446 entry_ir_ir_ir(rshr_u)          entry_ir_ir_im(rshi_u)
1447 entry_ir_ir(negr)               entry_ir_ir(comr)
1448 entry_ir_ir_ir(ltr)             entry_ir_ir_im(lti)
1449 entry_ir_ir_ir(ltr_u)           entry_ir_ir_im(lti_u)
1450 entry_ir_ir_ir(ler)             entry_ir_ir_im(lei)
1451 entry_ir_ir_ir(ler_u)           entry_ir_ir_im(lei_u)
1452 entry_ir_ir_ir(eqr)             entry_ir_ir_im(eqi)
1453 entry_ir_ir_ir(ger)             entry_ir_ir_im(gei)
1454 entry_ir_ir_ir(ger_u)           entry_ir_ir_im(gei_u)
1455 entry_ir_ir_ir(gtr)             entry_ir_ir_im(gti)
1456 entry_ir_ir_ir(gtr_u)           entry_ir_ir_im(gti_u)
1457 entry_ir_ir_ir(ner)             entry_ir_ir_im(nei)
1458 entry_ir_ir_ir_ir(casr)         entry_ir_im_ir_ir(casi)
1459 entry_ir_ir(movr)
1460 static void
1461 movi(void)
1462 {
1463     int          ch;
1464     label_t     *label;
1465     void        *value;
1466     jit_gpr_t    r0 = get_ireg();
1467     ch = skipws();
1468     switch (ch) {
1469         case '+': case '-':
1470         case '0' ... '9':
1471             ungetch(ch);
1472             value = (void *)(jit_word_t)get_uint(skip_none);
1473             break;
1474         case '\'':
1475             character();
1476             value = (void *)parser.value.i;
1477             break;
1478         case '$':
1479             switch (expression()) {
1480                 case tok_int:
1481                     value = (void *)parser.value.i;
1482                     break;
1483                 case tok_pointer:
1484                     value = parser.value.p;
1485                     break;
1486                 default:
1487                     error("expecting pointer");
1488             }
1489             break;
1490         case '@':
1491             dynamic();
1492             value = parser.value.p;
1493             break;
1494         default:
1495             ungetch(ch);
1496             label = get_label(skip_none);
1497             if (label->kind == label_kind_code ||
1498                 label->kind == label_kind_code_forward) {
1499                 mov_forward((void *)jit_movi(r0, 0), label);
1500                 return;
1501             }
1502             value = label->value;
1503             break;
1504     }
1505     jit_movi(r0, (jit_word_t)value);
1506 }
1507 entry_ir_ir(extr_c)             entry_ir_ir(extr_uc)
1508 entry_ir_ir(extr_s)             entry_ir_ir(extr_us)
1509 #if __WORDSIZE == 64
1510 entry_ir_ir(extr_i)             entry_ir_ir(extr_ui)
1511 #endif
1512 entry_ir_ir(htonr_us)           entry_ir_ir(ntohr_us)
1513 entry_ir_ir(htonr_ui)           entry_ir_ir(ntohr_ui)
1514 #if __WORDSIZE == 64
1515 entry_ir_ir(htonr_ul)           entry_ir_ir(ntohr_ul)
1516 #endif
1517 entry_ir_ir(htonr)              entry_ir_ir(ntohr)
1518 entry_ir_ir(bswapr_us)          entry_ir_ir(bswapr_ui)
1519 #if __WORDSIZE == 64
1520 entry_ir_ir(bswapr_ul)
1521 #endif
1522 entry_ir_ir(bswapr)
1523 entry_ir_ir_ir(movnr)           entry_ir_ir_ir(movzr)
1524 entry_ir_ir(ldr_c)              entry_ir_pm(ldi_c)
1525 entry_ir_ir(ldr_uc)             entry_ir_pm(ldi_uc)
1526 entry_ir_ir(ldr_s)              entry_ir_pm(ldi_s)
1527 entry_ir_ir(ldr_us)             entry_ir_pm(ldi_us)
1528 entry_ir_ir(ldr_i)              entry_ir_pm(ldi_i)
1529 #if __WORDSIZE == 64
1530 entry_ir_ir(ldr_ui)             entry_ir_pm(ldi_ui)
1531 entry_ir_ir(ldr_l)              entry_ir_pm(ldi_l)
1532 #endif
1533 entry_ir_ir(ldr)                entry_ir_pm(ldi)
1534 entry_ir_ir_ir(ldxr_c)          entry_ir_ir_im(ldxi_c)
1535 entry_ir_ir_ir(ldxr_uc)         entry_ir_ir_im(ldxi_uc)
1536 entry_ir_ir_ir(ldxr_s)          entry_ir_ir_im(ldxi_s)
1537 entry_ir_ir_ir(ldxr_us)         entry_ir_ir_im(ldxi_us)
1538 entry_ir_ir_ir(ldxr_i)          entry_ir_ir_im(ldxi_i)
1539 #if __WORDSIZE == 64
1540 entry_ir_ir_ir(ldxr_ui)         entry_ir_ir_im(ldxi_ui)
1541 entry_ir_ir_ir(ldxr_l)          entry_ir_ir_im(ldxi_l)
1542 #endif
1543 entry_ir_ir_ir(ldxr)            entry_ir_ir_im(ldxi)
1544 entry_ir_ir(str_c)              entry_pm_ir(sti_c)
1545 entry_ir_ir(str_s)              entry_pm_ir(sti_s)
1546 entry_ir_ir(str_i)              entry_pm_ir(sti_i)
1547 #if __WORDSIZE == 64
1548 entry_ir_ir(str_l)              entry_pm_ir(sti_l)
1549 #endif
1550 entry_ir_ir(str)                entry_pm_ir(sti)
1551 entry_ir_ir_ir(stxr_c)          entry_im_ir_ir(stxi_c)
1552 entry_ir_ir_ir(stxr_s)          entry_im_ir_ir(stxi_s)
1553 entry_ir_ir_ir(stxr_i)          entry_im_ir_ir(stxi_i)
1554 #if __WORDSIZE == 64
1555 entry_ir_ir_ir(stxr_l)          entry_im_ir_ir(stxi_l)
1556 #endif
1557 entry_ir_ir_ir(stxr)            entry_im_ir_ir(stxi)
1558 entry_lb_ir_ir(bltr)            entry_lb_ir_im(blti)
1559 entry_lb_ir_ir(bltr_u)          entry_lb_ir_im(blti_u)
1560 entry_lb_ir_ir(bler)            entry_lb_ir_im(blei)
1561 entry_lb_ir_ir(bler_u)          entry_lb_ir_im(blei_u)
1562 entry_lb_ir_ir(beqr)            entry_lb_ir_im(beqi)
1563 entry_lb_ir_ir(bger)            entry_lb_ir_im(bgei)
1564 entry_lb_ir_ir(bger_u)          entry_lb_ir_im(bgei_u)
1565 entry_lb_ir_ir(bgtr)            entry_lb_ir_im(bgti)
1566 entry_lb_ir_ir(bgtr_u)          entry_lb_ir_im(bgti_u)
1567 entry_lb_ir_ir(bner)            entry_lb_ir_im(bnei)
1568 entry_lb_ir_ir(bmsr)            entry_lb_ir_im(bmsi)
1569 entry_lb_ir_ir(bmcr)            entry_lb_ir_im(bmci)
1570 entry_lb_ir_ir(boaddr)          entry_lb_ir_im(boaddi)
1571 entry_lb_ir_ir(boaddr_u)        entry_lb_ir_im(boaddi_u)
1572 entry_lb_ir_ir(bxaddr)          entry_lb_ir_im(bxaddi)
1573 entry_lb_ir_ir(bxaddr_u)        entry_lb_ir_im(bxaddi_u)
1574 entry_lb_ir_ir(bosubr)          entry_lb_ir_im(bosubi)
1575 entry_lb_ir_ir(bosubr_u)        entry_lb_ir_im(bosubi_u)
1576 entry_lb_ir_ir(bxsubr)          entry_lb_ir_im(bxsubi)
1577 entry_lb_ir_ir(bxsubr_u)        entry_lb_ir_im(bxsubi_u)
1578 entry_ir(jmpr)                  entry_lb(jmpi)
1579 entry_ir(callr)                 entry_fn(calli)
1580 entry(prepare)
1581 entry_ir(pushargr)              entry_im(pushargi)
1582 entry_ir(finishr)               entry_fn(finishi)
1583 entry(ret)
1584 entry_ir(retr)                  entry_im(reti)
1585 entry_ir(retval_c)              entry_ir(retval_uc)
1586 entry_ir(retval_s)              entry_ir(retval_us)
1587 entry_ir(retval_i)
1588 #if __WORDSIZE == 64
1589 entry_ir(retval_ui)             entry_ir(retval_l)
1590 #endif
1591 entry_ir(retval)
1592 entry(epilog)
1593 entry_ca(arg_f)                 entry_fa(getarg_f)
1594 entry_fa(putargr_f)             entry_fma(putargi_f)
1595 entry_fr_fr_fr(addr_f)          entry_fr_fr_fm(addi_f)
1596 entry_fr_fr_fr(subr_f)          entry_fr_fr_fm(subi_f)
1597 entry_fr_fr_fr(rsbr_f)          entry_fr_fr_fm(rsbi_f)
1598 entry_fr_fr_fr(mulr_f)          entry_fr_fr_fm(muli_f)
1599 entry_fr_fr_fr(divr_f)          entry_fr_fr_fm(divi_f)
1600 entry_fr_fr(negr_f)             entry_fr_fr(absr_f)
1601 entry_fr_fr(sqrtr_f)
1602 entry_ir_fr_fr(ltr_f)           entry_ir_fr_fm(lti_f)
1603 entry_ir_fr_fr(ler_f)           entry_ir_fr_fm(lei_f)
1604 entry_ir_fr_fr(eqr_f)           entry_ir_fr_fm(eqi_f)
1605 entry_ir_fr_fr(ger_f)           entry_ir_fr_fm(gei_f)
1606 entry_ir_fr_fr(gtr_f)           entry_ir_fr_fm(gti_f)
1607 entry_ir_fr_fr(ner_f)           entry_ir_fr_fm(nei_f)
1608 entry_ir_fr_fr(unltr_f)         entry_ir_fr_fm(unlti_f)
1609 entry_ir_fr_fr(unler_f)         entry_ir_fr_fm(unlei_f)
1610 entry_ir_fr_fr(uneqr_f)         entry_ir_fr_fm(uneqi_f)
1611 entry_ir_fr_fr(unger_f)         entry_ir_fr_fm(ungei_f)
1612 entry_ir_fr_fr(ungtr_f)         entry_ir_fr_fm(ungti_f)
1613 entry_ir_fr_fr(ltgtr_f)         entry_ir_fr_fm(ltgti_f)
1614 entry_ir_fr_fr(ordr_f)          entry_ir_fr_fm(ordi_f)
1615 entry_ir_fr_fr(unordr_f)        entry_ir_fr_fm(unordi_f)
1616 entry_ir_fr(truncr_f_i)
1617 #if __WORDSIZE == 64
1618 entry_ir_fr(truncr_f_l)
1619 #endif
1620 entry_ir_fr(truncr_f)
1621 entry_fr_ir(extr_f)             entry_fr_fr(extr_d_f)
1622 entry_fr_fr(movr_f)             entry_fr_fm(movi_f)
1623 entry_fr_ir(ldr_f)              entry_fr_pm(ldi_f)
1624 entry_fr_ir_ir(ldxr_f)          entry_fr_ir_im(ldxi_f)
1625 entry_ir_fr(str_f)              entry_pm_fr(sti_f)
1626 entry_ir_ir_fr(stxr_f)          entry_im_ir_fr(stxi_f)
1627 entry_lb_fr_fr(bltr_f)          entry_lb_fr_fm(blti_f)
1628 entry_lb_fr_fr(bler_f)          entry_lb_fr_fm(blei_f)
1629 entry_lb_fr_fr(beqr_f)          entry_lb_fr_fm(beqi_f)
1630 entry_lb_fr_fr(bger_f)          entry_lb_fr_fm(bgei_f)
1631 entry_lb_fr_fr(bgtr_f)          entry_lb_fr_fm(bgti_f)
1632 entry_lb_fr_fr(bner_f)          entry_lb_fr_fm(bnei_f)
1633 entry_lb_fr_fr(bunltr_f)        entry_lb_fr_fm(bunlti_f)
1634 entry_lb_fr_fr(bunler_f)        entry_lb_fr_fm(bunlei_f)
1635 entry_lb_fr_fr(buneqr_f)        entry_lb_fr_fm(buneqi_f)
1636 entry_lb_fr_fr(bunger_f)        entry_lb_fr_fm(bungei_f)
1637 entry_lb_fr_fr(bungtr_f)        entry_lb_fr_fm(bungti_f)
1638 entry_lb_fr_fr(bltgtr_f)        entry_lb_fr_fm(bltgti_f)
1639 entry_lb_fr_fr(bordr_f)         entry_lb_fr_fm(bordi_f)
1640 entry_lb_fr_fr(bunordr_f)       entry_lb_fr_fm(bunordi_f)
1641 entry_fr(pushargr_f)            entry_fm(pushargi_f)
1642 entry_fr(retr_f)                entry_fm(reti_f)
1643 entry_fr(retval_f)
1644 entry_ca(arg_d)                 entry_fa(getarg_d)
1645 entry_fa(putargr_d)             entry_fma(putargi_d)
1646 entry_fr_fr_fr(addr_d)          entry_fr_fr_dm(addi_d)
1647 entry_fr_fr_fr(subr_d)          entry_fr_fr_dm(subi_d)
1648 entry_fr_fr_fr(rsbr_d)          entry_fr_fr_dm(rsbi_d)
1649 entry_fr_fr_fr(mulr_d)          entry_fr_fr_dm(muli_d)
1650 entry_fr_fr_fr(divr_d)          entry_fr_fr_dm(divi_d)
1651 entry_fr_fr(negr_d)             entry_fr_fr(absr_d)
1652 entry_fr_fr(sqrtr_d)
1653 entry_ir_fr_fr(ltr_d)           entry_ir_fr_dm(lti_d)
1654 entry_ir_fr_fr(ler_d)           entry_ir_fr_dm(lei_d)
1655 entry_ir_fr_fr(eqr_d)           entry_ir_fr_dm(eqi_d)
1656 entry_ir_fr_fr(ger_d)           entry_ir_fr_dm(gei_d)
1657 entry_ir_fr_fr(gtr_d)           entry_ir_fr_dm(gti_d)
1658 entry_ir_fr_fr(ner_d)           entry_ir_fr_dm(nei_d)
1659 entry_ir_fr_fr(unltr_d)         entry_ir_fr_dm(unlti_d)
1660 entry_ir_fr_fr(unler_d)         entry_ir_fr_dm(unlei_d)
1661 entry_ir_fr_fr(uneqr_d)         entry_ir_fr_dm(uneqi_d)
1662 entry_ir_fr_fr(unger_d)         entry_ir_fr_dm(ungei_d)
1663 entry_ir_fr_fr(ungtr_d)         entry_ir_fr_dm(ungti_d)
1664 entry_ir_fr_fr(ltgtr_d)         entry_ir_fr_dm(ltgti_d)
1665 entry_ir_fr_fr(ordr_d)          entry_ir_fr_dm(ordi_d)
1666 entry_ir_fr_fr(unordr_d)        entry_ir_fr_dm(unordi_d)
1667 entry_ir_fr(truncr_d_i)
1668 #if __WORDSIZE == 64
1669 entry_ir_fr(truncr_d_l)
1670 #endif
1671 entry_ir_fr(truncr_d)
1672 entry_fr_ir(extr_d)             entry_fr_fr(extr_f_d)
1673 entry_fr_fr(movr_d)             entry_fr_dm(movi_d)
1674 entry_fr_ir(ldr_d)              entry_fr_pm(ldi_d)
1675 entry_fr_ir_ir(ldxr_d)          entry_fr_ir_im(ldxi_d)
1676 entry_ir_fr(str_d)              entry_pm_fr(sti_d)
1677 entry_ir_ir_fr(stxr_d)          entry_im_ir_fr(stxi_d)
1678 entry_lb_fr_fr(bltr_d)          entry_lb_fr_dm(blti_d)
1679 entry_lb_fr_fr(bler_d)          entry_lb_fr_dm(blei_d)
1680 entry_lb_fr_fr(beqr_d)          entry_lb_fr_dm(beqi_d)
1681 entry_lb_fr_fr(bger_d)          entry_lb_fr_dm(bgei_d)
1682 entry_lb_fr_fr(bgtr_d)          entry_lb_fr_dm(bgti_d)
1683 entry_lb_fr_fr(bner_d)          entry_lb_fr_dm(bnei_d)
1684 entry_lb_fr_fr(bunltr_d)        entry_lb_fr_dm(bunlti_d)
1685 entry_lb_fr_fr(bunler_d)        entry_lb_fr_dm(bunlei_d)
1686 entry_lb_fr_fr(buneqr_d)        entry_lb_fr_dm(buneqi_d)
1687 entry_lb_fr_fr(bunger_d)        entry_lb_fr_dm(bungei_d)
1688 entry_lb_fr_fr(bungtr_d)        entry_lb_fr_dm(bungti_d)
1689 entry_lb_fr_fr(bltgtr_d)        entry_lb_fr_dm(bltgti_d)
1690 entry_lb_fr_fr(bordr_d)         entry_lb_fr_dm(bordi_d)
1691 entry_lb_fr_fr(bunordr_d)       entry_lb_fr_dm(bunordi_d)
1692 entry_fr(pushargr_d)            entry_dm(pushargi_d)
1693 entry_fr(retr_d)                entry_dm(reti_d)
1694 entry_fr(retval_d)
1695 static void
1696 vastart(void)
1697 {
1698     jit_gpr_t   r0 = get_ireg();
1699     jit_va_start(r0);
1700 }
1701 static void
1702 vapush(void)
1703 {
1704     jit_gpr_t   r0 = get_ireg();
1705     jit_va_push(r0);
1706 }
1707 static void
1708 vaarg(void)
1709 {
1710     jit_gpr_t   r0 = get_ireg(), r1 = get_ireg();
1711     jit_va_arg(r0, r1);
1712 }
1713 static void
1714 vaarg_d(void)
1715 {
1716     jit_fpr_t   r0 = get_freg();
1717     jit_gpr_t   r1 = get_ireg();
1718     jit_va_arg_d(r0, r1);
1719 }
1720 static void
1721 vaend(void)
1722 {
1723     jit_gpr_t   r0 = get_ireg();
1724     jit_va_end(r0);
1725 }
1726 #undef entry_fn
1727 #undef entry_fm
1728 #undef entry_dm
1729 #undef entry_lb_fr_fm
1730 #undef entry_lb_fr_dm
1731 #undef entry_lb_fr_fr
1732 #undef entry_im_ir_fr
1733 #undef entry_ir_ir_fr
1734 #undef entry_pm_fr
1735 #undef entry_fr_ir_ir
1736 #undef entry_fr_ir_im
1737 #undef entry_fr_pm
1738 #undef entry_fr_fm
1739 #undef entry_fr_dm
1740 #undef entry_fr_ir
1741 #undef entry_ir_fr
1742 #undef entry_ir_fr_fm
1743 #undef entry_ir_fr_dm
1744 #undef entry_ir_fr_fr
1745 #undef entry_fr_fr
1746 #undef entry_fr_fr_fm
1747 #undef entry_fr_fr_dm
1748 #undef entry_fr_fr_fr
1749 #undef entry_fma
1750 #undef entry_fa
1751 #undef entry_pm
1752 #undef entry_lb
1753 #undef entry_lb_ir_im
1754 #undef entry_lb_ir_ir
1755 #undef entry_im_ir_ir
1756 #undef entry_pm_ir
1757 #undef entry_ir_pm
1758 #undef entry_ir_im
1759 #undef entry_ir_ir
1760 #undef entry_ir_ir_im
1761 #undef entry_ir_ir_ir
1762 #undef entry_ima
1763 #undef entry_ir
1764 #undef entry_im
1765 #undef entry_ia
1766 #undef entry_ca
1767 #undef entry
1768
1769 static void
1770 error(const char *format, ...)
1771 {
1772     va_list      ap;
1773     int          length;
1774     char        *string;
1775
1776     va_start(ap, format);
1777     message("error", format, ap);
1778     va_end(ap);
1779     length = parser.data.length - parser.data.offset;
1780     string = (char *)(parser.data.buffer + parser.data.offset - 1);
1781     if (length > 77)
1782         strcpy(string + 74, "...");
1783     else
1784         parser.data.buffer[parser.data.length - 1] = '\0';
1785     fprintf(stderr, "(%s)\n", string);
1786     exit(-1);
1787 }
1788
1789 static void
1790 warn(const char *format, ...)
1791 {
1792     va_list     ap;
1793     va_start(ap, format);
1794     message("warning", format, ap);
1795     va_end(ap);
1796 }
1797
1798 static void
1799 message(const char *kind, const char *format, va_list ap)
1800 {
1801     fprintf(stderr, "%s:%d: %s: ", parser.name,
1802             parser.line - parser.newline, kind);
1803     vfprintf(stderr, format, ap);
1804     fputc('\n', stderr);
1805 }
1806
1807 static int
1808 getch(void)
1809 {
1810     int         ch;
1811
1812     if (parser.data.offset < parser.data.length)
1813         ch = parser.data.buffer[parser.data.offset++];
1814     else {
1815         /* keep first offset for ungetch */
1816         if ((parser.data.length = fread(parser.data.buffer + 1, 1,
1817                                         sizeof(parser.data.buffer) - 1,
1818                                         parser.fp) + 1) <= 1) {
1819             ch = EOF;
1820             parser.data.offset = 1;
1821         }
1822         else {
1823             ch = parser.data.buffer[1];
1824             parser.data.offset = 2;
1825         }
1826     }
1827     if ((parser.newline = ch == '\n'))
1828         ++parser.line;
1829
1830     return (ch);
1831 }
1832
1833 static int
1834 getch_noeof(void)
1835 {
1836     int         ch = getch();
1837
1838     if (ch == EOF)
1839         error("unexpected end of file");
1840
1841     return (ch);
1842 }
1843
1844 static int
1845 ungetch(int ch)
1846 {
1847     if ((parser.newline = ch == '\n'))
1848         --parser.line;
1849
1850     if (parser.data.offset)
1851         parser.data.buffer[--parser.data.offset] = ch;
1852     else
1853         /* overwrite */
1854         parser.data.buffer[0] = ch;
1855
1856     return (ch);
1857 }
1858
1859 static int
1860 skipws(void)
1861 {
1862     int         ch;
1863
1864     for (ch = getch();; ch = getch()) {
1865         switch (ch) {
1866             case '/':
1867                 ch = skipct();
1868                 break;
1869             case '#':
1870                 ch = skipcp();
1871                 break;
1872         }
1873         switch (ch) {
1874             case ' ': case '\f': case '\r': case '\t':
1875                 break;
1876             default:
1877                 return (ch);
1878         }
1879     }
1880 }
1881
1882 static int
1883 skipnl(void)
1884 {
1885     int         ch;
1886
1887     for (ch = getch();; ch = getch()) {
1888         switch (ch) {
1889             case '/':
1890                 ch = skipct();
1891                 break;
1892             case '#':
1893                 ch = skipcp();
1894                 break;
1895         }
1896         switch (ch) {
1897             case ' ': case '\f': case '\n': case '\r': case '\t':
1898                 break;
1899                 /* handle as newline */
1900             case ';':
1901                 break;
1902             default:
1903                 return (ch);
1904         }
1905     }
1906 }
1907
1908 static int
1909 skipct(void)
1910 {
1911     int         ch;
1912
1913     ch = getch();
1914     switch (ch) {
1915         case '/':
1916             for (ch = getch(); ch != '\n' && ch != EOF; ch = getch())
1917                 ;
1918             return (ch);
1919         case '*':
1920             for (; ch != '/';) {
1921                 while (getch_noeof() != '*')
1922                     ;
1923                 while ((ch = getch_noeof()) == '*')
1924                     ;
1925             }
1926             return (getch());
1927         default:
1928             ungetch(ch);
1929             return ('/');
1930     }
1931 }
1932
1933 static int
1934 skipcp(void)
1935 {
1936     int         ch;
1937
1938     for (ch = getch(); ch != '\n' && ch != EOF; ch = getch()) {
1939         switch (ch) {
1940             case '0' ... '9':
1941                 if ((number(ch)) == tok_int)
1942                     parser.line = parser.value.i - 1;
1943                 break;
1944             case '"':
1945                 string();
1946                 if (parser.offset >= (int)sizeof(parser.name)) {
1947                     strncpy(parser.name, parser.string, sizeof(parser.name));
1948                     parser.name[sizeof(parser.name) - 1] = '\0';
1949                 }
1950                 else
1951                     strcpy(parser.name, parser.string);
1952                 break;
1953             default:
1954                 break;
1955         }
1956     }
1957
1958     return (ch);
1959 }
1960
1961 static jit_word_t
1962 get_int(skip_t skip)
1963 {
1964     switch (primary(skip)) {
1965         case tok_int:
1966             break;
1967         case tok_pointer:
1968             parser.type = type_l;
1969             parser.value.i = (jit_word_t)parser.value.p;
1970             break;
1971         default:
1972             error("expecting integer");
1973     }
1974
1975     return (parser.value.i);
1976 }
1977
1978 static jit_uword_t
1979 get_uint(skip_t skip)
1980 {
1981     switch (primary(skip)) {
1982         case tok_char:          case tok_int:
1983             break;
1984         case tok_pointer:
1985             parser.type = type_l;
1986             parser.value.ui = (jit_uword_t)parser.value.p;
1987             break;
1988         default:
1989             error("expecting integer");
1990     }
1991
1992     return (parser.value.ui);
1993 }
1994
1995 static double
1996 get_float(skip_t skip)
1997 {
1998     switch (primary(skip)) {
1999         case tok_char:
2000         case tok_int:
2001             parser.type = type_d;
2002             parser.value.d = parser.value.i;
2003             break;
2004         case tok_float:
2005             break;
2006         default:
2007             error("expecting float");
2008     }
2009
2010     return (parser.value.d);
2011 }
2012
2013 /* Workaround gcc not converting unordered values from double to
2014  * float (as done in other architectures) on s390 */
2015 static float
2016 make_float(double d)
2017 {
2018     /* This is an workaround to a bug in Hercules s390 emulator,
2019      * and at least HP-UX ia64 not have these */
2020 #if defined(HAVE_ISNAN) && defined(HAVE_ISINF)
2021     if (isnan(d))       return ( 0.0f/0.0f);
2022     if (isinf(d)) {
2023         if (d > 0.0)    return ( 1.0f/0.0f);
2024         else            return (-1.0f/0.0f);
2025     }
2026 #endif
2027     return ((float)d);
2028 }
2029
2030 static void *
2031 get_pointer(skip_t skip)
2032 {
2033     label_t     *label;
2034     token_t      token = primary(skip);
2035
2036     switch (token) {
2037         case tok_symbol:
2038             label = get_label_by_name(parser.string);
2039             if (label == NULL)
2040                 error("bad identifier %s", parser.string);
2041             switch (label->kind) {
2042                 case label_kind_data:
2043                 case label_kind_code:
2044                     break;
2045                 case label_kind_code_forward:
2046                     /* as expression arguments */
2047                     error("forward references not implemented");
2048                     break;
2049                 case label_kind_dynamic:
2050                     break;
2051             }
2052             parser.type = type_p;
2053             return (parser.value.p = label->value);
2054         case tok_int:
2055             parser.type = type_p;
2056             return (parser.value.p = (void *)parser.value.ui);
2057         case tok_pointer:
2058             return (parser.value.p);
2059         default:                error("bad pointer");
2060     }
2061 }
2062
2063 static label_t *
2064 get_label(skip_t skip)
2065 {
2066     label_t     *label;
2067     int          ch = skipws();
2068
2069     switch (ch) {
2070         case '@':
2071             (void)dynamic();
2072             break;
2073         case 'a' ... 'z': case 'A' ... 'Z': case '_':
2074             (void)identifier(ch);
2075             break;
2076         default:
2077             error("expecting label/immediate");
2078     }
2079     if ((label = get_label_by_name(parser.string)) == NULL)
2080         label = new_label(label_kind_code_forward,
2081                           parser.string, jit_forward());
2082
2083     return (label);
2084 }
2085
2086 static token_t
2087 regname(void)
2088 {
2089     jit_word_t  num;
2090     int         check = 1, ch = getch();
2091
2092     switch (ch) {
2093         case 'r':
2094             parser.regtype = type_l;
2095             switch (ch = getch()) {
2096                 case '0':       parser.regval = JIT_R0;         break;
2097                 case '1':       parser.regval = JIT_R1;         break;
2098                 case '2':       parser.regval = JIT_R2;         break;
2099                 case '(':
2100                     num = get_int(skip_none);
2101                     if (num < 0 || num >= JIT_R_NUM)            goto fail;
2102                     parser.regval = JIT_R(num);
2103                     if (getch() != ')')                         goto fail;
2104                     check = 0;
2105                     break;
2106                 default:                                        goto fail;
2107             }
2108             break;
2109         case 'v':
2110             parser.regtype = type_l;
2111             switch (ch = getch()) {
2112                 case '0':       parser.regval = JIT_V0;         break;
2113                 case '1':       parser.regval = JIT_V1;         break;
2114                 case '2':       parser.regval = JIT_V2;         break;
2115                 default:                                        goto fail;
2116                 case '(':
2117                     num = get_int(skip_none);
2118                     if (num < 0 || num >= JIT_V_NUM)            goto fail;
2119                     parser.regval = JIT_V(num);
2120                     if (getch() != ')')                         goto fail;
2121                     check = 0;
2122                     break;
2123             }
2124             break;
2125         case 'f':
2126             parser.regtype = type_d;
2127             switch (ch = getch()) {
2128                 case '0':       parser.regval = JIT_F0;         break;
2129                 case '1':       parser.regval = JIT_F1;         break;
2130                 case '2':       parser.regval = JIT_F2;         break;
2131                 case '3':       parser.regval = JIT_F3;         break;
2132                 case '4':       parser.regval = JIT_F4;         break;
2133                 case '5':       parser.regval = JIT_F5;         break;
2134                 case 'p':
2135                     parser.regtype = type_l;    /* oops */
2136                     parser.regval = JIT_FP;                     break;
2137                 case '(':
2138                     num = get_int(skip_none);
2139                     if (num < 0 || num >= JIT_F_NUM)            goto fail;
2140                     parser.regval = JIT_F(num);
2141                     if (getch() != ')')                         goto fail;
2142                     check = 0;
2143                     break;
2144                 default:                                        goto fail;
2145             }
2146             break;
2147         default:
2148         fail:
2149             error("bad register");
2150     }
2151     if (check) {
2152         ch = getch();
2153         if ((ch >= 'a' && ch <= 'z') ||
2154             (ch >= 'A' && ch <= 'Z') ||
2155             (ch >= '0' && ch <= '9') ||
2156             ch == '_')
2157             goto fail;
2158         ungetch(ch);
2159     }
2160
2161     return (tok_register);
2162 }
2163
2164 static token_t
2165 identifier(int ch)
2166 {
2167     parser.string[0] = ch;
2168     for (parser.offset = 1;;) {
2169         switch ((ch = getch())) {
2170             case 'a' ... 'z': case 'A' ... 'Z': case '0' ... '9' :  case '_':
2171                 if (parser.offset + 1 >= MAX_IDENTIFIER) {
2172                     parser.string[parser.offset] = '\0';
2173                     error("bad identifier %s", parser.string);
2174                 }
2175                 parser.string[parser.offset++] = ch;
2176                 break;
2177             default:
2178                 parser.string[parser.offset] = '\0';
2179                 ungetch(ch);
2180                 return (tok_symbol);
2181         }
2182     }
2183 }
2184
2185 static void
2186 get_data(type_t type)
2187 {
2188     int          ch;
2189     token_t      token;
2190     char        *test = data;
2191
2192     for (;;) {
2193         switch (type) {
2194             case type_c:
2195                 switch (token = primary(skip_ws)) {
2196                     case tok_char: case tok_int:
2197                         check_data(sizeof(signed char));
2198                         *(signed char *)(data + data_offset) = parser.value.i;
2199                         data_offset += sizeof(char);
2200                         break;
2201                     case tok_string:
2202                         check_data(parser.offset);
2203                         memcpy(data + data_offset, parser.string,
2204                                parser.offset);
2205                         data_offset += parser.offset;
2206                         break;
2207                     case tok_newline:
2208                     case tok_semicollon:
2209                         if (test == data)       error("syntax error");
2210                         return;
2211                     default:                    error("bad initializer");
2212                 }
2213                 break;
2214             case type_s:
2215                 check_data(sizeof(signed short));
2216                 *(signed short *)(data + data_offset) = get_int(skip_ws);
2217                 data_offset += sizeof(short);
2218                 break;
2219             case type_i:
2220                 check_data(sizeof(signed int));
2221                 *(signed int *)(data + data_offset) = get_int(skip_ws);
2222                 data_offset += sizeof(int);
2223                 break;
2224             case type_l:
2225                 check_data(sizeof(jit_word_t));
2226                 *(jit_word_t *)(data + data_offset) = get_int(skip_ws);
2227                 data_offset += sizeof(jit_word_t);
2228                 break;
2229             case type_f:
2230                 check_data(sizeof(float));
2231                 *(float *)(data + data_offset) = get_float(skip_ws);
2232                 data_offset += sizeof(float);
2233                 break;
2234             case type_d:
2235                 check_data(sizeof(double));
2236                 *(double *)(data + data_offset) = get_float(skip_ws);
2237                 data_offset += sizeof(double);
2238                 break;
2239             case type_p:
2240                 /* FIXME **patch if realloc** */
2241                 check_data(sizeof(void*));
2242                 *(void **)(data + data_offset) = get_pointer(skip_ws);
2243                 data_offset += sizeof(void*);
2244                 break;
2245             default:
2246                 abort();
2247         }
2248         ch = skipws();
2249         if (ch == '\n' || ch == ';' || ch == EOF)
2250             break;
2251         ungetch(ch);
2252     }
2253 }
2254
2255 static void
2256 dot(void)
2257 {
2258     int         ch;
2259     size_t      offset, length;
2260
2261     switch (ch = getch_noeof()) {
2262         case '$':
2263             /* use .$(expression) for non side effects expression */
2264             (void)expression();
2265             return;
2266         case 'a' ... 'z': case 'A' ... 'Z': case '_':
2267             (void)identifier(ch);
2268             break;
2269         default:
2270             ungetch(ch);
2271             if (skipws() != '$')
2272                 error("expecting symbol");
2273             /* allow spaces before an expression */
2274             (void)expression();
2275             return;
2276     }
2277     if (parser.string[1] == '\0') {
2278         switch (parser.string[0]) {
2279             case 'c':   get_data(type_c);       break;
2280             case 's':   get_data(type_s);       break;
2281             case 'i':   get_data(type_i);       break;
2282             case 'l':   get_data(type_l);       break;
2283             case 'f':   get_data(type_f);       break;
2284             case 'd':   get_data(type_d);       break;
2285             case 'p':   get_data(type_p);       break;
2286             default:    error("bad type .%c", parser.string[0]);
2287         }
2288     }
2289     else if (strcmp(parser.string, "data") == 0) {
2290         if (parser.parsing != PARSING_NONE)
2291             error(".data must be specified once and be the first section");
2292         parser.parsing = PARSING_DATA;
2293         data_length = get_int(skip_ws);
2294         data = (char *)xcalloc(1, data_length);
2295     }
2296     else if (strcmp(parser.string, "code") == 0) {
2297         if (parser.parsing != PARSING_NONE &&
2298             parser.parsing != PARSING_DATA)
2299             error(".code must be specified once only");
2300         parser.parsing = PARSING_CODE;
2301     }
2302     else if (strcmp(parser.string, "align") == 0) {
2303         length = get_int(skip_ws);
2304         if (parser.parsing != PARSING_DATA)
2305             error(".align must be in .data");
2306         if (length > 1 && length <= 4096 && !(length & (length - 1))) {
2307             offset = data_offset;
2308             offset += length - ((offset + length) % length);
2309             check_data(offset - data_offset);
2310             data_offset = offset;
2311         }
2312         else
2313             error("bad .align %ld (must be a power of 2, >= 2 && <= 4096)",
2314                   (jit_word_t)length);
2315     }
2316     else if (strcmp(parser.string, "size") == 0) {
2317         length = get_int(skip_ws);
2318         if (parser.parsing != PARSING_DATA)
2319             error(".size must be in .data");
2320         check_data(length);
2321         data_offset += length;
2322     }
2323     else if (strcmp(parser.string, "disasm") == 0)
2324         flag_disasm = 1;
2325     else
2326         error("unknown command .%s", parser.string);
2327 }
2328
2329 static token_t
2330 number(int ch)
2331 {
2332     char        buffer[1024], *endptr;
2333     int         integer = 1, offset = 0, neg = 0, e = 0, d = 0, base = 10;
2334
2335     for (;; ch = getch()) {
2336         switch (ch) {
2337             case '-':
2338                 if (offset == 0) {
2339                     neg = 1;
2340                     continue;
2341                 }
2342                 if (offset && buffer[offset - 1] != 'e') {
2343                     ungetch(ch);
2344                     goto done;
2345                 }
2346                 break;
2347             case '+':
2348                 if (offset == 0)
2349                     continue;
2350                 if (offset && buffer[offset - 1] != 'e') {
2351                     ungetch(ch);
2352                     goto done;
2353                 }
2354                 break;
2355             case '.':
2356                 if (d)
2357                     goto fail;
2358                 d = 1;
2359                 base = 10;
2360                 integer = 0;
2361                 break;
2362             case '0':
2363                 if (offset == 0 && base == 10) {
2364                     base = 8;
2365                     continue;
2366                 }
2367                 break;
2368             case 'b':
2369                 if (offset == 0 && base == 8) {
2370                     base = 2;
2371                     continue;
2372                 }
2373                 if (base != 16)
2374                     goto fail;
2375                 break;
2376             case '1':
2377                 break;
2378             case '2' ... '7':
2379                 if (base < 8)
2380                     goto fail;
2381                 break;
2382             case '8': case '9':
2383                 if (base < 10)
2384                     goto fail;
2385                 break;
2386             case 'x':
2387                 if (offset == 0 && base == 8) {
2388                     base = 16;
2389                     continue;
2390                 }
2391                 goto fail;
2392             case 'a': case 'c': case 'd': case 'f':
2393                 if (base < 16)
2394                     goto fail;
2395                 break;
2396             case 'e':
2397                 if (e)
2398                     goto fail;
2399                 if (base != 16) {
2400                     e = 1;
2401                     base = 10;
2402                     integer = 0;
2403                 }
2404                 break;
2405             case '_': case 'g' ... 'w': case 'y': case 'z': case 'A' ... 'Z':
2406             fail:
2407                 buffer[offset++] = '\0';
2408                 error("bad constant %s", buffer);
2409             default:
2410                 ungetch(ch);
2411                 goto done;
2412         }
2413         if (offset + 1 >= (int)sizeof(buffer))
2414             goto fail;
2415         buffer[offset++] = ch;
2416     }
2417 done:
2418     /* check for literal 0 */
2419     if (offset == 0 && base == 8)       buffer[offset++] = '0';
2420     buffer[offset] = '\0';
2421     if (integer) {
2422 #if _WIN32
2423 #  define STRTOUL       strtoull
2424 #else
2425 #  define STRTOUL       strtoul
2426 #endif
2427         parser.value.ui = STRTOUL(buffer, &endptr, base);
2428         parser.type = type_l;
2429         if (neg)
2430             parser.value.i = -parser.value.i;
2431     }
2432     else {
2433         parser.type = type_d;
2434         parser.value.d = strtod(buffer, &endptr);
2435         if (neg)
2436             parser.value.d = -parser.value.d;
2437     }
2438     if (*endptr)
2439         goto fail;
2440
2441     return (integer ? tok_int : tok_float);
2442 }
2443
2444 static int
2445 escape(int ch)
2446 {
2447     switch (ch) {
2448         case 'a':       ch = '\a';      break;
2449         case 'b':       ch = '\b';      break;
2450         case 'f':       ch = '\f';      break;
2451         case 'n':       ch = '\n';      break;
2452         case 'r':       ch = '\r';      break;
2453         case 't':       ch = '\t';      break;
2454         case 'v':       ch = '\v';      break;
2455         default:                        break;
2456     }
2457
2458     return (ch);
2459 }
2460
2461 static token_t
2462 string(void)
2463 {
2464     int         ch, esc = 0;
2465
2466     for (parser.offset = 0;;) {
2467         switch (ch = getch_noeof()) {
2468             case '\\':
2469                 if (esc)                goto append;
2470                 esc = 1;
2471                 break;
2472             case '"':
2473                 if (!esc) {
2474                     parser.string[parser.offset++] = '\0';
2475                     parser.value.p = parser.string;
2476                     parser.type = type_p;
2477                     return (tok_string);
2478                 }
2479                 /* FALLTHROUGH */
2480             default:
2481             append:
2482                 if (esc) {
2483                     ch = escape(ch);
2484                     esc = 0;
2485                 }
2486                 if (parser.offset + 1 >= parser.length) {
2487                     parser.length += 4096;
2488                     parser.string = (char *)xrealloc(parser.string,
2489                                                      parser.length);
2490                 }
2491                 parser.string[parser.offset++] = ch;
2492                 break;
2493         }
2494     }
2495 }
2496
2497 static token_t
2498 character(void)
2499 {
2500     int         ch, esc = 0;
2501
2502     if ((ch = getch_noeof()) == '\\') {
2503         esc = 1;
2504         ch = getch();
2505     }
2506     if (getch_noeof() != '\'')
2507         error("bad single byte char");
2508     if (esc)
2509         ch = escape(ch);
2510     parser.type = type_l;
2511     parser.value.i = ch & 0xff;
2512
2513     return (tok_char);
2514 }
2515
2516 static token_t
2517 dynamic(void)
2518 {
2519     label_t     *label;
2520     void        *value;
2521     char        *string;
2522     (void)identifier('@');
2523     if ((label = get_label_by_name(parser.string)) == NULL) {
2524 #if __CYGWIN__ ||_WIN32
2525         /* FIXME kludge to pass varargs test case, otherwise,
2526          * will not print/scan float values */
2527         if (strcmp(parser.string + 1, "sprintf") == 0)
2528             value = sprintf;
2529         else if (strcmp(parser.string + 1, "sscanf") == 0)
2530             value = sscanf;
2531         else
2532 #endif
2533         {
2534             value = dlsym(DL_HANDLE, parser.string + 1);
2535             if ((string = dlerror()))
2536                 error("%s", string);
2537         }
2538         label = new_label(label_kind_dynamic, parser.string, value);
2539     }
2540     parser.type = type_p;
2541     parser.value.p = label->value;
2542
2543     return (tok_pointer);
2544 }
2545
2546 static void
2547 expression_prim(void)
2548 {
2549     int          ch;
2550     token_t      token;
2551     label_t     *label;
2552     symbol_t    *symbol;
2553
2554     if (parser.putback) {
2555         parser.expr = parser.putback;
2556         parser.putback = (expr_t)0;
2557         return;
2558     }
2559     switch (ch = skipws()) {
2560         case '!':
2561             if ((ch = getch_noeof()) == '=')    parser.expr = expr_ne;
2562             else {
2563                 ungetch(ch);                    parser.expr = expr_not;
2564             }
2565             break;
2566         case '~':                               parser.expr = expr_com;
2567             break;
2568         case '*':
2569             if ((ch = getch_noeof()) == '=')    parser.expr = expr_mulset;
2570             else {
2571                 ungetch(ch);                    parser.expr = expr_mul;
2572             }
2573             break;
2574         case '/':
2575             if ((ch = getch_noeof()) == '=')    parser.expr = expr_divset;
2576             else {
2577                 ungetch(ch);                    parser.expr = expr_div;
2578             }
2579             break;
2580         case '%':
2581             if ((ch = getch_noeof()) == '=')    parser.expr = expr_remset;
2582             else {
2583                 ungetch(ch);                    parser.expr = expr_rem;
2584             }
2585             break;
2586         case '+':
2587             switch (ch = getch_noeof()) {
2588                 case '+':                       parser.expr = expr_inc;
2589                     break;
2590                 case '=':                       parser.expr = expr_addset;
2591                     break;
2592                 default:        ungetch(ch);    parser.expr = expr_add;
2593                     break;
2594             }
2595             break;
2596         case '-':
2597             switch (ch = getch_noeof()) {
2598                 case '-':                       parser.expr = expr_dec;
2599                     break;
2600                 case '=':                       parser.expr = expr_subset;
2601                     break;
2602                 default:        ungetch(ch);    parser.expr = expr_sub;
2603                     break;
2604             }
2605             break;
2606         case '<':
2607             switch (ch = getch_noeof()) {
2608                 case '=':                       parser.expr = expr_le;
2609                     break;
2610                 case '<':                       ch = getch_noeof();
2611                     if (ch == '=')              parser.expr = expr_lshset;
2612                     else {
2613                         ungetch(ch);            parser.expr = expr_lsh;
2614                     }
2615                     break;
2616                 default:        ungetch(ch);    parser.expr = expr_lt;
2617                     break;
2618             }
2619             break;
2620         case '>':
2621             switch (ch = getch_noeof()) {
2622                 case '=':                       parser.expr = expr_ge;
2623                     break;
2624                 case '>':                       ch = getch_noeof();
2625                     if (ch == '=')              parser.expr = expr_rshset;
2626                     else {
2627                         ungetch(ch);            parser.expr = expr_rsh;
2628                     }
2629                     break;
2630                 default:        ungetch(ch);    parser.expr = expr_gt;
2631                     break;
2632             }
2633             break;
2634         case '&':
2635             switch (ch = getch_noeof()) {
2636                 case '=':                       parser.expr = expr_andset;
2637                     break;
2638                 case '&':                       parser.expr = expr_andand;
2639                     break;
2640                 default:        ungetch(ch);    parser.expr = expr_and;
2641                     break;
2642             }
2643             break;
2644         case '|':
2645             switch (ch = getch_noeof()) {
2646                 case '=':                       parser.expr = expr_orset;
2647                     break;
2648                 case '|':                       parser.expr = expr_oror;
2649                     break;
2650                 default:        ungetch(ch);    parser.expr = expr_or;
2651                     break;
2652             }
2653             break;
2654         case '^':
2655             if ((ch = getch_noeof()) == '=')    parser.expr = expr_xorset;
2656             else {
2657                 ungetch(ch);                    parser.expr = expr_xor;
2658             }
2659             break;
2660         case '=':
2661             if ((ch = getch_noeof()) == '=')    parser.expr = expr_eq;
2662             else {
2663                 ungetch(ch);                    parser.expr = expr_set;
2664             }
2665             break;
2666         case '(':                               parser.expr = expr_lparen;
2667             break;
2668         case ')':                               parser.expr = expr_rparen;
2669             break;
2670         case '0' ... '9':
2671             token = number(ch);
2672             parser.expr = token == tok_int ? expr_int : expr_float;
2673             break;
2674         case '@':
2675             (void)dynamic();
2676             parser.expr = expr_pointer;
2677             break;
2678         case '$':
2679             identifier('$');
2680             /* no support for nested expressions */
2681             if (parser.string[0] == '\0')
2682                 error("syntax error");
2683             parser.expr = expr_symbol;
2684             if ((symbol = get_symbol_by_name(parser.string)) != NULL) {
2685                 parser.type = symbol->type;
2686                 parser.value = symbol->value;
2687             }
2688             else
2689                 /* only create symbol on assignment */
2690                 parser.type = type_none;
2691             break;
2692         case 'a' ... 'z': case 'A' ... 'Z': case '_':
2693             identifier(ch);
2694             if ((label = get_label_by_name(parser.string))) {
2695                 if (label->kind == label_kind_code_forward)
2696                     error("forward value for %s not supported",
2697                           parser.string);
2698                 parser.expr = expr_pointer;
2699                 parser.type = type_p;
2700                 parser.value.p = label->value;
2701             }
2702             else
2703                 error("invalid identifier %s", parser.string);
2704             break;
2705         case '\'':
2706             character();
2707             parser.expr = expr_int;
2708             break;
2709         case '"':
2710             /* not smart enough to put it in data and/or relocate it, etc */
2711             error("must declare strings as data");
2712         default:
2713             error("syntax error");
2714     }
2715 }
2716
2717 static void
2718 expression_inc(int pre)
2719 {
2720     symbol_t    *symbol;
2721
2722     if (pre) {
2723         expression_prim();
2724         if (parser.expr != expr_symbol)
2725             error("syntax error");
2726     }
2727     if ((symbol = get_symbol_by_name(parser.string)) == NULL) {
2728         if (!parser.short_circuit)
2729             error("undefined symbol %s", symbol->name);
2730     }
2731     if (!parser.short_circuit) {
2732         parser.type = symbol->type;
2733         if (!pre)
2734             parser.value = symbol->value;
2735         switch (symbol->type) {
2736             case type_l:
2737                 ++symbol->value.i;
2738                 break;
2739             case type_d:
2740                 /* should really be an error */
2741                 symbol->value.d += 1.0;
2742                 break;
2743             default:
2744                 ++parser.value.cp;
2745                 break;
2746         }
2747         if (pre)
2748             parser.value = symbol->value;
2749     }
2750     expression_prim();
2751 }
2752
2753 static void
2754 expression_dec(int pre)
2755 {
2756     symbol_t    *symbol;
2757
2758     if (pre) {
2759         expression_prim();
2760         if (parser.expr != expr_symbol)
2761             error("syntax error");
2762     }
2763     if ((symbol = get_symbol_by_name(parser.string)) == NULL) {
2764         if (!parser.short_circuit)
2765             error("undefined symbol %s", symbol->name);
2766     }
2767     if (!parser.short_circuit) {
2768         parser.type = symbol->type;
2769         if (!pre)
2770             parser.value = symbol->value;
2771         switch (symbol->type) {
2772             case type_l:
2773                 --symbol->value.i;
2774                 break;
2775             case type_d:
2776                 /* should really be an error */
2777                 symbol->value.d -= 1.0;
2778                 break;
2779             default:
2780                 --parser.value.cp;
2781                 break;
2782         }
2783         if (pre)
2784             parser.value = symbol->value;
2785     }
2786     expression_prim();
2787 }
2788
2789 static void
2790 expression_unary(void)
2791 {
2792     symbol_t    *symbol;
2793     char         buffer[256];
2794
2795     expression_prim();
2796     switch (parser.expr) {
2797         case expr_add:
2798             expression_unary();
2799             switch (parser.type) {
2800                 case type_l:
2801                 case type_d:
2802                     break;
2803                 default:
2804                     error("syntax error");
2805             }
2806             break;
2807         case expr_sub:
2808             expression_unary();
2809             switch (parser.type) {
2810                 case type_l:
2811                     parser.value.i = -parser.value.i;
2812                     break;
2813                 case type_d:
2814                     parser.value.d = -parser.value.d;
2815                     break;
2816                 default:
2817                     error("syntax error");
2818             }
2819             break;
2820         case expr_inc:
2821             expression_inc(1);
2822             break;
2823         case expr_dec:
2824             expression_dec(1);
2825             break;
2826         case expr_not:
2827             expression_unary();
2828             switch (parser.type) {
2829                 case type_l:
2830                     parser.value.i = !parser.value.i;
2831                     break;
2832                 case type_d:
2833                     parser.value.i = parser.value.d != 0;
2834                     break;
2835                 case type_p:
2836                     parser.value.i = parser.value.p != NULL;
2837                     break;
2838                 default:
2839                     error("syntax error");
2840             }
2841             parser.type = type_l;
2842             break;
2843         case expr_com:
2844             expression_unary();
2845             if (parser.type != type_l)
2846                 error("syntax error");
2847             parser.value.i = ~parser.value.i;
2848             break;
2849         case expr_lparen:
2850             expression_cond();
2851             if (parser.expr != expr_rparen)
2852                 error("syntax error");
2853             expression_prim();
2854             break;
2855         case expr_symbol:
2856             strcpy(buffer, parser.string);
2857             expression_prim();
2858             switch (parser.expr) {
2859                 case expr_set:
2860                     if ((symbol = get_symbol_by_name(buffer)) == NULL) {
2861                         if (!parser.short_circuit)
2862                             symbol = new_symbol(buffer);
2863                     }
2864                     expression_cond();
2865                 set:
2866                     if (!parser.short_circuit) {
2867                         if (symbol == NULL)
2868                             error("syntax error");
2869                         symbol->type = parser.type;
2870                         symbol->value = parser.value;
2871                     }
2872                     break;
2873                 case expr_mulset:               parser.putback = expr_mul;
2874                     goto check;
2875                 case expr_divset:               parser.putback = expr_div;
2876                     goto check;
2877                 case expr_remset:               parser.putback = expr_rem;
2878                     goto check;
2879                 case expr_addset:               parser.putback = expr_add;
2880                     goto check;
2881                 case expr_subset:               parser.putback = expr_sub;
2882                     goto check;
2883                 case expr_lshset:               parser.putback = expr_lsh;
2884                     goto check;
2885                 case expr_rshset:               parser.putback = expr_rsh;
2886                     goto check;
2887                 case expr_andset:               parser.putback = expr_and;
2888                     goto check;
2889                 case expr_orset:                parser.putback = expr_or;
2890                     goto check;
2891                 case expr_xorset:               parser.putback = expr_xor;
2892                 check:
2893                     if ((symbol = get_symbol_by_name(buffer)) == NULL) {
2894                         if (!parser.short_circuit)
2895                             error("undefined symbol %s", buffer);
2896                         parser.type = type_l;
2897                         parser.value.i = 1;
2898                     }
2899                     switch (parser.putback) {
2900                         case expr_mul:  case expr_div:  case expr_rem:
2901                             expression_mul();
2902                             break;
2903                         case expr_add:  case expr_sub:
2904                             expression_add();
2905                             break;
2906                         case expr_lsh:  case expr_rsh:
2907                             expression_shift();
2908                             break;
2909                         case expr_and:  case expr_or:  case expr_xor:
2910                             expression_bit();
2911                             break;
2912                         default:
2913                             abort();
2914                     }
2915                     goto set;
2916                 case expr_inc:
2917                     expression_inc(0);
2918                     break;
2919                 case expr_dec:
2920                     expression_dec(0);
2921                     break;
2922                 default:
2923                     break;
2924             }
2925             break;
2926         case expr_int:
2927         case expr_float:
2928         case expr_pointer:
2929             /* make next token available */
2930             expression_prim();
2931         default:
2932             break;
2933     }
2934 }
2935
2936 static void
2937 expression_mul(void)
2938 {
2939     type_t      type;
2940     value_t     value;
2941
2942     expression_unary();
2943     switch (parser.type) {
2944         case type_l:    case type_d:    case type_p:    break;
2945         default:                                        return;
2946     }
2947     for (;;) {
2948         switch (parser.expr) {
2949             case expr_mul:
2950                 type = parser.type, value = parser.value;
2951                 expression_unary();
2952                 switch (parser.type) {
2953                     case type_l:
2954                         if (type == type_l)
2955                             value.i *= parser.value.i;
2956                         else
2957                             value.d *= parser.value.i;
2958                         break;
2959                     case type_d:
2960                         if (type == type_l) {
2961                             type = type_d;
2962                             value.d = value.i;
2963                         }
2964                         value.d *= parser.value.d;
2965                         break;
2966                     default:
2967                         error("invalid operand");
2968                 }
2969                 parser.type = type, parser.value = value;
2970                 break;
2971             case expr_div:
2972                 type = parser.type, value = parser.value;
2973                 expression_unary();
2974                 switch (parser.type) {
2975                     case type_l:
2976                         if (type == type_l) {
2977                             if (parser.value.i == 0)
2978                                 error("divide by zero");
2979                             value.i /= parser.value.i;
2980                         }
2981                         else
2982                             value.d /= parser.value.i;
2983                         break;
2984                     case type_d:
2985                         if (type == type_l) {
2986                             type = type_d;
2987                             value.d = value.i;
2988                         }
2989                         value.d /= parser.value.d;
2990                         break;
2991                     default:
2992                         error("invalid operand");
2993                 }
2994                 parser.type = type, parser.value = value;
2995                 break;
2996             case expr_rem:
2997                 type = parser.type, value = parser.value;
2998                 expression_unary();
2999                 switch (parser.type) {
3000                     case type_l:
3001                         if (type == type_l) {
3002                             if (parser.value.i == 0)
3003                                 error("divide by zero");
3004                             value.i %= parser.value.i;
3005                         }
3006                         else
3007                             error("invalid operand");
3008                         break;
3009                     default:
3010                         error("invalid operand");
3011                 }
3012                 parser.type = type, parser.value = value;
3013                 break;
3014             default:
3015                 return;
3016         }
3017     }
3018 }
3019
3020 static void
3021 expression_add(void)
3022 {
3023     type_t      type;
3024     value_t     value;
3025
3026     expression_mul();
3027     switch (parser.type) {
3028         case type_l:    case type_d:    case type_p:    break;
3029         default:                                        return;
3030     }
3031     for (;;) {
3032         switch (parser.expr) {
3033             case expr_add:
3034                 type = parser.type, value = parser.value;
3035                 expression_mul();
3036                 switch (parser.type) {
3037                     case type_l:
3038                         switch (type) {
3039                             case type_l:
3040                                 value.i += parser.value.i;
3041                                 break;
3042                             case type_d:
3043                                 value.d += parser.value.i;
3044                                 break;
3045                             default:
3046                                 value.cp += parser.value.i;
3047                                 break;
3048                         }
3049                         break;
3050                     case type_d:
3051                         switch (type) {
3052                             case type_l:
3053                                 type = type_d;
3054                                 value.d = value.i;
3055                                 break;
3056                             case type_d:
3057                                 break;
3058                             default:
3059                                 error("invalid operand");
3060                         }
3061                         value.d += parser.value.d;
3062                         break;
3063                     case type_p:
3064                         switch (type) {
3065                             case type_l:
3066                                 type = type_p;
3067                                 value.cp = value.i + parser.value.cp;
3068                                 break;
3069                             default:
3070                                 error("invalid operand");
3071                         }
3072                         break;
3073                     default:
3074                         error("invalid operand");
3075                 }
3076                 parser.type = type, parser.value = value;
3077                 break;
3078             case expr_sub:
3079                 type = parser.type, value = parser.value;
3080                 expression_mul();
3081                 switch (parser.type) {
3082                     case type_l:
3083                         switch (type) {
3084                             case type_l:
3085                                 value.i -= parser.value.i;
3086                                 break;
3087                             case type_d:
3088                                 value.d -= parser.value.i;
3089                                 break;
3090                             default:
3091                                 value.cp -= parser.value.i;
3092                                 break;
3093                         }
3094                         break;
3095                     case type_d:
3096                         switch (type) {
3097                             case type_l:
3098                                 type = type_d;
3099                                 value.d = value.i;
3100                                 break;
3101                             case type_d:
3102                                 break;
3103                             default:
3104                                 error("invalid operand");
3105                         }
3106                         value.d -= parser.value.d;
3107                         break;
3108                     case type_p:
3109                         switch (type) {
3110                             case type_p:
3111                                 type = type_l;
3112                                 value.i = value.cp - parser.value.cp;
3113                                 break;
3114                             default:
3115                                 error("invalid operand");
3116                         }
3117                         break;
3118                     default:
3119                         error("invalid operand");
3120                 }
3121                 parser.type = type, parser.value = value;
3122                 break;
3123             default:
3124                 return;
3125         }
3126     }
3127 }
3128
3129 static void
3130 expression_shift(void)
3131 {
3132     jit_word_t  value;
3133     expression_add();
3134
3135     switch (parser.type) {
3136         case type_l:    case type_d:    case type_p:    break;
3137         default:                                        return;
3138     }
3139     for (;;) {
3140         switch (parser.expr) {
3141             case expr_lsh:
3142                 value = parser.value.i;
3143                 if (parser.type != type_l)
3144                     error("invalid operand");
3145                 expression_add();
3146                 if (parser.type != type_l)
3147                     error("invalid operand");
3148                 value <<= parser.value.i;
3149                 parser.value.i = value;
3150                 break;
3151             case expr_rsh:
3152                 value = parser.value.i;
3153                 if (parser.type != type_l)
3154                     error("invalid operand");
3155                 expression_add();
3156                 if (parser.type != type_l)
3157                     error("invalid operand");
3158                 value >>= parser.value.i;
3159                 parser.value.i = value;
3160                 break;
3161             default:
3162                 return;
3163         }
3164     }
3165 }
3166
3167 static void
3168 expression_bit(void)
3169 {
3170     jit_word_t  i;
3171
3172     expression_shift();
3173     switch (parser.type) {
3174         case type_l:    case type_d:    case type_p:    break;
3175         default:                                        return;
3176     }
3177     for (;;) {
3178         switch (parser.expr) {
3179             case expr_and:
3180                 if (parser.type != type_l)
3181                     error("invalid operand");
3182                 i = parser.value.i;
3183                 expression_shift();
3184                 if (parser.type != type_l)
3185                     error("invalid operand");
3186                 i &= parser.value.i;
3187                 parser.value.i = i;
3188                 break;
3189             case expr_or:
3190                 if (parser.type != type_l)
3191                     error("invalid operand");
3192                 i = parser.value.i;
3193                 expression_shift();
3194                 if (parser.type != type_l)
3195                     error("invalid operand");
3196                 i |= parser.value.i;
3197                 parser.value.i = i;
3198                 break;
3199             case expr_xor:
3200                 if (parser.type != type_l)
3201                     error("invalid operand");
3202                 i = parser.value.i;
3203                 expression_shift();
3204                 if (parser.type != type_l)
3205                     error("invalid operand");
3206                 i ^= parser.value.i;
3207                 parser.value.i = i;
3208                 break;
3209             default:
3210                 return;
3211         }
3212     }
3213 }
3214
3215 static void
3216 expression_rel(void)
3217 {
3218     type_t      type;
3219     value_t     value;
3220
3221     expression_bit();
3222     switch (parser.type) {
3223         case type_l:    case type_d:    case type_p:    break;
3224         default:                                        return;
3225     }
3226     for (;;) {
3227         switch (parser.expr) {
3228             case expr_lt:
3229                 type = parser.type, value = parser.value;
3230                 expression_bit();
3231                 switch (parser.type) {
3232                     case type_l:
3233                         switch (type) {
3234                             case type_l:
3235                                 value.i = value.i < parser.value.i;
3236                                 break;
3237                             case type_d:
3238                                 value.i = value.d < parser.value.i;
3239                                 break;
3240                             default:
3241                                 value.i = (jit_word_t)value.p < parser.value.i;
3242                                 break;
3243                         }
3244                         break;
3245                     case type_d:
3246                         switch (type) {
3247                             case type_l:
3248                                 value.i = value.i < parser.value.d;
3249                                 break;
3250                             case type_d:
3251                                 value.i = value.d < parser.value.d;
3252                                 break;
3253                             default:
3254                                 error("invalid operand");
3255                         }
3256                         break;
3257                     case type_p:
3258                         switch (type) {
3259                             case type_l:
3260                                 value.i = value.i < (jit_word_t)parser.value.p;
3261                                 break;
3262                             case type_d:
3263                                 error("invalid operand");
3264                             default:
3265                                 value.i = (jit_word_t)value.p < (jit_word_t)parser.value.p;
3266                                 break;
3267                         }
3268                         break;
3269                     default:
3270                         error("invalid operand");
3271                 }
3272                 parser.type = type_l, parser.value = value;
3273                 break;
3274             case expr_le:
3275                 type = parser.type, value = parser.value;
3276                 expression_bit();
3277                 switch (parser.type) {
3278                     case type_l:
3279                         switch (type) {
3280                             case type_l:
3281                                 value.i = value.i <= parser.value.i;
3282                                 break;
3283                             case type_d:
3284                                 value.i = value.d <= parser.value.i;
3285                                 break;
3286                             default:
3287                                 value.i = (jit_word_t)value.p <= parser.value.i;
3288                                 break;
3289                         }
3290                         break;
3291                     case type_d:
3292                         switch (type) {
3293                             case type_l:
3294                                 value.i = value.i <= parser.value.d;
3295                                 break;
3296                             case type_d:
3297                                 value.i = value.d <= parser.value.d;
3298                                 break;
3299                             default:
3300                                 value.i = (jit_word_t)value.p <= parser.value.d;
3301                                 break;
3302                         }
3303                         break;
3304                     case type_p:
3305                         switch (type) {
3306                             case type_l:
3307                                 value.i = value.i <= (jit_word_t)parser.value.p;
3308                                 break;
3309                             case type_d:
3310                                 error("invalid operand");
3311                             default:
3312                                 value.i = (jit_word_t)value.p <= (jit_word_t)parser.value.p;
3313                                 break;
3314                         }
3315                         break;
3316                     default:
3317                         error("invalid operand");
3318                 }
3319                 parser.type = type_l, parser.value = value;
3320                 break;
3321             case expr_eq:
3322                 type = parser.type, value = parser.value;
3323                 expression_bit();
3324                 switch (parser.type) {
3325                     case type_l:
3326                         switch (type) {
3327                             case type_l:
3328                                 value.i = value.i == parser.value.i;
3329                                 break;
3330                             case type_d:
3331                                 value.i = value.d == parser.value.i;
3332                                 break;
3333                             default:
3334                                 value.i = (jit_word_t)value.p == parser.value.i;
3335                                 break;
3336                         }
3337                         break;
3338                     case type_d:
3339                         switch (type) {
3340                             case type_l:
3341                                 value.i = value.i == parser.value.d;
3342                                 break;
3343                             case type_d:
3344                                 value.i = value.d == parser.value.d;
3345                                 break;
3346                             default:
3347                                 error("invalid operand");
3348                         }
3349                         break;
3350                     case type_p:
3351                         switch (type) {
3352                             case type_l:
3353                                 value.i = value.i == (jit_word_t)parser.value.p;
3354                                 break;
3355                             case type_d:
3356                                 error("invalid operand");
3357                             default:
3358                                 value.i = value.p == parser.value.p;
3359                                 break;
3360                         }
3361                         break;
3362                     default:
3363                         error("invalid operand");
3364                 }
3365                 parser.type = type_l, parser.value = value;
3366                 break;
3367             case expr_ge:
3368                 type = parser.type, value = parser.value;
3369                 expression_bit();
3370                 switch (parser.type) {
3371                     case type_l:
3372                         switch (type) {
3373                             case type_l:
3374                                 value.i = value.i >= parser.value.i;
3375                                 break;
3376                             case type_d:
3377                                 value.i = value.d >= parser.value.i;
3378                                 break;
3379                             default:
3380                                 value.i = (jit_word_t)value.p >= parser.value.i;
3381                                 break;
3382                         }
3383                         break;
3384                     case type_d:
3385                         switch (type) {
3386                             case type_l:
3387                                 value.i = value.i >= parser.value.d;
3388                                 break;
3389                             case type_d:
3390                                 value.i = value.d >= parser.value.d;
3391                                 break;
3392                             default:
3393                                 error("invalid operand");
3394                         }
3395                         break;
3396                     case type_p:
3397                         switch (type) {
3398                             case type_l:
3399                                 value.i = value.i >= (jit_word_t)parser.value.p;
3400                                 break;
3401                             case type_d:
3402                                 error("invalid operand");
3403                             default:
3404                                 value.i = (jit_word_t)value.p >= (jit_word_t)parser.value.p;
3405                                 break;
3406                         }
3407                         break;
3408                     default:
3409                         error("invalid operand");
3410                 }
3411                 parser.type = type_l, parser.value = value;
3412                 break;
3413             case expr_gt:
3414                 type = parser.type, value = parser.value;
3415                 expression_bit();
3416                 switch (parser.type) {
3417                     case type_l:
3418                         switch (type) {
3419                             case type_l:
3420                                 value.i = value.i > parser.value.i;
3421                                 break;
3422                             case type_d:
3423                                 value.i = value.d > parser.value.i;
3424                                 break;
3425                             default:
3426                                 value.i = (jit_word_t)value.p > parser.value.i;
3427                                 break;
3428                         }
3429                         break;
3430                     case type_d:
3431                         switch (type) {
3432                             case type_l:
3433                                 value.i = value.i > parser.value.d;
3434                                 break;
3435                             case type_d:
3436                                 value.i = value.d > parser.value.d;
3437                                 break;
3438                             default:
3439                                 error("invalid operand");
3440                         }
3441                         break;
3442                     case type_p:
3443                         switch (type) {
3444                             case type_l:
3445                                 value.i = value.i > (jit_word_t)parser.value.p;
3446                                 break;
3447                             case type_d:
3448                                 error("invalid operand");
3449                             default:
3450                                 value.i = (jit_word_t)value.p > (jit_word_t)parser.value.p;
3451                                 break;
3452                         }
3453                         break;
3454                     default:
3455                         error("invalid operand");
3456                 }
3457                 parser.type = type_l, parser.value = value;
3458                 break;
3459             case expr_ne:
3460                 type = parser.type, value = parser.value;
3461                 expression_bit();
3462                 switch (parser.type) {
3463                     case type_l:
3464                         switch (type) {
3465                             case type_l:
3466                                 value.i = value.i != parser.value.i;
3467                                 break;
3468                             case type_d:
3469                                 value.i = value.d != parser.value.i;
3470                                 break;
3471                             default:
3472                                 value.i = (jit_word_t)value.p != parser.value.i;
3473                                 break;
3474                         }
3475                         break;
3476                     case type_d:
3477                         switch (type) {
3478                             case type_l:
3479                                 value.i = value.i != parser.value.d;
3480                                 break;
3481                             case type_d:
3482                                 value.i = value.d != parser.value.d;
3483                                 break;
3484                             default:
3485                                 error("invalid operand");
3486                         }
3487                         break;
3488                     case type_p:
3489                         switch (type) {
3490                             case type_l:
3491                                 value.i = value.i != (jit_word_t)parser.value.p;
3492                                 break;
3493                             case type_d:
3494                                 error("invalid operand");
3495                             default:
3496                                 value.i = value.p != parser.value.p;
3497                                 break;
3498                         }
3499                         break;
3500                     default:
3501                         error("invalid operand");
3502                 }
3503                 parser.type = type_l, parser.value = value;
3504                 break;
3505             default:
3506                 return;
3507         }
3508     }
3509 }
3510
3511 static void
3512 expression_cond(void)
3513 {
3514     type_t      type;
3515     value_t     value;
3516     int         short_circuit;
3517
3518     expression_rel();
3519     switch (parser.type) {
3520         case type_l:    case type_d:    case type_p:    break;
3521         default:                                        return;
3522     }
3523     for (;;) {
3524         switch (parser.expr) {
3525             case expr_andand:
3526                 type = parser.type, value = parser.value;
3527                 switch (type) {
3528                     case type_l:
3529                         short_circuit = value.i == 0;
3530                         break;
3531                     case type_d:
3532                         short_circuit = value.d == 0.0;
3533                         break;
3534                     default:
3535                         short_circuit = value.p == NULL;
3536                         break;
3537                 }
3538                 parser.short_circuit += short_circuit;
3539                 expression_rel();
3540                 parser.short_circuit -= short_circuit;
3541                 switch (parser.type) {
3542                     case type_l:
3543                         switch (type) {
3544                             case type_l:
3545                                 value.i = value.i && parser.value.i;
3546                                 break;
3547                             case type_d:
3548                                 value.i = value.d && parser.value.i;
3549                                 break;
3550                             default:
3551                                 value.i = value.p && parser.value.i;
3552                                 break;
3553                         }
3554                         break;
3555                     case type_d:
3556                         switch (type) {
3557                             case type_l:
3558                                 value.i = value.i && parser.value.d;
3559                                 break;
3560                             case type_d:
3561                                 value.i = value.d && parser.value.d;
3562                                 break;
3563                             default:
3564                                 value.i = value.p && parser.value.d;
3565                                 break;
3566                         }
3567                         break;
3568                     case type_p:
3569                         switch (type) {
3570                             case type_l:
3571                                 value.i = value.i && parser.value.p;
3572                                 break;
3573                             case type_d:
3574                                 value.i = value.d && parser.value.p;
3575                                 break;
3576                             default:
3577                                 value.i = value.p && parser.value.p;
3578                                 break;
3579                         }
3580                         break;
3581                     default:
3582                         error("invalid operand");
3583                 }
3584                 parser.type = type_l, parser.value.i = value.i;
3585                 break;
3586             case expr_oror:
3587                 type = parser.type, value = parser.value;
3588                 switch (type) {
3589                     case type_l:
3590                         short_circuit = value.i != 0;
3591                         break;
3592                     case type_d:
3593                         short_circuit = value.d != 0.0;
3594                         break;
3595                     default:
3596                         short_circuit = value.p != NULL;
3597                         break;
3598                 }
3599                 parser.short_circuit += short_circuit;
3600                 expression_rel();
3601                 parser.short_circuit -= short_circuit;
3602                 switch (parser.type) {
3603                     case type_l:
3604                         switch (type) {
3605                             case type_l:
3606                                 value.i = value.i || parser.value.i;
3607                                 break;
3608                             case type_d:
3609                                 value.i = value.d || parser.value.i;
3610                                 break;
3611                             default:
3612                                 value.i = value.p || parser.value.i;
3613                                 break;
3614                         }
3615                         break;
3616                     case type_d:
3617                         switch (type) {
3618                             case type_l:
3619                                 value.i = value.i || parser.value.d;
3620                                 break;
3621                             case type_d:
3622                                 value.i = value.d || parser.value.d;
3623                                 break;
3624                             default:
3625                                 value.i = value.p || parser.value.d;
3626                                 break;
3627                         }
3628                         break;
3629                     case type_p:
3630                         switch (type) {
3631                             case type_l:
3632                                 value.i = value.i || parser.value.p;
3633                                 break;
3634                             case type_d:
3635                                 value.i = value.d || parser.value.p;
3636                                 break;
3637                             default:
3638                                 value.i = value.p || parser.value.p;
3639                                 break;
3640                         }
3641                         break;
3642                     default:
3643                         error("invalid operand");
3644                 }
3645                 parser.type = type_l, parser.value.i = value.i;
3646                 break;
3647             default:
3648                 return;
3649         }
3650     }
3651 }
3652
3653 static token_t
3654 expression(void)
3655 {
3656     symbol_t    *symbol;
3657
3658     (void)identifier('$');
3659     if (parser.string[1] == '\0') {
3660         if (getch_noeof() != '(')
3661             error("bad symbol or expression");
3662         parser.type = type_none;
3663         expression_cond();
3664         if (parser.expr != expr_rparen)
3665             error("bad expression");
3666         switch (parser.type) {
3667             case type_l:
3668                 return (tok_int);
3669             case type_d:
3670                 return (tok_float);
3671             case type_p:
3672                 return (tok_pointer);
3673             default:
3674                 error("bad expression");
3675         }
3676     }
3677     else if ((symbol = get_symbol_by_name(parser.string))) {
3678         switch (parser.type = symbol->type) {
3679             case type_l:
3680                 parser.value.i = symbol->value.i;
3681                 return (tok_int);
3682             case type_d:
3683                 parser.value.d = symbol->value.d;
3684                 return (tok_float);
3685             default:
3686                 parser.value.p = symbol->value.p;
3687                 return (tok_pointer);
3688         }
3689     }
3690     else
3691         error("undefined symbol %s", parser.string);
3692 }
3693
3694 static token_t
3695 primary(skip_t skip)
3696 {
3697     int         ch;
3698
3699     switch (skip) {
3700         case skip_none: ch = getch();   break;
3701         case skip_ws:   ch = skipws();  break;
3702         case skip_nl:   ch = skipnl();  break;
3703         default:                        abort();
3704     }
3705     switch (ch) {
3706         case '%':
3707             return (regname());
3708         case 'a' ... 'z': case 'A' ... 'Z': case '_':
3709             return (identifier(ch));
3710         case '0' ... '9': case '+': case '-':
3711             return (number(ch));
3712         case '.':
3713             return (tok_dot);
3714         case '"':
3715             return (string());
3716         case '\'':
3717             return (character());
3718         case '@':
3719             return (dynamic());
3720         case '$':
3721             return (expression());
3722         case EOF:
3723             return (tok_eof);
3724         case '\n':
3725             return (tok_newline);
3726         case ';':
3727             return (tok_semicollon);
3728         default:
3729             error("syntax error");
3730     }
3731 }
3732
3733 static void
3734 parse(void)
3735 {
3736     int          ch;
3737     token_t      token;
3738     instr_t     *instr;
3739     label_t     *label;
3740     void        *value;
3741
3742     for (;;) {
3743         switch (token = primary(skip_nl)) {
3744             case tok_symbol:
3745                 ch = getch_noeof();
3746                 if (ch == ':') {
3747                     if ((label = get_label_by_name(parser.string))) {
3748                         if (label->kind == label_kind_code_forward) {
3749                             label->kind = label_kind_code;
3750                             jit_link(label->value);
3751                             jit_note(parser.name, parser.line);
3752                         }
3753                         else
3754                             error("label %s: redefined", parser.string);
3755                     }
3756                     else {
3757                         if (parser.parsing == PARSING_DATA) {
3758                             value = data + data_offset;
3759                             label = new_label(label_kind_data,
3760                                               parser.string, value);
3761                         }
3762                         else if (parser.parsing == PARSING_CODE) {
3763                             value = jit_label();
3764                             jit_note(parser.name, parser.line);
3765                             label = new_label(label_kind_code,
3766                                               parser.string, value);
3767                         }
3768                         else
3769                             error("label not in .code or .data");
3770                     }
3771                     break;
3772                 }
3773                 ungetch(ch);
3774                 if ((instr =
3775                      (instr_t *)get_hash(instrs, parser.string)) == NULL)
3776                     error("unhandled symbol %s", parser.string);
3777                 if (parser.parsing != PARSING_CODE)
3778                     error(".code must be specified before instructions");
3779                 (*instr->function)();
3780                 break;
3781             case tok_dot:
3782                 dot();
3783                 break;
3784             case tok_eof:
3785                 return;
3786             default:
3787                 error("syntax error");
3788         }
3789     }
3790 }
3791
3792 static int
3793 execute(int argc, char *argv[])
3794 {
3795     int          result;
3796     label_t     *label;
3797     function_t   function;
3798     patch_t     *patch, *next;
3799
3800     for (patch = patches; patch; patch = next) {
3801         next = patch->next;
3802         label = patch->label;
3803         if (label->kind == label_kind_code_forward)
3804             error("undefined label %s", label->name);
3805         switch (patch->kind) {
3806             case patch_kind_jmp:
3807             case patch_kind_mov:
3808             case patch_kind_call:
3809                 jit_patch_at(patch->value, label->value);
3810                 break;
3811             default:
3812                 abort();
3813         }
3814         free(patch);
3815         patch = next;
3816     }
3817
3818     if (flag_data == 0) {
3819         jit_realize();
3820         jit_set_data(NULL, 0, JIT_DISABLE_DATA | JIT_DISABLE_NOTE);
3821     }
3822
3823     function = jit_emit();
3824     if (flag_verbose > 1 || flag_disasm) {
3825         jit_print();
3826         fprintf(stderr, "  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n");
3827     }
3828     if (flag_verbose > 0 || flag_disasm) {
3829         jit_disassemble();
3830         fprintf(stderr, "  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n");
3831     }
3832
3833     jit_clear_state();
3834     if (flag_disasm)
3835         result = 0;
3836     else
3837         result = (*function)(argc, argv);
3838     jit_destroy_state();
3839
3840     return (result);
3841 }
3842
3843 static void *
3844 xmalloc(size_t size)
3845 {
3846     void        *pointer = malloc(size);
3847
3848     if (pointer == NULL)
3849         error("out of memory");
3850
3851     return (pointer);
3852 }
3853
3854 static void *
3855 xrealloc(void *pointer, size_t size)
3856 {
3857     pointer = realloc(pointer, size);
3858
3859     if (pointer == NULL)
3860         error("out of memory");
3861
3862     return (pointer);
3863 }
3864
3865 static void *
3866 xcalloc(size_t nmemb, size_t size)
3867 {
3868     void        *pointer = calloc(nmemb, size);
3869
3870     if (pointer == NULL)
3871         error("out of memory");
3872
3873     return (pointer);
3874 }
3875
3876 static label_t *
3877 new_label(label_kind_t kind, char *name, void *value)
3878 {
3879     label_t     *label;
3880
3881     label = (label_t *)xmalloc(sizeof(label_t));
3882     label->kind = kind;
3883     label->name = strdup(name);
3884     label->value = value;
3885     put_hash(labels, (entry_t *)label);
3886     label_offset++;
3887     return (label);
3888 }
3889
3890 static patch_t *
3891 new_patch(patch_kind_t kind, label_t *label, void *value)
3892 {
3893     patch_t     *patch = (patch_t *)xmalloc(sizeof(patch_t));
3894     patch->kind = kind;
3895     patch->label = label;
3896     patch->value = value;
3897     patch->next = patches;
3898     patches = patch;
3899
3900     return (patch);
3901 }
3902
3903 static int
3904 bcmp_symbols(const void *left, const void *right)
3905 {
3906     return (strcmp((char *)left, (*(symbol_t **)right)->name));
3907 }
3908
3909 static int
3910 qcmp_symbols(const void *left, const void *right)
3911 {
3912     return (strcmp((*(symbol_t **)left)->name, (*(symbol_t **)right)->name));
3913 }
3914
3915 static symbol_t *
3916 new_symbol(char *name)
3917 {
3918     symbol_t    *symbol;
3919
3920     if ((symbol_offset & 15) == 0) {
3921         if ((symbol_length += 16) == 16)
3922             symbols = (symbol_t **)xmalloc(sizeof(symbol_t *) *
3923                                            symbol_length);
3924         else
3925             symbols = (symbol_t **)xrealloc(symbols, sizeof(symbol_t *) *
3926                                             symbol_length);
3927     }
3928     symbol = (symbol_t *)xmalloc(sizeof(symbol_t));
3929     symbol->name = strdup(name);
3930     symbols[symbol_offset++] = symbol;
3931     qsort(symbols, symbol_offset, sizeof(symbol_t *), qcmp_symbols);
3932
3933     return (symbol);
3934 }
3935
3936 static symbol_t *
3937 get_symbol_by_name(char *name)
3938 {
3939     symbol_t    **symbol_pointer;
3940
3941     if (symbols == NULL)
3942         return (NULL);
3943     symbol_pointer = (symbol_t **)bsearch(name, symbols, symbol_offset,
3944                                           sizeof(symbol_t *), bcmp_symbols);
3945
3946     return (symbol_pointer ? *symbol_pointer : NULL);
3947 }
3948
3949 static hash_t *
3950 new_hash(void)
3951 {
3952     hash_t      *hash;
3953
3954     hash = (hash_t *)xmalloc(sizeof(hash_t));
3955     hash->count = 0;
3956     hash->entries = (entry_t **)xcalloc(hash->size = 32, sizeof(void *));
3957
3958     return (hash);
3959 }
3960
3961 static int
3962 hash_string(char *name)
3963 {
3964     char        *ptr;
3965     int          key;
3966
3967     for (key = 0, ptr = name; *ptr; ptr++)
3968         key = (key << (key & 1)) ^ *ptr;
3969
3970     return (key);
3971 }
3972
3973 static void
3974 put_hash(hash_t *hash, entry_t *entry)
3975 {
3976     entry_t     *prev, *ptr;
3977     int          key = hash_string(entry->name) & (hash->size - 1);
3978
3979     for (prev = ptr = hash->entries[key]; ptr; prev = ptr, ptr = ptr->next) {
3980         if (strcmp(entry->name, ptr->name) == 0)
3981             error("duplicated entry %s", entry->name);
3982     }
3983     if (prev == NULL)
3984         hash->entries[key] = entry;
3985     else
3986         prev->next = entry;
3987     entry->next = NULL;
3988     ++hash->count;
3989     if (hash->count > hash->size * 0.75)
3990         rehash(hash);
3991 }
3992
3993 static entry_t *
3994 get_hash(hash_t *hash, char *name)
3995 {
3996     entry_t     *entry;
3997     int          key = hash_string(name) & (hash->size - 1);
3998
3999     for (entry = hash->entries[key]; entry; entry = entry->next) {
4000         if (strcmp(entry->name, name) == 0)
4001             return (entry);
4002     }
4003     return (NULL);
4004 }
4005
4006 static void
4007 rehash(hash_t *hash)
4008 {
4009     int          i, size, key;
4010     entry_t     *entry, *next, **entries;
4011
4012     entries = (entry_t **)xcalloc(size = hash->size * 2, sizeof(void *));
4013     for (i = 0; i < hash->size; i++) {
4014         for (entry = hash->entries[i]; entry; entry = next) {
4015             next = entry->next;
4016             key = hash_string(entry->name) & (size - 1);
4017             entry->next = entries[key];
4018             entries[key] = entry;
4019         }
4020     }
4021     free(hash->entries);
4022     hash->entries = entries;
4023     hash->size = size;
4024 }
4025
4026 static void
4027 usage(void)
4028 {
4029 #if HAVE_GETOPT_LONG_ONLY
4030     fprintf(stderr, "\
4031 Usage: %s [jit assembler options] file [jit program options]\n\
4032 Jit assembler options:\n\
4033   -help                    Display this information\n\
4034   -v[0-3]                  Verbose output level\n\
4035   -d                       Do not use a data buffer\n\
4036   -D<macro>[=<val>]        Preprocessor options\n"
4037 #  if defined(__i386__) && __WORDSIZE == 32
4038 "  -mx87=1                  Force using x87 when sse2 available\n"
4039 #  endif
4040 #  if defined(__i386__) || defined(__x86_64__)
4041 "  -msse4_1=0               Do not use sse4_1 instructions when available\n"
4042 #  endif
4043 #  if defined(__arm__)
4044 "  -mcpu=<val>              Force cpu version (4, 5, 6 or 7)\n\
4045   -mthumb[=0|1]            Enable or disable thumb\n\
4046   -mvfp=<val>              Set vpf version (0 to disable)\n\
4047   -mneon[=0|1]             Enable or disable neon\n"
4048 #  endif
4049             , progname);
4050 #else
4051     fprintf(stderr, "\
4052 Usage: %s [jit assembler options] file [jit program options]\n\
4053 Jit assembler options:\n\
4054   -h                       Display this information\n\
4055   -v                       Verbose output level\n\
4056   -D<macro>[=<val>]        Preprocessor options\n", progname);
4057 #endif
4058     finish_jit();
4059     exit(1);
4060 }
4061
4062 int
4063 main(int argc, char *argv[])
4064 {
4065 #if HAVE_GETOPT_LONG_ONLY
4066     static const char   *short_options = "dv::";
4067     static struct option long_options[] = {
4068         { "help",               0, 0, 'h' },
4069         { "data",               2, 0, 'd' },
4070 #  if defined(__i386__) && __WORDSIZE == 32
4071         { "mx87",               2, 0, '7' },
4072 #  endif
4073 #  if defined(__i386__) || defined(__x86_64__)
4074         { "msse4_1",            2, 0, '4' },
4075 #  endif
4076 #  if defined(__arm__)
4077         { "mcpu",               2, 0, 'c' },
4078         { "mthumb",             2, 0, 't' },
4079         { "mvfp",               2, 0, 'f' },
4080         { "mneon",              2, 0, 'n' },
4081 #  endif
4082         { 0,                    0, 0, 0   }
4083     };
4084 #else
4085 #endif  /* HAVE_GETOPT_LONG_ONLY */
4086     int                  offset;
4087     char                *endptr;
4088     int                  opt_index;
4089     int                  opt_short;
4090     char                 cmdline[8192];
4091
4092 #if defined(__CYGWIN__)
4093     /* Cause a compile warning about redefinition without dllimport
4094      * attribute, *but* cause correct linkage if liblightning.a is
4095      * linked to binutils (that happens to have an internal
4096      * getopt* implementation and an apparently conflicting
4097      * optind global variable) */
4098     extern int           optind;
4099     optind = 1;
4100 #endif
4101
4102     progname = argv[0];
4103
4104     init_jit(progname);
4105
4106 #if defined(__sgi)
4107     DL_HANDLE = dlopen(NULL, RTLD_LAZY);
4108 #endif
4109
4110     flag_data = 1;
4111 #if HAVE_GETOPT_LONG_ONLY
4112     for (;;) {
4113         if ((opt_short = getopt_long_only(argc, argv, short_options,
4114                                           long_options, &opt_index)) < 0)
4115             break;
4116         switch (opt_short) {
4117             case 'h':
4118             default:
4119                 usage();
4120                 break;
4121             case 'v':
4122                 if (optarg) {
4123                     flag_verbose = strtol(optarg, &endptr, 10);
4124                     if (*endptr || flag_verbose < 0)
4125                         usage();
4126                 }
4127                 else
4128                     flag_verbose = 1;
4129                 break;
4130             case 'd':
4131                 flag_data = 0;
4132                 break;
4133 #if defined(__i386__) && __WORDSIZE == 32
4134             case '7':
4135                 if (optarg) {
4136                     if (strcmp(optarg, "") == 0 || strcmp(optarg, "1") == 0)
4137                         jit_cpu.sse2 = 0;
4138                     else if (strcmp(optarg, "0"))
4139                         usage();
4140                 }
4141                 else
4142                     jit_cpu.sse2 = 0;
4143                 break;
4144 #endif
4145 #if defined(__i386__) || defined(__x86_64__)
4146             case '4':
4147                 if (optarg) {
4148                     if (strcmp(optarg, "0") == 0)
4149                         jit_cpu.sse4_2 = 0;
4150                     else if (strcmp(optarg, "1"))
4151                         usage();
4152                 }
4153                 break;
4154 #endif
4155 #if defined(__arm__)
4156             case 'c':
4157                 if (optarg) {
4158                     offset = strtol(optarg, &endptr, 10);
4159                     if (*endptr || offset < 0)
4160                         usage();
4161                     if (offset < jit_cpu.version)
4162                         jit_cpu.version = offset;
4163                 }
4164                 break;
4165             case 't':
4166                 if (optarg) {
4167                     if (strcmp(optarg, "0") == 0)
4168                         jit_cpu.thumb = 0;
4169                     else if (strcmp(optarg, "1") && strcmp(optarg, "2"))
4170                         usage();
4171                 }
4172                 break;
4173             case 'f':
4174 #  if !defined(__ARM_PCS_VFP)
4175                 /* Do not allow overrinding hard float abi */
4176                 if (optarg) {
4177                     offset = strtol(optarg, &endptr, 10);
4178                     if (*endptr || offset < 0)
4179                         usage();
4180                     if (offset < jit_cpu.vfp)
4181                         jit_cpu.vfp = offset;
4182                 }
4183 #  endif
4184                 break;
4185             case 'n':
4186                 if (optarg) {
4187                     if (strcmp(optarg, "0") == 0)
4188                         jit_cpu.neon = 0;
4189                     else if (strcmp(optarg, "1"))
4190                         usage();
4191                 }
4192                 break;
4193 #endif
4194         }
4195     }
4196 #else
4197     while ((opt_short = getopt(argc, argv, "hvd")) >= 0) {
4198         if (opt_short == 'v')
4199             ++flag_verbose;
4200         else if (opt_short == 'd')
4201             flag_data = 0;
4202         else
4203             usage();
4204     }
4205 #endif
4206
4207     opt_index = optind;
4208 #if defined(__hpux)
4209     /* Workaround */
4210     if (opt_index < argc && argv[opt_index][0] == '-')
4211         ++opt_index;
4212 #endif
4213     if (opt_index < 0 || opt_index >= argc)
4214         usage();
4215     if (strcmp(argv[opt_index], "-") == 0)
4216         strcpy(parser.name, "<stdin>");
4217     else {
4218         if ((endptr = strrchr(argv[opt_index], '/')) == NULL)
4219             endptr = argv[opt_index];
4220         else
4221             ++endptr;
4222         strncpy(parser.name, endptr, sizeof(parser.name));
4223         parser.name[sizeof(parser.name) - 1] = '\0';
4224     }
4225 #if __clang__
4226 #  define cc "clang"
4227 #else
4228 #  define cc "gcc"
4229 #endif
4230     opt_short = snprintf(cmdline, sizeof(cmdline), cc " -E -x c %s", argv[opt_index]);
4231     for (++opt_index; opt_index < argc; opt_index++) {
4232         if (argv[opt_index][0] == '-')
4233             opt_short += snprintf(cmdline + opt_short,
4234                                   sizeof(cmdline) - opt_short,
4235                                   " %s", argv[opt_index]);
4236         else {
4237             --opt_index;
4238             break;
4239         }
4240     }
4241     opt_short += snprintf(cmdline + opt_short,
4242                           sizeof(cmdline) - opt_short,
4243                           " -D__WORDSIZE=%d", __WORDSIZE);
4244     opt_short += snprintf(cmdline + opt_short,
4245                           sizeof(cmdline) - opt_short,
4246                           " -D__LITTLE_ENDIAN=%d", __LITTLE_ENDIAN);
4247     opt_short += snprintf(cmdline + opt_short,
4248                           sizeof(cmdline) - opt_short,
4249                           " -D__BIG_ENDIAN=%d", __BIG_ENDIAN);
4250     opt_short += snprintf(cmdline + opt_short,
4251                           sizeof(cmdline) - opt_short,
4252                           " -D__BYTE_ORDER=%d", __BYTE_ORDER);
4253 #if defined(__i386__)
4254     opt_short += snprintf(cmdline + opt_short,
4255                           sizeof(cmdline) - opt_short,
4256                           " -D__i386__=1");
4257 #endif
4258 #if defined(__x86_64__)
4259     opt_short += snprintf(cmdline + opt_short,
4260                           sizeof(cmdline) - opt_short,
4261                           " -D__x86_64__=1");
4262 #endif
4263 #if defined(__mips__)
4264     opt_short += snprintf(cmdline + opt_short,
4265                           sizeof(cmdline) - opt_short,
4266                           " -D__mips__=1");
4267 #endif
4268 #if defined(__arm__)
4269     opt_short += snprintf(cmdline + opt_short,
4270                           sizeof(cmdline) - opt_short,
4271                           " -D__arm__=1");
4272 #endif
4273 #if defined(__powerpc__)
4274     opt_short += snprintf(cmdline + opt_short,
4275                           sizeof(cmdline) - opt_short,
4276                           " -D__ppc__=1");
4277 #endif
4278 #if defined(__sparc__)
4279     opt_short += snprintf(cmdline + opt_short,
4280                           sizeof(cmdline) - opt_short,
4281                           " -D__sparc__=1");
4282 #endif
4283 #if defined(__ia64__)
4284     opt_short += snprintf(cmdline + opt_short,
4285                           sizeof(cmdline) - opt_short,
4286                           " -D__ia64__=1");
4287 #endif
4288 #if defined(__hppa__)
4289     opt_short += snprintf(cmdline + opt_short,
4290                           sizeof(cmdline) - opt_short,
4291                           " -D__hppa__=1");
4292 #endif
4293 #if defined(_AIX)
4294     opt_short += snprintf(cmdline + opt_short,
4295                           sizeof(cmdline) - opt_short,
4296                           " -D_AIX=1");
4297 #endif
4298 #if defined(__sgi__)
4299     opt_short += snprintf(cmdline + opt_short,
4300                           sizeof(cmdline) - opt_short,
4301                           " -D__sgi__=1");
4302 #endif
4303 #if defined(__aarch64__)
4304     opt_short += snprintf(cmdline + opt_short,
4305                           sizeof(cmdline) - opt_short,
4306                           " -D__aarch64__=1");
4307 #endif
4308 #if defined(__s390__) || defined(__s390x__)
4309     opt_short += snprintf(cmdline + opt_short,
4310                           sizeof(cmdline) - opt_short,
4311                           " -D__s390__=1");
4312 #endif
4313 #if defined(__alpha__)
4314     opt_short += snprintf(cmdline + opt_short,
4315                           sizeof(cmdline) - opt_short,
4316                           " -D__alpha__=1");
4317 #endif
4318     if ((parser.fp = popen(cmdline, "r")) == NULL)
4319         error("cannot execute %s", cmdline);
4320
4321     parser.line = 1;
4322     parser.string = (char *)xmalloc(parser.length = 4096);
4323
4324 #if defined(__linux__) && (defined(__i386__) || defined(__x86_64__))
4325     /*  double precision                0x200
4326      *  round nearest                   0x000
4327      *  invalid operation mask          0x001
4328      *  denormalized operand mask       0x002
4329      *  zero divide mask                0x004
4330      *  precision (inexact) mask        0x020
4331      */
4332     {
4333         fpu_control_t fpu_control = 0x027f;
4334         _FPU_SETCW(fpu_control);
4335     }
4336 #endif
4337
4338     _jit = jit_new_state();
4339
4340     instrs = new_hash();
4341     for (offset = 0;
4342          offset < (int)(sizeof(instr_vector) / sizeof(instr_vector[0]));
4343          offset++)
4344         put_hash(instrs, (entry_t *)(instr_vector + offset));
4345
4346     labels = new_hash();
4347
4348     parse();
4349     pclose(parser.fp);
4350     parser.fp = NULL;
4351
4352     for (opt_short = 0; opt_index < argc; opt_short++, opt_index++)
4353         argv[opt_short] = argv[opt_index];
4354     argv[opt_short] = NULL;
4355     argc = opt_short;
4356     execute(argc, argv);
4357
4358     finish_jit();
4359
4360     return (0);
4361 }