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