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