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