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